@lmzhen/dsh-evolution-state-storage 0.3.63 → 0.3.64
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 +32 -10
- package/lib/types/index.d.ts +19 -6
- package/package.json +1 -1
package/lib/index.js
CHANGED
|
@@ -50,24 +50,46 @@ const canResolvePending = (status) => status === "pending" || status === "execut
|
|
|
50
50
|
/** Releasing a claim on an executing record rolls it back to pending (a
|
|
51
51
|
* runner FAILURE is retryable); other statuses pass through unchanged. */
|
|
52
52
|
const releasedStatus = (status) => status === "executing" ? "pending" : status;
|
|
53
|
-
/** P2-4 (v15): the live pending map/table is BOUNDED
|
|
54
|
-
*
|
|
55
|
-
* `resolvedAt
|
|
56
|
-
* so domain deployments grew the table without
|
|
57
|
-
*
|
|
58
|
-
*
|
|
53
|
+
/** P2-4 (v15): the live pending map/table is BOUNDED on the RESOLVE path —
|
|
54
|
+
* `tryResolvePending` drops the oldest resolved (approved/rejected) records by
|
|
55
|
+
* `resolvedAt` once more than this many exist. Single source (the v15 audit
|
|
56
|
+
* found the bound was json-only, so domain deployments grew the table without
|
|
57
|
+
* bound).
|
|
58
|
+
*
|
|
59
|
+
* C-6 (v18) contract precision: a direct `savePending` of an already-resolved
|
|
60
|
+
* record does NOT trigger eviction (the cap is maintained by the resolve
|
|
61
|
+
* operation, not by the writer), and pending/executing records are never
|
|
62
|
+
* trimmed. Callers that write resolved audit records themselves own that
|
|
63
|
+
* growth; the seam's resolve path is what keeps the table bounded.
|
|
64
|
+
* The audit ARCHIVE sidecar that json maintains beyond the cap stays
|
|
65
|
+
* json-specific (domain has no sidecar facility) — declared in both READMEs. */
|
|
59
66
|
const PENDING_RESOLVED_CAP = 200;
|
|
60
67
|
var EvolutionStateStorageRegistry = class extends Service {
|
|
61
68
|
providers = /* @__PURE__ */ new Map();
|
|
69
|
+
/** C-7 (v18): per-name dispose, mirroring the evolution-io registry. */
|
|
70
|
+
disposals = /* @__PURE__ */ new Map();
|
|
62
71
|
constructor(ctx) {
|
|
63
72
|
super(ctx, "evolutionStateStorage");
|
|
64
73
|
}
|
|
74
|
+
/** C-7 (v18): re-registering the IDENTICAL provider object is idempotent and
|
|
75
|
+
* returns the original dispose (HMR / re-mounted row); a DIFFERENT object
|
|
76
|
+
* under a registered name still fails loud. The dispose carries a generation
|
|
77
|
+
* guard so a stale handle cannot remove a newer registration. */
|
|
65
78
|
registerProvider(provider) {
|
|
66
|
-
|
|
67
|
-
this.providers.
|
|
68
|
-
|
|
69
|
-
|
|
79
|
+
const idempotent = this.providers.get(provider.name) === provider;
|
|
80
|
+
if (!idempotent && this.providers.has(provider.name)) throw new Error(`evolution state storage provider "${provider.name}" already registered`);
|
|
81
|
+
if (idempotent) {
|
|
82
|
+
const existing = this.disposals.get(provider.name);
|
|
83
|
+
if (existing !== void 0) return existing;
|
|
84
|
+
}
|
|
85
|
+
const dispose = () => {
|
|
86
|
+
if (this.disposals.get(provider.name) !== dispose) return;
|
|
87
|
+
this.providers.delete(provider.name);
|
|
88
|
+
this.disposals.delete(provider.name);
|
|
70
89
|
};
|
|
90
|
+
this.providers.set(provider.name, provider);
|
|
91
|
+
this.disposals.set(provider.name, dispose);
|
|
92
|
+
return dispose;
|
|
71
93
|
}
|
|
72
94
|
/** S-07: whether ANY provider is registered. Lets the state
|
|
73
95
|
* consumer precheck a pinned `provider` config at mount time (a typo fails
|
package/lib/types/index.d.ts
CHANGED
|
@@ -24,12 +24,19 @@ export declare const canResolvePending: (status: PendingStatus) => boolean;
|
|
|
24
24
|
/** Releasing a claim on an executing record rolls it back to pending (a
|
|
25
25
|
* runner FAILURE is retryable); other statuses pass through unchanged. */
|
|
26
26
|
export declare const releasedStatus: (status: PendingStatus) => PendingStatus;
|
|
27
|
-
/** P2-4 (v15): the live pending map/table is BOUNDED
|
|
28
|
-
*
|
|
29
|
-
* `resolvedAt
|
|
30
|
-
* so domain deployments grew the table without
|
|
31
|
-
*
|
|
32
|
-
*
|
|
27
|
+
/** P2-4 (v15): the live pending map/table is BOUNDED on the RESOLVE path —
|
|
28
|
+
* `tryResolvePending` drops the oldest resolved (approved/rejected) records by
|
|
29
|
+
* `resolvedAt` once more than this many exist. Single source (the v15 audit
|
|
30
|
+
* found the bound was json-only, so domain deployments grew the table without
|
|
31
|
+
* bound).
|
|
32
|
+
*
|
|
33
|
+
* C-6 (v18) contract precision: a direct `savePending` of an already-resolved
|
|
34
|
+
* record does NOT trigger eviction (the cap is maintained by the resolve
|
|
35
|
+
* operation, not by the writer), and pending/executing records are never
|
|
36
|
+
* trimmed. Callers that write resolved audit records themselves own that
|
|
37
|
+
* growth; the seam's resolve path is what keeps the table bounded.
|
|
38
|
+
* The audit ARCHIVE sidecar that json maintains beyond the cap stays
|
|
39
|
+
* json-specific (domain has no sidecar facility) — declared in both READMEs. */
|
|
33
40
|
export declare const PENDING_RESOLVED_CAP = 200;
|
|
34
41
|
/**
|
|
35
42
|
* Claim lifecycle (S3.3): pending →(claim)→ executing →(resolve)→ approved/rejected.
|
|
@@ -108,7 +115,13 @@ declare module '@deepseek-ai/cordis' {
|
|
|
108
115
|
}
|
|
109
116
|
export declare class EvolutionStateStorageRegistry extends Service {
|
|
110
117
|
private readonly providers;
|
|
118
|
+
/** C-7 (v18): per-name dispose, mirroring the evolution-io registry. */
|
|
119
|
+
private readonly disposals;
|
|
111
120
|
constructor(ctx: Context);
|
|
121
|
+
/** C-7 (v18): re-registering the IDENTICAL provider object is idempotent and
|
|
122
|
+
* returns the original dispose (HMR / re-mounted row); a DIFFERENT object
|
|
123
|
+
* under a registered name still fails loud. The dispose carries a generation
|
|
124
|
+
* guard so a stale handle cannot remove a newer registration. */
|
|
112
125
|
registerProvider(provider: EvolutionStateStorage): () => void;
|
|
113
126
|
/** S-07: whether ANY provider is registered. Lets the state
|
|
114
127
|
* consumer precheck a pinned `provider` config at mount time (a typo fails
|