@evolu/common 7.2.2 → 7.2.3

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.
@@ -24,7 +24,7 @@ type StringKeyOf<T> = Extract<keyof T, string>;
24
24
  *
25
25
  * ```ts
26
26
  * type UserId = string & { readonly __brand: "UserId" };
27
- * const users: Record<UserId, string> = {};
27
+ * const users = createRecord<UserId, string>();
28
28
  * const entries = objectToEntries(users); // [UserId, string][]
29
29
  * ```
30
30
  */
@@ -37,5 +37,20 @@ export declare const objectToEntries: <T extends Record<string, any>>(record: T)
37
37
  export declare const mapObject: <K extends string, V, U>(record: ReadonlyRecord<K, V>, fn: (value: V, key: K) => U) => ReadonlyRecord<K, U>;
38
38
  /** Conditionally excludes a property from an object. */
39
39
  export declare const excludeProp: <T extends object, K extends keyof T>(obj: T, prop: K, condition?: boolean) => typeof condition extends true ? T : Omit<T, K>;
40
+ /**
41
+ * Creates a prototype-less object typed as `Record<K, V>`.
42
+ *
43
+ * Use this function when you need a plain record without a prototype chain
44
+ * (e.g. when keys are controlled by external sources) to avoid prototype
45
+ * pollution and accidental collisions with properties like `__proto__`.
46
+ *
47
+ * Example:
48
+ *
49
+ * ```ts
50
+ * const values = createRecord<string, SqliteValue>();
51
+ * values["__proto__"] = someValue; // safe, no prototype pollution
52
+ * ```
53
+ */
54
+ export declare const createRecord: <K extends string = string, V = unknown>() => Record<K, V>;
40
55
  export {};
41
56
  //# sourceMappingURL=Object.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Object.d.ts","sourceRoot":"","sources":["../../src/Object.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,aAAa,GACxB,OAAO,OAAO,KACb,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAC2B,CAAC;AAE9D;;;GAGG;AACH,MAAM,MAAM,cAAc,CAAC,CAAC,SAAS,MAAM,GAAG,EAAE,CAAC,IAAI,QAAQ,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AAG5E,KAAK,WAAW,CAAC,CAAC,IAAI,OAAO,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC;AAE/C;;;;;;;;;;GAUG;AACH,eAAO,MAAM,eAAe,GAAI,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC3D,QAAQ,CAAC,KACR,aAAa,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAGK,CAAC;AAE1D;;;;GAIG;AACH,eAAO,MAAM,SAAS,GAAI,CAAC,SAAS,MAAM,EAAE,CAAC,EAAE,CAAC,EAC9C,QAAQ,cAAc,CAAC,CAAC,EAAE,CAAC,CAAC,EAC5B,IAAI,CAAC,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,KAC1B,cAAc,CAAC,CAAC,EAAE,CAAC,CAMK,CAAC;AAE5B,wDAAwD;AACxD,eAAO,MAAM,WAAW,GAAI,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,MAAM,CAAC,EAC7D,KAAK,CAAC,EACN,MAAM,CAAC,EACP,YAAY,OAAO,KAClB,OAAO,SAAS,SAAS,IAAI,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC,EAAE,CAAC,CAM/C,CAAC"}
