@forgeax/engine-pack 0.1.21 → 0.1.24

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 (139) hide show
  1. package/README.md +167 -48
  2. package/dist/__tests__/inventory-schema.test.d.ts +2 -0
  3. package/dist/__tests__/inventory-schema.test.d.ts.map +1 -0
  4. package/dist/__tests__/material-cook-receipt-layer-plan.unit.test.d.ts +2 -0
  5. package/dist/__tests__/material-cook-receipt-layer-plan.unit.test.d.ts.map +1 -0
  6. package/dist/__tests__/pack-authoring-gateway.unit.test.d.ts +2 -0
  7. package/dist/__tests__/pack-authoring-gateway.unit.test.d.ts.map +1 -0
  8. package/dist/__tests__/pack-authoring.unit.test.d.ts +2 -0
  9. package/dist/__tests__/pack-authoring.unit.test.d.ts.map +1 -0
  10. package/dist/__tests__/pack-scanner.unit.test.d.ts +2 -0
  11. package/dist/__tests__/pack-scanner.unit.test.d.ts.map +1 -0
  12. package/dist/__tests__/scanner-blacklist.test.d.ts +2 -0
  13. package/dist/__tests__/scanner-blacklist.test.d.ts.map +1 -0
  14. package/dist/build.d.ts +9 -4
  15. package/dist/build.d.ts.map +1 -1
  16. package/dist/build.mjs +3449 -897
  17. package/dist/build.mjs.map +1 -1
  18. package/dist/builtin.mjs +37 -4
  19. package/dist/builtin.mjs.map +1 -1
  20. package/dist/catalog-builder.d.ts.map +1 -1
  21. package/dist/cli-asset.d.ts.map +1 -1
  22. package/dist/cli-asset.mjs +1361 -845
  23. package/dist/cli-asset.mjs.map +1 -1
  24. package/dist/deriveAssetName.d.ts +11 -7
  25. package/dist/deriveAssetName.d.ts.map +1 -1
  26. package/dist/evidence/material-cook.d.ts +11 -0
  27. package/dist/evidence/material-cook.d.ts.map +1 -1
  28. package/dist/evidence/source-inventory.d.ts.map +1 -1
  29. package/dist/guid.d.ts +15 -0
  30. package/dist/guid.d.ts.map +1 -1
  31. package/dist/guid.mjs +53 -5
  32. package/dist/guid.mjs.map +1 -1
  33. package/dist/index.d.ts +4 -2
  34. package/dist/index.d.ts.map +1 -1
  35. package/dist/index.mjs +1297 -562
  36. package/dist/index.mjs.map +1 -1
  37. package/dist/inventory/binding.d.ts +6 -0
  38. package/dist/inventory/binding.d.ts.map +1 -0
  39. package/dist/inventory/declaration.d.ts +24 -0
  40. package/dist/inventory/declaration.d.ts.map +1 -0
  41. package/dist/inventory/index.d.ts +3 -0
  42. package/dist/inventory/index.d.ts.map +1 -0
  43. package/dist/inventory/sync.d.ts +5 -0
  44. package/dist/inventory/sync.d.ts.map +1 -0
  45. package/dist/material-cook.d.ts +1 -1
  46. package/dist/material-cook.d.ts.map +1 -1
  47. package/dist/material-cook.mjs +50 -3
  48. package/dist/material-cook.mjs.map +1 -1
  49. package/dist/name.mjs +4 -7
  50. package/dist/name.mjs.map +1 -1
  51. package/dist/pack-authoring-node.d.ts +26 -0
  52. package/dist/pack-authoring-node.d.ts.map +1 -0
  53. package/dist/pack-authoring-node.mjs +11089 -0
  54. package/dist/pack-authoring-node.mjs.map +1 -0
  55. package/dist/pack-authoring.d.ts +230 -0
  56. package/dist/pack-authoring.d.ts.map +1 -0
  57. package/dist/pack-authoring.mjs +1137 -0
  58. package/dist/pack-authoring.mjs.map +1 -0
  59. package/dist/package-finalizer.d.ts +2 -20
  60. package/dist/package-finalizer.d.ts.map +1 -1
  61. package/dist/resolve-asset-source.d.ts +1 -3
  62. package/dist/resolve-asset-source.d.ts.map +1 -1
  63. package/dist/resolve-asset-source.mjs +6 -81
  64. package/dist/resolve-asset-source.mjs.map +1 -1
  65. package/dist/runtime.mjs +77 -7
  66. package/dist/runtime.mjs.map +1 -1
  67. package/dist/scanner.d.ts +18 -7
  68. package/dist/scanner.d.ts.map +1 -1
  69. package/dist/scanner.mjs +1164 -687
  70. package/dist/scanner.mjs.map +1 -1
  71. package/dist/schema-compiled.d.ts.map +1 -1
  72. package/dist/schema.mjs +79 -7
  73. package/dist/schema.mjs.map +1 -1
  74. package/dist/scriptable-pack-node.d.ts +7 -31
  75. package/dist/scriptable-pack-node.d.ts.map +1 -1
  76. package/dist/scriptable-pack-node.mjs +572 -1019
  77. package/dist/scriptable-pack-node.mjs.map +1 -1
  78. package/dist/scriptable-pack-worker.mjs +29 -11
  79. package/dist/scriptable-pack-worker.mjs.map +1 -1
  80. package/dist/scriptable-pack.d.ts +20 -532
  81. package/dist/scriptable-pack.d.ts.map +1 -1
  82. package/dist/scriptable-pack.mjs +1038 -527
  83. package/dist/scriptable-pack.mjs.map +1 -1
  84. package/package.json +2 -7
  85. package/schema/meta.schema.json +1 -1
  86. package/schema/pack.schema.json +76 -6
  87. package/src/__tests__/guid-collision.unit.test.ts +18 -9
  88. package/src/__tests__/inventory-schema.test.ts +109 -0
  89. package/src/__tests__/material-cook-receipt-layer-plan.unit.test.ts +16 -0
  90. package/src/__tests__/material-cook-schema.unit.test.ts +62 -0
  91. package/src/__tests__/pack-authoring-gateway.unit.test.ts +249 -0
  92. package/src/__tests__/pack-authoring.unit.test.ts +266 -0
  93. package/src/__tests__/pack-scanner.unit.test.ts +123 -0
  94. package/src/__tests__/pack.unit.test.ts +1 -238
  95. package/src/__tests__/package-finalizer.contract.test.ts +55 -0
  96. package/src/__tests__/resolve-asset-source.test.ts +15 -98
  97. package/src/__tests__/scanner-blacklist.test.ts +55 -0
  98. package/src/__tests__/scanner-inventory.contract.test.ts +11 -14
  99. package/src/__tests__/scanner-inventory.test.ts +23 -10
  100. package/src/__tests__/scriptable-pack-cli.integration.test.ts +4 -9
  101. package/src/__tests__/topology.unit.test.ts +23 -0
  102. package/src/build.ts +28 -18
  103. package/src/catalog-builder.ts +60 -33
  104. package/src/cli-asset.ts +68 -83
  105. package/src/deriveAssetName.ts +14 -13
  106. package/src/evidence/material-cook.ts +79 -3
  107. package/src/evidence/source-inventory.ts +34 -21
  108. package/src/guid.ts +65 -4
  109. package/src/index.ts +15 -11
  110. package/src/inventory/binding.ts +25 -0
  111. package/src/inventory/declaration.ts +168 -0
  112. package/src/inventory/index.ts +18 -0
  113. package/src/inventory/sync.ts +22 -0
  114. package/src/material-cook.ts +1 -0
  115. package/src/pack-authoring-node.ts +1966 -0
  116. package/src/pack-authoring.ts +1478 -0
  117. package/src/package-finalizer.ts +2 -42
  118. package/src/resolve-asset-source.ts +4 -76
  119. package/src/scanner.ts +236 -56
  120. package/src/schema/material-cook.schema.json +4 -1
  121. package/src/schema-compiled.ts +2 -0
  122. package/src/scriptable-pack-node.ts +108 -719
  123. package/src/scriptable-pack-worker.ts +48 -16
  124. package/src/scriptable-pack.ts +28 -939
  125. package/dist/.tsbuildinfo +0 -1
  126. package/dist/__tests__/load-asset-config.test.d.ts +0 -2
  127. package/dist/__tests__/load-asset-config.test.d.ts.map +0 -1
  128. package/dist/__tests__/scriptable-pack.test-d.d.ts +0 -2
  129. package/dist/__tests__/scriptable-pack.test-d.d.ts.map +0 -1
  130. package/dist/__tests__/scriptable-pack.unit.test.d.ts +0 -2
  131. package/dist/__tests__/scriptable-pack.unit.test.d.ts.map +0 -1
  132. package/dist/config.d.ts +0 -6
  133. package/dist/config.d.ts.map +0 -1
  134. package/dist/config.mjs +0 -29
  135. package/dist/config.mjs.map +0 -1
  136. package/src/__tests__/load-asset-config.test.ts +0 -121
  137. package/src/__tests__/scriptable-pack.test-d.ts +0 -131
  138. package/src/__tests__/scriptable-pack.unit.test.ts +0 -789
  139. package/src/config.ts +0 -36
