@lmzhen/dsh-evolution-state-json 0.31.0 → 0.32.0

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 CHANGED
@@ -2,6 +2,54 @@ import z from "@deepseek-ai/schemastery";
2
2
  import { 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
5
53
  //#region lib/types/index.js
6
54
  /**
7
55
  * JSON-file evolution state provider over the IO seam.
@@ -704,6 +752,7 @@ function apply(ctx, rawConfig = {}) {
704
752
  }
705
753
  };
706
754
  ctx.effect(() => ctx.evolutionStateStorage.registerProvider(provider), "evolution-state-json.provider");
755
+ ctx.provide("evolutionStateStore", new JsonStateStore(io(), root));
707
756
  }
708
757
  //#endregion
709
- export { Config, apply, inject, jsonTransact, name, newQuarantineMemory };
758
+ export { Config, JsonStateStore, apply, inject, jsonTransact, name, newQuarantineMemory };
@@ -57,4 +57,5 @@ export declare function jsonTransact<T>(ctx: Context, io: () => EvolutionIoLike,
57
57
  memory: QuarantineMemory;
58
58
  }): Promise<void>;
59
59
  export declare function apply(ctx: Context, rawConfig?: Config): void;
60
+ export { JsonStateStore } from './state-store.ts';
60
61
  //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,23 @@
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
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.31.0",
4
+ "version": "0.32.0",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -27,17 +27,18 @@
27
27
  "license": "MIT",
28
28
  "dependencies": {
29
29
  "@deepseek-ai/schemastery": "^3.18.5",
30
- "@lmzhen/dsh-evolution-core": "^0.31.0"
30
+ "@lmzhen/dsh-evolution-contract": "^0.32.0",
31
+ "@lmzhen/dsh-evolution-core": "^0.32.0"
31
32
  },
32
33
  "peerDependencies": {
33
34
  "@deepseek-ai/cordis": "^4.0.5",
34
- "@lmzhen/dsh-evolution-io": "^0.31.0",
35
- "@lmzhen/dsh-evolution-state-storage": "^0.31.0"
35
+ "@lmzhen/dsh-evolution-io": "^0.32.0",
36
+ "@lmzhen/dsh-evolution-state-storage": "^0.32.0"
36
37
  },
37
38
  "devDependencies": {
38
- "@lmzhen/dsh-evolution-io": "^0.31.0",
39
- "@lmzhen/dsh-evolution-state-storage": "^0.31.0",
40
- "@lmzhen/dsh-evolution-io-node": "^0.31.0"
39
+ "@lmzhen/dsh-evolution-io": "^0.32.0",
40
+ "@lmzhen/dsh-evolution-state-storage": "^0.32.0",
41
+ "@lmzhen/dsh-evolution-io-node": "^0.32.0"
41
42
  },
42
43
  "engines": {
43
44
  "dsh": ">=0.2.1-rc.2 <0.2.2-0"