@forgeax/engine-import 0.1.7 → 0.1.19

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.
@@ -57,7 +57,7 @@ export interface ScriptablePackExternalImportOptions {
57
57
  readonly assetPaths?: Readonly<Record<string, string>>;
58
58
  }
59
59
  export declare function canonicalScriptableSourcePath(sourcePath: string): string;
60
- export declare function scriptablePackInputs(sourcePaths: readonly string[], declarations: ReadonlyMap<string, ScanSourceDeclaration>, cwd: string, generationFor: (displaySourcePath: string) => number, policyFor: (displaySourcePath: string) => ScriptablePackTransportPolicy): ScriptablePackInput[];
60
+ export declare function scriptablePackInputs(sourcePaths: readonly string[], declarations: ReadonlyMap<string, ScanSourceDeclaration>, cwd: string, generationFor: (displaySourcePath: string) => number, policyFor: (displaySourcePath: string) => ScriptablePackTransportPolicy, sourceIdentityFor?: (sourcePath: string) => string): ScriptablePackInput[];
61
61
  /** Materialize one accepted ScriptablePack without duplicating dev/build loops. */
62
62
  export declare function materializePreparedScriptablePack(prepared: PreparedScriptablePack, paths: ScriptablePackTransportPaths, sink: ScriptablePackTransportSink): Promise<ReadonlyMap<string, string>>;
63
63
  export declare function readCookedAuthoredPack(authoredPack: AuthoredPackInput, cookers?: readonly NativeCooker[], sourcePath?: string): Promise<CookedAuthoredPack | undefined>;
