@toclocoinc/lattice-grid 1.63.2 → 1.64.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.
Files changed (163) hide show
  1. package/README.md +2 -1
  2. package/docs/API.html +674 -53
  3. package/docs/CHART-CODES.md +24 -0
  4. package/docs/api-detail.html +111 -5
  5. package/lattice-grid.d.ts +93 -1
  6. package/lattice-grid.esm.min.js +154 -95
  7. package/lattice-grid.min.cjs +154 -95
  8. package/lattice-grid.min.js +154 -95
  9. package/modules/ai.d.ts +1 -1
  10. package/modules/ai.esm.min.js +3 -6
  11. package/modules/ai.min.cjs +3 -6
  12. package/modules/ai.min.js +3 -6
  13. package/modules/angular.d.ts +1 -1
  14. package/modules/angular.esm.min.js +1 -4
  15. package/modules/angular.min.cjs +1 -4
  16. package/modules/angular.min.js +1 -4
  17. package/modules/chart-alluvial.d.ts +1 -1
  18. package/modules/chart-alluvial.esm.min.js +1 -1
  19. package/modules/chart-alluvial.min.cjs +1 -1
  20. package/modules/chart-alluvial.min.js +1 -1
  21. package/modules/chart-arc.d.ts +1 -1
  22. package/modules/chart-arc.esm.min.js +1 -1
  23. package/modules/chart-arc.min.cjs +1 -1
  24. package/modules/chart-arc.min.js +1 -1
  25. package/modules/chart-bubblemap.d.ts +1 -1
  26. package/modules/chart-bubblemap.esm.min.js +1 -1
  27. package/modules/chart-bubblemap.min.cjs +1 -1
  28. package/modules/chart-bubblemap.min.js +1 -1
  29. package/modules/chart-bump.d.ts +1 -1
  30. package/modules/chart-bump.esm.min.js +1 -1
  31. package/modules/chart-bump.min.cjs +1 -1
  32. package/modules/chart-bump.min.js +1 -1
  33. package/modules/chart-calendar.d.ts +1 -1
  34. package/modules/chart-calendar.esm.min.js +1 -1
  35. package/modules/chart-calendar.min.cjs +1 -1
  36. package/modules/chart-calendar.min.js +1 -1
  37. package/modules/chart-decomposition.d.ts +1 -1
  38. package/modules/chart-decomposition.esm.min.js +1 -1
  39. package/modules/chart-decomposition.min.cjs +1 -1
  40. package/modules/chart-decomposition.min.js +1 -1
  41. package/modules/chart-diverging.d.ts +1 -1
  42. package/modules/chart-diverging.esm.min.js +1 -1
  43. package/modules/chart-diverging.min.cjs +1 -1
  44. package/modules/chart-diverging.min.js +1 -1
  45. package/modules/chart-dumbbell.d.ts +1 -1
  46. package/modules/chart-dumbbell.esm.min.js +1 -1
  47. package/modules/chart-dumbbell.min.cjs +1 -1
  48. package/modules/chart-dumbbell.min.js +1 -1
  49. package/modules/chart-fan.d.ts +1 -1
  50. package/modules/chart-fan.esm.min.js +1 -1
  51. package/modules/chart-fan.min.cjs +1 -1
  52. package/modules/chart-fan.min.js +1 -1
  53. package/modules/chart-hexbin.d.ts +1 -1
  54. package/modules/chart-hexbin.esm.min.js +1 -1
  55. package/modules/chart-hexbin.min.cjs +1 -1
  56. package/modules/chart-hexbin.min.js +1 -1
  57. package/modules/chart-hexmap.d.ts +1 -1
  58. package/modules/chart-hexmap.esm.min.js +1 -1
  59. package/modules/chart-hexmap.min.cjs +1 -1
  60. package/modules/chart-hexmap.min.js +1 -1
  61. package/modules/chart-icicle.d.ts +1 -1
  62. package/modules/chart-icicle.esm.min.js +1 -1
  63. package/modules/chart-icicle.min.cjs +1 -1
  64. package/modules/chart-icicle.min.js +1 -1
  65. package/modules/chart-markermap.d.ts +29 -0
  66. package/modules/chart-markermap.esm.min.js +313 -0
  67. package/modules/chart-markermap.min.cjs +317 -0
  68. package/modules/chart-markermap.min.js +317 -0
  69. package/modules/chart-parallel.d.ts +1 -1
  70. package/modules/chart-parallel.esm.min.js +1 -1
  71. package/modules/chart-parallel.min.cjs +1 -1
  72. package/modules/chart-parallel.min.js +1 -1
  73. package/modules/chart-ridgeline.d.ts +1 -1
  74. package/modules/chart-ridgeline.esm.min.js +1 -1
  75. package/modules/chart-ridgeline.min.cjs +1 -1
  76. package/modules/chart-ridgeline.min.js +1 -1
  77. package/modules/chart-roc.d.ts +1 -1
  78. package/modules/chart-roc.esm.min.js +1 -1
  79. package/modules/chart-roc.min.cjs +1 -1
  80. package/modules/chart-roc.min.js +1 -1
  81. package/modules/chart-slope.d.ts +1 -1
  82. package/modules/chart-slope.esm.min.js +1 -1
  83. package/modules/chart-slope.min.cjs +1 -1
  84. package/modules/chart-slope.min.js +1 -1
  85. package/modules/chart-splom.d.ts +1 -1
  86. package/modules/chart-splom.esm.min.js +1 -1
  87. package/modules/chart-splom.min.cjs +1 -1
  88. package/modules/chart-splom.min.js +1 -1
  89. package/modules/chart-waffle.d.ts +1 -1
  90. package/modules/chart-waffle.esm.min.js +1 -1
  91. package/modules/chart-waffle.min.cjs +1 -1
  92. package/modules/chart-waffle.min.js +1 -1
  93. package/modules/charts.d.ts +1 -1
  94. package/modules/charts.esm.min.js +395 -33
  95. package/modules/charts.min.cjs +395 -33
  96. package/modules/charts.min.js +395 -33
  97. package/modules/data-router.d.ts +313 -30
  98. package/modules/data-router.esm.min.js +3 -6
  99. package/modules/data-router.min.cjs +3 -6
  100. package/modules/data-router.min.js +3 -6
  101. package/modules/devtools.d.ts +1 -1
  102. package/modules/devtools.esm.min.js +1 -4
  103. package/modules/devtools.min.cjs +1 -4
  104. package/modules/devtools.min.js +1 -4
  105. package/modules/dhtmlx-compat.d.ts +1 -1
  106. package/modules/dhtmlx-compat.esm.min.js +3 -6
  107. package/modules/dhtmlx-compat.min.cjs +3 -6
  108. package/modules/dhtmlx-compat.min.js +3 -6
  109. package/modules/gantt.d.ts +1 -1
  110. package/modules/gantt.esm.min.js +3 -6
  111. package/modules/gantt.min.cjs +3 -6
  112. package/modules/gantt.min.js +3 -6
  113. package/modules/geo-europe-nuts.d.ts +1 -1
  114. package/modules/geo-europe-nuts.esm.min.js +1 -1
  115. package/modules/geo-uk.d.ts +1 -1
  116. package/modules/geo-uk.esm.min.js +1 -1
  117. package/modules/geo-us-states.d.ts +1 -1
  118. package/modules/geo-us-states.esm.min.js +1 -1
  119. package/modules/geo-world-110m.d.ts +1 -1
  120. package/modules/geo-world-110m.esm.min.js +1 -1
  121. package/modules/geo-world-50m.d.ts +1 -1
  122. package/modules/geo-world-50m.esm.min.js +1 -1
  123. package/modules/htmx.d.ts +1 -1
  124. package/modules/htmx.esm.min.js +154 -95
  125. package/modules/htmx.min.cjs +154 -95
  126. package/modules/htmx.min.js +154 -95
  127. package/modules/kanban.d.ts +1 -1
  128. package/modules/kanban.esm.min.js +3 -6
  129. package/modules/kanban.min.cjs +3 -6
  130. package/modules/kanban.min.js +3 -6
  131. package/modules/kpi.d.ts +56 -3
  132. package/modules/kpi.esm.min.js +202 -10
  133. package/modules/kpi.min.cjs +202 -10
  134. package/modules/kpi.min.js +202 -10
  135. package/modules/layout.d.ts +1 -1
  136. package/modules/layout.esm.min.js +3 -6
  137. package/modules/layout.min.cjs +3 -6
  138. package/modules/layout.min.js +3 -6
  139. package/modules/mock-socket.d.ts +1 -1
  140. package/modules/mock-socket.esm.min.js +1 -4
  141. package/modules/mock-socket.min.cjs +1 -4
  142. package/modules/mock-socket.min.js +1 -4
  143. package/modules/react.d.ts +1 -1
  144. package/modules/react.esm.min.js +3 -6
  145. package/modules/react.min.cjs +3 -6
  146. package/modules/react.min.js +3 -6
  147. package/modules/svelte.d.ts +1 -1
  148. package/modules/svelte.esm.min.js +1 -4
  149. package/modules/svelte.min.cjs +1 -4
  150. package/modules/svelte.min.js +1 -4
  151. package/modules/tabs.d.ts +1 -1
  152. package/modules/tabs.esm.min.js +3 -6
  153. package/modules/tabs.min.cjs +3 -6
  154. package/modules/tabs.min.js +3 -6
  155. package/modules/vue.d.ts +1 -1
  156. package/modules/vue.esm.min.js +1 -4
  157. package/modules/vue.min.cjs +1 -4
  158. package/modules/vue.min.js +1 -4
  159. package/modules/webcomponent.d.ts +1 -1
  160. package/modules/webcomponent.esm.min.js +154 -95
  161. package/modules/webcomponent.min.cjs +154 -95
  162. package/modules/webcomponent.min.js +154 -95
  163. package/package.json +1 -1
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * Lattice Grid 1.63.2, data-router module type declarations
2
+ * Lattice Grid 1.64.0, data-router module type declarations
3
3
  * Copyright (c) 2026 TOCLOCO Inc. All rights reserved.
