@declarion/react 0.53.0 → 0.54.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/dist-lib/{DraggableChildrenTable-BQZTvZaU.js → DraggableChildrenTable-Djc7QDzR.js} +32 -32
  2. package/dist-lib/{Grid-B9Tiytbd.js → Grid-Bd2r0_4J.js} +45 -45
  3. package/dist-lib/{LayoutRenderer-D_v9OD_A.js → LayoutRenderer-V6nf9aa_.js} +716 -714
  4. package/dist-lib/{ListCardsBody-dRnXsQ7A.js → ListCardsBody-Cdsvu0Vs.js} +29 -29
  5. package/dist-lib/{MarkdownRenderer-BCyrsLrd.js → MarkdownRenderer-CZo5ZgM7.js} +1 -1
  6. package/dist-lib/{RefreshControl-CV8nGACW.js → RefreshControl-CJm3vz9p.js} +40 -40
  7. package/dist-lib/{SmartDetailPage.impl-DWprVNMb.js → SmartDetailPage.impl-DoIjCzjQ.js} +492 -492
  8. package/dist-lib/{SmartListPage.impl-BwWURGwa.js → SmartListPage.impl-DnM8e14t.js} +743 -742
  9. package/dist-lib/{SmartRecordListPage.impl-BKKBShAg.js → SmartRecordListPage.impl-BmHGYbD9.js} +128 -128
  10. package/dist-lib/{SortHeaderMenu-pgi4sxMs.js → SortHeaderMenu-CA53NerB.js} +1 -1
  11. package/dist-lib/{action-dispatch-DlHTYag7.js → action-dispatch-JcUrLFaW.js} +177 -177
  12. package/dist-lib/api/agents.d.ts +0 -1
  13. package/dist-lib/api/events.d.ts +13 -4
  14. package/dist-lib/{cardProjection-C7Orz841.js → cardProjection-Q2kwqv8V.js} +19 -19
  15. package/dist-lib/components/actions/ObjectActionBar.d.ts +1 -1
  16. package/dist-lib/components/chrome/Breadcrumbs.d.ts +1 -1
  17. package/dist-lib/components/detail-layout/DetailAuditStrip.d.ts +1 -1
  18. package/dist-lib/components/detail-layout/DetailHighlights.d.ts +1 -1
  19. package/dist-lib/components/detail-layout/DraggableChildrenTable.d.ts +1 -1
  20. package/dist-lib/components/detail-layout/EditableChildrenTable.d.ts +1 -1
  21. package/dist-lib/components/detail-layout/LayoutRenderer.d.ts +1 -1
  22. package/dist-lib/components/file-widgets/host.d.ts +1 -1
  23. package/dist-lib/components/layout/Layout.d.ts +1 -1
  24. package/dist-lib/components/layout/TopBar.d.ts +1 -1
  25. package/dist-lib/components/list/InlineEditCell.d.ts +1 -1
  26. package/dist-lib/components/list/PeekFieldCell.d.ts +1 -1
  27. package/dist-lib/components/list/QuickPeek.d.ts +1 -1
  28. package/dist-lib/components/pages/auth/AuthShell.d.ts +1 -1
  29. package/dist-lib/components/pages/list/ListCardRow.d.ts +1 -1
  30. package/dist-lib/components/pages/list/ListCardsBody.d.ts +1 -1
  31. package/dist-lib/components/pages/list/ListFloatbar.d.ts +1 -1
  32. package/dist-lib/components/pages/list/ListHeader.d.ts +1 -1
  33. package/dist-lib/components/pages/list/ListToolbar.d.ts +5 -3
  34. package/dist-lib/components/pages/list/columns.d.ts +1 -1
  35. package/dist-lib/components/pages/list/filter-meta.d.ts +1 -1
  36. package/dist-lib/components/pages/list/use-filter-value-labels.d.ts +1 -1
  37. package/dist-lib/components/pages/list/useListQuery.d.ts +1 -5
  38. package/dist-lib/components/pages/list/useListRowInteraction.d.ts +1 -1
  39. package/dist-lib/components/pages/list/useListViews.d.ts +1 -1
  40. package/dist-lib/components/pages/list/useRowMenu.d.ts +1 -1
  41. package/dist-lib/{field-classification-EY8CFF3P.js → field-classification-ssZvtr8J.js} +268 -397
  42. package/dist-lib/{format-count-BHkaDr9V.js → format-count-DHuivNT7.js} +236 -236
  43. package/dist-lib/hooks/useEntityData.d.ts +7 -0
  44. package/dist-lib/hooks/useRealtimeThresholds.d.ts +1 -0
  45. package/dist-lib/hooks/useSSE.d.ts +0 -1
  46. package/dist-lib/index.js +1039 -1020
  47. package/dist-lib/lib/action-dispatch.d.ts +1 -1
  48. package/dist-lib/lib/realtime-query-keys.d.ts +22 -0
  49. package/dist-lib/lib/realtime-reconcile.d.ts +0 -9
  50. package/dist-lib/lib/realtime-resync.d.ts +23 -0
  51. package/dist-lib/{peekDraftStore-1pIajluX.js → peekDraftStore-lm9ViVLA.js} +17 -17
  52. package/dist-lib/{registry-C5ug25M8.js → registry-DsQFhEAD.js} +511 -511
  53. package/dist-lib/stores/realtime.d.ts +86 -19
  54. package/dist-lib/testing.js +40 -40
  55. package/dist-lib/types/api.d.ts +8 -4
  56. package/dist-lib/types/schema.d.ts +6 -0
  57. package/dist-lib/{useCurrentScreen-BdnZq8vZ.js → useCurrentScreen-aHx9HH1m.js} +2473 -1960
  58. package/dist-lib/useListQuery-DZn2BAxY.js +96 -0
  59. package/dist-lib/{useProperties-Bhi9Wn5O.js → useProperties-CAqKmUKg.js} +25 -25
  60. package/dist-lib/{useTabSearchMirror-Dl5x0xKu.js → useTabSearchMirror-DYW9WoK7.js} +10 -10
  61. package/dist-lib/{value-Rp-5W3o8.js → value-CzKQPJOp.js} +4 -4
  62. package/package.json +10 -10
  63. package/dist-lib/useListQuery-BxgrPZIB.js +0 -90
