@evolu/common 5.4.7 → 6.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 (242) hide show
  1. package/README.md +30 -34
  2. package/dist/src/Array.d.ts +17 -0
  3. package/dist/src/Array.d.ts.map +1 -0
  4. package/dist/src/Array.js +12 -0
  5. package/dist/src/Assert.d.ts +68 -0
  6. package/dist/src/Assert.d.ts.map +1 -0
  7. package/dist/src/Assert.js +77 -0
  8. package/dist/src/BigInt.d.ts +20 -0
  9. package/dist/src/BigInt.d.ts.map +1 -0
  10. package/dist/src/BigInt.js +18 -0
  11. package/dist/src/Buffer.d.ts +92 -0
  12. package/dist/src/Buffer.d.ts.map +1 -0
  13. package/dist/src/Buffer.js +62 -0
  14. package/dist/src/Callbacks.d.ts +20 -0
  15. package/dist/src/Callbacks.d.ts.map +1 -0
  16. package/dist/src/Callbacks.js +18 -0
  17. package/dist/src/Console.d.ts +78 -0
  18. package/dist/src/Console.d.ts.map +1 -0
  19. package/dist/src/Console.js +103 -0
  20. package/dist/src/Crypto.d.ts +72 -39
  21. package/dist/src/Crypto.d.ts.map +1 -1
  22. package/dist/src/Crypto.js +89 -54
  23. package/dist/src/Eq.d.ts +97 -0
  24. package/dist/src/Eq.d.ts.map +1 -0
  25. package/dist/src/Eq.js +167 -0
  26. package/dist/src/Error.d.ts +14 -10
  27. package/dist/src/Error.d.ts.map +1 -1
  28. package/dist/src/Error.js +43 -11
  29. package/dist/src/Evolu/Config.d.ts +69 -0
  30. package/dist/src/Evolu/Config.d.ts.map +1 -0
  31. package/dist/src/Evolu/Config.js +9 -0
  32. package/dist/src/Evolu/Db.d.ts +126 -0
  33. package/dist/src/Evolu/Db.d.ts.map +1 -0
  34. package/dist/src/Evolu/Db.js +774 -0
  35. package/dist/src/Evolu/Diff.d.ts +43 -0
  36. package/dist/src/Evolu/Diff.d.ts.map +1 -0
  37. package/dist/src/Evolu/Diff.js +95 -0
  38. package/dist/src/Evolu/Evolu.d.ts +334 -0
  39. package/dist/src/Evolu/Evolu.d.ts.map +1 -0
  40. package/dist/src/Evolu/Evolu.js +434 -0
  41. package/dist/src/Evolu/Internal.d.ts +26 -0
  42. package/dist/src/Evolu/Internal.d.ts.map +1 -0
  43. package/dist/src/Evolu/Internal.js +25 -0
  44. package/dist/src/Evolu/Kysely.d.ts +6 -0
  45. package/dist/src/Evolu/Kysely.d.ts.map +1 -0
  46. package/dist/src/Evolu/Kysely.js +21 -0
  47. package/dist/src/Evolu/Owner.d.ts +155 -0
  48. package/dist/src/Evolu/Owner.d.ts.map +1 -0
  49. package/dist/src/Evolu/Owner.js +126 -0
  50. package/dist/src/Evolu/Platform.d.ts +23 -0
  51. package/dist/src/Evolu/Platform.d.ts.map +1 -0
  52. package/dist/src/Evolu/Platform.js +1 -0
  53. package/dist/src/Evolu/Protocol.d.ts +401 -0
  54. package/dist/src/Evolu/Protocol.d.ts.map +1 -0
  55. package/dist/src/Evolu/Protocol.js +1151 -0
  56. package/dist/src/Evolu/Public.d.ts +18 -0
  57. package/dist/src/Evolu/Public.d.ts.map +1 -0
  58. package/dist/src/Evolu/Public.js +11 -0
  59. package/dist/src/Evolu/PublicKysely.d.ts +148 -0
  60. package/dist/src/Evolu/PublicKysely.d.ts.map +1 -0
  61. package/dist/src/Evolu/PublicKysely.js +185 -0
  62. package/dist/src/Evolu/Query.d.ts +63 -0
  63. package/dist/src/Evolu/Query.d.ts.map +1 -0
  64. package/dist/src/Evolu/Query.js +61 -0
  65. package/dist/src/Evolu/Relay.d.ts +13 -0
  66. package/dist/src/Evolu/Relay.d.ts.map +1 -0
  67. package/dist/src/Evolu/Relay.js +109 -0
  68. package/dist/src/Evolu/Schema.d.ts +201 -0
  69. package/dist/src/Evolu/Schema.d.ts.map +1 -0
  70. package/dist/src/Evolu/Schema.js +150 -0
  71. package/dist/src/Evolu/Storage.d.ts +49 -0
  72. package/dist/src/Evolu/Storage.d.ts.map +1 -0
  73. package/dist/src/Evolu/Storage.js +1111 -0
  74. package/dist/src/Evolu/Sync.d.ts +59 -0
  75. package/dist/src/Evolu/Sync.d.ts.map +1 -0
  76. package/dist/src/Evolu/Sync.js +29 -0
  77. package/dist/src/Evolu/Timestamp.d.ts +106 -0
  78. package/dist/src/Evolu/Timestamp.d.ts.map +1 -0
  79. package/dist/src/Evolu/Timestamp.js +179 -0
  80. package/dist/src/Function.d.ts +54 -0
  81. package/dist/src/Function.d.ts.map +1 -0
  82. package/dist/src/Function.js +38 -0
  83. package/dist/src/ManyToManyMap.d.ts +26 -0
  84. package/dist/src/ManyToManyMap.d.ts.map +1 -0
  85. package/dist/src/ManyToManyMap.js +92 -0
  86. package/dist/src/NanoId.d.ts +27 -0
  87. package/dist/src/NanoId.d.ts.map +1 -0
  88. package/dist/src/NanoId.js +6 -0
  89. package/dist/src/Number.d.ts +42 -0
  90. package/dist/src/Number.d.ts.map +1 -0
  91. package/dist/src/Number.js +55 -0
  92. package/dist/src/Object.d.ts +35 -0
  93. package/dist/src/Object.d.ts.map +1 -0
  94. package/dist/src/Object.js +36 -0
  95. package/dist/src/Order.d.ts +90 -0
  96. package/dist/src/Order.d.ts.map +1 -0
  97. package/dist/src/Order.js +85 -0
  98. package/dist/src/Promise.d.ts +180 -0
  99. package/dist/src/Promise.d.ts.map +1 -0
  100. package/dist/src/Promise.js +176 -0
  101. package/dist/src/Random.d.ts +52 -0
  102. package/dist/src/Random.d.ts.map +1 -0
  103. package/dist/src/Random.js +29 -0
  104. package/dist/src/Ref.d.ts +40 -0
  105. package/dist/src/Ref.d.ts.map +1 -0
  106. package/dist/src/Ref.js +13 -0
  107. package/dist/src/Result.d.ts +421 -0
  108. package/dist/src/Result.d.ts.map +1 -0
  109. package/dist/src/Result.js +357 -0
  110. package/dist/src/Skiplist.d.ts +23 -0
  111. package/dist/src/Skiplist.d.ts.map +1 -0
  112. package/dist/src/Skiplist.js +58 -0
  113. package/dist/src/Sqlite.d.ts +116 -52
  114. package/dist/src/Sqlite.d.ts.map +1 -1
  115. package/dist/src/Sqlite.js +183 -67
  116. package/dist/src/Store.d.ts +45 -8
  117. package/dist/src/Store.d.ts.map +1 -1
  118. package/dist/src/Store.js +33 -17
  119. package/dist/src/String.d.ts +2 -0
  120. package/dist/src/String.d.ts.map +1 -0
  121. package/dist/src/String.js +14 -0
  122. package/dist/src/Time.d.ts +20 -0
  123. package/dist/src/Time.d.ts.map +1 -0
  124. package/dist/src/Time.js +25 -0
  125. package/dist/src/Type.d.ts +1937 -0
  126. package/dist/src/Type.d.ts.map +1 -0
  127. package/dist/src/Type.js +2002 -0
  128. package/dist/src/Types.d.ts +188 -0
  129. package/dist/src/Types.d.ts.map +1 -0
  130. package/dist/src/Types.js +6 -0
  131. package/dist/src/WebSocket.d.ts +112 -0
  132. package/dist/src/WebSocket.d.ts.map +1 -0
  133. package/dist/src/WebSocket.js +139 -0
  134. package/dist/src/Worker.d.ts +44 -0
  135. package/dist/src/Worker.d.ts.map +1 -0
  136. package/dist/src/Worker.js +66 -0
  137. package/dist/src/index.d.ts +24 -11
  138. package/dist/src/index.d.ts.map +1 -1
  139. package/dist/src/index.js +24 -11
  140. package/package.json +29 -38
  141. package/src/Array.ts +39 -0
  142. package/src/Assert.ts +116 -0
  143. package/src/BigInt.ts +29 -0
  144. package/src/Buffer.ts +175 -0
  145. package/src/Callbacks.ts +43 -0
  146. package/src/Console.ts +159 -0
  147. package/src/Crypto.ts +169 -115
  148. package/src/Eq.ts +204 -0
  149. package/src/Error.ts +57 -20
  150. package/src/Evolu/Config.ts +83 -0
  151. package/src/Evolu/Db.ts +1275 -0
  152. package/src/Evolu/Diff.ts +142 -0
  153. package/src/Evolu/Evolu.ts +947 -0
  154. package/src/Evolu/Internal.ts +26 -0
  155. package/src/Evolu/Kysely.ts +38 -0
  156. package/src/Evolu/Owner.ts +296 -0
  157. package/src/Evolu/Platform.ts +27 -0
  158. package/src/Evolu/Protocol.ts +1857 -0
  159. package/src/Evolu/Public.ts +43 -0
  160. package/src/Evolu/PublicKysely.ts +240 -0
  161. package/src/Evolu/Query.ts +167 -0
  162. package/src/Evolu/Relay.ts +142 -0
  163. package/src/Evolu/Schema.ts +417 -0
  164. package/src/Evolu/Storage.ts +1281 -0
  165. package/src/Evolu/Sync.ts +105 -0
  166. package/src/Evolu/Timestamp.ts +311 -0
  167. package/src/Function.ts +58 -0
  168. package/src/ManyToManyMap.ts +140 -0
  169. package/src/NanoId.ts +39 -0
  170. package/src/Number.ts +90 -0
  171. package/src/Object.ts +64 -0
  172. package/src/Order.ts +113 -0
  173. package/src/Promise.ts +295 -0
  174. package/src/Random.ts +68 -0
  175. package/src/Ref.ts +63 -0
  176. package/src/Result.ts +453 -0
  177. package/src/Skiplist.ts +102 -0
  178. package/src/Sqlite.ts +366 -153
  179. package/src/Store.ts +79 -36
  180. package/src/String.ts +10 -0
  181. package/src/Time.ts +36 -0
  182. package/src/Type.ts +3978 -0
  183. package/src/Types.ts +209 -0
  184. package/src/WebSocket.ts +273 -0
  185. package/src/Worker.ts +129 -0
  186. package/src/index.ts +24 -11
  187. package/dist/src/Config.d.ts +0 -56
  188. package/dist/src/Config.d.ts.map +0 -1
  189. package/dist/src/Config.js +0 -39
  190. package/dist/src/Crdt.d.ts +0 -89
  191. package/dist/src/Crdt.d.ts.map +0 -1
  192. package/dist/src/Crdt.js +0 -181
  193. package/dist/src/Db.d.ts +0 -107
  194. package/dist/src/Db.d.ts.map +0 -1
  195. package/dist/src/Db.js +0 -443
  196. package/dist/src/Diff.d.ts +0 -27
  197. package/dist/src/Diff.d.ts.map +0 -1
  198. package/dist/src/Diff.js +0 -84
  199. package/dist/src/Evolu.d.ts +0 -426
  200. package/dist/src/Evolu.d.ts.map +0 -1
  201. package/dist/src/Evolu.js +0 -333
  202. package/dist/src/Model.d.ts +0 -141
  203. package/dist/src/Model.d.ts.map +0 -1
  204. package/dist/src/Model.js +0 -125
  205. package/dist/src/Murmurhash.d.ts +0 -2
  206. package/dist/src/Murmurhash.d.ts.map +0 -1
  207. package/dist/src/Murmurhash.js +0 -60
  208. package/dist/src/Owner.d.ts +0 -33
  209. package/dist/src/Owner.d.ts.map +0 -1
  210. package/dist/src/Owner.js +0 -26
  211. package/dist/src/Platform.d.ts +0 -37
  212. package/dist/src/Platform.d.ts.map +0 -1
  213. package/dist/src/Platform.js +0 -11
  214. package/dist/src/Protobuf.d.ts +0 -81
  215. package/dist/src/Protobuf.d.ts.map +0 -1
  216. package/dist/src/Protobuf.js +0 -92
  217. package/dist/src/Public.d.ts +0 -13
  218. package/dist/src/Public.d.ts.map +0 -1
  219. package/dist/src/Public.js +0 -6
  220. package/dist/src/Socket.d.ts +0 -8
  221. package/dist/src/Socket.d.ts.map +0 -1
  222. package/dist/src/Socket.js +0 -51
  223. package/dist/src/Sql.d.ts +0 -12
  224. package/dist/src/Sql.d.ts.map +0 -1
  225. package/dist/src/Sql.js +0 -30
  226. package/dist/src/Sync.d.ts +0 -70
  227. package/dist/src/Sync.d.ts.map +0 -1
  228. package/dist/src/Sync.js +0 -127
  229. package/src/Config.ts +0 -119
  230. package/src/Crdt.ts +0 -361
  231. package/src/Db.ts +0 -955
  232. package/src/Diff.ts +0 -114
  233. package/src/Evolu.ts +0 -1016
  234. package/src/Model.ts +0 -233
  235. package/src/Murmurhash.ts +0 -70
  236. package/src/Owner.ts +0 -69
  237. package/src/Platform.ts +0 -47
  238. package/src/Protobuf.ts +0 -155
  239. package/src/Public.ts +0 -12
  240. package/src/Socket.ts +0 -83
  241. package/src/Sql.ts +0 -41
  242. package/src/Sync.ts +0 -315