@@ -1 +1 @@
1
- {"version":3,"file":"scriptable-pack-host.d.ts","sourceRoot":"","sources":["../src/scriptable-pack-host.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"scriptable-pack-host.d.ts","sourceRoot":"","sources":["../src/scriptable-pack-host.ts"],"names":[],"mappings":"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"}
@@ -47,6 +47,8 @@ export interface SourcePackageError {
47
47
  readonly detail: SourcePackageErrorDetail;
48
48
  }
49
49
  export declare function sourcePackageError(code: SourcePackageErrorCode, context: SourcePackageErrorContext, detail: Omit<SourcePackageErrorDetail, keyof SourcePackageErrorContext>): SourcePackageError;
50
+ /** Return whether an error chain contains a source-package/import contract error. */
51
+ export declare function containsSourcePackageError(error: unknown, seen?: Set<unknown>): boolean;
50
52
  export declare function normalizeSourcePackageError(error: unknown, context: SourcePackageErrorContext): SourcePackageError;
51
53
  export {};
52
54
  //# sourceMappingURL=source-package-errors.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"source-package-errors.d.ts","sourceRoot":"","sources":["../src/source-package-errors.ts"],"names":[],"mappings":"AAEA,QAAA,MAAM,2BAA2B;;;;;;;;;;;;;;;;;;;;;;;;;CAyBvB,CAAC;AAEX,MAAM,MAAM,sBAAsB,GAAG,MAAM,OAAO,2BAA2B,CAAC;AAE9E,MAAM,MAAM,uBAAuB,GAC/B,MAAM,GACN,UAAU,GACV,YAAY,GACZ,SAAS,GACT,KAAK,GACL,iBAAiB,CAAC;AAEtB,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,aAAa,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,wBAAyB,SAAQ,yBAAyB;IACzE,QAAQ,CAAC,KAAK,EAAE,uBAAuB,CAAC;IACxC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,QAAQ,CAAC,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACxC,QAAQ,CAAC,mBAAmB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAClD;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,IAAI,EAAE,sBAAsB,CAAC;IACtC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,wBAAwB,CAAC;CAC3C;AAED,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,sBAAsB,EAC5B,OAAO,EAAE,yBAAyB,EAClC,MAAM,EAAE,IAAI,CAAC,wBAAwB,EAAE,MAAM,yBAAyB,CAAC,GACtE,kBAAkB,CAQpB;AA8CD,wBAAgB,2BAA2B,CACzC,KAAK,EAAE,OAAO,EACd,OAAO,EAAE,yBAAyB,GACjC,kBAAkB,CAuBpB"}
1
+ {"version":3,"file":"source-package-errors.d.ts","sourceRoot":"","sources":["../src/source-package-errors.ts"],"names":[],"mappings":"AAEA,QAAA,MAAM,2BAA2B;;;;;;;;;;;;;;;;;;;;;;;;;CAyBvB,CAAC;AAEX,MAAM,MAAM,sBAAsB,GAAG,MAAM,OAAO,2BAA2B,CAAC;AAE9E,MAAM,MAAM,uBAAuB,GAC/B,MAAM,GACN,UAAU,GACV,YAAY,GACZ,SAAS,GACT,KAAK,GACL,iBAAiB,CAAC;AAEtB,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,aAAa,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,wBAAyB,SAAQ,yBAAyB;IACzE,QAAQ,CAAC,KAAK,EAAE,uBAAuB,CAAC;IACxC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,QAAQ,CAAC,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACxC,QAAQ,CAAC,mBAAmB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAClD;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,IAAI,EAAE,sBAAsB,CAAC;IACtC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,wBAAwB,CAAC;CAC3C;AAED,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,sBAAsB,EAC5B,OAAO,EAAE,yBAAyB,EAClC,MAAM,EAAE,IAAI,CAAC,wBAAwB,EAAE,MAAM,yBAAyB,CAAC,GACtE,kBAAkB,CAQpB;AAsED,qFAAqF;AACrF,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,eAAqB,GAAG,OAAO,CAM7F;AAED,wBAAgB,2BAA2B,CACzC,KAAK,EAAE,OAAO,EACd,OAAO,EAAE,yBAAyB,GACjC,kBAAkB,CAyBpB"}
@@ -0,0 +1,12 @@
1
+ import type { ScanSourceDeclaration } from '@forgeax/engine-pack/scanner';
2
+ export interface CatalogSourceDeclaration {
3
+ readonly sourcePath: string;
4
+ readonly declaration: ScanSourceDeclaration;
5
+ }
6
+ /**
7
+ * Resolve a Catalog row's logical source locator back to its physical scanner
8
+ * declaration. Catalog rows are host identities; declaration maps remain
9
+ * physical because production still has to read those files from disk.
10
+ */
11
+ export declare function sourceDeclarationForCatalogPath(sourcePath: string, declarations: ReadonlyMap<string, ScanSourceDeclaration>, sourceIdentityFor?: (sourcePath: string) => string, cwd?: string): CatalogSourceDeclaration | undefined;
12
+ //# sourceMappingURL=source-path.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"source-path.d.ts","sourceRoot":"","sources":["../src/source-path.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AAM1E,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,WAAW,EAAE,qBAAqB,CAAC;CAC7C;AAED;;;;GAIG;AACH,wBAAgB,+BAA+B,CAC7C,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,WAAW,CAAC,MAAM,EAAE,qBAAqB,CAAC,EACxD,iBAAiB,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,MAAM,EAClD,GAAG,SAAgB,GAClB,wBAAwB,GAAG,SAAS,CAYtC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@forgeax/engine-import",
3
- "version": "0.1.7",
3
+ "version": "0.1.19",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
@@ -27,12 +27,12 @@
27
27
  "LICENSE"
28
28
  ],
29
29
  "dependencies": {
30
- "@forgeax/engine-ddc": "0.1.7",
31
- "@forgeax/engine-ecs": "0.1.7",
32
- "@forgeax/engine-geometry": "0.1.7",
33
- "@forgeax/engine-pack": "0.1.7",
34
- "@forgeax/engine-scene": "0.1.7",
35
- "@forgeax/engine-types": "0.1.7",
30
+ "@forgeax/engine-ddc": "0.1.19",
31
+ "@forgeax/engine-ecs": "0.1.19",
32
+ "@forgeax/engine-geometry": "0.1.19",
33
+ "@forgeax/engine-pack": "0.1.19",
34
+ "@forgeax/engine-scene": "0.1.19",
35
+ "@forgeax/engine-types": "0.1.19",
36
36
  "@noble/hashes": "^2.2.0"
37
37
  },
38
38
  "devDependencies": {
@@ -62,4 +62,38 @@ describe('import runner dependency observation', () => {
62
62
  'ui/icons/missing.svg',
63
63
  ]);
64
64
  });
