@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.
Files changed (51) hide show
  1. package/dist/cjs/index.cjs +664 -0
  2. package/dist/cjs/index.cjs.map +1 -0
  3. package/dist/index.legacy-esm.js +611 -0
  4. package/dist/index.mjs +611 -0
  5. package/dist/index.mjs.map +1 -0
  6. package/package.json +30 -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 +129 -0
  13. package/src/asset/index.tsx +10 -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,114 @@
1
+ import React from "react";
2
+ import { ReactAsset, usePlayer } from "../..";
3
+ import type {
4
+ ReactPlayer,
5
+ ReactPlayerPlugin,
6
+ Asset,
7
+ AssetWrapper,
8
+ Flow,
9
+ } from "../..";
10
+
11
+ interface SimpleAsset extends Asset<"simple"> {
12
+ /** text value of the asset */
13
+ value?: string;
14
+ }
15
+
16
+ /** basic aset */
17
+ const SimpleAsset = (props: SimpleAsset) => (
18
+ <div id={props.id}>{props.value}</div>
19
+ );
20
+
21
+ interface ActionAsset extends Asset<"action"> {
22
+ /** label of the action */
23
+ label: string;
24
+
25
+ /** value of the action */
26
+ value: string;
27
+
28
+ /** expression of the action */
29
+ exp: string;
30
+ }
31
+
32
+ /** basic action asset */
33
+ const Action = (props: ActionAsset) => {
34
+ const player = usePlayer();
35
+
36
+ return (
37
+ <button
38
+ type="button"
39
+ id={props.id}
40
+ onClick={() => {
41
+ const state = player?.getState();
42
+
43
+ if (state?.status === "in-progress") {
44
+ if (props.exp) {
45
+ state.controllers.expression.evaluate(props.exp);
46
+ }
47
+
48
+ if (props.value) {
49
+ state.controllers.flow.transition(props.value);
50
+ }
51
+ }
52
+ }}
53
+ >
54
+ {props.label}
55
+ </button>
56
+ );
57
+ };
58
+
59
+ interface CollectionAsset extends Asset<"collection"> {
60
+ /** values in a collection */
61
+ values: Array<AssetWrapper<any>>;
62
+ }
63
+
64
+ /** basic collection asset */
65
+ const Collection = (props: CollectionAsset) => {
66
+ return (
67
+ <div id={props.id}>
68
+ {props.values.map((a) => (
69
+ <ReactAsset key={a.asset.id} {...a.asset} />
70
+ ))}
71
+ </div>
72
+ );
73
+ };
74
+
75
+ export const simpleFlow: Flow<any> = {
76
+ id: "flow_1",
77
+ views: [
78
+ {
79
+ id: "first_view",
80
+ type: "simple",
81
+ value: "{{foo.bar}}",
82
+ },
83
+ ],
84
+ navigation: {
85
+ BEGIN: "flow_1",
86
+ flow_1: {
87
+ startState: "view_1",
88
+ view_1: {
89
+ state_type: "VIEW",
90
+ ref: "first_view",
91
+ transitions: {
92
+ "*": "end_1",
93
+ },
94
+ },
95
+ end_1: {
96
+ state_type: "END",
97
+ outcome: "end",
98
+ },
99
+ },
100
+ },
101
+ };
102
+
103
+ /**
104
+ * Registers a simple asset as a react comp
105
+ */
106
+ export class SimpleAssetPlugin implements ReactPlayerPlugin {
107
+ name = "simple-asset-plugin";
108
+
109
+ applyReact(rp: ReactPlayer) {
110
+ rp.assetRegistry.set({ type: "simple" }, SimpleAsset);
111
+ rp.assetRegistry.set({ type: "action" }, Action);
112
+ rp.assetRegistry.set({ type: "collection" }, Collection);
113
+ }
114
+ }
@@ -0,0 +1,8 @@
1
+ import { test, expect } from "vitest";
2
+ import { renderHook } from "@testing-library/react-hooks";
3
+ import { useReactPlayer } from "..";
4
+
5
+ test("reactPlayer hook", () => {
6
+ const { result } = renderHook(() => useReactPlayer());
7
+ expect(result.current.reactPlayer).toBeDefined();
8
+ });
package/src/app.tsx CHANGED
@@ -1,6 +1,6 @@
1
- import React from 'react';
2
- import type { View } from '@player-ui/player';
3
- import { ReactAsset } from './asset';
1
+ import React from "react";
2
+ import type { View } from "@player-ui/player";
3
+ import { ReactAsset } from "./asset";
4
4
 
