@evolu/common 7.4.1 → 8.0.0-next.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 (251) hide show
  1. package/README.md +4 -61
  2. package/dist/src/Array.d.ts +343 -102
  3. package/dist/src/Array.d.ts.map +1 -1
  4. package/dist/src/Array.js +181 -85
  5. package/dist/src/Assert.d.ts +57 -11
  6. package/dist/src/Assert.d.ts.map +1 -1
  7. package/dist/src/Assert.js +47 -11
  8. package/dist/src/BigInt.d.ts +6 -1
  9. package/dist/src/BigInt.d.ts.map +1 -1
  10. package/dist/src/BigInt.js +5 -0
  11. package/dist/src/Brand.d.ts +40 -12
  12. package/dist/src/Brand.d.ts.map +1 -1
  13. package/dist/src/Brand.js +5 -0
  14. package/dist/src/Buffer.d.ts +6 -1
  15. package/dist/src/Buffer.d.ts.map +1 -1
  16. package/dist/src/Buffer.js +7 -2
  17. package/dist/src/Cache.d.ts +10 -2
  18. package/dist/src/Cache.d.ts.map +1 -1
  19. package/dist/src/Cache.js +6 -0
  20. package/dist/src/Callbacks.d.ts +10 -7
  21. package/dist/src/Callbacks.d.ts.map +1 -1
  22. package/dist/src/Callbacks.js +23 -13
  23. package/dist/src/Console.d.ts +361 -69
  24. package/dist/src/Console.d.ts.map +1 -1
  25. package/dist/src/Console.js +217 -117
  26. package/dist/src/Crypto.d.ts +70 -21
  27. package/dist/src/Crypto.d.ts.map +1 -1
  28. package/dist/src/Crypto.js +72 -27
  29. package/dist/src/Eq.d.ts +22 -2
  30. package/dist/src/Eq.d.ts.map +1 -1
  31. package/dist/src/Eq.js +21 -1
  32. package/dist/src/Error.d.ts +23 -12
  33. package/dist/src/Error.d.ts.map +1 -1
  34. package/dist/src/Error.js +27 -11
  35. package/dist/src/Function.d.ts +128 -56
  36. package/dist/src/Function.d.ts.map +1 -1
  37. package/dist/src/Function.js +118 -14
  38. package/dist/src/Identicon.d.ts +5 -0
  39. package/dist/src/Identicon.d.ts.map +1 -1
  40. package/dist/src/Identicon.js +6 -1
  41. package/dist/src/Lookup.d.ts +160 -0
  42. package/dist/src/Lookup.d.ts.map +1 -0
  43. package/dist/src/Lookup.js +192 -0
  44. package/dist/src/Microtask.d.ts +21 -0
  45. package/dist/src/Microtask.d.ts.map +1 -0
  46. package/dist/src/Microtask.js +37 -0
  47. package/dist/src/Number.d.ts +18 -4
  48. package/dist/src/Number.d.ts.map +1 -1
  49. package/dist/src/Number.js +23 -1
  50. package/dist/src/Object.d.ts +110 -5
  51. package/dist/src/Object.d.ts.map +1 -1
  52. package/dist/src/Object.js +108 -5
  53. package/dist/src/Option.d.ts +58 -0
  54. package/dist/src/Option.d.ts.map +1 -0
  55. package/dist/src/Option.js +43 -0
  56. package/dist/src/Order.d.ts +5 -0
  57. package/dist/src/Order.d.ts.map +1 -1
  58. package/dist/src/Order.js +8 -3
  59. package/dist/src/Platform.d.ts +36 -2
  60. package/dist/src/Platform.d.ts.map +1 -1
  61. package/dist/src/Platform.js +10 -6
  62. package/dist/src/Polyfills.d.ts +27 -0
  63. package/dist/src/Polyfills.d.ts.map +1 -0
  64. package/dist/src/Polyfills.js +299 -0
  65. package/dist/src/Random.d.ts +18 -7
  66. package/dist/src/Random.d.ts.map +1 -1
  67. package/dist/src/Random.js +9 -7
  68. package/dist/src/Redacted.d.ts +7 -4
  69. package/dist/src/Redacted.d.ts.map +1 -1
  70. package/dist/src/Redacted.js +5 -0
  71. package/dist/src/Ref.d.ts +31 -16
  72. package/dist/src/Ref.d.ts.map +1 -1
  73. package/dist/src/Ref.js +35 -7
  74. package/dist/src/RefCount.d.ts +62 -0
  75. package/dist/src/RefCount.d.ts.map +1 -0
  76. package/dist/src/RefCount.js +83 -0
  77. package/dist/src/Relation.d.ts +84 -29
  78. package/dist/src/Relation.d.ts.map +1 -1
  79. package/dist/src/Relation.js +83 -105
  80. package/dist/src/Resource.d.ts +263 -0
  81. package/dist/src/Resource.d.ts.map +1 -0
  82. package/dist/src/Resource.js +389 -0
  83. package/dist/src/Result.d.ts +390 -374
  84. package/dist/src/Result.d.ts.map +1 -1
  85. package/dist/src/Result.js +142 -70
  86. package/dist/src/Schedule.d.ts +953 -0
  87. package/dist/src/Schedule.d.ts.map +1 -0
  88. package/dist/src/Schedule.js +1199 -0
  89. package/dist/src/Set.d.ts +181 -0
  90. package/dist/src/Set.d.ts.map +1 -0
  91. package/dist/src/Set.js +137 -0
  92. package/dist/src/Skiplist.d.ts +6 -1
  93. package/dist/src/Skiplist.d.ts.map +1 -1
  94. package/dist/src/Skiplist.js +5 -0
  95. package/dist/src/Sqlite.d.ts +160 -60
  96. package/dist/src/Sqlite.d.ts.map +1 -1
  97. package/dist/src/Sqlite.js +290 -190
  98. package/dist/src/Store.d.ts +36 -28
  99. package/dist/src/Store.d.ts.map +1 -1
  100. package/dist/src/Store.js +55 -15
  101. package/dist/src/String.d.ts +5 -0
  102. package/dist/src/String.d.ts.map +1 -1
  103. package/dist/src/String.js +5 -0
  104. package/dist/src/Task.d.ts +2263 -423
  105. package/dist/src/Task.d.ts.map +1 -1
  106. package/dist/src/Task.js +1488 -348
  107. package/dist/src/Test.d.ts +122 -0
  108. package/dist/src/Test.d.ts.map +1 -0
  109. package/dist/src/Test.js +66 -0
  110. package/dist/src/Time.d.ts +201 -48
  111. package/dist/src/Time.d.ts.map +1 -1
  112. package/dist/src/Time.js +190 -86
  113. package/dist/src/Tracer.d.ts +48 -0
  114. package/dist/src/Tracer.d.ts.map +1 -0
  115. package/dist/src/Tracer.js +6 -0
  116. package/dist/src/Type.d.ts +582 -209
  117. package/dist/src/Type.d.ts.map +1 -1
  118. package/dist/src/Type.js +362 -240
  119. package/dist/src/Types.d.ts +160 -6
  120. package/dist/src/Types.d.ts.map +1 -1
  121. package/dist/src/Types.js +22 -2
  122. package/dist/src/WebSocket.d.ts +113 -58
  123. package/dist/src/WebSocket.d.ts.map +1 -1
  124. package/dist/src/WebSocket.js +210 -118
  125. package/dist/src/Worker.d.ts +245 -60
  126. package/dist/src/Worker.d.ts.map +1 -1
  127. package/dist/src/Worker.js +220 -64
  128. package/dist/src/index.d.ts +25 -3
  129. package/dist/src/index.d.ts.map +1 -1
  130. package/dist/src/index.js +19 -3
  131. package/dist/src/local-first/Db.d.ts +24 -213
  132. package/dist/src/local-first/Db.d.ts.map +1 -1
  133. package/dist/src/local-first/Db.js +622 -293
  134. package/dist/src/local-first/Error.d.ts +12 -0
  135. package/dist/src/local-first/Error.d.ts.map +1 -0
  136. package/dist/src/local-first/Error.js +6 -0
  137. package/dist/src/local-first/Evolu.d.ts +330 -285
  138. package/dist/src/local-first/Evolu.d.ts.map +1 -1
  139. package/dist/src/local-first/Evolu.js +472 -402
  140. package/dist/src/local-first/LocalAuth.d.ts +10 -10
  141. package/dist/src/local-first/LocalAuth.d.ts.map +1 -1
  142. package/dist/src/local-first/LocalAuth.js +6 -1
  143. package/dist/src/local-first/Owner.d.ts +70 -27
  144. package/dist/src/local-first/Owner.d.ts.map +1 -1
  145. package/dist/src/local-first/Owner.js +27 -14
  146. package/dist/src/local-first/Protocol.d.ts +58 -50
  147. package/dist/src/local-first/Protocol.d.ts.map +1 -1
  148. package/dist/src/local-first/Protocol.js +253 -155
  149. package/dist/src/local-first/Query.d.ts +133 -43
  150. package/dist/src/local-first/Query.d.ts.map +1 -1
  151. package/dist/src/local-first/Query.js +139 -90
  152. package/dist/src/local-first/Relay.d.ts +18 -38
  153. package/dist/src/local-first/Relay.d.ts.map +1 -1
  154. package/dist/src/local-first/Relay.js +59 -171
  155. package/dist/src/local-first/Schema.d.ts +139 -144
  156. package/dist/src/local-first/Schema.d.ts.map +1 -1
  157. package/dist/src/local-first/Schema.js +78 -163
  158. package/dist/src/local-first/Shared.d.ts +125 -0
  159. package/dist/src/local-first/Shared.d.ts.map +1 -0
  160. package/dist/src/local-first/Shared.js +569 -0
  161. package/dist/src/local-first/Storage.d.ts +50 -53
  162. package/dist/src/local-first/Storage.d.ts.map +1 -1
  163. package/dist/src/local-first/Storage.js +121 -173
  164. package/dist/src/local-first/Timestamp.d.ts +28 -35
  165. package/dist/src/local-first/Timestamp.d.ts.map +1 -1
  166. package/dist/src/local-first/Timestamp.js +24 -25
  167. package/dist/src/local-first/index.d.ts +2 -15
  168. package/dist/src/local-first/index.d.ts.map +1 -1
  169. package/dist/src/local-first/index.js +2 -15
  170. package/package.json +36 -26
  171. package/src/Array.ts +467 -106
  172. package/src/Assert.ts +87 -12
  173. package/src/BigInt.ts +7 -1
  174. package/src/Brand.ts +41 -12
  175. package/src/Buffer.ts +10 -4
  176. package/src/Cache.ts +11 -2
  177. package/src/Callbacks.ts +33 -23
  178. package/src/Console.ts +567 -178
  179. package/src/Crypto.ts +111 -62
  180. package/src/Eq.ts +30 -3
  181. package/src/Error.ts +50 -34
  182. package/src/Function.ts +140 -68
  183. package/src/Identicon.ts +7 -1
  184. package/src/Lookup.ts +415 -0
  185. package/src/Microtask.ts +58 -0
  186. package/src/Number.ts +40 -7
  187. package/src/Object.ts +155 -16
  188. package/src/Option.ts +74 -0
  189. package/src/Order.ts +11 -3
  190. package/src/Platform.ts +43 -7
  191. package/src/Polyfills.ts +465 -0
  192. package/src/Random.ts +25 -11
  193. package/src/Redacted.ts +8 -4
  194. package/src/Ref.ts +72 -21
  195. package/src/RefCount.ts +170 -0
  196. package/src/Relation.ts +188 -136
  197. package/src/Resource.ts +864 -0
  198. package/src/Result.ts +548 -381
  199. package/src/Schedule.ts +1471 -0
  200. package/src/Set.ts +247 -0
  201. package/src/Skiplist.ts +7 -1
  202. package/src/Sqlite.ts +409 -304
  203. package/src/Store.ts +94 -48
  204. package/src/String.ts +6 -0
  205. package/src/Task.ts +3685 -740
  206. package/src/Test.ts +162 -0
  207. package/src/Time.ts +348 -145
  208. package/src/Tracer.ts +54 -0
  209. package/src/Type.ts +851 -430
  210. package/src/Types.ts +202 -7
  211. package/src/WebSocket.ts +311 -178
  212. package/src/Worker.ts +527 -147
  213. package/src/index.ts +74 -3
  214. package/src/local-first/Db.ts +871 -597
  215. package/src/local-first/Error.ts +17 -0
  216. package/src/local-first/Evolu.ts +884 -824
  217. package/src/local-first/LocalAuth.ts +10 -10
  218. package/src/local-first/Owner.ts +94 -42
  219. package/src/local-first/Protocol.ts +440 -303
  220. package/src/local-first/Query.ts +243 -194
  221. package/src/local-first/Relay.ts +91 -252
  222. package/src/local-first/Schema.ts +284 -394
  223. package/src/local-first/Shared.ts +932 -0
  224. package/src/local-first/Storage.ts +206 -277
  225. package/src/local-first/Timestamp.ts +38 -45
  226. package/src/local-first/index.ts +2 -16
  227. package/LICENSE +0 -21
  228. package/dist/src/Instances.d.ts +0 -34
  229. package/dist/src/Instances.d.ts.map +0 -1
  230. package/dist/src/Instances.js +0 -44
  231. package/dist/src/Resources.d.ts +0 -118
  232. package/dist/src/Resources.d.ts.map +0 -1
  233. package/dist/src/Resources.js +0 -197
  234. package/dist/src/local-first/Platform.d.ts +0 -25
  235. package/dist/src/local-first/Platform.d.ts.map +0 -1
  236. package/dist/src/local-first/Platform.js +0 -1
  237. package/dist/src/local-first/Public.d.ts +0 -22
  238. package/dist/src/local-first/Public.d.ts.map +0 -1
  239. package/dist/src/local-first/Public.js +0 -15
  240. package/dist/src/local-first/PublicKysely.d.ts +0 -148
  241. package/dist/src/local-first/PublicKysely.d.ts.map +0 -1
  242. package/dist/src/local-first/PublicKysely.js +0 -184
  243. package/dist/src/local-first/Sync.d.ts +0 -112
  244. package/dist/src/local-first/Sync.d.ts.map +0 -1
  245. package/dist/src/local-first/Sync.js +0 -526
  246. package/src/Instances.ts +0 -92
  247. package/src/Resources.ts +0 -367
  248. package/src/local-first/Platform.ts +0 -27
  249. package/src/local-first/Public.ts +0 -42
  250. package/src/local-first/PublicKysely.ts +0 -239
  251. package/src/local-first/Sync.ts +0 -949
