@nivaro/react 0.3.24 → 0.3.26

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 (27) hide show
  1. package/dist/hooks/useSessionRecorder.js +1 -1
  2. package/dist/index.d.ts +45 -26
  3. package/dist/shared/components/FilePreviewLightbox.js +56 -35
  4. package/dist/shared/components/ItemEditForm.js +4309 -4263
  5. package/dist/shared/components/PageRenderer.js +63 -62
  6. package/dist/shared/components/RecordReadView.js +229 -229
  7. package/dist/shared/components/ReportView.js +123 -120
  8. package/dist/shared/components/ai/AiMarkdown.js +168 -148
  9. package/dist/shared/components/chat/RoomParts.js +120 -119
  10. package/dist/shared/components/chat/chat-core.js +228 -224
  11. package/dist/shared/components/item-edit/FieldRenderer.js +333 -333
  12. package/dist/shared/components/item-edit/FieldRow.js +413 -394
  13. package/dist/shared/components/item-edit/GroupSection.js +637 -635
  14. package/dist/shared/components/item-edit/InlineGridField.js +89 -90
  15. package/dist/shared/components/item-edit/M2MCombobox.js +117 -116
  16. package/dist/shared/components/item-edit/QuickPicker.js +9 -9
  17. package/dist/shared/components/item-edit/RawEditSheet.js +80 -79
  18. package/dist/shared/components/item-edit/RelationCombobox.js +173 -167
  19. package/dist/shared/components/item-edit/RowMatchPanel.js +1 -1
  20. package/dist/shared/components/item-edit/m2m-invalidate.js +19 -0
  21. package/dist/shared/components/item-edit/record-lookups.js +15 -0
  22. package/dist/shared/components/item-edit/render-stability.js +147 -0
  23. package/dist/shared/components/layout-editor/FormMapButton.js +5 -4
  24. package/dist/shared/lib/picker-rank.js +21 -0
  25. package/dist/shared/lib/safe-href.js +10 -0
  26. package/dist/shared/lib/socket-realtime.js +107 -78
  27. package/package.json +6 -6
@@ -5,7 +5,7 @@ import { useMemo as O } from "react";
5
5
  import { get as V } from "../../lib/commands.js";
6
6
  import { evaluateNumeric as ee } from "../../lib/expression.js";
7
7
  import { cn as W } from "../../lib/utils.js";
8
- import "../../lib/field-interfaces.js";
8
+ import "./FieldRenderer.js";
9
9
  import { resolveOptionFilterTokens as te } from "../../lib/option-filter-tokens.js";
