@prometheus-ags/entity-graph-core 4.2.0 → 4.4.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/CHANGELOG.md +39 -0
- package/README.md +64 -0
- package/dist/{chunk-64YZRB56.mjs → chunk-T5WSFBXH.mjs} +127 -93
- package/dist/chunk-T5WSFBXH.mjs.map +1 -0
- package/dist/devtools.d.ts +1 -1
- package/dist/devtools.mjs +1 -1
- package/dist/{graph-QfI6o5eV.d.ts → graph-BNIJRUzI.d.ts} +8 -0
- package/dist/index.d.ts +208 -18
- package/dist/index.mjs +394 -94
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-64YZRB56.mjs.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,44 @@
|
|
|
1
1
|
# @prometheus-ags/entity-graph-core
|
|
2
2
|
|
|
3
|
+
## 4.4.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- **Behavior change: the AG-UI bridge now deletes entities the agent removes
|
|
8
|
+
from its state.** In 4.3.0 such entities stayed in the graph. Only ids the
|
|
9
|
+
previous stored (or caller-supplied) state held at a mapped pointer are
|
|
10
|
+
removed; an id still held by another mapping of the same type is kept; a base
|
|
11
|
+
reconstructed from a pre-4.4.0 graph never removes anything.
|
|
12
|
+
|
|
13
|
+
- Streaming-store hardening for agentic UIs.
|
|
14
|
+
|
|
15
|
+
**Atomic batched writes without a graph copy.** New `batchGraphWrites(fn)`
|
|
16
|
+
applies any number of writes across entity types on one immer draft and
|
|
17
|
+
publishes once; a throw writes nothing. `applyGraphChanges(changes)` is its
|
|
18
|
+
serialisable, idempotent form. `createGraphTransaction` no longer
|
|
19
|
+
`structuredClone`s the whole graph when it opens: its rollback baseline is the
|
|
20
|
+
set of references to the current immutable state, so opening is O(1).
|
|
21
|
+
|
|
22
|
+
**Render-only live layer.** `createLiveLayer()` holds ephemeral field values
|
|
23
|
+
(streaming text) beside the graph: per-entity subscriptions, a merged
|
|
24
|
+
`read()`, and explicit `commit()` / `commitAll()` / `discard()`. Live values are
|
|
25
|
+
not graph writes, are not persisted and do not reach devtools.
|
|
26
|
+
|
|
27
|
+
**Lossless, ordered AG-UI bridge.** `applyAgUiSnapshot` / `applyAgUiDelta` now
|
|
28
|
+
store the whole agent state document (`readAgUiState`, so plain fields and
|
|
29
|
+
root pointers survive), keep collection order in a list (`agUiListKey`), apply
|
|
30
|
+
RFC 6902 `remove` / `replace` / `move` as entity removals and reorders, publish
|
|
31
|
+
once per event, never freeze the caller's event objects, and skip an `eventId`
|
|
32
|
+
that was already applied. Both functions now return `{ applied, state }`
|
|
33
|
+
instead of `void`.
|
|
34
|
+
|
|
35
|
+
**No devtools events in production browsers.** The transaction op-site stream
|
|
36
|
+
emitted in every browser bundle (`typeof process === "undefined" || ...`). It is
|
|
37
|
+
now off where `process` is absent unless Vite's `import.meta.env.DEV` is set or
|
|
38
|
+
`setGraphDevtoolsEmission(true)` is called; Node/SSR keep the
|
|
39
|
+
`NODE_ENV !== "production"` rule. Defining `__PROMETHEUS_ENTITY_GRAPH_DEVTOOLS__`
|
|
40
|
+
as `false` removes the emission code from bundles.
|
|
41
|
+
|
|
3
42
|
## 4.1.1
|
|
4
43
|
|
|
5
44
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -78,6 +78,70 @@ UI components should consume the hooks provided by their framework binding inste
|
|
|
78
78
|
|
|
79
79
|
The deprecated core `useGraphStore` name is a StoreApi-shaped alias for `graphStore`, not a React hook. React consumers import the callable `useGraphStore(selector)` hook from `@prometheus-ags/prometheus-entity-management`. See the repository's `release/framework-neutral-core.md` migration contract for the complete boundary.
|
|
80
80
|
|
|
81
|
+
## Streaming agent state
|
|
82
|
+
|
|
83
|
+
Four primitives keep a store usable at token rate (all since 4.4.0):
|
|
84
|
+
|
|
85
|
+
```ts
|
|
86
|
+
import {
|
|
87
|
+
applyAgUiDelta,
|
|
88
|
+
applyAgUiSnapshot,
|
|
89
|
+
applyGraphChanges,
|
|
90
|
+
batchGraphWrites,
|
|
91
|
+
createLiveLayer,
|
|
92
|
+
readAgUiState,
|
|
93
|
+
} from "@prometheus-ags/entity-graph-core";
|
|
94
|
+
|
|
95
|
+
// 1. Many writes, one notification, no graph copy. A throw writes nothing.
|
|
96
|
+
batchGraphWrites((batch) => {
|
|
97
|
+
batch.upsertEntity("Message", "m1", { id: "m1", status: "done" });
|
|
98
|
+
batch.upsertEntity("ToolCall", "t1", { id: "t1", status: "running" });
|
|
99
|
+
batch.insertIdInList("thread:messages", "m1", "end");
|
|
100
|
+
});
|
|
101
|
+
// The same thing as data (journal, replay); idempotent with the default merge.
|
|
102
|
+
applyGraphChanges([{ op: "remove", type: "Message", id: "draft" }]);
|
|
103
|
+
|
|
104
|
+
// 2. Render-only live values: not graph writes, not persisted, not in devtools.
|
|
105
|
+
const live = createLiveLayer();
|
|
106
|
+
live.append("Message", "m1", "text", token); // per token
|
|
107
|
+
live.subscribe("Message", "m1", render); // live + durable changes
|
|
108
|
+
live.read("Message", "m1"); // durable entity + live fields
|
|
109
|
+
live.commit("Message", "m1"); // one durable write
|
|
110
|
+
|
|
111
|
+
// 3. Lossless AG-UI state: plain fields, order and removals are kept.
|
|
112
|
+
applyAgUiSnapshot({ snapshot }, { mappings, eventId: "41" });
|
|
113
|
+
applyAgUiDelta({ delta }, { mappings, eventId: "42" }); // a replayed id is skipped
|
|
114
|
+
readAgUiState(); // the whole agent state document
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
`createGraphTransaction` no longer copies the graph when it opens (rollback
|
|
118
|
+
restores references to the immutable previous state). Collection mappings keep
|
|
119
|
+
their order in the list `agUiListKey(mapping)`; items that leave a mapped slice
|
|
120
|
+
are removed. Only ids that the previous agent state held at that pointer are
|
|
121
|
+
removed. Written values are adopted and deep-frozen by the store, so if your
|
|
122
|
+
code keeps mutating an object, write a `structuredClone` of it. The AG-UI bridge
|
|
123
|
+
copies its input for you.
|
|
124
|
+
|
|
125
|
+
Persisting with `persistGraphToStorage` and hydrating with
|
|
126
|
+
`hydrateGraphFromStorage` round-trips the AG-UI document, its order lists and
|
|
127
|
+
its applied event ids, so a transport that replays after a reload does not
|
|
128
|
+
apply the same delta twice. Live values are not persisted. Commit them before a
|
|
129
|
+
checkpoint if they must survive.
|
|
130
|
+
|
|
131
|
+
### DevTools events in production
|
|
132
|
+
|
|
133
|
+
The deprecated `subscribeDevtoolsEvent` stream fed by graph transactions emits
|
|
134
|
+
only where `process` exists and `NODE_ENV !== "production"`, or in a browser
|
|
135
|
+
under Vite's `import.meta.env.DEV`. Plain browser production bundles emit
|
|
136
|
+
nothing. To enable or disable it at runtime, call
|
|
137
|
+
`setGraphDevtoolsEmission(true | false)`. To remove the code from a bundle,
|
|
138
|
+
define `__PROMETHEUS_ENTITY_GRAPH_DEVTOOLS__` as `false`:
|
|
139
|
+
|
|
140
|
+
```ts
|
|
141
|
+
// vite.config.ts
|
|
142
|
+
export default { define: { __PROMETHEUS_ENTITY_GRAPH_DEVTOOLS__: "false" } };
|
|
143
|
+
```
|
|
144
|
+
|
|
81
145
|
## Optional Loro merge strategy
|
|
82
146
|
|
|
83
147
|
`loro-crdt` remains an optional peer. Node consumers can let core load it at
|
|
@@ -158,6 +158,105 @@ function getNestedValue(obj, path) {
|
|
|
158
158
|
}
|
|
159
159
|
return current;
|
|
160
160
|
}
|
|
161
|
+
|
|
162
|
+
// src/graph-mutators.ts
|
|
163
|
+
function entityKey(type, id) {
|
|
164
|
+
return `${type}:${id}`;
|
|
165
|
+
}
|
|
166
|
+
function defaultSyncMetadata() {
|
|
167
|
+
return { synced: true, origin: "server", updatedAt: null };
|
|
168
|
+
}
|
|
169
|
+
function defaultListState() {
|
|
170
|
+
return {
|
|
171
|
+
ids: [],
|
|
172
|
+
total: null,
|
|
173
|
+
nextCursor: null,
|
|
174
|
+
prevCursor: null,
|
|
175
|
+
hasNextPage: false,
|
|
176
|
+
hasPrevPage: false,
|
|
177
|
+
isFetching: false,
|
|
178
|
+
isFetchingMore: false,
|
|
179
|
+
error: null,
|
|
180
|
+
lastError: null,
|
|
181
|
+
lastFetched: null,
|
|
182
|
+
stale: false,
|
|
183
|
+
currentPage: null,
|
|
184
|
+
pageSize: null
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
function upsertEntityDraft(s, type, id, data) {
|
|
188
|
+
if (!s.entities[type]) s.entities[type] = {};
|
|
189
|
+
const key = entityKey(type, id);
|
|
190
|
+
const strategy = getMergeStrategy(type);
|
|
191
|
+
const ctx = { type, id, origin: s.syncMetadata[key]?.origin ?? "server", updatedAt: Date.now() };
|
|
192
|
+
s.entities[type][id] = strategy(s.entities[type][id], data, ctx);
|
|
193
|
+
if (!s.syncMetadata[key]) s.syncMetadata[key] = defaultSyncMetadata();
|
|
194
|
+
}
|
|
195
|
+
function upsertEntitiesDraft(s, type, entries) {
|
|
196
|
+
if (!s.entities[type]) s.entities[type] = {};
|
|
197
|
+
const strategy = getMergeStrategy(type);
|
|
198
|
+
for (const { id, data } of entries) {
|
|
199
|
+
const key = entityKey(type, id);
|
|
200
|
+
const ctx = { type, id, origin: s.syncMetadata[key]?.origin ?? "server", updatedAt: Date.now() };
|
|
201
|
+
s.entities[type][id] = strategy(s.entities[type][id], data, ctx);
|
|
202
|
+
if (!s.syncMetadata[key]) s.syncMetadata[key] = defaultSyncMetadata();
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
function replaceEntityDraft(s, type, id, data) {
|
|
206
|
+
if (!s.entities[type]) s.entities[type] = {};
|
|
207
|
+
s.entities[type][id] = data;
|
|
208
|
+
const key = entityKey(type, id);
|
|
209
|
+
if (!s.syncMetadata[key]) s.syncMetadata[key] = defaultSyncMetadata();
|
|
210
|
+
}
|
|
211
|
+
function removeEntityDraft(s, type, id) {
|
|
212
|
+
delete s.entities[type]?.[id];
|
|
213
|
+
delete s.patches[type]?.[id];
|
|
214
|
+
delete s.entityStates[entityKey(type, id)];
|
|
215
|
+
delete s.syncMetadata[entityKey(type, id)];
|
|
216
|
+
}
|
|
217
|
+
function patchEntityDraft(s, type, id, patch) {
|
|
218
|
+
if (!s.patches[type]) s.patches[type] = {};
|
|
219
|
+
s.patches[type][id] = { ...s.patches[type][id] ?? {}, ...patch };
|
|
220
|
+
}
|
|
221
|
+
function unpatchEntityDraft(s, type, id, keys) {
|
|
222
|
+
const p = s.patches[type]?.[id];
|
|
223
|
+
if (!p) return;
|
|
224
|
+
for (const k of keys) delete p[k];
|
|
225
|
+
}
|
|
226
|
+
function clearPatchDraft(s, type, id) {
|
|
227
|
+
delete s.patches[type]?.[id];
|
|
228
|
+
}
|
|
229
|
+
function setEntitySyncMetadataDraft(s, type, id, metadata) {
|
|
230
|
+
const k = entityKey(type, id);
|
|
231
|
+
s.syncMetadata[k] = { ...s.syncMetadata[k] ?? defaultSyncMetadata(), ...metadata };
|
|
232
|
+
}
|
|
233
|
+
function removeIdFromAllListsDraft(s, type, id) {
|
|
234
|
+
for (const key of Object.keys(s.lists)) {
|
|
235
|
+
const list = s.lists[key];
|
|
236
|
+
if (list.entityType && list.entityType !== type) continue;
|
|
237
|
+
const idx = list.ids.indexOf(id);
|
|
238
|
+
if (idx !== -1) {
|
|
239
|
+
list.ids.splice(idx, 1);
|
|
240
|
+
if (list.total !== null) list.total -= 1;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
function insertIdInListDraft(s, key, id, position) {
|
|
245
|
+
if (!s.lists[key]) s.lists[key] = defaultListState();
|
|
246
|
+
const ids = s.lists[key].ids;
|
|
247
|
+
const ex = ids.indexOf(id);
|
|
248
|
+
if (ex !== -1) ids.splice(ex, 1);
|
|
249
|
+
if (position === "start") ids.unshift(id);
|
|
250
|
+
else if (position === "end") ids.push(id);
|
|
251
|
+
else ids.splice(position, 0, id);
|
|
252
|
+
}
|
|
253
|
+
function setListIdsDraft(s, key, ids, entityType) {
|
|
254
|
+
if (!s.lists[key]) s.lists[key] = defaultListState();
|
|
255
|
+
s.lists[key].ids = Array.from(new Set(ids));
|
|
256
|
+
if (entityType !== void 0) s.lists[key].entityType = entityType;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
// src/graph.ts
|
|
161
260
|
var EMPTY_IDS = [];
|
|
162
261
|
var EMPTY_ENTITY_STATE = {
|
|
163
262
|
isFetching: false,
|
|
@@ -189,19 +288,10 @@ var EMPTY_LIST_STATE = {
|
|
|
189
288
|
function defaultEntityState() {
|
|
190
289
|
return { ...EMPTY_ENTITY_STATE };
|
|
191
290
|
}
|
|
192
|
-
function defaultSyncMetadata() {
|
|
193
|
-
return { ...EMPTY_SYNC_METADATA };
|
|
194
|
-
}
|
|
195
|
-
function defaultListState() {
|
|
196
|
-
return { ...EMPTY_LIST_STATE, ids: [] };
|
|
197
|
-
}
|
|
198
|
-
function ek(type, id) {
|
|
199
|
-
return `${type}:${id}`;
|
|
200
|
-
}
|
|
201
291
|
var snapshotCache = /* @__PURE__ */ new Map();
|
|
202
292
|
var mergedReadCache = /* @__PURE__ */ new Map();
|
|
203
293
|
function readCachedEntitySnapshot(type, id, base, patch, metadata) {
|
|
204
|
-
const key =
|
|
294
|
+
const key = entityKey(type, id);
|
|
205
295
|
const cached = snapshotCache.get(key);
|
|
206
296
|
if (cached && cached.base === base && cached.patch === patch && cached.metadata === metadata) {
|
|
207
297
|
return cached.snapshot;
|
|
@@ -224,24 +314,8 @@ function createGraphStore() {
|
|
|
224
314
|
entityStates: {},
|
|
225
315
|
syncMetadata: {},
|
|
226
316
|
lists: {},
|
|
227
|
-
upsertEntity: (type, id, data) => set((s) =>
|
|
228
|
-
|
|
229
|
-
const key = ek(type, id);
|
|
230
|
-
const strategy = getMergeStrategy(type);
|
|
231
|
-
const ctx = { type, id, origin: s.syncMetadata[key]?.origin ?? "server", updatedAt: Date.now() };
|
|
232
|
-
s.entities[type][id] = strategy(s.entities[type][id], data, ctx);
|
|
233
|
-
if (!s.syncMetadata[key]) s.syncMetadata[key] = defaultSyncMetadata();
|
|
234
|
-
}),
|
|
235
|
-
upsertEntities: (type, entries) => set((s) => {
|
|
236
|
-
if (!s.entities[type]) s.entities[type] = {};
|
|
237
|
-
const strategy = getMergeStrategy(type);
|
|
238
|
-
for (const { id, data } of entries) {
|
|
239
|
-
const key = ek(type, id);
|
|
240
|
-
const ctx = { type, id, origin: s.syncMetadata[key]?.origin ?? "server", updatedAt: Date.now() };
|
|
241
|
-
s.entities[type][id] = strategy(s.entities[type][id], data, ctx);
|
|
242
|
-
if (!s.syncMetadata[key]) s.syncMetadata[key] = defaultSyncMetadata();
|
|
243
|
-
}
|
|
244
|
-
}),
|
|
317
|
+
upsertEntity: (type, id, data) => set((s) => upsertEntityDraft(s, type, id, data)),
|
|
318
|
+
upsertEntities: (type, entries) => set((s) => upsertEntitiesDraft(s, type, entries)),
|
|
245
319
|
ingestFetchedList: (type, entries, options = {}) => set((s) => {
|
|
246
320
|
const fetchedAt = Date.now();
|
|
247
321
|
const ids = entries.map(({ id }) => id);
|
|
@@ -253,7 +327,7 @@ function createGraphStore() {
|
|
|
253
327
|
for (const batch of batches) {
|
|
254
328
|
if (!s.entities[batch.type]) s.entities[batch.type] = {};
|
|
255
329
|
for (const { id } of batch.entries) {
|
|
256
|
-
const key =
|
|
330
|
+
const key = entityKey(batch.type, id);
|
|
257
331
|
if (!origins.has(key)) {
|
|
258
332
|
origins.set(key, s.syncMetadata[key]?.origin ?? "server");
|
|
259
333
|
}
|
|
@@ -262,7 +336,7 @@ function createGraphStore() {
|
|
|
262
336
|
for (const batch of batches) {
|
|
263
337
|
const strategy = getMergeStrategy(batch.type);
|
|
264
338
|
for (const { id, data } of batch.entries) {
|
|
265
|
-
const key =
|
|
339
|
+
const key = entityKey(batch.type, id);
|
|
266
340
|
const ctx = {
|
|
267
341
|
type: batch.type,
|
|
268
342
|
id,
|
|
@@ -275,7 +349,7 @@ function createGraphStore() {
|
|
|
275
349
|
const completed = /* @__PURE__ */ new Set();
|
|
276
350
|
for (const batch of batches) {
|
|
277
351
|
for (const { id } of batch.entries) {
|
|
278
|
-
const key =
|
|
352
|
+
const key = entityKey(batch.type, id);
|
|
279
353
|
if (completed.has(key)) continue;
|
|
280
354
|
completed.add(key);
|
|
281
355
|
if (!s.entityStates[key]) s.entityStates[key] = defaultEntityState();
|
|
@@ -295,7 +369,7 @@ function createGraphStore() {
|
|
|
295
369
|
const base = s.entities[type]?.[id];
|
|
296
370
|
if (!base) return null;
|
|
297
371
|
const patch = s.patches[type]?.[id];
|
|
298
|
-
const metadata = s.syncMetadata[
|
|
372
|
+
const metadata = s.syncMetadata[entityKey(type, id)] ?? defaultSyncMetadata();
|
|
299
373
|
return {
|
|
300
374
|
...base,
|
|
301
375
|
...patch ?? {},
|
|
@@ -355,43 +429,24 @@ function createGraphStore() {
|
|
|
355
429
|
s.lists[key].isFetching = false;
|
|
356
430
|
}
|
|
357
431
|
}),
|
|
358
|
-
replaceEntity: (type, id, data) => set((s) =>
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
}),
|
|
364
|
-
removeEntity: (type, id) => set((s) => {
|
|
365
|
-
delete s.entities[type]?.[id];
|
|
366
|
-
delete s.patches[type]?.[id];
|
|
367
|
-
delete s.entityStates[ek(type, id)];
|
|
368
|
-
delete s.syncMetadata[ek(type, id)];
|
|
369
|
-
}),
|
|
370
|
-
patchEntity: (type, id, patch) => set((s) => {
|
|
371
|
-
if (!s.patches[type]) s.patches[type] = {};
|
|
372
|
-
s.patches[type][id] = { ...s.patches[type][id] ?? {}, ...patch };
|
|
373
|
-
}),
|
|
374
|
-
unpatchEntity: (type, id, keys) => set((s) => {
|
|
375
|
-
const p = s.patches[type]?.[id];
|
|
376
|
-
if (!p) return;
|
|
377
|
-
for (const k of keys) delete p[k];
|
|
378
|
-
}),
|
|
379
|
-
clearPatch: (type, id) => set((s) => {
|
|
380
|
-
delete s.patches[type]?.[id];
|
|
381
|
-
}),
|
|
432
|
+
replaceEntity: (type, id, data) => set((s) => replaceEntityDraft(s, type, id, data)),
|
|
433
|
+
removeEntity: (type, id) => set((s) => removeEntityDraft(s, type, id)),
|
|
434
|
+
patchEntity: (type, id, patch) => set((s) => patchEntityDraft(s, type, id, patch)),
|
|
435
|
+
unpatchEntity: (type, id, keys) => set((s) => unpatchEntityDraft(s, type, id, keys)),
|
|
436
|
+
clearPatch: (type, id) => set((s) => clearPatchDraft(s, type, id)),
|
|
382
437
|
setEntityFetching: (type, id, fetching) => set((s) => {
|
|
383
|
-
const k =
|
|
438
|
+
const k = entityKey(type, id);
|
|
384
439
|
if (!s.entityStates[k]) s.entityStates[k] = defaultEntityState();
|
|
385
440
|
s.entityStates[k].isFetching = fetching;
|
|
386
441
|
}),
|
|
387
442
|
setEntityError: (type, id, error) => set((s) => {
|
|
388
|
-
const k =
|
|
443
|
+
const k = entityKey(type, id);
|
|
389
444
|
if (!s.entityStates[k]) s.entityStates[k] = defaultEntityState();
|
|
390
445
|
s.entityStates[k].error = error;
|
|
391
446
|
s.entityStates[k].isFetching = false;
|
|
392
447
|
}),
|
|
393
448
|
setEntityFetched: (type, id) => set((s) => {
|
|
394
|
-
const k =
|
|
449
|
+
const k = entityKey(type, id);
|
|
395
450
|
if (!s.entityStates[k]) s.entityStates[k] = defaultEntityState();
|
|
396
451
|
s.entityStates[k].lastFetched = Date.now();
|
|
397
452
|
s.entityStates[k].isFetching = false;
|
|
@@ -400,16 +455,13 @@ function createGraphStore() {
|
|
|
400
455
|
s.syncMetadata[k] = { ...s.syncMetadata[k] ?? defaultSyncMetadata(), synced: true, origin: "server", updatedAt: Date.now() };
|
|
401
456
|
}),
|
|
402
457
|
setEntityStale: (type, id, stale) => set((s) => {
|
|
403
|
-
const k =
|
|
458
|
+
const k = entityKey(type, id);
|
|
404
459
|
if (!s.entityStates[k]) s.entityStates[k] = defaultEntityState();
|
|
405
460
|
s.entityStates[k].stale = stale;
|
|
406
461
|
}),
|
|
407
|
-
setEntitySyncMetadata: (type, id, metadata) => set((s) =>
|
|
408
|
-
const k = ek(type, id);
|
|
409
|
-
s.syncMetadata[k] = { ...s.syncMetadata[k] ?? defaultSyncMetadata(), ...metadata };
|
|
410
|
-
}),
|
|
462
|
+
setEntitySyncMetadata: (type, id, metadata) => set((s) => setEntitySyncMetadataDraft(s, type, id, metadata)),
|
|
411
463
|
clearEntitySyncMetadata: (type, id) => set((s) => {
|
|
412
|
-
delete s.syncMetadata[
|
|
464
|
+
delete s.syncMetadata[entityKey(type, id)];
|
|
413
465
|
}),
|
|
414
466
|
setListResult: (key, ids, meta) => set((s) => {
|
|
415
467
|
const ex = s.lists[key] ?? defaultListState();
|
|
@@ -423,26 +475,8 @@ function createGraphStore() {
|
|
|
423
475
|
const ex = s.lists[key] ?? defaultListState();
|
|
424
476
|
s.lists[key] = { ...ex, ...meta ?? {}, ids: Array.from(/* @__PURE__ */ new Set([...ids, ...ex.ids])), isFetching: false, isFetchingMore: false, error: null, lastError: null, stale: false, lastFetched: Date.now() };
|
|
425
477
|
}),
|
|
426
|
-
removeIdFromAllLists: (type, id) => set((s) =>
|
|
427
|
-
|
|
428
|
-
const list = s.lists[key];
|
|
429
|
-
if (list.entityType && list.entityType !== type) continue;
|
|
430
|
-
const idx = list.ids.indexOf(id);
|
|
431
|
-
if (idx !== -1) {
|
|
432
|
-
list.ids.splice(idx, 1);
|
|
433
|
-
if (list.total !== null) list.total -= 1;
|
|
434
|
-
}
|
|
435
|
-
}
|
|
436
|
-
}),
|
|
437
|
-
insertIdInList: (key, id, position) => set((s) => {
|
|
438
|
-
if (!s.lists[key]) s.lists[key] = defaultListState();
|
|
439
|
-
const ids = s.lists[key].ids;
|
|
440
|
-
const ex = ids.indexOf(id);
|
|
441
|
-
if (ex !== -1) ids.splice(ex, 1);
|
|
442
|
-
if (position === "start") ids.unshift(id);
|
|
443
|
-
else if (position === "end") ids.push(id);
|
|
444
|
-
else ids.splice(position, 0, id);
|
|
445
|
-
}),
|
|
478
|
+
removeIdFromAllLists: (type, id) => set((s) => removeIdFromAllListsDraft(s, type, id)),
|
|
479
|
+
insertIdInList: (key, id, position) => set((s) => insertIdInListDraft(s, key, id, position)),
|
|
446
480
|
setListFetching: (key, fetching) => set((s) => {
|
|
447
481
|
if (!s.lists[key]) s.lists[key] = defaultListState();
|
|
448
482
|
s.lists[key].isFetching = fetching;
|
|
@@ -466,7 +500,7 @@ function createGraphStore() {
|
|
|
466
500
|
}),
|
|
467
501
|
invalidateEntity: (type, id) => set((s) => {
|
|
468
502
|
if (id) {
|
|
469
|
-
const k =
|
|
503
|
+
const k = entityKey(type, id);
|
|
470
504
|
if (s.entityStates[k]) s.entityStates[k].stale = true;
|
|
471
505
|
} else {
|
|
472
506
|
for (const k of Object.keys(s.entityStates)) if (k.startsWith(`${type}:`)) s.entityStates[k].stale = true;
|
|
@@ -484,12 +518,12 @@ function createGraphStore() {
|
|
|
484
518
|
const s = get();
|
|
485
519
|
const base = s.entities[type]?.[id];
|
|
486
520
|
if (!base) {
|
|
487
|
-
mergedReadCache.delete(
|
|
521
|
+
mergedReadCache.delete(entityKey(type, id));
|
|
488
522
|
return null;
|
|
489
523
|
}
|
|
490
524
|
const patch = s.patches[type]?.[id];
|
|
491
525
|
if (!patch) return base;
|
|
492
|
-
const key =
|
|
526
|
+
const key = entityKey(type, id);
|
|
493
527
|
const cached = mergedReadCache.get(key);
|
|
494
528
|
if (cached && cached.base === base && cached.patch === patch) {
|
|
495
529
|
return cached.merged;
|
|
@@ -502,11 +536,11 @@ function createGraphStore() {
|
|
|
502
536
|
const s = get();
|
|
503
537
|
const base = s.entities[type]?.[id];
|
|
504
538
|
if (!base) {
|
|
505
|
-
snapshotCache.delete(
|
|
539
|
+
snapshotCache.delete(entityKey(type, id));
|
|
506
540
|
return null;
|
|
507
541
|
}
|
|
508
542
|
const patch = s.patches[type]?.[id];
|
|
509
|
-
const metadata = s.syncMetadata[
|
|
543
|
+
const metadata = s.syncMetadata[entityKey(type, id)] ?? EMPTY_SYNC_METADATA;
|
|
510
544
|
return readCachedEntitySnapshot(
|
|
511
545
|
type,
|
|
512
546
|
id,
|
|
@@ -959,6 +993,6 @@ function subscribeGraphDevtoolsCompatibility(store, listener) {
|
|
|
959
993
|
};
|
|
960
994
|
}
|
|
961
995
|
|
|
962
|
-
export { EMPTY_ENTITY_STATE, EMPTY_IDS, EMPTY_LIST_STATE, EMPTY_SYNC_METADATA, __require, applyView, attachGlobalListeners, cascadeInvalidation, checkCompleteness, compareEntities, configureEngine, createGraphStore, dedupe, emitLegacyDevtoolsEvent, fetchEntity, fetchList, findInsertionIndex, getActiveSubscriberCount, getEngineOptions, getGraphDevtoolsCompatibilityDelegate, getMergeStrategy, getRegisteredSchemas, getSchema, graphStore, hasMergeStrategy, lwwStrategy, matchesFilter, matchesSearch, readRelations, registerGraphDevtoolsCompatibilityDelegate, registerGraphDevtoolsCompatibilityFactory, registerMergeStrategy, registerSchema, registerSubscriber, serializeKey, setDefaultMergeStrategy, startGarbageCollector, stopGarbageCollector, subscribeDevtoolsEvent, subscribeGraphDevtoolsCompatibility, subscribeSubscriberStats, unregisterSubscriber, useGraphStore };
|
|
963
|
-
//# sourceMappingURL=chunk-
|
|
964
|
-
//# sourceMappingURL=chunk-
|
|
996
|
+
export { EMPTY_ENTITY_STATE, EMPTY_IDS, EMPTY_LIST_STATE, EMPTY_SYNC_METADATA, __require, applyView, attachGlobalListeners, cascadeInvalidation, checkCompleteness, clearPatchDraft, compareEntities, configureEngine, createGraphStore, dedupe, emitLegacyDevtoolsEvent, fetchEntity, fetchList, findInsertionIndex, getActiveSubscriberCount, getEngineOptions, getGraphDevtoolsCompatibilityDelegate, getMergeStrategy, getRegisteredSchemas, getSchema, graphStore, hasMergeStrategy, insertIdInListDraft, lwwStrategy, matchesFilter, matchesSearch, patchEntityDraft, readRelations, registerGraphDevtoolsCompatibilityDelegate, registerGraphDevtoolsCompatibilityFactory, registerMergeStrategy, registerSchema, registerSubscriber, removeEntityDraft, removeIdFromAllListsDraft, replaceEntityDraft, serializeKey, setDefaultMergeStrategy, setEntitySyncMetadataDraft, setListIdsDraft, startGarbageCollector, stopGarbageCollector, subscribeDevtoolsEvent, subscribeGraphDevtoolsCompatibility, subscribeSubscriberStats, unpatchEntityDraft, unregisterSubscriber, upsertEntitiesDraft, upsertEntityDraft, useGraphStore };
|
|
997
|
+
//# sourceMappingURL=chunk-T5WSFBXH.mjs.map
|
|
998
|
+
//# sourceMappingURL=chunk-T5WSFBXH.mjs.map
|