@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 @@
1
+ {"version":3,"file":"data-port.d.ts","sourceRoot":"","sources":["../../src/client/data-port.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,OAAO,KAAK,EAAE,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAE/D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,MAAM,WAAW,QAAQ;IACtB;;;;;;;;;;;;;OAaG;IACH,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAE1B;;;;;;;OAOG;IACH,OAAO,IAAI,OAAO,CAAC,iBAAiB,CAAC,CAAC;IAEtC;;;;;;;;OAQG;IACH,WAAW,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAEnD;;;;;;;;;;;;OAYG;IACH,QAAQ,CAAC,SAAS,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;CAClC"}
@@ -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=data-port.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data-port.js","sourceRoot":"","sources":["../../src/client/data-port.ts"],"names":[],"mappings":";AAAA;;;;;;;kFAOkF"}
@@ -0,0 +1,129 @@
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 { MessageConnection } from 'vscode-jsonrpc';
10
+ import { type DataClientProtocol, type DataServerProtocol } from '../data';
11
+ import { type RpcProxy } from '../rpc';
12
+ import type { TransferDocument } from '../transfer-document';
13
+ import type { TransferElement } from '../transfer-element';
14
+ import type { DataPort } from './data-port';
15
+ /** Options for {@link DataSession}. */
16
+ export interface DataSessionOptions {
17
+ /**
18
+ * Wire namespace the server is addressed under. Defaults to the
19
+ * framework's {@link DATA_SERVER_WIRE_PREFIX}, which is what an unmodified
20
+ * `DataServer` binds. Override only alongside the server's own
21
+ * `methodNamespace` option — a mismatch turns every request into
22
+ * "Unhandled method" rather than failing at wire-up.
23
+ */
24
+ readonly methodNamespace?: string;
25
+ }
26
+ /** One connection generation: its connection, its proxy, and its readiness. */
27
+ interface Generation<TTransfer extends TransferElement> {
28
+ readonly connection: Promise<MessageConnection>;
29
+ readonly server: RpcProxy<DataServerProtocol<TTransfer>>;
30
+ /** Set on first use; the shared readiness gate for this generation. */
31
+ ready?: Promise<void>;
32
+ }
33
+ /**
34
+ * The host-invariant half of talking to the data head: everything above
35
+ * {@link DataPort} that would otherwise be re-derived by every host
36
+ * adapter.
37
+ *
38
+ * Three jobs, and deliberately no fourth:
39
+ *
40
+ * 1. **Build the typed proxy** over the port's connection, with the framework's
41
+ * wire prefix and its drift-proof client-method allowlist.
42
+ * 2. **Own the readiness gate** — `waitForReady` once per connection, shared
43
+ * across concurrent callers. A socket client can connect before the
44
+ * workspace walk finishes, and an early request is then answered correctly
45
+ * from an empty registry, which reads as a broken project tier rather than
46
+ * as a race.
47
+ * 3. **Own the reconnect policy**, by dropping its connection generation when
48
+ * the port disposes and building a fresh one on the next request.
49
+ *
50
+ * It does **not** wrap the protocol methods; callers reach them through
51
+ * {@link connected}. The one exception is {@link openDocument}, which exists
52
+ * because the open/watch *order* is silently wrong the other way round — see
53
+ * its own doc.
54
+ *
55
+ * Generic over the transfer root so this file names no grammar. An adopter
56
+ * binds the concrete root (or the union of them, for a multi-grammar head) at
57
+ * its own edge.
58
+ */
59
+ export declare class DataSession<TTransfer extends TransferElement> {
60
+ protected readonly port: DataPort;
61
+ protected readonly client: DataClientProtocol<TTransfer>;
62
+ protected readonly methodNamespace: string;
63
+ /** The current generation, or `undefined` before the first request / after a teardown. */
64
+ protected generation?: Generation<TTransfer>;
65
+ protected disposed: boolean;
66
+ protected readonly portDisposeListener: {
67
+ dispose(): void;
68
+ };
69
+ constructor(port: DataPort, client: DataClientProtocol<TTransfer>, options?: DataSessionOptions);
70
+ /** The identity every request is made under — the port's, not a second one. */
71
+ get clientId(): string;
72
+ /**
73
+ * The connected, READY server proxy.
74
+ *
75
+ * Returns the proxy rather than `void` on purpose. A reconnect replaces the
76
+ * proxy, so a caller that cached one from an earlier call would go on
77
+ * addressing a dead connection with no error — handing it back per call
78
+ * makes the stale reference unrepresentable.
79
+ *
80
+ * Concurrent callers share one readiness promise, so `waitForReady` is
81
+ * awaited once per generation and not once per caller.
82
+ */
83
+ connected(): Promise<RpcProxy<DataServerProtocol<TTransfer>>>;
84
+ /**
85
+ * Open `uri` for editing and start watching it, in that order, returning
86
+ * the opened snapshot.
87
+ *
88
+ * **The order is the whole reason this method exists.**
89
+ * `watchModelDocument` baselines its dedup fingerprint from the *current*
90
+ * document, but only if one exists. Watching first therefore leaves no
91
+ * baseline, and the first phase event after the open arrives as a spurious
92
+ * `'changed'` — which a widget that resets its in-memory root to the server
93
+ * view misreads as a concurrent third-party write, losing whatever the user
94
+ * had typed. Nothing about the wrong order fails loudly, so it is encoded
95
+ * here rather than documented and re-derived.
96
+ *
97
+ * Note that the returned snapshot's empty `diagnostics` does not mean
98
+ * valid: `open` settles at the integrity landmark, not at validation.
99
+ * Validity arrives asynchronously on `onDocumentUpdated`, or synchronously
100
+ * from `getModelDocument({ includeDiagnostics: true })`.
101
+ */
102
+ openDocument(uri: string): Promise<TransferDocument<TTransfer>>;
103
+ /**
104
+ * Close `uri`. The server unwatches implicitly, so this is the dual of
105
+ * {@link openDocument} and needs no separate unwatch.
106
+ */
107
+ closeDocument(uri: string): Promise<void>;
108
+ /**
109
+ * Whether `event.sourceClientId` identifies this session's own write.
110
+ *
111
+ * Every watcher needs this and the check is one comparison, so getting it
112
+ * wrong is cheap to do and expensive to find: an unfiltered echo looks
113
+ * exactly like a concurrent third-party edit.
114
+ */
115
+ isOwnEcho(sourceClientId: string): boolean;
116
+ /** Tear down the current connection and stop tracking the port. Idempotent. */
117
+ dispose(): void;
118
+ /** The live generation, building one if there is none. */
119
+ protected currentGeneration(): Generation<TTransfer>;
120
+ /** Await the connection and the server's startup gate for one generation. */
121
+ protected awaitReady(generation: Generation<TTransfer>): Promise<void>;
122
+ /**
123
+ * Discard the current generation, disposing its connection if it opened.
124
+ * The next {@link connected} builds a fresh one.
125
+ */
126
+ protected dropGeneration(): void;
127
+ }
128
+ export {};
129
+ //# sourceMappingURL=data-session.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data-session.d.ts","sourceRoot":"","sources":["../../src/client/data-session.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAyD,KAAK,kBAAkB,EAAE,KAAK,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAClI,OAAO,EAAE,KAAK,QAAQ,EAAkB,MAAM,QAAQ,CAAC;AACvD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE5C,uCAAuC;AACvC,MAAM,WAAW,kBAAkB;IAChC;;;;;;OAMG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;CACpC;AAED,+EAA+E;AAC/E,UAAU,UAAU,CAAC,SAAS,SAAS,eAAe;IACnD,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC,iBAAiB,CAAC,CAAC;IAChD,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC,CAAC;IACzD,uEAAuE;IACvE,KAAK,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,qBAAa,WAAW,CAAC,SAAS,SAAS,eAAe;IAQpD,SAAS,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ;IACjC,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,kBAAkB,CAAC,SAAS,CAAC;IAR3D,SAAS,CAAC,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IAC3C,0FAA0F;IAC1F,SAAS,CAAC,UAAU,CAAC,EAAE,UAAU,CAAC,SAAS,CAAC,CAAC;IAC7C,SAAS,CAAC,QAAQ,UAAS;IAC3B,SAAS,CAAC,QAAQ,CAAC,mBAAmB,EAAE;QAAE,OAAO,IAAI,IAAI,CAAA;KAAE,CAAC;gBAGtC,IAAI,EAAE,QAAQ,EACd,MAAM,EAAE,kBAAkB,CAAC,SAAS,CAAC,EACxD,OAAO,GAAE,kBAAuB;IAMnC,+EAA+E;IAC/E,IAAI,QAAQ,IAAI,MAAM,CAErB;IAED;;;;;;;;;;OAUG;IACG,SAAS,IAAI,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC,CAAC;IAYnE;;;;;;;;;;;;;;;;;OAiBG;IACG,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC;IAOrE;;;OAGG;IACG,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAK/C;;;;;;OAMG;IACH,SAAS,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO;IAI1C,+EAA+E;IAC/E,OAAO,IAAI,IAAI;IASf,0DAA0D;IAC1D,SAAS,CAAC,iBAAiB,IAAI,UAAU,CAAC,SAAS,CAAC;IAkBpD,6EAA6E;cAC7D,UAAU,CAAC,UAAU,EAAE,UAAU,CAAC,SAAS,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAe5E;;;OAGG;IACH,SAAS,CAAC,cAAc,IAAI,IAAI;CAQlC"}
@@ -0,0 +1,179 @@
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.DataSession = void 0;
12
+ const data_1 = require("../data");
13
+ const rpc_1 = require("../rpc");
14
+ /**
15
+ * The host-invariant half of talking to the data head: everything above
16
+ * {@link DataPort} that would otherwise be re-derived by every host
17
+ * adapter.
18
+ *
19
+ * Three jobs, and deliberately no fourth:
20
+ *
21
+ * 1. **Build the typed proxy** over the port's connection, with the framework's
22
+ * wire prefix and its drift-proof client-method allowlist.
23
+ * 2. **Own the readiness gate** — `waitForReady` once per connection, shared
24
+ * across concurrent callers. A socket client can connect before the
25
+ * workspace walk finishes, and an early request is then answered correctly
26
+ * from an empty registry, which reads as a broken project tier rather than
27
+ * as a race.
28
+ * 3. **Own the reconnect policy**, by dropping its connection generation when
29
+ * the port disposes and building a fresh one on the next request.
30
+ *
31
+ * It does **not** wrap the protocol methods; callers reach them through
32
+ * {@link connected}. The one exception is {@link openDocument}, which exists
33
+ * because the open/watch *order* is silently wrong the other way round — see
34
+ * its own doc.
35
+ *
36
+ * Generic over the transfer root so this file names no grammar. An adopter
37
+ * binds the concrete root (or the union of them, for a multi-grammar head) at
38
+ * its own edge.
39
+ */
40
+ class DataSession {
41
+ port;
42
+ client;
43
+ methodNamespace;
44
+ /** The current generation, or `undefined` before the first request / after a teardown. */
45
+ generation;
46
+ disposed = false;
47
+ portDisposeListener;
48
+ constructor(port, client, options = {}) {
49
+ this.port = port;
50
+ this.client = client;
51
+ this.methodNamespace = options.methodNamespace ?? data_1.DATA_SERVER_WIRE_PREFIX;
52
+ this.portDisposeListener = this.port.onDispose(() => this.dropGeneration());
53
+ }
54
+ /** The identity every request is made under — the port's, not a second one. */
55
+ get clientId() {
56
+ return this.port.clientId;
57
+ }
58
+ /**
59
+ * The connected, READY server proxy.
60
+ *
61
+ * Returns the proxy rather than `void` on purpose. A reconnect replaces the
62
+ * proxy, so a caller that cached one from an earlier call would go on
63
+ * addressing a dead connection with no error — handing it back per call
64
+ * makes the stale reference unrepresentable.
65
+ *
66
+ * Concurrent callers share one readiness promise, so `waitForReady` is
67
+ * awaited once per generation and not once per caller.
68
+ */
69
+ async connected() {
70
+ if (this.disposed) {
71
+ throw new Error('DataSession is disposed');
72
+ }
73
+ const generation = this.currentGeneration();
74
+ if (!generation.ready) {
75
+ generation.ready = this.awaitReady(generation);
76
+ }
77
+ await generation.ready;
78
+ return generation.server;
79
+ }
80
+ /**
81
+ * Open `uri` for editing and start watching it, in that order, returning
82
+ * the opened snapshot.
83
+ *
84
+ * **The order is the whole reason this method exists.**
85
+ * `watchModelDocument` baselines its dedup fingerprint from the *current*
86
+ * document, but only if one exists. Watching first therefore leaves no
87
+ * baseline, and the first phase event after the open arrives as a spurious
88
+ * `'changed'` — which a widget that resets its in-memory root to the server
89
+ * view misreads as a concurrent third-party write, losing whatever the user
90
+ * had typed. Nothing about the wrong order fails loudly, so it is encoded
91
+ * here rather than documented and re-derived.
92
+ *
93
+ * Note that the returned snapshot's empty `diagnostics` does not mean
94
+ * valid: `open` settles at the integrity landmark, not at validation.
95
+ * Validity arrives asynchronously on `onDocumentUpdated`, or synchronously
96
+ * from `getModelDocument({ includeDiagnostics: true })`.
97
+ */
98
+ async openDocument(uri) {
99
+ const server = await this.connected();
100
+ const document = await server.openModelDocument({ uri, clientId: this.clientId });
101
+ await server.watchModelDocument({ uri, clientId: this.clientId });
102
+ return document;
103
+ }
104
+ /**
105
+ * Close `uri`. The server unwatches implicitly, so this is the dual of
106
+ * {@link openDocument} and needs no separate unwatch.
107
+ */
108
+ async closeDocument(uri) {
109
+ const server = await this.connected();
110
+ await server.closeModelDocument({ uri, clientId: this.clientId });
111
+ }
112
+ /**
113
+ * Whether `event.sourceClientId` identifies this session's own write.
114
+ *
115
+ * Every watcher needs this and the check is one comparison, so getting it
116
+ * wrong is cheap to do and expensive to find: an unfiltered echo looks
117
+ * exactly like a concurrent third-party edit.
118
+ */
119
+ isOwnEcho(sourceClientId) {
120
+ return sourceClientId === this.clientId;
121
+ }
122
+ /** Tear down the current connection and stop tracking the port. Idempotent. */
123
+ dispose() {
124
+ if (this.disposed) {
125
+ return;
126
+ }
127
+ this.disposed = true;
128
+ this.portDisposeListener.dispose();
129
+ this.dropGeneration();
130
+ }
131
+ /** The live generation, building one if there is none. */
132
+ currentGeneration() {
133
+ if (this.generation) {
134
+ return this.generation;
135
+ }
136
+ const connection = this.port.connect();
137
+ // Rejection is reported here rather than left to float: an unhandled
138
+ // rejection on a connection promise is the failure mode that reads as
139
+ // "the model is empty" instead of "the transport never opened".
140
+ connection.catch((error) => this.port.reportError(error, 'connecting to the data server'));
141
+ const server = (0, rpc_1.createRpcProxy)(connection, {
142
+ methodNamespace: this.methodNamespace,
143
+ localTarget: this.client,
144
+ localMethods: data_1.DATA_CLIENT_PROTOCOL_METHODS
145
+ });
146
+ this.generation = { connection, server };
147
+ return this.generation;
148
+ }
149
+ /** Await the connection and the server's startup gate for one generation. */
150
+ async awaitReady(generation) {
151
+ try {
152
+ await generation.connection;
153
+ await generation.server.waitForReady();
154
+ }
155
+ catch (error) {
156
+ // Drop the generation so the next request retries rather than
157
+ // re-awaiting a settled rejection forever.
158
+ if (this.generation === generation) {
159
+ this.generation = undefined;
160
+ }
161
+ this.port.reportError(error, 'waiting for the data server to become ready');
162
+ throw error;
163
+ }
164
+ }
165
+ /**
166
+ * Discard the current generation, disposing its connection if it opened.
167
+ * The next {@link connected} builds a fresh one.
168
+ */
169
+ dropGeneration() {
170
+ const generation = this.generation;
171
+ this.generation = undefined;
172
+ if (!generation) {
173
+ return;
174
+ }
175
+ generation.connection.then(connection => connection.dispose()).catch(() => undefined);
176
+ }
177
+ }
178
+ exports.DataSession = DataSession;
179
+ //# sourceMappingURL=data-session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data-session.js","sourceRoot":"","sources":["../../src/client/data-session.ts"],"names":[],"mappings":"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"}
@@ -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
+ /**
10
+ * Subpath barrel for `@hydranium/protocol/client` — the **host-neutral client
11
+ * tier** of the data head.
12
+ *
13
+ * Where `./data` is the wire *contract* and `./rpc` is the machinery that lowers
14
+ * it onto a connection, this is what a client wraps around both: the seam a host
15
+ * fills in (`DataPort`), the lifecycle above it (`DataSession` —
16
+ * readiness gate, open/watch ordering, echo recognition, reconnect), the inbound
17
+ * fan-out (`DataEvents`), and the two halves of the hop for hosts whose
18
+ * client cannot hold a socket — `createPostMessageTransport` on the client
19
+ * side and `relayToPostMessageChannel` on the side that does hold it.
20
+ *
21
+ * **Neutral, and gate-enforced so.** Nothing here imports a host package or a
22
+ * Node builtin, which is what lets one client tier serve a Theia frontend, a VS
23
+ * Code extension host, a VS Code webview and a plain browser app. `npm run
24
+ * check:neutral` bundles these modules for the browser; `scripts/check-neutral-bundles.mjs`
25
+ * carries the entries.
26
+ *
27
+ * The Theia-specific mounting of the same contract lives in
28
+ * `@hydranium/data-client-theia`: its `AbstractDataServiceFrontend` solves the
29
+ * same problem against Theia's channel transport, and its `EmitterDataClient`
30
+ * is the Theia-bound counterpart of `DataEvents`. Prefer this tier for
31
+ * anything new, and reach for the Theia package only for what genuinely needs
32
+ * Theia DI.
33
+ */
34
+ export * from './data-events';
35
+ export * from './data-port';
36
+ export * from './data-session';
37
+ export * from './message-relay';
38
+ export * from './post-message-transport';
39
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC;AAChC,cAAc,0BAA0B,CAAC"}
@@ -0,0 +1,55 @@
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
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ var desc = Object.getOwnPropertyDescriptor(m, k);
13
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
14
+ desc = { enumerable: true, get: function() { return m[k]; } };
15
+ }
16
+ Object.defineProperty(o, k2, desc);
17
+ }) : (function(o, m, k, k2) {
18
+ if (k2 === undefined) k2 = k;
19
+ o[k2] = m[k];
20
+ }));
21
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
22
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
23
+ };
24
+ Object.defineProperty(exports, "__esModule", { value: true });
25
+ /**
26
+ * Subpath barrel for `@hydranium/protocol/client` — the **host-neutral client
27
+ * tier** of the data head.
28
+ *
29
+ * Where `./data` is the wire *contract* and `./rpc` is the machinery that lowers
30
+ * it onto a connection, this is what a client wraps around both: the seam a host
31
+ * fills in (`DataPort`), the lifecycle above it (`DataSession` —
32
+ * readiness gate, open/watch ordering, echo recognition, reconnect), the inbound
33
+ * fan-out (`DataEvents`), and the two halves of the hop for hosts whose
34
+ * client cannot hold a socket — `createPostMessageTransport` on the client
35
+ * side and `relayToPostMessageChannel` on the side that does hold it.
36
+ *
37
+ * **Neutral, and gate-enforced so.** Nothing here imports a host package or a
38
+ * Node builtin, which is what lets one client tier serve a Theia frontend, a VS
39
+ * Code extension host, a VS Code webview and a plain browser app. `npm run
40
+ * check:neutral` bundles these modules for the browser; `scripts/check-neutral-bundles.mjs`
41
+ * carries the entries.
42
+ *
43
+ * The Theia-specific mounting of the same contract lives in
44
+ * `@hydranium/data-client-theia`: its `AbstractDataServiceFrontend` solves the
45
+ * same problem against Theia's channel transport, and its `EmitterDataClient`
46
+ * is the Theia-bound counterpart of `DataEvents`. Prefer this tier for
47
+ * anything new, and reach for the Theia package only for what genuinely needs
48
+ * Theia DI.
49
+ */
50
+ __exportStar(require("./data-events"), exports);
51
+ __exportStar(require("./data-port"), exports);
52
+ __exportStar(require("./data-session"), exports);
53
+ __exportStar(require("./message-relay"), exports);
54
+ __exportStar(require("./post-message-transport"), exports);
55
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":";AAAA;;;;;;;kFAOkF;;;;;;;;;;;;;;;;AAElF;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,gDAA8B;AAC9B,8CAA4B;AAC5B,iDAA+B;AAC/B,kDAAgC;AAChC,2DAAyC"}
@@ -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 { type Disposable, type Event, type MessageReader, type MessageWriter } from 'vscode-jsonrpc';
10
+ import type { PostMessageChannel } from './post-message-transport';
11
+ /**
12
+ * The framed side of a relay: the reader/writer pair over whatever transport the
13
+ * host actually holds — a TCP socket to the data-server, a child process' stdio,
14
+ * a websocket.
15
+ *
16
+ * Structurally the same pair `PostMessageTransport` exposes, and
17
+ * deliberately so: either can stand on either side of a relay. What differs is
18
+ * only who owns the framing, which is why this tier never needs to know.
19
+ */
20
+ export interface RelayTransport {
21
+ readonly reader: MessageReader;
22
+ readonly writer: MessageWriter;
23
+ /** Release the transport. Called when the relay is disposed. */
24
+ dispose?(): void;
25
+ }
26
+ /** Options for {@link relayToPostMessageChannel}. */
27
+ export interface MessageRelayOptions {
28
+ /**
29
+ * Surface a failure the way the host does. Same contract as
30
+ * `DataPort.reportError`: `context` names what was being attempted.
31
+ *
32
+ * A relay has no other way to report — it sits between two transports and
33
+ * owns neither, so a swallowed error here presents as a form that never
34
+ * populates.
35
+ */
36
+ readonly reportError?: (error: unknown, context: string) => void;
37
+ }
38
+ /** A live relay. Dispose to tear both directions down. */
39
+ export interface MessageRelay extends Disposable {
40
+ /**
41
+ * Resolves `true` once messages are flowing in both directions, `false` if
42
+ * opening the framed transport failed or the relay was disposed first.
43
+ *
44
+ * It resolves rather than rejects on failure so that a caller which never
45
+ * awaits it cannot produce an unhandled rejection; the error itself goes to
46
+ * {@link MessageRelayOptions.reportError}. Tests await it to get a
47
+ * deterministic "wiring is done" edge instead of polling.
48
+ */
49
+ readonly wired: Promise<boolean>;
50
+ /**
51
+ * Fires when the framed side goes away — the data-server exiting, the socket
52
+ * erroring, a language-server restart taking its ports with it.
53
+ *
54
+ * **The relay cannot propagate this to the clone hop itself**, and the host
55
+ * has to. {@link PostMessageChannel} is deliberately an input-only contract:
56
+ * it offers `onClose` for observing the pipe but no `close()` for ending it,
57
+ * because a webview's pipe belongs to the webview's lifecycle, not to
58
+ * whoever relays over it. So a framed-side death is invisible to the far
59
+ * end, whose pending requests would otherwise hang forever with no rejection
60
+ * — the far side's `MessageConnection` sees an open pipe and no answer. On
61
+ * this event a host disposes the webview, reloads it, or sends its own
62
+ * "connection lost" notification; doing nothing is the one wrong choice.
63
+ */
64
+ readonly onClose: Event<void>;
65
+ }
66
+ /**
67
+ * Pump JSON-RPC messages between a framed transport and a structured-clone
68
+ * {@link PostMessageChannel}, decoding neither.
69
+ *
70
+ * This is the extension-host half of the hop whose webview half is
71
+ * `createPostMessageTransport`. A webview has no `net`, so the data-server
72
+ * socket can only be held by the extension host; the host therefore has to move
73
+ * whole messages between a Content-Length-framed socket and a pipe that carries
74
+ * objects. Both sides speak the same JSON-RPC, so this moves messages and adds
75
+ * no semantics — there is no re-proxy in between, and `createRpcProxy` on the far
76
+ * side is unaware the relay exists.
77
+ *
78
+ * **No `MessageConnection` is built here, and that is what keeps the module
79
+ * browser-neutral.** A relay is not a JSON-RPC endpoint: it has no requests of
80
+ * its own, so it needs no message queue, hence no vscode-jsonrpc runtime
81
+ * abstraction layer. `reader.listen` / `writer.write` are enough. The caller
82
+ * imports the entrypoint that frames its own transport (`vscode-jsonrpc/node`
83
+ * for a socket) and the RAL that comes with it; this tier stays neutral and is
84
+ * gated so by `npm run check:neutral`. Contrast
85
+ * `@hydranium/data-client-theia`'s `SocketChannelForwarder`, which does build a
86
+ * connection only to borrow its `onClose`, and pays a Theia dependency for the
87
+ * byte coding this shape does not need.
88
+ *
89
+ * **The race this exists to close.** `openTransport` is asynchronous — a real
90
+ * host discovers a port first, then connects — while the clone pipe is usable
91
+ * immediately. `PostMessageChannel.onMessage` is a plain emitter with no replay,
92
+ * so a message sent during the connect window is dropped outright.
93
+ *
94
+ * It is not enough that a disciplined client awaits its own connection before
95
+ * sending: a host builds the far-side connection and hands it back *without*
96
+ * waiting for the relay, so `DataSession`'s very first call — the readiness
97
+ * handshake — is already in flight while the socket is still opening. Dropping
98
+ * that first request presents as a client hanging forever on connect against a
99
+ * perfectly healthy server.
100
+ *
101
+ * So the subscription is taken **synchronously, before the first await**, and
102
+ * buffers; the hand-off then swaps listeners and replays within one turn of the
103
+ * event loop, which is what makes it impossible for a message to be both
104
+ * buffered and forwarded, or to arrive between the two. Replay is FIFO because
105
+ * order is load-bearing — a `getModelDocument` that overtook its own
106
+ * `openModelDocument` would answer against an unopened document.
107
+ * `@hydranium/client-theia`'s `AbstractSocketForwardingConnectionHandler` carries the
108
+ * same fix for the Theia channel transport.
109
+ */
110
+ export declare function relayToPostMessageChannel(channel: PostMessageChannel, openTransport: () => Promise<RelayTransport>, options?: MessageRelayOptions): MessageRelay;
111
+ //# sourceMappingURL=message-relay.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"message-relay.d.ts","sourceRoot":"","sources":["../../src/client/message-relay.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,OAAO,EAAW,KAAK,UAAU,EAAE,KAAK,KAAK,EAAgB,KAAK,aAAa,EAAE,KAAK,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC5H,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAEnE;;;;;;;;GAQG;AACH,MAAM,WAAW,cAAc;IAC5B,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC;IAC/B,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC;IAC/B,gEAAgE;IAChE,OAAO,CAAC,IAAI,IAAI,CAAC;CACnB;AAED,qDAAqD;AACrD,MAAM,WAAW,mBAAmB;IACjC;;;;;;;OAOG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACnE;AAED,0DAA0D;AAC1D,MAAM,WAAW,YAAa,SAAQ,UAAU;IAC7C;;;;;;;;OAQG;IACH,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;IAEjC;;;;;;;;;;;;;OAaG;IACH,QAAQ,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;CAChC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AACH,wBAAgB,yBAAyB,CACtC,OAAO,EAAE,kBAAkB,EAC3B,aAAa,EAAE,MAAM,OAAO,CAAC,cAAc,CAAC,EAC5C,OAAO,GAAE,mBAAwB,GACjC,YAAY,CAgGd"}