@optimystic/db-core 1.0.0-beta.3 → 1.1.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 (171) hide show
  1. package/dist/src/cluster/structs.d.ts +30 -6
  2. package/dist/src/cluster/structs.d.ts.map +1 -1
  3. package/dist/src/cluster/structs.js +5 -3
  4. package/dist/src/cluster/structs.js.map +1 -1
  5. package/dist/src/cohort-topic/antidos/bootstrap-evidence-envelope.d.ts +2 -1
  6. package/dist/src/cohort-topic/antidos/bootstrap-evidence-envelope.d.ts.map +1 -1
  7. package/dist/src/cohort-topic/antidos/bootstrap-evidence-envelope.js +10 -3
  8. package/dist/src/cohort-topic/antidos/bootstrap-evidence-envelope.js.map +1 -1
  9. package/dist/src/cohort-topic/wire/codec.d.ts.map +1 -1
  10. package/dist/src/cohort-topic/wire/codec.js +8 -2
  11. package/dist/src/cohort-topic/wire/codec.js.map +1 -1
  12. package/dist/src/collection/collection.d.ts +439 -34
  13. package/dist/src/collection/collection.d.ts.map +1 -1
  14. package/dist/src/collection/collection.js +843 -148
  15. package/dist/src/collection/collection.js.map +1 -1
  16. package/dist/src/collection/struct.d.ts +109 -4
  17. package/dist/src/collection/struct.d.ts.map +1 -1
  18. package/dist/src/collection/struct.js +88 -1
  19. package/dist/src/collection/struct.js.map +1 -1
  20. package/dist/src/collections/diary/diary.d.ts +6 -2
  21. package/dist/src/collections/diary/diary.d.ts.map +1 -1
  22. package/dist/src/collections/diary/diary.js +5 -2
  23. package/dist/src/collections/diary/diary.js.map +1 -1
  24. package/dist/src/collections/tree/struct.d.ts +124 -16
  25. package/dist/src/collections/tree/struct.d.ts.map +1 -1
  26. package/dist/src/collections/tree/struct.js +86 -11
  27. package/dist/src/collections/tree/struct.js.map +1 -1
  28. package/dist/src/collections/tree/tree.d.ts +13 -3
  29. package/dist/src/collections/tree/tree.d.ts.map +1 -1
  30. package/dist/src/collections/tree/tree.js +106 -40
  31. package/dist/src/collections/tree/tree.js.map +1 -1
  32. package/dist/src/index.d.ts +1 -1
  33. package/dist/src/index.d.ts.map +1 -1
  34. package/dist/src/index.js +1 -1
  35. package/dist/src/index.js.map +1 -1
  36. package/dist/src/matchmaking/wire.d.ts.map +1 -1
  37. package/dist/src/matchmaking/wire.js +8 -2
  38. package/dist/src/matchmaking/wire.js.map +1 -1
  39. package/dist/src/network/durability.d.ts +45 -0
  40. package/dist/src/network/durability.d.ts.map +1 -0
  41. package/dist/src/network/durability.js +114 -0
  42. package/dist/src/network/durability.js.map +1 -0
  43. package/dist/src/network/i-key-network.d.ts +14 -6
  44. package/dist/src/network/i-key-network.d.ts.map +1 -1
  45. package/dist/src/network/index.d.ts +3 -0
  46. package/dist/src/network/index.d.ts.map +1 -1
  47. package/dist/src/network/index.js +3 -0
  48. package/dist/src/network/index.js.map +1 -1
  49. package/dist/src/network/lineage.d.ts +39 -0
  50. package/dist/src/network/lineage.d.ts.map +1 -0
  51. package/dist/src/network/lineage.js +61 -0
  52. package/dist/src/network/lineage.js.map +1 -0
  53. package/dist/src/network/routing-key.d.ts +24 -0
  54. package/dist/src/network/routing-key.d.ts.map +1 -0
  55. package/dist/src/network/routing-key.js +9 -0
  56. package/dist/src/network/routing-key.js.map +1 -0
  57. package/dist/src/network/stale-failure.d.ts +5 -1
  58. package/dist/src/network/stale-failure.d.ts.map +1 -1
  59. package/dist/src/network/stale-failure.js +5 -1
  60. package/dist/src/network/stale-failure.js.map +1 -1
  61. package/dist/src/network/struct.d.ts +151 -8
  62. package/dist/src/network/struct.d.ts.map +1 -1
  63. package/dist/src/network/struct.js.map +1 -1
  64. package/dist/src/reactivity/wire.d.ts.map +1 -1
  65. package/dist/src/reactivity/wire.js +8 -2
  66. package/dist/src/reactivity/wire.js.map +1 -1
  67. package/dist/src/testing/test-transactor.d.ts +64 -7
  68. package/dist/src/testing/test-transactor.d.ts.map +1 -1
  69. package/dist/src/testing/test-transactor.js +150 -23
  70. package/dist/src/testing/test-transactor.js.map +1 -1
  71. package/dist/src/transaction/coordinator.d.ts +141 -21
  72. package/dist/src/transaction/coordinator.d.ts.map +1 -1
  73. package/dist/src/transaction/coordinator.js +408 -122
  74. package/dist/src/transaction/coordinator.js.map +1 -1
  75. package/dist/src/transaction/errors.d.ts +39 -10
  76. package/dist/src/transaction/errors.d.ts.map +1 -1
  77. package/dist/src/transaction/errors.js +34 -9
  78. package/dist/src/transaction/errors.js.map +1 -1
  79. package/dist/src/transaction/index.d.ts +1 -0
  80. package/dist/src/transaction/index.d.ts.map +1 -1
  81. package/dist/src/transaction/index.js.map +1 -1
  82. package/dist/src/transactor/block-floors.d.ts +78 -0
  83. package/dist/src/transactor/block-floors.d.ts.map +1 -0
  84. package/dist/src/transactor/block-floors.js +62 -0
  85. package/dist/src/transactor/block-floors.js.map +1 -0
  86. package/dist/src/transactor/change-notifier.d.ts +43 -0
  87. package/dist/src/transactor/change-notifier.d.ts.map +1 -1
  88. package/dist/src/transactor/change-notifier.js +3 -0
  89. package/dist/src/transactor/change-notifier.js.map +1 -1
  90. package/dist/src/transactor/index.d.ts +1 -0
  91. package/dist/src/transactor/index.d.ts.map +1 -1
  92. package/dist/src/transactor/index.js +1 -0
  93. package/dist/src/transactor/index.js.map +1 -1
  94. package/dist/src/transactor/network-transactor.d.ts +43 -6
  95. package/dist/src/transactor/network-transactor.d.ts.map +1 -1
  96. package/dist/src/transactor/network-transactor.js +279 -86
  97. package/dist/src/transactor/network-transactor.js.map +1 -1
  98. package/dist/src/transactor/transactor-source.d.ts +94 -4
  99. package/dist/src/transactor/transactor-source.d.ts.map +1 -1
  100. package/dist/src/transactor/transactor-source.js +120 -42
  101. package/dist/src/transactor/transactor-source.js.map +1 -1
  102. package/dist/src/transactor/transactor.d.ts +14 -1
  103. package/dist/src/transactor/transactor.d.ts.map +1 -1
  104. package/dist/src/transform/atomic.d.ts.map +1 -1
  105. package/dist/src/transform/atomic.js +12 -9
  106. package/dist/src/transform/atomic.js.map +1 -1
  107. package/dist/src/transform/base-pins.d.ts +50 -17
  108. package/dist/src/transform/base-pins.d.ts.map +1 -1
  109. package/dist/src/transform/base-pins.js +58 -11
  110. package/dist/src/transform/base-pins.js.map +1 -1
  111. package/dist/src/transform/cache-source.d.ts +75 -11
  112. package/dist/src/transform/cache-source.d.ts.map +1 -1
  113. package/dist/src/transform/cache-source.js +162 -36
  114. package/dist/src/transform/cache-source.js.map +1 -1
  115. package/dist/src/transform/digest.d.ts +8 -1
  116. package/dist/src/transform/digest.d.ts.map +1 -1
  117. package/dist/src/transform/digest.js +19 -9
  118. package/dist/src/transform/digest.js.map +1 -1
  119. package/dist/src/transform/helpers.d.ts +6 -2
  120. package/dist/src/transform/helpers.d.ts.map +1 -1
  121. package/dist/src/transform/helpers.js +8 -3
  122. package/dist/src/transform/helpers.js.map +1 -1
  123. package/dist/src/transform/tracker.d.ts +94 -14
  124. package/dist/src/transform/tracker.d.ts.map +1 -1
  125. package/dist/src/transform/tracker.js +222 -68
  126. package/dist/src/transform/tracker.js.map +1 -1
  127. package/dist/src/utility/structural-equals.d.ts +38 -0
  128. package/dist/src/utility/structural-equals.d.ts.map +1 -0
  129. package/dist/src/utility/structural-equals.js +77 -0
  130. package/dist/src/utility/structural-equals.js.map +1 -0
  131. package/package.json +2 -2
  132. package/src/cluster/structs.ts +28 -7
  133. package/src/cohort-topic/antidos/bootstrap-evidence-envelope.ts +260 -253
  134. package/src/cohort-topic/wire/codec.ts +222 -216
  135. package/src/collection/collection.ts +960 -157
  136. package/src/collection/struct.ts +99 -4
  137. package/src/collections/diary/diary.ts +71 -68
  138. package/src/collections/tree/struct.ts +155 -23
  139. package/src/collections/tree/tree.ts +127 -40
  140. package/src/index.ts +1 -1
  141. package/src/matchmaking/wire.ts +8 -2
  142. package/src/network/durability.ts +123 -0
  143. package/src/network/i-key-network.ts +60 -52
  144. package/src/network/index.ts +10 -7
  145. package/src/network/lineage.ts +80 -0
  146. package/src/network/routing-key.ts +27 -0
  147. package/src/network/stale-failure.ts +5 -1
  148. package/src/network/struct.ts +156 -8
  149. package/src/reactivity/wire.ts +230 -224
  150. package/src/testing/test-transactor.ts +152 -24
  151. package/src/transaction/coordinator.ts +470 -131
  152. package/src/transaction/errors.ts +34 -9
  153. package/src/transaction/index.ts +1 -0
  154. package/src/transactor/block-floors.ts +105 -0
  155. package/src/transactor/change-notifier.ts +129 -80
  156. package/src/transactor/index.ts +1 -0
  157. package/src/transactor/network-transactor.ts +297 -89
  158. package/src/transactor/transactor-source.ts +131 -42
  159. package/src/transactor/transactor.ts +13 -1
  160. package/src/transform/atomic.ts +25 -22
  161. package/src/transform/base-pins.ts +76 -18
  162. package/src/transform/cache-source.ts +327 -194
  163. package/src/transform/digest.ts +21 -10
  164. package/src/transform/helpers.ts +8 -3
  165. package/src/transform/tracker.ts +423 -270
  166. package/src/utility/structural-equals.ts +72 -0
  167. package/dist/src/utility/block-id-to-bytes.d.ts +0 -3
  168. package/dist/src/utility/block-id-to-bytes.d.ts.map +0 -1
  169. package/dist/src/utility/block-id-to-bytes.js +0 -7
  170. package/dist/src/utility/block-id-to-bytes.js.map +0 -1
  171. package/src/utility/block-id-to-bytes.ts +0 -8
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Deep structural equality over the JSON-shaped values this codebase stores and transports:
3
+ * primitives, plain objects, arrays, and `Uint8Array` (compared by bytes — a byte array survives
4
+ * `structuredClone`, which is the in-process transport the test transactors use).
5
+ *
6
+ * Written for the tree's `unchanged` entry guard (`TreeEntryGuard` in
7
+ * `packages/db-core/src/collections/tree/struct.ts`), which must decide whether the entry
8
+ * currently committed at a key is still the one a staged write read — where one side has
9
+ * usually round-tripped through the log's encoding and the other has not. The three rules
10
+ * that follow from that:
11
+ *
12
+ * - **Object key ORDER is irrelevant.** An encoder may sort keys (see `canonicalJson`); the
13
+ * value did not change because the bytes were reordered.
14
+ * - **A key whose value is `undefined` counts as ABSENT**, matching what JSON does to it, so
15
+ * `{ a: 1, b: undefined }` and `{ a: 1 }` compare equal. Without this, an entry carrying an
16
+ * explicit `undefined` property would refuse itself the moment it crossed a JSON boundary.
17
+ * - **`NaN` equals `NaN`.** A guard that can never accept its own value is a trap, not a check.
18
+ *
19
+ * NOTE: values outside that shape — `Date`, `Map`, `Set`, class instances — fall through to the
20
+ * plain-object arm and are compared by their own enumerable properties, which for two distinct
21
+ * `Date`s (no own properties) reports EQUAL. Entries are JSON-shaped by contract (they are
22
+ * serialized into the log), so nothing reaches that path today; if a richer entry type is ever
23
+ * introduced, this function needs a type tag before it can judge it.
24
+ *
25
+ * NOTE: the `Uint8Array` arm is correct but currently unreachable across the REAL transport. The
26
+ * peer-to-peer repo protocol is JSON both directions (`JSON.stringify` in
27
+ * `packages/db-p2p/src/protocol-client.ts`, `JSON.parse` in `packages/db-p2p/src/repo/service.ts`),
28
+ * and JSON turns a `Uint8Array` into an index-keyed object — which the arm below deliberately
29
+ * reports as NOT equal to the bytes it came from. So an entry type that is genuinely byte-shaped
30
+ * would make an `unchanged` guard refuse an honest write forever, not just once. No such entry
31
+ * type exists: the one candidate is the plugin's `EncodedRow` under `msgpack`, and that encoder
32
+ * throws `not yet implemented` (`packages/quereus-plugin-optimystic/src/schema/row-codec.ts`);
33
+ * under the `json` encoding BLOB columns are base64 strings before they ever reach a tree entry.
34
+ * If a byte-shaped entry type is ever introduced, the guard's `expected` needs a transport-stable
35
+ * encoding (base64, or a tagged wrapper) BEFORE this comparison can be trusted over the wire.
36
+ */
37
+ export function structuralEquals(a: unknown, b: unknown): boolean {
38
+ if (a === b) return true; // identical reference, or identical primitive
39
+ if (typeof a === 'number' && typeof b === 'number') return Number.isNaN(a) && Number.isNaN(b);
40
+ if (a === null || b === null || typeof a !== 'object' || typeof b !== 'object') return false;
41
+ if (a instanceof Uint8Array || b instanceof Uint8Array) return bytesEqual(a, b);
42
+ if (Array.isArray(a) || Array.isArray(b)) return arraysEqual(a, b);
43
+ return objectsEqual(a as Record<string, unknown>, b as Record<string, unknown>);
44
+ }
45
+
46
+ /** Byte-wise comparison. A `Uint8Array` is only equal to another `Uint8Array` — a plain array or
47
+ * object with the same numeric indices is a DIFFERENT encoding of the value, and treating it as
48
+ * equal would let an encoding change slip past a guard unnoticed. */
49
+ function bytesEqual(a: object, b: object): boolean {
50
+ if (!(a instanceof Uint8Array) || !(b instanceof Uint8Array) || a.length !== b.length) return false;
51
+ return a.every((byte, i) => byte === b[i]);
52
+ }
53
+
54
+ /** Element-wise comparison; position is meaning, so order matters here (unlike object keys). */
55
+ function arraysEqual(a: object, b: object): boolean {
56
+ if (!Array.isArray(a) || !Array.isArray(b) || a.length !== b.length) return false;
57
+ return a.every((value, i) => structuralEquals(value, b[i]));
58
+ }
59
+
60
+ /** Compares the DEFINED own properties of two plain objects, order-independently. Equal counts of
61
+ * defined keys plus a recursive match on each of `a`'s is sufficient: a key present in `b` but
62
+ * not `a` would push `b`'s count higher, and a key `a` defines that `b` leaves undefined fails
63
+ * the recursive compare. */
64
+ function objectsEqual(a: Record<string, unknown>, b: Record<string, unknown>): boolean {
65
+ const keys = definedKeys(a);
66
+ if (keys.length !== definedKeys(b).length) return false;
67
+ return keys.every(key => structuralEquals(a[key], b[key]));
68
+ }
69
+
70
+ function definedKeys(value: Record<string, unknown>): string[] {
71
+ return Object.keys(value).filter(key => value[key] !== undefined);
72
+ }
@@ -1,3 +0,0 @@
1
- import type { BlockId } from '../index.js';
2
- export declare function blockIdToBytes(blockId: BlockId): Promise<Uint8Array>;
3
- //# sourceMappingURL=block-id-to-bytes.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"block-id-to-bytes.d.ts","sourceRoot":"","sources":["../../../src/utility/block-id-to-bytes.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AAE1C,wBAAsB,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC,CAI1E"}
@@ -1,7 +0,0 @@
1
- import { sha256 } from 'multiformats/hashes/sha2';
2
- export async function blockIdToBytes(blockId) {
3
- const input = new TextEncoder().encode(blockId);
4
- const mh = await sha256.digest(input);
5
- return mh.digest;
6
- }
7
- //# sourceMappingURL=block-id-to-bytes.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"block-id-to-bytes.js","sourceRoot":"","sources":["../../../src/utility/block-id-to-bytes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAA;AAGjD,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,OAAgB;IACjD,MAAM,KAAK,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;IAC/C,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;IACrC,OAAO,EAAE,CAAC,MAAM,CAAA;AACpB,CAAC"}
@@ -1,8 +0,0 @@
1
- import { sha256 } from 'multiformats/hashes/sha2'
2
- import type { BlockId } from '../index.js'
3
-
4
- export async function blockIdToBytes(blockId: BlockId): Promise<Uint8Array> {
5
- const input = new TextEncoder().encode(blockId)
6
- const mh = await sha256.digest(input)
7
- return mh.digest
8
- }