rastack 0.0.64 → 0.0.69
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 +25 -0
- package/README.md +19 -24
- package/admin/httpEngine.ts +5 -6
- package/admin/index.tsx +11 -91
- package/dist/admin.js +14 -22
- package/dist/compile/model.d.ts +1 -1
- package/dist/compile/run.d.ts +2 -2
- package/dist/compile/run.js +2 -2
- package/dist/define/index.d.ts +2 -3
- package/dist/deploy/workflows.js +1 -1
- package/dist/dev/harness.d.ts +19 -27
- package/dist/dev/harness.js +31 -40
- package/dist/dev/native-server.d.ts +29 -0
- package/dist/dev/native-server.js +174 -0
- package/dist/external/envelope.d.ts +1 -1
- package/dist/external/envelope.js +1 -1
- package/dist/external/service.d.ts +2 -2
- package/dist/external/service.js +2 -2
- package/dist/external/types.d.ts +1 -1
- package/dist/external/types.js +1 -1
- package/dist/rastack-admin.d.ts +6 -14
- package/dist/rastack-admin.js +60 -88
- package/dist/rastack-design.d.ts +1 -2
- package/dist/rastack-design.js +1 -2
- package/dist/rastack-dev.d.ts +7 -10
- package/dist/rastack-dev.js +68 -80
- package/dist/rastack.d.ts +1 -1
- package/dist/rastack.js +5 -6
- package/dist/validate/transitions.d.ts +1 -1
- package/dist/validate/transitions.js +1 -1
- package/hooks/query/api.ts +4 -6
- package/package.json +2 -2
- package/provider/index.ts +0 -1
- package/provider/provider.tsx +31 -157
- package/provider/types.ts +29 -77
- package/src/compile/model.ts +1 -1
- package/src/compile/run.ts +2 -2
- package/src/define/index.ts +2 -3
- package/src/deploy/workflows.ts +1 -1
- package/src/dev/harness.ts +30 -43
- package/src/dev/native-server.ts +164 -0
- package/src/external/envelope.ts +1 -1
- package/src/external/service.ts +2 -2
- package/src/external/types.ts +1 -1
- package/src/rastack-admin.ts +66 -107
- package/src/rastack-design.ts +1 -2
- package/src/rastack-dev.ts +79 -91
- package/src/rastack.ts +5 -6
- package/src/validate/transitions.ts +1 -1
- package/dist/rastack-wasm-build.d.ts +0 -19
- package/dist/rastack-wasm-build.js +0 -94
- package/dist/wasm/package.json +0 -4
- package/dist/wasm/rastack_wasm.d.ts +0 -100
- package/dist/wasm/rastack_wasm.js +0 -745
- package/dist/wasm/rastack_wasm_bg.wasm +0 -0
- package/dist/wasm/rastack_wasm_bg.wasm.d.ts +0 -28
- package/provider/wasm.ts +0 -126
- package/scripts/copy-wasm.js +0 -35
- package/src/rastack-wasm-build.ts +0 -113
package/src/rastack-dev.ts
CHANGED
|
@@ -1,32 +1,24 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* `rastack dev` — local development of **your app
|
|
4
|
+
* `rastack dev` — local development of **your app** against the native engine.
|
|
5
5
|
*
|
|
6
6
|
* rastack dev [resourcesDir] [--port <n>] [--warehouse <dir>] [--out <dir>] [--app <dir>] [--no-open]
|
|
7
7
|
*
|
|
8
|
-
* Compiles the resources,
|
|
9
|
-
*
|
|
10
|
-
*
|
|
8
|
+
* Compiles the resources, starts a native `rastack-server` (`rastack-api-core`
|
|
9
|
+
* over the on-disk Iceberg warehouse), and serves the developer's app. The
|
|
10
|
+
* browser is the UI. `/api` on this origin is proxied to that process.
|
|
11
11
|
* • the developer's app (`index.html` from the resolved app root), or a
|
|
12
12
|
* Django-style welcome page when the project has no app yet,
|
|
13
|
-
* • the prebuilt WASM engine (`/wasm/…`) shipped in the package,
|
|
14
13
|
* • the compiled `schema.rastack.json` / `openapi.json`,
|
|
15
|
-
* •
|
|
14
|
+
* • `/api/…` forwarded to the native server.
|
|
16
15
|
*
|
|
17
16
|
* It does **not** serve the admin console — that is a separate command,
|
|
18
|
-
* `rastack admin`.
|
|
19
|
-
*
|
|
20
|
-
* The engine is resolved from the package's prebuilt bundle; if none is present
|
|
21
|
-
* but a Rust + wasm toolchain is, it is built from source as a fallback.
|
|
17
|
+
* `rastack admin`. The browser does not execute the engine. There is no
|
|
18
|
+
* in-browser fallback.
|
|
22
19
|
*/
|
|
23
20
|
|
|
24
|
-
import {
|
|
25
|
-
execFileSync,
|
|
26
|
-
spawn,
|
|
27
|
-
spawnSync,
|
|
28
|
-
type ChildProcess,
|
|
29
|
-
} from "child_process";
|
|
21
|
+
import { execFileSync, spawn, type ChildProcess } from "child_process";
|
|
30
22
|
import * as fs from "fs";
|
|
31
23
|
import * as http from "http";
|
|
32
24
|
import * as net from "net";
|
|
@@ -36,25 +28,17 @@ import { cognitoRuntimeConfig } from "./deploy/config";
|
|
|
36
28
|
import { loadConfig } from "./deploy/io";
|
|
37
29
|
import {
|
|
38
30
|
APP_ENTRY,
|
|
39
|
-
WASM_ENTRY,
|
|
40
31
|
appRootCandidates,
|
|
41
32
|
contentType,
|
|
42
33
|
type DevArgs,
|
|
43
34
|
parseDevArgs,
|
|
44
35
|
renderWelcome,
|
|
45
|
-
wasmBundleCandidates,
|
|
46
36
|
} from "./dev/harness";
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
try {
|
|
53
|
-
return spawnSync("cargo", ["--version"], { stdio: "ignore" }).status === 0;
|
|
54
|
-
} catch {
|
|
55
|
-
return false;
|
|
56
|
-
}
|
|
57
|
-
}
|
|
37
|
+
import {
|
|
38
|
+
ensureServerBinary,
|
|
39
|
+
startNativeServer,
|
|
40
|
+
waitForTcp,
|
|
41
|
+
} from "./dev/native-server";
|
|
58
42
|
|
|
59
43
|
/** First app-root candidate that holds an `index.html`, or null (→ welcome). */
|
|
60
44
|
function resolveAppRoot(appDir: string): string | null {
|
|
@@ -64,30 +48,6 @@ function resolveAppRoot(appDir: string): string | null {
|
|
|
64
48
|
return null;
|
|
65
49
|
}
|
|
66
50
|
|
|
67
|
-
/** Locate the prebuilt wasm bundle dir, building from source as a fallback. */
|
|
68
|
-
function resolveWasmDir(): string | null {
|
|
69
|
-
for (const dir of wasmBundleCandidates(HERE)) {
|
|
70
|
-
if (fs.existsSync(path.join(dir, WASM_ENTRY))) return dir;
|
|
71
|
-
}
|
|
72
|
-
if (cargoAvailable()) {
|
|
73
|
-
console.log(
|
|
74
|
-
"\n▸ No prebuilt WASM engine found — building it from source (cargo)…\n",
|
|
75
|
-
);
|
|
76
|
-
try {
|
|
77
|
-
// Lazy require so a normal `dev` with a prebuilt bundle never loads it.
|
|
78
|
-
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
79
|
-
require("./rastack-wasm-build").buildWasm();
|
|
80
|
-
} catch (err) {
|
|
81
|
-
console.error(` ✗ wasm build failed: ${(err as Error).message}`);
|
|
82
|
-
return null;
|
|
83
|
-
}
|
|
84
|
-
for (const dir of wasmBundleCandidates(HERE)) {
|
|
85
|
-
if (fs.existsSync(path.join(dir, WASM_ENTRY))) return dir;
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
return null;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
51
|
/** Serve one file if it exists and stays within `root`; else 404/403. */
|
|
92
52
|
function serveUnder(
|
|
93
53
|
res: http.ServerResponse,
|
|
@@ -174,8 +134,9 @@ function openBrowser(url: string): void {
|
|
|
174
134
|
// A React Native (Expo) app has no static `index.html`: its web build is a
|
|
175
135
|
// Metro bundle. Rather than make the developer run a second tool, `dev` starts
|
|
176
136
|
// Expo's Metro dev server itself and reverse-proxies to it, so `rastack dev`
|
|
177
|
-
// stays the single command *and* keeps Metro's fast-refresh.
|
|
178
|
-
//
|
|
137
|
+
// stays the single command *and* keeps Metro's fast-refresh. Apps that ship
|
|
138
|
+
// a built index.html use the static server below. Both proxy /api to the
|
|
139
|
+
// native server.
|
|
179
140
|
// ---------------------------------------------------------------------------
|
|
180
141
|
|
|
181
142
|
/** True when the project is an Expo app (so `dev` should drive Metro). */
|
|
@@ -199,15 +160,7 @@ function isExpoProject(cwd: string): boolean {
|
|
|
199
160
|
return false;
|
|
200
161
|
}
|
|
201
162
|
|
|
202
|
-
/**
|
|
203
|
-
function findWasmDir(): string | null {
|
|
204
|
-
for (const dir of wasmBundleCandidates(HERE)) {
|
|
205
|
-
if (fs.existsSync(path.join(dir, WASM_ENTRY))) return dir;
|
|
206
|
-
}
|
|
207
|
-
return null;
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
/** Grab an ephemeral free TCP port for Metro (avoids a fixed-port clash). */
|
|
163
|
+
/** Grab an ephemeral free TCP port (Metro, or the native API beside this server). */
|
|
211
164
|
function getFreePort(): Promise<number> {
|
|
212
165
|
return new Promise((resolve, reject) => {
|
|
213
166
|
const srv = net.createServer();
|
|
@@ -295,7 +248,7 @@ function proxyToMetro(
|
|
|
295
248
|
);
|
|
296
249
|
proxyReq.on("error", () => {
|
|
297
250
|
if (!res.headersSent) res.writeHead(502);
|
|
298
|
-
res.end("
|
|
251
|
+
res.end("Upstream is not reachable.");
|
|
299
252
|
});
|
|
300
253
|
req.pipe(proxyReq);
|
|
301
254
|
}
|
|
@@ -323,11 +276,12 @@ function proxyUpgrade(
|
|
|
323
276
|
}
|
|
324
277
|
|
|
325
278
|
/** `rastack dev` for an Expo app: start Metro and reverse-proxy to it. */
|
|
326
|
-
async function runMetroMode(
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
279
|
+
async function runMetroMode(
|
|
280
|
+
args: DevArgs,
|
|
281
|
+
cwd: string,
|
|
282
|
+
apiPort: number,
|
|
283
|
+
stopEngine: () => void,
|
|
284
|
+
): Promise<void> {
|
|
331
285
|
const metroPort = await getFreePort();
|
|
332
286
|
console.log(`▸ Starting Metro bundler (Expo) on :${metroPort} …`);
|
|
333
287
|
const metro = startMetro(cwd, metroPort);
|
|
@@ -336,6 +290,7 @@ async function runMetroMode(args: DevArgs, cwd: string): Promise<void> {
|
|
|
336
290
|
const stop = (code = 0) => {
|
|
337
291
|
if (shuttingDown) return;
|
|
338
292
|
shuttingDown = true;
|
|
293
|
+
stopEngine();
|
|
339
294
|
try {
|
|
340
295
|
metro.kill();
|
|
341
296
|
} catch {
|
|
@@ -359,9 +314,8 @@ async function runMetroMode(args: DevArgs, cwd: string): Promise<void> {
|
|
|
359
314
|
|
|
360
315
|
const server = http.createServer((req, res) => {
|
|
361
316
|
const url = (req.url || "/").split("?")[0];
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
return serveUnder(res, wasmDir, url.slice("/wasm/".length));
|
|
317
|
+
if (url.startsWith("/api/") || url === "/api")
|
|
318
|
+
return proxyToMetro(req, res, apiPort);
|
|
365
319
|
if (url === "/schema.rastack.json" || url === "/openapi.json")
|
|
366
320
|
return serveUnder(res, args.outDir, path.basename(url));
|
|
367
321
|
if (url === "/__rastack/cognito.json") return serveDevCognito(res, cwd);
|
|
@@ -392,7 +346,7 @@ async function runMetroMode(args: DevArgs, cwd: string): Promise<void> {
|
|
|
392
346
|
server.listen(args.port, () => {
|
|
393
347
|
const url = `http://localhost:${args.port}`;
|
|
394
348
|
console.log(` ✓ Metro live on :${metroPort} — fast refresh on`);
|
|
395
|
-
|
|
349
|
+
console.log(` ✓ native engine: 127.0.0.1:${apiPort} (proxied at /api)`);
|
|
396
350
|
console.log(`\n ▸ ${url}\n`);
|
|
397
351
|
console.log(
|
|
398
352
|
" Edits reload live. Need the database console? Run `rastack admin`. Ctrl+C to stop.\n",
|
|
@@ -405,7 +359,9 @@ async function main(argv: string[]): Promise<void> {
|
|
|
405
359
|
const args = parseDevArgs(argv);
|
|
406
360
|
const cwd = process.cwd();
|
|
407
361
|
|
|
408
|
-
console.log(
|
|
362
|
+
console.log(
|
|
363
|
+
`\n rastack dev — your app in the browser, the API in native Rust\n`,
|
|
364
|
+
);
|
|
409
365
|
console.log(`▸ Compiling ${args.resourcesDir} → ${args.outDir}`);
|
|
410
366
|
if (!runCompile(args.resourcesDir, args.outDir)) {
|
|
411
367
|
console.error(" ✗ compile failed — fix the resource graph and re-run.");
|
|
@@ -415,32 +371,64 @@ async function main(argv: string[]): Promise<void> {
|
|
|
415
371
|
// Serve the developer's own app when there is one; otherwise the welcome page.
|
|
416
372
|
const appRoot = resolveAppRoot(args.appDir);
|
|
417
373
|
|
|
374
|
+
let engine: ChildProcess;
|
|
375
|
+
let apiPort: number;
|
|
376
|
+
let stopping = false;
|
|
377
|
+
try {
|
|
378
|
+
const bin = ensureServerBinary(cwd);
|
|
379
|
+
apiPort = await getFreePort();
|
|
380
|
+
const manifest = path.resolve(cwd, args.outDir, "schema.rastack.json");
|
|
381
|
+
const warehouse = path.resolve(cwd, args.warehouseDir);
|
|
382
|
+
engine = startNativeServer({
|
|
383
|
+
bin,
|
|
384
|
+
command: "serve",
|
|
385
|
+
manifest,
|
|
386
|
+
warehouse,
|
|
387
|
+
addr: `127.0.0.1:${apiPort}`,
|
|
388
|
+
});
|
|
389
|
+
await waitForTcp(apiPort, engine);
|
|
390
|
+
} catch (err) {
|
|
391
|
+
console.error(`\n${(err as Error).message}\n`);
|
|
392
|
+
process.exit(1);
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
const stopEngine = () => {
|
|
396
|
+
stopping = true;
|
|
397
|
+
try {
|
|
398
|
+
engine.kill("SIGTERM");
|
|
399
|
+
} catch {
|
|
400
|
+
/* already gone */
|
|
401
|
+
}
|
|
402
|
+
};
|
|
403
|
+
engine.on("exit", (code) => {
|
|
404
|
+
if (stopping) return;
|
|
405
|
+
console.error(`\n ✗ native engine exited (code ${code ?? "?"}).`);
|
|
406
|
+
process.exit(code ?? 1);
|
|
407
|
+
});
|
|
408
|
+
|
|
418
409
|
// No static build, but an Expo source tree → drive Metro live (fast refresh).
|
|
410
|
+
// Metro mode owns the shutdown signals so it can stop both processes.
|
|
419
411
|
if (!appRoot && isExpoProject(cwd)) {
|
|
420
|
-
return runMetroMode(args, cwd);
|
|
412
|
+
return runMetroMode(args, cwd, apiPort, stopEngine);
|
|
421
413
|
}
|
|
422
414
|
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
);
|
|
432
|
-
process.exit(1);
|
|
433
|
-
}
|
|
415
|
+
process.on("SIGINT", () => {
|
|
416
|
+
stopEngine();
|
|
417
|
+
process.exit(0);
|
|
418
|
+
});
|
|
419
|
+
process.on("SIGTERM", () => {
|
|
420
|
+
stopEngine();
|
|
421
|
+
process.exit(0);
|
|
422
|
+
});
|
|
434
423
|
|
|
435
424
|
const server = http.createServer((req, res) => {
|
|
436
425
|
const url = (req.url || "/").split("?")[0];
|
|
426
|
+
if (url.startsWith("/api/") || url === "/api")
|
|
427
|
+
return proxyToMetro(req, res, apiPort);
|
|
437
428
|
if (req.method !== "GET") {
|
|
438
429
|
res.writeHead(405).end("Method not allowed");
|
|
439
430
|
return;
|
|
440
431
|
}
|
|
441
|
-
// Reserved backend routes always win over the app's static files.
|
|
442
|
-
if (url.startsWith("/wasm/"))
|
|
443
|
-
return serveUnder(res, wasmDir, url.slice("/wasm/".length));
|
|
444
432
|
if (url === "/schema.rastack.json" || url === "/openapi.json")
|
|
445
433
|
return serveUnder(res, args.outDir, path.basename(url));
|
|
446
434
|
if (url === "/__rastack/cognito.json") return serveDevCognito(res, cwd);
|
|
@@ -479,7 +467,7 @@ async function main(argv: string[]): Promise<void> {
|
|
|
479
467
|
|
|
480
468
|
server.listen(args.port, () => {
|
|
481
469
|
const url = `http://localhost:${args.port}`;
|
|
482
|
-
console.log(` ✓
|
|
470
|
+
console.log(` ✓ native engine: 127.0.0.1:${apiPort} (proxied at /api)`);
|
|
483
471
|
if (appRoot)
|
|
484
472
|
console.log(` ✓ app: ${path.relative(process.cwd(), appRoot) || "."}`);
|
|
485
473
|
else console.log(` ○ no app found — serving the welcome page`);
|
package/src/rastack.ts
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
* rastack generate [--schema-only] Generate typed hooks from OpenAPI
|
|
14
14
|
* rastack tokens [input] [outDir] Compile design tokens → CSS vars + typed theme
|
|
15
15
|
* rastack design [input] [--port n] Live design-system studio (showcase + edit)
|
|
16
|
-
* rastack dev [--port n] [--warehouse d] Local dev:
|
|
16
|
+
* rastack dev [--port n] [--warehouse d] Local dev: your app in the browser, the API in native Rust
|
|
17
17
|
* rastack admin [--warehouse dir] [--port n] Full admin console — React UI (rastack/components) over the native server
|
|
18
18
|
* rastack import <file> --resource app.model Load CSV/XLSX/PDF data and validate it (state machine)
|
|
19
19
|
* rastack scan [files...] [--fail-on-pii] (LEGACY, pre-Rust) Scan CSVs for PII and schema info
|
|
@@ -72,7 +72,7 @@ switch (command) {
|
|
|
72
72
|
console.error(
|
|
73
73
|
"`rastack compile` has been removed — compilation now runs automatically\n" +
|
|
74
74
|
"inside the two modalities of use:\n" +
|
|
75
|
-
" • rastack dev local development (compiles, then
|
|
75
|
+
" • rastack dev local development (compiles, then proxies /api to native rastack-server)\n" +
|
|
76
76
|
" • rastack ci the deploy pipeline (compiles the manifest + OpenAPI)\n\n" +
|
|
77
77
|
"Introspect the resource graph with: rastack check | list | urls\n",
|
|
78
78
|
);
|
|
@@ -85,9 +85,8 @@ switch (command) {
|
|
|
85
85
|
run("rastack-compile.js", [command, ...rest]);
|
|
86
86
|
break;
|
|
87
87
|
case "dev":
|
|
88
|
-
// Local development: serve your app
|
|
89
|
-
//
|
|
90
|
-
// `rastack admin`. Replaces `serve` + `wasm`.
|
|
88
|
+
// Local development: serve your app and proxy /api to native rastack-server.
|
|
89
|
+
// The admin console is a separate command, `rastack admin`.
|
|
91
90
|
run("rastack-dev.js", rest);
|
|
92
91
|
break;
|
|
93
92
|
case "admin":
|
|
@@ -162,7 +161,7 @@ switch (command) {
|
|
|
162
161
|
` rastack generate [--schema-only]\n` +
|
|
163
162
|
` rastack tokens [input] [outDir] [--prefix p] Compile design tokens → CSS vars + typed theme\n` +
|
|
164
163
|
` rastack design [input] [--port n] Live design-system studio (showcase + edit)\n` +
|
|
165
|
-
` rastack dev [--port n] [--warehouse dir] [--app dir] [--no-open]
|
|
164
|
+
` rastack dev [--port n] [--warehouse dir] [--app dir] [--no-open] App in the browser, API in native rastack-server\n` +
|
|
166
165
|
` rastack admin [--warehouse dir] [--port n] [--no-open] Full admin console (React UI over the native server; needs a built rastack-server)\n` +
|
|
167
166
|
` rastack import <file.csv|.xlsx|.pdf> --resource app.model [--related app.model=<file>] [--out cleaned.json]\n` +
|
|
168
167
|
` rastack scan [files...] [--fail-on-pii] (legacy, pre-Rust)\n` +
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
* list), and this module is the *shared executable form* of it: the same pure
|
|
24
24
|
* functions guard a form submit (`useForm(...).transition("board")`), the
|
|
25
25
|
* record machine (`runRecordMachine` with a `previous` row in context), and —
|
|
26
|
-
* re-implemented 1:1 in `rastack-api-core` — every server
|
|
26
|
+
* re-implemented 1:1 in `rastack-api-core` — every native-server write. A write
|
|
27
27
|
* that jumps between states without a declared edge is rejected on every
|
|
28
28
|
* surface, which is what makes a transition "a backend function that is
|
|
29
29
|
* state-machine safe": the only way to move a record between states is a
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* Compile the Rust API to WebAssembly for in-browser local dev — the engine
|
|
4
|
-
* `rastack dev` serves and `<RAStackProvider mode="local">` loads.
|
|
5
|
-
*
|
|
6
|
-
* Pipeline:
|
|
7
|
-
* 1. cargo build -p rastack-wasm --release --target wasm32-unknown-unknown
|
|
8
|
-
* 2. wasm-bindgen --target web → wasm/rastack_wasm.js + rastack_wasm_bg.wasm
|
|
9
|
-
* 3. wasm-opt -Oz (if available) to shrink the binary
|
|
10
|
-
*
|
|
11
|
-
* This is invoked by the release CI (to bundle a prebuilt engine into the npm
|
|
12
|
-
* package) and by `rastack dev` as a from-source fallback when no prebuilt
|
|
13
|
-
* bundle is present but the toolchain is. Prereqs:
|
|
14
|
-
* rustup target add wasm32-unknown-unknown
|
|
15
|
-
* cargo install wasm-bindgen-cli (version must match the wasm-bindgen crate)
|
|
16
|
-
*/
|
|
17
|
-
/** Run the full compile → wasm-bindgen → optimise pipeline. Throws via `run`'s
|
|
18
|
-
* `process.exit` on a missing tool or a non-zero step. */
|
|
19
|
-
export declare function buildWasm(): void;
|
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
"use strict";
|
|
3
|
-
/**
|
|
4
|
-
* Compile the Rust API to WebAssembly for in-browser local dev — the engine
|
|
5
|
-
* `rastack dev` serves and `<RAStackProvider mode="local">` loads.
|
|
6
|
-
*
|
|
7
|
-
* Pipeline:
|
|
8
|
-
* 1. cargo build -p rastack-wasm --release --target wasm32-unknown-unknown
|
|
9
|
-
* 2. wasm-bindgen --target web → wasm/rastack_wasm.js + rastack_wasm_bg.wasm
|
|
10
|
-
* 3. wasm-opt -Oz (if available) to shrink the binary
|
|
11
|
-
*
|
|
12
|
-
* This is invoked by the release CI (to bundle a prebuilt engine into the npm
|
|
13
|
-
* package) and by `rastack dev` as a from-source fallback when no prebuilt
|
|
14
|
-
* bundle is present but the toolchain is. Prereqs:
|
|
15
|
-
* rustup target add wasm32-unknown-unknown
|
|
16
|
-
* cargo install wasm-bindgen-cli (version must match the wasm-bindgen crate)
|
|
17
|
-
*/
|
|
18
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
19
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
20
|
-
};
|
|
21
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
|
-
exports.buildWasm = buildWasm;
|
|
23
|
-
const child_process_1 = require("child_process");
|
|
24
|
-
const fs_1 = __importDefault(require("fs"));
|
|
25
|
-
const path_1 = __importDefault(require("path"));
|
|
26
|
-
const repoRoot = path_1.default.resolve(__dirname, "..");
|
|
27
|
-
const rustDir = path_1.default.join(repoRoot, "engine");
|
|
28
|
-
const outDir = path_1.default.join(repoRoot, "wasm");
|
|
29
|
-
const wasmPath = path_1.default.join(rustDir, "target", "wasm32-unknown-unknown", "release", "rastack_wasm.wasm");
|
|
30
|
-
function run(cmd, args, cwd = repoRoot) {
|
|
31
|
-
// Local build tool: `cmd`/`args` are the fixed toolchain invocations below
|
|
32
|
-
// (cargo, wasm-bindgen, wasm-opt), not untrusted input — no injection surface.
|
|
33
|
-
// nosemgrep: javascript.lang.security.detect-child-process.detect-child-process
|
|
34
|
-
const result = (0, child_process_1.spawnSync)(cmd, args, {
|
|
35
|
-
stdio: "inherit",
|
|
36
|
-
cwd,
|
|
37
|
-
env: process.env,
|
|
38
|
-
});
|
|
39
|
-
if (result.error) {
|
|
40
|
-
console.error(`\nCould not run \`${cmd}\`. Is it installed and on PATH?`);
|
|
41
|
-
if (cmd === "wasm-bindgen") {
|
|
42
|
-
console.error(" cargo install wasm-bindgen-cli");
|
|
43
|
-
}
|
|
44
|
-
process.exit(1);
|
|
45
|
-
}
|
|
46
|
-
if (result.status !== 0) {
|
|
47
|
-
process.exit(result.status ?? 1);
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
function has(cmd) {
|
|
51
|
-
// Probes a fixed toolchain name (e.g. "wasm-opt") for availability; not
|
|
52
|
-
// untrusted input.
|
|
53
|
-
// nosemgrep: javascript.lang.security.detect-child-process.detect-child-process
|
|
54
|
-
return (0, child_process_1.spawnSync)(cmd, ["--version"], { stdio: "ignore" }).status === 0;
|
|
55
|
-
}
|
|
56
|
-
/** Run the full compile → wasm-bindgen → optimise pipeline. Throws via `run`'s
|
|
57
|
-
* `process.exit` on a missing tool or a non-zero step. */
|
|
58
|
-
function buildWasm() {
|
|
59
|
-
console.log("→ cargo build -p rastack-wasm --release (wasm32-unknown-unknown)");
|
|
60
|
-
run("cargo", [
|
|
61
|
-
"build",
|
|
62
|
-
"-p",
|
|
63
|
-
"rastack-wasm",
|
|
64
|
-
"--release",
|
|
65
|
-
"--target",
|
|
66
|
-
"wasm32-unknown-unknown",
|
|
67
|
-
], rustDir);
|
|
68
|
-
console.log("→ wasm-bindgen → wasm/");
|
|
69
|
-
run("wasm-bindgen", [
|
|
70
|
-
"--target",
|
|
71
|
-
"web",
|
|
72
|
-
"--out-dir",
|
|
73
|
-
outDir,
|
|
74
|
-
"--out-name",
|
|
75
|
-
"rastack_wasm",
|
|
76
|
-
wasmPath,
|
|
77
|
-
]);
|
|
78
|
-
// Mark the emitted bundle as ESM so Node and bundlers treat it correctly
|
|
79
|
-
// without forcing the parent rastack package to be a module.
|
|
80
|
-
fs_1.default.writeFileSync(path_1.default.join(outDir, "package.json"), JSON.stringify({ type: "module", sideEffects: false }, null, 2) + "\n");
|
|
81
|
-
if (has("wasm-opt")) {
|
|
82
|
-
console.log("→ wasm-opt -Oz");
|
|
83
|
-
const bg = path_1.default.join(outDir, "rastack_wasm_bg.wasm");
|
|
84
|
-
run("wasm-opt", ["-Oz", "-o", bg, bg]);
|
|
85
|
-
}
|
|
86
|
-
else {
|
|
87
|
-
console.log("· wasm-opt not found — skipping size optimisation (optional)");
|
|
88
|
-
}
|
|
89
|
-
const size = fs_1.default.statSync(path_1.default.join(outDir, "rastack_wasm_bg.wasm")).size;
|
|
90
|
-
console.log(`✓ wasm engine built: wasm/ (${(size / 1024).toFixed(0)} KB)`);
|
|
91
|
-
}
|
|
92
|
-
if (require.main === module) {
|
|
93
|
-
buildWasm();
|
|
94
|
-
}
|
package/dist/wasm/package.json
DELETED
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
/* tslint:disable */
|
|
2
|
-
/* eslint-disable */
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* The in-browser API engine. Cheap to clone (everything behind `Arc`), which
|
|
6
|
-
* is what lets each async call own its state without borrowing across `await`.
|
|
7
|
-
*/
|
|
8
|
-
export class RastackApi {
|
|
9
|
-
free(): void;
|
|
10
|
-
[Symbol.dispose](): void;
|
|
11
|
-
/**
|
|
12
|
-
* Snapshot the entire warehouse to a blob for persistence (`data/` folder,
|
|
13
|
-
* IndexedDB, or an upload to S3).
|
|
14
|
-
*/
|
|
15
|
-
exportWarehouse(): Promise<any>;
|
|
16
|
-
/**
|
|
17
|
-
* Handle one request. `query` is a `{ [k]: string }` object, `body` any
|
|
18
|
-
* JSON value (or `undefined`). Resolves to `{ status, body }`.
|
|
19
|
-
*/
|
|
20
|
-
handle(method: string, path: string, query: any, body: any): Promise<any>;
|
|
21
|
-
/**
|
|
22
|
-
* Seed the warehouse from a blob previously produced by
|
|
23
|
-
* [`export_warehouse`](Self::export_warehouse) (the `data/` folder or an
|
|
24
|
-
* IndexedDB/OPFS snapshot).
|
|
25
|
-
*/
|
|
26
|
-
importWarehouse(blob: Uint8Array): Promise<any>;
|
|
27
|
-
/**
|
|
28
|
-
* Build an engine from the compiled manifest (`schema.rastack.json`) and an
|
|
29
|
-
* optional OpenAPI document (`openapi.json`, served at `/api/schema/`).
|
|
30
|
-
*/
|
|
31
|
-
constructor(manifest_json: string, openapi_json?: string | null);
|
|
32
|
-
/**
|
|
33
|
-
* Seed one Iceberg file (metadata or data file) at its warehouse key. The
|
|
34
|
-
* provider walks the committed `data/warehouse` Iceberg tree over HTTP and
|
|
35
|
-
* calls this for each file, so the browser reads the *actual* Iceberg files
|
|
36
|
-
* — no bundled blob.
|
|
37
|
-
*/
|
|
38
|
-
seedFile(key: string, bytes: Uint8Array): Promise<any>;
|
|
39
|
-
/**
|
|
40
|
-
* Run subsequent requests as a signed-in identity (the Cognito `sub` and
|
|
41
|
-
* `cognito:groups` claims). Owner fields are stamped from — and row
|
|
42
|
-
* filters and tenant scoping keyed by — this subject, matching the server
|
|
43
|
-
* byte-for-byte. Pass no subject to fall back to the trusted local
|
|
44
|
-
* context.
|
|
45
|
-
*/
|
|
46
|
-
setAuth(subject: string | null | undefined, groups: any): void;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module;
|
|
50
|
-
|
|
51
|
-
export interface InitOutput {
|
|
52
|
-
readonly memory: WebAssembly.Memory;
|
|
53
|
-
readonly __wbg_rastackapi_free: (a: number, b: number) => void;
|
|
54
|
-
readonly rastackapi_exportWarehouse: (a: number) => any;
|
|
55
|
-
readonly rastackapi_handle: (a: number, b: number, c: number, d: number, e: number, f: any, g: any) => any;
|
|
56
|
-
readonly rastackapi_importWarehouse: (a: number, b: number, c: number) => any;
|
|
57
|
-
readonly rastackapi_new: (a: number, b: number, c: number, d: number) => [number, number, number];
|
|
58
|
-
readonly rastackapi_seedFile: (a: number, b: number, c: number, d: number, e: number) => any;
|
|
59
|
-
readonly rastackapi_setAuth: (a: number, b: number, c: number, d: any) => [number, number];
|
|
60
|
-
readonly rust_zstd_wasm_shim_calloc: (a: number, b: number) => number;
|
|
61
|
-
readonly rust_zstd_wasm_shim_free: (a: number) => void;
|
|
62
|
-
readonly rust_zstd_wasm_shim_malloc: (a: number) => number;
|
|
63
|
-
readonly rust_zstd_wasm_shim_memcmp: (a: number, b: number, c: number) => number;
|
|
64
|
-
readonly rust_zstd_wasm_shim_memcpy: (a: number, b: number, c: number) => number;
|
|
65
|
-
readonly rust_zstd_wasm_shim_memmove: (a: number, b: number, c: number) => number;
|
|
66
|
-
readonly rust_zstd_wasm_shim_memset: (a: number, b: number, c: number) => number;
|
|
67
|
-
readonly rust_zstd_wasm_shim_qsort: (a: number, b: number, c: number, d: number) => void;
|
|
68
|
-
readonly wasm_bindgen_ac0f9960a408a037___convert__closures_____invoke___wasm_bindgen_ac0f9960a408a037___JsValue__core_9b3796e30d99ddb7___result__Result_____wasm_bindgen_ac0f9960a408a037___JsError___true_: (a: number, b: number, c: any) => [number, number];
|
|
69
|
-
readonly wasm_bindgen_ac0f9960a408a037___convert__closures_____invoke___js_sys_10c47e7ecd0a94ab___Function_fn_wasm_bindgen_ac0f9960a408a037___JsValue_____wasm_bindgen_ac0f9960a408a037___sys__Undefined___js_sys_10c47e7ecd0a94ab___Function_fn_wasm_bindgen_ac0f9960a408a037___JsValue_____wasm_bindgen_ac0f9960a408a037___sys__Undefined_______true_: (a: number, b: number, c: any, d: any) => void;
|
|
70
|
-
readonly __wbindgen_malloc: (a: number, b: number) => number;
|
|
71
|
-
readonly __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number;
|
|
72
|
-
readonly __wbindgen_exn_store: (a: number) => void;
|
|
73
|
-
readonly __externref_table_alloc: () => number;
|
|
74
|
-
readonly __wbindgen_externrefs: WebAssembly.Table;
|
|
75
|
-
readonly __wbindgen_destroy_closure: (a: number, b: number) => void;
|
|
76
|
-
readonly __externref_table_dealloc: (a: number) => void;
|
|
77
|
-
readonly __wbindgen_start: () => void;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
export type SyncInitInput = BufferSource | WebAssembly.Module;
|
|
81
|
-
|
|
82
|
-
/**
|
|
83
|
-
* Instantiates the given `module`, which can either be bytes or
|
|
84
|
-
* a precompiled `WebAssembly.Module`.
|
|
85
|
-
*
|
|
86
|
-
* @param {{ module: SyncInitInput }} module - Passing `SyncInitInput` directly is deprecated.
|
|
87
|
-
*
|
|
88
|
-
* @returns {InitOutput}
|
|
89
|
-
*/
|
|
90
|
-
export function initSync(module: { module: SyncInitInput } | SyncInitInput): InitOutput;
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* If `module_or_path` is {RequestInfo} or {URL}, makes a request and
|
|
94
|
-
* for everything else, calls `WebAssembly.instantiate` directly.
|
|
95
|
-
*
|
|
96
|
-
* @param {{ module_or_path: InitInput | Promise<InitInput> }} module_or_path - Passing `InitInput` directly is deprecated.
|
|
97
|
-
*
|
|
98
|
-
* @returns {Promise<InitOutput>}
|
|
99
|
-
*/
|
|
100
|
-
export default function __wbg_init (module_or_path?: { module_or_path: InitInput | Promise<InitInput> } | InitInput | Promise<InitInput>): Promise<InitOutput>;
|