package/README.md CHANGED
@@ -14,6 +14,78 @@ recook 并重新验证,不手改 cooked payload。
14
14
 
15
15
  ## Authoring and recovery index
16
16
 
17
+ ## ScriptablePack 与 Pack authoring
18
+
19
+ > [!IMPORTANT]
20
+ > 这里有两个一等 source 实体,且必须保持可见区别:`ScriptablePack` 是可执行的
21
+ > `*.pack.ts` TypeScript source;`Pack` 是可编辑、可持久化的 `*.pack.json` JSON
22
+ > source。参数化只是 ScriptablePack/Pack instance 的可选能力,不是第三种实体。
23
+ > 构建后的 Pack v2 是 transport 产物;runtime 只按 GUID 加载产物。
24
+
25
+ The current authoring contract keeps one Pack identity and derives every output
26
+ identity from the author-owned pair `(packageId, sourceKey)`:
27
+
28
+ ```ts
29
+ import { AssetGuid, definePack, definePackageId } from '@forgeax/engine/pack/source';
30
+ import { ok } from '@forgeax/engine/types';
31
+
32
+ const packageId = definePackageId('01900000-0000-7000-8000-000000000001');
33
+
34
+ export default definePack({
35
+ schemaVersion: '2.0.0',
36
+ packageId,
37
+ build: ({ packageId: subjectId }) =>
38
+ ok({
39
+ 'mesh/main': { kind: 'mesh', materialSlots: [] },
40
+ 'scene/main': {
41
+ kind: 'scene',
42
+ entities: [],
43
+ mounts: [],
44
+ mesh: AssetGuid.format(AssetGuid.derive(subjectId, 'mesh/main')),
45
+ },
46
+ }),
47
+ });
48
+ ```
49
+
50
+ `definePack` omits `parameters` for the default zero-parameter path; its build
51
+ context then has `packageId` and `readByGuid()` only. A non-empty `parameters`
52
+ array opts into typed `values`, defaults, numeric bounds, enum choices, vectors,
53
+ colors, and asset-GUID kind constraints. The build return object is the whole
54
+ current output topology: there is no output manifest, `output.add()`,
55
+ `externalAssets`, or per-output GUID field.
56
+
57
+ `Pack` authoring (`*.pack.json`) uses schema `3.0.0`. A direct document stores
58
+ `assets[sourceKey]`; an instance stores only its own `packageId`, `parent`, and
59
+ sparse `values`. These branches are mutually exclusive. Every instance has an
60
+ independent package identity, while the parent chain is resolved through the
61
+ current Source Index. The authoring form is lowered to the ordinary Pack v2
62
+ transport before runtime; player code still calls `loadByGuid()` and never
63
+ executes TypeScript or understands parameters.
64
+
65
+ `@forgeax/engine-pack/build` exposes the filesystem gateway
66
+ `createFileSystemPackAuthoringGateway()`. Its read operations are
67
+ `asset.list`, `asset.inspect`, `asset.resolve`, and `asset.verify`; mutations
68
+ are `asset-source.create`, `asset-source.clone`,
69
+ `asset-source.create-instance`, `asset-source.apply-values`,
70
+ `asset-source.rebuild`, and `asset-source.cold-cook`. Every operation carries a
71
+ caller-minted `requestId`; source mutations are confined to the game root,
72
+ atomic, and CAS-protected by `expectedRevision`.
73
+
74
+ `AssetGuid.derive(packageId, sourceKey)` is the browser-safe UUIDv5 projection.
75
+ `PackageId` and `AssetGuid` are distinct brands, and a derived identity alone
76
+ reports only `identity`; `present` and `ready` require current materialization
77
+ and validated Pack/artifact evidence respectively.
78
+
79
+ ## 灯光 Pack/Catalog 入口
80
+
81
+ 三条最短入口:
82
+
83
+ 1. scene Pack 只保存 `RectAreaLight`、`SpotLight`、`LightProbe` 的 authored 字段,并把 `iesProfile`/`cookie` 写入 `refs`。
84
+ 2. `IesProfileAsset` 由 `iesImporter` 在 build-time 生成 fixed cooked payload;`SpotLight.cookie` 仍是普通 `TextureAsset`。
85
+ 3. runtime 按 GUID 读取 Catalog/Pack 记录;`current`、`accepted`、`lastKnownGood`、`verified` 分层检查,缺失时回到 producer 重建。
86
+
87
+ Pack 是 published 边界,不是 author authority、runtime registry 或 GPU owner。源文件与 Meta 保留 authored identity,DDC/Catalog 是可丢弃或可重建的 projection;`sourceKey` 只表达 producer 语义,不是 URL 替身。
88
+
17
89
  ## Material contract index
