@prometheus-ags/prometheus-entity-management 1.1.0 → 1.2.1

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/dist/index.mjs CHANGED
@@ -1,13 +1,13 @@
1
1
  import { create, createStore, useStore } from 'zustand';
2
2
  import { subscribeWithSelector, persist } from 'zustand/middleware';
3
3
  import { immer } from 'zustand/middleware/immer';
4
- import React5, { createContext, useSyncExternalStore, useMemo, useRef, useCallback, useEffect, useState, useContext, useId } from 'react';
4
+ import React6, { createContext, useMemo, useSyncExternalStore, useRef, useCallback, useEffect, useState, useContext, useId } from 'react';
5
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
5
6
  import { useShallow } from 'zustand/react/shallow';
6
7
  import { useReactTable, getSortedRowModel, getCoreRowModel, flexRender } from '@tanstack/react-table';
7
8
  import { Search, X, Loader2, RefreshCw, ChevronLeft, ChevronRight, Pencil, Trash2 } from 'lucide-react';
8
9
  import { clsx } from 'clsx';
9
10
  import { twMerge } from 'tailwind-merge';
10
- import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
11
11
 
12
12
  // src/graph.ts
13
13
  var EMPTY_IDS = [];
@@ -288,6 +288,8 @@ function applySelection(row, select) {
288
288
  }
289
289
 
290
290
  // src/graph-actions.ts