@@ -1,6 +1,11 @@
1
+ /**
2
+ * Number arithmetic, comparison, and branded numeric types.
3
+ *
4
+ * @module
5
+ */
1
6
  import { assertNonEmptyReadonlyArray } from "./Assert.js";
2
7
  import { err, ok } from "./Result.js";
3
- import { PositiveInt } from "./Type.js";
8
+ import { brand, lessThanOrEqualTo, onePositiveInt, NonNegativeInt, PositiveInt, } from "./Type.js";
4
9
  export const increment = (n) => n + 1;
5
10
  export const decrement = (n) => n - 1;
6
11
  /** Clamps a number within a given range. */
@@ -54,3 +59,20 @@ minNumberOfItemsPerBucket = PositiveInt.orThrow(2)) => {
54
59
  assertNonEmptyReadonlyArray(indexes);
55
60
  return ok(indexes);
56
61
  };
62
+ /**
63
+ * Valid index for {@link fibonacciAt}, constrained to 1-78.
64
+ *
65
+ * Limited to 78 because F(79) exceeds JavaScript's `MAX_SAFE_INTEGER`.
66
+ */
67
+ export const FibonacciIndex = /*#__PURE__*/ brand("FibonacciIndex",
68
+ /*#__PURE__*/ lessThanOrEqualTo(78)(PositiveInt));
69
+ /** Returns the Fibonacci number at the given index (1-indexed: 1,1,2,3,5,8,...). */
70
+ export const fibonacciAt = (index) => {
71
+ if (index <= 2)
72
+ return onePositiveInt;
73
+ let a = 1;
74
+ let b = 1;
75
+ for (let i = 3; i <= index; i++)
76
+ [a, b] = [b, a + b];
77
+ return PositiveInt.orThrow(b);
78
+ };
@@ -1,22 +1,61 @@
1
+ /**
2
+ * Object utilities.
3
+ *
4
+ * @module
5
+ */
6
+ /**
7
+ * A read-only `Record<K, V>` with `K extends keyof any` to preserve branded key
8
+ * types (e.g., in {@link mapObject}).
9
+ */
10
+ export type ReadonlyRecord<K extends keyof any, V> = Readonly<Record<K, V>>;
1
11
  /**
2
12
  * Checks if a value is a plain object (e.g., created with `{}` or `Object`).
3
13
  *
14
+ * Accepts objects with `Object.prototype` and objects with a `null` prototype
15
+ * created via `Object.create(null)`. Rejects class instances and other built-in
16
+ * objects because their prototype chain includes an application-specific or
17
+ * built-in prototype before `Object.prototype`.
18
+ *
19
+ * The prototype-chain check uses structure instead of `prototype ===
20
+ * Object.prototype` so it also works for plain objects coming from another
21
+ * JavaScript realm.
22
+ *
4
23
  * ### Example
5
24
  *
6
25
  * ```ts
7
26
  * isPlainObject({}); // true
27
+ * isPlainObject(Object.create(null)); // true
8
28
  * isPlainObject(new Date()); // false
29
+ * isPlainObject(new (class Example {})()); // false
9
30
  * isPlainObject([]); // false
10
31
  * isPlainObject(null); // false
11
32
  * ```
12
33
  */
