@evolu/common 8.0.0-next.5 → 8.0.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 (236) hide show
  1. package/dist/src/Array.d.ts +279 -173
  2. package/dist/src/Array.d.ts.map +1 -1
  3. package/dist/src/Array.js +105 -101
  4. package/dist/src/Assert.d.ts +39 -44
  5. package/dist/src/Assert.d.ts.map +1 -1
  6. package/dist/src/Assert.js +38 -31
  7. package/dist/src/BigInt.d.ts +6 -3
  8. package/dist/src/BigInt.d.ts.map +1 -1
  9. package/dist/src/BigInt.js +5 -2
  10. package/dist/src/Brand.d.ts +27 -40
  11. package/dist/src/Brand.d.ts.map +1 -1
  12. package/dist/src/Buffer.d.ts +27 -11
  13. package/dist/src/Buffer.d.ts.map +1 -1
  14. package/dist/src/Cache.d.ts +9 -4
  15. package/dist/src/Cache.d.ts.map +1 -1
  16. package/dist/src/Cache.js +8 -3
  17. package/dist/src/Callbacks.d.ts +30 -19
  18. package/dist/src/Callbacks.d.ts.map +1 -1
  19. package/dist/src/Console.d.ts +145 -66
  20. package/dist/src/Console.d.ts.map +1 -1
  21. package/dist/src/Console.js +91 -43
  22. package/dist/src/Crypto.d.ts +85 -42
  23. package/dist/src/Crypto.d.ts.map +1 -1
  24. package/dist/src/Crypto.js +44 -20
  25. package/dist/src/Eq.d.ts +87 -21
  26. package/dist/src/Eq.d.ts.map +1 -1
  27. package/dist/src/Eq.js +67 -19
  28. package/dist/src/Error.d.ts +3 -3
  29. package/dist/src/Error.d.ts.map +1 -1
  30. package/dist/src/Function.d.ts +119 -58
  31. package/dist/src/Function.d.ts.map +1 -1
  32. package/dist/src/Function.js +86 -43
  33. package/dist/src/Http.d.ts +394 -0
  34. package/dist/src/Http.d.ts.map +1 -0
  35. package/dist/src/Http.js +102 -0
  36. package/dist/src/Identicon.d.ts +16 -7
  37. package/dist/src/Identicon.d.ts.map +1 -1
  38. package/dist/src/Identicon.js +14 -5
  39. package/dist/src/LeakDetector.d.ts +88 -0
  40. package/dist/src/LeakDetector.d.ts.map +1 -0
  41. package/dist/src/LeakDetector.js +86 -0
  42. package/dist/src/LockManager.d.ts +18 -9
  43. package/dist/src/LockManager.d.ts.map +1 -1
  44. package/dist/src/LockManager.js +7 -8
  45. package/dist/src/Lookup.d.ts +43 -13
  46. package/dist/src/Lookup.d.ts.map +1 -1
  47. package/dist/src/Lookup.js +28 -8
  48. package/dist/src/Microtask.d.ts +1 -1
  49. package/dist/src/Microtask.d.ts.map +1 -1
  50. package/dist/src/Microtask.js +3 -7
  51. package/dist/src/Number.d.ts +49 -13
  52. package/dist/src/Number.d.ts.map +1 -1
  53. package/dist/src/Number.js +34 -5
  54. package/dist/src/Object.d.ts +160 -40
  55. package/dist/src/Object.d.ts.map +1 -1
  56. package/dist/src/Object.js +92 -46
  57. package/dist/src/Option.d.ts +10 -7
  58. package/dist/src/Option.d.ts.map +1 -1
  59. package/dist/src/Option.js +9 -6
  60. package/dist/src/Order.d.ts +21 -21
  61. package/dist/src/Order.d.ts.map +1 -1
  62. package/dist/src/Order.js +18 -21
  63. package/dist/src/Platform.d.ts +31 -0
  64. package/dist/src/Platform.d.ts.map +1 -1
  65. package/dist/src/Platform.js +98 -0
  66. package/dist/src/Random.d.ts +32 -17
  67. package/dist/src/Random.d.ts.map +1 -1
  68. package/dist/src/Random.js +12 -8
  69. package/dist/src/Redacted.d.ts +43 -29
  70. package/dist/src/Redacted.d.ts.map +1 -1
  71. package/dist/src/Redacted.js +14 -3
  72. package/dist/src/Ref.d.ts +11 -3
  73. package/dist/src/Ref.d.ts.map +1 -1
  74. package/dist/src/Ref.js +2 -2
  75. package/dist/src/RefCount.d.ts +2 -6
  76. package/dist/src/RefCount.d.ts.map +1 -1
  77. package/dist/src/RefCount.js +33 -90
  78. package/dist/src/Relation.d.ts +70 -5
  79. package/dist/src/Relation.d.ts.map +1 -1
  80. package/dist/src/Relation.js +77 -2
  81. package/dist/src/Resource.d.ts +590 -155
  82. package/dist/src/Resource.d.ts.map +1 -1
  83. package/dist/src/Resource.js +592 -343
  84. package/dist/src/Result.d.ts +838 -191
  85. package/dist/src/Result.d.ts.map +1 -1
  86. package/dist/src/Result.js +163 -102
  87. package/dist/src/Schedule.d.ts +684 -231
  88. package/dist/src/Schedule.d.ts.map +1 -1
  89. package/dist/src/Schedule.js +766 -295
  90. package/dist/src/Set.d.ts +89 -40
  91. package/dist/src/Set.d.ts.map +1 -1
  92. package/dist/src/Set.js +50 -29
  93. package/dist/src/Sqlite.d.ts +29 -72
  94. package/dist/src/Sqlite.d.ts.map +1 -1
  95. package/dist/src/Sqlite.js +39 -45
  96. package/dist/src/StackTrace.d.ts +40 -0
  97. package/dist/src/StackTrace.d.ts.map +1 -0
  98. package/dist/src/StackTrace.js +140 -0
  99. package/dist/src/Store.d.ts +5 -4
  100. package/dist/src/Store.d.ts.map +1 -1
  101. package/dist/src/Store.js +5 -4
  102. package/dist/src/String.d.ts +7 -1
  103. package/dist/src/String.d.ts.map +1 -1
  104. package/dist/src/String.js +20 -7
  105. package/dist/src/Task.d.ts +3428 -1629
  106. package/dist/src/Task.d.ts.map +1 -1
  107. package/dist/src/Task.js +1876 -1279
  108. package/dist/src/Test.d.ts +17 -124
  109. package/dist/src/Test.d.ts.map +1 -1
  110. package/dist/src/Test.js +17 -68
  111. package/dist/src/Time.d.ts +108 -49
  112. package/dist/src/Time.d.ts.map +1 -1
  113. package/dist/src/Time.js +172 -73
  114. package/dist/src/Type.d.ts +3542 -1926
  115. package/dist/src/Type.d.ts.map +1 -1
  116. package/dist/src/Type.js +3070 -1784
  117. package/dist/src/Types.d.ts +200 -100
  118. package/dist/src/Types.d.ts.map +1 -1
  119. package/dist/src/Types.js +39 -8
  120. package/dist/src/WebSocket.d.ts +48 -23
  121. package/dist/src/WebSocket.d.ts.map +1 -1
  122. package/dist/src/WebSocket.js +15 -6
  123. package/dist/src/Worker.d.ts +94 -36
  124. package/dist/src/Worker.d.ts.map +1 -1
  125. package/dist/src/Worker.js +58 -24
  126. package/dist/src/index.d.ts +55 -52
  127. package/dist/src/index.d.ts.map +1 -1
  128. package/dist/src/index.js +3 -1
  129. package/dist/src/intl/cs.d.ts +94 -0
  130. package/dist/src/intl/cs.d.ts.map +1 -0
  131. package/dist/src/intl/cs.js +220 -0
  132. package/dist/src/intl/index.d.ts +7 -0
  133. package/dist/src/intl/index.d.ts.map +1 -0
  134. package/dist/src/intl/index.js +6 -0
  135. package/dist/src/local-first/Db.d.ts +12 -8
  136. package/dist/src/local-first/Db.d.ts.map +1 -1
  137. package/dist/src/local-first/Db.js +107 -130
  138. package/dist/src/local-first/Error.d.ts +4 -4
  139. package/dist/src/local-first/Evolu.d.ts +338 -92
  140. package/dist/src/local-first/Evolu.d.ts.map +1 -1
  141. package/dist/src/local-first/Evolu.js +47 -55
  142. package/dist/src/local-first/LocalAuth.d.ts +4 -4
  143. package/dist/src/local-first/LocalAuth.d.ts.map +1 -1
  144. package/dist/src/local-first/Owner.d.ts +61 -24
  145. package/dist/src/local-first/Owner.d.ts.map +1 -1
  146. package/dist/src/local-first/Owner.js +45 -8
  147. package/dist/src/local-first/Protocol.d.ts +44 -31
  148. package/dist/src/local-first/Protocol.d.ts.map +1 -1
  149. package/dist/src/local-first/Protocol.js +36 -13
  150. package/dist/src/local-first/Query.d.ts +147 -62
  151. package/dist/src/local-first/Query.d.ts.map +1 -1
  152. package/dist/src/local-first/Query.js +112 -58
  153. package/dist/src/local-first/Relay.d.ts +44 -14
  154. package/dist/src/local-first/Relay.d.ts.map +1 -1
  155. package/dist/src/local-first/Schema.d.ts +92 -41
  156. package/dist/src/local-first/Schema.d.ts.map +1 -1
  157. package/dist/src/local-first/Schema.js +25 -8
  158. package/dist/src/local-first/Shared.d.ts +23 -21
  159. package/dist/src/local-first/Shared.d.ts.map +1 -1
  160. package/dist/src/local-first/Shared.js +85 -42
  161. package/dist/src/local-first/Storage.d.ts +53 -32
  162. package/dist/src/local-first/Storage.d.ts.map +1 -1
  163. package/dist/src/local-first/Storage.js +194 -234
  164. package/dist/src/local-first/Timestamp.d.ts +21 -21
  165. package/dist/src/local-first/Timestamp.d.ts.map +1 -1
  166. package/dist/src/local-first/Timestamp.js +2 -2
  167. package/dist/src/local-first/index.d.ts +11 -11
  168. package/package.json +14 -13
  169. package/src/Array.ts +306 -205
  170. package/src/Assert.ts +48 -68
  171. package/src/BigInt.ts +6 -3
  172. package/src/Brand.ts +27 -40
  173. package/src/Buffer.ts +28 -12
  174. package/src/Cache.ts +9 -4
  175. package/src/Callbacks.ts +30 -19
  176. package/src/Console.ts +156 -84
  177. package/src/Crypto.ts +83 -41
  178. package/src/Eq.ts +95 -22
  179. package/src/Error.ts +5 -2
  180. package/src/Function.ts +167 -59
  181. package/src/Http.ts +549 -0
  182. package/src/Identicon.ts +16 -7
  183. package/src/LeakDetector.ts +182 -0
  184. package/src/LockManager.ts +43 -39
  185. package/src/Lookup.ts +62 -28
  186. package/src/Microtask.ts +19 -23
  187. package/src/Number.ts +64 -12
  188. package/src/Object.ts +173 -49
  189. package/src/Option.ts +10 -7
  190. package/src/Order.ts +23 -21
  191. package/src/Platform.ts +136 -0
  192. package/src/Polyfills.ts +6 -12
  193. package/src/Random.ts +32 -19
  194. package/src/Redacted.ts +44 -30
  195. package/src/Ref.ts +14 -6
  196. package/src/RefCount.ts +38 -80
  197. package/src/Relation.ts +202 -10
  198. package/src/Resource.ts +1199 -591
  199. package/src/Result.ts +930 -271
  200. package/src/Schedule.ts +859 -343
  201. package/src/Set.ts +89 -40
  202. package/src/Sqlite.ts +142 -137
  203. package/src/StackTrace.ts +230 -0
  204. package/src/Store.ts +8 -7
  205. package/src/String.ts +22 -5
  206. package/src/Task.ts +5109 -2845
  207. package/src/Test.ts +20 -167
  208. package/src/Time.ts +293 -90
  209. package/src/Type.ts +10034 -4117
  210. package/src/Types.ts +227 -101
  211. package/src/WebSocket.ts +64 -36
  212. package/src/Worker.ts +180 -72
  213. package/src/index.ts +55 -52
  214. package/src/intl/cs.ts +388 -0
  215. package/src/intl/index.ts +7 -0
  216. package/src/local-first/Db.ts +161 -190
  217. package/src/local-first/Error.ts +4 -4
  218. package/src/local-first/Evolu.ts +495 -250
  219. package/src/local-first/LocalAuth.ts +6 -12
  220. package/src/local-first/Owner.ts +58 -21
  221. package/src/local-first/Protocol.ts +49 -31
  222. package/src/local-first/Query.ts +146 -61
  223. package/src/local-first/Relay.ts +51 -21
  224. package/src/local-first/Schema.ts +109 -51
  225. package/src/local-first/Shared.ts +253 -214
  226. package/src/local-first/Storage.ts +266 -264
  227. package/src/local-first/Timestamp.ts +25 -18
  228. package/src/local-first/index.ts +11 -11
  229. package/dist/src/Skiplist.d.ts +0 -28
  230. package/dist/src/Skiplist.d.ts.map +0 -1
  231. package/dist/src/Skiplist.js +0 -64
  232. package/dist/src/Tracer.d.ts +0 -48
  233. package/dist/src/Tracer.d.ts.map +0 -1
  234. package/dist/src/Tracer.js +0 -6
  235. package/src/Skiplist.ts +0 -108
  236. package/src/Tracer.ts +0 -54