291
+ var graphActionListeners = /* @__PURE__ */ new Set();
292
+ var graphActionReplayers = /* @__PURE__ */ new Map();
291
293
  function createGraphTransaction() {
292
294
  const baseline = cloneGraphData();
293
295
  let closed = false;
@@ -355,22 +357,53 @@ function createGraphTransaction() {
355
357
  return tx;
356
358
  }
357
359
  function createGraphAction(opts) {
360
+ if (opts.key) {
361
+ graphActionReplayers.set(opts.key, async (record) => {
362
+ const tx = createGraphTransaction();
363
+ try {
364
+ const result = await opts.run(tx, record.input);
365
+ tx.commit();
366
+ return result;
367
+ } catch (error) {
368
+ tx.rollback();
369
+ throw error;
370
+ }
371
+ });
372
+ }
358
373
  return async (input) => {
359
374
  const tx = createGraphTransaction();
375
+ const record = opts.key ? {
376
+ id: `${opts.key}:${Date.now()}`,
377
+ key: opts.key,
378
+ input: structuredClone(input),
379
+ enqueuedAt: (/* @__PURE__ */ new Date()).toISOString()
380
+ } : null;
360
381
  try {
382
+ if (record) emitGraphActionEvent({ type: "enqueued", record });
361
383
  opts.optimistic?.(tx, input);
362
384
  const result = await opts.run(tx, input);
363
385
  opts.onSuccess?.(result, input, tx);
364
386
  tx.commit();
387
+ if (record) emitGraphActionEvent({ type: "settled", record });
365
388
  return result;
366
389
  } catch (error) {
367
390
  tx.rollback();
368
391
  const normalized = error instanceof Error ? error : new Error(String(error));
392
+ if (record) emitGraphActionEvent({ type: "settled", record });
369
393
  opts.onError?.(normalized, input);
370
394
  throw normalized;
371
395
  }
372
396
  };
373
397
  }
398
+ function subscribeGraphActionEvents(listener) {
399
+ graphActionListeners.add(listener);
400
+ return () => graphActionListeners.delete(listener);
401
+ }
402
+ async function replayRegisteredGraphAction(record) {
403
+ const replayer = graphActionReplayers.get(record.key);
404
+ if (!replayer) throw new Error(`No graph action registered for key "${record.key}"`);
405
+ return replayer(record);
406
+ }
374
407
  function cloneGraphData(source = useGraphStore.getState()) {
375
408
  return {
376
409
  entities: structuredClone(source.entities),
@@ -380,6 +413,9 @@ function cloneGraphData(source = useGraphStore.getState()) {
380
413
  lists: structuredClone(source.lists)
381
414
  };
382
415
  }
416
+ function emitGraphActionEvent(event) {
417
+ for (const listener of graphActionListeners) listener(event);
418
+ }
383
419
 
384
420
  // src/graph-effects.ts
385
421
  function createGraphEffect(opts) {
@@ -439,6 +475,213 @@ function defaultIsEqual(previousValue, nextValue) {
439
475
  return JSON.stringify(previousValue) === JSON.stringify(nextValue);
440
476
  }
441
477
 
478
+ // src/object-path.ts
479
+ function isObject(value) {
480
+ return typeof value === "object" && value !== null && !Array.isArray(value);
481
+ }
482
+ function getValueAtPath(source, path) {
483
+ if (!path) return source;
484
+ const segments = path.split(".").filter(Boolean);
485
+ let current = source;
486
+ for (const segment of segments) {
487
+ if (!isObject(current) && !Array.isArray(current)) return void 0;
488
+ current = current[segment];
489
+ }
490
+ return current;
491
+ }
492
+ function setValueAtPath(source, path, value) {
493
+ const segments = path.split(".").filter(Boolean);
494
+ if (segments.length === 0) return source;
495
+ const clone = structuredClone(source);
496
+ let current = clone;
497
+ for (let index = 0; index < segments.length - 1; index += 1) {
498
+ const segment = segments[index];
499
+ const next = current[segment];
500
+ if (!isObject(next)) current[segment] = {};
501
+ current = current[segment];
502
+ }
503
+ current[segments[segments.length - 1]] = value;
504
+ return clone;
505
+ }
506
+ function collectDirtyPaths(current, original, prefix = "", acc = /* @__PURE__ */ new Set()) {
507
+ if (isObject(current) && isObject(original)) {
508
+ const keys = /* @__PURE__ */ new Set([...Object.keys(current), ...Object.keys(original)]);
509
+ for (const key of keys) {
510
+ const nextPrefix = prefix ? `${prefix}.${key}` : key;
511
+ collectDirtyPaths(current[key], original[key], nextPrefix, acc);
512
+ }
513
+ return acc;
514
+ }
515
+ if (JSON.stringify(current) !== JSON.stringify(original) && prefix) acc.add(prefix);
516
+ return acc;
517
+ }
518
+ var schemaRegistry = /* @__PURE__ */ new Map();
519
+ function registerEntityJsonSchema(config) {
520
+ const key = registryKey(config.entityType, config.field, config.schemaId);
521
+ schemaRegistry.set(key, config);
522
+ }
523
+ function registerRuntimeSchema(config) {
524
+ registerEntityJsonSchema(config);
525
+ }
526
+ function getEntityJsonSchema(opts) {
527
+ const exact = schemaRegistry.get(registryKey(opts.entityType, opts.field, opts.schemaId));
528
+ if (exact) return exact;
529
+ if (opts.field) {
530
+ const byField = schemaRegistry.get(registryKey(opts.entityType, opts.field));
531
+ if (byField) return byField;
532
+ }
533
+ if (opts.schemaId) {
534
+ const byId = schemaRegistry.get(registryKey(opts.entityType, void 0, opts.schemaId));
535
+ if (byId) return byId;
536
+ }
537
+ for (const schema of schemaRegistry.values()) {
538
+ if (schema.entityType !== opts.entityType) continue;
539
+ if (opts.field && schema.field !== opts.field) continue;
540
+ return schema;
541
+ }
542
+ return null;
543
+ }
544
+ function useSchemaEntityFields(opts) {
545
+ return useMemo(() => {
546
+ const schema = opts.schema ?? getEntityJsonSchema(opts)?.schema;
547
+ if (!schema) return [];
548
+ return buildEntityFieldsFromSchema({ schema, rootField: opts.rootField ?? opts.field });
549
+ }, [opts.entityType, opts.field, opts.rootField, opts.schemaId, opts.schema]);
550
+ }
551
+ function buildEntityFieldsFromSchema(opts) {
552
+ return buildSchemaFields(opts.schema, opts.rootField ?? "", "");
553
+ }
554
+ function exportGraphSnapshotWithSchemas(opts) {
555
+ return JSON.stringify(
556
+ {
557
+ scope: opts.scope,
558
+ generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
559
+ data: opts.data,
560
+ schemas: opts.schemas.filter(Boolean)
561
+ },
562
+ null,
563
+ opts.pretty === false ? 0 : 2
564
+ );
565
+ }
566
+ function escapeHtml(input) {
567
+ return input.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
568
+ }
569
+ function renderMarkdownToHtml(value) {
570
+ const escaped = escapeHtml(value);
571
+ const blocks = escaped.split(/\n{2,}/).map((block) => block.trim()).filter(Boolean);
572
+ return blocks.map((block) => renderMarkdownBlock(block)).join("");
573
+ }
574
+ function MarkdownFieldRenderer({ value, className }) {
575
+ return /* @__PURE__ */ jsx(
576
+ "div",
577
+ {
578
+ className,
579
+ dangerouslySetInnerHTML: { __html: renderMarkdownToHtml(value ?? "") }
580
+ }
581
+ );
582
+ }
583
+ function MarkdownFieldEditor({
584
+ value,
585
+ onChange,
586
+ placeholder
587
+ }) {
588
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
589
+ /* @__PURE__ */ jsx(
590
+ "textarea",
591
+ {
592
+ value,
593
+ onChange: (event) => onChange(event.target.value),
594
+ placeholder,
595
+ className: "w-full min-h-[120px] rounded-md border bg-muted/50 px-3 py-2 text-sm resize-y focus:outline-none focus:ring-1 focus:ring-ring transition-colors"
596
+ }
597
+ ),
598
+ /* @__PURE__ */ jsx("div", { className: "rounded-md border bg-background px-3 py-2", children: /* @__PURE__ */ jsx(MarkdownFieldRenderer, { value, className: "prose prose-sm max-w-none" }) })
599
+ ] });
600
+ }
601
+ function createMarkdownDetailRenderer(field) {
602
+ return (value, entity) => /* @__PURE__ */ jsx(MarkdownFieldRenderer, { value: String(value ?? getValueAtPath(entity, field) ?? ""), className: "prose prose-sm max-w-none" });
603
+ }
604
+ function buildSchemaFields(schema, pathPrefix, schemaPathPrefix) {
605
+ if (schema.type === "object" && schema.properties) {
606
+ const entries = Object.entries(schema.properties).sort(([, left], [, right]) => {
607
+ const l = left["x-display-order"] ?? Number.MAX_SAFE_INTEGER;
608
+ const r = right["x-display-order"] ?? Number.MAX_SAFE_INTEGER;
609
+ return l - r;
610
+ });
611
+ return entries.flatMap(([key, childSchema]) => {
612
+ if (childSchema["x-hidden"]) return [];
613
+ const field = pathPrefix ? `${pathPrefix}.${key}` : key;
614
+ const schemaPath = schemaPathPrefix ? `${schemaPathPrefix}.${key}` : key;
615
+ if (childSchema.type === "object" && childSchema.properties) {
616
+ return buildSchemaFields(childSchema, field, schemaPath);
617
+ }
618
+ return [schemaField(field, schemaPath, childSchema, schema.required?.includes(key) ?? false)];
619
+ });
620
+ }
621
+ return [];
622
+ }
623
+ function schemaField(field, schemaPath, schema, required) {
624
+ const type = inferFieldType(schema);
625
+ const descriptor = {
626
+ field,
627
+ label: schema.title ?? humanize(field.split(".").pop() ?? field),
628
+ type,
629
+ required,
630
+ hint: schema.description,
631
+ schemaPath,
632
+ schema,
633
+ componentHint: schema["x-a2ui-component"]
634
+ };
635
+ if (schema.enum) {
636
+ descriptor.options = schema.enum.map((value) => ({
637
+ value: String(value),
638
+ label: String(value)
639
+ }));
640
+ }
641
+ if (type === "markdown") {
642
+ descriptor.render = createMarkdownDetailRenderer(field);
643
+ }
644
+ return descriptor;
645
+ }
646
+ function inferFieldType(schema) {
647
+ const forced = schema["x-field-type"];
648
+ if (forced === "markdown") return "markdown";
649
+ if (schema.format === "markdown") return "markdown";
650
+ if (schema.enum) return "enum";
651
+ const type = Array.isArray(schema.type) ? schema.type[0] : schema.type;
652
+ switch (type) {
653
+ case "boolean":
654
+ return "boolean";
655
+ case "integer":
656
+ case "number":
657
+ return "number";
658
+ case "string":
659
+ if (schema.format === "email") return "email";
660
+ if (schema.format === "uri" || schema.format === "url") return "url";
661
+ if (schema.format === "date" || schema.format === "date-time") return "date";
662
+ return "text";
663
+ case "array":
664
+ case "object":
665
+ return "json";
666
+ default:
667
+ return "text";
668
+ }
669
+ }
670
+ function registryKey(entityType, field, schemaId) {
671
+ return `${entityType}::${field ?? "*"}::${schemaId ?? "*"}`;
672
+ }
673
+ function humanize(value) {
674
+ return value.replace(/([a-z0-9])([A-Z])/g, "$1 $2").replace(/[_-]+/g, " ").replace(/\b\w/g, (char) => char.toUpperCase());
675
+ }
676
+ function renderMarkdownBlock(block) {
677
+ if (block.startsWith("# ")) return `<h1>${renderInlineMarkdown(block.slice(2))}</h1>`;
678
+ if (block.startsWith("## ")) return `<h2>${renderInlineMarkdown(block.slice(3))}</h2>`;
679
+ return `<p>${renderInlineMarkdown(block).replaceAll("\n", "<br/>")}</p>`;
680
+ }
681
+ function renderInlineMarkdown(block) {
682
+ return block.replace(/\*\*(.+?)\*\*/g, "<strong>$1</strong>");
683
+ }
684
+
442
685
  // src/ai-interop.ts