@@ -1,29 +1,96 @@
1
+ import type { QueryCacheNotifyEvent, QueryKey } from "@tanstack/react-query";
2
+ /** A query as the query cache holds it, whatever its data type. */
3
+ export type CachedQuery = QueryCacheNotifyEvent["query"];
4
+ /** An entity the relay is not delivering; `mark` lets a resync drop only the mark it saw. */
5
+ export interface DegradedMark {
6
+ mark: number;
7
+ since: number;
8
+ }
9
+ export interface RealtimeThresholds {
10
+ pauseGraceMs: number;
11
+ silenceMs: number;
12
+ }
13
+ /**
14
+ * Which query keys a resync covers. `all` and `entities` also take in matching
15
+ * keys first observed while the resync is pending; `keys` is fixed.
16
+ */
17
+ export type ResyncScope = {
18
+ kind: "all";
19
+ } | {
20
+ kind: "entities";
21
+ entities: ReadonlySet<string>;
22
+ } | {
23
+ kind: "keys";
24
+ };
25
+ export interface Resync {
26
+ id: number;
27
+ /** The fetch generation when it opened; only a fetch stamped above it satisfies a key. */
28
+ generation: number;
29
+ openedAt: number;
30
+ /** A refused read: shown at once, never issued, closed only by a fetch someone else starts. */
31
+ standing: boolean;
32
+ issued: boolean;
33
+ /** Whether issuing waits a random delay, so a fleet-wide cause does not burst. */
34
+ jitter: boolean;
35
+ scope: ResyncScope;
36
+ /** Query hash → key. */
37
+ keys: ReadonlyMap<string, QueryKey>;
38
+ /** Query hash → the query last seen observed under it, so a removed one still blocks while observed. */
39
+ observed: ReadonlyMap<string, CachedQuery>;
40
+ /** Marks dropped on completion, each only while it still carries this number. */
41
+ carriedMarks: ReadonlyMap<string, number>;
42
+ /** Entities with an observed key not yet satisfied. */
43
+ blocking: ReadonlySet<string>;
44
+ }
1
45
  interface RealtimeState {
2
- /** Entity codes the relay auto-degraded this session. */
3
- degradedEntities: ReadonlySet<string>;
4
- /** Mark one entity as auto-degraded. Idempotent. */
46
+ degradedEntities: ReadonlyMap<string, DegradedMark>;
47
+ /** Mark one entity degraded. A repeated mark renumbers it and keeps its start. */
5
48
  markDegraded: (entityCode: string) => void;
6
- /** Realtime is delivering everything again; forget every degraded entity. */
7
- clearDegraded: () => void;
49
+ /** Drop each mark named, only while the entity still carries that number. */
50
+ unmarkDegraded: (marks: ReadonlyMap<string, number>) => void;
51
+ /** Self-closing: no connection has stated its snapshot, or it went silent. */
52
+ connectionInterruptedSince: number | null;
53
+ holdConnectionInterruption: () => void;
54
+ clearConnectionInterruption: () => void;
55
+ /** Self-closing: the server's last word says the relay may not be streaming. */
56
+ relayInterruptedSince: number | null;
57
+ holdRelayInterruption: () => void;
58
+ clearRelayInterruption: () => void;
59
+ /** Self-closing: a connection presented a position and its replay has not applied. */
60
+ replayStartedAt: number | null;
61
+ startReplay: () => void;
62
+ endReplay: () => void;
8
63
  /**
9
- * True while a presented resume position's replay has not landed. The rows
10
- * keep rendering; what is not true is that they are up to date.
64
+ * Null while the declared thresholds load. `unreadable` is itself a held
65
+ * connection interruption, shown at once: claiming "Live" without the means
66
+ * to know is the defect this model removes.
11
67
  */
12
- replayPending: boolean;
13
- setReplayPending: (pending: boolean) => void;
14
- /**
15
- * True while a row re-read was turned away for budget. The rows keep
16
- * rendering, but only a refresh the person asks for will renew them.
17
- */
18
- readRefused: boolean;
19
- setReadRefused: (refused: boolean) => void;
68
+ thresholds: RealtimeThresholds | "unreadable" | null;
69
+ setThresholds: (thresholds: RealtimeThresholds | "unreadable" | null) => void;
70
+ resyncs: readonly Resync[];
71
+ addResync: (resync: Omit<Resync, "id">) => number;
72
+ updateResync: (id: number, patch: Partial<Omit<Resync, "id">>) => void;
73
+ removeResync: (id: number) => void;
20
74
  }
