@fasl-work/caos-app-shell 0.19.11 → 0.19.12
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/CHANGELOG.md +12 -0
- package/VERSION +1 -1
- package/gate/artifacts.mjs +29 -0
- package/gate/run.mjs +7 -6
- package/package.json +100 -100
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
## [0.19.012] - 2026-11-01
|
|
2
|
+
|
|
3
|
+
### Fixed
|
|
4
|
+
|
|
5
|
+
- Verify complete JSON artifact documents when navigation interrupts a page-owned body read or a conditional response has no body. One bounded GET preserves the observed URL and credentials while removing range/cache preconditions; transport retries are recorded. HTML, empty, malformed and failed responses remain failures.
|
|
6
|
+
- Keep artifact validation independent of page-context lifetime without changing readiness declarations, idle-rate limits, traversal rules or component styles.
|
|
7
|
+
- Permit the gate self-test to use the configured external temporary root; CI uses its runner temporary root.
|
|
8
|
+
|
|
9
|
+
### Adoption
|
|
10
|
+
|
|
11
|
+
- Pin npm 0.19.12 and run the installed gate against the deployed origin. Components and scientific calculations are unchanged.
|
|
12
|
+
|
|
1
13
|
## [0.19.011] - 2026-11-01
|
|
2
14
|
|
|
3
15
|
### Fixed
|
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.19.
|
|
1
|
+
0.19.012
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/** Complete JSON verification, including a bounded retry after a page-owned read is interrupted. */
|
|
2
|
+
export async function readJsonArtifact(response) {
|
|
3
|
+
const url = response.url();
|
|
4
|
+
let text = '', transportRetry = false, originalReadError;
|
|
5
|
+
try {
|
|
6
|
+
// The partial header map omits browser cookies; capture complete on-wire headers before teardown.
|
|
7
|
+
const headers = { ...(await response.request().allHeaders()) };
|
|
8
|
+
try {
|
|
9
|
+
if (response.status() === 304) throw new Error('Conditional response has no complete document body');
|
|
10
|
+
text = await response.text();
|
|
11
|
+
} catch (error) {
|
|
12
|
+
transportRetry = true;
|
|
13
|
+
originalReadError = String(error);
|
|
14
|
+
// Request the full original document, retaining credentials but not cache/range preconditions.
|
|
15
|
+
for (const name of Object.keys(headers)) {
|
|
16
|
+
if (['if-none-match', 'if-modified-since', 'range', 'if-range', 'content-length', 'host', 'connection'].includes(name.toLowerCase())) delete headers[name];
|
|
17
|
+
}
|
|
18
|
+
const retry = await fetch(url, { headers, redirect: 'error', cache: 'no-store', signal: AbortSignal.timeout(10000) });
|
|
19
|
+
if (!retry.ok) throw new Error(`Complete artifact GET answered HTTP ${retry.status}`);
|
|
20
|
+
text = await retry.text();
|
|
21
|
+
}
|
|
22
|
+
const first = text.trimStart().slice(0, 1);
|
|
23
|
+
const value = JSON.parse(text);
|
|
24
|
+
if (value === null || typeof value !== 'object') throw new Error('Artifact must be a JSON object or array');
|
|
25
|
+
return { ok: true, first, transportRetry, ...(originalReadError ? { originalReadError } : {}) };
|
|
26
|
+
} catch (error) {
|
|
27
|
+
return { ok: false, first: text.trimStart().slice(0, 1), transportRetry, error: String(error), ...(originalReadError ? { originalReadError } : {}) };
|
|
28
|
+
}
|
|
29
|
+
}
|
package/gate/run.mjs
CHANGED
|
@@ -38,6 +38,7 @@
|
|
|
38
38
|
// plus the ADR-0071 and ADR-0017 measures (viewport, one-row tabs, rail without scroll, centred prose, captions,
|
|
39
39
|
// references).
|
|
40
40
|
|
|
41
|
+
import { readJsonArtifact } from './artifacts.mjs';
|
|
41
42
|
import { existsSync, mkdirSync, readdirSync, rmSync, writeFileSync } from 'node:fs';
|
|
42
43
|
import { join } from 'node:path';
|
|
43
44
|
import { decodePng, paintedBox, unionArea } from './png.mjs';
|
|
@@ -135,6 +136,7 @@ export async function runGate(o) {
|
|
|
135
136
|
let states = 0;
|
|
136
137
|
const fail = (check, where, message) => failures.push({ check, route: where.route ?? '', mode: where.mode ?? '', trail: where.trail ?? '', message });
|
|
137
138
|
const artifacts = new Map();
|
|
139
|
+
const artifactChecks = [];
|
|
138
140
|
|
|
139
141
|
const browser = await chromium.launch();
|
|
140
142
|
const openContext = async ([w, h], theme, lang, wide = false) => {
|
|
@@ -193,10 +195,7 @@ export async function runGate(o) {
|
|
|
193
195
|
if ((type === 'fetch' || type === 'xhr') && pathname.endsWith('.json') && r.status() < 400 && !artifacts.has(pathname)) {
|
|
194
196
|
artifacts.set(
|
|
195
197
|
pathname,
|
|
196
|
-
r
|
|
197
|
-
(t) => t.trimStart().slice(0, 1),
|
|
198
|
-
() => '',
|
|
199
|
-
),
|
|
198
|
+
readJsonArtifact(r),
|
|
200
199
|
);
|
|
201
200
|
}
|
|
202
201
|
});
|
|
@@ -444,8 +443,9 @@ export async function runGate(o) {
|
|
|
444
443
|
|
|
445
444
|
// ---- G4: artifacts answered as JSON.
|
|
446
445
|
for (const [pathname, first] of artifacts) {
|
|
447
|
-
const
|
|
448
|
-
|
|
446
|
+
const result = await first;
|
|
447
|
+
artifactChecks.push({ path: pathname, ...result });
|
|
448
|
+
if (!result.ok) fail('G4', { route: pathname }, `the artifact ${pathname} did not answer JSON (starts with "${result.first}"; ${result.error ?? 'the HTML fallback?'})`);
|
|
449
449
|
}
|
|
450
450
|
} finally {
|
|
451
451
|
await browser.close();
|
|
@@ -1131,6 +1131,7 @@ export async function runGate(o) {
|
|
|
1131
1131
|
checks,
|
|
1132
1132
|
captures: captures.length,
|
|
1133
1133
|
failures,
|
|
1134
|
+
artifactChecks,
|
|
1134
1135
|
};
|
|
1135
1136
|
writeFileSync(join(opt.out, 'gate-report.json'), JSON.stringify(report, null, 2));
|
|
1136
1137
|
// G14: the captures are for a person to read (the gate measures, it does not judge content); one page shows them.
|
package/package.json
CHANGED
|
@@ -1,100 +1,100 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@fasl-work/caos-app-shell",
|
|
3
|
-
"version": "0.19.
|
|
4
|
-
"description": "Shared web-app shell, workbench primitives, content primitives, design system and measured gate for the CAOS / Faena public apps (ADR-0016, ADR-0017, ADR-0071).",
|
|
5
|
-
"license": "MIT",
|
|
6
|
-
"author": "Felipe Santibáñez-Leal",
|
|
7
|
-
"repository": {
|
|
8
|
-
"type": "git",
|
|
9
|
-
"url": "git+https://github.com/fsantibanezleal/CAOS_APP_SHELL.git"
|
|
10
|
-
},
|
|
11
|
-
"type": "module",
|
|
12
|
-
"publishConfig": {
|
|
13
|
-
"access": "public"
|
|
14
|
-
},
|
|
15
|
-
"sideEffects": [
|
|
16
|
-
"*.css"
|
|
17
|
-
],
|
|
18
|
-
"exports": {
|
|
19
|
-
".": {
|
|
20
|
-
"types": "./dist/index.d.ts",
|
|
21
|
-
"import": "./dist/index.js"
|
|
22
|
-
},
|
|
23
|
-
"./chart": {
|
|
24
|
-
"types": "./dist/chart.d.ts",
|
|
25
|
-
"import": "./dist/chart.js"
|
|
26
|
-
},
|
|
27
|
-
"./keys": {
|
|
28
|
-
"types": "./dist/keys.d.ts",
|
|
29
|
-
"import": "./dist/keys.js"
|
|
30
|
-
},
|
|
31
|
-
"./styles.css": "./styles.css",
|
|
32
|
-
"./chart.css": "./chart.css",
|
|
33
|
-
"./reserved-classes.json": "./reserved-classes.json",
|
|
34
|
-
"./executive.schema.json": "./src/content/executive.schema.json",
|
|
35
|
-
"./serve": "./gate/serve.mjs",
|
|
36
|
-
"./gate": "./gate/run.mjs",
|
|
37
|
-
"./package.json": "./package.json"
|
|
38
|
-
},
|
|
39
|
-
"files": [
|
|
40
|
-
"dist",
|
|
41
|
-
"styles.css",
|
|
42
|
-
"chart.css",
|
|
43
|
-
"bin",
|
|
44
|
-
"gate",
|
|
45
|
-
"reserved-classes.json",
|
|
46
|
-
"src/content/executive.schema.json",
|
|
47
|
-
"VERSION",
|
|
48
|
-
"CHANGELOG.md"
|
|
49
|
-
],
|
|
50
|
-
"scripts": {
|
|
51
|
-
"build": "tsup",
|
|
52
|
-
"test": "node --import tsx --test \"test/**/*.test.ts\" \"test/**/*.test.tsx\"",
|
|
53
|
-
"test:browser": "node --import tsx --test \"e2e/**/*.test.ts\"",
|
|
54
|
-
"prepare": "npm run build",
|
|
55
|
-
"prepublishOnly": "npm run build",
|
|
56
|
-
"prebuild": "node scripts/reserved-classes.mjs",
|
|
57
|
-
"test:gate": "node --test test/gate-selftest.mjs",
|
|
58
|
-
"check:sdd": "python scripts/check_sdd.py ."
|
|
59
|
-
},
|
|
60
|
-
"peerDependencies": {
|
|
61
|
-
"katex": "^0.16.0 || ^0.17.0 || ^0.18.0 || ^0.19.0",
|
|
62
|
-
"lucide-react": ">=0.400.0",
|
|
63
|
-
"react": "^18 || ^19",
|
|
64
|
-
"react-dom": "^18 || ^19",
|
|
65
|
-
"react-router": "^6 || ^7 || ^8",
|
|
66
|
-
"zustand": "^4 || ^5",
|
|
67
|
-
"playwright": ">=1.40",
|
|
68
|
-
"uplot": "^1.6.30"
|
|
69
|
-
},
|
|
70
|
-
"devDependencies": {
|
|
71
|
-
"@playwright/test": "1.63.0",
|
|
72
|
-
"@types/react": "^19.0.0",
|
|
73
|
-
"@types/react-dom": "^19.0.0",
|
|
74
|
-
"esbuild": "0.28.1",
|
|
75
|
-
"katex": "0.19.0",
|
|
76
|
-
"lucide-react": "1.43.0",
|
|
77
|
-
"react": "^19.0.0",
|
|
78
|
-
"react-dom": "^19.0.0",
|
|
79
|
-
"react-router": "^8.3.0",
|
|
80
|
-
"tsup": "^8.3.5",
|
|
81
|
-
"tsx": "^4.23.0",
|
|
82
|
-
"typescript": "^5.7.3",
|
|
83
|
-
"zustand": "^5.0.2",
|
|
84
|
-
"uplot": "1.6.32"
|
|
85
|
-
},
|
|
86
|
-
"overrides": {
|
|
87
|
-
"esbuild": "0.28.1"
|
|
88
|
-
},
|
|
89
|
-
"bin": {
|
|
90
|
-
"caos-shell-gate": "bin/caos-shell-gate.mjs"
|
|
91
|
-
},
|
|
92
|
-
"peerDependenciesMeta": {
|
|
93
|
-
"playwright": {
|
|
94
|
-
"optional": true
|
|
95
|
-
},
|
|
96
|
-
"uplot": {
|
|
97
|
-
"optional": true
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@fasl-work/caos-app-shell",
|
|
3
|
+
"version": "0.19.12",
|
|
4
|
+
"description": "Shared web-app shell, workbench primitives, content primitives, design system and measured gate for the CAOS / Faena public apps (ADR-0016, ADR-0017, ADR-0071).",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"author": "Felipe Santibáñez-Leal",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/fsantibanezleal/CAOS_APP_SHELL.git"
|
|
10
|
+
},
|
|
11
|
+
"type": "module",
|
|
12
|
+
"publishConfig": {
|
|
13
|
+
"access": "public"
|
|
14
|
+
},
|
|
15
|
+
"sideEffects": [
|
|
16
|
+
"*.css"
|
|
17
|
+
],
|
|
18
|
+
"exports": {
|
|
19
|
+
".": {
|
|
20
|
+
"types": "./dist/index.d.ts",
|
|
21
|
+
"import": "./dist/index.js"
|
|
22
|
+
},
|
|
23
|
+
"./chart": {
|
|
24
|
+
"types": "./dist/chart.d.ts",
|
|
25
|
+
"import": "./dist/chart.js"
|
|
26
|
+
},
|
|
27
|
+
"./keys": {
|
|
28
|
+
"types": "./dist/keys.d.ts",
|
|
29
|
+
"import": "./dist/keys.js"
|
|
30
|
+
},
|
|
31
|
+
"./styles.css": "./styles.css",
|
|
32
|
+
"./chart.css": "./chart.css",
|
|
33
|
+
"./reserved-classes.json": "./reserved-classes.json",
|
|
34
|
+
"./executive.schema.json": "./src/content/executive.schema.json",
|
|
35
|
+
"./serve": "./gate/serve.mjs",
|
|
36
|
+
"./gate": "./gate/run.mjs",
|
|
37
|
+
"./package.json": "./package.json"
|
|
38
|
+
},
|
|
39
|
+
"files": [
|
|
40
|
+
"dist",
|
|
41
|
+
"styles.css",
|
|
42
|
+
"chart.css",
|
|
43
|
+
"bin",
|
|
44
|
+
"gate",
|
|
45
|
+
"reserved-classes.json",
|
|
46
|
+
"src/content/executive.schema.json",
|
|
47
|
+
"VERSION",
|
|
48
|
+
"CHANGELOG.md"
|
|
49
|
+
],
|
|
50
|
+
"scripts": {
|
|
51
|
+
"build": "tsup",
|
|
52
|
+
"test": "node --import tsx --test \"test/**/*.test.ts\" \"test/**/*.test.tsx\"",
|
|
53
|
+
"test:browser": "node --import tsx --test \"e2e/**/*.test.ts\"",
|
|
54
|
+
"prepare": "npm run build",
|
|
55
|
+
"prepublishOnly": "npm run build",
|
|
56
|
+
"prebuild": "node scripts/reserved-classes.mjs",
|
|
57
|
+
"test:gate": "node --test test/gate-selftest.mjs",
|
|
58
|
+
"check:sdd": "python scripts/check_sdd.py ."
|
|
59
|
+
},
|
|
60
|
+
"peerDependencies": {
|
|
61
|
+
"katex": "^0.16.0 || ^0.17.0 || ^0.18.0 || ^0.19.0",
|
|
62
|
+
"lucide-react": ">=0.400.0",
|
|
63
|
+
"react": "^18 || ^19",
|
|
64
|
+
"react-dom": "^18 || ^19",
|
|
65
|
+
"react-router": "^6 || ^7 || ^8",
|
|
66
|
+
"zustand": "^4 || ^5",
|
|
67
|
+
"playwright": ">=1.40",
|
|
68
|
+
"uplot": "^1.6.30"
|
|
69
|
+
},
|
|
70
|
+
"devDependencies": {
|
|
71
|
+
"@playwright/test": "1.63.0",
|
|
72
|
+
"@types/react": "^19.0.0",
|
|
73
|
+
"@types/react-dom": "^19.0.0",
|
|
74
|
+
"esbuild": "0.28.1",
|
|
75
|
+
"katex": "0.19.0",
|
|
76
|
+
"lucide-react": "1.43.0",
|
|
77
|
+
"react": "^19.0.0",
|
|
78
|
+
"react-dom": "^19.0.0",
|
|
79
|
+
"react-router": "^8.3.0",
|
|
80
|
+
"tsup": "^8.3.5",
|
|
81
|
+
"tsx": "^4.23.0",
|
|
82
|
+
"typescript": "^5.7.3",
|
|
83
|
+
"zustand": "^5.0.2",
|
|
84
|
+
"uplot": "1.6.32"
|
|
85
|
+
},
|
|
86
|
+
"overrides": {
|
|
87
|
+
"esbuild": "0.28.1"
|
|
88
|
+
},
|
|
89
|
+
"bin": {
|
|
90
|
+
"caos-shell-gate": "bin/caos-shell-gate.mjs"
|
|
91
|
+
},
|
|
92
|
+
"peerDependenciesMeta": {
|
|
93
|
+
"playwright": {
|
|
94
|
+
"optional": true
|
|
95
|
+
},
|
|
96
|
+
"uplot": {
|
|
97
|
+
"optional": true
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|