@forgeax/engine-import 0.1.28 → 0.1.30
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 +15 -0
- package/dist/__tests__/scriptable-pack-fingerprint.unit.test.d.ts +2 -0
- package/dist/__tests__/scriptable-pack-fingerprint.unit.test.d.ts.map +1 -0
- package/dist/build-production.d.ts.map +1 -1
- package/dist/index.mjs +1250 -1144
- package/dist/index.mjs.map +1 -1
- package/dist/scriptable-pack-build.d.ts.map +1 -1
- package/dist/scriptable-pack-file-snapshot.d.ts.map +1 -1
- package/dist/scriptable-pack-fingerprint.d.ts +3 -0
- package/dist/scriptable-pack-fingerprint.d.ts.map +1 -0
- package/dist/scriptable-pack-output-producers.d.ts.map +1 -1
- package/dist/scriptable-pack-staged-snapshot.d.ts.map +1 -1
- package/dist/scriptable-pack.d.ts +9 -4
- package/dist/scriptable-pack.d.ts.map +1 -1
- package/package.json +8 -8
- package/src/__tests__/scriptable-pack-build.unit.test.ts +193 -1
- package/src/__tests__/scriptable-pack-fingerprint.unit.test.ts +65 -0
- package/src/__tests__/scriptable-pack-host.unit.test.ts +4 -4
- package/src/__tests__/scriptable-pack-production-producers.unit.test.ts +65 -26
- package/src/build-production.ts +3 -7
- package/src/scriptable-pack-build.ts +129 -35
- package/src/scriptable-pack-file-snapshot.ts +2 -28
- package/src/scriptable-pack-fingerprint.ts +48 -0
- package/src/scriptable-pack-output-producers.ts +24 -2
- package/src/scriptable-pack-staged-snapshot.ts +2 -22
- package/src/scriptable-pack.ts +9 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scriptable-pack-build.d.ts","sourceRoot":"","sources":["../src/scriptable-pack-build.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,YAAY,EAAwB,MAAM,oCAAoC,CAAC;AAC7F,OAAO,EACL,KAAK,2BAA2B,EAIhC,KAAK,kBAAkB,EACvB,SAAS,
|
|
1
|
+
{"version":3,"file":"scriptable-pack-build.d.ts","sourceRoot":"","sources":["../src/scriptable-pack-build.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scriptable-pack-file-snapshot.d.ts","sourceRoot":"","sources":["../src/scriptable-pack-file-snapshot.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"scriptable-pack-file-snapshot.d.ts","sourceRoot":"","sources":["../src/scriptable-pack-file-snapshot.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAEV,iCAAiC,EAClC,MAAM,sBAAsB,CAAC;AAG9B,MAAM,WAAW,4CAA4C;IAC3D,QAAQ,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;CACxC;AAED,MAAM,MAAM,oCAAoC,GAC5C;IACE,QAAQ,CAAC,IAAI,EAAE,sCAAsC,CAAC;IACtD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;CACrE,GACD;IACE,QAAQ,CAAC,IAAI,EAAE,iCAAiC,CAAC;IACjD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;CACrE,GACD;IACE,QAAQ,CAAC,IAAI,EAAE,mCAAmC,CAAC;IACnD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;CACrE,GACD;IACE,QAAQ,CAAC,IAAI,EAAE,8BAA8B,CAAC;IAC9C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE;QACf,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QACtB,QAAQ,CAAC,SAAS,EAAE,SAAS;YAAE,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;YAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;SAAE,EAAE,CAAC;KAC5F,CAAC;CACH,GACD;IACE,QAAQ,CAAC,IAAI,EAAE,qCAAqC,CAAC;IACrD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAAE,CAAC;CACvF,GACD;IACE,QAAQ,CAAC,IAAI,EAAE,oCAAoC,CAAC;IACpD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;CAC5F,GACD;IACE,QAAQ,CAAC,IAAI,EAAE,iBAAiB,CAAC;IACjC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;CAC5C,CAAC;AAkON;;;;GAIG;AACH,wBAAgB,2CAA2C,CACzD,OAAO,EAAE,4CAA4C,GACpD,iCAAiC,CAyBnC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scriptable-pack-fingerprint.d.ts","sourceRoot":"","sources":["../src/scriptable-pack-fingerprint.ts"],"names":[],"mappings":"AAGA,oFAAoF;AACpF,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CA2ChE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scriptable-pack-output-producers.d.ts","sourceRoot":"","sources":["../src/scriptable-pack-output-producers.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,6BAA6B,CAAC;AAmChF,OAAO,EAEL,KAAK,mBAAmB,EACxB,2BAA2B,EAE5B,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"scriptable-pack-output-producers.d.ts","sourceRoot":"","sources":["../src/scriptable-pack-output-producers.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,6BAA6B,CAAC;AAmChF,OAAO,EAEL,KAAK,mBAAmB,EACxB,2BAA2B,EAE5B,MAAM,sBAAsB,CAAC;AA2d9B,eAAO,MAAM,2BAA2B,qBAIvC,CAAC;AAEF,eAAO,MAAM,uBAAuB,qBAA2D,CAAC;AAChG,eAAO,MAAM,0BAA0B,qBAItC,CAAC;AAEF,wBAAgB,8BAA8B,CAC5C,eAAe,GAAE,SAAS,4BAA4B,EAAO,GAC5D,mBAAmB,CAKrB;AAED,wBAAgB,6CAA6C,IAAI,mBAAmB,CAEnF;AAED,wBAAgB,yCAAyC,CACvD,eAAe,GAAE,SAAS,4BAA4B,EAAO,GAC5D,2BAA2B,CA8B7B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scriptable-pack-staged-snapshot.d.ts","sourceRoot":"","sources":["../src/scriptable-pack-staged-snapshot.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AACtE,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"scriptable-pack-staged-snapshot.d.ts","sourceRoot":"","sources":["../src/scriptable-pack-staged-snapshot.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AACtE,OAAO,KAAK,EAAE,SAAS,IAAI,aAAa,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAC7F,OAAO,EAAE,UAAU,EAAW,MAAM,uBAAuB,CAAC;AAC5D,OAAO,KAAK,EAEV,iCAAiC,EACjC,yBAAyB,EACzB,0BAA0B,EAC3B,MAAM,sBAAsB,CAAC;AAG9B,MAAM,MAAM,2BAA2B,GACnC,UAAU,GACV,WAAW,GACX,kBAAkB,GAClB,yBAAyB,CAAC;AAE9B,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,KAAK,EAAE,SAAS,aAAa,EAAE,CAAC;IACzC,KAAK,CACH,MAAM,EAAE,iCAAiC,GACxC,OAAO,CAAC,MAAM,CAAC,SAAS,0BAA0B,EAAE,EAAE,2BAA2B,CAAC,CAAC,CAAC;CACxF;AAED,MAAM,WAAW,mCAAmC;IAClD,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,SAAS,yBAAyB,EAAE,CAAC;IACtD,QAAQ,CAAC,uBAAuB,CAAC,EAAE,SAAS,0BAA0B,EAAE,CAAC;CAC1E;AA0BD;;;GAGG;AACH,wBAAgB,6CAA6C,CAC3D,OAAO,EAAE,mCAAmC,GAC3C,iCAAiC,CA0FnC"}
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import type { ScriptablePackAssetKind } from '@forgeax/engine-pack';
|
|
2
|
-
import type { AssetReader, PackAuthoringError, ScriptablePackReadError } from '@forgeax/engine-pack/source';
|
|
2
|
+
import type { AssetReader, PackAuthoringError, PackCookSource, ScriptablePackReadError } from '@forgeax/engine-pack/source';
|
|
3
3
|
import type { AnimationGraph, Asset, AssetGuid as AssetGuidType, AssetPublicationEnvelope, FontAsset, ImportError, ImportedAsset, MaterialAsset, MeshAsset, Result, TilesetAsset } from '@forgeax/engine-types';
|
|
4
4
|
import type { ImportAssetProduct, TerminalImportProduct } from './import-product.js';
|
|
5
5
|
export type { ScriptablePackSourceClosureEntry } from '@forgeax/engine-pack/source';
|
|
6
6
|
export interface ScriptablePackAssetSnapshot {
|
|
7
|
-
readonly asset: Asset;
|
|
7
|
+
readonly asset: Asset | PackCookSource;
|
|
8
8
|
readonly generation: number;
|
|
9
9
|
readonly digest: string;
|
|
10
10
|
}
|
|
11
11
|
export interface ScriptablePackStagedOutput {
|
|
12
12
|
readonly guid: AssetGuidType;
|
|
13
13
|
readonly sourceKey: string;
|
|
14
|
-
readonly asset: Asset;
|
|
14
|
+
readonly asset: Asset | PackCookSource;
|
|
15
15
|
readonly digest?: string;
|
|
16
16
|
}
|
|
17
17
|
export interface ScriptablePackAssetSnapshotSource {
|
|
@@ -21,6 +21,8 @@ export interface AssetOutputInput {
|
|
|
21
21
|
readonly guid: string;
|
|
22
22
|
readonly sourceKey: string;
|
|
23
23
|
readonly asset: Asset;
|
|
24
|
+
/** Filesystem-backed authoring host; absent for pure payload projections. */
|
|
25
|
+
readonly sourcePath?: string;
|
|
24
26
|
}
|
|
25
27
|
type MaterialPackPayload = Omit<MaterialAsset, 'parent' | 'values'> & {
|
|
26
28
|
readonly parent?: number;
|
|
@@ -89,7 +91,10 @@ export type AssetOutputPayloadByKind = {
|
|
|
89
91
|
}>;
|
|
90
92
|
};
|
|
91
93
|
export type AssetOutputPayload = AssetOutputPayloadByKind[ScriptablePackAssetKind];
|
|
92
|
-
export
|
|
94
|
+
export interface AssetOutputProduct extends ImportAssetProduct<AssetOutputPayload> {
|
|
95
|
+
readonly inputFingerprint?: string;
|
|
96
|
+
readonly sourceDependencies?: readonly string[];
|
|
97
|
+
}
|
|
93
98
|
export interface AssetOutputProducer {
|
|
94
99
|
readonly kind: string;
|
|
95
100
|
readonly version: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scriptable-pack.d.ts","sourceRoot":"","sources":["../src/scriptable-pack.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AACpE,OAAO,KAAK,EACV,WAAW,EACX,kBAAkB,EAClB,uBAAuB,EACxB,MAAM,6BAA6B,CAAC;AACrC,OAAO,KAAK,EACV,cAAc,EACd,KAAK,EACL,SAAS,IAAI,aAAa,EAC1B,wBAAwB,EACxB,SAAS,EACT,WAAW,EACX,aAAa,EACb,aAAa,EACb,SAAS,EACT,MAAM,EACN,YAAY,EACb,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAErF,YAAY,EAAE,gCAAgC,EAAE,MAAM,6BAA6B,CAAC;AAEpF,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"scriptable-pack.d.ts","sourceRoot":"","sources":["../src/scriptable-pack.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@forgeax/engine-import",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.30",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -27,13 +27,13 @@
|
|
|
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-shader": "0.1.
|
|
36
|
-
"@forgeax/engine-types": "0.1.
|
|
30
|
+
"@forgeax/engine-ddc": "0.1.30",
|
|
31
|
+
"@forgeax/engine-ecs": "0.1.30",
|
|
32
|
+
"@forgeax/engine-geometry": "0.1.30",
|
|
33
|
+
"@forgeax/engine-pack": "0.1.30",
|
|
34
|
+
"@forgeax/engine-scene": "0.1.30",
|
|
35
|
+
"@forgeax/engine-shader": "0.1.30",
|
|
36
|
+
"@forgeax/engine-types": "0.1.30",
|
|
37
37
|
"@noble/hashes": "^2.2.0"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
@@ -5,6 +5,7 @@ import type { ScriptablePackAssetSnapshotSource } from '../scriptable-pack.js';
|
|
|
5
5
|
import { AssetOutputProducerRegistry } from '../scriptable-pack.js';
|
|
6
6
|
import { buildScriptablePack, buildScriptablePackWorklist } from '../scriptable-pack-build.js';
|
|
7
7
|
import { produceScriptablePackProducts } from '../scriptable-pack-host.js';
|
|
8
|
+
import { materialAssetOutputProducer } from '../scriptable-pack-output-producers.js';
|
|
8
9
|
|
|
9
10
|
function id(value: string) {
|
|
10
11
|
const result = PackageId.parse(value);
|
|
@@ -13,7 +14,7 @@ function id(value: string) {
|
|
|
13
14
|
}
|
|
14
15
|
|
|
15
16
|
function scene() {
|
|
16
|
-
return { kind: 'scene' as const, entities:
|
|
17
|
+
return { kind: 'scene' as const, entities: {} };
|
|
17
18
|
}
|
|
18
19
|
|
|
19
20
|
function producers() {
|
|
@@ -27,6 +28,135 @@ function producers() {
|
|
|
27
28
|
}
|
|
28
29
|
|
|
29
30
|
describe('ScriptablePack import bridge with optional parameters', () => {
|
|
31
|
+
it('cooks parameterized custom sources alongside ordinary Assets with derived identity and references', async () => {
|
|
32
|
+
const packageId = definePackageId('01900000-0000-7000-8000-000000000049');
|
|
33
|
+
const sceneGuid = AssetGuid.format(AssetGuid.derive(packageId, 'scene/main'));
|
|
34
|
+
const shapeGuid = AssetGuid.format(AssetGuid.derive(packageId, 'shape/custom'));
|
|
35
|
+
const definition = definePack({
|
|
36
|
+
schemaVersion: '2.0.0',
|
|
37
|
+
packageId,
|
|
38
|
+
parameters: [{ name: 'count', type: 'u32', default: 2, minimum: 1 }] as const,
|
|
39
|
+
build: ({ values }) =>
|
|
40
|
+
ok({
|
|
41
|
+
'scene/main': scene(),
|
|
42
|
+
'shape/custom': {
|
|
43
|
+
kind: 'test-volume',
|
|
44
|
+
execution: 'cooked',
|
|
45
|
+
source: { count: values.count, reference: sceneGuid },
|
|
46
|
+
},
|
|
47
|
+
}),
|
|
48
|
+
});
|
|
49
|
+
const inputs: unknown[] = [];
|
|
50
|
+
const cooker = {
|
|
51
|
+
key: 'test-volume',
|
|
52
|
+
cook(raw: unknown) {
|
|
53
|
+
inputs.push(raw);
|
|
54
|
+
const input = raw as { guid: string; source: { count: number; reference: string } };
|
|
55
|
+
return {
|
|
56
|
+
guid: input.guid,
|
|
57
|
+
payload: { kind: 'test-volume', count: input.source.count },
|
|
58
|
+
refs: [input.source.reference],
|
|
59
|
+
artifacts: {
|
|
60
|
+
body: {
|
|
61
|
+
mediaType: 'application/octet-stream',
|
|
62
|
+
bytes: new Uint8Array(input.source.count),
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
inputFingerprint: `test-count:${input.source.count}`,
|
|
66
|
+
};
|
|
67
|
+
},
|
|
68
|
+
};
|
|
69
|
+
const options = {
|
|
70
|
+
definition,
|
|
71
|
+
sourcePath: 'assets/custom.pack.ts',
|
|
72
|
+
outputs: producers(),
|
|
73
|
+
availableGuids: new Set<string>(),
|
|
74
|
+
};
|
|
75
|
+
const missing = await buildScriptablePack(options);
|
|
76
|
+
expect(missing).toMatchObject({ ok: false, error: { code: 'native-cook-failed' } });
|
|
77
|
+
const first = await buildScriptablePack({
|
|
78
|
+
...options,
|
|
79
|
+
cookers: [cooker],
|
|
80
|
+
values: { count: 3 },
|
|
81
|
+
});
|
|
82
|
+
expect(first.ok).toBe(true);
|
|
83
|
+
if (!first.ok) throw first.error;
|
|
84
|
+
expect(inputs).toEqual([
|
|
85
|
+
{
|
|
86
|
+
guid: shapeGuid,
|
|
87
|
+
sourceKey: 'shape/custom',
|
|
88
|
+
sourcePath: 'assets/custom.pack.ts',
|
|
89
|
+
source: { count: 3, reference: sceneGuid },
|
|
90
|
+
refs: [],
|
|
91
|
+
},
|
|
92
|
+
]);
|
|
93
|
+
const output = first.value.product.assets.find((asset) => asset.guid === shapeGuid);
|
|
94
|
+
expect(output).toMatchObject({
|
|
95
|
+
kind: 'test-volume',
|
|
96
|
+
payload: { kind: 'test-volume', count: 3 },
|
|
97
|
+
refs: [{ guid: sceneGuid }],
|
|
98
|
+
artifacts: { body: { bytes: new Uint8Array(3) } },
|
|
99
|
+
});
|
|
100
|
+
expect(first.value.stagedOutputs.map((output) => output.sourceKey)).toEqual([
|
|
101
|
+
'scene/main',
|
|
102
|
+
'shape/custom',
|
|
103
|
+
]);
|
|
104
|
+
const second = await buildScriptablePack({
|
|
105
|
+
...options,
|
|
106
|
+
cookers: [cooker],
|
|
107
|
+
values: { count: 4 },
|
|
108
|
+
});
|
|
109
|
+
expect(second.ok).toBe(true);
|
|
110
|
+
if (!second.ok) throw second.error;
|
|
111
|
+
expect(
|
|
112
|
+
second.value.product.assets.find((asset) => asset.guid === shapeGuid)?.artifacts.body?.bytes,
|
|
113
|
+
).toEqual(new Uint8Array(4));
|
|
114
|
+
expect(second.value.inputFingerprint).not.toBe(first.value.inputFingerprint);
|
|
115
|
+
const wrongIdentity = await buildScriptablePack({
|
|
116
|
+
...options,
|
|
117
|
+
cookers: [
|
|
118
|
+
{
|
|
119
|
+
...cooker,
|
|
120
|
+
cook(raw: unknown) {
|
|
121
|
+
return { ...cooker.cook(raw), guid: sceneGuid };
|
|
122
|
+
},
|
|
123
|
+
},
|
|
124
|
+
],
|
|
125
|
+
});
|
|
126
|
+
expect(wrongIdentity).toMatchObject({
|
|
127
|
+
ok: false,
|
|
128
|
+
error: { code: 'pack-source-output-invalid' },
|
|
129
|
+
});
|
|
130
|
+
const published = await produceScriptablePackProducts({
|
|
131
|
+
sources: [
|
|
132
|
+
{
|
|
133
|
+
definition,
|
|
134
|
+
sourcePath: options.sourcePath,
|
|
135
|
+
displaySourcePath: options.sourcePath,
|
|
136
|
+
sourceClosure: [],
|
|
137
|
+
publicationGeneration: 1,
|
|
138
|
+
values: { count: 3 },
|
|
139
|
+
policy: {
|
|
140
|
+
base: '/',
|
|
141
|
+
packagePath: 'assets/custom.pack.json',
|
|
142
|
+
artifactPath: (guid, key) => `artifacts/${guid}/${key}`,
|
|
143
|
+
},
|
|
144
|
+
},
|
|
145
|
+
],
|
|
146
|
+
cookers: [cooker],
|
|
147
|
+
});
|
|
148
|
+
expect(published.ok).toBe(true);
|
|
149
|
+
if (!published.ok) throw published.error;
|
|
150
|
+
const prepared = published.value.get(options.sourcePath);
|
|
151
|
+
if (prepared === undefined) throw new Error('custom source was not published');
|
|
152
|
+
expect(prepared.facts.outputs).toContainEqual(
|
|
153
|
+
expect.objectContaining({ guid: shapeGuid, sourceKey: 'shape/custom', kind: 'test-volume' }),
|
|
154
|
+
);
|
|
155
|
+
expect(
|
|
156
|
+
prepared.finalized.pack.assets.find((asset) => asset.guid === shapeGuid)?.artifacts?.body,
|
|
157
|
+
).toMatchObject({ byteLength: 3, integrity: { algorithm: 'sha256' } });
|
|
158
|
+
});
|
|
159
|
+
|
|
30
160
|
it('uses the subject packageId and dynamic sourceKey output map', async () => {
|
|
31
161
|
const packageId = definePackageId('01900000-0000-7000-8000-000000000040');
|
|
32
162
|
const definition = definePack({
|
|
@@ -171,6 +301,68 @@ describe('ScriptablePack import bridge with optional parameters', () => {
|
|
|
171
301
|
expect(revision?.observedAt).toBe(0);
|
|
172
302
|
});
|
|
173
303
|
|
|
304
|
+
it('cooks a dynamic material once, re-projects refsIndex values, and keeps cooker-only refs', async () => {
|
|
305
|
+
const packageId = id('01900000-0000-7000-8000-000000000068');
|
|
306
|
+
const textureGuid = '11111111-1111-4111-8111-111111111111';
|
|
307
|
+
const cookerOnlyGuid = '22222222-2222-4222-8222-222222222222';
|
|
308
|
+
const material = {
|
|
309
|
+
kind: 'material' as const,
|
|
310
|
+
passes: [{ name: 'forward', program: { module: 'game::custom' } }] as const,
|
|
311
|
+
parameters: [{ name: 'baseColorTexture', type: 'texture' as const }],
|
|
312
|
+
values: { baseColorTexture: textureGuid },
|
|
313
|
+
};
|
|
314
|
+
const outputs = new AssetOutputProducerRegistry();
|
|
315
|
+
outputs.register(materialAssetOutputProducer);
|
|
316
|
+
let cookCount = 0;
|
|
317
|
+
const result = await buildScriptablePack({
|
|
318
|
+
definition: definePack({
|
|
319
|
+
schemaVersion: '2.0.0',
|
|
320
|
+
packageId,
|
|
321
|
+
build: () => ok({ 'material/main': material }),
|
|
322
|
+
}),
|
|
323
|
+
sourcePath: 'assets/dynamic-material.pack.ts',
|
|
324
|
+
outputs,
|
|
325
|
+
availableGuids: new Set([textureGuid, cookerOnlyGuid]),
|
|
326
|
+
cookers: [
|
|
327
|
+
{
|
|
328
|
+
key: 'material',
|
|
329
|
+
cook(input: {
|
|
330
|
+
readonly guid: string;
|
|
331
|
+
readonly source: typeof material;
|
|
332
|
+
readonly refs: readonly string[];
|
|
333
|
+
}) {
|
|
334
|
+
cookCount += 1;
|
|
335
|
+
expect(input.refs).toContain(textureGuid);
|
|
336
|
+
return {
|
|
337
|
+
guid: input.guid,
|
|
338
|
+
payload: {
|
|
339
|
+
...input.source,
|
|
340
|
+
values: { baseColorTexture: { texture: textureGuid } },
|
|
341
|
+
},
|
|
342
|
+
refs: [cookerOnlyGuid],
|
|
343
|
+
artifacts: {},
|
|
344
|
+
inputFingerprint: 'sha256:dynamic-material',
|
|
345
|
+
};
|
|
346
|
+
},
|
|
347
|
+
},
|
|
348
|
+
],
|
|
349
|
+
});
|
|
350
|
+
expect(result.ok).toBe(true);
|
|
351
|
+
if (!result.ok) return;
|
|
352
|
+
expect(cookCount).toBe(1);
|
|
353
|
+
const [asset] = result.value.product.assets;
|
|
354
|
+
expect(asset?.payload).toMatchObject({ values: { baseColorTexture: { texture: 0 } } });
|
|
355
|
+
expect(asset?.refs).toEqual(
|
|
356
|
+
expect.arrayContaining([
|
|
357
|
+
{
|
|
358
|
+
guid: textureGuid,
|
|
359
|
+
sourceField: { componentName: '<material>', fieldName: 'baseColorTexture' },
|
|
360
|
+
},
|
|
361
|
+
{ guid: cookerOnlyGuid },
|
|
362
|
+
]),
|
|
363
|
+
);
|
|
364
|
+
});
|
|
365
|
+
|
|
174
366
|
it('does not replace a staged read failure with a published value', async () => {
|
|
175
367
|
const packageId = id('01900000-0000-7000-8000-000000000064');
|
|
176
368
|
const dependencyGuid = AssetGuid.derive(packageId, 'scene/dependency');
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { createMeshBuilder } from '@forgeax/engine-geometry';
|
|
2
|
+
import { definePack, definePackageId } from '@forgeax/engine-pack/source';
|
|
3
|
+
import { ok } from '@forgeax/engine-types';
|
|
4
|
+
import { expect, it, vi } from 'vitest';
|
|
5
|
+
import { AssetOutputProducerRegistry } from '../scriptable-pack.js';
|
|
6
|
+
import { buildScriptablePack } from '../scriptable-pack-build.js';
|
|
7
|
+
import { scriptablePackFingerprint } from '../scriptable-pack-fingerprint.js';
|
|
8
|
+
|
|
9
|
+
it('fingerprints mesh buffers without enumerating a JSON property for every float', async () => {
|
|
10
|
+
const mesh = createMeshBuilder({
|
|
11
|
+
attributes: { position: new Float32Array([0, 0, 0, 1, 0, 0, 0, 1, 0]) },
|
|
12
|
+
indices: [0, 1, 2],
|
|
13
|
+
})
|
|
14
|
+
.build()
|
|
15
|
+
.unwrap();
|
|
16
|
+
const outputs = new AssetOutputProducerRegistry();
|
|
17
|
+
outputs.register({
|
|
18
|
+
kind: 'mesh',
|
|
19
|
+
version: 'test',
|
|
20
|
+
produce: () => ok({ payload: mesh, refs: [], artifacts: {} }),
|
|
21
|
+
});
|
|
22
|
+
const definition = definePack({
|
|
23
|
+
schemaVersion: '2.0.0',
|
|
24
|
+
packageId: definePackageId('01900000-0000-7000-8000-000000000089'),
|
|
25
|
+
build: () => ok({ 'mesh/large': mesh }),
|
|
26
|
+
});
|
|
27
|
+
const keys = Object.keys;
|
|
28
|
+
let enumeratedBuffers = 0;
|
|
29
|
+
const spy = vi.spyOn(Object, 'keys').mockImplementation((value) => {
|
|
30
|
+
if (ArrayBuffer.isView(value)) enumeratedBuffers++;
|
|
31
|
+
return keys(value);
|
|
32
|
+
});
|
|
33
|
+
try {
|
|
34
|
+
const result = await buildScriptablePack({ definition, sourcePath: 'large.pack.ts', outputs });
|
|
35
|
+
expect(result.ok).toBe(true);
|
|
36
|
+
expect(enumeratedBuffers).toBe(0);
|
|
37
|
+
} finally {
|
|
38
|
+
spy.mockRestore();
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
it('hashes the selected byte range, type and content with stable object order', () => {
|
|
43
|
+
const values = new Float32Array([99, 1.25, -2, 88]);
|
|
44
|
+
const view = values.subarray(1, 3);
|
|
45
|
+
expect(scriptablePackFingerprint({ z: view, a: 1 })).toBe(
|
|
46
|
+
scriptablePackFingerprint({ a: 1, z: new Float32Array([1.25, -2]) }),
|
|
47
|
+
);
|
|
48
|
+
expect(scriptablePackFingerprint(view)).not.toBe(
|
|
49
|
+
scriptablePackFingerprint(new Uint8Array(view.buffer, view.byteOffset, view.byteLength)),
|
|
50
|
+
);
|
|
51
|
+
const before = scriptablePackFingerprint(view);
|
|
52
|
+
view[1] = 3;
|
|
53
|
+
expect(scriptablePackFingerprint(view)).not.toBe(before);
|
|
54
|
+
expect(scriptablePackFingerprint(new ArrayBuffer(4))).not.toBe(scriptablePackFingerprint({}));
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
// This checks bounded serialization, not throughput under coverage instrumentation.
|
|
58
|
+
it('streams a representative large mesh buffer without a giant JSON string', () => {
|
|
59
|
+
const vertices = new Float32Array(16 * 1024 * 1024);
|
|
60
|
+
vertices[0] = 1.25;
|
|
61
|
+
vertices[vertices.length - 1] = -2;
|
|
62
|
+
const first = scriptablePackFingerprint({ kind: 'mesh', vertices });
|
|
63
|
+
vertices[vertices.length - 1] = -3;
|
|
64
|
+
expect(scriptablePackFingerprint({ kind: 'mesh', vertices })).not.toBe(first);
|
|
65
|
+
}, 60000);
|
|
@@ -105,7 +105,7 @@ describe('ScriptablePack external Meta staging', () => {
|
|
|
105
105
|
'vfx/main': {
|
|
106
106
|
kind: 'particle-effect',
|
|
107
107
|
payload: {
|
|
108
|
-
schemaVersion:
|
|
108
|
+
schemaVersion: 3,
|
|
109
109
|
emitters: [
|
|
110
110
|
{
|
|
111
111
|
id: 'main',
|
|
@@ -128,11 +128,11 @@ describe('ScriptablePack external Meta staging', () => {
|
|
|
128
128
|
guid: source.guid,
|
|
129
129
|
payload: {
|
|
130
130
|
kind: 'particle-effect',
|
|
131
|
-
schemaVersion:
|
|
131
|
+
schemaVersion: 3,
|
|
132
132
|
programFingerprint: 'sha256:cooked',
|
|
133
133
|
emitters: [],
|
|
134
134
|
program: {
|
|
135
|
-
format: 'forgeax-vfx-program-
|
|
135
|
+
format: 'forgeax-vfx-program-3',
|
|
136
136
|
fingerprint: 'sha256:cooked',
|
|
137
137
|
emitters: [],
|
|
138
138
|
},
|
|
@@ -169,7 +169,7 @@ describe('ScriptablePack external Meta staging', () => {
|
|
|
169
169
|
asset: {
|
|
170
170
|
kind: 'particle-effect',
|
|
171
171
|
programFingerprint: 'sha256:cooked',
|
|
172
|
-
program: { format: 'forgeax-vfx-program-
|
|
172
|
+
program: { format: 'forgeax-vfx-program-3' },
|
|
173
173
|
},
|
|
174
174
|
});
|
|
175
175
|
});
|
|
@@ -57,7 +57,7 @@ function canonicalAttributes(vertexCount: number): MeshAsset['attributes'] {
|
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
const particleProgram = {
|
|
60
|
-
format: 'forgeax-vfx-program-
|
|
60
|
+
format: 'forgeax-vfx-program-3',
|
|
61
61
|
fingerprint: 'sha256:scriptable-pack-matrix',
|
|
62
62
|
emitters: [
|
|
63
63
|
{
|
|
@@ -86,7 +86,7 @@ const matrixAssets = [
|
|
|
86
86
|
materialSlots: [],
|
|
87
87
|
} satisfies MeshAsset,
|
|
88
88
|
{ kind: 'material', values: { roughness: 0.5 } } satisfies MaterialAsset,
|
|
89
|
-
{ kind: 'scene', entities:
|
|
89
|
+
{ kind: 'scene', entities: {} } satisfies SceneAsset,
|
|
90
90
|
{
|
|
91
91
|
kind: 'texture',
|
|
92
92
|
shape: { viewDimension: '2d', extent: { width: 1, height: 1 } },
|
|
@@ -158,7 +158,7 @@ const matrixAssets = [
|
|
|
158
158
|
} satisfies AudioClipAsset,
|
|
159
159
|
{
|
|
160
160
|
kind: 'particle-effect',
|
|
161
|
-
schemaVersion:
|
|
161
|
+
schemaVersion: 3,
|
|
162
162
|
programFingerprint: particleProgram.fingerprint,
|
|
163
163
|
emitters: [{ id: 'default', capacity: 16 }],
|
|
164
164
|
program: particleProgram,
|
|
@@ -166,6 +166,49 @@ const matrixAssets = [
|
|
|
166
166
|
] as const satisfies readonly Asset[];
|
|
167
167
|
|
|
168
168
|
describe('standard ScriptablePack output producers', () => {
|
|
169
|
+
it('publishes the deduplicated renderer dependency closure of a particle effect', async () => {
|
|
170
|
+
const material = AssetGuid.format(MATERIAL_GUID);
|
|
171
|
+
const mesh = AssetGuid.format(MESH_GUID);
|
|
172
|
+
const asset: ParticleEffectAsset = {
|
|
173
|
+
kind: 'particle-effect',
|
|
174
|
+
schemaVersion: 3,
|
|
175
|
+
programFingerprint: particleProgram.fingerprint,
|
|
176
|
+
emitters: [{ id: 'default', capacity: 16 }],
|
|
177
|
+
program: {
|
|
178
|
+
...particleProgram,
|
|
179
|
+
emitters: [
|
|
180
|
+
{
|
|
181
|
+
...particleProgram.emitters[0],
|
|
182
|
+
renderers: [
|
|
183
|
+
{ kind: 'billboard', material },
|
|
184
|
+
{ kind: 'mesh', material, mesh },
|
|
185
|
+
],
|
|
186
|
+
},
|
|
187
|
+
],
|
|
188
|
+
},
|
|
189
|
+
};
|
|
190
|
+
const producer = createStandardAssetOutputProducerRegistry().get('particle-effect');
|
|
191
|
+
if (producer === undefined) throw new Error('Missing particle producer');
|
|
192
|
+
const result = await producer.produce({
|
|
193
|
+
guid: AssetGuid.format(OUTPUT_GUID),
|
|
194
|
+
sourceKey: 'vfx/closure',
|
|
195
|
+
asset,
|
|
196
|
+
});
|
|
197
|
+
if (!result.ok) throw result.error;
|
|
198
|
+
expect(result.value.refs.map((ref) => ref.guid)).toEqual([material, mesh].sort());
|
|
199
|
+
expect(result.value.payload).toMatchObject({
|
|
200
|
+
program: {
|
|
201
|
+
emitters: [
|
|
202
|
+
{
|
|
203
|
+
renderers: [
|
|
204
|
+
{ kind: 'billboard', material },
|
|
205
|
+
{ kind: 'mesh', material, mesh },
|
|
206
|
+
],
|
|
207
|
+
},
|
|
208
|
+
],
|
|
209
|
+
},
|
|
210
|
+
});
|
|
211
|
+
});
|
|
169
212
|
it('registers the production producer versions for all ordinary Asset kinds', () => {
|
|
170
213
|
const registry = createStandardAssetOutputProducerRegistry();
|
|
171
214
|
expect(registry.versions()).toEqual({
|
|
@@ -177,7 +220,7 @@ describe('standard ScriptablePack output producers', () => {
|
|
|
177
220
|
'ies-profile': 'ordinary-pod/1',
|
|
178
221
|
material: 'material-pack/2',
|
|
179
222
|
mesh: 'mesh-binary/4',
|
|
180
|
-
'particle-effect': '
|
|
223
|
+
'particle-effect': 'particle-effect/2',
|
|
181
224
|
'render-pipeline': 'ordinary-pod/1',
|
|
182
225
|
sampler: 'ordinary-pod/1',
|
|
183
226
|
scene: 'scene-pack/3',
|
|
@@ -270,9 +313,8 @@ describe('standard ScriptablePack output producers', () => {
|
|
|
270
313
|
|
|
271
314
|
const scene: SceneAsset = {
|
|
272
315
|
kind: 'scene',
|
|
273
|
-
entities:
|
|
274
|
-
{
|
|
275
|
-
localId: 0 as never,
|
|
316
|
+
entities: {
|
|
317
|
+
hero: {
|
|
276
318
|
components: {
|
|
277
319
|
ScriptablePackTestMeshFilter: { assetHandle: AssetGuid.format(MESH_GUID) },
|
|
278
320
|
ScriptablePackTestMeshRenderer: {
|
|
@@ -280,7 +322,7 @@ describe('standard ScriptablePack output producers', () => {
|
|
|
280
322
|
},
|
|
281
323
|
},
|
|
282
324
|
},
|
|
283
|
-
|
|
325
|
+
},
|
|
284
326
|
};
|
|
285
327
|
const result = await producer.produce({
|
|
286
328
|
guid: '019ffa97-3000-7000-8000-000000000003',
|
|
@@ -291,15 +333,14 @@ describe('standard ScriptablePack output producers', () => {
|
|
|
291
333
|
expect(result.ok).toBe(true);
|
|
292
334
|
if (!result.ok) return;
|
|
293
335
|
expect(result.value.payload).toMatchObject({
|
|
294
|
-
entities:
|
|
295
|
-
{
|
|
296
|
-
localId: 0,
|
|
336
|
+
entities: {
|
|
337
|
+
hero: {
|
|
297
338
|
components: {
|
|
298
339
|
ScriptablePackTestMeshFilter: { assetHandle: 0 },
|
|
299
340
|
ScriptablePackTestMeshRenderer: { materials: [1] },
|
|
300
341
|
},
|
|
301
342
|
},
|
|
302
|
-
|
|
343
|
+
},
|
|
303
344
|
});
|
|
304
345
|
expect(result.value.refs).toEqual([
|
|
305
346
|
{
|
|
@@ -308,7 +349,7 @@ describe('standard ScriptablePack output producers', () => {
|
|
|
308
349
|
componentName: 'ScriptablePackTestMeshFilter',
|
|
309
350
|
fieldName: 'assetHandle',
|
|
310
351
|
},
|
|
311
|
-
|
|
352
|
+
sceneEntityKey: 'hero',
|
|
312
353
|
},
|
|
313
354
|
{
|
|
314
355
|
guid: AssetGuid.format(MATERIAL_GUID),
|
|
@@ -317,7 +358,7 @@ describe('standard ScriptablePack output producers', () => {
|
|
|
317
358
|
fieldName: 'materials',
|
|
318
359
|
arrayIndex: 0,
|
|
319
360
|
},
|
|
320
|
-
|
|
361
|
+
sceneEntityKey: 'hero',
|
|
321
362
|
},
|
|
322
363
|
]);
|
|
323
364
|
});
|
|
@@ -333,7 +374,7 @@ describe('standard ScriptablePack output producers', () => {
|
|
|
333
374
|
sourceKey: 'scene/unknown-component',
|
|
334
375
|
asset: {
|
|
335
376
|
kind: 'scene',
|
|
336
|
-
entities:
|
|
377
|
+
entities: { mystery: { components: { Mystery: { asset: 'not-a-ref' } } } },
|
|
337
378
|
},
|
|
338
379
|
});
|
|
339
380
|
|
|
@@ -361,16 +402,14 @@ describe('standard ScriptablePack output producers', () => {
|
|
|
361
402
|
sourceKey: 'scene/environment',
|
|
362
403
|
asset: {
|
|
363
404
|
kind: 'scene',
|
|
364
|
-
entities:
|
|
365
|
-
{
|
|
366
|
-
localId: 0 as never,
|
|
405
|
+
entities: {
|
|
406
|
+
skylight: {
|
|
367
407
|
components: { Skylight: { equirect: AssetGuid.format(EQUIRECT_GUID) } },
|
|
368
408
|
},
|
|
369
|
-
{
|
|
370
|
-
localId: 1 as never,
|
|
409
|
+
skybox: {
|
|
371
410
|
components: { SkyboxBackground: { equirect: AssetGuid.format(EQUIRECT_GUID) } },
|
|
372
411
|
},
|
|
373
|
-
|
|
412
|
+
},
|
|
374
413
|
},
|
|
375
414
|
});
|
|
376
415
|
|
|
@@ -379,10 +418,10 @@ describe('standard ScriptablePack output producers', () => {
|
|
|
379
418
|
expect(result.value.refs).toHaveLength(1);
|
|
380
419
|
expect(result.value.refs[0]?.guid).toBe(AssetGuid.format(EQUIRECT_GUID));
|
|
381
420
|
expect(result.value.payload).toMatchObject({
|
|
382
|
-
entities:
|
|
383
|
-
{ components: { Skylight: { equirect: 0 } } },
|
|
384
|
-
{ components: { SkyboxBackground: { equirect: 0 } } },
|
|
385
|
-
|
|
421
|
+
entities: {
|
|
422
|
+
skylight: { components: { Skylight: { equirect: 0 } } },
|
|
423
|
+
skybox: { components: { SkyboxBackground: { equirect: 0 } } },
|
|
424
|
+
},
|
|
386
425
|
});
|
|
387
426
|
});
|
|
388
427
|
|
|
@@ -471,7 +510,7 @@ describe('standard ScriptablePack output producers', () => {
|
|
|
471
510
|
{
|
|
472
511
|
guid: AssetGuid.format(guid('019ffa97-3000-7000-8000-000000000003')),
|
|
473
512
|
sourceKey: 'scene/generated',
|
|
474
|
-
asset: { kind: 'scene' as const, entities:
|
|
513
|
+
asset: { kind: 'scene' as const, entities: {} },
|
|
475
514
|
producer: scene,
|
|
476
515
|
},
|
|
477
516
|
];
|