4
4
  * https://latticegrid.dev
5
5
  */
@@ -9,25 +9,89 @@
9
9
  */
10
10
  type RouterRecord = Record<string, unknown>;
11
11
 
12
+ /** A property name, or a function reading the value off a row. */
13
+ type RouterKey = string | ((row: RouterRecord) => unknown);
14
+
12
15
  /** A per-route diff summary returned by `load`. */
13
16
  interface RouteDiff { added: number; updated: number; removed: number }
14
17
 
15
- /** A predicate: a property value (`row[key] === value`) or a `fn(row)`. */
16
- type RoutePredicate = unknown | ((row: RouterRecord) => boolean);
18
+ /**
19
+ * What a route matches: a partition VALUE (the record is routed when
20
+ * `row[key] === value`), or a `fn(row)` predicate for a composite route.
21
+ * Declared as `unknown` because any value can be a partition key; the
22
+ * function form is the only one TypeScript can check.
23
+ */
24
+ type RoutePredicate = unknown;
25
+
26
+ /** A route's `sort`: a comparator, or a key and direction (`'asc'` unless `'desc'`). */
27
+ type RouteSort = ((a: RouterRecord, b: RouterRecord) => number) | { key: string; dir?: 'asc' | 'desc' };
28
+
29
+ /**
30
+ * One incremental change: `upsert` adds or updates the row by `rowKey`,
31
+ * `delete` removes it. `seq` versions the delta when the row itself carries
32
+ * no version field (the router's `seq` option names one that does).
33
+ */
34
+ interface RouterDelta { op: 'upsert' | 'delete'; row: RouterRecord; seq?: number }
35
+
36
+ /** The change a `subscribe` handler receives: the same keyed diff a grid gets. */
37
+ interface RouterChange { add: RouterRecord[]; update: RouterRecord[]; remove: string[] }
38
+
39
+ /**
40
+ * A filter-wire condition for a route's `where` (v7): `{ col, op, value }`,
41
+ * or an `and` / `or` / `not` group of them.
42
+ */
43
+ type RouteWhere = Record<string, unknown>;
44
+
45
+ /**
46
+ * A rollup route's summary spec (v3): one summary row per `groupBy` group,
47
+ * each `aggregate` a named reducer over the group's rows or a `{ op, field }`
48
+ * shorthand (`sum`, `avg`, `min`, `max`, `count`).
49
+ */
50
+ interface RouteRollup {
51
+ groupBy: RouterKey | RouterKey[];
52
+ aggregate?: Record<string, ((rows: RouterRecord[]) => unknown) | { op: string; field?: string }>;
53
+ }
54
+
55
+ /**
56
+ * A route's backpressure policy (v13): how its viewer is refreshed under load.
57
+ * `maxHz` or `minInterval` caps the refresh rate; `sample` repaints only once
58
+ * N changes have accrued; `maxLag` is the backlog depth at or below which
59
+ * changes pass straight through and the limits stay off. All optional.
60
+ */
61
+ interface RouteBackpressure { maxHz?: number; minInterval?: number; sample?: number; maxLag?: number }
62
+
63
+ /** A write captured off a writable route's grid, handed to `onWrite`. */
64
+ type RouterWrite = Record<string, unknown>;
17
65
 
