@evolu/common 6.0.1-preview.19 → 6.0.1-preview.20

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 (140) hide show
  1. package/dist/src/Assert.d.ts.map +1 -1
  2. package/dist/src/Assert.js +1 -1
  3. package/dist/src/Buffer.d.ts +1 -1
  4. package/dist/src/Buffer.d.ts.map +1 -1
  5. package/dist/src/Buffer.js +1 -1
  6. package/dist/src/CallbackRegistry.d.ts +53 -0
  7. package/dist/src/CallbackRegistry.d.ts.map +1 -0
  8. package/dist/src/CallbackRegistry.js +25 -0
  9. package/dist/src/Console.d.ts +31 -6
  10. package/dist/src/Console.d.ts.map +1 -1
  11. package/dist/src/Console.js +72 -9
  12. package/dist/src/Crypto.d.ts +48 -37
  13. package/dist/src/Crypto.d.ts.map +1 -1
  14. package/dist/src/Crypto.js +27 -50
  15. package/dist/src/Evolu/Db.d.ts +138 -66
  16. package/dist/src/Evolu/Db.d.ts.map +1 -1
  17. package/dist/src/Evolu/Db.js +248 -645
  18. package/dist/src/Evolu/Diff.d.ts +3 -3
  19. package/dist/src/Evolu/Diff.d.ts.map +1 -1
  20. package/dist/src/Evolu/Diff.js +7 -5
  21. package/dist/src/Evolu/Evolu.d.ts +79 -116
  22. package/dist/src/Evolu/Evolu.d.ts.map +1 -1
  23. package/dist/src/Evolu/Evolu.js +275 -132
  24. package/dist/src/Evolu/Internal.d.ts +0 -2
  25. package/dist/src/Evolu/Internal.d.ts.map +1 -1
  26. package/dist/src/Evolu/Internal.js +0 -2
  27. package/dist/src/Evolu/LocalAuth.d.ts +144 -0
  28. package/dist/src/Evolu/LocalAuth.d.ts.map +1 -0
  29. package/dist/src/Evolu/LocalAuth.js +171 -0
  30. package/dist/src/Evolu/Owner.d.ts +129 -83
  31. package/dist/src/Evolu/Owner.d.ts.map +1 -1
  32. package/dist/src/Evolu/Owner.js +80 -89
  33. package/dist/src/Evolu/Platform.d.ts +9 -7
  34. package/dist/src/Evolu/Platform.d.ts.map +1 -1
  35. package/dist/src/Evolu/Protocol.d.ts +114 -191
  36. package/dist/src/Evolu/Protocol.d.ts.map +1 -1
  37. package/dist/src/Evolu/Protocol.js +409 -416
  38. package/dist/src/Evolu/Public.d.ts +6 -8
  39. package/dist/src/Evolu/Public.d.ts.map +1 -1
  40. package/dist/src/Evolu/Public.js +2 -3
  41. package/dist/src/Evolu/PublicKysely.js +3 -3
  42. package/dist/src/Evolu/Relay.d.ts +1 -2
  43. package/dist/src/Evolu/Relay.d.ts.map +1 -1
  44. package/dist/src/Evolu/Relay.js +11 -9
  45. package/dist/src/Evolu/Schema.d.ts +88 -27
  46. package/dist/src/Evolu/Schema.d.ts.map +1 -1
  47. package/dist/src/Evolu/Schema.js +141 -24
  48. package/dist/src/Evolu/Storage.d.ts +158 -14
  49. package/dist/src/Evolu/Storage.d.ts.map +1 -1
  50. package/dist/src/Evolu/Storage.js +32 -32
  51. package/dist/src/Evolu/Sync.d.ts +77 -13
  52. package/dist/src/Evolu/Sync.d.ts.map +1 -1
  53. package/dist/src/Evolu/Sync.js +453 -20
  54. package/dist/src/Evolu/Timestamp.d.ts +29 -27
  55. package/dist/src/Evolu/Timestamp.d.ts.map +1 -1
  56. package/dist/src/Evolu/Timestamp.js +20 -18
  57. package/dist/src/ManyToManyMap.d.ts +74 -10
  58. package/dist/src/ManyToManyMap.d.ts.map +1 -1
  59. package/dist/src/ManyToManyMap.js +41 -6
  60. package/dist/src/Random.d.ts +3 -2
  61. package/dist/src/Random.d.ts.map +1 -1
  62. package/dist/src/RefCountedResourceManager.d.ts +119 -0
  63. package/dist/src/RefCountedResourceManager.d.ts.map +1 -0
  64. package/dist/src/RefCountedResourceManager.js +197 -0
  65. package/dist/src/Result.d.ts +144 -22
  66. package/dist/src/Result.d.ts.map +1 -1
  67. package/dist/src/Result.js +5 -2
  68. package/dist/src/Sqlite.d.ts +20 -4
  69. package/dist/src/Sqlite.d.ts.map +1 -1
  70. package/dist/src/Sqlite.js +50 -8
  71. package/dist/src/Task.d.ts +511 -0
  72. package/dist/src/Task.d.ts.map +1 -0
  73. package/dist/src/Task.js +410 -0
  74. package/dist/src/Time.d.ts +59 -0
  75. package/dist/src/Time.d.ts.map +1 -1
  76. package/dist/src/Time.js +87 -4
  77. package/dist/src/Type.d.ts +431 -341
  78. package/dist/src/Type.d.ts.map +1 -1
  79. package/dist/src/Type.js +458 -466
  80. package/dist/src/WebSocket.d.ts +5 -2
  81. package/dist/src/WebSocket.d.ts.map +1 -1
  82. package/dist/src/WebSocket.js +12 -13
  83. package/dist/src/Worker.d.ts +39 -11
  84. package/dist/src/Worker.d.ts.map +1 -1
  85. package/dist/src/Worker.js +22 -4
  86. package/dist/src/index.d.ts +2 -3
  87. package/dist/src/index.d.ts.map +1 -1
  88. package/dist/src/index.js +2 -3
  89. package/package.json +7 -7
  90. package/src/Assert.ts +2 -4
  91. package/src/Buffer.ts +1 -1
  92. package/src/CallbackRegistry.ts +84 -0
  93. package/src/Console.ts +91 -11
  94. package/src/Crypto.ts +78 -91
  95. package/src/Evolu/Db.ts +455 -947
  96. package/src/Evolu/Diff.ts +7 -5
  97. package/src/Evolu/Evolu.ts +545 -307
  98. package/src/Evolu/Internal.ts +0 -2
  99. package/src/Evolu/LocalAuth.ts +422 -0
  100. package/src/Evolu/Owner.ts +191 -131
  101. package/src/Evolu/Platform.ts +9 -9
  102. package/src/Evolu/Protocol.ts +536 -653
  103. package/src/Evolu/Public.ts +7 -9
  104. package/src/Evolu/PublicKysely.ts +3 -3
  105. package/src/Evolu/Relay.ts +17 -12
  106. package/src/Evolu/Schema.ts +271 -66
  107. package/src/Evolu/Storage.ts +263 -55
  108. package/src/Evolu/Sync.ts +758 -37
  109. package/src/Evolu/Timestamp.ts +30 -35
  110. package/src/ManyToManyMap.ts +127 -24
  111. package/src/Random.ts +3 -2
  112. package/src/RefCountedResourceManager.ts +368 -0
  113. package/src/Result.ts +149 -23
  114. package/src/Sqlite.ts +59 -24
  115. package/src/Task.ts +779 -0
  116. package/src/Time.ts +168 -4
  117. package/src/Type.ts +657 -695
  118. package/src/WebSocket.ts +23 -17
  119. package/src/Worker.ts +72 -23
  120. package/src/index.ts +2 -3
  121. package/dist/src/Callbacks.d.ts +0 -20
  122. package/dist/src/Callbacks.d.ts.map +0 -1
  123. package/dist/src/Callbacks.js +0 -18
  124. package/dist/src/Evolu/Config.d.ts +0 -82
  125. package/dist/src/Evolu/Config.d.ts.map +0 -1
  126. package/dist/src/Evolu/Config.js +0 -9
  127. package/dist/src/Evolu/Kysely.d.ts +0 -6
  128. package/dist/src/Evolu/Kysely.d.ts.map +0 -1
  129. package/dist/src/Evolu/Kysely.js +0 -21
  130. package/dist/src/NanoId.d.ts +0 -27
  131. package/dist/src/NanoId.d.ts.map +0 -1
  132. package/dist/src/NanoId.js +0 -6
  133. package/dist/src/Promise.d.ts +0 -180
  134. package/dist/src/Promise.d.ts.map +0 -1
  135. package/dist/src/Promise.js +0 -176
  136. package/src/Callbacks.ts +0 -43
  137. package/src/Evolu/Config.ts +0 -97
  138. package/src/Evolu/Kysely.ts +0 -38
  139. package/src/NanoId.ts +0 -39
  140. package/src/Promise.ts +0 -295
