@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,67 @@
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.waitFor = waitFor;
12
+ exports.tick = tick;
13
+ /**
14
+ * Resolve once `predicate()` returns true, polling at `intervalMs`; reject with
15
+ * `message` once `timeoutMs` elapses. The **non-racy** alternative to a fixed
16
+ * sleep for awaiting an asynchronous side effect that lands on an observable
17
+ * value.
18
+ *
19
+ * It resolves the instant the condition holds, so it is *faster* than a fixed
20
+ * delay on the happy path, and tolerates a slow event loop up to `timeoutMs`, so
21
+ * it does not flake under parallel CI where a fixed `setTimeout` can be starved
22
+ * past the test timeout.
23
+ *
24
+ * @example
25
+ * await proxy.updateModelDocument({ uri, clientId, model });
26
+ * await waitFor(() => harness.events.length === 1); // the notification crossed
27
+ * expect(harness.events[0].document.uri).toBe(uri);
28
+ */
29
+ function waitFor(predicate, options = {}) {
30
+ const timeoutMs = options.timeoutMs ?? 2000;
31
+ const intervalMs = options.intervalMs ?? 5;
32
+ const message = options.message ?? `Timed out after ${timeoutMs}ms waiting for a condition`;
33
+ if (predicate()) {
34
+ return Promise.resolve();
35
+ }
36
+ return new Promise((resolve, reject) => {
37
+ const deadline = setTimeout(() => {
38
+ clearInterval(poll);
39
+ reject(new Error(message));
40
+ }, timeoutMs);
41
+ const poll = setInterval(() => {
42
+ if (predicate()) {
43
+ clearInterval(poll);
44
+ clearTimeout(deadline);
45
+ resolve();
46
+ }
47
+ }, intervalMs);
48
+ });
49
+ }
50
+ /**
51
+ * Yield the event loop for `ms` (default 10). The bounded counterpart to
52
+ * {@link waitFor}, for the rare assertion that something has NOT happened — a
53
+ * *negative* you cannot poll positively. Give async delivery a real chance to
54
+ * (wrongly) occur, then assert it did not.
55
+ *
56
+ * A fixed yield is unavoidable here, but the failure mode is a false-green, not
57
+ * the flaky-red a fixed delay causes on a positive wait.
58
+ *
59
+ * @example
60
+ * await proxy.saveModelDocument({ uri, clientId, model }); // no subscriber yet
61
+ * await tick(); // give a (wrongly) fired event a chance to land
62
+ * expect(savedEvents).toHaveLength(0); // assert the ABSENCE
63
+ */
64
+ function tick(ms = 10) {
65
+ return new Promise(resolve => setTimeout(resolve, ms));
66
+ }
67
+ //# sourceMappingURL=wait-for.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wait-for.js","sourceRoot":"","sources":["../../src/testing/wait-for.ts"],"names":[],"mappings":";AAAA;;;;;;;kFAOkF;;AAgDlF,0BAoBC;AAgBD,oBAEC;AAtDD;;;;;;;;;;;;;;;GAeG;AACH,SAAgB,OAAO,CAAC,SAAwB,EAAE,UAA0B,EAAE;IAC3E,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,IAAI,CAAC;IAC5C,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,CAAC,CAAC;IAC3C,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,mBAAmB,SAAS,4BAA4B,CAAC;IAC5F,IAAI,SAAS,EAAE,EAAE,CAAC;QACf,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;IAC5B,CAAC;IACD,OAAO,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QAC1C,MAAM,QAAQ,GAAG,UAAU,CAAC,GAAG,EAAE;YAC9B,aAAa,CAAC,IAAI,CAAC,CAAC;YACpB,MAAM,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;QAC9B,CAAC,EAAE,SAAS,CAAC,CAAC;QACd,MAAM,IAAI,GAAG,WAAW,CAAC,GAAG,EAAE;YAC3B,IAAI,SAAS,EAAE,EAAE,CAAC;gBACf,aAAa,CAAC,IAAI,CAAC,CAAC;gBACpB,YAAY,CAAC,QAAQ,CAAC,CAAC;gBACvB,OAAO,EAAE,CAAC;YACb,CAAC;QACJ,CAAC,EAAE,UAAU,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;AACN,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,SAAgB,IAAI,CAAC,EAAE,GAAG,EAAE;IACzB,OAAO,IAAI,OAAO,CAAO,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;AAChE,CAAC"}
@@ -0,0 +1,115 @@
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 { Logger, type LogThreshold } from './logger';
11
+ import { type ProfileSession } from './profile-session';
12
+ import { Disposable } from './util';
13
+ /** Ops completing before this threshold are silent on success — only failures emit a retroactive start. */
14
+ export declare const DEFER_START_MS = 5;
15
+ /** Optional settings for {@link Tracer.time}. */
16
+ export interface TimeOptions {
17
+ /** Defer the [start] line until the op has run this long. Set to 0 to always log. */
18
+ logAfterMs?: number;
19
+ /** Called with the correlation id before the op runs. */
20
+ captureId?: (id: number) => void;
21
+ /** Extra context included in the status brackets. Read on each emit so callers can mutate. */
22
+ tags?: string[];
23
+ /** Server-only: force the memory suffix on [done] when elapsed >= this many ms, ignoring the delta gate. */
24
+ forceMemoryAboveMs?: number;
25
+ }
26
+ /** Platform-specific heap readout. Returns `undefined` where unavailable (e.g. a browser outside Chromium). */
27
+ export interface MemoryInfo {
28
+ /** Bytes currently in use (heap used / `usedJSHeapSize`). */
29
+ usedBytes: number;
30
+ /** Optional capacity for a "used / total" rendering (heap total / `totalJSHeapSize`). */
31
+ totalBytes?: number;
32
+ }
33
+ /** Reads the current process/heap memory. The single per-head piece of {@link DefaultTracer}. */
34
+ export type MemoryReader = () => MemoryInfo | undefined;
35
+ /**
36
+ * Cross-head observability handle: everything a {@link Logger} does (emission,
37
+ * threshold gating, component-prefix derivation) **plus** timing an operation,
38
+ * reading memory, and opening aggregate {@link ProfileSession}s.
39
+ *
40
+ * `Tracer extends Logger` so a service that both logs and times holds a single
41
+ * handle (`this.tracer.debug(...)` / `this.tracer.time(...)`), and a Tracer is
42
+ * usable anywhere a Logger is wanted. The emission-only {@link Logger} stays
43
+ * the lean default for consumers that only log.
44
+ *
45
+ * The variance lives in the loggers (per-platform emit sinks); the Tracer
46
+ * **composes** a Logger and forwards emission to it, so one
47
+ * {@link DefaultTracer} serves every head with no per-platform subclass. The
48
+ * {@link for}/{@link sub}/{@link with}/{@link withUri} derivations produce a
49
+ * child Tracer over the correspondingly-derived logger, so
50
+ * `tracer.withUri(uri).time(...)` emits through that logger's rendering.
51
+ */
52
+ export interface Tracer extends Logger {
53
+ /** Read process/heap memory and emit it as a log line. Platform-specific via {@link MemoryReader}. */
54
+ memory(label?: string, logLevel?: LogThreshold): void;
55
+ /**
56
+ * Run `callback`, emit start / completion / failure with timings. Zero-cost
57
+ * when `logLevel` is suppressed (incl. `'off'`).
58
+ *
59
+ * A success completing under {@link TimeOptions.logAfterMs} is **silent** —
60
+ * this is "tell me when it is slow", not "record every occurrence". A caller
61
+ * that wants an unconditional per-occurrence line composes it from
62
+ * `Clock.measure` instead.
63
+ */
64
+ time<T>(label: string, callback: () => T, logLevel?: LogThreshold, options?: TimeOptions): T;
65
+ /** Start a deferred-start timer that logs elapsed on dispose. Zero-cost when `logLevel` is suppressed (incl. `'off'`). */
66
+ startTimer(label: string, logLevel?: LogThreshold, logAfterMs?: number): Disposable;
67
+ /** Open an aggregating self-time {@link ProfileSession} that dumps through the bound Logger. */
68
+ profile(identifier: string): ProfileSession;
69
+ /** Derive a child Tracer with `component` as the logger prefix. */
70
+ for(component: string): this;
71
+ /** Derive a child Tracer deepening the `Foo :: bar` prefix chain. */
72
+ sub(component: string): this;
73
+ /** Derive a child Tracer appending `component` as a separate `[a] [b]` bracket. */
74
+ with(component: string): this;
75
+ /** Derive a child Tracer labelled with the given URI (subclasses may render workspace-relative). */
76
+ withUri(uri: string): this;
77
+ }
78
+ /**
79
+ * Default cross-head {@link Tracer}. One concrete class serves every head:
80
+ * emission delegates to the composed {@link Logger}, timing/profiling go
81
+ * through the injected {@link Clock}, and the only per-head varying piece is
82
+ * the {@link MemoryReader} (default: none — heads that log memory pass a
83
+ * reader, or subclass for richer rendering, as the server's `ServerTracer`
84
+ * does). The `time` / `startTimer` bodies are zero-cost when the level is
85
+ * suppressed: the callback runs directly and no stopwatch / timer / id is
86
+ * allocated.
87
+ */
88
+ export declare class DefaultTracer implements Tracer {
89
+ protected readonly logger: Logger;
90
+ protected readonly clock: Clock;
91
+ protected readonly readMemory: MemoryReader;
92
+ constructor(logger?: Logger, clock?: Clock, readMemory?: MemoryReader);
93
+ error(message?: string, ...args: unknown[]): this;
94
+ warn(message?: string, ...args: unknown[]): this;
95
+ info(message?: string, ...args: unknown[]): this;
96
+ debug(message?: string, ...args: unknown[]): this;
97
+ trace(message?: string, ...args: unknown[]): this;
98
+ log(message?: string, ...args: unknown[]): this;
99
+ logAt(threshold: LogThreshold, message: string): this;
100
+ memory(label?: string, logLevel?: LogThreshold): void;
101
+ time<T>(label: string, callback: () => T, logLevel?: LogThreshold, options?: TimeOptions): T;
102
+ startTimer(label: string, logLevel?: LogThreshold, logAfterMs?: number): Disposable;
103
+ profile(identifier: string): ProfileSession;
104
+ for(component: string): this;
105
+ sub(component: string): this;
106
+ with(component: string): this;
107
+ withUri(uri: string): this;
108
+ /** Construct a sibling Tracer over a derived logger, preserving the concrete subclass. */
109
+ protected derive(logger: Logger): this;
110
+ /** Hook for appending status-bracket suffixes like memory deltas. Default: none. */
111
+ protected timingSuffix(_status: 'done' | 'failed' | 'cancelled', _elapsedMs: number, _options: TimeOptions): string;
112
+ /** Hook to differentiate cancelled operations from failures. Default: all errors are failures. */
113
+ protected categorizeError(_error: unknown): 'failed' | 'cancelled';
114
+ }
115
+ //# sourceMappingURL=tracer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tracer.d.ts","sourceRoot":"","sources":["../src/tracer.ts"],"names":[],"mappings":"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"}
package/lib/tracer.js ADDED
@@ -0,0 +1,205 @@
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.DefaultTracer = exports.DEFER_START_MS = void 0;
12
+ const clock_1 = require("./clock");
13
+ const logger_1 = require("./logger");
14
+ const noop_logger_1 = require("./noop-logger");
15
+ const profile_session_1 = require("./profile-session");
16
+ const util_1 = require("./util");
17
+ /** Module-global so nested timers don't reuse ids. */
18
+ let nextTimerId = 0;
19
+ /** Ops completing before this threshold are silent on success — only failures emit a retroactive start. */
20
+ exports.DEFER_START_MS = 5;
21
+ /**
22
+ * Default cross-head {@link Tracer}. One concrete class serves every head:
23
+ * emission delegates to the composed {@link Logger}, timing/profiling go
24
+ * through the injected {@link Clock}, and the only per-head varying piece is
25
+ * the {@link MemoryReader} (default: none — heads that log memory pass a
26
+ * reader, or subclass for richer rendering, as the server's `ServerTracer`
27
+ * does). The `time` / `startTimer` bodies are zero-cost when the level is
28
+ * suppressed: the callback runs directly and no stopwatch / timer / id is
29
+ * allocated.
30
+ */
31
+ class DefaultTracer {
32
+ logger;
33
+ clock;
34
+ readMemory;
35
+ constructor(logger = new noop_logger_1.NoopLogger(), clock = new clock_1.SystemClock(), readMemory = () => undefined) {
36
+ this.logger = logger;
37
+ this.clock = clock;
38
+ this.readMemory = readMemory;
39
+ }
40
+ // Emission — forwarded to the composed logger (the platform-specific sink).
41
+ // Each returns the Tracer (not the wrapped logger) so chained emits stay on
42
+ // the tracer and `tracer.for(x).trace(y)` yields a Tracer.
43
+ error(message, ...args) {
44
+ this.logger.error(message, ...args);
45
+ return this;
46
+ }
47
+ warn(message, ...args) {
48
+ this.logger.warn(message, ...args);
49
+ return this;
50
+ }
51
+ info(message, ...args) {
52
+ this.logger.info(message, ...args);
53
+ return this;
54
+ }
55
+ debug(message, ...args) {
56
+ this.logger.debug(message, ...args);
57
+ return this;
58
+ }
59
+ trace(message, ...args) {
60
+ this.logger.trace(message, ...args);
61
+ return this;
62
+ }
63
+ log(message, ...args) {
64
+ this.logger.log(message, ...args);
65
+ return this;
66
+ }
67
+ logAt(threshold, message) {
68
+ this.logger.logAt(threshold, message);
69
+ return this;
70
+ }
71
+ memory(label, logLevel = 'info') {
72
+ if (logLevel === 'off' || !logger_1.Logger.isLevelEnabled(logLevel)) {
73
+ return;
74
+ }
75
+ const info = this.readMemory();
76
+ if (!info) {
77
+ // No memory stats available — a contentless "Memory:" line is noise.
78
+ return;
79
+ }
80
+ const used = logger_1.Format.bytes(info.usedBytes);
81
+ const text = info.totalBytes !== undefined ? `${used}/${logger_1.Format.bytes(info.totalBytes)}` : used;
82
+ this.logger[logLevel](`${label ? `${label}: ` : 'Memory: '}${text}`);
83
+ }
84
+ time(label, callback, logLevel = 'info', options = {}) {
85
+ if (logLevel === 'off' || !logger_1.Logger.isLevelEnabled(logLevel)) {
86
+ return callback();
87
+ }
88
+ const { logAfterMs = exports.DEFER_START_MS, captureId, tags } = options;
89
+ const id = ++nextTimerId;
90
+ captureId?.(id);
91
+ const stopwatch = this.clock.stopwatch();
92
+ let startEmitted = false;
93
+ let startTimer;
94
+ const currentExtras = () => (tags && tags.length > 0 ? `, ${tags.join(', ')}` : '');
95
+ const emitStart = () => {
96
+ this.logger[logLevel](`${label} [#${id} start${currentExtras()}]`);
97
+ startEmitted = true;
98
+ };
99
+ if (logAfterMs <= 0) {
100
+ emitStart();
101
+ }
102
+ else {
103
+ startTimer = this.clock.setTimer(emitStart, logAfterMs);
104
+ }
105
+ const emit = (status, error) => {
106
+ startTimer?.dispose();
107
+ if (!startEmitted) {
108
+ if (status === 'done') {
109
+ return;
110
+ }
111
+ emitStart();
112
+ }
113
+ const elapsed = stopwatch.elapsedMs;
114
+ const suffix = this.timingSuffix(status, elapsed, options);
115
+ this.logger[logLevel](`${label} [#${id} ${status}, ${logger_1.Format.elapsed(elapsed)}${currentExtras()}${suffix}]`);
116
+ if (status === 'failed') {
117
+ // The timing line above sits at `logLevel`, which may be below the
118
+ // active threshold — and on its own it never carries *why* the op
119
+ // failed. Surface the error at warn so the failure is never silent,
120
+ // with the stack at debug. Cancellations are normal control flow.
121
+ const detail = error instanceof Error ? error.message : String(error);
122
+ this.logger.warn(`${label} [#${id}] failed: ${detail}`);
123
+ if (error instanceof Error && error.stack) {
124
+ this.logger.debug(error.stack);
125
+ }
126
+ }
127
+ };
128
+ let result;
129
+ try {
130
+ result = callback();
131
+ }
132
+ catch (error) {
133
+ emit(this.categorizeError(error), error);
134
+ throw error;
135
+ }
136
+ if (result instanceof Promise) {
137
+ return result.then(value => {
138
+ emit('done');
139
+ return value;
140
+ }, error => {
141
+ emit(this.categorizeError(error), error);
142
+ throw error;
143
+ });
144
+ }
145
+ emit('done');
146
+ return result;
147
+ }
148
+ startTimer(label, logLevel = 'info', logAfterMs = exports.DEFER_START_MS) {
149
+ if (logLevel === 'off' || !logger_1.Logger.isLevelEnabled(logLevel)) {
150
+ return util_1.Disposable.create(() => { });
151
+ }
152
+ const id = ++nextTimerId;
153
+ const stopwatch = this.clock.stopwatch();
154
+ let startEmitted = false;
155
+ let startTimer;
156
+ const emitStart = () => {
157
+ this.logger[logLevel](`${label} [#${id} start]`);
158
+ startEmitted = true;
159
+ };
160
+ if (logAfterMs <= 0) {
161
+ emitStart();
162
+ }
163
+ else {
164
+ startTimer = this.clock.setTimer(emitStart, logAfterMs);
165
+ }
166
+ return util_1.Disposable.create(() => {
167
+ startTimer?.dispose();
168
+ if (!startEmitted) {
169
+ return;
170
+ }
171
+ const elapsed = stopwatch.elapsedMs;
172
+ const suffix = this.timingSuffix('done', elapsed, {});
173
+ this.logger[logLevel](`${label} [#${id} done, ${logger_1.Format.elapsed(elapsed)}${suffix}]`);
174
+ });
175
+ }
176
+ profile(identifier) {
177
+ return new profile_session_1.DefaultProfileSession(this.logger, this.clock, identifier);
178
+ }
179
+ for(component) {
180
+ return this.derive(this.logger.for(component));
181
+ }
182
+ sub(component) {
183
+ return this.derive(this.logger.sub(component));
184
+ }
185
+ with(component) {
186
+ return this.derive(this.logger.with(component));
187
+ }
188
+ withUri(uri) {
189
+ return this.derive(this.logger.withUri(uri));
190
+ }
191
+ /** Construct a sibling Tracer over a derived logger, preserving the concrete subclass. */
192
+ derive(logger) {
193
+ return new DefaultTracer(logger, this.clock, this.readMemory);
194
+ }
195
+ /** Hook for appending status-bracket suffixes like memory deltas. Default: none. */
196
+ timingSuffix(_status, _elapsedMs, _options) {
197
+ return '';
198
+ }
199
+ /** Hook to differentiate cancelled operations from failures. Default: all errors are failures. */
200
+ categorizeError(_error) {
201
+ return 'failed';
202
+ }
203
+ }
204
+ exports.DefaultTracer = DefaultTracer;
205
+ //# sourceMappingURL=tracer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tracer.js","sourceRoot":"","sources":["../src/tracer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,73 @@
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
+ * Generic, transport-friendly diagnostic shape used by the model-server protocol.
11
+ *
12
+ * The `element` path is a `/`-separated location string with `@` and `^` as index
13
+ * and property separators, matching the conventions used by Langium's
14
+ * `AstNodeLocator` service.
15
+ */
16
+ export interface TransferDiagnostic {
17
+ /**
18
+ * Which stage produced it. Coarse by construction: only the two syntactic
19
+ * stages are recognised by name and everything else — a framework integrity
20
+ * rule, an adopter check, a linker failure — arrives as `validation-error`.
21
+ * Use it to decide whether the document PARSED, not to identify a rule.
22
+ */
23
+ type: 'lexing-error' | 'parsing-error' | 'validation-error';
24
+ /**
25
+ * `AstNodeLocator`-style path to the offending node. **Empty string when the
26
+ * diagnostic carries no location** — the framework's own validator decorates
27
+ * every diagnostic, but a rebound one need not, and an empty path denotes
28
+ * "unlocated" rather than the document root.
29
+ */
30
+ element: string;
31
+ /**
32
+ * Names the offending property when the diagnostic is about one; absent when
33
+ * it is about the node as a whole. Append it to {@link element} with
34
+ * `ELEMENT_PROPERTY_SEPARATOR` rather than by hand — `getPath` does exactly
35
+ * that and handles the absent case.
36
+ */
37
+ property?: string;
38
+ /**
39
+ * Plain text, always. An LSP `MarkupContent` message is flattened on the way
40
+ * out, so no markup survives the wire and a consumer must not try to render
41
+ * it as rich text.
42
+ */
43
+ message: string;
44
+ /**
45
+ * Three levels against LSP's four: `Hint` and `Information` both arrive as
46
+ * `info`, so a client cannot recover the distinction. Anything that is not
47
+ * an error or a warning lands in `info`, including a diagnostic that carried
48
+ * no severity at all.
49
+ */
50
+ severity: 'error' | 'warning' | 'info';
51
+ /**
52
+ * The diagnostic's own code where it has one, otherwise Langium's internal
53
+ * code — which means it may simply restate {@link type} for a syntactic
54
+ * error. Absent when neither exists, and not unique across languages, so it
55
+ * is not usable as a rule identity on its own.
56
+ */
57
+ code?: number | string;
58
+ }
59
+ export declare namespace TransferDiagnostic {
60
+ /** Path separator between AST nodes within an element location. */
61
+ const ELEMENT_SEGMENT_SEPARATOR = "/";
62
+ /** Index separator within an array property segment. */
63
+ const ELEMENT_INDEX_SEPARATOR = "@";
64
+ /** Property separator suffixing the element path with the offending property name. */
65
+ const ELEMENT_PROPERTY_SEPARATOR = "^";
66
+ function isError(diagnostic: TransferDiagnostic): boolean;
67
+ function isParseError(diagnostic: TransferDiagnostic): boolean;
68
+ function getPath(diagnostic: TransferDiagnostic): string;
69
+ function errors(diagnostics: TransferDiagnostic[]): TransferDiagnostic[];
70
+ function hasErrors(diagnostics: TransferDiagnostic[]): boolean;
71
+ function hasParseErrors(diagnostics: TransferDiagnostic[]): boolean;
72
+ }
73
+ //# sourceMappingURL=transfer-diagnostic.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transfer-diagnostic.d.ts","sourceRoot":"","sources":["../src/transfer-diagnostic.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF;;;;;;GAMG;AACH,MAAM,WAAW,kBAAkB;IAChC;;;;;OAKG;IACH,IAAI,EAAE,cAAc,GAAG,eAAe,GAAG,kBAAkB,CAAC;IAC5D;;;;;OAKG;IACH,OAAO,EAAE,MAAM,CAAC;IAChB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,OAAO,EAAE,MAAM,CAAC;IAChB;;;;;OAKG;IACH,QAAQ,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;IACvC;;;;;OAKG;IACH,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CACzB;AAED,yBAAiB,kBAAkB,CAAC;IACjC,mEAAmE;IAC5D,MAAM,yBAAyB,MAAM,CAAC;IAC7C,wDAAwD;IACjD,MAAM,uBAAuB,MAAM,CAAC;IAC3C,sFAAsF;IAC/E,MAAM,0BAA0B,MAAM,CAAC;IAE9C,SAAgB,OAAO,CAAC,UAAU,EAAE,kBAAkB,GAAG,OAAO,CAE/D;IAED,SAAgB,YAAY,CAAC,UAAU,EAAE,kBAAkB,GAAG,OAAO,CAEpE;IAED,SAAgB,OAAO,CAAC,UAAU,EAAE,kBAAkB,GAAG,MAAM,CAE9D;IAED,SAAgB,MAAM,CAAC,WAAW,EAAE,kBAAkB,EAAE,GAAG,kBAAkB,EAAE,CAE9E;IAED,SAAgB,SAAS,CAAC,WAAW,EAAE,kBAAkB,EAAE,GAAG,OAAO,CAEpE;IAED,SAAgB,cAAc,CAAC,WAAW,EAAE,kBAAkB,EAAE,GAAG,OAAO,CAEzE;CACH"}
@@ -0,0 +1,45 @@
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.TransferDiagnostic = void 0;
12
+ var TransferDiagnostic;
13
+ (function (TransferDiagnostic) {
14
+ /** Path separator between AST nodes within an element location. */
15
+ TransferDiagnostic.ELEMENT_SEGMENT_SEPARATOR = '/';
16
+ /** Index separator within an array property segment. */
17
+ TransferDiagnostic.ELEMENT_INDEX_SEPARATOR = '@';
18
+ /** Property separator suffixing the element path with the offending property name. */
19
+ TransferDiagnostic.ELEMENT_PROPERTY_SEPARATOR = '^';
20
+ function isError(diagnostic) {
21
+ return diagnostic.severity === 'error';
22
+ }
23
+ TransferDiagnostic.isError = isError;
24
+ function isParseError(diagnostic) {
25
+ return diagnostic.type === 'parsing-error';
26
+ }
27
+ TransferDiagnostic.isParseError = isParseError;
28
+ function getPath(diagnostic) {
29
+ return diagnostic.property ? `${diagnostic.element}${TransferDiagnostic.ELEMENT_PROPERTY_SEPARATOR}${diagnostic.property}` : diagnostic.element;
30
+ }
31
+ TransferDiagnostic.getPath = getPath;
32
+ function errors(diagnostics) {
33
+ return diagnostics.filter(isError);
34
+ }
35
+ TransferDiagnostic.errors = errors;
36
+ function hasErrors(diagnostics) {
37
+ return diagnostics.some(isError);
38
+ }
39
+ TransferDiagnostic.hasErrors = hasErrors;
40
+ function hasParseErrors(diagnostics) {
41
+ return diagnostics.some(isParseError);
42
+ }
43
+ TransferDiagnostic.hasParseErrors = hasParseErrors;
44
+ })(TransferDiagnostic || (exports.TransferDiagnostic = TransferDiagnostic = {}));
45
+ //# sourceMappingURL=transfer-diagnostic.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transfer-diagnostic.js","sourceRoot":"","sources":["../src/transfer-diagnostic.ts"],"names":[],"mappings":";AAAA;;;;;;;kFAOkF;;;AAqDlF,IAAiB,kBAAkB,CA+BlC;AA/BD,WAAiB,kBAAkB;IAChC,mEAAmE;IACtD,4CAAyB,GAAG,GAAG,CAAC;IAC7C,wDAAwD;IAC3C,0CAAuB,GAAG,GAAG,CAAC;IAC3C,sFAAsF;IACzE,6CAA0B,GAAG,GAAG,CAAC;IAE9C,SAAgB,OAAO,CAAC,UAA8B;QACnD,OAAO,UAAU,CAAC,QAAQ,KAAK,OAAO,CAAC;IAC1C,CAAC;IAFe,0BAAO,UAEtB,CAAA;IAED,SAAgB,YAAY,CAAC,UAA8B;QACxD,OAAO,UAAU,CAAC,IAAI,KAAK,eAAe,CAAC;IAC9C,CAAC;IAFe,+BAAY,eAE3B,CAAA;IAED,SAAgB,OAAO,CAAC,UAA8B;QACnD,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,OAAO,GAAG,mBAAA,0BAA0B,GAAG,UAAU,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC;IAChI,CAAC;IAFe,0BAAO,UAEtB,CAAA;IAED,SAAgB,MAAM,CAAC,WAAiC;QACrD,OAAO,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACtC,CAAC;IAFe,yBAAM,SAErB,CAAA;IAED,SAAgB,SAAS,CAAC,WAAiC;QACxD,OAAO,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACpC,CAAC;IAFe,4BAAS,YAExB,CAAA;IAED,SAAgB,cAAc,CAAC,WAAiC;QAC7D,OAAO,WAAW,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IACzC,CAAC;IAFe,iCAAc,iBAE7B,CAAA;AACJ,CAAC,EA/BgB,kBAAkB,kCAAlB,kBAAkB,QA+BlC"}
@@ -0,0 +1,73 @@
1
+ /********************************************************************************
2
+ * Copyright (c) 2023-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 { TransferDiagnostic } from './transfer-diagnostic';
10
+ import type { TransferElement } from './transfer-element';
11
+ /**
12
+ * Wire envelope exchanged between the model-server's data-server head and
13
+ * its clients. Carries a transfer-shaped root — never an AST root — plus
14
+ * the document's diagnostics in the adopter's wire-diagnostic shape.
15
+ *
16
+ * The constraint `TTransfer extends TransferElement` pins the type system
17
+ * to the wire data shape (no `$container` cycles, references as strings;
18
+ * see {@link TransferElement}). The paired server-internal envelope is
19
+ * `AstDocument<TAst extends AstNode, TDiagnostic>` in
20
+ * `@hydranium/core` — same structural shape, different generic
21
+ * constraint, used at the AST layer before the `TransferEncoder`
22
+ * translation produces a {@link TransferDocument}.
23
+ */
24
+ export interface TransferDocument<TTransfer extends TransferElement, TDiagnostic = TransferDiagnostic> {
25
+ uri: string;
26
+ /**
27
+ * The document version this snapshot was taken at — sourced from the
28
+ * server's text-document version counter. Callers that mutate the
29
+ * document subsequently pass this value back as `TransferUpdateArgs.baseVersion`
30
+ * (or `TransferSaveArgs.baseVersion`) so the server can detect stale-based
31
+ * updates and reject them with `ConflictError`.
32
+ *
33
+ * See `@hydranium/protocol#errors` for the conflict-detection contract.
34
+ */
35
+ version: number;
36
+ /**
37
+ * Absent when the document does not exist — the server answers an unknown URI
38
+ * with a shaped envelope rather than an error, so absence is an ordinary
39
+ * branch and not a catch. Declared required it reads as a guarantee, and
40
+ * every `root.x` compiles into a throw.
41
+ */
42
+ root?: TTransfer;
43
+ diagnostics: TDiagnostic[];
44
+ }
45
+ /**
46
+ * A {@link TransferDocument} the server actually had, so `root` is present.
47
+ * Narrowed to by {@link TransferDocument.isLoaded} / {@link TransferDocument.assertLoaded}.
48
+ */
49
+ export type LoadedTransferDocument<TTransfer extends TransferElement, TDiagnostic = TransferDiagnostic> = TransferDocument<TTransfer, TDiagnostic> & {
50
+ root: TTransfer;
51
+ };
52
+ export declare namespace TransferDocument {
53
+ /**
54
+ * Whether the server had this document. Branch on it where absence is an
55
+ * ordinary state — a view bound to a file that may not exist yet.
56
+ */
57
+ function isLoaded<TTransfer extends TransferElement, TDiagnostic = TransferDiagnostic>(document: TransferDocument<TTransfer, TDiagnostic>): document is LoadedTransferDocument<TTransfer, TDiagnostic>;
58
+ /**
59
+ * The same document with `root` no longer optional, or a throw. For call
60
+ * sites where absence is a bug rather than a branch; the whole envelope is
61
+ * returned because a caller needing `root` usually needs `uri` or `version`
62
+ * with it.
63
+ */
64
+ function assertLoaded<TTransfer extends TransferElement, TDiagnostic = TransferDiagnostic>(document: TransferDocument<TTransfer, TDiagnostic>): LoadedTransferDocument<TTransfer, TDiagnostic>;
65
+ /**
66
+ * Construct a {@link TransferDocument} envelope. `diagnostics` defaults
67
+ * to `[]` so test fixtures, fake protocol implementations, and the
68
+ * "no diagnostics yet" code paths don't need to repeat the empty array
69
+ * at every call site.
70
+ */
71
+ function create<TTransfer extends TransferElement, TDiagnostic = TransferDiagnostic>(uri: string, version: number, root: TTransfer, diagnostics?: TDiagnostic[]): TransferDocument<TTransfer, TDiagnostic>;
72
+ }
73
+ //# sourceMappingURL=transfer-document.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transfer-document.d.ts","sourceRoot":"","sources":["../src/transfer-document.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAE1D;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,gBAAgB,CAAC,SAAS,SAAS,eAAe,EAAE,WAAW,GAAG,kBAAkB;IAClG,GAAG,EAAE,MAAM,CAAC;IACZ;;;;;;;;OAQG;IACH,OAAO,EAAE,MAAM,CAAC;IAChB;;;;;OAKG;IACH,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,WAAW,EAAE,WAAW,EAAE,CAAC;CAC7B;AAED;;;GAGG;AACH,MAAM,MAAM,sBAAsB,CAAC,SAAS,SAAS,eAAe,EAAE,WAAW,GAAG,kBAAkB,IAAI,gBAAgB,CACvH,SAAS,EACT,WAAW,CACb,GAAG;IACD,IAAI,EAAE,SAAS,CAAC;CAClB,CAAC;AAEF,yBAAiB,gBAAgB,CAAC;IAC/B;;;OAGG;IACH,SAAgB,QAAQ,CAAC,SAAS,SAAS,eAAe,EAAE,WAAW,GAAG,kBAAkB,EACzF,QAAQ,EAAE,gBAAgB,CAAC,SAAS,EAAE,WAAW,CAAC,GAClD,QAAQ,IAAI,sBAAsB,CAAC,SAAS,EAAE,WAAW,CAAC,CAE5D;IAED;;;;;OAKG;IACH,SAAgB,YAAY,CAAC,SAAS,SAAS,eAAe,EAAE,WAAW,GAAG,kBAAkB,EAC7F,QAAQ,EAAE,gBAAgB,CAAC,SAAS,EAAE,WAAW,CAAC,GAClD,sBAAsB,CAAC,SAAS,EAAE,WAAW,CAAC,CAKhD;IAED;;;;;OAKG;IACH,SAAgB,MAAM,CAAC,SAAS,SAAS,eAAe,EAAE,WAAW,GAAG,kBAAkB,EACvF,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,SAAS,EACf,WAAW,GAAE,WAAW,EAAO,GAC/B,gBAAgB,CAAC,SAAS,EAAE,WAAW,CAAC,CAE1C;CACH"}