@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.
Files changed (30) hide show
  1. package/README.md +5 -5
  2. package/dist/__tests__/scriptable-pack-build.unit.test.d.ts +2 -0
  3. package/dist/__tests__/scriptable-pack-build.unit.test.d.ts.map +1 -0
  4. package/dist/build-production.d.ts.map +1 -1
  5. package/dist/index.d.ts +4 -4
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.mjs +284 -60
  8. package/dist/index.mjs.map +1 -1
  9. package/dist/{parameterized-scriptable-pack.d.ts → scriptable-pack-build.d.ts} +20 -15
  10. package/dist/scriptable-pack-build.d.ts.map +1 -0
  11. package/dist/scriptable-pack-host.d.ts +15 -13
  12. package/dist/scriptable-pack-host.d.ts.map +1 -1
  13. package/dist/scriptable-pack.d.ts +2 -1
  14. package/dist/scriptable-pack.d.ts.map +1 -1
  15. package/dist/source-package-publication.d.ts +7 -0
  16. package/dist/source-package-publication.d.ts.map +1 -1
  17. package/package.json +8 -8
  18. package/src/__tests__/{parameterized-scriptable-pack.unit.test.ts → scriptable-pack-build.unit.test.ts} +11 -14
  19. package/src/__tests__/scriptable-pack-host.unit.test.ts +53 -5
  20. package/src/__tests__/scriptable-pack-output-producers.unit.test.ts +4 -5
  21. package/src/__tests__/source-package-publication.integration.test.ts +141 -0
  22. package/src/build-production.ts +45 -50
  23. package/src/index.ts +17 -16
  24. package/src/{parameterized-scriptable-pack.ts → scriptable-pack-build.ts} +91 -27
  25. package/src/scriptable-pack-host.ts +48 -40
  26. package/src/scriptable-pack.ts +2 -1
  27. package/src/source-package-publication.ts +242 -10
  28. package/dist/__tests__/parameterized-scriptable-pack.unit.test.d.ts +0 -2
  29. package/dist/__tests__/parameterized-scriptable-pack.unit.test.d.ts.map +0 -1
  30. package/dist/parameterized-scriptable-pack.d.ts.map +0 -1
@@ -1,6 +1,7 @@
1
1
  import { BUILTIN_MESH_ASSETS } from '@forgeax/engine-pack/builtin';
