@lmzhen/dsh-evolution-state-json 0.32.3 → 0.32.5

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/README.md CHANGED
@@ -1,28 +1,19 @@
1
1
  # @lmzhen/dsh-evolution-state-json
2
2
 
3
- JSON-file evolution state provider over the IO seam: review, curator and pending records are JSON
4
- files under the state root, so the medium behind `ctx.evolutionIo` can change without a format
5
- change.
3
+ > 内部组件,默认的本地状态存储。
6
4
 
7
- ## Model surface
5
+ ## 你会看到
8
6
 
9
- - **Model-visible:** nothing of its own: the rows that read this state own the injection.
10
- - **Prompt prefix / KV cache:** unchanged by this package: family-level rules single-sourced in `packages/README.md` §"Model-visible prompt prefix and the KV cache".
11
- - **Mount it?** yes — the `evolution-state-json` row, in `evolution-host`/`evolution-all`/one-click `evolution-preset` (it is the medium they pin).
7
+ 没有命令、面板或工具入口。
12
8
 
13
- ## Configuration
9
+ ## 什么时候会用到
14
10
 
15
- - `root`: the directory the state files live in; `''` means the evolution home.
11
+ 只在排障状态时。
16
12
 
17
- ## Known limitations
13
+ ## 默认 / 前提
18
14
 
19
- - Both tables are capped (200 pending, 500 sessions), and past the pending cap the DOMAIN provider deletes instead of archiving: this provider keeps an audit sidecar. The `updatedAt` stamp is stripped on read, so the consumer-facing record shape is unchanged.
20
- - The one medium without cross-process write locking is the `storage-json` store behind the DOMAIN provider: route multi-process deployments to a backend with cross-process semantics such as SQLite or remote storage.
15
+ 默认启用。
21
16
 
22
- **Runtime invariant:** No companion is published. The platform auto-assembles nothing and the family mounts no `<pkg>/invariant` cordis row, so a companion here would never execute (v37 S2.1 / I-3).
17
+ ## 边界
23
18
 
24
- ## Notes and history
25
-
26
- - P2-4 (v15): the live pending map is BOUNDED — resolved (approved/rejected) records are kept to the most recent `PENDING_RESOLVED_CAP` (200, seam constant in `evolution-state-storage`); the oldest by `resolvedAt` rotate into the `pending-state-archive.json` sidecar (with `.bak` rotation), which is JSON-provider-specific.
27
- - V25-11 (v25): the review-state table is likewise BOUNDED: `REVIEW_STATE_SESSION_CAP` (500, seam constant) rows keyed by session; on every save the least-recently-active sessions (provider-stamped `updatedAt`, stored on disk only) are pruned.
28
- - JSON provider serializes writers inside one process AND through the IO backend's cross-process transact lock (an internal transact wrapper (not public API, audit v10 S-03) wraps every mutation, 0.3.20/0.3.27) — this provider is NOT limited to single-process safety.
19
+ 损坏文件会被隔离,不会静默覆盖。
package/lib/index.js CHANGED
@@ -1,55 +1,7 @@
1
1
  import z from "@deepseek-ai/schemastery";
2
- import { evolutionHome, isAbsent, isPresent, isRecord, isUnknown, makeSerialQueue, probeText, transactIo, transactTaskGuard } from "@lmzhen/dsh-evolution-core";
2
+ import { WriteKernel, evolutionHome, isAbsent, isPresent, isRecord, isUnknown, makeSerialQueue, probeText, transactIo, transactTaskGuard } from "@lmzhen/dsh-evolution-core";
3
3
  import { CURATOR_STATE_FILE, CURATOR_STATE_KEY, CURATOR_STATE_TABLE, PENDING_ARCHIVE_BAK_FILE, PENDING_ARCHIVE_FILE, PENDING_LEGACY_FILE, PENDING_RESOLVED_CAP, PENDING_STATE_FILE, PENDING_TABLE, PROVIDER_JSON, REVIEW_STATE_FILE, REVIEW_STATE_SESSION_CAP, REVIEW_STATE_TABLE, assertCloneable, canClaimPending, canResolvePending, cloneRecord, recordIssue, releasedStatus, selectPendingOverflow, selectSessionOverflow } from "@lmzhen/dsh-evolution-state-storage";
4
4
  import { basename, dirname, isAbsolute, join } from "node:path";
5
- //#region lib/types/state-store.js
6
- const safeName = (collection) => String(collection).replace(/[^a-zA-Z0-9._-]/g, "_");
7
- var JsonStateStore = class {
8
- name = "json-state-store";
9
- capabilities = { crossProcess: false };
10
- io;
11
- root;
12
- serial = makeSerialQueue();
13
- constructor(io, root) {
14
- this.io = io;
15
- this.root = root;
16
- }
17
- path(collection) {
18
- return join(this.root, "state-store", safeName(collection) + ".json");
19
- }
20
- async load(collection) {
21
- const text = await this.io.readText(this.path(collection));
22
- if (text === null) return {
23
- schemaVersion: 1,
24
- records: {}
25
- };
26
- const parsed = JSON.parse(text);
27
- if (parsed.schemaVersion !== 1 || parsed.records === null || typeof parsed.records !== "object" || Array.isArray(parsed.records)) throw new Error("state-store collection is corrupt: " + String(collection));
28
- return parsed;
29
- }
30
- async read(collection, key) {
31
- return (await this.load(collection)).records[key];
32
- }
33
- async transact(collection, key, fn) {
34
- return this.serial(async () => {
35
- let next;
36
- await transactIo(this.io, this.path(collection), async (current) => {
37
- const file = current === null ? {
38
- schemaVersion: 1,
39
- records: {}
40
- } : JSON.parse(current);
41
- next = await fn(file.records[key]);
42
- file.records[key] = next;
43
- return JSON.stringify(file);
44
- });
45
- return next;
46
- });
47
- }
48
- async list(collection) {
49
- return Object.values((await this.load(collection)).records);
50
- }
51
- };
52
- //#endregion
53
5
  //#region lib/types/index.js