18
90
 
19
91
  Pack is the single material-cook and publication boundary. It publishes one
@@ -44,12 +116,13 @@ recreate that table.
44
116
 
45
117
  ## ScriptablePack in 30 seconds
46
118
 
47
- The public happy path is: declare GUIDs in a `*.pack.ts`, run the Vite Pack
48
- producer, publish Pack v2 plus the Catalog, then call
49
- `AssetRegistry.loadByGuid(guid)`. The durable consumer matrix is the exported
119
+ The public happy path is: declare one stable `packageId` and return a complete
120
+ `sourceKey -> Asset` topology from `definePack`, run the Vite Pack producer,
121
+ publish Pack v2 plus the Catalog, then call `AssetRegistry.loadByGuid(guid)`.
122
+ The durable consumer matrix is the exported
50
123
  `SCRIPTABLE_PACK_ASSET_KINDS` list: mesh, material, scene, texture, equirect,
51
124
  sampler, font, render-pipeline, tileset, video, skeleton, skin,
52
- animation-clip, animation-graph, audio, and particle-effect.
125
+ animation-clip, animation-graph, audio, particle-effect, and ies-profile.
53
126
 
54
127
  Every successful row keeps its `sourceKey` identity, dependency `refs`, and
55
128
  producer-owned `artifacts`. Audio keeps `mediaType` and bytes; particle effects
