|
1 |
| -import global from 'global'; |
2 |
| - |
3 |
| -import type { Channel } from '@storybook/channels'; |
4 |
| -import { SET_CONFIG } from '@storybook/core-events'; |
5 |
| -import type { API } from '@storybook/manager-api'; |
6 |
| -import type { |
7 |
| - Addon_Collection, |
8 |
| - Addon_Config, |
9 |
| - Addon_Elements, |
10 |
| - Addon_Loaders, |
11 |
| - Addon_Type, |
12 |
| - Addon_Types, |
13 |
| -} from '@storybook/types'; |
14 |
| -import { Addon_TypesEnum } from '@storybook/types'; |
15 |
| -import { logger } from '@storybook/client-logger'; |
16 |
| -import { mockChannel } from './storybook-channel-mock'; |
17 |
| - |
18 |
| -export { Addon_Type as Addon, Addon_TypesEnum as types }; |
19 |
| - |
20 |
| -export function isSupportedType(type: Addon_Types): boolean { |
21 |
| - return !!Object.values(Addon_TypesEnum).find((typeVal) => typeVal === type); |
22 |
| -} |
23 |
| - |
24 |
| -export class AddonStore { |
25 |
| - constructor() { |
26 |
| - this.promise = new Promise((res) => { |
27 |
| - this.resolve = () => res(this.getChannel()); |
28 |
| - }) as Promise<Channel>; |
29 |
| - } |
30 |
| - |
31 |
| - private loaders: Addon_Loaders<API> = {}; |
32 |
| - |
33 |
| - private elements: Addon_Elements = {}; |
34 |
| - |
35 |
| - private config: Addon_Config = {}; |
36 |
| - |
37 |
| - private channel: Channel | undefined; |
38 |
| - |
39 |
| - private serverChannel: Channel | undefined; |
40 |
| - |
41 |
| - private promise: any; |
42 |
| - |
43 |
| - private resolve: any; |
44 |
| - |
45 |
| - getChannel = (): Channel => { |
46 |
| - // this.channel should get overwritten by setChannel. If it wasn't called (e.g. in non-browser environment), set a mock instead. |
47 |
| - if (!this.channel) { |
48 |
| - this.setChannel(mockChannel()); |
49 |
| - } |
50 |
| - |
51 |
| - return this.channel; |
52 |
| - }; |
53 |
| - |
54 |
| - getServerChannel = (): Channel => { |
55 |
| - if (!this.serverChannel) { |
56 |
| - throw new Error('Accessing non-existent serverChannel'); |
57 |
| - } |
58 |
| - |
59 |
| - return this.serverChannel; |
60 |
| - }; |
61 |
| - |
62 |
| - ready = (): Promise<Channel> => this.promise; |
63 |
| - |
64 |
| - hasChannel = (): boolean => !!this.channel; |
65 |
| - |
66 |
| - hasServerChannel = (): boolean => !!this.serverChannel; |
67 |
| - |
68 |
| - setChannel = (channel: Channel): void => { |
69 |
| - this.channel = channel; |
70 |
| - this.resolve(); |
71 |
| - }; |
72 |
| - |
73 |
| - setServerChannel = (channel: Channel): void => { |
74 |
| - this.serverChannel = channel; |
75 |
| - }; |
76 |
| - |
77 |
| - getElements = (type: Addon_Types): Addon_Collection => { |
78 |
| - if (!this.elements[type]) { |
79 |
| - this.elements[type] = {}; |
80 |
| - } |
81 |
| - return this.elements[type]; |
82 |
| - }; |
83 |
| - |
84 |
| - addPanel = (name: string, options: Addon_Type): void => { |
85 |
| - this.add(name, { |
86 |
| - type: Addon_TypesEnum.PANEL, |
87 |
| - ...options, |
88 |
| - }); |
89 |
| - }; |
90 |
| - |
91 |
| - add = (name: string, addon: Addon_Type) => { |
92 |
| - const { type } = addon; |
93 |
| - const collection = this.getElements(type); |
94 |
| - collection[name] = { id: name, ...addon }; |
95 |
| - }; |
96 |
| - |
97 |
| - setConfig = (value: Addon_Config) => { |
98 |
| - Object.assign(this.config, value); |
99 |
| - if (this.hasChannel()) { |
100 |
| - this.getChannel().emit(SET_CONFIG, value); |
101 |
| - } |
102 |
| - }; |
103 |
| - |
104 |
| - getConfig = () => this.config; |
105 |
| - |
106 |
| - register = (name: string, registerCallback: (api: API) => void): void => { |
107 |
| - if (this.loaders[name]) { |
108 |
| - logger.warn(`${name} was loaded twice, this could have bad side-effects`); |
109 |
| - } |
110 |
| - this.loaders[name] = registerCallback; |
111 |
| - }; |
112 |
| - |
113 |
| - loadAddons = (api: any) => { |
114 |
| - Object.values(this.loaders).forEach((value) => value(api)); |
115 |
| - }; |
116 |
| -} |
117 |
| - |
118 |
| -// Enforce addons store to be a singleton |
119 |
| -const KEY = '__STORYBOOK_ADDONS'; |
120 |
| - |
121 |
| -function getAddonsStore(): AddonStore { |
122 |
| - if (!global[KEY]) { |
123 |
| - global[KEY] = new AddonStore(); |
124 |
| - } |
125 |
| - return global[KEY]; |
126 |
| -} |
127 |
| - |
128 |
| -// Exporting this twice in order to to be able to import it like { addons } instead of 'addons' |
129 |
| -// prefer import { addons } from '@storybook/addons' over import addons from '@storybook/addons' |
130 |
| -// |
131 |
| -// See public_api.ts |
132 |
| - |
133 |
| -export const addons = getAddonsStore(); |
| 1 | +export { addons, type AddonStore } from '@storybook/manager-api'; |
0 commit comments