@@ -15,15 +15,20 @@
15
15
  * Object.prototype` so it also works for plain objects coming from another
16
16
  * JavaScript realm.
17
17
  *
18
+ * TODO: deprecated Use `Object.is` from Type. Define a dedicated Type when
19
+ * another object domain is required.
20
+ *
18
21
  * ### Example
19
22
  *
20
23
  * ```ts
21
- * isPlainObject({}); // true
22
- * isPlainObject(Object.create(null)); // true
23
- * isPlainObject(new Date()); // false
24
- * isPlainObject(new (class Example {})()); // false
25
- * isPlainObject([]); // false
26
- * isPlainObject(null); // false
24
+ * import { isPlainObject } from "@evolu/common";
25
+ *
26
+ * expect(isPlainObject({})).toBe(true);
27
+ * expect(isPlainObject(Object.create(null))).toBe(true);
28
+ * expect(isPlainObject(new Date())).toBe(false);
29
+ * expect(isPlainObject(new (class Example {})())).toBe(false);
30
+ * expect(isPlainObject([])).toBe(false);
31
+ * expect(isPlainObject(null)).toBe(false);
27
32
  * ```
28
33
  */
29
34
  export const isPlainObject = (value) => {
@@ -39,9 +44,11 @@ export const isPlainObject = (value) => {
39
44
  * ### Example
40
45
  *
41
46
  * ```ts
