@neocompose/cli 0.9.0 → 0.9.2
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 +14 -0
- package/dist/neo.mjs +137 -14
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,20 @@
|
|
|
7
7
|
- Document the final relation-only world layer-link contract and keep the
|
|
8
8
|
format-4 Hello World corpus free of the retired value-side binding field.
|
|
9
9
|
|
|
10
|
+
## [0.9.2] - 2026-07-24
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- Create idless list entries inside existing stored value graphs, including
|
|
15
|
+
nested class subtrees and references to files created by the same push.
|
|
16
|
+
|
|
17
|
+
## [0.9.1] - 2026-07-24
|
|
18
|
+
|
|
19
|
+
### Fixed
|
|
20
|
+
|
|
21
|
+
- Avoid synthesizing `partial: false` on member kinds that do not support the
|
|
22
|
+
field, so prospective animation validation accepts ordinary project members.
|
|
23
|
+
|
|
10
24
|
## [0.9.0] - 2026-07-23
|
|
11
25
|
|
|
12
26
|
### Added
|
package/dist/neo.mjs
CHANGED
|
@@ -1235,6 +1235,7 @@ function memberDefaultApplies(field, type) {
|
|
|
1235
1235
|
if (field === "collectionValueId") return type === 9;
|
|
1236
1236
|
if (field === "dialogueGroupId") return type === 18;
|
|
1237
1237
|
if (field === "templateId") return type === 11 || type === 12;
|
|
1238
|
+
if (field === "partial") return type === 7 || type === 21;
|
|
1238
1239
|
return true;
|
|
1239
1240
|
}
|
|
1240
1241
|
function omitRedundantDeclarationOrder(recordKind, value) {
|
|
@@ -42083,6 +42084,7 @@ function lowerStaticValueSourcesV4(state, analysis, manifest) {
|
|
|
42083
42084
|
);
|
|
42084
42085
|
bindings.push({
|
|
42085
42086
|
memberId,
|
|
42087
|
+
purpose: "stored",
|
|
42086
42088
|
ownerClassId: sourceIdentityId(sourceClass, "class", sourceClass.name),
|
|
42087
42089
|
initializer: declaration.initializer,
|
|
42088
42090
|
source: declaration.source,
|
|
@@ -42124,12 +42126,14 @@ function buildValueLowerContext(state, manifest, options = {}) {
|
|
|
42124
42126
|
),
|
|
42125
42127
|
staticValueIdsBySymbol: staticTargets,
|
|
42126
42128
|
dialogueTargetsBySymbol: dialogueTargetsBySymbol(options.analysis),
|
|
42127
|
-
projectFileIdsBySymbol: projectFileIdsBySymbol(state),
|
|
42129
|
+
projectFileIdsBySymbol: projectFileIdsBySymbol(state, options.analysis),
|
|
42128
42130
|
mainLocale: projectMainLocaleFromState(state),
|
|
42129
42131
|
valuePlacements: indexValuePlacements(state),
|
|
42130
42132
|
parsedInitializers,
|
|
42131
42133
|
reconstructed: /* @__PURE__ */ new Map(),
|
|
42132
42134
|
pendingValues: /* @__PURE__ */ new Map(),
|
|
42135
|
+
pendingLocalizedTexts: /* @__PURE__ */ new Map(),
|
|
42136
|
+
loweredMemberIdByValueId: /* @__PURE__ */ new Map(),
|
|
42133
42137
|
pendingBindingMembersByClassId: /* @__PURE__ */ new Map()
|
|
42134
42138
|
};
|
|
42135
42139
|
}
|
|
@@ -42166,6 +42170,7 @@ function lowerMemberDefaultSourcesV4(state, analysis, manifest) {
|
|
|
42166
42170
|
if (member === void 0) continue;
|
|
42167
42171
|
const binding = {
|
|
42168
42172
|
memberId,
|
|
42173
|
+
purpose: "memberDefault",
|
|
42169
42174
|
ownerClassId: sourceIdentityId(sourceClass, "class", sourceClass.name),
|
|
42170
42175
|
initializer: declaration.initializer,
|
|
42171
42176
|
source: declaration.source,
|
|
@@ -42379,13 +42384,75 @@ function lowerStoredBinding(context, binding, memberValueIds, seeds) {
|
|
|
42379
42384
|
const valueId = annotatedId ?? currentValueId ?? pendingValueId(binding, binding.label);
|
|
42380
42385
|
memberValueIds.set(binding.memberId, valueId);
|
|
42381
42386
|
if (currentValueId === valueId) {
|
|
42387
|
+
const existingReconstructedKeys = new Set(context.reconstructed.keys());
|
|
42388
|
+
const existingPendingValueIds = new Set(context.pendingValues.keys());
|
|
42389
|
+
const existingPendingLocalizedTextIds = new Set(
|
|
42390
|
+
context.pendingLocalizedTexts.keys()
|
|
42391
|
+
);
|
|
42392
|
+
const existingPendingBindingMemberIds = new Set(
|
|
42393
|
+
[...context.pendingBindingMembersByClassId.values()].map(
|
|
42394
|
+
(pending) => pending.id
|
|
42395
|
+
)
|
|
42396
|
+
);
|
|
42382
42397
|
lowerValueRow(context, member, expression, valueId, binding);
|
|
42398
|
+
const pendingRows = [...context.pendingValues.values()].filter(
|
|
42399
|
+
(row) => !existingPendingValueIds.has(row.id)
|
|
42400
|
+
);
|
|
42401
|
+
if (pendingRows.length > 0) {
|
|
42402
|
+
const root = reconstructedOrStateValue(context, valueId);
|
|
42403
|
+
const existingRows = [...context.reconstructed].filter(
|
|
42404
|
+
([key, record3]) => key !== `value:${valueId}` && !existingReconstructedKeys.has(key) && record3.recordKind === "value"
|
|
42405
|
+
).map(
|
|
42406
|
+
([, record3]) => staticValueSeedRow(
|
|
42407
|
+
record3.fileFields,
|
|
42408
|
+
context.loweredMemberIdByValueId.get(record3.recordId)
|
|
42409
|
+
)
|
|
42410
|
+
);
|
|
42411
|
+
const bindingMembers = [
|
|
42412
|
+
...context.pendingBindingMembersByClassId.values()
|
|
42413
|
+
].filter((pending) => !existingPendingBindingMemberIds.has(pending.id));
|
|
42414
|
+
const localizedTexts = [...context.pendingLocalizedTexts.values()].filter(
|
|
42415
|
+
(text) => !existingPendingLocalizedTextIds.has(text.id)
|
|
42416
|
+
);
|
|
42417
|
+
seeds.set(binding.memberId, {
|
|
42418
|
+
value: root.value,
|
|
42419
|
+
classId: stringOrNull(root.classId),
|
|
42420
|
+
valueId,
|
|
42421
|
+
values: [...existingRows, ...pendingRows],
|
|
42422
|
+
...bindingMembers.length === 0 ? {} : { bindingMembers },
|
|
42423
|
+
...localizedTexts.length === 0 ? {} : { localizedTexts }
|
|
42424
|
+
});
|
|
42425
|
+
}
|
|
42383
42426
|
return;
|
|
42384
42427
|
}
|
|
42385
42428
|
preserveReboundValue(context, currentValueId, valueId, binding);
|
|
42386
42429
|
const seed = lowerStaticSeed(context, member, expression, binding, valueId);
|
|
42387
42430
|
seeds.set(binding.memberId, { ...seed, valueId });
|
|
42388
42431
|
}
|
|
42432
|
+
function reconstructedOrStateValue(context, valueId) {
|
|
42433
|
+
return context.reconstructed.get(`value:${valueId}`)?.fileFields ?? valueBase(context, valueId);
|
|
42434
|
+
}
|
|
42435
|
+
function staticValueSeedRow(value, loweredMemberId) {
|
|
42436
|
+
const id2 = stringOrNull(value.id);
|
|
42437
|
+
if (id2 === null) throw new Error("Authored value row is missing id.");
|
|
42438
|
+
if (loweredMemberId === void 0) {
|
|
42439
|
+
throw new Error(`Authored value row ${id2} is missing memberId.`);
|
|
42440
|
+
}
|
|
42441
|
+
return {
|
|
42442
|
+
id: id2,
|
|
42443
|
+
memberId: loweredMemberId,
|
|
42444
|
+
value: value.value,
|
|
42445
|
+
classId: stringOrNull(value.classId),
|
|
42446
|
+
...typeof value.containerId === "string" ? { containerId: value.containerId } : {},
|
|
42447
|
+
...isObjectRecord2(value.genericBindings) ? {
|
|
42448
|
+
genericBindings: Object.fromEntries(
|
|
42449
|
+
Object.entries(value.genericBindings).filter(
|
|
42450
|
+
(entry) => typeof entry[1] === "string"
|
|
42451
|
+
)
|
|
42452
|
+
)
|
|
42453
|
+
} : {}
|
|
42454
|
+
};
|
|
42455
|
+
}
|
|
42389
42456
|
function preserveReboundValue(context, currentValueId, nextValueId, binding) {
|
|
42390
42457
|
if (currentValueId === null || currentValueId === nextValueId) return;
|
|
42391
42458
|
const base = valueBase(context, currentValueId);
|
|
@@ -42597,6 +42664,11 @@ function lowerSeedRow(context, member, sourceExpression, source, valueId, path,
|
|
|
42597
42664
|
valueId,
|
|
42598
42665
|
value: expression.value
|
|
42599
42666
|
});
|
|
42667
|
+
context.pendingLocalizedTexts.set(textId, {
|
|
42668
|
+
id: textId,
|
|
42669
|
+
valueId,
|
|
42670
|
+
value: expression.value
|
|
42671
|
+
});
|
|
42600
42672
|
value = textId;
|
|
42601
42673
|
} else {
|
|
42602
42674
|
const lowered = lowerValueBody(
|
|
@@ -42644,6 +42716,7 @@ function lowerSeedChild(context, member, expression, source, path, rows, localiz
|
|
|
42644
42716
|
return valueId;
|
|
42645
42717
|
}
|
|
42646
42718
|
function lowerValueRow(context, member, sourceExpression, expectedValueId, source, environment) {
|
|
42719
|
+
context.loweredMemberIdByValueId.set(expectedValueId, member.id);
|
|
42647
42720
|
const { expression, id: id2 } = annotatedValue(sourceExpression);
|
|
42648
42721
|
if (id2 !== null && id2 !== expectedValueId) {
|
|
42649
42722
|
throw new Error(
|
|
@@ -43134,7 +43207,7 @@ function lowerListValue(context, member, expression, base, source, inheritedEnvi
|
|
|
43134
43207
|
const environment = valueGenericEnvironment(base, inheritedEnvironment);
|
|
43135
43208
|
const existingIds = existingListItemIds(context, member, base);
|
|
43136
43209
|
const ids = [];
|
|
43137
|
-
for (const element of expression.elements) {
|
|
43210
|
+
for (const [index, element] of expression.elements.entries()) {
|
|
43138
43211
|
const symbolId = sourceValueSymbol(context, element);
|
|
43139
43212
|
if (symbolId !== null) {
|
|
43140
43213
|
if (!existingIds.has(symbolId)) {
|
|
@@ -43145,12 +43218,27 @@ function lowerListValue(context, member, expression, base, source, inheritedEnvi
|
|
|
43145
43218
|
ids.push(symbolId);
|
|
43146
43219
|
continue;
|
|
43147
43220
|
}
|
|
43148
|
-
const
|
|
43149
|
-
if (
|
|
43150
|
-
|
|
43151
|
-
|
|
43221
|
+
const annotatedItemId = annotatedValue(element).id;
|
|
43222
|
+
if (annotatedItemId === null) {
|
|
43223
|
+
if (source.purpose === "memberDefault") {
|
|
43224
|
+
throw new Error(
|
|
43225
|
+
`List ${member.name} contains an idless default item. New default list item creation is not implemented by this slice.`
|
|
43226
|
+
);
|
|
43227
|
+
}
|
|
43228
|
+
ids.push(
|
|
43229
|
+
lowerPendingListItem(
|
|
43230
|
+
context,
|
|
43231
|
+
entryMember,
|
|
43232
|
+
element,
|
|
43233
|
+
source,
|
|
43234
|
+
`${String(base.id)}[${index}]`,
|
|
43235
|
+
member.listKind === "unordered" ? stringOrNull(base.id) : void 0,
|
|
43236
|
+
environment
|
|
43237
|
+
)
|
|
43152
43238
|
);
|
|
43239
|
+
continue;
|
|
43153
43240
|
}
|
|
43241
|
+
const itemId = annotatedItemId;
|
|
43154
43242
|
const child = valueBase(context, itemId);
|
|
43155
43243
|
if (member.listKind === "unordered" && child.containerId !== base.id) {
|
|
43156
43244
|
throw new Error(
|
|
@@ -43166,6 +43254,25 @@ function lowerListValue(context, member, expression, base, source, inheritedEnvi
|
|
|
43166
43254
|
value: member.listKind === "unordered" ? [] : ids
|
|
43167
43255
|
};
|
|
43168
43256
|
}
|
|
43257
|
+
function lowerPendingListItem(context, member, expression, source, path, containerId, environment) {
|
|
43258
|
+
const rows = /* @__PURE__ */ new Map();
|
|
43259
|
+
const localizedTexts = /* @__PURE__ */ new Map();
|
|
43260
|
+
const valueId = lowerSeedChild(
|
|
43261
|
+
context,
|
|
43262
|
+
member,
|
|
43263
|
+
expression,
|
|
43264
|
+
source,
|
|
43265
|
+
path,
|
|
43266
|
+
rows,
|
|
43267
|
+
localizedTexts,
|
|
43268
|
+
containerId ?? void 0,
|
|
43269
|
+
environment
|
|
43270
|
+
);
|
|
43271
|
+
for (const text of localizedTexts.values()) {
|
|
43272
|
+
context.pendingLocalizedTexts.set(text.id, text);
|
|
43273
|
+
}
|
|
43274
|
+
return valueId;
|
|
43275
|
+
}
|
|
43169
43276
|
function existingListItemIds(context, member, base) {
|
|
43170
43277
|
if (member.listKind === "unordered") {
|
|
43171
43278
|
const containerId = stringOrNull(base.id);
|
|
@@ -43699,6 +43806,7 @@ function indexSourceStaticTargets(targets, state, analysis, manifest, parsedInit
|
|
|
43699
43806
|
annotatedValue(expression).id ?? current ?? pendingValueId(
|
|
43700
43807
|
{
|
|
43701
43808
|
memberId,
|
|
43809
|
+
purpose: "stored",
|
|
43702
43810
|
initializer: declaration.initializer,
|
|
43703
43811
|
source: declaration.source,
|
|
43704
43812
|
label: symbol
|
|
@@ -43901,7 +44009,7 @@ function staticValueIdsBySymbol(state, manifest) {
|
|
|
43901
44009
|
}
|
|
43902
44010
|
return result;
|
|
43903
44011
|
}
|
|
43904
|
-
function projectFileIdsBySymbol(state) {
|
|
44012
|
+
function projectFileIdsBySymbol(state, analysis) {
|
|
43905
44013
|
const files = Object.values(state).flatMap((record3) => {
|
|
43906
44014
|
if (record3.recordKind !== "project-file" || !isObjectRecord2(record3.data))
|
|
43907
44015
|
return [];
|
|
@@ -43910,12 +44018,21 @@ function projectFileIdsBySymbol(state) {
|
|
|
43910
44018
|
return kind === "image" || kind === "audio" ? [{ stableId: record3.recordId, path: name, kind }] : [];
|
|
43911
44019
|
});
|
|
43912
44020
|
const symbols = assignDeterministicFileSymbols(files);
|
|
43913
|
-
|
|
44021
|
+
const result = new Map(
|
|
43914
44022
|
files.map((file) => [
|
|
43915
44023
|
`${file.kind === "image" ? "Images" : "AudioClips"}.${symbols.get(file.stableId)}`,
|
|
43916
44024
|
file.stableId
|
|
43917
44025
|
])
|
|
43918
44026
|
);
|
|
44027
|
+
if (analysis !== void 0) {
|
|
44028
|
+
for (const declaration of projectFileDeclarationsV4(analysis)) {
|
|
44029
|
+
result.set(
|
|
44030
|
+
`${declaration.kind === "image" ? "Images" : "AudioClips"}.${declaration.symbol}`,
|
|
44031
|
+
declaration.recordId
|
|
44032
|
+
);
|
|
44033
|
+
}
|
|
44034
|
+
}
|
|
44035
|
+
return result;
|
|
43919
44036
|
}
|
|
43920
44037
|
function projectMainLocaleFromState(state) {
|
|
43921
44038
|
const config = Object.values(state).find(
|
|
@@ -44662,17 +44779,18 @@ ${declarations.join("\n\n")}
|
|
|
44662
44779
|
}
|
|
44663
44780
|
function lowerProjectRootSourceV4(state, analysis, manifest) {
|
|
44664
44781
|
const validated = validateProjectRootEnvelopeV4(state, analysis);
|
|
44665
|
-
if (validated === null)
|
|
44782
|
+
if (validated === null) {
|
|
44783
|
+
return { records: [], memberValueIds: /* @__PURE__ */ new Map(), seeds: /* @__PURE__ */ new Map() };
|
|
44784
|
+
}
|
|
44666
44785
|
const { expectedIds, global, slots } = validated;
|
|
44667
44786
|
const bindings = PROJECT_ROOT_SOURCE_SLOTS.map((expected, index) => ({
|
|
44668
44787
|
memberId: expectedIds[index],
|
|
44788
|
+
purpose: "stored",
|
|
44669
44789
|
initializer: slots[index].initializer,
|
|
44670
44790
|
source: global.source,
|
|
44671
44791
|
label: `root.${expected.name}`
|
|
44672
44792
|
}));
|
|
44673
|
-
return
|
|
44674
|
-
...lowerStoredValueBindingsV4(state, manifest, bindings, { analysis }).records
|
|
44675
|
-
];
|
|
44793
|
+
return lowerStoredValueBindingsV4(state, manifest, bindings, { analysis });
|
|
44676
44794
|
}
|
|
44677
44795
|
function validateProjectRootEnvelopeV4(state, analysis) {
|
|
44678
44796
|
const project = Object.values(state).find(
|
|
@@ -48184,7 +48302,10 @@ function computeWorkspaceStatus(workspace, options = {}) {
|
|
|
48184
48302
|
}
|
|
48185
48303
|
manifest = lowerProjectSchemaV4(baseManifest, analysis, {
|
|
48186
48304
|
staticValueIdsBySymbol: staticValueIdsBySymbol2(workspace.state.records),
|
|
48187
|
-
projectFileIdsBySymbol: projectFileIdsBySymbol(
|
|
48305
|
+
projectFileIdsBySymbol: projectFileIdsBySymbol(
|
|
48306
|
+
workspace.state.records,
|
|
48307
|
+
analysis
|
|
48308
|
+
),
|
|
48188
48309
|
rowBackedDefaultMemberIds: rowBackedDefaultMemberIdsV4(
|
|
48189
48310
|
workspace.state.records
|
|
48190
48311
|
)
|
|
@@ -48270,11 +48391,13 @@ function computeWorkspaceStatus(workspace, options = {}) {
|
|
|
48270
48391
|
);
|
|
48271
48392
|
staticValueSeeds = new Map([...staticValues.seeds, ...memberDefaults.seeds]);
|
|
48272
48393
|
staticMemberValueIds = staticValues.memberValueIds;
|
|
48273
|
-
const
|
|
48394
|
+
const rootValues = lowerProjectRootSourceV4(
|
|
48274
48395
|
workspace.state.records,
|
|
48275
48396
|
projectAnalysisV4,
|
|
48276
48397
|
manifest
|
|
48277
48398
|
);
|
|
48399
|
+
staticValueSeeds = new Map([...staticValueSeeds, ...rootValues.seeds]);
|
|
48400
|
+
const rootRecords = rootValues.records;
|
|
48278
48401
|
const supplementalRecords = lowerSupplementalProjectSourcesV4(
|
|
48279
48402
|
workspace.root,
|
|
48280
48403
|
workspace.state.records,
|