@neocompose/cli 0.61.2 → 0.61.3
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/CHANGELOG.md +6 -0
- package/dist/neo.mjs +520 -201
- package/package.json +1 -1
- package/skills/neocompose-cli/SKILL.md +1 -1
- package/skills/neocompose-cli/references/cli-development.md +1 -1
- package/skills/neocompose-cli/references/declarations-and-construction.md +4 -0
- package/skills/neocompose-cli/references/values-identities-and-references.md +5 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.61.3] - 2026-10-01
|
|
4
|
+
|
|
5
|
+
- Resolve `collectionValue: Reference(root.Assets.Quests.Daily)` through construction defaults, including classes and empty collections declared in the same push. Preparation creates the required rows and associations together; no preliminary push or manually assigned value IDs are needed.
|
|
6
|
+
- Preserve generated collection identities through source verification and subsequent pulls. Report one source diagnostic when a collection path cannot resolve.
|
|
7
|
+
- Capture root-path reads through construction defaults as executable initializers, including nested object fields. Preserve sparse receiver identities during read-only construction replay so local and web preparation can resolve those reads.
|
|
8
|
+
|
|
3
9
|
## [0.61.2] - 2026-09-30
|
|
4
10
|
|
|
5
11
|
- Delete hidden collection entry members when their owning class or collection declaration is removed or changed to a scalar, while preserving entries still used by surviving declarations.
|
package/dist/neo.mjs
CHANGED
|
@@ -63084,6 +63084,7 @@ function isSourceMemberValueRead(context, expression, ownerClass) {
|
|
|
63084
63084
|
while (current.kind === "annotated") current = current.expression;
|
|
63085
63085
|
const path = expressionMemberPath(current);
|
|
63086
63086
|
if (path === null) return false;
|
|
63087
|
+
if (path.startsWith("root.")) return true;
|
|
63087
63088
|
const parts = path.split(".");
|
|
63088
63089
|
let classId;
|
|
63089
63090
|
let memberName;
|
|
@@ -75760,7 +75761,7 @@ function withEvaluationRuntime(ctx, writes) {
|
|
|
75760
75761
|
ctx.__runtimeSessionValues
|
|
75761
75762
|
);
|
|
75762
75763
|
const referencesAlreadyRemapped = ctx.__valueOverlay !== void 0 && ctx.__runtimeReferenceRemap !== void 0;
|
|
75763
|
-
const remap = (value) => referencesAlreadyRemapped ? value : remapRuntimeReferences(
|
|
75764
|
+
const remap = (value) => referencesAlreadyRemapped || ctx.storedConstructionReplay === true ? value : remapRuntimeReferences(
|
|
75764
75765
|
value,
|
|
75765
75766
|
overlay,
|
|
75766
75767
|
referenceRemap,
|
|
@@ -85753,14 +85754,15 @@ function claimVirtualIdentity(args) {
|
|
|
85753
85754
|
virtualId: args.fixedVirtualId
|
|
85754
85755
|
};
|
|
85755
85756
|
}
|
|
85756
|
-
const
|
|
85757
|
+
const valueId = (sourceIdentity4) => args.instanceRootId.startsWith("__pending__:") || hasPendingVirtualSourceIdentity(sourceIdentity4) ? pendingVirtualValueId(args.instanceRootId, sourceIdentity4) : virtualValueId(args.instanceRootId, sourceIdentity4);
|
|
85758
|
+
const derivedId = valueId(args.rawSourceIdentity);
|
|
85757
85759
|
const claimedPath = args.claimedVirtualIds.get(derivedId);
|
|
85758
85760
|
if (claimedPath === void 0 || claimedPath === args.pathKey) {
|
|
85759
85761
|
args.claimedVirtualIds.set(derivedId, args.pathKey);
|
|
85760
85762
|
return { sourceIdentity: args.rawSourceIdentity, virtualId: derivedId };
|
|
85761
85763
|
}
|
|
85762
85764
|
const sourceIdentity3 = `${args.rawSourceIdentity}:${args.pathKey}`;
|
|
85763
|
-
const virtualId =
|
|
85765
|
+
const virtualId = valueId(sourceIdentity3);
|
|
85764
85766
|
args.claimedVirtualIds.set(virtualId, args.pathKey);
|
|
85765
85767
|
return { sourceIdentity: sourceIdentity3, virtualId };
|
|
85766
85768
|
}
|
|
@@ -88141,6 +88143,8 @@ function createHeadlessVirtualInstanceResolver(args) {
|
|
|
88141
88143
|
const remember = (graph, rows) => {
|
|
88142
88144
|
graphRowsByRootId.set(graph.instanceRootId, rows);
|
|
88143
88145
|
for (const [id2, row] of graph.rowsById) {
|
|
88146
|
+
if (id2 !== graph.instanceRootId && graphByValueId.get(id2)?.instanceRootId === id2)
|
|
88147
|
+
continue;
|
|
88144
88148
|
expandedRowById.set(id2, row);
|
|
88145
88149
|
graphByValueId.set(id2, graph);
|
|
88146
88150
|
if (typeof row.value === "object" && row.value !== null) {
|
|
@@ -88148,6 +88152,8 @@ function createHeadlessVirtualInstanceResolver(args) {
|
|
|
88148
88152
|
}
|
|
88149
88153
|
}
|
|
88150
88154
|
for (const id2 of graph.locationsById.keys()) {
|
|
88155
|
+
if (id2 !== graph.instanceRootId && graphByValueId.get(id2)?.instanceRootId === id2)
|
|
88156
|
+
continue;
|
|
88151
88157
|
graphByValueId.set(id2, graph);
|
|
88152
88158
|
}
|
|
88153
88159
|
graphByValueId.set(graph.instanceRootId, graph);
|
|
@@ -88266,7 +88272,10 @@ function createHeadlessVirtualInstanceResolver(args) {
|
|
|
88266
88272
|
rowForValueReference: (value) => expandedRowByRecord.get(value) ?? null,
|
|
88267
88273
|
virtualInstanceGraphForValue: (valueId) => {
|
|
88268
88274
|
const known = graphByValueId.get(valueId);
|
|
88269
|
-
if (known
|
|
88275
|
+
if (known?.instanceRootId === valueId) return known;
|
|
88276
|
+
const stored = rawById.get(valueId);
|
|
88277
|
+
if (known !== void 0 && (stored === void 0 || !isStoredClassResolutionRoot(stored)))
|
|
88278
|
+
return known;
|
|
88270
88279
|
virtualInstanceRowsForValue(valueId);
|
|
88271
88280
|
return graphByValueId.get(valueId) ?? null;
|
|
88272
88281
|
},
|
|
@@ -98336,6 +98345,389 @@ var init_project_commit_preparation_scoped_loader = __esm({
|
|
|
98336
98345
|
}
|
|
98337
98346
|
});
|
|
98338
98347
|
|
|
98348
|
+
// ../src/runtime/neoscript/index.ts
|
|
98349
|
+
var init_neoscript2 = __esm({
|
|
98350
|
+
"../src/runtime/neoscript/index.ts"() {
|
|
98351
|
+
"use strict";
|
|
98352
|
+
init_NSGetterRuntimeError();
|
|
98353
|
+
init_evaluateNSGetter();
|
|
98354
|
+
init_evaluateInitializer();
|
|
98355
|
+
init_initializer_context();
|
|
98356
|
+
}
|
|
98357
|
+
});
|
|
98358
|
+
|
|
98359
|
+
// ../src/database/headless-virtual-instance-lookups.ts
|
|
98360
|
+
function headlessVirtualInstanceLookups(document, options = {}) {
|
|
98361
|
+
const members = document.members;
|
|
98362
|
+
const expandedDocument = expandPackedDocumentValues(document);
|
|
98363
|
+
const values = expandedDocument.values;
|
|
98364
|
+
const indexed = makeEvaluatorLookups(
|
|
98365
|
+
members,
|
|
98366
|
+
values,
|
|
98367
|
+
options.includeValueGraphIndexes === true ? {
|
|
98368
|
+
includeValueGraphIndexes: true,
|
|
98369
|
+
constructorInitializerDocument: {
|
|
98370
|
+
classes: document.classes,
|
|
98371
|
+
members,
|
|
98372
|
+
values
|
|
98373
|
+
}
|
|
98374
|
+
} : {}
|
|
98375
|
+
);
|
|
98376
|
+
const virtual = createHeadlessVirtualInstanceResolver2({
|
|
98377
|
+
document: {
|
|
98378
|
+
...expandedDocument,
|
|
98379
|
+
...options.initializerCompiler === void 0 ? {} : { initializerCompiler: options.initializerCompiler }
|
|
98380
|
+
},
|
|
98381
|
+
// A thunk: the resolver resolves nested reads through the lookups being
|
|
98382
|
+
// built around it.
|
|
98383
|
+
resolverLookups: () => lookups
|
|
98384
|
+
});
|
|
98385
|
+
const lookups = {
|
|
98386
|
+
...indexed,
|
|
98387
|
+
// Raw first, then virtual: a materialized row always wins over the
|
|
98388
|
+
// expansion that would otherwise answer for it.
|
|
98389
|
+
valueById: (id2) => indexed.valueById(id2) ?? virtual.valueById(id2),
|
|
98390
|
+
rowForValueReference: (value) => indexed.rowForValueReference(value) ?? virtual.rowForValueReference(value),
|
|
98391
|
+
virtualInstanceRowsForValue: (receiverValueId) => virtual.virtualInstanceRowsForValue(receiverValueId),
|
|
98392
|
+
// Stored-construction replay evaluates `ToVariant`, and production's
|
|
98393
|
+
// variant-constructed placements collapse through exactly this path.
|
|
98394
|
+
resolveVariantInstanceGraph: (args) => resolveVariantInstanceGraphForDocument2({
|
|
98395
|
+
document,
|
|
98396
|
+
resolverLookups: lookups,
|
|
98397
|
+
...args
|
|
98398
|
+
}),
|
|
98399
|
+
// A write to a virtual key must MATERIALIZE it (a pin row at the
|
|
98400
|
+
// deterministic virtual id plus the sparse spine); the planner needs the
|
|
98401
|
+
// owning graph, not just its rows.
|
|
98402
|
+
virtualInstanceGraphForValue: (valueId) => virtual.virtualInstanceGraphForValue(valueId)
|
|
98403
|
+
};
|
|
98404
|
+
return lookups;
|
|
98405
|
+
}
|
|
98406
|
+
var init_headless_virtual_instance_lookups = __esm({
|
|
98407
|
+
"../src/database/headless-virtual-instance-lookups.ts"() {
|
|
98408
|
+
"use strict";
|
|
98409
|
+
init_virtual_instance_values();
|
|
98410
|
+
init_packed_value_encoding();
|
|
98411
|
+
init_neoscript2();
|
|
98412
|
+
}
|
|
98413
|
+
});
|
|
98414
|
+
|
|
98415
|
+
// ../src/database/collection-binding-materialization.ts
|
|
98416
|
+
function mergeBodies(left, right) {
|
|
98417
|
+
if (right === void 0) return left;
|
|
98418
|
+
if (typeof left === "object" && left !== null && !Array.isArray(left) && typeof right === "object" && right !== null && !Array.isArray(right)) {
|
|
98419
|
+
return { ...left, ...right };
|
|
98420
|
+
}
|
|
98421
|
+
return right;
|
|
98422
|
+
}
|
|
98423
|
+
var CollectionBindingMaterializer;
|
|
98424
|
+
var init_collection_binding_materialization = __esm({
|
|
98425
|
+
"../src/database/collection-binding-materialization.ts"() {
|
|
98426
|
+
"use strict";
|
|
98427
|
+
init_members();
|
|
98428
|
+
init_virtual_instance_values();
|
|
98429
|
+
init_headless_virtual_instance_lookups();
|
|
98430
|
+
init_document_initializer_compiler();
|
|
98431
|
+
CollectionBindingMaterializer = class {
|
|
98432
|
+
constructor(document) {
|
|
98433
|
+
this.document = document;
|
|
98434
|
+
this.stored = new Map(document.values.map((row) => [row.id, row]));
|
|
98435
|
+
this.lookups = headlessVirtualInstanceLookups(document, {
|
|
98436
|
+
initializerCompiler: documentInitializerCompiler(document)
|
|
98437
|
+
});
|
|
98438
|
+
}
|
|
98439
|
+
document;
|
|
98440
|
+
rows = /* @__PURE__ */ new Map();
|
|
98441
|
+
pathRowsByRootId = /* @__PURE__ */ new Map();
|
|
98442
|
+
stored;
|
|
98443
|
+
lookups;
|
|
98444
|
+
resolvePath(rootId, segments) {
|
|
98445
|
+
let id2 = rootId;
|
|
98446
|
+
const pathRows = this.pathRowsByRootId.get(rootId) ?? /* @__PURE__ */ new Set();
|
|
98447
|
+
this.pathRowsByRootId.set(rootId, pathRows);
|
|
98448
|
+
for (const segment of segments) {
|
|
98449
|
+
const graph = this.lookups.virtualInstanceGraphForValue(id2);
|
|
98450
|
+
const row = graph?.rowsById.get(id2) ?? this.stored.get(id2);
|
|
98451
|
+
if (row === void 0 || !isLiteralValueContent(row)) return null;
|
|
98452
|
+
const body = row.value;
|
|
98453
|
+
if (typeof body !== "object" || body === null || Array.isArray(body))
|
|
98454
|
+
return null;
|
|
98455
|
+
const next = Reflect.get(body, segment);
|
|
98456
|
+
if (typeof next !== "string") return null;
|
|
98457
|
+
id2 = next;
|
|
98458
|
+
pathRows.add(id2);
|
|
98459
|
+
}
|
|
98460
|
+
return this.materialize(id2, pathRows) ? id2 : null;
|
|
98461
|
+
}
|
|
98462
|
+
/** Discover opaque virtual IDs from web selections against this candidate's roots. */
|
|
98463
|
+
materializeTargets(ids) {
|
|
98464
|
+
const missing = new Set([...ids].filter((id2) => !this.stored.has(id2)));
|
|
98465
|
+
if (missing.size === 0) return;
|
|
98466
|
+
const visited = /* @__PURE__ */ new Set();
|
|
98467
|
+
for (const row of this.document.values) {
|
|
98468
|
+
if (typeof row.classId !== "string") continue;
|
|
98469
|
+
const graph = this.lookups.virtualInstanceGraphForValue(row.id);
|
|
98470
|
+
if (graph === null || visited.has(graph.instanceRootId)) continue;
|
|
98471
|
+
visited.add(graph.instanceRootId);
|
|
98472
|
+
for (const id2 of graph.rowsById.keys()) {
|
|
98473
|
+
if (!missing.has(id2)) continue;
|
|
98474
|
+
if (this.materialize(id2)) missing.delete(id2);
|
|
98475
|
+
}
|
|
98476
|
+
if (missing.size === 0) return;
|
|
98477
|
+
}
|
|
98478
|
+
if (missing.size > 0) {
|
|
98479
|
+
throw new Error(
|
|
98480
|
+
`Collection binding targets missing values: ${[...missing].join(", ")}.`
|
|
98481
|
+
);
|
|
98482
|
+
}
|
|
98483
|
+
}
|
|
98484
|
+
locationForValue(id2) {
|
|
98485
|
+
return this.lookups.virtualInstanceGraphForValue(id2)?.locationsById.get(id2);
|
|
98486
|
+
}
|
|
98487
|
+
rowForValue(id2) {
|
|
98488
|
+
return this.rows.get(id2) ?? this.stored.get(id2);
|
|
98489
|
+
}
|
|
98490
|
+
materialize(id2, pathRows) {
|
|
98491
|
+
if (this.stored.has(id2) || this.rows.has(id2)) return true;
|
|
98492
|
+
const graph = this.lookups.virtualInstanceGraphForValue(id2);
|
|
98493
|
+
const row = graph?.rowsById.get(id2);
|
|
98494
|
+
if (graph === null || row === void 0 || !isLiteralValueContent(row))
|
|
98495
|
+
return false;
|
|
98496
|
+
const plan = planVirtualOverrideWrite({
|
|
98497
|
+
graph,
|
|
98498
|
+
valueId: id2,
|
|
98499
|
+
value: row.value
|
|
98500
|
+
});
|
|
98501
|
+
for (const create of plan.creates) {
|
|
98502
|
+
pathRows?.add(create.id);
|
|
98503
|
+
const { valuePlacement: _placement, ...fields } = create;
|
|
98504
|
+
const previous = this.rows.get(create.id);
|
|
98505
|
+
this.rows.set(create.id, {
|
|
98506
|
+
...fields,
|
|
98507
|
+
value: mergeBodies(fields.value, previous?.value),
|
|
98508
|
+
projectId: this.document.project.id,
|
|
98509
|
+
createdAt: 0,
|
|
98510
|
+
updatedAt: 0
|
|
98511
|
+
});
|
|
98512
|
+
}
|
|
98513
|
+
for (const update of plan.updates) {
|
|
98514
|
+
pathRows?.add(update.valueId);
|
|
98515
|
+
const previous = this.rows.get(update.valueId) ?? this.stored.get(update.valueId);
|
|
98516
|
+
if (previous === void 0)
|
|
98517
|
+
throw new Error(
|
|
98518
|
+
`Collection binding has no ancestor ${update.valueId}.`
|
|
98519
|
+
);
|
|
98520
|
+
this.rows.set(update.valueId, {
|
|
98521
|
+
...previous,
|
|
98522
|
+
value: mergeBodies(previous.value, update.value)
|
|
98523
|
+
});
|
|
98524
|
+
}
|
|
98525
|
+
return true;
|
|
98526
|
+
}
|
|
98527
|
+
};
|
|
98528
|
+
}
|
|
98529
|
+
});
|
|
98530
|
+
|
|
98531
|
+
// ../src/database/project-version-write-changes.ts
|
|
98532
|
+
function applyProjectVersionWriteChanges(document, changes) {
|
|
98533
|
+
return projectVersionDocumentWithChanges(document, changes, false);
|
|
98534
|
+
}
|
|
98535
|
+
function projectVersionDocumentWithChanges(document, changes, reuseUnchangedBuckets) {
|
|
98536
|
+
const projectRows = (rows, kind) => {
|
|
98537
|
+
const relevant = changes.filter((change) => change.recordKind === kind);
|
|
98538
|
+
if (reuseUnchangedBuckets && relevant.length === 0) return rows;
|
|
98539
|
+
return applyArrayChanges(rows, relevant);
|
|
98540
|
+
};
|
|
98541
|
+
const hasGranularDialogueRecords = document.dialogueRecords !== void 0 || changes.some((change) => change.recordKind === "dialogue");
|
|
98542
|
+
const hasGranularDialogueNodes = document.dialogueNodes !== void 0 || changes.some((change) => change.recordKind === "dialogue-node");
|
|
98543
|
+
const dialogueRecords = hasGranularDialogueRecords ? projectRows(document.dialogueRecords ?? [], "dialogue") : void 0;
|
|
98544
|
+
const dialogueNodes = hasGranularDialogueNodes ? projectRows(document.dialogueNodes ?? [], "dialogue-node") : void 0;
|
|
98545
|
+
const projected = {
|
|
98546
|
+
localizedTexts: projectRows(
|
|
98547
|
+
document.localizedTexts ?? [],
|
|
98548
|
+
"localized-text"
|
|
98549
|
+
),
|
|
98550
|
+
localizationConfig: applySingletonChange(
|
|
98551
|
+
document.localizationConfig,
|
|
98552
|
+
changes,
|
|
98553
|
+
"localization-config"
|
|
98554
|
+
),
|
|
98555
|
+
project: applySingletonChange(document.project, changes, "project"),
|
|
98556
|
+
members: projectRows(document.members, "member"),
|
|
98557
|
+
classes: projectRows(document.classes, "class"),
|
|
98558
|
+
// P43 §6. Declared constructors participate in the post-transaction
|
|
98559
|
+
// document so the whole-graph validator and every body compile see the
|
|
98560
|
+
// same constructor surface the transaction is about to persist.
|
|
98561
|
+
constructors: projectRows(document.constructors ?? [], "constructor"),
|
|
98562
|
+
// P67 §2.1. Same reason as constructors: without these buckets the
|
|
98563
|
+
// whole-graph validator, the variant ownership roots, and every body
|
|
98564
|
+
// compile would grade the transaction against the pre-transaction
|
|
98565
|
+
// variant set — so a newly pushed variant's closures would compile
|
|
98566
|
+
// against a document that does not contain it.
|
|
98567
|
+
variants: projectRows(document.variants ?? [], "variant"),
|
|
98568
|
+
variantFolders: projectRows(
|
|
98569
|
+
document.variantFolders ?? [],
|
|
98570
|
+
"variant-folder"
|
|
98571
|
+
),
|
|
98572
|
+
values: projectRows(document.values ?? [], "value"),
|
|
98573
|
+
// Project-file staging finalizes pending uploads before schema
|
|
98574
|
+
// preparation. Defaults and authored instance graphs may reference a file
|
|
98575
|
+
// created by the same source transaction, so every construction pass must
|
|
98576
|
+
// see that finalized row in its post-write document.
|
|
98577
|
+
projectFiles: projectRows(document.projectFiles ?? [], "project-file"),
|
|
98578
|
+
// Import-setting templates are part of the same file graph. A new file
|
|
98579
|
+
// may select a new template in one source transaction, and default-value
|
|
98580
|
+
// materialization validates that relationship immediately against this
|
|
98581
|
+
// post-write document.
|
|
98582
|
+
textureTemplates: projectRows(
|
|
98583
|
+
document.textureTemplates ?? [],
|
|
98584
|
+
"unity-texture-template"
|
|
98585
|
+
),
|
|
98586
|
+
audioClipTemplates: projectRows(
|
|
98587
|
+
document.audioClipTemplates ?? [],
|
|
98588
|
+
"unity-audio-clip-template"
|
|
98589
|
+
),
|
|
98590
|
+
internalRecordRelations: projectRows(
|
|
98591
|
+
document.internalRecordRelations ?? [],
|
|
98592
|
+
"internal-record-relation"
|
|
98593
|
+
),
|
|
98594
|
+
enums: projectRows(document.enums, "enum"),
|
|
98595
|
+
interfaces: projectRows(document.interfaces, "interface"),
|
|
98596
|
+
dialogues: dialogueRecords === void 0 || dialogueNodes === void 0 || dialogueRecords === document.dialogueRecords && dialogueNodes === document.dialogueNodes ? document.dialogues : materializeDialogues(
|
|
98597
|
+
dialogueRecords,
|
|
98598
|
+
dialogueNodes
|
|
98599
|
+
),
|
|
98600
|
+
dialogueGroups: projectRows(
|
|
98601
|
+
document.dialogueGroups ?? [],
|
|
98602
|
+
"dialogue-group"
|
|
98603
|
+
),
|
|
98604
|
+
migrations: projectRows(document.migrations ?? [], "migration")
|
|
98605
|
+
};
|
|
98606
|
+
return {
|
|
98607
|
+
...document,
|
|
98608
|
+
...projected,
|
|
98609
|
+
...dialogueRecords === void 0 ? {} : { dialogueRecords },
|
|
98610
|
+
...dialogueNodes === void 0 ? {} : { dialogueNodes }
|
|
98611
|
+
// The document spread above carries every bucket the caller's view declares
|
|
98612
|
+
// beyond the projected ones, so the result is the same view; TypeScript
|
|
98613
|
+
// cannot prove that of an object literal built over a type parameter.
|
|
98614
|
+
};
|
|
98615
|
+
}
|
|
98616
|
+
function applySingletonChange(current, changes, recordKind) {
|
|
98617
|
+
const change = changes.find(
|
|
98618
|
+
(candidate) => candidate.recordKind === recordKind
|
|
98619
|
+
);
|
|
98620
|
+
if (change === void 0) return current;
|
|
98621
|
+
if (change.operation === "delete" || change.nextData === void 0) {
|
|
98622
|
+
throw new Error(`Schema commit cannot delete the ${recordKind} record.`);
|
|
98623
|
+
}
|
|
98624
|
+
return change.nextData;
|
|
98625
|
+
}
|
|
98626
|
+
function applyArrayChanges(current, changes) {
|
|
98627
|
+
const byId = new Map(current.map((record6) => [record6.id, record6]));
|
|
98628
|
+
for (const change of changes) {
|
|
98629
|
+
if (change.operation === "delete") {
|
|
98630
|
+
byId.delete(change.recordId);
|
|
98631
|
+
continue;
|
|
98632
|
+
}
|
|
98633
|
+
if (change.nextData !== void 0) {
|
|
98634
|
+
byId.set(change.recordId, change.nextData);
|
|
98635
|
+
}
|
|
98636
|
+
}
|
|
98637
|
+
return [...byId.values()];
|
|
98638
|
+
}
|
|
98639
|
+
var init_project_version_write_changes = __esm({
|
|
98640
|
+
"../src/database/project-version-write-changes.ts"() {
|
|
98641
|
+
"use strict";
|
|
98642
|
+
init_projectDocumentDialogueMaterialization();
|
|
98643
|
+
}
|
|
98644
|
+
});
|
|
98645
|
+
|
|
98646
|
+
// ../src/database/prepared-collection-bindings.ts
|
|
98647
|
+
function materializePreparedCollectionBindings(args) {
|
|
98648
|
+
const targets = /* @__PURE__ */ new Set();
|
|
98649
|
+
for (const change of args.prepared) {
|
|
98650
|
+
if (change.operation === "delete") continue;
|
|
98651
|
+
if (change.recordKind !== "member" && change.recordKind !== "variant-folder" && change.recordKind !== "dialogue-group")
|
|
98652
|
+
continue;
|
|
98653
|
+
const data = change.nextData;
|
|
98654
|
+
if (typeof data !== "object" || data === null) continue;
|
|
98655
|
+
const binding = change.recordKind === "variant-folder" ? Reflect.get(data, "binding") : data;
|
|
98656
|
+
if (typeof binding !== "object" || binding === null) continue;
|
|
98657
|
+
const id2 = Reflect.get(binding, "collectionValueId");
|
|
98658
|
+
if (typeof id2 === "string") targets.add(id2);
|
|
98659
|
+
}
|
|
98660
|
+
if (targets.size === 0) return;
|
|
98661
|
+
const deletedTargets = /* @__PURE__ */ new Set();
|
|
98662
|
+
for (const change of args.prepared) {
|
|
98663
|
+
if (change.recordKind !== "value" || !targets.has(change.recordId))
|
|
98664
|
+
continue;
|
|
98665
|
+
if (change.operation === "delete") deletedTargets.add(change.recordId);
|
|
98666
|
+
else targets.delete(change.recordId);
|
|
98667
|
+
}
|
|
98668
|
+
if (targets.size === 0) return;
|
|
98669
|
+
for (const row of args.document.values) {
|
|
98670
|
+
if (!deletedTargets.has(row.id)) targets.delete(row.id);
|
|
98671
|
+
if (targets.size === 0) return;
|
|
98672
|
+
}
|
|
98673
|
+
const document = projectVersionDocumentWithChanges(
|
|
98674
|
+
args.document,
|
|
98675
|
+
args.prepared,
|
|
98676
|
+
true
|
|
98677
|
+
);
|
|
98678
|
+
const existingIds = new Set(document.values.map((row) => row.id));
|
|
98679
|
+
const materializer = new CollectionBindingMaterializer(document);
|
|
98680
|
+
materializer.materializeTargets(targets);
|
|
98681
|
+
const indexes2 = /* @__PURE__ */ new Map();
|
|
98682
|
+
args.prepared.forEach((change, index) => {
|
|
98683
|
+
if (change.recordKind === "value") indexes2.set(change.recordId, index);
|
|
98684
|
+
});
|
|
98685
|
+
const hashes = new Map(
|
|
98686
|
+
args.contentHashHeads.filter((head) => head.recordKind === "value").map((head) => [head.recordId, head.contentHash])
|
|
98687
|
+
);
|
|
98688
|
+
for (const row of materializer.rows.values()) {
|
|
98689
|
+
const index = indexes2.get(row.id);
|
|
98690
|
+
if (index !== void 0) {
|
|
98691
|
+
const previous = args.prepared[index];
|
|
98692
|
+
args.prepared[index] = {
|
|
98693
|
+
...previous,
|
|
98694
|
+
operation: previous.operation === "delete" ? "update" : previous.operation,
|
|
98695
|
+
deleted: false,
|
|
98696
|
+
nextData: row,
|
|
98697
|
+
intent: previous.operation === "delete" ? createProjectVersionIntent("value.update", {
|
|
98698
|
+
source: "collection-binding-materialization"
|
|
98699
|
+
}) : previous.intent
|
|
98700
|
+
};
|
|
98701
|
+
continue;
|
|
98702
|
+
}
|
|
98703
|
+
const contentHash = hashes.get(row.id);
|
|
98704
|
+
if (existingIds.has(row.id) && contentHash === void 0) {
|
|
98705
|
+
throw new Error(
|
|
98706
|
+
`Collection binding ancestor "${row.id}" has no content hash.`
|
|
98707
|
+
);
|
|
98708
|
+
}
|
|
98709
|
+
args.prepared.push({
|
|
98710
|
+
recordKind: "value",
|
|
98711
|
+
recordId: row.id,
|
|
98712
|
+
operation: existingIds.has(row.id) ? "update" : "create",
|
|
98713
|
+
nextData: row,
|
|
98714
|
+
expectedBaseContentHash: contentHash ?? null,
|
|
98715
|
+
intent: createProjectVersionIntent(
|
|
98716
|
+
existingIds.has(row.id) ? "value.update" : "value.create",
|
|
98717
|
+
{ source: "collection-binding-materialization" }
|
|
98718
|
+
)
|
|
98719
|
+
});
|
|
98720
|
+
}
|
|
98721
|
+
}
|
|
98722
|
+
var init_prepared_collection_bindings = __esm({
|
|
98723
|
+
"../src/database/prepared-collection-bindings.ts"() {
|
|
98724
|
+
"use strict";
|
|
98725
|
+
init_project_version_intents();
|
|
98726
|
+
init_collection_binding_materialization();
|
|
98727
|
+
init_project_version_write_changes();
|
|
98728
|
+
}
|
|
98729
|
+
});
|
|
98730
|
+
|
|
98339
98731
|
// ../src/models/project/world-content-sidecar-validation.ts
|
|
98340
98732
|
function cachedWorldLayerTarget(context, args) {
|
|
98341
98733
|
let target = context.linkTargetsByClassId.get(args.sourceClassId);
|
|
@@ -98991,17 +99383,6 @@ var init_world_content_sidecar_validation = __esm({
|
|
|
98991
99383
|
}
|
|
98992
99384
|
});
|
|
98993
99385
|
|
|
98994
|
-
// ../src/runtime/neoscript/index.ts
|
|
98995
|
-
var init_neoscript2 = __esm({
|
|
98996
|
-
"../src/runtime/neoscript/index.ts"() {
|
|
98997
|
-
"use strict";
|
|
98998
|
-
init_NSGetterRuntimeError();
|
|
98999
|
-
init_evaluateNSGetter();
|
|
99000
|
-
init_evaluateInitializer();
|
|
99001
|
-
init_initializer_context();
|
|
99002
|
-
}
|
|
99003
|
-
});
|
|
99004
|
-
|
|
99005
99386
|
// ../src/database/dialogue-node-index.ts
|
|
99006
99387
|
function indexDialogueNodesByDialogue(nodes, dialogueId) {
|
|
99007
99388
|
const result = /* @__PURE__ */ new Map();
|
|
@@ -100300,62 +100681,6 @@ var init_general_function_call_ir_source_recompile = __esm({
|
|
|
100300
100681
|
}
|
|
100301
100682
|
});
|
|
100302
100683
|
|
|
100303
|
-
// ../src/database/headless-virtual-instance-lookups.ts
|
|
100304
|
-
function headlessVirtualInstanceLookups(document, options = {}) {
|
|
100305
|
-
const members = document.members;
|
|
100306
|
-
const expandedDocument = expandPackedDocumentValues(document);
|
|
100307
|
-
const values = expandedDocument.values;
|
|
100308
|
-
const indexed = makeEvaluatorLookups(
|
|
100309
|
-
members,
|
|
100310
|
-
values,
|
|
100311
|
-
options.includeValueGraphIndexes === true ? {
|
|
100312
|
-
includeValueGraphIndexes: true,
|
|
100313
|
-
constructorInitializerDocument: {
|
|
100314
|
-
classes: document.classes,
|
|
100315
|
-
members,
|
|
100316
|
-
values
|
|
100317
|
-
}
|
|
100318
|
-
} : {}
|
|
100319
|
-
);
|
|
100320
|
-
const virtual = createHeadlessVirtualInstanceResolver2({
|
|
100321
|
-
document: {
|
|
100322
|
-
...expandedDocument,
|
|
100323
|
-
...options.initializerCompiler === void 0 ? {} : { initializerCompiler: options.initializerCompiler }
|
|
100324
|
-
},
|
|
100325
|
-
// A thunk: the resolver resolves nested reads through the lookups being
|
|
100326
|
-
// built around it.
|
|
100327
|
-
resolverLookups: () => lookups
|
|
100328
|
-
});
|
|
100329
|
-
const lookups = {
|
|
100330
|
-
...indexed,
|
|
100331
|
-
// Raw first, then virtual: a materialized row always wins over the
|
|
100332
|
-
// expansion that would otherwise answer for it.
|
|
100333
|
-
valueById: (id2) => indexed.valueById(id2) ?? virtual.valueById(id2),
|
|
100334
|
-
rowForValueReference: (value) => indexed.rowForValueReference(value) ?? virtual.rowForValueReference(value),
|
|
100335
|
-
virtualInstanceRowsForValue: (receiverValueId) => virtual.virtualInstanceRowsForValue(receiverValueId),
|
|
100336
|
-
// Stored-construction replay evaluates `ToVariant`, and production's
|
|
100337
|
-
// variant-constructed placements collapse through exactly this path.
|
|
100338
|
-
resolveVariantInstanceGraph: (args) => resolveVariantInstanceGraphForDocument2({
|
|
100339
|
-
document,
|
|
100340
|
-
resolverLookups: lookups,
|
|
100341
|
-
...args
|
|
100342
|
-
}),
|
|
100343
|
-
// A write to a virtual key must MATERIALIZE it (a pin row at the
|
|
100344
|
-
// deterministic virtual id plus the sparse spine); the planner needs the
|
|
100345
|
-
// owning graph, not just its rows.
|
|
100346
|
-
virtualInstanceGraphForValue: (valueId) => virtual.virtualInstanceGraphForValue(valueId)
|
|
100347
|
-
};
|
|
100348
|
-
return lookups;
|
|
100349
|
-
}
|
|
100350
|
-
var init_headless_virtual_instance_lookups = __esm({
|
|
100351
|
-
"../src/database/headless-virtual-instance-lookups.ts"() {
|
|
100352
|
-
"use strict";
|
|
100353
|
-
init_virtual_instance_values();
|
|
100354
|
-
init_packed_value_encoding();
|
|
100355
|
-
init_neoscript2();
|
|
100356
|
-
}
|
|
100357
|
-
});
|
|
100358
|
-
|
|
100359
100684
|
// ../src/database/localized-instance-override-writes.ts
|
|
100360
100685
|
function collapseEditedLocalizedInstanceOverrides(args) {
|
|
100361
100686
|
const edits = args.changes.filter(
|
|
@@ -100787,121 +101112,6 @@ var init_member_access_modifier_validation = __esm({
|
|
|
100787
101112
|
}
|
|
100788
101113
|
});
|
|
100789
101114
|
|
|
100790
|
-
// ../src/database/project-version-write-changes.ts
|
|
100791
|
-
function applyProjectVersionWriteChanges(document, changes) {
|
|
100792
|
-
return projectVersionDocumentWithChanges(document, changes, false);
|
|
100793
|
-
}
|
|
100794
|
-
function projectVersionDocumentWithChanges(document, changes, reuseUnchangedBuckets) {
|
|
100795
|
-
const projectRows = (rows, kind) => {
|
|
100796
|
-
const relevant = changes.filter((change) => change.recordKind === kind);
|
|
100797
|
-
if (reuseUnchangedBuckets && relevant.length === 0) return rows;
|
|
100798
|
-
return applyArrayChanges(rows, relevant);
|
|
100799
|
-
};
|
|
100800
|
-
const hasGranularDialogueRecords = document.dialogueRecords !== void 0 || changes.some((change) => change.recordKind === "dialogue");
|
|
100801
|
-
const hasGranularDialogueNodes = document.dialogueNodes !== void 0 || changes.some((change) => change.recordKind === "dialogue-node");
|
|
100802
|
-
const dialogueRecords = hasGranularDialogueRecords ? projectRows(document.dialogueRecords ?? [], "dialogue") : void 0;
|
|
100803
|
-
const dialogueNodes = hasGranularDialogueNodes ? projectRows(document.dialogueNodes ?? [], "dialogue-node") : void 0;
|
|
100804
|
-
const projected = {
|
|
100805
|
-
localizedTexts: projectRows(
|
|
100806
|
-
document.localizedTexts ?? [],
|
|
100807
|
-
"localized-text"
|
|
100808
|
-
),
|
|
100809
|
-
localizationConfig: applySingletonChange(
|
|
100810
|
-
document.localizationConfig,
|
|
100811
|
-
changes,
|
|
100812
|
-
"localization-config"
|
|
100813
|
-
),
|
|
100814
|
-
project: applySingletonChange(document.project, changes, "project"),
|
|
100815
|
-
members: projectRows(document.members, "member"),
|
|
100816
|
-
classes: projectRows(document.classes, "class"),
|
|
100817
|
-
// P43 §6. Declared constructors participate in the post-transaction
|
|
100818
|
-
// document so the whole-graph validator and every body compile see the
|
|
100819
|
-
// same constructor surface the transaction is about to persist.
|
|
100820
|
-
constructors: projectRows(document.constructors ?? [], "constructor"),
|
|
100821
|
-
// P67 §2.1. Same reason as constructors: without these buckets the
|
|
100822
|
-
// whole-graph validator, the variant ownership roots, and every body
|
|
100823
|
-
// compile would grade the transaction against the pre-transaction
|
|
100824
|
-
// variant set — so a newly pushed variant's closures would compile
|
|
100825
|
-
// against a document that does not contain it.
|
|
100826
|
-
variants: projectRows(document.variants ?? [], "variant"),
|
|
100827
|
-
variantFolders: projectRows(
|
|
100828
|
-
document.variantFolders ?? [],
|
|
100829
|
-
"variant-folder"
|
|
100830
|
-
),
|
|
100831
|
-
values: projectRows(document.values ?? [], "value"),
|
|
100832
|
-
// Project-file staging finalizes pending uploads before schema
|
|
100833
|
-
// preparation. Defaults and authored instance graphs may reference a file
|
|
100834
|
-
// created by the same source transaction, so every construction pass must
|
|
100835
|
-
// see that finalized row in its post-write document.
|
|
100836
|
-
projectFiles: projectRows(document.projectFiles ?? [], "project-file"),
|
|
100837
|
-
// Import-setting templates are part of the same file graph. A new file
|
|
100838
|
-
// may select a new template in one source transaction, and default-value
|
|
100839
|
-
// materialization validates that relationship immediately against this
|
|
100840
|
-
// post-write document.
|
|
100841
|
-
textureTemplates: projectRows(
|
|
100842
|
-
document.textureTemplates ?? [],
|
|
100843
|
-
"unity-texture-template"
|
|
100844
|
-
),
|
|
100845
|
-
audioClipTemplates: projectRows(
|
|
100846
|
-
document.audioClipTemplates ?? [],
|
|
100847
|
-
"unity-audio-clip-template"
|
|
100848
|
-
),
|
|
100849
|
-
internalRecordRelations: projectRows(
|
|
100850
|
-
document.internalRecordRelations ?? [],
|
|
100851
|
-
"internal-record-relation"
|
|
100852
|
-
),
|
|
100853
|
-
enums: projectRows(document.enums, "enum"),
|
|
100854
|
-
interfaces: projectRows(document.interfaces, "interface"),
|
|
100855
|
-
dialogues: dialogueRecords === void 0 || dialogueNodes === void 0 || dialogueRecords === document.dialogueRecords && dialogueNodes === document.dialogueNodes ? document.dialogues : materializeDialogues(
|
|
100856
|
-
dialogueRecords,
|
|
100857
|
-
dialogueNodes
|
|
100858
|
-
),
|
|
100859
|
-
dialogueGroups: projectRows(
|
|
100860
|
-
document.dialogueGroups ?? [],
|
|
100861
|
-
"dialogue-group"
|
|
100862
|
-
),
|
|
100863
|
-
migrations: projectRows(document.migrations ?? [], "migration")
|
|
100864
|
-
};
|
|
100865
|
-
return {
|
|
100866
|
-
...document,
|
|
100867
|
-
...projected,
|
|
100868
|
-
...dialogueRecords === void 0 ? {} : { dialogueRecords },
|
|
100869
|
-
...dialogueNodes === void 0 ? {} : { dialogueNodes }
|
|
100870
|
-
// The document spread above carries every bucket the caller's view declares
|
|
100871
|
-
// beyond the projected ones, so the result is the same view; TypeScript
|
|
100872
|
-
// cannot prove that of an object literal built over a type parameter.
|
|
100873
|
-
};
|
|
100874
|
-
}
|
|
100875
|
-
function applySingletonChange(current, changes, recordKind) {
|
|
100876
|
-
const change = changes.find(
|
|
100877
|
-
(candidate) => candidate.recordKind === recordKind
|
|
100878
|
-
);
|
|
100879
|
-
if (change === void 0) return current;
|
|
100880
|
-
if (change.operation === "delete" || change.nextData === void 0) {
|
|
100881
|
-
throw new Error(`Schema commit cannot delete the ${recordKind} record.`);
|
|
100882
|
-
}
|
|
100883
|
-
return change.nextData;
|
|
100884
|
-
}
|
|
100885
|
-
function applyArrayChanges(current, changes) {
|
|
100886
|
-
const byId = new Map(current.map((record6) => [record6.id, record6]));
|
|
100887
|
-
for (const change of changes) {
|
|
100888
|
-
if (change.operation === "delete") {
|
|
100889
|
-
byId.delete(change.recordId);
|
|
100890
|
-
continue;
|
|
100891
|
-
}
|
|
100892
|
-
if (change.nextData !== void 0) {
|
|
100893
|
-
byId.set(change.recordId, change.nextData);
|
|
100894
|
-
}
|
|
100895
|
-
}
|
|
100896
|
-
return [...byId.values()];
|
|
100897
|
-
}
|
|
100898
|
-
var init_project_version_write_changes = __esm({
|
|
100899
|
-
"../src/database/project-version-write-changes.ts"() {
|
|
100900
|
-
"use strict";
|
|
100901
|
-
init_projectDocumentDialogueMaterialization();
|
|
100902
|
-
}
|
|
100903
|
-
});
|
|
100904
|
-
|
|
100905
101115
|
// ../src/database/member-localization-normalization.ts
|
|
100906
101116
|
function planMemberLocalizationNormalization(input, now = 0) {
|
|
100907
101117
|
const before = expandPackedDocumentValues(input);
|
|
@@ -103350,6 +103560,11 @@ function* prepareServerOwnedSchemaCommitPasses(args) {
|
|
|
103350
103560
|
prepared,
|
|
103351
103561
|
contentHashHeads: args.contentHashHeads
|
|
103352
103562
|
});
|
|
103563
|
+
materializePreparedCollectionBindings({
|
|
103564
|
+
document: args.document,
|
|
103565
|
+
prepared,
|
|
103566
|
+
contentHashHeads: args.contentHashHeads
|
|
103567
|
+
});
|
|
103353
103568
|
drainConstructedGraphValidations({
|
|
103354
103569
|
document: args.document,
|
|
103355
103570
|
prepared,
|
|
@@ -106840,6 +107055,7 @@ var SERVER_COMPILATION_PROJECT_CACHE_LIMIT, serverCompilationProjectCache, READ_
|
|
|
106840
107055
|
var init_project_version_schema_commit = __esm({
|
|
106841
107056
|
"../src/database/project-version-schema-commit.ts"() {
|
|
106842
107057
|
"use strict";
|
|
107058
|
+
init_prepared_collection_bindings();
|
|
106843
107059
|
init_document_initializer_compiler();
|
|
106844
107060
|
init_effective_value_comparison();
|
|
106845
107061
|
init_classes();
|
|
@@ -120807,7 +121023,8 @@ function resolveRootPathCollectionValuesV4(args) {
|
|
|
120807
121023
|
args.registry,
|
|
120808
121024
|
placements,
|
|
120809
121025
|
rootValues,
|
|
120810
|
-
fail2
|
|
121026
|
+
fail2,
|
|
121027
|
+
args.resolveVirtualPath
|
|
120811
121028
|
);
|
|
120812
121029
|
if (target !== null) resolved.set(member.id, target);
|
|
120813
121030
|
}
|
|
@@ -120845,7 +121062,8 @@ function resolveRootPathVariantFolderCollectionValuesV4(args) {
|
|
|
120845
121062
|
args.registry,
|
|
120846
121063
|
placements,
|
|
120847
121064
|
rootValues,
|
|
120848
|
-
fail2
|
|
121065
|
+
fail2,
|
|
121066
|
+
args.resolveVirtualPath
|
|
120849
121067
|
);
|
|
120850
121068
|
if (target !== null) resolved.set(folder.id, target);
|
|
120851
121069
|
}
|
|
@@ -120882,7 +121100,8 @@ function resolveRootPathDialogueGroupCollectionValuesV4(args) {
|
|
|
120882
121100
|
expression: null,
|
|
120883
121101
|
label: String(record6.fileFields.name)
|
|
120884
121102
|
}
|
|
120885
|
-
})
|
|
121103
|
+
}),
|
|
121104
|
+
args.resolveVirtualPath
|
|
120886
121105
|
);
|
|
120887
121106
|
if (target !== null) record6.fileFields.collectionValueId = target;
|
|
120888
121107
|
}
|
|
@@ -120902,7 +121121,7 @@ function rootSlotValueIds(state) {
|
|
|
120902
121121
|
});
|
|
120903
121122
|
return values;
|
|
120904
121123
|
}
|
|
120905
|
-
function walkRootValuePath(path, state, registry, placements, rootValues, fail2) {
|
|
121124
|
+
function walkRootValuePath(path, state, registry, placements, rootValues, fail2, resolveVirtualPath) {
|
|
120906
121125
|
const segments = path.split(".");
|
|
120907
121126
|
const slotName = segments[1];
|
|
120908
121127
|
if (segments[0] !== "root" || slotName === void 0) {
|
|
@@ -120945,10 +121164,17 @@ function walkRootValuePath(path, state, registry, placements, rootValues, fail2)
|
|
|
120945
121164
|
}
|
|
120946
121165
|
const next = placements.childrenByParentValueId.get(cursor)?.get(segment)?.childValueId;
|
|
120947
121166
|
if (typeof next !== "string") {
|
|
120948
|
-
|
|
120949
|
-
|
|
121167
|
+
try {
|
|
121168
|
+
const resolved = resolveVirtualPath?.(slotValueId, segments.slice(2));
|
|
121169
|
+
if (resolved != null) return resolved;
|
|
121170
|
+
} catch (error) {
|
|
121171
|
+
fail2(
|
|
121172
|
+
`collectionValue path ${path} could not resolve its construction: ${error instanceof Error ? error.message : String(error)}`
|
|
121173
|
+
);
|
|
121174
|
+
return null;
|
|
121175
|
+
}
|
|
120950
121176
|
fail2(
|
|
120951
|
-
|
|
121177
|
+
`collectionValue path ${path} has no value at segment ${segment} after this push.`
|
|
120952
121178
|
);
|
|
120953
121179
|
return null;
|
|
120954
121180
|
}
|
|
@@ -121018,7 +121244,6 @@ var init_root_source = __esm({
|
|
|
121018
121244
|
"use strict";
|
|
121019
121245
|
init_src();
|
|
121020
121246
|
init_src2();
|
|
121021
|
-
init_instance_provenance();
|
|
121022
121247
|
init_value_sources();
|
|
121023
121248
|
init_source_format();
|
|
121024
121249
|
init_stored_value_placements();
|
|
@@ -122636,9 +122861,35 @@ function computeWorkspaceStatus(workspace, options) {
|
|
|
122636
122861
|
[...staticValues.records, ...memberDefaults.records, ...rootValues.records],
|
|
122637
122862
|
staticMemberValueIds
|
|
122638
122863
|
);
|
|
122864
|
+
let collectionBindings;
|
|
122865
|
+
const resolveVirtualPath = (rootId, segments) => {
|
|
122866
|
+
if (collectionBindings === void 0) {
|
|
122867
|
+
const candidate = /* @__PURE__ */ new Map();
|
|
122868
|
+
for (const [key, record6] of Object.entries(rootPathResolutionState)) {
|
|
122869
|
+
if (record6.file !== void 0 && isSchemaRecordKindV4(record6.recordKind) && !documentsByKey.has(key))
|
|
122870
|
+
continue;
|
|
122871
|
+
candidate.set(key, { ...record6, deleted: false });
|
|
122872
|
+
}
|
|
122873
|
+
for (const row of valueLowerRegistry.pendingValues.values()) {
|
|
122874
|
+
candidate.set(`value:${row.id}`, {
|
|
122875
|
+
recordKind: "value",
|
|
122876
|
+
recordId: row.id,
|
|
122877
|
+
contentHash: "",
|
|
122878
|
+
deleted: false,
|
|
122879
|
+
data: { id: row.id, ...encodeStoredValueRowFields(row) }
|
|
122880
|
+
});
|
|
122881
|
+
}
|
|
122882
|
+
const document = readPulledProjectDocumentV4(candidate);
|
|
122883
|
+
compilePulledProjectDocumentForEvaluationV4(document);
|
|
122884
|
+
collectionBindings = new CollectionBindingMaterializer(document);
|
|
122885
|
+
}
|
|
122886
|
+
const resolved = collectionBindings.resolvePath(rootId, segments);
|
|
122887
|
+
return resolved;
|
|
122888
|
+
};
|
|
122639
122889
|
const resolvedCollectionPaths = resolveRootPathCollectionValuesV4({
|
|
122640
122890
|
manifest,
|
|
122641
122891
|
state: rootPathResolutionState,
|
|
122892
|
+
resolveVirtualPath,
|
|
122642
122893
|
registry: valueLowerRegistry,
|
|
122643
122894
|
siteForMember: (memberId) => {
|
|
122644
122895
|
const span2 = sourceByKey.get(recordStateKey("member", memberId))?.span;
|
|
@@ -122667,6 +122918,7 @@ function computeWorkspaceStatus(workspace, options) {
|
|
|
122667
122918
|
const resolvedVariantFolderPaths = resolveRootPathVariantFolderCollectionValuesV4({
|
|
122668
122919
|
manifest,
|
|
122669
122920
|
state: rootPathResolutionState,
|
|
122921
|
+
resolveVirtualPath,
|
|
122670
122922
|
registry: valueLowerRegistry,
|
|
122671
122923
|
siteForFolder: (folderId) => {
|
|
122672
122924
|
const span2 = sourceByKey.get(
|
|
@@ -122753,7 +123005,7 @@ function computeWorkspaceStatus(workspace, options) {
|
|
|
122753
123005
|
}
|
|
122754
123006
|
}
|
|
122755
123007
|
}
|
|
122756
|
-
const rootRecords = rootValues.records;
|
|
123008
|
+
const rootRecords = [...rootValues.records];
|
|
122757
123009
|
const variantValues = lowerVariantValueSourcesV4(
|
|
122758
123010
|
loweringRecords,
|
|
122759
123011
|
manifest,
|
|
@@ -122769,8 +123021,71 @@ function computeWorkspaceStatus(workspace, options) {
|
|
|
122769
123021
|
records: supplementalRecords,
|
|
122770
123022
|
manifest,
|
|
122771
123023
|
state: rootPathResolutionState,
|
|
123024
|
+
resolveVirtualPath,
|
|
122772
123025
|
registry: valueLowerRegistry
|
|
122773
123026
|
});
|
|
123027
|
+
if (collectionBindings !== void 0) {
|
|
123028
|
+
const bindingSeeds = new Map(authoredValueSeeds);
|
|
123029
|
+
const rootRecordsById = new Map(
|
|
123030
|
+
rootRecords.filter((record6) => record6.recordKind === "value").map((record6) => [record6.recordId, record6])
|
|
123031
|
+
);
|
|
123032
|
+
const rootMembers = /* @__PURE__ */ new Map();
|
|
123033
|
+
for (const record6 of Object.values(rootPathResolutionState)) {
|
|
123034
|
+
if (record6.recordKind === "member" && isObjectRecord2(record6.data) && typeof record6.data.valueId === "string")
|
|
123035
|
+
rootMembers.set(record6.data.valueId, record6.recordId);
|
|
123036
|
+
}
|
|
123037
|
+
for (const row of collectionBindings.rows.values()) {
|
|
123038
|
+
if (rootPathResolutionState[`value:${row.id}`] === void 0) continue;
|
|
123039
|
+
const existing = rootRecordsById.get(row.id);
|
|
123040
|
+
if (existing !== void 0) Object.assign(existing.fileFields, row);
|
|
123041
|
+
else
|
|
123042
|
+
rootRecords.push({
|
|
123043
|
+
recordKind: "value",
|
|
123044
|
+
recordId: row.id,
|
|
123045
|
+
file: "Root.neo",
|
|
123046
|
+
line: 1,
|
|
123047
|
+
fileFields: { ...row }
|
|
123048
|
+
});
|
|
123049
|
+
}
|
|
123050
|
+
for (const [rootId, rowIds] of collectionBindings.pathRowsByRootId) {
|
|
123051
|
+
const memberId = rootMembers.get(rootId);
|
|
123052
|
+
const root = collectionBindings.rowForValue(rootId);
|
|
123053
|
+
if (memberId === void 0 || root === void 0) continue;
|
|
123054
|
+
const seed = authoredValueSeeds.get(memberId);
|
|
123055
|
+
const rows = new Map((seed?.values ?? []).map((row) => [row.id, row]));
|
|
123056
|
+
for (const id2 of rowIds) {
|
|
123057
|
+
if (id2 === rootId) continue;
|
|
123058
|
+
const row = collectionBindings.rowForValue(id2);
|
|
123059
|
+
const location3 = collectionBindings.locationForValue(id2);
|
|
123060
|
+
if (row === void 0 || !isLiteralValueContent(row) || location3 === void 0)
|
|
123061
|
+
throw new Error(`Collection binding row ${id2} has no member.`);
|
|
123062
|
+
const isNew = rootPathResolutionState[`value:${id2}`] === void 0;
|
|
123063
|
+
const classId = row.classId ?? (isMemberClassBase(location3.member) ? location3.member.classId : null);
|
|
123064
|
+
const authored = staticValueSeedRow(
|
|
123065
|
+
{
|
|
123066
|
+
...row,
|
|
123067
|
+
classId,
|
|
123068
|
+
...isNew && classId !== null ? {
|
|
123069
|
+
constructorArgs: row.constructorArgs ?? {},
|
|
123070
|
+
instanceConstructorId: row.instanceConstructorId ?? null
|
|
123071
|
+
} : {}
|
|
123072
|
+
},
|
|
123073
|
+
location3.memberId
|
|
123074
|
+
);
|
|
123075
|
+
rows.set(id2, authored);
|
|
123076
|
+
if (isNew) valueLowerRegistry.pendingValues.set(id2, authored);
|
|
123077
|
+
}
|
|
123078
|
+
bindingSeeds.set(memberId, {
|
|
123079
|
+
...seed,
|
|
123080
|
+
nodeType: "literal",
|
|
123081
|
+
valueId: rootId,
|
|
123082
|
+
value: root.value,
|
|
123083
|
+
classId: root.classId ?? null,
|
|
123084
|
+
values: [...rows.values()]
|
|
123085
|
+
});
|
|
123086
|
+
}
|
|
123087
|
+
authoredValueSeeds = bindingSeeds;
|
|
123088
|
+
}
|
|
122774
123089
|
const prospectiveState = overlayProspectiveSourceRecords(
|
|
122775
123090
|
loweringRecords,
|
|
122776
123091
|
documents,
|
|
@@ -124153,6 +124468,8 @@ var ANIMATION_DOCUMENT_RECORD_KINDS, ANIMATION_REPLAY_RECORD_KINDS, PROSPECTIVE_
|
|
|
124153
124468
|
var init_workspace_status_core = __esm({
|
|
124154
124469
|
"src/project-source/workspace-status-core.ts"() {
|
|
124155
124470
|
"use strict";
|
|
124471
|
+
init_members();
|
|
124472
|
+
init_collection_binding_materialization();
|
|
124156
124473
|
init_localizable_member_value_writes();
|
|
124157
124474
|
init_localized_instance_override_writes();
|
|
124158
124475
|
init_localization2();
|
|
@@ -126824,6 +127141,7 @@ function collectionValueObligations(manifest) {
|
|
|
126824
127141
|
for (const member of manifest.members) {
|
|
126825
127142
|
if (member.kind !== "lookup") continue;
|
|
126826
127143
|
if (typeof member.collectionValueId !== "string") continue;
|
|
127144
|
+
if (member.collectionValueId.startsWith("__pending__:root-path:")) continue;
|
|
126827
127145
|
obligations.push({
|
|
126828
127146
|
kind: "collectionValue",
|
|
126829
127147
|
site: {
|
|
@@ -127208,6 +127526,7 @@ function memberInitializerRequiresEvaluation(context, member, expression, source
|
|
|
127208
127526
|
function isSchemaMemberValueRead(context, expression, source) {
|
|
127209
127527
|
const path = memberPath2(annotatedValue(expression).expression);
|
|
127210
127528
|
if (path === null) return false;
|
|
127529
|
+
if (path.startsWith("root.")) return true;
|
|
127211
127530
|
const parts = path.split(".");
|
|
127212
127531
|
const name = parts.at(-1);
|
|
127213
127532
|
if (name === void 0) return false;
|
|
@@ -131452,10 +131771,9 @@ function classValueBody(context, member, value, visited, targetTyped, outerEnvir
|
|
|
131452
131771
|
`${key} = ${emitValue(context, emittedChildMember, childId, {
|
|
131453
131772
|
environment,
|
|
131454
131773
|
definitionSite: !context.symbolsByValueId.has(childId),
|
|
131455
|
-
//
|
|
131456
|
-
//
|
|
131457
|
-
|
|
131458
|
-
writeIdentity: false,
|
|
131774
|
+
// Existing slots recover identity from storage. A newly pinned virtual
|
|
131775
|
+
// slot must keep its derived pending identity through repeat lowering.
|
|
131776
|
+
writeIdentity: pendingVirtualValueIdentity(childId) !== null,
|
|
131459
131777
|
visited
|
|
131460
131778
|
})}`
|
|
131461
131779
|
);
|
|
@@ -133121,6 +133439,7 @@ var INFERRED_GENERIC_CLASS_PREFIX, MEMBER_KIND_DICTIONARY2, MEMBER_KIND_LIST2, M
|
|
|
133121
133439
|
var init_value_sources = __esm({
|
|
133122
133440
|
"src/project-source/value-sources.ts"() {
|
|
133123
133441
|
"use strict";
|
|
133442
|
+
init_member_value_id();
|
|
133124
133443
|
init_effective_value_comparison();
|
|
133125
133444
|
init_member_declared_type_info();
|
|
133126
133445
|
init_constructor_argument_ownership();
|
|
@@ -145703,7 +146022,7 @@ var init_registry2 = __esm({
|
|
|
145703
146022
|
"../packages/manifest/schema-contract/registry.mjs"() {
|
|
145704
146023
|
"use strict";
|
|
145705
146024
|
PROJECT_SCHEMA_CONTRACT = Object.freeze({
|
|
145706
|
-
cliVersion: "0.61.
|
|
146025
|
+
cliVersion: "0.61.3",
|
|
145707
146026
|
projectFileUploadBatchSize: 32,
|
|
145708
146027
|
documentRecords: {
|
|
145709
146028
|
member: {
|
|
@@ -154383,7 +154702,7 @@ There is no --keep-current: preserving current semantic state defines flatten.
|
|
|
154383
154702
|
async function main() {
|
|
154384
154703
|
const args = parseArgs(process.argv.slice(2));
|
|
154385
154704
|
if (args.command === "--version") {
|
|
154386
|
-
console.log("0.61.
|
|
154705
|
+
console.log("0.61.3");
|
|
154387
154706
|
return;
|
|
154388
154707
|
}
|
|
154389
154708
|
if (args.command === null || args.command === "help" || args.command === "--help" || args.command === "-h") {
|
package/package.json
CHANGED
|
@@ -110,7 +110,7 @@ wrappers.
|
|
|
110
110
|
The marker near the top of `SKILL.md` must exactly match the package version:
|
|
111
111
|
|
|
112
112
|
```html
|
|
113
|
-
<!-- reviewed-through-cli: 0.61.
|
|
113
|
+
<!-- reviewed-through-cli: 0.61.3 -->
|
|
114
114
|
```
|
|
115
115
|
|
|
116
116
|
The quoted version above is checked too, so this instruction cannot go stale
|
|
@@ -219,6 +219,10 @@ qualified static, or reached through a stable root path. For example,
|
|
|
219
219
|
`protected int Slots = FeatureFlags.StartInventorySize;` evaluates the current
|
|
220
220
|
static field or getter whenever a new instance is constructed; it is not baked
|
|
221
221
|
into a persisted literal during push.
|
|
222
|
+
Root paths such as `root.Save.World.Time.Year` remain executable even when
|
|
223
|
+
`World` and `Time` exist only through construction defaults. This also applies
|
|
224
|
+
inside `new() { Year = root.Save.World.Time.Year }`: the child field retains
|
|
225
|
+
its initializer and reads the root when the instance is constructed.
|
|
222
226
|
|
|
223
227
|
Declare overloadable constructors as members when each constructor body owns
|
|
224
228
|
its parameter scope:
|
|
@@ -130,7 +130,11 @@ the edit is not a target, and lookup/dialogue references must still satisfy
|
|
|
130
130
|
assignability, collection membership, multiplicity, and group constraints.
|
|
131
131
|
|
|
132
132
|
`collectionValue` references follow the same post-push resolution and
|
|
133
|
-
membership rules as member defaults.
|
|
133
|
+
membership rules as member defaults. Name the collection itself, for example
|
|
134
|
+
`Reference(root.Assets.Quests.Daily)`. A path may traverse construction defaults
|
|
135
|
+
and declarations created in the same push. Preparation materializes the target
|
|
136
|
+
collection and its required ancestor rows together, preserving the virtual
|
|
137
|
+
identities. No preliminary push or manual value ID is needed.
|
|
134
138
|
|
|
135
139
|
## Defaults and localization
|
|
136
140
|
|