@prometheus-ags/prometheus-entity-management 1.2.3 → 2.0.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/dist/index.d.mts CHANGED
@@ -5,6 +5,77 @@ import React$1, { ReactNode } from 'react';
5
5
  import { ColumnDef as ColumnDef$1 } from '@tanstack/react-table';
6
6
  import { PersistStorage } from 'zustand/middleware';
7
7
 
8
+ /**
9
+ * Typed errors used throughout 2.0 to drive retry policy and consumer
10
+ * UI decisions.
11
+ *
12
+ * Why two classes (not a discriminator field):
13
+ * - `instanceof` checks are zero-cost at runtime and survive bundler
14
+ * minification of property names.
15
+ * - Consumers can write `if (error instanceof TerminalError) renderInline()`
16
+ * without importing a type-narrowing helper.
17
+ * - The engine's retry policy is one `instanceof TransientError` check.
18
+ *
19
+ * 4xx → `TerminalError` (no retry — the request is structurally wrong:
20
+ * unauthorized, not-found, schema mismatch, validation failure).
21
+ *
22
+ * 5xx + network failures → `TransientError` (engine retries with
23
+ * exponential backoff up to `maxRetries`).
24
+ *
25
+ * Custom transports can throw either class. The default REST helper
26
+ * (`makeRestTransport`) maps HTTP status codes to the appropriate
27
+ * class automatically.
28
+ *
29
+ * Both classes preserve the original error via the standard
30
+ * `cause` option so stack traces survive the boundary.
31
+ */
32
+ interface EntityErrorOptions {
33
+ /** HTTP status if the underlying transport was HTTP. */
34
+ status?: number;
35
+ /** Original thrown value (`Error`, `Response`, anything). */
36
+ cause?: unknown;
37
+ }
38
+ /**
39
+ * Permanent failure — do not retry. The request will not succeed by
40
+ * trying again with the same inputs.
41
+ *
42
+ * Typical sources: HTTP 4xx, missing tables, validation errors,
43
+ * permission denied, schema mismatches.
44
+ */
45
+ declare class TerminalError extends Error {
46
+ readonly kind: "terminal";
47
+ readonly status?: number;
48
+ constructor(message: string, opts?: EntityErrorOptions);
49
+ }
50
+ /**
51
+ * Temporary failure — safe to retry. The engine will retry with
52
+ * exponential backoff up to the configured `maxRetries`.
53
+ *
54
+ * Typical sources: HTTP 5xx, network timeouts, fetch rejections,
55
+ * dropped sockets.
56
+ */
57
+ declare class TransientError extends Error {
58
+ readonly kind: "transient";
59
+ readonly status?: number;
60
+ constructor(message: string, opts?: EntityErrorOptions);
61
+ }
62
+ /**
63
+ * Union of every typed error the library raises. Use on consumer-side
64
+ * `error` props when both classes are possible.
65
+ */
66
+ type EntityError = TerminalError | TransientError;
67
+ /**
68
+ * Convert an unknown thrown value into a typed entity error.
69
+ *
70
+ * - Already-typed errors pass through.
71
+ * - HTTP-status-bearing errors become Terminal (4xx) or Transient (5xx).
72
+ * - `AbortError` / `DOMException` "AbortError" → Terminal (caller
73
+ * cancelled; not worth retrying).
74
+ * - Everything else → Transient (assume retryable; better than
75
+ * accidentally permanently failing on a one-off network blip).
76
+ */
77
+ declare function toEntityError(err: unknown): EntityError;
78
+
8
79
  /** Logical entity kind (e.g. `"Post"`). Used to partition the normalized graph. */
9
80
  type EntityType = string;
10
81
  /** Primary key for an entity within its `type`. Lists and relations reference this, not row copies. */
@@ -20,7 +91,7 @@ interface EntitySyncMetadata {
20
91
  updatedAt: number | null;
21
92
  }
22
93
  /** Snapshot shape returned by sync-aware reads and graph-native query helpers. */
