@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.
- package/README.md +30 -34
- package/dist/src/Array.d.ts +17 -0
- package/dist/src/Array.d.ts.map +1 -0
- package/dist/src/Array.js +12 -0
- package/dist/src/Assert.d.ts +68 -0
- package/dist/src/Assert.d.ts.map +1 -0
- package/dist/src/Assert.js +77 -0
- package/dist/src/BigInt.d.ts +20 -0
- package/dist/src/BigInt.d.ts.map +1 -0
- package/dist/src/BigInt.js +18 -0
- package/dist/src/Buffer.d.ts +92 -0
- package/dist/src/Buffer.d.ts.map +1 -0
- package/dist/src/Buffer.js +62 -0
- package/dist/src/Callbacks.d.ts +20 -0
- package/dist/src/Callbacks.d.ts.map +1 -0
- package/dist/src/Callbacks.js +18 -0
- package/dist/src/Console.d.ts +78 -0
- package/dist/src/Console.d.ts.map +1 -0
- package/dist/src/Console.js +103 -0
- package/dist/src/Crypto.d.ts +72 -39
- package/dist/src/Crypto.d.ts.map +1 -1
- package/dist/src/Crypto.js +89 -54
- package/dist/src/Eq.d.ts +97 -0
- package/dist/src/Eq.d.ts.map +1 -0
- package/dist/src/Eq.js +167 -0
- package/dist/src/Error.d.ts +14 -10
- package/dist/src/Error.d.ts.map +1 -1
- package/dist/src/Error.js +43 -11
- package/dist/src/Evolu/Config.d.ts +69 -0
- package/dist/src/Evolu/Config.d.ts.map +1 -0
- package/dist/src/Evolu/Config.js +9 -0
- package/dist/src/Evolu/Db.d.ts +126 -0
- package/dist/src/Evolu/Db.d.ts.map +1 -0
- package/dist/src/Evolu/Db.js +774 -0
- package/dist/src/Evolu/Diff.d.ts +43 -0
- package/dist/src/Evolu/Diff.d.ts.map +1 -0
- package/dist/src/Evolu/Diff.js +95 -0
- package/dist/src/Evolu/Evolu.d.ts +334 -0
- package/dist/src/Evolu/Evolu.d.ts.map +1 -0
- package/dist/src/Evolu/Evolu.js +434 -0
- package/dist/src/Evolu/Internal.d.ts +26 -0
- package/dist/src/Evolu/Internal.d.ts.map +1 -0
- package/dist/src/Evolu/Internal.js +25 -0
- package/dist/src/Evolu/Kysely.d.ts +6 -0
- package/dist/src/Evolu/Kysely.d.ts.map +1 -0
- package/dist/src/Evolu/Kysely.js +21 -0
- package/dist/src/Evolu/Owner.d.ts +155 -0
- package/dist/src/Evolu/Owner.d.ts.map +1 -0
- package/dist/src/Evolu/Owner.js +126 -0
- package/dist/src/Evolu/Platform.d.ts +23 -0
- package/dist/src/Evolu/Platform.d.ts.map +1 -0
- package/dist/src/Evolu/Platform.js +1 -0
- package/dist/src/Evolu/Protocol.d.ts +401 -0
- package/dist/src/Evolu/Protocol.d.ts.map +1 -0
- package/dist/src/Evolu/Protocol.js +1151 -0
- package/dist/src/Evolu/Public.d.ts +18 -0
- package/dist/src/Evolu/Public.d.ts.map +1 -0
- package/dist/src/Evolu/Public.js +11 -0
- package/dist/src/Evolu/PublicKysely.d.ts +148 -0
- package/dist/src/Evolu/PublicKysely.d.ts.map +1 -0
- package/dist/src/Evolu/PublicKysely.js +185 -0
- package/dist/src/Evolu/Query.d.ts +63 -0
- package/dist/src/Evolu/Query.d.ts.map +1 -0
- package/dist/src/Evolu/Query.js +61 -0
- package/dist/src/Evolu/Relay.d.ts +13 -0
- package/dist/src/Evolu/Relay.d.ts.map +1 -0
- package/dist/src/Evolu/Relay.js +109 -0
- package/dist/src/Evolu/Schema.d.ts +201 -0
- package/dist/src/Evolu/Schema.d.ts.map +1 -0
- package/dist/src/Evolu/Schema.js +150 -0
- package/dist/src/Evolu/Storage.d.ts +49 -0
- package/dist/src/Evolu/Storage.d.ts.map +1 -0
- package/dist/src/Evolu/Storage.js +1111 -0
- package/dist/src/Evolu/Sync.d.ts +59 -0
- package/dist/src/Evolu/Sync.d.ts.map +1 -0
- package/dist/src/Evolu/Sync.js +29 -0
- package/dist/src/Evolu/Timestamp.d.ts +106 -0
- package/dist/src/Evolu/Timestamp.d.ts.map +1 -0
- package/dist/src/Evolu/Timestamp.js +179 -0
- package/dist/src/Function.d.ts +54 -0
- package/dist/src/Function.d.ts.map +1 -0
- package/dist/src/Function.js +38 -0
- package/dist/src/ManyToManyMap.d.ts +26 -0
- package/dist/src/ManyToManyMap.d.ts.map +1 -0
- package/dist/src/ManyToManyMap.js +92 -0
- package/dist/src/NanoId.d.ts +27 -0
- package/dist/src/NanoId.d.ts.map +1 -0
- package/dist/src/NanoId.js +6 -0
- package/dist/src/Number.d.ts +42 -0
- package/dist/src/Number.d.ts.map +1 -0
- package/dist/src/Number.js +55 -0
- package/dist/src/Object.d.ts +35 -0
- package/dist/src/Object.d.ts.map +1 -0
- package/dist/src/Object.js +36 -0
- package/dist/src/Order.d.ts +90 -0
- package/dist/src/Order.d.ts.map +1 -0
- package/dist/src/Order.js +85 -0
- package/dist/src/Promise.d.ts +180 -0
- package/dist/src/Promise.d.ts.map +1 -0
- package/dist/src/Promise.js +176 -0
- package/dist/src/Random.d.ts +52 -0
- package/dist/src/Random.d.ts.map +1 -0
- package/dist/src/Random.js +29 -0
- package/dist/src/Ref.d.ts +40 -0
- package/dist/src/Ref.d.ts.map +1 -0
- package/dist/src/Ref.js +13 -0
- package/dist/src/Result.d.ts +421 -0
- package/dist/src/Result.d.ts.map +1 -0
- package/dist/src/Result.js +357 -0
- package/dist/src/Skiplist.d.ts +23 -0
- package/dist/src/Skiplist.d.ts.map +1 -0
- package/dist/src/Skiplist.js +58 -0
- package/dist/src/Sqlite.d.ts +116 -52
- package/dist/src/Sqlite.d.ts.map +1 -1
- package/dist/src/Sqlite.js +183 -67
- package/dist/src/Store.d.ts +45 -8
- package/dist/src/Store.d.ts.map +1 -1
- package/dist/src/Store.js +33 -17
- package/dist/src/String.d.ts +2 -0
- package/dist/src/String.d.ts.map +1 -0
- package/dist/src/String.js +14 -0
- package/dist/src/Time.d.ts +20 -0
- package/dist/src/Time.d.ts.map +1 -0
- package/dist/src/Time.js +25 -0
- package/dist/src/Type.d.ts +1937 -0
- package/dist/src/Type.d.ts.map +1 -0
- package/dist/src/Type.js +2002 -0
- package/dist/src/Types.d.ts +188 -0
- package/dist/src/Types.d.ts.map +1 -0
- package/dist/src/Types.js +6 -0
- package/dist/src/WebSocket.d.ts +112 -0
- package/dist/src/WebSocket.d.ts.map +1 -0
- package/dist/src/WebSocket.js +139 -0
- package/dist/src/Worker.d.ts +44 -0
- package/dist/src/Worker.d.ts.map +1 -0
- package/dist/src/Worker.js +66 -0
- package/dist/src/index.d.ts +24 -11
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +24 -11
- package/package.json +29 -38
- package/src/Array.ts +39 -0
- package/src/Assert.ts +116 -0
- package/src/BigInt.ts +29 -0
- package/src/Buffer.ts +175 -0
- package/src/Callbacks.ts +43 -0
- package/src/Console.ts +159 -0
- package/src/Crypto.ts +169 -115
- package/src/Eq.ts +204 -0
- package/src/Error.ts +57 -20
- package/src/Evolu/Config.ts +83 -0
- package/src/Evolu/Db.ts +1275 -0
- package/src/Evolu/Diff.ts +142 -0
- package/src/Evolu/Evolu.ts +947 -0
- package/src/Evolu/Internal.ts +26 -0
- package/src/Evolu/Kysely.ts +38 -0
- package/src/Evolu/Owner.ts +296 -0
- package/src/Evolu/Platform.ts +27 -0
- package/src/Evolu/Protocol.ts +1857 -0
- package/src/Evolu/Public.ts +43 -0
- package/src/Evolu/PublicKysely.ts +240 -0
- package/src/Evolu/Query.ts +167 -0
- package/src/Evolu/Relay.ts +142 -0
- package/src/Evolu/Schema.ts +417 -0
- package/src/Evolu/Storage.ts +1281 -0
- package/src/Evolu/Sync.ts +105 -0
- package/src/Evolu/Timestamp.ts +311 -0
- package/src/Function.ts +58 -0
- package/src/ManyToManyMap.ts +140 -0
- package/src/NanoId.ts +39 -0
- package/src/Number.ts +90 -0
- package/src/Object.ts +64 -0
- package/src/Order.ts +113 -0
- package/src/Promise.ts +295 -0
- package/src/Random.ts +68 -0
- package/src/Ref.ts +63 -0
- package/src/Result.ts +453 -0
- package/src/Skiplist.ts +102 -0
- package/src/Sqlite.ts +366 -153
- package/src/Store.ts +79 -36
- package/src/String.ts +10 -0
- package/src/Time.ts +36 -0
- package/src/Type.ts +3978 -0
- package/src/Types.ts +209 -0
- package/src/WebSocket.ts +273 -0
- package/src/Worker.ts +129 -0
- package/src/index.ts +24 -11
- package/dist/src/Config.d.ts +0 -56
- package/dist/src/Config.d.ts.map +0 -1
- package/dist/src/Config.js +0 -39
- package/dist/src/Crdt.d.ts +0 -89
- package/dist/src/Crdt.d.ts.map +0 -1
- package/dist/src/Crdt.js +0 -181
- package/dist/src/Db.d.ts +0 -107
- package/dist/src/Db.d.ts.map +0 -1
- package/dist/src/Db.js +0 -443
- package/dist/src/Diff.d.ts +0 -27
- package/dist/src/Diff.d.ts.map +0 -1
- package/dist/src/Diff.js +0 -84
- package/dist/src/Evolu.d.ts +0 -426
- package/dist/src/Evolu.d.ts.map +0 -1
- package/dist/src/Evolu.js +0 -333
- package/dist/src/Model.d.ts +0 -141
- package/dist/src/Model.d.ts.map +0 -1
- package/dist/src/Model.js +0 -125
- package/dist/src/Murmurhash.d.ts +0 -2
- package/dist/src/Murmurhash.d.ts.map +0 -1
- package/dist/src/Murmurhash.js +0 -60
- package/dist/src/Owner.d.ts +0 -33
- package/dist/src/Owner.d.ts.map +0 -1
- package/dist/src/Owner.js +0 -26
- package/dist/src/Platform.d.ts +0 -37
- package/dist/src/Platform.d.ts.map +0 -1
- package/dist/src/Platform.js +0 -11
- package/dist/src/Protobuf.d.ts +0 -81
- package/dist/src/Protobuf.d.ts.map +0 -1
- package/dist/src/Protobuf.js +0 -92
- package/dist/src/Public.d.ts +0 -13
- package/dist/src/Public.d.ts.map +0 -1
- package/dist/src/Public.js +0 -6
- package/dist/src/Socket.d.ts +0 -8
- package/dist/src/Socket.d.ts.map +0 -1
- package/dist/src/Socket.js +0 -51
- package/dist/src/Sql.d.ts +0 -12
- package/dist/src/Sql.d.ts.map +0 -1
- package/dist/src/Sql.js +0 -30
- package/dist/src/Sync.d.ts +0 -70
- package/dist/src/Sync.d.ts.map +0 -1
- package/dist/src/Sync.js +0 -127
- package/src/Config.ts +0 -119
- package/src/Crdt.ts +0 -361
- package/src/Db.ts +0 -955
- package/src/Diff.ts +0 -114
- package/src/Evolu.ts +0 -1016
- package/src/Model.ts +0 -233
- package/src/Murmurhash.ts +0 -70
- package/src/Owner.ts +0 -69
- package/src/Platform.ts +0 -47
- package/src/Protobuf.ts +0 -155
- package/src/Public.ts +0 -12
- package/src/Socket.ts +0 -83
- package/src/Sql.ts +0 -41
- package/src/Sync.ts +0 -315
package/src/Types.ts
ADDED
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TypeScript utility types
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import * as Kysely from "kysely";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Checks a condition on a value and returns a boolean.
|
|
11
|
+
*
|
|
12
|
+
* A predicate starts with an 'is' prefix, e.g., `isEven`.
|
|
13
|
+
*
|
|
14
|
+
* ### Example
|
|
15
|
+
*
|
|
16
|
+
* ```ts
|
|
17
|
+
* const isEven: Predicate<number> = (n) => n % 2 === 0;
|
|
18
|
+
*
|
|
19
|
+
* const numbers = [1, 2, 3, 4];
|
|
20
|
+
* const evenNumbers = numbers.filter(isEven); // [2, 4]
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export type Predicate<T> = (value: T) => boolean;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* A type guard function that refines type `A` to a narrower type `B`.
|
|
27
|
+
*
|
|
28
|
+
* ### Example
|
|
29
|
+
*
|
|
30
|
+
* ```ts
|
|
31
|
+
* type Animal = { name: string };
|
|
32
|
+
* type Dog = Animal & { breed: string };
|
|
33
|
+
*
|
|
34
|
+
* const isDog: Refinement<Animal, Dog> = (animal): animal is Dog =>
|
|
35
|
+
* "breed" in animal;
|
|
36
|
+
*
|
|
37
|
+
* const animal: Animal = { name: "Dog", breed: "Beagle" };
|
|
38
|
+
* if (isDog(animal)) {
|
|
39
|
+
* console.log(animal.breed); // Safe access to `breed`
|
|
40
|
+
* }
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
export type Refinement<in A, out B extends A> = (a: A) => a is B;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Makes properties optional if they accept `null` as a value.
|
|
47
|
+
*
|
|
48
|
+
* For each property in `T`, if `null` is a valid value for that property, the
|
|
49
|
+
* property will be made optional in the resulting type.
|
|
50
|
+
*
|
|
51
|
+
* ### Example
|
|
52
|
+
*
|
|
53
|
+
* ```ts
|
|
54
|
+
* type Example = {
|
|
55
|
+
* required: string;
|
|
56
|
+
* optionalWithNull: string | null;
|
|
57
|
+
* };
|
|
58
|
+
*
|
|
59
|
+
* type Result = NullablePartial<Example>;
|
|
60
|
+
* // Result is:
|
|
61
|
+
* // {
|
|
62
|
+
* // required: string;
|
|
63
|
+
* // optionalWithNull?: string | null;
|
|
64
|
+
* // }
|
|
65
|
+
* ```
|
|
66
|
+
*/
|
|
67
|
+
export type NullablePartial<
|
|
68
|
+
T,
|
|
69
|
+
NK extends keyof T = {
|
|
70
|
+
[K in keyof T]: null extends T[K] ? K : never;
|
|
71
|
+
}[keyof T],
|
|
72
|
+
NP = Pick<T, Exclude<keyof T, NK>> & Partial<Pick<T, NK>>,
|
|
73
|
+
> = { [K in keyof NP]: NP[K] };
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* A type alias for `never` that is used intentionally when casting is not
|
|
77
|
+
* needed and unit tests exist to ensure correctness.
|
|
78
|
+
*/
|
|
79
|
+
export type IntentionalNever = never;
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* A utility interface for creating branded types.
|
|
83
|
+
*
|
|
84
|
+
* Branded types enhance type safety by differentiating otherwise identical base
|
|
85
|
+
* types, such as `number` or `string`, to enforce stricter type checks.
|
|
86
|
+
*
|
|
87
|
+
* Supports multiple brands, allowing types to act like flags.
|
|
88
|
+
*
|
|
89
|
+
* ### Example 1: Single Brand
|
|
90
|
+
*
|
|
91
|
+
* ```ts
|
|
92
|
+
* // A branded type definition
|
|
93
|
+
* type UserId = number & Brand<"UserId">;
|
|
94
|
+
*
|
|
95
|
+
* // A function that creates `UserId` values.
|
|
96
|
+
* // Casting with `as UserId` is unsafe, so `createUserId` must be unit-tested.
|
|
97
|
+
* const createUserId = (): UserId => {
|
|
98
|
+
* return 123 as UserId; // Unsafe casting
|
|
99
|
+
* };
|
|
100
|
+
*
|
|
101
|
+
* const userId = createUserId();
|
|
102
|
+
*
|
|
103
|
+
* // A function that accepts only `UserId`.
|
|
104
|
+
* const getUser = (id: UserId) => {
|
|
105
|
+
* // Implementation
|
|
106
|
+
* };
|
|
107
|
+
*
|
|
108
|
+
* getUser(userId); // ✅ Valid
|
|
109
|
+
* getUser(123); // ❌ TypeScript error
|
|
110
|
+
* getUser("123"); // ❌ TypeScript error
|
|
111
|
+
* ```
|
|
112
|
+
*
|
|
113
|
+
* ### Example 2: Multiple Brands
|
|
114
|
+
*
|
|
115
|
+
* ```ts
|
|
116
|
+
* // Define branded types
|
|
117
|
+
* type Min1 = string & Brand<"Min1">;
|
|
118
|
+
* type Max100 = string & Brand<"Max100">;
|
|
119
|
+
* type Min1Max100 = string & Brand<"Min1" | "Max100">;
|
|
120
|
+
*
|
|
121
|
+
* // Functions requiring specific brands
|
|
122
|
+
* const requiresMin1 = (value: Min1): void => {};
|
|
123
|
+
* const requiresMax100 = (value: Max100): void => {};
|
|
124
|
+
*
|
|
125
|
+
* // Values with single brands
|
|
126
|
+
* const min1Value: Min1 = "hello" as Min1;
|
|
127
|
+
* const max100Value: Max100 = "world" as Max100;
|
|
128
|
+
*
|
|
129
|
+
* // Value with multiple brands
|
|
130
|
+
* const min1Max100Value: Min1Max100 = "typescript" as Min1Max100;
|
|
131
|
+
*
|
|
132
|
+
* // Valid cases
|
|
133
|
+
* requiresMin1(min1Value); // ✅ Valid
|
|
134
|
+
* requiresMax100(max100Value); // ✅ Valid
|
|
135
|
+
* requiresMin1(min1Max100Value); // ✅ Valid: Min1Max100 satisfies Min1
|
|
136
|
+
* requiresMax100(min1Max100Value); // ✅ Valid: Min1Max100 satisfies Max100
|
|
137
|
+
* ```
|
|
138
|
+
*/
|
|
139
|
+
export interface Brand<B extends string> {
|
|
140
|
+
readonly [__brand]: Readonly<Record<B, true>>;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
declare const __brand: unique symbol;
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Determines whether a type `T` is a branded type.
|
|
147
|
+
*
|
|
148
|
+
* Works with any base type intersected with a `Brand`.
|
|
149
|
+
*
|
|
150
|
+
* ### Examples
|
|
151
|
+
*
|
|
152
|
+
* - `IsBranded<string>` -> false
|
|
153
|
+
* - `IsBranded<string & Brand<"X">>` -> true
|
|
154
|
+
*/
|
|
155
|
+
export type IsBranded<T> = T extends Brand<string> ? true : false;
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* String | number | bigint | boolean | undefined | null
|
|
159
|
+
*
|
|
160
|
+
* https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types
|
|
161
|
+
*/
|
|
162
|
+
export type Literal = string | number | bigint | boolean | undefined | null;
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Infers a broader type from a specific literal value type.
|
|
166
|
+
*
|
|
167
|
+
* Examples:
|
|
168
|
+
*
|
|
169
|
+
* - "foo" -> string
|
|
170
|
+
* - 42 -> number
|
|
171
|
+
* - 42n -> bigint
|
|
172
|
+
* - True -> boolean
|
|
173
|
+
*/
|
|
174
|
+
export type WidenLiteral<T extends Literal> = T extends string
|
|
175
|
+
? string
|
|
176
|
+
: T extends number
|
|
177
|
+
? number
|
|
178
|
+
: T extends boolean
|
|
179
|
+
? boolean
|
|
180
|
+
: T extends bigint
|
|
181
|
+
? bigint
|
|
182
|
+
: T;
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Simplify an intersection type into a single mapped type.
|
|
186
|
+
*
|
|
187
|
+
* This utility forces TypeScript to "flatten" an intersection type into a
|
|
188
|
+
* single object type so that tooltips and error messages are easier to read.
|
|
189
|
+
*
|
|
190
|
+
* ### Example
|
|
191
|
+
*
|
|
192
|
+
* ```ts
|
|
193
|
+
* type A = { a: string } & { b: number };
|
|
194
|
+
* // Without Simplify, TypeScript may display A as:
|
|
195
|
+
* // { a: string } & { b: number }
|
|
196
|
+
*
|
|
197
|
+
* type B = Simplify<A>;
|
|
198
|
+
* // B is equivalent to:
|
|
199
|
+
* // { a: string; b: number }
|
|
200
|
+
* ```
|
|
201
|
+
*/
|
|
202
|
+
export type Simplify<T> = Kysely.Simplify<T>;
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Makes a specific property of an object optional while keeping others
|
|
206
|
+
* unchanged.
|
|
207
|
+
*/
|
|
208
|
+
export type PartialProp<T, K extends keyof T> = Omit<T, K> &
|
|
209
|
+
Partial<Pick<T, K>>;
|
package/src/WebSocket.ts
ADDED
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Websocket with auto-reconnect and offline support
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { assertNoErrorInCatch } from "./Assert.js";
|
|
8
|
+
import { constVoid } from "./Function.js";
|
|
9
|
+
import { retry, RetryError, RetryOptions } from "./Promise.js";
|
|
10
|
+
import { err, ok, Result } from "./Result.js";
|
|
11
|
+
|
|
12
|
+
/** WebSocket with auto-reconnect and offline support. */
|
|
13
|
+
export interface WebSocket extends Disposable {
|
|
14
|
+
/**
|
|
15
|
+
* Send data through the WebSocket connection. Returns {@link Result} with an
|
|
16
|
+
* error if the data couldn't be sent.
|
|
17
|
+
*/
|
|
18
|
+
send: (
|
|
19
|
+
data: string | ArrayBufferLike | Blob | ArrayBufferView,
|
|
20
|
+
) => Result<void, WebSocketSendError>;
|
|
21
|
+
|
|
22
|
+
readonly getReadyState: () => WebSocketReadyState;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* An error that occurs when trying to send data but WebSocket is connecting.
|
|
27
|
+
*
|
|
28
|
+
* https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/send
|
|
29
|
+
*/
|
|
30
|
+
export interface WebSocketSendError {
|
|
31
|
+
readonly type: "WebSocketSendError";
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** WebSocket connection states. */
|
|
35
|
+
export type WebSocketReadyState = "connecting" | "open" | "closing" | "closed";
|
|
36
|
+
|
|
37
|
+
export type CreateWebSocket = (
|
|
38
|
+
url: string,
|
|
39
|
+
options?: WebSocketOptions,
|
|
40
|
+
) => WebSocket;
|
|
41
|
+
|
|
42
|
+
export interface CreateWebSocketDep {
|
|
43
|
+
readonly createWebSocket: CreateWebSocket;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/** Options for creating {@link WebSocket} */
|
|
47
|
+
export interface WebSocketOptions {
|
|
48
|
+
/** Protocol(s) to use with the WebSocket connection. */
|
|
49
|
+
protocols?: string | Array<string>;
|
|
50
|
+
|
|
51
|
+
/** Sets the binary type for the data being received. */
|
|
52
|
+
binaryType?: "blob" | "arraybuffer";
|
|
53
|
+
|
|
54
|
+
/** Callback when the connection is established. */
|
|
55
|
+
onOpen?: () => void;
|
|
56
|
+
|
|
57
|
+
/** Callback when an error occurs. */
|
|
58
|
+
onError?: (error: WebSocketError) => void;
|
|
59
|
+
|
|
60
|
+
/** Callback when the connection is closed. */
|
|
61
|
+
onClose?: (event: CloseEvent) => void;
|
|
62
|
+
|
|
63
|
+
/** Callback when message data is received. */
|
|
64
|
+
onMessage?: (data: string | ArrayBuffer | Blob) => void;
|
|
65
|
+
|
|
66
|
+
/** Options for retry behavior. */
|
|
67
|
+
retryOptions?: Omit<RetryOptions<WebSocketRetryError>, "signal">;
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* For custom WebSocket implementations.
|
|
71
|
+
*
|
|
72
|
+
* This suppors blob:
|
|
73
|
+
*
|
|
74
|
+
* https://github.com/callstackincubator/react-native-fast-io
|
|
75
|
+
*/
|
|
76
|
+
WebSocketConstructor?: typeof globalThis.WebSocket;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export type WebSocketError =
|
|
80
|
+
| WebSocketConnectError
|
|
81
|
+
| WebSocketConnectionError
|
|
82
|
+
| RetryError<WebSocketRetryError>;
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* An error that occurs when a connection cannot be established due to a network
|
|
86
|
+
* error.
|
|
87
|
+
*/
|
|
88
|
+
export interface WebSocketConnectError {
|
|
89
|
+
readonly type: "WebSocketConnectError";
|
|
90
|
+
readonly event: Event;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* An error that occurs when a connection is closed due to an issue (e.g.,
|
|
95
|
+
* failure to send some data).
|
|
96
|
+
*
|
|
97
|
+
* https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/error_event
|
|
98
|
+
*/
|
|
99
|
+
export interface WebSocketConnectionError {
|
|
100
|
+
readonly type: "WebSocketConnectionError";
|
|
101
|
+
readonly event: Event;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export type WebSocketRetryError =
|
|
105
|
+
| WebSocketConnectError
|
|
106
|
+
| WebSocketConnectionCloseError;
|
|
107
|
+
|
|
108
|
+
export interface WebSocketConnectionCloseError {
|
|
109
|
+
readonly type: "WebSocketConnectionCloseError";
|
|
110
|
+
readonly event: CloseEvent;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Create a new {@link WebSocket}.
|
|
115
|
+
*
|
|
116
|
+
* The default behavior is that WebSocket tries to reconnect repeatedly in case
|
|
117
|
+
* the application is offline, because online events (both web and native) are
|
|
118
|
+
* not reliable. Once it connects and the connection is closed, it tries to
|
|
119
|
+
* reconnect again. Retrying the connection can be controlled using the
|
|
120
|
+
* retryOptions retryable predicate.
|
|
121
|
+
*
|
|
122
|
+
* ### How Binary Messages Work in WebSockets
|
|
123
|
+
*
|
|
124
|
+
* The Server Chooses the Message Type:
|
|
125
|
+
*
|
|
126
|
+
* - Text (0x1) → Sent as UTF-8 encoded text (always received as a string in the
|
|
127
|
+
* browser).
|
|
128
|
+
* - Binary (0x2) → Sent as raw binary data (received as a Blob or ArrayBuffer,
|
|
129
|
+
* depending on binaryType).
|
|
130
|
+
*
|
|
131
|
+
* The Client's binaryType Controls How Binary Data is Processed:
|
|
132
|
+
*
|
|
133
|
+
* - If the server sends a text frame (0x1), the browser always delivers
|
|
134
|
+
* event.data as a string, regardless of binaryType.
|
|
135
|
+
* - If the server sends a binary frame (0x2), the browser delivers event.data as:
|
|
136
|
+
*
|
|
137
|
+
* - A Blob (default: "blob")
|
|
138
|
+
* - An ArrayBuffer ("arraybuffer")
|
|
139
|
+
*
|
|
140
|
+
* ### Example
|
|
141
|
+
*
|
|
142
|
+
* TODO:
|
|
143
|
+
*/
|
|
144
|
+
export const createWebSocket: CreateWebSocket = (url, options = {}) => {
|
|
145
|
+
const {
|
|
146
|
+
protocols,
|
|
147
|
+
binaryType,
|
|
148
|
+
onOpen,
|
|
149
|
+
onClose,
|
|
150
|
+
onMessage,
|
|
151
|
+
onError,
|
|
152
|
+
retryOptions,
|
|
153
|
+
WebSocketConstructor = globalThis.WebSocket,
|
|
154
|
+
} = options;
|
|
155
|
+
let isDisposed = false;
|
|
156
|
+
|
|
157
|
+
const reconnectController = new AbortController();
|
|
158
|
+
|
|
159
|
+
const defaultRetryOptions: RetryOptions<WebSocketRetryError> = {
|
|
160
|
+
signal: reconnectController.signal,
|
|
161
|
+
maxRetries: Infinity,
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
let socket: globalThis.WebSocket | null = null;
|
|
165
|
+
|
|
166
|
+
const disposeSocket = () => {
|
|
167
|
+
if (!socket) return;
|
|
168
|
+
|
|
169
|
+
// Remove all listeners before closing
|
|
170
|
+
socket.onopen = null;
|
|
171
|
+
socket.onclose = null;
|
|
172
|
+
socket.onmessage = null;
|
|
173
|
+
socket.onerror = null;
|
|
174
|
+
|
|
175
|
+
socket.close();
|
|
176
|
+
socket = null;
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
// To prevent a memory leak from pending connection promise.
|
|
180
|
+
let disposePromise: null | typeof constVoid = null;
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* This promise represents continuous connection which:
|
|
184
|
+
*
|
|
185
|
+
* - Is rejected when a connection cannot be established.
|
|
186
|
+
* - Is rejected when a connection is closed.
|
|
187
|
+
* - Is resolved when WebSocket is disposed().
|
|
188
|
+
*/
|
|
189
|
+
retry(
|
|
190
|
+
(): Promise<Result<void, WebSocketRetryError>> =>
|
|
191
|
+
new Promise((resolve) => {
|
|
192
|
+
disposePromise = () => {
|
|
193
|
+
resolve(ok());
|
|
194
|
+
};
|
|
195
|
+
|
|
196
|
+
if (isDisposed) disposePromise();
|
|
197
|
+
|
|
198
|
+
disposeSocket();
|
|
199
|
+
|
|
200
|
+
socket = new WebSocketConstructor(url, protocols);
|
|
201
|
+
if (binaryType) socket.binaryType = binaryType;
|
|
202
|
+
|
|
203
|
+
let isOpen = false;
|
|
204
|
+
|
|
205
|
+
socket.onopen = () => {
|
|
206
|
+
isOpen = true;
|
|
207
|
+
onOpen?.();
|
|
208
|
+
};
|
|
209
|
+
|
|
210
|
+
socket.onerror = (event) => {
|
|
211
|
+
const error: WebSocketConnectionError | WebSocketConnectError = isOpen
|
|
212
|
+
? { type: "WebSocketConnectionError", event }
|
|
213
|
+
: { type: "WebSocketConnectError", event };
|
|
214
|
+
onError?.(error);
|
|
215
|
+
// Trigger reconnect only on WebSocketConnectError.
|
|
216
|
+
if (error.type === "WebSocketConnectError") {
|
|
217
|
+
resolve(err(error));
|
|
218
|
+
}
|
|
219
|
+
};
|
|
220
|
+
|
|
221
|
+
socket.onclose = (event) => {
|
|
222
|
+
onClose?.(event);
|
|
223
|
+
resolve(err({ type: "WebSocketConnectionCloseError", event }));
|
|
224
|
+
};
|
|
225
|
+
|
|
226
|
+
socket.onmessage = (event) => {
|
|
227
|
+
onMessage?.(event.data as string | ArrayBuffer | Blob);
|
|
228
|
+
};
|
|
229
|
+
}),
|
|
230
|
+
{
|
|
231
|
+
...defaultRetryOptions,
|
|
232
|
+
...retryOptions,
|
|
233
|
+
},
|
|
234
|
+
)
|
|
235
|
+
.then((result) => {
|
|
236
|
+
if (result.ok || result.error.type === "RetryAbortError") return;
|
|
237
|
+
onError?.(result.error);
|
|
238
|
+
})
|
|
239
|
+
.catch((error: unknown) => {
|
|
240
|
+
assertNoErrorInCatch("WebSocket retry", error);
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
const webSocket: WebSocket = {
|
|
244
|
+
send: (data) => {
|
|
245
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/send
|
|
246
|
+
if (!socket || socket.readyState === socket.CONNECTING) {
|
|
247
|
+
return err({ type: "WebSocketSendError" });
|
|
248
|
+
}
|
|
249
|
+
socket.send(data);
|
|
250
|
+
return ok();
|
|
251
|
+
},
|
|
252
|
+
|
|
253
|
+
getReadyState: () =>
|
|
254
|
+
socket ? nativeToStringState[socket.readyState] : "connecting",
|
|
255
|
+
|
|
256
|
+
[Symbol.dispose]() {
|
|
257
|
+
if (isDisposed) return;
|
|
258
|
+
isDisposed = true;
|
|
259
|
+
reconnectController.abort();
|
|
260
|
+
disposeSocket();
|
|
261
|
+
disposePromise?.();
|
|
262
|
+
},
|
|
263
|
+
};
|
|
264
|
+
|
|
265
|
+
return webSocket;
|
|
266
|
+
};
|
|
267
|
+
|
|
268
|
+
const nativeToStringState: Record<number, WebSocketReadyState> = {
|
|
269
|
+
[WebSocket.CONNECTING]: "connecting",
|
|
270
|
+
[WebSocket.OPEN]: "open",
|
|
271
|
+
[WebSocket.CLOSING]: "closing",
|
|
272
|
+
[WebSocket.CLOSED]: "closed",
|
|
273
|
+
};
|
package/src/Worker.ts
ADDED
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cross-platform worker abstraction
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { assert } from "./Assert.js";
|
|
8
|
+
import { createTransferableError, TransferableError } from "./Error.js";
|
|
9
|
+
|
|
10
|
+
/** Cross-platform worker abstraction. */
|
|
11
|
+
export interface Worker<Input, Output> {
|
|
12
|
+
/** Sends a message to the worker. */
|
|
13
|
+
readonly postMessage: (message: Input) => void;
|
|
14
|
+
|
|
15
|
+
/** Sets a callback for messages from the worker. */
|
|
16
|
+
readonly onMessage: (callback: (message: Output) => void) => void;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface WorkerPostMessageDep<Output> {
|
|
20
|
+
readonly postMessage: (message: Output) => void;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Creates a {@link Worker} that supports initialization with dependencies and
|
|
25
|
+
* safe error handling.
|
|
26
|
+
*/
|
|
27
|
+
export const createInitializedWorker = <
|
|
28
|
+
Input extends { readonly type: string } & HasInit<Input>,
|
|
29
|
+
Output extends { readonly type: string } & HasWorkerErrorOutput<Output>,
|
|
30
|
+
Deps,
|
|
31
|
+
>({
|
|
32
|
+
init,
|
|
33
|
+
onMessage,
|
|
34
|
+
}: {
|
|
35
|
+
readonly init: (
|
|
36
|
+
initMessage: Extract<Input, { type: "init" }>,
|
|
37
|
+
postMessage: (msg: Output) => void,
|
|
38
|
+
safeHandler: <A extends Array<any>>(
|
|
39
|
+
handler: (...args: A) => void,
|
|
40
|
+
) => (...args: A) => void,
|
|
41
|
+
) => Promise<Deps | null>;
|
|
42
|
+
readonly onMessage: (
|
|
43
|
+
deps: Deps,
|
|
44
|
+
) => (message: Exclude<Input, { type: "init" }>) => void;
|
|
45
|
+
}): Worker<Input, Output> => {
|
|
46
|
+
type NonInitMessage = Exclude<Input, { type: "init" }>;
|
|
47
|
+
|
|
48
|
+
let onMessageCallback: ((msg: Output) => void) | null = null;
|
|
49
|
+
let deps: Deps | null = null;
|
|
50
|
+
const pendingMessages: Array<Input> = [];
|
|
51
|
+
let initializing = false;
|
|
52
|
+
|
|
53
|
+
const postMessage = (msg: Output) => {
|
|
54
|
+
assert(onMessageCallback != null, "The onMessage wasn't set");
|
|
55
|
+
onMessageCallback(msg);
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
const postMessageTransferableError = (error: unknown) => {
|
|
59
|
+
postMessage({
|
|
60
|
+
type: "onError",
|
|
61
|
+
error: createTransferableError(error),
|
|
62
|
+
} as unknown as Output);
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
const safeHandler =
|
|
66
|
+
<A extends Array<any>>(handler: (...args: A) => void) =>
|
|
67
|
+
(...args: A) => {
|
|
68
|
+
try {
|
|
69
|
+
handler(...args);
|
|
70
|
+
} catch (error) {
|
|
71
|
+
postMessageTransferableError(error);
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
const worker: Worker<Input, Output> = {
|
|
76
|
+
postMessage: (message) => {
|
|
77
|
+
if (message.type !== "init") {
|
|
78
|
+
if (!deps) {
|
|
79
|
+
pendingMessages.push(message);
|
|
80
|
+
} else {
|
|
81
|
+
safeHandler(onMessage(deps))(message as NonInitMessage);
|
|
82
|
+
}
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (initializing) return;
|
|
87
|
+
initializing = true;
|
|
88
|
+
|
|
89
|
+
init(
|
|
90
|
+
message as Extract<Input, { type: "init" }>,
|
|
91
|
+
postMessage,
|
|
92
|
+
safeHandler,
|
|
93
|
+
)
|
|
94
|
+
.then((_deps) => {
|
|
95
|
+
if (_deps == null) return;
|
|
96
|
+
deps = _deps;
|
|
97
|
+
for (const message of pendingMessages) {
|
|
98
|
+
safeHandler(onMessage(deps))(message as NonInitMessage);
|
|
99
|
+
}
|
|
100
|
+
pendingMessages.length = 0;
|
|
101
|
+
})
|
|
102
|
+
.catch(postMessageTransferableError);
|
|
103
|
+
},
|
|
104
|
+
|
|
105
|
+
onMessage: (callback) => {
|
|
106
|
+
onMessageCallback = callback;
|
|
107
|
+
},
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
return worker;
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
type HasInit<Input> =
|
|
114
|
+
Extract<Input, { type: "init" }> extends never
|
|
115
|
+
? ["Input must contain a variant with { type: 'init' }"]
|
|
116
|
+
: unknown;
|
|
117
|
+
|
|
118
|
+
type HasWorkerErrorOutput<T> =
|
|
119
|
+
Extract<T, { type: "onError" }> extends infer E
|
|
120
|
+
? [E] extends [never]
|
|
121
|
+
? [
|
|
122
|
+
"Output must contain { type: 'onError'; error: TransferableError | ... }",
|
|
123
|
+
]
|
|
124
|
+
: E extends { error: infer Err }
|
|
125
|
+
? TransferableError extends Err
|
|
126
|
+
? unknown
|
|
127
|
+
: ["Output.onError.error must include TransferableError"]
|
|
128
|
+
: ["Output.onError must have an error property"]
|
|
129
|
+
: never;
|
package/src/index.ts
CHANGED
|
@@ -1,15 +1,28 @@
|
|
|
1
|
-
export * from "./
|
|
2
|
-
export * from "./
|
|
1
|
+
export * from "./Array.js";
|
|
2
|
+
export * from "./Assert.js";
|
|
3
|
+
export * from "./BigInt.js";
|
|
4
|
+
export * from "./Buffer.js";
|
|
5
|
+
export * from "./Callbacks.js";
|
|
6
|
+
export * from "./Console.js";
|
|
3
7
|
export * from "./Crypto.js";
|
|
4
|
-
export * from "./
|
|
5
|
-
export * from "./Diff.js";
|
|
8
|
+
export * from "./Eq.js";
|
|
6
9
|
export * from "./Error.js";
|
|
7
|
-
export * from "./Evolu.js";
|
|
8
|
-
export * from "./
|
|
9
|
-
export * from "./
|
|
10
|
-
export * from "./
|
|
11
|
-
export * from "./
|
|
12
|
-
export * from "./
|
|
10
|
+
export * from "./Evolu/Public.js";
|
|
11
|
+
export * from "./Function.js";
|
|
12
|
+
export * from "./ManyToManyMap.js";
|
|
13
|
+
export * from "./NanoId.js";
|
|
14
|
+
export * from "./Number.js";
|
|
15
|
+
export * from "./Object.js";
|
|
16
|
+
export * from "./Order.js";
|
|
17
|
+
export * from "./Promise.js";
|
|
18
|
+
export * from "./Random.js";
|
|
19
|
+
export * from "./Ref.js";
|
|
20
|
+
export * from "./Result.js";
|
|
13
21
|
export * from "./Sqlite.js";
|
|
14
22
|
export * from "./Store.js";
|
|
15
|
-
export * from "./
|
|
23
|
+
export * from "./String.js";
|
|
24
|
+
export * from "./Time.js";
|
|
25
|
+
export * from "./Type.js";
|
|
26
|
+
export * from "./Types.js";
|
|
27
|
+
export * from "./WebSocket.js";
|
|
28
|
+
export * from "./Worker.js";
|
package/dist/src/Config.d.ts
DELETED
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
import * as Context from "effect/Context";
|
|
2
|
-
import * as ManagedRuntime from "effect/ManagedRuntime";
|
|
3
|
-
export interface Config {
|
|
4
|
-
/**
|
|
5
|
-
* URL to reload browser tabs after {@link Owner} reset or restore.
|
|
6
|
-
*
|
|
7
|
-
* The default value is `/`.
|
|
8
|
-
*/
|
|
9
|
-
reloadUrl: string;
|
|
10
|
-
/**
|
|
11
|
-
* URL for Evolu sync and backup server.
|
|
12
|
-
*
|
|
13
|
-
* The default value is `https://evolu.world`.
|
|
14
|
-
*/
|
|
15
|
-
syncUrl: string;
|
|
16
|
-
/**
|
|
17
|
-
* Evolu is multitenant - it can run more instances concurrently. Every Evolu
|
|
18
|
-
* instance has to have its own unique name. Database files are separated and
|
|
19
|
-
* invisible to each other.
|
|
20
|
-
*
|
|
21
|
-
* The default value is: `Evolu`.
|
|
22
|
-
*/
|
|
23
|
-
name: string;
|
|
24
|
-
/**
|
|
25
|
-
* Maximum physical clock drift allowed in ms.
|
|
26
|
-
*
|
|
27
|
-
* The default value is 5 * 60 * 1000 (5 minutes).
|
|
28
|
-
*/
|
|
29
|
-
maxDrift: number;
|
|
30
|
-
/**
|
|
31
|
-
* Setting the minimum log level. The default value is `none`.
|
|
32
|
-
*
|
|
33
|
-
* For development, use `trace` to log all events and `debug` to log only
|
|
34
|
-
* events with values. For production, use `warning`.
|
|
35
|
-
*/
|
|
36
|
-
minimumLogLevel: "none" | "trace" | "debug" | "warning";
|
|
37
|
-
/**
|
|
38
|
-
* Enables websocket connection
|
|
39
|
-
*
|
|
40
|
-
* If set to true runs a websocket connection on the sync url
|
|
41
|
-
*/
|
|
42
|
-
enableWebsocketConnection?: true;
|
|
43
|
-
/**
|
|
44
|
-
* Allows to reuse websocket connections for multiple database setup
|
|
45
|
-
*
|
|
46
|
-
* Works INSTEAD of enableWebsocket and if set overrides enableWebsocket this
|
|
47
|
-
* attaches the database to a connection produced by a call back from another
|
|
48
|
-
* database that has enableWebsocketConnection
|
|
49
|
-
*/
|
|
50
|
-
externalWebsocketConnection?: WebSocket;
|
|
51
|
-
}
|
|
52
|
-
export declare const Config: Context.Tag<Config, Config>;
|
|
53
|
-
export declare const defaultConfig: Config;
|
|
54
|
-
/** https://effect.website/docs/guides/runtime */
|
|
55
|
-
export declare const createRuntime: (partialConfig?: Partial<Config>) => ManagedRuntime.ManagedRuntime<Config, never>;
|
|
56
|
-
//# sourceMappingURL=Config.d.ts.map
|
package/dist/src/Config.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Config.d.ts","sourceRoot":"","sources":["../../src/Config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,gBAAgB,CAAC;AAI1C,OAAO,KAAK,cAAc,MAAM,uBAAuB,CAAC;AAGxD,MAAM,WAAW,MAAM;IACrB;;;;OAIG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;;;OAIG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;;;;;OAMG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;;;OAIG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;;;;OAKG;IACH,eAAe,EAAE,MAAM,GAAG,OAAO,GAAG,OAAO,GAAG,SAAS,CAAC;IAExD;;;;OAIG;IACH,yBAAyB,CAAC,EAAE,IAAI,CAAC;IAEjC;;;;;;OAMG;IACH,2BAA2B,CAAC,EAAE,SAAS,CAAC;CACzC;AAED,eAAO,MAAM,MAAM,6BAAuC,CAAC;AAE3D,eAAO,MAAM,aAAa,EAAE,MAM3B,CAAC;AAEF,iDAAiD;AACjD,eAAO,MAAM,aAAa,mBACR,OAAO,CAAC,MAAM,CAAC,KAC9B,cAAc,CAAC,cAAc,CAAC,MAAM,EAAE,KAAK,CAsB7C,CAAC"}
|