@player-ui/react 0.8.0--canary.307.9621 → 0.8.0--canary.410.15865

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.
Files changed (51) hide show
  1. package/dist/cjs/index.cjs +686 -0
  2. package/dist/cjs/index.cjs.map +1 -0
  3. package/dist/index.legacy-esm.js +633 -0
  4. package/dist/index.mjs +633 -0
  5. package/dist/index.mjs.map +1 -0
  6. package/package.json +31 -64
  7. package/src/__tests__/__snapshots__/app.test.tsx.snap +139 -0
  8. package/src/__tests__/app.test.tsx +244 -0
  9. package/src/__tests__/helpers/simple-asset-plugin.tsx +114 -0
  10. package/src/__tests__/hooks.test.tsx +8 -0
  11. package/src/app.tsx +3 -3
  12. package/src/asset/__tests__/index.test.tsx +158 -0
  13. package/src/asset/index.tsx +31 -10
  14. package/src/hooks.tsx +7 -8
  15. package/src/index.tsx +8 -8
  16. package/src/manager/__tests__/managed-player.test.tsx +454 -0
  17. package/src/manager/managed-player.tsx +31 -36
  18. package/src/manager/request-time.tsx +8 -8
  19. package/src/manager/types.ts +12 -12
  20. package/src/player.tsx +24 -43
  21. package/src/plugins/onupdate-plugin.ts +3 -3
  22. package/src/plugins/tapstate-plugin.ts +4 -4
  23. package/src/utils/__tests__/helpers.test.ts +39 -0
  24. package/src/utils/__tests__/url.test.ts +14 -0
  25. package/src/utils/helpers.ts +15 -12
  26. package/src/utils/index.tsx +6 -6
  27. package/src/utils/player-context.ts +2 -2
  28. package/src/utils/shared-constants.tsx +2 -2
  29. package/src/utils/url.ts +2 -2
  30. package/src/utils/use-asset-props.tsx +2 -2
  31. package/src/utils/use-logger.ts +3 -3
  32. package/types/app.d.ts +14 -0
  33. package/types/asset/index.d.ts +16 -0
  34. package/types/hooks.d.ts +17 -0
  35. package/types/index.d.ts +9 -0
  36. package/types/manager/managed-player.d.ts +93 -0
  37. package/types/manager/request-time.d.ts +7 -0
  38. package/types/manager/types.d.ts +125 -0
  39. package/types/player.d.ts +86 -0
  40. package/types/plugins/onupdate-plugin.d.ts +12 -0
  41. package/types/plugins/tapstate-plugin.d.ts +12 -0
  42. package/types/utils/helpers.d.ts +17 -0
  43. package/types/utils/index.d.ts +7 -0
  44. package/types/utils/player-context.d.ts +16 -0
  45. package/types/utils/shared-constants.d.ts +5 -0
  46. package/types/utils/url.d.ts +5 -0
  47. package/types/utils/use-asset-props.d.ts +7 -0
  48. package/types/utils/use-logger.d.ts +6 -0
  49. package/dist/index.cjs.js +0 -690
  50. package/dist/index.d.ts +0 -397
  51. package/dist/index.esm.js +0 -658
