@evolu/common 3.1.8 → 4.0.1
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/Config.d.ts +6 -0
- package/dist/src/Config.d.ts.map +1 -1
- package/dist/src/Config.js +1 -0
- package/dist/src/Crdt.d.ts +2 -2
- package/dist/src/Crdt.d.ts.map +1 -1
- package/dist/src/Crdt.js +2 -2
- package/dist/src/Crypto.d.ts +5 -4
- package/dist/src/Crypto.d.ts.map +1 -1
- package/dist/src/Crypto.js +2 -2
- package/dist/src/Db.d.ts +2 -2
- package/dist/src/Db.d.ts.map +1 -1
- package/dist/src/Db.js +5 -7
- package/dist/src/DbWorker.d.ts +8 -8
- package/dist/src/DbWorker.d.ts.map +1 -1
- package/dist/src/DbWorker.js +44 -28
- package/dist/src/Evolu.d.ts +4 -5
- package/dist/src/Evolu.d.ts.map +1 -1
- package/dist/src/Evolu.js +10 -13
- package/dist/src/OnCompletes.d.ts +3 -3
- package/dist/src/OnCompletes.d.ts.map +1 -1
- package/dist/src/OnCompletes.js +3 -3
- package/dist/src/Platform.d.ts +3 -1
- package/dist/src/Platform.d.ts.map +1 -1
- package/dist/src/Platform.js +1 -0
- package/dist/src/Sql.d.ts +10 -10
- package/dist/src/Sql.d.ts.map +1 -1
- package/dist/src/Sql.js +48 -47
- package/dist/src/Sqlite.d.ts +3 -2
- package/dist/src/Sqlite.d.ts.map +1 -1
- package/dist/src/Sqlite.js +11 -0
- package/dist/src/SyncWorker.d.ts +3 -4
- package/dist/src/SyncWorker.d.ts.map +1 -1
- package/dist/src/SyncWorker.js +1 -1
- package/dist/src/Types.d.ts +13 -0
- package/dist/src/Types.d.ts.map +1 -0
- package/dist/src/Types.js +1 -0
- package/package.json +5 -5
- package/src/Config.ts +8 -0
- package/src/Crdt.ts +2 -2
- package/src/Crypto.ts +11 -7
- package/src/Db.ts +9 -11
- package/src/DbWorker.ts +54 -44
- package/src/Evolu.ts +23 -18
- package/src/OnCompletes.ts +4 -4
- package/src/Platform.ts +6 -5
- package/src/Sql.ts +52 -49
- package/src/Sqlite.ts +18 -2
- package/src/SyncWorker.ts +4 -6
- package/src/Types.ts +11 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OnCompletes.d.ts","sourceRoot":"","sources":["../../src/OnCompletes.ts"],"names":[],"mappings":"AAAA,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;AAGtC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"OnCompletes.d.ts","sourceRoot":"","sources":["../../src/OnCompletes.ts"],"names":[],"mappings":"AAAA,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;AAGtC,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEtD,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,GAAG,EAAE,CAAC,UAAU,EAAE,UAAU,KAAK,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;IAEtE,QAAQ,CAAC,QAAQ,EAAE,CACjB,aAAa,EAAE,SAAS,YAAY,EAAE,KACnC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;CAC1B;AAED,MAAM,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC;AAEpC,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;AAEhE,eAAO,MAAM,WAAW,uCAEvB,CAAC;AAEF,eAAO,MAAM,eAAe,kDA0B3B,CAAC"}
|
package/dist/src/OnCompletes.js
CHANGED
|
@@ -3,13 +3,13 @@ import * as Effect from "effect/Effect";
|
|
|
3
3
|
import * as Layer from "effect/Layer";
|
|
4
4
|
import * as Option from "effect/Option";
|
|
5
5
|
import * as ReadonlyArray from "effect/ReadonlyArray";
|
|
6
|
-
import {
|
|
6
|
+
import { NanoIdGenerator } from "./Crypto.js";
|
|
7
7
|
export const OnCompletes = Context.GenericTag("@services/OnCompletes");
|
|
8
8
|
export const OnCompletesLive = Layer.effect(OnCompletes, Effect.gen(function* (_) {
|
|
9
|
-
const nanoid = yield* _(
|
|
9
|
+
const { nanoid } = yield* _(NanoIdGenerator);
|
|
10
10
|
const map = new Map();
|
|
11
11
|
return OnCompletes.of({
|
|
12
|
-
add: (onComplete) => nanoid.
|
|
12
|
+
add: (onComplete) => nanoid.pipe(Effect.map((nanoid) => {
|
|
13
13
|
const id = nanoid;
|
|
14
14
|
map.set(id, onComplete);
|
|
15
15
|
return id;
|
package/dist/src/Platform.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as Context from "effect/Context";
|
|
2
2
|
import * as Effect from "effect/Effect";
|
|
3
3
|
import * as Layer from "effect/Layer";
|
|
4
|
-
export type PlatformName = "server" | "web
|
|
4
|
+
export type PlatformName = "server" | "web" | "react-native";
|
|
5
5
|
export declare const PlatformName: Context.Tag<PlatformName, PlatformName>;
|
|
6
6
|
/**
|
|
7
7
|
* FlushSync lets you force React to flush any updates inside the provided
|
|
@@ -23,6 +23,8 @@ export interface SyncLock {
|
|
|
23
23
|
readonly release: Effect.Effect<void>;
|
|
24
24
|
}
|
|
25
25
|
export declare const SyncLock: Context.Tag<SyncLock, SyncLock>;
|
|
26
|
+
export type DbWorkerLock = (callback: () => Promise<void>) => void;
|
|
27
|
+
export declare const DbWorkerLock: Context.Tag<DbWorkerLock, DbWorkerLock>;
|
|
26
28
|
export type Fetch = (url: string, body: Uint8Array) => Effect.Effect<Response, FetchError>;
|
|
27
29
|
export declare const Fetch: Context.Tag<Fetch, Fetch>;
|
|
28
30
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Platform.d.ts","sourceRoot":"","sources":["../../src/Platform.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,gBAAgB,CAAC;AAC1C,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AAEtC,MAAM,MAAM,YAAY,
|
|
1
|
+
{"version":3,"file":"Platform.d.ts","sourceRoot":"","sources":["../../src/Platform.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,gBAAgB,CAAC;AAC1C,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AAEtC,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,KAAK,GAAG,cAAc,CAAC;AAE7D,eAAO,MAAM,YAAY,yCAExB,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,MAAM,SAAS,GAAG,CAAC,QAAQ,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;AAEvD,eAAO,MAAM,SAAS,mCAAuD,CAAC;AAE9E,eAAO,MAAM,oBAAoB,sCAEhC,CAAC;AAEF,MAAM,WAAW,QAAQ;IACvB;;;OAGG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAEzC,2BAA2B;IAC3B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;CACvC;AAED,eAAO,MAAM,QAAQ,iCAAqD,CAAC;AAE3E,MAAM,MAAM,YAAY,GAAG,CAAC,QAAQ,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC;AACnE,eAAO,MAAM,YAAY,yCAExB,CAAC;AAEF,MAAM,MAAM,KAAK,GAAG,CAClB,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,UAAU,KACb,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;AAEzC,eAAO,MAAM,KAAK,2BAA+C,CAAC;AAElE;;;GAGG;AACH,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;CAC7B;AAED,eAAO,MAAM,SAAS,kCAgBrB,CAAC;AAEF,UAAU,cAAc;IACtB,QAAQ,CAAC,aAAa,EAAE,MAAM,IAAI,CAAC;CACpC;AAED,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,IAAI,EAAE,CAAC,MAAM,EAAE,cAAc,KAAK,IAAI,CAAC;IAChD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;CACrC;AAED,eAAO,MAAM,QAAQ,iCAAqD,CAAC;AAE3E,yCAAyC;AACzC,eAAO,MAAM,SAAS,SAYlB,CAAC"}
|
package/dist/src/Platform.js
CHANGED
|
@@ -5,6 +5,7 @@ export const PlatformName = Context.GenericTag("@services/PlatformName");
|
|
|
5
5
|
export const FlushSync = Context.GenericTag("@services/FlushSync");
|
|
6
6
|
export const FlushSyncDefaultLive = Layer.succeed(FlushSync, (callback) => callback());
|
|
7
7
|
export const SyncLock = Context.GenericTag("@services/SyncLock");
|
|
8
|
+
export const DbWorkerLock = Context.GenericTag("@services/DbWorkerLock");
|
|
8
9
|
export const Fetch = Context.GenericTag("@services/Fetch");
|
|
9
10
|
export const FetchLive = Layer.succeed(Fetch, Fetch.of((url, body) => Effect.tryPromise({
|
|
10
11
|
try: () => fetch(url, {
|
package/dist/src/Sql.d.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
export declare const selectOwner
|
|
2
|
-
export declare const createMessageTable
|
|
3
|
-
export declare const createMessageTableIndex
|
|
4
|
-
export declare const createOwnerTable
|
|
5
|
-
export declare const insertOwner
|
|
6
|
-
export declare const selectOwnerTimestampAndMerkleTree
|
|
7
|
-
export declare const selectLastTimestampForTableRowColumn
|
|
1
|
+
export declare const selectOwner: string;
|
|
2
|
+
export declare const createMessageTable: string;
|
|
3
|
+
export declare const createMessageTableIndex: string;
|
|
4
|
+
export declare const createOwnerTable: string;
|
|
5
|
+
export declare const insertOwner: string;
|
|
6
|
+
export declare const selectOwnerTimestampAndMerkleTree: string;
|
|
7
|
+
export declare const selectLastTimestampForTableRowColumn: string;
|
|
8
8
|
export declare const upsertValueIntoTableRowColumn: (table: string, column: string) => string;
|
|
9
9
|
export declare const deleteTableRow: (table: string) => string;
|
|
10
|
-
export declare const insertIntoMessagesIfNew
|
|
11
|
-
export declare const updateOwnerTimestampAndMerkleTree
|
|
12
|
-
export declare const selectMessagesToSync
|
|
10
|
+
export declare const insertIntoMessagesIfNew: string;
|
|
11
|
+
export declare const updateOwnerTimestampAndMerkleTree: string;
|
|
12
|
+
export declare const selectMessagesToSync: string;
|
|
13
13
|
//# sourceMappingURL=Sql.d.ts.map
|
package/dist/src/Sql.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Sql.d.ts","sourceRoot":"","sources":["../../src/Sql.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,WAAW,
|
|
1
|
+
{"version":3,"file":"Sql.d.ts","sourceRoot":"","sources":["../../src/Sql.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,WAAW,QAOhB,CAAC;AAET,eAAO,MAAM,kBAAkB,QASvB,CAAC;AAET,eAAO,MAAM,uBAAuB,QAI5B,CAAC;AAET,eAAO,MAAM,gBAAgB,QASrB,CAAC;AAET,eAAO,MAAM,WAAW,QAWhB,CAAC;AAET,eAAO,MAAM,iCAAiC,QAMtC,CAAC;AAET,eAAO,MAAM,oCAAoC,QAazC,CAAC;AAET,eAAO,MAAM,6BAA6B,UACjC,MAAM,UACL,MAAM,KACb,MASK,CAAC;AAET,eAAO,MAAM,cAAc,UAAW,MAAM,KAAG,MAKvC,CAAC;AAET,eAAO,MAAM,uBAAuB,QAM5B,CAAC;AAET,eAAO,MAAM,iCAAiC,QAKtC,CAAC;AAET,eAAO,MAAM,oBAAoB,QASzB,CAAC"}
|
package/dist/src/Sql.js
CHANGED
|
@@ -2,30 +2,30 @@
|
|
|
2
2
|
// The reason for not using Kysely directly is bundle size.
|
|
3
3
|
// [Playground Link](https://kyse.link/?p=b&i=haFkpnNxbGl0ZaF2pjAuMjYuMKFz2gFoaW1wb3J0IHsgR2VuZXJhdGVkIH0gZnJvbSAna3lzZWx5JwoKZGVjbGFyZSBnbG9iYWwgewogIGludGVyZmFjZSBEQiB7CiAgICBldm9sdV9tZXNzYWdlOiB7CiAgICAgIHRpbWVzdGFtcDogc3RyaW5nLAogICAgICB0YWJsZTogc3RyaW5nLAogICAgICByb3c6IHN0cmluZywKICAgICAgY29sdW1uOiBzdHJpbmcsCiAgICAgIHZhbHVlOiB1bmtub3duCiAgICB9LAoKICAgIGV2b2x1X293bmVyOiB7CiAgICAgIGlkOiBzdHJpbmcKICAgICAgbW5lbW9uaWM6IHN0cmluZwogICAgICBlbmNyeXB0aW9uS2V5OiBVaW50OEFycmF5LAogICAgICB0aW1lc3RhbXA6IHN0cmluZywKICAgICAgbWVya2xlVHJlZTogc3RyaW5nCiAgICB9CiAgfQp9oXHaBnhhd2FpdCBreXNlbHkuc2VsZWN0RnJvbSgiZXZvbHVfb3duZXIiKQogIC5zZWxlY3QoWyJpZCIsICJtbmVtb25pYyIsICJlbmNyeXB0aW9uS2V5Il0pCiAgLmV4ZWN1dGUoKQoKYXdhaXQga3lzZWx5LnNjaGVtYQogIC5jcmVhdGVUYWJsZSgnZXZvbHVfbWVzc2FnZScpCiAgLmFkZENvbHVtbigndGltZXN0YW1wJywgJ2Jsb2InLCBjb2wgPT4gY29sLnByaW1hcnlLZXkoKSkKICAuYWRkQ29sdW1uKCd0YWJsZScsICdibG9iJykKICAuYWRkQ29sdW1uKCdyb3cnLCAnYmxvYicpCiAgLmFkZENvbHVtbignY29sdW1uJywgJ2Jsb2InKQogIC5hZGRDb2x1bW4oJ3ZhbHVlJywgJ2Jsb2InKQogIC5leGVjdXRlKCkKCmF3YWl0IGt5c2VseS5zY2hlbWEKICAuY3JlYXRlSW5kZXgoImluZGV4X2V2b2x1X21lc3NhZ2UiKQogIC5vbigiZXZvbHVfbWVzc2FnZSIpCiAgLmNvbHVtbnMoWyJ0YWJsZSIsICJyb3ciLCAiY29sdW1uIiwgInRpbWVzdGFtcCJdKQogIC5leGVjdXRlKCkKCmF3YWl0IGt5c2VseS5zY2hlbWEKICAuY3JlYXRlVGFibGUoJ2V2b2x1X19vd25lcicpCiAgLmFkZENvbHVtbignaWQnLCAnYmxvYicpCiAgLmFkZENvbHVtbignbW5lbW9uaWMnLCAnYmxvYicpCiAgLmFkZENvbHVtbignZW5jcnlwdGlvbktleScsICdibG9iJykKICAuYWRkQ29sdW1uKCd0aW1lc3RhbXAnLCAnYmxvYicpCiAgLmFkZENvbHVtbignbWVya2xlVHJlZScsICdibG9iJykKICAuZXhlY3V0ZSgpCgphd2FpdCBreXNlbHkuaW5zZXJ0SW50bygiZXZvbHVfb3duZXIiKQogIC52YWx1ZXMoewogICAgImlkIjogImIiLAogICAgIm1uZW1vbmljIjogImEiLAogICAgImVuY3J5cHRpb25LZXkiOiBuZXcgVWludDhBcnJheSgpLAogICAgInRpbWVzdGFtcCI6ICJhIiwKICAgICJtZXJrbGVUcmVlIjogImIiCiAgfSkKICAuZXhlY3V0ZSgpCgphd2FpdCBreXNlbHkuc2VsZWN0RnJvbSgiZXZvbHVfb3duZXIiKQogIC5zZWxlY3QoWyJ0aW1lc3RhbXAiLCAibWVya2xlVHJlZSJdKQogIC5leGVjdXRlKCkKCmF3YWl0IGt5c2VseS5zZWxlY3RGcm9tKCJldm9sdV9tZXNzYWdlIikKICAuc2VsZWN0KCJ0aW1lc3RhbXAiKQogIC53aGVyZSgndGFibGUnLCAnPScsICcxJykKICAud2hlcmUoJ3JvdycsICc9JywgJzInKQogIC53aGVyZSgnY29sdW1uJywgJz0nLCAnMycpCiAgLm9yZGVyQnkoInRpbWVzdGFtcCIsICJkZXNjIikKICAubGltaXQoMSkKICAuZXhlY3V0ZVRha2VGaXJzdCgpCgphd2FpdCBreXNlbHkuaW5zZXJ0SW50bygiZXZvbHVfbWVzc2FnZSIpCiAgLnZhbHVlcyh7CiAgICAidGltZXN0YW1wIjogJzEnLAogICAgInRhYmxlIjogJzInLAogICAgInJvdyI6ICczJywKICAgICJjb2x1bW4iOiAnNCcsCiAgICAidmFsdWUiOiAnNScsCiAgfSkKICAub25Db25mbGljdChvYyA9PiBvYy5kb05vdGhpbmcoKSkKICAuZXhlY3V0ZSgpCgphd2FpdCBreXNlbHkudXBkYXRlVGFibGUoImV2b2x1X293bmVyIikKICAuc2V0KHsKICAgICJtZXJrbGVUcmVlIjogJzEnLAogICAgInRpbWVzdGFtcCI6ICIyIgogIH0pCiAgLmV4ZWN1dGUoKQoKYXdhaXQga3lzZWx5LnNlbGVjdEZyb20oImV2b2x1X21lc3NhZ2UiKQogIC5zZWxlY3RBbGwoKQogIC53aGVyZSgidGltZXN0YW1wIiwgIj49IiwgJzEnKQogIC5vcmRlckJ5KCJ0aW1lc3RhbXAiKQogIC5leGVjdXRlKCmhY8M=)
|
|
4
4
|
export const selectOwner = `
|
|
5
|
-
|
|
5
|
+
select
|
|
6
6
|
"id",
|
|
7
7
|
"mnemonic",
|
|
8
8
|
"encryptionKey"
|
|
9
|
-
|
|
9
|
+
from
|
|
10
10
|
"evolu_owner"
|
|
11
|
-
|
|
11
|
+
`.trim();
|
|
12
12
|
export const createMessageTable = `
|
|
13
|
-
|
|
13
|
+
create table
|
|
14
14
|
"evolu_message" (
|
|
15
|
-
"timestamp" blob
|
|
15
|
+
"timestamp" blob primary key,
|
|
16
16
|
"table" blob,
|
|
17
17
|
"row" blob,
|
|
18
18
|
"column" blob,
|
|
19
19
|
"value" blob
|
|
20
20
|
);
|
|
21
|
-
|
|
21
|
+
`.trim();
|
|
22
22
|
export const createMessageTableIndex = `
|
|
23
|
-
|
|
23
|
+
create index "index_evolu_message" on "evolu_message" (
|
|
24
24
|
"table", "row", "column", "timestamp"
|
|
25
25
|
);
|
|
26
|
-
|
|
26
|
+
`.trim();
|
|
27
27
|
export const createOwnerTable = `
|
|
28
|
-
|
|
28
|
+
create table
|
|
29
29
|
"evolu_owner" (
|
|
30
30
|
"id" blob,
|
|
31
31
|
"mnemonic" blob,
|
|
@@ -33,9 +33,9 @@ CREATE TABLE
|
|
|
33
33
|
"timestamp" blob,
|
|
34
34
|
"merkleTree" blob
|
|
35
35
|
);
|
|
36
|
-
|
|
36
|
+
`.trim();
|
|
37
37
|
export const insertOwner = `
|
|
38
|
-
|
|
38
|
+
insert into
|
|
39
39
|
"evolu_owner" (
|
|
40
40
|
"id",
|
|
41
41
|
"mnemonic",
|
|
@@ -43,63 +43,64 @@ INSERT INTO
|
|
|
43
43
|
"timestamp",
|
|
44
44
|
"merkleTree"
|
|
45
45
|
)
|
|
46
|
-
|
|
46
|
+
values
|
|
47
47
|
(?, ?, ?, ?, ?);
|
|
48
|
-
|
|
48
|
+
`.trim();
|
|
49
49
|
export const selectOwnerTimestampAndMerkleTree = `
|
|
50
|
-
|
|
50
|
+
select
|
|
51
51
|
"timestamp",
|
|
52
52
|
"merkleTree"
|
|
53
|
-
|
|
53
|
+
from
|
|
54
54
|
"evolu_owner"
|
|
55
|
-
|
|
55
|
+
`.trim();
|
|
56
56
|
export const selectLastTimestampForTableRowColumn = `
|
|
57
|
-
|
|
57
|
+
select
|
|
58
58
|
"timestamp"
|
|
59
|
-
|
|
59
|
+
from
|
|
60
60
|
"evolu_message"
|
|
61
|
-
|
|
61
|
+
where
|
|
62
62
|
"table" = ?
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
"timestamp"
|
|
67
|
-
|
|
63
|
+
and "row" = ?
|
|
64
|
+
and "column" = ?
|
|
65
|
+
order by
|
|
66
|
+
"timestamp" desc
|
|
67
|
+
limit
|
|
68
68
|
1
|
|
69
|
-
|
|
69
|
+
`.trim();
|
|
70
70
|
export const upsertValueIntoTableRowColumn = (table, column) => `
|
|
71
|
-
|
|
72
|
-
"${table}" ("id", "${column}")
|
|
73
|
-
|
|
74
|
-
(?, ?)
|
|
75
|
-
|
|
76
|
-
"${column}" =
|
|
77
|
-
|
|
71
|
+
insert into
|
|
72
|
+
"${table}" ("id", "${column}", "createdAt", "updatedAt")
|
|
73
|
+
values
|
|
74
|
+
(?, ?, ?, ?)
|
|
75
|
+
on conflict do update set
|
|
76
|
+
"${column}" = ?,
|
|
77
|
+
"updatedAt" = ?
|
|
78
|
+
`.trim();
|
|
78
79
|
export const deleteTableRow = (table) => `
|
|
79
|
-
|
|
80
|
-
|
|
80
|
+
delete from "${table}"
|
|
81
|
+
where
|
|
81
82
|
"id" = ?;
|
|
82
|
-
|
|
83
|
+
`.trim();
|
|
83
84
|
export const insertIntoMessagesIfNew = `
|
|
84
|
-
|
|
85
|
+
insert into
|
|
85
86
|
"evolu_message" ("timestamp", "table", "row", "column", "value")
|
|
86
|
-
|
|
87
|
+
values
|
|
87
88
|
(?, ?, ?, ?, ?)
|
|
88
|
-
|
|
89
|
-
|
|
89
|
+
on conflict do nothing
|
|
90
|
+
`.trim();
|
|
90
91
|
export const updateOwnerTimestampAndMerkleTree = `
|
|
91
|
-
|
|
92
|
-
|
|
92
|
+
update "evolu_owner"
|
|
93
|
+
set
|
|
93
94
|
"timestamp" = ?,
|
|
94
95
|
"merkleTree" = ?
|
|
95
|
-
|
|
96
|
+
`.trim();
|
|
96
97
|
export const selectMessagesToSync = `
|
|
97
|
-
|
|
98
|
+
select
|
|
98
99
|
*
|
|
99
|
-
|
|
100
|
+
from
|
|
100
101
|
"evolu_message"
|
|
101
|
-
|
|
102
|
+
where
|
|
102
103
|
"timestamp" >= ?
|
|
103
|
-
|
|
104
|
+
order by
|
|
104
105
|
"timestamp"
|
|
105
|
-
|
|
106
|
+
`.trim();
|
package/dist/src/Sqlite.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import * as Context from "effect/Context";
|
|
|
2
2
|
import * as Effect from "effect/Effect";
|
|
3
3
|
import * as Predicate from "effect/Predicate";
|
|
4
4
|
export interface Sqlite {
|
|
5
|
-
readonly exec: (arg: string | SqliteQuery) => Effect.Effect<
|
|
5
|
+
readonly exec: (arg: string | SqliteQuery) => Effect.Effect<SqliteExecResult>;
|
|
6
6
|
}
|
|
7
7
|
export declare const Sqlite: Context.Tag<Sqlite, Sqlite>;
|
|
8
8
|
export interface SqliteQuery {
|
|
@@ -18,7 +18,7 @@ type JsonObject = {
|
|
|
18
18
|
type JsonArray = ReadonlyArray<Json>;
|
|
19
19
|
type JsonPrimitive = string | number | boolean | null;
|
|
20
20
|
type Json = JsonPrimitive | JsonObject | JsonArray;
|
|
21
|
-
interface
|
|
21
|
+
export interface SqliteExecResult {
|
|
22
22
|
readonly rows: SqliteRow[];
|
|
23
23
|
readonly changes: number;
|
|
24
24
|
}
|
|
@@ -28,5 +28,6 @@ export declare const valuesToSqliteValues: (values: ReadonlyArray<Value>) => Sql
|
|
|
28
28
|
export declare const ensureSqliteQuery: (arg: string | SqliteQuery) => SqliteQuery;
|
|
29
29
|
export declare const maybeParseJson: (rows: SqliteRow[]) => SqliteRow[];
|
|
30
30
|
export declare const maybeJson: Predicate.Predicate<string>;
|
|
31
|
+
export declare const isSqlMutation: (sql: string) => boolean;
|
|
31
32
|
export {};
|
|
32
33
|
//# sourceMappingURL=Sqlite.d.ts.map
|
package/dist/src/Sqlite.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Sqlite.d.ts","sourceRoot":"","sources":["../../src/Sqlite.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,gBAAgB,CAAC;AAC1C,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,SAAS,MAAM,kBAAkB,CAAC;AAE9C,MAAM,WAAW,MAAM;IACrB,QAAQ,CAAC,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,GAAG,WAAW,KAAK,MAAM,CAAC,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"Sqlite.d.ts","sourceRoot":"","sources":["../../src/Sqlite.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,gBAAgB,CAAC;AAC1C,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,SAAS,MAAM,kBAAkB,CAAC;AAE9C,MAAM,WAAW,MAAM;IACrB,QAAQ,CAAC,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,GAAG,WAAW,KAAK,MAAM,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC;CAC/E;AAED,eAAO,MAAM,MAAM,6BAAiD,CAAC;AAErE,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,UAAU,EAAE,KAAK,EAAE,CAAC;CAC9B;AAED,MAAM,MAAM,KAAK,GAAG,WAAW,GAAG,iBAAiB,CAAC;AACpD,MAAM,MAAM,WAAW,GAAG,IAAI,GAAG,MAAM,GAAG,MAAM,GAAG,UAAU,CAAC;AAC9D,MAAM,MAAM,iBAAiB,GAAG,UAAU,GAAG,SAAS,CAAC;AACvD,KAAK,UAAU,GAAG;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC;AAC1C,KAAK,SAAS,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;AACrC,KAAK,aAAa,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC;AACtD,KAAK,IAAI,GAAG,aAAa,GAAG,UAAU,GAAG,SAAS,CAAC;AAEnD,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,IAAI,EAAE,SAAS,EAAE,CAAC;IAC3B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;AAEpD,eAAO,MAAM,mBAAmB,EAAE,SAAS,CAAC,UAAU,CACpD,KAAK,EACL,iBAAiB,CAE4D,CAAC;AAEhF,eAAO,MAAM,oBAAoB,WACvB,cAAc,KAAK,CAAC,KAC3B,WAAW,EAGX,CAAC;AAEJ,eAAO,MAAM,iBAAiB,QAAS,MAAM,GAAG,WAAW,KAAG,WAG7D,CAAC;AAEF,eAAO,MAAM,cAAc,SAAU,SAAS,EAAE,KAAG,SAAS,EAC1C,CAAC;AA0BnB,eAAO,MAAM,SAAS,EAAE,SAAS,CAAC,SAAS,CAAC,MAAM,CACpB,CAAC;AAoB/B,eAAO,MAAM,aAAa,QAAS,MAAM,KAAG,OACd,CAAC"}
|
package/dist/src/Sqlite.js
CHANGED
|
@@ -40,3 +40,14 @@ const parseObject = (o) => {
|
|
|
40
40
|
o[key] = parse(o[key]);
|
|
41
41
|
return o;
|
|
42
42
|
};
|
|
43
|
+
/** This is good enough detection because SQL strings in Evolu are predictable. */
|
|
44
|
+
const isSqlMutationRegEx = new RegExp(`\\b(${[
|
|
45
|
+
"alter",
|
|
46
|
+
"create",
|
|
47
|
+
"delete",
|
|
48
|
+
"drop",
|
|
49
|
+
"insert",
|
|
50
|
+
"replace",
|
|
51
|
+
"update",
|
|
52
|
+
].join("|")})\\b`);
|
|
53
|
+
export const isSqlMutation = (sql) => isSqlMutationRegEx.test(sql);
|
package/dist/src/SyncWorker.d.ts
CHANGED
|
@@ -8,9 +8,8 @@ import { Id } from "./Model.js";
|
|
|
8
8
|
import { Owner } from "./Owner.js";
|
|
9
9
|
import { Fetch, SyncLock } from "./Platform.js";
|
|
10
10
|
import { Value } from "./Sqlite.js";
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
onMessage: (output: SyncWorkerOutput) => void;
|
|
11
|
+
import { Messaging } from "./Types.js";
|
|
12
|
+
export interface SyncWorker extends Messaging<SyncWorkerInput, SyncWorkerOutput> {
|
|
14
13
|
}
|
|
15
14
|
export declare const SyncWorker: Context.Tag<SyncWorker, SyncWorker>;
|
|
16
15
|
export type SyncWorkerPostMessage = SyncWorker["postMessage"];
|
|
@@ -76,6 +75,6 @@ export interface SyncStateServerError {
|
|
|
76
75
|
export interface SyncStatePaymentRequiredError {
|
|
77
76
|
readonly _tag: "PaymentRequiredError";
|
|
78
77
|
}
|
|
79
|
-
export declare const
|
|
78
|
+
export declare const SyncWorkerCommonLive: Layer.Layer<SyncWorker, never, SecretBox | SyncLock | Fetch>;
|
|
80
79
|
export {};
|
|
81
80
|
//# sourceMappingURL=SyncWorker.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SyncWorker.d.ts","sourceRoot":"","sources":["../../src/SyncWorker.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,OAAO,MAAM,gBAAgB,CAAC;AAE1C,OAAO,KAAK,WAAW,MAAM,oBAAoB,CAAC;AAGlD,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AAKtC,OAAO,EACL,UAAU,EACV,MAAM,EACN,SAAS,EACT,eAAe,EAGhB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,eAAe,EAAuB,MAAM,iBAAiB,CAAC;AACvE,OAAO,EAAE,EAAE,EAAE,MAAM,YAAY,CAAC;AAChC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAOhD,OAAO,EAAqB,KAAK,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"SyncWorker.d.ts","sourceRoot":"","sources":["../../src/SyncWorker.ts"],"names":[],"mappings":"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"}
|
package/dist/src/SyncWorker.js
CHANGED
|
@@ -131,7 +131,7 @@ const sync = (input) => Effect.gen(function* (_) {
|
|
|
131
131
|
syncLoopCount: input.syncLoopCount,
|
|
132
132
|
})))), Effect.tapError(() => syncLock.release), Effect.merge, Effect.map(syncWorkerOnMessage));
|
|
133
133
|
});
|
|
134
|
-
export const
|
|
134
|
+
export const SyncWorkerCommonLive = Layer.effect(SyncWorker, Effect.gen(function* (_) {
|
|
135
135
|
const syncLock = yield* _(SyncLock);
|
|
136
136
|
const onError = (error) => Effect.sync(() => {
|
|
137
137
|
syncWorker.onMessage(error);
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Add types for WebWorker and BroadcastChannel. Messages must have a `_tag`
|
|
3
|
+
* property.
|
|
4
|
+
*/
|
|
5
|
+
export interface Messaging<Input extends {
|
|
6
|
+
_tag: string;
|
|
7
|
+
}, Output extends {
|
|
8
|
+
_tag: string;
|
|
9
|
+
}> {
|
|
10
|
+
readonly postMessage: (input: Input) => void;
|
|
11
|
+
onMessage: (output: Output) => void;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=Types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Types.d.ts","sourceRoot":"","sources":["../../src/Types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,WAAW,SAAS,CACxB,KAAK,SAAS;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,EAC9B,MAAM,SAAS;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE;IAE/B,QAAQ,CAAC,WAAW,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IAC7C,SAAS,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;CACrC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@evolu/common",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.1",
|
|
4
4
|
"description": "Local-first platform designed for privacy, ease of use, and no vendor lock-in to sync and backup people's lifetime data",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"evolu",
|
|
@@ -52,11 +52,11 @@
|
|
|
52
52
|
"nanoid": "^5.0.6"
|
|
53
53
|
},
|
|
54
54
|
"devDependencies": {
|
|
55
|
-
"@effect/schema": "^0.63.
|
|
55
|
+
"@effect/schema": "^0.63.2",
|
|
56
56
|
"@protobuf-ts/plugin": "^2.9.3",
|
|
57
57
|
"@protobuf-ts/protoc": "^2.9.3",
|
|
58
58
|
"array-shuffle": "^3.0.0",
|
|
59
|
-
"effect": "2.4.
|
|
59
|
+
"effect": "2.4.1",
|
|
60
60
|
"eslint": "^8.57.0",
|
|
61
61
|
"typescript": "^5.3.3",
|
|
62
62
|
"vitest": "^1.3.1",
|
|
@@ -64,8 +64,8 @@
|
|
|
64
64
|
"eslint-config-evolu": "1.0.0"
|
|
65
65
|
},
|
|
66
66
|
"peerDependencies": {
|
|
67
|
-
"@effect/schema": "^0.63.
|
|
68
|
-
"effect": "2.4.
|
|
67
|
+
"@effect/schema": "^0.63.2",
|
|
68
|
+
"effect": "2.4.1"
|
|
69
69
|
},
|
|
70
70
|
"publishConfig": {
|
|
71
71
|
"access": "public"
|
package/src/Config.ts
CHANGED
|
@@ -16,6 +16,13 @@ export interface Config {
|
|
|
16
16
|
* 1000 (5 minutes).
|
|
17
17
|
*/
|
|
18
18
|
readonly maxDrift: number;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Evolu application name. For now, this is only useful for localhost
|
|
22
|
+
* development, where we want each application to have its own database. The
|
|
23
|
+
* default value is: "Evolu".
|
|
24
|
+
*/
|
|
25
|
+
readonly name: string;
|
|
19
26
|
}
|
|
20
27
|
|
|
21
28
|
export const Config = Context.GenericTag<Config>("@services/Config");
|
|
@@ -27,6 +34,7 @@ export const ConfigLive = (config?: Partial<Config>): Layer.Layer<Config> =>
|
|
|
27
34
|
syncUrl: "https://evolu.world",
|
|
28
35
|
maxDrift: 5 * 60 * 1000,
|
|
29
36
|
reloadUrl: "/",
|
|
37
|
+
name: "Evolu",
|
|
30
38
|
...config,
|
|
31
39
|
}),
|
|
32
40
|
);
|
package/src/Crdt.ts
CHANGED
|
@@ -10,7 +10,7 @@ import * as Option from "effect/Option";
|
|
|
10
10
|
import * as ReadonlyArray from "effect/ReadonlyArray";
|
|
11
11
|
import * as String from "effect/String";
|
|
12
12
|
import { Config } from "./Config.js";
|
|
13
|
-
import {
|
|
13
|
+
import { NanoIdGenerator, NodeId } from "./Crypto.js";
|
|
14
14
|
import { murmurhash } from "./Murmurhash.js";
|
|
15
15
|
|
|
16
16
|
// https://muratbuffalo.blogspot.com/2014/07/hybrid-logical-clocks.html
|
|
@@ -86,7 +86,7 @@ export const makeSyncTimestamp = (
|
|
|
86
86
|
node: syncNodeId,
|
|
87
87
|
});
|
|
88
88
|
|
|
89
|
-
export const makeInitialTimestamp =
|
|
89
|
+
export const makeInitialTimestamp = NanoIdGenerator.pipe(
|
|
90
90
|
Effect.flatMap(({ nanoidAsNodeId }) => nanoidAsNodeId),
|
|
91
91
|
Effect.map(
|
|
92
92
|
(node): Timestamp => ({
|
package/src/Crypto.ts
CHANGED
|
@@ -36,12 +36,16 @@ export interface InvalidMnemonicError {
|
|
|
36
36
|
*/
|
|
37
37
|
export type Mnemonic = string & Brand.Brand<"Mnemonic">;
|
|
38
38
|
|
|
39
|
-
export interface
|
|
40
|
-
readonly nanoid: Effect.Effect<
|
|
39
|
+
export interface NanoIdGenerator {
|
|
40
|
+
readonly nanoid: Effect.Effect<NanoId>;
|
|
41
41
|
readonly nanoidAsNodeId: Effect.Effect<NodeId>;
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
export const
|
|
44
|
+
export const NanoIdGenerator = Context.GenericTag<NanoIdGenerator>(
|
|
45
|
+
"@services/NanoIdGenerator",
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
export type NanoId = string & Brand.Brand<"NanoId">;
|
|
45
49
|
|
|
46
50
|
export const NodeId = S.string.pipe(
|
|
47
51
|
S.pattern(/^[\w-]{16}$/),
|
|
@@ -51,10 +55,10 @@ export type NodeId = S.Schema.To<typeof NodeId>;
|
|
|
51
55
|
|
|
52
56
|
const nanoidForNodeId = customAlphabet("0123456789abcdef", 16);
|
|
53
57
|
|
|
54
|
-
export const
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
nanoid: Effect.sync(() => nanoid()),
|
|
58
|
+
export const NanoIdGeneratorLive = Layer.succeed(
|
|
59
|
+
NanoIdGenerator,
|
|
60
|
+
NanoIdGenerator.of({
|
|
61
|
+
nanoid: Effect.sync(() => nanoid() as NanoId),
|
|
58
62
|
nanoidAsNodeId: Effect.sync(() => nanoidForNodeId() as NodeId),
|
|
59
63
|
}),
|
|
60
64
|
);
|
package/src/Db.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import * as AST from "@effect/schema/AST";
|
|
2
2
|
import * as S from "@effect/schema/Schema";
|
|
3
3
|
import { make } from "@effect/schema/Schema";
|
|
4
|
-
import { bytesToHex } from "@noble/ciphers/utils";
|
|
5
4
|
import * as Brand from "effect/Brand";
|
|
6
5
|
import * as Context from "effect/Context";
|
|
7
6
|
import * as Effect from "effect/Effect";
|
|
@@ -21,7 +20,7 @@ import {
|
|
|
21
20
|
merkleTreeToString,
|
|
22
21
|
timestampToString,
|
|
23
22
|
} from "./Crdt.js";
|
|
24
|
-
import { Bip39, Mnemonic,
|
|
23
|
+
import { Bip39, Mnemonic, NanoIdGenerator } from "./Crypto.js";
|
|
25
24
|
import { EvoluTypeError } from "./ErrorStore.js";
|
|
26
25
|
import { Id, SqliteBoolean, SqliteDate } from "./Model.js";
|
|
27
26
|
import { Owner, makeOwner } from "./Owner.js";
|
|
@@ -288,10 +287,10 @@ export const transaction = <R, E, A>(
|
|
|
288
287
|
): Effect.Effect<A, E, Sqlite | R> =>
|
|
289
288
|
Effect.flatMap(Sqlite, (sqlite) =>
|
|
290
289
|
Effect.acquireUseRelease(
|
|
291
|
-
sqlite.exec("
|
|
290
|
+
sqlite.exec("begin"),
|
|
292
291
|
() => effect,
|
|
293
292
|
(_, exit) =>
|
|
294
|
-
Exit.isFailure(exit) ? sqlite.exec("
|
|
293
|
+
Exit.isFailure(exit) ? sqlite.exec("rollback") : sqlite.exec("end"),
|
|
295
294
|
),
|
|
296
295
|
);
|
|
297
296
|
|
|
@@ -323,7 +322,7 @@ export const someDefectToNoSuchTableOrColumnError = Effect.catchSomeDefect(
|
|
|
323
322
|
|
|
324
323
|
export const lazyInit = (
|
|
325
324
|
mnemonic?: Mnemonic,
|
|
326
|
-
): Effect.Effect<Owner, never, Sqlite | Bip39 |
|
|
325
|
+
): Effect.Effect<Owner, never, Sqlite | Bip39 | NanoIdGenerator> =>
|
|
327
326
|
Effect.gen(function* (_) {
|
|
328
327
|
const [owner, sqlite, initialTimestampString] = yield* _(
|
|
329
328
|
Effect.all([makeOwner(mnemonic), Sqlite, makeInitialTimestamp], {
|
|
@@ -341,8 +340,7 @@ export const lazyInit = (
|
|
|
341
340
|
parameters: [
|
|
342
341
|
owner.id,
|
|
343
342
|
owner.mnemonic,
|
|
344
|
-
|
|
345
|
-
bytesToHex(owner.encryptionKey),
|
|
343
|
+
owner.encryptionKey,
|
|
346
344
|
timestampToString(initialTimestampString),
|
|
347
345
|
merkleTreeToString(initialMerkleTree),
|
|
348
346
|
],
|
|
@@ -359,7 +357,7 @@ const getTables: Effect.Effect<
|
|
|
359
357
|
Sqlite
|
|
360
358
|
> = Sqlite.pipe(
|
|
361
359
|
Effect.flatMap((sqlite) =>
|
|
362
|
-
sqlite.exec(`
|
|
360
|
+
sqlite.exec(`select "name" from "sqlite_schema" where "type" = 'table'`),
|
|
363
361
|
),
|
|
364
362
|
Effect.map((result) => result.rows),
|
|
365
363
|
Effect.map(ReadonlyArray.map((row) => (row.name as string) + "")),
|
|
@@ -374,7 +372,7 @@ const updateTable = ({
|
|
|
374
372
|
Effect.gen(function* (_) {
|
|
375
373
|
const sqlite = yield* _(Sqlite);
|
|
376
374
|
const sql = yield* _(
|
|
377
|
-
sqlite.exec(`
|
|
375
|
+
sqlite.exec(`pragma table_info (${name})`),
|
|
378
376
|
Effect.map((result) => result.rows),
|
|
379
377
|
Effect.map(ReadonlyArray.map((row) => row.name as string)),
|
|
380
378
|
Effect.map((existingColumns) =>
|
|
@@ -385,7 +383,7 @@ const updateTable = ({
|
|
|
385
383
|
Effect.map(
|
|
386
384
|
ReadonlyArray.map(
|
|
387
385
|
(newColumn) =>
|
|
388
|
-
`
|
|
386
|
+
`alter table "${name}" add column "${newColumn}" blob;`,
|
|
389
387
|
),
|
|
390
388
|
),
|
|
391
389
|
Effect.map(ReadonlyArray.join("")),
|
|
@@ -399,7 +397,7 @@ const createTable = ({
|
|
|
399
397
|
}: Table): Effect.Effect<void, never, Sqlite> =>
|
|
400
398
|
Effect.flatMap(Sqlite, (sqlite) =>
|
|
401
399
|
sqlite.exec(`
|
|
402
|
-
|
|
400
|
+
create table ${name} (
|
|
403
401
|
"id" text primary key,
|
|
404
402
|
${columns
|
|
405
403
|
.filter((c) => c !== "id")
|