@@ -0,0 +1,176 @@
1
+ import { constTrue } from "./Function.js";
2
+ import { err, ok } from "./Result.js";
3
+ /**
4
+ * Helper function to delay execution for a specified number of milliseconds.
5
+ *
6
+ * ### Example
7
+ *
8
+ * ```ts
9
+ * await wait(10);
10
+ * ```
11
+ */
12
+ export const wait = (ms) => new Promise((resolve) => setTimeout(() => {
13
+ resolve(ok());
14
+ }, ms));
15
+ /**
16
+ * Executes a function with retry logic using exponential backoff and jitter.
17
+ *
18
+ * ### Example with Result-based API
19
+ *
20
+ * ```ts
21
+ * interface ApiError {
22
+ * type: "ApiError";
23
+ * statusCode: number;
24
+ * }
25
+ *
26
+ * const fetchData = async (
27
+ * url: string,
28
+ * ): Promise<Result<Data, ApiError>> => {
29
+ * // Implementation that returns Result
30
+ * };
31
+ *
32
+ * const result = await retry(
33
+ * async () => fetchData("https://api.example.com/data"),
34
+ * {
35
+ * maxRetries: 5,
36
+ * initialDelay: 200,
37
+ * // Only retry on specific status codes
38
+ * retryable: (error) =>
39
+ * error.type === "ApiError" && [429, 503].includes(error.statusCode),
40
+ * },
41
+ * );
42
+ *
43
+ * if (!result.ok) {
44
+ * if (result.error.type === "RetryAbortError") {
45
+ * console.log("Operation was aborted");
46
+ * } else {
47
+ * console.log(`Failed after ${result.error.attempts} attempts`);
48
+ * }
49
+ * return;
50
+ * }
51
+ *
52
+ * // Use result.value
53
+ * ```
54
+ *
55
+ * ### Example with tryAsync for exception-based API
56
+ *
57
+ * ```ts
58
+ * interface FetchError {
59
+ * type: "FetchError";
60
+ * message: string;
61
+ * }
62
+ *
63
+ * const controller = new AbortController();
64
+ *
65
+ * const result = await retry(
66
+ * async () =>
67
+ * tryAsync(
68
+ * async () => {
69
+ * const response = await fetch("https://api.example.com/data", {
70
+ * signal: controller.signal,
71
+ * });
72
+ *
73
+ * if (!response.ok) {
74
+ * throw new Error(`HTTP error ${response.status}`);
75
+ * }
76
+ *
77
+ * return await response.json();
78
+ * },
79
+ * (error): FetchError => ({
80
+ * type: "FetchError",
81
+ * message: String(error),
82
+ * }),
83
+ * ),
84
+ * {
85
+ * maxRetries: 3,
86
+ * signal: controller.signal,
87
+ * },
88
+ * );
89
+ * ```
90
+ *
91
+ * ## HTTP Request Recommendations
92
+ *
93
+ * For HTTP requests, configure the `retryable` option to only retry on
94
+ * appropriate errors:
95
+ *
96
+ * - **DO retry**: 429 (Too Many Requests), 503 (Service Unavailable), network
97
+ * errors
98
+ * - **DON'T retry**: 4xx client errors (except 429), most 5xx server errors
99
+ */
100
+ export const retry = async (fn, options = {}) => {
101
+ const { maxRetries = 3, initialDelay = 100, maxDelay = 10000, factor = 2, jitter = 0.1, signal, retryable = constTrue, onRetry, } = options;
102
+ let attempt = 0;
103
+ if (signal?.aborted) {
104
+ return err({ type: "RetryAbortError", abortedBeforeExecution: true });
105
+ }
106
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
107
+ while (true) {
108
+ const result = await fn();
109
+ if (result.ok) {
110
+ return result;
111
+ }
112
+ attempt += 1;
113
+ if (attempt > maxRetries || !retryable(result.error)) {
114
+ return err({
115
+ type: "RetryError",
116
+ cause: result.error,
117
+ attempts: attempt,
118
+ });
119
+ }
120
+ // Calculate delay with exponential backoff
121
+ const exponentialDelay = initialDelay * Math.pow(factor, attempt);
122
+ const cappedDelay = Math.min(exponentialDelay, maxDelay);
123
+ // Apply jitter to prevent thundering herd problem
124
+ const randomFactor = 1 - jitter + Math.random() * jitter * 2;
125
+ const delay = Math.floor(cappedDelay * randomFactor);
126
+ if (onRetry) {
127
+ onRetry(result.error, attempt, delay);
128
+ }
129
+ if (signal?.aborted) {
130
+ return err({ type: "RetryAbortError", abortedBeforeExecution: false });
131
+ }
132
+ // Wait with abort support
133
+ if (signal) {
134
+ const abortPromise = new Promise((resolve) => {
135
+ const onAbort = () => {
136
+ resolve(err({ type: "RetryAbortError", abortedBeforeExecution: false }));
137
+ };
138
+ signal.addEventListener("abort", onAbort, { once: true });
139
+ });
140
+ const delayPromise = wait(delay);
141
+ const raceResult = await Promise.race([abortPromise, delayPromise]);
142
+ if (!raceResult.ok) {
143
+ return raceResult;
144
+ }
145
+ }
146
+ else {
147
+ await wait(delay);
148
+ }
149
+ }
150
+ };
151
+ /**
152
+ * Wraps an async function with a timeout, returning {@link Result} that fails
153
+ * with {@link TimeoutError} if the timeout is exceeded. The provided function
154
+ * must accept an AbortSignal and return a Result.
155
+ *
156
+ * ### Example
157
+ *
158
+ * ```ts
159
+ * const fetchWithTimeout = () =>
160
+ * withTimeout((signal) => fetch("url", signal), 5000);
161
+ * const result = await retry(fetchWithTimeout, { maxRetries: 3 });
162
+ * ```
163
+ */
164
+ export const withTimeout = async (fn, timeoutMs) => {
165
+ const controller = new AbortController();
166
+ const signal = controller.signal;
167
+ const timeoutId = setTimeout(() => {
168
+ controller.abort();
169
+ }, timeoutMs);
170
+ const result = await fn(signal);
171
+ clearTimeout(timeoutId);
172
+ if (signal.aborted) {
173
+ return err({ type: "TimeoutError", timeoutMs });
174
+ }
175
+ return result;
176
+ };
@@ -0,0 +1,52 @@
1
+ /**
2
+ * 🎲
3
+ *
4
+ * @module
5
+ */
6
+ import { Random as RandomLib } from "random";
7
+ /**
8
+ * A simple wrapper around Math.random(). Most apps need only this. For more
9
+ * complex needs check {@link RandomLibDep}.
10
+ *
11
+ * ### Example
12
+ *
13
+ * ```ts
14
+ * // For apps
15
+ * const random = createRandom();
16
+ * random.next();
17
+ *
18
+ * // For tests
19
+ * const random = createRandomWithSeed("test");
20
+ * random.next();
21
+ * ```
22
+ */
23
+ export interface Random {
24
+ /** Returns a floating point number in [0, 1). Just like Math.random(). */
25
+ next: () => number;
26
+ }
27
+ export interface RandomDep {
28
+ random: Random;
29
+ }
30
+ /** Creates a {@link Random} using Math.random(). */
31
+ export declare const createRandom: () => Random;
32
+ /**
33
+ * Creates {@link Random} using {@link RandomLibDep} with a seed which is useful
34
+ * for tests.
35
+ */
36
+ export declare const createRandomWithSeed: (seed: string) => Random;
37
+ /**
38
+ * A random number generator using the NPM `random` package dependency.
39
+ *
40
+ * https://github.com/transitive-bullshit/random
41
+ */
42
+ export interface RandomLibDep {
43
+ random: RandomLib;
44
+ }
45
+ /** Creates a `RandomLib` using the NPM `random` package. */
46
+ export declare const createRandomLib: () => RandomLib;
47
+ /**
48
+ * Creates {@link RandomLibDep} using the NPM `random` package with a seed which
49
+ * is useful for tests.
50
+ */
51
+ export declare const createRandomLibWithSeed: (seed: string) => RandomLibDep;
52
+ //# sourceMappingURL=Random.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Random.d.ts","sourceRoot":"","sources":["../../src/Random.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,MAAM,IAAI,SAAS,EAAE,MAAM,QAAQ,CAAC;AAE7C;;;;;;;;;;;;;;;GAeG;AACH,MAAM,WAAW,MAAM;IACrB,0EAA0E;IAC1E,IAAI,EAAE,MAAM,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,oDAAoD;AACpD,eAAO,MAAM,YAAY,QAAO,MAE9B,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAM,oBAAoB,GAAI,MAAM,MAAM,KAAG,MAKnD,CAAC;AAEF;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,SAAS,CAAC;CACnB;AAED,4DAA4D;AAC5D,eAAO,MAAM,eAAe,QAAO,SAA4B,CAAC;AAEhE;;;GAGG;AACH,eAAO,MAAM,uBAAuB,GAAI,MAAM,MAAM,KAAG,YAErD,CAAC"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * 🎲
3
+ *
4
+ * @module
5
+ */
6
+ import { Random as RandomLib } from "random";
7
+ /** Creates a {@link Random} using Math.random(). */
8
+ export const createRandom = () => ({
9
+ next: () => Math.random(),
10
+ });
11
+ /**
12
+ * Creates {@link Random} using {@link RandomLibDep} with a seed which is useful
13
+ * for tests.
14
+ */
15
+ export const createRandomWithSeed = (seed) => {
16
+ const random = new RandomLib(seed);
17
+ return {
18
+ next: () => random.next(),
19
+ };
20
+ };
21
+ /** Creates a `RandomLib` using the NPM `random` package. */
22
+ export const createRandomLib = () => new RandomLib();
23
+ /**
24
+ * Creates {@link RandomLibDep} using the NPM `random` package with a seed which
25
+ * is useful for tests.
26
+ */
27
+ export const createRandomLibWithSeed = (seed) => ({
28
+ random: new RandomLib(seed),
29
+ });
@@ -0,0 +1,40 @@
1
+ /**
2
+ * `Ref` provides a simple API to hold and update a value, similar to a "ref" in
3
+ * functional programming or React. It exposes methods to get, set, and modify
4
+ * the current state.
5
+ *
6
+ * Use a Ref instead of a variable when you want to pass state around as an
7
+ * object or update it in a controlled way. If you need subscriptions, see
8
+ * {@link Store}.
9
+ *
10
+ * Updating in a controlled way means all changes go through specific methods
11
+ * (`set` or `modify`), making state updates predictable and easy to track.
12
+ *
13
+ * ### Example
14
+ *
15
+ * ```ts
16
+ * const count = createRef(0);
17
+ * count.set(1);
18
+ * count.modify((n) => n + 1);
19
+ * console.log(count.get()); // 2
20
+ * ```
21
+ *
22
+ * ### Example of using Ref as a dependency
23
+ *
24
+ * ```ts
25
+ * interface CounterRefDep {
26
+ * readonly counterRef: Ref<number>;
27
+ * }
28
+ * ```
29
+ */
30
+ export interface Ref<T> {
31
+ /** Returns the current state. */
32
+ readonly get: () => T;
33
+ /** Sets the state. */
34
+ readonly set: (state: T) => void;
35
+ /** Modifies the state using an updater function. */
36
+ readonly modify: (updater: (current: T) => T) => void;
37
+ }
38
+ /** Creates a {@link Ref} with the given initial state. */
39
+ export declare const createRef: <T>(initialState: T) => Ref<T>;
40
+ //# sourceMappingURL=Ref.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Ref.d.ts","sourceRoot":"","sources":["../../src/Ref.ts"],"names":[],"mappings":"AAOA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,MAAM,WAAW,GAAG,CAAC,CAAC;IACpB,iCAAiC;IACjC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IAEtB,sBAAsB;IACtB,QAAQ,CAAC,GAAG,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC;IAEjC,oDAAoD;IACpD,QAAQ,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC;CACvD;AAED,0DAA0D;AAC1D,eAAO,MAAM,SAAS,GAAI,CAAC,EAAE,cAAc,CAAC,KAAG,GAAG,CAAC,CAAC,CAcnD,CAAC"}
@@ -0,0 +1,13 @@
1
+ /** Creates a {@link Ref} with the given initial state. */
2
+ export const createRef = (initialState) => {
3
+ let currentState = initialState;
4
+ return {
5
+ get: () => currentState,
6
+ set: (state) => {
7
+ currentState = state;
8
+ },
9
+ modify: (updater) => {
10
+ currentState = updater(currentState);
11
+ },
12
+ };
13
+ };