@dreamboard-games/sdk 0.4.0-alpha.13 → 0.4.0-alpha.14

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 (81) hide show
  1. package/README.md +29 -11
  2. package/dist/authoring/index.d.ts +3 -6
  3. package/dist/authoring/index.js +2 -2
  4. package/dist/authoring-compiler.d.ts +3 -3
  5. package/dist/authoring-compiler.js +3 -4
  6. package/dist/authoring-materialize-cli.js +5 -6
  7. package/dist/authoring-materialize-cli.js.map +1 -1
  8. package/dist/browser-interaction.d.ts +21 -21
  9. package/dist/{chunk-3PFDHTR7.js → chunk-3VSOH3TZ.js} +29 -2
  10. package/dist/chunk-3VSOH3TZ.js.map +1 -0
  11. package/dist/{chunk-OFIDC7DJ.js → chunk-73YISGYO.js} +4 -4
  12. package/dist/chunk-73YISGYO.js.map +1 -0
  13. package/dist/{chunk-YNW3KBDE.js → chunk-7QKE5BFU.js} +2 -2
  14. package/dist/{chunk-KZFHTUI5.js → chunk-CHOXM43O.js} +4 -4
  15. package/dist/chunk-CSIEFYTC.js +9 -0
  16. package/dist/chunk-CSIEFYTC.js.map +1 -0
  17. package/dist/{chunk-MLFHVYF7.js → chunk-KH6AET7P.js} +4 -4
  18. package/dist/chunk-KH6AET7P.js.map +1 -0
  19. package/dist/{chunk-MPVC2SU6.js → chunk-LMHCGCA6.js} +2 -2
  20. package/dist/{chunk-WAQUD4IG.js → chunk-NLZDRIVW.js} +16 -16
  21. package/dist/{chunk-5XTAQ4EQ.js → chunk-TO6WRLRN.js} +2 -2
  22. package/dist/{chunk-42HQLHVA.js → chunk-VJVKGWHW.js} +4 -7
  23. package/dist/chunk-VJVKGWHW.js.map +1 -0
  24. package/dist/{chunk-YOLIZMXR.js → chunk-VRRR6QZT.js} +3 -3
  25. package/dist/{chunk-YOLIZMXR.js.map → chunk-VRRR6QZT.js.map} +1 -1
  26. package/dist/{chunk-XDGRC6OR.js → chunk-WASWAYYX.js} +3 -3
  27. package/dist/{chunk-7JBPOJOF.js → chunk-ZGQGFXFG.js} +9 -9
  28. package/dist/{index.d-C7Ztirg6.d.ts → index.d-90ms7Mwh.d.ts} +124 -115
  29. package/dist/index.js +2 -2
  30. package/dist/package-set.d.ts +2 -2
  31. package/dist/package-set.js +2 -2
  32. package/dist/reducer/advanced.js +3 -3
  33. package/dist/reducer-contract.d.ts +1 -1
  34. package/dist/reducer-contract.js +3 -1
  35. package/dist/reducer.d.ts +1 -1
  36. package/dist/reducer.js +3 -3
  37. package/dist/reference-games/index.d.ts +29 -11
  38. package/dist/reference-games/index.js +43 -45
  39. package/dist/reference-games/index.js.map +1 -1
  40. package/dist/runtime/primitives.js +4 -4
  41. package/dist/runtime/workspace-contract.js +8 -8
  42. package/dist/runtime.js +12 -12
  43. package/dist/testing-compiler.d.ts +1 -1
  44. package/dist/testing-compiler.js +1 -4
  45. package/dist/testing-compiler.js.map +1 -1
  46. package/dist/testing-runtime.d.ts +3 -3
  47. package/dist/testing-runtime.js +5 -5
  48. package/dist/testing.d.ts +5 -140
  49. package/dist/testing.js +5 -450
  50. package/dist/testing.js.map +1 -1
  51. package/dist/{types-B-FI0jrx.d.ts → types-Cs_Jp0cf.d.ts} +1 -1
  52. package/dist/ui/components.js +1 -1
  53. package/dist/ui.js +2 -2
  54. package/package.json +22 -29
  55. package/REFERENCE.md +0 -25375
  56. package/dist/chunk-3PFDHTR7.js.map +0 -1
  57. package/dist/chunk-42HQLHVA.js.map +0 -1
  58. package/dist/chunk-MLFHVYF7.js.map +0 -1
  59. package/dist/chunk-OFIDC7DJ.js.map +0 -1
  60. package/dist/chunk-THWT4V3Z.js +0 -12
  61. package/dist/chunk-THWT4V3Z.js.map +0 -1
  62. package/dist/chunk-UNVCT5Z7.js +0 -73
  63. package/dist/chunk-UNVCT5Z7.js.map +0 -1
  64. package/dist/chunk-UTSBXZAM.js +0 -435
  65. package/dist/chunk-UTSBXZAM.js.map +0 -1
  66. package/dist/chunk-YN5W67YL.js +0 -174
  67. package/dist/chunk-YN5W67YL.js.map +0 -1
  68. package/dist/reference-game-compiler.d.ts +0 -45
  69. package/dist/reference-game-compiler.js +0 -25
  70. package/dist/reference-game-compiler.js.map +0 -1
  71. package/dist/reference-game-source-manifest-cli.d.ts +0 -1
  72. package/dist/reference-game-source-manifest-cli.js +0 -84
  73. package/dist/reference-game-source-manifest-cli.js.map +0 -1
  74. package/dist/schema-CJc0UfjJ.d.ts +0 -216
  75. /package/dist/{chunk-YNW3KBDE.js.map → chunk-7QKE5BFU.js.map} +0 -0
  76. /package/dist/{chunk-KZFHTUI5.js.map → chunk-CHOXM43O.js.map} +0 -0
  77. /package/dist/{chunk-MPVC2SU6.js.map → chunk-LMHCGCA6.js.map} +0 -0
  78. /package/dist/{chunk-WAQUD4IG.js.map → chunk-NLZDRIVW.js.map} +0 -0
  79. /package/dist/{chunk-5XTAQ4EQ.js.map → chunk-TO6WRLRN.js.map} +0 -0
  80. /package/dist/{chunk-XDGRC6OR.js.map → chunk-WASWAYYX.js.map} +0 -0
  81. /package/dist/{chunk-7JBPOJOF.js.map → chunk-ZGQGFXFG.js.map} +0 -0
package/dist/index.js CHANGED
@@ -2,8 +2,8 @@ import {
2
2
  DREAMBOARD_SDK_PACKAGES,
3
3
  DREAMBOARD_SDK_PACKAGE_SET,
4
4
  DREAMBOARD_SDK_VERSION
5
- } from "./chunk-MLFHVYF7.js";
6
- import "./chunk-THWT4V3Z.js";
5
+ } from "./chunk-KH6AET7P.js";
6
+ import "./chunk-CSIEFYTC.js";
7
7
  import "./chunk-PZ5AY32C.js";
