@dreamboard-games/sdk 0.4.0-alpha.8 → 0.5.0-alpha.0
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 +49 -11
- package/dist/authoring/index.d.ts +6 -14
- package/dist/authoring/index.js +11 -547
- package/dist/authoring/index.js.map +1 -1
- package/dist/authoring-compiler.d.ts +27 -0
- package/dist/authoring-compiler.js +11 -0
- package/dist/authoring-compiler.js.map +1 -0
- package/dist/authoring-materialize-cli.d.ts +1 -0
- package/dist/authoring-materialize-cli.js +45 -0
- package/dist/authoring-materialize-cli.js.map +1 -0
- package/dist/browser-interaction.d.ts +22 -22
- package/dist/{chunk-3BLN5POZ.js → chunk-2GQIALJL.js} +51 -15
- package/dist/chunk-2GQIALJL.js.map +1 -0
- package/dist/chunk-533O7C4L.js +7095 -0
- package/dist/chunk-533O7C4L.js.map +1 -0
- package/dist/{chunk-44N3T2A5.js → chunk-6LMESVGT.js} +9 -28
- package/dist/chunk-6LMESVGT.js.map +1 -0
- package/dist/{chunk-ZYONCTZ2.js → chunk-DQS2EG5E.js} +3 -3
- package/dist/{chunk-ZYONCTZ2.js.map → chunk-DQS2EG5E.js.map} +1 -1
- package/dist/chunk-EOEA3I64.js +1864 -0
- package/dist/chunk-EOEA3I64.js.map +1 -0
- package/dist/{chunk-B2YBS3SG.js → chunk-FL67RDID.js} +41 -13
- package/dist/chunk-FL67RDID.js.map +1 -0
- package/dist/{chunk-2TAKLJJD.js → chunk-HIH6Y4FA.js} +222 -1267
- package/dist/chunk-HIH6Y4FA.js.map +1 -0
- package/dist/chunk-HUK4234C.js +166 -0
- package/dist/chunk-HUK4234C.js.map +1 -0
- package/dist/chunk-KGV2EUNN.js +532 -0
- package/dist/chunk-KGV2EUNN.js.map +1 -0
- package/dist/{chunk-VTK4TIXC.js → chunk-KRJPRYEA.js} +49 -4
- package/dist/chunk-KRJPRYEA.js.map +1 -0
- package/dist/chunk-KWHOFBDM.js +9 -0
- package/dist/chunk-KWHOFBDM.js.map +1 -0
- package/dist/{chunk-UC2UXAC6.js → chunk-LMHCGCA6.js} +2 -2
- package/dist/{chunk-XV27IQHA.js → chunk-N33CGX2F.js} +15 -85
- package/dist/chunk-N33CGX2F.js.map +1 -0
- package/dist/chunk-TXELBVTG.js +32 -0
- package/dist/chunk-TXELBVTG.js.map +1 -0
- package/dist/{chunk-2TRZSZGD.js → chunk-VRRR6QZT.js} +9 -12
- package/dist/chunk-VRRR6QZT.js.map +1 -0
- package/dist/chunk-VWTKGIYF.js +90 -0
- package/dist/chunk-VWTKGIYF.js.map +1 -0
- package/dist/{chunk-IYX5OO2K.js → chunk-XFMSLL3P.js} +133 -61
- package/dist/chunk-XFMSLL3P.js.map +1 -0
- package/dist/{chunk-YGQTL63W.js → chunk-ZSTCUJKZ.js} +4 -4
- package/dist/chunk-ZSTCUJKZ.js.map +1 -0
- package/dist/codegen.js +1 -1
- package/dist/{components-BTwSIjXj.d.ts → components-CNAt5J1p.d.ts} +1 -1
- package/dist/definitions-bZSBaPjj.d.ts +300 -0
- package/dist/{diagnostics-1BWjRo6-.d.ts → diagnostics-DIi3ina7.d.ts} +2 -1
- package/dist/digest.d.ts +8 -0
- package/dist/{index-CFTjJIXd.d.ts → index-CR69MyWr.d.ts} +2 -2
- package/dist/{index.d-C0PKOVbh.d.ts → index.d-Bw8AOcgp.d.ts} +532 -225
- package/dist/index.js +2 -2
- package/dist/package-set.d.ts +2 -2
- package/dist/package-set.js +2 -2
- package/dist/plugin-runtime-contract.d.ts +17 -0
- package/dist/plugin-runtime-contract.js +94 -0
- package/dist/plugin-runtime-contract.js.map +1 -0
- package/dist/{protocol-nS2ojsGr.d.ts → protocol-CVaSqPgX.d.ts} +54 -47
- package/dist/reducer/advanced.d.ts +5 -4
- package/dist/reducer/advanced.js +14 -108
- package/dist/reducer/advanced.js.map +1 -1
- package/dist/reducer-contract.d.ts +1 -1
- package/dist/reducer-contract.js +6 -4
- package/dist/reducer.d.ts +20 -98
- package/dist/reducer.js +28 -6050
- package/dist/reducer.js.map +1 -1
- package/dist/reference-games/index.d.ts +6 -198
- package/dist/reference-games/index.js +18 -200
- package/dist/reference-games/index.js.map +1 -1
- package/dist/runtime/primitives.d.ts +3 -3
- package/dist/runtime/primitives.js +5 -5
- package/dist/runtime/runtime-api.d.ts +1 -1
- package/dist/runtime/workspace-contract.d.ts +343 -11
- package/dist/runtime/workspace-contract.js +12 -6
- package/dist/{runtime-Dkfm1x2r.d.ts → runtime-C7Z2acNU.d.ts} +67 -31
- package/dist/{runtime-api-C6aWo9c0.d.ts → runtime-api-CgPuEVeF.d.ts} +4 -13
- package/dist/runtime.d.ts +7 -7
- package/dist/runtime.js +15 -11
- package/dist/runtime.js.map +1 -1
- package/dist/schema.d.ts +405 -0
- package/dist/{stale-contract-artifact-error-C5AaZPJ8.d.ts → stale-contract-artifact-error-XLaweZtF.d.ts} +1 -1
- package/dist/testing-compiler.d.ts +37 -0
- package/dist/testing-compiler.js +272 -0
- package/dist/testing-compiler.js.map +1 -0
- package/dist/testing-runtime.d.ts +98 -21
- package/dist/testing-runtime.js +154 -95
- package/dist/testing-runtime.js.map +1 -1
- package/dist/testing.d.ts +197 -156
- package/dist/testing.js +660 -372
- package/dist/testing.js.map +1 -1
- package/dist/types-DN4O7kH_.d.ts +122 -0
- package/dist/{types-CTeN_QAk.d.ts → types-q1Guidm5.d.ts} +4 -5
- package/dist/types.d.ts +0 -1
- package/dist/ui/components.d.ts +3 -2
- package/dist/ui/components.js +1 -1
- package/dist/ui/plugin-styles.css +1 -1
- package/dist/{ui-contract-Ue6SywvO.d.ts → ui-contract-BC4JpysE.d.ts} +2 -6
- package/dist/ui.d.ts +4 -3
- package/dist/ui.js +2 -2
- package/dist/{views-Qx-EHBP8.d.ts → views-D2Cfzr3h.d.ts} +17 -5
- package/package.json +41 -22
- package/REFERENCE.md +0 -22884
- package/dist/chunk-2TAKLJJD.js.map +0 -1
- package/dist/chunk-2TRZSZGD.js.map +0 -1
- package/dist/chunk-3BLN5POZ.js.map +0 -1
- package/dist/chunk-3OZMHZK3.js +0 -40
- package/dist/chunk-3OZMHZK3.js.map +0 -1
- package/dist/chunk-44N3T2A5.js.map +0 -1
- package/dist/chunk-5CQIJHGF.js +0 -663
- package/dist/chunk-5CQIJHGF.js.map +0 -1
- package/dist/chunk-B2YBS3SG.js.map +0 -1
- package/dist/chunk-IYX5OO2K.js.map +0 -1
- package/dist/chunk-VTK4TIXC.js.map +0 -1
- package/dist/chunk-VTNEWMWJ.js +0 -12
- package/dist/chunk-VTNEWMWJ.js.map +0 -1
- package/dist/chunk-XV27IQHA.js.map +0 -1
- package/dist/chunk-YGQTL63W.js.map +0 -1
- package/dist/types-B_3pObUV.d.ts +0 -192
- /package/dist/{chunk-UC2UXAC6.js.map → chunk-LMHCGCA6.js.map} +0 -0
package/README.md
CHANGED
|
@@ -1,19 +1,57 @@
|
|
|
1
1
|
# @dreamboard-games/sdk
|
|
2
2
|
|
|
3
|
-
The public
|
|
4
|
-
package
|
|
5
|
-
|
|
3
|
+
The public TypeScript SDK for authoring, testing, and rendering Dreamboard
|
|
4
|
+
games. Install this package rather than any of the repository's unpublished
|
|
5
|
+
workspace inputs.
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
```sh
|
|
8
|
+
pnpm add @dreamboard-games/sdk
|
|
9
|
+
```
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
The package's declarations and export map are the API authority. Supported
|
|
12
|
+
imports include the root module and explicit subpaths for authoring, runtime,
|
|
13
|
+
reducer contracts, testing, browser interaction, UI, and reference-game
|
|
14
|
+
metadata. Import only subpaths present in the installed package's `exports`
|
|
15
|
+
field.
|
|
12
16
|
|
|
13
17
|
```ts
|
|
14
|
-
import {
|
|
15
|
-
DREAMBOARD_SDK_PACKAGE_SET,
|
|
16
|
-
DREAMBOARD_SDK_VERSION,
|
|
17
|
-
} from "@dreamboard-games/sdk";
|
|
18
|
+
import { DREAMBOARD_SDK_VERSION } from "@dreamboard-games/sdk";
|
|
18
19
|
import type { ReducerWire } from "@dreamboard-games/sdk/reducer-contract";
|
|
20
|
+
import {
|
|
21
|
+
REFERENCE_GAME_MANIFEST_SCHEMA_VERSION,
|
|
22
|
+
parseReferenceGameManifest,
|
|
23
|
+
type ReferenceGameManifest,
|
|
24
|
+
} from "@dreamboard-games/sdk/reference-games";
|
|
25
|
+
|
|
26
|
+
const manifest: ReferenceGameManifest = parseReferenceGameManifest(input);
|
|
27
|
+
console.log(REFERENCE_GAME_MANIFEST_SCHEMA_VERSION, manifest.id);
|
|
19
28
|
```
|
|
29
|
+
|
|
30
|
+
Reference-game manifests use schema V5. They describe the game workspace,
|
|
31
|
+
teaching purpose, mechanics, UI patterns, and substantive rights metadata.
|
|
32
|
+
|
|
33
|
+
Include the packaged stylesheet when using SDK UI components:
|
|
34
|
+
|
|
35
|
+
```ts
|
|
36
|
+
import "@dreamboard-games/sdk/ui/plugin-styles.css";
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Reducer runner contract
|
|
40
|
+
|
|
41
|
+
`createReducerBundle(game)` returns exactly the contract version and four
|
|
42
|
+
operations: `boardStatic()`, `initialize(input)`, `dispatch({ state, input })`,
|
|
43
|
+
and `project({ state, playerIds })`. The runner contract is `0.5.0`; hosts must
|
|
44
|
+
require that exact version. Dispatch includes validation and effect execution. Initialization returns
|
|
45
|
+
`{ state, terminal?, events? }`, preserving outcomes and events from initial
|
|
46
|
+
phase entry and automatic continuations.
|
|
47
|
+
|
|
48
|
+
The authoritative state is explicit on every dispatch and projection. A host
|
|
49
|
+
may retain a warm worker and SDK caches, but replaying the same state and input
|
|
50
|
+
must produce the same gameplay result as a fresh worker. Projection timing is
|
|
51
|
+
diagnostic and is excluded from this equivalence.
|
|
52
|
+
|
|
53
|
+
Seat projections are independent of session versions. The gameplay service
|
|
54
|
+
owns the monotonically increasing version, perspective, and action-set identity.
|
|
55
|
+
The plugin frame basis contains `version`, `actionSetVersion`, and
|
|
56
|
+
`perspectivePlayerId`; it has no generation counter. Hosts merge the separately
|
|
57
|
+
cached board static projection when materializing plugin gameplay frames.
|
|
@@ -1,10 +1,7 @@
|
|
|
1
|
-
import { JsonValue
|
|
1
|
+
import { JsonValue } from '../types.js';
|
|
2
2
|
|
|
3
|
-
type
|
|
3
|
+
type AuthoringMetadataV1 = {
|
|
4
4
|
sdkVersion: string;
|
|
5
|
-
codegenVersion: string;
|
|
6
|
-
manifestSchemaVersion: number;
|
|
7
|
-
generatedArtifactSchemaVersion: number;
|
|
8
5
|
};
|
|
9
6
|
type AuthoringValidationResultV1 = {
|
|
10
7
|
valid: boolean;
|
|
@@ -13,7 +10,7 @@ type AuthoringValidationResultV1 = {
|
|
|
13
10
|
};
|
|
14
11
|
type GeneratedArtifactV1 = {
|
|
15
12
|
path: string;
|
|
16
|
-
ownership: "authoritative" | "seed"
|
|
13
|
+
ownership: "authoritative" | "seed";
|
|
17
14
|
content: string;
|
|
18
15
|
contentSha256: string;
|
|
19
16
|
};
|
|
@@ -21,9 +18,6 @@ type GeneratedPathPatternV1 = {
|
|
|
21
18
|
prefix: string;
|
|
22
19
|
suffix: string;
|
|
23
20
|
};
|
|
24
|
-
type GenerateTestArtifactsInputV1 = {
|
|
25
|
-
manifest: GameTopologyManifest;
|
|
26
|
-
};
|
|
27
21
|
type AuthoringManifestConformanceCaseV1 = {
|
|
28
22
|
id: string;
|
|
29
23
|
manifest: JsonValue;
|
|
@@ -39,14 +33,13 @@ type AuthoringManifestConformanceCaseV1 = {
|
|
|
39
33
|
};
|
|
40
34
|
type ProjectAuthoringAdapterV1 = {
|
|
41
35
|
protocolVersion: 1;
|
|
42
|
-
metadata:
|
|
36
|
+
metadata: AuthoringMetadataV1;
|
|
43
37
|
generatedPaths: readonly string[];
|
|
44
38
|
generatedPathPatterns: readonly GeneratedPathPatternV1[];
|
|
45
39
|
manifestConformanceCases: readonly AuthoringManifestConformanceCaseV1[];
|
|
46
40
|
validateManifest(manifest: unknown): AuthoringValidationResultV1;
|
|
47
41
|
materializeManifest(manifest: unknown): JsonValue;
|
|
48
42
|
generateWorkspaceArtifacts(manifest: unknown): readonly GeneratedArtifactV1[];
|
|
49
|
-
generateTestArtifacts(input: GenerateTestArtifactsInputV1): readonly GeneratedArtifactV1[];
|
|
50
43
|
};
|
|
51
44
|
|
|
52
45
|
declare function diagnosticCodesForValidationErrors(errors: readonly string[]): readonly string[];
|
|
@@ -54,8 +47,7 @@ declare function diagnosticCodesForValidationErrors(errors: readonly string[]):
|
|
|
54
47
|
declare function validateManifest(manifest: unknown): AuthoringValidationResultV1;
|
|
55
48
|
declare function materializeManifest(manifest: unknown): JsonValue;
|
|
56
49
|
declare function generateWorkspaceArtifacts(manifest: unknown): readonly GeneratedArtifactV1[];
|
|
57
|
-
declare
|
|
58
|
-
declare const GENERATED_WORKSPACE_PATHS: readonly [...string[], "test/generated/base-state.json"];
|
|
50
|
+
declare const GENERATED_WORKSPACE_PATHS: readonly string[];
|
|
59
51
|
type GeneratedWorkspacePathPattern = {
|
|
60
52
|
readonly prefix: string;
|
|
61
53
|
readonly suffix: string;
|
|
@@ -64,4 +56,4 @@ declare const GENERATED_WORKSPACE_PATH_PATTERNS: readonly GeneratedWorkspacePath
|
|
|
64
56
|
declare const MANIFEST_CONFORMANCE_CASES: readonly AuthoringManifestConformanceCaseV1[];
|
|
65
57
|
declare const projectAuthoringAdapter: ProjectAuthoringAdapterV1;
|
|
66
58
|
|
|
67
|
-
export { type AuthoringManifestConformanceCaseV1, type AuthoringValidationResultV1, GENERATED_WORKSPACE_PATHS, GENERATED_WORKSPACE_PATH_PATTERNS, type
|
|
59
|
+
export { type AuthoringManifestConformanceCaseV1, type AuthoringMetadataV1, type AuthoringValidationResultV1, GENERATED_WORKSPACE_PATHS, GENERATED_WORKSPACE_PATH_PATTERNS, type GeneratedArtifactV1, type GeneratedPathPatternV1, MANIFEST_CONFORMANCE_CASES, type ProjectAuthoringAdapterV1, diagnosticCodesForValidationErrors, generateWorkspaceArtifacts, materializeManifest, projectAuthoringAdapter, validateManifest };
|
package/dist/authoring/index.js
CHANGED
|
@@ -1,557 +1,21 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
generateSeedFiles,
|
|
7
|
-
materializeManifestTable,
|
|
8
|
-
validateManifestAuthoring
|
|
9
|
-
} from "../chunk-2TAKLJJD.js";
|
|
10
|
-
import {
|
|
11
|
-
GENERATED_AUTHORING_METADATA
|
|
12
|
-
} from "../chunk-VTNEWMWJ.js";
|
|
13
|
-
import "../chunk-PZ5AY32C.js";
|
|
14
|
-
|
|
15
|
-
// src/authoring/adapter.ts
|
|
16
|
-
import { createHash } from "crypto";
|
|
17
|
-
|
|
18
|
-
// src/authoring/manifest-conformance-cases.ts
|
|
19
|
-
function baseManifest(cardSet, overrides = {}) {
|
|
20
|
-
return {
|
|
21
|
-
players: {
|
|
22
|
-
minPlayers: 2,
|
|
23
|
-
maxPlayers: 2,
|
|
24
|
-
optimalPlayers: 2
|
|
25
|
-
},
|
|
26
|
-
cardSets: [cardSet],
|
|
27
|
-
zones: [],
|
|
28
|
-
boardTemplates: [],
|
|
29
|
-
boards: [],
|
|
30
|
-
pieceTypes: [],
|
|
31
|
-
pieceSeeds: [],
|
|
32
|
-
dieTypes: [],
|
|
33
|
-
dieSeeds: [],
|
|
34
|
-
resources: [],
|
|
35
|
-
setupOptions: [],
|
|
36
|
-
setupProfiles: [],
|
|
37
|
-
...overrides
|
|
38
|
-
};
|
|
39
|
-
}
|
|
40
|
-
function manualCardSet(id, defaultHome, cards) {
|
|
41
|
-
const cardSet = {
|
|
42
|
-
id,
|
|
43
|
-
name: id,
|
|
44
|
-
type: "manual",
|
|
45
|
-
cardSchema: { properties: {} },
|
|
46
|
-
defaultHome,
|
|
47
|
-
cards
|
|
48
|
-
};
|
|
49
|
-
return cardSet;
|
|
50
|
-
}
|
|
51
|
-
var sharedZone = {
|
|
52
|
-
id: "shared-zone",
|
|
53
|
-
name: "Shared Zone",
|
|
54
|
-
scope: "shared",
|
|
55
|
-
allowedCardSetIds: ["cards"]
|
|
56
|
-
};
|
|
57
|
-
var sharedBoard = {
|
|
58
|
-
id: "square-board",
|
|
59
|
-
name: "Square Board",
|
|
60
|
-
layout: "square",
|
|
61
|
-
scope: "shared",
|
|
62
|
-
spaces: [
|
|
63
|
-
{ id: "a1", row: 0, col: 0 },
|
|
64
|
-
{ id: "a2", row: 0, col: 1 },
|
|
65
|
-
{ id: "b1", row: 1, col: 0 },
|
|
66
|
-
{ id: "b2", row: 1, col: 1 }
|
|
67
|
-
],
|
|
68
|
-
relations: [],
|
|
69
|
-
containers: [
|
|
70
|
-
{
|
|
71
|
-
id: "display-row",
|
|
72
|
-
name: "Display Row",
|
|
73
|
-
host: { type: "board" }
|
|
74
|
-
}
|
|
75
|
-
],
|
|
76
|
-
edges: [],
|
|
77
|
-
vertices: []
|
|
78
|
-
};
|
|
79
|
-
var sharedTopology = {
|
|
80
|
-
boards: [sharedBoard],
|
|
81
|
-
pieceTypes: [
|
|
82
|
-
{
|
|
83
|
-
id: "holder",
|
|
84
|
-
name: "Holder",
|
|
85
|
-
slots: [{ id: "pocket" }]
|
|
86
|
-
}
|
|
87
|
-
],
|
|
88
|
-
pieceSeeds: [{ id: "holder-a", typeId: "holder" }]
|
|
89
|
-
};
|
|
90
|
-
var fixtures = [
|
|
91
|
-
{
|
|
92
|
-
id: "manual-default-detached",
|
|
93
|
-
manifest: baseManifest(
|
|
94
|
-
manualCardSet("cards", { type: "detached" }, [
|
|
95
|
-
{ type: "marker", name: "Marker", count: 1, properties: {} }
|
|
96
|
-
])
|
|
97
|
-
),
|
|
98
|
-
expected: {
|
|
99
|
-
valid: true,
|
|
100
|
-
transportValid: true,
|
|
101
|
-
materializedSha256: "ed6f7ce2ff4fbe697e49134f1d59157cf146e202db29a77be50e8326585f535c"
|
|
102
|
-
}
|
|
103
|
-
},
|
|
104
|
-
{
|
|
105
|
-
id: "manual-default-shared-zone",
|
|
106
|
-
manifest: baseManifest(
|
|
107
|
-
manualCardSet("cards", { type: "zone", zoneId: "shared-zone" }, [
|
|
108
|
-
{ type: "coin", name: "Coin", count: 2, properties: {} }
|
|
109
|
-
]),
|
|
110
|
-
{ zones: [sharedZone] }
|
|
111
|
-
),
|
|
112
|
-
expected: {
|
|
113
|
-
valid: true,
|
|
114
|
-
transportValid: true,
|
|
115
|
-
materializedSha256: "75028d28dbc415c81db5e2d780d55b04c4db36378a149bc02b0194d94a8cc2b9"
|
|
116
|
-
}
|
|
117
|
-
},
|
|
118
|
-
{
|
|
119
|
-
id: "preset-default-shared-zone",
|
|
120
|
-
manifest: baseManifest(
|
|
121
|
-
{
|
|
122
|
-
id: "cards",
|
|
123
|
-
name: "Preset Cards",
|
|
124
|
-
type: "preset",
|
|
125
|
-
presetId: "standard_52_deck",
|
|
126
|
-
defaultHome: { type: "zone", zoneId: "shared-zone" }
|
|
127
|
-
},
|
|
128
|
-
{ zones: [sharedZone] }
|
|
129
|
-
),
|
|
130
|
-
expected: {
|
|
131
|
-
valid: true,
|
|
132
|
-
transportValid: true,
|
|
133
|
-
materializedSha256: "b3471c577ed266667b16799f75aa9b7358100a94108aa46a31ad16a0291f67ca"
|
|
134
|
-
}
|
|
135
|
-
},
|
|
136
|
-
{
|
|
137
|
-
id: "manual-per-card-detached-override",
|
|
138
|
-
manifest: baseManifest(
|
|
139
|
-
manualCardSet("cards", { type: "zone", zoneId: "shared-zone" }, [
|
|
140
|
-
{
|
|
141
|
-
type: "removed",
|
|
142
|
-
name: "Removed",
|
|
143
|
-
count: 1,
|
|
144
|
-
home: { type: "detached" },
|
|
145
|
-
properties: {}
|
|
146
|
-
}
|
|
147
|
-
]),
|
|
148
|
-
{ zones: [sharedZone] }
|
|
149
|
-
),
|
|
150
|
-
expected: {
|
|
151
|
-
valid: true,
|
|
152
|
-
transportValid: true,
|
|
153
|
-
materializedSha256: "fdcb2de78fc391e11aca1f266fd8bbb348a82faa0fbbac1d8eb1defd8697a0e9"
|
|
154
|
-
}
|
|
155
|
-
},
|
|
156
|
-
{
|
|
157
|
-
id: "manual-per-card-shared-zone-override",
|
|
158
|
-
manifest: baseManifest(
|
|
159
|
-
manualCardSet("cards", { type: "detached" }, [
|
|
160
|
-
{
|
|
161
|
-
type: "dealt",
|
|
162
|
-
name: "Dealt",
|
|
163
|
-
count: 1,
|
|
164
|
-
home: { type: "zone", zoneId: "shared-zone" },
|
|
165
|
-
properties: {}
|
|
166
|
-
}
|
|
167
|
-
]),
|
|
168
|
-
{ zones: [sharedZone] }
|
|
169
|
-
),
|
|
170
|
-
expected: {
|
|
171
|
-
valid: true,
|
|
172
|
-
transportValid: true,
|
|
173
|
-
materializedSha256: "b6bee1db85f16e8a12a7136c7d524591f925427c8ec04d64b07905c5bc859d7a"
|
|
174
|
-
}
|
|
175
|
-
},
|
|
176
|
-
{
|
|
177
|
-
id: "manual-compatible-zones-no-inference",
|
|
178
|
-
manifest: baseManifest(
|
|
179
|
-
manualCardSet("cards", { type: "detached" }, [
|
|
180
|
-
{ type: "token", name: "Token", count: 1, properties: {} }
|
|
181
|
-
]),
|
|
182
|
-
{
|
|
183
|
-
zones: [
|
|
184
|
-
sharedZone,
|
|
185
|
-
{
|
|
186
|
-
...sharedZone,
|
|
187
|
-
id: "second-compatible-zone",
|
|
188
|
-
name: "Second Compatible Zone"
|
|
189
|
-
}
|
|
190
|
-
]
|
|
191
|
-
}
|
|
192
|
-
),
|
|
193
|
-
expected: {
|
|
194
|
-
valid: true,
|
|
195
|
-
transportValid: true,
|
|
196
|
-
materializedSha256: "2727728ba3743d2b1874b2bc573b48c88f962fdcbdcdf20c62bed551d6d955c4"
|
|
197
|
-
}
|
|
198
|
-
},
|
|
199
|
-
{
|
|
200
|
-
id: "manual-per-player-zone-rejected",
|
|
201
|
-
manifest: baseManifest(
|
|
202
|
-
manualCardSet("cards", { type: "zone", zoneId: "hand" }, [
|
|
203
|
-
{ type: "secret", name: "Secret", count: 1, properties: {} }
|
|
204
|
-
]),
|
|
205
|
-
{
|
|
206
|
-
zones: [
|
|
207
|
-
{
|
|
208
|
-
id: "hand",
|
|
209
|
-
name: "Hand",
|
|
210
|
-
scope: "perPlayer",
|
|
211
|
-
allowedCardSetIds: ["cards"]
|
|
212
|
-
}
|
|
213
|
-
]
|
|
214
|
-
}
|
|
215
|
-
),
|
|
216
|
-
expected: {
|
|
217
|
-
valid: false,
|
|
218
|
-
transportValid: true,
|
|
219
|
-
diagnosticCodes: ["CARD_HOME_PER_PLAYER_ZONE_REJECTED"]
|
|
220
|
-
}
|
|
221
|
-
},
|
|
222
|
-
{
|
|
223
|
-
id: "manual-space-home",
|
|
224
|
-
manifest: baseManifest(
|
|
225
|
-
manualCardSet(
|
|
226
|
-
"cards",
|
|
227
|
-
{ type: "space", boardId: "square-board", spaceId: "a1" },
|
|
228
|
-
[{ type: "space-card", name: "Space", count: 1, properties: {} }]
|
|
229
|
-
),
|
|
230
|
-
sharedTopology
|
|
231
|
-
),
|
|
232
|
-
expected: {
|
|
233
|
-
valid: true,
|
|
234
|
-
transportValid: true,
|
|
235
|
-
materializedSha256: "429abfb3276c67cdca59d3dc077fc73022a9716bccef2c43f6805ff5cce0f2c2"
|
|
236
|
-
}
|
|
237
|
-
},
|
|
238
|
-
{
|
|
239
|
-
id: "manual-container-home",
|
|
240
|
-
manifest: baseManifest(
|
|
241
|
-
manualCardSet(
|
|
242
|
-
"cards",
|
|
243
|
-
{
|
|
244
|
-
type: "container",
|
|
245
|
-
boardId: "square-board",
|
|
246
|
-
containerId: "display-row"
|
|
247
|
-
},
|
|
248
|
-
[
|
|
249
|
-
{
|
|
250
|
-
type: "container-card",
|
|
251
|
-
name: "Container",
|
|
252
|
-
count: 1,
|
|
253
|
-
properties: {}
|
|
254
|
-
}
|
|
255
|
-
]
|
|
256
|
-
),
|
|
257
|
-
sharedTopology
|
|
258
|
-
),
|
|
259
|
-
expected: {
|
|
260
|
-
valid: true,
|
|
261
|
-
transportValid: true,
|
|
262
|
-
materializedSha256: "eff372263227b316d064a519cf282a6cc1d2d8df4ac04673b7f47ac518d7a2a3"
|
|
263
|
-
}
|
|
264
|
-
},
|
|
265
|
-
{
|
|
266
|
-
id: "manual-slot-home",
|
|
267
|
-
manifest: baseManifest(
|
|
268
|
-
manualCardSet(
|
|
269
|
-
"cards",
|
|
270
|
-
{
|
|
271
|
-
type: "slot",
|
|
272
|
-
host: { kind: "piece", id: "holder-a" },
|
|
273
|
-
slotId: "pocket"
|
|
274
|
-
},
|
|
275
|
-
[{ type: "slot-card", name: "Slot", count: 1, properties: {} }]
|
|
276
|
-
),
|
|
277
|
-
sharedTopology
|
|
278
|
-
),
|
|
279
|
-
expected: {
|
|
280
|
-
valid: true,
|
|
281
|
-
transportValid: true,
|
|
282
|
-
materializedSha256: "af3111f8d861ae69b77f2f46ba3df9f2f698f3306c412efc91095544e8121ab6"
|
|
283
|
-
}
|
|
284
|
-
},
|
|
285
|
-
{
|
|
286
|
-
id: "manual-edge-home",
|
|
287
|
-
manifest: baseManifest(
|
|
288
|
-
manualCardSet(
|
|
289
|
-
"cards",
|
|
290
|
-
{
|
|
291
|
-
type: "edge",
|
|
292
|
-
boardId: "square-board",
|
|
293
|
-
ref: { spaces: ["a1", "a2"] }
|
|
294
|
-
},
|
|
295
|
-
[{ type: "edge-card", name: "Edge", count: 1, properties: {} }]
|
|
296
|
-
),
|
|
297
|
-
sharedTopology
|
|
298
|
-
),
|
|
299
|
-
expected: {
|
|
300
|
-
valid: true,
|
|
301
|
-
transportValid: true,
|
|
302
|
-
materializedSha256: "f8606ea25f52d9bf801aa4fee9f558b60d7f39bcd601d57bdfccdf1ddbf4c500"
|
|
303
|
-
}
|
|
304
|
-
},
|
|
305
|
-
{
|
|
306
|
-
id: "manual-vertex-home",
|
|
307
|
-
manifest: baseManifest(
|
|
308
|
-
manualCardSet(
|
|
309
|
-
"cards",
|
|
310
|
-
{
|
|
311
|
-
type: "vertex",
|
|
312
|
-
boardId: "square-board",
|
|
313
|
-
ref: { spaces: ["a1", "a2", "b1", "b2"] }
|
|
314
|
-
},
|
|
315
|
-
[{ type: "vertex-card", name: "Vertex", count: 1, properties: {} }]
|
|
316
|
-
),
|
|
317
|
-
sharedTopology
|
|
318
|
-
),
|
|
319
|
-
expected: {
|
|
320
|
-
valid: true,
|
|
321
|
-
transportValid: true,
|
|
322
|
-
materializedSha256: "e84a4920ea8b71052acd42accf11101380ab982e493ebe207113dd4d243034de"
|
|
323
|
-
}
|
|
324
|
-
},
|
|
325
|
-
{
|
|
326
|
-
id: "manual-invalid-target-id",
|
|
327
|
-
manifest: baseManifest(
|
|
328
|
-
manualCardSet("cards", { type: "zone", zoneId: "missing-zone" }, [
|
|
329
|
-
{ type: "lost", name: "Lost", count: 1, properties: {} }
|
|
330
|
-
])
|
|
331
|
-
),
|
|
332
|
-
expected: {
|
|
333
|
-
valid: false,
|
|
334
|
-
transportValid: true,
|
|
335
|
-
diagnosticCodes: ["AUTHORING_VALIDATION_ERROR"]
|
|
336
|
-
}
|
|
337
|
-
},
|
|
338
|
-
{
|
|
339
|
-
id: "manual-count-order",
|
|
340
|
-
manifest: baseManifest(
|
|
341
|
-
manualCardSet("cards", { type: "zone", zoneId: "shared-zone" }, [
|
|
342
|
-
{ type: "first", name: "First", count: 3, properties: {} },
|
|
343
|
-
{ type: "second", name: "Second", count: 2, properties: {} }
|
|
344
|
-
]),
|
|
345
|
-
{ zones: [sharedZone] }
|
|
346
|
-
),
|
|
347
|
-
expected: {
|
|
348
|
-
valid: true,
|
|
349
|
-
transportValid: true,
|
|
350
|
-
materializedSha256: "2e4ced71909d4c36053317311c9ceaf3bf3adba875bff3fe9596bbea47746423"
|
|
351
|
-
}
|
|
352
|
-
},
|
|
353
|
-
{
|
|
354
|
-
id: "manual-generated-scenario-base",
|
|
355
|
-
manifest: baseManifest(
|
|
356
|
-
manualCardSet("cards", { type: "zone", zoneId: "shared-zone" }, [
|
|
357
|
-
{ type: "alpha", name: "Alpha", count: 2, properties: {} },
|
|
358
|
-
{ type: "beta", name: "Beta", count: 1, properties: {} }
|
|
359
|
-
]),
|
|
360
|
-
{ zones: [sharedZone] }
|
|
361
|
-
),
|
|
362
|
-
expected: {
|
|
363
|
-
valid: true,
|
|
364
|
-
transportValid: true,
|
|
365
|
-
materializedSha256: "b1b65d708b503036a49434c64c6f4aab3bedd295681bd103b69c4b98fdd5e2bb"
|
|
366
|
-
}
|
|
367
|
-
},
|
|
368
|
-
{
|
|
369
|
-
id: "manual-default-required",
|
|
370
|
-
manifest: {
|
|
371
|
-
...baseManifest(
|
|
372
|
-
manualCardSet("cards", { type: "detached" }, [
|
|
373
|
-
{ type: "card", name: "Card", count: 1, properties: {} }
|
|
374
|
-
])
|
|
375
|
-
),
|
|
376
|
-
cardSets: [
|
|
377
|
-
{
|
|
378
|
-
id: "cards",
|
|
379
|
-
name: "Cards",
|
|
380
|
-
type: "manual",
|
|
381
|
-
cardSchema: { properties: {} },
|
|
382
|
-
cards: [{ type: "card", name: "Card", count: 1, properties: {} }]
|
|
383
|
-
}
|
|
384
|
-
]
|
|
385
|
-
},
|
|
386
|
-
expected: {
|
|
387
|
-
valid: false,
|
|
388
|
-
transportValid: false,
|
|
389
|
-
diagnosticCodes: ["MANUAL_CARD_SET_DEFAULT_HOME_REQUIRED"]
|
|
390
|
-
}
|
|
391
|
-
}
|
|
392
|
-
];
|
|
393
|
-
function deepFreeze(value) {
|
|
394
|
-
if (value && typeof value === "object" && !Object.isFrozen(value)) {
|
|
395
|
-
for (const entry of Object.values(value)) {
|
|
396
|
-
deepFreeze(entry);
|
|
397
|
-
}
|
|
398
|
-
Object.freeze(value);
|
|
399
|
-
}
|
|
400
|
-
return value;
|
|
401
|
-
}
|
|
402
|
-
function diagnosticCodesForValidationErrors(errors) {
|
|
403
|
-
return [...new Set(errors.map(diagnosticCodeForValidationError))].sort();
|
|
404
|
-
}
|
|
405
|
-
function diagnosticCodeForValidationError(error) {
|
|
406
|
-
if (error.includes(".defaultHome: Manual card sets must declare defaultHome")) {
|
|
407
|
-
return "MANUAL_CARD_SET_DEFAULT_HOME_REQUIRED";
|
|
408
|
-
}
|
|
409
|
-
if (error.includes("cannot target per-player zone")) {
|
|
410
|
-
return "CARD_HOME_PER_PLAYER_ZONE_REJECTED";
|
|
411
|
-
}
|
|
412
|
-
if (error.includes("cannot target per-player board")) {
|
|
413
|
-
return "CARD_HOME_PER_PLAYER_BOARD_REJECTED";
|
|
414
|
-
}
|
|
415
|
-
return "AUTHORING_VALIDATION_ERROR";
|
|
416
|
-
}
|
|
417
|
-
function createManifestConformanceCases() {
|
|
418
|
-
return deepFreeze(
|
|
419
|
-
fixtures
|
|
420
|
-
);
|
|
421
|
-
}
|
|
422
|
-
|
|
423
|
-
// src/authoring/adapter.ts
|
|
424
|
-
var PLAYER_IDS = ["player-1", "player-2"];
|
|
425
|
-
function stableJson(value) {
|
|
426
|
-
if (value === void 0) {
|
|
427
|
-
return "null";
|
|
428
|
-
}
|
|
429
|
-
if (value === null || typeof value !== "object") {
|
|
430
|
-
return JSON.stringify(value);
|
|
431
|
-
}
|
|
432
|
-
if (Array.isArray(value)) {
|
|
433
|
-
return `[${value.map((item) => stableJson(item)).join(",")}]`;
|
|
434
|
-
}
|
|
435
|
-
return `{${Object.entries(value).filter(([, entry]) => entry !== void 0).sort(([left], [right]) => left.localeCompare(right)).map(([key, entry]) => `${JSON.stringify(key)}:${stableJson(entry)}`).join(",")}}`;
|
|
436
|
-
}
|
|
437
|
-
function sha256(value) {
|
|
438
|
-
return createHash("sha256").update(value).digest("hex");
|
|
439
|
-
}
|
|
440
|
-
function assertManifest(manifest) {
|
|
441
|
-
if (!manifest || typeof manifest !== "object") {
|
|
442
|
-
throw new Error("Expected a manifest object.");
|
|
443
|
-
}
|
|
444
|
-
return manifest;
|
|
445
|
-
}
|
|
446
|
-
function normalizeArtifact(path, content, ownership) {
|
|
447
|
-
if (path.length === 0 || path.startsWith("/") || path.includes("\\") || path.split("/").some((segment) => !segment || segment === "." || segment === "..")) {
|
|
448
|
-
throw new Error(`Generated artifact path '${path}' is not normalized.`);
|
|
449
|
-
}
|
|
450
|
-
return {
|
|
451
|
-
path,
|
|
452
|
-
ownership,
|
|
453
|
-
content,
|
|
454
|
-
contentSha256: sha256(content)
|
|
455
|
-
};
|
|
456
|
-
}
|
|
457
|
-
function normalizeArtifacts(entries, ownership) {
|
|
458
|
-
return Object.entries(entries).map(([path, content]) => normalizeArtifact(path, content, ownership)).sort((left, right) => left.path.localeCompare(right.path));
|
|
459
|
-
}
|
|
460
|
-
function validateNoDuplicateArtifactPaths(artifacts) {
|
|
461
|
-
const seen = /* @__PURE__ */ new Set();
|
|
462
|
-
for (const artifact of artifacts) {
|
|
463
|
-
if (seen.has(artifact.path)) {
|
|
464
|
-
throw new Error(
|
|
465
|
-
`Generated artifact path '${artifact.path}' was emitted twice.`
|
|
466
|
-
);
|
|
467
|
-
}
|
|
468
|
-
seen.add(artifact.path);
|
|
469
|
-
if (artifact.contentSha256 !== sha256(artifact.content)) {
|
|
470
|
-
throw new Error(
|
|
471
|
-
`Generated artifact '${artifact.path}' has a stale hash.`
|
|
472
|
-
);
|
|
473
|
-
}
|
|
474
|
-
}
|
|
475
|
-
}
|
|
476
|
-
function validateManifest(manifest) {
|
|
477
|
-
try {
|
|
478
|
-
const gameManifest = assertManifest(manifest);
|
|
479
|
-
const result = validateManifestAuthoring(gameManifest);
|
|
480
|
-
const errors = [...result.errors];
|
|
481
|
-
if (errors.length === 0) {
|
|
482
|
-
try {
|
|
483
|
-
materializeManifest(gameManifest);
|
|
484
|
-
} catch (error) {
|
|
485
|
-
errors.push(error instanceof Error ? error.message : String(error));
|
|
486
|
-
}
|
|
487
|
-
}
|
|
488
|
-
return {
|
|
489
|
-
valid: errors.length === 0,
|
|
490
|
-
errors,
|
|
491
|
-
warnings: result.warnings
|
|
492
|
-
};
|
|
493
|
-
} catch (error) {
|
|
494
|
-
return {
|
|
495
|
-
valid: false,
|
|
496
|
-
errors: [error instanceof Error ? error.message : String(error)],
|
|
497
|
-
warnings: []
|
|
498
|
-
};
|
|
499
|
-
}
|
|
500
|
-
}
|
|
501
|
-
function materializeManifest(manifest) {
|
|
502
|
-
return materializeManifestTable({
|
|
503
|
-
manifest: assertManifest(manifest),
|
|
504
|
-
playerIds: PLAYER_IDS,
|
|
505
|
-
shuffleItems: (values) => [...values]
|
|
506
|
-
});
|
|
507
|
-
}
|
|
508
|
-
function generateWorkspaceArtifacts(manifest) {
|
|
509
|
-
const gameManifest = assertManifest(manifest);
|
|
510
|
-
const artifacts = [
|
|
511
|
-
...normalizeArtifacts(
|
|
512
|
-
generateAuthoritativeFiles(gameManifest),
|
|
513
|
-
"authoritative"
|
|
514
|
-
),
|
|
515
|
-
...normalizeArtifacts(generateSeedFiles(gameManifest), "seed")
|
|
516
|
-
].sort((left, right) => left.path.localeCompare(right.path));
|
|
517
|
-
validateNoDuplicateArtifactPaths(artifacts);
|
|
518
|
-
return artifacts;
|
|
519
|
-
}
|
|
520
|
-
function generateTestArtifacts(input) {
|
|
521
|
-
const materialized = materializeManifest(input.manifest);
|
|
522
|
-
return [
|
|
523
|
-
normalizeArtifact(
|
|
524
|
-
"test/generated/base-state.json",
|
|
525
|
-
`${stableJson(materialized)}
|
|
526
|
-
`,
|
|
527
|
-
"derived-test"
|
|
528
|
-
)
|
|
529
|
-
];
|
|
530
|
-
}
|
|
531
|
-
var GENERATED_WORKSPACE_PATHS = [
|
|
532
|
-
...AUTHORITATIVE_GENERATED_FILES,
|
|
533
|
-
...SEED_FILES,
|
|
534
|
-
"test/generated/base-state.json"
|
|
535
|
-
];
|
|
536
|
-
var GENERATED_WORKSPACE_PATH_PATTERNS = SEED_FILE_PATTERNS;
|
|
537
|
-
var MANIFEST_CONFORMANCE_CASES = createManifestConformanceCases();
|
|
538
|
-
var projectAuthoringAdapter = {
|
|
539
|
-
protocolVersion: 1,
|
|
540
|
-
metadata: GENERATED_AUTHORING_METADATA,
|
|
541
|
-
generatedPaths: GENERATED_WORKSPACE_PATHS,
|
|
542
|
-
generatedPathPatterns: GENERATED_WORKSPACE_PATH_PATTERNS,
|
|
543
|
-
manifestConformanceCases: MANIFEST_CONFORMANCE_CASES,
|
|
544
|
-
validateManifest,
|
|
545
|
-
materializeManifest,
|
|
2
|
+
GENERATED_WORKSPACE_PATHS,
|
|
3
|
+
GENERATED_WORKSPACE_PATH_PATTERNS,
|
|
4
|
+
MANIFEST_CONFORMANCE_CASES,
|
|
5
|
+
diagnosticCodesForValidationErrors,
|
|
546
6
|
generateWorkspaceArtifacts,
|
|
547
|
-
|
|
548
|
-
|
|
7
|
+
materializeManifest,
|
|
8
|
+
projectAuthoringAdapter,
|
|
9
|
+
validateManifest
|
|
10
|
+
} from "../chunk-KGV2EUNN.js";
|
|
11
|
+
import "../chunk-KWHOFBDM.js";
|
|
12
|
+
import "../chunk-HIH6Y4FA.js";
|
|
13
|
+
import "../chunk-PZ5AY32C.js";
|
|
549
14
|
export {
|
|
550
15
|
GENERATED_WORKSPACE_PATHS,
|
|
551
16
|
GENERATED_WORKSPACE_PATH_PATTERNS,
|
|
552
17
|
MANIFEST_CONFORMANCE_CASES,
|
|
553
18
|
diagnosticCodesForValidationErrors,
|
|
554
|
-
generateTestArtifacts,
|
|
555
19
|
generateWorkspaceArtifacts,
|
|
556
20
|
materializeManifest,
|
|
557
21
|
projectAuthoringAdapter,
|