@hydranium/protocol 1.0.0-next.10

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 (254) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +81 -0
  3. package/lib/abstract-logger.d.ts +66 -0
  4. package/lib/abstract-logger.d.ts.map +1 -0
  5. package/lib/abstract-logger.js +110 -0
  6. package/lib/abstract-logger.js.map +1 -0
  7. package/lib/browser-runtime.d.ts +124 -0
  8. package/lib/browser-runtime.d.ts.map +1 -0
  9. package/lib/browser-runtime.js +11 -0
  10. package/lib/browser-runtime.js.map +1 -0
  11. package/lib/client/data-events.d.ts +49 -0
  12. package/lib/client/data-events.d.ts.map +1 -0
  13. package/lib/client/data-events.js +60 -0
  14. package/lib/client/data-events.js.map +1 -0
  15. package/lib/client/data-port.d.ts +95 -0
  16. package/lib/client/data-port.d.ts.map +1 -0
  17. package/lib/client/data-port.js +11 -0
  18. package/lib/client/data-port.js.map +1 -0
  19. package/lib/client/data-session.d.ts +129 -0
  20. package/lib/client/data-session.d.ts.map +1 -0
  21. package/lib/client/data-session.js +179 -0
  22. package/lib/client/data-session.js.map +1 -0
  23. package/lib/client/index.d.ts +39 -0
  24. package/lib/client/index.d.ts.map +1 -0
  25. package/lib/client/index.js +55 -0
  26. package/lib/client/index.js.map +1 -0
  27. package/lib/client/message-relay.d.ts +111 -0
  28. package/lib/client/message-relay.d.ts.map +1 -0
  29. package/lib/client/message-relay.js +139 -0
  30. package/lib/client/message-relay.js.map +1 -0
  31. package/lib/client/post-message-transport.d.ts +77 -0
  32. package/lib/client/post-message-transport.d.ts.map +1 -0
  33. package/lib/client/post-message-transport.js +95 -0
  34. package/lib/client/post-message-transport.js.map +1 -0
  35. package/lib/clock.d.ts +111 -0
  36. package/lib/clock.d.ts.map +1 -0
  37. package/lib/clock.js +74 -0
  38. package/lib/clock.js.map +1 -0
  39. package/lib/data/data-protocol-methods.d.ts +39 -0
  40. package/lib/data/data-protocol-methods.d.ts.map +1 -0
  41. package/lib/data/data-protocol-methods.js +61 -0
  42. package/lib/data/data-protocol-methods.js.map +1 -0
  43. package/lib/data/data-server-protocol.d.ts +264 -0
  44. package/lib/data/data-server-protocol.d.ts.map +1 -0
  45. package/lib/data/data-server-protocol.js +11 -0
  46. package/lib/data/data-server-protocol.js.map +1 -0
  47. package/lib/data/diagnostics.d.ts +97 -0
  48. package/lib/data/diagnostics.d.ts.map +1 -0
  49. package/lib/data/diagnostics.js +25 -0
  50. package/lib/data/diagnostics.js.map +1 -0
  51. package/lib/data/events.d.ts +107 -0
  52. package/lib/data/events.d.ts.map +1 -0
  53. package/lib/data/events.js +11 -0
  54. package/lib/data/events.js.map +1 -0
  55. package/lib/data/index.d.ts +15 -0
  56. package/lib/data/index.d.ts.map +1 -0
  57. package/lib/data/index.js +38 -0
  58. package/lib/data/index.js.map +1 -0
  59. package/lib/data/methods.d.ts +57 -0
  60. package/lib/data/methods.d.ts.map +1 -0
  61. package/lib/data/methods.js +60 -0
  62. package/lib/data/methods.js.map +1 -0
  63. package/lib/data/requests.d.ts +65 -0
  64. package/lib/data/requests.d.ts.map +1 -0
  65. package/lib/data/requests.js +11 -0
  66. package/lib/data/requests.js.map +1 -0
  67. package/lib/debouncer.d.ts +75 -0
  68. package/lib/debouncer.d.ts.map +1 -0
  69. package/lib/debouncer.js +91 -0
  70. package/lib/debouncer.js.map +1 -0
  71. package/lib/errors.d.ts +84 -0
  72. package/lib/errors.d.ts.map +1 -0
  73. package/lib/errors.js +113 -0
  74. package/lib/errors.js.map +1 -0
  75. package/lib/host-diagnostics.d.ts +58 -0
  76. package/lib/host-diagnostics.d.ts.map +1 -0
  77. package/lib/host-diagnostics.js +18 -0
  78. package/lib/host-diagnostics.js.map +1 -0
  79. package/lib/index.d.ts +34 -0
  80. package/lib/index.d.ts.map +1 -0
  81. package/lib/index.js +56 -0
  82. package/lib/index.js.map +1 -0
  83. package/lib/latency-collector.d.ts +126 -0
  84. package/lib/latency-collector.d.ts.map +1 -0
  85. package/lib/latency-collector.js +137 -0
  86. package/lib/latency-collector.js.map +1 -0
  87. package/lib/logger.d.ts +119 -0
  88. package/lib/logger.d.ts.map +1 -0
  89. package/lib/logger.js +126 -0
  90. package/lib/logger.js.map +1 -0
  91. package/lib/model-server.d.ts +352 -0
  92. package/lib/model-server.d.ts.map +1 -0
  93. package/lib/model-server.js +160 -0
  94. package/lib/model-server.js.map +1 -0
  95. package/lib/model-service/args.d.ts +64 -0
  96. package/lib/model-service/args.d.ts.map +1 -0
  97. package/lib/model-service/args.js +11 -0
  98. package/lib/model-service/args.js.map +1 -0
  99. package/lib/model-service/index.d.ts +11 -0
  100. package/lib/model-service/index.d.ts.map +1 -0
  101. package/lib/model-service/index.js +31 -0
  102. package/lib/model-service/index.js.map +1 -0
  103. package/lib/model-service/reference-candidate.d.ts +56 -0
  104. package/lib/model-service/reference-candidate.d.ts.map +1 -0
  105. package/lib/model-service/reference-candidate.js +11 -0
  106. package/lib/model-service/reference-candidate.js.map +1 -0
  107. package/lib/noop-logger.d.ts +25 -0
  108. package/lib/noop-logger.d.ts.map +1 -0
  109. package/lib/noop-logger.js +36 -0
  110. package/lib/noop-logger.js.map +1 -0
  111. package/lib/observable-value.d.ts +72 -0
  112. package/lib/observable-value.d.ts.map +1 -0
  113. package/lib/observable-value.js +52 -0
  114. package/lib/observable-value.js.map +1 -0
  115. package/lib/patch-merge.d.ts +123 -0
  116. package/lib/patch-merge.d.ts.map +1 -0
  117. package/lib/patch-merge.js +104 -0
  118. package/lib/patch-merge.js.map +1 -0
  119. package/lib/profile-session.d.ts +87 -0
  120. package/lib/profile-session.d.ts.map +1 -0
  121. package/lib/profile-session.js +98 -0
  122. package/lib/profile-session.js.map +1 -0
  123. package/lib/profiling.d.ts +83 -0
  124. package/lib/profiling.d.ts.map +1 -0
  125. package/lib/profiling.js +20 -0
  126. package/lib/profiling.js.map +1 -0
  127. package/lib/project.d.ts +121 -0
  128. package/lib/project.d.ts.map +1 -0
  129. package/lib/project.js +34 -0
  130. package/lib/project.js.map +1 -0
  131. package/lib/rpc/bind-rpc-methods.d.ts +100 -0
  132. package/lib/rpc/bind-rpc-methods.d.ts.map +1 -0
  133. package/lib/rpc/bind-rpc-methods.js +110 -0
  134. package/lib/rpc/bind-rpc-methods.js.map +1 -0
  135. package/lib/rpc/create-rpc-proxy.d.ts +188 -0
  136. package/lib/rpc/create-rpc-proxy.d.ts.map +1 -0
  137. package/lib/rpc/create-rpc-proxy.js +158 -0
  138. package/lib/rpc/create-rpc-proxy.js.map +1 -0
  139. package/lib/rpc/index.d.ts +12 -0
  140. package/lib/rpc/index.d.ts.map +1 -0
  141. package/lib/rpc/index.js +31 -0
  142. package/lib/rpc/index.js.map +1 -0
  143. package/lib/rpc/wire-prefix.d.ts +37 -0
  144. package/lib/rpc/wire-prefix.d.ts.map +1 -0
  145. package/lib/rpc/wire-prefix.js +49 -0
  146. package/lib/rpc/wire-prefix.js.map +1 -0
  147. package/lib/testing/data-doubles.d.ts +121 -0
  148. package/lib/testing/data-doubles.d.ts.map +1 -0
  149. package/lib/testing/data-doubles.js +102 -0
  150. package/lib/testing/data-doubles.js.map +1 -0
  151. package/lib/testing/fake-clock.d.ts +35 -0
  152. package/lib/testing/fake-clock.d.ts.map +1 -0
  153. package/lib/testing/fake-clock.js +86 -0
  154. package/lib/testing/fake-clock.js.map +1 -0
  155. package/lib/testing/harness.d.ts +24 -0
  156. package/lib/testing/harness.d.ts.map +1 -0
  157. package/lib/testing/harness.js +11 -0
  158. package/lib/testing/harness.js.map +1 -0
  159. package/lib/testing/index.d.ts +13 -0
  160. package/lib/testing/index.d.ts.map +1 -0
  161. package/lib/testing/index.js +41 -0
  162. package/lib/testing/index.js.map +1 -0
  163. package/lib/testing/node/duplex-connection.d.ts +25 -0
  164. package/lib/testing/node/duplex-connection.d.ts.map +1 -0
  165. package/lib/testing/node/duplex-connection.js +34 -0
  166. package/lib/testing/node/duplex-connection.js.map +1 -0
  167. package/lib/testing/node/duplex-stream.d.ts +32 -0
  168. package/lib/testing/node/duplex-stream.d.ts.map +1 -0
  169. package/lib/testing/node/duplex-stream.js +35 -0
  170. package/lib/testing/node/duplex-stream.js.map +1 -0
  171. package/lib/testing/node/index.d.ts +11 -0
  172. package/lib/testing/node/index.d.ts.map +1 -0
  173. package/lib/testing/node/index.js +37 -0
  174. package/lib/testing/node/index.js.map +1 -0
  175. package/lib/testing/wait-for.d.ts +69 -0
  176. package/lib/testing/wait-for.d.ts.map +1 -0
  177. package/lib/testing/wait-for.js +67 -0
  178. package/lib/testing/wait-for.js.map +1 -0
  179. package/lib/tracer.d.ts +115 -0
  180. package/lib/tracer.d.ts.map +1 -0
  181. package/lib/tracer.js +205 -0
  182. package/lib/tracer.js.map +1 -0
  183. package/lib/transfer-diagnostic.d.ts +73 -0
  184. package/lib/transfer-diagnostic.d.ts.map +1 -0
  185. package/lib/transfer-diagnostic.js +45 -0
  186. package/lib/transfer-diagnostic.js.map +1 -0
  187. package/lib/transfer-document.d.ts +73 -0
  188. package/lib/transfer-document.d.ts.map +1 -0
  189. package/lib/transfer-document.js +46 -0
  190. package/lib/transfer-document.js.map +1 -0
  191. package/lib/transfer-element.d.ts +39 -0
  192. package/lib/transfer-element.d.ts.map +1 -0
  193. package/lib/transfer-element.js +11 -0
  194. package/lib/transfer-element.js.map +1 -0
  195. package/lib/uri.d.ts +62 -0
  196. package/lib/uri.d.ts.map +1 -0
  197. package/lib/uri.js +28 -0
  198. package/lib/uri.js.map +1 -0
  199. package/lib/util.d.ts +147 -0
  200. package/lib/util.d.ts.map +1 -0
  201. package/lib/util.js +211 -0
  202. package/lib/util.js.map +1 -0
  203. package/package.json +100 -0
  204. package/src/abstract-logger.ts +120 -0
  205. package/src/browser-runtime.ts +135 -0
  206. package/src/client/data-events.ts +71 -0
  207. package/src/client/data-port.ts +99 -0
  208. package/src/client/data-session.ts +209 -0
  209. package/src/client/index.ts +40 -0
  210. package/src/client/message-relay.ts +216 -0
  211. package/src/client/post-message-transport.ts +167 -0
  212. package/src/clock.ts +173 -0
  213. package/src/data/data-protocol-methods.ts +79 -0
  214. package/src/data/data-server-protocol.ts +296 -0
  215. package/src/data/diagnostics.ts +116 -0
  216. package/src/data/events.ts +127 -0
  217. package/src/data/index.ts +23 -0
  218. package/src/data/methods.ts +59 -0
  219. package/src/data/requests.ts +70 -0
  220. package/src/debouncer.ts +118 -0
  221. package/src/errors.ts +127 -0
  222. package/src/host-diagnostics.ts +63 -0
  223. package/src/index.ts +41 -0
  224. package/src/latency-collector.ts +231 -0
  225. package/src/logger.ts +172 -0
  226. package/src/model-server.ts +479 -0
  227. package/src/model-service/args.ts +67 -0
  228. package/src/model-service/index.ts +16 -0
  229. package/src/model-service/reference-candidate.ts +58 -0
  230. package/src/noop-logger.ts +36 -0
  231. package/src/observable-value.ts +92 -0
  232. package/src/patch-merge.ts +165 -0
  233. package/src/profile-session.ts +164 -0
  234. package/src/profiling.ts +113 -0
  235. package/src/project.ts +125 -0
  236. package/src/rpc/README.md +163 -0
  237. package/src/rpc/bind-rpc-methods.ts +180 -0
  238. package/src/rpc/create-rpc-proxy.ts +292 -0
  239. package/src/rpc/index.ts +16 -0
  240. package/src/rpc/wire-prefix.ts +48 -0
  241. package/src/testing/data-doubles.ts +178 -0
  242. package/src/testing/fake-clock.ts +106 -0
  243. package/src/testing/harness.ts +24 -0
  244. package/src/testing/index.ts +26 -0
  245. package/src/testing/node/duplex-connection.ts +50 -0
  246. package/src/testing/node/duplex-stream.ts +51 -0
  247. package/src/testing/node/index.ts +22 -0
  248. package/src/testing/wait-for.ts +94 -0
  249. package/src/tracer.ts +277 -0
  250. package/src/transfer-diagnostic.ts +92 -0
  251. package/src/transfer-document.ts +99 -0
  252. package/src/transfer-element.ts +43 -0
  253. package/src/uri.ts +61 -0
  254. package/src/util.ts +250 -0
