@lmzhen/dsh-evolution-state-json 0.3.33 → 0.3.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/lib/index.js +40 -29
- package/package.json +6 -6
package/lib/index.js
CHANGED
|
@@ -95,25 +95,35 @@ function apply(ctx, rawConfig) {
|
|
|
95
95
|
}
|
|
96
96
|
const mutate = makeSerialQueue();
|
|
97
97
|
let legacyMigrated = false;
|
|
98
|
+
let archivedIdsCache = null;
|
|
99
|
+
async function readArchivedIds() {
|
|
100
|
+
if (archivedIdsCache !== null) return archivedIdsCache;
|
|
101
|
+
const ids = /* @__PURE__ */ new Set();
|
|
102
|
+
try {
|
|
103
|
+
const rawArchive = await readJson("pending-state-archive.json");
|
|
104
|
+
if (Array.isArray(rawArchive)) {
|
|
105
|
+
for (const entry of rawArchive) if (entry && typeof entry.id === "string") ids.add(entry.id);
|
|
106
|
+
}
|
|
107
|
+
} catch {}
|
|
108
|
+
archivedIdsCache = ids;
|
|
109
|
+
return ids;
|
|
110
|
+
}
|
|
111
|
+
function filterLegacy(legacy, current, archivedIds) {
|
|
112
|
+
const retired = {};
|
|
113
|
+
for (const [id, record] of Object.entries(legacy)) {
|
|
114
|
+
if (id in (current ?? {})) continue;
|
|
115
|
+
if (archivedIds.has(id)) continue;
|
|
116
|
+
retired[id] = record;
|
|
117
|
+
}
|
|
118
|
+
return retired;
|
|
119
|
+
}
|
|
98
120
|
async function retireLegacyOnce(legacy, current) {
|
|
99
121
|
if (legacyMigrated) return {};
|
|
100
122
|
try {
|
|
101
|
-
const
|
|
102
|
-
|
|
103
|
-
const rawArchive = await readJson("pending-state-archive.json");
|
|
104
|
-
if (Array.isArray(rawArchive)) {
|
|
105
|
-
for (const entry of rawArchive) if (entry && typeof entry.id === "string") archivedIds.add(entry.id);
|
|
106
|
-
}
|
|
107
|
-
} catch {}
|
|
108
|
-
const retired = {};
|
|
109
|
-
for (const [id, record] of Object.entries(legacy)) {
|
|
110
|
-
if (id in (current ?? {})) continue;
|
|
111
|
-
if (archivedIds.has(id)) continue;
|
|
112
|
-
retired[id] = record;
|
|
113
|
-
}
|
|
114
|
-
await jsonTransact(io, root, "pending-state.json", () => ({
|
|
123
|
+
const retired = filterLegacy(legacy, current, await readArchivedIds());
|
|
124
|
+
await jsonTransact(io, root, "pending-state.json", (fresh) => ({
|
|
115
125
|
...retired,
|
|
116
|
-
...
|
|
126
|
+
...fresh ?? {}
|
|
117
127
|
}));
|
|
118
128
|
await io().rename(pathOf("pending.json"), pathOf("pending.json.migrated"));
|
|
119
129
|
legacyMigrated = true;
|
|
@@ -130,6 +140,17 @@ function apply(ctx, rawConfig) {
|
|
|
130
140
|
};
|
|
131
141
|
return { ...current ?? {} };
|
|
132
142
|
}
|
|
143
|
+
/** V6-01 (0.3.34): single-sourced legacy merge for the four mutation paths —
|
|
144
|
+
* the SAME exclusion as the retirement read path, so a mutation that runs
|
|
145
|
+
* before any retirement cannot fixate a ghost pending twin in current
|
|
146
|
+
* (the archive id set is cached once; current-wins covers stale misses). */
|
|
147
|
+
async function mergedWithFilteredLegacy(legacy, current) {
|
|
148
|
+
if (legacy === null) return current;
|
|
149
|
+
return {
|
|
150
|
+
...filterLegacy(legacy, current, await readArchivedIds()),
|
|
151
|
+
...current
|
|
152
|
+
};
|
|
153
|
+
}
|
|
133
154
|
/** 0.3.22 (F-336): when the live pending map holds more than
|
|
134
155
|
* `PENDING_RESOLVED_CAP` resolved records, drop the oldest (by resolvedAt,
|
|
135
156
|
* then insertion order on ties) from the map and return them for archiving.
|
|
@@ -244,8 +265,7 @@ function apply(ctx, rawConfig) {
|
|
|
244
265
|
await mutate(async () => {
|
|
245
266
|
await jsonTransact(io, root, "pending-state.json", async (current) => {
|
|
246
267
|
return {
|
|
247
|
-
...(legacyMigrated ? null : await readJson("pending.json")
|
|
248
|
-
...current ?? {},
|
|
268
|
+
...await mergedWithFilteredLegacy(legacyMigrated ? null : await readJson("pending.json"), current ?? {}),
|
|
249
269
|
[record.id]: record
|
|
250
270
|
};
|
|
251
271
|
});
|
|
@@ -255,10 +275,7 @@ function apply(ctx, rawConfig) {
|
|
|
255
275
|
return await mutate(async () => {
|
|
256
276
|
const slot = { claimed: null };
|
|
257
277
|
await jsonTransact(io, root, "pending-state.json", async (current) => {
|
|
258
|
-
const map = {
|
|
259
|
-
...(legacyMigrated ? null : await readJson("pending.json")) ?? {},
|
|
260
|
-
...current ?? {}
|
|
261
|
-
};
|
|
278
|
+
const map = { ...await mergedWithFilteredLegacy(legacyMigrated ? null : await readJson("pending.json"), current ?? {}) };
|
|
262
279
|
const record = map[id] ?? null;
|
|
263
280
|
if (record === null || !canClaimPending(record.status)) return map;
|
|
264
281
|
const now = Date.now();
|
|
@@ -277,10 +294,7 @@ function apply(ctx, rawConfig) {
|
|
|
277
294
|
async releasePendingClaim(id, claimId) {
|
|
278
295
|
await mutate(async () => {
|
|
279
296
|
await jsonTransact(io, root, "pending-state.json", async (current) => {
|
|
280
|
-
const map = {
|
|
281
|
-
...(legacyMigrated ? null : await readJson("pending.json")) ?? {},
|
|
282
|
-
...current ?? {}
|
|
283
|
-
};
|
|
297
|
+
const map = { ...await mergedWithFilteredLegacy(legacyMigrated ? null : await readJson("pending.json"), current ?? {}) };
|
|
284
298
|
const record = map[id];
|
|
285
299
|
if (!record || record.claimedBy !== claimId) return map;
|
|
286
300
|
record.status = releasedStatus(record.status);
|
|
@@ -298,10 +312,7 @@ function apply(ctx, rawConfig) {
|
|
|
298
312
|
};
|
|
299
313
|
let evicted = [];
|
|
300
314
|
await jsonTransact(io, root, "pending-state.json", async (current) => {
|
|
301
|
-
const map = {
|
|
302
|
-
...(legacyMigrated ? null : await readJson("pending.json")) ?? {},
|
|
303
|
-
...current ?? {}
|
|
304
|
-
};
|
|
315
|
+
const map = { ...await mergedWithFilteredLegacy(legacyMigrated ? null : await readJson("pending.json"), current ?? {}) };
|
|
305
316
|
const record = map[id] ?? null;
|
|
306
317
|
if (record === null || !canResolvePending(record.status)) {
|
|
307
318
|
result = {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lmzhen/dsh-evolution-state-json",
|
|
3
3
|
"description": "JSON-file evolution state provider over the IO seam (community build)",
|
|
4
|
-
"version": "0.3.
|
|
4
|
+
"version": "0.3.35",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
@@ -31,17 +31,17 @@
|
|
|
31
31
|
"license": "MIT",
|
|
32
32
|
"dependencies": {
|
|
33
33
|
"@deepseek-ai/schemastery": "^3.18.1",
|
|
34
|
-
"@lmzhen/dsh-evolution-core": "^0.3.
|
|
34
|
+
"@lmzhen/dsh-evolution-core": "^0.3.35"
|
|
35
35
|
},
|
|
36
36
|
"peerDependencies": {
|
|
37
37
|
"@deepseek-ai/dsh-invariants": "^0.1.1-rc.2",
|
|
38
38
|
"@deepseek-ai/cordis": "^4.0.1",
|
|
39
|
-
"@lmzhen/dsh-evolution-io": "^0.3.
|
|
40
|
-
"@lmzhen/dsh-evolution-state-storage": "^0.3.
|
|
39
|
+
"@lmzhen/dsh-evolution-io": "^0.3.35",
|
|
40
|
+
"@lmzhen/dsh-evolution-state-storage": "^0.3.35"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
43
|
"@deepseek-ai/dsh-invariants": "^0.1.1-rc.2",
|
|
44
|
-
"@lmzhen/dsh-evolution-io": "^0.3.
|
|
45
|
-
"@lmzhen/dsh-evolution-state-storage": "^0.3.
|
|
44
|
+
"@lmzhen/dsh-evolution-io": "^0.3.35",
|
|
45
|
+
"@lmzhen/dsh-evolution-state-storage": "^0.3.35"
|
|
46
46
|
}
|
|
47
47
|
}
|