@evolu/common 1.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.
Files changed (79) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +205 -0
  3. package/dist/src/Config.d.ts +20 -0
  4. package/dist/src/Config.d.ts.map +1 -0
  5. package/dist/src/Config.js +8 -0
  6. package/dist/src/Crypto.d.ts +42 -0
  7. package/dist/src/Crypto.d.ts.map +1 -0
  8. package/dist/src/Crypto.js +44 -0
  9. package/dist/src/Db.d.ts +60 -0
  10. package/dist/src/Db.d.ts.map +1 -0
  11. package/dist/src/Db.js +118 -0
  12. package/dist/src/DbWorker.d.ts +78 -0
  13. package/dist/src/DbWorker.d.ts.map +1 -0
  14. package/dist/src/DbWorker.js +282 -0
  15. package/dist/src/Diff.d.ts +19 -0
  16. package/dist/src/Diff.d.ts.map +1 -0
  17. package/dist/src/Diff.js +86 -0
  18. package/dist/src/Errors.d.ts +19 -0
  19. package/dist/src/Errors.d.ts.map +1 -0
  20. package/dist/src/Errors.js +11 -0
  21. package/dist/src/Evolu.d.ts +71 -0
  22. package/dist/src/Evolu.d.ts.map +1 -0
  23. package/dist/src/Evolu.js +235 -0
  24. package/dist/src/MerkleTree.d.ts +15 -0
  25. package/dist/src/MerkleTree.d.ts.map +1 -0
  26. package/dist/src/MerkleTree.js +49 -0
  27. package/dist/src/Model.d.ts +143 -0
  28. package/dist/src/Model.d.ts.map +1 -0
  29. package/dist/src/Model.js +103 -0
  30. package/dist/src/Murmurhash.d.ts +2 -0
  31. package/dist/src/Murmurhash.d.ts.map +1 -0
  32. package/dist/src/Murmurhash.js +60 -0
  33. package/dist/src/Platform.d.ts +29 -0
  34. package/dist/src/Platform.d.ts.map +1 -0
  35. package/dist/src/Platform.js +17 -0
  36. package/dist/src/Protobuf.d.ts +130 -0
  37. package/dist/src/Protobuf.d.ts.map +1 -0
  38. package/dist/src/Protobuf.js +100 -0
  39. package/dist/src/Public.d.ts +7 -0
  40. package/dist/src/Public.d.ts.map +1 -0
  41. package/dist/src/Public.js +2 -0
  42. package/dist/src/Sql.d.ts +12 -0
  43. package/dist/src/Sql.d.ts.map +1 -0
  44. package/dist/src/Sql.js +100 -0
  45. package/dist/src/Sqlite.d.ts +30 -0
  46. package/dist/src/Sqlite.d.ts.map +1 -0
  47. package/dist/src/Sqlite.js +41 -0
  48. package/dist/src/Store.d.ts +9 -0
  49. package/dist/src/Store.d.ts.map +1 -0
  50. package/dist/src/Store.js +18 -0
  51. package/dist/src/SyncWorker.d.ts +73 -0
  52. package/dist/src/SyncWorker.d.ts.map +1 -0
  53. package/dist/src/SyncWorker.js +136 -0
  54. package/dist/src/Timestamp.d.ts +44 -0
  55. package/dist/src/Timestamp.d.ts.map +1 -0
  56. package/dist/src/Timestamp.js +76 -0
  57. package/dist/src/index.d.ts +19 -0
  58. package/dist/src/index.d.ts.map +1 -0
  59. package/dist/src/index.js +18 -0
  60. package/package.json +76 -0
  61. package/src/Config.ts +33 -0
  62. package/src/Crypto.ts +113 -0
  63. package/src/Db.ts +323 -0
  64. package/src/DbWorker.ts +683 -0
  65. package/src/Diff.ts +113 -0
  66. package/src/Errors.ts +33 -0
  67. package/src/Evolu.ts +527 -0
  68. package/src/MerkleTree.ts +83 -0
  69. package/src/Model.ts +212 -0
  70. package/src/Murmurhash.ts +70 -0
  71. package/src/Platform.ts +63 -0
  72. package/src/Protobuf.ts +204 -0
  73. package/src/Public.ts +6 -0
  74. package/src/Sql.ts +114 -0
  75. package/src/Sqlite.ts +92 -0
  76. package/src/Store.ts +32 -0
  77. package/src/SyncWorker.ts +344 -0
  78. package/src/Timestamp.ts +192 -0
  79. package/src/index.ts +18 -0
