@webstir-io/webstir-frontend 0.1.40 → 0.1.41
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/README.md +124 -60
- package/dist/assets/imageOptimizer.js +10 -15
- package/dist/assets/precompression.js +1 -1
- package/dist/builders/contentBuilder.js +102 -90
- package/dist/builders/cssBuilder.js +25 -19
- package/dist/builders/htmlBuilder.js +57 -42
- package/dist/builders/index.js +1 -1
- package/dist/builders/jsBuilder.js +219 -76
- package/dist/builders/staticAssetsBuilder.js +27 -9
- package/dist/builders/types.d.ts +1 -0
- package/dist/cli.d.ts +1 -1
- package/dist/cli.js +6 -30
- package/dist/config/manifest.js +7 -6
- package/dist/config/paths.js +2 -2
- package/dist/config/schema.d.ts +8 -0
- package/dist/config/schema.js +7 -6
- package/dist/config/setup.js +1 -1
- package/dist/config/workspace.js +11 -9
- package/dist/core/constants.d.ts +1 -1
- package/dist/core/constants.js +5 -5
- package/dist/core/diagnostics.js +1 -1
- package/dist/core/pages.js +4 -4
- package/dist/hooks.js +3 -3
- package/dist/html/criticalCss.js +6 -3
- package/dist/html/htmlSecurity.d.ts +6 -1
- package/dist/html/htmlSecurity.js +28 -14
- package/dist/html/lazyLoad.js +1 -1
- package/dist/html/pageScaffold.js +1 -1
- package/dist/html/resourceHints.js +5 -2
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/inspect.d.ts +2 -0
- package/dist/inspect.js +110 -0
- package/dist/modes/ssg/metadata.js +4 -4
- package/dist/modes/ssg/routing.js +2 -5
- package/dist/modes/ssg/seo.js +5 -5
- package/dist/modes/ssg/views.js +17 -11
- package/dist/operations.js +18 -10
- package/dist/pipeline.d.ts +1 -0
- package/dist/pipeline.js +6 -1
- package/dist/provider.js +28 -24
- package/dist/runtime/boundary.d.ts +28 -0
- package/dist/runtime/boundary.js +247 -0
- package/dist/runtime/index.d.ts +1 -0
- package/dist/runtime/index.js +1 -0
- package/dist/types.d.ts +52 -0
- package/dist/utils/fs.d.ts +11 -10
- package/dist/utils/fs.js +48 -20
- package/dist/utils/glob.d.ts +8 -0
- package/dist/utils/glob.js +21 -0
- package/dist/utils/hash.js +1 -2
- package/dist/utils/pagePaths.js +2 -2
- package/package.json +19 -14
- package/scripts/publish.sh +2 -94
- package/scripts/update-contract.sh +12 -10
- package/src/assets/assetManifest.ts +39 -29
- package/src/assets/imageOptimizer.ts +91 -82
- package/src/assets/precompression.ts +22 -16
- package/src/builders/contentBuilder.ts +1224 -1149
- package/src/builders/cssBuilder.ts +466 -417
- package/src/builders/htmlBuilder.ts +511 -448
- package/src/builders/index.ts +7 -7
- package/src/builders/jsBuilder.ts +538 -280
- package/src/builders/staticAssetsBuilder.ts +166 -135
- package/src/builders/types.ts +7 -6
- package/src/cli.ts +66 -90
- package/src/config/manifest.ts +16 -14
- package/src/config/paths.ts +5 -5
- package/src/config/schema.ts +38 -37
- package/src/config/setup.ts +7 -7
- package/src/config/workspace.ts +118 -116
- package/src/config/workspaceManifest.ts +14 -14
- package/src/core/constants.ts +62 -62
- package/src/core/diagnostics.ts +26 -26
- package/src/core/pages.ts +19 -19
- package/src/hooks.ts +128 -118
- package/src/html/criticalCss.ts +84 -77
- package/src/html/htmlSecurity.ts +107 -66
- package/src/html/lazyLoad.ts +22 -19
- package/src/html/pageScaffold.ts +37 -28
- package/src/html/resourceHints.ts +83 -74
- package/src/index.ts +2 -0
- package/src/inspect.ts +158 -0
- package/src/modes/ssg/metadata.ts +53 -51
- package/src/modes/ssg/routing.ts +177 -177
- package/src/modes/ssg/seo.ts +208 -200
- package/src/modes/ssg/validation.ts +31 -25
- package/src/modes/ssg/views.ts +257 -238
- package/src/operations.ts +105 -95
- package/src/pipeline.ts +81 -69
- package/src/provider.ts +184 -176
- package/src/runtime/boundary.ts +325 -0
- package/src/runtime/index.ts +1 -0
- package/src/types.ts +107 -48
- package/src/utils/changedFile.ts +22 -22
- package/src/utils/fs.ts +73 -26
- package/src/utils/glob.ts +38 -0
- package/src/utils/hash.ts +2 -4
- package/src/utils/pagePaths.ts +35 -23
- package/src/utils/pathMatch.ts +26 -23
- package/tests/add-page-defaults.test.js +44 -39
- package/tests/bundlerParity.test.js +252 -0
- package/tests/cli.contract.test.js +13 -0
- package/tests/content-pages.test.js +108 -13
- package/tests/css-app-imports.test.js +22 -11
- package/tests/css-page-imports.test.js +26 -13
- package/tests/diagnostics.test.js +39 -36
- package/tests/features.test.js +48 -43
- package/tests/hooks.test.js +58 -42
- package/tests/htmlSecurity.test.js +66 -0
- package/tests/inspect.test.js +148 -0
- package/tests/provider.integration.test.js +71 -20
- package/tests/runtime.test.js +493 -0
- package/tests/ssg-defaults.test.js +284 -177
- package/tests/ssg-guardrails.test.js +51 -51
- package/tsconfig.json +3 -10
- package/dist/watch/frontendFiles.d.ts +0 -3
- package/dist/watch/frontendFiles.js +0 -25
- package/dist/watch/hotUpdateTracker.d.ts +0 -51
- package/dist/watch/hotUpdateTracker.js +0 -205
- package/dist/watch/pipelineHelpers.d.ts +0 -26
- package/dist/watch/pipelineHelpers.js +0 -177
- package/dist/watch/types.d.ts +0 -27
- package/dist/watch/types.js +0 -1
- package/dist/watch/watchCoordinator.d.ts +0 -36
- package/dist/watch/watchCoordinator.js +0 -551
- package/dist/watch/watchDaemon.d.ts +0 -17
- package/dist/watch/watchDaemon.js +0 -127
- package/dist/watch/watchReporter.d.ts +0 -21
- package/dist/watch/watchReporter.js +0 -64
- package/scripts/smoke.mjs +0 -35
- package/src/watch/frontendFiles.ts +0 -32
- package/src/watch/hotUpdateTracker.ts +0 -285
- package/src/watch/pipelineHelpers.ts +0 -242
- package/src/watch/types.ts +0 -23
- package/src/watch/watchCoordinator.ts +0 -666
- package/src/watch/watchDaemon.ts +0 -144
- package/src/watch/watchReporter.ts +0 -98
package/src/watch/watchDaemon.ts
DELETED
|
@@ -1,144 +0,0 @@
|
|
|
1
|
-
import process from 'node:process';
|
|
2
|
-
import { createInterface, Interface as ReadLineInterface } from 'node:readline';
|
|
3
|
-
import { emitDiagnostic } from '../core/diagnostics.js';
|
|
4
|
-
import { WatchCoordinator } from './watchCoordinator.js';
|
|
5
|
-
import type { WatchDaemonCommand, WatchDaemonOptions } from './types.js';
|
|
6
|
-
|
|
7
|
-
export class WatchDaemon {
|
|
8
|
-
private readonly coordinator: WatchCoordinator;
|
|
9
|
-
private readonly options: WatchDaemonOptions;
|
|
10
|
-
private readonly shutdownPromise: Promise<void>;
|
|
11
|
-
private resolveShutdown: (() => void) | null = null;
|
|
12
|
-
private commandQueue: Promise<void> = Promise.resolve();
|
|
13
|
-
private isShuttingDown = false;
|
|
14
|
-
private rl?: ReadLineInterface;
|
|
15
|
-
|
|
16
|
-
public constructor(options: WatchDaemonOptions) {
|
|
17
|
-
this.options = options;
|
|
18
|
-
this.coordinator = new WatchCoordinator({
|
|
19
|
-
workspaceRoot: options.workspaceRoot,
|
|
20
|
-
verbose: options.verbose ?? false,
|
|
21
|
-
hmrVerbose: options.hmrVerbose ?? false
|
|
22
|
-
});
|
|
23
|
-
this.shutdownPromise = new Promise((resolve) => {
|
|
24
|
-
this.resolveShutdown = resolve;
|
|
25
|
-
});
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
public async run(): Promise<void> {
|
|
29
|
-
if (this.options.autoStart !== false) {
|
|
30
|
-
await this.coordinator.start();
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
this.setupSignalHandlers();
|
|
34
|
-
this.setupCommandLoop();
|
|
35
|
-
|
|
36
|
-
await this.shutdownPromise;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
private setupCommandLoop(): void {
|
|
40
|
-
if (process.stdin.isTTY) {
|
|
41
|
-
process.stdin.setRawMode(false);
|
|
42
|
-
}
|
|
43
|
-
process.stdin.setEncoding('utf8');
|
|
44
|
-
|
|
45
|
-
this.rl = createInterface({ input: process.stdin, crlfDelay: Infinity });
|
|
46
|
-
this.rl.on('line', (line) => this.processLine(line));
|
|
47
|
-
this.rl.on('close', () => {
|
|
48
|
-
void this.shutdown();
|
|
49
|
-
});
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
private setupSignalHandlers(): void {
|
|
53
|
-
const shutdown = () => {
|
|
54
|
-
void this.shutdown();
|
|
55
|
-
};
|
|
56
|
-
|
|
57
|
-
process.on('SIGINT', shutdown);
|
|
58
|
-
process.on('SIGTERM', shutdown);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
private processLine(rawLine: string): void {
|
|
62
|
-
const line = rawLine.trim();
|
|
63
|
-
if (line.length === 0) {
|
|
64
|
-
return;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
let command: WatchDaemonCommand | null = null;
|
|
68
|
-
try {
|
|
69
|
-
command = JSON.parse(line) as WatchDaemonCommand;
|
|
70
|
-
} catch (error) {
|
|
71
|
-
emitDiagnostic({
|
|
72
|
-
code: 'frontend.watch.command.invalid',
|
|
73
|
-
kind: 'watch-daemon',
|
|
74
|
-
stage: 'command',
|
|
75
|
-
severity: 'warning',
|
|
76
|
-
message: `Discarding invalid command payload: ${String(error)}`
|
|
77
|
-
});
|
|
78
|
-
return;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
this.commandQueue = this.commandQueue.then(() => this.handleCommand(command!)).catch((error) => {
|
|
82
|
-
emitDiagnostic({
|
|
83
|
-
code: 'frontend.watch.command.failure',
|
|
84
|
-
kind: 'watch-daemon',
|
|
85
|
-
stage: 'command',
|
|
86
|
-
severity: 'error',
|
|
87
|
-
message: `Command handling failed: ${error instanceof Error ? error.message : String(error)}`
|
|
88
|
-
});
|
|
89
|
-
});
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
private async handleCommand(command: WatchDaemonCommand): Promise<void> {
|
|
93
|
-
switch (command.type) {
|
|
94
|
-
case 'start':
|
|
95
|
-
await this.coordinator.start();
|
|
96
|
-
return;
|
|
97
|
-
case 'reload':
|
|
98
|
-
await this.coordinator.reload();
|
|
99
|
-
return;
|
|
100
|
-
case 'change':
|
|
101
|
-
await this.coordinator.handleChange({ path: command.path });
|
|
102
|
-
return;
|
|
103
|
-
case 'shutdown':
|
|
104
|
-
await this.shutdown();
|
|
105
|
-
return;
|
|
106
|
-
case 'ping':
|
|
107
|
-
emitDiagnostic({
|
|
108
|
-
code: 'frontend.watch.pong',
|
|
109
|
-
kind: 'watch-daemon',
|
|
110
|
-
stage: 'command',
|
|
111
|
-
severity: 'info',
|
|
112
|
-
message: 'Watch daemon heartbeat acknowledged.',
|
|
113
|
-
data: command.id ? { id: command.id } : undefined
|
|
114
|
-
});
|
|
115
|
-
return;
|
|
116
|
-
default:
|
|
117
|
-
emitDiagnostic({
|
|
118
|
-
code: 'frontend.watch.command.unknown',
|
|
119
|
-
kind: 'watch-daemon',
|
|
120
|
-
stage: 'command',
|
|
121
|
-
severity: 'warning',
|
|
122
|
-
message: `Unknown watch daemon command: ${(command as { type?: unknown }).type}`
|
|
123
|
-
});
|
|
124
|
-
return;
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
private async shutdown(): Promise<void> {
|
|
129
|
-
if (this.isShuttingDown) {
|
|
130
|
-
return;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
this.isShuttingDown = true;
|
|
134
|
-
|
|
135
|
-
if (this.rl) {
|
|
136
|
-
this.rl.close();
|
|
137
|
-
this.rl = undefined;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
await this.coordinator.stop();
|
|
141
|
-
this.resolveShutdown?.();
|
|
142
|
-
this.resolveShutdown = null;
|
|
143
|
-
}
|
|
144
|
-
}
|
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
import type { BuildResult, Message } from 'esbuild';
|
|
2
|
-
import { emitDiagnostic } from '../core/diagnostics.js';
|
|
3
|
-
import type { DiagnosticEvent } from '../core/diagnostics.js';
|
|
4
|
-
|
|
5
|
-
export interface WatchReporterOptions {
|
|
6
|
-
readonly verbose: boolean;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export interface SerializedMessage {
|
|
10
|
-
readonly text: string;
|
|
11
|
-
readonly location?: {
|
|
12
|
-
readonly file?: string;
|
|
13
|
-
readonly line?: number;
|
|
14
|
-
readonly column?: number;
|
|
15
|
-
};
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export class WatchReporter {
|
|
19
|
-
private readonly verbose: boolean;
|
|
20
|
-
|
|
21
|
-
public constructor(options: WatchReporterOptions) {
|
|
22
|
-
this.verbose = options.verbose;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
public emit(event: DiagnosticEvent): void {
|
|
26
|
-
emitDiagnostic(event);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
public emitVerbose(event: DiagnosticEvent): void {
|
|
30
|
-
if (!this.verbose) {
|
|
31
|
-
return;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
emitDiagnostic(event);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
public emitJavaScriptStats(pageName: string, result: BuildResult, durationMs: number): void {
|
|
38
|
-
if (!this.verbose) {
|
|
39
|
-
return;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
const stats = extractMetafileStats(result);
|
|
43
|
-
const data: Record<string, unknown> = {
|
|
44
|
-
page: pageName,
|
|
45
|
-
durationMs: Number(durationMs.toFixed(1))
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
if (stats) {
|
|
49
|
-
data.inputs = stats.inputs;
|
|
50
|
-
data.outputs = stats.outputs;
|
|
51
|
-
data.bytes = stats.bytes;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
emitDiagnostic({
|
|
55
|
-
code: 'frontend.watch.javascript.build.stats',
|
|
56
|
-
kind: 'watch-daemon',
|
|
57
|
-
stage: 'javascript',
|
|
58
|
-
severity: 'info',
|
|
59
|
-
message: `JavaScript rebuild stats for '${pageName}' (${durationMs.toFixed(1)}ms).`,
|
|
60
|
-
data
|
|
61
|
-
});
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
export function serializeMessages(messages: readonly Message[]): SerializedMessage[] {
|
|
66
|
-
return messages.map((message) => ({
|
|
67
|
-
text: message.text,
|
|
68
|
-
location: message.location
|
|
69
|
-
? {
|
|
70
|
-
file: message.location.file,
|
|
71
|
-
line: message.location.line,
|
|
72
|
-
column: message.location.column
|
|
73
|
-
}
|
|
74
|
-
: undefined
|
|
75
|
-
}));
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
function extractMetafileStats(result: BuildResult): MetafileStats | null {
|
|
79
|
-
if (!result.metafile) {
|
|
80
|
-
return null;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
const inputs = Object.keys(result.metafile.inputs ?? {}).length;
|
|
84
|
-
const outputsEntries = Object.entries(result.metafile.outputs ?? {});
|
|
85
|
-
const bytes = outputsEntries.reduce((sum, [, output]) => sum + (output.bytes ?? 0), 0);
|
|
86
|
-
|
|
87
|
-
return {
|
|
88
|
-
inputs,
|
|
89
|
-
outputs: outputsEntries.length,
|
|
90
|
-
bytes
|
|
91
|
-
};
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
interface MetafileStats {
|
|
95
|
-
readonly inputs: number;
|
|
96
|
-
readonly outputs: number;
|
|
97
|
-
readonly bytes: number;
|
|
98
|
-
}
|