42
- * isFunction(() => {}); // true
43
- * isFunction(function () {}); // true
44
- * isFunction({}); // false
47
+ * import { isFunction } from "@evolu/common";
48
+ *
49
+ * expect(isFunction(() => {})).toBe(true);
50
+ * expect(isFunction(function () {})).toBe(true);
51
+ * expect(isFunction({})).toBe(false);
45
52
  * ```
46
53
  */
47
54
  export const isFunction = (value) => typeof value === "function";
@@ -51,9 +58,11 @@ export const isFunction = (value) => typeof value === "function";
51
58
  * ### Example
52
59
  *
53
60
  * ```ts
54
- * isIterable([1, 2, 3]); // true
55
- * isIterable("abc"); // true
56
- * isIterable({}); // false
61
+ * import { isIterable } from "@evolu/common";
62
+ *
63
+ * expect(isIterable([1, 2, 3])).toBe(true);
64
+ * expect(isIterable("abc")).toBe(true);
65
+ * expect(isIterable({})).toBe(false);
57
66
  * ```
58
67
  */
59
68
  export const isIterable = (value) => value != null &&
@@ -64,9 +73,20 @@ export const isIterable = (value) => value != null &&
64
73
  * ### Example
65
74
  *
66
75
  * ```ts
67
- * type UserId = string & { readonly __brand: "UserId" };
68
- * const users = createRecord<UserId, string>();
69
- * const entries = objectToEntries(users); // [UserId, string][]
76
+ * import {
77
+ * objectToEntries,
78
+ * type Brand,
79
+ * type ReadonlyRecord,
80
+ * } from "@evolu/common";
81
+ *
82
+ * type UserId = string & Brand<"UserId">;
83
+ *
84
+ * const userId = "u1" as UserId;
85
+ * const users: ReadonlyRecord<UserId, string> = { [userId]: "Alice" };
86
+ * const entries = objectToEntries(users);
87
+ *
88
+ * expectTypeOf(entries).toEqualTypeOf<ReadonlyArray<[UserId, string]>>();
89
+ * expect(entries).toEqual([[userId, "Alice"]]);
70
90
  * ```
71
91
  */
72
92
  export const objectToEntries = (record) => Object.entries(record);
@@ -79,11 +99,20 @@ export const objectToEntries = (record) => Object.entries(record);
79
99
  * ### Example
80
100
  *
81
101
  * ```ts
82
- * type UserId = string & { readonly __brand: "UserId" };
102
+ * import {
103
+ * objectFromEntries,
104
+ * type Brand,
105
+ * type ReadonlyRecord,
106
+ * } from "@evolu/common";
107
+ *
108
+ * type UserId = string & Brand<"UserId">;
83
109
  * const entries: ReadonlyArray<[UserId, string]> = [
84
110
  * ["u1" as UserId, "Alice"],
85
111
  * ];
86
- * const users = objectFromEntries(entries); // ReadonlyRecord<UserId, string>
112
+ * const users = objectFromEntries(entries);
113
+ *
114
+ * expectTypeOf(users).toEqualTypeOf<ReadonlyRecord<UserId, string>>();
115
+ * expect(users).toEqual({ u1: "Alice" });
87
116
  * ```
88
117
  */
89
118
  export const objectFromEntries = (entries) => Object.fromEntries(entries);
@@ -96,11 +125,20 @@ export const objectFromEntries = (entries) => Object.fromEntries(entries);
96
125
  * ### Example
97
126
  *
98
127
  * ```ts
