diff --git a/code/builders/builder-vite/package.json b/code/builders/builder-vite/package.json index ff881c6dd22b..8842c18b7b18 100644 --- a/code/builders/builder-vite/package.json +++ b/code/builders/builder-vite/package.json @@ -43,6 +43,7 @@ }, "dependencies": { "@storybook/channel-postmessage": "7.1.0-alpha.30", + "@storybook/channel-websocket": "7.1.0-alpha.30", "@storybook/client-logger": "7.1.0-alpha.30", "@storybook/core-common": "7.1.0-alpha.30", "@storybook/csf-plugin": "7.1.0-alpha.30", diff --git a/code/builders/builder-vite/src/codegen-set-addon-channel.ts b/code/builders/builder-vite/src/codegen-set-addon-channel.ts index 6548d64c67c1..71bb0cee8952 100644 --- a/code/builders/builder-vite/src/codegen-set-addon-channel.ts +++ b/code/builders/builder-vite/src/codegen-set-addon-channel.ts @@ -1,9 +1,23 @@ export async function generateAddonSetupCode() { return ` - import { createChannel as createPostMessageChannel } from '@storybook/channel-postmessage'; + import { Channel } from '@storybook/channels'; + import { PostmsgTransport } from '@storybook/channel-postmessage'; + import { WebsocketTransport } from '@storybook/channel-websocket'; import { addons } from '@storybook/preview-api'; - const channel = createPostMessageChannel({ page: 'preview' }); + const page = 'preview'; + const transports = [new PostmsgTransport({ page })]; + + if (CONFIG_TYPE === 'DEVELOPMENT') { + const protocol = window.location.protocol === 'http:' ? 'ws' : 'wss'; + const { hostname, port } = window.location; + const channelUrl = \`$\{protocol}://$\{hostname}:$\{port}/storybook-server-channel\`; + + transports.push(new WebsocketTransport({ url: channelUrl, onError: () => {} })); + } + + const channel = new Channel({ transports }); + addons.setChannel(channel); window.__STORYBOOK_ADDONS_CHANNEL__ = channel; diff --git a/code/builders/builder-webpack5/templates/virtualModuleModernEntry.js.handlebars b/code/builders/builder-webpack5/templates/virtualModuleModernEntry.js.handlebars index ec9848e1e121..1bb7ec300fb1 100644 --- a/code/builders/builder-webpack5/templates/virtualModuleModernEntry.js.handlebars +++ b/code/builders/builder-webpack5/templates/virtualModuleModernEntry.js.handlebars @@ -1,14 +1,27 @@ import { global } from '@storybook/global'; import { ClientApi, PreviewWeb, addons, composeConfigs } from '@storybook/preview-api'; -import { createChannel as createPostMessageChannel } from '@storybook/channel-postmessage'; +import { Channel } from '@storybook/channels'; +import { PostmsgTransport } from '@storybook/channel-postmessage'; +import { WebsocketTransport } from '@storybook/channel-websocket'; import { importFn } from './{{storiesFilename}}'; const getProjectAnnotations = () => composeConfigs([{{#each previewAnnotations}}require('{{this}}'),{{/each}}]); -const channel = createPostMessageChannel({ page: 'preview' }); +const page = 'preview'; +const transports = [new PostmsgTransport({ page })]; + +if (global.CONFIG_TYPE === 'DEVELOPMENT') { + const protocol = window.location.protocol === 'http:' ? 'ws' : 'wss'; + const { hostname, port } = window.location; + const channelUrl = `${protocol}://${hostname}:${port}/storybook-server-channel`; + + transports.push(new WebsocketTransport({ url: channelUrl, onError: () => {} })); +} + +const channel = new Channel({ transports }); addons.setChannel(channel); if (global.CONFIG_TYPE === 'DEVELOPMENT'){ diff --git a/code/lib/channel-postmessage/src/index.ts b/code/lib/channel-postmessage/src/index.ts index 7a6b428c2a1e..5ec6a64fc856 100644 --- a/code/lib/channel-postmessage/src/index.ts +++ b/code/lib/channel-postmessage/src/index.ts @@ -288,6 +288,13 @@ const getEventSourceUrl = (event: MessageEvent) => { /** * Creates a channel which communicates with an iframe or child window. + * + * @deprecated This function is deprecated. Use the `Channel` class instead. + * @example + * const channel = new Channel({ transports: new PostmsgTransport({ page }) }); + * + * @param {Config} config - The configuration object. + * @returns {Channel} The channel instance. */ export function createChannel({ page }: Config): Channel { const transports: ChannelTransport[] = [new PostmsgTransport({ page })]; @@ -303,5 +310,9 @@ export function createChannel({ page }: Config): Channel { return new Channel({ transports }); } -// backwards compat with builder-vite +/** + * @deprecated This function is deprecated. Use the `Channel` class instead. + * @example + * const channel = new Channel({ transports: new PostmsgTransport({ page }) }); + */ export default createChannel; diff --git a/code/lib/channel-websocket/src/index.ts b/code/lib/channel-websocket/src/index.ts index 64fa26e74b2c..597259353470 100644 --- a/code/lib/channel-websocket/src/index.ts +++ b/code/lib/channel-websocket/src/index.ts @@ -82,23 +82,15 @@ export function createChannel({ async = false, onError = (err) => logger.warn(err), }: CreateChannelArgs) { - const transports: ChannelTransport[] = []; - - if (url) { - transports.push(new WebsocketTransport({ url, onError })); - } - - const isUrlServerChannel = !!url?.includes('storybook-server-channel'); - - if (CONFIG_TYPE === 'DEVELOPMENT' && isUrlServerChannel === false) { + let channelUrl = url; + if (!channelUrl) { const protocol = window.location.protocol === 'http:' ? 'ws' : 'wss'; const { hostname, port } = window.location; - const channelUrl = `${protocol}://${hostname}:${port}/storybook-server-channel`; - - transports.push(new WebsocketTransport({ url: channelUrl, onError: () => {} })); + channelUrl = `${protocol}://${hostname}:${port}/storybook-server-channel`; } - return new Channel({ transports, async }); + const transport = new WebsocketTransport({ url: channelUrl, onError }); + return new Channel({ transport, async }); } // backwards compat with builder-vite diff --git a/code/lib/preview-api/package.json b/code/lib/preview-api/package.json index 663aed6f69fa..3d97d4813c18 100644 --- a/code/lib/preview-api/package.json +++ b/code/lib/preview-api/package.json @@ -68,6 +68,7 @@ }, "dependencies": { "@storybook/channel-postmessage": "7.1.0-alpha.30", + "@storybook/channel-websocket": "7.1.0-alpha.30", "@storybook/channels": "7.1.0-alpha.30", "@storybook/client-logger": "7.1.0-alpha.30", "@storybook/core-events": "7.1.0-alpha.30", diff --git a/code/lib/preview-api/src/modules/core-client/start.ts b/code/lib/preview-api/src/modules/core-client/start.ts index b27f64e48799..1d9f69ebfdad 100644 --- a/code/lib/preview-api/src/modules/core-client/start.ts +++ b/code/lib/preview-api/src/modules/core-client/start.ts @@ -1,7 +1,10 @@ /* eslint-disable no-underscore-dangle, @typescript-eslint/naming-convention */ import { global } from '@storybook/global'; import type { Renderer, ArgsStoryFn, Path, ProjectAnnotations } from '@storybook/types'; -import { createChannel } from '@storybook/channel-postmessage'; +import { PostmsgTransport } from '@storybook/channel-postmessage'; +import { WebsocketTransport } from '@storybook/channel-websocket'; +import type { ChannelTransport } from '@storybook/channels'; +import { Channel } from '@storybook/channels'; import { FORCE_RE_RENDER } from '@storybook/core-events'; import { addons } from '../../addons'; import { PreviewWeb } from '../../preview-web'; @@ -10,7 +13,7 @@ import { ClientApi } from '../../client-api'; import { executeLoadableForChanges } from './executeLoadable'; import type { Loadable } from './executeLoadable'; -const { FEATURES } = global; +const { FEATURES, CONFIG_TYPE } = global; const removedApi = (name: string) => () => { throw new Error(`@storybook/client-api:${name} was removed in storyStoreV7.`); @@ -94,7 +97,18 @@ export function start( }; } - const channel = createChannel({ page: 'preview' }); + const page = 'preview'; + const transports: ChannelTransport[] = [new PostmsgTransport({ page })]; + + if (CONFIG_TYPE === 'DEVELOPMENT') { + const protocol = window.location.protocol === 'http:' ? 'ws' : 'wss'; + const { hostname, port } = window.location; + const channelUrl = `${protocol}://${hostname}:${port}/storybook-server-channel`; + + transports.push(new WebsocketTransport({ url: channelUrl, onError: () => {} })); + } + + const channel = new Channel({ transports }); addons.setChannel(channel); const clientApi = global?.__STORYBOOK_CLIENT_API__ || new ClientApi(); diff --git a/code/lib/preview-api/src/typings.d.ts b/code/lib/preview-api/src/typings.d.ts index ff6233a2b547..5f0fae0ca9fb 100644 --- a/code/lib/preview-api/src/typings.d.ts +++ b/code/lib/preview-api/src/typings.d.ts @@ -32,6 +32,7 @@ declare var __STORYBOOK_PREVIEW__: import('./modules/preview-web/PreviewWeb').Pr declare var __STORYBOOK_STORY_STORE__: any; declare var STORYBOOK_HOOKS_CONTEXT: any; declare var LOGLEVEL: 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'silent' | undefined; +declare var CONFIG_TYPE: 'DEVELOPMENT' | 'PRODUCTION'; declare module 'ansi-to-html'; declare class AnsiToHtml { diff --git a/code/ui/manager/package.json b/code/ui/manager/package.json index be1b5442ecdf..b3dd15a90636 100644 --- a/code/ui/manager/package.json +++ b/code/ui/manager/package.json @@ -54,6 +54,7 @@ "@storybook/addons": "7.1.0-alpha.30", "@storybook/api": "7.1.0-alpha.30", "@storybook/channel-postmessage": "7.1.0-alpha.30", + "@storybook/channel-websocket": "7.1.0-alpha.30", "@storybook/channels": "7.1.0-alpha.30", "@storybook/client-logger": "7.1.0-alpha.30", "@storybook/components": "7.1.0-alpha.30", diff --git a/code/ui/manager/src/runtime.ts b/code/ui/manager/src/runtime.ts index 27a96b44dbdb..c2dab6361d97 100644 --- a/code/ui/manager/src/runtime.ts +++ b/code/ui/manager/src/runtime.ts @@ -1,11 +1,13 @@ import { global } from '@storybook/global'; -import type { Channel } from '@storybook/channels'; +import { Channel } from '@storybook/channels'; +import type { ChannelTransport } from '@storybook/channels'; import type { AddonStore } from '@storybook/manager-api'; import { addons } from '@storybook/manager-api'; import type { Addon_Types, Addon_Config } from '@storybook/types'; -import * as postMessage from '@storybook/channel-postmessage'; +import { PostmsgTransport } from '@storybook/channel-postmessage'; import { CHANNEL_CREATED } from '@storybook/core-events'; +import { WebsocketTransport } from '@storybook/channel-websocket'; import Provider from './provider'; import { renderStorybookUI } from './index'; @@ -27,7 +29,18 @@ class ReactProvider extends Provider { constructor() { super(); - const channel = postMessage.createChannel({ page: 'manager' }); + const page = 'manager'; + const transports: ChannelTransport[] = [new PostmsgTransport({ page })]; + + if (CONFIG_TYPE === 'DEVELOPMENT') { + const protocol = window.location.protocol === 'http:' ? 'ws' : 'wss'; + const { hostname, port } = window.location; + const channelUrl = `${protocol}://${hostname}:${port}/storybook-server-channel`; + + transports.push(new WebsocketTransport({ url: channelUrl, onError: () => {} })); + } + + const channel = new Channel({ transports }); addons.setChannel(channel); diff --git a/code/yarn.lock b/code/yarn.lock index 7cc533dd1f7f..d18753666eb0 100644 --- a/code/yarn.lock +++ b/code/yarn.lock @@ -5840,6 +5840,7 @@ __metadata: resolution: "@storybook/builder-vite@workspace:builders/builder-vite" dependencies: "@storybook/channel-postmessage": 7.1.0-alpha.30 + "@storybook/channel-websocket": 7.1.0-alpha.30 "@storybook/client-logger": 7.1.0-alpha.30 "@storybook/core-common": 7.1.0-alpha.30 "@storybook/csf-plugin": 7.1.0-alpha.30 @@ -6557,6 +6558,7 @@ __metadata: "@storybook/addons": 7.1.0-alpha.30 "@storybook/api": 7.1.0-alpha.30 "@storybook/channel-postmessage": 7.1.0-alpha.30 + "@storybook/channel-websocket": 7.1.0-alpha.30 "@storybook/channels": 7.1.0-alpha.30 "@storybook/client-logger": 7.1.0-alpha.30 "@storybook/components": 7.1.0-alpha.30 @@ -6934,6 +6936,7 @@ __metadata: dependencies: "@jest/globals": ^29.5.0 "@storybook/channel-postmessage": 7.1.0-alpha.30 + "@storybook/channel-websocket": 7.1.0-alpha.30 "@storybook/channels": 7.1.0-alpha.30 "@storybook/client-logger": 7.1.0-alpha.30 "@storybook/core-common": 7.1.0-alpha.30