18
66
  /**
19
- * Per-route reshaping options (v3, BACKLOG-0000887): `transform` maps/renames/
20
- * derives each row before the grid sees it; `filter` gives the grid only the
21
- * rows it admits; `sort` (a comparator or `{ key, dir }`) orders what the grid
22
- * receives. `rowKey` overrides the router default. All optional.
67
+ * Per-route options, shared by `attach`, `attachDefault` and `subscribe`.
68
+ * `rowKey` overrides the router default for this route. `transform` reshapes
69
+ * each row before the viewer sees it; `filter` admits a subset; `sort`
70
+ * orders what the viewer receives; `rollup` summarises the slice (v3). A
71
+ * `transform` or `rollup` route is derived and cannot be `writable`. `where`
72
+ * is read only by `query()` (v7). `writable` routes the grid's committed
73
+ * edits to `onWrite`, reverting on reject, with `onConflict` for a last-
74
+ * write-wins conflict (v8); both default to the router's own. `label` names
75
+ * the route in metrics and the devtools panel; `backpressure` throttles its
76
+ * refresh under load (v13).
23
77
  */
24
78
  interface RouteOptions {
25
- rowKey?: (string | ((row: RouterRecord) => unknown));
79
+ rowKey?: RouterKey;
26
80
  transform?: (row: RouterRecord) => RouterRecord;
27
81
  filter?: (row: RouterRecord) => boolean;
28
- sort?: (((a: RouterRecord, b: RouterRecord) => number) | { key: string; dir?: 'asc' | 'desc' });
82
+ sort?: RouteSort;
83
+ rollup?: RouteRollup;
84
+ where?: RouteWhere;
85
+ writable?: boolean;
86
+ onWrite?: (change: RouterWrite, ctx: { route: unknown; source: unknown }) => unknown;
87
+ onConflict?: (change: RouterWrite, ctx: { serverRow: RouterRecord }) => void;
88
+ label?: string;
89
+ backpressure?: RouteBackpressure;
29
90
  }
