@rljson/db 0.0.20 → 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.
- package/dist/connector/connector.d.ts +14 -5
- package/dist/db.d.ts +1 -0
- package/dist/db.js +40 -18
- package/dist/db.js.map +1 -1
- package/package.json +16 -8
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
import { Socket } from '@rljson/io';
|
|
2
|
-
import { AckPayload, ClientId, ConflictCallback,
|
|
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
|
-
|
|
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
|
|
43
|
-
*
|
|
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:
|
|
54
|
+
setPredecessors(predecessors: string[]): void;
|
|
46
55
|
/**
|
|
47
56
|
* Registers a callback for incoming refs on this route.
|
|
48
57
|
*
|
package/dist/db.d.ts
CHANGED
|
@@ -112,6 +112,7 @@ export declare class Db {
|
|
|
112
112
|
insertTrees(treeKey: string, trees: Tree[], options?: {
|
|
113
113
|
skipNotification?: boolean;
|
|
114
114
|
skipHistory?: boolean;
|
|
115
|
+
previous?: InsertHistoryTimeId[];
|
|
115
116
|
}): Promise<InsertHistoryRow<any>[]>;
|
|
116
117
|
/**
|
|
117
118
|
* Recursively runs controllers based on the route of the Insert
|
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
|
|
96
|
-
*
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
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.
|
|
287
|
-
|
|
288
|
-
|
|
305
|
+
this._lastPredecessors = refs;
|
|
306
|
+
}
|
|
307
|
+
this.send(ref);
|
|
289
308
|
});
|
|
290
309
|
}
|
|
291
310
|
get socket() {
|
|
@@ -3843,6 +3862,9 @@ class Db {
|
|
|
3843
3862
|
...rootResult,
|
|
3844
3863
|
route: route.flat
|
|
3845
3864
|
};
|
|
3865
|
+
if (options?.previous) {
|
|
3866
|
+
result.previous = options.previous;
|
|
3867
|
+
}
|
|
3846
3868
|
if (!options?.skipHistory) {
|
|
3847
3869
|
await this._writeInsertHistory(treeKey, result);
|
|
3848
3870
|
}
|