99
- * objectFrom(["en", "fr", "de"], loadTranslations);
100
- * // { en: Translations, fr: Translations, de: Translations }
101
- *
102
- * objectFrom(["trace", "debug", "log"], (level) => createHandler(level));
103
- * // { trace: Handler, debug: Handler, log: Handler }
128
+ * import { objectFrom, type ReadonlyRecord } from "@evolu/common";
129
+ *
130
+ * const translations = objectFrom(
131
+ * ["en", "fr"] as const,
132
+ * (locale): string => `Hello in ${locale}`,
133
+ * );
134
+ *
135
+ * expectTypeOf(translations).toEqualTypeOf<
136
+ * ReadonlyRecord<"en" | "fr", string>
137
+ * >();
138
+ * expect(translations).toEqual({
139
+ * en: "Hello in en",
140
+ * fr: "Hello in fr",
141
+ * });
104
142
  * ```
105
143
  */
106
144
  export const objectFrom = (keys, getValue) => Object.fromEntries(keys.map((k) => [k, getValue(k)]));
@@ -124,46 +162,54 @@ export const excludeProp = (obj, prop, condition) => {
124
162
  const { [prop]: _, ...rest } = obj;
125
163
  return rest;
126
164
  };
165
+ export function createMutableRecord(source) {
166
+ const record = Object.create(null);
167
+ return source === undefined ? record : Object.assign(record, source);
168
+ }
127
169
  /**
128
- * Creates a prototype-less object typed as `Record<K, V>`.
170
+ * A shared frozen empty readonly Record.
129
171
  *
130
- * Use this function when you need a plain record without a prototype chain
131
- * (e.g. when keys are controlled by external sources) to avoid prototype
132
- * pollution and accidental collisions with properties like `__proto__`.
172
+ * Use it as an immutable empty value for defaults and placeholders instead of
173
+ * allocating a new empty object. Because the instance is shared, it is frozen
174
+ * to prevent accidental mutation.
133
175
  *
134
- * Example:
135
- *
136
- * ```ts
137
- * const values = createRecord<string, SqliteValue>();
138
- * values["__proto__"] = someValue; // safe, no prototype pollution
139
- * ```
140
- */
141
- export const createRecord = () => Object.create(null);
142
- /**
143
- * An empty readonly record.
144
- *
145
- * Use as a default or initial value to avoid allocating new empty records.
176
+ * Use {@link createMutableRecord} to build a Record locally through mutation
177
+ * instead of repeated object spreads.
146
178
  *
147
179
  * @group Constants
148
180
  */
149
181
  export const emptyRecord =
150
- /*#__PURE__*/ createRecord();
182
+ /*#__PURE__*/ Object.freeze(
183
+ /*#__PURE__*/ createMutableRecord());
151
184
  /**
152
- * Safely gets a property from a record, returning `undefined` if the key
153
- * doesn't exist.
185
+ * Gets an own property from a record, returning `undefined` if the key is
186
+ * missing or inherited.
154
187
  *
155
188
  * TypeScript's `Record<K, V>` type assumes all keys exist, but at runtime
156
- * accessing a non-existent key returns `undefined`. This helper provides proper
157
- * typing for that case without needing a type assertion.
189
+ * accessing a missing key returns `undefined`. This helper provides proper
190
+ * typing for that case without treating properties inherited from
191
+ * `Object.prototype` as record data.
158
192
  *
159
193
  * ### Example
160
194
  *
161
195
  * ```ts
162
- * const users: Record<string, User> = { alice: { name: "Alice" } };
163
- * const user = getProperty(users, "bob"); // User | undefined
196
+ * import { getOwnProp } from "@evolu/common";
197
+ *
198
+ * interface User {
199
+ * readonly name: string;
200
+ * }
201
+ *
202
+ * const users: Readonly<Record<string, User>> = {
203
+ * alice: { name: "Alice" },
204
+ * };
205
+ * const user = getOwnProp(users, "bob");
206
+ *
207
+ * expectTypeOf(user).toEqualTypeOf<User | undefined>();
208
+ * expect(user).toBeUndefined();
209
+ * expect(getOwnProp(users, "toString")).toBeUndefined();
164
210
  * ```
165
211
  */
166
- export const getProperty = (record, key) => (key in record ? record[key] : undefined);
212
+ export const getOwnProp = (record, key) => (Object.hasOwn(record, key) ? record[key] : undefined);
167
213
  /** Creates a disposable {@link ObjectURL} for the given blob. */
168
214
  export const createObjectURL = (blob) => {
169
215
  const url = URL.createObjectURL(blob);
@@ -9,23 +9,26 @@
9
9
  * ### Example
10
10
  *
11
11
  * ```ts
12
- * // A cache that can store any value, including null and undefined
12
+ * import { isNone, isSome, none, type Option, some } from "@evolu/common";
13
+ *
13
14
  * const cache = new Map<string, Option<unknown>>();
14
15
  *
15
16
  * const get = (key: string): Option<unknown> => cache.get(key) ?? none;
16
17
  *
17
- * cache.set("a", some(null)); // Stored null
18
- * cache.set("b", some(undefined)); // Stored undefined
18
+ * cache.set("a", some(null));
19
+ * cache.set("b", some(undefined));
19
20
  *