30
91
 
92
+ /** Per-alert options (v5): `filter` narrows the slice; `debounce` (ms) coalesces a burst into one emit. */
93
+ interface AlertOptions { rowKey?: RouterKey; filter?: (row: RouterRecord) => boolean; debounce?: number }
94
+
31
95
  /**
32
96
  * A cross-grid selection relation (v2, BACKLOG-0000880): a key map (target
33
97
  * rows whose `to` value is among the selected source rows' `from` values — an
@@ -38,6 +102,137 @@ type SelectionRelation =
38
102
  | { from: string; to: string }
39
103
  | ((selected: RouterRecord[]) => ((row: RouterRecord) => boolean));
40
104
 
105
+ /**
106
+ * One edge of a relationship graph (v3): the source grid whose selection
107
+ * filters the target. `on` (or `relation`) is the relation; `mutual` makes
108
+ * the edge work in both directions.
109
+ */
110
+ interface RouterEdge { from: unknown; to: unknown; on?: SelectionRelation; relation?: SelectionRelation; mutual?: boolean }
111
+
112
+ /**
113
+ * A declarative routing graph (v5, BACKLOG-0000910): the same routes, links,
114
+ * relationship edges and buffer the imperative calls would make, as one data
115
+ * spec. Desugars to those calls and composes with them.
116
+ */
117
+ interface RouterConfig {
118
+ routes?: Record<string, unknown>[];
119
+ links?: { from: unknown; to: unknown; on?: SelectionRelation; relation?: SelectionRelation }[];
120
+ relate?: RouterEdge[];
121
+ buffer?: { window?: number; max?: number };
122
+ }
123
+
124
+ /**
125
+ * A fan-in source's lookup join (v11): `from` is the lookup source's id;
126
+ * `localKey` (alias `on`) reads the joining value off this source's row;
127
+ * `foreignKey` (alias `fromKey`) reads it off the lookup row, defaulting to a
128
+ * string `localKey`; `fields` (alias `select`) picks the lookup fields to
129
+ * carry — a list, a rename map, or a function of both rows; `missing` says
130
+ * what to do while the lookup row has not arrived: `hold` the row back,
131
+ * `passthrough` it unjoined, or fill the fields with `null`.
132
+ */
133
+ interface RouterJoin {
134
+ from: string;
135
+ localKey?: RouterKey;
136
+ on?: RouterKey;
137
+ foreignKey?: RouterKey;
138
+ fromKey?: RouterKey;
139
+ fields?: string[] | Record<string, string> | ((lookupRow: RouterRecord | null, leftRow: RouterRecord) => RouterRecord);
140
+ select?: string[] | Record<string, string> | ((lookupRow: RouterRecord | null, leftRow: RouterRecord) => RouterRecord);
141
+ missing?: 'hold' | 'passthrough' | 'null';
142
+ }
143
+
144
+ /**
145
+ * Options for a fan-in source (v9): `map` normalises each of the feed's rows
146
+ * before routing; `key` namespaces the feed's identities (`true` prefixes
147
+ * the source id) so feeds with colliding ids do not clobber one another;
148
+ * `join` enriches rows from another registered source (v11).
149
+ */
150
+ interface RouterSourceOptions { id?: string; map?: (row: RouterRecord) => RouterRecord; key?: unknown; join?: RouterJoin }
151
+
152
+ /**
153
+ * The handle `addSource` returns for one feed (v9). Its `load` is a
154
+ * per-source snapshot — a keyed diff over this feed's rows only, other feeds
155
+ * untouched; `apply` and `push` take this feed's deltas through the router's
156
+ * ordinary and batched paths; `remove` deletes exactly the rows it holds and
157
+ * unregisters it, returning the router.
158
+ */
159
+ interface RouterSourceHandle {
160
+ /** The source id. */
161
+ readonly id: string;
162
+ /** How many rows this source currently holds live. */
163
+ readonly size: number;
164
+ /** Apply a per-source snapshot: upsert its current rows, delete the ones it no longer has. */
165
+ load(rows: RouterRecord[]): RouterSourceHandle;
166
+ /** Apply per-source deltas through the router's ordinary apply path. */
167
+ apply(deltas: RouterDelta[]): RouterSourceHandle;
168
+ /** Enqueue per-source deltas through the router's stream path (batching honoured). */
169
+ push(delta: RouterDelta | RouterDelta[]): RouterSourceHandle;
170
+ /** Remove this source: delete exactly the rows it holds from every route, then unregister it. */
171
+ remove(): DataRouter;
172
+ }
173
+
174
+ /** One route's figures in a `metrics()` snapshot (v10). */
175
+ interface RouterRouteMetrics {
176
+ label: string | null;
177
+ rows: number;
178
+ shown: number;
179
+ throughput: number;
180
+ [key: string]: unknown;
181
+ }
182
+
183
+ /** One source's figures in a `metrics()` snapshot (v10). */
184
+ interface RouterSourceMetrics { id: string; rows: number; throughput: number; [key: string]: unknown }
185
+
186
+ /**
187
+ * A `metrics()` snapshot (v10): per-route and per-source counts and
188
+ * throughput (rows/sec since the previous read), and the global unrouted,
189
+ * dropped (duplicate), buffered and lag figures.
190
+ */
191
+ interface RouterMetrics {
192
+ routes: RouterRouteMetrics[];
193
+ sources: RouterSourceMetrics[];
194
+ unrouted: number;
195
+ dropped: number;
196
+ buffered: number;
197
+ lag: number;
198
+ throughput: number;
199
+ }
200
+
201
+ /**
202
+ * One entry of `lastQueryPlan()` (v7): a `where` route's fetch, or the single
203
+ * `base` fetch that fed every route without a `where`. `pushedFilter` says
204
+ * whether the filter reached the engine; `residual` is what was finished
205
+ * client-side.
206
+ */
207
+ interface RouterQueryPlanEntry { route?: unknown; base?: boolean; pushedFilter: boolean; residual: unknown }
208
+
209
+ /** The controller `mountDevtools` returns: `refresh` re-renders now, `destroy` unsubscribes and removes the panel. */
210
+ interface RouterDevtoolsPanel { refresh(): void; destroy(): void }
211
+
212
+ /**
213
+ * A pushdown adapter `query()` can source the router from (v7): anything
214
+ * with an `execute(query, request)` returning rows, and optional
215
+ * `capabilities` the planner consults to decide what it may push down.
216
+ */
217
+ interface RouterQueryAdapter {
218
+ capabilities?: Record<string, unknown>;
219
+ execute: (query: Record<string, unknown>, request?: Record<string, unknown>) => Promise<{ rows: RouterRecord[]; total?: number }>;
220
+ }
221
+
222
+ /**
223
+ * Durable persistence options (v12): `key` names the snapshot, `debounce`
224
+ * (ms) coalesces writes, `storage` is a `{ get, set }` pair of your own, or
225
+ * `indexedDB` / `dbName` / `storeName` select the browser store.
226
+ */
227
+ interface RouterPersistOptions {
228
+ key?: string;
229
+ debounce?: number;
230
+ storage?: { get: (key: string) => Promise<unknown>; set: (key: string, value: unknown) => Promise<void> };
231
+ indexedDB?: unknown;
232
+ dbName?: string;
233
+ storeName?: string;
234
+ }
235
+
41
236
  /**
42
237
  * A data router: one arriving stream, partitioned by a property (or composite
43
238
  * predicate), fanned out to a grid per partition (BACKLOG-0000879). Each grid
@@ -47,16 +242,16 @@ type SelectionRelation =
47
242
  * update or remove in place by `rowKey`, preserving selection and scroll.
48
243
  */
