@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.
- package/dist/.tsbuildinfo +1 -1
- package/dist/__tests__/source-package-errors.unit.test.d.ts +2 -0
- package/dist/__tests__/source-package-errors.unit.test.d.ts.map +1 -0
- package/dist/browser.mjs +5 -2
- package/dist/browser.mjs.map +1 -1
- package/dist/build-production.d.ts.map +1 -1
- package/dist/catalog-inventory.d.ts +1 -1
- package/dist/catalog-inventory.d.ts.map +1 -1
- package/dist/import-runner.d.ts +9 -0
- package/dist/import-runner.d.ts.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +102 -29
- package/dist/index.mjs.map +1 -1
- package/dist/scriptable-pack-host.d.ts +1 -1
- package/dist/scriptable-pack-host.d.ts.map +1 -1
- package/dist/source-package-errors.d.ts +2 -0
- package/dist/source-package-errors.d.ts.map +1 -1
- package/dist/source-path.d.ts +12 -0
- package/dist/source-path.d.ts.map +1 -0
- package/package.json +7 -7
- package/src/__tests__/import-dependencies.test.ts +34 -0
- package/src/__tests__/source-package-errors.unit.test.ts +62 -0
- package/src/build-production.ts +38 -14
- package/src/catalog-inventory.ts +2 -0
- package/src/import-runner.ts +15 -2
- package/src/index.ts +5 -0
- package/src/scriptable-pack-host.ts +6 -2
- package/src/source-package-errors.ts +37 -0
- package/src/source-path.ts +36 -0
|
@@ -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;
|
|
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.
|
|
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.
|
|
31
|
-
"@forgeax/engine-ecs": "0.1.
|
|
32
|
-
"@forgeax/engine-geometry": "0.1.
|
|
33
|
-
"@forgeax/engine-pack": "0.1.
|
|
34
|
-
"@forgeax/engine-scene": "0.1.
|
|
35
|
-
"@forgeax/engine-types": "0.1.
|
|
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
|
+
});
|
package/src/build-production.ts
CHANGED
|
@@ -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
|
-
|
|
111
|
-
|
|
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
|
|
280
|
-
|
|
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:
|
|
307
|
-
sourceRevision:
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
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
|
|
package/src/catalog-inventory.ts
CHANGED
|
@@ -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
|
}
|
package/src/import-runner.ts
CHANGED
|
@@ -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(
|
|
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(
|
|
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
|
|
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
|
+
}
|