@prometheus-ags/entity-graph-core 3.0.4 → 3.1.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 +30 -0
- package/README.md +248 -0
- package/dist/chunk-BE3BMRKF.mjs +938 -0
- package/dist/chunk-BE3BMRKF.mjs.map +1 -0
- package/dist/devtools.cjs +2561 -0
- package/dist/devtools.cjs.map +1 -0
- package/dist/devtools.d.cts +531 -0
- package/dist/devtools.d.ts +531 -0
- package/dist/devtools.mjs +2019 -0
- package/dist/devtools.mjs.map +1 -0
- package/dist/graph-ClW3HD8B.d.cts +990 -0
- package/dist/graph-ClW3HD8B.d.ts +990 -0
- package/dist/index.cjs +572 -448
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +131 -1059
- package/dist/index.d.ts +131 -1059
- package/dist/index.mjs +127 -910
- package/dist/index.mjs.map +1 -1
- package/fixtures/devtools/README.md +37 -0
- package/fixtures/devtools/entity-inspection-v1.json +304 -0
- package/fixtures/devtools/time-travel-v1.json +110 -0
- package/package.json +25 -1
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import { graphStore, useGraphStore, subscribeDevtoolsEvent, getGraphDevtoolsCompatibilityDelegate, subscribeGraphDevtoolsCompatibility, matchesFilter, matchesSearch, compareEntities, emitLegacyDevtoolsEvent, __require } from './chunk-BE3BMRKF.mjs';
|
|
2
|
+
export { EMPTY_ENTITY_STATE, EMPTY_IDS, EMPTY_LIST_STATE, EMPTY_SYNC_METADATA, applyView, attachGlobalListeners, cascadeInvalidation, checkCompleteness, compareEntities, configureEngine, createGraphStore, dedupe, fetchEntity, fetchList, findInsertionIndex, getActiveSubscriberCount, getEngineOptions, getMergeStrategy, getSchema, graphStore, hasMergeStrategy, lwwStrategy, matchesFilter, matchesSearch, readRelations, registerMergeStrategy, registerSchema, registerSubscriber, serializeKey, setDefaultMergeStrategy, startGarbageCollector, stopGarbageCollector, subscribeDevtoolsEvent, subscribeSubscriberStats, unregisterSubscriber, useGraphStore } from './chunk-BE3BMRKF.mjs';
|
|
1
3
|
import { createStore } from 'zustand/vanilla';
|
|
2
|
-
import { subscribeWithSelector } from 'zustand/middleware';
|
|
3
|
-
import { immer } from 'zustand/middleware/immer';
|
|
4
4
|
|
|
5
5
|
// src/errors.ts
|
|
6
6
|
var TerminalError = class _TerminalError extends Error {
|
|
@@ -68,6 +68,88 @@ function getRegisteredEntityTypes() {
|
|
|
68
68
|
return Array.from(transports.keys());
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
+
// src/active-store.ts
|
|
72
|
+
var moduleActiveStore = null;
|
|
73
|
+
var asyncScope = null;
|
|
74
|
+
var asyncScopeAttempted = false;
|
|
75
|
+
function isNodeLike() {
|
|
76
|
+
return typeof process !== "undefined" && typeof process.versions?.node === "string";
|
|
77
|
+
}
|
|
78
|
+
function resolveAsyncScope() {
|
|
79
|
+
if (asyncScopeAttempted) return asyncScope;
|
|
80
|
+
asyncScopeAttempted = true;
|
|
81
|
+
if (!isNodeLike()) return null;
|
|
82
|
+
try {
|
|
83
|
+
const req = typeof module !== "undefined" && typeof module.require === "function" ? module.require : typeof __require === "function" ? __require : null;
|
|
84
|
+
if (!req) return null;
|
|
85
|
+
const { AsyncLocalStorage } = req("node:async_hooks");
|
|
86
|
+
asyncScope = new AsyncLocalStorage();
|
|
87
|
+
} catch {
|
|
88
|
+
asyncScope = null;
|
|
89
|
+
}
|
|
90
|
+
return asyncScope;
|
|
91
|
+
}
|
|
92
|
+
async function prepareGraphStoreScope() {
|
|
93
|
+
if (asyncScope) return true;
|
|
94
|
+
if (!isNodeLike()) {
|
|
95
|
+
asyncScopeAttempted = true;
|
|
96
|
+
return false;
|
|
97
|
+
}
|
|
98
|
+
if (resolveAsyncScope()) return true;
|
|
99
|
+
try {
|
|
100
|
+
const specifier = "node:async_hooks";
|
|
101
|
+
const mod = await import(
|
|
102
|
+
/* @vite-ignore */
|
|
103
|
+
specifier
|
|
104
|
+
);
|
|
105
|
+
asyncScope = new mod.AsyncLocalStorage();
|
|
106
|
+
asyncScopeAttempted = true;
|
|
107
|
+
return true;
|
|
108
|
+
} catch {
|
|
109
|
+
asyncScopeAttempted = true;
|
|
110
|
+
return false;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
function setActiveGraphStore(store) {
|
|
114
|
+
const previous = moduleActiveStore;
|
|
115
|
+
moduleActiveStore = store;
|
|
116
|
+
return () => {
|
|
117
|
+
moduleActiveStore = previous;
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
var warnedUnscopedFallback = false;
|
|
121
|
+
function warnUnscopedRequestFallback() {
|
|
122
|
+
if (warnedUnscopedFallback || !isNodeLike()) return;
|
|
123
|
+
warnedUnscopedFallback = true;
|
|
124
|
+
console.warn(
|
|
125
|
+
"[entity-graph-core] runWithGraphStore() could not load node:async_hooks, so it fell back to a module-level store. Concurrent requests will NOT be isolated. Await prepareGraphStoreScope() once during server startup."
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
function runWithGraphStore(store, fn) {
|
|
129
|
+
const scope = resolveAsyncScope();
|
|
130
|
+
if (!scope) {
|
|
131
|
+
warnUnscopedRequestFallback();
|
|
132
|
+
const restore = setActiveGraphStore(store);
|
|
133
|
+
try {
|
|
134
|
+
return fn();
|
|
135
|
+
} finally {
|
|
136
|
+
restore();
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return scope.run(store, fn);
|
|
140
|
+
}
|
|
141
|
+
function resolveActiveGraphStore(fallback) {
|
|
142
|
+
const scoped = resolveAsyncScope()?.getStore();
|
|
143
|
+
if (scoped) return scoped;
|
|
144
|
+
return moduleActiveStore ?? fallback;
|
|
145
|
+
}
|
|
146
|
+
function __resetActiveGraphStore() {
|
|
147
|
+
moduleActiveStore = null;
|
|
148
|
+
asyncScope = null;
|
|
149
|
+
asyncScopeAttempted = false;
|
|
150
|
+
warnedUnscopedFallback = false;
|
|
151
|
+
}
|
|
152
|
+
|
|
71
153
|
// src/view/prisma-compile.ts
|
|
72
154
|
function nestWhereField(parts, leaf) {
|
|
73
155
|
if (parts.length === 0) return {};
|
|
@@ -405,506 +487,6 @@ function mapPostgrestError(error, status) {
|
|
|
405
487
|
return toEntityError(error);
|
|
406
488
|
}
|
|
407
489
|
|
|
408
|
-
// src/merge/lww.ts
|
|
409
|
-
var lwwStrategy = (prev, next) => {
|
|
410
|
-
return prev ? { ...prev, ...next } : { ...next };
|
|
411
|
-
};
|
|
412
|
-
|
|
413
|
-
// src/merge/registry.ts
|
|
414
|
-
var byType = /* @__PURE__ */ new Map();
|
|
415
|
-
var globalDefault = null;
|
|
416
|
-
function registerMergeStrategy(type, strategy) {
|
|
417
|
-
byType.set(type, strategy);
|
|
418
|
-
}
|
|
419
|
-
function setDefaultMergeStrategy(strategy) {
|
|
420
|
-
globalDefault = strategy;
|
|
421
|
-
}
|
|
422
|
-
function getMergeStrategy(type) {
|
|
423
|
-
return byType.get(type) ?? globalDefault ?? lwwStrategy;
|
|
424
|
-
}
|
|
425
|
-
function hasMergeStrategy(type) {
|
|
426
|
-
return byType.has(type) || globalDefault !== null;
|
|
427
|
-
}
|
|
428
|
-
|
|
429
|
-
// src/view/evaluator.ts
|
|
430
|
-
function matchesFilter(entity, filter) {
|
|
431
|
-
if (Array.isArray(filter)) return filter.every((clause) => matchesClause(entity, clause));
|
|
432
|
-
return matchesGroup(entity, filter);
|
|
433
|
-
}
|
|
434
|
-
function matchesGroup(entity, group) {
|
|
435
|
-
const { logic, clauses } = group;
|
|
436
|
-
if (logic === "and") return clauses.every((c) => "logic" in c ? matchesGroup(entity, c) : matchesClause(entity, c));
|
|
437
|
-
return clauses.some((c) => "logic" in c ? matchesGroup(entity, c) : matchesClause(entity, c));
|
|
438
|
-
}
|
|
439
|
-
function matchesClause(entity, clause) {
|
|
440
|
-
const { field, op, value, predicate } = clause;
|
|
441
|
-
const fv = getNestedValue(entity, field);
|
|
442
|
-
switch (op) {
|
|
443
|
-
case "eq":
|
|
444
|
-
return fv === value;
|
|
445
|
-
case "neq":
|
|
446
|
-
return fv !== value;
|
|
447
|
-
case "gt":
|
|
448
|
-
return fv > value;
|
|
449
|
-
case "gte":
|
|
450
|
-
return fv >= value;
|
|
451
|
-
case "lt":
|
|
452
|
-
return fv < value;
|
|
453
|
-
case "lte":
|
|
454
|
-
return fv <= value;
|
|
455
|
-
case "in":
|
|
456
|
-
return Array.isArray(value) && value.includes(fv);
|
|
457
|
-
case "nin":
|
|
458
|
-
return Array.isArray(value) && !value.includes(fv);
|
|
459
|
-
case "isNull":
|
|
460
|
-
return fv == null;
|
|
461
|
-
case "isNotNull":
|
|
462
|
-
return fv != null;
|
|
463
|
-
case "contains":
|
|
464
|
-
return typeof fv === "string" && typeof value === "string" && fv.toLowerCase().includes(value.toLowerCase());
|
|
465
|
-
case "startsWith":
|
|
466
|
-
return typeof fv === "string" && typeof value === "string" && fv.toLowerCase().startsWith(value.toLowerCase());
|
|
467
|
-
case "endsWith":
|
|
468
|
-
return typeof fv === "string" && typeof value === "string" && fv.toLowerCase().endsWith(value.toLowerCase());
|
|
469
|
-
case "between": {
|
|
470
|
-
const [lo, hi] = value;
|
|
471
|
-
return fv >= lo && fv <= hi;
|
|
472
|
-
}
|
|
473
|
-
case "arrayContains":
|
|
474
|
-
return Array.isArray(fv) && fv.includes(value);
|
|
475
|
-
case "arrayOverlaps":
|
|
476
|
-
return Array.isArray(fv) && Array.isArray(value) && value.some((v) => fv.includes(v));
|
|
477
|
-
case "matches":
|
|
478
|
-
return typeof fv === "string" && new RegExp(value).test(fv);
|
|
479
|
-
case "custom":
|
|
480
|
-
return predicate ? predicate(fv, entity) : true;
|
|
481
|
-
default:
|
|
482
|
-
return true;
|
|
483
|
-
}
|
|
484
|
-
}
|
|
485
|
-
function matchesSearch(entity, query, fields) {
|
|
486
|
-
if (!query.trim()) return true;
|
|
487
|
-
const lq = query.toLowerCase();
|
|
488
|
-
return fields.some((field) => {
|
|
489
|
-
const v = getNestedValue(entity, field);
|
|
490
|
-
return typeof v === "string" && v.toLowerCase().includes(lq);
|
|
491
|
-
});
|
|
492
|
-
}
|
|
493
|
-
function compareEntities(a, b, sort) {
|
|
494
|
-
for (const clause of sort) {
|
|
495
|
-
const r = compareByClause(a, b, clause);
|
|
496
|
-
if (r !== 0) return r;
|
|
497
|
-
}
|
|
498
|
-
return 0;
|
|
499
|
-
}
|
|
500
|
-
function compareByClause(a, b, clause) {
|
|
501
|
-
const { field, direction, nulls = "last", comparator } = clause;
|
|
502
|
-
const av = getNestedValue(a, field);
|
|
503
|
-
const bv = getNestedValue(b, field);
|
|
504
|
-
const aNull = av == null;
|
|
505
|
-
const bNull = bv == null;
|
|
506
|
-
if (aNull && bNull) return 0;
|
|
507
|
-
if (aNull) return nulls === "first" ? -1 : 1;
|
|
508
|
-
if (bNull) return nulls === "first" ? 1 : -1;
|
|
509
|
-
let cmp;
|
|
510
|
-
if (comparator) cmp = comparator(av, bv);
|
|
511
|
-
else if (typeof av === "string" && typeof bv === "string") cmp = av.localeCompare(bv, void 0, { sensitivity: "base", numeric: true });
|
|
512
|
-
else if (typeof av === "number" && typeof bv === "number") cmp = av - bv;
|
|
513
|
-
else cmp = String(av).localeCompare(String(bv));
|
|
514
|
-
return direction === "desc" ? -cmp : cmp;
|
|
515
|
-
}
|
|
516
|
-
function findInsertionIndex(entity, sortedIds, getEntity, sort) {
|
|
517
|
-
let lo = 0;
|
|
518
|
-
let hi = sortedIds.length;
|
|
519
|
-
while (lo < hi) {
|
|
520
|
-
const mid = lo + hi >>> 1;
|
|
521
|
-
const me = getEntity(sortedIds[mid]);
|
|
522
|
-
if (!me) {
|
|
523
|
-
lo = mid + 1;
|
|
524
|
-
continue;
|
|
525
|
-
}
|
|
526
|
-
if (compareEntities(entity, me, sort) <= 0) hi = mid;
|
|
527
|
-
else lo = mid + 1;
|
|
528
|
-
}
|
|
529
|
-
return lo;
|
|
530
|
-
}
|
|
531
|
-
function applyView(ids, getEntity, filter, sort, search) {
|
|
532
|
-
let entries = [];
|
|
533
|
-
for (const id of ids) {
|
|
534
|
-
const entity = getEntity(id);
|
|
535
|
-
if (!entity) continue;
|
|
536
|
-
entries.push({ id, entity });
|
|
537
|
-
}
|
|
538
|
-
if (filter && entries.length > 0) entries = entries.filter(({ entity }) => matchesFilter(entity, filter));
|
|
539
|
-
if (search?.query) entries = entries.filter(({ entity }) => matchesSearch(entity, search.query, search.fields));
|
|
540
|
-
if (sort && sort.length > 0) entries.sort((a, b) => compareEntities(a.entity, b.entity, sort));
|
|
541
|
-
return entries.map((e) => e.id);
|
|
542
|
-
}
|
|
543
|
-
function checkCompleteness(loadedCount, total, hasNextPage) {
|
|
544
|
-
if (!hasNextPage && total !== null && loadedCount >= total) return { isComplete: true, reason: "all-loaded" };
|
|
545
|
-
if (hasNextPage) return { isComplete: false, reason: "has-more-pages" };
|
|
546
|
-
return { isComplete: true, reason: "no-more-pages" };
|
|
547
|
-
}
|
|
548
|
-
function getNestedValue(obj, path) {
|
|
549
|
-
const parts = path.replace(/\[(\d+)\]/g, ".$1").split(".");
|
|
550
|
-
let current = obj;
|
|
551
|
-
for (const part of parts) {
|
|
552
|
-
if (current == null || typeof current !== "object") return void 0;
|
|
553
|
-
current = current[part];
|
|
554
|
-
}
|
|
555
|
-
return current;
|
|
556
|
-
}
|
|
557
|
-
|
|
558
|
-
// src/graph.ts
|
|
559
|
-
var EMPTY_IDS = [];
|
|
560
|
-
var EMPTY_ENTITY_STATE = {
|
|
561
|
-
isFetching: false,
|
|
562
|
-
lastFetched: null,
|
|
563
|
-
error: null,
|
|
564
|
-
stale: false
|
|
565
|
-
};
|
|
566
|
-
var EMPTY_SYNC_METADATA = {
|
|
567
|
-
synced: true,
|
|
568
|
-
origin: "server",
|
|
569
|
-
updatedAt: null
|
|
570
|
-
};
|
|
571
|
-
var EMPTY_LIST_STATE = {
|
|
572
|
-
ids: EMPTY_IDS,
|
|
573
|
-
total: null,
|
|
574
|
-
nextCursor: null,
|
|
575
|
-
prevCursor: null,
|
|
576
|
-
hasNextPage: false,
|
|
577
|
-
hasPrevPage: false,
|
|
578
|
-
isFetching: false,
|
|
579
|
-
isFetchingMore: false,
|
|
580
|
-
error: null,
|
|
581
|
-
lastError: null,
|
|
582
|
-
lastFetched: null,
|
|
583
|
-
stale: false,
|
|
584
|
-
currentPage: null,
|
|
585
|
-
pageSize: null
|
|
586
|
-
};
|
|
587
|
-
function defaultEntityState() {
|
|
588
|
-
return { ...EMPTY_ENTITY_STATE };
|
|
589
|
-
}
|
|
590
|
-
function defaultSyncMetadata() {
|
|
591
|
-
return { ...EMPTY_SYNC_METADATA };
|
|
592
|
-
}
|
|
593
|
-
function defaultListState() {
|
|
594
|
-
return { ...EMPTY_LIST_STATE, ids: [] };
|
|
595
|
-
}
|
|
596
|
-
function ek(type, id) {
|
|
597
|
-
return `${type}:${id}`;
|
|
598
|
-
}
|
|
599
|
-
var snapshotCache = /* @__PURE__ */ new Map();
|
|
600
|
-
function readCachedEntitySnapshot(type, id, base, patch, metadata) {
|
|
601
|
-
const key = ek(type, id);
|
|
602
|
-
const cached = snapshotCache.get(key);
|
|
603
|
-
if (cached && cached.base === base && cached.patch === patch && cached.metadata === metadata) {
|
|
604
|
-
return cached.snapshot;
|
|
605
|
-
}
|
|
606
|
-
const snapshot = {
|
|
607
|
-
...patch ? { ...base, ...patch } : base,
|
|
608
|
-
$synced: metadata.synced,
|
|
609
|
-
$origin: metadata.origin,
|
|
610
|
-
$updatedAt: metadata.updatedAt
|
|
611
|
-
};
|
|
612
|
-
snapshotCache.set(key, { base, patch, metadata, snapshot });
|
|
613
|
-
return snapshot;
|
|
614
|
-
}
|
|
615
|
-
function createGraphStore() {
|
|
616
|
-
return createStore()(
|
|
617
|
-
subscribeWithSelector(
|
|
618
|
-
immer((set, get) => ({
|
|
619
|
-
entities: {},
|
|
620
|
-
patches: {},
|
|
621
|
-
entityStates: {},
|
|
622
|
-
syncMetadata: {},
|
|
623
|
-
lists: {},
|
|
624
|
-
upsertEntity: (type, id, data) => set((s) => {
|
|
625
|
-
if (!s.entities[type]) s.entities[type] = {};
|
|
626
|
-
const key = ek(type, id);
|
|
627
|
-
const strategy = getMergeStrategy(type);
|
|
628
|
-
const ctx = { type, id, origin: s.syncMetadata[key]?.origin ?? "server", updatedAt: Date.now() };
|
|
629
|
-
s.entities[type][id] = strategy(s.entities[type][id], data, ctx);
|
|
630
|
-
if (!s.syncMetadata[key]) s.syncMetadata[key] = defaultSyncMetadata();
|
|
631
|
-
}),
|
|
632
|
-
upsertEntities: (type, entries) => set((s) => {
|
|
633
|
-
if (!s.entities[type]) s.entities[type] = {};
|
|
634
|
-
const strategy = getMergeStrategy(type);
|
|
635
|
-
for (const { id, data } of entries) {
|
|
636
|
-
const key = ek(type, id);
|
|
637
|
-
const ctx = { type, id, origin: s.syncMetadata[key]?.origin ?? "server", updatedAt: Date.now() };
|
|
638
|
-
s.entities[type][id] = strategy(s.entities[type][id], data, ctx);
|
|
639
|
-
if (!s.syncMetadata[key]) s.syncMetadata[key] = defaultSyncMetadata();
|
|
640
|
-
}
|
|
641
|
-
}),
|
|
642
|
-
ingestFetchedList: (type, entries, options = {}) => set((s) => {
|
|
643
|
-
const fetchedAt = Date.now();
|
|
644
|
-
const ids = entries.map(({ id }) => id);
|
|
645
|
-
const batches = [
|
|
646
|
-
{ type, entries },
|
|
647
|
-
...options.sideBatches ?? []
|
|
648
|
-
];
|
|
649
|
-
const origins = /* @__PURE__ */ new Map();
|
|
650
|
-
for (const batch of batches) {
|
|
651
|
-
if (!s.entities[batch.type]) s.entities[batch.type] = {};
|
|
652
|
-
for (const { id } of batch.entries) {
|
|
653
|
-
const key = ek(batch.type, id);
|
|
654
|
-
if (!origins.has(key)) {
|
|
655
|
-
origins.set(key, s.syncMetadata[key]?.origin ?? "server");
|
|
656
|
-
}
|
|
657
|
-
}
|
|
658
|
-
}
|
|
659
|
-
for (const batch of batches) {
|
|
660
|
-
const strategy = getMergeStrategy(batch.type);
|
|
661
|
-
for (const { id, data } of batch.entries) {
|
|
662
|
-
const key = ek(batch.type, id);
|
|
663
|
-
const ctx = {
|
|
664
|
-
type: batch.type,
|
|
665
|
-
id,
|
|
666
|
-
origin: origins.get(key) ?? "server",
|
|
667
|
-
updatedAt: fetchedAt
|
|
668
|
-
};
|
|
669
|
-
s.entities[batch.type][id] = strategy(s.entities[batch.type][id], data, ctx);
|
|
670
|
-
}
|
|
671
|
-
}
|
|
672
|
-
const completed = /* @__PURE__ */ new Set();
|
|
673
|
-
for (const batch of batches) {
|
|
674
|
-
for (const { id } of batch.entries) {
|
|
675
|
-
const key = ek(batch.type, id);
|
|
676
|
-
if (completed.has(key)) continue;
|
|
677
|
-
completed.add(key);
|
|
678
|
-
if (!s.entityStates[key]) s.entityStates[key] = defaultEntityState();
|
|
679
|
-
s.entityStates[key].lastFetched = fetchedAt;
|
|
680
|
-
s.entityStates[key].isFetching = false;
|
|
681
|
-
s.entityStates[key].error = null;
|
|
682
|
-
s.entityStates[key].stale = false;
|
|
683
|
-
s.syncMetadata[key] = {
|
|
684
|
-
...s.syncMetadata[key] ?? defaultSyncMetadata(),
|
|
685
|
-
synced: true,
|
|
686
|
-
origin: "server",
|
|
687
|
-
updatedAt: fetchedAt
|
|
688
|
-
};
|
|
689
|
-
}
|
|
690
|
-
}
|
|
691
|
-
const readDraftEntity = (id) => {
|
|
692
|
-
const base = s.entities[type]?.[id];
|
|
693
|
-
if (!base) return null;
|
|
694
|
-
const patch = s.patches[type]?.[id];
|
|
695
|
-
const metadata = s.syncMetadata[ek(type, id)] ?? defaultSyncMetadata();
|
|
696
|
-
return {
|
|
697
|
-
...base,
|
|
698
|
-
...patch ?? {},
|
|
699
|
-
$synced: metadata.synced,
|
|
700
|
-
$origin: metadata.origin,
|
|
701
|
-
$updatedAt: metadata.updatedAt
|
|
702
|
-
};
|
|
703
|
-
};
|
|
704
|
-
for (const target of options.lists ?? []) {
|
|
705
|
-
const existing = s.lists[target.key] ?? defaultListState();
|
|
706
|
-
const targetIds = target.ids ?? ids;
|
|
707
|
-
const nextIds = target.mode === "append" ? Array.from(/* @__PURE__ */ new Set([...existing.ids, ...targetIds])) : targetIds;
|
|
708
|
-
s.lists[target.key] = {
|
|
709
|
-
...existing,
|
|
710
|
-
...target.meta ?? {},
|
|
711
|
-
ids: nextIds,
|
|
712
|
-
isFetching: false,
|
|
713
|
-
isFetchingMore: false,
|
|
714
|
-
error: null,
|
|
715
|
-
lastError: null,
|
|
716
|
-
stale: false,
|
|
717
|
-
lastFetched: fetchedAt
|
|
718
|
-
};
|
|
719
|
-
}
|
|
720
|
-
for (const projection of options.projections ?? []) {
|
|
721
|
-
const existing = s.lists[projection.key] ?? defaultListState();
|
|
722
|
-
const nextIds = [...existing.ids];
|
|
723
|
-
const { filter, sort, search } = projection.view;
|
|
724
|
-
for (const id of new Set(ids)) {
|
|
725
|
-
if (nextIds.includes(id)) continue;
|
|
726
|
-
const entity = readDraftEntity(id);
|
|
727
|
-
if (!entity) continue;
|
|
728
|
-
const matches = (!filter || matchesFilter(entity, filter)) && (!search?.query || matchesSearch(entity, search.query, search.fields));
|
|
729
|
-
if (!matches) continue;
|
|
730
|
-
if (sort && sort.length > 0) {
|
|
731
|
-
const index = findInsertionIndex(entity, nextIds, readDraftEntity, sort);
|
|
732
|
-
nextIds.splice(index, 0, id);
|
|
733
|
-
} else {
|
|
734
|
-
nextIds.unshift(id);
|
|
735
|
-
}
|
|
736
|
-
}
|
|
737
|
-
s.lists[projection.key] = projection.completeFetch ? {
|
|
738
|
-
...existing,
|
|
739
|
-
ids: nextIds,
|
|
740
|
-
isFetching: false,
|
|
741
|
-
isFetchingMore: false,
|
|
742
|
-
error: null,
|
|
743
|
-
lastError: null,
|
|
744
|
-
stale: false,
|
|
745
|
-
lastFetched: fetchedAt
|
|
746
|
-
} : { ...existing, ids: nextIds };
|
|
747
|
-
}
|
|
748
|
-
for (const key of options.finishListFetches ?? []) {
|
|
749
|
-
if (!s.lists[key]) s.lists[key] = defaultListState();
|
|
750
|
-
s.lists[key].isFetching = false;
|
|
751
|
-
}
|
|
752
|
-
}),
|
|
753
|
-
replaceEntity: (type, id, data) => set((s) => {
|
|
754
|
-
if (!s.entities[type]) s.entities[type] = {};
|
|
755
|
-
s.entities[type][id] = data;
|
|
756
|
-
const key = ek(type, id);
|
|
757
|
-
if (!s.syncMetadata[key]) s.syncMetadata[key] = defaultSyncMetadata();
|
|
758
|
-
}),
|
|
759
|
-
removeEntity: (type, id) => set((s) => {
|
|
760
|
-
delete s.entities[type]?.[id];
|
|
761
|
-
delete s.patches[type]?.[id];
|
|
762
|
-
delete s.entityStates[ek(type, id)];
|
|
763
|
-
delete s.syncMetadata[ek(type, id)];
|
|
764
|
-
}),
|
|
765
|
-
patchEntity: (type, id, patch) => set((s) => {
|
|
766
|
-
if (!s.patches[type]) s.patches[type] = {};
|
|
767
|
-
s.patches[type][id] = { ...s.patches[type][id] ?? {}, ...patch };
|
|
768
|
-
}),
|
|
769
|
-
unpatchEntity: (type, id, keys) => set((s) => {
|
|
770
|
-
const p = s.patches[type]?.[id];
|
|
771
|
-
if (!p) return;
|
|
772
|
-
for (const k of keys) delete p[k];
|
|
773
|
-
}),
|
|
774
|
-
clearPatch: (type, id) => set((s) => {
|
|
775
|
-
delete s.patches[type]?.[id];
|
|
776
|
-
}),
|
|
777
|
-
setEntityFetching: (type, id, fetching) => set((s) => {
|
|
778
|
-
const k = ek(type, id);
|
|
779
|
-
if (!s.entityStates[k]) s.entityStates[k] = defaultEntityState();
|
|
780
|
-
s.entityStates[k].isFetching = fetching;
|
|
781
|
-
}),
|
|
782
|
-
setEntityError: (type, id, error) => set((s) => {
|
|
783
|
-
const k = ek(type, id);
|
|
784
|
-
if (!s.entityStates[k]) s.entityStates[k] = defaultEntityState();
|
|
785
|
-
s.entityStates[k].error = error;
|
|
786
|
-
s.entityStates[k].isFetching = false;
|
|
787
|
-
}),
|
|
788
|
-
setEntityFetched: (type, id) => set((s) => {
|
|
789
|
-
const k = ek(type, id);
|
|
790
|
-
if (!s.entityStates[k]) s.entityStates[k] = defaultEntityState();
|
|
791
|
-
s.entityStates[k].lastFetched = Date.now();
|
|
792
|
-
s.entityStates[k].isFetching = false;
|
|
793
|
-
s.entityStates[k].error = null;
|
|
794
|
-
s.entityStates[k].stale = false;
|
|
795
|
-
s.syncMetadata[k] = { ...s.syncMetadata[k] ?? defaultSyncMetadata(), synced: true, origin: "server", updatedAt: Date.now() };
|
|
796
|
-
}),
|
|
797
|
-
setEntityStale: (type, id, stale) => set((s) => {
|
|
798
|
-
const k = ek(type, id);
|
|
799
|
-
if (!s.entityStates[k]) s.entityStates[k] = defaultEntityState();
|
|
800
|
-
s.entityStates[k].stale = stale;
|
|
801
|
-
}),
|
|
802
|
-
setEntitySyncMetadata: (type, id, metadata) => set((s) => {
|
|
803
|
-
const k = ek(type, id);
|
|
804
|
-
s.syncMetadata[k] = { ...s.syncMetadata[k] ?? defaultSyncMetadata(), ...metadata };
|
|
805
|
-
}),
|
|
806
|
-
clearEntitySyncMetadata: (type, id) => set((s) => {
|
|
807
|
-
delete s.syncMetadata[ek(type, id)];
|
|
808
|
-
}),
|
|
809
|
-
setListResult: (key, ids, meta) => set((s) => {
|
|
810
|
-
const ex = s.lists[key] ?? defaultListState();
|
|
811
|
-
s.lists[key] = { ...ex, ...meta, ids, isFetching: false, isFetchingMore: false, error: null, lastError: null, stale: false, lastFetched: Date.now() };
|
|
812
|
-
}),
|
|
813
|
-
appendListResult: (key, ids, meta) => set((s) => {
|
|
814
|
-
const ex = s.lists[key] ?? defaultListState();
|
|
815
|
-
s.lists[key] = { ...ex, ...meta, ids: Array.from(/* @__PURE__ */ new Set([...ex.ids, ...ids])), isFetching: false, isFetchingMore: false, error: null, lastError: null, stale: false, lastFetched: Date.now() };
|
|
816
|
-
}),
|
|
817
|
-
prependListResult: (key, ids, meta) => set((s) => {
|
|
818
|
-
const ex = s.lists[key] ?? defaultListState();
|
|
819
|
-
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() };
|
|
820
|
-
}),
|
|
821
|
-
removeIdFromAllLists: (_type, id) => set((s) => {
|
|
822
|
-
for (const key of Object.keys(s.lists)) {
|
|
823
|
-
const list = s.lists[key];
|
|
824
|
-
const idx = list.ids.indexOf(id);
|
|
825
|
-
if (idx !== -1) {
|
|
826
|
-
list.ids.splice(idx, 1);
|
|
827
|
-
if (list.total !== null) list.total -= 1;
|
|
828
|
-
}
|
|
829
|
-
}
|
|
830
|
-
}),
|
|
831
|
-
insertIdInList: (key, id, position) => set((s) => {
|
|
832
|
-
if (!s.lists[key]) s.lists[key] = defaultListState();
|
|
833
|
-
const ids = s.lists[key].ids;
|
|
834
|
-
const ex = ids.indexOf(id);
|
|
835
|
-
if (ex !== -1) ids.splice(ex, 1);
|
|
836
|
-
if (position === "start") ids.unshift(id);
|
|
837
|
-
else if (position === "end") ids.push(id);
|
|
838
|
-
else ids.splice(position, 0, id);
|
|
839
|
-
}),
|
|
840
|
-
setListFetching: (key, fetching) => set((s) => {
|
|
841
|
-
if (!s.lists[key]) s.lists[key] = defaultListState();
|
|
842
|
-
s.lists[key].isFetching = fetching;
|
|
843
|
-
}),
|
|
844
|
-
setListFetchingMore: (key, fetchingMore) => set((s) => {
|
|
845
|
-
if (!s.lists[key]) s.lists[key] = defaultListState();
|
|
846
|
-
s.lists[key].isFetchingMore = fetchingMore;
|
|
847
|
-
}),
|
|
848
|
-
setListError: (key, error, typed) => set((s) => {
|
|
849
|
-
if (!s.lists[key]) s.lists[key] = defaultListState();
|
|
850
|
-
s.lists[key].error = error;
|
|
851
|
-
s.lists[key].lastError = typed ?? (error === null ? null : s.lists[key].lastError);
|
|
852
|
-
s.lists[key].isFetching = false;
|
|
853
|
-
s.lists[key].isFetchingMore = false;
|
|
854
|
-
s.lists[key].lastFetched = Date.now();
|
|
855
|
-
s.lists[key].stale = false;
|
|
856
|
-
}),
|
|
857
|
-
setListStale: (key, stale) => set((s) => {
|
|
858
|
-
if (!s.lists[key]) s.lists[key] = defaultListState();
|
|
859
|
-
s.lists[key].stale = stale;
|
|
860
|
-
}),
|
|
861
|
-
invalidateEntity: (type, id) => set((s) => {
|
|
862
|
-
if (id) {
|
|
863
|
-
const k = ek(type, id);
|
|
864
|
-
if (s.entityStates[k]) s.entityStates[k].stale = true;
|
|
865
|
-
} else {
|
|
866
|
-
for (const k of Object.keys(s.entityStates)) if (k.startsWith(`${type}:`)) s.entityStates[k].stale = true;
|
|
867
|
-
}
|
|
868
|
-
}),
|
|
869
|
-
invalidateLists: (matcher) => set((s) => {
|
|
870
|
-
const pred = typeof matcher === "string" ? (k) => k.startsWith(matcher) : matcher;
|
|
871
|
-
for (const key of Object.keys(s.lists)) if (pred(key)) s.lists[key].stale = true;
|
|
872
|
-
}),
|
|
873
|
-
invalidateType: (type) => {
|
|
874
|
-
get().invalidateEntity(type);
|
|
875
|
-
get().invalidateLists(type);
|
|
876
|
-
},
|
|
877
|
-
readEntity: (type, id) => {
|
|
878
|
-
const s = get();
|
|
879
|
-
const base = s.entities[type]?.[id];
|
|
880
|
-
if (!base) return null;
|
|
881
|
-
const patch = s.patches[type]?.[id];
|
|
882
|
-
return patch ? { ...base, ...patch } : base;
|
|
883
|
-
},
|
|
884
|
-
readEntitySnapshot: (type, id) => {
|
|
885
|
-
const s = get();
|
|
886
|
-
const base = s.entities[type]?.[id];
|
|
887
|
-
if (!base) {
|
|
888
|
-
snapshotCache.delete(ek(type, id));
|
|
889
|
-
return null;
|
|
890
|
-
}
|
|
891
|
-
const patch = s.patches[type]?.[id];
|
|
892
|
-
const metadata = s.syncMetadata[ek(type, id)] ?? EMPTY_SYNC_METADATA;
|
|
893
|
-
return readCachedEntitySnapshot(
|
|
894
|
-
type,
|
|
895
|
-
id,
|
|
896
|
-
base,
|
|
897
|
-
patch,
|
|
898
|
-
metadata
|
|
899
|
-
);
|
|
900
|
-
}
|
|
901
|
-
}))
|
|
902
|
-
)
|
|
903
|
-
);
|
|
904
|
-
}
|
|
905
|
-
var graphStore = createGraphStore();
|
|
906
|
-
var useGraphStore = graphStore;
|
|
907
|
-
|
|
908
490
|
// src/object-path.ts
|
|
909
491
|
function isObject(value) {
|
|
910
492
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -948,8 +530,9 @@ function collectDirtyPaths(current, original, prefix = "", acc = /* @__PURE__ */
|
|
|
948
530
|
|
|
949
531
|
// src/merge/loro.ts
|
|
950
532
|
var ROOT_MAP = "entity";
|
|
533
|
+
var LORO_MODULE_SPECIFIER = "loro-crdt";
|
|
951
534
|
var docs = /* @__PURE__ */ new Map();
|
|
952
|
-
function
|
|
535
|
+
function ek(type, id) {
|
|
953
536
|
return `${type}:${id}`;
|
|
954
537
|
}
|
|
955
538
|
async function createLoroMergeStrategy(loadLoro) {
|
|
@@ -957,7 +540,7 @@ async function createLoroMergeStrategy(loadLoro) {
|
|
|
957
540
|
try {
|
|
958
541
|
const loaded = loadLoro ? await loadLoro() : await import(
|
|
959
542
|
/* @vite-ignore */
|
|
960
|
-
|
|
543
|
+
LORO_MODULE_SPECIFIER
|
|
961
544
|
);
|
|
962
545
|
if (typeof loaded.LoroDoc !== "function") {
|
|
963
546
|
throw new TypeError("loro-crdt did not export a LoroDoc constructor");
|
|
@@ -971,7 +554,7 @@ async function createLoroMergeStrategy(loadLoro) {
|
|
|
971
554
|
}
|
|
972
555
|
const { LoroDoc } = mod;
|
|
973
556
|
return (prev, next, ctx) => {
|
|
974
|
-
const key =
|
|
557
|
+
const key = ek(ctx.type, ctx.id);
|
|
975
558
|
let doc = docs.get(key);
|
|
976
559
|
if (!doc) {
|
|
977
560
|
doc = new LoroDoc();
|
|
@@ -1059,272 +642,6 @@ function applySelection(row, select) {
|
|
|
1059
642
|
return picked;
|
|
1060
643
|
}
|
|
1061
644
|
|
|
1062
|
-
// src/engine.ts
|
|
1063
|
-
function serializeKey(key) {
|
|
1064
|
-
return JSON.stringify(key, (_, v) => v && typeof v === "object" && !Array.isArray(v) ? Object.fromEntries(Object.entries(v).sort()) : v);
|
|
1065
|
-
}
|
|
1066
|
-
function sleep(ms) {
|
|
1067
|
-
return new Promise((r) => setTimeout(r, ms));
|
|
1068
|
-
}
|
|
1069
|
-
var inflightByStore = /* @__PURE__ */ new WeakMap();
|
|
1070
|
-
function inflightFor(store) {
|
|
1071
|
-
let inflight = inflightByStore.get(store);
|
|
1072
|
-
if (!inflight) {
|
|
1073
|
-
inflight = /* @__PURE__ */ new Map();
|
|
1074
|
-
inflightByStore.set(store, inflight);
|
|
1075
|
-
}
|
|
1076
|
-
return inflight;
|
|
1077
|
-
}
|
|
1078
|
-
function dedupe(key, fn, store = graphStore) {
|
|
1079
|
-
const inflight = inflightFor(store);
|
|
1080
|
-
if (inflight.has(key)) return inflight.get(key);
|
|
1081
|
-
const p = fn().finally(() => inflight.delete(key));
|
|
1082
|
-
inflight.set(key, p);
|
|
1083
|
-
return p;
|
|
1084
|
-
}
|
|
1085
|
-
var subscriberStatsListeners = /* @__PURE__ */ new Set();
|
|
1086
|
-
function emitSubscriberStatsChange() {
|
|
1087
|
-
for (const cb of subscriberStatsListeners) cb();
|
|
1088
|
-
}
|
|
1089
|
-
var subscribersByStore = /* @__PURE__ */ new WeakMap();
|
|
1090
|
-
function subscribersFor(store) {
|
|
1091
|
-
let subscribers = subscribersByStore.get(store);
|
|
1092
|
-
if (!subscribers) {
|
|
1093
|
-
subscribers = /* @__PURE__ */ new Map();
|
|
1094
|
-
subscribersByStore.set(store, subscribers);
|
|
1095
|
-
}
|
|
1096
|
-
return subscribers;
|
|
1097
|
-
}
|
|
1098
|
-
function registerSubscriber(key, store = graphStore) {
|
|
1099
|
-
const subscribers = subscribersFor(store);
|
|
1100
|
-
const token = Symbol(key);
|
|
1101
|
-
if (!subscribers.has(key)) subscribers.set(key, /* @__PURE__ */ new Set());
|
|
1102
|
-
subscribers.get(key).add(token);
|
|
1103
|
-
emitSubscriberStatsChange();
|
|
1104
|
-
return token;
|
|
1105
|
-
}
|
|
1106
|
-
function unregisterSubscriber(key, token, store = graphStore) {
|
|
1107
|
-
const subscribers = subscribersFor(store);
|
|
1108
|
-
const set = subscribers.get(key);
|
|
1109
|
-
if (!set) return;
|
|
1110
|
-
set.delete(token);
|
|
1111
|
-
if (set.size === 0) subscribers.delete(key);
|
|
1112
|
-
emitSubscriberStatsChange();
|
|
1113
|
-
}
|
|
1114
|
-
function hasSubscribers(key, store = graphStore) {
|
|
1115
|
-
return (subscribersFor(store).get(key)?.size ?? 0) > 0;
|
|
1116
|
-
}
|
|
1117
|
-
var DEFAULT_OPTIONS = {
|
|
1118
|
-
defaultStaleTime: 3e4,
|
|
1119
|
-
defaultGcTime: 3e5,
|
|
1120
|
-
gcInterval: 6e4,
|
|
1121
|
-
maxRetries: 3,
|
|
1122
|
-
retryBaseDelay: 1e3,
|
|
1123
|
-
revalidateOnFocus: true,
|
|
1124
|
-
revalidateOnReconnect: true
|
|
1125
|
-
};
|
|
1126
|
-
var engineOptions = { ...DEFAULT_OPTIONS };
|
|
1127
|
-
function subscribeSubscriberStats(onChange) {
|
|
1128
|
-
subscriberStatsListeners.add(onChange);
|
|
1129
|
-
return () => subscriberStatsListeners.delete(onChange);
|
|
1130
|
-
}
|
|
1131
|
-
function getActiveSubscriberCount(store = graphStore) {
|
|
1132
|
-
let n = 0;
|
|
1133
|
-
for (const set of subscribersFor(store).values()) n += set.size;
|
|
1134
|
-
return n;
|
|
1135
|
-
}
|
|
1136
|
-
var devtoolsSubscribers = /* @__PURE__ */ new Set();
|
|
1137
|
-
function subscribeDevtoolsEvent(cb) {
|
|
1138
|
-
devtoolsSubscribers.add(cb);
|
|
1139
|
-
return () => {
|
|
1140
|
-
devtoolsSubscribers.delete(cb);
|
|
1141
|
-
};
|
|
1142
|
-
}
|
|
1143
|
-
function notifyDevtools(event) {
|
|
1144
|
-
if (devtoolsSubscribers.size === 0) return;
|
|
1145
|
-
const listeners2 = [...devtoolsSubscribers];
|
|
1146
|
-
for (const cb of listeners2) {
|
|
1147
|
-
try {
|
|
1148
|
-
cb(event);
|
|
1149
|
-
} catch (err) {
|
|
1150
|
-
console.warn("[engine] devtools subscriber threw:", err);
|
|
1151
|
-
}
|
|
1152
|
-
}
|
|
1153
|
-
}
|
|
1154
|
-
var gcIntervalsByStore = /* @__PURE__ */ new Map();
|
|
1155
|
-
function runGarbageCollection(storeApi = graphStore) {
|
|
1156
|
-
const store = storeApi.getState();
|
|
1157
|
-
const { defaultGcTime: gcTime } = getEngineOptions();
|
|
1158
|
-
const now = Date.now();
|
|
1159
|
-
const toRemove = [];
|
|
1160
|
-
for (const type of Object.keys(store.entities)) {
|
|
1161
|
-
const bucket = store.entities[type];
|
|
1162
|
-
if (!bucket) continue;
|
|
1163
|
-
for (const id of Object.keys(bucket)) {
|
|
1164
|
-
const key = `${type}:${id}`;
|
|
1165
|
-
if (hasSubscribers(key, storeApi)) continue;
|
|
1166
|
-
const patch = store.patches[type]?.[id];
|
|
1167
|
-
if (patch !== void 0 && Object.keys(patch).length > 0) continue;
|
|
1168
|
-
const entityState = store.entityStates[key];
|
|
1169
|
-
if (entityState?.isFetching) continue;
|
|
1170
|
-
const lastFetched = entityState?.lastFetched;
|
|
1171
|
-
if (lastFetched == null) continue;
|
|
1172
|
-
if (now - lastFetched <= gcTime) continue;
|
|
1173
|
-
toRemove.push({ type, id });
|
|
1174
|
-
}
|
|
1175
|
-
}
|
|
1176
|
-
for (const { type, id } of toRemove) {
|
|
1177
|
-
store.removeEntity(type, id);
|
|
1178
|
-
store.removeIdFromAllLists(type, id);
|
|
1179
|
-
}
|
|
1180
|
-
}
|
|
1181
|
-
function stopGarbageCollector(storeApi = graphStore) {
|
|
1182
|
-
const intervalId = gcIntervalsByStore.get(storeApi);
|
|
1183
|
-
if (intervalId != null && typeof clearInterval !== "undefined") {
|
|
1184
|
-
clearInterval(intervalId);
|
|
1185
|
-
gcIntervalsByStore.delete(storeApi);
|
|
1186
|
-
}
|
|
1187
|
-
}
|
|
1188
|
-
function startGarbageCollector(storeApi = graphStore) {
|
|
1189
|
-
stopGarbageCollector(storeApi);
|
|
1190
|
-
if (typeof window === "undefined" || typeof setInterval === "undefined") return () => {
|
|
1191
|
-
};
|
|
1192
|
-
const intervalId = setInterval(
|
|
1193
|
-
() => runGarbageCollection(storeApi),
|
|
1194
|
-
getEngineOptions().gcInterval
|
|
1195
|
-
);
|
|
1196
|
-
gcIntervalsByStore.set(storeApi, intervalId);
|
|
1197
|
-
return () => stopGarbageCollector(storeApi);
|
|
1198
|
-
}
|
|
1199
|
-
function restartGarbageCollector(storeApi = graphStore) {
|
|
1200
|
-
startGarbageCollector(storeApi);
|
|
1201
|
-
}
|
|
1202
|
-
function configureEngine(opts) {
|
|
1203
|
-
engineOptions = { ...DEFAULT_OPTIONS, ...opts };
|
|
1204
|
-
const activeStores = [...gcIntervalsByStore.keys()];
|
|
1205
|
-
if (activeStores.length === 0) restartGarbageCollector();
|
|
1206
|
-
else for (const storeApi of activeStores) restartGarbageCollector(storeApi);
|
|
1207
|
-
}
|
|
1208
|
-
function getEngineOptions() {
|
|
1209
|
-
return engineOptions;
|
|
1210
|
-
}
|
|
1211
|
-
async function fetchEntity(opts, engineOpts, storeApi = graphStore) {
|
|
1212
|
-
const { type, id, fetch, normalize, sideEffects, idField = "id" } = opts;
|
|
1213
|
-
if (!id) return;
|
|
1214
|
-
storeApi.getState().setEntityFetching(type, id, true);
|
|
1215
|
-
const attempt = async (retries) => {
|
|
1216
|
-
try {
|
|
1217
|
-
const raw = await fetch(id);
|
|
1218
|
-
const normalized = normalize(raw);
|
|
1219
|
-
const resolvedId = normalized[idField] ?? id;
|
|
1220
|
-
storeApi.getState().upsertEntity(type, resolvedId, normalized);
|
|
1221
|
-
storeApi.getState().setEntityFetched(type, resolvedId);
|
|
1222
|
-
if (sideEffects) sideEffects(raw, storeApi);
|
|
1223
|
-
opts.onSuccess?.(normalized);
|
|
1224
|
-
} catch (err) {
|
|
1225
|
-
const error = err instanceof Error ? err : new Error(String(err));
|
|
1226
|
-
if (retries < engineOpts.maxRetries) {
|
|
1227
|
-
await sleep(engineOpts.retryBaseDelay * Math.pow(2, retries));
|
|
1228
|
-
return attempt(retries + 1);
|
|
1229
|
-
}
|
|
1230
|
-
storeApi.getState().setEntityError(type, id, error.message);
|
|
1231
|
-
opts.onError?.(error);
|
|
1232
|
-
}
|
|
1233
|
-
};
|
|
1234
|
-
await dedupe(`${type}:${id}`, () => attempt(0), storeApi);
|
|
1235
|
-
}
|
|
1236
|
-
async function fetchList(opts, params, engineOpts, isLoadMore = false, storeApi = graphStore) {
|
|
1237
|
-
const { type, queryKey, fetch, normalize, sideEffects, mode = "replace" } = opts;
|
|
1238
|
-
const key = serializeKey(queryKey);
|
|
1239
|
-
const store = storeApi.getState();
|
|
1240
|
-
if (!fetch || !normalize) return;
|
|
1241
|
-
if (isLoadMore) store.setListFetchingMore(key, true);
|
|
1242
|
-
else store.setListFetching(key, true);
|
|
1243
|
-
const attempt = async (retries) => {
|
|
1244
|
-
try {
|
|
1245
|
-
const response = await fetch(params);
|
|
1246
|
-
const normalized = response.items.map(normalize);
|
|
1247
|
-
const meta = { total: response.total ?? null, nextCursor: response.nextCursor ?? null, prevCursor: response.prevCursor ?? null, hasNextPage: response.hasNextPage ?? !!response.nextCursor, hasPrevPage: response.hasPrevPage ?? !!response.prevCursor, currentPage: response.page ?? null, pageSize: response.pageSize ?? null };
|
|
1248
|
-
storeApi.getState().ingestFetchedList(
|
|
1249
|
-
type,
|
|
1250
|
-
normalized.map(({ id, data }) => ({ id, data })),
|
|
1251
|
-
{ lists: [{ key, mode: mode === "append" && isLoadMore ? "append" : "replace", meta }] }
|
|
1252
|
-
);
|
|
1253
|
-
if (sideEffects) sideEffects(response.items, storeApi);
|
|
1254
|
-
opts.onSuccess?.(response);
|
|
1255
|
-
} catch (err) {
|
|
1256
|
-
const error = err instanceof Error ? err : new Error(String(err));
|
|
1257
|
-
if (retries < engineOpts.maxRetries) {
|
|
1258
|
-
await sleep(engineOpts.retryBaseDelay * Math.pow(2, retries));
|
|
1259
|
-
return attempt(retries + 1);
|
|
1260
|
-
}
|
|
1261
|
-
storeApi.getState().setListError(key, error.message);
|
|
1262
|
-
opts.onError?.(error);
|
|
1263
|
-
}
|
|
1264
|
-
};
|
|
1265
|
-
await dedupe(isLoadMore ? `${key}:more` : key, () => attempt(0), storeApi);
|
|
1266
|
-
}
|
|
1267
|
-
var globalListenerAttachments = /* @__PURE__ */ new WeakMap();
|
|
1268
|
-
function releaseGlobalListenerAttachment(storeApi, attachment) {
|
|
1269
|
-
let released = false;
|
|
1270
|
-
return () => {
|
|
1271
|
-
if (released) return;
|
|
1272
|
-
released = true;
|
|
1273
|
-
const current = globalListenerAttachments.get(storeApi);
|
|
1274
|
-
if (current !== attachment) return;
|
|
1275
|
-
current.references -= 1;
|
|
1276
|
-
if (current.references > 0) return;
|
|
1277
|
-
current.dispose();
|
|
1278
|
-
globalListenerAttachments.delete(storeApi);
|
|
1279
|
-
};
|
|
1280
|
-
}
|
|
1281
|
-
function attachGlobalListeners(storeApi = graphStore) {
|
|
1282
|
-
if (typeof window === "undefined") return () => {
|
|
1283
|
-
};
|
|
1284
|
-
const existing = globalListenerAttachments.get(storeApi);
|
|
1285
|
-
if (existing) {
|
|
1286
|
-
existing.references += 1;
|
|
1287
|
-
return releaseGlobalListenerAttachment(storeApi, existing);
|
|
1288
|
-
}
|
|
1289
|
-
const stopGc = startGarbageCollector(storeApi);
|
|
1290
|
-
const revalidateAll = () => {
|
|
1291
|
-
const state = storeApi.getState();
|
|
1292
|
-
for (const key of subscribersFor(storeApi).keys()) {
|
|
1293
|
-
if (!hasSubscribers(key, storeApi)) continue;
|
|
1294
|
-
const colonIdx = key.indexOf(":");
|
|
1295
|
-
if (colonIdx === -1) continue;
|
|
1296
|
-
const type = key.slice(0, colonIdx);
|
|
1297
|
-
const id = key.slice(colonIdx + 1);
|
|
1298
|
-
state.setEntityStale(type, id, true);
|
|
1299
|
-
}
|
|
1300
|
-
};
|
|
1301
|
-
const revalidateWhenVisible = () => {
|
|
1302
|
-
if (document.visibilityState === "visible") revalidateAll();
|
|
1303
|
-
};
|
|
1304
|
-
const revalidateOnFocus = engineOptions.revalidateOnFocus;
|
|
1305
|
-
const revalidateOnReconnect = engineOptions.revalidateOnReconnect;
|
|
1306
|
-
if (revalidateOnFocus) {
|
|
1307
|
-
window.addEventListener("visibilitychange", revalidateWhenVisible);
|
|
1308
|
-
window.addEventListener("focus", revalidateAll);
|
|
1309
|
-
}
|
|
1310
|
-
if (revalidateOnReconnect) window.addEventListener("online", revalidateAll);
|
|
1311
|
-
const attachment = {
|
|
1312
|
-
references: 1,
|
|
1313
|
-
dispose: () => {
|
|
1314
|
-
if (revalidateOnFocus) {
|
|
1315
|
-
window.removeEventListener("visibilitychange", revalidateWhenVisible);
|
|
1316
|
-
window.removeEventListener("focus", revalidateAll);
|
|
1317
|
-
}
|
|
1318
|
-
if (revalidateOnReconnect) {
|
|
1319
|
-
window.removeEventListener("online", revalidateAll);
|
|
1320
|
-
}
|
|
1321
|
-
stopGc();
|
|
1322
|
-
}
|
|
1323
|
-
};
|
|
1324
|
-
globalListenerAttachments.set(storeApi, attachment);
|
|
1325
|
-
return releaseGlobalListenerAttachment(storeApi, attachment);
|
|
1326
|
-
}
|
|
1327
|
-
|
|
1328
645
|
// src/graph-actions.ts
|
|
1329
646
|
var graphActionListeners = /* @__PURE__ */ new Set();
|
|
1330
647
|
var graphActionReplayers = /* @__PURE__ */ new Map();
|
|
@@ -1335,7 +652,7 @@ function createGraphTransaction(storeApi = graphStore) {
|
|
|
1335
652
|
upsertEntity(type, id, data) {
|
|
1336
653
|
storeApi.getState().upsertEntity(type, id, data);
|
|
1337
654
|
if (typeof process === "undefined" || process.env.NODE_ENV !== "production") {
|
|
1338
|
-
|
|
655
|
+
emitLegacyDevtoolsEvent({ kind: "upsert", type, id, data, at: (/* @__PURE__ */ new Date()).toISOString() });
|
|
1339
656
|
}
|
|
1340
657
|
return tx;
|
|
1341
658
|
},
|
|
@@ -1350,14 +667,14 @@ function createGraphTransaction(storeApi = graphStore) {
|
|
|
1350
667
|
patchEntity(type, id, patch) {
|
|
1351
668
|
storeApi.getState().patchEntity(type, id, patch);
|
|
1352
669
|
if (typeof process === "undefined" || process.env.NODE_ENV !== "production") {
|
|
1353
|
-
|
|
670
|
+
emitLegacyDevtoolsEvent({ kind: "patch", type, id, patch, at: (/* @__PURE__ */ new Date()).toISOString() });
|
|
1354
671
|
}
|
|
1355
672
|
return tx;
|
|
1356
673
|
},
|
|
1357
674
|
clearPatch(type, id) {
|
|
1358
675
|
storeApi.getState().clearPatch(type, id);
|
|
1359
676
|
if (typeof process === "undefined" || process.env.NODE_ENV !== "production") {
|
|
1360
|
-
|
|
677
|
+
emitLegacyDevtoolsEvent({ kind: "clearPatch", type, id, at: (/* @__PURE__ */ new Date()).toISOString() });
|
|
1361
678
|
}
|
|
1362
679
|
return tx;
|
|
1363
680
|
},
|
|
@@ -1840,7 +1157,7 @@ function computeDelay(policy, attempt) {
|
|
|
1840
1157
|
return base / 2 + Math.random() * (base / 2);
|
|
1841
1158
|
}
|
|
1842
1159
|
}
|
|
1843
|
-
function
|
|
1160
|
+
function sleep(ms) {
|
|
1844
1161
|
if (ms <= 0) return Promise.resolve();
|
|
1845
1162
|
return new Promise((r) => setTimeout(r, ms));
|
|
1846
1163
|
}
|
|
@@ -1853,7 +1170,7 @@ async function replayActionWithRetry(action, policy, storeApi = graphStore) {
|
|
|
1853
1170
|
} catch (error) {
|
|
1854
1171
|
lastError = error;
|
|
1855
1172
|
if (attempt >= policy.maxAttempts) break;
|
|
1856
|
-
await
|
|
1173
|
+
await sleep(computeDelay(policy, attempt));
|
|
1857
1174
|
}
|
|
1858
1175
|
}
|
|
1859
1176
|
try {
|
|
@@ -1887,9 +1204,9 @@ function getDefaultOnlineSource() {
|
|
|
1887
1204
|
|
|
1888
1205
|
// src/devtools-event-bus.ts
|
|
1889
1206
|
var _busInjectMap = /* @__PURE__ */ new WeakMap();
|
|
1890
|
-
var
|
|
1207
|
+
var registries = /* @__PURE__ */ new Map();
|
|
1891
1208
|
function __resetStoreRegistry() {
|
|
1892
|
-
|
|
1209
|
+
registries.clear();
|
|
1893
1210
|
}
|
|
1894
1211
|
function createDevtoolsEventBus(opts) {
|
|
1895
1212
|
const bufferSize = opts?.bufferSize ?? 500;
|
|
@@ -2004,8 +1321,10 @@ function createDevtoolsEventBus(opts) {
|
|
|
2004
1321
|
pendingBurst = [];
|
|
2005
1322
|
dispatchedCount = 0;
|
|
2006
1323
|
flushScheduled = false;
|
|
2007
|
-
|
|
2008
|
-
|
|
1324
|
+
const registry = registries.get(bus);
|
|
1325
|
+
if (registry) {
|
|
1326
|
+
for (const entry of registry.values()) {
|
|
1327
|
+
if (!entry.active) continue;
|
|
2009
1328
|
entry.active = false;
|
|
2010
1329
|
try {
|
|
2011
1330
|
entry.unsubscribeSrc();
|
|
@@ -2013,12 +1332,19 @@ function createDevtoolsEventBus(opts) {
|
|
|
2013
1332
|
}
|
|
2014
1333
|
}
|
|
2015
1334
|
}
|
|
1335
|
+
registries.delete(bus);
|
|
1336
|
+
_busInjectMap.delete(bus);
|
|
2016
1337
|
}
|
|
2017
1338
|
};
|
|
2018
1339
|
_busInjectMap.set(bus, handleEngineEvent);
|
|
2019
1340
|
return bus;
|
|
2020
1341
|
}
|
|
2021
1342
|
function registerStore(bus, source, name) {
|
|
1343
|
+
let registry = registries.get(bus);
|
|
1344
|
+
if (!registry) {
|
|
1345
|
+
registry = /* @__PURE__ */ new Map();
|
|
1346
|
+
registries.set(bus, registry);
|
|
1347
|
+
}
|
|
2022
1348
|
if (registry.get(name)?.active === true) {
|
|
2023
1349
|
throw new Error(
|
|
2024
1350
|
`[devtools-store-registry] Store name "${name}" is already registered and active`
|
|
@@ -2039,75 +1365,38 @@ function registerStore(bus, source, name) {
|
|
|
2039
1365
|
unsubscribeSrc();
|
|
2040
1366
|
};
|
|
2041
1367
|
}
|
|
2042
|
-
function getRegisteredStores() {
|
|
2043
|
-
|
|
1368
|
+
function getRegisteredStores(bus) {
|
|
1369
|
+
const entries = bus ? [...registries.get(bus)?.values() ?? []] : [...registries.values()].flatMap((registry) => [...registry.values()]);
|
|
1370
|
+
return entries.map((entry) => ({ name: entry.name, active: entry.active }));
|
|
2044
1371
|
}
|
|
2045
1372
|
|
|
2046
1373
|
// src/devtools-time-travel.ts
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
var listeners = /* @__PURE__ */ new Set();
|
|
2052
|
-
function notify() {
|
|
2053
|
-
for (const l of listeners) l();
|
|
2054
|
-
}
|
|
2055
|
-
function cloneSlice(s) {
|
|
2056
|
-
return {
|
|
2057
|
-
entities: structuredClone(s.entities),
|
|
2058
|
-
patches: structuredClone(s.patches),
|
|
2059
|
-
entityStates: structuredClone(s.entityStates),
|
|
2060
|
-
syncMetadata: structuredClone(s.syncMetadata),
|
|
2061
|
-
lists: structuredClone(s.lists)
|
|
2062
|
-
};
|
|
2063
|
-
}
|
|
2064
|
-
function configureTimeTravel(opts) {
|
|
2065
|
-
if (opts.capacity && opts.capacity > 0) capacity = opts.capacity;
|
|
2066
|
-
if (ring.length > capacity) ring = ring.slice(-capacity);
|
|
2067
|
-
notify();
|
|
1374
|
+
function configureTimeTravel(opts, storeApi = graphStore) {
|
|
1375
|
+
if (opts.capacity && opts.capacity > 0) {
|
|
1376
|
+
getGraphDevtoolsCompatibilityDelegate(storeApi)?.configure(opts.capacity);
|
|
1377
|
+
}
|
|
2068
1378
|
}
|
|
2069
1379
|
function recordGraphSnapshot(label, storeApi = graphStore) {
|
|
2070
|
-
|
|
2071
|
-
const snap = {
|
|
2072
|
-
seq: seqCounter++,
|
|
2073
|
-
at: Date.now(),
|
|
2074
|
-
...label !== void 0 ? { label } : {},
|
|
2075
|
-
data: cloneSlice(s)
|
|
2076
|
-
};
|
|
2077
|
-
ring.push(snap);
|
|
2078
|
-
if (ring.length > capacity) ring = ring.slice(-capacity);
|
|
2079
|
-
cursor = null;
|
|
2080
|
-
notify();
|
|
2081
|
-
return snap.seq;
|
|
1380
|
+
return getGraphDevtoolsCompatibilityDelegate(storeApi)?.capture(label) ?? -1;
|
|
2082
1381
|
}
|
|
2083
1382
|
function restoreGraphSnapshot(index, storeApi = graphStore) {
|
|
2084
|
-
|
|
2085
|
-
if (!snap) return false;
|
|
2086
|
-
const clone2 = cloneSlice(snap.data);
|
|
2087
|
-
storeApi.setState(clone2);
|
|
2088
|
-
cursor = index;
|
|
2089
|
-
notify();
|
|
2090
|
-
return true;
|
|
1383
|
+
return getGraphDevtoolsCompatibilityDelegate(storeApi)?.restoreByIndex(index) ?? false;
|
|
2091
1384
|
}
|
|
2092
1385
|
function restoreGraphSnapshotBySeq(seq, storeApi = graphStore) {
|
|
2093
|
-
|
|
2094
|
-
return index === -1 ? false : restoreGraphSnapshot(index, storeApi);
|
|
1386
|
+
return getGraphDevtoolsCompatibilityDelegate(storeApi)?.restoreByCursor(seq) ?? false;
|
|
2095
1387
|
}
|
|
2096
1388
|
function stepTimeTravel(delta, storeApi = graphStore) {
|
|
2097
|
-
|
|
2098
|
-
const target = Math.max(0, Math.min(ring.length - 1, base + delta));
|
|
2099
|
-
return restoreGraphSnapshot(target, storeApi);
|
|
1389
|
+
return getGraphDevtoolsCompatibilityDelegate(storeApi)?.step(delta) ?? false;
|
|
2100
1390
|
}
|
|
2101
|
-
function getTimeTravelState() {
|
|
2102
|
-
return {
|
|
2103
|
-
snapshots:
|
|
2104
|
-
cursor,
|
|
2105
|
-
capacity
|
|
1391
|
+
function getTimeTravelState(storeApi = graphStore) {
|
|
1392
|
+
return getGraphDevtoolsCompatibilityDelegate(storeApi)?.getState() ?? {
|
|
1393
|
+
snapshots: [],
|
|
1394
|
+
cursor: null,
|
|
1395
|
+
capacity: 50
|
|
2106
1396
|
};
|
|
2107
1397
|
}
|
|
2108
|
-
function subscribeTimeTravel(cb) {
|
|
2109
|
-
|
|
2110
|
-
return () => listeners.delete(cb);
|
|
1398
|
+
function subscribeTimeTravel(cb, storeApi = graphStore) {
|
|
1399
|
+
return subscribeGraphDevtoolsCompatibility(storeApi, cb);
|
|
2111
1400
|
}
|
|
2112
1401
|
|
|
2113
1402
|
// src/view/incremental.ts
|
|
@@ -2202,78 +1491,6 @@ var IncrementalView = class {
|
|
|
2202
1491
|
}
|
|
2203
1492
|
};
|
|
2204
1493
|
|
|
2205
|
-
// src/crud/relations.ts
|
|
2206
|
-
var schemaRegistry2 = /* @__PURE__ */ new Map();
|
|
2207
|
-
function registerSchema(schema) {
|
|
2208
|
-
schemaRegistry2.set(schema.type, schema);
|
|
2209
|
-
}
|
|
2210
|
-
function getSchema(type) {
|
|
2211
|
-
return schemaRegistry2.get(type) ?? null;
|
|
2212
|
-
}
|
|
2213
|
-
function cascadeInvalidation(ctx, storeApi = graphStore) {
|
|
2214
|
-
const schema = schemaRegistry2.get(ctx.type);
|
|
2215
|
-
if (!schema) return;
|
|
2216
|
-
const store = storeApi.getState();
|
|
2217
|
-
if (schema.globalListKeys) for (const key of schema.globalListKeys) store.invalidateLists(key);
|
|
2218
|
-
if (!schema.relations) return;
|
|
2219
|
-
for (const [, relation] of Object.entries(schema.relations)) {
|
|
2220
|
-
switch (relation.cardinality) {
|
|
2221
|
-
case "belongsTo": {
|
|
2222
|
-
const prevFk = ctx.previous?.[relation.foreignKey];
|
|
2223
|
-
const nextFk = ctx.next?.[relation.foreignKey];
|
|
2224
|
-
if (prevFk && prevFk !== nextFk && relation.invalidateTargetLists) for (const kp of relation.invalidateTargetLists) store.invalidateLists((k) => k.startsWith(kp) && k.includes(prevFk));
|
|
2225
|
-
if (nextFk && relation.invalidateTargetLists) for (const kp of relation.invalidateTargetLists) store.invalidateLists((k) => k.startsWith(kp) && k.includes(nextFk));
|
|
2226
|
-
if (prevFk) store.invalidateEntity(relation.targetType, prevFk);
|
|
2227
|
-
if (nextFk) store.invalidateEntity(relation.targetType, nextFk);
|
|
2228
|
-
break;
|
|
2229
|
-
}
|
|
2230
|
-
case "hasMany":
|
|
2231
|
-
store.invalidateLists(serializeKey(relation.listKeyPrefix(ctx.id)));
|
|
2232
|
-
break;
|
|
2233
|
-
case "manyToMany": {
|
|
2234
|
-
const prevIds = ctx.previous?.[relation.localArrayField ?? ""];
|
|
2235
|
-
const nextIds = ctx.next?.[relation.localArrayField ?? ""];
|
|
2236
|
-
for (const relatedId of /* @__PURE__ */ new Set([...prevIds ?? [], ...nextIds ?? []])) store.invalidateLists(serializeKey(relation.listKeyPrefix(relatedId)));
|
|
2237
|
-
break;
|
|
2238
|
-
}
|
|
2239
|
-
}
|
|
2240
|
-
}
|
|
2241
|
-
for (const [, otherSchema] of schemaRegistry2) {
|
|
2242
|
-
if (!otherSchema.relations) continue;
|
|
2243
|
-
for (const [, rel] of Object.entries(otherSchema.relations)) {
|
|
2244
|
-
if (rel.targetType !== ctx.type) continue;
|
|
2245
|
-
if (rel.cardinality === "hasMany") store.invalidateLists(serializeKey(rel.listKeyPrefix(ctx.id)));
|
|
2246
|
-
}
|
|
2247
|
-
}
|
|
2248
|
-
}
|
|
2249
|
-
function readRelations(type, entity, storeApi = graphStore) {
|
|
2250
|
-
const schema = schemaRegistry2.get(type);
|
|
2251
|
-
if (!schema?.relations) return {};
|
|
2252
|
-
const store = storeApi.getState();
|
|
2253
|
-
const result = {};
|
|
2254
|
-
for (const [name, relation] of Object.entries(schema.relations)) {
|
|
2255
|
-
switch (relation.cardinality) {
|
|
2256
|
-
case "belongsTo": {
|
|
2257
|
-
const fkValue = entity[relation.foreignKey];
|
|
2258
|
-
result[name] = fkValue ? store.readEntity(relation.targetType, fkValue) : null;
|
|
2259
|
-
break;
|
|
2260
|
-
}
|
|
2261
|
-
case "hasMany": {
|
|
2262
|
-
const listKey = serializeKey(relation.listKeyPrefix(entity.id));
|
|
2263
|
-
const listState = store.lists[listKey];
|
|
2264
|
-
result[name] = listState ? listState.ids.map((id) => store.readEntity(relation.targetType, id)).filter(Boolean) : [];
|
|
2265
|
-
break;
|
|
2266
|
-
}
|
|
2267
|
-
case "manyToMany": {
|
|
2268
|
-
const ids = entity[relation.localArrayField ?? ""];
|
|
2269
|
-
result[name] = ids ? ids.map((id) => store.readEntity(relation.targetType, id)).filter(Boolean) : [];
|
|
2270
|
-
break;
|
|
2271
|
-
}
|
|
2272
|
-
}
|
|
2273
|
-
}
|
|
2274
|
-
return result;
|
|
2275
|
-
}
|
|
2276
|
-
|
|
2277
1494
|
// src/agent/json-patch.ts
|
|
2278
1495
|
function unescape(token) {
|
|
2279
1496
|
return token.replace(/~1/g, "/").replace(/~0/g, "~");
|
|
@@ -2811,10 +2028,10 @@ function createGraphQLSubscriptionAdapter(opts) {
|
|
|
2811
2028
|
subscribe(_cfg, handler) {
|
|
2812
2029
|
const unsubs = [];
|
|
2813
2030
|
for (const sub of subscriptions) {
|
|
2814
|
-
const { type, document
|
|
2031
|
+
const { type, document, variables, getPayload } = sub;
|
|
2815
2032
|
unsubs.push(
|
|
2816
2033
|
client.subscribe(
|
|
2817
|
-
{ query:
|
|
2034
|
+
{ query: document, variables },
|
|
2818
2035
|
{
|
|
2819
2036
|
next: ({ data }) => {
|
|
2820
2037
|
const raw = getPayload(data);
|
|
@@ -3946,6 +3163,6 @@ function getFacetedRowModel(preFilteredRowModel, columnId, allFilteredRowModel)
|
|
|
3946
3163
|
return preFilteredRowModel;
|
|
3947
3164
|
}
|
|
3948
3165
|
|
|
3949
|
-
export {
|
|
3166
|
+
export { IncrementalView, RealtimeManager, TerminalError, TransientError, __resetActiveGraphStore, __resetEntityTransports, __resetStoreRegistry, applyAgUiDelta, applyAgUiSnapshot, applyJsonPatch, buildTenantWhere, collectDirtyPaths, configureTimeTravel, createConvexAdapter, createDevtoolsEventBus, createElectricAdapter, createFlintAdapter, createGraphAction, createGraphEffect, createGraphQLSubscriptionAdapter, createGraphTool, createGraphTransaction, createLoroMergeStrategy, createPGlitePersistenceAdapter, createRow, createSchemaGraphTool, createSupabaseRealtimeAdapter, createSurrealLiveAdapter, createTauriSqlPersistenceAdapter, createTenantScopedElectricAdapter, createWebSocketAdapter, escapeHtml, exportGraphSnapshot, exportGraphSnapshotWithSchemas, flattenClauses, getCoreRowModel, getRealtimeManager as getElectricRealtimeManager, getEntityJsonSchema, getEntityTransport, getExpandedRowModel, getFacetedMinMaxValues, getFacetedRowModel, getFacetedUniqueValues, getFilteredRowModel, getGraphSyncStatus, getGroupedRowModel, getPaginatedRowModel, getRealtimeManager, getRegisteredEntityTypes, getRegisteredStores, getSelectedRowModel, getSortedRowModel, getTimeTravelState, getValueAtPath, graphSyncStatusStore, hasCustomPredicates, humanizeFieldName, hydrateGraphFromStorage, inferSchemaFieldType, makeRestTransport, parseCreateTable, persistGraphToStorage, prepareGraphStoreScope, publishFlintMutation, queryOnce, recordGraphSnapshot, registerEntityFromSql, registerEntityJsonSchema, registerEntityTransport, registerRuntimeSchema, registerStore, registryKey, renderMarkdownToHtml, replayActionWithRetry, resetRealtimeManager, resolveActiveGraphStore, restoreGraphSnapshot, restoreGraphSnapshotBySeq, runWithGraphStore, selectGraph, setActiveGraphStore, setValueAtPath, sqlTypeToJsonSchema, startLocalFirstGraph, stepTimeTravel, subscribeTimeTravel, toEntityError, toGraphQLVariables, toPrismaOrderBy, toPrismaWhere, toRestParams, toSQLClauses };
|
|
3950
3167
|
//# sourceMappingURL=index.mjs.map
|
|
3951
3168
|
//# sourceMappingURL=index.mjs.map
|