package/src/Time.ts CHANGED
@@ -4,9 +4,12 @@
4
4
  * @module
5
5
  */
6
6
 
7
+ import { DateIso, NonNegativeInt } from "./Type.js";
8
+
7
9
  /** Retrieves the current time in milliseconds, similar to `Date.now()`. */
8
10
  export interface Time {
9
11
  readonly now: () => number;
12
+ readonly nowIso: () => DateIso;
10
13
  }
11
14
 
12
15
  export interface TimeDep {
@@ -14,9 +17,16 @@ export interface TimeDep {
14
17
  }
15
18
 
16
19
  /** Creates a {@link Time} using Date.now(). */
17
- export const createTime = (): Time => ({
18
- now: () => Date.now(),
19
- });
20
+ export const createTime = (): Time => {
21
+ const time: Time = {
22
+ now: () => {
23
+ const iso = time.nowIso();
24
+ return new globalThis.Date(iso).getTime();
25
+ },
26
+ nowIso: () => DateIso.orThrow(new globalThis.Date().toISOString()),
27
+ };
28
+ return time;
29
+ };
20
30
 
21
31
  /**
22
32
  * Creates a {@link Time} that returns a monotonically increasing number based on
@@ -24,7 +34,7 @@ export const createTime = (): Time => ({
24
34
  */
25
35
  export const createTestTime = (): Time => {
26
36
  let now = 0;
27
- return {
37
+ const time: Time = {
28
38
  now: () => {
29
39
  const current = now;
30
40
  queueMicrotask(() => {
@@ -32,5 +42,159 @@ export const createTestTime = (): Time => {
32
42
  });
33
43
  return current;
34
44
  },
45
+ nowIso: () =>
46
+ DateIso.orThrow(new globalThis.Date(time.now()).toISOString()),
35
47
  };
48
+ return time;
49
+ };
50
+
51
+ /** Single digit 0-9. Used internally for {@link DurationString} validation. */
52
+ export type D = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9";
53
+
54
+ /**
55
+ * Minutes and seconds 1-59. Used internally for {@link DurationString}
56
+ * validation. Uses single digits for 1-9, full numbers for 10-59.
57
+ */
58
+ export type MmSs =
59
+ | Exclude<D, "0"> // 1..9 (single digit)
60
+ | `1${D}` // 10..19
61
+ | `2${D}` // 20..29
62
+ | `3${D}` // 30..39
63
+ | `4${D}` // 40..49
64
+ | `5${D}`; // 50..59
65
+
66
+ /** Hours 1-23. Used internally for {@link DurationString} validation. */
67
+ export type Hours =
68
+ | Exclude<D, "0"> // 1-9
69
+ | `1${D}` // 10-19
70
+ | `2${"0" | "1" | "2" | "3"}`; // 20-23
71
+
72
+ /** Days 1-99. Used internally for {@link DurationString} validation. */
73
+ export type Days = Exclude<D, "0"> | `${Exclude<D, "0">}${D}`;
74
+
75
+ /**
76
+ * Template literal type for compile-time validated duration strings.
77
+ *
78
+ * Allowed patterns: basic units (ms, s, m, h, d) and logical combinations
79
+ * (s+ms, m+s, h+m, d+h).
80
+ *
81
+ * Supported formats:
82
+ *
83
+ * - Milliseconds: `0ms`, `1ms`, `500ms`, `999ms`
84
+ * - Seconds: `5s`, `30s` (1-59, single digit for 1-9)
85
+ * - Minutes: `5m`, `30m` (1-59, single digit for 1-9)
86
+ * - Hours: `1h`, `12h`, `23h` (1-23)
87
+ * - Days: `1d`, `30d`, `99d` (1-99)
88
+ * - Combinations: `1s 250ms`, `30m 15s`, `2h 45m`, `7d 12h`
89
+ *
90
+ * Note: Duration strings are for developer experience only - they provide
91
+ * readable, compile-time validated expressions but should never be persisted or
92
+ * parsed from users as they are not localized. Always convert to NonNegativeInt
93
+ * (milliseconds) for storage and APIs.
94
+ */
95
+ export type DurationString =
96
+ | `${D}ms`
97
+ | `${D}${D}ms`
98
+ | `${D}${D}${D}ms`
99
+ | `${MmSs}s`
100
+ | `${MmSs}m`
101
+ | `${Hours}h`
102
+ | `${Days}d`
103
+ | `${MmSs}s ${D}ms`
104
+ | `${MmSs}s ${D}${D}ms`
105
+ | `${MmSs}s ${D}${D}${D}ms`
106
+ | `${MmSs}m ${MmSs}s`
107
+ | `${Hours}h ${MmSs}m`
108
+ | `${Days}d ${Hours}h`;
109
+
110
+ /**
111
+ * Duration can be either a {@link DurationString} or milliseconds as
112
+ * {@link NonNegativeInt}.
113
+ */
114
+ export type Duration = DurationString | NonNegativeInt;
115
+
116
+ /**
117
+ * Converts a duration to milliseconds.
118
+ *
119
+ * Accepts either a {@link DurationString} (e.g., "5m", "1h 30m") or milliseconds
120
+ * as {@link NonNegativeInt}.
121
+ *
122
+ * ### Example
123
+ *
124
+ * ```ts
125
+ * durationToNonNegativeInt("0ms"); // 0 ✅
126
+ * durationToNonNegativeInt("500ms"); // 500 ✅
127
+ * durationToNonNegativeInt("30s"); // 30000 ✅
128
+ * durationToNonNegativeInt("5m"); // 300000 ✅
129
+ * durationToNonNegativeInt("12h"); // 43200000 ✅
130
+ * durationToNonNegativeInt("7d"); // 604800000 ✅
131
+ * durationToNonNegativeInt("2h 45m"); // 9900000 ✅
132
+ * durationToNonNegativeInt(5000); // 5000 ✅ (already milliseconds)
133
+ * ```
134
+ */
135
+ export const durationToNonNegativeInt = (
136
+ duration: Duration,
137
+ ): NonNegativeInt => {
138
+ // If it's already a NonNegativeInt (milliseconds), return as-is
139
+ if (typeof duration === "number") {
140
+ return duration;
141
+ }
142
+
143
+ // Parse duration string without regex to avoid ReDoS vulnerabilities
144
+ const units = {
145
+ ms: 1,
146
+ s: 1000,
147
+ m: 60000,
148
+ h: 3600000,
149
+ d: 86400000, // 24 * 60 * 60 * 1000
150
+ } as const;
151
+
152
+ let total = 0;
153
+ let i = 0;
154
+
155
+ while (i < duration.length) {
156
+ // Skip whitespace
157
+ while (i < duration.length && duration[i] === " ") {
158
+ i++;
159
+ }
160
+
161
+ if (i >= duration.length) break;
162
+
163
+ // Parse number
164
+ let numStr = "";
165
+ while (i < duration.length && duration[i] >= "0" && duration[i] <= "9") {
166
+ numStr += duration[i];
167
+ i++;
168
+ }
169
+
170
+ if (numStr === "") break;
171
+
172
+ // Parse unit (ms or single char s/m/h/d)
173
+ let unit = "";
174
+ if (i < duration.length) {
175
+ if (
176
+ duration[i] === "m" &&
177
+ i + 1 < duration.length &&
178
+ duration[i + 1] === "s"
179
+ ) {
180
+ unit = "ms";
181
+ i += 2;
182
+ } else if (
183
+ duration[i] === "s" ||
184
+ duration[i] === "m" ||
185
+ duration[i] === "h" ||
186
+ duration[i] === "d"
187
+ ) {
188
+ unit = duration[i];
189
+ i++;
190
+ }
191
+ }
192
+
193
+ if (unit === "") break;
194
+
195
+ const value = parseInt(numStr, 10);
196
+ total += value * units[unit as keyof typeof units];
197
+ }
198
+
199
+ return total as NonNegativeInt;
36
200
  };