23
- type EntitySnapshot<T extends Record<string, unknown>> = T & {
94
+ type EntitySnapshot<T extends object> = T & {
24
95
  $synced: boolean;
25
96
  $origin: SyncOrigin;
26
97
  $updatedAt: number | null;
@@ -49,6 +120,14 @@ interface ListState {
49
120
  isFetching: boolean;
50
121
  isFetchingMore: boolean;
51
122
  error: string | null;
123
+ /**
124
+ * Typed error instance for 2.0 hooks (`useEntities`, `useEntityQuery`).
125
+ * Carries `TerminalError` / `TransientError` so consumers can
126
+ * `instanceof`-check the failure mode without parsing the string in
127
+ * `error`. Both fields are written together by `setListError`; the
128
+ * string `error` field remains for back-compat with 1.x consumers.
129
+ */
130
+ lastError: EntityError | null;
52
131
  lastFetched: number | null;
53
132
  stale: boolean;
54
133
  currentPage: number | null;
@@ -131,8 +210,13 @@ interface GraphState {
131
210
  setListFetching: (key: QueryKey, fetching: boolean) => void;
132
211
  /** Pagination / “load more” in progress for the same list key. */
133
212
  setListFetchingMore: (key: QueryKey, fetchingMore: boolean) => void;
134
- /** Record list fetch failure; clears both fetching flags. */
135
- setListError: (key: QueryKey, error: string | null) => void;
213
+ /**
214
+ * Record list fetch failure; clears both fetching flags.
215
+ * The optional `typed` argument is the typed `EntityError` instance
216
+ * (used by 2.0 hooks); when omitted only the string `error` field is
217
+ * populated (back-compat with 1.x callers).
218
+ */
219
+ setListError: (key: QueryKey, error: string | null, typed?: EntityError | null) => void;
136
220
  /** Mark a list query stale so hooks can refetch without discarding current ids (stale-while-revalidate). */
137
221
  setListStale: (key: QueryKey, stale: boolean) => void;
138
222
  /**
@@ -210,6 +294,21 @@ declare const useGraphStore: zustand.UseBoundStore<Omit<Omit<zustand.StoreApi<Gr
210
294
  isFetching: boolean;
211
295
  isFetchingMore: boolean;
212
296
  error: string | null;
297
+ lastError: {
298
+ kind: "terminal";
299
+ status?: number | undefined;
300
+ name: string;
301
+ message: string;
302
+ stack?: string | undefined;
303
+ cause?: unknown;
304
+ } | {
305
+ kind: "transient";
306
+ status?: number | undefined;
307
+ name: string;
308
+ message: string;
309
+ stack?: string | undefined;
310
+ cause?: unknown;
311
+ } | null;
213
312
  lastFetched: number | null;
214
313
  stale: boolean;
215
314
  currentPage: number | null;
@@ -239,7 +338,7 @@ declare const useGraphStore: zustand.UseBoundStore<Omit<Omit<zustand.StoreApi<Gr
239
338
  insertIdInList: (key: QueryKey, id: EntityId, position: "start" | "end" | number) => void;
240
339
  setListFetching: (key: QueryKey, fetching: boolean) => void;
241
340
  setListFetchingMore: (key: QueryKey, fetchingMore: boolean) => void;
242
- setListError: (key: QueryKey, error: string | null) => void;
341
+ setListError: (key: QueryKey, error: string | null, typed?: EntityError | null) => void;
243
342
  setListStale: (key: QueryKey, stale: boolean) => void;
244
343
  invalidateEntity: (type: EntityType, id?: EntityId) => void;
245
344
  invalidateLists: (matcher: string | ((key: QueryKey) => boolean)) => void;
@@ -288,6 +387,21 @@ declare const useGraphStore: zustand.UseBoundStore<Omit<Omit<zustand.StoreApi<Gr
288
387
  isFetching: boolean;
289
388
  isFetchingMore: boolean;
290
389
  error: string | null;
390
+ lastError: {
391
+ kind: "terminal";
392
+ status?: number | undefined;
393
+ name: string;
394
+ message: string;
395
+ stack?: string | undefined;
396
+ cause?: unknown;
397
+ } | {
398
+ kind: "transient";
399
+ status?: number | undefined;
400
+ name: string;
401
+ message: string;
402
+ stack?: string | undefined;
403
+ cause?: unknown;
404
+ } | null;
291
405
  lastFetched: number | null;
292
406
  stale: boolean;
293
407
  currentPage: number | null;
@@ -317,7 +431,7 @@ declare const useGraphStore: zustand.UseBoundStore<Omit<Omit<zustand.StoreApi<Gr
317
431
  insertIdInList: (key: QueryKey, id: EntityId, position: "start" | "end" | number) => void;
318
432
  setListFetching: (key: QueryKey, fetching: boolean) => void;
319
433
  setListFetchingMore: (key: QueryKey, fetchingMore: boolean) => void;
320
- setListError: (key: QueryKey, error: string | null) => void;
434
+ setListError: (key: QueryKey, error: string | null, typed?: EntityError | null) => void;
321
435
  setListStale: (key: QueryKey, stale: boolean) => void;
322
436
  invalidateEntity: (type: EntityType, id?: EntityId) => void;
323
437
  invalidateLists: (matcher: string | ((key: QueryKey) => boolean)) => void;
@@ -327,6 +441,481 @@ declare const useGraphStore: zustand.UseBoundStore<Omit<Omit<zustand.StoreApi<Gr
327
441
  }) => void), shouldReplace: true): void;
328
442
  }>;
329
443
 
444
+ /**
445
+ * Compiles a {@link FilterSpec} into a Prisma `where` object (plain JSON-serializable shape).
446
+ *
447
+ * Operator mapping matches common Prisma filter APIs: `eq` → `equals`, string ops use `mode: "insensitive"`,
448
+ * `nin` → `notIn`, `arrayContains` → `has`, `isNull` uses `null` / `{ not: null }` per `value`, and `isNotNull` → `{ not: null }`.
449
+ * Unsupported ops (`between`, `arrayOverlaps`, `matches`, `custom`) are omitted from the result.
450
+ *
451
+ * Top-level clause arrays are combined with `AND`. {@link FilterGroup} uses `AND` / `OR` to match `group.logic`.
452
+ */
453
+ declare function toPrismaWhere(filter: FilterSpec): Record<string, unknown>;
454
+ /**
455
+ * Compiles a {@link SortSpec} into Prisma `orderBy` form: `[{ fieldName: "asc" | "desc" }, …]`.
456
+ * `nulls` and `comparator` on {@link SortClause} are ignored (local-only); extend callers if your Prisma version supports null ordering.
457
+ */
458
+ declare function toPrismaOrderBy(sort: SortSpec): Record<string, string>[];
459
+
460
+ /**
461
+ * Transport-agnostic comparison operators. Same spec can compile to REST, SQL, GraphQL, or local JS (`evaluator`).
462
+ * `custom` opts out of automatic serialization — use for predicates only the client can evaluate.
463
+ */
464
+ type FilterOperator = "eq" | "neq" | "gt" | "gte" | "lt" | "lte" | "in" | "nin" | "contains" | "startsWith" | "endsWith" | "isNull" | "isNotNull" | "between" | "arrayContains" | "arrayOverlaps" | "matches" | "custom";
465
+ /** Atomic filter: field path, operator, optional value, and optional JS predicate for `custom`. */
466
+ interface FilterClause {
467
+ field: string;
468
+ op: FilterOperator;
469
+ value?: unknown;
470
+ predicate?: (fieldValue: unknown, entity: Record<string, unknown>) => boolean;
471
+ }
472
+ type FilterLogic = "and" | "or";
473
+ /** Nested boolean group so you can express `(A AND B) OR C` without losing structure when compiling to backends. */
474
+ interface FilterGroup {
475
+ logic: FilterLogic;
476
+ clauses: Array<FilterClause | FilterGroup>;
477
+ }
478
+ /** Top-level filter: flat AND list of clauses, or a recursive `FilterGroup`. */
479
+ type FilterSpec = FilterGroup | FilterClause[];
480
+ type SortDirection = "asc" | "desc";
481
+ /** Single sort key with optional null ordering and custom comparator for local sort parity with remote semantics. */
482
+ interface SortClause {
483
+ field: string;
484
+ direction: SortDirection;
485
+ nulls?: "first" | "last";
486
+ comparator?: (a: unknown, b: unknown) => number;
487
+ }
488
+ /** Ordered multi-key sort (stable application in `compareEntities`). */
489
+ type SortSpec = SortClause[];
490
+ /**
491
+ * Everything `useEntityView` needs to describe a virtualized collection: filters, sorts, and simple multi-field search.
492
+ * One descriptor can drive local evaluation, remote query compilation, or hybrid mode.
493
+ */
494
+ interface ViewDescriptor {
495
+ filter?: FilterSpec;
496
+ sort?: SortSpec;
497
+ search?: {
498
+ query: string;
499
+ fields: string[];
500
+ minChars?: number;
501
+ };
502
+ }
503
+ /**
504
+ * How complete local graph data is relative to the view: **local** (all in memory), **remote** (server must filter/sort), **hybrid** (show local fast + remote reconcile).
505
+ */
506
+ type CompletenessMode = "local" | "remote" | "hybrid";
507
+ /**
508
+ * Compile a view to flat REST query params (`sort`, `q`, and `field[op]=value` keys). Skips `custom` clauses — those cannot be expressed as strings.
509
+ */
510
+ declare function toRestParams(view: ViewDescriptor): Record<string, string>;
511
+ /**
512
+ * Compile a view to parameterized SQL fragments for server-side filtering/sorting. Unknown ops become `TRUE` — validate or restrict ops at the edge.
513
+ */
514
+ declare function toSQLClauses(view: ViewDescriptor): {
515
+ where: string;
516
+ orderBy: string;
517
+ params: unknown[];
518
+ };
519
+ /**
520
+ * Produce a GraphQL-variable-shaped object from a view (Hasura/Postgraphile-style `_op` maps). Intended as a starting point — wire to your actual schema.
521
+ */
522
+ declare function toGraphQLVariables(view: ViewDescriptor): {
523
+ where?: Record<string, unknown>;
524
+ orderBy?: Array<Record<string, unknown>>;
525
+ search?: string;
526
+ };
527
+
528
+ /**
529
+ * Normalize nested `FilterGroup` trees to a flat clause list for compilers that only understand atomic predicates.
530
+ */
531
+ declare function flattenClauses(filter: FilterSpec): FilterClause[];
532
+ /** True if any clause requires client-side `predicate` logic — forces local/hybrid evaluation paths that cannot be pushed to generic REST/SQL. */
533
+ declare function hasCustomPredicates(filter: FilterSpec): boolean;
534
+
535
+ /**
536
+ * 2.0 transport contract.
537
+ *
538
+ * Why this exists: in 1.x each call site of `useEntityList` /
539
+ * `useEntityView` passed its own `fetch` closure + `normalize`
540
+ * callback. That leaked the transport contract to every consumer and
541
+ * was the structural cause of the Quick Stats trap — each widget could
542
+ * (and did) reinvent the same retry-loop bug.
543
+ *
544
+ * In 2.0 the transport is registered ONCE per entity type at app boot
545
+ * via `registerEntityTransport(type, transport)`. Hooks
546
+ * (`useEntities`, `useEntityQuery`) look up the registered transport
547
+ * by entity type — consumers never pass a fetcher.
548
+ *
549
+ * Transports are pluggable: a built-in `makeRestTransport` covers
550
+ * PostgREST / Supabase; future helpers can cover GraphQL, PGlite-direct,
551
+ * mock-in-memory, etc. The contract is intentionally tiny.
552
+ */
553
+
554
+ /**
555
+ * Transport-agnostic list query passed by `useEntities` / `useEntityQuery`
556
+ * down to the registered transport.
557
+ *
558
+ * The transport is responsible for compiling this into the
559
+ * transport-specific wire format (HTTP query string, GraphQL variables,
560
+ * SQL WHERE, in-memory predicate, etc.).
561
+ */
562
+ interface ListQuery {
563
+ /** Optional filter; transport-agnostic, see `FilterSpec`. */
564
+ filter?: FilterSpec | null;
565
+ /** Optional sort spec; transport-agnostic. */
566
+ sort?: SortSpec | null;
567
+ /** Free-text search string; transport decides which fields to match. */
568
+ search?: string;
569
+ /** Page size hint. Transport may cap or ignore. */
570
+ limit?: number;
571
+ /** Opaque cursor for pagination (cursor or numeric offset). */
572
+ cursor?: string | number | null;
573
+ /** Aborts the request when fired. Transports MUST honour this. */
574
+ signal?: AbortSignal;
575
+ }
576
+ /**
577
+ * Page of results returned by `EntityTransport.list`.
578
+ *
579
+ * `total` is `null` when the backend doesn't report it cheaply
580
+ * (consumers should treat as "unknown" rather than "zero").
581
+ *
582
+ * `nextCursor` is `null`/`undefined` when there are no more pages.
583
+ */
584
+ interface ListResult<T> {
585
+ rows: T[];
586
+ total: number | null;
587
+ nextCursor?: string | number | null;
588
+ }
589
+ /**
590
+ * Operation flavour for a realtime change event.
591
+ */
592
+ type ChangeOp = "insert" | "update" | "delete";
593
+ /**
594
+ * Realtime change event emitted by a transport's `subscribe`.
595
+ *
596
+ * For `delete` only `id` is meaningful; `row` MAY be omitted.
597
+ */
598
+ interface ChangeEvent<T> {
599
+ op: ChangeOp;
600
+ id: string;
601
+ row?: T;
602
+ }
603
+ /**
604
+ * The full per-entity transport contract.
605
+ *
606
+ * One transport per entity type, registered at app boot. The hooks
607
+ * (`useEntities`, `useEntityQuery`) look it up via `getEntityTransport(type)`.
608
+ *
609
+ * Required: `identify`, `authoritative`, `list`.
610
+ * Optional: `get` (for single-row fetches), `subscribe` (for realtime),
611
+ * `staleTime` (hint for SWR).
612
+ */
613
+ interface EntityTransport<T extends object> {
614
+ /**
615
+ * Derive the stable string id of a row. Used by the engine to write
616
+ * into the entity graph under the right id key.
617
+ */
618
+ identify: (row: T) => string;
619
+ /**
620
+ * `true` when the local copy is considered authoritative (e.g. PGlite
621
+ * + Electric Tier-A sync) — consumers can render from cache without
622
+ * a remote round-trip on every mount.
623
+ *
624
+ * `false` when the remote is authoritative (Tier-B REST hybrid) — the
625
+ * cache is a hint, not the truth.
626
+ */
627
+ authoritative: boolean;
628
+ /**
629
+ * Stale-time hint in ms. The engine SWR logic refetches when
630
+ * `Date.now() - lastFetched > staleTime`. Omit to inherit the engine
631
+ * default (30s).
632
+ */
633
+ staleTime?: number;
634
+ /** Fetch a list. The signal in `q.signal` MUST be honoured. */
635
+ list: (q: ListQuery) => Promise<ListResult<T>>;
636
+ /** Fetch a single row by id. Optional. */
637
+ get?: (id: string, signal?: AbortSignal) => Promise<T | null>;
638
+ /**
639
+ * Subscribe to realtime change events for this entity type. Optional.
640
+ *
641
+ * Called by `useEntities` / `useEntityQuery` exactly once per
642
+ * subscriber-bearing key. The returned function MUST tear down all
643
+ * underlying resources (sockets, channels, intervals).
644
+ */
645
+ subscribe?: (onChange: (ev: ChangeEvent<T>) => void) => () => void;
646
+ }
647
+
648
+ /**
649
+ * Process-global registry of `EntityTransport` instances by entity type.
650
+ *
651
+ * Why global state: every consumer of `useEntities("Client")` must
652
+ * resolve the SAME transport. Threading a registry through React
653
+ * context would require every test, every isolated story, every
654
+ * non-React caller (engine internals) to plumb the context — a tax
655
+ * that buys nothing. The 1.x library already used module-global state
656
+ * for the `useGraphStore` Zustand store; this follows the same shape.
657
+ *
658
+ * The registry is mutable: re-registering a type silently replaces the
659
+ * prior transport (tests rely on this; production code should only
660
+ * register once at app boot).
661
+ */
662
+
663
+ /**
664
+ * Register the transport for an entity type. Called once per type at
665
+ * app boot, typically from `src/shared/db/entity-transports.ts` in the
666
+ * consuming application.
667
+ *
668
+ * Re-registering REPLACES the prior transport — useful for tests, a
669
+ * footgun for production code. If you find yourself re-registering at
670
+ * runtime, you almost certainly want a different design.
671
+ */
672
+ declare function registerEntityTransport<T extends object>(type: EntityType, transport: EntityTransport<T>): void;
673
+ /**
674
+ * Look up the transport for an entity type. Throws if none is
675
+ * registered — there is no "default" transport, by design.
676
+ *
677
+ * The cast to `EntityTransport<T>` is the API ergonomic
678
+ * compromise that lets call sites stay generic; the registry stores
679
+ * `EntityTransport<object>` because TypeScript can't otherwise unify
680
+ * heterogeneous rows in one map.
681
+ */
682
+ declare function getEntityTransport<T extends object>(type: EntityType): EntityTransport<T>;
683
+ /**
684
+ * Test-only: clear ALL registered transports. Production code should
685
+ * never need this; tests use it to reset between specs.
686
+ */
687
+ declare function __resetEntityTransports(): void;
688
+ /**
689
+ * Introspection: how many transports are currently registered.
690
+ * Useful for asserting in tests that boot wiring ran exactly once.
691
+ */
692
+ declare function getRegisteredEntityTypes(): EntityType[];
693
+
694
+ /**
695
+ * `makeRestTransport` — built-in helper for the most common case: a
696
+ * Supabase / PostgREST backend reached through a `SupabaseClient`-like
697
+ * object.
698
+ *
699
+ * Why a helper (not a class): consumers stay declarative —
700
+ * registerEntityTransport("Client",
701
+ * makeRestTransport<Client>({ supabase, table: "client" }));
702
+ * — and the library never imports `@supabase/supabase-js` directly
703
+ * (peer-dep-free).
704
+ *
705
+ * The transport:
706
+ * - Compiles `ListQuery` (filter / sort / search / cursor / limit)
707
+ * into a PostgREST query via the supabase-js builder.
708
+ * - Maps HTTP status to `TerminalError` (4xx) or `TransientError`
709
+ * (5xx / network).
710
+ * - Honours `AbortSignal` via supabase-js `.abortSignal(signal)`.
711
+ * - Returns `total` from PostgREST `count: 'exact'` when requested.
712
+ */
713
+
714
+ /**
715
+ * Minimal slice of the `@supabase/supabase-js` `SupabaseClient` we use.
716
+ * Declared structurally so the library does not need to import the
717
+ * package as a dependency (peer-dep-free).
718
+ */
719
+ interface SupabaseLike {
720
+ from: (table: string) => SupabaseQueryBuilderLike;
721
+ }
722
+ /**
723
+ * Subset of the supabase-js builder we exercise. Each call returns the
724
+ * same builder for chaining; `then`-able at the end resolves to
725
+ * `{ data, error, count, status }`.
726
+ */
727
+ interface SupabaseQueryBuilderLike {
728
+ select: (columns: string, opts?: {
729
+ count?: "exact" | "planned" | "estimated";
730
+ head?: boolean;
731
+ }) => SupabaseQueryBuilderLike;
732
+ eq: (col: string, val: unknown) => SupabaseQueryBuilderLike;
733
+ neq: (col: string, val: unknown) => SupabaseQueryBuilderLike;
734
+ gt: (col: string, val: unknown) => SupabaseQueryBuilderLike;
735
+ gte: (col: string, val: unknown) => SupabaseQueryBuilderLike;
736
+ lt: (col: string, val: unknown) => SupabaseQueryBuilderLike;
737
+ lte: (col: string, val: unknown) => SupabaseQueryBuilderLike;
738
+ in: (col: string, vals: readonly unknown[]) => SupabaseQueryBuilderLike;
739
+ ilike: (col: string, pattern: string) => SupabaseQueryBuilderLike;
740
+ is: (col: string, val: null | boolean) => SupabaseQueryBuilderLike;
741
+ or: (filter: string) => SupabaseQueryBuilderLike;
742
+ order: (col: string, opts?: {
743
+ ascending?: boolean;
744
+ nullsFirst?: boolean;
745
+ }) => SupabaseQueryBuilderLike;
746
+ range: (from: number, to: number) => SupabaseQueryBuilderLike;
747
+ limit: (n: number) => SupabaseQueryBuilderLike;
748
+ abortSignal?: (signal: AbortSignal) => SupabaseQueryBuilderLike;
749
+ then: <TResult1 = unknown, TResult2 = never>(onfulfilled?: ((value: {
750
+ data: unknown;
751
+ error: unknown;
752
+ count?: number | null;
753
+ status?: number;
754
+ }) => TResult1 | PromiseLike<TResult1>) | null, onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null) => Promise<TResult1 | TResult2>;
755
+ }
756
+ /** Options for `makeRestTransport`. */
757
+ interface MakeRestTransportOptions<T extends object> {
758
+ /** A `@supabase/supabase-js` client (or any structurally-compatible thing). */
759
+ supabase: SupabaseLike;
760
+ /** PostgREST table name. */
761
+ table: string;
762
+ /** Columns to select (default `"*"`). */
763
+ select?: string;
764
+ /** Stable id derivation. Defaults to `(row) => String(row.id)`. */
765
+ identify?: (row: T) => string;
766
+ /** Whether the local cache is treated as authoritative. */
767
+ authoritative?: boolean;
768
+ /** Stale-time hint in ms. */
769
+ staleTime?: number;
770
+ /** Free-text search column list (compiled to `or=col.ilike.*query*,…`). */
771
+ searchColumns?: string[];
772
+ /** Default page size when `ListQuery.limit` is absent. */
773
+ defaultLimit?: number;
774
+ }
775
+ /**
776
+ * Build an `EntityTransport<T>` from a Supabase client + a table name.
777
+ *
778
+ * The returned transport:
779
+ * - Maps `ListQuery.filter` clauses to PostgREST operators (`eq`, `gt`,
780
+ * `in`, `ilike`, `is null`, etc.).
781
+ * - Compiles `ListQuery.search` into an `or=` clause across
782
+ * `searchColumns`.
783
+ * - Uses `count: 'exact'` on first page to surface `total`.
784
+ * - Throws `TerminalError` on 4xx (no retry); `TransientError` on 5xx
785
+ * or network failure.
786
+ * - Honours `signal` via `.abortSignal(signal)` (supabase-js >= 2.39).
787
+ */
788
+ declare function makeRestTransport<T extends object>(opts: MakeRestTransportOptions<T>): EntityTransport<T>;
789
+
790
+ /**
791
+ * `useEntities` — thin 2.0 hook (5-field API).
792
+ *
793
+ * Replaces the `useEntityList(opts)` pattern where each call site carried
794
+ * its own `fetch` closure, query-key shape, and retry logic. Instead:
795
+ *
796
+ * 1. Register a transport once at app boot:
797
+ * `registerEntityTransport("Invoice", makeRestTransport({ supabase, table: "invoice" }))`
798
+ *
799
+ * 2. Consume anywhere:
800
+ * `const { items, isLoading, isError, error } = useEntities<Invoice>("Invoice")`
801
+ *
802
+ * - 4xx from transport → `TerminalError`, no retry, `isError: true`, `isLoading: false`
803
+ * - 5xx/network → `TransientError`, up to `maxRetries` with exponential back-off
804
+ * - `enabled: false` → no fetch, `isLoading: false` immediately
805
+ * - SWR: within `staleTime` (from transport or engine default) → cached rows, no refetch
806
+ * - AbortController per fetch; aborted on unmount, key change, or `refetch()`
807
+ * - Transport `subscribe` wired on mount, torn down on unmount
808
+ */
809
+
810
+ /** Subset of `ListQuery` that callers may pass alongside `enabled`. */
811
+ interface UseEntitiesOptions {
812
+ filter?: FilterSpec | null;
813
+ sort?: SortSpec | null;
814
+ search?: string;
815
+ limit?: number;
816
+ cursor?: string | number | null;
817
+ enabled?: boolean;
818
+ }
819
+ /** Five-field return — the entirety of what a list consumer needs for the common case. */
820
+ interface UseEntitiesResult<T> {
821
+ /** Resolved entity rows in the graph for this query, in server order. */
822
+ items: T[];
823
+ /** True only while the very first attempt is in-flight with no cached rows yet. */
824
+ isLoading: boolean;
825
+ /** True when the last attempt ended with any error (terminal or transient). */
826
+ isError: boolean;
827
+ /** Typed error instance — `instanceof TerminalError` (4xx) or `instanceof TransientError` (5xx/network). */
828
+ error: TerminalError | TransientError | null;
829
+ /** Manually trigger a fresh fetch (bypasses staleTime). */
830
+ refetch: () => void;
831
+ }
832
+ /**
833
+ * Thin replacement for `useEntityList`.
834
+ * Looks up the registered `EntityTransport<T>` for `type` and drives a
835
+ * Zustand-backed SWR cycle. Returns `{ items, isLoading, isError, error, refetch }`.
836
+ */
837
+ declare function useEntities<T extends object>(type: EntityType, options?: UseEntitiesOptions): UseEntitiesResult<T>;
838
+
839
+ /**
840
+ * `useEntityQuery` — rich 2.0 hook (replaces `useEntityView`).
841
+ *
842
+ * Same feature surface as `useEntityView` (view descriptor, hybrid mode,
843
+ * pagination, realtime sorted insertion, toolbar setters) but transport is
844
+ * looked up from the registry — callers no longer pass `remoteFetch`.
845
+ *
846
+ * Usage:
847
+ * registerEntityTransport("Client", makeRestTransport({ supabase, table: "client" }));
848
+ *
849
+ * const { items, setFilter, setSort, setSearch, fetchNextPage, error } =
850
+ * useEntityQuery<Client>("Client", { view: defaultView });
851
+ */
852
+
853
+ interface UseEntityQueryOptions {
854
+ /** Initial view descriptor (filter/sort/search). */
855
+ view?: ViewDescriptor;
856
+ /** Force a completeness mode instead of auto-detecting. */
857
+ mode?: CompletenessMode;
858
+ /** Skip all fetching when false. `isLoading` is immediately `false`. */
859
+ enabled?: boolean;
860
+ /** SSR-seed ids for the base list slot (avoids flash-of-empty-state). */
861
+ initialIds?: EntityId[];
862
+ /** SSR-seed total for completeness heuristics. */
863
+ initialTotal?: number;
864
+ /** Debounce delay (ms) for view changes before a remote re-fetch fires. */
865
+ remoteDebounce?: number;
866
+ }
867
+ interface UseEntityQueryResult<T> {
868
+ /** Projected entity rows visible through the current view. */
869
+ items: T[];
870
+ /** All ids in the projected view (for virtualised renderers). */
871
+ viewIds: EntityId[];
872
+ /** Server-reported total or local count if complete, else null. */
873
+ viewTotal: number | null;
874
+ /** True while the very first page is loading with zero cached rows. */
875
+ isLoading: boolean;
876
+ /** True while any fetch (initial or page) is in-flight. */
877
+ isFetching: boolean;
878
+ /** True while a paginated "load more" fetch is in-flight. */
879
+ isFetchingMore: boolean;
880
+ /** True when the last attempt ended with any error. */
881
+ isError: boolean;
882
+ /**
883
+ * Typed error — `instanceof TerminalError` (4xx) or
884
+ * `instanceof TransientError` (5xx/network). `null` on success.
885
+ */
886
+ error: TerminalError | TransientError | null;
887
+ /** True when there are more pages to load. */
888
+ hasNextPage: boolean;
889
+ /** Load the next page of results. */
890
+ fetchNextPage: () => void;
891
+ /** True when `completenessMode === "hybrid"` and remote is still in-flight while local rows are displayed. */
892
+ isShowingLocalPending: boolean;
893
+ /** Whether local graph data is complete for the current view. */
894
+ isLocallyComplete: boolean;
895
+ /** Resolved completeness mode for the current view. */
896
+ completenessMode: CompletenessMode;
897
+ /** Merge partial view descriptor updates. */
898
+ setView: (v: Partial<ViewDescriptor>) => void;
899
+ /** Replace the active filter spec. */
900
+ setFilter: (f: FilterSpec | null) => void;
901
+ /** Replace the active sort spec. */
902
+ setSort: (s: SortSpec | null) => void;
903
+ /** Update free-text search query. */
904
+ setSearch: (q: string) => void;
905
+ /** Reset view to the initial descriptor. */
906
+ clearView: () => void;
907
+ /** Force a fresh fetch (bypasses staleTime). */
908
+ refetch: () => void;
909
+ }
910
+ /**
911
+ * Rich list hook: view descriptor, local/remote/hybrid completeness, pagination,
912
+ * realtime sorted insertion, typed errors — all backed by the transport registry.
913
+ *
914
+ * @param type - Registered entity type key (e.g. `"Client"`)
915
+ * @param opts - View descriptor, mode override, SSR seeds, enabled gate
916
+ */
917
+ declare function useEntityQuery<T extends object>(type: EntityType, opts?: UseEntityQueryOptions): UseEntityQueryResult<T>;
918
+
330
919
  type GraphStore = ReturnType<typeof useGraphStore.getState>;
331
920
  type GraphIncludeMap = Record<string, GraphIncludeRelation>;
332
921
  type GraphIncludeRelation = {
@@ -358,7 +947,7 @@ type GraphIncludeRelation = {
358
947
  };
359
948
  include?: GraphIncludeMap;
360
949
  };
361
- interface GraphQueryOptions<TEntity extends Record<string, unknown>> {
950
+ interface GraphQueryOptions<TEntity extends object> {
362
951
  type: EntityType;
363
952
  id?: EntityId;
364
953
  ids?: EntityId[];
@@ -369,10 +958,10 @@ interface GraphQueryOptions<TEntity extends Record<string, unknown>> {
369
958
  select?: ((entity: Record<string, unknown>) => unknown) | string[];
370
959
  }
371
960
  type ProjectedRow = Record<string, unknown>;
372
- declare function queryOnce<TEntity extends Record<string, unknown>>(opts: GraphQueryOptions<TEntity> & {
961
+ declare function queryOnce<TEntity extends object>(opts: GraphQueryOptions<TEntity> & {
373
962
  id: EntityId;
374
963
  }): ProjectedRow | null;
375
- declare function queryOnce<TEntity extends Record<string, unknown>>(opts: GraphQueryOptions<TEntity>): ProjectedRow[];
964
+ declare function queryOnce<TEntity extends object>(opts: GraphQueryOptions<TEntity>): ProjectedRow[];
376
965
  declare const selectGraph: typeof queryOnce;
377
966
 
378
967
  interface GraphDataSnapshot {
@@ -445,97 +1034,6 @@ interface GraphEffectHandle {
445
1034
  }
446
1035
  declare function createGraphEffect<T>(opts: GraphEffectOptions<T>): GraphEffectHandle;
447
1036
 
448
- /**
449
- * Compiles a {@link FilterSpec} into a Prisma `where` object (plain JSON-serializable shape).
450
- *
451
- * Operator mapping matches common Prisma filter APIs: `eq` → `equals`, string ops use `mode: "insensitive"`,
452
- * `nin` → `notIn`, `arrayContains` → `has`, `isNull` uses `null` / `{ not: null }` per `value`, and `isNotNull` → `{ not: null }`.
453
- * Unsupported ops (`between`, `arrayOverlaps`, `matches`, `custom`) are omitted from the result.
454
- *
455
- * Top-level clause arrays are combined with `AND`. {@link FilterGroup} uses `AND` / `OR` to match `group.logic`.
456
- */
457
- declare function toPrismaWhere(filter: FilterSpec): Record<string, unknown>;
458
- /**
459
- * Compiles a {@link SortSpec} into Prisma `orderBy` form: `[{ fieldName: "asc" | "desc" }, …]`.
460
- * `nulls` and `comparator` on {@link SortClause} are ignored (local-only); extend callers if your Prisma version supports null ordering.
461
- */
462
- declare function toPrismaOrderBy(sort: SortSpec): Record<string, string>[];
463
-
464
- /**
465
- * Transport-agnostic comparison operators. Same spec can compile to REST, SQL, GraphQL, or local JS (`evaluator`).
466
- * `custom` opts out of automatic serialization — use for predicates only the client can evaluate.
467
- */
468
- type FilterOperator = "eq" | "neq" | "gt" | "gte" | "lt" | "lte" | "in" | "nin" | "contains" | "startsWith" | "endsWith" | "isNull" | "isNotNull" | "between" | "arrayContains" | "arrayOverlaps" | "matches" | "custom";
469
- /** Atomic filter: field path, operator, optional value, and optional JS predicate for `custom`. */
470
- interface FilterClause {
471
- field: string;
472
- op: FilterOperator;
473
- value?: unknown;
474
- predicate?: (fieldValue: unknown, entity: Record<string, unknown>) => boolean;
475
- }
476
- type FilterLogic = "and" | "or";
477
- /** Nested boolean group so you can express `(A AND B) OR C` without losing structure when compiling to backends. */
478
- interface FilterGroup {
479
- logic: FilterLogic;
480
- clauses: Array<FilterClause | FilterGroup>;
481
- }
482
- /** Top-level filter: flat AND list of clauses, or a recursive `FilterGroup`. */
483
- type FilterSpec = FilterGroup | FilterClause[];
484
- type SortDirection = "asc" | "desc";
485
- /** Single sort key with optional null ordering and custom comparator for local sort parity with remote semantics. */
486
- interface SortClause {
487
- field: string;
488
- direction: SortDirection;
489
- nulls?: "first" | "last";
490
- comparator?: (a: unknown, b: unknown) => number;
491
- }
492
- /** Ordered multi-key sort (stable application in `compareEntities`). */
493
- type SortSpec = SortClause[];
494
- /**
495
- * Everything `useEntityView` needs to describe a virtualized collection: filters, sorts, and simple multi-field search.
496
- * One descriptor can drive local evaluation, remote query compilation, or hybrid mode.
497
- */
498
- interface ViewDescriptor {
499
- filter?: FilterSpec;
500
- sort?: SortSpec;
501
- search?: {
502
- query: string;
503
- fields: string[];
504
- minChars?: number;
505
- };
506
- }
507
- /**
508
- * How complete local graph data is relative to the view: **local** (all in memory), **remote** (server must filter/sort), **hybrid** (show local fast + remote reconcile).
509
- */
510
- type CompletenessMode = "local" | "remote" | "hybrid";
511
- /**
512
- * Compile a view to flat REST query params (`sort`, `q`, and `field[op]=value` keys). Skips `custom` clauses — those cannot be expressed as strings.
513
- */
514
- declare function toRestParams(view: ViewDescriptor): Record<string, string>;
515
- /**
516
- * Compile a view to parameterized SQL fragments for server-side filtering/sorting. Unknown ops become `TRUE` — validate or restrict ops at the edge.
517
- */
518
- declare function toSQLClauses(view: ViewDescriptor): {
519
- where: string;
520
- orderBy: string;
521
- params: unknown[];
522
- };
523
- /**
524
- * Produce a GraphQL-variable-shaped object from a view (Hasura/Postgraphile-style `_op` maps). Intended as a starting point — wire to your actual schema.
525
- */
526
- declare function toGraphQLVariables(view: ViewDescriptor): {
527
- where?: Record<string, unknown>;
528
- orderBy?: Array<Record<string, unknown>>;
529
- search?: string;
530
- };
531
-
532
- /**
533
- * Normalize nested `FilterGroup` trees to a flat clause list for compilers that only understand atomic predicates.
534
- */
535
- declare function flattenClauses(filter: FilterSpec): FilterClause[];
536
- /** True if any clause requires client-side `predicate` logic — forces local/hybrid evaluation paths that cannot be pushed to generic REST/SQL. */
537
- declare function hasCustomPredicates(filter: FilterSpec): boolean;
538
-
539
1037
  /**
540
1038
  * Process-wide defaults for stale times, retries, and background revalidation.
541
1039
  * Keeps hook signatures small: `useEntity` / `useEntityList` merge these with per-query overrides.
@@ -555,7 +1053,7 @@ interface EngineOptions {
555
1053
  * Declarative **instruction** for loading one entity: wire transport (`fetch`), normalization, and graph writes.
556
1054
  * Hooks pass this to `fetchEntity`; the graph remains source of truth after success.
557
1055
  */
558
- interface EntityQueryOptions<TRaw, TEntity extends Record<string, unknown>> {
1056
+ interface EntityQueryOptions<TRaw, TEntity extends object> {
559
1057
  type: EntityType;
560
1058
  id: EntityId | null | undefined;
561
1059
  fetch: (id: EntityId) => Promise<TRaw>;
@@ -579,8 +1077,8 @@ interface ListFetchParams {
579
1077
  */
580
1078
  interface ListResponse<T> {
581
1079
  items: T[];
582
- total?: number;
583
- nextCursor?: string;
1080
+ total?: number | null;
1081
+ nextCursor?: string | null;
584
1082
  prevCursor?: string;
585
1083
  hasNextPage?: boolean;
586
1084
  hasPrevPage?: boolean;
@@ -591,7 +1089,7 @@ interface ListResponse<T> {
591
1089
  * Declarative **instruction** for a collection query: stable `queryKey`, fetcher, and per-row normalization into the graph.
592
1090
  * `mode` controls whether a fetch replaces ids or appends (infinite scroll) when used with load-more.
593
1091
  */
594
- interface ListQueryOptions<TRaw, TEntity extends Record<string, unknown>> {
1092
+ interface ListQueryOptions<TRaw, TEntity extends object> {
595
1093
  type: EntityType;
596
1094
  queryKey: unknown[];
597
1095
  fetch: (params: ListFetchParams) => Promise<ListResponse<TRaw>>;
@@ -633,12 +1131,12 @@ declare function configureEngine(opts: EngineOptions): void;
633
1131
  * Run a single-entity fetch with dedupe, retries, normalization, and graph updates.
634
1132
  * Call from hooks/adapters — not from presentational components.
635
1133
  */
636
- declare function fetchEntity<TRaw, TEntity extends Record<string, unknown>>(opts: EntityQueryOptions<TRaw, TEntity>, engineOpts: Required<EngineOptions>): Promise<void>;
1134
+ declare function fetchEntity<TRaw, TEntity extends object>(opts: EntityQueryOptions<TRaw, TEntity>, engineOpts: Required<EngineOptions>): Promise<void>;
637
1135
  /**
638
1136
  * Fetch a list page: upserts all rows, writes ids to the list key, supports append mode for pagination.
639
1137
  * @param isLoadMore - When true, uses a separate dedupe key and `appendListResult` / `setListFetchingMore`.
640
1138
  */
641
- declare function fetchList<TRaw, TEntity extends Record<string, unknown>>(opts: ListQueryOptions<TRaw, TEntity>, params: ListFetchParams, engineOpts: Required<EngineOptions>, isLoadMore?: boolean): Promise<void>;
1139
+ declare function fetchList<TRaw, TEntity extends object>(opts: ListQueryOptions<TRaw, TEntity>, params: ListFetchParams, engineOpts: Required<EngineOptions>, isLoadMore?: boolean): Promise<void>;
642
1140
 
643
1141
  /**
644
1142
  * Precompiled transport payloads for one view snapshot — pass to REST, GraphQL, or SQL backends without re-deriving from `ViewDescriptor`.
@@ -653,7 +1151,7 @@ interface ViewFetchParams {
653
1151
  * Configure a **live view** over a base list: filter/sort/search in JS when data is complete, or compile the same spec to remote params when not.
654
1152
  * `baseQueryKey` identifies the underlying id list in the graph; the hook may create additional keys for remote result sets.
655
1153
  */
656
- interface UseEntityViewOptions<TEntity extends Record<string, unknown>> {
1154
+ interface UseEntityViewOptions<TEntity extends object> {
657
1155
  type: EntityType;
658
1156
  baseQueryKey: unknown[];
659
1157
  view: ViewDescriptor;
@@ -661,7 +1159,7 @@ interface UseEntityViewOptions<TEntity extends Record<string, unknown>> {
661
1159
  remoteFetch?: (params: ViewFetchParams) => Promise<ListResponse<TEntity>>;
662
1160
  normalize?: (raw: TEntity) => {
663
1161
  id: EntityId;
664
- data: Record<string, unknown>;
1162
+ data: TEntity;
665
1163
  };
666
1164
  remoteDebounce?: number;
667
1165
  staleTime?: number;
@@ -683,7 +1181,14 @@ interface UseEntityViewResult<TEntity> {
683
1181
  isFetching: boolean;
684
1182
  isRemoteFetching: boolean;
685
1183
  isShowingLocalPending: boolean;
1184
+ /**
1185
+ * Last error message from the remote fetcher (or the cached base
1186
+ * list state). `null` when the latest attempt succeeded or no
1187
+ * attempt has been made.
1188
+ */
686
1189
  error: string | null;
1190
+ /** Convenience for `error !== null`. TanStack-Query-style. */
1191
+ isError: boolean;
687
1192
  hasNextPage: boolean;
688
1193
  fetchNextPage: () => void;
689
1194
  isLocallyComplete: boolean;
@@ -714,7 +1219,13 @@ interface UseEntityViewResult<TEntity> {
714
1219
  * });
715
1220
  * ```
716
1221
  */
717
- declare function useEntityView<TEntity extends Record<string, unknown>>(opts: UseEntityViewOptions<TEntity>): UseEntityViewResult<TEntity>;
1222
+ /**
1223
+ * @deprecated Use `useEntityQuery` from `"@prometheus-ags/prometheus-entity-management"` instead.
1224
+ * Register a transport: `registerEntityTransport("Foo", makeRestTransport({ supabase, table: "foo" }))`
1225
+ * Then consume: `const { items, setFilter, setSort } = useEntityQuery<Foo>("Foo", { view })`
1226
+ * `useEntityView` will be removed in a future major version.
1227
+ */
1228
+ declare function useEntityView<TEntity extends object>(opts: UseEntityViewOptions<TEntity>): UseEntityViewResult<TEntity>;
718
1229
 
719
1230
  /** UI mode for a single CRUD surface: drives which panels/forms are active without scattering boolean flags. */
720
1231
  type CRUDMode = "list" | "detail" | "edit" | "create";
@@ -722,7 +1233,7 @@ type CRUDMode = "list" | "detail" | "edit" | "create";
722
1233
  * Wire one entity type into list+detail+forms: remote list via `useEntityView`, optional detail fetch, and create/update/delete callbacks.
723
1234
  * Mutations call `cascadeInvalidation` on success so related lists/entities refresh per registered schemas.
724
1235
  */
725
- interface CRUDOptions<TEntity extends Record<string, unknown>> {
1236
+ interface CRUDOptions<TEntity extends object> {
726
1237
  type: EntityType;
727
1238
  listQueryKey: unknown[];
728
1239
  listFetch: (params: ViewFetchParams) => Promise<ListResponse<TEntity>>;
@@ -744,9 +1255,9 @@ interface CRUDOptions<TEntity extends Record<string, unknown>> {
744
1255
  clearSelectionAfterDelete?: boolean;
745
1256
  }
746
1257
  /** Public field input for CRUD setters: supports classic `keyof T` calls and dotted nested paths for JSON-backed forms. */
747
- type EntityFieldPath<TEntity extends Record<string, unknown>> = keyof TEntity | string;
1258
+ type EntityFieldPath<TEntity extends object> = keyof TEntity | string;
748
1259
  /** Tracks which fields diverge from loaded detail — edit buffer stays in React state so other views keep showing canonical graph data until save. */
749
- interface DirtyFields<TEntity extends Record<string, unknown>> {
1260
+ interface DirtyFields<TEntity extends object> {
750
1261
  changed: ReadonlySet<EntityFieldPath<TEntity>>;
751
1262
  isDirty: boolean;
752
1263
  }
@@ -754,7 +1265,7 @@ interface DirtyFields<TEntity extends Record<string, unknown>> {
754
1265
  * Everything a CRUD screen needs: composed `list` view, selection, detail subscription, relation joins, edit/create buffers, and mutating actions.
755
1266
  * `applyOptimistic` is the escape hatch to mirror the buffer into `patches` for instant sliders/toggles without committing `save` yet.
756
1267
  */
757
- interface CRUDState<TEntity extends Record<string, unknown>> {
1268
+ interface CRUDState<TEntity extends object> {
758
1269
  mode: CRUDMode;
759
1270
  setMode: (mode: CRUDMode) => void;
760
1271
  list: UseEntityViewResult<TEntity>;
@@ -797,7 +1308,7 @@ interface CRUDState<TEntity extends Record<string, unknown>> {
797
1308
  * @param opts - `CRUDOptions` for type, list key/fetch, normalization, lifecycle callbacks
798
1309
  * @returns `CRUDState` with list/detail/edit/create controls
799
1310
  */
800
- declare function useEntityCRUD<TEntity extends Record<string, unknown>>(opts: CRUDOptions<TEntity>): CRUDState<TEntity>;
1311
+ declare function useEntityCRUD<TEntity extends object>(opts: CRUDOptions<TEntity>): CRUDState<TEntity>;
801
1312
 
802
1313
  type FieldType = "text" | "textarea" | "number" | "email" | "url" | "date" | "boolean" | "enum" | "json" | "markdown" | "custom";
803
1314
  interface FieldDescriptor<TEntity> {
@@ -826,7 +1337,7 @@ declare function Sheet({ open, onClose, title, subtitle, children, footer, width
826
1337
  footer?: React$1.ReactNode;
827
1338
  width?: string;
828
1339
  }): react_jsx_runtime.JSX.Element;
829
- declare function EntityDetailSheet<TEntity extends Record<string, unknown>>({ crud, fields, title, description, children, showEditButton, showDeleteButton, deleteConfirmMessage }: {
1340
+ declare function EntityDetailSheet<TEntity extends object>({ crud, fields, title, description, children, showEditButton, showDeleteButton, deleteConfirmMessage }: {
830
1341
  crud: CRUDState<TEntity>;
831
1342
  fields: FieldDescriptor<TEntity>[];
832
1343
  title?: string | ((e: TEntity) => string);
@@ -836,7 +1347,7 @@ declare function EntityDetailSheet<TEntity extends Record<string, unknown>>({ cr
836
1347
  showDeleteButton?: boolean;
837
1348
  deleteConfirmMessage?: string;
838
1349
  }): react_jsx_runtime.JSX.Element;
839
- declare function EntityFormSheet<TEntity extends Record<string, unknown>>({ crud, fields, createTitle, editTitle }: {
1350
+ declare function EntityFormSheet<TEntity extends object>({ crud, fields, createTitle, editTitle }: {
840
1351
  crud: CRUDState<TEntity>;
841
1352
  fields: FieldDescriptor<TEntity>[];
842
1353
  createTitle?: string;
@@ -849,11 +1360,12 @@ interface JsonSchemaObject {
849
1360
  description?: string;
850
1361
  type?: string | string[];
851
1362
  format?: string;
852
- enum?: unknown[];
1363
+ enum?: readonly unknown[];
853
1364
  default?: unknown;
854
1365
  properties?: Record<string, JsonSchemaObject>;
855
1366
  items?: JsonSchemaObject;
856
1367
  required?: string[];
1368
+ additionalProperties?: boolean | JsonSchemaObject;
857
1369
  ["x-a2ui-component"]?: string;
858
1370
  ["x-display-order"]?: number;
859
1371
  ["x-field-type"]?: string;
@@ -872,7 +1384,7 @@ interface GetEntityJsonSchemaOptions {
872
1384
  schemaId?: string;
873
1385
  field?: string;
874
1386
  }
875
- interface SchemaFieldDescriptor<TEntity extends Record<string, unknown> = Record<string, unknown>> extends FieldDescriptor<TEntity> {
1387
+ interface SchemaFieldDescriptor<TEntity extends object = Record<string, unknown>> extends FieldDescriptor<TEntity> {
876
1388
  schemaPath: string;
877
1389
  schema: JsonSchemaObject;
878
1390
  componentHint?: string;
@@ -890,11 +1402,11 @@ interface GraphSnapshotWithSchemasOptions {
890
1402
  declare function registerEntityJsonSchema(config: EntityJsonSchemaConfig): void;
891
1403
  declare function registerRuntimeSchema(config: EntityJsonSchemaConfig): void;
892
1404
  declare function getEntityJsonSchema(opts: GetEntityJsonSchemaOptions): EntityJsonSchemaConfig | null;
893
- declare function useSchemaEntityFields<TEntity extends Record<string, unknown> = Record<string, unknown>>(opts: GetEntityJsonSchemaOptions & {
1405
+ declare function useSchemaEntityFields<TEntity extends object = Record<string, unknown>>(opts: GetEntityJsonSchemaOptions & {
894
1406
  schema?: JsonSchemaObject;
895
1407
  rootField?: string;
896
1408
  }): SchemaFieldDescriptor<TEntity>[];
897
- declare function buildEntityFieldsFromSchema<TEntity extends Record<string, unknown> = Record<string, unknown>>(opts: BuildEntityFieldsFromSchemaOptions): SchemaFieldDescriptor<TEntity>[];
1409
+ declare function buildEntityFieldsFromSchema<TEntity extends object = Record<string, unknown>>(opts: BuildEntityFieldsFromSchemaOptions): SchemaFieldDescriptor<TEntity>[];
898
1410
  declare function exportGraphSnapshotWithSchemas(opts: GraphSnapshotWithSchemasOptions): string;
899
1411
  declare function renderMarkdownToHtml(value: string): string;
900
1412
  declare function MarkdownFieldRenderer({ value, className }: {
@@ -966,6 +1478,26 @@ interface HydrateGraphFromStorageOptions {
966
1478
  storage: GraphPersistenceAdapter;
967
1479
  key: string;
968
1480
  }
1481
+ /**
1482
+ * Retry-with-backoff policy for replaying pending offline actions.
1483
+ *
1484
+ * The replay loop tracks per-action attempt counts. After `maxAttempts`
1485
+ * failed attempts the action is considered "poisoned" — it is removed from
1486
+ * the in-memory pending queue (so it won't block other actions) and the
1487
+ * optional `poisonHandler` is invoked. Consumers typically log the action,
1488
+ * surface a UI prompt, or persist it to a dead-letter store.
1489
+ *
1490
+ * Defaults: 5 attempts, starting at 500ms, doubling up to 30s, with
1491
+ * "equal" jitter (random in `[delay/2, delay]`).
1492
+ */
1493
+ interface ReplayRetryPolicy {
1494
+ maxAttempts?: number;
1495
+ initialDelayMs?: number;
1496
+ maxDelayMs?: number;
1497
+ backoffFactor?: number;
1498
+ jitter?: "full" | "equal" | "none";
1499
+ poisonHandler?: (action: GraphActionRecord, error: unknown) => void | Promise<void>;
1500
+ }
969
1501
  interface StartLocalFirstGraphOptions {
970
1502
  storage: GraphPersistenceAdapter;
971
1503
  key?: string;
@@ -975,6 +1507,8 @@ interface StartLocalFirstGraphOptions {
975
1507
  subscribe: (listener: (online: boolean) => void) => () => void;
976
1508
  };
977
1509
  persistDebounceMs?: number;
1510
+ /** Retry-with-backoff policy for offline action replay. */
1511
+ retryPolicy?: ReplayRetryPolicy;
978
1512
  }
979
1513
  interface LocalFirstGraphRuntime {
980
1514
  ready: Promise<void>;
@@ -1008,6 +1542,26 @@ declare function hydrateGraphFromStorage(opts: HydrateGraphFromStorageOptions):
1008
1542
  error?: undefined;
1009
1543
  }>;
1010
1544
  declare function startLocalFirstGraph(opts: StartLocalFirstGraphOptions): LocalFirstGraphRuntime;
1545
+ interface ResolvedRetryPolicy {
1546
+ maxAttempts: number;
1547
+ initialDelayMs: number;
1548
+ maxDelayMs: number;
1549
+ backoffFactor: number;
1550
+ jitter: "full" | "equal" | "none";
1551
+ poisonHandler?: (action: GraphActionRecord, error: unknown) => void | Promise<void>;
1552
+ }
1553
+ /**
1554
+ * Attempt to replay an action up to `maxAttempts` times. On exhaustion the
1555
+ * action goes to "poison" — the optional handler is invoked and the function
1556
+ * resolves. Exposed for unit testing.
1557
+ */
1558
+ declare function replayActionWithRetry(action: GraphActionRecord, policy: ResolvedRetryPolicy): Promise<{
1559
+ ok: true;
1560
+ } | {
1561
+ ok: false;
1562
+ poisoned: true;
1563
+ error: unknown;
1564
+ }>;
1011
1565
 
1012
1566
  /**
1013
1567
  * Debug-time snapshot of entity graph health: counts, list queries, patches, staleness,
@@ -1071,7 +1625,7 @@ interface UseEntityResult<T> {
1071
1625
  * });
1072
1626
  * ```
1073
1627
  */
1074
- declare function useEntity<TRaw, TEntity extends Record<string, unknown>>(opts: EntityQueryOptions<TRaw, TEntity>): UseEntityResult<TEntity>;
1628
+ declare function useEntity<TRaw, TEntity extends object>(opts: EntityQueryOptions<TRaw, TEntity>): UseEntityResult<TEntity>;
1075
1629
  /**
1076
1630
  * Resolved rows for a list query: **`items` joins `ids` to the graph** at render time so shared entities update everywhere.
1077
1631
  */
@@ -1081,7 +1635,14 @@ interface UseEntityListResult<TEntity> {
1081
1635
  isLoading: boolean;
1082
1636
  isFetching: boolean;
1083
1637
  isFetchingMore: boolean;
1638
+ /**
1639
+ * Last error message from the underlying fetcher, or `null` when
1640
+ * the latest attempt succeeded / no attempt has been made.
1641
+ * Combined with `isError` for TanStack-Query-style ergonomics.
1642
+ */
1084
1643
  error: string | null;
1644
+ /** Convenience for `error !== null`. TanStack-Query-style. */
1645
+ isError: boolean;
1085
1646
  hasNextPage: boolean;
1086
1647
  hasPrevPage: boolean;
1087
1648
  total: number | null;
@@ -1107,12 +1668,18 @@ interface UseEntityListResult<TEntity> {
1107
1668
  * });
1108
1669
  * ```
1109
1670
  */
1110
- declare function useEntityList<TRaw, TEntity extends Record<string, unknown>>(opts: ListQueryOptions<TRaw, TEntity>): UseEntityListResult<TEntity>;
1671
+ /**
1672
+ * @deprecated Use `useEntities` from `"@prometheus-ags/prometheus-entity-management"` instead.
1673
+ * Register a transport: `registerEntityTransport("Foo", makeRestTransport({ supabase, table: "foo" }))`
1674
+ * Then consume: `const { items } = useEntities<Foo>("Foo")`.
1675
+ * `useEntityList` will be removed in a future major version.
1676
+ */
1677
+ declare function useEntityList<TRaw, TEntity extends object>(opts: ListQueryOptions<TRaw, TEntity>): UseEntityListResult<TEntity>;
1111
1678
  /**
1112
1679
  * Options for graph-aware mutations: API call + optional normalization into `entities`, optimistic patches, and targeted invalidation.
1113
1680
  * Prefer `invalidateLists` prefixes / `invalidateEntities` over ad-hoc store calls so list UIs stay coherent.
1114
1681
  */
1115
- interface MutationOptions<TInput, TRaw, TEntity extends Record<string, unknown>> {
1682
+ interface MutationOptions<TInput, TRaw, TEntity extends object> {
1116
1683
  type: EntityType;
1117
1684
  mutate: (input: TInput) => Promise<TRaw>;
1118
1685
  normalize?: (raw: TRaw, input: TInput) => {
@@ -1156,7 +1723,7 @@ interface UseMutationResult<TInput, TRaw> {
1156
1723
  * });
1157
1724
  * ```
1158
1725
  */
1159
- declare function useEntityMutation<TInput, TRaw, TEntity extends Record<string, unknown>>(opts: MutationOptions<TInput, TRaw, TEntity>): UseMutationResult<TInput, TRaw>;
1726
+ declare function useEntityMutation<TInput, TRaw, TEntity extends object>(opts: MutationOptions<TInput, TRaw, TEntity>): UseMutationResult<TInput, TRaw>;
1160
1727
  /**
1161
1728
  * Read/write **UI-only** fields for one entity (`patches` layer) so selection, hover, or transient state is visible in every view that reads that id.
1162
1729
  * Does not replace `useEntityCRUD`’s edit buffer for form drafts — patches are for shared, non-persisted overlays.
@@ -1165,7 +1732,7 @@ declare function useEntityMutation<TInput, TRaw, TEntity extends Record<string,
1165
1732
  * @param id - Entity id (no-ops when null/undefined)
1166
1733
  * @returns Current patch slice and helpers `augment` / `unaugment` / `clear`
1167
1734
  */
1168
- declare function useEntityAugment<TEntity extends Record<string, unknown>>(type: EntityType, id: EntityId | null | undefined): {
1735
+ declare function useEntityAugment<TEntity extends object>(type: EntityType, id: EntityId | null | undefined): {
1169
1736
  patch: Partial<TEntity> | null;
1170
1737
  augment: (fields: Partial<TEntity>) => void;
1171
1738
  unaugment: (keys: (keyof TEntity)[]) => void;
@@ -1181,7 +1748,7 @@ declare function useEntityAugment<TEntity extends Record<string, unknown>>(type:
1181
1748
  * @throws Promise while loading (caught by the nearest Suspense boundary)
1182
1749
  * @throws Error if the fetch fails with no data, if `id` is missing when required, or if the entity never resolves
1183
1750
  */
1184
- declare function useSuspenseEntity<TRaw, TEntity extends Record<string, unknown>>(opts: EntityQueryOptions<TRaw, TEntity>): {
1751
+ declare function useSuspenseEntity<TRaw, TEntity extends object>(opts: EntityQueryOptions<TRaw, TEntity>): {
1185
1752
  data: TEntity;
1186
1753
  isFetching: boolean;
1187
1754
  isStale: boolean;
@@ -1196,7 +1763,7 @@ declare function useSuspenseEntity<TRaw, TEntity extends Record<string, unknown>
1196
1763
  * @throws Promise while initially loading (caught by the nearest Suspense boundary)
1197
1764
  * @throws Error if the fetch fails while the list is still empty
1198
1765
  */
1199
- declare function useSuspenseEntityList<TRaw, TEntity extends Record<string, unknown>>(opts: ListQueryOptions<TRaw, TEntity>): Omit<UseEntityListResult<TEntity>, "isLoading">;
1766
+ declare function useSuspenseEntityList<TRaw, TEntity extends object>(opts: ListQueryOptions<TRaw, TEntity>): Omit<UseEntityListResult<TEntity>, "isLoading">;
1200
1767
 
1201
1768
  /**
1202
1769
  * Evaluate `FilterSpec` against one in-memory entity — mirrors remote semantics as closely as plain JS allows.
@@ -1413,14 +1980,14 @@ declare function createSupabaseRealtimeAdapter(client: SupabaseClient$1, opts?:
1413
1980
  interface ConvexClient {
1414
1981
  onUpdate<T>(query: unknown, args: Record<string, unknown>, handler: (result: T) => void): UnsubscribeFn$1;
1415
1982
  }
1416
- interface ConvexChannelConfig<T extends Record<string, unknown>> {
1983
+ interface ConvexChannelConfig<T extends object> {
1417
1984
  type: string;
1418
1985
  query: unknown;
1419
1986
  args?: Record<string, unknown>;
1420
1987
  extractId?: (record: T) => string;
1421
1988
  normalize?: (record: T) => Record<string, unknown>;
1422
1989
  }
1423
- declare function createConvexAdapter<T extends Record<string, unknown>>(opts: {
1990
+ declare function createConvexAdapter<T extends object>(opts: {
1424
1991
  client: ConvexClient;
1425
1992
  channels: ConvexChannelConfig<T>[];
1426
1993
  }): RealtimeAdapter;
@@ -1436,7 +2003,7 @@ interface GQLWsClient {
1436
2003
  complete: () => void;
1437
2004
  }): UnsubscribeFn$1;
1438
2005
  }
1439
- interface GQLSubscriptionConfig<T extends Record<string, unknown>> {
2006
+ interface GQLSubscriptionConfig<T extends object> {
1440
2007
  type: string;
1441
2008
  document: string;
1442
2009
  variables?: Record<string, unknown>;
@@ -1447,7 +2014,7 @@ interface GQLPayload {
1447
2014
  node?: Record<string, unknown>;
1448
2015
  id?: string;
1449
2016
  }
1450
- declare function createGraphQLSubscriptionAdapter<T extends Record<string, unknown>>(opts: {
2017
+ declare function createGraphQLSubscriptionAdapter<T extends object>(opts: {
1451
2018
  client: GQLWsClient;
1452
2019
  subscriptions: GQLSubscriptionConfig<T>[];
1453
2020
  extractId?: (node: Record<string, unknown>, type: string) => string;
@@ -1457,7 +2024,7 @@ declare function createGraphQLSubscriptionAdapter<T extends Record<string, unkno
1457
2024
  /**
1458
2025
  * Options for {@link createPrismaEntityConfig}: one REST-backed resource aligned with Prisma-style `where` / `orderBy` / `include` payloads.
1459
2026
  */
1460
- interface PrismaEntityConfigOptions<TEntity extends Record<string, unknown>> {
2027
+ interface PrismaEntityConfigOptions<TEntity extends object> {
1461
2028
  /** Graph entity type key (e.g. `"Task"`). */
1462
2029
  type: string;
1463
2030
  /** Base REST URL for the collection (list) and detail as `${endpoint}/:id`. */
@@ -1490,7 +2057,7 @@ declare function prismaRelationsToSchema(type: string, relations: PrismaEntityCo
1490
2057
  * - {@link PrismaEntityConfigOptions.endpoint `endpoint`} — GET list; GET `${endpoint}/:id` for detail.
1491
2058
  * - List/CRUD fetchers send `where` and `orderBy` as JSON query strings unless you override via {@link ListFetchParams.params}.
1492
2059
  */
1493
- declare function createPrismaEntityConfig<TEntity extends Record<string, unknown>>(config: PrismaEntityConfigOptions<TEntity>): {
2060
+ declare function createPrismaEntityConfig<TEntity extends object>(config: PrismaEntityConfigOptions<TEntity>): {
1494
2061
  /**
1495
2062
  * Builds {@link EntityQueryOptions} for {@link useEntity} (GET `${endpoint}/:id`).
1496
2063
  */
@@ -1516,14 +2083,14 @@ declare function createPrismaEntityConfig<TEntity extends Record<string, unknown
1516
2083
  schemas: () => EntitySchema[];
1517
2084
  };
1518
2085
 
1519
- interface PGlite {
2086
+ interface PGlite$1 {
1520
2087
  query<T = Record<string, unknown>>(sql: string, params?: unknown[]): Promise<{
1521
2088
  rows: T[];
1522
2089
  }>;
1523
- exec(sql: string): Promise<void>;
2090
+ exec(sql: string): Promise<unknown>;
1524
2091
  listen(channel: string, handler: (payload: string) => void): Promise<() => void>;
1525
2092
  }
1526
- interface ShapeMessage<T = Record<string, unknown>> {
2093
+ interface ShapeMessage$1<T = Record<string, unknown>> {
1527
2094
  headers: {
1528
2095
  operation: "insert" | "update" | "delete";
1529
2096
  };
@@ -1531,21 +2098,21 @@ interface ShapeMessage<T = Record<string, unknown>> {
1531
2098
  value: T;
1532
2099
  key: string;
1533
2100
  }
1534
- interface ShapeStream<T = Record<string, unknown>> {
1535
- subscribe(onMsg: (msgs: ShapeMessage<T>[]) => void, onErr?: (e: Error) => void): () => void;
2101
+ interface ShapeStream$1<T = Record<string, unknown>> {
2102
+ subscribe(onMsg: (msgs: ShapeMessage$1<T>[]) => void, onErr?: (e: Error) => void): () => void;
1536
2103
  isUpToDate: boolean;
1537
2104
  lastOffset: string;
1538
2105
  }
1539
- interface ElectricTableConfig<T extends Record<string, unknown>> {
2106
+ interface ElectricTableConfig<T extends object> {
1540
2107
  type: EntityType;
1541
2108
  table: string;
1542
2109
  where?: string;
1543
2110
  idColumn?: string;
1544
2111
  normalize?: (row: T) => Record<string, unknown>;
1545
- shapeStream: ShapeStream<T>;
2112
+ shapeStream: ShapeStream$1<T>;
1546
2113
  }
1547
2114
  interface ElectricAdapterOptions {
1548
- pglite: PGlite;
2115
+ pglite: PGlite$1;
1549
2116
  tables: ElectricTableConfig<Record<string, unknown>>[];
1550
2117
  onSynced?: () => void;
1551
2118
  }
@@ -1556,7 +2123,7 @@ interface UseLocalFirstResult {
1556
2123
  execute: (sql: string, params?: unknown[]) => Promise<void>;
1557
2124
  }
1558
2125
  declare function useLocalFirst(adapter: SyncAdapter): UseLocalFirstResult;
1559
- declare function usePGliteQuery<T extends Record<string, unknown>>(opts: {
2126
+ declare function usePGliteQuery<T extends object>(opts: {
1560
2127
  adapter: SyncAdapter;
1561
2128
  type: EntityType;
1562
2129
  sql: string;
@@ -1569,6 +2136,280 @@ declare function usePGliteQuery<T extends Record<string, unknown>>(opts: {
1569
2136
  error: string | null;
1570
2137
  };
1571
2138
 
2139
+ /**
2140
+ * adapters/electricsql-tenant.ts
2141
+ *
2142
+ * Tenant-scoped Electric adapter — the safety primitive that enforces
2143
+ * **RULE 5 — Shape predicates ⊆ RLS** (see hotseaters constraints).
2144
+ *
2145
+ * PGlite has no row-level security. The only way to guarantee a client
2146
+ * never sees cross-tenant data through Electric is to refuse to attach
2147
+ * any shape that lacks a tenant predicate. This wrapper does exactly that:
2148
+ *
2149
+ * - Validates the tenant claim (currently `{ companyId }`) is a UUID.
2150
+ * - Refuses to attach a shape whose `tenantColumn` is `undefined`. We
2151
+ * accept explicit `null` for the company root itself (filtered by `id`).
2152
+ * - Builds the `where` clause from `tenantColumn` and the validated
2153
+ * companyId so individual shape factories cannot drift from RLS.
2154
+ * - Delegates to the existing `createElectricAdapter` for the actual
2155
+ * sync wiring.
2156
+ *
2157
+ * This also fulfils Change 13 item 11 (auth-claim-aware shape registration):
2158
+ * the `tenantClaim` is the typed seam where authn meets shape registration.
2159
+ *
2160
+ * Self-hosted Supabase only. Local stack and `https://electricsql.prometheusags.ai`
2161
+ * are the only acceptable Electric endpoints — this module does not
2162
+ * hard-code either; it only governs the predicate.
2163
+ */
2164
+
2165
+ interface PGlite {
2166
+ query<T = Record<string, unknown>>(sql: string, params?: unknown[]): Promise<{
2167
+ rows: T[];
2168
+ }>;
2169
+ exec(sql: string): Promise<unknown>;
2170
+ listen(channel: string, handler: (payload: string) => void): Promise<() => void>;
2171
+ }
2172
+ interface ShapeMessage<T = Record<string, unknown>> {
2173
+ headers: {
2174
+ operation: "insert" | "update" | "delete";
2175
+ };
2176
+ offset: string;
2177
+ value: T;
2178
+ key: string;
2179
+ }
2180
+ interface ShapeStream<T = Record<string, unknown>> {
2181
+ subscribe(onMsg: (msgs: ShapeMessage<T>[]) => void, onErr?: (e: Error) => void): () => void;
2182
+ isUpToDate: boolean;
2183
+ lastOffset: string;
2184
+ }
2185
+ /** Auth claim required to register tenant-scoped shapes. */
2186
+ interface TenantClaim {
2187
+ companyId: string;
2188
+ }
2189
+ interface TenantScopedTableConfig<T extends object = Record<string, unknown>> {
2190
+ type: EntityType;
2191
+ table: string;
2192
+ /**
2193
+ * Column used for tenant filtering.
2194
+ *
2195
+ * - A string (`"company_id"`) yields `WHERE company_id = '<companyId>'`.
2196
+ * - Explicit `null` means the table IS the tenant root and is filtered by
2197
+ * `id = '<companyId>'`. Only the `company` table qualifies.
2198
+ * - `undefined` is **rejected** — this is the safety gate.
2199
+ */
2200
+ tenantColumn: string | null;
2201
+ primaryKey?: string[];
2202
+ /**
2203
+ * Factory invoked with the constructed `where` clause and the tenant claim.
2204
+ * Consumers wire their preferred Electric `ShapeStream` builder here. The
2205
+ * factory must use the supplied `where` verbatim (no widening).
2206
+ */
2207
+ shapeStreamFactory: (params: {
2208
+ table: string;
2209
+ where: string;
2210
+ tenantClaim: TenantClaim;
2211
+ }) => ShapeStream<T>;
2212
+ normalize?: (row: T) => Record<string, unknown>;
2213
+ }
2214
+ interface TenantScopedAdapterOptions {
2215
+ pglite: PGlite;
2216
+ tenantClaim: TenantClaim;
2217
+ tables: TenantScopedTableConfig[];
2218
+ onSynced?: () => void;
2219
+ }
2220
+ /**
2221
+ * Build the `where` clause for a single shape. Exposed for tests.
2222
+ *
2223
+ * - `tenantColumn === null` → `id = '<companyId>'` (company-root case)
2224
+ * - `tenantColumn === string` → `<tenantColumn> = '<companyId>'`
2225
+ *
2226
+ * Throws if `tenantColumn` is `undefined` or `companyId` is not a UUID.
2227
+ */
2228
+ declare function buildTenantWhere(tenantColumn: string | null | undefined, companyId: string, tableLabel: string): string;
2229
+ /**
2230
+ * Build a tenant-scoped {@link SyncAdapter}.
2231
+ *
2232
+ * For each table in `tables`:
2233
+ * 1. Validates `tenantColumn` is defined (string or explicit null).
2234
+ * 2. Validates `companyId` is a UUID.
2235
+ * 3. Builds the predicate and calls `shapeStreamFactory(...)` to get the
2236
+ * actual `ShapeStream`.
2237
+ * 4. Hands the resulting list off to `createElectricAdapter` for wiring.
2238
+ *
2239
+ * @throws if any table lacks `tenantColumn`, or the company id is not a UUID.
2240
+ */
2241
+ declare function createTenantScopedElectricAdapter(opts: TenantScopedAdapterOptions): SyncAdapter;
2242
+
2243
+ /**
2244
+ * adapters/pglite-persistence.ts
2245
+ *
2246
+ * PGlite-backed implementation of {@link GraphPersistenceAdapter}.
2247
+ *
2248
+ * Stores the local-first runtime's graph snapshot inside a PGlite table
2249
+ * (`_graph_snapshot` by default) instead of `localStorage`/`IndexedDB`.
2250
+ *
2251
+ * Why this exists:
2252
+ * - The app already has a PGlite handle for ElectricSQL sync.
2253
+ * - Putting the graph snapshot alongside synced data means one storage
2254
+ * surface to back up, clear, and reason about.
2255
+ * - Works in Tauri WebView + Node (PGlite is a WASM Postgres) without
2256
+ * pulling in browser-only storage.
2257
+ *
2258
+ * Contract:
2259
+ * - `get(key)` -> returns the stored string or null
2260
+ * - `set(key, v)` -> upserts (insert-or-replace), stamping `updated_at`
2261
+ * - `remove(key)` -> deletes the row (no-op if absent)
2262
+ *
2263
+ * The function lazily ensures the storage table exists on first call.
2264
+ * That `CREATE TABLE IF NOT EXISTS` is idempotent so it's safe to retry.
2265
+ *
2266
+ * Self-hosted Supabase only. HotSeatersMVP is the bible. This module does
2267
+ * not import `@electric-sql/pglite` — consumers pass a PGlite-shaped handle.
2268
+ */
2269
+
2270
+ interface PGlitePersistenceClient {
2271
+ query<T = Record<string, unknown>>(sql: string, params?: unknown[]): Promise<{
2272
+ rows: T[];
2273
+ }>;
2274
+ exec(sql: string): Promise<unknown>;
2275
+ }
2276
+ interface CreatePGlitePersistenceAdapterOptions {
2277
+ /** Name of the snapshot table. Defaults to `_graph_snapshot`. */
2278
+ tableName?: string;
2279
+ }
2280
+ /**
2281
+ * Returns a {@link GraphPersistenceAdapter} that reads/writes the graph
2282
+ * snapshot through a PGlite-shaped client.
2283
+ *
2284
+ * @example
2285
+ * ```ts
2286
+ * import { PGlite } from "@electric-sql/pglite";
2287
+ * import { startLocalFirstGraph, createPGlitePersistenceAdapter } from "@prometheus-ags/prometheus-entity-management";
2288
+ *
2289
+ * const pglite = await PGlite.create("idb://hotseaters");
2290
+ * const storage = await createPGlitePersistenceAdapter(pglite);
2291
+ * const runtime = startLocalFirstGraph({ storage, key: "hotseaters:graph" });
2292
+ * ```
2293
+ */
2294
+ declare function createPGlitePersistenceAdapter(pglite: PGlitePersistenceClient, options?: CreatePGlitePersistenceAdapterOptions): Promise<GraphPersistenceAdapter>;
2295
+
2296
+ /**
2297
+ * schema-from-sql.ts
2298
+ *
2299
+ * Generates a JSON Schema (and registers it via `registerEntityJsonSchema`)
2300
+ * directly from a Postgres `CREATE TABLE` statement. Lets a consumer keep
2301
+ * `latest-data/supabase/migrations/*.sql` as the single source of truth for
2302
+ * column shapes — no hand-maintained TypeScript schema duplicates.
2303
+ *
2304
+ * Deliberately regex-based: a real SQL parser is overkill for the slice of
2305
+ * DDL we care about, and would add a non-trivial runtime dep.
2306
+ *
2307
+ * Type mapping
2308
+ * ------------
2309
+ * UUID, TEXT, VARCHAR(*) -> { type: "string" }
2310
+ * INTEGER, INT, BIGINT, SMALLINT -> { type: "integer" }
2311
+ * NUMERIC(*), DECIMAL(*) -> { type: "number" }
2312
+ * BOOLEAN, BOOL -> { type: "boolean" }
2313
+ * TIMESTAMPTZ, TIMESTAMP -> { type: "string", format: "date-time" }
2314
+ * DATE -> { type: "string", format: "date" }
2315
+ * JSONB, JSON -> { type: "object" }
2316
+ * TEXT[] -> { type: "array", items: { type: "string" } }
2317
+ * anything else -> { type: "string" } + "x-warning"
2318
+ *
2319
+ * `required` is populated from `NOT NULL` columns that lack a `DEFAULT`.
2320
+ * Callers can pass `overrides` to deep-merge a partial config (typically to
2321
+ * narrow a JSONB column to an array, or to add `enum`/`format` hints).
2322
+ */
2323
+
2324
+ interface RegisterEntityFromSqlOptions {
2325
+ entityType: string;
2326
+ /** A single `CREATE TABLE` statement (extra DDL around it is ignored). */
2327
+ createTableSql: string;
2328
+ /** Optional deep-merge overrides (overrides win). */
2329
+ overrides?: Partial<EntityJsonSchemaConfig>;
2330
+ }
2331
+ interface ParsedColumn {
2332
+ name: string;
2333
+ sqlType: string;
2334
+ notNull: boolean;
2335
+ hasDefault: boolean;
2336
+ }
2337
+ interface ParsedTable {
2338
+ tableName: string;
2339
+ columns: ParsedColumn[];
2340
+ }
2341
+ /**
2342
+ * Parse a `CREATE TABLE` block. Exposed for tests and for callers who need
2343
+ * the intermediate representation.
2344
+ */
2345
+ declare function parseCreateTable(sql: string): ParsedTable;
2346
+ /**
2347
+ * Map a normalized (uppercased, whitespace-stripped) SQL type to a JSON
2348
+ * schema fragment.
2349
+ *
2350
+ * Returns `{ schema, warning }` so the caller can surface "unmapped type"
2351
+ * notes via `x-warning` on the property.
2352
+ */
2353
+ declare function sqlTypeToJsonSchema(sqlType: string): {
2354
+ schema: JsonSchemaObject;
2355
+ warning?: string;
2356
+ };
2357
+ /**
2358
+ * Build (and register) an `EntityJsonSchemaConfig` from a CREATE TABLE
2359
+ * statement. Returns the registered config so callers can introspect it.
2360
+ */
2361
+ declare function registerEntityFromSql(opts: RegisterEntityFromSqlOptions): EntityJsonSchemaConfig;
2362
+
2363
+ /**
2364
+ * table/use-entity-list-as-table.ts
2365
+ *
2366
+ * Adapter hook that shapes a `useEntityList` result for TanStack Table (or
2367
+ * any data-grid that wants a plain `data` array + `rowCount`).
2368
+ *
2369
+ * It deliberately does NOT bring `@tanstack/react-table` as a dependency.
2370
+ * Consumers wire the table; this helper only stabilizes the array reference
2371
+ * so the table doesn't re-render unnecessarily, and exposes the same
2372
+ * loading/error surface as `useEntityList`.
2373
+ *
2374
+ * @example
2375
+ * ```tsx
2376
+ * const tableProps = useEntityListAsTable({
2377
+ * type: "Client",
2378
+ * fetch: (params) => api.listClients(params),
2379
+ * normalize: (raw) => ({ id: raw.id, data: raw }),
2380
+ * });
2381
+ *
2382
+ * const table = useReactTable({
2383
+ * data: tableProps.data,
2384
+ * rowCount: tableProps.rowCount,
2385
+ * columns,
2386
+ * getCoreRowModel: getCoreRowModel(),
2387
+ * });
2388
+ * ```
2389
+ */
2390
+
2391
+ interface UseEntityListAsTableOptions<TRaw, TEntity extends object> extends Omit<ListQueryOptions<TRaw, TEntity>, "type" | "queryKey"> {
2392
+ type: EntityType;
2393
+ /** Optional override for the cache key. Defaults to `["entity-list-as-table", type]`. */
2394
+ queryKey?: unknown[];
2395
+ }
2396
+ interface UseEntityListAsTableResult<TEntity> {
2397
+ data: TEntity[];
2398
+ rowCount: number;
2399
+ isLoading: boolean;
2400
+ isFetching: boolean;
2401
+ error: string | null;
2402
+ refetch: () => void;
2403
+ }
2404
+ /**
2405
+ * Wraps `useEntityList` for table consumers.
2406
+ *
2407
+ * Returns a referentially-stable `data` array (replaced only when items
2408
+ * actually change). TanStack Table treats `data` by identity for memoization,
2409
+ * so this is essential to avoid blowing away row state on every render.
2410
+ */
2411
+ declare function useEntityListAsTable<TRaw, TEntity extends object>(opts: UseEntityListAsTableOptions<TRaw, TEntity>): UseEntityListAsTableResult<TEntity>;
2412
+
1572
2413
  interface GQLClientConfig {
1573
2414
  url: string;
1574
2415
  headers?: () => Record<string, string>;
@@ -1587,7 +2428,7 @@ interface GQLResponse<T> {
1587
2428
  data: T | null;
1588
2429
  errors?: GQLError[];
1589
2430
  }
1590
- interface EntityDescriptor<TNode, TEntity extends Record<string, unknown>> {
2431
+ interface EntityDescriptor<TNode, TEntity extends object> {
1591
2432
  type: EntityType;
1592
2433
  path: string;
1593
2434
  extractId?: (node: TNode) => EntityId;
@@ -1602,13 +2443,13 @@ declare function normalizeGQLResponse<T>(data: T, descriptors: EntityDescriptor<
1602
2443
  declare class GQLClient {
1603
2444
  private cfg;
1604
2445
  constructor(cfg: GQLClientConfig);
1605
- query<TData, TEntity extends Record<string, unknown>>(opts: {
2446
+ query<TData, TEntity extends object>(opts: {
1606
2447
  document: string;
1607
2448
  variables?: Record<string, unknown>;
1608
2449
  descriptors: EntityDescriptor<unknown, TEntity>[];
1609
2450
  cacheKey?: string;
1610
2451
  }): Promise<GQLResponse<TData>>;
1611
- mutate<TData, TEntity extends Record<string, unknown>>(opts: {
2452
+ mutate<TData, TEntity extends object>(opts: {
1612
2453
  document: string;
1613
2454
  variables?: Record<string, unknown>;
1614
2455
  descriptors?: EntityDescriptor<unknown, TEntity>[];
@@ -1627,7 +2468,7 @@ declare class GQLClient {
1627
2468
  }
1628
2469
  declare function createGQLClient(cfg: GQLClientConfig): GQLClient;
1629
2470
 
1630
- interface GQLEntityOptions<TData, TEntity extends Record<string, unknown>> {
2471
+ interface GQLEntityOptions<TData, TEntity extends object> {
1631
2472
  client: GQLClient;
1632
2473
  document: string;
1633
2474
  variables?: Record<string, unknown>;
@@ -1640,7 +2481,7 @@ interface GQLEntityOptions<TData, TEntity extends Record<string, unknown>> {
1640
2481
  onSuccess?: (data: TData) => void;
1641
2482
  onError?: (err: Error) => void;
1642
2483
  }
1643
- declare function useGQLEntity<TData, TEntity extends Record<string, unknown>>(opts: GQLEntityOptions<TData, TEntity>): {
2484
+ declare function useGQLEntity<TData, TEntity extends object>(opts: GQLEntityOptions<TData, TEntity>): {
1644
2485
  data: TEntity | null;
1645
2486
  isLoading: boolean;
1646
2487
  isFetching: boolean;
@@ -1648,7 +2489,7 @@ declare function useGQLEntity<TData, TEntity extends Record<string, unknown>>(op
1648
2489
  isStale: boolean;
1649
2490
  refetch: () => void;
1650
2491
  };
1651
- interface GQLListOptions<TData, TEntity extends Record<string, unknown>> {
2492
+ interface GQLListOptions<TData, TEntity extends object> {
1652
2493
  client: GQLClient;
1653
2494
  document: string;
1654
2495
  variables?: Record<string, unknown>;
@@ -1668,7 +2509,7 @@ interface GQLListOptions<TData, TEntity extends Record<string, unknown>> {
1668
2509
  staleTime?: number;
1669
2510
  enabled?: boolean;
1670
2511
  }
1671
- declare function useGQLList<TData, TEntity extends Record<string, unknown>>(opts: GQLListOptions<TData, TEntity>): {
2512
+ declare function useGQLList<TData, TEntity extends object>(opts: GQLListOptions<TData, TEntity>): {
1672
2513
  items: TEntity[];
1673
2514
  ids: string[];
1674
2515
  isLoading: boolean;
@@ -1681,7 +2522,7 @@ declare function useGQLList<TData, TEntity extends Record<string, unknown>>(opts
1681
2522
  fetchNextPage: () => void;
1682
2523
  refetch: () => void;
1683
2524
  };
1684
- declare function useGQLMutation<TData, TEntity extends Record<string, unknown>>(opts: {
2525
+ declare function useGQLMutation<TData, TEntity extends object>(opts: {
1685
2526
  client: GQLClient;
1686
2527
  document: string;
1687
2528
  type: string;
@@ -1722,7 +2563,7 @@ declare function InlineCellEditor$1({ initialValue, onCommit, onCancel, classNam
1722
2563
  onCancel: () => void;
1723
2564
  className?: string;
1724
2565
  }): react_jsx_runtime.JSX.Element;
1725
- interface EntityTableProps<T extends Record<string, unknown>> {
2566
+ interface EntityTableProps<T extends object> {
1726
2567
  viewResult: UseEntityViewResult<T>;
1727
2568
  columns: ColumnDef$1<T>[];
1728
2569
  getRowId?: (row: T) => string;
@@ -1739,7 +2580,7 @@ interface EntityTableProps<T extends Record<string, unknown>> {
1739
2580
  emptyState?: React$1.ReactNode;
1740
2581
  className?: string;
1741
2582
  }
1742
- declare function EntityTable<T extends Record<string, unknown>>({ viewResult, columns, getRowId, selectedId, onRowClick, onCellEdit, onBulkAction, paginationMode, pageSize, searchPlaceholder, searchFields, toolbarChildren, showToolbar, emptyState, className }: EntityTableProps<T>): react_jsx_runtime.JSX.Element;
2583
+ declare function EntityTable<T extends object>({ viewResult, columns, getRowId, selectedId, onRowClick, onCellEdit, onBulkAction, paginationMode, pageSize, searchPlaceholder, searchFields, toolbarChildren, showToolbar, emptyState, className }: EntityTableProps<T>): react_jsx_runtime.JSX.Element;
1743
2584
 
1744
2585
  type ColumnFilterType = "text" | "number" | "date" | "dateRange" | "boolean" | "enum" | "relation" | "none";
1745
2586
  interface EntityColumnMeta<TEntity> {
@@ -2256,7 +3097,7 @@ interface GalleryColumns {
2256
3097
  xl?: number;
2257
3098
  }
2258
3099
 
2259
- declare function useTable<TData extends Record<string, unknown>>(options: TableOptions<TData>): TableInstance<TData>;
3100
+ declare function useTable<TData extends object>(options: TableOptions<TData>): TableInstance<TData>;
2260
3101
 
2261
3102
  /**
2262
3103
  * table/row-models.ts
@@ -2650,7 +3491,7 @@ declare function TableStorageProvider({ adapter, realtimeMode, children, }: Tabl
2650
3491
  declare function useTableStorageAdapter(): TableStorageAdapter;
2651
3492
  declare function useTableRealtimeMode(): "auto-apply" | "notify";
2652
3493
 
2653
- interface EntityListViewProps<TData extends Record<string, unknown>> {
3494
+ interface EntityListViewProps<TData extends object> {
2654
3495
  data?: TData[];
2655
3496
  viewResult?: {
2656
3497
  items: TData[];
@@ -2685,9 +3526,9 @@ interface EntityListViewProps<TData extends Record<string, unknown>> {
2685
3526
  onRefresh?: () => void;
2686
3527
  className?: string;
2687
3528
  }
2688
- declare function EntityListView<TData extends Record<string, unknown>>(props: EntityListViewProps<TData>): react_jsx_runtime.JSX.Element;
3529
+ declare function EntityListView<TData extends object>(props: EntityListViewProps<TData>): react_jsx_runtime.JSX.Element;
2689
3530
 
2690
- interface DataTableProps<TData extends Record<string, unknown>> {
3531
+ interface DataTableProps<TData extends object> {
2691
3532
  table: TableInstance<TData>;
2692
3533
  actions?: ActionDef<TData>[];
2693
3534
  enableInlineEdit?: boolean;
@@ -2697,9 +3538,9 @@ interface DataTableProps<TData extends Record<string, unknown>> {
2697
3538
  getRowId?: (row: TData) => string;
2698
3539
  className?: string;
2699
3540
  }
2700
- declare function DataTable<TData extends Record<string, unknown>>({ table, actions, enableInlineEdit, onInlineSave, selectionStore, enableMultiSelect, getRowId, className, }: DataTableProps<TData>): react_jsx_runtime.JSX.Element;
3541
+ declare function DataTable<TData extends object>({ table, actions, enableInlineEdit, onInlineSave, selectionStore, enableMultiSelect, getRowId, className, }: DataTableProps<TData>): react_jsx_runtime.JSX.Element;
2701
3542
 
2702
- interface GalleryViewProps<TData extends Record<string, unknown>> {
3543
+ interface GalleryViewProps<TData extends object> {
2703
3544
  rows: Row<TData>[];
2704
3545
  columns: ColumnDef<TData>[];
2705
3546
  itemDescriptor?: ItemDescriptor<TData>;
@@ -2713,9 +3554,9 @@ interface GalleryViewProps<TData extends Record<string, unknown>> {
2713
3554
  galleryColumns?: GalleryColumns;
2714
3555
  className?: string;
2715
3556
  }
2716
- declare function GalleryView<TData extends Record<string, unknown>>({ rows, columns, itemDescriptor, renderCard, actions, enableInlineEdit, onInlineSave, selectionStore, enableMultiSelect, getRowId, galleryColumns, className, }: GalleryViewProps<TData>): react_jsx_runtime.JSX.Element;
3557
+ declare function GalleryView<TData extends object>({ rows, columns, itemDescriptor, renderCard, actions, enableInlineEdit, onInlineSave, selectionStore, enableMultiSelect, getRowId, galleryColumns, className, }: GalleryViewProps<TData>): react_jsx_runtime.JSX.Element;
2717
3558
 
2718
- interface ListViewProps<TData extends Record<string, unknown>> {
3559
+ interface ListViewProps<TData extends object> {
2719
3560
  rows: Row<TData>[];
2720
3561
  columns: ColumnDef<TData>[];
2721
3562
  itemDescriptor?: ItemDescriptor<TData>;
@@ -2728,7 +3569,7 @@ interface ListViewProps<TData extends Record<string, unknown>> {
2728
3569
  getRowId?: (row: TData) => string;
2729
3570
  className?: string;
2730
3571
  }
2731
- declare function ListView<TData extends Record<string, unknown>>({ rows, columns, itemDescriptor, renderItem, actions, enableInlineEdit, onInlineSave, selectionStore, enableMultiSelect, getRowId, className, }: ListViewProps<TData>): react_jsx_runtime.JSX.Element;
3572
+ declare function ListView<TData extends object>({ rows, columns, itemDescriptor, renderItem, actions, enableInlineEdit, onInlineSave, selectionStore, enableMultiSelect, getRowId, className, }: ListViewProps<TData>): react_jsx_runtime.JSX.Element;
2732
3573
 
2733
3574
  interface ViewModeSwitcherProps {
2734
3575
  mode: ViewMode;
@@ -2813,7 +3654,7 @@ interface InlineCellEditorProps<TData> {
2813
3654
  ariaLabel?: string;
2814
3655
  }
2815
3656
  declare function InlineCellEditor<TData>({ value: initialValue, columnDef, onSave, onCancel, className, inputId, ariaLabel, }: InlineCellEditorProps<TData>): react_jsx_runtime.JSX.Element;
2816
- interface InlineItemEditorProps<TData extends Record<string, unknown>> {
3657
+ interface InlineItemEditorProps<TData extends object> {
2817
3658
  item: TData;
2818
3659
  columns: ColumnDef<TData>[];
2819
3660
  itemDescriptor?: ItemDescriptor<TData>;
@@ -2821,7 +3662,7 @@ interface InlineItemEditorProps<TData extends Record<string, unknown>> {
2821
3662
  onCancel: () => void;
2822
3663
  className?: string;
2823
3664
  }
2824
- declare function InlineItemEditor<TData extends Record<string, unknown>>({ item, columns, itemDescriptor: _itemDescriptor, onSave, onCancel, className, }: InlineItemEditorProps<TData>): react_jsx_runtime.JSX.Element;
3665
+ declare function InlineItemEditor<TData extends object>({ item, columns, itemDescriptor: _itemDescriptor, onSave, onCancel, className, }: InlineItemEditorProps<TData>): react_jsx_runtime.JSX.Element;
2825
3666
 
2826
3667
  interface MultiSelectBarProps {
2827
3668
  store: StoreApi<SelectionStoreState>;
@@ -2935,4 +3776,4 @@ declare const TableHead: React$1.ForwardRefExoticComponent<React$1.ThHTMLAttribu
2935
3776
  declare const TableCell: React$1.ForwardRefExoticComponent<React$1.TdHTMLAttributes<HTMLTableCellElement> & React$1.RefAttributes<HTMLTableCellElement>>;
2936
3777
  declare const TableCaption: React$1.ForwardRefExoticComponent<React$1.HTMLAttributes<HTMLTableCaptionElement> & React$1.RefAttributes<HTMLTableCaptionElement>>;
2937
3778
 
2938
- export { type AccessorFn, ActionButtonRow, type ActionDef, ActionDropdown, type ActionItem, type ActivePresets, type AdapterStatus, type AggregationFn, type BatchActionDef, type BelongsToRelation, type BuildEntityFieldsFromSchemaOptions, type CRUDMode, type CRUDOptions, type CRUDState, type CascadeContext, type Cell, type CellContext, type CellRenderer, type ChangeOperation, type ChangeSet, type ChannelConfig, type Column, type ColumnFilterType, type ColumnFiltersState, type ColumnOrderState, type ColumnPinningState, type ColumnPreset, ColumnPresetDialog, type ColumnPresetEntry, type ColumnSizingState, type ColumnVisibilityState, type CompletenessMode, DataTable, DataTableColumnHeader, DataTableFilter, DataTablePagination, DataTableToolbar, type DirtyFields, type ElectricAdapterOptions, ElectricSQLAdapter as ElectricSQLPresetAdapter, type ElectricSQLAdapterOptions as ElectricSQLPresetAdapterOptions, type ElectricTableConfig, EmptyState, type EmptyStateConfig, type EngineOptions, type EntityChange, type EntityColumnMeta, type EntityDescriptor, EntityDetailSheet, EntityFormSheet, type EntityId, type EntityJsonSchemaConfig, EntityListView, type EntityListViewProps, type EntityQueryOptions, type EntitySchema, type EntitySnapshot, type EntityState, type EntitySyncMetadata, EntityTable, type EntityType, type ExpandedState, type FieldDescriptor, type FieldType, type FilterClause, type FilterFn, type FilterGroup, type FilterOperator, type FilterPreset, FilterPresetDialog, type FilterSpec, GQLClient, type GQLClientConfig, type GQLEntityOptions, type GQLError, type GQLListOptions, type GQLResponse, type GalleryColumns, GalleryView, type GraphActionEvent, type GraphActionOptions, type GraphActionRecord$1 as GraphActionRecord, type GraphEffectEvent, type GraphEffectHandle, type GraphEffectOptions, type GraphIncludeMap, type GraphIncludeRelation, type GraphPersistenceAdapter, type GraphQueryOptions, type GraphSnapshotExportOptions, type GraphSnapshotPayload, type GraphSnapshotWithSchemasOptions, type GraphState, type GraphSyncStatus, type GraphToolContext, type GraphTransaction, type GroupingState, type HasManyRelation, type Header, type HeaderContext, type HeaderGroup, type HeaderRenderer, InlineCellEditor$1 as InlineCellEditor, InlineItemEditor, type ItemDescriptor, type ItemDescriptorBadge, type ItemDescriptorMeta, type ItemRenderContext, type JsonSchemaObject, type ListFetchParams, type ListQueryOptions, type ListResponse, type ListState, ListView, type LocalFirstGraphRuntime, type ManagerOptions, type ManyToManyRelation, MarkdownFieldEditor, MarkdownFieldRenderer, MemoryAdapter, MultiSelectBar, type PaginationState, type GraphActionRecord as PersistedGraphActionRecord, type PresetChangeEvent, type PresetChangeOperation, PresetPicker, type PresetStoreState, type UnsubscribeFn as PresetUnsubscribeFn, type PrismaEntityConfigOptions, type ColumnDef as PureColumnDef, type ColumnMeta as PureColumnMeta, InlineCellEditor as PureInlineCellEditor, type QueryKey, type RealtimeAdapter, RealtimeManager, type RelationDescriptor, type RestAdapterOptions, RestApiAdapter, type Row, type RowModel, type RowSelectionState, type SchemaFieldDescriptor, type SchemaGraphToolContext, SelectionContext, type SelectionStoreState, Sheet, type SortClause, type SortDirection, SortHeader, type SortSpec, type SortingFn, type SortingState, type StartLocalFirstGraphOptions, type SubscriptionConfig, type SupabaseAdapterOptions$1 as SupabaseAdapterOptions, SupabaseRealtimeAdapter as SupabasePresetAdapter, type SupabaseAdapterOptions as SupabasePresetAdapterOptions, type SyncAdapter, type SyncOrigin, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, type TableInstance, type TableOptions, type TablePresetSlice, TableRow, type TableState, type TableStorageAdapter, TableStorageProvider, type TableStorageProviderProps, type UnsubscribeFn$1 as UnsubscribeFn, type Updater, type UseEntityViewOptions, type UseEntityViewResult, type UseLocalFirstResult, type UseTablePresetsOptions, type UseTablePresetsResult, type ViewDescriptor, type ViewFetchParams, type ViewMode, ViewModeSwitcher, type WebSocketAdapterOptions, type ZustandAdapterOptions, ZustandPersistAdapter, actionsColumn$1 as actionsColumn, applyView, booleanColumn$1 as booleanColumn, buildEntityFieldsFromSchema, cascadeInvalidation, checkCompleteness, compareEntities, configureEngine, createConvexAdapter, createElectricAdapter, createGQLClient, createGraphAction, createGraphEffect, createGraphQLSubscriptionAdapter, createGraphTool, createGraphTransaction, createPresetStore, createPrismaEntityConfig, createRow, createSchemaGraphTool, createSelectionStore, createSupabaseRealtimeAdapter, createWebSocketAdapter, dateColumn$1 as dateColumn, dedupe, deleteAction, editAction, enumColumn$1 as enumColumn, executeGQL, exportGraphSnapshot, exportGraphSnapshotWithSchemas, fetchEntity, fetchList, flattenClauses, getCoreRowModel, getEntityJsonSchema, getExpandedRowModel, getFacetedMinMaxValues, getFacetedRowModel, getFacetedUniqueValues, getFilteredRowModel, getGroupedRowModel, getPaginatedRowModel, getRealtimeManager, getSchema, getSelectedRowModel, getSortedRowModel, hasCustomPredicates, hydrateGraphFromStorage, matchesFilter, matchesSearch, normalizeGQLResponse, numberColumn$1 as numberColumn, persistGraphToStorage, prismaRelationsToSchema, actionsColumn as pureActionsColumn, booleanColumn as pureBooleanColumn, dateColumn as pureDateColumn, enumColumn as pureEnumColumn, numberColumn as pureNumberColumn, selectionColumn as pureSelectionColumn, textColumn as pureTextColumn, queryOnce, readRelations, registerEntityJsonSchema, registerRuntimeSchema, registerSchema, renderMarkdownToHtml, resetRealtimeManager, selectGraph, selectionColumn$1 as selectionColumn, serializeKey, startGarbageCollector, startLocalFirstGraph, stopGarbageCollector, textColumn$1 as 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 };
3779
+ export { type AccessorFn, ActionButtonRow, type ActionDef, ActionDropdown, type ActionItem, type ActivePresets, type AdapterStatus, type AggregationFn, type BatchActionDef, type BelongsToRelation, type BuildEntityFieldsFromSchemaOptions, type CRUDMode, type CRUDOptions, type CRUDState, type CascadeContext, type Cell, type CellContext, type CellRenderer, type ChangeEvent, type ChangeOp, type ChangeOperation, type ChangeSet, type ChannelConfig, type Column, type ColumnFilterType, type ColumnFiltersState, type ColumnOrderState, type ColumnPinningState, type ColumnPreset, ColumnPresetDialog, type ColumnPresetEntry, type ColumnSizingState, type ColumnVisibilityState, type CompletenessMode, type CreatePGlitePersistenceAdapterOptions, DataTable, DataTableColumnHeader, DataTableFilter, DataTablePagination, DataTableToolbar, type DirtyFields, type ElectricAdapterOptions, ElectricSQLAdapter as ElectricSQLPresetAdapter, type ElectricSQLAdapterOptions as ElectricSQLPresetAdapterOptions, type ElectricTableConfig, EmptyState, type EmptyStateConfig, type EngineOptions, type EntityChange, type EntityColumnMeta, type EntityDescriptor, EntityDetailSheet, type EntityError, type EntityErrorOptions, EntityFormSheet, type EntityId, type EntityJsonSchemaConfig, EntityListView, type EntityListViewProps, type EntityQueryOptions, type EntitySchema, type EntitySnapshot, type EntityState, type EntitySyncMetadata, EntityTable, type EntityTransport, type EntityType, type ExpandedState, type FieldDescriptor, type FieldType, type FilterClause, type FilterFn, type FilterGroup, type FilterOperator, type FilterPreset, FilterPresetDialog, type FilterSpec, GQLClient, type GQLClientConfig, type GQLEntityOptions, type GQLError, type GQLListOptions, type GQLResponse, type GalleryColumns, GalleryView, type GraphActionEvent, type GraphActionOptions, type GraphActionRecord$1 as GraphActionRecord, type GraphEffectEvent, type GraphEffectHandle, type GraphEffectOptions, type GraphIncludeMap, type GraphIncludeRelation, type GraphPersistenceAdapter, type GraphQueryOptions, type GraphSnapshotExportOptions, type GraphSnapshotPayload, type GraphSnapshotWithSchemasOptions, type GraphState, type GraphSyncStatus, type GraphToolContext, type GraphTransaction, type GroupingState, type HasManyRelation, type Header, type HeaderContext, type HeaderGroup, type HeaderRenderer, InlineCellEditor$1 as InlineCellEditor, InlineItemEditor, type ItemDescriptor, type ItemDescriptorBadge, type ItemDescriptorMeta, type ItemRenderContext, type JsonSchemaObject, type ListFetchParams, type ListQuery, type ListQueryOptions, type ListResponse, type ListResult, type ListState, ListView, type LocalFirstGraphRuntime, type MakeRestTransportOptions, type ManagerOptions, type ManyToManyRelation, MarkdownFieldEditor, MarkdownFieldRenderer, MemoryAdapter, MultiSelectBar, type PGlitePersistenceClient, type PaginationState, type GraphActionRecord as PersistedGraphActionRecord, type PresetChangeEvent, type PresetChangeOperation, PresetPicker, type PresetStoreState, type UnsubscribeFn as PresetUnsubscribeFn, type PrismaEntityConfigOptions, type ColumnDef as PureColumnDef, type ColumnMeta as PureColumnMeta, InlineCellEditor as PureInlineCellEditor, type QueryKey, type RealtimeAdapter, RealtimeManager, type RegisterEntityFromSqlOptions, type RelationDescriptor, type ReplayRetryPolicy, type RestAdapterOptions, RestApiAdapter, type Row, type RowModel, type RowSelectionState, type SchemaFieldDescriptor, type SchemaGraphToolContext, SelectionContext, type SelectionStoreState, Sheet, type SortClause, type SortDirection, SortHeader, type SortSpec, type SortingFn, type SortingState, type StartLocalFirstGraphOptions, type SubscriptionConfig, type SupabaseAdapterOptions$1 as SupabaseAdapterOptions, type SupabaseLike, SupabaseRealtimeAdapter as SupabasePresetAdapter, type SupabaseAdapterOptions as SupabasePresetAdapterOptions, type SupabaseQueryBuilderLike, type SyncAdapter, type SyncOrigin, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, type TableInstance, type TableOptions, type TablePresetSlice, TableRow, type TableState, type TableStorageAdapter, TableStorageProvider, type TableStorageProviderProps, type TenantClaim, type TenantScopedAdapterOptions, type TenantScopedTableConfig, TerminalError, TransientError, type UnsubscribeFn$1 as UnsubscribeFn, type Updater, type UseEntitiesOptions, type UseEntitiesResult, type UseEntityListAsTableOptions, type UseEntityListAsTableResult, type UseEntityQueryOptions, type UseEntityQueryResult, type UseEntityViewOptions, type UseEntityViewResult, type UseLocalFirstResult, type UseTablePresetsOptions, type UseTablePresetsResult, type ViewDescriptor, type ViewFetchParams, type ViewMode, ViewModeSwitcher, type WebSocketAdapterOptions, type ZustandAdapterOptions, ZustandPersistAdapter, __resetEntityTransports, actionsColumn$1 as actionsColumn, applyView, booleanColumn$1 as booleanColumn, buildEntityFieldsFromSchema, buildTenantWhere, cascadeInvalidation, checkCompleteness, compareEntities, configureEngine, createConvexAdapter, createElectricAdapter, createGQLClient, createGraphAction, createGraphEffect, createGraphQLSubscriptionAdapter, createGraphTool, createGraphTransaction, createPGlitePersistenceAdapter, createPresetStore, createPrismaEntityConfig, createRow, createSchemaGraphTool, createSelectionStore, createSupabaseRealtimeAdapter, createTenantScopedElectricAdapter, createWebSocketAdapter, dateColumn$1 as dateColumn, dedupe, deleteAction, editAction, enumColumn$1 as enumColumn, executeGQL, exportGraphSnapshot, exportGraphSnapshotWithSchemas, fetchEntity, fetchList, flattenClauses, getCoreRowModel, getEntityJsonSchema, getEntityTransport, getExpandedRowModel, getFacetedMinMaxValues, getFacetedRowModel, getFacetedUniqueValues, getFilteredRowModel, getGroupedRowModel, getPaginatedRowModel, getRealtimeManager, getRegisteredEntityTypes, getSchema, getSelectedRowModel, getSortedRowModel, hasCustomPredicates, hydrateGraphFromStorage, makeRestTransport, matchesFilter, matchesSearch, normalizeGQLResponse, numberColumn$1 as numberColumn, parseCreateTable, persistGraphToStorage, prismaRelationsToSchema, actionsColumn as pureActionsColumn, booleanColumn as pureBooleanColumn, dateColumn as pureDateColumn, enumColumn as pureEnumColumn, numberColumn as pureNumberColumn, selectionColumn as pureSelectionColumn, textColumn as pureTextColumn, queryOnce, readRelations, registerEntityFromSql, registerEntityJsonSchema, registerEntityTransport, registerRuntimeSchema, registerSchema, renderMarkdownToHtml, replayActionWithRetry, resetRealtimeManager, selectGraph, selectionColumn$1 as selectionColumn, serializeKey, sqlTypeToJsonSchema, startGarbageCollector, startLocalFirstGraph, stopGarbageCollector, textColumn$1 as textColumn, toEntityError, toGraphQLVariables, toPrismaInclude, toPrismaOrderBy, toPrismaWhere, toRestParams, toSQLClauses, useEntities, useEntity, useEntityAugment, useEntityCRUD, useEntityList, useEntityListAsTable, useEntityMutation, useEntityQuery, useEntityView, useGQLEntity, useGQLList, useGQLMutation, useGQLSubscription, useGraphDevTools, useGraphStore, useGraphSyncStatus, useLocalFirst, usePGliteQuery, useSchemaEntityFields, useSelectionContext, useSelectionStore, useSuspenseEntity, useSuspenseEntityList, useTable, useTablePresets, useTableRealtimeMode, useTableStorageAdapter, viewAction };