@@ -157,46 +230,59 @@ root barrel. The root entry remains the build-time scanner/evidence surface.
157
230
 
158
231
  ## Quick start
159
232
 
160
- ### ScriptablePack source
233
+ ### ScriptablePack source (`*.pack.ts`)
161
234
 
162
- Use `@forgeax/engine-pack/source` when one trusted TypeScript source declares and builds a multi-asset package. The definition owns `packageId`, every output `guid`, `sourceKey`, `kind`, optional display `name`, and the scene component schema needed to externalize scene refs. `build(reader)` returns ordinary typed Assets keyed by the same `sourceKey` set; it cannot publish, mutate Catalog, or mint identity.
235
+ Use `@forgeax/engine-pack/source` when one trusted TypeScript source declares
236
+ and builds a multi-asset package. The definition owns one stable `packageId`;
237
+ each build returns ordinary typed Assets keyed by author-owned `sourceKey`.
238
+ The Pack boundary derives every output GUID as
239
+ `AssetGuid.derive(packageId, sourceKey)`, so the source does not contain a
240
+ per-output GUID table, `externalAssets`, or an output writer.
163
241
 
164
242
  ```ts
165
- import type { ScriptablePackDefinition } from '@forgeax/engine-pack/source';
166
- import { Camera } from '@forgeax/engine-render';
167
- import { Transform } from '@forgeax/engine-scene';
243
+ import { AssetGuid, definePackageId, definePack } from '@forgeax/engine/pack/source';
244
+ import { ok } from '@forgeax/engine/types';
245
+
246
+ const packageId = definePackageId('01900000-0000-7000-8000-000000000001');
168
247
 
169
- export default {
170
- schemaVersion: '1.0.0',
248
+ export default definePack({
249
+ schemaVersion: '2.0.0',
171
250
  packageId,
172
- assets: {
173
- mesh: { guid: meshGuid, kind: 'mesh', name: 'Generated Mesh' },
174
- scene: { guid: sceneGuid, kind: 'scene', name: 'Generated Scene' },
175
- },
176
- sceneComponents: [Transform, Camera],
177
- externalAssets: { material: materialGuid },
178
- build: async (assets) => ({ ok: true, value: { mesh, scene } }),
179
- } satisfies ScriptablePackDefinition;
251
+ build: ({ packageId: subjectId }) =>
252
+ ok({
253
+ 'mesh/main': { kind: 'mesh', payload: {}, refs: [] },
254
+ 'scene/main': {
255
+ kind: 'scene',
256
+ payload: { mesh: AssetGuid.derive(subjectId, 'mesh/main') },
257
+ refs: [],
258
+ },
259
+ }),
260
+ });
180
261
  ```