443
686
  function exportGraphSnapshot(opts) {
444
687
  const payload = {
@@ -455,6 +698,216 @@ function createGraphTool(handler) {
455
698
  exportGraphSnapshot
456
699
  });
457
700
  }
701
+ function createSchemaGraphTool(handler) {
702
+ return (input) => handler(input, {
703
+ store: useGraphStore.getState(),
704
+ queryOnce,
705
+ exportGraphSnapshot,
706
+ getEntityJsonSchema,
707
+ exportGraphSnapshotWithSchemas
708
+ });
709
+ }
710
+ var DEFAULT_STORAGE_KEY = "prometheus:graph";
711
+ var useGraphSyncStatusStore = create((set) => ({
712
+ status: {
713
+ phase: "idle",
714
+ isOnline: true,
715
+ isSynced: true,
716
+ pendingActions: 0,
717
+ lastHydratedAt: null,
718
+ lastPersistedAt: null,
719
+ storageKey: null,
720
+ error: null
721
+ },
722
+ setStatus: (status) => set((state) => ({
723
+ status: {
724
+ ...state.status,
725
+ ...status
726
+ }
727
+ }))
728
+ }));
729
+ var pendingActions = /* @__PURE__ */ new Map();
730
+ function useGraphSyncStatus() {
731
+ return useGraphSyncStatusStore((state) => state.status);
732
+ }
733
+ async function persistGraphToStorage(opts) {
734
+ const payload = {
735
+ version: 1,
736
+ snapshot: cloneGraphSnapshot(),
737
+ pendingActions: opts.pendingActions ?? Array.from(pendingActions.values())
738
+ };
739
+ const json = JSON.stringify(payload);
740
+ await opts.storage.set(opts.key, json);
741
+ const persistedAt = (/* @__PURE__ */ new Date()).toISOString();
742
+ useGraphSyncStatusStore.getState().setStatus({
743
+ lastPersistedAt: persistedAt,
744
+ storageKey: opts.key,
745
+ pendingActions: payload.pendingActions.length
746
+ });
747
+ return {
748
+ ok: true,
749
+ key: opts.key,
750
+ bytes: json.length,
751
+ persistedAt
752
+ };
753
+ }
754
+ async function hydrateGraphFromStorage(opts) {
755
+ const raw = await opts.storage.get(opts.key);
756
+ if (!raw) {
757
+ return {
758
+ ok: false,
759
+ key: opts.key,
760
+ hydratedAt: null,
761
+ entityCounts: {},
762
+ error: "No persisted graph snapshot found"
763
+ };
764
+ }
765
+ try {
766
+ const parsed = JSON.parse(raw);
767
+ useGraphStore.setState(parsed.snapshot);
768
+ pendingActions.clear();
769
+ for (const action of parsed.pendingActions ?? []) pendingActions.set(action.id, action);
770
+ const hydratedAt = (/* @__PURE__ */ new Date()).toISOString();
771
+ useGraphSyncStatusStore.getState().setStatus({
772
+ lastHydratedAt: hydratedAt,
773
+ storageKey: opts.key,
774
+ pendingActions: pendingActions.size,
775
+ error: null
776
+ });
777
+ return {
778
+ ok: true,
779
+ key: opts.key,
780
+ hydratedAt,
781
+ entityCounts: Object.fromEntries(
782
+ Object.entries(parsed.snapshot.entities).map(([type, entities]) => [type, Object.keys(entities).length])
783
+ ),
784
+ pendingActions: Array.from(pendingActions.values())
785
+ };
786
+ } catch (error) {
787
+ const message = error instanceof Error ? error.message : String(error);
788
+ useGraphSyncStatusStore.getState().setStatus({
789
+ phase: "error",
790
+ error: message,
791
+ storageKey: opts.key
792
+ });
793
+ return {
794
+ ok: false,
795
+ key: opts.key,
796
+ hydratedAt: null,
797
+ entityCounts: {},
798
+ error: message
799
+ };
800
+ }
801
+ }
802
+ function startLocalFirstGraph(opts) {
803
+ const key = opts.key ?? DEFAULT_STORAGE_KEY;
804
+ const persistDebounceMs = opts.persistDebounceMs ?? 50;
805
+ const statusStore = useGraphSyncStatusStore.getState();
806
+ statusStore.setStatus({
807
+ phase: "hydrating",
808
+ storageKey: key,
809
+ isOnline: opts.onlineSource?.getIsOnline() ?? getDefaultOnlineSource().getIsOnline(),
810
+ isSynced: pendingActions.size === 0,
811
+ error: null
812
+ });
813
+ let persistTimer = null;
814
+ const schedulePersist = () => {
815
+ if (persistTimer) clearTimeout(persistTimer);
816
+ persistTimer = setTimeout(() => {
817
+ void persistGraphToStorage({ storage: opts.storage, key });
818
+ }, persistDebounceMs);
819
+ };
820
+ const graphUnsub = useGraphStore.subscribe(() => {
821
+ schedulePersist();
822
+ });
823
+ const actionUnsub = subscribeGraphActionEvents((event) => {
824
+ if (event.type === "enqueued") pendingActions.set(event.record.id, event.record);
825
+ if (event.type === "settled") pendingActions.delete(event.record.id);
826
+ useGraphSyncStatusStore.getState().setStatus({
827
+ pendingActions: pendingActions.size,
828
+ isSynced: pendingActions.size === 0
829
+ });
830
+ schedulePersist();
831
+ });
832
+ const onlineSource = opts.onlineSource ?? getDefaultOnlineSource();
833
+ const onlineUnsub = onlineSource.subscribe((online) => {
834
+ useGraphSyncStatusStore.getState().setStatus({
835
+ isOnline: online,
836
+ phase: online ? "ready" : "offline"
837
+ });
838
+ });
839
+ const ready = (async () => {
840
+ const hydrated = await hydrateGraphFromStorage({ storage: opts.storage, key });
841
+ if (opts.replayPendingActions && hydrated.ok && pendingActions.size > 0) {
842
+ useGraphSyncStatusStore.getState().setStatus({
843
+ phase: "syncing",
844
+ isSynced: false
845
+ });
846
+ for (const action of Array.from(pendingActions.values())) {
847
+ await replayRegisteredGraphAction(action);
848
+ pendingActions.delete(action.id);
849
+ }
850
+ await persistGraphToStorage({ storage: opts.storage, key });
851
+ }
852
+ const online = onlineSource.getIsOnline();
853
+ useGraphSyncStatusStore.getState().setStatus({
854
+ phase: online ? "ready" : "offline",
855
+ isOnline: online,
856
+ isSynced: pendingActions.size === 0,
857
+ pendingActions: pendingActions.size
858
+ });
859
+ })();
860
+ return {
861
+ ready,
862
+ dispose() {
863
+ graphUnsub();
864
+ actionUnsub();
865
+ onlineUnsub();
866
+ if (persistTimer) clearTimeout(persistTimer);
867
+ },
868
+ async persistNow() {
869
+ await persistGraphToStorage({ storage: opts.storage, key });
870
+ },
871
+ hydrate() {
872
+ return hydrateGraphFromStorage({ storage: opts.storage, key });
873
+ },
874
+ getStatus() {
875
+ return useGraphSyncStatusStore.getState().status;
876
+ }
877
+ };
878
+ }
879
+ function cloneGraphSnapshot() {
880
+ const state = useGraphStore.getState();
881
+ return {
882
+ entities: structuredClone(state.entities),
883
+ patches: structuredClone(state.patches),
884
+ entityStates: structuredClone(state.entityStates),
885
+ syncMetadata: structuredClone(state.syncMetadata),
886
+ lists: structuredClone(state.lists)
887
+ };
888
+ }
889
+ function getDefaultOnlineSource() {
890
+ if (typeof window !== "undefined" && typeof window.addEventListener === "function") {
891
+ return {
892
+ getIsOnline: () => window.navigator.onLine,
893
+ subscribe: (listener) => {
894
+ const onlineHandler = () => listener(true);
895
+ const offlineHandler = () => listener(false);
896
+ window.addEventListener("online", onlineHandler);
897
+ window.addEventListener("offline", offlineHandler);
898
+ return () => {
899
+ window.removeEventListener("online", onlineHandler);
900
+ window.removeEventListener("offline", offlineHandler);
901
+ };
902
+ }
903
+ };
904
+ }
905
+ return {
906
+ getIsOnline: () => true,
907
+ subscribe: () => () => {
908
+ }
909
+ };
910
+ }
458
911
 
