@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.
- package/README.md +29 -11
- package/dist/authoring/index.d.ts +3 -6
- package/dist/authoring/index.js +2 -2
- package/dist/authoring-compiler.d.ts +3 -3
- package/dist/authoring-compiler.js +3 -4
- package/dist/authoring-materialize-cli.js +5 -6
- package/dist/authoring-materialize-cli.js.map +1 -1
- package/dist/browser-interaction.d.ts +21 -21
- package/dist/{chunk-3PFDHTR7.js → chunk-3VSOH3TZ.js} +29 -2
- package/dist/chunk-3VSOH3TZ.js.map +1 -0
- package/dist/{chunk-OFIDC7DJ.js → chunk-73YISGYO.js} +4 -4
- package/dist/chunk-73YISGYO.js.map +1 -0
- package/dist/{chunk-YNW3KBDE.js → chunk-7QKE5BFU.js} +2 -2
- package/dist/{chunk-KZFHTUI5.js → chunk-CHOXM43O.js} +4 -4
- package/dist/chunk-CSIEFYTC.js +9 -0
- package/dist/chunk-CSIEFYTC.js.map +1 -0
- package/dist/{chunk-MLFHVYF7.js → chunk-KH6AET7P.js} +4 -4
- package/dist/chunk-KH6AET7P.js.map +1 -0
- package/dist/{chunk-MPVC2SU6.js → chunk-LMHCGCA6.js} +2 -2
- package/dist/{chunk-WAQUD4IG.js → chunk-NLZDRIVW.js} +16 -16
- package/dist/{chunk-5XTAQ4EQ.js → chunk-TO6WRLRN.js} +2 -2
- package/dist/{chunk-42HQLHVA.js → chunk-VJVKGWHW.js} +4 -7
- package/dist/chunk-VJVKGWHW.js.map +1 -0
- package/dist/{chunk-YOLIZMXR.js → chunk-VRRR6QZT.js} +3 -3
- package/dist/{chunk-YOLIZMXR.js.map → chunk-VRRR6QZT.js.map} +1 -1
- package/dist/{chunk-XDGRC6OR.js → chunk-WASWAYYX.js} +3 -3
- package/dist/{chunk-7JBPOJOF.js → chunk-ZGQGFXFG.js} +9 -9
- package/dist/{index.d-C7Ztirg6.d.ts → index.d-90ms7Mwh.d.ts} +124 -115
- package/dist/index.js +2 -2
- package/dist/package-set.d.ts +2 -2
- package/dist/package-set.js +2 -2
- package/dist/reducer/advanced.js +3 -3
- package/dist/reducer-contract.d.ts +1 -1
- package/dist/reducer-contract.js +3 -1
- package/dist/reducer.d.ts +1 -1
- package/dist/reducer.js +3 -3
- package/dist/reference-games/index.d.ts +29 -11
- package/dist/reference-games/index.js +43 -45
- package/dist/reference-games/index.js.map +1 -1
- package/dist/runtime/primitives.js +4 -4
- package/dist/runtime/workspace-contract.js +8 -8
- package/dist/runtime.js +12 -12
- package/dist/testing-compiler.d.ts +1 -1
- package/dist/testing-compiler.js +1 -4
- package/dist/testing-compiler.js.map +1 -1
- package/dist/testing-runtime.d.ts +3 -3
- package/dist/testing-runtime.js +5 -5
- package/dist/testing.d.ts +5 -140
- package/dist/testing.js +5 -450
- package/dist/testing.js.map +1 -1
- package/dist/{types-B-FI0jrx.d.ts → types-Cs_Jp0cf.d.ts} +1 -1
- package/dist/ui/components.js +1 -1
- package/dist/ui.js +2 -2
- package/package.json +22 -29
- package/REFERENCE.md +0 -25375
- package/dist/chunk-3PFDHTR7.js.map +0 -1
- package/dist/chunk-42HQLHVA.js.map +0 -1
- package/dist/chunk-MLFHVYF7.js.map +0 -1
- package/dist/chunk-OFIDC7DJ.js.map +0 -1
- package/dist/chunk-THWT4V3Z.js +0 -12
- package/dist/chunk-THWT4V3Z.js.map +0 -1
- package/dist/chunk-UNVCT5Z7.js +0 -73
- package/dist/chunk-UNVCT5Z7.js.map +0 -1
- package/dist/chunk-UTSBXZAM.js +0 -435
- package/dist/chunk-UTSBXZAM.js.map +0 -1
- package/dist/chunk-YN5W67YL.js +0 -174
- package/dist/chunk-YN5W67YL.js.map +0 -1
- package/dist/reference-game-compiler.d.ts +0 -45
- package/dist/reference-game-compiler.js +0 -25
- package/dist/reference-game-compiler.js.map +0 -1
- package/dist/reference-game-source-manifest-cli.d.ts +0 -1
- package/dist/reference-game-source-manifest-cli.js +0 -84
- package/dist/reference-game-source-manifest-cli.js.map +0 -1
- package/dist/schema-CJc0UfjJ.d.ts +0 -216
- /package/dist/{chunk-YNW3KBDE.js.map → chunk-7QKE5BFU.js.map} +0 -0
- /package/dist/{chunk-KZFHTUI5.js.map → chunk-CHOXM43O.js.map} +0 -0
- /package/dist/{chunk-MPVC2SU6.js.map → chunk-LMHCGCA6.js.map} +0 -0
- /package/dist/{chunk-WAQUD4IG.js.map → chunk-NLZDRIVW.js.map} +0 -0
- /package/dist/{chunk-5XTAQ4EQ.js.map → chunk-TO6WRLRN.js.map} +0 -0
- /package/dist/{chunk-XDGRC6OR.js.map → chunk-WASWAYYX.js.map} +0 -0
- /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-
|
|
6
|
-
import "./chunk-
|
|
5
|
+
} from "./chunk-KH6AET7P.js";
|
|
6
|
+
import "./chunk-CSIEFYTC.js";
|
|
7
7
|
import "./chunk-PZ5AY32C.js";
|
|
8
8
|
export {
|
|
9
9
|
DREAMBOARD_SDK_PACKAGES,
|
package/dist/package-set.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
declare const DREAMBOARD_SDK_VERSION:
|
|
1
|
+
declare const DREAMBOARD_SDK_VERSION: string;
|
|
2
2
|
declare const DREAMBOARD_SDK_PACKAGES: {
|
|
3
|
-
readonly "@dreamboard-games/sdk":
|
|
3
|
+
readonly "@dreamboard-games/sdk": string;
|
|
4
4
|
};
|
|
5
5
|
type DreamboardSdkPackageName = keyof typeof DREAMBOARD_SDK_PACKAGES;
|
|
6
6
|
type DreamboardSdkPackageSet = {
|
package/dist/package-set.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-
|
|
6
|
-
import "./chunk-
|
|
5
|
+
} from "./chunk-KH6AET7P.js";
|
|
6
|
+
import "./chunk-CSIEFYTC.js";
|
|
7
7
|
import "./chunk-PZ5AY32C.js";
|
|
8
8
|
export {
|
|
9
9
|
DREAMBOARD_SDK_PACKAGES,
|
package/dist/reducer/advanced.js
CHANGED
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
} from "../chunk-VWTKGIYF.js";
|
|
8
8
|
import {
|
|
9
9
|
createClientParamSchemasByPhase
|
|
10
|
-
} from "../chunk-
|
|
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-
|
|
24
|
-
import "../chunk-
|
|
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-
|
|
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';
|
package/dist/reducer-contract.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
2
|
REDUCER_CONTRACT_VERSION,
|
|
3
|
+
assertReducerBundleContract,
|
|
3
4
|
zod_exports
|
|
4
|
-
} from "./chunk-
|
|
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-
|
|
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-
|
|
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-
|
|
48
|
+
} from "./chunk-7QKE5BFU.js";
|
|
49
49
|
import "./chunk-PF7L4BMG.js";
|
|
50
|
-
import "./chunk-
|
|
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 {
|
|
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
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
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 {
|
|
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
|
-
|
|
30
|
-
|
|
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-
|
|
88
|
-
import "../chunk-MPVC2SU6.js";
|
|
87
|
+
} from "../chunk-NLZDRIVW.js";
|
|
89
88
|
import "../chunk-T3ZKNUZ7.js";
|
|
90
|
-
import "../chunk-
|
|
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-
|
|
4
|
+
} from "../chunk-ZGQGFXFG.js";
|
|
5
5
|
import "../chunk-VWTKGIYF.js";
|
|
6
|
-
import "../chunk-
|
|
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-
|
|
13
|
-
import "../chunk-
|
|
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-
|
|
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-
|
|
3
|
+
} from "./chunk-ZGQGFXFG.js";
|
|
4
4
|
import "./chunk-VWTKGIYF.js";
|
|
5
|
-
import "./chunk-
|
|
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-
|
|
18
|
-
import "./chunk-
|
|
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-
|
|
24
|
-
import "./chunk-
|
|
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-
|
|
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
|
|
33
|
+
* player, spectator, browser, or ordinary-log boundary.
|
|
34
34
|
*/
|
|
35
35
|
declare function compileScenarioReplay(options: CompileScenarioReplayOptions): Promise<CompiledScenarioReplay>;
|
|
36
36
|
|
package/dist/testing-compiler.js
CHANGED
|
@@ -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) =>
|
|
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":"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","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-
|
|
4
|
-
export { h as ScenarioRuntimeCheckpointMaterialization, m as materializeScenarioRuntimeCheckpoint } from './types-
|
|
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-
|
|
10
|
+
import './index.d-90ms7Mwh.js';
|
|
11
11
|
|
|
12
12
|
type GameLike = {
|
|
13
13
|
readonly phases: Readonly<Record<string, unknown>>;
|
package/dist/testing-runtime.js
CHANGED
|
@@ -5,15 +5,15 @@ import {
|
|
|
5
5
|
materializeScenarioRuntimeCheckpoint,
|
|
6
6
|
replayScenario,
|
|
7
7
|
resolveScenarioCommandParams
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-CHOXM43O.js";
|
|
9
9
|
import {
|
|
10
10
|
interactionDomainEligibleCount
|
|
11
|
-
} from "./chunk-
|
|
12
|
-
import "./chunk-
|
|
13
|
-
import "./chunk-
|
|
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-
|
|
16
|
+
import "./chunk-3VSOH3TZ.js";
|
|
17
17
|
import "./chunk-PZ5AY32C.js";
|
|
18
18
|
|
|
19
19
|
// src/testing/scenario-projection-digest.ts
|