20
- * isSome(get("a")); // true — value is null
21
- * isSome(get("b")); // true — value is undefined
22
- * isNone(get("c")); // true — key doesn't exist
21
+ * const a = get("a");
22
+ * assert(isSome(a));
23
+ * expect(a.value).toBeNull();
24
+ * expect(isSome(get("b"))).toBe(true);
25
+ * expect(isNone(get("c"))).toBe(true);
23
26
  * ```
24
27
  *
25
28
  * @module
26
29
  */
27
30
  /** Optional value. */
28
- import type { Typed } from "./Type.js";
31
+ import type { Typed } from "./Type.ts";
29
32
  /** Optional value. */
30
33
  export type Option<T> = Some<T> | None;
31
34
  /** Present value in an {@link Option}. */
@@ -1 +1 @@
1
- {"version":3,"file":"Option.d.ts","sourceRoot":"","sources":["../../src/Option.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,sBAAsB;AACtB,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,WAAW,CAAC;AAEvC,sBAAsB;AACtB,MAAM,MAAM,MAAM,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;AAEvC,0CAA0C;AAC1C,MAAM,WAAW,IAAI,CAAC,GAAG,CAAC,CAAC,CAAE,SAAQ,KAAK,CAAC,MAAM,CAAC;IAChD,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC;CACnB;AAED,yCAAyC;AACzC,MAAM,WAAW,IAAK,SAAQ,KAAK,CAAC,MAAM,CAAC;CAAG;AAE9C;;;;GAIG;AACH,MAAM,MAAM,WAAW,CAAC,CAAC,SAAS,MAAM,CAAC,GAAG,CAAC,IAC3C,CAAC,SAAS,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;AAEtC,8BAA8B;AAC9B,eAAO,MAAM,IAAI,GAAI,CAAC,EAAE,OAAO,CAAC,KAAG,MAAM,CAAC,CAAC,CAGzC,CAAC;AAEH,oCAAoC;AACpC,eAAO,MAAM,IAAI,EAAE,IAAuB,CAAC;AAE3C,mCAAmC;AACnC,eAAO,MAAM,MAAM,GAAI,CAAC,EAAE,QAAQ,MAAM,CAAC,CAAC,CAAC,KAAG,MAAM,IAAI,IAAI,CAAC,CAAC,CACtC,CAAC;AAEzB,mCAAmC;AACnC,eAAO,MAAM,MAAM,GAAI,CAAC,EAAE,QAAQ,MAAM,CAAC,CAAC,CAAC,KAAG,MAAM,IAAI,IAChC,CAAC;AAEzB;;;;GAIG;AACH,eAAO,MAAM,YAAY,GAAI,CAAC,EAC5B,OAAO,CAAC,GAAG,IAAI,GAAG,SAAS,KAC1B,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAyC,CAAC"}
1
+ {"version":3,"file":"Option.d.ts","sourceRoot":"","sources":["../../src/Option.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,sBAAsB;AACtB,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,WAAW,CAAC;AAEvC,sBAAsB;AACtB,MAAM,MAAM,MAAM,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;AAEvC,0CAA0C;AAC1C,MAAM,WAAW,IAAI,CAAC,GAAG,CAAC,CAAC,CAAE,SAAQ,KAAK,CAAC,MAAM,CAAC;IAChD,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC;CACnB;AAED,yCAAyC;AACzC,MAAM,WAAW,IAAK,SAAQ,KAAK,CAAC,MAAM,CAAC;CAAG;AAE9C;;;;GAIG;AACH,MAAM,MAAM,WAAW,CAAC,CAAC,SAAS,MAAM,CAAC,GAAG,CAAC,IAC3C,CAAC,SAAS,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;AAEtC,8BAA8B;AAC9B,eAAO,MAAM,IAAI,GAAI,CAAC,SAAS,CAAC,KAAG,MAAM,CAAC,CAAC,CAGzC,CAAC;AAEH,oCAAoC;AACpC,eAAO,MAAM,IAAI,EAAE,IAAuB,CAAC;AAE3C,mCAAmC;AACnC,eAAO,MAAM,MAAM,GAAI,CAAC,UAAU,MAAM,CAAC,CAAC,CAAC,KAAG,MAAM,IAAI,IAAI,CAAC,CAAC,CACtC,CAAC;AAEzB,mCAAmC;AACnC,eAAO,MAAM,MAAM,GAAI,CAAC,UAAU,MAAM,CAAC,CAAC,CAAC,KAAG,MAAM,IAAI,IAChC,CAAC;AAEzB;;;;GAIG;AACH,eAAO,MAAM,YAAY,GAAI,CAAC,SACrB,CAAC,GAAG,IAAI,GAAG,SAAS,KAC1B,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAyC,CAAC"}
@@ -9,17 +9,20 @@
9
9
  * ### Example
10
10
  *
11
11
  * ```ts
12
- * // A cache that can store any value, including null and undefined
12
+ * import { isNone, isSome, none, type Option, some } from "@evolu/common";
13
+ *
13
14
  * const cache = new Map<string, Option<unknown>>();
14
15
  *
15
16
  * const get = (key: string): Option<unknown> => cache.get(key) ?? none;
16
17
  *
17
- * cache.set("a", some(null)); // Stored null
18
- * cache.set("b", some(undefined)); // Stored undefined
18
+ * cache.set("a", some(null));
19
+ * cache.set("b", some(undefined));
19
20
  *
20
- * isSome(get("a")); // true — value is null
21
- * isSome(get("b")); // true — value is undefined
22
- * isNone(get("c")); // true — key doesn't exist
21
+ * const a = get("a");
22
+ * assert(isSome(a));
23
+ * expect(a.value).toBeNull();
24
+ * expect(isSome(get("b"))).toBe(true);
25
+ * expect(isNone(get("c"))).toBe(true);
23
26
  * ```
24
27
  *
25
28
  * @module
@@ -11,6 +11,9 @@
11
11
  * - Returns `-1` if `x` is less than `y`.
12
12
  * - Returns `0` if `x` is equal to `y`.
13
13
  * - Returns `1` if `x` is greater than `y`.
14
+ *
15
+ * An `Order` also defines equality. Use {@link eqFromOrder} to derive an
16
+ * {@link Eq}.
14
17
  */
15
18
  export type Order<in A> = (x: A, y: A) => Ordering;
16
19
  /**
@@ -25,10 +28,12 @@ export type Ordering = -1 | 0 | 1;
25
28
  * ### Example
26
29
  *
27
30
  * ```ts
31
+ * import { createOrder } from "@evolu/common";
32
+ *
28
33
  * const orderNumber = createOrder<number>((x, y) => x < y);
29
- * expect(orderNumber(1, 2)).toEqual(-1);
30
- * expect(orderNumber(2, 1)).toEqual(1);
31
- * expect(orderNumber(1, 1)).toEqual(0);
34
+ * expect(orderNumber(1, 2)).toBe(-1);
35
+ * expect(orderNumber(2, 1)).toBe(1);
36
+ * expect(orderNumber(1, 1)).toBe(0);
32
37
  * ```
33
38
  */
34
39
  export declare const createOrder: <A>(isLessThan: (x: A, y: A) => boolean) => Order<A>;
@@ -38,9 +43,10 @@ export declare const createOrder: <A>(isLessThan: (x: A, y: A) => boolean) => Or
38
43
  * ### Example
39
44
  *
40
45
  * ```ts
