@evolu/common 6.0.1-preview.2 → 6.0.1-preview.21

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 (154) hide show
  1. package/dist/src/Assert.d.ts +6 -3
  2. package/dist/src/Assert.d.ts.map +1 -1
  3. package/dist/src/Assert.js +7 -4
  4. package/dist/src/Brand.d.ts +75 -0
  5. package/dist/src/Brand.d.ts.map +1 -0
  6. package/dist/src/Brand.js +1 -0
  7. package/dist/src/Buffer.d.ts +1 -1
  8. package/dist/src/Buffer.d.ts.map +1 -1
  9. package/dist/src/Buffer.js +1 -1
  10. package/dist/src/CallbackRegistry.d.ts +53 -0
  11. package/dist/src/CallbackRegistry.d.ts.map +1 -0
  12. package/dist/src/CallbackRegistry.js +25 -0
  13. package/dist/src/Console.d.ts +31 -6
  14. package/dist/src/Console.d.ts.map +1 -1
  15. package/dist/src/Console.js +72 -9
  16. package/dist/src/Crypto.d.ts +61 -34
  17. package/dist/src/Crypto.d.ts.map +1 -1
  18. package/dist/src/Crypto.js +29 -42
  19. package/dist/src/Evolu/Db.d.ts +159 -66
  20. package/dist/src/Evolu/Db.d.ts.map +1 -1
  21. package/dist/src/Evolu/Db.js +300 -705
  22. package/dist/src/Evolu/Diff.d.ts +3 -3
  23. package/dist/src/Evolu/Diff.d.ts.map +1 -1
  24. package/dist/src/Evolu/Diff.js +7 -5
  25. package/dist/src/Evolu/Evolu.d.ts +200 -115
  26. package/dist/src/Evolu/Evolu.d.ts.map +1 -1
  27. package/dist/src/Evolu/Evolu.js +287 -157
  28. package/dist/src/Evolu/Internal.d.ts +0 -2
  29. package/dist/src/Evolu/Internal.d.ts.map +1 -1
  30. package/dist/src/Evolu/Internal.js +0 -2
  31. package/dist/src/Evolu/LocalAuth.d.ts +144 -0
  32. package/dist/src/Evolu/LocalAuth.d.ts.map +1 -0
  33. package/dist/src/Evolu/LocalAuth.js +171 -0
  34. package/dist/src/Evolu/Owner.d.ts +209 -124
  35. package/dist/src/Evolu/Owner.d.ts.map +1 -1
  36. package/dist/src/Evolu/Owner.js +118 -104
  37. package/dist/src/Evolu/Platform.d.ts +9 -7
  38. package/dist/src/Evolu/Platform.d.ts.map +1 -1
  39. package/dist/src/Evolu/Protocol.d.ts +256 -211
  40. package/dist/src/Evolu/Protocol.d.ts.map +1 -1
  41. package/dist/src/Evolu/Protocol.js +558 -359
  42. package/dist/src/Evolu/Public.d.ts +6 -8
  43. package/dist/src/Evolu/Public.d.ts.map +1 -1
  44. package/dist/src/Evolu/Public.js +2 -3
  45. package/dist/src/Evolu/PublicKysely.js +3 -3
  46. package/dist/src/Evolu/Query.d.ts +2 -1
  47. package/dist/src/Evolu/Query.d.ts.map +1 -1
  48. package/dist/src/Evolu/Relay.d.ts +72 -4
  49. package/dist/src/Evolu/Relay.d.ts.map +1 -1
  50. package/dist/src/Evolu/Relay.js +124 -13
  51. package/dist/src/Evolu/Schema.d.ts +129 -73
  52. package/dist/src/Evolu/Schema.d.ts.map +1 -1
  53. package/dist/src/Evolu/Schema.js +169 -89
  54. package/dist/src/Evolu/Storage.d.ts +159 -14
  55. package/dist/src/Evolu/Storage.d.ts.map +1 -1
  56. package/dist/src/Evolu/Storage.js +42 -32
  57. package/dist/src/Evolu/Sync.d.ts +68 -13
  58. package/dist/src/Evolu/Sync.d.ts.map +1 -1
  59. package/dist/src/Evolu/Sync.js +414 -20
  60. package/dist/src/Evolu/Timestamp.d.ts +35 -27
  61. package/dist/src/Evolu/Timestamp.d.ts.map +1 -1
  62. package/dist/src/Evolu/Timestamp.js +27 -18
  63. package/dist/src/ManyToManyMap.d.ts +74 -10
  64. package/dist/src/ManyToManyMap.d.ts.map +1 -1
  65. package/dist/src/ManyToManyMap.js +41 -6
  66. package/dist/src/Number.d.ts +2 -1
  67. package/dist/src/Number.d.ts.map +1 -1
  68. package/dist/src/Random.d.ts +3 -2
  69. package/dist/src/Random.d.ts.map +1 -1
  70. package/dist/src/RefCountedResourceManager.d.ts +119 -0
  71. package/dist/src/RefCountedResourceManager.d.ts.map +1 -0
  72. package/dist/src/RefCountedResourceManager.js +197 -0
  73. package/dist/src/Result.d.ts +176 -51
  74. package/dist/src/Result.d.ts.map +1 -1
  75. package/dist/src/Result.js +30 -241
  76. package/dist/src/Sqlite.d.ts +21 -4
  77. package/dist/src/Sqlite.d.ts.map +1 -1
  78. package/dist/src/Sqlite.js +50 -8
  79. package/dist/src/Task.d.ts +511 -0
  80. package/dist/src/Task.d.ts.map +1 -0
  81. package/dist/src/Task.js +410 -0
  82. package/dist/src/Time.d.ts +59 -0
  83. package/dist/src/Time.d.ts.map +1 -1
  84. package/dist/src/Time.js +87 -4
  85. package/dist/src/Type.d.ts +474 -327
  86. package/dist/src/Type.d.ts.map +1 -1
  87. package/dist/src/Type.js +502 -436
  88. package/dist/src/Types.d.ts +0 -74
  89. package/dist/src/Types.d.ts.map +1 -1
  90. package/dist/src/WebSocket.d.ts +5 -2
  91. package/dist/src/WebSocket.d.ts.map +1 -1
  92. package/dist/src/WebSocket.js +12 -13
  93. package/dist/src/Worker.d.ts +39 -11
  94. package/dist/src/Worker.d.ts.map +1 -1
  95. package/dist/src/Worker.js +22 -4
  96. package/dist/src/index.d.ts +3 -3
  97. package/dist/src/index.d.ts.map +1 -1
  98. package/dist/src/index.js +3 -3
  99. package/package.json +14 -13
  100. package/src/Assert.ts +8 -7
  101. package/src/Brand.ts +75 -0
  102. package/src/Buffer.ts +1 -1
  103. package/src/CallbackRegistry.ts +84 -0
  104. package/src/Console.ts +91 -11
  105. package/src/Crypto.ts +94 -79
  106. package/src/Evolu/Db.ts +528 -1027
  107. package/src/Evolu/Diff.ts +7 -5
  108. package/src/Evolu/Evolu.ts +682 -329
  109. package/src/Evolu/Internal.ts +0 -2
  110. package/src/Evolu/LocalAuth.ts +422 -0
  111. package/src/Evolu/Owner.ts +282 -227
  112. package/src/Evolu/Platform.ts +9 -9
  113. package/src/Evolu/Protocol.ts +788 -640
  114. package/src/Evolu/Public.ts +7 -14
  115. package/src/Evolu/PublicKysely.ts +3 -3
  116. package/src/Evolu/Query.ts +2 -1
  117. package/src/Evolu/Relay.ts +238 -18
  118. package/src/Evolu/Schema.ts +391 -191
  119. package/src/Evolu/Storage.ts +275 -55
  120. package/src/Evolu/Sync.ts +708 -37
  121. package/src/Evolu/Timestamp.ts +38 -35
  122. package/src/ManyToManyMap.ts +127 -24
  123. package/src/Number.ts +2 -6
  124. package/src/Random.ts +3 -2
  125. package/src/RefCountedResourceManager.ts +368 -0
  126. package/src/Result.ts +183 -53
  127. package/src/Sqlite.ts +59 -23
  128. package/src/Task.ts +779 -0
  129. package/src/Time.ts +168 -4
  130. package/src/Type.ts +708 -660
  131. package/src/Types.ts +0 -76
  132. package/src/WebSocket.ts +23 -17
  133. package/src/Worker.ts +72 -23
  134. package/src/index.ts +3 -3
  135. package/dist/src/Callbacks.d.ts +0 -20
  136. package/dist/src/Callbacks.d.ts.map +0 -1
  137. package/dist/src/Callbacks.js +0 -18
  138. package/dist/src/Evolu/Config.d.ts +0 -69
  139. package/dist/src/Evolu/Config.d.ts.map +0 -1
  140. package/dist/src/Evolu/Config.js +0 -9
  141. package/dist/src/Evolu/Kysely.d.ts +0 -6
  142. package/dist/src/Evolu/Kysely.d.ts.map +0 -1
  143. package/dist/src/Evolu/Kysely.js +0 -21
  144. package/dist/src/NanoId.d.ts +0 -27
  145. package/dist/src/NanoId.d.ts.map +0 -1
  146. package/dist/src/NanoId.js +0 -6
  147. package/dist/src/Promise.d.ts +0 -180
  148. package/dist/src/Promise.d.ts.map +0 -1
  149. package/dist/src/Promise.js +0 -176
  150. package/src/Callbacks.ts +0 -43
  151. package/src/Evolu/Config.ts +0 -83
  152. package/src/Evolu/Kysely.ts +0 -38
  153. package/src/NanoId.ts +0 -39
  154. package/src/Promise.ts +0 -295
