tinybase 6.2.0-beta.3 → 6.2.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 (76) hide show
  1. package/@types/common/index.d.ts +295 -0
  2. package/@types/common/with-schemas/index.d.ts +375 -0
  3. package/@types/mergeable-store/index.d.ts +5 -34
  4. package/@types/mergeable-store/with-schemas/index.d.ts +5 -34
  5. package/@types/omni/with-schemas/index.d.ts +3 -3
  6. package/common/index.js +62 -3
  7. package/common/with-schemas/index.js +62 -3
  8. package/index.js +133 -86
  9. package/mergeable-store/index.js +102 -94
  10. package/mergeable-store/with-schemas/index.js +102 -94
  11. package/min/common/index.js +1 -1
  12. package/min/common/index.js.gz +0 -0
  13. package/min/common/with-schemas/index.js +1 -1
  14. package/min/common/with-schemas/index.js.gz +0 -0
  15. package/min/index.js +1 -1
  16. package/min/index.js.gz +0 -0
  17. package/min/mergeable-store/index.js +1 -1
  18. package/min/mergeable-store/index.js.gz +0 -0
  19. package/min/mergeable-store/with-schemas/index.js +1 -1
  20. package/min/mergeable-store/with-schemas/index.js.gz +0 -0
  21. package/min/omni/index.js +1 -1
  22. package/min/omni/index.js.gz +0 -0
  23. package/min/omni/with-schemas/index.js +1 -1
  24. package/min/omni/with-schemas/index.js.gz +0 -0
  25. package/min/persisters/index.js +1 -1
  26. package/min/persisters/index.js.gz +0 -0
  27. package/min/persisters/persister-pglite/index.js +1 -1
  28. package/min/persisters/persister-pglite/index.js.gz +0 -0
  29. package/min/persisters/persister-pglite/with-schemas/index.js +1 -1
  30. package/min/persisters/persister-pglite/with-schemas/index.js.gz +0 -0
  31. package/min/persisters/persister-postgres/index.js +1 -1
  32. package/min/persisters/persister-postgres/index.js.gz +0 -0
  33. package/min/persisters/persister-postgres/with-schemas/index.js +1 -1
  34. package/min/persisters/persister-postgres/with-schemas/index.js.gz +0 -0
  35. package/min/persisters/with-schemas/index.js +1 -1
  36. package/min/persisters/with-schemas/index.js.gz +0 -0
  37. package/min/store/index.js +1 -1
  38. package/min/store/index.js.gz +0 -0
  39. package/min/store/with-schemas/index.js +1 -1
  40. package/min/store/with-schemas/index.js.gz +0 -0
  41. package/min/ui-react-inspector/index.js +1 -1
  42. package/min/ui-react-inspector/index.js.gz +0 -0
  43. package/min/ui-react-inspector/with-schemas/index.js +1 -1
  44. package/min/ui-react-inspector/with-schemas/index.js.gz +0 -0
  45. package/min/with-schemas/index.js +1 -1
  46. package/min/with-schemas/index.js.gz +0 -0
  47. package/omni/index.js +148 -101
  48. package/omni/with-schemas/index.js +148 -101
  49. package/package.json +3 -3
  50. package/persisters/index.js +9 -9
  51. package/persisters/persister-durable-object-storage/index.js +12 -12
  52. package/persisters/persister-durable-object-storage/with-schemas/index.js +12 -12
  53. package/persisters/persister-pglite/index.js +11 -11
  54. package/persisters/persister-pglite/with-schemas/index.js +11 -11
  55. package/persisters/persister-postgres/index.js +11 -11
  56. package/persisters/persister-postgres/with-schemas/index.js +11 -11
  57. package/persisters/with-schemas/index.js +9 -9
  58. package/readme.md +2 -2
  59. package/releases.md +9 -10
  60. package/store/index.js +4 -4
  61. package/store/with-schemas/index.js +4 -4
  62. package/synchronizers/index.js +7 -7
  63. package/synchronizers/synchronizer-broadcast-channel/index.js +7 -7
  64. package/synchronizers/synchronizer-broadcast-channel/with-schemas/index.js +7 -7
  65. package/synchronizers/synchronizer-local/index.js +7 -7
  66. package/synchronizers/synchronizer-local/with-schemas/index.js +7 -7
  67. package/synchronizers/synchronizer-ws-client/index.js +7 -7
  68. package/synchronizers/synchronizer-ws-client/with-schemas/index.js +7 -7
  69. package/synchronizers/synchronizer-ws-server/index.js +7 -7
  70. package/synchronizers/synchronizer-ws-server/with-schemas/index.js +7 -7
  71. package/synchronizers/synchronizer-ws-server-durable-object/index.js +7 -7
  72. package/synchronizers/synchronizer-ws-server-durable-object/with-schemas/index.js +7 -7
  73. package/synchronizers/with-schemas/index.js +7 -7
  74. package/ui-react-inspector/index.js +1 -1
  75. package/ui-react-inspector/with-schemas/index.js +1 -1
  76. package/with-schemas/index.js +133 -86