459
912
  // src/engine.ts
460
913
  function serializeKey(key) {
@@ -721,10 +1174,11 @@ function useEntity(opts) {
721
1174
  fetchRef.current = opts.fetch;
722
1175
  const normalizeRef = useRef(opts.normalize);
723
1176
  normalizeRef.current = opts.normalize;
724
- const data = useStore(useGraphStore, useShallow((state) => {
1177
+ const dataSelector = useCallback((state) => {
725
1178
  if (!id) return null;
726
1179
  return state.readEntitySnapshot(type, id);
727
- }));
1180
+ }, [id, type]);
1181
+ const data = useStore(useGraphStore, useShallow(dataSelector));
728
1182
  const entityState = useStore(useGraphStore, useCallback(
729
1183
  (state) => state.entityStates[`${type}:${id}`] ?? EMPTY_ENTITY_STATE,
730
1184
  [type, id]
@@ -757,13 +1211,11 @@ function useEntityList(opts) {
757
1211
  const normalizeRef = useRef(opts.normalize);
758
1212
  normalizeRef.current = opts.normalize;
759
1213
  const listState = useStore(useGraphStore, useCallback((state) => state.lists[key] ?? EMPTY_LIST_STATE, [key]));
760
- const items = useStore(
761
- useGraphStore,
762
- useShallow((state) => {
763
- const ids = state.lists[key]?.ids ?? EMPTY_IDS;
764
- return ids.map((id) => state.readEntitySnapshot(type, id)).filter((x) => x !== null);
765
- })
766
- );
1214
+ const itemsSelector = useCallback((state) => {
1215
+ const ids = state.lists[key]?.ids ?? EMPTY_IDS;
1216
+ return ids.map((id) => state.readEntitySnapshot(type, id)).filter((x) => x !== null);
1217
+ }, [key, type]);
1218
+ const items = useStore(useGraphStore, useShallow(itemsSelector));
767
1219
  const doFetch = useCallback((params = {}) => {
768
1220
  if (!enabled) return;
769
1221
  fetchList({ type, queryKey, mode, fetch: fetchRef.current, normalize: normalizeRef.current }, params, getEngineOptions(), false);
@@ -1436,15 +1888,15 @@ function useEntityView(opts) {
1436
1888
  }
1437
1889
 
1438
1890
  // src/crud/relations.ts
1439
- var schemaRegistry = /* @__PURE__ */ new Map();
1891
+ var schemaRegistry2 = /* @__PURE__ */ new Map();
1440
1892
  function registerSchema(schema) {
1441
- schemaRegistry.set(schema.type, schema);
1893
+ schemaRegistry2.set(schema.type, schema);
1442
1894
  }
1443
1895
  function getSchema(type) {
1444
- return schemaRegistry.get(type) ?? null;
1896
+ return schemaRegistry2.get(type) ?? null;
1445
1897
  }
1446
1898
  function cascadeInvalidation(ctx) {
1447
- const schema = schemaRegistry.get(ctx.type);
1899
+ const schema = schemaRegistry2.get(ctx.type);
1448
1900
  if (!schema) return;
1449
1901
  const store = useGraphStore.getState();
1450
1902
  if (schema.globalListKeys) for (const key of schema.globalListKeys) store.invalidateLists(key);
@@ -1471,7 +1923,7 @@ function cascadeInvalidation(ctx) {
1471
1923
  }
1472
1924
  }
1473
1925
  }
1474
- for (const [, otherSchema] of schemaRegistry) {
1926
+ for (const [, otherSchema] of schemaRegistry2) {
1475
1927
  if (!otherSchema.relations) continue;
1476
1928
  for (const [, rel] of Object.entries(otherSchema.relations)) {
1477
1929
  if (rel.targetType !== ctx.type) continue;
@@ -1480,7 +1932,7 @@ function cascadeInvalidation(ctx) {
1480
1932
  }
1481
1933
  }
1482
1934
  function readRelations(type, entity) {
1483
- const schema = schemaRegistry.get(type);
1935
+ const schema = schemaRegistry2.get(type);
1484
1936
  if (!schema?.relations) return {};
1485
1937
  const store = useGraphStore.getState();
1486
1938
  const result = {};
@@ -1541,7 +1993,7 @@ function useEntityCRUD(opts) {
1541
1993
  useEffect(() => {
1542
1994
  if (detail) setEditBuffer({ ...detail });
1543
1995
  }, [selectedId]);
1544
- const setField = useCallback((field, value) => setEditBuffer((prev) => ({ ...prev, [field]: value })), []);
1996
+ const setField = useCallback((field, value) => setEditBuffer((prev) => setValueAtPath(prev, String(field), value)), []);
1545
1997
  const setFields = useCallback((fields) => setEditBuffer((prev) => ({ ...prev, ...fields })), []);
1546
1998
  const resetBuffer = useCallback(() => {
1547
1999
  const current = selectedId ? useGraphStore.getState().readEntity(type, selectedId) : null;
@@ -1549,10 +2001,7 @@ function useEntityCRUD(opts) {
1549
2001
  }, [type, selectedId]);
1550
2002
  const dirty = useMemo(() => {
1551
2003
  if (!detail) return { changed: /* @__PURE__ */ new Set(), isDirty: false };
1552
- const changed = /* @__PURE__ */ new Set();
1553
- for (const key of Object.keys(editBuffer)) {
1554
- if (JSON.stringify(editBuffer[key]) !== JSON.stringify(detail[key])) changed.add(key);
1555
- }
2004
+ const changed = collectDirtyPaths(editBuffer, detail);
1556
2005
  return { changed, isDirty: changed.size > 0 };
1557
2006
  }, [editBuffer, detail]);
1558
2007
  const startEdit = useCallback((id) => {
@@ -1609,7 +2058,7 @@ function useEntityCRUD(opts) {
1609
2058
  const [createBuffer, setCreateBuffer] = useState({ ...createDefaults });
1610
2059
  const [isCreating, setIsCreating] = useState(false);
1611
2060
  const [createError, setCreateError] = useState(null);
1612
- const setCreateField = useCallback((field, value) => setCreateBuffer((prev) => ({ ...prev, [field]: value })), []);
2061
+ const setCreateField = useCallback((field, value) => setCreateBuffer((prev) => setValueAtPath(prev, String(field), value)), []);
1613
2062
  const setCreateFields = useCallback((fields) => setCreateBuffer((prev) => ({ ...prev, ...fields })), []);
1614
2063
  const resetCreateBuffer = useCallback(() => setCreateBuffer({ ...optsRef.current.createDefaults ?? {} }), []);
1615
2064
  const startCreate = useCallback(() => {
@@ -1622,7 +2071,7 @@ function useEntityCRUD(opts) {
1622
2071
  setMode("list");
1623
2072
  setCreateError(null);
1624
2073
  }, [resetCreateBuffer]);
1625
- const create2 = useCallback(async () => {
2074
+ const create3 = useCallback(async () => {
1626
2075
  if (!onCreate) return null;
1627
2076
  setIsCreating(true);
1628
2077
  setCreateError(null);
@@ -1696,7 +2145,7 @@ function useEntityCRUD(opts) {
1696
2145
  setIsDeleting(false);
1697
2146
  }
1698
2147
  }, [type, selectedId, listQueryKey, clearSelectionAfterDelete]);
1699
- return { mode, setMode, list, selectedId, select, openDetail, detail: detail ?? null, detailIsLoading, detailError: detailError ?? null, relations, editBuffer, setField, setFields, resetBuffer, dirty, startEdit, cancelEdit, save, isSaving, saveError, applyOptimistic, createBuffer, setCreateField, setCreateFields, resetCreateBuffer, startCreate, cancelCreate, create: create2, isCreating, createError, deleteEntity, isDeleting, deleteError, isEditing: mode === "edit" || mode === "create" };
2148
+ return { mode, setMode, list, selectedId, select, openDetail, detail: detail ?? null, detailIsLoading, detailError: detailError ?? null, relations, editBuffer, setField, setFields, resetBuffer, dirty, startEdit, cancelEdit, save, isSaving, saveError, applyOptimistic, createBuffer, setCreateField, setCreateFields, resetCreateBuffer, startCreate, cancelCreate, create: create3, isCreating, createError, deleteEntity, isDeleting, deleteError, isEditing: mode === "edit" || mode === "create" };
1700
2149
  }
1701
2150
 
1702
2151
  // src/adapters/realtime-manager.ts
@@ -2744,7 +3193,7 @@ function EntityTable({ viewResult, columns, getRowId = (r) => String(r.id), sele
2744
3193
  ] });
2745
3194
  }
2746
3195
  function Sheet({ open, onClose, title, subtitle, children, footer, width = "w-[480px]" }) {
2747
- React5.useEffect(() => {
3196
+ React6.useEffect(() => {
2748
3197
  const h = (e) => {
2749
3198
  if (e.key === "Escape") onClose();
2750
3199
  };
@@ -2780,6 +3229,8 @@ function FieldControl({ descriptor, value, onChange, entity, readonly }) {
2780
3229
  return /* @__PURE__ */ jsx("input", { type: "number", value: String(value ?? ""), onChange: (e) => onChange(e.target.valueAsNumber), placeholder: descriptor.placeholder, className: base });
2781
3230
  case "textarea":
2782
3231
  return /* @__PURE__ */ jsx("textarea", { value: String(value ?? ""), onChange: (e) => onChange(e.target.value), placeholder: descriptor.placeholder, className: "w-full min-h-[80px] rounded-md border bg-muted/50 px-3 py-2 text-sm resize-none focus:outline-none focus:ring-1 focus:ring-ring transition-colors" });
3232
+ case "markdown":
3233
+ return /* @__PURE__ */ jsx(MarkdownFieldEditor, { value: String(value ?? ""), onChange: (nextValue) => onChange(nextValue), placeholder: descriptor.placeholder });
2783
3234
  case "date":
2784
3235
  return /* @__PURE__ */ jsx("input", { type: "date", value: value ? new Date(value).toISOString().split("T")[0] : "", onChange: (e) => onChange(e.target.value ? new Date(e.target.value).toISOString() : null), className: base });
2785
3236
  case "boolean":
@@ -2799,12 +3250,35 @@ function FieldControl({ descriptor, value, onChange, entity, readonly }) {
2799
3250
  !value && /* @__PURE__ */ jsx("option", { value: "", children: "Select\u2026" }),
2800
3251
  (descriptor.options ?? []).map((o) => /* @__PURE__ */ jsx("option", { value: o.value, children: o.label }, o.value))
2801
3252
  ] });
3253
+ case "json":
3254
+ return /* @__PURE__ */ jsx(
3255
+ "textarea",
3256
+ {
3257
+ value: value != null ? JSON.stringify(value, null, 2) : "",
3258
+ onChange: (event) => {
3259
+ const nextValue = event.target.value;
3260
+ try {
3261
+ onChange(nextValue ? JSON.parse(nextValue) : null);
3262
+ } catch {
3263
+ onChange(nextValue);
3264
+ }
3265
+ },
3266
+ placeholder: descriptor.placeholder,
3267
+ className: "w-full min-h-[120px] rounded-md border bg-muted/50 px-3 py-2 text-sm font-mono resize-y focus:outline-none focus:ring-1 focus:ring-ring transition-colors"
3268
+ }
3269
+ );
2802
3270
  default:
2803
3271
  return /* @__PURE__ */ jsx("input", { value: String(value ?? ""), onChange: (e) => onChange(e.target.value), className: base });
2804
3272
  }
2805
3273
  }
3274
+ function FieldReadonlyValue({ descriptor, value, entity }) {
3275
+ if (descriptor.render) return /* @__PURE__ */ jsx(Fragment, { children: descriptor.render(value, entity) });
3276
+ if (descriptor.type === "markdown") return /* @__PURE__ */ jsx(MarkdownFieldRenderer, { value: String(value ?? ""), className: "prose prose-sm max-w-none py-1" });
3277
+ if (descriptor.type === "json") return /* @__PURE__ */ jsx("pre", { className: "text-xs py-1 whitespace-pre-wrap break-words", children: JSON.stringify(value ?? null, null, 2) });
3278
+ return /* @__PURE__ */ jsx("p", { className: "text-sm py-1", children: value != null && value !== "" ? String(value) : "\u2014" });
3279
+ }
2806
3280
  function EntityDetailSheet({ crud, fields, title = "Details", description, children, showEditButton = true, showDeleteButton = true, deleteConfirmMessage = "This action cannot be undone." }) {
2807
- const [confirmDelete, setConfirmDelete] = React5.useState(false);
3281
+ const [confirmDelete, setConfirmDelete] = React6.useState(false);
2808
3282
  const open = crud.mode === "detail" && !!crud.selectedId;
2809
3283
  const entity = crud.detail;
2810
3284
  const resolvedTitle = entity && typeof title === "function" ? title(entity) : String(title);
@@ -2828,8 +3302,7 @@ function EntityDetailSheet({ crud, fields, title = "Details", description, child
2828
3302
  entity && /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-4", children: [
2829
3303
  fields.map((f) => /* @__PURE__ */ jsxs("div", { children: [
2830
3304
  /* @__PURE__ */ jsx("p", { className: "text-[10px] font-medium text-muted-foreground uppercase tracking-wide mb-1", children: f.label }),
2831
- /* @__PURE__ */ jsx(FieldControl, { descriptor: f, value: entity[f.field], onChange: () => {
2832
- }, entity, readonly: true })
3305
+ /* @__PURE__ */ jsx(FieldReadonlyValue, { descriptor: f, value: getValueAtPath(entity, f.field), entity })
2833
3306
  ] }, f.field)),
2834
3307
  children && /* @__PURE__ */ jsxs(Fragment, { children: [
2835
3308
  /* @__PURE__ */ jsx("div", { className: "border-t my-1" }),
@@ -2899,13 +3372,14 @@ function EntityFormSheet({ crud, fields, createTitle = "Create", editTitle = "Ed
2899
3372
  error && /* @__PURE__ */ jsx("div", { className: "px-3 py-2 rounded-md bg-destructive/10 border border-destructive/20 text-xs text-destructive", children: error }),
2900
3373
  visibleFields.map((f) => {
2901
3374
  const isDirty = !isCreate && crud.dirty.changed.has(f.field);
3375
+ const currentValue = getValueAtPath(buf, f.field);
2902
3376
  return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1.5", children: [
2903
3377
  /* @__PURE__ */ jsxs("label", { className: cn("text-xs font-medium", isDirty ? "text-primary" : "text-muted-foreground"), children: [
2904
3378
  f.label,
2905
3379
  f.required && /* @__PURE__ */ jsx("span", { className: "text-destructive ml-0.5", children: "*" }),
2906
3380
  isDirty && /* @__PURE__ */ jsx("span", { className: "ml-1.5 text-[10px] font-normal opacity-70", children: "modified" })
2907
3381
  ] }),
2908
- /* @__PURE__ */ jsx(FieldControl, { descriptor: f, value: buf[f.field], onChange: (v) => setField(f.field, v), entity: buf, readonly: f.readonlyOnEdit && isEdit }),
3382
+ /* @__PURE__ */ jsx(FieldControl, { descriptor: f, value: currentValue, onChange: (v) => setField(f.field, v), entity: buf, readonly: f.readonlyOnEdit && isEdit }),
2909
3383
  f.hint && /* @__PURE__ */ jsx("p", { className: "text-[10px] text-muted-foreground", children: f.hint })
2910
3384
  ] }, f.field);
2911
3385
  })
@@ -4106,9 +4580,9 @@ function createSelectionStore() {
4106
4580
  function useSelectionStore(store, selector) {
4107
4581
  return useStore(store, selector);
4108
4582
  }
4109
- var SelectionContext = React5.createContext(null);
4583
+ var SelectionContext = React6.createContext(null);
4110
4584
  function useSelectionContext() {
4111
- const store = React5.useContext(SelectionContext);
4585
+ const store = React6.useContext(SelectionContext);
4112
4586
  if (!store) throw new Error("useSelectionContext must be used within a SelectionContext.Provider");
4113
4587
  return store;
4114
4588
  }
@@ -5023,7 +5497,7 @@ function useTableStorageAdapter() {
5023
5497
  function useTableRealtimeMode() {
5024
5498
  return useContext(TableStorageContext).realtimeMode;
5025
5499
  }
5026
- var Table = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { className: "relative w-full overflow-auto", children: /* @__PURE__ */ jsx(
5500
+ var Table = React6.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { className: "relative w-full overflow-auto", children: /* @__PURE__ */ jsx(
5027
5501
  "table",
5028
5502
  {
5029
5503
  ref,
@@ -5032,11 +5506,11 @@ var Table = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */
5032
5506
  }
5033
5507
  ) }));
5034
5508
  Table.displayName = "Table";
5035
- var TableHeader = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("thead", { ref, className: cn("bg-muted/60", className), ...props }));
5509
+ var TableHeader = React6.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("thead", { ref, className: cn("bg-muted/60", className), ...props }));
5036
5510
  TableHeader.displayName = "TableHeader";
5037
- var TableBody = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("tbody", { ref, className: cn("bg-background", className), ...props }));
5511
+ var TableBody = React6.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("tbody", { ref, className: cn("bg-background", className), ...props }));
5038
5512
  TableBody.displayName = "TableBody";
5039
- var TableFooter = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
5513
+ var TableFooter = React6.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
5040
5514
  "tfoot",
5041
5515
  {
5042
5516
  ref,
@@ -5045,7 +5519,7 @@ var TableFooter = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE
5045
5519
  }
5046
5520
  ));
5047
5521
  TableFooter.displayName = "TableFooter";
5048
- var TableRow = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
5522
+ var TableRow = React6.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
5049
5523
  "tr",
5050
5524
  {
5051
5525
  ref,
@@ -5057,7 +5531,7 @@ var TableRow = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE__
5057
5531
  }
5058
5532
  ));
5059
5533
  TableRow.displayName = "TableRow";
5060
- var TableHead = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
5534
+ var TableHead = React6.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
5061
5535
  "th",
5062
5536
  {
5063
5537
  ref,
@@ -5069,7 +5543,7 @@ var TableHead = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE__
5069
5543
  }
5070
5544
  ));
5071
5545
  TableHead.displayName = "TableHead";
5072
- var TableCell = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
5546
+ var TableCell = React6.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
5073
5547
  "td",
5074
5548
  {
5075
5549
  ref,
@@ -5081,7 +5555,7 @@ var TableCell = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE__
5081
5555
  }
5082
5556
  ));
5083
5557
  TableCell.displayName = "TableCell";
5084
- var TableCaption = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
5558
+ var TableCaption = React6.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
5085
5559
  "caption",
5086
5560
  {
5087
5561
  ref,
@@ -6600,7 +7074,7 @@ function ChevronsRightIcon({ className }) {
6600
7074
  ] });
6601
7075
  }
6602
7076
  function EmptyState({ config, isFiltered = false, className }) {
6603
- if (React5.isValidElement(config)) {
7077
+ if (React6.isValidElement(config)) {
6604
7078
  return /* @__PURE__ */ jsx(Fragment, { children: config });
6605
7079
  }
6606
7080
  const cfg = config ?? {};
@@ -8000,13 +8474,13 @@ function selectionColumn2() {
8000
8474
  enableFiltering: false,
8001
8475
  enableHiding: false,
8002
8476
  enableResizing: false,
8003
- header: ({ table }) => React5.createElement("input", {
8477
+ header: ({ table }) => React6.createElement("input", {
8004
8478
  type: "checkbox",
8005
8479
  checked: table.getIsAllPageRowsSelected(),
8006
8480
  onChange: table.getToggleAllPageRowsSelectedHandler(),
8007
8481
  className: "h-4 w-4 rounded border-primary text-primary focus:ring-ring"
8008
8482
  }),
8009
- cell: ({ row }) => React5.createElement("input", {
8483
+ cell: ({ row }) => React6.createElement("input", {
8010
8484
  type: "checkbox",
8011
8485
  checked: row.getIsSelected(),
8012
8486
  onChange: row.getToggleSelectedHandler(),
@@ -8142,7 +8616,7 @@ function enumColumn2(options) {
8142
8616
  const opt = options.options.find((o) => o.value === val);
8143
8617
  if (!opt) return val;
8144
8618
  if (opt.badgeClassName) {
8145
- return React5.createElement(
8619
+ return React6.createElement(
8146
8620
  "span",
8147
8621
  {
8148
8622
  className: `inline-flex items-center rounded px-1.5 py-0.5 text-[11px] font-medium capitalize ${opt.badgeClassName}`
@@ -8150,7 +8624,7 @@ function enumColumn2(options) {
8150
8624
  opt.label
8151
8625
  );
8152
8626
  }
8153
- return React5.createElement(
8627
+ return React6.createElement(
8154
8628
  "span",
8155
8629
  {
8156
8630
  className: "inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium",
@@ -8187,6 +8661,6 @@ function actionsColumn2() {
8187
8661
  };
8188
8662
  }
8189
8663
 
8190
- export { ActionButtonRow, ActionDropdown, ColumnPresetDialog, DataTable, DataTableColumnHeader, DataTableFilter, DataTablePagination, DataTableToolbar, ElectricSQLAdapter as ElectricSQLPresetAdapter, EmptyState, EntityDetailSheet, EntityFormSheet, EntityListView, EntityTable, FilterPresetDialog, GQLClient, GalleryView, InlineCellEditor, InlineItemEditor, ListView, MemoryAdapter, MultiSelectBar, PresetPicker, InlineCellEditor2 as PureInlineCellEditor, RealtimeManager, RestApiAdapter, SelectionContext, Sheet, SortHeader, SupabaseRealtimeAdapter as SupabasePresetAdapter, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, TableStorageProvider, ViewModeSwitcher, ZustandPersistAdapter, actionsColumn, applyView, booleanColumn, cascadeInvalidation, checkCompleteness, compareEntities, configureEngine, createConvexAdapter, createElectricAdapter, createGQLClient, createGraphAction, createGraphEffect, createGraphQLSubscriptionAdapter, createGraphTool, createGraphTransaction, createPresetStore, createPrismaEntityConfig, createRow, createSelectionStore, createSupabaseRealtimeAdapter, createWebSocketAdapter, dateColumn, dedupe, deleteAction, editAction, enumColumn, executeGQL, exportGraphSnapshot, fetchEntity, fetchList, flattenClauses, getCoreRowModel2 as getCoreRowModel, getExpandedRowModel, getFacetedMinMaxValues, getFacetedRowModel, getFacetedUniqueValues, getFilteredRowModel, getGroupedRowModel, getPaginatedRowModel, getRealtimeManager, getSchema, getSelectedRowModel, getSortedRowModel2 as getSortedRowModel, hasCustomPredicates, matchesFilter, matchesSearch, normalizeGQLResponse, numberColumn, prismaRelationsToSchema, actionsColumn2 as pureActionsColumn, booleanColumn2 as pureBooleanColumn, dateColumn2 as pureDateColumn, enumColumn2 as pureEnumColumn, numberColumn2 as pureNumberColumn, selectionColumn2 as pureSelectionColumn, textColumn2 as pureTextColumn, queryOnce, readRelations, registerSchema, resetRealtimeManager, selectGraph, selectionColumn, serializeKey, startGarbageCollector, stopGarbageCollector, textColumn, toGraphQLVariables, toPrismaInclude, toPrismaOrderBy, toPrismaWhere, toRestParams, toSQLClauses, useEntity, useEntityAugment, useEntityCRUD, useEntityList, useEntityMutation, useEntityView, useGQLEntity, useGQLList, useGQLMutation, useGQLSubscription, useGraphDevTools, useGraphStore, useLocalFirst, usePGliteQuery, useSelectionContext, useSelectionStore, useSuspenseEntity, useSuspenseEntityList, useTable, useTablePresets, useTableRealtimeMode, useTableStorageAdapter, viewAction };
8664
+ export { ActionButtonRow, ActionDropdown, ColumnPresetDialog, DataTable, DataTableColumnHeader, DataTableFilter, DataTablePagination, DataTableToolbar, ElectricSQLAdapter as ElectricSQLPresetAdapter, EmptyState, EntityDetailSheet, EntityFormSheet, EntityListView, EntityTable, FilterPresetDialog, GQLClient, GalleryView, InlineCellEditor, InlineItemEditor, ListView, MarkdownFieldEditor, MarkdownFieldRenderer, MemoryAdapter, MultiSelectBar, PresetPicker, InlineCellEditor2 as PureInlineCellEditor, RealtimeManager, RestApiAdapter, SelectionContext, Sheet, SortHeader, SupabaseRealtimeAdapter as SupabasePresetAdapter, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, TableStorageProvider, ViewModeSwitcher, ZustandPersistAdapter, actionsColumn, applyView, booleanColumn, buildEntityFieldsFromSchema, cascadeInvalidation, checkCompleteness, compareEntities, configureEngine, createConvexAdapter, createElectricAdapter, createGQLClient, createGraphAction, createGraphEffect, createGraphQLSubscriptionAdapter, createGraphTool, createGraphTransaction, createPresetStore, createPrismaEntityConfig, createRow, createSchemaGraphTool, createSelectionStore, createSupabaseRealtimeAdapter, createWebSocketAdapter, dateColumn, dedupe, deleteAction, editAction, enumColumn, executeGQL, exportGraphSnapshot, exportGraphSnapshotWithSchemas, fetchEntity, fetchList, flattenClauses, getCoreRowModel2 as getCoreRowModel, getEntityJsonSchema, getExpandedRowModel, getFacetedMinMaxValues, getFacetedRowModel, getFacetedUniqueValues, getFilteredRowModel, getGroupedRowModel, getPaginatedRowModel, getRealtimeManager, getSchema, getSelectedRowModel, getSortedRowModel2 as getSortedRowModel, hasCustomPredicates, hydrateGraphFromStorage, matchesFilter, matchesSearch, normalizeGQLResponse, numberColumn, persistGraphToStorage, prismaRelationsToSchema, actionsColumn2 as pureActionsColumn, booleanColumn2 as pureBooleanColumn, dateColumn2 as pureDateColumn, enumColumn2 as pureEnumColumn, numberColumn2 as pureNumberColumn, selectionColumn2 as pureSelectionColumn, textColumn2 as pureTextColumn, queryOnce, readRelations, registerEntityJsonSchema, registerRuntimeSchema, registerSchema, renderMarkdownToHtml, resetRealtimeManager, selectGraph, selectionColumn, serializeKey, startGarbageCollector, startLocalFirstGraph, stopGarbageCollector, textColumn, toGraphQLVariables, toPrismaInclude, toPrismaOrderBy, toPrismaWhere, toRestParams, toSQLClauses, useEntity, useEntityAugment, useEntityCRUD, useEntityList, useEntityMutation, useEntityView, useGQLEntity, useGQLList, useGQLMutation, useGQLSubscription, useGraphDevTools, useGraphStore, useGraphSyncStatus, useLocalFirst, usePGliteQuery, useSchemaEntityFields, useSelectionContext, useSelectionStore, useSuspenseEntity, useSuspenseEntityList, useTable, useTablePresets, useTableRealtimeMode, useTableStorageAdapter, viewAction };
8191
8665
  //# sourceMappingURL=index.mjs.map
8192
8666
  //# sourceMappingURL=index.mjs.map