181
262
 
182
- `sceneComponents` is optional for packs that never produce a `scene`. When a
183
- scene is produced, declare every component used by its entities in the same
184
- definition; the isolated Pack worker projects the tokens to a neutral,
185
- serializable schema. A scene component missing from that declaration is a
186
- fail-closed producer error, not a lookup into a global World schema.
263
+ Omitting `parameters` selects the zero-parameter path; a non-empty
264
+ `parameters` array adds typed `values`, defaults, ranges, enum choices,
265
+ vectors, colors, and asset-GUID constraints. The isolated Pack worker passes
266
+ only serializable authoring data to the build and never exposes filesystem or
267
+ runtime state.
187
268
 
188
- `forgeax-engine-remote-asset meta <source.pack.ts> --json` executes module initialization, validates the default export, and projects canonical Meta without calling `build`. `@forgeax/engine-pack/source-node` accepts a host executor with `load` and optional `dispose`; `timeoutMs` bounds module initialization and `buildTimeoutMs` bounds one `build(reader)` call. A build timeout returns one structured `pack-source-load-failed` Result with `detail.phase: 'build'`, the configured `timeoutMs`, and deterministic cleanup of the isolated worker and compile root.
269
+ `forgeax-engine-remote-asset meta <source.pack.ts> --json` executes module initialization, validates the default export, and projects canonical Meta without calling `build`. `@forgeax/engine-pack/source-node` accepts a host executor with `load` and optional `dispose`; `timeoutMs` bounds module initialization and `buildTimeoutMs` bounds one `build(context)` call. A build timeout returns one structured `pack-source-load-failed` Result with `detail.phase: 'build'`, the configured `timeoutMs`, and deterministic cleanup of the isolated worker and compile root.
189
270
 
190
271
  The default worker executes the complete relative TypeScript module closure on the supported Node floor, including Node 22 hosts that do not load `.ts` files directly. It transpiles that closure into a disposable ESM directory, resolves bare imports through the source project's nearest `node_modules`, and removes the directory when the worker is disposed. Bulk producers use the internal `createScriptablePackModuleExecutorPool()` with two recyclable workers; a pooled lease is released after metadata projection or one build, so a generation never retains one live Worker-backed definition per source.
191
272
 
192
273
  > [!IMPORTANT]
193
- > Source authoring is an explicit Node contract. Every gateway call carries a caller-minted `requestId`; mutations may carry `expectedRevision` for SHA-256 CAS. The filesystem port confines paths to one game root and atomically replaces only `canonical-v1` scaffolds. Arbitrary valid TypeScript remains inspectable and rebuildable, but unsupported structural edits fail closed with stable `pack-source-*` errors.
274
+ > Source authoring is an explicit Node contract. Every gateway call carries a
275
+ > caller-minted `requestId`; mutations may carry `expectedRevision` for
276
+ > SHA-256 CAS. The filesystem port confines paths to one game root and only
277
+ > writes constrained generated source or structured v3 JSON. Arbitrary valid
278
+ > TypeScript remains inspectable and rebuildable, but unsupported structural
279
+ > edits fail closed with stable `pack-source-*` errors.
194
280
 
195
- `SOURCE_AUTHORING_OPERATION_DESCRIPTORS` is the producer-owned structured capability manifest for tools. The existing `asset.preflight` operation returns the current revision, canonical Meta, incoming references, and shape-derived mutation capabilities before any write.
281
+ `PACK_AUTHORING_OPERATION_DESCRIPTORS` is the producer-owned structured capability manifest for tools. The existing `asset.preflight` operation returns the current revision, canonical Meta, incoming references, and shape-derived mutation capabilities before any write.
196
282
 
