@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,139 @@
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.relayToPostMessageChannel = relayToPostMessageChannel;
12
+ const vscode_jsonrpc_1 = require("vscode-jsonrpc");
13
+ /**
14
+ * Pump JSON-RPC messages between a framed transport and a structured-clone
15
+ * {@link PostMessageChannel}, decoding neither.
16
+ *
17
+ * This is the extension-host half of the hop whose webview half is
18
+ * `createPostMessageTransport`. A webview has no `net`, so the data-server
19
+ * socket can only be held by the extension host; the host therefore has to move
20
+ * whole messages between a Content-Length-framed socket and a pipe that carries
21
+ * objects. Both sides speak the same JSON-RPC, so this moves messages and adds
22
+ * no semantics — there is no re-proxy in between, and `createRpcProxy` on the far
23
+ * side is unaware the relay exists.
24
+ *
25
+ * **No `MessageConnection` is built here, and that is what keeps the module
26
+ * browser-neutral.** A relay is not a JSON-RPC endpoint: it has no requests of
27
+ * its own, so it needs no message queue, hence no vscode-jsonrpc runtime
28
+ * abstraction layer. `reader.listen` / `writer.write` are enough. The caller
29
+ * imports the entrypoint that frames its own transport (`vscode-jsonrpc/node`
30
+ * for a socket) and the RAL that comes with it; this tier stays neutral and is
31
+ * gated so by `npm run check:neutral`. Contrast
32
+ * `@hydranium/data-client-theia`'s `SocketChannelForwarder`, which does build a
33
+ * connection only to borrow its `onClose`, and pays a Theia dependency for the
34
+ * byte coding this shape does not need.
35
+ *
36
+ * **The race this exists to close.** `openTransport` is asynchronous — a real
37
+ * host discovers a port first, then connects — while the clone pipe is usable
38
+ * immediately. `PostMessageChannel.onMessage` is a plain emitter with no replay,
39
+ * so a message sent during the connect window is dropped outright.
40
+ *
41
+ * It is not enough that a disciplined client awaits its own connection before
42
+ * sending: a host builds the far-side connection and hands it back *without*
43
+ * waiting for the relay, so `DataSession`'s very first call — the readiness
44
+ * handshake — is already in flight while the socket is still opening. Dropping
45
+ * that first request presents as a client hanging forever on connect against a
46
+ * perfectly healthy server.
47
+ *
48
+ * So the subscription is taken **synchronously, before the first await**, and
49
+ * buffers; the hand-off then swaps listeners and replays within one turn of the
50
+ * event loop, which is what makes it impossible for a message to be both
51
+ * buffered and forwarded, or to arrive between the two. Replay is FIFO because
52
+ * order is load-bearing — a `getModelDocument` that overtook its own
53
+ * `openModelDocument` would answer against an unopened document.
54
+ * `@hydranium/client-theia`'s `AbstractSocketForwardingConnectionHandler` carries the
55
+ * same fix for the Theia channel transport.
56
+ */
57
+ function relayToPostMessageChannel(channel, openTransport, options = {}) {
58
+ const closeEmitter = new vscode_jsonrpc_1.Emitter();
59
+ const subscriptions = [];
60
+ let transport;
61
+ let disposed = false;
62
+ // Taken before the first await, so nothing the far side sends during the
63
+ // connect window is lost. See the race note above.
64
+ const buffered = [];
65
+ let bufferSubscription = channel.onMessage(message => buffered.push(message));
66
+ const closeFramedSide = () => {
67
+ if (disposed) {
68
+ return;
69
+ }
70
+ closeEmitter.fire();
71
+ };
72
+ const wired = (async () => {
73
+ let opened;
74
+ try {
75
+ opened = await openTransport();
76
+ }
77
+ catch (error) {
78
+ bufferSubscription?.dispose();
79
+ bufferSubscription = undefined;
80
+ buffered.length = 0;
81
+ options.reportError?.(error, 'opening the transport to relay');
82
+ closeFramedSide();
83
+ return false;
84
+ }
85
+ if (disposed) {
86
+ // Disposed while connecting: the transport is ours now, so it is ours
87
+ // to release, or the socket outlives the relay that owns it.
88
+ opened.dispose?.();
89
+ return false;
90
+ }
91
+ transport = opened;
92
+ // Synchronous hand-off: drop the buffering listener, wire both
93
+ // directions, then replay. No await in between, so the event loop cannot
94
+ // interleave a message into the gap.
95
+ bufferSubscription?.dispose();
96
+ bufferSubscription = undefined;
97
+ subscriptions.push(opened.reader.listen(message => channel.post(message)), opened.reader.onClose(() => closeFramedSide()), opened.reader.onError(error => {
98
+ options.reportError?.(error, 'reading from the relayed transport');
99
+ closeFramedSide();
100
+ }), channel.onMessage(message => {
101
+ void opened.writer.write(message).catch((error) => {
102
+ options.reportError?.(error, 'writing to the relayed transport');
103
+ });
104
+ }));
105
+ const onChannelClose = channel.onClose?.(() => dispose());
106
+ if (onChannelClose) {
107
+ subscriptions.push(onChannelClose);
108
+ }
109
+ for (const message of buffered) {
110
+ void opened.writer.write(message).catch((error) => {
111
+ options.reportError?.(error, 'replaying a buffered message to the relayed transport');
112
+ });
113
+ }
114
+ buffered.length = 0;
115
+ return true;
116
+ })();
117
+ function dispose() {
118
+ if (disposed) {
119
+ return;
120
+ }
121
+ disposed = true;
122
+ bufferSubscription?.dispose();
123
+ bufferSubscription = undefined;
124
+ buffered.length = 0;
125
+ for (const subscription of subscriptions) {
126
+ subscription.dispose();
127
+ }
128
+ subscriptions.length = 0;
129
+ transport?.dispose?.();
130
+ transport = undefined;
131
+ closeEmitter.dispose();
132
+ }
133
+ return {
134
+ wired,
135
+ onClose: closeEmitter.event,
136
+ dispose
137
+ };
138
+ }
139
+ //# sourceMappingURL=message-relay.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"message-relay.js","sourceRoot":"","sources":["../../src/client/message-relay.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,77 @@
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 Disposable, type Message, type MessageReader, type MessageWriter } from 'vscode-jsonrpc';
10
+ /**
11
+ * A `postMessage`-shaped pipe: fire-and-forget, structured-clone-only, no
12
+ * framing and no bytes.
13
+ *
14
+ * This is the shape every extension↔webview hop reduces to, and the reason the
15
+ * data head needs a port at all. A webview has no `net`, no reach into the
16
+ * extension host's connection, and nothing but structured clone — so a
17
+ * transport built on it can carry plain data and nothing else.
18
+ *
19
+ * Deliberately minimal, and deliberately not typed against any host's messaging
20
+ * library — a host adapter satisfies it in a few lines over whatever messenger
21
+ * it already has, so a diagram and a form can share one hop, one lifecycle and
22
+ * one dispose rather than opening a second channel for the form.
23
+ */
24
+ export interface PostMessageChannel {
25
+ /**
26
+ * Hand one JSON-RPC message to the other side. Fire-and-forget: delivery
27
+ * failures surface through {@link onClose}, never as a rejection, because
28
+ * `postMessage` has no completion to report.
29
+ */
30
+ post(message: Message): void;
31
+ /** Register for messages arriving from the other side. */
32
+ onMessage(listener: (message: Message) => void): Disposable;
33
+ /**
34
+ * Register for the pipe going away — the webview being disposed, the
35
+ * extension deactivating. Optional: a channel with no observable end simply
36
+ * never fires close, and the reader/writer then rely on their owner's
37
+ * dispose instead.
38
+ */
39
+ onClose?(listener: () => void): Disposable;
40
+ }
41
+ /**
42
+ * A reader/writer pair over a {@link PostMessageChannel}, ready to be handed to
43
+ * `createMessageConnection`.
44
+ *
45
+ * The connection is NOT built here, and that omission is the point:
46
+ * `createMessageConnection`'s message queue needs a vscode-jsonrpc runtime
47
+ * abstraction layer, and only the `/node` and `/browser` entrypoints install
48
+ * one. vscode-jsonrpc 9's package ROOT resolves to the RAL-less common API and
49
+ * throws `No runtime abstraction layer installed` on the first message. Only
50
+ * the host knows which side it is on, so the host imports the matching entry
51
+ * (`/browser` in a webview, `/node` in an extension host) and builds the
52
+ * connection there.
53
+ *
54
+ * Keeping the factory out of this module is also what lets the module stay
55
+ * browser-neutral: it touches only `AbstractMessageReader` /
56
+ * `AbstractMessageWriter` / `Emitter`, none of which need a RAL.
57
+ */
58
+ export interface PostMessageTransport {
59
+ readonly reader: MessageReader;
60
+ readonly writer: MessageWriter;
61
+ /** Release the channel subscriptions. */
62
+ dispose(): void;
63
+ }
64
+ /**
65
+ * Build the reader/writer pair for `channel`.
66
+ *
67
+ * What this buys, and why `DataPort` is shaped the way it is:
68
+ * `createRpcProxy` runs **unchanged** over the result. The typed surface, the
69
+ * `DATA_*_PROTOCOL_METHODS` allowlists and the whole open → watch → update →
70
+ * close sequence are identical in a webview and in a Node extension host,
71
+ * because only the `MessageConnection` the port hands back differs. Terminating
72
+ * JSON-RPC in the extension host and declaring one request type per data-head
73
+ * method is the wrong trade: it hand-maintains a per-method mapping and
74
+ * discards the `as const satisfies keyof` allowlists, which cannot drift.
75
+ */
76
+ export declare function createPostMessageTransport(channel: PostMessageChannel): PostMessageTransport;
77
+ //# sourceMappingURL=post-message-transport.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"post-message-transport.d.ts","sourceRoot":"","sources":["../../src/client/post-message-transport.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,OAAO,EAKJ,KAAK,UAAU,EACf,KAAK,OAAO,EACZ,KAAK,aAAa,EAClB,KAAK,aAAa,EACpB,MAAM,gBAAgB,CAAC;AAExB;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,kBAAkB;IAChC;;;;OAIG;IACH,IAAI,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;IAE7B,0DAA0D;IAC1D,SAAS,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,GAAG,UAAU,CAAC;IAE5D;;;;;OAKG;IACH,OAAO,CAAC,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,UAAU,CAAC;CAC7C;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,WAAW,oBAAoB;IAClC,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC;IAC/B,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC;IAC/B,yCAAyC;IACzC,OAAO,IAAI,IAAI,CAAC;CAClB;AAmED;;;;;;;;;;;GAWG;AACH,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,kBAAkB,GAAG,oBAAoB,CAW5F"}
@@ -0,0 +1,95 @@
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.createPostMessageTransport = createPostMessageTransport;
12
+ const vscode_jsonrpc_1 = require("vscode-jsonrpc");
13
+ /**
14
+ * A `MessageReader` over a {@link PostMessageChannel}.
15
+ *
16
+ * Structured clone moves objects, so there is nothing to frame and nothing to
17
+ * decode — the message arrives as the message.
18
+ */
19
+ class PostMessageReader extends vscode_jsonrpc_1.AbstractMessageReader {
20
+ messageEmitter = new vscode_jsonrpc_1.Emitter();
21
+ subscriptions = [];
22
+ constructor(channel) {
23
+ super();
24
+ this.subscriptions.push(channel.onMessage(message => this.messageEmitter.fire(message)));
25
+ const onClose = channel.onClose?.(() => this.fireClose());
26
+ if (onClose) {
27
+ this.subscriptions.push(onClose);
28
+ }
29
+ }
30
+ listen(callback) {
31
+ return this.messageEmitter.event(callback);
32
+ }
33
+ dispose() {
34
+ super.dispose();
35
+ for (const subscription of this.subscriptions) {
36
+ subscription.dispose();
37
+ }
38
+ this.subscriptions.length = 0;
39
+ this.messageEmitter.dispose();
40
+ }
41
+ }
42
+ /** The dual of {@link PostMessageReader} — one `post` per JSON-RPC message. */
43
+ class PostMessageWriter extends vscode_jsonrpc_1.AbstractMessageWriter {
44
+ channel;
45
+ subscriptions = [];
46
+ constructor(channel) {
47
+ super();
48
+ this.channel = channel;
49
+ const onClose = channel.onClose?.(() => this.fireClose());
50
+ if (onClose) {
51
+ this.subscriptions.push(onClose);
52
+ }
53
+ }
54
+ write(message) {
55
+ this.channel.post(message);
56
+ // `postMessage` reports no completion, so the resolved promise means
57
+ // "handed over", not "delivered". vscode-jsonrpc only needs the former.
58
+ return Promise.resolve();
59
+ }
60
+ end() {
61
+ this.dispose();
62
+ }
63
+ dispose() {
64
+ super.dispose();
65
+ for (const subscription of this.subscriptions) {
66
+ subscription.dispose();
67
+ }
68
+ this.subscriptions.length = 0;
69
+ }
70
+ }
71
+ /**
72
+ * Build the reader/writer pair for `channel`.
73
+ *
74
+ * What this buys, and why `DataPort` is shaped the way it is:
75
+ * `createRpcProxy` runs **unchanged** over the result. The typed surface, the
76
+ * `DATA_*_PROTOCOL_METHODS` allowlists and the whole open → watch → update →
77
+ * close sequence are identical in a webview and in a Node extension host,
78
+ * because only the `MessageConnection` the port hands back differs. Terminating
79
+ * JSON-RPC in the extension host and declaring one request type per data-head
80
+ * method is the wrong trade: it hand-maintains a per-method mapping and
81
+ * discards the `as const satisfies keyof` allowlists, which cannot drift.
82
+ */
83
+ function createPostMessageTransport(channel) {
84
+ const reader = new PostMessageReader(channel);
85
+ const writer = new PostMessageWriter(channel);
86
+ return {
87
+ reader,
88
+ writer,
89
+ dispose() {
90
+ reader.dispose();
91
+ writer.dispose();
92
+ }
93
+ };
94
+ }
95
+ //# sourceMappingURL=post-message-transport.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"post-message-transport.js","sourceRoot":"","sources":["../../src/client/post-message-transport.ts"],"names":[],"mappings":";AAAA;;;;;;;kFAOkF;;AAoJlF,gEAWC;AA7JD,mDASwB;AA4DxB;;;;;GAKG;AACH,MAAM,iBAAkB,SAAQ,sCAAqB;IAC/B,cAAc,GAAG,IAAI,wBAAO,EAAW,CAAC;IACxC,aAAa,GAAiB,EAAE,CAAC;IAEpD,YAAY,OAA2B;QACpC,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QACzF,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;QAC1D,IAAI,OAAO,EAAE,CAAC;YACX,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACpC,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,QAAsB;QAC1B,OAAO,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAC9C,CAAC;IAEQ,OAAO;QACb,KAAK,CAAC,OAAO,EAAE,CAAC;QAChB,KAAK,MAAM,YAAY,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YAC7C,YAAY,CAAC,OAAO,EAAE,CAAC;QAC1B,CAAC;QACD,IAAI,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC;QAC9B,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,CAAC;IACjC,CAAC;CACH;AAED,+EAA+E;AAC/E,MAAM,iBAAkB,SAAQ,sCAAqB;IAGnB;IAFZ,aAAa,GAAiB,EAAE,CAAC;IAEpD,YAA+B,OAA2B;QACvD,KAAK,EAAE,CAAC;QADoB,YAAO,GAAP,OAAO,CAAoB;QAEvD,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;QAC1D,IAAI,OAAO,EAAE,CAAC;YACX,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACpC,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,OAAgB;QACnB,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC3B,qEAAqE;QACrE,wEAAwE;QACxE,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;IAC5B,CAAC;IAED,GAAG;QACA,IAAI,CAAC,OAAO,EAAE,CAAC;IAClB,CAAC;IAEQ,OAAO;QACb,KAAK,CAAC,OAAO,EAAE,CAAC;QAChB,KAAK,MAAM,YAAY,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YAC7C,YAAY,CAAC,OAAO,EAAE,CAAC;QAC1B,CAAC;QACD,IAAI,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC;IACjC,CAAC;CACH;AAED;;;;;;;;;;;GAWG;AACH,SAAgB,0BAA0B,CAAC,OAA2B;IACnE,MAAM,MAAM,GAAG,IAAI,iBAAiB,CAAC,OAAO,CAAC,CAAC;IAC9C,MAAM,MAAM,GAAG,IAAI,iBAAiB,CAAC,OAAO,CAAC,CAAC;IAC9C,OAAO;QACJ,MAAM;QACN,MAAM;QACN,OAAO;YACJ,MAAM,CAAC,OAAO,EAAE,CAAC;YACjB,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,CAAC;KACH,CAAC;AACL,CAAC"}
package/lib/clock.d.ts ADDED
@@ -0,0 +1,111 @@
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 { Disposable } from './util';
10
+ /**
11
+ * Measures how long something takes. Born running at {@link Clock.stopwatch};
12
+ * there is no `start` — you create it at the moment timing begins.
13
+ *
14
+ * Backed by a monotonic source (`performance.now`), so it is sub-millisecond
15
+ * precise and immune to wall-clock jumps (NTP/DST adjustments can make a
16
+ * `Date.now` delta go backwards; a stopwatch cannot). Use this for durations
17
+ * and {@link Clock.now} for "what time is it" (timestamps, TTLs).
18
+ *
19
+ * It holds no scheduled resource and is therefore NOT a {@link Disposable} —
20
+ * the disposable thing is a {@link Clock.setTimer}. Reads are lazy, so a fake
21
+ * clock just answers the current virtual time.
22
+ */
23
+ export interface Stopwatch {
24
+ /** Total elapsed since creation; live while running, frozen after {@link stop}. */
25
+ readonly elapsedMs: number;
26
+ /**
27
+ * Split: the elapsed since the previous `lap` (or since creation for the
28
+ * first call), starting a new split. Non-destructive — the running total
29
+ * ({@link elapsedMs}) is unaffected, so `lap` is not a restart.
30
+ */
31
+ lap(): number;
32
+ /**
33
+ * Freeze and return the grand total (the sum of every lap plus the tail
34
+ * since the last lap). Idempotent: further calls return the same value and
35
+ * {@link elapsedMs} stops advancing.
36
+ */
37
+ stop(): number;
38
+ }
39
+ /**
40
+ * Injectable time, so logic gated on time (debounce windows, slow-update
41
+ * warnings, request timeouts, the self-save TTL) is deterministically
42
+ * testable instead of waiting on real wall-clock. The {@link SystemClock}
43
+ * default delegates to the platform; tests bind `makeFakeClock`.
44
+ *
45
+ * Two distinct readings on purpose: {@link now} is wall-clock (for timestamps
46
+ * and TTLs that compare against a file's mtime), while {@link stopwatch}
47
+ * measures durations off a monotonic source. They are different clocks; do not
48
+ * subtract two {@link now} readings to measure a duration.
49
+ *
50
+ * A cross-head contract, so it carries no platform or DI-framework coupling.
51
+ *
52
+ * Note: the runtime health monitors (event-loop, memory) intentionally keep
53
+ * the real wall-clock rather than taking a `Clock` — faking the time they
54
+ * measure would invert their meaning.
55
+ */
56
+ export interface Clock {
57
+ /** Current wall-clock time in milliseconds (the `Date.now` reading). */
58
+ now(): number;
59
+ /**
60
+ * Run `callback` after `ms` have elapsed; the returned {@link Disposable}
61
+ * cancels it if disposed before it fires. This is the testable
62
+ * `setTimeout` — debounce, deferred slow-warn, request timeouts.
63
+ */
64
+ setTimer(callback: () => void, ms: number): Disposable;
65
+ /** Start measuring a duration. See {@link Stopwatch}. */
66
+ stopwatch(): Stopwatch;
67
+ /**
68
+ * Run `callback` and return its result together with how long it took.
69
+ * Sugar over {@link stopwatch} — pure measurement, no logging and no
70
+ * threshold gating (unlike `Tracer.time`). Use in
71
+ * measurement pipelines that consume `elapsedMs` directly. Async callbacks
72
+ * return a Promise of the same shape, timed across the full settle.
73
+ */
74
+ measure<T>(callback: () => Promise<T>): Promise<Timed<T>>;
75
+ measure<T>(callback: () => T): Timed<T>;
76
+ }
77
+ /**
78
+ * The result of {@link Clock.measure}: a callback's return value paired with
79
+ * its elapsed wall-time in milliseconds. A plain value object — no methods, no
80
+ * logging — deliberately distinct from `@theia/core`'s `Measurement` (a
81
+ * stateful self-logging handle), which would collide in a Theia process.
82
+ */
83
+ export interface Timed<T> {
84
+ /**
85
+ * The callback's return value, unchanged. For an async callback this is the
86
+ * settled value rather than the promise — and a callback that REJECTS
87
+ * produces no `Timed` at all, because the rejection propagates, so a failed
88
+ * run cannot be timed through this shape.
89
+ */
90
+ result: T;
91
+ /**
92
+ * Milliseconds off the monotonic source, so it is comparable with
93
+ * {@link Stopwatch.elapsedMs} and NOT with a difference of two
94
+ * {@link Clock.now} readings. For an async callback it spans the full settle,
95
+ * not just the synchronous prefix.
96
+ */
97
+ elapsedMs: number;
98
+ }
99
+ /**
100
+ * Default {@link Clock}: delegates to the platform's `Date.now`,
101
+ * `performance.now`, and `setTimeout`/`clearTimeout`. Bound everywhere in
102
+ * production; swapped for `makeFakeClock` in tests.
103
+ */
104
+ export declare class SystemClock implements Clock {
105
+ now(): number;
106
+ setTimer(callback: () => void, ms: number): Disposable;
107
+ stopwatch(): Stopwatch;
108
+ measure<T>(callback: () => Promise<T>): Promise<Timed<T>>;
109
+ measure<T>(callback: () => T): Timed<T>;
110
+ }
111
+ //# sourceMappingURL=clock.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clock.d.ts","sourceRoot":"","sources":["../src/clock.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAEpC;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,SAAS;IACvB,mFAAmF;IACnF,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B;;;;OAIG;IACH,GAAG,IAAI,MAAM,CAAC;IACd;;;;OAIG;IACH,IAAI,IAAI,MAAM,CAAC;CACjB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,WAAW,KAAK;IACnB,wEAAwE;IACxE,GAAG,IAAI,MAAM,CAAC;IACd;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,EAAE,MAAM,IAAI,EAAE,EAAE,EAAE,MAAM,GAAG,UAAU,CAAC;IACvD,yDAAyD;IACzD,SAAS,IAAI,SAAS,CAAC;IACvB;;;;;;OAMG;IACH,OAAO,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1D,OAAO,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;CAC1C;AAED;;;;;GAKG;AACH,MAAM,WAAW,KAAK,CAAC,CAAC;IACrB;;;;;OAKG;IACH,MAAM,EAAE,CAAC,CAAC;IACV;;;;;OAKG;IACH,SAAS,EAAE,MAAM,CAAC;CACpB;AAyCD;;;;GAIG;AACH,qBAAa,WAAY,YAAW,KAAK;IACtC,GAAG,IAAI,MAAM;IAIb,QAAQ,CAAC,QAAQ,EAAE,MAAM,IAAI,EAAE,EAAE,EAAE,MAAM,GAAG,UAAU;IAMtD,SAAS,IAAI,SAAS;IAItB,OAAO,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACzD,OAAO,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC;CASzC"}
package/lib/clock.js ADDED
@@ -0,0 +1,74 @@
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.SystemClock = void 0;
12
+ const util_1 = require("./util");
13
+ class SystemStopwatch {
14
+ start = performance.now();
15
+ lastLap = this.start;
16
+ stopped;
17
+ get elapsedMs() {
18
+ return (this.stopped ?? performance.now()) - this.start;
19
+ }
20
+ lap() {
21
+ const at = this.stopped ?? performance.now();
22
+ const split = at - this.lastLap;
23
+ this.lastLap = at;
24
+ return split;
25
+ }
26
+ stop() {
27
+ if (this.stopped === undefined) {
28
+ this.stopped = performance.now();
29
+ }
30
+ return this.stopped - this.start;
31
+ }
32
+ }
33
+ /**
34
+ * Detach a timer from the event loop so a single pending timer never keeps a
35
+ * Node process alive — a CLI run or test worker can exit cleanly while deferred
36
+ * work (debounce, slow-warn, idle CST eviction) is still scheduled; the
37
+ * persistent server connection keeps the loop alive in production regardless.
38
+ *
39
+ * `unref` is Node-only. {@link SystemClock} also runs in the browser, where
40
+ * `setTimeout` returns a bare numeric handle with no `unref` — the optional
41
+ * call is a no-op there, and declaring the parameter's `unref` optional accepts
42
+ * a Node `NodeJS.Timeout` structurally without a cast.
43
+ */
44
+ function unrefTimer(handle) {
45
+ handle.unref?.();
46
+ }
47
+ /**
48
+ * Default {@link Clock}: delegates to the platform's `Date.now`,
49
+ * `performance.now`, and `setTimeout`/`clearTimeout`. Bound everywhere in
50
+ * production; swapped for `makeFakeClock` in tests.
51
+ */
52
+ class SystemClock {
53
+ now() {
54
+ return Date.now();
55
+ }
56
+ setTimer(callback, ms) {
57
+ const handle = setTimeout(callback, ms);
58
+ unrefTimer(handle);
59
+ return util_1.Disposable.create(() => clearTimeout(handle));
60
+ }
61
+ stopwatch() {
62
+ return new SystemStopwatch();
63
+ }
64
+ measure(callback) {
65
+ const stopwatch = this.stopwatch();
66
+ const result = callback();
67
+ if (result instanceof Promise) {
68
+ return result.then(value => ({ result: value, elapsedMs: stopwatch.elapsedMs }));
69
+ }
70
+ return { result: result, elapsedMs: stopwatch.elapsedMs };
71
+ }
72
+ }
73
+ exports.SystemClock = SystemClock;
74
+ //# sourceMappingURL=clock.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clock.js","sourceRoot":"","sources":["../src/clock.ts"],"names":[],"mappings":";AAAA;;;;;;;kFAOkF;;;AAElF,iCAAoC;AA8FpC,MAAM,eAAe;IACC,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;IACnC,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC;IACrB,OAAO,CAAqB;IAEtC,IAAI,SAAS;QACV,OAAO,CAAC,IAAI,CAAC,OAAO,IAAI,WAAW,CAAC,GAAG,EAAE,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC;IAC3D,CAAC;IAED,GAAG;QACA,MAAM,EAAE,GAAG,IAAI,CAAC,OAAO,IAAI,WAAW,CAAC,GAAG,EAAE,CAAC;QAC7C,MAAM,KAAK,GAAG,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC;QAChC,IAAI,CAAC,OAAO,GAAG,EAAE,CAAC;QAClB,OAAO,KAAK,CAAC;IAChB,CAAC;IAED,IAAI;QACD,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;YAC9B,IAAI,CAAC,OAAO,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;QACpC,CAAC;QACD,OAAO,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC;IACpC,CAAC;CACH;AAED;;;;;;;;;;GAUG;AACH,SAAS,UAAU,CAAC,MAA8B;IAC/C,MAAM,CAAC,KAAK,EAAE,EAAE,CAAC;AACpB,CAAC;AAED;;;;GAIG;AACH,MAAa,WAAW;IACrB,GAAG;QACA,OAAO,IAAI,CAAC,GAAG,EAAE,CAAC;IACrB,CAAC;IAED,QAAQ,CAAC,QAAoB,EAAE,EAAU;QACtC,MAAM,MAAM,GAAG,UAAU,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QACxC,UAAU,CAAC,MAAM,CAAC,CAAC;QACnB,OAAO,iBAAU,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC;IACxD,CAAC;IAED,SAAS;QACN,OAAO,IAAI,eAAe,EAAE,CAAC;IAChC,CAAC;IAID,OAAO,CAAI,QAA8B;QACtC,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;QACnC,MAAM,MAAM,GAAG,QAAQ,EAAE,CAAC;QAC1B,IAAI,MAAM,YAAY,OAAO,EAAE,CAAC;YAC7B,OAAQ,MAAqB,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,SAAS,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;QACpG,CAAC;QACD,OAAO,EAAE,MAAM,EAAE,MAAW,EAAE,SAAS,EAAE,SAAS,CAAC,SAAS,EAAE,CAAC;IAClE,CAAC;CACH;AAzBD,kCAyBC"}
@@ -0,0 +1,39 @@
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
+ /** Request-method names on {@link DocumentServerProtocol}. */
10
+ export declare const DOCUMENT_SERVER_PROTOCOL_METHODS: readonly ["openModelDocument", "closeModelDocument", "getModelDocument", "updateModelDocument", "saveModelDocument", "watchModelDocument", "unwatchModelDocument", "waitForReady"];
11
+ /** Request-method names on {@link ProjectServerProtocol}. */
12
+ export declare const PROJECT_SERVER_PROTOCOL_METHODS: readonly ["getProjects", "getProjectForUri"];
13
+ /**
14
+ * Request-method names on the composed {@link DataServerProtocol} — the
15
+ * document fragment followed by the project fragment. The `as const satisfies`
16
+ * constraint makes the array typed against the interface — stale names (typos,
17
+ * renamed methods) fail to typecheck.
18
+ */
19
+ export declare const DATA_SERVER_PROTOCOL_METHODS: readonly ["openModelDocument", "closeModelDocument", "getModelDocument", "updateModelDocument", "saveModelDocument", "watchModelDocument", "unwatchModelDocument", "waitForReady", "getProjects", "getProjectForUri"];
20
+ /**
21
+ * Request-method names on {@link ReferenceServerProtocol}. NOT part of
22
+ * {@link DATA_SERVER_PROTOCOL_METHODS} — adopters that compose the reference
23
+ * fragment register these alongside (e.g. via a `DataServer` subclass's
24
+ * `additionalMethods`).
25
+ */
26
+ export declare const REFERENCE_SERVER_PROTOCOL_METHODS: readonly ["findReferenceCandidates", "resolveReference", "findNextName"];
27
+ /** Notification-method names on {@link DocumentClientProtocol}. */
28
+ export declare const DOCUMENT_CLIENT_PROTOCOL_METHODS: readonly ["onDocumentUpdated", "onDocumentSaved"];
29
+ /** Notification-method names on {@link ProjectClientProtocol}. */
30
+ export declare const PROJECT_CLIENT_PROTOCOL_METHODS: readonly ["onProjectsChanged"];
31
+ /**
32
+ * Notification-method names on the composed {@link DataClientProtocol}.
33
+ * Passed as the `localMethods` allowlist to `createRpcProxy` (frontend) /
34
+ * `bindRpcMethods` (backend) when binding inbound `on*` notifications — the
35
+ * data head's connection routes `<methodNamespace>onDocumentUpdated` etc. to
36
+ * the bound client target.
37
+ */
38
+ export declare const DATA_CLIENT_PROTOCOL_METHODS: readonly ["onDocumentUpdated", "onDocumentSaved", "onProjectsChanged"];
39
+ //# sourceMappingURL=data-protocol-methods.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data-protocol-methods.d.ts","sourceRoot":"","sources":["../../src/data/data-protocol-methods.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAalF,8DAA8D;AAC9D,eAAO,MAAM,gCAAgC,oLAS6C,CAAC;AAE3F,6DAA6D;AAC7D,eAAO,MAAM,+BAA+B,8CAE3C,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,4BAA4B,uNAG6C,CAAC;AAEvF;;;;;GAKG;AACH,eAAO,MAAM,iCAAiC,0EAI6C,CAAC;AAE5F,mEAAmE;AACnE,eAAO,MAAM,gCAAgC,mDAE5C,CAAC;AAEF,kEAAkE;AAClE,eAAO,MAAM,+BAA+B,gCAA+F,CAAC;AAE5I;;;;;;GAMG;AACH,eAAO,MAAM,4BAA4B,wEAG6C,CAAC"}
@@ -0,0 +1,61 @@
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_CLIENT_PROTOCOL_METHODS = exports.PROJECT_CLIENT_PROTOCOL_METHODS = exports.DOCUMENT_CLIENT_PROTOCOL_METHODS = exports.REFERENCE_SERVER_PROTOCOL_METHODS = exports.DATA_SERVER_PROTOCOL_METHODS = exports.PROJECT_SERVER_PROTOCOL_METHODS = exports.DOCUMENT_SERVER_PROTOCOL_METHODS = void 0;
12
+ /** Request-method names on {@link DocumentServerProtocol}. */
13
+ exports.DOCUMENT_SERVER_PROTOCOL_METHODS = [
14
+ 'openModelDocument',
15
+ 'closeModelDocument',
16
+ 'getModelDocument',
17
+ 'updateModelDocument',
18
+ 'saveModelDocument',
19
+ 'watchModelDocument',
20
+ 'unwatchModelDocument',
21
+ 'waitForReady'
22
+ ];
23
+ /** Request-method names on {@link ProjectServerProtocol}. */
24
+ exports.PROJECT_SERVER_PROTOCOL_METHODS = ['getProjects', 'getProjectForUri'];
25
+ /**
26
+ * Request-method names on the composed {@link DataServerProtocol} — the
27
+ * document fragment followed by the project fragment. The `as const satisfies`
28
+ * constraint makes the array typed against the interface — stale names (typos,
29
+ * renamed methods) fail to typecheck.
30
+ */
31
+ exports.DATA_SERVER_PROTOCOL_METHODS = [
32
+ ...exports.DOCUMENT_SERVER_PROTOCOL_METHODS,
33
+ ...exports.PROJECT_SERVER_PROTOCOL_METHODS
34
+ ];
35
+ /**
36
+ * Request-method names on {@link ReferenceServerProtocol}. NOT part of
37
+ * {@link DATA_SERVER_PROTOCOL_METHODS} — adopters that compose the reference
38
+ * fragment register these alongside (e.g. via a `DataServer` subclass's
39
+ * `additionalMethods`).
40
+ */
41
+ exports.REFERENCE_SERVER_PROTOCOL_METHODS = [
42
+ 'findReferenceCandidates',
43
+ 'resolveReference',
44
+ 'findNextName'
45
+ ];
46
+ /** Notification-method names on {@link DocumentClientProtocol}. */
47
+ exports.DOCUMENT_CLIENT_PROTOCOL_METHODS = ['onDocumentUpdated', 'onDocumentSaved'];
48
+ /** Notification-method names on {@link ProjectClientProtocol}. */
49
+ exports.PROJECT_CLIENT_PROTOCOL_METHODS = ['onProjectsChanged'];
50
+ /**
51
+ * Notification-method names on the composed {@link DataClientProtocol}.
52
+ * Passed as the `localMethods` allowlist to `createRpcProxy` (frontend) /
53
+ * `bindRpcMethods` (backend) when binding inbound `on*` notifications — the
54
+ * data head's connection routes `<methodNamespace>onDocumentUpdated` etc. to
55
+ * the bound client target.
56
+ */
57
+ exports.DATA_CLIENT_PROTOCOL_METHODS = [
58
+ ...exports.DOCUMENT_CLIENT_PROTOCOL_METHODS,
59
+ ...exports.PROJECT_CLIENT_PROTOCOL_METHODS
60
+ ];
61
+ //# sourceMappingURL=data-protocol-methods.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data-protocol-methods.js","sourceRoot":"","sources":["../../src/data/data-protocol-methods.ts"],"names":[],"mappings":";AAAA;;;;;;;kFAOkF;;;AAalF,8DAA8D;AACjD,QAAA,gCAAgC,GAAG;IAC7C,mBAAmB;IACnB,oBAAoB;IACpB,kBAAkB;IAClB,qBAAqB;IACrB,mBAAmB;IACnB,oBAAoB;IACpB,sBAAsB;IACtB,cAAc;CACyE,CAAC;AAE3F,6DAA6D;AAChD,QAAA,+BAA+B,GAAG,CAAC,aAAa,EAAE,kBAAkB,CAEhF,CAAC;AAEF;;;;;GAKG;AACU,QAAA,4BAA4B,GAAG;IACzC,GAAG,wCAAgC;IACnC,GAAG,uCAA+B;CACiD,CAAC;AAEvF;;;;;GAKG;AACU,QAAA,iCAAiC,GAAG;IAC9C,yBAAyB;IACzB,kBAAkB;IAClB,cAAc;CAC0E,CAAC;AAE5F,mEAAmE;AACtD,QAAA,gCAAgC,GAAG,CAAC,mBAAmB,EAAE,iBAAiB,CAEtF,CAAC;AAEF,kEAAkE;AACrD,QAAA,+BAA+B,GAAG,CAAC,mBAAmB,CAAwE,CAAC;AAE5I;;;;;;GAMG;AACU,QAAA,4BAA4B,GAAG;IACzC,GAAG,wCAAgC;IACnC,GAAG,uCAA+B;CACiD,CAAC"}