@evolu/common 1.0.17 → 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
@@ -1 +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"}
1
+ {"version":3,"file":"Store.d.ts","sourceRoot":"","sources":["../../src/Store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC,MAAM,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC;AAElC,MAAM,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC;AAErC,MAAM,WAAW,KAAK,CAAC,CAAC;IAEtB,QAAQ,CAAC,SAAS,EAAE,CAAC,QAAQ,EAAE,QAAQ,KAAK,WAAW,CAAC;IACxD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAG3B,QAAQ,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;CACpE;AAED,eAAO,MAAM,SAAS,+DA4BlB,CAAC"}
package/dist/src/Store.js CHANGED
@@ -1,18 +1,23 @@
1
- export const makeStore = (initialState) => {
2
- let currentState = initialState;
1
+ import { Effect } from "effect";
2
+ export const makeStore = (initialState) => Effect.sync(() => {
3
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());
4
+ let currentState = initialState;
5
+ const store = {
6
+ subscribe(listener) {
7
+ listeners.add(listener);
8
+ return () => {
9
+ listeners.delete(listener);
10
+ };
11
+ },
12
+ getState() {
13
+ return currentState;
14
+ },
15
+ setState: (state) => Effect.sync(() => {
16
+ if (state === currentState)
17
+ return;
18
+ currentState = state;
19
+ listeners.forEach((listener) => listener());
20
+ }),
15
21
  };
16
- const getState = () => currentState;
17
- return { subscribe, setState, getState };
18
- };
22
+ return store;
23
+ });
@@ -1,9 +1,9 @@
1
1
  import { Context, Equivalence, Layer } from "effect";
2
2
  import { MerkleTree, Millis, Timestamp, TimestampString } from "./Crdt.js";
3
3
  import { SecretBox } from "./Crypto.js";
4
- import { Owner } from "./Db.js";
5
- import { UnexpectedError } from "./Errors.js";
4
+ import { UnexpectedError } from "./ErrorStore.js";
6
5
  import { Id } from "./Model.js";
6
+ import { Owner } from "./Owner.js";
7
7
  import { Fetch, SyncLock } from "./Platform.js";
8
8
  import { Value } from "./Sqlite.js";