21
75
  export declare const useRealtimeStore: import("zustand").UseBoundStore<import("zustand").StoreApi<RealtimeState>>;
22
- export declare function isEntityLive(realtimeFlag: boolean | undefined, degradedEntities: ReadonlySet<string>, entityCode: string): boolean;
76
+ export declare function isEntityLive(realtimeFlag: boolean | undefined, degradedEntities: {
77
+ has(entityCode: string): boolean;
78
+ }, entityCode: string): boolean;
79
+ type CurrentnessInputs = Pick<RealtimeState, "degradedEntities" | "connectionInterruptedSince" | "relayInterruptedSince" | "replayStartedAt" | "thresholds" | "resyncs">;
80
+ /**
81
+ * Whether an entity is current at `now`, and the next instant that answer can
82
+ * flip without any state changing - when a self-closing cause reaches the pause
83
+ * grace. Measured from each cause's stored start, so every surface flips at the
84
+ * same instant.
85
+ */
86
+ export declare function screenCurrentness(state: CurrentnessInputs, realtimeFlag: boolean | undefined, entityCode: string, now: number): {
87
+ live: boolean;
88
+ recheckAt: number | null;
89
+ };
23
90
  /**
24
- * Whether a screen showing this entity is CURRENT - a different question from
25
- * isEntityLive, which answers whether the relay delivers at all. The rows keep
26
- * rendering throughout; this is what says they may be behind. docs/realtime.md.
91
+ * The one predicate every indicator reads: is the screen showing this entity
92
+ * CURRENT. The rows keep rendering throughout; this says whether they may be
93
+ * behind. docs/realtime.md "Currentness".
27
94
  */
28
95
  export declare function useScreenIsLive(realtimeFlag: boolean | undefined, entityCode: string): boolean;
29
96
  export {};
@@ -1,4 +1,4 @@
1
- import { Er as e, Jt as t, Vt as n, nn as r, on as i, r as a, rn as o, t as s, tn as c } from "./useCurrentScreen-BdnZq8vZ.js";
1
+ import { $t as e, Bt as t, cn as n, dn as r, jr as i, on as a, r as o, sn as s, t as c } from "./useCurrentScreen-aHx9HH1m.js";
2
2
  import { useState as l } from "react";
3
3
  import { MemoryRouter as u, useLocation as d } from "react-router";
4
4
  import { QueryClient as f, QueryClientProvider as p } from "@tanstack/react-query";