1
+ {"version":3,"file":"Object.d.ts","sourceRoot":"","sources":["../../src/Object.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,aAAa,GACxB,OAAO,OAAO,KACb,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAC2B,CAAC;AAE9D;;;GAGG;AACH,MAAM,MAAM,cAAc,CAAC,CAAC,SAAS,MAAM,GAAG,EAAE,CAAC,IAAI,QAAQ,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AAG5E,KAAK,WAAW,CAAC,CAAC,IAAI,OAAO,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC;AAE/C;;;;;;;;;;GAUG;AACH,eAAO,MAAM,eAAe,GAAI,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC3D,QAAQ,CAAC,KACR,aAAa,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAGK,CAAC;AAE1D;;;;GAIG;AACH,eAAO,MAAM,SAAS,GAAI,CAAC,SAAS,MAAM,EAAE,CAAC,EAAE,CAAC,EAC9C,QAAQ,cAAc,CAAC,CAAC,EAAE,CAAC,CAAC,EAC5B,IAAI,CAAC,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,KAC1B,cAAc,CAAC,CAAC,EAAE,CAAC,CAMK,CAAC;AAE5B,wDAAwD;AACxD,eAAO,MAAM,WAAW,GAAI,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,MAAM,CAAC,EAC7D,KAAK,CAAC,EACN,MAAM,CAAC,EACP,YAAY,OAAO,KAClB,OAAO,SAAS,SAAS,IAAI,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC,EAAE,CAAC,CAM/C,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,YAAY,GAAI,CAAC,SAAS,MAAM,GAAG,MAAM,EAAE,CAAC,GAAG,OAAO,OAAK,MAAM,CAC5E,CAAC,EACD,CAAC,CACqC,CAAC"}
@@ -18,7 +18,7 @@ export const isPlainObject = (value) => Object.prototype.toString.call(value) ==
18
18
  *
19
19
  * ```ts
20
20
  * type UserId = string & { readonly __brand: "UserId" };
21
- * const users: Record<UserId, string> = {};
21
+ * const users = createRecord<UserId, string>();
22
22
  * const entries = objectToEntries(users); // [UserId, string][]
23
23
  * ```
24
24
  */
@@ -40,3 +40,18 @@ export const excludeProp = (obj, prop, condition) => {
40
40
  const { [prop]: _, ...rest } = obj;
41
41
  return rest;
42
42
  };
43
+ /**
44
+ * Creates a prototype-less object typed as `Record<K, V>`.
45
+ *
46
+ * Use this function when you need a plain record without a prototype chain
47
+ * (e.g. when keys are controlled by external sources) to avoid prototype
48
+ * pollution and accidental collisions with properties like `__proto__`.
49
+ *
50
+ * Example:
51
+ *
52
+ * ```ts
53
+ * const values = createRecord<string, SqliteValue>();
54
+ * values["__proto__"] = someValue; // safe, no prototype pollution
55
+ * ```
56
+ */
57
+ export const createRecord = () => Object.create(null);
@@ -81,5 +81,6 @@ export declare const orderNumber: Order<number>;
81
81
  * ```
82
82
  */
83
83
  export declare const orderBigInt: Order<bigint>;
84
- export declare const orderUint8Array: Order<globalThis.Uint8Array>;
84
+ /** An {@link Order} for Uint8Array. */
85
+ export declare const orderUint8Array: Order<Uint8Array>;
85
86
  //# sourceMappingURL=Order.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Order.d.ts","sourceRoot":"","sources":["../../src/Order.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,MAAM,MAAM,KAAK,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,QAAQ,CAAC;AAEnD;;;;GAIG;AACH,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAElC;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,WAAW,GACrB,CAAC,EAAE,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,OAAO,KAAG,KAAK,CAAC,CAAC,CAER,CAAC;AAE5C;;;;;;;;;;GAUG;AACH,eAAO,MAAM,YAAY,GACtB,CAAC,EAAE,OAAO,KAAK,CAAC,CAAC,CAAC,KAAG,KAAK,CAAC,CAAC,CAEhB,CAAC;AAEhB;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,WAAW,EAAE,KAAK,CAAC,MAAM,CAAgC,CAAC;AAEvE;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,WAAW,eAAuC,CAAC;AAEhE;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,WAAW,eAAuC,CAAC;AAEhE,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,UAAU,CAAC,UAAU,CAUxD,CAAC"}
1
+ {"version":3,"file":"Order.d.ts","sourceRoot":"","sources":["../../src/Order.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,MAAM,MAAM,KAAK,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,QAAQ,CAAC;AAEnD;;;;GAIG;AACH,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAElC;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,WAAW,GACrB,CAAC,EAAE,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,OAAO,KAAG,KAAK,CAAC,CAAC,CAER,CAAC;AAE5C;;;;;;;;;;GAUG;AACH,eAAO,MAAM,YAAY,GACtB,CAAC,EAAE,OAAO,KAAK,CAAC,CAAC,CAAC,KAAG,KAAK,CAAC,CAAC,CAEhB,CAAC;AAEhB;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,WAAW,EAAE,KAAK,CAAC,MAAM,CAAgC,CAAC;AAEvE;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,WAAW,eAAuC,CAAC;AAEhE;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,WAAW,eAAuC,CAAC;AAEhE,uCAAuC;AACvC,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,UAAU,CAU7C,CAAC"}
package/dist/src/Order.js CHANGED
@@ -65,6 +65,7 @@ export const orderNumber = createOrder((a, b) => a < b);
65
65
  * ```
66
66
  */
67
67
  export const orderBigInt = createOrder((a, b) => a < b);
68
+ /** An {@link Order} for Uint8Array. */
68
69
  export const orderUint8Array = (a, b) => {
69
70
  if (a.byteLength > b.byteLength)
70
71
  return 1;
@@ -1 +1 @@
1
- {"version":3,"file":"Db.d.ts","sourceRoot":"","sources":["../../../src/local-first/Db.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Db.d.ts","sourceRoot":"","sources":["../../../src/local-first/Db.ts"],"names":[],"mappings":"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"}
@@ -18,8 +18,11 @@ export const defaultDbConfig = {
18
18
  maxDrift: 5 * 60 * 1000,
19
19
  enableLogging: false,
20
20
  };
21
- export const createDbWorkerForPlatform = (platformDeps) => createInitializedWorkerWithHandlers({ init: createDbWorkerDeps(platformDeps), handlers });
22
- const createDbWorkerDeps = (platformDeps) => async (initMessage, postMessage) => {
21
+ export const createDbWorkerForPlatform = (platformDeps) => createInitializedWorkerWithHandlers({
22
+ init: createInit(platformDeps),
23
+ handlers,
24
+ });
25
+ const createInit = (platformDeps) => async (initMessage, postMessage) => {
23
26
  platformDeps.console.enabled = initMessage.config.enableLogging ?? false;
24
27
  const sqliteResult = await createSqlite(platformDeps)(initMessage.config.name, {
25
28
  memory: initMessage.config.inMemory ?? false,
@@ -41,15 +44,6 @@ const createDbWorkerDeps = (platformDeps) => async (initMessage, postMessage) =>
41
44
  const currentVersion = sqlite.exec(sql `select protocolVersion from evolu_version limit 1;`);
42
45
  if (!currentVersion.ok)
43
46
  return currentVersion;
44
- // TODO: Handle version migrations here if needed
45
- // const [{ protocolVersion }] = protocolVersionResult.value.rows;
46
- // if (protocolVersion < currentProtocolVersion) {
47
- // const migrateResult = migrateDatabase({ sqlite })(
48
- // protocolVersion,
49
- // currentProtocolVersion
50
- // );
51
- // if (!migrateResult.ok) return migrateResult;
52
- // }
53
47
  const configResult = sqlite.exec(sql `
54
48
  select
55
49
  clock,
@@ -1,5 +1,5 @@
1
1
  import { createRandomBytes } from "../Crypto.js";
2
- import { isPlainObject } from "../Object.js";
2
+ import { createRecord, isPlainObject } from "../Object.js";
3
3
  import { orderUint8Array } from "../Order.js";
4
4
  import { createId, String } from "../Type.js";
5
5
  export const applyPatches = (patches, current) => patches.reduce((next, patch) => {
@@ -89,7 +89,7 @@ const parse = (obj) => {
89
89
  return obj;
90
90
  };
91
91
  const parseObject = (obj) => {
92
- const result = Object.create(null);
92
+ const result = createRecord();
93
93
  for (const key in obj) {
94
94
  result[key] = parse(obj[key]);
95
95
  }
@@ -1 +1 @@
1
- {"version":3,"file":"Evolu.d.ts","sourceRoot":"","sources":["../../../src/local-first/Evolu.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,2BAA2B,EAAE,MAAM,cAAc,CAAC;AAE3E,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAIhD,OAAO,EAIL,WAAW,EAEZ,MAAM,cAAc,CAAC;AACtB,OAAO,EAAe,cAAc,EAAE,MAAM,aAAa,CAAC;AAC1D,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AACrC,OAAO,EAML,QAAQ,EAKT,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,iBAAiB,EAAE,QAAQ,EAAmB,MAAM,SAAS,CAAC;AAEvE,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAGL,OAAO,EACP,0BAA0B,EAC1B,KAAK,EACL,SAAS,EAET,GAAG,EAGJ,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,WAAW,EACX,WAAW,EAEX,aAAa,EAGb,QAAQ,EAQR,cAAc,EACf,MAAM,aAAa,CAAC;AAErB,OAAO,EAAoB,SAAS,EAAa,MAAM,WAAW,CAAC;AACnE,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAEhD,MAAM,WAAW,WAAY,SAAQ,OAAO,CAAC,QAAQ,CAAC;IACpD;;;;;;;;;;;;;;;;;;;OAmBG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,aAAa,CAAC;IAEjC;;;;OAIG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,KAAK,CAAC,CAAC,SAAS,WAAW,GAAG,WAAW,CAAE,SAAQ,UAAU;IAC5E;;;;;;;;;;;OAWG;IACH,QAAQ,CAAC,cAAc,EAAE,cAAc,CAAC;IAExC,8BAA8B;IAC9B,QAAQ,CAAC,QAAQ,EAAE,MAAM,UAAU,GAAG,IAAI,CAAC;IAE3C;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACH,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC;IAErC;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACH,QAAQ,CAAC,SAAS,EAAE,CAAC,CAAC,SAAS,GAAG,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;IAE9E;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAC,SAAS,GAAG,EAAE,CAAC,SAAS,OAAO,CAAC,CAAC,CAAC,EACxD,OAAO,EAAE,CAAC,GAAG,CAAC,CAAC,KACZ,CAAC,GAAG,0BAA0B,CAAC,CAAC,CAAC,CAAC,CAAC;IAExC;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,cAAc,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,cAAc,CAAC;IAE1D;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,YAAY,EAAE,CAAC,CAAC,SAAS,GAAG,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC;IAExE;;;;;;;;;;;OAWG;IACH,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;IAErC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAyCG;IACH,MAAM,EAAE,QAAQ,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;IAE9B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA8CG;IACH,MAAM,EAAE,QAAQ,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;IAE9B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAyDG;IACH,MAAM,EAAE,QAAQ,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;IAE9B;;;;;;;;OAQG;IACH,QAAQ,CAAC,aAAa,EAAE,CAAC,OAAO,CAAC,EAAE;QACjC,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;KAC3B,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAEpB;;;OAGG;IACH,QAAQ,CAAC,eAAe,EAAE,CACxB,QAAQ,EAAE,QAAQ,EAClB,OAAO,CAAC,EAAE;QACR,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;KAC3B,KACE,OAAO,CAAC,IAAI,CAAC,CAAC;IAEnB;;;OAGG;IACH,QAAQ,CAAC,SAAS,EAAE,MAAM,IAAI,CAAC;IAE/B;;;;;OAKG;IACH,QAAQ,CAAC,cAAc,EAAE,MAAM,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC,CAAC;IAEhE;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACH,QAAQ,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,SAAS,KAAK,UAAU,CAAC;CACrD;AAED,sFAAsF;AACtF,MAAM,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC;AAEpC,iDAAiD;AACjD,MAAM,MAAM,UAAU,GAClB,aAAa,GACb,WAAW,GACX,2BAA2B,GAC3B,cAAc,GACd,iBAAiB,CAAC;AAWtB,MAAM,MAAM,SAAS,GAAG,UAAU,GAChC,iBAAiB,GACjB,OAAO,CAAC,YAAY,CAAC,GACrB,cAAc,GACd,YAAY,GACZ,OAAO,CAAC;AAUV;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,eAAO,MAAM,WAAW,GACrB,MAAM,SAAS,MACf,CAAC,SAAS,WAAW,EACpB,QAAQ,cAAc,CAAC,CAAC,CAAC,SAAS,KAAK,GAAG,CAAC,GAAG,cAAc,CAAC,CAAC,CAAC,EAC/D,SAAS,WAAW,KACnB,KAAK,CAAC,CAAC,CAQK,CAAC;AAoalB,eAAO,MAAM,WAAW,GAAI,CAAC,SAAS,GAAG,EACvC,eAAe,UAAU,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,EACtD,UAAU,UAAU,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,KAChD,KAAK,CAAC,CAAC,CAeT,CAAC"}
1
+ {"version":3,"file":"Evolu.d.ts","sourceRoot":"","sources":["../../../src/local-first/Evolu.ts"],"names":[],"mappings":"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"}
@@ -1,12 +1,12 @@
1
1
  import { pack } from "msgpackr";
2
2
  import { dedupeArray, isNonEmptyArray, isNonEmptyReadonlyArray, } from "../Array.js";
3
- import { assertNonEmptyReadonlyArray } from "../Assert.js";
3
+ import { assert, assertNonEmptyReadonlyArray } from "../Assert.js";
4
4
  import { createCallbacks } from "../Callbacks.js";
5
5
  import { eqArrayNumber } from "../Eq.js";
6
6
  import { exhaustiveCheck } from "../Function.js";
7
7
  import { createInstances } from "../Instances.js";
8
8
  import { err, ok } from "../Result.js";
9
- import { isSqlMutation, SqliteBoolean, } from "../Sqlite.js";
9
+ import { isSqlMutation, SqliteBoolean, sqliteBooleanToBoolean, } from "../Sqlite.js";
10
10
  import { createStore } from "../Store.js";
11
11
  import { createId, } from "../Type.js";
12
12
  import { defaultDbConfig } from "./Db.js";
@@ -193,13 +193,16 @@ const createEvoluInstance = (deps) => (schema, config) => {
193
193
  }
194
194
  else {
195
195
  const { id: _, isDeleted, ...values } = result.value;
196
- const dbChange = DbChange.orThrow({
196
+ const dbChange = {
197
197
  table,
198
198
  id,
199
199
  values,
200
200
  isInsert: kind === "insert" || kind === "upsert",
201
- isDelete: SqliteBoolean.is(isDeleted) ? Boolean(isDeleted) : null,
202
- });
201
+ isDelete: SqliteBoolean.is(isDeleted)
202
+ ? sqliteBooleanToBoolean(isDeleted)
203
+ : null,
204
+ };
205
+ assert(DbChange.is(dbChange), `Invalid DbChange for table '${table}': Please check schema type errors.`);
203
206
  mutateMicrotaskQueue.push([
204
207
  { ...dbChange, ownerId: options?.ownerId },
205
208
  options?.onComplete,
@@ -166,7 +166,7 @@ import { EncryptionKey, RandomBytesDep, SymmetricCryptoDecryptError, SymmetricCr
166
166
  import { Result } from "../Result.js";
167
167
  import { SqliteValue } from "../Sqlite.js";
168
168
  import { NonNegativeInt, PositiveInt } from "../Type.js";
169
- import { OwnerError, Owner, OwnerId, OwnerWriteKey } from "./Owner.js";
169
+ import { Owner, OwnerError, OwnerId, OwnerWriteKey } from "./Owner.js";
170
170
  import { BaseRange, CrdtMessage, DbChange, EncryptedCrdtMessage, EncryptedDbChange, FingerprintRange, RangeType, SkipRange, StorageDep } from "./Storage.js";
171
171
  import { NodeId, Timestamp } from "./Timestamp.js";
172
172
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"Protocol.d.ts","sourceRoot":"","sources":["../../../src/local-first/Protocol.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Protocol.d.ts","sourceRoot":"","sources":["../../../src/local-first/Protocol.ts"],"names":[],"mappings":"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"}
@@ -182,7 +182,7 @@ import { bytesToHex, bytesToUtf8, createBuffer, hexToBytes, utf8ToBytes, } from
182
182
  import { createPadmePadding, } from "../Crypto.js";
183
183
  import { eqArrayNumber } from "../Eq.js";
184
184
  import { computeBalancedBuckets } from "../Number.js";
185
- import { objectToEntries } from "../Object.js";
185
+ import { createRecord, objectToEntries } from "../Object.js";
186
186
  import { err, ok } from "../Result.js";
187
187
  import { Base64Url, base64UrlToUint8Array, between, DateIso, Id, idBytesToId, idBytesTypeValueLength, idToIdBytes, Int, Json, jsonToJsonValue, NonNegativeInt, Number, PositiveInt, uint8ArrayToBase64Url, } from "../Type.js";
188
188
  import { ownerIdToOwnerIdBytes, ownerWriteKeyLength, } from "./Owner.js";
@@ -1195,7 +1195,7 @@ export const decryptAndDecodeDbChange = (deps) => (message, key) => {
1195
1195
  const table = decodeString(buffer);
1196
1196
  const id = decodeId(buffer);
1197
1197
  const length = decodeLength(buffer);
1198
- const values = Object.create(null);
1198
+ const values = createRecord();
1199
1199
  for (let i = 0; i < length; i++) {
1200
1200
  const column = decodeString(buffer);
1201
1201
  const value = decodeSqliteValue(buffer);
@@ -6,13 +6,12 @@ import { RandomDep } from "../Random.js";
6
6
  import { Result } from "../Result.js";
7
7
  import { SqliteDep, SqliteError } from "../Sqlite.js";
8
8
  import { TimeDep } from "../Time.js";
9
- import { DateIso } from "../Type.js";
10
9
  import { CreateWebSocketDep } from "../WebSocket.js";
11
10
  import type { AppOwnerDep, PostMessageDep } from "./Db.js";
12
- import { AppOwner, Owner, OwnerIdBytes, OwnerTransport, ReadonlyOwner } from "./Owner.js";
11
+ import { AppOwner, Owner, OwnerTransport, ReadonlyOwner } from "./Owner.js";
13
12
  import { ProtocolError, ProtocolInvalidDataError, ProtocolTimestampMismatchError } from "./Protocol.js";
14
13
  import { MutationChange } from "./Schema.js";
15
- import { BaseSqliteStorage, CrdtMessage, Storage, StorageInsertTimestampStrategy } from "./Storage.js";
14
+ import { BaseSqliteStorage, Storage } from "./Storage.js";
16
15
  import { Millis, Timestamp, TimestampConfigDep, TimestampCounterOverflowError, TimestampDriftError, TimestampTimeOutOfRangeError } from "./Timestamp.js";
17
16
  export interface Sync extends Disposable {
18
17
  /**
@@ -64,7 +63,6 @@ export interface ClientStorageDep {
64
63
  readonly storage: ClientStorage;
65
64
  }
66
65
  export declare const applyLocalOnlyChange: (deps: SqliteDep & TimeDep & AppOwnerDep) => (change: MutationChange) => Result<void, SqliteError>;
67
- export declare const applyMessageToTimestampAndHistoryTables: (deps: ClientStorageDep & SqliteDep) => (ownerId: OwnerIdBytes, message: CrdtMessage, strategy: StorageInsertTimestampStrategy, date: DateIso) => Result<void, SqliteError>;
68
66
  /**
69
67
  * TODO: Rework for the new owners API.
70
68
  *
@@ -1 +1 @@
1
- {"version":3,"file":"Sync.d.ts","sourceRoot":"","sources":["../../../src/local-first/Sync.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Sync.d.ts","sourceRoot":"","sources":["../../../src/local-first/Sync.ts"],"names":[],"mappings":"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"}
@@ -1,14 +1,14 @@
1
- import { firstInArray, isNonEmptyReadonlyArray, } from "../Array.js";
2
- import { assert } from "../Assert.js";
1
+ import { appendToArray, firstInArray, isNonEmptyReadonlyArray, } from "../Array.js";
2
+ import { assert, assertNonEmptyReadonlyArray } from "../Assert.js";
3
3
  import { eqArrayNumber } from "../Eq.js";
4
4
  import { createTransferableError } from "../Error.js";
5
5
  import { constFalse, constTrue } from "../Function.js";
6
- import { objectToEntries } from "../Object.js";
6
+ import { createRecord, objectToEntries } from "../Object.js";
7
7
  import { createResources } from "../Resources.js";
8
8
  import { err, ok } from "../Result.js";
9
- import { booleanToSqliteBoolean, sql, SqliteBoolean, sqliteBooleanToBoolean, sqliteFalse, } from "../Sqlite.js";
9
+ import { booleanToSqliteBoolean, sql, SqliteBoolean, sqliteBooleanToBoolean, } from "../Sqlite.js";
10
10
  import { createMutex } from "../Task.js";
11
- import { idBytesToId, idToIdBytes, } from "../Type.js";
11
+ import { Boolean, idBytesToId, idToIdBytes, } from "../Type.js";
12
12
  import { ownerIdBytesToOwnerId, ownerIdToOwnerIdBytes, } from "./Owner.js";
13
13
  import { applyProtocolMessageAsClient, createProtocolMessageForSync, createProtocolMessageForUnsubscribe, createProtocolMessageFromCrdtMessages, decryptAndDecodeDbChange, encodeAndEncryptDbChange, SubscriptionFlags, } from "./Protocol.js";
14
14
  import { createBaseSqliteStorage, DbChange, getOwnerUsage, getTimestampInsertStrategy, updateOwnerUsage, } from "./Storage.js";
@@ -271,11 +271,6 @@ const createClientStorage = (deps) => (config) => {
271
271
  if (!applyMessagesResult.ok)
272
272
  return applyMessagesResult;
273
273
  }
274
- // // Apply local mutations atomically with approved messages
275
- // for (const change of localMutations) {
276
- // const result = applyLocalOnlyChange(deps)(change);
277
- // if (!result.ok) return result;
278
- // }
279
274
  return deps.clock.save(clockTimestamp);
280
275
  });
281
276
  if (!transaction.ok)
@@ -306,10 +301,10 @@ const createClientStorage = (deps) => (config) => {
306
301
  return null;
307
302
  }
308
303
  const { rows } = result.value;
309
- assert(rows.length > 0, "Rows must not be empty");
310
- const { table, id } = rows[0];
311
- const values = {};
312
- let isInsert = false;
304
+ assertNonEmptyReadonlyArray(rows, "Every timestamp must have rows");
305
+ const { table, id } = firstInArray(rows);
306
+ const values = createRecord();
307
+ let isInsert;
313
308
  let isDelete = null;
314
309
  for (const r of rows) {
315
310
  assert(r.table === table, "All rows must have the same table");
@@ -318,14 +313,18 @@ const createClientStorage = (deps) => (config) => {
318
313
  case "createdAt":
319
314
  isInsert = true;
320
315
  break;
316
+ case "updatedAt":
317
+ isInsert = false;
318
+ break;
321
319
  case "isDeleted":
322
- assert(SqliteBoolean.is(r.value), "isDeleted column must contain a valid SqliteBoolean (0 or 1)");
320
+ assert(SqliteBoolean.is(r.value), "isDeleted column must contain a valid SqliteBoolean");
323
321
  isDelete = sqliteBooleanToBoolean(r.value);
324
322
  break;
325
323
  default:
326
324
  values[r.column] = r.value;
327
325
  }
328
326
  }
327
+ assert(Boolean.is(isInsert), "isInsert must be in evolu_history");
329
328
  const message = {
330
329
  timestamp: timestampBytesToTimestamp(timestamp),
331
330
  change: DbChange.orThrow({
@@ -345,6 +344,21 @@ const createClientStorage = (deps) => (config) => {
345
344
  const createTransportKey = (transport) => {
346
345
  return `${transport.type}:${transport.url}`;
347
346
  };
347
+ const dbChangeToColumns = (change, now) => {
348
+ let values = objectToEntries(change.values);
349
+ // SystemColumns are not encoded in change.values.
350
+ values = appendToArray(values, [
351
+ change.isInsert ? "createdAt" : "updatedAt",
352
+ now,
353
+ ]);
354
+ if (change.isDelete != null) {
355
+ values = appendToArray(values, [
356
+ "isDeleted",
357
+ booleanToSqliteBoolean(change.isDelete),
358
+ ]);
359
+ }
360
+ return values;
361
+ };
348
362
  export const applyLocalOnlyChange = (deps) => (change) => {
349
363
  if (change.isDelete) {
350
364
  const result = deps.sqlite.exec(sql `
@@ -355,21 +369,15 @@ export const applyLocalOnlyChange = (deps) => (change) => {
355
369
  return result;
356
370
  }
357
371
  else {
358
- const now = deps.time.nowIso();
359
372
  const ownerId = deps.appOwner.id;
360
- let entries = objectToEntries(change.values);
361
- if (change.isDelete !== null) {
362
- entries = [...entries, ["isDeleted", sqliteFalse]];
363
- }
364
- for (const [column, value] of entries) {
373
+ const columns = dbChangeToColumns(change, deps.time.nowIso());
374
+ for (const [column, value] of columns) {
365
375
  const result = deps.sqlite.exec(sql.prepared `
366
376
  insert into ${sql.identifier(change.table)}
367
- ("ownerId", "id", ${sql.identifier(column)}, createdAt, updatedAt)
368
- values (${ownerId}, ${change.id}, ${value}, ${now}, ${now})
377
+ ("ownerId", "id", ${sql.identifier(column)})
378
+ values (${ownerId}, ${change.id}, ${value})
369
379
  on conflict ("ownerId", "id") do update
370
- set
371
- ${sql.identifier(column)} = ${value},
372
- updatedAt = ${now};
380
+ set ${sql.identifier(column)} = ${value};
373
381
  `);
374
382
  if (!result.ok)
375
383
  return result;
@@ -379,21 +387,60 @@ export const applyLocalOnlyChange = (deps) => (change) => {
379
387
  };
380
388
  const applyMessages = (deps) => (ownerId, messages) => {
381
389
  const ownerIdBytes = ownerIdToOwnerIdBytes(ownerId);
382
- const usageResult = getOwnerUsage(deps)(ownerIdBytes, timestampToTimestampBytes(firstInArray(messages).timestamp));
383
- if (!usageResult.ok)
384
- return usageResult;
385
- let { firstTimestamp, lastTimestamp } = usageResult.value;
386
- for (const message of messages) {
387
- const date = timestampToDateIso(message.timestamp);
388
- const result1 = applyMessageToAppTable(deps)(ownerIdBytes, message, date);
389
- if (!result1.ok)
390
- return result1;
391
- const timestamp = timestampToTimestampBytes(message.timestamp);
390
+ const usage = getOwnerUsage(deps)(ownerIdBytes, timestampToTimestampBytes(firstInArray(messages).timestamp));
391
+ if (!usage.ok)
392
+ return usage;
393
+ let { firstTimestamp, lastTimestamp } = usage.value;
394
+ for (const { timestamp, change } of messages) {
395
+ const timestampBytes = timestampToTimestampBytes(timestamp);
396
+ const idBytes = idToIdBytes(change.id);
397
+ const columns = dbChangeToColumns(change, timestampToDateIso(timestamp));
398
+ for (const [column, value] of columns) {
399
+ const updateAppTable = deps.sqlite.exec(sql.prepared `
400
+ with
401
+ existingTimestamp as (
402
+ select 1
403
+ from evolu_history
404
+ where
405
+ "ownerId" = ${ownerIdBytes}
406
+ and "table" = ${change.table}
407
+ and "id" = ${idBytes}
408
+ and "column" = ${column}
409
+ and "timestamp" >= ${timestampBytes}
410
+ limit 1
411
+ )
412
+ insert into ${sql.identifier(change.table)}
413
+ ("ownerId", "id", ${sql.identifier(column)})
414
+ select ${ownerId}, ${change.id}, ${value}
415
+ where not exists (select 1 from existingTimestamp)
416
+ on conflict ("ownerId", "id") do update
417
+ set ${sql.identifier(column)} = ${value}
418
+ where not exists (select 1 from existingTimestamp);
419
+ `);
420
+ if (!updateAppTable.ok)
421
+ return updateAppTable;
422
+ const insertHistory = deps.sqlite.exec(sql.prepared `
423
+ insert into evolu_history
424
+ ("ownerId", "table", "id", "column", "value", "timestamp")
425
+ values
426
+ (
427
+ ${ownerIdBytes},
428
+ ${change.table},
429
+ ${idBytes},
430
+ ${column},
431
+ ${value},
432
+ ${timestampBytes}
433
+ )
434
+ on conflict do nothing;
435
+ `);
436
+ if (!insertHistory.ok)
437
+ return insertHistory;
438
+ }
392
439
  let strategy;
393
- [strategy, firstTimestamp, lastTimestamp] = getTimestampInsertStrategy(timestamp, firstTimestamp, lastTimestamp);
394
- const result2 = applyMessageToTimestampAndHistoryTables(deps)(ownerIdBytes, message, strategy, date);
395
- if (!result2.ok)
396
- return result2;
440
+ [strategy, firstTimestamp, lastTimestamp] = getTimestampInsertStrategy(timestampBytes, firstTimestamp, lastTimestamp);
441
+ const insertTimestamp = deps.storage.insertTimestamp(ownerIdBytes, timestampBytes, strategy);
442
+ if (!insertTimestamp.ok)
443
+ return insertTimestamp;
397
444
  }
398
445
  /**
399
446
  * TODO: Implement proper storedBytes tracking for client using encrypted
@@ -406,73 +453,4 @@ const applyMessages = (deps) => (ownerId, messages) => {
406
453
  return updateUsage;
407
454
  return ok();
408
455
  };
409
- const applyMessageToAppTable = (deps) => (ownerIdBytes, message, date) => {
410
- const ownerId = ownerIdBytesToOwnerId(ownerIdBytes);
411
- const columns = dbChangeToColumns(message.change, date);
412
- for (const [column, value] of columns) {
413
- const result = deps.sqlite.exec(sql.prepared `
414
- with
415
- existingTimestamp as (
416
- select 1
417
- from evolu_history
418
- where
419
- "ownerId" = ${ownerIdBytes}
420
- and "table" = ${message.change.table}
421
- and "id" = ${idToIdBytes(message.change.id)}
422
- and "column" = ${column}
423
- and "timestamp" >= ${timestampToTimestampBytes(message.timestamp)}
424
- limit 1
425
- )
426
- insert into ${sql.identifier(message.change.table)}
427
- ("ownerId", "id", ${sql.identifier(column)}, updatedAt)
428
- select ${ownerId}, ${message.change.id}, ${value}, ${date}
429
- where not exists (select 1 from existingTimestamp)
430
- on conflict ("ownerId", "id") do update
431
- set
432
- ${sql.identifier(column)} = ${value},
433
- updatedAt = ${date}
434
- where not exists (select 1 from existingTimestamp);
435
- `);
436
- if (!result.ok)
437
- return result;
438
- }
439
- return ok();
440
- };
441
- export const applyMessageToTimestampAndHistoryTables = (deps) => (ownerId, message, strategy, date) => {
442
- const timestamp = timestampToTimestampBytes(message.timestamp);
443
- const id = idToIdBytes(message.change.id);
444
- const result = deps.storage.insertTimestamp(ownerId, timestamp, strategy);
445
- if (!result.ok)
446
- return result;
447
- const columns = dbChangeToColumns(message.change, date);
448
- for (const [column, value] of columns) {
449
- const result = deps.sqlite.exec(sql.prepared `
450
- insert into evolu_history
451
- ("ownerId", "table", "id", "column", "value", "timestamp")
452
- values
453
- (
454
- ${ownerId},
455
- ${message.change.table},
456
- ${id},
457
- ${column},
458
- ${value},
459
- ${timestamp}
460
- )
461
- on conflict do nothing;
462
- `);
463
- if (!result.ok)
464
- return result;
465
- }
466
- return ok();
467
- };
468
- const dbChangeToColumns = (change, date) => {
469
- const entries = [...objectToEntries(change.values)];
470
- if (change.isInsert) {
471
- entries.push(["createdAt", date]);
472
- }
473
- if (change.isDelete !== null) {
474
- entries.push(["isDeleted", booleanToSqliteBoolean(change.isDelete)]);
475
- }
476
- return entries;
477
- };
478
456
  export const initialSyncState = { type: "SyncStateInitial" };
@@ -154,6 +154,19 @@ export type TimestampBytes = typeof TimestampBytes.Type;
154
154
  export declare const timestampBytesLength: number & import("../Brand.js").Brand<"Int"> & import("../Brand.js").Brand<"NonNegative">;
155
155
  export declare const timestampToTimestampBytes: (timestamp: Timestamp) => TimestampBytes;
156
156
  export declare const timestampBytesToTimestamp: (timestamp: TimestampBytes) => Timestamp;
157
+ /**
158
+ * An {@link Order} for {@link TimestampBytes}.
159
+ *
160
+ * This `Order` uses lexicographic byte order to compare serialized
161
+ * {@link TimestampBytes} produced by {@link timestampToTimestampBytes}. See
162
+ * {@link orderUint8Array} for the underlying implementation.
163
+ */
157
164
  export declare const orderTimestampBytes: Order<TimestampBytes>;
165
+ /**
166
+ * Convert a {@link Timestamp} to an ISO 8601 {@link DateIso} string.
167
+ *
168
+ * The conversion uses the timestamp's `millis` (a {@link Millis} value) and
169
+ * `Date.prototype.toISOString()` to produce a `DateIso`.
170
+ */
158
171
  export declare const timestampToDateIso: (timestamp: Timestamp) => DateIso;
159
172
  //# sourceMappingURL=Timestamp.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Timestamp.d.ts","sourceRoot":"","sources":["../../../src/local-first/Timestamp.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Timestamp.d.ts","sourceRoot":"","sources":["../../../src/local-first/Timestamp.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAG9C,OAAO,EAAE,KAAK,EAAmB,MAAM,aAAa,CAAC;AACrD,OAAO,EAAW,MAAM,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AACrC,OAAO,EAEL,OAAO,EACP,SAAS,EAOV,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,eAAe;IAC9B;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,eAAe,EAAE,eAAe,CAAC;CAC3C;AAED,MAAM,MAAM,cAAc,GACtB,mBAAmB,GACnB,6BAA6B,GAC7B,4BAA4B,CAAC;AAEjC,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,IAAI,EAAE,qBAAqB,CAAC;IACrC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,6BAA6B;IAC5C,QAAQ,CAAC,IAAI,EAAE,+BAA+B,CAAC;CAChD;AAED,MAAM,WAAW,4BAA4B;IAC3C,QAAQ,CAAC,IAAI,EAAE,8BAA8B,CAAC;CAC/C;AAED;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,MAAM,kwBAGlB,CAAC;AACF,MAAM,MAAM,MAAM,GAAG,OAAO,MAAM,CAAC,IAAI,CAAC;AAExC,eAAO,MAAM,SAAS,EAAQ,MAAM,CAAC;AACrC,eAAO,MAAM,SAAS,EAA4B,MAAM,CAAC;AAEzD,eAAO,MAAM,OAAO,8vBAGnB,CAAC;AACF,MAAM,MAAM,OAAO,GAAG,OAAO,OAAO,CAAC,IAAI,CAAC;AAE1C,eAAO,MAAM,UAAU,EAAQ,OAAO,CAAC;AACvC,eAAO,MAAM,UAAU,EAAY,OAAO,CAAC;AAE3C;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,eAAO,MAAM,MAAM,wPAA4C,CAAC;AAChE,MAAM,MAAM,MAAM,GAAG,OAAO,MAAM,CAAC,IAAI,CAAC;AAExC,eAAO,MAAM,SAAS,EAAyB,MAAM,CAAC;AACtD,eAAO,MAAM,SAAS,EAAyB,MAAM,CAAC;AAEtD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuDG;AACH,eAAO,MAAM,SAAS;;;;EAIpB,CAAC;AACH,MAAM,WAAW,SAAU,SAAQ,SAAS,CAAC,OAAO,SAAS,CAAC;CAAG;AAEjE,yDAAyD;AACzD,eAAO,MAAM,WAAW;;;;EAItB,CAAC;AAEH,eAAO,MAAM,eAAe,GAAI,+BAI7B,OAAO,CAAC,SAAS,CAAM,KAAG,SAA0C,CAAC;AAExE,eAAO,MAAM,sBAAsB,GAAI,MAAM,cAAc,KAAG,SAG7D,CAAC;AA6BF,eAAO,MAAM,aAAa,GACvB,MAAM,OAAO,GAAG,kBAAkB,MAEjC,WAAW,SAAS,KACnB,MAAM,CACP,SAAS,EACP,mBAAmB,GACnB,6BAA6B,GAC7B,4BAA4B,CAgB/B,CAAC;AAEJ,eAAO,MAAM,gBAAgB,GAC1B,MAAM,OAAO,GAAG,kBAAkB,MAEjC,OAAO,SAAS,EAChB,QAAQ,SAAS,KAChB,MAAM,CACP,SAAS,EACP,mBAAmB,GACnB,6BAA6B,GAC7B,4BAA4B,CAqB/B,CAAC;AAEJ,0DAA0D;AAC1D,eAAO,MAAM,cAAc,2WAAsC,CAAC;AAClE,MAAM,MAAM,cAAc,GAAG,OAAO,cAAc,CAAC,IAAI,CAAC;AAExD,eAAO,MAAM,oBAAoB,0FAA6B,CAAC;AAE/D,eAAO,MAAM,yBAAyB,GACpC,WAAW,SAAS,KACnB,cA0BF,CAAC;AAEF,eAAO,MAAM,yBAAyB,GACpC,WAAW,cAAc,KACxB,SAoBF,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB,EAAE,KAAK,CAAC,cAAc,CAAmB,CAAC;AAE1E;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,GAAI,WAAW,SAAS,KAAG,OAEL,CAAC"}
@@ -218,7 +218,20 @@ export const timestampBytesToTimestamp = (timestamp) => {
218
218
  }
219
219
  return { millis: Number(millis), counter, nodeId };
220
220
  };
221
+ /**
222
+ * An {@link Order} for {@link TimestampBytes}.
223
+ *
224
+ * This `Order` uses lexicographic byte order to compare serialized
225
+ * {@link TimestampBytes} produced by {@link timestampToTimestampBytes}. See
226
+ * {@link orderUint8Array} for the underlying implementation.
227
+ */
221
228
  export const orderTimestampBytes = orderUint8Array;
229
+ /**
230
+ * Convert a {@link Timestamp} to an ISO 8601 {@link DateIso} string.
231
+ *
232
+ * The conversion uses the timestamp's `millis` (a {@link Millis} value) and
233
+ * `Date.prototype.toISOString()` to produce a `DateIso`.
234
+ */
222
235
  export const timestampToDateIso = (timestamp) =>
223
- // `as DateIso` is safe because the timestamp is always valid
236
+ // `as DateIso` is safe because Timestamp guarantees a valid `millis`
224
237
  new Date(timestamp.millis).toISOString();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@evolu/common",
3
- "version": "7.2.2",
3
+ "version": "7.2.3",
4
4
  "description": "TypeScript library and local-first platform",
5
5
  "keywords": [
6
6
  "evolu",
package/src/Object.ts CHANGED
@@ -31,7 +31,7 @@ type StringKeyOf<T> = Extract<keyof T, string>;
31
31
  *
32
32
  * ```ts
33
33
  * type UserId = string & { readonly __brand: "UserId" };
34
- * const users: Record<UserId, string> = {};
34
+ * const users = createRecord<UserId, string>();
35
35
  * const entries = objectToEntries(users); // [UserId, string][]
36
36
  * ```
37
37
  */
@@ -70,3 +70,22 @@ export const excludeProp = <T extends object, K extends keyof T>(
70
70
  const { [prop]: _, ...rest } = obj;
71
71
  return rest;
72
72
  };
73
+
74
+ /**
75
+ * Creates a prototype-less object typed as `Record<K, V>`.
76
+ *
77
+ * Use this function when you need a plain record without a prototype chain
78
+ * (e.g. when keys are controlled by external sources) to avoid prototype
79
+ * pollution and accidental collisions with properties like `__proto__`.
80
+ *
81
+ * Example:
82
+ *
83
+ * ```ts
84
+ * const values = createRecord<string, SqliteValue>();
85
+ * values["__proto__"] = someValue; // safe, no prototype pollution
86
+ * ```
87
+ */
88
+ export const createRecord = <K extends string = string, V = unknown>(): Record<
89
+ K,
90
+ V
91
+ > => Object.create(null) as Record<K, V>;
package/src/Order.ts CHANGED
@@ -94,7 +94,8 @@ export const orderNumber = createOrder<number>((a, b) => a < b);
94
94
  */
95
95
  export const orderBigInt = createOrder<bigint>((a, b) => a < b);
96
96
 
97
- export const orderUint8Array: Order<globalThis.Uint8Array> = (a, b) => {
97
+ /** An {@link Order} for Uint8Array. */
98
+ export const orderUint8Array: Order<Uint8Array> = (a, b) => {
98
99
  if (a.byteLength > b.byteLength) return 1;
99
100
  if (a.byteLength < b.byteLength) return -1;
100
101
 
@@ -336,9 +336,12 @@ export const createDbWorkerForPlatform = (
336
336
  DbWorkerInput,
337
337
  DbWorkerOutput,
338
338
  DbWorkerDeps
339
- >({ init: createDbWorkerDeps(platformDeps), handlers });
339
+ >({
340
+ init: createInit(platformDeps),
341
+ handlers,
342
+ });
340
343
 
341
- const createDbWorkerDeps =
344
+ const createInit =
342
345
  (platformDeps: DbWorkerPlatformDeps) =>
343
346
  async (
344
347
  initMessage: Extract<DbWorkerInput, { type: "init" }>,
@@ -376,16 +379,6 @@ const createDbWorkerDeps =
376
379
  }>(sql`select protocolVersion from evolu_version limit 1;`);
377
380
  if (!currentVersion.ok) return currentVersion;
378
381
 
379
- // TODO: Handle version migrations here if needed
380
- // const [{ protocolVersion }] = protocolVersionResult.value.rows;
381
- // if (protocolVersion < currentProtocolVersion) {
382
- // const migrateResult = migrateDatabase({ sqlite })(
383
- // protocolVersion,
384
- // currentProtocolVersion
385
- // );
386
- // if (!migrateResult.ok) return migrateResult;
387
- // }
388
-
389
382
  const configResult = sqlite.exec<{
390
383
  clock: TimestampBytes;
391
384
  appOwnerId: OwnerId;
@@ -1,5 +1,5 @@
1
1
  import { createRandomBytes } from "../Crypto.js";
2
- import { isPlainObject, ReadonlyRecord } from "../Object.js";
2
+ import { createRecord, isPlainObject, ReadonlyRecord } from "../Object.js";
3
3
  import { orderUint8Array } from "../Order.js";
4
4
  import { SqliteValue } from "../Sqlite.js";
5
5
  import { createId, String } from "../Type.js";
@@ -136,7 +136,7 @@ const parse = (obj: unknown): unknown => {
136
136
  const parseObject = (
137
137
  obj: ReadonlyRecord<string, unknown>,
138
138
  ): ReadonlyRecord<string, unknown> => {
139
- const result = Object.create(null) as Record<string, unknown>;
139
+ const result = createRecord();
140
140
  for (const key in obj) {
141
141
  result[key] = parse(obj[key]);
142
142
  }
@@ -4,7 +4,7 @@ import {
4
4
  isNonEmptyArray,
5
5
  isNonEmptyReadonlyArray,
6
6
  } from "../Array.js";
7
- import { assertNonEmptyReadonlyArray } from "../Assert.js";
7
+ import { assert, assertNonEmptyReadonlyArray } from "../Assert.js";
8
8
  import { createCallbacks } from "../Callbacks.js";
9
9
  import { ConsoleDep } from "../Console.js";
10
10
  import { RandomBytesDep, SymmetricCryptoDecryptError } from "../Crypto.js";
@@ -17,6 +17,7 @@ import {
17
17
  isSqlMutation,
18
18
  SafeSql,
19
19
  SqliteBoolean,
20
+ sqliteBooleanToBoolean,
20
21
  SqliteError,
21
22
  SqliteQuery,
22
23
  } from "../Sqlite.js";
@@ -730,13 +731,20 @@ const createEvoluInstance =
730
731
  } else {
731
732
  const { id: _, isDeleted, ...values } = result.value;
732
733
 
733
- const dbChange = DbChange.orThrow({
734
+ const dbChange = {
734
735
  table,
735
736
  id,
736
737
  values,
737
738
  isInsert: kind === "insert" || kind === "upsert",
738
- isDelete: SqliteBoolean.is(isDeleted) ? Boolean(isDeleted) : null,
739
- });
739
+ isDelete: SqliteBoolean.is(isDeleted)
740
+ ? sqliteBooleanToBoolean(isDeleted)
741
+ : null,
742
+ };
743
+
744
+ assert(
745
+ DbChange.is(dbChange),
746
+ `Invalid DbChange for table '${table}': Please check schema type errors.`,
747
+ );
740
748
 
741
749
  mutateMicrotaskQueue.push([
742
750
  { ...dbChange, ownerId: options?.ownerId },
@@ -198,7 +198,7 @@ import {
198
198
  } from "../Crypto.js";
199
199
  import { eqArrayNumber } from "../Eq.js";
200
200
  import { computeBalancedBuckets } from "../Number.js";
201
- import { objectToEntries } from "../Object.js";
201
+ import { createRecord, objectToEntries } from "../Object.js";
202
202
  import { err, ok, Result } from "../Result.js";
203
203
  import { SqliteValue } from "../Sqlite.js";
204
204
  import {
@@ -221,8 +221,8 @@ import {
221
221
  } from "../Type.js";
222
222
  import { Predicate } from "../Types.js";
223
223
  import {
224
- OwnerError,
225
224
  Owner,
225
+ OwnerError,
226
226
  OwnerId,
227
227
  OwnerIdBytes,
228
228
  ownerIdToOwnerIdBytes,
@@ -1816,7 +1816,7 @@ export const decryptAndDecodeDbChange =
1816
1816
  const id = decodeId(buffer);
1817
1817
 
1818
1818
  const length = decodeLength(buffer);
1819
- const values = Object.create(null) as Record<string, SqliteValue>;
1819
+ const values = createRecord<string, SqliteValue>();
1820
1820
 
1821
1821
  for (let i = 0; i < length; i++) {
1822
1822
  const column = decodeString(buffer);
@@ -1,10 +1,11 @@
1
1
  import {
2
+ appendToArray,
2
3
  firstInArray,
3
4
  isNonEmptyReadonlyArray,
4
5
  NonEmptyArray,
5
6
  NonEmptyReadonlyArray,
6
7
  } from "../Array.js";
7
- import { assert } from "../Assert.js";
8
+ import { assert, assertNonEmptyReadonlyArray } from "../Assert.js";
8
9
  import { Brand } from "../Brand.js";
9
10
  import { ConsoleDep } from "../Console.js";
10
11
  import {
@@ -15,7 +16,7 @@ import {
15
16
  import { eqArrayNumber } from "../Eq.js";
16
17
  import { createTransferableError, TransferableError } from "../Error.js";
17
18
  import { constFalse, constTrue } from "../Function.js";
18
- import { objectToEntries } from "../Object.js";
19
+ import { createRecord, objectToEntries } from "../Object.js";
19
20
  import { RandomDep } from "../Random.js";
20
21
  import { createResources } from "../Resources.js";
21
22
  import { err, ok, Result } from "../Result.js";
@@ -26,12 +27,12 @@ import {
26
27
  sqliteBooleanToBoolean,
27
28
  SqliteDep,
28
29
  SqliteError,
29
- sqliteFalse,
30
30
  SqliteValue,
31
31
  } from "../Sqlite.js";
32
32
  import { AbortError, createMutex } from "../Task.js";
33
33
  import { TimeDep } from "../Time.js";
34
34
  import {
35
+ Boolean,
35
36
  DateIso,
36
37
  IdBytes,
37
38
  idBytesToId,
@@ -44,7 +45,6 @@ import {
44
45
  AppOwner,
45
46
  Owner,
46
47
  OwnerId,
47
- OwnerIdBytes,
48
48
  ownerIdBytesToOwnerId,
49
49
  ownerIdToOwnerIdBytes,
50
50
  OwnerTransport,
@@ -71,7 +71,6 @@ import {
71
71
  getOwnerUsage,
72
72
  getTimestampInsertStrategy,
73
73
  Storage,
74
- StorageInsertTimestampStrategy,
75
74
  StorageWriteError,
76
75
  updateOwnerUsage,
77
76
  } from "./Storage.js";
@@ -451,8 +450,7 @@ const createClientStorage =
451
450
  SqliteDep &
452
451
  SymmetricCryptoDep &
453
452
  TimeDep &
454
- TimestampConfigDep &
455
- PostMessageDep,
453
+ TimestampConfigDep,
456
454
  ) =>
457
455
  (config: {
458
456
  onError: (
@@ -545,12 +543,6 @@ const createClientStorage =
545
543
  if (!applyMessagesResult.ok) return applyMessagesResult;
546
544
  }
547
545
 
548
- // // Apply local mutations atomically with approved messages
549
- // for (const change of localMutations) {
550
- // const result = applyLocalOnlyChange(deps)(change);
551
- // if (!result.ok) return result;
552
- // }
553
-
554
546
  return deps.clock.save(clockTimestamp);
555
547
  });
556
548
 
@@ -592,11 +584,11 @@ const createClientStorage =
592
584
  }
593
585
 
594
586
  const { rows } = result.value;
595
- assert(rows.length > 0, "Rows must not be empty");
587
+ assertNonEmptyReadonlyArray(rows, "Every timestamp must have rows");
596
588
 
597
- const { table, id } = rows[0];
598
- const values: Record<string, SqliteValue> = {};
599
- let isInsert = false;
589
+ const { table, id } = firstInArray(rows);
590
+ const values = createRecord<string, SqliteValue>();
591
+ let isInsert;
600
592
  let isDelete: boolean | null = null;
601
593
 
602
594
  for (const r of rows) {
@@ -606,10 +598,13 @@ const createClientStorage =
606
598
  case "createdAt":
607
599
  isInsert = true;
608
600
  break;
601
+ case "updatedAt":
602
+ isInsert = false;
603
+ break;
609
604
  case "isDeleted":
610
605
  assert(
611
606
  SqliteBoolean.is(r.value),
612
- "isDeleted column must contain a valid SqliteBoolean (0 or 1)",
607
+ "isDeleted column must contain a valid SqliteBoolean",
613
608
  );
614
609
  isDelete = sqliteBooleanToBoolean(r.value);
615
610
  break;
@@ -618,6 +613,8 @@ const createClientStorage =
618
613
  }
619
614
  }
620
615
 
616
+ assert(Boolean.is(isInsert), "isInsert must be in evolu_history");
617
+
621
618
  const message: CrdtMessage = {
622
619
  timestamp: timestampBytesToTimestamp(timestamp),
623
620
  change: DbChange.orThrow({
@@ -643,6 +640,24 @@ const createTransportKey = (transport: OwnerTransport): TransportKey => {
643
640
  return `${transport.type}:${transport.url}` as TransportKey;
644
641
  };
645
642
 
643
+ const dbChangeToColumns = (change: DbChange, now: DateIso) => {
644
+ let values = objectToEntries(change.values);
645
+
646
+ // SystemColumns are not encoded in change.values.
647
+ values = appendToArray(values, [
648
+ change.isInsert ? "createdAt" : "updatedAt",
649
+ now,
650
+ ]);
651
+ if (change.isDelete != null) {
652
+ values = appendToArray(values, [
653
+ "isDeleted",
654
+ booleanToSqliteBoolean(change.isDelete),
655
+ ]);
656
+ }
657
+
658
+ return values;
659
+ };
660
+
646
661
  export const applyLocalOnlyChange =
647
662
  (deps: SqliteDep & TimeDep & AppOwnerDep) =>
648
663
  (change: MutationChange): Result<void, SqliteError> => {
@@ -653,23 +668,16 @@ export const applyLocalOnlyChange =
653
668
  `);
654
669
  if (!result.ok) return result;
655
670
  } else {
656
- const now = deps.time.nowIso();
657
671
  const ownerId = deps.appOwner.id;
672
+ const columns = dbChangeToColumns(change, deps.time.nowIso());
658
673
 
659
- let entries = objectToEntries(change.values);
660
- if (change.isDelete !== null) {
661
- entries = [...entries, ["isDeleted", sqliteFalse]];
662
- }
663
-
664
- for (const [column, value] of entries) {
674
+ for (const [column, value] of columns) {
665
675
  const result = deps.sqlite.exec(sql.prepared`
666
676
  insert into ${sql.identifier(change.table)}
667
- ("ownerId", "id", ${sql.identifier(column)}, createdAt, updatedAt)
668
- values (${ownerId}, ${change.id}, ${value}, ${now}, ${now})
677
+ ("ownerId", "id", ${sql.identifier(column)})
678
+ values (${ownerId}, ${change.id}, ${value})
669
679
  on conflict ("ownerId", "id") do update
670
- set
671
- ${sql.identifier(column)} = ${value},
672
- updatedAt = ${now};
680
+ set ${sql.identifier(column)} = ${value};
673
681
  `);
674
682
  if (!result.ok) return result;
675
683
  }
@@ -686,35 +694,75 @@ const applyMessages =
686
694
  ): Result<void, SqliteError> => {
687
695
  const ownerIdBytes = ownerIdToOwnerIdBytes(ownerId);
688
696
 
689
- const usageResult = getOwnerUsage(deps)(
697
+ const usage = getOwnerUsage(deps)(
690
698
  ownerIdBytes,
691
699
  timestampToTimestampBytes(firstInArray(messages).timestamp),
692
700
  );
693
- if (!usageResult.ok) return usageResult;
694
-
695
- let { firstTimestamp, lastTimestamp } = usageResult.value;
701
+ if (!usage.ok) return usage;
702
+
703
+ let { firstTimestamp, lastTimestamp } = usage.value;
704
+
705
+ for (const { timestamp, change } of messages) {
706
+ const timestampBytes = timestampToTimestampBytes(timestamp);
707
+ const idBytes = idToIdBytes(change.id);
708
+ const columns = dbChangeToColumns(change, timestampToDateIso(timestamp));
709
+
710
+ for (const [column, value] of columns) {
711
+ const updateAppTable = deps.sqlite.exec(sql.prepared`
712
+ with
713
+ existingTimestamp as (
714
+ select 1
715
+ from evolu_history
716
+ where
717
+ "ownerId" = ${ownerIdBytes}
718
+ and "table" = ${change.table}
719
+ and "id" = ${idBytes}
720
+ and "column" = ${column}
721
+ and "timestamp" >= ${timestampBytes}
722
+ limit 1
723
+ )
724
+ insert into ${sql.identifier(change.table)}
725
+ ("ownerId", "id", ${sql.identifier(column)})
726
+ select ${ownerId}, ${change.id}, ${value}
727
+ where not exists (select 1 from existingTimestamp)
728
+ on conflict ("ownerId", "id") do update
729
+ set ${sql.identifier(column)} = ${value}
730
+ where not exists (select 1 from existingTimestamp);
731
+ `);
696
732
 
697
- for (const message of messages) {
698
- const date = timestampToDateIso(message.timestamp);
699
- const result1 = applyMessageToAppTable(deps)(ownerIdBytes, message, date);
700
- if (!result1.ok) return result1;
733
+ if (!updateAppTable.ok) return updateAppTable;
734
+
735
+ const insertHistory = deps.sqlite.exec(sql.prepared`
736
+ insert into evolu_history
737
+ ("ownerId", "table", "id", "column", "value", "timestamp")
738
+ values
739
+ (
740
+ ${ownerIdBytes},
741
+ ${change.table},
742
+ ${idBytes},
743
+ ${column},
744
+ ${value},
745
+ ${timestampBytes}
746
+ )
747
+ on conflict do nothing;
748
+ `);
701
749
 
702
- const timestamp = timestampToTimestampBytes(message.timestamp);
750
+ if (!insertHistory.ok) return insertHistory;
751
+ }
703
752
 
704
753
  let strategy;
705
754
  [strategy, firstTimestamp, lastTimestamp] = getTimestampInsertStrategy(
706
- timestamp,
755
+ timestampBytes,
707
756
  firstTimestamp,
708
757
  lastTimestamp,
709
758
  );
710
759
 
711
- const result2 = applyMessageToTimestampAndHistoryTables(deps)(
760
+ const insertTimestamp = deps.storage.insertTimestamp(
712
761
  ownerIdBytes,
713
- message,
762
+ timestampBytes,
714
763
  strategy,
715
- date,
716
764
  );
717
- if (!result2.ok) return result2;
765
+ if (!insertTimestamp.ok) return insertTimestamp;
718
766
  }
719
767
 
720
768
  /**
@@ -733,98 +781,6 @@ const applyMessages =
733
781
  return ok();
734
782
  };
735
783
 
736
- const applyMessageToAppTable =
737
- (deps: SqliteDep) =>
738
- (
739
- ownerIdBytes: OwnerIdBytes,
740
- message: CrdtMessage,
741
- date: DateIso,
742
- ): Result<void, SqliteError> => {
743
- const ownerId = ownerIdBytesToOwnerId(ownerIdBytes);
744
- const columns = dbChangeToColumns(message.change, date);
745
-
746
- for (const [column, value] of columns) {
747
- const result = deps.sqlite.exec(sql.prepared`
748
- with
749
- existingTimestamp as (
750
- select 1
751
- from evolu_history
752
- where
753
- "ownerId" = ${ownerIdBytes}
754
- and "table" = ${message.change.table}
755
- and "id" = ${idToIdBytes(message.change.id)}
756
- and "column" = ${column}
757
- and "timestamp" >= ${timestampToTimestampBytes(message.timestamp)}
758
- limit 1
759
- )
760
- insert into ${sql.identifier(message.change.table)}
761
- ("ownerId", "id", ${sql.identifier(column)}, updatedAt)
762
- select ${ownerId}, ${message.change.id}, ${value}, ${date}
763
- where not exists (select 1 from existingTimestamp)
764
- on conflict ("ownerId", "id") do update
765
- set
766
- ${sql.identifier(column)} = ${value},
767
- updatedAt = ${date}
768
- where not exists (select 1 from existingTimestamp);
769
- `);
770
-
771
- if (!result.ok) return result;
772
- }
773
-
774
- return ok();
775
- };
776
-
777
- export const applyMessageToTimestampAndHistoryTables =
778
- (deps: ClientStorageDep & SqliteDep) =>
779
- (
780
- ownerId: OwnerIdBytes,
781
- message: CrdtMessage,
782
- strategy: StorageInsertTimestampStrategy,
783
- date: DateIso,
784
- ): Result<void, SqliteError> => {
785
- const timestamp = timestampToTimestampBytes(message.timestamp);
786
- const id = idToIdBytes(message.change.id);
787
-
788
- const result = deps.storage.insertTimestamp(ownerId, timestamp, strategy);
789
- if (!result.ok) return result;
790
-
791
- const columns = dbChangeToColumns(message.change, date);
792
-
793
- for (const [column, value] of columns) {
794
- const result = deps.sqlite.exec(sql.prepared`
795
- insert into evolu_history
796
- ("ownerId", "table", "id", "column", "value", "timestamp")
797
- values
798
- (
799
- ${ownerId},
800
- ${message.change.table},
801
- ${id},
802
- ${column},
803
- ${value},
804
- ${timestamp}
805
- )
806
- on conflict do nothing;
807
- `);
808
- if (!result.ok) return result;
809
- }
810
-
811
- return ok();
812
- };
813
-
814
- const dbChangeToColumns = (
815
- change: DbChange,
816
- date: DateIso,
817
- ): Array<[string, SqliteValue | DateIso]> => {
818
- const entries = [...objectToEntries(change.values)];
819
- if (change.isInsert) {
820
- entries.push(["createdAt", date]);
821
- }
822
- if (change.isDelete !== null) {
823
- entries.push(["isDeleted", booleanToSqliteBoolean(change.isDelete)]);
824
- }
825
- return entries;
826
- };
827
-
828
784
  /**
829
785
  * TODO: Rework for the new owners API.
830
786
  *
@@ -336,8 +336,21 @@ export const timestampBytesToTimestamp = (
336
336
  return { millis: Number(millis), counter, nodeId } as Timestamp;
337
337
  };
338
338
 
339
+ /**
340
+ * An {@link Order} for {@link TimestampBytes}.
341
+ *
342
+ * This `Order` uses lexicographic byte order to compare serialized
343
+ * {@link TimestampBytes} produced by {@link timestampToTimestampBytes}. See
344
+ * {@link orderUint8Array} for the underlying implementation.
345
+ */
339
346
  export const orderTimestampBytes: Order<TimestampBytes> = orderUint8Array;
340
347
 
348
+ /**
349
+ * Convert a {@link Timestamp} to an ISO 8601 {@link DateIso} string.
350
+ *
351
+ * The conversion uses the timestamp's `millis` (a {@link Millis} value) and
352
+ * `Date.prototype.toISOString()` to produce a `DateIso`.
353
+ */
341
354
  export const timestampToDateIso = (timestamp: Timestamp): DateIso =>
342
- // `as DateIso` is safe because the timestamp is always valid
355
+ // `as DateIso` is safe because Timestamp guarantees a valid `millis`
343
356
  new Date(timestamp.millis).toISOString() as DateIso;