@@ -0,0 +1,17 @@
1
+ import { Context, Effect, Layer } from "effect";
2
+ export const Platform = Context.Tag("evolu/Platform");
3
+ export const FlushSync = Context.Tag("evolu/FlushSync");
4
+ export const SyncLock = Context.Tag("evolu/SyncLock");
5
+ export const Fetch = Context.Tag("evolu/Fetch");
6
+ export const FetchLive = Layer.succeed(Fetch, Fetch.of((url, body) => Effect.tryPromise({
7
+ try: () => fetch(url, {
8
+ method: "POST",
9
+ body,
10
+ headers: {
11
+ "Content-Type": "application/octet-stream",
12
+ "Content-Length": body.length.toString(),
13
+ },
14
+ }),
15
+ catch: () => ({ _tag: "FetchError" }),
16
+ })));
17
+ export const AppState = Context.Tag("evolu/AppState");
@@ -0,0 +1,130 @@
1
+ import { MessageType } from "@protobuf-ts/runtime";
2
+ import { MerkleTreeString } from "./MerkleTree.js";
3
+ import { OwnerId } from "./Db.js";
4
+ import { NodeId } from "./Crypto.js";
5
+ import { TimestampString } from "./Timestamp.js";
6
+ import { Id } from "./Model.js";
7
+ /**
8
+ * @generated from protobuf message SyncRequest
9
+ */
10
+ export interface SyncRequest {
11
+ /**
12
+ * @generated from protobuf field: repeated EncryptedMessage messages = 1;
13
+ */
14
+ messages: ReadonlyArray<EncryptedMessage>;
15
+ /**
16
+ * @generated from protobuf field: string userId = 2;
17
+ */
18
+ userId: OwnerId;
19
+ /**
20
+ * @generated from protobuf field: string nodeId = 3;
21
+ */
22
+ nodeId: NodeId;
23
+ /**
24
+ * @generated from protobuf field: string merkleTree = 4;
25
+ */
26
+ merkleTree: MerkleTreeString;
27
+ }
28
+ /**
29
+ * @generated from protobuf message SyncResponse
30
+ */
31
+ export interface SyncResponse {
32
+ /**
33
+ * @generated from protobuf field: repeated EncryptedMessage messages = 1;
34
+ */
35
+ messages: ReadonlyArray<EncryptedMessage>;
36
+ /**
37
+ * @generated from protobuf field: string merkleTree = 2;
38
+ */
39
+ merkleTree: MerkleTreeString;
40
+ }
41
+ /**
42
+ * @generated from protobuf message EncryptedMessage
43
+ */
44
+ export interface EncryptedMessage {
45
+ /**
46
+ * @generated from protobuf field: string timestamp = 1;
47
+ */
48
+ timestamp: TimestampString;
49
+ /**
50
+ * @generated from protobuf field: bytes content = 2;
51
+ */
52
+ content: Uint8Array;
53
+ }
54
+ /**
55
+ * @generated from protobuf message MessageContent
56
+ */
57
+ export interface MessageContent {
58
+ /**
59
+ * @generated from protobuf field: string table = 1;
60
+ */
61
+ table: string;
62
+ /**
63
+ * @generated from protobuf field: string row = 2;
64
+ */
65
+ row: Id;
66
+ /**
67
+ * @generated from protobuf field: string column = 3;
68
+ */
69
+ column: string;
70
+ /**
71
+ * @generated from protobuf oneof: value
72
+ */
73
+ value: {
74
+ oneofKind: "stringValue";
75
+ /**
76
+ * @generated from protobuf field: string stringValue = 4;
77
+ */
78
+ stringValue: string;
79
+ } | {
80
+ oneofKind: "numberValue";
81
+ /**
82
+ * @generated from protobuf field: int32 numberValue = 5;
83
+ */
84
+ numberValue: number;
85
+ } | {
86
+ oneofKind: "bytesValue";
87
+ /**
88
+ * @generated from protobuf field: bytes bytesValue = 6;
89
+ */
90
+ bytesValue: Uint8Array;
91
+ } | {
92
+ oneofKind: "jsonValue";
93
+ /**
94
+ * @generated from protobuf field: string jsonValue = 7;
95
+ */
96
+ jsonValue: string;
97
+ } | {
98
+ oneofKind: undefined;
99
+ };
100
+ }
101
+ declare class SyncRequest$Type extends MessageType<SyncRequest> {
102
+ constructor();
103
+ }
104
+ /**
105
+ * @generated MessageType for protobuf message SyncRequest
106
+ */
107
+ export declare const SyncRequest: SyncRequest$Type;
108
+ declare class SyncResponse$Type extends MessageType<SyncResponse> {
109
+ constructor();
110
+ }
111
+ /**
112
+ * @generated MessageType for protobuf message SyncResponse
113
+ */
114
+ export declare const SyncResponse: SyncResponse$Type;
115
+ declare class EncryptedMessage$Type extends MessageType<EncryptedMessage> {
116
+ constructor();
117
+ }
118
+ /**
119
+ * @generated MessageType for protobuf message EncryptedMessage
120
+ */
121
+ export declare const EncryptedMessage: EncryptedMessage$Type;
122
+ declare class MessageContent$Type extends MessageType<MessageContent> {
123
+ constructor();
124
+ }
125
+ /**
126
+ * @generated MessageType for protobuf message MessageContent
127
+ */
128
+ export declare const MessageContent: MessageContent$Type;
129
+ export {};
130
+ //# sourceMappingURL=Protobuf.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Protobuf.d.ts","sourceRoot":"","sources":["../../src/Protobuf.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,EAAE,EAAE,MAAM,YAAY,CAAC;AAChC;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B;;OAEG;IACH,QAAQ,EAAE,aAAa,CAAC,gBAAgB,CAAC,CAAC;IAC1C;;OAEG;IACH,MAAM,EAAE,OAAO,CAAC;IAChB;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;IACf;;OAEG;IACH,UAAU,EAAE,gBAAgB,CAAC;CAC9B;AACD;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B;;OAEG;IACH,QAAQ,EAAE,aAAa,CAAC,gBAAgB,CAAC,CAAC;IAC1C;;OAEG;IACH,UAAU,EAAE,gBAAgB,CAAC;CAC9B;AACD;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;OAEG;IACH,SAAS,EAAE,eAAe,CAAC;IAC3B;;OAEG;IACH,OAAO,EAAE,UAAU,CAAC;CACrB;AACD;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;OAEG;IACH,GAAG,EAAE,EAAE,CAAC;IACR;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;IACf;;OAEG;IACH,KAAK,EACD;QACE,SAAS,EAAE,aAAa,CAAC;QACzB;;WAEG;QACH,WAAW,EAAE,MAAM,CAAC;KACrB,GACD;QACE,SAAS,EAAE,aAAa,CAAC;QACzB;;WAEG;QACH,WAAW,EAAE,MAAM,CAAC;KACrB,GACD;QACE,SAAS,EAAE,YAAY,CAAC;QACxB;;WAEG;QACH,UAAU,EAAE,UAAU,CAAC;KACxB,GACD;QACE,SAAS,EAAE,WAAW,CAAC;QACvB;;WAEG;QACH,SAAS,EAAE,MAAM,CAAC;KACnB,GACD;QACE,SAAS,EAAE,SAAS,CAAC;KACtB,CAAC;CACP;AAED,cAAM,gBAAiB,SAAQ,WAAW,CAAC,WAAW,CAAC;;CAetD;AACD;;GAEG;AACH,eAAO,MAAM,WAAW,kBAAyB,CAAC;AAElD,cAAM,iBAAkB,SAAQ,WAAW,CAAC,YAAY,CAAC;;CAaxD;AACD;;GAEG;AACH,eAAO,MAAM,YAAY,mBAA0B,CAAC;AAEpD,cAAM,qBAAsB,SAAQ,WAAW,CAAC,gBAAgB,CAAC;;CAOhE;AACD;;GAEG;AACH,eAAO,MAAM,gBAAgB,uBAA8B,CAAC;AAE5D,cAAM,mBAAoB,SAAQ,WAAW,CAAC,cAAc,CAAC;;CAoC5D;AACD;;GAEG;AACH,eAAO,MAAM,cAAc,qBAA4B,CAAC"}
@@ -0,0 +1,100 @@
1
+ /* eslint-disable */
2
+ // @generated by protobuf-ts 2.9.1 with parameter eslint_disable,optimize_code_size
3
+ // @generated from protobuf file "Protobuf.proto" (syntax proto3)
4
+ // tslint:disable
5
+ import { MessageType } from "@protobuf-ts/runtime";
6
+ // @generated message type with reflection information, may provide speed optimized methods
7
+ class SyncRequest$Type extends MessageType {
8
+ constructor() {
9
+ super("SyncRequest", [
10
+ {
11
+ no: 1,
12
+ name: "messages",
13
+ kind: "message",
14
+ repeat: 1 /*RepeatType.PACKED*/,
15
+ T: () => EncryptedMessage,
16
+ },
17
+ { no: 2, name: "userId", kind: "scalar", T: 9 /*ScalarType.STRING*/ },
18
+ { no: 3, name: "nodeId", kind: "scalar", T: 9 /*ScalarType.STRING*/ },
19
+ { no: 4, name: "merkleTree", kind: "scalar", T: 9 /*ScalarType.STRING*/ },
20
+ ]);
21
+ }
22
+ }
23
+ /**
24
+ * @generated MessageType for protobuf message SyncRequest
25
+ */
26
+ export const SyncRequest = new SyncRequest$Type();
27
+ // @generated message type with reflection information, may provide speed optimized methods
28
+ class SyncResponse$Type extends MessageType {
29
+ constructor() {
30
+ super("SyncResponse", [
31
+ {
32
+ no: 1,
33
+ name: "messages",
34
+ kind: "message",
35
+ repeat: 1 /*RepeatType.PACKED*/,
36
+ T: () => EncryptedMessage,
37
+ },
38
+ { no: 2, name: "merkleTree", kind: "scalar", T: 9 /*ScalarType.STRING*/ },
39
+ ]);
40
+ }
41
+ }
42
+ /**
43
+ * @generated MessageType for protobuf message SyncResponse
44
+ */
45
+ export const SyncResponse = new SyncResponse$Type();
46
+ // @generated message type with reflection information, may provide speed optimized methods
47
+ class EncryptedMessage$Type extends MessageType {
48
+ constructor() {
49
+ super("EncryptedMessage", [
50
+ { no: 1, name: "timestamp", kind: "scalar", T: 9 /*ScalarType.STRING*/ },
51
+ { no: 2, name: "content", kind: "scalar", T: 12 /*ScalarType.BYTES*/ },
52
+ ]);
53
+ }
54
+ }
55
+ /**
56
+ * @generated MessageType for protobuf message EncryptedMessage
57
+ */
58
+ export const EncryptedMessage = new EncryptedMessage$Type();
59
+ // @generated message type with reflection information, may provide speed optimized methods
60
+ class MessageContent$Type extends MessageType {
61
+ constructor() {
62
+ super("MessageContent", [
63
+ { no: 1, name: "table", kind: "scalar", T: 9 /*ScalarType.STRING*/ },
64
+ { no: 2, name: "row", kind: "scalar", T: 9 /*ScalarType.STRING*/ },
65
+ { no: 3, name: "column", kind: "scalar", T: 9 /*ScalarType.STRING*/ },
66
+ {
67
+ no: 4,
68
+ name: "stringValue",
69
+ kind: "scalar",
70
+ oneof: "value",
71
+ T: 9 /*ScalarType.STRING*/,
72
+ },
73
+ {
74
+ no: 5,
75
+ name: "numberValue",
76
+ kind: "scalar",
77
+ oneof: "value",
78
+ T: 5 /*ScalarType.INT32*/,
79
+ },
80
+ {
81
+ no: 6,
82
+ name: "bytesValue",
83
+ kind: "scalar",
84
+ oneof: "value",
85
+ T: 12 /*ScalarType.BYTES*/,
86
+ },
87
+ {
88
+ no: 7,
89
+ name: "jsonValue",
90
+ kind: "scalar",
91
+ oneof: "value",
92
+ T: 9 /*ScalarType.STRING*/,
93
+ },
94
+ ]);
95
+ }
96
+ }
97
+ /**
98
+ * @generated MessageType for protobuf message MessageContent
99
+ */
100
+ export const MessageContent = new MessageContent$Type();
@@ -0,0 +1,7 @@
1
+ export { jsonArrayFrom, jsonObjectFrom } from "kysely/helpers/sqlite";
2
+ export type { Mnemonic } from "./Crypto.js";
3
+ export type { Owner, OwnerId } from "./Db.js";
4
+ export type { EvoluError } from "./Errors.js";
5
+ export * from "./Model.js";
6
+ export type { SyncState } from "./SyncWorker.js";
7
+ //# sourceMappingURL=Public.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Public.d.ts","sourceRoot":"","sources":["../../src/Public.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACtE,YAAY,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5C,YAAY,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAC9C,YAAY,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC9C,cAAc,YAAY,CAAC;AAC3B,YAAY,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { jsonArrayFrom, jsonObjectFrom } from "kysely/helpers/sqlite";
2
+ export * from "./Model.js";
@@ -0,0 +1,12 @@
1
+ export declare const selectOwner = "\nSELECT\n \"id\",\n \"mnemonic\",\n \"encryptionKey\"\nFROM\n \"evolu_owner\"\n";
2
+ export declare const createMessageTable = "\nCREATE TABLE\n \"evolu_message\" (\n \"timestamp\" blob PRIMARY KEY,\n \"table\" blob,\n \"row\" blob,\n \"column\" blob,\n \"value\" blob\n );\n";
3
+ export declare const createMessageTableIndex = "\nCREATE INDEX \"index_evolu_message\" ON \"evolu_message\" (\n \"table\", \"row\", \"column\", \"timestamp\"\n);\n";
4
+ export declare const createOwnerTable = "\nCREATE TABLE\n \"evolu_owner\" (\n \"id\" blob,\n \"mnemonic\" blob,\n \"encryptionKey\" blob,\n \"timestamp\" blob,\n \"merkleTree\" blob\n );\n";
5
+ export declare const insertOwner = "\nINSERT INTO\n \"evolu_owner\" (\n \"id\",\n \"mnemonic\",\n \"encryptionKey\",\n \"timestamp\",\n \"merkleTree\"\n )\nVALUES\n (?, ?, ?, ?, ?);\n";
6
+ export declare const selectOwnerTimestampAndMerkleTree = "\nSELECT\n \"timestamp\",\n \"merkleTree\"\nFROM\n \"evolu_owner\"\n";
7
+ export declare const selectLastTimestampForTableRowColumn = "\nSELECT\n \"timestamp\"\nFROM\n \"evolu_message\"\nWHERE\n \"table\" = ?\n AND \"row\" = ?\n AND \"column\" = ?\nORDER BY\n \"timestamp\" DESC\nLIMIT\n 1\n";
8
+ export declare const insertValueIntoTableRowColumn: (table: string, column: string) => string;
9
+ export declare const insertIntoMessagesIfNew = "\nINSERT INTO\n \"evolu_message\" (\"timestamp\", \"table\", \"row\", \"column\", \"value\")\nVALUES\n (?, ?, ?, ?, ?)\nON CONFLICT DO NOTHING\n";
10
+ export declare const updateOwnerTimestampAndMerkleTree = "\nUPDATE \"evolu_owner\"\nSET\n \"timestamp\" = ?,\n \"merkleTree\" = ?\n";
11
+ export declare const selectMessagesToSync = "\nSELECT\n *\nFROM\n \"evolu_message\"\nWHERE\n \"timestamp\" >= ?\nORDER BY\n \"timestamp\"\n";
12
+ //# sourceMappingURL=Sql.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Sql.d.ts","sourceRoot":"","sources":["../../src/Sql.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,WAAW,yFAOvB,CAAC;AAEF,eAAO,MAAM,kBAAkB,yKAS9B,CAAC;AAEF,eAAO,MAAM,uBAAuB,yHAInC,CAAC;AAEF,eAAO,MAAM,gBAAgB,yKAS5B,CAAC;AAEF,eAAO,MAAM,WAAW,0KAWvB,CAAC;AAEF,eAAO,MAAM,iCAAiC,4EAM7C,CAAC;AAEF,eAAO,MAAM,oCAAoC,wKAahD,CAAC;AAEF,eAAO,MAAM,6BAA6B,UACjC,MAAM,UACL,MAAM,KACb,MAOF,CAAC;AAEF,eAAO,MAAM,uBAAuB,uJAMnC,CAAC;AAEF,eAAO,MAAM,iCAAiC,gFAK7C,CAAC;AAEF,eAAO,MAAM,oBAAoB,uGAShC,CAAC"}
@@ -0,0 +1,100 @@
1
+ // TODO: This file should be generated from a script via Kysely.
2
+ // The reason for not using Kysely directly is bundle size.
3
+ // [Playground Link](https://kyse.link/?p=b&i=haFkpnNxbGl0ZaF2pjAuMjYuMKFz2gFoaW1wb3J0IHsgR2VuZXJhdGVkIH0gZnJvbSAna3lzZWx5JwoKZGVjbGFyZSBnbG9iYWwgewogIGludGVyZmFjZSBEQiB7CiAgICBldm9sdV9tZXNzYWdlOiB7CiAgICAgIHRpbWVzdGFtcDogc3RyaW5nLAogICAgICB0YWJsZTogc3RyaW5nLAogICAgICByb3c6IHN0cmluZywKICAgICAgY29sdW1uOiBzdHJpbmcsCiAgICAgIHZhbHVlOiB1bmtub3duCiAgICB9LAoKICAgIGV2b2x1X293bmVyOiB7CiAgICAgIGlkOiBzdHJpbmcKICAgICAgbW5lbW9uaWM6IHN0cmluZwogICAgICBlbmNyeXB0aW9uS2V5OiBVaW50OEFycmF5LAogICAgICB0aW1lc3RhbXA6IHN0cmluZywKICAgICAgbWVya2xlVHJlZTogc3RyaW5nCiAgICB9CiAgfQp9oXHaBnhhd2FpdCBreXNlbHkuc2VsZWN0RnJvbSgiZXZvbHVfb3duZXIiKQogIC5zZWxlY3QoWyJpZCIsICJtbmVtb25pYyIsICJlbmNyeXB0aW9uS2V5Il0pCiAgLmV4ZWN1dGUoKQoKYXdhaXQga3lzZWx5LnNjaGVtYQogIC5jcmVhdGVUYWJsZSgnZXZvbHVfbWVzc2FnZScpCiAgLmFkZENvbHVtbigndGltZXN0YW1wJywgJ2Jsb2InLCBjb2wgPT4gY29sLnByaW1hcnlLZXkoKSkKICAuYWRkQ29sdW1uKCd0YWJsZScsICdibG9iJykKICAuYWRkQ29sdW1uKCdyb3cnLCAnYmxvYicpCiAgLmFkZENvbHVtbignY29sdW1uJywgJ2Jsb2InKQogIC5hZGRDb2x1bW4oJ3ZhbHVlJywgJ2Jsb2InKQogIC5leGVjdXRlKCkKCmF3YWl0IGt5c2VseS5zY2hlbWEKICAuY3JlYXRlSW5kZXgoImluZGV4X2V2b2x1X21lc3NhZ2UiKQogIC5vbigiZXZvbHVfbWVzc2FnZSIpCiAgLmNvbHVtbnMoWyJ0YWJsZSIsICJyb3ciLCAiY29sdW1uIiwgInRpbWVzdGFtcCJdKQogIC5leGVjdXRlKCkKCmF3YWl0IGt5c2VseS5zY2hlbWEKICAuY3JlYXRlVGFibGUoJ2V2b2x1X19vd25lcicpCiAgLmFkZENvbHVtbignaWQnLCAnYmxvYicpCiAgLmFkZENvbHVtbignbW5lbW9uaWMnLCAnYmxvYicpCiAgLmFkZENvbHVtbignZW5jcnlwdGlvbktleScsICdibG9iJykKICAuYWRkQ29sdW1uKCd0aW1lc3RhbXAnLCAnYmxvYicpCiAgLmFkZENvbHVtbignbWVya2xlVHJlZScsICdibG9iJykKICAuZXhlY3V0ZSgpCgphd2FpdCBreXNlbHkuaW5zZXJ0SW50bygiZXZvbHVfb3duZXIiKQogIC52YWx1ZXMoewogICAgImlkIjogImIiLAogICAgIm1uZW1vbmljIjogImEiLAogICAgImVuY3J5cHRpb25LZXkiOiBuZXcgVWludDhBcnJheSgpLAogICAgInRpbWVzdGFtcCI6ICJhIiwKICAgICJtZXJrbGVUcmVlIjogImIiCiAgfSkKICAuZXhlY3V0ZSgpCgphd2FpdCBreXNlbHkuc2VsZWN0RnJvbSgiZXZvbHVfb3duZXIiKQogIC5zZWxlY3QoWyJ0aW1lc3RhbXAiLCAibWVya2xlVHJlZSJdKQogIC5leGVjdXRlKCkKCmF3YWl0IGt5c2VseS5zZWxlY3RGcm9tKCJldm9sdV9tZXNzYWdlIikKICAuc2VsZWN0KCJ0aW1lc3RhbXAiKQogIC53aGVyZSgndGFibGUnLCAnPScsICcxJykKICAud2hlcmUoJ3JvdycsICc9JywgJzInKQogIC53aGVyZSgnY29sdW1uJywgJz0nLCAnMycpCiAgLm9yZGVyQnkoInRpbWVzdGFtcCIsICJkZXNjIikKICAubGltaXQoMSkKICAuZXhlY3V0ZVRha2VGaXJzdCgpCgphd2FpdCBreXNlbHkuaW5zZXJ0SW50bygiZXZvbHVfbWVzc2FnZSIpCiAgLnZhbHVlcyh7CiAgICAidGltZXN0YW1wIjogJzEnLAogICAgInRhYmxlIjogJzInLAogICAgInJvdyI6ICczJywKICAgICJjb2x1bW4iOiAnNCcsCiAgICAidmFsdWUiOiAnNScsCiAgfSkKICAub25Db25mbGljdChvYyA9PiBvYy5kb05vdGhpbmcoKSkKICAuZXhlY3V0ZSgpCgphd2FpdCBreXNlbHkudXBkYXRlVGFibGUoImV2b2x1X293bmVyIikKICAuc2V0KHsKICAgICJtZXJrbGVUcmVlIjogJzEnLAogICAgInRpbWVzdGFtcCI6ICIyIgogIH0pCiAgLmV4ZWN1dGUoKQoKYXdhaXQga3lzZWx5LnNlbGVjdEZyb20oImV2b2x1X21lc3NhZ2UiKQogIC5zZWxlY3RBbGwoKQogIC53aGVyZSgidGltZXN0YW1wIiwgIj49IiwgJzEnKQogIC5vcmRlckJ5KCJ0aW1lc3RhbXAiKQogIC5leGVjdXRlKCmhY8M=)
4
+ export const selectOwner = `
5
+ SELECT
6
+ "id",
7
+ "mnemonic",
8
+ "encryptionKey"
9
+ FROM
10
+ "evolu_owner"
11
+ `;
12
+ export const createMessageTable = `
13
+ CREATE TABLE
14
+ "evolu_message" (
15
+ "timestamp" blob PRIMARY KEY,
16
+ "table" blob,
17
+ "row" blob,
18
+ "column" blob,
19
+ "value" blob
20
+ );
21
+ `;
22
+ export const createMessageTableIndex = `
23
+ CREATE INDEX "index_evolu_message" ON "evolu_message" (
24
+ "table", "row", "column", "timestamp"
25
+ );
26
+ `;
27
+ export const createOwnerTable = `
28
+ CREATE TABLE
29
+ "evolu_owner" (
30
+ "id" blob,
31
+ "mnemonic" blob,
32
+ "encryptionKey" blob,
33
+ "timestamp" blob,
34
+ "merkleTree" blob
35
+ );
36
+ `;
37
+ export const insertOwner = `
38
+ INSERT INTO
39
+ "evolu_owner" (
40
+ "id",
41
+ "mnemonic",
42
+ "encryptionKey",
43
+ "timestamp",
44
+ "merkleTree"
45
+ )
46
+ VALUES
47
+ (?, ?, ?, ?, ?);
48
+ `;
49
+ export const selectOwnerTimestampAndMerkleTree = `
50
+ SELECT
51
+ "timestamp",
52
+ "merkleTree"
53
+ FROM
54
+ "evolu_owner"
55
+ `;
56
+ export const selectLastTimestampForTableRowColumn = `
57
+ SELECT
58
+ "timestamp"
59
+ FROM
60
+ "evolu_message"
61
+ WHERE
62
+ "table" = ?
63
+ AND "row" = ?
64
+ AND "column" = ?
65
+ ORDER BY
66
+ "timestamp" DESC
67
+ LIMIT
68
+ 1
69
+ `;
70
+ export const insertValueIntoTableRowColumn = (table, column) => `
71
+ INSERT INTO
72
+ "${table}" ("id", "${column}")
73
+ VALUES
74
+ (?, ?)
75
+ ON CONFLICT DO UPDATE SET
76
+ "${column}" = ?
77
+ `;
78
+ export const insertIntoMessagesIfNew = `
79
+ INSERT INTO
80
+ "evolu_message" ("timestamp", "table", "row", "column", "value")
81
+ VALUES
82
+ (?, ?, ?, ?, ?)
83
+ ON CONFLICT DO NOTHING
84
+ `;
85
+ export const updateOwnerTimestampAndMerkleTree = `
86
+ UPDATE "evolu_owner"
87
+ SET
88
+ "timestamp" = ?,
89
+ "merkleTree" = ?
90
+ `;
91
+ export const selectMessagesToSync = `
92
+ SELECT
93
+ *
94
+ FROM
95
+ "evolu_message"
96
+ WHERE
97
+ "timestamp" >= ?
98
+ ORDER BY
99
+ "timestamp"
100
+ `;
@@ -0,0 +1,30 @@
1
+ import { Brand, Context, Effect, Predicate, ReadonlyRecord } from "effect";
2
+ export interface Sqlite {
3
+ readonly exec: (arg: string | QueryObject) => Effect.Effect<never, never, ExecResult>;
4
+ }
5
+ export declare const Sqlite: Context.Tag<Sqlite, Sqlite>;
6
+ export interface QueryObject {
7
+ readonly sql: string;
8
+ readonly parameters: ReadonlyArray<Value>;
9
+ }
10
+ export type Value = SqliteValue | JsonObjectOrArray;
11
+ export type SqliteValue = null | string | number | Uint8Array;
12
+ export type SqliteRow = Record<string, SqliteValue>;
13
+ export type JsonObjectOrArray = JsonObject | JsonArray;
14
+ type JsonObject = ReadonlyRecord.ReadonlyRecord<Json>;
15
+ type JsonArray = ReadonlyArray<Json>;
16
+ type Json = string | number | boolean | null | JsonObject | JsonArray;
17
+ interface ExecResult {
18
+ readonly rows: ReadonlyArray<Row>;
19
+ readonly changes: number;
20
+ }
21
+ export type Row = ReadonlyRecord.ReadonlyRecord<Value | Row | ReadonlyArray<Row>>;
22
+ export type Query = string & Brand.Brand<"Query">;
23
+ export declare const isJsonObjectOrArray: Predicate.Refinement<Value, JsonObjectOrArray>;
24
+ export declare const valuesToSqliteValues: (values: ReadonlyArray<Value>) => SqliteValue[];
25
+ export declare const queryObjectToQuery: ({ sql, parameters }: QueryObject) => Query;
26
+ export declare const queryObjectFromQuery: (s: Query) => QueryObject;
27
+ export declare const parseJsonResults: (rows: SqliteRow[]) => void;
28
+ export declare const maybeJson: Predicate.Predicate<string>;
29
+ export {};
30
+ //# sourceMappingURL=Sqlite.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Sqlite.d.ts","sourceRoot":"","sources":["../../src/Sqlite.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAC;AAE3E,MAAM,WAAW,MAAM;IACrB,QAAQ,CAAC,IAAI,EAAE,CACb,GAAG,EAAE,MAAM,GAAG,WAAW,KACtB,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC;CAC9C;AAED,eAAO,MAAM,MAAM,6BAAsC,CAAC;AAE1D,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,UAAU,EAAE,aAAa,CAAC,KAAK,CAAC,CAAC;CAC3C;AAED,MAAM,MAAM,KAAK,GAAG,WAAW,GAAG,iBAAiB,CAAC;AAEpD,MAAM,MAAM,WAAW,GAAG,IAAI,GAAG,MAAM,GAAG,MAAM,GAAG,UAAU,CAAC;AAC9D,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;AAEpD,MAAM,MAAM,iBAAiB,GAAG,UAAU,GAAG,SAAS,CAAC;AAEvD,KAAK,UAAU,GAAG,cAAc,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;AACtD,KAAK,SAAS,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;AACrC,KAAK,IAAI,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,UAAU,GAAG,SAAS,CAAC;AAEtE,UAAU,UAAU;IAClB,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC,GAAG,CAAC,CAAC;IAClC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,MAAM,GAAG,GAAG,cAAc,CAAC,cAAc,CAC7C,KAAK,GAAG,GAAG,GAAG,aAAa,CAAC,GAAG,CAAC,CACjC,CAAC;AAEF,MAAM,MAAM,KAAK,GAAG,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;AAElD,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,kBAAkB,wBAAyB,WAAW,KAAG,KACxB,CAAC;AAE/C,eAAO,MAAM,oBAAoB,MAAO,KAAK,KAAG,WAClB,CAAC;AAE/B,eAAO,MAAM,gBAAgB,SAAU,SAAS,EAAE,KAAG,IAEpD,CAAC;AA2BF,eAAO,MAAM,SAAS,EAAE,SAAS,CAAC,SAAS,CAAC,MAAM,CACpB,CAAC"}
@@ -0,0 +1,41 @@
1
+ import { Context, Predicate } from "effect";
2
+ export const Sqlite = Context.Tag("evolu/Sqlite");
3
+ export const isJsonObjectOrArray = (value) => value !== null && typeof value === "object" && !(value instanceof Uint8Array);
4
+ export const valuesToSqliteValues = (values) => values.map((value) => isJsonObjectOrArray(value) ? JSON.stringify(value) : value);
5
+ export const queryObjectToQuery = ({ sql, parameters }) => JSON.stringify({ sql, parameters });
6
+ export const queryObjectFromQuery = (s) => JSON.parse(s);
7
+ export const parseJsonResults = (rows) => {
8
+ parseArray(rows);
9
+ };
10
+ const parseArray = (a) => {
11
+ for (let i = 0; i < a.length; ++i)
12
+ a[i] = parse(a[i]);
13
+ return a;
14
+ };
15
+ const parse = (o) => {
16
+ if (Predicate.isString(o))
17
+ return parseString(o);
18
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-return
19
+ if (Array.isArray(o))
20
+ return parseArray(o);
21
+ // Predicate.isReadonlyRecord
22
+ if (typeof o === "object" && o !== null && !Predicate.isUint8Array(o))
23
+ return parseObject(o);
24
+ return o;
25
+ };
26
+ const parseString = (s) => {
27
+ if (maybeJson(s))
28
+ try {
29
+ return parse(JSON.parse(s));
30
+ }
31
+ catch (err) {
32
+ // Nothing to do.
33
+ }
34
+ return s;
35
+ };
36
+ export const maybeJson = (value) => value.match(/^[[{]/) != null;
37
+ const parseObject = (o) => {
38
+ for (const key in o)
39
+ o[key] = parse(o[key]);
40
+ return o;
41
+ };
@@ -0,0 +1,9 @@
1
+ export type StoreListener = () => void;
2
+ export type StoreUnsubscribe = () => void;
3
+ export interface Store<T> {
4
+ readonly subscribe: (listener: StoreListener) => StoreUnsubscribe;
5
+ readonly setState: (state: T) => void;
6
+ readonly getState: () => T;
7
+ }
8
+ export declare const makeStore: <T>(initialState: T) => Store<T>;
9
+ //# sourceMappingURL=Store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Store.d.ts","sourceRoot":"","sources":["../../src/Store.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC;AAEvC,MAAM,MAAM,gBAAgB,GAAG,MAAM,IAAI,CAAC;AAE1C,MAAM,WAAW,KAAK,CAAC,CAAC;IACtB,QAAQ,CAAC,SAAS,EAAE,CAAC,QAAQ,EAAE,aAAa,KAAK,gBAAgB,CAAC;IAClE,QAAQ,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC;IACtC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;CAC5B;AAED,eAAO,MAAM,SAAS,kCAqBrB,CAAC"}
@@ -0,0 +1,18 @@
1
+ export const makeStore = (initialState) => {
2
+ let currentState = initialState;
3
+ const listeners = new Set();
4
+ const subscribe = (listener) => {
5
+ listeners.add(listener);
6
+ return () => {
7
+ listeners.delete(listener);
8
+ };
9
+ };
10
+ const setState = (state) => {
11
+ if (state === currentState)
12
+ return;
13
+ currentState = state;
14
+ listeners.forEach((listener) => listener());
15
+ };
16
+ const getState = () => currentState;
17
+ return { subscribe, setState, getState };
18
+ };
@@ -0,0 +1,73 @@
1
+ import { Context, Layer } from "effect";
2
+ import { SecretBox } from "./Crypto.js";
3
+ import { Owner } from "./Db.js";
4
+ import { UnexpectedError } from "./Errors.js";
5
+ import { MerkleTree } from "./MerkleTree.js";
6
+ import { Id } from "./Model.js";
7
+ import { Fetch, SyncLock } from "./Platform.js";
8
+ import { Value } from "./Sqlite.js";
9
+ import { Millis, Timestamp, TimestampString } from "./Timestamp.js";
10
+ export interface SyncWorker {
11
+ readonly postMessage: (input: SyncWorkerInput) => void;
12
+ onMessage: (output: SyncWorkerOutput) => void;
13
+ }
14
+ export declare const SyncWorker: Context.Tag<SyncWorker, SyncWorker>;
15
+ export type SyncWorkerPostMessage = SyncWorker["postMessage"];
16
+ export declare const SyncWorkerPostMessage: Context.Tag<(input: SyncWorkerInput) => void, (input: SyncWorkerInput) => void>;
17
+ export type SyncWorkerInput = SyncWorkerInputSync | SyncWorkerInputSyncCompleted;
18
+ interface SyncWorkerInputSync {
19
+ readonly _tag: "sync";
20
+ readonly syncUrl: string;
21
+ readonly messages: ReadonlyArray<Message>;
22
+ readonly merkleTree: MerkleTree;
23
+ readonly timestamp: Timestamp;
24
+ readonly owner: Owner;
25
+ readonly syncLoopCount: number;
26
+ }
27
+ export interface NewMessage {
28
+ readonly table: string;
29
+ readonly row: Id;
30
+ readonly column: string;
31
+ readonly value: Value;
32
+ }
33
+ export interface Message extends NewMessage {
34
+ readonly timestamp: TimestampString;
35
+ }
36
+ interface SyncWorkerInputSyncCompleted {
37
+ readonly _tag: "syncCompleted";
38
+ }
39
+ export type SyncWorkerOutput = UnexpectedError | SyncWorkerOutputSyncResponse | SyncStateIsNotSyncedError | SyncStateIsSyncing;
40
+ export type SyncWorkerOutputSyncResponse = {
41
+ readonly _tag: "SyncWorkerOutputSyncResponse";
42
+ readonly messages: ReadonlyArray<Message>;
43
+ readonly merkleTree: MerkleTree;
44
+ readonly syncLoopCount: number;
45
+ };
46
+ export type SyncState = SyncStateInitial | SyncStateIsSyncing | SyncStateIsSynced | SyncStateIsNotSyncedError;
47
+ export interface SyncStateInitial {
48
+ readonly _tag: "SyncStateInitial";
49
+ }
50
+ export interface SyncStateIsSyncing {
51
+ readonly _tag: "SyncStateIsSyncing";
52
+ }
53
+ export interface SyncStateIsSynced {
54
+ readonly _tag: "SyncStateIsSynced";
55
+ readonly time: Millis;
56
+ }
57
+ export interface SyncStateIsNotSyncedError {
58
+ readonly _tag: "SyncStateIsNotSyncedError";
59
+ readonly error: SyncStateNetworkError | SyncStateServerError | SyncStatePaymentRequiredError;
60
+ }
61
+ export interface SyncStateNetworkError {
62
+ readonly _tag: "NetworkError";
63
+ }
64
+ export interface SyncStateServerError {
65
+ readonly _tag: "ServerError";
66
+ readonly status: number;
67
+ }
68
+ export interface SyncStatePaymentRequiredError {
69
+ readonly _tag: "PaymentRequiredError";
70
+ }
71
+ export declare const SyncWorkerLive: Layer.Layer<SecretBox | SyncLock | Fetch, never, SyncWorker>;
72
+ export {};
73
+ //# sourceMappingURL=SyncWorker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SyncWorker.d.ts","sourceRoot":"","sources":["../../src/SyncWorker.ts"],"names":[],"mappings":"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"}