@evolu/common 4.0.4 → 4.1.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 +6 -0
- package/dist/src/Config.d.ts +18 -0
- package/dist/src/Config.d.ts.map +1 -1
- package/dist/src/Config.js +1 -0
- package/dist/src/Crdt.d.ts +4 -4
- package/dist/src/Crdt.d.ts.map +1 -1
- package/dist/src/Crypto.d.ts +2 -2
- package/dist/src/Crypto.d.ts.map +1 -1
- package/dist/src/Db.d.ts +19 -29
- package/dist/src/Db.d.ts.map +1 -1
- package/dist/src/Db.js +111 -34
- package/dist/src/DbWorker.d.ts +3 -4
- package/dist/src/DbWorker.d.ts.map +1 -1
- package/dist/src/DbWorker.js +42 -22
- package/dist/src/Evolu.d.ts +4 -2
- package/dist/src/Evolu.d.ts.map +1 -1
- package/dist/src/Evolu.js +18 -6
- package/dist/src/Model.d.ts +17 -21
- package/dist/src/Model.d.ts.map +1 -1
- package/dist/src/Model.js +2 -5
- package/dist/src/Public.d.ts +2 -0
- package/dist/src/Public.d.ts.map +1 -1
- package/dist/src/Public.js +2 -0
- package/dist/src/Sql.d.ts +11 -12
- package/dist/src/Sql.d.ts.map +1 -1
- package/dist/src/Sql.js +30 -106
- package/dist/src/Sqlite.d.ts +29 -3
- package/dist/src/Sqlite.d.ts.map +1 -1
- package/dist/src/Sqlite.js +25 -5
- package/package.json +13 -13
- package/src/Config.ts +20 -0
- package/src/Crdt.ts +2 -2
- package/src/Crypto.ts +1 -1
- package/src/Db.ts +160 -84
- package/src/DbWorker.ts +57 -38
- package/src/Evolu.ts +36 -9
- package/src/Model.ts +10 -14
- package/src/Public.ts +2 -0
- package/src/Sql.ts +41 -123
- package/src/Sqlite.ts +65 -7
package/README.md
CHANGED
package/dist/src/Config.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as Context from "effect/Context";
|
|
2
2
|
import * as Layer from "effect/Layer";
|
|
3
|
+
import { CreateIndexBuilder } from "kysely";
|
|
3
4
|
export interface Config {
|
|
4
5
|
/** Alternate URL to Evolu sync and backup server. */
|
|
5
6
|
readonly syncUrl: string;
|
|
@@ -19,6 +20,23 @@ export interface Config {
|
|
|
19
20
|
* default value is: "Evolu".
|
|
20
21
|
*/
|
|
21
22
|
readonly name: string;
|
|
23
|
+
/**
|
|
24
|
+
* Use the `indexes` property to define SQLite indexes.
|
|
25
|
+
*
|
|
26
|
+
* Table and column names are not typed because Kysely doesn't support it.
|
|
27
|
+
*
|
|
28
|
+
* https://medium.com/@JasonWyatt/squeezing-performance-from-sqlite-indexes-indexes-c4e175f3c346
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* const indexes = [
|
|
32
|
+
* createIndex("indexTodoCreatedAt").on("todo").column("createdAt"),
|
|
33
|
+
*
|
|
34
|
+
* createIndex("indexTodoCategoryCreatedAt")
|
|
35
|
+
* .on("todoCategory")
|
|
36
|
+
* .column("createdAt"),
|
|
37
|
+
* ];
|
|
38
|
+
*/
|
|
39
|
+
readonly indexes: ReadonlyArray<CreateIndexBuilder<any>>;
|
|
22
40
|
}
|
|
23
41
|
export declare const Config: Context.Tag<Config, Config>;
|
|
24
42
|
export declare const ConfigLive: (config?: Partial<Config>) => Layer.Layer<Config>;
|
package/dist/src/Config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Config.d.ts","sourceRoot":"","sources":["../../src/Config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,gBAAgB,CAAC;AAC1C,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"Config.d.ts","sourceRoot":"","sources":["../../src/Config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,gBAAgB,CAAC;AAC1C,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,kBAAkB,EAAE,MAAM,QAAQ,CAAC;AAE5C,MAAM,WAAW,MAAM;IACrB,qDAAqD;IACrD,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAEzB;;;OAGG;IACH,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAE3B;;;OAGG;IACH,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAE1B;;;;OAIG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB;;;;;;;;;;;;;;;OAeG;IACH,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC,CAAC;CAC1D;AAED,eAAO,MAAM,MAAM,6BAAiD,CAAC;AAErE,eAAO,MAAM,UAAU,YAAa,QAAQ,MAAM,CAAC,KAAG,WAAW,CAAC,MAAM,CAWrE,CAAC"}
|
package/dist/src/Config.js
CHANGED
package/dist/src/Crdt.d.ts
CHANGED
|
@@ -22,11 +22,11 @@ export declare const AllowedTimeRange: {
|
|
|
22
22
|
* the device clock is out of range, Evolu will not store data until it's
|
|
23
23
|
* fixed.
|
|
24
24
|
*/
|
|
25
|
-
export declare const Millis: S.
|
|
26
|
-
export type Millis = S.Schema.
|
|
25
|
+
export declare const Millis: S.brand<S.Schema<number, number, never>, "Millis">;
|
|
26
|
+
export type Millis = S.Schema.Type<typeof Millis>;
|
|
27
27
|
export declare const initialMillis: number & Brand.Brand<"Millis">;
|
|
28
|
-
export declare const Counter: S.
|
|
29
|
-
export type Counter = S.Schema.
|
|
28
|
+
export declare const Counter: S.brand<S.Schema<number, number, never>, "Counter">;
|
|
29
|
+
export type Counter = S.Schema.Type<typeof Counter>;
|
|
30
30
|
export type TimestampHash = number & Brand.Brand<"TimestampHash">;
|
|
31
31
|
export type TimestampString = string & Brand.Brand<"TimestampString">;
|
|
32
32
|
export declare const timestampToString: (t: Timestamp) => TimestampString;
|
package/dist/src/Crdt.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Crdt.d.ts","sourceRoot":"","sources":["../../src/Crdt.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,uBAAuB,CAAC;AAC3C,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AACtC,OAAO,KAAK,OAAO,MAAM,gBAAgB,CAAC;AAC1C,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAGxC,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AAEtC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAGxC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAQtD,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;CAC3B;AAED,eAAO,MAAM,gBAAgB;;;CAG5B,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,MAAM,
|
|
1
|
+
{"version":3,"file":"Crdt.d.ts","sourceRoot":"","sources":["../../src/Crdt.ts"],"names":[],"mappings":"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"}
|
package/dist/src/Crypto.d.ts
CHANGED
|
@@ -26,8 +26,8 @@ export interface NanoIdGenerator {
|
|
|
26
26
|
}
|
|
27
27
|
export declare const NanoIdGenerator: Context.Tag<NanoIdGenerator, NanoIdGenerator>;
|
|
28
28
|
export type NanoId = string & Brand.Brand<"NanoId">;
|
|
29
|
-
export declare const NodeId: S.
|
|
30
|
-
export type NodeId = S.Schema.
|
|
29
|
+
export declare const NodeId: S.brand<S.Schema<string, string, never>, "NodeId">;
|
|
30
|
+
export type NodeId = S.Schema.Type<typeof NodeId>;
|
|
31
31
|
export declare const NanoIdGeneratorLive: Layer.Layer<NanoIdGenerator, never, never>;
|
|
32
32
|
export declare const slip21Derive: (seed: Uint8Array, path: ReadonlyArray<string>) => Effect.Effect<Uint8Array>;
|
|
33
33
|
/** Alias to xsalsa20poly1305, for compatibility with libsodium/nacl */
|
package/dist/src/Crypto.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Crypto.d.ts","sourceRoot":"","sources":["../../src/Crypto.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,uBAAuB,CAAC;AAM3C,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AACtC,OAAO,KAAK,OAAO,MAAM,gBAAgB,CAAC;AAC1C,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AAItC,MAAM,WAAW,KAAK;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAEvC,QAAQ,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,QAAQ,KAAK,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IAEnE,QAAQ,CAAC,KAAK,EAAE,CACd,QAAQ,EAAE,MAAM,KACb,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,oBAAoB,CAAC,CAAC;CACpD;AAED,eAAO,MAAM,KAAK,2BAA+C,CAAC;AAElE,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,IAAI,EAAE,sBAAsB,CAAC;CACvC;AAED;;;;;;GAMG;AACH,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;AAExD,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACvC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;CAChD;AAED,eAAO,MAAM,eAAe,+CAE3B,CAAC;AAEF,MAAM,MAAM,MAAM,GAAG,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;AAEpD,eAAO,MAAM,MAAM,
|
|
1
|
+
{"version":3,"file":"Crypto.d.ts","sourceRoot":"","sources":["../../src/Crypto.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,uBAAuB,CAAC;AAM3C,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AACtC,OAAO,KAAK,OAAO,MAAM,gBAAgB,CAAC;AAC1C,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AAItC,MAAM,WAAW,KAAK;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAEvC,QAAQ,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,QAAQ,KAAK,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IAEnE,QAAQ,CAAC,KAAK,EAAE,CACd,QAAQ,EAAE,MAAM,KACb,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,oBAAoB,CAAC,CAAC;CACpD;AAED,eAAO,MAAM,KAAK,2BAA+C,CAAC;AAElE,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,IAAI,EAAE,sBAAsB,CAAC;CACvC;AAED;;;;;;GAMG;AACH,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;AAExD,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACvC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;CAChD;AAED,eAAO,MAAM,eAAe,+CAE3B,CAAC;AAEF,MAAM,MAAM,MAAM,GAAG,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;AAEpD,eAAO,MAAM,MAAM,oDAGlB,CAAC;AACF,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,MAAM,CAAC,CAAC;AAIlD,eAAO,MAAM,mBAAmB,4CAM/B,CAAC;AAIF,eAAO,MAAM,YAAY,SACjB,UAAU,QACV,cAAc,MAAM,CAAC,KAC1B,aAAa,CAAC,UAAU,CAWvB,CAAC;AAEL,uEAAuE;AACvE,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,IAAI,EAAE,CACb,GAAG,EAAE,UAAU,EACf,SAAS,EAAE,UAAU,KAClB,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IAE/B,QAAQ,CAAC,IAAI,EAAE,CACb,GAAG,EAAE,UAAU,EACf,UAAU,EAAE,UAAU,KACnB,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;CAChC;AAED,eAAO,MAAM,SAAS,mCAAuD,CAAC;AAE9E,eAAO,MAAM,aAAa,sCAgBzB,CAAC"}
|
package/dist/src/Db.d.ts
CHANGED
|
@@ -11,7 +11,7 @@ import { Bip39, Mnemonic, NanoIdGenerator } from "./Crypto.js";
|
|
|
11
11
|
import { EvoluTypeError } from "./ErrorStore.js";
|
|
12
12
|
import { Id } from "./Model.js";
|
|
13
13
|
import { Owner } from "./Owner.js";
|
|
14
|
-
import { Sqlite, SqliteQuery, Value } from "./Sqlite.js";
|
|
14
|
+
import { Sqlite, SqliteQuery, SqliteSchema, Table, Value } from "./Sqlite.js";
|
|
15
15
|
import { Store } from "./Store.js";
|
|
16
16
|
export type DatabaseSchema = ReadonlyRecord.ReadonlyRecord<string, TableSchema>;
|
|
17
17
|
type TableSchema = ReadonlyRecord.ReadonlyRecord<string, Value> & {
|
|
@@ -28,25 +28,21 @@ type TableSchema = ReadonlyRecord.ReadonlyRecord<string, Value> & {
|
|
|
28
28
|
*
|
|
29
29
|
* @example
|
|
30
30
|
* const TodoId = id("Todo");
|
|
31
|
-
* type TodoId = S.Schema.
|
|
31
|
+
* type TodoId = S.Schema.Type<typeof TodoId>;
|
|
32
32
|
*
|
|
33
33
|
* const TodoTable = table({
|
|
34
34
|
* id: TodoId,
|
|
35
35
|
* title: NonEmptyString1000,
|
|
36
36
|
* isCompleted: S.nullable(SqliteBoolean),
|
|
37
37
|
* });
|
|
38
|
-
* type TodoTable = S.Schema.
|
|
38
|
+
* type TodoTable = S.Schema.Type<typeof TodoTable>;
|
|
39
39
|
*/
|
|
40
|
-
export declare const table: <Fields extends TableFields>(fields: Fields) => ValidateFieldsTypes<Fields> extends true ? ValidateFieldsNames<Fields> extends true ? ValidateFieldsHasId<Fields> extends true ? S.Schema<Types.Simplify<S.
|
|
41
|
-
declare const ReservedColumns: S.
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
}
|
|
46
|
-
readonly createdAt: string;
|
|
47
|
-
readonly updatedAt: string;
|
|
48
|
-
readonly isDeleted: number;
|
|
49
|
-
}, never>;
|
|
40
|
+
export declare const table: <Fields extends TableFields>(fields: Fields) => ValidateFieldsTypes<Fields> extends true ? ValidateFieldsNames<Fields> extends true ? ValidateFieldsHasId<Fields> extends true ? S.Schema<Types.Simplify<S.Struct.Type<Fields> & S.Schema.Type<typeof ReservedColumns>>, Types.Simplify<S.Struct.Encoded<Fields> & S.Schema.Encoded<typeof ReservedColumns>>> : EvoluTypeError<"table() called without id column."> : EvoluTypeError<"table() called with a reserved column. Reserved columns are createdAt, updatedAt, isDeleted. Those columns are added by default."> : EvoluTypeError<"table() called with unsupported type. Supported types are null, string, number, Uint8Array, JSON Object, and JSON Array. Use SqliteDate for dates and SqliteBoolean for booleans.">;
|
|
41
|
+
declare const ReservedColumns: S.struct<{
|
|
42
|
+
createdAt: S.brand<S.Schema<string, string, never>, "SqliteDate">;
|
|
43
|
+
updatedAt: S.brand<S.Schema<string, string, never>, "SqliteDate">;
|
|
44
|
+
isDeleted: S.brand<S.Schema<number, number, never>, "SqliteBoolean">;
|
|
45
|
+
}>;
|
|
50
46
|
type TableFields = Record<string, S.Schema<any>>;
|
|
51
47
|
type ValidateFieldsTypes<Fields extends TableFields> = keyof Fields extends infer K ? K extends keyof Fields ? Fields[K] extends TableFields ? ValidateFieldsTypes<Fields[K]> : Fields[K] extends S.Schema<infer A, infer _I> ? A extends Value ? true : false : never : never : never;
|
|
52
48
|
type ValidateFieldsNames<Fields extends TableFields> = keyof Fields extends infer K ? K extends keyof Fields ? K extends "createdAt" | "updatedAt" | "isDeleted" ? false : true : never : never;
|
|
@@ -64,9 +60,9 @@ type ValidateFieldsHasId<Fields extends TableFields> = "id" extends keyof Fields
|
|
|
64
60
|
* todo: TodoTable,
|
|
65
61
|
* todoCategory: TodoCategoryTable,
|
|
66
62
|
* });
|
|
67
|
-
* type Database = S.Schema.
|
|
63
|
+
* type Database = S.Schema.Type<typeof Database>;
|
|
68
64
|
*/
|
|
69
|
-
export declare const database:
|
|
65
|
+
export declare const database: typeof S.struct;
|
|
70
66
|
declare const __queryBrand: unique symbol;
|
|
71
67
|
/**
|
|
72
68
|
* The query is an SQL query serialized as a string with a branded type
|
|
@@ -76,7 +72,7 @@ export type Query<R extends Row = Row> = string & Brand.Brand<"Query"> & {
|
|
|
76
72
|
readonly [__queryBrand]: R;
|
|
77
73
|
};
|
|
78
74
|
export type Queries<R extends Row = Row> = ReadonlyArray<Query<R>>;
|
|
79
|
-
export declare const serializeQuery: <R extends Row>({ sql, parameters, }: SqliteQuery) => Query<R>;
|
|
75
|
+
export declare const serializeQuery: <R extends Row>({ sql, parameters, options, }: SqliteQuery) => Query<R>;
|
|
80
76
|
export declare const deserializeQuery: <R extends Row>(query: Query<R>) => SqliteQuery;
|
|
81
77
|
export type Row = {
|
|
82
78
|
[key: string]: Value | Row | ReadonlyArray<Row>;
|
|
@@ -109,25 +105,19 @@ export type QueryResultsPromisesFromQueries<Q extends Queries> = {
|
|
|
109
105
|
[P in keyof Q]: Q[P] extends Query<infer R> ? Promise<QueryResult<R>> : never;
|
|
110
106
|
};
|
|
111
107
|
export declare const queryResultFromRows: <R extends Row>(rows: ReadonlyArray<R>) => QueryResult<R>;
|
|
112
|
-
export
|
|
113
|
-
export interface Table {
|
|
114
|
-
readonly name: string;
|
|
115
|
-
readonly columns: ReadonlyArray<string>;
|
|
116
|
-
}
|
|
117
|
-
export declare const schemaToTables: (schema: S.Schema<any>) => Tables;
|
|
108
|
+
export declare const schemaToTables: (schema: S.Schema<any>) => ReadonlyArray<Table>;
|
|
118
109
|
export declare const transaction: <R, E, A>(effect: Effect.Effect<A, E, R>) => Effect.Effect<A, E, Sqlite | R>;
|
|
119
110
|
export interface NoSuchTableOrColumnError {
|
|
120
111
|
readonly _tag: "NoSuchTableOrColumnError";
|
|
121
112
|
}
|
|
122
|
-
export declare const SqliteNoSuchTableOrColumnError: S.
|
|
123
|
-
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
}, never>;
|
|
127
|
-
export type SqliteNoSuchTableOrColumnError = S.Schema.To<typeof SqliteNoSuchTableOrColumnError>;
|
|
113
|
+
export declare const SqliteNoSuchTableOrColumnError: S.struct<{
|
|
114
|
+
message: S.union<[S.Schema<string, string, never>, S.Schema<string, string, never>, S.Schema<string, string, never>]>;
|
|
115
|
+
}>;
|
|
116
|
+
export type SqliteNoSuchTableOrColumnError = S.Schema.Type<typeof SqliteNoSuchTableOrColumnError>;
|
|
128
117
|
export declare const someDefectToNoSuchTableOrColumnError: <A, E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A, NoSuchTableOrColumnError | E, R>;
|
|
129
118
|
export declare const lazyInit: (mnemonic?: Mnemonic) => Effect.Effect<Owner, never, Sqlite | Bip39 | NanoIdGenerator>;
|
|
130
|
-
export declare const ensureSchema: (
|
|
119
|
+
export declare const ensureSchema: (schema: SqliteSchema) => Effect.Effect<void, never, Sqlite>;
|
|
120
|
+
export declare const dropAllTables: Effect.Effect<void, never, Sqlite>;
|
|
131
121
|
export type RowsStore = Store<RowsStoreValue>;
|
|
132
122
|
export declare const RowsStore: Context.Tag<RowsStore, RowsStore>;
|
|
133
123
|
type RowsStoreValue = ReadonlyMap<Query, ReadonlyArray<Row>>;
|
package/dist/src/Db.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Db.d.ts","sourceRoot":"","sources":["../../src/Db.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,CAAC,MAAM,uBAAuB,CAAC;AAE3C,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AACtC,OAAO,KAAK,OAAO,MAAM,gBAAgB,CAAC;AAC1C,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAGxC,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AAGtC,OAAO,KAAK,aAAa,MAAM,sBAAsB,CAAC;AACtD,OAAO,KAAK,cAAc,MAAM,uBAAuB,CAAC;AAExD,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AACtC,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAC;AAOjC,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC/D,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAE,EAAE,EAA6B,MAAM,YAAY,CAAC;AAC3D,OAAO,EAAE,KAAK,EAAa,MAAM,YAAY,CAAC;AAO9C,OAAO,
|
|
1
|
+
{"version":3,"file":"Db.d.ts","sourceRoot":"","sources":["../../src/Db.ts"],"names":[],"mappings":"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"}
|
package/dist/src/Db.js
CHANGED
|
@@ -15,7 +15,7 @@ import { initialMerkleTree, makeInitialTimestamp, merkleTreeToString, timestampT
|
|
|
15
15
|
import { SqliteBoolean, SqliteDate } from "./Model.js";
|
|
16
16
|
import { makeOwner } from "./Owner.js";
|
|
17
17
|
import { createMessageTable, createMessageTableIndex, createOwnerTable, insertOwner, } from "./Sql.js";
|
|
18
|
-
import { Sqlite, isJsonObjectOrArray, } from "./Sqlite.js";
|
|
18
|
+
import { indexEquivalence, Sqlite, isJsonObjectOrArray, } from "./Sqlite.js";
|
|
19
19
|
import { makeStore } from "./Store.js";
|
|
20
20
|
/**
|
|
21
21
|
* Create table schema.
|
|
@@ -28,14 +28,14 @@ import { makeStore } from "./Store.js";
|
|
|
28
28
|
*
|
|
29
29
|
* @example
|
|
30
30
|
* const TodoId = id("Todo");
|
|
31
|
-
* type TodoId = S.Schema.
|
|
31
|
+
* type TodoId = S.Schema.Type<typeof TodoId>;
|
|
32
32
|
*
|
|
33
33
|
* const TodoTable = table({
|
|
34
34
|
* id: TodoId,
|
|
35
35
|
* title: NonEmptyString1000,
|
|
36
36
|
* isCompleted: S.nullable(SqliteBoolean),
|
|
37
37
|
* });
|
|
38
|
-
* type TodoTable = S.Schema.
|
|
38
|
+
* type TodoTable = S.Schema.Type<typeof TodoTable>;
|
|
39
39
|
*/
|
|
40
40
|
export const table = (fields) => S.struct(fields).pipe(S.extend(ReservedColumns));
|
|
41
41
|
const ReservedColumns = S.struct({
|
|
@@ -56,20 +56,19 @@ const ReservedColumns = S.struct({
|
|
|
56
56
|
* todo: TodoTable,
|
|
57
57
|
* todoCategory: TodoCategoryTable,
|
|
58
58
|
* });
|
|
59
|
-
* type Database = S.Schema.
|
|
59
|
+
* type Database = S.Schema.Type<typeof Database>;
|
|
60
60
|
*/
|
|
61
61
|
export const database = S.struct;
|
|
62
62
|
// We use queries as keys, hence JSON.stringify.
|
|
63
|
-
export const serializeQuery = ({ sql, parameters, }) => {
|
|
63
|
+
export const serializeQuery = ({ sql, parameters = [], options, }) => {
|
|
64
64
|
const query = {
|
|
65
65
|
sql,
|
|
66
|
-
parameters: parameters.map((p) =>
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
:
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
}),
|
|
66
|
+
parameters: parameters.map((p) => Predicate.isUint8Array(p)
|
|
67
|
+
? Array.from(p)
|
|
68
|
+
: isJsonObjectOrArray(p)
|
|
69
|
+
? { json: p }
|
|
70
|
+
: p),
|
|
71
|
+
...(options && { options }),
|
|
73
72
|
};
|
|
74
73
|
return JSON.stringify(query);
|
|
75
74
|
};
|
|
@@ -95,6 +94,7 @@ export const queryResultFromRows = (rows) => {
|
|
|
95
94
|
}
|
|
96
95
|
return queryResult;
|
|
97
96
|
};
|
|
97
|
+
// TODO: https://discord.com/channels/795981131316985866/1218626687546294386/1218796529725476935
|
|
98
98
|
// https://github.com/Effect-TS/schema/releases/tag/v0.18.0
|
|
99
99
|
const getPropertySignatures = (schema) => {
|
|
100
100
|
const out = {};
|
|
@@ -110,7 +110,9 @@ export const schemaToTables = (schema) => pipe(getPropertySignatures(schema), Re
|
|
|
110
110
|
name,
|
|
111
111
|
columns: Object.keys(getPropertySignatures(schema)),
|
|
112
112
|
})));
|
|
113
|
-
export const transaction = (effect) => Effect.flatMap(Sqlite, (sqlite) => Effect.acquireUseRelease(sqlite.exec("begin"), () => effect, (_, exit) => Exit.isFailure(exit)
|
|
113
|
+
export const transaction = (effect) => Effect.flatMap(Sqlite, (sqlite) => Effect.acquireUseRelease(sqlite.exec({ sql: "begin" }), () => effect, (_, exit) => Exit.isFailure(exit)
|
|
114
|
+
? sqlite.exec({ sql: "rollback" })
|
|
115
|
+
: sqlite.exec({ sql: "end" })));
|
|
114
116
|
export const SqliteNoSuchTableOrColumnError = S.struct({
|
|
115
117
|
message: S.union(S.string.pipe(S.includes("no such table")), S.string.pipe(S.includes("no such column")), S.string.pipe(S.includes("has no column"))),
|
|
116
118
|
});
|
|
@@ -128,7 +130,7 @@ export const lazyInit = (mnemonic) => Effect.gen(function* (_) {
|
|
|
128
130
|
sqlite.exec(createMessageTableIndex),
|
|
129
131
|
sqlite.exec(createOwnerTable),
|
|
130
132
|
sqlite.exec({
|
|
131
|
-
|
|
133
|
+
...insertOwner,
|
|
132
134
|
parameters: [
|
|
133
135
|
owner.id,
|
|
134
136
|
owner.mnemonic,
|
|
@@ -140,27 +142,102 @@ export const lazyInit = (mnemonic) => Effect.gen(function* (_) {
|
|
|
140
142
|
]));
|
|
141
143
|
return owner;
|
|
142
144
|
});
|
|
143
|
-
const
|
|
144
|
-
const
|
|
145
|
+
const getSchema = Effect.gen(function* (_) {
|
|
146
|
+
const sqlite = yield* _(Sqlite);
|
|
147
|
+
const tables = yield* _(sqlite.exec({
|
|
148
|
+
// https://til.simonwillison.net/sqlite/list-all-columns-in-a-database
|
|
149
|
+
sql: `
|
|
150
|
+
select
|
|
151
|
+
sqlite_master.name as tableName,
|
|
152
|
+
table_info.name as columnName
|
|
153
|
+
from
|
|
154
|
+
sqlite_master
|
|
155
|
+
join pragma_table_info(sqlite_master.name) as table_info
|
|
156
|
+
`.trim(),
|
|
157
|
+
}), Effect.map(({ rows }) => {
|
|
158
|
+
const map = new Map();
|
|
159
|
+
rows.forEach((row) => {
|
|
160
|
+
const { tableName, columnName } = row;
|
|
161
|
+
if (!map.has(tableName))
|
|
162
|
+
map.set(tableName, []);
|
|
163
|
+
map.get(tableName)?.push(columnName);
|
|
164
|
+
});
|
|
165
|
+
return Array.from(map, ([name, columns]) => ({
|
|
166
|
+
name,
|
|
167
|
+
columns,
|
|
168
|
+
}));
|
|
169
|
+
}));
|
|
170
|
+
const indexes = yield* _(sqlite.exec({
|
|
171
|
+
sql: `
|
|
172
|
+
select
|
|
173
|
+
name, sql
|
|
174
|
+
from
|
|
175
|
+
sqlite_master
|
|
176
|
+
where
|
|
177
|
+
type='index' and
|
|
178
|
+
name not like 'sqlite_%' and
|
|
179
|
+
name not like 'index_evolu_%'`,
|
|
180
|
+
}), Effect.map((result) => ReadonlyArray.map(result.rows, (row) => ({
|
|
181
|
+
name: row.name,
|
|
182
|
+
/**
|
|
183
|
+
* SQLite returns "CREATE INDEX" for "create index" for some reason.
|
|
184
|
+
* Other keywords remain unchanged. We have to normalize the casing
|
|
185
|
+
* for `indexEquivalence` manually.
|
|
186
|
+
*/
|
|
187
|
+
sql: row.sql.replace("CREATE INDEX", "create index"),
|
|
188
|
+
}))));
|
|
189
|
+
return { tables, indexes };
|
|
190
|
+
});
|
|
191
|
+
export const ensureSchema = (schema) => Effect.gen(function* (_) {
|
|
192
|
+
const sqlite = yield* _(Sqlite);
|
|
193
|
+
const currentSchema = yield* _(getSchema);
|
|
194
|
+
const sql = [];
|
|
195
|
+
schema.tables.forEach((table) => {
|
|
196
|
+
const currentTable = currentSchema.tables.find((t) => t.name === table.name);
|
|
197
|
+
if (!currentTable) {
|
|
198
|
+
sql.push(`
|
|
199
|
+
create table ${table.name} (
|
|
200
|
+
"id" text primary key,
|
|
201
|
+
${table.columns
|
|
202
|
+
.filter((c) => c !== "id")
|
|
203
|
+
// "A column with affinity BLOB does not prefer one storage class over another
|
|
204
|
+
// and no attempt is made to coerce data from one storage class into another."
|
|
205
|
+
// https://www.sqlite.org/datatype3.html
|
|
206
|
+
.map((name) => `"${name}" blob`)
|
|
207
|
+
.join(", ")}
|
|
208
|
+
);
|
|
209
|
+
`);
|
|
210
|
+
}
|
|
211
|
+
else {
|
|
212
|
+
ReadonlyArray.differenceWith(String.Equivalence)(table.columns, currentTable.columns).forEach((newColumn) => {
|
|
213
|
+
sql.push(`alter table "${table.name}" add column "${newColumn}" blob;`);
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
});
|
|
217
|
+
// Remove old indexes.
|
|
218
|
+
ReadonlyArray.differenceWith(indexEquivalence)(currentSchema.indexes, ReadonlyArray.intersectionWith(indexEquivalence)(currentSchema.indexes, schema.indexes)).forEach((indexToDrop) => {
|
|
219
|
+
sql.push(`drop index "${indexToDrop.name}";`);
|
|
220
|
+
});
|
|
221
|
+
// Add new indexes.
|
|
222
|
+
ReadonlyArray.differenceWith(indexEquivalence)(schema.indexes, currentSchema.indexes).forEach((newIndex) => {
|
|
223
|
+
sql.push(`${newIndex.sql};`);
|
|
224
|
+
});
|
|
225
|
+
if (sql.length > 0)
|
|
226
|
+
yield* _(sqlite.exec({
|
|
227
|
+
sql: sql.join(""),
|
|
228
|
+
}));
|
|
229
|
+
});
|
|
230
|
+
export const dropAllTables = Effect.gen(function* (_) {
|
|
145
231
|
const sqlite = yield* _(Sqlite);
|
|
146
|
-
const
|
|
147
|
-
|
|
148
|
-
|
|
232
|
+
const schema = yield* _(getSchema);
|
|
233
|
+
const sql = schema.tables
|
|
234
|
+
// The dropped table is completely removed from the database schema and
|
|
235
|
+
// the disk file. The table can not be recovered.
|
|
236
|
+
// All indices and triggers associated with the table are also deleted.
|
|
237
|
+
// https://sqlite.org/lang_droptable.html
|
|
238
|
+
.map((table) => `drop table "${table.name}";`)
|
|
239
|
+
.join("");
|
|
240
|
+
yield* _(sqlite.exec({ sql }));
|
|
149
241
|
});
|
|
150
|
-
const createTable = ({ name, columns, }) => Effect.flatMap(Sqlite, (sqlite) => sqlite.exec(`
|
|
151
|
-
create table ${name} (
|
|
152
|
-
"id" text primary key,
|
|
153
|
-
${columns
|
|
154
|
-
.filter((c) => c !== "id")
|
|
155
|
-
// "A column with affinity BLOB does not prefer one storage class over another
|
|
156
|
-
// and no attempt is made to coerce data from one storage class into another."
|
|
157
|
-
// https://www.sqlite.org/datatype3.html
|
|
158
|
-
.map((name) => `"${name}" blob`)
|
|
159
|
-
.join(", ")}
|
|
160
|
-
);
|
|
161
|
-
`));
|
|
162
|
-
export const ensureSchema = (tables) => Effect.flatMap(getTables, (existingTables) => Effect.forEach(tables, (tableDefinition) => existingTables.includes(tableDefinition.name)
|
|
163
|
-
? updateTable(tableDefinition)
|
|
164
|
-
: createTable(tableDefinition), { discard: true }));
|
|
165
242
|
export const RowsStore = Context.GenericTag("@services/RowsStore");
|
|
166
243
|
export const RowsStoreLive = Layer.effect(RowsStore, makeStore(new Map()));
|
package/dist/src/DbWorker.d.ts
CHANGED
|
@@ -6,14 +6,14 @@ import * as ReadonlyRecord from "effect/ReadonlyRecord";
|
|
|
6
6
|
import { Config } from "./Config.js";
|
|
7
7
|
import { Millis } from "./Crdt.js";
|
|
8
8
|
import { Bip39, Mnemonic, NanoIdGenerator } from "./Crypto.js";
|
|
9
|
-
import { Queries, Query
|
|
9
|
+
import { Queries, Query } from "./Db.js";
|
|
10
10
|
import { QueryPatches } from "./Diff.js";
|
|
11
11
|
import { EvoluError } from "./ErrorStore.js";
|
|
12
12
|
import { Id } from "./Model.js";
|
|
13
13
|
import { OnCompleteId } from "./OnCompletes.js";
|
|
14
14
|
import { Owner } from "./Owner.js";
|
|
15
15
|
import { DbWorkerLock } from "./Platform.js";
|
|
16
|
-
import { Sqlite, Value } from "./Sqlite.js";
|
|
16
|
+
import { Sqlite, SqliteSchema, Value } from "./Sqlite.js";
|
|
17
17
|
import { NewMessage, SyncState, SyncWorker, SyncWorkerOutputSyncResponse } from "./SyncWorker.js";
|
|
18
18
|
import { Messaging } from "./Types.js";
|
|
19
19
|
export interface DbWorker extends Messaging<DbWorkerInput, DbWorkerOutput> {
|
|
@@ -41,9 +41,8 @@ interface DbWorkerInputReset {
|
|
|
41
41
|
readonly _tag: "reset";
|
|
42
42
|
readonly mnemonic?: Mnemonic;
|
|
43
43
|
}
|
|
44
|
-
interface DbWorkerInputEnsureSchema {
|
|
44
|
+
interface DbWorkerInputEnsureSchema extends SqliteSchema {
|
|
45
45
|
readonly _tag: "ensureSchema";
|
|
46
|
-
readonly tables: Tables;
|
|
47
46
|
}
|
|
48
47
|
export type DbWorkerOutput = DbWorkerOutputOnError | DbWorkerOutputOnOwner | DbWorkerOutputOnQuery | DbWorkerOutputOnReceive | DbWorkerOutputOnResetOrRestore | DbWorkerOutputOnSyncState;
|
|
49
48
|
export interface DbWorkerOutputOnError {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DbWorker.d.ts","sourceRoot":"","sources":["../../src/DbWorker.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,gBAAgB,CAAC;AAC1C,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAGxC,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AAGtC,OAAO,KAAK,aAAa,MAAM,sBAAsB,CAAC;AACtD,OAAO,KAAK,cAAc,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,MAAM,EAAc,MAAM,aAAa,CAAC;AACjD,OAAO,EAEL,MAAM,EAiBP,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC/D,OAAO,EACL,OAAO,EACP,KAAK,
|
|
1
|
+
{"version":3,"file":"DbWorker.d.ts","sourceRoot":"","sources":["../../src/DbWorker.ts"],"names":[],"mappings":"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"}
|
package/dist/src/DbWorker.js
CHANGED
|
@@ -9,14 +9,14 @@ import * as ReadonlyArray from "effect/ReadonlyArray";
|
|
|
9
9
|
import { Config, ConfigLive } from "./Config.js";
|
|
10
10
|
import { Time, TimeLive, diffMerkleTrees, insertIntoMerkleTree, makeSyncTimestamp, merkleTreeToString, receiveTimestamp, sendTimestamp, timestampToString, unsafeTimestampFromString, } from "./Crdt.js";
|
|
11
11
|
import { Bip39, NanoIdGenerator } from "./Crypto.js";
|
|
12
|
-
import { RowsStore, RowsStoreLive, deserializeQuery, ensureSchema, lazyInit, someDefectToNoSuchTableOrColumnError, transaction, } from "./Db.js";
|
|
12
|
+
import { RowsStore, RowsStoreLive, deserializeQuery, dropAllTables, ensureSchema, lazyInit, someDefectToNoSuchTableOrColumnError, transaction, } from "./Db.js";
|
|
13
13
|
import { makePatches } from "./Diff.js";
|
|
14
14
|
import { makeUnexpectedError } from "./ErrorStore.js";
|
|
15
15
|
import { cast } from "./Model.js";
|
|
16
16
|
import { Owner } from "./Owner.js";
|
|
17
17
|
import { DbWorkerLock } from "./Platform.js";
|
|
18
18
|
import * as Sql from "./Sql.js";
|
|
19
|
-
import { Sqlite } from "./Sqlite.js";
|
|
19
|
+
import { Sqlite, drawSqliteQueryPlan as drawExplainQueryPlan, } from "./Sqlite.js";
|
|
20
20
|
import { NewMessageEquivalence, SyncWorker, SyncWorkerPostMessage, } from "./SyncWorker.js";
|
|
21
21
|
export const DbWorker = Context.GenericTag("@services/DbWorker");
|
|
22
22
|
const DbWorkerOnMessage = Context.GenericTag("@services/DbWorkerOnMessage");
|
|
@@ -32,9 +32,23 @@ const query = ({ queries, onCompleteIds = [], }) => Effect.gen(function* (_) {
|
|
|
32
32
|
const sqlite = yield* _(Sqlite);
|
|
33
33
|
const rowsStore = yield* _(RowsStore);
|
|
34
34
|
const dbWorkerOnMessage = yield* _(DbWorkerOnMessage);
|
|
35
|
-
const queriesRows = yield* _(ReadonlyArray.dedupe(queries), Effect.forEach((query) =>
|
|
36
|
-
|
|
37
|
-
.pipe(Effect.map((result) => [query, result.rows]))
|
|
35
|
+
const queriesRows = yield* _(ReadonlyArray.dedupe(queries), Effect.forEach((query) => {
|
|
36
|
+
const sqliteQuery = deserializeQuery(query);
|
|
37
|
+
return sqlite.exec(sqliteQuery).pipe(Effect.map((result) => [query, result.rows]), Effect.tap(() => {
|
|
38
|
+
if (!sqliteQuery.options?.logExplainQueryPlan)
|
|
39
|
+
return;
|
|
40
|
+
return sqlite
|
|
41
|
+
.exec({
|
|
42
|
+
...sqliteQuery,
|
|
43
|
+
sql: `EXPLAIN QUERY PLAN ${sqliteQuery.sql}`,
|
|
44
|
+
})
|
|
45
|
+
.pipe(Effect.tap(() => Effect.log("ExplainQueryPlan")), Effect.tap(({ rows }) => {
|
|
46
|
+
// Not using Effect.log because of formating
|
|
47
|
+
// eslint-disable-next-line no-console
|
|
48
|
+
console.log(drawExplainQueryPlan(rows));
|
|
49
|
+
}));
|
|
50
|
+
}));
|
|
51
|
+
}));
|
|
38
52
|
const previous = rowsStore.getState();
|
|
39
53
|
yield* _(rowsStore.setState(new Map([...previous, ...queriesRows])));
|
|
40
54
|
const queriesPatches = queriesRows.map(([query, rows]) => ({
|
|
@@ -87,13 +101,22 @@ const ensureSchemaByNewMessages = (messages) => Effect.gen(function* (_) {
|
|
|
87
101
|
columns: table.columns.concat(message.column),
|
|
88
102
|
});
|
|
89
103
|
});
|
|
90
|
-
|
|
104
|
+
const tables = Array.from(tablesMap.values());
|
|
105
|
+
yield* _(ensureSchema({ tables, indexes: [] }));
|
|
91
106
|
});
|
|
92
107
|
export const upsertValueIntoTableRowColumn = (message, messages, millis) => Effect.gen(function* (_) {
|
|
93
108
|
const sqlite = yield* _(Sqlite);
|
|
94
109
|
const createdAtOrUpdatedAt = cast(new Date(millis));
|
|
95
110
|
const insert = sqlite.exec({
|
|
96
|
-
sql:
|
|
111
|
+
sql: `
|
|
112
|
+
insert into
|
|
113
|
+
"${message.table}" ("id", "${message.column}", "createdAt", "updatedAt")
|
|
114
|
+
values
|
|
115
|
+
(?, ?, ?, ?)
|
|
116
|
+
on conflict do update set
|
|
117
|
+
"${message.column}" = ?,
|
|
118
|
+
"updatedAt" = ?
|
|
119
|
+
`.trim(),
|
|
97
120
|
parameters: [
|
|
98
121
|
message.row,
|
|
99
122
|
message.value,
|
|
@@ -111,8 +134,8 @@ const applyMessages = ({ merkleTree, messages, }) => Effect.gen(function* (_) {
|
|
|
111
134
|
const sqlite = yield* _(Sqlite);
|
|
112
135
|
for (const message of messages) {
|
|
113
136
|
const timestamp = yield* _(sqlite.exec({
|
|
114
|
-
|
|
115
|
-
parameters: [message.table, message.row, message.column],
|
|
137
|
+
...Sql.selectLastTimestampForTableRowColumn,
|
|
138
|
+
parameters: [message.table, message.row, message.column, 1],
|
|
116
139
|
}), Effect.map((result) => result.rows), Effect.flatMap(ReadonlyArray.head), Effect.map((row) => row.timestamp), Effect.catchTag("NoSuchElementException", () => Effect.succeed(null)));
|
|
117
140
|
if (timestamp == null || timestamp < message.timestamp) {
|
|
118
141
|
const { millis } = unsafeTimestampFromString(message.timestamp);
|
|
@@ -120,7 +143,7 @@ const applyMessages = ({ merkleTree, messages, }) => Effect.gen(function* (_) {
|
|
|
120
143
|
}
|
|
121
144
|
if (timestamp == null || timestamp !== message.timestamp) {
|
|
122
145
|
const { changes } = yield* _(sqlite.exec({
|
|
123
|
-
|
|
146
|
+
...Sql.insertIntoMessagesIfNew,
|
|
124
147
|
parameters: [
|
|
125
148
|
message.timestamp,
|
|
126
149
|
message.table,
|
|
@@ -138,10 +161,10 @@ const applyMessages = ({ merkleTree, messages, }) => Effect.gen(function* (_) {
|
|
|
138
161
|
return merkleTree;
|
|
139
162
|
});
|
|
140
163
|
const writeTimestampAndMerkleTree = ({ timestamp, merkleTree, }) => Effect.flatMap(Sqlite, (sqlite) => sqlite.exec({
|
|
141
|
-
|
|
164
|
+
...Sql.updateOwnerTimestampAndMerkleTree,
|
|
142
165
|
parameters: [
|
|
143
|
-
timestampToString(timestamp),
|
|
144
166
|
merkleTreeToString(merkleTree),
|
|
167
|
+
timestampToString(timestamp),
|
|
145
168
|
],
|
|
146
169
|
}));
|
|
147
170
|
const mutate = ({ mutations, queries, }) => Effect.gen(function* (_) {
|
|
@@ -153,7 +176,10 @@ const mutate = ({ mutations, queries, }) => Effect.gen(function* (_) {
|
|
|
153
176
|
yield* _(upsertValueIntoTableRowColumn(messageToUpsert, toUpsert, now));
|
|
154
177
|
}
|
|
155
178
|
const { exec } = yield* _(Sqlite);
|
|
156
|
-
yield* _(Effect.forEach(toDelete, ({ table, row }) => exec({
|
|
179
|
+
yield* _(Effect.forEach(toDelete, ({ table, row }) => exec({
|
|
180
|
+
sql: `delete from "${table}" where "id" = ?;`,
|
|
181
|
+
parameters: [row],
|
|
182
|
+
})));
|
|
157
183
|
if (toSync.length > 0) {
|
|
158
184
|
let { timestamp, merkleTree } = yield* _(readTimestampAndMerkleTree);
|
|
159
185
|
const messages = yield* _(mutationsToNewMessages(toSync), Effect.forEach((message) => Effect.map(sendTimestamp(timestamp), (nextTimestamp) => {
|
|
@@ -203,7 +229,7 @@ const handleSyncResponse = ({ messages, ...response }) => Effect.gen(function* (
|
|
|
203
229
|
const config = yield* _(Config);
|
|
204
230
|
const owner = yield* _(Owner);
|
|
205
231
|
const messagesToSync = yield* _(sqlite.exec({
|
|
206
|
-
|
|
232
|
+
...Sql.selectMessagesToSync,
|
|
207
233
|
parameters: [timestampToString(makeSyncTimestamp(diff.value))],
|
|
208
234
|
}), Effect.map(({ rows }) => rows));
|
|
209
235
|
if (response.syncLoopCount > 100) {
|
|
@@ -236,13 +262,7 @@ const sync = ({ queries, }) => Effect.gen(function* (_) {
|
|
|
236
262
|
});
|
|
237
263
|
});
|
|
238
264
|
const reset = (input) => Effect.gen(function* (_) {
|
|
239
|
-
|
|
240
|
-
yield* _(sqlite.exec(`SELECT "name" FROM "sqlite_master" WHERE "type" = 'table'`), Effect.map((result) => result.rows), Effect.flatMap(
|
|
241
|
-
// The dropped table is completely removed from the database schema and
|
|
242
|
-
// the disk file. The table can not be recovered.
|
|
243
|
-
// All indices and triggers associated with the table are also deleted.
|
|
244
|
-
// https://sqlite.org/lang_droptable.html
|
|
245
|
-
Effect.forEach(({ name }) => sqlite.exec(`DROP TABLE "${name}"`), { discard: true })));
|
|
265
|
+
yield* _(dropAllTables);
|
|
246
266
|
if (input.mnemonic)
|
|
247
267
|
yield* _(lazyInit(input.mnemonic));
|
|
248
268
|
const onMessage = yield* _(DbWorkerOnMessage);
|
|
@@ -290,7 +310,7 @@ export const DbWorkerCommonLive = Layer.effect(DbWorker, Effect.gen(function* (_
|
|
|
290
310
|
skipAllBecauseOfReset = true;
|
|
291
311
|
return reset(input);
|
|
292
312
|
},
|
|
293
|
-
ensureSchema
|
|
313
|
+
ensureSchema,
|
|
294
314
|
SyncWorkerOutputSyncResponse: handleSyncResponse,
|
|
295
315
|
}), Effect.provide(layer), run);
|
|
296
316
|
};
|