@forgeax/engine-assets-runtime 0.1.4 → 0.1.7
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 +453 -175
- package/dist/.tsbuildinfo +1 -1
- package/dist/__tests__/aabb.unit.test.d.ts +2 -0
- package/dist/__tests__/aabb.unit.test.d.ts.map +1 -0
- package/dist/__tests__/artifact-integrity.unit.test.d.ts +2 -0
- package/dist/__tests__/artifact-integrity.unit.test.d.ts.map +1 -0
- package/dist/__tests__/artifact-io.unit.test.d.ts +2 -0
- package/dist/__tests__/artifact-io.unit.test.d.ts.map +1 -0
- package/dist/__tests__/asset-evidence-sdk.integration.test.d.ts +2 -0
- package/dist/__tests__/asset-evidence-sdk.integration.test.d.ts.map +1 -0
- package/dist/__tests__/asset-evidence.unit.test.d.ts +2 -0
- package/dist/__tests__/asset-evidence.unit.test.d.ts.map +1 -0
- package/dist/__tests__/asset-kind.unit.test.d.ts +2 -0
- package/dist/__tests__/asset-kind.unit.test.d.ts.map +1 -0
- package/dist/__tests__/asset-registry-catalog-reconcile.integration.test.d.ts +2 -0
- package/dist/__tests__/asset-registry-catalog-reconcile.integration.test.d.ts.map +1 -0
- package/dist/__tests__/asset-registry-catalog-reconcile.unit.test.d.ts +2 -0
- package/dist/__tests__/asset-registry-catalog-reconcile.unit.test.d.ts.map +1 -0
- package/dist/__tests__/asset-registry-catalog.unit.test.d.ts +2 -0
- package/dist/__tests__/asset-registry-catalog.unit.test.d.ts.map +1 -0
- package/dist/__tests__/asset-registry.pack-cache.test.d.ts +2 -0
- package/dist/__tests__/asset-registry.pack-cache.test.d.ts.map +1 -0
- package/dist/__tests__/asset-registry.unit.test.d.ts +2 -0
- package/dist/__tests__/asset-registry.unit.test.d.ts.map +1 -0
- package/dist/__tests__/asset-runtime-error-code-owner.test-d.d.ts +2 -0
- package/dist/__tests__/asset-runtime-error-code-owner.test-d.d.ts.map +1 -0
- package/dist/__tests__/catalog-replica.unit.test.d.ts +2 -0
- package/dist/__tests__/catalog-replica.unit.test.d.ts.map +1 -0
- package/dist/__tests__/catalog-source-v2.unit.test.d.ts +2 -0
- package/dist/__tests__/catalog-source-v2.unit.test.d.ts.map +1 -0
- package/dist/__tests__/catalog-source.unit.test.d.ts +2 -0
- package/dist/__tests__/catalog-source.unit.test.d.ts.map +1 -0
- package/dist/__tests__/catalog-subscription-order.unit.test.d.ts +2 -0
- package/dist/__tests__/catalog-subscription-order.unit.test.d.ts.map +1 -0
- package/dist/__tests__/catalog-subscription.unit.test.d.ts +2 -0
- package/dist/__tests__/catalog-subscription.unit.test.d.ts.map +1 -0
- package/dist/__tests__/decode-image-bytes-pass-through.test.d.ts +2 -0
- package/dist/__tests__/decode-image-bytes-pass-through.test.d.ts.map +1 -0
- package/dist/__tests__/decode-image-bytes.browser.test.d.ts +2 -0
- package/dist/__tests__/decode-image-bytes.browser.test.d.ts.map +1 -0
- package/dist/__tests__/decode-image-bytes.test-d.d.ts +2 -0
- package/dist/__tests__/decode-image-bytes.test-d.d.ts.map +1 -0
- package/dist/__tests__/decode-image-bytes.test.d.ts +2 -0
- package/dist/__tests__/decode-image-bytes.test.d.ts.map +1 -0
- package/dist/__tests__/dynamic-texture-store.unit.test.d.ts +2 -0
- package/dist/__tests__/dynamic-texture-store.unit.test.d.ts.map +1 -0
- package/dist/__tests__/errors-asset.unit.test.d.ts +2 -0
- package/dist/__tests__/errors-asset.unit.test.d.ts.map +1 -0
- package/dist/__tests__/inline-pack-loaders.unit.test.d.ts +2 -0
- package/dist/__tests__/inline-pack-loaders.unit.test.d.ts.map +1 -0
- package/dist/__tests__/instantiate-context.unit.test.d.ts +2 -0
- package/dist/__tests__/instantiate-context.unit.test.d.ts.map +1 -0
- package/dist/__tests__/instantiate-publication-fence.unit.test.d.ts +2 -0
- package/dist/__tests__/instantiate-publication-fence.unit.test.d.ts.map +1 -0
- package/dist/__tests__/instantiate.unit.test.d.ts +2 -0
- package/dist/__tests__/instantiate.unit.test.d.ts.map +1 -0
- package/dist/__tests__/loader-input-contract.unit.test.d.ts +2 -0
- package/dist/__tests__/loader-input-contract.unit.test.d.ts.map +1 -0
- package/dist/__tests__/loader-registry.unit.test.d.ts +2 -0
- package/dist/__tests__/loader-registry.unit.test.d.ts.map +1 -0
- package/dist/__tests__/material-dependency-invalidation.unit.test.d.ts +2 -0
- package/dist/__tests__/material-dependency-invalidation.unit.test.d.ts.map +1 -0
- package/dist/__tests__/material-generation-cache.unit.test.d.ts +2 -0
- package/dist/__tests__/material-generation-cache.unit.test.d.ts.map +1 -0
- package/dist/__tests__/material-load-consumer.test-d.d.ts +2 -0
- package/dist/__tests__/material-load-consumer.test-d.d.ts.map +1 -0
- package/dist/__tests__/material-ready.integration.test.d.ts +2 -0
- package/dist/__tests__/material-ready.integration.test.d.ts.map +1 -0
- package/dist/__tests__/material-stale-generation.unit.test.d.ts +2 -0
- package/dist/__tests__/material-stale-generation.unit.test.d.ts.map +1 -0
- package/dist/__tests__/mesh-bin-morph-v3.test.d.ts +2 -0
- package/dist/__tests__/mesh-bin-morph-v3.test.d.ts.map +1 -0
- package/dist/__tests__/mesh-bin.unit.test.d.ts +2 -0
- package/dist/__tests__/mesh-bin.unit.test.d.ts.map +1 -0
- package/dist/__tests__/mipmap-generator.unit.test.d.ts +2 -0
- package/dist/__tests__/mipmap-generator.unit.test.d.ts.map +1 -0
- package/dist/__tests__/pack-artifact-transcode-model-owner.test.d.ts +2 -0
- package/dist/__tests__/pack-artifact-transcode-model-owner.test.d.ts.map +1 -0
- package/dist/__tests__/pack-basis-load.integration.test.d.ts +2 -0
- package/dist/__tests__/pack-basis-load.integration.test.d.ts.map +1 -0
- package/dist/__tests__/payload-validate.unit.test.d.ts +2 -0
- package/dist/__tests__/payload-validate.unit.test.d.ts.map +1 -0
- package/dist/__tests__/plugin.test.d.ts +2 -0
- package/dist/__tests__/plugin.test.d.ts.map +1 -0
- package/dist/__tests__/registry-concurrency.bench.test.d.ts +2 -0
- package/dist/__tests__/registry-concurrency.bench.test.d.ts.map +1 -0
- package/dist/__tests__/registry-failure-retry.integration.test.d.ts +2 -0
- package/dist/__tests__/registry-failure-retry.integration.test.d.ts.map +1 -0
- package/dist/__tests__/registry-load-graph.integration.test.d.ts +2 -0
- package/dist/__tests__/registry-load-graph.integration.test.d.ts.map +1 -0
- package/dist/__tests__/registry-load-state.unit.test.d.ts +2 -0
- package/dist/__tests__/registry-load-state.unit.test.d.ts.map +1 -0
- package/dist/__tests__/registry-package-cache.unit.test.d.ts +2 -0
- package/dist/__tests__/registry-package-cache.unit.test.d.ts.map +1 -0
- package/dist/__tests__/registry-public-ready.unit.test.d.ts +2 -0
- package/dist/__tests__/registry-public-ready.unit.test.d.ts.map +1 -0
- package/dist/__tests__/resolve-asset-handle.unit.test.d.ts +2 -0
- package/dist/__tests__/resolve-asset-handle.unit.test.d.ts.map +1 -0
- package/dist/__tests__/scene-handle-fields.unit.test.d.ts +2 -0
- package/dist/__tests__/scene-handle-fields.unit.test.d.ts.map +1 -0
- package/dist/__tests__/scene-payload.unit.test.d.ts +2 -0
- package/dist/__tests__/scene-payload.unit.test.d.ts.map +1 -0
- package/dist/__tests__/scene-publication-fence.test.d.ts +2 -0
- package/dist/__tests__/scene-publication-fence.test.d.ts.map +1 -0
- package/dist/__tests__/scriptable-pack-public-surface.test-d.d.ts +2 -0
- package/dist/__tests__/scriptable-pack-public-surface.test-d.d.ts.map +1 -0
- package/dist/__tests__/static-rig.integration.test.d.ts +2 -0
- package/dist/__tests__/static-rig.integration.test.d.ts.map +1 -0
- package/dist/__tests__/validate-material.unit.test.d.ts +2 -0
- package/dist/__tests__/validate-material.unit.test.d.ts.map +1 -0
- package/dist/__tests__/video-pack-loader.integration.test.d.ts +2 -0
- package/dist/__tests__/video-pack-loader.integration.test.d.ts.map +1 -0
- package/dist/aabb.d.ts +3 -0
- package/dist/aabb.d.ts.map +1 -0
- package/dist/asset-registry.d.ts +554 -0
- package/dist/asset-registry.d.ts.map +1 -0
- package/dist/builtin-asset-registry.d.ts +22 -0
- package/dist/builtin-asset-registry.d.ts.map +1 -0
- package/dist/catalog-source.d.ts +2 -1
- package/dist/catalog-source.d.ts.map +1 -1
- package/dist/decode-image-bytes.d.ts +57 -0
- package/dist/decode-image-bytes.d.ts.map +1 -0
- package/dist/dynamic-texture-store.d.ts +89 -0
- package/dist/dynamic-texture-store.d.ts.map +1 -0
- package/dist/errors/asset.d.ts +201 -0
- package/dist/errors/asset.d.ts.map +1 -0
- package/dist/handles.d.ts +143 -0
- package/dist/handles.d.ts.map +1 -0
- package/dist/image-error.d.ts +6 -0
- package/dist/image-error.d.ts.map +1 -0
- package/dist/index.d.ts +32 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +7233 -114
- package/dist/index.mjs.map +1 -1
- package/dist/internal.d.ts +1 -1
- package/dist/internal.d.ts.map +1 -1
- package/dist/loader-registry.d.ts +63 -0
- package/dist/loader-registry.d.ts.map +1 -0
- package/dist/loaders/inline-pack.d.ts +72 -0
- package/dist/loaders/inline-pack.d.ts.map +1 -0
- package/dist/loaders/mesh-bin.d.ts +21 -0
- package/dist/loaders/mesh-bin.d.ts.map +1 -0
- package/dist/loaders/pack-artifact.d.ts +20 -0
- package/dist/loaders/pack-artifact.d.ts.map +1 -0
- package/dist/material/dependency-graph.d.ts +9 -0
- package/dist/material/dependency-graph.d.ts.map +1 -0
- package/dist/material/generation-cache.d.ts +24 -0
- package/dist/material/generation-cache.d.ts.map +1 -0
- package/dist/material/inspection.d.ts +24 -0
- package/dist/material/inspection.d.ts.map +1 -0
- package/dist/material/loader.d.ts +59 -0
- package/dist/material/loader.d.ts.map +1 -0
- package/dist/material/runtime-shader.d.ts +14 -0
- package/dist/material/runtime-shader.d.ts.map +1 -0
- package/dist/mesh-bin.d.ts +3 -0
- package/dist/mesh-bin.d.ts.map +1 -0
- package/dist/mipmap-generator.d.ts +132 -0
- package/dist/mipmap-generator.d.ts.map +1 -0
- package/dist/payload-validate.d.ts +60 -0
- package/dist/payload-validate.d.ts.map +1 -0
- package/dist/plugin.d.ts +16 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/registry/artifact-io.d.ts +16 -0
- package/dist/registry/artifact-io.d.ts.map +1 -0
- package/dist/registry/asset-evidence.d.ts +13 -0
- package/dist/registry/asset-evidence.d.ts.map +1 -0
- package/dist/registry/catalog-state.d.ts +47 -0
- package/dist/registry/catalog-state.d.ts.map +1 -0
- package/dist/registry/catalog.d.ts +48 -0
- package/dist/registry/catalog.d.ts.map +1 -0
- package/dist/registry/instantiate.d.ts +153 -0
- package/dist/registry/instantiate.d.ts.map +1 -0
- package/dist/registry/load-by-guid.d.ts +247 -0
- package/dist/registry/load-by-guid.d.ts.map +1 -0
- package/dist/registry/load-state.d.ts +26 -0
- package/dist/registry/load-state.d.ts.map +1 -0
- package/dist/registry/runtime-projection.d.ts +16 -0
- package/dist/registry/runtime-projection.d.ts.map +1 -0
- package/dist/registry/scene-publication-fence.d.ts +38 -0
- package/dist/registry/scene-publication-fence.d.ts.map +1 -0
- package/dist/registry/validate-material.d.ts +77 -0
- package/dist/registry/validate-material.d.ts.map +1 -0
- package/dist/resolve-asset-handle.d.ts +43 -0
- package/dist/resolve-asset-handle.d.ts.map +1 -0
- package/dist/resolve-tileset-runtime.d.ts +23 -0
- package/dist/resolve-tileset-runtime.d.ts.map +1 -0
- package/dist/scene-handle-fields.d.ts +88 -0
- package/dist/scene-handle-fields.d.ts.map +1 -0
- package/dist/scene-payload.d.ts +15 -0
- package/dist/scene-payload.d.ts.map +1 -0
- package/dist/wire-default-loaders.d.ts +29 -0
- package/dist/wire-default-loaders.d.ts.map +1 -0
- package/package.json +22 -9
- package/src/__tests__/aabb.unit.test.ts +97 -0
- package/src/__tests__/artifact-integrity.unit.test.ts +99 -0
- package/src/__tests__/artifact-io.unit.test.ts +127 -0
- package/src/__tests__/asset-evidence-sdk.integration.test.ts +32 -0
- package/src/__tests__/asset-evidence.unit.test.ts +32 -0
- package/src/__tests__/{asset-kind.test.ts → asset-kind.unit.test.ts} +1 -1
- package/src/__tests__/asset-registry-catalog-reconcile.integration.test.ts +74 -0
- package/src/__tests__/asset-registry-catalog-reconcile.unit.test.ts +89 -0
- package/src/__tests__/asset-registry-catalog.unit.test.ts +170 -0
- package/src/__tests__/asset-registry.pack-cache.test.ts +96 -0
- package/src/__tests__/asset-registry.unit.test.ts +511 -0
- package/src/__tests__/asset-runtime-error-code-owner.test-d.ts +63 -0
- package/src/__tests__/catalog-replica.unit.test.ts +196 -0
- package/src/__tests__/catalog-source-v2.unit.test.ts +158 -0
- package/src/__tests__/catalog-source.unit.test.ts +126 -0
- package/src/__tests__/catalog-subscription-order.unit.test.ts +65 -0
- package/src/__tests__/catalog-subscription.unit.test.ts +28 -0
- package/src/__tests__/decode-image-bytes-pass-through.test.ts +34 -0
- package/src/__tests__/decode-image-bytes.browser.test.ts +102 -0
- package/src/__tests__/decode-image-bytes.test-d.ts +108 -0
- package/src/__tests__/decode-image-bytes.test.ts +90 -0
- package/src/__tests__/decode-image-mime-owner.test.ts +2 -5
- package/src/__tests__/dynamic-texture-store.unit.test.ts +115 -0
- package/src/__tests__/errors-asset.unit.test.ts +92 -0
- package/src/__tests__/inline-pack-loaders.unit.test.ts +548 -0
- package/src/__tests__/instantiate-context.unit.test.ts +65 -0
- package/src/__tests__/instantiate-publication-fence.unit.test.ts +158 -0
- package/src/__tests__/instantiate.unit.test.ts +684 -0
- package/src/__tests__/loader-input-contract.unit.test.ts +89 -0
- package/src/__tests__/loader-registry.unit.test.ts +101 -0
- package/src/__tests__/material-dependency-invalidation.unit.test.ts +14 -0
- package/src/__tests__/material-generation-cache.unit.test.ts +46 -0
- package/src/__tests__/material-load-consumer.test-d.ts +42 -0
- package/src/__tests__/material-ready.integration.test.ts +508 -0
- package/src/__tests__/material-stale-generation.unit.test.ts +147 -0
- package/src/__tests__/mesh-bin-morph-v3.test.ts +22 -0
- package/src/__tests__/mesh-bin.unit.test.ts +152 -0
- package/src/__tests__/mipmap-generator.unit.test.ts +202 -0
- package/src/__tests__/pack-artifact-transcode-model-owner.test.ts +32 -0
- package/src/__tests__/pack-basis-load.integration.test.ts +168 -0
- package/src/__tests__/payload-validate.unit.test.ts +285 -0
- package/src/__tests__/plugin.test.ts +55 -0
- package/src/__tests__/registry-concurrency.bench.test.ts +40 -0
- package/src/__tests__/registry-failure-retry.integration.test.ts +69 -0
- package/src/__tests__/registry-load-graph.integration.test.ts +246 -0
- package/src/__tests__/registry-load-state.unit.test.ts +35 -0
- package/src/__tests__/registry-package-cache.unit.test.ts +53 -0
- package/src/__tests__/registry-public-ready.unit.test.ts +38 -0
- package/src/__tests__/resolve-asset-handle.unit.test.ts +238 -0
- package/src/__tests__/scene-handle-fields.unit.test.ts +129 -0
- package/src/__tests__/scene-payload.unit.test.ts +151 -0
- package/src/__tests__/scene-publication-fence.test.ts +129 -0
- package/src/__tests__/scriptable-pack-public-surface.test-d.ts +27 -0
- package/src/__tests__/static-rig.integration.test.ts +8 -0
- package/src/__tests__/validate-material.unit.test.ts +359 -0
- package/src/__tests__/video-pack-loader.integration.test.ts +83 -0
- package/src/aabb.ts +107 -0
- package/src/asset-registry.ts +2045 -0
- package/src/builtin-asset-registry.ts +164 -0
- package/src/catalog-source.ts +14 -70
- package/src/decode-image-bytes.ts +126 -0
- package/src/dynamic-texture-store.ts +234 -0
- package/src/errors/asset.ts +347 -0
- package/src/handles.ts +186 -0
- package/src/image-error.ts +45 -0
- package/src/index.ts +183 -16
- package/src/internal.ts +1 -0
- package/src/loader-registry.ts +157 -0
- package/src/loaders/inline-pack.ts +837 -0
- package/src/loaders/mesh-bin.ts +304 -0
- package/src/loaders/pack-artifact.ts +665 -0
- package/src/material/dependency-graph.ts +46 -0
- package/src/material/generation-cache.ts +177 -0
- package/src/material/inspection.ts +46 -0
- package/src/material/loader.ts +326 -0
- package/src/material/runtime-shader.ts +133 -0
- package/src/mesh-bin.ts +5 -0
- package/src/mipmap-generator.ts +450 -0
- package/src/payload-validate.ts +573 -0
- package/src/plugin.ts +48 -0
- package/src/registry/artifact-io.ts +259 -0
- package/src/registry/asset-evidence.ts +51 -0
- package/src/registry/catalog-state.ts +409 -0
- package/src/registry/catalog.ts +369 -0
- package/src/registry/instantiate.ts +1056 -0
- package/src/registry/load-by-guid.ts +1657 -0
- package/src/registry/load-state.ts +115 -0
- package/src/registry/runtime-projection.ts +63 -0
- package/src/registry/scene-publication-fence.ts +256 -0
- package/src/registry/validate-material.ts +385 -0
- package/src/resolve-asset-handle.ts +147 -0
- package/src/resolve-tileset-runtime.ts +72 -0
- package/src/scene-handle-fields.ts +221 -0
- package/src/scene-payload.ts +207 -0
- package/src/wire-default-loaders.ts +79 -0
- package/dist/__tests__/asset-graph-red.integration.test.d.ts +0 -2
- package/dist/__tests__/asset-graph-red.integration.test.d.ts.map +0 -1
- package/dist/__tests__/asset-kind.test.d.ts +0 -2
- package/dist/__tests__/asset-kind.test.d.ts.map +0 -1
- package/dist/__tests__/asset-registry-core.integration.test.d.ts +0 -2
- package/dist/__tests__/asset-registry-core.integration.test.d.ts.map +0 -1
- package/dist/__tests__/asset-registry-public-api.test-d.d.ts +0 -2
- package/dist/__tests__/asset-registry-public-api.test-d.d.ts.map +0 -1
- package/dist/__tests__/asset-runtime-core-lifecycle.integration.test.d.ts +0 -2
- package/dist/__tests__/asset-runtime-core-lifecycle.integration.test.d.ts.map +0 -1
- package/dist/__tests__/asset-runtime-snapshot.unit.test.d.ts +0 -2
- package/dist/__tests__/asset-runtime-snapshot.unit.test.d.ts.map +0 -1
- package/dist/__tests__/catalog-session-red.unit.test.d.ts +0 -2
- package/dist/__tests__/catalog-session-red.unit.test.d.ts.map +0 -1
- package/dist/__tests__/registry-lifecycle-red.integration.test.d.ts +0 -2
- package/dist/__tests__/registry-lifecycle-red.integration.test.d.ts.map +0 -1
- package/src/__tests__/asset-graph-red.integration.test.ts +0 -113
- package/src/__tests__/asset-registry-core.integration.test.ts +0 -161
- package/src/__tests__/asset-registry-public-api.test-d.ts +0 -31
- package/src/__tests__/asset-runtime-core-lifecycle.integration.test.ts +0 -79
- package/src/__tests__/asset-runtime-snapshot.unit.test.ts +0 -23
- package/src/__tests__/catalog-session-red.unit.test.ts +0 -276
- package/src/__tests__/registry-lifecycle-red.integration.test.ts +0 -80
|
@@ -0,0 +1,369 @@
|
|
|
1
|
+
import { err, ok, type Result } from '@forgeax/engine-rhi';
|
|
2
|
+
import {
|
|
3
|
+
ASSET_ERROR_HINTS,
|
|
4
|
+
type Asset,
|
|
5
|
+
type AssetAuthoringCapability,
|
|
6
|
+
type AssetEnvelope,
|
|
7
|
+
AssetError,
|
|
8
|
+
type AssetPublicationEnvelope,
|
|
9
|
+
type AssetRelation,
|
|
10
|
+
authoringCapabilityForAssetKind,
|
|
11
|
+
type CatalogDiagnostic,
|
|
12
|
+
type CatalogLifecycle,
|
|
13
|
+
type CatalogProjection,
|
|
14
|
+
type CatalogSubject,
|
|
15
|
+
type CookExecution,
|
|
16
|
+
type ProviderProvenance,
|
|
17
|
+
type ResourceRevision,
|
|
18
|
+
type RuntimeAssetBinding,
|
|
19
|
+
type SourceOverrideDescriptor,
|
|
20
|
+
type SourceOverrideMap,
|
|
21
|
+
} from '@forgeax/engine-types';
|
|
22
|
+
import type { AssetRegistry } from '../asset-registry';
|
|
23
|
+
|
|
24
|
+
/** Runtime catalog row parsed from the shared pack-index POD shape. */
|
|
25
|
+
export interface CatalogRecord {
|
|
26
|
+
readonly packageUrl: string;
|
|
27
|
+
readonly kind: string;
|
|
28
|
+
readonly authoring?: import('@forgeax/engine-types').AssetAuthoringCapability;
|
|
29
|
+
readonly name?: string;
|
|
30
|
+
readonly refs?: readonly string[];
|
|
31
|
+
readonly sourcePath?: string;
|
|
32
|
+
readonly cookReceiptUrl?: string;
|
|
33
|
+
readonly packageId?: string;
|
|
34
|
+
readonly provenance?: ProviderProvenance;
|
|
35
|
+
readonly revision?: ResourceRevision;
|
|
36
|
+
readonly sourceKey?: string;
|
|
37
|
+
readonly sourceIndex?: number;
|
|
38
|
+
readonly sourceOverrides?: SourceOverrideMap;
|
|
39
|
+
readonly sourceOverrideDescriptors?: readonly SourceOverrideDescriptor[];
|
|
40
|
+
readonly relations?: readonly AssetRelation[];
|
|
41
|
+
readonly diagnostics?: readonly CatalogDiagnostic[];
|
|
42
|
+
/** Producer-owned projection axes; never infer these from locators. */
|
|
43
|
+
readonly subject?: CatalogSubject;
|
|
44
|
+
readonly execution?: CookExecution;
|
|
45
|
+
readonly lifecycle?: CatalogLifecycle;
|
|
46
|
+
readonly projection?: CatalogProjection;
|
|
47
|
+
/** Complete producer publication tuple used by Scene publication fences. */
|
|
48
|
+
readonly publication?: AssetPublicationEnvelope;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/** Build the canonical row for an inline asset without inventing producer facts. */
|
|
52
|
+
export function createInlineCatalogRecord(
|
|
53
|
+
envelope: AssetEnvelope<Asset>,
|
|
54
|
+
name: string,
|
|
55
|
+
): CatalogRecord {
|
|
56
|
+
return {
|
|
57
|
+
packageUrl: '',
|
|
58
|
+
kind: envelope.payload.kind,
|
|
59
|
+
authoring: authoringCapabilityForAssetKind(envelope.payload.kind),
|
|
60
|
+
name,
|
|
61
|
+
...(envelope.refs.length > 0 ? { refs: envelope.refs.map((ref) => ref.guid) } : {}),
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
type CatalogFetch = (
|
|
66
|
+
input: string,
|
|
67
|
+
init?: { readonly cache?: 'no-store' },
|
|
68
|
+
) => PromiseLike<{
|
|
69
|
+
readonly ok: boolean;
|
|
70
|
+
json(): Promise<unknown>;
|
|
71
|
+
}>;
|
|
72
|
+
|
|
73
|
+
function parseError(
|
|
74
|
+
expected: string,
|
|
75
|
+
detail?: object,
|
|
76
|
+
hint = ASSET_ERROR_HINTS['asset-parse-failed'],
|
|
77
|
+
): AssetError {
|
|
78
|
+
return new AssetError({
|
|
79
|
+
code: 'asset-parse-failed',
|
|
80
|
+
expected,
|
|
81
|
+
hint,
|
|
82
|
+
...(detail === undefined ? {} : { detail: detail as never }),
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function sameRevision(left: ResourceRevision, right: ResourceRevision): boolean {
|
|
87
|
+
return (
|
|
88
|
+
left.digest === right.digest &&
|
|
89
|
+
left.observedAt === right.observedAt &&
|
|
90
|
+
left.rootId === right.rootId
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function checkExpectedRevision(
|
|
95
|
+
records: readonly CatalogRecord[],
|
|
96
|
+
expectedRevision: ResourceRevision | undefined,
|
|
97
|
+
): AssetError | undefined {
|
|
98
|
+
if (expectedRevision === undefined || records.length === 0) return undefined;
|
|
99
|
+
const actualRevisions = records.flatMap((record) =>
|
|
100
|
+
record.revision === undefined ? [] : [record.revision],
|
|
101
|
+
);
|
|
102
|
+
if (
|
|
103
|
+
actualRevisions.length > 0 &&
|
|
104
|
+
actualRevisions.every((revision) => sameRevision(revision, expectedRevision))
|
|
105
|
+
) {
|
|
106
|
+
return undefined;
|
|
107
|
+
}
|
|
108
|
+
return parseError(
|
|
109
|
+
'every catalog entry to carry the expected producer revision',
|
|
110
|
+
{ expectedRevision, actualRevisions },
|
|
111
|
+
'restore a verified catalog revision before applying the source',
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/** Resolve a catalog entry URL against the configured pack-index URL. */
|
|
116
|
+
export function resolveCatalogAssetUrl(registry: AssetRegistry, packageUrl: string): string {
|
|
117
|
+
const packIndexUrl = registry.packIndexUrl;
|
|
118
|
+
if (packIndexUrl === undefined) return packageUrl;
|
|
119
|
+
|
|
120
|
+
try {
|
|
121
|
+
const baseUrl = new URL(packIndexUrl, globalThis.location?.href).href;
|
|
122
|
+
return new URL(packageUrl, baseUrl).href;
|
|
123
|
+
} catch {
|
|
124
|
+
return packageUrl;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function isRawSourceLocator(packageUrl: string): boolean {
|
|
129
|
+
const path = packageUrl.split(/[?#]/, 1)[0]?.toLowerCase() ?? packageUrl.toLowerCase();
|
|
130
|
+
if (path.endsWith('.pack.json')) return false;
|
|
131
|
+
return (
|
|
132
|
+
/\.(bin|fbx|gltf|glb|hdr|jpg|jpeg|png|wav|mp3|ogg|ttf|otf|woff|woff2|svg)$/.test(path) ||
|
|
133
|
+
path.endsWith('.particle-effect.json')
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/** Parse the shared pack-index/catalog wire shape without loading payloads. */
|
|
138
|
+
export function parseCatalog(
|
|
139
|
+
raw: unknown,
|
|
140
|
+
resolveUrl: (packageUrl: string) => string = (packageUrl) => packageUrl,
|
|
141
|
+
expectedRevision?: ResourceRevision,
|
|
142
|
+
expectedScope?: Pick<RuntimeAssetBinding, 'scopeId' | 'generation'>,
|
|
143
|
+
): Result<Map<string, CatalogRecord>, AssetError> {
|
|
144
|
+
let rows: readonly unknown[];
|
|
145
|
+
if (expectedScope !== undefined) {
|
|
146
|
+
if (raw === null || typeof raw !== 'object' || Array.isArray(raw)) {
|
|
147
|
+
return err(
|
|
148
|
+
parseError(
|
|
149
|
+
'scoped catalog snapshot to be an object with schema, scopeId, generation, authority, and entries',
|
|
150
|
+
),
|
|
151
|
+
);
|
|
152
|
+
}
|
|
153
|
+
const snapshot = raw as Record<string, unknown>;
|
|
154
|
+
if (
|
|
155
|
+
snapshot.schemaVersion !== 'runtime-catalog-snapshot-v1' ||
|
|
156
|
+
typeof snapshot.scopeId !== 'string' ||
|
|
157
|
+
typeof snapshot.generation !== 'number' ||
|
|
158
|
+
!Number.isSafeInteger(snapshot.generation) ||
|
|
159
|
+
!Array.isArray(snapshot.entries)
|
|
160
|
+
) {
|
|
161
|
+
return err(parseError('scoped catalog snapshot to satisfy its runtime schema'));
|
|
162
|
+
}
|
|
163
|
+
if (
|
|
164
|
+
snapshot.scopeId !== expectedScope.scopeId ||
|
|
165
|
+
snapshot.generation !== expectedScope.generation
|
|
166
|
+
) {
|
|
167
|
+
return err(
|
|
168
|
+
parseError('scoped catalog snapshot to match the active scope and generation', {
|
|
169
|
+
expectedScope,
|
|
170
|
+
actualScope: { scopeId: snapshot.scopeId, generation: snapshot.generation },
|
|
171
|
+
}),
|
|
172
|
+
);
|
|
173
|
+
}
|
|
174
|
+
if (snapshot.authority !== 'authoritative') {
|
|
175
|
+
return err(
|
|
176
|
+
parseError(
|
|
177
|
+
'scoped catalog snapshot authority to be authoritative before identity lookup',
|
|
178
|
+
{ authority: snapshot.authority, diagnostics: snapshot.diagnostics },
|
|
179
|
+
'repair the active game catalog before loading assets',
|
|
180
|
+
),
|
|
181
|
+
);
|
|
182
|
+
}
|
|
183
|
+
rows = snapshot.entries;
|
|
184
|
+
} else if (Array.isArray(raw)) {
|
|
185
|
+
rows = raw;
|
|
186
|
+
} else {
|
|
187
|
+
return err(parseError('pack-index.json to be a JSON array'));
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
const catalog = new Map<string, CatalogRecord>();
|
|
191
|
+
for (const item of rows) {
|
|
192
|
+
if (item === null || typeof item !== 'object') {
|
|
193
|
+
return err(parseError('each catalog row to be an object'));
|
|
194
|
+
}
|
|
195
|
+
const rawRow = item as Record<string, unknown>;
|
|
196
|
+
const legacyLocator = ['relative', 'Url'].join('');
|
|
197
|
+
if (
|
|
198
|
+
legacyLocator in rawRow ||
|
|
199
|
+
'metadata' in rawRow ||
|
|
200
|
+
'compression' in rawRow ||
|
|
201
|
+
'artifacts' in rawRow ||
|
|
202
|
+
'assetCodec' in rawRow ||
|
|
203
|
+
'contentEncoding' in rawRow
|
|
204
|
+
) {
|
|
205
|
+
return err(parseError('catalog rows to expose navigation fields only'));
|
|
206
|
+
}
|
|
207
|
+
if (
|
|
208
|
+
typeof rawRow.guid !== 'string' ||
|
|
209
|
+
rawRow.guid.length === 0 ||
|
|
210
|
+
typeof rawRow.packageUrl !== 'string' ||
|
|
211
|
+
rawRow.packageUrl.length === 0 ||
|
|
212
|
+
typeof rawRow.kind !== 'string' ||
|
|
213
|
+
rawRow.kind.length === 0
|
|
214
|
+
) {
|
|
215
|
+
return err(parseError('each catalog row to contain guid, packageUrl, and kind strings'));
|
|
216
|
+
}
|
|
217
|
+
if (isRawSourceLocator(rawRow.packageUrl)) {
|
|
218
|
+
return err(
|
|
219
|
+
parseError(`catalog packageUrl ${rawRow.packageUrl} to identify a cooked package`),
|
|
220
|
+
);
|
|
221
|
+
}
|
|
222
|
+
const guid = rawRow.guid.toLowerCase();
|
|
223
|
+
if (catalog.has(guid)) return err(parseError(`catalog GUID ${rawRow.guid} to be unique`));
|
|
224
|
+
const refs = rawRow.refs;
|
|
225
|
+
if (
|
|
226
|
+
refs !== undefined &&
|
|
227
|
+
(!Array.isArray(refs) || !refs.every((ref) => typeof ref === 'string'))
|
|
228
|
+
) {
|
|
229
|
+
return err(parseError(`catalog refs for GUID ${rawRow.guid} to be a string array`));
|
|
230
|
+
}
|
|
231
|
+
if (
|
|
232
|
+
rawRow.sourceOverrides !== undefined &&
|
|
233
|
+
(rawRow.sourceOverrides === null ||
|
|
234
|
+
typeof rawRow.sourceOverrides !== 'object' ||
|
|
235
|
+
Array.isArray(rawRow.sourceOverrides))
|
|
236
|
+
) {
|
|
237
|
+
return err(parseError(`catalog sourceOverrides for GUID ${rawRow.guid} to be an object`));
|
|
238
|
+
}
|
|
239
|
+
if (
|
|
240
|
+
rawRow.sourceOverrideDescriptors !== undefined &&
|
|
241
|
+
!Array.isArray(rawRow.sourceOverrideDescriptors)
|
|
242
|
+
) {
|
|
243
|
+
return err(
|
|
244
|
+
parseError(`catalog sourceOverrideDescriptors for GUID ${rawRow.guid} to be an array`),
|
|
245
|
+
);
|
|
246
|
+
}
|
|
247
|
+
let resolvedUrl: string;
|
|
248
|
+
try {
|
|
249
|
+
resolvedUrl = resolveUrl(rawRow.packageUrl);
|
|
250
|
+
} catch (error) {
|
|
251
|
+
return err(
|
|
252
|
+
parseError(`catalog entry ${rawRow.guid} to resolve its packageUrl`, {
|
|
253
|
+
packageUrl: rawRow.packageUrl,
|
|
254
|
+
reason: error instanceof Error ? error.message : String(error),
|
|
255
|
+
}),
|
|
256
|
+
);
|
|
257
|
+
}
|
|
258
|
+
const row: CatalogRecord = {
|
|
259
|
+
packageUrl: resolvedUrl,
|
|
260
|
+
kind: rawRow.kind,
|
|
261
|
+
...(rawRow.authoring !== undefined
|
|
262
|
+
? { authoring: rawRow.authoring as AssetAuthoringCapability }
|
|
263
|
+
: {}),
|
|
264
|
+
...(typeof rawRow.name === 'string' ? { name: rawRow.name } : {}),
|
|
265
|
+
...(typeof rawRow.sourcePath === 'string' ? { sourcePath: rawRow.sourcePath } : {}),
|
|
266
|
+
...(refs !== undefined ? { refs: refs as readonly string[] } : {}),
|
|
267
|
+
...(typeof rawRow.cookReceiptUrl === 'string'
|
|
268
|
+
? { cookReceiptUrl: rawRow.cookReceiptUrl }
|
|
269
|
+
: {}),
|
|
270
|
+
...(typeof rawRow.packageId === 'string' ? { packageId: rawRow.packageId } : {}),
|
|
271
|
+
...(rawRow.provenance !== undefined
|
|
272
|
+
? { provenance: rawRow.provenance as ProviderProvenance }
|
|
273
|
+
: {}),
|
|
274
|
+
...(rawRow.revision !== undefined ? { revision: rawRow.revision as ResourceRevision } : {}),
|
|
275
|
+
...(typeof rawRow.sourceKey === 'string' ? { sourceKey: rawRow.sourceKey } : {}),
|
|
276
|
+
...(typeof rawRow.sourceIndex === 'number' ? { sourceIndex: rawRow.sourceIndex } : {}),
|
|
277
|
+
...(rawRow.sourceOverrides !== undefined
|
|
278
|
+
? { sourceOverrides: rawRow.sourceOverrides as SourceOverrideMap }
|
|
279
|
+
: {}),
|
|
280
|
+
...(rawRow.sourceOverrideDescriptors !== undefined
|
|
281
|
+
? {
|
|
282
|
+
sourceOverrideDescriptors:
|
|
283
|
+
rawRow.sourceOverrideDescriptors as readonly SourceOverrideDescriptor[],
|
|
284
|
+
}
|
|
285
|
+
: {}),
|
|
286
|
+
...(Array.isArray(rawRow.relations)
|
|
287
|
+
? { relations: rawRow.relations as readonly AssetRelation[] }
|
|
288
|
+
: {}),
|
|
289
|
+
...(Array.isArray(rawRow.diagnostics)
|
|
290
|
+
? { diagnostics: rawRow.diagnostics as readonly CatalogDiagnostic[] }
|
|
291
|
+
: {}),
|
|
292
|
+
...(rawRow.subject === 'internal-asset' || rawRow.subject === 'imported-output'
|
|
293
|
+
? { subject: rawRow.subject }
|
|
294
|
+
: {}),
|
|
295
|
+
...(rawRow.execution === 'direct' || rawRow.execution === 'cooked'
|
|
296
|
+
? { execution: rawRow.execution }
|
|
297
|
+
: {}),
|
|
298
|
+
...(rawRow.lifecycle === 'missing' ||
|
|
299
|
+
rawRow.lifecycle === 'cooking' ||
|
|
300
|
+
rawRow.lifecycle === 'current' ||
|
|
301
|
+
rawRow.lifecycle === 'stale' ||
|
|
302
|
+
rawRow.lifecycle === 'failed'
|
|
303
|
+
? { lifecycle: rawRow.lifecycle }
|
|
304
|
+
: {}),
|
|
305
|
+
...(rawRow.projection !== undefined
|
|
306
|
+
? { projection: rawRow.projection as CatalogProjection }
|
|
307
|
+
: {}),
|
|
308
|
+
...(rawRow.publication !== undefined
|
|
309
|
+
? { publication: rawRow.publication as AssetPublicationEnvelope }
|
|
310
|
+
: {}),
|
|
311
|
+
};
|
|
312
|
+
catalog.set(guid, row);
|
|
313
|
+
}
|
|
314
|
+
const revisionError = checkExpectedRevision([...catalog.values()], expectedRevision);
|
|
315
|
+
if (revisionError !== undefined) return err(revisionError);
|
|
316
|
+
return ok(catalog);
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
/** Fetch and parse a catalog using the shared JSON/error boundary. */
|
|
320
|
+
export async function fetchCatalog(
|
|
321
|
+
url: string,
|
|
322
|
+
fetch: CatalogFetch,
|
|
323
|
+
resolveUrl?: (packageUrl: string) => string,
|
|
324
|
+
expectedRevision?: ResourceRevision,
|
|
325
|
+
expectedScope?: Pick<RuntimeAssetBinding, 'scopeId' | 'generation'>,
|
|
326
|
+
requestInit?: { readonly cache?: 'no-store' },
|
|
327
|
+
): Promise<Result<Map<string, CatalogRecord>, AssetError>> {
|
|
328
|
+
let raw: unknown;
|
|
329
|
+
try {
|
|
330
|
+
const response = requestInit === undefined ? await fetch(url) : await fetch(url, requestInit);
|
|
331
|
+
if (!response.ok) {
|
|
332
|
+
return err(
|
|
333
|
+
new AssetError({
|
|
334
|
+
code: 'asset-fetch-failed',
|
|
335
|
+
expected: `fetch(${url}) to return ok`,
|
|
336
|
+
hint: ASSET_ERROR_HINTS['asset-fetch-failed'],
|
|
337
|
+
}),
|
|
338
|
+
);
|
|
339
|
+
}
|
|
340
|
+
raw = await response.json();
|
|
341
|
+
} catch {
|
|
342
|
+
return err(
|
|
343
|
+
new AssetError({
|
|
344
|
+
code: 'asset-fetch-failed',
|
|
345
|
+
expected: `fetch(${url}) to succeed`,
|
|
346
|
+
hint: ASSET_ERROR_HINTS['asset-fetch-failed'],
|
|
347
|
+
}),
|
|
348
|
+
);
|
|
349
|
+
}
|
|
350
|
+
return parseCatalog(raw, resolveUrl, expectedRevision, expectedScope);
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
export function fetchPackIndex(
|
|
354
|
+
registry: AssetRegistry,
|
|
355
|
+
): Promise<Result<Map<string, CatalogRecord>, AssetError>> {
|
|
356
|
+
const expectedScope =
|
|
357
|
+
registry.runtimeBinding !== undefined &&
|
|
358
|
+
registry.packIndexUrl === registry.runtimeBinding.catalogUrl
|
|
359
|
+
? registry.runtimeBinding
|
|
360
|
+
: undefined;
|
|
361
|
+
return fetchCatalog(
|
|
362
|
+
registry.packIndexUrl as string,
|
|
363
|
+
globalThis.fetch,
|
|
364
|
+
(packageUrl) => resolveCatalogAssetUrl(registry, packageUrl),
|
|
365
|
+
undefined,
|
|
366
|
+
expectedScope,
|
|
367
|
+
{ cache: 'no-store' },
|
|
368
|
+
);
|
|
369
|
+
}
|