@player-ui/player 0.11.0-next.2 → 0.11.0-next.4

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/package.json CHANGED
@@ -6,12 +6,12 @@
6
6
  "types"
7
7
  ],
8
8
  "name": "@player-ui/player",
9
- "version": "0.11.0-next.2",
9
+ "version": "0.11.0-next.4",
10
10
  "main": "dist/cjs/index.cjs",
11
11
  "dependencies": {
12
- "@player-ui/partial-match-registry": "0.11.0-next.2",
13
- "@player-ui/make-flow": "0.11.0-next.2",
14
- "@player-ui/types": "0.11.0-next.2",
12
+ "@player-ui/partial-match-registry": "0.11.0-next.4",
13
+ "@player-ui/make-flow": "0.11.0-next.4",
14
+ "@player-ui/types": "0.11.0-next.4",
15
15
  "@types/dlv": "^1.1.4",
16
16
  "dequal": "^2.0.2",
17
17
  "dlv": "^1.1.3",
@@ -102,6 +102,34 @@ describe("addChild", () => {
102
102
  const value = Builder.value({ id: 2 });
103
103
  Builder.addChild(asset, ["path1", "path2"], value);
104
104
 
105
- expect(asset.children?.[0].path).toStrictEqual(["path1", "path2"]);
105
+ expect(asset.children?.[0]?.path).toStrictEqual(["path1", "path2"]);
106
+ });
107
+ });
108
+
109
+ describe("updateChildrenByPath", () => {
110
+ test("updates children with matching path in the same order", () => {
111
+ const parent = Builder.value();
112
+ const child1 = Builder.value({ foo: "child1Value" });
113
+ const child2 = Builder.value({ foo: "child2Value" });
114
+ const child3 = Builder.value({ foo: "child3Value" });
115
+
116
+ Builder.addChild(parent, "child1", child1);
117
+ // Child 2 has the same path as child 1
118
+ Builder.addChild(parent, "child1", child2);
119
+ Builder.addChild(parent, "child3", child3);
120
+
121
+ // Update matching children
122
+ const updated = Builder.updateChildrenByPath(parent, ["child1"], (child) =>
123
+ Builder.value({
124
+ transformed: true,
125
+ original: (child as any).value?.foo,
126
+ }),
127
+ );
128
+
129
+ expect(updated.children).toHaveLength(3);
130
+ // Verify children are in the correct order
131
+ expect(updated.children?.[0]?.path).toStrictEqual(["child1"]);
132
+ expect(updated.children?.[1]?.path).toStrictEqual(["child1"]);
133
+ expect(updated.children?.[2]?.path).toStrictEqual(["child3"]);
106
134
  });
107
135
  });
