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