54
6
  /**
55
7
  * JSON-file evolution state provider over the IO seam.
@@ -228,7 +180,7 @@ async function ensureCorruptCopy(ctx, io, root, file, bad, memory) {
228
180
  return wrote;
229
181
  }
230
182
  async function jsonTransact(ctx, io, root, file, task, options) {
231
- await transactIo(io(), join(root, file), async (current) => {
183
+ await new WriteKernel({ io: io() }).run({ path: join(root, file) }, async (current) => {
232
184
  let parsed = null;
233
185
  if (current !== null) {
234
186
  try {
@@ -752,7 +704,6 @@ function apply(ctx, rawConfig = {}) {
752
704
  }
753
705
  };
754
706
  ctx.effect(() => ctx.evolutionStateStorage.registerProvider(provider), "evolution-state-json.provider");
755
- ctx.provide("evolutionStateStore", new JsonStateStore(io(), root));
756
707
  }
757
708
  //#endregion
758
- export { Config, JsonStateStore, apply, inject, jsonTransact, name, newQuarantineMemory };
709
+ export { Config, apply, inject, jsonTransact, name, newQuarantineMemory };
@@ -15,9 +15,10 @@ export interface Config {
15
15
  }
16
16
  export declare const Config: z<Config>;
17
17
  /**
18
- * Cross-process JSON-file RMW (v3-audit M-8): every read-modify-write state
19
- * mutation runs inside the IO backend's transact lock (via transactIo) so a
20
- * second process sharing DSH_HOME cannot interleave its claim/resolve.
18
+ * In-process JSON-file RMW (v3-audit M-8): every read-modify-write state
19
+ * mutation runs inside the IO backend's transact lock (via transactIo). The
20
+ * shipped backend is single-process; a second process sharing DSH_HOME is not
21
+ * coordinated and must not be assumed safe.
21
22
  * `task` returns the next value; null = ENSURE-ABSENT (the file is deleted
22
23
  * when it exists — the parity of the transact seam, V6-32). For a record-map
23
24
  * file the return must be null or a plain object map of records, and an
@@ -57,5 +58,4 @@ export declare function jsonTransact<T>(ctx: Context, io: () => EvolutionIoLike,
57
58
  memory: QuarantineMemory;
58
59
  }): Promise<void>;
59
60
  export declare function apply(ctx: Context, rawConfig?: Config): void;
60
- export { JsonStateStore } from './state-store.ts';
61
61
  //# sourceMappingURL=index.d.ts.map
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.32.3",
4
+ "version": "0.32.5",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -27,18 +27,17 @@
27
27
  "license": "MIT",
28
28
  "dependencies": {
29
29
  "@deepseek-ai/schemastery": "^3.18.5",
30
- "@lmzhen/dsh-evolution-contract": "^0.32.3",
31
- "@lmzhen/dsh-evolution-core": "^0.32.3"
30
+ "@lmzhen/dsh-evolution-core": "^0.32.5"
32
31
  },
33
32
  "peerDependencies": {
34
33
  "@deepseek-ai/cordis": "^4.0.5",
35
- "@lmzhen/dsh-evolution-io": "^0.32.3",
36
- "@lmzhen/dsh-evolution-state-storage": "^0.32.3"
34
+ "@lmzhen/dsh-evolution-io": "^0.32.5",
35
+ "@lmzhen/dsh-evolution-state-storage": "^0.32.5"
37
36
  },
38
37
  "devDependencies": {
39
- "@lmzhen/dsh-evolution-io": "^0.32.3",
40
- "@lmzhen/dsh-evolution-state-storage": "^0.32.3",
41
- "@lmzhen/dsh-evolution-io-node": "^0.32.3"
38
+ "@lmzhen/dsh-evolution-io": "^0.32.5",
39
+ "@lmzhen/dsh-evolution-state-storage": "^0.32.5",
40
+ "@lmzhen/dsh-evolution-io-node": "^0.32.5"
42
41
  },
43
42
  "engines": {
44
43
  "dsh": ">=0.2.1-rc.2 <0.2.2-0"
@@ -1,23 +0,0 @@
1
- /**
2
- * Generic JSON-file implementation of the contract StateStore.
3
- *
4
- * One file per collection; records use a key map. `transact` delegates to the
5
- * IO seam's transact, so the medium's serialization/CAS behavior is preserved.
6
- * The node backend is process-local, so capabilities.crossProcess is false.
7
- */
8
- import type { EvolutionCollection, EvolutionStateCapabilities, EvolutionStateStore } from '@lmzhen/dsh-evolution-contract';
9
- import { type EvolutionIoLike } from '@lmzhen/dsh-evolution-core';
10
- export declare class JsonStateStore implements EvolutionStateStore {
11
- readonly name = "json-state-store";
12
- readonly capabilities: EvolutionStateCapabilities;
13
- private readonly io;
14
- private readonly root;
15
- private readonly serial;
16
- constructor(io: EvolutionIoLike, root: string);
17
- private path;
18
- private load;
19
- read<T>(collection: EvolutionCollection, key: string): Promise<T | undefined>;
20
- transact<T>(collection: EvolutionCollection, key: string, fn: (current: T | undefined) => Promise<T>): Promise<T>;
21
- list<T>(collection: EvolutionCollection): Promise<T[]>;
22
- }
23
- //# sourceMappingURL=state-store.d.ts.map