@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,18 @@
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.HOST_DIAGNOSTICS_PATH = void 0;
12
+ /**
13
+ * Theia service path the host-diagnostics RPC service is registered under. An
14
+ * ordinary in-process backend service (`RpcConnectionHandler`), unlike the
15
+ * socket-forwarded `DATA_SERVER_PATH`.
16
+ */
17
+ exports.HOST_DIAGNOSTICS_PATH = '/hydranium/host-diagnostics';
18
+ //# sourceMappingURL=host-diagnostics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"host-diagnostics.js","sourceRoot":"","sources":["../src/host-diagnostics.ts"],"names":[],"mappings":";AAAA;;;;;;;kFAOkF;;;AAkDlF;;;;GAIG;AACU,QAAA,qBAAqB,GAAG,6BAA6B,CAAC"}
package/lib/index.d.ts ADDED
@@ -0,0 +1,34 @@
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
+ export * from './abstract-logger';
10
+ export * from './client';
11
+ export * from './clock';
12
+ export * from './data';
13
+ export * from './browser-runtime';
14
+ export * from './debouncer';
15
+ export * from './errors';
16
+ export * from './host-diagnostics';
17
+ export * from './logger';
18
+ export * from './latency-collector';
19
+ export * from './patch-merge';
20
+ export * from './noop-logger';
21
+ export * from './observable-value';
22
+ export * from './profile-session';
23
+ export * from './profiling';
24
+ export * from './tracer';
25
+ export * from './transfer-diagnostic';
26
+ export * from './transfer-element';
27
+ export * from './model-service';
28
+ export * from './transfer-document';
29
+ export * from './model-server';
30
+ export * from './project';
31
+ export * from './rpc';
32
+ export * from './uri';
33
+ export * from './util';
34
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AASlF,cAAc,mBAAmB,CAAC;AAClC,cAAc,UAAU,CAAC;AACzB,cAAc,SAAS,CAAC;AACxB,cAAc,QAAQ,CAAC;AACvB,cAAc,mBAAmB,CAAC;AAClC,cAAc,aAAa,CAAC;AAC5B,cAAc,UAAU,CAAC;AACzB,cAAc,oBAAoB,CAAC;AACnC,cAAc,UAAU,CAAC;AACzB,cAAc,qBAAqB,CAAC;AACpC,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,oBAAoB,CAAC;AACnC,cAAc,mBAAmB,CAAC;AAClC,cAAc,aAAa,CAAC;AAC5B,cAAc,UAAU,CAAC;AACzB,cAAc,uBAAuB,CAAC;AACtC,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC;AAChC,cAAc,qBAAqB,CAAC;AACpC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,WAAW,CAAC;AAC1B,cAAc,OAAO,CAAC;AACtB,cAAc,OAAO,CAAC;AACtB,cAAc,QAAQ,CAAC"}
package/lib/index.js ADDED
@@ -0,0 +1,56 @@
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
+ // Public API barrel — re-exports every PRODUCTION entry of `@hydranium/protocol`.
26
+ // `./client` and `./data` are re-exported as well as declared standalone, so a
27
+ // consumer wanting the whole production surface needs one specifier while one
28
+ // wanting a narrower graph can still name the subpath. `./testing` is excluded
29
+ // on the opposite constraint: re-exporting it would put the test doubles in
30
+ // every production bundle that imports the root.
31
+ __exportStar(require("./abstract-logger"), exports);
32
+ __exportStar(require("./client"), exports);
33
+ __exportStar(require("./clock"), exports);
34
+ __exportStar(require("./data"), exports);
35
+ __exportStar(require("./browser-runtime"), exports);
36
+ __exportStar(require("./debouncer"), exports);
37
+ __exportStar(require("./errors"), exports);
38
+ __exportStar(require("./host-diagnostics"), exports);
39
+ __exportStar(require("./logger"), exports);
40
+ __exportStar(require("./latency-collector"), exports);
41
+ __exportStar(require("./patch-merge"), exports);
42
+ __exportStar(require("./noop-logger"), exports);
43
+ __exportStar(require("./observable-value"), exports);
44
+ __exportStar(require("./profile-session"), exports);
45
+ __exportStar(require("./profiling"), exports);
46
+ __exportStar(require("./tracer"), exports);
47
+ __exportStar(require("./transfer-diagnostic"), exports);
48
+ __exportStar(require("./transfer-element"), exports);
49
+ __exportStar(require("./model-service"), exports);
50
+ __exportStar(require("./transfer-document"), exports);
51
+ __exportStar(require("./model-server"), exports);
52
+ __exportStar(require("./project"), exports);
53
+ __exportStar(require("./rpc"), exports);
54
+ __exportStar(require("./uri"), exports);
55
+ __exportStar(require("./util"), exports);
56
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;kFAOkF;;;;;;;;;;;;;;;;AAElF,kFAAkF;AAClF,+EAA+E;AAC/E,8EAA8E;AAC9E,+EAA+E;AAC/E,4EAA4E;AAC5E,iDAAiD;AAEjD,oDAAkC;AAClC,2CAAyB;AACzB,0CAAwB;AACxB,yCAAuB;AACvB,oDAAkC;AAClC,8CAA4B;AAC5B,2CAAyB;AACzB,qDAAmC;AACnC,2CAAyB;AACzB,sDAAoC;AACpC,gDAA8B;AAC9B,gDAA8B;AAC9B,qDAAmC;AACnC,oDAAkC;AAClC,8CAA4B;AAC5B,2CAAyB;AACzB,wDAAsC;AACtC,qDAAmC;AACnC,kDAAgC;AAChC,sDAAoC;AACpC,iDAA+B;AAC/B,4CAA0B;AAC1B,wCAAsB;AACtB,wCAAsB;AACtB,yCAAuB"}
@@ -0,0 +1,126 @@
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, type Stopwatch } from './clock.js';
10
+ /** Latency/throughput for one method over the collection window. */
11
+ export interface MethodLatency {
12
+ /**
13
+ * Whatever key the caller passed to {@link LatencyCollector.record} or
14
+ * {@link LatencyCollector.time} — the framework feeds it RPC and LSP method
15
+ * names, but nothing enforces that, so two feeds using different spellings
16
+ * for one operation report as two methods.
17
+ */
18
+ method: string;
19
+ /**
20
+ * Calls since construction or the last {@link LatencyCollector.reset}, which
21
+ * is the only thing that clears it. Unaffected by retention: a ring-buffer
22
+ * collector keeps counting long after it stops keeping samples. Failed calls
23
+ * are counted — a call that threw still consumed time.
24
+ */
25
+ count: number;
26
+ /**
27
+ * Milliseconds, nearest-rank over the RETAINED samples rather than over
28
+ * {@link count} calls, so under `ring-buffer` retention it describes only the
29
+ * trailing window and can sit well below {@link maxMs}. `0` means no samples
30
+ * were retained, not that calls were instant.
31
+ */
32
+ p50Ms: number;
33
+ /** Milliseconds, nearest-rank; same retention caveat as {@link p50Ms}. */
34
+ p99Ms: number;
35
+ /**
36
+ * Milliseconds, the slowest single call since the last reset. A lifetime
37
+ * figure, so a spike that has aged out of a ring buffer still shows here
38
+ * after the percentiles have forgotten it.
39
+ */
40
+ maxMs: number;
41
+ /**
42
+ * Milliseconds summed across every call since the last reset, retention
43
+ * notwithstanding. This is what {@link LatencyCollector.report} ranks on, so
44
+ * it orders by total cost rather than by per-call slowness.
45
+ */
46
+ totalMs: number;
47
+ }
48
+ /** A collector snapshot: the window length and the per-method latencies, hottest first. */
49
+ export interface LatencyReport {
50
+ /**
51
+ * Milliseconds elapsed since construction or the last
52
+ * {@link LatencyCollector.reset}, off the monotonic stopwatch. It bounds the
53
+ * throughput a caller can derive; it is not the sum of the method totals,
54
+ * which overlap and can exceed it under concurrency.
55
+ */
56
+ windowMs: number;
57
+ /**
58
+ * Ordered by {@link MethodLatency.totalMs} descending. A method that was
59
+ * never called is absent rather than present with zeroes, so an empty array
60
+ * means nothing ran in the window.
61
+ */
62
+ methods: MethodLatency[];
63
+ }
64
+ /**
65
+ * How many samples a collector retains for percentile estimation. `keep-all`
66
+ * (the default) stores every duration for exact nearest-rank percentiles — sized
67
+ * for a bounded diagnostics window that gets read then {@link LatencyCollector.reset}.
68
+ * `ring-buffer` caps retention at `maxSamplesPerMethod`, keeping only the most
69
+ * recent samples so a collector left running indefinitely cannot grow without
70
+ * bound; percentiles then cover that trailing window while `count`/`totalMs`/
71
+ * `maxMs` remain lifetime totals.
72
+ */
73
+ export type LatencyRetention = {
74
+ readonly kind: 'keep-all';
75
+ } | {
76
+ readonly kind: 'ring-buffer';
77
+ readonly maxSamplesPerMethod: number;
78
+ };
79
+ /** Per-method state: retained samples (bounded in ring-buffer mode) plus lifetime totals. */
80
+ interface MethodAccumulator {
81
+ /** Retained durations for percentile estimation; capped in ring-buffer mode. Order is irrelevant (report sorts). */
82
+ readonly samples: number[];
83
+ /** Next slot to overwrite once the ring buffer is full (ring-buffer mode only). */
84
+ writeIndex: number;
85
+ /** Lifetime call count, unaffected by retention. */
86
+ count: number;
87
+ /** Lifetime total duration, unaffected by retention. */
88
+ totalMs: number;
89
+ /** Lifetime maximum duration, so a spike that ages out of the window still shows. */
90
+ maxMs: number;
91
+ }
92
+ /**
93
+ * Accumulates per-method call durations and reports count + latency percentiles.
94
+ * Exact (keeps every duration per method) — sized for a diagnostics window, not
95
+ * unbounded production telemetry; {@link reset} drops the samples and restarts
96
+ * the window. Feed it via {@link time} (wraps a call) or {@link record} (a
97
+ * pre-measured duration). Timing rides an injectable {@link Clock} so tests are
98
+ * deterministic on a fake clock.
99
+ */
100
+ export declare class LatencyCollector {
101
+ protected readonly clock: Clock;
102
+ protected readonly retention: LatencyRetention;
103
+ protected readonly durations: Map<string, MethodAccumulator>;
104
+ protected window: Stopwatch;
105
+ constructor(clock?: Clock, retention?: LatencyRetention);
106
+ /** Record a pre-measured call duration (ms) for `method`. */
107
+ record(method: string, durationMs: number): void;
108
+ /**
109
+ * Run `call`, record how long it took under `method`, and return its result.
110
+ * The duration is recorded even when the call throws/rejects (a failed call
111
+ * still consumed time), then the error propagates.
112
+ */
113
+ time<T>(method: string, call: () => Promise<T>): Promise<T>;
114
+ time<T>(method: string, call: () => T): T;
115
+ /** Non-destructive snapshot: per-method latencies ordered by total time descending (use {@link reset} to drain). */
116
+ report(): LatencyReport;
117
+ /** Drop all samples and restart the window. */
118
+ reset(): void;
119
+ }
120
+ /**
121
+ * Render a {@link LatencyReport} as a compact ranked table for a log line or a
122
+ * command channel — the latency counterpart to `formatProfileReport`.
123
+ */
124
+ export declare function formatLatencyReport(report: LatencyReport, label?: string): string;
125
+ export {};
126
+ //# sourceMappingURL=latency-collector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"latency-collector.d.ts","sourceRoot":"","sources":["../src/latency-collector.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAalF,OAAO,EAAE,KAAK,KAAK,EAAE,KAAK,SAAS,EAAe,MAAM,YAAY,CAAC;AAErE,oEAAoE;AACpE,MAAM,WAAW,aAAa;IAC3B;;;;;OAKG;IACH,MAAM,EAAE,MAAM,CAAC;IACf;;;;;OAKG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;;;;OAKG;IACH,KAAK,EAAE,MAAM,CAAC;IACd,0EAA0E;IAC1E,KAAK,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,OAAO,EAAE,MAAM,CAAC;CAClB;AAED,2FAA2F;AAC3F,MAAM,WAAW,aAAa;IAC3B;;;;;OAKG;IACH,QAAQ,EAAE,MAAM,CAAC;IACjB;;;;OAIG;IACH,OAAO,EAAE,aAAa,EAAE,CAAC;CAC3B;AAED;;;;;;;;GAQG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAA;CAAE,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAAC,QAAQ,CAAC,mBAAmB,EAAE,MAAM,CAAA;CAAE,CAAC;AAEtI,6FAA6F;AAC7F,UAAU,iBAAiB;IACxB,oHAAoH;IACpH,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC;IAC3B,mFAAmF;IACnF,UAAU,EAAE,MAAM,CAAC;IACnB,oDAAoD;IACpD,KAAK,EAAE,MAAM,CAAC;IACd,wDAAwD;IACxD,OAAO,EAAE,MAAM,CAAC;IAChB,qFAAqF;IACrF,KAAK,EAAE,MAAM,CAAC;CAChB;AAWD;;;;;;;GAOG;AACH,qBAAa,gBAAgB;IAKvB,SAAS,CAAC,QAAQ,CAAC,KAAK,EAAE,KAAK;IAC/B,SAAS,CAAC,QAAQ,CAAC,SAAS,EAAE,gBAAgB;IALjD,SAAS,CAAC,QAAQ,CAAC,SAAS,iCAAwC;IACpE,SAAS,CAAC,MAAM,EAAE,SAAS,CAAC;gBAGN,KAAK,GAAE,KAAyB,EAChC,SAAS,GAAE,gBAAuC;IAQxE,6DAA6D;IAC7D,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI;IAoBhD;;;;OAIG;IACH,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAC3D,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC;IA2BzC,oHAAoH;IACpH,MAAM,IAAI,aAAa;IAiBvB,+CAA+C;IAC/C,KAAK,IAAI,IAAI;CAIf;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,aAAa,EAAE,KAAK,SAAoB,GAAG,MAAM,CAa5F"}
@@ -0,0 +1,137 @@
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.LatencyCollector = void 0;
12
+ exports.formatLatencyReport = formatLatencyReport;
13
+ /*
14
+ * Per-operation latency/throughput accumulator — the time/throughput axis of a
15
+ * profiling run (the CPU profile says "where time went in aggregate"; this says
16
+ * "method X ran N times at p99 Y ms"). It sits on the framework's timing
17
+ * primitives (`Clock`), not on a Node inspector session, so it is neutral and
18
+ * lives here in `protocol`: the RPC binder feeds it at one chokepoint and the
19
+ * LSP connection decorator feeds it at another, both cross-head. A running head
20
+ * holds one collector and reads `report()` out (e.g. over the diagnostics wire
21
+ * or into a bundle's `server-latency.json`).
22
+ */
23
+ const clock_js_1 = require("./clock.js");
24
+ /** Nearest-rank percentile of an ascending-sorted array (empty → 0). */
25
+ function percentile(sortedAscending, percent) {
26
+ if (sortedAscending.length === 0) {
27
+ return 0;
28
+ }
29
+ const rank = Math.ceil((percent / 100) * sortedAscending.length);
30
+ return sortedAscending[Math.min(sortedAscending.length - 1, Math.max(0, rank - 1))];
31
+ }
32
+ /**
33
+ * Accumulates per-method call durations and reports count + latency percentiles.
34
+ * Exact (keeps every duration per method) — sized for a diagnostics window, not
35
+ * unbounded production telemetry; {@link reset} drops the samples and restarts
36
+ * the window. Feed it via {@link time} (wraps a call) or {@link record} (a
37
+ * pre-measured duration). Timing rides an injectable {@link Clock} so tests are
38
+ * deterministic on a fake clock.
39
+ */
40
+ class LatencyCollector {
41
+ clock;
42
+ retention;
43
+ durations = new Map();
44
+ window;
45
+ constructor(clock = new clock_js_1.SystemClock(), retention = { kind: 'keep-all' }) {
46
+ this.clock = clock;
47
+ this.retention = retention;
48
+ if (retention.kind === 'ring-buffer' && retention.maxSamplesPerMethod < 1) {
49
+ throw new RangeError(`ring-buffer maxSamplesPerMethod must be >= 1, got ${retention.maxSamplesPerMethod}`);
50
+ }
51
+ this.window = this.clock.stopwatch();
52
+ }
53
+ /** Record a pre-measured call duration (ms) for `method`. */
54
+ record(method, durationMs) {
55
+ let accumulator = this.durations.get(method);
56
+ if (!accumulator) {
57
+ accumulator = { samples: [], writeIndex: 0, count: 0, totalMs: 0, maxMs: 0 };
58
+ this.durations.set(method, accumulator);
59
+ }
60
+ accumulator.count++;
61
+ accumulator.totalMs += durationMs;
62
+ if (durationMs > accumulator.maxMs) {
63
+ accumulator.maxMs = durationMs;
64
+ }
65
+ if (this.retention.kind === 'ring-buffer' && accumulator.samples.length >= this.retention.maxSamplesPerMethod) {
66
+ // Buffer full: overwrite the oldest slot in O(1) (percentiles sort, so order does not matter).
67
+ accumulator.samples[accumulator.writeIndex] = durationMs;
68
+ accumulator.writeIndex = (accumulator.writeIndex + 1) % this.retention.maxSamplesPerMethod;
69
+ }
70
+ else {
71
+ accumulator.samples.push(durationMs);
72
+ }
73
+ }
74
+ time(method, call) {
75
+ const stopwatch = this.clock.stopwatch();
76
+ const finish = () => this.record(method, stopwatch.elapsedMs);
77
+ let result;
78
+ try {
79
+ result = call();
80
+ }
81
+ catch (error) {
82
+ finish();
83
+ throw error;
84
+ }
85
+ if (result instanceof Promise) {
86
+ return result.then(value => {
87
+ finish();
88
+ return value;
89
+ }, error => {
90
+ finish();
91
+ throw error;
92
+ });
93
+ }
94
+ finish();
95
+ return result;
96
+ }
97
+ /** Non-destructive snapshot: per-method latencies ordered by total time descending (use {@link reset} to drain). */
98
+ report() {
99
+ const methods = [];
100
+ for (const [method, accumulator] of this.durations) {
101
+ const sorted = [...accumulator.samples].sort((left, right) => left - right);
102
+ methods.push({
103
+ method,
104
+ count: accumulator.count,
105
+ totalMs: accumulator.totalMs,
106
+ maxMs: accumulator.maxMs,
107
+ p50Ms: percentile(sorted, 50),
108
+ p99Ms: percentile(sorted, 99)
109
+ });
110
+ }
111
+ methods.sort((left, right) => right.totalMs - left.totalMs);
112
+ return { windowMs: this.window.elapsedMs, methods };
113
+ }
114
+ /** Drop all samples and restart the window. */
115
+ reset() {
116
+ this.durations.clear();
117
+ this.window = this.clock.stopwatch();
118
+ }
119
+ }
120
+ exports.LatencyCollector = LatencyCollector;
121
+ /**
122
+ * Render a {@link LatencyReport} as a compact ranked table for a log line or a
123
+ * command channel — the latency counterpart to `formatProfileReport`.
124
+ */
125
+ function formatLatencyReport(report, label = 'RPC/LSP latency') {
126
+ const lines = [`${label} (window ${Math.round(report.windowMs)}ms):`];
127
+ if (report.methods.length === 0) {
128
+ lines.push(' (no calls recorded)');
129
+ return lines.join('\n');
130
+ }
131
+ for (const methodLatency of report.methods) {
132
+ lines.push(` ${methodLatency.method} n=${methodLatency.count} total ${Math.round(methodLatency.totalMs)}ms ` +
133
+ `p50 ${Math.round(methodLatency.p50Ms)}ms p99 ${Math.round(methodLatency.p99Ms)}ms max ${Math.round(methodLatency.maxMs)}ms`);
134
+ }
135
+ return lines.join('\n');
136
+ }
137
+ //# sourceMappingURL=latency-collector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"latency-collector.js","sourceRoot":"","sources":["../src/latency-collector.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,119 @@
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
+ export type LogLevel = 'error' | 'warn' | 'info' | 'debug' | 'trace';
10
+ export type LogThreshold = 'off' | LogLevel;
11
+ export declare const LEVEL_ORDER: Record<LogThreshold, number>;
12
+ /** Default labels rendered in the log line, padded to 5 chars so timestamps line up across sources. */
13
+ export declare const LEVEL_LABELS: Record<LogLevel, string>;
14
+ /**
15
+ * Cross-side public logger contract. Every consumer of the framework — browser
16
+ * client extensions, LSP servers, headless CLIs, tests — programs against this
17
+ * interface; concrete implementations supply platform-specific delivery
18
+ * (`AbstractLogger` is the abstract base class that satisfies this contract).
19
+ *
20
+ * Global threshold configuration lives on the {@link Logger} namespace
21
+ * (`Logger.setLevel(...)`, `Logger.getLevel()`, `Logger.isLevelEnabled(...)`).
22
+ *
23
+ * Every emit returns this logger so calls can chain (`logger.error(a).debug(b)`),
24
+ * and every `for` / `sub` / `with` derivation preserves the implementation type.
25
+ */
26
+ export interface Logger {
27
+ /** Log a message at error level. */
28
+ error(message?: string, ...args: unknown[]): this;
29
+ /** Log a message at warn level. */
30
+ warn(message?: string, ...args: unknown[]): this;
31
+ /** Log a message at info level. */
32
+ info(message?: string, ...args: unknown[]): this;
33
+ /** Log a message at debug level. */
34
+ debug(message?: string, ...args: unknown[]): this;
35
+ /** High-volume diagnostic lines, only emitted at the `'trace'` threshold. */
36
+ trace(message?: string, ...args: unknown[]): this;
37
+ /** Log a message at info-level threshold with a `Log` label (rather than `Info`). */
38
+ log(message?: string, ...args: unknown[]): this;
39
+ /** Derive a child logger with `component` as a `Foo :: bar`-style suffix. */
40
+ for(component: string): this;
41
+ /** Derive a child logger by deepening the existing `Foo :: bar :: baz` chain. */
42
+ sub(component: string): this;
43
+ /** Derive a child logger appending `component` as a separate bracket: `[a] [b]`. */
44
+ with(component: string): this;
45
+ /**
46
+ * Derive a child logger labelled with the given URI string. Default behaviour
47
+ * appends the URI as a bracket via {@link with}; subclasses with workspace
48
+ * awareness override to display workspace-relative paths. Subclasses MAY
49
+ * widen the parameter type to accept URI objects directly (TypeScript method
50
+ * parameter bivariance permits this) — callers typed against the {@link Logger}
51
+ * interface stringify their URI at the call site.
52
+ */
53
+ withUri(uri: string): this;
54
+ /**
55
+ * Emit `message` at `threshold`, or do nothing when `threshold === 'off'`.
56
+ * Lets a caller holding a {@link LogThreshold} emit without a hand-written
57
+ * `if (level === 'off') return` guard.
58
+ */
59
+ logAt(threshold: LogThreshold, message: string): this;
60
+ }
61
+ /**
62
+ * Companion namespace for the {@link Logger} interface holding global
63
+ * threshold configuration.
64
+ *
65
+ * The threshold is process-wide: every {@link Logger} instance shares one
66
+ * value, so adopters don't have to wire it through each logger they
67
+ * construct. The timing facilities that build on a logger — `Tracer.time` /
68
+ * `Tracer.startTimer` — consult {@link Logger.isLevelEnabled} internally to
69
+ * short-circuit when the configured level suppresses output.
70
+ */
71
+ export declare namespace Logger {
72
+ /** Set the process-wide log threshold. Every {@link Logger} instance picks up the new value live. */
73
+ function setLevel(level: LogThreshold): void;
74
+ /** Read the current process-wide log threshold. */
75
+ function getLevel(): LogThreshold;
76
+ /**
77
+ * Whether a message at `level` would be emitted at the current threshold.
78
+ * Use to guard expensive log-line construction:
79
+ * `if (Logger.isLevelEnabled('trace')) logger.trace(buildPayload())`.
80
+ */
81
+ function isLevelEnabled(level: LogLevel): boolean;
82
+ /**
83
+ * Whether a message at `threshold` would be emitted: `false` for `'off'`,
84
+ * otherwise tracks {@link isLevelEnabled}. Use to gate work behind a
85
+ * {@link LogThreshold} (which {@link isLevelEnabled} cannot accept).
86
+ */
87
+ function isThresholdEnabled(threshold: LogThreshold): boolean;
88
+ }
89
+ /** True when `value` is one of `'off' | 'error' | 'warn' | 'info' | 'debug' | 'trace'`. */
90
+ export declare function isLogThreshold(value: unknown): value is LogThreshold;
91
+ /**
92
+ * Parse a string-typed configuration value into a {@link LogThreshold}, returning
93
+ * `undefined` for unset or invalid inputs. Case-insensitive — `'WARN'` / `'warn'`
94
+ * / `'Warn'` all normalise to `'warn'`. Use to consume LSP / env-var / CLI inputs
95
+ * without exposing callers to the case-fold detail.
96
+ */
97
+ export declare function parseLogLevel(value: unknown): LogThreshold | undefined;
98
+ /**
99
+ * Names of the environment variables the server consults for its launch-time
100
+ * log configuration. They live in the shared protocol layer because they are
101
+ * the *contract* between whoever launches a server (the CLI, a test harness, a
102
+ * container) and the server that reads them — both sides reference one constant
103
+ * instead of duplicating the literal string.
104
+ */
105
+ export declare const DEFAULT_LOG_LEVEL_ENV = "HYDRANIUM_LOG_LEVEL";
106
+ /** Env var the server reads its log file-tee target from. See {@link DEFAULT_LOG_LEVEL_ENV}. */
107
+ export declare const DEFAULT_LOG_FILE_ENV = "HYDRANIUM_LOG_FILE";
108
+ /**
109
+ * Human-readable formatting helpers used in log lines and diagnostic output.
110
+ */
111
+ export declare namespace Format {
112
+ /** Format a date as `HH:MM:SS.mmm`. Defaults to `now`. */
113
+ function timestamp(d?: Date): string;
114
+ /** Format a millisecond duration: `<1s` as `Nms`, `>=1s` as `N.NNs`. */
115
+ function elapsed(ms: number): string;
116
+ /** Format a byte count with a human-readable unit suffix (B/KB/MB/GB/TB). */
117
+ function bytes(count: number): string;
118
+ }
119
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC;AACrE,MAAM,MAAM,YAAY,GAAG,KAAK,GAAG,QAAQ,CAAC;AAE5C,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,YAAY,EAAE,MAAM,CAA8D,CAAC;AAEpH,uGAAuG;AACvG,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,CAMjD,CAAC;AAMF;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,MAAM;IACpB,oCAAoC;IACpC,KAAK,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAClD,mCAAmC;IACnC,IAAI,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IACjD,mCAAmC;IACnC,IAAI,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IACjD,oCAAoC;IACpC,KAAK,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAClD,6EAA6E;IAC7E,KAAK,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAClD,qFAAqF;IACrF,GAAG,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAChD,6EAA6E;IAC7E,GAAG,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,iFAAiF;IACjF,GAAG,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,oFAAoF;IACpF,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B;;;;;;;OAOG;IACH,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B;;;;OAIG;IACH,KAAK,CAAC,SAAS,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACxD;AAED;;;;;;;;;GASG;AACH,yBAAiB,MAAM,CAAC;IACrB,qGAAqG;IACrG,SAAgB,QAAQ,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI,CAElD;IACD,mDAAmD;IACnD,SAAgB,QAAQ,IAAI,YAAY,CAEvC;IACD;;;;OAIG;IACH,SAAgB,cAAc,CAAC,KAAK,EAAE,QAAQ,GAAG,OAAO,CAEvD;IACD;;;;OAIG;IACH,SAAgB,kBAAkB,CAAC,SAAS,EAAE,YAAY,GAAG,OAAO,CAEnE;CACH;AAED,2FAA2F;AAC3F,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,YAAY,CAEpE;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,YAAY,GAAG,SAAS,CAGtE;AAED;;;;;;GAMG;AACH,eAAO,MAAM,qBAAqB,wBAAwB,CAAC;AAC3D,gGAAgG;AAChG,eAAO,MAAM,oBAAoB,uBAAuB,CAAC;AAEzD;;GAEG;AACH,yBAAiB,MAAM,CAAC;IACrB,0DAA0D;IAC1D,SAAgB,SAAS,CAAC,CAAC,GAAE,IAAiB,GAAG,MAAM,CAMtD;IAED,wEAAwE;IACxE,SAAgB,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAE1C;IAED,6EAA6E;IAC7E,SAAgB,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAY3C;CACH"}
package/lib/logger.js ADDED
@@ -0,0 +1,126 @@
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.Format = exports.DEFAULT_LOG_FILE_ENV = exports.DEFAULT_LOG_LEVEL_ENV = exports.Logger = exports.LEVEL_LABELS = exports.LEVEL_ORDER = void 0;
12
+ exports.isLogThreshold = isLogThreshold;
13
+ exports.parseLogLevel = parseLogLevel;
14
+ exports.LEVEL_ORDER = { off: 0, error: 1, warn: 2, info: 3, debug: 4, trace: 5 };
15
+ /** Default labels rendered in the log line, padded to 5 chars so timestamps line up across sources. */
16
+ exports.LEVEL_LABELS = {
17
+ error: 'Error',
18
+ warn: 'Warn',
19
+ info: 'Info',
20
+ debug: 'Debug',
21
+ trace: 'Trace'
22
+ };
23
+ /** Module-global threshold; shared by every `AbstractLogger` instance so derived child
24
+ * loggers pick up live updates without each having to subscribe to a configuration source. */
25
+ let currentLevel = 'info';
26
+ /**
27
+ * Companion namespace for the {@link Logger} interface holding global
28
+ * threshold configuration.
29
+ *
30
+ * The threshold is process-wide: every {@link Logger} instance shares one
31
+ * value, so adopters don't have to wire it through each logger they
32
+ * construct. The timing facilities that build on a logger — `Tracer.time` /
33
+ * `Tracer.startTimer` — consult {@link Logger.isLevelEnabled} internally to
34
+ * short-circuit when the configured level suppresses output.
35
+ */
36
+ var Logger;
37
+ (function (Logger) {
38
+ /** Set the process-wide log threshold. Every {@link Logger} instance picks up the new value live. */
39
+ function setLevel(level) {
40
+ currentLevel = level;
41
+ }
42
+ Logger.setLevel = setLevel;
43
+ /** Read the current process-wide log threshold. */
44
+ function getLevel() {
45
+ return currentLevel;
46
+ }
47
+ Logger.getLevel = getLevel;
48
+ /**
49
+ * Whether a message at `level` would be emitted at the current threshold.
50
+ * Use to guard expensive log-line construction:
51
+ * `if (Logger.isLevelEnabled('trace')) logger.trace(buildPayload())`.
52
+ */
53
+ function isLevelEnabled(level) {
54
+ return exports.LEVEL_ORDER[level] <= exports.LEVEL_ORDER[currentLevel];
55
+ }
56
+ Logger.isLevelEnabled = isLevelEnabled;
57
+ /**
58
+ * Whether a message at `threshold` would be emitted: `false` for `'off'`,
59
+ * otherwise tracks {@link isLevelEnabled}. Use to gate work behind a
60
+ * {@link LogThreshold} (which {@link isLevelEnabled} cannot accept).
61
+ */
62
+ function isThresholdEnabled(threshold) {
63
+ return threshold !== 'off' && isLevelEnabled(threshold);
64
+ }
65
+ Logger.isThresholdEnabled = isThresholdEnabled;
66
+ })(Logger || (exports.Logger = Logger = {}));
67
+ /** True when `value` is one of `'off' | 'error' | 'warn' | 'info' | 'debug' | 'trace'`. */
68
+ function isLogThreshold(value) {
69
+ return typeof value === 'string' && value in exports.LEVEL_ORDER;
70
+ }
71
+ /**
72
+ * Parse a string-typed configuration value into a {@link LogThreshold}, returning
73
+ * `undefined` for unset or invalid inputs. Case-insensitive — `'WARN'` / `'warn'`
74
+ * / `'Warn'` all normalise to `'warn'`. Use to consume LSP / env-var / CLI inputs
75
+ * without exposing callers to the case-fold detail.
76
+ */
77
+ function parseLogLevel(value) {
78
+ const normalised = typeof value === 'string' ? value.toLowerCase() : undefined;
79
+ return normalised && isLogThreshold(normalised) ? normalised : undefined;
80
+ }
81
+ /**
82
+ * Names of the environment variables the server consults for its launch-time
83
+ * log configuration. They live in the shared protocol layer because they are
84
+ * the *contract* between whoever launches a server (the CLI, a test harness, a
85
+ * container) and the server that reads them — both sides reference one constant
86
+ * instead of duplicating the literal string.
87
+ */
88
+ exports.DEFAULT_LOG_LEVEL_ENV = 'HYDRANIUM_LOG_LEVEL';
89
+ /** Env var the server reads its log file-tee target from. See {@link DEFAULT_LOG_LEVEL_ENV}. */
90
+ exports.DEFAULT_LOG_FILE_ENV = 'HYDRANIUM_LOG_FILE';
91
+ /**
92
+ * Human-readable formatting helpers used in log lines and diagnostic output.
93
+ */
94
+ var Format;
95
+ (function (Format) {
96
+ /** Format a date as `HH:MM:SS.mmm`. Defaults to `now`. */
97
+ function timestamp(d = new Date()) {
98
+ const hh = String(d.getHours()).padStart(2, '0');
99
+ const mm = String(d.getMinutes()).padStart(2, '0');
100
+ const ss = String(d.getSeconds()).padStart(2, '0');
101
+ const ms = String(d.getMilliseconds()).padStart(3, '0');
102
+ return `${hh}:${mm}:${ss}.${ms}`;
103
+ }
104
+ Format.timestamp = timestamp;
105
+ /** Format a millisecond duration: `<1s` as `Nms`, `>=1s` as `N.NNs`. */
106
+ function elapsed(ms) {
107
+ return ms < 1000 ? `${Math.round(ms)}ms` : `${(ms / 1000).toFixed(2)}s`;
108
+ }
109
+ Format.elapsed = elapsed;
110
+ /** Format a byte count with a human-readable unit suffix (B/KB/MB/GB/TB). */
111
+ function bytes(count) {
112
+ if (count < 1024) {
113
+ return `${count}B`;
114
+ }
115
+ const units = ['KB', 'MB', 'GB', 'TB'];
116
+ let value = count / 1024;
117
+ let unit = 0;
118
+ while (value >= 1024 && unit < units.length - 1) {
119
+ value /= 1024;
120
+ unit++;
121
+ }
122
+ return `${value.toFixed(value >= 100 ? 0 : value >= 10 ? 1 : 2)}${units[unit]}`;
123
+ }
124
+ Format.bytes = bytes;
125
+ })(Format || (exports.Format = Format = {}));
126
+ //# sourceMappingURL=logger.js.map