@player-ui/storybook 0.4.0 → 0.4.1-next.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs.js CHANGED
@@ -5,26 +5,53 @@ Object.defineProperty(exports, '__esModule', { value: true });
5
5
  var React = require('react');
6
6
  var addons = require('@storybook/addons');
7
7
  var storybookDarkMode = require('storybook-dark-mode');
8
- var dequal = require('dequal');
8
+ var deepEqual = require('deep-equal');
9
9
  var Editor = require('@monaco-editor/react');
10
- var uuid = require('uuid');
11
- var table = require('@devtools-ds/table');
12
- var makeClass = require('clsx');
13
10
  var components = require('@storybook/components');
14
- var api = require('@storybook/api');
15
- var coreEvents = require('@storybook/core-events');
11
+ var reactRedux = require('react-redux');
12
+ var PlayerDSL = require('@player-tools/dsl');
13
+ var toolkit = require('@reduxjs/toolkit');
14
+ var reduxStateSync = require('redux-state-sync');
15
+ var browser = require('esbuild-wasm/lib/browser');
16
16
  var react$1 = require('@player-ui/react');
17
- var react = require('@chakra-ui/react');
17
+ var beaconPluginReact = require('@player-ui/beacon-plugin-react');
18
18
  var makeFlow = require('@player-ui/make-flow');
19
- var addonDocs = require('@storybook/addon-docs');
20
19
  var lzString = require('lz-string');
21
20
  var metricsPluginReact = require('@player-ui/metrics-plugin-react');
21
+ var uuid = require('uuid');
22
+ var player = require('@player-ui/player');
23
+ var react = require('@chakra-ui/react');
24
+ var table = require('@devtools-ds/table');
25
+ var makeClass = require('clsx');
26
+ var api = require('@storybook/api');
27
+ var coreEvents = require('@storybook/core-events');
22
28
 
23
29
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
24
30
 
31
+ function _interopNamespace(e) {
32
+ if (e && e.__esModule) return e;
33
+ var n = Object.create(null);
34
+ if (e) {
35
+ Object.keys(e).forEach(function (k) {
36
+ if (k !== 'default') {
37
+ var d = Object.getOwnPropertyDescriptor(e, k);
38
+ Object.defineProperty(n, k, d.get ? d : {
39
+ enumerable: true,
40
+ get: function () { return e[k]; }
41
+ });
42
+ }
43
+ });
44
+ }
45
+ n["default"] = e;
46
+ return Object.freeze(n);
47
+ }
48
+
49
+ var React__namespace = /*#__PURE__*/_interopNamespace(React);
25
50
  var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
26
51
  var addons__default = /*#__PURE__*/_interopDefaultLegacy(addons);
52
+ var deepEqual__default = /*#__PURE__*/_interopDefaultLegacy(deepEqual);
27
53
  var Editor__default = /*#__PURE__*/_interopDefaultLegacy(Editor);
54
+ var PlayerDSL__namespace = /*#__PURE__*/_interopNamespace(PlayerDSL);
28
55
  var makeClass__default = /*#__PURE__*/_interopDefaultLegacy(makeClass);
29
56
 
30
57
  const ADDON_ID = "web-player/addon";
@@ -33,322 +60,73 @@ const EVENT_PANEL_ID = `${ADDON_ID}/events-panel`;
33
60
  const FLOW_REFRESH_TOOL_ID = `${ADDON_ID}/flow-refresh-tool`;
34
61
  const RENDER_SELECT_TOOL_ID = `${ADDON_ID}/render-select-tool`;
35
62
 
