@actuallab/rpc 12.3.50 → 12.3.64

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 CHANGED
@@ -2310,6 +2310,14 @@ var RpcPeer = class {
2310
2310
  * entered only after the handshake has succeeded. */
2311
2311
  connectionStateChanged = new import_core7.EventHandlerSet();
2312
2312
  _connection;
2313
+ /** Mirror of `_connectionState === Connected` — true only after the
2314
+ * handshake round-trip completes. Kept as its own field (rather than
2315
+ * derived from `_connection`) so outbound calls can be gated on
2316
+ * handshake completion, not merely WS-open: previously the run loop
2317
+ * nulled `_connection` during the handshake window to suppress calls,
2318
+ * which made `close()` a silent no-op and left a zombie peer when the
2319
+ * hub removed it mid-handshake. */
2320
+ _isConnected = false;
2313
2321
  _connectionState = 0 /* Disconnected */;
2314
2322
  _pendingSends = [];
2315
2323
  _keepAliveTimer;
@@ -2332,15 +2340,20 @@ var RpcPeer = class {
2332
2340
  return this._connectionState;
2333
2341
  }
2334
2342
  get isConnected() {
2335
- return this._connection?.isOpen ?? false;
2343
+ return this._isConnected;
2336
2344
  }
2337
2345
  _setConnectionState(value) {
2338
2346
  if (this._connectionState === value) return;
2347
+ const previousState = this._connectionState;
2339
2348
  this._connectionState = value;
2340
- if (value === 2 /* Connected */)
2349
+ if (value === 2 /* Connected */) {
2350
+ this._isConnected = true;
2341
2351
  this._armKeepAliveWatchdog();
2342
- else if (value === 0 /* Disconnected */)
2352
+ } else if (value === 0 /* Disconnected */) {
2353
+ if (previousState === 2 /* Connected */)
2354
+ this._isConnected = false;
2343
2355
  this._disarmKeepAliveWatchdog();
2356
+ }
2344
2357
  this.connectionStateChanged.trigger(value);
2345
2358
  }
2346
2359
  /** Resolves on the next transition into `Connected` — or immediately if
@@ -2362,6 +2375,7 @@ var RpcPeer = class {
2362
2375
  conn.messageReceived.add((raw) => this._handleMessage(raw));
2363
2376
  conn.closed.add((ev) => {
2364
2377
  this._connection = void 0;
2378
+ this._isConnected = false;
2365
2379
  if (ev.reason)
2366
2380
  infoLog?.log(`'${this.ref}': Disconnected: ${ev.reason} (code=${ev.code})`);
2367
2381
  else
@@ -2398,7 +2412,7 @@ var RpcPeer = class {
2398
2412
  this._connection?.encoder,
2399
2413
  this.hub.registry
2400
2414
  );
2401
- if (this._connection !== void 0) {
2415
+ if (this._isConnected) {
2402
2416
  this.outboundCalls.register(outboundCall);
2403
2417
  this._sendWireData(outboundCall.serializedWireData);
2404
2418
  } else {
@@ -2431,16 +2445,24 @@ var RpcPeer = class {
2431
2445
  return outboundCall;
2432
2446
  }
2433
2447
  callNoWait(method, args) {
2434
- if (this._connection === void 0) return;
2448
+ if (!this._isConnected) return;
2449
+ const conn = this._connection;
2435
2450
  const envelope = { Method: method, RelatedId: 0 };
2436
2451
  const wireData = this.serializationFormat.serializeMessage(
2437
2452
  envelope,
2438
2453
  args,
2439
- this._connection.encoder,
2454
+ conn.encoder,
2440
2455
  this.hub.registry
2441
2456
  );
2442
2457
  this._sendWireData(wireData);
2443
2458
  }
2459
+ /** Close the current WS connection without disposing the peer. The
2460
+ * `conn.closed` handler flips state to `Disconnected`; for
2461
+ * `RpcClientPeer` the run loop then iterates and reopens. The peer
2462
+ * stays in the hub and all client proxies bound to it remain valid. */
2463
+ disconnect() {
2464
+ this._connection?.close();
2465
+ }
2444
2466
  close() {
2445
2467
  infoLog?.log(`'${this.ref}': Stopping`);
2446
2468
  this.remoteObjects.disconnectAll();
@@ -2693,6 +2715,7 @@ var RpcClientPeer = class extends RpcPeer {
2693
2715
  * to simulate a same-peer reconnect in tests. */
2694
2716
  connectWith(conn, isPeerChanged = true) {
2695
2717
  this.setupConnection(conn);
2718
+ this._isConnected = true;
2696
2719
  void this._reconnect(isPeerChanged);
2697
2720
  }
2698
2721
  /** Kick off the reconnect loop. Idempotent — subsequent calls are
@@ -2753,7 +2776,6 @@ var RpcClientPeer = class extends RpcPeer {
2753
2776
  });
2754
2777
  this._pendingHandshake = new import_core7.PromiseSource();
2755
2778
  this.setupConnection(conn);
2756
- this._connection = void 0;
2757
2779
  await Promise.race([conn.whenConnected, closedRejection]);
2758
2780
  try {
2759
2781
  this.hub.systemCallSender.handshake(
@@ -2806,7 +2828,6 @@ var RpcClientPeer = class extends RpcPeer {
2806
2828
  this._lastRemoteHubId = remoteHubId;
2807
2829
  }
2808
2830
  infoLog?.log(`'${this.ref}': Handshake succeeded, peerChanged=${isPeerChanged}`);
2809
- this._connection = conn;
2810
2831
  this._setConnectionState(2 /* Connected */);
2811
2832
  this._tryIndex = 0;
2812
2833
  await this._reconnect(isPeerChanged, closedController.signal);