@evolu/common 1.0.16 → 2.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 (75) hide show
  1. package/README.md +7 -7
  2. package/dist/src/Config.d.ts +4 -6
  3. package/dist/src/Config.d.ts.map +1 -1
  4. package/dist/src/Config.js +1 -1
  5. package/dist/src/Crdt.d.ts +15 -9
  6. package/dist/src/Crdt.d.ts.map +1 -1
  7. package/dist/src/Crdt.js +15 -14
  8. package/dist/src/Crypto.d.ts +7 -13
  9. package/dist/src/Crypto.d.ts.map +1 -1
  10. package/dist/src/Crypto.js +7 -9
  11. package/dist/src/Db.d.ts +36 -70
  12. package/dist/src/Db.d.ts.map +1 -1
  13. package/dist/src/Db.js +45 -51
  14. package/dist/src/DbWorker.d.ts +13 -14
  15. package/dist/src/DbWorker.d.ts.map +1 -1
  16. package/dist/src/DbWorker.js +56 -57
  17. package/dist/src/Diff.d.ts +3 -1
  18. package/dist/src/Diff.d.ts.map +1 -1
  19. package/dist/src/Diff.js +3 -7
  20. package/dist/src/{Errors.d.ts → ErrorStore.d.ts} +14 -7
  21. package/dist/src/ErrorStore.d.ts.map +1 -0
  22. package/dist/src/{Errors.js → ErrorStore.js} +2 -0
  23. package/dist/src/Evolu.d.ts +316 -58
  24. package/dist/src/Evolu.d.ts.map +1 -1
  25. package/dist/src/Evolu.js +199 -185
  26. package/dist/src/Model.d.ts +47 -57
  27. package/dist/src/Model.d.ts.map +1 -1
  28. package/dist/src/Model.js +30 -35
  29. package/dist/src/OnCompletes.d.ts +11 -0
  30. package/dist/src/OnCompletes.d.ts.map +1 -0
  31. package/dist/src/OnCompletes.js +21 -0
  32. package/dist/src/Owner.d.ts +31 -0
  33. package/dist/src/Owner.d.ts.map +1 -0
  34. package/dist/src/Owner.js +20 -0
  35. package/dist/src/Platform.d.ts +15 -8
  36. package/dist/src/Platform.d.ts.map +1 -1
  37. package/dist/src/Platform.js +5 -5
  38. package/dist/src/Protobuf.d.ts +25 -73
  39. package/dist/src/Protobuf.d.ts.map +1 -1
  40. package/dist/src/Protobuf.js +4 -12
  41. package/dist/src/Public.d.ts +5 -3
  42. package/dist/src/Public.d.ts.map +1 -1
  43. package/dist/src/Public.js +1 -0
  44. package/dist/src/Sqlite.d.ts +8 -11
  45. package/dist/src/Sqlite.d.ts.map +1 -1
  46. package/dist/src/Sqlite.js +7 -7
  47. package/dist/src/Store.d.ts +6 -5
  48. package/dist/src/Store.d.ts.map +1 -1
  49. package/dist/src/Store.js +21 -16
  50. package/dist/src/SyncWorker.d.ts +8 -2
  51. package/dist/src/SyncWorker.d.ts.map +1 -1
  52. package/dist/src/SyncWorker.js +12 -19
  53. package/dist/src/index.d.ts +6 -2
  54. package/dist/src/index.d.ts.map +1 -1
  55. package/dist/src/index.js +6 -2
  56. package/package.json +23 -13
  57. package/src/Config.ts +7 -7
  58. package/src/Crdt.ts +29 -26
  59. package/src/Crypto.ts +14 -19
  60. package/src/Db.ts +113 -166
  61. package/src/DbWorker.ts +110 -140
  62. package/src/Diff.ts +5 -7
  63. package/src/{Errors.ts → ErrorStore.ts} +17 -8
  64. package/src/Evolu.ts +682 -442
  65. package/src/Model.ts +60 -85
  66. package/src/OnCompletes.ts +46 -0
  67. package/src/Owner.ts +65 -0
  68. package/src/Platform.ts +24 -16
  69. package/src/Protobuf.ts +25 -73
  70. package/src/Public.ts +5 -3
  71. package/src/Sqlite.ts +13 -24
  72. package/src/Store.ts +36 -24
  73. package/src/SyncWorker.ts +30 -38
  74. package/src/index.ts +6 -2
  75. package/dist/src/Errors.d.ts.map +0 -1
package/README.md CHANGED
@@ -28,20 +28,20 @@ Client-server architecture provides us with easy backup and synchronization, but
28
28
  To start using Evolu, define tables for your database and export React Hooks.
29
29
 
