@jxsuite/server 8.6.0 → 8.7.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.
- package/package.json +16 -16
- package/src/code-api.ts +7 -24
- package/src/live-preview.ts +26 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jxsuite/server",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.7.0",
|
|
4
4
|
"description": "Jx development server with live reload, server-side proxy, and studio integration",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -55,18 +55,18 @@
|
|
|
55
55
|
"upgrade": "bun update --latest && bun install"
|
|
56
56
|
},
|
|
57
57
|
"dependencies": {
|
|
58
|
-
"@jxsuite/ai": "^0.43.
|
|
59
|
-
"@jxsuite/catalog": "^0.1.
|
|
60
|
-
"@jxsuite/collab": "^0.11.
|
|
61
|
-
"@jxsuite/compiler": "^8.
|
|
62
|
-
"@jxsuite/create": "^1.
|
|
63
|
-
"@jxsuite/erase": "^0.
|
|
64
|
-
"@jxsuite/import": "^0.44.
|
|
65
|
-
"@jxsuite/protocol": "^6.
|
|
66
|
-
"@jxsuite/runtime": "^6.
|
|
67
|
-
"@jxsuite/schema": "^5.
|
|
68
|
-
"@jxsuite/site": "^2.
|
|
69
|
-
"@jxsuite/starters": "^3.
|
|
58
|
+
"@jxsuite/ai": "^0.43.4",
|
|
59
|
+
"@jxsuite/catalog": "^0.1.12",
|
|
60
|
+
"@jxsuite/collab": "^0.11.10",
|
|
61
|
+
"@jxsuite/compiler": "^8.6.0",
|
|
62
|
+
"@jxsuite/create": "^1.8.0",
|
|
63
|
+
"@jxsuite/erase": "^0.2.0",
|
|
64
|
+
"@jxsuite/import": "^0.44.1",
|
|
65
|
+
"@jxsuite/protocol": "^6.3.0",
|
|
66
|
+
"@jxsuite/runtime": "^6.3.0",
|
|
67
|
+
"@jxsuite/schema": "^5.6.0",
|
|
68
|
+
"@jxsuite/site": "^2.6.0",
|
|
69
|
+
"@jxsuite/starters": "^3.5.0",
|
|
70
70
|
"@npmcli/arborist": "^10.0.4",
|
|
71
71
|
"chokidar": "^6.0.0",
|
|
72
72
|
"kysely": "^0.29.8",
|
|
@@ -76,9 +76,9 @@
|
|
|
76
76
|
"zod": "^4.6.7"
|
|
77
77
|
},
|
|
78
78
|
"devDependencies": {
|
|
79
|
-
"@jxsuite/auth": "^0.8.
|
|
80
|
-
"@jxsuite/connector": "^0.8.
|
|
81
|
-
"@jxsuite/parser": "^4.3.
|
|
79
|
+
"@jxsuite/auth": "^0.8.8",
|
|
80
|
+
"@jxsuite/connector": "^0.8.8",
|
|
81
|
+
"@jxsuite/parser": "^4.3.4",
|
|
82
82
|
"@jxsuite/test-support": "^0.0.0",
|
|
83
83
|
"@types/npm-package-arg": "^6.1.4",
|
|
84
84
|
"@types/npmcli__arborist": "^6.3.3",
|
package/src/code-api.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Code-api.js — OXC-powered code services for the studio function editor
|
|
3
3
|
*
|
|
4
|
-
* Endpoints under /__studio/code/* that
|
|
5
|
-
*
|
|
4
|
+
* Endpoints under /__studio/code/* that format (oxfmt) and lint (oxlint CLI) a function body. A
|
|
5
|
+
* body may be TypeScript (`spec.md` §23.1), so both read it as `.ts`.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import { tmpdir } from "node:os";
|
|
@@ -111,10 +111,6 @@ function adjustDiagnostics(diagnostics: OxcDiagnostic[], headerLen: number) {
|
|
|
111
111
|
});
|
|
112
112
|
}
|
|
113
113
|
|
|
114
|
-
// ─── Reusable transpiler ─────────────────────────────────────────────────────
|
|
115
|
-
|
|
116
|
-
const minifier = new Bun.Transpiler({ minifyWhitespace: true });
|
|
117
|
-
|
|
118
114
|
// ─── Handler ─────────────────────────────────────────────────────────────────
|
|
119
115
|
|
|
120
116
|
/**
|
|
@@ -148,7 +144,7 @@ export async function handleCodeApi(req: Request, url: URL) {
|
|
|
148
144
|
|
|
149
145
|
try {
|
|
150
146
|
const wrapped = wrapBody(code, args);
|
|
151
|
-
const result = await format("fn.
|
|
147
|
+
const result = await format("fn.ts", wrapped, { useTabs: true });
|
|
152
148
|
return Response.json({
|
|
153
149
|
code: unwrapFormatted(result.code),
|
|
154
150
|
errors: result.errors,
|
|
@@ -161,22 +157,6 @@ export async function handleCodeApi(req: Request, url: URL) {
|
|
|
161
157
|
}
|
|
162
158
|
}
|
|
163
159
|
|
|
164
|
-
// ── Minify ─────────────────────────────────────────────────────────────────
|
|
165
|
-
|
|
166
|
-
if (action === "minify") {
|
|
167
|
-
const { code } = body;
|
|
168
|
-
if (!code?.trim()) {
|
|
169
|
-
return Response.json({ code: "" });
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
try {
|
|
173
|
-
const minified = minifier.transformSync(code).trim();
|
|
174
|
-
return Response.json({ code: minified });
|
|
175
|
-
} catch (error) {
|
|
176
|
-
return Response.json({ code, error: errorMessage(error) });
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
|
|
180
160
|
// ── Lint ───────────────────────────────────────────────────────────────────
|
|
181
161
|
|
|
182
162
|
if (action === "lint") {
|
|
@@ -195,12 +175,15 @@ export async function handleCodeApi(req: Request, url: URL) {
|
|
|
195
175
|
const headerLen = wrapped.indexOf("\n") + 1;
|
|
196
176
|
const tmpFile = join(
|
|
197
177
|
tmpdir(),
|
|
198
|
-
`__jx_lint_${Date.now()}_${Math.random().toString(36).slice(2)}.
|
|
178
|
+
`__jx_lint_${Date.now()}_${Math.random().toString(36).slice(2)}.ts`,
|
|
199
179
|
);
|
|
200
180
|
|
|
201
181
|
try {
|
|
202
182
|
await Bun.write(tmpFile, wrapped);
|
|
183
|
+
// Run from the temp directory, so the body gets oxlint's defaults and not the rules of
|
|
184
|
+
// The repository the server happens to be started in.
|
|
203
185
|
const proc = Bun.spawn([oxlintBin, "--format=json", "-A", "no-unused-vars", tmpFile], {
|
|
186
|
+
cwd: tmpdir(),
|
|
204
187
|
stderr: "pipe",
|
|
205
188
|
stdout: "pipe",
|
|
206
189
|
});
|
package/src/live-preview.ts
CHANGED
|
@@ -174,6 +174,22 @@ async function loadRuntimeBundle(): Promise<string> {
|
|
|
174
174
|
return runtimeBundle;
|
|
175
175
|
}
|
|
176
176
|
|
|
177
|
+
/** The body eraser's browser bundle, built once per process, the first time a page asks for it. */
|
|
178
|
+
let eraserBundle: string | null = null;
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* `@jxsuite/erase/browser` as one browser module (`spec.md` §23.1). A page fetches it only when a
|
|
182
|
+
* function body is TypeScript, so most previews never ask, and none pays for it at startup. A build
|
|
183
|
+
* that fails is not kept, so the next page that needs it tries again.
|
|
184
|
+
*/
|
|
185
|
+
async function loadEraserBundle(): Promise<string> {
|
|
186
|
+
eraserBundle ??= await bundleToString(
|
|
187
|
+
createRequire(import.meta.url).resolve("@jxsuite/erase/browser"),
|
|
188
|
+
{ minify: true, target: "browser" },
|
|
189
|
+
);
|
|
190
|
+
return eraserBundle;
|
|
191
|
+
}
|
|
192
|
+
|
|
177
193
|
/** Every path under a servable root, plus anything the overlay is holding. */
|
|
178
194
|
async function treePaths(projectRoot: string, overlay: Map<string, string>): Promise<string[]> {
|
|
179
195
|
const found = new Set<string>(overlay.keys());
|
|
@@ -344,6 +360,15 @@ async function handle(entry: Running, projectRoot: string, req: Request): Promis
|
|
|
344
360
|
});
|
|
345
361
|
}
|
|
346
362
|
|
|
363
|
+
if (surface === "eraser.js") {
|
|
364
|
+
return new Response(await loadEraserBundle(), {
|
|
365
|
+
headers: {
|
|
366
|
+
"Cache-Control": "public, max-age=31536000, immutable",
|
|
367
|
+
"Content-Type": "text/javascript; charset=utf-8",
|
|
368
|
+
},
|
|
369
|
+
});
|
|
370
|
+
}
|
|
371
|
+
|
|
347
372
|
if (surface === "client.js") {
|
|
348
373
|
return new Response(PREVIEW_CLIENT_JS, {
|
|
349
374
|
headers: {
|
|
@@ -404,6 +429,7 @@ async function handle(entry: Running, projectRoot: string, req: Request): Promis
|
|
|
404
429
|
shell: {
|
|
405
430
|
base: "/",
|
|
406
431
|
clientScriptUrl: `${LIVE_NAMESPACE}/client.js`,
|
|
432
|
+
eraserUrl: `${LIVE_NAMESPACE}/eraser.js`,
|
|
407
433
|
resolveToken: entry.token,
|
|
408
434
|
runtimeUrl: `${LIVE_NAMESPACE}/runtime.js`,
|
|
409
435
|
styleUrl: `${LIVE_NAMESPACE}/site.css`,
|