@evolu/common 6.0.1-preview.33 → 6.0.1-preview.35

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 (55) hide show
  1. package/README.md +2 -2
  2. package/dist/src/Array.d.ts +3 -3
  3. package/dist/src/Array.js +3 -3
  4. package/dist/src/Crypto.d.ts +6 -8
  5. package/dist/src/Crypto.d.ts.map +1 -1
  6. package/dist/src/Crypto.js +9 -9
  7. package/dist/src/Evolu/Db.d.ts.map +1 -1
  8. package/dist/src/Evolu/Db.js +4 -4
  9. package/dist/src/Evolu/Evolu.d.ts +9 -4
  10. package/dist/src/Evolu/Evolu.d.ts.map +1 -1
  11. package/dist/src/Evolu/Evolu.js +14 -14
  12. package/dist/src/Evolu/Protocol.d.ts +27 -2
  13. package/dist/src/Evolu/Protocol.d.ts.map +1 -1
  14. package/dist/src/Evolu/Protocol.js +71 -31
  15. package/dist/src/Evolu/PublicKysely.d.ts.map +1 -1
  16. package/dist/src/Evolu/PublicKysely.js +0 -1
  17. package/dist/src/Evolu/Query.d.ts +1 -1
  18. package/dist/src/Evolu/Query.d.ts.map +1 -1
  19. package/dist/src/Evolu/Query.js +1 -1
  20. package/dist/src/Evolu/Schema.d.ts +28 -22
  21. package/dist/src/Evolu/Schema.d.ts.map +1 -1
  22. package/dist/src/Evolu/Schema.js +37 -32
  23. package/dist/src/Evolu/Storage.d.ts +11 -2
  24. package/dist/src/Evolu/Storage.d.ts.map +1 -1
  25. package/dist/src/Evolu/Storage.js +21 -3
  26. package/dist/src/Evolu/Sync.d.ts +4 -3
  27. package/dist/src/Evolu/Sync.d.ts.map +1 -1
  28. package/dist/src/Evolu/Sync.js +68 -40
  29. package/dist/src/Evolu/Timestamp.d.ts +10 -14
  30. package/dist/src/Evolu/Timestamp.d.ts.map +1 -1
  31. package/dist/src/Evolu/Timestamp.js +3 -16
  32. package/dist/src/Object.d.ts +10 -4
  33. package/dist/src/Object.d.ts.map +1 -1
  34. package/dist/src/Object.js +9 -3
  35. package/dist/src/Sqlite.d.ts +29 -3
  36. package/dist/src/Sqlite.d.ts.map +1 -1
  37. package/dist/src/Sqlite.js +29 -3
  38. package/dist/src/Type.d.ts +94 -47
  39. package/dist/src/Type.d.ts.map +1 -1
  40. package/dist/src/Type.js +110 -65
  41. package/package.json +2 -2
  42. package/src/Array.ts +3 -3
  43. package/src/Crypto.ts +11 -9
  44. package/src/Evolu/Db.ts +7 -7
  45. package/src/Evolu/Evolu.ts +31 -24
  46. package/src/Evolu/Protocol.ts +84 -37
  47. package/src/Evolu/PublicKysely.ts +1 -2
  48. package/src/Evolu/Query.ts +2 -2
  49. package/src/Evolu/Schema.ts +54 -50
  50. package/src/Evolu/Storage.ts +39 -2
  51. package/src/Evolu/Sync.ts +97 -43
  52. package/src/Evolu/Timestamp.ts +5 -25
  53. package/src/Object.ts +13 -5
  54. package/src/Sqlite.ts +33 -3
  55. package/src/Type.ts +124 -80
@@ -6,13 +6,13 @@ import { constFalse, constTrue } from "../Function.js";
6
6
  import { objectToEntries } from "../Object.js";
7
7
  import { createResources } from "../Resources.js";
8
8
  import { err, ok } from "../Result.js";
9
- import { sql } from "../Sqlite.js";
9
+ import { booleanToSqliteBoolean, sql, SqliteBoolean, sqliteBooleanToBoolean, sqliteFalse, } from "../Sqlite.js";
10
10
  import { createMutex } from "../Task.js";