13
34
  export declare const isPlainObject: (value: unknown) => value is Record<string, unknown>;
14
35
  /**
15
- * A read-only `Record<K, V>` with `K extends keyof any` to preserve branded key
16
- * types (e.g., in {@link mapObject}).
36
+ * Checks if a value is a function.
37
+ *
38
+ * ### Example
39
+ *
40
+ * ```ts
41
+ * isFunction(() => {}); // true
42
+ * isFunction(function () {}); // true
43
+ * isFunction({}); // false
44
+ * ```
17
45
  */
18
- export type ReadonlyRecord<K extends keyof any, V> = Readonly<Record<K, V>>;
19
- type StringKeyOf<T> = Extract<keyof T, string>;
46
+ export declare const isFunction: (value: unknown) => value is globalThis.Function;
47
+ /**
48
+ * Checks if a value is {@link Iterable}.
49
+ *
50
+ * ### Example
51
+ *
52
+ * ```ts
53
+ * isIterable([1, 2, 3]); // true
54
+ * isIterable("abc"); // true
55
+ * isIterable({}); // false
56
+ * ```
57
+ */
58
+ export declare const isIterable: (value: unknown) => value is Iterable<unknown>;
20
59
  /**
21
60
  * Like `Object.entries` but preserves branded keys.
22
61
  *
@@ -29,6 +68,41 @@ type StringKeyOf<T> = Extract<keyof T, string>;
29
68
  * ```
30
69
  */