41
- * reverseOrder(orderNumber)(1, 2); // 1
42
- * reverseOrder(orderNumber)(2, 1); // -1
43
- * reverseOrder(orderNumber)(1, 1); // 0
46
+ * import { orderNumber, reverseOrder } from "@evolu/common";
47
+ *
48
+ * const descendingOrderNumber = reverseOrder(orderNumber);
49
+ * expect([3, 1, 2].toSorted(descendingOrderNumber)).toEqual([3, 2, 1]);
44
50
  * ```
45
51
  */
46
52
  export declare const reverseOrder: <A>(order: Order<A>) => Order<A>;
@@ -50,10 +56,9 @@ export declare const reverseOrder: <A>(order: Order<A>) => Order<A>;
50
56
  * ### Example
51
57
  *
52
58
  * ```ts
53
- * orderString("a", "b"); // -1
54
- * orderString("b", "a"); // 1
55
- * orderString("a", "a"); // 0
56
- * ["c", "b", "a"].toSorted(orderString); // ["a", "b", "c"]
59
+ * import { orderString } from "@evolu/common";
60
+ *
61
+ * expect(["c", "b", "a"].toSorted(orderString)).toEqual(["a", "b", "c"]);
57
62
  * ```
58
63
  */
59
64
  export declare const orderString: Order<string>;
@@ -63,13 +68,9 @@ export declare const orderString: Order<string>;
63
68
  * ### Example
64
69
  *
65
70
  * ```ts
66
- * orderNumber(1, 2); // -1
67
- * orderNumber(2, 1); // 1
68
- * orderNumber(1, 1); // 0
69
- * [2, 1, 3].toSorted(orderNumber); // [1, 2, 3]
70
- * reverseOrder(orderNumber)(1, 2); // 1
71
- * reverseOrder(orderNumber)(2, 1); // -1
72
- * reverseOrder(orderNumber)(1, 1); // 0
71
+ * import { orderNumber } from "@evolu/common";
72
+ *
73
+ * expect([2, 1, 3].toSorted(orderNumber)).toEqual([1, 2, 3]);
73
74
  * ```
74
75
  */
75
76
  export declare const orderNumber: Order<number>;
@@ -79,10 +80,9 @@ export declare const orderNumber: Order<number>;
79
80
  * ### Example
80
81
  *
81
82
  * ```ts
82
- * orderBigInt(1n, 2n); // -1
83
- * orderBigInt(2n, 1n); // 1
84
- * orderBigInt(1n, 1n); // 0
85
- * [2n, 1n, 3n].toSorted(orderBigInt); // [1n, 2n, 3n]
83
+ * import { orderBigInt } from "@evolu/common";
84
+ *
85
+ * expect([2n, 1n, 3n].toSorted(orderBigInt)).toEqual([1n, 2n, 3n]);
86
86
  * ```
87
87
  */
88
88
  export declare const orderBigInt: Order<bigint>;
@@ -1 +1 @@
1
- {"version":3,"file":"Order.d.ts","sourceRoot":"","sources":["../../src/Order.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;;;;;GAQG;AACH,MAAM,MAAM,KAAK,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,QAAQ,CAAC;AAEnD;;;;GAIG;AACH,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAElC;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,WAAW,GACrB,CAAC,EAAE,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,OAAO,KAAG,KAAK,CAAC,CAAC,CAER,CAAC;AAE5C;;;;;;;;;;GAUG;AACH,eAAO,MAAM,YAAY,GACtB,CAAC,EAAE,OAAO,KAAK,CAAC,CAAC,CAAC,KAAG,KAAK,CAAC,CAAC,CAEhB,CAAC;AAEhB;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,WAAW,EAAE,KAAK,CAAC,MAAM,CAErC,CAAC;AAEF;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,WAAW,eAAqD,CAAC;AAE9E;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,WAAW,eAAqD,CAAC;AAE9E,uCAAuC;AACvC,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,UAAU,CAU7C,CAAC"}
1
+ {"version":3,"file":"Order.d.ts","sourceRoot":"","sources":["../../src/Order.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,KAAK,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,QAAQ,CAAC;AAEnD;;;;GAIG;AACH,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAElC;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,WAAW,GACrB,CAAC,cAAc,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,OAAO,KAAG,KAAK,CAAC,CAAC,CAER,CAAC;AAE5C;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,YAAY,GACtB,CAAC,SAAS,KAAK,CAAC,CAAC,CAAC,KAAG,KAAK,CAAC,CAAC,CAEhB,CAAC;AAEhB;;;;;;;;;;GAUG;AACH,eAAO,MAAM,WAAW,EAAE,KAAK,CAAC,MAAM,CAErC,CAAC;AAEF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,WAAW,eAAqD,CAAC;AAE9E;;;;;;;;;;GAUG;AACH,eAAO,MAAM,WAAW,eAAqD,CAAC;AAE9E,uCAAuC;AACvC,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,UAAU,CAU7C,CAAC"}
package/dist/src/Order.js CHANGED
@@ -9,10 +9,12 @@
9
9
  * ### Example
10
10
  *
11
11
  * ```ts
12
+ * import { createOrder } from "@evolu/common";
13
+ *
12
14
  * const orderNumber = createOrder<number>((x, y) => x < y);
13
- * expect(orderNumber(1, 2)).toEqual(-1);
14
- * expect(orderNumber(2, 1)).toEqual(1);
15
- * expect(orderNumber(1, 1)).toEqual(0);
15
+ * expect(orderNumber(1, 2)).toBe(-1);
16
+ * expect(orderNumber(2, 1)).toBe(1);
17
+ * expect(orderNumber(1, 1)).toBe(0);
16
18
  * ```
17
19
  */
18
20
  export const createOrder = (isLessThan) => (x, y) => x === y ? 0 : isLessThan(x, y) ? -1 : 1;
@@ -22,9 +24,10 @@ export const createOrder = (isLessThan) => (x, y) => x === y ? 0 : isLessThan(x,
22
24
  * ### Example
23
25
  *
24
26
  * ```ts
