@forgeax/engine-pack 0.0.0-dev.8d955ade1c79

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 (276) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +429 -0
  3. package/dist/.tsbuildinfo +1 -0
  4. package/dist/__tests__/ai-recovery.unit.test.d.ts +2 -0
  5. package/dist/__tests__/ai-recovery.unit.test.d.ts.map +1 -0
  6. package/dist/__tests__/artifact-path.test.d.ts +2 -0
  7. package/dist/__tests__/artifact-path.test.d.ts.map +1 -0
  8. package/dist/__tests__/asset-evidence-error-hints.test.d.ts +2 -0
  9. package/dist/__tests__/asset-evidence-error-hints.test.d.ts.map +1 -0
  10. package/dist/__tests__/asset-evidence-lifecycle.test.d.ts +2 -0
  11. package/dist/__tests__/asset-evidence-lifecycle.test.d.ts.map +1 -0
  12. package/dist/__tests__/asset-evidence-schema.test.d.ts +2 -0
  13. package/dist/__tests__/asset-evidence-schema.test.d.ts.map +1 -0
  14. package/dist/__tests__/atlas-cli-region-mismatch.test.d.ts +2 -0
  15. package/dist/__tests__/atlas-cli-region-mismatch.test.d.ts.map +1 -0
  16. package/dist/__tests__/atlas-error-code-owner.test-d.d.ts +2 -0
  17. package/dist/__tests__/atlas-error-code-owner.test-d.d.ts.map +1 -0
  18. package/dist/__tests__/cli-asset-evidence.integration.test.d.ts +2 -0
  19. package/dist/__tests__/cli-asset-evidence.integration.test.d.ts.map +1 -0
  20. package/dist/__tests__/cli.unit.test.d.ts +2 -0
  21. package/dist/__tests__/cli.unit.test.d.ts.map +1 -0
  22. package/dist/__tests__/evidence-source-inventory.unit.test.d.ts +2 -0
  23. package/dist/__tests__/evidence-source-inventory.unit.test.d.ts.map +1 -0
  24. package/dist/__tests__/guid-collision.unit.test.d.ts +2 -0
  25. package/dist/__tests__/guid-collision.unit.test.d.ts.map +1 -0
  26. package/dist/__tests__/guid-validator-surface.unit.test.d.ts +2 -0
  27. package/dist/__tests__/guid-validator-surface.unit.test.d.ts.map +1 -0
  28. package/dist/__tests__/load-asset-config.test.d.ts +2 -0
  29. package/dist/__tests__/load-asset-config.test.d.ts.map +1 -0
  30. package/dist/__tests__/material-cook-dependencies.unit.test.d.ts +2 -0
  31. package/dist/__tests__/material-cook-dependencies.unit.test.d.ts.map +1 -0
  32. package/dist/__tests__/material-cook-receipt.unit.test.d.ts +2 -0
  33. package/dist/__tests__/material-cook-receipt.unit.test.d.ts.map +1 -0
  34. package/dist/__tests__/material-cook-schema.unit.test.d.ts +2 -0
  35. package/dist/__tests__/material-cook-schema.unit.test.d.ts.map +1 -0
  36. package/dist/__tests__/mesh-bin-consumer-surface.unit.test.d.ts +2 -0
  37. package/dist/__tests__/mesh-bin-consumer-surface.unit.test.d.ts.map +1 -0
  38. package/dist/__tests__/mesh-bin-contract.unit.test.d.ts +2 -0
  39. package/dist/__tests__/mesh-bin-contract.unit.test.d.ts.map +1 -0
  40. package/dist/__tests__/meta-schema-optional.test.d.ts +2 -0
  41. package/dist/__tests__/meta-schema-optional.test.d.ts.map +1 -0
  42. package/dist/__tests__/meta-source-overrides.unit.test.d.ts +2 -0
  43. package/dist/__tests__/meta-source-overrides.unit.test.d.ts.map +1 -0
  44. package/dist/__tests__/native-cooker-registry.test.d.ts +2 -0
  45. package/dist/__tests__/native-cooker-registry.test.d.ts.map +1 -0
  46. package/dist/__tests__/offline-evidence-artifact-verification-owner.test-d.d.ts +2 -0
  47. package/dist/__tests__/offline-evidence-artifact-verification-owner.test-d.d.ts.map +1 -0
  48. package/dist/__tests__/offline-evidence.integration.test.d.ts +2 -0
  49. package/dist/__tests__/offline-evidence.integration.test.d.ts.map +1 -0
  50. package/dist/__tests__/owner-chain.integration.test.d.ts +2 -0
  51. package/dist/__tests__/owner-chain.integration.test.d.ts.map +1 -0
  52. package/dist/__tests__/pack-v2-fixture-migration.test.d.ts +2 -0
  53. package/dist/__tests__/pack-v2-fixture-migration.test.d.ts.map +1 -0
  54. package/dist/__tests__/pack-v2-schema.test.d.ts +2 -0
  55. package/dist/__tests__/pack-v2-schema.test.d.ts.map +1 -0
  56. package/dist/__tests__/pack.unit.test.d.ts +2 -0
  57. package/dist/__tests__/pack.unit.test.d.ts.map +1 -0
  58. package/dist/__tests__/package-finalizer.contract.test.d.ts +2 -0
  59. package/dist/__tests__/package-finalizer.contract.test.d.ts.map +1 -0
  60. package/dist/__tests__/producer-contract-schema.unit.test.d.ts +2 -0
  61. package/dist/__tests__/producer-contract-schema.unit.test.d.ts.map +1 -0
  62. package/dist/__tests__/resolve-asset-source.test.d.ts +2 -0
  63. package/dist/__tests__/resolve-asset-source.test.d.ts.map +1 -0
  64. package/dist/__tests__/runtime-projection.unit.test.d.ts +2 -0
  65. package/dist/__tests__/runtime-projection.unit.test.d.ts.map +1 -0
  66. package/dist/__tests__/runtime.browser.test.d.ts +2 -0
  67. package/dist/__tests__/runtime.browser.test.d.ts.map +1 -0
  68. package/dist/__tests__/scanner-inventory.contract.test.d.ts +2 -0
  69. package/dist/__tests__/scanner-inventory.contract.test.d.ts.map +1 -0
  70. package/dist/__tests__/scanner-inventory.test.d.ts +2 -0
  71. package/dist/__tests__/scanner-inventory.test.d.ts.map +1 -0
  72. package/dist/__tests__/scanner-mount-cycle.test.d.ts +2 -0
  73. package/dist/__tests__/scanner-mount-cycle.test.d.ts.map +1 -0
  74. package/dist/__tests__/scriptable-pack-cli.integration.test.d.ts +2 -0
  75. package/dist/__tests__/scriptable-pack-cli.integration.test.d.ts.map +1 -0
  76. package/dist/__tests__/scriptable-pack-ddc-key.unit.test.d.ts +2 -0
  77. package/dist/__tests__/scriptable-pack-ddc-key.unit.test.d.ts.map +1 -0
  78. package/dist/__tests__/scriptable-pack.test-d.d.ts +2 -0
  79. package/dist/__tests__/scriptable-pack.test-d.d.ts.map +1 -0
  80. package/dist/__tests__/scriptable-pack.unit.test.d.ts +2 -0
  81. package/dist/__tests__/scriptable-pack.unit.test.d.ts.map +1 -0
  82. package/dist/__tests__/topology-actions.unit.test.d.ts +2 -0
  83. package/dist/__tests__/topology-actions.unit.test.d.ts.map +1 -0
  84. package/dist/__tests__/topology.unit.test.d.ts +2 -0
  85. package/dist/__tests__/topology.unit.test.d.ts.map +1 -0
  86. package/dist/artifact-path.d.ts +9 -0
  87. package/dist/artifact-path.d.ts.map +1 -0
  88. package/dist/artifact-path.mjs +53 -0
  89. package/dist/artifact-path.mjs.map +1 -0
  90. package/dist/atlas/run-atlas.d.ts +8 -0
  91. package/dist/atlas/run-atlas.d.ts.map +1 -0
  92. package/dist/atlas/shelf-pack.d.ts +55 -0
  93. package/dist/atlas/shelf-pack.d.ts.map +1 -0
  94. package/dist/bridge.d.ts +2 -0
  95. package/dist/bridge.d.ts.map +1 -0
  96. package/dist/bridge.mjs +3 -0
  97. package/dist/bridge.mjs.map +1 -0
  98. package/dist/build.d.ts +19 -0
  99. package/dist/build.d.ts.map +1 -0
  100. package/dist/build.mjs +10203 -0
  101. package/dist/build.mjs.map +1 -0
  102. package/dist/builtin.d.ts +44 -0
  103. package/dist/builtin.d.ts.map +1 -0
  104. package/dist/builtin.mjs +141 -0
  105. package/dist/builtin.mjs.map +1 -0
  106. package/dist/catalog-builder.d.ts +43 -0
  107. package/dist/catalog-builder.d.ts.map +1 -0
  108. package/dist/catalog-delta.d.ts +11 -0
  109. package/dist/catalog-delta.d.ts.map +1 -0
  110. package/dist/catalog-projection.d.ts +91 -0
  111. package/dist/catalog-projection.d.ts.map +1 -0
  112. package/dist/cli-asset.d.ts +22 -0
  113. package/dist/cli-asset.d.ts.map +1 -0
  114. package/dist/cli-asset.mjs +9697 -0
  115. package/dist/cli-asset.mjs.map +1 -0
  116. package/dist/config.d.ts +6 -0
  117. package/dist/config.d.ts.map +1 -0
  118. package/dist/config.mjs +29 -0
  119. package/dist/config.mjs.map +1 -0
  120. package/dist/deriveAssetName.d.ts +15 -0
  121. package/dist/deriveAssetName.d.ts.map +1 -0
  122. package/dist/errors.d.ts +30 -0
  123. package/dist/errors.d.ts.map +1 -0
  124. package/dist/errors.mjs +19 -0
  125. package/dist/errors.mjs.map +1 -0
  126. package/dist/evidence/material-cook.d.ts +92 -0
  127. package/dist/evidence/material-cook.d.ts.map +1 -0
  128. package/dist/evidence/offline-evidence.d.ts +25 -0
  129. package/dist/evidence/offline-evidence.d.ts.map +1 -0
  130. package/dist/evidence/source-inventory.d.ts +29 -0
  131. package/dist/evidence/source-inventory.d.ts.map +1 -0
  132. package/dist/guid.d.ts +45 -0
  133. package/dist/guid.d.ts.map +1 -0
  134. package/dist/guid.mjs +94 -0
  135. package/dist/guid.mjs.map +1 -0
  136. package/dist/index.d.ts +15 -0
  137. package/dist/index.d.ts.map +1 -0
  138. package/dist/index.mjs +8612 -0
  139. package/dist/index.mjs.map +1 -0
  140. package/dist/material/artifact-writer.d.ts +14 -0
  141. package/dist/material/artifact-writer.d.ts.map +1 -0
  142. package/dist/material-cook.d.ts +2 -0
  143. package/dist/material-cook.d.ts.map +1 -0
  144. package/dist/material-cook.mjs +248 -0
  145. package/dist/material-cook.mjs.map +1 -0
  146. package/dist/mesh-bin-contract.d.ts +36 -0
  147. package/dist/mesh-bin-contract.d.ts.map +1 -0
  148. package/dist/mesh-bin-contract.mjs +96 -0
  149. package/dist/mesh-bin-contract.mjs.map +1 -0
  150. package/dist/name.mjs +22 -0
  151. package/dist/name.mjs.map +1 -0
  152. package/dist/native-cooker-registry.d.ts +47 -0
  153. package/dist/native-cooker-registry.d.ts.map +1 -0
  154. package/dist/native-cooker.d.ts +3 -0
  155. package/dist/native-cooker.d.ts.map +1 -0
  156. package/dist/native-cooker.mjs +142 -0
  157. package/dist/native-cooker.mjs.map +1 -0
  158. package/dist/package-finalizer.d.ts +121 -0
  159. package/dist/package-finalizer.d.ts.map +1 -0
  160. package/dist/producer-contract.d.ts +19 -0
  161. package/dist/producer-contract.d.ts.map +1 -0
  162. package/dist/resolve-asset-source.d.ts +4 -0
  163. package/dist/resolve-asset-source.d.ts.map +1 -0
  164. package/dist/resolve-asset-source.mjs +109 -0
  165. package/dist/resolve-asset-source.mjs.map +1 -0
  166. package/dist/runtime-projection.d.ts +14 -0
  167. package/dist/runtime-projection.d.ts.map +1 -0
  168. package/dist/runtime-publication.d.ts +44 -0
  169. package/dist/runtime-publication.d.ts.map +1 -0
  170. package/dist/runtime.d.ts +8 -0
  171. package/dist/runtime.d.ts.map +1 -0
  172. package/dist/runtime.mjs +7261 -0
  173. package/dist/runtime.mjs.map +1 -0
  174. package/dist/scanner.d.ts +113 -0
  175. package/dist/scanner.d.ts.map +1 -0
  176. package/dist/scanner.mjs +8819 -0
  177. package/dist/scanner.mjs.map +1 -0
  178. package/dist/schema-compiled.d.ts +12 -0
  179. package/dist/schema-compiled.d.ts.map +1 -0
  180. package/dist/schema.mjs +7369 -0
  181. package/dist/schema.mjs.map +1 -0
  182. package/dist/scriptable-pack-node.d.ts +62 -0
  183. package/dist/scriptable-pack-node.d.ts.map +1 -0
  184. package/dist/scriptable-pack-node.mjs +1674 -0
  185. package/dist/scriptable-pack-node.mjs.map +1 -0
  186. package/dist/scriptable-pack-worker.d.ts +2 -0
  187. package/dist/scriptable-pack-worker.d.ts.map +1 -0
  188. package/dist/scriptable-pack-worker.mjs +224 -0
  189. package/dist/scriptable-pack-worker.mjs.map +1 -0
  190. package/dist/scriptable-pack.d.ts +558 -0
  191. package/dist/scriptable-pack.d.ts.map +1 -0
  192. package/dist/scriptable-pack.mjs +672 -0
  193. package/dist/scriptable-pack.mjs.map +1 -0
  194. package/dist/topology.d.ts +10 -0
  195. package/dist/topology.d.ts.map +1 -0
  196. package/package.json +154 -0
  197. package/schema/meta.schema.json +173 -0
  198. package/schema/pack.schema.json +232 -0
  199. package/src/__tests__/ai-recovery.unit.test.ts +114 -0
  200. package/src/__tests__/artifact-path.test.ts +41 -0
  201. package/src/__tests__/asset-evidence-error-hints.test.ts +46 -0
  202. package/src/__tests__/asset-evidence-lifecycle.test.ts +104 -0
  203. package/src/__tests__/asset-evidence-schema.test.ts +86 -0
  204. package/src/__tests__/atlas-cli-region-mismatch.test.ts +134 -0
  205. package/src/__tests__/atlas-error-code-owner.test-d.ts +23 -0
  206. package/src/__tests__/cli-asset-evidence.integration.test.ts +172 -0
  207. package/src/__tests__/cli.unit.test.ts +448 -0
  208. package/src/__tests__/evidence-source-inventory.unit.test.ts +37 -0
  209. package/src/__tests__/guid-collision.unit.test.ts +112 -0
  210. package/src/__tests__/guid-validator-surface.unit.test.ts +20 -0
  211. package/src/__tests__/load-asset-config.test.ts +121 -0
  212. package/src/__tests__/material-cook-dependencies.unit.test.ts +112 -0
  213. package/src/__tests__/material-cook-receipt.unit.test.ts +148 -0
  214. package/src/__tests__/material-cook-schema.unit.test.ts +152 -0
  215. package/src/__tests__/mesh-bin-consumer-surface.unit.test.ts +22 -0
  216. package/src/__tests__/mesh-bin-contract.unit.test.ts +32 -0
  217. package/src/__tests__/meta-schema-optional.test.ts +116 -0
  218. package/src/__tests__/meta-source-overrides.unit.test.ts +71 -0
  219. package/src/__tests__/native-cooker-registry.test.ts +64 -0
  220. package/src/__tests__/offline-evidence-artifact-verification-owner.test-d.ts +64 -0
  221. package/src/__tests__/offline-evidence.integration.test.ts +106 -0
  222. package/src/__tests__/owner-chain.integration.test.ts +78 -0
  223. package/src/__tests__/pack-v2-fixture-migration.test.ts +87 -0
  224. package/src/__tests__/pack-v2-schema.test.ts +142 -0
  225. package/src/__tests__/pack.unit.test.ts +2218 -0
  226. package/src/__tests__/package-finalizer.contract.test.ts +105 -0
  227. package/src/__tests__/producer-contract-schema.unit.test.ts +92 -0
  228. package/src/__tests__/resolve-asset-source.test.ts +121 -0
  229. package/src/__tests__/runtime-projection.unit.test.ts +87 -0
  230. package/src/__tests__/runtime.browser.test.ts +15 -0
  231. package/src/__tests__/scanner-inventory.contract.test.ts +167 -0
  232. package/src/__tests__/scanner-inventory.test.ts +76 -0
  233. package/src/__tests__/scanner-mount-cycle.test.ts +232 -0
  234. package/src/__tests__/scriptable-pack-cli.integration.test.ts +47 -0
  235. package/src/__tests__/scriptable-pack-ddc-key.unit.test.ts +63 -0
  236. package/src/__tests__/scriptable-pack.test-d.ts +131 -0
  237. package/src/__tests__/scriptable-pack.unit.test.ts +789 -0
  238. package/src/__tests__/topology-actions.unit.test.ts +94 -0
  239. package/src/__tests__/topology.unit.test.ts +85 -0
  240. package/src/artifact-path.ts +69 -0
  241. package/src/atlas/run-atlas.ts +358 -0
  242. package/src/atlas/shelf-pack.ts +172 -0
  243. package/src/atlas/upng-ambient.d.ts +13 -0
  244. package/src/bridge.ts +2 -0
  245. package/src/build.ts +139 -0
  246. package/src/builtin.ts +117 -0
  247. package/src/catalog-builder.ts +313 -0
  248. package/src/catalog-delta.ts +189 -0
  249. package/src/catalog-projection.ts +344 -0
  250. package/src/cli-asset.ts +586 -0
  251. package/src/config.ts +36 -0
  252. package/src/deriveAssetName.ts +42 -0
  253. package/src/errors.ts +47 -0
  254. package/src/evidence/material-cook.ts +411 -0
  255. package/src/evidence/offline-evidence.ts +90 -0
  256. package/src/evidence/source-inventory.ts +193 -0
  257. package/src/guid.ts +99 -0
  258. package/src/index.ts +108 -0
  259. package/src/material/artifact-writer.ts +26 -0
  260. package/src/material-cook.ts +15 -0
  261. package/src/mesh-bin-contract.ts +150 -0
  262. package/src/native-cooker-registry.ts +235 -0
  263. package/src/native-cooker.ts +2 -0
  264. package/src/package-finalizer.ts +394 -0
  265. package/src/producer-contract.ts +277 -0
  266. package/src/resolve-asset-source.ts +88 -0
  267. package/src/runtime-projection.ts +100 -0
  268. package/src/runtime-publication.ts +190 -0
  269. package/src/runtime.ts +23 -0
  270. package/src/scanner.ts +715 -0
  271. package/src/schema/material-cook.schema.json +119 -0
  272. package/src/schema-compiled.ts +238 -0
  273. package/src/scriptable-pack-node.ts +1394 -0
  274. package/src/scriptable-pack-worker.ts +308 -0
  275. package/src/scriptable-pack.ts +1006 -0
  276. package/src/topology.ts +157 -0