31
70
  export declare const objectToEntries: <T extends Record<string, any>>(record: T) => ReadonlyArray<[StringKeyOf<T>, T[StringKeyOf<T>]]>;
71
+ type StringKeyOf<T> = Extract<keyof T, string>;
72
+ /**
73
+ * Creates an object from key-value pairs, preserving branded key types.
74
+ *
75
+ * The inverse of {@link objectToEntries}. Use when you need type-safe
76
+ * reconstruction of objects with branded keys.
77
+ *
78
+ * ### Example
79
+ *
80
+ * ```ts
81
+ * type UserId = string & { readonly __brand: "UserId" };
82
+ * const entries: ReadonlyArray<[UserId, string]> = [
83
+ * ["u1" as UserId, "Alice"],
84
+ * ];
85
+ * const users = objectFromEntries(entries); // ReadonlyRecord<UserId, string>
86
+ * ```
87
+ */
88
+ export declare const objectFromEntries: <K extends string, V>(entries: Iterable<readonly [K, V]>) => ReadonlyRecord<K, V>;
89
+ /**
90
+ * Creates an object by mapping keys to values.
91
+ *
92
+ * The inverse of `Object.keys` — instead of extracting keys from an object,
93
+ * builds an object from keys with a mapper function.
94
+ *
95
+ * ### Example
96
+ *
97
+ * ```ts
98
+ * objectFrom(["en", "fr", "de"], loadTranslations);
99
+ * // { en: Translations, fr: Translations, de: Translations }
100
+ *
101
+ * objectFrom(["trace", "debug", "log"], (level) => createHandler(level));
102
+ * // { trace: Handler, debug: Handler, log: Handler }
103
+ * ```
104
+ */
105
+ export declare const objectFrom: <K extends string, V>(keys: ReadonlyArray<K>, getValue: (key: K) => V) => ReadonlyRecord<K, V>;
32
106
  /**
33
107
  * Maps a `ReadonlyRecord<K, V>` to a new `ReadonlyRecord<K, U>`, preserving
34
108
  * branded key types (e.g., `type Id = 'id' & string`) lost by `Object.entries`.
@@ -52,6 +126,14 @@ export declare const excludeProp: <T extends object, K extends keyof T>(obj: T,
52
126
  * ```
53
127
  */