25
- * reverseOrder(orderNumber)(1, 2); // 1
26
- * reverseOrder(orderNumber)(2, 1); // -1
27
- * reverseOrder(orderNumber)(1, 1); // 0
27
+ * import { orderNumber, reverseOrder } from "@evolu/common";
28
+ *
29
+ * const descendingOrderNumber = reverseOrder(orderNumber);
30
+ * expect([3, 1, 2].toSorted(descendingOrderNumber)).toEqual([3, 2, 1]);
28
31
  * ```
29
32
  */
30
33
  export const reverseOrder = (order) => (a, b) => order(b, a);
@@ -34,10 +37,9 @@ export const reverseOrder = (order) => (a, b) => order(b, a);
34
37
  * ### Example
35
38
  *
36
39
  * ```ts
37
- * orderString("a", "b"); // -1
38
- * orderString("b", "a"); // 1
39
- * orderString("a", "a"); // 0
40
- * ["c", "b", "a"].toSorted(orderString); // ["a", "b", "c"]
40
+ * import { orderString } from "@evolu/common";
41
+ *
42
+ * expect(["c", "b", "a"].toSorted(orderString)).toEqual(["a", "b", "c"]);
41
43
  * ```
42
44
  */
43
45
  export const orderString = /*#__PURE__*/ createOrder((a, b) => a < b);
@@ -47,13 +49,9 @@ export const orderString = /*#__PURE__*/ createOrder((a, b) => a < b);
47
49
  * ### Example
48
50
  *
49
51
  * ```ts
50
- * orderNumber(1, 2); // -1
51
- * orderNumber(2, 1); // 1
52
- * orderNumber(1, 1); // 0
53
- * [2, 1, 3].toSorted(orderNumber); // [1, 2, 3]
54
- * reverseOrder(orderNumber)(1, 2); // 1
55
- * reverseOrder(orderNumber)(2, 1); // -1
56
- * reverseOrder(orderNumber)(1, 1); // 0
52
+ * import { orderNumber } from "@evolu/common";
53
+ *
54
+ * expect([2, 1, 3].toSorted(orderNumber)).toEqual([1, 2, 3]);
57
55
  * ```
58
56
  */
59
57
  export const orderNumber = /*#__PURE__*/ createOrder((a, b) => a < b);
@@ -63,10 +61,9 @@ export const orderNumber = /*#__PURE__*/ createOrder((a, b) => a < b);
63
61
  * ### Example
64
62
  *
65
63
  * ```ts
