@sprig-and-prose/sprig-scenes 0.2.0 → 0.2.1

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/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # @sprig-and-prose/sprig-scenes
2
2
 
3
+ ## 0.2.1
4
+
5
+ ### Patch Changes
6
+
7
+ - 2a40227: - **scenes:** Emit array kinds in manifest as `array: { of: { type } }` to match prose; recognize field modifier `optional { }` when tokenized as identifier.
8
+ - **scene-engine:** Consume new array manifest shape (`kind.array.of`).
9
+ - **sprig-edge:** Attestation validation uses new array manifest shape (`kind.array.of`).
10
+ - Updated dependencies [2a40227]
11
+ - @sprig-and-prose/sprig-scene-engine@0.1.1
12
+
3
13
  ## 0.2.0
4
14
 
5
15
  ### Minor Changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sprig-and-prose/sprig-scenes",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "type": "module",
5
5
  "description": "Scene compiler and canonical outputs for sprig",
6
6
  "main": "src/index.js",
@@ -30,7 +30,9 @@
30
30
  "tools": {
31
31
  "type": {
32
32
  "array": {
33
- "actor": "Tool"
33
+ "of": {
34
+ "actor": "Tool"
35
+ }
34
36
  }
35
37
  }
36
38
  }
@@ -63,7 +65,9 @@
63
65
  "tools": {
64
66
  "type": {
65
67
  "array": {
66
- "actor": "Tool"
68
+ "of": {
69
+ "actor": "Tool"
70
+ }
67
71
  }
68
72
  }
69
73
  }
@@ -75,14 +79,18 @@
75
79
  "ContainerRows": {
76
80
  "kind": {
77
81
  "array": {
78
- "actor": "ContainerRow"
82
+ "of": {
83
+ "actor": "ContainerRow"
84
+ }
79
85
  }
80
86
  }
81
87
  },
82
88
  "AnotherToolPortal": {
83
89
  "kind": {
84
90
  "array": {
85
- "actor": "Something"
91
+ "of": {
92
+ "actor": "Something"
93
+ }
86
94
  }
87
95
  }
88
96
  }
@@ -37,12 +37,12 @@ function toKindRef(parsed) {
37
37
  }
38
38
  if (typeof parsed === 'object' && parsed !== null && 'arrayOf' in parsed && parsed.arrayOf != null) {
39
39
  const inner = toKindRef(parsed.arrayOf);
40
- return inner != null ? { array: inner } : null;
40
+ return inner != null ? { array: { of: inner } } : null;
41
41
  }
42
- // New array format: { array: itemType, minItems?, maxItems? }
42
+ // New array format: { array: itemType, minItems?, maxItems? } => manifest { array: { of: KindRef } }
43
43
  if (typeof parsed === 'object' && parsed !== null && 'array' in parsed) {
44
44
  const inner = toKindRef(parsed.array);
45
- return inner != null ? { array: inner } : null;
45
+ return inner != null ? { array: { of: inner } } : null;
46
46
  }
47
47
  // Primitive with optional constraints (already KindRef-shaped)