54
128
  export declare const createRecord: <K extends string = string, V = unknown>() => Record<K, V>;
129
+ /**
130
+ * An empty readonly record.
131
+ *
132
+ * Use as a default or initial value to avoid allocating new empty records.
133
+ *
134
+ * @group Constants
135
+ */
136
+ export declare const emptyRecord: Readonly<Record<string, never>>;
55
137
  /**
56
138
  * Safely gets a property from a record, returning `undefined` if the key
57
139
  * doesn't exist.
@@ -67,6 +149,29 @@ export declare const createRecord: <K extends string = string, V = unknown>() =>
67
149
  * const user = getProperty(users, "bob"); // User | undefined
68
150
  * ```
69
151
  */
70
- export declare const getProperty: <K extends string, V>(record: ReadonlyRecord<K, V>, key: string) => V | undefined;
152
+ export declare const getProperty: <K extends string, V>(record: ReadonlyRecord<K, V>, key: K) => V | undefined;
153
+ /**
154
+ * A disposable wrapper around `URL.createObjectURL` that automatically revokes
155
+ * the URL when disposed. Use with the `using` declaration for automatic
156
+ * cleanup.
157
+ *
158
+ * ### Example
159
+ *
160
+ * ```ts
161
+ * const blob = new Blob(["hello"], { type: "text/plain" });
162
+ * using objectUrl = createObjectURL(blob);
163
+ * console.log(objectUrl.url); // blob:...
164
+ * // URL.revokeObjectURL is automatically called when the scope ends
165
+ * ```
166
+ *
167
+ * This ensures the URL is always revoked when the scope ends, even if an error
168
+ * occurs, preventing memory leaks from unreleased blob URLs.
169
+ */
170
+ export interface ObjectURL extends Disposable {
171
+ /** The object URL string created by `URL.createObjectURL`. */
172
+ readonly url: string;
173
+ }
174
+ /** Creates a disposable {@link ObjectURL} for the given blob. */
175
+ export declare const createObjectURL: (blob: Blob) => ObjectURL;
71
176
  export {};
72
177
  //# sourceMappingURL=Object.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Object.d.ts","sourceRoot":"","sources":["../../src/Object.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,aAAa,GACxB,OAAO,OAAO,KACb,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAC2B,CAAC;AAE9D;;;GAGG;AACH,MAAM,MAAM,cAAc,CAAC,CAAC,SAAS,MAAM,GAAG,EAAE,CAAC,IAAI,QAAQ,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AAG5E,KAAK,WAAW,CAAC,CAAC,IAAI,OAAO,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC;AAE/C;;;;;;;;;;GAUG;AACH,eAAO,MAAM,eAAe,GAAI,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC3D,QAAQ,CAAC,KACR,aAAa,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAGK,CAAC;AAE1D;;;;GAIG;AACH,eAAO,MAAM,SAAS,GAAI,CAAC,SAAS,MAAM,EAAE,CAAC,EAAE,CAAC,EAC9C,QAAQ,cAAc,CAAC,CAAC,EAAE,CAAC,CAAC,EAC5B,IAAI,CAAC,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,KAC1B,cAAc,CAAC,CAAC,EAAE,CAAC,CAMK,CAAC;AAE5B,wDAAwD;AACxD,eAAO,MAAM,WAAW,GAAI,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,MAAM,CAAC,EAC7D,KAAK,CAAC,EACN,MAAM,CAAC,EACP,YAAY,OAAO,KAClB,OAAO,SAAS,SAAS,IAAI,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC,EAAE,CAAC,CAM/C,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,YAAY,GAAI,CAAC,SAAS,MAAM,GAAG,MAAM,EAAE,CAAC,GAAG,OAAO,OAAK,MAAM,CAC5E,CAAC,EACD,CAAC,CACqC,CAAC;AAEzC;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,WAAW,GAAI,CAAC,SAAS,MAAM,EAAE,CAAC,EAC7C,QAAQ,cAAc,CAAC,CAAC,EAAE,CAAC,CAAC,EAC5B,KAAK,MAAM,KACV,CAAC,GAAG,SAA2D,CAAC"}
1
+ {"version":3,"file":"Object.d.ts","sourceRoot":"","sources":["../../src/Object.ts"],"names":[],"mappings":"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"}
@@ -1,16 +1,63 @@
1
+ /**
2
+ * Object utilities.
3
+ *
4
+ * @module
5
+ */
1
6
  /**
2
7
  * Checks if a value is a plain object (e.g., created with `{}` or `Object`).
3
8
  *
9
+ * Accepts objects with `Object.prototype` and objects with a `null` prototype
10
+ * created via `Object.create(null)`. Rejects class instances and other built-in
11
+ * objects because their prototype chain includes an application-specific or
12
+ * built-in prototype before `Object.prototype`.
13
+ *
14
+ * The prototype-chain check uses structure instead of `prototype ===
15
+ * Object.prototype` so it also works for plain objects coming from another
16
+ * JavaScript realm.
17
+ *
4
18
  * ### Example
5
19
  *
6
20
  * ```ts
7
21
  * isPlainObject({}); // true
22
+ * isPlainObject(Object.create(null)); // true
8
23
  * isPlainObject(new Date()); // false
24
+ * isPlainObject(new (class Example {})()); // false
9
25
  * isPlainObject([]); // false
10
26
  * isPlainObject(null); // false
11
27
  * ```
12
28
  */
