@graphrefly/graphrefly 0.20.0 → 0.22.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/README.md +27 -8
- package/dist/chunk-44HD4BTA.js +47 -0
- package/dist/chunk-44HD4BTA.js.map +1 -0
- package/dist/chunk-7TAQJHQV.js +103 -0
- package/dist/chunk-7TAQJHQV.js.map +1 -0
- package/dist/chunk-BLD3IFYF.js +6827 -0
- package/dist/chunk-BLD3IFYF.js.map +1 -0
- package/dist/{chunk-IAPLC4NR.js → chunk-EQUZ5NLD.js} +34 -45
- package/dist/chunk-EQUZ5NLD.js.map +1 -0
- package/dist/{chunk-OOA2UTXF.js → chunk-IR3KMOLX.js} +358 -128
- package/dist/chunk-IR3KMOLX.js.map +1 -0
- package/dist/{chunk-5PSVTDNZ.js → chunk-MQBQOFDS.js} +20 -11
- package/dist/chunk-MQBQOFDS.js.map +1 -0
- package/dist/chunk-NXC35KC5.js +2417 -0
- package/dist/chunk-NXC35KC5.js.map +1 -0
- package/dist/chunk-QA3RP5NH.js +2234 -0
- package/dist/chunk-QA3RP5NH.js.map +1 -0
- package/dist/chunk-RHI3GHZW.js +115 -0
- package/dist/chunk-RHI3GHZW.js.map +1 -0
- package/dist/{chunk-2L5J6RPM.js → chunk-TH6COGOP.js} +15 -26
- package/dist/chunk-TH6COGOP.js.map +1 -0
- package/dist/compat/nestjs/index.cjs +3366 -2259
- package/dist/compat/nestjs/index.cjs.map +1 -1
- package/dist/compat/nestjs/index.d.cts +6 -4
- package/dist/compat/nestjs/index.d.ts +6 -4
- package/dist/compat/nestjs/index.js +8 -8
- package/dist/core/index.cjs +1611 -1218
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +3 -2
- package/dist/core/index.d.ts +3 -2
- package/dist/core/index.js +37 -34
- package/dist/extra/index.cjs +7726 -6470
- package/dist/extra/index.cjs.map +1 -1
- package/dist/extra/index.d.cts +4 -4
- package/dist/extra/index.d.ts +4 -4
- package/dist/extra/index.js +57 -30
- package/dist/graph/index.cjs +3107 -2216
- package/dist/graph/index.cjs.map +1 -1
- package/dist/graph/index.d.cts +5 -3
- package/dist/graph/index.d.ts +5 -3
- package/dist/graph/index.js +24 -11
- package/dist/graph-DFr0diXB.d.ts +1128 -0
- package/dist/graph-ab1yPwIB.d.cts +1128 -0
- package/dist/{index-8a605sg9.d.ts → index-BHm3Ba5q.d.ts} +2 -2
- package/dist/{index-SFzE_KTa.d.cts → index-BbYZma8G.d.ts} +1697 -586
- package/dist/{index-DuN3bhtm.d.ts → index-BvWfZCTt.d.cts} +1697 -586
- package/dist/index-C9z6rU9P.d.cts +388 -0
- package/dist/{index-BjtlNirP.d.cts → index-D36MAQ3f.d.ts} +4 -4
- package/dist/{index-VHA43cGP.d.cts → index-DLE1Sp-L.d.cts} +2 -2
- package/dist/{index-CgSiUouz.d.ts → index-DrJq9B1T.d.cts} +4 -4
- package/dist/index-DsGxLfwL.d.ts +315 -0
- package/dist/index-Dy04P4W3.d.cts +315 -0
- package/dist/index-HdJx_BjO.d.ts +388 -0
- package/dist/index.cjs +9919 -7900
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +415 -42
- package/dist/index.d.ts +415 -42
- package/dist/index.js +1064 -639
- package/dist/index.js.map +1 -1
- package/dist/meta--fr9sxRM.d.cts +41 -0
- package/dist/meta-n3FoVWML.d.ts +41 -0
- package/dist/node-C5UD5MGq.d.cts +1146 -0
- package/dist/node-C5UD5MGq.d.ts +1146 -0
- package/dist/{observable-DcBwQY7t.d.ts → observable-CQRBtEbq.d.ts} +1 -1
- package/dist/{observable-C8Kx_O6k.d.cts → observable-DWydVy5b.d.cts} +1 -1
- package/dist/patterns/reactive-layout/index.cjs +3102 -2132
- package/dist/patterns/reactive-layout/index.cjs.map +1 -1
- package/dist/patterns/reactive-layout/index.d.cts +5 -3
- package/dist/patterns/reactive-layout/index.d.ts +5 -3
- package/dist/patterns/reactive-layout/index.js +5 -4
- package/dist/storage-Bew05Xy6.d.cts +182 -0
- package/dist/storage-C9fZfMfM.d.ts +182 -0
- package/package.json +2 -1
- package/dist/chunk-2L5J6RPM.js.map +0 -1
- package/dist/chunk-3N2Y6PCR.js +0 -2117
- package/dist/chunk-3N2Y6PCR.js.map +0 -1
- package/dist/chunk-5PSVTDNZ.js.map +0 -1
- package/dist/chunk-BJAOEU4D.js +0 -6269
- package/dist/chunk-BJAOEU4D.js.map +0 -1
- package/dist/chunk-IAPLC4NR.js.map +0 -1
- package/dist/chunk-OOA2UTXF.js.map +0 -1
- package/dist/chunk-PGEU5MEH.js +0 -162
- package/dist/chunk-PGEU5MEH.js.map +0 -1
- package/dist/chunk-R2LPZIY2.js +0 -111
- package/dist/chunk-R2LPZIY2.js.map +0 -1
- package/dist/chunk-WZ2Z2CRV.js +0 -32
- package/dist/chunk-WZ2Z2CRV.js.map +0 -1
- package/dist/chunk-XYL3GLB3.js +0 -1631
- package/dist/chunk-XYL3GLB3.js.map +0 -1
- package/dist/graph-KsTe57nI.d.cts +0 -750
- package/dist/graph-mILUUqW8.d.ts +0 -750
- package/dist/index-B2SvPEbc.d.ts +0 -257
- package/dist/index-BHfg_Ez3.d.ts +0 -629
- package/dist/index-Bc_diYYJ.d.cts +0 -629
- package/dist/index-UudxGnzc.d.cts +0 -257
- package/dist/meta-BnG7XAaE.d.cts +0 -778
- package/dist/meta-BnG7XAaE.d.ts +0 -778
|
@@ -1,3 +1,5 @@
|
|
|
1
|
-
export { B as BlockAdapters, C as CanvasMeasureAdapter, a as CanvasMeasureAdapterOptions, b as CanvasModule, c as CharPosition, d as CliMeasureAdapter, e as CliMeasureAdapterOptions, f as ContentBlock, I as ImageMeasurer, g as ImageSizeAdapter, L as LayoutLine, h as LineBreaksResult, j as MeasuredBlock, M as MeasurementAdapter, N as NodeCanvasMeasureAdapter, P as PositionedBlock, k as PrecomputedAdapter, l as PrecomputedAdapterOptions, m as PreparedSegment, R as ReactiveBlockLayoutBundle, n as ReactiveBlockLayoutOptions, o as ReactiveLayoutBundle, p as ReactiveLayoutOptions, S as SegmentBreakKind, q as SegmentMeasureStats, r as SvgBoundsAdapter, s as SvgMeasurer, t as analyzeAndMeasure, u as computeBlockFlow, v as computeCharPositions, w as computeLineBreaks, x as computeTotalHeight, y as measureBlock, z as measureBlocks, A as reactiveBlockLayout, D as reactiveLayout } from '../../index-
|
|
2
|
-
import '../../
|
|
3
|
-
import '../../graph-
|
|
1
|
+
export { B as BlockAdapters, C as CanvasMeasureAdapter, a as CanvasMeasureAdapterOptions, b as CanvasModule, c as CharPosition, d as CliMeasureAdapter, e as CliMeasureAdapterOptions, f as ContentBlock, I as ImageMeasurer, g as ImageSizeAdapter, L as LayoutLine, h as LineBreaksResult, j as MeasuredBlock, M as MeasurementAdapter, N as NodeCanvasMeasureAdapter, P as PositionedBlock, k as PrecomputedAdapter, l as PrecomputedAdapterOptions, m as PreparedSegment, R as ReactiveBlockLayoutBundle, n as ReactiveBlockLayoutOptions, o as ReactiveLayoutBundle, p as ReactiveLayoutOptions, S as SegmentBreakKind, q as SegmentMeasureStats, r as SvgBoundsAdapter, s as SvgMeasurer, t as analyzeAndMeasure, u as computeBlockFlow, v as computeCharPositions, w as computeLineBreaks, x as computeTotalHeight, y as measureBlock, z as measureBlocks, A as reactiveBlockLayout, D as reactiveLayout } from '../../index-DLE1Sp-L.cjs';
|
|
2
|
+
import '../../node-C5UD5MGq.cjs';
|
|
3
|
+
import '../../graph-ab1yPwIB.cjs';
|
|
4
|
+
import '../../meta--fr9sxRM.cjs';
|
|
5
|
+
import '../../storage-Bew05Xy6.cjs';
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
-
export { B as BlockAdapters, C as CanvasMeasureAdapter, a as CanvasMeasureAdapterOptions, b as CanvasModule, c as CharPosition, d as CliMeasureAdapter, e as CliMeasureAdapterOptions, f as ContentBlock, I as ImageMeasurer, g as ImageSizeAdapter, L as LayoutLine, h as LineBreaksResult, j as MeasuredBlock, M as MeasurementAdapter, N as NodeCanvasMeasureAdapter, P as PositionedBlock, k as PrecomputedAdapter, l as PrecomputedAdapterOptions, m as PreparedSegment, R as ReactiveBlockLayoutBundle, n as ReactiveBlockLayoutOptions, o as ReactiveLayoutBundle, p as ReactiveLayoutOptions, S as SegmentBreakKind, q as SegmentMeasureStats, r as SvgBoundsAdapter, s as SvgMeasurer, t as analyzeAndMeasure, u as computeBlockFlow, v as computeCharPositions, w as computeLineBreaks, x as computeTotalHeight, y as measureBlock, z as measureBlocks, A as reactiveBlockLayout, D as reactiveLayout } from '../../index-
|
|
2
|
-
import '../../
|
|
3
|
-
import '../../graph-
|
|
1
|
+
export { B as BlockAdapters, C as CanvasMeasureAdapter, a as CanvasMeasureAdapterOptions, b as CanvasModule, c as CharPosition, d as CliMeasureAdapter, e as CliMeasureAdapterOptions, f as ContentBlock, I as ImageMeasurer, g as ImageSizeAdapter, L as LayoutLine, h as LineBreaksResult, j as MeasuredBlock, M as MeasurementAdapter, N as NodeCanvasMeasureAdapter, P as PositionedBlock, k as PrecomputedAdapter, l as PrecomputedAdapterOptions, m as PreparedSegment, R as ReactiveBlockLayoutBundle, n as ReactiveBlockLayoutOptions, o as ReactiveLayoutBundle, p as ReactiveLayoutOptions, S as SegmentBreakKind, q as SegmentMeasureStats, r as SvgBoundsAdapter, s as SvgMeasurer, t as analyzeAndMeasure, u as computeBlockFlow, v as computeCharPositions, w as computeLineBreaks, x as computeTotalHeight, y as measureBlock, z as measureBlocks, A as reactiveBlockLayout, D as reactiveLayout } from '../../index-BHm3Ba5q.js';
|
|
2
|
+
import '../../node-C5UD5MGq.js';
|
|
3
|
+
import '../../graph-DFr0diXB.js';
|
|
4
|
+
import '../../meta-n3FoVWML.js';
|
|
5
|
+
import '../../storage-C9fZfMfM.js';
|
|
@@ -14,10 +14,11 @@ import {
|
|
|
14
14
|
measureBlocks,
|
|
15
15
|
reactiveBlockLayout,
|
|
16
16
|
reactiveLayout
|
|
17
|
-
} from "../../chunk-
|
|
18
|
-
import "../../chunk-
|
|
19
|
-
import "../../chunk-
|
|
20
|
-
import "../../chunk-
|
|
17
|
+
} from "../../chunk-EQUZ5NLD.js";
|
|
18
|
+
import "../../chunk-NXC35KC5.js";
|
|
19
|
+
import "../../chunk-TH6COGOP.js";
|
|
20
|
+
import "../../chunk-7TAQJHQV.js";
|
|
21
|
+
import "../../chunk-QA3RP5NH.js";
|
|
21
22
|
export {
|
|
22
23
|
CanvasMeasureAdapter,
|
|
23
24
|
CliMeasureAdapter,
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import { N as Node } from './node-C5UD5MGq.cjs';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Storage tier primitive — unified persistence surface (roadmap §3.1).
|
|
5
|
+
*
|
|
6
|
+
* A {@link StorageTier} is the single abstraction used by:
|
|
7
|
+
* - {@link Graph.attachStorage} — snapshot cascade with per-tier cadence
|
|
8
|
+
* - {@link Graph.fromStorage} — hot-boot from the first tier that hits
|
|
9
|
+
* - {@link cascadingCache} — keyed lookup cache with auto-promotion
|
|
10
|
+
*
|
|
11
|
+
* Factory functions cover the common backends: {@link memoryStorage},
|
|
12
|
+
* {@link dictStorage}, {@link fileStorage}, {@link sqliteStorage} (sync), and
|
|
13
|
+
* {@link indexedDbStorage} (async). {@link fromIDBRequest} /
|
|
14
|
+
* {@link fromIDBTransaction} wrap raw IndexedDB primitives as reactive sources
|
|
15
|
+
* — they belong here as the browser-runtime neighbors of `indexedDbStorage`.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Single persistence primitive — supports sync and async backends alike via
|
|
20
|
+
* `void | Promise<void>` returns. `debounceMs` / `compactEvery` / `filter`
|
|
21
|
+
* are per-tier cadence controls honored by {@link Graph.attachStorage};
|
|
22
|
+
* {@link cascadingCache} ignores them (it has its own eviction policy).
|
|
23
|
+
*/
|
|
24
|
+
interface StorageTier {
|
|
25
|
+
/** Read a value. Returns `null` (or resolves to `null`) on miss. */
|
|
26
|
+
load(key: string): unknown | Promise<unknown>;
|
|
27
|
+
/** Write a record. Sync tiers return `void`; async tiers return `Promise<void>`. */
|
|
28
|
+
save(key: string, data: unknown): void | Promise<void>;
|
|
29
|
+
/** Delete a value. Optional — tiers without `clear` are append/overwrite-only. */
|
|
30
|
+
clear?(key: string): void | Promise<void>;
|
|
31
|
+
/**
|
|
32
|
+
* Debounce saves on this tier (ms). Hot tier: `0` (sync-through).
|
|
33
|
+
* Warm: `1000`. Cold: `60000`. Each tier holds its own last-save baseline,
|
|
34
|
+
* so cold flushes aren't penalized by hot flushes.
|
|
35
|
+
*/
|
|
36
|
+
debounceMs?: number;
|
|
37
|
+
/**
|
|
38
|
+
* Every Nth record is a full snapshot; others are diffs against this
|
|
39
|
+
* tier's own baseline. Default `10`. Set `1` for always-full;
|
|
40
|
+
* `Number.POSITIVE_INFINITY` is unsafe — WAL replay needs periodic anchors.
|
|
41
|
+
*/
|
|
42
|
+
compactEvery?: number;
|
|
43
|
+
/** Pre-save filter — return `false` to skip this record on this tier. */
|
|
44
|
+
filter?: (key: string, record: unknown) => boolean;
|
|
45
|
+
}
|
|
46
|
+
/** Handle returned by {@link Graph.attachStorage} — dispose to stop observing. */
|
|
47
|
+
interface StorageHandle {
|
|
48
|
+
dispose(): void;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* In-memory storage tier (process-local; useful for tests and hot tier).
|
|
52
|
+
*
|
|
53
|
+
* @returns Sync {@link StorageTier} with JSON-cloned isolation.
|
|
54
|
+
*
|
|
55
|
+
* @example
|
|
56
|
+
* ```ts
|
|
57
|
+
* import { memoryStorage } from "@graphrefly/graphrefly-ts";
|
|
58
|
+
*
|
|
59
|
+
* const hot = memoryStorage();
|
|
60
|
+
* graph.attachStorage([hot]);
|
|
61
|
+
* ```
|
|
62
|
+
*
|
|
63
|
+
* @category extra
|
|
64
|
+
*/
|
|
65
|
+
declare function memoryStorage(): StorageTier;
|
|
66
|
+
/**
|
|
67
|
+
* Dict-backed storage tier — stores JSON-cloned values under caller keys in
|
|
68
|
+
* a caller-owned plain object. Useful for embedding in a parent state shape.
|
|
69
|
+
*
|
|
70
|
+
* @param storage - Caller-owned object used as the backing store.
|
|
71
|
+
* @returns Sync {@link StorageTier}.
|
|
72
|
+
*
|
|
73
|
+
* @example
|
|
74
|
+
* ```ts
|
|
75
|
+
* import { dictStorage } from "@graphrefly/graphrefly-ts";
|
|
76
|
+
*
|
|
77
|
+
* const state: Record<string, unknown> = {};
|
|
78
|
+
* graph.attachStorage([dictStorage(state)]);
|
|
79
|
+
* ```
|
|
80
|
+
*
|
|
81
|
+
* @category extra
|
|
82
|
+
*/
|
|
83
|
+
declare function dictStorage(storage: Record<string, unknown>): StorageTier;
|
|
84
|
+
/**
|
|
85
|
+
* Atomic JSON file storage tier (one file per key in a directory, temp + rename).
|
|
86
|
+
*
|
|
87
|
+
* Keys are sanitized to filesystem-safe names (`[^a-zA-Z0-9_-]` → `%<hex>`).
|
|
88
|
+
* `load` returns `null` for missing files, empty files, or invalid JSON.
|
|
89
|
+
*
|
|
90
|
+
* @param dir - Directory where per-key JSON files are written.
|
|
91
|
+
* @returns Sync {@link StorageTier}.
|
|
92
|
+
*
|
|
93
|
+
* @example
|
|
94
|
+
* ```ts
|
|
95
|
+
* import { fileStorage, memoryStorage } from "@graphrefly/graphrefly-ts";
|
|
96
|
+
*
|
|
97
|
+
* graph.attachStorage([memoryStorage(), fileStorage("./checkpoints")]);
|
|
98
|
+
* ```
|
|
99
|
+
*
|
|
100
|
+
* @category extra
|
|
101
|
+
*/
|
|
102
|
+
declare function fileStorage(dir: string): StorageTier;
|
|
103
|
+
/**
|
|
104
|
+
* SQLite storage tier using Node.js `node:sqlite` ({@link DatabaseSync}).
|
|
105
|
+
*
|
|
106
|
+
* Returns a {@link StorageTier} extended with `close()` — the caller owns the
|
|
107
|
+
* connection and should close it when discarding the tier.
|
|
108
|
+
*
|
|
109
|
+
* **Runtime:** Requires Node 22.5+ with `node:sqlite` enabled.
|
|
110
|
+
*
|
|
111
|
+
* @param path - SQLite database file path.
|
|
112
|
+
* @returns Sync {@link StorageTier} with an idempotent `close()` method.
|
|
113
|
+
*
|
|
114
|
+
* @example
|
|
115
|
+
* ```ts
|
|
116
|
+
* import { sqliteStorage, memoryStorage } from "@graphrefly/graphrefly-ts";
|
|
117
|
+
*
|
|
118
|
+
* const cold = sqliteStorage("./graphs.sqlite");
|
|
119
|
+
* graph.attachStorage([memoryStorage(), cold]);
|
|
120
|
+
* // ... later, on shutdown:
|
|
121
|
+
* cold.close();
|
|
122
|
+
* ```
|
|
123
|
+
*
|
|
124
|
+
* @category extra
|
|
125
|
+
*/
|
|
126
|
+
declare function sqliteStorage(path: string): StorageTier & {
|
|
127
|
+
close(): void;
|
|
128
|
+
};
|
|
129
|
+
type IndexedDbStorageSpec = {
|
|
130
|
+
dbName: string;
|
|
131
|
+
storeName: string;
|
|
132
|
+
/** Object-store key under which snapshots are written. @default `"graphrefly_checkpoint"`. */
|
|
133
|
+
key?: string;
|
|
134
|
+
version?: number;
|
|
135
|
+
};
|
|
136
|
+
/**
|
|
137
|
+
* Wraps an `IDBRequest` as a one-shot reactive source.
|
|
138
|
+
*
|
|
139
|
+
* @param req - Request whose callbacks are converted to protocol messages.
|
|
140
|
+
* @returns `Node<T>` that emits `DATA` once on success then `COMPLETE`;
|
|
141
|
+
* emits `ERROR` on failure.
|
|
142
|
+
*
|
|
143
|
+
* @category extra
|
|
144
|
+
*/
|
|
145
|
+
declare function fromIDBRequest<T>(req: IDBRequest<T>): Node<T>;
|
|
146
|
+
/**
|
|
147
|
+
* Wraps an `IDBTransaction` terminal lifecycle as a one-shot reactive source.
|
|
148
|
+
*
|
|
149
|
+
* @param tx - Transaction to observe.
|
|
150
|
+
* @returns `Node<void>` that emits `DATA` (`undefined`) then `COMPLETE` on
|
|
151
|
+
* success; emits `ERROR` on `error`/`abort`.
|
|
152
|
+
*
|
|
153
|
+
* @category extra
|
|
154
|
+
*/
|
|
155
|
+
declare function fromIDBTransaction(tx: IDBTransaction): Node<void>;
|
|
156
|
+
/**
|
|
157
|
+
* IndexedDB-backed async storage tier (browser runtime).
|
|
158
|
+
*
|
|
159
|
+
* All three methods return `Promise`s — pairs naturally with a warm/cold
|
|
160
|
+
* cadence where async writes are debounced per tier via
|
|
161
|
+
* {@link Graph.attachStorage}. Writes use `readwrite` transactions; reads use
|
|
162
|
+
* `readonly`. Missing records resolve to `null`.
|
|
163
|
+
*
|
|
164
|
+
* @param spec - Database name, store name, optional `key` (default
|
|
165
|
+
* `"graphrefly_checkpoint"`) and schema `version` (default `1`).
|
|
166
|
+
* @returns Async {@link StorageTier}.
|
|
167
|
+
*
|
|
168
|
+
* @example
|
|
169
|
+
* ```ts
|
|
170
|
+
* import { indexedDbStorage, memoryStorage } from "@graphrefly/graphrefly-ts";
|
|
171
|
+
*
|
|
172
|
+
* graph.attachStorage([
|
|
173
|
+
* memoryStorage(),
|
|
174
|
+
* indexedDbStorage({ dbName: "myApp", storeName: "checkpoints" }),
|
|
175
|
+
* ]);
|
|
176
|
+
* ```
|
|
177
|
+
*
|
|
178
|
+
* @category extra
|
|
179
|
+
*/
|
|
180
|
+
declare function indexedDbStorage(spec: IndexedDbStorageSpec): StorageTier;
|
|
181
|
+
|
|
182
|
+
export { type IndexedDbStorageSpec as I, type StorageHandle as S, type StorageTier as a, fromIDBRequest as b, fromIDBTransaction as c, dictStorage as d, fileStorage as f, indexedDbStorage as i, memoryStorage as m, sqliteStorage as s };
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import { N as Node } from './node-C5UD5MGq.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Storage tier primitive — unified persistence surface (roadmap §3.1).
|
|
5
|
+
*
|
|
6
|
+
* A {@link StorageTier} is the single abstraction used by:
|
|
7
|
+
* - {@link Graph.attachStorage} — snapshot cascade with per-tier cadence
|
|
8
|
+
* - {@link Graph.fromStorage} — hot-boot from the first tier that hits
|
|
9
|
+
* - {@link cascadingCache} — keyed lookup cache with auto-promotion
|
|
10
|
+
*
|
|
11
|
+
* Factory functions cover the common backends: {@link memoryStorage},
|
|
12
|
+
* {@link dictStorage}, {@link fileStorage}, {@link sqliteStorage} (sync), and
|
|
13
|
+
* {@link indexedDbStorage} (async). {@link fromIDBRequest} /
|
|
14
|
+
* {@link fromIDBTransaction} wrap raw IndexedDB primitives as reactive sources
|
|
15
|
+
* — they belong here as the browser-runtime neighbors of `indexedDbStorage`.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Single persistence primitive — supports sync and async backends alike via
|
|
20
|
+
* `void | Promise<void>` returns. `debounceMs` / `compactEvery` / `filter`
|
|
21
|
+
* are per-tier cadence controls honored by {@link Graph.attachStorage};
|
|
22
|
+
* {@link cascadingCache} ignores them (it has its own eviction policy).
|
|
23
|
+
*/
|
|
24
|
+
interface StorageTier {
|
|
25
|
+
/** Read a value. Returns `null` (or resolves to `null`) on miss. */
|
|
26
|
+
load(key: string): unknown | Promise<unknown>;
|
|
27
|
+
/** Write a record. Sync tiers return `void`; async tiers return `Promise<void>`. */
|
|
28
|
+
save(key: string, data: unknown): void | Promise<void>;
|
|
29
|
+
/** Delete a value. Optional — tiers without `clear` are append/overwrite-only. */
|
|
30
|
+
clear?(key: string): void | Promise<void>;
|
|
31
|
+
/**
|
|
32
|
+
* Debounce saves on this tier (ms). Hot tier: `0` (sync-through).
|
|
33
|
+
* Warm: `1000`. Cold: `60000`. Each tier holds its own last-save baseline,
|
|
34
|
+
* so cold flushes aren't penalized by hot flushes.
|
|
35
|
+
*/
|
|
36
|
+
debounceMs?: number;
|
|
37
|
+
/**
|
|
38
|
+
* Every Nth record is a full snapshot; others are diffs against this
|
|
39
|
+
* tier's own baseline. Default `10`. Set `1` for always-full;
|
|
40
|
+
* `Number.POSITIVE_INFINITY` is unsafe — WAL replay needs periodic anchors.
|
|
41
|
+
*/
|
|
42
|
+
compactEvery?: number;
|
|
43
|
+
/** Pre-save filter — return `false` to skip this record on this tier. */
|
|
44
|
+
filter?: (key: string, record: unknown) => boolean;
|
|
45
|
+
}
|
|
46
|
+
/** Handle returned by {@link Graph.attachStorage} — dispose to stop observing. */
|
|
47
|
+
interface StorageHandle {
|
|
48
|
+
dispose(): void;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* In-memory storage tier (process-local; useful for tests and hot tier).
|
|
52
|
+
*
|
|
53
|
+
* @returns Sync {@link StorageTier} with JSON-cloned isolation.
|
|
54
|
+
*
|
|
55
|
+
* @example
|
|
56
|
+
* ```ts
|
|
57
|
+
* import { memoryStorage } from "@graphrefly/graphrefly-ts";
|
|
58
|
+
*
|
|
59
|
+
* const hot = memoryStorage();
|
|
60
|
+
* graph.attachStorage([hot]);
|
|
61
|
+
* ```
|
|
62
|
+
*
|
|
63
|
+
* @category extra
|
|
64
|
+
*/
|
|
65
|
+
declare function memoryStorage(): StorageTier;
|
|
66
|
+
/**
|
|
67
|
+
* Dict-backed storage tier — stores JSON-cloned values under caller keys in
|
|
68
|
+
* a caller-owned plain object. Useful for embedding in a parent state shape.
|
|
69
|
+
*
|
|
70
|
+
* @param storage - Caller-owned object used as the backing store.
|
|
71
|
+
* @returns Sync {@link StorageTier}.
|
|
72
|
+
*
|
|
73
|
+
* @example
|
|
74
|
+
* ```ts
|
|
75
|
+
* import { dictStorage } from "@graphrefly/graphrefly-ts";
|
|
76
|
+
*
|
|
77
|
+
* const state: Record<string, unknown> = {};
|
|
78
|
+
* graph.attachStorage([dictStorage(state)]);
|
|
79
|
+
* ```
|
|
80
|
+
*
|
|
81
|
+
* @category extra
|
|
82
|
+
*/
|
|
83
|
+
declare function dictStorage(storage: Record<string, unknown>): StorageTier;
|
|
84
|
+
/**
|
|
85
|
+
* Atomic JSON file storage tier (one file per key in a directory, temp + rename).
|
|
86
|
+
*
|
|
87
|
+
* Keys are sanitized to filesystem-safe names (`[^a-zA-Z0-9_-]` → `%<hex>`).
|
|
88
|
+
* `load` returns `null` for missing files, empty files, or invalid JSON.
|
|
89
|
+
*
|
|
90
|
+
* @param dir - Directory where per-key JSON files are written.
|
|
91
|
+
* @returns Sync {@link StorageTier}.
|
|
92
|
+
*
|
|
93
|
+
* @example
|
|
94
|
+
* ```ts
|
|
95
|
+
* import { fileStorage, memoryStorage } from "@graphrefly/graphrefly-ts";
|
|
96
|
+
*
|
|
97
|
+
* graph.attachStorage([memoryStorage(), fileStorage("./checkpoints")]);
|
|
98
|
+
* ```
|
|
99
|
+
*
|
|
100
|
+
* @category extra
|
|
101
|
+
*/
|
|
102
|
+
declare function fileStorage(dir: string): StorageTier;
|
|
103
|
+
/**
|
|
104
|
+
* SQLite storage tier using Node.js `node:sqlite` ({@link DatabaseSync}).
|
|
105
|
+
*
|
|
106
|
+
* Returns a {@link StorageTier} extended with `close()` — the caller owns the
|
|
107
|
+
* connection and should close it when discarding the tier.
|
|
108
|
+
*
|
|
109
|
+
* **Runtime:** Requires Node 22.5+ with `node:sqlite` enabled.
|
|
110
|
+
*
|
|
111
|
+
* @param path - SQLite database file path.
|
|
112
|
+
* @returns Sync {@link StorageTier} with an idempotent `close()` method.
|
|
113
|
+
*
|
|
114
|
+
* @example
|
|
115
|
+
* ```ts
|
|
116
|
+
* import { sqliteStorage, memoryStorage } from "@graphrefly/graphrefly-ts";
|
|
117
|
+
*
|
|
118
|
+
* const cold = sqliteStorage("./graphs.sqlite");
|
|
119
|
+
* graph.attachStorage([memoryStorage(), cold]);
|
|
120
|
+
* // ... later, on shutdown:
|
|
121
|
+
* cold.close();
|
|
122
|
+
* ```
|
|
123
|
+
*
|
|
124
|
+
* @category extra
|
|
125
|
+
*/
|
|
126
|
+
declare function sqliteStorage(path: string): StorageTier & {
|
|
127
|
+
close(): void;
|
|
128
|
+
};
|
|
129
|
+
type IndexedDbStorageSpec = {
|
|
130
|
+
dbName: string;
|
|
131
|
+
storeName: string;
|
|
132
|
+
/** Object-store key under which snapshots are written. @default `"graphrefly_checkpoint"`. */
|
|
133
|
+
key?: string;
|
|
134
|
+
version?: number;
|
|
135
|
+
};
|
|
136
|
+
/**
|
|
137
|
+
* Wraps an `IDBRequest` as a one-shot reactive source.
|
|
138
|
+
*
|
|
139
|
+
* @param req - Request whose callbacks are converted to protocol messages.
|
|
140
|
+
* @returns `Node<T>` that emits `DATA` once on success then `COMPLETE`;
|
|
141
|
+
* emits `ERROR` on failure.
|
|
142
|
+
*
|
|
143
|
+
* @category extra
|
|
144
|
+
*/
|
|
145
|
+
declare function fromIDBRequest<T>(req: IDBRequest<T>): Node<T>;
|
|
146
|
+
/**
|
|
147
|
+
* Wraps an `IDBTransaction` terminal lifecycle as a one-shot reactive source.
|
|
148
|
+
*
|
|
149
|
+
* @param tx - Transaction to observe.
|
|
150
|
+
* @returns `Node<void>` that emits `DATA` (`undefined`) then `COMPLETE` on
|
|
151
|
+
* success; emits `ERROR` on `error`/`abort`.
|
|
152
|
+
*
|
|
153
|
+
* @category extra
|
|
154
|
+
*/
|
|
155
|
+
declare function fromIDBTransaction(tx: IDBTransaction): Node<void>;
|
|
156
|
+
/**
|
|
157
|
+
* IndexedDB-backed async storage tier (browser runtime).
|
|
158
|
+
*
|
|
159
|
+
* All three methods return `Promise`s — pairs naturally with a warm/cold
|
|
160
|
+
* cadence where async writes are debounced per tier via
|
|
161
|
+
* {@link Graph.attachStorage}. Writes use `readwrite` transactions; reads use
|
|
162
|
+
* `readonly`. Missing records resolve to `null`.
|
|
163
|
+
*
|
|
164
|
+
* @param spec - Database name, store name, optional `key` (default
|
|
165
|
+
* `"graphrefly_checkpoint"`) and schema `version` (default `1`).
|
|
166
|
+
* @returns Async {@link StorageTier}.
|
|
167
|
+
*
|
|
168
|
+
* @example
|
|
169
|
+
* ```ts
|
|
170
|
+
* import { indexedDbStorage, memoryStorage } from "@graphrefly/graphrefly-ts";
|
|
171
|
+
*
|
|
172
|
+
* graph.attachStorage([
|
|
173
|
+
* memoryStorage(),
|
|
174
|
+
* indexedDbStorage({ dbName: "myApp", storeName: "checkpoints" }),
|
|
175
|
+
* ]);
|
|
176
|
+
* ```
|
|
177
|
+
*
|
|
178
|
+
* @category extra
|
|
179
|
+
*/
|
|
180
|
+
declare function indexedDbStorage(spec: IndexedDbStorageSpec): StorageTier;
|
|
181
|
+
|
|
182
|
+
export { type IndexedDbStorageSpec as I, type StorageHandle as S, type StorageTier as a, fromIDBRequest as b, fromIDBTransaction as c, dictStorage as d, fileStorage as f, indexedDbStorage as i, memoryStorage as m, sqliteStorage as s };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@graphrefly/graphrefly",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.22.0",
|
|
4
4
|
"packageManager": "pnpm@10.33.0+sha512.10568bb4a6afb58c9eb3630da90cc9516417abebd3fabbe6739f0ae795728da1491e9db5a544c76ad8eb7570f5c4bb3d6c637b2cb41bfdcdb47fa823c8649319",
|
|
5
5
|
"description": "Reactive harness layer for agent workflows. Describe automations in plain language, trace every decision, enforce policies, persist checkpoints. Zero dependencies.",
|
|
6
6
|
"repository": {
|
|
@@ -258,6 +258,7 @@
|
|
|
258
258
|
"@types/react": "^19.2.14",
|
|
259
259
|
"@types/react-dom": "^19.2.3",
|
|
260
260
|
"jsdom": "^29.0.1",
|
|
261
|
+
"openai": "^6.34.0",
|
|
261
262
|
"react": "^19.2.4",
|
|
262
263
|
"react-dom": "^19.2.4",
|
|
263
264
|
"reflect-metadata": "^0.2.2",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/core/meta.ts"],"sourcesContent":["import type { Actor } from \"./actor.js\";\nimport { DynamicNodeImpl } from \"./dynamic-node.js\";\nimport { accessHintForGuard } from \"./guard.js\";\nimport { NO_VALUE, type Node, NodeImpl } from \"./node.js\";\n\n/** JSON-shaped slice of a node for Phase 1 `Graph.describe()` (GRAPHREFLY-SPEC §3.6, Appendix B). */\nexport type DescribeNodeOutput = {\n\ttype: \"state\" | \"derived\" | \"producer\" | \"operator\" | \"effect\";\n\tstatus?: Node[\"status\"];\n\tdeps: string[];\n\tmeta?: Record<string, unknown>;\n\tname?: string;\n\tvalue?: unknown;\n\t/** True when the node has never received or been initialized with a value (cache holds SENTINEL). */\n\tsentinel?: boolean;\n\t/** Node versioning info (GRAPHREFLY-SPEC §7). Present only when versioning is enabled. */\n\tv?: { id: string; version: number; cid?: string; prev?: string | null };\n\t/** Guard info (full detail). */\n\tguard?: string;\n\t/** Last mutation attribution (full detail). */\n\tlastMutation?: Readonly<{ actor: Actor; timestamp_ns: number }>;\n};\n\n/**\n * Detail level for `describe()` progressive disclosure (Phase 3.3b).\n * - `\"minimal\"` — type + deps only (default). LLM-friendly.\n * - `\"standard\"` — type, status, value, deps, meta, versioning (`v`).\n * - `\"full\"` — standard + guard, lastMutation.\n */\nexport type DescribeDetail = \"minimal\" | \"standard\" | \"full\";\n\n/**\n * Valid field names for `describe({ fields: [...] })` (Phase 3.3b).\n * Dotted paths like `\"meta.label\"` select specific meta keys.\n */\nexport type DescribeField =\n\t| \"type\"\n\t| \"status\"\n\t| \"value\"\n\t| \"deps\"\n\t| \"meta\"\n\t| \"v\"\n\t| \"guard\"\n\t| \"lastMutation\"\n\t| `meta.${string}`;\n\n/** Resolve which fields to include based on detail level or explicit field list. */\nexport function resolveDescribeFields(\n\tdetail?: DescribeDetail,\n\tfields?: readonly DescribeField[],\n): Set<string> | null {\n\t// Explicit fields override detail level\n\tif (fields != null && fields.length > 0) return new Set(fields);\n\tswitch (detail) {\n\t\tcase \"standard\":\n\t\t\treturn new Set([\"type\", \"status\", \"value\", \"deps\", \"meta\", \"v\"]);\n\t\tcase \"full\":\n\t\t\treturn null; // null = include everything\n\t\tdefault:\n\t\t\treturn new Set([\"type\", \"deps\"]);\n\t}\n}\n\nfunction inferDescribeType(n: NodeImpl): DescribeNodeOutput[\"type\"] {\n\tif (n._describeKind != null) return n._describeKind;\n\tif (!n._hasDeps) return n._fn != null ? \"producer\" : \"state\";\n\tif (n._fn == null) return \"derived\";\n\tif (n._manualEmitUsed) return \"operator\";\n\treturn \"derived\";\n}\n\n/**\n * Reads the current cached value of every companion meta field on a node,\n * suitable for merging into `describe()`-style JSON (GRAPHREFLY-SPEC §2.3, §3.6).\n *\n * @remarks\n * Values come from {@link Node.get}, which returns the **last settled** cache.\n * If a meta field is in `\"dirty\"` status (DIRTY received, DATA pending), the\n * snapshot contains the *previous* value — check `node.meta[key].status` when\n * freshness matters. Avoid calling mid-batch for the same reason.\n *\n * Meta nodes are **not** terminated when their parent receives COMPLETE or\n * ERROR — they remain writable so callers can record post-mortem metadata\n * (e.g. `meta.error`). They *are* torn down when the parent receives TEARDOWN.\n *\n * @param node - The node whose meta fields to snapshot.\n * @returns Plain object of `{ key: value }` pairs (empty if no meta defined).\n * Keys whose companion node's {@link Node.get} throws are omitted.\n *\n * @example\n * ```ts\n * import { core } from \"@graphrefly/graphrefly-ts\";\n *\n * const n = core.node({ initial: 0, meta: { tag: \"a\" } });\n * core.metaSnapshot(n); // { tag: \"a\" }\n * ```\n */\n/** @internal Used by {@link describeNode} — not part of the public API. */\nexport function metaSnapshot(node: Node): Record<string, unknown> {\n\tconst out: Record<string, unknown> = {};\n\tfor (const [key, child] of Object.entries(node.meta)) {\n\t\ttry {\n\t\t\tout[key] = child.get();\n\t\t} catch {\n\t\t\t/* omit key — describe tooling still gets other fields */\n\t\t}\n\t}\n\treturn out;\n}\n\n/**\n * Builds a single-node slice of `Graph.describe()` JSON (structure + `meta` snapshot).\n * Parity with graphrefly-py `describe_node`.\n *\n * `type` is inferred from factory configuration, optional `describeKind` in node options,\n * and the last `manualEmitUsed` hint (operator vs derived). {@link effect} sets\n * `describeKind: \"effect\"`. Nodes not created by {@link node} fall back to `type: \"state\"` and empty `deps`.\n *\n * @param node - Any `Node` to introspect.\n * @returns `DescribeNodeOutput` suitable for merging into graph describe maps.\n *\n * @example\n * ```ts\n * import { describeNode, state } from \"@graphrefly/graphrefly-ts\";\n *\n * describeNode(state(0));\n * ```\n */\n/**\n * Builds a single-node slice for `Graph.describe()`.\n *\n * @param node - Node to introspect.\n * @param includeFields - Set of fields to include, or `null` for all. When omitted, all fields are included (legacy behavior).\n */\n/** @internal Used by {@link Graph.describe} — not part of the public API. */\nexport function describeNode(node: Node, includeFields?: Set<string> | null): DescribeNodeOutput {\n\tconst all = includeFields == null; // null or undefined → include everything\n\n\t// Specific meta keys requested via dotted paths (e.g. \"meta.label\")\n\tconst metaKeys: string[] | null =\n\t\t!all && includeFields != null\n\t\t\t? [...includeFields].filter((f) => f.startsWith(\"meta.\")).map((f) => f.slice(5))\n\t\t\t: null;\n\tconst wantsMeta = all || includeFields!.has(\"meta\") || (metaKeys != null && metaKeys.length > 0);\n\n\tlet type: DescribeNodeOutput[\"type\"] = \"state\";\n\tlet deps: string[] = [];\n\n\tif (node instanceof NodeImpl) {\n\t\ttype = inferDescribeType(node);\n\t\tdeps = node._deps.map((d) => d.name ?? \"\");\n\t} else if (node instanceof DynamicNodeImpl) {\n\t\ttype = node._describeKind ?? \"derived\";\n\t\tdeps = [];\n\t}\n\n\tconst out: DescribeNodeOutput = { type, deps };\n\n\t// status\n\tif (all || includeFields!.has(\"status\")) {\n\t\tout.status = node.status;\n\t}\n\n\t// Resolve guard once — used by both meta.access hint and standalone guard field\n\tconst guard =\n\t\t(node instanceof NodeImpl && node._guard) ||\n\t\t(node instanceof DynamicNodeImpl && node._guard) ||\n\t\tundefined;\n\n\t// meta\n\tif (wantsMeta) {\n\t\tconst rawMeta: Record<string, unknown> = { ...metaSnapshot(node) };\n\t\tif (guard != null && rawMeta.access === undefined) {\n\t\t\trawMeta.access = accessHintForGuard(guard);\n\t\t}\n\n\t\tif (metaKeys != null && metaKeys.length > 0 && !includeFields!.has(\"meta\")) {\n\t\t\t// Only specific meta keys\n\t\t\tconst filtered: Record<string, unknown> = {};\n\t\t\tfor (const k of metaKeys) {\n\t\t\t\tif (k in rawMeta) filtered[k] = rawMeta[k];\n\t\t\t}\n\t\t\tout.meta = filtered;\n\t\t} else {\n\t\t\tout.meta = rawMeta;\n\t\t}\n\t}\n\n\t// name (always include when present — it's identity, not detail)\n\tif (node.name != null) {\n\t\tout.name = node.name;\n\t}\n\n\t// value + sentinel indicator\n\tif (all || includeFields!.has(\"value\")) {\n\t\tconst isSentinel =\n\t\t\t(node instanceof NodeImpl && node._cached === NO_VALUE) ||\n\t\t\t(node instanceof DynamicNodeImpl && node._cached === NO_VALUE);\n\t\tif (isSentinel) {\n\t\t\tout.sentinel = true;\n\t\t}\n\t\ttry {\n\t\t\tout.value = node.get();\n\t\t} catch {\n\t\t\t/* omit value */\n\t\t}\n\t}\n\n\t// Versioning (GRAPHREFLY-SPEC §7)\n\tif ((all || includeFields!.has(\"v\")) && node.v != null) {\n\t\tconst vInfo: DescribeNodeOutput[\"v\"] = { id: node.v.id, version: node.v.version };\n\t\tif (\"cid\" in node.v) {\n\t\t\tvInfo!.cid = (node.v as { cid: string }).cid;\n\t\t\tvInfo!.prev = (node.v as { prev: string | null }).prev;\n\t\t}\n\t\tout.v = vInfo;\n\t}\n\n\t// Guard info (full detail)\n\tif (all || includeFields!.has(\"guard\")) {\n\t\tif (guard != null) {\n\t\t\tout.guard = accessHintForGuard(guard);\n\t\t}\n\t}\n\n\t// Last mutation attribution (full detail)\n\tif (all || includeFields!.has(\"lastMutation\")) {\n\t\tif (node.lastMutation != null) {\n\t\t\tout.lastMutation = node.lastMutation;\n\t\t}\n\t}\n\n\treturn out;\n}\n"],"mappings":"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","names":[]}
|