@forgeax/engine-import 0.1.3 → 0.1.4
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 +6 -5
- package/dist/.tsbuildinfo +1 -1
- package/dist/__tests__/owner-chain.integration.test.d.ts +2 -0
- package/dist/__tests__/owner-chain.integration.test.d.ts.map +1 -0
- package/dist/__tests__/scriptable-pack-product.contract.test.d.ts +2 -0
- package/dist/__tests__/scriptable-pack-product.contract.test.d.ts.map +1 -0
- package/dist/browser.d.ts +5 -0
- package/dist/browser.d.ts.map +1 -0
- package/dist/browser.mjs +782 -0
- package/dist/browser.mjs.map +1 -0
- package/dist/build-production.d.ts +48 -0
- package/dist/build-production.d.ts.map +1 -0
- package/dist/catalog-importer-policy.d.ts +13 -0
- package/dist/catalog-importer-policy.d.ts.map +1 -0
- package/dist/catalog-inventory.d.ts +4 -0
- package/dist/catalog-inventory.d.ts.map +1 -0
- package/dist/import-product.d.ts +16 -25
- package/dist/import-product.d.ts.map +1 -1
- package/dist/import-runner.d.ts +6 -3
- package/dist/import-runner.d.ts.map +1 -1
- package/dist/importer-registry.d.ts +9 -1
- package/dist/importer-registry.d.ts.map +1 -1
- package/dist/index.d.ts +11 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +1315 -155
- package/dist/index.mjs.map +1 -1
- package/dist/mesh-bin.d.ts +1 -1
- package/dist/mesh-bin.d.ts.map +1 -1
- package/dist/mesh-bin.mjs +182 -0
- package/dist/mesh-bin.mjs.map +1 -0
- package/dist/pack-projection.d.ts +5 -0
- package/dist/pack-projection.d.ts.map +1 -0
- package/dist/scriptable-pack-host.d.ts +64 -0
- package/dist/scriptable-pack-host.d.ts.map +1 -0
- package/dist/scriptable-pack-output-producers.d.ts +3 -2
- package/dist/scriptable-pack-output-producers.d.ts.map +1 -1
- package/dist/scriptable-pack-staged-snapshot.d.ts +1 -2
- package/dist/scriptable-pack-staged-snapshot.d.ts.map +1 -1
- package/dist/scriptable-pack.d.ts +6 -18
- package/dist/scriptable-pack.d.ts.map +1 -1
- package/dist/scriptable-source-package.d.ts +14 -0
- package/dist/scriptable-source-package.d.ts.map +1 -0
- package/dist/source-package-errors.d.ts +52 -0
- package/dist/source-package-errors.d.ts.map +1 -0
- package/dist/source-package-publication.d.ts +63 -0
- package/dist/source-package-publication.d.ts.map +1 -0
- package/dist/source-package.d.ts +60 -0
- package/dist/source-package.d.ts.map +1 -0
- package/package.json +13 -7
- package/src/__tests__/import-contract-migration.test.ts +33 -0
- package/src/__tests__/import-local-artifacts.test.ts +3 -1
- package/src/__tests__/owner-chain.integration.test.ts +37 -0
- package/src/__tests__/scriptable-pack-product.contract.test.ts +47 -0
- package/src/__tests__/scriptable-pack-production-producers.unit.test.ts +78 -19
- package/src/__tests__/scriptable-pack-staged-snapshot.unit.test.ts +52 -20
- package/src/browser.ts +14 -0
- package/src/build-production.ts +487 -0
- package/src/catalog-importer-policy.ts +58 -0
- package/src/catalog-inventory.ts +24 -0
- package/src/import-product.ts +37 -69
- package/src/import-runner.ts +36 -7
- package/src/importer-registry.ts +24 -1
- package/src/index.ts +79 -8
- package/src/mesh-bin.ts +2 -2
- package/src/pack-projection.ts +21 -0
- package/src/scriptable-pack-host.ts +461 -0
- package/src/scriptable-pack-output-producers.ts +48 -58
- package/src/scriptable-pack-staged-snapshot.ts +17 -6
- package/src/scriptable-pack.ts +37 -26
- package/src/scriptable-source-package.ts +88 -0
- package/src/source-package-errors.ts +201 -0
- package/src/source-package-publication.ts +295 -0
- package/src/source-package.ts +187 -0
- package/dist/__tests__/material-import-product.unit.test.d.ts +0 -2
- package/dist/__tests__/material-import-product.unit.test.d.ts.map +0 -1
- package/src/__tests__/material-import-product.unit.test.ts +0 -56
package/dist/index.mjs
CHANGED
|
@@ -1,52 +1,41 @@
|
|
|
1
1
|
import { ok, validateSourceOverrideMap, ImportError, IMPORT_ERROR_HINTS, canonicalizeSourceOverrides, err, AssetError, MATERIAL_TEXTURE_SLOTS } from '@forgeax/engine-types';
|
|
2
2
|
export { IMPORT_ERROR_HINTS, ImportError } from '@forgeax/engine-types';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import { resolve, dirname } from 'path';
|
|
4
|
+
import { upgradeLegacyAuthoredPack, finalizePackageTransportSource, projectCookedPackageEntry, buildCatalogProjection, createRuntimePackPublication, metaPathForGuid } from '@forgeax/engine-pack/build';
|
|
5
|
+
import { createHash } from 'crypto';
|
|
6
|
+
import { stat, mkdir, writeFile, rename, rm } from 'fs/promises';
|
|
7
|
+
import { createAcceptedPublication, ddcOutputDigest, DdcGenerationSession, DdcLifecycle } from '@forgeax/engine-ddc';
|
|
5
8
|
import { AssetGuid } from '@forgeax/engine-pack/guid';
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
9
|
+
import { NativeCookerRegistry } from '@forgeax/engine-pack/native-cooker';
|
|
10
|
+
import { projectScriptablePackSceneComponents, projectScriptablePackMeta } from '@forgeax/engine-pack/source';
|
|
11
|
+
import { inventoryScriptablePackSource } from '@forgeax/engine-pack/source-node';
|
|
8
12
|
import { externalizeSceneAsset } from '@forgeax/engine-scene';
|
|
9
13
|
import { sha256 } from '@noble/hashes/sha2.js';
|
|
10
14
|
import { bytesToHex } from '@noble/hashes/utils.js';
|
|
15
|
+
import { deriveVertexLayoutProjection } from '@forgeax/engine-geometry';
|
|
16
|
+
import { MESH_BIN_HEADER_V4_BYTES, writeMeshBinHeader } from '@forgeax/engine-pack/mesh-bin-contract';
|
|
17
|
+
import { isScriptablePackAssetKind } from '@forgeax/engine-pack';
|
|
11
18
|
|
|
12
19
|
// src/index.ts
|
|
13
|
-
function
|
|
20
|
+
function invalidProduct(field) {
|
|
14
21
|
return err({
|
|
15
|
-
code: "
|
|
16
|
-
expected: "
|
|
17
|
-
hint: "
|
|
22
|
+
code: "import-product-invalid",
|
|
23
|
+
expected: "a complete terminal import product with source identity",
|
|
24
|
+
hint: "preserve refs, artifacts, receipts, diagnostics, and source revision at the product boundary",
|
|
18
25
|
detail: { field }
|
|
19
26
|
});
|
|
20
27
|
}
|
|
21
|
-
function
|
|
22
|
-
return
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
if (!
|
|
26
|
-
if (input.
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
...input.refs.textures,
|
|
33
|
-
...input.refs.samplers,
|
|
34
|
-
...input.refs.modules
|
|
35
|
-
]);
|
|
36
|
-
return ok({
|
|
37
|
-
sourcePath: input.sourcePath,
|
|
38
|
-
sourceEvidence: input.sourceEvidence,
|
|
39
|
-
asset: {
|
|
40
|
-
guid: input.guid,
|
|
41
|
-
kind: "material",
|
|
42
|
-
payload: input.material,
|
|
43
|
-
refs: refs.map((guid) => ({ guid })),
|
|
44
|
-
artifacts: {}
|
|
45
|
-
}
|
|
46
|
-
});
|
|
47
|
-
}
|
|
48
|
-
function materialImportProductReady(product, availableRefs) {
|
|
49
|
-
return product.asset.refs.every((reference) => availableRefs.has(reference.guid));
|
|
28
|
+
function createImportProduct(input) {
|
|
29
|
+
if (!Array.isArray(input.assets)) return invalidProduct("assets");
|
|
30
|
+
if (!Array.isArray(input.sourceDependencies)) return invalidProduct("sourceDependencies");
|
|
31
|
+
if (input.sourceRevision.trim().length === 0) return invalidProduct("sourceRevision");
|
|
32
|
+
if (!Array.isArray(input.refs)) return invalidProduct("refs");
|
|
33
|
+
if (input.artifacts === null || typeof input.artifacts !== "object") {
|
|
34
|
+
return invalidProduct("artifacts");
|
|
35
|
+
}
|
|
36
|
+
if (!Array.isArray(input.receipts)) return invalidProduct("receipts");
|
|
37
|
+
if (!Array.isArray(input.diagnostics)) return invalidProduct("diagnostics");
|
|
38
|
+
return ok({ ...input });
|
|
50
39
|
}
|
|
51
40
|
async function sha256Hex(bytes2) {
|
|
52
41
|
const subtle = globalThis.crypto?.subtle;
|
|
@@ -75,7 +64,7 @@ function concatBytes(chunks) {
|
|
|
75
64
|
}
|
|
76
65
|
async function productDigest(asset, artifacts) {
|
|
77
66
|
const chunks = [
|
|
78
|
-
JSON.stringify(
|
|
67
|
+
JSON.stringify(projectImportedAssetPayload(asset)),
|
|
79
68
|
JSON.stringify(asset.refs.map((ref2) => ref2.guid)),
|
|
80
69
|
JSON.stringify(artifacts)
|
|
81
70
|
];
|
|
@@ -102,15 +91,15 @@ async function artifactDescriptors(artifacts) {
|
|
|
102
91
|
}
|
|
103
92
|
return Object.fromEntries(entries);
|
|
104
93
|
}
|
|
105
|
-
function
|
|
106
|
-
|
|
94
|
+
function projectImportedAssetPayload(asset) {
|
|
95
|
+
const payload = asset.payload;
|
|
96
|
+
if (Object.keys(asset.artifacts).length === 0) return payload;
|
|
107
97
|
if (asset.kind === "mesh") return { kind: "mesh" };
|
|
108
98
|
if (asset.kind === "texture" || asset.kind === "equirect") {
|
|
109
|
-
const payload = asset.payload;
|
|
110
99
|
const { data: _runtimeBytes, ...metadata } = payload;
|
|
111
100
|
return metadata;
|
|
112
101
|
}
|
|
113
|
-
return
|
|
102
|
+
return payload;
|
|
114
103
|
}
|
|
115
104
|
function finalizeImportProducts(product, inputFingerprint) {
|
|
116
105
|
return (async () => {
|
|
@@ -498,10 +487,35 @@ async function runImport(meta, registry, fs) {
|
|
|
498
487
|
})
|
|
499
488
|
);
|
|
500
489
|
}
|
|
490
|
+
const terminalProduct = createImportProduct({
|
|
491
|
+
...productWithDependencies,
|
|
492
|
+
refs: productWithDependencies.assets.flatMap((asset) => asset.refs),
|
|
493
|
+
artifacts: Object.fromEntries(
|
|
494
|
+
productWithDependencies.assets.flatMap(
|
|
495
|
+
(asset) => Object.entries(asset.artifacts).map(([key, artifact]) => [
|
|
496
|
+
`${asset.guid}/${key}`,
|
|
497
|
+
artifact
|
|
498
|
+
])
|
|
499
|
+
)
|
|
500
|
+
),
|
|
501
|
+
receipts: cookProducts.map((product2) => product2.receipt),
|
|
502
|
+
diagnostics: meta.diagnostics ?? [],
|
|
503
|
+
sourceRevision: inputFingerprint
|
|
504
|
+
});
|
|
505
|
+
if (!terminalProduct.ok) {
|
|
506
|
+
return errResult(
|
|
507
|
+
new ImportError({
|
|
508
|
+
code: "import-internal-error",
|
|
509
|
+
expected: "the import product to retain complete terminal producer facts",
|
|
510
|
+
hint: "preserve source identity and producer evidence when returning the import product",
|
|
511
|
+
detail: { reason: terminalProduct.error.detail.field }
|
|
512
|
+
})
|
|
513
|
+
);
|
|
514
|
+
}
|
|
501
515
|
if (meta.buildPack === false) {
|
|
502
516
|
return {
|
|
503
517
|
ok: true,
|
|
504
|
-
value: { product:
|
|
518
|
+
value: { product: terminalProduct.value, cookProducts }
|
|
505
519
|
};
|
|
506
520
|
}
|
|
507
521
|
const assets = produced.map((a) => {
|
|
@@ -536,57 +550,28 @@ async function runImport(meta, registry, fs) {
|
|
|
536
550
|
return {
|
|
537
551
|
ok: true,
|
|
538
552
|
value: {
|
|
539
|
-
product:
|
|
540
|
-
...productWithDependencies
|
|
541
|
-
},
|
|
553
|
+
product: terminalProduct.value,
|
|
542
554
|
cookProducts,
|
|
543
555
|
pack
|
|
544
556
|
}
|
|
545
557
|
};
|
|
546
558
|
}
|
|
547
559
|
|
|
548
|
-
// src/
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
);
|
|
564
|
-
}
|
|
565
|
-
if (typeof importer.import !== "function") {
|
|
566
|
-
throw new TypeError(
|
|
567
|
-
`ImporterRegistry.register: importer.import must be a function for key "${importer.key}"`
|
|
568
|
-
);
|
|
569
|
-
}
|
|
570
|
-
this.importers.set(importer.key, importer);
|
|
571
|
-
}
|
|
572
|
-
/**
|
|
573
|
-
* Look up the importer registered for `key`. Returns `undefined` when no
|
|
574
|
-
* importer is wired - the import runner maps that to a structured
|
|
575
|
-
* `ImportError(code='importer-not-registered')` with the registered keys in
|
|
576
|
-
* `.detail.registeredImporters` (charter P3).
|
|
577
|
-
*/
|
|
578
|
-
get(key) {
|
|
579
|
-
return this.importers.get(key);
|
|
580
|
-
}
|
|
581
|
-
/**
|
|
582
|
-
* The importer keys currently wired, in insertion order. Fed into the
|
|
583
|
-
* `importer-not-registered` error `.detail.registeredImporters` so AI users
|
|
584
|
-
* see exactly what is injectable.
|
|
585
|
-
*/
|
|
586
|
-
registeredImporters() {
|
|
587
|
-
return [...this.importers.keys()];
|
|
588
|
-
}
|
|
589
|
-
};
|
|
560
|
+
// src/pack-projection.ts
|
|
561
|
+
function projectImportProductForBuild(product) {
|
|
562
|
+
return {
|
|
563
|
+
schemaVersion: "2.0.0",
|
|
564
|
+
kind: "internal-text-package",
|
|
565
|
+
assets: product.assets.map((asset) => ({
|
|
566
|
+
guid: asset.guid,
|
|
567
|
+
kind: asset.kind,
|
|
568
|
+
...asset.name === void 0 ? {} : { name: asset.name },
|
|
569
|
+
payload: normaliseForPack(projectImportedAssetPayload(asset)),
|
|
570
|
+
refs: asset.refs.map((reference) => reference.guid),
|
|
571
|
+
artifacts: asset.artifacts
|
|
572
|
+
}))
|
|
573
|
+
};
|
|
574
|
+
}
|
|
590
575
|
function failure(sourceKey, expected, actual) {
|
|
591
576
|
return {
|
|
592
577
|
code: "mesh-bin-payload-invalid",
|
|
@@ -842,7 +827,7 @@ function observedAssetReader(source) {
|
|
|
842
827
|
new AssetError({
|
|
843
828
|
code: "asset-not-found",
|
|
844
829
|
expected: `a host Asset snapshot source for ScriptablePack content read ${key}`,
|
|
845
|
-
hint: "configure
|
|
830
|
+
hint: "configure the standard ScriptablePack asset source or remove the content read"
|
|
846
831
|
})
|
|
847
832
|
);
|
|
848
833
|
}
|
|
@@ -1036,8 +1021,7 @@ async function buildScriptablePack(options) {
|
|
|
1036
1021
|
const product2 = await producer.produce({
|
|
1037
1022
|
guid: AssetGuid.format(descriptor.guid),
|
|
1038
1023
|
sourceKey,
|
|
1039
|
-
asset
|
|
1040
|
-
...options.components === void 0 ? {} : { components: options.components }
|
|
1024
|
+
asset
|
|
1041
1025
|
});
|
|
1042
1026
|
if (!product2.ok) return err(product2.error);
|
|
1043
1027
|
const productError = productContractError(sourceKey, descriptor.kind, product2.value);
|
|
@@ -1061,8 +1045,8 @@ async function buildScriptablePack(options) {
|
|
|
1061
1045
|
(guid) => AssetGuid.format(guid).toLowerCase()
|
|
1062
1046
|
)
|
|
1063
1047
|
);
|
|
1064
|
-
const
|
|
1065
|
-
if (
|
|
1048
|
+
const closureError2 = externalClosureError(declared, referenced, read);
|
|
1049
|
+
if (closureError2 !== void 0) return err(closureError2);
|
|
1066
1050
|
const externalEvidence = [...declared].sort().map((guid) => {
|
|
1067
1051
|
const observedRead = observed.reads.get(guid);
|
|
1068
1052
|
const isReference = referenced.has(guid);
|
|
@@ -1077,19 +1061,38 @@ async function buildScriptablePack(options) {
|
|
|
1077
1061
|
usage,
|
|
1078
1062
|
...digest === void 0 ? {} : { digest }
|
|
1079
1063
|
}));
|
|
1080
|
-
const product = {
|
|
1081
|
-
assets,
|
|
1082
|
-
sourceDependencies: options.sourceClosure.map((entry) => entry.path)
|
|
1083
|
-
};
|
|
1084
1064
|
const inputFingerprint = await fingerprint({
|
|
1085
1065
|
meta: projectScriptablePackMeta(options.definition, options.sourcePath),
|
|
1066
|
+
sceneComponents: projectScriptablePackSceneComponents(options.definition.sceneComponents),
|
|
1086
1067
|
sourceClosure: stableSourceClosure(options.sourceClosure),
|
|
1087
1068
|
externalEvidence: fingerprintEvidence,
|
|
1088
1069
|
authoringContractVersion: options.authoringContractVersion,
|
|
1089
1070
|
producerVersions: options.outputs.versions()
|
|
1090
1071
|
});
|
|
1072
|
+
const refs = assets.flatMap((asset) => asset.refs);
|
|
1073
|
+
const artifacts = Object.fromEntries(
|
|
1074
|
+
assets.flatMap(
|
|
1075
|
+
(asset) => Object.entries(asset.artifacts).map(([key, artifact]) => [`${asset.guid}/${key}`, artifact])
|
|
1076
|
+
)
|
|
1077
|
+
);
|
|
1078
|
+
const product = createImportProduct({
|
|
1079
|
+
assets,
|
|
1080
|
+
sourceDependencies: options.sourceClosure.map((entry) => entry.path),
|
|
1081
|
+
refs,
|
|
1082
|
+
artifacts,
|
|
1083
|
+
receipts: assets.map((asset) => ({
|
|
1084
|
+
guid: asset.guid,
|
|
1085
|
+
origin: "sourceMeta",
|
|
1086
|
+
status: "succeeded",
|
|
1087
|
+
inputFingerprint
|
|
1088
|
+
})),
|
|
1089
|
+
diagnostics: [],
|
|
1090
|
+
sourceRevision: inputFingerprint,
|
|
1091
|
+
sourceKey: options.sourcePath
|
|
1092
|
+
});
|
|
1093
|
+
if (!product.ok) return err(product.error);
|
|
1091
1094
|
return ok({
|
|
1092
|
-
product,
|
|
1095
|
+
product: product.value,
|
|
1093
1096
|
stagedOutputs: await Promise.all(
|
|
1094
1097
|
Object.keys(options.definition.assets).sort().map(async (sourceKey) => {
|
|
1095
1098
|
const descriptor = options.definition.assets[sourceKey];
|
|
@@ -1109,6 +1112,8 @@ async function buildScriptablePack(options) {
|
|
|
1109
1112
|
inputFingerprint
|
|
1110
1113
|
});
|
|
1111
1114
|
}
|
|
1115
|
+
|
|
1116
|
+
// src/scriptable-pack-output-producers.ts
|
|
1112
1117
|
function producerError(input, reason) {
|
|
1113
1118
|
return new ImportError({
|
|
1114
1119
|
code: "import-internal-error",
|
|
@@ -1192,17 +1197,6 @@ function materialProduct(input) {
|
|
|
1192
1197
|
artifacts: {}
|
|
1193
1198
|
};
|
|
1194
1199
|
}
|
|
1195
|
-
var materialAssetOutputProducer = {
|
|
1196
|
-
kind: "material",
|
|
1197
|
-
version: "material-pack/1",
|
|
1198
|
-
produce(input) {
|
|
1199
|
-
try {
|
|
1200
|
-
return ok(materialProduct(input));
|
|
1201
|
-
} catch (error) {
|
|
1202
|
-
return err(producerError(input, error));
|
|
1203
|
-
}
|
|
1204
|
-
}
|
|
1205
|
-
};
|
|
1206
1200
|
function meshProduct(input) {
|
|
1207
1201
|
if (input.asset.kind !== "mesh") throw new TypeError("expected MeshAsset");
|
|
1208
1202
|
const mesh = input.asset;
|
|
@@ -1237,22 +1231,16 @@ function meshProduct(input) {
|
|
|
1237
1231
|
}
|
|
1238
1232
|
};
|
|
1239
1233
|
}
|
|
1240
|
-
|
|
1241
|
-
kind: "mesh",
|
|
1242
|
-
version: "mesh-binary/4",
|
|
1243
|
-
produce(input) {
|
|
1244
|
-
try {
|
|
1245
|
-
return ok(meshProduct(input));
|
|
1246
|
-
} catch (error) {
|
|
1247
|
-
return err(producerError(input, error));
|
|
1248
|
-
}
|
|
1249
|
-
}
|
|
1250
|
-
};
|
|
1251
|
-
function sceneProduct(input) {
|
|
1234
|
+
function sceneProduct(input, components) {
|
|
1252
1235
|
if (input.asset.kind !== "scene") throw new TypeError("expected SceneAsset");
|
|
1253
1236
|
const externalized = externalizeSceneAsset(input.asset, (componentName) => {
|
|
1254
|
-
const
|
|
1255
|
-
|
|
1237
|
+
const schema = components.get(componentName);
|
|
1238
|
+
if (schema === void 0) {
|
|
1239
|
+
throw new TypeError(
|
|
1240
|
+
`ScriptablePack scene component ${componentName} is missing from sceneComponents`
|
|
1241
|
+
);
|
|
1242
|
+
}
|
|
1243
|
+
return schema;
|
|
1256
1244
|
});
|
|
1257
1245
|
if (!externalized.ok) throw new TypeError(`scene field ${externalized.error.field} is invalid`);
|
|
1258
1246
|
return {
|
|
@@ -1261,6 +1249,19 @@ function sceneProduct(input) {
|
|
|
1261
1249
|
artifacts: {}
|
|
1262
1250
|
};
|
|
1263
1251
|
}
|
|
1252
|
+
function createSafeProducer(kind, version, product) {
|
|
1253
|
+
return {
|
|
1254
|
+
kind,
|
|
1255
|
+
version,
|
|
1256
|
+
produce(input) {
|
|
1257
|
+
try {
|
|
1258
|
+
return ok(product(input));
|
|
1259
|
+
} catch (error) {
|
|
1260
|
+
return err(producerError(input, error));
|
|
1261
|
+
}
|
|
1262
|
+
}
|
|
1263
|
+
};
|
|
1264
|
+
}
|
|
1264
1265
|
function jsonArtifact(value) {
|
|
1265
1266
|
return {
|
|
1266
1267
|
mediaType: "application/json",
|
|
@@ -1442,36 +1443,23 @@ function ordinaryPodProduct(input) {
|
|
|
1442
1443
|
throw new TypeError(`ordinary producer received already-owned ${asset.kind} asset`);
|
|
1443
1444
|
}
|
|
1444
1445
|
}
|
|
1445
|
-
var
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
function createOrdinaryAssetOutputProducer(kind) {
|
|
1457
|
-
return { ...ordinaryAssetOutputProducer, kind };
|
|
1446
|
+
var materialAssetOutputProducer = createSafeProducer(
|
|
1447
|
+
"material",
|
|
1448
|
+
"material-pack/1",
|
|
1449
|
+
materialProduct
|
|
1450
|
+
);
|
|
1451
|
+
var meshAssetOutputProducer = createSafeProducer("mesh", "mesh-binary/4", meshProduct);
|
|
1452
|
+
function createSceneAssetOutputProducer(sceneComponents = []) {
|
|
1453
|
+
const schemas = new Map(
|
|
1454
|
+
sceneComponents.map((component) => [component.name, component.fields])
|
|
1455
|
+
);
|
|
1456
|
+
return createSafeProducer("scene", "scene-pack/3", (input) => sceneProduct(input, schemas));
|
|
1458
1457
|
}
|
|
1459
|
-
|
|
1460
|
-
kind: "scene",
|
|
1461
|
-
version: "scene-pack/2",
|
|
1462
|
-
produce(input) {
|
|
1463
|
-
try {
|
|
1464
|
-
return ok(sceneProduct(input));
|
|
1465
|
-
} catch (error) {
|
|
1466
|
-
return err(producerError(input, error));
|
|
1467
|
-
}
|
|
1468
|
-
}
|
|
1469
|
-
};
|
|
1470
|
-
function createStandardAssetOutputProducerRegistry() {
|
|
1458
|
+
function createStandardAssetOutputProducerRegistry(sceneComponents = []) {
|
|
1471
1459
|
const registry = new AssetOutputProducerRegistry();
|
|
1472
1460
|
registry.register(materialAssetOutputProducer);
|
|
1473
1461
|
registry.register(meshAssetOutputProducer);
|
|
1474
|
-
registry.register(
|
|
1462
|
+
registry.register(createSceneAssetOutputProducer(sceneComponents));
|
|
1475
1463
|
for (const kind of [
|
|
1476
1464
|
"texture",
|
|
1477
1465
|
"equirect",
|
|
@@ -1487,7 +1475,7 @@ function createStandardAssetOutputProducerRegistry() {
|
|
|
1487
1475
|
"audio",
|
|
1488
1476
|
"particle-effect"
|
|
1489
1477
|
]) {
|
|
1490
|
-
registry.register(
|
|
1478
|
+
registry.register(createSafeProducer(kind, "ordinary-pod/1", ordinaryPodProduct));
|
|
1491
1479
|
}
|
|
1492
1480
|
return registry;
|
|
1493
1481
|
}
|
|
@@ -1529,8 +1517,18 @@ function missingOutputError(owner, guid) {
|
|
|
1529
1517
|
};
|
|
1530
1518
|
}
|
|
1531
1519
|
function createScriptablePackStagedAssetSnapshotSource(options) {
|
|
1520
|
+
const owners = options.declaredExternalOutputs === void 0 || options.declaredExternalOutputs.length === 0 ? options.owners : [
|
|
1521
|
+
{
|
|
1522
|
+
id: "<declared-pack-external>",
|
|
1523
|
+
guids: options.declaredExternalOutputs.map((output) => output.guid),
|
|
1524
|
+
async build() {
|
|
1525
|
+
return ok(options.declaredExternalOutputs ?? []);
|
|
1526
|
+
}
|
|
1527
|
+
},
|
|
1528
|
+
...options.owners
|
|
1529
|
+
];
|
|
1532
1530
|
const ownerByGuid = /* @__PURE__ */ new Map();
|
|
1533
|
-
for (const owner of
|
|
1531
|
+
for (const owner of owners) {
|
|
1534
1532
|
if (owner.id.trim().length === 0) throw new TypeError("staged owner id must be non-empty");
|
|
1535
1533
|
for (const guid of owner.guids) {
|
|
1536
1534
|
const key = AssetGuid.format(guid).toLowerCase();
|
|
@@ -1550,12 +1548,11 @@ function createScriptablePackStagedAssetSnapshotSource(options) {
|
|
|
1550
1548
|
if (cached !== void 0) return ok(structuredClone(cached));
|
|
1551
1549
|
const owner = ownerByGuid.get(key);
|
|
1552
1550
|
if (owner === void 0) {
|
|
1553
|
-
if (options.fallback !== void 0) return options.fallback.readByGuid(guid);
|
|
1554
1551
|
return err(
|
|
1555
1552
|
new AssetError({
|
|
1556
1553
|
code: "asset-not-imported",
|
|
1557
|
-
expected: "a staged local owner
|
|
1558
|
-
hint: "declare the local ScriptablePack output
|
|
1554
|
+
expected: "a staged local owner for the requested GUID",
|
|
1555
|
+
hint: "declare the local ScriptablePack output before rebuilding the generation"
|
|
1559
1556
|
})
|
|
1560
1557
|
);
|
|
1561
1558
|
}
|
|
@@ -1601,7 +1598,1170 @@ function createScriptablePackStagedAssetSnapshotSource(options) {
|
|
|
1601
1598
|
});
|
|
1602
1599
|
return sourceFor([]);
|
|
1603
1600
|
}
|
|
1601
|
+
var META_ARTIFACT_KEY = "scriptable-pack.meta.json";
|
|
1602
|
+
function withPrebuiltMeta(product, anchorGuid, meta) {
|
|
1603
|
+
const bytes2 = new TextEncoder().encode(`${JSON.stringify(meta)}
|
|
1604
|
+
`);
|
|
1605
|
+
return {
|
|
1606
|
+
...product,
|
|
1607
|
+
assets: product.assets.map(
|
|
1608
|
+
(asset) => asset.guid.toLowerCase() === anchorGuid ? {
|
|
1609
|
+
...asset,
|
|
1610
|
+
artifacts: {
|
|
1611
|
+
...asset.artifacts,
|
|
1612
|
+
[META_ARTIFACT_KEY]: { mediaType: "application/json", bytes: bytes2 }
|
|
1613
|
+
}
|
|
1614
|
+
} : asset
|
|
1615
|
+
)
|
|
1616
|
+
};
|
|
1617
|
+
}
|
|
1618
|
+
async function produceScriptableSourcePackage(options) {
|
|
1619
|
+
const built = await buildScriptablePack(options);
|
|
1620
|
+
if (!built.ok) return err(built.error);
|
|
1621
|
+
const declaredGuids = Object.values(options.definition.assets).map((descriptor) => AssetGuid.format(descriptor.guid).toLowerCase()).sort();
|
|
1622
|
+
const anchorGuid = declaredGuids[0];
|
|
1623
|
+
if (anchorGuid === void 0) {
|
|
1624
|
+
return err({
|
|
1625
|
+
code: "pack-source-output-invalid",
|
|
1626
|
+
expected: "at least one declared ScriptablePack output",
|
|
1627
|
+
hint: "add an output descriptor before building the package",
|
|
1628
|
+
detail: { missingGuids: [], unexpectedSourceKeys: [], kindMismatches: [] }
|
|
1629
|
+
});
|
|
1630
|
+
}
|
|
1631
|
+
const product = withPrebuiltMeta(
|
|
1632
|
+
built.value.product,
|
|
1633
|
+
anchorGuid,
|
|
1634
|
+
projectScriptablePackMeta(options.definition, options.sourcePath)
|
|
1635
|
+
);
|
|
1636
|
+
return ok({
|
|
1637
|
+
anchorGuid,
|
|
1638
|
+
declaredGuids,
|
|
1639
|
+
product,
|
|
1640
|
+
stagedOutputs: built.value.stagedOutputs,
|
|
1641
|
+
inputFingerprint: built.value.inputFingerprint,
|
|
1642
|
+
externalEvidence: built.value.externalEvidence
|
|
1643
|
+
});
|
|
1644
|
+
}
|
|
1645
|
+
|
|
1646
|
+
// src/scriptable-pack-host.ts
|
|
1647
|
+
function canonicalScriptableSourcePath(sourcePath) {
|
|
1648
|
+
const normalized = sourcePath.replaceAll("\\", "/");
|
|
1649
|
+
const marker = "/assets/";
|
|
1650
|
+
const markerIndex = normalized.indexOf(marker);
|
|
1651
|
+
return markerIndex < 0 ? normalized : normalized.slice(markerIndex + 1);
|
|
1652
|
+
}
|
|
1653
|
+
function scriptablePackInputs(sourcePaths, declarations, cwd, generationFor, policyFor) {
|
|
1654
|
+
return sourcePaths.flatMap((sourcePath) => {
|
|
1655
|
+
const declaration = declarations.get(resolve(cwd, sourcePath));
|
|
1656
|
+
if (declaration?.format !== "pack.ts") return [];
|
|
1657
|
+
const displaySourcePath = canonicalScriptableSourcePath(sourcePath);
|
|
1658
|
+
return [
|
|
1659
|
+
{
|
|
1660
|
+
sourcePath: resolve(cwd, sourcePath),
|
|
1661
|
+
displaySourcePath,
|
|
1662
|
+
definition: declaration.definition,
|
|
1663
|
+
sourceClosure: declaration.sourceClosure,
|
|
1664
|
+
publicationGeneration: generationFor(displaySourcePath),
|
|
1665
|
+
policy: policyFor(displaySourcePath)
|
|
1666
|
+
}
|
|
1667
|
+
];
|
|
1668
|
+
});
|
|
1669
|
+
}
|
|
1670
|
+
async function materializePreparedScriptablePack(prepared, paths, sink) {
|
|
1671
|
+
const { product, finalized } = prepared;
|
|
1672
|
+
await sink.writePackage(paths.packagePath, JSON.stringify(finalized.pack));
|
|
1673
|
+
for (const artifact of finalized.artifacts) {
|
|
1674
|
+
await sink.writeArtifact(
|
|
1675
|
+
paths.artifactPath(artifact.path),
|
|
1676
|
+
artifact.bytes,
|
|
1677
|
+
artifact.path.endsWith(".json") ? "application/json" : artifact.mediaType
|
|
1678
|
+
);
|
|
1679
|
+
}
|
|
1680
|
+
const receipts = /* @__PURE__ */ new Map();
|
|
1681
|
+
for (const guid of product.declaredGuids) {
|
|
1682
|
+
const path = paths.receiptPath(guid);
|
|
1683
|
+
await sink.writeReceipt(
|
|
1684
|
+
path,
|
|
1685
|
+
JSON.stringify({
|
|
1686
|
+
guid,
|
|
1687
|
+
origin: "sourceMeta",
|
|
1688
|
+
status: "succeeded",
|
|
1689
|
+
inputFingerprint: product.inputFingerprint,
|
|
1690
|
+
outputDigest: finalized.digest
|
|
1691
|
+
})
|
|
1692
|
+
);
|
|
1693
|
+
receipts.set(guid, path);
|
|
1694
|
+
}
|
|
1695
|
+
return receipts;
|
|
1696
|
+
}
|
|
1697
|
+
async function readCookedAuthoredPack(authoredPack, cookers = [], sourcePath) {
|
|
1698
|
+
const parsed = upgradeLegacyAuthoredPack(authoredPack);
|
|
1699
|
+
if (parsed.schemaVersion !== "2.0.0" || parsed.assets === void 0) return void 0;
|
|
1700
|
+
const registry = new NativeCookerRegistry();
|
|
1701
|
+
for (const cooker of cookers) registry.register(cooker);
|
|
1702
|
+
const assets = [];
|
|
1703
|
+
const refsByGuid = /* @__PURE__ */ new Map();
|
|
1704
|
+
let hasCookedAsset = false;
|
|
1705
|
+
for (const asset of parsed.assets) {
|
|
1706
|
+
const shouldCook = asset.execution === "cooked";
|
|
1707
|
+
if (!shouldCook) {
|
|
1708
|
+
assets.push({
|
|
1709
|
+
guid: asset.guid,
|
|
1710
|
+
kind: asset.kind,
|
|
1711
|
+
...asset.name === void 0 ? {} : { name: asset.name },
|
|
1712
|
+
...asset.sourceKey === void 0 ? {} : { sourceKey: asset.sourceKey },
|
|
1713
|
+
...asset.sourceIndex === void 0 ? {} : { sourceIndex: asset.sourceIndex },
|
|
1714
|
+
...asset.relations === void 0 ? {} : { relations: asset.relations },
|
|
1715
|
+
payload: asset.payload,
|
|
1716
|
+
refs: asset.refs ?? [],
|
|
1717
|
+
artifacts: {}
|
|
1718
|
+
});
|
|
1719
|
+
continue;
|
|
1720
|
+
}
|
|
1721
|
+
hasCookedAsset = true;
|
|
1722
|
+
const result = await registry.runDraft(asset.kind, {
|
|
1723
|
+
guid: asset.guid,
|
|
1724
|
+
source: asset.payload,
|
|
1725
|
+
...asset.sourceKey === void 0 ? {} : { sourceKey: asset.sourceKey },
|
|
1726
|
+
...sourcePath === void 0 ? {} : { sourcePath },
|
|
1727
|
+
refs: asset.refs ?? []
|
|
1728
|
+
});
|
|
1729
|
+
if (!result.ok) throw result.error;
|
|
1730
|
+
const draft = result.value;
|
|
1731
|
+
const refs = [...draft.refs];
|
|
1732
|
+
refsByGuid.set(asset.guid.toLowerCase(), refs);
|
|
1733
|
+
assets.push({
|
|
1734
|
+
guid: draft.guid,
|
|
1735
|
+
kind: asset.kind,
|
|
1736
|
+
...asset.name === void 0 ? {} : { name: asset.name },
|
|
1737
|
+
...asset.sourceKey === void 0 ? {} : { sourceKey: asset.sourceKey },
|
|
1738
|
+
...asset.sourceIndex === void 0 ? {} : { sourceIndex: asset.sourceIndex },
|
|
1739
|
+
...asset.relations === void 0 ? {} : { relations: asset.relations },
|
|
1740
|
+
payload: draft.payload,
|
|
1741
|
+
refs,
|
|
1742
|
+
artifacts: draft.artifacts
|
|
1743
|
+
});
|
|
1744
|
+
}
|
|
1745
|
+
return hasCookedAsset ? {
|
|
1746
|
+
logicalPackage: { schemaVersion: "2.0.0", kind: "internal-text-package", assets },
|
|
1747
|
+
refsByGuid
|
|
1748
|
+
} : void 0;
|
|
1749
|
+
}
|
|
1750
|
+
async function declaredPackExternalOutputs(declarations, cookers = [], requiredGuids = []) {
|
|
1751
|
+
if (requiredGuids.length === 0) return [];
|
|
1752
|
+
const required = new Set(requiredGuids.map((guid) => AssetGuid.format(guid).toLowerCase()));
|
|
1753
|
+
const outputs = [];
|
|
1754
|
+
for (const declaration of declarations.values()) {
|
|
1755
|
+
if (declaration.format !== "pack.json") continue;
|
|
1756
|
+
const declaredAssets = declaration.value.assets.filter(
|
|
1757
|
+
(asset) => required.has(asset.guid.toLowerCase())
|
|
1758
|
+
);
|
|
1759
|
+
if (declaredAssets.length === 0) continue;
|
|
1760
|
+
const cooked = await readCookedAuthoredPack(declaration.value, cookers, declaration.sourcePath);
|
|
1761
|
+
for (const asset of cooked?.logicalPackage.assets.filter(
|
|
1762
|
+
(item) => required.has(item.guid.toLowerCase())
|
|
1763
|
+
) ?? declaredAssets) {
|
|
1764
|
+
const parsed = AssetGuid.parse(asset.guid);
|
|
1765
|
+
if (!parsed.ok) throw parsed.error;
|
|
1766
|
+
outputs.push({ guid: parsed.value, asset: { kind: asset.kind, ...asset.payload } });
|
|
1767
|
+
}
|
|
1768
|
+
}
|
|
1769
|
+
return outputs;
|
|
1770
|
+
}
|
|
1771
|
+
async function prepareAuthoredPackTransport(authoredPack, cookers, policyFor, sourcePath) {
|
|
1772
|
+
const pack = upgradeLegacyAuthoredPack(authoredPack);
|
|
1773
|
+
const firstGuid = pack.assets?.[0]?.guid?.toLowerCase();
|
|
1774
|
+
if (pack.schemaVersion !== "2.0.0" || firstGuid === void 0) {
|
|
1775
|
+
return { pack, ...firstGuid === void 0 ? {} : { firstGuid } };
|
|
1776
|
+
}
|
|
1777
|
+
const cooked = await readCookedAuthoredPack(pack, cookers, sourcePath);
|
|
1778
|
+
if (cooked === void 0) return { pack, firstGuid };
|
|
1779
|
+
return {
|
|
1780
|
+
pack,
|
|
1781
|
+
firstGuid,
|
|
1782
|
+
cooked,
|
|
1783
|
+
finalized: await finalizePackageTransportSource(cooked.logicalPackage, policyFor(firstGuid))
|
|
1784
|
+
};
|
|
1785
|
+
}
|
|
1786
|
+
function projectScriptablePackPublication(product) {
|
|
1787
|
+
const assets = new Map(product.product.assets.map((asset) => [asset.guid.toLowerCase(), asset]));
|
|
1788
|
+
const outputs = [];
|
|
1789
|
+
for (const staged of product.stagedOutputs) {
|
|
1790
|
+
const guid = AssetGuid.format(staged.guid).toLowerCase();
|
|
1791
|
+
const asset = assets.get(guid);
|
|
1792
|
+
if (asset === void 0 || staged.digest === void 0) {
|
|
1793
|
+
return err({
|
|
1794
|
+
code: "pack-source-output-invalid",
|
|
1795
|
+
expected: `ScriptablePack publication output ${guid} to include a product and digest`,
|
|
1796
|
+
hint: "repair the ScriptablePack producer output and rebuild",
|
|
1797
|
+
detail: { stage: "publication", guid }
|
|
1798
|
+
});
|
|
1799
|
+
}
|
|
1800
|
+
outputs.push({
|
|
1801
|
+
guid,
|
|
1802
|
+
sourceKey: staged.sourceKey ?? guid,
|
|
1803
|
+
kind: asset.kind,
|
|
1804
|
+
digest: staged.digest,
|
|
1805
|
+
refs: asset.refs.map((reference) => reference.guid)
|
|
1806
|
+
});
|
|
1807
|
+
}
|
|
1808
|
+
return ok({
|
|
1809
|
+
outputs,
|
|
1810
|
+
refs: new Map(
|
|
1811
|
+
product.product.assets.map((asset) => [
|
|
1812
|
+
asset.guid.toLowerCase(),
|
|
1813
|
+
asset.refs.map((reference) => reference.guid)
|
|
1814
|
+
])
|
|
1815
|
+
)
|
|
1816
|
+
});
|
|
1817
|
+
}
|
|
1818
|
+
async function scriptablePackResourceRevision(displaySourcePath, digest, sourceClosure) {
|
|
1819
|
+
const observedAt = Math.trunc(
|
|
1820
|
+
Math.max(
|
|
1821
|
+
...await Promise.all(sourceClosure.map(async (entry) => (await stat(entry.path)).mtimeMs))
|
|
1822
|
+
)
|
|
1823
|
+
);
|
|
1824
|
+
return { digest, observedAt, rootId: displaySourcePath };
|
|
1825
|
+
}
|
|
1826
|
+
async function produceScriptablePackProducts(sources, declaredExternalOutputs = []) {
|
|
1827
|
+
const entries = /* @__PURE__ */ new Map();
|
|
1828
|
+
for (const source of sources) {
|
|
1829
|
+
if (entries.has(source.displaySourcePath)) continue;
|
|
1830
|
+
entries.set(source.displaySourcePath, {
|
|
1831
|
+
source,
|
|
1832
|
+
definition: source.definition,
|
|
1833
|
+
closure: source.sourceClosure
|
|
1834
|
+
});
|
|
1835
|
+
}
|
|
1836
|
+
const products = /* @__PURE__ */ new Map();
|
|
1837
|
+
const owners = [...entries.entries()].map(
|
|
1838
|
+
([displaySourcePath, entry]) => ({
|
|
1839
|
+
id: displaySourcePath,
|
|
1840
|
+
guids: Object.values(entry.definition.assets).map((asset) => asset.guid),
|
|
1841
|
+
async build(source) {
|
|
1842
|
+
const produced = await produceScriptableSourcePackage({
|
|
1843
|
+
definition: entry.definition,
|
|
1844
|
+
sourcePath: displaySourcePath,
|
|
1845
|
+
assetSource: source,
|
|
1846
|
+
outputs: createStandardAssetOutputProducerRegistry(
|
|
1847
|
+
projectScriptablePackSceneComponents(entry.definition.sceneComponents)
|
|
1848
|
+
),
|
|
1849
|
+
sourceClosure: entry.closure,
|
|
1850
|
+
authoringContractVersion: "scriptable-pack-production/1"
|
|
1851
|
+
});
|
|
1852
|
+
if (!produced.ok) return produced;
|
|
1853
|
+
const observedClosure = await inventoryScriptablePackSource(entry.source.sourcePath);
|
|
1854
|
+
if (JSON.stringify(observedClosure) !== JSON.stringify(entry.closure)) {
|
|
1855
|
+
return err({
|
|
1856
|
+
code: "pack-source-load-failed",
|
|
1857
|
+
expected: "the complete ScriptablePack module closure to remain fixed during one build",
|
|
1858
|
+
hint: "retry the build after source and helper writes have settled",
|
|
1859
|
+
detail: {
|
|
1860
|
+
sourcePath: displaySourcePath,
|
|
1861
|
+
reason: "source-changed",
|
|
1862
|
+
phase: "build",
|
|
1863
|
+
diagnostic: "module closure changed while the staged generation was building"
|
|
1864
|
+
}
|
|
1865
|
+
});
|
|
1866
|
+
}
|
|
1867
|
+
products.set(displaySourcePath, produced.value);
|
|
1868
|
+
return ok(produced.value.stagedOutputs);
|
|
1869
|
+
}
|
|
1870
|
+
})
|
|
1871
|
+
);
|
|
1872
|
+
const generationDigest = createHash("sha256").update(
|
|
1873
|
+
JSON.stringify(
|
|
1874
|
+
[...entries.values()].flatMap((entry) => entry.closure).sort((a, b) => a.path.localeCompare(b.path))
|
|
1875
|
+
)
|
|
1876
|
+
).digest();
|
|
1877
|
+
const stagedSource = createScriptablePackStagedAssetSnapshotSource({
|
|
1878
|
+
generation: generationDigest.readUInt32BE(0),
|
|
1879
|
+
owners,
|
|
1880
|
+
declaredExternalOutputs
|
|
1881
|
+
});
|
|
1882
|
+
const prepared = /* @__PURE__ */ new Map();
|
|
1883
|
+
for (const source of sources) {
|
|
1884
|
+
const entry = entries.get(source.displaySourcePath);
|
|
1885
|
+
if (entry === void 0) {
|
|
1886
|
+
return err({
|
|
1887
|
+
code: "pack-source-path-invalid",
|
|
1888
|
+
expected: "a ScriptablePack source registered in the current inventory",
|
|
1889
|
+
actual: source.displaySourcePath,
|
|
1890
|
+
hint: "rebuild the source inventory before producing this path",
|
|
1891
|
+
retryable: true,
|
|
1892
|
+
recoveryActions: ["rebuild-source-inventory"],
|
|
1893
|
+
detail: { sourcePath: source.displaySourcePath }
|
|
1894
|
+
});
|
|
1895
|
+
}
|
|
1896
|
+
const first = Object.values(entry.definition.assets)[0];
|
|
1897
|
+
if (first === void 0) {
|
|
1898
|
+
return err({
|
|
1899
|
+
code: "pack-source-output-invalid",
|
|
1900
|
+
expected: "at least one declared ScriptablePack output",
|
|
1901
|
+
hint: "add an output descriptor before building the package",
|
|
1902
|
+
detail: { missingGuids: [], unexpectedSourceKeys: [], kindMismatches: [] }
|
|
1903
|
+
});
|
|
1904
|
+
}
|
|
1905
|
+
const staged = await stagedSource.readByGuid(first.guid);
|
|
1906
|
+
if (!staged.ok) return err(staged.error);
|
|
1907
|
+
const produced = products.get(source.displaySourcePath);
|
|
1908
|
+
if (produced === void 0) {
|
|
1909
|
+
return err({
|
|
1910
|
+
code: "pack-source-output-invalid",
|
|
1911
|
+
expected: "the staged owner build to retain its source-package product",
|
|
1912
|
+
hint: "retry the ScriptablePack production attempt",
|
|
1913
|
+
detail: {
|
|
1914
|
+
missingGuids: [AssetGuid.format(first.guid)],
|
|
1915
|
+
unexpectedSourceKeys: [],
|
|
1916
|
+
kindMismatches: []
|
|
1917
|
+
}
|
|
1918
|
+
});
|
|
1919
|
+
}
|
|
1920
|
+
const transportPolicy = typeof source.policy === "function" ? source.policy(produced) : source.policy;
|
|
1921
|
+
const logicalPackage = projectImportProductForBuild(produced.product);
|
|
1922
|
+
const finalized = await finalizePackageTransportSource(logicalPackage, transportPolicy);
|
|
1923
|
+
const facts = projectScriptablePackPublication(produced);
|
|
1924
|
+
if (!facts.ok) return err(facts.error);
|
|
1925
|
+
const revision = await scriptablePackResourceRevision(
|
|
1926
|
+
source.displaySourcePath,
|
|
1927
|
+
produced.inputFingerprint,
|
|
1928
|
+
source.sourceClosure
|
|
1929
|
+
);
|
|
1930
|
+
const publication = createAcceptedPublication({
|
|
1931
|
+
sourcePath: source.displaySourcePath,
|
|
1932
|
+
sourceRevision: produced.inputFingerprint,
|
|
1933
|
+
generation: source.publicationGeneration,
|
|
1934
|
+
digest: finalized.digest,
|
|
1935
|
+
packageUrl: finalized.packageUrl,
|
|
1936
|
+
inputFingerprint: produced.inputFingerprint,
|
|
1937
|
+
outputs: facts.value.outputs,
|
|
1938
|
+
externalEvidence: produced.externalEvidence
|
|
1939
|
+
});
|
|
1940
|
+
prepared.set(source.displaySourcePath, {
|
|
1941
|
+
product: produced,
|
|
1942
|
+
finalized,
|
|
1943
|
+
facts: facts.value,
|
|
1944
|
+
revision,
|
|
1945
|
+
publication
|
|
1946
|
+
});
|
|
1947
|
+
}
|
|
1948
|
+
return ok(prepared);
|
|
1949
|
+
}
|
|
1950
|
+
function parseProducerReadiness(value) {
|
|
1951
|
+
if (value === void 0 || value === "before-consume" || value === "on-demand") {
|
|
1952
|
+
return { ok: true, value: value ?? "before-consume" };
|
|
1953
|
+
}
|
|
1954
|
+
return {
|
|
1955
|
+
ok: false,
|
|
1956
|
+
error: {
|
|
1957
|
+
code: "producer-readiness-invalid",
|
|
1958
|
+
expected: "'before-consume' or 'on-demand'",
|
|
1959
|
+
hint: "set producerReadiness to before-consume or on-demand",
|
|
1960
|
+
detail: { value }
|
|
1961
|
+
}
|
|
1962
|
+
};
|
|
1963
|
+
}
|
|
1964
|
+
function finalizeSourcePackage(product, finalizer, artifactUrl) {
|
|
1965
|
+
if (finalizer === void 0) return ok(product);
|
|
1966
|
+
const result = finalizer(product, { artifactUrl });
|
|
1967
|
+
if (!result.ok) return err(result.error);
|
|
1968
|
+
return ok({
|
|
1969
|
+
...product,
|
|
1970
|
+
assets: product.assets.map(
|
|
1971
|
+
(asset, index) => index === 0 ? { ...asset, payload: result.value.asset } : asset
|
|
1972
|
+
)
|
|
1973
|
+
});
|
|
1974
|
+
}
|
|
1975
|
+
function closureError(declaredGuids, producedGuids) {
|
|
1976
|
+
const declared = new Set(declaredGuids.map((guid) => guid.toLowerCase()));
|
|
1977
|
+
const produced = new Set(producedGuids.map((guid) => guid.toLowerCase()));
|
|
1978
|
+
const counts = /* @__PURE__ */ new Map();
|
|
1979
|
+
for (const guid of producedGuids) {
|
|
1980
|
+
const key = guid.toLowerCase();
|
|
1981
|
+
counts.set(key, (counts.get(key) ?? 0) + 1);
|
|
1982
|
+
}
|
|
1983
|
+
const duplicateGuids = [...counts.entries()].filter(([, count]) => count > 1).map(([guid]) => guid);
|
|
1984
|
+
return {
|
|
1985
|
+
code: "source-package-guid-closure-mismatch",
|
|
1986
|
+
expected: "the importer to return exactly one asset for every declared Meta GUID",
|
|
1987
|
+
hint: "repair the Meta declaration or importer output, then rebuild the whole source package",
|
|
1988
|
+
detail: {
|
|
1989
|
+
stage: "closure",
|
|
1990
|
+
declaredGuids,
|
|
1991
|
+
producedGuids,
|
|
1992
|
+
missingGuids: declaredGuids.filter((guid) => !produced.has(guid.toLowerCase())),
|
|
1993
|
+
unexpectedGuids: producedGuids.filter((guid) => !declared.has(guid.toLowerCase())),
|
|
1994
|
+
duplicateGuids
|
|
1995
|
+
}
|
|
1996
|
+
};
|
|
1997
|
+
}
|
|
1998
|
+
function producedGuidsFromImportFailure(declaredGuids, detail) {
|
|
1999
|
+
if ("missingGuids" in detail) {
|
|
2000
|
+
return declaredGuids.filter((guid) => !detail.missingGuids.includes(guid));
|
|
2001
|
+
}
|
|
2002
|
+
if ("unexpectedGuids" in detail) return [...declaredGuids, ...detail.unexpectedGuids];
|
|
2003
|
+
return [];
|
|
2004
|
+
}
|
|
2005
|
+
async function produceSourcePackage(input) {
|
|
2006
|
+
const declaredGuids = input.meta.subAssets.map((asset) => asset.guid);
|
|
2007
|
+
const result = await runImport(input.meta, input.registry, input.fs);
|
|
2008
|
+
if (!result.ok) {
|
|
2009
|
+
const producedGuids2 = producedGuidsFromImportFailure(declaredGuids, result.error.detail);
|
|
2010
|
+
return {
|
|
2011
|
+
ok: false,
|
|
2012
|
+
error: closureError(declaredGuids, producedGuids2)
|
|
2013
|
+
};
|
|
2014
|
+
}
|
|
2015
|
+
if ("skipped" in result.value) {
|
|
2016
|
+
return { ok: false, error: closureError(declaredGuids, []) };
|
|
2017
|
+
}
|
|
2018
|
+
const producedGuids = result.value.product.assets.map((asset) => asset.guid);
|
|
2019
|
+
const declaredSet = new Set(declaredGuids.map((guid) => guid.toLowerCase()));
|
|
2020
|
+
const producedSet = new Set(producedGuids.map((guid) => guid.toLowerCase()));
|
|
2021
|
+
const hasDuplicate = new Set(producedGuids.map((guid) => guid.toLowerCase())).size !== producedGuids.length;
|
|
2022
|
+
const complete = !hasDuplicate && declaredGuids.length === producedGuids.length && declaredGuids.every((guid) => producedSet.has(guid.toLowerCase())) && producedGuids.every((guid) => declaredSet.has(guid.toLowerCase()));
|
|
2023
|
+
if (!complete) return { ok: false, error: closureError(declaredGuids, producedGuids) };
|
|
2024
|
+
const product = result.value.product;
|
|
2025
|
+
const anchorGuid = [...declaredGuids].sort((left, right) => left.localeCompare(right))[0];
|
|
2026
|
+
if (anchorGuid === void 0)
|
|
2027
|
+
return { ok: false, error: closureError(declaredGuids, producedGuids) };
|
|
2028
|
+
return {
|
|
2029
|
+
ok: true,
|
|
2030
|
+
value: {
|
|
2031
|
+
anchorGuid,
|
|
2032
|
+
declaredGuids,
|
|
2033
|
+
product
|
|
2034
|
+
}
|
|
2035
|
+
};
|
|
2036
|
+
}
|
|
2037
|
+
function sourcePackageAssetsByGuid(source) {
|
|
2038
|
+
return new Map(source.product.assets.map((asset) => [asset.guid.toLowerCase(), asset]));
|
|
2039
|
+
}
|
|
2040
|
+
|
|
2041
|
+
// src/build-production.ts
|
|
2042
|
+
function scriptableArtifactPath(guid, key) {
|
|
2043
|
+
return `${guid.toLowerCase()}/${key.includes(".") ? key : `${key}.bin`}`;
|
|
2044
|
+
}
|
|
2045
|
+
function runtimePublicationFor(context, input) {
|
|
2046
|
+
return createRuntimePackPublication({
|
|
2047
|
+
pack: input.pack,
|
|
2048
|
+
scopeId: context.runtimeBinding?.scopeId ?? "asset-runtime",
|
|
2049
|
+
sourcePath: input.sourcePath,
|
|
2050
|
+
sourceRevision: input.sourceRevision,
|
|
2051
|
+
packageUrl: input.packageUrl,
|
|
2052
|
+
...input.digest === void 0 ? {} : { digest: input.digest },
|
|
2053
|
+
generation: context.runtimeBinding?.generation ?? context.generation
|
|
2054
|
+
});
|
|
2055
|
+
}
|
|
2056
|
+
async function buildAuthoredPackages(context) {
|
|
2057
|
+
const scriptableSources = [
|
|
2058
|
+
...new Set(
|
|
2059
|
+
context.inventory.entries.filter((entry) => entry.sourcePath.endsWith(".pack.ts")).map((entry) => entry.sourcePath)
|
|
2060
|
+
)
|
|
2061
|
+
];
|
|
2062
|
+
if (scriptableSources.length === 0) return /* @__PURE__ */ new Map();
|
|
2063
|
+
const inputs = scriptablePackInputs(
|
|
2064
|
+
scriptableSources,
|
|
2065
|
+
context.inventory.sourceDeclarations,
|
|
2066
|
+
context.cwd,
|
|
2067
|
+
() => context.generation,
|
|
2068
|
+
() => (product) => ({
|
|
2069
|
+
base: context.basePrefix === "" ? "/" : context.basePrefix,
|
|
2070
|
+
packagePath: `assets/${product.anchorGuid}.pack.json`,
|
|
2071
|
+
artifactPath: scriptableArtifactPath
|
|
2072
|
+
})
|
|
2073
|
+
);
|
|
2074
|
+
const preparedResult = await produceScriptablePackProducts(
|
|
2075
|
+
inputs,
|
|
2076
|
+
await declaredPackExternalOutputs(
|
|
2077
|
+
context.inventory.sourceDeclarations,
|
|
2078
|
+
context.cookers,
|
|
2079
|
+
inputs.flatMap((input) => Object.values(input.definition.externalAssets))
|
|
2080
|
+
)
|
|
2081
|
+
);
|
|
2082
|
+
if (!preparedResult.ok) throw context.fail(preparedResult.error);
|
|
2083
|
+
const result = /* @__PURE__ */ new Map();
|
|
2084
|
+
for (const entry of context.inventory.entries) {
|
|
2085
|
+
if (!entry.sourcePath.endsWith(".pack.ts") || result.has(entry.sourcePath)) continue;
|
|
2086
|
+
const prepared = preparedResult.value.get(canonicalScriptableSourcePath(entry.sourcePath));
|
|
2087
|
+
if (prepared === void 0) {
|
|
2088
|
+
throw context.fail({
|
|
2089
|
+
code: "catalog-declaration-missing",
|
|
2090
|
+
expected: "the ScriptablePack inventory to retain every authored Pack source",
|
|
2091
|
+
hint: "rerun the source inventory and rebuild from the accepted declaration set",
|
|
2092
|
+
detail: { stage: "scan", sourcePath: entry.sourcePath }
|
|
2093
|
+
});
|
|
2094
|
+
}
|
|
2095
|
+
const { product, finalized, facts, revision, publication } = prepared;
|
|
2096
|
+
const packagePath = `assets/${product.anchorGuid}.pack.json`;
|
|
2097
|
+
const runtimePublication = createRuntimePackPublication({
|
|
2098
|
+
pack: { assets: finalized.pack.assets },
|
|
2099
|
+
scopeId: context.runtimeBinding?.scopeId ?? "asset-runtime",
|
|
2100
|
+
sourcePath: publication.sourcePath,
|
|
2101
|
+
sourceRevision: publication.sourceRevision,
|
|
2102
|
+
packageUrl: finalized.packageUrl,
|
|
2103
|
+
inputFingerprint: publication.receipt.inputFingerprint,
|
|
2104
|
+
digest: finalized.digest,
|
|
2105
|
+
generation: context.runtimeBinding?.generation ?? publication.generation,
|
|
2106
|
+
outputs: facts.outputs,
|
|
2107
|
+
externalEvidence: publication.externalEvidence
|
|
2108
|
+
});
|
|
2109
|
+
const receiptPaths = await materializePreparedScriptablePack(
|
|
2110
|
+
prepared,
|
|
2111
|
+
{
|
|
2112
|
+
packagePath,
|
|
2113
|
+
artifactPath: (path) => `assets/${path}`,
|
|
2114
|
+
receiptPath: (guid) => `assets/${guid}.receipt.json`
|
|
2115
|
+
},
|
|
2116
|
+
{
|
|
2117
|
+
writePackage: (path) => {
|
|
2118
|
+
context.sink.emitFile({
|
|
2119
|
+
type: "asset",
|
|
2120
|
+
fileName: path,
|
|
2121
|
+
originalFileName: `${context.cwd}/${entry.sourcePath}`,
|
|
2122
|
+
source: JSON.stringify(runtimePublication.pack)
|
|
2123
|
+
});
|
|
2124
|
+
},
|
|
2125
|
+
writeArtifact: (path, bytes2) => {
|
|
2126
|
+
context.sink.emitFile({ type: "asset", fileName: path, source: bytes2 });
|
|
2127
|
+
},
|
|
2128
|
+
writeReceipt: (path, source) => {
|
|
2129
|
+
context.sink.emitFile({ type: "asset", fileName: path, source });
|
|
2130
|
+
}
|
|
2131
|
+
}
|
|
2132
|
+
);
|
|
2133
|
+
result.set(entry.sourcePath, {
|
|
2134
|
+
packageUrl: finalized.packageUrl,
|
|
2135
|
+
receiptUrls: new Map(
|
|
2136
|
+
[...receiptPaths].map(([guid, path]) => [guid, context.sink.fileUrl(path)])
|
|
2137
|
+
),
|
|
2138
|
+
revision,
|
|
2139
|
+
publication: runtimePublication.publication,
|
|
2140
|
+
refs: facts.refs
|
|
2141
|
+
});
|
|
2142
|
+
}
|
|
2143
|
+
return result;
|
|
2144
|
+
}
|
|
2145
|
+
function updateImportedEntries(entries, guids, packageUrl, projection = {}, refsByGuid, publication) {
|
|
2146
|
+
const selected = new Set(guids.map((guid) => guid.toLowerCase()));
|
|
2147
|
+
for (let index = 0; index < entries.length; index += 1) {
|
|
2148
|
+
const entry = entries[index];
|
|
2149
|
+
if (entry === void 0 || !selected.has(entry.guid.toLowerCase())) continue;
|
|
2150
|
+
const refs = refsByGuid?.get(entry.guid.toLowerCase());
|
|
2151
|
+
entries[index] = {
|
|
2152
|
+
...entry,
|
|
2153
|
+
packageUrl,
|
|
2154
|
+
...projection,
|
|
2155
|
+
...publication === void 0 ? {} : { publication },
|
|
2156
|
+
...refs === void 0 ? {} : { refs }
|
|
2157
|
+
};
|
|
2158
|
+
}
|
|
2159
|
+
}
|
|
2160
|
+
async function emitPackDocument(work, options) {
|
|
2161
|
+
for (const artifact of options.artifacts) {
|
|
2162
|
+
work.context.sink.emitFile({
|
|
2163
|
+
type: "asset",
|
|
2164
|
+
fileName: `assets/${artifact.path}`,
|
|
2165
|
+
source: artifact.bytes
|
|
2166
|
+
});
|
|
2167
|
+
}
|
|
2168
|
+
const referenceId = work.context.sink.emitFile({
|
|
2169
|
+
type: "asset",
|
|
2170
|
+
name: options.packageName,
|
|
2171
|
+
originalFileName: options.originalFileName,
|
|
2172
|
+
source: JSON.stringify(options.pack)
|
|
2173
|
+
});
|
|
2174
|
+
const packageUrl = work.context.sink.fileUrl(work.context.sink.getFileName(referenceId));
|
|
2175
|
+
updateImportedEntries(
|
|
2176
|
+
work.importedEntries,
|
|
2177
|
+
options.guids,
|
|
2178
|
+
packageUrl,
|
|
2179
|
+
options.projection,
|
|
2180
|
+
options.refsByGuid,
|
|
2181
|
+
options.publication
|
|
2182
|
+
);
|
|
2183
|
+
return packageUrl;
|
|
2184
|
+
}
|
|
2185
|
+
async function emitAuthoredPack(work, guidSeen, entry) {
|
|
2186
|
+
const packPath = resolve(work.context.cwd, entry.sourcePath);
|
|
2187
|
+
const declaration = work.context.inventory.sourceDeclarations.get(packPath);
|
|
2188
|
+
if (declaration?.format !== "pack.json") {
|
|
2189
|
+
throw work.context.fail({
|
|
2190
|
+
code: "catalog-declaration-missing",
|
|
2191
|
+
expected: "the inventory to retain the authored Pack declaration",
|
|
2192
|
+
hint: "rerun Pack inventory before emitting the authored Pack",
|
|
2193
|
+
detail: { stage: "scan", sourcePath: packPath }
|
|
2194
|
+
});
|
|
2195
|
+
}
|
|
2196
|
+
const prepared = await prepareAuthoredPackTransport(
|
|
2197
|
+
declaration.value,
|
|
2198
|
+
work.context.cookers,
|
|
2199
|
+
(guid) => ({
|
|
2200
|
+
base: work.context.basePrefix === "" ? "/" : work.context.basePrefix,
|
|
2201
|
+
packagePath: `assets/${guid}.pack.json`,
|
|
2202
|
+
artifactPath: (artifactGuid, key) => `${artifactGuid}/${key}.bin`
|
|
2203
|
+
}),
|
|
2204
|
+
packPath
|
|
2205
|
+
);
|
|
2206
|
+
const outputGuid = prepared.firstGuid ?? entry.guid;
|
|
2207
|
+
const authoredPack = prepared.finalized?.pack ?? prepared.pack;
|
|
2208
|
+
const runtimePublication = authoredPack.assets === void 0 || authoredPack.assets.length === 0 ? void 0 : runtimePublicationFor(work.context, {
|
|
2209
|
+
pack: { assets: authoredPack.assets },
|
|
2210
|
+
sourcePath: packPath,
|
|
2211
|
+
sourceRevision: prepared.finalized?.sourceRevision ?? entry.sourcePath,
|
|
2212
|
+
packageUrl: prepared.finalized?.packageUrl ?? `${work.context.basePrefix === "/" ? "" : work.context.basePrefix}/assets/${outputGuid}.pack.json`,
|
|
2213
|
+
...prepared.finalized?.digest === void 0 ? {} : { digest: prepared.finalized.digest }
|
|
2214
|
+
});
|
|
2215
|
+
await emitPackDocument(work, {
|
|
2216
|
+
pack: runtimePublication?.pack ?? authoredPack,
|
|
2217
|
+
artifacts: prepared.finalized?.artifacts ?? [],
|
|
2218
|
+
packageName: `${outputGuid}.pack.json`,
|
|
2219
|
+
originalFileName: packPath,
|
|
2220
|
+
guids: prepared.pack.assets?.map((asset) => asset.guid) ?? [outputGuid],
|
|
2221
|
+
projection: prepared.finalized === void 0 ? work.context.directCurrentProjection : work.context.authoredCookedCurrentProjection,
|
|
2222
|
+
...prepared.cooked === void 0 ? {} : { refsByGuid: prepared.cooked.refsByGuid },
|
|
2223
|
+
...runtimePublication === void 0 ? {} : { publication: runtimePublication.publication }
|
|
2224
|
+
});
|
|
2225
|
+
for (const guid of prepared.pack.assets?.map((asset) => asset.guid) ?? [outputGuid]) {
|
|
2226
|
+
guidSeen.add(guid.toLowerCase());
|
|
2227
|
+
}
|
|
2228
|
+
}
|
|
2229
|
+
async function emitFinalizedOwner(work, metaPath, subAssets, sourcePackage, ownerFinalizer) {
|
|
2230
|
+
const ownerGuid = subAssets[0]?.guid;
|
|
2231
|
+
if (ownerGuid === void 0) return;
|
|
2232
|
+
const artifactPaths = /* @__PURE__ */ new Map();
|
|
2233
|
+
const sourceAsset = sourcePackage.product.assets[0];
|
|
2234
|
+
for (const [path, artifact] of Object.entries(sourceAsset?.artifacts ?? {})) {
|
|
2235
|
+
const ref2 = work.context.sink.emitFile({
|
|
2236
|
+
type: "asset",
|
|
2237
|
+
name: path,
|
|
2238
|
+
originalFileName: path,
|
|
2239
|
+
source: artifact.bytes
|
|
2240
|
+
});
|
|
2241
|
+
artifactPaths.set(path, work.context.sink.getFileName(ref2));
|
|
2242
|
+
}
|
|
2243
|
+
const ownerProduct = finalizeSourcePackage(
|
|
2244
|
+
sourcePackage.product,
|
|
2245
|
+
ownerFinalizer,
|
|
2246
|
+
(artifact) => work.context.sink.fileUrl(artifactPaths.get(artifact.path) ?? artifact.path)
|
|
2247
|
+
);
|
|
2248
|
+
if (!ownerProduct.ok) throw work.context.fail(ownerProduct.error);
|
|
2249
|
+
const ownerPackage = await finalizePackageTransportSource(
|
|
2250
|
+
projectImportProductForBuild(ownerProduct.value),
|
|
2251
|
+
{
|
|
2252
|
+
base: work.context.basePrefix,
|
|
2253
|
+
packagePath: `assets/${ownerGuid}.pack.json`,
|
|
2254
|
+
artifactPath: (_guid, key) => {
|
|
2255
|
+
const emittedPath = artifactPaths.get(key);
|
|
2256
|
+
if (emittedPath === void 0) {
|
|
2257
|
+
throw work.context.fail({
|
|
2258
|
+
code: "producer-artifact-missing",
|
|
2259
|
+
expected: `producer artifact ${key} to be emitted before Pack finalization`,
|
|
2260
|
+
hint: "repair the importer finalizer artifact closure and rebuild",
|
|
2261
|
+
detail: { stage: "finalize", metaPath, artifact: key }
|
|
2262
|
+
});
|
|
2263
|
+
}
|
|
2264
|
+
return emittedPath.replace(/^assets\//, "");
|
|
2265
|
+
},
|
|
2266
|
+
sink: () => {
|
|
2267
|
+
}
|
|
2268
|
+
}
|
|
2269
|
+
);
|
|
2270
|
+
const runtimePublication = runtimePublicationFor(work.context, {
|
|
2271
|
+
pack: { assets: ownerPackage.pack.assets },
|
|
2272
|
+
sourcePath: metaPath,
|
|
2273
|
+
sourceRevision: ownerPackage.sourceRevision,
|
|
2274
|
+
packageUrl: ownerPackage.packageUrl,
|
|
2275
|
+
digest: ownerPackage.digest
|
|
2276
|
+
});
|
|
2277
|
+
await emitPackDocument(work, {
|
|
2278
|
+
pack: runtimePublication.pack,
|
|
2279
|
+
artifacts: ownerPackage.artifacts,
|
|
2280
|
+
packageName: `${ownerGuid}.pack.json`,
|
|
2281
|
+
originalFileName: metaPath,
|
|
2282
|
+
guids: subAssets.map((sub) => sub.guid),
|
|
2283
|
+
projection: work.context.cookedCurrentProjection,
|
|
2284
|
+
refsByGuid: new Map(
|
|
2285
|
+
ownerProduct.value.assets.map((asset) => [
|
|
2286
|
+
asset.guid.toLowerCase(),
|
|
2287
|
+
asset.refs.map((ref2) => ref2.guid)
|
|
2288
|
+
])
|
|
2289
|
+
),
|
|
2290
|
+
publication: runtimePublication.publication
|
|
2291
|
+
});
|
|
2292
|
+
}
|
|
2293
|
+
async function emitBuildEntry(work, guidSeen, entry) {
|
|
2294
|
+
const guid = entry.guid.toLowerCase();
|
|
2295
|
+
const metaPath = metaPathForGuid(work.context.inventory.declarations, guid);
|
|
2296
|
+
if (metaPath === void 0) {
|
|
2297
|
+
if (entry.sourcePath.endsWith(".pack.json")) await emitAuthoredPack(work, guidSeen, entry);
|
|
2298
|
+
else guidSeen.add(guid);
|
|
2299
|
+
return;
|
|
2300
|
+
}
|
|
2301
|
+
const declaration = work.context.inventory.declarations.get(metaPath);
|
|
2302
|
+
if (declaration === void 0) {
|
|
2303
|
+
throw work.context.fail({
|
|
2304
|
+
code: "catalog-declaration-missing",
|
|
2305
|
+
expected: "every indexed Meta path to have one validated producer declaration",
|
|
2306
|
+
hint: "rerun the inventory and repair the Catalog declaration index",
|
|
2307
|
+
detail: { metaPath }
|
|
2308
|
+
});
|
|
2309
|
+
}
|
|
2310
|
+
const runMeta = { ...declaration, buildPack: false };
|
|
2311
|
+
const subAssets = runMeta.subAssets;
|
|
2312
|
+
for (const sub of subAssets) guidSeen.add(sub.guid.toLowerCase());
|
|
2313
|
+
const sourcePackage = await produceSourcePackage({
|
|
2314
|
+
meta: runMeta,
|
|
2315
|
+
registry: work.context.importerRegistry,
|
|
2316
|
+
fs: work.context.fsForImport
|
|
2317
|
+
});
|
|
2318
|
+
if (!sourcePackage.ok) throw work.context.fail(sourcePackage.error);
|
|
2319
|
+
const ownerFinalizer = work.context.importerRegistry.get(runMeta.importer)?.finalize;
|
|
2320
|
+
if (ownerFinalizer !== void 0) {
|
|
2321
|
+
await emitFinalizedOwner(work, metaPath, subAssets, sourcePackage.value, ownerFinalizer);
|
|
2322
|
+
return;
|
|
2323
|
+
}
|
|
2324
|
+
const finalized = await finalizePackageTransportSource(
|
|
2325
|
+
projectImportProductForBuild(sourcePackage.value.product),
|
|
2326
|
+
{
|
|
2327
|
+
base: work.context.basePrefix,
|
|
2328
|
+
packagePath: `assets/${subAssets[0]?.guid ?? "pack"}.pack.json`,
|
|
2329
|
+
artifactPath: (assetGuid, key) => `${assetGuid}-${key}.bin`,
|
|
2330
|
+
sink: () => {
|
|
2331
|
+
}
|
|
2332
|
+
}
|
|
2333
|
+
);
|
|
2334
|
+
const productByGuid = sourcePackageAssetsByGuid(sourcePackage.value);
|
|
2335
|
+
const runtimePublication = runtimePublicationFor(work.context, {
|
|
2336
|
+
pack: { assets: finalized.pack.assets },
|
|
2337
|
+
sourcePath: metaPath,
|
|
2338
|
+
sourceRevision: finalized.sourceRevision,
|
|
2339
|
+
packageUrl: finalized.packageUrl,
|
|
2340
|
+
digest: finalized.digest
|
|
2341
|
+
});
|
|
2342
|
+
await emitPackDocument(work, {
|
|
2343
|
+
pack: runtimePublication.pack,
|
|
2344
|
+
artifacts: finalized.artifacts,
|
|
2345
|
+
packageName: `${subAssets[0]?.guid ?? "pack"}.pack.json`,
|
|
2346
|
+
originalFileName: metaPath,
|
|
2347
|
+
guids: subAssets.map((sub) => sub.guid),
|
|
2348
|
+
projection: work.context.cookedCurrentProjection,
|
|
2349
|
+
refsByGuid: new Map(
|
|
2350
|
+
[...productByGuid].map(([guid2, asset]) => [guid2, asset.refs.map((ref2) => ref2.guid)])
|
|
2351
|
+
),
|
|
2352
|
+
publication: runtimePublication.publication
|
|
2353
|
+
});
|
|
2354
|
+
}
|
|
2355
|
+
async function produceBuildAssets(context) {
|
|
2356
|
+
const entries = [...context.inventory.entries];
|
|
2357
|
+
const authored = await buildAuthoredPackages(context);
|
|
2358
|
+
const importedEntries = entries.map((entry) => {
|
|
2359
|
+
const scriptable = authored.get(entry.sourcePath);
|
|
2360
|
+
if (scriptable === void 0) return entry;
|
|
2361
|
+
const cookReceiptUrl = scriptable.receiptUrls.get(entry.guid.toLowerCase());
|
|
2362
|
+
return projectCookedPackageEntry(entry, {
|
|
2363
|
+
packageUrl: scriptable.packageUrl,
|
|
2364
|
+
revision: scriptable.revision,
|
|
2365
|
+
refs: scriptable.refs.get(entry.guid.toLowerCase()) ?? [],
|
|
2366
|
+
...cookReceiptUrl === void 0 ? {} : { cookReceiptUrl },
|
|
2367
|
+
publication: scriptable.publication
|
|
2368
|
+
});
|
|
2369
|
+
});
|
|
2370
|
+
const guidSeen = /* @__PURE__ */ new Set();
|
|
2371
|
+
const work = { importedEntries, context };
|
|
2372
|
+
for (const entry of importedEntries) {
|
|
2373
|
+
if (!guidSeen.has(entry.guid.toLowerCase())) await emitBuildEntry(work, guidSeen, entry);
|
|
2374
|
+
}
|
|
2375
|
+
return importedEntries;
|
|
2376
|
+
}
|
|
2377
|
+
|
|
2378
|
+
// src/catalog-importer-policy.ts
|
|
2379
|
+
var DEFAULT_CATALOG_IMPORTER_KEYS = [
|
|
2380
|
+
"image",
|
|
2381
|
+
"gltf",
|
|
2382
|
+
"fbx",
|
|
2383
|
+
"audio",
|
|
2384
|
+
"font",
|
|
2385
|
+
"ui"
|
|
2386
|
+
];
|
|
2387
|
+
function catalogImporterPolicy(importer, hostImporterKeys) {
|
|
2388
|
+
if (importer === SHADER_RESERVED_IMPORTER_KEY) {
|
|
2389
|
+
return {
|
|
2390
|
+
disposition: "exclude",
|
|
2391
|
+
hostProvided: false,
|
|
2392
|
+
expected: "the provider must publish cooked runtime output before Catalog projection",
|
|
2393
|
+
hint: "remove the source declaration from Pack roots or publish its cooked runtime module"
|
|
2394
|
+
};
|
|
2395
|
+
}
|
|
2396
|
+
if (DEFAULT_CATALOG_IMPORTER_KEYS.includes(importer)) {
|
|
2397
|
+
return {
|
|
2398
|
+
disposition: "publish",
|
|
2399
|
+
hostProvided: false,
|
|
2400
|
+
expected: "a standard Catalog provider declaration",
|
|
2401
|
+
hint: "let the provider producer materialize the declared output"
|
|
2402
|
+
};
|
|
2403
|
+
}
|
|
2404
|
+
if (hostImporterKeys.has(importer)) {
|
|
2405
|
+
return {
|
|
2406
|
+
disposition: "publish",
|
|
2407
|
+
hostProvided: true,
|
|
2408
|
+
expected: "a registered host Catalog provider declaration",
|
|
2409
|
+
hint: "let the registered provider materialize the declared output"
|
|
2410
|
+
};
|
|
2411
|
+
}
|
|
2412
|
+
return {
|
|
2413
|
+
disposition: "missing",
|
|
2414
|
+
hostProvided: false,
|
|
2415
|
+
expected: "the sidecar importer must be present in the registered provider set",
|
|
2416
|
+
hint: "wire the provider through the host importer registry before building the Catalog"
|
|
2417
|
+
};
|
|
2418
|
+
}
|
|
2419
|
+
async function buildCatalogResult(roots, base = "/", registeredImporterKeys = /* @__PURE__ */ new Set(), scanOptions = {}, catalogVisibility = () => true) {
|
|
2420
|
+
const options = {
|
|
2421
|
+
base,
|
|
2422
|
+
scanOptions,
|
|
2423
|
+
importerPolicy: (importer) => catalogImporterPolicy(importer, registeredImporterKeys),
|
|
2424
|
+
visibility: catalogVisibility
|
|
2425
|
+
};
|
|
2426
|
+
return buildCatalogProjection(roots, options);
|
|
2427
|
+
}
|
|
2428
|
+
|
|
2429
|
+
// src/importer-registry.ts
|
|
2430
|
+
var ImporterRegistry = class {
|
|
2431
|
+
importers = /* @__PURE__ */ new Map();
|
|
2432
|
+
/**
|
|
2433
|
+
* Register an importer for its `importer.key`. Fail-fast on a malformed
|
|
2434
|
+
* importer (charter P3); idempotent on a repeated key (last write wins).
|
|
2435
|
+
*
|
|
2436
|
+
* @param importer the `{ key, import }` object to register.
|
|
2437
|
+
* @throws TypeError when `importer.key` is empty or `importer.import` is not
|
|
2438
|
+
* a function - a wire-time misconfiguration the host must fix.
|
|
2439
|
+
*/
|
|
2440
|
+
register(importer) {
|
|
2441
|
+
if (typeof importer.key !== "string" || importer.key.length === 0) {
|
|
2442
|
+
throw new TypeError(
|
|
2443
|
+
`ImporterRegistry.register: importer.key must be a non-empty string (got ${JSON.stringify(importer.key)})`
|
|
2444
|
+
);
|
|
2445
|
+
}
|
|
2446
|
+
if (typeof importer.import !== "function") {
|
|
2447
|
+
throw new TypeError(
|
|
2448
|
+
`ImporterRegistry.register: importer.import must be a function for key "${importer.key}"`
|
|
2449
|
+
);
|
|
2450
|
+
}
|
|
2451
|
+
this.importers.set(importer.key, importer);
|
|
2452
|
+
}
|
|
2453
|
+
/**
|
|
2454
|
+
* Look up the importer registered for `key`. Returns `undefined` when no
|
|
2455
|
+
* importer is wired - the import runner maps that to a structured
|
|
2456
|
+
* `ImportError(code='importer-not-registered')` with the registered keys in
|
|
2457
|
+
* `.detail.registeredImporters` (charter P3).
|
|
2458
|
+
*/
|
|
2459
|
+
get(key) {
|
|
2460
|
+
return this.importers.get(key);
|
|
2461
|
+
}
|
|
2462
|
+
/**
|
|
2463
|
+
* The importer keys currently wired, in insertion order. Fed into the
|
|
2464
|
+
* `importer-not-registered` error `.detail.registeredImporters` so AI users
|
|
2465
|
+
* see exactly what is injectable.
|
|
2466
|
+
*/
|
|
2467
|
+
registeredImporters() {
|
|
2468
|
+
return [...this.importers.keys()];
|
|
2469
|
+
}
|
|
2470
|
+
/** Project the first registered producer capability into the runner context. */
|
|
2471
|
+
contextCapabilities() {
|
|
2472
|
+
for (const importer of this.importers.values()) {
|
|
2473
|
+
const decoder = importer.capabilities?.decodeImage;
|
|
2474
|
+
if (decoder !== void 0) return { decodeImage: decoder };
|
|
2475
|
+
}
|
|
2476
|
+
return {};
|
|
2477
|
+
}
|
|
2478
|
+
/** Ask the registered producer whether a declaration has a Catalog product. */
|
|
2479
|
+
shouldPublishCatalog(input) {
|
|
2480
|
+
return this.get(input.importer)?.capabilities?.catalog?.publish?.({
|
|
2481
|
+
importSettings: input.importSettings,
|
|
2482
|
+
subAssets: input.subAssets
|
|
2483
|
+
}) ?? true;
|
|
2484
|
+
}
|
|
2485
|
+
};
|
|
2486
|
+
|
|
2487
|
+
// src/source-package-errors.ts
|
|
2488
|
+
var SOURCE_PACKAGE_ERROR_POLICY = {
|
|
2489
|
+
"source-package-meta-invalid": {
|
|
2490
|
+
expected: "a valid source Meta declaration with complete GUID topology",
|
|
2491
|
+
hint: "repair the Meta declaration, then rebuild or cold-cook the source package"
|
|
2492
|
+
},
|
|
2493
|
+
"source-package-importer-missing": {
|
|
2494
|
+
expected: "a registered importer for the source Meta importer key",
|
|
2495
|
+
hint: "register the named importer, then rebuild or cold-cook the source package"
|
|
2496
|
+
},
|
|
2497
|
+
"source-package-conversion-failed": {
|
|
2498
|
+
expected: "the configured importer to convert the source successfully",
|
|
2499
|
+
hint: "repair the source or importer, then rebuild or cold-cook the source package"
|
|
2500
|
+
},
|
|
2501
|
+
"source-package-ddc-failed": {
|
|
2502
|
+
expected: "a readable persistent DDC entry with matching integrity evidence",
|
|
2503
|
+
hint: "discard the invalid derived entry, then rebuild or cold-cook the source package"
|
|
2504
|
+
},
|
|
2505
|
+
"source-package-publication-invalid": {
|
|
2506
|
+
expected: "a complete Pack body, refs, artifacts, and route integrity",
|
|
2507
|
+
hint: "repair the missing product bytes, then rebuild or cold-cook the source package"
|
|
2508
|
+
},
|
|
2509
|
+
"source-package-guid-closure-mismatch": {
|
|
2510
|
+
expected: "exactly one produced asset for every declared GUID",
|
|
2511
|
+
hint: "repair the Meta topology or importer output, then rebuild the whole source package"
|
|
2512
|
+
}
|
|
2513
|
+
};
|
|
2514
|
+
function sourcePackageError(code, context, detail) {
|
|
2515
|
+
const policy = SOURCE_PACKAGE_ERROR_POLICY[code];
|
|
2516
|
+
return {
|
|
2517
|
+
code,
|
|
2518
|
+
expected: policy?.expected,
|
|
2519
|
+
hint: policy?.hint,
|
|
2520
|
+
detail: { ...context, ...detail }
|
|
2521
|
+
};
|
|
2522
|
+
}
|
|
2523
|
+
function unknownReason(error) {
|
|
2524
|
+
if (error !== null && typeof error === "object") {
|
|
2525
|
+
const value = error;
|
|
2526
|
+
if (typeof value.code === "string") {
|
|
2527
|
+
const detail = value.detail;
|
|
2528
|
+
const reason = detail !== null && typeof detail === "object" && "reason" in detail ? detail.reason : void 0;
|
|
2529
|
+
const diagnostic = detail !== null && typeof detail === "object" && "diagnostic" in detail ? detail.diagnostic : void 0;
|
|
2530
|
+
return `${value.code}: ${typeof diagnostic === "string" ? diagnostic : typeof reason === "string" ? reason : String(value.expected ?? "producer failure")}`;
|
|
2531
|
+
}
|
|
2532
|
+
}
|
|
2533
|
+
return error instanceof Error ? error.message : String(error);
|
|
2534
|
+
}
|
|
2535
|
+
function importFailureCode(error) {
|
|
2536
|
+
switch (error.code) {
|
|
2537
|
+
case "importer-not-registered":
|
|
2538
|
+
return "source-package-importer-missing";
|
|
2539
|
+
case "import-produced-no-assets":
|
|
2540
|
+
case "guid-mismatch":
|
|
2541
|
+
case "source-validation-failed":
|
|
2542
|
+
return "source-package-guid-closure-mismatch";
|
|
2543
|
+
case "source-read-failed":
|
|
2544
|
+
case "import-internal-error":
|
|
2545
|
+
case "mesh-material-slot-topology-change":
|
|
2546
|
+
case "unknown-source-key":
|
|
2547
|
+
case "duplicate-source-key":
|
|
2548
|
+
case "invalid-source-overrides":
|
|
2549
|
+
case "invalid-source-override-payload":
|
|
2550
|
+
return "source-package-conversion-failed";
|
|
2551
|
+
}
|
|
2552
|
+
}
|
|
2553
|
+
function normalizeSourcePackageError(error, context) {
|
|
2554
|
+
if (isSourcePackageError(error)) return error;
|
|
2555
|
+
if (isScriptablePackFailure(error)) {
|
|
2556
|
+
return sourcePackageError("source-package-conversion-failed", context, {
|
|
2557
|
+
stage: "conversion",
|
|
2558
|
+
reason: unknownReason(error)
|
|
2559
|
+
});
|
|
2560
|
+
}
|
|
2561
|
+
if (isImportError(error)) {
|
|
2562
|
+
const code = importFailureCode(error);
|
|
2563
|
+
const detail = {
|
|
2564
|
+
stage: code === "source-package-importer-missing" ? "importer" : "conversion",
|
|
2565
|
+
reason: unknownReason(error),
|
|
2566
|
+
...code === "source-package-importer-missing" && "registeredImporters" in error.detail ? { registeredImporters: error.detail.registeredImporters } : {}
|
|
2567
|
+
};
|
|
2568
|
+
return sourcePackageError(code, context, detail);
|
|
2569
|
+
}
|
|
2570
|
+
return sourcePackageError(contextErrorStage(error), context, {
|
|
2571
|
+
stage: "conversion",
|
|
2572
|
+
reason: unknownReason(error)
|
|
2573
|
+
});
|
|
2574
|
+
}
|
|
2575
|
+
function isSourcePackageError(error) {
|
|
2576
|
+
return error !== null && typeof error === "object" && "code" in error && typeof error.code === "string" && error.code in SOURCE_PACKAGE_ERROR_POLICY && "expected" in error && typeof error.expected === "string" && "hint" in error && typeof error.hint === "string" && "detail" in error && error.detail !== null && typeof error.detail === "object";
|
|
2577
|
+
}
|
|
2578
|
+
function contextErrorStage(error) {
|
|
2579
|
+
return error instanceof SyntaxError ? "source-package-meta-invalid" : "source-package-conversion-failed";
|
|
2580
|
+
}
|
|
2581
|
+
function isImportError(error) {
|
|
2582
|
+
return error !== null && typeof error === "object" && "code" in error && "expected" in error && "hint" in error && "detail" in error;
|
|
2583
|
+
}
|
|
2584
|
+
function isScriptablePackFailure(error) {
|
|
2585
|
+
return error !== null && typeof error === "object" && "code" in error && typeof error.code === "string" && error.code.startsWith("pack-source-") && "expected" in error && typeof error.expected === "string" && "hint" in error && typeof error.hint === "string" && "detail" in error;
|
|
2586
|
+
}
|
|
2587
|
+
function inspectHead(root, guid, desiredKey) {
|
|
2588
|
+
return new DdcLifecycle(root).inspect(guid, desiredKey);
|
|
2589
|
+
}
|
|
2590
|
+
async function stageSourcePackageDdc(input) {
|
|
2591
|
+
const session = new DdcGenerationSession(input.root, { generation: 1 });
|
|
2592
|
+
try {
|
|
2593
|
+
const candidate = await session.stageEntry(input.entry);
|
|
2594
|
+
return ok({ ...candidate, root: input.root, session, context: input.context });
|
|
2595
|
+
} catch (error) {
|
|
2596
|
+
return err(
|
|
2597
|
+
sourcePackageError("source-package-ddc-failed", input.context, {
|
|
2598
|
+
stage: "ddc",
|
|
2599
|
+
reason: error instanceof Error ? error.message : String(error)
|
|
2600
|
+
})
|
|
2601
|
+
);
|
|
2602
|
+
}
|
|
2603
|
+
}
|
|
2604
|
+
async function commitSourcePackageDdc(candidate) {
|
|
2605
|
+
try {
|
|
2606
|
+
const commit = await candidate.session.commitEntry(candidate, candidate.lease.desiredKey);
|
|
2607
|
+
if (commit.result !== "current") {
|
|
2608
|
+
return err(
|
|
2609
|
+
sourcePackageError("source-package-ddc-failed", candidate.context, {
|
|
2610
|
+
stage: "ddc",
|
|
2611
|
+
reason: `DDC lifecycle commit returned ${commit.result}`
|
|
2612
|
+
})
|
|
2613
|
+
);
|
|
2614
|
+
}
|
|
2615
|
+
return ok(await inspectHead(candidate.root, candidate.lease.guid, candidate.lease.desiredKey));
|
|
2616
|
+
} catch (error) {
|
|
2617
|
+
return err(
|
|
2618
|
+
sourcePackageError("source-package-ddc-failed", candidate.context, {
|
|
2619
|
+
stage: "ddc",
|
|
2620
|
+
reason: error instanceof Error ? error.message : String(error)
|
|
2621
|
+
})
|
|
2622
|
+
);
|
|
2623
|
+
}
|
|
2624
|
+
}
|
|
2625
|
+
async function persistTransport(transport) {
|
|
2626
|
+
if (transport === void 0) return true;
|
|
2627
|
+
const directory = dirname(transport.path);
|
|
2628
|
+
const temporary = `${transport.path}.tmp`;
|
|
2629
|
+
try {
|
|
2630
|
+
await mkdir(directory, { recursive: true });
|
|
2631
|
+
if (((await stat(directory)).mode & 146) === 0) {
|
|
2632
|
+
throw new Error("transport directory is read-only");
|
|
2633
|
+
}
|
|
2634
|
+
await writeFile(temporary, transport.body);
|
|
2635
|
+
await rename(temporary, transport.path);
|
|
2636
|
+
return true;
|
|
2637
|
+
} catch {
|
|
2638
|
+
await rm(temporary, { force: true }).catch(() => {
|
|
2639
|
+
});
|
|
2640
|
+
return false;
|
|
2641
|
+
}
|
|
2642
|
+
}
|
|
2643
|
+
function importPublicationFailure(error) {
|
|
2644
|
+
return {
|
|
2645
|
+
code: error.code,
|
|
2646
|
+
expected: error.expected,
|
|
2647
|
+
hint: error.hint,
|
|
2648
|
+
detail: error.detail.reason ?? error.detail.stage,
|
|
2649
|
+
diagnostic: error
|
|
2650
|
+
};
|
|
2651
|
+
}
|
|
2652
|
+
function projectImportPublication(input, head, observedAt) {
|
|
2653
|
+
const digest = head.currentKey ?? input.desiredKey;
|
|
2654
|
+
const revision = { digest, observedAt, rootId: input.root };
|
|
2655
|
+
const published = new Set(input.publishedGuids.map((guid) => guid.toLowerCase()));
|
|
2656
|
+
const catalog = input.nextCatalog.map((row) => {
|
|
2657
|
+
if (!published.has(row.guid.toLowerCase())) return row;
|
|
2658
|
+
const previousLkg = head.lastKnownGoodKey === void 0 ? void 0 : input.previousCatalog.find(
|
|
2659
|
+
(candidate) => candidate.guid.toLowerCase() === row.guid.toLowerCase() && candidate.revision?.digest === head.lastKnownGoodKey
|
|
2660
|
+
);
|
|
2661
|
+
const projection = row.projection === void 0 ? void 0 : (() => {
|
|
2662
|
+
const { lastKnownGood: _staleLastKnownGood, ...withoutLastKnownGood } = row.projection;
|
|
2663
|
+
return previousLkg?.packageUrl === void 0 ? withoutLastKnownGood : { ...withoutLastKnownGood, lastKnownGood: { packageUrl: previousLkg.packageUrl } };
|
|
2664
|
+
})();
|
|
2665
|
+
return {
|
|
2666
|
+
...row,
|
|
2667
|
+
revision,
|
|
2668
|
+
...projection === void 0 ? {} : { projection }
|
|
2669
|
+
};
|
|
2670
|
+
});
|
|
2671
|
+
return { catalog, revision };
|
|
2672
|
+
}
|
|
2673
|
+
async function publishImportPublication(input) {
|
|
2674
|
+
const staged = await stageImportPublication(input);
|
|
2675
|
+
if (!staged.ok) return staged;
|
|
2676
|
+
return commitImportPublication(staged.candidate);
|
|
2677
|
+
}
|
|
2678
|
+
async function stageImportPublication(input) {
|
|
2679
|
+
const staged = await stageSourcePackageDdc({
|
|
2680
|
+
root: input.root,
|
|
2681
|
+
entry: {
|
|
2682
|
+
key: input.desiredKey,
|
|
2683
|
+
guid: input.guid,
|
|
2684
|
+
payload: input.pack,
|
|
2685
|
+
refs: [],
|
|
2686
|
+
artifacts: {},
|
|
2687
|
+
receipt: {
|
|
2688
|
+
guid: input.guid,
|
|
2689
|
+
key: input.desiredKey,
|
|
2690
|
+
producer: "engine-import/source-package-publication",
|
|
2691
|
+
inputFingerprint: input.desiredKey,
|
|
2692
|
+
outputDigest: ddcOutputDigest({
|
|
2693
|
+
guid: input.guid,
|
|
2694
|
+
payload: input.pack,
|
|
2695
|
+
refs: [],
|
|
2696
|
+
artifacts: {}
|
|
2697
|
+
})
|
|
2698
|
+
}
|
|
2699
|
+
},
|
|
2700
|
+
context: {
|
|
2701
|
+
sourceMeta: "<import-publication>",
|
|
2702
|
+
anchorGuid: input.guid,
|
|
2703
|
+
affectedGuids: input.publishedGuids,
|
|
2704
|
+
producer: "source-package/import-publication",
|
|
2705
|
+
importer: "import-publication"
|
|
2706
|
+
}
|
|
2707
|
+
});
|
|
2708
|
+
if (!staged.ok) {
|
|
2709
|
+
return {
|
|
2710
|
+
ok: false,
|
|
2711
|
+
error: importPublicationFailure(staged.error),
|
|
2712
|
+
head: await inspectHead(input.root, input.guid, input.desiredKey)
|
|
2713
|
+
};
|
|
2714
|
+
}
|
|
2715
|
+
const lastKnownGoodKey = staged.value.previousHead.currentKey !== void 0 && staged.value.previousHead.currentKey !== input.desiredKey ? staged.value.previousHead.currentKey : staged.value.previousHead.lastKnownGoodKey;
|
|
2716
|
+
const projectedHead = {
|
|
2717
|
+
...staged.value.previousHead,
|
|
2718
|
+
state: "cooking",
|
|
2719
|
+
currentKey: input.desiredKey,
|
|
2720
|
+
...lastKnownGoodKey === void 0 ? {} : { lastKnownGoodKey }
|
|
2721
|
+
};
|
|
2722
|
+
const projected = projectImportPublication(input, projectedHead, Date.now());
|
|
2723
|
+
return {
|
|
2724
|
+
ok: true,
|
|
2725
|
+
candidate: {
|
|
2726
|
+
input,
|
|
2727
|
+
ddc: staged.value,
|
|
2728
|
+
key: input.desiredKey,
|
|
2729
|
+
head: projectedHead,
|
|
2730
|
+
catalog: projected.catalog,
|
|
2731
|
+
revision: projected.revision
|
|
2732
|
+
}
|
|
2733
|
+
};
|
|
2734
|
+
}
|
|
2735
|
+
async function commitImportPublication(candidate) {
|
|
2736
|
+
const publication = await commitSourcePackageDdc(candidate.ddc);
|
|
2737
|
+
if (!publication.ok) {
|
|
2738
|
+
return {
|
|
2739
|
+
ok: false,
|
|
2740
|
+
error: importPublicationFailure(publication.error),
|
|
2741
|
+
head: await inspectHead(
|
|
2742
|
+
candidate.input.root,
|
|
2743
|
+
candidate.input.guid,
|
|
2744
|
+
candidate.input.desiredKey
|
|
2745
|
+
)
|
|
2746
|
+
};
|
|
2747
|
+
}
|
|
2748
|
+
const projected = projectImportPublication(candidate.input, publication.value, Date.now());
|
|
2749
|
+
return {
|
|
2750
|
+
ok: true,
|
|
2751
|
+
key: candidate.input.desiredKey,
|
|
2752
|
+
head: publication.value,
|
|
2753
|
+
catalog: projected.catalog,
|
|
2754
|
+
revision: projected.revision,
|
|
2755
|
+
transportPersisted: await persistTransport(candidate.input.transport)
|
|
2756
|
+
};
|
|
2757
|
+
}
|
|
2758
|
+
async function discardImportPublication(candidate) {
|
|
2759
|
+
await candidate.ddc.session.discardEntry(candidate.ddc);
|
|
2760
|
+
}
|
|
2761
|
+
async function restoreImportPublication(candidate) {
|
|
2762
|
+
await candidate.ddc.session.restoreEntry(candidate.ddc);
|
|
2763
|
+
}
|
|
1604
2764
|
|
|
1605
|
-
export { AssetOutputProducerRegistry, ImporterRegistry, SHADER_RESERVED_IMPORTER_KEY, buildScriptablePack,
|
|
2765
|
+
export { AssetOutputProducerRegistry, DEFAULT_CATALOG_IMPORTER_KEYS, ImporterRegistry, SHADER_RESERVED_IMPORTER_KEY, buildCatalogResult, buildScriptablePack, canonicalScriptableSourcePath, catalogImporterPolicy, commitImportPublication, createImportProduct, createSceneAssetOutputProducer, createScriptablePackStagedAssetSnapshotSource, createStandardAssetOutputProducerRegistry, declaredPackExternalOutputs, discardImportPublication, finalizeImportProducts, finalizeSourcePackage, materialAssetOutputProducer, materializePreparedScriptablePack, meshAssetOutputProducer, normaliseForPack, normalizeSourcePackageError, packMeshBinV4, parseProducerReadiness, prepareAuthoredPackTransport, produceBuildAssets, produceScriptablePackProducts, produceScriptableSourcePackage, produceSourcePackage, projectImportProductForBuild, projectScriptablePackPublication, publishImportPublication, readCookedAuthoredPack, restoreImportPublication, runImport, scriptablePackInputs, sourcePackageAssetsByGuid, sourcePackageError, stageImportPublication };
|
|
1606
2766
|
//# sourceMappingURL=index.mjs.map
|
|
1607
2767
|
//# sourceMappingURL=index.mjs.map
|