36
- var __defProp$2 = Object.defineProperty;
37
- var __getOwnPropSymbols$2 = Object.getOwnPropertySymbols;
38
- var __hasOwnProp$2 = Object.prototype.hasOwnProperty;
39
- var __propIsEnum$2 = Object.prototype.propertyIsEnumerable;
40
- var __defNormalProp$2 = (obj, key, value) => key in obj ? __defProp$2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
41
- var __spreadValues$2 = (a, b) => {
63
+ var __defProp$4 = Object.defineProperty;
64
+ var __getOwnPropSymbols$4 = Object.getOwnPropertySymbols;
65
+ var __hasOwnProp$4 = Object.prototype.hasOwnProperty;
66
+ var __propIsEnum$4 = Object.prototype.propertyIsEnumerable;
67
+ var __defNormalProp$4 = (obj, key, value) => key in obj ? __defProp$4(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
68
+ var __spreadValues$4 = (a, b) => {
42
69
  for (var prop in b || (b = {}))
43
- if (__hasOwnProp$2.call(b, prop))
44
- __defNormalProp$2(a, prop, b[prop]);
45
- if (__getOwnPropSymbols$2)
46
- for (var prop of __getOwnPropSymbols$2(b)) {
47
- if (__propIsEnum$2.call(b, prop))
48
- __defNormalProp$2(a, prop, b[prop]);
70
+ if (__hasOwnProp$4.call(b, prop))
71
+ __defNormalProp$4(a, prop, b[prop]);
72
+ if (__getOwnPropSymbols$4)
73
+ for (var prop of __getOwnPropSymbols$4(b)) {
74
+ if (__propIsEnum$4.call(b, prop))
75
+ __defNormalProp$4(a, prop, b[prop]);
49
76
  }
50
77
  return a;
51
78
  };
52
- function createEvent(base) {
53
- return __spreadValues$2({
54
- id: uuid.v4(),
55
- time: Date.now()
56
- }, base);
57
- }
58
-
59
- function subscribe(chan, eventName, callback) {
60
- const handler = (payload) => {
61
- callback(JSON.parse(payload));
62
- };
63
- chan.addListener(eventName, handler);
64
- return () => {
65
- chan.removeListener(eventName, handler);
66
- };
67
- }
68
- function publish(chan, event) {
69
- chan.emit(event.type, JSON.stringify(event));
70
- }
71
- function useStateActions(chan) {
72
- return React__default["default"].useMemo(() => ({
73
- addEvents: (events) => {
74
- publish(chan, {
75
- type: "@@player/event/add",
76
- events
77
- });
78
- },
79
- setMetrics: (metrics) => {
80
- publish(chan, {
81
- type: "@@player/metrics/set",
82
- metrics
83
- });
84
- },
85
- clearEvents: () => {
86
- publish(chan, {
87
- type: "@@player/event/clear"
88
- });
89
- },
90
- setFlow: (flow) => {
91
- publish(chan, {
92
- type: "@@player/flow/set",
93
- flow
94
- });
95
- },
96
- resetFlow: () => {
97
- publish(chan, { type: "@@player/flow/reset" });
98
- },
99
- setPlatform: (platform) => {
100
- publish(chan, { type: "@@player/platform/set", platform });
101
- }
102
- }), [chan]);
103
- }
104
- function useEventState(chan) {
105
- const [events, setEvents] = React__default["default"].useState([]);
106
- React__default["default"].useEffect(() => {
107
- const unsubAdd = subscribe(chan, "@@player/event/add", (evt) => setEvents((old) => [...old, ...evt.events]));
108
- const unsubClear = subscribe(chan, "@@player/event/clear", () => {
109
- setEvents([]);
110
- });
111
- return () => {
112
- unsubAdd();
113
- unsubClear();
114
- };
115
- }, [chan]);
116
- return events;
117
- }
118
- function useFlowState(chan) {
119
- const [flow, setFlow] = React__default["default"].useState();
120
- React__default["default"].useEffect(() => {
121
- return subscribe(chan, "@@player/flow/set", (evt) => {
122
- setFlow(evt.flow);
123
- });
124
- }, [chan]);
125
- return flow;
126
- }
127
-
128
- const EditorPanel = (props) => {
129
- const { active } = props;
130
- const darkMode = storybookDarkMode.useDarkMode();
131
- const flow = useFlowState(props.api.getChannel());
132
- const actions = useStateActions(props.api.getChannel());
133
- const [editorValue, setEditorValue] = React__default["default"].useState(flow ? JSON.stringify(flow, null, 2) : "{}");
134
- const updateTimerRef = React__default["default"].useRef(void 0);
135
- function clearPending() {
136
- if (updateTimerRef.current) {
137
- clearTimeout(updateTimerRef.current);
138
- updateTimerRef.current = void 0;
139
- }
140
- }
141
- React__default["default"].useEffect(() => {
142
- if (!active) {
143
- return;
144
- }
145
- try {
146
- if (editorValue) {
147
- const parsed = JSON.parse(editorValue);
148
- if (dequal.dequal(flow, parsed)) {
149
- return;
150
- }
151
- }
152
- } catch (e) {
153
- }
154
- setEditorValue(JSON.stringify(flow, null, 2));
155
- }, [flow, active]);
156
- if (!active) {
157
- return null;
158
- }
159
- const onChange = (val) => {
160
- clearPending();
161
- setEditorValue(val != null ? val : "");
162
- try {
163
- if (val) {
164
- const parsed = JSON.parse(val);
165
- if (!dequal.dequal(parsed, flow)) {
166
- updateTimerRef.current = setTimeout(() => {
167
- if (active) {
168
- actions.setFlow(parsed);
169
- }
170
- }, 1e3);
171
- }
79
+ var __async$2 = (__this, __arguments, generator) => {
80
+ return new Promise((resolve, reject) => {
81
+ var fulfilled = (value) => {
82
+ try {
83
+ step(generator.next(value));
84
+ } catch (e) {
85
+ reject(e);
172
86
  }
173
- } catch (e) {
174
- }
175
- };
176
- return /* @__PURE__ */ React__default["default"].createElement("div", null, /* @__PURE__ */ React__default["default"].createElement(Editor__default["default"], {
177
- theme: darkMode ? "vs-dark" : "light",
178
- value: editorValue,
179
- language: "json",
180
- onChange
181
- }));
182
- };
183
-
184
- var e=[],t=[];function n(n,r){if(n&&"undefined"!=typeof document){var a,s=!0===r.prepend?"prepend":"append",d=!0===r.singleTag,i="string"==typeof r.container?document.querySelector(r.container):document.getElementsByTagName("head")[0];if(d){var u=e.indexOf(i);-1===u&&(u=e.push(i)-1,t[u]={}),a=t[u]&&t[u][s]?t[u][s]:t[u][s]=c();}else a=c();65279===n.charCodeAt(0)&&(n=n.substring(1)),a.styleSheet?a.styleSheet.cssText+=n:a.appendChild(document.createTextNode(n));}function c(){var e=document.createElement("style");if(e.setAttribute("type","text/css"),r.attributes)for(var t=Object.keys(r.attributes),n=0;n<t.length;n++)e.setAttribute(t[n],r.attributes[t[n]]);var a="prepend"===s?"afterbegin":"beforeend";return i.insertAdjacentElement(a,e),e}}
185
-
186
- var css = "\n.events_header__1bcc1085 td {\n width: 200px;\n}\n\n.events_body__1bcc1085 td {\n}\n";
187
- var modules_2563542d = {"header":"events_header__1bcc1085","body":"events_body__1bcc1085"};
188
- n(css,{});
189
-
190
- var __defProp$1 = Object.defineProperty;
191
- var __getOwnPropSymbols$1 = Object.getOwnPropertySymbols;
192
- var __hasOwnProp$1 = Object.prototype.hasOwnProperty;
193
- var __propIsEnum$1 = Object.prototype.propertyIsEnumerable;
194
- var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
195
- var __spreadValues$1 = (a, b) => {
196
- for (var prop in b || (b = {}))
197
- if (__hasOwnProp$1.call(b, prop))
198
- __defNormalProp$1(a, prop, b[prop]);
199
- if (__getOwnPropSymbols$1)
200
- for (var prop of __getOwnPropSymbols$1(b)) {
201
- if (__propIsEnum$1.call(b, prop))
202
- __defNormalProp$1(a, prop, b[prop]);
203
- }
204
- return a;
205
- };
206
- const ExtraCells = (event) => {
207
- var _a, _b;
208
- if (event.type === "log") {
209
- return /* @__PURE__ */ React__default["default"].createElement(React__default["default"].Fragment, null, /* @__PURE__ */ React__default["default"].createElement("td", null, event.severity), /* @__PURE__ */ React__default["default"].createElement("td", null, event.message.map((a) => JSON.stringify(a)).join(" ")));
210
- }
211
- if (event.type === "dataChange") {
212
- return /* @__PURE__ */ React__default["default"].createElement(React__default["default"].Fragment, null, /* @__PURE__ */ React__default["default"].createElement("td", null, event.binding), /* @__PURE__ */ React__default["default"].createElement("td", null, `${JSON.stringify(event.from)} \u279C ${JSON.stringify(event.to)}`));
213
- }
214
- if (event.type === "stateChange") {
215
- let name = event.state;
216
- if (event.state === "completed") {
217
- name = `${name} (${event.error ? "error" : "success"})`;
218
- }
219
- return /* @__PURE__ */ React__default["default"].createElement(React__default["default"].Fragment, null, /* @__PURE__ */ React__default["default"].createElement("td", null, name), /* @__PURE__ */ React__default["default"].createElement("td", null, (_b = (_a = event.outcome) != null ? _a : event.error) != null ? _b : ""));
220
- }
221
- if (event.type === "metric") {
222
- return /* @__PURE__ */ React__default["default"].createElement(React__default["default"].Fragment, null, /* @__PURE__ */ React__default["default"].createElement("td", null, event.metricType), /* @__PURE__ */ React__default["default"].createElement("td", null, event.message));
223
- }
224
- return null;
225
- };
226
- const EventsPanel = (props) => {
227
- const events = useEventState(props.api.getChannel());
228
- const darkMode = storybookDarkMode.useDarkMode();
229
- if (!props.active) {
230
- return null;
231
- }
232
- return /* @__PURE__ */ React__default["default"].createElement("div", {
233
- className: makeClass__default["default"](modules_2563542d.wrapper, {
234
- [modules_2563542d.dark]: darkMode
235
- })
236
- }, /* @__PURE__ */ React__default["default"].createElement(table.Table, {
237
- colorScheme: darkMode ? "dark" : "light"
238
- }, /* @__PURE__ */ React__default["default"].createElement(table.Head, {
239
- className: modules_2563542d.header
240
- }, /* @__PURE__ */ React__default["default"].createElement(table.Row, null, /* @__PURE__ */ React__default["default"].createElement(table.HeadCell, null, "Time"), /* @__PURE__ */ React__default["default"].createElement(table.HeadCell, null, "Type"), /* @__PURE__ */ React__default["default"].createElement(table.HeadCell, null), /* @__PURE__ */ React__default["default"].createElement(table.HeadCell, null))), /* @__PURE__ */ React__default["default"].createElement(table.Body, {
241
- className: modules_2563542d.body
242
- }, events.map((evt) => /* @__PURE__ */ React__default["default"].createElement(table.Row, {
243
- key: evt.id
244
- }, /* @__PURE__ */ React__default["default"].createElement(table.Cell, null, evt.time), /* @__PURE__ */ React__default["default"].createElement(table.Cell, null, evt.type), /* @__PURE__ */ React__default["default"].createElement(ExtraCells, __spreadValues$1({}, evt)))))));
245
- };
246
-
247
- const FlowRefresh = ({ api }) => {
248
- const actions = useStateActions(api.getChannel());
249
- return /* @__PURE__ */ React__default["default"].createElement(React__default["default"].Fragment, null, /* @__PURE__ */ React__default["default"].createElement(components.Separator, null), /* @__PURE__ */ React__default["default"].createElement(components.IconButton, {
250
- title: "Reset the current flow",
251
- onClick: () => {
252
- actions.resetFlow();
253
- }
254
- }, /* @__PURE__ */ React__default["default"].createElement(components.Icons, {
255
- icon: "sync"
256
- })));
257
- };
258
-
259
- const RenderSelection = ({ api: api$1 }) => {
260
- const params = api.useParameter("appetizeTokens", {});
261
- const actions = useStateActions(api$1.getChannel());
262
- const [selectedPlatform, setPlatform] = React__default["default"].useState("web");
263
- React__default["default"].useEffect(() => {
264
- const listener = () => {
265
- setPlatform("web");
266
87
  };
267
- api$1.getChannel().addListener(coreEvents.STORY_CHANGED, listener);
268
- return () => {
269
- api$1.getChannel().removeListener(coreEvents.STORY_CHANGED, listener);
88
+ var rejected = (value) => {
89
+ try {
90
+ step(generator.throw(value));
91
+ } catch (e) {
92
+ reject(e);
93
+ }
270
94
  };
271
- }, [api$1]);
272
- const mobilePlatforms = Object.keys(params);
273
- if (mobilePlatforms.length === 0) {
274
- return null;
275
- }
276
- return /* @__PURE__ */ React__default["default"].createElement(components.WithTooltip, {
277
- closeOnClick: true,
278
- placement: "top",
279
- trigger: "click",
280
- tooltip: ({ onHide }) => /* @__PURE__ */ React__default["default"].createElement(components.TooltipLinkList, {
281
- links: ["web", ...mobilePlatforms].map((platform) => ({
282
- id: platform,
283
- title: platform,
284
- onClick: () => {
285
- setPlatform(platform);
286
- actions.setPlatform(platform);
287
- onHide();
288
- },
289
- value: platform,
290
- active: platform === selectedPlatform
291
- }))
292
- })
293
- }, /* @__PURE__ */ React__default["default"].createElement(components.IconButton, {
294
- title: "Change the render target"
295
- }, /* @__PURE__ */ React__default["default"].createElement(components.Icons, {
296
- icon: selectedPlatform === "web" ? "browser" : "mobile"
297
- })));
95
+ var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
96
+ step((generator = generator.apply(__this, __arguments)).next());
97
+ });
298
98
  };
299
-
300
- function register() {
301
- addons__default["default"].register(ADDON_ID, (api) => {
302
- addons__default["default"].addPanel(EVENT_PANEL_ID, {
303
- title: "Events",
304
- render: ({ active, key }) => /* @__PURE__ */ React__default["default"].createElement(EventsPanel, {
305
- key,
306
- api,
307
- active: Boolean(active)
308
- })
309
- });
310
- addons__default["default"].addPanel(FLOW_PANEL_ID, {
311
- title: "Flow",
312
- render: ({ active, key }) => /* @__PURE__ */ React__default["default"].createElement(EditorPanel, {
313
- key,
314
- api,
315
- active: Boolean(active)
316
- })
317
- });
318
- addons__default["default"].add(FLOW_REFRESH_TOOL_ID, {
319
- title: "Refresh Flow",
320
- type: addons.types.TOOL,
321
- render: () => /* @__PURE__ */ React__default["default"].createElement(FlowRefresh, {
322
- api
323
- })
324
- });
325
- addons__default["default"].add(RENDER_SELECT_TOOL_ID, {
326
- title: "Render Selection",
327
- type: addons.types.TOOL,
328
- render: () => /* @__PURE__ */ React__default["default"].createElement(RenderSelection, {
329
- api
330
- })
99
+ const setup = (() => __async$2(undefined, null, function* () {
100
+ try {
101
+ yield browser.initialize({
102
+ worker: true,
103
+ wasmURL: "https://unpkg.com/esbuild-wasm@0.14.23/esbuild.wasm"
331
104
  });
332
- });
333
- }
334
-
335
- function useEditorFlow(initialFlow) {
336
- const stateActions = useStateActions(addons__default["default"].getChannel());
337
- const flow = useFlowState(addons__default["default"].getChannel());
338
- const docsContext = React__default["default"].useContext(addonDocs.DocsContext);
339
- React__default["default"].useEffect(() => {
340
- stateActions.setFlow(initialFlow);
341
- }, [initialFlow]);
342
- React__default["default"].useEffect(() => {
343
- if (!flow) {
344
- stateActions.setFlow(initialFlow);
345
- }
346
- }, [flow]);
347
- if (docsContext.id) {
348
- return initialFlow;
105
+ } catch (e) {
349
106
  }
350
- return flow != null ? flow : initialFlow;
351
- }
107
+ }))();
108
+ const execute = (code, options) => __async$2(undefined, null, function* () {
109
+ const { additionalModules = {} } = options != null ? options : {};
110
+ yield setup;
111
+ const result = yield browser.transform(code, {
112
+ loader: "tsx",
113
+ format: "cjs",
114
+ tsconfigRaw: {
115
+ compilerOptions: {}
116
+ }
117
+ });
118
+ const mods = __spreadValues$4({
119
+ react: React__namespace,
120
+ "@player-tools/dsl": PlayerDSL__namespace
121
+ }, additionalModules);
122
+ const mod = eval(`(function(require, module){ ${result.code}})`);
123
+ const exp = {};
124
+ const req = (name) => {
125
+ return mods[name];
126
+ };
127
+ mod(req, exp);
128
+ return exp.exports;
129
+ });
352
130
 
353
131
  const DEVICE_HEIGHT = {
354
132
  iphonexs: 845
@@ -385,13 +163,35 @@ const Appetize = (props) => {
385
163
  });
386
164
  };
387
165
 
166
+ var __defProp$3 = Object.defineProperty;
167
+ var __getOwnPropSymbols$3 = Object.getOwnPropertySymbols;
168
+ var __hasOwnProp$3 = Object.prototype.hasOwnProperty;
169
+ var __propIsEnum$3 = Object.prototype.propertyIsEnumerable;
170
+ var __defNormalProp$3 = (obj, key, value) => key in obj ? __defProp$3(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
171
+ var __spreadValues$3 = (a, b) => {
172
+ for (var prop in b || (b = {}))
173
+ if (__hasOwnProp$3.call(b, prop))
174
+ __defNormalProp$3(a, prop, b[prop]);
175
+ if (__getOwnPropSymbols$3)
176
+ for (var prop of __getOwnPropSymbols$3(b)) {
177
+ if (__propIsEnum$3.call(b, prop))
178
+ __defNormalProp$3(a, prop, b[prop]);
179
+ }
180
+ return a;
181
+ };
182
+ function createEvent(base) {
183
+ return __spreadValues$3({
184
+ id: uuid.v4(),
185
+ time: Date.now()
186
+ }, base);
187
+ }
188
+
388
189
  class StorybookPlayerPlugin {
389
- constructor(actions) {
190
+ constructor(dispatch) {
390
191
  this.name = "Storybook";
391
- this.actions = actions;
192
+ this.dispatch = dispatch;
392
193
  this.metricsPlugin = new metricsPluginReact.MetricsPlugin({
393
194
  onUpdate: (metrics) => {
394
- actions.setMetrics(metrics);
395
195
  },
396
196
  onRenderEnd: (timing) => {
397
197
  this.onMetricChange(timing, "render");
@@ -407,7 +207,7 @@ class StorybookPlayerPlugin {
407
207
  applyReact(rp) {
408
208
  rp.registerPlugin(this.metricsPlugin);
409
209
  rp.player.hooks.dataController.tap(this.name, (dc) => {
410
- this.actions.clearEvents();
210
+ this.dispatch(clearEvents());
411
211
  dc.hooks.onUpdate.tap(this.name, (dataUpdates) => {
412
212
  const events = dataUpdates.map((dataUpdate) => createEvent({
413
213
  type: "dataChange",
@@ -415,42 +215,42 @@ class StorybookPlayerPlugin {
415
215
  from: dataUpdate.oldValue,
416
216
  to: dataUpdate.newValue
417
217
  }));
418
- this.actions.addEvents(events);
218
+ this.dispatch(addEvents(events));
419
219
  });
420
220
  });
421
221
  rp.player.logger.hooks.log.tap(this.name, (severity, data) => {
422
- this.actions.addEvents([
222
+ this.dispatch(addEvents([
423
223
  createEvent({
424
224
  type: "log",
425
225
  message: data,
426
226
  severity
427
227
  })
428
- ]);
228
+ ]));
429
229
  });
430
230
  rp.player.hooks.state.tap(this.name, (newState) => {
431
231
  if ("error" in newState) {
432
- this.actions.addEvents([
232
+ this.dispatch(addEvents([
433
233
  createEvent({
434
234
  type: "stateChange",
435
235
  state: newState.status,
436
236
  error: newState.error.message
437
237
  })
438
- ]);
238
+ ]));
439
239
  } else if (newState.status === "completed") {
440
- this.actions.addEvents([
240
+ this.dispatch(addEvents([
441
241
  createEvent({
442
242
  type: "stateChange",
443
243
  state: newState.status,
444
244
  outcome: newState.endState.outcome
445
245
  })
446
- ]);
246
+ ]));
447
247
  } else {
448
- this.actions.addEvents([
248
+ this.dispatch(addEvents([
449
249
  createEvent({
450
250
  type: "stateChange",
451
251
  state: newState.status
452
252
  })
453
- ]);
253
+ ]));
454
254
  }
455
255
  });
456
256
  }
@@ -458,62 +258,96 @@ class StorybookPlayerPlugin {
458
258
  if (!timing.completed) {
459
259
  return;
460
260
  }
461
- this.actions.addEvents([
261
+ this.dispatch(addEvents([
462
262
  createEvent({
463
263
  type: "metric",
464
264
  metricType,
465
265
  message: `Duration: ${timing.duration.toFixed(0)} ms`
466
266
  })
467
- ]);
267
+ ]));
468
268
  }
469
269
  }
470
270
 
471
271
  const PlayerFlowSummary = (props) => {
472
- var _a;
272
+ var _a, _b, _c;
273
+ React.useEffect(() => {
274
+ var _a2, _b2;
275
+ const model = new player.LocalModel((_a2 = props.completedState) == null ? void 0 : _a2.data);
276
+ const parser = new player.BindingParser({
277
+ get: (binding) => model.get(binding)
278
+ });
279
+ window.__PLAYER_COMPLETED_DATA__ = {
280
+ completedState: props.completedState,
281
+ get: (path) => model.get(parser.parse(path)),
282
+ beacons: (_b2 = props.beacons) != null ? _b2 : []
283
+ };
284
+ return () => {
285
+ delete window.__PLAYER_COMPLETED_DATA__;
286
+ };
287
+ }, [props.completedState, props.beacons]);
473
288
  return /* @__PURE__ */ React__default["default"].createElement(react.VStack, {
474
289
  gap: "10"
475
- }, /* @__PURE__ */ React__default["default"].createElement(react.Heading, null, "Flow Completed ", props.error ? "with Error" : ""), props.outcome && /* @__PURE__ */ React__default["default"].createElement(react.Code, null, "Outcome: ", /* @__PURE__ */ React__default["default"].createElement(react.Text, {
290
+ }, /* @__PURE__ */ React__default["default"].createElement(react.Heading, null, "Flow Completed ", props.error ? "with Error" : ""), ((_a = props.completedState) == null ? void 0 : _a.endState.outcome) && /* @__PURE__ */ React__default["default"].createElement(react.Code, null, "Outcome:", " ", /* @__PURE__ */ React__default["default"].createElement(react.Text, {
476
291
  as: "strong"
477
- }, props.outcome)), props.error && /* @__PURE__ */ React__default["default"].createElement(react.Code, {
292
+ }, (_b = props.completedState) == null ? void 0 : _b.endState.outcome)), props.error && /* @__PURE__ */ React__default["default"].createElement(react.Code, {
478
293
  colorScheme: "red"
479
- }, /* @__PURE__ */ React__default["default"].createElement("pre", null, (_a = props.error) == null ? void 0 : _a.message)), /* @__PURE__ */ React__default["default"].createElement(react.Button, {
294
+ }, /* @__PURE__ */ React__default["default"].createElement("pre", null, (_c = props.error) == null ? void 0 : _c.message)), /* @__PURE__ */ React__default["default"].createElement(react.Button, {
480
295
  variant: "solid",
481
296
  onClick: props.reset
482
297
  }, "Reset"));
483
298
  };
484
299
 
485
- var __defProp = Object.defineProperty;
486
- var __defProps = Object.defineProperties;
487
- var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
488
- var __getOwnPropSymbols = Object.getOwnPropertySymbols;
489
- var __hasOwnProp = Object.prototype.hasOwnProperty;
490
- var __propIsEnum = Object.prototype.propertyIsEnumerable;
491
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
492
- var __spreadValues = (a, b) => {
300
+ const useFlowSetListener = (chan) => {
301
+ const dispatch = reactRedux.useDispatch();
302
+ React__default["default"].useEffect(() => {
303
+ const handler = (payload) => {
304
+ try {
305
+ const { flow } = JSON.parse(payload);
306
+ dispatch(setJSONEditorValue({ value: flow }));
307
+ } catch (e) {
308
+ console.error("Unable to set JSON payload from storybook event", e);
309
+ }
310
+ };
311
+ const eventName = "@@player/flow/set";
312
+ chan.addListener(eventName, handler);
313
+ return () => {
314
+ chan.removeListener(eventName, handler);
315
+ };
316
+ }, [chan]);
317
+ };
318
+
319
+ var __defProp$2 = Object.defineProperty;
320
+ var __defProps$1 = Object.defineProperties;
321
+ var __getOwnPropDescs$1 = Object.getOwnPropertyDescriptors;
322
+ var __getOwnPropSymbols$2 = Object.getOwnPropertySymbols;
323
+ var __hasOwnProp$2 = Object.prototype.hasOwnProperty;
324
+ var __propIsEnum$2 = Object.prototype.propertyIsEnumerable;
325
+ var __defNormalProp$2 = (obj, key, value) => key in obj ? __defProp$2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
326
+ var __spreadValues$2 = (a, b) => {
493
327
  for (var prop in b || (b = {}))
494
- if (__hasOwnProp.call(b, prop))
495
- __defNormalProp(a, prop, b[prop]);
496
- if (__getOwnPropSymbols)
497
- for (var prop of __getOwnPropSymbols(b)) {
498
- if (__propIsEnum.call(b, prop))
499
- __defNormalProp(a, prop, b[prop]);
328
+ if (__hasOwnProp$2.call(b, prop))
329
+ __defNormalProp$2(a, prop, b[prop]);
330
+ if (__getOwnPropSymbols$2)
331
+ for (var prop of __getOwnPropSymbols$2(b)) {
332
+ if (__propIsEnum$2.call(b, prop))
333
+ __defNormalProp$2(a, prop, b[prop]);
500
334
  }
501
335
  return a;
502
336
  };
503
- var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
337
+ var __spreadProps$1 = (a, b) => __defProps$1(a, __getOwnPropDescs$1(b));
504
338
  var __objRest = (source, exclude) => {
505
339
  var target = {};
506
340
  for (var prop in source)
507
- if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
341
+ if (__hasOwnProp$2.call(source, prop) && exclude.indexOf(prop) < 0)
508
342
  target[prop] = source[prop];
509
- if (source != null && __getOwnPropSymbols)
510
- for (var prop of __getOwnPropSymbols(source)) {
511
- if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
343
+ if (source != null && __getOwnPropSymbols$2)
344
+ for (var prop of __getOwnPropSymbols$2(source)) {
345
+ if (exclude.indexOf(prop) < 0 && __propIsEnum$2.call(source, prop))
512
346
  target[prop] = source[prop];
513
347
  }
514
348
  return target;
515
349
  };
516
- var __async = (__this, __arguments, generator) => {
350
+ var __async$1 = (__this, __arguments, generator) => {
517
351
  return new Promise((resolve, reject) => {
518
352
  var fulfilled = (value) => {
519
353
  try {
@@ -534,6 +368,7 @@ var __async = (__this, __arguments, generator) => {
534
368
  });
535
369
  };
536
370
  const ReactPlayerPluginContext = React__default["default"].createContext({ plugins: [] });
371
+ const DSLPluginContext = React__default["default"].createContext({});
537
372
  const PlayerRenderContext = React__default["default"].createContext({
538
373
  platform: "web"
539
374
  });
@@ -541,30 +376,30 @@ const StorybookControlsContext = React__default["default"].createContext({
541
376
  controls: {}
542
377
  });
543
378
  const PlayerOptionsContext = React__default["default"].createContext({ options: {} });
544
- const LocalPlayerStory = (props) => {
545
- var _a, _b;
546
- let flow = useEditorFlow(props.flow);
547
- const renderContext = React__default["default"].useContext(PlayerRenderContext);
548
- const pluginContext = React__default["default"].useContext(ReactPlayerPluginContext);
549
- const controlsContext = React__default["default"].useContext(StorybookControlsContext);
550
- const optionsContext = React__default["default"].useContext(PlayerOptionsContext);
551
- const options = __spreadValues({}, optionsContext == null ? void 0 : optionsContext.options);
552
- const stateActions = useStateActions(addons__default["default"].getChannel());
553
- const plugins = (_b = (_a = props.webPlugins) != null ? _a : pluginContext == null ? void 0 : pluginContext.plugins) != null ? _b : [];
379
+ const PlayerJsonEditorStory = () => {
380
+ const jsonEditorValue = useJSONEditorValue();
381
+ useFlowSetListener(addons__default["default"].getChannel());
382
+ const { plugins } = React__default["default"].useContext(ReactPlayerPluginContext);
383
+ const dispatch = reactRedux.useDispatch();
554
384
  const [playerState, setPlayerState] = React__default["default"].useState("not-started");
555
- const rp = React__default["default"].useMemo(() => {
556
- var _a2;
557
- return new react$1.ReactPlayer(__spreadProps(__spreadValues({}, options), {
558
- plugins: [
559
- new StorybookPlayerPlugin(stateActions),
560
- ...plugins,
561
- ...(_a2 = options == null ? void 0 : options.plugins) != null ? _a2 : []
562
- ]
563
- }));
564
- }, [plugins]);
385
+ const [trackedBeacons, setTrackedBeacons] = React__default["default"].useState([]);
386
+ const wp = React__default["default"].useMemo(() => {
387
+ const beaconPlugin = new beaconPluginReact.BeaconPlugin({
388
+ callback: (beacon) => {
389
+ setTrackedBeacons((t) => [...t, beacon]);
390
+ }
391
+ });
392
+ return new react$1.ReactPlayer({
393
+ plugins: [new StorybookPlayerPlugin(dispatch), beaconPlugin, ...plugins]
394
+ });
395
+ }, [dispatch, plugins]);
565
396
  const startFlow = () => {
397
+ if ((jsonEditorValue == null ? void 0 : jsonEditorValue.state) !== "loaded") {
398
+ return;
399
+ }
566
400
  setPlayerState("in-progress");
567
- rp.start(flow).then(() => {
401
+ setTrackedBeacons([]);
402
+ wp.start(jsonEditorValue.value).then(() => {
568
403
  setPlayerState("completed");
569
404
  }).catch((e) => {
570
405
  console.error("Error starting flow", e);
@@ -573,35 +408,13 @@ const LocalPlayerStory = (props) => {
573
408
  };
574
409
  React__default["default"].useEffect(() => {
575
410
  startFlow();
576
- }, [rp, flow]);
577
- React__default["default"].useEffect(() => {
578
- var _a2;
579
- if (controlsContext) {
580
- flow = __spreadProps(__spreadValues({}, flow), {
581
- data: __spreadValues(__spreadValues({}, (_a2 = flow.data) != null ? _a2 : {}), controlsContext)
582
- });
583
- stateActions.setFlow(flow);
584
- }
585
- }, [controlsContext]);
586
- React__default["default"].useEffect(() => {
587
- return subscribe(addons__default["default"].getChannel(), "@@player/flow/reset", () => {
588
- startFlow();
589
- });
590
- }, [rp, flow]);
591
- if (renderContext.platform !== "web" && renderContext.token) {
592
- return /* @__PURE__ */ React__default["default"].createElement(Appetize, {
593
- flow,
594
- platform: renderContext.platform,
595
- token: renderContext.token,
596
- baseUrl: renderContext.baseUrl,
597
- osVersions: renderContext.appetizeVersions
598
- });
599
- }
600
- const currentState = rp.player.getState();
411
+ }, [wp, jsonEditorValue]);
412
+ const currentState = wp.player.getState();
601
413
  if (playerState === "completed" && currentState.status === "completed") {
602
414
  return /* @__PURE__ */ React__default["default"].createElement(PlayerFlowSummary, {
603
415
  reset: startFlow,
604
- outcome: currentState.endState.outcome
416
+ completedState: currentState,
417
+ beacons: trackedBeacons
605
418
  });
606
419
  }
607
420
  if (playerState === "error" && currentState.status === "error") {
@@ -610,15 +423,44 @@ const LocalPlayerStory = (props) => {
610
423
  error: currentState.error
611
424
  });
612
425
  }
613
- return /* @__PURE__ */ React__default["default"].createElement(rp.Component, null);
426
+ return /* @__PURE__ */ React__default["default"].createElement(wp.Component, null);
614
427
  };
615
- function wrapInLazy(Component, flowFactory, other) {
616
- const asPlayer = () => __async(this, null, function* () {
617
- const mock = typeof flowFactory === "function" ? yield flowFactory() : flowFactory;
428
+ const LocalPlayerStory = (props) => {
429
+ var _a, _b;
430
+ const flow = useInitialJsonEditorValue(props.mock);
431
+ const platform = reactRedux.useSelector((state) => state.platform.platform);
432
+ const renderContext = React__default["default"].useContext(PlayerRenderContext);
433
+ const webPlayerContext = React__default["default"].useContext(ReactPlayerPluginContext);
434
+ const { options } = React__default["default"].useContext(PlayerOptionsContext);
435
+ if (platform === "web") {
436
+ return /* @__PURE__ */ React__default["default"].createElement(ReactPlayerPluginContext.Provider, {
437
+ value: props.webPlugins || (options == null ? void 0 : options.plugins) ? __spreadProps$1(__spreadValues$2({}, webPlayerContext), {
438
+ plugins: [
439
+ ...webPlayerContext.plugins,
440
+ ...(_a = props.webPlugins) != null ? _a : [],
441
+ ...(_b = options == null ? void 0 : options.plugins) != null ? _b : []
442
+ ]
443
+ }) : webPlayerContext
444
+ }, /* @__PURE__ */ React__default["default"].createElement(PlayerJsonEditorStory, null));
445
+ }
446
+ if (renderContext.platform !== "web" && renderContext.token && (flow == null ? void 0 : flow.state) === "loaded") {
447
+ return /* @__PURE__ */ React__default["default"].createElement(Appetize, {
448
+ flow: flow.value,
449
+ platform: renderContext.platform,
450
+ token: renderContext.token,
451
+ baseUrl: renderContext.baseUrl,
452
+ osVersions: renderContext.appetizeVersions
453
+ });
454
+ }
455
+ return /* @__PURE__ */ React__default["default"].createElement(components.Placeholder, null, "Unable to render flow");
456
+ };
457
+ function wrapInLazy(Component, mockFactory, other) {
458
+ const asPlayer = () => __async$1(this, null, function* () {
459
+ const mock = typeof mockFactory === "function" ? yield mockFactory() : mockFactory;
618
460
  const Comp = () => {
619
- const flow = __spreadValues(__spreadValues({}, makeFlow.makeFlow("default" in mock ? mock.default : mock)), other != null ? other : {});
461
+ const flow = __spreadValues$2(__spreadValues$2({}, makeFlow.makeFlow("default" in mock ? mock.default : mock)), other != null ? other : {});
620
462
  return /* @__PURE__ */ React__default["default"].createElement(Component, {
621
- flow
463
+ mock: flow
622
464
  });
623
465
  };
624
466
  return {
@@ -629,44 +471,621 @@ function wrapInLazy(Component, flowFactory, other) {
629
471
  }
630
472
  const PlayerStory = (props) => {
631
473
  const _a = props, { flow, storybookControls, options } = _a, other = __objRest(_a, ["flow", "storybookControls", "options"]);
474
+ useContentKind("json");
632
475
  const MockComp = React__default["default"].useMemo(() => wrapInLazy(LocalPlayerStory, flow, other), []);
633
- return /* @__PURE__ */ React__default["default"].createElement("div", null, /* @__PURE__ */ React__default["default"].createElement(react.ChakraProvider, null, /* @__PURE__ */ React__default["default"].createElement(React__default["default"].Suspense, {
634
- fallback: /* @__PURE__ */ React__default["default"].createElement(react.Spinner, null)
476
+ return /* @__PURE__ */ React__default["default"].createElement("div", null, /* @__PURE__ */ React__default["default"].createElement(React__default["default"].Suspense, {
477
+ fallback: "Loading..."
635
478
  }, /* @__PURE__ */ React__default["default"].createElement(StorybookControlsContext.Provider, {
636
- value: __spreadValues({}, storybookControls)
479
+ value: __spreadValues$2({}, storybookControls)
637
480
  }, /* @__PURE__ */ React__default["default"].createElement(PlayerOptionsContext.Provider, {
638
481
  value: {
639
482
  options
640
483
  }
641
- }, /* @__PURE__ */ React__default["default"].createElement(MockComp, null)), " "))));
484
+ }, /* @__PURE__ */ React__default["default"].createElement(MockComp, null)))));
485
+ };
486
+ const DSLLocalPlayerStory = (props) => {
487
+ const dslContext = React__default["default"].useContext(DSLPluginContext);
488
+ useContentKind("dsl");
489
+ useCompiledEditorValue(props.dslContent, {
490
+ additionalModules: dslContext == null ? void 0 : dslContext.additionalModules
491
+ });
492
+ return /* @__PURE__ */ React__default["default"].createElement(PlayerJsonEditorStory, null);
493
+ };
494
+ const DSLPlayerStory = (props) => {
495
+ const _a = props, { dslContent } = _a, other = __objRest(_a, ["dslContent"]);
496
+ const AsLazyComp = React__default["default"].useMemo(() => {
497
+ const loadFlow = () => __async$1(undefined, null, function* () {
498
+ let content = yield dslContent();
499
+ if (typeof content === "object") {
500
+ content = content.default;
501
+ }
502
+ return {
503
+ default: () => {
504
+ return /* @__PURE__ */ React__default["default"].createElement(DSLLocalPlayerStory, __spreadValues$2({
505
+ dslContent: content
506
+ }, other));
507
+ }
508
+ };
509
+ });
510
+ return React__default["default"].lazy(loadFlow);
511
+ }, [dslContent]);
512
+ return /* @__PURE__ */ React__default["default"].createElement(React__default["default"].Suspense, {
513
+ fallback: "Loading..."
514
+ }, /* @__PURE__ */ React__default["default"].createElement(AsLazyComp, null));
642
515
  };
643
516
 
644
- const PlayerDecorator = (story, ctx) => {
517
+ function createDSLStory(loader, options) {
518
+ const Comp = () => /* @__PURE__ */ React__default["default"].createElement(DSLPlayerStory, {
519
+ dslContent: loader
520
+ });
521
+ if (options == null ? void 0 : options.args) {
522
+ Comp.args = options.args;
523
+ }
524
+ return Comp;
525
+ }
526
+
527
+ var __defProp$1 = Object.defineProperty;
528
+ var __defProps = Object.defineProperties;
529
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
530
+ var __getOwnPropSymbols$1 = Object.getOwnPropertySymbols;
531
+ var __hasOwnProp$1 = Object.prototype.hasOwnProperty;
532
+ var __propIsEnum$1 = Object.prototype.propertyIsEnumerable;
533
+ var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
534
+ var __spreadValues$1 = (a, b) => {
535
+ for (var prop in b || (b = {}))
536
+ if (__hasOwnProp$1.call(b, prop))
537
+ __defNormalProp$1(a, prop, b[prop]);
538
+ if (__getOwnPropSymbols$1)
539
+ for (var prop of __getOwnPropSymbols$1(b)) {
540
+ if (__propIsEnum$1.call(b, prop))
541
+ __defNormalProp$1(a, prop, b[prop]);
542
+ }
543
+ return a;
544
+ };
545
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
546
+ var __async = (__this, __arguments, generator) => {
547
+ return new Promise((resolve, reject) => {
548
+ var fulfilled = (value) => {
549
+ try {
550
+ step(generator.next(value));
551
+ } catch (e) {
552
+ reject(e);
553
+ }
554
+ };
555
+ var rejected = (value) => {
556
+ try {
557
+ step(generator.throw(value));
558
+ } catch (e) {
559
+ reject(e);
560
+ }
561
+ };
562
+ var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
563
+ step((generator = generator.apply(__this, __arguments)).next());
564
+ });
565
+ };
566
+ const compiler = new PlayerDSL.DSLCompiler();
567
+ const resetEditor = toolkit.createAction("@@player/flow/reset");
568
+ const setDSLEditorValue = toolkit.createAction("setDSLEditorValue");
569
+ const setCompiledEditorResult = toolkit.createAction("setCompiledEditorResult");
570
+ const setEditorContentType = toolkit.createAction("setEditorContentType");
571
+ const setJSONEditorValue = toolkit.createAction("setJSONEditorValue");
572
+ const updateAndCompileDSLFlow = toolkit.createAsyncThunk("editor/dsl/compile", (context, thunkAPI) => __async(undefined, null, function* () {
645
573
  var _a;
646
- const playerParams = ctx.parameters;
647
- const [selectedPlatform, setPlatform] = React__default["default"].useState("web");
648
- React__default["default"].useEffect(() => {
649
- return subscribe(addons__default["default"].getChannel(), "@@player/platform/set", (evt) => {
650
- setPlatform(evt.platform);
574
+ const content = (_a = thunkAPI.getState().editor.dsl) == null ? void 0 : _a.value;
575
+ if (!content) {
576
+ throw new Error("No content to compile");
577
+ }
578
+ try {
579
+ const transpiledResult = yield execute(content, {
580
+ additionalModules: context.additionalModules
651
581
  });
582
+ if (transpiledResult) {
583
+ const compiled = yield compiler.serialize(transpiledResult.default);
584
+ thunkAPI.dispatch(setCompiledEditorResult({ result: compiled.value }));
585
+ }
586
+ } catch (e) {
587
+ thunkAPI.dispatch(setCompiledEditorResult({
588
+ errors: {
589
+ transpileErrors: [
590
+ {
591
+ message: e.message
592
+ }
593
+ ]
594
+ }
595
+ }));
596
+ }
597
+ }));
598
+ const setPlatform = toolkit.createAction("@@player/platform/set");
599
+ const unsetPlatform = toolkit.createAction("@@player/platform/unset");
600
+ const platformReducer = toolkit.createReducer({
601
+ platform: "web"
602
+ }, (builder) => {
603
+ builder.addCase(setPlatform, (state, action) => {
604
+ state.platform = action.payload.platform;
605
+ });
606
+ builder.addCase(unsetPlatform, (state) => {
607
+ state.platform = void 0;
608
+ });
609
+ });
610
+ const setCompilationErrors = toolkit.createAction("setCompilationErrors");
611
+ const flowEditorReducer = toolkit.createReducer({
612
+ json: { state: "initial" },
613
+ dsl: { state: "initial" },
614
+ contentType: void 0
615
+ }, (builder) => {
616
+ builder.addCase(setEditorContentType, (state, action) => {
617
+ state.contentType = action.payload.contentType;
618
+ if (action.payload.contentType === "json") {
619
+ state.dsl = { state: "initial" };
620
+ }
621
+ });
622
+ builder.addCase(setDSLEditorValue, (state, action) => {
623
+ state.dsl = {
624
+ state: "loaded",
625
+ value: action.payload.value,
626
+ needsCompile: true,
627
+ compilationErrors: void 0
628
+ };
629
+ });
630
+ builder.addCase(setCompilationErrors, (state, action) => {
631
+ var _a;
632
+ if (((_a = state.dsl) == null ? void 0 : _a.state) === "loaded") {
633
+ state.dsl.compilationErrors = action.payload;
634
+ }
635
+ });
636
+ builder.addCase(updateAndCompileDSLFlow.pending, (state) => {
637
+ state.json = { state: "loading" };
638
+ });
639
+ builder.addCase(resetEditor, (state) => {
640
+ state.json = { state: "initial" };
641
+ state.dsl = { state: "initial" };
642
+ });
643
+ builder.addCase(updateAndCompileDSLFlow.rejected, (state) => {
644
+ state.dsl = { state: "error" };
645
+ });
646
+ builder.addCase(setCompiledEditorResult, (state, action) => {
647
+ var _a;
648
+ if (((_a = state.dsl) == null ? void 0 : _a.state) === "loaded") {
649
+ state.dsl.needsCompile = false;
650
+ state.dsl.compilationErrors = action.payload.errors;
651
+ }
652
+ if (action.payload.result) {
653
+ state.json = { state: "loaded", value: action.payload.result };
654
+ }
655
+ });
656
+ builder.addCase(setJSONEditorValue, (state, action) => {
657
+ state.json = { state: "loaded", value: action.payload.value };
658
+ });
659
+ });
660
+ const addEvents = toolkit.createAction("@@player/events/add");
661
+ const clearEvents = toolkit.createAction("@@player/events/clear");
662
+ const eventsReducer = toolkit.createReducer([], (builder) => {
663
+ builder.addCase(addEvents, (state, action) => {
664
+ state.push(...action.payload);
665
+ });
666
+ builder.addCase(clearEvents, () => {
667
+ return [];
668
+ });
669
+ });
670
+ const STATE_SYNC_CHANNEL_NAME = (() => {
671
+ if (sessionStorage.getItem("player:channel")) {
672
+ return sessionStorage.getItem("player:channel");
673
+ }
674
+ const channel = Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
675
+ sessionStorage.setItem("player:channel", channel);
676
+ return channel;
677
+ })();
678
+ const store = toolkit.configureStore({
679
+ reducer: {
680
+ editor: flowEditorReducer,
681
+ platform: platformReducer,
682
+ events: eventsReducer
683
+ },
684
+ middleware: (getDefaultMiddleware) => {
685
+ return [
686
+ ...getDefaultMiddleware(),
687
+ reduxStateSync.createStateSyncMiddleware({
688
+ channel: STATE_SYNC_CHANNEL_NAME,
689
+ blacklist: [
690
+ "editor/dsl/compile/pending",
691
+ "editor/dsl/compile/fulfilled",
692
+ "editor/dsl/compile/rejected"
693
+ ]
694
+ })
695
+ ];
696
+ },
697
+ devTools: true
698
+ });
699
+ reduxStateSync.initStateWithPrevTab(store);
700
+ const StateProvider = (props) => {
701
+ return /* @__PURE__ */ React__default["default"].createElement(reactRedux.Provider, __spreadProps(__spreadValues$1({}, props), {
702
+ store
703
+ }));
704
+ };
705
+ const useJSONEditorValue = () => {
706
+ return reactRedux.useSelector((state) => {
707
+ return state.editor.json;
708
+ });
709
+ };
710
+ const useDSLEditorValue = () => {
711
+ const dslEditorValue = reactRedux.useSelector((state) => {
712
+ return state.editor.dsl;
713
+ });
714
+ return dslEditorValue;
715
+ };
716
+ const useContentKind = (contentTypeToSet) => {
717
+ const dispatch = reactRedux.useDispatch();
718
+ const contentType = reactRedux.useSelector((state) => {
719
+ return state.editor.contentType;
720
+ });
721
+ React__default["default"].useEffect(() => {
722
+ if (contentTypeToSet && contentTypeToSet !== contentType) {
723
+ dispatch(setEditorContentType({
724
+ contentType: contentTypeToSet
725
+ }));
726
+ }
727
+ }, [contentType, contentTypeToSet, dispatch]);
728
+ return contentType;
729
+ };
730
+ const useCompiledEditorValue = (initialValue, options) => {
731
+ useContentKind("dsl");
732
+ const dispatch = reactRedux.useDispatch();
733
+ const dslEditorValue = reactRedux.useSelector((s) => {
734
+ return s.editor.dsl;
735
+ });
736
+ React__default["default"].useEffect(() => {
737
+ store.dispatch(setDSLEditorValue({ value: initialValue }));
738
+ }, []);
739
+ React__default["default"].useEffect(() => {
740
+ if ((dslEditorValue == null ? void 0 : dslEditorValue.state) === "initial") {
741
+ dispatch(setDSLEditorValue({ value: initialValue }));
742
+ }
743
+ }, [dslEditorValue, initialValue]);
744
+ React__default["default"].useEffect(() => {
745
+ if ((dslEditorValue == null ? void 0 : dslEditorValue.state) === "loaded" && dslEditorValue.needsCompile) {
746
+ dispatch(updateAndCompileDSLFlow({
747
+ additionalModules: options == null ? void 0 : options.additionalModules
748
+ }));
749
+ }
750
+ }, [dslEditorValue, options == null ? void 0 : options.additionalModules]);
751
+ return dslEditorValue;
752
+ };
753
+ const useInitialJsonEditorValue = (initialValue) => {
754
+ const dispatch = reactRedux.useDispatch();
755
+ useContentKind("json");
756
+ const jsonEditorValue = reactRedux.useSelector((s) => {
757
+ return s.editor.json;
758
+ });
759
+ React__default["default"].useEffect(() => {
760
+ store.dispatch(setJSONEditorValue({ value: initialValue }));
652
761
  }, []);
762
+ React__default["default"].useEffect(() => {
763
+ if ((jsonEditorValue == null ? void 0 : jsonEditorValue.state) === "initial") {
764
+ dispatch(setJSONEditorValue({ value: initialValue }));
765
+ }
766
+ }, [jsonEditorValue, initialValue]);
767
+ return jsonEditorValue;
768
+ };
769
+
770
+ Editor.loader.init().then((m) => {
771
+ m.languages.typescript.typescriptDefaults.setCompilerOptions({
772
+ jsx: m.languages.typescript.JsxEmit.React
773
+ });
774
+ });
775
+ const JSONEditorPanel = () => {
776
+ const darkMode = storybookDarkMode.useDarkMode();
777
+ const jsonEditorValue = useJSONEditorValue();
778
+ const jsonValueAsString = (jsonEditorValue == null ? void 0 : jsonEditorValue.state) === "loaded" ? JSON.stringify(jsonEditorValue.value, null, 2) : "";
779
+ const dispatch = reactRedux.useDispatch();
780
+ const onChange = (val) => {
781
+ if (!val || (jsonEditorValue == null ? void 0 : jsonEditorValue.state) !== "loaded") {
782
+ return;
783
+ }
784
+ try {
785
+ const parsed = JSON.parse(val);
786
+ if (!deepEqual__default["default"](parsed, jsonEditorValue.value)) {
787
+ dispatch(setJSONEditorValue({
788
+ value: parsed
789
+ }));
790
+ }
791
+ } catch (e) {
792
+ }
793
+ };
794
+ return /* @__PURE__ */ React__default["default"].createElement(Editor__default["default"], {
795
+ theme: darkMode ? "dark" : "light",
796
+ value: jsonValueAsString,
797
+ language: "json",
798
+ options: {
799
+ formatOnPaste: true
800
+ },
801
+ onChange: (val) => {
802
+ onChange(val);
803
+ }
804
+ });
805
+ };
806
+ const CompileErrors = ({
807
+ errors
808
+ }) => {
809
+ var _a, _b;
810
+ if ((errors.compileErrors === void 0 || errors.compileErrors.length === 0) && (errors.transpileErrors === void 0 || errors.transpileErrors.length === 0)) {
811
+ return null;
812
+ }
813
+ return /* @__PURE__ */ React__default["default"].createElement("div", {
814
+ style: {
815
+ position: "absolute",
816
+ bottom: 0,
817
+ zIndex: 100,
818
+ background: "white",
819
+ padding: "8px",
820
+ border: "1px solid red",
821
+ color: "red",
822
+ width: "100%"
823
+ }
824
+ }, /* @__PURE__ */ React__default["default"].createElement("h3", null, "Errors"), (_a = errors.compileErrors) == null ? void 0 : _a.map((e) => /* @__PURE__ */ React__default["default"].createElement("pre", {
825
+ key: e.message
826
+ }, e.message)), (_b = errors.transpileErrors) == null ? void 0 : _b.map((e) => /* @__PURE__ */ React__default["default"].createElement("pre", {
827
+ key: e.message
828
+ }, e.message)));
829
+ };
830
+ const DSLEditorPanel = () => {
831
+ const darkMode = storybookDarkMode.useDarkMode();
832
+ const jsonEditorValue = useJSONEditorValue();
833
+ const dslEditorValue = useDSLEditorValue();
834
+ const dispatch = reactRedux.useDispatch();
835
+ const editorValue = (dslEditorValue == null ? void 0 : dslEditorValue.state) === "loaded" ? dslEditorValue.value : "";
836
+ const flow = (jsonEditorValue == null ? void 0 : jsonEditorValue.state) === "loaded" ? jsonEditorValue.value : "";
837
+ const compilationErrors = (dslEditorValue == null ? void 0 : dslEditorValue.state) === "loaded" ? dslEditorValue.compilationErrors : void 0;
838
+ const [selected, setSelected] = React__default["default"].useState("tsx");
839
+ const onChange = (val) => {
840
+ if (val) {
841
+ dispatch(setDSLEditorValue({
842
+ value: val
843
+ }));
844
+ }
845
+ };
846
+ return /* @__PURE__ */ React__default["default"].createElement("div", null, /* @__PURE__ */ React__default["default"].createElement(components.Tabs, {
847
+ selected,
848
+ actions: {
849
+ onSelect: (id) => {
850
+ setSelected(id);
851
+ }
852
+ }
853
+ }, /* @__PURE__ */ React__default["default"].createElement("div", {
854
+ id: "tsx",
855
+ title: "TSX"
856
+ }), /* @__PURE__ */ React__default["default"].createElement("div", {
857
+ id: "json",
858
+ title: "JSON (read-only)"
859
+ })), /* @__PURE__ */ React__default["default"].createElement("div", {
860
+ style: {
861
+ height: "calc(100% - 60px)"
862
+ }
863
+ }, selected === "tsx" && /* @__PURE__ */ React__default["default"].createElement(React__default["default"].Fragment, null, compilationErrors && /* @__PURE__ */ React__default["default"].createElement(CompileErrors, {
864
+ errors: compilationErrors
865
+ }), /* @__PURE__ */ React__default["default"].createElement(Editor__default["default"], {
866
+ theme: darkMode ? "dark" : "light",
867
+ value: editorValue,
868
+ language: "typescript",
869
+ onChange: (val) => {
870
+ onChange(val);
871
+ }
872
+ })), selected === "json" && /* @__PURE__ */ React__default["default"].createElement(Editor__default["default"], {
873
+ options: {
874
+ readOnly: true
875
+ },
876
+ theme: darkMode ? "dark" : "light",
877
+ value: flow ? JSON.stringify(flow, null, 2) : "{}",
878
+ language: "json"
879
+ })));
880
+ };
881
+ const EditorPanel = (props) => {
882
+ const contentType = useContentKind();
883
+ if (!props.active) {
884
+ return null;
885
+ }
886
+ if (contentType === "dsl") {
887
+ return /* @__PURE__ */ React__default["default"].createElement(DSLEditorPanel, null);
888
+ }
889
+ if (contentType === "json") {
890
+ return /* @__PURE__ */ React__default["default"].createElement(JSONEditorPanel, null);
891
+ }
892
+ return /* @__PURE__ */ React__default["default"].createElement(components.Placeholder, null, "This story is not configured to allow flow edits.");
893
+ };
894
+
895
+ var e=[],t=[];function n(n,r){if(n&&"undefined"!=typeof document){var a,s=!0===r.prepend?"prepend":"append",d=!0===r.singleTag,i="string"==typeof r.container?document.querySelector(r.container):document.getElementsByTagName("head")[0];if(d){var u=e.indexOf(i);-1===u&&(u=e.push(i)-1,t[u]={}),a=t[u]&&t[u][s]?t[u][s]:t[u][s]=c();}else a=c();65279===n.charCodeAt(0)&&(n=n.substring(1)),a.styleSheet?a.styleSheet.cssText+=n:a.appendChild(document.createTextNode(n));}function c(){var e=document.createElement("style");if(e.setAttribute("type","text/css"),r.attributes)for(var t=Object.keys(r.attributes),n=0;n<t.length;n++)e.setAttribute(t[n],r.attributes[t[n]]);var a="prepend"===s?"afterbegin":"beforeend";return i.insertAdjacentElement(a,e),e}}
896
+
897
+ var css = "\n.events_header__1bcc1085 td {\n width: 200px;\n}\n\n.events_body__1bcc1085 td {\n}\n";
898
+ var modules_2563542d = {"header":"events_header__1bcc1085","body":"events_body__1bcc1085"};
899
+ n(css,{});
900
+
901
+ var __defProp = Object.defineProperty;
902
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
903
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
904
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
905
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
906
+ var __spreadValues = (a, b) => {
907
+ for (var prop in b || (b = {}))
908
+ if (__hasOwnProp.call(b, prop))
909
+ __defNormalProp(a, prop, b[prop]);
910
+ if (__getOwnPropSymbols)
911
+ for (var prop of __getOwnPropSymbols(b)) {
912
+ if (__propIsEnum.call(b, prop))
913
+ __defNormalProp(a, prop, b[prop]);
914
+ }
915
+ return a;
916
+ };
917
+ const ExtraCells = (event) => {
918
+ var _a, _b;
919
+ if (event.type === "log") {
920
+ return /* @__PURE__ */ React__default["default"].createElement(React__default["default"].Fragment, null, /* @__PURE__ */ React__default["default"].createElement("td", null, event.severity), /* @__PURE__ */ React__default["default"].createElement("td", null, event.message.map((a) => JSON.stringify(a)).join(" ")));
921
+ }
922
+ if (event.type === "dataChange") {
923
+ return /* @__PURE__ */ React__default["default"].createElement(React__default["default"].Fragment, null, /* @__PURE__ */ React__default["default"].createElement("td", null, event.binding), /* @__PURE__ */ React__default["default"].createElement("td", null, `${JSON.stringify(event.from)} \u279C ${JSON.stringify(event.to)}`));
924
+ }
925
+ if (event.type === "stateChange") {
926
+ let name = event.state;
927
+ if (event.state === "completed") {
928
+ name = `${name} (${event.error ? "error" : "success"})`;
929
+ }
930
+ return /* @__PURE__ */ React__default["default"].createElement(React__default["default"].Fragment, null, /* @__PURE__ */ React__default["default"].createElement("td", null, name), /* @__PURE__ */ React__default["default"].createElement("td", null, (_b = (_a = event.outcome) != null ? _a : event.error) != null ? _b : ""));
931
+ }
932
+ if (event.type === "metric") {
933
+ return /* @__PURE__ */ React__default["default"].createElement(React__default["default"].Fragment, null, /* @__PURE__ */ React__default["default"].createElement("td", null, event.metricType), /* @__PURE__ */ React__default["default"].createElement("td", null, event.message));
934
+ }
935
+ return null;
936
+ };
937
+ const EventsPanel = (props) => {
938
+ const events = reactRedux.useSelector((state) => state.events);
939
+ const darkMode = storybookDarkMode.useDarkMode();
940
+ const contentType = useContentKind();
941
+ if (!props.active) {
942
+ return null;
943
+ }
944
+ if (contentType === void 0) {
945
+ return /* @__PURE__ */ React__default["default"].createElement(components.Placeholder, null, "This story is not configured to receive Player events.");
946
+ }
947
+ return /* @__PURE__ */ React__default["default"].createElement("div", {
948
+ className: makeClass__default["default"](modules_2563542d.wrapper, {
949
+ [modules_2563542d.dark]: darkMode
950
+ })
951
+ }, /* @__PURE__ */ React__default["default"].createElement(table.Table, {
952
+ colorScheme: darkMode ? "dark" : "light"
953
+ }, /* @__PURE__ */ React__default["default"].createElement(table.Head, {
954
+ className: modules_2563542d.header
955
+ }, /* @__PURE__ */ React__default["default"].createElement(table.Row, null, /* @__PURE__ */ React__default["default"].createElement(table.HeadCell, null, "Time"), /* @__PURE__ */ React__default["default"].createElement(table.HeadCell, null, "Type"), /* @__PURE__ */ React__default["default"].createElement(table.HeadCell, null), /* @__PURE__ */ React__default["default"].createElement(table.HeadCell, null))), /* @__PURE__ */ React__default["default"].createElement(table.Body, {
956
+ className: modules_2563542d.body
957
+ }, events.map((evt) => /* @__PURE__ */ React__default["default"].createElement(table.Row, {
958
+ key: evt.id
959
+ }, /* @__PURE__ */ React__default["default"].createElement(table.Cell, null, evt.time), /* @__PURE__ */ React__default["default"].createElement(table.Cell, null, evt.type), /* @__PURE__ */ React__default["default"].createElement(ExtraCells, __spreadValues({}, evt)))))));
960
+ };
961
+
962
+ const FlowRefresh = () => {
963
+ const dispatch = reactRedux.useDispatch();
964
+ return /* @__PURE__ */ React__default["default"].createElement(React__default["default"].Fragment, null, /* @__PURE__ */ React__default["default"].createElement(components.Separator, null), /* @__PURE__ */ React__default["default"].createElement(components.IconButton, {
965
+ title: "Reset the current flow",
966
+ onClick: () => {
967
+ dispatch(resetEditor());
968
+ }
969
+ }, /* @__PURE__ */ React__default["default"].createElement(components.Icons, {
970
+ icon: "sync"
971
+ })));
972
+ };
973
+
974
+ const RenderSelection = ({ api: api$1 }) => {
975
+ const params = api.useParameter("appetizeTokens", {});
976
+ const dispatch = reactRedux.useDispatch();
977
+ const selectedPlatform = reactRedux.useSelector((state) => {
978
+ var _a;
979
+ return (_a = state.platform.platform) != null ? _a : "web";
980
+ });
981
+ React__default["default"].useEffect(() => {
982
+ const listener = () => {
983
+ dispatch(setPlatform({ platform: "web" }));
984
+ };
985
+ api$1.getChannel().addListener(coreEvents.STORY_CHANGED, listener);
986
+ return () => {
987
+ api$1.getChannel().removeListener(coreEvents.STORY_CHANGED, listener);
988
+ };
989
+ }, [api$1, dispatch]);
990
+ const mobilePlatforms = Object.keys(params);
991
+ if (mobilePlatforms.length === 0) {
992
+ return null;
993
+ }
994
+ return /* @__PURE__ */ React__default["default"].createElement(components.WithTooltip, {
995
+ closeOnClick: true,
996
+ placement: "top",
997
+ trigger: "click",
998
+ tooltip: ({ onHide }) => /* @__PURE__ */ React__default["default"].createElement(components.TooltipLinkList, {
999
+ links: ["web", ...mobilePlatforms].map((platform) => ({
1000
+ id: platform,
1001
+ title: platform,
1002
+ onClick: () => {
1003
+ setPlatform(platform);
1004
+ dispatch(setPlatform({ platform }));
1005
+ onHide();
1006
+ },
1007
+ value: platform,
1008
+ active: platform === selectedPlatform
1009
+ }))
1010
+ })
1011
+ }, /* @__PURE__ */ React__default["default"].createElement(components.IconButton, {
1012
+ title: "Change the render target"
1013
+ }, /* @__PURE__ */ React__default["default"].createElement(components.Icons, {
1014
+ icon: selectedPlatform === "web" ? "browser" : "mobile"
1015
+ })));
1016
+ };
1017
+
1018
+ function register() {
1019
+ addons__default["default"].register(ADDON_ID, (api) => {
1020
+ addons__default["default"].addPanel(EVENT_PANEL_ID, {
1021
+ title: "Events",
1022
+ render: ({ active, key }) => /* @__PURE__ */ React__default["default"].createElement(StateProvider, {
1023
+ key
1024
+ }, /* @__PURE__ */ React__default["default"].createElement(EventsPanel, {
1025
+ active: Boolean(active)
1026
+ }))
1027
+ });
1028
+ addons__default["default"].addPanel(FLOW_PANEL_ID, {
1029
+ title: "Flow",
1030
+ render: ({ active, key }) => /* @__PURE__ */ React__default["default"].createElement(StateProvider, {
1031
+ key
1032
+ }, /* @__PURE__ */ React__default["default"].createElement(EditorPanel, {
1033
+ active: Boolean(active)
1034
+ }))
1035
+ });
1036
+ addons__default["default"].add(FLOW_REFRESH_TOOL_ID, {
1037
+ title: "Refresh Flow",
1038
+ type: addons.types.TOOL,
1039
+ render: () => /* @__PURE__ */ React__default["default"].createElement(StateProvider, null, /* @__PURE__ */ React__default["default"].createElement(FlowRefresh, null))
1040
+ });
1041
+ addons__default["default"].add(RENDER_SELECT_TOOL_ID, {
1042
+ title: "Render Selection",
1043
+ type: addons.types.TOOL,
1044
+ render: () => /* @__PURE__ */ React__default["default"].createElement(StateProvider, null, /* @__PURE__ */ React__default["default"].createElement(RenderSelection, {
1045
+ api
1046
+ }))
1047
+ });
1048
+ });
1049
+ }
1050
+
1051
+ const PlayerRenderContextWrapper = (props) => {
1052
+ var _a;
1053
+ const { playerParams } = props;
1054
+ const platform = reactRedux.useSelector((s) => {
1055
+ var _a2;
1056
+ return (_a2 = s.platform.platform) != null ? _a2 : "web";
1057
+ });
653
1058
  return /* @__PURE__ */ React__default["default"].createElement(PlayerRenderContext.Provider, {
654
1059
  value: {
655
- platform: selectedPlatform,
656
- token: selectedPlatform === "web" ? void 0 : (_a = playerParams == null ? void 0 : playerParams.appetizeTokens) == null ? void 0 : _a[selectedPlatform],
1060
+ platform,
1061
+ token: platform === "web" ? void 0 : (_a = playerParams == null ? void 0 : playerParams.appetizeTokens) == null ? void 0 : _a[platform],
657
1062
  baseUrl: playerParams.appetizeBaseUrl,
658
1063
  appetizeVersions: playerParams.appetizeVersions
659
1064
  }
1065
+ }, props.children);
1066
+ };
1067
+ const PlayerDecorator = (story, ctx) => {
1068
+ var _a, _b;
1069
+ const playerParams = ctx.parameters;
1070
+ return /* @__PURE__ */ React__default["default"].createElement(StateProvider, null, /* @__PURE__ */ React__default["default"].createElement(PlayerRenderContextWrapper, {
1071
+ playerParams
660
1072
  }, /* @__PURE__ */ React__default["default"].createElement(ReactPlayerPluginContext.Provider, {
661
- value: { plugins: playerParams.reactPlayerPlugins }
662
- }, story()));
1073
+ value: { plugins: (_a = playerParams.reactPlayerPlugins) != null ? _a : [] }
1074
+ }, /* @__PURE__ */ React__default["default"].createElement(DSLPluginContext.Provider, {
1075
+ value: (_b = playerParams.dslEditor) != null ? _b : {}
1076
+ }, story()))));
663
1077
  };
664
1078
 
1079
+ exports.DSLLocalPlayerStory = DSLLocalPlayerStory;
1080
+ exports.DSLPlayerStory = DSLPlayerStory;
1081
+ exports.DSLPluginContext = DSLPluginContext;
665
1082
  exports.PlayerDecorator = PlayerDecorator;
666
1083
  exports.PlayerOptionsContext = PlayerOptionsContext;
667
1084
  exports.PlayerRenderContext = PlayerRenderContext;
668
1085
  exports.PlayerStory = PlayerStory;
669
1086
  exports.ReactPlayerPluginContext = ReactPlayerPluginContext;
670
1087
  exports.StorybookControlsContext = StorybookControlsContext;
1088
+ exports.createDSLStory = createDSLStory;
1089
+ exports.execute = execute;
671
1090
  exports.register = register;
672
1091
  //# sourceMappingURL=index.cjs.js.map