48
48
  if (typeof parsed === 'object' && parsed !== null && 'primitive' in parsed) {
@@ -937,7 +937,7 @@ class SceneParser extends ParserCore {
937
937
  this.expect('RBRACKET');
938
938
  if (inner) {
939
939
  const ref = toKindRef(inner);
940
- if (ref) return { array: ref };
940
+ if (ref) return { array: { of: ref } };
941
941
  }
942
942
  continue;
943
943
  }
@@ -1200,7 +1200,7 @@ class SceneParser extends ParserCore {
1200
1200
 
1201
1201
  const typeTok = this.peek();
1202
1202
  if (typeTok) {
1203
- if (typeTok.type === 'KEYWORD' && PRIMITIVE_KINDS.has(typeTok.value)) {
1203
+ if ((typeTok.type === 'KEYWORD' || typeTok.type === 'IDENTIFIER') && PRIMITIVE_KINDS.has(typeTok.value)) {
1204
1204
  itemType = this.parsePrimitiveType(typeTok.value);
1205
1205
  } else if (typeTok.type === 'IDENTIFIER' || typeTok.type === 'KEYWORD') {
1206
1206
  itemType = { actor: typeTok.value };
@@ -1273,7 +1273,7 @@ class SceneParser extends ParserCore {
1273
1273
  continue;
1274
1274
  }
1275
1275
 
1276
- if (depth === 1 && token.type === 'KEYWORD' && token.value === 'optional') {
1276
+ if (depth === 1 && (token.type === 'KEYWORD' || token.type === 'IDENTIFIER') && token.value === 'optional') {
1277
1277
  this.advance();
1278
1278
  if (this.match('LBRACE')) {
1279
1279
  this.advance();
@@ -2257,7 +2257,7 @@ function isActorKind(kindRef) {
2257
2257
 
2258
2258
  /**
2259
2259
  * @param {KindRef} kindRef
2260
- * @returns {kindRef is { array: KindRef }}
2260
+ * @returns {kindRef is { array: { of: KindRef } }}
2261
2261
  */
2262
2262
  function isArrayKind(kindRef) {
2263
2263
  return (
@@ -2304,7 +2304,7 @@ function validateKindRefConstraints(kindRef, context) {
2304
2304
  return;
2305
2305
  }
2306
2306
  if (isArrayKind(kindRef)) {
2307
- validateKindRefConstraints(kindRef.array, context);
2307
+ validateKindRefConstraints(kindRef.array.of, context);
2308
2308
  return;
2309
2309
  }
2310
2310
  if (isObjectKind(kindRef)) {
@@ -2351,7 +2351,7 @@ function kindTypesEqual(left, right) {
2351
2351
  return left.actor === right.actor;
2352
2352
  }
2353
2353
  if (isArrayKind(left) && isArrayKind(right)) {
2354
- return kindTypesEqual(left.array, right.array);
2354
+ return kindTypesEqual(left.array.of, right.array.of);
2355
2355
  }
2356
2356
  if (isObjectKind(left) && isObjectKind(right)) {
2357
2357
  const lk = Object.keys(left.object).sort();
@@ -2542,7 +2542,7 @@ function assertActorRefsExist(scene, kindRef, context) {
2542
2542
  return;
2543
2543
  }
2544
2544
  if (isArrayKind(kindRef)) {
2545
- assertActorRefsExist(scene, kindRef.array, context);
2545
+ assertActorRefsExist(scene, kindRef.array.of, context);
2546
2546
  }
2547
2547
  if (isObjectKind(kindRef)) {
2548
2548
  for (const ref of Object.values(kindRef.object)) {
@@ -11,11 +11,11 @@ export type PrimitiveKind =
11
11
  | 'date'
12
12
  | 'route';
13
13
 
14
- /** Uniform kind: primitive, object (named fields), or array. */
14
+ /** Uniform kind: primitive, object (named fields), or array. Array mirrors prose: array { of { Type } } => { array: { of: KindRef } }. */
15
15
  export type Kind =
16
16
  | { primitive: PrimitiveKind }
17
17
  | { object: Record<string, KindRef> }
18
- | { array: KindRef };
18
+ | { array: { of: KindRef } };
19
19
 
20
20
  /** Reference: full Kind or actor by name. */
21
21
  export type KindRef = Kind | { actor: string };
@@ -16,7 +16,8 @@
16
16
 
17
17
  /**
18
18
  * Uniform kind: primitive, object (named fields), or array.
19
- * @typedef {{ primitive: PrimitiveKind } | { object: Record<string, KindRef> } | { array: KindRef }} Kind
19
+ * Array mirrors prose: array { of { Type } } => { array: { of: KindRef } }.
20
+ * @typedef {{ primitive: PrimitiveKind } | { object: Record<string, KindRef> } | { array: { of: KindRef } }} Kind
20
21
  */
21
22
 
22
23
  /**
@@ -94,11 +94,11 @@ test('tools scene: portals have array kind', async () => {
94
94
 
95
95
  strictEqual(!!manifest.portals?.ContainerRows, true);
96
96
  deepStrictEqual(manifest.portals.ContainerRows.kind, {
97
- array: { actor: 'ContainerRow' },
97
+ array: { of: { actor: 'ContainerRow' } },
98
98
  });
99
99
  strictEqual(!!manifest.portals?.AnotherToolPortal, true);
100
100
  deepStrictEqual(manifest.portals.AnotherToolPortal.kind, {
101
- array: { actor: 'Something' },
101
+ array: { of: { actor: 'Something' } },
102
102
  });
103
103
  });
104
104
 
@@ -257,7 +257,7 @@ test('skills scene: derived PlayerSkills has each step with expected shape', asy
257
257
 
258
258
  const playerSkills = manifest.derived?.PlayerSkills;
259
259
  strictEqual(!!playerSkills, true);
260
- strictEqual(playerSkills?.kind?.array?.actor, 'PlayerSkill');
260
+ strictEqual(playerSkills?.kind?.array?.of?.actor, 'PlayerSkill');
261
261
  const steps = playerSkills?.steps ?? [];
262
262
  strictEqual(steps.length, 1);
263
263
  strictEqual(steps[0]?.type, 'each');