5
5
  export interface ReactPlayerProps {
6
6
  /**
@@ -0,0 +1,129 @@
1
+ import { test, expect } from "vitest";
2
+ import React from "react";
3
+ import { render } from "@testing-library/react";
4
+ import { Registry } from "@player-ui/partial-match-registry";
5
+ import type { Asset as AssetType } from "@player-ui/player";
6
+ import type { AssetRegistryType } from "..";
7
+ import { ReactAsset, AssetContext } from "..";
8
+
9
+ test("it prioritizes local type and id", () => {
10
+ const assetDef = {
11
+ id: "foo",
12
+ type: "foo",
13
+ asset: {
14
+ id: "bar",
15
+ type: "bar",
16
+ },
17
+ };
18
+
19
+ const registry: AssetRegistryType = new Registry([
20
+ [{ type: "foo" }, () => <div>foo</div>],
21
+ [{ type: "bar" }, () => <div>bar</div>],
22
+ ]);
23
+
24
+ const asset = render(
25
+ <AssetContext.Provider value={{ registry }}>
26
+ <ReactAsset {...assetDef} />
27
+ </AssetContext.Provider>,
28
+ );
29
+
30
+ expect(asset.getByText("foo")).not.toBeUndefined();
31
+ });
32
+
33
+ test("throws an error for an asset missing implementation", () => {
34
+ const assetDef = {
35
+ asset: {
36
+ id: "bar-id",
37
+ type: "bar",
38
+ },
39
+ } as unknown as AssetType;
40
+
41
+ const registry: AssetRegistryType = new Registry([
42
+ [{ type: "foo" }, () => <div>foo</div>],
43
+ ]);
44
+
45
+ expect(() =>
46
+ render(
47
+ <AssetContext.Provider value={{ registry }}>
48
+ <ReactAsset {...assetDef} />
49
+ </AssetContext.Provider>,
50
+ ),
51
+ ).toThrowError("No implementation found for id: bar-id type: bar");
52
+ });
53
+
54
+ test("throws an error for an asset missing type", () => {
55
+ const assetDef = {
56
+ asset: {
57
+ id: "bar-id",
58
+ },
59
+ } as unknown as AssetType;
60
+
61
+ const registry: AssetRegistryType = new Registry([
62
+ [{ type: "foo" }, () => <div>foo</div>],
63
+ [{ type: "bar" }, () => <div>bar</div>],
64
+ ]);
65
+
66
+ expect(() =>
67
+ render(
68
+ <AssetContext.Provider value={{ registry }}>
69
+ <ReactAsset {...assetDef} />
70
+ </AssetContext.Provider>,
71
+ ),
72
+ ).toThrowError("Asset is missing type for id: bar-id");
73
+ });
74
+
75
+ test("throws an error for an asset that isnt an object", () => {
76
+ const assetDef = {
77
+ asset: "bar",
78
+ } as unknown as AssetType;
79
+
80
+ const registry: AssetRegistryType = new Registry([
81
+ [{ type: "foo" }, () => <div>foo</div>],
82
+ [{ type: "bar" }, () => <div>bar</div>],
83
+ ]);
84
+
85
+ expect(() =>
86
+ render(
87
+ <AssetContext.Provider value={{ registry }}>
88
+ <ReactAsset {...assetDef} />
89
+ </AssetContext.Provider>,
90
+ ),
91
+ ).toThrowError("Asset was not an object got (string) instead: bar");
92
+ });
93
+
94
+ test("throws an error for an asset that is an object but not valid", () => {
95
+ const assetDef = {
96
+ asset: ["a"],
97
+ } as unknown as AssetType;
98
+
99
+ const registry: AssetRegistryType = new Registry([
100
+ [{ type: "foo" }, () => <div>foo</div>],
101
+ [{ type: "bar" }, () => <div>bar</div>],
102
+ ]);
103
+
104
+ expect(() =>
105
+ render(
106
+ <AssetContext.Provider value={{ registry }}>
107
+ <ReactAsset {...assetDef} />
108
+ </AssetContext.Provider>,
109
+ ),
110
+ ).toThrowError('Asset is missing type for {"asset":["a"]}');
111
+ });
112
+ test("throws an error for an asset that unwraps nothing", () => {
113
+ const assetDef = {
114
+ asset: undefined,
115
+ } as unknown as AssetType;
116
+
117
+ const registry: AssetRegistryType = new Registry([
118
+ [{ type: "foo" }, () => <div>foo</div>],
119
+ [{ type: "bar" }, () => <div>bar</div>],
120
+ ]);
121
+
122
+ expect(() =>
123
+ render(
124
+ <AssetContext.Provider value={{ registry }}>
125
+ <ReactAsset {...assetDef} />
126
+ </AssetContext.Provider>,
127
+ ),
128
+ ).toThrowError("Cannot determine asset type for props: {}");
129
+ });
@@ -1,6 +1,6 @@
1
- import React from 'react';
2
- import type { Asset as AssetType, AssetWrapper } from '@player-ui/player';
3
- import type { Registry } from '@player-ui/partial-match-registry';
1
+ import React from "react";
2
+ import type { Asset as AssetType, AssetWrapper } from "@player-ui/player";
3
+ import type { Registry } from "@player-ui/partial-match-registry";
4
4
 
5
5
  export type AssetRegistryType = Registry<React.ComponentType<any>>;
6
6
 
@@ -17,27 +17,27 @@ export const AssetContext = React.createContext<ContextType>({});
17
17
  * A React Component that looks up an implementation from a registry
18
18
  */
19
19
  export const ReactAsset = (
20
- props: AssetType<string> | AssetWrapper<AssetType<string>>
20
+ props: AssetType<string> | AssetWrapper<AssetType<string>>,
21
21
  ) => {
22
22
  const { registry } = React.useContext(AssetContext);
23
23
 
24
24
  let unwrapped;
25
25
 
26
- if ('type' in props && 'id' in props) {
26
+ if ("type" in props && "id" in props) {
27
27
  unwrapped = props;
28
- } else if ('asset' in props) {
28
+ } else if ("asset" in props) {
29
29
  unwrapped = (props as unknown as AssetWrapper).asset;
30
30
  }
31
31
 
32
32
  if (!unwrapped) {
33
33
  throw Error(
34
- `Cannot determine asset type for props: ${JSON.stringify(props)}`
34
+ `Cannot determine asset type for props: ${JSON.stringify(props)}`,
35
35
  );
36
36
  }
37
37
 
38
- if (typeof unwrapped !== 'object') {
38
+ if (typeof unwrapped !== "object") {
39
39
  throw Error(
40
- `Asset was not an object got (${typeof unwrapped}) instead: ${unwrapped}`
40
+ `Asset was not an object got (${typeof unwrapped}) instead: ${unwrapped}`,
41
41
  );
42
42
  }
43
43
 
@@ -53,7 +53,7 @@ export const ReactAsset = (
53
53
 
54
54
  if (!Impl) {
55
55
  throw Error(
56
- `No implementation found for id: ${unwrapped.id} type: ${unwrapped.type}`
56
+ `No implementation found for id: ${unwrapped.id} type: ${unwrapped.type}`,
57
57
  );
58
58
  }
59
59
 
package/src/hooks.tsx CHANGED
@@ -1,9 +1,9 @@
1
- import type { Player, PlayerFlowState } from '@player-ui/player';
2
- import { NOT_STARTED_STATE } from '@player-ui/player';
3
- import React from 'react';
4
- import type { ReactPlayerOptions } from './player';
5
- import { ReactPlayer } from './player';
6
- import { StateTapPlugin } from './plugins/tapstate-plugin';
1
+ import type { Player, PlayerFlowState } from "@player-ui/player";
2
+ import { NOT_STARTED_STATE } from "@player-ui/player";
3
+ import React from "react";
4
+ import type { ReactPlayerOptions } from "./player";
5
+ import { ReactPlayer } from "./player";
6
+ import { StateTapPlugin } from "./plugins/tapstate-plugin";
7
7
 
8
8
  export interface UseReactPlayerReturn {
9
9
  /** The web-player instance */
@@ -19,7 +19,7 @@ export interface UseReactPlayerReturn {
19
19
  * Simply supply your config, plugins, and an optional flow, which will be automatically started for you when changed.
20
20
  */
21
21
  export const useReactPlayer = (
22
- options?: ReactPlayerOptions
22
+ options?: ReactPlayerOptions,
23
23
  ): UseReactPlayerReturn => {
24
24
  const [playerState, setPlayerState] =
25
25
  React.useState<PlayerFlowState>(NOT_STARTED_STATE);
@@ -31,7 +31,6 @@ export const useReactPlayer = (
31
31
  ...(options?.plugins ?? []),
32
32
  new StateTapPlugin(setPlayerState),
33
33
  ],
34
- suspend: options?.suspend,
35
34
  });
36
35
 
37
36
  return rp;
package/src/index.tsx CHANGED
@@ -1,8 +1,8 @@
1
- export * from '@player-ui/player';
2
- export * from './player';
3
- export * from './hooks';
4
- export * from './manager/managed-player';
5
- export * from './manager/request-time';
6
- export * from './manager/types';
7
- export * from './asset';
8
- export * from './utils';
1
+ export * from "@player-ui/player";
2
+ export * from "./player";
3
+ export * from "./hooks";
4
+ export * from "./manager/managed-player";
5
+ export * from "./manager/request-time";
6
+ export * from "./manager/types";
7
+ export * from "./asset";
8
+ export * from "./utils";