11
- import { idBytesToId, idToIdBytes } from "../Type.js";
11
+ import { 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
- import { createBaseSqliteStorage, getOwnerUsage, getTimestampInsertStrategy, updateOwnerUsage, } from "./Storage.js";
15
- import { createInitialTimestamp, receiveTimestamp, sendTimestamp, timestampBytesToTimestamp, timestampToTimestampBytes, timestampToTimestampString, } from "./Timestamp.js";
14
+ import { createBaseSqliteStorage, DbChange, getOwnerUsage, getTimestampInsertStrategy, updateOwnerUsage, } from "./Storage.js";
15
+ import { createInitialTimestamp, receiveTimestamp, sendTimestamp, timestampBytesToTimestamp, timestampToDateIso, timestampToTimestampBytes, } from "./Timestamp.js";
16
16
  export const createSync = (deps) => (config) => {
17
17
  let isDisposed = false;
18
18
  /** Returns owner data only if actively assigned to at least one transport. */
@@ -160,7 +160,10 @@ export const createSync = (deps) => (config) => {
160
160
  return nextTimestamp;
161
161
  clockTimestamp = nextTimestamp.value;
162
162
  const { ownerId = config.appOwner.id, ...dbChange } = change;
163
- const message = { timestamp: clockTimestamp, change: dbChange };
163
+ const message = {
164
+ timestamp: clockTimestamp,
165
+ change: dbChange,
166
+ };
164
167
  const messages = ownerMessages.get(ownerId);
165
168
  if (messages)
166
169
  messages.push(message);
@@ -209,9 +212,9 @@ export const createClock = (deps) => (initialTimestamp = createInitialTimestamp(
209
212
  get: () => currentTimestamp,
210
213
  save: (timestamp) => {
211
214
  currentTimestamp = timestamp;
212
- const timestampString = timestampToTimestampString(timestamp);
213
215
  const result = deps.sqlite.exec(sql.prepared `
214
- update evolu_config set "clock" = ${timestampString};
216
+ update evolu_config
217
+ set "clock" = ${timestampToTimestampBytes(timestamp)};
215
218
  `);
216
219
  if (!result.ok)
217
220
  return result;
@@ -306,18 +309,32 @@ const createClientStorage = (deps) => (config) => {
306
309
  assert(rows.length > 0, "Rows must not be empty");
307
310
  const { table, id } = rows[0];
308
311
  const values = {};
312
+ let isInsert = false;
313
+ let isDelete = null;
309
314
  for (const r of rows) {
310
315
  assert(r.table === table, "All rows must have the same table");
311
316
  assert(eqArrayNumber(r.id, id), "All rows must have the same Id");
312
- values[r.column] = r.value;
317
+ switch (r.column) {
318
+ case "createdAt":
319
+ isInsert = true;
320
+ break;
321
+ case "isDeleted":
322
+ assert(SqliteBoolean.is(r.value), "isDeleted column must contain a valid SqliteBoolean (0 or 1)");
323
+ isDelete = sqliteBooleanToBoolean(r.value);
324
+ break;
325
+ default:
326
+ values[r.column] = r.value;
327
+ }
313
328
  }
314
329
  const message = {
315
330
  timestamp: timestampBytesToTimestamp(timestamp),
316
- change: {
331
+ change: DbChange.orThrow({
317
332
  table: rows[0].table,
318
333
  id: idBytesToId(rows[0].id),
319
334
  values,
320
- },
335
+ isInsert,
336
+ isDelete,
337
+ }),
321
338
  };
322
339
  return encodeAndEncryptDbChange(deps)(message, owner.encryptionKey);
323
340
  },
@@ -329,31 +346,30 @@ const createTransportKey = (transportConfig) => {
329
346
  return `${transportConfig.type}:${transportConfig.url}`;
330
347
  };
331
348
  export const applyLocalOnlyChange = (deps) => (change) => {
332
- const dbChange = {
333
- table: change.table,
334
- id: change.id,
335
- values: change.values,
336
- };
337
- const isDeletion = "isDeleted" in dbChange.values && dbChange.values.isDeleted === 1;
338
- if (isDeletion) {
349
+ if (change.isDelete) {
339
350
  const result = deps.sqlite.exec(sql `
340
- delete from ${sql.identifier(dbChange.table)}
341
- where id = ${dbChange.id};
351
+ delete from ${sql.identifier(change.table)}
352
+ where id = ${change.id};
342
353
  `);
343
354
  if (!result.ok)
344
355
  return result;
345
356
  }
346
357
  else {
347
- const date = new Date(deps.time.now()).toISOString();
348
- for (const [column, value] of objectToEntries(dbChange.values)) {
358
+ const now = deps.time.nowIso();
359
+ 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) {
349
365
  const result = deps.sqlite.exec(sql.prepared `
350
- insert into ${sql.identifier(dbChange.table)}
351
- ("id", ${sql.identifier(column)}, createdAt, updatedAt)
352
- values (${dbChange.id}, ${value}, ${date}, ${date})
353
- on conflict ("id") do update
366
+ insert into ${sql.identifier(change.table)}
367
+ ("ownerId", "id", ${sql.identifier(column)}, createdAt, updatedAt)
368
+ values (${ownerId}, ${change.id}, ${value}, ${now}, ${now})
369
+ on conflict ("ownerId", "id") do update
354
370
  set
355
371
  ${sql.identifier(column)} = ${value},
356
- updatedAt = ${date};
372
+ updatedAt = ${now};
357
373
  `);
358
374
  if (!result.ok)
359
375
  return result;
@@ -368,13 +384,14 @@ const applyMessages = (deps) => (ownerId, messages) => {
368
384
  return usageResult;
369
385
  let { firstTimestamp, lastTimestamp } = usageResult.value;
370
386
  for (const message of messages) {
371
- const result1 = applyMessageToAppTable(deps)(ownerIdBytes, message);
387
+ const date = timestampToDateIso(message.timestamp);
388
+ const result1 = applyMessageToAppTable(deps)(ownerIdBytes, message, date);
372
389
  if (!result1.ok)
373
390
  return result1;
374
391
  const timestamp = timestampToTimestampBytes(message.timestamp);
375
392
  let strategy;
376
393
  [strategy, firstTimestamp, lastTimestamp] = getTimestampInsertStrategy(timestamp, firstTimestamp, lastTimestamp);
377
- const result2 = applyMessageToTimestampAndHistoryTables(deps)(ownerIdBytes, message, strategy);
394
+ const result2 = applyMessageToTimestampAndHistoryTables(deps)(ownerIdBytes, message, strategy, date);
378
395
  if (!result2.ok)
379
396
  return result2;
380
397
  }
@@ -389,31 +406,31 @@ const applyMessages = (deps) => (ownerId, messages) => {
389
406
  return updateUsage;
390
407
  return ok();
391
408
  };
392
- const applyMessageToAppTable = (deps) => (ownerId, message) => {
393
- const timestamp = timestampToTimestampBytes(message.timestamp);
394
- const updatedAt = new Date(message.timestamp.millis).toISOString();
395
- for (const [column, value] of objectToEntries(message.change.values)) {
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) {
396
413
  const result = deps.sqlite.exec(sql.prepared `
397
414
  with
398
415
  existingTimestamp as (
399
416
  select 1
400
417
  from evolu_history
401
418
  where
402
- "ownerId" = ${ownerId}
419
+ "ownerId" = ${ownerIdBytes}
403
420
  and "table" = ${message.change.table}
404
421
  and "id" = ${idToIdBytes(message.change.id)}
405
422
  and "column" = ${column}
406
- and "timestamp" >= ${timestamp}
423
+ and "timestamp" >= ${timestampToTimestampBytes(message.timestamp)}
407
424
  limit 1
408
425
  )
409
426
  insert into ${sql.identifier(message.change.table)}
410
- ("id", ${sql.identifier(column)}, updatedAt)
411
- select ${message.change.id}, ${value}, ${updatedAt}
427
+ ("ownerId", "id", ${sql.identifier(column)}, updatedAt)
428
+ select ${ownerId}, ${message.change.id}, ${value}, ${date}
412
429
  where not exists (select 1 from existingTimestamp)
413
- on conflict ("id") do update
430
+ on conflict ("ownerId", "id") do update
414
431
  set
415
432
  ${sql.identifier(column)} = ${value},
416
- updatedAt = ${updatedAt}
433
+ updatedAt = ${date}
417
434
  where not exists (select 1 from existingTimestamp);
418
435
  `);
419
436
  if (!result.ok)
@@ -421,13 +438,14 @@ const applyMessageToAppTable = (deps) => (ownerId, message) => {
421
438
  }
422
439
  return ok();
423
440
  };
424
- export const applyMessageToTimestampAndHistoryTables = (deps) => (ownerId, message, strategy) => {
441
+ export const applyMessageToTimestampAndHistoryTables = (deps) => (ownerId, message, strategy, date) => {
425
442
  const timestamp = timestampToTimestampBytes(message.timestamp);
426
443
  const id = idToIdBytes(message.change.id);
427
444
  const result = deps.storage.insertTimestamp(ownerId, timestamp, strategy);
428
445
  if (!result.ok)
429
446
  return result;
430
- for (const [column, value] of Object.entries(message.change.values)) {
447
+ const columns = dbChangeToColumns(message.change, date);
448
+ for (const [column, value] of columns) {
431
449
  const result = deps.sqlite.exec(sql.prepared `
432
450
  insert into evolu_history
433
451
  ("ownerId", "table", "id", "column", "value", "timestamp")
@@ -447,4 +465,14 @@ export const applyMessageToTimestampAndHistoryTables = (deps) => (ownerId, messa
447
465
  }
448
466
  return ok();
449
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
+ };
450
478
  export const initialSyncState = { type: "SyncStateInitial" };
@@ -1,9 +1,8 @@
1
- import { Brand } from "../Brand.js";
2
1
  import { RandomBytesDep } from "../Crypto.js";
3
2
  import { Order } from "../Order.js";
4
3
  import { Result } from "../Result.js";
5
4
  import { TimeDep } from "../Time.js";
6
- import { InferType } from "../Type.js";
5
+ import { DateIso, InferType } from "../Type.js";
7
6
  export interface TimestampConfig {
8
7
  /**
9
8
  * Maximum physical clock drift allowed in ms.
@@ -39,11 +38,11 @@ export interface TimestampTimeOutOfRangeError {
39
38
  *
40
39
  * `new Date(281474976710654).toString()` = Tue Aug 02 10889 07:31:49
41
40
  */
42
- export declare const Millis: import("../Type.js").BrandType<import("../Type.js").BrandType<import("../Type.js").Type<"Brand", number & Brand<"Int"> & Brand<"NonNegative">, number, import("../Type.js").NonNegativeError, number & Brand<"Int">, import("../Type.js").IntError | import("../Type.js").NumberError>, `LessThanOrEqualTo${number}`, import("../Type.js").LessThanOrEqualToError<number>, import("../Type.js").NonNegativeError | import("../Type.js").IntError | import("../Type.js").NumberError>, "Millis", import("../Type.js").BrandWithoutRefineError<"Millis", import("../Type.js").NonNegativeError | import("../Type.js").IntError | import("../Type.js").NumberError | import("../Type.js").LessThanOrEqualToError<number>>, never>;
41
+ export declare const Millis: import("../Type.js").BrandType<import("../Type.js").BrandType<import("../Type.js").Type<"Brand", number & import("../Brand.js").Brand<"Int"> & import("../Brand.js").Brand<"NonNegative">, number, import("../Type.js").NonNegativeError, number & import("../Brand.js").Brand<"Int">, import("../Type.js").IntError | import("../Type.js").NumberError>, `LessThanOrEqualTo${number}`, import("../Type.js").LessThanOrEqualToError<number>, import("../Type.js").NonNegativeError | import("../Type.js").IntError | import("../Type.js").NumberError>, "Millis", import("../Type.js").BrandWithoutRefineError<"Millis", import("../Type.js").NonNegativeError | import("../Type.js").IntError | import("../Type.js").NumberError | import("../Type.js").LessThanOrEqualToError<number>>, never>;
43
42
  export type Millis = typeof Millis.Type;
44
43
  export declare const minMillis: Millis;
45
44
  export declare const maxMillis: Millis;
46
- export declare const Counter: import("../Type.js").BrandType<import("../Type.js").BrandType<import("../Type.js").Type<"Brand", number & Brand<"Int"> & Brand<"NonNegative">, number, import("../Type.js").NonNegativeError, number & Brand<"Int">, import("../Type.js").IntError | import("../Type.js").NumberError>, "LessThanOrEqualTo65535", import("../Type.js").LessThanOrEqualToError<65535>, import("../Type.js").NonNegativeError | import("../Type.js").IntError | import("../Type.js").NumberError>, "Counter", import("../Type.js").BrandWithoutRefineError<"Counter", import("../Type.js").NonNegativeError | import("../Type.js").IntError | import("../Type.js").NumberError | import("../Type.js").LessThanOrEqualToError<65535>>, never>;
45
+ export declare const Counter: import("../Type.js").BrandType<import("../Type.js").BrandType<import("../Type.js").Type<"Brand", number & import("../Brand.js").Brand<"Int"> & import("../Brand.js").Brand<"NonNegative">, number, import("../Type.js").NonNegativeError, number & import("../Brand.js").Brand<"Int">, import("../Type.js").IntError | import("../Type.js").NumberError>, "LessThanOrEqualTo65535", import("../Type.js").LessThanOrEqualToError<65535>, import("../Type.js").NonNegativeError | import("../Type.js").IntError | import("../Type.js").NumberError>, "Counter", import("../Type.js").BrandWithoutRefineError<"Counter", import("../Type.js").NonNegativeError | import("../Type.js").IntError | import("../Type.js").NumberError | import("../Type.js").LessThanOrEqualToError<65535>>, never>;
47
46
  export type Counter = typeof Counter.Type;
48
47
  export declare const minCounter: Counter;
49
48
  export declare const maxCounter: Counter;
@@ -133,31 +132,28 @@ export declare const maxNodeId: NodeId;
133
132
  * **Trade-off:** It breaks real-time collaboration.
134
133
  */
135
134
  export declare const Timestamp: import("../Type.js").ObjectType<{
136
- millis: import("../Type.js").BrandType<import("../Type.js").BrandType<import("../Type.js").Type<"Brand", number & Brand<"Int"> & Brand<"NonNegative">, number, import("../Type.js").NonNegativeError, number & Brand<"Int">, import("../Type.js").IntError | import("../Type.js").NumberError>, `LessThanOrEqualTo${number}`, import("../Type.js").LessThanOrEqualToError<number>, import("../Type.js").NonNegativeError | import("../Type.js").IntError | import("../Type.js").NumberError>, "Millis", import("../Type.js").BrandWithoutRefineError<"Millis", import("../Type.js").NonNegativeError | import("../Type.js").IntError | import("../Type.js").NumberError | import("../Type.js").LessThanOrEqualToError<number>>, never>;
137
- counter: import("../Type.js").BrandType<import("../Type.js").BrandType<import("../Type.js").Type<"Brand", number & Brand<"Int"> & Brand<"NonNegative">, number, import("../Type.js").NonNegativeError, number & Brand<"Int">, import("../Type.js").IntError | import("../Type.js").NumberError>, "LessThanOrEqualTo65535", import("../Type.js").LessThanOrEqualToError<65535>, import("../Type.js").NonNegativeError | import("../Type.js").IntError | import("../Type.js").NumberError>, "Counter", import("../Type.js").BrandWithoutRefineError<"Counter", import("../Type.js").NonNegativeError | import("../Type.js").IntError | import("../Type.js").NumberError | import("../Type.js").LessThanOrEqualToError<65535>>, never>;
135
+ millis: import("../Type.js").BrandType<import("../Type.js").BrandType<import("../Type.js").Type<"Brand", number & import("../Brand.js").Brand<"Int"> & import("../Brand.js").Brand<"NonNegative">, number, import("../Type.js").NonNegativeError, number & import("../Brand.js").Brand<"Int">, import("../Type.js").IntError | import("../Type.js").NumberError>, `LessThanOrEqualTo${number}`, import("../Type.js").LessThanOrEqualToError<number>, import("../Type.js").NonNegativeError | import("../Type.js").IntError | import("../Type.js").NumberError>, "Millis", import("../Type.js").BrandWithoutRefineError<"Millis", import("../Type.js").NonNegativeError | import("../Type.js").IntError | import("../Type.js").NumberError | import("../Type.js").LessThanOrEqualToError<number>>, never>;
136
+ counter: import("../Type.js").BrandType<import("../Type.js").BrandType<import("../Type.js").Type<"Brand", number & import("../Brand.js").Brand<"Int"> & import("../Brand.js").Brand<"NonNegative">, number, import("../Type.js").NonNegativeError, number & import("../Brand.js").Brand<"Int">, import("../Type.js").IntError | import("../Type.js").NumberError>, "LessThanOrEqualTo65535", import("../Type.js").LessThanOrEqualToError<65535>, import("../Type.js").NonNegativeError | import("../Type.js").IntError | import("../Type.js").NumberError>, "Counter", import("../Type.js").BrandWithoutRefineError<"Counter", import("../Type.js").NonNegativeError | import("../Type.js").IntError | import("../Type.js").NumberError | import("../Type.js").LessThanOrEqualToError<65535>>, never>;
138
137
  nodeId: import("../Type.js").BrandType<import("../Type.js").Type<"String", string, string, import("../Type.js").StringError, string, import("../Type.js").StringError>, "NodeId", import("../Type.js").RegexError<"NodeId">, import("../Type.js").StringError>;
139
138
  }>;
140
139
  export interface Timestamp extends InferType<typeof Timestamp> {
141
140
  }
142
141
  /** Equality function for comparing {@link Timestamp}. */
143
142
  export declare const eqTimestamp: import("../Eq.js").Eq<{
144
- readonly millis: number & Brand<"Int"> & Brand<"NonNegative"> & Brand<`LessThanOrEqualTo${number}`> & Brand<"Millis">;
145
- readonly counter: number & Brand<"Int"> & Brand<"NonNegative"> & Brand<"LessThanOrEqualTo65535"> & Brand<"Counter">;
146
- readonly nodeId: string & Brand<"NodeId">;
143
+ readonly millis: number & import("../Brand.js").Brand<"Int"> & import("../Brand.js").Brand<"NonNegative"> & import("../Brand.js").Brand<`LessThanOrEqualTo${number}`> & import("../Brand.js").Brand<"Millis">;
144
+ readonly counter: number & import("../Brand.js").Brand<"Int"> & import("../Brand.js").Brand<"NonNegative"> & import("../Brand.js").Brand<"LessThanOrEqualTo65535"> & import("../Brand.js").Brand<"Counter">;
145
+ readonly nodeId: string & import("../Brand.js").Brand<"NodeId">;
147
146
  }>;
148
147
  export declare const createTimestamp: ({ millis, counter, nodeId, }?: Partial<Timestamp>) => Timestamp;
149
148
  export declare const createInitialTimestamp: (deps: RandomBytesDep) => Timestamp;
150
- /** Sortable string representation of {@link Timestamp}. */
151
- export type TimestampString = string & Brand<"TimestampString">;
152
- export declare const timestampToTimestampString: (t: Timestamp) => TimestampString;
153
- export declare const timestampStringToTimestamp: (timestampString: TimestampString) => Timestamp;
154
149
  export declare const sendTimestamp: (deps: TimeDep & TimestampConfigDep) => (timestamp: Timestamp) => Result<Timestamp, TimestampDriftError | TimestampCounterOverflowError | TimestampTimeOutOfRangeError>;
155
150
  export declare const receiveTimestamp: (deps: TimeDep & TimestampConfigDep) => (local: Timestamp, remote: Timestamp) => Result<Timestamp, TimestampDriftError | TimestampCounterOverflowError | TimestampTimeOutOfRangeError>;
156
151
  /** Sortable bytes representation of {@link Timestamp}. */
157
152
  export declare const TimestampBytes: import("../Type.js").BrandType<import("../Type.js").Type<"Uint8Array", Uint8Array<ArrayBufferLike>, Uint8Array<ArrayBufferLike>, import("../Type.js").Uint8ArrayError, Uint8Array<ArrayBufferLike>, import("../Type.js").Uint8ArrayError>, "TimestampBytes", import("../Type.js").BrandWithoutRefineError<"TimestampBytes", import("../Type.js").Uint8ArrayError>, never>;
158
153
  export type TimestampBytes = typeof TimestampBytes.Type;
159
- export declare const timestampBytesLength: number & Brand<"Int"> & Brand<"NonNegative">;
154
+ export declare const timestampBytesLength: number & import("../Brand.js").Brand<"Int"> & import("../Brand.js").Brand<"NonNegative">;
160
155
  export declare const timestampToTimestampBytes: (timestamp: Timestamp) => TimestampBytes;
161
156
  export declare const timestampBytesToTimestamp: (timestamp: TimestampBytes) => Timestamp;
162
157
  export declare const orderTimestampBytes: Order<TimestampBytes>;
158
+ export declare const timestampToDateIso: (timestamp: Timestamp) => DateIso;
163
159
  //# sourceMappingURL=Timestamp.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Timestamp.d.ts","sourceRoot":"","sources":["../../../src/Evolu/Timestamp.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Timestamp.d.ts","sourceRoot":"","sources":["../../../src/Evolu/Timestamp.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,3 @@
1
- import { assert } from "../Assert.js";
2
1
  import { bytesToHex } from "../Buffer.js";
3
2
  import { createEqObject, eqNumber, eqString } from "../Eq.js";
4
3
  import { increment } from "../Number.js";
@@ -123,21 +122,6 @@ export const createInitialTimestamp = (deps) => {
123
122
  const nodeId = bytesToHex(deps.randomBytes.create(8));
124
123
  return createTimestamp({ nodeId });
125
124
  };
126
- export const timestampToTimestampString = (t) => [
127
- new Date(t.millis).toISOString(),
128
- t.counter.toString(16).toUpperCase().padStart(4, "0"),
129
- t.nodeId,
130
- ].join("-");
131
- export const timestampStringToTimestamp = (timestampString) => {
132
- const array = timestampString.split("-");
133
- const timestamp = {
134
- millis: Date.parse(array.slice(0, 3).join("-")).valueOf(),
135
- counter: parseInt(array[3], 16),
136
- nodeId: array[4],
137
- };
138
- assert(Timestamp.is(timestamp), "timestampString is malformed");
139
- return timestamp;
140
- };
141
125
  const getNextMillis = (deps) => (millis) => {
142
126
  const now = Millis.from(deps.time.now());
143
127
  if (!now.ok) {
@@ -235,3 +219,6 @@ export const timestampBytesToTimestamp = (timestamp) => {
235
219
  return { millis: Number(millis), counter, nodeId };
236
220
  };
237
221
  export const orderTimestampBytes = orderUint8Array;
222
+ export const timestampToDateIso = (timestamp) =>
223
+ // `as DateIso` is safe because the timestamp is always valid
224
+ new Date(timestamp.millis).toISOString();
@@ -18,11 +18,17 @@ export declare const isPlainObject: (value: unknown) => value is Record<string,
18
18
  export type ReadonlyRecord<K extends keyof any, V> = Readonly<Record<K, V>>;
19
19
  type StringKeyOf<T> = Extract<keyof T, string>;
20
20
  /**
21
- * Converts a record to entries, preserving branded string key types (e.g.,
22
- * `type Id = 'id' & string`) via `StringKeyOf<T>`, unlike `Object.entries`
23
- * which widens keys to `string`.
21
+ * Like `Object.entries` but preserves branded keys.
22
+ *
23
+ * ### Example
24
+ *
25
+ * ```ts
26
+ * type UserId = string & { readonly __brand: "UserId" };
27
+ * const users: Record<UserId, string> = {};
28
+ * const entries = objectToEntries(users); // [UserId, string][]
29
+ * ```
24
30
  */
25
- export declare const objectToEntries: <T extends Record<string, any>>(record: T) => Array<[StringKeyOf<T>, T[StringKeyOf<T>]]>;
31
+ export declare const objectToEntries: <T extends Record<string, any>>(record: T) => ReadonlyArray<[StringKeyOf<T>, T[StringKeyOf<T>]]>;
26
32
  /**
27
33
  * Maps a `ReadonlyRecord<K, V>` to a new `ReadonlyRecord<K, U>`, preserving
28
34
  * branded key types (e.g., `type Id = 'id' & string`) lost by `Object.entries`.
@@ -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;;;;GAIG;AACH,eAAO,MAAM,eAAe,GAAI,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC3D,QAAQ,CAAC,KACR,KAAK,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAC0B,CAAC;AAEvE;;;;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"}
@@ -12,9 +12,15 @@
12
12
  */
13
13
  export const isPlainObject = (value) => Object.prototype.toString.call(value) === "[object Object]";
14
14
  /**
15
- * Converts a record to entries, preserving branded string key types (e.g.,
16
- * `type Id = 'id' & string`) via `StringKeyOf<T>`, unlike `Object.entries`
17
- * which widens keys to `string`.
15
+ * Like `Object.entries` but preserves branded keys.
16
+ *
17
+ * ### Example
18
+ *
19
+ * ```ts
20
+ * type UserId = string & { readonly __brand: "UserId" };
21
+ * const users: Record<UserId, string> = {};
22
+ * const entries = objectToEntries(users); // [UserId, string][]
23
+ * ```
18
24
  */
19
25
  export const objectToEntries = (record) => Object.entries(record);
20
26
  /**
@@ -170,10 +170,14 @@ export declare const explainSqliteQueryPlan: (deps: SqliteDep) => (query: Sqlite
170
170
  * SQLite represents boolean values using `0` (false) and `1` (true) instead of
171
171
  * a dedicated boolean type.
172
172
  *
173
- * Use {@link sqliteTrue} and {@link sqliteFalse} constants for better
174
- * readability.
175
- *
176
173
  * See: https://www.sqlite.org/quirks.html#no_separate_boolean_datatype
174
+ *
175
+ * ### Tips
176
+ *
177
+ * - Use {@link sqliteTrue} and {@link sqliteFalse} constants for better
178
+ * readability.
179
+ * - Use {@link booleanToSqliteBoolean} and {@link sqliteBooleanToBoolean} for
180
+ * converting between JavaScript booleans and SQLite boolean values.
177
181
  */
178
182
  export declare const SqliteBoolean: import("./Type.js").UnionType<[import("./Type.js").LiteralType<0>, import("./Type.js").LiteralType<1>]>;
179
183
  export type SqliteBoolean = typeof SqliteBoolean.Type;
@@ -189,4 +193,26 @@ export declare const sqliteTrue = 1;
189
193
  * See {@link SqliteBoolean}.
190
194
  */
191
195
  export declare const sqliteFalse = 0;
196
+ /**
197
+ * Converts a JavaScript boolean to a {@link SqliteBoolean}.
198
+ *
199
+ * ### Example
200
+ *
201
+ * ```ts
202
+ * const isActive = true;
203
+ * const sqlValue = booleanToSqliteBoolean(isActive); // Returns 1
204
+ * ```
205
+ */
206
+ export declare const booleanToSqliteBoolean: (value: boolean) => SqliteBoolean;
207
+ /**
208
+ * Converts a {@link SqliteBoolean} to a JavaScript boolean.
209
+ *
210
+ * ### Example
211
+ *
212
+ * ```ts
213
+ * const sqlValue: SqliteBoolean = 1;
214
+ * const bool = sqliteBooleanToBoolean(sqlValue); // Returns true
215
+ * ```
216
+ */
217
+ export declare const sqliteBooleanToBoolean: (value: SqliteBoolean) => boolean;
192
218
  //# sourceMappingURL=Sqlite.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Sqlite.d.ts","sourceRoot":"","sources":["../../src/Sqlite.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Sqlite.d.ts","sourceRoot":"","sources":["../../src/Sqlite.ts"],"names":[],"mappings":"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"}
@@ -292,10 +292,14 @@ const drawSqliteQueryPlan = (rows) => rows
292
292
  * SQLite represents boolean values using `0` (false) and `1` (true) instead of
293
293
  * a dedicated boolean type.
294
294
  *
295
- * Use {@link sqliteTrue} and {@link sqliteFalse} constants for better
296
- * readability.
297
- *
298
295
  * See: https://www.sqlite.org/quirks.html#no_separate_boolean_datatype
296
+ *
297
+ * ### Tips
298
+ *
299
+ * - Use {@link sqliteTrue} and {@link sqliteFalse} constants for better
300
+ * readability.
301
+ * - Use {@link booleanToSqliteBoolean} and {@link sqliteBooleanToBoolean} for
302
+ * converting between JavaScript booleans and SQLite boolean values.
299
303
  */
300
304
  export const SqliteBoolean = union(0, 1);
301
305
  /**
@@ -310,3 +314,25 @@ export const sqliteTrue = 1;
310
314
  * See {@link SqliteBoolean}.
311
315
  */
312
316
  export const sqliteFalse = 0;
317
+ /**
318
+ * Converts a JavaScript boolean to a {@link SqliteBoolean}.
319
+ *
320
+ * ### Example
321
+ *
322
+ * ```ts
323
+ * const isActive = true;
324
+ * const sqlValue = booleanToSqliteBoolean(isActive); // Returns 1
325
+ * ```
326
+ */
327
+ export const booleanToSqliteBoolean = (value) => value ? sqliteTrue : sqliteFalse;
328
+ /**
329
+ * Converts a {@link SqliteBoolean} to a JavaScript boolean.
330
+ *
331
+ * ### Example
332
+ *
333
+ * ```ts
334
+ * const sqlValue: SqliteBoolean = 1;
335
+ * const bool = sqliteBooleanToBoolean(sqlValue); // Returns true
336
+ * ```
337
+ */
338
+ export const sqliteBooleanToBoolean = (value) => value === sqliteTrue;