@evolu/common 4.1.1 → 5.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 +1 -1
- package/dist/src/Config.d.ts +27 -30
- package/dist/src/Config.d.ts.map +1 -1
- package/dist/src/Config.js +32 -5
- package/dist/src/Crdt.d.ts +5 -4
- package/dist/src/Crdt.d.ts.map +1 -1
- package/dist/src/Crdt.js +27 -24
- package/dist/src/Crypto.d.ts +16 -10
- package/dist/src/Crypto.d.ts.map +1 -1
- package/dist/src/Crypto.js +24 -11
- package/dist/src/Db.d.ts +58 -78
- package/dist/src/Db.d.ts.map +1 -1
- package/dist/src/Db.js +368 -170
- package/dist/src/Diff.d.ts +9 -3
- package/dist/src/Diff.d.ts.map +1 -1
- package/dist/src/Diff.js +12 -11
- package/dist/src/Error.d.ts +15 -0
- package/dist/src/Error.d.ts.map +1 -0
- package/dist/src/Error.js +14 -0
- package/dist/src/Evolu.d.ts +139 -91
- package/dist/src/Evolu.d.ts.map +1 -1
- package/dist/src/Evolu.js +267 -239
- package/dist/src/Model.d.ts +52 -0
- package/dist/src/Model.d.ts.map +1 -1
- package/dist/src/Model.js +47 -5
- package/dist/src/Owner.d.ts.map +1 -1
- package/dist/src/Owner.js +14 -8
- package/dist/src/Platform.d.ts +24 -34
- package/dist/src/Platform.d.ts.map +1 -1
- package/dist/src/Platform.js +9 -31
- package/dist/src/Public.d.ts +3 -5
- package/dist/src/Public.d.ts.map +1 -1
- package/dist/src/Public.js +2 -3
- package/dist/src/Sqlite.d.ts +25 -16
- package/dist/src/Sqlite.d.ts.map +1 -1
- package/dist/src/Sqlite.js +28 -20
- package/dist/src/Store.d.ts.map +1 -1
- package/dist/src/Sync.d.ts +70 -0
- package/dist/src/Sync.d.ts.map +1 -0
- package/dist/src/Sync.js +126 -0
- package/dist/src/index.d.ts +2 -5
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +2 -5
- package/package.json +12 -10
- package/src/Config.ts +77 -36
- package/src/Crdt.ts +61 -76
- package/src/Crypto.ts +83 -60
- package/src/Db.ts +782 -352
- package/src/Diff.ts +23 -21
- package/src/Error.ts +29 -0
- package/src/Evolu.ts +599 -499
- package/src/Model.ts +102 -6
- package/src/Owner.ts +24 -24
- package/src/Platform.ts +33 -81
- package/src/Public.ts +3 -5
- package/src/Sqlite.ts +81 -44
- package/src/Sync.ts +306 -0
- package/src/index.ts +2 -5
- package/dist/src/DbWorker.d.ts +0 -82
- package/dist/src/DbWorker.d.ts.map +0 -1
- package/dist/src/DbWorker.js +0 -335
- package/dist/src/ErrorStore.d.ts +0 -29
- package/dist/src/ErrorStore.d.ts.map +0 -1
- package/dist/src/ErrorStore.js +0 -13
- package/dist/src/OnCompletes.d.ts +0 -14
- package/dist/src/OnCompletes.d.ts.map +0 -1
- package/dist/src/OnCompletes.js +0 -25
- package/dist/src/SyncWorker.d.ts +0 -80
- package/dist/src/SyncWorker.d.ts.map +0 -1
- package/dist/src/SyncWorker.js +0 -150
- package/dist/src/Types.d.ts +0 -13
- package/dist/src/Types.d.ts.map +0 -1
- package/dist/src/Types.js +0 -1
- package/src/DbWorker.ts +0 -721
- package/src/ErrorStore.ts +0 -46
- package/src/OnCompletes.ts +0 -51
- package/src/SyncWorker.ts +0 -361
- package/src/Types.ts +0 -11
package/dist/src/Diff.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { Query, Row } from "./Db.js";
|
|
1
|
+
import type { Query, Row } from "./Db.js";
|
|
3
2
|
import { Value } from "./Sqlite.js";
|
|
4
3
|
export interface QueryPatches {
|
|
5
4
|
readonly query: Query;
|
|
@@ -15,7 +14,14 @@ export interface ReplaceAtPatch {
|
|
|
15
14
|
readonly index: number;
|
|
16
15
|
readonly value: Row;
|
|
17
16
|
}
|
|
18
|
-
export declare const applyPatches: (patches: ReadonlyArray<Patch
|
|
17
|
+
export declare const applyPatches: (patches: ReadonlyArray<Patch>, current: ReadonlyArray<Row>) => ReadonlyArray<Row>;
|
|
18
|
+
/**
|
|
19
|
+
* We detect only changes in the whole result and in-place edits. In the future,
|
|
20
|
+
* we will add more heuristics. We will probably not implement the Myers diff
|
|
21
|
+
* algorithm because it's faster to rerender all than to compute many detailed
|
|
22
|
+
* patches. We will only implement logic a developer would implement manually,
|
|
23
|
+
* if necessary.
|
|
24
|
+
*/
|
|
19
25
|
export declare const makePatches: (previousRows: ReadonlyArray<Row> | undefined, nextRows: ReadonlyArray<Row>) => readonly Patch[];
|
|
20
26
|
export declare const areEqual: (a: Value | Row | ReadonlyArray<Row>, b: Value | Row | ReadonlyArray<Row>) => boolean;
|
|
21
27
|
//# sourceMappingURL=Diff.d.ts.map
|
package/dist/src/Diff.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Diff.d.ts","sourceRoot":"","sources":["../../src/Diff.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Diff.d.ts","sourceRoot":"","sources":["../../src/Diff.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAEpC,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC,KAAK,CAAC,CAAC;CACxC;AAED,MAAM,MAAM,KAAK,GAAG,eAAe,GAAG,cAAc,CAAC;AAErD,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,EAAE,EAAE,YAAY,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC,GAAG,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,EAAE,EAAE,WAAW,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,GAAG,CAAC;CACrB;AAED,eAAO,MAAM,YAAY,YACd,cAAc,KAAK,CAAC,WACpB,cAAc,GAAG,CAAC,KAC1B,cAAc,GAAG,CASP,CAAC;AAEd;;;;;;GAMG;AACH,eAAO,MAAM,WAAW,iBACR,cAAc,GAAG,CAAC,GAAG,SAAS,YAClC,cAAc,GAAG,CAAC,KAC3B,SAAS,KAAK,EA2BhB,CAAC;AAEF,eAAO,MAAM,QAAQ,MAChB,KAAK,GAAG,GAAG,GAAG,cAAc,GAAG,CAAC,KAChC,KAAK,GAAG,GAAG,GAAG,cAAc,GAAG,CAAC,KAClC,OAkCF,CAAC"}
|
package/dist/src/Diff.js
CHANGED
|
@@ -1,20 +1,21 @@
|
|
|
1
|
+
import * as Arr from "effect/Array";
|
|
1
2
|
import * as Predicate from "effect/Predicate";
|
|
2
|
-
|
|
3
|
-
export const applyPatches = (patches) => (current) => patches.reduce((next, patch) => {
|
|
3
|
+
export const applyPatches = (patches, current) => patches.reduce((next, patch) => {
|
|
4
4
|
switch (patch.op) {
|
|
5
5
|
case "replaceAll":
|
|
6
6
|
return patch.value;
|
|
7
7
|
case "replaceAt": {
|
|
8
|
-
return
|
|
8
|
+
return Arr.replace(next, patch.index, patch.value);
|
|
9
9
|
}
|
|
10
10
|
}
|
|
11
11
|
}, current);
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
12
|
+
/**
|
|
13
|
+
* We detect only changes in the whole result and in-place edits. In the future,
|
|
14
|
+
* we will add more heuristics. We will probably not implement the Myers diff
|
|
15
|
+
* algorithm because it's faster to rerender all than to compute many detailed
|
|
16
|
+
* patches. We will only implement logic a developer would implement manually,
|
|
17
|
+
* if necessary.
|
|
18
|
+
*/
|
|
18
19
|
export const makePatches = (previousRows, nextRows) => {
|
|
19
20
|
if (previousRows === undefined)
|
|
20
21
|
return [{ op: "replaceAll", value: nextRows }];
|
|
@@ -58,8 +59,8 @@ export const areEqual = (a, b) => {
|
|
|
58
59
|
return false;
|
|
59
60
|
return true;
|
|
60
61
|
}
|
|
61
|
-
const aIsArray =
|
|
62
|
-
const bIsArray =
|
|
62
|
+
const aIsArray = Arr.isArray(a);
|
|
63
|
+
const bIsArray = Arr.isArray(b);
|
|
63
64
|
if (aIsArray && bIsArray) {
|
|
64
65
|
if (a.length !== b.length)
|
|
65
66
|
return false;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { TimestampError } from "./Crdt.js";
|
|
2
|
+
/** The EvoluError type is used to represent errors that can occur in Evolu. */
|
|
3
|
+
export type EvoluError = TimestampError | UnexpectedError;
|
|
4
|
+
/**
|
|
5
|
+
* UnexpectedError represents errors that can occur unexpectedly anywhere, even
|
|
6
|
+
* in third-party libraries, because Evolu uses Effect to track all errors.
|
|
7
|
+
*/
|
|
8
|
+
export interface UnexpectedError {
|
|
9
|
+
readonly _tag: "UnexpectedError";
|
|
10
|
+
readonly error: unknown;
|
|
11
|
+
}
|
|
12
|
+
export declare const makeUnexpectedError: (error: unknown) => UnexpectedError;
|
|
13
|
+
/** Error isn't a structured cloneable object. */
|
|
14
|
+
export declare const ensureTransferableError: (error: unknown) => unknown;
|
|
15
|
+
//# sourceMappingURL=Error.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Error.d.ts","sourceRoot":"","sources":["../../src/Error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAE3C,+EAA+E;AAC/E,MAAM,MAAM,UAAU,GAAG,cAAc,GAAG,eAAe,CAAC;AAE1D;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,EAAE,iBAAiB,CAAC;IACjC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;CACzB;AAED,eAAO,MAAM,mBAAmB,UAAW,OAAO,KAAG,eAGnD,CAAC;AAEH,iDAAiD;AACjD,eAAO,MAAM,uBAAuB,UAAW,OAAO,KAAG,OAQxD,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export const makeUnexpectedError = (error) => ({
|
|
2
|
+
_tag: "UnexpectedError",
|
|
3
|
+
error,
|
|
4
|
+
});
|
|
5
|
+
/** Error isn't a structured cloneable object. */
|
|
6
|
+
export const ensureTransferableError = (error) => {
|
|
7
|
+
if (error instanceof Error)
|
|
8
|
+
return {
|
|
9
|
+
message: error.message,
|
|
10
|
+
name: error.name,
|
|
11
|
+
stack: error.stack,
|
|
12
|
+
};
|
|
13
|
+
return error;
|
|
14
|
+
};
|
package/dist/src/Evolu.d.ts
CHANGED
|
@@ -1,19 +1,40 @@
|
|
|
1
1
|
import * as S from "@effect/schema/Schema";
|
|
2
2
|
import * as Context from "effect/Context";
|
|
3
|
+
import * as Effect from "effect/Effect";
|
|
3
4
|
import * as Layer from "effect/Layer";
|
|
5
|
+
import * as Record from "effect/Record";
|
|
4
6
|
import * as Kysely from "kysely";
|
|
5
7
|
import { Config } from "./Config.js";
|
|
6
|
-
import { Mnemonic } from "./Crypto.js";
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import { SqliteBoolean, SqliteDate } from "./Model.js";
|
|
8
|
+
import { Mnemonic, NanoIdGenerator } from "./Crypto.js";
|
|
9
|
+
import { DbFactory, DbSchema, Index, Queries, Query, QueryResult, QueryResultsPromisesFromQueries, Row } from "./Db.js";
|
|
10
|
+
import { EvoluError } from "./Error.js";
|
|
11
|
+
import { Id, SqliteBoolean, SqliteDate } from "./Model.js";
|
|
11
12
|
import { Owner } from "./Owner.js";
|
|
12
|
-
import { AppState
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import { SyncState } from "./
|
|
16
|
-
|
|
13
|
+
import { AppState } from "./Platform.js";
|
|
14
|
+
import { SqliteQueryOptions, Value } from "./Sqlite.js";
|
|
15
|
+
import { Listener, Unsubscribe } from "./Store.js";
|
|
16
|
+
import { SyncState } from "./Sync.js";
|
|
17
|
+
/**
|
|
18
|
+
* The Evolu interface provides a type-safe SQL query building and state
|
|
19
|
+
* management defined by a database schema. It leverages Kysely for creating SQL
|
|
20
|
+
* queries in TypeScript, enabling operations such as data querying, loading,
|
|
21
|
+
* subscription to data changes, and mutations (create, update, createOrUpdate).
|
|
22
|
+
* It also includes functionalities for error handling, syncing state
|
|
23
|
+
* management, and owner data manipulation. Specifically, Evolu allows:
|
|
24
|
+
*
|
|
25
|
+
* - Subscribing to and getting errors via subscribeError and getError.
|
|
26
|
+
* - Creating type-safe SQL queries with createQuery, leveraging Kysely's
|
|
27
|
+
* capabilities.
|
|
28
|
+
* - Loading queries and subscribing to query result changes using loadQuery,
|
|
29
|
+
* loadQueries, subscribeQuery, and getQuery.
|
|
30
|
+
* - Subscribing to and getting the owner's information and sync state changes.
|
|
31
|
+
* - Performing mutations on the database with create, update, and createOrUpdate
|
|
32
|
+
* methods, which include automatic management of common columns like
|
|
33
|
+
* createdAt, updatedAt, and isDeleted.
|
|
34
|
+
* - Managing owner data with resetOwner and restoreOwner.
|
|
35
|
+
* - Ensuring the database schema's integrity with ensureSchema.
|
|
36
|
+
*/
|
|
37
|
+
export interface Evolu<T extends EvoluSchema = EvoluSchema> {
|
|
17
38
|
/**
|
|
18
39
|
* Subscribe to {@link EvoluError} changes.
|
|
19
40
|
*
|
|
@@ -23,9 +44,9 @@ export interface Evolu<S extends DatabaseSchema = DatabaseSchema> {
|
|
|
23
44
|
* console.log(error);
|
|
24
45
|
* });
|
|
25
46
|
*/
|
|
26
|
-
readonly subscribeError:
|
|
47
|
+
readonly subscribeError: (listener: Listener) => Unsubscribe;
|
|
27
48
|
/** Get {@link EvoluError}. */
|
|
28
|
-
readonly getError:
|
|
49
|
+
readonly getError: () => EvoluError | null;
|
|
29
50
|
/**
|
|
30
51
|
* Create type-safe SQL {@link Query}.
|
|
31
52
|
*
|
|
@@ -44,7 +65,11 @@ export interface Evolu<S extends DatabaseSchema = DatabaseSchema> {
|
|
|
44
65
|
* db.selectFrom("todo").selectAll().where("id", "=", id),
|
|
45
66
|
* );
|
|
46
67
|
*/
|
|
47
|
-
readonly createQuery:
|
|
68
|
+
readonly createQuery: <R extends Row>(queryCallback: (db: Pick<Kysely.Kysely<{
|
|
69
|
+
[Table in keyof T]: NullableExceptIdCreatedAtUpdatedAt<{
|
|
70
|
+
[Column in keyof T[Table]]: T[Table][Column];
|
|
71
|
+
}>;
|
|
72
|
+
}>, "selectFrom" | "fn" | "with" | "withRecursive">) => Kysely.SelectQueryBuilder<any, any, R>, options?: SqliteQueryOptions) => Query<R>;
|
|
48
73
|
/**
|
|
49
74
|
* Load {@link Query} and return a promise with {@link QueryResult}.
|
|
50
75
|
*
|
|
@@ -94,7 +119,7 @@ export interface Evolu<S extends DatabaseSchema = DatabaseSchema> {
|
|
|
94
119
|
* console.log(rows);
|
|
95
120
|
* });
|
|
96
121
|
*/
|
|
97
|
-
readonly loadQuery:
|
|
122
|
+
readonly loadQuery: <R extends Row>(query: Query<R>) => Promise<QueryResult<R>>;
|
|
98
123
|
/**
|
|
99
124
|
* Load an array of {@link Query} queries and return an array of
|
|
100
125
|
* {@link QueryResult} promises. It's like `queries.map(loadQuery)` but with
|
|
@@ -112,7 +137,7 @@ export interface Evolu<S extends DatabaseSchema = DatabaseSchema> {
|
|
|
112
137
|
* const { rows } = evolu.getQuery(allTodos);
|
|
113
138
|
* });
|
|
114
139
|
*/
|
|
115
|
-
readonly subscribeQuery:
|
|
140
|
+
readonly subscribeQuery: (query: Query) => (listener: Listener) => Unsubscribe;
|
|
116
141
|
/**
|
|
117
142
|
* Get {@link Query} {@link QueryResult}.
|
|
118
143
|
*
|
|
@@ -121,7 +146,7 @@ export interface Evolu<S extends DatabaseSchema = DatabaseSchema> {
|
|
|
121
146
|
* const { rows } = evolu.getQuery(allTodos);
|
|
122
147
|
* });
|
|
123
148
|
*/
|
|
124
|
-
readonly getQuery:
|
|
149
|
+
readonly getQuery: <R extends Row>(query: Query<R>) => QueryResult<R>;
|
|
125
150
|
/**
|
|
126
151
|
* Subscribe to {@link Owner} changes.
|
|
127
152
|
*
|
|
@@ -130,7 +155,7 @@ export interface Evolu<S extends DatabaseSchema = DatabaseSchema> {
|
|
|
130
155
|
* const owner = evolu.getOwner();
|
|
131
156
|
* });
|
|
132
157
|
*/
|
|
133
|
-
readonly subscribeOwner:
|
|
158
|
+
readonly subscribeOwner: (listener: Listener) => Unsubscribe;
|
|
134
159
|
/**
|
|
135
160
|
* Get {@link Owner}.
|
|
136
161
|
*
|
|
@@ -139,7 +164,7 @@ export interface Evolu<S extends DatabaseSchema = DatabaseSchema> {
|
|
|
139
164
|
* const owner = evolu.getOwner();
|
|
140
165
|
* });
|
|
141
166
|
*/
|
|
142
|
-
readonly getOwner:
|
|
167
|
+
readonly getOwner: () => Owner | null;
|
|
143
168
|
/**
|
|
144
169
|
* Subscribe to {@link SyncState} changes.
|
|
145
170
|
*
|
|
@@ -148,7 +173,7 @@ export interface Evolu<S extends DatabaseSchema = DatabaseSchema> {
|
|
|
148
173
|
* const syncState = evolu.getSyncState();
|
|
149
174
|
* });
|
|
150
175
|
*/
|
|
151
|
-
readonly subscribeSyncState:
|
|
176
|
+
readonly subscribeSyncState: (listener: Listener) => Unsubscribe;
|
|
152
177
|
/**
|
|
153
178
|
* Get {@link SyncState}.
|
|
154
179
|
*
|
|
@@ -157,7 +182,7 @@ export interface Evolu<S extends DatabaseSchema = DatabaseSchema> {
|
|
|
157
182
|
* const syncState = evolu.getSyncState();
|
|
158
183
|
* });
|
|
159
184
|
*/
|
|
160
|
-
readonly getSyncState:
|
|
185
|
+
readonly getSyncState: () => SyncState;
|
|
161
186
|
/**
|
|
162
187
|
* Create a row in the database and returns a new ID. The first argument is
|
|
163
188
|
* the table name, and the second is an object.
|
|
@@ -184,7 +209,7 @@ export interface Evolu<S extends DatabaseSchema = DatabaseSchema> {
|
|
|
184
209
|
* // onComplete callback
|
|
185
210
|
* });
|
|
186
211
|
*/
|
|
187
|
-
create:
|
|
212
|
+
create: Mutate<T, "create">;
|
|
188
213
|
/**
|
|
189
214
|
* Update a row in the database and return the existing ID. The first argument
|
|
190
215
|
* is the table name, and the second is an object.
|
|
@@ -211,7 +236,7 @@ export interface Evolu<S extends DatabaseSchema = DatabaseSchema> {
|
|
|
211
236
|
* // To delete a row, set `isDeleted` to true.
|
|
212
237
|
* evolu.update("todo", { id, isDeleted: true });
|
|
213
238
|
*/
|
|
214
|
-
update:
|
|
239
|
+
update: Mutate<T, "update">;
|
|
215
240
|
/**
|
|
216
241
|
* Create or update a row in the database and return the existing ID. The
|
|
217
242
|
* first argument is the table name, and the second is an object.
|
|
@@ -241,7 +266,7 @@ export interface Evolu<S extends DatabaseSchema = DatabaseSchema> {
|
|
|
241
266
|
*
|
|
242
267
|
* evolu.createOrUpdate("todo", { id, title });
|
|
243
268
|
*/
|
|
244
|
-
createOrUpdate:
|
|
269
|
+
createOrUpdate: Mutate<T, "createOrUpdate">;
|
|
245
270
|
/**
|
|
246
271
|
* Delete {@link Owner} and all their data from the current device. After the
|
|
247
272
|
* deletion, Evolu will purge the application state. For browsers, this will
|
|
@@ -251,69 +276,26 @@ export interface Evolu<S extends DatabaseSchema = DatabaseSchema> {
|
|
|
251
276
|
/** Restore {@link Owner} with all their synced data. */
|
|
252
277
|
readonly restoreOwner: (mnemonic: Mnemonic) => void;
|
|
253
278
|
/**
|
|
254
|
-
* Ensure tables and columns defined in {@link
|
|
279
|
+
* Ensure tables and columns defined in {@link EvoluSchema} exist in the
|
|
255
280
|
* database.
|
|
256
|
-
*/
|
|
257
|
-
readonly ensureSchema: <From, To extends S>(schema: S.Schema<To, From>, indexes?: ReadonlyArray<Index>) => void;
|
|
258
|
-
/**
|
|
259
|
-
* Force sync with Evolu Server.
|
|
260
281
|
*
|
|
261
|
-
*
|
|
262
|
-
* generally not required to sync manually, but if you need it, you can do
|
|
263
|
-
* it.
|
|
282
|
+
* This function is for hot/live reloading.
|
|
264
283
|
*/
|
|
265
|
-
readonly
|
|
284
|
+
readonly ensureSchema: (schema: DbSchema) => void;
|
|
266
285
|
}
|
|
267
|
-
|
|
268
|
-
type
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
readonly [Column in keyof S[Table]]: S[Table][Column];
|
|
273
|
-
}>;
|
|
274
|
-
};
|
|
275
|
-
type NullableExceptForIdAndAutomaticColumns<T> = {
|
|
286
|
+
/** A type to define tables, columns, and column types. */
|
|
287
|
+
export type EvoluSchema = Record.ReadonlyRecord<string, Record.ReadonlyRecord<string, Value> & {
|
|
288
|
+
readonly id: Id;
|
|
289
|
+
}>;
|
|
290
|
+
type NullableExceptIdCreatedAtUpdatedAt<T> = {
|
|
276
291
|
readonly [K in keyof T]: K extends "id" | "createdAt" | "updatedAt" ? T[K] : T[K] | null;
|
|
277
292
|
};
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
readonly
|
|
282
|
-
readonly promise: LoadingPromise<R>;
|
|
283
|
-
readonly isNew: boolean;
|
|
284
|
-
};
|
|
285
|
-
readonly resolve: <R extends Row>(query: Query<R>, rows: ReadonlyArray<R>) => void;
|
|
286
|
-
/**
|
|
287
|
-
* Release all unsubscribed queries on mutation because only subscribed
|
|
288
|
-
* queries are automatically updated.
|
|
289
|
-
*/
|
|
290
|
-
readonly release: () => void;
|
|
291
|
-
}
|
|
292
|
-
export declare const LoadingPromises: Context.Tag<LoadingPromises, LoadingPromises>;
|
|
293
|
-
export type LoadingPromise<R extends Row> = Promise<QueryResult<R>> & {
|
|
294
|
-
status?: "pending" | "fulfilled" | "rejected";
|
|
295
|
-
value?: QueryResult<R>;
|
|
296
|
-
reason?: unknown;
|
|
293
|
+
type Mutate<T extends EvoluSchema = EvoluSchema, Mode extends "create" | "update" | "createOrUpdate" = "update"> = <K extends keyof T>(table: K, values: Kysely.Simplify<Mode extends "create" ? PartialForNullable<Castable<Omit<T[K], "id" | "createdAt" | "updatedAt" | "isDeleted">>> : Mode extends "update" ? Partial<Castable<Omit<T[K], "id" | "createdAt" | "updatedAt">>> & {
|
|
294
|
+
readonly id: T[K]["id"];
|
|
295
|
+
} : PartialForNullable<Castable<Omit<T[K], "createdAt" | "updatedAt" | "isDeleted">>>>, onComplete?: MutateOnComplete) => {
|
|
296
|
+
readonly id: T[K]["id"];
|
|
297
297
|
};
|
|
298
|
-
|
|
299
|
-
type LoadQuery = <R extends Row>(query: Query<R>) => Promise<QueryResult<R>>;
|
|
300
|
-
declare const LoadQuery: Context.Tag<LoadQuery, LoadQuery>;
|
|
301
|
-
export interface SubscribedQueries {
|
|
302
|
-
readonly subscribeQuery: (query: Query) => Store<Row>["subscribe"];
|
|
303
|
-
readonly getQuery: <R extends Row>(query: Query<R>) => QueryResult<R>;
|
|
304
|
-
readonly getSubscribedQueries: () => Queries;
|
|
305
|
-
}
|
|
306
|
-
export declare const SubscribedQueries: Context.Tag<SubscribedQueries, SubscribedQueries>;
|
|
307
|
-
export declare const SubscribedQueriesLive: Layer.Layer<SubscribedQueries, never, RowsStore>;
|
|
308
|
-
export type Create<S extends DatabaseSchema = DatabaseSchema> = Mutate<S, "create">;
|
|
309
|
-
export type Update<S extends DatabaseSchema = DatabaseSchema> = Mutate<S, "update">;
|
|
310
|
-
export type CreateOrUpdate<S extends DatabaseSchema = DatabaseSchema> = Mutate<S, "createOrUpdate">;
|
|
311
|
-
export type Mutate<S extends DatabaseSchema = DatabaseSchema, Mode extends "create" | "update" | "createOrUpdate" = "update"> = <K extends keyof S>(table: K, values: Kysely.Simplify<Mode extends "create" ? PartialForNullable<Castable<Omit<S[K], "id" | "createdAt" | "updatedAt" | "isDeleted">>> : Mode extends "update" ? Partial<Castable<Omit<S[K], "id" | "createdAt" | "updatedAt">>> & {
|
|
312
|
-
readonly id: S[K]["id"];
|
|
313
|
-
} : PartialForNullable<Castable<Omit<S[K], "createdAt" | "updatedAt" | "isDeleted">>>>, onComplete?: () => void) => {
|
|
314
|
-
readonly id: S[K]["id"];
|
|
315
|
-
};
|
|
316
|
-
export declare const Mutate: Context.Tag<Mutate<DatabaseSchema, "update">, Mutate<DatabaseSchema, "update">>;
|
|
298
|
+
type MutateOnComplete = () => void;
|
|
317
299
|
type PartialForNullable<T, NK extends keyof T = {
|
|
318
300
|
[K in keyof T]: null extends T[K] ? K : never;
|
|
319
301
|
}[keyof T], NP = Pick<T, Exclude<keyof T, NK>> & Partial<Pick<T, NK>>> = {
|
|
@@ -322,24 +304,90 @@ type PartialForNullable<T, NK extends keyof T = {
|
|
|
322
304
|
/**
|
|
323
305
|
* SQLite doesn't support Date nor Boolean types, so Evolu emulates them with
|
|
324
306
|
* {@link SqliteBoolean} and {@link SqliteDate}.
|
|
325
|
-
*
|
|
326
|
-
* For {@link SqliteBoolean}, you can use JavaScript boolean. For
|
|
327
|
-
* {@link SqliteDate}, you can use JavaScript Date.
|
|
328
307
|
*/
|
|
329
308
|
type Castable<T> = {
|
|
330
309
|
readonly [K in keyof T]: T[K] extends SqliteBoolean ? boolean | SqliteBoolean : T[K] extends null | SqliteBoolean ? null | boolean | SqliteBoolean : T[K] extends SqliteDate ? Date | SqliteDate : T[K] extends null | SqliteDate ? null | Date | SqliteDate : T[K];
|
|
331
310
|
};
|
|
332
|
-
|
|
311
|
+
declare const EvoluFactory_base: Context.TagClass<EvoluFactory, "EvoluFactory", {
|
|
312
|
+
/**
|
|
313
|
+
* Create Evolu from the database schema.
|
|
314
|
+
*
|
|
315
|
+
* Tables with a name prefixed with `_` are local-only, which means they are
|
|
316
|
+
* never synced. It's useful for device-specific or temporal data.
|
|
317
|
+
*
|
|
318
|
+
* @example
|
|
319
|
+
* import * as S from "@effect/schema/Schema";
|
|
320
|
+
* import * as E from "@evolu/react";
|
|
321
|
+
* // The same API for different platforms
|
|
322
|
+
* // import * as E from "@evolu/react-native";
|
|
323
|
+
* // import * as E from "@evolu/common-web";
|
|
324
|
+
*
|
|
325
|
+
* const TodoId = E.id("Todo");
|
|
326
|
+
* type TodoId = S.Schema.Type<typeof TodoId>;
|
|
327
|
+
*
|
|
328
|
+
* const TodoTable = E.table({
|
|
329
|
+
* id: TodoId,
|
|
330
|
+
* title: E.NonEmptyString1000,
|
|
331
|
+
* });
|
|
332
|
+
* type TodoTable = S.Schema.Type<typeof TodoTable>;
|
|
333
|
+
*
|
|
334
|
+
* const Database = E.database({
|
|
335
|
+
* todo: TodoTable,
|
|
336
|
+
*
|
|
337
|
+
* // Prefix `_` makes the table local-only (it will not sync)
|
|
338
|
+
* _todo: TodoTable,
|
|
339
|
+
* });
|
|
340
|
+
* type Database = S.Schema.Type<typeof Database>;
|
|
341
|
+
*
|
|
342
|
+
* const evolu = E.createEvolu(Database);
|
|
343
|
+
*/
|
|
344
|
+
readonly createEvolu: <T extends EvoluSchema, I>(schema: S.Schema<T, I>, config?: Partial<EvoluConfig<T>>) => Evolu<T>;
|
|
345
|
+
}>;
|
|
346
|
+
export declare class EvoluFactory extends EvoluFactory_base {
|
|
347
|
+
static Common: Layer.Layer<EvoluFactory, never, NanoIdGenerator | AppState | DbFactory>;
|
|
348
|
+
}
|
|
349
|
+
export interface EvoluConfig<T extends EvoluSchema = EvoluSchema> extends Config {
|
|
350
|
+
/**
|
|
351
|
+
* Use the `indexes` property to define SQLite indexes.
|
|
352
|
+
*
|
|
353
|
+
* Table and column names are not typed because Kysely doesn't support it.
|
|
354
|
+
*
|
|
355
|
+
* https://medium.com/@JasonWyatt/squeezing-performance-from-sqlite-indexes-indexes-c4e175f3c346
|
|
356
|
+
*
|
|
357
|
+
* @example
|
|
358
|
+
* const indexes = [
|
|
359
|
+
* createIndex("indexTodoCreatedAt").on("todo").column("createdAt"),
|
|
360
|
+
*
|
|
361
|
+
* createIndex("indexTodoCategoryCreatedAt")
|
|
362
|
+
* .on("todoCategory")
|
|
363
|
+
* .column("createdAt"),
|
|
364
|
+
* ];
|
|
365
|
+
*/
|
|
366
|
+
indexes: ReadonlyArray<Index>;
|
|
367
|
+
/** Use this option to create initial data (fixtures). */
|
|
368
|
+
initialData: (evolu: EvoluForInitialData<T>) => void;
|
|
369
|
+
}
|
|
370
|
+
interface EvoluForInitialData<T extends EvoluSchema = EvoluSchema> {
|
|
371
|
+
create: Mutate<T, "create">;
|
|
372
|
+
createOrUpdate: Mutate<T, "createOrUpdate">;
|
|
373
|
+
}
|
|
374
|
+
declare const createIndex: (indexName: string) => Kysely.CreateIndexBuilder<never>;
|
|
375
|
+
type CreateIndex = typeof createIndex;
|
|
333
376
|
/**
|
|
334
|
-
*
|
|
377
|
+
* Create SQLite indexes.
|
|
378
|
+
*
|
|
379
|
+
* See https://www.evolu.dev/docs/indexes
|
|
335
380
|
*
|
|
336
|
-
*
|
|
337
|
-
*
|
|
338
|
-
*
|
|
339
|
-
*
|
|
340
|
-
*
|
|
341
|
-
*
|
|
381
|
+
* @example
|
|
382
|
+
* const indexes = createIndexes((create) => [
|
|
383
|
+
* create("indexTodoCreatedAt").on("todo").column("createdAt"),
|
|
384
|
+
* create("indexTodoCategoryCreatedAt")
|
|
385
|
+
* .on("todoCategory")
|
|
386
|
+
* .column("createdAt"),
|
|
387
|
+
* ]);
|
|
342
388
|
*/
|
|
343
|
-
export declare const
|
|
389
|
+
export declare const createIndexes: (callback: (create: CreateIndex) => ReadonlyArray<Kysely.CreateIndexBuilder<any>>) => ReadonlyArray<Index>;
|
|
390
|
+
/** Create a namespaced lock name. */
|
|
391
|
+
export declare const getLockName: (name: string) => Effect.Effect<string, never, Config>;
|
|
344
392
|
export {};
|
|
345
393
|
//# sourceMappingURL=Evolu.d.ts.map
|
package/dist/src/Evolu.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Evolu.d.ts","sourceRoot":"","sources":["../../src/Evolu.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Evolu.d.ts","sourceRoot":"","sources":["../../src/Evolu.ts"],"names":[],"mappings":"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"}
|