2
+ import { type NativeCooker, NativeCookerRegistry } from '@forgeax/engine-pack/native-cooker';
2
3
  import {
3
- type AnyParameterizedPackDefinition,
4
+ type AnyScriptablePackDefinition,
4
5
  AssetGuid,
5
6
  isScriptablePackAssetKind,
6
7
  isValidPackSourceKey,
@@ -12,6 +13,7 @@ import {
12
13
  type PackParameterValue,
13
14
  resolvePackParameterValues,
14
15
  } from '@forgeax/engine-pack/source';
16
+ import { DEFAULT_STANDARD_SURFACE_MODULE } from '@forgeax/engine-shader';
15
17
  import type {
16
18
  Asset,
17
19
  AssetGuid as AssetGuidType,
@@ -28,16 +30,16 @@ import {
28
30
  import type {
29
31
  AssetOutputProducer,
30
32
  AssetOutputProducerRegistry,
33
+ PackBuildProduct,
31
34
  ScriptablePackAssetSnapshotSource,
32
- ScriptablePackBuildProduct,
33
35
  ScriptablePackDomainError,
34
36
  ScriptablePackExternalEvidence,
35
37
  ScriptablePackSourceClosureEntry,
36
38
  ScriptablePackStagedOutput,
37
39
  } from './scriptable-pack.js';
38
40
 
39
- export interface ParameterizedScriptablePackBuildOptions {
40
- readonly definition: AnyParameterizedPackDefinition;
41
+ export interface ScriptablePackBuildOptions {
42
+ readonly definition: AnyScriptablePackDefinition;
41
43
  readonly sourcePath: string;
42
44
  /** Instance identity. Omitted for a root source and defaults to definition.packageId. */
43
45
  readonly subjectPackageId?: PackageId;
@@ -47,6 +49,8 @@ export interface ParameterizedScriptablePackBuildOptions {
47
49
  readonly inheritedValues?: Readonly<Record<string, PackParameterValue>>;
48
50
  readonly assetSource?: ScriptablePackAssetSnapshotSource;
49
51
  readonly outputs: AssetOutputProducerRegistry;
52
+ /** Optional build-time cookers for authored producer outputs that need artifacts. */
53
+ readonly cookers?: readonly NativeCooker[];
50
54
  readonly sourceClosure?: readonly ScriptablePackSourceClosureEntry[];
51
55
  readonly authoringContractVersion?: string;
52
56
  /** Known published GUIDs used for the optional global reference gate. */
@@ -56,12 +60,12 @@ export interface ParameterizedScriptablePackBuildOptions {
56
60
  readonly publication?: AssetPublicationEnvelope;
57
61
  }
58
62
 
59
- export interface ParameterizedScriptablePackBuildProduct extends ScriptablePackBuildProduct {
63
+ export interface ScriptablePackBuildProduct extends PackBuildProduct {
60
64
  readonly publication?: AssetPublicationEnvelope;
61
65
  }
62
66
 
63
- export type ParameterizedScriptablePackBuildResult = Result<
64
- ParameterizedScriptablePackBuildProduct,
67
+ export type ScriptablePackBuildResult = Result<
68
+ ScriptablePackBuildProduct,
65
69
  | PackAuthoringError
66
70
  | ScriptablePackDomainError
67
71
  | AssetError
@@ -89,6 +93,23 @@ function isAsset(value: unknown): value is Asset {
89
93
  return record(value) && typeof value.kind === 'string' && isScriptablePackAssetKind(value.kind);
90
94
  }
91
95
 
96
+ function needsMaterialCook(asset: Asset): asset is Extract<Asset, { readonly kind: 'material' }> {
97
+ if (asset.kind !== 'material' || !Array.isArray(asset.passes)) return false;
98
+ return asset.passes.some((pass) => {
99
+ const module = pass.program.module;
100
+ const surface = pass.program.moduleSlots?.surface;
101
+ return (
102
+ surface !== undefined &&
103
+ surface !== DEFAULT_STANDARD_SURFACE_MODULE &&
104
+ (module === 'forgeax_material::standard' ||
105
+ module === 'forgeax::default-standard-pbr' ||
106
+ module === 'forgeax_material::pbr-skin' ||
107
+ module === 'forgeax::pbr-skin' ||
108
+ module === 'forgeax::default-standard-pbr-skin')
109
+ );
110
+ });
111
+ }
112
+
92
113
  function clone<T>(value: T): T {
93
114
  return structuredClone(value);
94
115
  }
@@ -289,9 +310,9 @@ function normalizedGuidSet(value: ReadonlySet<string> | undefined): Set<string>
289
310
  * Execute a v2 Pack source and project its dynamic output map through the
290
311
  * existing importer producers. No output GUID or output manifest is read.
291
312
  */
292
- export async function buildParameterizedScriptablePack(
293
- options: ParameterizedScriptablePackBuildOptions,
294
- ): Promise<ParameterizedScriptablePackBuildResult> {
313
+ export async function buildScriptablePack(
314
+ options: ScriptablePackBuildOptions,
315
+ ): Promise<ScriptablePackBuildResult> {
295
316
  const subjectPackageId = options.subjectPackageId ?? options.definition.packageId;
296
317
  const availableGuids = normalizedGuidSet(options.availableGuids);
297
318
  const observed = observedReader(options.assetSource);
@@ -319,8 +340,8 @@ export async function buildParameterizedScriptablePack(
319
340
  PackageId.format(options.definition.packageId).toLowerCase()
320
341
  ) {
321
342
  return err({
322
- code: 'pack-parent-not-parameterized',
323
- expected: 'a parameterized Pack source for an independent instance packageId',
343
+ code: 'pack-parent-has-no-parameters',
344
+ expected: 'a ScriptablePack source with parameters for an independent instance packageId',
324
345
  hint: 'use clone for a zero-parameter Pack instead of building it as an instance',
325
346
  detail: {
326
347
  sourcePath: options.sourcePath,
@@ -384,6 +405,9 @@ export async function buildParameterizedScriptablePack(
384
405
  const imported: ImportedAsset<unknown>[] = [];
385
406
  const stagedOutputs: ScriptablePackStagedOutput[] = [];
386
407
  const localGuids = new Set<string>();
408
+ const materialCookerRegistry = new NativeCookerRegistry();
409
+ for (const cooker of options.cookers ?? []) materialCookerRegistry.register(cooker);
410
+ const nativeFingerprints = new Map<string, string>();
387
411
  for (const sourceKey of Object.keys(built.value).sort()) {
388
412
  if (!isValidPackSourceKey(sourceKey))
389
413
  return err(sourceKeyFailure(options.sourcePath, sourceKey));
@@ -459,12 +483,40 @@ export async function buildParameterizedScriptablePack(
459
483
  const invalidProduct = productError(options.sourcePath, sourceKey, producer, produced.value);
460
484
  if (invalidProduct !== undefined) return err(invalidProduct);
461
485
  const product = produced.value as ImportAssetProduct<unknown>;
486
+ let payload = product.payload;
487
+ let artifacts = product.artifacts;
488
+ if (needsMaterialCook(asset) && materialCookerRegistry.get('material') !== undefined) {
489
+ const cooked = await materialCookerRegistry.runDraft('material', {
490
+ guid,
491
+ source: asset,
492
+ sourceKey,
493
+ sourcePath: options.sourcePath,
494
+ refs: product.refs.map((reference) => reference.guid),
495
+ });
496
+ if (!cooked.ok) return err(cooked.error);
497
+ if (cooked.value.guid.toLowerCase() !== normalizedGuid) {
498
+ return err({
499
+ code: 'pack-source-output-invalid',
500
+ expected: 'the authored material cooker to preserve the derived AssetGuid',
501
+ hint: 'repair the native material cooker output GUID and rebuild the Pack',
502
+ detail: {
503
+ sourcePath: options.sourcePath,
504
+ sourceKey,
505
+ expectedGuid: guid,
506
+ actualGuid: cooked.value.guid,
507
+ },
508
+ });
509
+ }
510
+ payload = cooked.value.payload;
511
+ artifacts = cooked.value.artifacts;
512
+ nativeFingerprints.set(sourceKey, cooked.value.inputFingerprint);
513
+ }
462
514
  imported.push({
463
515
  guid,
464
516
  kind: asset.kind,
465
- payload: product.payload,
517
+ payload,
466
518
  refs: product.refs,
467
- artifacts: product.artifacts,
519
+ artifacts,
468
520
  });
469
521
  stagedOutputs.push({
470
522
  guid: AssetGuid.derive(subjectPackageId, sourceKey),
@@ -499,7 +551,7 @@ export async function buildParameterizedScriptablePack(
499
551
  digest: read.digest,
500
552
  }),
501
553
  );
502
- const inputFingerprint = await digest({
554
+ const authoredInputFingerprint = await digest({
503
555
  packageId: PackageId.format(subjectPackageId),
504
556
  sourcePath: options.sourcePath,
505
557
  sourceClosure: options.sourceClosure ?? [],
@@ -509,9 +561,18 @@ export async function buildParameterizedScriptablePack(
509
561
  usage,
510
562
  digest: evidenceDigest,
511
563
  })),
512
- authoringContractVersion: options.authoringContractVersion ?? 'parameterized-pack/1',
564
+ authoringContractVersion: options.authoringContractVersion ?? 'scriptable-pack/1',
513
565
  producerVersions: options.outputs.versions(),
514
566
  });
567
+ const inputFingerprint =
568
+ nativeFingerprints.size === 0
569
+ ? authoredInputFingerprint
570
+ : await digest({
571
+ sourceRevision: authoredInputFingerprint,
572
+ nativeCookers: [...nativeFingerprints.entries()].sort(([left], [right]) =>
573
+ left.localeCompare(right),
574
+ ),
575
+ });
515
576
  const refs = imported.flatMap((asset) => asset.refs);
516
577
  const artifacts = Object.fromEntries(
517
578
  imported.flatMap((asset) =>
@@ -543,8 +604,8 @@ export async function buildParameterizedScriptablePack(
543
604
  });
544
605
  }
545
606
 
546
- export interface ParameterizedScriptablePackWorkItem {
547
- readonly definition: AnyParameterizedPackDefinition;
607
+ export interface ScriptablePackBuildWorkItem {
608
+ readonly definition: AnyScriptablePackDefinition;
548
609
  readonly sourcePath: string;
549
610
  readonly subjectPackageId?: PackageId;
550
611
  readonly values?: Readonly<Record<string, unknown>>;
@@ -552,18 +613,20 @@ export interface ParameterizedScriptablePackWorkItem {
552
613
  readonly sourceClosure?: readonly ScriptablePackSourceClosureEntry[];
553
614
  }
554
615
 
555
- export interface ParameterizedScriptablePackWorklistOptions {
556
- readonly subjects: readonly ParameterizedScriptablePackWorkItem[];
616
+ export interface ScriptablePackBuildWorklistOptions {
617
+ readonly subjects: readonly ScriptablePackBuildWorkItem[];
557
618
  readonly outputs: AssetOutputProducerRegistry;
619
+ /** Optional build-time cookers forwarded to each authored Pack subject. */
620
+ readonly cookers?: readonly NativeCooker[];
558
621
  readonly assetSource?: ScriptablePackAssetSnapshotSource;
559
622
  readonly availableGuids?: ReadonlySet<string>;
560
623
  readonly incomingRefs?: ReadonlyMap<string, readonly string[]>;
561
624
  readonly maxPasses?: number;
562
625
  }
563
626
 
564
- export interface ParameterizedScriptablePackWorklistProduct {
627
+ export interface ScriptablePackBuildWorklistProduct {
565
628
  readonly products: readonly TerminalImportProduct<unknown>[];
566
- readonly buildProducts: readonly ParameterizedScriptablePackBuildProduct[];
629
+ readonly buildProducts: readonly ScriptablePackBuildProduct[];
567
630
  readonly stagedOutputs: readonly ScriptablePackStagedOutput[];
568
631
  readonly iterations: number;
569
632
  }
@@ -597,11 +660,11 @@ function stagedSource(
597
660
  }
598
661
 
599
662
  /** Build subjects in stable passes; content reads may wait for a later subject. */
600
- export async function buildParameterizedScriptablePackWorklist(
601
- options: ParameterizedScriptablePackWorklistOptions,
663
+ export async function buildScriptablePackWorklist(
664
+ options: ScriptablePackBuildWorklistOptions,
602
665
  ): Promise<
603
666
  Result<
604
- ParameterizedScriptablePackWorklistProduct,
667
+ ScriptablePackBuildWorklistProduct,
605
668
  | PackAuthoringError
606
669
  | ScriptablePackDomainError
607
670
  | AssetError
@@ -621,7 +684,7 @@ export async function buildParameterizedScriptablePackWorklist(
621
684
  orderedSubjects.map((subject, index) => [`${index}:${subject.sourcePath}`, subject]),
622
685
  );
623
686
  const staged = new Map<string, ScriptablePackStagedOutput>();
624
- const results = new Map<string, ParameterizedScriptablePackBuildProduct>();
687
+ const results = new Map<string, ScriptablePackBuildProduct>();
625
688
  const availableGuids = new Set([
626
689
  ...(normalizedGuidSet(options.availableGuids) ?? []),
627
690
  ...BUILTIN_MESH_ASSETS.map((asset) => asset.guid.toLowerCase()),
@@ -632,7 +695,7 @@ export async function buildParameterizedScriptablePackWorklist(
632
695
  let progress = false;
633
696
  const waiting = new Set<string>();
634
697
  for (const [key, subject] of pending) {
635
- const result = await buildParameterizedScriptablePack({
698
+ const result = await buildScriptablePack({
636
699
  definition: subject.definition,
637
700
  sourcePath: subject.sourcePath,
638
701
  ...(subject.subjectPackageId === undefined
@@ -644,6 +707,7 @@ export async function buildParameterizedScriptablePackWorklist(
644
707
  : { inheritedValues: subject.inheritedValues }),
645
708
  ...(subject.sourceClosure === undefined ? {} : { sourceClosure: subject.sourceClosure }),
646
709
  outputs: options.outputs,
710
+ ...(options.cookers === undefined ? {} : { cookers: options.cookers }),
647
711
  assetSource: stagedSource(staged, options.assetSource),
648
712
  availableGuids: new Set([...availableGuids, ...staged.keys()]),
649
713
  deferReferenceValidation: true,
@@ -20,10 +20,10 @@ import type {
20
20
  ScanSourceDeclaration,
21
21
  } from '@forgeax/engine-pack/scanner';
22
22
  import {
23
- type AnyParameterizedPackDefinition,
23
+ type AnyScriptablePackDefinition,
24
24
  type DirectPackAssetProjection,
25
25
  isScriptablePackAssetKind,
26
- parseParameterizedPackJson,
26
+ parsePackSourceJson,
27
27
  projectDirectPackJson,
28
28
  projectScriptablePackSceneComponents,
29
29
  type ScriptablePackSourceClosureEntry,
@@ -45,17 +45,17 @@ import { AssetError, err, ok } from '@forgeax/engine-types';
45
45
  import type { DdcPack, ImportRunnerFs, RunImportMeta } from './import-runner.js';
46
46
  import type { ImporterRegistry } from './importer-registry.js';
47
47
  import { projectImportProductForBuild } from './pack-projection.js';
48
- import {
49
- buildParameterizedScriptablePack,
50
- buildParameterizedScriptablePackWorklist,
51
- type ParameterizedScriptablePackBuildProduct,
52
- type ParameterizedScriptablePackWorkItem,
53
- } from './parameterized-scriptable-pack.js';
54
48
  import type {
55
49
  ScriptablePackAssetSnapshotSource,
56
50
  ScriptablePackDomainError,
57
51
  ScriptablePackStagedOutput,
58
52
  } from './scriptable-pack.js';
53
+ import {
54
+ buildScriptablePack,
55
+ buildScriptablePackWorklist,
56
+ type ScriptablePackBuildProduct,
57
+ type ScriptablePackBuildWorkItem,
58
+ } from './scriptable-pack-build.js';
59
59
  import {
60
60
  createPreExternalizedSceneAssetOutputProducer,
61
61
  createStandardAssetOutputProducerRegistry,
@@ -64,15 +64,15 @@ import { produceSourcePackage } from './source-package.js';
64
64
 
65
65
  type FinalizedPackageTransport = Awaited<ReturnType<typeof finalizePackageTransportSource>>;
66
66
 
67
- export interface ParameterizedScriptablePackInput {
67
+ export interface ScriptablePackInput {
68
68
  readonly sourcePath: string;
69
69
  readonly displaySourcePath: string;
70
- readonly definition: AnyParameterizedPackDefinition;
70
+ readonly definition: AnyScriptablePackDefinition;
71
71
  readonly sourceClosure: readonly ScriptablePackSourceClosureEntry[];
72
72
  readonly publicationGeneration: number;
73
73
  readonly policy:
74
74
  | PackageFinalizePolicy
75
- | ((product: ParameterizedScriptablePackBuildProduct) => PackageFinalizePolicy);
75
+ | ((product: ScriptablePackBuildProduct) => PackageFinalizePolicy);
76
76
  readonly subjectPackageId?: PackageIdType;
77
77
  readonly values?: Readonly<Record<string, unknown>>;
78
78
  readonly inheritedValues?: Readonly<
@@ -80,18 +80,20 @@ export interface ParameterizedScriptablePackInput {
80
80
  >;
81
81
  }
82
82
 
83
- export interface PreparedParameterizedScriptablePack {
84
- readonly product: ParameterizedScriptablePackBuildProduct;
83
+ export interface PreparedScriptablePack {
84
+ readonly product: ScriptablePackBuildProduct;
85
85
  readonly finalized: FinalizedPackageTransport;
86
86
  readonly facts: ScriptablePackPublicationFacts;
87
87
  readonly revision: ResourceRevision;
88
88
  readonly publication: AssetPublicationEnvelope;
89
89
  }
90
90
 
91
- export interface ParameterizedScriptablePackProductionOptions {
92
- readonly sources: readonly ParameterizedScriptablePackInput[];
91
+ export interface ScriptablePackProductionOptions {
92
+ readonly sources: readonly ScriptablePackInput[];
93
93
  readonly declaredExternalOutputs?: readonly ScriptablePackStagedOutput[];
94
94
  readonly assetSource?: ScriptablePackAssetSnapshotSource;
95
+ /** Build-time producers used for custom or otherwise uncooked asset rows. */
96
+ readonly cookers?: readonly NativeCooker[];
95
97
  readonly availableGuids?: ReadonlySet<string>;
96
98
  readonly incomingRefs?: ReadonlyMap<string, readonly string[]>;
97
99
  readonly maxPasses?: number;
@@ -211,7 +213,7 @@ export async function declaredPackExternalOutputs(
211
213
  }
212
214
  if (declaration.format !== 'pack.json') continue;
213
215
  if (declaration.value.schemaVersion === '3.0.0') {
214
- const parsed = parseParameterizedPackJson(declaration.value);
216
+ const parsed = parsePackSourceJson(declaration.value);
215
217
  if (!parsed.ok || parsed.value.format !== 'direct') continue;
216
218
  const projected = projectDirectPackJson(parsed.value);
217
219
  if (!projected.ok) continue;
@@ -299,6 +301,13 @@ export async function readCookedAuthoredPack(
299
301
  continue;
300
302
  }
301
303
  if (isEngineOwnedMaterial(asset)) {
304
+ // Engine-owned material payloads are already cooked, but a legacy Pack
305
+ // source still needs to be projected into the runtime transport route.
306
+ // Mark the package as cooked so prepareLegacyPackTransport stages a
307
+ // published body instead of falling back to the source URL, which the
308
+ // dev route intentionally rejects for cooked v2 inputs.
309
+ hasCookedAsset = true;
310
+ refsByGuid.set(asset.guid.toLowerCase(), [...asset.refs]);
302
311
  assets.push({
303
312
  guid: asset.guid,
304
313
  kind: asset.kind,
@@ -352,7 +361,7 @@ export interface DirectPackTransport {
352
361
  readonly packageId: string;
353
362
  readonly assets: readonly DirectPackAssetProjection[];
354
363
  };
355
- readonly product: ParameterizedScriptablePackBuildProduct;
364
+ readonly product: ScriptablePackBuildProduct;
356
365
  readonly finalized: FinalizedPackageTransport;
357
366
  readonly facts: ScriptablePackPublicationFacts;
358
367
  readonly revision: ResourceRevision;
@@ -429,9 +438,7 @@ function importedAssetArtifacts(
429
438
  );
430
439
  }
431
440
 
432
- function rawDirectProduct(
433
- input: DirectPackTransportInput,
434
- ): ParameterizedScriptablePackBuildProduct {
441
+ function rawDirectProduct(input: DirectPackTransportInput): ScriptablePackBuildProduct {
435
442
  const inputFingerprint = `sha256:${packageTransportRevision({
436
443
  packageId: input.projected.packageId,
437
444
  sourceRevision: input.sourceRevision,
@@ -623,7 +630,7 @@ export async function prepareDirectPackTransport(
623
630
  projectImportProductForBuild(raw.product),
624
631
  input.policy,
625
632
  );
626
- const facts = projectParameterizedPackPublication(raw);
633
+ const facts = projectScriptablePackPublication(raw);
627
634
  if (!facts.ok) return facts;
628
635
  const displaySourcePath = input.displaySourcePath ?? input.sourcePath;
629
636
  const revision = await scriptablePackResourceRevision(displaySourcePath, raw.inputFingerprint, [
@@ -654,10 +661,10 @@ export async function prepareDirectPackTransport(
654
661
  ]),
655
662
  ),
656
663
  ),
657
- } as AnyParameterizedPackDefinition;
664
+ } as AnyScriptablePackDefinition;
658
665
  const outputs = createStandardAssetOutputProducerRegistry();
659
666
  outputs.register(createPreExternalizedSceneAssetOutputProducer());
660
- const built = await buildParameterizedScriptablePack({
667
+ const built = await buildScriptablePack({
661
668
  definition,
662
669
  sourcePath: input.sourcePath,
663
670
  outputs,
@@ -702,7 +709,7 @@ export async function prepareDirectPackTransport(
702
709
  asset: directAssetForProducer(asset),
703
710
  digest: `sha256:${packageTransportRevision({ kind: asset.kind, payload: asset.payload })}`,
704
711
  }));
705
- const product: ParameterizedScriptablePackBuildProduct = {
712
+ const product: ScriptablePackBuildProduct = {
706
713
  ...built.value,
707
714
  inputFingerprint,
708
715
  stagedOutputs,
@@ -722,7 +729,7 @@ export async function prepareDirectPackTransport(
722
729
  projectImportProductForBuild(product.product),
723
730
  input.policy,
724
731
  );
725
- const facts = projectParameterizedPackPublication(product);
732
+ const facts = projectScriptablePackPublication(product);
726
733
  if (!facts.ok) return facts;
727
734
  const displaySourcePath = input.displaySourcePath ?? input.sourcePath;
728
735
  const revision = await scriptablePackResourceRevision(
@@ -761,8 +768,8 @@ export async function prepareLegacyPackTransport(
761
768
  }
762
769
 
763
770
  /** Materialize a dynamic Pack product through the same dev transport seam. */
764
- export async function materializePreparedParameterizedScriptablePack(
765
- prepared: PreparedParameterizedScriptablePack,
771
+ export async function materializePreparedScriptablePack(
772
+ prepared: PreparedScriptablePack,
766
773
  paths: ScriptablePackTransportPaths,
767
774
  sink: ScriptablePackTransportSink,
768
775
  ): Promise<ReadonlyMap<string, string>> {
@@ -793,8 +800,8 @@ export async function materializePreparedParameterizedScriptablePack(
793
800
  return receipts;
794
801
  }
795
802
 
796
- function projectParameterizedPackPublication(
797
- product: ParameterizedScriptablePackBuildProduct,
803
+ function projectScriptablePackPublication(
804
+ product: ScriptablePackBuildProduct,
798
805
  ): Result<ScriptablePackPublicationFacts, ScriptablePackDomainError> {
799
806
  const assets = new Map(product.product.assets.map((asset) => [asset.guid.toLowerCase(), asset]));
800
807
  const outputs: AssetPublicationOutput[] = [];
@@ -804,7 +811,7 @@ function projectParameterizedPackPublication(
804
811
  if (asset === undefined || staged.digest === undefined || staged.sourceKey === undefined) {
805
812
  return err({
806
813
  code: 'pack-source-output-invalid',
807
- expected: `parameterized Pack publication output ${guid} to include a product, sourceKey, and digest`,
814
+ expected: `ScriptablePack publication output ${guid} to include a product, sourceKey, and digest`,
808
815
  hint: 'repair the dynamic Pack output and rebuild the current generation',
809
816
  detail: { stage: 'publication', guid },
810
817
  });
@@ -857,7 +864,7 @@ function snapshotSourceForStagedOutputs(
857
864
  };
858
865
  }
859
866
 
860
- function composeParameterizedAssetSource(
867
+ function composeScriptablePackAssetSource(
861
868
  staged: import('./scriptable-pack.js').ScriptablePackAssetSnapshotSource | undefined,
862
869
  published: import('./scriptable-pack.js').ScriptablePackAssetSnapshotSource | undefined,
863
870
  ): import('./scriptable-pack.js').ScriptablePackAssetSnapshotSource | undefined {
@@ -873,16 +880,16 @@ function composeParameterizedAssetSource(
873
880
  }
874
881
 
875
882
  /**
876
- * Build parameterized sources in one generation and hand their terminal
883
+ * Build ScriptablePack sources in one generation and hand their terminal
877
884
  * products to the ordinary Pack v2 finalizer. The worklist is deliberately
878
885
  * below publication: it only decides which current-generation products exist.
879
886
  */
880
- export async function produceParameterizedScriptablePackProducts(
881
- options: ParameterizedScriptablePackProductionOptions,
882
- ): Promise<Result<ReadonlyMap<string, PreparedParameterizedScriptablePack>, unknown>> {
887
+ export async function produceScriptablePackProducts(
888
+ options: ScriptablePackProductionOptions,
889
+ ): Promise<Result<ReadonlyMap<string, PreparedScriptablePack>, unknown>> {
883
890
  if (options.sources.length === 0) return ok(new Map());
884
891
  const external = options.declaredExternalOutputs ?? [];
885
- const assetSource = composeParameterizedAssetSource(
892
+ const assetSource = composeScriptablePackAssetSource(
886
893
  snapshotSourceForStagedOutputs(external),
887
894
  options.assetSource,
888
895
  );
@@ -890,7 +897,7 @@ export async function produceParameterizedScriptablePackProducts(
890
897
  ...(options.availableGuids ?? []),
891
898
  ...external.map((output) => AssetGuid.format(output.guid).toLowerCase()),
892
899
  ]);
893
- const workItems: ParameterizedScriptablePackWorkItem[] = options.sources.map((source) => ({
900
+ const workItems: ScriptablePackBuildWorkItem[] = options.sources.map((source) => ({
894
901
  definition: source.definition,
895
902
  sourcePath: source.sourcePath,
896
903
  ...(source.subjectPackageId === undefined ? {} : { subjectPackageId: source.subjectPackageId }),
@@ -898,13 +905,14 @@ export async function produceParameterizedScriptablePackProducts(
898
905
  ...(source.inheritedValues === undefined ? {} : { inheritedValues: source.inheritedValues }),
899
906
  sourceClosure: source.sourceClosure,
900
907
  }));
901
- const worklist = await buildParameterizedScriptablePackWorklist({
908
+ const worklist = await buildScriptablePackWorklist({
902
909
  subjects: workItems,
903
910
  outputs: createStandardAssetOutputProducerRegistry(
904
911
  options.sources.flatMap((source) =>
905
912
  projectScriptablePackSceneComponents(source.definition.sceneComponents),
906
913
  ),
907
914
  ),
915
+ ...(options.cookers === undefined ? {} : { cookers: options.cookers }),
908
916
  ...(assetSource === undefined ? {} : { assetSource }),
909
917
  availableGuids,
910
918
  ...(options.incomingRefs === undefined ? {} : { incomingRefs: options.incomingRefs }),
@@ -917,7 +925,7 @@ export async function produceParameterizedScriptablePackProducts(
917
925
  .filter((product) => product.product.sourceKey !== undefined)
918
926
  .map((product) => [product.product.sourceKey as string, product]),
919
927
  );
920
- const prepared = new Map<string, PreparedParameterizedScriptablePack>();
928
+ const prepared = new Map<string, PreparedScriptablePack>();
921
929
  for (const source of options.sources) {
922
930
  const product = productsBySource.get(source.sourcePath);
923
931
  if (product === undefined) {
@@ -933,7 +941,7 @@ export async function produceParameterizedScriptablePackProducts(
933
941
  projectImportProductForBuild(product.product),
934
942
  policy,
935
943
  );
936
- const facts = projectParameterizedPackPublication(product);
944
+ const facts = projectScriptablePackPublication(product);
937
945
  if (!facts.ok) return facts;
938
946
  const revision = await scriptablePackResourceRevision(
939
947
  source.displaySourcePath,
@@ -136,7 +136,8 @@ export interface ScriptablePackExternalEvidence {
136
136
  readonly digest?: string;
137
137
  }
138
138
 
139
- export interface ScriptablePackBuildProduct {
139
+ /** Shared terminal product envelope for every Pack source form. */
140
+ export interface PackBuildProduct {
140
141
  readonly product: TerminalImportProduct<unknown>;
141
142
  readonly stagedOutputs: readonly ScriptablePackStagedOutput[];
142
143
  readonly externalEvidence: readonly ScriptablePackExternalEvidence[];