197
283
  ```typescript
198
- import { AssetGuid } from "@forgeax/engine-pack/guid";
199
- import { scan, scanInventory } from "@forgeax/engine-pack/scanner";
284
+ import { AssetGuid } from "@forgeax/engine/pack/guid";
285
+ import { scan, scanInventory } from "@forgeax/engine/pack/scanner";
200
286
 
201
287
  // Runtime: resolve a known GUID at build time
202
288
  const result = AssetGuid.parse("cbe42beb-8975-5096-b3a1-3dda4cb4c077");
@@ -211,12 +297,14 @@ console.log(scanResult.value); // PackEntry[]
211
297
  // Build hosts can retain one validated inventory and project paths from it.
212
298
  const inventory = await scanInventory(["apps/hello/cube/assets"]);
213
299
  if (!inventory.ok) throw inventory.error;
214
- console.log(inventory.value.paths, inventory.value.scriptablePackMeta);
300
+ console.log(inventory.value.paths, inventory.value.declarations);
215
301
  ```
216
302
 
217
303
  ## Schema shapes
218
304
 
219
- Two sidecar JSON files live next to each source file in an asset directory:
305
+ External imports and authored Packs have different identity owners. An external
306
+ source keeps importer-owned sub-asset GUIDs in its `.meta.json`; an authored
307
+ Pack keeps one `packageId` and names outputs with `sourceKey`.
220
308
 
221
309
  ### `.meta.json` -- external-asset-package
222
310
 
@@ -231,6 +319,7 @@ Two sidecar JSON files live next to each source file in an asset directory:
231
319
  { "guid": "<UUIDv7-or-UUIDv5>", "sourceIndex": 0, "kind": "mesh", "compression": "zstd" }
232
320
  ]
233
321
  }
322
+ ```
234
323
 
235
324
  > [!NOTE]
236
325
  > `compression?: 'none' | 'zstd'` on `PackIndexEntry` (and `subAssets[].compression`)
@@ -243,33 +332,45 @@ Two sidecar JSON files live next to each source file in an asset directory:
243
332
  > (default: mesh -> `zstd`, texture -> `none`; `.pack.json` never compressed).
244
333
  > The importer honors the override and writes the resulting `compression` onto
245
334
  > the output catalog row. Omit it to accept the kind-keyed default.
335
+
336
+ ### `.pack.json` -- authored Pack v3
337
+
338
+ Direct authoring names its outputs by `sourceKey`; it never stores output GUIDs:
339
+
340
+ ```json
341
+ {
342
+ "schemaVersion": "3.0.0",
343
+ "packageId": "01900000-0000-7000-8000-000000000010",
344
+ "assets": {
345
+ "mesh/main": { "kind": "mesh", "payload": {}, "refs": [] }
346
+ }
347
+ }
246
348
  ```
247
349
 
248
- ### `.pack.json` -- internal-text-package
350
+ An instance uses the same extension and schema version, but has only its own
351
+ identity, parent, and sparse parameter values:
249
352
 
250
353
  ```json
251
354
  {
252
- "schemaVersion": "1.0.0",
253
- "kind": "internal-text-package",
254
- "assets": [
255
- {
256
- "guid": "<UUIDv7-or-UUIDv5>",
257
- "kind": "mesh",
258
- "payload": {},
259
- "refs": []
260
- }
261
- ]
355
+ "schemaVersion": "3.0.0",
356
+ "packageId": "01900000-0000-7000-8000-000000000011",
357
+ "parent": "01900000-0000-7000-8000-000000000010",
358
+ "values": { "count": 4 }
262
359
  }