@@ -74,7 +74,7 @@ function T() {
74
74
  created_at: "2026-01-01T00:00:00Z",
75
75
  updated_at: "2026-01-01T00:00:00Z"
76
76
  };
77
- i.getState().setUser(t, e);
77
+ r.getState().setUser(t, e);
78
78
  }
79
79
  function E(e) {
80
80
  if (e === void 0) return { rows: [] };
@@ -89,15 +89,15 @@ function E(e) {
89
89
  }
90
90
  return e;
91
91
  }
92
- function D(e) {
93
- let n = e.entityData ?? {};
94
- o((t, r) => {
95
- let i = r;
96
- e.onListRequest?.(t, i);
97
- let a = n[t], o = typeof a == "function" ? a(i) : a;
92
+ function D(t) {
93
+ let r = t.entityData ?? {};
94
+ n((e, n) => {
95
+ let i = n;
96
+ t.onListRequest?.(e, i);
97
+ let a = r[e], o = typeof a == "function" ? a(i) : a;
98
98
  if (o instanceof Error) throw o;
99
99
  let s = E(o), c = s.meta?.per_page ?? 50, l = s.meta?.total ?? s.rows.length;
100
- return r.count === "only" ? {
100
+ return n.count === "only" ? {
101
101
  data: [],
102
102
  meta: {
103
103
  page: 1,
@@ -116,64 +116,64 @@ function D(e) {
116
116
  ...s.refs === void 0 ? {} : { $refs: s.refs }
117
117
  };
118
118
  });
119
- let i = e.entityItems ?? {}, a = e.entityItemResponses ?? {};
120
- r((e, n) => {
121
- let r = typeof n == "string" ? n : t(n), o = a[e]?.[r];
122
- if (o instanceof Error) throw o;
123
- if (o !== void 0) return o;
124
- let s = i[e]?.[r];
119
+ let i = t.entityItems ?? {}, o = t.entityItemResponses ?? {};
120
+ s((t, n) => {
121
+ let r = typeof n == "string" ? n : e(n), a = o[t]?.[r];
122
+ if (a instanceof Error) throw a;
123
+ if (a !== void 0) return a;
124
+ let s = i[t]?.[r];
125
125
  if (s instanceof Error) throw s;
126
126
  return { data: s };
127
127
  });
128
- let s = e.actionResults ?? {};
129
- c(async (e, t) => {
130
- if (!(e in s)) throw Error(`renderWithDeclarion: no action result registered for "${e}" (seed it via actionResults)`);
131
- let n = s[e];
128
+ let c = t.actionResults ?? {};
129
+ a(async (e, t) => {
130
+ if (!(e in c)) throw Error(`renderWithDeclarion: no action result registered for "${e}" (seed it via actionResults)`);
131
+ let n = c[e];
132
132
  return C(typeof n == "function" ? await n(t) : n);
133
133
  });
134
134
  }
135
135
  function O() {
136
- o(null), r(null), c(null), i.setState({
136
+ n(null), s(null), a(null), r.setState({
137
137
  user: null,
138
138
  isAuthenticated: !1,
139
139
  activeTenant: null,
140
140
  tenants: []
141
141
  });
142
142
  }
143
- function k(t, r = {}) {
144
- let i = new f({ defaultOptions: { queries: {
143
+ function k(e, n = {}) {
144
+ let r = new f({ defaultOptions: { queries: {
145
145
  retry: !1,
146
146
  gcTime: Infinity
147
147
  } } });
148
- T(), i.setQueryData(["schema", !0], r.schema ?? v()), D(r);
149
- let o = r.screenCode ? /* @__PURE__ */ h(s, {
150
- code: r.screenCode,
151
- children: t
152
- }) : t, c = { current: r.route ?? "/" }, l = /* @__PURE__ */ g(p, {
153
- client: i,
148
+ T(), r.setQueryData(["schema", !0], n.schema ?? v()), D(n);
149
+ let a = n.screenCode ? /* @__PURE__ */ h(c, {
150
+ code: n.screenCode,
151
+ children: e
152
+ }) : e, s = { current: n.route ?? "/" }, l = /* @__PURE__ */ g(p, {
153
+ client: r,
154
154
  children: [/* @__PURE__ */ g(u, {
155
- initialEntries: [r.route ?? "/"],
156
- children: [/* @__PURE__ */ h(w, { into: c }), /* @__PURE__ */ h(a, { children: o })]
155
+ initialEntries: [n.route ?? "/"],
156
+ children: [/* @__PURE__ */ h(w, { into: s }), /* @__PURE__ */ h(o, { children: a })]
157
157
  }), /* @__PURE__ */ h(m, {})]
158
- }), d = r.embedQuery ? /* @__PURE__ */ h(n, {
159
- query: r.embedQuery,
158
+ }), d = n.embedQuery ? /* @__PURE__ */ h(t, {
159
+ query: n.embedQuery,
160
160
  children: l
161
- }) : l, y = _(r.viewport ? /* @__PURE__ */ h(e, {
162
- viewportOverride: r.viewport,
161
+ }) : l, y = _(n.viewport ? /* @__PURE__ */ h(i, {
162
+ viewportOverride: n.viewport,
163
163
  children: d
164
164
  }) : d);
165
165
  return Object.assign(y, {
166
- queryClient: i,
167
- location: () => c.current
166
+ queryClient: r,
167
+ location: () => s.current
168
168
  });
169
169
  }
170
170
  function A({ children: e, authenticated: t = !0, ...n }) {
171
- let [r] = l(() => {
171
+ let [i] = l(() => {
172
172
  let e = new f({ defaultOptions: { queries: {
173
173
  retry: !1,
174
174
  gcTime: Infinity
175
175
  } } });
176
- return t ? (T(), e.setQueryData(["schema", !0], n.schema ?? v())) : i.setState({
176
+ return t ? (T(), e.setQueryData(["schema", !0], n.schema ?? v())) : r.setState({
177
177
  user: null,
178
178
  isAuthenticated: !1,
179
179
  activeTenant: null,
@@ -181,10 +181,10 @@ function A({ children: e, authenticated: t = !0, ...n }) {
181
181
  }), D(n), e;
182
182
  });
183
183
  return /* @__PURE__ */ g(p, {
184
- client: r,
184
+ client: i,
185
185
  children: [/* @__PURE__ */ h(u, {
186
186
  initialEntries: [n.route ?? "/"],
187
- children: /* @__PURE__ */ h(a, { children: e })
187
+ children: /* @__PURE__ */ h(o, { children: e })
188
188
  }), /* @__PURE__ */ h(m, {})]
189
189
  });
190
190
  }
@@ -1,4 +1,4 @@
1
- import type { AccentDef, LocalizedString } from "./schema";
1
+ import type { AccentDef, EntityField, LocalizedString } from "./schema";
2
2
  import type { HydratedFile } from "./files";
3
3
  import type { FilterNode } from "../lib/filters";
4
4
  export interface ListMeta {
@@ -398,7 +398,7 @@ export interface ParamLookup {
398
398
  /**
399
399
  * One entry of the bulk `GET /api/params` response (and per-code resolution).
400
400
  * Carries the declaration facets the admin UIs need to compute attachment,
401
- * render structure editors, and render choice selects, so the bulk endpoint is
401
+ * render structure editors, and render member selects, so the bulk endpoint is
402
402
  * self-sufficient without a second schema fetch.
403
403
  */
404
404
  export interface ResolvedParam {
@@ -413,8 +413,12 @@ export interface ResolvedParam {
413
413
  scopes?: string[];
414
414
  /** Structure code when `type === "structure"`. */
415
415
  structure?: string;
416
- /** Closed value set for a choices-constrained string param. */
417
- choices?: string[];
416
+ /** Members of a closed type - `enum`, or an enum-backed `string_array`.
417
+ * Carried whole rather than as bare codes so the editor can show a name. */
418
+ values?: EntityField["values"];
419
+ /** Shared enum this parameter names, when it names one rather than listing
420
+ * its members inline. Present for display; `values` is what to render. */
421
+ enum?: string;
418
422
  }
419
423
  export interface ParamOverride {
420
424
  param_code: string;
@@ -301,6 +301,12 @@ export interface ParameterDef {
301
301
  category?: string;
302
302
  /** Override scopes accepted on writes. Subset of: env, tenant, role, user, object. Empty = all. */
303
303
  scopes?: string[];
304
+ /** Members of a closed type - `enum`, or an enum-backed `string_array`. Resolved
305
+ * at load whether declared inline or by naming a shared enum, so this is the set
306
+ * the platform enforces. Same shape a field's members have. */
307
+ values?: EntityField["values"];
308
+ /** The shared enum this parameter names, when it names one. `values` is what to render. */
309
+ enum?: string;
304
310
  }
305
311
  export interface AssociationDisplay {
306
312
  name?: LocalizedString;