66
- * orderBigInt(1n, 2n); // -1
67
- * orderBigInt(2n, 1n); // 1
68
- * orderBigInt(1n, 1n); // 0
69
- * [2n, 1n, 3n].toSorted(orderBigInt); // [1n, 2n, 3n]
64
+ * import { orderBigInt } from "@evolu/common";
65
+ *
66
+ * expect([2n, 1n, 3n].toSorted(orderBigInt)).toEqual([1n, 2n, 3n]);
70
67
  * ```
71
68
  */
72
69
  export const orderBigInt = /*#__PURE__*/ createOrder((a, b) => a < b);
@@ -7,6 +7,18 @@
7
7
  export declare const isHermes: boolean;
8
8
  /** Returns true if running in a server environment (no DOM). */
9
9
  export declare const isServer: boolean;
10
+ /**
11
+ * True outside production builds.
12
+ *
13
+ * Bundlers (webpack, Vite, esbuild, Metro) replace the text
14
+ * `process.env.NODE_ENV` statically at build time, so in production bundles
15
+ * this expression folds to `false` and code behind it is dead-code-eliminated —
16
+ * the same mechanism React uses. The `typeof` guard makes the runtime read safe
17
+ * where no bundler ran, such as un-bundled browser ESM, where it fails closed
18
+ * to production behavior. Node.js reads it natively; React Native polyfills it.
19
+ * A missing `NODE_ENV` counts as development, matching React semantics.
20
+ */
21
+ export declare const isDev: boolean;
10
22
  /**
11
23
  * Detects if Node.js Buffer is available and should be used.
12
24
  *
@@ -46,4 +58,23 @@ export type ReloadApp = (url?: string) => void;
46
58
  export interface ReloadAppDep {
47
59
  readonly reloadApp: ReloadApp;
48
60
  }
61
+ export interface TestGlobalErrors extends Disposable {
62
+ readonly errors: ReadonlyArray<unknown>;
63
+ readonly next: () => Promise<unknown>;
64
+ /**
65
+ * Waits until every error already reported to the platform has been delivered
66
+ * to this recorder, then returns {@link TestGlobalErrors.errors}.
67
+ *
68
+ * Platforms deliver global errors asynchronously and provide no hook for
69
+ * "nothing was reported", so settle emits a sentinel of the same kind and
70
+ * resolves when it arrives. Platform delivery is ordered, so all earlier
71
+ * errors are recorded by then. Use it to assert absence: `expect(await
72
+ * unhandledRejections.settle()).toEqual([])`.
73
+ */
74
+ readonly settle: () => Promise<ReadonlyArray<unknown>>;
75
+ }
76
+ /** Records platform global uncaught-error reporting until disposed. */
77
+ export declare const testGlobalUncaughtErrors: () => TestGlobalErrors;
78
+ /** Records platform global unhandled-rejection reporting until disposed. */
79
+ export declare const testGlobalUnhandledRejections: () => TestGlobalErrors;
49
80
  //# sourceMappingURL=Platform.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Platform.d.ts","sourceRoot":"","sources":["../../src/Platform.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,kEAAkE;AAClE,eAAO,MAAM,QAAQ,SAAiC,CAAC;AAEvD,gEAAgE;AAChE,eAAO,MAAM,QAAQ,SAAkC,CAAC;AAExD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,aAAa,SAC6B,CAAC;AAExD;;;;;;;;;GASG;AACH,MAAM,MAAM,SAAS,GAAG,CAAC,QAAQ,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;AAEvD,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;CAC/B;AAED;;;;;;;;GAQG;AACH,MAAM,MAAM,SAAS,GAAG,CAAC,GAAG,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;AAE/C,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;CAC/B"}
1
+ {"version":3,"file":"Platform.d.ts","sourceRoot":"","sources":["../../src/Platform.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,kEAAkE;AAClE,eAAO,MAAM,QAAQ,SAAiC,CAAC;AAEvD,gEAAgE;AAChE,eAAO,MAAM,QAAQ,SAAkC,CAAC;AAExD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,KAAK,SAGyB,CAAC;AAE5C;;;;;;;;;;GAUG;AACH,eAAO,MAAM,aAAa,SAC6B,CAAC;AAExD;;;;;;;;;GASG;AACH,MAAM,MAAM,SAAS,GAAG,CAAC,QAAQ,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;AAEvD,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;CAC/B;AAED;;;;;;;;GAQG;AACH,MAAM,MAAM,SAAS,GAAG,CAAC,GAAG,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;AAE/C,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;CAC/B;AAED,MAAM,WAAW,gBAAiB,SAAQ,UAAU;IAClD,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC,OAAO,CAAC,CAAC;IACxC,QAAQ,CAAC,IAAI,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;IAEtC;;;;;;;;;OASG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,OAAO,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC;CACxD;AAED,uEAAuE;AACvE,eAAO,MAAM,wBAAwB,QAAO,gBACF,CAAC;AAE3C,4EAA4E;AAC5E,eAAO,MAAM,6BAA6B,QAAO,gBACH,CAAC"}
@@ -7,6 +7,20 @@
7
7
  export const isHermes = "HermesInternal" in globalThis;
8
8
  /** Returns true if running in a server environment (no DOM). */
9
9
  export const isServer = typeof document === "undefined";
10
+ /**
11
+ * True outside production builds.
12
+ *
13
+ * Bundlers (webpack, Vite, esbuild, Metro) replace the text
14
+ * `process.env.NODE_ENV` statically at build time, so in production bundles
15
+ * this expression folds to `false` and code behind it is dead-code-eliminated —
16
+ * the same mechanism React uses. The `typeof` guard makes the runtime read safe
17
+ * where no bundler ran, such as un-bundled browser ESM, where it fails closed
18
+ * to production behavior. Node.js reads it natively; React Native polyfills it.
19
+ * A missing `NODE_ENV` counts as development, matching React semantics.
20
+ */
21
+ export const isDev = typeof process === "undefined"
22
+ ? false
23
+ : process.env.NODE_ENV !== "production";
10
24
  /**
11
25
  * Detects if Node.js Buffer is available and should be used.
12
26
  *
@@ -19,3 +33,87 @@ export const isServer = typeof document === "undefined";
19
33
  * @see https://github.com/craftzdog/react-native-quick-base64#installation
20
34
  */
21
35
  export const hasNodeBuffer = !isHermes && typeof globalThis.Buffer !== "undefined";
36
+ /** Records platform global uncaught-error reporting until disposed. */
37
+ export const testGlobalUncaughtErrors = () => createTestGlobalErrors("uncaughtErrors");
38
+ /** Records platform global unhandled-rejection reporting until disposed. */
39
+ export const testGlobalUnhandledRejections = () => createTestGlobalErrors("unhandledRejection");
40
+ const settleSentinel = new Error("TestGlobalErrors.settle sentinel");
41
+ const createTestGlobalErrors = (kind) => {
42
+ const nodeEvent = kind === "uncaughtErrors" ? "uncaughtException" : "unhandledRejection";
43
+ const webEvent = kind === "uncaughtErrors" ? "error" : "unhandledrejection";
44
+ const webErrorKey = kind === "uncaughtErrors" ? "error" : "reason";
45
+ const errorType = kind === "uncaughtErrors" ? "uncaught-error" : "unhandled-rejection";
46
+ const disposableStack = new DisposableStack();
47
+ const errors = [];
48
+ const nextWaiters = [];
49
+ const settleWaiters = [];
50
+ let nextIndex = 0;
51
+ const next = () => {
52
+ if (nextIndex < errors.length) {
53
+ const error = errors[nextIndex];
54
+ nextIndex += 1;
55
+ return Promise.resolve(error);
56
+ }
57
+ const next = Promise.withResolvers();
58
+ nextWaiters.push(next.resolve);
59
+ return next.promise;
60
+ };
61
+ const record = (error) => {
62
+ if (error === settleSentinel) {
63
+ settleWaiters.shift()?.();
64
+ return;
65
+ }
66
+ errors.push(error);
67
+ const resolveNext = nextWaiters.shift();
68
+ if (!resolveNext)
69
+ return;
70
+ nextIndex += 1;
71
+ resolveNext(error);
72
+ };
73
+ const settle = () => {
74
+ const settled = Promise.withResolvers();
75
+ settleWaiters.push(() => {
76
+ settled.resolve(errors);
77
+ });
78
+ if (kind === "unhandledRejection") {
79
+ void Promise.reject(settleSentinel);
80
+ }
81
+ else {
82
+ queueMicrotask(() => {
83
+ throw settleSentinel;
84
+ });
85
+ }
86
+ return settled.promise;
87
+ };
88
+ if (typeof process === "object" &&
89
+ typeof process.on === "function" &&
90
+ typeof process.off === "function") {
91
+ process.on(nodeEvent, record);
92
+ disposableStack.defer(() => {
93
+ process.off(nodeEvent, record);
94
+ });
95
+ }
96
+ else if (typeof globalThis.addEventListener === "function") {
97
+ const listener = (event) => {
98
+ event.preventDefault();
99
+ record(event[webErrorKey]);
100
+ };
101
+ globalThis.addEventListener(webEvent, listener);
102
+ disposableStack.defer(() => {
103
+ globalThis.removeEventListener(webEvent, listener);
104
+ });
105
+ }
106
+ else {
107
+ throw new Error(`Unsupported platform global ${errorType} reporting.`);
108
+ }
109
+ return {
110
+ errors,
111
+ next,
112
+ settle,
113
+ [Symbol.dispose]: () => {
114
+ nextWaiters.length = 0;
115
+ settleWaiters.length = 0;
116
+ disposableStack.dispose();
117
+ },
118
+ };
119
+ };