263
360
  ```
264
361
 
362
+ The two v3 branches are mutually exclusive. The build lowers them to the
363
+ runtime Pack v2 projection, whose rows contain derived GUIDs and `kind:
364
+ "internal-text-package"`; runtime still loads only that cooked projection.
365
+
265
366
  ### Producer provenance and topology
266
367
 
267
- Both package schemas accept producer-owned `packageId`, `provenance`,
268
- `revision`, and structured `diagnostics`. Asset/output rows may declare a
269
- stable `sourceKey`; `sourceIndex` is positional evidence only. The runtime
270
- function `diffTopology(previous, next)` preserves GUIDs by `sourceKey`, reports additions,
271
- removals, and kind changes, and marks multi-output source-index-only matching
272
- as ambiguous.
368
+ Authored and cooked Pack projections carry producer-owned `packageId`,
369
+ `provenance`, `revision`, and structured `diagnostics`. Asset/output rows may
370
+ declare a stable `sourceKey`; `sourceIndex` is positional evidence only. The
371
+ runtime function `diffTopology(previous, next)` preserves GUIDs by `sourceKey`,
372
+ reports additions, removals, and kind changes, and marks multi-output
373
+ source-index-only matching as ambiguous.
273
374
 
274
375
  | Fact | Published by | Consumer rule |
275
376
  |:--|:--|:--|
@@ -417,6 +518,24 @@ one receipt per GUID, validates asset-local artifact paths and bytes, and emits
417
518
  the deterministic package URL and digest. Producers provide policy through the
418
519
  finalizer sink; Pack owns package serialization and publication facts.
419
520
 
521
+ ## Mesh LOD relation closure
522
+
523
+ LOD is a relation inside the root mesh payload, not an independent runtime
524
+ asset kind. A valid Pack row contains the lower MeshAsset GUID in both the
525
+ payload and root `refs[]`, and the lower row is present in the same package:
526
+
527
+ ```json
528
+ {
529
+ "kind": "mesh",
530
+ "payload": { "lods": [{ "mesh": "<lod-guid>", "screenCoverage": 0.5 }] },
531
+ "refs": ["<lod-guid>"]
532
+ }
533
+ ```
534
+
535
+ The finalizer preserves this relation while sorting rows deterministically.
536
+ Missing closure, duplicate GUIDs, invalid artifacts, or incomplete receipts
537
+ fail before publication; repair the producer and retry the same source Meta.
538
+
420
539
  ## Entry subpaths
421
540
 
422
541
  | Subpath | Exports |
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=inventory-schema.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inventory-schema.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/inventory-schema.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=material-cook-receipt-layer-plan.unit.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"material-cook-receipt-layer-plan.unit.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/material-cook-receipt-layer-plan.unit.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=pack-authoring-gateway.unit.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pack-authoring-gateway.unit.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/pack-authoring-gateway.unit.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=pack-authoring.unit.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pack-authoring.unit.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/pack-authoring.unit.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=pack-scanner.unit.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pack-scanner.unit.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/pack-scanner.unit.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=scanner-blacklist.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scanner-blacklist.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/scanner-blacklist.test.ts"],"names":[],"mappings":""}
package/dist/build.d.ts CHANGED
@@ -4,16 +4,21 @@ export { validateArtifactPath } from './artifact-path.js';
4
4
  export { buildCatalogProjection, type CatalogAuthority, type CatalogBuildError, type CatalogBuildErrorCode, type CatalogBuildProjectionOptions, type CatalogBuildResult, type CatalogImporterPolicy, type CatalogProducerVisibility, catalogSourcePathFor, metaPathForGuid, } from './catalog-builder.js';
5
5
  export { calculateCatalogDelta } from './catalog-delta.js';
6
6
  export { type CatalogOutputDeclaration, type CatalogProducerMeta, type CookedPackageProjection, catalogProjectionFor, currentProjectionFor, findReservedAssetKindConflict, type PackageCatalogInput, projectCookedPackageEntry, projectExternalCatalogEntries, projectPackageCatalog, projectRuntimeCatalogRow, type RuntimeCatalogRowInput, } from './catalog-projection.js';
7
- export { type LoadAssetConfigResult, loadAssetConfig } from './config.js';
8
7
  export { type CookedMaterialRecord, collectMaterialCookRefs, createMaterialArtifactDigest, type MaterialCookArtifact, type MaterialCookIdentityExpectation, type MaterialCookReceipt, type MaterialCookRecordError, type MaterialCookRefs, projectCookedMaterialRecord, serializeCookedMaterialRecord, serializeMaterialCookReceipt, validateCookedMaterialRecord, validateMaterialCookReceipt, } from './evidence/material-cook.js';
9
8
  export { buildOfflineAssetEvidence, packageVerification } from './evidence/offline-evidence.js';
9
+ export { AssetGuid, isValidAssetGuidString, isValidPackSourceKey, PACK_SOURCE_KEY_RE, PackageId, } from './guid.js';
10
+ export { projectAssetRefs, projectSceneEntityRefs } from './inventory/binding.js';
11
+ export { type AuthorInventory, type AuthorInventoryRow, type InventoryError, type InventoryErrorCode, validateAuthorInventory, } from './inventory/declaration.js';
12
+ export { inventoryDigest, syncAuthorInventory } from './inventory/sync.js';
10
13
  export { decodeMeshBinHeader, MESH_BIN_DIGEST_BYTES, MESH_BIN_HEADER_V4_BYTES, MESH_BIN_PROJECTION_VERSION, MESH_BIN_VERSION, type MeshBinContractError, type MeshBinHeaderResult, type MeshBinHeaderV4, writeMeshBinHeader, } from './mesh-bin-contract.js';
11
- export { type AuthoredPackAssetInput, type AuthoredPackInput, type FinalizedPackageProduct, finalizePackageProduct, finalizePackageTransportSource, type PackageArtifactBody, type PackageFinalizePolicy, type PackageFinalizeResult, type PackageFinalizerError, type PackageProduct, type PackageProductAsset, packageTransportRevision, upgradeLegacyAuthoredPack, } from './package-finalizer.js';
14
+ export * from './pack-authoring.js';
15
+ export { createFileSystemPackAuthoringGateway, createFileSystemPackAuthoringPort, type FileSystemPackAuthoringOptions, type PackAuthoringMaterializedAsset, } from './pack-authoring-node.js';
16
+ export { type FinalizedPackageProduct, finalizePackageProduct, finalizePackageTransportSource, type PackageArtifactBody, type PackageFinalizePolicy, type PackageFinalizeResult, type PackageFinalizerError, type PackageProduct, type PackageProductAsset, packageTransportRevision, } from './package-finalizer.js';
12
17
  export { validateProducerContract, validateProducerOutputs } from './producer-contract.js';
13
18
  export { resolveAssetSource } from './resolve-asset-source.js';
14
19
  export { parsePackV2, validateMeta, validatePack, validatePackV2 } from './runtime.js';
15
20
  export { createRuntimePackPublication, type RuntimePackAssetInput, type RuntimePackEnvelope, type RuntimePackInput, type RuntimePackPublication, type RuntimePackPublicationInput, } from './runtime-publication.js';
16
- export { type InventoryDeclaration, type ScanInventory, type ScanOptions, type ScriptablePackInventoryDeclaration, type ScriptablePackScanOptions, STANDARD_SCRIPTABLE_PACK_SCAN_OPTIONS, scanInventory, } from './scanner.js';
17
- export { type AssetReader, isScriptablePackAssetKind, projectScriptablePackMeta, projectScriptablePackSceneComponents, SCRIPTABLE_PACK_ASSET_KINDS, SCRIPTABLE_PACK_CAPABILITY_MANIFEST, type ScriptablePackAssetDeclaration, type ScriptablePackAssetDeclarations, type ScriptablePackAssetFor, type ScriptablePackAssetKind, type ScriptablePackDefinition, type ScriptablePackError, type ScriptablePackExternalAssets, type ScriptablePackMetaJson, type ScriptablePackOutputs, type ScriptablePackPublicationEnvelope, type ScriptablePackReadError, type ScriptablePackSceneComponent, type ScriptablePackSceneComponentInput, type ScriptablePackSourceClosureEntry, validateScriptablePackDefinition, } from './scriptable-pack.js';
21
+ export { type InventoryDeclaration, type LegacyPackInventoryDocument, type PackInventoryAsset, type PackInventoryDocument, type PackSourceInventoryDocument, type ScanInventory, type ScanOptions, type ScanSourceDeclaration, type ScriptablePackInventoryDeclaration, type ScriptablePackScanOptions, STANDARD_SCRIPTABLE_PACK_SCAN_OPTIONS, scanInventory, } from './scanner.js';
22
+ export { type AssetReader, isScriptablePackAssetKind, projectScriptablePackSceneComponents, SCRIPTABLE_PACK_ASSET_KINDS, type ScriptablePackAssetKind, type ScriptablePackReadError, type ScriptablePackSourceClosureEntry, } from './scriptable-pack.js';
18
23
  export { calculateTopologyDiff, diffTopology } from './topology.js';
19
24
  //# sourceMappingURL=build.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../src/build.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../src/build.ts"],"names":[],"mappings":"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"}