@hydranium/core 1.0.0-next.288 → 1.0.0-next.289
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.
- package/lib/langium/diagnostics/logger.d.ts +9 -1
- package/lib/langium/diagnostics/logger.d.ts.map +1 -1
- package/lib/langium/diagnostics/logger.js +24 -6
- package/lib/langium/diagnostics/logger.js.map +1 -1
- package/lib/langium/workspace/hydranium-workspace-manager.d.ts +4 -3
- package/lib/langium/workspace/hydranium-workspace-manager.d.ts.map +1 -1
- package/lib/langium/workspace/hydranium-workspace-manager.js +7 -6
- package/lib/langium/workspace/hydranium-workspace-manager.js.map +1 -1
- package/lib/node/index.d.ts.map +1 -1
- package/lib/node/index.js +4 -0
- package/lib/node/index.js.map +1 -1
- package/lib/node/startup-cpu-profile.d.ts +29 -0
- package/lib/node/startup-cpu-profile.d.ts.map +1 -0
- package/lib/node/startup-cpu-profile.js +91 -0
- package/lib/node/startup-cpu-profile.js.map +1 -0
- package/lib/testing/playwright/server-log-capture.d.ts +25 -12
- package/lib/testing/playwright/server-log-capture.d.ts.map +1 -1
- package/lib/testing/playwright/server-log-capture.js +94 -39
- package/lib/testing/playwright/server-log-capture.js.map +1 -1
- package/lib/testing/playwright/server-log-rename-reporter.d.ts.map +1 -1
- package/lib/testing/playwright/server-log-rename-reporter.js +4 -3
- package/lib/testing/playwright/server-log-rename-reporter.js.map +1 -1
- package/package.json +6 -6
- package/src/langium/diagnostics/logger.ts +26 -6
- package/src/langium/workspace/hydranium-workspace-manager.ts +7 -6
- package/src/node/index.ts +4 -0
- package/src/node/startup-cpu-profile.ts +94 -0
- package/src/testing/playwright/server-log-capture.ts +98 -41
- package/src/testing/playwright/server-log-rename-reporter.ts +4 -3
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
import { appendFileSync, existsSync, readdirSync, readFileSync, renameSync, unlinkSync, writeFileSync } from 'node:fs';
|
|
10
10
|
import { join } from 'node:path';
|
|
11
11
|
import { fileURLToPath } from 'node:url';
|
|
12
|
-
import { DEFAULT_LOG_FILE_ENV, DEFAULT_LOG_FILE_LEVEL_ENV, DEFAULT_LOG_LEVEL_ENV, parseLogLevel } from '@hydranium/protocol';
|
|
12
|
+
import { DEFAULT_CPU_PROFILE_FILE_ENV, DEFAULT_LOG_FILE_ENV, DEFAULT_LOG_FILE_LEVEL_ENV, DEFAULT_LOG_LEVEL_ENV, parseLogLevel } from '@hydranium/protocol';
|
|
13
13
|
import { toLogFileWorkspaceToken } from '../../langium/diagnostics/log-file-token.js';
|
|
14
14
|
/**
|
|
15
15
|
* Default env var naming the per-test server-log capture directory. Its presence
|
|
@@ -18,6 +18,13 @@ import { toLogFileWorkspaceToken } from '../../langium/diagnostics/log-file-toke
|
|
|
18
18
|
* {@link attachServerLog}.
|
|
19
19
|
*/
|
|
20
20
|
export const DEFAULT_SERVER_LOG_DIR_ENV = 'HYDRANIUM_SERVER_LOG_DIR';
|
|
21
|
+
/**
|
|
22
|
+
* Default env var opting a capture into the servers' CPU profiles: any
|
|
23
|
+
* non-empty value makes {@link captureServerLog} name a
|
|
24
|
+
* `<token>.<pid>.cpuprofile` beside each log, which each server of that
|
|
25
|
+
* workspace writes when it ends.
|
|
26
|
+
*/
|
|
27
|
+
export const DEFAULT_SERVER_CPU_PROFILE_ENV = 'HYDRANIUM_SERVER_CPU_PROFILE';
|
|
21
28
|
/**
|
|
22
29
|
* Default env var providing a central {@link AttachServerLogOptions.attachOn}
|
|
23
30
|
* policy (`'failure' | 'always' | 'never'`) for a whole run, so a debugging
|
|
@@ -50,13 +57,32 @@ function parseBrowserLogLevels(value) {
|
|
|
50
57
|
}
|
|
51
58
|
/** The `{workspace}` placeholder the file-tee expands once the workspace is known. */
|
|
52
59
|
const WORKSPACE_PLACEHOLDER = '{workspace}';
|
|
60
|
+
/**
|
|
61
|
+
* Name of each server's CPU profile beside `<token>.log`. Per process, since
|
|
62
|
+
* every server of a workspace writes one and a write replaces the file.
|
|
63
|
+
*/
|
|
64
|
+
const CPU_PROFILE_NAME = `${WORKSPACE_PLACEHOLDER}.{pid}.cpuprofile`;
|
|
65
|
+
/** Matches the `.<pid>.cpuprofile` ending of a profile named by {@link CPU_PROFILE_NAME}. */
|
|
66
|
+
const CPU_PROFILE_SUFFIX_PATTERN = /\.\d+\.cpuprofile$/;
|
|
67
|
+
/** The `.<pid>.cpuprofile` suffixes of the profiles among `entries` written for `token`. */
|
|
68
|
+
function cpuProfileSuffixes(entries, token) {
|
|
69
|
+
const suffixes = [];
|
|
70
|
+
for (const entry of entries) {
|
|
71
|
+
const suffix = CPU_PROFILE_SUFFIX_PATTERN.exec(entry)?.[0];
|
|
72
|
+
if (suffix !== undefined && entry.slice(0, -suffix.length) === token) {
|
|
73
|
+
suffixes.push(suffix);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return suffixes.sort();
|
|
77
|
+
}
|
|
53
78
|
/**
|
|
54
79
|
* Build the environment to inject into the server process (e.g. a Playwright
|
|
55
80
|
* `webServer.env`) so it writes one per-workspace log file under the capture dir,
|
|
56
81
|
* plus the reporter entry that renames those files to spec names once the run
|
|
57
82
|
* ends. Returns an **empty env, and no reporter, when no dir is configured**, so a
|
|
58
83
|
* normal run is untouched. The `{workspace}` token is expanded server-side once
|
|
59
|
-
* the workspace is known.
|
|
84
|
+
* the workspace is known. With {@link DEFAULT_SERVER_CPU_PROFILE_ENV} set, the
|
|
85
|
+
* env also names a `<token>.<pid>.cpuprofile` per server beside each log.
|
|
60
86
|
*
|
|
61
87
|
* **Publishes a resolved `options.dir` onto {@link DEFAULT_SERVER_LOG_DIR_ENV} in
|
|
62
88
|
* the CALLING process, and that mutation is load-bearing rather than a
|
|
@@ -83,6 +109,9 @@ export function captureServerLog(options = {}) {
|
|
|
83
109
|
parseLogLevel(process.env[DEFAULT_LOG_FILE_LEVEL_ENV]) ??
|
|
84
110
|
parseLogLevel(process.env[DEFAULT_LOG_LEVEL_ENV]) ??
|
|
85
111
|
'debug';
|
|
112
|
+
if (process.env[DEFAULT_SERVER_CPU_PROFILE_ENV]) {
|
|
113
|
+
env[DEFAULT_CPU_PROFILE_FILE_ENV] = join(dir, CPU_PROFILE_NAME);
|
|
114
|
+
}
|
|
86
115
|
const reporterModule = fileURLToPath(new URL('./server-log-rename-reporter.js', import.meta.url));
|
|
87
116
|
return { env, reporter: [reporterModule, { dir }] };
|
|
88
117
|
}
|
|
@@ -103,16 +132,18 @@ export function serverLogSpecName(file) {
|
|
|
103
132
|
return relative.replace(/\.spec\.[cm]?tsx?$/, '').replace(/[^A-Za-z0-9._-]/g, '_');
|
|
104
133
|
}
|
|
105
134
|
/**
|
|
106
|
-
* Rename each `<token>.log` (backend)
|
|
107
|
-
* browser console)
|
|
108
|
-
*
|
|
109
|
-
*
|
|
110
|
-
*
|
|
111
|
-
*
|
|
135
|
+
* Rename each `<token>.log` (backend), `<token>.browser.log` (forwarded
|
|
136
|
+
* browser console) and `<token>.<pid>.cpuprofile` (each server's CPU profile,
|
|
137
|
+
* when {@link DEFAULT_SERVER_CPU_PROFILE_ENV} is set) to the spec name recorded
|
|
138
|
+
* in its `<token>.spec` sidecar (written by {@link markServerLog}), then delete
|
|
139
|
+
* the sidecar. Colliding names — a spec that opened more than one workspace —
|
|
140
|
+
* get a `-2`, `-3`, … suffix. Run once, after all server processes have exited
|
|
141
|
+
* (e.g. a reporter's `onEnd`). Best-effort.
|
|
112
142
|
*
|
|
113
|
-
* Returns the workspace tokens left UNATTRIBUTED — a log
|
|
114
|
-
* no test claimed, because that spec never reached
|
|
115
|
-
* {@link markServerLog} (no `serverLog` fixture, no `beforeEach` call)
|
|
143
|
+
* Returns the workspace tokens left UNATTRIBUTED — a log or CPU profile the
|
|
144
|
+
* capture wrote that no test claimed, because that spec never reached
|
|
145
|
+
* {@link markServerLog} (no `serverLog` fixture, no `beforeEach` call), or
|
|
146
|
+
* because its server never learned its workspace and named it `_startup-<pid>`.
|
|
116
147
|
*
|
|
117
148
|
* **Returned rather than ignored, because the unattributed state is the
|
|
118
149
|
* misleading one.** Such a log still exists, still has content, and is named by
|
|
@@ -130,29 +161,37 @@ export function renameServerLogs(dir) {
|
|
|
130
161
|
// unattributed, since no log was observed at all.
|
|
131
162
|
return [];
|
|
132
163
|
}
|
|
133
|
-
//
|
|
134
|
-
//
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
164
|
+
// One base name per token, free for every file the token has, so a spec's
|
|
165
|
+
// second workspace keeps its log, browser log and profiles paired under one
|
|
166
|
+
// `-N`. A base chosen per file pairs nothing: a profile's suffix carries its
|
|
167
|
+
// pid and never collides, so it would stay at the plain name beside a `-2` log.
|
|
168
|
+
const renameAll = (token, name) => {
|
|
169
|
+
const suffixes = ['.log', '.browser.log', ...cpuProfileSuffixes(entries, token)].filter(suffix => existsSync(join(dir, `${token}${suffix}`)));
|
|
170
|
+
let base = name;
|
|
171
|
+
for (let n = 2; suffixes.some(suffix => existsSync(join(dir, `${base}${suffix}`))); n++) {
|
|
172
|
+
base = `${name}-${n}`;
|
|
140
173
|
}
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
174
|
+
for (const suffix of suffixes) {
|
|
175
|
+
try {
|
|
176
|
+
renameSync(join(dir, `${token}${suffix}`), join(dir, `${base}${suffix}`));
|
|
177
|
+
}
|
|
178
|
+
catch {
|
|
179
|
+
// ignore
|
|
180
|
+
}
|
|
144
181
|
}
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
182
|
+
};
|
|
183
|
+
// Every token the capture produced a backend log or a CPU profile for, so
|
|
184
|
+
// the ones no sidecar claims can be reported rather than silently left behind.
|
|
185
|
+
const unattributed = new Set();
|
|
186
|
+
for (const entry of entries) {
|
|
187
|
+
if (entry.endsWith('.log') && !entry.endsWith('.browser.log')) {
|
|
188
|
+
unattributed.add(entry.slice(0, -'.log'.length));
|
|
148
189
|
}
|
|
149
|
-
|
|
150
|
-
|
|
190
|
+
const profileSuffix = CPU_PROFILE_SUFFIX_PATTERN.exec(entry)?.[0];
|
|
191
|
+
if (profileSuffix !== undefined) {
|
|
192
|
+
unattributed.add(entry.slice(0, -profileSuffix.length));
|
|
151
193
|
}
|
|
152
|
-
}
|
|
153
|
-
// Every token the capture produced a backend log for, so the ones no sidecar
|
|
154
|
-
// claims can be reported rather than silently left behind.
|
|
155
|
-
const unattributed = new Set(entries.filter(entry => entry.endsWith('.log') && !entry.endsWith('.browser.log')).map(entry => entry.slice(0, -'.log'.length)));
|
|
194
|
+
}
|
|
156
195
|
for (const entry of entries) {
|
|
157
196
|
if (!entry.endsWith('.spec')) {
|
|
158
197
|
continue;
|
|
@@ -176,8 +215,7 @@ export function renameServerLogs(dir) {
|
|
|
176
215
|
continue;
|
|
177
216
|
}
|
|
178
217
|
unattributed.delete(token);
|
|
179
|
-
|
|
180
|
-
rename(token, name, '.browser.log');
|
|
218
|
+
renameAll(token, name);
|
|
181
219
|
}
|
|
182
220
|
return [...unattributed];
|
|
183
221
|
}
|
|
@@ -322,8 +360,11 @@ export function findUnexpectedServerLogLines(text, allowlist = {}) {
|
|
|
322
360
|
* server log, so each test's region is delimited within the shared stream;
|
|
323
361
|
* - attaches that log — and the separate browser-console log, when one exists —
|
|
324
362
|
* to the test, so it shows in the HTML report alongside the trace + screenshot.
|
|
325
|
-
*
|
|
326
|
-
*
|
|
363
|
+
* Every CPU profile of the workspace's servers written by then is attached
|
|
364
|
+
* too, so one of a server that ended in an earlier test of the same
|
|
365
|
+
* workspace comes along, and one written after the test is only named after
|
|
366
|
+
* the spec by {@link renameServerLogs}. Which outcomes attach is
|
|
367
|
+
* {@link AttachServerLogOptions.attachOn}, failure-only by default.
|
|
327
368
|
*
|
|
328
369
|
* **No-op when no capture dir is configured** (`options.dir` and the default env
|
|
329
370
|
* var both unset), so a normal run is untouched — no per-spec guard needed.
|
|
@@ -348,18 +389,32 @@ export async function attachServerLog(testInfo, workspacePath, options = {}) {
|
|
|
348
389
|
if (!shouldAttach) {
|
|
349
390
|
return;
|
|
350
391
|
}
|
|
351
|
-
// Attach
|
|
352
|
-
// browser-console log, so a failing test carries the frontend side too
|
|
392
|
+
// Attach every stream present: the backend server log, the separate
|
|
393
|
+
// browser-console log, so a failing test carries the frontend side too, and
|
|
394
|
+
// the CPU profile of each server of the workspace that has already ended.
|
|
395
|
+
const token = toLogFileWorkspaceToken(workspacePath);
|
|
396
|
+
let entries = [];
|
|
397
|
+
try {
|
|
398
|
+
entries = readdirSync(dir);
|
|
399
|
+
}
|
|
400
|
+
catch {
|
|
401
|
+
// No profiles to attach; the logs below are checked one by one.
|
|
402
|
+
}
|
|
353
403
|
const attachments = [
|
|
354
|
-
{ name: 'server-log', path: file },
|
|
355
|
-
{ name: 'browser-console-log', path: join(dir, `${
|
|
404
|
+
{ name: 'server-log', path: file, contentType: 'text/plain' },
|
|
405
|
+
{ name: 'browser-console-log', path: join(dir, `${token}.browser.log`), contentType: 'text/plain' },
|
|
406
|
+
...cpuProfileSuffixes(entries, token).map(suffix => ({
|
|
407
|
+
name: 'server-cpu-profile',
|
|
408
|
+
path: join(dir, `${token}${suffix}`),
|
|
409
|
+
contentType: 'application/json'
|
|
410
|
+
}))
|
|
356
411
|
];
|
|
357
412
|
for (const attachment of attachments) {
|
|
358
413
|
if (!existsSync(attachment.path)) {
|
|
359
414
|
continue;
|
|
360
415
|
}
|
|
361
416
|
try {
|
|
362
|
-
await testInfo.attach(attachment.name, { path: attachment.path, contentType:
|
|
417
|
+
await testInfo.attach(attachment.name, { path: attachment.path, contentType: attachment.contentType });
|
|
363
418
|
}
|
|
364
419
|
catch {
|
|
365
420
|
// Attaching must not break the test run.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server-log-capture.js","sourceRoot":"","sources":["../../../src/testing/playwright/server-log-capture.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"server-log-capture.js","sourceRoot":"","sources":["../../../src/testing/playwright/server-log-capture.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACvH,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EACJ,4BAA4B,EAC5B,oBAAoB,EACpB,0BAA0B,EAC1B,qBAAqB,EAErB,aAAa,EACf,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,uBAAuB,EAAE,MAAM,6CAA6C,CAAC;AAEtF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG,0BAA0B,CAAC;AACrE;;;;;GAKG;AACH,MAAM,CAAC,MAAM,8BAA8B,GAAG,8BAA8B,CAAC;AAC7E;;;;;GAKG;AACH,MAAM,CAAC,MAAM,6BAA6B,GAAG,6BAA6B,CAAC;AAC3E;;;;;GAKG;AACH,MAAM,CAAC,MAAM,8BAA8B,GAAG,8BAA8B,CAAC;AAE7E,+GAA+G;AAC/G,MAAM,CAAC,MAAM,0BAA0B,GAAsB,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;AAKlF,SAAS,aAAa,CAAC,KAAyB;IAC7C,OAAO,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;AAC7F,CAAC;AAED,mFAAmF;AACnF,SAAS,qBAAqB,CAAC,KAAyB;IACrD,IAAI,CAAC,KAAK,EAAE,CAAC;QACV,OAAO,SAAS,CAAC;IACpB,CAAC;IACD,MAAM,MAAM,GAAG,KAAK;SAChB,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;SAC1B,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACtC,OAAO,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;AACjD,CAAC;AAED,sFAAsF;AACtF,MAAM,qBAAqB,GAAG,aAAa,CAAC;AAC5C;;;GAGG;AACH,MAAM,gBAAgB,GAAG,GAAG,qBAAqB,mBAAmB,CAAC;AAErE,6FAA6F;AAC7F,MAAM,0BAA0B,GAAG,oBAAoB,CAAC;AAExD,4FAA4F;AAC5F,SAAS,kBAAkB,CAAC,OAA0B,EAAE,KAAa;IAClE,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC3B,MAAM,MAAM,GAAG,0BAA0B,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAC3D,IAAI,MAAM,KAAK,SAAS,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,KAAK,EAAE,CAAC;YACpE,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACzB,CAAC;IACJ,CAAC;IACD,OAAO,QAAQ,CAAC,IAAI,EAAE,CAAC;AAC1B,CAAC;AA0CD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,gBAAgB,CAAC,OAAO,GAA4B,EAAE;IACnE,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAC;IACnE,IAAI,CAAC,GAAG,EAAE,CAAC;QACR,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC;IACtB,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,0BAA0B,CAAC,GAAG,GAAG,CAAC;IAC9C,MAAM,GAAG,GAA2B;QACjC,CAAC,oBAAoB,CAAC,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,qBAAqB,MAAM,CAAC;KACnE,CAAC;IACF,GAAG,CAAC,0BAA0B,CAAC;QAC5B,OAAO,CAAC,KAAK;YACb,aAAa,CAAC,OAAO,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAC;YACtD,aAAa,CAAC,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;YACjD,OAAO,CAAC;IACX,IAAI,OAAO,CAAC,GAAG,CAAC,8BAA8B,CAAC,EAAE,CAAC;QAC/C,GAAG,CAAC,4BAA4B,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,gBAAgB,CAAC,CAAC;IACnE,CAAC;IACD,MAAM,cAAc,GAAG,aAAa,CAAC,IAAI,GAAG,CAAC,iCAAiC,EAAE,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IAClG,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,CAAC,cAAc,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC;AACvD,CAAC;AAiBD;;;;;;;;;GASG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC3C,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IACtC,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC;IACxC,MAAM,QAAQ,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;IACvG,OAAO,QAAQ,CAAC,OAAO,CAAC,oBAAoB,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,kBAAkB,EAAE,GAAG,CAAC,CAAC;AACtF,CAAC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,gBAAgB,CAAC,GAAW;IACzC,IAAI,OAAiB,CAAC;IACtB,IAAI,CAAC;QACF,OAAO,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;IAC9B,CAAC;IAAC,MAAM,CAAC;QACN,sEAAsE;QACtE,kDAAkD;QAClD,OAAO,EAAE,CAAC;IACb,CAAC;IACD,0EAA0E;IAC1E,4EAA4E;IAC5E,6EAA6E;IAC7E,gFAAgF;IAChF,MAAM,SAAS,GAAG,CAAC,KAAa,EAAE,IAAY,EAAQ,EAAE;QACrD,MAAM,QAAQ,GAAG,CAAC,MAAM,EAAE,cAAc,EAAE,GAAG,kBAAkB,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAC9F,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,GAAG,MAAM,EAAE,CAAC,CAAC,CAC5C,CAAC;QACF,IAAI,IAAI,GAAG,IAAI,CAAC;QAChB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,GAAG,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YACvF,IAAI,GAAG,GAAG,IAAI,IAAI,CAAC,EAAE,CAAC;QACzB,CAAC;QACD,KAAK,MAAM,MAAM,IAAI,QAAQ,EAAE,CAAC;YAC7B,IAAI,CAAC;gBACF,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,GAAG,MAAM,EAAE,CAAC,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,GAAG,MAAM,EAAE,CAAC,CAAC,CAAC;YAC7E,CAAC;YAAC,MAAM,CAAC;gBACN,SAAS;YACZ,CAAC;QACJ,CAAC;IACJ,CAAC,CAAC;IACF,0EAA0E;IAC1E,+EAA+E;IAC/E,MAAM,YAAY,GAAG,IAAI,GAAG,EAAU,CAAC;IACvC,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC3B,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC;YAC7D,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;QACpD,CAAC;QACD,MAAM,aAAa,GAAG,0BAA0B,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAClE,IAAI,aAAa,KAAK,SAAS,EAAE,CAAC;YAC/B,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC;QAC3D,CAAC;IACJ,CAAC;IACD,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC3B,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;YAC5B,SAAS;QACZ,CAAC;QACD,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QACjC,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAC9C,IAAI,IAAY,CAAC;QACjB,IAAI,CAAC;YACF,IAAI,GAAG,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;QAChD,CAAC;QAAC,MAAM,CAAC;YACN,SAAS;QACZ,CAAC;QACD,IAAI,CAAC;YACF,UAAU,CAAC,OAAO,CAAC,CAAC;QACvB,CAAC;QAAC,MAAM,CAAC;YACN,SAAS;QACZ,CAAC;QACD,IAAI,CAAC,IAAI,EAAE,CAAC;YACT,SAAS;QACZ,CAAC;QACD,YAAY,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC3B,SAAS,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAC1B,CAAC;IACD,OAAO,CAAC,GAAG,YAAY,CAAC,CAAC;AAC5B,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,oBAAoB,CAAC,aAAqB,EAAE,OAAO,GAAqB,EAAE;IACvF,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAC;IACnE,IAAI,CAAC,GAAG,EAAE,CAAC;QACR,OAAO,SAAS,CAAC;IACpB,CAAC;IACD,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,uBAAuB,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;AACrE,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,4BAA4B,CAAC,aAAqB,EAAE,OAAO,GAAqB,EAAE;IAC/F,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAC;IACnE,IAAI,CAAC,GAAG,EAAE,CAAC;QACR,OAAO,SAAS,CAAC;IACpB,CAAC;IACD,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,uBAAuB,CAAC,aAAa,CAAC,cAAc,CAAC,CAAC;AAC7E,CAAC;AAoBD;;;;;GAKG;AACH,MAAM,UAAU,aAAa,CAAC,QAA2B,EAAE,aAAqB,EAAE,OAAO,GAA2B,EAAE;IACnH,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAC;IACnE,IAAI,CAAC,GAAG,EAAE,CAAC;QACR,OAAO;IACV,CAAC;IACD,MAAM,KAAK,GAAG,uBAAuB,CAAC,aAAa,CAAC,CAAC;IACrD,IAAI,CAAC;QACF,cAAc,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,MAAM,CAAC,EAAE,kBAAkB,QAAQ,CAAC,KAAK,UAAU,CAAC,CAAC;IACzF,CAAC;IAAC,MAAM,CAAC;QACN,sEAAsE;IACzE,CAAC;IACD,+EAA+E;IAC/E,kFAAkF;IAClF,IAAI,QAAQ,CAAC,IAAI,EAAE,CAAC;QACjB,IAAI,CAAC;YACF,aAAa,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC,EAAE,iBAAiB,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;QAC/E,CAAC;QAAC,MAAM,CAAC;YACN,SAAS;QACZ,CAAC;IACJ,CAAC;AACJ,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,eAAe,CAAC,aAAqB,EAAE,IAAY,EAAE,OAAO,GAAqB,EAAE;IAChG,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAC;IACnE,IAAI,CAAC,GAAG,EAAE,CAAC;QACR,OAAO;IACV,CAAC;IACD,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,uBAAuB,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;IACxE,IAAI,CAAC;QACF,cAAc,CAAC,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,CAAC,CAAC;IAClE,CAAC;IAAC,MAAM,CAAC;QACN,+DAA+D;IAClE,CAAC;AACJ,CAAC;AAkBD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,qBAAqB,CAClC,IAAqB,EACrB,aAAqB,EACrB,OAAO,GAAiD,EAAE;IAE1D,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAC;IACnE,IAAI,CAAC,GAAG,EAAE,CAAC;QACR,OAAO;IACV,CAAC;IACD,MAAM,MAAM,GAAG,IAAI,GAAG,CACnB,OAAO,CAAC,MAAM,IAAI,qBAAqB,CAAC,OAAO,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAC,IAAI,0BAA0B,CACpH,CAAC;IACF,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,uBAAuB,CAAC,aAAa,CAAC,cAAc,CAAC,CAAC;IAChF,IAAI,CAAC,EAAE,CAAC,SAAS,EAAE,OAAO,CAAC,EAAE;QAC1B,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;QAC5B,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YACrB,OAAO;QACV,CAAC;QACD,IAAI,CAAC;YACF,cAAc,CAAC,IAAI,EAAE,cAAc,IAAI,KAAK,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QACnE,CAAC;QAAC,MAAM,CAAC;YACN,+DAA+D;QAClE,CAAC;IACJ,CAAC,CAAC,CAAC;AACN,CAAC;AAED,+FAA+F;AAC/F,MAAM,kBAAkB,GAAG,qBAAqB,CAAC;AAEjD;;;;;GAKG;AACH,MAAM,UAAU,4BAA4B,CAAC,IAAY,EAAE,SAAS,GAAqC,EAAE;IACxG,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IAC1C,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAC1H,CAAC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAClC,QAA2B,EAC3B,aAAqB,EACrB,OAAO,GAA2B,EAAE;IAEpC,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAC;IACnE,IAAI,CAAC,GAAG,EAAE,CAAC;QACR,OAAO;IACV,CAAC;IACD,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,uBAAuB,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;IACxE,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,IAAI,SAAS,CAAC;IAC5C,IAAI,CAAC;QACF,cAAc,CAAC,IAAI,EAAE,gBAAgB,QAAQ,CAAC,KAAK,MAAM,MAAM,UAAU,CAAC,CAAC;IAC9E,CAAC;IAAC,MAAM,CAAC;QACN,sEAAsE;IACzE,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,QAAQ,CAAC,cAAc,IAAI,QAAQ,CAAC,CAAC;IAChE,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,aAAa,CAAC,OAAO,CAAC,GAAG,CAAC,6BAA6B,CAAC,CAAC,IAAI,SAAS,CAAC;IAC5G,MAAM,YAAY,GAAG,QAAQ,KAAK,QAAQ,IAAI,CAAC,QAAQ,KAAK,SAAS,IAAI,MAAM,CAAC,CAAC;IACjF,IAAI,CAAC,YAAY,EAAE,CAAC;QACjB,OAAO;IACV,CAAC;IACD,oEAAoE;IACpE,4EAA4E;IAC5E,0EAA0E;IAC1E,MAAM,KAAK,GAAG,uBAAuB,CAAC,aAAa,CAAC,CAAC;IACrD,IAAI,OAAO,GAAa,EAAE,CAAC;IAC3B,IAAI,CAAC;QACF,OAAO,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;IAC9B,CAAC;IAAC,MAAM,CAAC;QACN,gEAAgE;IACnE,CAAC;IACD,MAAM,WAAW,GAA0D;QACxE,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,IAAI,EAAE,WAAW,EAAE,YAAY,EAAE;QAC7D,EAAE,IAAI,EAAE,qBAAqB,EAAE,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,cAAc,CAAC,EAAE,WAAW,EAAE,YAAY,EAAE;QACnG,GAAG,kBAAkB,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YAClD,IAAI,EAAE,oBAAoB;YAC1B,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,GAAG,MAAM,EAAE,CAAC;YACpC,WAAW,EAAE,kBAAkB;SACjC,CAAC,CAAC;KACL,CAAC;IACF,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE,CAAC;QACpC,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YAChC,SAAS;QACZ,CAAC;QACD,IAAI,CAAC;YACF,MAAM,QAAQ,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,UAAU,CAAC,IAAI,EAAE,WAAW,EAAE,UAAU,CAAC,WAAW,EAAE,CAAC,CAAC;QAC1G,CAAC;QAAC,MAAM,CAAC;YACN,yCAAyC;QAC5C,CAAC;IACJ,CAAC;AACJ,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server-log-rename-reporter.d.ts","sourceRoot":"","sources":["../../../src/testing/playwright/server-log-rename-reporter.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,OAAO,EAAoB,KAAK,8BAA8B,EAAE,MAAM,yBAAyB,CAAC;AAEhG;;;;;;GAMG;AACH,MAAM,CAAC,OAAO,OAAO,uBAAuB;IACzC,SAAS,CAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IAE/B,YAAY,OAAO,EAAE,8BAA8B,EAElD;IAED,KAAK,IAAI,IAAI,
|
|
1
|
+
{"version":3,"file":"server-log-rename-reporter.d.ts","sourceRoot":"","sources":["../../../src/testing/playwright/server-log-rename-reporter.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,OAAO,EAAoB,KAAK,8BAA8B,EAAE,MAAM,yBAAyB,CAAC;AAEhG;;;;;;GAMG;AACH,MAAM,CAAC,OAAO,OAAO,uBAAuB;IACzC,SAAS,CAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IAE/B,YAAY,OAAO,EAAE,8BAA8B,EAElD;IAED,KAAK,IAAI,IAAI,CAcZ;CACH"}
|
|
@@ -26,9 +26,10 @@ export default class ServerLogRenameReporter {
|
|
|
26
26
|
// complete: these logs exist and have content, but are named by an
|
|
27
27
|
// opaque workspace token and carry no test boundaries, so nothing
|
|
28
28
|
// about them says which spec they belong to.
|
|
29
|
-
console.warn(`[server-log] ${unattributed.length}
|
|
30
|
-
'[server-log]
|
|
31
|
-
'or call `markServerLog`/`attachServerLog` from the suite, or
|
|
29
|
+
console.warn(`[server-log] ${unattributed.length} workspace(s) left captured logs or profiles that belong to no test: ${unattributed.join(', ')}.\n` +
|
|
30
|
+
'[server-log] A workspace token means its spec never marked a boundary — apply the `serverLog` fixture, ' +
|
|
31
|
+
'or call `markServerLog`/`attachServerLog` from the suite, or its logs cannot be read per test. ' +
|
|
32
|
+
'A `_startup-<pid>` name is a server that never learned its workspace, so no spec can claim its files.');
|
|
32
33
|
}
|
|
33
34
|
}
|
|
34
35
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server-log-rename-reporter.js","sourceRoot":"","sources":["../../../src/testing/playwright/server-log-rename-reporter.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,OAAO,EAAE,gBAAgB,EAAuC,MAAM,yBAAyB,CAAC;AAEhG;;;;;;GAMG;AACH,MAAM,CAAC,OAAO,OAAO,uBAAuB;IACtB,GAAG,CAAS;IAE/B,YAAY,OAAuC;QAChD,IAAI,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC;IAC1B,CAAC;IAED,KAAK;QACF,MAAM,YAAY,GAAG,gBAAgB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAChD,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC3B,+DAA+D;YAC/D,mEAAmE;YACnE,kEAAkE;YAClE,6CAA6C;YAC7C,OAAO,CAAC,IAAI,CACT,gBAAgB,YAAY,CAAC,MAAM,
|
|
1
|
+
{"version":3,"file":"server-log-rename-reporter.js","sourceRoot":"","sources":["../../../src/testing/playwright/server-log-rename-reporter.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,OAAO,EAAE,gBAAgB,EAAuC,MAAM,yBAAyB,CAAC;AAEhG;;;;;;GAMG;AACH,MAAM,CAAC,OAAO,OAAO,uBAAuB;IACtB,GAAG,CAAS;IAE/B,YAAY,OAAuC;QAChD,IAAI,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC;IAC1B,CAAC;IAED,KAAK;QACF,MAAM,YAAY,GAAG,gBAAgB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAChD,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC3B,+DAA+D;YAC/D,mEAAmE;YACnE,kEAAkE;YAClE,6CAA6C;YAC7C,OAAO,CAAC,IAAI,CACT,gBAAgB,YAAY,CAAC,MAAM,wEAAwE,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK;gBACpI,yGAAyG;gBACzG,iGAAiG;gBACjG,uGAAuG,CAC5G,CAAC;QACL,CAAC;IACJ,CAAC;CACH"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hydranium/core",
|
|
3
|
-
"version": "1.0.0-next.
|
|
3
|
+
"version": "1.0.0-next.289",
|
|
4
4
|
"description": "Foundational runtime of the hydranium framework: AST coordination layer (services, integrity, AST extension, serialization, multi-client documents) plus the LSP textual head at the /lsp subpath. Consumed by protocol-head packages (@hydranium/data-server, @hydranium/glsp-server).",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ast",
|
|
@@ -83,8 +83,8 @@
|
|
|
83
83
|
"diff": "^5.2.0"
|
|
84
84
|
},
|
|
85
85
|
"devDependencies": {
|
|
86
|
-
"@hydranium/langium": "1.0.0-next.
|
|
87
|
-
"@hydranium/protocol": "1.0.0-next.
|
|
86
|
+
"@hydranium/langium": "1.0.0-next.289",
|
|
87
|
+
"@hydranium/protocol": "1.0.0-next.289",
|
|
88
88
|
"@playwright/test": "^1.40.0",
|
|
89
89
|
"@types/diff": "^5.2.0",
|
|
90
90
|
"rimraf": "^5.0.0",
|
|
@@ -96,8 +96,8 @@
|
|
|
96
96
|
"vscode-languageserver-types": "^3.17.5"
|
|
97
97
|
},
|
|
98
98
|
"peerDependencies": {
|
|
99
|
-
"@hydranium/langium": "1.0.0-next.
|
|
100
|
-
"@hydranium/protocol": "1.0.0-next.
|
|
99
|
+
"@hydranium/langium": "1.0.0-next.289",
|
|
100
|
+
"@hydranium/protocol": "1.0.0-next.289",
|
|
101
101
|
"@playwright/test": "^1.40.0",
|
|
102
102
|
"vscode-jsonrpc": "^9.0.0",
|
|
103
103
|
"vscode-languageserver": "~10.0.1",
|
|
@@ -115,5 +115,5 @@
|
|
|
115
115
|
},
|
|
116
116
|
"//peerDependencies": "`vscode-jsonrpc` takes a caret, so the framework shares the transport the LSP connection resolves, which an `init` scaffold pins: each `vscode-languageserver-protocol` release pins its transport exactly, so an exact peer would name a copy a fresh install rarely holds. The caret excludes 8.x, so a tree whose top holds GLSP's copy fails the peer with a named ERESOLVE warning, an error under `--strict-peer-deps`, rather than resolving silently. No peer reaches a NESTED copy, such as GLSP's or one the LSP packages nest. The wire compares message types and `ResponseError`s by copy identity, so the framework sends typed messages by method name and recognises errors with `isResponseError` rather than `instanceof`. This manifest declares the two links ABOVE the transport as well, with `~`: each admits exactly what the pinned `langium` itself admits, and a range reaching back past the 3.18 stack admits a release on the 8.x transport. `vscode-languageserver-types` and `vscode-languageserver-textdocument` are deliberately NOT narrowed: both declare zero dependencies and expose structural APIs, so a duplicate of either drags no transport in and no identity check reads it.",
|
|
117
117
|
"//prepack": "The publish guard, a `prepack` rather than a `prepare`: `prepack` runs only when a tarball is made (`npm pack`, `npm publish`) and never on install, so it cannot break the install it has no business touching. What it defends against: `files` lists `lib`, `lib` is gitignored, and a `files` entry matching nothing is skipped SILENTLY — so `npm publish` from an unbuilt tree emits a tarball of `src` and nothing else, with no error.",
|
|
118
|
-
"//sideEffects": "NOT `false`: two barrels do work at module load that their re-exports do not account for, and a bundler skips an unflagged re-export barrel outright. `node/index.js` calls `installNodeLogFileSink()` and `
|
|
118
|
+
"//sideEffects": "NOT `false`: two barrels do work at module load that their re-exports do not account for, and a bundler skips an unflagged re-export barrel outright. `node/index.js` calls `installNodeLogFileSink()`, `installNodeWriteLockScope()` and `startCpuProfileFromEnv()`, which is how a Node host gets the log file-tee, write-lock reentrancy detection and the `HYDRANIUM_CPU_PROFILE_FILE` profile merely by importing `@hydranium/core/node`. `util/index.js` carries a bare `import '@hydranium/langium'` so the `UriUtils` namespace augmentation stays loaded for anything importing from here. All three failures are runtime-only and silent — a missing log file, a missing profile, a `UriUtils.toUri` that is `undefined`."
|
|
119
119
|
}
|
|
@@ -69,6 +69,28 @@ const pendingLogLines: string[] = [];
|
|
|
69
69
|
/** Matches any remaining `{name}` placeholder token. */
|
|
70
70
|
const PLACEHOLDER_PATTERN = /\{[^}]+\}/;
|
|
71
71
|
|
|
72
|
+
/**
|
|
73
|
+
* `template` with `{pid}` replaced by the process id, known from the start, and
|
|
74
|
+
* each placeholder supplied so far by its value.
|
|
75
|
+
*/
|
|
76
|
+
function substituteLogFilePlaceholders(template: string): string {
|
|
77
|
+
let path = template.split('{pid}').join(String(processPid() ?? 'unknown'));
|
|
78
|
+
for (const [name, value] of logFilePlaceholders) {
|
|
79
|
+
path = path.split(`{${name}}`).join(value);
|
|
80
|
+
}
|
|
81
|
+
return path;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Expand `template` the way the file-tee names its file: `{pid}` and each
|
|
86
|
+
* supplied placeholder by its value, each one still missing by
|
|
87
|
+
* `_startup-<pid>`. A file written beside the log, such as the CPU profile,
|
|
88
|
+
* names itself through this so both carry the same workspace token.
|
|
89
|
+
*/
|
|
90
|
+
export function expandLogFilePlaceholders(template: string): string {
|
|
91
|
+
return substituteLogFilePlaceholders(template).replace(new RegExp(PLACEHOLDER_PATTERN, 'g'), `_startup-${processPid() ?? 'unknown'}`);
|
|
92
|
+
}
|
|
93
|
+
|
|
72
94
|
/**
|
|
73
95
|
* Recompute {@link resolvedLogFilePath} from the template + known placeholders.
|
|
74
96
|
* Resolves (and flushes the pending buffer) only once no `{...}` token remains.
|
|
@@ -78,10 +100,7 @@ function tryResolveLogFilePath(): void {
|
|
|
78
100
|
resolvedLogFilePath = undefined;
|
|
79
101
|
return;
|
|
80
102
|
}
|
|
81
|
-
|
|
82
|
-
for (const [name, value] of logFilePlaceholders) {
|
|
83
|
-
path = path.split(`{${name}}`).join(value);
|
|
84
|
-
}
|
|
103
|
+
const path = substituteLogFilePlaceholders(logFileTemplate);
|
|
85
104
|
if (PLACEHOLDER_PATTERN.test(path)) {
|
|
86
105
|
resolvedLogFilePath = undefined;
|
|
87
106
|
// Target is pending — guarantee the buffer is flushed even if the process
|
|
@@ -116,7 +135,8 @@ function flushPendingLogLines(): void {
|
|
|
116
135
|
/**
|
|
117
136
|
* Set the file-tee target programmatically. Pass `undefined` to disable. The
|
|
118
137
|
* path may contain `{placeholder}` tokens (e.g. `{workspace}`); lines buffer
|
|
119
|
-
* until every token is supplied via {@link resolveLogFilePlaceholder}
|
|
138
|
+
* until every token is supplied via {@link resolveLogFilePlaceholder}, except
|
|
139
|
+
* `{pid}`, which is the process id from the start.
|
|
120
140
|
* Called by the `LspLogger` constructor's
|
|
121
141
|
* one-time `HYDRANIUM_LOG_FILE` env baseline (and by tests).
|
|
122
142
|
*
|
|
@@ -156,7 +176,7 @@ export function flushLogFileFallback(): void {
|
|
|
156
176
|
if (!logFileTemplate || resolvedLogFilePath || pendingLogLines.length === 0) {
|
|
157
177
|
return;
|
|
158
178
|
}
|
|
159
|
-
resolvedLogFilePath = logFileTemplate
|
|
179
|
+
resolvedLogFilePath = expandLogFilePlaceholders(logFileTemplate);
|
|
160
180
|
ensureLogDir(resolvedLogFilePath);
|
|
161
181
|
flushPendingLogLines();
|
|
162
182
|
}
|
|
@@ -285,9 +285,9 @@ export class HydraniumWorkspaceManager extends DefaultWorkspaceManager {
|
|
|
285
285
|
}
|
|
286
286
|
|
|
287
287
|
protected override async performStartup(folders: WorkspaceFolder[]): Promise<LangiumDocument[]> {
|
|
288
|
-
//
|
|
289
|
-
//
|
|
290
|
-
//
|
|
288
|
+
// Supply the `{workspace}` placeholder as early as possible — before any
|
|
289
|
+
// build logging — so per-workspace log capture names its file correctly
|
|
290
|
+
// and the buffered startup lines flush; the CPU profile reads it too.
|
|
291
291
|
this.resolveWorkspaceLogTarget(folders);
|
|
292
292
|
// Snapshot the document set around discovery so the descriptor documents
|
|
293
293
|
// it creates can be identified afterwards. Plain iteration rather than
|
|
@@ -512,9 +512,10 @@ export class HydraniumWorkspaceManager extends DefaultWorkspaceManager {
|
|
|
512
512
|
}
|
|
513
513
|
|
|
514
514
|
/**
|
|
515
|
-
*
|
|
516
|
-
*
|
|
517
|
-
* target is configured.
|
|
515
|
+
* Supply the `{workspace}` placeholder from the first workspace folder, which
|
|
516
|
+
* the log file-tee and the CPU profile's file name both read, whether or not
|
|
517
|
+
* a log target is configured. No-op when no folder is known. See
|
|
518
|
+
* {@link toLogFileWorkspaceToken} for the token
|
|
518
519
|
* derivation — a log-capturing test harness uses the same function so the
|
|
519
520
|
* server's file name and the harness's correlation key agree.
|
|
520
521
|
*/
|
package/src/node/index.ts
CHANGED
|
@@ -18,7 +18,10 @@
|
|
|
18
18
|
// Node hosts also get workspace-write-lock reentrancy detection for free, by the
|
|
19
19
|
// same mechanism and for the same reason: the check needs `node:async_hooks`, so
|
|
20
20
|
// the neutral tree can only declare the seam.
|
|
21
|
+
// A Node host is also profiled from here when `HYDRANIUM_CPU_PROFILE_FILE` is
|
|
22
|
+
// set, so the profile covers the workspace load that follows the import.
|
|
21
23
|
import { installNodeLogFileSink } from './log-file-sink.js';
|
|
24
|
+
import { startCpuProfileFromEnv } from './startup-cpu-profile.js';
|
|
22
25
|
import { installNodeWriteLockScope } from './write-lock-scope-node.js';
|
|
23
26
|
|
|
24
27
|
export * from './node-file-system-provider.js';
|
|
@@ -51,3 +54,4 @@ export * from './validate-workspace.js';
|
|
|
51
54
|
|
|
52
55
|
installNodeLogFileSink();
|
|
53
56
|
installNodeWriteLockScope();
|
|
57
|
+
startCpuProfileFromEnv();
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/********************************************************************************
|
|
2
|
+
* Copyright (c) 2026 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
|
+
import { DEFAULT_CPU_PROFILE_FILE_ENV } from '@hydranium/protocol';
|
|
11
|
+
import { mkdirSync, writeFileSync } from 'node:fs';
|
|
12
|
+
import { Session } from 'node:inspector';
|
|
13
|
+
import { dirname } from 'node:path';
|
|
14
|
+
import { isMainThread } from 'node:worker_threads';
|
|
15
|
+
import { expandLogFilePlaceholders } from '../langium/diagnostics/logger.js';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Marks the profile started on `globalThis` rather than in this module, since
|
|
19
|
+
* a second installed copy of the package loads its own module and would start
|
|
20
|
+
* a second session writing a profile of its own.
|
|
21
|
+
*/
|
|
22
|
+
const CPU_PROFILE_STARTED: unique symbol = Symbol.for('@hydranium/core#startupCpuProfileStarted');
|
|
23
|
+
const processGlobal = globalThis as typeof globalThis & { [CPU_PROFILE_STARTED]?: true };
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Start profiling this process when {@link DEFAULT_CPU_PROFILE_FILE_ENV} is
|
|
27
|
+
* set, and write the profile once, on `exit` or on SIGTERM. Called when
|
|
28
|
+
* `@hydranium/core/node` loads, so every Node head is profiled from before its
|
|
29
|
+
* workspace load; a no-op on a second call, from any copy of the package, and
|
|
30
|
+
* in a `worker_threads` worker.
|
|
31
|
+
*
|
|
32
|
+
* `--cpu-prof` is no substitute: it writes only on a normal exit, and SIGTERM
|
|
33
|
+
* ends a process without one. The SIGTERM listener re-raises the signal when it
|
|
34
|
+
* is the only one, so the process still ends by it; another listener keeps
|
|
35
|
+
* control of the ending. Samples accumulate for the life of the process, so
|
|
36
|
+
* this is for test runs, not a production server.
|
|
37
|
+
*
|
|
38
|
+
* A head in a worker is not profiled: a worker's session would write the main
|
|
39
|
+
* thread's file, since threads share the pid, no signal reaches it, and its
|
|
40
|
+
* `exit` listeners run neither when it is terminated nor when the process ends.
|
|
41
|
+
*
|
|
42
|
+
* A `ProfileCapture` window runs beside it in its own inspector session.
|
|
43
|
+
*/
|
|
44
|
+
export function startCpuProfileFromEnv(): void {
|
|
45
|
+
const template = process.env[DEFAULT_CPU_PROFILE_FILE_ENV];
|
|
46
|
+
if (!template || !isMainThread || processGlobal[CPU_PROFILE_STARTED]) {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
processGlobal[CPU_PROFILE_STARTED] = true;
|
|
50
|
+
const session = new Session();
|
|
51
|
+
session.connect();
|
|
52
|
+
session.post('Profiler.enable');
|
|
53
|
+
session.post('Profiler.start');
|
|
54
|
+
let written = false;
|
|
55
|
+
// Synchronous throughout: an in-process session answers `post` before it
|
|
56
|
+
// returns, and nothing asynchronous runs after `exit`. The session is
|
|
57
|
+
// disconnected from the answer, so nothing here depends on that order.
|
|
58
|
+
const write = (): void => {
|
|
59
|
+
if (written) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
written = true;
|
|
63
|
+
const file = expandLogFilePlaceholders(template);
|
|
64
|
+
session.post('Profiler.stop', (error, result) => {
|
|
65
|
+
try {
|
|
66
|
+
if (error) {
|
|
67
|
+
throw error;
|
|
68
|
+
}
|
|
69
|
+
mkdirSync(dirname(file), { recursive: true });
|
|
70
|
+
writeFileSync(file, JSON.stringify(result.profile));
|
|
71
|
+
} catch (err: unknown) {
|
|
72
|
+
process.stderr.write(
|
|
73
|
+
`[hydranium] Could not write the CPU profile to ${file}: ${err instanceof Error ? err.message : String(err)}\n`
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
session.disconnect();
|
|
77
|
+
});
|
|
78
|
+
};
|
|
79
|
+
process.once('exit', write);
|
|
80
|
+
// Registered until the write is done, not `once`: a `once` listener is gone
|
|
81
|
+
// before it runs, and with no listener left the default action ends the
|
|
82
|
+
// process on a second SIGTERM, which a host ending its process tree sends
|
|
83
|
+
// while the write is still running. Prepended: a `once` listener ahead of
|
|
84
|
+
// this one has removed itself by the time this counts, which would re-raise
|
|
85
|
+
// into its unfinished shutdown.
|
|
86
|
+
const writeOnSigterm = (): void => {
|
|
87
|
+
write();
|
|
88
|
+
process.removeListener('SIGTERM', writeOnSigterm);
|
|
89
|
+
if (process.listenerCount('SIGTERM') === 0) {
|
|
90
|
+
process.kill(process.pid, 'SIGTERM');
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
process.prependListener('SIGTERM', writeOnSigterm);
|
|
94
|
+
}
|