@bitmagic/cli 0.1.52-dev.1 → 0.1.52-dev.10
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 +175 -5
- package/dist/assets/add.d.ts +40 -0
- package/dist/assets/add.js +229 -0
- package/dist/assets/add.js.map +1 -0
- package/dist/assets/entry.d.ts +44 -0
- package/dist/assets/entry.js +71 -0
- package/dist/assets/entry.js.map +1 -0
- package/dist/assets/file-kind.d.ts +61 -0
- package/dist/assets/file-kind.js +195 -0
- package/dist/assets/file-kind.js.map +1 -0
- package/dist/assets/list.d.ts +27 -0
- package/dist/assets/list.js +50 -0
- package/dist/assets/list.js.map +1 -0
- package/dist/assets/remove.d.ts +50 -0
- package/dist/assets/remove.js +91 -0
- package/dist/assets/remove.js.map +1 -0
- package/dist/assets/voxelize-glb.d.ts +37 -0
- package/dist/assets/voxelize-glb.js +65 -0
- package/dist/assets/voxelize-glb.js.map +1 -0
- package/dist/assets/vxl-summary.d.ts +32 -0
- package/dist/assets/vxl-summary.js +118 -0
- package/dist/assets/vxl-summary.js.map +1 -0
- package/dist/bin.js +25 -0
- package/dist/bin.js.map +1 -1
- package/dist/cli.d.ts +4 -0
- package/dist/cli.js +15 -1
- package/dist/cli.js.map +1 -1
- package/dist/commands/assets.d.ts +56 -0
- package/dist/commands/assets.js +328 -0
- package/dist/commands/assets.js.map +1 -0
- package/dist/commands/cover.js +2 -3
- package/dist/commands/cover.js.map +1 -1
- package/dist/commands/forge.d.ts +2 -9
- package/dist/commands/forge.js +2 -13
- package/dist/commands/forge.js.map +1 -1
- package/dist/commands/generate.d.ts +41 -9
- package/dist/commands/generate.js +234 -54
- package/dist/commands/generate.js.map +1 -1
- package/dist/commands/judge.d.ts +2 -7
- package/dist/commands/judge.js +26 -19
- package/dist/commands/judge.js.map +1 -1
- package/dist/commands/levels.d.ts +33 -0
- package/dist/commands/levels.js +241 -0
- package/dist/commands/levels.js.map +1 -0
- package/dist/commands/number-flag.d.ts +7 -0
- package/dist/commands/number-flag.js +38 -0
- package/dist/commands/number-flag.js.map +1 -0
- package/dist/commands/publish.js +13 -0
- package/dist/commands/publish.js.map +1 -1
- package/dist/commands/run-deps.d.ts +27 -0
- package/dist/commands/run-deps.js +43 -0
- package/dist/commands/run-deps.js.map +1 -0
- package/dist/editor/journal.d.ts +48 -1
- package/dist/editor/journal.js +44 -0
- package/dist/editor/journal.js.map +1 -1
- package/dist/editor/previews.d.ts +6 -0
- package/dist/editor/previews.js +16 -0
- package/dist/editor/previews.js.map +1 -1
- package/dist/editor/server.js +228 -53
- package/dist/editor/server.js.map +1 -1
- package/dist/editor/shell-page.js +221 -116
- package/dist/editor/shell-page.js.map +1 -1
- package/dist/editor/voxel-save.d.ts +47 -0
- package/dist/editor/voxel-save.js +49 -0
- package/dist/editor/voxel-save.js.map +1 -0
- package/dist/errors.d.ts +10 -0
- package/dist/errors.js +16 -0
- package/dist/errors.js.map +1 -1
- package/dist/forge/apply-modifications.d.ts +18 -1
- package/dist/forge/apply-modifications.js +15 -32
- package/dist/forge/apply-modifications.js.map +1 -1
- package/dist/forge/browser-host.js +9 -4
- package/dist/forge/browser-host.js.map +1 -1
- package/dist/forge/voxelize-session.d.ts +61 -0
- package/dist/forge/voxelize-session.js +137 -0
- package/dist/forge/voxelize-session.js.map +1 -0
- package/dist/generate/model.d.ts +36 -0
- package/dist/generate/model.js +90 -0
- package/dist/generate/model.js.map +1 -0
- package/dist/generate/prop.d.ts +52 -4
- package/dist/generate/prop.js +169 -102
- package/dist/generate/prop.js.map +1 -1
- package/dist/generate/stream.d.ts +7 -0
- package/dist/generate/stream.js +2 -1
- package/dist/generate/stream.js.map +1 -1
- package/dist/generate/vehicle.js +5 -85
- package/dist/generate/vehicle.js.map +1 -1
- package/dist/http/signed-upload.d.ts +55 -0
- package/dist/http/signed-upload.js +168 -0
- package/dist/http/signed-upload.js.map +1 -0
- package/dist/judge/facts.js +72 -57
- package/dist/judge/facts.js.map +1 -1
- package/dist/levels/registry.d.ts +88 -0
- package/dist/levels/registry.js +309 -0
- package/dist/levels/registry.js.map +1 -0
- package/dist/messages/check.d.ts +30 -0
- package/dist/messages/check.js +119 -0
- package/dist/messages/check.js.map +1 -0
- package/dist/messages/notice.d.ts +58 -0
- package/dist/messages/notice.js +54 -0
- package/dist/messages/notice.js.map +1 -0
- package/dist/messages/refresh.d.ts +19 -0
- package/dist/messages/refresh.js +42 -0
- package/dist/messages/refresh.js.map +1 -0
- package/dist/project/jobs.d.ts +1 -1
- package/dist/project/jobs.js.map +1 -1
- package/dist/publish/client.d.ts +13 -0
- package/dist/publish/client.js +13 -34
- package/dist/publish/client.js.map +1 -1
- package/dist/publish/platform.d.ts +46 -0
- package/dist/publish/platform.js +92 -0
- package/dist/publish/platform.js.map +1 -0
- package/dist/scaffold/project-files.js +109 -21
- package/dist/scaffold/project-files.js.map +1 -1
- package/package.json +4 -4
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { CliError } from '../errors.js';
|
|
2
|
+
import { mintAssetId, validateAssetName } from '../assets/file-kind.js';
|
|
3
|
+
import { assertEngineHonouredId, voxelizeGlbIntoAsset, } from '../assets/voxelize-glb.js';
|
|
4
|
+
import { applyModificationsToWorld } from '../forge/apply-modifications.js';
|
|
5
|
+
import { projectWorldJsonPath } from '../forge/run-pipeline.js';
|
|
6
|
+
import { requestGeneration } from './stream.js';
|
|
7
|
+
import { isJsonObject, readWorldJson } from '../project/world-json.js';
|
|
8
|
+
/**
|
|
9
|
+
* The wire type. `prop` is the api-server generator that turns a prompt into a mesh; see the file
|
|
10
|
+
* header for why this command does not define one of its own.
|
|
11
|
+
*/
|
|
12
|
+
const MESH_GENERATOR_TYPE = 'prop';
|
|
13
|
+
/**
|
|
14
|
+
* A usable asset name from the creator's sentence. Names are what game code places by, so this
|
|
15
|
+
* favours something short and typeable over something faithful: the prompt itself is kept on the
|
|
16
|
+
* asset's `description`, which is where the full wording belongs.
|
|
17
|
+
*/
|
|
18
|
+
export function modelNameFromPrompt(prompt) {
|
|
19
|
+
const words = prompt.toLowerCase().replace(/[^a-z0-9\s-]/g, ' ').split(/\s+/).filter((w) => w !== '');
|
|
20
|
+
const camel = words.slice(0, 4).map((w, i) => (i === 0 ? w : w[0].toUpperCase() + w.slice(1))).join('');
|
|
21
|
+
return camel === '' ? 'model' : camel;
|
|
22
|
+
}
|
|
23
|
+
export async function generateAndInstallModel(options) {
|
|
24
|
+
const { context, environment, token, prompt, log } = options;
|
|
25
|
+
const now = options.now ?? (() => new Date());
|
|
26
|
+
// Everything refusable for free, before a spark is spent.
|
|
27
|
+
const name = validateAssetName(options.name ?? modelNameFromPrompt(prompt));
|
|
28
|
+
const assetId = options.assetId ?? mintAssetId();
|
|
29
|
+
const worldPath = projectWorldJsonPath(context.root);
|
|
30
|
+
const world = readWorldJson(worldPath);
|
|
31
|
+
const assets = Array.isArray(world.assets) ? world.assets : [];
|
|
32
|
+
if (assets.some((item) => isJsonObject(item) && item.name === name && item.id !== assetId)) {
|
|
33
|
+
log(`note: another asset is already named "${name}". Assets looked up by name resolve to the `
|
|
34
|
+
+ 'FIRST match — pass --name to give this one its own.');
|
|
35
|
+
}
|
|
36
|
+
let glbUrl = options.glbUrl;
|
|
37
|
+
if (glbUrl === undefined) {
|
|
38
|
+
const outcome = await requestGeneration(environment, token, MESH_GENERATOR_TYPE, { gameId: context.metadata.gameId, prompt }, { fetch: options.fetchImpl ?? globalThis.fetch, onProgress: log });
|
|
39
|
+
if (!outcome.success)
|
|
40
|
+
throw new CliError(`${outcome.message} world.json is unchanged.`);
|
|
41
|
+
if (!outcome.glbUrl) {
|
|
42
|
+
throw new CliError('The generator reported success but returned no mesh. world.json is unchanged.');
|
|
43
|
+
}
|
|
44
|
+
glbUrl = outcome.glbUrl;
|
|
45
|
+
log(`Mesh generated: ${glbUrl}`);
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
log(`Reusing the mesh at ${glbUrl} — skipping generation.`);
|
|
49
|
+
}
|
|
50
|
+
// From here the mesh is PAID FOR, so every failure names the command that resumes without
|
|
51
|
+
// paying again — the same contract `generate prop` and `generate vehicle` make.
|
|
52
|
+
const retryHint = 'The generated mesh is kept — retry the browser step for free with:\n'
|
|
53
|
+
+ ` bitmagic generate model --glb-url ${glbUrl} --asset-id ${assetId} --name "${name}"`;
|
|
54
|
+
const voxelize = options.voxelize ?? voxelizeGlbIntoAsset;
|
|
55
|
+
const engineAsset = await voxelize({
|
|
56
|
+
context, environment, token, name, glbUrl, assetId, voxel: options.voxel, retryHint,
|
|
57
|
+
requestPrefix: 'model', log,
|
|
58
|
+
});
|
|
59
|
+
assertEngineHonouredId(engineAsset, assetId, name, `the mesh is kept at ${glbUrl}`);
|
|
60
|
+
// The Asset Forger embeds no scene description, so the engine's record comes back with none and
|
|
61
|
+
// its `production.prompt` is empty. Carrying the prompt across is what makes a later HQ
|
|
62
|
+
// regeneration ask for the same object rather than a generic one.
|
|
63
|
+
const asset = {
|
|
64
|
+
...engineAsset,
|
|
65
|
+
description: typeof engineAsset.description === 'string' && engineAsset.description.trim() !== ''
|
|
66
|
+
? engineAsset.description
|
|
67
|
+
: prompt,
|
|
68
|
+
production: {
|
|
69
|
+
method: 'generated',
|
|
70
|
+
at: now().toISOString(),
|
|
71
|
+
prompt,
|
|
72
|
+
sourceUrl: glbUrl,
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
const modification = {
|
|
76
|
+
type: 'upsertRoot',
|
|
77
|
+
path: ['assets'],
|
|
78
|
+
predicate: (item) => isJsonObject(item) && item.id === assetId,
|
|
79
|
+
value: asset,
|
|
80
|
+
};
|
|
81
|
+
applyModificationsToWorld(worldPath, [modification], { subject: 'The generated model' });
|
|
82
|
+
return {
|
|
83
|
+
assetId,
|
|
84
|
+
assetName: name,
|
|
85
|
+
...(typeof asset.url === 'string' ? { assetUrl: asset.url } : {}),
|
|
86
|
+
...(typeof asset.voxelCount === 'number' ? { voxelCount: asset.voxelCount } : {}),
|
|
87
|
+
glbUrl,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=model.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model.js","sourceRoot":"","sources":["../../src/generate/model.ts"],"names":[],"mappings":"AAuBA,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAExC,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AACxE,OAAO,EACL,sBAAsB,EAAE,oBAAoB,GAC7C,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,yBAAyB,EAAE,MAAM,iCAAiC,CAAC;AAC5E,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAEhD,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAEvE;;;GAGG;AACH,MAAM,mBAAmB,GAAG,MAAM,CAAC;AA8BnC;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CAAC,MAAc;IAChD,MAAM,KAAK,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,eAAe,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;IACtG,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAE,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACzG,OAAO,KAAK,KAAK,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC;AACxC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAAC,OAA6B;IACzE,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC;IAC7D,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;IAE9C,0DAA0D;IAC1D,MAAM,IAAI,GAAG,iBAAiB,CAAC,OAAO,CAAC,IAAI,IAAI,mBAAmB,CAAC,MAAM,CAAC,CAAC,CAAC;IAC5E,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,WAAW,EAAE,CAAC;IACjD,MAAM,SAAS,GAAG,oBAAoB,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACrD,MAAM,KAAK,GAAG,aAAa,CAAC,SAAS,CAAC,CAAC;IACvC,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;IAC/D,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,KAAK,IAAI,IAAI,IAAI,CAAC,EAAE,KAAK,OAAO,CAAC,EAAE,CAAC;QAC3F,GAAG,CACD,yCAAyC,IAAI,6CAA6C;cACxF,qDAAqD,CACxD,CAAC;IACJ,CAAC;IAED,IAAI,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAC5B,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,MAAM,OAAO,GAAG,MAAM,iBAAiB,CACrC,WAAW,EACX,KAAK,EACL,mBAAmB,EACnB,EAAE,MAAM,EAAE,OAAO,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,EAC3C,EAAE,KAAK,EAAE,OAAO,CAAC,SAAS,IAAI,UAAU,CAAC,KAAK,EAAE,UAAU,EAAE,GAAG,EAAE,CAClE,CAAC;QACF,IAAI,CAAC,OAAO,CAAC,OAAO;YAAE,MAAM,IAAI,QAAQ,CAAC,GAAG,OAAO,CAAC,OAAO,2BAA2B,CAAC,CAAC;QACxF,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;YACpB,MAAM,IAAI,QAAQ,CAAC,+EAA+E,CAAC,CAAC;QACtG,CAAC;QACD,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;QACxB,GAAG,CAAC,mBAAmB,MAAM,EAAE,CAAC,CAAC;IACnC,CAAC;SAAM,CAAC;QACN,GAAG,CAAC,uBAAuB,MAAM,yBAAyB,CAAC,CAAC;IAC9D,CAAC;IAED,0FAA0F;IAC1F,gFAAgF;IAChF,MAAM,SAAS,GAAG,sEAAsE;UACpF,uCAAuC,MAAM,eAAe,OAAO,YAAY,IAAI,GAAG,CAAC;IAE3F,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,oBAAoB,CAAC;IAC1D,MAAM,WAAW,GAAG,MAAM,QAAQ,CAAC;QACjC,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,SAAS;QACnF,aAAa,EAAE,OAAO,EAAE,GAAG;KAC5B,CAAC,CAAC;IACH,sBAAsB,CAAC,WAAW,EAAE,OAAO,EAAE,IAAI,EAAE,uBAAuB,MAAM,EAAE,CAAC,CAAC;IAEpF,gGAAgG;IAChG,wFAAwF;IACxF,kEAAkE;IAClE,MAAM,KAAK,GAA4B;QACrC,GAAG,WAAW;QACd,WAAW,EAAE,OAAO,WAAW,CAAC,WAAW,KAAK,QAAQ,IAAI,WAAW,CAAC,WAAW,CAAC,IAAI,EAAE,KAAK,EAAE;YAC/F,CAAC,CAAC,WAAW,CAAC,WAAW;YACzB,CAAC,CAAC,MAAM;QACV,UAAU,EAAE;YACV,MAAM,EAAE,WAAW;YACnB,EAAE,EAAE,GAAG,EAAE,CAAC,WAAW,EAAE;YACvB,MAAM;YACN,SAAS,EAAE,MAAM;SAClB;KACF,CAAC;IAEF,MAAM,YAAY,GAA0B;QAC1C,IAAI,EAAE,YAAY;QAClB,IAAI,EAAE,CAAC,QAAQ,CAAC;QAChB,SAAS,EAAE,CAAC,IAAa,EAAE,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,EAAE,KAAK,OAAO;QACvE,KAAK,EAAE,KAAK;KACb,CAAC;IACF,yBAAyB,CAAC,SAAS,EAAE,CAAC,YAAY,CAAC,EAAE,EAAE,OAAO,EAAE,qBAAqB,EAAE,CAAC,CAAC;IAEzF,OAAO;QACL,OAAO;QACP,SAAS,EAAE,IAAI;QACf,GAAG,CAAC,OAAO,KAAK,CAAC,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACjE,GAAG,CAAC,OAAO,KAAK,CAAC,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACjF,MAAM;KACP,CAAC;AACJ,CAAC"}
|
package/dist/generate/prop.d.ts
CHANGED
|
@@ -1,5 +1,32 @@
|
|
|
1
1
|
import type { Environment } from '../config/environments.js';
|
|
2
|
+
import { withVoxelizeSession } from '../forge/voxelize-session.js';
|
|
2
3
|
import type { ProjectContext } from '../project/context.js';
|
|
4
|
+
/**
|
|
5
|
+
* What the bake was handed: a mesh to voxelize, or a voxel master to compile.
|
|
6
|
+
*
|
|
7
|
+
* A union rather than two optional URLs because exactly one is always true, and the error messages
|
|
8
|
+
* differ in the only part that matters — what was kept and how to retry with it.
|
|
9
|
+
*/
|
|
10
|
+
export type PropSource = {
|
|
11
|
+
kind: 'glb';
|
|
12
|
+
glbUrl: string;
|
|
13
|
+
} | {
|
|
14
|
+
kind: 'master';
|
|
15
|
+
masterUrl: string;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Whether this project's engine can bake a voxel master.
|
|
19
|
+
*
|
|
20
|
+
* A capability probe, not a version comparison. `withVoxelizeSession` runs the project's OWN
|
|
21
|
+
* vendored engine, and `CREATE_ASSET_FROM_VXL_MASTER` only exists in engines from 2026-08-02 —
|
|
22
|
+
* but the failure mode of guessing wrong is what makes this worth checking rather than trying:
|
|
23
|
+
* an engine with no handler for a message does not answer, so the request stalls for the full
|
|
24
|
+
* VOXELIZE_TIMEOUT_MS (10 minutes) and then again on the retry, after which the paid generation
|
|
25
|
+
* is thrown away. Reading a version string is the indirect way to ask; the file is the answer.
|
|
26
|
+
*
|
|
27
|
+
* `engine` resolves to `engine/engine` — see scaffold/aliases.ts.
|
|
28
|
+
*/
|
|
29
|
+
export declare function engineSupportsVxlMaster(projectRoot: string): boolean;
|
|
3
30
|
interface FitBox {
|
|
4
31
|
x: number;
|
|
5
32
|
z: number;
|
|
@@ -11,8 +38,14 @@ export interface PropVoxelizeOptions {
|
|
|
11
38
|
token: string;
|
|
12
39
|
assetId: string;
|
|
13
40
|
prompt: string;
|
|
14
|
-
|
|
41
|
+
source: PropSource;
|
|
15
42
|
log: (message: string) => void;
|
|
43
|
+
/**
|
|
44
|
+
* Injected by tests so the bake runs without Chrome, matching the `voxelize` seam
|
|
45
|
+
* `generateAndInstallModel` already has. Without it none of the routing, capability or fallback
|
|
46
|
+
* logic below can be covered at all — every path ends in a real browser.
|
|
47
|
+
*/
|
|
48
|
+
session?: typeof withVoxelizeSession;
|
|
16
49
|
}
|
|
17
50
|
export interface GenerateAndInstallOptions {
|
|
18
51
|
context: ProjectContext;
|
|
@@ -24,7 +57,24 @@ export interface GenerateAndInstallOptions {
|
|
|
24
57
|
glbUrl?: string;
|
|
25
58
|
fetchImpl?: typeof globalThis.fetch;
|
|
26
59
|
log: (message: string) => void;
|
|
60
|
+
/** See PropVoxelizeOptions.session. */
|
|
61
|
+
session?: typeof withVoxelizeSession;
|
|
27
62
|
}
|
|
63
|
+
/**
|
|
64
|
+
* What the asset was made from, reported so callers do not have to guess.
|
|
65
|
+
*
|
|
66
|
+
* Two fields rather than one, because both end up in machine-readable output — the `--json`
|
|
67
|
+
* document and the editor's journal — and a voxel master reported under `glbUrl` would tell an
|
|
68
|
+
* agent there is a mesh to retry with when there is not, on the one path whose whole point is
|
|
69
|
+
* that no mesh exists.
|
|
70
|
+
*/
|
|
71
|
+
export type PropSourceResult = {
|
|
72
|
+
glbUrl: string;
|
|
73
|
+
masterUrl?: undefined;
|
|
74
|
+
} | {
|
|
75
|
+
masterUrl: string;
|
|
76
|
+
glbUrl?: undefined;
|
|
77
|
+
};
|
|
28
78
|
export interface PropVoxelizeResult {
|
|
29
79
|
assetId: string;
|
|
30
80
|
assetName: string;
|
|
@@ -58,9 +108,7 @@ export declare function shouldFillInterior(fitBox: FitBox): boolean;
|
|
|
58
108
|
* Everything the caller must resolve first (project, environment, token) is a parameter, so this
|
|
59
109
|
* stays free of CLI output plumbing and of how the token was obtained.
|
|
60
110
|
*/
|
|
61
|
-
export declare function generateAndInstallProp(options: GenerateAndInstallOptions): Promise<PropVoxelizeResult &
|
|
62
|
-
glbUrl: string;
|
|
63
|
-
}>;
|
|
111
|
+
export declare function generateAndInstallProp(options: GenerateAndInstallOptions): Promise<PropVoxelizeResult & PropSourceResult>;
|
|
64
112
|
/**
|
|
65
113
|
* Steps 2 and 3. Split from the command so the browser work is callable directly on a retry that
|
|
66
114
|
* already has a GLB, and so the command file stays about flags and output.
|
package/dist/generate/prop.js
CHANGED
|
@@ -8,31 +8,37 @@
|
|
|
8
8
|
*
|
|
9
9
|
* Three steps, mirroring `game-play-agent/src/mastra/utils/hq-asset-jobs.ts` — the proven chain:
|
|
10
10
|
*
|
|
11
|
-
* 1. Ask api-server for
|
|
12
|
-
* live there and never reach this machine, which is the whole reason the editor
|
|
13
|
-
* the agent rather than doing it inline.
|
|
14
|
-
* 2.
|
|
15
|
-
*
|
|
16
|
-
* `
|
|
11
|
+
* 1. Ask api-server for the source (`POST /api/cli/v1/assets/<type>/stream`). Asset Forger
|
|
12
|
+
* credentials live there and never reach this machine, which is the whole reason the editor
|
|
13
|
+
* hands this to the agent rather than doing it inline.
|
|
14
|
+
* 2. Bake it in a browser, constrained to the asset's recorded `fitBox`. Only the engine can do
|
|
15
|
+
* this, so the CLI drives its own headless Chrome — `forge/voxelize-session.ts`, shared with
|
|
16
|
+
* `generate vehicle` and `assets add`.
|
|
17
17
|
* 3. Upsert the result into `assets[]` under the SAME id, which is what upgrades every already
|
|
18
18
|
* placed instance instead of adding a second asset beside them.
|
|
19
19
|
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
20
|
+
* Step 1 has two sources, and which one is used depends on the environment:
|
|
21
|
+
*
|
|
22
|
+
* - `prop` returns a GLB. The engine then voxelizes it and throws the mesh away — which is all
|
|
23
|
+
* a 50-100 MB textured model was ever for here.
|
|
24
|
+
* - `prop-voxel` returns an HFVX voxel master directly from TRELLIS.2's own voxel field, no mesh
|
|
25
|
+
* at any point. Measured on staging: 219 KB and ~8.5s warm, against minutes and megabytes.
|
|
26
|
+
*
|
|
27
|
+
* `prop-voxel` is used in the `dev` environment ONLY, and only when the project's vendored engine
|
|
28
|
+
* has the handler for it. Everywhere else this is exactly the command it has always been. The
|
|
29
|
+
* newer path is the better one; it is gated because it is newer, not because it is lesser, and
|
|
30
|
+
* `prod` graduates when there is reason to.
|
|
31
|
+
*
|
|
32
|
+
* The generated source survives a failure in steps 2-3: it is reported in the error so a retry can
|
|
33
|
+
* be pointed at it rather than paying for the generation twice.
|
|
22
34
|
*/
|
|
23
35
|
import * as fs from 'fs';
|
|
24
|
-
import
|
|
36
|
+
import * as path from 'path';
|
|
25
37
|
import { CliError } from '../errors.js';
|
|
26
38
|
import { applyModificationsToWorld } from '../forge/apply-modifications.js';
|
|
27
|
-
import { ForgeBrowserHost, readProjectGameData } from '../forge/browser-host.js';
|
|
28
39
|
import { projectWorldJsonPath } from '../forge/run-pipeline.js';
|
|
29
|
-
import {
|
|
40
|
+
import { VOXELIZE_TIMEOUT_MS, withVoxelizeSession } from '../forge/voxelize-session.js';
|
|
30
41
|
import { requestGeneration } from './stream.js';
|
|
31
|
-
import { reserveCorsAllowedPort } from '../local-port.js';
|
|
32
|
-
import { projectBin } from '../project/context.js';
|
|
33
|
-
import { waitForServer } from '../verify/wait-for-server.js';
|
|
34
|
-
/** Voxelizing a dense mesh is minutes of work in the browser, not seconds. */
|
|
35
|
-
const VOXELIZE_TIMEOUT_MS = 10 * 60 * 1000;
|
|
36
42
|
/**
|
|
37
43
|
* Bake resolution. Taken from the HQ job rather than re-derived: these two values are what the
|
|
38
44
|
* web lane has always produced HQ assets at, and a project should not get a different-looking
|
|
@@ -40,6 +46,28 @@ const VOXELIZE_TIMEOUT_MS = 10 * 60 * 1000;
|
|
|
40
46
|
*/
|
|
41
47
|
const MIN_VOXEL_SIZE = 0.1;
|
|
42
48
|
const MAX_VOXEL_SIZE = 0.5;
|
|
49
|
+
/** The api-server generator types this command can ask for. */
|
|
50
|
+
const MESH_GENERATOR_TYPE = 'prop';
|
|
51
|
+
const VOXEL_GENERATOR_TYPE = 'prop-voxel';
|
|
52
|
+
/**
|
|
53
|
+
* Whether this project's engine can bake a voxel master.
|
|
54
|
+
*
|
|
55
|
+
* A capability probe, not a version comparison. `withVoxelizeSession` runs the project's OWN
|
|
56
|
+
* vendored engine, and `CREATE_ASSET_FROM_VXL_MASTER` only exists in engines from 2026-08-02 —
|
|
57
|
+
* but the failure mode of guessing wrong is what makes this worth checking rather than trying:
|
|
58
|
+
* an engine with no handler for a message does not answer, so the request stalls for the full
|
|
59
|
+
* VOXELIZE_TIMEOUT_MS (10 minutes) and then again on the retry, after which the paid generation
|
|
60
|
+
* is thrown away. Reading a version string is the indirect way to ask; the file is the answer.
|
|
61
|
+
*
|
|
62
|
+
* `engine` resolves to `engine/engine` — see scaffold/aliases.ts.
|
|
63
|
+
*/
|
|
64
|
+
export function engineSupportsVxlMaster(projectRoot) {
|
|
65
|
+
return fs.existsSync(path.join(projectRoot, 'engine', 'engine', 'template', 'VxlMasterAssetHandler.ts'));
|
|
66
|
+
}
|
|
67
|
+
/** A thrown CliError's message, without letting a non-Error stringify to "[object Object]". */
|
|
68
|
+
function messageOf(error) {
|
|
69
|
+
return error instanceof Error ? error.message : String(error);
|
|
70
|
+
}
|
|
43
71
|
function isRecord(value) {
|
|
44
72
|
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
45
73
|
}
|
|
@@ -101,103 +129,152 @@ export function shouldFillInterior(fitBox) {
|
|
|
101
129
|
*/
|
|
102
130
|
export async function generateAndInstallProp(options) {
|
|
103
131
|
const { context, environment, token, assetId, prompt, log } = options;
|
|
132
|
+
const fetchImpl = options.fetchImpl ?? globalThis.fetch;
|
|
104
133
|
// Before anything is spent: a mistyped id or an asset with no fitBox costs nothing.
|
|
105
134
|
findPropAsset(readWorld(projectWorldJsonPath(context.root)), assetId);
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
135
|
+
// A retry with `--glb-url` skips generation entirely and is always the mesh path — the caller
|
|
136
|
+
// has a mesh in hand and asked for it to be used.
|
|
137
|
+
if (options.glbUrl !== undefined) {
|
|
138
|
+
log(`Reusing the mesh at ${options.glbUrl} — skipping generation.`);
|
|
139
|
+
const reused = await voxelizeAndInstall({
|
|
140
|
+
context, environment, token, assetId, prompt,
|
|
141
|
+
source: { kind: 'glb', glbUrl: options.glbUrl },
|
|
142
|
+
log, ...(options.session ? { session: options.session } : {}),
|
|
143
|
+
});
|
|
144
|
+
return { ...reused, glbUrl: options.glbUrl };
|
|
116
145
|
}
|
|
117
|
-
|
|
118
|
-
|
|
146
|
+
if (environment.name === 'dev' && engineSupportsVxlMaster(context.root)) {
|
|
147
|
+
const viaVoxels = await tryVoxelMasterPath({ ...options, fetchImpl });
|
|
148
|
+
if (viaVoxels)
|
|
149
|
+
return viaVoxels;
|
|
150
|
+
// Only a GENERATION failure falls through — a bake failure throws out of tryVoxelMasterPath,
|
|
151
|
+
// because re-generating would pay twice for a source we already have.
|
|
152
|
+
log('Falling back to the mesh path.');
|
|
119
153
|
}
|
|
154
|
+
const outcome = await requestGeneration(environment, token, MESH_GENERATOR_TYPE, { gameId: context.metadata.gameId, prompt }, { fetch: fetchImpl, onProgress: log });
|
|
155
|
+
if (!outcome.success)
|
|
156
|
+
throw new CliError(`${outcome.message} world.json is unchanged.`);
|
|
157
|
+
if (!outcome.glbUrl) {
|
|
158
|
+
throw new CliError('The generator reported success but returned no mesh. world.json is unchanged.');
|
|
159
|
+
}
|
|
160
|
+
const glbUrl = outcome.glbUrl;
|
|
161
|
+
log(`Mesh generated: ${glbUrl}`);
|
|
120
162
|
const result = await voxelizeAndInstall({
|
|
121
|
-
context, environment, token, assetId, prompt,
|
|
163
|
+
context, environment, token, assetId, prompt,
|
|
164
|
+
source: { kind: 'glb', glbUrl },
|
|
165
|
+
log, ...(options.session ? { session: options.session } : {}),
|
|
122
166
|
});
|
|
123
167
|
return { ...result, glbUrl };
|
|
124
168
|
}
|
|
169
|
+
/**
|
|
170
|
+
* The dev-only path: a voxel master instead of a mesh.
|
|
171
|
+
*
|
|
172
|
+
* Returns null when GENERATION failed, so the caller can fall back to the mesh path. Bake failures
|
|
173
|
+
* throw instead: the master exists and was paid for, so the useful answer is "here is what is
|
|
174
|
+
* kept", not another generation. That is the same split the mesh path has always made with
|
|
175
|
+
* `--glb-url`.
|
|
176
|
+
*/
|
|
177
|
+
async function tryVoxelMasterPath(options) {
|
|
178
|
+
const { context, environment, token, assetId, prompt, log, fetchImpl } = options;
|
|
179
|
+
let outcome;
|
|
180
|
+
try {
|
|
181
|
+
outcome = await requestGeneration(environment, token, VOXEL_GENERATOR_TYPE, { gameId: context.metadata.gameId, prompt }, { fetch: fetchImpl, onProgress: log });
|
|
182
|
+
}
|
|
183
|
+
catch (error) {
|
|
184
|
+
// A non-2xx THROWS rather than returning an unsuccessful outcome, so catching is not belt and
|
|
185
|
+
// braces — it is the whole fallback for the most likely failure of all. An api-server that
|
|
186
|
+
// does not know `prop-voxel` answers 400, which is exactly what a dev deployment looks like
|
|
187
|
+
// before this feature reaches it. Without this the command would die there instead of doing
|
|
188
|
+
// what it has always done.
|
|
189
|
+
log(`Direct voxel generation is unavailable (${messageOf(error)}).`);
|
|
190
|
+
return null;
|
|
191
|
+
}
|
|
192
|
+
const masterUrl = outcome.success ? outcome.masterUrl : undefined;
|
|
193
|
+
if (!masterUrl) {
|
|
194
|
+
// Said out loud, including the cost: the generator bills the moment the Forger accepts the
|
|
195
|
+
// job, so a failure here may already have spent sparks and the mesh attempt will spend more.
|
|
196
|
+
// A silent fallback is how a doubled bill becomes a mystery.
|
|
197
|
+
log(`Direct voxel generation did not produce a master (${outcome.message}). `
|
|
198
|
+
+ 'If the generator had already accepted the job, that attempt was still billed.');
|
|
199
|
+
return null;
|
|
200
|
+
}
|
|
201
|
+
log(`Voxels generated: ${masterUrl}`);
|
|
202
|
+
const result = await voxelizeAndInstall({
|
|
203
|
+
context, environment, token, assetId, prompt,
|
|
204
|
+
source: { kind: 'master', masterUrl },
|
|
205
|
+
log, ...(options.session ? { session: options.session } : {}),
|
|
206
|
+
});
|
|
207
|
+
return { ...result, masterUrl };
|
|
208
|
+
}
|
|
125
209
|
/**
|
|
126
210
|
* Steps 2 and 3. Split from the command so the browser work is callable directly on a retry that
|
|
127
211
|
* already has a GLB, and so the command file stays about flags and output.
|
|
128
212
|
*/
|
|
129
213
|
export async function voxelizeAndInstall(options) {
|
|
130
|
-
const { context, environment, token, assetId, prompt,
|
|
214
|
+
const { context, environment, token, assetId, prompt, source, log } = options;
|
|
215
|
+
const runSession = options.session ?? withVoxelizeSession;
|
|
131
216
|
const worldPath = projectWorldJsonPath(context.root);
|
|
132
217
|
const world = readWorld(worldPath);
|
|
133
218
|
const { asset, fitBox } = findPropAsset(world, assetId);
|
|
134
219
|
const assetName = typeof asset.name === 'string' ? asset.name : assetId;
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
let host;
|
|
143
|
-
let uploadProxy;
|
|
144
|
-
try {
|
|
145
|
-
server = spawn(vite, ['--port', String(port), '--strictPort'], {
|
|
146
|
-
cwd: context.root,
|
|
147
|
-
stdio: ['ignore', 'ignore', 'pipe'],
|
|
148
|
-
});
|
|
149
|
-
let viteStderr = '';
|
|
150
|
-
server.stderr?.on('data', (chunk) => { viteStderr += String(chunk); });
|
|
151
|
-
try {
|
|
152
|
-
await waitForServer(port, 30_000);
|
|
220
|
+
// What was generated, what it cost, and how to reuse it — the three things every failure below
|
|
221
|
+
// has to say, and the only part of those messages that differs between the two sources.
|
|
222
|
+
const kept = source.kind === 'glb'
|
|
223
|
+
? {
|
|
224
|
+
subject: 'the mesh',
|
|
225
|
+
what: `The generated mesh is kept at ${source.glbUrl}`,
|
|
226
|
+
retry: ' — retry with `--glb-url` to skip the paid generation step.',
|
|
153
227
|
}
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
fillInterior:
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
228
|
+
: {
|
|
229
|
+
subject: 'the voxels',
|
|
230
|
+
// No --master-url retry flag exists yet; saying so beats implying one.
|
|
231
|
+
what: `The generated voxel master is kept at ${source.masterUrl}`,
|
|
232
|
+
retry: '. Re-run to generate again, or bake it by hand from that URL.',
|
|
233
|
+
};
|
|
234
|
+
return runSession({
|
|
235
|
+
context, environment, token, log, subject: kept.subject, retryHint: `${kept.what}${kept.retry}`,
|
|
236
|
+
}, async ({ host, port }) => {
|
|
237
|
+
log(`Baking "${assetName}" to its recorded fitBox…`);
|
|
238
|
+
// Both messages are answered on the GLB reply channel: the engine does that deliberately so
|
|
239
|
+
// the Creator's persist-and-reload watcher fires for either. `hq-asset-jobs.ts` picks between
|
|
240
|
+
// exactly these two shapes — this is that fork, not a third one.
|
|
241
|
+
const request = source.kind === 'glb'
|
|
242
|
+
? {
|
|
243
|
+
type: 'CREATE_ASSET_FROM_GLB_URL',
|
|
244
|
+
requestId: `prop-${assetId}-${port}`,
|
|
245
|
+
name: assetName,
|
|
246
|
+
glbUrl: source.glbUrl,
|
|
247
|
+
// The SAME id, which is what makes this an upgrade of every placed instance rather than
|
|
248
|
+
// a new asset sitting beside them.
|
|
249
|
+
assetId,
|
|
250
|
+
options: {
|
|
251
|
+
minVoxelSize: MIN_VOXEL_SIZE,
|
|
252
|
+
maxVoxelSize: MAX_VOXEL_SIZE,
|
|
253
|
+
fitBox,
|
|
254
|
+
fillInterior: shouldFillInterior(fitBox),
|
|
255
|
+
placeholder: false,
|
|
256
|
+
},
|
|
257
|
+
}
|
|
258
|
+
: {
|
|
259
|
+
type: 'CREATE_ASSET_FROM_VXL_MASTER',
|
|
260
|
+
requestId: `prop-${assetId}-${port}`,
|
|
261
|
+
name: assetName,
|
|
262
|
+
masterUrl: source.masterUrl,
|
|
263
|
+
assetId,
|
|
264
|
+
// No fillInterior: a master already carries the occupancy the mesh path has to infer.
|
|
265
|
+
options: {
|
|
266
|
+
minVoxelSize: MIN_VOXEL_SIZE,
|
|
267
|
+
maxVoxelSize: MAX_VOXEL_SIZE,
|
|
268
|
+
fitBox,
|
|
269
|
+
},
|
|
270
|
+
};
|
|
271
|
+
const result = await host.transport.sendAndWait(request, 'ASSET_FROM_GLB_URL_RESULT', VOXELIZE_TIMEOUT_MS, { maxRetries: 1 });
|
|
194
272
|
if (!result) {
|
|
195
|
-
throw new CliError(`
|
|
196
|
-
+ '`--glb-url` to skip the paid generation step.');
|
|
273
|
+
throw new CliError(`Baking "${assetName}" timed out. ${kept.what}${kept.retry}`);
|
|
197
274
|
}
|
|
198
275
|
if (result.success === false || !isRecord(result.asset)) {
|
|
199
276
|
const reason = typeof result.error === 'string' ? result.error : 'unknown error';
|
|
200
|
-
throw new CliError(`
|
|
277
|
+
throw new CliError(`Baking "${assetName}" failed: ${reason}. ${kept.what}.`);
|
|
201
278
|
}
|
|
202
279
|
const engineAsset = result.asset;
|
|
203
280
|
// The voxelize handler reads `description` from the GLB's scene extras, which the world-forger
|
|
@@ -225,16 +302,6 @@ export async function voxelizeAndInstall(options) {
|
|
|
225
302
|
...(typeof upgraded.url === 'string' ? { assetUrl: upgraded.url } : {}),
|
|
226
303
|
instanceCount: countInstances(world, assetId),
|
|
227
304
|
};
|
|
228
|
-
}
|
|
229
|
-
finally {
|
|
230
|
-
// Ordered: the page first (it may still be mid-upload), then the proxy it was uploading
|
|
231
|
-
// through, then the server underneath both.
|
|
232
|
-
if (host)
|
|
233
|
-
await host.close();
|
|
234
|
-
if (uploadProxy)
|
|
235
|
-
await uploadProxy.close();
|
|
236
|
-
if (server)
|
|
237
|
-
server.kill('SIGTERM');
|
|
238
|
-
}
|
|
305
|
+
});
|
|
239
306
|
}
|
|
240
307
|
//# sourceMappingURL=prop.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prop.js","sourceRoot":"","sources":["../../src/generate/prop.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"prop.js","sourceRoot":"","sources":["../../src/generate/prop.ts"],"names":[],"mappings":"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"}
|
|
@@ -11,6 +11,13 @@ export interface GenerationOutcome {
|
|
|
11
11
|
* for them this, not `patches`, is the result that matters. Absent for every other type.
|
|
12
12
|
*/
|
|
13
13
|
glbUrl?: string;
|
|
14
|
+
/**
|
|
15
|
+
* Only the `prop-voxel` type sets this: an HFVX voxel master, generated with no mesh at any
|
|
16
|
+
* point. The same half-made-asset story as `glbUrl` — the caller bakes it in a browser before
|
|
17
|
+
* there is anything to write — but the bake takes a different engine message, so which field
|
|
18
|
+
* came back is what tells the caller which one to send.
|
|
19
|
+
*/
|
|
20
|
+
masterUrl?: string;
|
|
14
21
|
/**
|
|
15
22
|
* Only the `vehicle` type sets this: the bake settings its GLB was authored for. `minVoxelSize`
|
|
16
23
|
* is derived from the vehicle's own proportions rather than fixed, so the CLI cannot pick it —
|
package/dist/generate/stream.js
CHANGED
|
@@ -39,7 +39,7 @@ function asVehicleOutcome(value) {
|
|
|
39
39
|
function asGenerationOutcome(data) {
|
|
40
40
|
if (!isRecord(data))
|
|
41
41
|
return null;
|
|
42
|
-
const { success, message, patches, glbUrl, vehicle } = data;
|
|
42
|
+
const { success, message, patches, glbUrl, masterUrl, vehicle } = data;
|
|
43
43
|
if (typeof success !== 'boolean' || typeof message !== 'string' || !Array.isArray(patches)) {
|
|
44
44
|
return null;
|
|
45
45
|
}
|
|
@@ -49,6 +49,7 @@ function asGenerationOutcome(data) {
|
|
|
49
49
|
message,
|
|
50
50
|
patches: patches,
|
|
51
51
|
...(typeof glbUrl === 'string' ? { glbUrl } : {}),
|
|
52
|
+
...(typeof masterUrl === 'string' ? { masterUrl } : {}),
|
|
52
53
|
...(vehicleOutcome ? { vehicle: vehicleOutcome } : {}),
|
|
53
54
|
};
|
|
54
55
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stream.js","sourceRoot":"","sources":["../../src/generate/stream.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAExC,OAAO,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AACxG,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AAQnE,gGAAgG;AAChG,gGAAgG;AAChG,qCAAqC;AACrC,OAAO,EAAE,cAAc,EAAiB,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"stream.js","sourceRoot":"","sources":["../../src/generate/stream.ts"],"names":[],"mappings":"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"}
|