@@ -70,79 +70,6 @@ export type NullablePartial<T, NK extends keyof T = {
70
70
  * needed and unit tests exist to ensure correctness.
71
71
  */
72
72
  export type IntentionalNever = never;
73
- /**
74
- * A utility interface for creating branded types.
75
- *
76
- * Branded types enhance type safety by differentiating otherwise identical base
77
- * types, such as `number` or `string`, to enforce stricter type checks.
78
- *
79
- * Supports multiple brands, allowing types to act like flags.
80
- *
81
- * ### Example 1: Single Brand
82
- *
83
- * ```ts
84
- * // A branded type definition
85
- * type UserId = number & Brand<"UserId">;
86
- *
87
- * // A function that creates `UserId` values.
88
- * // Casting with `as UserId` is unsafe, so `createUserId` must be unit-tested.
89
- * const createUserId = (): UserId => {
90
- * return 123 as UserId; // Unsafe casting
91
- * };
92
- *
93
- * const userId = createUserId();
94
- *
95
- * // A function that accepts only `UserId`.
96
- * const getUser = (id: UserId) => {
97
- * // Implementation
98
- * };
99
- *
100
- * getUser(userId); // ✅ Valid
101
- * getUser(123); // ❌ TypeScript error
102
- * getUser("123"); // ❌ TypeScript error
103
- * ```
104
- *
105
- * ### Example 2: Multiple Brands
106
- *
107
- * ```ts
108
- * // Define branded types
109
- * type Min1 = string & Brand<"Min1">;
110
- * type Max100 = string & Brand<"Max100">;
111
- * type Min1Max100 = string & Brand<"Min1" | "Max100">;
112
- *
113
- * // Functions requiring specific brands
114
- * const requiresMin1 = (value: Min1): void => {};
115
- * const requiresMax100 = (value: Max100): void => {};
116
- *
117
- * // Values with single brands
118
- * const min1Value: Min1 = "hello" as Min1;
119
- * const max100Value: Max100 = "world" as Max100;
120
- *
121
- * // Value with multiple brands
122
- * const min1Max100Value: Min1Max100 = "typescript" as Min1Max100;
123
- *
124
- * // Valid cases
125
- * requiresMin1(min1Value); // ✅ Valid
126
- * requiresMax100(max100Value); // ✅ Valid
127
- * requiresMin1(min1Max100Value); // ✅ Valid: Min1Max100 satisfies Min1
128
- * requiresMax100(min1Max100Value); // ✅ Valid: Min1Max100 satisfies Max100
129
- * ```
130
- */
131
- export interface Brand<B extends string> {
132
- readonly [__brand]: Readonly<Record<B, true>>;
133
- }
134
- declare const __brand: unique symbol;
135
- /**
136
- * Determines whether a type `T` is a branded type.
137
- *
138
- * Works with any base type intersected with a `Brand`.
139
- *
140
- * ### Examples
141
- *
142
- * - `IsBranded<string>` -> false
143
- * - `IsBranded<string & Brand<"X">>` -> true
144
- */
145
- export type IsBranded<T> = T extends Brand<string> ? true : false;
146
73
  /**
147
74
  * String | number | bigint | boolean | undefined | null
148
75
  *
@@ -184,5 +111,4 @@ export type Simplify<T> = Kysely.Simplify<T>;
184
111
  * unchanged.
185
112
  */
186
113
  export type PartialProp<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
187
- export {};
188
114
  //# sourceMappingURL=Types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Types.d.ts","sourceRoot":"","sources":["../../src/Types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAC;AAEjC;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,SAAS,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,KAAK,OAAO,CAAC;AAEjD;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,MAAM,UAAU,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;AAEjE;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,MAAM,eAAe,CACzB,CAAC,EACD,EAAE,SAAS,MAAM,CAAC,GAAG;KAClB,CAAC,IAAI,MAAM,CAAC,GAAG,IAAI,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK;CAC9C,CAAC,MAAM,CAAC,CAAC,EACV,EAAE,GAAG,IAAI,CAAC,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IACvD;KAAG,CAAC,IAAI,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;CAAE,CAAC;AAE/B;;;GAGG;AACH,MAAM,MAAM,gBAAgB,GAAG,KAAK,CAAC;AAErC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyDG;AACH,MAAM,WAAW,KAAK,CAAC,CAAC,SAAS,MAAM;IACrC,QAAQ,CAAC,CAAC,OAAO,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;CAC/C;AAED,OAAO,CAAC,MAAM,OAAO,EAAE,OAAO,MAAM,CAAC;AAErC;;;;;;;;;GASG;AACH,MAAM,MAAM,SAAS,CAAC,CAAC,IAAI,CAAC,SAAS,KAAK,CAAC,MAAM,CAAC,GAAG,IAAI,GAAG,KAAK,CAAC;AAElE;;;;GAIG;AACH,MAAM,MAAM,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,GAAG,IAAI,CAAC;AAE5E;;;;;;;;;GASG;AACH,MAAM,MAAM,YAAY,CAAC,CAAC,SAAS,OAAO,IAAI,CAAC,SAAS,MAAM,GAC1D,MAAM,GACN,CAAC,SAAS,MAAM,GACd,MAAM,GACN,CAAC,SAAS,OAAO,GACf,OAAO,GACP,CAAC,SAAS,MAAM,GACd,MAAM,GACN,CAAC,CAAC;AAEZ;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,MAAM,QAAQ,CAAC,CAAC,IAAI,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AAE7C;;;GAGG;AACH,MAAM,MAAM,WAAW,CAAC,CAAC,EAAE,CAAC,SAAS,MAAM,CAAC,IAAI,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,GACxD,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"Types.d.ts","sourceRoot":"","sources":["../../src/Types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAC;AAEjC;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,SAAS,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,KAAK,OAAO,CAAC;AAEjD;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,MAAM,UAAU,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;AAEjE;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,MAAM,eAAe,CACzB,CAAC,EACD,EAAE,SAAS,MAAM,CAAC,GAAG;KAClB,CAAC,IAAI,MAAM,CAAC,GAAG,IAAI,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK;CAC9C,CAAC,MAAM,CAAC,CAAC,EACV,EAAE,GAAG,IAAI,CAAC,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IACvD;KAAG,CAAC,IAAI,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;CAAE,CAAC;AAE/B;;;GAGG;AACH,MAAM,MAAM,gBAAgB,GAAG,KAAK,CAAC;AAErC;;;;GAIG;AACH,MAAM,MAAM,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,GAAG,IAAI,CAAC;AAE5E;;;;;;;;;GASG;AACH,MAAM,MAAM,YAAY,CAAC,CAAC,SAAS,OAAO,IAAI,CAAC,SAAS,MAAM,GAC1D,MAAM,GACN,CAAC,SAAS,MAAM,GACd,MAAM,GACN,CAAC,SAAS,OAAO,GACf,OAAO,GACP,CAAC,SAAS,MAAM,GACd,MAAM,GACN,CAAC,CAAC;AAEZ;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,MAAM,QAAQ,CAAC,CAAC,IAAI,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AAE7C;;;GAGG;AACH,MAAM,MAAM,WAAW,CAAC,CAAC,EAAE,CAAC,SAAS,MAAM,CAAC,IAAI,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,GACxD,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC"}
@@ -3,8 +3,8 @@
3
3
  *
4
4
  * @module
5
5
  */
6
- import { RetryError, RetryOptions } from "./Promise.js";
7
6
  import { Result } from "./Result.js";
7
+ import { RetryError, RetryOptions } from "./Task.js";
8
8
  /** WebSocket with auto-reconnect and offline support. */
9
9
  export interface WebSocket extends Disposable {
10
10
  /**
@@ -13,9 +13,12 @@ export interface WebSocket extends Disposable {
13
13
  */
14
14
  send: (data: string | ArrayBufferLike | Blob | ArrayBufferView) => Result<void, WebSocketSendError>;
15
15
  readonly getReadyState: () => WebSocketReadyState;
16
+ /** Returns true if the WebSocket is open and ready to send data. */
17
+ readonly isOpen: () => boolean;
16
18
  }
17
19
  /**
18
- * An error that occurs when trying to send data but WebSocket is connecting.
20
+ * An error that occurs when trying to send data but WebSocket is not available
21
+ * or is in the CONNECTING state.
19
22
  *
20
23
  * https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/send
21
24
  */
@@ -1 +1 @@
1
- {"version":3,"file":"WebSocket.d.ts","sourceRoot":"","sources":["../../src/WebSocket.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,EAAS,UAAU,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC/D,OAAO,EAAW,MAAM,EAAE,MAAM,aAAa,CAAC;AAE9C,yDAAyD;AACzD,MAAM,WAAW,SAAU,SAAQ,UAAU;IAC3C;;;OAGG;IACH,IAAI,EAAE,CACJ,IAAI,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI,GAAG,eAAe,KACpD,MAAM,CAAC,IAAI,EAAE,kBAAkB,CAAC,CAAC;IAEtC,QAAQ,CAAC,aAAa,EAAE,MAAM,mBAAmB,CAAC;CACnD;AAED;;;;GAIG;AACH,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,IAAI,EAAE,oBAAoB,CAAC;CACrC;AAED,mCAAmC;AACnC,MAAM,MAAM,mBAAmB,GAAG,YAAY,GAAG,MAAM,GAAG,SAAS,GAAG,QAAQ,CAAC;AAE/E,MAAM,MAAM,eAAe,GAAG,CAC5B,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,gBAAgB,KACvB,SAAS,CAAC;AAEf,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,eAAe,EAAE,eAAe,CAAC;CAC3C;AAED,6CAA6C;AAC7C,MAAM,WAAW,gBAAgB;IAC/B,wDAAwD;IACxD,SAAS,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;IAEnC,wDAAwD;IACxD,UAAU,CAAC,EAAE,MAAM,GAAG,aAAa,CAAC;IAEpC,mDAAmD;IACnD,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IAEpB,qCAAqC;IACrC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,CAAC;IAE1C,8CAA8C;IAC9C,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;IAEtC,8CAA8C;IAC9C,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,KAAK,IAAI,CAAC;IAExD,kCAAkC;IAClC,YAAY,CAAC,EAAE,IAAI,CAAC,YAAY,CAAC,mBAAmB,CAAC,EAAE,QAAQ,CAAC,CAAC;IAEjE;;;;;;OAMG;IACH,oBAAoB,CAAC,EAAE,OAAO,UAAU,CAAC,SAAS,CAAC;CACpD;AAED,MAAM,MAAM,cAAc,GACtB,qBAAqB,GACrB,wBAAwB,GACxB,UAAU,CAAC,mBAAmB,CAAC,CAAC;AAEpC;;;GAGG;AACH,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,IAAI,EAAE,uBAAuB,CAAC;IACvC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;CACvB;AAED;;;;;GAKG;AACH,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,IAAI,EAAE,0BAA0B,CAAC;IAC1C,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;CACvB;AAED,MAAM,MAAM,mBAAmB,GAC3B,qBAAqB,GACrB,6BAA6B,CAAC;AAElC,MAAM,WAAW,6BAA6B;IAC5C,QAAQ,CAAC,IAAI,EAAE,+BAA+B,CAAC;IAC/C,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;CAC5B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,eAAO,MAAM,eAAe,EAAE,eA0H7B,CAAC"}
1
+ {"version":3,"file":"WebSocket.d.ts","sourceRoot":"","sources":["../../src/WebSocket.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,EAAW,MAAM,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAS,UAAU,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAG5D,yDAAyD;AACzD,MAAM,WAAW,SAAU,SAAQ,UAAU;IAC3C;;;OAGG;IACH,IAAI,EAAE,CACJ,IAAI,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI,GAAG,eAAe,KACpD,MAAM,CAAC,IAAI,EAAE,kBAAkB,CAAC,CAAC;IAEtC,QAAQ,CAAC,aAAa,EAAE,MAAM,mBAAmB,CAAC;IAElD,oEAAoE;IACpE,QAAQ,CAAC,MAAM,EAAE,MAAM,OAAO,CAAC;CAChC;AAED;;;;;GAKG;AACH,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,IAAI,EAAE,oBAAoB,CAAC;CACrC;AAED,mCAAmC;AACnC,MAAM,MAAM,mBAAmB,GAAG,YAAY,GAAG,MAAM,GAAG,SAAS,GAAG,QAAQ,CAAC;AAE/E,MAAM,MAAM,eAAe,GAAG,CAC5B,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,gBAAgB,KACvB,SAAS,CAAC;AAEf,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,eAAe,EAAE,eAAe,CAAC;CAC3C;AAED,6CAA6C;AAC7C,MAAM,WAAW,gBAAgB;IAC/B,wDAAwD;IACxD,SAAS,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;IAEnC,wDAAwD;IACxD,UAAU,CAAC,EAAE,MAAM,GAAG,aAAa,CAAC;IAEpC,mDAAmD;IACnD,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IAEpB,qCAAqC;IACrC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,CAAC;IAE1C,8CAA8C;IAC9C,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;IAEtC,8CAA8C;IAC9C,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,KAAK,IAAI,CAAC;IAExD,kCAAkC;IAClC,YAAY,CAAC,EAAE,IAAI,CAAC,YAAY,CAAC,mBAAmB,CAAC,EAAE,QAAQ,CAAC,CAAC;IAEjE;;;;;;OAMG;IACH,oBAAoB,CAAC,EAAE,OAAO,UAAU,CAAC,SAAS,CAAC;CACpD;AAED,MAAM,MAAM,cAAc,GACtB,qBAAqB,GACrB,wBAAwB,GACxB,UAAU,CAAC,mBAAmB,CAAC,CAAC;AAEpC;;;GAGG;AACH,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,IAAI,EAAE,uBAAuB,CAAC;IACvC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;CACvB;AAED;;;;;GAKG;AACH,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,IAAI,EAAE,0BAA0B,CAAC;IAC1C,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;CACvB;AAED,MAAM,MAAM,mBAAmB,GAC3B,qBAAqB,GACrB,6BAA6B,CAAC;AAElC,MAAM,WAAW,6BAA6B;IAC5C,QAAQ,CAAC,IAAI,EAAE,+BAA+B,CAAC;IAC/C,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;CAC5B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,eAAO,MAAM,eAAe,EAAE,eA2H7B,CAAC"}
@@ -4,8 +4,9 @@
4
4
  * @module
5
5
  */
6
6
  import { assertNoErrorInCatch } from "./Assert.js";
7
- import { retry } from "./Promise.js";
8
7
  import { err, ok } from "./Result.js";
8
+ import { retry } from "./Task.js";
9
+ import { maxPositiveInt } from "./Type.js";
9
10
  /**
10
11
  * Create a new {@link WebSocket}.
11
12
  *
@@ -37,13 +38,11 @@ import { err, ok } from "./Result.js";
37
38
  *
38
39
  * TODO:
39
40
  */
40
- export const createWebSocket = (url, options = {}) => {
41
- const { protocols, binaryType, onOpen, onClose, onMessage, onError, retryOptions, WebSocketConstructor = globalThis.WebSocket, } = options;
41
+ export const createWebSocket = (url, { protocols, binaryType, onOpen, onClose, onMessage, onError, retryOptions, WebSocketConstructor = globalThis.WebSocket, } = {}) => {
42
42
  let isDisposed = false;
43
43
  const reconnectController = new AbortController();
44
44
  const defaultRetryOptions = {
45
- signal: reconnectController.signal,
46
- maxRetries: Infinity,
45
+ retries: maxPositiveInt, // Practically infinite retries
47
46
  };
48
47
  let socket = null;
49
48
  const disposeSocket = () => {
@@ -66,7 +65,10 @@ export const createWebSocket = (url, options = {}) => {
66
65
  * - Is rejected when a connection is closed.
67
66
  * - Is resolved when WebSocket is disposed().
68
67
  */
69
- retry(() => new Promise((resolve) => {
68
+ retry({
69
+ ...defaultRetryOptions,
70
+ ...retryOptions,
71
+ }, () => new Promise((resolve) => {
70
72
  disposePromise = () => {
71
73
  resolve(ok());
72
74
  };
@@ -98,19 +100,16 @@ export const createWebSocket = (url, options = {}) => {
98
100
  socket.onmessage = (event) => {
99
101
  onMessage?.(event.data);
100
102
  };
101
- }), {
102
- ...defaultRetryOptions,
103
- ...retryOptions,
104
- })
103
+ }))(reconnectController)
105
104
  .then((result) => {
106
- if (result.ok || result.error.type === "RetryAbortError")
105
+ if (result.ok || result.error.type === "AbortError")
107
106
  return;
108
107
  onError?.(result.error);
109
108
  })
110
109
  .catch((error) => {
111
110
  assertNoErrorInCatch("WebSocket retry", error);
112
111
  });
113
- const webSocket = {
112
+ return {
114
113
  send: (data) => {
115
114
  // https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/send
116
115
  if (!socket || socket.readyState === socket.CONNECTING) {
@@ -120,6 +119,7 @@ export const createWebSocket = (url, options = {}) => {
120
119
  return ok();
121
120
  },
122
121
  getReadyState: () => socket ? nativeToStringState[socket.readyState] : "connecting",
122
+ isOpen: () => (socket ? socket.readyState === socket.OPEN : false),
123
123
  [Symbol.dispose]() {
124
124
  if (isDisposed)
125
125
  return;
@@ -129,7 +129,6 @@ export const createWebSocket = (url, options = {}) => {
129
129
  disposePromise?.();
130
130
  },
131
131
  };
132
- return webSocket;
133
132
  };
134
133
  const nativeToStringState = {
135
134
  [WebSocket.CONNECTING]: "connecting",
@@ -14,6 +14,21 @@ export interface Worker<Input, Output> {
14
14
  export interface WorkerPostMessageDep<Output> {
15
15
  readonly postMessage: (message: Output) => void;
16
16
  }
17
+ /**
18
+ * Error reporting wrapper that catches synchronous errors in handlers and
19
+ * converts them to transferable error messages sent to the main thread.
20
+ */
21
+ export type WithErrorReporting = <A extends Array<any>>(handler: (...args: A) => void) => (...args: A) => void;
22
+ type HasInit<Input> = Extract<Input, {
23
+ type: "init";
24
+ }> extends never ? ["Input must contain a variant with { type: 'init' }"] : unknown;
25
+ type HasWorkerErrorOutput<T> = Extract<T, {
26
+ type: "onError";
27
+ }> extends infer E ? [E] extends [never] ? [
28
+ "Output must contain { type: 'onError'; error: TransferableError | ... }"
29
+ ] : E extends {
30
+ error: infer Err;
31
+ } ? TransferableError extends Err ? unknown : ["Output.onError.error must include TransferableError"] : ["Output.onError must have an error property"] : never;
17
32
  /**
18
33
  * Creates a {@link Worker} that supports initialization with dependencies and
19
34
  * safe error handling.
@@ -25,20 +40,33 @@ export declare const createInitializedWorker: <Input extends {
25
40
  } & HasWorkerErrorOutput<Output>, Deps>({ init, onMessage, }: {
26
41
  readonly init: (initMessage: Extract<Input, {
27
42
  type: "init";
28
- }>, postMessage: (msg: Output) => void, safeHandler: <A extends Array<any>>(handler: (...args: A) => void) => (...args: A) => void) => Promise<Deps | null>;
43
+ }>, postMessage: (msg: Output) => void, withErrorReporting: WithErrorReporting) => Promise<Deps | null>;
29
44
  readonly onMessage: (deps: Deps) => (message: Exclude<Input, {
30
45
  type: "init";
31
46
  }>) => void;
32
47
  }) => Worker<Input, Output>;
33
- type HasInit<Input> = Extract<Input, {
34
- type: "init";
35
- }> extends never ? ["Input must contain a variant with { type: 'init' }"] : unknown;
36
- type HasWorkerErrorOutput<T> = Extract<T, {
37
- type: "onError";
38
- }> extends infer E ? [E] extends [never] ? [
39
- "Output must contain { type: 'onError'; error: TransferableError | ... }"
40
- ] : E extends {
41
- error: infer Err;
42
- } ? TransferableError extends Err ? unknown : ["Output.onError.error must include TransferableError"] : ["Output.onError must have an error property"] : never;
48
+ /** Type helper to extract message types from a union type */
49
+ export type MessageHandlers<Input extends {
50
+ readonly type: string;
51
+ }, Deps> = {
52
+ readonly [K in Input["type"]]: (deps: Deps) => (message: Extract<Input, {
53
+ type: K;
54
+ }>) => void;
55
+ };
56
+ /**
57
+ * Creates a {@link Worker} with type-safe message handlers for each message
58
+ * type. This provides better type safety and organization compared to a single
59
+ * onMessage handler.
60
+ */
61
+ export declare const createInitializedWorkerWithHandlers: <Input extends {
62
+ readonly type: string;
63
+ } & HasInit<Input>, Output extends {
64
+ readonly type: string;
65
+ } & HasWorkerErrorOutput<Output>, Deps>({ init, handlers, }: {
66
+ readonly init: (initMessage: Extract<Input, {
67
+ type: "init";
68
+ }>, postMessage: (msg: Output) => void, withErrorReporting: WithErrorReporting) => Promise<Deps | null>;
69
+ readonly handlers: Omit<MessageHandlers<Input, Deps>, "init">;
70
+ }) => Worker<Input, Output>;
43
71
  export {};
44
72
  //# sourceMappingURL=Worker.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Worker.d.ts","sourceRoot":"","sources":["../../src/Worker.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAA2B,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAExE,yCAAyC;AACzC,MAAM,WAAW,MAAM,CAAC,KAAK,EAAE,MAAM;IACnC,qCAAqC;IACrC,QAAQ,CAAC,WAAW,EAAE,CAAC,OAAO,EAAE,KAAK,KAAK,IAAI,CAAC;IAE/C,oDAAoD;IACpD,QAAQ,CAAC,SAAS,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,KAAK,IAAI,CAAC;CACnE;AAED,MAAM,WAAW,oBAAoB,CAAC,MAAM;IAC1C,QAAQ,CAAC,WAAW,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACjD;AAED;;;GAGG;AACH,eAAO,MAAM,uBAAuB,GAClC,KAAK,SAAS;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,KAAK,CAAC,EACxD,MAAM,SAAS;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,oBAAoB,CAAC,MAAM,CAAC,EACvE,IAAI,EACJ,sBAGC;IACD,QAAQ,CAAC,IAAI,EAAE,CACb,WAAW,EAAE,OAAO,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,EAC7C,WAAW,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,EAClC,WAAW,EAAE,CAAC,CAAC,SAAS,KAAK,CAAC,GAAG,CAAC,EAChC,OAAO,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,KAAK,IAAI,KAC1B,CAAC,GAAG,IAAI,EAAE,CAAC,KAAK,IAAI,KACtB,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,CAClB,IAAI,EAAE,IAAI,KACP,CAAC,OAAO,EAAE,OAAO,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,KAAK,IAAI,CAAC;CAC1D,KAAG,MAAM,CAAC,KAAK,EAAE,MAAM,CAkEvB,CAAC;AAEF,KAAK,OAAO,CAAC,KAAK,IAChB,OAAO,CAAC,KAAK,EAAE;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,SAAS,KAAK,GAC1C,CAAC,oDAAoD,CAAC,GACtD,OAAO,CAAC;AAEd,KAAK,oBAAoB,CAAC,CAAC,IACzB,OAAO,CAAC,CAAC,EAAE;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,CAAC,SAAS,MAAM,CAAC,GAC3C,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,GACjB;IACE,yEAAyE;CAC1E,GACD,CAAC,SAAS;IAAE,KAAK,EAAE,MAAM,GAAG,CAAA;CAAE,GAC5B,iBAAiB,SAAS,GAAG,GAC3B,OAAO,GACP,CAAC,qDAAqD,CAAC,GACzD,CAAC,4CAA4C,CAAC,GAClD,KAAK,CAAC"}
1
+ {"version":3,"file":"Worker.d.ts","sourceRoot":"","sources":["../../src/Worker.ts"],"names":[],"mappings":"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"}
@@ -24,7 +24,11 @@ export const createInitializedWorker = ({ init, onMessage, }) => {
24
24
  error: createTransferableError(error),
25
25
  });
26
26
  };
27
- const safeHandler = (handler) => (...args) => {
27
+ /**
28
+ * Wraps function to catch errors and send them to the main thread instead of
29
+ * crashing the worker.
30
+ */
31
+ const withErrorReporting = (handler) => (...args) => {
28
32
  try {
29
33
  handler(...args);
30
34
  }
@@ -39,20 +43,20 @@ export const createInitializedWorker = ({ init, onMessage, }) => {
39
43
  pendingMessages.push(message);
40
44
  }
41
45
  else {
42
- safeHandler(onMessage(deps))(message);
46
+ withErrorReporting(onMessage(deps))(message);
43
47
  }
44
48
  return;
45
49
  }
46
50
  if (initializing)
47
51
  return;
48
52
  initializing = true;
49
- init(message, postMessage, safeHandler)
53
+ init(message, postMessage, withErrorReporting)
50
54
  .then((_deps) => {
51
55
  if (_deps == null)
52
56
  return;
53
57
  deps = _deps;
54
58
  for (const message of pendingMessages) {
55
- safeHandler(onMessage(deps))(message);
59
+ withErrorReporting(onMessage(deps))(message);
56
60
  }
57
61
  pendingMessages.length = 0;
58
62
  })
@@ -64,3 +68,17 @@ export const createInitializedWorker = ({ init, onMessage, }) => {
64
68
  };
65
69
  return worker;
66
70
  };
71
+ /**
72
+ * Creates a {@link Worker} with type-safe message handlers for each message
73
+ * type. This provides better type safety and organization compared to a single
74
+ * onMessage handler.
75
+ */
76
+ export const createInitializedWorkerWithHandlers = ({ init, handlers, }) => createInitializedWorker({
77
+ init,
78
+ onMessage: (deps) => (message) => {
79
+ const messageType = message.type;
80
+ const handler = handlers[messageType];
81
+ // TypeScript knows handler exists because handlers covers all non-init message types
82
+ handler(deps)(message);
83
+ },
84
+ });
@@ -1,8 +1,9 @@
1
1
  export * from "./Array.js";
2
2
  export * from "./Assert.js";
3
3
  export * from "./BigInt.js";
4
+ export * from "./Brand.js";
4
5
  export * from "./Buffer.js";
5
- export * from "./Callbacks.js";
6
+ export * from "./CallbackRegistry.js";
6
7
  export * from "./Console.js";
7
8
  export * from "./Crypto.js";
8
9
  export * from "./Eq.js";
@@ -10,17 +11,16 @@ export * from "./Error.js";
10
11
  export * from "./Evolu/Public.js";
11
12
  export * from "./Function.js";
12
13
  export * from "./ManyToManyMap.js";
13
- export * from "./NanoId.js";
14
14
  export * from "./Number.js";
15
15
  export * from "./Object.js";
16
16
  export * from "./Order.js";
17
- export * from "./Promise.js";
18
17
  export * from "./Random.js";
19
18
  export * from "./Ref.js";
20
19
  export * from "./Result.js";
21
20
  export * from "./Sqlite.js";
22
21
  export * from "./Store.js";
23
22
  export * from "./String.js";
23
+ export * from "./Task.js";
24
24
  export * from "./Time.js";
25
25
  export * from "./Type.js";
26
26
  export * from "./Types.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,SAAS,CAAC;AACxB,cAAc,YAAY,CAAC;AAC3B,cAAc,mBAAmB,CAAC;AAClC,cAAc,eAAe,CAAC;AAC9B,cAAc,oBAAoB,CAAC;AACnC,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,UAAU,CAAC;AACzB,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,uBAAuB,CAAC;AACtC,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,SAAS,CAAC;AACxB,cAAc,YAAY,CAAC;AAC3B,cAAc,mBAAmB,CAAC;AAClC,cAAc,eAAe,CAAC;AAC9B,cAAc,oBAAoB,CAAC;AACnC,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,UAAU,CAAC;AACzB,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC"}
package/dist/src/index.js CHANGED
@@ -1,8 +1,9 @@
1
1
  export * from "./Array.js";
2
2
  export * from "./Assert.js";
3
3
  export * from "./BigInt.js";
4
+ export * from "./Brand.js";
4
5
  export * from "./Buffer.js";
5
- export * from "./Callbacks.js";
6
+ export * from "./CallbackRegistry.js";
6
7
  export * from "./Console.js";
7
8
  export * from "./Crypto.js";
8
9
  export * from "./Eq.js";
@@ -10,17 +11,16 @@ export * from "./Error.js";
10
11
  export * from "./Evolu/Public.js";
11
12
  export * from "./Function.js";
12
13
  export * from "./ManyToManyMap.js";
13
- export * from "./NanoId.js";
14
14
  export * from "./Number.js";
15
15
  export * from "./Object.js";
16
16
  export * from "./Order.js";
17
- export * from "./Promise.js";
18
17
  export * from "./Random.js";
19
18
  export * from "./Ref.js";
20
19
  export * from "./Result.js";
21
20
  export * from "./Sqlite.js";
22
21
  export * from "./Store.js";
23
22
  export * from "./String.js";
23
+ export * from "./Task.js";
24
24
  export * from "./Time.js";
25
25
  export * from "./Type.js";
26
26
  export * from "./Types.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@evolu/common",
3
- "version": "6.0.1-preview.2",
3
+ "version": "6.0.1-preview.21",
4
4
  "description": "TypeScript library and local-first framework",
5
5
  "keywords": [
6
6
  "evolu",
@@ -42,22 +42,22 @@
42
42
  "README.md"
43
43
  ],
44
44
  "dependencies": {
45
- "@noble/ciphers": "^1.3.0",
46
- "@noble/hashes": "^1.8.0",
47
- "@scure/bip39": "^1.6.0",
48
- "kysely": "^0.28.2",
49
- "msgpackr": "^1.11.4",
50
- "nanoid": "^3.3.11",
51
- "random": "^5.4.0"
45
+ "@noble/ciphers": "^2.0.0",
46
+ "@noble/hashes": "^2.0.0",
47
+ "@scure/bip39": "^2.0.0",
48
+ "kysely": "^0.28.4",
49
+ "msgpackr": "^1.11.5",
50
+ "random": "^5.4.1"
52
51
  },
53
52
  "devDependencies": {
54
53
  "@bokuweb/zstd-wasm": "0.0.27",
55
54
  "@types/better-sqlite3": "^7.6.13",
56
55
  "@types/ws": "^8.18.1",
57
- "better-sqlite3": "^11.10.0",
58
- "shx": "^0.3.4",
59
- "typescript": "^5.8.3",
60
- "vitest": "^3.2.2",
56
+ "better-sqlite3": "^12.1.1",
57
+ "fast-check": "^4.2.0",
58
+ "shx": "^0.4.0",
59
+ "typescript": "^5.9.2",
60
+ "vitest": "^4.0.4",
61
61
  "ws": "^8.18.2",
62
62
  "@evolu/tsconfig": "0.0.2"
63
63
  },
@@ -71,7 +71,8 @@
71
71
  "scripts": {
72
72
  "dev": "tsc --watch",
73
73
  "build": "shx rm -rf dist ./README.md && tsc && shx cp ../../README.md ./",
74
- "test": "vitest --disableConsoleIntercept",
74
+ "test": "vitest run --disableConsoleIntercept",
75
+ "test:watch": "vitest --disableConsoleIntercept",
75
76
  "clean": "shx rm -rf .turbo node_modules dist",
76
77
  "format": "prettier --write \"src/*.{ts,tsx,md}\"",
77
78
  "bench": "vitest bench"
package/src/Assert.ts CHANGED
@@ -32,9 +32,12 @@ import type { Type } from "./Type.js";
32
32
  * assert(true, "true is not true"); // no-op
33
33
  * assert(false, "true is not true"); // throws Error
34
34
  *
35
- * const size = fooSize - buffer.getLength();
36
- * // Ensure required type
37
- * assert(PositiveInt.is(size), "size is not positive int");
35
+ * const length = buffer.getLength();
36
+ * // We know length is logically non-negative, but TypeScript doesn't
37
+ * assert(
38
+ * NonNegativeInt.is(length),
39
+ * "buffer length should be non-negative",
40
+ * );
38
41
  * ```
39
42
  */
40
43
  export const assert: (
@@ -107,10 +110,8 @@ export const assertNonEmptyReadonlyArray: <T>(
107
110
  * ```
108
111
  */
109
112
  export function assertNoErrorInCatch(context: string, error: unknown): never {
110
- throw Object.assign(
111
- new Error(
112
- `Error in ${context}: an unexpected error reached a catch block and requires a fix`,
113
- ),
113
+ throw new Error(
114
+ `Error in ${context}: an unexpected error reached a catch block and requires a fix`,
114
115
  { cause: error },
115
116
  );
116
117
  }
package/src/Brand.ts ADDED
@@ -0,0 +1,75 @@
1
+ /**
2
+ * A utility interface for creating branded types.
3
+ *
4
+ * Branded types enhance type safety by differentiating otherwise identical base
5
+ * types, such as `number` or `string`, to enforce stricter type checks.
6
+ *
7
+ * Supports multiple brands, allowing types to act like flags.
8
+ *
9
+ * ### Example 1: Single Brand
10
+ *
11
+ * ```ts
12
+ * // A branded type definition
13
+ * type UserId = number & Brand<"UserId">;
14
+ *
15
+ * // A function that creates `UserId` values.
16
+ * // Casting with `as UserId` is unsafe, so `createUserId` must be unit-tested.
17
+ * const createUserId = (): UserId => {
18
+ * return 123 as UserId; // Unsafe casting
19
+ * };
20
+ *
21
+ * const userId = createUserId();
22
+ *
23
+ * // A function that accepts only `UserId`.
24
+ * const getUser = (id: UserId) => {
25
+ * // Implementation
26
+ * };
27
+ *
28
+ * getUser(userId); // ✅ Valid
29
+ * getUser(123); // ❌ TypeScript error
30
+ * getUser("123"); // ❌ TypeScript error
31
+ * ```
32
+ *
33
+ * ### Example 2: Multiple Brands
34
+ *
35
+ * ```ts
36
+ * // Define branded types
37
+ * type Min1 = string & Brand<"Min1">;
38
+ * type Max100 = string & Brand<"Max100">;
39
+ * type Min1Max100 = string & Brand<"Min1" | "Max100">;
40
+ *
41
+ * // Functions requiring specific brands
42
+ * const requiresMin1 = (value: Min1): void => {};
43
+ * const requiresMax100 = (value: Max100): void => {};
44
+ *
45
+ * // Values with single brands
46
+ * const min1Value: Min1 = "hello" as Min1;
47
+ * const max100Value: Max100 = "world" as Max100;
48
+ *
49
+ * // Value with multiple brands
50
+ * const min1Max100Value: Min1Max100 = "typescript" as Min1Max100;
51
+ *
52
+ * // Valid cases
53
+ * requiresMin1(min1Value); // ✅ Valid
54
+ * requiresMax100(max100Value); // ✅ Valid
55
+ * requiresMin1(min1Max100Value); // ✅ Valid: Min1Max100 satisfies Min1
56
+ * requiresMax100(min1Max100Value); // ✅ Valid: Min1Max100 satisfies Max100
57
+ * ```
58
+ */
59
+ export interface Brand<B extends string> {
60
+ readonly [__brand]: Readonly<Record<B, true>>;
61
+ }
62
+
63
+ declare const __brand: unique symbol;
64
+
65
+ /**
66
+ * Determines whether a type `T` is a branded type.
67
+ *
68
+ * Works with any base type intersected with a `Brand`.
69
+ *
70
+ * ### Examples
71
+ *
72
+ * - `IsBranded<string>` -> false
73
+ * - `IsBranded<string & Brand<"X">>` -> true
74
+ */
75
+ export type IsBranded<T> = T extends Brand<string> ? true : false;
package/src/Buffer.ts CHANGED
@@ -6,7 +6,7 @@ export {
6
6
  concatBytes,
7
7
  hexToBytes,
8
8
  utf8ToBytes,
9
- } from "@noble/ciphers/utils";
9
+ } from "@noble/ciphers/utils.js";
10
10
 
11
11
  /**
12
12
  * Custom error for {@link Buffer}-related failures like premature end of data.