49
244
  interface DataRouter {
50
- /** Attach a grid behind a predicate; `opts` may reshape/filter/sort the route (v3). */
245
+ /** Attach a grid behind a predicate; `opts` may reshape, filter, sort, summarise or throttle the route. */
51
246
  attach(grid: unknown, predicate: RoutePredicate, opts?: RouteOptions): DataRouter;
52
- /** Attach the "rest" sink for records no explicit route matched. */
247
+ /** Attach the "rest" sink for records no explicit route matched. A second call replaces the first. */
53
248
  attachDefault(grid: unknown, opts?: RouteOptions): DataRouter;
54
- /** Detach a grid; the host still owns and destroys it. */
55
- detach(grid: unknown): DataRouter;
56
- /** Apply a full snapshot as a keyed diff per grid; returns per-route counts. */
57
- load(snapshot: RouterRecord[]): RouteDiff[];
58
- /** Apply incremental deltas, routed and applied in place by `rowKey`. */
59
- apply(deltas: { op: 'upsert' | 'delete'; row: RouterRecord }[]): void;
249
+ /** Route a partition slice to any non-grid view (v5): the handler receives the same keyed diff a grid would. */
250
+ subscribe(predicate: RoutePredicate, handler: (change: RouterChange) => void, opts?: RouteOptions): DataRouter;
251
+ /** Watch a slice and emit on a rising edge of `condition` rather than render (v5). Removed only by `destroy`. */
252
+ alert(predicate: RoutePredicate, condition: (rows: RouterRecord[]) => unknown, handler: (signal: unknown, rows: RouterRecord[]) => void, opts?: AlertOptions): DataRouter;
253
+ /** Take the whole routing graph as one declarative spec (v5); desugars to the calls above and composes with them. */
254
+ configure(spec?: RouterConfig): DataRouter;
60
255
  /**
61
256
  * Link a source grid's selection to what a target grid receives (v2,
62
257
  * BACKLOG-0000880): the target shows the subset of its partition the
@@ -64,28 +259,116 @@ interface DataRouter {
64
259
  * shows the full partition; changes are debounced.
65
260
  */
66
261
  link(source: unknown, target: unknown, relation: SelectionRelation): DataRouter;
262
+ /** Declare a relationship graph (v3): multi-hop, several-into-one and mutual edges — the scalable form of `link`. */
263
+ relate(edges: RouterEdge[]): DataRouter;
67
264
  /** Apply any debounced selection refilter synchronously (for tests/determinism). */
68
265
  flush(): DataRouter;
69
- /** How many records matched no route. */
266
+ /** Detach a grid — or a `subscribe` handler — and drop any link it is part of; the host still owns and destroys it. */
267
+ detach(grid: unknown): DataRouter;
268
+ /** Apply a full snapshot as a keyed diff per grid; returns per-route counts. Resets `unrouted`. */
269
+ load(snapshot: RouterRecord[]): RouteDiff[];
270
+ /** Apply incremental deltas, routed and applied in place by `rowKey`; ordered and de-duplicated when `seq` is on. */
271
+ apply(deltas: RouterDelta[]): void;
272
+ /** Enqueue deltas for batched or coalesced application (v3); applies at once when no batching mode is on. */
273
+ push(delta: RouterDelta | RouterDelta[]): DataRouter;
274
+ /** Apply the buffered deltas now as a single `apply` (v3) — a deterministic point, and for tests. */
275
+ flushStream(): DataRouter;
276
+ /** Refresh every backpressured route to the latest state now (v13); a no-op with nothing pending. */
277
+ flushBackpressure(): DataRouter;
278
+ /** Register a source feed for fan-in (v9): its rows are normalised and namespaced into the one keyed store. */
279
+ addSource(feed: string | RouterSourceOptions, opts?: RouterSourceOptions): RouterSourceHandle;
280
+ /** Remove a source feed by id or handle (v9): delete exactly its rows from every route, then unregister it. */
281
+ removeSource(ref: string | RouterSourceHandle): DataRouter;
282
+ /** The registered source ids (v9). */
283
+ sources(): string[];
284
+ /** A cheap point-in-time snapshot of the router's runtime (v10); throughput is measured since the previous read. */
285
+ metrics(): RouterMetrics;
286
+ /** Subscribe to the periodic `metrics` emit (v10) — the only event; the timer runs only while a listener is registered. Returns the unsubscribe. */
287
+ on(event: 'metrics', handler: (snapshot: RouterMetrics) => void): () => void;
288
+ /** Mount the live devtools panel into `el` (v10); it re-renders on each `metrics` emit. */
289
+ mountDevtools(el: unknown): RouterDevtoolsPanel;
290
+ /** How many records matched no route since the last `load` or `query`, running for deltas. */
70
291
  readonly unrouted: number;
292
+ /** How many stale or duplicate deltas the dedupe gate dropped since creation (v3). */
293
+ readonly dropped: number;
294
+ /** The highest seq applied — the resume point to request the feed from after a dropped socket (v3). */
295
+ lastSeq(): number | undefined;
296
+ /** A copy of the per-record resume checkpoint: record identity → last applied seq (v3). */
297
+ checkpoint(): Map<string, number>;
298
+ /** Prime the resume checkpoint from a persisted one, so replayed deltas at or below those seqs are dropped (v3). */
299
+ seenThrough(mark: Map<string, number> | Record<string, number>): DataRouter;
300
+ /** Turn on durable persistence of the router's state (v12). */
301
+ persist(opts?: RouterPersistOptions): DataRouter;
302
+ /** Resume from the durable snapshot (v12); resolves true when one was found and applied. */
303
+ restore(): Promise<boolean>;
304
+ /** Flush any pending durable write now (v12); resolves once it has settled. */
305
+ flushPersist(): Promise<DataRouter>;
306
+ /** Whether durable persistence is on and not degraded to in-memory (v12). */
307
+ readonly persisting: boolean;
308
+ /** Record the stream into a bounded ring for time travel (v4): a time `window` in ms and/or a `max` delta count. */
309
+ buffer(opts?: { window?: number; max?: number }): DataRouter;
310
+ /** Scrub the attached grids to a past seq or timestamp (v4). */
311
+ scrubTo(target: number, opts?: { by?: 'seq' | 'time' }): DataRouter;
312
+ /** Replay a buffered range step by step (v4); resolves when it completes or is superseded. */
313
+ replay(from: number, to: number, opts?: { speed?: number; by?: 'seq' | 'time' }): Promise<void>;
314
+ /** Pause an in-flight replay at the current step (v4); a no-op when nothing is replaying. */
315
+ pause(): DataRouter;
316
+ /** Resume a paused replay from where it stopped (v4); a no-op when not paused. */
317
+ resume(): DataRouter;
318
+ /** Return to live (v4): rebuild the head from the base plus every buffered delta. */
319
+ live(): DataRouter;
320
+ /** Whether the grids are currently showing a reconstructed past (v4). */
321
+ readonly traveling: boolean;
322
+ /** How many deltas the bounded buffer currently holds (v4). */
323
+ readonly buffered: number;
324
+ /** Mirror the ordered, de-duplicated deltas to other tabs over a BroadcastChannel (v6), with no echo loop. */
325
+ broadcast(opts: { channel: string }): DataRouter;
326
+ /** Whether the router is mirroring to a BroadcastChannel (v6). */
327
+ readonly broadcasting: boolean;
328
+ /** Source the router from a pushdown adapter (v7): each `where` route is planned against the adapter's capabilities. */
329
+ query(adapter: RouterQueryAdapter, request?: Record<string, unknown>): Promise<DataRouter>;
330
+ /** The pushed/residual split of the last `query()` (v7), per fetch, or null before any. */
331
+ lastQueryPlan(): RouterQueryPlanEntry[] | null;
71
332
  /** Detach every grid and drop every link (the host destroys the grids themselves). */
72
333
  destroy(): void;
73
334
  }