8
8
  export {
9
9
  DREAMBOARD_SDK_PACKAGES,
@@ -1,6 +1,6 @@
1
- declare const DREAMBOARD_SDK_VERSION: "0.4.0-alpha.13";
1
+ declare const DREAMBOARD_SDK_VERSION: string;
2
2
  declare const DREAMBOARD_SDK_PACKAGES: {
3
- readonly "@dreamboard-games/sdk": "0.4.0-alpha.13";
3
+ readonly "@dreamboard-games/sdk": string;
4
4
  };
5
5
  type DreamboardSdkPackageName = keyof typeof DREAMBOARD_SDK_PACKAGES;
6
6
  type DreamboardSdkPackageSet = {
@@ -2,8 +2,8 @@ import {
2
2
  DREAMBOARD_SDK_PACKAGES,
3
3
  DREAMBOARD_SDK_PACKAGE_SET,
4
4
  DREAMBOARD_SDK_VERSION
5
- } from "./chunk-MLFHVYF7.js";
6
- import "./chunk-THWT4V3Z.js";
5
+ } from "./chunk-KH6AET7P.js";
6
+ import "./chunk-CSIEFYTC.js";
7
7
  import "./chunk-PZ5AY32C.js";
8
8
  export {
9
9
  DREAMBOARD_SDK_PACKAGES,
@@ -7,7 +7,7 @@ import {
7
7
  } from "../chunk-VWTKGIYF.js";
8
8
  import {
9
9
  createClientParamSchemasByPhase
10
- } from "../chunk-5XTAQ4EQ.js";
10
+ } from "../chunk-TO6WRLRN.js";
11
11
  import {
12
12
  FrameworkErrorCodes,
13
13
  applySetupBootstrap,
@@ -20,8 +20,8 @@ import {
20
20
  manifestSchemaFamily,
21
21
  markManifestScopedSchema,
22
22
  resolveManifestPlayerIds
23
- } from "../chunk-YNW3KBDE.js";
24
- import "../chunk-3PFDHTR7.js";
23
+ } from "../chunk-7QKE5BFU.js";
24
+ import "../chunk-3VSOH3TZ.js";
25
25
  import "../chunk-PZ5AY32C.js";
26
26
  export {
27
27
  FrameworkErrorCodes,
@@ -1,3 +1,3 @@
1
- export { M as MaybePromise, R as REDUCER_CONTRACT_VERSION, a as ReducerBundleContract, w as ReducerWire, z as ReducerWireZod } from './index.d-C7Ztirg6.js';
1
+ export { M as MaybePromise, R as REDUCER_CONTRACT_VERSION, a as ReducerBundleContract, w as ReducerWire, z as ReducerWireZod, b as assertReducerBundleContract } from './index.d-90ms7Mwh.js';
2
2
  export { materializeManifestTable } from './codegen.js';
3
3
  import 'zod';
@@ -1,7 +1,8 @@
1
1
  import {
2
2
  REDUCER_CONTRACT_VERSION,
3
+ assertReducerBundleContract,
3
4
  zod_exports
4
- } from "./chunk-3PFDHTR7.js";
5
+ } from "./chunk-3VSOH3TZ.js";
5
6
  import {
6
7
  materializeManifestTable
7
8
  } from "./chunk-HIH6Y4FA.js";
@@ -9,6 +10,7 @@ import "./chunk-PZ5AY32C.js";
9
10
  export {
10
11
  REDUCER_CONTRACT_VERSION,
11
12
  zod_exports as ReducerWireZod,
13
+ assertReducerBundleContract,
12
14
  materializeManifestTable
13
15
  };
14
16
  //# sourceMappingURL=reducer-contract.js.map
package/dist/reducer.d.ts CHANGED
@@ -3,7 +3,7 @@ import { V as GeneratedManifestContractLike, bV as RuntimeTableRecord, cC as Sta
3
3
  export { h as BoardRef, R as FrameworkErrorCodes, S as GameEvent, T as GameEventDetail, U as GameOutcome, al as OutcomeResult, am as OutcomeScoreComponent, an as OutcomeStanding, ao as OutcomeTieBreak, ap as PerPlayer, aq as PerPlayerBoardRef, ar as PerPlayerSchemaOptions, aE as PlayerId, aP as ReducerAccept, aQ as ReducerAcceptOptions, aU as ReducerReject, aV as ReducerResult, aY as ReducerValidationResult, ck as SharedBoardRef, cZ as asPlayerId, c$ as boardRef, d0 as boardRefKey, d1 as boardRefSchema, d7 as isPerPlayer, d8 as isPerPlayerBoardRef, d9 as isPlayerId, da as isSharedBoardRef, dd as parseBoardRefKey, de as perPlayer, df as perPlayerBoardRef, dg as perPlayerEntries, dh as perPlayerGet, di as perPlayerHas, dj as perPlayerKeys, dk as perPlayerMap, dl as perPlayerRequire, dm as perPlayerSchema, dn as perPlayerSet, dp as perPlayerSize, dq as perPlayerValues, ds as sharedBoardRef } from './runtime-BhuaOkIL.js';
4
4
  import { j as BaseGameStateOfContract, aq as PhaseDefinition, aB as PlayerViewDefinition, aZ as SharedViewDefinition, aG as ReducerGameContract, Z as InputCollector, y as CollectorState, K as DerivedResolver, ba as ValidationIssue, b9 as TargetKind, a4 as InputSelectionDescriptor, a1 as InputDomainDescriptor, n as BoardTargetDomainDescriptor, l as BoardInputCollectorMeta, f as AnyInteractionSpec, d as AnyCardActionSpec, R as EffectMap, aY as ScopedPhaseState, b4 as StageMap, ay as PhaseZoneList, C as CardActionMap, au as PhaseMapOf, bc as ViewMapOf, aI as ReducerGameDefinition, W as EmptyViewDefinition, b7 as StaticViewDefinition, af as InteractionSpec, p as CardActionSpec, ad as InteractionRule, aa as InteractionMap, z as ContinuationCallable, T as EffectRollDieDefinition, U as EffectShuffleDefinition, V as EffectShufflePlayerZoneDefinition, b6 as StageSpec, aH as ReducerGameContractLike } from './views-BbCGDuCs.js';
5
5
  export { J as DerivedDefinition, X as GameStateOf, Y as InitialStateCallbacks, an as Op, aF as ReducerEdit, aJ as ReducerOps, aL as ReducerStateBase, aN as ReducerTransaction, aW as RotatePlayerZoneArgs, bh as createDerivedResolver, bi as createReducerEdit, bj as createReducerOps, bk as createReducerTransaction, bl as defineDerived, bm as pipe } from './views-BbCGDuCs.js';
6
- import { a as ReducerBundleContract, w as wire } from './index.d-C7Ztirg6.js';
6
+ import { a as ReducerBundleContract, w as wire } from './index.d-90ms7Mwh.js';
7
7
  import { a as ReducerDiagnosticsSink } from './diagnostics-DIi3ina7.js';
8
8
  export { D as DispatchTraceSummaryEntry, R as ReducerDiagnosticEvent, n as noopDiagnosticsSink } from './diagnostics-DIi3ina7.js';
9
9
  export { S as StaleContractArtifactError, a as StaleContractArtifactErrorOptions, b as StaleContractArtifactKind, i as isStaleContractArtifactError } from './stale-contract-artifact-error-XLaweZtF.js';
package/dist/reducer.js CHANGED
@@ -11,7 +11,7 @@ import {
11
11
  defineDerived,
12
12
  isStaleContractArtifactError,
13
13
  noopDiagnosticsSink
14
- } from "./chunk-XDGRC6OR.js";
14
+ } from "./chunk-WASWAYYX.js";
15
15
  import {
16
16
  FrameworkErrorCodes,
17
17
  asPlayerId,
@@ -45,9 +45,9 @@ import {
45
45
  perPlayerValues,
46
46
  setActivePlayers,
47
47
  sharedBoardRef
48
- } from "./chunk-YNW3KBDE.js";
48
+ } from "./chunk-7QKE5BFU.js";
49
49
  import "./chunk-PF7L4BMG.js";
50
- import "./chunk-3PFDHTR7.js";
50
+ import "./chunk-3VSOH3TZ.js";
51
51
  import "./chunk-PZ5AY32C.js";
52
52
 
53
53
  // src/reducer/schema-helpers.ts
@@ -1,13 +1,31 @@
1
- import { i as ReferenceGameSourceManifestPayload } from '../schema-CJc0UfjJ.js';
2
- export { R as REFERENCE_GAME_MANIFEST_SCHEMA_VERSION, a as REFERENCE_GAME_SOURCE_MANIFEST_SCHEMA_VERSION, b as ReferenceGameDemoRelease, c as ReferenceGameManifestV4, d as ReferenceGameRights, e as ReferenceGameSdkPolicy, f as ReferenceGameSourceEntry, g as ReferenceGameSourceInventoryPolicy, h as ReferenceGameSourceManifest, j as ReferenceGameSourceObject, k as ReferenceGameSourceProvenance, l as ReferenceGameTeaching, m as ReferenceGameWorkspace, n as isPackageableReferenceGame, p as parseReferenceGameManifestV4, o as parseReferenceGameSourceManifest, r as referenceGameDemoReleaseSchema, q as referenceGameManifestV4Schema, s as referenceGameRightsSchema, t as referenceGameSdkPolicySchema, u as referenceGameSha256DigestSchema, v as referenceGameSourceEntrySchema, w as referenceGameSourceInventoryPolicySchema, x as referenceGameSourceManifestPayloadSchema, y as referenceGameSourceManifestSchema, z as referenceGameSourceObjectSchema, A as referenceGameSourceProvenanceSchema, B as referenceGameTeachingSchema, C as referenceGameWorkspaceSchema } from '../schema-CJc0UfjJ.js';
3
- import 'zod';
1
+ import { z } from 'zod';
4
2
 
5
- type CanonicalReferenceGameJson = null | boolean | number | string | CanonicalReferenceGameJson[] | {
6
- [key: string]: CanonicalReferenceGameJson;
7
- };
8
- declare function computeReferenceGameSourceFingerprint(payload: ReferenceGameSourceManifestPayload): `sha256:${string}`;
9
- declare function canonicalizeReferenceGameSourcePayload(payload: ReferenceGameSourceManifestPayload): CanonicalReferenceGameJson;
10
- /** Locale-independent UTF-16 code-unit order, equivalent to Java String.compareTo. */
11
- declare function compareReferenceGameCanonicalStrings(left: string, right: string): number;
3
+ declare const REFERENCE_GAME_MANIFEST_SCHEMA_VERSION = 5;
4
+ declare const referenceGameManifestSchema: z.ZodObject<{
5
+ schemaVersion: z.ZodLiteral<5>;
6
+ id: z.ZodString;
7
+ displayName: z.ZodString;
8
+ workspace: z.ZodObject<{
9
+ manifest: z.ZodString;
10
+ reducer: z.ZodString;
11
+ ui: z.ZodString;
12
+ }, z.core.$strict>;
13
+ teaching: z.ZodObject<{
14
+ whatThisTeaches: z.ZodArray<z.ZodString>;
15
+ whenToCopyThisPattern: z.ZodArray<z.ZodString>;
16
+ readFirst: z.ZodArray<z.ZodString>;
17
+ }, z.core.$strict>;
18
+ mechanics: z.ZodArray<z.ZodString>;
19
+ uiPatterns: z.ZodArray<z.ZodString>;
20
+ rights: z.ZodObject<{
21
+ mechanicsProvenance: z.ZodString;
22
+ sourceCode: z.ZodString;
23
+ codeLicense: z.ZodString;
24
+ ruleText: z.ZodString;
25
+ thirdPartyMarks: z.ZodArray<z.ZodString>;
26
+ }, z.core.$strict>;
27
+ }, z.core.$strict>;
28
+ type ReferenceGameManifest = z.infer<typeof referenceGameManifestSchema>;
29
+ declare function parseReferenceGameManifest(value: unknown): ReferenceGameManifest;
12
30
 
13
- export { ReferenceGameSourceManifestPayload, canonicalizeReferenceGameSourcePayload, compareReferenceGameCanonicalStrings, computeReferenceGameSourceFingerprint };
31
+ export { REFERENCE_GAME_MANIFEST_SCHEMA_VERSION, type ReferenceGameManifest, parseReferenceGameManifest, referenceGameManifestSchema };
@@ -1,50 +1,48 @@
1
- import {
2
- REFERENCE_GAME_MANIFEST_SCHEMA_VERSION,
3
- REFERENCE_GAME_SOURCE_MANIFEST_SCHEMA_VERSION,
4
- isPackageableReferenceGame,
5
- parseReferenceGameManifestV4,
6
- parseReferenceGameSourceManifest,
7
- referenceGameDemoReleaseSchema,
8
- referenceGameManifestV4Schema,
9
- referenceGameRightsSchema,
10
- referenceGameSdkPolicySchema,
11
- referenceGameSha256DigestSchema,
12
- referenceGameSourceEntrySchema,
13
- referenceGameSourceInventoryPolicySchema,
14
- referenceGameSourceManifestPayloadSchema,
15
- referenceGameSourceManifestSchema,
16
- referenceGameSourceObjectSchema,
17
- referenceGameSourceProvenanceSchema,
18
- referenceGameTeachingSchema,
19
- referenceGameWorkspaceSchema
20
- } from "../chunk-YN5W67YL.js";
21
- import {
22
- canonicalizeReferenceGameSourcePayload,
23
- compareReferenceGameCanonicalStrings,
24
- computeReferenceGameSourceFingerprint
25
- } from "../chunk-UNVCT5Z7.js";
26
1
  import "../chunk-PZ5AY32C.js";
2
+
3
+ // src/reference-games/schema.ts
4
+ import { z } from "zod";
5
+ var REFERENCE_GAME_MANIFEST_SCHEMA_VERSION = 5;
6
+ var referenceGameIdSchema = z.string().regex(/^[a-z0-9][a-z0-9-]*$/);
7
+ var referenceGamePathSchema = z.string().min(1).refine(
8
+ (value) => !value.startsWith("/") && !value.includes("\\") && value.split("/").every(
9
+ (segment) => segment.length > 0 && segment !== "." && segment !== ".." && /^[A-Za-z0-9._-]+$/.test(segment)
10
+ ),
11
+ { message: "path must stay inside the reference game workspace" }
12
+ );
13
+ var referenceGameWorkspaceSchema = z.object({
14
+ manifest: referenceGamePathSchema,
15
+ reducer: referenceGamePathSchema,
16
+ ui: referenceGamePathSchema
17
+ }).strict();
18
+ var referenceGameTeachingSchema = z.object({
19
+ whatThisTeaches: z.array(z.string().min(1)).min(1),
20
+ whenToCopyThisPattern: z.array(z.string().min(1)).min(1),
21
+ readFirst: z.array(referenceGamePathSchema).min(1)
22
+ }).strict();
23
+ var referenceGameRightsSchema = z.object({
24
+ mechanicsProvenance: z.string().min(1),
25
+ sourceCode: z.string().min(1),
26
+ codeLicense: z.string().min(1),
27
+ ruleText: z.string().min(1),
28
+ thirdPartyMarks: z.array(z.string())
29
+ }).strict();
30
+ var referenceGameManifestSchema = z.object({
31
+ schemaVersion: z.literal(REFERENCE_GAME_MANIFEST_SCHEMA_VERSION),
32
+ id: referenceGameIdSchema,
33
+ displayName: z.string().min(1),
34
+ workspace: referenceGameWorkspaceSchema,
35
+ teaching: referenceGameTeachingSchema,
36
+ mechanics: z.array(z.string().min(1)).min(1),
37
+ uiPatterns: z.array(z.string().min(1)).min(1),
38
+ rights: referenceGameRightsSchema
39
+ }).strict();
40
+ function parseReferenceGameManifest(value) {
41
+ return referenceGameManifestSchema.parse(value);
42
+ }
27
43
  export {
28
44
  REFERENCE_GAME_MANIFEST_SCHEMA_VERSION,
29
- REFERENCE_GAME_SOURCE_MANIFEST_SCHEMA_VERSION,
30
- canonicalizeReferenceGameSourcePayload,
31
- compareReferenceGameCanonicalStrings,
32
- computeReferenceGameSourceFingerprint,
33
- isPackageableReferenceGame,
34
- parseReferenceGameManifestV4,
35
- parseReferenceGameSourceManifest,
36
- referenceGameDemoReleaseSchema,
37
- referenceGameManifestV4Schema,
38
- referenceGameRightsSchema,
39
- referenceGameSdkPolicySchema,
40
- referenceGameSha256DigestSchema,
41
- referenceGameSourceEntrySchema,
42
- referenceGameSourceInventoryPolicySchema,
43
- referenceGameSourceManifestPayloadSchema,
44
- referenceGameSourceManifestSchema,
45
- referenceGameSourceObjectSchema,
46
- referenceGameSourceProvenanceSchema,
47
- referenceGameTeachingSchema,
48
- referenceGameWorkspaceSchema
45
+ parseReferenceGameManifest,
46
+ referenceGameManifestSchema
49
47
  };
50
48
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
1
+ {"version":3,"sources":["../../src/reference-games/schema.ts"],"sourcesContent":["import { z } from \"zod\";\n\nexport const REFERENCE_GAME_MANIFEST_SCHEMA_VERSION = 5;\n\nconst referenceGameIdSchema = z.string().regex(/^[a-z0-9][a-z0-9-]*$/);\n\nconst referenceGamePathSchema = z\n .string()\n .min(1)\n .refine(\n (value) =>\n !value.startsWith(\"/\") &&\n !value.includes(\"\\\\\") &&\n value\n .split(\"/\")\n .every(\n (segment) =>\n segment.length > 0 &&\n segment !== \".\" &&\n segment !== \"..\" &&\n /^[A-Za-z0-9._-]+$/.test(segment),\n ),\n { message: \"path must stay inside the reference game workspace\" },\n );\n\nconst referenceGameWorkspaceSchema = z\n .object({\n manifest: referenceGamePathSchema,\n reducer: referenceGamePathSchema,\n ui: referenceGamePathSchema,\n })\n .strict();\n\nconst referenceGameTeachingSchema = z\n .object({\n whatThisTeaches: z.array(z.string().min(1)).min(1),\n whenToCopyThisPattern: z.array(z.string().min(1)).min(1),\n readFirst: z.array(referenceGamePathSchema).min(1),\n })\n .strict();\n\nconst referenceGameRightsSchema = z\n .object({\n mechanicsProvenance: z.string().min(1),\n sourceCode: z.string().min(1),\n codeLicense: z.string().min(1),\n ruleText: z.string().min(1),\n thirdPartyMarks: z.array(z.string()),\n })\n .strict();\n\nexport const referenceGameManifestSchema = z\n .object({\n schemaVersion: z.literal(REFERENCE_GAME_MANIFEST_SCHEMA_VERSION),\n id: referenceGameIdSchema,\n displayName: z.string().min(1),\n workspace: referenceGameWorkspaceSchema,\n teaching: referenceGameTeachingSchema,\n mechanics: z.array(z.string().min(1)).min(1),\n uiPatterns: z.array(z.string().min(1)).min(1),\n rights: referenceGameRightsSchema,\n })\n .strict();\n\nexport type ReferenceGameManifest = z.infer<typeof referenceGameManifestSchema>;\n\nexport function parseReferenceGameManifest(\n value: unknown,\n): ReferenceGameManifest {\n return referenceGameManifestSchema.parse(value);\n}\n"],"mappings":";;;AAAA,SAAS,SAAS;AAEX,IAAM,yCAAyC;AAEtD,IAAM,wBAAwB,EAAE,OAAO,EAAE,MAAM,sBAAsB;AAErE,IAAM,0BAA0B,EAC7B,OAAO,EACP,IAAI,CAAC,EACL;AAAA,EACC,CAAC,UACC,CAAC,MAAM,WAAW,GAAG,KACrB,CAAC,MAAM,SAAS,IAAI,KACpB,MACG,MAAM,GAAG,EACT;AAAA,IACC,CAAC,YACC,QAAQ,SAAS,KACjB,YAAY,OACZ,YAAY,QACZ,oBAAoB,KAAK,OAAO;AAAA,EACpC;AAAA,EACJ,EAAE,SAAS,qDAAqD;AAClE;AAEF,IAAM,+BAA+B,EAClC,OAAO;AAAA,EACN,UAAU;AAAA,EACV,SAAS;AAAA,EACT,IAAI;AACN,CAAC,EACA,OAAO;AAEV,IAAM,8BAA8B,EACjC,OAAO;AAAA,EACN,iBAAiB,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC;AAAA,EACjD,uBAAuB,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC;AAAA,EACvD,WAAW,EAAE,MAAM,uBAAuB,EAAE,IAAI,CAAC;AACnD,CAAC,EACA,OAAO;AAEV,IAAM,4BAA4B,EAC/B,OAAO;AAAA,EACN,qBAAqB,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EACrC,YAAY,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EAC5B,aAAa,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EAC7B,UAAU,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EAC1B,iBAAiB,EAAE,MAAM,EAAE,OAAO,CAAC;AACrC,CAAC,EACA,OAAO;AAEH,IAAM,8BAA8B,EACxC,OAAO;AAAA,EACN,eAAe,EAAE,QAAQ,sCAAsC;AAAA,EAC/D,IAAI;AAAA,EACJ,aAAa,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EAC7B,WAAW;AAAA,EACX,UAAU;AAAA,EACV,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC;AAAA,EAC3C,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC;AAAA,EAC5C,QAAQ;AACV,CAAC,EACA,OAAO;AAIH,SAAS,2BACd,OACuB;AACvB,SAAO,4BAA4B,MAAM,KAAK;AAChD;","names":[]}
@@ -84,15 +84,15 @@ import {
84
84
  useZoneCards,
85
85
  useZonePileContext,
86
86
  useZonePrimitiveContext
87
- } from "../chunk-WAQUD4IG.js";
88
- import "../chunk-MPVC2SU6.js";
87
+ } from "../chunk-NLZDRIVW.js";
89
88
  import "../chunk-T3ZKNUZ7.js";