13
- export const isPlainObject = (value) => Object.prototype.toString.call(value) === "[object Object]";
29
+ export const isPlainObject = (value) => {
30
+ if (Object.prototype.toString.call(value) !== "[object Object]") {
31
+ return false;
32
+ }
33
+ const prototype = Object.getPrototypeOf(value);
34
+ return prototype === null || Object.getPrototypeOf(prototype) === null;
35
+ };
36
+ /**
37
+ * Checks if a value is a function.
38
+ *
39
+ * ### Example
40
+ *
41
+ * ```ts
42
+ * isFunction(() => {}); // true
43
+ * isFunction(function () {}); // true
44
+ * isFunction({}); // false
45
+ * ```
46
+ */
47
+ export const isFunction = (value) => typeof value === "function";
48
+ /**
49
+ * Checks if a value is {@link Iterable}.
50
+ *
51
+ * ### Example
52
+ *
53
+ * ```ts
54
+ * isIterable([1, 2, 3]); // true
55
+ * isIterable("abc"); // true
56
+ * isIterable({}); // false
57
+ * ```
58
+ */
59
+ export const isIterable = (value) => value != null &&
60
+ typeof value[Symbol.iterator] === "function";
14
61
  /**
15
62
  * Like `Object.entries` but preserves branded keys.
16
63
  *
@@ -23,15 +70,52 @@ export const isPlainObject = (value) => Object.prototype.toString.call(value) ==
23
70
  * ```
24
71
  */
25
72
  export const objectToEntries = (record) => Object.entries(record);
73
+ /**
74
+ * Creates an object from key-value pairs, preserving branded key types.
75
+ *
76
+ * The inverse of {@link objectToEntries}. Use when you need type-safe
77
+ * reconstruction of objects with branded keys.
78
+ *
79
+ * ### Example
80
+ *
81
+ * ```ts
82
+ * type UserId = string & { readonly __brand: "UserId" };
83
+ * const entries: ReadonlyArray<[UserId, string]> = [
84
+ * ["u1" as UserId, "Alice"],
85
+ * ];
86
+ * const users = objectFromEntries(entries); // ReadonlyRecord<UserId, string>
87
+ * ```
88
+ */
89
+ export const objectFromEntries = (entries) => Object.fromEntries(entries);
90
+ /**
91
+ * Creates an object by mapping keys to values.
92
+ *
93
+ * The inverse of `Object.keys` — instead of extracting keys from an object,
94
+ * builds an object from keys with a mapper function.
95
+ *
96
+ * ### Example
97
+ *
98
+ * ```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 }
104
+ * ```
105
+ */
106
+ export const objectFrom = (keys, getValue) => Object.fromEntries(keys.map((k) => [k, getValue(k)]));
26
107
  /**
27
108
  * Maps a `ReadonlyRecord<K, V>` to a new `ReadonlyRecord<K, U>`, preserving
28
109
  * branded key types (e.g., `type Id = 'id' & string`) lost by `Object.entries`.
29
110
  * Uses `K extends string` for precision.
30
111
  */
31
- export const mapObject = (record, fn) => Object.fromEntries(Object.entries(record).map(([key, value]) => [
32
- key,
33
- fn(value, key),
34
- ]));
112
+ export const mapObject = (record, fn) => {
113
+ const out = Object.create(null);
114
+ for (const key in record) {
115
+ out[key] = fn(record[key], key);
116
+ }
117
+ return out;
118
+ };
35
119
  /** Conditionally excludes a property from an object. */
