@webstir-io/webstir 0.1.1 → 0.1.2
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 +13 -0
- package/assets/deployment/docker/.dockerignore +7 -0
- package/assets/deployment/docker/Dockerfile +17 -0
- package/assets/deployment/docker/README.md +44 -0
- package/assets/deployment/docker/example.env +3 -0
- package/assets/features/client_nav/client_nav.ts +369 -264
- package/assets/features/client_nav/document_navigation.ts +344 -0
- package/assets/features/client_nav/form_enhancement.ts +275 -0
- package/assets/templates/api/src/backend/index.ts +71 -10
- package/assets/templates/api/src/backend/tsconfig.json +6 -1
- package/assets/templates/full/src/backend/index.ts +71 -10
- package/assets/templates/full/src/backend/module.ts +515 -0
- package/assets/templates/full/src/backend/tests/progressive-enhancement.test.ts +180 -0
- package/assets/templates/full/src/backend/tsconfig.json +6 -1
- package/assets/templates/full/src/frontend/app/scripts/features/client-nav.ts +574 -0
- package/assets/templates/full/src/frontend/app/scripts/features/document-navigation.ts +344 -0
- package/assets/templates/full/src/frontend/app/scripts/features/form-enhancement.ts +275 -0
- package/assets/templates/full/src/frontend/pages/home/index.css +8 -0
- package/assets/templates/full/src/frontend/pages/home/index.html +6 -1
- package/assets/templates/full/src/frontend/pages/home/tests/home.test.ts +12 -2
- package/assets/templates/spa/src/frontend/pages/home/tests/home.test.ts +10 -2
- package/package.json +31 -13
- package/scripts/check-feature-projections.mjs +87 -0
- package/scripts/check-full-demo-sync.mjs +89 -0
- package/scripts/check-package-install.mjs +537 -0
- package/scripts/check-standalone-install.mjs +221 -0
- package/scripts/pack-standalone.mjs +52 -28
- package/scripts/publish.sh +9 -0
- package/scripts/run-tests.mjs +99 -0
- package/scripts/sync-assets.mjs +175 -17
- package/src/add-backend-compat.ts +628 -0
- package/src/add-backend.ts +155 -27
- package/src/add.ts +111 -4
- package/src/agent.ts +393 -0
- package/src/api-watch.ts +7 -4
- package/src/backend-inspect.ts +70 -2
- package/src/backend-runtime.ts +22 -14
- package/src/build.ts +1 -3
- package/src/bun-generated-frontend-watch.ts +209 -0
- package/src/bun-globals.d.ts +23 -0
- package/src/bun-spa-document.ts +310 -0
- package/src/bun-spa-routes.ts +159 -0
- package/src/bun-spa-watch.ts +29 -0
- package/src/bun-ssg-watch.ts +304 -0
- package/src/cli.ts +381 -50
- package/src/compile-tests.ts +37 -29
- package/src/dev-server.ts +214 -143
- package/src/doctor.ts +164 -0
- package/src/enable-assets.ts +18 -1
- package/src/enable.ts +133 -41
- package/src/execute.ts +28 -4
- package/src/external-workspace.ts +178 -0
- package/src/format.ts +296 -17
- package/src/frontend-inspect.ts +32 -0
- package/src/frontend-watch.ts +27 -102
- package/src/full-watch.ts +13 -18
- package/src/index.ts +7 -0
- package/src/init-assets.ts +41 -11
- package/src/init.ts +85 -71
- package/src/inspect.ts +112 -0
- package/src/mcp/run-cli-json.ts +46 -0
- package/src/mcp/server.ts +307 -0
- package/src/operations.ts +176 -0
- package/src/providers.ts +20 -18
- package/src/refresh.ts +29 -3
- package/src/repair.ts +110 -43
- package/src/runtime-filter.ts +41 -0
- package/src/runtime.ts +1 -1
- package/src/smoke.ts +48 -16
- package/src/test.ts +54 -16
- package/src/testing-runtime.ts +273 -0
- package/src/types.ts +1 -4
- package/src/watch-events.ts +46 -17
- package/src/watch.ts +5 -1
- package/src/workspace-watcher.ts +10 -6
- package/src/workspace.ts +4 -2
- package/src/watch-daemon-client.ts +0 -171
|
@@ -1,171 +0,0 @@
|
|
|
1
|
-
import path from 'node:path';
|
|
2
|
-
import { spawn, type ChildProcessWithoutNullStreams } from 'node:child_process';
|
|
3
|
-
import { createInterface, type Interface as ReadLineInterface } from 'node:readline';
|
|
4
|
-
import { fileURLToPath } from 'node:url';
|
|
5
|
-
|
|
6
|
-
import { createWorkspaceRuntimeEnv, resolveRuntimeCommand } from './runtime.ts';
|
|
7
|
-
import { parseStructuredDiagnosticLine, type StructuredDiagnosticPayload } from './watch-events.ts';
|
|
8
|
-
import { ensureLocalPackageArtifacts } from './providers.ts';
|
|
9
|
-
|
|
10
|
-
type WatchDaemonCommand =
|
|
11
|
-
| { readonly type: 'start' }
|
|
12
|
-
| { readonly type: 'change'; readonly path: string }
|
|
13
|
-
| { readonly type: 'reload' }
|
|
14
|
-
| { readonly type: 'shutdown' };
|
|
15
|
-
|
|
16
|
-
export interface FrontendWatchDaemonClientOptions {
|
|
17
|
-
readonly workspaceRoot: string;
|
|
18
|
-
readonly verbose?: boolean;
|
|
19
|
-
readonly hmrVerbose?: boolean;
|
|
20
|
-
readonly env?: Record<string, string | undefined>;
|
|
21
|
-
readonly onLine?: (line: string) => void;
|
|
22
|
-
readonly onErrorLine?: (line: string) => void;
|
|
23
|
-
readonly onDiagnostic?: (payload: StructuredDiagnosticPayload) => void;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export class FrontendWatchDaemonClient {
|
|
27
|
-
private readonly workspaceRoot: string;
|
|
28
|
-
private readonly verbose: boolean;
|
|
29
|
-
private readonly hmrVerbose: boolean;
|
|
30
|
-
private readonly env?: Record<string, string | undefined>;
|
|
31
|
-
private readonly onLine?: (line: string) => void;
|
|
32
|
-
private readonly onErrorLine?: (line: string) => void;
|
|
33
|
-
private readonly onDiagnostic?: (payload: StructuredDiagnosticPayload) => void;
|
|
34
|
-
private child?: ChildProcessWithoutNullStreams;
|
|
35
|
-
private stdoutReader?: ReadLineInterface;
|
|
36
|
-
private stderrReader?: ReadLineInterface;
|
|
37
|
-
private exitPromise?: Promise<number | null>;
|
|
38
|
-
private isStopping = false;
|
|
39
|
-
|
|
40
|
-
public constructor(options: FrontendWatchDaemonClientOptions) {
|
|
41
|
-
this.workspaceRoot = path.resolve(options.workspaceRoot);
|
|
42
|
-
this.verbose = options.verbose ?? false;
|
|
43
|
-
this.hmrVerbose = options.hmrVerbose ?? false;
|
|
44
|
-
this.env = options.env;
|
|
45
|
-
this.onLine = options.onLine;
|
|
46
|
-
this.onErrorLine = options.onErrorLine;
|
|
47
|
-
this.onDiagnostic = options.onDiagnostic;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
public async start(): Promise<void> {
|
|
51
|
-
if (this.child) {
|
|
52
|
-
return;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
await ensureLocalPackageArtifacts();
|
|
56
|
-
const frontendCliPath = fileURLToPath(import.meta.resolve('@webstir-io/webstir-frontend/cli'));
|
|
57
|
-
const args = [
|
|
58
|
-
frontendCliPath,
|
|
59
|
-
'watch-daemon',
|
|
60
|
-
'--workspace',
|
|
61
|
-
this.workspaceRoot,
|
|
62
|
-
'--no-auto-start',
|
|
63
|
-
];
|
|
64
|
-
|
|
65
|
-
if (this.verbose) {
|
|
66
|
-
args.push('--verbose');
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
if (this.hmrVerbose) {
|
|
70
|
-
args.push('--hmr-verbose');
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
const child = spawn(resolveRuntimeCommand(), args, {
|
|
74
|
-
cwd: this.workspaceRoot,
|
|
75
|
-
env: createWorkspaceRuntimeEnv(this.workspaceRoot, 'build', this.env),
|
|
76
|
-
stdio: 'pipe',
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
this.child = child;
|
|
80
|
-
this.exitPromise = new Promise<number | null>((resolve, reject) => {
|
|
81
|
-
child.once('error', reject);
|
|
82
|
-
child.once('close', (code) => resolve(code));
|
|
83
|
-
});
|
|
84
|
-
|
|
85
|
-
this.stdoutReader = createInterface({ input: child.stdout, crlfDelay: Infinity });
|
|
86
|
-
this.stdoutReader.on('line', (line) => {
|
|
87
|
-
const diagnostic = parseStructuredDiagnosticLine(line);
|
|
88
|
-
if (diagnostic) {
|
|
89
|
-
this.onDiagnostic?.(diagnostic);
|
|
90
|
-
return;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
this.onLine?.(line);
|
|
94
|
-
});
|
|
95
|
-
|
|
96
|
-
this.stderrReader = createInterface({ input: child.stderr, crlfDelay: Infinity });
|
|
97
|
-
this.stderrReader.on('line', (line) => {
|
|
98
|
-
this.onErrorLine?.(line);
|
|
99
|
-
});
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
public async sendStart(): Promise<void> {
|
|
103
|
-
await this.send({ type: 'start' });
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
public async sendChange(filePath: string): Promise<void> {
|
|
107
|
-
await this.send({ type: 'change', path: filePath });
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
public async sendReload(): Promise<void> {
|
|
111
|
-
await this.send({ type: 'reload' });
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
public async stop(): Promise<number | null> {
|
|
115
|
-
if (!this.child || !this.exitPromise) {
|
|
116
|
-
return 0;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
if (!this.isStopping) {
|
|
120
|
-
this.isStopping = true;
|
|
121
|
-
try {
|
|
122
|
-
await this.send({ type: 'shutdown' });
|
|
123
|
-
} catch {
|
|
124
|
-
// Fall through to best-effort teardown.
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
this.child.stdin.end();
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
const code = await this.exitPromise;
|
|
131
|
-
this.cleanup();
|
|
132
|
-
return code;
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
public async waitForExit(): Promise<number | null> {
|
|
136
|
-
if (!this.exitPromise) {
|
|
137
|
-
throw new Error('Frontend watch daemon has not started.');
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
const code = await this.exitPromise;
|
|
141
|
-
this.cleanup();
|
|
142
|
-
return code;
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
private async send(command: WatchDaemonCommand): Promise<void> {
|
|
146
|
-
if (!this.child || !this.child.stdin.writable) {
|
|
147
|
-
throw new Error('Frontend watch daemon is not running.');
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
await new Promise<void>((resolve, reject) => {
|
|
151
|
-
this.child!.stdin.write(`${JSON.stringify(command)}\n`, (error) => {
|
|
152
|
-
if (error) {
|
|
153
|
-
reject(error);
|
|
154
|
-
return;
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
resolve();
|
|
158
|
-
});
|
|
159
|
-
});
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
private cleanup(): void {
|
|
163
|
-
this.stdoutReader?.close();
|
|
164
|
-
this.stderrReader?.close();
|
|
165
|
-
this.stdoutReader = undefined;
|
|
166
|
-
this.stderrReader = undefined;
|
|
167
|
-
this.child = undefined;
|
|
168
|
-
this.exitPromise = undefined;
|
|
169
|
-
this.isStopping = false;
|
|
170
|
-
}
|
|
171
|
-
}
|