@storylet-studio/model 0.3.0 → 0.4.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/dist/index.cjs CHANGED
@@ -29,6 +29,7 @@ __export(index_exports, {
29
29
  DEFAULT_PLAY_RUNG: () => DEFAULT_PLAY_RUNG,
30
30
  FURNITURE_COLOURS: () => FURNITURE_COLOURS,
31
31
  HANDS_SCHEMA: () => HANDS_SCHEMA,
32
+ MAP_SCHEMA: () => MAP_SCHEMA,
32
33
  NOTES_SCHEMA: () => NOTES_SCHEMA,
33
34
  PLACE_GROUP: () => PLACE_GROUP,
34
35
  PROJECT_FOLDER_EXTENSION: () => PROJECT_FOLDER_EXTENSION,
@@ -562,11 +563,22 @@ var SHARD_EXTENSIONS = {
562
563
  tags: ".storylettags",
563
564
  hands: ".storylethands",
564
565
  deck: ".storyletdeck",
565
- /** The arrangement layer: where things SIT, never what they are. Its own shard
566
- * because positions churn (an afternoon of tidying a canvas touches every
567
- * card) and content does not, so a designer arranging and a writer editing
568
- * never collide on one file (design/graphical-views.md section 1.2). */
566
+ /** The AUTHOR's arrangement layer: the canvases, where cards sit on a deck's
567
+ * node canvas and the furniture drawn round them. Its own shard because
568
+ * positions churn (an afternoon of tidying a canvas touches every card) and
569
+ * content does not, so a designer arranging and a writer editing never
570
+ * collide on one file (design/graphical-views.md section 1.2). */
569
571
  view: ".storyletview",
572
+ /** The DESIGNER's map: where a box's hands stand in space, and the furniture
573
+ * round them. One per box, beside the view shard.
574
+ *
575
+ * Split out of the view shard on 2026-09-06 (design/engine-server.md 9.1
576
+ * point 5) because the two halves stopped having one owner. A hand's
577
+ * position ships in the bundle's `maps` block (4.3) and is where a venue's
578
+ * kiosk stands, so it is SHAPE, which a server's author key may not change;
579
+ * the canvases are the author's own working drawing and never leave the
580
+ * project folder. One file could not be both. */
581
+ map: ".storyletmap",
570
582
  /** Threaded comments: content-ADJACENT, so neither in a content shard (a
571
583
  * writer's deck edit must not conflict with a reviewer's comment) nor in the
572
584
  * arrangement sidecar (this is not where anything sits). One per box,
@@ -589,6 +601,7 @@ var TAGS_SCHEMA = "storylets/tags@0";
589
601
  var HANDS_SCHEMA = "storylets/hands@0";
590
602
  var DECK_SCHEMA = "storylets/deck@0";
591
603
  var VIEW_SCHEMA = "storylets/view@0";
604
+ var MAP_SCHEMA = "storylets/map@0";
592
605
  var NOTES_SCHEMA = "storylets/notes@0";
593
606
  var CONTRACT_SCHEMA = "storylets/contract@0";
594
607
  var contractPropertyPath = (p) => typeof p === "string" ? p : p.path;
@@ -605,6 +618,7 @@ var FURNITURE_COLOURS = ["paper", "amber", "sage", "sky", "rose", "slate"];
605
618
  DEFAULT_PLAY_RUNG,
606
619
  FURNITURE_COLOURS,
607
620
  HANDS_SCHEMA,
621
+ MAP_SCHEMA,
608
622
  NOTES_SCHEMA,
609
623
  PLACE_GROUP,
610
624
  PROJECT_FOLDER_EXTENSION,
package/dist/index.d.cts CHANGED
@@ -430,8 +430,9 @@ interface PropertyDecl {
430
430
  durable?: boolean;
431
431
  purpose?: string;
432
432
  }
433
- /** A card-template field (box-defined). Data for the host; the engine never
434
- * interprets fields and they are not addressable from expressions. */
433
+ /** A template field (box-defined), of the card template or of the outcome
434
+ * fields. Data for the host; the engine never interprets fields and they are
435
+ * not addressable from expressions. */
435
436
  interface FieldDecl {
436
437
  name: string;
437
438
  type: PropertyType;
@@ -544,6 +545,11 @@ interface Outcome<E> {
544
545
  /** Target ("@scope.name") -> expression; all right-hand sides evaluate
545
546
  * against pre-play state (schema 3.7). */
546
547
  changes: Record<string, E>;
548
+ /** Template data, as `Card.fields` is: field name -> value, declared by
549
+ * the box's `outcomeFields`, validated at publish, and handed to the host
550
+ * with the outcome. The engine never reads it: a press can say one line
551
+ * ("The notice is in your pocket") without spending a card on it. */
552
+ fields?: Record<string, ScalarValue>;
547
553
  }
548
554
  interface Card<E> {
549
555
  id: string;
@@ -847,6 +853,10 @@ interface Box<E> {
847
853
  };
848
854
  /** The card template: what every card in this box carries. */
849
855
  fields: FieldDecl[];
856
+ /** What every outcome in this box may carry, declared the same way.
857
+ * Absent when the box declares none, so a bundle without them is byte for
858
+ * byte what it was. */
859
+ outcomeFields?: FieldDecl[];
850
860
  properties: PropertyDecl[];
851
861
  tagGroups: TagGroup[];
852
862
  decks: Deck<E>[];
@@ -971,6 +981,8 @@ declare const SAVE_SCHEMA = "storylets/save@1";
971
981
  interface PlayRecord {
972
982
  /** Card and outcome by gameId (feeds the play-history functions). */
973
983
  card: string;
984
+ /** "" for a card with no outcomes, played with none: the key is always
985
+ * there, so a save's shape does not depend on the card. */
974
986
  outcome: string;
975
987
  turn: number;
976
988
  }
@@ -1127,11 +1139,22 @@ declare const SHARD_EXTENSIONS: {
1127
1139
  readonly tags: ".storylettags";
1128
1140
  readonly hands: ".storylethands";
1129
1141
  readonly deck: ".storyletdeck";
1130
- /** The arrangement layer: where things SIT, never what they are. Its own shard
1131
- * because positions churn (an afternoon of tidying a canvas touches every
1132
- * card) and content does not, so a designer arranging and a writer editing
1133
- * never collide on one file (design/graphical-views.md section 1.2). */
1142
+ /** The AUTHOR's arrangement layer: the canvases, where cards sit on a deck's
1143
+ * node canvas and the furniture drawn round them. Its own shard because
1144
+ * positions churn (an afternoon of tidying a canvas touches every card) and
1145
+ * content does not, so a designer arranging and a writer editing never
1146
+ * collide on one file (design/graphical-views.md section 1.2). */
1134
1147
  readonly view: ".storyletview";
1148
+ /** The DESIGNER's map: where a box's hands stand in space, and the furniture
1149
+ * round them. One per box, beside the view shard.
1150
+ *
1151
+ * Split out of the view shard on 2026-09-06 (design/engine-server.md 9.1
1152
+ * point 5) because the two halves stopped having one owner. A hand's
1153
+ * position ships in the bundle's `maps` block (4.3) and is where a venue's
1154
+ * kiosk stands, so it is SHAPE, which a server's author key may not change;
1155
+ * the canvases are the author's own working drawing and never leave the
1156
+ * project folder. One file could not be both. */
1157
+ readonly map: ".storyletmap";
1135
1158
  /** Threaded comments: content-ADJACENT, so neither in a content shard (a
1136
1159
  * writer's deck edit must not conflict with a reviewer's comment) nor in the
1137
1160
  * arrangement sidecar (this is not where anything sits). One per box,
@@ -1157,6 +1180,7 @@ declare const TAGS_SCHEMA = "storylets/tags@0";
1157
1180
  declare const HANDS_SCHEMA = "storylets/hands@0";
1158
1181
  declare const DECK_SCHEMA = "storylets/deck@0";
1159
1182
  declare const VIEW_SCHEMA = "storylets/view@0";
1183
+ declare const MAP_SCHEMA = "storylets/map@0";
1160
1184
  /** The comment sidecar's schema. Still called "notes" on disk: the file already
1161
1185
  * held both, and renaming it would break every project for no gain. */
1162
1186
  declare const NOTES_SCHEMA = "storylets/notes@0";
@@ -1203,6 +1227,10 @@ interface ContractShard {
1203
1227
  properties?: ContractProperty[];
1204
1228
  /** Card-template field names the crew and the bridges read. */
1205
1229
  fields?: string[];
1230
+ /** Outcome field names they read, the same way: the after-line a station
1231
+ * shows when a press lands. What `fields` is to the card template, this is
1232
+ * to the box's `outcomeFields`. */
1233
+ outcomeFields?: string[];
1206
1234
  }
1207
1235
  /**
1208
1236
  * One contracted property.
@@ -1284,7 +1312,9 @@ interface DeckCanvas extends CanvasFurniture {
1284
1312
  /** Keyed by CARD id. */
1285
1313
  cards?: Record<string, ViewPoint>;
1286
1314
  }
1287
- /** The box's map: where its hands sit in space, and the furniture around them. */
1315
+ /** The box's map: where its hands sit in space, and the furniture around them.
1316
+ * Carried by the MAP shard since 2026-09-06; `ViewShard.map` is the old
1317
+ * address, read for one release and never written. */
1288
1318
  interface BoxMap extends CanvasFurniture {
1289
1319
  /** Keyed by HAND id. WHERE a site is, and nothing else.
1290
1320
  *
@@ -1300,7 +1330,8 @@ interface BoxMap extends CanvasFurniture {
1300
1330
  * were edited. */
1301
1331
  sites?: Record<string, ViewPoint>;
1302
1332
  }
1303
- /** The arrangement layer for one box: where things SIT, never what they are.
1333
+ /** The AUTHOR's arrangement layer for one box: where cards sit on their decks'
1334
+ * canvases, and the furniture drawn round them.
1304
1335
  *
1305
1336
  * Its own shard on purpose (design/graphical-views.md section 1.2). Positions
1306
1337
  * churn, content does not: an afternoon of tidying a canvas touches every card,
@@ -1315,8 +1346,33 @@ interface ViewShard {
1315
1346
  schema: typeof VIEW_SCHEMA;
1316
1347
  /** Keyed by DECK id: one node canvas each. */
1317
1348
  canvases?: Record<string, DeckCanvas>;
1349
+ /** @deprecated The box map's old address, kept for one release and READ ONLY.
1350
+ * A reader that meets it uses it when the box has no `MapShard`, and the
1351
+ * formatter moves it; nothing writes it any more. Removed after the next
1352
+ * release, at which point a map left here is simply lost. */
1318
1353
  map?: BoxMap;
1319
1354
  }
1355
+ /** The DESIGNER's map for one box: where its hands stand in space.
1356
+ *
1357
+ * Split out of the view shard on 2026-09-06 (design/engine-server.md 9.1 point
1358
+ * 5). The two halves had stopped sharing an owner: a hand's position ships in
1359
+ * the bundle's `maps` block (4.3), which makes it the thing a venue provisions
1360
+ * its kiosks against, while a deck's canvas is a working drawing that never
1361
+ * leaves the folder. A server's author key may change the canvases and not
1362
+ * this.
1363
+ *
1364
+ * The map is NESTED under `map` rather than flattened to the top level, and
1365
+ * deliberately: the block's bytes are then exactly what the view shard held, so
1366
+ * the migration is a move of a value rather than a reshaping of it, the merge
1367
+ * strategy carries over word for word, and a reader that has to look in both
1368
+ * places is one expression (`box.map?.map ?? box.view?.map`).
1369
+ *
1370
+ * Source-only in the sense the view shard is not: `compileMaps` reads the
1371
+ * positions for the bundle's `maps` block, under `export.map`. */
1372
+ interface MapShard {
1373
+ schema: typeof MAP_SCHEMA;
1374
+ map: BoxMap;
1375
+ }
1320
1376
  /** A coverage input driver: during a coverage run the harness feeds a
1321
1377
  * host-seam property (`@world.x`) values from `values`, so content gated on
1322
1378
  * external state gets exercised (Patter's coverageDrivers, carried whole). */
@@ -1416,6 +1472,9 @@ interface BoxShard {
1416
1472
  seconds: number;
1417
1473
  };
1418
1474
  fields: FieldDecl[];
1475
+ /** The outcome fields (see `Box.outcomeFields`); a shard without the key
1476
+ * declares none. */
1477
+ outcomeFields?: FieldDecl[];
1419
1478
  properties: PropertyDecl[];
1420
1479
  };
1421
1480
  }
@@ -1449,4 +1508,4 @@ interface DeckShard {
1449
1508
  cards: Card<string>[];
1450
1509
  }
1451
1510
 
1452
- export { BOX_SCHEMA, BUNDLE_EXTENSION, BUNDLE_SCHEMA, type Box, type BoxMap, type BoxShard, type Bundle, type BundleBackground, type BundleContent, type BundleMap, type BundleSettings, CONTRACTS_DIR, CONTRACT_SCHEMA, type CanvasFurniture, type Card, type Comment, type CommentMark, type CommentMessage, type ContractProperty, type ContractShard, type CoverageConfig, type CoverageDriver, DECK_SCHEMA, DEFAULT_PLAY_RUNG, type Deck, type DeckCanvas, type DeckShard, FURNITURE_COLOURS, type FieldDecl, type FlowSave, type Frame, type FurnitureColour, HANDS_SCHEMA, type Hand, type HandBinding, type HandRule, type HandTemplate, type HandsShard, type HoleRef, type HoleRefScope, type LoadEviction, type LoadProperty, type LoadReport, NOTES_SCHEMA, type NotesShard, type Outcome, PLACE_GROUP, PROJECT_FOLDER_EXTENSION, PROJECT_SCHEMA, type PlayRecord, type PlayRung, type Polygon, type ProjectSettings, type ProjectShard, type PropertyBag, type PropertyDecl, type PropertyType, type PropsPartition, type Rect, type RedrawPolicy, SAVEFILE_SCHEMA, SAVE_SCHEMA, SHARD_EXTENSIONS, SPATIAL, type SaveEnvelope, type SaveFile, type SharedSave, type SpatialBackground, type SpatialGroup, type StackMove, type Stacked, TAGS_SCHEMA, type Tag, type TagGroup, type TagsShard, VIEW_SCHEMA, type ValueAddresses, type ViewPoint, type ViewShard, ambiguousValueAddressMessage, backgroundsOf, bindHand, bundleAssetPath, byDisplayOrder, centroid, commentsOf, contractPropertyPath, contractPropertyType, droppedRect, effectiveGameId, framesOf, freeGameId, freeTitle, gameIdify, handBinding, inferDeclFromWrite, isHoleRef, isSpatial, isValidGameId, labelPoint, markOf, marksOn, openThreadCounts, parseHoleRef, pointInPolygon, polygonBounds, polygonOf, restack, spatialOf, stacked, threadsFor, turnSpan, unbindHand, valueAddresses, withBackgrounds, withPolygon, withSpatialGroup, withZ, zOf, zoneAt, zonesAt };
1511
+ export { BOX_SCHEMA, BUNDLE_EXTENSION, BUNDLE_SCHEMA, type Box, type BoxMap, type BoxShard, type Bundle, type BundleBackground, type BundleContent, type BundleMap, type BundleSettings, CONTRACTS_DIR, CONTRACT_SCHEMA, type CanvasFurniture, type Card, type Comment, type CommentMark, type CommentMessage, type ContractProperty, type ContractShard, type CoverageConfig, type CoverageDriver, DECK_SCHEMA, DEFAULT_PLAY_RUNG, type Deck, type DeckCanvas, type DeckShard, FURNITURE_COLOURS, type FieldDecl, type FlowSave, type Frame, type FurnitureColour, HANDS_SCHEMA, type Hand, type HandBinding, type HandRule, type HandTemplate, type HandsShard, type HoleRef, type HoleRefScope, type LoadEviction, type LoadProperty, type LoadReport, MAP_SCHEMA, type MapShard, NOTES_SCHEMA, type NotesShard, type Outcome, PLACE_GROUP, PROJECT_FOLDER_EXTENSION, PROJECT_SCHEMA, type PlayRecord, type PlayRung, type Polygon, type ProjectSettings, type ProjectShard, type PropertyBag, type PropertyDecl, type PropertyType, type PropsPartition, type Rect, type RedrawPolicy, SAVEFILE_SCHEMA, SAVE_SCHEMA, SHARD_EXTENSIONS, SPATIAL, type SaveEnvelope, type SaveFile, type SharedSave, type SpatialBackground, type SpatialGroup, type StackMove, type Stacked, TAGS_SCHEMA, type Tag, type TagGroup, type TagsShard, VIEW_SCHEMA, type ValueAddresses, type ViewPoint, type ViewShard, ambiguousValueAddressMessage, backgroundsOf, bindHand, bundleAssetPath, byDisplayOrder, centroid, commentsOf, contractPropertyPath, contractPropertyType, droppedRect, effectiveGameId, framesOf, freeGameId, freeTitle, gameIdify, handBinding, inferDeclFromWrite, isHoleRef, isSpatial, isValidGameId, labelPoint, markOf, marksOn, openThreadCounts, parseHoleRef, pointInPolygon, polygonBounds, polygonOf, restack, spatialOf, stacked, threadsFor, turnSpan, unbindHand, valueAddresses, withBackgrounds, withPolygon, withSpatialGroup, withZ, zOf, zoneAt, zonesAt };
package/dist/index.d.ts CHANGED
@@ -430,8 +430,9 @@ interface PropertyDecl {
430
430
  durable?: boolean;
431
431
  purpose?: string;
432
432
  }
433
- /** A card-template field (box-defined). Data for the host; the engine never
434
- * interprets fields and they are not addressable from expressions. */
433
+ /** A template field (box-defined), of the card template or of the outcome
434
+ * fields. Data for the host; the engine never interprets fields and they are
435
+ * not addressable from expressions. */
435
436
  interface FieldDecl {
436
437
  name: string;
437
438
  type: PropertyType;
@@ -544,6 +545,11 @@ interface Outcome<E> {
544
545
  /** Target ("@scope.name") -> expression; all right-hand sides evaluate
545
546
  * against pre-play state (schema 3.7). */
546
547
  changes: Record<string, E>;
548
+ /** Template data, as `Card.fields` is: field name -> value, declared by
549
+ * the box's `outcomeFields`, validated at publish, and handed to the host
550
+ * with the outcome. The engine never reads it: a press can say one line
551
+ * ("The notice is in your pocket") without spending a card on it. */
552
+ fields?: Record<string, ScalarValue>;
547
553
  }
548
554
  interface Card<E> {
549
555
  id: string;
@@ -847,6 +853,10 @@ interface Box<E> {
847
853
  };
848
854
  /** The card template: what every card in this box carries. */
849
855
  fields: FieldDecl[];
856
+ /** What every outcome in this box may carry, declared the same way.
857
+ * Absent when the box declares none, so a bundle without them is byte for
858
+ * byte what it was. */
859
+ outcomeFields?: FieldDecl[];
850
860
  properties: PropertyDecl[];
851
861
  tagGroups: TagGroup[];
852
862
  decks: Deck<E>[];
@@ -971,6 +981,8 @@ declare const SAVE_SCHEMA = "storylets/save@1";
971
981
  interface PlayRecord {
972
982
  /** Card and outcome by gameId (feeds the play-history functions). */
973
983
  card: string;
984
+ /** "" for a card with no outcomes, played with none: the key is always
985
+ * there, so a save's shape does not depend on the card. */
974
986
  outcome: string;
975
987
  turn: number;
976
988
  }
@@ -1127,11 +1139,22 @@ declare const SHARD_EXTENSIONS: {
1127
1139
  readonly tags: ".storylettags";
1128
1140
  readonly hands: ".storylethands";
1129
1141
  readonly deck: ".storyletdeck";
1130
- /** The arrangement layer: where things SIT, never what they are. Its own shard
1131
- * because positions churn (an afternoon of tidying a canvas touches every
1132
- * card) and content does not, so a designer arranging and a writer editing
1133
- * never collide on one file (design/graphical-views.md section 1.2). */
1142
+ /** The AUTHOR's arrangement layer: the canvases, where cards sit on a deck's
1143
+ * node canvas and the furniture drawn round them. Its own shard because
1144
+ * positions churn (an afternoon of tidying a canvas touches every card) and
1145
+ * content does not, so a designer arranging and a writer editing never
1146
+ * collide on one file (design/graphical-views.md section 1.2). */
1134
1147
  readonly view: ".storyletview";
1148
+ /** The DESIGNER's map: where a box's hands stand in space, and the furniture
1149
+ * round them. One per box, beside the view shard.
1150
+ *
1151
+ * Split out of the view shard on 2026-09-06 (design/engine-server.md 9.1
1152
+ * point 5) because the two halves stopped having one owner. A hand's
1153
+ * position ships in the bundle's `maps` block (4.3) and is where a venue's
1154
+ * kiosk stands, so it is SHAPE, which a server's author key may not change;
1155
+ * the canvases are the author's own working drawing and never leave the
1156
+ * project folder. One file could not be both. */
1157
+ readonly map: ".storyletmap";
1135
1158
  /** Threaded comments: content-ADJACENT, so neither in a content shard (a
1136
1159
  * writer's deck edit must not conflict with a reviewer's comment) nor in the
1137
1160
  * arrangement sidecar (this is not where anything sits). One per box,
@@ -1157,6 +1180,7 @@ declare const TAGS_SCHEMA = "storylets/tags@0";
1157
1180
  declare const HANDS_SCHEMA = "storylets/hands@0";
1158
1181
  declare const DECK_SCHEMA = "storylets/deck@0";
1159
1182
  declare const VIEW_SCHEMA = "storylets/view@0";
1183
+ declare const MAP_SCHEMA = "storylets/map@0";
1160
1184
  /** The comment sidecar's schema. Still called "notes" on disk: the file already
1161
1185
  * held both, and renaming it would break every project for no gain. */
1162
1186
  declare const NOTES_SCHEMA = "storylets/notes@0";
@@ -1203,6 +1227,10 @@ interface ContractShard {
1203
1227
  properties?: ContractProperty[];
1204
1228
  /** Card-template field names the crew and the bridges read. */
1205
1229
  fields?: string[];
1230
+ /** Outcome field names they read, the same way: the after-line a station
1231
+ * shows when a press lands. What `fields` is to the card template, this is
1232
+ * to the box's `outcomeFields`. */
1233
+ outcomeFields?: string[];
1206
1234
  }
1207
1235
  /**
1208
1236
  * One contracted property.
@@ -1284,7 +1312,9 @@ interface DeckCanvas extends CanvasFurniture {
1284
1312
  /** Keyed by CARD id. */
1285
1313
  cards?: Record<string, ViewPoint>;
1286
1314
  }
1287
- /** The box's map: where its hands sit in space, and the furniture around them. */
1315
+ /** The box's map: where its hands sit in space, and the furniture around them.
1316
+ * Carried by the MAP shard since 2026-09-06; `ViewShard.map` is the old
1317
+ * address, read for one release and never written. */
1288
1318
  interface BoxMap extends CanvasFurniture {
1289
1319
  /** Keyed by HAND id. WHERE a site is, and nothing else.
1290
1320
  *
@@ -1300,7 +1330,8 @@ interface BoxMap extends CanvasFurniture {
1300
1330
  * were edited. */
1301
1331
  sites?: Record<string, ViewPoint>;
1302
1332
  }
1303
- /** The arrangement layer for one box: where things SIT, never what they are.
1333
+ /** The AUTHOR's arrangement layer for one box: where cards sit on their decks'
1334
+ * canvases, and the furniture drawn round them.
1304
1335
  *
1305
1336
  * Its own shard on purpose (design/graphical-views.md section 1.2). Positions
1306
1337
  * churn, content does not: an afternoon of tidying a canvas touches every card,
@@ -1315,8 +1346,33 @@ interface ViewShard {
1315
1346
  schema: typeof VIEW_SCHEMA;
1316
1347
  /** Keyed by DECK id: one node canvas each. */
1317
1348
  canvases?: Record<string, DeckCanvas>;
1349
+ /** @deprecated The box map's old address, kept for one release and READ ONLY.
1350
+ * A reader that meets it uses it when the box has no `MapShard`, and the
1351
+ * formatter moves it; nothing writes it any more. Removed after the next
1352
+ * release, at which point a map left here is simply lost. */
1318
1353
  map?: BoxMap;
1319
1354
  }
1355
+ /** The DESIGNER's map for one box: where its hands stand in space.
1356
+ *
1357
+ * Split out of the view shard on 2026-09-06 (design/engine-server.md 9.1 point
1358
+ * 5). The two halves had stopped sharing an owner: a hand's position ships in
1359
+ * the bundle's `maps` block (4.3), which makes it the thing a venue provisions
1360
+ * its kiosks against, while a deck's canvas is a working drawing that never
1361
+ * leaves the folder. A server's author key may change the canvases and not
1362
+ * this.
1363
+ *
1364
+ * The map is NESTED under `map` rather than flattened to the top level, and
1365
+ * deliberately: the block's bytes are then exactly what the view shard held, so
1366
+ * the migration is a move of a value rather than a reshaping of it, the merge
1367
+ * strategy carries over word for word, and a reader that has to look in both
1368
+ * places is one expression (`box.map?.map ?? box.view?.map`).
1369
+ *
1370
+ * Source-only in the sense the view shard is not: `compileMaps` reads the
1371
+ * positions for the bundle's `maps` block, under `export.map`. */
1372
+ interface MapShard {
1373
+ schema: typeof MAP_SCHEMA;
1374
+ map: BoxMap;
1375
+ }
1320
1376
  /** A coverage input driver: during a coverage run the harness feeds a
1321
1377
  * host-seam property (`@world.x`) values from `values`, so content gated on
1322
1378
  * external state gets exercised (Patter's coverageDrivers, carried whole). */
@@ -1416,6 +1472,9 @@ interface BoxShard {
1416
1472
  seconds: number;
1417
1473
  };
1418
1474
  fields: FieldDecl[];
1475
+ /** The outcome fields (see `Box.outcomeFields`); a shard without the key
1476
+ * declares none. */
1477
+ outcomeFields?: FieldDecl[];
1419
1478
  properties: PropertyDecl[];
1420
1479
  };
1421
1480
  }
@@ -1449,4 +1508,4 @@ interface DeckShard {
1449
1508
  cards: Card<string>[];
1450
1509
  }
1451
1510
 
1452
- export { BOX_SCHEMA, BUNDLE_EXTENSION, BUNDLE_SCHEMA, type Box, type BoxMap, type BoxShard, type Bundle, type BundleBackground, type BundleContent, type BundleMap, type BundleSettings, CONTRACTS_DIR, CONTRACT_SCHEMA, type CanvasFurniture, type Card, type Comment, type CommentMark, type CommentMessage, type ContractProperty, type ContractShard, type CoverageConfig, type CoverageDriver, DECK_SCHEMA, DEFAULT_PLAY_RUNG, type Deck, type DeckCanvas, type DeckShard, FURNITURE_COLOURS, type FieldDecl, type FlowSave, type Frame, type FurnitureColour, HANDS_SCHEMA, type Hand, type HandBinding, type HandRule, type HandTemplate, type HandsShard, type HoleRef, type HoleRefScope, type LoadEviction, type LoadProperty, type LoadReport, NOTES_SCHEMA, type NotesShard, type Outcome, PLACE_GROUP, PROJECT_FOLDER_EXTENSION, PROJECT_SCHEMA, type PlayRecord, type PlayRung, type Polygon, type ProjectSettings, type ProjectShard, type PropertyBag, type PropertyDecl, type PropertyType, type PropsPartition, type Rect, type RedrawPolicy, SAVEFILE_SCHEMA, SAVE_SCHEMA, SHARD_EXTENSIONS, SPATIAL, type SaveEnvelope, type SaveFile, type SharedSave, type SpatialBackground, type SpatialGroup, type StackMove, type Stacked, TAGS_SCHEMA, type Tag, type TagGroup, type TagsShard, VIEW_SCHEMA, type ValueAddresses, type ViewPoint, type ViewShard, ambiguousValueAddressMessage, backgroundsOf, bindHand, bundleAssetPath, byDisplayOrder, centroid, commentsOf, contractPropertyPath, contractPropertyType, droppedRect, effectiveGameId, framesOf, freeGameId, freeTitle, gameIdify, handBinding, inferDeclFromWrite, isHoleRef, isSpatial, isValidGameId, labelPoint, markOf, marksOn, openThreadCounts, parseHoleRef, pointInPolygon, polygonBounds, polygonOf, restack, spatialOf, stacked, threadsFor, turnSpan, unbindHand, valueAddresses, withBackgrounds, withPolygon, withSpatialGroup, withZ, zOf, zoneAt, zonesAt };
1511
+ export { BOX_SCHEMA, BUNDLE_EXTENSION, BUNDLE_SCHEMA, type Box, type BoxMap, type BoxShard, type Bundle, type BundleBackground, type BundleContent, type BundleMap, type BundleSettings, CONTRACTS_DIR, CONTRACT_SCHEMA, type CanvasFurniture, type Card, type Comment, type CommentMark, type CommentMessage, type ContractProperty, type ContractShard, type CoverageConfig, type CoverageDriver, DECK_SCHEMA, DEFAULT_PLAY_RUNG, type Deck, type DeckCanvas, type DeckShard, FURNITURE_COLOURS, type FieldDecl, type FlowSave, type Frame, type FurnitureColour, HANDS_SCHEMA, type Hand, type HandBinding, type HandRule, type HandTemplate, type HandsShard, type HoleRef, type HoleRefScope, type LoadEviction, type LoadProperty, type LoadReport, MAP_SCHEMA, type MapShard, NOTES_SCHEMA, type NotesShard, type Outcome, PLACE_GROUP, PROJECT_FOLDER_EXTENSION, PROJECT_SCHEMA, type PlayRecord, type PlayRung, type Polygon, type ProjectSettings, type ProjectShard, type PropertyBag, type PropertyDecl, type PropertyType, type PropsPartition, type Rect, type RedrawPolicy, SAVEFILE_SCHEMA, SAVE_SCHEMA, SHARD_EXTENSIONS, SPATIAL, type SaveEnvelope, type SaveFile, type SharedSave, type SpatialBackground, type SpatialGroup, type StackMove, type Stacked, TAGS_SCHEMA, type Tag, type TagGroup, type TagsShard, VIEW_SCHEMA, type ValueAddresses, type ViewPoint, type ViewShard, ambiguousValueAddressMessage, backgroundsOf, bindHand, bundleAssetPath, byDisplayOrder, centroid, commentsOf, contractPropertyPath, contractPropertyType, droppedRect, effectiveGameId, framesOf, freeGameId, freeTitle, gameIdify, handBinding, inferDeclFromWrite, isHoleRef, isSpatial, isValidGameId, labelPoint, markOf, marksOn, openThreadCounts, parseHoleRef, pointInPolygon, polygonBounds, polygonOf, restack, spatialOf, stacked, threadsFor, turnSpan, unbindHand, valueAddresses, withBackgrounds, withPolygon, withSpatialGroup, withZ, zOf, zoneAt, zonesAt };
package/dist/index.js CHANGED
@@ -479,11 +479,22 @@ var SHARD_EXTENSIONS = {
479
479
  tags: ".storylettags",
480
480
  hands: ".storylethands",
481
481
  deck: ".storyletdeck",
482
- /** The arrangement layer: where things SIT, never what they are. Its own shard
483
- * because positions churn (an afternoon of tidying a canvas touches every
484
- * card) and content does not, so a designer arranging and a writer editing
485
- * never collide on one file (design/graphical-views.md section 1.2). */
482
+ /** The AUTHOR's arrangement layer: the canvases, where cards sit on a deck's
483
+ * node canvas and the furniture drawn round them. Its own shard because
484
+ * positions churn (an afternoon of tidying a canvas touches every card) and
485
+ * content does not, so a designer arranging and a writer editing never
486
+ * collide on one file (design/graphical-views.md section 1.2). */
486
487
  view: ".storyletview",
488
+ /** The DESIGNER's map: where a box's hands stand in space, and the furniture
489
+ * round them. One per box, beside the view shard.
490
+ *
491
+ * Split out of the view shard on 2026-09-06 (design/engine-server.md 9.1
492
+ * point 5) because the two halves stopped having one owner. A hand's
493
+ * position ships in the bundle's `maps` block (4.3) and is where a venue's
494
+ * kiosk stands, so it is SHAPE, which a server's author key may not change;
495
+ * the canvases are the author's own working drawing and never leave the
496
+ * project folder. One file could not be both. */
497
+ map: ".storyletmap",
487
498
  /** Threaded comments: content-ADJACENT, so neither in a content shard (a
488
499
  * writer's deck edit must not conflict with a reviewer's comment) nor in the
489
500
  * arrangement sidecar (this is not where anything sits). One per box,
@@ -506,6 +517,7 @@ var TAGS_SCHEMA = "storylets/tags@0";
506
517
  var HANDS_SCHEMA = "storylets/hands@0";
507
518
  var DECK_SCHEMA = "storylets/deck@0";
508
519
  var VIEW_SCHEMA = "storylets/view@0";
520
+ var MAP_SCHEMA = "storylets/map@0";
509
521
  var NOTES_SCHEMA = "storylets/notes@0";
510
522
  var CONTRACT_SCHEMA = "storylets/contract@0";
511
523
  var contractPropertyPath = (p) => typeof p === "string" ? p : p.path;
@@ -521,6 +533,7 @@ export {
521
533
  DEFAULT_PLAY_RUNG,
522
534
  FURNITURE_COLOURS,
523
535
  HANDS_SCHEMA,
536
+ MAP_SCHEMA,
524
537
  NOTES_SCHEMA,
525
538
  PLACE_GROUP,
526
539
  PROJECT_FOLDER_EXTENSION,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@storylet-studio/model",
3
- "version": "0.3.0",
3
+ "version": "0.4.1",
4
4
  "description": "Storylets data-model types: source shards (project / box / tags / hands / deck), the compiled bundle, the save envelope. The shape source-of-truth.",
5
5
  "type": "module",
6
6
  "license": "MIT",