@@ -0,0 +1,57 @@
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
+ * The shared path identifier under which the data-server exposes its typed
11
+ * RPC methods. Production adopters using vscode-jsonrpc transports use this
12
+ * as the connection-builder path; the data-server side uses it when
13
+ * registering handlers.
14
+ *
15
+ * Distinct from the LSP (`languageId`-routed) and GLSP (`diagram-type`-routed)
16
+ * heads — each protocol head owns its own path namespace.
17
+ */
18
+ export declare const DATA_SERVER_PATH = "/hydranium/data-server";
19
+ /**
20
+ * Wire-name prefix used by `createRpcProxy` and `DataServer`'s
21
+ * handler binding. Every property name on the typed `DataServerProtocol`
22
+ * (or `DataClientProtocol`) interface lowers to `<prefix><methodName>` on
23
+ * the wire — so renaming a TS method renames the wire method,
24
+ * intentionally.
25
+ *
26
+ * Adopters writing custom transports or inspecting the wire derive each
27
+ * wire name as `DATA_SERVER_WIRE_PREFIX + methodName`, where the method
28
+ * names live in `DATA_SERVER_PROTOCOL_METHODS` (request methods) and
29
+ * `DATA_CLIENT_PROTOCOL_METHODS` (notification methods), both exported
30
+ * from `./data-protocol-methods`. The interface (`DataServerProtocol`,
31
+ * `DataClientProtocol`) is the source of truth; the method-name arrays
32
+ * are typed against the interface (`as const satisfies …`) so they
33
+ * cannot drift.
34
+ */
35
+ export declare const DATA_SERVER_WIRE_PREFIX = "data-server/";
36
+ /**
37
+ * Default LSP command id under which a data-server publishes its listening
38
+ * TCP port for client discovery. Parallel to {@link DATA_SERVER_PATH} (the
39
+ * service-path routing constant) — both name the data-server head's transport
40
+ * surface so a simple adopter needs no constants of its own.
41
+ *
42
+ * Two ends reference this id:
43
+ * - PUBLISH (server): the launcher registers the port under this command on
44
+ * the LSP connection —
45
+ * `publishPortOnLspConnection(conn, DATA_SERVER_PORT_COMMAND, port)`.
46
+ * `@hydranium/core`'s `publishPortOnLspConnection` stays command-agnostic
47
+ * (it publishes any port under any command); the adopter passes this
48
+ * constant.
49
+ * - EXTRACT (Theia host): `@hydranium/data-client-theia`'s
50
+ * `DataServerConnectionHandler` polls this command to discover the port —
51
+ * its `portCommand` option defaults to this value.
52
+ *
53
+ * Adopters with an established command id (e.g. `'modelserver:port'`)
54
+ * override both ends.
55
+ */
56
+ export declare const DATA_SERVER_PORT_COMMAND = "hydranium/data-server/port";
57
+ //# sourceMappingURL=methods.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"methods.d.ts","sourceRoot":"","sources":["../../src/data/methods.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF;;;;;;;;GAQG;AACH,eAAO,MAAM,gBAAgB,2BAA2B,CAAC;AAEzD;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,uBAAuB,iBAAiB,CAAC;AAEtD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,wBAAwB,+BAA+B,CAAC"}
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+ /********************************************************************************
3
+ * Copyright (c) 2026 CrossBreeze, EclipseSource and others.
4
+ *
5
+ * This program and the accompanying materials are made available under the
6
+ * terms of the MIT License which is available in the project root.
7
+ *
8
+ * SPDX-License-Identifier: MIT
9
+ ********************************************************************************/
10
+ Object.defineProperty(exports, "__esModule", { value: true });
11
+ exports.DATA_SERVER_PORT_COMMAND = exports.DATA_SERVER_WIRE_PREFIX = exports.DATA_SERVER_PATH = void 0;
12
+ /**
13
+ * The shared path identifier under which the data-server exposes its typed
14
+ * RPC methods. Production adopters using vscode-jsonrpc transports use this
15
+ * as the connection-builder path; the data-server side uses it when
16
+ * registering handlers.
17
+ *
18
+ * Distinct from the LSP (`languageId`-routed) and GLSP (`diagram-type`-routed)
19
+ * heads — each protocol head owns its own path namespace.
20
+ */
21
+ exports.DATA_SERVER_PATH = '/hydranium/data-server';
22
+ /**
23
+ * Wire-name prefix used by `createRpcProxy` and `DataServer`'s
24
+ * handler binding. Every property name on the typed `DataServerProtocol`
25
+ * (or `DataClientProtocol`) interface lowers to `<prefix><methodName>` on
26
+ * the wire — so renaming a TS method renames the wire method,
27
+ * intentionally.
28
+ *
29
+ * Adopters writing custom transports or inspecting the wire derive each
30
+ * wire name as `DATA_SERVER_WIRE_PREFIX + methodName`, where the method
31
+ * names live in `DATA_SERVER_PROTOCOL_METHODS` (request methods) and
32
+ * `DATA_CLIENT_PROTOCOL_METHODS` (notification methods), both exported
33
+ * from `./data-protocol-methods`. The interface (`DataServerProtocol`,
34
+ * `DataClientProtocol`) is the source of truth; the method-name arrays
35
+ * are typed against the interface (`as const satisfies …`) so they
36
+ * cannot drift.
37
+ */
38
+ exports.DATA_SERVER_WIRE_PREFIX = 'data-server/';
39
+ /**
40
+ * Default LSP command id under which a data-server publishes its listening
41
+ * TCP port for client discovery. Parallel to {@link DATA_SERVER_PATH} (the
42
+ * service-path routing constant) — both name the data-server head's transport
43
+ * surface so a simple adopter needs no constants of its own.
44
+ *
45
+ * Two ends reference this id:
46
+ * - PUBLISH (server): the launcher registers the port under this command on
47
+ * the LSP connection —
48
+ * `publishPortOnLspConnection(conn, DATA_SERVER_PORT_COMMAND, port)`.
49
+ * `@hydranium/core`'s `publishPortOnLspConnection` stays command-agnostic
50
+ * (it publishes any port under any command); the adopter passes this
51
+ * constant.
52
+ * - EXTRACT (Theia host): `@hydranium/data-client-theia`'s
53
+ * `DataServerConnectionHandler` polls this command to discover the port —
54
+ * its `portCommand` option defaults to this value.
55
+ *
56
+ * Adopters with an established command id (e.g. `'modelserver:port'`)
57
+ * override both ends.
58
+ */
59
+ exports.DATA_SERVER_PORT_COMMAND = 'hydranium/data-server/port';
60
+ //# sourceMappingURL=methods.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"methods.js","sourceRoot":"","sources":["../../src/data/methods.ts"],"names":[],"mappings":";AAAA;;;;;;;kFAOkF;;;AAElF;;;;;;;;GAQG;AACU,QAAA,gBAAgB,GAAG,wBAAwB,CAAC;AAEzD;;;;;;;;;;;;;;;GAeG;AACU,QAAA,uBAAuB,GAAG,cAAc,CAAC;AAEtD;;;;;;;;;;;;;;;;;;;GAmBG;AACU,QAAA,wBAAwB,GAAG,4BAA4B,CAAC"}
@@ -0,0 +1,65 @@
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
+ import type { TransferSaveArgs, TransferUpdateArgs } from '../model-service/args';
10
+ /** Get the current state of a single document. The server returns the latest built version. */
11
+ export interface GetModelDocumentArgs {
12
+ /** Document URI. */
13
+ uri: string;
14
+ /**
15
+ * When `true`, the response is settled at the validation phase so its
16
+ * `diagnostics` are populated. When `false`/absent, the response returns at
17
+ * the (faster) integrity-settled phase and `diagnostics` may be absent —
18
+ * they are computed asynchronously and delivered via the subscription
19
+ * channel (and, for an LSP head, `publishDiagnostics`).
20
+ *
21
+ * Set this for one-shot / unsubscribed callers (CLI queries, batch checks)
22
+ * that need diagnostics in the response itself. Mirrors Langium's
23
+ * `BuildOptions.validation: boolean`. Note it does not *strip* diagnostics:
24
+ * a document already validated still carries them; the flag only controls
25
+ * whether the read forces/awaits validation.
26
+ */
27
+ includeDiagnostics?: boolean;
28
+ }
29
+ /**
30
+ * Look up the project owning the given document URI. Membership semantics
31
+ * are decided by the server's `ProjectManager` (default in
32
+ * `AbstractProjectManager`: closest-ancestor descriptor folder); the data-
33
+ * server forwards the URI without interpretation.
34
+ */
35
+ export interface GetProjectForUriArgs {
36
+ /** Document URI to look up. */
37
+ uri: string;
38
+ }
39
+ /**
40
+ * Update a document's content. Wire-side projection of the facade's
41
+ * {@link TransferUpdateArgs}; structurally identical so the data-server RPC
42
+ * handler can forward straight to the in-process `ModelService.update`
43
+ * without an args mapping.
44
+ */
45
+ export type TransferUpdateDocumentArgs<TTransfer> = TransferUpdateArgs<TTransfer>;
46
+ /** Persist a document to disk. Wire-side projection of {@link TransferSaveArgs}. */
47
+ export type TransferSaveDocumentArgs<TTransfer> = TransferSaveArgs<TTransfer>;
48
+ /**
49
+ * Identifies a per-document watch on the data server. Shared by both
50
+ * `watchModelDocument` and `unwatchModelDocument` — the `(uri, clientId)`
51
+ * pair is the watch key, so unwatching names the same watch that was
52
+ * started. The `clientId` identifies the originator the same way it does
53
+ * on facade-side mutations (`TransferUpdateArgs.clientId`,
54
+ * `TransferSaveArgs.clientId`): it keys the per-`(uri, clientId)` watch
55
+ * bucket so multiple watchers on the same wire stay distinct, AND it lets
56
+ * each watcher recognise its own echo on inbound `onDocumentUpdated` events
57
+ * (the wire shape's `sourceClientId` carries the originating mutation's
58
+ * `clientId`).
59
+ */
60
+ export interface WatchModelDocumentArgs {
61
+ uri: string;
62
+ /** Stable identifier for the watching client. */
63
+ clientId: string;
64
+ }
65
+ //# sourceMappingURL=requests.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"requests.d.ts","sourceRoot":"","sources":["../../src/data/requests.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,OAAO,KAAK,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAElF,+FAA+F;AAC/F,MAAM,WAAW,oBAAoB;IAClC,oBAAoB;IACpB,GAAG,EAAE,MAAM,CAAC;IACZ;;;;;;;;;;;;OAYG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC/B;AAED;;;;;GAKG;AACH,MAAM,WAAW,oBAAoB;IAClC,+BAA+B;IAC/B,GAAG,EAAE,MAAM,CAAC;CACd;AAED;;;;;GAKG;AACH,MAAM,MAAM,0BAA0B,CAAC,SAAS,IAAI,kBAAkB,CAAC,SAAS,CAAC,CAAC;AAElF,oFAAoF;AACpF,MAAM,MAAM,wBAAwB,CAAC,SAAS,IAAI,gBAAgB,CAAC,SAAS,CAAC,CAAC;AAE9E;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,sBAAsB;IACpC,GAAG,EAAE,MAAM,CAAC;IACZ,iDAAiD;IACjD,QAAQ,EAAE,MAAM,CAAC;CACnB"}
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ /********************************************************************************
3
+ * Copyright (c) 2026 CrossBreeze, EclipseSource and others.
4
+ *
5
+ * This program and the accompanying materials are made available under the
6
+ * terms of the MIT License which is available in the project root.
7
+ *
8
+ * SPDX-License-Identifier: MIT
9
+ ********************************************************************************/
10
+ Object.defineProperty(exports, "__esModule", { value: true });
11
+ //# sourceMappingURL=requests.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"requests.js","sourceRoot":"","sources":["../../src/data/requests.ts"],"names":[],"mappings":";AAAA;;;;;;;kFAOkF"}
@@ -0,0 +1,75 @@
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
+ import { type Clock } from './clock';
10
+ import { ObservableValue, type MaybeObservableValue } from './observable-value';
11
+ import { type Disposable } from './util';
12
+ /** Construction options for {@link Debouncer}. */
13
+ export interface DebouncerOptions {
14
+ /**
15
+ * Trailing-edge delay in milliseconds, read per {@link Debouncer.schedule}
16
+ * so a setting-bound cell reshapes the live window without rebuilding the
17
+ * debouncer. A value `<= 0` still defers to the next tick via
18
+ * {@link Clock.setTimer}; callers wanting a synchronous path handle that
19
+ * themselves before scheduling.
20
+ */
21
+ readonly delayMs: MaybeObservableValue<number>;
22
+ /**
23
+ * Optional starvation ceiling. When calls keep arriving faster than
24
+ * {@link delayMs}, the trailing edge never settles and `fn` would never
25
+ * run; with `maxWaitMs` set, a fire is forced once that many milliseconds
26
+ * have elapsed since the first pending {@link Debouncer.schedule}, so a
27
+ * continuous stream still makes progress. Omitted (the default) = pure
28
+ * trailing edge, which may defer indefinitely under a non-stop stream.
29
+ */
30
+ readonly maxWaitMs?: number;
31
+ }
32
+ /**
33
+ * Trailing-edge debounce built on the injectable {@link Clock}, so the window
34
+ * is deterministically testable with `makeFakeClock` — the framework's timer
35
+ * seam rather than raw `setTimeout` (which `p-debounce` / `lodash.debounce`
36
+ * hold internally and cannot be driven by a fake clock).
37
+ *
38
+ * Owns ONLY timing. {@link fn} is zero-argument and returns nothing: the caller
39
+ * keeps whatever payload it is coalescing — an accumulator set, a "latest
40
+ * value" field — and reads it inside `fn` when the debouncer fires. That
41
+ * timing/payload split is what lets one primitive serve both an accumulating
42
+ * caller (merge changed/deleted sets) and a replacing one (last value wins).
43
+ *
44
+ * Leading-edge invocation and a result-returning ("await the debounced run")
45
+ * variant are deliberately omitted to keep this a pure timing primitive; both
46
+ * are additive later (a `leading` option; a separate promise helper) rather
47
+ * than a breaking change.
48
+ */
49
+ export declare class Debouncer implements Disposable {
50
+ protected readonly clock: Clock;
51
+ protected readonly fn: () => void;
52
+ protected readonly delay: ObservableValue<number>;
53
+ protected readonly maxWaitMs?: number;
54
+ protected timer?: Disposable;
55
+ /** Virtual time of the first {@link schedule} of the current pending window; drives {@link DebouncerOptions.maxWaitMs}. */
56
+ protected firstScheduledAt?: number;
57
+ constructor(clock: Clock, fn: () => void, options: DebouncerOptions);
58
+ /** True while a fire is armed (scheduled, not yet fired or cancelled). */
59
+ get pending(): boolean;
60
+ /**
61
+ * Arm — or re-arm — the trailing-edge timer. Repeated calls within the
62
+ * window collapse into a single {@link fn} run at the trailing edge; with
63
+ * {@link DebouncerOptions.maxWaitMs} set, the run is forced once that ceiling
64
+ * elapses since the first pending call.
65
+ */
66
+ schedule(): void;
67
+ /** If a fire is pending, run {@link fn} now and clear the window; otherwise a no-op. */
68
+ flush(): void;
69
+ /** Drop a pending fire without running {@link fn}. */
70
+ cancel(): void;
71
+ /** Cancel any pending fire and release. */
72
+ dispose(): void;
73
+ protected fire(): void;
74
+ }
75
+ //# sourceMappingURL=debouncer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"debouncer.d.ts","sourceRoot":"","sources":["../src/debouncer.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,OAAO,EAAE,KAAK,KAAK,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,eAAe,EAAE,KAAK,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAChF,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,QAAQ,CAAC;AAEzC,kDAAkD;AAClD,MAAM,WAAW,gBAAgB;IAC9B;;;;;;OAMG;IACH,QAAQ,CAAC,OAAO,EAAE,oBAAoB,CAAC,MAAM,CAAC,CAAC;IAC/C;;;;;;;OAOG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,SAAU,YAAW,UAAU;IAQtC,SAAS,CAAC,QAAQ,CAAC,KAAK,EAAE,KAAK;IAC/B,SAAS,CAAC,QAAQ,CAAC,EAAE,EAAE,MAAM,IAAI;IARpC,SAAS,CAAC,QAAQ,CAAC,KAAK,EAAE,eAAe,CAAC,MAAM,CAAC,CAAC;IAClD,SAAS,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IACtC,SAAS,CAAC,KAAK,CAAC,EAAE,UAAU,CAAC;IAC7B,2HAA2H;IAC3H,SAAS,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;gBAGd,KAAK,EAAE,KAAK,EACZ,EAAE,EAAE,MAAM,IAAI,EACjC,OAAO,EAAE,gBAAgB;IAM5B,0EAA0E;IAC1E,IAAI,OAAO,IAAI,OAAO,CAErB;IAED;;;;;OAKG;IACH,QAAQ,IAAI,IAAI;IAchB,wFAAwF;IACxF,KAAK,IAAI,IAAI;IAMb,sDAAsD;IACtD,MAAM,IAAI,IAAI;IAMd,2CAA2C;IAC3C,OAAO,IAAI,IAAI;IAIf,SAAS,CAAC,IAAI,IAAI,IAAI;CAMxB"}
@@ -0,0 +1,91 @@
1
+ "use strict";
2
+ /********************************************************************************
3
+ * Copyright (c) 2026 CrossBreeze, EclipseSource and others.
4
+ *
5
+ * This program and the accompanying materials are made available under the
6
+ * terms of the MIT License which is available in the project root.
7
+ *
8
+ * SPDX-License-Identifier: MIT
9
+ ********************************************************************************/
10
+ Object.defineProperty(exports, "__esModule", { value: true });
11
+ exports.Debouncer = void 0;
12
+ const observable_value_1 = require("./observable-value");
13
+ /**
14
+ * Trailing-edge debounce built on the injectable {@link Clock}, so the window
15
+ * is deterministically testable with `makeFakeClock` — the framework's timer
16
+ * seam rather than raw `setTimeout` (which `p-debounce` / `lodash.debounce`
17
+ * hold internally and cannot be driven by a fake clock).
18
+ *
19
+ * Owns ONLY timing. {@link fn} is zero-argument and returns nothing: the caller
20
+ * keeps whatever payload it is coalescing — an accumulator set, a "latest
21
+ * value" field — and reads it inside `fn` when the debouncer fires. That
22
+ * timing/payload split is what lets one primitive serve both an accumulating
23
+ * caller (merge changed/deleted sets) and a replacing one (last value wins).
24
+ *
25
+ * Leading-edge invocation and a result-returning ("await the debounced run")
26
+ * variant are deliberately omitted to keep this a pure timing primitive; both
27
+ * are additive later (a `leading` option; a separate promise helper) rather
28
+ * than a breaking change.
29
+ */
30
+ class Debouncer {
31
+ clock;
32
+ fn;
33
+ delay;
34
+ maxWaitMs;
35
+ timer;
36
+ /** Virtual time of the first {@link schedule} of the current pending window; drives {@link DebouncerOptions.maxWaitMs}. */
37
+ firstScheduledAt;
38
+ constructor(clock, fn, options) {
39
+ this.clock = clock;
40
+ this.fn = fn;
41
+ this.delay = observable_value_1.ObservableValue.from(options.delayMs);
42
+ this.maxWaitMs = options.maxWaitMs;
43
+ }
44
+ /** True while a fire is armed (scheduled, not yet fired or cancelled). */
45
+ get pending() {
46
+ return this.timer !== undefined;
47
+ }
48
+ /**
49
+ * Arm — or re-arm — the trailing-edge timer. Repeated calls within the
50
+ * window collapse into a single {@link fn} run at the trailing edge; with
51
+ * {@link DebouncerOptions.maxWaitMs} set, the run is forced once that ceiling
52
+ * elapses since the first pending call.
53
+ */
54
+ schedule() {
55
+ const now = this.clock.now();
56
+ if (this.firstScheduledAt === undefined) {
57
+ this.firstScheduledAt = now;
58
+ }
59
+ let wait = Math.max(0, this.delay.value);
60
+ if (this.maxWaitMs !== undefined) {
61
+ const untilCeiling = this.firstScheduledAt + this.maxWaitMs - now;
62
+ wait = Math.min(wait, Math.max(0, untilCeiling));
63
+ }
64
+ this.timer?.dispose();
65
+ this.timer = this.clock.setTimer(() => this.fire(), wait);
66
+ }
67
+ /** If a fire is pending, run {@link fn} now and clear the window; otherwise a no-op. */
68
+ flush() {
69
+ if (this.timer !== undefined) {
70
+ this.fire();
71
+ }
72
+ }
73
+ /** Drop a pending fire without running {@link fn}. */
74
+ cancel() {
75
+ this.timer?.dispose();
76
+ this.timer = undefined;
77
+ this.firstScheduledAt = undefined;
78
+ }
79
+ /** Cancel any pending fire and release. */
80
+ dispose() {
81
+ this.cancel();
82
+ }
83
+ fire() {
84
+ this.timer?.dispose();
85
+ this.timer = undefined;
86
+ this.firstScheduledAt = undefined;
87
+ this.fn();
88
+ }
89
+ }
90
+ exports.Debouncer = Debouncer;
91
+ //# sourceMappingURL=debouncer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"debouncer.js","sourceRoot":"","sources":["../src/debouncer.ts"],"names":[],"mappings":";AAAA;;;;;;;kFAOkF;;;AAGlF,yDAAgF;AAwBhF;;;;;;;;;;;;;;;;GAgBG;AACH,MAAa,SAAS;IAQG;IACA;IARH,KAAK,CAA0B;IAC/B,SAAS,CAAU;IAC5B,KAAK,CAAc;IAC7B,2HAA2H;IACjH,gBAAgB,CAAU;IAEpC,YACsB,KAAY,EACZ,EAAc,EACjC,OAAyB;QAFN,UAAK,GAAL,KAAK,CAAO;QACZ,OAAE,GAAF,EAAE,CAAY;QAGjC,IAAI,CAAC,KAAK,GAAG,kCAAe,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACnD,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC;IACtC,CAAC;IAED,0EAA0E;IAC1E,IAAI,OAAO;QACR,OAAO,IAAI,CAAC,KAAK,KAAK,SAAS,CAAC;IACnC,CAAC;IAED;;;;;OAKG;IACH,QAAQ;QACL,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC;QAC7B,IAAI,IAAI,CAAC,gBAAgB,KAAK,SAAS,EAAE,CAAC;YACvC,IAAI,CAAC,gBAAgB,GAAG,GAAG,CAAC;QAC/B,CAAC;QACD,IAAI,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACzC,IAAI,IAAI,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;YAChC,MAAM,YAAY,GAAG,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC,SAAS,GAAG,GAAG,CAAC;YAClE,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC,CAAC;QACpD,CAAC;QACD,IAAI,CAAC,KAAK,EAAE,OAAO,EAAE,CAAC;QACtB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,IAAI,CAAC,CAAC;IAC7D,CAAC;IAED,wFAAwF;IACxF,KAAK;QACF,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;YAC5B,IAAI,CAAC,IAAI,EAAE,CAAC;QACf,CAAC;IACJ,CAAC;IAED,sDAAsD;IACtD,MAAM;QACH,IAAI,CAAC,KAAK,EAAE,OAAO,EAAE,CAAC;QACtB,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC;QACvB,IAAI,CAAC,gBAAgB,GAAG,SAAS,CAAC;IACrC,CAAC;IAED,2CAA2C;IAC3C,OAAO;QACJ,IAAI,CAAC,MAAM,EAAE,CAAC;IACjB,CAAC;IAES,IAAI;QACX,IAAI,CAAC,KAAK,EAAE,OAAO,EAAE,CAAC;QACtB,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC;QACvB,IAAI,CAAC,gBAAgB,GAAG,SAAS,CAAC;QAClC,IAAI,CAAC,EAAE,EAAE,CAAC;IACb,CAAC;CACH;AAlED,8BAkEC"}
@@ -0,0 +1,84 @@
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
+ import { ResponseError } from 'vscode-jsonrpc';
10
+ /**
11
+ * Application-specific JSON-RPC error code for {@link ConflictError}.
12
+ * Outside the reserved range (-32768 .. -32000) per JSON-RPC 2.0.
13
+ *
14
+ * The code is the load-bearing identifier across realm boundaries —
15
+ * `code` is a first-class field on the JSON-RPC error envelope and
16
+ * survives wire reconstruction; the custom `Error` subclass name does
17
+ * not.
18
+ */
19
+ export declare const CONFLICT_ERROR_CODE = 1001;
20
+ /**
21
+ * Structured payload carried in {@link ConflictError.data}, and the only place
22
+ * a post-RPC caller can read the version mismatch from.
23
+ */
24
+ export interface ConflictErrorData {
25
+ readonly uri: string;
26
+ /** The based-on version the caller authored against. */
27
+ readonly expected: number;
28
+ /** The server's current text-document version at the time of the throw. */
29
+ readonly actual: number;
30
+ }
31
+ /**
32
+ * Thrown by `ModelService.update` / `ModelService.save` when the caller-
33
+ * supplied based-on version no longer matches the server's current text-
34
+ * document version for the same URI — i.e. the snapshot the caller
35
+ * authored against has been superseded by an intervening edit.
36
+ *
37
+ * Extends vscode-jsonrpc's {@link ResponseError} so the typed
38
+ * {@link ConflictErrorData} payload rides on the standard JSON-RPC
39
+ * error envelope (`code`, `message`, `data`) — all three fields are
40
+ * preserved by RPC reconstruction. Adopters that catch the error on
41
+ * the receiving side of an RPC call read the version mismatch from
42
+ * `err.data` (the instance is reconstructed as a generic
43
+ * `ResponseError`, so subclass getters / fields do not survive).
44
+ *
45
+ * Detection is opt-in via the optional `baseVersion` field on
46
+ * `TransferUpdateArgs` / `TransferSaveArgs`; callers that omit the field get
47
+ * no gating. This mirrors LSP's `OptionalVersionedTextDocumentIdentifier`
48
+ * posture, so headless / CLI / batch tooling with no meaningful based-on
49
+ * version can opt out explicitly.
50
+ *
51
+ * Three reasonable adopter recovery strategies:
52
+ *
53
+ * | Strategy | Use case |
54
+ * |---|---|
55
+ * | Drop + refetch | Form-widget save; user can re-trigger if they still want the edit. |
56
+ * | Refetch + replay user edit | Specific structural edits (`setField`, drag-position). Adopter responsibility. |
57
+ * | Surface to user | Large edits, multi-step transactions. Adopter UI. |
58
+ *
59
+ * The framework provides the **detection**; adopters provide the **policy**.
60
+ * No auto-retry or auto-merge ships by default.
61
+ */
62
+ export declare class ConflictError extends ResponseError<ConflictErrorData> {
63
+ constructor(uri: string, expected: number, actual: number);
64
+ get uri(): string;
65
+ get expected(): number;
66
+ get actual(): number;
67
+ }
68
+ /**
69
+ * Type guard for {@link ConflictError}. Detection ladder:
70
+ *
71
+ * 1. `error.name === 'ConflictError'` — direct in-process throw, no
72
+ * RPC round-trip.
73
+ * 2. `(error as ResponseError).code === CONFLICT_ERROR_CODE` — the
74
+ * canonical wire-side check; the JSON-RPC `code` field is preserved
75
+ * across reconstruction, so any adopter catching after an RPC call
76
+ * hits this branch.
77
+ * 3. `error.message.includes('Stale-based update for ')` — fallback
78
+ * for transports that re-wrap the message and drop the code (rare).
79
+ *
80
+ * `instanceof ConflictError` alone would silently return `false` on the
81
+ * reconstructed shape, so callers do not use it.
82
+ */
83
+ export declare function isConflictError(error: unknown): error is ConflictError;
84
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAE/C;;;;;;;;GAQG;AACH,eAAO,MAAM,mBAAmB,OAAO,CAAC;AAExC;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAC/B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,wDAAwD;IACxD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,2EAA2E;IAC3E,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CAC1B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,qBAAa,aAAc,SAAQ,aAAa,CAAC,iBAAiB,CAAC;gBACpD,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAezD,IAAI,GAAG,IAAI,MAAM,CAEhB;IAED,IAAI,QAAQ,IAAI,MAAM,CAErB;IAED,IAAI,MAAM,IAAI,MAAM,CAEnB;CACH;AAOD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,aAAa,CAYtE"}
package/lib/errors.js ADDED
@@ -0,0 +1,113 @@
1
+ "use strict";
2
+ /********************************************************************************
3
+ * Copyright (c) 2026 CrossBreeze, EclipseSource and others.
4
+ *
5
+ * This program and the accompanying materials are made available under the
6
+ * terms of the MIT License which is available in the project root.
7
+ *
8
+ * SPDX-License-Identifier: MIT
9
+ ********************************************************************************/
10
+ Object.defineProperty(exports, "__esModule", { value: true });
11
+ exports.ConflictError = exports.CONFLICT_ERROR_CODE = void 0;
12
+ exports.isConflictError = isConflictError;
13
+ const vscode_jsonrpc_1 = require("vscode-jsonrpc");
14
+ /**
15
+ * Application-specific JSON-RPC error code for {@link ConflictError}.
16
+ * Outside the reserved range (-32768 .. -32000) per JSON-RPC 2.0.
17
+ *
18
+ * The code is the load-bearing identifier across realm boundaries —
19
+ * `code` is a first-class field on the JSON-RPC error envelope and
20
+ * survives wire reconstruction; the custom `Error` subclass name does
21
+ * not.
22
+ */
23
+ exports.CONFLICT_ERROR_CODE = 1001;
24
+ /**
25
+ * Thrown by `ModelService.update` / `ModelService.save` when the caller-
26
+ * supplied based-on version no longer matches the server's current text-
27
+ * document version for the same URI — i.e. the snapshot the caller
28
+ * authored against has been superseded by an intervening edit.
29
+ *
30
+ * Extends vscode-jsonrpc's {@link ResponseError} so the typed
31
+ * {@link ConflictErrorData} payload rides on the standard JSON-RPC
32
+ * error envelope (`code`, `message`, `data`) — all three fields are
33
+ * preserved by RPC reconstruction. Adopters that catch the error on
34
+ * the receiving side of an RPC call read the version mismatch from
35
+ * `err.data` (the instance is reconstructed as a generic
36
+ * `ResponseError`, so subclass getters / fields do not survive).
37
+ *
38
+ * Detection is opt-in via the optional `baseVersion` field on
39
+ * `TransferUpdateArgs` / `TransferSaveArgs`; callers that omit the field get
40
+ * no gating. This mirrors LSP's `OptionalVersionedTextDocumentIdentifier`
41
+ * posture, so headless / CLI / batch tooling with no meaningful based-on
42
+ * version can opt out explicitly.
43
+ *
44
+ * Three reasonable adopter recovery strategies:
45
+ *
46
+ * | Strategy | Use case |
47
+ * |---|---|
48
+ * | Drop + refetch | Form-widget save; user can re-trigger if they still want the edit. |
49
+ * | Refetch + replay user edit | Specific structural edits (`setField`, drag-position). Adopter responsibility. |
50
+ * | Surface to user | Large edits, multi-step transactions. Adopter UI. |
51
+ *
52
+ * The framework provides the **detection**; adopters provide the **policy**.
53
+ * No auto-retry or auto-merge ships by default.
54
+ */
55
+ class ConflictError extends vscode_jsonrpc_1.ResponseError {
56
+ constructor(uri, expected, actual) {
57
+ super(exports.CONFLICT_ERROR_CODE, `Stale-based update for ${uri}: expected v${expected}, server is at v${actual}`, {
58
+ uri,
59
+ expected,
60
+ actual
61
+ });
62
+ this.name = 'ConflictError';
63
+ // ResponseError's constructor calls `Object.setPrototypeOf(this,
64
+ // ResponseError.prototype)` to keep its own prototype chain intact across
65
+ // transpilation targets; that resets us to ResponseError, hiding the
66
+ // ConflictError-specific getters. Restore the prototype here so
67
+ // `err.uri` / `.expected` / `.actual` resolve through this class.
68
+ Object.setPrototypeOf(this, ConflictError.prototype);
69
+ }
70
+ get uri() {
71
+ return this.data.uri;
72
+ }
73
+ get expected() {
74
+ return this.data.expected;
75
+ }
76
+ get actual() {
77
+ return this.data.actual;
78
+ }
79
+ }
80
+ exports.ConflictError = ConflictError;
81
+ /** Marker substring present in every {@link ConflictError} message, used by
82
+ * {@link isConflictError} as a fallback when a transport re-wraps the error
83
+ * and drops the JSON-RPC code. */
84
+ const CONFLICT_ERROR_MESSAGE_MARKER = 'Stale-based update for ';
85
+ /**
86
+ * Type guard for {@link ConflictError}. Detection ladder:
87
+ *
88
+ * 1. `error.name === 'ConflictError'` — direct in-process throw, no
89
+ * RPC round-trip.
90
+ * 2. `(error as ResponseError).code === CONFLICT_ERROR_CODE` — the
91
+ * canonical wire-side check; the JSON-RPC `code` field is preserved
92
+ * across reconstruction, so any adopter catching after an RPC call
93
+ * hits this branch.
94
+ * 3. `error.message.includes('Stale-based update for ')` — fallback
95
+ * for transports that re-wrap the message and drop the code (rare).
96
+ *
97
+ * `instanceof ConflictError` alone would silently return `false` on the
98
+ * reconstructed shape, so callers do not use it.
99
+ */
100
+ function isConflictError(error) {
101
+ if (!(error instanceof Error)) {
102
+ return false;
103
+ }
104
+ if (error.name === 'ConflictError') {
105
+ return true;
106
+ }
107
+ const code = error.code;
108
+ if (code === exports.CONFLICT_ERROR_CODE) {
109
+ return true;
110
+ }
111
+ return typeof error.message === 'string' && error.message.includes(CONFLICT_ERROR_MESSAGE_MARKER);
112
+ }
113
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":";AAAA;;;;;;;kFAOkF;;;AA2GlF,0CAYC;AArHD,mDAA+C;AAE/C;;;;;;;;GAQG;AACU,QAAA,mBAAmB,GAAG,IAAI,CAAC;AAcxC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,MAAa,aAAc,SAAQ,8BAAgC;IAChE,YAAY,GAAW,EAAE,QAAgB,EAAE,MAAc;QACtD,KAAK,CAAC,2BAAmB,EAAE,0BAA0B,GAAG,eAAe,QAAQ,mBAAmB,MAAM,EAAE,EAAE;YACzG,GAAG;YACH,QAAQ;YACR,MAAM;SACR,CAAC,CAAC;QACH,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;QAC5B,iEAAiE;QACjE,0EAA0E;QAC1E,qEAAqE;QACrE,gEAAgE;QAChE,kEAAkE;QAClE,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,aAAa,CAAC,SAAS,CAAC,CAAC;IACxD,CAAC;IAED,IAAI,GAAG;QACJ,OAAO,IAAI,CAAC,IAAK,CAAC,GAAG,CAAC;IACzB,CAAC;IAED,IAAI,QAAQ;QACT,OAAO,IAAI,CAAC,IAAK,CAAC,QAAQ,CAAC;IAC9B,CAAC;IAED,IAAI,MAAM;QACP,OAAO,IAAI,CAAC,IAAK,CAAC,MAAM,CAAC;IAC5B,CAAC;CACH;AA3BD,sCA2BC;AAED;;mCAEmC;AACnC,MAAM,6BAA6B,GAAG,yBAAyB,CAAC;AAEhE;;;;;;;;;;;;;;GAcG;AACH,SAAgB,eAAe,CAAC,KAAc;IAC3C,IAAI,CAAC,CAAC,KAAK,YAAY,KAAK,CAAC,EAAE,CAAC;QAC7B,OAAO,KAAK,CAAC;IAChB,CAAC;IACD,IAAI,KAAK,CAAC,IAAI,KAAK,eAAe,EAAE,CAAC;QAClC,OAAO,IAAI,CAAC;IACf,CAAC;IACD,MAAM,IAAI,GAAI,KAAyC,CAAC,IAAI,CAAC;IAC7D,IAAI,IAAI,KAAK,2BAAmB,EAAE,CAAC;QAChC,OAAO,IAAI,CAAC;IACf,CAAC;IACD,OAAO,OAAO,KAAK,CAAC,OAAO,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,6BAA6B,CAAC,CAAC;AACrG,CAAC"}
@@ -0,0 +1,58 @@
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
+ * Diagnostics contract for the HOST (parent) process — the Theia backend
11
+ * itself, the process that runs the data-client connection handlers and any
12
+ * in-process services. Distinct from `DataServerDiagnosticsProtocol`,
13
+ * which targets the separate data-server child (the heavy model store): the
14
+ * host process is reached by an ordinary in-process Theia RPC service, NOT over
15
+ * the data-server socket. Universal (`process.memoryUsage()` always works) and
16
+ * cheap, so the framework wires it by default for every host that opts the
17
+ * data-client backend module in.
18
+ *
19
+ * Returns are plain formatted strings — the caller (a command, a log sink, the
20
+ * pod's stdout) decides how to surface them.
21
+ */
22
+ /** Arguments for {@link HostDiagnosticsProtocol.dumpHostState}. */
23
+ export interface DumpHostStateArgs {
24
+ /** Optional label folded into the snapshot heading (e.g. an ISO timestamp). */
25
+ label?: string;
26
+ }
27
+ /** Arguments for {@link HostDiagnosticsProtocol.writeHostHeapSnapshot}. */
28
+ export interface WriteHostHeapSnapshotArgs {
29
+ /** Optional label folded into the snapshot filename. */
30
+ label?: string;
31
+ /** Directory to write into; defaults to the OS temp dir when absent or not present on disk. */
32
+ directory?: string;
33
+ }
34
+ /**
35
+ * Memory diagnostics the running HOST (Theia backend) process exposes. Computed
36
+ * in-process: the snapshots reflect the parent process, the counterpart to the
37
+ * data-server child's `DataServerDiagnosticsProtocol`.
38
+ */
39
+ export interface HostDiagnosticsProtocol {
40
+ /**
41
+ * Capture a host-process memory snapshot — heap, rss, external, V8 limit —
42
+ * and return it formatted. The host hosts no Langium documents, so this is
43
+ * the lighter `formatProcessMemory` view, not `formatServerState`.
44
+ */
45
+ dumpHostState(args: DumpHostStateArgs): Promise<string>;
46
+ /**
47
+ * Write a V8 heap snapshot of the host process to disk (full GC first;
48
+ * briefly pauses the process) and return the absolute file path.
49
+ */
50
+ writeHostHeapSnapshot(args: WriteHostHeapSnapshotArgs): Promise<string>;
51
+ }
52
+ /**
53
+ * Theia service path the host-diagnostics RPC service is registered under. An
54
+ * ordinary in-process backend service (`RpcConnectionHandler`), unlike the
55
+ * socket-forwarded `DATA_SERVER_PATH`.
56
+ */
57
+ export declare const HOST_DIAGNOSTICS_PATH = "/hydranium/host-diagnostics";
58
+ //# sourceMappingURL=host-diagnostics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"host-diagnostics.d.ts","sourceRoot":"","sources":["../src/host-diagnostics.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF;;;;;;;;;;;;GAYG;AAEH,mEAAmE;AACnE,MAAM,WAAW,iBAAiB;IAC/B,+EAA+E;IAC/E,KAAK,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,2EAA2E;AAC3E,MAAM,WAAW,yBAAyB;IACvC,wDAAwD;IACxD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,+FAA+F;IAC/F,SAAS,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;GAIG;AACH,MAAM,WAAW,uBAAuB;IACrC;;;;OAIG;IACH,aAAa,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAExD;;;OAGG;IACH,qBAAqB,CAAC,IAAI,EAAE,yBAAyB,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CAC1E;AAED;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,gCAAgC,CAAC"}