@rljson/db 0.0.21 → 0.0.22

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.
@@ -1,8 +1,14 @@
1
1
  import { Socket } from '@rljson/io';
2
- import { AckPayload, ClientId, ConflictCallback, InsertHistoryTimeId, Route, SyncConfig, SyncEventNames } from '@rljson/rljson';
2
+ import { AckPayload, ClientId, ConflictCallback, Route, SyncConfig, SyncEventNames } from '@rljson/rljson';
3
3
  import { Db } from '../db.ts';
4
4
  export type { ConnectorPayload } from '@rljson/rljson';
5
- export type ConnectorCallback = (ref: string) => Promise<any>;
5
+ /**
6
+ * Invoked for each deduplicated incoming ref. `predecessorRefs` carries the
7
+ * causal predecessor *content refs* (shared identity across clients) when
8
+ * `causalOrdering` is enabled, so the receiver can record correct ancestry in
9
+ * its own InsertHistory. Empty/undefined for roots or when causal ordering is off.
10
+ */
11
+ export type ConnectorCallback = (ref: string, predecessorRefs?: string[]) => Promise<any>;
6
12
  export declare class Connector {
7
13
  private readonly _db;
8
14
  private readonly _route;
@@ -11,6 +17,7 @@ export declare class Connector {
11
17
  private _callbacks;
12
18
  private _conflictCallbacks;
13
19
  private _missedRef;
20
+ private _missedPredecessorRefs;
14
21
  private _lastSentRef;
15
22
  private _isListening;
16
23
  private _sentRefsCurrent;
@@ -39,10 +46,12 @@ export declare class Connector {
39
46
  */
40
47
  sendWithAck(ref: string): Promise<AckPayload>;
41
48
  /**
42
- * Sets the causal predecessors for the next send.
43
- * @param predecessors - The InsertHistory timeIds of causal predecessors
49
+ * Sets the causal predecessors (content refs) attached to the next send.
50
+ * Normally auto-populated from the InsertHistoryRow; exposed for tests/manual
51
+ * control.
52
+ * @param predecessors - The predecessor content refs
44
53
  */
45
- setPredecessors(predecessors: InsertHistoryTimeId[]): void;
54
+ setPredecessors(predecessors: string[]): void;
46
55
  /**
47
56
  * Registers a callback for incoming refs on this route.
48
57
  *
package/dist/db.js CHANGED
@@ -24,6 +24,7 @@ class Connector {
24
24
  _callbacks = [];
25
25
  _conflictCallbacks = [];
26
26
  _missedRef = null;
27
+ _missedPredecessorRefs = void 0;
27
28
  _lastSentRef = null;
28
29
  _isListening = false;
29
30
  // Two-generation dedup sets — bounded memory
@@ -37,6 +38,9 @@ class Connector {
37
38
  _clientId;
38
39
  _events;
39
40
  _seq = 0;
41
+ // Predecessor *content refs* (not timeIds) attached to the next send. Refs are
42
+ // the only identity shared across clients, so the receiver can map them to its
43
+ // own local ancestry. Auto-populated from the InsertHistoryRow on db inserts.
40
44
  _lastPredecessors = [];
41
45
  _peerSeqs = /* @__PURE__ */ new Map();
42
46
  // ...........................................................................
@@ -92,8 +96,10 @@ class Connector {
92
96
  }
93
97
  // ...........................................................................
94
98
  /**
95
- * Sets the causal predecessors for the next send.
96
- * @param predecessors - The InsertHistory timeIds of causal predecessors
99
+ * Sets the causal predecessors (content refs) attached to the next send.
100
+ * Normally auto-populated from the InsertHistoryRow; exposed for tests/manual
101
+ * control.
102
+ * @param predecessors - The predecessor content refs
97
103
  */
98
104
  setPredecessors(predecessors) {
99
105
  this._lastPredecessors = predecessors;
@@ -111,8 +117,12 @@ class Connector {
111
117
  this._callbacks.push(callback);
112
118
  if (this._missedRef !== null) {
113
119
  const ref = this._missedRef;
120
+ const predecessorRefs = this._missedPredecessorRefs;
114
121
  this._missedRef = null;
115
- Promise.resolve(callback(ref)).catch(console.error);
122
+ this._missedPredecessorRefs = void 0;
123
+ Promise.resolve(
124
+ predecessorRefs ? callback(ref, predecessorRefs) : callback(ref)
125
+ ).catch(console.error);
116
126
  }
117
127
  }
118
128
  // ...........................................................................
@@ -209,12 +219,17 @@ class Connector {
209
219
  this._receivedRefsCurrent = /* @__PURE__ */ new Set();
210
220
  }
211
221
  }
212
- _notifyCallbacks(ref) {
222
+ _notifyCallbacks(ref, predecessorRefs) {
213
223
  if (this._callbacks.length === 0) {
214
224
  this._missedRef = ref;
225
+ this._missedPredecessorRefs = predecessorRefs;
215
226
  return;
216
227
  }
217
- Promise.all(this._callbacks.map((cb) => cb(ref))).catch((err) => {
228
+ Promise.all(
229
+ this._callbacks.map(
230
+ (cb) => predecessorRefs ? cb(ref, predecessorRefs) : cb(ref)
231
+ )
232
+ ).catch((err) => {
218
233
  console.error(`Error notifying connector callbacks for ref ${ref}:`, err);
219
234
  });
220
235
  }
@@ -235,7 +250,7 @@ class Connector {
235
250
  this._peerSeqs.set(payload.c, payload.seq);
236
251
  }
237
252
  this._addReceivedRef(ref);
238
- this._notifyCallbacks(ref);
253
+ this._notifyCallbacks(ref, payload.p);
239
254
  if (this._syncConfig?.requireAck) {
240
255
  this._socket.emit(this._events.ackClient, { r: ref });
241
256
  }
@@ -273,19 +288,23 @@ class Connector {
273
288
  });
274
289
  }
275
290
  _registerDbObserver() {
276
- this._db.registerObserver(this._route, (ins) => {
277
- return new Promise((resolve) => {
278
- const ref = ins[this.route.root.tableKey + "Ref"];
279
- if (this._hasSentRef(ref)) {
280
- resolve();
281
- return;
282
- }
283
- if (this._syncConfig?.causalOrdering && ins.previous?.length) {
284
- this._lastPredecessors = [...ins.previous];
291
+ this._db.registerObserver(this._route, async (ins) => {
292
+ const tableKey = this.route.root.tableKey;
293
+ const ref = ins[tableKey + "Ref"];
294
+ if (this._hasSentRef(ref)) {
295
+ return;
296
+ }
297
+ if (this._syncConfig?.causalOrdering && ins.previous?.length) {
298
+ const refs = [];
299
+ for (const timeId2 of ins.previous) {
300
+ const predRef = await this._db.getRefOfTimeId(tableKey, timeId2);
301
+ if (predRef) {
302
+ refs.push(predRef);
303
+ }
285
304
  }
286
- this.send(ref);
287
- resolve();
288
- });
305
+ this._lastPredecessors = refs;
306
+ }
307
+ this.send(ref);
289
308
  });
290
309
  }
291
310
  get socket() {