@@ -0,0 +1,672 @@
1
+ import { err, ok } from '@forgeax/engine-types';
2
+ import { uuidv7obj } from 'uuidv7';
3
+
4
+ // src/scriptable-pack.ts
5
+
6
+ // src/errors.ts
7
+ var PackError = class extends Error {
8
+ code;
9
+ expected;
10
+ hint;
11
+ detail;
12
+ constructor(args) {
13
+ super(`[PackError ${args.code}] expected: ${args.expected}; hint: ${args.hint}`);
14
+ this.name = "PackError";
15
+ this.code = args.code;
16
+ this.expected = args.expected;
17
+ this.hint = args.hint;
18
+ this.detail = args.detail;
19
+ }
20
+ };
21
+
22
+ // src/guid.ts
23
+ function brand(bytes) {
24
+ return bytes;
25
+ }
26
+ var HEX_BYTE = Array.from({ length: 256 }, (_, i) => i.toString(16).padStart(2, "0"));
27
+ function bytesToDashForm(bytes) {
28
+ const h = HEX_BYTE;
29
+ return `${h[bytes[0]]}${h[bytes[1]]}${h[bytes[2]]}${h[bytes[3]]}-${h[bytes[4]]}${h[bytes[5]]}-${h[bytes[6]]}${h[bytes[7]]}-${h[bytes[8]]}${h[bytes[9]]}-${h[bytes[10]]}${h[bytes[11]]}${h[bytes[12]]}${h[bytes[13]]}${h[bytes[14]]}${h[bytes[15]]}`;
30
+ }
31
+ var UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
32
+ function isValidAssetGuidString(value) {
33
+ return typeof value === "string" && UUID_RE.test(value);
34
+ }
35
+ function dashFormToBytes(dashForm) {
36
+ const hex = dashForm.replace(/-/g, "");
37
+ const bytes = new Uint8Array(16);
38
+ for (let i = 0; i < 16; i++) {
39
+ bytes[i] = parseInt(hex.slice(i * 2, i * 2 + 2), 16);
40
+ }
41
+ return bytes;
42
+ }
43
+ var AssetGuid = {
44
+ /**
45
+ * Parse a 36-char RFC 4122 dash-form UUID string into an AssetGuid.
46
+ * Returns Ok(AssetGuid) on success or Err(PackError) with code 'pack-guid-malformed' on failure.
47
+ * Never throws for expected failures (requirements §4.2 / §14 / charter proposition 4).
48
+ */
49
+ parse(dashForm) {
50
+ if (!isValidAssetGuidString(dashForm)) {
51
+ return {
52
+ ok: false,
53
+ error: new PackError({
54
+ code: "pack-guid-malformed",
55
+ expected: "36-char RFC 4122 dash-form UUID",
56
+ hint: "use AssetGuid.random() or a UUIDv7 generator; all GUID fields must be 36-char RFC 4122 dash-form",
57
+ detail: {
58
+ raw: dashForm,
59
+ reason: "expected 36-char RFC 4122 dash-form UUID"
60
+ }
61
+ })
62
+ };
63
+ }
64
+ return { ok: true, value: brand(dashFormToBytes(dashForm)) };
65
+ },
66
+ /**
67
+ * Format an AssetGuid as a 36-char RFC 4122 lowercase dash-form string.
68
+ */
69
+ format(guid) {
70
+ return bytesToDashForm(guid);
71
+ },
72
+ /**
73
+ * Test byte-by-byte equality between two AssetGuids.
74
+ */
75
+ equals(a, b) {
76
+ for (let i = 0; i < 16; i++) {
77
+ if (a[i] !== b[i]) return false;
78
+ }
79
+ return true;
80
+ },
81
+ /**
82
+ * Mint a new time-ordered UUIDv7 as an AssetGuid.
83
+ * Works in both Node.js and browser environments.
84
+ */
85
+ random() {
86
+ const uuid = uuidv7obj();
87
+ const bytes = new Uint8Array(16);
88
+ bytes.set(uuid.bytes);
89
+ return brand(bytes);
90
+ }
91
+ };
92
+
93
+ // src/scriptable-pack.ts
94
+ var SCRIPTABLE_PACK_ASSET_KINDS = [
95
+ "mesh",
96
+ "material",
97
+ "scene",
98
+ "texture",
99
+ "equirect",
100
+ "sampler",
101
+ "font",
102
+ "render-pipeline",
103
+ "tileset",
104
+ "video",
105
+ "skeleton",
106
+ "skin",
107
+ "animation-clip",
108
+ "animation-graph",
109
+ "audio",
110
+ "particle-effect"
111
+ ];
112
+ var SCRIPTABLE_PACK_CAPABILITY_MANIFEST = {
113
+ assetKinds: SCRIPTABLE_PACK_ASSET_KINDS,
114
+ durablePayload: true,
115
+ refs: true,
116
+ artifacts: true,
117
+ hostCapabilities: ["audio-install", "video-play", "particle-execute"]
118
+ };
119
+ function isScriptablePackAssetKind(value) {
120
+ return SCRIPTABLE_PACK_ASSET_KINDS.includes(value);
121
+ }
122
+ function sceneComponentFieldType(value) {
123
+ if (typeof value === "string") return value;
124
+ if (isRecord(value) && typeof value.type === "string") return value.type;
125
+ return void 0;
126
+ }
127
+ function projectScriptablePackSceneComponents(components) {
128
+ return (components ?? []).map((component) => ({
129
+ name: component.name,
130
+ fields: Object.fromEntries(
131
+ Object.entries(component.fields).map(([fieldName, field]) => [
132
+ fieldName,
133
+ sceneComponentFieldType(field)
134
+ ])
135
+ )
136
+ }));
137
+ }
138
+ function createScriptablePackAuthoringGateway(port, allocateGuid = AssetGuid.random) {
139
+ const requests = /* @__PURE__ */ new Map();
140
+ async function mutationResult(result) {
141
+ if (!result.ok) return result;
142
+ const inspected = await port.inspect(result.value.sourcePath);
143
+ if (!inspected.ok) return inspected;
144
+ return ok({
145
+ sourcePath: result.value.sourcePath,
146
+ revision: inspected.value.revision,
147
+ meta: inspected.value.meta
148
+ });
149
+ }
150
+ async function dispatch(operation) {
151
+ switch (operation.kind) {
152
+ case "preflight": {
153
+ const preflight = await port.preflight(operation.sourcePath);
154
+ return preflight.ok ? ok({ sourcePath: operation.sourcePath, ...preflight.value }) : preflight;
155
+ }
156
+ case "inspect-meta": {
157
+ const inspected = await port.inspect(operation.sourcePath);
158
+ return inspected.ok ? ok({ sourcePath: operation.sourcePath, ...inspected.value }) : inspected;
159
+ }
160
+ case "rebuild":
161
+ case "cold-cook": {
162
+ const preflight = await port.preflight(operation.sourcePath);
163
+ if (!preflight.ok) return preflight;
164
+ if (operation.expectedRevision !== void 0 && operation.expectedRevision !== preflight.value.revision) {
165
+ return err({
166
+ code: "pack-source-revision-conflict",
167
+ expected: operation.expectedRevision,
168
+ actual: preflight.value.revision,
169
+ hint: "inspect the current source revision, then retry the build with a new requestId",
170
+ retryable: true,
171
+ recoveryActions: ["asset.preflight", "mint-request-id"],
172
+ detail: { requestId: operation.requestId, sourcePath: operation.sourcePath }
173
+ });
174
+ }
175
+ const rebuilt = await port.rebuild(operation.sourcePath, operation.kind);
176
+ return rebuilt.ok ? ok({ sourcePath: operation.sourcePath, ...rebuilt.value }) : rebuilt;
177
+ }
178
+ case "create-scriptable-pack":
179
+ return mutationResult(
180
+ await port.mutate({
181
+ ...operation,
182
+ packageId: allocateGuid(),
183
+ initialOutput: { ...operation.initialOutput, guid: allocateGuid() }
184
+ })
185
+ );
186
+ case "add-output":
187
+ return mutationResult(await port.mutate({ ...operation, guid: allocateGuid() }));
188
+ case "clone-scriptable-pack": {
189
+ const inspected = await port.inspect(operation.sourcePath);
190
+ if (!inspected.ok) return inspected;
191
+ const outputGuids = Object.fromEntries(
192
+ inspected.value.meta.subAssets.map((asset) => [asset.sourceKey, allocateGuid()])
193
+ );
194
+ return mutationResult(
195
+ await port.mutate({
196
+ ...operation,
197
+ packageId: allocateGuid(),
198
+ outputGuids
199
+ })
200
+ );
201
+ }
202
+ case "add-external-asset":
203
+ case "rename-display":
204
+ case "remove-output":
205
+ return mutationResult(await port.mutate(operation));
206
+ }
207
+ }
208
+ return {
209
+ execute(operation) {
210
+ if (operation.requestId.trim().length === 0) {
211
+ return Promise.resolve(
212
+ err({
213
+ code: "pack-source-operation-committed",
214
+ expected: "a non-empty caller-minted requestId",
215
+ actual: operation.requestId,
216
+ hint: "mint a new requestId and retry the operation once",
217
+ retryable: true,
218
+ recoveryActions: ["mint-request-id"],
219
+ detail: { requestId: operation.requestId, sourcePath: operation.sourcePath }
220
+ })
221
+ );
222
+ }
223
+ const fingerprint = JSON.stringify(operation);
224
+ const prior = requests.get(operation.requestId);
225
+ if (prior !== void 0) {
226
+ if (prior.fingerprint === fingerprint) return prior.result;
227
+ return Promise.resolve(
228
+ err({
229
+ code: "pack-source-operation-committed",
230
+ expected: "one immutable operation per requestId",
231
+ actual: operation.kind,
232
+ hint: "read the original operation result or mint a new requestId",
233
+ retryable: false,
234
+ recoveryActions: ["read-operation-run", "mint-request-id"],
235
+ detail: { requestId: operation.requestId, sourcePath: operation.sourcePath }
236
+ })
237
+ );
238
+ }
239
+ const result = dispatch(operation);
240
+ requests.set(operation.requestId, { fingerprint, result });
241
+ return result;
242
+ }
243
+ };
244
+ }
245
+ var SCRIPTABLE_PACK_REQUEST_ID_SCHEMA = {
246
+ type: "string",
247
+ minLength: 1,
248
+ maxLength: 128,
249
+ pattern: "^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$",
250
+ description: "Caller-minted identity for one idempotent ScriptablePack operation."
251
+ };
252
+ var SCRIPTABLE_PACK_SOURCE_PATH_SCHEMA = {
253
+ type: "string",
254
+ minLength: 8,
255
+ pattern: "^[^/].*\\.pack\\.ts$",
256
+ description: "Game-root-relative ScriptablePack source path."
257
+ };
258
+ var SCRIPTABLE_PACK_OWNER_GUID_SCHEMA = {
259
+ type: "string",
260
+ format: "uuid",
261
+ description: "Catalog GUID used to resolve the producer-owned source subject."
262
+ };
263
+ var SCRIPTABLE_PACK_REVISION_SCHEMA = {
264
+ type: "string",
265
+ minLength: 64,
266
+ maxLength: 64,
267
+ pattern: "^[a-f0-9]{64}$",
268
+ description: "SHA-256 source revision returned by preflight."
269
+ };
270
+ var SCRIPTABLE_PACK_SOURCE_KEY_SCHEMA = { type: "string", minLength: 1 };
271
+ var SCRIPTABLE_PACK_ASSET_KIND_SCHEMA = {
272
+ enum: SCRIPTABLE_PACK_ASSET_KINDS,
273
+ description: "Ordinary Asset kind supported by the ScriptablePack producer/loader matrix."
274
+ };
275
+ var SCRIPTABLE_PACK_NAME_SCHEMA = { type: "string", minLength: 1 };
276
+ function scriptablePackArgsSchema(properties, required, options = {}) {
277
+ const subjectRequired = ["requestId", ...required];
278
+ return {
279
+ type: "object",
280
+ properties: {
281
+ sourcePath: SCRIPTABLE_PACK_SOURCE_PATH_SCHEMA,
282
+ ownerGuid: SCRIPTABLE_PACK_OWNER_GUID_SCHEMA,
283
+ requestId: SCRIPTABLE_PACK_REQUEST_ID_SCHEMA,
284
+ ...properties
285
+ },
286
+ required: subjectRequired,
287
+ ...options.subject === false ? {} : {
288
+ anyOf: [
289
+ { required: [...subjectRequired, "sourcePath"] },
290
+ { required: [...subjectRequired, "ownerGuid"] },
291
+ ...options.guidSubject === false ? [] : [{ required: [...subjectRequired, "guid"] }]
292
+ ]
293
+ },
294
+ additionalProperties: false
295
+ };
296
+ }
297
+ var SOURCE_AUTHORING_OPERATION_DESCRIPTORS = [
298
+ {
299
+ id: "asset-source.create",
300
+ kind: "create",
301
+ domain: "session",
302
+ title: "Create Asset Source",
303
+ argsSchema: scriptablePackArgsSchema(
304
+ {
305
+ name: SCRIPTABLE_PACK_NAME_SCHEMA,
306
+ initialOutput: {
307
+ type: "object",
308
+ properties: {
309
+ sourceKey: SCRIPTABLE_PACK_SOURCE_KEY_SCHEMA,
310
+ kind: SCRIPTABLE_PACK_ASSET_KIND_SCHEMA,
311
+ name: SCRIPTABLE_PACK_NAME_SCHEMA
312
+ },
313
+ required: ["sourceKey", "kind"],
314
+ additionalProperties: false
315
+ }
316
+ },
317
+ ["sourcePath", "initialOutput"],
318
+ { subject: false }
319
+ )
320
+ },
321
+ {
322
+ id: "asset-source.add-output",
323
+ kind: "add-output",
324
+ domain: "session",
325
+ title: "Add Asset Source Output",
326
+ argsSchema: scriptablePackArgsSchema(
327
+ {
328
+ sourceKey: SCRIPTABLE_PACK_SOURCE_KEY_SCHEMA,
329
+ assetKind: SCRIPTABLE_PACK_ASSET_KIND_SCHEMA,
330
+ name: SCRIPTABLE_PACK_NAME_SCHEMA,
331
+ expectedRevision: SCRIPTABLE_PACK_REVISION_SCHEMA
332
+ },
333
+ ["sourceKey", "assetKind", "expectedRevision"]
334
+ )
335
+ },
336
+ {
337
+ id: "asset-source.add-external-asset",
338
+ kind: "add-external-asset",
339
+ domain: "session",
340
+ title: "Add Asset Source External Asset",
341
+ argsSchema: scriptablePackArgsSchema(
342
+ {
343
+ alias: SCRIPTABLE_PACK_SOURCE_KEY_SCHEMA,
344
+ guid: { type: "string", format: "uuid" },
345
+ expectedRevision: SCRIPTABLE_PACK_REVISION_SCHEMA
346
+ },
347
+ ["alias", "guid", "expectedRevision"],
348
+ { guidSubject: false }
349
+ )
350
+ },
351
+ {
352
+ id: "asset-source.rename",
353
+ kind: "rename",
354
+ domain: "session",
355
+ title: "Rename Asset Source Display Name",
356
+ argsSchema: scriptablePackArgsSchema(
357
+ {
358
+ target: {
359
+ oneOf: [
360
+ {
361
+ type: "object",
362
+ properties: { kind: { const: "package" } },
363
+ required: ["kind"],
364
+ additionalProperties: false
365
+ },
366
+ {
367
+ type: "object",
368
+ properties: {
369
+ kind: { const: "output" },
370
+ sourceKey: SCRIPTABLE_PACK_SOURCE_KEY_SCHEMA
371
+ },
372
+ required: ["kind", "sourceKey"],
373
+ additionalProperties: false
374
+ }
375
+ ]
376
+ },
377
+ name: SCRIPTABLE_PACK_NAME_SCHEMA,
378
+ expectedRevision: SCRIPTABLE_PACK_REVISION_SCHEMA
379
+ },
380
+ ["target", "name", "expectedRevision"]
381
+ )
382
+ },
383
+ {
384
+ id: "asset-source.remove-output",
385
+ kind: "remove-output",
386
+ domain: "session",
387
+ title: "Remove Asset Source Output",
388
+ destructive: true,
389
+ argsSchema: scriptablePackArgsSchema(
390
+ {
391
+ sourceKey: SCRIPTABLE_PACK_SOURCE_KEY_SCHEMA,
392
+ confirmIncomingRefs: { type: "array", items: { type: "string" } },
393
+ expectedRevision: SCRIPTABLE_PACK_REVISION_SCHEMA
394
+ },
395
+ ["sourceKey", "expectedRevision"]
396
+ )
397
+ },
398
+ {
399
+ id: "asset-source.clone",
400
+ kind: "clone",
401
+ domain: "session",
402
+ title: "Clone Asset Source",
403
+ argsSchema: scriptablePackArgsSchema(
404
+ {
405
+ targetPath: SCRIPTABLE_PACK_SOURCE_PATH_SCHEMA,
406
+ expectedRevision: SCRIPTABLE_PACK_REVISION_SCHEMA
407
+ },
408
+ ["targetPath", "expectedRevision"]
409
+ )
410
+ },
411
+ {
412
+ id: "asset-source.rebuild",
413
+ kind: "rebuild",
414
+ domain: "session",
415
+ title: "Rebuild Asset Source",
416
+ argsSchema: scriptablePackArgsSchema({ expectedRevision: SCRIPTABLE_PACK_REVISION_SCHEMA }, [
417
+ "expectedRevision"
418
+ ])
419
+ },
420
+ {
421
+ id: "asset-source.cold-cook",
422
+ kind: "cold-cook",
423
+ domain: "session",
424
+ title: "Cold Cook Asset Source",
425
+ argsSchema: scriptablePackArgsSchema({ expectedRevision: SCRIPTABLE_PACK_REVISION_SCHEMA }, [
426
+ "expectedRevision"
427
+ ])
428
+ }
429
+ ];
430
+ function actual(value) {
431
+ if (value === null) return "null";
432
+ if (Array.isArray(value)) return "array";
433
+ if (ArrayBuffer.isView(value)) return value.constructor.name;
434
+ return typeof value;
435
+ }
436
+ function invalid(propertyPath, expected, value, sourcePath) {
437
+ return err({
438
+ code: "pack-source-definition-invalid",
439
+ expected,
440
+ hint: "repair the default exported ScriptablePack definition, then inspect Meta again",
441
+ detail: {
442
+ ...sourcePath === void 0 ? {} : { sourcePath },
443
+ propertyPath,
444
+ actual: actual(value)
445
+ }
446
+ });
447
+ }
448
+ function isRecord(value) {
449
+ return value !== null && typeof value === "object" && !Array.isArray(value);
450
+ }
451
+ function isAssetGuid(value) {
452
+ return value instanceof Uint8Array && value.byteLength === 16;
453
+ }
454
+ function guidKey(guid) {
455
+ return AssetGuid.format(guid);
456
+ }
457
+ function freezeDefinition(definition) {
458
+ const assets = Object.fromEntries(
459
+ Object.entries(definition.assets).map(([sourceKey, descriptor]) => [
460
+ sourceKey,
461
+ Object.freeze({ ...descriptor, guid: descriptor.guid.slice() })
462
+ ])
463
+ );
464
+ const externalAssets = Object.fromEntries(
465
+ Object.entries(definition.externalAssets).map(([alias, guid]) => [
466
+ alias,
467
+ guid.slice()
468
+ ])
469
+ );
470
+ const sceneComponents = definition.sceneComponents === void 0 ? void 0 : Object.freeze(
471
+ projectScriptablePackSceneComponents(definition.sceneComponents).map(
472
+ (component) => Object.freeze({
473
+ ...component,
474
+ fields: Object.freeze({ ...component.fields })
475
+ })
476
+ )
477
+ );
478
+ return Object.freeze({
479
+ ...definition,
480
+ packageId: definition.packageId.slice(),
481
+ assets: Object.freeze(assets),
482
+ externalAssets: Object.freeze(externalAssets),
483
+ ...sceneComponents === void 0 ? {} : { sceneComponents }
484
+ });
485
+ }
486
+ function validateScriptablePackDefinition(value, sourcePath) {
487
+ if (!isRecord(value))
488
+ return invalid("$", "a ScriptablePack definition object", value, sourcePath);
489
+ if (value.schemaVersion !== "1.0.0") {
490
+ return invalid("$.schemaVersion", "the literal '1.0.0'", value.schemaVersion, sourcePath);
491
+ }
492
+ if (!isAssetGuid(value.packageId)) {
493
+ return invalid("$.packageId", "a 16-byte AssetGuid", value.packageId, sourcePath);
494
+ }
495
+ if (value.name !== void 0 && typeof value.name !== "string") {
496
+ return invalid("$.name", "a string when present", value.name, sourcePath);
497
+ }
498
+ if (!isRecord(value.assets) || Object.keys(value.assets).length === 0) {
499
+ return invalid(
500
+ "$.assets",
501
+ "a non-empty sourceKey to descriptor object",
502
+ value.assets,
503
+ sourcePath
504
+ );
505
+ }
506
+ if (!isRecord(value.externalAssets)) {
507
+ return invalid(
508
+ "$.externalAssets",
509
+ "an alias to AssetGuid object",
510
+ value.externalAssets,
511
+ sourcePath
512
+ );
513
+ }
514
+ if (value.sceneComponents !== void 0) {
515
+ if (!Array.isArray(value.sceneComponents)) {
516
+ return invalid(
517
+ "$.sceneComponents",
518
+ "an array of component tokens or neutral schema rows when present",
519
+ value.sceneComponents,
520
+ sourcePath
521
+ );
522
+ }
523
+ const componentNames = /* @__PURE__ */ new Set();
524
+ for (const [componentIndex, component] of value.sceneComponents.entries()) {
525
+ if (!isRecord(component)) {
526
+ return invalid(
527
+ `$.sceneComponents[${componentIndex}]`,
528
+ "a component token or neutral schema row",
529
+ component,
530
+ sourcePath
531
+ );
532
+ }
533
+ if (typeof component.name !== "string" || component.name.trim().length === 0) {
534
+ return invalid(
535
+ `$.sceneComponents[${componentIndex}].name`,
536
+ "a non-empty component name",
537
+ component.name,
538
+ sourcePath
539
+ );
540
+ }
541
+ if (componentNames.has(component.name)) {
542
+ return invalid(
543
+ `$.sceneComponents[${componentIndex}].name`,
544
+ "component names to be unique within one ScriptablePack",
545
+ component.name,
546
+ sourcePath
547
+ );
548
+ }
549
+ componentNames.add(component.name);
550
+ if (!isRecord(component.fields)) {
551
+ return invalid(
552
+ `$.sceneComponents[${componentIndex}].fields`,
553
+ "a field-name to schema-type object",
554
+ component.fields,
555
+ sourcePath
556
+ );
557
+ }
558
+ for (const [fieldName, field] of Object.entries(component.fields)) {
559
+ const type = sceneComponentFieldType(field);
560
+ if (fieldName.trim().length === 0 || type === void 0 || type.trim().length === 0) {
561
+ return invalid(
562
+ `$.sceneComponents[${componentIndex}].fields`,
563
+ "field names with non-empty string schema types",
564
+ field,
565
+ sourcePath
566
+ );
567
+ }
568
+ }
569
+ }
570
+ }
571
+ if (typeof value.build !== "function") {
572
+ return invalid("$.build", "a build(assetReader) function", value.build, sourcePath);
573
+ }
574
+ const packageGuid = guidKey(value.packageId);
575
+ const localGuids = /* @__PURE__ */ new Set();
576
+ for (const [sourceKey, descriptor] of Object.entries(value.assets)) {
577
+ if (sourceKey.trim().length === 0) {
578
+ return invalid("$.assets", "non-empty sourceKey object keys", sourceKey, sourcePath);
579
+ }
580
+ if (!isRecord(descriptor)) {
581
+ return invalid(
582
+ `$.assets[${JSON.stringify(sourceKey)}]`,
583
+ "an asset descriptor",
584
+ descriptor,
585
+ sourcePath
586
+ );
587
+ }
588
+ if (!isAssetGuid(descriptor.guid)) {
589
+ return invalid(
590
+ `$.assets[${JSON.stringify(sourceKey)}].guid`,
591
+ "a 16-byte AssetGuid",
592
+ descriptor.guid,
593
+ sourcePath
594
+ );
595
+ }
596
+ if (typeof descriptor.kind !== "string" || !isScriptablePackAssetKind(descriptor.kind)) {
597
+ return invalid(
598
+ `$.assets[${JSON.stringify(sourceKey)}].kind`,
599
+ "one of SCRIPTABLE_PACK_ASSET_KINDS",
600
+ descriptor.kind,
601
+ sourcePath
602
+ );
603
+ }
604
+ if (descriptor.name !== void 0 && typeof descriptor.name !== "string") {
605
+ return invalid(
606
+ `$.assets[${JSON.stringify(sourceKey)}].name`,
607
+ "a string when present",
608
+ descriptor.name,
609
+ sourcePath
610
+ );
611
+ }
612
+ const guid = guidKey(descriptor.guid);
613
+ if (guid === packageGuid || localGuids.has(guid)) {
614
+ return invalid(
615
+ `$.assets[${JSON.stringify(sourceKey)}].guid`,
616
+ "a GUID unique within the package and distinct from packageId",
617
+ descriptor.guid,
618
+ sourcePath
619
+ );
620
+ }
621
+ localGuids.add(guid);
622
+ }
623
+ const externalGuids = /* @__PURE__ */ new Set();
624
+ for (const [alias, guidValue] of Object.entries(value.externalAssets)) {
625
+ if (alias.trim().length === 0) {
626
+ return invalid("$.externalAssets", "non-empty alias object keys", alias, sourcePath);
627
+ }
628
+ if (!isAssetGuid(guidValue)) {
629
+ return invalid(
630
+ `$.externalAssets[${JSON.stringify(alias)}]`,
631
+ "a 16-byte AssetGuid",
632
+ guidValue,
633
+ sourcePath
634
+ );
635
+ }
636
+ const guid = guidKey(guidValue);
637
+ if (guid === packageGuid || localGuids.has(guid) || externalGuids.has(guid)) {
638
+ return invalid(
639
+ `$.externalAssets[${JSON.stringify(alias)}]`,
640
+ "a unique foreign GUID not owned by this package",
641
+ guidValue,
642
+ sourcePath
643
+ );
644
+ }
645
+ externalGuids.add(guid);
646
+ }
647
+ return ok(freezeDefinition(value));
648
+ }
649
+ function projectScriptablePackMeta(definition, source) {
650
+ const subAssets = Object.entries(definition.assets).sort(([left], [right]) => left.localeCompare(right)).map(([sourceKey, descriptor], sourceIndex) => ({
651
+ guid: guidKey(descriptor.guid),
652
+ sourceIndex,
653
+ sourceKey,
654
+ kind: descriptor.kind,
655
+ ...descriptor.name === void 0 ? {} : { name: descriptor.name }
656
+ }));
657
+ const externalAssets = Object.entries(definition.externalAssets).sort(([left], [right]) => left.localeCompare(right)).map(([alias, guid]) => ({ alias, guid: guidKey(guid) }));
658
+ return {
659
+ schemaVersion: "1.0.0",
660
+ kind: "external-asset-package",
661
+ packageId: guidKey(definition.packageId),
662
+ ...definition.name === void 0 ? {} : { name: definition.name },
663
+ importer: "pack-ts",
664
+ source,
665
+ importSettings: { contractVersion: "1.0.0", externalAssets },
666
+ subAssets
667
+ };
668
+ }
669
+
670
+ export { SCRIPTABLE_PACK_ASSET_KINDS, SCRIPTABLE_PACK_CAPABILITY_MANIFEST, SOURCE_AUTHORING_OPERATION_DESCRIPTORS, createScriptablePackAuthoringGateway, isRecord, isScriptablePackAssetKind, projectScriptablePackMeta, projectScriptablePackSceneComponents, validateScriptablePackDefinition };
671
+ //# sourceMappingURL=scriptable-pack.mjs.map
672
+ //# sourceMappingURL=scriptable-pack.mjs.map