30
30
  ```ts
31
- import * as Schema from "@effect/schema/Schema";
31
+ import * as S from "@effect/schema/Schema";
32
32
  import * as Evolu from "@evolu/react";
33
33
 
34
34
  const TodoId = Evolu.id("Todo");
35
- type TodoId = Schema.Schema.To<typeof TodoId>;
35
+ type TodoId = S.Schema.To<typeof TodoId>;
36
36
 
37
- const TodoTable = Schema.struct({
37
+ const TodoTable = S.struct({
38
38
  id: TodoId,
39
39
  title: Evolu.NonEmptyString1000,
40
40
  isCompleted: Evolu.SqliteBoolean,
41
41
  });
42
- type TodoTable = Schema.Schema.To<typeof TodoTable>;
42
+ type TodoTable = S.Schema.To<typeof TodoTable>;
43
43
 
44
- const Database = Schema.struct({
44
+ const Database = S.struct({
45
45
  todo: TodoTable,
46
46
  });
47
47
 
@@ -59,10 +59,10 @@ export const {
59
59
  Learn more about [Schema](https://github.com/effect-ts/schema).
60
60
 
61
61
  ```ts
62
- import * as Schema from "@effect/schema/Schema";
62
+ import * as S from "@effect/schema/Schema";
63
63
  import * as Evolu from "@evolu/react";
64
64
 