74
335
 
75
336
  /**
76
- * Create a data router that partitions one stream to many grids.
77
- *
78
- * `key` is the partition property or `fn(row)`; `rowKey` is the identity within
79
- * a grid; `overlap` fans a record to every matching route (default: first match
80
- * wins); `onUnrouted` receives records that match none; `selectionDebounce` is
81
- * the debounce in ms for cross-grid selection refilters (default 16; `0` is
82
- * synchronous).
337
+ * Options for `createDataRouter`. `key` is the partition property or
338
+ * `fn(row)`; optional, since a router whose routes all use `fn(row)`
339
+ * predicates never reads it. `rowKey` is the identity within a grid;
340
+ * `overlap` fans a record to every matching route (default: first match
341
+ * wins); `onUnrouted` receives what matched no route — the row on `load` and
342
+ * `query`, the whole delta on `apply`; `selectionDebounce` is the ms
343
+ * debounce for cross-grid selection refilters (default 16; `0` is
344
+ * synchronous). `seq` names the per-record version that orders and
345
+ * de-duplicates a feed (v3), `dedupe` (default on with `seq`) drops stale
346
+ * and duplicate deltas; `batch` (ms, or `{ intervalMs }`) and `coalesce`
347
+ * buffer a high-frequency feed for `push`; `time` reads a row's timestamp
348
+ * for time-domain scrubbing and `now` overrides the clock (v4); `config` is
349
+ * a declarative routing graph applied at construction (v5); `onWrite` and
350
+ * `onConflict` are the defaults for every writable route (v8);
351
+ * `metricsInterval` is the ms between `metrics` emits (default 1000; `0`
352
+ * disables the timer) (v10).
83
353
  */
84
- export function createDataRouter(opts: {
85
- key: (string | ((row: RouterRecord) => unknown));
86
- rowKey?: (string | ((row: RouterRecord) => unknown));
354
+ interface DataRouterOptions {
355
+ key?: RouterKey;
356
+ rowKey?: RouterKey;
87
357
  overlap?: boolean;
88
- onUnrouted?: (item: unknown) => void;
358
+ onUnrouted?: (item: RouterRecord | RouterDelta) => void;
89
359
  selectionDebounce?: number;
90
- }): DataRouter;
360
+ seq?: RouterKey;
361
+ dedupe?: boolean;
362
+ batch?: number | { intervalMs: number };
363
+ coalesce?: boolean;
364
+ time?: RouterKey;
365
+ now?: () => number;
366
+ config?: RouterConfig;
367
+ onWrite?: (change: RouterWrite, ctx: { route: unknown; source: unknown }) => unknown;
368
+ onConflict?: (change: RouterWrite, ctx: { serverRow: RouterRecord }) => void;
369
+ metricsInterval?: number;
370
+ }
371
+
372
+ /** Create a data router that partitions one stream to many grids. */
373
+ export function createDataRouter(opts?: DataRouterOptions): DataRouter;
91
374
  export default createDataRouter;