@hydranium/core 1.0.0-next.252 → 1.0.0-next.254

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.
Files changed (31) hide show
  1. package/lib/langium/model-service/model-service.js +2 -2
  2. package/lib/langium/model-service/model-service.js.map +1 -1
  3. package/lib/lsp/connection-features.d.ts +1 -1
  4. package/lib/lsp/connection-features.js +3 -3
  5. package/lib/lsp/connection-features.js.map +1 -1
  6. package/lib/lsp/diagnostics-connection.js +3 -3
  7. package/lib/lsp/diagnostics-connection.js.map +1 -1
  8. package/lib/testing/node/applied-edit-capture.d.ts +29 -0
  9. package/lib/testing/node/applied-edit-capture.d.ts.map +1 -0
  10. package/lib/testing/node/applied-edit-capture.js +115 -0
  11. package/lib/testing/node/applied-edit-capture.js.map +1 -0
  12. package/lib/testing/node/lsp-server-connection.d.ts +1 -1
  13. package/lib/testing/node/lsp-server-connection.d.ts.map +1 -1
  14. package/lib/testing/node/lsp-server-connection.js +7 -101
  15. package/lib/testing/node/lsp-server-connection.js.map +1 -1
  16. package/lib/testing/node/spawned-server.d.ts +16 -1
  17. package/lib/testing/node/spawned-server.d.ts.map +1 -1
  18. package/lib/testing/node/spawned-server.js +5 -0
  19. package/lib/testing/node/spawned-server.js.map +1 -1
  20. package/lib/util/connection-liveness.d.ts +12 -0
  21. package/lib/util/connection-liveness.d.ts.map +1 -1
  22. package/lib/util/connection-liveness.js +24 -0
  23. package/lib/util/connection-liveness.js.map +1 -1
  24. package/package.json +5 -5
  25. package/src/langium/model-service/model-service.ts +2 -2
  26. package/src/lsp/connection-features.ts +3 -3
  27. package/src/lsp/diagnostics-connection.ts +3 -3
  28. package/src/testing/node/applied-edit-capture.ts +139 -0
  29. package/src/testing/node/lsp-server-connection.ts +8 -105
  30. package/src/testing/node/spawned-server.ts +21 -1
  31. package/src/util/connection-liveness.ts +27 -0
@@ -1 +1 @@
1
- {"version":3,"file":"spawned-server.d.ts","sourceRoot":"","sources":["../../../src/testing/node/spawned-server.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,6BAA6B,CAAC;AAK3D,OAAO,EAQJ,KAAK,UAAU,EACf,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,KAAK,kBAAkB,EACvB,KAAK,wBAAwB,EAC/B,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EAAE,KAAK,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AAEzE;;;;;;;;;;GAUG;AACH,eAAO,MAAM,8BAA8B,QAAS,CAAC;AAErD;;;;;;;GAOG;AACH,eAAO,MAAM,8BAA8B,QAAS,CAAC;AAwBrD,8CAA8C;AAC9C,MAAM,WAAW,iBAAiB;IAC/B,wCAAwC;IACxC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,uCAAuC;IACvC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,oDAAoD;AACpD,MAAM,WAAW,oBAAoB;IAClC;;;;;OAKG;IACH,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,6EAA6E;IAC7E,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC;;;;;;;OAOG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,iFAAiF;IACjF,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IACtC;;;OAGG;IACH,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACjC,mEAAmE;IACnE,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,sFAAsF;IACtF,QAAQ,CAAC,gBAAgB,CAAC,EAAE,OAAO,CAAC,gBAAgB,CAAC,CAAC;IACtD,kFAAkF;IAClF,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,mEAAmE;IACnE,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;CAClC;AAED,8DAA8D;AAC9D,MAAM,WAAW,aAAc,SAAQ,OAAO;IAC3C,oDAAoD;IACpD,QAAQ,CAAC,UAAU,EAAE,kBAAkB,CAAC;IACxC,kFAAkF;IAClF,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,mFAAmF;IACnF,QAAQ,CAAC,gBAAgB,EAAE,gBAAgB,CAAC;IAC5C,6FAA6F;IAC7F,QAAQ,CAAC,WAAW,EAAE,aAAa,CAAC,wBAAwB,CAAC,CAAC;IAC9D;;;;;;OAMG;IACH,QAAQ,CAAC,WAAW,EAAE,aAAa,CAAC,gBAAgB,CAAC,CAAC;IACtD,yDAAyD;IACzD,MAAM,IAAI,MAAM,CAAC;IACjB;;;;;;;OAOG;IACH,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACpE;;;;;;;;;;;OAWG;IACH,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,kBAAkB,CAAC,EAAE,MAAM,GAAG,sBAAsB,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;IAC1G;;;;OAIG;IACH,OAAO,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;CACpC;AAcD;;;;;;;;;;;;GAYG;AACH,wBAAsB,qBAAqB,IAAI,OAAO,CAAC,IAAI,CAAC,CAI3D;AAWD;;;;;;;;;;GAUG;AACH,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,aAAa,CAAC,CAgO9F"}
1
+ {"version":3,"file":"spawned-server.d.ts","sourceRoot":"","sources":["../../../src/testing/node/spawned-server.ts"],"names":[],"mappings":"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"}
@@ -11,6 +11,7 @@ import { existsSync } from 'node:fs';
11
11
  import * as path from 'node:path';
12
12
  import { pathToFileURL } from 'node:url';
13
13
  import { ExitNotification, InitializeRequest, InitializedNotification, LogMessageNotification, ShutdownRequest, PublishDiagnosticsNotification, createProtocolConnection } from 'vscode-languageserver-protocol/node';
14
+ import { captureAppliedEdits } from './applied-edit-capture.js';
14
15
  /**
15
16
  * Default bound on the `initialize` handshake, and the reason there is one at
16
17
  * all: without it a child that never answers hangs until the test runner's own
@@ -137,6 +138,7 @@ export async function startSpawnedServer(options) {
137
138
  connection.onNotification(LogMessageNotification.type, params => {
138
139
  logMessages.push(params);
139
140
  });
141
+ const appliedEditCapture = captureAppliedEdits(connection, RESPONSE_TIMEOUT_MS);
140
142
  connection.listen();
141
143
  const killTimeoutMs = options.killTimeoutMs ?? DEFAULT_KILL_TIMEOUT_MS;
142
144
  /** Terminate unconditionally and wait for the child to be reaped. */
@@ -285,7 +287,10 @@ export async function startSpawnedServer(options) {
285
287
  waiters.add(notify);
286
288
  });
