@chelone/core 0.6.0 → 0.9.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 (255) hide show
  1. package/dist/assistant/assistant-session.d.ts +6 -0
  2. package/dist/assistant/assistant-session.js +204 -181
  3. package/dist/assistant/echo-transport.js +26 -29
  4. package/dist/assistant/http-transport.d.ts +10 -0
  5. package/dist/assistant/http-transport.js +98 -0
  6. package/dist/assistant/types.d.ts +1 -7
  7. package/dist/auth/access-control.d.ts +13 -5
  8. package/dist/auth/access-control.js +25 -21
  9. package/dist/auth/auth-options.d.ts +23 -17
  10. package/dist/auth/auth-options.js +82 -48
  11. package/dist/auth/permission-matrix.d.ts +12 -0
  12. package/dist/auth/permission-matrix.js +67 -0
  13. package/dist/auth/types.d.ts +14 -4
  14. package/dist/block-editor/block-document.d.ts +64 -0
  15. package/dist/block-editor/block-document.js +147 -0
  16. package/dist/block-editor/data-blocks.d.ts +63 -0
  17. package/dist/block-editor/data-blocks.js +117 -0
  18. package/dist/chart/chart-data.js +46 -44
  19. package/dist/command-menu/hotkey.js +58 -47
  20. package/dist/command-menu/recents.d.ts +4 -0
  21. package/dist/command-menu/recents.js +12 -11
  22. package/dist/command-menu/registry.d.ts +9 -5
  23. package/dist/command-menu/registry.js +36 -46
  24. package/dist/controller/calendar-dates.d.ts +12 -0
  25. package/dist/controller/calendar-dates.js +94 -113
  26. package/dist/controller/calendar-events.js +93 -88
  27. package/dist/controller/client-list-controller.d.ts +2 -2
  28. package/dist/controller/client-list-controller.js +251 -254
  29. package/dist/controller/data-table-columns.d.ts +2 -0
  30. package/dist/controller/data-table-columns.js +50 -56
  31. package/dist/controller/deep-equal.d.ts +1 -0
  32. package/dist/controller/deep-equal.js +14 -0
  33. package/dist/controller/filter-toggle.js +36 -44
  34. package/dist/controller/in-place-editor.d.ts +43 -0
  35. package/dist/controller/in-place-editor.js +43 -0
  36. package/dist/controller/infinite-list-controller.js +219 -189
  37. package/dist/controller/inspector.d.ts +55 -0
  38. package/dist/controller/inspector.js +70 -0
  39. package/dist/controller/job-monitor.d.ts +10 -4
  40. package/dist/controller/job-monitor.js +46 -47
  41. package/dist/controller/kanban-board.js +45 -24
  42. package/dist/controller/list-controller.d.ts +8 -5
  43. package/dist/controller/list-controller.js +447 -400
  44. package/dist/controller/list-params.js +96 -87
  45. package/dist/controller/pivot-grid.d.ts +4 -4
  46. package/dist/controller/pivot-grid.js +89 -95
  47. package/dist/controller/prev-next.d.ts +2 -2
  48. package/dist/controller/prev-next.js +74 -54
  49. package/dist/controller/record-controllers.d.ts +14 -6
  50. package/dist/controller/record-controllers.js +288 -257
  51. package/dist/controller/record-diff.d.ts +21 -0
  52. package/dist/controller/record-diff.js +50 -0
  53. package/dist/controller/record-timeline.d.ts +5 -5
  54. package/dist/controller/record-timeline.js +42 -30
  55. package/dist/controller/record-tree.js +57 -47
  56. package/dist/controller/record-workflow.d.ts +38 -16
  57. package/dist/controller/record-workflow.js +85 -64
  58. package/dist/controller/reference-many-controller.d.ts +2 -0
  59. package/dist/controller/reference-many-controller.js +199 -192
  60. package/dist/controller/reference-one-controller.d.ts +1 -1
  61. package/dist/controller/reference-one-controller.js +63 -56
  62. package/dist/controller/saved-queries.js +104 -91
  63. package/dist/controller/translate-fallback.js +10 -6
  64. package/dist/csv/export.d.ts +4 -3
  65. package/dist/csv/export.js +43 -40
  66. package/dist/csv/import-controller.d.ts +4 -0
  67. package/dist/csv/import-controller.js +189 -169
  68. package/dist/csv/match-headers.js +29 -22
  69. package/dist/csv/parse-with.js +60 -54
  70. package/dist/csv/run-import.js +69 -72
  71. package/dist/csv/validate-rows.d.ts +1 -1
  72. package/dist/csv/validate-rows.js +65 -52
  73. package/dist/data/cache-ops.d.ts +5 -4
  74. package/dist/data/cache-ops.js +208 -188
  75. package/dist/data/combine-data-providers.js +25 -23
  76. package/dist/data/data-provider-log.d.ts +45 -0
  77. package/dist/data/data-provider-log.js +93 -0
  78. package/dist/data/errors.js +14 -10
  79. package/dist/data/fake-provider.d.ts +6 -3
  80. package/dist/data/fake-provider.js +135 -114
  81. package/dist/data/fetch-utils.js +61 -44
  82. package/dist/data/filter-branch.d.ts +5 -0
  83. package/dist/data/filter-branch.js +10 -0
  84. package/dist/data/get-many-aggregate.js +84 -76
  85. package/dist/data/http-error.js +17 -12
  86. package/dist/data/keys.js +50 -36
  87. package/dist/data/mutation-options.d.ts +14 -9
  88. package/dist/data/mutation-options.js +93 -109
  89. package/dist/data/query-options.js +73 -68
  90. package/dist/data/remove-empty.d.ts +3 -0
  91. package/dist/data/remove-empty.js +11 -0
  92. package/dist/data/undoable.d.ts +2 -2
  93. package/dist/data/undoable.js +190 -174
  94. package/dist/data/with-lifecycle-callbacks.d.ts +45 -17
  95. package/dist/data/with-lifecycle-callbacks.js +66 -52
  96. package/dist/environment/application-update-store.js +58 -55
  97. package/dist/environment/offline-store.js +21 -21
  98. package/dist/form/array-binding.d.ts +30 -11
  99. package/dist/form/array-binding.js +184 -166
  100. package/dist/form/choice-ids.d.ts +7 -0
  101. package/dist/form/choice-ids.js +11 -0
  102. package/dist/form/choices-controller.d.ts +22 -2
  103. package/dist/form/choices-controller.js +315 -275
  104. package/dist/form/date-format.d.ts +38 -0
  105. package/dist/form/date-format.js +89 -0
  106. package/dist/form/dirty-values.d.ts +2 -2
  107. package/dist/form/dirty-values.js +22 -11
  108. package/dist/form/duration.d.ts +22 -0
  109. package/dist/form/duration.js +49 -0
  110. package/dist/form/edit-create-form.d.ts +12 -5
  111. package/dist/form/edit-create-form.js +243 -188
  112. package/dist/form/event-value.d.ts +6 -0
  113. package/dist/form/event-value.js +17 -0
  114. package/dist/form/field-error.d.ts +14 -0
  115. package/dist/form/field-error.js +28 -0
  116. package/dist/form/field-name.d.ts +20 -0
  117. package/dist/form/field-name.js +6 -0
  118. package/dist/form/filter-form-values.js +63 -49
  119. package/dist/form/form-controller.d.ts +9 -1
  120. package/dist/form/form-controller.js +165 -160
  121. package/dist/form/form-groups.d.ts +4 -3
  122. package/dist/form/form-groups.js +79 -79
  123. package/dist/form/form-handle.d.ts +175 -0
  124. package/dist/form/form-handle.js +68 -0
  125. package/dist/form/input-binding.d.ts +56 -31
  126. package/dist/form/input-binding.js +171 -118
  127. package/dist/form/input-values.d.ts +140 -0
  128. package/dist/form/input-values.js +206 -0
  129. package/dist/form/json-text.d.ts +11 -0
  130. package/dist/form/json-text.js +62 -37
  131. package/dist/form/save-pipeline.d.ts +6 -8
  132. package/dist/form/save-pipeline.js +91 -82
  133. package/dist/form/set-form-values.d.ts +6 -0
  134. package/dist/form/set-form-values.js +10 -0
  135. package/dist/form/source.js +97 -65
  136. package/dist/form/text-of.d.ts +2 -0
  137. package/dist/form/text-of.js +7 -0
  138. package/dist/form/validators.d.ts +58 -19
  139. package/dist/form/validators.js +97 -71
  140. package/dist/geo/bbox.d.ts +5 -4
  141. package/dist/geo/bbox.js +69 -48
  142. package/dist/geo/bounds.d.ts +14 -3
  143. package/dist/geo/bounds.js +98 -68
  144. package/dist/geo/constraints.js +88 -93
  145. package/dist/geo/coordinates.d.ts +10 -0
  146. package/dist/geo/coordinates.js +44 -23
  147. package/dist/geo/editor.d.ts +13 -13
  148. package/dist/geo/editor.js +176 -153
  149. package/dist/geo/geocoding.d.ts +4 -4
  150. package/dist/geo/geocoding.js +38 -41
  151. package/dist/geo/geojson.d.ts +12 -74
  152. package/dist/geo/geojson.js +52 -40
  153. package/dist/geo/geometry-math.d.ts +4 -4
  154. package/dist/geo/geometry-math.js +100 -93
  155. package/dist/geo/index.d.ts +9 -8
  156. package/dist/geo/map-layers.d.ts +42 -7
  157. package/dist/geo/map-layers.js +88 -62
  158. package/dist/geo/map-style.d.ts +12 -0
  159. package/dist/geo/map-style.js +43 -32
  160. package/dist/geo/messages.js +48 -45
  161. package/dist/geo/nominatim.js +88 -80
  162. package/dist/geo/osm-presets.d.ts +4 -3
  163. package/dist/geo/osm-presets.js +108 -86
  164. package/dist/geo/osm-tags.js +14 -12
  165. package/dist/geo/overpass.d.ts +14 -2
  166. package/dist/geo/overpass.js +83 -90
  167. package/dist/geo/shape-value.d.ts +9 -5
  168. package/dist/geo/shape-value.js +169 -146
  169. package/dist/geo/snap-to-roads.d.ts +3 -3
  170. package/dist/geo/snap-to-roads.js +55 -50
  171. package/dist/geo/throttle.js +36 -39
  172. package/dist/guards.d.ts +44 -0
  173. package/dist/guards.js +77 -0
  174. package/dist/i18n/default-messages.js +34 -29
  175. package/dist/i18n/english-messages.d.ts +172 -0
  176. package/dist/i18n/english-messages.js +359 -189
  177. package/dist/i18n/i18n.d.ts +2 -2
  178. package/dist/i18n/i18n.js +47 -60
  179. package/dist/i18n/inflection.d.ts +34 -0
  180. package/dist/i18n/inflection.js +82 -0
  181. package/dist/i18n/messages.d.ts +10 -2
  182. package/dist/i18n/messages.js +17 -4
  183. package/dist/i18n/missing-keys.d.ts +4 -0
  184. package/dist/i18n/missing-keys.js +70 -62
  185. package/dist/i18n/translatable.d.ts +16 -1
  186. package/dist/i18n/translatable.js +40 -47
  187. package/dist/index.d.ts +87 -39
  188. package/dist/index.js +54 -301
  189. package/dist/json/deep-equal.d.ts +8 -0
  190. package/dist/json/deep-equal.js +24 -0
  191. package/dist/json/strip-json-comments.js +38 -42
  192. package/dist/noop.d.ts +2 -0
  193. package/dist/noop.js +4 -0
  194. package/dist/notification/error-message.d.ts +2 -0
  195. package/dist/notification/error-message.js +10 -0
  196. package/dist/notification/notification-store.d.ts +3 -2
  197. package/dist/notification/notification-store.js +41 -45
  198. package/dist/onboarding-tour/placement.d.ts +2 -0
  199. package/dist/onboarding-tour/placement.js +65 -78
  200. package/dist/onboarding-tour/tour-controller.js +46 -54
  201. package/dist/realtime/add-events-for-mutations.js +75 -81
  202. package/dist/realtime/announce-lock.js +16 -13
  203. package/dist/realtime/broadcast-channel-transport.js +65 -59
  204. package/dist/realtime/copy-members.js +22 -14
  205. package/dist/realtime/in-memory-lock-provider.js +40 -48
  206. package/dist/realtime/live.js +95 -101
  207. package/dist/realtime/lock-options.js +16 -16
  208. package/dist/realtime/lock-session.js +91 -78
  209. package/dist/realtime/memory-transport.js +25 -25
  210. package/dist/realtime/presence.js +120 -122
  211. package/dist/realtime/realtime-data-provider.d.ts +10 -0
  212. package/dist/realtime/realtime-data-provider.js +45 -42
  213. package/dist/realtime/reconnect-backoff.js +17 -0
  214. package/dist/realtime/sse-transport.d.ts +31 -0
  215. package/dist/realtime/sse-transport.js +235 -0
  216. package/dist/realtime/status-store.js +23 -28
  217. package/dist/realtime/topic-hub.js +62 -71
  218. package/dist/realtime/topics.js +10 -12
  219. package/dist/realtime/types.js +10 -12
  220. package/dist/realtime/unread-count.js +21 -21
  221. package/dist/realtime/websocket-transport.d.ts +32 -0
  222. package/dist/realtime/websocket-transport.js +306 -0
  223. package/dist/resource/describe-resource.d.ts +2 -0
  224. package/dist/resource/describe-resource.js +247 -219
  225. package/dist/resource/get-at-path.js +29 -14
  226. package/dist/resource/identifier.d.ts +18 -0
  227. package/dist/resource/identifier.js +27 -0
  228. package/dist/resource/record.d.ts +4 -0
  229. package/dist/resource/record.js +10 -0
  230. package/dist/resource/register.d.ts +7 -0
  231. package/dist/resource/registry-store.d.ts +45 -15
  232. package/dist/resource/registry-store.js +67 -60
  233. package/dist/resource/registry.d.ts +10 -0
  234. package/dist/resource/registry.js +8 -4
  235. package/dist/resource/source-path.d.ts +23 -2
  236. package/dist/rich-text/rich-text-extras.d.ts +134 -0
  237. package/dist/rich-text/rich-text-extras.js +181 -0
  238. package/dist/rich-text/rich-text-image.d.ts +124 -0
  239. package/dist/rich-text/rich-text-image.js +163 -0
  240. package/dist/rich-text/rich-text.d.ts +6 -0
  241. package/dist/rich-text/rich-text.js +125 -88
  242. package/dist/router/location.d.ts +24 -4
  243. package/dist/router/location.js +43 -18
  244. package/dist/router/match.js +47 -39
  245. package/dist/router/paths.js +40 -34
  246. package/dist/router/record-from-location.d.ts +1 -1
  247. package/dist/router/record-from-location.js +25 -17
  248. package/dist/store/adapters.js +51 -55
  249. package/dist/store/micro-store.js +57 -59
  250. package/dist/store/shallow-equal.d.ts +12 -0
  251. package/dist/store/shallow-equal.js +20 -0
  252. package/dist/store/store.js +54 -57
  253. package/dist/ui-defaults.d.ts +15 -0
  254. package/dist/ui-defaults.js +17 -0
  255. package/package.json +13 -11
