@evolu/common 8.0.0-next.4 → 8.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/dist/src/Array.d.ts +279 -173
- package/dist/src/Array.d.ts.map +1 -1
- package/dist/src/Array.js +105 -101
- package/dist/src/Assert.d.ts +44 -44
- package/dist/src/Assert.d.ts.map +1 -1
- package/dist/src/Assert.js +44 -32
- package/dist/src/BigInt.d.ts +6 -3
- package/dist/src/BigInt.d.ts.map +1 -1
- package/dist/src/BigInt.js +5 -2
- package/dist/src/Brand.d.ts +27 -40
- package/dist/src/Brand.d.ts.map +1 -1
- package/dist/src/Buffer.d.ts +27 -11
- package/dist/src/Buffer.d.ts.map +1 -1
- package/dist/src/Cache.d.ts +9 -4
- package/dist/src/Cache.d.ts.map +1 -1
- package/dist/src/Cache.js +8 -3
- package/dist/src/Callbacks.d.ts +30 -19
- package/dist/src/Callbacks.d.ts.map +1 -1
- package/dist/src/Console.d.ts +145 -66
- package/dist/src/Console.d.ts.map +1 -1
- package/dist/src/Console.js +91 -43
- package/dist/src/Crypto.d.ts +85 -42
- package/dist/src/Crypto.d.ts.map +1 -1
- package/dist/src/Crypto.js +44 -20
- package/dist/src/Eq.d.ts +87 -21
- package/dist/src/Eq.d.ts.map +1 -1
- package/dist/src/Eq.js +67 -19
- package/dist/src/Error.d.ts +5 -3
- package/dist/src/Error.d.ts.map +1 -1
- package/dist/src/Error.js +16 -0
- package/dist/src/Function.d.ts +119 -58
- package/dist/src/Function.d.ts.map +1 -1
- package/dist/src/Function.js +86 -43
- package/dist/src/Http.d.ts +394 -0
- package/dist/src/Http.d.ts.map +1 -0
- package/dist/src/Http.js +102 -0
- package/dist/src/Identicon.d.ts +16 -7
- package/dist/src/Identicon.d.ts.map +1 -1
- package/dist/src/Identicon.js +14 -5
- package/dist/src/LeakDetector.d.ts +88 -0
- package/dist/src/LeakDetector.d.ts.map +1 -0
- package/dist/src/LeakDetector.js +86 -0
- package/dist/src/LockManager.d.ts +18 -9
- package/dist/src/LockManager.d.ts.map +1 -1
- package/dist/src/LockManager.js +7 -8
- package/dist/src/Lookup.d.ts +43 -13
- package/dist/src/Lookup.d.ts.map +1 -1
- package/dist/src/Lookup.js +28 -8
- package/dist/src/Microtask.d.ts +1 -1
- package/dist/src/Microtask.d.ts.map +1 -1
- package/dist/src/Microtask.js +3 -7
- package/dist/src/Number.d.ts +49 -13
- package/dist/src/Number.d.ts.map +1 -1
- package/dist/src/Number.js +34 -5
- package/dist/src/Object.d.ts +160 -40
- package/dist/src/Object.d.ts.map +1 -1
- package/dist/src/Object.js +92 -46
- package/dist/src/Option.d.ts +10 -7
- package/dist/src/Option.d.ts.map +1 -1
- package/dist/src/Option.js +9 -6
- package/dist/src/Order.d.ts +21 -21
- package/dist/src/Order.d.ts.map +1 -1
- package/dist/src/Order.js +18 -21
- package/dist/src/Platform.d.ts +31 -0
- package/dist/src/Platform.d.ts.map +1 -1
- package/dist/src/Platform.js +98 -0
- package/dist/src/Random.d.ts +32 -17
- package/dist/src/Random.d.ts.map +1 -1
- package/dist/src/Random.js +12 -8
- package/dist/src/Redacted.d.ts +43 -29
- package/dist/src/Redacted.d.ts.map +1 -1
- package/dist/src/Redacted.js +14 -3
- package/dist/src/Ref.d.ts +11 -3
- package/dist/src/Ref.d.ts.map +1 -1
- package/dist/src/Ref.js +2 -2
- package/dist/src/RefCount.d.ts +2 -6
- package/dist/src/RefCount.d.ts.map +1 -1
- package/dist/src/RefCount.js +33 -90
- package/dist/src/Relation.d.ts +70 -5
- package/dist/src/Relation.d.ts.map +1 -1
- package/dist/src/Relation.js +77 -2
- package/dist/src/Resource.d.ts +590 -155
- package/dist/src/Resource.d.ts.map +1 -1
- package/dist/src/Resource.js +592 -343
- package/dist/src/Result.d.ts +838 -191
- package/dist/src/Result.d.ts.map +1 -1
- package/dist/src/Result.js +163 -102
- package/dist/src/Schedule.d.ts +684 -231
- package/dist/src/Schedule.d.ts.map +1 -1
- package/dist/src/Schedule.js +766 -295
- package/dist/src/Set.d.ts +89 -40
- package/dist/src/Set.d.ts.map +1 -1
- package/dist/src/Set.js +50 -29
- package/dist/src/Sqlite.d.ts +29 -72
- package/dist/src/Sqlite.d.ts.map +1 -1
- package/dist/src/Sqlite.js +41 -46
- package/dist/src/StackTrace.d.ts +40 -0
- package/dist/src/StackTrace.d.ts.map +1 -0
- package/dist/src/StackTrace.js +140 -0
- package/dist/src/Store.d.ts +5 -4
- package/dist/src/Store.d.ts.map +1 -1
- package/dist/src/Store.js +5 -4
- package/dist/src/String.d.ts +7 -1
- package/dist/src/String.d.ts.map +1 -1
- package/dist/src/String.js +20 -7
- package/dist/src/Task.d.ts +3572 -1770
- package/dist/src/Task.d.ts.map +1 -1
- package/dist/src/Task.js +1879 -1274
- package/dist/src/Test.d.ts +17 -125
- package/dist/src/Test.d.ts.map +1 -1
- package/dist/src/Test.js +17 -68
- package/dist/src/Time.d.ts +108 -49
- package/dist/src/Time.d.ts.map +1 -1
- package/dist/src/Time.js +172 -73
- package/dist/src/Type.d.ts +3542 -1926
- package/dist/src/Type.d.ts.map +1 -1
- package/dist/src/Type.js +3070 -1784
- package/dist/src/Types.d.ts +200 -108
- package/dist/src/Types.d.ts.map +1 -1
- package/dist/src/Types.js +39 -8
- package/dist/src/WebSocket.d.ts +48 -23
- package/dist/src/WebSocket.d.ts.map +1 -1
- package/dist/src/WebSocket.js +15 -6
- package/dist/src/Worker.d.ts +94 -36
- package/dist/src/Worker.d.ts.map +1 -1
- package/dist/src/Worker.js +58 -24
- package/dist/src/index.d.ts +55 -52
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +3 -1
- package/dist/src/intl/cs.d.ts +94 -0
- package/dist/src/intl/cs.d.ts.map +1 -0
- package/dist/src/intl/cs.js +220 -0
- package/dist/src/intl/index.d.ts +7 -0
- package/dist/src/intl/index.d.ts.map +1 -0
- package/dist/src/intl/index.js +6 -0
- package/dist/src/local-first/Db.d.ts +12 -8
- package/dist/src/local-first/Db.d.ts.map +1 -1
- package/dist/src/local-first/Db.js +109 -132
- package/dist/src/local-first/Error.d.ts +4 -4
- package/dist/src/local-first/Evolu.d.ts +338 -92
- package/dist/src/local-first/Evolu.d.ts.map +1 -1
- package/dist/src/local-first/Evolu.js +47 -55
- package/dist/src/local-first/LocalAuth.d.ts +4 -4
- package/dist/src/local-first/LocalAuth.d.ts.map +1 -1
- package/dist/src/local-first/Owner.d.ts +61 -24
- package/dist/src/local-first/Owner.d.ts.map +1 -1
- package/dist/src/local-first/Owner.js +45 -8
- package/dist/src/local-first/Protocol.d.ts +44 -31
- package/dist/src/local-first/Protocol.d.ts.map +1 -1
- package/dist/src/local-first/Protocol.js +36 -13
- package/dist/src/local-first/Query.d.ts +147 -62
- package/dist/src/local-first/Query.d.ts.map +1 -1
- package/dist/src/local-first/Query.js +112 -58
- package/dist/src/local-first/Relay.d.ts +44 -14
- package/dist/src/local-first/Relay.d.ts.map +1 -1
- package/dist/src/local-first/Schema.d.ts +92 -41
- package/dist/src/local-first/Schema.d.ts.map +1 -1
- package/dist/src/local-first/Schema.js +25 -8
- package/dist/src/local-first/Shared.d.ts +23 -21
- package/dist/src/local-first/Shared.d.ts.map +1 -1
- package/dist/src/local-first/Shared.js +100 -57
- package/dist/src/local-first/Storage.d.ts +53 -32
- package/dist/src/local-first/Storage.d.ts.map +1 -1
- package/dist/src/local-first/Storage.js +194 -234
- package/dist/src/local-first/Timestamp.d.ts +21 -21
- package/dist/src/local-first/Timestamp.d.ts.map +1 -1
- package/dist/src/local-first/Timestamp.js +2 -2
- package/dist/src/local-first/index.d.ts +11 -11
- package/package.json +14 -13
- package/src/Array.ts +306 -205
- package/src/Assert.ts +54 -69
- package/src/BigInt.ts +6 -3
- package/src/Brand.ts +27 -40
- package/src/Buffer.ts +28 -12
- package/src/Cache.ts +9 -4
- package/src/Callbacks.ts +30 -19
- package/src/Console.ts +156 -84
- package/src/Crypto.ts +83 -41
- package/src/Eq.ts +95 -22
- package/src/Error.ts +8 -4
- package/src/Function.ts +167 -59
- package/src/Http.ts +549 -0
- package/src/Identicon.ts +16 -7
- package/src/LeakDetector.ts +182 -0
- package/src/LockManager.ts +43 -39
- package/src/Lookup.ts +62 -28
- package/src/Microtask.ts +19 -23
- package/src/Number.ts +64 -12
- package/src/Object.ts +173 -49
- package/src/Option.ts +10 -7
- package/src/Order.ts +23 -21
- package/src/Platform.ts +136 -0
- package/src/Polyfills.ts +6 -12
- package/src/Random.ts +32 -19
- package/src/Redacted.ts +44 -30
- package/src/Ref.ts +14 -6
- package/src/RefCount.ts +38 -80
- package/src/Relation.ts +202 -10
- package/src/Resource.ts +1199 -591
- package/src/Result.ts +930 -271
- package/src/Schedule.ts +859 -343
- package/src/Set.ts +89 -40
- package/src/Sqlite.ts +144 -138
- package/src/StackTrace.ts +230 -0
- package/src/Store.ts +8 -7
- package/src/String.ts +22 -5
- package/src/Task.ts +5101 -2832
- package/src/Test.ts +20 -168
- package/src/Time.ts +293 -90
- package/src/Type.ts +10034 -4117
- package/src/Types.ts +227 -110
- package/src/WebSocket.ts +64 -36
- package/src/Worker.ts +180 -72
- package/src/index.ts +55 -52
- package/src/intl/cs.ts +388 -0
- package/src/intl/index.ts +7 -0
- package/src/local-first/Db.ts +152 -179
- package/src/local-first/Error.ts +4 -4
- package/src/local-first/Evolu.ts +495 -250
- package/src/local-first/LocalAuth.ts +6 -12
- package/src/local-first/Owner.ts +58 -21
- package/src/local-first/Protocol.ts +49 -31
- package/src/local-first/Query.ts +146 -61
- package/src/local-first/Relay.ts +51 -21
- package/src/local-first/Schema.ts +109 -51
- package/src/local-first/Shared.ts +266 -226
- package/src/local-first/Storage.ts +266 -264
- package/src/local-first/Timestamp.ts +25 -18
- package/src/local-first/index.ts +11 -11
- package/dist/src/Skiplist.d.ts +0 -28
- package/dist/src/Skiplist.d.ts.map +0 -1
- package/dist/src/Skiplist.js +0 -64
- package/dist/src/Tracer.d.ts +0 -48
- package/dist/src/Tracer.d.ts.map +0 -1
- package/dist/src/Tracer.js +0 -6
- package/src/Skiplist.ts +0 -108
- package/src/Tracer.ts +0 -54
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { AliasNode, ColumnNode, ExpressionWrapper, IdentifierNode, sql as kyselySqlBuilder, ReferenceNode, TableNode, ValueNode, } from "kysely";
|
|
7
7
|
import { createRandomBytes } from "../Crypto.js";
|
|
8
|
-
import {
|
|
8
|
+
import { createMutableRecord, isPlainObject } from "../Object.js";
|
|
9
9
|
import { eqSqliteValue, SqliteValue } from "../Sqlite.js";
|
|
10
10
|
import { createId, String } from "../Type.js";
|
|
11
11
|
export { sql as kyselySql } from "kysely";
|
|
@@ -21,25 +21,42 @@ export { sql as kyselySql } from "kysely";
|
|
|
21
21
|
* ### Example
|
|
22
22
|
*
|
|
23
23
|
* ```ts
|
|
24
|
-
* import {
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
24
|
+
* import {
|
|
25
|
+
* createQueryBuilder,
|
|
26
|
+
* evoluJsonArrayFrom,
|
|
27
|
+
* id,
|
|
28
|
+
* NonEmptyTrimmedString100,
|
|
29
|
+
* } from "@evolu/common";
|
|
30
|
+
*
|
|
31
|
+
* const PersonId = id("Person");
|
|
32
|
+
* const Schema = {
|
|
33
|
+
* person: { id: PersonId },
|
|
34
|
+
* pet: {
|
|
35
|
+
* id: id("Pet"),
|
|
36
|
+
* name: NonEmptyTrimmedString100,
|
|
37
|
+
* personId: PersonId,
|
|
38
|
+
* },
|
|
39
|
+
* };
|
|
40
|
+
* const createQuery = createQueryBuilder(Schema);
|
|
41
|
+
* const people = createQuery((db) =>
|
|
42
|
+
* db
|
|
43
|
+
* .selectFrom("person")
|
|
44
|
+
* .select(["person.id"])
|
|
45
|
+
* .select((eb) => [
|
|
46
|
+
* evoluJsonArrayFrom(
|
|
47
|
+
* eb
|
|
48
|
+
* .selectFrom("pet")
|
|
49
|
+
* .select(["pet.id as petId", "pet.name"])
|
|
50
|
+
* .whereRef("pet.personId", "=", "person.id")
|
|
51
|
+
* .orderBy("pet.name"),
|
|
52
|
+
* ).as("pets"),
|
|
53
|
+
* ]),
|
|
54
|
+
* );
|
|
55
|
+
*
|
|
56
|
+
* expectTypeOf<(typeof people.Row.pets)[number]>().toEqualTypeOf<{
|
|
57
|
+
* petId: typeof Schema.pet.id.Output;
|
|
58
|
+
* name: NonEmptyTrimmedString100 | null;
|
|
59
|
+
* }>();
|
|
43
60
|
* ```
|
|
44
61
|
*/
|
|
45
62
|
export const evoluJsonArrayFrom = (expr) => kyselySqlBuilder `(select ${kyselySqlBuilder.lit(kyselyJsonIdentifier)} || coalesce(json_group_array(json_object(${kyselySqlBuilder.join(getSqliteJsonObjectArgs(expr.toOperationNode(), "agg"))})), '[]') from ${expr} as agg)`;
|
|
@@ -57,25 +74,44 @@ export const evoluJsonArrayFrom = (expr) => kyselySqlBuilder `(select ${kyselySq
|
|
|
57
74
|
* ### Example
|
|
58
75
|
*
|
|
59
76
|
* ```ts
|
|
60
|
-
* import {
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
*
|
|
74
|
-
*
|
|
75
|
-
*
|
|
76
|
-
*
|
|
77
|
-
*
|
|
78
|
-
*
|
|
77
|
+
* import {
|
|
78
|
+
* createQueryBuilder,
|
|
79
|
+
* evoluJsonObjectFrom,
|
|
80
|
+
* id,
|
|
81
|
+
* NonEmptyTrimmedString100,
|
|
82
|
+
* SqliteBoolean,
|
|
83
|
+
* } from "@evolu/common";
|
|
84
|
+
*
|
|
85
|
+
* const PersonId = id("Person");
|
|
86
|
+
* const Schema = {
|
|
87
|
+
* person: { id: PersonId },
|
|
88
|
+
* pet: {
|
|
89
|
+
* id: id("Pet"),
|
|
90
|
+
* name: NonEmptyTrimmedString100,
|
|
91
|
+
* personId: PersonId,
|
|
92
|
+
* isFavorite: SqliteBoolean,
|
|
93
|
+
* },
|
|
94
|
+
* };
|
|
95
|
+
* const createQuery = createQueryBuilder(Schema);
|
|
96
|
+
* const people = createQuery((db) =>
|
|
97
|
+
* db
|
|
98
|
+
* .selectFrom("person")
|
|
99
|
+
* .select(["person.id"])
|
|
100
|
+
* .select((eb) => [
|
|
101
|
+
* evoluJsonObjectFrom(
|
|
102
|
+
* eb
|
|
103
|
+
* .selectFrom("pet")
|
|
104
|
+
* .select(["pet.id as petId", "pet.name"])
|
|
105
|
+
* .whereRef("pet.personId", "=", "person.id")
|
|
106
|
+
* .where("pet.isFavorite", "=", 1),
|
|
107
|
+
* ).as("favoritePet"),
|
|
108
|
+
* ]),
|
|
109
|
+
* );
|
|
110
|
+
*
|
|
111
|
+
* expectTypeOf<typeof people.Row.favoritePet>().toEqualTypeOf<{
|
|
112
|
+
* petId: typeof Schema.pet.id.Output;
|
|
113
|
+
* name: NonEmptyTrimmedString100 | null;
|
|
114
|
+
* } | null>();
|
|
79
115
|
* ```
|
|
80
116
|
*/
|
|
81
117
|
export const evoluJsonObjectFrom = (expr) => kyselySqlBuilder `(select ${kyselySqlBuilder.lit(kyselyJsonIdentifier)} || json_object(${kyselySqlBuilder.join(getSqliteJsonObjectArgs(expr.toOperationNode(), "obj"))}) from ${expr} as obj)`;
|
|
@@ -91,24 +127,42 @@ export const evoluJsonObjectFrom = (expr) => kyselySqlBuilder `(select ${kyselyS
|
|
|
91
127
|
* ### Example
|
|
92
128
|
*
|
|
93
129
|
* ```ts
|
|
94
|
-
* import {
|
|
95
|
-
*
|
|
96
|
-
*
|
|
97
|
-
*
|
|
98
|
-
*
|
|
99
|
-
*
|
|
100
|
-
*
|
|
101
|
-
*
|
|
102
|
-
*
|
|
103
|
-
*
|
|
104
|
-
*
|
|
105
|
-
*
|
|
106
|
-
*
|
|
107
|
-
*
|
|
108
|
-
*
|
|
109
|
-
*
|
|
110
|
-
*
|
|
111
|
-
*
|
|
130
|
+
* import {
|
|
131
|
+
* createQueryBuilder,
|
|
132
|
+
* evoluJsonBuildObject,
|
|
133
|
+
* id,
|
|
134
|
+
* kyselySql,
|
|
135
|
+
* NonEmptyTrimmedString100,
|
|
136
|
+
* } from "@evolu/common";
|
|
137
|
+
*
|
|
138
|
+
* const Schema = {
|
|
139
|
+
* person: {
|
|
140
|
+
* id: id("Person"),
|
|
141
|
+
* firstName: NonEmptyTrimmedString100,
|
|
142
|
+
* lastName: NonEmptyTrimmedString100,
|
|
143
|
+
* },
|
|
144
|
+
* };
|
|
145
|
+
* const createQuery = createQueryBuilder(Schema);
|
|
146
|
+
* const people = createQuery((db) =>
|
|
147
|
+
* db
|
|
148
|
+
* .selectFrom("person")
|
|
149
|
+
* .select("person.id")
|
|
150
|
+
* .select((eb) => [
|
|
151
|
+
* evoluJsonBuildObject({
|
|
152
|
+
* first: eb.ref("firstName"),
|
|
153
|
+
* last: eb.ref("lastName"),
|
|
154
|
+
* full: kyselySql<string>`${eb.ref("firstName")} || ' ' || ${eb.ref(
|
|
155
|
+
* "lastName",
|
|
156
|
+
* )}`,
|
|
157
|
+
* }).as("name"),
|
|
158
|
+
* ]),
|
|
159
|
+
* );
|
|
160
|
+
*
|
|
161
|
+
* expectTypeOf<typeof people.Row.name>().toEqualTypeOf<{
|
|
162
|
+
* first: NonEmptyTrimmedString100 | null;
|
|
163
|
+
* last: NonEmptyTrimmedString100 | null;
|
|
164
|
+
* full: string;
|
|
165
|
+
* }>();
|
|
112
166
|
* ```
|
|
113
167
|
*/
|
|
114
168
|
export const evoluJsonBuildObject = (obj) => kyselySqlBuilder `${kyselySqlBuilder.lit(kyselyJsonIdentifier)} || json_object(${kyselySqlBuilder.join(Object.keys(obj).flatMap((k) => [kyselySqlBuilder.lit(k), obj[k]]))})`;
|
|
@@ -219,7 +273,7 @@ const parse = (obj) => {
|
|
|
219
273
|
return obj;
|
|
220
274
|
};
|
|
221
275
|
const parseObject = (obj) => {
|
|
222
|
-
const result =
|
|
276
|
+
const result = createMutableRecord();
|
|
223
277
|
for (const key in obj) {
|
|
224
278
|
result[key] = parse(obj[key]);
|
|
225
279
|
}
|
|
@@ -3,12 +3,12 @@
|
|
|
3
3
|
*
|
|
4
4
|
* @module
|
|
5
5
|
*/
|
|
6
|
-
import type { TimingSafeEqualDep } from "../Crypto.
|
|
7
|
-
import type { SqliteDep } from "../Sqlite.
|
|
8
|
-
import { Name } from "../Type.
|
|
9
|
-
import { type Awaitable } from "../Types.
|
|
10
|
-
import { OwnerId } from "./Owner.
|
|
11
|
-
import type { SqliteStorageDeps, Storage, StorageConfig } from "./Storage.
|
|
6
|
+
import type { TimingSafeEqualDep } from "../Crypto.ts";
|
|
7
|
+
import type { SqliteDep } from "../Sqlite.ts";
|
|
8
|
+
import { Name } from "../Type.ts";
|
|
9
|
+
import { type Awaitable } from "../Types.ts";
|
|
10
|
+
import { OwnerId } from "./Owner.ts";
|
|
11
|
+
import type { SqliteStorageDeps, Storage, StorageConfig } from "./Storage.ts";
|
|
12
12
|
export interface RelayConfig extends StorageConfig {
|
|
13
13
|
/**
|
|
14
14
|
* The relay name.
|
|
@@ -45,20 +45,50 @@ export interface RelayConfig extends StorageConfig {
|
|
|
45
45
|
* ### Example
|
|
46
46
|
*
|
|
47
47
|
* ```ts
|
|
48
|
-
*
|
|
48
|
+
* import {
|
|
49
|
+
* AppName,
|
|
50
|
+
* createAppOwner,
|
|
51
|
+
* createEvolu,
|
|
52
|
+
* createOwnerWebSocketTransport,
|
|
53
|
+
* createOwnerSecret,
|
|
54
|
+
* createRandomBytes,
|
|
55
|
+
* id,
|
|
56
|
+
* type AnyTask,
|
|
57
|
+
* } from "@evolu/common";
|
|
58
|
+
* import type { RelayConfig } from "@evolu/common/local-first";
|
|
59
|
+
*
|
|
60
|
+
* // Create once, persist the mnemonic securely, and restore it on later runs.
|
|
61
|
+
* const appOwner = createAppOwner(
|
|
62
|
+
* createOwnerSecret({ randomBytes: createRandomBytes() }),
|
|
63
|
+
* );
|
|
64
|
+
* // Client: include the OwnerId so the relay can authenticate the connection.
|
|
49
65
|
* const transport = createOwnerWebSocketTransport({
|
|
50
66
|
* url: "wss://relay.evolu.dev",
|
|
51
|
-
* ownerId:
|
|
67
|
+
* ownerId: appOwner.id,
|
|
52
68
|
* });
|
|
53
69
|
*
|
|
54
|
-
* const
|
|
55
|
-
*
|
|
56
|
-
*
|
|
70
|
+
* const createTodoEvolu = createEvolu(
|
|
71
|
+
* { todo: { id: id("Todo") } },
|
|
72
|
+
* {
|
|
73
|
+
* appName: AppName.orThrow("AuthenticatedRelayExample"),
|
|
74
|
+
* appOwner,
|
|
75
|
+
* transports: [transport],
|
|
76
|
+
* },
|
|
77
|
+
* );
|
|
78
|
+
* expectTypeOf(createTodoEvolu).toExtend<AnyTask>();
|
|
57
79
|
*
|
|
80
|
+
* // Relay: accept owners allowed by the app's access policy.
|
|
81
|
+
* type IsOwnerAllowed = NonNullable<RelayConfig["isOwnerAllowed"]>;
|
|
82
|
+
* const allowedOwnerIds = new Set([appOwner.id]);
|
|
83
|
+
* const isOwnerAllowed: IsOwnerAllowed = (ownerId, { signal }) =>
|
|
84
|
+
* !signal.aborted && allowedOwnerIds.has(ownerId);
|
|
58
85
|
*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
*
|
|
86
|
+
* expect(
|
|
87
|
+
* isOwnerAllowed(appOwner.id, {
|
|
88
|
+
* signal: new AbortController().signal,
|
|
89
|
+
* }),
|
|
90
|
+
* ).toBe(true);
|
|
91
|
+
* expect(transport.url).toContain(`ownerId=${appOwner.id}`);
|
|
62
92
|
* ```
|
|
63
93
|
*/
|
|
64
94
|
readonly isOwnerAllowed?: (ownerId: OwnerId, options: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Relay.d.ts","sourceRoot":"","sources":["../../../src/local-first/Relay.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAUH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAEvD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAG9C,OAAO,EAAE,IAAI,EAAsC,MAAM,YAAY,CAAC;AACtE,OAAO,EAAiB,KAAK,SAAS,EAAE,MAAM,aAAa,CAAC;AAC5D,OAAO,EACL,OAAO,EAIR,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAEV,iBAAiB,EACjB,OAAO,EACP,aAAa,EAEd,MAAM,cAAc,CAAC;AAStB,MAAM,WAAW,WAAY,SAAQ,aAAa;IAChD;;;;;OAKG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC;IAErB
|
|
1
|
+
{"version":3,"file":"Relay.d.ts","sourceRoot":"","sources":["../../../src/local-first/Relay.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAUH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAEvD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAG9C,OAAO,EAAE,IAAI,EAAsC,MAAM,YAAY,CAAC;AACtE,OAAO,EAAiB,KAAK,SAAS,EAAE,MAAM,aAAa,CAAC;AAC5D,OAAO,EACL,OAAO,EAIR,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAEV,iBAAiB,EACjB,OAAO,EACP,aAAa,EAEd,MAAM,cAAc,CAAC;AAStB,MAAM,WAAW,WAAY,SAAQ,aAAa;IAChD;;;;;OAKG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC;IAErB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAyEG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,CACxB,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE;QACP,iEAAiE;QACjE,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;KAC9B,KACE,SAAS,CAAC,OAAO,CAAC,CAAC;CACzB;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,KAAM,SAAQ,eAAe;IAC5C,gDAAgD;IAChD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,eAAO,MAAM,wBAAwB,SAC5B,iBAAiB,GAAG,kBAAkB,cACpC,aAAa,KAAG,OAuLxB,CAAC;AAEJ,eAAO,MAAM,wBAAwB,SAAU,SAAS,KAAG,IAuB1D,CAAC"}
|
|
@@ -4,16 +4,16 @@
|
|
|
4
4
|
* @module
|
|
5
5
|
*/
|
|
6
6
|
import * as Kysely from "kysely";
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import type
|
|
10
|
-
import { type Id, IdBytes, type
|
|
11
|
-
import type { Simplify } from "../Types.
|
|
12
|
-
import { OwnerId } from "./Owner.
|
|
13
|
-
import type { Query, Row } from "./Query.
|
|
14
|
-
import type { DbChange } from "./Storage.
|
|
15
|
-
import { TimestampBytes } from "./Timestamp.
|
|
16
|
-
/** Any
|
|
7
|
+
import type { StandardSchemaV1 } from "@standard-schema/spec";
|
|
8
|
+
import { type ReadonlyRecord } from "../Object.ts";
|
|
9
|
+
import { SqliteBoolean, type SqliteDep, type SqliteQueryOptions, type SqliteSchema, SqliteValue } from "../Sqlite.ts";
|
|
10
|
+
import { DateIso, type Id, IdBytes, type InferType, Null, type ObjectType, type UnionType } from "../Type.ts";
|
|
11
|
+
import type { CompileTimeError, Simplify } from "../Types.ts";
|
|
12
|
+
import { OwnerId } from "./Owner.ts";
|
|
13
|
+
import type { Query, Row } from "./Query.ts";
|
|
14
|
+
import type { DbChange } from "./Storage.ts";
|
|
15
|
+
import { TimestampBytes } from "./Timestamp.ts";
|
|
16
|
+
/** Any Standard Schema V1 declaration. */
|
|
17
17
|
export type AnyStandardSchemaV1 = StandardSchemaV1<any, any>;
|
|
18
18
|
/**
|
|
19
19
|
* Defines the schema of an Evolu database.
|
|
@@ -27,26 +27,36 @@ export type AnyStandardSchemaV1 = StandardSchemaV1<any, any>;
|
|
|
27
27
|
* ### Example
|
|
28
28
|
*
|
|
29
29
|
* ```ts
|
|
30
|
-
*
|
|
30
|
+
* import * as z from "zod";
|
|
31
|
+
* import {
|
|
32
|
+
* id,
|
|
33
|
+
* NonEmptyTrimmedString100,
|
|
34
|
+
* nullOr,
|
|
35
|
+
* SqliteBoolean,
|
|
36
|
+
* } from "@evolu/common";
|
|
37
|
+
*
|
|
38
|
+
* // Evolu Type
|
|
31
39
|
* const TodoId = id("Todo");
|
|
32
|
-
* type TodoId = typeof TodoId.
|
|
40
|
+
* type TodoId = typeof TodoId.Output;
|
|
33
41
|
*
|
|
34
42
|
* const Schema = {
|
|
35
43
|
* todo: {
|
|
36
44
|
* id: TodoId,
|
|
37
|
-
* title:
|
|
45
|
+
* title: NonEmptyTrimmedString100,
|
|
38
46
|
* isCompleted: nullOr(SqliteBoolean),
|
|
39
47
|
* },
|
|
40
48
|
* };
|
|
49
|
+
* expectOk(Schema.todo.title.fromUnknown("Write docs"), "Write docs");
|
|
41
50
|
*
|
|
42
|
-
* //
|
|
43
|
-
* const
|
|
51
|
+
* // Zod, or another Standard Schema library
|
|
52
|
+
* const ZodSchema = {
|
|
44
53
|
* todo: {
|
|
45
|
-
* id: TodoId,
|
|
54
|
+
* id: TodoId,
|
|
46
55
|
* title: z.string().min(1).max(100),
|
|
47
56
|
* isCompleted: z.union([z.literal(0), z.literal(1)]).nullable(),
|
|
48
57
|
* },
|
|
49
58
|
* };
|
|
59
|
+
* expect(ZodSchema.todo.title.safeParse("Write docs").success).toBe(true);
|
|
50
60
|
* ```
|
|
51
61
|
*/
|
|
52
62
|
export type EvoluSchema = ReadonlyRecord<string, TableSchema>;
|
|
@@ -89,7 +99,7 @@ export type CreateQuery<S extends EvoluSchema> = <R extends Row>(queryCallback:
|
|
|
89
99
|
readonly column: string;
|
|
90
100
|
readonly value: SqliteValue;
|
|
91
101
|
};
|
|
92
|
-
}>, "selectFrom" | "fn" | "with" | "withRecursive">) => Kysely.SelectQueryBuilder<any, any, R>, options?: SqliteQueryOptions) => Query<S, Simplify<R>>;
|
|
102
|
+
}>, "selectFrom" | "fn" | "with" | "withRecursive">) => Kysely.SelectQueryBuilder<any, any, R>, options?: SqliteQueryOptions) => Query<S, Kysely.Simplify<R>>;
|
|
93
103
|
/**
|
|
94
104
|
* System columns that are implicitly defined by Evolu.
|
|
95
105
|
*
|
|
@@ -99,11 +109,11 @@ export type CreateQuery<S extends EvoluSchema> = <R extends Row>(queryCallback:
|
|
|
99
109
|
* mark rows as deleted.
|
|
100
110
|
* - `ownerId`: Represents ownership and logically partitions the database.
|
|
101
111
|
*/
|
|
102
|
-
export declare const SystemColumns:
|
|
103
|
-
createdAt:
|
|
104
|
-
updatedAt:
|
|
105
|
-
isDeleted:
|
|
106
|
-
ownerId:
|
|
112
|
+
export declare const SystemColumns: ObjectType<{
|
|
113
|
+
readonly createdAt: typeof DateIso;
|
|
114
|
+
readonly updatedAt: typeof DateIso;
|
|
115
|
+
readonly isDeleted: UnionType<readonly [typeof SqliteBoolean, typeof Null]>;
|
|
116
|
+
readonly ownerId: typeof OwnerId;
|
|
107
117
|
}>;
|
|
108
118
|
export interface SystemColumns extends InferType<typeof SystemColumns> {
|
|
109
119
|
}
|
|
@@ -149,24 +159,50 @@ export interface MutationOptions {
|
|
|
149
159
|
* ### Example
|
|
150
160
|
*
|
|
151
161
|
* ```ts
|
|
152
|
-
*
|
|
162
|
+
* import {
|
|
163
|
+
* createAppOwner,
|
|
164
|
+
* createOwnerSecret,
|
|
165
|
+
* createRandomBytes,
|
|
166
|
+
* createSharedOwner,
|
|
167
|
+
* deriveShardOwner,
|
|
168
|
+
* id,
|
|
169
|
+
* NonEmptyTrimmedString100,
|
|
170
|
+
* type Evolu,
|
|
171
|
+
* } from "@evolu/common";
|
|
172
|
+
*
|
|
173
|
+
* const Schema = {
|
|
174
|
+
* task: { id: id("Task"), title: NonEmptyTrimmedString100 },
|
|
175
|
+
* comment: { id: id("Comment"), text: NonEmptyTrimmedString100 },
|
|
176
|
+
* };
|
|
177
|
+
* const randomBytes = createRandomBytes();
|
|
178
|
+
* // Create once, persist the mnemonic securely, and restore it on later runs.
|
|
179
|
+
* const appOwner = createAppOwner(createOwnerSecret({ randomBytes }));
|
|
153
180
|
* const projectOwner = deriveShardOwner(appOwner, [
|
|
154
181
|
* "project",
|
|
155
|
-
*
|
|
182
|
+
* "project-1",
|
|
156
183
|
* ]);
|
|
157
|
-
*
|
|
158
|
-
*
|
|
159
|
-
* { title: "Task 1" },
|
|
160
|
-
* { ownerId: projectOwner.id },
|
|
184
|
+
* const sharedOwner = createSharedOwner(
|
|
185
|
+
* createOwnerSecret({ randomBytes }),
|
|
161
186
|
* );
|
|
162
187
|
*
|
|
163
|
-
*
|
|
164
|
-
*
|
|
165
|
-
*
|
|
166
|
-
*
|
|
167
|
-
*
|
|
168
|
-
*
|
|
169
|
-
*
|
|
188
|
+
* const insertOwnedRows = (evolu: Evolu<typeof Schema>): void => {
|
|
189
|
+
* // Partition app data by project.
|
|
190
|
+
* evolu.insert(
|
|
191
|
+
* "task",
|
|
192
|
+
* { title: NonEmptyTrimmedString100.orThrow("Task 1") },
|
|
193
|
+
* { ownerId: projectOwner.id },
|
|
194
|
+
* );
|
|
195
|
+
*
|
|
196
|
+
* // Put collaborative data under a shared owner.
|
|
197
|
+
* evolu.insert(
|
|
198
|
+
* "comment",
|
|
199
|
+
* { text: NonEmptyTrimmedString100.orThrow("Hello") },
|
|
200
|
+
* { ownerId: sharedOwner.id },
|
|
201
|
+
* );
|
|
202
|
+
* };
|
|
203
|
+
*
|
|
204
|
+
* expect(projectOwner.type).toBe("ShardOwner");
|
|
205
|
+
* expect(sharedOwner.type).toBe("SharedOwner");
|
|
170
206
|
* ```
|
|
171
207
|
*/
|
|
172
208
|
readonly ownerId?: OwnerId;
|
|
@@ -207,7 +243,7 @@ export type ValidateIdColumnType<S extends EvoluSchema> = keyof S extends infer
|
|
|
207
243
|
export type ValidateNoSystemColumns<S extends EvoluSchema> = keyof S extends infer TableName ? TableName extends keyof S ? keyof S[TableName] extends infer ColumnName ? ColumnName extends keyof S[TableName] ? ColumnName extends "createdAt" | "updatedAt" | "isDeleted" | "ownerId" ? SchemaValidationError<`Table "${TableName & string}" uses system column name "${ColumnName & string}". System columns (createdAt, updatedAt, isDeleted, ownerId) are added automatically.`> : never : never : never : never : never;
|
|
208
244
|
export type ValidateColumnTypes<S extends EvoluSchema> = keyof S extends infer TableName ? TableName extends keyof S ? keyof S[TableName] extends infer ColumnName ? ColumnName extends keyof S[TableName] ? StandardSchemaV1.InferOutput<S[TableName][ColumnName]> extends SqliteValue ? never : SchemaValidationError<`Table "${TableName & string}" column "${ColumnName & string}" type is not compatible with SQLite. Column types must extend SqliteValue (string, number, Uint8Array, or null).`> : never : never : never : never;
|
|
209
245
|
/** Schema validation error that shows clear, readable messages */
|
|
210
|
-
export type SchemaValidationError<Message extends string> =
|
|
246
|
+
export type SchemaValidationError<Message extends string> = CompileTimeError<"Schema", Message>;
|
|
211
247
|
/** Makes columns whose output type includes `null` optional. */
|
|
212
248
|
export type NullableColumnsToOptional<T extends TableSchema> = {
|
|
213
249
|
readonly [K in RequiredColumnKeys<T>]: StandardSchemaV1.InferOutput<T[K]>;
|
|
@@ -235,21 +271,36 @@ export declare const evoluSchemaToSqliteSchema: <S extends EvoluSchema>(schema:
|
|
|
235
271
|
* ### Example
|
|
236
272
|
*
|
|
237
273
|
* ```ts
|
|
274
|
+
* import {
|
|
275
|
+
* createQueryBuilder,
|
|
276
|
+
* id,
|
|
277
|
+
* NonEmptyTrimmedString100,
|
|
278
|
+
* nullOr,
|
|
279
|
+
* SqliteBoolean,
|
|
280
|
+
* } from "@evolu/common";
|
|
281
|
+
*
|
|
282
|
+
* const TodoId = id("Todo");
|
|
283
|
+
* type TodoId = typeof TodoId.Output;
|
|
238
284
|
* const Schema = {
|
|
239
285
|
* todo: {
|
|
240
|
-
* id:
|
|
241
|
-
* title:
|
|
286
|
+
* id: TodoId,
|
|
287
|
+
* title: NonEmptyTrimmedString100,
|
|
242
288
|
* isCompleted: nullOr(SqliteBoolean),
|
|
243
289
|
* },
|
|
244
290
|
* };
|
|
245
291
|
*
|
|
246
|
-
* // Create
|
|
292
|
+
* // Create one typed builder per schema and reuse it for every query.
|
|
247
293
|
* const createQuery = createQueryBuilder(Schema);
|
|
248
|
-
*
|
|
249
|
-
* // Use it for all queries
|
|
250
294
|
* const todosQuery = createQuery((db) =>
|
|
251
295
|
* db.selectFrom("todo").select(["id", "title", "isCompleted"]),
|
|
252
296
|
* );
|
|
297
|
+
*
|
|
298
|
+
* expectTypeOf<typeof todosQuery.Row>().toEqualTypeOf<{
|
|
299
|
+
* id: TodoId;
|
|
300
|
+
* title: NonEmptyTrimmedString100 | null;
|
|
301
|
+
* isCompleted: SqliteBoolean | null;
|
|
302
|
+
* }>();
|
|
303
|
+
* expect(todosQuery).toBeTypeOf("string");
|
|
253
304
|
* ```
|
|
254
305
|
*/
|
|
255
306
|
export declare const createQueryBuilder: <S extends EvoluSchema>(_schema: S) => CreateQuery<S>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Schema.d.ts","sourceRoot":"","sources":["../../../src/local-first/Schema.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAC;AACjC,OAAO,
|
|
1
|
+
{"version":3,"file":"Schema.d.ts","sourceRoot":"","sources":["../../../src/local-first/Schema.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAC;AACjC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAE9D,OAAO,EAAyB,KAAK,cAAc,EAAE,MAAM,cAAc,CAAC;AAC1E,OAAO,EAML,aAAa,EACb,KAAK,SAAS,EAGd,KAAK,kBAAkB,EACvB,KAAK,YAAY,EACjB,WAAW,EACZ,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,OAAO,EACP,KAAK,EAAE,EACP,OAAO,EACP,KAAK,SAAS,EACd,IAAI,EAGJ,KAAK,UAAU,EACf,KAAK,SAAS,EACf,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE9D,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AACrC,OAAO,KAAK,EAGV,KAAK,EACL,GAAG,EACJ,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAe,QAAQ,EAAE,MAAM,cAAc,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAEhD,0CAA0C;AAC1C,MAAM,MAAM,mBAAmB,GAAG,gBAAgB,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;AAE7D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AACH,MAAM,MAAM,WAAW,GAAG,cAAc,CACtC,MAAM,EAEN,WAAW,CACZ,CAAC;AAEF,yEAAyE;AACzE,MAAM,MAAM,WAAW,GAAG,cAAc,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC;AAEtE,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,YAAY,EAAE,YAAY,CAAC;CACrC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,cAAc,CAAC,CAAC,SAAS,WAAW,IAC9C,mBAAmB,CAAC,CAAC,CAAC,SAAS,KAAK,GAChC,oBAAoB,CAAC,CAAC,CAAC,SAAS,KAAK,GACnC,uBAAuB,CAAC,CAAC,CAAC,SAAS,KAAK,GACtC,mBAAmB,CAAC,CAAC,CAAC,SAAS,KAAK,GAClC,CAAC,GACD,mBAAmB,CAAC,CAAC,CAAC,GACxB,uBAAuB,CAAC,CAAC,CAAC,GAC5B,oBAAoB,CAAC,CAAC,CAAC,GACzB,mBAAmB,CAAC,CAAC,CAAC,CAAC;AAE7B,MAAM,MAAM,aAAa,GAAG,CAC1B,MAAM,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,MAAM,CAAC,kBAAkB,KACrD,aAAa,CAAC,MAAM,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC,CAAC;AAEnD,MAAM,MAAM,WAAW,CAAC,CAAC,SAAS,WAAW,IAAI,CAAC,CAAC,SAAS,GAAG,EAC7D,aAAa,EAAE,CACb,EAAE,EAAE,IAAI,CACN,MAAM,CAAC,MAAM,CACX;KACG,KAAK,IAAI,MAAM,CAAC,GAAG;QAClB,QAAQ,EAAE,MAAM,IAAI,MAAM,CAAC,CAAC,KAAK,CAAC,GAAG,MAAM,SAAS,IAAI,GACpD,gBAAgB,CAAC,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,GAC9C,gBAAgB,CAAC,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,IAAI;KAC1D,GAAG,aAAa;CAClB,GAAG;IACF,QAAQ,CAAC,aAAa,EAAE;QACtB,QAAQ,CAAC,SAAS,EAAE,cAAc,CAAC;QACnC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QACxB,QAAQ,CAAC,EAAE,EAAE,OAAO,CAAC;QACrB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QACxB,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC;KAC7B,CAAC;IACF,QAAQ,CAAC,wBAAwB,EAAE;QACjC,QAAQ,CAAC,SAAS,EAAE,cAAc,CAAC;QACnC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QACvB,QAAQ,CAAC,EAAE,EAAE,OAAO,CAAC;QACrB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QACxB,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC;KAC7B,CAAC;CACH,CACF,EACD,YAAY,GAAG,IAAI,GAAG,MAAM,GAAG,eAAe,CAC/C,KACE,MAAM,CAAC,kBAAkB,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,EAC3C,OAAO,CAAC,EAAE,kBAAkB,KACzB,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;AAElC;;;;;;;;GAQG;AACH,eAAO,MAAM,aAAa,EAAE,UAAU,CAAC;IACrC,QAAQ,CAAC,SAAS,EAAE,OAAO,OAAO,CAAC;IACnC,QAAQ,CAAC,SAAS,EAAE,OAAO,OAAO,CAAC;IACnC,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC,SAAS,CAAC,OAAO,aAAa,EAAE,OAAO,IAAI,CAAC,CAAC,CAAC;IAC5E,QAAQ,CAAC,OAAO,EAAE,OAAO,OAAO,CAAC;CAClC,CAKC,CAAC;AACH,MAAM,WAAW,aAAc,SAAQ,SAAS,CAAC,OAAO,aAAa,CAAC;CAAG;AAEzE,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAE1D;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,MAAM,QAAQ,CAAC,CAAC,SAAS,WAAW,EAAE,IAAI,SAAS,YAAY,IAAI,CACvE,SAAS,SAAS,MAAM,CAAC,EAEzB,KAAK,EAAE,SAAS,EAChB,MAAM,EAAE,cAAc,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,IAAI,CAAC,EAC1C,OAAO,CAAC,EAAE,eAAe,KACtB;IAAE,QAAQ,CAAC,EAAE,EAAE,gBAAgB,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,CAAC,CAAA;CAAE,CAAC;AAEvE,MAAM,WAAW,eAAe;IAC9B;;;;OAIG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;IAEjC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAwDG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED,MAAM,WAAW,cAAe,SAAQ,QAAQ;IAC9C,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;CAC3B;AAED;;;GAGG;AACH,MAAM,MAAM,cAAc,CACxB,CAAC,SAAS,WAAW,EACrB,CAAC,SAAS,YAAY,IACpB,QAAQ,CACV,CAAC,SAAS,QAAQ,GACd,YAAY,CAAC,CAAC,CAAC,GACf,CAAC,SAAS,QAAQ,GAChB,YAAY,CAAC,CAAC,CAAC,GACf,YAAY,CAAC,CAAC,CAAC,CACtB,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,YAAY,CAAC,CAAC,SAAS,WAAW,IAAI,IAAI,CACpD,yBAAyB,CAAC,CAAC,CAAC,EAC5B,IAAI,CACL,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,YAAY,CAAC,CAAC,SAAS,WAAW,IAAI;IAChD,QAAQ,CAAC,EAAE,EAAE,gBAAgB,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;CACpD,GAAG;IACF,QAAQ,EAAE,CAAC,IAAI,OAAO,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,gBAAgB,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CAC5E,GAAG;IACF,QAAQ,CAAC,SAAS,CAAC,EAAE,aAAa,CAAC;CACpC,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,YAAY,CAAC,CAAC,SAAS,WAAW,IAC5C,yBAAyB,CAAC,CAAC,CAAC,GAAG;IAC7B,QAAQ,CAAC,SAAS,CAAC,EAAE,aAAa,CAAC;CACpC,CAAC;AAEJ,MAAM,MAAM,mBAAmB,CAAC,CAAC,SAAS,WAAW,IACnD,MAAM,CAAC,SAAS,MAAM,SAAS,GAC3B,SAAS,SAAS,MAAM,CAAC,GACvB,IAAI,SAAS,MAAM,CAAC,CAAC,SAAS,CAAC,GAC7B,KAAK,GACL,qBAAqB,CAAC,UAAU,SAAS,GAAG,MAAM,kCAAkC,CAAC,GACvF,KAAK,GACP,KAAK,CAAC;AAEZ,MAAM,MAAM,oBAAoB,CAAC,CAAC,SAAS,WAAW,IACpD,MAAM,CAAC,SAAS,MAAM,SAAS,GAC3B,SAAS,SAAS,MAAM,CAAC,GACvB,IAAI,SAAS,MAAM,CAAC,CAAC,SAAS,CAAC,GAC7B,gBAAgB,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,GACzD,KAAK,GACL,qBAAqB,CAAC,UAAU,SAAS,GAAG,MAAM,mDAAmD,SAAS,GAAG,MAAM,qBAAqB,CAAC,GAC/I,KAAK,GACP,KAAK,GACP,KAAK,CAAC;AAEZ,MAAM,MAAM,uBAAuB,CAAC,CAAC,SAAS,WAAW,IACvD,MAAM,CAAC,SAAS,MAAM,SAAS,GAC3B,SAAS,SAAS,MAAM,CAAC,GACvB,MAAM,CAAC,CAAC,SAAS,CAAC,SAAS,MAAM,UAAU,GACzC,UAAU,SAAS,MAAM,CAAC,CAAC,SAAS,CAAC,GACnC,UAAU,SACR,WAAW,GAAG,WAAW,GAAG,WAAW,GAAG,SAAS,GACnD,qBAAqB,CAAC,UAAU,SAAS,GAAG,MAAM,8BAA8B,UAAU,GAAG,MAAM,uFAAuF,CAAC,GAC3L,KAAK,GACP,KAAK,GACP,KAAK,GACP,KAAK,GACP,KAAK,CAAC;AAEZ,MAAM,MAAM,mBAAmB,CAAC,CAAC,SAAS,WAAW,IACnD,MAAM,CAAC,SAAS,MAAM,SAAS,GAC3B,SAAS,SAAS,MAAM,CAAC,GACvB,MAAM,CAAC,CAAC,SAAS,CAAC,SAAS,MAAM,UAAU,GACzC,UAAU,SAAS,MAAM,CAAC,CAAC,SAAS,CAAC,GACnC,gBAAgB,CAAC,WAAW,CAC1B,CAAC,CAAC,SAAS,CAAC,CAAC,UAAU,CAAC,CACzB,SAAS,WAAW,GACnB,KAAK,GACL,qBAAqB,CAAC,UAAU,SAAS,GAAG,MAAM,aAAa,UAAU,GAAG,MAAM,mHAAmH,CAAC,GACxM,KAAK,GACP,KAAK,GACP,KAAK,GACP,KAAK,CAAC;AAEZ,kEAAkE;AAClE,MAAM,MAAM,qBAAqB,CAAC,OAAO,SAAS,MAAM,IAAI,gBAAgB,CAC1E,QAAQ,EACR,OAAO,CACR,CAAC;AAEF,gEAAgE;AAChE,MAAM,MAAM,yBAAyB,CAAC,CAAC,SAAS,WAAW,IAAI;IAC7D,QAAQ,EAAE,CAAC,IAAI,kBAAkB,CAAC,CAAC,CAAC,GAAG,gBAAgB,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CAC1E,GAAG;IACF,QAAQ,EAAE,CAAC,IAAI,kBAAkB,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,gBAAgB,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CAC3E,CAAC;AAEF,MAAM,MAAM,kBAAkB,CAAC,CAAC,SAAS,WAAW,IAAI;KACrD,CAAC,IAAI,MAAM,CAAC,GAAG,IAAI,SAAS,gBAAgB,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC;CAC5E,CAAC,MAAM,CAAC,CAAC,CAAC;AAEX,MAAM,MAAM,kBAAkB,CAAC,CAAC,SAAS,WAAW,IAAI;KACrD,CAAC,IAAI,MAAM,CAAC,GAAG,IAAI,SAAS,gBAAgB,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK;CAC5E,CAAC,MAAM,CAAC,CAAC,CAAC;AAEX,eAAO,MAAM,aAAa,EAAE,WAAW,CAAC,MAAM,CAE7C,CAAC;AAEF,eAAO,MAAM,mBAAmB,EAAE,aAAa,CAAC,MAAM,CAGrD,CAAC;AAEF,eAAO,MAAM,yBAAyB,GAAI,CAAC,SAAS,WAAW,UACrD,cAAc,CAAC,CAAC,CAAC,SAAS,KAAK,GAAG,CAAC,GAAG,cAAc,CAAC,CAAC,CAAC,kBAC/C,aAAa,KAC5B,YAgBF,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AACH,eAAO,MAAM,kBAAkB,GAAI,CAAC,SAAS,WAAW,WAC7C,CAAC,KACT,WAAW,CAAC,CAAC,CAef,CAAC;AAEF,eAAO,MAAM,kBAAkB,SACtB,SAAS,iBACJ,YAAY,kBAAkB,YAAY,KAAG,IA+CxD,CAAC;AAEJ,eAAO,MAAM,oBAAoB,SAAU,SAAS,WAAS,YACA,CAAC;AAG9D,eAAO,MAAM,MAAM,wBASjB,CAAC"}
|
|
@@ -4,9 +4,10 @@
|
|
|
4
4
|
* @module
|
|
5
5
|
*/
|
|
6
6
|
import * as Kysely from "kysely";
|
|
7
|
-
import {
|
|
7
|
+
import { assertNonNullable } from "../Assert.js";
|
|
8
|
+
import { getOwnProp, mapObject } from "../Object.js";
|
|
8
9
|
import { eqSqliteIndex, getSqliteSchema, sql, sqliteQueryToSqliteQueryString, SqliteBoolean, SqliteValue, } from "../Sqlite.js";
|
|
9
|
-
import { DateIso, IdBytes, nullOr, object, } from "../Type.js";
|
|
10
|
+
import { DateIso, IdBytes, Null, nullOr, object, } from "../Type.js";
|
|
10
11
|
import { OwnerId } from "./Owner.js";
|
|
11
12
|
import { TimestampBytes } from "./Timestamp.js";
|
|
12
13
|
/**
|
|
@@ -53,21 +54,36 @@ export const evoluSchemaToSqliteSchema = (schema, indexesConfig) => {
|
|
|
53
54
|
* ### Example
|
|
54
55
|
*
|
|
55
56
|
* ```ts
|
|
57
|
+
* import {
|
|
58
|
+
* createQueryBuilder,
|
|
59
|
+
* id,
|
|
60
|
+
* NonEmptyTrimmedString100,
|
|
61
|
+
* nullOr,
|
|
62
|
+
* SqliteBoolean,
|
|
63
|
+
* } from "@evolu/common";
|
|
64
|
+
*
|
|
65
|
+
* const TodoId = id("Todo");
|
|
66
|
+
* type TodoId = typeof TodoId.Output;
|
|
56
67
|
* const Schema = {
|
|
57
68
|
* todo: {
|
|
58
|
-
* id:
|
|
59
|
-
* title:
|
|
69
|
+
* id: TodoId,
|
|
70
|
+
* title: NonEmptyTrimmedString100,
|
|
60
71
|
* isCompleted: nullOr(SqliteBoolean),
|
|
61
72
|
* },
|
|
62
73
|
* };
|
|
63
74
|
*
|
|
64
|
-
* // Create
|
|
75
|
+
* // Create one typed builder per schema and reuse it for every query.
|
|
65
76
|
* const createQuery = createQueryBuilder(Schema);
|
|
66
|
-
*
|
|
67
|
-
* // Use it for all queries
|
|
68
77
|
* const todosQuery = createQuery((db) =>
|
|
69
78
|
* db.selectFrom("todo").select(["id", "title", "isCompleted"]),
|
|
70
79
|
* );
|
|
80
|
+
*
|
|
81
|
+
* expectTypeOf<typeof todosQuery.Row>().toEqualTypeOf<{
|
|
82
|
+
* id: TodoId;
|
|
83
|
+
* title: NonEmptyTrimmedString100 | null;
|
|
84
|
+
* isCompleted: SqliteBoolean | null;
|
|
85
|
+
* }>();
|
|
86
|
+
* expect(todosQuery).toBeTypeOf("string");
|
|
71
87
|
* ```
|
|
72
88
|
*/
|
|
73
89
|
export const createQueryBuilder = (_schema) => {
|
|
@@ -86,7 +102,8 @@ export const ensureSqliteSchema = (deps) => (newSchema, currentSchema) => {
|
|
|
86
102
|
const queries = [];
|
|
87
103
|
currentSchema ??= getEvoluSqliteSchema(deps)();
|
|
88
104
|
for (const [tableName, newColumns] of Object.entries(newSchema.tables)) {
|
|
89
|
-
|
|
105
|
+
assertNonNullable(newColumns);
|
|
106
|
+
const currentColumns = getOwnProp(currentSchema.tables, tableName);
|
|
90
107
|
if (!currentColumns) {
|
|
91
108
|
queries.push(createAppTable(tableName, newColumns));
|
|
92
109
|
}
|