spacetimedb 2.4.1 → 2.6.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 (194) hide show
  1. package/LICENSE.txt +759 -759
  2. package/README.md +211 -120
  3. package/dist/angular/index.cjs.map +1 -1
  4. package/dist/angular/index.mjs.map +1 -1
  5. package/dist/browser/angular/index.mjs.map +1 -1
  6. package/dist/browser/react/index.mjs +129 -57
  7. package/dist/browser/react/index.mjs.map +1 -1
  8. package/dist/browser/solid/index.mjs +1933 -0
  9. package/dist/browser/solid/index.mjs.map +1 -0
  10. package/dist/browser/svelte/index.mjs.map +1 -1
  11. package/dist/browser/vue/index.mjs.map +1 -1
  12. package/dist/index.browser.mjs +10 -2
  13. package/dist/index.browser.mjs.map +1 -1
  14. package/dist/index.cjs +10 -2
  15. package/dist/index.cjs.map +1 -1
  16. package/dist/index.mjs +10 -2
  17. package/dist/index.mjs.map +1 -1
  18. package/dist/min/index.browser.mjs +1 -1
  19. package/dist/min/index.browser.mjs.map +1 -1
  20. package/dist/min/react/index.mjs +1 -1
  21. package/dist/min/react/index.mjs.map +1 -1
  22. package/dist/min/sdk/index.browser.mjs +1 -1
  23. package/dist/min/sdk/index.browser.mjs.map +1 -1
  24. package/dist/react/index.cjs +129 -57
  25. package/dist/react/index.cjs.map +1 -1
  26. package/dist/react/index.mjs +129 -57
  27. package/dist/react/index.mjs.map +1 -1
  28. package/dist/react/useTable.d.ts.map +1 -1
  29. package/dist/sdk/connection_manager.d.ts +8 -0
  30. package/dist/sdk/connection_manager.d.ts.map +1 -1
  31. package/dist/sdk/db_connection_impl.d.ts +7 -0
  32. package/dist/sdk/db_connection_impl.d.ts.map +1 -1
  33. package/dist/sdk/index.browser.mjs +10 -2
  34. package/dist/sdk/index.browser.mjs.map +1 -1
  35. package/dist/sdk/index.cjs +10 -2
  36. package/dist/sdk/index.cjs.map +1 -1
  37. package/dist/sdk/index.mjs +10 -2
  38. package/dist/sdk/index.mjs.map +1 -1
  39. package/dist/sdk/websocket_test_adapter.d.ts +2 -1
  40. package/dist/sdk/websocket_test_adapter.d.ts.map +1 -1
  41. package/dist/server/index.mjs.map +1 -1
  42. package/dist/server/runtime.d.ts.map +1 -1
  43. package/dist/solid/SpacetimeDBProvider.d.ts +7 -0
  44. package/dist/solid/SpacetimeDBProvider.d.ts.map +1 -0
  45. package/dist/solid/connection_state.d.ts +6 -0
  46. package/dist/solid/connection_state.d.ts.map +1 -0
  47. package/dist/solid/index.cjs +1939 -0
  48. package/dist/solid/index.cjs.map +1 -0
  49. package/dist/solid/index.d.ts +6 -0
  50. package/dist/solid/index.d.ts.map +1 -0
  51. package/dist/solid/index.mjs +1933 -0
  52. package/dist/solid/index.mjs.map +1 -0
  53. package/dist/solid/useProcedure.d.ts +4 -0
  54. package/dist/solid/useProcedure.d.ts.map +1 -0
  55. package/dist/solid/useReducer.d.ts +4 -0
  56. package/dist/solid/useReducer.d.ts.map +1 -0
  57. package/dist/solid/useSpacetimeDB.d.ts +4 -0
  58. package/dist/solid/useSpacetimeDB.d.ts.map +1 -0
  59. package/dist/solid/useTable.d.ts +32 -0
  60. package/dist/solid/useTable.d.ts.map +1 -0
  61. package/dist/svelte/index.cjs.map +1 -1
  62. package/dist/svelte/index.mjs.map +1 -1
  63. package/dist/tanstack/index.cjs +120 -50
  64. package/dist/tanstack/index.cjs.map +1 -1
  65. package/dist/tanstack/index.mjs +120 -50
  66. package/dist/tanstack/index.mjs.map +1 -1
  67. package/dist/vue/index.cjs.map +1 -1
  68. package/dist/vue/index.mjs.map +1 -1
  69. package/package.json +13 -3
  70. package/src/angular/connection_state.ts +19 -19
  71. package/src/angular/index.ts +3 -3
  72. package/src/angular/injectors/index.ts +4 -4
  73. package/src/angular/injectors/inject-reducer.ts +62 -62
  74. package/src/angular/injectors/inject-spacetimedb-connected.ts +13 -13
  75. package/src/angular/injectors/inject-spacetimedb.ts +10 -10
  76. package/src/angular/injectors/inject-table.ts +234 -234
  77. package/src/angular/providers/index.ts +1 -1
  78. package/src/angular/providers/provide-spacetimedb.ts +96 -96
  79. package/src/index.ts +16 -16
  80. package/src/lib/algebraic_type.ts +819 -819
  81. package/src/lib/algebraic_type_variants.ts +26 -26
  82. package/src/lib/algebraic_value.ts +10 -10
  83. package/src/lib/autogen/types.ts +746 -746
  84. package/src/lib/binary_reader.ts +188 -188
  85. package/src/lib/binary_writer.ts +213 -213
  86. package/src/lib/connection_id.ts +102 -102
  87. package/src/lib/constraints.ts +48 -48
  88. package/src/lib/errors.ts +26 -26
  89. package/src/lib/filter.ts +195 -195
  90. package/src/lib/identity.ts +83 -83
  91. package/src/lib/indexes.ts +251 -251
  92. package/src/lib/option.ts +34 -34
  93. package/src/lib/query.ts +1019 -1019
  94. package/src/lib/reducer_schema.ts +38 -38
  95. package/src/lib/reducers.ts +116 -116
  96. package/src/lib/result.ts +36 -36
  97. package/src/lib/schedule_at.ts +86 -86
  98. package/src/lib/schema.ts +420 -420
  99. package/src/lib/table.ts +548 -548
  100. package/src/lib/table_schema.ts +64 -64
  101. package/src/lib/time_duration.ts +77 -77
  102. package/src/lib/timestamp.ts +148 -148
  103. package/src/lib/type_builders.test-d.ts +128 -128
  104. package/src/lib/type_builders.ts +4014 -4014
  105. package/src/lib/type_util.ts +124 -124
  106. package/src/lib/util.ts +196 -196
  107. package/src/lib/uuid.ts +337 -337
  108. package/src/react/SpacetimeDBProvider.ts +84 -84
  109. package/src/react/connection_state.ts +6 -6
  110. package/src/react/index.ts +5 -5
  111. package/src/react/useProcedure.ts +60 -60
  112. package/src/react/useReducer.ts +53 -53
  113. package/src/react/useSpacetimeDB.ts +18 -18
  114. package/src/react/useTable.ts +256 -251
  115. package/src/sdk/client_api/index.ts +114 -114
  116. package/src/sdk/client_api/types/procedures.ts +8 -8
  117. package/src/sdk/client_api/types/reducers.ts +8 -8
  118. package/src/sdk/client_api/types.ts +288 -288
  119. package/src/sdk/client_cache.ts +129 -129
  120. package/src/sdk/client_table.ts +179 -179
  121. package/src/sdk/connection_manager.ts +352 -237
  122. package/src/sdk/db_connection_builder.ts +290 -290
  123. package/src/sdk/db_connection_impl.ts +1356 -1347
  124. package/src/sdk/db_context.ts +28 -28
  125. package/src/sdk/db_view.ts +12 -12
  126. package/src/sdk/decompress.ts +51 -51
  127. package/src/sdk/event.ts +18 -18
  128. package/src/sdk/event_context.ts +51 -51
  129. package/src/sdk/event_emitter.ts +32 -32
  130. package/src/sdk/index.ts +14 -14
  131. package/src/sdk/internal.ts +2 -2
  132. package/src/sdk/json_api.ts +46 -46
  133. package/src/sdk/logger.ts +134 -134
  134. package/src/sdk/message_types.ts +46 -46
  135. package/src/sdk/procedures.ts +83 -83
  136. package/src/sdk/reducer_event.ts +20 -20
  137. package/src/sdk/reducer_handle.ts +12 -12
  138. package/src/sdk/reducers.ts +159 -159
  139. package/src/sdk/schema.ts +45 -45
  140. package/src/sdk/spacetime_module.ts +28 -28
  141. package/src/sdk/subscription_builder_impl.ts +275 -275
  142. package/src/sdk/table_cache.ts +581 -581
  143. package/src/sdk/type_utils.ts +19 -19
  144. package/src/sdk/version.ts +133 -133
  145. package/src/sdk/websocket_decompress_adapter.ts +63 -63
  146. package/src/sdk/websocket_protocols.ts +25 -25
  147. package/src/sdk/websocket_test_adapter.ts +107 -100
  148. package/src/sdk/websocket_v3_frames.ts +126 -126
  149. package/src/sdk/ws.ts +105 -105
  150. package/src/server/console.ts +81 -81
  151. package/src/server/db_view.ts +21 -21
  152. package/src/server/errors.ts +138 -138
  153. package/src/server/http.test-d.ts +80 -80
  154. package/src/server/http.ts +14 -14
  155. package/src/server/http_handlers.ts +413 -413
  156. package/src/server/http_internal.ts +79 -79
  157. package/src/server/http_shared.ts +186 -186
  158. package/src/server/index.ts +37 -37
  159. package/src/server/polyfills.ts +4 -4
  160. package/src/server/procedures.ts +239 -239
  161. package/src/server/query.ts +1 -1
  162. package/src/server/range.ts +53 -53
  163. package/src/server/reducers.ts +113 -113
  164. package/src/server/rng.ts +113 -113
  165. package/src/server/runtime.ts +1102 -1102
  166. package/src/server/schema.test-d.ts +99 -99
  167. package/src/server/schema.ts +663 -663
  168. package/src/server/sys.d.ts +125 -125
  169. package/src/server/view.test-d.ts +194 -194
  170. package/src/server/views.ts +340 -340
  171. package/src/solid/SpacetimeDBProvider.ts +97 -0
  172. package/src/solid/connection_state.ts +6 -0
  173. package/src/solid/index.ts +5 -0
  174. package/src/solid/useProcedure.ts +57 -0
  175. package/src/solid/useReducer.ts +50 -0
  176. package/src/solid/useSpacetimeDB.ts +18 -0
  177. package/src/solid/useTable.ts +203 -0
  178. package/src/svelte/SpacetimeDBProvider.ts +101 -101
  179. package/src/svelte/connection_state.ts +16 -16
  180. package/src/svelte/index.ts +4 -4
  181. package/src/svelte/useReducer.ts +61 -61
  182. package/src/svelte/useSpacetimeDB.ts +22 -22
  183. package/src/svelte/useTable.ts +218 -218
  184. package/src/tanstack/SpacetimeDBQueryClient.ts +330 -330
  185. package/src/tanstack/hooks.ts +83 -83
  186. package/src/tanstack/index.ts +16 -16
  187. package/src/util-stub.ts +1 -1
  188. package/src/vue/SpacetimeDBProvider.ts +157 -157
  189. package/src/vue/connection_state.ts +19 -19
  190. package/src/vue/index.ts +5 -5
  191. package/src/vue/useProcedure.ts +62 -62
  192. package/src/vue/useReducer.ts +55 -55
  193. package/src/vue/useSpacetimeDB.ts +18 -18
  194. package/src/vue/useTable.ts +229 -229