287
289
  },
290
+ appliedEdits: appliedEditCapture.appliedEdits,
291
+ nextAppliedEdit: appliedEditCapture.nextAppliedEdit,
288
292
  dispose() {
293
+ appliedEditCapture.dispose();
289
294
  liveServers.delete(server);
290
295
  disposal ??= terminate();
291
296
  return disposal;
@@ -1 +1 @@
1
- {"version":3,"file":"spawned-server.js","sourceRoot":"","sources":["../../../src/testing/node/spawned-server.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAqClF,OAAO,EAAuC,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAChF,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EACJ,gBAAgB,EAChB,iBAAiB,EACjB,uBAAuB,EACvB,sBAAsB,EACtB,eAAe,EACf,8BAA8B,EAC9B,wBAAwB,EAO1B,MAAM,qCAAqC,CAAC;AAG7C;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,8BAA8B,GAAG,MAAM,CAAC;AAErD;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,8BAA8B,GAAG,MAAM,CAAC;AAErD,oFAAoF;AACpF,MAAM,mBAAmB,GAAG,MAAM,CAAC;AAEnC;;;;;GAKG;AACH,MAAM,uBAAuB,GAAG,KAAK,CAAC;AAEtC,0FAA0F;AAC1F,MAAM,YAAY,GAAsB,CAAC,SAAS,CAAC,CAAC;AAEpD;;;;;GAKG;AACH,MAAM,mBAAmB,GAAG,GAAG,CAAC;AAiGhC;;;;;;;;;GASG;AACH,MAAM,WAAW,GAAG,IAAI,GAAG,EAAiB,CAAC;AAE7C;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB;IACxC,MAAM,WAAW,GAAG,CAAC,GAAG,WAAW,CAAC,CAAC;IACrC,WAAW,CAAC,KAAK,EAAE,CAAC;IACpB,MAAM,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;AAClE,CAAC;AAED,gEAAgE;AAChE,SAAS,aAAa,CAAC,YAAoB,EAAE,MAAc;IACxD,OAAO,CACJ,0FAA0F;QAC1F,gCAAgC,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,IAAI,WAAW,IAAI;QAC/E,oBAAoB,MAAM,IAAI,WAAW,EAAE,CAC7C,CAAC;AACL,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,OAA6B;IACnE,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;IACxD,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CACZ,oCAAoC,YAAY,uGAAuG,CACzJ,CAAC;IACL,CAAC;IAED,MAAM,KAAK,GAAmC,KAAK,CAChD,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,QAAQ,EACpC,CAAC,YAAY,EAAE,GAAG,CAAC,OAAO,CAAC,IAAI,IAAI,YAAY,CAAC,CAAC,EACjD;QACG,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;QAC/B,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE;KACzC,CACH,CAAC;IACF,IAAI,SAAS,GAAG,EAAE,CAAC;IACnB,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE;QAC7B,SAAS,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC;IAC9B,CAAC,CAAC,CAAC;IACH,0EAA0E;IAC1E,2EAA2E;IAC3E,gDAAgD;IAChD,IAAI,YAAY,GAAG,EAAE,CAAC;IACtB,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE;QAC7B,IAAI,YAAY,CAAC,MAAM,GAAG,mBAAmB,EAAE,CAAC;YAC7C,YAAY,GAAG,CAAC,YAAY,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,mBAAmB,CAAC,CAAC;QAC/E,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,MAAM,UAAU,GAAG,wBAAwB,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IAChF,MAAM,WAAW,GAA+B,EAAE,CAAC;IACnD;;;;;OAKG;IACH,MAAM,OAAO,GAAG,IAAI,GAAG,EAA8C,CAAC;IACtE,UAAU,CAAC,cAAc,CAAC,8BAA8B,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE;QACrE,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACzB,KAAK,MAAM,MAAM,IAAI,CAAC,GAAG,OAAO,CAAC,EAAE,CAAC;YACjC,MAAM,CAAC,MAAM,CAAC,CAAC;QAClB,CAAC;IACJ,CAAC,CAAC,CAAC;IACH,MAAM,WAAW,GAAuB,EAAE,CAAC;IAC3C,UAAU,CAAC,cAAc,CAAC,sBAAsB,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE;QAC7D,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC5B,CAAC,CAAC,CAAC;IACH,UAAU,CAAC,MAAM,EAAE,CAAC;IAEpB,MAAM,aAAa,GAAG,OAAO,CAAC,aAAa,IAAI,uBAAuB,CAAC;IAEvE,qEAAqE;IACrE,KAAK,UAAU,cAAc;QAC1B,UAAU,CAAC,OAAO,EAAE,CAAC;QACrB,MAAM,QAAQ,GAAG,MAAM,IAAI,OAAO,CAAgB,OAAO,CAAC,EAAE;YACzD,IAAI,KAAK,CAAC,QAAQ,KAAK,IAAI,IAAI,KAAK,CAAC,UAAU,KAAK,IAAI,EAAE,CAAC;gBACxD,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;gBACxB,OAAO;YACV,CAAC;YACD,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;YAC3C,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACzB,CAAC,CAAC,CAAC;QACH,KAAK,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;QACtB,KAAK,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACvB,KAAK,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACvB,OAAO,QAAQ,CAAC;IACnB,CAAC;IAED,MAAM,OAAO,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,aAAa,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IAC/F,MAAM,gBAAgB,GAAqB;QACxC,SAAS,EAAE,OAAO,CAAC,GAAG;QACtB,OAAO;QACP,gBAAgB,EACb,OAAO,IAAI,OAAO,CAAC,aAAa;YAC7B,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,mBAAmB,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,aAAa,CAAC,EAAE,CAAC;YAC/F,CAAC,CAAC,IAAI;QACZ,YAAY,EAAE,EAAE;QAChB,GAAG,OAAO,CAAC,gBAAgB;KAC7B,CAAC;IAEF,MAAM,aAAa,GAAG,OAAO,CAAC,aAAa,IAAI,8BAA8B,CAAC;IAC9E,IAAI,SAAqC,CAAC;IAC1C,IAAI,YAAyD,CAAC;IAC9D,IAAI,gBAAkC,CAAC;IACvC,IAAI,CAAC;QACF,gBAAgB,GAAG,MAAM,IAAI,OAAO,CAAmB,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACxE,SAAS,GAAG,UAAU,CAAC,GAAG,EAAE;gBACzB,MAAM,CACH,IAAI,KAAK,CACN,kBAAkB,YAAY,uCAAuC,aAAa,OAAO,aAAa,CAAC,YAAY,EAAE,SAAS,CAAC,EAAE,CACnI,CACH,CAAC;YACL,CAAC,EAAE,aAAa,CAAC,CAAC;YAClB,YAAY,GAAG,IAAI,CAAC,EAAE;gBACnB,MAAM,CACH,IAAI,KAAK,CACN,kBAAkB,YAAY,qBAAqB,IAAI,0BAA0B,aAAa,CAAC,YAAY,EAAE,SAAS,CAAC,EAAE,CAC3H,CACH,CAAC;YACL,CAAC,CAAC;YACF,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;YAClC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;YAC5B,UAAU,CAAC,WAAW,CAAC,iBAAiB,CAAC,IAAI,EAAE,gBAAgB,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC1F,CAAC,CAAC,CAAC;IACN,CAAC;IAAC,OAAO,KAAc,EAAE,CAAC;QACvB,MAAM,cAAc,EAAE,CAAC;QACvB,MAAM,KAAK,CAAC;IACf,CAAC;YAAS,CAAC;QACR,YAAY,CAAC,SAAS,CAAC,CAAC;QACxB,IAAI,YAAY,EAAE,CAAC;YAChB,KAAK,CAAC,GAAG,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;QACpC,CAAC;IACJ,CAAC;IACD,UAAU,CAAC,gBAAgB,CAAC,uBAAuB,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IAE9D,IAAI,QAA4C,CAAC;IAEjD,iGAAiG;IACjG,SAAS,OAAO,CAAC,OAAyB;QACvC,OAAO,IAAI,OAAO,CAAO,OAAO,CAAC,EAAE;YAChC,MAAM,KAAK,GAAG,UAAU,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC;YACjD,OAAO,CAAC,IAAI,CACT,GAAG,EAAE;gBACF,YAAY,CAAC,KAAK,CAAC,CAAC;gBACpB,OAAO,EAAE,CAAC;YACb,CAAC,EACD,GAAG,EAAE;gBACF,YAAY,CAAC,KAAK,CAAC,CAAC;gBACpB,OAAO,EAAE,CAAC;YACb,CAAC,CACH,CAAC;QACL,CAAC,CAAC,CAAC;IACN,CAAC;IAED,KAAK,UAAU,SAAS;QACrB,yEAAyE;QACzE,qEAAqE;QACrE,+DAA+D;QAC/D,MAAM,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,eAAe,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC;QACvE,MAAM,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,gBAAgB,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACnF,wEAAwE;QACxE,uEAAuE;QACvE,sCAAsC;QACtC,UAAU,CAAC,OAAO,EAAE,CAAC;QACrB,MAAM,QAAQ,GAAG,MAAM,IAAI,OAAO,CAAgB,OAAO,CAAC,EAAE;YACzD,IAAI,KAAK,CAAC,QAAQ,KAAK,IAAI,IAAI,KAAK,CAAC,UAAU,KAAK,IAAI,EAAE,CAAC;gBACxD,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;gBACxB,OAAO;YACV,CAAC;YACD,MAAM,SAAS,GAAG,UAAU,CAAC,GAAG,EAAE;gBAC/B,IAAI,KAAK,CAAC,QAAQ,KAAK,IAAI,EAAE,CAAC;oBAC3B,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;gBACzB,CAAC;YACJ,CAAC,EAAE,aAAa,CAAC,CAAC;YAClB,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,EAAE;gBACxB,YAAY,CAAC,SAAS,CAAC,CAAC;gBACxB,OAAO,CAAC,IAAI,CAAC,CAAC;YACjB,CAAC,CAAC,CAAC;QACN,CAAC,CAAC,CAAC;QACH,KAAK,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;QACtB,KAAK,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACvB,KAAK,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACvB,OAAO,QAAQ,CAAC;IACnB,CAAC;IAED,MAAM,MAAM,GAAkB;QAC3B,UAAU;QACV,GAAG,EAAE,KAAK,CAAC,GAAG;QACd,gBAAgB;QAChB,WAAW;QACX,WAAW;QACX,MAAM,EAAE,GAAG,EAAE,CAAC,SAAS;QACvB,KAAK,CAAC,IAAI,CAAC,OAAe,EAAE,WAAW,GAAsB,EAAE;YAC5D,MAAM,QAAQ,GAAG,WAAW,CAAC,QAAQ,IAAI,EAAE,CAAC;YAC5C,MAAM,UAAU,GAAG,WAAW,CAAC,UAAU,IAAI,GAAG,CAAC;YACjD,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,GAAG,QAAQ,EAAE,OAAO,EAAE,EAAE,CAAC;gBACnD,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,WAAW,CAAqB,OAAO,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;gBAChG,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;oBAC5C,OAAO,MAAM,CAAC;gBACjB,CAAC;gBACD,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC,CAAC;YACjE,CAAC;YACD,MAAM,IAAI,KAAK,CAAC,sCAAsC,OAAO,WAAW,QAAQ,WAAW,CAAC,CAAC;QAChG,CAAC;QACD,eAAe,CAAC,GAAW,EAAE,kBAAoD;YAC9E,MAAM,WAAW,GACd,OAAO,kBAAkB,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,kBAAkB,EAAE,CAAC,CAAC,CAAC,CAAC,kBAAkB,IAAI,EAAE,CAAC,CAAC;YAC3G,MAAM,SAAS,GAAG,WAAW,CAAC,SAAS,IAAI,mBAAmB,CAAC;YAC/D,MAAM,EAAE,SAAS,EAAE,GAAG,WAAW,CAAC;YAClC,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;gBAC3B,sEAAsE;gBACtE,gEAAgE;gBAChE,MAAM,QAAQ,GAAG,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC;gBAC9F,IAAI,QAAQ,EAAE,CAAC;oBACZ,OAAO,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;gBAChD,CAAC;YACJ,CAAC;YACD,OAAO,IAAI,OAAO,CAAe,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;gBAClD,MAAM,MAAM,GAAG,CAAC,MAAgC,EAAQ,EAAE;oBACvD,IAAI,MAAM,CAAC,GAAG,KAAK,GAAG,EAAE,CAAC;wBACtB,OAAO;oBACV,CAAC;oBACD,YAAY,CAAC,KAAK,CAAC,CAAC;oBACpB,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;oBACvB,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;gBAC/B,CAAC,CAAC;gBACF,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;oBAC3B,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;oBACvB,MAAM,IAAI,GAAG,WAAW,CAAC,KAAK,CAAC,SAAS,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;oBACzE,MAAM,CAAC,IAAI,KAAK,CAAC,yCAAyC,GAAG,sBAAsB,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,WAAW,EAAE,CAAC,CAAC,CAAC;gBACzH,CAAC,EAAE,SAAS,CAAC,CAAC;gBACd,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YACvB,CAAC,CAAC,CAAC;QACN,CAAC;QACD,OAAO;YACJ,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YAC3B,QAAQ,KAAK,SAAS,EAAE,CAAC;YACzB,OAAO,QAAQ,CAAC;QACnB,CAAC;KACH,CAAC;IACF,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACxB,OAAO,MAAM,CAAC;AACjB,CAAC"}
1
+ {"version":3,"file":"spawned-server.js","sourceRoot":"","sources":["../../../src/testing/node/spawned-server.ts"],"names":[],"mappings":"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"}
@@ -23,4 +23,16 @@
23
23
  * that, since a logger has nowhere to report a logging failure anyway.
24
24
  */
25
25
  export declare function isConnectionGoneError(err: unknown): boolean;
26
+ /**
27
+ * Whether `err` means the client a connection serves has gone: what
28
+ * {@link isConnectionGoneError} recognises, or a write to a socket the client
29
+ * closed (`EPIPE`, `ECONNRESET`), matched by code or, for a request, by the
30
+ * code's name in the message.
31
+ *
32
+ * Only for a call whose errors can come from that connection alone. A socket
33
+ * error names no peer, so where a file system or another socket can fail the
34
+ * same call, it is a genuine failure and {@link isConnectionGoneError} is the
35
+ * one to ask.
36
+ */
37
+ export declare function isClientGoneError(err: unknown): boolean;
26
38
  //# sourceMappingURL=connection-liveness.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"connection-liveness.d.ts","sourceRoot":"","sources":["../../src/util/connection-liveness.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAuClF;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAO3D"}
1
+ {"version":3,"file":"connection-liveness.d.ts","sourceRoot":"","sources":["../../src/util/connection-liveness.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAuClF;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAO3D;AAOD;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CASvD"}
@@ -64,4 +64,28 @@ export function isConnectionGoneError(err) {
64
64
  const normalized = message.toLowerCase();
65
65
  return CONNECTION_GONE_PATTERNS.some(pattern => pattern.test(normalized));
66
66
  }
67
+ const SOCKET_GONE_CODES = new Set(['EPIPE', 'ECONNRESET']);
68
+ /** `write EPIPE` / `read ECONNRESET`, as a request's `ResponseError` copies the message. */
69
+ const SOCKET_GONE_PATTERN = /\b(epipe|econnreset)\b/;
70
+ /**
71
+ * Whether `err` means the client a connection serves has gone: what
72
+ * {@link isConnectionGoneError} recognises, or a write to a socket the client
73
+ * closed (`EPIPE`, `ECONNRESET`), matched by code or, for a request, by the
74
+ * code's name in the message.
75
+ *
76
+ * Only for a call whose errors can come from that connection alone. A socket
77
+ * error names no peer, so where a file system or another socket can fail the
78
+ * same call, it is a genuine failure and {@link isConnectionGoneError} is the
79
+ * one to ask.
80
+ */
81
+ export function isClientGoneError(err) {
82
+ if (isConnectionGoneError(err)) {
83
+ return true;
84
+ }
85
+ if (err instanceof Error && 'code' in err && typeof err.code === 'string' && SOCKET_GONE_CODES.has(err.code)) {
86
+ return true;
87
+ }
88
+ const message = err instanceof Error ? err.message : String(err);
89
+ return SOCKET_GONE_PATTERN.test(message.toLowerCase());
90
+ }
67
91
  //# sourceMappingURL=connection-liveness.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"connection-liveness.js","sourceRoot":"","sources":["../../src/util/connection-liveness.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,wBAAwB,GAAG;IAC9B,wBAAwB;IACxB,sBAAsB;IACtB,yBAAyB;IACzB,uBAAuB;IACvB,8BAA8B;CAChC,CAAC;AAEF,MAAM,qBAAqB,GAAG,sBAAsB,CAAC;AAErD,SAAS,sBAAsB,CAAC,GAAY;IACzC,OAAO,GAAG,YAAY,KAAK,IAAI,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,IAAI,KAAK,qBAAqB,CAAC;AACtF,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,qBAAqB,CAAC,GAAY;IAC/C,IAAI,sBAAsB,CAAC,GAAG,CAAC,EAAE,CAAC;QAC/B,OAAO,IAAI,CAAC;IACf,CAAC;IACD,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACjE,MAAM,UAAU,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IACzC,OAAO,wBAAwB,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;AAC7E,CAAC"}
1
+ {"version":3,"file":"connection-liveness.js","sourceRoot":"","sources":["../../src/util/connection-liveness.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,wBAAwB,GAAG;IAC9B,wBAAwB;IACxB,sBAAsB;IACtB,yBAAyB;IACzB,uBAAuB;IACvB,8BAA8B;CAChC,CAAC;AAEF,MAAM,qBAAqB,GAAG,sBAAsB,CAAC;AAErD,SAAS,sBAAsB,CAAC,GAAY;IACzC,OAAO,GAAG,YAAY,KAAK,IAAI,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,IAAI,KAAK,qBAAqB,CAAC;AACtF,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,qBAAqB,CAAC,GAAY;IAC/C,IAAI,sBAAsB,CAAC,GAAG,CAAC,EAAE,CAAC;QAC/B,OAAO,IAAI,CAAC;IACf,CAAC;IACD,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACjE,MAAM,UAAU,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IACzC,OAAO,wBAAwB,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;AAC7E,CAAC;AAED,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAAC,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC;AAE3D,4FAA4F;AAC5F,MAAM,mBAAmB,GAAG,wBAAwB,CAAC;AAErD;;;;;;;;;;GAUG;AACH,MAAM,UAAU,iBAAiB,CAAC,GAAY;IAC3C,IAAI,qBAAqB,CAAC,GAAG,CAAC,EAAE,CAAC;QAC9B,OAAO,IAAI,CAAC;IACf,CAAC;IACD,IAAI,GAAG,YAAY,KAAK,IAAI,MAAM,IAAI,GAAG,IAAI,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ,IAAI,iBAAiB,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;QAC5G,OAAO,IAAI,CAAC;IACf,CAAC;IACD,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACjE,OAAO,mBAAmB,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;AAC1D,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hydranium/core",
3
- "version": "1.0.0-next.252",
3
+ "version": "1.0.0-next.254",
4
4
  "description": "Foundational runtime of the hydranium framework: AST coordination layer (services, integrity, AST extension, serialization, multi-client documents) plus the LSP textual head at the /lsp subpath. Consumed by protocol-head packages (@hydranium/data-server, @hydranium/glsp-server).",
5
5
  "keywords": [
6
6
  "ast",
@@ -83,8 +83,8 @@
83
83
  "diff": "^5.2.0"
84
84
  },
85
85
  "devDependencies": {
86
- "@hydranium/langium": "1.0.0-next.252",
87
- "@hydranium/protocol": "1.0.0-next.252",
86
+ "@hydranium/langium": "1.0.0-next.254",
87
+ "@hydranium/protocol": "1.0.0-next.254",
88
88
  "@playwright/test": "^1.40.0",
89
89
  "@types/diff": "^5.2.0",
90
90
  "rimraf": "^5.0.0",
@@ -96,8 +96,8 @@
96
96
  "vscode-languageserver-types": "^3.17.5"
97
97
  },
98
98
  "peerDependencies": {
99
- "@hydranium/langium": "1.0.0-next.252",
100
- "@hydranium/protocol": "1.0.0-next.252",
99
+ "@hydranium/langium": "1.0.0-next.254",
100
+ "@hydranium/protocol": "1.0.0-next.254",
101
101
  "@playwright/test": "^1.40.0",
102
102
  "vscode-jsonrpc": "^9.0.0",
103
103
  "vscode-languageserver": "~10.0.1",
@@ -26,7 +26,7 @@ import { type DocumentUriPolicy } from '../workspace/document-uri-policy.js';
26
26
  import { ReentrantWriteLockError, isInsideWriteLock, isWriteLockScopeInstalled } from '../workspace/write-lock-scope.js';
27
27
  import { CancellationToken, Disposable } from 'vscode-languageserver';
28
28
  import { AstDocument } from '../../documents/ast-document-manager.js';
29
- import { isConnectionGoneError } from '../../util/connection-liveness.js';
29
+ import { isClientGoneError } from '../../util/connection-liveness.js';
30
30
  import { type LogNameOptions } from '../diagnostics/logger.js';
31
31
  import { IntegrityService } from '../integrity/integrity-service.js';
32
32
  import { labelPhaseListener } from '../document-builder/labeled-phase-listener.js';
@@ -1120,7 +1120,7 @@ export class DefaultModelService<
1120
1120
  // ordinary shutdown. Reporting it at `error` makes routine teardown
1121
1121
  // look like it needs investigating. A genuine applyEdit failure
1122
1122
  // (client refused, request malformed) still surfaces at `error`.
1123
- if (isConnectionGoneError(err)) {
1123
+ if (isClientGoneError(err)) {
1124
1124
  uriLogger.debug(`applyEdit to ${LANGUAGE_CLIENT_ID} skipped: client disconnected`);
1125
1125
  } else {
1126
1126
  uriLogger.error(`applyEdit to ${LANGUAGE_CLIENT_ID} failed: ${err}`);
@@ -8,14 +8,14 @@
8
8
  ********************************************************************************/
9
9
 
10
10
  import { LogMessageNotification, MessageType, type Features, type RemoteConsole } from 'vscode-languageserver';
11
- import { isConnectionGoneError } from '../util/connection-liveness.js';
11
+ import { isClientGoneError } from '../util/connection-liveness.js';
12
12
 
13
13
  /**
14
14
  * Add Hydranium's connection-liveness handling to a language-server
15
15
  * connection's console. The upstream `RemoteConsole` catches every failed log
16
16
  * notification and prints `Sending log message failed`, so every ordinary
17
17
  * teardown reports a failure; this console drops only a failure that
18
- * {@link isConnectionGoneError} recognises and re-raises any other as an
18
+ * {@link isClientGoneError} recognises and re-raises any other as an
19
19
  * unhandled rejection.
20
20
  *
21
21
  * Supply it where the connection is created. `createConnection` builds the
@@ -58,7 +58,7 @@ export function withHydraniumLspFeatures<T extends Features>(features: T): T {
58
58
  }
59
59
 
60
60
  private handleLogSendFailure(error: unknown): void {
61
- if (!isConnectionGoneError(error)) {
61
+ if (!isClientGoneError(error)) {
62
62
  void Promise.reject(error);
63
63
  }
64
64
  }
@@ -8,7 +8,7 @@
8
8
  ********************************************************************************/
9
9
 
10
10
  import type { Connection } from 'vscode-languageserver';
11
- import { isConnectionGoneError } from '../util/connection-liveness.js';
11
+ import { isClientGoneError } from '../util/connection-liveness.js';
12
12
 
13
13
  const wrappedConnections = new WeakSet<object>();
14
14
 
@@ -40,13 +40,13 @@ export function guardDiagnosticsConnection(connection: Connection): void {
40
40
  try {
41
41
  result = sendDiagnostics(params);
42
42
  } catch (error: unknown) {
43
- if (isConnectionGoneError(error)) {
43
+ if (isClientGoneError(error)) {
44
44
  return Promise.resolve();
45
45
  }
46
46
  throw error;
47
47
  }
48
48
  void result.catch(error => {
49
- if (isConnectionGoneError(error)) {
49
+ if (isClientGoneError(error)) {
50
50
  return;
51
51
  }
52
52
  throw error;
@@ -0,0 +1,139 @@
1
+ /********************************************************************************
2
+ * Copyright (c) 2026 CrossBreeze, EclipseSource and others.
3
+ *
4
+ * This program and the accompanying materials are made available under the
5
+ * terms of the MIT License which is available in the project root.
6
+ *
7
+ * SPDX-License-Identifier: MIT
8
+ ********************************************************************************/
9
+
10
+ import {
11
+ ApplyWorkspaceEditRequest,
12
+ type ApplyWorkspaceEditParams,
13
+ type ApplyWorkspaceEditResult,
14
+ type ProtocolConnection,
15
+ type WorkspaceEdit
16
+ } from 'vscode-languageserver-protocol/node';
17
+ import type { AppliedEdit, NextAppliedEditOptions } from './lsp-server-connection.js';
18
+
19
+ /**
20
+ * The client side of `workspace/applyEdit` on one LSP connection, shared by the
21
+ * in-process and the spawned tiers so their capture and wait cannot drift.
22
+ */
23
+ export interface AppliedEditCapture {
24
+ readonly appliedEdits: ReadonlyArray<AppliedEdit>;
25
+ nextAppliedEdit(uri: string, timeoutMsOrOptions?: number | NextAppliedEditOptions): Promise<AppliedEdit>;
26
+ setApplyEditHandler(handler: (params: ApplyWorkspaceEditParams) => ApplyWorkspaceEditResult): void;
27
+ dispose(): void;
28
+ }
29
+
30
+ /**
31
+ * Answer and record every `workspace/applyEdit` arriving on `client`.
32
+ *
33
+ * Register before the connection can receive one: `vscode-jsonrpc` keeps a
34
+ * single handler per request type, so this must be the only `applyEdit`
35
+ * handler on `client`, and a second registration displaces the capture.
36
+ */
37
+ export function captureAppliedEdits(client: ProtocolConnection, defaultTimeoutMs: number): AppliedEditCapture {
38
+ const appliedEdits: AppliedEdit[] = [];
39
+ const waiters: Array<(edit: AppliedEdit) => boolean> = [];
40
+ let handler: (params: ApplyWorkspaceEditParams) => ApplyWorkspaceEditResult = () => ({ applied: true });
41
+ const subscription = client.onRequest(ApplyWorkspaceEditRequest.type, (params: ApplyWorkspaceEditParams) => {
42
+ const edit: AppliedEdit = { params, uris: editedUris(params.edit), text: insertedText(params.edit) };
43
+ // Record before the handler runs, so a handler that rejects the edit or
44
+ // throws still leaves the push observable — the send is what the egress
45
+ // assertion is about.
46
+ appliedEdits.push(edit);
47
+ for (const waiter of [...waiters]) {
48
+ if (waiter(edit)) {
49
+ const at = waiters.indexOf(waiter);
50
+ if (at >= 0) {
51
+ waiters.splice(at, 1);
52
+ }
53
+ }
54
+ }
55
+ return handler(params);
56
+ });
57
+
58
+ return {
59
+ appliedEdits,
60
+
61
+ nextAppliedEdit(uri: string, timeoutMsOrOptions?: number | NextAppliedEditOptions): Promise<AppliedEdit> {
62
+ const options: NextAppliedEditOptions =
63
+ typeof timeoutMsOrOptions === 'number' ? { timeoutMs: timeoutMsOrOptions } : (timeoutMsOrOptions ?? {});
64
+ const timeoutMs = options.timeoutMs ?? defaultTimeoutMs;
65
+ const { fromIndex, match } = options;
66
+ const matches = (edit: AppliedEdit): boolean => edit.uris.includes(uri) && (match?.(edit) ?? true);
67
+ if (fromIndex !== undefined) {
68
+ // Replay from the capture first: the push may already have arrived,
69
+ // and a waiter only ever sees later ones.
70
+ const captured = appliedEdits.slice(Math.max(0, fromIndex)).find(matches);
71
+ if (captured) {
72
+ return Promise.resolve(captured);
73
+ }
74
+ }
75
+ return new Promise<AppliedEdit>((resolve, reject) => {
76
+ const waiter = (edit: AppliedEdit): boolean => {
77
+ if (!matches(edit)) {
78
+ return false;
79
+ }
80
+ clearTimeout(timer);
81
+ resolve(edit);
82
+ return true;
83
+ };
84
+ const timer = setTimeout(() => {
85
+ const at = waiters.indexOf(waiter);
86
+ if (at >= 0) {
87
+ waiters.splice(at, 1);
88
+ }
89
+ reject(new Error(`Timed out waiting for a workspace/applyEdit addressing ${uri}`));
90
+ }, timeoutMs);
91
+ waiters.push(waiter);
92
+ });
93
+ },
94
+
95
+ setApplyEditHandler(next: (params: ApplyWorkspaceEditParams) => ApplyWorkspaceEditResult): void {
96
+ handler = next;
97
+ },
98
+
99
+ dispose(): void {
100
+ subscription.dispose();
101
+ }
102
+ };
103
+ }
104
+
105
+ /** Every URI a {@link WorkspaceEdit} addresses, in `documentChanges` then `changes` order. */
106
+ function editedUris(edit: WorkspaceEdit): string[] {
107
+ const uris: string[] = [];
108
+ for (const change of edit.documentChanges ?? []) {
109
+ if ('textDocument' in change) {
110
+ uris.push(change.textDocument.uri);
111
+ } else if ('oldUri' in change) {
112
+ uris.push(change.oldUri, change.newUri);
113
+ } else {
114
+ uris.push(change.uri);
115
+ }
116
+ }
117
+ uris.push(...Object.keys(edit.changes ?? {}));
118
+ return uris;
119
+ }
120
+
121
+ /** Every text edit's `newText` in a {@link WorkspaceEdit}, concatenated in edit order. */
122
+ function insertedText(edit: WorkspaceEdit): string {
123
+ const parts: string[] = [];
124
+ for (const change of edit.documentChanges ?? []) {
125
+ if ('edits' in change) {
126
+ for (const textEdit of change.edits) {
127
+ if ('newText' in textEdit) {
128
+ parts.push(textEdit.newText);
129
+ }
130
+ }
131
+ }
132
+ }
133
+ for (const textEdits of Object.values(edit.changes ?? {})) {
134
+ for (const textEdit of textEdits) {
135
+ parts.push(textEdit.newText);
136
+ }
137
+ }
138
+ return parts.join('');
139
+ }
@@ -12,6 +12,7 @@ import { PassThrough, type TransformCallback } from 'node:stream';
12
12
  import { StreamMessageReader, StreamMessageWriter } from 'vscode-jsonrpc/node';
13
13
  import { type Connection, ProposedFeatures } from 'vscode-languageserver/node';
14
14
  import { withHydraniumLspFeatures } from '../../lsp/connection-features.js';
15
+ import { captureAppliedEdits } from './applied-edit-capture.js';
15
16
  // The node `createConnection` from `vscode-languageserver/node` is built for a
16
17
  // standalone server PROCESS: it wires `process.exit()` onto the input stream's
17
18
  // `end`/`close` events, onto the `exit` notification (via its watchDog), and onto
@@ -26,7 +27,6 @@ import { withHydraniumLspFeatures } from '../../lsp/connection-features.js';
26
27
  // package map the LSP 3.18 libs ship.)
27
28
  import { createConnection, type WatchDog } from 'vscode-languageserver';
28
29
  import {
29
- ApplyWorkspaceEditRequest,
30
30
  CompletionRequest,
31
31
  DidChangeTextDocumentNotification,
32
32
  DidCloseTextDocumentNotification,
@@ -48,8 +48,7 @@ import {
48
48
  type Position,
49
49
  type ProtocolConnection,
50
50
  type PublishDiagnosticsParams,
51
- type SemanticTokens,
52
- type WorkspaceEdit
51
+ type SemanticTokens
53
52
  } from 'vscode-languageserver-protocol/node';
54
53
 
55
54
  /**
@@ -122,7 +121,7 @@ export interface NextAppliedEditOptions {
122
121
  * and needed for the same reason: one write can fan out to several pushes.
123
122
  */
124
123
  readonly fromIndex?: number;
125
- /** Reject after this long. Defaults to the in-process publish timeout. */
124
+ /** Reject after this long. Defaults to the harness's own timeout, which differs by tier. */
126
125
  readonly timeoutMs?: number;
127
126
  /**
128
127
  * Additional predicate the edit must satisfy. The framework coalesces
@@ -133,42 +132,6 @@ export interface NextAppliedEditOptions {
133
132
  readonly match?: (edit: AppliedEdit) => boolean;
134
133
  }
135
134
 
136
- /** Every URI a {@link WorkspaceEdit} addresses, in `documentChanges` then `changes` order. */
137
- function editedUris(edit: WorkspaceEdit): string[] {
138
- const uris: string[] = [];
139
- for (const change of edit.documentChanges ?? []) {
140
- if ('textDocument' in change) {
141
- uris.push(change.textDocument.uri);
142
- } else if ('oldUri' in change) {
143
- uris.push(change.oldUri, change.newUri);
144
- } else {
145
- uris.push(change.uri);
146
- }
147
- }
148
- uris.push(...Object.keys(edit.changes ?? {}));
149
- return uris;
150
- }
151
-
152
- /** Every text edit's `newText` in a {@link WorkspaceEdit}, concatenated in edit order. */
153
- function insertedText(edit: WorkspaceEdit): string {
154
- const parts: string[] = [];
155
- for (const change of edit.documentChanges ?? []) {
156
- if ('edits' in change) {
157
- for (const textEdit of change.edits) {
158
- if ('newText' in textEdit) {
159
- parts.push(textEdit.newText);
160
- }
161
- }
162
- }
163
- }
164
- for (const textEdits of Object.values(edit.changes ?? {})) {
165
- for (const textEdit of textEdits) {
166
- parts.push(textEdit.newText);
167
- }
168
- }
169
- return parts.join('');
170
- }
171
-
172
135
  /**
173
136
  * The in-process LSP transport seam — a real `Connection` over a crossed pair
174
137
  * of in-memory streams, plus the client side, the diagnostics capture,
@@ -426,32 +389,7 @@ export function makeLspServerConnection(): LspServerConnection {
426
389
  }
427
390
  });
428
391
 
429
- const appliedEdits: AppliedEdit[] = [];
430
- /**
431
- * Waiters armed by {@link LspServerConnection.nextAppliedEdit}, fanned out to
432
- * from the ONE handler below — `vscode-jsonrpc` keeps a single handler per
433
- * REQUEST type just as it does per notification type, so a second
434
- * `onRequest` would displace this one and leave the server's `applyEdit`
435
- * unanswered.
436
- */
437
- const appliedEditWaiters: Array<(edit: AppliedEdit) => boolean> = [];
438
- let applyEditHandler: (params: ApplyWorkspaceEditParams) => ApplyWorkspaceEditResult = () => ({ applied: true });
439
- const appliedEditSubscription = client.onRequest(ApplyWorkspaceEditRequest.type, (params: ApplyWorkspaceEditParams) => {
440
- const edit: AppliedEdit = { params, uris: editedUris(params.edit), text: insertedText(params.edit) };
441
- // Record BEFORE the handler runs, so a handler that rejects the edit or
442
- // throws still leaves the push observable — the send is what the egress
443
- // assertion is about.
444
- appliedEdits.push(edit);
445
- for (const waiter of [...appliedEditWaiters]) {
446
- if (waiter(edit)) {
447
- const at = appliedEditWaiters.indexOf(waiter);
448
- if (at >= 0) {
449
- appliedEditWaiters.splice(at, 1);
450
- }
451
- }
452
- }
453
- return applyEditHandler(params);
454
- });
392
+ const appliedEditCapture = captureAppliedEdits(client, DEFAULT_DIAGNOSTICS_TIMEOUT_MS);
455
393
 
456
394
  let disposed = false;
457
395
 
@@ -459,7 +397,7 @@ export function makeLspServerConnection(): LspServerConnection {
459
397
  serverConnection,
460
398
  client,
461
399
  diagnostics,
462
- appliedEdits,
400
+ appliedEdits: appliedEditCapture.appliedEdits,
463
401
  wireBytes: () => ({
464
402
  clientToServer: pair.clientToServer.bytes,
465
403
  serverToClient: pair.serverToClient.bytes,
@@ -575,51 +513,16 @@ export function makeLspServerConnection(): LspServerConnection {
575
513
  });
576
514
  },
577
515
 
578
- nextAppliedEdit(uri: string, timeoutMsOrOptions?: number | NextAppliedEditOptions): Promise<AppliedEdit> {
579
- const options: NextAppliedEditOptions =
580
- typeof timeoutMsOrOptions === 'number' ? { timeoutMs: timeoutMsOrOptions } : (timeoutMsOrOptions ?? {});
581
- const timeoutMs = options.timeoutMs ?? DEFAULT_DIAGNOSTICS_TIMEOUT_MS;
582
- const { fromIndex, match } = options;
583
- const matches = (edit: AppliedEdit): boolean => edit.uris.includes(uri) && (match?.(edit) ?? true);
584
- if (fromIndex !== undefined) {
585
- // Replay from the capture first, for the same reason
586
- // `nextDiagnostics` does: the push may already have arrived, and a
587
- // waiter only ever sees later ones.
588
- const captured = appliedEdits.slice(Math.max(0, fromIndex)).find(matches);
589
- if (captured) {
590
- return Promise.resolve(captured);
591
- }
592
- }
593
- return new Promise<AppliedEdit>((resolve, reject) => {
594
- const waiter = (edit: AppliedEdit): boolean => {
595
- if (!matches(edit)) {
596
- return false;
597
- }
598
- clearTimeout(timer);
599
- resolve(edit);
600
- return true;
601
- };
602
- const timer = setTimeout(() => {
603
- const at = appliedEditWaiters.indexOf(waiter);
604
- if (at >= 0) {
605
- appliedEditWaiters.splice(at, 1);
606
- }
607
- reject(new Error(`Timed out waiting for a workspace/applyEdit addressing ${uri}`));
608
- }, timeoutMs);
609
- appliedEditWaiters.push(waiter);
610
- });
611
- },
516
+ nextAppliedEdit: appliedEditCapture.nextAppliedEdit,
612
517
 
613
- setApplyEditHandler(handler: (params: ApplyWorkspaceEditParams) => ApplyWorkspaceEditResult): void {
614
- applyEditHandler = handler;
615
- },
518
+ setApplyEditHandler: appliedEditCapture.setApplyEditHandler,
616
519
 
617
520
  dispose(): void {
618
521
  if (disposed) {
619
522
  return;
620
523
  }
621
524
  disposed = true;
622
- appliedEditSubscription.dispose();
525
+ appliedEditCapture.dispose();
623
526
  diagnosticsSubscription.dispose();
624
527
  client.dispose();
625
528
  serverConnection.dispose();
@@ -61,7 +61,8 @@ import {
61
61
  type ProtocolConnection,
62
62
  type PublishDiagnosticsParams
63
63
  } from 'vscode-languageserver-protocol/node';
64
- import { type NextDiagnosticsOptions } from './lsp-server-connection.js';
64
+ import { captureAppliedEdits } from './applied-edit-capture.js';
65
+ import { type AppliedEdit, type NextAppliedEditOptions, type NextDiagnosticsOptions } from './lsp-server-connection.js';
65
66
 
66
67
  /**
67
68
  * Default bound on the `initialize` handshake, and the reason there is one at
@@ -195,6 +196,21 @@ export interface SpawnedServer extends Harness {
195
196
  * whenever one action fans out.
196
197
  */
197
198
  nextDiagnostics(uri: string, timeoutMsOrOptions?: number | NextDiagnosticsOptions): Promise<Diagnostic[]>;
199
+ /**
200
+ * Every `workspace/applyEdit` the child sent, in arrival order; append-only,
201
+ * each answered `{ applied: true }` as a real language client does.
202
+ *
203
+ * A Hydranium server mirrors an edit only for a document this connection has
204
+ * opened, so a write to one never sent `didOpen` here produces no entry. A
205
+ * second `applyEdit` handler registered on {@link connection} displaces this
206
+ * capture.
207
+ */
208
+ readonly appliedEdits: ReadonlyArray<AppliedEdit>;
209
+ /**
210
+ * Resolve with the next captured `workspace/applyEdit` addressing `uri`,
211
+ * with the same `fromIndex` and `match` contract as the in-process tier's.
212
+ */
213
+ nextAppliedEdit(uri: string, timeoutMsOrOptions?: number | NextAppliedEditOptions): Promise<AppliedEdit>;
198
214
  /**
199
215
  * Graceful `shutdown` / `exit`, each bounded, then `SIGKILL`. Resolves with
200
216
  * the child's exit code — `null` when a signal ended it, which is itself the
@@ -303,6 +319,7 @@ export async function startSpawnedServer(options: SpawnedServerOptions): Promise
303
319
  connection.onNotification(LogMessageNotification.type, params => {
304
320
  logMessages.push(params);
305
321
  });
322
+ const appliedEditCapture = captureAppliedEdits(connection, RESPONSE_TIMEOUT_MS);
306
323
  connection.listen();
307
324
 
308
325
  const killTimeoutMs = options.killTimeoutMs ?? DEFAULT_KILL_TIMEOUT_MS;
@@ -470,7 +487,10 @@ export async function startSpawnedServer(options: SpawnedServerOptions): Promise
470
487
  waiters.add(notify);
471
488
  });
472
489
  },
490
+ appliedEdits: appliedEditCapture.appliedEdits,
491
+ nextAppliedEdit: appliedEditCapture.nextAppliedEdit,
473
492
  dispose(): Promise<number | null> {
493
+ appliedEditCapture.dispose();
474
494
  liveServers.delete(server);
475
495
  disposal ??= terminate();
476
496
  return disposal;
@@ -68,3 +68,30 @@ export function isConnectionGoneError(err: unknown): boolean {
68
68
  const normalized = message.toLowerCase();
69
69
  return CONNECTION_GONE_PATTERNS.some(pattern => pattern.test(normalized));
70
70
  }
71
+
72
+ const SOCKET_GONE_CODES = new Set(['EPIPE', 'ECONNRESET']);
73
+
74
+ /** `write EPIPE` / `read ECONNRESET`, as a request's `ResponseError` copies the message. */
75
+ const SOCKET_GONE_PATTERN = /\b(epipe|econnreset)\b/;
76
+
77
+ /**
78
+ * Whether `err` means the client a connection serves has gone: what
79
+ * {@link isConnectionGoneError} recognises, or a write to a socket the client
80
+ * closed (`EPIPE`, `ECONNRESET`), matched by code or, for a request, by the
81
+ * code's name in the message.
82
+ *
83
+ * Only for a call whose errors can come from that connection alone. A socket
84
+ * error names no peer, so where a file system or another socket can fail the
85
+ * same call, it is a genuine failure and {@link isConnectionGoneError} is the
86
+ * one to ask.
87
+ */
88
+ export function isClientGoneError(err: unknown): boolean {
89
+ if (isConnectionGoneError(err)) {
90
+ return true;
91
+ }
92
+ if (err instanceof Error && 'code' in err && typeof err.code === 'string' && SOCKET_GONE_CODES.has(err.code)) {
93
+ return true;
94
+ }
95
+ const message = err instanceof Error ? err.message : String(err);
96
+ return SOCKET_GONE_PATTERN.test(message.toLowerCase());
97
+ }