@forgeax/engine-pack 0.1.32 → 0.1.33
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/build.mjs +15 -5
- package/dist/build.mjs.map +1 -1
- package/dist/pack-authoring-node.d.ts.map +1 -1
- package/dist/pack-authoring-node.mjs +15 -5
- package/dist/pack-authoring-node.mjs.map +1 -1
- package/package.json +2 -2
- package/src/__tests__/pack-authoring-gateway.unit.test.ts +71 -1
- package/src/pack-authoring-node.ts +20 -4
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@forgeax/engine-pack",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.33",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -128,7 +128,7 @@
|
|
|
128
128
|
}
|
|
129
129
|
},
|
|
130
130
|
"dependencies": {
|
|
131
|
-
"@forgeax/engine-types": "0.1.
|
|
131
|
+
"@forgeax/engine-types": "0.1.33",
|
|
132
132
|
"@noble/hashes": "^2.2.0",
|
|
133
133
|
"fast-glob": "^3.3.3",
|
|
134
134
|
"typescript": "^5.8.3",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { mkdtemp, readFile, rm } from 'node:fs/promises';
|
|
1
|
+
import { mkdtemp, readFile, rm, writeFile } from 'node:fs/promises';
|
|
2
2
|
import { tmpdir } from 'node:os';
|
|
3
3
|
import { join } from 'node:path';
|
|
4
4
|
import { afterEach, describe, expect, it } from 'vitest';
|
|
@@ -296,3 +296,73 @@ describe('Pack authoring gateway', () => {
|
|
|
296
296
|
expect(verified).toMatchObject({ ok: true, value: { summary: { assetCount: 1 } } });
|
|
297
297
|
});
|
|
298
298
|
});
|
|
299
|
+
|
|
300
|
+
it('inspects the exact source revision used by rebuild conflict checks', async () => {
|
|
301
|
+
const root = await mkdtemp(join(tmpdir(), 'forgeax-inspect-revision-'));
|
|
302
|
+
roots.push(root);
|
|
303
|
+
const outputs = [
|
|
304
|
+
{
|
|
305
|
+
packageId: SOURCE_PACKAGE,
|
|
306
|
+
sourceKey: 'mesh/main',
|
|
307
|
+
guid: AssetGuid.format(AssetGuid.derive(packageId(SOURCE_PACKAGE), 'mesh/main')),
|
|
308
|
+
kind: 'mesh',
|
|
309
|
+
sourcePath: 'assets/source.pack.ts',
|
|
310
|
+
ready: true,
|
|
311
|
+
},
|
|
312
|
+
];
|
|
313
|
+
let published = false;
|
|
314
|
+
const gateway = createFileSystemPackAuthoringGateway({
|
|
315
|
+
gameRoot: root,
|
|
316
|
+
materialized: () => (published ? outputs : []),
|
|
317
|
+
rebuild: async () => ({ ok: true, value: undefined }),
|
|
318
|
+
});
|
|
319
|
+
const created = await gateway.execute({
|
|
320
|
+
operation: 'asset-source.create',
|
|
321
|
+
requestId: 'create',
|
|
322
|
+
targetPath: 'assets/source.pack.ts',
|
|
323
|
+
format: 'pack.ts',
|
|
324
|
+
packageId: SOURCE_PACKAGE,
|
|
325
|
+
});
|
|
326
|
+
expect(created.ok).toBe(true);
|
|
327
|
+
if (!created.ok) return;
|
|
328
|
+
published = true;
|
|
329
|
+
const inspected = await gateway.execute({
|
|
330
|
+
operation: 'asset.inspect',
|
|
331
|
+
subject: 'assets/source.pack.ts',
|
|
332
|
+
requestId: 'inspect',
|
|
333
|
+
});
|
|
334
|
+
expect(inspected).toMatchObject({
|
|
335
|
+
ok: true,
|
|
336
|
+
value: {
|
|
337
|
+
revision: created.value.revision,
|
|
338
|
+
sourcePath: 'assets/source.pack.ts',
|
|
339
|
+
assets: outputs,
|
|
340
|
+
},
|
|
341
|
+
});
|
|
342
|
+
const rebuilt = await gateway.execute({
|
|
343
|
+
operation: 'asset-source.rebuild',
|
|
344
|
+
sourcePath: 'assets/source.pack.ts',
|
|
345
|
+
expectedRevision: created.value.revision,
|
|
346
|
+
requestId: 'rebuild',
|
|
347
|
+
});
|
|
348
|
+
expect(rebuilt).toMatchObject({
|
|
349
|
+
ok: true,
|
|
350
|
+
value: { assets: outputs, revision: created.value.revision },
|
|
351
|
+
});
|
|
352
|
+
const path = join(root, 'assets/source.pack.ts');
|
|
353
|
+
await writeFile(path, `${await readFile(path, 'utf8')}\n// source edit\n`);
|
|
354
|
+
const changed = await gateway.execute({
|
|
355
|
+
operation: 'asset.inspect',
|
|
356
|
+
subject: 'assets/source.pack.ts',
|
|
357
|
+
requestId: 'inspect-edited',
|
|
358
|
+
});
|
|
359
|
+
expect(changed.ok).toBe(true);
|
|
360
|
+
if (changed.ok) expect(changed.value.revision).not.toBe(created.value.revision);
|
|
361
|
+
const stale = await gateway.execute({
|
|
362
|
+
operation: 'asset-source.rebuild',
|
|
363
|
+
sourcePath: 'assets/source.pack.ts',
|
|
364
|
+
expectedRevision: created.value.revision,
|
|
365
|
+
requestId: 'stale',
|
|
366
|
+
});
|
|
367
|
+
expect(stale).toMatchObject({ ok: false, error: { code: 'pack-source-revision-conflict' } });
|
|
368
|
+
});
|
|
@@ -817,6 +817,19 @@ async function inspectAsset(
|
|
|
817
817
|
const selected = subjectFor(gameRoot, snapshot, operation);
|
|
818
818
|
if (!selected.ok) return selected;
|
|
819
819
|
const subject = selected.value;
|
|
820
|
+
const source = await readConfined({ gameRoot }, operation, subject.relativePath);
|
|
821
|
+
if (!source.ok) return source;
|
|
822
|
+
const inspectedSource = {
|
|
823
|
+
...sourceResult(subject, operation),
|
|
824
|
+
revision: source.value.revision,
|
|
825
|
+
...(subject.format === 'source'
|
|
826
|
+
? {
|
|
827
|
+
assets: snapshot.materialized
|
|
828
|
+
.filter((asset) => asset.packageId === packageKey(subject.packageId))
|
|
829
|
+
.map((asset) => ({ ...asset })),
|
|
830
|
+
}
|
|
831
|
+
: {}),
|
|
832
|
+
};
|
|
820
833
|
if (operation.sourceKey !== undefined) {
|
|
821
834
|
if (!isValidPackSourceKey(operation.sourceKey)) {
|
|
822
835
|
return err(
|
|
@@ -851,7 +864,7 @@ async function inspectAsset(
|
|
|
851
864
|
candidate.sourceKey === operation.sourceKey,
|
|
852
865
|
);
|
|
853
866
|
return ok({
|
|
854
|
-
...
|
|
867
|
+
...inspectedSource,
|
|
855
868
|
sourceKey: asset.sourceKey,
|
|
856
869
|
guid: asset.guid,
|
|
857
870
|
kind: asset.kind,
|
|
@@ -871,7 +884,7 @@ async function inspectAsset(
|
|
|
871
884
|
candidate.sourceKey === operation.sourceKey,
|
|
872
885
|
);
|
|
873
886
|
return ok({
|
|
874
|
-
...
|
|
887
|
+
...inspectedSource,
|
|
875
888
|
sourceKey: operation.sourceKey,
|
|
876
889
|
guid,
|
|
877
890
|
...(materialized === undefined
|
|
@@ -897,7 +910,7 @@ async function inspectAsset(
|
|
|
897
910
|
const resolved = await resolveInstance(snapshot, subject);
|
|
898
911
|
if (!resolved.ok) return resolved;
|
|
899
912
|
return ok({
|
|
900
|
-
...
|
|
913
|
+
...inspectedSource,
|
|
901
914
|
parameters: resolved.value.parameters.map((parameter) => ({
|
|
902
915
|
name: parameter.name,
|
|
903
916
|
type: parameter.type,
|
|
@@ -911,7 +924,7 @@ async function inspectAsset(
|
|
|
911
924
|
parentChain: resolved.value.parentChain,
|
|
912
925
|
});
|
|
913
926
|
}
|
|
914
|
-
return ok(
|
|
927
|
+
return ok(inspectedSource);
|
|
915
928
|
}
|
|
916
929
|
|
|
917
930
|
function listAssets(
|
|
@@ -2188,6 +2201,9 @@ async function executeRaw(
|
|
|
2188
2201
|
selected.value.packageId,
|
|
2189
2202
|
{
|
|
2190
2203
|
format: refreshed.value.relative.endsWith('.pack.json') ? 'pack.json' : 'pack.ts',
|
|
2204
|
+
assets: refreshedSnapshot.value.materialized
|
|
2205
|
+
.filter((asset) => asset.packageId === packageKey(selected.value.packageId))
|
|
2206
|
+
.map((asset) => ({ ...asset })),
|
|
2191
2207
|
},
|
|
2192
2208
|
);
|
|
2193
2209
|
}
|