90
- import "../chunk-YOLIZMXR.js";
89
+ import "../chunk-B33RRZ4O.js";
90
+ import "../chunk-LMHCGCA6.js";
91
+ import "../chunk-VRRR6QZT.js";
91
92
  import {
92
93
  composeEventHandlers,
93
94
  renderPrimitive
94
95
  } from "../chunk-VDXOF4FW.js";
95
- import "../chunk-B33RRZ4O.js";
96
96
  import "../chunk-WHR5UW3F.js";
97
97
  import "../chunk-PF7L4BMG.js";
98
98
  import "../chunk-FBQNCOPQ.js";
@@ -1,20 +1,20 @@
1
1
  import {
2
2
  createGameUiContract,
3
3
  createWorkspaceUIContract
4
- } from "../chunk-7JBPOJOF.js";
4
+ } from "../chunk-ZGQGFXFG.js";
5
5
  import "../chunk-VWTKGIYF.js";
6
- import "../chunk-WAQUD4IG.js";
7
- import "../chunk-MPVC2SU6.js";
6
+ import "../chunk-NLZDRIVW.js";
8
7
  import "../chunk-T3ZKNUZ7.js";
9
- import "../chunk-YOLIZMXR.js";
10
- import "../chunk-VDXOF4FW.js";
11
8
  import "../chunk-B33RRZ4O.js";