@@ -87,7 +87,7 @@ export class Builder {
87
87
  node: N,
88
88
  path: Node.PathSegment | Node.PathSegment[],
89
89
  child: Node.Node,
90
- ) {
90
+ ): N {
91
91
  child.parent = node as Node.Node;
92
92
 
93
93
  const newChild: Node.Child = {
@@ -100,4 +100,32 @@ export class Builder {
100
100
 
101
101
  return node;
102
102
  }
103
+
104
+ /**
105
+ * Updates children of a node of the same path and preserves order
106
+ *
107
+ * @param node - The node to update children for
108
+ * @param pathToMatch - The path to match against child paths
109
+ * @param mapFn - Function to transform matching children
110
+ */
111
+ static updateChildrenByPath<T extends Node.ViewOrAsset | Node.Value>(
112
+ node: T,
113
+ pathToMatch: Node.PathSegment[],
114
+ updateFn: (child: Node.Child) => Node.Node,
115
+ ): T {
116
+ if (!node.children) return node;
117
+
118
+ // Use map to preserve original order
119
+ const updatedChildren = node.children.map((child) =>
120
+ // Check if paths match exactly
121
+ child.path.join() === pathToMatch.join()
122
+ ? { ...child, value: updateFn(child) }
123
+ : child,
124
+ );
125
+
126
+ return {
127
+ ...node,
128
+ children: updatedChildren,
129
+ };
130
+ }
103
131
  }
@@ -74,8 +74,11 @@ export declare namespace Node {
74
74
  /** The number of nested templates so far */
75
75
  depth: number;
76
76
 
77
- /** should the template recomputed when data changes */
77
+ /** Should the template recompute when data changes */
78
78
  dynamic?: boolean;
79
+
80
+ /** Specifies the template placement in relation to existing elements*/
81
+ placement?: "prepend" | "append";
79
82
  }
80
83
 
81
84
  export interface Value
@@ -1,6 +1,119 @@
1
1
  // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2
2
 
3
- exports[`dynamic templates > Works with template items plus value items > Should show template item first when coming before values on lexical order 1`] = `
3
+ exports[`templates > Should preserve order when multiple templates have the same placement 1`] = `
4
+ [
5
+ {
6
+ "asset": {
7
+ "id": "static-value",
8
+ "type": "text",
9
+ "value": "Static value in the collection",
10
+ },
11
+ },
12
+ {
13
+ "asset": {
14
+ "id": "first-0",
15
+ "type": "text",
16
+ "value": "first A",
17
+ },
18
+ },
19
+ {
20
+ "asset": {
21
+ "id": "first-1",
22
+ "type": "text",
23
+ "value": "first B",
24
+ },
25
+ },
26
+ {
27
+ "asset": {
28
+ "id": "second-0",
29
+ "type": "text",
30
+ "value": "second C",
31
+ },
32
+ },
33
+ {
34
+ "asset": {
35
+ "id": "second-1",
36
+ "type": "text",
37
+ "value": "second D",
38
+ },
39
+ },
40
+ ]
41
+ `;
42
+
43
+ exports[`templates > Works with template items plus value items > Should show dynamic template items first when using placement prepend 1`] = `
44
+ [
45
+ {
46
+ "asset": {
47
+ "id": "dynamic-0",
48
+ "type": "text",
49
+ "value": "item Ginger",
50
+ },
51
+ },
52
+ {
53
+ "asset": {
54
+ "id": "dynamic-1",
55
+ "type": "text",
56
+ "value": "item Vokey",
57
+ },
58
+ },
59
+ {
60
+ "asset": {
61
+ "id": "value-1",
62
+ "type": "text",
63
+ "value": "First value in the collection",
64
+ },
65
+ },
66
+ {
67
+ "asset": {
68
+ "id": "value-2",
69
+ "type": "text",
70
+ "value": "Second value in the collection",
71
+ },
72
+ },
73
+ ]
74
+ `;
75
+
76
+ exports[`templates > Works with template items plus value items > Should show dynamic template items first when using placement prepend 2`] = `
77
+ [
78
+ {
79
+ "asset": {
80
+ "id": "dynamic-0",
81
+ "type": "text",
82
+ "value": "item Louis",
83
+ },
84
+ },
85
+ {
86
+ "asset": {
87
+ "id": "dynamic-1",
88
+ "type": "text",
89
+ "value": "item Bob",
90
+ },
91
+ },
92
+ {
93
+ "asset": {
94
+ "id": "dynamic-2",
95
+ "type": "text",
96
+ "value": "item Nuri",
97
+ },
98
+ },
99
+ {
100
+ "asset": {
101
+ "id": "value-1",
102
+ "type": "text",
103
+ "value": "First value in the collection",
104
+ },
105
+ },
106
+ {
107
+ "asset": {
108
+ "id": "value-2",
109
+ "type": "text",
110
+ "value": "Second value in the collection",
111
+ },
112
+ },
113
+ ]
114
+ `;
115
+
116
+ exports[`templates > Works with template items plus value items > Should show static template item first when coming before values on lexical order 1`] = `
4
117
  [
5
118
  {
6
119
  "asset": {
@@ -33,7 +146,7 @@ exports[`dynamic templates > Works with template items plus value items > Should
33
146
  ]
34
147
  `;
35
148
 
36
- exports[`dynamic templates > Works with template items plus value items > Should show template item last when coming after values on lexical order 1`] = `
149
+ exports[`templates > Works with template items plus value items > Should show static template item last when coming after values on lexical order 1`] = `
37
150
  [
38
151
  {
39
152
  "asset": {
@@ -66,7 +179,219 @@ exports[`dynamic templates > Works with template items plus value items > Should
66
179
  ]
67
180
  `;
68
181
 
69
- exports[`templates > works with nested templates 1`] = `
182
+ exports[`templates > Works with template items plus value items > Should show static template items first when using placement prepend 1`] = `
183
+ [
184
+ {
185
+ "asset": {
186
+ "id": "value-0",
187
+ "type": "text",
188
+ "value": "item 1",
189
+ },
190
+ },
191
+ {
192
+ "asset": {
193
+ "id": "value-1",
194
+ "type": "text",
195
+ "value": "item 2",
196
+ },
197
+ },
198
+ {
199
+ "asset": {
200
+ "id": "value-2",
201
+ "type": "text",
202
+ "value": "First value in the collection",
203
+ },
204
+ },
205
+ {
206
+ "asset": {
207
+ "id": "value-3",
208
+ "type": "text",
209
+ "value": "Second value in the collection",
210
+ },
211
+ },
212
+ ]
213
+ `;
214
+
215
+ exports[`templates > Works with template items plus value items > Should show static template items last when using placement append 1`] = `
216
+ [
217
+ {
218
+ "asset": {
219
+ "id": "value-2",
220
+ "type": "text",
221
+ "value": "First value in the collection",
222
+ },
223
+ },
224
+ {
225
+ "asset": {
226
+ "id": "value-3",
227
+ "type": "text",
228
+ "value": "Second value in the collection",
229
+ },
230
+ },
231
+ {
232
+ "asset": {
233
+ "id": "value-0",
234
+ "type": "text",
235
+ "value": "item 1",
236
+ },
237
+ },
238
+ {
239
+ "asset": {
240
+ "id": "value-1",
241
+ "type": "text",
242
+ "value": "item 2",
243
+ },
244
+ },
245
+ ]
246
+ `;
247
+
248
+ exports[`templates > Works with template items plus value items > Should support placement for both static and dynamic templates 1`] = `
249
+ [
250
+ {
251
+ "asset": {
252
+ "id": "static-0",
253
+ "type": "text",
254
+ "value": "static Ginger",
255
+ },
256
+ },
257
+ {
258
+ "asset": {
259
+ "id": "static-1",
260
+ "type": "text",
261
+ "value": "static Vokey",
262
+ },
263
+ },
264
+ {
265
+ "asset": {
266
+ "id": "value-1",
267
+ "type": "text",
268
+ "value": "First value in the collection",
269
+ },
270
+ },
271
+ {
272
+ "asset": {
273
+ "id": "value-2",
274
+ "type": "text",
275
+ "value": "Second value in the collection",
276
+ },
277
+ },
278
+ {
279
+ "asset": {
280
+ "id": "dynamic-0",
281
+ "type": "text",
282
+ "value": "dynamic Ginger",
283
+ },
284
+ },
285
+ {
286
+ "asset": {
287
+ "id": "dynamic-1",
288
+ "type": "text",
289
+ "value": "dynamic Vokey",
290
+ },
291
+ },
292
+ ]
293
+ `;
294
+
295
+ exports[`templates > Works with template items plus value items > Should support placement for both static and dynamic templates 2`] = `
296
+ [
297
+ {
298
+ "asset": {
299
+ "id": "static-0",
300
+ "type": "text",
301
+ "value": "static Louis",
302
+ },
303
+ },
304
+ {
305
+ "asset": {
306
+ "id": "static-1",
307
+ "type": "text",
308
+ "value": "static Bob",
309
+ },
310
+ },
311
+ {
312
+ "asset": {
313
+ "id": "value-1",
314
+ "type": "text",
315
+ "value": "First value in the collection",
316
+ },
317
+ },
318
+ {
319
+ "asset": {
320
+ "id": "value-2",
321
+ "type": "text",
322
+ "value": "Second value in the collection",
323
+ },
324
+ },
325
+ {
326
+ "asset": {
327
+ "id": "dynamic-0",
328
+ "type": "text",
329
+ "value": "dynamic Louis",
330
+ },
331
+ },
332
+ {
333
+ "asset": {
334
+ "id": "dynamic-1",
335
+ "type": "text",
336
+ "value": "dynamic Bob",
337
+ },
338
+ },
339
+ {
340
+ "asset": {
341
+ "id": "dynamic-2",
342
+ "type": "text",
343
+ "value": "dynamic Nuri",
344
+ },
345
+ },
346
+ ]
347
+ `;
348
+
349
+ exports[`templates > works with simple ones 1`] = `
350
+ {
351
+ "children": [
352
+ {
353
+ "path": [
354
+ "values",
355
+ ],
356
+ "value": {
357
+ "override": false,
358
+ "parent": [Circular],
359
+ "type": "multi-node",
360
+ "values": [
361
+ {
362
+ "parent": [Circular],
363
+ "type": "value",
364
+ "value": {
365
+ "value": "{{foo.bar.0}}",
366
+ },
367
+ },
368
+ {
369
+ "parent": [Circular],
370
+ "type": "value",
371
+ "value": {
372
+ "value": "{{foo.bar.1}}",
373
+ },
374
+ },
375
+ {
376
+ "parent": [Circular],
377
+ "type": "value",
378
+ "value": {
379
+ "value": "{{foo.bar.2}}",
380
+ },
381
+ },
382
+ ],
383
+ },
384
+ },
385
+ ],
386
+ "type": "value",
387
+ "value": {
388
+ "id": "foo",
389
+ "type": "collection",
390
+ },
391
+ }
392
+ `;
393
+
394
+ exports[`templates > works with static nested templates 1`] = `
70
395
  {
71
396
  "children": [
72
397
  {
@@ -233,48 +558,3 @@ exports[`templates > works with nested templates 1`] = `
233
558
  },
234
559
  }
235
560
  `;
236
-
237
- exports[`templates > works with simple ones 1`] = `
238
- {
239
- "children": [
240
- {
241
- "path": [
242
- "values",
243
- ],
244
- "value": {
245
- "override": false,
246
- "parent": [Circular],
247
- "type": "multi-node",
248
- "values": [
249
- {
250
- "parent": [Circular],
251
- "type": "value",
252
- "value": {
253
- "value": "{{foo.bar.0}}",
254
- },
255
- },
256
- {
257
- "parent": [Circular],
258
- "type": "value",
259
- "value": {
260
- "value": "{{foo.bar.1}}",
261
- },
262
- },
263
- {
264
- "parent": [Circular],
265
- "type": "value",
266
- "value": {
267
- "value": "{{foo.bar.2}}",
268
- },
269
- },
270
- ],
271
- },
272
- },
273
- ],
274
- "type": "value",
275
- "value": {
276
- "id": "foo",
277
- "type": "collection",
278
- },
279
- }
280
- `;