65
+
66
+ it('uses host-provided logical identities for dependency fingerprints', async () => {
67
+ const importer: Importer = {
68
+ key: 'fixture',
69
+ async import(ctx: ImportContext): Promise<ImportResult> {
70
+ await ctx.readSibling('./main.css');
71
+ return {
72
+ ok: true,
73
+ value: {
74
+ assets: [{ guid: GUID, kind: 'mesh', payload: MESH, refs: [], artifacts: {} }],
75
+ sourceDependencies: [],
76
+ },
77
+ };
78
+ },
79
+ };
80
+ const registry = new ImporterRegistry();
81
+ registry.register(importer);
82
+ const result = await runImport(meta(), registry, {
83
+ sourceIdentityFor: (sourcePath) =>
84
+ sourcePath.replace('ui/', '@shared/ui/').replace('\\\\', '/'),
85
+ readSource: async () => ({ ok: true, value: new Uint8Array([1]) }),
86
+ });
87
+
88
+ expect(result.ok).toBe(true);
89
+ if (result.ok && 'product' in result.value) {
90
+ expect(result.value.product.sourceDependencies).toEqual([
91
+ '@shared/ui/main.html',
92
+ '@shared/ui/main.css',
93
+ ]);
94
+ expect(result.value.product.sourceRevision).toBe(
95
+ 'source:@shared/ui/main.css|@shared/ui/main.html',
96
+ );
97
+ }
98
+ });
65
99
  });
@@ -0,0 +1,62 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import {
3
+ containsSourcePackageError,
4
+ normalizeSourcePackageError,
5
+ sourcePackageError,
6
+ } from '../source-package-errors.js';
7
+
8
+ const context = {
9
+ sourceMeta: '/game/assets/fox.glb.meta.json',
10
+ anchorGuid: '018e7a4d-1234-7abc-8def-000000000020',
11
+ affectedGuids: ['018e7a4d-1234-7abc-8def-000000000020'],
12
+ producer: 'source-package/gltf',
13
+ importer: 'gltf',
14
+ };
15
+
16
+ describe('source-package error normalization', () => {
17
+ it('walks nested production wrappers to retain the source-package failure', () => {
18
+ const sourceFailure = sourcePackageError('source-package-ddc-failed', context, {
19
+ stage: 'ddc',
20
+ reason: 'DDC lifecycle commit returned stale',
21
+ });
22
+ const wrapped = {
23
+ code: 'commit-failed',
24
+ expected: 'DDC to commit the staged publication',
25
+ hint: 'retry the active generation',
26
+ detail: { stage: 'commit' },
27
+ cause: {
28
+ code: 'produce-failed',
29
+ expected: 'the production generation to complete',
30
+ hint: 'repair the producer',
31
+ detail: { stage: 'produce' },
32
+ cause: sourceFailure,
33
+ },
34
+ };
35
+
36
+ expect(normalizeSourcePackageError(wrapped, context)).toEqual(sourceFailure);
37
+ expect(containsSourcePackageError(wrapped)).toBe(true);
38
+ });
39
+
40
+ it('does not mistake an unrelated lifecycle wrapper for an ImportError', () => {
41
+ const normalized = normalizeSourcePackageError(
42
+ {
43
+ code: 'commit-failed',
44
+ expected: 'a commit',
45
+ hint: 'retry',
46
+ detail: { stage: 'commit' },
47
+ },
48
+ context,
49
+ );
50
+
51
+ expect(normalized.code).toBe('source-package-conversion-failed');
52
+ expect(normalized.detail.reason).toContain('commit-failed');
53
+ expect(
54
+ containsSourcePackageError({
55
+ code: 'pack-source-load-failed',
56
+ expected: 'a ScriptablePack build',
57
+ hint: 'retry',
58
+ detail: { reason: 'timeout' },
59
+ }),
60
+ ).toBe(false);
61
+ });
62
+ });
@@ -31,6 +31,7 @@ import {
31
31
  produceSourcePackage,
32
32
  sourcePackageAssetsByGuid,
33
33
  } from './source-package.js';
34
+ import { sourceDeclarationForCatalogPath } from './source-path.js';
34
35
 
