@serfab/cadre-core 1.5.0 → 1.7.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.
- package/dist/cadre-node.d.ts +206 -67
- package/dist/cadre-node.js +399 -98
- package/dist/cadre-node.js.map +1 -1
- package/dist/index.d.ts +6 -1
- package/dist/index.js +17 -1
- package/dist/index.js.map +1 -1
- package/dist/joined-strand-store.d.ts +112 -0
- package/dist/joined-strand-store.js +263 -0
- package/dist/joined-strand-store.js.map +1 -0
- package/dist/key-store.d.ts +6 -0
- package/dist/key-store.js.map +1 -1
- package/dist/link-budget.d.ts +95 -53
- package/dist/link-budget.js +97 -53
- package/dist/link-budget.js.map +1 -1
- package/dist/node-local-snapshot.d.ts +5 -4
- package/dist/node-local-snapshot.js +6 -3
- package/dist/node-local-snapshot.js.map +1 -1
- package/dist/peer-dial.d.ts +3 -3
- package/dist/peer-dial.js +3 -3
- package/dist/peer-join-backfill.d.ts +35 -16
- package/dist/peer-join-backfill.js +117 -57
- package/dist/peer-join-backfill.js.map +1 -1
- package/dist/relay-reservation.d.ts +2 -2
- package/dist/relay-reservation.js +2 -2
- package/dist/seed-bootstrap.js +1 -1
- package/dist/strand-first-sync-gate.d.ts +88 -43
- package/dist/strand-first-sync-gate.js +92 -46
- package/dist/strand-first-sync-gate.js.map +1 -1
- package/dist/strand-instance-manager.d.ts +39 -0
- package/dist/strand-instance-manager.js +80 -3
- package/dist/strand-instance-manager.js.map +1 -1
- package/dist/strand-peer-book-file.d.ts +12 -0
- package/dist/strand-peer-book-file.js +37 -0
- package/dist/strand-peer-book-file.js.map +1 -0
- package/dist/strand-peer-book-protocol.d.ts +159 -0
- package/dist/strand-peer-book-protocol.js +360 -0
- package/dist/strand-peer-book-protocol.js.map +1 -0
- package/dist/strand-peer-book-swap.d.ts +104 -0
- package/dist/strand-peer-book-swap.js +284 -0
- package/dist/strand-peer-book-swap.js.map +1 -0
- package/dist/strand-peer-book.d.ts +159 -0
- package/dist/strand-peer-book.js +354 -0
- package/dist/strand-peer-book.js.map +1 -0
- package/dist/strand-peer-observer.d.ts +88 -0
- package/dist/strand-peer-observer.js +180 -0
- package/dist/strand-peer-observer.js.map +1 -0
- package/dist/types.d.ts +84 -17
- package/dist/types.js +6 -0
- package/dist/types.js.map +1 -1
- package/package.json +11 -7
- package/src/cadre-node.ts +7776 -7445
- package/src/index.ts +68 -0
- package/src/joined-strand-store.ts +308 -0
- package/src/key-store.ts +6 -0
- package/src/link-budget.ts +100 -53
- package/src/node-local-snapshot.ts +293 -289
- package/src/peer-dial.ts +3 -3
- package/src/peer-join-backfill.ts +709 -647
- package/src/relay-reservation.ts +2 -2
- package/src/seed-bootstrap.ts +1 -1
- package/src/strand-first-sync-gate.ts +352 -306
- package/src/strand-instance-manager.ts +106 -3
- package/src/strand-peer-book-file.ts +39 -0
- package/src/strand-peer-book-protocol.ts +463 -0
- package/src/strand-peer-book-swap.ts +338 -0
- package/src/strand-peer-book.ts +468 -0
- package/src/strand-peer-observer.ts +235 -0
- package/src/types.ts +86 -17
package/dist/types.d.ts
CHANGED
|
@@ -10,7 +10,9 @@ import type { SeedTrustPolicy } from './seed-trust-policy.js';
|
|
|
10
10
|
import type { KeyStore, KeyId } from './key-store.js';
|
|
11
11
|
import type { TrustedOwnerStore, TrustSource } from './trusted-owner-store.js';
|
|
12
12
|
import type { BootstrapPeerStore } from './bootstrap-peer-store.js';
|
|
13
|
+
import type { StrandPeerBookStore } from './strand-peer-book.js';
|
|
13
14
|
import type { EnrolledMachineStore } from './enrolled-machine-store.js';
|
|
15
|
+
import type { JoinedStrandStore } from './joined-strand-store.js';
|
|
14
16
|
import type { PushNotifier } from './push-notifier.js';
|
|
15
17
|
import type { RevocableTable } from './control-authorization.js';
|
|
16
18
|
import type { ControlRetryAbandonment } from './control-retry.js';
|
|
@@ -285,7 +287,7 @@ export interface NetworkConfig {
|
|
|
285
287
|
* It buys a node that BOOTS, not a node that boots fast: `start()` still waits
|
|
286
288
|
* out that first attempt, which costs the drive's whole timeout
|
|
287
289
|
* (`DEFAULT_RELAY_RESERVE_TIMEOUT_MS`, four link round trips at
|
|
288
|
-
* {@link linkRoundTripMs} —
|
|
290
|
+
* {@link linkRoundTripMs} — 14 s at its default) against a relay that is unreachable
|
|
289
291
|
* rather than merely refusing (`relay-reservation.ts` polls to the deadline, in
|
|
290
292
|
* case libp2p's own discovery lands a reservation independently).
|
|
291
293
|
*
|
|
@@ -402,22 +404,25 @@ export interface NetworkConfig {
|
|
|
402
404
|
* The round trip this node assumes between itself and another machine, in milliseconds, for
|
|
403
405
|
* the control node and every strand node — as {@link cohortQueryTimeoutMs} is, and for the
|
|
404
406
|
* same reason: the setting describes the LINK, and a phone's control node and its strand
|
|
405
|
-
* nodes ride the same one. Omitted takes {@link DECLARED_LINK_ROUND_TRIP_MS} (
|
|
407
|
+
* nodes ride the same one. Omitted takes {@link DECLARED_LINK_ROUND_TRIP_MS} (3500 ms).
|
|
406
408
|
*
|
|
407
409
|
* This is NOT a timeout. It is the one stated assumption that cadre's own dial and
|
|
408
410
|
* reservation deadlines are DERIVED from, each by the number of round trips that operation
|
|
409
411
|
* was measured to cost: a peer-join catch-up's dial to one peer, its push response, one relay
|
|
410
|
-
* reservation drive,
|
|
411
|
-
*
|
|
412
|
-
*
|
|
413
|
-
*
|
|
414
|
-
*
|
|
412
|
+
* reservation drive, the control-cohort dial budgets, and libp2p's own `dialTimeout` and
|
|
413
|
+
* `inboundUpgradeTimeout` on every node. Reaching another machine through a relay costs a
|
|
414
|
+
* fixed number of exchanges, so a deadline written as milliseconds has a link speed above
|
|
415
|
+
* which it can never open a connection — which is the defect this declaration exists to make
|
|
416
|
+
* impossible to reintroduce one budget at a time. The counts, the measurement behind them,
|
|
417
|
+
* and what still fails at the supported link are in `link-budget.ts`.
|
|
415
418
|
*
|
|
416
|
-
*
|
|
417
|
-
* the ordinary cost of longer deadlines, a peer
|
|
418
|
-
* that
|
|
419
|
-
*
|
|
420
|
-
*
|
|
419
|
+
* The default covers the slowest link sereus supports, a 3-second round trip through a relay.
|
|
420
|
+
* Raise it for a link slower still; the cost is the ordinary cost of longer deadlines, a peer
|
|
421
|
+
* that is genuinely gone holding each operation that much longer before it is abandoned and
|
|
422
|
+
* retried. Lower it only if EVERY machine of the party is that close: this node is also the
|
|
423
|
+
* listener for connections other machines open to it, and its `inboundUpgradeTimeout` comes
|
|
424
|
+
* from this value, so a node declaring a faster link than its peers discards their
|
|
425
|
+
* half-built connections — silently, from the dialer's side.
|
|
421
426
|
*
|
|
422
427
|
* Refused where the libp2p node is built — inside `CadreNode.start()` for the control
|
|
423
428
|
* network, inside `CadreNode.addStrand` for a strand — if it is not a finite number above
|
|
@@ -536,6 +541,12 @@ export interface NetworkConfig {
|
|
|
536
541
|
* kept it (the same pair aborted at a 200ms stall only when the deadline was 300ms). An
|
|
537
542
|
* interval strictly above the deadline is what makes the 30 seconds real.
|
|
538
543
|
*
|
|
544
|
+
* WHAT THE LINK NEEDS OF IT. One ping opens a fresh stream and echoes over it: a protocol
|
|
545
|
+
* negotiation plus the echo, two link round trips by `link-budget.ts`'s counts (a `newStream`
|
|
546
|
+
* over a relayed circuit measured 3016 ms at 1500 ms one-way). At the slowest link sereus
|
|
547
|
+
* supports, a 3-second relayed round trip, that is about 6 s — well inside the 30 s deadline,
|
|
548
|
+
* which exists for the phone's CPU rather than the link.
|
|
549
|
+
*
|
|
539
550
|
* WHAT IT COSTS. A dead peer is reclaimed 30 to 65 seconds after it stops answering — the
|
|
540
551
|
* deadline, plus up to one interval of waiting for the ping that will fail — where
|
|
541
552
|
* libp2p's defaults took about 5 to 15 seconds. `db-p2p` caps a node at 16 connections,
|
|
@@ -742,11 +753,11 @@ export interface CadreNodeConfig {
|
|
|
742
753
|
* `timeoutMs` bounds how long {@link CadreNode.addStrand} waits before rejecting with
|
|
743
754
|
* `StrandAwaitingFirstSyncError` (retryable — the launch stays up and keeps probing);
|
|
744
755
|
* `pollIntervalMs` is the probe cadence. Omit for the defaults (`DEFAULT_STRAND_FIRST_SYNC_TIMEOUT_MS`,
|
|
745
|
-
*
|
|
746
|
-
*
|
|
747
|
-
* only copy of
|
|
748
|
-
* deliberately no way to disable the gate: a machine
|
|
749
|
-
* gated, so nothing that works today is blocked by it.
|
|
756
|
+
* sized for a machine re-attaching through a relay on a slow link, the slowest attach
|
|
757
|
+
* measured; that constant's doc comment carries the number, the measurement behind it and
|
|
758
|
+
* what the budget costs, and is the only copy of them; `DEFAULT_STRAND_FIRST_SYNC_POLL_MS`,
|
|
759
|
+
* 500 ms). There is deliberately no way to disable the gate: a machine whose store already
|
|
760
|
+
* holds the Header is never gated, so nothing that works today is blocked by it.
|
|
750
761
|
*/
|
|
751
762
|
strandFirstSync?: StrandFirstSyncConfig;
|
|
752
763
|
/** Hibernation configuration */
|
|
@@ -865,6 +876,52 @@ export interface CadreNodeConfig {
|
|
|
865
876
|
*/
|
|
866
877
|
store?: EnrolledMachineStore;
|
|
867
878
|
};
|
|
879
|
+
/**
|
|
880
|
+
* Node-local record of the strands this node joined from ANOTHER party (see
|
|
881
|
+
* `joined-strand-store.ts`): id, type and the closed strand's read secret, recorded
|
|
882
|
+
* by `formStrand` and by a joining (not `founder: true`) `addStrand` whose row is
|
|
883
|
+
* not in this party's control database, and re-offered on every start as `strand:discovered` — so an embedding
|
|
884
|
+
* app keeps no list of its own.
|
|
885
|
+
*
|
|
886
|
+
* Absent ⇒ a `KeyStoreJoinedStrandStore` over {@link keyStore} when one is
|
|
887
|
+
* configured (the record carries a secret, and the KeyStore is where every platform
|
|
888
|
+
* already keeps secrets), else an in-memory store that warns once and forgets every
|
|
889
|
+
* join on restart. An embedder that passes {@link privateKey} rather than a
|
|
890
|
+
* `keyStore` injects a durable store here, e.g.
|
|
891
|
+
* `new KeyStoreJoinedStrandStore(new FileKeyStore(dir), partyId)`.
|
|
892
|
+
*/
|
|
893
|
+
joinedStrands?: {
|
|
894
|
+
/** Its `partyId` must match `controlNetwork.partyId`; start() fails closed on a mismatch. */
|
|
895
|
+
store?: JoinedStrandStore;
|
|
896
|
+
};
|
|
897
|
+
/**
|
|
898
|
+
* Node-local strand peer book (see `strand-peer-book.ts`): per strand, the strand
|
|
899
|
+
* peers this node has met — the other parties' strand transport peers a formation
|
|
900
|
+
* carried back, and every strand peer observed on a live connection — with their
|
|
901
|
+
* last-known addresses. Read on every launch, hibernation resume and periodic
|
|
902
|
+
* address refresh, so a restarted machine dials the peers it was talking to before
|
|
903
|
+
* anything else, instead of coming back up alone (gotchoices/sereus#18). Sibling
|
|
904
|
+
* of {@link bootstrapPeers} — same NON-replicated, per-party, injected-backend
|
|
905
|
+
* shape — and, like it, nothing here is trust-bearing: dial hints only, each
|
|
906
|
+
* bound to its peer id. Entries age out after 14 days (`STRAND_PEER_MAX_AGE_MS`,
|
|
907
|
+
* overridable per store via `StrandPeerBookOptions.maxAgeMs`).
|
|
908
|
+
*
|
|
909
|
+
* Absent ⇒ an in-memory store is created at start() (ephemeral: the book dies
|
|
910
|
+
* with the process, and a cross-party strand whose only contact was the other
|
|
911
|
+
* party does not re-mesh after a restart until a fresh formation). Every
|
|
912
|
+
* reference embedder injects a durable backend over the same slot kind as its
|
|
913
|
+
* bootstrap-peer store. A new platform needs no new store class: supply a
|
|
914
|
+
* `DurableSlot` and inject `PersistentStrandPeerBookStore.open(slot, partyId)`.
|
|
915
|
+
*/
|
|
916
|
+
strandPeers?: {
|
|
917
|
+
/**
|
|
918
|
+
* Injected store instance — e.g. a `FileStrandPeerBookStore` from the
|
|
919
|
+
* Node-only subpath `@serfab/cadre-core/strand-peer-book-file`, persisted in
|
|
920
|
+
* the node's state directory. Its `partyId` must match
|
|
921
|
+
* `controlNetwork.partyId`; start() fails closed on a mismatch.
|
|
922
|
+
*/
|
|
923
|
+
store?: StrandPeerBookStore;
|
|
924
|
+
};
|
|
868
925
|
/**
|
|
869
926
|
* Platform push-delivery for suspended mobile peers. When present, the node's
|
|
870
927
|
* server fan-out can deliver strand-wake data messages over the platform push
|
|
@@ -1287,6 +1344,10 @@ export interface CadreNodeEvents {
|
|
|
1287
1344
|
* re-admits this party, so a second removal is reported again — and a
|
|
1288
1345
|
* hibernation wake rebuilds the gate, which may re-emit for a strand still
|
|
1289
1346
|
* revoked.
|
|
1347
|
+
*
|
|
1348
|
+
* For a strand joined from another party, the node also forgets its remembered
|
|
1349
|
+
* join (see {@link CadreNodeConfig.joinedStrands}): it keeps running this session
|
|
1350
|
+
* and is not re-offered after the next start.
|
|
1290
1351
|
*/
|
|
1291
1352
|
'strand:revoked': {
|
|
1292
1353
|
strandId: string;
|
|
@@ -1324,6 +1385,12 @@ export interface CadreNodeEvents {
|
|
|
1324
1385
|
* Carries the full {@link StrandRow} so the app can join without re-querying
|
|
1325
1386
|
* the control DB.
|
|
1326
1387
|
*
|
|
1388
|
+
* Also emitted for a strand this node joined from ANOTHER party, which no control
|
|
1389
|
+
* row names: the node remembers every such join (see
|
|
1390
|
+
* {@link CadreNodeConfig.joinedStrands}) and offers it here on each start, as a row
|
|
1391
|
+
* with `FounderOwnerKey: null` carrying the closed strand's `MemberPrivateKey`. That
|
|
1392
|
+
* row is the product of the formation's consent, so claiming it needs no second one.
|
|
1393
|
+
*
|
|
1327
1394
|
* **Fired once per strand per session, and it can fire before your listener is
|
|
1328
1395
|
* attached.** The strand watcher's first poll runs inside `CadreNode.start()`
|
|
1329
1396
|
* (100 ms after the watcher starts), so every strand already stored for this
|
package/dist/types.js
CHANGED
|
@@ -66,6 +66,12 @@ export const HIBERNATION_TIMEOUTS = {
|
|
|
66
66
|
* kept it (the same pair aborted at a 200ms stall only when the deadline was 300ms). An
|
|
67
67
|
* interval strictly above the deadline is what makes the 30 seconds real.
|
|
68
68
|
*
|
|
69
|
+
* WHAT THE LINK NEEDS OF IT. One ping opens a fresh stream and echoes over it: a protocol
|
|
70
|
+
* negotiation plus the echo, two link round trips by `link-budget.ts`'s counts (a `newStream`
|
|
71
|
+
* over a relayed circuit measured 3016 ms at 1500 ms one-way). At the slowest link sereus
|
|
72
|
+
* supports, a 3-second relayed round trip, that is about 6 s — well inside the 30 s deadline,
|
|
73
|
+
* which exists for the phone's CPU rather than the link.
|
|
74
|
+
*
|
|
69
75
|
* WHAT IT COSTS. A dead peer is reclaimed 30 to 65 seconds after it stops answering — the
|
|
70
76
|
* deadline, plus up to one interval of waiting for the ping that will fail — where
|
|
71
77
|
* libp2p's defaults took about 5 to 15 seconds. `db-p2p` caps a node at 16 connections,
|
package/dist/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAkFA;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAA6C;IAC5E,QAAQ,EAAE;QACR,WAAW,EAAE,QAAQ,EAAS,aAAa;QAC3C,gBAAgB,EAAE,QAAQ,EAAI,kBAAkB;QAChD,eAAe,EAAE,QAAQ,EAAK,MAAM;QACpC,oBAAoB,EAAE,CAAC;QACvB,kBAAkB,EAAE,QAAQ,CAAE,MAAM;KACrC;IACD,WAAW,EAAE;QACX,WAAW,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI,EAAI,YAAY;QAC1C,gBAAgB,EAAE,EAAE,GAAG,EAAE,GAAG,IAAI,EAAE,wBAAwB;QAC1D,eAAe,EAAE,EAAE,GAAG,IAAI,EAAI,mBAAmB;QACjD,oBAAoB,EAAE,CAAC;QACvB,kBAAkB,EAAE,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,eAAe;KACnD;IACD,UAAU,EAAE;QACV,WAAW,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI,EAAI,WAAW;QACzC,gBAAgB,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI,EAAG,uBAAuB;QACzD,eAAe,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI,EAAI,kBAAkB;QACpD,oBAAoB,EAAE,CAAC;QACvB,kBAAkB,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,gBAAgB;KACxD;IACD,OAAO,EAAE;QACP,WAAW,EAAE,EAAE,GAAG,IAAI,EAAQ,aAAa;QAC3C,gBAAgB,EAAE,EAAE,GAAG,IAAI,EAAG,wBAAwB;QACtD,eAAe,EAAE,EAAE,GAAG,EAAE,GAAG,IAAI,EAAG,eAAe;QACjD,oBAAoB,EAAE,CAAC;QACvB,kBAAkB,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,eAAe;KAC5D;CACF,CAAC;AA2aF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuDG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG,MAAM,CAAC,MAAM,CAAC;IACtD,uFAAuF;IACvF,mFAAmF;IACnF,YAAY,EAAE,KAAM;IACpB,kFAAkF;IAClF,kFAAkF;IAClF,mBAAmB;IACnB,WAAW,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,UAAU,EAAE,KAAM,EAAE,UAAU,EAAE,KAAM,EAAE,CAAC;CACjC,CAAC,CAAC;AAmBzC;;;GAGG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,EAAE,GAAG,IAAI,CAAC;AAYnD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,OAAO,EACL,gBAAgB,EAChB,uBAAuB,EACvB,2BAA2B,EAC3B,sBAAsB,EACtB,2BAA2B,EAC3B,qBAAqB,EACrB,wBAAwB,EACxB,sBAAsB,EACtB,oBAAoB,EACpB,mBAAmB,EACpB,MAAM,+BAA+B,CAAC;AAEvC;;;;;GAKG;AACH,OAAO,EAAE,2BAA2B,EAAE,MAAM,kBAAkB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@serfab/cadre-core",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.7.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Core library for Sereus cadre nodes - manages control networks and strand participation",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -36,6 +36,10 @@
|
|
|
36
36
|
"types": "./dist/enrolled-machine-store-file.d.ts",
|
|
37
37
|
"import": "./dist/enrolled-machine-store-file.js"
|
|
38
38
|
},
|
|
39
|
+
"./strand-peer-book-file": {
|
|
40
|
+
"types": "./dist/strand-peer-book-file.d.ts",
|
|
41
|
+
"import": "./dist/strand-peer-book-file.js"
|
|
42
|
+
},
|
|
39
43
|
"./push-node": {
|
|
40
44
|
"types": "./dist/push-node.d.ts",
|
|
41
45
|
"import": "./dist/push-node.js"
|
|
@@ -73,7 +77,7 @@
|
|
|
73
77
|
"@libp2p/tcp": "^11.0.10",
|
|
74
78
|
"@libp2p/webrtc": "6.0.14",
|
|
75
79
|
"@libp2p/websockets": "^10.1.3",
|
|
76
|
-
"@optimystic/db-p2p-storage-fs": "^1.
|
|
80
|
+
"@optimystic/db-p2p-storage-fs": "^1.7.0",
|
|
77
81
|
"@types/debug": "^4.1.12",
|
|
78
82
|
"@types/node": "^25.0.10",
|
|
79
83
|
"@vitest/coverage-v8": "^4.0.17",
|
|
@@ -88,12 +92,12 @@
|
|
|
88
92
|
"@libp2p/interface": "^3.1.0",
|
|
89
93
|
"@libp2p/peer-id": "^6.0.4",
|
|
90
94
|
"@multiformats/multiaddr": "^12.5.1",
|
|
91
|
-
"@optimystic/db-core": "^1.
|
|
92
|
-
"@optimystic/db-p2p": "^1.
|
|
93
|
-
"@optimystic/quereus-plugin-crypto": "^1.
|
|
94
|
-
"@optimystic/quereus-plugin-optimystic": "^1.
|
|
95
|
+
"@optimystic/db-core": "^1.7.0",
|
|
96
|
+
"@optimystic/db-p2p": "^1.7.0",
|
|
97
|
+
"@optimystic/quereus-plugin-crypto": "^1.7.0",
|
|
98
|
+
"@optimystic/quereus-plugin-optimystic": "^1.7.0",
|
|
95
99
|
"@quereus/quereus": "^4.20.0",
|
|
96
|
-
"@serfab/quereus-plugin-sereus": "^1.
|
|
100
|
+
"@serfab/quereus-plugin-sereus": "^1.7.0",
|
|
97
101
|
"debug": "^4.4.3",
|
|
98
102
|
"libp2p": "^3.1.3",
|
|
99
103
|
"uint8arrays": "^5.1.0"
|