@lmzhen/dsh-evolution-state-domain 0.3.63 → 0.3.65
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 +47 -19
- package/lib/types/index.d.ts +3 -3
- package/package.json +3 -3
package/lib/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { DomainError, defineDomain, domainTable } from "@deepseek-ai/dsh-storage-domain";
|
|
3
|
-
import { CURATOR_STATE_KEY, CURATOR_STATE_TABLE, PENDING_RESOLVED_CAP, PENDING_TABLE, PROVIDER_DOMAIN, REVIEW_STATE_TABLE, canClaimPending, canResolvePending, releasedStatus } from "@lmzhen/dsh-evolution-state-storage";
|
|
3
|
+
import { CURATOR_STATE_KEY, CURATOR_STATE_TABLE, PENDING_RESOLVED_CAP, PENDING_TABLE, PROVIDER_DOMAIN, REVIEW_STATE_TABLE, assertCloneable, canClaimPending, canResolvePending, cloneRecord, recordIssue, releasedStatus } from "@lmzhen/dsh-evolution-state-storage";
|
|
4
4
|
//#region lib/types/index.js
|
|
5
5
|
/**
|
|
6
6
|
* storage-domain provider for evolution state.
|
|
@@ -23,7 +23,7 @@ const reviewStateSchema = z.object({
|
|
|
23
23
|
turnsSinceMemory: z.number().int().nonnegative(),
|
|
24
24
|
turnsSinceSkill: z.number().int().nonnegative(),
|
|
25
25
|
lastTurn: z.number().int().nonnegative()
|
|
26
|
-
});
|
|
26
|
+
}).loose();
|
|
27
27
|
/**
|
|
28
28
|
* Curator-state record schema of the storage-domain table.
|
|
29
29
|
* @internal Referenced only by this package's own tests and EVOLUTION_DOMAIN
|
|
@@ -36,7 +36,7 @@ const curatorStateSchema = z.object({
|
|
|
36
36
|
runCount: z.number().int().nonnegative(),
|
|
37
37
|
lastSummary: z.string(),
|
|
38
38
|
paused: z.boolean()
|
|
39
|
-
});
|
|
39
|
+
}).loose();
|
|
40
40
|
/**
|
|
41
41
|
* Pending record schema of the storage-domain table.
|
|
42
42
|
* @internal Referenced only by this package's own tests and EVOLUTION_DOMAIN
|
|
@@ -63,7 +63,7 @@ const pendingSchema = z.object({
|
|
|
63
63
|
claimedAt: z.string().optional(),
|
|
64
64
|
origin: z.string().optional(),
|
|
65
65
|
sessionId: z.string().optional()
|
|
66
|
-
});
|
|
66
|
+
}).loose();
|
|
67
67
|
/**
|
|
68
68
|
* The evolution storage-domain spec: three schema-validated KV tables.
|
|
69
69
|
* @internal Referenced only by this package's own tests and `open()` — not
|
|
@@ -116,40 +116,64 @@ function apply(ctx) {
|
|
|
116
116
|
const provider = {
|
|
117
117
|
name: PROVIDER_DOMAIN,
|
|
118
118
|
async loadReviewState(sessionId) {
|
|
119
|
-
|
|
119
|
+
const record = (await ensure()).table(REVIEW_STATE_TABLE).get(sessionId);
|
|
120
|
+
return record === void 0 ? null : structuredClone(record);
|
|
120
121
|
},
|
|
121
122
|
async saveReviewState(sessionId, record) {
|
|
122
|
-
|
|
123
|
+
const issue = recordIssue(REVIEW_STATE_TABLE, record) ?? assertCloneable(record);
|
|
124
|
+
if (issue !== null) throw new Error(`evolution-state-domain: refusing to persist an invalid review-state record: ${issue}`);
|
|
125
|
+
const parsed = reviewStateSchema.safeParse(record);
|
|
126
|
+
if (!parsed.success) throw new Error(`evolution-state-domain: refusing to persist an invalid review-state record: ${parsed.error.issues[0]?.message ?? "schema mismatch"}`);
|
|
127
|
+
await (await ensure()).table(REVIEW_STATE_TABLE).put(sessionId, cloneRecord(parsed.data));
|
|
123
128
|
},
|
|
124
129
|
async loadCuratorState() {
|
|
125
|
-
|
|
130
|
+
const record = (await ensure()).table(CURATOR_STATE_TABLE).get(CURATOR_STATE_KEY);
|
|
131
|
+
return record === void 0 ? null : structuredClone(record);
|
|
126
132
|
},
|
|
127
133
|
async saveCuratorState(record) {
|
|
128
|
-
|
|
134
|
+
const issue = recordIssue(CURATOR_STATE_TABLE, record) ?? assertCloneable(record);
|
|
135
|
+
if (issue !== null) throw new Error(`evolution-state-domain: refusing to persist an invalid curator-state record: ${issue}`);
|
|
136
|
+
const parsed = curatorStateSchema.safeParse(record);
|
|
137
|
+
if (!parsed.success) throw new Error(`evolution-state-domain: refusing to persist an invalid curator-state record: ${parsed.error.issues[0]?.message ?? "schema mismatch"}`);
|
|
138
|
+
await (await ensure()).table(CURATOR_STATE_TABLE).put(CURATOR_STATE_KEY, cloneRecord(parsed.data));
|
|
129
139
|
},
|
|
130
140
|
async transactCuratorState(task) {
|
|
131
141
|
const table = (await ensure()).table(CURATOR_STATE_TABLE);
|
|
142
|
+
const guarded = (current) => {
|
|
143
|
+
const next = task(current);
|
|
144
|
+
if (next === null) return null;
|
|
145
|
+
const issue = recordIssue(CURATOR_STATE_TABLE, next) ?? assertCloneable(next);
|
|
146
|
+
if (issue !== null) throw new Error(`evolution-state-domain: refusing to persist an invalid curator-state record: ${issue}`);
|
|
147
|
+
return cloneRecord(next);
|
|
148
|
+
};
|
|
132
149
|
try {
|
|
133
|
-
await table.update(CURATOR_STATE_KEY, (current) =>
|
|
150
|
+
await table.update(CURATOR_STATE_KEY, (current) => guarded(current) ?? current);
|
|
134
151
|
return;
|
|
135
152
|
} catch (error) {
|
|
136
153
|
if (!(error instanceof DomainError && error.code === "missing-key")) throw error;
|
|
137
154
|
}
|
|
138
155
|
try {
|
|
139
|
-
await table.update(CURATOR_STATE_KEY, (current) =>
|
|
156
|
+
await table.update(CURATOR_STATE_KEY, (current) => guarded(current) ?? current);
|
|
140
157
|
return;
|
|
141
158
|
} catch (error) {
|
|
142
159
|
if (!(error instanceof DomainError && error.code === "missing-key")) throw error;
|
|
143
160
|
}
|
|
144
|
-
const next =
|
|
161
|
+
const next = guarded(null);
|
|
145
162
|
if (next !== null) await table.put(CURATOR_STATE_KEY, next);
|
|
146
163
|
else await table.delete(CURATOR_STATE_KEY);
|
|
147
164
|
},
|
|
148
165
|
async listPending(status = "pending") {
|
|
149
|
-
return [...(await ensure()).table(PENDING_TABLE).entries()].
|
|
166
|
+
return [...(await ensure()).table(PENDING_TABLE).entries()].filter(([, value]) => value.status === status).map(([, value]) => structuredClone(value));
|
|
150
167
|
},
|
|
151
168
|
async savePending(record) {
|
|
152
|
-
|
|
169
|
+
const issue = recordIssue(PENDING_TABLE, record) ?? assertCloneable(record);
|
|
170
|
+
if (issue !== null) throw new Error(`evolution-state-domain: refusing to persist an invalid pending record: ${issue}`);
|
|
171
|
+
const parsed = pendingSchema.safeParse({
|
|
172
|
+
...record,
|
|
173
|
+
args: record.args
|
|
174
|
+
});
|
|
175
|
+
if (!parsed.success) throw new Error(`evolution-state-domain: refusing to persist an invalid pending record: ${parsed.error.issues[0]?.message ?? "schema mismatch"}`);
|
|
176
|
+
await (await ensure()).table(PENDING_TABLE).put(record.id, cloneRecord(parsed.data));
|
|
153
177
|
},
|
|
154
178
|
async claimPending(id, claimId) {
|
|
155
179
|
const table = (await ensure()).table(PENDING_TABLE);
|
|
@@ -166,7 +190,7 @@ function apply(ctx) {
|
|
|
166
190
|
};
|
|
167
191
|
return slot.record;
|
|
168
192
|
});
|
|
169
|
-
return slot.record === null ? null :
|
|
193
|
+
return slot.record === null ? null : structuredClone(slot.record);
|
|
170
194
|
} catch (error) {
|
|
171
195
|
if (error instanceof DomainError && error.code === "missing-key") return null;
|
|
172
196
|
throw error;
|
|
@@ -216,17 +240,21 @@ function apply(ctx) {
|
|
|
216
240
|
};
|
|
217
241
|
resolvedEntries.sort((a, b) => resolvedAtMs(a.record) - resolvedAtMs(b.record));
|
|
218
242
|
const evicted = resolvedEntries.slice(0, Math.max(0, resolvedEntries.length - PENDING_RESOLVED_CAP));
|
|
219
|
-
for (const entry of evicted)
|
|
220
|
-
|
|
221
|
-
|
|
243
|
+
for (const entry of evicted) {
|
|
244
|
+
const current = table.get(entry.key);
|
|
245
|
+
if (!(current !== void 0 && (current.status === "approved" || current.status === "rejected") && current.resolvedAt === entry.record.resolvedAt)) continue;
|
|
246
|
+
await table.delete(entry.key).catch((error) => {
|
|
247
|
+
ctx.logger.warn(`evolution-state-domain: pending-cap eviction for "${entry.key}" failed (will retry on the next resolve): ${error instanceof Error ? error.message : String(error)}`);
|
|
248
|
+
});
|
|
249
|
+
}
|
|
222
250
|
}
|
|
223
251
|
const rawRecord = record;
|
|
224
252
|
if (resolved.record === null) return {
|
|
225
|
-
record: rawRecord === null ? null :
|
|
253
|
+
record: rawRecord === null ? null : structuredClone(rawRecord),
|
|
226
254
|
applied: false
|
|
227
255
|
};
|
|
228
256
|
return {
|
|
229
|
-
record:
|
|
257
|
+
record: structuredClone(resolved.record),
|
|
230
258
|
applied: true
|
|
231
259
|
};
|
|
232
260
|
} catch (error) {
|
package/lib/types/index.d.ts
CHANGED
|
@@ -22,7 +22,7 @@ export declare const reviewStateSchema: z.ZodObject<{
|
|
|
22
22
|
turnsSinceMemory: z.ZodNumber;
|
|
23
23
|
turnsSinceSkill: z.ZodNumber;
|
|
24
24
|
lastTurn: z.ZodNumber;
|
|
25
|
-
}, z.core.$
|
|
25
|
+
}, z.core.$loose>;
|
|
26
26
|
/**
|
|
27
27
|
* Curator-state record schema of the storage-domain table.
|
|
28
28
|
* @internal Referenced only by this package's own tests and EVOLUTION_DOMAIN
|
|
@@ -34,7 +34,7 @@ export declare const curatorStateSchema: z.ZodObject<{
|
|
|
34
34
|
runCount: z.ZodNumber;
|
|
35
35
|
lastSummary: z.ZodString;
|
|
36
36
|
paused: z.ZodBoolean;
|
|
37
|
-
}, z.core.$
|
|
37
|
+
}, z.core.$loose>;
|
|
38
38
|
/**
|
|
39
39
|
* Pending record schema of the storage-domain table.
|
|
40
40
|
* @internal Referenced only by this package's own tests and EVOLUTION_DOMAIN
|
|
@@ -52,7 +52,7 @@ export declare const pendingSchema: z.ZodObject<{
|
|
|
52
52
|
claimedAt: z.ZodOptional<z.ZodString>;
|
|
53
53
|
origin: z.ZodOptional<z.ZodString>;
|
|
54
54
|
sessionId: z.ZodOptional<z.ZodString>;
|
|
55
|
-
}, z.core.$
|
|
55
|
+
}, z.core.$loose>;
|
|
56
56
|
/**
|
|
57
57
|
* The evolution storage-domain spec: three schema-validated KV tables.
|
|
58
58
|
* @internal Referenced only by this package's own tests and `open()` — not
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lmzhen/dsh-evolution-state-domain",
|
|
3
3
|
"description": "storage-domain provider for evolution state (community build)",
|
|
4
|
-
"version": "0.3.
|
|
4
|
+
"version": "0.3.65",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
@@ -36,13 +36,13 @@
|
|
|
36
36
|
"@deepseek-ai/dsh-invariants": "^0.1.1-rc.2",
|
|
37
37
|
"@deepseek-ai/cordis": "^4.0.1",
|
|
38
38
|
"@deepseek-ai/dsh-storage-domain": "^0.1.1-rc.2",
|
|
39
|
-
"@lmzhen/dsh-evolution-state-storage": "^0.3.
|
|
39
|
+
"@lmzhen/dsh-evolution-state-storage": "^0.3.65"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
42
|
"@deepseek-ai/dsh-invariants": "^0.1.1-rc.2",
|
|
43
43
|
"@deepseek-ai/dsh-storage-domain": "^0.1.1-rc.2",
|
|
44
44
|
"@deepseek-ai/dsh-storage": "^0.1.1-rc.2",
|
|
45
45
|
"@deepseek-ai/dsh-storage-json": "^0.1.1-rc.2",
|
|
46
|
-
"@lmzhen/dsh-evolution-state-storage": "^0.3.
|
|
46
|
+
"@lmzhen/dsh-evolution-state-storage": "^0.3.65"
|
|
47
47
|
}
|
|
48
48
|
}
|