@forgeax/engine-import 0.1.23 → 0.1.25
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 +5 -5
- package/dist/__tests__/scriptable-pack-build.unit.test.d.ts +2 -0
- package/dist/__tests__/scriptable-pack-build.unit.test.d.ts.map +1 -0
- package/dist/build-production.d.ts.map +1 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +284 -60
- package/dist/index.mjs.map +1 -1
- package/dist/{parameterized-scriptable-pack.d.ts → scriptable-pack-build.d.ts} +20 -15
- package/dist/scriptable-pack-build.d.ts.map +1 -0
- package/dist/scriptable-pack-host.d.ts +15 -13
- package/dist/scriptable-pack-host.d.ts.map +1 -1
- package/dist/scriptable-pack.d.ts +2 -1
- package/dist/scriptable-pack.d.ts.map +1 -1
- package/dist/source-package-publication.d.ts +7 -0
- package/dist/source-package-publication.d.ts.map +1 -1
- package/package.json +8 -8
- package/src/__tests__/{parameterized-scriptable-pack.unit.test.ts → scriptable-pack-build.unit.test.ts} +11 -14
- package/src/__tests__/scriptable-pack-host.unit.test.ts +53 -5
- package/src/__tests__/scriptable-pack-output-producers.unit.test.ts +4 -5
- package/src/__tests__/source-package-publication.integration.test.ts +141 -0
- package/src/build-production.ts +45 -50
- package/src/index.ts +17 -16
- package/src/{parameterized-scriptable-pack.ts → scriptable-pack-build.ts} +91 -27
- package/src/scriptable-pack-host.ts +48 -40
- package/src/scriptable-pack.ts +2 -1
- package/src/source-package-publication.ts +242 -10
- package/dist/__tests__/parameterized-scriptable-pack.unit.test.d.ts +0 -2
- package/dist/__tests__/parameterized-scriptable-pack.unit.test.d.ts.map +0 -1
- package/dist/parameterized-scriptable-pack.d.ts.map +0 -1
package/dist/index.mjs
CHANGED
|
@@ -3,20 +3,21 @@ export { IMPORT_ERROR_HINTS, ImportError } from '@forgeax/engine-types';
|
|
|
3
3
|
import { resolve, dirname, isAbsolute, relative } from 'path';
|
|
4
4
|
import { resolveAssetSource, finalizePackageTransportSource, packageTransportRevision, catalogSourcePathFor, buildCatalogProjection, projectPackageCatalog, createRuntimePackPublication, metaPathForGuid } from '@forgeax/engine-pack/build';
|
|
5
5
|
import { AssetGuid as AssetGuid$1, PackageId as PackageId$1 } from '@forgeax/engine-pack/guid';
|
|
6
|
-
import { resolvePackParameterValues, PackageId, isValidPackSourceKey, AssetGuid,
|
|
7
|
-
import {
|
|
6
|
+
import { resolvePackParameterValues, PackageId, isValidPackSourceKey, AssetGuid, parsePackSourceJson, projectDirectPackJson, isScriptablePackAssetKind, projectScriptablePackSceneComponents, resolvePackParameterInheritance } from '@forgeax/engine-pack/source';
|
|
7
|
+
import { loadScriptablePack } from '@forgeax/engine-pack/source-node';
|
|
8
8
|
import { stat, readFile, mkdir, writeFile, rename, rm, readdir } from 'fs/promises';
|
|
9
|
-
import { createAcceptedPublication, ddcOutputDigest,
|
|
9
|
+
import { createAcceptedPublication, ddcOutputDigest, DdcLifecycle, DdcGenerationSession } from '@forgeax/engine-ddc';
|
|
10
10
|
import { deriveVertexLayoutProjection, normalizeMeshPayload } from '@forgeax/engine-geometry';
|
|
11
11
|
import { BUILTIN_MESH_ASSETS } from '@forgeax/engine-pack/builtin';
|
|
12
12
|
import { NativeCookerRegistry } from '@forgeax/engine-pack/native-cooker';
|
|
13
|
-
import { isEngineMaterial } from '@forgeax/engine-shader';
|
|
13
|
+
import { isEngineMaterial, DEFAULT_STANDARD_SURFACE_MODULE } from '@forgeax/engine-shader';
|
|
14
14
|
import { externalizeSceneAsset } from '@forgeax/engine-scene';
|
|
15
15
|
import { sha256 } from '@noble/hashes/sha2.js';
|
|
16
16
|
import { bytesToHex } from '@noble/hashes/utils.js';
|
|
17
17
|
import { MESH_BIN_HEADER_V4_BYTES, writeMeshBinHeader } from '@forgeax/engine-pack/mesh-bin-contract';
|
|
18
|
-
import {
|
|
18
|
+
import { createHash, randomUUID } from 'crypto';
|
|
19
19
|
import { validatePack, isScriptablePackAssetKind as isScriptablePackAssetKind$1 } from '@forgeax/engine-pack';
|
|
20
|
+
import { canonicalDdcJson } from '@forgeax/engine-ddc/key';
|
|
20
21
|
|
|
21
22
|
// src/index.ts
|
|
22
23
|
function invalidProduct(field) {
|
|
@@ -784,6 +785,14 @@ function record(value) {
|
|
|
784
785
|
function isAsset(value) {
|
|
785
786
|
return record(value) && typeof value.kind === "string" && isScriptablePackAssetKind(value.kind);
|
|
786
787
|
}
|
|
788
|
+
function needsMaterialCook(asset) {
|
|
789
|
+
if (asset.kind !== "material" || !Array.isArray(asset.passes)) return false;
|
|
790
|
+
return asset.passes.some((pass) => {
|
|
791
|
+
const module = pass.program.module;
|
|
792
|
+
const surface = pass.program.moduleSlots?.surface;
|
|
793
|
+
return surface !== void 0 && surface !== DEFAULT_STANDARD_SURFACE_MODULE && (module === "forgeax_material::standard" || module === "forgeax::default-standard-pbr" || module === "forgeax_material::pbr-skin" || module === "forgeax::pbr-skin" || module === "forgeax::default-standard-pbr-skin");
|
|
794
|
+
});
|
|
795
|
+
}
|
|
787
796
|
function clone(value) {
|
|
788
797
|
return structuredClone(value);
|
|
789
798
|
}
|
|
@@ -923,7 +932,7 @@ function errorCode(value) {
|
|
|
923
932
|
function normalizedGuidSet(value) {
|
|
924
933
|
return value === void 0 ? void 0 : new Set([...value].map((guid) => guid.toLowerCase()));
|
|
925
934
|
}
|
|
926
|
-
async function
|
|
935
|
+
async function buildScriptablePack(options) {
|
|
927
936
|
const subjectPackageId = options.subjectPackageId ?? options.definition.packageId;
|
|
928
937
|
const availableGuids = normalizedGuidSet(options.availableGuids);
|
|
929
938
|
const observed = observedReader(options.assetSource);
|
|
@@ -947,8 +956,8 @@ async function buildParameterizedScriptablePack(options) {
|
|
|
947
956
|
);
|
|
948
957
|
} else if (options.subjectPackageId !== void 0 && PackageId.format(options.subjectPackageId).toLowerCase() !== PackageId.format(options.definition.packageId).toLowerCase()) {
|
|
949
958
|
return err({
|
|
950
|
-
code: "pack-parent-
|
|
951
|
-
expected: "a
|
|
959
|
+
code: "pack-parent-has-no-parameters",
|
|
960
|
+
expected: "a ScriptablePack source with parameters for an independent instance packageId",
|
|
952
961
|
hint: "use clone for a zero-parameter Pack instead of building it as an instance",
|
|
953
962
|
detail: {
|
|
954
963
|
sourcePath: options.sourcePath,
|
|
@@ -1008,6 +1017,9 @@ async function buildParameterizedScriptablePack(options) {
|
|
|
1008
1017
|
const imported = [];
|
|
1009
1018
|
const stagedOutputs = [];
|
|
1010
1019
|
const localGuids = /* @__PURE__ */ new Set();
|
|
1020
|
+
const materialCookerRegistry = new NativeCookerRegistry();
|
|
1021
|
+
for (const cooker of options.cookers ?? []) materialCookerRegistry.register(cooker);
|
|
1022
|
+
const nativeFingerprints = /* @__PURE__ */ new Map();
|
|
1011
1023
|
for (const sourceKey of Object.keys(built.value).sort()) {
|
|
1012
1024
|
if (!isValidPackSourceKey(sourceKey))
|
|
1013
1025
|
return err(sourceKeyFailure(options.sourcePath, sourceKey));
|
|
@@ -1083,12 +1095,40 @@ async function buildParameterizedScriptablePack(options) {
|
|
|
1083
1095
|
const invalidProduct2 = productError(options.sourcePath, sourceKey, producer, produced.value);
|
|
1084
1096
|
if (invalidProduct2 !== void 0) return err(invalidProduct2);
|
|
1085
1097
|
const product2 = produced.value;
|
|
1098
|
+
let payload = product2.payload;
|
|
1099
|
+
let artifacts2 = product2.artifacts;
|
|
1100
|
+
if (needsMaterialCook(asset) && materialCookerRegistry.get("material") !== void 0) {
|
|
1101
|
+
const cooked = await materialCookerRegistry.runDraft("material", {
|
|
1102
|
+
guid,
|
|
1103
|
+
source: asset,
|
|
1104
|
+
sourceKey,
|
|
1105
|
+
sourcePath: options.sourcePath,
|
|
1106
|
+
refs: product2.refs.map((reference) => reference.guid)
|
|
1107
|
+
});
|
|
1108
|
+
if (!cooked.ok) return err(cooked.error);
|
|
1109
|
+
if (cooked.value.guid.toLowerCase() !== normalizedGuid) {
|
|
1110
|
+
return err({
|
|
1111
|
+
code: "pack-source-output-invalid",
|
|
1112
|
+
expected: "the authored material cooker to preserve the derived AssetGuid",
|
|
1113
|
+
hint: "repair the native material cooker output GUID and rebuild the Pack",
|
|
1114
|
+
detail: {
|
|
1115
|
+
sourcePath: options.sourcePath,
|
|
1116
|
+
sourceKey,
|
|
1117
|
+
expectedGuid: guid,
|
|
1118
|
+
actualGuid: cooked.value.guid
|
|
1119
|
+
}
|
|
1120
|
+
});
|
|
1121
|
+
}
|
|
1122
|
+
payload = cooked.value.payload;
|
|
1123
|
+
artifacts2 = cooked.value.artifacts;
|
|
1124
|
+
nativeFingerprints.set(sourceKey, cooked.value.inputFingerprint);
|
|
1125
|
+
}
|
|
1086
1126
|
imported.push({
|
|
1087
1127
|
guid,
|
|
1088
1128
|
kind: asset.kind,
|
|
1089
|
-
payload
|
|
1129
|
+
payload,
|
|
1090
1130
|
refs: product2.refs,
|
|
1091
|
-
artifacts:
|
|
1131
|
+
artifacts: artifacts2
|
|
1092
1132
|
});
|
|
1093
1133
|
stagedOutputs.push({
|
|
1094
1134
|
guid: AssetGuid.derive(subjectPackageId, sourceKey),
|
|
@@ -1119,7 +1159,7 @@ async function buildParameterizedScriptablePack(options) {
|
|
|
1119
1159
|
digest: read.digest
|
|
1120
1160
|
})
|
|
1121
1161
|
);
|
|
1122
|
-
const
|
|
1162
|
+
const authoredInputFingerprint = await digest({
|
|
1123
1163
|
packageId: PackageId.format(subjectPackageId),
|
|
1124
1164
|
sourcePath: options.sourcePath,
|
|
1125
1165
|
sourceClosure: options.sourceClosure ?? [],
|
|
@@ -1129,9 +1169,15 @@ async function buildParameterizedScriptablePack(options) {
|
|
|
1129
1169
|
usage,
|
|
1130
1170
|
digest: evidenceDigest
|
|
1131
1171
|
})),
|
|
1132
|
-
authoringContractVersion: options.authoringContractVersion ?? "
|
|
1172
|
+
authoringContractVersion: options.authoringContractVersion ?? "scriptable-pack/1",
|
|
1133
1173
|
producerVersions: options.outputs.versions()
|
|
1134
1174
|
});
|
|
1175
|
+
const inputFingerprint = nativeFingerprints.size === 0 ? authoredInputFingerprint : await digest({
|
|
1176
|
+
sourceRevision: authoredInputFingerprint,
|
|
1177
|
+
nativeCookers: [...nativeFingerprints.entries()].sort(
|
|
1178
|
+
([left], [right]) => left.localeCompare(right)
|
|
1179
|
+
)
|
|
1180
|
+
});
|
|
1135
1181
|
const refs = imported.flatMap((asset) => asset.refs);
|
|
1136
1182
|
const artifacts = Object.fromEntries(
|
|
1137
1183
|
imported.flatMap(
|
|
@@ -1186,7 +1232,7 @@ function stagedSource(staged, fallback) {
|
|
|
1186
1232
|
}
|
|
1187
1233
|
};
|
|
1188
1234
|
}
|
|
1189
|
-
async function
|
|
1235
|
+
async function buildScriptablePackWorklist(options) {
|
|
1190
1236
|
const orderedSubjects = [...options.subjects].sort(
|
|
1191
1237
|
(left, right) => left.sourcePath.localeCompare(right.sourcePath)
|
|
1192
1238
|
);
|
|
@@ -1205,7 +1251,7 @@ async function buildParameterizedScriptablePackWorklist(options) {
|
|
|
1205
1251
|
let progress = false;
|
|
1206
1252
|
const waiting = /* @__PURE__ */ new Set();
|
|
1207
1253
|
for (const [key, subject] of pending) {
|
|
1208
|
-
const result = await
|
|
1254
|
+
const result = await buildScriptablePack({
|
|
1209
1255
|
definition: subject.definition,
|
|
1210
1256
|
sourcePath: subject.sourcePath,
|
|
1211
1257
|
...subject.subjectPackageId === void 0 ? {} : { subjectPackageId: subject.subjectPackageId },
|
|
@@ -1213,6 +1259,7 @@ async function buildParameterizedScriptablePackWorklist(options) {
|
|
|
1213
1259
|
...subject.inheritedValues === void 0 ? {} : { inheritedValues: subject.inheritedValues },
|
|
1214
1260
|
...subject.sourceClosure === void 0 ? {} : { sourceClosure: subject.sourceClosure },
|
|
1215
1261
|
outputs: options.outputs,
|
|
1262
|
+
...options.cookers === void 0 ? {} : { cookers: options.cookers },
|
|
1216
1263
|
assetSource: stagedSource(staged, options.assetSource),
|
|
1217
1264
|
availableGuids: /* @__PURE__ */ new Set([...availableGuids, ...staged.keys()]),
|
|
1218
1265
|
deferReferenceValidation: true
|
|
@@ -2113,7 +2160,7 @@ async function declaredPackExternalOutputs(declarations, cookers = [], requiredG
|
|
|
2113
2160
|
}
|
|
2114
2161
|
if (declaration.format !== "pack.json") continue;
|
|
2115
2162
|
if (declaration.value.schemaVersion === "3.0.0") {
|
|
2116
|
-
const parsed =
|
|
2163
|
+
const parsed = parsePackSourceJson(declaration.value);
|
|
2117
2164
|
if (!parsed.ok || parsed.value.format !== "direct") continue;
|
|
2118
2165
|
const projected = projectDirectPackJson(parsed.value);
|
|
2119
2166
|
if (!projected.ok) continue;
|
|
@@ -2190,6 +2237,8 @@ async function readCookedAuthoredPack(authoredPack, cookers = [], sourcePath) {
|
|
|
2190
2237
|
continue;
|
|
2191
2238
|
}
|
|
2192
2239
|
if (isEngineOwnedMaterial(asset)) {
|
|
2240
|
+
hasCookedAsset = true;
|
|
2241
|
+
refsByGuid.set(asset.guid.toLowerCase(), [...asset.refs]);
|
|
2193
2242
|
assets.push({
|
|
2194
2243
|
guid: asset.guid,
|
|
2195
2244
|
kind: asset.kind,
|
|
@@ -2432,7 +2481,7 @@ async function prepareDirectPackTransport(input) {
|
|
|
2432
2481
|
projectImportProductForBuild(raw.product),
|
|
2433
2482
|
input.policy
|
|
2434
2483
|
);
|
|
2435
|
-
const facts2 =
|
|
2484
|
+
const facts2 = projectScriptablePackPublication(raw);
|
|
2436
2485
|
if (!facts2.ok) return facts2;
|
|
2437
2486
|
const displaySourcePath2 = input.displaySourcePath ?? input.sourcePath;
|
|
2438
2487
|
const revision2 = await scriptablePackResourceRevision(displaySourcePath2, raw.inputFingerprint, [
|
|
@@ -2463,7 +2512,7 @@ async function prepareDirectPackTransport(input) {
|
|
|
2463
2512
|
};
|
|
2464
2513
|
const outputs = createStandardAssetOutputProducerRegistry();
|
|
2465
2514
|
outputs.register(createPreExternalizedSceneAssetOutputProducer());
|
|
2466
|
-
const built = await
|
|
2515
|
+
const built = await buildScriptablePack({
|
|
2467
2516
|
definition,
|
|
2468
2517
|
sourcePath: input.sourcePath,
|
|
2469
2518
|
outputs,
|
|
@@ -2526,7 +2575,7 @@ async function prepareDirectPackTransport(input) {
|
|
|
2526
2575
|
projectImportProductForBuild(product.product),
|
|
2527
2576
|
input.policy
|
|
2528
2577
|
);
|
|
2529
|
-
const facts =
|
|
2578
|
+
const facts = projectScriptablePackPublication(product);
|
|
2530
2579
|
if (!facts.ok) return facts;
|
|
2531
2580
|
const displaySourcePath = input.displaySourcePath ?? input.sourcePath;
|
|
2532
2581
|
const revision = await scriptablePackResourceRevision(
|
|
@@ -2556,7 +2605,7 @@ async function prepareLegacyPackTransport(authoredPack, cookers, policyFor, sour
|
|
|
2556
2605
|
finalized: await finalizePackageTransportSource(cooked.logicalPackage, policyFor(firstGuid))
|
|
2557
2606
|
};
|
|
2558
2607
|
}
|
|
2559
|
-
async function
|
|
2608
|
+
async function materializePreparedScriptablePack(prepared, paths, sink) {
|
|
2560
2609
|
const { product, finalized } = prepared;
|
|
2561
2610
|
await sink.writePackage(paths.packagePath, JSON.stringify(finalized.pack));
|
|
2562
2611
|
for (const artifact of finalized.artifacts) {
|
|
@@ -2583,7 +2632,7 @@ async function materializePreparedParameterizedScriptablePack(prepared, paths, s
|
|
|
2583
2632
|
}
|
|
2584
2633
|
return receipts;
|
|
2585
2634
|
}
|
|
2586
|
-
function
|
|
2635
|
+
function projectScriptablePackPublication(product) {
|
|
2587
2636
|
const assets = new Map(product.product.assets.map((asset) => [asset.guid.toLowerCase(), asset]));
|
|
2588
2637
|
const outputs = [];
|
|
2589
2638
|
for (const staged of product.stagedOutputs) {
|
|
@@ -2592,7 +2641,7 @@ function projectParameterizedPackPublication(product) {
|
|
|
2592
2641
|
if (asset === void 0 || staged.digest === void 0 || staged.sourceKey === void 0) {
|
|
2593
2642
|
return err({
|
|
2594
2643
|
code: "pack-source-output-invalid",
|
|
2595
|
-
expected: `
|
|
2644
|
+
expected: `ScriptablePack publication output ${guid} to include a product, sourceKey, and digest`,
|
|
2596
2645
|
hint: "repair the dynamic Pack output and rebuild the current generation",
|
|
2597
2646
|
detail: { stage: "publication", guid }
|
|
2598
2647
|
});
|
|
@@ -2641,7 +2690,7 @@ function snapshotSourceForStagedOutputs(outputs) {
|
|
|
2641
2690
|
}
|
|
2642
2691
|
};
|
|
2643
2692
|
}
|
|
2644
|
-
function
|
|
2693
|
+
function composeScriptablePackAssetSource(staged, published) {
|
|
2645
2694
|
if (staged === void 0) return published;
|
|
2646
2695
|
if (published === void 0) return staged;
|
|
2647
2696
|
return {
|
|
@@ -2652,10 +2701,10 @@ function composeParameterizedAssetSource(staged, published) {
|
|
|
2652
2701
|
}
|
|
2653
2702
|
};
|
|
2654
2703
|
}
|
|
2655
|
-
async function
|
|
2704
|
+
async function produceScriptablePackProducts(options) {
|
|
2656
2705
|
if (options.sources.length === 0) return ok(/* @__PURE__ */ new Map());
|
|
2657
2706
|
const external = options.declaredExternalOutputs ?? [];
|
|
2658
|
-
const assetSource =
|
|
2707
|
+
const assetSource = composeScriptablePackAssetSource(
|
|
2659
2708
|
snapshotSourceForStagedOutputs(external),
|
|
2660
2709
|
options.assetSource
|
|
2661
2710
|
);
|
|
@@ -2671,13 +2720,14 @@ async function produceParameterizedScriptablePackProducts(options) {
|
|
|
2671
2720
|
...source.inheritedValues === void 0 ? {} : { inheritedValues: source.inheritedValues },
|
|
2672
2721
|
sourceClosure: source.sourceClosure
|
|
2673
2722
|
}));
|
|
2674
|
-
const worklist = await
|
|
2723
|
+
const worklist = await buildScriptablePackWorklist({
|
|
2675
2724
|
subjects: workItems,
|
|
2676
2725
|
outputs: createStandardAssetOutputProducerRegistry(
|
|
2677
2726
|
options.sources.flatMap(
|
|
2678
2727
|
(source) => projectScriptablePackSceneComponents(source.definition.sceneComponents)
|
|
2679
2728
|
)
|
|
2680
2729
|
),
|
|
2730
|
+
...options.cookers === void 0 ? {} : { cookers: options.cookers },
|
|
2681
2731
|
...assetSource === void 0 ? {} : { assetSource },
|
|
2682
2732
|
availableGuids,
|
|
2683
2733
|
...options.incomingRefs === void 0 ? {} : { incomingRefs: options.incomingRefs },
|
|
@@ -2703,7 +2753,7 @@ async function produceParameterizedScriptablePackProducts(options) {
|
|
|
2703
2753
|
projectImportProductForBuild(product.product),
|
|
2704
2754
|
policy
|
|
2705
2755
|
);
|
|
2706
|
-
const facts =
|
|
2756
|
+
const facts = projectScriptablePackPublication(product);
|
|
2707
2757
|
if (!facts.ok) return facts;
|
|
2708
2758
|
const revision = await scriptablePackResourceRevision(
|
|
2709
2759
|
source.displaySourcePath,
|
|
@@ -2801,21 +2851,21 @@ function dynamicFailure(context, value) {
|
|
|
2801
2851
|
const candidate = value !== null && typeof value === "object" ? value : {};
|
|
2802
2852
|
const error = candidate;
|
|
2803
2853
|
throw context.fail({
|
|
2804
|
-
code: typeof error.code === "string" ? error.code : "
|
|
2805
|
-
expected: typeof error.expected === "string" ? error.expected : "the
|
|
2806
|
-
hint: typeof error.hint === "string" ? error.hint : "inspect the
|
|
2854
|
+
code: typeof error.code === "string" ? error.code : "pack-build-failed",
|
|
2855
|
+
expected: typeof error.expected === "string" ? error.expected : "the Pack source generation to produce a valid terminal result",
|
|
2856
|
+
hint: typeof error.hint === "string" ? error.hint : "inspect the Pack source subject and rebuild the current generation",
|
|
2807
2857
|
...error.detail === void 0 ? {} : { detail: error.detail }
|
|
2808
2858
|
});
|
|
2809
2859
|
}
|
|
2810
|
-
function
|
|
2860
|
+
function packCatalogSourcePath(context, sourcePath) {
|
|
2811
2861
|
const projected = context.fsForImport.sourceIdentityFor?.(sourcePath);
|
|
2812
2862
|
const logical = projected === void 0 || isAbsolute(projected) ? relative(context.cwd, sourcePath) : projected;
|
|
2813
2863
|
return canonicalScriptableSourcePath(logical).replaceAll("\\", "/");
|
|
2814
2864
|
}
|
|
2815
|
-
async function
|
|
2865
|
+
async function buildPackSources(context) {
|
|
2816
2866
|
const subjects = /* @__PURE__ */ new Map();
|
|
2817
2867
|
for (const [sourcePath, declaration] of context.inventory.sourceDeclarations) {
|
|
2818
|
-
if (declaration.format === "pack.ts
|
|
2868
|
+
if (declaration.format === "pack.ts") {
|
|
2819
2869
|
const key = PackageId.format(declaration.definition.packageId).toLowerCase();
|
|
2820
2870
|
subjects.set(key, {
|
|
2821
2871
|
kind: "source",
|
|
@@ -2829,7 +2879,7 @@ async function buildParameterizedPackages(context) {
|
|
|
2829
2879
|
if (declaration.format !== "pack.json" || declaration.value.schemaVersion !== "3.0.0") {
|
|
2830
2880
|
continue;
|
|
2831
2881
|
}
|
|
2832
|
-
const parsed =
|
|
2882
|
+
const parsed = parsePackSourceJson(declaration.value);
|
|
2833
2883
|
if (!parsed.ok) dynamicFailure(context, parsed.error);
|
|
2834
2884
|
if (parsed.value.format === "direct") {
|
|
2835
2885
|
subjects.set(PackageId.format(parsed.value.packageId).toLowerCase(), {
|
|
@@ -2881,12 +2931,12 @@ async function buildParameterizedPackages(context) {
|
|
|
2881
2931
|
for (const subject of orderedSubjects) {
|
|
2882
2932
|
if (subject.kind === "source") {
|
|
2883
2933
|
const packageId = PackageId.format(subject.packageId);
|
|
2884
|
-
const loaded = await
|
|
2934
|
+
const loaded = await loadScriptablePack(subject.sourcePath);
|
|
2885
2935
|
if (!loaded.ok) dynamicFailure(context, loaded.error);
|
|
2886
2936
|
if (PackageId.format(loaded.value.packageId) !== packageId) {
|
|
2887
2937
|
dynamicFailure(context, {
|
|
2888
2938
|
code: "pack-source-revision-conflict",
|
|
2889
|
-
expected: "the
|
|
2939
|
+
expected: "the ScriptablePack source packageId to remain fixed during production",
|
|
2890
2940
|
hint: "retry after source writes settle and rebuild the current generation",
|
|
2891
2941
|
detail: {
|
|
2892
2942
|
sourcePath: subject.sourcePath,
|
|
@@ -2897,7 +2947,7 @@ async function buildParameterizedPackages(context) {
|
|
|
2897
2947
|
}
|
|
2898
2948
|
inputs.push({
|
|
2899
2949
|
sourcePath: subject.sourcePath,
|
|
2900
|
-
displaySourcePath:
|
|
2950
|
+
displaySourcePath: packCatalogSourcePath(context, subject.sourcePath),
|
|
2901
2951
|
definition: loaded.value,
|
|
2902
2952
|
sourceClosure: subject.sourceClosure,
|
|
2903
2953
|
publicationGeneration: context.generation,
|
|
@@ -2924,18 +2974,18 @@ async function buildParameterizedPackages(context) {
|
|
|
2924
2974
|
const root = sourceSubject(resolved.value.rootPackageId);
|
|
2925
2975
|
if (root === void 0) {
|
|
2926
2976
|
dynamicFailure(context, {
|
|
2927
|
-
code: "pack-parent-
|
|
2928
|
-
expected: "the instance parent chain to terminate at a
|
|
2929
|
-
hint: "point the instance at a
|
|
2977
|
+
code: "pack-parent-has-no-parameters",
|
|
2978
|
+
expected: "the instance parent chain to terminate at a ScriptablePack source",
|
|
2979
|
+
hint: "point the instance at a ScriptablePack *.pack.ts source with parameters",
|
|
2930
2980
|
detail: { packageId: PackageId.format(subject.packageId) }
|
|
2931
2981
|
});
|
|
2932
2982
|
}
|
|
2933
|
-
const loaded = await
|
|
2983
|
+
const loaded = await loadScriptablePack(root.sourcePath);
|
|
2934
2984
|
if (!loaded.ok) dynamicFailure(context, loaded.error);
|
|
2935
2985
|
if (PackageId.format(loaded.value.packageId) !== PackageId.format(root.packageId)) {
|
|
2936
2986
|
dynamicFailure(context, {
|
|
2937
2987
|
code: "pack-source-revision-conflict",
|
|
2938
|
-
expected: "the
|
|
2988
|
+
expected: "the ScriptablePack parent packageId to remain fixed during production",
|
|
2939
2989
|
hint: "retry after source writes settle and rebuild the current generation",
|
|
2940
2990
|
detail: {
|
|
2941
2991
|
sourcePath: root.sourcePath,
|
|
@@ -2947,7 +2997,7 @@ async function buildParameterizedPackages(context) {
|
|
|
2947
2997
|
const packageId = PackageId.format(subject.packageId);
|
|
2948
2998
|
inputs.push({
|
|
2949
2999
|
sourcePath: subject.sourcePath,
|
|
2950
|
-
displaySourcePath:
|
|
3000
|
+
displaySourcePath: packCatalogSourcePath(context, subject.sourcePath),
|
|
2951
3001
|
definition: loaded.value,
|
|
2952
3002
|
sourceClosure: root.sourceClosure,
|
|
2953
3003
|
subjectPackageId: subject.packageId,
|
|
@@ -2976,9 +3026,10 @@ async function buildParameterizedPackages(context) {
|
|
|
2976
3026
|
}
|
|
2977
3027
|
);
|
|
2978
3028
|
const availableGuids = new Set(requiredGuids.map((guid) => AssetGuid$1.format(guid).toLowerCase()));
|
|
2979
|
-
const built = await
|
|
3029
|
+
const built = await produceScriptablePackProducts({
|
|
2980
3030
|
sources: inputs,
|
|
2981
3031
|
declaredExternalOutputs: externalOutputs,
|
|
3032
|
+
cookers: context.cookers,
|
|
2982
3033
|
availableGuids
|
|
2983
3034
|
});
|
|
2984
3035
|
if (!built.ok) dynamicFailure(context, built.error);
|
|
@@ -2987,9 +3038,9 @@ async function buildParameterizedPackages(context) {
|
|
|
2987
3038
|
const prepared = built.value.get(input.displaySourcePath);
|
|
2988
3039
|
if (prepared === void 0) {
|
|
2989
3040
|
dynamicFailure(context, {
|
|
2990
|
-
code: "
|
|
3041
|
+
code: "pack-build-failed",
|
|
2991
3042
|
expected: "the worklist to return one prepared result per source subject",
|
|
2992
|
-
hint: "rerun
|
|
3043
|
+
hint: "rerun Pack source generation from a clean inventory",
|
|
2993
3044
|
detail: { sourcePath: input.sourcePath }
|
|
2994
3045
|
});
|
|
2995
3046
|
}
|
|
@@ -3105,13 +3156,13 @@ async function emitAuthoredPack(work, guidSeen, entry, availableGuids) {
|
|
|
3105
3156
|
});
|
|
3106
3157
|
}
|
|
3107
3158
|
if (declaration.value.schemaVersion === "3.0.0") {
|
|
3108
|
-
const parsed =
|
|
3159
|
+
const parsed = parsePackSourceJson(declaration.value);
|
|
3109
3160
|
if (!parsed.ok) dynamicFailure(work.context, parsed.error);
|
|
3110
3161
|
if (parsed.value.format !== "direct") {
|
|
3111
3162
|
dynamicFailure(work.context, {
|
|
3112
3163
|
code: "catalog-declaration-missing",
|
|
3113
3164
|
expected: "a direct v3 Pack declaration for an indexed authored output",
|
|
3114
|
-
hint: "instances are built from their
|
|
3165
|
+
hint: "instances are built from their ScriptablePack parent and do not have direct Catalog rows",
|
|
3115
3166
|
detail: { stage: "scan", sourcePath: packPath }
|
|
3116
3167
|
});
|
|
3117
3168
|
}
|
|
@@ -3210,7 +3261,7 @@ async function emitAuthoredPack(work, guidSeen, entry, availableGuids) {
|
|
|
3210
3261
|
guidSeen.add(guid.toLowerCase());
|
|
3211
3262
|
}
|
|
3212
3263
|
}
|
|
3213
|
-
async function
|
|
3264
|
+
async function emitScriptablePack(work, guidSeen, bundle) {
|
|
3214
3265
|
const { input, prepared } = bundle;
|
|
3215
3266
|
const packageId = PackageId.format(input.subjectPackageId ?? input.definition.packageId);
|
|
3216
3267
|
const runtimePublication = createRuntimePackPublication({
|
|
@@ -3385,7 +3436,7 @@ async function emitBuildEntry(work, guidSeen, entry, availableGuids) {
|
|
|
3385
3436
|
});
|
|
3386
3437
|
}
|
|
3387
3438
|
async function produceBuildAssets(context) {
|
|
3388
|
-
const dynamicBundles = await
|
|
3439
|
+
const dynamicBundles = await buildPackSources(context);
|
|
3389
3440
|
const entries = [
|
|
3390
3441
|
...context.inventory.entries,
|
|
3391
3442
|
...dynamicBundles.flatMap((bundle) => bundle.entries)
|
|
@@ -3395,7 +3446,7 @@ async function produceBuildAssets(context) {
|
|
|
3395
3446
|
const guidSeen = /* @__PURE__ */ new Set();
|
|
3396
3447
|
const work = { importedEntries, context };
|
|
3397
3448
|
for (const bundle of dynamicBundles) {
|
|
3398
|
-
await
|
|
3449
|
+
await emitScriptablePack(work, guidSeen, bundle);
|
|
3399
3450
|
}
|
|
3400
3451
|
for (const entry of importedEntries) {
|
|
3401
3452
|
if (!guidSeen.has(entry.guid.toLowerCase()))
|
|
@@ -4318,6 +4369,176 @@ function importPublicationFailure(error) {
|
|
|
4318
4369
|
diagnostic: error
|
|
4319
4370
|
};
|
|
4320
4371
|
}
|
|
4372
|
+
function publicationArtifacts(transport) {
|
|
4373
|
+
return Object.fromEntries(
|
|
4374
|
+
(transport?.artifacts ?? []).map((artifact) => [
|
|
4375
|
+
artifact.path,
|
|
4376
|
+
{ mediaType: artifact.mediaType, bytes: artifact.bytes }
|
|
4377
|
+
])
|
|
4378
|
+
);
|
|
4379
|
+
}
|
|
4380
|
+
function publicationContext(input) {
|
|
4381
|
+
return {
|
|
4382
|
+
sourceMeta: "<import-publication>",
|
|
4383
|
+
anchorGuid: input.guid,
|
|
4384
|
+
affectedGuids: input.publishedGuids,
|
|
4385
|
+
producer: "source-package/import-publication",
|
|
4386
|
+
importer: "import-publication"
|
|
4387
|
+
};
|
|
4388
|
+
}
|
|
4389
|
+
function validatePublicationArtifactClosure(input) {
|
|
4390
|
+
const context = publicationContext(input);
|
|
4391
|
+
const pack = input.pack;
|
|
4392
|
+
if (pack === null || typeof pack !== "object" || pack.schemaVersion !== "2.0.0" || pack.kind !== "internal-text-package") {
|
|
4393
|
+
return ok(publicationArtifacts(input.transport));
|
|
4394
|
+
}
|
|
4395
|
+
const assets = pack.assets;
|
|
4396
|
+
if (!Array.isArray(assets)) {
|
|
4397
|
+
return err(
|
|
4398
|
+
sourcePackageError("source-package-publication-invalid", context, {
|
|
4399
|
+
stage: "route-integrity",
|
|
4400
|
+
reason: "published Pack does not contain an assets array"
|
|
4401
|
+
})
|
|
4402
|
+
);
|
|
4403
|
+
}
|
|
4404
|
+
const required = /* @__PURE__ */ new Map();
|
|
4405
|
+
for (const asset of assets) {
|
|
4406
|
+
if (asset === null || typeof asset !== "object") {
|
|
4407
|
+
return err(
|
|
4408
|
+
sourcePackageError("source-package-publication-invalid", context, {
|
|
4409
|
+
stage: "route-integrity",
|
|
4410
|
+
reason: "published Pack contains a non-object asset row"
|
|
4411
|
+
})
|
|
4412
|
+
);
|
|
4413
|
+
}
|
|
4414
|
+
const rawArtifacts = asset.artifacts;
|
|
4415
|
+
if (rawArtifacts === void 0) continue;
|
|
4416
|
+
if (rawArtifacts === null || typeof rawArtifacts !== "object" || Array.isArray(rawArtifacts)) {
|
|
4417
|
+
return err(
|
|
4418
|
+
sourcePackageError("source-package-publication-invalid", context, {
|
|
4419
|
+
stage: "route-integrity",
|
|
4420
|
+
reason: "published Pack contains an invalid asset artifact map"
|
|
4421
|
+
})
|
|
4422
|
+
);
|
|
4423
|
+
}
|
|
4424
|
+
for (const [localKey, rawDescriptor] of Object.entries(
|
|
4425
|
+
rawArtifacts
|
|
4426
|
+
)) {
|
|
4427
|
+
if (rawDescriptor === null || typeof rawDescriptor !== "object") {
|
|
4428
|
+
return err(
|
|
4429
|
+
sourcePackageError("source-package-publication-invalid", context, {
|
|
4430
|
+
stage: "route-integrity",
|
|
4431
|
+
reason: `artifact descriptor ${localKey} is not an object`
|
|
4432
|
+
})
|
|
4433
|
+
);
|
|
4434
|
+
}
|
|
4435
|
+
const descriptor = rawDescriptor;
|
|
4436
|
+
const path = descriptor.path;
|
|
4437
|
+
if (typeof path !== "string" || path.length === 0) {
|
|
4438
|
+
return err(
|
|
4439
|
+
sourcePackageError("source-package-publication-invalid", context, {
|
|
4440
|
+
stage: "route-integrity",
|
|
4441
|
+
reason: `artifact descriptor ${localKey} has no package-relative path`
|
|
4442
|
+
})
|
|
4443
|
+
);
|
|
4444
|
+
}
|
|
4445
|
+
const mediaType = descriptor.mediaType;
|
|
4446
|
+
const byteLength = descriptor.byteLength;
|
|
4447
|
+
const integrityValue = descriptor.integrity;
|
|
4448
|
+
const integrity = integrityValue !== null && typeof integrityValue === "object" ? {
|
|
4449
|
+
algorithm: integrityValue.algorithm,
|
|
4450
|
+
digest: integrityValue.digest
|
|
4451
|
+
} : void 0;
|
|
4452
|
+
if (mediaType !== void 0 && typeof mediaType !== "string" || byteLength !== void 0 && (!Number.isSafeInteger(byteLength) || byteLength < 0) || integrityValue !== void 0 && (integrity === void 0 || typeof integrity.algorithm !== "string" || typeof integrity.digest !== "string")) {
|
|
4453
|
+
return err(
|
|
4454
|
+
sourcePackageError("source-package-publication-invalid", context, {
|
|
4455
|
+
stage: "route-integrity",
|
|
4456
|
+
reason: `artifact descriptor ${path} has invalid metadata`
|
|
4457
|
+
})
|
|
4458
|
+
);
|
|
4459
|
+
}
|
|
4460
|
+
if (required.has(path)) {
|
|
4461
|
+
return err(
|
|
4462
|
+
sourcePackageError("source-package-publication-invalid", context, {
|
|
4463
|
+
stage: "route-integrity",
|
|
4464
|
+
reason: `artifact path ${path} is declared more than once`
|
|
4465
|
+
})
|
|
4466
|
+
);
|
|
4467
|
+
}
|
|
4468
|
+
required.set(path, {
|
|
4469
|
+
...typeof mediaType === "string" ? { mediaType } : {},
|
|
4470
|
+
...typeof byteLength === "number" ? { byteLength } : {},
|
|
4471
|
+
...integrity !== void 0 && typeof integrity.algorithm === "string" && typeof integrity.digest === "string" ? { integrity: { algorithm: integrity.algorithm, digest: integrity.digest } } : {}
|
|
4472
|
+
});
|
|
4473
|
+
}
|
|
4474
|
+
}
|
|
4475
|
+
const available = /* @__PURE__ */ new Map();
|
|
4476
|
+
const duplicatePaths = [];
|
|
4477
|
+
for (const artifact of input.transport?.artifacts ?? []) {
|
|
4478
|
+
if (available.has(artifact.path)) duplicatePaths.push(artifact.path);
|
|
4479
|
+
available.set(artifact.path, artifact);
|
|
4480
|
+
}
|
|
4481
|
+
const missing = [];
|
|
4482
|
+
const mismatched = [...duplicatePaths.map((path) => `${path}: duplicate body`)];
|
|
4483
|
+
for (const path of available.keys()) {
|
|
4484
|
+
if (!required.has(path)) mismatched.push(`${path}: unexpected body`);
|
|
4485
|
+
}
|
|
4486
|
+
for (const [path, descriptor] of required) {
|
|
4487
|
+
const artifact = available.get(path);
|
|
4488
|
+
if (artifact === void 0) {
|
|
4489
|
+
missing.push(path);
|
|
4490
|
+
continue;
|
|
4491
|
+
}
|
|
4492
|
+
if (!(artifact.bytes instanceof Uint8Array)) {
|
|
4493
|
+
mismatched.push(`${path}: body is not Uint8Array`);
|
|
4494
|
+
continue;
|
|
4495
|
+
}
|
|
4496
|
+
if (descriptor.mediaType !== void 0 && artifact.mediaType !== descriptor.mediaType) {
|
|
4497
|
+
mismatched.push(`${path}: media type mismatch`);
|
|
4498
|
+
}
|
|
4499
|
+
if (descriptor.byteLength !== void 0 && artifact.bytes.byteLength !== descriptor.byteLength) {
|
|
4500
|
+
mismatched.push(`${path}: byte length mismatch`);
|
|
4501
|
+
}
|
|
4502
|
+
if (descriptor.integrity !== void 0) {
|
|
4503
|
+
const actualDigest = `sha256:${createHash("sha256").update(artifact.bytes).digest("hex")}`;
|
|
4504
|
+
if (descriptor.integrity.algorithm !== "sha256" || descriptor.integrity.digest !== actualDigest) {
|
|
4505
|
+
mismatched.push(`${path}: integrity mismatch`);
|
|
4506
|
+
}
|
|
4507
|
+
}
|
|
4508
|
+
}
|
|
4509
|
+
if (missing.length > 0 || mismatched.length > 0) {
|
|
4510
|
+
return err(
|
|
4511
|
+
sourcePackageError("source-package-publication-invalid", context, {
|
|
4512
|
+
stage: "route-integrity",
|
|
4513
|
+
reason: "Pack artifact closure is incomplete or mismatched",
|
|
4514
|
+
...missing.length === 0 ? {} : { missing },
|
|
4515
|
+
...mismatched.length === 0 ? {} : { unexpected: mismatched }
|
|
4516
|
+
})
|
|
4517
|
+
);
|
|
4518
|
+
}
|
|
4519
|
+
if (input.transport !== void 0) {
|
|
4520
|
+
let transportedPack;
|
|
4521
|
+
try {
|
|
4522
|
+
transportedPack = JSON.parse(input.transport.body);
|
|
4523
|
+
} catch {
|
|
4524
|
+
return err(
|
|
4525
|
+
sourcePackageError("source-package-publication-invalid", context, {
|
|
4526
|
+
stage: "route-integrity",
|
|
4527
|
+
reason: "transport body is not valid JSON for the published Pack"
|
|
4528
|
+
})
|
|
4529
|
+
);
|
|
4530
|
+
}
|
|
4531
|
+
if (canonicalDdcJson(transportedPack) !== canonicalDdcJson(pack)) {
|
|
4532
|
+
return err(
|
|
4533
|
+
sourcePackageError("source-package-publication-invalid", context, {
|
|
4534
|
+
stage: "route-integrity",
|
|
4535
|
+
reason: "transport body does not match the published Pack"
|
|
4536
|
+
})
|
|
4537
|
+
);
|
|
4538
|
+
}
|
|
4539
|
+
}
|
|
4540
|
+
return ok(publicationArtifacts(input.transport));
|
|
4541
|
+
}
|
|
4321
4542
|
function projectImportPublication(input, head, observedAt) {
|
|
4322
4543
|
const digest3 = head.currentKey ?? input.desiredKey;
|
|
4323
4544
|
const revision = { digest: digest3, observedAt, rootId: input.root };
|
|
@@ -4345,6 +4566,15 @@ async function publishImportPublication(input) {
|
|
|
4345
4566
|
return commitImportPublication(staged.candidate);
|
|
4346
4567
|
}
|
|
4347
4568
|
async function stageImportPublication(input) {
|
|
4569
|
+
const validatedArtifacts = validatePublicationArtifactClosure(input);
|
|
4570
|
+
if (!validatedArtifacts.ok) {
|
|
4571
|
+
return {
|
|
4572
|
+
ok: false,
|
|
4573
|
+
error: importPublicationFailure(validatedArtifacts.error),
|
|
4574
|
+
head: await inspectHead(input.root, input.guid, input.desiredKey)
|
|
4575
|
+
};
|
|
4576
|
+
}
|
|
4577
|
+
const artifacts = validatedArtifacts.value;
|
|
4348
4578
|
const staged = await stageSourcePackageDdc({
|
|
4349
4579
|
root: input.root,
|
|
4350
4580
|
entry: {
|
|
@@ -4352,7 +4582,7 @@ async function stageImportPublication(input) {
|
|
|
4352
4582
|
guid: input.guid,
|
|
4353
4583
|
payload: input.pack,
|
|
4354
4584
|
refs: [],
|
|
4355
|
-
artifacts
|
|
4585
|
+
artifacts,
|
|
4356
4586
|
receipt: {
|
|
4357
4587
|
guid: input.guid,
|
|
4358
4588
|
key: input.desiredKey,
|
|
@@ -4362,17 +4592,11 @@ async function stageImportPublication(input) {
|
|
|
4362
4592
|
guid: input.guid,
|
|
4363
4593
|
payload: input.pack,
|
|
4364
4594
|
refs: [],
|
|
4365
|
-
artifacts
|
|
4595
|
+
artifacts
|
|
4366
4596
|
})
|
|
4367
4597
|
}
|
|
4368
4598
|
},
|
|
4369
|
-
context:
|
|
4370
|
-
sourceMeta: "<import-publication>",
|
|
4371
|
-
anchorGuid: input.guid,
|
|
4372
|
-
affectedGuids: input.publishedGuids,
|
|
4373
|
-
producer: "source-package/import-publication",
|
|
4374
|
-
importer: "import-publication"
|
|
4375
|
-
}
|
|
4599
|
+
context: publicationContext(input)
|
|
4376
4600
|
});
|
|
4377
4601
|
if (!staged.ok) {
|
|
4378
4602
|
return {
|
|
@@ -4460,6 +4684,6 @@ async function restoreImportPublication(candidate) {
|
|
|
4460
4684
|
await candidate.ddc.session.restoreEntry(candidate.ddc);
|
|
4461
4685
|
}
|
|
4462
4686
|
|
|
4463
|
-
export { AssetOutputProducerRegistry, DEFAULT_CATALOG_IMPORTER_KEYS, ImporterRegistry, SHADER_RESERVED_IMPORTER_KEY, buildCatalogResult,
|
|
4687
|
+
export { AssetOutputProducerRegistry, DEFAULT_CATALOG_IMPORTER_KEYS, ImporterRegistry, SHADER_RESERVED_IMPORTER_KEY, buildCatalogResult, buildScriptablePack, buildScriptablePackWorklist, canonicalScriptableSourcePath, catalogImporterPolicy, commitImportPublication, containsSourcePackageError, createImportProduct, createPreExternalizedSceneAssetOutputProducer, createSceneAssetOutputProducer, createScriptablePackFileAssetSnapshotSource, createScriptablePackStagedAssetSnapshotSource, createStandardAssetOutputProducerRegistry, declaredPackExternalOutputs, deriveDefaultLodScreenCoverages, discardImportPublication, finalizeImportProducts, finalizeSourcePackage, iesImporter, materialAssetOutputProducer, materializePreparedScriptablePack, meshAssetOutputProducer, normaliseForPack, normalizeSourcePackageError, packMeshBinV4, parseLm63TypeC, parseProducerReadiness, prepareDirectPackTransport, prepareLegacyPackTransport, produceBuildAssets, produceScriptablePackProducts, produceSourcePackage, projectImportProductForBuild, publishImportPublication, readCookedAuthoredPack, readFloat16LE, reconcileMeshLodMeta, resampleTypeC, restoreImportPublication, runImport, sourceDeclarationForCatalogPath, sourcePackageAssetsByGuid, sourcePackageError, stageImportPublication, textureAssetOutputProducer, validateIesProfilePayload, validateMeshLodContract };
|
|
4464
4688
|
//# sourceMappingURL=index.mjs.map
|
|
4465
4689
|
//# sourceMappingURL=index.mjs.map
|