@@ -0,0 +1,686 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
21
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
22
+ // If the importer is in node compatibility mode or this is not an ESM
23
+ // file that has been converted to a CommonJS file using a Babel-
24
+ // compatible transform (i.e. "__esModule" has not been set), then set
25
+ // "default" to the CommonJS "module.exports" for node compatibility.
26
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
27
+ mod
28
+ ));
29
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
30
+
31
+ // ../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/react/player/src/index.tsx
32
+ var src_exports = {};
33
+ __export(src_exports, {
34
+ AssetContext: () => AssetContext,
35
+ ManagedPlayer: () => ManagedPlayer,
36
+ PlayerContext: () => PlayerContext,
37
+ ReactAsset: () => ReactAsset,
38
+ ReactPlayer: () => ReactPlayer2,
39
+ WebPlayer: () => WebPlayer,
40
+ buildUrl: () => buildUrl,
41
+ callOrReturn: () => callOrReturn,
42
+ isEmptyObject: () => isEmptyObject,
43
+ isFunction: () => isFunction,
44
+ removeEmptyValuesFromObject: () => removeEmptyValuesFromObject,
45
+ trimSlashes: () => trimSlashes,
46
+ useAssetProps: () => useAssetProps,
47
+ useGetConstant: () => useGetConstant,
48
+ useGetConstantByType: () => useGetConstantByType,
49
+ useLogger: () => useLogger,
50
+ usePersistentStateMachine: () => usePersistentStateMachine,
51
+ usePlayer: () => usePlayer,
52
+ useReactPlayer: () => useReactPlayer,
53
+ useRequestTime: () => useRequestTime
54
+ });
55
+ module.exports = __toCommonJS(src_exports);
56
+ __reExport(src_exports, require("@player-ui/player"), module.exports);
57
+
58
+ // ../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/react/player/src/player.tsx
59
+ var import_react4 = __toESM(require("react"));
60
+ var import_tapable_ts = require("tapable-ts");
61
+ var import_react_subscribe = require("@player-ui/react-subscribe");
62
+ var import_partial_match_registry = require("@player-ui/partial-match-registry");
63
+ var import_player2 = require("@player-ui/player");
64
+ var import_react_error_boundary = require("react-error-boundary");
65
+
66
+ // ../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/react/player/src/asset/index.tsx
67
+ var import_react = __toESM(require("react"));
68
+ var import_fuse = __toESM(require("fuse.js"));
69
+ var AssetContext = import_react.default.createContext({});
70
+ var ReactAsset = (props) => {
71
+ const { registry } = import_react.default.useContext(AssetContext);
72
+ let unwrapped;
73
+ if ("type" in props && "id" in props) {
74
+ unwrapped = props;
75
+ } else if ("asset" in props) {
76
+ unwrapped = props.asset;
77
+ }
78
+ if (!unwrapped) {
79
+ throw Error(
80
+ `Cannot determine asset type for props: ${JSON.stringify(props)}`
81
+ );
82
+ }
83
+ if (typeof unwrapped !== "object") {
84
+ throw Error(
85
+ `Asset was not an object got (${typeof unwrapped}) instead: ${unwrapped}`
86
+ );
87
+ }
88
+ if (unwrapped.type === void 0) {
89
+ const info = unwrapped.id === void 0 ? JSON.stringify(props) : `id: ${unwrapped.id}`;
90
+ throw Error(`Asset is missing type for ${info}`);
91
+ }
92
+ if (!registry || registry.isRegistryEmpty()) {
93
+ throw Error(`No asset found in registry. This could happen for one of the following reasons:
94
+
95
+ 1. You might have no assets registered or no plugins added to the Player instance.
96
+
97
+ 2. You might have mismatching versions of React Asset Registry Context.
98
+
99
+ See https://player-ui.github.io/latest/tools/cli#player-dependency-versions-check for tips about how to debug and fix this problem`);
100
+ }
101
+ const Impl = registry?.get(unwrapped);
102
+ if (!Impl) {
103
+ const matchList = [];
104
+ registry.forEach((asset) => {
105
+ matchList.push(asset.key);
106
+ });
107
+ const fuse = new import_fuse.default(matchList, { keys: ["type", "key"] });
108
+ const similarType = JSON.stringify(
109
+ fuse.search(unwrapped.type)[0].item
110
+ );
111
+ throw Error(
112
+ `No implementation found for id: ${unwrapped.id} type: ${unwrapped.type}. Did you mean ${similarType}?
113
+
114
+ Registered Asset matching functions are listed below:
115
+
116
+ ${JSON.stringify(matchList)}`
117
+ );
118
+ }
119
+ return /* @__PURE__ */ import_react.default.createElement(Impl, { key: unwrapped.id, ...unwrapped });
120
+ };
121
+
122
+ // ../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/react/player/src/utils/player-context.ts
123
+ var import_react2 = __toESM(require("react"));
124
+ var PlayerContext = import_react2.default.createContext({});
125
+ var usePlayer = () => {
126
+ const { player } = import_react2.default.useContext(PlayerContext);
127
+ return player;
128
+ };
129
+
130
+ // ../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/react/player/src/utils/use-logger.ts
131
+ var import_player = require("@player-ui/player");
132
+ var noopLogger = new import_player.NoopLogger();
133
+ function useLogger() {
134
+ const player = usePlayer();
135
+ return player?.logger ?? noopLogger;
136
+ }
137
+
138
+ // ../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/react/player/src/utils/use-asset-props.tsx
139
+ function useAssetProps(asset) {
140
+ return {
141
+ id: asset.id,
142
+ "data-asset-type": asset.type
143
+ };
144
+ }
145
+
146
+ // ../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/react/player/src/utils/helpers.ts
147
+ function trimSlashes(str) {
148
+ return str.replace(/^\/+|\/+$/g, "");
149
+ }
150
+ function removeEmptyValuesFromObject(obj) {
151
+ return Object.keys(obj).reduce(
152
+ (acc, key) => {
153
+ const value = obj[key];
154
+ if (value !== null && value !== void 0) {
155
+ acc[key] = value;
156
+ }
157
+ return acc;
158
+ },
159
+ {}
160
+ );
161
+ }
162
+ function isEmptyObject(obj) {
163
+ return Object.keys(obj).length === 0 && obj.constructor === Object;
164
+ }
165
+ function isFunction(maybeFn) {
166
+ return Boolean(maybeFn instanceof Function || typeof maybeFn === "function");
167
+ }
168
+ function callOrReturn(maybeFn, fnArgs) {
169
+ if (isFunction(maybeFn)) {
170
+ return maybeFn(fnArgs);
171
+ }
172
+ return maybeFn;
173
+ }
174
+
175
+ // ../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/react/player/src/utils/url.ts
176
+ function buildUrl(url, params = {}) {
177
+ const baseUrl = new URL(url);
178
+ if (params && isEmptyObject(params)) {
179
+ return baseUrl.toString();
180
+ }
181
+ Object.keys(params).forEach((key) => {
182
+ const value = params[key];
183
+ baseUrl.searchParams.append(key, String(value));
184
+ });
185
+ return baseUrl.toString();
186
+ }
187
+
188
+ // ../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/react/player/src/utils/shared-constants.tsx
189
+ function useGetConstantByType(type, key) {
190
+ const player = usePlayer();
191
+ return player?.constantsController.getConstants(key, type);
192
+ }
193
+ function useGetConstant(key) {
194
+ const player = usePlayer();
195
+ return player?.constantsController.getConstants(key, "constants");
196
+ }
197
+
198
+ // ../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/react/player/src/app.tsx
199
+ var import_react3 = __toESM(require("react"));
200
+ var ReactPlayer = ({ view }) => {
201
+ return /* @__PURE__ */ import_react3.default.createElement(ReactAsset, { ...view });
202
+ };
203
+ var app_default = ReactPlayer;
204
+
205
+ // ../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/react/player/src/plugins/onupdate-plugin.ts
206
+ var OnUpdatePlugin = class {
207
+ constructor(onUpdate) {
208
+ this.name = "view-update";
209
+ this.onUpdateCallback = onUpdate;
210
+ }
211
+ apply(player) {
212
+ const updateTap = (updatedView) => {
213
+ this.onUpdateCallback(updatedView);
214
+ };
215
+ const viewTap = (view) => {
216
+ view.hooks.onUpdate.tap(this.name, updateTap);
217
+ };
218
+ player.hooks.view.tap(this.name, viewTap);
219
+ const currentPlayerState = player.getState();
220
+ if (currentPlayerState.status === "in-progress") {
221
+ const { currentView } = currentPlayerState.controllers.view;
222
+ if (currentView) {
223
+ viewTap(currentView);
224
+ const { lastUpdate } = currentView;
225
+ if (lastUpdate) {
226
+ this.onUpdateCallback(lastUpdate);
227
+ }
228
+ }
229
+ }
230
+ }
231
+ };
232
+
233
+ // ../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/react/player/src/player.tsx
234
+ var WEB_PLAYER_VERSION = "__VERSION__";
235
+ var COMMIT = "__GIT_COMMIT__";
236
+ var _window = typeof window === "undefined" ? void 0 : window;
237
+ var ReactPlayer2 = class {
238
+ constructor(options) {
239
+ this.assetRegistry = new import_partial_match_registry.Registry();
240
+ this.hooks = {
241
+ /**
242
+ * A hook to create a React Component to be used for Player, regardless of the current flow state
243
+ */
244
+ webComponent: new import_tapable_ts.SyncWaterfallHook(),
245
+ /**
246
+ * A hook to create a React Component that's used to render a specific view.
247
+ * It will be called for each view update from the core player.
248
+ * Typically this will just be `Asset`
249
+ */
250
+ playerComponent: new import_tapable_ts.SyncWaterfallHook(),
251
+ /**
252
+ * A hook to execute async tasks before the view resets to undefined
253
+ */
254
+ onBeforeViewReset: new import_tapable_ts.AsyncParallelHook()
255
+ };
256
+ this.viewUpdateSubscription = new import_react_subscribe.Subscribe();
257
+ this.options = options ?? {};
258
+ const Devtools = _window?.__PLAYER_DEVTOOLS_PLUGIN;
259
+ const onUpdatePlugin = new OnUpdatePlugin(
260
+ this.viewUpdateSubscription.publish
261
+ );
262
+ const plugins = options?.plugins ?? [];
263
+ if (Devtools) {
264
+ plugins.push(new Devtools());
265
+ }
266
+ const playerPlugins = plugins.filter(
267
+ (p) => Boolean(p.apply)
268
+ );
269
+ this.player = options?.player ?? new import_player2.Player({ plugins: playerPlugins });
270
+ plugins.forEach((plugin) => {
271
+ if (plugin.applyReact) {
272
+ plugin.applyReact(this);
273
+ }
274
+ });
275
+ onUpdatePlugin.apply(this.player);
276
+ this.Component = this.createReactPlayerComponent();
277
+ this.reactPlayerInfo = {
278
+ playerVersion: this.player.getVersion(),
279
+ playerCommit: this.player.getCommit(),
280
+ reactPlayerVersion: WEB_PLAYER_VERSION,
281
+ reactPlayerCommit: COMMIT
282
+ };
283
+ }
284
+ /** Returns the current version of the underlying core Player */
285
+ getPlayerVersion() {
286
+ return this.reactPlayerInfo.playerVersion;
287
+ }
288
+ /** Returns the git commit used to build this core Player version */
289
+ getPlayerCommit() {
290
+ return this.reactPlayerInfo.playerCommit;
291
+ }
292
+ /** Find instance of [Plugin] that has been registered to the web player */
293
+ findPlugin(symbol) {
294
+ return this.options.plugins?.find((el) => el.symbol === symbol);
295
+ }
296
+ /** Register and apply [Plugin] if one with the same symbol is not already registered. */
297
+ registerPlugin(plugin) {
298
+ if (!plugin.applyReact)
299
+ return;
300
+ plugin.applyReact(this);
301
+ this.options.plugins?.push(plugin);
302
+ }
303
+ /** Returns the current version of the running React Player */
304
+ getReactPlayerVersion() {
305
+ return this.reactPlayerInfo.reactPlayerVersion;
306
+ }
307
+ /** Returns the git commit used to build the React Player version */
308
+ getReactPlayerCommit() {
309
+ return this.reactPlayerInfo.reactPlayerCommit;
310
+ }
311
+ createReactPlayerComponent() {
312
+ const BaseComp = this.hooks.webComponent.call(this.createReactComp());
313
+ const ReactPlayerComponent = (props) => {
314
+ return /* @__PURE__ */ import_react4.default.createElement(
315
+ import_react_error_boundary.ErrorBoundary,
316
+ {
317
+ fallbackRender: () => null,
318
+ onError: (err) => {
319
+ const playerState = this.player.getState();
320
+ if (playerState.status === "in-progress") {
321
+ playerState.fail(err);
322
+ }
323
+ }
324
+ },
325
+ /* @__PURE__ */ import_react4.default.createElement(PlayerContext.Provider, { value: { player: this.player } }, /* @__PURE__ */ import_react4.default.createElement(BaseComp, { ...props }))
326
+ );
327
+ };
328
+ return ReactPlayerComponent;
329
+ }
330
+ createReactComp() {
331
+ const ActualPlayerComp = this.hooks.playerComponent.call(app_default);
332
+ const WebPlayerComponent = () => {
333
+ const view = (0, import_react_subscribe.useSubscribedState)(this.viewUpdateSubscription);
334
+ this.viewUpdateSubscription.suspend();
335
+ return /* @__PURE__ */ import_react4.default.createElement(
336
+ AssetContext.Provider,
337
+ {
338
+ value: {
339
+ registry: this.assetRegistry
340
+ }
341
+ },
342
+ view && /* @__PURE__ */ import_react4.default.createElement(ActualPlayerComp, { view })
343
+ );
344
+ };
345
+ return WebPlayerComponent;
346
+ }
347
+ /**
348
+ * Call this method to force the ReactPlayer to wait for the next view-update before performing the next render.
349
+ * If the `suspense` option is set, this will suspend while an update is pending, otherwise nothing will be rendered.
350
+ */
351
+ setWaitForNextViewUpdate() {
352
+ const shouldCallResetHook = this.hooks.onBeforeViewReset.isUsed();
353
+ return this.viewUpdateSubscription.reset(
354
+ shouldCallResetHook ? this.hooks.onBeforeViewReset.call() : void 0
355
+ );
356
+ }
357
+ start(flow) {
358
+ this.setWaitForNextViewUpdate();
359
+ return this.player.start(flow).finally(async () => {
360
+ await this.setWaitForNextViewUpdate();
361
+ });
362
+ }
363
+ };
364
+ var WebPlayer = ReactPlayer2;
365
+
366
+ // ../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/react/player/src/hooks.tsx
367
+ var import_player3 = require("@player-ui/player");
368
+ var import_react5 = __toESM(require("react"));
369
+
370
+ // ../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/react/player/src/plugins/tapstate-plugin.ts
371
+ var StateTapPlugin = class {
372
+ constructor(callback) {
373
+ this.name = "statetap";
374
+ this.callbackFunction = callback;
375
+ }
376
+ apply(player) {
377
+ player.hooks.state.tap("usePlayer", (newPlayerState) => {
378
+ this.callbackFunction(newPlayerState);
379
+ });
380
+ }
381
+ };
382
+
383
+ // ../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/react/player/src/hooks.tsx
384
+ var useReactPlayer = (options) => {
385
+ const [playerState, setPlayerState] = import_react5.default.useState(import_player3.NOT_STARTED_STATE);
386
+ const reactPlayer = import_react5.default.useMemo(() => {
387
+ const rp = new ReactPlayer2({
388
+ player: options?.player,
389
+ plugins: [
390
+ ...options?.plugins ?? [],
391
+ new StateTapPlugin(setPlayerState)
392
+ ]
393
+ });
394
+ return rp;
395
+ }, []);
396
+ const { player } = reactPlayer;
397
+ return {
398
+ reactPlayer,
399
+ player,
400
+ playerState
401
+ };
402
+ };
403
+
404
+ // ../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/react/player/src/manager/managed-player.tsx
405
+ var import_react7 = __toESM(require("react"));
406
+
407
+ // ../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/react/player/src/manager/request-time.tsx
408
+ var import_react6 = require("react");
409
+ var import_metrics_plugin = require("@player-ui/metrics-plugin");
410
+ var useRequestTime = () => {
411
+ const requestTimeRef = (0, import_react6.useRef)({});
412
+ (0, import_react6.useEffect)(() => {
413
+ return () => {
414
+ requestTimeRef.current = {};
415
+ };
416
+ }, [requestTimeRef]);
417
+ const getRequestTime = (0, import_react6.useCallback)(() => {
418
+ const { end, start } = requestTimeRef.current;
419
+ if (end && start) {
420
+ return end - start;
421
+ }
422
+ }, [requestTimeRef]);
423
+ function withRequestTime(nextPromise) {
424
+ const getTime = typeof performance === "undefined" ? Date : performance;
425
+ requestTimeRef.current = { start: getTime.now() };
426
+ return nextPromise.finally(() => {
427
+ requestTimeRef.current = {
428
+ ...requestTimeRef.current,
429
+ end: getTime.now()
430
+ };
431
+ });
432
+ }
433
+ const RequestTimeMetricsPlugin = (0, import_react6.useMemo)(() => {
434
+ return {
435
+ name: "RequestTimeMetricsPlugin",
436
+ apply(player) {
437
+ player.applyTo(
438
+ import_metrics_plugin.MetricsCorePluginSymbol,
439
+ (metricsCorePlugin) => {
440
+ new import_metrics_plugin.RequestTimeWebPlugin(getRequestTime).apply(metricsCorePlugin);
441
+ }
442
+ );
443
+ }
444
+ };
445
+ }, [getRequestTime]);
446
+ return { withRequestTime, RequestTimeMetricsPlugin };
447
+ };
448
+
449
+ // ../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/react/player/src/manager/managed-player.tsx
450
+ function identityMiddleware(next) {
451
+ return next;
452
+ }
453
+ var ManagedState = class {
454
+ constructor({
455
+ middleware
456
+ }) {
457
+ this.middleware = middleware;
458
+ this.callbacks = [];
459
+ }
460
+ /** Add a listener to state changes */
461
+ addListener(callback) {
462
+ this.callbacks.push(callback);
463
+ return () => {
464
+ this.callbacks = this.callbacks.filter((s) => s !== callback);
465
+ };
466
+ }
467
+ /** start the managed flow */
468
+ start(options) {
469
+ const initialState = {
470
+ value: "not_started",
471
+ context: {
472
+ playerConfig: options.playerConfig,
473
+ reactPlayer: new ReactPlayer2(options.playerConfig),
474
+ manager: options.manager
475
+ }
476
+ };
477
+ this.setState(initialState);
478
+ return this;
479
+ }
480
+ /** reset starts from nothing */
481
+ reset() {
482
+ if (this.state?.value === "error") {
483
+ const { playerConfig, manager } = this.state.context;
484
+ this.start({ playerConfig, manager });
485
+ } else {
486
+ throw new Error("Flow must be in error state to reset");
487
+ }
488
+ }
489
+ /** restart starts from the last result */
490
+ restart() {
491
+ if (this.state?.value === "error") {
492
+ const { playerConfig, manager, prevResult, reactPlayer } = this.state.context;
493
+ this.setState({
494
+ value: "completed",
495
+ context: {
496
+ playerConfig,
497
+ manager,
498
+ result: prevResult,
499
+ reactPlayer
500
+ }
501
+ });
502
+ } else {
503
+ throw new Error("Flow must be in error state to restart");
504
+ }
505
+ }
506
+ async setState(state) {
507
+ this.state = state;
508
+ this.callbacks.forEach((c) => {
509
+ c.onState(state);
510
+ });
511
+ const { manager, reactPlayer, playerConfig } = state.context;
512
+ try {
513
+ const nextState = await this.processState(state, {
514
+ manager,
515
+ reactPlayer,
516
+ playerConfig
517
+ });
518
+ if (nextState) {
519
+ this.setState(nextState);
520
+ }
521
+ } catch (e) {
522
+ this.setState({
523
+ value: "error",
524
+ context: {
525
+ manager,
526
+ reactPlayer,
527
+ playerConfig,
528
+ error: e
529
+ }
530
+ });
531
+ }
532
+ }
533
+ async processState(state, context) {
534
+ if (state.value === "not_started" || state.value === "completed") {
535
+ const prevResult = state.value === "completed" ? state.context.result : void 0;
536
+ const middleware = this.middleware?.next ?? identityMiddleware;
537
+ return {
538
+ value: "pending",
539
+ context: {
540
+ ...context,
541
+ prevResult,
542
+ next: middleware(state.context.manager.next(prevResult))
543
+ }
544
+ };
545
+ }
546
+ if (state.value === "pending") {
547
+ const nextResult = await state.context.next;
548
+ if (nextResult.done) {
549
+ return {
550
+ value: "ended",
551
+ context: {
552
+ ...context,
553
+ result: state.context.prevResult
554
+ }
555
+ };
556
+ }
557
+ return {
558
+ value: "loaded",
559
+ context: {
560
+ ...context,
561
+ prevResult: state.context.prevResult,
562
+ flow: nextResult.value
563
+ }
564
+ };
565
+ }
566
+ if (state.value === "loaded") {
567
+ return {
568
+ value: "running",
569
+ context: {
570
+ ...context,
571
+ flow: state.context.flow,
572
+ prevResult: state.context.prevResult,
573
+ result: state.context.reactPlayer.start(state.context.flow)
574
+ }
575
+ };
576
+ }
577
+ if (state.value === "running") {
578
+ const result = await state.context.result;
579
+ return {
580
+ value: "completed",
581
+ context: {
582
+ ...context,
583
+ result
584
+ }
585
+ };
586
+ }
587
+ }
588
+ };
589
+ var managedPlayerStateMachines = /* @__PURE__ */ new WeakMap();
590
+ var usePersistentStateMachine = (options) => {
591
+ const keyRef = import_react7.default.useRef({
592
+ _key: Symbol("managed-player")
593
+ });
594
+ const managedState = managedPlayerStateMachines.get(keyRef.current) ?? new ManagedState({ middleware: options.middleware });
595
+ managedPlayerStateMachines.set(keyRef.current, managedState);
596
+ const [state, setState] = import_react7.default.useState(managedState.state);
597
+ import_react7.default.useEffect(() => {
598
+ const unsub = managedState.addListener({
599
+ onState: (s) => {
600
+ setState(s);
601
+ }
602
+ });
603
+ if (managedState.state === void 0) {
604
+ managedState.start(options);
605
+ }
606
+ return unsub;
607
+ }, []);
608
+ return { managedState, state };
609
+ };
610
+ var ManagedPlayer = (props) => {
611
+ const { withRequestTime, RequestTimeMetricsPlugin } = useRequestTime();
612
+ const { state, managedState } = usePersistentStateMachine({
613
+ manager: props.manager,
614
+ middleware: { next: withRequestTime },
615
+ playerConfig: {
616
+ plugins: [...props?.plugins ?? [], RequestTimeMetricsPlugin],
617
+ player: props.player
618
+ }
619
+ });
620
+ import_react7.default.useEffect(() => {
621
+ if (state?.value === "ended") {
622
+ props.onComplete?.(state?.context.result);
623
+ } else if (state?.value === "error") {
624
+ props.onError?.(state?.context.error);
625
+ } else if (state?.value === "running") {
626
+ props.onStartedFlow?.();
627
+ }
628
+ }, [state]);
629
+ import_react7.default.useEffect(() => {
630
+ return () => {
631
+ const playerState = state?.context.reactPlayer.player.getState();
632
+ if (state?.value === "running" && playerState?.status === "in-progress") {
633
+ props.manager.terminate?.(playerState.controllers.data.serialize());
634
+ }
635
+ };
636
+ }, [props.manager, state?.context.reactPlayer.player, state?.value]);
637
+ if (state?.value === "error") {
638
+ if (props.fallbackComponent) {
639
+ return /* @__PURE__ */ import_react7.default.createElement(
640
+ props.fallbackComponent,
641
+ {
642
+ reset: () => {
643
+ managedState.reset();
644
+ },
645
+ retry: () => {
646
+ managedState.restart();
647
+ },
648
+ error: state.context.error
649
+ }
650
+ );
651
+ }
652
+ if (!props.onError) {
653
+ throw state.context.error;
654
+ }
655
+ }
656
+ if (state?.context.reactPlayer) {
657
+ const { Component } = state.context.reactPlayer;
658
+ return /* @__PURE__ */ import_react7.default.createElement(Component, null);
659
+ }
660
+ return null;
661
+ };
662
+ // Annotate the CommonJS export names for ESM import in node:
663
+ 0 && (module.exports = {
664
+ AssetContext,
665
+ ManagedPlayer,
666
+ PlayerContext,
667
+ ReactAsset,
668
+ ReactPlayer,
669
+ WebPlayer,
670
+ buildUrl,
671
+ callOrReturn,
672
+ isEmptyObject,
673
+ isFunction,
674
+ removeEmptyValuesFromObject,
675
+ trimSlashes,
676
+ useAssetProps,
677
+ useGetConstant,
678
+ useGetConstantByType,
679
+ useLogger,
680
+ usePersistentStateMachine,
681
+ usePlayer,
682
+ useReactPlayer,
683
+ useRequestTime,
684
+ ...require("@player-ui/player")
685
+ });
686
+ //# sourceMappingURL=index.cjs.map