wire-mesh-core 4.1.4 → 4.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.
- package/README.md +1 -0
- package/dist/adapters/tls-transport.cjs +2 -0
- package/dist/adapters/tls-transport.mjs +2 -0
- package/dist/domain/async-queue.cjs +48 -12
- package/dist/domain/async-queue.d.cts +1 -1
- package/dist/domain/async-queue.d.mts +1 -1
- package/dist/domain/async-queue.mjs +48 -12
- package/dist/domain/bulk.cjs +50 -10
- package/dist/domain/bulk.d.cts +4 -0
- package/dist/domain/bulk.d.mts +4 -0
- package/dist/domain/bulk.mjs +50 -11
- package/dist/domain/capability-request.cjs +2 -5
- package/dist/domain/capability-request.mjs +1 -4
- package/dist/domain/consume-incoming.cjs +96 -0
- package/dist/domain/consume-incoming.d.cts +27 -0
- package/dist/domain/consume-incoming.d.mts +27 -0
- package/dist/domain/consume-incoming.mjs +93 -0
- package/dist/domain/direct-manage-request.cjs +25 -12
- package/dist/domain/direct-manage-request.mjs +25 -12
- package/dist/domain/fault-report.cjs +136 -0
- package/dist/domain/fault-report.d.cts +25 -0
- package/dist/domain/fault-report.d.mts +25 -0
- package/dist/domain/fault-report.mjs +129 -0
- package/dist/domain/gossip-expansion.cjs +1 -1
- package/dist/domain/gossip-expansion.mjs +1 -1
- package/dist/domain/mesh-session.cjs +9 -13
- package/dist/domain/mesh-session.mjs +9 -13
- package/dist/domain/ping-round-trips.cjs +21 -8
- package/dist/domain/ping-round-trips.mjs +21 -8
- package/dist/timers-DTJNuBa8.cjs +12 -0
- package/dist/timers-Q1_kDTyY.mjs +7 -0
- package/package.json +9 -1
- package/wasm-dist/wire_mesh_threshold_wasm_bg.wasm +0 -0
|
@@ -6,6 +6,7 @@ import { a as OWN_VERSION, i as CORE_VERSION_GOSSIP_KEY, n as TOPOLOGY_PEERS_GOS
|
|
|
6
6
|
import { signPeerAdvert, verifyPeerAdvert } from "./peer-advert.mjs";
|
|
7
7
|
import { createAsyncQueue } from "./async-queue.mjs";
|
|
8
8
|
import { ChannelExhaustedError } from "./channel-exhausted-error.mjs";
|
|
9
|
+
import { deliverContained } from "./fault-report.mjs";
|
|
9
10
|
import { localHandshake, negotiate } from "./handshake.mjs";
|
|
10
11
|
import { isDataFrame } from "./hub-mailbox.mjs";
|
|
11
12
|
import { createPingRoundTrips } from "./ping-round-trips.mjs";
|
|
@@ -279,17 +280,9 @@ async function establishChannelFrom(identity, { pending, remote, peer, firstSend
|
|
|
279
280
|
function createRelayChannels(identity, sendHello, options = {}) {
|
|
280
281
|
if (options.firstSendCounter !== void 0) assertFirstSendCounter(options.firstSendCounter);
|
|
281
282
|
const channels = /* @__PURE__ */ new Map();
|
|
282
|
-
/** Tells the owner of a failure that is local to this side. The callback is the owner's code: its own failure, thrown or as a rejected promise it returns, must not end the session or go unobserved, so it
|
|
283
|
+
/** Tells the owner of a failure that is local to this side. The callback is the owner's code: its own failure, thrown or as a rejected promise it returns, must not end the session or go unobserved, so it goes through the shared containment in fault-report.ts. */
|
|
283
284
|
function reportFault(error) {
|
|
284
|
-
|
|
285
|
-
console.error("the local fault callback failed", faultError);
|
|
286
|
-
};
|
|
287
|
-
try {
|
|
288
|
-
const result = options.onFault?.(error);
|
|
289
|
-
if (typeof result === "object" && result !== null && "then" in result && typeof result.then === "function") Promise.resolve(result).catch(report);
|
|
290
|
-
} catch (faultError) {
|
|
291
|
-
report(faultError);
|
|
292
|
-
}
|
|
285
|
+
deliverContained(async () => options.onFault?.(error), 0);
|
|
293
286
|
}
|
|
294
287
|
/** Abandons a handshake that failed: the entry goes if it is still the one held for the peer, and whoever awaits it is told. */
|
|
295
288
|
function abandon(entry, error) {
|
|
@@ -502,7 +495,7 @@ function createSessionCore(identity, clock, reconnect, dial, onPeerAdvert, addre
|
|
|
502
495
|
}
|
|
503
496
|
/** The "not connected" guard every send* method on the public session needs, deduplicated into one place rather than repeated inline at each call site: throws unless there is a live connection AND the session's own state machine agrees it is "connected" (transmit's own connection===null check alone doesn't cover the latter). Returns the connection itself, narrowed non-null, for a caller that needs to send directly on it (sendPing/sendPingMeasureRtt); a caller that only needs the throwing side effect (sendManageRequest and friends, which go through transmit instead) calls this and discards the result. */
|
|
504
497
|
function requireConnectedLink() {
|
|
505
|
-
if (connection === null || state.status !== "connected") throw new Error("not connected");
|
|
498
|
+
if (feedCancelled || connection === null || state.status !== "connected") throw new Error("not connected");
|
|
506
499
|
return connection;
|
|
507
500
|
}
|
|
508
501
|
/** Sends a frame. Through a relay it is sealed for toDevice on their secure channel first (spec/secure-channel.cddl) and only then wrapped as relay-data, so the hub carries ciphertext. This is the single choke point every outbound manage-request and manage-response passes through, so a consumer of sendManageRequest or respond never needs its own relay logic. */
|
|
@@ -833,7 +826,10 @@ function createSessionCore(identity, clock, reconnect, dial, onPeerAdvert, addre
|
|
|
833
826
|
},
|
|
834
827
|
async sendManageRequest(command, scope, targetDevice, token, timeoutMs) {
|
|
835
828
|
requireConnectedLink();
|
|
836
|
-
if (targetDevice !== void 0)
|
|
829
|
+
if (targetDevice !== void 0) {
|
|
830
|
+
await ensureRelayPairing(targetDevice);
|
|
831
|
+
requireConnectedLink();
|
|
832
|
+
}
|
|
837
833
|
const frame = buildManageRequest(command, scope, token);
|
|
838
834
|
const requestId = frame["request-id"];
|
|
839
835
|
const outcome = new Promise((resolve, reject) => {
|
|
@@ -843,6 +839,7 @@ function createSessionCore(identity, clock, reconnect, dial, onPeerAdvert, addre
|
|
|
843
839
|
expectedFrom: targetDevice
|
|
844
840
|
});
|
|
845
841
|
});
|
|
842
|
+
outcome.catch(() => void 0);
|
|
846
843
|
recordFrame({
|
|
847
844
|
direction: "sent",
|
|
848
845
|
frame
|
|
@@ -852,7 +849,6 @@ function createSessionCore(identity, clock, reconnect, dial, onPeerAdvert, addre
|
|
|
852
849
|
await transmit(frame, targetDevice !== void 0, targetDevice);
|
|
853
850
|
} catch (error) {
|
|
854
851
|
pendingManageRequests.delete(requestId);
|
|
855
|
-
outcome.catch(() => void 0);
|
|
856
852
|
throw error;
|
|
857
853
|
}
|
|
858
854
|
emit();
|
|
@@ -9,8 +9,8 @@ var PingTimeoutError = class extends Error {
|
|
|
9
9
|
};
|
|
10
10
|
function createPingRoundTrips() {
|
|
11
11
|
const pending = [];
|
|
12
|
-
function cancel(
|
|
13
|
-
const index = pending.
|
|
12
|
+
function cancel(registration) {
|
|
13
|
+
const index = pending.indexOf(registration);
|
|
14
14
|
if (index === -1) return false;
|
|
15
15
|
pending.splice(index, 1);
|
|
16
16
|
return true;
|
|
@@ -24,20 +24,33 @@ function createPingRoundTrips() {
|
|
|
24
24
|
for (const entry of pending.splice(0)) entry.reject(new Error(reason));
|
|
25
25
|
},
|
|
26
26
|
async sendAndAwait(sentAt, sendPing, timeoutMs) {
|
|
27
|
+
let registration;
|
|
27
28
|
const rtt = new Promise((resolve, reject) => {
|
|
28
|
-
|
|
29
|
+
registration = {
|
|
29
30
|
sentAt,
|
|
30
31
|
resolve,
|
|
31
32
|
reject
|
|
32
|
-
}
|
|
33
|
+
};
|
|
34
|
+
pending.push(registration);
|
|
33
35
|
});
|
|
34
|
-
|
|
36
|
+
if (registration === void 0) throw new Error("the round trip was not registered");
|
|
37
|
+
const registered = registration;
|
|
38
|
+
rtt.catch(() => void 0);
|
|
39
|
+
try {
|
|
40
|
+
await sendPing();
|
|
41
|
+
} catch (error) {
|
|
42
|
+
cancel(registered);
|
|
43
|
+
throw error;
|
|
44
|
+
}
|
|
35
45
|
if (timeoutMs === void 0) return rtt;
|
|
46
|
+
let timer;
|
|
36
47
|
return Promise.race([rtt, new Promise((_resolve, reject) => {
|
|
37
|
-
setTimeout(() => {
|
|
38
|
-
if (cancel(
|
|
48
|
+
timer = setTimeout(() => {
|
|
49
|
+
if (cancel(registered)) reject(new PingTimeoutError());
|
|
39
50
|
}, timeoutMs);
|
|
40
|
-
})])
|
|
51
|
+
})]).finally(() => {
|
|
52
|
+
clearTimeout(timer);
|
|
53
|
+
});
|
|
41
54
|
}
|
|
42
55
|
};
|
|
43
56
|
}
|
|
@@ -8,8 +8,8 @@ var PingTimeoutError = class extends Error {
|
|
|
8
8
|
};
|
|
9
9
|
function createPingRoundTrips() {
|
|
10
10
|
const pending = [];
|
|
11
|
-
function cancel(
|
|
12
|
-
const index = pending.
|
|
11
|
+
function cancel(registration) {
|
|
12
|
+
const index = pending.indexOf(registration);
|
|
13
13
|
if (index === -1) return false;
|
|
14
14
|
pending.splice(index, 1);
|
|
15
15
|
return true;
|
|
@@ -23,20 +23,33 @@ function createPingRoundTrips() {
|
|
|
23
23
|
for (const entry of pending.splice(0)) entry.reject(new Error(reason));
|
|
24
24
|
},
|
|
25
25
|
async sendAndAwait(sentAt, sendPing, timeoutMs) {
|
|
26
|
+
let registration;
|
|
26
27
|
const rtt = new Promise((resolve, reject) => {
|
|
27
|
-
|
|
28
|
+
registration = {
|
|
28
29
|
sentAt,
|
|
29
30
|
resolve,
|
|
30
31
|
reject
|
|
31
|
-
}
|
|
32
|
+
};
|
|
33
|
+
pending.push(registration);
|
|
32
34
|
});
|
|
33
|
-
|
|
35
|
+
if (registration === void 0) throw new Error("the round trip was not registered");
|
|
36
|
+
const registered = registration;
|
|
37
|
+
rtt.catch(() => void 0);
|
|
38
|
+
try {
|
|
39
|
+
await sendPing();
|
|
40
|
+
} catch (error) {
|
|
41
|
+
cancel(registered);
|
|
42
|
+
throw error;
|
|
43
|
+
}
|
|
34
44
|
if (timeoutMs === void 0) return rtt;
|
|
45
|
+
let timer;
|
|
35
46
|
return Promise.race([rtt, new Promise((_resolve, reject) => {
|
|
36
|
-
setTimeout(() => {
|
|
37
|
-
if (cancel(
|
|
47
|
+
timer = setTimeout(() => {
|
|
48
|
+
if (cancel(registered)) reject(new PingTimeoutError());
|
|
38
49
|
}, timeoutMs);
|
|
39
|
-
})])
|
|
50
|
+
})]).finally(() => {
|
|
51
|
+
clearTimeout(timer);
|
|
52
|
+
});
|
|
40
53
|
}
|
|
41
54
|
};
|
|
42
55
|
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
//#region src/domain/timers.ts
|
|
2
|
+
/** Stops a pending timer from keeping the process alive, where the runtime has that notion. Node's `setTimeout` returns an object with `unref()`; a browser's or a Worker's returns a number, which has nothing to unref and must not be called as if it did. */
|
|
3
|
+
function unrefIfSupported(handle) {
|
|
4
|
+
if (typeof handle === "object" && handle !== null && "unref" in handle && typeof handle.unref === "function") Reflect.apply(handle.unref, handle, []);
|
|
5
|
+
}
|
|
6
|
+
//#endregion
|
|
7
|
+
Object.defineProperty(exports, "unrefIfSupported", {
|
|
8
|
+
enumerable: true,
|
|
9
|
+
get: function() {
|
|
10
|
+
return unrefIfSupported;
|
|
11
|
+
}
|
|
12
|
+
});
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
//#region src/domain/timers.ts
|
|
2
|
+
/** Stops a pending timer from keeping the process alive, where the runtime has that notion. Node's `setTimeout` returns an object with `unref()`; a browser's or a Worker's returns a number, which has nothing to unref and must not be called as if it did. */
|
|
3
|
+
function unrefIfSupported(handle) {
|
|
4
|
+
if (typeof handle === "object" && handle !== null && "unref" in handle && typeof handle.unref === "function") Reflect.apply(handle.unref, handle, []);
|
|
5
|
+
}
|
|
6
|
+
//#endregion
|
|
7
|
+
export { unrefIfSupported as t };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wire-mesh-core",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.2.0",
|
|
4
4
|
"dependencies": {
|
|
5
5
|
"cbor2": "2.3.0",
|
|
6
6
|
"cddl.js": "2.0.0",
|
|
@@ -90,6 +90,10 @@
|
|
|
90
90
|
"import": "./dist/domain/channel-exhausted-error.mjs",
|
|
91
91
|
"require": "./dist/domain/channel-exhausted-error.cjs"
|
|
92
92
|
},
|
|
93
|
+
"./domain/consume-incoming": {
|
|
94
|
+
"import": "./dist/domain/consume-incoming.mjs",
|
|
95
|
+
"require": "./dist/domain/consume-incoming.cjs"
|
|
96
|
+
},
|
|
93
97
|
"./domain/coordinator-election": {
|
|
94
98
|
"import": "./dist/domain/coordinator-election.mjs",
|
|
95
99
|
"require": "./dist/domain/coordinator-election.cjs"
|
|
@@ -114,6 +118,10 @@
|
|
|
114
118
|
"import": "./dist/domain/erasure-coding.mjs",
|
|
115
119
|
"require": "./dist/domain/erasure-coding.cjs"
|
|
116
120
|
},
|
|
121
|
+
"./domain/fault-report": {
|
|
122
|
+
"import": "./dist/domain/fault-report.mjs",
|
|
123
|
+
"require": "./dist/domain/fault-report.cjs"
|
|
124
|
+
},
|
|
117
125
|
"./domain/gossip-expansion": {
|
|
118
126
|
"import": "./dist/domain/gossip-expansion.mjs",
|
|
119
127
|
"require": "./dist/domain/gossip-expansion.cjs"
|
|
Binary file
|