@actuallab/rpc 12.5.2 → 13.0.12
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/index.cjs +72 -27
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +60 -6
- package/dist/index.d.ts +60 -6
- package/dist/index.js +72 -27
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -33,7 +33,6 @@ __export(index_exports, {
|
|
|
33
33
|
ARG_DELIMITER: () => ARG_DELIMITER,
|
|
34
34
|
ENVELOPE_DELIMITER: () => ENVELOPE_DELIMITER,
|
|
35
35
|
FRAME_DELIMITER: () => FRAME_DELIMITER,
|
|
36
|
-
HANDSHAKE_TIMEOUT_MS: () => HANDSHAKE_TIMEOUT_MS,
|
|
37
36
|
IncreasingSeqCompressor: () => IncreasingSeqCompressor,
|
|
38
37
|
RPC_CLOSE_CODE_UNSUPPORTED_FORMAT: () => RPC_CLOSE_CODE_UNSUPPORTED_FORMAT,
|
|
39
38
|
RpcCallStage: () => RpcCallStage,
|
|
@@ -46,6 +45,7 @@ __export(index_exports, {
|
|
|
46
45
|
RpcInboundCall: () => RpcInboundCall,
|
|
47
46
|
RpcInboundCallTracker: () => RpcInboundCallTracker,
|
|
48
47
|
RpcJsonSerializationFormat: () => RpcJsonSerializationFormat,
|
|
48
|
+
RpcLimits: () => RpcLimits,
|
|
49
49
|
RpcMessageChannelConnection: () => RpcMessageChannelConnection,
|
|
50
50
|
RpcMessagePackCompactSerializationFormat: () => RpcMessagePackCompactSerializationFormat,
|
|
51
51
|
RpcMessagePackSerializationFormat: () => RpcMessagePackSerializationFormat,
|
|
@@ -2290,9 +2290,6 @@ function yieldToEventLoop() {
|
|
|
2290
2290
|
return new Promise((resolve) => setTimeout(resolve, 0));
|
|
2291
2291
|
}
|
|
2292
2292
|
var RPC_CLOSE_CODE_UNSUPPORTED_FORMAT = 4001;
|
|
2293
|
-
var HANDSHAKE_TIMEOUT_MS = 1e4;
|
|
2294
|
-
var KEEP_ALIVE_PERIOD_MS = 15e3;
|
|
2295
|
-
var KEEP_ALIVE_TIMEOUT_MS = 55e3;
|
|
2296
2293
|
var { debugLog: debugLog2, infoLog, warnLog: warnLog6, errorLog: errorLog2 } = getLogs("RpcPeer");
|
|
2297
2294
|
var defaultConnectionUrlResolver = (peer) => {
|
|
2298
2295
|
const formatKey = peer.serializationFormat.key;
|
|
@@ -2354,13 +2351,17 @@ var RpcPeer = class {
|
|
|
2354
2351
|
/** Wall-clock time of the last inbound `$sys.KeepAlive`, or 0 if none yet
|
|
2355
2352
|
* for the current connection. Useful for diagnostics. */
|
|
2356
2353
|
_lastKeepAliveAt = 0;
|
|
2357
|
-
/** Outbound keep-alive send period
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2354
|
+
/** Outbound keep-alive send period. Initialized from `hub.limits` at
|
|
2355
|
+
* construction; set directly to override on a single peer. */
|
|
2356
|
+
keepAlivePeriodMs;
|
|
2357
|
+
/** Inbound keep-alive silence tolerance. Initialized from `hub.limits`
|
|
2358
|
+
* at construction; set directly to override on a single peer. */
|
|
2359
|
+
keepAliveTimeoutMs;
|
|
2361
2360
|
constructor(hub, ref) {
|
|
2362
2361
|
this.hub = hub;
|
|
2363
2362
|
this.ref = ref;
|
|
2363
|
+
this.keepAlivePeriodMs = hub.limits.keepAlivePeriodMs;
|
|
2364
|
+
this.keepAliveTimeoutMs = hub.limits.keepAliveTimeoutMs;
|
|
2364
2365
|
}
|
|
2365
2366
|
get connection() {
|
|
2366
2367
|
return this._connection;
|
|
@@ -2679,9 +2680,14 @@ var RpcClientPeer = class extends RpcPeer {
|
|
|
2679
2680
|
* `Cookie` headers to the WS upgrade, which the browser `WebSocket`
|
|
2680
2681
|
* constructor can't do). Must be set before `start()`. */
|
|
2681
2682
|
webSocketFactory;
|
|
2683
|
+
/** Max time to wait for the WebSocket to reach OPEN before aborting the
|
|
2684
|
+
* connection attempt. Initialized from `hub.limits` at construction;
|
|
2685
|
+
* set directly to override on a single peer. */
|
|
2686
|
+
connectTimeoutMs;
|
|
2682
2687
|
/** Max time to wait for the server's handshake response before aborting
|
|
2683
|
-
* the connection attempt.
|
|
2684
|
-
|
|
2688
|
+
* the connection attempt. Initialized from `hub.limits` at construction;
|
|
2689
|
+
* set directly to override on a single peer. */
|
|
2690
|
+
handshakeTimeoutMs;
|
|
2685
2691
|
peerChanged = new import_core7.EventHandlerSet();
|
|
2686
2692
|
/** Fired when the server rejects the connection due to an unsupported serialization format (close code 4010). */
|
|
2687
2693
|
unsupportedFormat = new import_core7.EventHandlerSet();
|
|
@@ -2712,6 +2718,8 @@ var RpcClientPeer = class extends RpcPeer {
|
|
|
2712
2718
|
*/
|
|
2713
2719
|
constructor(hub, url, mustStart = true) {
|
|
2714
2720
|
super(hub, url);
|
|
2721
|
+
this.connectTimeoutMs = hub.limits.connectTimeoutMs;
|
|
2722
|
+
this.handshakeTimeoutMs = hub.limits.handshakeTimeoutMs;
|
|
2715
2723
|
this.clientId = guidToBase64Url(this.id);
|
|
2716
2724
|
const resolver = RpcSerializationFormatResolver.Default;
|
|
2717
2725
|
this.serializationFormat = resolver.get(parseFormatFromUrl(url) ?? resolver.defaultFormatKey);
|
|
@@ -2788,7 +2796,20 @@ var RpcClientPeer = class extends RpcPeer {
|
|
|
2788
2796
|
});
|
|
2789
2797
|
this._pendingHandshake = new import_core7.PromiseSource();
|
|
2790
2798
|
this.setupConnection(conn);
|
|
2791
|
-
|
|
2799
|
+
const connectTimeoutMs = this.connectTimeoutMs;
|
|
2800
|
+
try {
|
|
2801
|
+
await (0, import_core7.withTimeout)(
|
|
2802
|
+
Promise.race([conn.whenConnected, closedRejection]),
|
|
2803
|
+
connectTimeoutMs,
|
|
2804
|
+
"Connect timeout"
|
|
2805
|
+
);
|
|
2806
|
+
} catch (e) {
|
|
2807
|
+
if (e instanceof import_core7.TimeoutError) {
|
|
2808
|
+
warnLog6?.log(`'${this.ref}': Connect timed out after ${connectTimeoutMs}ms`);
|
|
2809
|
+
conn.close();
|
|
2810
|
+
}
|
|
2811
|
+
throw e;
|
|
2812
|
+
}
|
|
2792
2813
|
this._setConnectionState(2 /* Handshaking */);
|
|
2793
2814
|
try {
|
|
2794
2815
|
this.hub.systemCallSender.handshake(
|
|
@@ -2803,29 +2824,20 @@ var RpcClientPeer = class extends RpcPeer {
|
|
|
2803
2824
|
throw e;
|
|
2804
2825
|
}
|
|
2805
2826
|
const handshakeTimeoutMs = this.handshakeTimeoutMs;
|
|
2806
|
-
let handshakeTimer;
|
|
2807
|
-
const handshakeTimeout = new Promise((_, reject) => {
|
|
2808
|
-
handshakeTimer = setTimeout(() => {
|
|
2809
|
-
reject(new Error("Handshake timeout"));
|
|
2810
|
-
}, handshakeTimeoutMs);
|
|
2811
|
-
});
|
|
2812
|
-
handshakeTimeout.catch(() => {
|
|
2813
|
-
});
|
|
2814
2827
|
let remoteHandshake;
|
|
2815
2828
|
try {
|
|
2816
|
-
remoteHandshake = await
|
|
2817
|
-
this._pendingHandshake.promise,
|
|
2818
|
-
|
|
2819
|
-
|
|
2820
|
-
|
|
2829
|
+
remoteHandshake = await (0, import_core7.withTimeout)(
|
|
2830
|
+
Promise.race([this._pendingHandshake.promise, closedRejection]),
|
|
2831
|
+
handshakeTimeoutMs,
|
|
2832
|
+
"Handshake timeout"
|
|
2833
|
+
);
|
|
2821
2834
|
} catch (e) {
|
|
2822
|
-
if (e instanceof
|
|
2835
|
+
if (e instanceof import_core7.TimeoutError) {
|
|
2823
2836
|
warnLog6?.log(`'${this.ref}': Handshake timed out after ${handshakeTimeoutMs}ms`);
|
|
2824
2837
|
conn.close();
|
|
2825
2838
|
}
|
|
2826
2839
|
throw e;
|
|
2827
2840
|
} finally {
|
|
2828
|
-
if (handshakeTimer !== void 0) clearTimeout(handshakeTimer);
|
|
2829
2841
|
this._pendingHandshake = void 0;
|
|
2830
2842
|
}
|
|
2831
2843
|
this._remoteHandshakeIndex = remoteHandshake.Index ?? 0;
|
|
@@ -3057,6 +3069,32 @@ function _toBytes2(value) {
|
|
|
3057
3069
|
return null;
|
|
3058
3070
|
}
|
|
3059
3071
|
|
|
3072
|
+
// src/rpc-limits.ts
|
|
3073
|
+
var RpcLimits = class _RpcLimits {
|
|
3074
|
+
/** Process-wide default. Hubs read from this when they're constructed
|
|
3075
|
+
* unless caller assigns a custom instance to `hub.limits`. */
|
|
3076
|
+
static Default = new _RpcLimits();
|
|
3077
|
+
/** Max time to wait for the WebSocket to enter the OPEN state. On a
|
|
3078
|
+
* hung connect (mobile after network change, half-open after sleep)
|
|
3079
|
+
* the browser can take ~2 min to emit `onerror`/`onclose`; without
|
|
3080
|
+
* this cap the reconnect loop blocks for that whole window. */
|
|
3081
|
+
connectTimeoutMs = 1e4;
|
|
3082
|
+
/** Max time to wait for the server's handshake response after WS opens. */
|
|
3083
|
+
handshakeTimeoutMs = 1e4;
|
|
3084
|
+
/** Outbound `$sys.KeepAlive` send period. */
|
|
3085
|
+
keepAlivePeriodMs = 1e4;
|
|
3086
|
+
/** Reaper threshold — connection is force-closed (and the reconnect
|
|
3087
|
+
* loop takes over) if no inbound `$sys.KeepAlive` has been seen for
|
|
3088
|
+
* this long. Sized to tolerate a complete server stall plus most of
|
|
3089
|
+
* one keepalive cycle: the worst-case age of `_lastKeepAliveAt` is
|
|
3090
|
+
* `keepAlivePeriodMs + stall_duration`, so with these defaults the
|
|
3091
|
+
* tolerated stall is ~15 s. */
|
|
3092
|
+
keepAliveTimeoutMs = 25e3;
|
|
3093
|
+
constructor(overrides) {
|
|
3094
|
+
if (overrides) Object.assign(this, overrides);
|
|
3095
|
+
}
|
|
3096
|
+
};
|
|
3097
|
+
|
|
3060
3098
|
// src/rpc-client-peer-reconnect-delayer.ts
|
|
3061
3099
|
var import_core8 = require("@actuallab/core");
|
|
3062
3100
|
var RpcClientPeerReconnectDelayer = class extends import_core8.RetryDelayer {
|
|
@@ -3671,6 +3709,13 @@ var RpcHub = class {
|
|
|
3671
3709
|
/** Shared reconnect delayer used by every client peer in this hub. Swap in
|
|
3672
3710
|
* a custom subclass (e.g. app-level signal-gated) before peers start. */
|
|
3673
3711
|
reconnectDelayer = new RpcClientPeerReconnectDelayer();
|
|
3712
|
+
/** Connection-lifecycle timing limits. Peers constructed against this hub
|
|
3713
|
+
* read their initial `*Ms` field values from this instance; later
|
|
3714
|
+
* mutations affect only peers built afterward (existing peers can be
|
|
3715
|
+
* retuned by setting their `*Ms` fields directly). Defaults to the
|
|
3716
|
+
* process-wide {@link RpcLimits.Default} so a single global override
|
|
3717
|
+
* propagates to every hub that hasn't replaced this. */
|
|
3718
|
+
limits = RpcLimits.Default;
|
|
3674
3719
|
/** URL used by {@link defaultPeer} to resolve / create the default client
|
|
3675
3720
|
* peer. Must be set before the first {@link defaultPeer} access. */
|
|
3676
3721
|
defaultPeerUrl;
|
|
@@ -4119,7 +4164,6 @@ var RpcPeerStateMonitor = class {
|
|
|
4119
4164
|
ARG_DELIMITER,
|
|
4120
4165
|
ENVELOPE_DELIMITER,
|
|
4121
4166
|
FRAME_DELIMITER,
|
|
4122
|
-
HANDSHAKE_TIMEOUT_MS,
|
|
4123
4167
|
IncreasingSeqCompressor,
|
|
4124
4168
|
RPC_CLOSE_CODE_UNSUPPORTED_FORMAT,
|
|
4125
4169
|
RpcCallStage,
|
|
@@ -4132,6 +4176,7 @@ var RpcPeerStateMonitor = class {
|
|
|
4132
4176
|
RpcInboundCall,
|
|
4133
4177
|
RpcInboundCallTracker,
|
|
4134
4178
|
RpcJsonSerializationFormat,
|
|
4179
|
+
RpcLimits,
|
|
4135
4180
|
RpcMessageChannelConnection,
|
|
4136
4181
|
RpcMessagePackCompactSerializationFormat,
|
|
4137
4182
|
RpcMessagePackSerializationFormat,
|