36
120
  export const excludeProp = (obj, prop, condition) => {
37
121
  if (condition) {
@@ -55,6 +139,15 @@ export const excludeProp = (obj, prop, condition) => {
55
139
  * ```
56
140
  */
57
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.
146
+ *
147
+ * @group Constants
148
+ */
149
+ export const emptyRecord =
150
+ /*#__PURE__*/ createRecord();
58
151
  /**
59
152
  * Safely gets a property from a record, returning `undefined` if the key
60
153
  * doesn't exist.
@@ -71,3 +164,13 @@ export const createRecord = () => Object.create(null);
71
164
  * ```
72
165
  */
73
166
  export const getProperty = (record, key) => (key in record ? record[key] : undefined);
167
+ /** Creates a disposable {@link ObjectURL} for the given blob. */
168
+ export const createObjectURL = (blob) => {
169
+ const url = URL.createObjectURL(blob);
170
+ return {
171
+ url,
172
+ [Symbol.dispose]: () => {
173
+ URL.revokeObjectURL(url);
174
+ },
175
+ };
176
+ };
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Optional value container.
3
+ *
4
+ * Distinguishes absence from values like `null` or `undefined`.
5
+ *
6
+ * Use Option when the value itself can be `null` or `undefined`. For APIs where
7
+ * `null` means "not found", just use `T | null` directly.
8
+ *
9
+ * ### Example
10
+ *
11
+ * ```ts
12
+ * // A cache that can store any value, including null and undefined
13
+ * const cache = new Map<string, Option<unknown>>();
14
+ *
15
+ * const get = (key: string): Option<unknown> => cache.get(key) ?? none;
16
+ *
17
+ * cache.set("a", some(null)); // Stored null
18
+ * cache.set("b", some(undefined)); // Stored undefined
19
+ *
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
23
+ * ```
24
+ *
25
+ * @module
26
+ */
27
+ /** Optional value. */
28
+ import type { Typed } from "./Type.js";
29
+ /** Optional value. */
30
+ export type Option<T> = Some<T> | None;
31
+ /** Present value in an {@link Option}. */
32
+ export interface Some<out T> extends Typed<"Some"> {
33
+ readonly value: T;
34
+ }
35
+ /** Absent value in an {@link Option}. */
36
+ export interface None extends Typed<"None"> {
37
+ }
38
+ /**
39
+ * Extracts the value type from an {@link Option} or {@link Some}.
40
+ *
41
+ * @group Utilities
42
+ */
43
+ export type InferOption<O extends Option<any>> = O extends Some<infer T> ? T : never;
44
+ /** Creates a {@link Some}. */
45
+ export declare const some: <T>(value: T) => Option<T>;
46
+ /** Shared {@link None} instance. */
47
+ export declare const none: None;
48
+ /** Type guard for {@link Some}. */
49
+ export declare const isSome: <T>(option: Option<T>) => option is Some<T>;
50
+ /** Type guard for {@link None}. */
51
+ export declare const isNone: <T>(option: Option<T>) => option is None;
52
+ /**
53
+ * Converts a nullable value to an {@link Option}.
54
+ *
55
+ * `null` and `undefined` become {@link none}.
56
+ */
57
+ export declare const fromNullable: <T>(value: T | null | undefined) => Option<NonNullable<T>>;
58
+ //# sourceMappingURL=Option.d.ts.map
@@ -0,0 +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"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Optional value container.
3
+ *
4
+ * Distinguishes absence from values like `null` or `undefined`.
5
+ *
6
+ * Use Option when the value itself can be `null` or `undefined`. For APIs where
7
+ * `null` means "not found", just use `T | null` directly.
8
+ *
9
+ * ### Example
10
+ *
11
+ * ```ts
12
+ * // A cache that can store any value, including null and undefined
13
+ * const cache = new Map<string, Option<unknown>>();
14
+ *
15
+ * const get = (key: string): Option<unknown> => cache.get(key) ?? none;
16
+ *
17
+ * cache.set("a", some(null)); // Stored null
18
+ * cache.set("b", some(undefined)); // Stored undefined
19
+ *
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
23
+ * ```
24
+ *
25
+ * @module
26
+ */
27
+ /** Creates a {@link Some}. */
28
+ export const some = (value) => ({
29
+ type: "Some",
30
+ value,
31
+ });
32
+ /** Shared {@link None} instance. */
33
+ export const none = { type: "None" };
34
+ /** Type guard for {@link Some}. */
35
+ export const isSome = (option) => option.type === "Some";
36
+ /** Type guard for {@link None}. */
37
+ export const isNone = (option) => option.type === "None";
38
+ /**
39
+ * Converts a nullable value to an {@link Option}.
40
+ *
41
+ * `null` and `undefined` become {@link none}.
42
+ */
43
+ export const fromNullable = (value) => (value == null ? none : some(value));
@@ -1,3 +1,8 @@
1
+ /**
2
+ * Ordering and comparison utilities.
3
+ *
4
+ * @module
5
+ */
1
6
  /**
2
7
  * Compares two values of type `A` and returns their ordering.
3
8
  *
@@ -1 +1 @@
1
- {"version":3,"file":"Order.d.ts","sourceRoot":"","sources":["../../src/Order.ts"],"names":[],"mappings":"AAAA;;;;;;;;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,CAAgC,CAAC;AAEvE;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,WAAW,eAAuC,CAAC;AAEhE;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,WAAW,eAAuC,CAAC;AAEhE,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;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"}
package/dist/src/Order.js CHANGED
@@ -1,3 +1,8 @@
1
+ /**
2
+ * Ordering and comparison utilities.
3
+ *
4
+ * @module
5
+ */
1
6
  /**
2
7
  * Creates an ordering function from a "less than" comparator.
3
8
  *
@@ -35,7 +40,7 @@ export const reverseOrder = (order) => (a, b) => order(b, a);
35
40
  * ["c", "b", "a"].toSorted(orderString); // ["a", "b", "c"]
36
41
  * ```
37
42
  */
38
- export const orderString = createOrder((a, b) => a < b);
43
+ export const orderString = /*#__PURE__*/ createOrder((a, b) => a < b);
39
44
  /**
40
45
  * An order for numbers in ascending order.
41
46
  *
@@ -51,7 +56,7 @@ export const orderString = createOrder((a, b) => a < b);
51
56
  * reverseOrder(orderNumber)(1, 1); // 0
52
57
  * ```
53
58
  */
54
- export const orderNumber = createOrder((a, b) => a < b);
59
+ export const orderNumber = /*#__PURE__*/ createOrder((a, b) => a < b);
55
60
  /**
56
61
  * An order for bigints in ascending order.
57
62
  *
@@ -64,7 +69,7 @@ export const orderNumber = createOrder((a, b) => a < b);
64
69
  * [2n, 1n, 3n].toSorted(orderBigInt); // [1n, 2n, 3n]
65
70
  * ```
66
71
  */
67
- export const orderBigInt = createOrder((a, b) => a < b);
72
+ export const orderBigInt = /*#__PURE__*/ createOrder((a, b) => a < b);
68
73
  /** An {@link Order} for Uint8Array. */
69
74
  export const orderUint8Array = (a, b) => {
70
75
  if (a.byteLength > b.byteLength)
@@ -1,5 +1,12 @@
1
- /** Detects if the code is running in React Native environment. */
2
- export declare const isReactNative: boolean;
1
+ /**
2
+ * Platform runtime utilities and capability abstractions.
3
+ *
4
+ * @module
5
+ */
6
+ /** Returns true if running in React Native with Hermes engine. */
7
+ export declare const isHermes: boolean;
8
+ /** Returns true if running in a server environment (no DOM). */
9
+ export declare const isServer: boolean;
3
10
  /**
4
11
  * Detects if Node.js Buffer is available and should be used.
5
12
  *
@@ -12,4 +19,31 @@ export declare const isReactNative: boolean;
12
19
  * @see https://github.com/craftzdog/react-native-quick-base64#installation
13
20
  */
14
21
  export declare const hasNodeBuffer: boolean;
22
+ /**
23
+ * FlushSync is for libraries like React to flush updates synchronously inside
24
+ * the provided callback to ensure the DOM is updated immediately.
25
+ *
26
+ * For example, with React, when we want to focus on an element rendered as a
27
+ * result of a mutation, Evolu ensures all DOM changes are flushed synchronously
28
+ * if an onComplete callback is used.
29
+ *
30
+ * https://react.dev/reference/react-dom/flushSync
31
+ */
32
+ export type FlushSync = (callback: () => void) => void;
33
+ export interface FlushSyncDep {
34
+ readonly flushSync: FlushSync;
35
+ }
36
+ /**
37
+ * Reload the app in a platform-specific way.
38
+ *
39
+ * Use this after purging persistent storage to clear in-memory state and ensure
40
+ * the app starts fresh. It does not purge storage itself.
41
+ *
42
+ * - Web: Redirects to the specified URL (defaults to `/`)
43
+ * - React Native: Restarts the app (URL ignored)
44
+ */
45
+ export type ReloadApp = (url?: string) => void;
46
+ export interface ReloadAppDep {
47
+ readonly reloadApp: ReloadApp;
48
+ }
15
49
  //# sourceMappingURL=Platform.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Platform.d.ts","sourceRoot":"","sources":["../../src/Platform.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,eAAO,MAAM,aAAa,SAIoB,CAAC;AAE/C;;;;;;;;;;GAUG;AACH,eAAO,MAAM,aAAa,SACkC,CAAC"}
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,8 +1,12 @@
1
- /** Detects if the code is running in React Native environment. */
2
- export const isReactNative = typeof navigator !== "undefined" &&
3
- "product" in navigator &&
4
- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
5
- navigator.product === "ReactNative";
1
+ /**
2
+ * Platform runtime utilities and capability abstractions.
3
+ *
4
+ * @module
5
+ */
6
+ /** Returns true if running in React Native with Hermes engine. */
7
+ export const isHermes = "HermesInternal" in globalThis;
8
+ /** Returns true if running in a server environment (no DOM). */
9
+ export const isServer = typeof document === "undefined";
6
10
  /**
7
11
  * Detects if Node.js Buffer is available and should be used.
8
12
  *
@@ -14,4 +18,4 @@ export const isReactNative = typeof navigator !== "undefined" &&
14
18
  *
15
19
  * @see https://github.com/craftzdog/react-native-quick-base64#installation
16
20
  */
17
- export const hasNodeBuffer = !isReactNative && typeof globalThis.Buffer !== "undefined";
21
+ export const hasNodeBuffer = !isHermes && typeof globalThis.Buffer !== "undefined";
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Polyfills.
3
+ *
4
+ * @module
5
+ */
6
+ /**
7
+ * Installs polyfills required by `@evolu/common`.
8
+ *
9
+ * Installs resource-management polyfills (`Symbol.dispose`,
10
+ * `Symbol.asyncDispose`, `DisposableStack`, `AsyncDisposableStack`, and
11
+ * `SuppressedError`), which are not yet supported by Safari and React Native.
12
+ *
13
+ * Evolu currently does not require any additional polyfills. If that changes,
14
+ * this is where they will be installed.
15
+ *
16
+ * `@evolu/react-native` has its own `Polyfills` module and its
17
+ * `installPolyfills` calls this function first, then installs React Native
18
+ * specific polyfills.
19
+ *
20
+ * Call this explicitly from the app entry point.
21
+ *
22
+ * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Resource_management
23
+ * @see https://github.com/es-shims/DisposableStack
24
+ * @see https://github.com/es-shims/DisposableStack/issues/9
25
+ */
26
+ export declare const installPolyfills: () => void;
27
+ //# sourceMappingURL=Polyfills.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Polyfills.d.ts","sourceRoot":"","sources":["../../src/Polyfills.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,gBAAgB,QAAO,IAgBnC,CAAC"}