65
- Schema.parse(Evolu.String1000)(title);
65
+ S.parse(Evolu.String1000)(title);
66
66
  ```
67
67
 
68
68
  ### Mutate Data
@@ -1,17 +1,15 @@
1
1
  import { Context, Layer } from "effect";
2
2
  export interface Config {
3
- /**
4
- * Alternate URL to Evolu sync&backup server.
5
- */
3
+ /** Alternate URL to Evolu sync and backup server. */
6
4
  readonly syncUrl: string;
7
5
  /**
8
- * Alternate URL to reload browser tabs after `Owner` reset or restore.
6
+ * Alternate URL to reload browser tabs after {@link Owner} reset or restore.
9
7
  * The default value is `/`.
10
8
  */
11
9
  readonly reloadUrl: string;
12
10
  /**
13
- * Maximum physical clock drift allowed in ms.
14
- * The default value is 5 * 60 * 1000 (5 minutes).
11
+ * Maximum physical clock drift allowed in ms. The default value is 5 * 60 *
12
+ * 1000 (5 minutes).
15
13
  */
16
14
  readonly maxDrift: number;
17
15
  }
@@ -1 +1 @@
1
- {"version":3,"file":"Config.d.ts","sourceRoot":"","sources":["../../src/Config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAExC,MAAM,WAAW,MAAM;IACrB;;OAEG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB;;;OAGG;IACH,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B;;;OAGG;IACH,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED,eAAO,MAAM,MAAM,6BAAsC,CAAC;AAE1D,eAAO,MAAM,UAAU,YACZ,QAAQ,MAAM,CAAC,KACvB,WAAW,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,CAShC,CAAC"}
1
+ {"version":3,"file":"Config.d.ts","sourceRoot":"","sources":["../../src/Config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAExC,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;CAC3B;AAED,eAAO,MAAM,MAAM,6BAAwB,CAAC;AAE5C,eAAO,MAAM,UAAU,YACZ,QAAQ,MAAM,CAAC,KACvB,WAAW,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,CAShC,CAAC"}
@@ -1,5 +1,5 @@
1
1
  import { Context, Layer } from "effect";
2
- export const Config = Context.Tag("evolu/Config");
2
+ export const Config = Context.Tag();
3
3
  export const ConfigLive = (config) => Layer.succeed(Config, Config.of({
4
4
  syncUrl: "https://evolu.world",
5
5
  maxDrift: 5 * 60 * 1000,
@@ -1,4 +1,4 @@
1
- import * as Schema from "@effect/schema/Schema";
1
+ import * as S from "@effect/schema/Schema";
2
2
  import { Brand, Context, Effect, Layer, Option } from "effect";
3
3
  import { Config } from "./Config.js";
4
4
  import { NanoId, NodeId } from "./Crypto.js";
@@ -12,16 +12,17 @@ export declare const AllowedTimeRange: {
12
12
  lessThan: number;
13
13
  };
14
14
  /**
15
- * Millis represents a time that is valid for usage with the Merkle tree.
16
- * It must be between Apr 13, 1997, and Nov 05, 2051, to ensure MinutesBase3
17
- * length equals 16. We can find diff for two Merkle trees only within this range.
18
- * If the device clock is out of range, Evolu will not store data until it's fixed.
15
+ * Millis represents a time that is valid for usage with the Merkle tree. It
16
+ * must be between Apr 13, 1997, and Nov 05, 2051, to ensure MinutesBase3 length
17
+ * equals 16. We can find diff for two Merkle trees only within this range. If
18
+ * the device clock is out of range, Evolu will not store data until it's
19
+ * fixed.
19
20
  */
20
- export declare const Millis: Schema.BrandSchema<number, number & Brand.Brand<"Millis">>;
21
- export type Millis = Schema.Schema.To<typeof Millis>;
21
+ export declare const Millis: S.BrandSchema<number, number & Brand.Brand<"Millis">>;
22
+ export type Millis = S.Schema.To<typeof Millis>;
22
23
  export declare const initialMillis: number & Brand.Brand<"Millis">;
23
- export declare const Counter: Schema.BrandSchema<number, number & Brand.Brand<"Counter">>;
24
- export type Counter = Schema.Schema.To<typeof Counter>;
24
+ export declare const Counter: S.BrandSchema<number, number & Brand.Brand<"Counter">>;
25
+ export type Counter = S.Schema.To<typeof Counter>;
25
26
  export type TimestampHash = number & Brand.Brand<"TimestampHash">;
26
27
  export type TimestampString = string & Brand.Brand<"TimestampString">;
27
28
  export declare const timestampToString: (t: Timestamp) => TimestampString;
@@ -34,6 +35,11 @@ export interface Time {
34
35
  }
35
36
  export declare const Time: Context.Tag<Time, Time>;
36
37
  export declare const TimeLive: Layer.Layer<never, never, Time>;
38
+ /**
39
+ * The TimestampError type represents all Timestamp-related errors. If such an
40
+ * error happens, the device clock is skewed and should be set to the current
41
+ * time.
42
+ */
37
43
  export type TimestampError = TimestampDriftError | TimestampCounterOverflowError | TimestampDuplicateNodeError | TimestampTimeOutOfRangeError;
38
44
  export interface TimestampDriftError {
39
45
  readonly _tag: "TimestampDriftError";
@@ -1 +1 @@
1
- {"version":3,"file":"Crdt.d.ts","sourceRoot":"","sources":["../../src/Crdt.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Crdt.d.ts","sourceRoot":"","sources":["../../src/Crdt.ts"],"names":[],"mappings":"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"}
package/dist/src/Crdt.js CHANGED
@@ -1,4 +1,4 @@
1
- import * as Schema from "@effect/schema/Schema";
1
+ import * as S from "@effect/schema/Schema";
2
2
  import { Context, Effect, Either, Layer, Number, Option, ReadonlyArray, String, pipe, } from "effect";
3
3
  import { Config } from "./Config.js";
4
4
  import { NanoId, NodeId } from "./Crypto.js";
@@ -8,15 +8,16 @@ export const AllowedTimeRange = {
8
8
  lessThan: 2582803260000,
9
9
  };
10
10
  /**
11
- * Millis represents a time that is valid for usage with the Merkle tree.
12
- * It must be between Apr 13, 1997, and Nov 05, 2051, to ensure MinutesBase3
13
- * length equals 16. We can find diff for two Merkle trees only within this range.
14
- * If the device clock is out of range, Evolu will not store data until it's fixed.
11
+ * Millis represents a time that is valid for usage with the Merkle tree. It
12
+ * must be between Apr 13, 1997, and Nov 05, 2051, to ensure MinutesBase3 length
13
+ * equals 16. We can find diff for two Merkle trees only within this range. If
14
+ * the device clock is out of range, Evolu will not store data until it's
15
+ * fixed.
15
16
  */
16
- export const Millis = Schema.number.pipe(Schema.greaterThan(AllowedTimeRange.greaterThan), Schema.lessThan(AllowedTimeRange.lessThan), Schema.brand("Millis"));
17
- export const initialMillis = Schema.parseSync(Millis)(AllowedTimeRange.greaterThan + 1);
18
- export const Counter = Schema.number.pipe(Schema.between(0, 65535), Schema.brand("Counter"));
19
- const initialCounter = Schema.parseSync(Counter)(0);
17
+ export const Millis = S.number.pipe(S.greaterThan(AllowedTimeRange.greaterThan), S.lessThan(AllowedTimeRange.lessThan), S.brand("Millis"));
18
+ export const initialMillis = S.parseSync(Millis)(AllowedTimeRange.greaterThan + 1);
19
+ export const Counter = S.number.pipe(S.between(0, 65535), S.brand("Counter"));
20
+ const initialCounter = S.parseSync(Counter)(0);
20
21
  export const timestampToString = (t) => [
21
22
  new Date(t.millis).toISOString(),
22
23
  t.counter.toString(16).toUpperCase().padStart(4, "0"),
@@ -31,7 +32,7 @@ export const unsafeTimestampFromString = (s) => {
31
32
  };
32
33
  };
33
34
  export const timestampToHash = (t) => murmurhash(timestampToString(t));
34
- const syncNodeId = Schema.parseSync(NodeId)("0000000000000000");
35
+ const syncNodeId = S.parseSync(NodeId)("0000000000000000");
35
36
  export const makeSyncTimestamp = (millis = initialMillis) => ({
36
37
  millis,
37
38
  counter: initialCounter,
@@ -42,9 +43,9 @@ export const makeInitialTimestamp = NanoId.pipe(Effect.flatMap(({ nanoidAsNodeId
42
43
  counter: initialCounter,
43
44
  node,
44
45
  })));
45
- export const Time = Context.Tag("evolu/Time");
46
+ export const Time = Context.Tag();
46
47
  export const TimeLive = Layer.succeed(Time, Time.of({
47
- now: Effect.suspend(() => Schema.parse(Millis)(Date.now())).pipe(Effect.catchTag("ParseError", () => Effect.fail({
48
+ now: Effect.suspend(() => S.parse(Millis)(Date.now())).pipe(Effect.catchTag("ParseError", () => Effect.fail({
48
49
  _tag: "TimestampTimeOutOfRangeError",
49
50
  }))),
50
51
  }));
@@ -61,8 +62,8 @@ const getNextMillis = (millis) => Effect.gen(function* (_) {
61
62
  }));
62
63
  return next;
63
64
  });
64
- const incrementCounter = (counter) => pipe(Number.increment(counter), Schema.parseEither(Counter), Either.mapLeft(() => ({ _tag: "TimestampCounterOverflowError" })));
65
- const counterMin = Schema.parseSync(Counter)(0);
65
+ const incrementCounter = (counter) => pipe(Number.increment(counter), S.parseEither(Counter), Either.mapLeft(() => ({ _tag: "TimestampCounterOverflowError" })));
66
+ const counterMin = S.parseSync(Counter)(0);
66
67
  export const sendTimestamp = (timestamp) => Effect.gen(function* (_) {
67
68
  const millis = yield* _(getNextMillis([timestamp.millis]));
68
69
  const counter = millis === timestamp.millis
@@ -1,4 +1,4 @@
1
- import * as Schema from "@effect/schema/Schema";
1
+ import * as S from "@effect/schema/Schema";
2
2
  import { Brand, Context, Effect, Layer } from "effect";
3
3
  export interface Bip39 {
4
4
  readonly make: Effect.Effect<never, never, Mnemonic>;
@@ -12,9 +12,9 @@ export interface InvalidMnemonicError {
12
12
  /**
13
13
  * Mnemonic is a password generated by Evolu in BIP39 format.
14
14
  *
15
- * A mnemonic, also known as a "seed phrase," is a set of 12 words in a
16
- * specific order chosen from a predefined list. The purpose of the BIP39
17
- * mnemonic is to provide a human-readable way of storing a private key.
15
+ * A mnemonic, also known as a "seed phrase," is a set of 12 words in a specific
16
+ * order chosen from a predefined list. The purpose of the BIP39 mnemonic is to
17
+ * provide a human-readable way of storing a private key.
18
18
  */
19
19
  export type Mnemonic = string & Brand.Brand<"Mnemonic">;
20
20
  export interface NanoId {
@@ -22,17 +22,11 @@ export interface NanoId {
22
22
  readonly nanoidAsNodeId: Effect.Effect<never, never, NodeId>;
23
23
  }
24
24
  export declare const NanoId: Context.Tag<NanoId, NanoId>;
25
- export declare const NodeId: Schema.BrandSchema<string, string & Brand.Brand<"NodeId">>;
26
- export type NodeId = Schema.Schema.To<typeof NodeId>;
25
+ export declare const NodeId: S.BrandSchema<string, string & Brand.Brand<"NodeId">>;
26
+ export type NodeId = S.Schema.To<typeof NodeId>;
27
27
  export declare const NanoIdLive: Layer.Layer<never, never, NanoId>;
28
- /**
29
- * SLIP-21 implementation
30
- * https://github.com/satoshilabs/slips/blob/master/slip-0021.md
31
- */
32
28
  export declare const slip21Derive: (seed: Uint8Array, path: ReadonlyArray<string>) => Effect.Effect<never, never, Uint8Array>;
33
- /**
34
- * Alias to xsalsa20poly1305, for compatibility with libsodium / nacl
35
- */
29
+ /** Alias to xsalsa20poly1305, for compatibility with libsodium/nacl */
36
30
  export interface SecretBox {
37
31
  readonly seal: (key: Uint8Array, plaintext: Uint8Array) => Effect.Effect<never, never, Uint8Array>;
38
32
  readonly open: (key: Uint8Array, ciphertext: Uint8Array) => Effect.Effect<never, never, Uint8Array>;
@@ -1 +1 @@
1
- {"version":3,"file":"Crypto.d.ts","sourceRoot":"","sources":["../../src/Crypto.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,uBAAuB,CAAC;AAMhD,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAGvD,MAAM,WAAW,KAAK;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;IAErD,QAAQ,CAAC,MAAM,EAAE,CACf,QAAQ,EAAE,QAAQ,KACf,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC;IAE7C,QAAQ,CAAC,KAAK,EAAE,CACd,QAAQ,EAAE,MAAM,KACb,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,oBAAoB,EAAE,QAAQ,CAAC,CAAC;CAC3D;AAED,eAAO,MAAM,KAAK,2BAAoC,CAAC;AAEvD,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,MAAM;IACrB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IACrD,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;CAC9D;AAED,eAAO,MAAM,MAAM,6BAAsC,CAAC;AAE1D,eAAO,MAAM,MAAM,EAAE,MAAM,CAAC,WAAW,CACrC,MAAM,EACN,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,CAC6C,CAAC;AAC9E,MAAM,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,MAAM,CAAC,CAAC;AAIrD,eAAO,MAAM,UAAU,mCAMtB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,YAAY,SACjB,UAAU,QACV,cAAc,MAAM,CAAC,KAC1B,aAAa,CAAC,KAAK,EAAE,KAAK,EAAE,UAAU,CAWrC,CAAC;AAEL;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,IAAI,EAAE,CACb,GAAG,EAAE,UAAU,EACf,SAAS,EAAE,UAAU,KAClB,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC;IAE7C,QAAQ,CAAC,IAAI,EAAE,CACb,GAAG,EAAE,UAAU,EACf,UAAU,EAAE,UAAU,KACnB,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC;CAC9C;AAED,eAAO,MAAM,SAAS,mCAA4C,CAAC;AAEnE,eAAO,MAAM,aAAa,sCAgBzB,CAAC"}
1
+ {"version":3,"file":"Crypto.d.ts","sourceRoot":"","sources":["../../src/Crypto.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,uBAAuB,CAAC;AAM3C,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAIvD,MAAM,WAAW,KAAK;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;IAErD,QAAQ,CAAC,MAAM,EAAE,CACf,QAAQ,EAAE,QAAQ,KACf,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC;IAE7C,QAAQ,CAAC,KAAK,EAAE,CACd,QAAQ,EAAE,MAAM,KACb,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,oBAAoB,EAAE,QAAQ,CAAC,CAAC;CAC3D;AAED,eAAO,MAAM,KAAK,2BAAuB,CAAC;AAE1C,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,MAAM;IACrB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IACrD,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;CAC9D;AAED,eAAO,MAAM,MAAM,6BAAwB,CAAC;AAE5C,eAAO,MAAM,MAAM,EAAE,CAAC,CAAC,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,CACb,CAAC;AAC7D,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,MAAM,CAAC,CAAC;AAIhD,eAAO,MAAM,UAAU,mCAMtB,CAAC;AAIF,eAAO,MAAM,YAAY,SACjB,UAAU,QACV,cAAc,MAAM,CAAC,KAC1B,aAAa,CAAC,KAAK,EAAE,KAAK,EAAE,UAAU,CAWrC,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,KAAK,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC;IAE7C,QAAQ,CAAC,IAAI,EAAE,CACb,GAAG,EAAE,UAAU,EACf,UAAU,EAAE,UAAU,KACnB,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC;CAC9C;AAED,eAAO,MAAM,SAAS,mCAA2B,CAAC;AAElD,eAAO,MAAM,aAAa,sCAgBzB,CAAC"}
@@ -1,4 +1,4 @@
1
- import * as Schema from "@effect/schema/Schema";
1
+ import * as S from "@effect/schema/Schema";
2
2
  import { secretbox } from "@noble/ciphers/salsa";
3
3
  import { concatBytes } from "@noble/ciphers/utils";
4
4
  import { hmac } from "@noble/hashes/hmac";
@@ -6,18 +6,16 @@ import { sha512 } from "@noble/hashes/sha512";
6
6
  import { randomBytes } from "@noble/hashes/utils";
7
7
  import { Context, Effect, Layer } from "effect";
8
8
  import { customAlphabet, nanoid } from "nanoid";
9
- export const Bip39 = Context.Tag("evolu/Bip39");
10
- export const NanoId = Context.Tag("evolu/NanoId");
11
- export const NodeId = Schema.string.pipe(Schema.pattern(/^[\w-]{16}$/), Schema.brand("NodeId"));
9
+ export const Bip39 = Context.Tag();
10
+ export const NanoId = Context.Tag();
11
+ export const NodeId = S.string.pipe(S.pattern(/^[\w-]{16}$/), S.brand("NodeId"));
12
12
  const nanoidForNodeId = customAlphabet("0123456789abcdef", 16);
13
13
  export const NanoIdLive = Layer.succeed(NanoId, NanoId.of({
14
14
  nanoid: Effect.sync(() => nanoid()),
15
15
  nanoidAsNodeId: Effect.sync(() => nanoidForNodeId()),
16
16
  }));
17
- /**
18
- * SLIP-21 implementation
19
- * https://github.com/satoshilabs/slips/blob/master/slip-0021.md
20
- */
17
+ // SLIP-21 implementation
18
+ // https://github.com/satoshilabs/slips/blob/master/slip-0021.md
21
19
  export const slip21Derive = (seed, path) => Effect.sync(() => {
22
20
  let m = hmac(sha512, "Symmetric key seed", seed);
23
21
  for (let i = 0; i < path.length; i++) {
@@ -29,7 +27,7 @@ export const slip21Derive = (seed, path) => Effect.sync(() => {
29
27
  }
30
28
  return m.slice(32, 64);
31
29
  });
32
- export const SecretBox = Context.Tag("evolu/SecretBox");
30
+ export const SecretBox = Context.Tag();
33
31
  export const SecretBoxLive = Layer.succeed(SecretBox, SecretBox.of({
34
32
  seal: (key, plaintext) => Effect.sync(() => {
35
33
  const nonce = randomBytes(24);
package/dist/src/Db.d.ts CHANGED
@@ -1,87 +1,51 @@
1
1
  import * as S from "@effect/schema/Schema";
2
- import { Brand, Context, Effect, ReadonlyRecord } from "effect";
2
+ import { Brand, Context, Effect, Layer, ReadonlyArray, ReadonlyRecord } from "effect";
3
3
  import * as Kysely from "kysely";
4
- import { Simplify } from "kysely";
5
4
  import { Bip39, Mnemonic, NanoId } from "./Crypto.js";
6
- import { Id, SqliteBoolean, SqliteDate } from "./Model.js";
7
- import { Query, Row, Sqlite, Value } from "./Sqlite.js";
5
+ import { Id } from "./Model.js";
6
+ import { Owner } from "./Owner.js";
7
+ import { Sqlite, SqliteQuery, Value } from "./Sqlite.js";
8
+ import { Store } from "./Store.js";
9
+ export type Schema = ReadonlyRecord.ReadonlyRecord<TableSchema>;
8
10
  export type TableSchema = ReadonlyRecord.ReadonlyRecord<Value> & {
9
11
  readonly id: Id;
10
12
  };
11
- export type Schema = ReadonlyRecord.ReadonlyRecord<TableSchema>;
12
- export type CreateQuery<S extends Schema> = (queryCallback: QueryCallback<S, Row>) => Query;
13
- export type QueryCallback<S extends Schema, QueryRow> = (db: KyselyWithoutMutation<QuerySchema<S>>) => Kysely.SelectQueryBuilder<any, any, QueryRow>;
14
- type KyselyWithoutMutation<DB> = Pick<Kysely.Kysely<DB>, "selectFrom" | "fn">;
15
- type QuerySchema<S extends Schema> = {
16
- readonly [Table in keyof S]: NullableExceptOfId<{
17
- readonly [Column in keyof S[Table]]: S[Table][Column];
18
- } & CommonColumns>;
19
- };
20
- export type NullableExceptOfId<T> = {
21
- readonly [K in keyof T]: K extends "id" ? T[K] : T[K] | null;
22
- };
23
- export interface CommonColumns {
24
- readonly createdAt: SqliteDate;
25
- readonly updatedAt: SqliteDate;
26
- readonly isDeleted: SqliteBoolean;
27
- }
13
+ declare const __queryBrand: unique symbol;
28
14
  /**
29
- * Filter and map array items in one step with the correct return type and
30
- * without unreliable TypeScript type guards.
31
- *
32
- * ### Examples
33
- *
34
- * ```
35
- * useQuery(
36
- * (db) => db.selectFrom("todo").selectAll(),
37
- * // Filter and map nothing.
38
- * (row) => row,
39
- * );
40
- *
41
- * useQuery(
42
- * (db) => db.selectFrom("todo").selectAll(),
43
- * // Filter items with title != null.
44
- * // Note the title type isn't nullable anymore in rows.
45
- * ({ title, ...rest }) => title != null && { title, ...rest },
46
- * );
47
- * ```
15
+ * The query is an SQL query serialized as a string with a branded type
16
+ * representing a row it returns.
48
17
  */
49
- export type FilterMap<QueryRow extends Row, FilterMapRow extends Row> = (row: QueryRow) => FilterMapRow | null | false;
50
- export interface QueryResult<FilterMapRow extends Row> {
51
- /**
52
- * Rows from the database. They can be filtered and mapped by `filterMap`.
53
- */
54
- readonly rows: ReadonlyArray<Readonly<Simplify<ExcludeNullAndFalse<FilterMapRow>>>>;
18
+ export type Query<R extends Row = Row> = string & Brand.Brand<"Query"> & {
19
+ readonly [__queryBrand]: R;
20
+ };
21
+ export type Queries<R extends Row = Row> = ReadonlyArray<Query<R>>;
22
+ export declare const serializeQuery: <R extends Row>({ sql, parameters, }: SqliteQuery) => Query<R>;
23
+ export declare const deserializeQuery: <R extends Row>(query: Query<R>) => SqliteQuery;
24
+ export type Row = ReadonlyRecord.ReadonlyRecord<Value | Row | ReadonlyArray<Row>>;
25
+ export declare const emptyRows: <R extends Row>() => readonly R[];
26
+ /** An object with rows and row properties. */
27
+ export interface QueryResult<R extends Row = Row> {
28
+ /** An array containing all the rows returned by the query. */
29
+ readonly rows: ReadonlyArray<Readonly<Kysely.Simplify<R>>>;
55
30
  /**
56
- * The first row from `rows`. For empty rows, it's null.
31
+ * The first row returned by the query, or null if no rows were returned. This
32
+ * property is useful for queries that are expected to return a single row.
57
33
  */
58
- readonly firstRow: Readonly<Simplify<ExcludeNullAndFalse<FilterMapRow>>> | null;
34
+ readonly row: Readonly<Kysely.Simplify<R>> | null;
59
35
  }
60
- type ExcludeNullAndFalse<T> = Exclude<T, null | false>;
36
+ export type QueryResultsFromQueries<Q extends Queries> = {
37
+ [P in keyof Q]: Q[P] extends Query<infer R> ? QueryResult<R> : never;
38
+ };
39
+ export type QueryResultsPromisesFromQueries<Q extends Queries> = {
40
+ [P in keyof Q]: Q[P] extends Query<infer R> ? Promise<QueryResult<R>> : never;
41
+ };
42
+ export declare const queryResultFromRows: <R extends Row>(rows: readonly R[]) => QueryResult<R>;
43
+ export type Tables = ReadonlyArray<Table>;
61
44
  export interface Table {
62
45
  readonly name: string;
63
46
  readonly columns: ReadonlyArray<string>;
64
47
  }
65
- export type Tables = ReadonlyArray<Table>;
66
- export declare const makeCreateQuery: <S extends Schema>() => CreateQuery<S>;
67
48
  export declare const schemaToTables: (schema: S.Schema<any, any>) => Tables;
68
- /**
69
- * `Owner` represents the Evolu database owner. Evolu auto-generates `Owner`
70
- * on the first run. `Owner` can be reset on the current device and restored
71
- * on a different one.
72
- */
73
- export interface Owner {
74
- /** The `Mnemonic` associated with `Owner`. */
75
- readonly mnemonic: Mnemonic;
76
- /** The unique identifier of `Owner` safely derived from its `Mnemonic`. */
77
- readonly id: OwnerId;
78
- readonly encryptionKey: Uint8Array;
79
- }
80
- export declare const Owner: Context.Tag<Owner, Owner>;
81
- /**
82
- * The unique identifier of `Owner` safely derived from its `Mnemonic`.
83
- */
84
- export type OwnerId = Id & Brand.Brand<"Owner">;
85
49
  export declare const transaction: <R, E, A>(effect: Effect.Effect<R, E, A>) => Effect.Effect<Sqlite | R, E, A>;
86
50
  export interface NoSuchTableOrColumnError {
87
51
  readonly _tag: "NoSuchTableOrColumnError";
@@ -93,9 +57,11 @@ export declare const SqliteNoSuchTableOrColumnError: S.Schema<{
93
57
  }>;
94
58
  export type SqliteNoSuchTableOrColumnError = S.Schema.To<typeof SqliteNoSuchTableOrColumnError>;
95
59
  export declare const someDefectToNoSuchTableOrColumnError: <R, E, A>(self: Effect.Effect<R, E, A>) => Effect.Effect<R, NoSuchTableOrColumnError | E, A>;
96
- export declare const makeOwner: (mnemonic?: Mnemonic) => Effect.Effect<Bip39, never, Owner>;
97
60
  export declare const lazyInit: (mnemonic?: Mnemonic) => Effect.Effect<Sqlite | Bip39 | NanoId, never, Owner>;
98
61
  export declare const ensureSchema: (tables: Tables) => Effect.Effect<Sqlite, never, void>;
99
- export declare const makeCacheFilterMap: () => <QueryRow extends Row, FilterMapRow extends Row>(filterMap: FilterMap<QueryRow, FilterMapRow>) => FilterMap<QueryRow, FilterMapRow>;
62
+ export type RowsStore = Store<RowsStoreValue>;
63
+ export declare const RowsStore: Context.Tag<RowsStore, RowsStore>;
64
+ type RowsStoreValue = ReadonlyMap<Query, ReadonlyArray<Row>>;
65
+ export declare const RowsStoreLive: Layer.Layer<never, never, RowsStore>;
100
66
  export {};
101
67
  //# sourceMappingURL=Db.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Db.d.ts","sourceRoot":"","sources":["../../src/Db.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Db.d.ts","sourceRoot":"","sources":["../../src/Db.ts"],"names":[],"mappings":"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"}
package/dist/src/Db.js CHANGED
@@ -2,45 +2,64 @@ 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
4
  import { bytesToHex } from "@noble/ciphers/utils";
5
- import { Context, Effect, Exit, Option, Predicate, ReadonlyArray, ReadonlyRecord, String, pipe, } from "effect";
6
- import * as Kysely from "kysely";
7
- import { urlAlphabet } from "nanoid";
5
+ import { Context, Effect, Exit, Layer, Option, Predicate, ReadonlyArray, ReadonlyRecord, String, pipe, } from "effect";
8
6
  import { initialMerkleTree, makeInitialTimestamp, merkleTreeToString, timestampToString, } from "./Crdt.js";
9
- import { Bip39, slip21Derive } from "./Crypto.js";
7
+ import { makeOwner } from "./Owner.js";
10
8
  import { createMessageTable, createMessageTableIndex, createOwnerTable, insertOwner, } from "./Sql.js";
11
- import { Sqlite, queryObjectToQuery, } from "./Sqlite.js";
12
- const commonColumns = ["createdAt", "updatedAt", "isDeleted"];
13
- const kysely = new Kysely.Kysely({
14
- dialect: {
15
- createAdapter: () => new Kysely.SqliteAdapter(),
16
- createDriver: () => new Kysely.DummyDriver(),
17
- createIntrospector() {
18
- throw "Not implemeneted";
19
- },
20
- createQueryCompiler: () => new Kysely.SqliteQueryCompiler(),
21
- },
22
- });
23
- export const makeCreateQuery = () => (queryCallback) => queryObjectToQuery(queryCallback(kysely).compile());
9
+ import { Sqlite, isJsonObjectOrArray, } from "./Sqlite.js";
10
+ import { makeStore } from "./Store.js";
11
+ // We use queries as keys, hence JSON.stringify.
12
+ export const serializeQuery = ({ sql, parameters, }) => {
13
+ const query = {
14
+ sql,
15
+ parameters: parameters.map((p) => {
16
+ return Predicate.isUint8Array(p)
17
+ ? Array.from(p)
18
+ : isJsonObjectOrArray(p)
19
+ ? { json: p }
20
+ : p;
21
+ }),
22
+ };
23
+ return JSON.stringify(query);
24
+ };
25
+ export const deserializeQuery = (query) => {
26
+ const serializedSqliteQuery = JSON.parse(query);
27
+ return {
28
+ ...serializedSqliteQuery,
29
+ parameters: serializedSqliteQuery.parameters.map((p) => Array.isArray(p)
30
+ ? new Uint8Array(p)
31
+ : typeof p === "object" && p != null
32
+ ? p.json
33
+ : p),
34
+ };
35
+ };
36
+ const _emptyRows = [];
37
+ export const emptyRows = () => _emptyRows;
38
+ const queryResultCache = new WeakMap();
39
+ export const queryResultFromRows = (rows) => {
40
+ let queryResult = queryResultCache.get(rows);
41
+ if (queryResult == null) {
42
+ queryResult = { rows, row: rows[0] };
43
+ queryResultCache.set(rows, queryResult);
44
+ }
45
+ return queryResult;
46
+ };
24
47
  // https://github.com/Effect-TS/schema/releases/tag/v0.18.0
25
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
26
48
  const getPropertySignatures = (schema) => {
27
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
28
49
  const out = {};
29
50
  const propertySignatures = AST.getPropertySignatures(schema.ast);
30
51
  for (let i = 0; i < propertySignatures.length; i++) {
31
52
  const propertySignature = propertySignatures[i];
32
53
  out[propertySignature.name] = make(propertySignature.type);
33
54
  }
34
- // eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-explicit-any
55
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-return
35
56
  return out;
36
57
  };
37
- export const schemaToTables = (
38
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
39
- schema) => pipe(getPropertySignatures(schema), ReadonlyRecord.toEntries, ReadonlyArray.map(([name, schema]) => ({
58
+ const commonColumns = ["createdAt", "updatedAt", "isDeleted"];
59
+ export const schemaToTables = (schema) => pipe(getPropertySignatures(schema), ReadonlyRecord.toEntries, ReadonlyArray.map(([name, schema]) => ({
40
60
  name,
41
61
  columns: Object.keys(getPropertySignatures(schema)).concat(commonColumns),
42
62
  })));
43
- export const Owner = Context.Tag("evolu/Owner");
44
63
  export const transaction = (effect) => Effect.flatMap(Sqlite, (sqlite) => Effect.acquireUseRelease(sqlite.exec("BEGIN"), () => effect, (_, exit) => Exit.isFailure(exit) ? sqlite.exec("ROLLBACK") : sqlite.exec("END")));
45
64
  export const SqliteNoSuchTableOrColumnError = S.struct({
46
65
  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"))),
@@ -50,22 +69,6 @@ export const someDefectToNoSuchTableOrColumnError = Effect.catchSomeDefect((erro
50
69
  _tag: "NoSuchTableOrColumnError",
51
70
  }))
52
71
  : Option.none());
53
- export const makeOwner = (mnemonic) => Effect.gen(function* (_) {
54
- const bip39 = yield* _(Bip39);
55
- if (mnemonic == null)
56
- mnemonic = yield* _(bip39.make);
57
- const seed = yield* _(bip39.toSeed(mnemonic));
58
- const id = yield* _(slip21Derive(seed, ["Evolu", "Owner Id"]).pipe(Effect.map((key) => {
59
- // convert key to nanoid
60
- let id = "";
61
- for (let i = 0; i < 21; i++) {
62
- id += urlAlphabet[key[i] & 63];
63
- }
64
- return id;
65
- })));
66
- const encryptionKey = yield* _(slip21Derive(seed, ["Evolu", "Encryption Key"]));
67
- return { mnemonic, id, encryptionKey };
68
- });
69
72
  export const lazyInit = (mnemonic) => Effect.gen(function* (_) {
70
73
  const [owner, sqlite, initialTimestampString] = yield* _(Effect.all([makeOwner(mnemonic), Sqlite, makeInitialTimestamp], {
71
74
  concurrency: "unbounded",
@@ -110,14 +113,5 @@ const createTable = ({ name, columns, }) => Effect.flatMap(Sqlite, (sqlite) => s
110
113
  export const ensureSchema = (tables) => Effect.flatMap(getTables, (existingTables) => Effect.forEach(tables, (tableDefinition) => existingTables.includes(tableDefinition.name)
111
114
  ? updateTable(tableDefinition)
112
115
  : createTable(tableDefinition), { discard: true }));
113
- export const makeCacheFilterMap = () => {
114
- const cache = new WeakMap();
115
- return (filterMap) => (row) => {
116
- let cachedRow = cache.get(row);
117
- if (cachedRow === undefined) {
118
- cachedRow = filterMap(row);
119
- cache.set(row, cachedRow);
120
- }
121
- return cachedRow;
122
- };
123
- };
116
+ export const RowsStore = Context.Tag();
117
+ export const RowsStoreLive = Layer.effect(RowsStore, makeStore(new Map()));