@@ -0,0 +1,1939 @@
1
+ 'use strict';
2
+
3
+ var base64Js = require('base64-js');
4
+ var solidJs = require('solid-js');
5
+ var store = require('solid-js/store');
6
+
7
+ // src/lib/time_duration.ts
8
+ var TimeDuration = class _TimeDuration {
9
+ __time_duration_micros__;
10
+ static MICROS_PER_MILLIS = 1000n;
11
+ /**
12
+ * Get the algebraic type representation of the {@link TimeDuration} type.
13
+ * @returns The algebraic type representation of the type.
14
+ */
15
+ static getAlgebraicType() {
16
+ return AlgebraicType.Product({
17
+ elements: [
18
+ {
19
+ name: "__time_duration_micros__",
20
+ algebraicType: AlgebraicType.I64
21
+ }
22
+ ]
23
+ });
24
+ }
25
+ static isTimeDuration(algebraicType) {
26
+ if (algebraicType.tag !== "Product") {
27
+ return false;
28
+ }
29
+ const elements = algebraicType.value.elements;
30
+ if (elements.length !== 1) {
31
+ return false;
32
+ }
33
+ const microsElement = elements[0];
34
+ return microsElement.name === "__time_duration_micros__" && microsElement.algebraicType.tag === "I64";
35
+ }
36
+ get micros() {
37
+ return this.__time_duration_micros__;
38
+ }
39
+ get millis() {
40
+ return Number(this.micros / _TimeDuration.MICROS_PER_MILLIS);
41
+ }
42
+ constructor(micros) {
43
+ this.__time_duration_micros__ = micros;
44
+ }
45
+ static fromMillis(millis) {
46
+ return new _TimeDuration(BigInt(millis) * _TimeDuration.MICROS_PER_MILLIS);
47
+ }
48
+ /** This outputs the same string format that we use in the host and in Rust modules */
49
+ toString() {
50
+ const micros = this.micros;
51
+ const sign = micros < 0 ? "-" : "+";
52
+ const pos = micros < 0 ? -micros : micros;
53
+ const secs = pos / 1000000n;
54
+ const micros_remaining = pos % 1000000n;
55
+ return `${sign}${secs}.${String(micros_remaining).padStart(6, "0")}`;
56
+ }
57
+ };
58
+
59
+ // src/lib/timestamp.ts
60
+ var Timestamp = class _Timestamp {
61
+ __timestamp_micros_since_unix_epoch__;
62
+ static MICROS_PER_MILLIS = 1000n;
63
+ get microsSinceUnixEpoch() {
64
+ return this.__timestamp_micros_since_unix_epoch__;
65
+ }
66
+ constructor(micros) {
67
+ this.__timestamp_micros_since_unix_epoch__ = micros;
68
+ }
69
+ /**
70
+ * Get the algebraic type representation of the {@link Timestamp} type.
71
+ * @returns The algebraic type representation of the type.
72
+ */
73
+ static getAlgebraicType() {
74
+ return AlgebraicType.Product({
75
+ elements: [
76
+ {
77
+ name: "__timestamp_micros_since_unix_epoch__",
78
+ algebraicType: AlgebraicType.I64
79
+ }
80
+ ]
81
+ });
82
+ }
83
+ static isTimestamp(algebraicType) {
84
+ if (algebraicType.tag !== "Product") {
85
+ return false;
86
+ }
87
+ const elements = algebraicType.value.elements;
88
+ if (elements.length !== 1) {
89
+ return false;
90
+ }
91
+ const microsElement = elements[0];
92
+ return microsElement.name === "__timestamp_micros_since_unix_epoch__" && microsElement.algebraicType.tag === "I64";
93
+ }
94
+ /**
95
+ * The Unix epoch, the midnight at the beginning of January 1, 1970, UTC.
96
+ */
97
+ static UNIX_EPOCH = new _Timestamp(0n);
98
+ /**
99
+ * Get a `Timestamp` representing the execution environment's belief of the current moment in time.
100
+ */
101
+ static now() {
102
+ return _Timestamp.fromDate(/* @__PURE__ */ new Date());
103
+ }
104
+ /** Convert to milliseconds since Unix epoch. */
105
+ toMillis() {
106
+ return this.microsSinceUnixEpoch / 1000n;
107
+ }
108
+ /**
109
+ * Get a `Timestamp` representing the same point in time as `date`.
110
+ */
111
+ static fromDate(date) {
112
+ const millis = date.getTime();
113
+ const micros = BigInt(millis) * _Timestamp.MICROS_PER_MILLIS;
114
+ return new _Timestamp(micros);
115
+ }
116
+ /**
117
+ * Get a `Date` representing approximately the same point in time as `this`.
118
+ *
119
+ * This method truncates to millisecond precision,
120
+ * and throws `RangeError` if the `Timestamp` is outside the range representable as a `Date`.
121
+ */
122
+ toDate() {
123
+ const micros = this.__timestamp_micros_since_unix_epoch__;
124
+ const millis = micros / _Timestamp.MICROS_PER_MILLIS;
125
+ if (millis > BigInt(Number.MAX_SAFE_INTEGER) || millis < BigInt(Number.MIN_SAFE_INTEGER)) {
126
+ throw new RangeError(
127
+ "Timestamp is outside of the representable range of JS's Date"
128
+ );
129
+ }
130
+ return new Date(Number(millis));
131
+ }
132
+ /**
133
+ * Get an ISO 8601 / RFC 3339 formatted string representation of this timestamp with microsecond precision.
134
+ *
135
+ * This method preserves the full microsecond precision of the timestamp,
136
+ * and throws `RangeError` if the `Timestamp` is outside the range representable in ISO format.
137
+ *
138
+ * @returns ISO 8601 formatted string with microsecond precision (e.g., '2025-02-17T10:30:45.123456Z')
139
+ */
140
+ toISOString() {
141
+ const micros = this.__timestamp_micros_since_unix_epoch__;
142
+ const millis = micros / _Timestamp.MICROS_PER_MILLIS;
143
+ if (millis > BigInt(Number.MAX_SAFE_INTEGER) || millis < BigInt(Number.MIN_SAFE_INTEGER)) {
144
+ throw new RangeError(
145
+ "Timestamp is outside of the representable range for ISO string formatting"
146
+ );
147
+ }
148
+ const date = new Date(Number(millis));
149
+ const isoBase = date.toISOString();
150
+ const microsRemainder = Math.abs(Number(micros % 1000000n));
151
+ const fractionalPart = String(microsRemainder).padStart(6, "0");
152
+ return isoBase.replace(/\.\d{3}Z$/, `.${fractionalPart}Z`);
153
+ }
154
+ since(other) {
155
+ return new TimeDuration(
156
+ this.__timestamp_micros_since_unix_epoch__ - other.__timestamp_micros_since_unix_epoch__
157
+ );
158
+ }
159
+ };
160
+
161
+ // src/lib/uuid.ts
162
+ var Uuid = class _Uuid {
163
+ __uuid__;
164
+ /**
165
+ * The nil UUID (all zeros).
166
+ *
167
+ * @example
168
+ * ```ts
169
+ * const uuid = Uuid.NIL;
170
+ * console.assert(
171
+ * uuid.toString() === "00000000-0000-0000-0000-000000000000"
172
+ * );
173
+ * ```
174
+ */
175
+ static NIL = new _Uuid(0n);
176
+ static MAX_UUID_BIGINT = 0xffffffffffffffffffffffffffffffffn;
177
+ /**
178
+ * The max UUID (all ones).
179
+ *
180
+ * @example
181
+ * ```ts
182
+ * const uuid = Uuid.MAX;
183
+ * console.assert(
184
+ * uuid.toString() === "ffffffff-ffff-ffff-ffff-ffffffffffff"
185
+ * );
186
+ * ```
187
+ */
188
+ static MAX = new _Uuid(_Uuid.MAX_UUID_BIGINT);
189
+ /**
190
+ * Create a UUID from a raw 128-bit value.
191
+ *
192
+ * @param u - Unsigned 128-bit integer
193
+ * @throws {Error} If the value is outside the valid UUID range
194
+ */
195
+ constructor(u) {
196
+ if (u < 0n || u > _Uuid.MAX_UUID_BIGINT) {
197
+ throw new Error("Invalid UUID: must be between 0 and `MAX_UUID_BIGINT`");
198
+ }
199
+ this.__uuid__ = u;
200
+ }
201
+ /**
202
+ * Create a UUID `v4` from explicit random bytes.
203
+ *
204
+ * This method assumes the bytes are already sufficiently random.
205
+ * It only sets the appropriate bits for the UUID version and variant.
206
+ *
207
+ * @param bytes - Exactly 16 random bytes
208
+ * @returns A UUID `v4`
209
+ * @throws {Error} If `bytes.length !== 16`
210
+ *
211
+ * @example
212
+ * ```ts
213
+ * const randomBytes = new Uint8Array(16);
214
+ * const uuid = Uuid.fromRandomBytesV4(randomBytes);
215
+ *
216
+ * console.assert(
217
+ * uuid.toString() === "00000000-0000-4000-8000-000000000000"
218
+ * );
219
+ * ```
220
+ */
221
+ static fromRandomBytesV4(bytes) {
222
+ if (bytes.length !== 16) throw new Error("UUID v4 requires 16 bytes");
223
+ const arr = new Uint8Array(bytes);
224
+ arr[6] = arr[6] & 15 | 64;
225
+ arr[8] = arr[8] & 63 | 128;
226
+ return new _Uuid(_Uuid.bytesToBigInt(arr));
227
+ }
228
+ /**
229
+ * Generate a UUID `v7` using a monotonic counter from `0` to `2^31 - 1`,
230
+ * a timestamp, and 4 random bytes.
231
+ *
232
+ * The counter wraps around on overflow.
233
+ *
234
+ * The UUID `v7` is structured as follows:
235
+ *
236
+ * ```ascii
237
+ * ┌───────────────────────────────────────────────┬───────────────────┐
238
+ * | B0 | B1 | B2 | B3 | B4 | B5 | B6 |
239
+ * ├───────────────────────────────────────────────┼───────────────────┤
240
+ * | unix_ts_ms | version 7 |
241
+ * └───────────────────────────────────────────────┴───────────────────┘
242
+ * ┌──────────────┬─────────┬──────────────────┬───────────────────────┐
243
+ * | B7 | B8 | B9 | B10 | B11 | B12 | B13 | B14 | B15 |
244
+ * ├──────────────┼─────────┼──────────────────┼───────────────────────┤
245
+ * | counter_high | variant | counter_low | random |
246
+ * └──────────────┴─────────┴──────────────────┴───────────────────────┘
247
+ * ```
248
+ *
249
+ * @param counter - Mutable monotonic counter (31-bit)
250
+ * @param now - Timestamp since the Unix epoch
251
+ * @param randomBytes - Exactly 4 random bytes
252
+ * @returns A UUID `v7`
253
+ *
254
+ * @throws {Error} If the `counter` is negative
255
+ * @throws {Error} If the `timestamp` is before the Unix epoch
256
+ * @throws {Error} If `randomBytes.length !== 4`
257
+ *
258
+ * @example
259
+ * ```ts
260
+ * const now = Timestamp.fromMillis(1_686_000_000_000n);
261
+ * const counter = { value: 1 };
262
+ * const randomBytes = new Uint8Array(4);
263
+ *
264
+ * const uuid = Uuid.fromCounterV7(counter, now, randomBytes);
265
+ *
266
+ * console.assert(
267
+ * uuid.toString() === "0000647e-5180-7000-8000-000200000000"
268
+ * );
269
+ * ```
270
+ */
271
+ static fromCounterV7(counter, now, randomBytes) {
272
+ if (randomBytes.length !== 4) {
273
+ throw new Error("`fromCounterV7` requires `randomBytes.length == 4`");
274
+ }
275
+ if (counter.value < 0) {
276
+ throw new Error("`fromCounterV7` uuid `counter` must be non-negative");
277
+ }
278
+ if (now.__timestamp_micros_since_unix_epoch__ < 0) {
279
+ throw new Error("`fromCounterV7` `timestamp` before unix epoch");
280
+ }
281
+ const counterVal = counter.value;
282
+ counter.value = counterVal + 1 & 2147483647;
283
+ const tsMs = now.toMillis() & 0xffffffffffffn;
284
+ const bytes = new Uint8Array(16);
285
+ bytes[0] = Number(tsMs >> 40n & 0xffn);
286
+ bytes[1] = Number(tsMs >> 32n & 0xffn);
287
+ bytes[2] = Number(tsMs >> 24n & 0xffn);
288
+ bytes[3] = Number(tsMs >> 16n & 0xffn);
289
+ bytes[4] = Number(tsMs >> 8n & 0xffn);
290
+ bytes[5] = Number(tsMs & 0xffn);
291
+ bytes[7] = counterVal >>> 23 & 255;
292
+ bytes[9] = counterVal >>> 15 & 255;
293
+ bytes[10] = counterVal >>> 7 & 255;
294
+ bytes[11] = (counterVal & 127) << 1 & 255;
295
+ bytes[12] |= randomBytes[0] & 127;
296
+ bytes[13] = randomBytes[1];
297
+ bytes[14] = randomBytes[2];
298
+ bytes[15] = randomBytes[3];
299
+ bytes[6] = bytes[6] & 15 | 112;
300
+ bytes[8] = bytes[8] & 63 | 128;
301
+ return new _Uuid(_Uuid.bytesToBigInt(bytes));
302
+ }
303
+ /**
304
+ * Parse a UUID from a string representation.
305
+ *
306
+ * @param s - UUID string
307
+ * @returns Parsed UUID
308
+ * @throws {Error} If the string is not a valid UUID
309
+ *
310
+ * @example
311
+ * ```ts
312
+ * const s = "01888d6e-5c00-7000-8000-000000000000";
313
+ * const uuid = Uuid.parse(s);
314
+ *
315
+ * console.assert(uuid.toString() === s);
316
+ * ```
317
+ */
318
+ static parse(s) {
319
+ const hex = s.replace(/-/g, "");
320
+ if (hex.length !== 32) throw new Error("Invalid hex UUID");
321
+ let v = 0n;
322
+ for (let i = 0; i < 32; i += 2) {
323
+ v = v << 8n | BigInt(parseInt(hex.slice(i, i + 2), 16));
324
+ }
325
+ return new _Uuid(v);
326
+ }
327
+ /** Convert to string (hyphenated form). */
328
+ toString() {
329
+ const bytes = _Uuid.bigIntToBytes(this.__uuid__);
330
+ const hex = [...bytes].map((b) => b.toString(16).padStart(2, "0")).join("");
331
+ return hex.slice(0, 8) + "-" + hex.slice(8, 12) + "-" + hex.slice(12, 16) + "-" + hex.slice(16, 20) + "-" + hex.slice(20);
332
+ }
333
+ /** Convert to bigint (u128). */
334
+ asBigInt() {
335
+ return this.__uuid__;
336
+ }
337
+ /** Return a `Uint8Array` of 16 bytes. */
338
+ toBytes() {
339
+ return _Uuid.bigIntToBytes(this.__uuid__);
340
+ }
341
+ static bytesToBigInt(bytes) {
342
+ let result = 0n;
343
+ for (const b of bytes) result = result << 8n | BigInt(b);
344
+ return result;
345
+ }
346
+ static bigIntToBytes(value) {
347
+ const bytes = new Uint8Array(16);
348
+ for (let i = 15; i >= 0; i--) {
349
+ bytes[i] = Number(value & 0xffn);
350
+ value >>= 8n;
351
+ }
352
+ return bytes;
353
+ }
354
+ /**
355
+ * Returns the version of this UUID.
356
+ *
357
+ * This represents the algorithm used to generate the value.
358
+ *
359
+ * @returns A `UuidVersion`
360
+ * @throws {Error} If the version field is not recognized
361
+ */
362
+ getVersion() {
363
+ const version = this.toBytes()[6] >> 4 & 15;
364
+ switch (version) {
365
+ case 4:
366
+ return "V4";
367
+ case 7:
368
+ return "V7";
369
+ default:
370
+ if (this == _Uuid.NIL) {
371
+ return "Nil";
372
+ }
373
+ if (this == _Uuid.MAX) {
374
+ return "Max";
375
+ }
376
+ throw new Error(`Unsupported UUID version: ${version}`);
377
+ }
378
+ }
379
+ /**
380
+ * Extract the monotonic counter from a UUIDv7.
381
+ *
382
+ * Intended for testing and diagnostics.
383
+ * Behavior is undefined if called on a non-V7 UUID.
384
+ *
385
+ * @returns 31-bit counter value
386
+ */
387
+ getCounter() {
388
+ const bytes = this.toBytes();
389
+ const high = bytes[7];
390
+ const mid1 = bytes[9];
391
+ const mid2 = bytes[10];
392
+ const low = bytes[11] >>> 1;
393
+ return high << 23 | mid1 << 15 | mid2 << 7 | low | 0;
394
+ }
395
+ compareTo(other) {
396
+ if (this.__uuid__ < other.__uuid__) return -1;
397
+ if (this.__uuid__ > other.__uuid__) return 1;
398
+ return 0;
399
+ }
400
+ static getAlgebraicType() {
401
+ return AlgebraicType.Product({
402
+ elements: [
403
+ {
404
+ name: "__uuid__",
405
+ algebraicType: AlgebraicType.U128
406
+ }
407
+ ]
408
+ });
409
+ }
410
+ };
411
+
412
+ // src/lib/binary_reader.ts
413
+ var BinaryReader = class {
414
+ /**
415
+ * The DataView used to read values from the binary data.
416
+ *
417
+ * Note: The DataView's `byteOffset` is relative to the beginning of the
418
+ * underlying ArrayBuffer, not the start of the provided Uint8Array input.
419
+ * This `BinaryReader`'s `#offset` field is used to track the current read position
420
+ * relative to the start of the provided Uint8Array input.
421
+ */
422
+ view;
423
+ /**
424
+ * Represents the offset (in bytes) relative to the start of the DataView
425
+ * and provided Uint8Array input.
426
+ *
427
+ * Note: This is *not* the absolute byte offset within the underlying ArrayBuffer.
428
+ */
429
+ offset = 0;
430
+ constructor(input) {
431
+ this.view = input instanceof DataView ? input : new DataView(input.buffer, input.byteOffset, input.byteLength);
432
+ this.offset = 0;
433
+ }
434
+ reset(input) {
435
+ this.view = input instanceof DataView ? input : new DataView(input.buffer, input.byteOffset, input.byteLength);
436
+ this.offset = 0;
437
+ }
438
+ get remaining() {
439
+ return this.view.byteLength - this.offset;
440
+ }
441
+ /** Ensure we have at least `n` bytes left to read */
442
+ #ensure(n) {
443
+ if (this.offset + n > this.view.byteLength) {
444
+ throw new RangeError(
445
+ `Tried to read ${n} byte(s) at relative offset ${this.offset}, but only ${this.remaining} byte(s) remain`
446
+ );
447
+ }
448
+ }
449
+ readUInt8Array() {
450
+ const length = this.readU32();
451
+ this.#ensure(length);
452
+ return this.readBytes(length);
453
+ }
454
+ readBool() {
455
+ const value = this.view.getUint8(this.offset);
456
+ this.offset += 1;
457
+ return value !== 0;
458
+ }
459
+ readByte() {
460
+ const value = this.view.getUint8(this.offset);
461
+ this.offset += 1;
462
+ return value;
463
+ }
464
+ readBytes(length) {
465
+ const array = new Uint8Array(
466
+ this.view.buffer,
467
+ this.view.byteOffset + this.offset,
468
+ length
469
+ );
470
+ this.offset += length;
471
+ return array;
472
+ }
473
+ readI8() {
474
+ const value = this.view.getInt8(this.offset);
475
+ this.offset += 1;
476
+ return value;
477
+ }
478
+ readU8() {
479
+ return this.readByte();
480
+ }
481
+ readI16() {
482
+ const value = this.view.getInt16(this.offset, true);
483
+ this.offset += 2;
484
+ return value;
485
+ }
486
+ readU16() {
487
+ const value = this.view.getUint16(this.offset, true);
488
+ this.offset += 2;
489
+ return value;
490
+ }
491
+ readI32() {
492
+ const value = this.view.getInt32(this.offset, true);
493
+ this.offset += 4;
494
+ return value;
495
+ }
496
+ readU32() {
497
+ const value = this.view.getUint32(this.offset, true);
498
+ this.offset += 4;
499
+ return value;
500
+ }
501
+ readI64() {
502
+ const value = this.view.getBigInt64(this.offset, true);
503
+ this.offset += 8;
504
+ return value;
505
+ }
506
+ readU64() {
507
+ const value = this.view.getBigUint64(this.offset, true);
508
+ this.offset += 8;
509
+ return value;
510
+ }
511
+ readU128() {
512
+ const lowerPart = this.view.getBigUint64(this.offset, true);
513
+ const upperPart = this.view.getBigUint64(this.offset + 8, true);
514
+ this.offset += 16;
515
+ return (upperPart << BigInt(64)) + lowerPart;
516
+ }
517
+ readI128() {
518
+ const lowerPart = this.view.getBigUint64(this.offset, true);
519
+ const upperPart = this.view.getBigInt64(this.offset + 8, true);
520
+ this.offset += 16;
521
+ return (upperPart << BigInt(64)) + lowerPart;
522
+ }
523
+ readU256() {
524
+ const p0 = this.view.getBigUint64(this.offset, true);
525
+ const p1 = this.view.getBigUint64(this.offset + 8, true);
526
+ const p2 = this.view.getBigUint64(this.offset + 16, true);
527
+ const p3 = this.view.getBigUint64(this.offset + 24, true);
528
+ this.offset += 32;
529
+ return (p3 << BigInt(3 * 64)) + (p2 << BigInt(2 * 64)) + (p1 << BigInt(1 * 64)) + p0;
530
+ }
531
+ readI256() {
532
+ const p0 = this.view.getBigUint64(this.offset, true);
533
+ const p1 = this.view.getBigUint64(this.offset + 8, true);
534
+ const p2 = this.view.getBigUint64(this.offset + 16, true);
535
+ const p3 = this.view.getBigInt64(this.offset + 24, true);
536
+ this.offset += 32;
537
+ return (p3 << BigInt(3 * 64)) + (p2 << BigInt(2 * 64)) + (p1 << BigInt(1 * 64)) + p0;
538
+ }
539
+ readF32() {
540
+ const value = this.view.getFloat32(this.offset, true);
541
+ this.offset += 4;
542
+ return value;
543
+ }
544
+ readF64() {
545
+ const value = this.view.getFloat64(this.offset, true);
546
+ this.offset += 8;
547
+ return value;
548
+ }
549
+ readString() {
550
+ const uint8Array = this.readUInt8Array();
551
+ return new TextDecoder("utf-8").decode(uint8Array);
552
+ }
553
+ };
554
+ var ArrayBufferPrototypeTransfer = ArrayBuffer.prototype.transfer ?? function(newByteLength) {
555
+ if (newByteLength === void 0) {
556
+ return this.slice();
557
+ } else if (newByteLength <= this.byteLength) {
558
+ return this.slice(0, newByteLength);
559
+ } else {
560
+ const copy = new Uint8Array(newByteLength);
561
+ copy.set(new Uint8Array(this));
562
+ return copy.buffer;
563
+ }
564
+ };
565
+ var ResizableBuffer = class {
566
+ buffer;
567
+ view;
568
+ constructor(init) {
569
+ this.buffer = typeof init === "number" ? new ArrayBuffer(init) : init;
570
+ this.view = new DataView(this.buffer);
571
+ }
572
+ get capacity() {
573
+ return this.buffer.byteLength;
574
+ }
575
+ grow(newSize) {
576
+ if (newSize <= this.buffer.byteLength) return;
577
+ this.buffer = ArrayBufferPrototypeTransfer.call(this.buffer, newSize);
578
+ this.view = new DataView(this.buffer);
579
+ }
580
+ };
581
+ var BinaryWriter = class {
582
+ buffer;
583
+ offset = 0;
584
+ constructor(init) {
585
+ this.buffer = typeof init === "number" ? new ResizableBuffer(init) : init;
586
+ }
587
+ clear() {
588
+ this.offset = 0;
589
+ }
590
+ reset(buffer) {
591
+ this.buffer = buffer;
592
+ this.offset = 0;
593
+ }
594
+ expandBuffer(additionalCapacity) {
595
+ const minCapacity = this.offset + additionalCapacity + 1;
596
+ if (minCapacity <= this.buffer.capacity) return;
597
+ let newCapacity = this.buffer.capacity * 2;
598
+ if (newCapacity < minCapacity) newCapacity = minCapacity;
599
+ this.buffer.grow(newCapacity);
600
+ }
601
+ toBase64() {
602
+ return base64Js.fromByteArray(this.getBuffer());
603
+ }
604
+ getBuffer() {
605
+ return new Uint8Array(this.buffer.buffer, 0, this.offset);
606
+ }
607
+ get view() {
608
+ return this.buffer.view;
609
+ }
610
+ writeUInt8Array(value) {
611
+ const length = value.length;
612
+ this.expandBuffer(4 + length);
613
+ this.writeU32(length);
614
+ new Uint8Array(this.buffer.buffer, this.offset).set(value);
615
+ this.offset += length;
616
+ }
617
+ writeBool(value) {
618
+ this.expandBuffer(1);
619
+ this.view.setUint8(this.offset, value ? 1 : 0);
620
+ this.offset += 1;
621
+ }
622
+ writeByte(value) {
623
+ this.expandBuffer(1);
624
+ this.view.setUint8(this.offset, value);
625
+ this.offset += 1;
626
+ }
627
+ writeBytes(value) {
628
+ this.expandBuffer(value.length);
629
+ new Uint8Array(this.buffer.buffer, this.offset, value.length).set(value);
630
+ this.offset += value.length;
631
+ }
632
+ writeI8(value) {
633
+ this.expandBuffer(1);
634
+ this.view.setInt8(this.offset, value);
635
+ this.offset += 1;
636
+ }
637
+ writeU8(value) {
638
+ this.expandBuffer(1);
639
+ this.view.setUint8(this.offset, value);
640
+ this.offset += 1;
641
+ }
642
+ writeI16(value) {
643
+ this.expandBuffer(2);
644
+ this.view.setInt16(this.offset, value, true);
645
+ this.offset += 2;
646
+ }
647
+ writeU16(value) {
648
+ this.expandBuffer(2);
649
+ this.view.setUint16(this.offset, value, true);
650
+ this.offset += 2;
651
+ }
652
+ writeI32(value) {
653
+ this.expandBuffer(4);
654
+ this.view.setInt32(this.offset, value, true);
655
+ this.offset += 4;
656
+ }
657
+ writeU32(value) {
658
+ this.expandBuffer(4);
659
+ this.view.setUint32(this.offset, value, true);
660
+ this.offset += 4;
661
+ }
662
+ writeI64(value) {
663
+ this.expandBuffer(8);
664
+ this.view.setBigInt64(this.offset, value, true);
665
+ this.offset += 8;
666
+ }
667
+ writeU64(value) {
668
+ this.expandBuffer(8);
669
+ this.view.setBigUint64(this.offset, value, true);
670
+ this.offset += 8;
671
+ }
672
+ writeU128(value) {
673
+ this.expandBuffer(16);
674
+ const lowerPart = value & BigInt("0xFFFFFFFFFFFFFFFF");
675
+ const upperPart = value >> BigInt(64);
676
+ this.view.setBigUint64(this.offset, lowerPart, true);
677
+ this.view.setBigUint64(this.offset + 8, upperPart, true);
678
+ this.offset += 16;
679
+ }
680
+ writeI128(value) {
681
+ this.expandBuffer(16);
682
+ const lowerPart = value & BigInt("0xFFFFFFFFFFFFFFFF");
683
+ const upperPart = value >> BigInt(64);
684
+ this.view.setBigInt64(this.offset, lowerPart, true);
685
+ this.view.setBigInt64(this.offset + 8, upperPart, true);
686
+ this.offset += 16;
687
+ }
688
+ writeU256(value) {
689
+ this.expandBuffer(32);
690
+ const low_64_mask = BigInt("0xFFFFFFFFFFFFFFFF");
691
+ const p0 = value & low_64_mask;
692
+ const p1 = value >> BigInt(64 * 1) & low_64_mask;
693
+ const p2 = value >> BigInt(64 * 2) & low_64_mask;
694
+ const p3 = value >> BigInt(64 * 3);
695
+ this.view.setBigUint64(this.offset + 8 * 0, p0, true);
696
+ this.view.setBigUint64(this.offset + 8 * 1, p1, true);
697
+ this.view.setBigUint64(this.offset + 8 * 2, p2, true);
698
+ this.view.setBigUint64(this.offset + 8 * 3, p3, true);
699
+ this.offset += 32;
700
+ }
701
+ writeI256(value) {
702
+ this.expandBuffer(32);
703
+ const low_64_mask = BigInt("0xFFFFFFFFFFFFFFFF");
704
+ const p0 = value & low_64_mask;
705
+ const p1 = value >> BigInt(64 * 1) & low_64_mask;
706
+ const p2 = value >> BigInt(64 * 2) & low_64_mask;
707
+ const p3 = value >> BigInt(64 * 3);
708
+ this.view.setBigUint64(this.offset + 8 * 0, p0, true);
709
+ this.view.setBigUint64(this.offset + 8 * 1, p1, true);
710
+ this.view.setBigUint64(this.offset + 8 * 2, p2, true);
711
+ this.view.setBigInt64(this.offset + 8 * 3, p3, true);
712
+ this.offset += 32;
713
+ }
714
+ writeF32(value) {
715
+ this.expandBuffer(4);
716
+ this.view.setFloat32(this.offset, value, true);
717
+ this.offset += 4;
718
+ }
719
+ writeF64(value) {
720
+ this.expandBuffer(8);
721
+ this.view.setFloat64(this.offset, value, true);
722
+ this.offset += 8;
723
+ }
724
+ writeString(value) {
725
+ const encoder = new TextEncoder();
726
+ const encodedString = encoder.encode(value);
727
+ this.writeUInt8Array(encodedString);
728
+ }
729
+ };
730
+
731
+ // src/lib/util.ts
732
+ function uint8ArrayToHexString(array) {
733
+ return Array.prototype.map.call(array.reverse(), (x) => ("00" + x.toString(16)).slice(-2)).join("");
734
+ }
735
+ function uint8ArrayToU128(array) {
736
+ if (array.length != 16) {
737
+ throw new Error(`Uint8Array is not 16 bytes long: ${array}`);
738
+ }
739
+ return new BinaryReader(array).readU128();
740
+ }
741
+ function uint8ArrayToU256(array) {
742
+ if (array.length != 32) {
743
+ throw new Error(`Uint8Array is not 32 bytes long: [${array}]`);
744
+ }
745
+ return new BinaryReader(array).readU256();
746
+ }
747
+ function hexStringToUint8Array(str) {
748
+ if (str.startsWith("0x")) {
749
+ str = str.slice(2);
750
+ }
751
+ const matches = str.match(/.{1,2}/g) || [];
752
+ const data = Uint8Array.from(
753
+ matches.map((byte) => parseInt(byte, 16))
754
+ );
755
+ return data.reverse();
756
+ }
757
+ function hexStringToU128(str) {
758
+ return uint8ArrayToU128(hexStringToUint8Array(str));
759
+ }
760
+ function hexStringToU256(str) {
761
+ return uint8ArrayToU256(hexStringToUint8Array(str));
762
+ }
763
+ function u128ToUint8Array(data) {
764
+ const writer = new BinaryWriter(16);
765
+ writer.writeU128(data);
766
+ return writer.getBuffer();
767
+ }
768
+ function u128ToHexString(data) {
769
+ return uint8ArrayToHexString(u128ToUint8Array(data));
770
+ }
771
+ function u256ToUint8Array(data) {
772
+ const writer = new BinaryWriter(32);
773
+ writer.writeU256(data);
774
+ return writer.getBuffer();
775
+ }
776
+ function u256ToHexString(data) {
777
+ return uint8ArrayToHexString(u256ToUint8Array(data));
778
+ }
779
+ var hasOwn = Object.hasOwn;
780
+
781
+ // src/lib/identity.ts
782
+ var Identity = class _Identity {
783
+ __identity__;
784
+ /**
785
+ * Creates a new `Identity`.
786
+ *
787
+ * `data` can be a hexadecimal string or a `bigint`.
788
+ */
789
+ constructor(data) {
790
+ this.__identity__ = typeof data === "string" ? hexStringToU256(data) : data;
791
+ }
792
+ /**
793
+ * Get the algebraic type representation of the {@link Identity} type.
794
+ * @returns The algebraic type representation of the type.
795
+ */
796
+ static getAlgebraicType() {
797
+ return AlgebraicType.Product({
798
+ elements: [{ name: "__identity__", algebraicType: AlgebraicType.U256 }]
799
+ });
800
+ }
801
+ /**
802
+ * Check if two identities are equal.
803
+ */
804
+ isEqual(other) {
805
+ return this.toHexString() === other.toHexString();
806
+ }
807
+ /**
808
+ * Check if two identities are equal.
809
+ */
810
+ equals(other) {
811
+ return this.isEqual(other);
812
+ }
813
+ /**
814
+ * Print the identity as a hexadecimal string.
815
+ */
816
+ toHexString() {
817
+ return u256ToHexString(this.__identity__);
818
+ }
819
+ /**
820
+ * Convert the address to a Uint8Array.
821
+ */
822
+ toUint8Array() {
823
+ return u256ToUint8Array(this.__identity__);
824
+ }
825
+ /**
826
+ * Parse an Identity from a hexadecimal string.
827
+ */
828
+ static fromString(str) {
829
+ return new _Identity(str);
830
+ }
831
+ /**
832
+ * Zero identity (0x0000000000000000000000000000000000000000000000000000000000000000)
833
+ */
834
+ static zero() {
835
+ return new _Identity(0n);
836
+ }
837
+ toString() {
838
+ return this.toHexString();
839
+ }
840
+ };
841
+
842
+ // src/lib/algebraic_type.ts
843
+ var SERIALIZERS = /* @__PURE__ */ new Map();
844
+ var DESERIALIZERS = /* @__PURE__ */ new Map();
845
+ var AlgebraicType = {
846
+ Ref: (value) => ({ tag: "Ref", value }),
847
+ Sum: (value) => ({
848
+ tag: "Sum",
849
+ value
850
+ }),
851
+ Product: (value) => ({
852
+ tag: "Product",
853
+ value
854
+ }),
855
+ Array: (value) => ({
856
+ tag: "Array",
857
+ value
858
+ }),
859
+ String: { tag: "String" },
860
+ Bool: { tag: "Bool" },
861
+ I8: { tag: "I8" },
862
+ U8: { tag: "U8" },
863
+ I16: { tag: "I16" },
864
+ U16: { tag: "U16" },
865
+ I32: { tag: "I32" },
866
+ U32: { tag: "U32" },
867
+ I64: { tag: "I64" },
868
+ U64: { tag: "U64" },
869
+ I128: { tag: "I128" },
870
+ U128: { tag: "U128" },
871
+ I256: { tag: "I256" },
872
+ U256: { tag: "U256" },
873
+ F32: { tag: "F32" },
874
+ F64: { tag: "F64" },
875
+ makeSerializer(ty, typespace) {
876
+ if (ty.tag === "Ref") {
877
+ if (!typespace)
878
+ throw new Error("cannot serialize refs without a typespace");
879
+ while (ty.tag === "Ref") ty = typespace.types[ty.value];
880
+ }
881
+ switch (ty.tag) {
882
+ case "Product":
883
+ return ProductType.makeSerializer(ty.value, typespace);
884
+ case "Sum":
885
+ return SumType.makeSerializer(ty.value, typespace);
886
+ case "Array":
887
+ if (ty.value.tag === "U8") {
888
+ return serializeUint8Array;
889
+ } else {
890
+ const serialize = AlgebraicType.makeSerializer(ty.value, typespace);
891
+ return (writer, value) => {
892
+ writer.writeU32(value.length);
893
+ for (const elem of value) {
894
+ serialize(writer, elem);
895
+ }
896
+ };
897
+ }
898
+ default:
899
+ return primitiveSerializers[ty.tag];
900
+ }
901
+ },
902
+ /** @deprecated Use `makeSerializer` instead. */
903
+ serializeValue(writer, ty, value, typespace) {
904
+ AlgebraicType.makeSerializer(ty, typespace)(writer, value);
905
+ },
906
+ makeDeserializer(ty, typespace) {
907
+ if (ty.tag === "Ref") {
908
+ if (!typespace)
909
+ throw new Error("cannot deserialize refs without a typespace");
910
+ while (ty.tag === "Ref") ty = typespace.types[ty.value];
911
+ }
912
+ switch (ty.tag) {
913
+ case "Product":
914
+ return ProductType.makeDeserializer(ty.value, typespace);
915
+ case "Sum":
916
+ return SumType.makeDeserializer(ty.value, typespace);
917
+ case "Array":
918
+ if (ty.value.tag === "U8") {
919
+ return deserializeUint8Array;
920
+ } else {
921
+ const deserialize = AlgebraicType.makeDeserializer(
922
+ ty.value,
923
+ typespace
924
+ );
925
+ return (reader) => {
926
+ const length = reader.readU32();
927
+ const result = Array(length);
928
+ for (let i = 0; i < length; i++) {
929
+ result[i] = deserialize(reader);
930
+ }
931
+ return result;
932
+ };
933
+ }
934
+ default:
935
+ return primitiveDeserializers[ty.tag];
936
+ }
937
+ },
938
+ /** @deprecated Use `makeDeserializer` instead. */
939
+ deserializeValue(reader, ty, typespace) {
940
+ return AlgebraicType.makeDeserializer(ty, typespace)(reader);
941
+ },
942
+ /**
943
+ * Convert a value of the algebraic type into something that can be used as a key in a map.
944
+ * There are no guarantees about being able to order it.
945
+ * This is only guaranteed to be comparable to other values of the same type.
946
+ * @param value A value of the algebraic type
947
+ * @returns Something that can be used as a key in a map.
948
+ */
949
+ intoMapKey: function(ty, value) {
950
+ switch (ty.tag) {
951
+ case "U8":
952
+ case "U16":
953
+ case "U32":
954
+ case "U64":
955
+ case "U128":
956
+ case "U256":
957
+ case "I8":
958
+ case "I16":
959
+ case "I32":
960
+ case "I64":
961
+ case "I128":
962
+ case "I256":
963
+ case "F32":
964
+ case "F64":
965
+ case "String":
966
+ case "Bool":
967
+ return value;
968
+ case "Product":
969
+ return ProductType.intoMapKey(ty.value, value);
970
+ default: {
971
+ const writer = new BinaryWriter(10);
972
+ AlgebraicType.serializeValue(writer, ty, value);
973
+ return writer.toBase64();
974
+ }
975
+ }
976
+ }
977
+ };
978
+ function bindCall(f) {
979
+ return Function.prototype.call.bind(f);
980
+ }
981
+ var primitiveSerializers = {
982
+ Bool: bindCall(BinaryWriter.prototype.writeBool),
983
+ I8: bindCall(BinaryWriter.prototype.writeI8),
984
+ U8: bindCall(BinaryWriter.prototype.writeU8),
985
+ I16: bindCall(BinaryWriter.prototype.writeI16),
986
+ U16: bindCall(BinaryWriter.prototype.writeU16),
987
+ I32: bindCall(BinaryWriter.prototype.writeI32),
988
+ U32: bindCall(BinaryWriter.prototype.writeU32),
989
+ I64: bindCall(BinaryWriter.prototype.writeI64),
990
+ U64: bindCall(BinaryWriter.prototype.writeU64),
991
+ I128: bindCall(BinaryWriter.prototype.writeI128),
992
+ U128: bindCall(BinaryWriter.prototype.writeU128),
993
+ I256: bindCall(BinaryWriter.prototype.writeI256),
994
+ U256: bindCall(BinaryWriter.prototype.writeU256),
995
+ F32: bindCall(BinaryWriter.prototype.writeF32),
996
+ F64: bindCall(BinaryWriter.prototype.writeF64),
997
+ String: bindCall(BinaryWriter.prototype.writeString)
998
+ };
999
+ Object.freeze(primitiveSerializers);
1000
+ var serializeUint8Array = bindCall(BinaryWriter.prototype.writeUInt8Array);
1001
+ var primitiveDeserializers = {
1002
+ Bool: bindCall(BinaryReader.prototype.readBool),
1003
+ I8: bindCall(BinaryReader.prototype.readI8),
1004
+ U8: bindCall(BinaryReader.prototype.readU8),
1005
+ I16: bindCall(BinaryReader.prototype.readI16),
1006
+ U16: bindCall(BinaryReader.prototype.readU16),
1007
+ I32: bindCall(BinaryReader.prototype.readI32),
1008
+ U32: bindCall(BinaryReader.prototype.readU32),
1009
+ I64: bindCall(BinaryReader.prototype.readI64),
1010
+ U64: bindCall(BinaryReader.prototype.readU64),
1011
+ I128: bindCall(BinaryReader.prototype.readI128),
1012
+ U128: bindCall(BinaryReader.prototype.readU128),
1013
+ I256: bindCall(BinaryReader.prototype.readI256),
1014
+ U256: bindCall(BinaryReader.prototype.readU256),
1015
+ F32: bindCall(BinaryReader.prototype.readF32),
1016
+ F64: bindCall(BinaryReader.prototype.readF64),
1017
+ String: bindCall(BinaryReader.prototype.readString)
1018
+ };
1019
+ Object.freeze(primitiveDeserializers);
1020
+ var deserializeUint8Array = bindCall(BinaryReader.prototype.readUInt8Array);
1021
+ var primitiveSizes = {
1022
+ Bool: 1,
1023
+ I8: 1,
1024
+ U8: 1,
1025
+ I16: 2,
1026
+ U16: 2,
1027
+ I32: 4,
1028
+ U32: 4,
1029
+ I64: 8,
1030
+ U64: 8,
1031
+ I128: 16,
1032
+ U128: 16,
1033
+ I256: 32,
1034
+ U256: 32,
1035
+ F32: 4,
1036
+ F64: 8
1037
+ };
1038
+ var fixedSizePrimitives = new Set(Object.keys(primitiveSizes));
1039
+ var isFixedSizeProduct = (ty) => ty.elements.every(
1040
+ ({ algebraicType }) => fixedSizePrimitives.has(algebraicType.tag)
1041
+ );
1042
+ var productSize = (ty) => ty.elements.reduce(
1043
+ (acc, { algebraicType }) => acc + primitiveSizes[algebraicType.tag],
1044
+ 0
1045
+ );
1046
+ var primitiveJSName = {
1047
+ Bool: "Uint8",
1048
+ I8: "Int8",
1049
+ U8: "Uint8",
1050
+ I16: "Int16",
1051
+ U16: "Uint16",
1052
+ I32: "Int32",
1053
+ U32: "Uint32",
1054
+ I64: "BigInt64",
1055
+ U64: "BigUint64",
1056
+ F32: "Float32",
1057
+ F64: "Float64"
1058
+ };
1059
+ var specialProductDeserializers = {
1060
+ __time_duration_micros__: (reader) => new TimeDuration(reader.readI64()),
1061
+ __timestamp_micros_since_unix_epoch__: (reader) => new Timestamp(reader.readI64()),
1062
+ __identity__: (reader) => new Identity(reader.readU256()),
1063
+ __connection_id__: (reader) => new ConnectionId(reader.readU128()),
1064
+ __uuid__: (reader) => new Uuid(reader.readU128())
1065
+ };
1066
+ Object.freeze(specialProductDeserializers);
1067
+ var unitDeserializer = () => ({});
1068
+ var getElementInitializer = (element) => {
1069
+ let init;
1070
+ switch (element.algebraicType.tag) {
1071
+ case "String":
1072
+ init = "''";
1073
+ break;
1074
+ case "Bool":
1075
+ init = "false";
1076
+ break;
1077
+ case "I8":
1078
+ case "U8":
1079
+ case "I16":
1080
+ case "U16":
1081
+ case "I32":
1082
+ case "U32":
1083
+ init = "0";
1084
+ break;
1085
+ case "I64":
1086
+ case "U64":
1087
+ case "I128":
1088
+ case "U128":
1089
+ case "I256":
1090
+ case "U256":
1091
+ init = "0n";
1092
+ break;
1093
+ case "F32":
1094
+ case "F64":
1095
+ init = "0.0";
1096
+ break;
1097
+ default:
1098
+ init = "undefined";
1099
+ }
1100
+ return `${element.name}: ${init}`;
1101
+ };
1102
+ var ProductType = {
1103
+ makeSerializer(ty, typespace) {
1104
+ let serializer = SERIALIZERS.get(ty);
1105
+ if (serializer != null) return serializer;
1106
+ if (isFixedSizeProduct(ty)) {
1107
+ const size = productSize(ty);
1108
+ const body2 = `"use strict";
1109
+ writer.expandBuffer(${size});
1110
+ const view = writer.view;
1111
+ ${ty.elements.map(
1112
+ ({ name, algebraicType: { tag } }) => tag in primitiveJSName ? `view.set${primitiveJSName[tag]}(writer.offset, value.${name}, ${primitiveSizes[tag] > 1 ? "true" : ""});
1113
+ writer.offset += ${primitiveSizes[tag]};` : `writer.write${tag}(value.${name});`
1114
+ ).join("\n")}`;
1115
+ serializer = Function("writer", "value", body2);
1116
+ SERIALIZERS.set(ty, serializer);
1117
+ return serializer;
1118
+ }
1119
+ const serializers = {};
1120
+ const body = '"use strict";\n' + ty.elements.map(
1121
+ (element) => `this.${element.name}(writer, value.${element.name});`
1122
+ ).join("\n");
1123
+ serializer = Function("writer", "value", body).bind(
1124
+ serializers
1125
+ );
1126
+ SERIALIZERS.set(ty, serializer);
1127
+ for (const { name, algebraicType } of ty.elements) {
1128
+ serializers[name] = AlgebraicType.makeSerializer(
1129
+ algebraicType,
1130
+ typespace
1131
+ );
1132
+ }
1133
+ Object.freeze(serializers);
1134
+ return serializer;
1135
+ },
1136
+ /** @deprecated Use `makeSerializer` instead. */
1137
+ serializeValue(writer, ty, value, typespace) {
1138
+ ProductType.makeSerializer(ty, typespace)(writer, value);
1139
+ },
1140
+ makeDeserializer(ty, typespace) {
1141
+ switch (ty.elements.length) {
1142
+ case 0:
1143
+ return unitDeserializer;
1144
+ case 1: {
1145
+ const fieldName = ty.elements[0].name;
1146
+ if (hasOwn(specialProductDeserializers, fieldName))
1147
+ return specialProductDeserializers[fieldName];
1148
+ }
1149
+ }
1150
+ let deserializer = DESERIALIZERS.get(ty);
1151
+ if (deserializer != null) return deserializer;
1152
+ if (isFixedSizeProduct(ty)) {
1153
+ const body = `"use strict";
1154
+ const result = { ${ty.elements.map(getElementInitializer).join(", ")} };
1155
+ const view = reader.view;
1156
+ ${ty.elements.map(
1157
+ ({ name, algebraicType: { tag } }) => tag in primitiveJSName ? tag === "Bool" ? `result.${name} = view.getUint8(reader.offset) !== 0;
1158
+ reader.offset += 1;` : `result.${name} = view.get${primitiveJSName[tag]}(reader.offset, ${primitiveSizes[tag] > 1 ? "true" : ""});
1159
+ reader.offset += ${primitiveSizes[tag]};` : `result.${name} = reader.read${tag}();`
1160
+ ).join("\n")}
1161
+ return result;`;
1162
+ deserializer = Function("reader", body);
1163
+ DESERIALIZERS.set(ty, deserializer);
1164
+ return deserializer;
1165
+ }
1166
+ const deserializers = {};
1167
+ deserializer = Function(
1168
+ "reader",
1169
+ `"use strict";
1170
+ const result = { ${ty.elements.map(getElementInitializer).join(", ")} };
1171
+ ${ty.elements.map(({ name }) => `result.${name} = this.${name}(reader);`).join("\n")}
1172
+ return result;`
1173
+ ).bind(deserializers);
1174
+ DESERIALIZERS.set(ty, deserializer);
1175
+ for (const { name, algebraicType } of ty.elements) {
1176
+ deserializers[name] = AlgebraicType.makeDeserializer(
1177
+ algebraicType,
1178
+ typespace
1179
+ );
1180
+ }
1181
+ Object.freeze(deserializers);
1182
+ return deserializer;
1183
+ },
1184
+ /** @deprecated Use `makeDeserializer` instead. */
1185
+ deserializeValue(reader, ty, typespace) {
1186
+ return ProductType.makeDeserializer(ty, typespace)(reader);
1187
+ },
1188
+ intoMapKey(ty, value) {
1189
+ if (ty.elements.length === 1) {
1190
+ const fieldName = ty.elements[0].name;
1191
+ if (hasOwn(specialProductDeserializers, fieldName)) {
1192
+ return value[fieldName];
1193
+ }
1194
+ }
1195
+ const writer = new BinaryWriter(10);
1196
+ AlgebraicType.serializeValue(writer, AlgebraicType.Product(ty), value);
1197
+ return writer.toBase64();
1198
+ }
1199
+ };
1200
+ var SumType = {
1201
+ makeSerializer(ty, typespace) {
1202
+ if (ty.variants.length == 2 && ty.variants[0].name === "some" && ty.variants[1].name === "none") {
1203
+ const serialize = AlgebraicType.makeSerializer(
1204
+ ty.variants[0].algebraicType,
1205
+ typespace
1206
+ );
1207
+ return (writer, value) => {
1208
+ if (value !== null && value !== void 0) {
1209
+ writer.writeByte(0);
1210
+ serialize(writer, value);
1211
+ } else {
1212
+ writer.writeByte(1);
1213
+ }
1214
+ };
1215
+ } else if (ty.variants.length == 2 && ty.variants[0].name === "ok" && ty.variants[1].name === "err") {
1216
+ const serializeOk = AlgebraicType.makeSerializer(
1217
+ ty.variants[0].algebraicType,
1218
+ typespace
1219
+ );
1220
+ const serializeErr = AlgebraicType.makeSerializer(
1221
+ ty.variants[0].algebraicType,
1222
+ typespace
1223
+ );
1224
+ return (writer, value) => {
1225
+ if ("ok" in value) {
1226
+ writer.writeU8(0);
1227
+ serializeOk(writer, value.ok);
1228
+ } else if ("err" in value) {
1229
+ writer.writeU8(1);
1230
+ serializeErr(writer, value.err);
1231
+ } else {
1232
+ throw new TypeError(
1233
+ "could not serialize result: object had neither a `ok` nor an `err` field"
1234
+ );
1235
+ }
1236
+ };
1237
+ } else {
1238
+ let serializer = SERIALIZERS.get(ty);
1239
+ if (serializer != null) return serializer;
1240
+ const serializers = {};
1241
+ const body = `switch (value.tag) {
1242
+ ${ty.variants.map(
1243
+ ({ name }, i) => ` case ${JSON.stringify(name)}:
1244
+ writer.writeByte(${i});
1245
+ return this.${name}(writer, value.value);`
1246
+ ).join("\n")}
1247
+ default:
1248
+ throw new TypeError(
1249
+ \`Could not serialize sum type; unknown tag \${value.tag}\`
1250
+ )
1251
+ }
1252
+ `;
1253
+ serializer = Function("writer", "value", body).bind(
1254
+ serializers
1255
+ );
1256
+ SERIALIZERS.set(ty, serializer);
1257
+ for (const { name, algebraicType } of ty.variants) {
1258
+ serializers[name] = AlgebraicType.makeSerializer(
1259
+ algebraicType,
1260
+ typespace
1261
+ );
1262
+ }
1263
+ Object.freeze(serializers);
1264
+ return serializer;
1265
+ }
1266
+ },
1267
+ /** @deprecated Use `makeSerializer` instead. */
1268
+ serializeValue(writer, ty, value, typespace) {
1269
+ SumType.makeSerializer(ty, typespace)(writer, value);
1270
+ },
1271
+ makeDeserializer(ty, typespace) {
1272
+ if (ty.variants.length == 2 && ty.variants[0].name === "some" && ty.variants[1].name === "none") {
1273
+ const deserialize = AlgebraicType.makeDeserializer(
1274
+ ty.variants[0].algebraicType,
1275
+ typespace
1276
+ );
1277
+ return (reader) => {
1278
+ const tag = reader.readU8();
1279
+ if (tag === 0) {
1280
+ return deserialize(reader);
1281
+ } else if (tag === 1) {
1282
+ return void 0;
1283
+ } else {
1284
+ throw `Can't deserialize an option type, couldn't find ${tag} tag`;
1285
+ }
1286
+ };
1287
+ } else if (ty.variants.length == 2 && ty.variants[0].name === "ok" && ty.variants[1].name === "err") {
1288
+ const deserializeOk = AlgebraicType.makeDeserializer(
1289
+ ty.variants[0].algebraicType,
1290
+ typespace
1291
+ );
1292
+ const deserializeErr = AlgebraicType.makeDeserializer(
1293
+ ty.variants[1].algebraicType,
1294
+ typespace
1295
+ );
1296
+ return (reader) => {
1297
+ const tag = reader.readByte();
1298
+ if (tag === 0) {
1299
+ return { ok: deserializeOk(reader) };
1300
+ } else if (tag === 1) {
1301
+ return { err: deserializeErr(reader) };
1302
+ } else {
1303
+ throw `Can't deserialize a result type, couldn't find ${tag} tag`;
1304
+ }
1305
+ };
1306
+ } else {
1307
+ let deserializer = DESERIALIZERS.get(ty);
1308
+ if (deserializer != null) return deserializer;
1309
+ const deserializers = {};
1310
+ deserializer = Function(
1311
+ "reader",
1312
+ `switch (reader.readU8()) {
1313
+ ${ty.variants.map(
1314
+ ({ name }, i) => `case ${i}: return { tag: ${JSON.stringify(name)}, value: this.${name}(reader) };`
1315
+ ).join("\n")} }`
1316
+ ).bind(deserializers);
1317
+ DESERIALIZERS.set(ty, deserializer);
1318
+ for (const { name, algebraicType } of ty.variants) {
1319
+ deserializers[name] = AlgebraicType.makeDeserializer(
1320
+ algebraicType,
1321
+ typespace
1322
+ );
1323
+ }
1324
+ Object.freeze(deserializers);
1325
+ return deserializer;
1326
+ }
1327
+ },
1328
+ /** @deprecated Use `makeDeserializer` instead. */
1329
+ deserializeValue(reader, ty, typespace) {
1330
+ return SumType.makeDeserializer(ty, typespace)(reader);
1331
+ }
1332
+ };
1333
+
1334
+ // src/lib/connection_id.ts
1335
+ var ConnectionId = class _ConnectionId {
1336
+ __connection_id__;
1337
+ /**
1338
+ * Creates a new `ConnectionId`.
1339
+ */
1340
+ constructor(data) {
1341
+ this.__connection_id__ = data;
1342
+ }
1343
+ /**
1344
+ * Get the algebraic type representation of the {@link ConnectionId} type.
1345
+ * @returns The algebraic type representation of the type.
1346
+ */
1347
+ static getAlgebraicType() {
1348
+ return AlgebraicType.Product({
1349
+ elements: [
1350
+ { name: "__connection_id__", algebraicType: AlgebraicType.U128 }
1351
+ ]
1352
+ });
1353
+ }
1354
+ isZero() {
1355
+ return this.__connection_id__ === BigInt(0);
1356
+ }
1357
+ static nullIfZero(addr) {
1358
+ if (addr.isZero()) {
1359
+ return null;
1360
+ } else {
1361
+ return addr;
1362
+ }
1363
+ }
1364
+ static random() {
1365
+ function randomU8() {
1366
+ return Math.floor(Math.random() * 255);
1367
+ }
1368
+ let result = BigInt(0);
1369
+ for (let i = 0; i < 16; i++) {
1370
+ result = result << BigInt(8) | BigInt(randomU8());
1371
+ }
1372
+ return new _ConnectionId(result);
1373
+ }
1374
+ /**
1375
+ * Compare two connection IDs for equality.
1376
+ */
1377
+ isEqual(other) {
1378
+ return this.__connection_id__ == other.__connection_id__;
1379
+ }
1380
+ /**
1381
+ * Check if two connection IDs are equal.
1382
+ */
1383
+ equals(other) {
1384
+ return this.isEqual(other);
1385
+ }
1386
+ /**
1387
+ * Print the connection ID as a hexadecimal string.
1388
+ */
1389
+ toHexString() {
1390
+ return u128ToHexString(this.__connection_id__);
1391
+ }
1392
+ /**
1393
+ * Convert the connection ID to a Uint8Array.
1394
+ */
1395
+ toUint8Array() {
1396
+ return u128ToUint8Array(this.__connection_id__);
1397
+ }
1398
+ /**
1399
+ * Parse a connection ID from a hexadecimal string.
1400
+ */
1401
+ static fromString(str) {
1402
+ return new _ConnectionId(hexStringToU128(str));
1403
+ }
1404
+ static fromStringOrNull(str) {
1405
+ const addr = _ConnectionId.fromString(str);
1406
+ if (addr.isZero()) {
1407
+ return null;
1408
+ } else {
1409
+ return addr;
1410
+ }
1411
+ }
1412
+ };
1413
+ function toSql(q) {
1414
+ return q.toSql();
1415
+ }
1416
+ function isLiteralExpr(expr) {
1417
+ return expr.type === "literal";
1418
+ }
1419
+ function evaluateBooleanExpr(expr, row) {
1420
+ return evaluateData(expr.data, row);
1421
+ }
1422
+ function evaluateData(data, row) {
1423
+ switch (data.type) {
1424
+ case "eq":
1425
+ return resolveValue(data.left, row) === resolveValue(data.right, row);
1426
+ case "ne":
1427
+ return resolveValue(data.left, row) !== resolveValue(data.right, row);
1428
+ case "gt":
1429
+ return resolveValue(data.left, row) > resolveValue(data.right, row);
1430
+ case "gte":
1431
+ return resolveValue(data.left, row) >= resolveValue(data.right, row);
1432
+ case "lt":
1433
+ return resolveValue(data.left, row) < resolveValue(data.right, row);
1434
+ case "lte":
1435
+ return resolveValue(data.left, row) <= resolveValue(data.right, row);
1436
+ case "and":
1437
+ return data.clauses.every((c) => evaluateData(c, row));
1438
+ case "or":
1439
+ return data.clauses.some((c) => evaluateData(c, row));
1440
+ case "not":
1441
+ return !evaluateData(data.clause, row);
1442
+ }
1443
+ }
1444
+ function resolveValue(expr, row) {
1445
+ if (isLiteralExpr(expr)) {
1446
+ return toComparableValue(expr.value);
1447
+ }
1448
+ return toComparableValue(row[expr.column]);
1449
+ }
1450
+ function isHexSerializableLike(value) {
1451
+ return !!value && typeof value === "object" && typeof value.toHexString === "function";
1452
+ }
1453
+ function isTimestampLike(value) {
1454
+ if (!value || typeof value !== "object") return false;
1455
+ if (value instanceof Timestamp) return true;
1456
+ const micros = value["__timestamp_micros_since_unix_epoch__"];
1457
+ return typeof micros === "bigint";
1458
+ }
1459
+ function toComparableValue(value) {
1460
+ if (isHexSerializableLike(value)) {
1461
+ return value.toHexString();
1462
+ }
1463
+ if (isTimestampLike(value)) {
1464
+ return value.__timestamp_micros_since_unix_epoch__;
1465
+ }
1466
+ return value;
1467
+ }
1468
+ function getQueryAccessorName(query) {
1469
+ if (query.table) return query.table.accessorName;
1470
+ if (query.accessorName) return query.accessorName;
1471
+ if (query.sourceQuery) return query.sourceQuery.table.accessorName;
1472
+ throw new Error("Cannot extract accessor name from query");
1473
+ }
1474
+ function getQueryWhereClause(query) {
1475
+ if (query.whereClause) return query.whereClause;
1476
+ return void 0;
1477
+ }
1478
+ var SpacetimeDBContext = solidJs.createContext(
1479
+ void 0
1480
+ );
1481
+ function useSpacetimeDB() {
1482
+ const context = solidJs.useContext(SpacetimeDBContext);
1483
+ if (!context) {
1484
+ throw new Error(
1485
+ "useSpacetimeDB must be used within a SpacetimeDBProvider component. Did you forget to add a `SpacetimeDBProvider` to your component tree?"
1486
+ );
1487
+ }
1488
+ return context;
1489
+ }
1490
+
1491
+ // src/sdk/connection_manager.ts
1492
+ var CONNECTION_MANAGER_RECONNECT_BASE_DELAY_MS = 1e3;
1493
+ var CONNECTION_MANAGER_RECONNECT_MAX_DELAY_MS = 3e4;
1494
+ function connectionManagerReconnectDelayMs(attempt) {
1495
+ return Math.min(
1496
+ CONNECTION_MANAGER_RECONNECT_BASE_DELAY_MS * 2 ** attempt,
1497
+ CONNECTION_MANAGER_RECONNECT_MAX_DELAY_MS
1498
+ );
1499
+ }
1500
+ function defaultState() {
1501
+ return {
1502
+ isActive: false,
1503
+ identity: void 0,
1504
+ token: void 0,
1505
+ connectionId: ConnectionId.random(),
1506
+ connectionError: void 0
1507
+ };
1508
+ }
1509
+ var ConnectionManagerImpl = class _ConnectionManagerImpl {
1510
+ #connections = /* @__PURE__ */ new Map();
1511
+ /** Generates a unique key for a connection based on URI and module name. */
1512
+ static getKey(uri, moduleName) {
1513
+ return `${uri}::${moduleName}`;
1514
+ }
1515
+ /** Instance method wrapper for getKey. */
1516
+ getKey(uri, moduleName) {
1517
+ return _ConnectionManagerImpl.getKey(uri, moduleName);
1518
+ }
1519
+ #ensureEntry(key) {
1520
+ const existing = this.#connections.get(key);
1521
+ if (existing) {
1522
+ return existing;
1523
+ }
1524
+ const managed = {
1525
+ connection: void 0,
1526
+ builder: void 0,
1527
+ refCount: 0,
1528
+ state: defaultState(),
1529
+ listeners: /* @__PURE__ */ new Set(),
1530
+ pendingRelease: null,
1531
+ reconnectTimer: null,
1532
+ reconnectAttempt: 0
1533
+ };
1534
+ this.#connections.set(key, managed);
1535
+ return managed;
1536
+ }
1537
+ #notify(managed) {
1538
+ for (const listener of managed.listeners) {
1539
+ listener();
1540
+ }
1541
+ }
1542
+ #updateState(managed, updates) {
1543
+ managed.state = { ...managed.state, ...updates };
1544
+ this.#notify(managed);
1545
+ }
1546
+ #ensureCallbacks(managed) {
1547
+ if (managed.onConnect) {
1548
+ return;
1549
+ }
1550
+ managed.onConnect = (conn) => {
1551
+ if (conn !== managed.connection) {
1552
+ return;
1553
+ }
1554
+ managed.reconnectAttempt = 0;
1555
+ this.#updateState(managed, {
1556
+ isActive: conn.isActive,
1557
+ identity: conn.identity,
1558
+ token: conn.token,
1559
+ connectionId: conn.connectionId,
1560
+ connectionError: void 0
1561
+ });
1562
+ };
1563
+ managed.onDisconnect = (ctx, error) => {
1564
+ if (ctx !== managed.connection) {
1565
+ return;
1566
+ }
1567
+ this.#updateState(managed, {
1568
+ isActive: false,
1569
+ connectionError: error ?? void 0
1570
+ });
1571
+ this.#scheduleReconnect(managed);
1572
+ };
1573
+ managed.onConnectError = (ctx, error) => {
1574
+ if (ctx !== managed.connection) {
1575
+ return;
1576
+ }
1577
+ this.#updateState(managed, {
1578
+ isActive: false,
1579
+ connectionError: error
1580
+ });
1581
+ this.#scheduleReconnect(managed);
1582
+ };
1583
+ }
1584
+ #attachCallbacks(managed, builder) {
1585
+ this.#ensureCallbacks(managed);
1586
+ builder.onConnect(managed.onConnect);
1587
+ builder.onDisconnect(managed.onDisconnect);
1588
+ builder.onConnectError(managed.onConnectError);
1589
+ }
1590
+ #detachCallbacks(managed, connection) {
1591
+ if (managed.onConnect) {
1592
+ connection.removeOnConnect(managed.onConnect);
1593
+ }
1594
+ if (managed.onDisconnect) {
1595
+ connection.removeOnDisconnect(managed.onDisconnect);
1596
+ }
1597
+ if (managed.onConnectError) {
1598
+ connection.removeOnConnectError(managed.onConnectError);
1599
+ }
1600
+ }
1601
+ #buildManagedConnection(managed, builder) {
1602
+ managed.builder = builder;
1603
+ const connection = builder.build();
1604
+ managed.connection = connection;
1605
+ this.#attachCallbacks(managed, builder);
1606
+ this.#updateState(managed, {
1607
+ isActive: connection.isActive,
1608
+ identity: connection.identity,
1609
+ token: connection.token,
1610
+ connectionId: connection.connectionId,
1611
+ connectionError: void 0
1612
+ });
1613
+ return connection;
1614
+ }
1615
+ #scheduleReconnect(managed) {
1616
+ if (managed.refCount <= 0 || managed.pendingRelease || managed.reconnectTimer || !managed.builder) {
1617
+ return;
1618
+ }
1619
+ const connection = managed.connection;
1620
+ if (connection) {
1621
+ this.#detachCallbacks(managed, connection);
1622
+ }
1623
+ managed.connection = void 0;
1624
+ if (connection?.isDisconnectRequested) {
1625
+ return;
1626
+ }
1627
+ const delay = connectionManagerReconnectDelayMs(managed.reconnectAttempt);
1628
+ managed.reconnectAttempt += 1;
1629
+ managed.reconnectTimer = setTimeout(() => {
1630
+ managed.reconnectTimer = null;
1631
+ if (managed.refCount <= 0 || managed.pendingRelease || managed.connection || !managed.builder) {
1632
+ return;
1633
+ }
1634
+ this.#buildManagedConnection(managed, managed.builder);
1635
+ }, delay);
1636
+ }
1637
+ /**
1638
+ * Retains a connection, incrementing its reference count.
1639
+ * Creates the connection on first call; returns existing connection on subsequent calls.
1640
+ * Cancels any pending release if the connection was about to be cleaned up.
1641
+ *
1642
+ * @param key - Unique identifier for the connection (use getKey to generate)
1643
+ * @param builder - Connection builder to create the connection if needed
1644
+ * @returns The managed connection instance
1645
+ */
1646
+ retain(key, builder) {
1647
+ const managed = this.#ensureEntry(key);
1648
+ if (managed.pendingRelease) {
1649
+ clearTimeout(managed.pendingRelease);
1650
+ managed.pendingRelease = null;
1651
+ }
1652
+ if (managed.reconnectTimer) {
1653
+ clearTimeout(managed.reconnectTimer);
1654
+ managed.reconnectTimer = null;
1655
+ }
1656
+ managed.refCount += 1;
1657
+ managed.builder = builder;
1658
+ if (managed.connection) {
1659
+ return managed.connection;
1660
+ }
1661
+ return this.#buildManagedConnection(managed, builder);
1662
+ }
1663
+ release(key) {
1664
+ const managed = this.#connections.get(key);
1665
+ if (!managed) {
1666
+ return;
1667
+ }
1668
+ managed.refCount -= 1;
1669
+ if (managed.refCount > 0 || managed.pendingRelease) {
1670
+ return;
1671
+ }
1672
+ if (managed.reconnectTimer) {
1673
+ clearTimeout(managed.reconnectTimer);
1674
+ managed.reconnectTimer = null;
1675
+ }
1676
+ managed.pendingRelease = setTimeout(() => {
1677
+ managed.pendingRelease = null;
1678
+ if (managed.refCount > 0) {
1679
+ return;
1680
+ }
1681
+ const connection = managed.connection;
1682
+ managed.connection = void 0;
1683
+ if (connection) {
1684
+ this.#detachCallbacks(managed, connection);
1685
+ connection.disconnect();
1686
+ }
1687
+ this.#connections.delete(key);
1688
+ }, 0);
1689
+ }
1690
+ subscribe(key, listener) {
1691
+ const managed = this.#ensureEntry(key);
1692
+ managed.listeners.add(listener);
1693
+ return () => {
1694
+ managed.listeners.delete(listener);
1695
+ if (managed.refCount <= 0 && managed.listeners.size === 0 && !managed.connection) {
1696
+ this.#connections.delete(key);
1697
+ }
1698
+ };
1699
+ }
1700
+ getSnapshot(key) {
1701
+ return this.#connections.get(key)?.state;
1702
+ }
1703
+ getConnection(key) {
1704
+ return this.#connections.get(key)?.connection ?? null;
1705
+ }
1706
+ };
1707
+ var ConnectionManager = new ConnectionManagerImpl();
1708
+
1709
+ // src/solid/SpacetimeDBProvider.ts
1710
+ function SpacetimeDBProvider(props) {
1711
+ const uri = () => props.connectionBuilder.getUri();
1712
+ const moduleName = () => props.connectionBuilder.getModuleName();
1713
+ const key = solidJs.createMemo(() => ConnectionManager.getKey(uri(), moduleName()));
1714
+ const fallbackState = {
1715
+ isActive: false,
1716
+ identity: void 0,
1717
+ token: void 0,
1718
+ connectionId: ConnectionId.random(),
1719
+ connectionError: void 0
1720
+ };
1721
+ const [state, setState] = store.createStore(fallbackState);
1722
+ solidJs.createComputed(() => {
1723
+ const currentKey = key();
1724
+ const unsubscribe = ConnectionManager.subscribe(currentKey, () => {
1725
+ const snapshot2 = ConnectionManager.getSnapshot(currentKey) ?? fallbackState;
1726
+ setState(snapshot2);
1727
+ });
1728
+ const snapshot = ConnectionManager.getSnapshot(currentKey) ?? fallbackState;
1729
+ setState(snapshot);
1730
+ solidJs.onCleanup(() => {
1731
+ unsubscribe();
1732
+ });
1733
+ });
1734
+ const getConnection = () => ConnectionManager.getConnection(key());
1735
+ const contextValue = {
1736
+ get isActive() {
1737
+ return state.isActive;
1738
+ },
1739
+ get identity() {
1740
+ return state.identity;
1741
+ },
1742
+ get token() {
1743
+ return state.token;
1744
+ },
1745
+ get connectionId() {
1746
+ return state.connectionId;
1747
+ },
1748
+ get connectionError() {
1749
+ return state.connectionError;
1750
+ },
1751
+ getConnection
1752
+ };
1753
+ solidJs.createComputed(() => {
1754
+ const currentKey = key();
1755
+ ConnectionManager.retain(currentKey, props.connectionBuilder);
1756
+ solidJs.onCleanup(() => {
1757
+ ConnectionManager.release(currentKey);
1758
+ });
1759
+ });
1760
+ return SpacetimeDBContext.Provider({
1761
+ value: contextValue,
1762
+ get children() {
1763
+ return props.children;
1764
+ }
1765
+ });
1766
+ }
1767
+ function classifyMembership(whereExpr, oldRow, newRow) {
1768
+ if (!whereExpr) return "stayIn";
1769
+ const oldIn = evaluateBooleanExpr(whereExpr, oldRow);
1770
+ const newIn = evaluateBooleanExpr(whereExpr, newRow);
1771
+ if (oldIn && !newIn) return "leave";
1772
+ if (!oldIn && newIn) return "enter";
1773
+ if (oldIn && newIn) return "stayIn";
1774
+ return "stayOut";
1775
+ }
1776
+ function useTable(query, callbacks) {
1777
+ const enabled = callbacks?.enabled ?? (() => true);
1778
+ const q = solidJs.createMemo(query);
1779
+ const accessorName = solidJs.createMemo(() => getQueryAccessorName(q()));
1780
+ const whereExpr = solidJs.createMemo(() => getQueryWhereClause(q()));
1781
+ const querySql = solidJs.createMemo(() => toSql(q()));
1782
+ let connectionState;
1783
+ try {
1784
+ connectionState = useSpacetimeDB();
1785
+ } catch {
1786
+ throw new Error(
1787
+ "Could not find SpacetimeDB client! Did you forget to add a `SpacetimeDBProvider`? `useTable` must be used in the SolidJS component tree under a `SpacetimeDBProvider` component."
1788
+ );
1789
+ }
1790
+ const [rows, setRows] = store.createStore([]);
1791
+ let latestTransactionEventId = null;
1792
+ const computeSnapshot = () => {
1793
+ if (!enabled()) {
1794
+ return [];
1795
+ }
1796
+ const connection = connectionState.getConnection();
1797
+ if (!connection) {
1798
+ return [];
1799
+ }
1800
+ const table = connection.db[accessorName()];
1801
+ const result = whereExpr() ? Array.from(table.iter()).filter(
1802
+ (row) => evaluateBooleanExpr(whereExpr(), row)
1803
+ ) : Array.from(table.iter());
1804
+ return result;
1805
+ };
1806
+ const [isReady, setIsReady] = solidJs.createSignal(false);
1807
+ solidJs.createComputed(() => {
1808
+ if (!enabled()) {
1809
+ setIsReady(false);
1810
+ return;
1811
+ }
1812
+ const connection = connectionState.getConnection();
1813
+ if (!connectionState.isActive || !connection) {
1814
+ setIsReady(false);
1815
+ return;
1816
+ }
1817
+ const cancel = connection.subscriptionBuilder().onApplied(() => {
1818
+ setIsReady(true);
1819
+ }).subscribe(querySql());
1820
+ solidJs.onCleanup(() => {
1821
+ cancel.unsubscribe();
1822
+ });
1823
+ const table = connection.db[accessorName()];
1824
+ const onInsert = (ctx, row) => {
1825
+ if (whereExpr() && !evaluateBooleanExpr(whereExpr(), row)) {
1826
+ return;
1827
+ }
1828
+ callbacks?.onInsert?.(row);
1829
+ if (ctx.event.id !== latestTransactionEventId) {
1830
+ latestTransactionEventId = ctx.event.id;
1831
+ setRows(store.reconcile(computeSnapshot()));
1832
+ }
1833
+ };
1834
+ const onDelete = (ctx, row) => {
1835
+ if (whereExpr() && !evaluateBooleanExpr(whereExpr(), row)) {
1836
+ return;
1837
+ }
1838
+ callbacks?.onDelete?.(row);
1839
+ if (ctx.event.id !== latestTransactionEventId) {
1840
+ latestTransactionEventId = ctx.event.id;
1841
+ setRows(store.reconcile(computeSnapshot()));
1842
+ }
1843
+ };
1844
+ const onUpdate = (ctx, oldRow, newRow) => {
1845
+ const change = classifyMembership(whereExpr(), oldRow, newRow);
1846
+ switch (change) {
1847
+ case "leave":
1848
+ callbacks?.onDelete?.(oldRow);
1849
+ break;
1850
+ case "enter":
1851
+ callbacks?.onInsert?.(newRow);
1852
+ break;
1853
+ case "stayIn":
1854
+ callbacks?.onUpdate?.(oldRow, newRow);
1855
+ break;
1856
+ case "stayOut":
1857
+ return;
1858
+ }
1859
+ if (ctx.event.id !== latestTransactionEventId) {
1860
+ latestTransactionEventId = ctx.event.id;
1861
+ setRows(store.reconcile(computeSnapshot()));
1862
+ }
1863
+ };
1864
+ table.onInsert(onInsert);
1865
+ table.onDelete(onDelete);
1866
+ table.onUpdate?.(onUpdate);
1867
+ setRows(store.reconcile(computeSnapshot()));
1868
+ solidJs.onCleanup(() => {
1869
+ table.removeOnInsert(onInsert);
1870
+ table.removeOnDelete(onDelete);
1871
+ table.removeOnUpdate?.(onUpdate);
1872
+ });
1873
+ });
1874
+ return [rows, isReady];
1875
+ }
1876
+ function useReducer(reducerDef) {
1877
+ const { getConnection, isActive } = useSpacetimeDB();
1878
+ const reducerName = reducerDef.accessorName;
1879
+ const queue = [];
1880
+ solidJs.createEffect(() => {
1881
+ if (!isActive) return;
1882
+ const conn = getConnection();
1883
+ if (!conn) return;
1884
+ const fn = conn.reducers[reducerName];
1885
+ if (queue.length) {
1886
+ const pending = queue.splice(0);
1887
+ for (const item of pending) {
1888
+ fn(...item.params).then(item.resolve, item.reject);
1889
+ }
1890
+ }
1891
+ });
1892
+ return (...params) => {
1893
+ const conn = getConnection();
1894
+ if (!conn) {
1895
+ return new Promise((resolve, reject) => {
1896
+ queue.push({ params, resolve, reject });
1897
+ });
1898
+ }
1899
+ const fn = conn.reducers[reducerName];
1900
+ return fn(...params);
1901
+ };
1902
+ }
1903
+ function useProcedure(procedureDef) {
1904
+ const { getConnection, isActive } = useSpacetimeDB();
1905
+ const procedureName = procedureDef.accessorName;
1906
+ const queue = [];
1907
+ solidJs.createEffect(() => {
1908
+ if (!isActive) return;
1909
+ const conn = getConnection();
1910
+ if (!conn) return;
1911
+ const fn = conn.procedures[procedureName];
1912
+ if (queue.length) {
1913
+ const pending = queue.splice(0);
1914
+ for (const item of pending) {
1915
+ fn(...item.params).then(item.resolve, item.reject);
1916
+ }
1917
+ }
1918
+ });
1919
+ return (...params) => {
1920
+ const conn = getConnection();
1921
+ if (!conn) {
1922
+ return new Promise(
1923
+ (resolve, reject) => {
1924
+ queue.push({ params, resolve, reject });
1925
+ }
1926
+ );
1927
+ }
1928
+ const fn = conn.procedures[procedureName];
1929
+ return fn(...params);
1930
+ };
1931
+ }
1932
+
1933
+ exports.SpacetimeDBProvider = SpacetimeDBProvider;
1934
+ exports.useProcedure = useProcedure;
1935
+ exports.useReducer = useReducer;
1936
+ exports.useSpacetimeDB = useSpacetimeDB;
1937
+ exports.useTable = useTable;
1938
+ //# sourceMappingURL=index.cjs.map
1939
+ //# sourceMappingURL=index.cjs.map