12
- import "../chunk-5XTAQ4EQ.js";
13
- import "../chunk-YNW3KBDE.js";
9
+ import "../chunk-TO6WRLRN.js";
10
+ import "../chunk-7QKE5BFU.js";
11
+ import "../chunk-LMHCGCA6.js";
12
+ import "../chunk-VRRR6QZT.js";
13
+ import "../chunk-VDXOF4FW.js";
14
14
  import "../chunk-WHR5UW3F.js";
15
15
  import "../chunk-PF7L4BMG.js";
16
16
  import "../chunk-FBQNCOPQ.js";
17
- import "../chunk-3PFDHTR7.js";
17
+ import "../chunk-3VSOH3TZ.js";
18
18
  import "../chunk-PZ5AY32C.js";
19
19
  export {
20
20
  createGameUiContract,
package/dist/runtime.js CHANGED
@@ -1,33 +1,33 @@
1
1
  import {
2
2
  createWorkspaceUIContract
3
- } from "./chunk-7JBPOJOF.js";
3
+ } from "./chunk-ZGQGFXFG.js";
4
4
  import "./chunk-VWTKGIYF.js";
5
- import "./chunk-WAQUD4IG.js";
6
- import "./chunk-MPVC2SU6.js";
5
+ import "./chunk-NLZDRIVW.js";
7
6
  import "./chunk-T3ZKNUZ7.js";
8
- import {
9
- GameSkeleton
10
- } from "./chunk-YOLIZMXR.js";
11
- import "./chunk-VDXOF4FW.js";
12
7
  import {
13
8
  PluginRuntimeBoundary,
14
9
  createPluginRuntimeClient
15
10
  } from "./chunk-NQTXQWUP.js";
16
11
  import "./chunk-B33RRZ4O.js";
17
- import "./chunk-5XTAQ4EQ.js";
18
- import "./chunk-YNW3KBDE.js";
12
+ import "./chunk-TO6WRLRN.js";
13
+ import "./chunk-7QKE5BFU.js";
14
+ import "./chunk-LMHCGCA6.js";
15
+ import {
16
+ GameSkeleton
17
+ } from "./chunk-VRRR6QZT.js";
18
+ import "./chunk-VDXOF4FW.js";
19
19
  import "./chunk-WHR5UW3F.js";
20
20
  import "./chunk-PF7L4BMG.js";
21
21
  import {
22
22
  DREAMBOARD_SDK_VERSION
23
- } from "./chunk-MLFHVYF7.js";
24
- import "./chunk-THWT4V3Z.js";
23
+ } from "./chunk-KH6AET7P.js";
24
+ import "./chunk-CSIEFYTC.js";
25
25
  import {
26
26
  DREAMBOARD_PLUGIN_PROTOCOL,
27
27
  DREAMBOARD_PLUGIN_PROTOCOL_VERSION,
28
28
  HostToPluginEnvelopeSchema
29
29
  } from "./chunk-FBQNCOPQ.js";
30
- import "./chunk-3PFDHTR7.js";
30
+ import "./chunk-3VSOH3TZ.js";
31
31
  import "./chunk-PZ5AY32C.js";
32
32
 
33
33
  // src/runtime/hooks/usePluginRuntime.ts
@@ -30,7 +30,7 @@ type CompileScenarioReplayOptions = {
30
30
  * by dev-host, Workbench, demo, and performance adapters.
31
31
  *
32
32
  * The DTO may contain sealed/private command parameters. It must never cross a
33
- * player, spectator, browser, ordinary-log, or public-receipt boundary.
33
+ * player, spectator, browser, or ordinary-log boundary.
34
34
  */
35
35
  declare function compileScenarioReplay(options: CompileScenarioReplayOptions): Promise<CompiledScenarioReplay>;
36
36
 
@@ -1,6 +1,3 @@
1
- import {
2
- compareReferenceGameCanonicalStrings
3
- } from "./chunk-UNVCT5Z7.js";
4
1
  import "./chunk-PZ5AY32C.js";
5
2
 
6
3
  // src/testing/compile-scenario-replay.ts
@@ -232,7 +229,7 @@ async function digestSourceClosure(options) {
232
229
  })
233
230
  );
234
231
  inputs.sort(
235
- (left, right) => compareReferenceGameCanonicalStrings(left.path, right.path)
232
+ (left, right) => left.path < right.path ? -1 : left.path > right.path ? 1 : 0
236
233
  );