10
10
  const U = (t, e) => e.split(".").reduce(
11
11
  (a, s) => a && typeof a == "object" ? a[s] : void 0,
@@ -0,0 +1,19 @@
1
+ function r(t, i) {
2
+ const o = /* @__PURE__ */ new Set();
3
+ for (const e of i) o.add(String(e));
4
+ const n = (e) => e.length > 3 && o.has(String(e[3]));
5
+ t.invalidateQueries({ queryKey: ["m2m-items"], predicate: (e) => n(e.queryKey) }), t.invalidateQueries({
6
+ queryKey: ["m2m-items"],
7
+ predicate: (e) => !n(e.queryKey),
8
+ refetchType: "none"
9
+ });
10
+ }
11
+ function s(t) {
12
+ const i = [];
13
+ for (const o of t.values()) for (const n of o.keys()) i.push(String(n));
14
+ return i;
15
+ }
16
+ export {
17
+ s as editedRowIds,
18
+ r as invalidateM2MFor
19
+ };
@@ -0,0 +1,15 @@
1
+ const t = /* @__PURE__ */ new Map();
2
+ function r(o, e) {
3
+ if (t.delete(o), t.set(o, { role: e.role, state: e.state }), t.size > 200) {
4
+ const s = t.keys().next().value;
5
+ s !== void 0 && t.delete(s);
6
+ }
7
+ }
8
+ function n(o) {
9
+ const e = t.get(o);
10
+ return e && (e.role || e.state) ? e : null;
11
+ }
12
+ export {
13
+ n as recordLookupsFor,
14
+ r as rememberRecordLookups
15
+ };
@@ -0,0 +1,147 @@
1
+ import { useRef as S, useLayoutEffect as v, useMemo as a } from "react";
2
+ function C(e, t) {
3
+ if (Object.is(e, t)) return !0;
4
+ if (e == null || t == null || typeof e != "object" || typeof t != "object") return !1;
5
+ try {
6
+ return JSON.stringify(e) === JSON.stringify(t);
7
+ } catch {
8
+ return !1;
9
+ }
10
+ }
11
+ function E(e, t) {
12
+ if (Object.is(e, t)) return !0;
13
+ if (!e || !t) return !1;
14
+ const n = Object.keys(e);
15
+ if (n.length !== Object.keys(t).length) return !1;
16
+ for (const o of n) if (!Object.hasOwn(t, o) || !Object.is(e[o], t[o])) return !1;
17
+ return !0;
18
+ }
19
+ function b(e, t, n) {
20
+ const o = e.current;
21
+ return o !== void 0 && n(o, t) ? o : (e.current = t, t);
22
+ }
23
+ function j(e, t) {
24
+ const n = S(void 0);
25
+ return b(n, e, t);
26
+ }
27
+ function L(e, t) {
28
+ const n = Object.keys(e);
29
+ if (n.length !== Object.keys(t).length) return !1;
30
+ for (const o of n) {
31
+ const s = e[o], r = t[o];
32
+ if (!r || s.label !== r.label || s.count !== r.count) return !1;
33
+ }
34
+ return !0;
35
+ }
36
+ function T(e) {
37
+ const t = S(e);
38
+ v(() => {
39
+ t.current = e;
40
+ });
41
+ const n = a(
42
+ () => ({
43
+ dismissRemoteChange: (c) => t.current.dismissRemoteChange(c),
44
+ takeRemoteChange: (c) => {
45
+ var u, f;
46
+ return (f = (u = t.current).takeRemoteChange) == null ? void 0 : f.call(u, c);
47
+ },
48
+ onLockHover: () => {
49
+ var c, u;
50
+ return (u = (c = t.current).onLockHover) == null ? void 0 : u.call(c);
51
+ },
52
+ openRelated: (c, u) => {
53
+ var f, i;
54
+ return (i = (f = t.current).openRelated) == null ? void 0 : i.call(f, c, u);
55
+ }
56
+ }),
57
+ []
58
+ ), o = j(e.lockReasons, E), s = j(e.applyToLines, L), r = a(() => {
59
+ const c = {};
60
+ for (const [u, f] of Object.entries(s))
61
+ c[u] = {
62
+ ...f,
63
+ onApply: (i) => {
64
+ var d;
65
+ return (d = t.current.applyToLines[u]) == null ? void 0 : d.onApply(i);
66
+ }
67
+ };
68
+ return c;
69
+ }, [s]), l = !!e.takeRemoteChange, p = !!e.onLockHover, y = !!e.openRelated, { remoteChanges: h, layoutId: g, pickerMisses: k, fromAutofill: O, glossaryHelp: R, placementText: m } = e;
70
+ return a(
71
+ () => ({
72
+ remoteChanges: h,
73
+ dismissRemoteChange: n.dismissRemoteChange,
74
+ takeRemoteChange: l ? n.takeRemoteChange : void 0,
75
+ lockReasons: o,
76
+ onLockHover: p ? n.onLockHover : void 0,
77
+ applyToLines: r,
78
+ openRelated: y ? n.openRelated : void 0,
79
+ layoutId: g,
80
+ pickerMisses: k,
81
+ fromAutofill: O,
82
+ glossaryHelp: R,
83
+ placementText: m
84
+ }),
85
+ [
86
+ h,
87
+ n,
88
+ l,
89
+ o,
90
+ p,
91
+ r,
92
+ y,
93
+ g,
94
+ k,
95
+ O,
96
+ R,
97
+ m
98
+ ]
99
+ );
100
+ }
101
+ function q(e, t) {
102
+ if (e.size !== t.size) return !1;
103
+ for (const n of e) if (!t.has(n)) return !1;
104
+ return !0;
105
+ }
106
+ function A(e, t) {
107
+ if (e.length !== t.length) return !1;
108
+ for (let n = 0; n < e.length; n++) if (!Object.is(e[n], t[n])) return !1;
109
+ return !0;
110
+ }
111
+ const P = /* @__PURE__ */ new Set(["summaryFields", "swapConfig", "alternateWidths"]), w = /* @__PURE__ */ new Set(["onToggle", "onSwapToggle"]);
112
+ function N(e, t) {
113
+ const n = Object.keys(e);
114
+ if (n.length !== Object.keys(t).length) return !1;
115
+ for (const o of n) {
116
+ if (!Object.hasOwn(t, o)) return !1;
117
+ const s = e[o], r = t[o];
118
+ if (!Object.is(s, r)) {
119
+ if (w.has(o)) {
120
+ if (typeof s == "function" && typeof r == "function") continue;
121
+ return !1;
122
+ }
123
+ if (P.has(o)) {
124
+ if (C(s, r)) continue;
125
+ return !1;
126
+ }
127
+ if (s instanceof Set && r instanceof Set) {
128
+ if (q(s, r)) continue;
129
+ return !1;
130
+ }
131
+ if (Array.isArray(s) && Array.isArray(r)) {
132
+ if (A(s, r)) continue;
133
+ return !1;
134
+ }
135
+ return !1;
136
+ }
137
+ }
138
+ return !0;
139
+ }
140
+ export {
141
+ N as groupSectionPropsEqual,
142
+ C as jsonEqual,
143
+ b as keepIfEqual,
144
+ E as shallowRecordEqual,
145
+ j as useKeepIfEqual,
146
+ T as useStableFieldAffordances
147
+ };
@@ -55,9 +55,9 @@ function H({
55
55
  collection: i,
56
56
  onClose: c
57
57
  }) {
58
- const a = L(i), l = j(i), d = B(!0), t = a.data, n = l.data ?? [], s = d.data ?? [], p = a.isError || l.isError || d.isError, k = () => {
58
+ const a = L(i), l = j(i), d = B(!0), t = a.data, n = l.data ?? [], s = d.data ?? [], p = a.isError || l.isError || d.isError, w = () => {
59
59
  a.isError && a.refetch(), l.isError && l.refetch(), d.isError && d.refetch();
60
- }, u = f(null), h = f(null), w = F(() => {
60
+ }, u = f(null), h = f(null), k = F(() => {
61
61
  const r = D({
62
62
  bundle: o,
63
63
  collectionLabel: (t == null ? void 0 : t.label) || i,
@@ -119,14 +119,15 @@ function H({
119
119
  }
120
120
  )
121
121
  ] }),
122
- /* @__PURE__ */ e("div", { className: "min-h-0 flex-1 overflow-hidden p-4 sm:p-6", children: p ? /* @__PURE__ */ e("div", { className: "mx-auto max-w-[900px] rounded-md border border-slate-200 bg-white p-4 dark:border-border dark:bg-card", children: /* @__PURE__ */ e(R, { what: "the field labels and roles for the map", onRetry: k }) }) : (
122
+ /* @__PURE__ */ e("div", { className: "min-h-0 flex-1 overflow-hidden p-4 sm:p-6", children: p ? /* @__PURE__ */ e("div", { className: "mx-auto max-w-[900px] rounded-md border border-slate-200 bg-white p-4 dark:border-border dark:bg-card", children: /* @__PURE__ */ e(R, { what: "the field labels and roles for the map", onRetry: w }) }) : (
123
123
  // The page itself is always light: it is paper.
124
124
  /* @__PURE__ */ e(
125
125
  "iframe",
126
126
  {
127
127
  ref: u,
128
128
  title: "Form map preview",
129
- srcDoc: w,
129
+ srcDoc: k,
130
+ sandbox: "allow-same-origin allow-modals",
130
131
  "data-form-map-frame": "",
131
132
  className: "mx-auto block h-full w-full max-w-[900px] rounded-md border border-slate-300 bg-white shadow-lg dark:border-border"
132
133
  }
@@ -0,0 +1,21 @@
1
+ const i = (r) => r.toLocaleLowerCase().replace(/\s+/g, " ").trim();
2
+ function s(r, o) {
3
+ const t = i(o);
4
+ if (!t) return 4;
5
+ const e = i(r);
6
+ if (e === t) return 0;
7
+ if (e.startsWith(t)) return 1;
8
+ const n = e.split(/[\s,.;:()/\-_@]+/).filter(Boolean);
9
+ return t.split(" ").every((c) => n.some((f) => f.startsWith(c))) ? 2 : e.includes(t) ? 3 : 4;
10
+ }
11
+ function l(r, o, t, e = !1) {
12
+ if (t.trim()) {
13
+ const n = s(r, t) - s(o, t);
14
+ if (n) return n;
15
+ }
16
+ return e ? o.localeCompare(r) : r.localeCompare(o);
17
+ }
18
+ export {
19
+ l as compareByMatch,
20
+ s as pickerMatchTier
21
+ };
@@ -0,0 +1,10 @@
1
+ function n(t) {
2
+ return /^\/(?![/\\])/.test(t) && !/[\s\\]/.test(t);
3
+ }
4
+ function e(t) {
5
+ return /^https?:\/\/\S+$/i.test(t) ? "external" : n(t) ? "internal" : null;
6
+ }
7
+ export {
8
+ n as isInAppPath,
9
+ e as safeLinkKind
10
+ };
@@ -1,11 +1,32 @@
1
- var N = Object.defineProperty;
2
- var U = (i, n, r) => n in i ? N(i, n, { enumerable: !0, configurable: !0, writable: !0, value: r }) : i[n] = r;
3
- var _ = (i, n, r) => U(i, typeof n != "symbol" ? n + "" : n, r);
4
- import { bindClientChaosSocket as k } from "./client-chaos.js";
5
- import { deliveryAckFor as L } from "./delivery-ack.js";
6
- import { forgetSettledReads as y } from "./request-gate.js";
7
- import { createRoomGapTracker as M, refetchEventsFor as W } from "./room-gaps.js";
8
- const p = {
1
+ var y = Object.defineProperty;
2
+ var I = (i, n, r) => n in i ? y(i, n, { enumerable: !0, configurable: !0, writable: !0, value: r }) : i[n] = r;
3
+ var N = (i, n, r) => I(i, typeof n != "symbol" ? n + "" : n, r);
4
+ import { bindClientChaosSocket as J } from "./client-chaos.js";
5
+ import { deliveryAckFor as O } from "./delivery-ack.js";
6
+ import { forgetSettledReads as L } from "./request-gate.js";
7
+ import { createRoomGapTracker as W, refetchEventsFor as $ } from "./room-gaps.js";
8
+ const U = 3e3;
9
+ function x(i = U) {
10
+ const n = /* @__PURE__ */ new Map();
11
+ return (r, d) => {
12
+ var g;
13
+ if (!(i > 0)) {
14
+ d();
15
+ return;
16
+ }
17
+ const a = n.has(r);
18
+ if (n.set(r, d), a) return;
19
+ const l = setTimeout(
20
+ () => {
21
+ const f = n.get(r);
22
+ n.delete(r), f == null || f();
23
+ },
24
+ Math.floor(Math.random() * i)
25
+ );
26
+ (g = l.unref) == null || g.call(l);
27
+ };
28
+ }
29
+ const j = {
9
30
  catchupFull: "nvr:catchup-full",
10
31
  accessChanged: "nvr:access-changed",
11
32
  configUpdate: "nvr:config-update",
@@ -13,7 +34,7 @@ const p = {
13
34
  };
14
35
  class C {
15
36
  constructor(n, r) {
16
- _(this, "refs", /* @__PURE__ */ new Map());
37
+ N(this, "refs", /* @__PURE__ */ new Map());
17
38
  this.join = n, this.leave = r;
18
39
  }
19
40
  add(n) {
@@ -31,154 +52,162 @@ class C {
31
52
  return [...this.refs.keys()];
32
53
  }
33
54
  }
34
- function G(i) {
35
- let n = null, r = 0, j = !1, l = null, a = { state: "live", transport: null, refreshed: null, resumed: null };
36
- const T = /* @__PURE__ */ new Set(), v = (e) => {
55
+ function z(i) {
56
+ let n = null, r = 0, d = !1, a = null, l = { state: "live", transport: null, refreshed: null, resumed: null };
57
+ const g = /* @__PURE__ */ new Set(), f = (e) => {
37
58
  var o;
38
59
  return ((o = i.windowEvents) == null ? void 0 : o[e]) !== !1;
39
- }, g = (e) => {
40
- const o = { ...a, ...e };
41
- if (!(o.state === a.state && o.transport === a.transport && o.refreshed === a.refreshed && o.resumed === a.resumed)) {
42
- a = o;
43
- for (const t of T) t(a);
60
+ }, b = x(i.reactionJitterMs ?? U), A = /* @__PURE__ */ new Set(), p = (e) => {
61
+ const o = { ...l, ...e };
62
+ if (!(o.state === l.state && o.transport === l.transport && o.refreshed === l.refreshed && o.resumed === l.resumed)) {
63
+ l = o;
64
+ for (const t of g) t(l);
44
65
  }
45
- }, R = () => {
66
+ }, _ = () => {
46
67
  var e, o, t;
47
68
  return ((t = (o = (e = n == null ? void 0 : n.io) == null ? void 0 : e.engine) == null ? void 0 : o.transport) == null ? void 0 : t.name) ?? null;
48
- }, b = (e, o) => {
49
- l && clearTimeout(l), l = null, g({ state: "live", transport: R(), refreshed: e, resumed: o });
50
- }, u = (e, o) => {
51
- typeof window > "u" || window.dispatchEvent(new CustomEvent(e, { detail: o }));
69
+ }, E = (e, o) => {
70
+ a && clearTimeout(a), a = null, p({ state: "live", transport: _(), refreshed: e, resumed: o });
52
71
  }, h = (e, o) => {
72
+ typeof window > "u" || window.dispatchEvent(new CustomEvent(e, { detail: o }));
73
+ }, m = (e, o) => {
53
74
  n != null && n.connected && n.emit(e, o);
54
- }, E = (e, o) => {
75
+ }, F = (e, o) => {
55
76
  var t;
56
77
  for (const s of ((t = n == null ? void 0 : n.listeners) == null ? void 0 : t.call(n, e)) ?? []) s(o);
57
- }, F = (e) => {
58
- for (const o of W(e)) E(o.event, o.payload);
59
- u("nvr:realtime-stale", { rooms: e });
60
- }, m = M({
61
- request: (e) => h("catchup:room", e),
62
- dispatch: E,
63
- refetch: F
64
- }), q = new C(
78
+ }, M = (e) => {
79
+ for (const o of $(e)) F(o.event, o.payload);
80
+ h("nvr:realtime-stale", { rooms: e });
81
+ }, w = W({
82
+ request: (e) => m("catchup:room", e),
83
+ dispatch: F,
84
+ refetch: M
85
+ }), R = new C(
65
86
  (e) => {
66
- m.reset([`collection:${e}`]), h("collection:join", { collection: e });
87
+ w.reset([`collection:${e}`]), m("collection:join", { collection: e });
67
88
  },
68
89
  (e) => {
69
- m.reset([`collection:${e}`]), h("collection:leave", { collection: e });
90
+ w.reset([`collection:${e}`]), m("collection:leave", { collection: e });
70
91
  }
71
- ), A = new C(
92
+ ), S = new C(
72
93
  // The Traffic Map page reads batched frames (api traffic-map-batch.ts); twin: admin
73
94
  // lib/socket.ts watchJoinPayload.
74
- (e) => h("admin:join", e === "traffic-map" ? { room: e, frames: "batch" } : { room: e }),
75
- (e) => h("admin:leave", { room: e })
76
- ), S = new C(
77
- (e) => h("ops:join", { topic: e }),
78
- (e) => h("ops:leave", { topic: e })
79
- ), w = () => {
95
+ (e) => m("admin:join", e === "traffic-map" ? { room: e, frames: "batch" } : { room: e }),
96
+ (e) => m("admin:leave", { room: e })
97
+ ), q = new C(
98
+ (e) => m("ops:join", { topic: e }),
99
+ (e) => m("ops:leave", { topic: e })
100
+ ), T = () => {
80
101
  var o;
81
102
  if (n) return n;
82
103
  const e = typeof i.socket == "function" ? i.socket() : i.socket;
83
- return n = e, k(e), j = e.connected, e.on("auth:ok", () => {
84
- if (m.reset(), q.rejoinAll(), A.rejoinAll(), S.rejoinAll(), j && r > 0) {
104
+ return n = e, J(e), d = e.connected, e.on("auth:ok", () => {
105
+ if (w.reset(), R.rejoinAll(), S.rejoinAll(), q.rejoinAll(), d && r > 0) {
85
106
  const t = r;
86
- g({ transport: R() }), l && clearTimeout(l), l = setTimeout(() => b(null, "unverified"), i.catchupTimeoutMs ?? 8e3), e.emit("catchup", { cursor: t });
107
+ p({ transport: _() }), a && clearTimeout(a), a = setTimeout(() => E(null, "unverified"), i.catchupTimeoutMs ?? 8e3), e.emit("catchup", { cursor: t });
87
108
  } else
88
- g({
109
+ p({
89
110
  state: "live",
90
- transport: R(),
111
+ transport: _(),
91
112
  refreshed: null,
92
- resumed: j && a.state === "reconnecting" ? "unverified" : null
113
+ resumed: d && l.state === "reconnecting" ? "unverified" : null
93
114
  });
94
- j = !0;
115
+ d = !0;
95
116
  }), e.on("catchup:cursor", (t) => {
96
117
  r === 0 && typeof (t == null ? void 0 : t.seq) == "number" && t.seq > 0 && (r = t.seq);
97
118
  }), e.on("disconnect", () => {
98
- l && clearTimeout(l), l = null, g({ state: "reconnecting", refreshed: null });
99
- }), e.on("connect_error", () => g({ state: "reconnecting", refreshed: null })), (o = e.onAny) == null || o.call(e, (t, s) => {
119
+ a && clearTimeout(a), a = null, p({ state: "reconnecting", refreshed: null });
120
+ }), e.on("connect_error", () => p({ state: "reconnecting", refreshed: null })), (o = e.onAny) == null || o.call(e, (t, s) => {
100
121
  const c = s == null ? void 0 : s._seq;
101
- typeof c == "number" && c > r && (r = c), m.observe(s);
102
- const d = L(s);
103
- d && e.emit("rt:ack", d);
104
- }), e.on("catchup:room:events", (t) => m.replayed(t)), e.on("realtime:stale", (t) => {
122
+ typeof c == "number" && c > r && (r = c), w.observe(s);
123
+ const v = O(s);
124
+ v && e.emit("rt:ack", v);
125
+ }), e.on("catchup:room:events", (t) => w.replayed(t)), e.on("realtime:stale", (t) => {
105
126
  const s = Array.isArray(t == null ? void 0 : t.rooms) ? t.rooms.filter((c) => typeof c == "string") : [];
106
- m.reset(s), t != null && t.all ? (v("catchupFull") && u(p.catchupFull, {}), u("nvr:realtime-stale", { rooms: s, all: !0 })) : s.length && F(s);
127
+ w.reset(s), t != null && t.all ? (f("catchupFull") && h(j.catchupFull, {}), h("nvr:realtime-stale", { rooms: s, all: !0 })) : s.length && M(s);
107
128
  }), e.on(
108
129
  "catchup:events",
109
130
  (t) => {
110
131
  var s;
111
132
  for (const c of (t == null ? void 0 : t.events) ?? []) {
112
133
  c.seq > r && (r = c.seq);
113
- for (const d of ((s = e.listeners) == null ? void 0 : s.call(e, c.event)) ?? []) d({ ...c.payload, _seq: c.seq });
134
+ for (const v of ((s = e.listeners) == null ? void 0 : s.call(e, c.event)) ?? []) v({ ...c.payload, _seq: c.seq });
114
135
  }
115
- b(null, "replayed");
136
+ E(null, "replayed");
116
137
  }
117
138
  ), e.on("catchup:full", (t) => {
118
- v("catchupFull") && u(p.catchupFull, {}), b(
139
+ f("catchupFull") && b("full", () => h(j.catchupFull, {})), E(
119
140
  (t == null ? void 0 : t.reason) === "slow-consumer" ? "Live updates resumed. This tab fell too far behind to send each change, so the lists and records on this page were reloaded." : "Live updates resumed. The connection was gone too long to replay each change, so the lists and records on this page were reloaded.",
120
141
  "reloaded"
121
142
  );
122
143
  }), e.on("access:changed", (t) => {
123
144
  var s;
124
- y(), (s = t == null ? void 0 : t.rooms_left) != null && s.length && v("accessChanged") && u(p.accessChanged, t);
145
+ if (L(), (s = t == null ? void 0 : t.rooms_left) != null && s.length && f("accessChanged")) {
146
+ for (const c of t.rooms_left) A.add(c);
147
+ b("access", () => {
148
+ const c = [...A];
149
+ A.clear(), h(j.accessChanged, { rooms_left: c });
150
+ });
151
+ }
125
152
  }), e.on("config:update", (t) => {
126
- y(), v("configUpdate") && u(p.configUpdate, t ?? {});
153
+ L(), f("configUpdate") && h(j.configUpdate, t ?? {});
127
154
  }), e.on("client:force-refresh", (t) => {
128
- v("forceRefresh") && u(p.forceRefresh, t ?? {});
155
+ f("forceRefresh") && h(j.forceRefresh, t ?? {});
129
156
  }), e;
130
157
  };
131
158
  return {
132
159
  subscribeCollections(e, o) {
133
- const t = w(), s = [...new Set(e.filter(Boolean))];
134
- for (const f of s) q.add(f);
135
- const c = (f) => {
136
- f != null && f.collection && s.includes(f.collection) && o(f);
160
+ const t = T(), s = [...new Set(e.filter(Boolean))];
161
+ for (const u of s) R.add(u);
162
+ const c = (u) => {
163
+ u != null && u.collection && s.includes(u.collection) && o(u);
137
164
  };
138
165
  t.on("collection:update", c);
139
- let d = !1;
166
+ let v = !1;
140
167
  return () => {
141
- if (!d) {
142
- d = !0, t.off("collection:update", c);
143
- for (const f of s) q.remove(f);
168
+ if (!v) {
169
+ v = !0, t.off("collection:update", c);
170
+ for (const u of s) R.remove(u);
144
171
  }
145
172
  };
146
173
  },
147
174
  on(e, o) {
148
- const t = w();
175
+ const t = T();
149
176
  return t.on(e, o), () => {
150
177
  t.off(e, o);
151
178
  };
152
179
  },
153
180
  emit(e, o) {
154
- if (w(), e === "ops:join" || e === "ops:leave") {
181
+ if (T(), e === "ops:join" || e === "ops:leave") {
155
182
  const t = String((o == null ? void 0 : o.topic) ?? "");
156
183
  if (!t) return;
157
- e === "ops:join" ? S.add(t) : S.remove(t);
184
+ e === "ops:join" ? q.add(t) : q.remove(t);
158
185
  return;
159
186
  }
160
187
  n == null || n.emit(e, o);
161
188
  },
162
189
  status() {
163
- return a;
190
+ return l;
164
191
  },
165
192
  onStatus(e) {
166
- return w(), T.add(e), () => {
167
- T.delete(e);
193
+ return T(), g.add(e), () => {
194
+ g.delete(e);
168
195
  };
169
196
  },
170
197
  joinWatch(e) {
171
- w(), A.add(e);
198
+ T(), S.add(e);
172
199
  let o = !1;
173
200
  return () => {
174
- o || (o = !0, A.remove(e));
201
+ o || (o = !0, S.remove(e));
175
202
  };
176
203
  },
177
204
  held() {
178
- return { collections: q.keys(), watch: A.keys(), ops: S.keys() };
205
+ return { collections: R.keys(), watch: S.keys(), ops: q.keys() };
179
206
  }
180
207
  };
181
208
  }
182
209
  export {
183
- G as createSocketRealtime
210
+ U as REACTION_JITTER_MS,
211
+ x as createJitteredReaction,
212
+ z as createSocketRealtime
184
213
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nivaro/react",
3
- "version": "0.3.24",
3
+ "version": "0.3.26",
4
4
  "description": "React hooks and components for Nivaro CMS forms",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -77,11 +77,11 @@
77
77
  "@radix-ui/react-switch": "^1.2.6",
78
78
  "@radix-ui/react-tabs": "^1.1.14",
79
79
  "@radix-ui/react-tooltip": "^1.2.7",
80
- "@tiptap/extension-link": "^3.26.0",
81
- "@tiptap/extension-placeholder": "^3.26.0",
82
- "@tiptap/extension-underline": "^3.26.0",
83
- "@tiptap/react": "^3.26.0",
84
- "@tiptap/starter-kit": "^3.26.0",
80
+ "@tiptap/extension-link": "^3.32.0",
81
+ "@tiptap/extension-placeholder": "^3.32.0",
82
+ "@tiptap/extension-underline": "^3.32.0",
83
+ "@tiptap/react": "^3.32.0",
84
+ "@tiptap/starter-kit": "^3.32.0",
85
85
  "class-variance-authority": "^0.7.0",
86
86
  "clsx": "^2.0.0",
87
87
  "cmdk": "^1.0.0",