9
9
  export interface SyncWorker {
@@ -43,6 +43,12 @@ export type SyncWorkerOutputSyncResponse = {
43
43
  readonly merkleTree: MerkleTree;
44
44
  readonly syncLoopCount: number;
45
45
  };
46
+ /**
47
+ * The SyncState type represents the various states that a synchronization
48
+ * process can be in. Evolu apps should not bother users with an "unsynced"
49
+ * state. Instead, they should warn users if data have not been synced for too
50
+ * long (a week, for example).
51
+ */
46
52
  export type SyncState = SyncStateInitial | SyncStateIsSyncing | SyncStateIsSynced | SyncStateIsNotSyncedError;
47
53
  export interface SyncStateInitial {
48
54
  readonly _tag: "SyncStateInitial";
@@ -1 +1 @@
1
- {"version":3,"file":"SyncWorker.d.ts","sourceRoot":"","sources":["../../src/SyncWorker.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"SyncWorker.d.ts","sourceRoot":"","sources":["../../src/SyncWorker.ts"],"names":[],"mappings":"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"}
@@ -1,18 +1,18 @@
1
1
  import { concatBytes } from "@noble/ciphers/utils";
2
2
  import { BinaryReader, BinaryWriter } from "@protobuf-ts/runtime";
3
- import { Context, Effect, Function, Layer, Option, Predicate, ReadonlyArray, absurd, identity, } from "effect";
3
+ import { Context, Effect, Function, Layer, Match, Option, Predicate, ReadonlyArray, absurd, identity, } from "effect";
4
4
  import { merkleTreeToString, unsafeMerkleTreeFromString, } from "./Crdt.js";
5
5
  import { SecretBox } from "./Crypto.js";
6
- import { makeUnexpectedError } from "./Errors.js";
6
+ import { makeUnexpectedError } from "./ErrorStore.js";
7
7
  import { Fetch, SyncLock } from "./Platform.js";
8
8
  import { MessageContent, SyncRequest, SyncResponse, } from "./Protobuf.js";
9
- export const SyncWorker = Context.Tag("evolu/SyncWorker");
10
- export const SyncWorkerPostMessage = Context.Tag("evolu/SyncWorkerPostMessage");
9
+ export const SyncWorker = Context.Tag();
10
+ export const SyncWorkerPostMessage = Context.Tag();
11
11
  export const NewMessageEquivalence = (a, b) => a.table === b.table &&
12
12
  a.row === b.row &&
13
13
  a.column === b.column &&
14
14
  JSON.stringify(a.value) === JSON.stringify(b.value);
15
- const SyncWorkerOnMessage = Context.Tag("evolu/SyncWorkerOnMessage");
15
+ const SyncWorkerOnMessage = Context.Tag();
16
16
  const version1 = new Uint8Array([0, 1]);
17
17
  const valueToProtobuf = (value) => {
18
18
  switch (typeof value) {
@@ -121,24 +121,17 @@ const sync = (input) => Effect.gen(function* (_) {
121
121
  });
122
122
  export const SyncWorkerLive = Layer.effect(SyncWorker, Effect.gen(function* (_) {
123
123
  const syncLock = yield* _(SyncLock);
124
- const fetch = yield* _(Fetch);
125
- const secretBox = yield* _(SecretBox);
126
124
  const onError = (error) => Effect.sync(() => {
127
125
  syncWorker.onMessage(error);
128
126
  });
129
- const mapInputToEffect = (input) => {
130
- switch (input._tag) {
131
- case "sync":
132
- return sync(input);
133
- case "syncCompleted":
134
- return syncLock.release;
135
- }
136
- };
137
- const postMessage = (input) => {
138
- void mapInputToEffect(input).pipe(Effect.catchAllDefect(makeUnexpectedError), Effect.catchAll(onError), Effect.provideService(SyncLock, syncLock), Effect.provideService(Fetch, fetch), Effect.provideService(SecretBox, secretBox), Effect.provideService(SyncWorkerOnMessage, syncWorker.onMessage), Effect.runPromise);
139
- };
127
+ const context = Context.empty().pipe(Context.add(SyncLock, syncLock), Context.add(Fetch, yield* _(Fetch)), Context.add(SecretBox, yield* _(SecretBox)));
140
128
  const syncWorker = {
141
- postMessage,
129
+ postMessage: (input) => {
130
+ Match.value(input).pipe(Match.tagsExhaustive({
131
+ sync,
132
+ syncCompleted: () => syncLock.release,
133
+ }), Effect.catchAllDefect(makeUnexpectedError), Effect.catchAll(onError), Effect.provide(context), Effect.provideService(SyncWorkerOnMessage, syncWorker.onMessage), Effect.runPromise);
134
+ },
142
135
  onMessage: Function.constVoid,
143
136
  };
144
137
  return syncWorker;
@@ -1,14 +1,18 @@
1
- export { jsonArrayFrom, jsonObjectFrom } from "kysely/helpers/sqlite";
2
1
  export * from "./Config.js";
3
2
  export * from "./Crdt.js";
4
3
  export * from "./Crypto.js";
5
4
  export * from "./Db.js";
6
5
  export * from "./DbWorker.js";
7
- export * from "./Errors.js";
6
+ export * from "./Diff.js";
7
+ export * from "./ErrorStore.js";
8
8
  export * from "./Evolu.js";
9
9
  export * from "./Model.js";
10
+ export * from "./Murmurhash.js";
11
+ export * from "./OnCompletes.js";
12
+ export * from "./Owner.js";
10
13
  export * from "./Platform.js";
11
14
  export * from "./Protobuf.js";
15
+ export * from "./Public.js";
12
16
  export * from "./Sqlite.js";
13
17
  export * from "./Store.js";
14
18
  export * from "./SyncWorker.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACtE,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC;AAC5B,cAAc,SAAS,CAAC;AACxB,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC;AAC5B,cAAc,SAAS,CAAC;AACxB,cAAc,eAAe,CAAC;AAC9B,cAAc,WAAW,CAAC;AAC1B,cAAc,iBAAiB,CAAC;AAChC,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC"}
package/dist/src/index.js CHANGED
@@ -1,14 +1,18 @@
1
- export { jsonArrayFrom, jsonObjectFrom } from "kysely/helpers/sqlite";
2
1
  export * from "./Config.js";
3
2
  export * from "./Crdt.js";
4
3
  export * from "./Crypto.js";
5
4
  export * from "./Db.js";
6
5
  export * from "./DbWorker.js";
7
- export * from "./Errors.js";
6
+ export * from "./Diff.js";
7
+ export * from "./ErrorStore.js";
8
8
  export * from "./Evolu.js";
9
9
  export * from "./Model.js";
10
+ export * from "./Murmurhash.js";
11
+ export * from "./OnCompletes.js";
12
+ export * from "./Owner.js";
10
13
  export * from "./Platform.js";
11
14
  export * from "./Protobuf.js";
15
+ export * from "./Public.js";
12
16
  export * from "./Sqlite.js";
13
17
  export * from "./Store.js";
14
18
  export * from "./SyncWorker.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@evolu/common",
3
- "version": "1.0.17",
3
+ "version": "2.0.0",
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",
@@ -23,11 +23,21 @@
23
23
  "types": "./dist/src/index.d.ts",
24
24
  "import": "./dist/src/index.js",
25
25
  "browser": "./dist/src/index.js"
26
+ },
27
+ "./public": {
28
+ "import": "./dist/src/Public.js"
26
29
  }
27
30
  },
28
31
  "react-native": {
29
32
  "./index.js": "./dist/src/index.js"
30
33
  },
34
+ "typesVersions": {
35
+ "*": {
36
+ "public": [
37
+ "./dist/src/Public.d.ts"
38
+ ]
39
+ }
40
+ },
31
41
  "files": [
32
42
  "dist/src/**",
33
43
  "src/**",
@@ -39,24 +49,24 @@
39
49
  "@protobuf-ts/runtime": "^2.9.1",
40
50
  "@scure/bip39": "^1.2.1",
41
51
  "kysely": "^0.26.3",
42
- "nanoid": "^5.0.2"
52
+ "nanoid": "^5.0.3"
43
53
  },
44
54
  "devDependencies": {
45
- "@effect/schema": "0.46.3",
55
+ "@effect/schema": "0.50.0",
46
56
  "@protobuf-ts/plugin": "^2.9.1",
47
57
  "@protobuf-ts/protoc": "^2.9.1",
48
58
  "array-shuffle": "^3.0.0",
49
- "better-sqlite3": "^9.0.0",
50
- "effect": "2.0.0-next.52",
51
- "eslint": "^8.52.0",
52
- "typescript": "^5.2.2",
59
+ "better-sqlite3": "^9.1.1",
60
+ "effect": "2.0.0-next.56",
61
+ "eslint": "^8.54.0",
62
+ "typescript": "^5.3.2",
53
63
  "vitest": "^0.34.6",
54
64
  "@evolu/tsconfig": "0.0.2",
55
- "eslint-config-evolu": "0.0.2"
65
+ "eslint-config-evolu": "1.0.0"
56
66
  },
57
67
  "peerDependencies": {
58
- "@effect/schema": "0.46.3",
59
- "effect": "2.0.0-next.52"
68
+ "@effect/schema": "0.50.0",
69
+ "effect": "2.0.0-next.56"
60
70
  },
61
71
  "publishConfig": {
62
72
  "access": "public"
@@ -64,13 +74,13 @@
64
74
  "engines": {
65
75
  "node": ">=18.16"
66
76
  },
67
- "sideEffects": false,
77
+ "sideEffects": [],
68
78
  "scripts": {
69
79
  "dev": "tsc --watch",
70
80
  "build": "rm -rf dist ./README.md && tsc && cp ../../README.md ./",
71
- "lint": "TIMING=1 eslint src --ext .ts,.tsx",
81
+ "lint": "eslint src --ext .ts,.tsx",
72
82
  "test": "vitest run",
73
- "clean": "rm -rf .turbo && rm -rf node_modules && rm -rf dist",
83
+ "clean": "rm -rf .turbo node_modules dist",
74
84
  "format": "prettier --write \"src/*.{ts,tsx,md}\"",
75
85
  "protobuf": "pnpm protoc --ts_out ./src --proto_path protobuf protobuf/Protobuf.proto --ts_opt eslint_disable --ts_opt optimize_code_size && pnpm format"
76
86
  }
package/src/Config.ts CHANGED
@@ -1,23 +1,23 @@
1
1
  import { Context, Layer } from "effect";
2
2
 
3
3
  export interface Config {
4
- /**
5
- * Alternate URL to Evolu sync&backup server.
6
- */
4
+ /** Alternate URL to Evolu sync and backup server. */
7
5
  readonly syncUrl: string;
6
+
8
7
  /**
9
- * Alternate URL to reload browser tabs after `Owner` reset or restore.
8
+ * Alternate URL to reload browser tabs after {@link Owner} reset or restore.
10
9
  * The default value is `/`.
11
10
  */
12
11
  readonly reloadUrl: string;
12
+
13
13
  /**
14
- * Maximum physical clock drift allowed in ms.
15
- * The default value is 5 * 60 * 1000 (5 minutes).
14
+ * Maximum physical clock drift allowed in ms. The default value is 5 * 60 *
15
+ * 1000 (5 minutes).
16
16
  */
17
17
  readonly maxDrift: number;
18
18
  }
19
19
 
20
- export const Config = Context.Tag<Config>("evolu/Config");
20
+ export const Config = Context.Tag<Config>();
21
21
 
22
22
  export const ConfigLive = (
23
23
  config?: Partial<Config>,
package/src/Crdt.ts CHANGED
@@ -1,4 +1,4 @@
1
- import * as Schema from "@effect/schema/Schema";
1
+ import * as S from "@effect/schema/Schema";
2
2
  import {
3
3
  Brand,
4
4
  Context,
@@ -32,30 +32,28 @@ export const AllowedTimeRange = {
32
32
  };
33
33
 
34
34
  /**
35
- * Millis represents a time that is valid for usage with the Merkle tree.
36
- * It must be between Apr 13, 1997, and Nov 05, 2051, to ensure MinutesBase3
37
- * length equals 16. We can find diff for two Merkle trees only within this range.
38
- * If the device clock is out of range, Evolu will not store data until it's fixed.
35
+ * Millis represents a time that is valid for usage with the Merkle tree. It
36
+ * must be between Apr 13, 1997, and Nov 05, 2051, to ensure MinutesBase3 length
37
+ * equals 16. We can find diff for two Merkle trees only within this range. If
38
+ * the device clock is out of range, Evolu will not store data until it's
39
+ * fixed.
39
40
  */
40
- export const Millis = Schema.number.pipe(
41
- Schema.greaterThan(AllowedTimeRange.greaterThan),
42
- Schema.lessThan(AllowedTimeRange.lessThan),
43
- Schema.brand("Millis"),
41
+ export const Millis = S.number.pipe(
42
+ S.greaterThan(AllowedTimeRange.greaterThan),
43
+ S.lessThan(AllowedTimeRange.lessThan),
44
+ S.brand("Millis"),
44
45
  );
45
46
 
46
- export type Millis = Schema.Schema.To<typeof Millis>;
47
+ export type Millis = S.Schema.To<typeof Millis>;
47
48
 
48
- export const initialMillis = Schema.parseSync(Millis)(
49
+ export const initialMillis = S.parseSync(Millis)(
49
50
  AllowedTimeRange.greaterThan + 1,
50
51
  );
51
52
 
52
- export const Counter = Schema.number.pipe(
53
- Schema.between(0, 65535),
54
- Schema.brand("Counter"),
55
- );
56
- export type Counter = Schema.Schema.To<typeof Counter>;
53
+ export const Counter = S.number.pipe(S.between(0, 65535), S.brand("Counter"));
54
+ export type Counter = S.Schema.To<typeof Counter>;
57
55
 
58
- const initialCounter = Schema.parseSync(Counter)(0);
56
+ const initialCounter = S.parseSync(Counter)(0);
59
57
 
60
58
  export type TimestampHash = number & Brand.Brand<"TimestampHash">;
61
59
 
@@ -80,7 +78,7 @@ export const unsafeTimestampFromString = (s: TimestampString): Timestamp => {
80
78
  export const timestampToHash = (t: Timestamp): TimestampHash =>
81
79
  murmurhash(timestampToString(t)) as TimestampHash;
82
80
 
83
- const syncNodeId = Schema.parseSync(NodeId)("0000000000000000");
81
+ const syncNodeId = S.parseSync(NodeId)("0000000000000000");
84
82
 
85
83
  export const makeSyncTimestamp = (
86
84
  millis: Millis = initialMillis,
@@ -105,12 +103,12 @@ export interface Time {
105
103
  readonly now: Effect.Effect<never, TimestampTimeOutOfRangeError, Millis>;
106
104
  }
107
105
 
108
- export const Time = Context.Tag<Time>("evolu/Time");
106
+ export const Time = Context.Tag<Time>();
109
107
 
110
108
  export const TimeLive = Layer.succeed(
111
109
  Time,
112
110
  Time.of({
113
- now: Effect.suspend(() => Schema.parse(Millis)(Date.now())).pipe(
111
+ now: Effect.suspend(() => S.parse(Millis)(Date.now())).pipe(
114
112
  Effect.catchTag("ParseError", () =>
115
113
  Effect.fail<TimestampTimeOutOfRangeError>({
116
114
  _tag: "TimestampTimeOutOfRangeError",
@@ -120,6 +118,11 @@ export const TimeLive = Layer.succeed(
120
118
  }),
121
119
  );
122
120
 
121
+ /**
122
+ * The TimestampError type represents all Timestamp-related errors. If such an
123
+ * error happens, the device clock is skewed and should be set to the current
124
+ * time.
125
+ */
123
126
  export type TimestampError =
124
127
  | TimestampDriftError
125
128
  | TimestampCounterOverflowError
@@ -176,11 +179,11 @@ const incrementCounter = (
176
179
  ): Either.Either<TimestampCounterOverflowError, Counter> =>
177
180
  pipe(
178
181
  Number.increment(counter),
179
- Schema.parseEither(Counter),
182
+ S.parseEither(Counter),
180
183
  Either.mapLeft(() => ({ _tag: "TimestampCounterOverflowError" })),
181
184
  );
182
185
 
183
- const counterMin = Schema.parseSync(Counter)(0);
186
+ const counterMin = S.parseSync(Counter)(0);
184
187
 
185
188
  export const sendTimestamp = (
186
189
  timestamp: Timestamp,
@@ -228,10 +231,10 @@ export const receiveTimestamp = ({
228
231
  millis === local.millis && millis === remote.millis
229
232
  ? incrementCounter(Math.max(local.counter, remote.counter) as Counter)
230
233
  : millis === local.millis
231
- ? incrementCounter(local.counter)
232
- : millis === remote.millis
233
- ? incrementCounter(remote.counter)
234
- : Either.right(counterMin),
234
+ ? incrementCounter(local.counter)
235
+ : millis === remote.millis
236
+ ? incrementCounter(remote.counter)
237
+ : Either.right(counterMin),
235
238
  );
236
239
 
237
240
  return { ...local, millis, counter };
package/src/Crypto.ts CHANGED
@@ -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";
@@ -7,6 +7,7 @@ import { randomBytes } from "@noble/hashes/utils";
7
7
  import { Brand, Context, Effect, Layer } from "effect";
8
8
  import { customAlphabet, nanoid } from "nanoid";
9
9
 
10
+ // TODO: Add dynamic import error.
10
11
  export interface Bip39 {
11
12
  readonly make: Effect.Effect<never, never, Mnemonic>;
12
13
 
@@ -19,7 +20,7 @@ export interface Bip39 {
19
20
  ) => Effect.Effect<never, InvalidMnemonicError, Mnemonic>;
20
21
  }
21
22
 
22
- export const Bip39 = Context.Tag<Bip39>("evolu/Bip39");
23
+ export const Bip39 = Context.Tag<Bip39>();
23
24
 
24
25
  export interface InvalidMnemonicError {
25
26
  readonly _tag: "InvalidMnemonicError";
@@ -28,9 +29,9 @@ export interface InvalidMnemonicError {
28
29
  /**
29
30
  * Mnemonic is a password generated by Evolu in BIP39 format.
30
31
  *
31
- * A mnemonic, also known as a "seed phrase," is a set of 12 words in a
32
- * specific order chosen from a predefined list. The purpose of the BIP39
33
- * mnemonic is to provide a human-readable way of storing a private key.
32
+ * A mnemonic, also known as a "seed phrase," is a set of 12 words in a specific
33
+ * order chosen from a predefined list. The purpose of the BIP39 mnemonic is to
34
+ * provide a human-readable way of storing a private key.
34
35
  */
35
36
  export type Mnemonic = string & Brand.Brand<"Mnemonic">;
36
37
 
@@ -39,13 +40,11 @@ export interface NanoId {
39
40
  readonly nanoidAsNodeId: Effect.Effect<never, never, NodeId>;
40
41
  }
41
42
 
42
- export const NanoId = Context.Tag<NanoId>("evolu/NanoId");
43
+ export const NanoId = Context.Tag<NanoId>();
43
44
 
44
- export const NodeId: Schema.BrandSchema<
45
- string,
46
- string & Brand.Brand<"NodeId">
47
- > = Schema.string.pipe(Schema.pattern(/^[\w-]{16}$/), Schema.brand("NodeId"));
48
- export type NodeId = Schema.Schema.To<typeof NodeId>;
45
+ export const NodeId: S.BrandSchema<string, string & Brand.Brand<"NodeId">> =
46
+ S.string.pipe(S.pattern(/^[\w-]{16}$/), S.brand("NodeId"));
47
+ export type NodeId = S.Schema.To<typeof NodeId>;
49
48
 
50
49
  const nanoidForNodeId = customAlphabet("0123456789abcdef", 16);
51
50
 
@@ -57,10 +56,8 @@ export const NanoIdLive = Layer.succeed(
57
56
  }),
58
57
  );
59
58
 
60
- /**
61
- * SLIP-21 implementation
62
- * https://github.com/satoshilabs/slips/blob/master/slip-0021.md
63
- */
59
+ // SLIP-21 implementation
60
+ // https://github.com/satoshilabs/slips/blob/master/slip-0021.md
64
61
  export const slip21Derive = (
65
62
  seed: Uint8Array,
66
63
  path: ReadonlyArray<string>,
@@ -77,9 +74,7 @@ export const slip21Derive = (
77
74
  return m.slice(32, 64);
78
75
  });
79
76
 
80
- /**
81
- * Alias to xsalsa20poly1305, for compatibility with libsodium / nacl
82
- */
77
+ /** Alias to xsalsa20poly1305, for compatibility with libsodium/nacl */
83
78
  export interface SecretBox {
84
79
  readonly seal: (
85
80
  key: Uint8Array,
@@ -92,7 +87,7 @@ export interface SecretBox {
92
87
  ) => Effect.Effect<never, never, Uint8Array>;
93
88
  }
94
89
 
95
- export const SecretBox = Context.Tag<SecretBox>("evolu/SecretBox");
90
+ export const SecretBox = Context.Tag<SecretBox>();
96
91
 
97
92
  export const SecretBoxLive = Layer.succeed(
98
93
  SecretBox,