@@ -0,0 +1,306 @@
1
+ import { reconnectDelay, resolveReconnectConfig } from "./reconnect-backoff.js";
2
+ import { createTopicHub } from "./topic-hub.js";
3
+ // src/realtime/websocket-transport.ts
4
+ var isObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
5
+ function isServerFrame(value) {
6
+ if (!isObject(value)) return false;
7
+ if (!("topic" in value) || typeof value.topic !== "string") return false;
8
+ if (!("type" in value) || typeof value.type !== "string") return false;
9
+ return !("meta" in value) || value.meta === void 0 || isObject(value.meta);
10
+ }
11
+ var isPong = (value) => isObject(value) && "op" in value && value.op === "pong";
12
+ function parseFrame(data) {
13
+ try {
14
+ if (typeof data !== "string") throw new Error("frame is not text");
15
+ const frame = JSON.parse(data);
16
+ if (isPong(frame)) return { kind: "pong" };
17
+ if (isServerFrame(frame)) return {
18
+ kind: "event",
19
+ event: frame
20
+ };
21
+ throw new Error("frame is not a realtime event");
22
+ } catch (cause) {
23
+ return {
24
+ kind: "invalid",
25
+ cause: cause instanceof Error ? cause : /* @__PURE__ */ new Error("frame is invalid")
26
+ };
27
+ }
28
+ }
29
+ /** Carries realtime events over one WebSocket and reconnects with backoff. */
30
+ function webSocketTransport({ url, protocols = [], getAuthToken, authMode = "query", reconnect, idleDisconnectMs = 3e4, heartbeatMs = 3e4, onError }) {
31
+ const hub = createTopicHub({ onError });
32
+ const backoff = resolveReconnectConfig(reconnect);
33
+ hub.setStatus("idle");
34
+ let connection = null;
35
+ let connecting = false;
36
+ let epoch = 0;
37
+ let attempt = 0;
38
+ let lostConnection = false;
39
+ let retryTimer;
40
+ let idleTimer;
41
+ let heartbeatTimer;
42
+ let queue = [];
43
+ const setStatus = (status) => {
44
+ if (hub.getStatus() !== status) hub.setStatus(status);
45
+ };
46
+ const rejectQueue = (reason) => {
47
+ const rejected = queue;
48
+ queue = [];
49
+ for (const publish of rejected) publish.reject(reason);
50
+ };
51
+ const send = (target, frame, topic) => {
52
+ try {
53
+ target.socket.send(JSON.stringify(frame));
54
+ return null;
55
+ } catch (cause) {
56
+ hub.report({
57
+ kind: "send_failed",
58
+ topic,
59
+ cause,
60
+ retrying: false
61
+ });
62
+ return cause instanceof Error ? cause : /* @__PURE__ */ new Error("send failed");
63
+ }
64
+ };
65
+ const stopHeartbeat = () => {
66
+ clearInterval(heartbeatTimer);
67
+ heartbeatTimer = void 0;
68
+ };
69
+ const detach = (target) => {
70
+ stopHeartbeat();
71
+ target.socket.removeEventListener("open", target.onOpen);
72
+ target.socket.removeEventListener("message", target.onMessage);
73
+ target.socket.removeEventListener("close", target.onClose);
74
+ try {
75
+ target.socket.close();
76
+ } catch {}
77
+ if (connection === target) connection = null;
78
+ };
79
+ const teardown = () => {
80
+ epoch += 1;
81
+ connecting = false;
82
+ attempt = 0;
83
+ lostConnection = false;
84
+ clearTimeout(retryTimer);
85
+ retryTimer = void 0;
86
+ clearTimeout(idleTimer);
87
+ idleTimer = void 0;
88
+ if (connection) detach(connection);
89
+ };
90
+ const touchIdle = () => {
91
+ clearTimeout(idleTimer);
92
+ idleTimer = void 0;
93
+ if (hub.topics().length > 0) return;
94
+ idleTimer = setTimeout(() => {
95
+ idleTimer = void 0;
96
+ if (hub.topics().length > 0) return;
97
+ if (!connection && !connecting && retryTimer === void 0) return;
98
+ teardown();
99
+ rejectQueue(/* @__PURE__ */ new Error("webSocketTransport went idle"));
100
+ setStatus("idle");
101
+ }, idleDisconnectMs);
102
+ };
103
+ const giveUp = (reason) => {
104
+ rejectQueue(reason);
105
+ setStatus("disconnected");
106
+ };
107
+ const lose = (target, clean, cause) => {
108
+ detach(target);
109
+ clearTimeout(idleTimer);
110
+ if (target.opened) lostConnection = true;
111
+ if (clean) {
112
+ setStatus("disconnected");
113
+ return;
114
+ }
115
+ if (backoff.enabled && attempt < backoff.maxAttempts) {
116
+ const delay = reconnectDelay(attempt, backoff);
117
+ attempt += 1;
118
+ hub.report({
119
+ kind: "connect_failed",
120
+ cause,
121
+ retrying: true
122
+ });
123
+ setStatus("reconnecting");
124
+ retryTimer = setTimeout(() => {
125
+ retryTimer = void 0;
126
+ connect();
127
+ }, delay);
128
+ touchIdle();
129
+ return;
130
+ }
131
+ hub.report({
132
+ kind: "connect_failed",
133
+ cause,
134
+ retrying: false
135
+ });
136
+ giveUp(/* @__PURE__ */ new Error("webSocketTransport could not connect"));
137
+ };
138
+ const heartbeat = (target) => {
139
+ if (target.awaitingPong) {
140
+ lose(target, false, { reason: "heartbeat missed" });
141
+ return;
142
+ }
143
+ target.awaitingPong = true;
144
+ send(target, { op: "ping" });
145
+ };
146
+ const handleMessage = (target, message) => {
147
+ target.awaitingPong = false;
148
+ const parsed = parseFrame(message.data);
149
+ if (parsed.kind === "pong") return;
150
+ if (parsed.kind === "invalid") {
151
+ hub.report({
152
+ kind: "parse_failed",
153
+ cause: parsed.cause,
154
+ retrying: false
155
+ });
156
+ return;
157
+ }
158
+ const { topic, type, payload, meta } = parsed.event;
159
+ hub.dispatch({
160
+ topic,
161
+ type,
162
+ payload,
163
+ ...meta ? { meta } : {}
164
+ });
165
+ };
166
+ const handleOpen = (target) => {
167
+ target.opened = true;
168
+ attempt = 0;
169
+ setStatus("connected");
170
+ for (const topic of hub.topics()) send(target, {
171
+ op: "subscribe",
172
+ topic
173
+ });
174
+ const flushed = queue;
175
+ queue = [];
176
+ for (const { topic, event, resolve, reject } of flushed) {
177
+ const failure = send(target, {
178
+ op: "publish",
179
+ topic,
180
+ event
181
+ }, topic);
182
+ if (failure) reject(failure);
183
+ else resolve();
184
+ }
185
+ heartbeatTimer = setInterval(() => heartbeat(target), heartbeatMs);
186
+ touchIdle();
187
+ if (lostConnection) {
188
+ lostConnection = false;
189
+ hub.reconnected();
190
+ }
191
+ };
192
+ const open = (token) => {
193
+ let target;
194
+ try {
195
+ const address = token && authMode === "query" ? `${url}${url.includes("?") ? "&" : "?"}token=${encodeURIComponent(token)}` : url;
196
+ const offered = token && authMode === "subprotocol" ? [...protocols, token] : protocols;
197
+ target = {
198
+ socket: offered.length > 0 ? new WebSocket(address, offered) : new WebSocket(address),
199
+ opened: false,
200
+ awaitingPong: false,
201
+ onOpen: () => handleOpen(target),
202
+ onMessage: (message) => handleMessage(target, message),
203
+ onClose: (event) => lose(target, event.wasClean, {
204
+ code: event.code,
205
+ reason: event.reason
206
+ })
207
+ };
208
+ } catch (error) {
209
+ const name = error instanceof Error ? error.name : "Error";
210
+ const cause = /* @__PURE__ */ new Error(`WebSocket constructor failed: ${name}`);
211
+ hub.report({
212
+ kind: "connect_failed",
213
+ cause,
214
+ retrying: false
215
+ });
216
+ giveUp(cause);
217
+ return;
218
+ }
219
+ connection = target;
220
+ target.socket.addEventListener("open", target.onOpen);
221
+ target.socket.addEventListener("message", target.onMessage);
222
+ target.socket.addEventListener("close", target.onClose);
223
+ };
224
+ async function connect() {
225
+ connecting = true;
226
+ const startedAt = epoch;
227
+ let token;
228
+ if (getAuthToken) {
229
+ try {
230
+ token = await getAuthToken();
231
+ } catch (cause) {
232
+ if (epoch !== startedAt) return;
233
+ connecting = false;
234
+ hub.report({
235
+ kind: "auth_failed",
236
+ cause,
237
+ retrying: false
238
+ });
239
+ giveUp(cause instanceof Error ? cause : /* @__PURE__ */ new Error("auth failed"));
240
+ return;
241
+ }
242
+ if (epoch !== startedAt) return;
243
+ }
244
+ connecting = false;
245
+ open(token);
246
+ }
247
+ const ensureOpen = () => {
248
+ if (connection || connecting || retryTimer !== void 0) return;
249
+ attempt = 0;
250
+ connect();
251
+ };
252
+ return {
253
+ subscribe(topic, callback) {
254
+ const first = !hub.has(topic);
255
+ const unsubscribe = hub.subscribe(topic, callback);
256
+ touchIdle();
257
+ if (first && connection?.opened) send(connection, {
258
+ op: "subscribe",
259
+ topic
260
+ }, topic);
261
+ ensureOpen();
262
+ let done = false;
263
+ return () => {
264
+ if (done) return;
265
+ done = true;
266
+ unsubscribe();
267
+ if (!hub.has(topic) && connection?.opened) send(connection, {
268
+ op: "unsubscribe",
269
+ topic
270
+ }, topic);
271
+ touchIdle();
272
+ };
273
+ },
274
+ publish(topic, event) {
275
+ if (connection?.opened) {
276
+ touchIdle();
277
+ const failure = send(connection, {
278
+ op: "publish",
279
+ topic,
280
+ event
281
+ }, topic);
282
+ return failure ? Promise.reject(failure) : Promise.resolve();
283
+ }
284
+ return new Promise((resolve, reject) => {
285
+ queue.push({
286
+ topic,
287
+ event,
288
+ resolve,
289
+ reject
290
+ });
291
+ touchIdle();
292
+ ensureOpen();
293
+ });
294
+ },
295
+ onReconnect: hub.onReconnect,
296
+ onStatusChange: hub.onStatusChange,
297
+ onError: hub.onError,
298
+ getStatus: hub.getStatus,
299
+ close() {
300
+ teardown();
301
+ rejectQueue(/* @__PURE__ */ new Error("webSocketTransport is closed"));
302
+ setStatus("disconnected");
303
+ }
304
+ };
305
+ }
306
+ export { webSocketTransport };
@@ -28,6 +28,8 @@ export interface ResourceDescriptor {
28
28
  resource: string;
29
29
  fields: FieldDescriptor[];
30
30
  }
31
+ /** For core's block editor helpers; not exported from the package index. */
32
+ export declare function describeField(source: string, schema: unknown, references: ResourceConfig["references"]): FieldDescriptor;
31
33
  /**
32
34
  * Turns a resource's registered Zod schema (Zod 3 or Zod 4) into one descriptor per field, in
33
35
  * schema key order. Returns `undefined` when there is no schema to read or it