@wairon/cli 5.1.1-dev.34 → 5.1.1-dev.35
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/index.js +203 -28
- package/dist/cli/index.js.map +1 -1
- package/dist/index.js +200 -25
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1113,7 +1113,7 @@ var init_defaults = __esm({
|
|
|
1113
1113
|
copilot: ".github/prompts",
|
|
1114
1114
|
codex: ".codex/agents"
|
|
1115
1115
|
};
|
|
1116
|
-
WAIRON_VERSION = "5.1.1-dev.
|
|
1116
|
+
WAIRON_VERSION = "5.1.1-dev.35";
|
|
1117
1117
|
GITHUB_REPO = "SYW-Apps/Waffle-AIron";
|
|
1118
1118
|
ARCHITECT_AGENT_ID = "agent-architect";
|
|
1119
1119
|
ARCHITECT_TEMPLATE_ID = "architect";
|
|
@@ -18345,10 +18345,30 @@ function identityKeyOf(field, item) {
|
|
|
18345
18345
|
return str(o.description);
|
|
18346
18346
|
case "databases":
|
|
18347
18347
|
return str(o.id) ?? str(o.name);
|
|
18348
|
+
// A flow step's own arrays, addressed by the thing the author named them
|
|
18349
|
+
// for. Their `step` is a RELOCATABLE number, never an identity — a switch
|
|
18350
|
+
// case is the value it matches and a catch clause is the error it catches,
|
|
18351
|
+
// and both survive the renumbering that moves their target. (A parallel
|
|
18352
|
+
// arm falls to the default: named, it merges by name; unnamed, it carries
|
|
18353
|
+
// no identity at all and the list replaces wholesale, which is the same
|
|
18354
|
+
// rule everywhere else.)
|
|
18355
|
+
case "cases":
|
|
18356
|
+
return str(o.value);
|
|
18357
|
+
case "catches":
|
|
18358
|
+
return str(o.error);
|
|
18348
18359
|
default:
|
|
18349
18360
|
return str(o.name) ?? str(o.id);
|
|
18350
18361
|
}
|
|
18351
18362
|
}
|
|
18363
|
+
function stepFieldsFor(type) {
|
|
18364
|
+
const own = STEP_TYPE_FIELDS[type] ?? [];
|
|
18365
|
+
const allowed = /* @__PURE__ */ new Set([...STEP_COMMON_FIELDS, ...own]);
|
|
18366
|
+
for (const field of own) {
|
|
18367
|
+
const twin = STEP_LABEL_TWINS[field];
|
|
18368
|
+
if (twin) allowed.add(twin);
|
|
18369
|
+
}
|
|
18370
|
+
return allowed;
|
|
18371
|
+
}
|
|
18352
18372
|
function reportIdentityOf(field, item) {
|
|
18353
18373
|
if (item !== null && typeof item === "object") {
|
|
18354
18374
|
const step = item.stepNumber;
|
|
@@ -18624,7 +18644,7 @@ function findLegacySpecFiles() {
|
|
|
18624
18644
|
function updateSpec(kind, id, delta, hooks) {
|
|
18625
18645
|
return current().updateSpec(kind, id, delta, hooks);
|
|
18626
18646
|
}
|
|
18627
|
-
var fs11, path16, NO_ROOT_SUBSYSTEMS, SIGNATURE_TTL_MS, SpecWorkspace, workspaces;
|
|
18647
|
+
var fs11, path16, NO_ROOT_SUBSYSTEMS, SIGNATURE_TTL_MS, STEP_TYPE_FIELDS, STEP_COMMON_FIELDS, STEP_LABEL_TWINS, SpecWorkspace, workspaces;
|
|
18628
18648
|
var init_specs2 = __esm({
|
|
18629
18649
|
"src/core/specs.ts"() {
|
|
18630
18650
|
"use strict";
|
|
@@ -18642,6 +18662,36 @@ var init_specs2 = __esm({
|
|
|
18642
18662
|
init_diagram();
|
|
18643
18663
|
NO_ROOT_SUBSYSTEMS = /* @__PURE__ */ new Set();
|
|
18644
18664
|
SIGNATURE_TTL_MS = 2e3;
|
|
18665
|
+
STEP_TYPE_FIELDS = {
|
|
18666
|
+
local: [],
|
|
18667
|
+
call: ["targetComponent", "targetMethod", "auth", "detach"],
|
|
18668
|
+
register: ["targetComponent", "targetMethod"],
|
|
18669
|
+
dispatch: ["targetComponent", "capability", "auth", "detach"],
|
|
18670
|
+
branch: ["condition", "onTrueStep", "onFalseStep"],
|
|
18671
|
+
switch: ["on", "cases", "defaultStep"],
|
|
18672
|
+
loop: ["loopKind", "over", "condition", "endStep"],
|
|
18673
|
+
try: ["endStep", "catches", "finallyStep"],
|
|
18674
|
+
parallel: ["endStep", "branches"],
|
|
18675
|
+
jump: ["toStep"],
|
|
18676
|
+
return: ["outcome"],
|
|
18677
|
+
throw: ["error"]
|
|
18678
|
+
};
|
|
18679
|
+
STEP_COMMON_FIELDS = [
|
|
18680
|
+
"stepNumber",
|
|
18681
|
+
"label",
|
|
18682
|
+
"description",
|
|
18683
|
+
"type",
|
|
18684
|
+
"assertsGuarantees",
|
|
18685
|
+
"assertsInvariants"
|
|
18686
|
+
];
|
|
18687
|
+
STEP_LABEL_TWINS = {
|
|
18688
|
+
onTrueStep: "onTrueLabel",
|
|
18689
|
+
onFalseStep: "onFalseLabel",
|
|
18690
|
+
defaultStep: "defaultLabel",
|
|
18691
|
+
endStep: "endLabel",
|
|
18692
|
+
finallyStep: "finallyLabel",
|
|
18693
|
+
toStep: "toLabel"
|
|
18694
|
+
};
|
|
18645
18695
|
SpecWorkspace = class {
|
|
18646
18696
|
constructor(rootDir) {
|
|
18647
18697
|
this.cachedIndex = null;
|
|
@@ -19879,9 +19929,39 @@ var init_specs2 = __esm({
|
|
|
19879
19929
|
// Granular delta updates (sdd_update_spec)
|
|
19880
19930
|
// -------------------------------------------------------------------------
|
|
19881
19931
|
/**
|
|
19882
|
-
*
|
|
19883
|
-
*
|
|
19884
|
-
*
|
|
19932
|
+
* Apply a delta to one stored spec, in this ORDER — the order is the contract,
|
|
19933
|
+
* because every stage below can see what the stage above left:
|
|
19934
|
+
*
|
|
19935
|
+
* 1. LOAD the stored spec for the addressed kind and id; a spec that does
|
|
19936
|
+
* not exist refuses, and a mis-selected `system` kind refuses by name.
|
|
19937
|
+
* 2. REFUSE unknown delta keys, whole. A key the level's schema does not
|
|
19938
|
+
* know is dropped on write, so the edit would report a success it never
|
|
19939
|
+
* performed.
|
|
19940
|
+
* 3. QUALIFY the delta's id-bearing references against the spec's namespace,
|
|
19941
|
+
* BEFORE the merge — post-merge a bare id is ambiguous.
|
|
19942
|
+
* 4. MERGE. Identity-keyed arrays upsert element by element and honour their
|
|
19943
|
+
* delete markers, at every depth. Narrative step deltas apply in ASCENDING
|
|
19944
|
+
* stepNumber order, each against the numbering the earlier entries of the
|
|
19945
|
+
* same delta left behind — delete step 3 and step 7 becomes step 6, so a
|
|
19946
|
+
* second delete written as 7 addresses what used to be step 8. That is why
|
|
19947
|
+
* a delete may restate the step's `label` or `description` as a guard, and
|
|
19948
|
+
* why labels are the reliable way to name a jump target. Inserts and
|
|
19949
|
+
* deletes relocate every jump field in the same narrative around them; a
|
|
19950
|
+
* step whose `type` changes is REBUILT for its new type, keeping its
|
|
19951
|
+
* description and label.
|
|
19952
|
+
* 5. UNSET the fields the delta names, at the level each `unset` sits in.
|
|
19953
|
+
* 6. RESOLVE symbolic `*Label` references against the MERGED numbering — after
|
|
19954
|
+
* the merge, so a delta may anchor on a label that only pre-existing steps
|
|
19955
|
+
* carry, and a label in the delta retargets the stored numeric jump it
|
|
19956
|
+
* twins. An unresolved reference aborts the whole update.
|
|
19957
|
+
* 7. COMPARE with what is stored, both read through the level's canonical
|
|
19958
|
+
* schema. Equal means nothing is written and `written` is false.
|
|
19959
|
+
* 8. GATE the merged spec through the caller's hook, then SAVE.
|
|
19960
|
+
*
|
|
19961
|
+
* Returns the change report, whose `notices` carry the non-fatal effects (an
|
|
19962
|
+
* insert whose position was a jump target, so the relocated jumps now bypass
|
|
19963
|
+
* the inserted step; the fields a retype dropped) — empty when the merge had
|
|
19964
|
+
* nothing to say.
|
|
19885
19965
|
*/
|
|
19886
19966
|
updateSpec(kind, id, delta, hooks) {
|
|
19887
19967
|
const notices = [];
|
|
@@ -19995,14 +20075,113 @@ var init_specs2 = __esm({
|
|
|
19995
20075
|
);
|
|
19996
20076
|
}
|
|
19997
20077
|
};
|
|
19998
|
-
const
|
|
20078
|
+
const NO_NESTED_MERGE = /* @__PURE__ */ new Set(["ext", "narrative", "unset"]);
|
|
20079
|
+
const mergeElement = (existing, deltaItem) => {
|
|
20080
|
+
const out = { ...existing, ...deltaItem };
|
|
20081
|
+
if (!existing || typeof existing !== "object" || !deltaItem || typeof deltaItem !== "object") return out;
|
|
20082
|
+
for (const [key, value] of Object.entries(deltaItem)) {
|
|
20083
|
+
if (NO_NESTED_MERGE.has(key) || !Array.isArray(value) || value.length === 0) continue;
|
|
20084
|
+
const before = existing[key];
|
|
20085
|
+
if (before !== void 0 && !Array.isArray(before)) continue;
|
|
20086
|
+
const stored = Array.isArray(before) ? before : [];
|
|
20087
|
+
if (!isIdentifiedArray(key, stored, value)) continue;
|
|
20088
|
+
out[key] = mergeIdentifiedArray(key, stored, value);
|
|
20089
|
+
}
|
|
20090
|
+
return out;
|
|
20091
|
+
};
|
|
20092
|
+
const retargetByLabel = (merged, deltaStep) => {
|
|
20093
|
+
const out = { ...merged };
|
|
20094
|
+
for (const [stepField, labelField] of Object.entries(STEP_LABEL_TWINS)) {
|
|
20095
|
+
if (deltaStep?.[labelField] !== void 0 && deltaStep?.[stepField] === void 0) delete out[stepField];
|
|
20096
|
+
}
|
|
20097
|
+
for (const key of ["cases", "catches"]) {
|
|
20098
|
+
const deltaEntries = deltaStep?.[key];
|
|
20099
|
+
if (!Array.isArray(deltaEntries) || !Array.isArray(out[key])) continue;
|
|
20100
|
+
const retargeted = new Set(
|
|
20101
|
+
deltaEntries.filter((e) => e?.label !== void 0 && e?.step === void 0).map((e) => identityKeyOf(key, e)).filter((k) => k !== null)
|
|
20102
|
+
);
|
|
20103
|
+
if (!retargeted.size) continue;
|
|
20104
|
+
out[key] = out[key].map((e) => {
|
|
20105
|
+
const k = identityKeyOf(key, e);
|
|
20106
|
+
if (k === null || !retargeted.has(k)) return e;
|
|
20107
|
+
const { step, ...rest } = e;
|
|
20108
|
+
return rest;
|
|
20109
|
+
});
|
|
20110
|
+
}
|
|
20111
|
+
return out;
|
|
20112
|
+
};
|
|
20113
|
+
const rebuildOnRetype = (stored, deltaStep, merged, methodName) => {
|
|
20114
|
+
const newType = merged?.type;
|
|
20115
|
+
if (typeof newType !== "string" || stored?.type === newType) return merged;
|
|
20116
|
+
if (!Object.prototype.hasOwnProperty.call(STEP_TYPE_FIELDS, newType)) return merged;
|
|
20117
|
+
const allowed = stepFieldsFor(newType);
|
|
20118
|
+
const stated = Object.keys(deltaStep).filter(
|
|
20119
|
+
(k) => k !== "type" && deltaStep[k] !== void 0 && !allowed.has(k)
|
|
20120
|
+
);
|
|
20121
|
+
if (stated.length) {
|
|
20122
|
+
throw new Error(
|
|
20123
|
+
`Refusing to retype narrative step ${stored.stepNumber} of "${methodName}" from "${stored.type}" to "${newType}": the same delta sets ${stated.map((f) => `"${f}"`).join(", ")}, which a ${newType} step cannot carry. Drop those keys, or retype to a step type that carries them.`
|
|
20124
|
+
);
|
|
20125
|
+
}
|
|
20126
|
+
const out = {};
|
|
20127
|
+
const dropped = [];
|
|
20128
|
+
for (const [key, value] of Object.entries(merged)) {
|
|
20129
|
+
if (allowed.has(key)) out[key] = value;
|
|
20130
|
+
else dropped.push(key);
|
|
20131
|
+
}
|
|
20132
|
+
if (dropped.length) {
|
|
20133
|
+
notices.push(
|
|
20134
|
+
`Narrative step ${stored.stepNumber} of "${methodName}" was retyped ${stored.type} -> ${newType}: ${dropped.join(", ")} dropped \u2014 a ${newType} step cannot carry ${dropped.length === 1 ? "it" : "them"}. Its description and label are kept.`
|
|
20135
|
+
);
|
|
20136
|
+
}
|
|
20137
|
+
return out;
|
|
20138
|
+
};
|
|
20139
|
+
const mergeNarrative = (methodName, existingSteps, deltaSteps) => {
|
|
19999
20140
|
let steps = [...existingSteps];
|
|
20000
20141
|
const sortedDeltas = [...deltaSteps].sort((a, b) => a.stepNumber - b.stepNumber);
|
|
20001
20142
|
for (const deltaStep of sortedDeltas) {
|
|
20002
20143
|
const stepNum = deltaStep.stepNumber;
|
|
20144
|
+
if (typeof stepNum !== "number") {
|
|
20145
|
+
throw new Error(
|
|
20146
|
+
`Refusing to update the narrative of "${methodName}": a step delta must carry the "stepNumber" it addresses, got ${JSON.stringify(stepNum ?? null)}.`
|
|
20147
|
+
);
|
|
20148
|
+
}
|
|
20149
|
+
if ("remove" in deltaStep && typeof deltaStep.remove !== "boolean") {
|
|
20150
|
+
throw new Error(
|
|
20151
|
+
`Refusing to update narrative step ${stepNum} of "${methodName}": "remove" must be the boolean true, got ${JSON.stringify(deltaStep.remove)}. A non-boolean is ignored, which would leave the step in place while reporting success.`
|
|
20152
|
+
);
|
|
20153
|
+
}
|
|
20154
|
+
if ("action" in deltaStep && deltaStep.action !== "insert" && deltaStep.action !== "delete") {
|
|
20155
|
+
throw new Error(
|
|
20156
|
+
`Refusing to update narrative step ${stepNum} of "${methodName}": unknown action ${JSON.stringify(deltaStep.action)} \u2014 expected "insert" or "delete", or no action at all to edit the step in place. An unknown verb is ignored, which would report success for an edit never made.`
|
|
20157
|
+
);
|
|
20158
|
+
}
|
|
20159
|
+
if ("captureJumps" in deltaStep && deltaStep.action !== "insert") {
|
|
20160
|
+
throw new Error(
|
|
20161
|
+
`Refusing to update narrative step ${stepNum} of "${methodName}": "captureJumps" only means anything on an inserted step \u2014 it decides whether jumps aimed at that number follow the shifted original or land on the new step. On any other delta it is ignored.`
|
|
20162
|
+
);
|
|
20163
|
+
}
|
|
20003
20164
|
if (deltaStep.action === "delete" || deltaStep.remove === true) {
|
|
20004
20165
|
const idx = steps.findIndex((s) => s.stepNumber === stepNum);
|
|
20005
20166
|
if (idx !== -1) {
|
|
20167
|
+
const victim = steps[idx];
|
|
20168
|
+
for (const field of ["label", "description"]) {
|
|
20169
|
+
if (deltaStep[field] === void 0) continue;
|
|
20170
|
+
if (victim[field] !== deltaStep[field]) {
|
|
20171
|
+
throw new Error(
|
|
20172
|
+
`Refusing to delete narrative step ${stepNum}: the delta states ${field} ${JSON.stringify(deltaStep[field])}, but step ${stepNum} holds ${JSON.stringify(victim[field] ?? null)}. Step deltas apply in ascending order against the numbering earlier entries of the same delta left behind, so a later delete can address a step that has already moved.`
|
|
20173
|
+
);
|
|
20174
|
+
}
|
|
20175
|
+
}
|
|
20176
|
+
if (typeof victim.endStep === "number") {
|
|
20177
|
+
const body = steps.filter((s) => s.stepNumber > stepNum && s.stepNumber <= victim.endStep);
|
|
20178
|
+
if (body.length) {
|
|
20179
|
+
const span = body.length === 1 ? `step ${body[0].stepNumber}` : `steps ${body[0].stepNumber}-${body[body.length - 1].stepNumber}`;
|
|
20180
|
+
throw new Error(
|
|
20181
|
+
`Cannot delete narrative step ${stepNum}: it is a ${victim.type} header and ${span} ${body.length === 1 ? "is" : "are"} still its body. Deleting it would leave them in place with no ${victim.type} around them \u2014 a change of meaning nothing later reports. Dissolve the region first: retype step ${stepNum} to a type that carries no region (the region fields are dropped and reported), then delete it.`
|
|
20182
|
+
);
|
|
20183
|
+
}
|
|
20184
|
+
}
|
|
20006
20185
|
const referrers = steps.filter((s) => s.stepNumber !== stepNum).map((s) => ({ n: s.stepNumber, refs: jumpRefsTo(s, stepNum) })).filter((r) => r.refs.length > 0);
|
|
20007
20186
|
if (referrers.length) {
|
|
20008
20187
|
throw new Error(
|
|
@@ -20015,6 +20194,11 @@ var init_specs2 = __esm({
|
|
|
20015
20194
|
stepNum,
|
|
20016
20195
|
-1
|
|
20017
20196
|
));
|
|
20197
|
+
} else {
|
|
20198
|
+
const present = steps.length ? ` \u2014 it has steps ${steps[0].stepNumber}-${steps[steps.length - 1].stepNumber}` : " \u2014 it has no steps";
|
|
20199
|
+
throw new Error(
|
|
20200
|
+
`Refusing to delete narrative step ${stepNum}: this narrative has no step ${stepNum}${present}. Step deltas apply in ascending order against the numbering earlier entries of the same delta left behind, so a later delete can address a step that has already moved.`
|
|
20201
|
+
);
|
|
20018
20202
|
}
|
|
20019
20203
|
} else if (deltaStep.action === "insert") {
|
|
20020
20204
|
const capture = deltaStep.captureJumps === true;
|
|
@@ -20038,10 +20222,9 @@ var init_specs2 = __esm({
|
|
|
20038
20222
|
const idx = steps.findIndex((s) => s.stepNumber === stepNum);
|
|
20039
20223
|
if (idx !== -1) {
|
|
20040
20224
|
const { action, remove, ...cleanStep } = deltaStep;
|
|
20041
|
-
steps[idx]
|
|
20042
|
-
|
|
20043
|
-
|
|
20044
|
-
}, deltaStep);
|
|
20225
|
+
const stored = steps[idx];
|
|
20226
|
+
const merged = withUnset(retargetByLabel(mergeElement(stored, cleanStep), cleanStep), deltaStep);
|
|
20227
|
+
steps[idx] = rebuildOnRetype(stored, cleanStep, merged, methodName);
|
|
20045
20228
|
} else {
|
|
20046
20229
|
const { action, remove, ...cleanStep } = deltaStep;
|
|
20047
20230
|
steps.push(withUnset(cleanStep, deltaStep));
|
|
@@ -20072,12 +20255,11 @@ var init_specs2 = __esm({
|
|
|
20072
20255
|
const existingMethod = merged[idx];
|
|
20073
20256
|
let narrative = existingMethod.narrative ? [...existingMethod.narrative] : [];
|
|
20074
20257
|
if (Array.isArray(deltaMethod.narrative)) {
|
|
20075
|
-
narrative = deltaMethod.narrative.length === 0 ? [] : mergeNarrative(narrative, deltaMethod.narrative);
|
|
20258
|
+
narrative = deltaMethod.narrative.length === 0 ? [] : mergeNarrative(String(deltaMethod.name), narrative, deltaMethod.narrative);
|
|
20076
20259
|
}
|
|
20077
20260
|
const { narrative: _, ...cleanMethod } = deltaMethod;
|
|
20078
20261
|
merged[idx] = withUnset({
|
|
20079
|
-
...existingMethod,
|
|
20080
|
-
...cleanMethod,
|
|
20262
|
+
...mergeElement(existingMethod, cleanMethod),
|
|
20081
20263
|
...deltaMethod.ext !== void 0 ? { ext: mergeExt(existingMethod.ext, deltaMethod.ext) } : {},
|
|
20082
20264
|
narrative
|
|
20083
20265
|
}, deltaMethod);
|
|
@@ -20099,12 +20281,8 @@ var init_specs2 = __esm({
|
|
|
20099
20281
|
merged.splice(idx, 1);
|
|
20100
20282
|
} else {
|
|
20101
20283
|
merged[idx] = withUnset({
|
|
20102
|
-
...merged[idx],
|
|
20103
|
-
...deltaItem,
|
|
20104
|
-
...deltaItem.ext !== void 0 ? { ext: mergeExt(merged[idx].ext, deltaItem.ext) } : {},
|
|
20105
|
-
// An interface method's findings upsert and delete by code, like
|
|
20106
|
-
// lint.allow; an empty list still clears them outright.
|
|
20107
|
-
...Array.isArray(deltaItem.findings) && deltaItem.findings.length > 0 ? { findings: mergeIdentifiedArray("findings", merged[idx].findings ?? [], deltaItem.findings) } : {}
|
|
20284
|
+
...mergeElement(merged[idx], deltaItem),
|
|
20285
|
+
...deltaItem.ext !== void 0 ? { ext: mergeExt(merged[idx].ext, deltaItem.ext) } : {}
|
|
20108
20286
|
}, deltaItem);
|
|
20109
20287
|
}
|
|
20110
20288
|
} else {
|
|
@@ -20123,7 +20301,7 @@ var init_specs2 = __esm({
|
|
|
20123
20301
|
if (deltaItem.remove === true || deltaItem.action === "delete") {
|
|
20124
20302
|
merged.splice(idx, 1);
|
|
20125
20303
|
} else {
|
|
20126
|
-
merged[idx] = withUnset(
|
|
20304
|
+
merged[idx] = withUnset(mergeElement(merged[idx], deltaItem), deltaItem);
|
|
20127
20305
|
}
|
|
20128
20306
|
} else {
|
|
20129
20307
|
assertUnmatchedIsAnAddition(deltaItem, keyOf(deltaItem), merged.map(keyOf), "entry");
|
|
@@ -20142,10 +20320,7 @@ var init_specs2 = __esm({
|
|
|
20142
20320
|
if (deltaItem.remove === true || deltaItem.action === "delete") {
|
|
20143
20321
|
merged.splice(idx, 1);
|
|
20144
20322
|
} else {
|
|
20145
|
-
merged[idx] = withUnset(
|
|
20146
|
-
...merged[idx],
|
|
20147
|
-
...deltaItem
|
|
20148
|
-
}, deltaItem);
|
|
20323
|
+
merged[idx] = withUnset(mergeElement(merged[idx], deltaItem), deltaItem);
|
|
20149
20324
|
}
|
|
20150
20325
|
} else {
|
|
20151
20326
|
assertUnmatchedIsAnAddition(deltaItem, piKey(deltaItem), merged.map(piKey), "publicInterface");
|
|
@@ -20163,7 +20338,7 @@ var init_specs2 = __esm({
|
|
|
20163
20338
|
const isDelete = deltaItem?.remove === true || deltaItem?.action === "delete";
|
|
20164
20339
|
if (idx !== -1) {
|
|
20165
20340
|
if (isDelete) merged.splice(idx, 1);
|
|
20166
|
-
else merged[idx] = withUnset(
|
|
20341
|
+
else merged[idx] = withUnset(mergeElement(merged[idx], deltaItem), deltaItem);
|
|
20167
20342
|
} else {
|
|
20168
20343
|
if (key !== null) {
|
|
20169
20344
|
assertUnmatchedIsAnAddition(
|