@@ -19,7 +19,7 @@
19
19
  * @module mergeable-store
20
20
  * @since v5.0.0
21
21
  */
22
- import type {GetNow, Id} from '../common/index.d.ts';
22
+ import type {GetNow, Hash, Hlc, Id} from '../common/index.d.ts';
23
23
  import type {
24
24
  CellOrUndefined,
25
25
  Content,
@@ -27,41 +27,12 @@ import type {
27
27
  ValueOrUndefined,
28
28
  } from '../store/index.d.ts';
29
29
 
30
- /**
31
- * The Hash type is used within the mergeable-store module to quickly compare
32
- * the content of two objects.
33
- *
34
- * This is simply an alias for a JavaScript `number`.
35
- *
36
- * This type is mostly utilized internally within TinyBase itself and is
37
- * generally assumed to be opaque to applications that use it.
38
- * @category Stamps
39
- * @since v5.0.0
40
- */
41
- export type Hash = number;
42
-
43
- /**
44
- * The Time type is used within the mergeable-store module to store the value of
45
- * a hybrid logical clock (HLC).
46
- *
47
- * It is simply an alias for a JavaScript `string`, but it comprises three HLC
48
- * parts: a logical timestamp, a sequence counter, and a client Id. It is
49
- * designed to be string-sortable and unique across all of the systems involved
50
- * in synchronizing a MergeableStore.
51
- *
52
- * This type is mostly utilized internally within TinyBase itself and is
53
- * generally assumed to be opaque to applications that use it.
54
- * @category Stamps
55
- * @since v5.0.0
56
- */
57
- export type Time = string;
58
-
59
30
  /**
60
31
  * The Stamp type is used as metadata to decide how to merge two different
61
32
  * MergeableStore objects together.
62
33
  *
63
- * It describes a combination of a value (or object), a Time, and optionally a
64
- * Hash, all in an array.
34
+ * It describes a combination of a value (or object), an Hlc timestamp, and
35
+ * optionally a Hash, all in an array.
65
36
  *
66
37
  * This type is mostly utilized internally within TinyBase itself and is
67
38
  * generally assumed to be opaque to applications that use it.
@@ -69,8 +40,8 @@ export type Time = string;
69
40
  * @since v5.0.0
70
41
  */
71
42
  export type Stamp<Thing, Hashed extends boolean = false> = Hashed extends true
72
- ? [thing: Thing, time: Time, hash: Hash]
73
- : [thing: Thing, time?: Time];
43
+ ? [thing: Thing, hlc: Hlc, hash: Hash]
44
+ : [thing: Thing, hlc?: Hlc];
74
45
 
75
46
  /**
76
47
  * The ContentHashes type is used to quickly compare the content of two
@@ -24,7 +24,7 @@ import type {
24
24
  TableIdFromSchema,
25
25
  ValueIdFromSchema,
26
26
  } from '../../_internal/store/with-schemas/index.d.ts';
27
- import type {GetNow, Id} from '../../common/with-schemas/index.d.ts';
27
+ import type {GetNow, Hash, Hlc, Id} from '../../common/with-schemas/index.d.ts';
28
28
  import type {
29
29
  CellOrUndefined,
30
30
  Content,
@@ -40,41 +40,12 @@ import type {
40
40
  ValuesSchema,
41
41
  } from '../../store/with-schemas/index.d.ts';
42
42
 
43
- /**
44
- * The Hash type is used within the mergeable-store module to quickly compare
45
- * the content of two objects.
46
- *
47
- * This is simply an alias for a JavaScript `number`.
48
- *
49
- * This type is mostly utilized internally within TinyBase itself and is
50
- * generally assumed to be opaque to applications that use it.
51
- * @category Stamps
52
- * @since v5.0.0
53
- */
54
- export type Hash = number;
55
-
56
- /**
57
- * The Time type is used within the mergeable-store module to store the value of
58
- * a hybrid logical clock (HLC).
59
- *
60
- * It is simply an alias for a JavaScript `string`, but it comprises three HLC
61
- * parts: a logical timestamp, a sequence counter, and a client Id. It is
62
- * designed to be string-sortable and unique across all of the systems involved
63
- * in synchronizing a MergeableStore.
64
- *
65
- * This type is mostly utilized internally within TinyBase itself and is
66
- * generally assumed to be opaque to applications that use it.
67
- * @category Stamps
68
- * @since v5.0.0
69
- */
70
- export type Time = string;
71
-
72
43
  /**
73
44
  * The Stamp type is used as metadata to decide how to merge two different
74
45
  * MergeableStore objects together.
75
46
  *
76
- * It describes a combination of a value (or object), a Time, and optionally a
77
- * Hash, all in an array.
47
+ * It describes a combination of a value (or object), an Hlc timestamp, and
48
+ * optionally a Hash, all in an array.
78
49
  *
79
50
  * This type is mostly utilized internally within TinyBase itself and is
80
51
  * generally assumed to be opaque to applications that use it.
@@ -82,8 +53,8 @@ export type Time = string;
82
53
  * @since v5.0.0
83
54
  */
84
55
  export type Stamp<Thing, Hashed extends boolean = false> = Hashed extends true
85
- ? [thing: Thing, time: Time, hash: Hash]
86
- : [thing: Thing, time?: Time];
56
+ ? [thing: Thing, hlc: Hlc, hash: Hash]
57
+ : [thing: Thing, hlc?: Hlc];
87
58
 
88
59
  /**
89
60
  * The ContentHashes type is used to quickly compare the content of two
@@ -49,6 +49,6 @@ export * from '../../synchronizers/synchronizer-ws-server-durable-object/with-sc
49
49
  export * from '../../synchronizers/synchronizer-ws-server-simple/with-schemas/index.d.ts';
50
50
  export * from '../../synchronizers/synchronizer-ws-server/with-schemas/index.d.ts';
51
51
  export * from '../../synchronizers/with-schemas/index.d.ts';
52
- export * from '../../ui-react-dom/with-schemas/index.d.ts';
53
- export * from '../../ui-react-inspector/with-schemas/index.d.ts';
54
- export * from '../../ui-react/with-schemas/index.d.ts';
52
+ export {WithSchemas as UiReactDomWithSchemas} from '../../ui-react-dom/with-schemas/index.d.ts';
53
+ export {WithSchemas as UiReactInspectorWithSchemas} from '../../ui-react-inspector/with-schemas/index.d.ts';
54
+ export {WithSchemas as UiReactWithSchemas} from '../../ui-react/with-schemas/index.d.ts';
package/common/index.js CHANGED
@@ -6,6 +6,7 @@ const GLOBAL = globalThis;
6
6
  const math = Math;
7
7
  const mathMax = math.max;
8
8
  const mathFloor = math.floor;
9
+ const isInstanceOf = (thing, cls) => thing instanceof cls;
9
10
  const isUndefined = (thing) => thing == void 0;
10
11
  const ifNotUndefined = (value, then, otherwise) =>
11
12
  isUndefined(value) ? otherwise?.() : then(value);
@@ -14,6 +15,9 @@ const arrayForEach = (array, cb) => array.forEach(cb);
14
15
  const arrayMap = (array, cb) => array.map(cb);
15
16
  const arrayReduce = (array, cb, initial) => array.reduce(cb, initial);
16
17
 
18
+ const object = Object;
19
+ const objEntries = object.entries;
20
+
17
21
  const mapNew = (entries) => new Map(entries);
18
22
  const mapGet = (map, key) => map?.get(key);
19
23
 
@@ -37,16 +41,55 @@ const getUniqueId = (length = 16) =>
37
41
  '',
38
42
  );
39
43
 
44
+ const jsonString = JSON.stringify;
45
+ const jsonStringWithMap = (obj) =>
46
+ jsonString(obj, (_key, value) =>
47
+ isInstanceOf(value, Map) ? object.fromEntries([...value]) : value,
48
+ );
49
+
40
50
  const textEncoder = /* @__PURE__ */ new GLOBAL.TextEncoder();
41
- const getHash = (value) => {
51
+ const getHash = (string) => {
42
52
  let hash = 2166136261;
43
- arrayForEach(textEncoder.encode(value), (char) => {
53
+ arrayForEach(textEncoder.encode(string), (char) => {
44
54
  hash ^= char;
45
55
  hash +=
46
56
  (hash << 1) + (hash << 4) + (hash << 7) + (hash << 8) + (hash << 24);
47
57
  });
48
58
  return hash >>> 0;
49
59
  };
60
+ const addOrRemoveHash = (hash1, hash2) => (hash1 ^ hash2) >>> 0;
61
+ const getValuesHash = (valueHashes) =>
62
+ arrayReduce(
63
+ objEntries(valueHashes),
64
+ (valuesHash, [valueId, valueHash]) =>
65
+ addOrRemoveHash(
66
+ valuesHash,
67
+ getValueInValuesHash(valueId, valueHash) ^
68
+ getValueInValuesHash(valueId, 0),
69
+ // legacy v5; remove in v7
70
+ ),
71
+ 0,
72
+ // legacy v5; valuesHlc in v7?
73
+ );
74
+ const getValueInValuesHash = (valueId, valueHash) =>
75
+ getHash(valueId + ':' + valueHash);
76
+ const getValueHash = (value, valueHlc) =>
77
+ getHash(jsonStringWithMap(value ?? null) + ':' + valueHlc);
78
+ const getCellHash = getValueHash;
79
+ const getCellInRowHash = getValueInValuesHash;
80
+ const getRowHash = getValuesHash;
81
+ const getRowInTableHash = getValueInValuesHash;
82
+ const getTableHash = (rowHashes) =>
83
+ // alias to getValuesHash in v7
84
+ arrayReduce(
85
+ objEntries(rowHashes),
86
+ (valuesHash, [rowId, rowHash]) =>
87
+ addOrRemoveHash(valuesHash, getValueInValuesHash(rowId, rowHash)),
88
+ 0,
89
+ // legacy v5; rowHlc in v7?
90
+ );
91
+ const getTableInTablesHash = getValueInValuesHash;
92
+ const getTablesHash = getTableHash;
50
93
 
51
94
  const SHIFT36 = 2 ** 36;
52
95
  const SHIFT30 = 2 ** 30;
@@ -132,4 +175,20 @@ const getHlcFunctions = (uniqueId, getNow = Date.now) => {
132
175
  const defaultSorter = (sortKey1, sortKey2) =>
133
176
  (sortKey1 ?? 0) < (sortKey2 ?? 0) ? -1 : 1;
134
177
 
135
- export {defaultSorter, getHlcFunctions, getRandomValues, getUniqueId};
178
+ export {
179
+ addOrRemoveHash,
180
+ defaultSorter,
181
+ getCellHash,
182
+ getCellInRowHash,
183
+ getHash,
184
+ getHlcFunctions,
185
+ getRowHash,
186
+ getRowInTableHash,
187
+ getTableHash,
188
+ getTableInTablesHash,
189
+ getTablesHash,
190
+ getUniqueId,
191
+ getValueHash,
192
+ getValueInValuesHash,
193
+ getValuesHash,
194
+ };
@@ -6,6 +6,7 @@ const GLOBAL = globalThis;
6
6
  const math = Math;
7
7
  const mathMax = math.max;
8
8
  const mathFloor = math.floor;
9
+ const isInstanceOf = (thing, cls) => thing instanceof cls;
9
10
  const isUndefined = (thing) => thing == void 0;
10
11
  const ifNotUndefined = (value, then, otherwise) =>
11
12
  isUndefined(value) ? otherwise?.() : then(value);
@@ -14,6 +15,9 @@ const arrayForEach = (array, cb) => array.forEach(cb);
14
15
  const arrayMap = (array, cb) => array.map(cb);
15
16
  const arrayReduce = (array, cb, initial) => array.reduce(cb, initial);
16
17
 
18
+ const object = Object;
19
+ const objEntries = object.entries;
20
+
17
21
  const mapNew = (entries) => new Map(entries);
18
22
  const mapGet = (map, key) => map?.get(key);
19
23
 
@@ -37,16 +41,55 @@ const getUniqueId = (length = 16) =>
37
41
  '',
38
42
  );
39
43
 
44
+ const jsonString = JSON.stringify;
45
+ const jsonStringWithMap = (obj) =>
46
+ jsonString(obj, (_key, value) =>
47
+ isInstanceOf(value, Map) ? object.fromEntries([...value]) : value,
48
+ );
49
+
40
50
  const textEncoder = /* @__PURE__ */ new GLOBAL.TextEncoder();
41
- const getHash = (value) => {
51
+ const getHash = (string) => {
42
52
  let hash = 2166136261;
43
- arrayForEach(textEncoder.encode(value), (char) => {
53
+ arrayForEach(textEncoder.encode(string), (char) => {
44
54
  hash ^= char;
45
55
  hash +=
46
56
  (hash << 1) + (hash << 4) + (hash << 7) + (hash << 8) + (hash << 24);
47
57
  });
48
58
  return hash >>> 0;
49
59
  };
60
+ const addOrRemoveHash = (hash1, hash2) => (hash1 ^ hash2) >>> 0;
61
+ const getValuesHash = (valueHashes) =>
62
+ arrayReduce(
63
+ objEntries(valueHashes),
64
+ (valuesHash, [valueId, valueHash]) =>
65
+ addOrRemoveHash(
66
+ valuesHash,
67
+ getValueInValuesHash(valueId, valueHash) ^
68
+ getValueInValuesHash(valueId, 0),
69
+ // legacy v5; remove in v7
70
+ ),
71
+ 0,
72
+ // legacy v5; valuesHlc in v7?
73
+ );
74
+ const getValueInValuesHash = (valueId, valueHash) =>
75
+ getHash(valueId + ':' + valueHash);
76
+ const getValueHash = (value, valueHlc) =>
77
+ getHash(jsonStringWithMap(value ?? null) + ':' + valueHlc);
78
+ const getCellHash = getValueHash;
79
+ const getCellInRowHash = getValueInValuesHash;
80
+ const getRowHash = getValuesHash;
81
+ const getRowInTableHash = getValueInValuesHash;
82
+ const getTableHash = (rowHashes) =>
83
+ // alias to getValuesHash in v7
84
+ arrayReduce(
85
+ objEntries(rowHashes),
86
+ (valuesHash, [rowId, rowHash]) =>
87
+ addOrRemoveHash(valuesHash, getValueInValuesHash(rowId, rowHash)),
88
+ 0,
89
+ // legacy v5; rowHlc in v7?
90
+ );
91
+ const getTableInTablesHash = getValueInValuesHash;
92
+ const getTablesHash = getTableHash;
50
93
 
51
94
  const SHIFT36 = 2 ** 36;
52
95
  const SHIFT30 = 2 ** 30;
@@ -132,4 +175,20 @@ const getHlcFunctions = (uniqueId, getNow = Date.now) => {
132
175
  const defaultSorter = (sortKey1, sortKey2) =>
133
176
  (sortKey1 ?? 0) < (sortKey2 ?? 0) ? -1 : 1;
134
177
 
135
- export {defaultSorter, getHlcFunctions, getRandomValues, getUniqueId};
178
+ export {
179
+ addOrRemoveHash,
180
+ defaultSorter,
181
+ getCellHash,
182
+ getCellInRowHash,
183
+ getHash,
184
+ getHlcFunctions,
185
+ getRowHash,
186
+ getRowInTableHash,
187
+ getTableHash,
188
+ getTableInTablesHash,
189
+ getTablesHash,
190
+ getUniqueId,
191
+ getValueHash,
192
+ getValueInValuesHash,
193
+ getValuesHash,
194
+ };