hypha-rpc 0.21.27 → 0.21.28

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.
@@ -86,7 +86,7 @@
86
86
  <div class='footer quiet pad2 space-top1 center small'>
87
87
  Code coverage generated by
88
88
  <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
89
- at 2026-02-26T22:49:57.528Z
89
+ at 2026-02-27T13:29:51.171Z
90
90
  </div>
91
91
  <script src="prettify.js"></script>
92
92
  <script>
@@ -3281,25 +3281,25 @@ async function _connectToServerHTTP(config) {
3281
3281
  // Auto-refresh workspace manager proxy after reconnection.
3282
3282
  // See websocket-client.js for detailed explanation.
3283
3283
  let isInitialRefresh = true;
3284
- rpc.on("manager_refreshed", async ({ manager: internalManager }) => {
3284
+ rpc.on("manager_refreshed", async () => {
3285
3285
  if (isInitialRefresh) {
3286
3286
  isInitialRefresh = false;
3287
3287
  return;
3288
3288
  }
3289
3289
  try {
3290
- const freshWm = internalManager;
3291
- for (const key of Object.keys(freshWm)) {
3292
- if (typeof freshWm[key] === "function") {
3293
- wm[key] = freshWm[key];
3290
+ const newTarget = `*/${rpc._connection.manager_id}`;
3291
+ for (const key of Object.keys(wm)) {
3292
+ if (typeof wm[key] === "function" && wm[key].__rpc_object__) {
3293
+ wm[key].__rpc_object__._rtarget = newTarget;
3294
3294
  }
3295
3295
  }
3296
3296
  console.info(
3297
- "Workspace manager proxy refreshed after reconnection (new manager_id:",
3297
+ "Workspace manager proxy retargeted after reconnection (new manager_id:",
3298
3298
  rpc._connection?.manager_id + ")",
3299
3299
  );
3300
3300
  } catch (err) {
3301
3301
  console.warn(
3302
- "Failed to refresh workspace manager after reconnection:",
3302
+ "Failed to retarget workspace manager after reconnection:",
3303
3303
  err,
3304
3304
  );
3305
3305
  }
@@ -5719,6 +5719,10 @@ class RPC extends _utils_index_js__WEBPACK_IMPORTED_MODULE_0__.MessageEmitter {
5719
5719
  function remote_method() {
5720
5720
  return new Promise(async (resolve, reject) => {
5721
5721
  try {
5722
+ // Read target_id from encoded_method at call time (not captured
5723
+ // at generation time) so that _rtarget can be updated after
5724
+ // reconnection without regenerating the method closures.
5725
+ const target_id = encoded_method._rtarget;
5722
5726
  let local_session_id = (0,_utils_index_js__WEBPACK_IMPORTED_MODULE_0__.randId)();
5723
5727
  if (local_parent) {
5724
5728
  // Store the children session under the parent
@@ -10966,50 +10970,34 @@ async function connectToServer(config) {
10966
10970
  wm.rpc = rpc;
10967
10971
 
10968
10972
  // Auto-refresh workspace manager proxy after reconnection.
10969
- // When the server restarts, it assigns a new manager_id. The wm proxy
10970
- // returned to the caller has methods bound to the old manager_id.
10971
- //
10972
- // The RPC layer fires "manager_refreshed" IMMEDIATELY after getting the
10973
- // fresh manager service before service re-registration. This minimizes
10974
- // the window where stale methods exist (~100ms instead of ~2-3s).
10975
- //
10976
- // Combined with the RPC layer's immediate rejection of pending calls to
10977
- // the old manager_id, recovery is near-instant.
10973
+ // When the server restarts, it assigns a new manager_id. The remote
10974
+ // methods on wm have their target baked into __rpc_object__._rtarget.
10975
+ // Since remote_method() reads _rtarget at call time (not generation
10976
+ // time), we just update _rtarget on every existing method — no need
10977
+ // to regenerate methods or copy from a fresh proxy. This preserves
10978
+ // locally-overridden methods (registerService, unregisterService, etc.)
10979
+ // that would otherwise be lost by wholesale function copying.
10978
10980
  let isInitialRefresh = true;
10979
- rpc.on("manager_refreshed", async ({ manager: internalManager }) => {
10981
+ rpc.on("manager_refreshed", async () => {
10980
10982
  if (isInitialRefresh) {
10981
10983
  isInitialRefresh = false;
10982
10984
  return; // Skip the first event (initial connection, wm is already fresh)
10983
10985
  }
10984
10986
  try {
10985
- let freshWm;
10986
- if (config.kwargs_expansion) {
10987
- // kwargs_expansion changes the method signatures, so we need to
10988
- // fetch a new manager with matching config
10989
- freshWm = await rpc.get_manager_service({
10990
- timeout: config.method_timeout || 30,
10991
- case_conversion: "camel",
10992
- kwargs_expansion: config.kwargs_expansion,
10993
- });
10994
- } else {
10995
- // The internal manager already uses case_conversion: "camel",
10996
- // so we can copy directly without an extra RPC call
10997
- freshWm = internalManager;
10998
- }
10999
- // Copy all function properties from fresh wm onto existing wm object.
11000
- // This preserves the caller's reference while updating method targets.
11001
- for (const key of Object.keys(freshWm)) {
11002
- if (typeof freshWm[key] === "function") {
11003
- wm[key] = freshWm[key];
10987
+ const newTarget = `*/${rpc._connection.manager_id}`;
10988
+ // Retarget all remote methods on the wm proxy to the new manager
10989
+ for (const key of Object.keys(wm)) {
10990
+ if (typeof wm[key] === "function" && wm[key].__rpc_object__) {
10991
+ wm[key].__rpc_object__._rtarget = newTarget;
11004
10992
  }
11005
10993
  }
11006
10994
  console.info(
11007
- "Workspace manager proxy refreshed after reconnection (new manager_id:",
10995
+ "Workspace manager proxy retargeted after reconnection (new manager_id:",
11008
10996
  rpc._connection?.manager_id + ")",
11009
10997
  );
11010
10998
  } catch (err) {
11011
10999
  console.warn(
11012
- "Failed to refresh workspace manager after reconnection:",
11000
+ "Failed to retarget workspace manager after reconnection:",
11013
11001
  err,
11014
11002
  );
11015
11003
  }