237
234
  return `sha256:${createHash("sha256").update(
238
235
  JSON.stringify({
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/testing/compile-scenario-replay.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport { createRequire } from \"node:module\";\nimport {\n lstat,\n mkdtemp,\n readFile,\n realpath,\n rm,\n stat,\n writeFile,\n} from \"node:fs/promises\";\nimport { tmpdir } from \"node:os\";\nimport path from \"node:path\";\nimport { compareReferenceGameCanonicalStrings } from \"../reference-games/canonical.js\";\nimport { pathToFileURL } from \"node:url\";\nimport { build } from \"esbuild\";\nimport type {\n ScenarioCheckpoint,\n ScenarioCheckpointSelector,\n ScenarioReplayDefinition,\n} from \"./definitions.js\";\nimport type { ScenarioDefinitionGameLike } from \"./scenario-definition-validation.js\";\n\nexport type CompiledScenarioReplay<\n Game extends ScenarioDefinitionGameLike = ScenarioDefinitionGameLike,\n> = {\n readonly schemaVersion: 1;\n readonly scenario: {\n readonly path: string;\n /** Covers the local game/scenario module graph, including assertions. */\n readonly sourceDigest: `sha256:${string}`;\n };\n /** Canonical serializable scenario projection; never contains `then`. */\n readonly definition: ScenarioReplayDefinition<Game>;\n readonly checkpoint: ScenarioCheckpoint;\n readonly expected: {\n readonly checkpointDigest: `sha256:${string}`;\n readonly publicProjectionDigest: `sha256:${string}`;\n };\n};\n\nexport type CompileScenarioReplayOptions = {\n readonly scenarioPath: string;\n readonly at?: ScenarioCheckpointSelector;\n};\n\ntype SyntheticCompileResult = Omit<\n CompiledScenarioReplay,\n \"schemaVersion\" | \"scenario\"\n>;\n\ntype SyntheticCompileModule = {\n readonly compile: (options: {\n readonly at?: ScenarioCheckpointSelector;\n readonly scenarioPath: string;\n readonly sourceDigest: `sha256:${string}`;\n }) => Promise<SyntheticCompileResult>;\n};\n\ntype ScenarioSource = {\n readonly projectRoot: string;\n readonly scenarioPath: string;\n readonly relativeScenarioPath: string;\n readonly gamePath: string;\n};\n\nconst scenarioSourceDigestVersion = \"dreamboard-scenario-source-closure@1\";\nconst syntheticSourceFile = \"__dreamboard_compile_scenario_replay__.ts\";\n\n/**\n * Compile one authored scenario into the trusted, serializable replay DTO used\n * by dev-host, Workbench, demo, and performance adapters.\n *\n * The DTO may contain sealed/private command parameters. It must never cross a\n * player, spectator, browser, ordinary-log, or public-receipt boundary.\n */\nexport async function compileScenarioReplay(\n options: CompileScenarioReplayOptions,\n): Promise<CompiledScenarioReplay> {\n const source = await resolveScenarioSource(options.scenarioPath);\n const syntheticSource = buildSyntheticSource(source);\n const [\n reducerEntry,\n reducerAdvancedEntry,\n testingEntry,\n testingRuntimeEntry,\n typesEntry,\n ] = await Promise.all([\n resolveCurrentSdkFacade(\"reducer\"),\n resolveCurrentSdkFacade(\"reducer/advanced\"),\n resolveCurrentSdkFacade(\"testing\"),\n resolveCurrentSdkFacade(\"testing-runtime\"),\n resolveCurrentSdkFacade(\"types\"),\n ]);\n const bundled = await build({\n absWorkingDir: source.projectRoot,\n stdin: {\n contents: syntheticSource,\n loader: \"ts\",\n resolveDir: source.projectRoot,\n sourcefile: syntheticSourceFile,\n },\n bundle: true,\n alias: {\n \"@dreamboard-games/sdk/reducer\": reducerEntry,\n \"@dreamboard-games/sdk/reducer/advanced\": reducerAdvancedEntry,\n \"@dreamboard-games/sdk/testing\": testingEntry,\n \"@dreamboard-games/sdk/testing-runtime\": testingRuntimeEntry,\n \"@dreamboard-games/sdk/types\": typesEntry,\n zod: createRequire(import.meta.url).resolve(\"zod\"),\n },\n format: \"esm\",\n platform: \"node\",\n target: \"node24\",\n sourcemap: \"inline\",\n metafile: true,\n write: false,\n logLevel: \"silent\",\n });\n const output = bundled.outputFiles?.[0];\n if (!output || !bundled.metafile) {\n throw new Error(\"Scenario replay compilation did not produce a bundle.\");\n }\n const sourceDigest = await digestSourceClosure({\n projectRoot: source.projectRoot,\n inputPaths: Object.keys(bundled.metafile.inputs),\n });\n\n const tempRoot = await mkdtemp(\n path.join(tmpdir(), \"dreamboard-compiled-scenario-\"),\n );\n const outputPath = path.join(tempRoot, \"compiled-scenario.mjs\");\n try {\n await writeFile(outputPath, output.text);\n const loaded = (await import(\n `${pathToFileURL(outputPath).href}?source=${sourceDigest.slice(7, 19)}`\n )) as SyntheticCompileModule;\n if (typeof loaded.compile !== \"function\") {\n throw new Error(\"Scenario replay bundle is missing compile().\");\n }\n const materialized = await loaded.compile({\n ...(options.at === undefined ? {} : { at: options.at }),\n scenarioPath: source.relativeScenarioPath,\n sourceDigest,\n });\n const compiled = {\n schemaVersion: 1,\n scenario: {\n path: source.relativeScenarioPath,\n sourceDigest,\n },\n definition: materialized.definition,\n checkpoint: materialized.checkpoint,\n expected: materialized.expected,\n } satisfies CompiledScenarioReplay;\n return assertSerializableCompiledReplay(compiled);\n } finally {\n await rm(tempRoot, { recursive: true, force: true });\n }\n}\n\nasync function resolveCurrentSdkFacade(name: string): Promise<string> {\n const candidates = [\n path.resolve(import.meta.dirname, `../${name}.ts`),\n path.resolve(import.meta.dirname, `${name}.js`),\n ];\n for (const candidate of candidates) {\n if (await isFile(candidate)) return candidate;\n }\n throw new Error(\n `Could not resolve the current @dreamboard-games/sdk/${name} facade from ${import.meta.dirname}.`,\n );\n}\n\nasync function resolveScenarioSource(\n requestedPath: string,\n): Promise<ScenarioSource> {\n if (typeof requestedPath !== \"string\" || requestedPath.length === 0) {\n throw new Error(\"scenarioPath must be a non-empty string.\");\n }\n const requestedAbsolute = path.resolve(process.cwd(), requestedPath);\n const requestedStats = await lstat(requestedAbsolute).catch((error) => {\n if (isMissingPathError(error)) return null;\n throw error;\n });\n if (!requestedStats?.isFile()) {\n throw new Error(`Scenario path does not name a file: ${requestedPath}.`);\n }\n const scenarioPath = await realpath(requestedAbsolute);\n const projectRoot = await findProjectRoot(path.dirname(scenarioPath));\n const canonicalProjectRoot = await realpath(projectRoot);\n const scenarioRoot = path.join(canonicalProjectRoot, \"test\", \"scenarios\");\n const canonicalScenarioRoot = await realpath(scenarioRoot).catch((error) => {\n if (isMissingPathError(error)) return null;\n throw error;\n });\n if (\n canonicalScenarioRoot === null ||\n !isWithinDirectory(canonicalScenarioRoot, scenarioPath) ||\n !scenarioPath.endsWith(\".scenario.ts\")\n ) {\n throw new Error(\n \"scenarioPath must resolve to test/scenarios/**/*.scenario.ts inside one game package.\",\n );\n }\n const gamePath = path.join(canonicalProjectRoot, \"app\", \"game.ts\");\n if (!(await isFile(gamePath))) {\n throw new Error(`Game package is missing ${gamePath}.`);\n }\n return {\n projectRoot: canonicalProjectRoot,\n scenarioPath,\n relativeScenarioPath: toPosix(\n path.relative(canonicalProjectRoot, scenarioPath),\n ),\n gamePath,\n };\n}\n\nasync function findProjectRoot(start: string): Promise<string> {\n let current = path.resolve(start);\n for (;;) {\n if (\n (await isFile(path.join(current, \"package.json\"))) &&\n (await isFile(path.join(current, \"app\", \"game.ts\")))\n ) {\n return current;\n }\n const parent = path.dirname(current);\n if (parent === current) {\n throw new Error(\n \"Could not find a game package containing package.json and app/game.ts.\",\n );\n }\n current = parent;\n }\n}\n\nfunction buildSyntheticSource(source: ScenarioSource): string {\n const gameSpecifier = localImportSpecifier(\n source.projectRoot,\n source.gamePath,\n );\n const scenarioSpecifier = localImportSpecifier(\n source.projectRoot,\n source.scenarioPath,\n );\n return [\n `import * as gameModule from ${JSON.stringify(gameSpecifier)};`,\n `import * as scenarioModule from ${JSON.stringify(scenarioSpecifier)};`,\n 'import { inspectScenario, toScenarioReplayDefinition } from \"@dreamboard-games/sdk/testing\";',\n 'import { digestScenarioProjection, scenarioProjectionParityFromInspectNode } from \"@dreamboard-games/sdk/testing-runtime\";',\n \"const game = gameModule.game ?? gameModule.default;\",\n \"const scenario = scenarioModule.scenario ?? scenarioModule.default;\",\n \"export async function compile(options) {\",\n \" if (!game || !scenario) {\",\n ' throw new Error(\"Compiled scenario entry is missing game or scenario authority.\");',\n \" }\",\n \" const definition = toScenarioReplayDefinition(scenario);\",\n \" const checkpoint = typeof options.at === 'string' ? scenario.checkpoints?.[options.at] : options.at;\",\n \" if (typeof options.at === 'string' && checkpoint === undefined) {\",\n \" const available = Object.keys(scenario.checkpoints ?? {}).sort();\",\n \" throw new Error(`Unknown checkpoint '${options.at}'; available checkpoints: ${available.join(', ') || 'none'}.`);\",\n \" }\",\n \" const inspected = await inspectScenario({\",\n \" game,\",\n \" scenario: definition,\",\n \" identity: {\",\n \" id: definition.id,\",\n \" path: options.scenarioPath,\",\n \" sourceDigest: options.sourceDigest,\",\n \" },\",\n ' perspective: { kind: \"spectator\" },',\n \" ...(checkpoint === undefined ? {} : { at: checkpoint }),\",\n \" });\",\n \" return {\",\n \" definition,\",\n \" checkpoint: inspected.node.checkpoint,\",\n \" expected: {\",\n \" checkpointDigest: inspected.node.checkpointDigest,\",\n \" publicProjectionDigest: digestScenarioProjection(\",\n \" scenarioProjectionParityFromInspectNode(inspected.node),\",\n \" ),\",\n \" },\",\n \" };\",\n \"}\",\n ].join(\"\\n\");\n}\n\nasync function digestSourceClosure(options: {\n readonly projectRoot: string;\n readonly inputPaths: readonly string[];\n}): Promise<`sha256:${string}`> {\n const syntheticPath = path.resolve(options.projectRoot, syntheticSourceFile);\n const localPaths = options.inputPaths\n .map((inputPath) =>\n path.isAbsolute(inputPath)\n ? inputPath\n : path.resolve(options.projectRoot, inputPath),\n )\n .filter(\n (inputPath) =>\n inputPath !== syntheticPath &&\n isWithinDirectory(options.projectRoot, inputPath) &&\n !toPosix(path.relative(options.projectRoot, inputPath))\n .split(\"/\")\n .includes(\"node_modules\"),\n );\n const inputs = await Promise.all(\n [...new Set(localPaths)].map(async (inputPath) => {\n const content = await readFile(inputPath);\n return {\n path: toPosix(path.relative(options.projectRoot, inputPath)),\n sha256: createHash(\"sha256\").update(content).digest(\"hex\"),\n };\n }),\n );\n inputs.sort((left, right) =>\n compareReferenceGameCanonicalStrings(left.path, right.path),\n );\n return `sha256:${createHash(\"sha256\")\n .update(\n JSON.stringify({\n digestVersion: scenarioSourceDigestVersion,\n inputs,\n }),\n )\n .digest(\"hex\")}`;\n}\n\nfunction assertSerializableCompiledReplay(\n value: CompiledScenarioReplay,\n): CompiledScenarioReplay {\n const serialized = JSON.stringify(value);\n const parsed = JSON.parse(serialized) as CompiledScenarioReplay;\n if (\n parsed.schemaVersion !== 1 ||\n !/^sha256:[a-f0-9]{64}$/.test(parsed.scenario.sourceDigest) ||\n !/^sha256:[a-f0-9]{64}$/.test(parsed.expected.checkpointDigest) ||\n !/^sha256:[a-f0-9]{64}$/.test(parsed.expected.publicProjectionDigest)\n ) {\n throw new Error(\"Compiled scenario replay failed digest validation.\");\n }\n return parsed;\n}\n\nfunction localImportSpecifier(projectRoot: string, filePath: string): string {\n const relative = toPosix(path.relative(projectRoot, filePath));\n return relative.startsWith(\".\") ? relative : `./${relative}`;\n}\n\nfunction isWithinDirectory(directory: string, filePath: string): boolean {\n const relative = path.relative(directory, filePath);\n return (\n relative !== \"\" &&\n relative !== \"..\" &&\n !relative.startsWith(`..${path.sep}`) &&\n !path.isAbsolute(relative)\n );\n}\n\nasync function isFile(filePath: string): Promise<boolean> {\n return stat(filePath)\n .then((value) => value.isFile())\n .catch((error) => {\n if (isMissingPathError(error)) return false;\n throw error;\n });\n}\n\nfunction isMissingPathError(error: unknown): boolean {\n return (\n typeof error === \"object\" &&\n error !== null &&\n \"code\" in error &&\n (error as { readonly code?: unknown }).code === \"ENOENT\"\n );\n}\n\nfunction toPosix(value: string): string {\n return value.split(path.sep).join(\"/\");\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/testing/compile-scenario-replay.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport { createRequire } from \"node:module\";\nimport {\n lstat,\n mkdtemp,\n readFile,\n realpath,\n rm,\n stat,\n writeFile,\n} from \"node:fs/promises\";\nimport { tmpdir } from \"node:os\";\nimport path from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\nimport { build } from \"esbuild\";\nimport type {\n ScenarioCheckpoint,\n ScenarioCheckpointSelector,\n ScenarioReplayDefinition,\n} from \"./definitions.js\";\nimport type { ScenarioDefinitionGameLike } from \"./scenario-definition-validation.js\";\n\nexport type CompiledScenarioReplay<\n Game extends ScenarioDefinitionGameLike = ScenarioDefinitionGameLike,\n> = {\n readonly schemaVersion: 1;\n readonly scenario: {\n readonly path: string;\n /** Covers the local game/scenario module graph, including assertions. */\n readonly sourceDigest: `sha256:${string}`;\n };\n /** Canonical serializable scenario projection; never contains `then`. */\n readonly definition: ScenarioReplayDefinition<Game>;\n readonly checkpoint: ScenarioCheckpoint;\n readonly expected: {\n readonly checkpointDigest: `sha256:${string}`;\n readonly publicProjectionDigest: `sha256:${string}`;\n };\n};\n\nexport type CompileScenarioReplayOptions = {\n readonly scenarioPath: string;\n readonly at?: ScenarioCheckpointSelector;\n};\n\ntype SyntheticCompileResult = Omit<\n CompiledScenarioReplay,\n \"schemaVersion\" | \"scenario\"\n>;\n\ntype SyntheticCompileModule = {\n readonly compile: (options: {\n readonly at?: ScenarioCheckpointSelector;\n readonly scenarioPath: string;\n readonly sourceDigest: `sha256:${string}`;\n }) => Promise<SyntheticCompileResult>;\n};\n\ntype ScenarioSource = {\n readonly projectRoot: string;\n readonly scenarioPath: string;\n readonly relativeScenarioPath: string;\n readonly gamePath: string;\n};\n\nconst scenarioSourceDigestVersion = \"dreamboard-scenario-source-closure@1\";\nconst syntheticSourceFile = \"__dreamboard_compile_scenario_replay__.ts\";\n\n/**\n * Compile one authored scenario into the trusted, serializable replay DTO used\n * by dev-host, Workbench, demo, and performance adapters.\n *\n * The DTO may contain sealed/private command parameters. It must never cross a\n * player, spectator, browser, or ordinary-log boundary.\n */\nexport async function compileScenarioReplay(\n options: CompileScenarioReplayOptions,\n): Promise<CompiledScenarioReplay> {\n const source = await resolveScenarioSource(options.scenarioPath);\n const syntheticSource = buildSyntheticSource(source);\n const [\n reducerEntry,\n reducerAdvancedEntry,\n testingEntry,\n testingRuntimeEntry,\n typesEntry,\n ] = await Promise.all([\n resolveCurrentSdkFacade(\"reducer\"),\n resolveCurrentSdkFacade(\"reducer/advanced\"),\n resolveCurrentSdkFacade(\"testing\"),\n resolveCurrentSdkFacade(\"testing-runtime\"),\n resolveCurrentSdkFacade(\"types\"),\n ]);\n const bundled = await build({\n absWorkingDir: source.projectRoot,\n stdin: {\n contents: syntheticSource,\n loader: \"ts\",\n resolveDir: source.projectRoot,\n sourcefile: syntheticSourceFile,\n },\n bundle: true,\n alias: {\n \"@dreamboard-games/sdk/reducer\": reducerEntry,\n \"@dreamboard-games/sdk/reducer/advanced\": reducerAdvancedEntry,\n \"@dreamboard-games/sdk/testing\": testingEntry,\n \"@dreamboard-games/sdk/testing-runtime\": testingRuntimeEntry,\n \"@dreamboard-games/sdk/types\": typesEntry,\n zod: createRequire(import.meta.url).resolve(\"zod\"),\n },\n format: \"esm\",\n platform: \"node\",\n target: \"node24\",\n sourcemap: \"inline\",\n metafile: true,\n write: false,\n logLevel: \"silent\",\n });\n const output = bundled.outputFiles?.[0];\n if (!output || !bundled.metafile) {\n throw new Error(\"Scenario replay compilation did not produce a bundle.\");\n }\n const sourceDigest = await digestSourceClosure({\n projectRoot: source.projectRoot,\n inputPaths: Object.keys(bundled.metafile.inputs),\n });\n\n const tempRoot = await mkdtemp(\n path.join(tmpdir(), \"dreamboard-compiled-scenario-\"),\n );\n const outputPath = path.join(tempRoot, \"compiled-scenario.mjs\");\n try {\n await writeFile(outputPath, output.text);\n const loaded = (await import(\n `${pathToFileURL(outputPath).href}?source=${sourceDigest.slice(7, 19)}`\n )) as SyntheticCompileModule;\n if (typeof loaded.compile !== \"function\") {\n throw new Error(\"Scenario replay bundle is missing compile().\");\n }\n const materialized = await loaded.compile({\n ...(options.at === undefined ? {} : { at: options.at }),\n scenarioPath: source.relativeScenarioPath,\n sourceDigest,\n });\n const compiled = {\n schemaVersion: 1,\n scenario: {\n path: source.relativeScenarioPath,\n sourceDigest,\n },\n definition: materialized.definition,\n checkpoint: materialized.checkpoint,\n expected: materialized.expected,\n } satisfies CompiledScenarioReplay;\n return assertSerializableCompiledReplay(compiled);\n } finally {\n await rm(tempRoot, { recursive: true, force: true });\n }\n}\n\nasync function resolveCurrentSdkFacade(name: string): Promise<string> {\n const candidates = [\n path.resolve(import.meta.dirname, `../${name}.ts`),\n path.resolve(import.meta.dirname, `${name}.js`),\n ];\n for (const candidate of candidates) {\n if (await isFile(candidate)) return candidate;\n }\n throw new Error(\n `Could not resolve the current @dreamboard-games/sdk/${name} facade from ${import.meta.dirname}.`,\n );\n}\n\nasync function resolveScenarioSource(\n requestedPath: string,\n): Promise<ScenarioSource> {\n if (typeof requestedPath !== \"string\" || requestedPath.length === 0) {\n throw new Error(\"scenarioPath must be a non-empty string.\");\n }\n const requestedAbsolute = path.resolve(process.cwd(), requestedPath);\n const requestedStats = await lstat(requestedAbsolute).catch((error) => {\n if (isMissingPathError(error)) return null;\n throw error;\n });\n if (!requestedStats?.isFile()) {\n throw new Error(`Scenario path does not name a file: ${requestedPath}.`);\n }\n const scenarioPath = await realpath(requestedAbsolute);\n const projectRoot = await findProjectRoot(path.dirname(scenarioPath));\n const canonicalProjectRoot = await realpath(projectRoot);\n const scenarioRoot = path.join(canonicalProjectRoot, \"test\", \"scenarios\");\n const canonicalScenarioRoot = await realpath(scenarioRoot).catch((error) => {\n if (isMissingPathError(error)) return null;\n throw error;\n });\n if (\n canonicalScenarioRoot === null ||\n !isWithinDirectory(canonicalScenarioRoot, scenarioPath) ||\n !scenarioPath.endsWith(\".scenario.ts\")\n ) {\n throw new Error(\n \"scenarioPath must resolve to test/scenarios/**/*.scenario.ts inside one game package.\",\n );\n }\n const gamePath = path.join(canonicalProjectRoot, \"app\", \"game.ts\");\n if (!(await isFile(gamePath))) {\n throw new Error(`Game package is missing ${gamePath}.`);\n }\n return {\n projectRoot: canonicalProjectRoot,\n scenarioPath,\n relativeScenarioPath: toPosix(\n path.relative(canonicalProjectRoot, scenarioPath),\n ),\n gamePath,\n };\n}\n\nasync function findProjectRoot(start: string): Promise<string> {\n let current = path.resolve(start);\n for (;;) {\n if (\n (await isFile(path.join(current, \"package.json\"))) &&\n (await isFile(path.join(current, \"app\", \"game.ts\")))\n ) {\n return current;\n }\n const parent = path.dirname(current);\n if (parent === current) {\n throw new Error(\n \"Could not find a game package containing package.json and app/game.ts.\",\n );\n }\n current = parent;\n }\n}\n\nfunction buildSyntheticSource(source: ScenarioSource): string {\n const gameSpecifier = localImportSpecifier(\n source.projectRoot,\n source.gamePath,\n );\n const scenarioSpecifier = localImportSpecifier(\n source.projectRoot,\n source.scenarioPath,\n );\n return [\n `import * as gameModule from ${JSON.stringify(gameSpecifier)};`,\n `import * as scenarioModule from ${JSON.stringify(scenarioSpecifier)};`,\n 'import { inspectScenario, toScenarioReplayDefinition } from \"@dreamboard-games/sdk/testing\";',\n 'import { digestScenarioProjection, scenarioProjectionParityFromInspectNode } from \"@dreamboard-games/sdk/testing-runtime\";',\n \"const game = gameModule.game ?? gameModule.default;\",\n \"const scenario = scenarioModule.scenario ?? scenarioModule.default;\",\n \"export async function compile(options) {\",\n \" if (!game || !scenario) {\",\n ' throw new Error(\"Compiled scenario entry is missing game or scenario authority.\");',\n \" }\",\n \" const definition = toScenarioReplayDefinition(scenario);\",\n \" const checkpoint = typeof options.at === 'string' ? scenario.checkpoints?.[options.at] : options.at;\",\n \" if (typeof options.at === 'string' && checkpoint === undefined) {\",\n \" const available = Object.keys(scenario.checkpoints ?? {}).sort();\",\n \" throw new Error(`Unknown checkpoint '${options.at}'; available checkpoints: ${available.join(', ') || 'none'}.`);\",\n \" }\",\n \" const inspected = await inspectScenario({\",\n \" game,\",\n \" scenario: definition,\",\n \" identity: {\",\n \" id: definition.id,\",\n \" path: options.scenarioPath,\",\n \" sourceDigest: options.sourceDigest,\",\n \" },\",\n ' perspective: { kind: \"spectator\" },',\n \" ...(checkpoint === undefined ? {} : { at: checkpoint }),\",\n \" });\",\n \" return {\",\n \" definition,\",\n \" checkpoint: inspected.node.checkpoint,\",\n \" expected: {\",\n \" checkpointDigest: inspected.node.checkpointDigest,\",\n \" publicProjectionDigest: digestScenarioProjection(\",\n \" scenarioProjectionParityFromInspectNode(inspected.node),\",\n \" ),\",\n \" },\",\n \" };\",\n \"}\",\n ].join(\"\\n\");\n}\n\nasync function digestSourceClosure(options: {\n readonly projectRoot: string;\n readonly inputPaths: readonly string[];\n}): Promise<`sha256:${string}`> {\n const syntheticPath = path.resolve(options.projectRoot, syntheticSourceFile);\n const localPaths = options.inputPaths\n .map((inputPath) =>\n path.isAbsolute(inputPath)\n ? inputPath\n : path.resolve(options.projectRoot, inputPath),\n )\n .filter(\n (inputPath) =>\n inputPath !== syntheticPath &&\n isWithinDirectory(options.projectRoot, inputPath) &&\n !toPosix(path.relative(options.projectRoot, inputPath))\n .split(\"/\")\n .includes(\"node_modules\"),\n );\n const inputs = await Promise.all(\n [...new Set(localPaths)].map(async (inputPath) => {\n const content = await readFile(inputPath);\n return {\n path: toPosix(path.relative(options.projectRoot, inputPath)),\n sha256: createHash(\"sha256\").update(content).digest(\"hex\"),\n };\n }),\n );\n inputs.sort((left, right) =>\n left.path < right.path ? -1 : left.path > right.path ? 1 : 0,\n );\n return `sha256:${createHash(\"sha256\")\n .update(\n JSON.stringify({\n digestVersion: scenarioSourceDigestVersion,\n inputs,\n }),\n )\n .digest(\"hex\")}`;\n}\n\nfunction assertSerializableCompiledReplay(\n value: CompiledScenarioReplay,\n): CompiledScenarioReplay {\n const serialized = JSON.stringify(value);\n const parsed = JSON.parse(serialized) as CompiledScenarioReplay;\n if (\n parsed.schemaVersion !== 1 ||\n !/^sha256:[a-f0-9]{64}$/.test(parsed.scenario.sourceDigest) ||\n !/^sha256:[a-f0-9]{64}$/.test(parsed.expected.checkpointDigest) ||\n !/^sha256:[a-f0-9]{64}$/.test(parsed.expected.publicProjectionDigest)\n ) {\n throw new Error(\"Compiled scenario replay failed digest validation.\");\n }\n return parsed;\n}\n\nfunction localImportSpecifier(projectRoot: string, filePath: string): string {\n const relative = toPosix(path.relative(projectRoot, filePath));\n return relative.startsWith(\".\") ? relative : `./${relative}`;\n}\n\nfunction isWithinDirectory(directory: string, filePath: string): boolean {\n const relative = path.relative(directory, filePath);\n return (\n relative !== \"\" &&\n relative !== \"..\" &&\n !relative.startsWith(`..${path.sep}`) &&\n !path.isAbsolute(relative)\n );\n}\n\nasync function isFile(filePath: string): Promise<boolean> {\n return stat(filePath)\n .then((value) => value.isFile())\n .catch((error) => {\n if (isMissingPathError(error)) return false;\n throw error;\n });\n}\n\nfunction isMissingPathError(error: unknown): boolean {\n return (\n typeof error === \"object\" &&\n error !== null &&\n \"code\" in error &&\n (error as { readonly code?: unknown }).code === \"ENOENT\"\n );\n}\n\nfunction toPosix(value: string): string {\n return value.split(path.sep).join(\"/\");\n}\n"],"mappings":";;;AAAA,SAAS,kBAAkB;AAC3B,SAAS,qBAAqB;AAC9B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,cAAc;AACvB,OAAO,UAAU;AACjB,SAAS,qBAAqB;AAC9B,SAAS,aAAa;AAmDtB,IAAM,8BAA8B;AACpC,IAAM,sBAAsB;AAS5B,eAAsB,sBACpB,SACiC;AACjC,QAAM,SAAS,MAAM,sBAAsB,QAAQ,YAAY;AAC/D,QAAM,kBAAkB,qBAAqB,MAAM;AACnD,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI,MAAM,QAAQ,IAAI;AAAA,IACpB,wBAAwB,SAAS;AAAA,IACjC,wBAAwB,kBAAkB;AAAA,IAC1C,wBAAwB,SAAS;AAAA,IACjC,wBAAwB,iBAAiB;AAAA,IACzC,wBAAwB,OAAO;AAAA,EACjC,CAAC;AACD,QAAM,UAAU,MAAM,MAAM;AAAA,IAC1B,eAAe,OAAO;AAAA,IACtB,OAAO;AAAA,MACL,UAAU;AAAA,MACV,QAAQ;AAAA,MACR,YAAY,OAAO;AAAA,MACnB,YAAY;AAAA,IACd;AAAA,IACA,QAAQ;AAAA,IACR,OAAO;AAAA,MACL,iCAAiC;AAAA,MACjC,0CAA0C;AAAA,MAC1C,iCAAiC;AAAA,MACjC,yCAAyC;AAAA,MACzC,+BAA+B;AAAA,MAC/B,KAAK,cAAc,YAAY,GAAG,EAAE,QAAQ,KAAK;AAAA,IACnD;AAAA,IACA,QAAQ;AAAA,IACR,UAAU;AAAA,IACV,QAAQ;AAAA,IACR,WAAW;AAAA,IACX,UAAU;AAAA,IACV,OAAO;AAAA,IACP,UAAU;AAAA,EACZ,CAAC;AACD,QAAM,SAAS,QAAQ,cAAc,CAAC;AACtC,MAAI,CAAC,UAAU,CAAC,QAAQ,UAAU;AAChC,UAAM,IAAI,MAAM,uDAAuD;AAAA,EACzE;AACA,QAAM,eAAe,MAAM,oBAAoB;AAAA,IAC7C,aAAa,OAAO;AAAA,IACpB,YAAY,OAAO,KAAK,QAAQ,SAAS,MAAM;AAAA,EACjD,CAAC;AAED,QAAM,WAAW,MAAM;AAAA,IACrB,KAAK,KAAK,OAAO,GAAG,+BAA+B;AAAA,EACrD;AACA,QAAM,aAAa,KAAK,KAAK,UAAU,uBAAuB;AAC9D,MAAI;AACF,UAAM,UAAU,YAAY,OAAO,IAAI;AACvC,UAAM,SAAU,MAAM,OACpB,GAAG,cAAc,UAAU,EAAE,IAAI,WAAW,aAAa,MAAM,GAAG,EAAE,CAAC;AAEvE,QAAI,OAAO,OAAO,YAAY,YAAY;AACxC,YAAM,IAAI,MAAM,8CAA8C;AAAA,IAChE;AACA,UAAM,eAAe,MAAM,OAAO,QAAQ;AAAA,MACxC,GAAI,QAAQ,OAAO,SAAY,CAAC,IAAI,EAAE,IAAI,QAAQ,GAAG;AAAA,MACrD,cAAc,OAAO;AAAA,MACrB;AAAA,IACF,CAAC;AACD,UAAM,WAAW;AAAA,MACf,eAAe;AAAA,MACf,UAAU;AAAA,QACR,MAAM,OAAO;AAAA,QACb;AAAA,MACF;AAAA,MACA,YAAY,aAAa;AAAA,MACzB,YAAY,aAAa;AAAA,MACzB,UAAU,aAAa;AAAA,IACzB;AACA,WAAO,iCAAiC,QAAQ;AAAA,EAClD,UAAE;AACA,UAAM,GAAG,UAAU,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAAA,EACrD;AACF;AAEA,eAAe,wBAAwB,MAA+B;AACpE,QAAM,aAAa;AAAA,IACjB,KAAK,QAAQ,YAAY,SAAS,MAAM,IAAI,KAAK;AAAA,IACjD,KAAK,QAAQ,YAAY,SAAS,GAAG,IAAI,KAAK;AAAA,EAChD;AACA,aAAW,aAAa,YAAY;AAClC,QAAI,MAAM,OAAO,SAAS,EAAG,QAAO;AAAA,EACtC;AACA,QAAM,IAAI;AAAA,IACR,uDAAuD,IAAI,gBAAgB,YAAY,OAAO;AAAA,EAChG;AACF;AAEA,eAAe,sBACb,eACyB;AACzB,MAAI,OAAO,kBAAkB,YAAY,cAAc,WAAW,GAAG;AACnE,UAAM,IAAI,MAAM,0CAA0C;AAAA,EAC5D;AACA,QAAM,oBAAoB,KAAK,QAAQ,QAAQ,IAAI,GAAG,aAAa;AACnE,QAAM,iBAAiB,MAAM,MAAM,iBAAiB,EAAE,MAAM,CAAC,UAAU;AACrE,QAAI,mBAAmB,KAAK,EAAG,QAAO;AACtC,UAAM;AAAA,EACR,CAAC;AACD,MAAI,CAAC,gBAAgB,OAAO,GAAG;AAC7B,UAAM,IAAI,MAAM,uCAAuC,aAAa,GAAG;AAAA,EACzE;AACA,QAAM,eAAe,MAAM,SAAS,iBAAiB;AACrD,QAAM,cAAc,MAAM,gBAAgB,KAAK,QAAQ,YAAY,CAAC;AACpE,QAAM,uBAAuB,MAAM,SAAS,WAAW;AACvD,QAAM,eAAe,KAAK,KAAK,sBAAsB,QAAQ,WAAW;AACxE,QAAM,wBAAwB,MAAM,SAAS,YAAY,EAAE,MAAM,CAAC,UAAU;AAC1E,QAAI,mBAAmB,KAAK,EAAG,QAAO;AACtC,UAAM;AAAA,EACR,CAAC;AACD,MACE,0BAA0B,QAC1B,CAAC,kBAAkB,uBAAuB,YAAY,KACtD,CAAC,aAAa,SAAS,cAAc,GACrC;AACA,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACA,QAAM,WAAW,KAAK,KAAK,sBAAsB,OAAO,SAAS;AACjE,MAAI,CAAE,MAAM,OAAO,QAAQ,GAAI;AAC7B,UAAM,IAAI,MAAM,2BAA2B,QAAQ,GAAG;AAAA,EACxD;AACA,SAAO;AAAA,IACL,aAAa;AAAA,IACb;AAAA,IACA,sBAAsB;AAAA,MACpB,KAAK,SAAS,sBAAsB,YAAY;AAAA,IAClD;AAAA,IACA;AAAA,EACF;AACF;AAEA,eAAe,gBAAgB,OAAgC;AAC7D,MAAI,UAAU,KAAK,QAAQ,KAAK;AAChC,aAAS;AACP,QACG,MAAM,OAAO,KAAK,KAAK,SAAS,cAAc,CAAC,KAC/C,MAAM,OAAO,KAAK,KAAK,SAAS,OAAO,SAAS,CAAC,GAClD;AACA,aAAO;AAAA,IACT;AACA,UAAM,SAAS,KAAK,QAAQ,OAAO;AACnC,QAAI,WAAW,SAAS;AACtB,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AACA,cAAU;AAAA,EACZ;AACF;AAEA,SAAS,qBAAqB,QAAgC;AAC5D,QAAM,gBAAgB;AAAA,IACpB,OAAO;AAAA,IACP,OAAO;AAAA,EACT;AACA,QAAM,oBAAoB;AAAA,IACxB,OAAO;AAAA,IACP,OAAO;AAAA,EACT;AACA,SAAO;AAAA,IACL,+BAA+B,KAAK,UAAU,aAAa,CAAC;AAAA,IAC5D,mCAAmC,KAAK,UAAU,iBAAiB,CAAC;AAAA,IACpE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,EAAE,KAAK,IAAI;AACb;AAEA,eAAe,oBAAoB,SAGH;AAC9B,QAAM,gBAAgB,KAAK,QAAQ,QAAQ,aAAa,mBAAmB;AAC3E,QAAM,aAAa,QAAQ,WACxB;AAAA,IAAI,CAAC,cACJ,KAAK,WAAW,SAAS,IACrB,YACA,KAAK,QAAQ,QAAQ,aAAa,SAAS;AAAA,EACjD,EACC;AAAA,IACC,CAAC,cACC,cAAc,iBACd,kBAAkB,QAAQ,aAAa,SAAS,KAChD,CAAC,QAAQ,KAAK,SAAS,QAAQ,aAAa,SAAS,CAAC,EACnD,MAAM,GAAG,EACT,SAAS,cAAc;AAAA,EAC9B;AACF,QAAM,SAAS,MAAM,QAAQ;AAAA,IAC3B,CAAC,GAAG,IAAI,IAAI,UAAU,CAAC,EAAE,IAAI,OAAO,cAAc;AAChD,YAAM,UAAU,MAAM,SAAS,SAAS;AACxC,aAAO;AAAA,QACL,MAAM,QAAQ,KAAK,SAAS,QAAQ,aAAa,SAAS,CAAC;AAAA,QAC3D,QAAQ,WAAW,QAAQ,EAAE,OAAO,OAAO,EAAE,OAAO,KAAK;AAAA,MAC3D;AAAA,IACF,CAAC;AAAA,EACH;AACA,SAAO;AAAA,IAAK,CAAC,MAAM,UACjB,KAAK,OAAO,MAAM,OAAO,KAAK,KAAK,OAAO,MAAM,OAAO,IAAI;AAAA,EAC7D;AACA,SAAO,UAAU,WAAW,QAAQ,EACjC;AAAA,IACC,KAAK,UAAU;AAAA,MACb,eAAe;AAAA,MACf;AAAA,IACF,CAAC;AAAA,EACH,EACC,OAAO,KAAK,CAAC;AAClB;AAEA,SAAS,iCACP,OACwB;AACxB,QAAM,aAAa,KAAK,UAAU,KAAK;AACvC,QAAM,SAAS,KAAK,MAAM,UAAU;AACpC,MACE,OAAO,kBAAkB,KACzB,CAAC,wBAAwB,KAAK,OAAO,SAAS,YAAY,KAC1D,CAAC,wBAAwB,KAAK,OAAO,SAAS,gBAAgB,KAC9D,CAAC,wBAAwB,KAAK,OAAO,SAAS,sBAAsB,GACpE;AACA,UAAM,IAAI,MAAM,oDAAoD;AAAA,EACtE;AACA,SAAO;AACT;AAEA,SAAS,qBAAqB,aAAqB,UAA0B;AAC3E,QAAM,WAAW,QAAQ,KAAK,SAAS,aAAa,QAAQ,CAAC;AAC7D,SAAO,SAAS,WAAW,GAAG,IAAI,WAAW,KAAK,QAAQ;AAC5D;AAEA,SAAS,kBAAkB,WAAmB,UAA2B;AACvE,QAAM,WAAW,KAAK,SAAS,WAAW,QAAQ;AAClD,SACE,aAAa,MACb,aAAa,QACb,CAAC,SAAS,WAAW,KAAK,KAAK,GAAG,EAAE,KACpC,CAAC,KAAK,WAAW,QAAQ;AAE7B;AAEA,eAAe,OAAO,UAAoC;AACxD,SAAO,KAAK,QAAQ,EACjB,KAAK,CAAC,UAAU,MAAM,OAAO,CAAC,EAC9B,MAAM,CAAC,UAAU;AAChB,QAAI,mBAAmB,KAAK,EAAG,QAAO;AACtC,UAAM;AAAA,EACR,CAAC;AACL;AAEA,SAAS,mBAAmB,OAAyB;AACnD,SACE,OAAO,UAAU,YACjB,UAAU,QACV,UAAU,SACT,MAAsC,SAAS;AAEpD;AAEA,SAAS,QAAQ,OAAuB;AACtC,SAAO,MAAM,MAAM,KAAK,GAAG,EAAE,KAAK,GAAG;AACvC;","names":[]}
@@ -1,13 +1,13 @@
1
1
  import { D as DispatchTraceSummaryEntry } from './diagnostics-DIi3ina7.js';