35
36
  export interface BuildProductionFailure {
36
37
  readonly code: string;
@@ -106,13 +107,9 @@ function runtimePublicationFor(
106
107
  async function buildAuthoredPackages(
107
108
  context: BuildProductionOptions,
108
109
  ): Promise<ReadonlyMap<string, ScriptableBuildPackage>> {
109
- const scriptableSources = [
110
- ...new Set(
111
- context.inventory.entries
112
- .filter((entry) => entry.sourcePath.endsWith('.pack.ts'))
113
- .map((entry) => entry.sourcePath),
114
- ),
115
- ];
110
+ const scriptableSources = [...context.inventory.sourceDeclarations.entries()]
111
+ .filter(([, declaration]) => declaration.format === 'pack.ts')
112
+ .map(([sourcePath]) => sourcePath);
116
113
  if (scriptableSources.length === 0) return new Map();
117
114
  const inputs = scriptablePackInputs(
118
115
  scriptableSources,
@@ -124,6 +121,7 @@ async function buildAuthoredPackages(
124
121
  packagePath: `assets/${product.anchorGuid}.pack.json`,
125
122
  artifactPath: scriptableArtifactPath,
126
123
  }),
124
+ context.fsForImport.sourceIdentityFor,
127
125
  );
128
126
  const preparedResult = await produceScriptablePackProducts(
129
127
  inputs,
@@ -210,6 +208,7 @@ function updateImportedEntries(
210
208
  projection: Record<string, unknown> = {},
211
209
  refsByGuid?: ReadonlyMap<string, readonly string[]>,
212
210
  publication?: AssetPublicationEnvelope,
211
+ sourcePath?: string,
213
212
  ): void {
214
213
  const selected = new Set(guids.map((guid) => guid.toLowerCase()));
215
214
  for (let index = 0; index < entries.length; index += 1) {
@@ -220,6 +219,7 @@ function updateImportedEntries(
220
219
  ...entry,
221
220
  packageUrl,
222
221
  ...projection,
222
+ ...(sourcePath === undefined ? {} : { sourcePath }),
223
223
  ...(publication === undefined ? {} : { publication }),
224
224
  ...(refs === undefined ? {} : { refs }),
225
225
  };
@@ -240,6 +240,7 @@ interface PackEmissionOptions {
240
240
  readonly projection?: Record<string, unknown>;
241
241
  readonly refsByGuid?: ReadonlyMap<string, readonly string[]>;
242
242
  readonly publication?: AssetPublicationEnvelope;
243
+ readonly sourcePath?: string;
243
244
  }
244
245
 
245
246
  async function emitPackDocument(
@@ -267,6 +268,7 @@ async function emitPackDocument(
267
268
  options.projection,
268
269
  options.refsByGuid,
269
270
  options.publication,
271
+ options.sourcePath,
270
272
  );
271
273
  return packageUrl;
272
274
  }
@@ -276,8 +278,14 @@ async function emitAuthoredPack(
276
278
  guidSeen: Set<string>,
277
279
  entry: PackIndexEntry,
278
280
  ): Promise<void> {
279
- const packPath = resolve(work.context.cwd, entry.sourcePath);
280
- const declaration = work.context.inventory.sourceDeclarations.get(packPath);
281
+ const sourceDeclaration = sourceDeclarationForCatalogPath(
282
+ entry.sourcePath,
283
+ work.context.inventory.sourceDeclarations,
284
+ work.context.fsForImport.sourceIdentityFor,
285
+ work.context.cwd,
286
+ );
287
+ const packPath = sourceDeclaration?.sourcePath ?? resolve(work.context.cwd, entry.sourcePath);
288
+ const declaration = sourceDeclaration?.declaration;
281
289
  if (declaration?.format !== 'pack.json') {
282
290
  throw work.context.fail({
283
291
  code: 'catalog-declaration-missing',
@@ -303,8 +311,8 @@ async function emitAuthoredPack(
303
311
  ? undefined
304
312
  : runtimePublicationFor(work.context, {
305
313
  pack: { assets: authoredPack.assets },
306
- sourcePath: packPath,
307
- sourceRevision: prepared.finalized?.sourceRevision ?? entry.sourcePath,
314
+ sourcePath: entry.sourcePath,
315
+ sourceRevision: declaration.sourceRevision,
308
316
  packageUrl:
309
317
  prepared.finalized?.packageUrl ??
310
318
  `${work.context.basePrefix === '/' ? '' : work.context.basePrefix}/assets/${outputGuid}.pack.json`,
@@ -333,6 +341,7 @@ async function emitAuthoredPack(
333
341
  async function emitFinalizedOwner(
334
342
  work: BuildEmissionWork,
335
343
  metaPath: string,
344
+ sourcePath: string,
336
345
  subAssets: readonly { readonly guid: string }[],
337
346
  sourcePackage: Extract<
338
347
  Awaited<ReturnType<typeof produceSourcePackage>>,
@@ -379,7 +388,10 @@ async function emitFinalizedOwner(
379
388
  );
380
389
  const runtimePublication = runtimePublicationFor(work.context, {
381
390
  pack: { assets: ownerPackage.pack.assets },
382
- sourcePath: metaPath,
391
+ // The Catalog entry identifies the imported source, while metaPath is the
392
+ // sidecar declaration that drove the import. Keep publication fences on
393
+ // the Catalog identity in production just as the dev importer does.
394
+ sourcePath,
383
395
  sourceRevision: ownerPackage.sourceRevision,
384
396
  packageUrl: ownerPackage.packageUrl,
385
397
  digest: ownerPackage.digest,
@@ -398,6 +410,7 @@ async function emitFinalizedOwner(
398
410
  ]),
399
411
  ),
400
412
  publication: runtimePublication.publication,
413
+ sourcePath,
401
414
  });
402
415
  }
403
416
 
@@ -433,7 +446,14 @@ async function emitBuildEntry(
433
446
  if (!sourcePackage.ok) throw work.context.fail(sourcePackage.error);
434
447
  const ownerFinalizer = work.context.importerRegistry.get(runMeta.importer)?.finalize;
435
448
  if (ownerFinalizer !== undefined) {
436
- await emitFinalizedOwner(work, metaPath, subAssets, sourcePackage.value, ownerFinalizer);
449
+ await emitFinalizedOwner(
450
+ work,
451
+ metaPath,
452
+ canonicalScriptableSourcePath(entry.sourcePath),
453
+ subAssets,
454
+ sourcePackage.value,
455
+ ownerFinalizer,
456
+ );
437
457
  return;
438
458
  }
439
459
  const finalized = await finalizePackageTransportSource(
@@ -446,9 +466,12 @@ async function emitBuildEntry(
446
466
  },
447
467
  );
448
468
  const productByGuid = sourcePackageAssetsByGuid(sourcePackage.value);
469
+ const canonicalSourcePath = canonicalScriptableSourcePath(entry.sourcePath);
449
470
  const runtimePublication = runtimePublicationFor(work.context, {
450
471
  pack: { assets: finalized.pack.assets },
451
- sourcePath: metaPath,
472
+ // See emitFinalizedOwner: the sidecar path is an import driver, not the
473
+ // stable source identity carried by the Catalog row.
474
+ sourcePath: canonicalSourcePath,
452
475
  sourceRevision: finalized.sourceRevision,
453
476
  packageUrl: finalized.packageUrl,
454
477
  digest: finalized.digest,
@@ -464,6 +487,7 @@ async function emitBuildEntry(
464
487
  [...productByGuid].map(([guid, asset]) => [guid, asset.refs.map((ref) => ref.guid)]),
465
488
  ),
466
489
  publication: runtimePublication.publication,
490
+ sourcePath: canonicalSourcePath,
467
491
  });
468
492
  }
469
493
 
@@ -13,12 +13,14 @@ export async function buildCatalogResult(
13
13
  registeredImporterKeys: ReadonlySet<string> = new Set(),
14
14
  scanOptions: ScanOptions = {},
15
15
  catalogVisibility: CatalogProducerVisibility = () => true,
16
+ sourceIdentityFor?: (sourcePath: string) => string,
16
17
  ): Promise<CatalogBuildResult> {
17
18
  const options: CatalogBuildProjectionOptions = {
18
19
  base,
19
20
  scanOptions,
20
21
  importerPolicy: (importer) => catalogImporterPolicy(importer, registeredImporterKeys),
21
22
  visibility: catalogVisibility,
23
+ ...(sourceIdentityFor === undefined ? {} : { sourceIdentityFor }),
22
24
  };
23
25
  return buildCatalogProjection(roots, options);
24
26
  }
@@ -218,6 +218,15 @@ function declarationFields(
218
218
  * `ImportRunnerFs`.
219
219
  */
220
220
  export interface ImportRunnerFs {
221
+ /**
222
+ * Map a physical read path to the host's stable logical source identity.
223
+ *
224
+ * Hosts may expose the same source through different filesystem coordinates
225
+ * (for example a symlink farm in a browser Vite root). The identity is used
226
+ * only for dependency/revision facts; `readSource` and `readSibling` still
227
+ * receive the physical path supplied by the importer.
228
+ */
229
+ sourceIdentityFor?(sourcePath: string): string;
221
230
  readSource(
222
231
  sourcePath: string,
223
232
  ): Promise<
@@ -259,6 +268,10 @@ function normalizeDependencyPath(path: string): string {
259
268
  return parts.join('/');
260
269
  }
261
270
 
271
+ function dependencyIdentity(fs: ImportRunnerFs, sourcePath: string): string {
272
+ return normalizeDependencyPath(fs.sourceIdentityFor?.(sourcePath) ?? sourcePath);
273
+ }
274
+
262
275
  function errResult(error: ImportErrorType): {
263
276
  readonly ok: false;
264
277
  readonly error: ImportErrorType;
@@ -451,7 +464,7 @@ export async function runImport(
451
464
 
452
465
  const dependencies = new Set<string>();
453
466
  const readSource = async (sourcePath: string) => {
454
- dependencies.add(normalizeDependencyPath(sourcePath));
467
+ dependencies.add(dependencyIdentity(fs, sourcePath));
455
468
  try {
456
469
  return await fs.readSource(sourcePath);
457
470
  } catch (error) {
@@ -471,7 +484,7 @@ export async function runImport(
471
484
  | { readonly ok: false; readonly error: ImportErrorType };
472
485
  try {
473
486
  if (fs.readSibling) {
474
- dependencies.add(normalizeDependencyPath(joinSiblingPath(meta.source, uri)));
487
+ dependencies.add(dependencyIdentity(fs, joinSiblingPath(meta.source, uri)));
475
488
  inner = await fs.readSibling(meta.source, uri);
476
489
  } else {
477
490
  inner = await readSource(joinSiblingPath(meta.source, uri));
package/src/index.ts CHANGED
@@ -153,6 +153,7 @@ export {
153
153
  sourcePackageAssetsByGuid,
154
154
  } from './source-package.js';
155
155
  export {
156
+ containsSourcePackageError,
156
157
  normalizeSourcePackageError,
157
158
  type SourcePackageError,
158
159
  type SourcePackageErrorCode,
@@ -173,3 +174,7 @@ export {
173
174
  type StagedImportPublicationResult,
174
175
  stageImportPublication,
175
176
  } from './source-package-publication.js';
177
+ export {
178
+ type CatalogSourceDeclaration,
179
+ sourceDeclarationForCatalogPath,
180
+ } from './source-path.js';
@@ -1,6 +1,6 @@
1
1
  import { createHash } from 'node:crypto';
2
2
  import { stat } from 'node:fs/promises';
3
- import { resolve } from 'node:path';
3
+ import { isAbsolute, relative, resolve } from 'node:path';
4
4
  import { createAcceptedPublication } from '@forgeax/engine-ddc';
5
5
  import {
6
6
  type AuthoredPackInput,
@@ -120,11 +120,15 @@ export function scriptablePackInputs(
120
120
  cwd: string,
121
121
  generationFor: (displaySourcePath: string) => number,
122
122
  policyFor: (displaySourcePath: string) => ScriptablePackTransportPolicy,
123
+ sourceIdentityFor?: (sourcePath: string) => string,
123
124
  ): ScriptablePackInput[] {
124
125
  return sourcePaths.flatMap((sourcePath) => {
125
126
  const declaration = declarations.get(resolve(cwd, sourcePath));
126
127
  if (declaration?.format !== 'pack.ts') return [];
127
- const displaySourcePath = canonicalScriptableSourcePath(sourcePath);
128
+ const projected = sourceIdentityFor?.(sourcePath);
129
+ const catalogSourcePath =
130
+ projected === undefined || isAbsolute(projected) ? relative(cwd, sourcePath) : projected;
131
+ const displaySourcePath = canonicalScriptableSourcePath(catalogSourcePath);
128
132
  return [
129
133
  {
130
134
  sourcePath: resolve(cwd, sourcePath),
@@ -118,10 +118,45 @@ function importFailureCode(error: ImportError): SourcePackageErrorCode {
118
118
  }
119
119
  }
120
120
 
121
+ const IMPORT_ERROR_CODES = new Set([
122
+ 'importer-not-registered',
123
+ 'source-read-failed',
124
+ 'import-produced-no-assets',
125
+ 'guid-mismatch',
126
+ 'mesh-material-slot-topology-change',
127
+ 'import-internal-error',
128
+ 'source-validation-failed',
129
+ 'unknown-source-key',
130
+ 'duplicate-source-key',
131
+ 'invalid-source-overrides',
132
+ 'invalid-source-override-payload',
133
+ ]);
134
+
135
+ function findNormalizableCause(error: unknown, seen = new Set<unknown>()): unknown {
136
+ if (error === null || typeof error !== 'object' || seen.has(error)) return undefined;
137
+ seen.add(error);
138
+ if (isSourcePackageError(error) || isScriptablePackFailure(error) || isImportError(error)) {
139
+ return error;
140
+ }
141
+ const cause = (error as { readonly cause?: unknown }).cause;
142
+ return cause === undefined ? undefined : findNormalizableCause(cause, seen);
143
+ }
144
+
145
+ /** Return whether an error chain contains a source-package/import contract error. */
146
+ export function containsSourcePackageError(error: unknown, seen = new Set<unknown>()): boolean {
147
+ if (error === null || typeof error !== 'object' || seen.has(error)) return false;
148
+ seen.add(error);
149
+ if (isSourcePackageError(error) || isImportError(error)) return true;
150
+ const cause = (error as { readonly cause?: unknown }).cause;
151
+ return cause !== undefined && containsSourcePackageError(cause, seen);
152
+ }
153
+
121
154
  export function normalizeSourcePackageError(
122
155
  error: unknown,
123
156
  context: SourcePackageErrorContext,
124
157
  ): SourcePackageError {
158
+ const cause = findNormalizableCause(error);
159
+ if (cause !== undefined && cause !== error) return normalizeSourcePackageError(cause, context);
125
160
  if (isSourcePackageError(error)) return error;
126
161
  if (isScriptablePackFailure(error)) {
127
162
  return sourcePackageError('source-package-conversion-failed', context, {
@@ -174,6 +209,8 @@ function isImportError(error: unknown): error is ImportError {
174
209
  error !== null &&
175
210
  typeof error === 'object' &&
176
211
  'code' in error &&
212
+ typeof error.code === 'string' &&
213
+ IMPORT_ERROR_CODES.has(error.code) &&
177
214
  'expected' in error &&
178
215
  'hint' in error &&
179
216
  'detail' in error
@@ -0,0 +1,36 @@
1
+ import { resolve } from 'node:path';
2
+ import { catalogSourcePathFor } from '@forgeax/engine-pack/build';
3
+ import type { ScanSourceDeclaration } from '@forgeax/engine-pack/scanner';
4
+
5
+ function normalizeCatalogPath(path: string): string {
6
+ return path.replaceAll('\\', '/').replace(/^\.\//, '');
7
+ }
8
+
9
+ export interface CatalogSourceDeclaration {
10
+ readonly sourcePath: string;
11
+ readonly declaration: ScanSourceDeclaration;
12
+ }
13
+
14
+ /**
15
+ * Resolve a Catalog row's logical source locator back to its physical scanner
16
+ * declaration. Catalog rows are host identities; declaration maps remain
17
+ * physical because production still has to read those files from disk.
18
+ */
19
+ export function sourceDeclarationForCatalogPath(
20
+ sourcePath: string,
21
+ declarations: ReadonlyMap<string, ScanSourceDeclaration>,
22
+ sourceIdentityFor?: (sourcePath: string) => string,
23
+ cwd = process.cwd(),
24
+ ): CatalogSourceDeclaration | undefined {
25
+ const normalized = normalizeCatalogPath(sourcePath);
26
+ const direct = declarations.get(resolve(cwd, sourcePath));
27
+ if (direct !== undefined) {
28
+ return { sourcePath: resolve(cwd, sourcePath), declaration: direct };
29
+ }
30
+ for (const [physicalPath, declaration] of declarations) {
31
+ if (catalogSourcePathFor(cwd, physicalPath, sourceIdentityFor) === normalized) {
32
+ return { sourcePath: physicalPath, declaration };
33
+ }
34
+ }
35
+ return undefined;
36
+ }