@player-ui/reference-assets-plugin 0.13.0-next.5 → 0.13.0-next.6
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/ReferenceAssetsPlugin.native.js +506 -5
- package/dist/ReferenceAssetsPlugin.native.js.map +1 -1
- package/dist/cjs/index.cjs +101 -1
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/index.legacy-esm.js +104 -1
- package/dist/index.mjs +104 -1
- package/dist/index.mjs.map +1 -1
- package/dist/xlr/ActionAsset.json +2 -2
- package/dist/xlr/ChatMessageAsset.json +1 -1
- package/dist/xlr/ChoiceAsset.json +5 -5
- package/dist/xlr/CollectionAsset.json +1 -1
- package/dist/xlr/ImageAsset.json +2 -2
- package/dist/xlr/InfoAsset.json +1 -1
- package/dist/xlr/InputAsset.json +2 -2
- package/dist/xlr/TextAsset.json +4 -4
- package/dist/xlr/send.json +40 -0
- package/package.json +7 -5
- package/src/__tests__/plugin.test.ts +287 -0
- package/src/assets/chat-message/transform.ts +0 -1
- package/src/plugin.ts +18 -46
- package/src/plugins/chat-ui-demo-plugin.ts +101 -0
- package/src/plugins/index.ts +2 -0
- package/src/plugins/reference-assets-transform-plugin.ts +51 -0
- package/src/plugins/send.ts +3 -0
- package/types/plugin.d.ts +3 -13
- package/types/plugins/chat-ui-demo-plugin.d.ts +7 -0
- package/types/plugins/index.d.ts +3 -0
- package/types/plugins/reference-assets-transform-plugin.d.ts +17 -0
- package/types/plugins/send.d.ts +3 -0
package/dist/xlr/InputAsset.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"source": "/home/circleci/.cache/bazel/_bazel_circleci/e8362d362e14c7d23506d1dfa3aea8b8/sandbox/processwrapper-sandbox/
|
|
2
|
+
"source": "/home/circleci/.cache/bazel/_bazel_circleci/e8362d362e14c7d23506d1dfa3aea8b8/sandbox/processwrapper-sandbox/4555/execroot/_main/bazel-out/k8-fastbuild/bin/plugins/reference-assets/core/src/assets/input/types.ts",
|
|
3
3
|
"name": "InputAsset",
|
|
4
4
|
"type": "object",
|
|
5
5
|
"properties": {
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
"beacon": {
|
|
51
51
|
"required": false,
|
|
52
52
|
"node": {
|
|
53
|
-
"source": "/home/circleci/.cache/bazel/_bazel_circleci/e8362d362e14c7d23506d1dfa3aea8b8/sandbox/processwrapper-sandbox/
|
|
53
|
+
"source": "/home/circleci/.cache/bazel/_bazel_circleci/e8362d362e14c7d23506d1dfa3aea8b8/sandbox/processwrapper-sandbox/4555/execroot/_main/bazel-out/k8-fastbuild/bin/node_modules/.aspect_rules_js/@player-ui+beacon-plugin@0.0.0/node_modules/@player-ui/beacon-plugin/types/beacon.d.ts",
|
|
54
54
|
"name": "BeaconDataType",
|
|
55
55
|
"type": "or",
|
|
56
56
|
"or": [
|
package/dist/xlr/TextAsset.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"source": "/home/circleci/.cache/bazel/_bazel_circleci/e8362d362e14c7d23506d1dfa3aea8b8/sandbox/processwrapper-sandbox/
|
|
2
|
+
"source": "/home/circleci/.cache/bazel/_bazel_circleci/e8362d362e14c7d23506d1dfa3aea8b8/sandbox/processwrapper-sandbox/4555/execroot/_main/bazel-out/k8-fastbuild/bin/plugins/reference-assets/core/src/assets/text/types.ts",
|
|
3
3
|
"name": "TextAsset",
|
|
4
4
|
"type": "object",
|
|
5
5
|
"properties": {
|
|
@@ -16,12 +16,12 @@
|
|
|
16
16
|
"node": {
|
|
17
17
|
"type": "array",
|
|
18
18
|
"elementType": {
|
|
19
|
-
"source": "/home/circleci/.cache/bazel/_bazel_circleci/e8362d362e14c7d23506d1dfa3aea8b8/sandbox/processwrapper-sandbox/
|
|
19
|
+
"source": "/home/circleci/.cache/bazel/_bazel_circleci/e8362d362e14c7d23506d1dfa3aea8b8/sandbox/processwrapper-sandbox/4555/execroot/_main/bazel-out/k8-fastbuild/bin/plugins/reference-assets/core/src/assets/text/types.ts",
|
|
20
20
|
"name": "TextModifier",
|
|
21
21
|
"type": "or",
|
|
22
22
|
"or": [
|
|
23
23
|
{
|
|
24
|
-
"source": "/home/circleci/.cache/bazel/_bazel_circleci/e8362d362e14c7d23506d1dfa3aea8b8/sandbox/processwrapper-sandbox/
|
|
24
|
+
"source": "/home/circleci/.cache/bazel/_bazel_circleci/e8362d362e14c7d23506d1dfa3aea8b8/sandbox/processwrapper-sandbox/4555/execroot/_main/bazel-out/k8-fastbuild/bin/plugins/reference-assets/core/src/assets/text/types.ts",
|
|
25
25
|
"name": "BasicTextModifier",
|
|
26
26
|
"type": "object",
|
|
27
27
|
"properties": {
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
"title": "BasicTextModifier"
|
|
49
49
|
},
|
|
50
50
|
{
|
|
51
|
-
"source": "/home/circleci/.cache/bazel/_bazel_circleci/e8362d362e14c7d23506d1dfa3aea8b8/sandbox/processwrapper-sandbox/
|
|
51
|
+
"source": "/home/circleci/.cache/bazel/_bazel_circleci/e8362d362e14c7d23506d1dfa3aea8b8/sandbox/processwrapper-sandbox/4555/execroot/_main/bazel-out/k8-fastbuild/bin/plugins/reference-assets/core/src/assets/text/types.ts",
|
|
52
52
|
"name": "LinkModifier",
|
|
53
53
|
"type": "object",
|
|
54
54
|
"properties": {
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"source": "/home/circleci/.cache/bazel/_bazel_circleci/e8362d362e14c7d23506d1dfa3aea8b8/sandbox/processwrapper-sandbox/4555/execroot/_main/bazel-out/k8-fastbuild/bin/plugins/reference-assets/core/src/plugins/send.ts",
|
|
3
|
+
"name": "send",
|
|
4
|
+
"type": "ref",
|
|
5
|
+
"ref": "ExpressionHandler<[string, string | undefined]>",
|
|
6
|
+
"genericArguments": [
|
|
7
|
+
{
|
|
8
|
+
"type": "tuple",
|
|
9
|
+
"elementTypes": [
|
|
10
|
+
{
|
|
11
|
+
"type": {
|
|
12
|
+
"type": "string",
|
|
13
|
+
"title": "0"
|
|
14
|
+
},
|
|
15
|
+
"optional": false
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"type": {
|
|
19
|
+
"type": "or",
|
|
20
|
+
"or": [
|
|
21
|
+
{
|
|
22
|
+
"type": "string",
|
|
23
|
+
"title": "1"
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
"type": "undefined",
|
|
27
|
+
"title": "1"
|
|
28
|
+
}
|
|
29
|
+
],
|
|
30
|
+
"title": "1"
|
|
31
|
+
},
|
|
32
|
+
"optional": false
|
|
33
|
+
}
|
|
34
|
+
],
|
|
35
|
+
"additionalItems": false,
|
|
36
|
+
"minItems": 2
|
|
37
|
+
}
|
|
38
|
+
],
|
|
39
|
+
"title": "send"
|
|
40
|
+
}
|
package/package.json
CHANGED
|
@@ -6,12 +6,14 @@
|
|
|
6
6
|
"types"
|
|
7
7
|
],
|
|
8
8
|
"name": "@player-ui/reference-assets-plugin",
|
|
9
|
-
"version": "0.13.0-next.
|
|
9
|
+
"version": "0.13.0-next.6",
|
|
10
10
|
"main": "dist/cjs/index.cjs",
|
|
11
11
|
"dependencies": {
|
|
12
|
-
"@player-ui/asset-transform-plugin": "0.13.0-next.
|
|
13
|
-
"@player-ui/beacon-plugin": "0.13.0-next.
|
|
14
|
-
"@player-ui/async-node-plugin": "0.13.0-next.
|
|
12
|
+
"@player-ui/asset-transform-plugin": "0.13.0-next.6",
|
|
13
|
+
"@player-ui/beacon-plugin": "0.13.0-next.6",
|
|
14
|
+
"@player-ui/async-node-plugin": "0.13.0-next.6",
|
|
15
|
+
"@player-ui/expression-plugin": "0.13.0-next.6",
|
|
16
|
+
"@player-ui/meta-plugin": "0.13.0-next.6",
|
|
15
17
|
"tslib": "^2.6.2"
|
|
16
18
|
},
|
|
17
19
|
"devDependencies": {
|
|
@@ -19,7 +21,7 @@
|
|
|
19
21
|
"@player-ui/common-types-plugin": "workspace:*"
|
|
20
22
|
},
|
|
21
23
|
"peerDependencies": {
|
|
22
|
-
"@player-ui/player": "0.13.0-next.
|
|
24
|
+
"@player-ui/player": "0.13.0-next.6"
|
|
23
25
|
},
|
|
24
26
|
"module": "dist/index.legacy-esm.js",
|
|
25
27
|
"types": "types/index.d.ts",
|
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
import { Flow, InProgressState, Logger, Player } from "@player-ui/player";
|
|
2
|
+
import { describe, it, expect, beforeEach, vi } from "vitest";
|
|
3
|
+
import { ChatUiDemoPlugin } from "../plugins/chat-ui-demo-plugin";
|
|
4
|
+
import { AsyncNodePlugin } from "@player-ui/async-node-plugin";
|
|
5
|
+
import { ReferenceAssetsPlugin } from "../plugin";
|
|
6
|
+
|
|
7
|
+
const mockLogger = (): Logger => ({
|
|
8
|
+
trace: vi.fn(),
|
|
9
|
+
debug: vi.fn(),
|
|
10
|
+
error: vi.fn(),
|
|
11
|
+
info: vi.fn(),
|
|
12
|
+
warn: vi.fn(),
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
const makeFlow = (asyncNodeCount: number): Flow => ({
|
|
16
|
+
id: "flow-with-async",
|
|
17
|
+
views: [
|
|
18
|
+
{
|
|
19
|
+
id: "view",
|
|
20
|
+
type: "view",
|
|
21
|
+
values: Array.from({ length: asyncNodeCount }, (_, index) => ({
|
|
22
|
+
async: true,
|
|
23
|
+
id: `id-${index}`,
|
|
24
|
+
})),
|
|
25
|
+
},
|
|
26
|
+
],
|
|
27
|
+
navigation: {
|
|
28
|
+
BEGIN: "FlowStart",
|
|
29
|
+
FlowStart: {
|
|
30
|
+
startState: "VIEW_1",
|
|
31
|
+
VIEW_1: {
|
|
32
|
+
state_type: "VIEW",
|
|
33
|
+
ref: "view",
|
|
34
|
+
transitions: {
|
|
35
|
+
"*": "END_DONE",
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
END_DONE: {
|
|
39
|
+
state_type: "END",
|
|
40
|
+
outcome: "DONE",
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
describe("ReferenceAssetsPlugin", () => {
|
|
47
|
+
let player: Player;
|
|
48
|
+
let logger: Logger;
|
|
49
|
+
let asyncPlugin: AsyncNodePlugin;
|
|
50
|
+
|
|
51
|
+
beforeEach(() => {
|
|
52
|
+
logger = mockLogger();
|
|
53
|
+
|
|
54
|
+
player = new Player({
|
|
55
|
+
logger,
|
|
56
|
+
plugins: [new ReferenceAssetsPlugin()],
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
asyncPlugin = player.findPlugin<AsyncNodePlugin>(AsyncNodePlugin.Symbol)!;
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
describe("ChatUiPlugin", () => {
|
|
63
|
+
it("should warn when there is no async node to receive the message", async () => {
|
|
64
|
+
player.start(makeFlow(0));
|
|
65
|
+
const state = player.getState();
|
|
66
|
+
|
|
67
|
+
expect(state.status).toBe("in-progress");
|
|
68
|
+
(state as InProgressState).controllers.expression.evaluate(
|
|
69
|
+
"send('message')",
|
|
70
|
+
);
|
|
71
|
+
|
|
72
|
+
await vi.waitFor(() => {
|
|
73
|
+
expect(logger.warn).toHaveBeenCalledOnce();
|
|
74
|
+
expect(logger.warn).toHaveBeenCalledWith(
|
|
75
|
+
"'send' called with no waiting async nodes",
|
|
76
|
+
);
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
it("should warn when there is no async node that matches the given id", async () => {
|
|
81
|
+
player.start(makeFlow(1));
|
|
82
|
+
const state = player.getState();
|
|
83
|
+
|
|
84
|
+
expect(state.status).toBe("in-progress");
|
|
85
|
+
(state as InProgressState).controllers.expression.evaluate(
|
|
86
|
+
"send('message', 'Not a real id')",
|
|
87
|
+
);
|
|
88
|
+
|
|
89
|
+
await vi.waitFor(() => {
|
|
90
|
+
expect(logger.warn).toHaveBeenCalledOnce();
|
|
91
|
+
expect(logger.warn).toHaveBeenCalledWith(
|
|
92
|
+
"'send' expression called with unrecognized id 'Not a real id'",
|
|
93
|
+
);
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
it("should resolve all async node to a chat message when the send expression is called without an id", async () => {
|
|
98
|
+
const asyncHookTap = vi.fn();
|
|
99
|
+
asyncPlugin.hooks.onAsyncNode.intercept({
|
|
100
|
+
context: false,
|
|
101
|
+
call: asyncHookTap,
|
|
102
|
+
});
|
|
103
|
+
player.start(makeFlow(2));
|
|
104
|
+
|
|
105
|
+
await vi.waitFor(() => {
|
|
106
|
+
expect(asyncHookTap).toHaveBeenCalledTimes(2);
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
const state = player.getState();
|
|
110
|
+
|
|
111
|
+
expect(state.status).toBe("in-progress");
|
|
112
|
+
(state as InProgressState).controllers.expression.evaluate(
|
|
113
|
+
"send('message')",
|
|
114
|
+
);
|
|
115
|
+
|
|
116
|
+
await vi.waitFor(() => {
|
|
117
|
+
const nextState = player.getState();
|
|
118
|
+
expect(nextState.status).toBe("in-progress");
|
|
119
|
+
const inProgress = nextState as InProgressState;
|
|
120
|
+
const view = inProgress.controllers.view.currentView?.lastUpdate;
|
|
121
|
+
expect(view).toBeDefined();
|
|
122
|
+
// Don't need to test the whole view, just that the values array has been updated with the results of the 'send' command
|
|
123
|
+
expect(view).toStrictEqual(
|
|
124
|
+
expect.objectContaining({
|
|
125
|
+
values: [
|
|
126
|
+
{
|
|
127
|
+
asset: {
|
|
128
|
+
type: "collection",
|
|
129
|
+
id: "collection-async-message-0",
|
|
130
|
+
values: [
|
|
131
|
+
{
|
|
132
|
+
asset: {
|
|
133
|
+
id: "message-0-value",
|
|
134
|
+
type: "text",
|
|
135
|
+
value: "message",
|
|
136
|
+
},
|
|
137
|
+
},
|
|
138
|
+
],
|
|
139
|
+
},
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
asset: {
|
|
143
|
+
type: "collection",
|
|
144
|
+
id: "collection-async-message-1",
|
|
145
|
+
values: [
|
|
146
|
+
{
|
|
147
|
+
asset: {
|
|
148
|
+
id: "message-1-value",
|
|
149
|
+
type: "text",
|
|
150
|
+
value: "message",
|
|
151
|
+
},
|
|
152
|
+
},
|
|
153
|
+
],
|
|
154
|
+
},
|
|
155
|
+
},
|
|
156
|
+
],
|
|
157
|
+
}),
|
|
158
|
+
);
|
|
159
|
+
});
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
it("should resolve allow for single resolution by id", async () => {
|
|
163
|
+
const asyncHookTap = vi.fn();
|
|
164
|
+
asyncPlugin.hooks.onAsyncNode.intercept({
|
|
165
|
+
context: false,
|
|
166
|
+
call: asyncHookTap,
|
|
167
|
+
});
|
|
168
|
+
player.start(makeFlow(2));
|
|
169
|
+
|
|
170
|
+
await vi.waitFor(() => {
|
|
171
|
+
expect(asyncHookTap).toHaveBeenCalledTimes(2);
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
let state = player.getState();
|
|
175
|
+
|
|
176
|
+
expect(state.status).toBe("in-progress");
|
|
177
|
+
// resolve the second async node by targeting it by id
|
|
178
|
+
(state as InProgressState).controllers.expression.evaluate(
|
|
179
|
+
"send('first resolve', 'id-1')",
|
|
180
|
+
);
|
|
181
|
+
|
|
182
|
+
await vi.waitFor(() => {
|
|
183
|
+
const nextState = player.getState();
|
|
184
|
+
expect(nextState.status).toBe("in-progress");
|
|
185
|
+
const inProgress = nextState as InProgressState;
|
|
186
|
+
const view = inProgress.controllers.view.currentView?.lastUpdate;
|
|
187
|
+
expect(view).toBeDefined();
|
|
188
|
+
// Don't need to test the whole view, just that the values array has been updated with the results of the 'send' command
|
|
189
|
+
expect(view).toStrictEqual(
|
|
190
|
+
expect.objectContaining({
|
|
191
|
+
values: [
|
|
192
|
+
{
|
|
193
|
+
asset: {
|
|
194
|
+
type: "collection",
|
|
195
|
+
id: "collection-async-message-0",
|
|
196
|
+
values: [
|
|
197
|
+
{
|
|
198
|
+
asset: {
|
|
199
|
+
id: "message-0-value",
|
|
200
|
+
type: "text",
|
|
201
|
+
value: "first resolve",
|
|
202
|
+
},
|
|
203
|
+
},
|
|
204
|
+
],
|
|
205
|
+
},
|
|
206
|
+
},
|
|
207
|
+
],
|
|
208
|
+
}),
|
|
209
|
+
);
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
state = player.getState();
|
|
213
|
+
|
|
214
|
+
expect(state.status).toBe("in-progress");
|
|
215
|
+
// resolve the first async node and the new one generated by the last chat-message by allowing the plugin to resolve remaining nodes.
|
|
216
|
+
(state as InProgressState).controllers.expression.evaluate(
|
|
217
|
+
"send('second resolve')",
|
|
218
|
+
);
|
|
219
|
+
|
|
220
|
+
await vi.waitFor(() => {
|
|
221
|
+
const nextState = player.getState();
|
|
222
|
+
expect(nextState.status).toBe("in-progress");
|
|
223
|
+
const inProgress = nextState as InProgressState;
|
|
224
|
+
const view = inProgress.controllers.view.currentView?.lastUpdate;
|
|
225
|
+
expect(view).toBeDefined();
|
|
226
|
+
// Don't need to test the whole view, just that the values array has been updated with the results of the 'send' command
|
|
227
|
+
expect(view).toStrictEqual(
|
|
228
|
+
expect.objectContaining({
|
|
229
|
+
values: [
|
|
230
|
+
{
|
|
231
|
+
asset: {
|
|
232
|
+
type: "collection",
|
|
233
|
+
id: "collection-async-message-1",
|
|
234
|
+
values: [
|
|
235
|
+
{
|
|
236
|
+
asset: {
|
|
237
|
+
id: "message-1-value",
|
|
238
|
+
type: "text",
|
|
239
|
+
value: "second resolve",
|
|
240
|
+
},
|
|
241
|
+
},
|
|
242
|
+
],
|
|
243
|
+
},
|
|
244
|
+
},
|
|
245
|
+
{
|
|
246
|
+
asset: {
|
|
247
|
+
type: "collection",
|
|
248
|
+
id: "collection-async-message-0",
|
|
249
|
+
values: [
|
|
250
|
+
{
|
|
251
|
+
asset: {
|
|
252
|
+
id: "message-0-value",
|
|
253
|
+
type: "text",
|
|
254
|
+
value: "first resolve",
|
|
255
|
+
},
|
|
256
|
+
},
|
|
257
|
+
{
|
|
258
|
+
asset: {
|
|
259
|
+
id: "message-2-value",
|
|
260
|
+
type: "text",
|
|
261
|
+
value: "second resolve",
|
|
262
|
+
},
|
|
263
|
+
},
|
|
264
|
+
],
|
|
265
|
+
},
|
|
266
|
+
},
|
|
267
|
+
],
|
|
268
|
+
}),
|
|
269
|
+
);
|
|
270
|
+
});
|
|
271
|
+
});
|
|
272
|
+
});
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
describe("ChatUiDemoPlugin - Failed Setup", () => {
|
|
276
|
+
it("should warn if the async node plugin is not found", () => {
|
|
277
|
+
const logger = mockLogger();
|
|
278
|
+
new Player({
|
|
279
|
+
logger,
|
|
280
|
+
plugins: [new ChatUiDemoPlugin()],
|
|
281
|
+
});
|
|
282
|
+
|
|
283
|
+
expect(logger.warn).toHaveBeenCalledWith(
|
|
284
|
+
"Failed to apply 'chat-ui-demo-plugin'. Reason: Could not find AsyncNodePlugin.",
|
|
285
|
+
);
|
|
286
|
+
});
|
|
287
|
+
});
|
package/src/plugin.ts
CHANGED
|
@@ -1,54 +1,26 @@
|
|
|
1
|
-
import type { Player,
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
4
|
-
ActionAsset,
|
|
5
|
-
InputAsset,
|
|
6
|
-
ImageAsset,
|
|
7
|
-
InfoAsset,
|
|
8
|
-
TextAsset,
|
|
9
|
-
CollectionAsset,
|
|
10
|
-
ChoiceAsset,
|
|
11
|
-
ChatMessageAsset,
|
|
12
|
-
} from "./assets";
|
|
1
|
+
import type { Player, PlayerPlugin } from "@player-ui/player";
|
|
2
|
+
import { MetaPlugin } from "@player-ui/meta-plugin";
|
|
3
|
+
import { ChatUiDemoPlugin, ReferenceAssetsTransformPlugin } from "./plugins";
|
|
13
4
|
import {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
infoTransform,
|
|
18
|
-
choiceTransform,
|
|
19
|
-
chatMessageTransform,
|
|
20
|
-
} from "./assets";
|
|
5
|
+
AsyncNodePlugin,
|
|
6
|
+
AsyncNodePluginPlugin,
|
|
7
|
+
} from "@player-ui/async-node-plugin";
|
|
21
8
|
|
|
22
9
|
/**
|
|
23
10
|
* A plugin to add transforms for the reference assets
|
|
24
11
|
*/
|
|
25
|
-
export class ReferenceAssetsPlugin
|
|
26
|
-
|
|
27
|
-
ExtendedPlayerPlugin<
|
|
28
|
-
[
|
|
29
|
-
ActionAsset,
|
|
30
|
-
InputAsset,
|
|
31
|
-
ImageAsset,
|
|
32
|
-
TextAsset,
|
|
33
|
-
CollectionAsset,
|
|
34
|
-
ChoiceAsset,
|
|
35
|
-
ChatMessageAsset,
|
|
36
|
-
],
|
|
37
|
-
[InfoAsset]
|
|
38
|
-
>
|
|
39
|
-
{
|
|
40
|
-
name = "reference-assets-transforms";
|
|
12
|
+
export class ReferenceAssetsPlugin implements PlayerPlugin {
|
|
13
|
+
name = "reference-assets-plugin";
|
|
41
14
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
new
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
);
|
|
15
|
+
private readonly metaPlugin = new MetaPlugin([
|
|
16
|
+
new AsyncNodePlugin({
|
|
17
|
+
plugins: [new AsyncNodePluginPlugin()],
|
|
18
|
+
}),
|
|
19
|
+
new ReferenceAssetsTransformPlugin(),
|
|
20
|
+
new ChatUiDemoPlugin(),
|
|
21
|
+
]);
|
|
22
|
+
|
|
23
|
+
apply(player: Player): void {
|
|
24
|
+
player.registerPlugin(this.metaPlugin);
|
|
53
25
|
}
|
|
54
26
|
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { AsyncNodePlugin } from "@player-ui/async-node-plugin";
|
|
2
|
+
import {
|
|
3
|
+
ExpressionContext,
|
|
4
|
+
ExtendedPlayerPlugin,
|
|
5
|
+
Player,
|
|
6
|
+
} from "@player-ui/player";
|
|
7
|
+
import { ExpressionPlugin } from "@player-ui/expression-plugin";
|
|
8
|
+
import { send } from "./send";
|
|
9
|
+
|
|
10
|
+
const createContentFromMessage = (message: string, id: string): any => ({
|
|
11
|
+
asset: {
|
|
12
|
+
type: "chat-message",
|
|
13
|
+
id,
|
|
14
|
+
value: {
|
|
15
|
+
asset: {
|
|
16
|
+
type: "text",
|
|
17
|
+
id: `${id}-value`,
|
|
18
|
+
value: message,
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
export class ChatUiDemoPlugin implements ExtendedPlayerPlugin<[], [], [send]> {
|
|
25
|
+
public readonly name = "chat-ui-demo-plugin";
|
|
26
|
+
|
|
27
|
+
public apply(player: Player): void {
|
|
28
|
+
const asyncNodePlugin = player.findPlugin<AsyncNodePlugin>(
|
|
29
|
+
AsyncNodePlugin.Symbol,
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
if (!asyncNodePlugin) {
|
|
33
|
+
player.logger.warn(
|
|
34
|
+
`Failed to apply '${this.name}'. Reason: Could not find AsyncNodePlugin.`,
|
|
35
|
+
);
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
let deferredPromises: Record<string, (val: string) => void> = {};
|
|
40
|
+
let allPromiseKeys: string[] = [];
|
|
41
|
+
let counter = 0;
|
|
42
|
+
|
|
43
|
+
const sendMessage: send = (
|
|
44
|
+
context: ExpressionContext,
|
|
45
|
+
message: string,
|
|
46
|
+
nodeId?: string,
|
|
47
|
+
): void => {
|
|
48
|
+
if (nodeId && !(nodeId in deferredPromises)) {
|
|
49
|
+
context.logger?.warn(
|
|
50
|
+
`'send' expression called with unrecognized id '${nodeId}'`,
|
|
51
|
+
);
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (!nodeId && allPromiseKeys.length === 0) {
|
|
56
|
+
context.logger?.warn(`'send' called with no waiting async nodes`);
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Either resolve the node by the id or resolve all of them if no id provided
|
|
61
|
+
const keys = nodeId ? [nodeId] : allPromiseKeys;
|
|
62
|
+
|
|
63
|
+
for (const id of keys) {
|
|
64
|
+
const content = createContentFromMessage(
|
|
65
|
+
message,
|
|
66
|
+
`message-${counter++}`,
|
|
67
|
+
);
|
|
68
|
+
const resolveFunction = deferredPromises[id];
|
|
69
|
+
resolveFunction?.(content);
|
|
70
|
+
delete deferredPromises[id];
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (nodeId) {
|
|
74
|
+
const index = allPromiseKeys.indexOf(nodeId);
|
|
75
|
+
allPromiseKeys.splice(index, 1);
|
|
76
|
+
} else {
|
|
77
|
+
allPromiseKeys = [];
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
asyncNodePlugin.hooks.onAsyncNode.tap(this.name, (node) => {
|
|
82
|
+
return new Promise((res) => {
|
|
83
|
+
deferredPromises[node.id] = res;
|
|
84
|
+
allPromiseKeys.push(node.id);
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
// Reset at the start of a new view.
|
|
89
|
+
player.hooks.view.tap(this.name, (_) => {
|
|
90
|
+
deferredPromises = {};
|
|
91
|
+
allPromiseKeys = [];
|
|
92
|
+
counter = 0;
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
// Register 'send' expression
|
|
96
|
+
const expressionPlugin = new ExpressionPlugin(
|
|
97
|
+
new Map([["send", sendMessage]]),
|
|
98
|
+
);
|
|
99
|
+
player.registerPlugin(expressionPlugin);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { ExtendedPlayerPlugin, Player } from "@player-ui/player";
|
|
2
|
+
import { AssetTransformPlugin } from "@player-ui/asset-transform-plugin";
|
|
3
|
+
import {
|
|
4
|
+
actionTransform,
|
|
5
|
+
chatMessageTransform,
|
|
6
|
+
choiceTransform,
|
|
7
|
+
imageTransform,
|
|
8
|
+
infoTransform,
|
|
9
|
+
inputTransform,
|
|
10
|
+
} from "../assets";
|
|
11
|
+
import type {
|
|
12
|
+
ActionAsset,
|
|
13
|
+
ChatMessageAsset,
|
|
14
|
+
ChoiceAsset,
|
|
15
|
+
CollectionAsset,
|
|
16
|
+
ImageAsset,
|
|
17
|
+
InfoAsset,
|
|
18
|
+
InputAsset,
|
|
19
|
+
TextAsset,
|
|
20
|
+
} from "../assets";
|
|
21
|
+
|
|
22
|
+
export class ReferenceAssetsTransformPlugin
|
|
23
|
+
implements
|
|
24
|
+
ExtendedPlayerPlugin<
|
|
25
|
+
[
|
|
26
|
+
ActionAsset,
|
|
27
|
+
InputAsset,
|
|
28
|
+
ImageAsset,
|
|
29
|
+
TextAsset,
|
|
30
|
+
CollectionAsset,
|
|
31
|
+
ChoiceAsset,
|
|
32
|
+
ChatMessageAsset,
|
|
33
|
+
],
|
|
34
|
+
[InfoAsset]
|
|
35
|
+
>
|
|
36
|
+
{
|
|
37
|
+
name = "reference-assets-transforms";
|
|
38
|
+
|
|
39
|
+
apply(player: Player): void {
|
|
40
|
+
player.registerPlugin(
|
|
41
|
+
new AssetTransformPlugin([
|
|
42
|
+
[{ type: "action" }, actionTransform],
|
|
43
|
+
[{ type: "input" }, inputTransform],
|
|
44
|
+
[{ type: "image" }, imageTransform],
|
|
45
|
+
[{ type: "info" }, infoTransform],
|
|
46
|
+
[{ type: "choice" }, choiceTransform],
|
|
47
|
+
[{ type: "chat-message" }, chatMessageTransform],
|
|
48
|
+
]),
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
}
|
package/types/plugin.d.ts
CHANGED
|
@@ -1,20 +1,10 @@
|
|
|
1
|
-
import type { Player,
|
|
2
|
-
import type { ActionAsset, InputAsset, ImageAsset, InfoAsset, TextAsset, CollectionAsset, ChoiceAsset, ChatMessageAsset } from "./assets";
|
|
1
|
+
import type { Player, PlayerPlugin } from "@player-ui/player";
|
|
3
2
|
/**
|
|
4
3
|
* A plugin to add transforms for the reference assets
|
|
5
4
|
*/
|
|
6
|
-
export declare class ReferenceAssetsPlugin implements
|
|
7
|
-
ActionAsset,
|
|
8
|
-
InputAsset,
|
|
9
|
-
ImageAsset,
|
|
10
|
-
TextAsset,
|
|
11
|
-
CollectionAsset,
|
|
12
|
-
ChoiceAsset,
|
|
13
|
-
ChatMessageAsset
|
|
14
|
-
], [
|
|
15
|
-
InfoAsset
|
|
16
|
-
]> {
|
|
5
|
+
export declare class ReferenceAssetsPlugin implements PlayerPlugin {
|
|
17
6
|
name: string;
|
|
7
|
+
private readonly metaPlugin;
|
|
18
8
|
apply(player: Player): void;
|
|
19
9
|
}
|
|
20
10
|
//# sourceMappingURL=plugin.d.ts.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { ExtendedPlayerPlugin, Player } from "@player-ui/player";
|
|
2
|
+
import { send } from "./send";
|
|
3
|
+
export declare class ChatUiDemoPlugin implements ExtendedPlayerPlugin<[], [], [send]> {
|
|
4
|
+
readonly name = "chat-ui-demo-plugin";
|
|
5
|
+
apply(player: Player): void;
|
|
6
|
+
}
|
|
7
|
+
//# sourceMappingURL=chat-ui-demo-plugin.d.ts.map
|