2
2
  import { o as ScenarioDefinitionGameLike, n as ScenarioDefinition } from './definitions-BezxXhhP.js';
3
- import { i as Sha256Digest, d as InspectNode } from './types-B-FI0jrx.js';
4
- export { h as ScenarioRuntimeCheckpointMaterialization, m as materializeScenarioRuntimeCheckpoint } from './types-B-FI0jrx.js';
3
+ import { i as Sha256Digest, d as InspectNode } from './types-Cs_Jp0cf.js';
4
+ export { h as ScenarioRuntimeCheckpointMaterialization, m as materializeScenarioRuntimeCheckpoint } from './types-Cs_Jp0cf.js';
5
5
  import 'zod';
6
6
  import './views-BbCGDuCs.js';
7
7
  import './runtime-BhuaOkIL.js';
8
8
  import './types.js';
9
9
  import './protocol-Bcas2Xa8.js';
10
- import './index.d-C7Ztirg6.js';
10
+ import './index.d-90ms7Mwh.js';
11
11
 
12
12
  type GameLike = {
13
13
  readonly phases: Readonly<Record<string, unknown>>;
@@ -5,15 +5,15 @@ import {
5
5
  materializeScenarioRuntimeCheckpoint,
6
6
  replayScenario,
7
7
  resolveScenarioCommandParams
8
- } from "./chunk-KZFHTUI5.js";
8
+ } from "./chunk-CHOXM43O.js";
9
9
  import {
10
10
  interactionDomainEligibleCount
11
- } from "./chunk-XDGRC6OR.js";
12
- import "./chunk-5XTAQ4EQ.js";
13
- import "./chunk-YNW3KBDE.js";
11
+ } from "./chunk-WASWAYYX.js";
12
+ import "./chunk-TO6WRLRN.js";
13
+ import "./chunk-7QKE5BFU.js";
14
14
  import "./chunk-PF7L4BMG.js";
15
15
  import "./chunk-FBQNCOPQ.js";
16
- import "./chunk-3PFDHTR7.js";
16
+ import "./chunk-3VSOH3TZ.js";
17
17
  import "./chunk-PZ5AY32C.js";
18
18
 
19
19
  // src/testing/scenario-projection-digest.ts