@stacknext/regression 0.0.0-stage → 0.6.0

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.
@@ -0,0 +1,305 @@
1
+ import { access, chmod, link, mkdir, readFile, readdir, rename, rm, stat, unlink, writeFile, } from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ import { baselineSchema, comparisonSchema, testRunSchema, } from './schema.js';
4
+ import { baselineSummary, comparisonSummaryItem, runSummary, } from './stats.js';
5
+ export const REGRESSION_DIR_NAME = '.stacknext';
6
+ export const RUNS_DIR_NAME = 'runs';
7
+ export const BASELINES_DIR_NAME = 'baselines';
8
+ export const COMPARISONS_DIR_NAME = 'comparisons';
9
+ const MAX_RECORD_BYTES = 16 * 1024 * 1024;
10
+ export class RegressionStorageError extends Error {
11
+ code;
12
+ constructor(code, message) {
13
+ super(message);
14
+ this.name = 'RegressionStorageError';
15
+ this.code = code;
16
+ }
17
+ }
18
+ export function regressionDir(projectDir) {
19
+ return path.join(projectDir, REGRESSION_DIR_NAME);
20
+ }
21
+ export function runsDir(projectDir) {
22
+ return path.join(regressionDir(projectDir), RUNS_DIR_NAME);
23
+ }
24
+ export function baselinesDir(projectDir) {
25
+ return path.join(regressionDir(projectDir), BASELINES_DIR_NAME);
26
+ }
27
+ export function comparisonsDir(projectDir) {
28
+ return path.join(regressionDir(projectDir), COMPARISONS_DIR_NAME);
29
+ }
30
+ export function runPath(projectDir, id) {
31
+ return path.join(runsDir(projectDir), `${id}.json`);
32
+ }
33
+ export function baselinePath(projectDir, id) {
34
+ return path.join(baselinesDir(projectDir), `${id}.json`);
35
+ }
36
+ export function comparisonPath(projectDir, id) {
37
+ return path.join(comparisonsDir(projectDir), `${id}.json`);
38
+ }
39
+ export async function ensureRegressionDirs(projectDir) {
40
+ const root = regressionDir(projectDir);
41
+ await mkdir(root, { recursive: true, mode: 0o700 });
42
+ await chmod(root, 0o700).catch(() => undefined);
43
+ const gitignore = path.join(root, '.gitignore');
44
+ try {
45
+ await writeFile(gitignore, '*\n', { mode: 0o600, flag: 'wx' });
46
+ }
47
+ catch (error) {
48
+ if (error.code !== 'EEXIST')
49
+ throw error;
50
+ }
51
+ for (const dir of [runsDir(projectDir), baselinesDir(projectDir), comparisonsDir(projectDir)]) {
52
+ await mkdir(dir, { recursive: true, mode: 0o700 });
53
+ await chmod(dir, 0o700).catch(() => undefined);
54
+ }
55
+ }
56
+ async function exists(file) {
57
+ try {
58
+ await access(file);
59
+ return true;
60
+ }
61
+ catch {
62
+ return false;
63
+ }
64
+ }
65
+ async function writeJson(file, payload, overwrite) {
66
+ const body = `${JSON.stringify(payload, null, 2)}\n`;
67
+ if (Buffer.byteLength(body, 'utf8') > MAX_RECORD_BYTES) {
68
+ throw new RegressionStorageError('too-large', `${file} exceeds the ${MAX_RECORD_BYTES} byte regression record limit and was not written.`);
69
+ }
70
+ await mkdir(path.dirname(file), { recursive: true, mode: 0o700 });
71
+ await chmod(path.dirname(file), 0o700).catch(() => undefined);
72
+ if (!overwrite && (await exists(file))) {
73
+ throw new RegressionStorageError('exists', `${file} already exists. Use an explicit overwrite flag after confirming you want to replace it.`);
74
+ }
75
+ const temporary = `${file}.${process.pid}.${Date.now()}.tmp`;
76
+ try {
77
+ await writeFile(temporary, body, { mode: 0o600, flag: 'wx' });
78
+ await chmod(temporary, 0o600).catch(() => undefined);
79
+ if (overwrite) {
80
+ await rename(temporary, file);
81
+ return;
82
+ }
83
+ try {
84
+ await link(temporary, file);
85
+ }
86
+ catch (error) {
87
+ const code = error.code;
88
+ if (code === 'EEXIST') {
89
+ throw new RegressionStorageError('exists', `${file} already exists. Use an explicit overwrite flag after confirming you want to replace it.`);
90
+ }
91
+ if (code === 'EPERM' || code === 'ENOSYS' || code === 'EOPNOTSUPP') {
92
+ if (await exists(file)) {
93
+ throw new RegressionStorageError('exists', `${file} already exists. Use an explicit overwrite flag after confirming you want to replace it.`);
94
+ }
95
+ await rename(temporary, file);
96
+ return;
97
+ }
98
+ throw error;
99
+ }
100
+ finally {
101
+ await unlink(temporary).catch(() => undefined);
102
+ }
103
+ }
104
+ catch (error) {
105
+ await rm(temporary, { force: true }).catch(() => undefined);
106
+ throw error;
107
+ }
108
+ }
109
+ async function readJson(file, schema) {
110
+ let info;
111
+ try {
112
+ info = await stat(file);
113
+ }
114
+ catch (error) {
115
+ if (error.code === 'ENOENT') {
116
+ throw new RegressionStorageError('not-found', `${file} does not exist.`);
117
+ }
118
+ throw error;
119
+ }
120
+ if (info.size > MAX_RECORD_BYTES) {
121
+ throw new RegressionStorageError('too-large', `${file} is larger than the ${MAX_RECORD_BYTES} byte regression record limit.`);
122
+ }
123
+ const contents = await readFile(file, 'utf8');
124
+ let parsed;
125
+ try {
126
+ parsed = JSON.parse(contents);
127
+ }
128
+ catch {
129
+ throw new RegressionStorageError('invalid', `${file} is not valid JSON.`);
130
+ }
131
+ const result = schema.safeParse(parsed);
132
+ if (!result.success) {
133
+ throw new RegressionStorageError('invalid', `${file} failed validation: ${result.error.issues
134
+ .map((issue) => `${issue.path.join('.') || '(root)'}: ${issue.message}`)
135
+ .join('; ')}`);
136
+ }
137
+ return result.data;
138
+ }
139
+ function idsFrom(names, prefix) {
140
+ const pattern = new RegExp(`^${prefix}-[0-9a-f]{16}\\.json$`);
141
+ return names
142
+ .filter((name) => pattern.test(name))
143
+ .map((name) => name.slice(0, -'.json'.length))
144
+ .sort();
145
+ }
146
+ function page(items, options, invalid = 0) {
147
+ const limit = Math.min(Math.max(options.limit ?? 50, 1), 200);
148
+ const offset = Math.max(options.offset ?? 0, 0);
149
+ return {
150
+ items: items.slice(offset, offset + limit),
151
+ total: items.length,
152
+ limit,
153
+ offset,
154
+ invalid,
155
+ };
156
+ }
157
+ function invalidRecord(error) {
158
+ return error instanceof RegressionStorageError && error.code !== 'not-found';
159
+ }
160
+ async function readRunSummaries(projectDir) {
161
+ let names;
162
+ try {
163
+ names = await readdir(runsDir(projectDir));
164
+ }
165
+ catch (error) {
166
+ if (error.code === 'ENOENT') {
167
+ return { items: [], invalid: 0 };
168
+ }
169
+ throw error;
170
+ }
171
+ const items = [];
172
+ let invalid = 0;
173
+ for (const id of idsFrom(names, 'run')) {
174
+ try {
175
+ items.push(runSummary(await loadRun(projectDir, id)));
176
+ }
177
+ catch (error) {
178
+ if (error instanceof RegressionStorageError) {
179
+ if (invalidRecord(error))
180
+ invalid += 1;
181
+ continue;
182
+ }
183
+ throw error;
184
+ }
185
+ }
186
+ items.sort((a, b) => b.createdAt - a.createdAt || (a.id < b.id ? -1 : 1));
187
+ return { items, invalid };
188
+ }
189
+ export async function saveRun(projectDir, run, options = {}) {
190
+ await ensureRegressionDirs(projectDir);
191
+ testRunSchema.parse(run);
192
+ const file = runPath(projectDir, run.id);
193
+ await writeJson(file, run, options.overwrite ?? false);
194
+ return file;
195
+ }
196
+ export async function loadRun(projectDir, id) {
197
+ return readJson(runPath(projectDir, id), testRunSchema);
198
+ }
199
+ export async function listAllRuns(projectDir) {
200
+ return readRunSummaries(projectDir);
201
+ }
202
+ export async function listRuns(projectDir, options = {}) {
203
+ const records = await readRunSummaries(projectDir);
204
+ return page(records.items, options, records.invalid);
205
+ }
206
+ export async function saveBaseline(projectDir, baseline, options = {}) {
207
+ await ensureRegressionDirs(projectDir);
208
+ baselineSchema.parse(baseline);
209
+ const file = baselinePath(projectDir, baseline.id);
210
+ await writeJson(file, baseline, options.overwrite ?? false);
211
+ return file;
212
+ }
213
+ export async function loadBaseline(projectDir, id) {
214
+ return readJson(baselinePath(projectDir, id), baselineSchema);
215
+ }
216
+ async function readBaselineSummaries(projectDir) {
217
+ let names;
218
+ try {
219
+ names = await readdir(baselinesDir(projectDir));
220
+ }
221
+ catch (error) {
222
+ if (error.code === 'ENOENT') {
223
+ return { items: [], invalid: 0 };
224
+ }
225
+ throw error;
226
+ }
227
+ const items = [];
228
+ let invalid = 0;
229
+ for (const id of idsFrom(names, 'base')) {
230
+ try {
231
+ items.push(baselineSummary(await loadBaseline(projectDir, id)));
232
+ }
233
+ catch (error) {
234
+ if (error instanceof RegressionStorageError) {
235
+ if (invalidRecord(error))
236
+ invalid += 1;
237
+ continue;
238
+ }
239
+ throw error;
240
+ }
241
+ }
242
+ items.sort((a, b) => b.createdAt - a.createdAt || (a.id < b.id ? -1 : 1));
243
+ return { items, invalid };
244
+ }
245
+ export async function listAllBaselines(projectDir) {
246
+ return readBaselineSummaries(projectDir);
247
+ }
248
+ export async function listBaselines(projectDir, options = {}) {
249
+ const records = await readBaselineSummaries(projectDir);
250
+ return page(records.items, options, records.invalid);
251
+ }
252
+ export async function removeBaseline(projectDir, id) {
253
+ const file = baselinePath(projectDir, id);
254
+ if (!(await exists(file)))
255
+ return false;
256
+ await rm(file);
257
+ return true;
258
+ }
259
+ export async function saveComparison(projectDir, comparison, options = {}) {
260
+ await ensureRegressionDirs(projectDir);
261
+ comparisonSchema.parse(comparison);
262
+ const file = comparisonPath(projectDir, comparison.id);
263
+ await writeJson(file, comparison, options.overwrite ?? false);
264
+ return file;
265
+ }
266
+ export async function loadComparison(projectDir, id) {
267
+ return readJson(comparisonPath(projectDir, id), comparisonSchema);
268
+ }
269
+ async function readComparisonSummaries(projectDir) {
270
+ let names;
271
+ try {
272
+ names = await readdir(comparisonsDir(projectDir));
273
+ }
274
+ catch (error) {
275
+ if (error.code === 'ENOENT') {
276
+ return { items: [], invalid: 0 };
277
+ }
278
+ throw error;
279
+ }
280
+ const items = [];
281
+ let invalid = 0;
282
+ for (const id of idsFrom(names, 'cmp')) {
283
+ try {
284
+ items.push(comparisonSummaryItem(await loadComparison(projectDir, id)));
285
+ }
286
+ catch (error) {
287
+ if (error instanceof RegressionStorageError) {
288
+ if (invalidRecord(error))
289
+ invalid += 1;
290
+ continue;
291
+ }
292
+ throw error;
293
+ }
294
+ }
295
+ items.sort((a, b) => b.createdAt - a.createdAt || (a.id < b.id ? -1 : 1));
296
+ return { items, invalid };
297
+ }
298
+ export async function listAllComparisons(projectDir) {
299
+ return readComparisonSummaries(projectDir);
300
+ }
301
+ export async function listComparisons(projectDir, options = {}) {
302
+ const records = await readComparisonSummaries(projectDir);
303
+ return page(records.items, options, records.invalid);
304
+ }
305
+ //# sourceMappingURL=storage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage.js","sourceRoot":"","sources":["../src/storage.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,53 @@
1
1
  {
2
2
  "name": "@stacknext/regression",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
3
+ "version": "0.6.0",
4
+ "description": "Deterministic Playwright-linked runtime regression capture for StackNext",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "files": [
8
+ "dist"
9
+ ],
10
+ "main": "./dist/index.js",
11
+ "types": "./dist/index.d.ts",
12
+ "exports": {
13
+ ".": {
14
+ "types": "./dist/index.d.ts",
15
+ "import": "./dist/index.js",
16
+ "default": "./dist/index.js"
17
+ },
18
+ "./package.json": "./package.json"
19
+ },
20
+ "dependencies": {
21
+ "@stacknext/core": "0.6.0",
22
+ "@stacknext/diagnostics": "0.6.0",
23
+ "zod": "4.6.7"
24
+ },
25
+ "engines": {
26
+ "node": ">=20.9.0"
27
+ },
28
+ "author": "StackNext contributors",
29
+ "homepage": "https://github.com/marrrkkk/stacknext#readme",
30
+ "repository": {
31
+ "type": "git",
32
+ "url": "git+https://github.com/marrrkkk/stacknext.git",
33
+ "directory": "packages/regression"
34
+ },
35
+ "bugs": {
36
+ "url": "https://github.com/marrrkkk/stacknext/issues"
37
+ },
38
+ "keywords": [
39
+ "stacknext",
40
+ "nextjs",
41
+ "playwright",
42
+ "regression-testing",
43
+ "baseline",
44
+ "performance"
45
+ ],
46
+ "publishConfig": {
47
+ "access": "public"
48
+ },
49
+ "scripts": {
50
+ "build": "tsc -p tsconfig.build.json",
51
+ "typecheck": "tsc -p tsconfig.json --noEmit"
52
+ }
6
53
  }