diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1336ef8..68d092a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -80,10 +80,12 @@ jobs: run: | ./target/debug/slice serve ./tests/apps/09-wintertc-web-router --port=18080 --smoke-test - - name: Verify time-travel deterministic test runner + - name: Verify time-travel deterministic test runner and SvelteKit 3 Edge SSR run: | (cd ./tests/apps/15-time-travel-test-suite && npm install --no-audit --no-fund) ./target/debug/slice test ./tests/apps/15-time-travel-test-suite + (cd ./tests/frameworks/04-sveltekit-edge-ssr && npm install --no-audit --no-fund && npm run build) + ./target/debug/slice test ./tests/frameworks/04-sveltekit-edge-ssr - name: Verify Flagship Case Studies & Workbench (CS 01-05) run: | diff --git a/.gitignore b/.gitignore index 2bce38d..3692ac7 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,10 @@ *.cas *.snap **/node_modules/ +**/.svelte-kit/ +tests/frameworks/04-sveltekit-edge-ssr/src/build/ +tests/frameworks/04-sveltekit-edge-ssr/build/ +tests/frameworks/04-sveltekit-edge-ssr/package-lock.json /docs/system/raw_results_*.json /docs/general/raw_results_*.json /docs/raw_results_*.json diff --git a/README.md b/README.md index b975cd7..65fab5b 100644 --- a/README.md +++ b/README.md @@ -12,9 +12,9 @@ ## Verified Benchmark Overview (Linux `x86_64` Docker & Windows `x86_64`) -> **Latest Verified Benchmark Report:** **[`tests/reports/latest.md`](./tests/reports/latest.md)** (Archive: [`bench_v0.10.4_20261109_073538Z_7a86dd6.md`](./tests/reports/bench_v0.10.4_20261109_073538Z_7a86dd6.md)) -> **Provenance:** Slice `v0.10.5` (`7a86dd6`) · Generated `2026-11-09T07:35:38Z` · Environment: `Linux x86_64 Docker (io_uring SQPOLL + WRPKRU)` -> **Scorecard Across All 32 Production Workloads:** Beats **Deno (`v2.9.8`)** on **32/32**, **Node.js (`v27.0.0-alpha.0.0.0`)** on **32/32**, **Bun (`v1.4.4`)** on **29/32** cold one-shot, and **all 3 runtimes on 32/32 workloads in `--warm` pooled execution**. +> **Latest Verified Benchmark Report:** **[`tests/reports/latest.md`](./tests/reports/latest.md)** (Archive: [`bench_v0.10.5_20261109_202907Z_a0c723e.md`](./tests/reports/bench_v0.10.5_20261109_202907Z_a0c723e.md)) +> **Provenance:** Slice `v0.10.5` (`a0c723e`) · Generated `2026-11-09T20:29:07Z` · Environment: `Linux x86_64 Docker (io_uring SQPOLL + WRPKRU)` +> **Scorecard Across All 33 Production Workloads:** Beats **Deno (`v2.9.8`)** on **33/33**, **Node.js (`v27.0.0-alpha.0.0.0`)** on **33/33**, **Bun (`v1.4.4`)** on **30/33** cold one-shot, and **all 3 runtimes on 33/33 workloads in `--warm` pooled execution**. #### 1. Core Architecture, HTTP Throughput & 1,000-Tenant MicroVM Density @@ -24,10 +24,10 @@ | **1,000-Tenant MicroVM Swarm (Boot + Exec)** | **`1.51 ms` (`10.07 MB` RSS)** | > 5,000 ms | > 15,000 ms | > 30,000 ms | **> 3,900x faster / ~32,000x denser** | | **500-Module Monorepo Cold Boot (`stat()` Calls)** | **`3.41 ms` (`0 stat()`)** | `12.72 ms` (`500+ stat`) | `41.80 ms` (`500+ stat`) | `70.38 ms` (`1,500+ stat`) | **`3.7x` faster than Bun / `20.6x` Node.js** | | **HTTP/1.1 Keep-Alive Throughput (`16k` Reqs)** | **`148,407 req/s`** (Tier-0)
**`145,839 req/s`** (Tier-1) | `97,987 req/s` | `100,099 req/s` | `55,977 req/s` | **`1.51x` (`Tier-0`) / `1.49x` (`Tier-1`) vs `Bun.serve`** | -| **Peak Process Memory (`Max RSS` Across Suite)** | **`13.38 – 21.50 MB`** | `27.25 – 40.59 MB` | `45.86 – 61.39 MB` | `69.90 – 92.50 MB` | **`2.0x–2.3x` less than Bun / `4.3x–6.8x` less than Node** | +| **Peak Process Memory (`Max RSS` Across Suite)** | **`13.38 – 21.50 MB`** | `27.25 – 41.00 MB` | `45.47 – 61.39 MB` | `69.90 – 92.50 MB` | **`2.0x–2.3x` less than Bun / `4.3x–6.8x` less than Node** | | **Multi-Tenant Security Containment** | **`5 / 5 PASS`** (OCap+SES+Fuel+DLP) | `0 / 5` (Ambient) | `2 / 5` (Coarse CLI) | `0 / 5` (Ambient) | **Hardware & Language Zero-Trust Isolation** | -#### 2. Real-Life Workload Summary by Domain (All 32 Workloads Aggregated) +#### 2. Real-Life Workload Summary by Domain (All 33 Workloads Aggregated) | Workload Domain & Stack Coverage | Suites | Slice Cold `.cas` Avg (Range) | Slice Warm (`--warm`) Avg | Bun `v1.4.4` Avg | Deno `v2.9.8` Avg | Node.js `v27.0.0-alpha.0.0.0` Avg | Category Speedup vs Bun / Node.js | | :--- | :---: | :---: | :---: | :---: | :---: | :---: | :--- | @@ -35,10 +35,10 @@ | **NPM Ecosystem, AST & Disk I/O (`Apps 02, 03, 06, 07, 08, 20`)**
`semver`, `flatted`, `dlv`/`dset`, `mitt`, 10-Shard JSONL I/O, `Buffer` | `6` | **`11.85 ms`** (`8.04–14.66 ms`) | **`3.87 ms`** | `17.63 ms` | `51.32 ms` | `67.38 ms` | **`1.49x Bun` (`4.55x` Warm) / `5.69x Node`** | | **WinterTC Web Standards, Fetch Mesh & DLP (`Apps 09–14, 17–19`)**
`Request`/`Response`, Static CDN `304`, SSE, Live `fetch`, WebCrypto | `9` | **`15.73 ms`** (`8.35–30.83 ms`) | **`8.25 ms`** | `19.22 ms` | `55.05 ms` | `97.59 ms` | **`1.22x Bun` (`2.33x` Warm) / `6.20x Node`** | | **Realtime WebSockets, Workers & Wasm/TSX (`Apps 15, 21–24`)**
RFC 6455 WS, `worker_threads` + TCP/UDP, Pure-Rust `wasmi` Wasm, TSX SSR | `5` | **`14.43 ms`** (`8.93–21.16 ms`) | **`2.79 ms`** | `28.88 ms` | `64.18 ms` | `87.52 ms` | **`2.00x Bun` (`10.35x` Warm) / `6.07x Node`** | -| **Full-Stack Edge & Node Frameworks (`FW 01–03`)**
`Hono v4.6.20`, `itty-router + UnJS Nitro`, `Express/Polka node:http` | `3` | **`16.85 ms`** (`15.32–18.32 ms`) | **`5.45 ms`** | `25.21 ms` | `50.68 ms` | `90.96 ms` | **`1.50x Bun` (`4.63x` Warm) / `5.40x Node`** | +| **Full-Stack Edge & Node Frameworks (`FW 01–04`)**
`Hono v4.6.20`, `itty-router + UnJS Nitro`, `Express/Polka node:http`, `SvelteKit 3.1.1 + Svelte 5.57.3` | `4` | **`21.84 ms`** (`15.86–36.16 ms`) | **`8.39 ms`** | `33.81 ms` | `60.33 ms` | `101.48 ms` | **`1.55x Bun` (`4.03x` Warm) / `4.65x Node`** | | **AI Agent, Multi-Tenant SaaS & Chaos Case Studies (`CS 01–05`)**
Depth-4 ToT Agent, MCP Code Mode, 12-Tenant Mesh, Wasm CDR, 48 Payment Sagas | `5` | **`19.29 ms`** (`13.98–26.48 ms`) | **`7.87 ms`** | `20.04 ms` | `54.98 ms` | `78.81 ms` | **`1.04x Bun` (`2.55x` Warm) / `4.08x Node`** | -#### 3. Flagship Real-World Representative Workloads (8 of 32 Highlights) +#### 3. Flagship Real-World Representative Workloads (9 of 33 Highlights) | # | Flagship Workload | Slice Cold `.cas` | Slice Warm (`--warm`) | Bun `v1.4.4` | Deno `v2.9.8` | Node.js `v27.0.0-alpha.0.0.0` | Speedup vs Bun / Node.js | | :- | :--- | :---: | :---: | :---: | :---: | :---: | :--- | @@ -47,11 +47,12 @@ | **14** | `14-federated-api-mesh-dlp` (`bytes` + `dlv` + `dset` + Live `fetch`) | **`15.52 ms`** | **`7.87 ms`** | `22.38 ms` | `56.66 ms` | `112.02 ms` | **`1.44x Bun` (`2.84x` Warm) / `7.22x Node`** | | **20** | `20-node-compat-and-edge-router` (`Uint8Array` `Buffer`/Node Core/AST Bundler) | **`11.50 ms`** | **`0.55 ms`** | `22.56 ms` | `55.77 ms` | `71.86 ms` | **`1.96x Bun` (`41.39x` Warm) / `6.25x Node`** | | **22** | `22-worker-threads-and-raw-sockets` (3 Worker Threads + TCP/UDP + 5-Ring Sec) | **`21.52 ms`** | **`2.22 ms`** | `57.85 ms` | `113.39 ms` | `103.24 ms` | **`2.73x Bun` (`26.09x` Warm) / `4.88x Node`** | -| **FW-01** | `FW-01: frameworks/01-hono-edge-microservice` (`hono@4.6.20` + `hono/cookie` + `ms`) | **`15.32 ms`** | **`6.48 ms`** | `20.41 ms` | `54.05 ms` | `96.96 ms` | **`1.33x Bun` (`3.15x` Warm) / `6.33x Node`** | +| **FW-01** | `FW-01: frameworks/01-hono-edge-microservice` (`hono@4.6.20` + `hono/cookie` + `ms`) | **`16.07 ms`** | **`5.72 ms`** | `19.91 ms` | `53.97 ms` | `99.71 ms` | **`1.26x Bun` (`3.48x` Warm) / `6.29x Node`** | +| **FW-04** | `FW-04: frameworks/04-sveltekit-edge-ssr` (`@sveltejs/kit@3.1.1` + `svelte@5.57.3` + `devalue@6.0.3`) | **`36.16 ms`** | **`17.02 ms`** | `46.58 ms` | `71.05 ms` | `119.71 ms` | **`1.29x Bun` (`2.74x` Warm) / `3.31x Node`** | | **CS-01** | `CS-01: case_studies/01-tot-autonomous-sre-agent` (20 ToT Sandboxes) | **`26.48 ms`** | **`13.12 ms`** | `28.26 ms` | `72.65 ms` | `89.71 ms` | **`1.07x Bun` (`2.15x` Warm) / `3.39x Node`** | | **CS-05** | `CS-05: case_studies/05-time-travel-chaos-fuzzer-payments` (48 Payment Sagas) | **`18.13 ms`** | **`10.31 ms`** | `19.62 ms` | `62.94 ms` | `83.70 ms` | **`1.08x Bun` (`1.90x` Warm) / `4.62x Node`** | -*Full 32-workload latency breakdown, standalone binary metrics, peak RSS per app, and historical reports: **[`tests/reports/latest.md`](./tests/reports/latest.md)**.* +*Full 33-workload latency breakdown, standalone binary metrics, peak RSS per app, and historical reports: **[`tests/reports/latest.md`](./tests/reports/latest.md)**.* --- @@ -81,6 +82,9 @@ cargo build --release slice init my-edge-service cd my-edge-service slice run --metrics + +# Or scaffold a full-stack SvelteKit 3 + Svelte 5 SSR application with adapter-slice: +slice init my-sveltekit-app --template=sveltekit ``` This creates: @@ -295,7 +299,7 @@ Single-file scripts and self-contained tests can configure their execution tier, | Command | Description | | :--- | :--- | -| `slice init [dir]` | Scaffold a new TypeScript Edge project with `slice.toml`, `slice.d.ts`, `tsconfig.json`, and `src/index.ts`. | +| `slice init [dir] [--template=sveltekit]` | Scaffold a new TypeScript Edge project (`slice.toml`, `slice.d.ts`, `tsconfig.json`, `src/index.ts`) or full-stack SvelteKit 3 + Svelte 5 SSR project (`--template=sveltekit`). | | `slice run [target] [flags]` | Execute a `.ts`/`.js`/`.tsx`/`.mjs`/`.cjs` file, project folder, or `.cas` archive (`--tier=0\|1\|2`, `--boacas`/`--no-boacas`, `--warm`, `--deterministic=SEED`, `--audit-egress=SECRET`, `--watch`, `--metrics`). | | `slice pack ` | Flatten and pre-compile a module tree (plus optional `--static=DIR` assets) into a 64-byte aligned BLAKE3 `.cas` archive (`SLICEBC\x01` by default). | | `slice compile -o ` | Produce a zero-dependency standalone executable (`SLICEEXE`, embeds `SLICEBC\x01` CAS and optional `--static=DIR` assets). | @@ -313,7 +317,7 @@ Single-file scripts and self-contained tests can configure their execution tier, ## Running the Reproducible Docker Benchmark & Verification Suite -Run the full 32-workload Docker benchmark suite (which automatically writes a timestamped report to [`tests/reports/`](./tests/reports/latest.md) and syncs documentation tables) or filter by tags (`all`, `apps`, `frameworks`, `case_studies`, `n1`, `n2`, `n3`, `f1`, `f2`, `f3`, `f4`, `wasm`, `serve`, `swarm`): +Run the full 33-workload Docker benchmark suite (which automatically writes a timestamped report to [`tests/reports/`](./tests/reports/latest.md) and syncs documentation tables) or filter by tags (`all`, `apps`, `frameworks`, `case_studies`, `n1`, `n2`, `n3`, `f1`, `f2`, `f3`, `f4`, `wasm`, `serve`, `swarm`): ```powershell # Automated one-command runner (builds Docker image, runs benchmarks, generates tests/reports/latest.md, and syncs docs) @@ -340,12 +344,12 @@ cargo test --workspace * **[Chapter 06: AI Agent "Code Mode" Sandbox, `< 5 us` Checkpoints & Native MCP Server (`slice mcp`)](./docs/general/06_ai_agent_sandbox_checkpoints_and_mcp.md)** * **[Chapter 07: Node.js Compatibility (`node:*`), Native Intrinsics & External NPM Packages](./docs/general/07_node_compat_intrinsics_and_npm.md)** * **[Chapter 08: Kernel Completion Rings (`slice-io`) & Embedding Slice in Rust](./docs/general/08_kernel_io_rings_and_rust_embedding.md)** -* **[Chapter 09: Benchmarks, Time-Travel Testing & 31-Workload Docker Verification Suite](./docs/general/09_benchmarks_testing_and_docker_suite.md)** +* **[Chapter 09: Benchmarks, Time-Travel Testing & 33-Workload Docker Verification Suite](./docs/general/09_benchmarks_testing_and_docker_suite.md)** * **[Runtime Compatibility Matrix (`docs/general/COMPATIBILITY.md`)](./docs/general/COMPATIBILITY.md)** ### Developer How-To Guides (`docs/guides/`) * **[Developer Guides & Recipes Index (`docs/guides/README.md`)](./docs/guides/README.md)** -* **[Guide 01: Building & Deploying Hono (`v4`) and UnJS Edge Microservices (`docs/guides/01_hono_and_unjs_edge_microservices.md`)](./docs/guides/01_hono_and_unjs_edge_microservices.md)** +* **[Guide 01: Building & Deploying Hono (`v4`), UnJS, and SvelteKit (`v3`) Edge Microservices (`docs/guides/01_hono_and_unjs_edge_microservices.md`)](./docs/guides/01_hono_and_unjs_edge_microservices.md)** * **[Guide 02: TypeScript IDE Setup (`slice.d.ts`), Linting (`oxlint` / `Biome`), & `.wasm` Modules (`docs/guides/02_typescript_ide_linting_and_wasm.md`)](./docs/guides/02_typescript_ide_linting_and_wasm.md)** ### System Engineering Specifications (`docs/system/`, `vendor/`, & `tests/`) @@ -357,10 +361,10 @@ cargo test --workspace * **[05: Pure-Rust WebAssembly, Web Workers & Direct Kernel I/O (`docs/system/05_wasm_workers_and_kernel_io.md`)](./docs/system/05_wasm_workers_and_kernel_io.md)** * **[06: Serverless Edge KV, AI Agent "Code Mode" & MCP Server (`docs/system/06_edge_kv_ai_sandbox_and_mcp.md`)](./docs/system/06_edge_kv_ai_sandbox_and_mcp.md)** * **[07: Production Tooling & Deployment Guide (`docs/system/07_production_tooling_guide.md`)](./docs/system/07_production_tooling_guide.md)** -* **[08: Empirical Benchmarks & 31-Workload Comparisons (`docs/system/08_benchmarks_and_comparisons.md`)](./docs/system/08_benchmarks_and_comparisons.md)** +* **[08: Empirical Benchmarks & 33-Workload Comparisons (`docs/system/08_benchmarks_and_comparisons.md`)](./docs/system/08_benchmarks_and_comparisons.md)** * **[09: Cutting-Edge 2026 Research Deep Dive (`docs/system/09_research_deep_dive.md`)](./docs/system/09_research_deep_dive.md)** * **[Vendored `boa_engine` `SLICEBC\x01` Patch Specification (`vendor/boa_engine/SLICE_PATCH.md`)](./vendor/boa_engine/SLICE_PATCH.md)** -* **[Latest Full 32-Workload Benchmark Report (`tests/reports/latest.md`)](./tests/reports/latest.md)** -* **[Docker 31-Workload Production Benchmarks (`tests/README.md`)](./tests/README.md)** +* **[Latest Full 33-Workload Benchmark Report (`tests/reports/latest.md`)](./tests/reports/latest.md)** +* **[Docker 33-Workload Production Benchmarks (`tests/README.md`)](./tests/README.md)** * **[Framework Integration Benchmarks (`tests/frameworks/README.md`)](./tests/frameworks/README.md)** * **[Interactive Production Case Studies & Visual Cockpit (`tests/case_studies/README.md`)](./tests/case_studies/README.md)** diff --git a/crates/slice-cas/src/linker/ast_walker.rs b/crates/slice-cas/src/linker/ast_walker.rs index 99fedaf..21d54fa 100644 --- a/crates/slice-cas/src/linker/ast_walker.rs +++ b/crates/slice-cas/src/linker/ast_walker.rs @@ -147,7 +147,22 @@ where walk_expr(&c.consequent, visit); walk_expr(&c.alternate, visit); } - Expression::AssignmentExpression(a) => walk_expr(&a.right, visit), + Expression::AssignmentExpression(a) => { + match &a.left { + oxc::ast::ast::AssignmentTarget::StaticMemberExpression(m) => { + walk_expr(&m.object, visit); + } + oxc::ast::ast::AssignmentTarget::ComputedMemberExpression(m) => { + walk_expr(&m.object, visit); + walk_expr(&m.expression, visit); + } + oxc::ast::ast::AssignmentTarget::PrivateFieldExpression(m) => { + walk_expr(&m.object, visit); + } + _ => {} + } + walk_expr(&a.right, visit); + } Expression::SequenceExpression(seq) => { for e in &seq.expressions { walk_expr(e, visit); @@ -218,8 +233,8 @@ where walk_expr(e, visit); } } - Expression::ChainExpression(ch) => { - if let oxc::ast::ast::ChainElement::CallExpression(call) = &ch.expression { + Expression::ChainExpression(ch) => match &ch.expression { + oxc::ast::ast::ChainElement::CallExpression(call) => { walk_expr(&call.callee, visit); for arg in &call.arguments { if let Some(e) = arg.as_expression() { @@ -227,7 +242,20 @@ where } } } - } + oxc::ast::ast::ChainElement::StaticMemberExpression(m) => { + walk_expr(&m.object, visit); + } + oxc::ast::ast::ChainElement::ComputedMemberExpression(m) => { + walk_expr(&m.object, visit); + walk_expr(&m.expression, visit); + } + oxc::ast::ast::ChainElement::PrivateFieldExpression(m) => { + walk_expr(&m.object, visit); + } + oxc::ast::ast::ChainElement::TSNonNullExpression(n) => { + walk_expr(&n.expression, visit); + } + }, _ => {} } } @@ -620,3 +648,732 @@ pub fn slice_with_edits( out.push_str(&code[cursor..span_end]); out } + +/// Collects all binding identifier names that are reassigned via `AssignmentExpression` +/// (`x = ...`, `x ??= ...`, `({ x } = ...)`, `[x] = ...`) or `UpdateExpression` (`x++`, `--x`) +/// anywhere in `program`. Used to identify mutable ES module live bindings. +pub fn collect_mutated_binding_names( + program: &oxc::ast::ast::Program<'_>, +) -> rustc_hash::FxHashSet { + use oxc::ast::ast::{ + AssignmentTarget, AssignmentTargetMaybeDefault, AssignmentTargetPattern, + AssignmentTargetProperty, Expression, SimpleAssignmentTarget, + }; + + fn collect_target(target: &AssignmentTarget<'_>, out: &mut rustc_hash::FxHashSet) { + match target { + AssignmentTarget::AssignmentTargetIdentifier(id) => { + out.insert(id.name.to_string()); + } + AssignmentTarget::ObjectAssignmentTarget(obj) => { + for prop in &obj.properties { + match prop { + AssignmentTargetProperty::AssignmentTargetPropertyIdentifier(p) => { + out.insert(p.binding.name.to_string()); + } + AssignmentTargetProperty::AssignmentTargetPropertyProperty(p) => { + collect_maybe_default(&p.binding, out); + } + } + } + if let Some(rest) = &obj.rest { + collect_target(&rest.target, out); + } + } + AssignmentTarget::ArrayAssignmentTarget(arr) => { + for el in arr.elements.iter().flatten() { + collect_maybe_default(el, out); + } + if let Some(rest) = &arr.rest { + collect_target(&rest.target, out); + } + } + _ => {} + } + } + + fn collect_maybe_default( + md: &AssignmentTargetMaybeDefault<'_>, + out: &mut rustc_hash::FxHashSet, + ) { + match md { + AssignmentTargetMaybeDefault::AssignmentTargetWithDefault(def) => { + collect_target(&def.binding, out); + } + AssignmentTargetMaybeDefault::AssignmentTargetIdentifier(id) => { + out.insert(id.name.to_string()); + } + AssignmentTargetMaybeDefault::ObjectAssignmentTarget(obj) => { + for prop in &obj.properties { + match prop { + AssignmentTargetProperty::AssignmentTargetPropertyIdentifier(p) => { + out.insert(p.binding.name.to_string()); + } + AssignmentTargetProperty::AssignmentTargetPropertyProperty(p) => { + collect_maybe_default(&p.binding, out); + } + } + } + if let Some(rest) = &obj.rest { + collect_target(&rest.target, out); + } + } + AssignmentTargetMaybeDefault::ArrayAssignmentTarget(arr) => { + for el in arr.elements.iter().flatten() { + collect_maybe_default(el, out); + } + if let Some(rest) = &arr.rest { + collect_target(&rest.target, out); + } + } + _ => {} + } + } + + let _ = AssignmentTargetPattern::ArrayAssignmentTarget; + let mut out = rustc_hash::FxHashSet::default(); + walk_ast_expressions(program, &mut |expr| match expr { + Expression::AssignmentExpression(assign) => { + collect_target(&assign.left, &mut out); + } + Expression::UpdateExpression(upd) => { + if let SimpleAssignmentTarget::AssignmentTargetIdentifier(id) = &upd.argument { + out.insert(id.name.to_string()); + } + } + _ => {} + }); + out +} + +/// Walks `program` while tracking lexical shadowing and emits span replacement edits for any +/// unshadowed reference to a live imported binding in `live_map` (`local_ident -> "__live_N.exp"`). +pub fn collect_live_import_reference_edits( + program: &oxc::ast::ast::Program<'_>, + live_map: &rustc_hash::FxHashMap, + edits: &mut Vec<(usize, usize, String)>, +) { + use oxc::ast::ast::{ + BindingPattern, ChainElement, ClassElement, Declaration, ExportDefaultDeclarationKind, + Expression, ForStatementInit, ForStatementLeft, ObjectPropertyKind, Statement, + }; + use rustc_hash::FxHashSet; + + if live_map.is_empty() { + return; + } + + fn bind_pat(pat: &BindingPattern<'_>, shadowed: &mut FxHashSet) { + let mut names = Vec::new(); + collect_binding_pattern_names(pat, &mut names); + for (n, _) in names { + shadowed.insert(n); + } + } + + fn bind_stmts(stmts: &[Statement<'_>], shadowed: &mut FxHashSet) { + for s in stmts { + match s { + Statement::VariableDeclaration(vd) => { + for d in &vd.declarations { + bind_pat(&d.id, shadowed); + } + } + Statement::FunctionDeclaration(fd) => { + if let Some(id) = &fd.id { + shadowed.insert(id.name.to_string()); + } + } + Statement::ClassDeclaration(cd) => { + if let Some(id) = &cd.id { + shadowed.insert(id.name.to_string()); + } + } + Statement::ExportDeclaration(exp) => match &exp.declaration { + Declaration::VariableDeclaration(vd) => { + for d in &vd.declarations { + bind_pat(&d.id, shadowed); + } + } + Declaration::FunctionDeclaration(fd) => { + if let Some(id) = &fd.id { + shadowed.insert(id.name.to_string()); + } + } + Declaration::ClassDeclaration(cd) => { + if let Some(id) = &cd.id { + shadowed.insert(id.name.to_string()); + } + } + _ => {} + }, + _ => {} + } + } + } + + fn walk_pat( + pat: &BindingPattern<'_>, + shadowed: &FxHashSet, + live_map: &rustc_hash::FxHashMap, + edits: &mut Vec<(usize, usize, String)>, + ) { + match pat { + BindingPattern::ObjectPattern(obj) => { + for p in &obj.properties { + if p.computed { + if let Some(ke) = p.key.as_expression() { + walk_expr(ke, shadowed, live_map, edits); + } + } + walk_pat(&p.value, shadowed, live_map, edits); + } + if let Some(r) = &obj.rest { + walk_pat(&r.argument, shadowed, live_map, edits); + } + } + BindingPattern::ArrayPattern(arr) => { + for el in arr.elements.iter().flatten() { + walk_pat(el, shadowed, live_map, edits); + } + if let Some(r) = &arr.rest { + walk_pat(&r.argument, shadowed, live_map, edits); + } + } + BindingPattern::AssignmentPattern(assign) => { + walk_pat(&assign.left, shadowed, live_map, edits); + walk_expr(&assign.right, shadowed, live_map, edits); + } + BindingPattern::BindingIdentifier(_) => {} + } + } + + fn walk_class( + cls: &oxc::ast::ast::Class<'_>, + shadowed: &FxHashSet, + live_map: &rustc_hash::FxHashMap, + edits: &mut Vec<(usize, usize, String)>, + ) { + for el in &cls.body.body { + match el { + ClassElement::MethodDefinition(md) => { + if md.computed { + if let Some(ke) = md.key.as_expression() { + walk_expr(ke, shadowed, live_map, edits); + } + } + let mut fn_shadow = shadowed.clone(); + for p in &md.value.params.items { + bind_pat(&p.pattern, &mut fn_shadow); + } + if let Some(rest) = &md.value.params.rest { + bind_pat(&rest.rest.argument, &mut fn_shadow); + } + if let Some(body) = &md.value.body { + bind_stmts(&body.statements, &mut fn_shadow); + } + for p in &md.value.params.items { + walk_pat(&p.pattern, &fn_shadow, live_map, edits); + } + if let Some(body) = &md.value.body { + for s in &body.statements { + walk_stmt(s, &fn_shadow, live_map, edits); + } + } + } + ClassElement::PropertyDefinition(pd) => { + if pd.computed { + if let Some(ke) = pd.key.as_expression() { + walk_expr(ke, shadowed, live_map, edits); + } + } + if let Some(v) = &pd.value { + walk_expr(v, shadowed, live_map, edits); + } + } + ClassElement::StaticBlock(sb) => { + let mut blk_shadow = shadowed.clone(); + bind_stmts(&sb.body, &mut blk_shadow); + for s in &sb.body { + walk_stmt(s, &blk_shadow, live_map, edits); + } + } + _ => {} + } + } + } + + fn walk_expr( + expr: &Expression<'_>, + shadowed: &FxHashSet, + live_map: &rustc_hash::FxHashMap, + edits: &mut Vec<(usize, usize, String)>, + ) { + match expr { + Expression::Identifier(id) => { + let name = id.name.as_str(); + if !shadowed.contains(name) { + if let Some(rep) = live_map.get(name) { + edits.push((id.span.start as usize, id.span.end as usize, rep.clone())); + } + } + } + Expression::CallExpression(call) => { + walk_expr(&call.callee, shadowed, live_map, edits); + for arg in &call.arguments { + if let Some(e) = arg.as_expression() { + walk_expr(e, shadowed, live_map, edits); + } + } + } + Expression::ImportExpression(imp) => { + walk_expr(&imp.source, shadowed, live_map, edits); + } + Expression::NewExpression(ne) => { + walk_expr(&ne.callee, shadowed, live_map, edits); + for arg in &ne.arguments { + if let Some(e) = arg.as_expression() { + walk_expr(e, shadowed, live_map, edits); + } + } + } + Expression::StaticMemberExpression(m) => { + walk_expr(&m.object, shadowed, live_map, edits); + } + Expression::ComputedMemberExpression(m) => { + walk_expr(&m.object, shadowed, live_map, edits); + walk_expr(&m.expression, shadowed, live_map, edits); + } + Expression::PrivateFieldExpression(m) => { + walk_expr(&m.object, shadowed, live_map, edits); + } + Expression::BinaryExpression(b) => { + walk_expr(&b.left, shadowed, live_map, edits); + walk_expr(&b.right, shadowed, live_map, edits); + } + Expression::LogicalExpression(l) => { + walk_expr(&l.left, shadowed, live_map, edits); + walk_expr(&l.right, shadowed, live_map, edits); + } + Expression::UnaryExpression(u) => { + walk_expr(&u.argument, shadowed, live_map, edits); + } + Expression::ConditionalExpression(c) => { + walk_expr(&c.test, shadowed, live_map, edits); + walk_expr(&c.consequent, shadowed, live_map, edits); + walk_expr(&c.alternate, shadowed, live_map, edits); + } + Expression::AssignmentExpression(a) => { + match &a.left { + oxc::ast::ast::AssignmentTarget::StaticMemberExpression(m) => { + walk_expr(&m.object, shadowed, live_map, edits); + } + oxc::ast::ast::AssignmentTarget::ComputedMemberExpression(m) => { + walk_expr(&m.object, shadowed, live_map, edits); + walk_expr(&m.expression, shadowed, live_map, edits); + } + oxc::ast::ast::AssignmentTarget::PrivateFieldExpression(m) => { + walk_expr(&m.object, shadowed, live_map, edits); + } + _ => {} + } + walk_expr(&a.right, shadowed, live_map, edits); + } + Expression::SequenceExpression(seq) => { + for e in &seq.expressions { + walk_expr(e, shadowed, live_map, edits); + } + } + Expression::ParenthesizedExpression(p) => { + walk_expr(&p.expression, shadowed, live_map, edits); + } + Expression::AwaitExpression(aw) => { + walk_expr(&aw.argument, shadowed, live_map, edits); + } + Expression::YieldExpression(y) => { + if let Some(arg) = &y.argument { + walk_expr(arg, shadowed, live_map, edits); + } + } + Expression::ArrowFunctionExpression(arrow) => { + let mut fn_shadow = shadowed.clone(); + for p in &arrow.params.items { + bind_pat(&p.pattern, &mut fn_shadow); + } + if let Some(rest) = &arrow.params.rest { + bind_pat(&rest.rest.argument, &mut fn_shadow); + } + if let oxc::ast::ast::ArrowFunctionBody::FunctionBody(fb) = &arrow.body { + bind_stmts(&fb.statements, &mut fn_shadow); + } + for p in &arrow.params.items { + walk_pat(&p.pattern, &fn_shadow, live_map, edits); + } + if let oxc::ast::ast::ArrowFunctionBody::FunctionBody(fb) = &arrow.body { + for s in &fb.statements { + walk_stmt(s, &fn_shadow, live_map, edits); + } + } else if let Some(e) = arrow.body.as_expression() { + walk_expr(e, &fn_shadow, live_map, edits); + } + } + Expression::FunctionExpression(fe) => { + let mut fn_shadow = shadowed.clone(); + if let Some(id) = &fe.id { + fn_shadow.insert(id.name.to_string()); + } + for p in &fe.params.items { + bind_pat(&p.pattern, &mut fn_shadow); + } + if let Some(rest) = &fe.params.rest { + bind_pat(&rest.rest.argument, &mut fn_shadow); + } + if let Some(body) = &fe.body { + bind_stmts(&body.statements, &mut fn_shadow); + } + for p in &fe.params.items { + walk_pat(&p.pattern, &fn_shadow, live_map, edits); + } + if let Some(body) = &fe.body { + for s in &body.statements { + walk_stmt(s, &fn_shadow, live_map, edits); + } + } + } + Expression::ClassExpression(ce) => walk_class(ce, shadowed, live_map, edits), + Expression::ObjectExpression(obj) => { + for prop in &obj.properties { + match prop { + ObjectPropertyKind::ObjectProperty(p) => { + if p.shorthand { + if let Expression::Identifier(id) = &p.value { + let name = id.name.as_str(); + if !shadowed.contains(name) { + if let Some(rep) = live_map.get(name) { + edits.push(( + p.span.start as usize, + p.span.end as usize, + format!("{}: {}", name, rep), + )); + continue; + } + } + } + } + if p.computed { + if let Some(ke) = p.key.as_expression() { + walk_expr(ke, shadowed, live_map, edits); + } + } + walk_expr(&p.value, shadowed, live_map, edits); + } + ObjectPropertyKind::SpreadProperty(sp) => { + walk_expr(&sp.argument, shadowed, live_map, edits); + } + } + } + } + Expression::ArrayExpression(arr) => { + for el in &arr.elements { + if let Some(e) = el.as_expression() { + walk_expr(e, shadowed, live_map, edits); + } else if let oxc::ast::ast::ArrayExpressionElement::SpreadElement(sp) = el { + walk_expr(&sp.argument, shadowed, live_map, edits); + } + } + } + Expression::TemplateLiteral(tpl) => { + for e in &tpl.expressions { + walk_expr(e, shadowed, live_map, edits); + } + } + Expression::TaggedTemplateExpression(tt) => { + walk_expr(&tt.tag, shadowed, live_map, edits); + for e in &tt.quasi.expressions { + walk_expr(e, shadowed, live_map, edits); + } + } + Expression::ChainExpression(ch) => match &ch.expression { + ChainElement::CallExpression(call) => { + walk_expr(&call.callee, shadowed, live_map, edits); + for arg in &call.arguments { + if let Some(e) = arg.as_expression() { + walk_expr(e, shadowed, live_map, edits); + } + } + } + ChainElement::StaticMemberExpression(m) => { + walk_expr(&m.object, shadowed, live_map, edits); + } + ChainElement::ComputedMemberExpression(m) => { + walk_expr(&m.object, shadowed, live_map, edits); + walk_expr(&m.expression, shadowed, live_map, edits); + } + ChainElement::PrivateFieldExpression(m) => { + walk_expr(&m.object, shadowed, live_map, edits); + } + ChainElement::TSNonNullExpression(n) => { + walk_expr(&n.expression, shadowed, live_map, edits); + } + }, + _ => {} + } + } + + fn walk_decl( + decl: &Declaration<'_>, + shadowed: &FxHashSet, + live_map: &rustc_hash::FxHashMap, + edits: &mut Vec<(usize, usize, String)>, + ) { + match decl { + Declaration::VariableDeclaration(vd) => { + for d in &vd.declarations { + walk_pat(&d.id, shadowed, live_map, edits); + if let Some(init) = &d.init { + walk_expr(init, shadowed, live_map, edits); + } + } + } + Declaration::FunctionDeclaration(fd) => { + let mut fn_shadow = shadowed.clone(); + if let Some(id) = &fd.id { + fn_shadow.insert(id.name.to_string()); + } + for p in &fd.params.items { + bind_pat(&p.pattern, &mut fn_shadow); + } + if let Some(rest) = &fd.params.rest { + bind_pat(&rest.rest.argument, &mut fn_shadow); + } + if let Some(body) = &fd.body { + bind_stmts(&body.statements, &mut fn_shadow); + } + for p in &fd.params.items { + walk_pat(&p.pattern, &fn_shadow, live_map, edits); + } + if let Some(body) = &fd.body { + for s in &body.statements { + walk_stmt(s, &fn_shadow, live_map, edits); + } + } + } + Declaration::ClassDeclaration(cd) => walk_class(cd, shadowed, live_map, edits), + _ => {} + } + } + + fn walk_stmt( + stmt: &Statement<'_>, + shadowed: &FxHashSet, + live_map: &rustc_hash::FxHashMap, + edits: &mut Vec<(usize, usize, String)>, + ) { + match stmt { + Statement::VariableDeclaration(vd) => { + for d in &vd.declarations { + walk_pat(&d.id, shadowed, live_map, edits); + if let Some(init) = &d.init { + walk_expr(init, shadowed, live_map, edits); + } + } + } + Statement::FunctionDeclaration(fd) => { + let mut fn_shadow = shadowed.clone(); + if let Some(id) = &fd.id { + fn_shadow.insert(id.name.to_string()); + } + for p in &fd.params.items { + bind_pat(&p.pattern, &mut fn_shadow); + } + if let Some(rest) = &fd.params.rest { + bind_pat(&rest.rest.argument, &mut fn_shadow); + } + if let Some(body) = &fd.body { + bind_stmts(&body.statements, &mut fn_shadow); + } + for p in &fd.params.items { + walk_pat(&p.pattern, &fn_shadow, live_map, edits); + } + if let Some(body) = &fd.body { + for s in &body.statements { + walk_stmt(s, &fn_shadow, live_map, edits); + } + } + } + Statement::ClassDeclaration(cd) => walk_class(cd, shadowed, live_map, edits), + Statement::ExpressionStatement(es) => { + walk_expr(&es.expression, shadowed, live_map, edits); + } + Statement::BlockStatement(bs) => { + let mut blk_shadow = shadowed.clone(); + bind_stmts(&bs.body, &mut blk_shadow); + for s in &bs.body { + walk_stmt(s, &blk_shadow, live_map, edits); + } + } + Statement::ReturnStatement(rs) => { + if let Some(arg) = &rs.argument { + walk_expr(arg, shadowed, live_map, edits); + } + } + Statement::ThrowStatement(ts) => { + walk_expr(&ts.argument, shadowed, live_map, edits); + } + Statement::IfStatement(ifs) => { + walk_expr(&ifs.test, shadowed, live_map, edits); + walk_stmt(&ifs.consequent, shadowed, live_map, edits); + if let Some(alt) = &ifs.alternate { + walk_stmt(alt, shadowed, live_map, edits); + } + } + Statement::SwitchStatement(sw) => { + walk_expr(&sw.discriminant, shadowed, live_map, edits); + let mut sw_shadow = shadowed.clone(); + for c in &sw.cases { + bind_stmts(&c.consequent, &mut sw_shadow); + } + for c in &sw.cases { + if let Some(t) = &c.test { + walk_expr(t, &sw_shadow, live_map, edits); + } + for s in &c.consequent { + walk_stmt(s, &sw_shadow, live_map, edits); + } + } + } + Statement::ForStatement(fs) => { + let mut for_shadow = shadowed.clone(); + if let Some(ForStatementInit::VariableDeclaration(vd)) = &fs.init { + for d in &vd.declarations { + bind_pat(&d.id, &mut for_shadow); + } + } + if let Some(init) = &fs.init { + match init { + ForStatementInit::VariableDeclaration(vd) => { + for d in &vd.declarations { + walk_pat(&d.id, &for_shadow, live_map, edits); + if let Some(e) = &d.init { + walk_expr(e, &for_shadow, live_map, edits); + } + } + } + _ => { + if let Some(e) = init.as_expression() { + walk_expr(e, &for_shadow, live_map, edits); + } + } + } + } + if let Some(t) = &fs.test { + walk_expr(t, &for_shadow, live_map, edits); + } + if let Some(u) = &fs.update { + walk_expr(u, &for_shadow, live_map, edits); + } + walk_stmt(&fs.body, &for_shadow, live_map, edits); + } + Statement::ForInStatement(fi) => { + let mut for_shadow = shadowed.clone(); + if let ForStatementLeft::VariableDeclaration(vd) = &fi.left { + for d in &vd.declarations { + bind_pat(&d.id, &mut for_shadow); + } + } + walk_expr(&fi.right, shadowed, live_map, edits); + walk_stmt(&fi.body, &for_shadow, live_map, edits); + } + Statement::ForOfStatement(fo) => { + let mut for_shadow = shadowed.clone(); + if let ForStatementLeft::VariableDeclaration(vd) = &fo.left { + for d in &vd.declarations { + bind_pat(&d.id, &mut for_shadow); + } + } + walk_expr(&fo.right, shadowed, live_map, edits); + walk_stmt(&fo.body, &for_shadow, live_map, edits); + } + Statement::WhileStatement(ws) => { + walk_expr(&ws.test, shadowed, live_map, edits); + walk_stmt(&ws.body, shadowed, live_map, edits); + } + Statement::DoWhileStatement(dw) => { + walk_stmt(&dw.body, shadowed, live_map, edits); + walk_expr(&dw.test, shadowed, live_map, edits); + } + Statement::TryStatement(ts) => { + let mut try_shadow = shadowed.clone(); + bind_stmts(&ts.block.body, &mut try_shadow); + for s in &ts.block.body { + walk_stmt(s, &try_shadow, live_map, edits); + } + if let Some(h) = &ts.handler { + let mut catch_shadow = shadowed.clone(); + if let Some(p) = &h.param { + bind_pat(&p.pattern, &mut catch_shadow); + } + bind_stmts(&h.body.body, &mut catch_shadow); + if let Some(p) = &h.param { + walk_pat(&p.pattern, &catch_shadow, live_map, edits); + } + for s in &h.body.body { + walk_stmt(s, &catch_shadow, live_map, edits); + } + } + if let Some(f) = &ts.finalizer { + let mut fin_shadow = shadowed.clone(); + bind_stmts(&f.body, &mut fin_shadow); + for s in &f.body { + walk_stmt(s, &fin_shadow, live_map, edits); + } + } + } + Statement::LabeledStatement(ls) => walk_stmt(&ls.body, shadowed, live_map, edits), + Statement::ExportDeclaration(exp) => { + walk_decl(&exp.declaration, shadowed, live_map, edits); + } + Statement::ExportDefaultDeclaration(exp) => match &exp.declaration { + ExportDefaultDeclarationKind::FunctionDeclaration(fd) => { + let mut fn_shadow = shadowed.clone(); + if let Some(id) = &fd.id { + fn_shadow.insert(id.name.to_string()); + } + for p in &fd.params.items { + bind_pat(&p.pattern, &mut fn_shadow); + } + if let Some(rest) = &fd.params.rest { + bind_pat(&rest.rest.argument, &mut fn_shadow); + } + if let Some(body) = &fd.body { + bind_stmts(&body.statements, &mut fn_shadow); + } + for p in &fd.params.items { + walk_pat(&p.pattern, &fn_shadow, live_map, edits); + } + if let Some(body) = &fd.body { + for s in &body.statements { + walk_stmt(s, &fn_shadow, live_map, edits); + } + } + } + ExportDefaultDeclarationKind::ClassDeclaration(cd) => { + walk_class(cd, shadowed, live_map, edits); + } + other => { + if let Some(e) = other.as_expression() { + walk_expr(e, shadowed, live_map, edits); + } + } + }, + _ => {} + } + } + + let mut top_shadow = FxHashSet::default(); + bind_stmts(&program.body, &mut top_shadow); + for stmt in &program.body { + walk_stmt(stmt, &top_shadow, live_map, edits); + } +} + diff --git a/crates/slice-cas/src/linker/builtins_and_ids.rs b/crates/slice-cas/src/linker/builtins_and_ids.rs index 5378896..5be5735 100644 --- a/crates/slice-cas/src/linker/builtins_and_ids.rs +++ b/crates/slice-cas/src/linker/builtins_and_ids.rs @@ -1,7 +1,7 @@ //! Built-in Module Classifier, Canonical Module ID Cache, and Identifier Sanitizer. use crate::bundler::resolve_module_specifier; -use rustc_hash::FxHashMap; +use rustc_hash::{FxHashMap, FxHashSet}; use std::path::{Path, PathBuf}; #[inline] @@ -112,10 +112,13 @@ pub fn format_exports_lhs(export_name: &str) -> String { thread_local! { static CANONICAL_MOD_ID_CACHE: std::cell::RefCell> = std::cell::RefCell::new(FxHashMap::default()); + pub(crate) static MUTABLE_EXPORTS_CACHE: std::cell::RefCell>> = + std::cell::RefCell::new(FxHashMap::default()); } pub fn clear_canonical_mod_id_cache() { CANONICAL_MOD_ID_CACHE.with(|c| c.borrow_mut().clear()); + MUTABLE_EXPORTS_CACHE.with(|c| c.borrow_mut().clear()); } #[inline] diff --git a/crates/slice-cas/src/linker/esm_transform.rs b/crates/slice-cas/src/linker/esm_transform.rs index 6dd16ad..2260d72 100644 --- a/crates/slice-cas/src/linker/esm_transform.rs +++ b/crates/slice-cas/src/linker/esm_transform.rs @@ -1,13 +1,111 @@ //! Oxc AST-Driven ESM-to-CommonJS Transformer (`transform_module_to_cjs`) //! and Barrel Lazy-Getter Optimizer (`apply_cjs_lazy_barrel_getters`). +use crate::bundler::resolve_module_specifier; +use crate::compiler::strip_typescript_raw_with_ext; +use crate::linker::builtins_and_ids::MUTABLE_EXPORTS_CACHE; use crate::linker::{ - collect_binding_pattern_names, collect_require_edits_from_program, format_exports_lhs, - is_valid_js_identifier, resolve_spec_and_record, rewrite_cjs_requires_ast, slice_with_edits, + collect_binding_pattern_names, collect_live_import_reference_edits, + collect_mutated_binding_names, collect_require_edits_from_program, format_exports_lhs, + is_builtin_module, is_jsx_runtime_builtin, is_valid_js_identifier, resolve_spec_and_record, + rewrite_cjs_requires_ast, slice_with_edits, }; use rustc_hash::{FxHashMap, FxHashSet}; use std::path::{Path, PathBuf}; +fn get_module_mutable_exports(path: &Path) -> FxHashSet { + if let Some(cached) = MUTABLE_EXPORTS_CACHE.with(|c| c.borrow().get(path).cloned()) { + return cached; + } + // Insert empty sentinel first to break any cyclic `export ... from` chains + MUTABLE_EXPORTS_CACHE.with(|c| { + c.borrow_mut() + .insert(path.to_path_buf(), FxHashSet::default()); + }); + + let ext = path.extension().and_then(|e| e.to_str()).unwrap_or(""); + if matches!(ext, "json" | "wasm") { + return FxHashSet::default(); + } + let Ok(raw_src) = std::fs::read_to_string(path) else { + return FxHashSet::default(); + }; + if !raw_src.contains("export") { + return FxHashSet::default(); + } + + let is_ts = matches!(ext, "ts" | "tsx" | "jsx"); + let is_jsx_ext = matches!(ext, "tsx" | "jsx"); + let js_code = strip_typescript_raw_with_ext(&raw_src, is_ts, is_jsx_ext); + + let allocator = oxc::allocator::Allocator::default(); + let source_type = oxc::span::SourceType::ts().with_module(true); + let parser_ret = oxc::parser::Parser::new(&allocator, &js_code, source_type).parse(); + if !parser_ret.diagnostics.is_empty() { + return FxHashSet::default(); + } + + let mutated_locals = collect_mutated_binding_names(&parser_ret.program); + let mut mutable_exported_names = FxHashSet::default(); + let from_dir = path.parent().unwrap_or_else(|| Path::new(".")); + + use oxc::ast::ast::{Declaration, Statement}; + for stmt in &parser_ret.program.body { + match stmt { + Statement::ExportDeclaration(exp_decl) if !mutated_locals.is_empty() => { + if let Declaration::VariableDeclaration(vd) = &exp_decl.declaration { + let mut pairs = Vec::new(); + for d in &vd.declarations { + collect_binding_pattern_names(&d.id, &mut pairs); + } + for (exp_n, loc_n) in pairs { + if mutated_locals.contains(&loc_n) { + mutable_exported_names.insert(exp_n); + } + } + } + } + Statement::ExportNamedDeclaration(exp_named) + if !mutated_locals.is_empty() && !exp_named.export_kind.is_type() => + { + for spec in &exp_named.specifiers { + if spec.export_kind.is_type() { + continue; + } + let loc_n = spec.local.name().as_str(); + if mutated_locals.contains(loc_n) { + mutable_exported_names.insert(spec.exported.name().to_string()); + } + } + } + Statement::ExportFromDeclaration(exp_from) if !exp_from.export_kind.is_type() => { + let spec_str = exp_from.source.value.as_str(); + if !is_builtin_module(spec_str) && !is_jsx_runtime_builtin(spec_str) { + if let Some(inner_path) = resolve_module_specifier(from_dir, spec_str) { + let inner_mut = get_module_mutable_exports(&inner_path); + if !inner_mut.is_empty() { + for spec in &exp_from.specifiers { + if !spec.export_kind.is_type() + && inner_mut.contains(spec.local.name().as_str()) + { + mutable_exported_names.insert(spec.exported.name().to_string()); + } + } + } + } + } + } + _ => {} + } + } + + MUTABLE_EXPORTS_CACHE.with(|c| { + c.borrow_mut() + .insert(path.to_path_buf(), mutable_exported_names.clone()); + }); + mutable_exported_names +} + fn collapse_multiline_imports_exports(code: &str) -> String { let mut out = String::with_capacity(code.len()); let mut in_stmt = false; @@ -141,7 +239,7 @@ fn try_transform_esm_to_cjs_ast( } // Single-pass `require(...)`, dynamic `import(...)`, and `import.meta` AST edit collection: - let req_edits = collect_require_edits_from_program( + let mut req_edits = collect_require_edits_from_program( js_code, &parser_ret.program, from_dir, @@ -173,6 +271,68 @@ fn try_transform_esm_to_cjs_ast( return Some(apply_cjs_lazy_barrel_getters(body_lines).join("\n")); } + // Detect any imported bindings that point to mutable ESM live bindings in their source module: + let mut live_import_map: FxHashMap = FxHashMap::default(); + let mut live_var_by_stmt_start: FxHashMap = FxHashMap::default(); + let mut live_counter = 0usize; + for stmt in &parser_ret.program.body { + let Statement::ImportDeclaration(imp) = stmt else { + continue; + }; + if imp.import_kind.is_type() { + continue; + } + let Some(specs) = &imp.specifiers else { + continue; + }; + let has_named = specs + .iter() + .any(|s| matches!(s, ImportDeclarationSpecifier::ImportSpecifier(n) if !n.import_kind.is_type())); + if !has_named { + continue; + } + let spec = imp.source.value.as_str(); + if is_builtin_module(spec) || is_jsx_runtime_builtin(spec) { + continue; + } + let Some(dep_path) = resolve_module_specifier(from_dir, spec) else { + continue; + }; + let mut_exports = get_module_mutable_exports(&dep_path); + if mut_exports.is_empty() { + continue; + } + let mut live_var: Option = None; + for s in specs { + if let ImportDeclarationSpecifier::ImportSpecifier(named) = s { + if named.import_kind.is_type() { + continue; + } + let imp_n = named.imported.name().as_str(); + if mut_exports.contains(imp_n) { + let var_name = live_var.get_or_insert_with(|| { + live_counter += 1; + format!("__live_{}", live_counter) + }); + let access = if is_valid_js_identifier(imp_n) { + format!("{}.{}", var_name, imp_n) + } else { + format!("{}[{:?}]", var_name, imp_n) + }; + live_import_map.insert(named.local.name.to_string(), access); + } + } + } + if let Some(var_name) = live_var { + live_var_by_stmt_start.insert(imp.span.start, var_name); + } + } + + if !live_import_map.is_empty() { + collect_live_import_reference_edits(&parser_ret.program, &live_import_map, &mut req_edits); + req_edits.sort_by_key(|e| e.0); + } + let mut body_lines = Vec::with_capacity(parser_ret.program.body.len() + 4); let mut deferred_exports: Vec<(String, String)> = Vec::new(); let mut has_default_export = false; @@ -194,6 +354,9 @@ fn try_transform_esm_to_cjs_ast( body_lines.push(format!("require({:?});", resolved_id)); continue; } + if let Some(live_var) = live_var_by_stmt_start.get(&imp.span.start) { + body_lines.push(format!("const {} = require({:?});", live_var, resolved_id)); + } let mut default_ident: Option<&str> = None; let mut namespace_ident: Option<&str> = None; let mut named_specs: Vec<(String, String)> = Vec::new(); @@ -210,9 +373,13 @@ fn try_transform_esm_to_cjs_ast( if named.import_kind.is_type() { continue; } + let loc_s = named.local.name.as_str(); + if live_import_map.contains_key(loc_s) { + continue; + } named_specs.push(( named.imported.name().to_string(), - named.local.name.to_string(), + loc_s.to_string(), )); } } @@ -460,9 +627,21 @@ fn try_transform_esm_to_cjs_ast( if has_default_export || !deferred_exports.is_empty() { body_lines.push("exports.__esModule = true;".to_string()); } + let mutated_locals = if deferred_exports.is_empty() { + FxHashSet::default() + } else { + collect_mutated_binding_names(&parser_ret.program) + }; for (export_name, local_name) in &deferred_exports { - let lhs = format_exports_lhs(export_name); - body_lines.push(format!("{} = {};", lhs, local_name)); + if is_valid_js_identifier(local_name) && mutated_locals.contains(local_name) { + body_lines.push(format!( + "Object.defineProperty(exports, {:?}, {{ enumerable: true, get: function() {{ return {}; }} }});", + export_name, local_name + )); + } else { + let lhs = format_exports_lhs(export_name); + body_lines.push(format!("{} = {};", lhs, local_name)); + } } if has_default_export { body_lines.push("exports.default = __slice_default;".to_string()); diff --git a/crates/slice-cas/src/linker/mod.rs b/crates/slice-cas/src/linker/mod.rs index 70ba3cd..751f65b 100644 --- a/crates/slice-cas/src/linker/mod.rs +++ b/crates/slice-cas/src/linker/mod.rs @@ -17,7 +17,8 @@ pub mod lazy_and_inline; pub mod tree_shaker; pub use ast_walker::{ - collect_binding_pattern_names, has_top_level_await, slice_with_edits, + collect_binding_pattern_names, collect_live_import_reference_edits, + collect_mutated_binding_names, has_top_level_await, slice_with_edits, walk_ast_call_expressions, walk_ast_expressions, wrap_top_level_await_script, }; pub use builtins_and_ids::{ diff --git a/crates/slice-cli/src/commands/init.rs b/crates/slice-cli/src/commands/init.rs index 11b8237..5bcccd6 100644 --- a/crates/slice-cli/src/commands/init.rs +++ b/crates/slice-cli/src/commands/init.rs @@ -242,12 +242,315 @@ pub(crate) const DEFAULT_TSCONFIG_JSON: &str = r#"{ } "#; -pub(crate) fn cmd_init(args: &[String]) -> Result<()> { - let target_dir = if args.is_empty() { - PathBuf::from(".") - } else { - PathBuf::from(&args[0]) +pub(crate) const SVELTEKIT_ADAPTER_SLICE_JS: &str = r#"import fs from 'node:fs'; +import path from 'node:path'; + +/** + * @sveltejs/kit Adapter for Slice Runtime (`@slicevm/adapter-sveltekit`) + * Supports SvelteKit 3 (`generateServerInstance`) and SvelteKit 2 (`generateManifest`). + * Emits: + * - `build/client/` (static assets & immutable client chunks for `--static`) + * - `build/server/` (SvelteKit SSR server chunks + server instance) + * - `build/slice-entry.js` (WinterTC `export default { fetch }` entrypoint) + */ +export default function adapterSlice(options = {}) { + const out = options.out || 'build'; + return { + name: '@slicevm/adapter-sveltekit', + async adapt(builder) { + const tmp = builder.getBuildDirectory('adapter-slice'); + builder.rimraf(out); + builder.rimraf(tmp); + builder.mkdirp(tmp); + builder.mkdirp(`${out}/client`); + builder.mkdirp(`${out}/server`); + + builder.writeClient(`${out}/client`); + builder.writePrerendered(`${out}/client`); + builder.copy(builder.getServerDirectory(), `${out}/server`); + + let entryHeader; + if (typeof builder.generateServerInstance === 'function') { + builder.generateServerInstance(`${out}/server/instance.js`, { + serverDirectory: `${out}/server` + }); + entryHeader = `import { server } from './server/instance.js';\n`; + } else { + const manifestStr = builder.generateManifest({ relativePath: '.' }); + fs.writeFileSync( + `${out}/server/manifest.js`, + `export const manifest = ${manifestStr};\n` + ); + entryHeader = `import { Server } from './server/index.js';\nimport { manifest } from './server/manifest.js';\nconst server = new Server(manifest);\n`; + } + + const entryCode = `${entryHeader} +let initPromise = null; + +export default { + async fetch(request, env, ctx) { + if (!initPromise) { + initPromise = server.init({ env: env || (typeof process !== 'undefined' && process.env) || {} }); + } + await initPromise; + return await server.respond(request, { + getClientAddress() { + return request.headers.get('x-forwarded-for') || '127.0.0.1'; + }, + platform: { + env, + ctx, + Slice: typeof Slice !== 'undefined' ? Slice : undefined + } + }); + } +}; +`; + fs.writeFileSync(path.join(out, 'slice-entry.js'), entryCode); + builder.log.minor(`Wrote Slice WinterTC entrypoint to ${out}/slice-entry.js and client assets to ${out}/client`); + } + }; +} +"#; + +fn init_sveltekit_template(target_dir: &std::path::Path, project_name: &str) -> Result<()> { + std::fs::create_dir_all(target_dir.join("src").join("routes").join("api").join("items"))?; + + let manifest_path = target_dir.join("slice.toml"); + if !manifest_path.exists() { + let toml_content = format!( + r#"[project] +name = "{project_name}" +version = "0.1.0" +entrypoint = "./build/slice-entry.js" +static_dir = "./build/client" + +[runtime] +fuel_limit = 50_000_000 +memory_limit_mb = 64 + +[capabilities] +allow_env = ["NODE_ENV", "ORIGIN", "PORT"] +"# + ); + std::fs::write(&manifest_path, toml_content)?; + } + + let dts_path = target_dir.join("slice.d.ts"); + if !dts_path.exists() { + std::fs::write(&dts_path, DEFAULT_SLICE_D_TS)?; + } + + let pkg_path = target_dir.join("package.json"); + if !pkg_path.exists() { + let pkg_json = format!( + r#"{{ + "name": "{project_name}", + "version": "0.1.0", + "private": true, + "type": "module", + "scripts": {{ + "dev": "vite dev", + "build": "vite build", + "pack": "slice pack ./build/slice-entry.js ./build/app.cas --static=./build/client", + "serve": "slice serve ./build/app.cas" + }}, + "devDependencies": {{ + "@sveltejs/kit": "^3.1.1", + "@sveltejs/vite-plugin-svelte": "^7.3.1", + "svelte": "^5.57.3", + "vite": "^8.3.7" + }} +}} +"# + ); + std::fs::write(&pkg_path, pkg_json)?; + } + + let adapter_path = target_dir.join("adapter-slice.js"); + if !adapter_path.exists() { + std::fs::write(&adapter_path, SVELTEKIT_ADAPTER_SLICE_JS)?; + } + + let vite_cfg_path = target_dir.join("vite.config.js"); + if !vite_cfg_path.exists() { + let vite_cfg = r#"import { sveltekit } from '@sveltejs/kit/vite'; +import { defineConfig } from 'vite'; +import adapterSlice from './adapter-slice.js'; + +export default defineConfig({ + plugins: [ + sveltekit({ + adapter: adapterSlice({ out: 'build' }) + }) + ] +}); +"#; + std::fs::write(&vite_cfg_path, vite_cfg)?; + } + + let app_html_path = target_dir.join("src").join("app.html"); + if !app_html_path.exists() { + let app_html = r#" + + + + + SvelteKit on Slice Runtime + %sveltekit.head% + + +
%sveltekit.body%
+ + +"#; + std::fs::write(&app_html_path, app_html)?; + } + + let hooks_path = target_dir.join("src").join("hooks.server.js"); + if !hooks_path.exists() { + let hooks_js = r#"/** @type {import('@sveltejs/kit').Handle} */ +export async function handle({ event, resolve }) { + event.locals.requestId = 'req-slice-edge'; + const response = await resolve(event); + response.headers.set('x-powered-by', 'SvelteKit-on-Slice'); + return response; +} + +/** @type {import('@sveltejs/kit').HandleServerError} */ +export function handleError({ status, error }) { + if (status !== 404 && error?.status !== 404) { + console.error(error); + } +} +"#; + std::fs::write(&hooks_path, hooks_js)?; + } + + let page_srv_path = target_dir.join("src").join("routes").join("+page.server.js"); + if !page_srv_path.exists() { + let page_srv = r#"/** @type {import('./$types').PageServerLoad} */ +export async function load({ url, cookies, locals }) { + const visitor = url.searchParams.get('name') || 'Edge Developer'; + const theme = cookies.get('theme') || 'light'; + const hits = typeof Slice !== 'undefined' && Slice.kv + ? Slice.kv.incr('sveltekit_page_views', 1) + : 1; + + return { + title: 'SvelteKit 3 + Svelte 5 SSR on Slice', + visitor, + theme, + requestId: locals.requestId || 'none', + hits, + runtime: 'Slice WinterTC Isolate' }; +} + +/** @type {import('./$types').Actions} */ +export const actions = { + setTheme: async ({ request, cookies }) => { + const form = await request.formData(); + const theme = String(form.get('theme') || 'dark'); + cookies.set('theme', theme, { path: '/', httpOnly: true }); + return { success: true, theme }; + } +}; +"#; + std::fs::write(&page_srv_path, page_srv)?; + } + + let page_svelte_path = target_dir.join("src").join("routes").join("+page.svelte"); + if !page_svelte_path.exists() { + let page_svelte = r#" + +
+

{data.title}

+

Hello, {data.visitor}!

+

Runtime: {data.runtime} | Request ID: {data.requestId} | Theme: {data.theme} | KV Page Views: {data.hits}

+ {#if form?.success} +

Updated theme to: {form.theme}

+ {/if} +
+"#; + std::fs::write(&page_svelte_path, page_svelte)?; + } + + let api_srv_path = target_dir + .join("src") + .join("routes") + .join("api") + .join("items") + .join("+server.js"); + if !api_srv_path.exists() { + let api_srv = r#"import { json } from '@sveltejs/kit'; + +/** @type {import('./$types').RequestHandler} */ +export async function GET({ url }) { + const tag = url.searchParams.get('tag') || 'all'; + const count = typeof Slice !== 'undefined' && Slice.kv + ? Slice.kv.incr('sveltekit_api_calls', 1) + : 1; + + return json({ + ok: true, + framework: 'SvelteKit', + tag, + count, + items: ['slice-cas', 'slice-engine', 'slice-sandbox'] + }); +} + +/** @type {import('./$types').RequestHandler} */ +export async function POST({ request }) { + const body = await request.json(); + return json({ + created: true, + received: body + }, { status: 201 }); +} +"#; + std::fs::write(&api_srv_path, api_srv)?; + } + + println!( + "Initialized Slice SvelteKit (SvelteKit 3 + Svelte 5) project '{}' in {}", + project_name, + target_dir.display() + ); + println!(" Created {}", manifest_path.display()); + println!(" Created {}", pkg_path.display()); + println!(" Created {}", adapter_path.display()); + println!(" Created {}", vite_cfg_path.display()); + println!(" Created {}", page_svelte_path.display()); + println!(" Created {}", api_srv_path.display()); + println!("Next steps:"); + println!(" npm install && npm run build"); + println!(" slice pack ./build/slice-entry.js ./build/app.cas --static=./build/client"); + println!(" slice serve ./build/app.cas --port=3000"); + Ok(()) +} + +pub(crate) fn cmd_init(args: &[String]) -> Result<()> { + let mut target_dir = PathBuf::from("."); + let mut template = String::from("default"); + let mut dir_set = false; + let mut i = 0; + while i < args.len() { + let arg = &args[i]; + if let Some(t) = arg.strip_prefix("--template=") { + template = t.to_ascii_lowercase(); + } else if (arg == "--template" || arg == "-t") && i + 1 < args.len() { + template = args[i + 1].to_ascii_lowercase(); + i += 1; + } else if !arg.starts_with('-') && !dir_set { + target_dir = PathBuf::from(arg); + dir_set = true; + } + i += 1; + } std::fs::create_dir_all(target_dir.join("src"))?; let project_name = target_dir @@ -255,6 +558,10 @@ pub(crate) fn cmd_init(args: &[String]) -> Result<()> { .and_then(|s| s.to_str()) .unwrap_or("slice-edge-app"); + if template == "sveltekit" || template == "svelte" { + return init_sveltekit_template(&target_dir, project_name); + } + let manifest_path = target_dir.join("slice.toml"); if !manifest_path.exists() { std::fs::write( diff --git a/crates/slice-cli/src/commands/pack_and_compile.rs b/crates/slice-cli/src/commands/pack_and_compile.rs index ed454c1..ae6aaf2 100644 --- a/crates/slice-cli/src/commands/pack_and_compile.rs +++ b/crates/slice-cli/src/commands/pack_and_compile.rs @@ -39,7 +39,7 @@ pub(crate) fn print_usage() { ); println!(); println!("Core Commands:"); - println!(" slice init [dir] Scaffold a new TypeScript Edge project with slice.toml"); + println!(" slice init [dir] [--template=sveltekit] Scaffold a new TypeScript Edge or SvelteKit 2 project"); println!(" slice run [target] [--warm] [--watch] Execute a script, folder app, .cas bundle, or slice.toml"); println!(" slice test [target] [--filter=PAT] [--json] Run Time-Travel Test Suite (< 5us VFS+KV rollback per test)"); println!(" slice serve [target] [--port=N] [--smoke-test] Launch multi-tenant WinterTC HTTP MicroVM server"); diff --git a/crates/slice-cli/tests/frameworks_wasm_and_config_tests.rs b/crates/slice-cli/tests/frameworks_wasm_and_config_tests.rs index b2c3e7b..08795a5 100644 --- a/crates/slice-cli/tests/frameworks_wasm_and_config_tests.rs +++ b/crates/slice-cli/tests/frameworks_wasm_and_config_tests.rs @@ -161,6 +161,10 @@ fn test_wave_e_hono_and_itty_unjs_framework_suites() { .join("tests") .join("frameworks") .join("03-node-http-express-compat"); + let fw4_dir = repo_root + .join("tests") + .join("frameworks") + .join("04-sveltekit-edge-ssr"); assert!(fw1_dir.join("slice.toml").is_file()); assert!(fw1_dir.join("src/index.ts").is_file()); @@ -168,6 +172,8 @@ fn test_wave_e_hono_and_itty_unjs_framework_suites() { assert!(fw2_dir.join("src/index.ts").is_file()); assert!(fw3_dir.join("slice.toml").is_file()); assert!(fw3_dir.join("src/index.ts").is_file()); + assert!(fw4_dir.join("slice.toml").is_file()); + assert!(fw4_dir.join("src/index.ts").is_file()); let bundled3 = slice_cas::bundle_entrypoint_with_deps(&fw3_dir.join("src/index.ts")).unwrap(); let bc3 = compile_source_to_bytecode(&bundled3); @@ -216,6 +222,36 @@ fn test_wave_e_hono_and_itty_unjs_framework_suites() { assert!(out2.stdout[0].contains(r#""totalRequestsDispatched":12"#)); assert!(out2.stdout[0].contains(r#""status304Count":2"#)); } + + if fw4_dir.join("node_modules/@sveltejs/kit").is_dir() + && fw4_dir.join("src/build/slice-entry.js").is_file() + { + let fw4_clone = fw4_dir.clone(); + std::thread::Builder::new() + .stack_size(16 * 1024 * 1024) + .spawn(move || { + let bundled4 = + slice_cas::bundle_entrypoint_with_deps(&fw4_clone.join("src/index.ts")) + .unwrap(); + let bc4 = compile_source_to_bytecode(&bundled4); + let mut iso4 = SliceIsolate::spawn( + "wave-e-sveltekit", + 1, + CapabilityToken::pure_compute(), + 50_000_000, + 64 * 1024 * 1024, + ); + let out4 = iso4.execute_bytecode(&bc4, None).unwrap(); + assert!(out4.stdout[0].contains(r#""framework":"04-sveltekit-edge-ssr""#)); + assert!(out4.stdout[0].contains(r#""totalRequestsDispatched":12"#)); + assert!(out4.stdout[0].contains(r#""ssrPagesRendered":4"#)); + assert!(out4.stdout[0].contains(r#""formActionsExecuted":2"#)); + assert!(out4.stdout[0].contains(r#""auditDigest":"1d85e85c9c954480""#)); + }) + .unwrap() + .join() + .unwrap(); + } } #[test] @@ -240,6 +276,24 @@ fn test_wave_f_slice_init_generates_slice_d_ts_and_tsconfig() { assert!(tsconfig.contains("\"slice.d.ts\"")); let _ = std::fs::remove_dir_all(&tmp_dir); + + // Verify `slice init --template=sveltekit` + let sk_dir = env::temp_dir().join("slice_cli_test_init_sveltekit"); + let _ = std::fs::remove_dir_all(&sk_dir); + cmd_init(&[ + sk_dir.to_string_lossy().to_string(), + "--template=sveltekit".to_string(), + ]) + .unwrap(); + assert!(sk_dir.join("slice.toml").is_file()); + assert!(sk_dir.join("package.json").is_file()); + assert!(sk_dir.join("adapter-slice.js").is_file()); + assert!(sk_dir.join("vite.config.js").is_file()); + assert!(sk_dir.join("src/hooks.server.js").is_file()); + assert!(sk_dir.join("src/routes/+page.server.js").is_file()); + assert!(sk_dir.join("src/routes/+page.svelte").is_file()); + assert!(sk_dir.join("src/routes/api/items/+server.js").is_file()); + let _ = std::fs::remove_dir_all(&sk_dir); } #[test] diff --git a/crates/slice-engine/src/intrinsics/url_and_usp.rs b/crates/slice-engine/src/intrinsics/url_and_usp.rs index 9288a8a..c764888 100644 --- a/crates/slice-engine/src/intrinsics/url_and_usp.rs +++ b/crates/slice-engine/src/intrinsics/url_and_usp.rs @@ -245,6 +245,28 @@ fn is_valid_whatwg_hostname(hostname: &str) -> bool { }) } +#[inline] +fn has_non_special_scheme(s: &str) -> bool { + let Some(ci) = s.find(':') else { + return false; + }; + if ci == 0 || s.find('/').is_some_and(|sl| sl < ci) { + return false; + } + let scheme = &s[..ci]; + if !scheme.bytes().next().is_some_and(|b| b.is_ascii_alphabetic()) + || !scheme + .bytes() + .all(|b| b.is_ascii_alphanumeric() || matches!(b, b'+' | b'-' | b'.')) + { + return false; + } + !matches!( + scheme.to_ascii_lowercase().as_str(), + "http" | "https" | "ws" | "wss" | "file" | "ftp" + ) +} + /// Resolves and parses a WHATWG `URL` from `input` and optional `base`, returning `None` if invalid. pub fn parse_whatwg_url(input: &str, base: Option<&str>) -> Option { // WHATWG URL step 1: trim leading/trailing C0 controls and space (`<= 0x20`) and strip ASCII tab/LF/CR @@ -253,7 +275,7 @@ pub fn parse_whatwg_url(input: &str, base: Option<&str>) -> Option = - if let Some(base_str) = base.filter(|_| !trimmed.contains("://")) { + if let Some(base_str) = base.filter(|_| !trimmed.contains("://") && !has_non_special_scheme(trimmed)) { let b = parse_whatwg_url(base_str, None)?; if trimmed.starts_with("//") { Cow::Owned(format!("{}{}", b.protocol, trimmed)) @@ -284,7 +306,56 @@ pub fn parse_whatwg_url(input: &str, base: Option<&str>) -> Option (before_hash, ""), }; - let si = before_query.find("://")?; + let Some(si) = before_query.find("://") else { + let ci = before_query.find(':')?; + if ci == 0 { + return None; + } + let scheme_part = &before_query[..ci]; + if !scheme_part.bytes().next()?.is_ascii_alphabetic() + || !scheme_part + .bytes() + .all(|b| b.is_ascii_alphanumeric() || matches!(b, b'+' | b'-' | b'.')) + { + return None; + } + let protocol = format!("{}:", scheme_part.to_ascii_lowercase()); + if matches!( + protocol.as_str(), + "http:" | "https:" | "ws:" | "wss:" | "file:" | "ftp:" + ) { + return None; + } + let path_part = &before_query[ci + 1..]; + if path_part.starts_with('/') || path_part.starts_with('\\') { + return None; + } + let pathname = path_part.to_string(); + let search = if search_raw == "?" { + String::new() + } else { + search_raw.to_string() + }; + let hash = if hash_raw == "#" { + String::new() + } else { + hash_raw.to_string() + }; + let href = format!("{}{}{}{}", protocol, pathname, search, hash); + return Some(ParsedWhatwgUrl { + href, + origin: "null".to_string(), + protocol, + username: String::new(), + password: String::new(), + host: String::new(), + hostname: String::new(), + port: String::new(), + pathname, + search, + hash, + }); + }; if si == 0 { return None; } @@ -326,7 +397,7 @@ pub fn parse_whatwg_url(input: &str, base: Option<&str>) -> Option (String::new(), String::new(), auth_host), }; - if host_port.is_empty() && protocol != "file:" { + if host_port.is_empty() && is_special && protocol != "file:" { return None; } @@ -358,7 +429,7 @@ pub fn parse_whatwg_url(input: &str, base: Option<&str>) -> Option (host_port.to_ascii_lowercase(), String::new()), }; - if protocol != "file:" && !is_valid_whatwg_hostname(&hostname) { + if (is_special || !hostname.is_empty()) && protocol != "file:" && !is_valid_whatwg_hostname(&hostname) { return None; } diff --git a/crates/slice-engine/src/preludes/01_web_fetch_url.js b/crates/slice-engine/src/preludes/01_web_fetch_url.js index 41b98d7..43ae090 100644 --- a/crates/slice-engine/src/preludes/01_web_fetch_url.js +++ b/crates/slice-engine/src/preludes/01_web_fetch_url.js @@ -175,9 +175,19 @@ return "/" + out.join("/") + (p.length > 1 && p.charCodeAt(p.length - 1) === 47 && out.length > 0 ? "/" : ""); } + function __hasNonSpecialScheme(s) { + var ci = s.indexOf(":"); + if (ci <= 0) return false; + var sl = s.indexOf("/"); + if (sl !== -1 && sl < ci) return false; + if (!/^[a-zA-Z][a-zA-Z0-9+.-]*$/.test(s.slice(0, ci))) return false; + var p = s.slice(0, ci + 1).toLowerCase(); + return p !== "http:" && p !== "https:" && p !== "ws:" && p !== "wss:" && p !== "file:" && p !== "ftp:"; + } + function URL(input, base) { var raw = (input && input._isSliceUrl) ? input.href : (typeof input === "string" ? input.trim() : String(input).trim()); - if (base !== undefined && raw.indexOf("https://") !== 0 && raw.indexOf("http://") !== 0 && raw.indexOf("://") === -1) { + if (base !== undefined && raw.indexOf("https://") !== 0 && raw.indexOf("http://") !== 0 && raw.indexOf("://") === -1 && !__hasNonSpecialScheme(raw)) { if (typeof base === "string" && raw.charCodeAt(0) === 47 && raw.charCodeAt(1) !== 47) { var bsi = base.indexOf("://"); if (bsi > 0 && base.indexOf("?", bsi + 3) === -1 && base.indexOf("#", bsi + 3) === -1) { @@ -189,7 +199,8 @@ } } else { var b = (base && base._isSliceUrl) ? base : new URL(String(base)); - if (raw.indexOf("//") === 0) raw = b.protocol + raw; + if (raw === "") raw = b.href; + else if (raw.indexOf("//") === 0) raw = b.protocol + raw; else if (raw.charCodeAt(0) === 47) raw = b.origin + raw; else if (raw.charCodeAt(0) === 63) raw = b.origin + b.pathname + raw; else if (raw.charCodeAt(0) === 35) raw = b.origin + b.pathname + b.search + raw; @@ -210,7 +221,28 @@ raw = raw.slice(0, qi); } var si = raw.indexOf("://"); - if (si <= 0) throw new TypeError("Invalid URL: " + input); + if (si <= 0) { + var ci0 = raw.indexOf(":"); + if (ci0 > 0 && /^[a-zA-Z][a-zA-Z0-9+.-]*$/.test(raw.slice(0, ci0))) { + var proto0 = raw.slice(0, ci0 + 1).toLowerCase(); + if (proto0 !== "http:" && proto0 !== "https:" && proto0 !== "ws:" && proto0 !== "wss:" && proto0 !== "file:" && proto0 !== "ftp:" && raw.charCodeAt(ci0 + 1) !== 47) { + this.protocol = proto0; + this.username = ""; + this.password = ""; + this.hostname = ""; + this.port = ""; + this.host = ""; + this.origin = "null"; + this.pathname = raw.slice(ci0 + 1); + this.hash = hash === "#" ? "" : hash; + this.search = search === "?" ? "" : search; + this.href = this.protocol + this.pathname + this.search + this.hash; + this._sp = null; + return; + } + } + throw new TypeError("Invalid URL: " + input); + } this.protocol = raw.slice(0, si + 1).toLowerCase(); var rest = raw.slice(si + 3); var pi = rest.indexOf("/"); @@ -250,14 +282,15 @@ } }); URL.prototype._syncSearch = function() { + var baseHref = (this.origin === "null" ? this.protocol : this.origin) + this.pathname; if (!this._sp || this._sp._p.length === 0) { this.search = ""; - this.href = this.origin + this.pathname + this.hash; + this.href = baseHref + this.hash; return; } var qs = this._sp.toString(); this.search = qs ? "?" + qs : ""; - this.href = this.origin + this.pathname + this.search + this.hash; + this.href = baseHref + this.search + this.hash; }; URL.prototype.toString = URL.prototype.toJSON = function() { return this.href; diff --git a/crates/slice-engine/src/preludes/03_streams_formdata.js b/crates/slice-engine/src/preludes/03_streams_formdata.js index ca21a33..cc5ef6a 100644 --- a/crates/slice-engine/src/preludes/03_streams_formdata.js +++ b/crates/slice-engine/src/preludes/03_streams_formdata.js @@ -27,8 +27,10 @@ } }; this._ctrl = ctrl; + this._startPromise = null; if (this._src && typeof this._src.start === "function") { - this._src.start(ctrl); + var sp = this._src.start(ctrl); + if (sp && typeof sp.then === "function") this._startPromise = sp; } } ReadableStream.from = function(iterable) { diff --git a/crates/slice-engine/src/preludes/11_fetch_headers_req_res.js b/crates/slice-engine/src/preludes/11_fetch_headers_req_res.js index b910fab..9f1f146 100644 --- a/crates/slice-engine/src/preludes/11_fetch_headers_req_res.js +++ b/crates/slice-engine/src/preludes/11_fetch_headers_req_res.js @@ -193,6 +193,16 @@ return { str: JSON.stringify(rawBody), u8: null, fd: null }; } + var __defaultReqSignal = { + aborted: false, + reason: undefined, + onabort: null, + addEventListener: function() {}, + removeEventListener: function() {}, + dispatchEvent: function() { return true; }, + throwIfAborted: function() {} + }; + function Request(input, init) { if (input === "__SLICE_LIVE_REQ__") { this.method = __slice_http_method() || "GET"; @@ -205,7 +215,7 @@ this._u8 = null; this._fd = null; this.redirect = "follow"; - this.signal = null; + this.signal = __defaultReqSignal; this.bodyUsed = false; return; } @@ -217,7 +227,7 @@ this._u8 = null; this._fd = null; this.redirect = "follow"; - this.signal = null; + this.signal = __defaultReqSignal; this.bodyUsed = false; return; } @@ -253,7 +263,7 @@ this._fd = null; } this.redirect = o.redirect ? String(o.redirect) : (isReq && input.redirect ? input.redirect : "follow"); - this.signal = o.signal || (isReq && input.signal ? input.signal : null); + this.signal = o.signal || (isReq && input.signal ? input.signal : __defaultReqSignal); this.bodyUsed = false; } Request.prototype._isSliceReq = true; @@ -267,6 +277,7 @@ var oh = o.headers; this.headers = (oh && oh._isHeaders) ? oh : new Headers(oh); this._data = undefined; + this._stream = null; if (body === undefined || body === null) { this._body = ""; this._u8 = null; @@ -275,6 +286,11 @@ this._body = body; this._u8 = null; this._fd = null; + } else if (typeof body === "object" && typeof body._toText === "function" && (!body._closed || body._startPromise)) { + this._stream = body; + this._body = ""; + this._u8 = null; + this._fd = null; } else { var nb = __normHttpBody(body, this.headers); this._body = nb.str; @@ -289,6 +305,18 @@ var RP = Request.prototype, SP = Response.prototype; RP.text = SP.text = function() { this.bodyUsed = true; + if (this._stream) { + var st = this._stream, self = this; + if (st._startPromise) { + return st._startPromise.then(function() { + self._body = st._toText(); + self._stream = null; + return self._body; + }); + } + this._body = st._toText(); + this._stream = null; + } if (this._data !== undefined && !this._body) this._body = JSON.stringify(this._data); return Promise.resolve(this._body); }; @@ -406,11 +434,33 @@ var ks = Object.keys(h._m), out = []; for (var i = 0; i < ks.length; i++) { var k = ks[i]; - if (k !== "content-type" && k !== "content-length") out.push([k, h._m[k]]); + if (k === "content-type" || k === "content-length") continue; + if (k === "set-cookie" && h._sc && h._sc.length > 1) { + for (var j = 0; j < h._sc.length; j++) out.push(["set-cookie", h._sc[j]]); + } else { + out.push([k, h._m[k]]); + } } return out.length > 0 ? JSON.stringify(out) : ""; } + function __finishSliceRes(r) { + var ct = (r.headers && r.headers._m && r.headers._m["content-type"]) || r._ct; + if (r._stream) { + var st = r._stream; + if (st._startPromise) { + st._startPromise.then(function() { + __slice_http_respond(r.status, st._toText(), ct, __resHdrJson(r.headers)); + }); + return; + } + __slice_http_respond(r.status, st._toText(), ct, __resHdrJson(r.headers)); + return; + } + var rb = r._body || (r._data !== undefined ? JSON.stringify(r._data) : ""); + __slice_http_respond(r.status, rb, ct, __resHdrJson(r.headers)); + } + globalThis.Headers = Headers; globalThis.Request = Request; globalThis.Response = Response; @@ -429,14 +479,10 @@ var res = fn.call(h, new Request("__SLICE_LIVE_REQ__"), globalThis.process.env, __slice_web_ctx); if (res) { if (res._isSliceRes) { - var b = res._body || (res._data !== undefined ? JSON.stringify(res._data) : ""); - __slice_http_respond(res.status, b, res._ct, __resHdrJson(res.headers)); + __finishSliceRes(res); } else if (typeof res.then === "function") { res.then(function(r) { - if (r && r._isSliceRes) { - var rb = r._body || (r._data !== undefined ? JSON.stringify(r._data) : ""); - __slice_http_respond(r.status, rb, r._ct, __resHdrJson(r.headers)); - } + if (r && r._isSliceRes) __finishSliceRes(r); }); } } diff --git a/crates/slice-engine/tests/web_primitives_and_case_studies_tests.rs b/crates/slice-engine/tests/web_primitives_and_case_studies_tests.rs index a88670a..6e724f2 100644 --- a/crates/slice-engine/tests/web_primitives_and_case_studies_tests.rs +++ b/crates/slice-engine/tests/web_primitives_and_case_studies_tests.rs @@ -401,3 +401,75 @@ fn test_audit_neo_phase3_zero_alloc_kv_counters_and_cow_vfs_checkpoints() { assert_eq!(res["restoredVfs"], "alpha"); assert_eq!(res["restoredKv"], "12"); } + +#[test] +fn test_sveltekit_whatwg_opaque_url_signal_and_async_stream_response() { + use crate::intrinsics::{can_parse_whatwg_url, parse_whatwg_url}; + + // 1. Native Rust WHATWG URL non-special opaque-path URLs (used by SvelteKit `$app/state` `new URL("a:")`) + let u_a = parse_whatwg_url("a:", None).expect("new URL('a:') must parse"); + assert_eq!(u_a.protocol, "a:"); + assert_eq!(u_a.pathname, ""); + assert_eq!(u_a.origin, "null"); + assert_eq!(u_a.href, "a:"); + assert!(can_parse_whatwg_url("a:", None)); + assert!(can_parse_whatwg_url("about:blank", None)); + assert!(can_parse_whatwg_url("data:text/plain;base64,SGVsbG8=", None)); + assert!(!can_parse_whatwg_url("http:foo", None)); + + // 2. JS `new URL("a:")`, `Request.prototype.signal`, and async `ReadableStream` `Response` body + let js = r#" + (async () => { + const u1 = new URL("a:"); + const u2 = new URL("about:blank?x=1#top"); + const req = new Request("https://edge.slice.local/items"); + let abortListenerOk = false; + req.signal.addEventListener("abort", () => {}); + abortListenerOk = (req.signal.aborted === false); + + const stream = new ReadableStream({ + async start(controller) { + await Promise.resolve(); + controller.enqueue("chunk-1:"); + await Promise.resolve(); + controller.enqueue("chunk-2"); + controller.close(); + } + }); + const res = new Response(stream, { headers: { "x-test": "1" } }); + res.headers.set("content-type", "text/sveltekit-data"); + res.headers.append("set-cookie", "a=1; Path=/"); + res.headers.append("set-cookie", "b=2; Path=/"); + const text = await res.text(); + console.log(JSON.stringify({ + u1Href: u1.href, + u1Proto: u1.protocol, + u1Origin: u1.origin, + u2Path: u2.pathname, + u2Search: u2.search, + canParseA: URL.canParse("a:"), + abortListenerOk, + text, + cookies: res.headers.getSetCookie() + })); + })(); + "#; + let m = run_source_isolated( + "sveltekit-primitives-tenant", + js, + CapabilityToken::pure_compute(), + 1_000_000, + 8 * 1024 * 1024, + ) + .unwrap(); + let res: serde_json::Value = serde_json::from_str(&m.stdout[0]).unwrap(); + assert_eq!(res["u1Href"], "a:"); + assert_eq!(res["u1Proto"], "a:"); + assert_eq!(res["u1Origin"], "null"); + assert_eq!(res["u2Path"], "blank"); + assert_eq!(res["u2Search"], "?x=1"); + assert_eq!(res["canParseA"], true); + assert_eq!(res["abortListenerOk"], true); + assert_eq!(res["text"], "chunk-1:chunk-2"); + assert_eq!(res["cookies"], serde_json::json!(["a=1; Path=/", "b=2; Path=/"])); +} diff --git a/docs/general/00_index.md b/docs/general/00_index.md index cd361ce..c16eed0 100644 --- a/docs/general/00_index.md +++ b/docs/general/00_index.md @@ -39,7 +39,7 @@ Traditional JavaScript runtimes (**Node.js**, **Deno**, and **Bun**) were built | **[Chapter 06](./06_ai_agent_sandbox_checkpoints_and_mcp.md)** | **AI Agents, Nested MicroVM Sandboxes (`Slice.evalSandbox`), `< 5 us` Checkpoints & `slice mcp`**
Execute untrusted LLM or user plugin code safely in microseconds, branch and roll back VFS + KV state with `Slice.checkpoint()` / `Slice.restore()`, and integrate `slice mcp` with Claude Code and Cursor. | | **[Chapter 07](./07_node_compat_intrinsics_and_npm.md)** | **Node.js Compatibility (`node:*`), NPM Packages & Migration Guide (Node / Bun / Deno to Slice)**
Complete API reference for `node:fs`, `node:crypto`, `node:path`, `node:os`, `node:buffer`, `node:url`, `node:util`, `node:process`, and `node:test`, plus recipes for npm packages and step-by-step migration guides from Express/Fastify, Hono, Bun, and Deno. | | **[Chapter 08](./08_kernel_io_rings_and_rust_embedding.md)** | **Embedding Slice in Rust Applications & High-Density MicroVM Swarms**
Embed `slice-engine`, `slice-cas`, `slice-sandbox`, and `slice-io` as a library inside your own Rust services to run thousands of isolated tenant scripts in a single process. | -| **[Chapter 09](./09_benchmarks_testing_and_docker_suite.md)** | **Time-Travel Testing (`slice test`), Deterministic Replay & Production Benchmarks**
Write rock-solid unit and security tests with `slice test` (`expect(...).toViolate()`, `.toStayWithinFuel()`, `< 5 us` VFS+KV rollbacks), replay bugs with `--deterministic`, and explore all 31 real-world benchmark applications and case studies. | +| **[Chapter 09](./09_benchmarks_testing_and_docker_suite.md)** | **Time-Travel Testing (`slice test`), Deterministic Replay & Production Benchmarks**
Write rock-solid unit and security tests with `slice test` (`expect(...).toViolate()`, `.toStayWithinFuel()`, `< 5 us` VFS+KV rollbacks), replay bugs with `--deterministic`, and explore all 33 real-world benchmark applications, frameworks, and case studies. | | **[Compatibility Matrix](./COMPATIBILITY.md)** | **WinterTC, Node.js (`node:*`), `Buffer` & NPM Bundler Compatibility Matrix**
Complete reference of supported WinterTC Web APIs, `Uint8Array`-backed `Buffer` methods, `node:*` core modules, and `package.json` `"exports"` bundler capabilities. | --- @@ -86,6 +86,6 @@ Traditional JavaScript runtimes (**Node.js**, **Deno**, and **Bun**) were built - [`docs/system/09_research_deep_dive.md`](../system/09_research_deep_dive.md) - [`vendor/boa_engine/SLICE_PATCH.md`](../../vendor/boa_engine/SLICE_PATCH.md) (`SLICEBC1` Precompiled `CodeBlock` Vendor Patch Specification) - **Docker Application, Framework & Case Study Test Suites (`tests/`):** - - [`tests/README.md`](../../tests/README.md) (`tests/apps/` — 25 Production Apps) - - [`tests/frameworks/README.md`](../../tests/frameworks/README.md) (`tests/frameworks/` — Hono v4 & itty-router + UnJS) - - [`tests/case_studies/README.md`](../../tests/case_studies/README.md) (`tests/case_studies/` — 4 Architectural Differentiation Workloads) + - [`tests/README.md`](../../tests/README.md) (`tests/apps/` — 24 Production Apps) + - [`tests/frameworks/README.md`](../../tests/frameworks/README.md) (`tests/frameworks/` — Hono v4, itty-router + UnJS, Express/Polka, & SvelteKit 3 + Svelte 5) + - [`tests/case_studies/README.md`](../../tests/case_studies/README.md) (`tests/case_studies/` — 5 Architectural Differentiation Workloads) diff --git a/docs/general/09_benchmarks_testing_and_docker_suite.md b/docs/general/09_benchmarks_testing_and_docker_suite.md index 9144cd9..edbfc79 100644 --- a/docs/general/09_benchmarks_testing_and_docker_suite.md +++ b/docs/general/09_benchmarks_testing_and_docker_suite.md @@ -132,9 +132,9 @@ When deterministic mode is active: --- -## 4. Running the 32-Workload Docker Benchmark Suite (`tests/`) +## 4. Running the 33-Workload Docker Benchmark Suite (`tests/`) -Slice includes a comprehensive Linux `x86_64` Docker benchmark suite ([`tests/`](../../tests/README.md)) that tests **32 realistic multi-file TypeScript + `node_modules` applications, full-stack edge frameworks, and architectural case studies** against the latest official releases of **Bun**, **Deno**, and **Node.js**, verifying **100% byte-for-byte identical JSON output** across all 4 runtimes and automatically writing timestamped reports to [`tests/reports/`](../../tests/reports/latest.md). +Slice includes a comprehensive Linux `x86_64` Docker benchmark suite ([`tests/`](../../tests/README.md)) that tests **33 realistic multi-file TypeScript + `node_modules` applications, full-stack edge frameworks (`Hono`, `itty-router + UnJS`, `Express/Polka`, `SvelteKit 3 + Svelte 5`), and architectural case studies** against the latest official releases of **Bun**, **Deno**, and **Node.js**, verifying **100% byte-for-byte identical JSON output** across all 4 runtimes and automatically writing timestamped reports to [`tests/reports/`](../../tests/reports/latest.md). ```bash # Run the automated benchmark suite & doc sync (PowerShell or Bash) @@ -144,12 +144,12 @@ Slice includes a comprehensive Linux `x86_64` Docker benchmark suite ([`tests/`] ./scripts/run_benchmarks.sh "apps,frameworks,case_studies,serve,swarm" ``` -### 4.1 Verified Results Across All 32 Production Applications, Frameworks & Case Studies ([`tests/reports/latest.md`](../../tests/reports/latest.md)) +### 4.1 Verified Results Across All 33 Production Applications, Frameworks & Case Studies ([`tests/reports/latest.md`](../../tests/reports/latest.md)) -> **Latest Verified Benchmark Report:** **[`tests/reports/latest.md`](../../tests/reports/latest.md)** (Archive: [`bench_v0.10.4_20261109_073538Z_7a86dd6.md`](../../tests/reports/bench_v0.10.4_20261109_073538Z_7a86dd6.md)) -> **Provenance:** Slice `v0.10.5` (`7a86dd6`) · Generated `2026-11-09T07:35:38Z` · Environment: `Linux x86_64 Docker (io_uring SQPOLL + WRPKRU)` -> **Scorecard Across All 32 Production Workloads:** Beats **Deno (`v2.9.8`)** on **32/32**, **Node.js (`v27.0.0-alpha.0.0.0`)** on **32/32**, **Bun (`v1.4.4`)** on **29/32** cold one-shot, and **all 3 runtimes on 32/32 workloads in `--warm` pooled execution**. +> **Latest Verified Benchmark Report:** **[`tests/reports/latest.md`](../../tests/reports/latest.md)** (Archive: [`bench_v0.10.5_20261109_202907Z_a0c723e.md`](../../tests/reports/bench_v0.10.5_20261109_202907Z_a0c723e.md)) +> **Provenance:** Slice `v0.10.5` (`a0c723e`) · Generated `2026-11-09T20:29:07Z` · Environment: `Linux x86_64 Docker (io_uring SQPOLL + WRPKRU)` +> **Scorecard Across All 33 Production Workloads:** Beats **Deno (`v2.9.8`)** on **33/33**, **Node.js (`v27.0.0-alpha.0.0.0`)** on **33/33**, **Bun (`v1.4.4`)** on **30/33** cold one-shot, and **all 3 runtimes on 33/33 workloads in `--warm` pooled execution**. #### 1. Core Architecture, HTTP Throughput & 1,000-Tenant MicroVM Density @@ -159,10 +159,10 @@ Slice includes a comprehensive Linux `x86_64` Docker benchmark suite ([`tests/`] | **1,000-Tenant MicroVM Swarm (Boot + Exec)** | **`1.51 ms` (`10.07 MB` RSS)** | > 5,000 ms | > 15,000 ms | > 30,000 ms | **> 3,900x faster / ~32,000x denser** | | **500-Module Monorepo Cold Boot (`stat()` Calls)** | **`3.41 ms` (`0 stat()`)** | `12.72 ms` (`500+ stat`) | `41.80 ms` (`500+ stat`) | `70.38 ms` (`1,500+ stat`) | **`3.7x` faster than Bun / `20.6x` Node.js** | | **HTTP/1.1 Keep-Alive Throughput (`16k` Reqs)** | **`148,407 req/s`** (Tier-0)
**`145,839 req/s`** (Tier-1) | `97,987 req/s` | `100,099 req/s` | `55,977 req/s` | **`1.51x` (`Tier-0`) / `1.49x` (`Tier-1`) vs `Bun.serve`** | -| **Peak Process Memory (`Max RSS` Across Suite)** | **`13.38 – 21.50 MB`** | `27.25 – 40.59 MB` | `45.86 – 61.39 MB` | `69.90 – 92.50 MB` | **`2.0x–2.3x` less than Bun / `4.3x–6.8x` less than Node** | +| **Peak Process Memory (`Max RSS` Across Suite)** | **`13.38 – 21.50 MB`** | `27.25 – 41.00 MB` | `45.47 – 61.39 MB` | `69.90 – 92.50 MB` | **`2.0x–2.3x` less than Bun / `4.3x–6.8x` less than Node** | | **Multi-Tenant Security Containment** | **`5 / 5 PASS`** (OCap+SES+Fuel+DLP) | `0 / 5` (Ambient) | `2 / 5` (Coarse CLI) | `0 / 5` (Ambient) | **Hardware & Language Zero-Trust Isolation** | -#### 2. Real-Life Workload Summary by Domain (All 32 Workloads Aggregated) +#### 2. Real-Life Workload Summary by Domain (All 33 Workloads Aggregated) | Workload Domain & Stack Coverage | Suites | Slice Cold `.cas` Avg (Range) | Slice Warm (`--warm`) Avg | Bun `v1.4.4` Avg | Deno `v2.9.8` Avg | Node.js `v27.0.0-alpha.0.0.0` Avg | Category Speedup vs Bun / Node.js | | :--- | :---: | :---: | :---: | :---: | :---: | :---: | :--- | @@ -170,10 +170,10 @@ Slice includes a comprehensive Linux `x86_64` Docker benchmark suite ([`tests/`] | **NPM Ecosystem, AST & Disk I/O (`Apps 02, 03, 06, 07, 08, 20`)**
`semver`, `flatted`, `dlv`/`dset`, `mitt`, 10-Shard JSONL I/O, `Buffer` | `6` | **`11.85 ms`** (`8.04–14.66 ms`) | **`3.87 ms`** | `17.63 ms` | `51.32 ms` | `67.38 ms` | **`1.49x Bun` (`4.55x` Warm) / `5.69x Node`** | | **WinterTC Web Standards, Fetch Mesh & DLP (`Apps 09–14, 17–19`)**
`Request`/`Response`, Static CDN `304`, SSE, Live `fetch`, WebCrypto | `9` | **`15.73 ms`** (`8.35–30.83 ms`) | **`8.25 ms`** | `19.22 ms` | `55.05 ms` | `97.59 ms` | **`1.22x Bun` (`2.33x` Warm) / `6.20x Node`** | | **Realtime WebSockets, Workers & Wasm/TSX (`Apps 15, 21–24`)**
RFC 6455 WS, `worker_threads` + TCP/UDP, Pure-Rust `wasmi` Wasm, TSX SSR | `5` | **`14.43 ms`** (`8.93–21.16 ms`) | **`2.79 ms`** | `28.88 ms` | `64.18 ms` | `87.52 ms` | **`2.00x Bun` (`10.35x` Warm) / `6.07x Node`** | -| **Full-Stack Edge & Node Frameworks (`FW 01–03`)**
`Hono v4.6.20`, `itty-router + UnJS Nitro`, `Express/Polka node:http` | `3` | **`16.85 ms`** (`15.32–18.32 ms`) | **`5.45 ms`** | `25.21 ms` | `50.68 ms` | `90.96 ms` | **`1.50x Bun` (`4.63x` Warm) / `5.40x Node`** | +| **Full-Stack Edge & Node Frameworks (`FW 01–04`)**
`Hono v4.6.20`, `itty-router + UnJS Nitro`, `Express/Polka node:http`, `SvelteKit 3.1.1 + Svelte 5.57.3` | `4` | **`21.84 ms`** (`15.86–36.16 ms`) | **`8.39 ms`** | `33.81 ms` | `60.33 ms` | `101.48 ms` | **`1.55x Bun` (`4.03x` Warm) / `4.65x Node`** | | **AI Agent, Multi-Tenant SaaS & Chaos Case Studies (`CS 01–05`)**
Depth-4 ToT Agent, MCP Code Mode, 12-Tenant Mesh, Wasm CDR, 48 Payment Sagas | `5` | **`19.29 ms`** (`13.98–26.48 ms`) | **`7.87 ms`** | `20.04 ms` | `54.98 ms` | `78.81 ms` | **`1.04x Bun` (`2.55x` Warm) / `4.08x Node`** | -#### 3. Flagship Real-World Representative Workloads (8 of 32 Highlights) +#### 3. Flagship Real-World Representative Workloads (9 of 33 Highlights) | # | Flagship Workload | Slice Cold `.cas` | Slice Warm (`--warm`) | Bun `v1.4.4` | Deno `v2.9.8` | Node.js `v27.0.0-alpha.0.0.0` | Speedup vs Bun / Node.js | | :- | :--- | :---: | :---: | :---: | :---: | :---: | :--- | @@ -182,11 +182,12 @@ Slice includes a comprehensive Linux `x86_64` Docker benchmark suite ([`tests/`] | **14** | `14-federated-api-mesh-dlp` (`bytes` + `dlv` + `dset` + Live `fetch`) | **`15.52 ms`** | **`7.87 ms`** | `22.38 ms` | `56.66 ms` | `112.02 ms` | **`1.44x Bun` (`2.84x` Warm) / `7.22x Node`** | | **20** | `20-node-compat-and-edge-router` (`Uint8Array` `Buffer`/Node Core/AST Bundler) | **`11.50 ms`** | **`0.55 ms`** | `22.56 ms` | `55.77 ms` | `71.86 ms` | **`1.96x Bun` (`41.39x` Warm) / `6.25x Node`** | | **22** | `22-worker-threads-and-raw-sockets` (3 Worker Threads + TCP/UDP + 5-Ring Sec) | **`21.52 ms`** | **`2.22 ms`** | `57.85 ms` | `113.39 ms` | `103.24 ms` | **`2.73x Bun` (`26.09x` Warm) / `4.88x Node`** | -| **FW-01** | `FW-01: frameworks/01-hono-edge-microservice` (`hono@4.6.20` + `hono/cookie` + `ms`) | **`15.32 ms`** | **`6.48 ms`** | `20.41 ms` | `54.05 ms` | `96.96 ms` | **`1.33x Bun` (`3.15x` Warm) / `6.33x Node`** | +| **FW-01** | `FW-01: frameworks/01-hono-edge-microservice` (`hono@4.6.20` + `hono/cookie` + `ms`) | **`16.07 ms`** | **`5.72 ms`** | `19.91 ms` | `53.97 ms` | `99.71 ms` | **`1.26x Bun` (`3.48x` Warm) / `6.29x Node`** | +| **FW-04** | `FW-04: frameworks/04-sveltekit-edge-ssr` (`@sveltejs/kit@3.1.1` + `svelte@5.57.3` + `devalue@6.0.3`) | **`36.16 ms`** | **`17.02 ms`** | `46.58 ms` | `71.05 ms` | `119.71 ms` | **`1.29x Bun` (`2.74x` Warm) / `3.31x Node`** | | **CS-01** | `CS-01: case_studies/01-tot-autonomous-sre-agent` (20 ToT Sandboxes) | **`26.48 ms`** | **`13.12 ms`** | `28.26 ms` | `72.65 ms` | `89.71 ms` | **`1.07x Bun` (`2.15x` Warm) / `3.39x Node`** | | **CS-05** | `CS-05: case_studies/05-time-travel-chaos-fuzzer-payments` (48 Payment Sagas) | **`18.13 ms`** | **`10.31 ms`** | `19.62 ms` | `62.94 ms` | `83.70 ms` | **`1.08x Bun` (`1.90x` Warm) / `4.62x Node`** | -*Full 32-workload latency breakdown, standalone binary metrics, peak RSS per app, and historical reports: **[`tests/reports/latest.md`](../../tests/reports/latest.md)**.* +*Full 33-workload latency breakdown, standalone binary metrics, peak RSS per app, and historical reports: **[`tests/reports/latest.md`](../../tests/reports/latest.md)**.* --- diff --git a/docs/guides/01_hono_and_unjs_edge_microservices.md b/docs/guides/01_hono_and_unjs_edge_microservices.md index 1c53e46..148e646 100644 --- a/docs/guides/01_hono_and_unjs_edge_microservices.md +++ b/docs/guides/01_hono_and_unjs_edge_microservices.md @@ -1,6 +1,6 @@ -# Guide 01: Building & Deploying Hono (`v4`) and UnJS Edge Microservices on Slice +# Guide 01: Building & Deploying Hono (`v4`), UnJS, and SvelteKit (`v3`) Edge Microservices on Slice -Because Slice implements the WinterTC Minimum Common Web Platform API (`Request`, `Response`, `Headers`, `URL`, `URLSearchParams`, `ReadableStream`, `crypto.subtle`, `TextEncoder`/`TextDecoder`, and `export default { fetch }`) and compiles bundles ahead-of-time into **`SLICEBC\x01` Precompiled Boa `CodeBlock` CAS** containers with Oxc AST deferred function module spans, WinterTC frameworks like **Hono (`v4`)**, **`itty-router` (`v5`)**, and the **UnJS / Nitro ecosystem (`ufo`, `destr`, `ohash`, `radix3`, `cookie`)** run unmodified on Slice at **`13.11 ms - 15.52 ms` cold** and **`0.55 ms - 0.56 ms` warm** (`2.54x - 2.65x` faster cold than Bun, `59x - 75x` faster warm than Bun, and `7.36x - 7.39x` faster cold than Node.js). +Because Slice implements the WinterTC Minimum Common Web Platform API (`Request`, `Response`, `Headers`, `URL`, `URLSearchParams`, `ReadableStream`, `crypto.subtle`, `TextEncoder`/`TextDecoder`, and `export default { fetch }`) and compiles bundles ahead-of-time into **`SLICEBC\x01` Precompiled Boa `CodeBlock` CAS** containers with Oxc AST deferred function module spans and live ES module bindings, WinterTC frameworks like **Hono (`v4`)**, **`itty-router` (`v5`)**, the **UnJS / Nitro ecosystem (`ufo`, `destr`, `ohash`, `radix3`, `cookie`)**, and **SvelteKit (`@sveltejs/kit@3.1.1` + `svelte@5.57.3`)** run unmodified on Slice. --- @@ -62,3 +62,28 @@ slice compile . -o ./my-hono-bin See [`tests/frameworks/01-hono-edge-microservice`](../../tests/frameworks/01-hono-edge-microservice/src/index.ts) and [`tests/frameworks/02-itty-router-unjs-nitro-stack`](../../tests/frameworks/02-itty-router-unjs-nitro-stack/src/index.ts) for complete, benchmarked reference implementations verified across Slice, Bun, Deno, and Node.js. +--- + +## 3. Scaffolding & Deploying a Full-Stack SvelteKit (`v3.1.1`) + Svelte 5 (`v5.57.3`) SSR Application + +Slice includes a built-in project scaffolder (`slice init --template=sveltekit`) and custom WinterTC adapter (`adapter-slice.js`) for full-stack SvelteKit 3 + Svelte 5 SSR applications (`+page.svelte`, `+page.server.js` `load` & `actions`, `+server.js` JSON endpoints, `hooks.server.js`, and `devalue` `__data.json` hydration): + +```bash +# 1. Scaffold a SvelteKit 3 + Svelte 5 project with adapter-slice: +slice init ./my-sveltekit-app --template=sveltekit +cd ./my-sveltekit-app + +# 2. Install dependencies & run the Vite 8 + SvelteKit SSR build: +npm install +npm run build + +# 3. Pack the SSR server + client static assets into a single zero-stat .cas archive: +slice pack ./build/slice-entry.js ./build/app.cas --static=./build/client + +# 4. Serve with multi-worker HTTP/1.1 Keep-Alive and BLAKE3 ETag static assets: +slice serve ./build/app.cas --port=3000 --workers=8 +``` + +See [`tests/frameworks/04-sveltekit-edge-ssr`](../../tests/frameworks/04-sveltekit-edge-ssr/src/index.ts) for the full 12-request benchmark and verification suite. + + diff --git a/docs/guides/README.md b/docs/guides/README.md index 12f7562..a0d4421 100644 --- a/docs/guides/README.md +++ b/docs/guides/README.md @@ -4,7 +4,7 @@ This directory contains practical step-by-step developer guides, production depl ## Available Guides -* **[Guide 01: Building & Deploying Hono (`v4`) and UnJS Edge Microservices](./01_hono_and_unjs_edge_microservices.md)**: Scaffolding, serving (`slice serve`), and compiling (`slice compile`) `hono`, `itty-router`, and UnJS (`ufo`, `destr`, `ohash`, `radix3`) microservices. +* **[Guide 01: Building & Deploying Hono (`v4`), UnJS, and SvelteKit (`v3`) Edge Microservices](./01_hono_and_unjs_edge_microservices.md)**: Scaffolding (`slice init --template=sveltekit`), serving (`slice serve`), and compiling (`slice compile`) `hono`, `itty-router`, UnJS (`ufo`, `destr`, `ohash`, `radix3`), and full-stack SvelteKit 3 + Svelte 5 SSR applications. * **[Guide 02: TypeScript IDE Setup (`slice.d.ts`), Linting (`oxlint` / `Biome`), & `.wasm` Modules](./02_typescript_ide_linting_and_wasm.md)**: Configuring `tsc --noEmit`, `oxlint`, `Biome`, and replacing `.node` C++ addons with 5-Ring sandboxed `.wasm` modules. * **[Production Tooling & Deployment Guide](../system/07_production_tooling_guide.md)**: End-to-end guide for `slice pack` (Zero-Stat `.cas` bundles), `slice compile` (self-contained `SLICEEXE` binaries), `slice serve` (multi-tenant HTTP/1.1 & WebSocket MicroVM hosting), `slice mcp` (AI Agent "Code Mode" MCP server), and `slice doctor`. * **[Getting Started, `slice.toml` & CLI Reference](../general/01_getting_started_and_cli.md)**: Quickstart, project scaffolding (`slice init`), `.env` Auto-DLP configuration, and complete CLI command reference. diff --git a/tests/Dockerfile b/tests/Dockerfile index d27e0b1..afbc2fb 100644 --- a/tests/Dockerfile +++ b/tests/Dockerfile @@ -64,6 +64,8 @@ RUN bun install --cwd /app/tests/apps/02-npm-ecosystem-suite \ && bun install --cwd /app/tests/apps/24-tsx-ssr-and-wasm-edge-pipeline \ && bun install --cwd /app/tests/frameworks/01-hono-edge-microservice \ && bun install --cwd /app/tests/frameworks/02-itty-router-unjs-nitro-stack \ + && bun install --cwd /app/tests/frameworks/04-sveltekit-edge-ssr \ + && bun run --cwd /app/tests/frameworks/04-sveltekit-edge-ssr build \ && bun install --cwd /app/tests/case_studies/01-tot-autonomous-sre-agent \ && bun install --cwd /app/tests/case_studies/02-mcp-code-mode-orchestrator \ && bun install --cwd /app/tests/case_studies/03-multi-tenant-saas-plugin-mesh \ diff --git a/tests/README.md b/tests/README.md index 7730783..a63a8f5 100644 --- a/tests/README.md +++ b/tests/README.md @@ -1,6 +1,6 @@ # Slice Docker-Based Folder Applications, Frameworks, Case Studies, External NPM Libraries & Disk I/O Benchmark Suite -This directory (`tests/`) contains a reproducible Linux `x86_64` Docker benchmark suite comparing **Slice (Nexus-JS)** against the **absolute latest releases** of **Bun (`v1.4.4`)**, **Deno (`v2.9.8`)**, and **Node.js (`v27.0.0-alpha`)** across **31 real-world workloads**: **24 folder-based production TypeScript applications** ([`tests/apps/`](./apps)), **2 full-stack edge framework suites** ([`tests/frameworks/`](./frameworks/README.md)), and **5 intensive AI Agent / SaaS / Chaos Case Studies** ([`tests/case_studies/`](./case_studies/README.md)). +This directory (`tests/`) contains a reproducible Linux `x86_64` Docker benchmark suite comparing **Slice (Nexus-JS)** against the **absolute latest releases** of **Bun (`v1.4.4`)**, **Deno (`v2.9.8`)**, and **Node.js (`v27.0.0-alpha`)** across **33 real-world workloads**: **24 folder-based production TypeScript applications** ([`tests/apps/`](./apps)), **4 full-stack edge & Node framework suites** ([`tests/frameworks/`](./frameworks/README.md)), and **5 intensive AI Agent / SaaS / Chaos Case Studies** ([`tests/case_studies/`](./case_studies/README.md)). --- @@ -209,12 +209,12 @@ This directory (`tests/`) contains a reproducible Linux `x86_64` Docker benchmar --- -## Verified Linux Docker (`x86_64`) Benchmark Results Across All 32 Workloads ([`reports/latest.md`](./reports/latest.md)) +## Verified Linux Docker (`x86_64`) Benchmark Results Across All 33 Workloads ([`reports/latest.md`](./reports/latest.md)) -> **Latest Verified Benchmark Report:** **[`tests/reports/latest.md`](./reports/latest.md)** (Archive: [`bench_v0.10.4_20261109_073538Z_7a86dd6.md`](./reports/bench_v0.10.4_20261109_073538Z_7a86dd6.md)) -> **Provenance:** Slice `v0.10.5` (`7a86dd6`) · Generated `2026-11-09T07:35:38Z` · Environment: `Linux x86_64 Docker (io_uring SQPOLL + WRPKRU)` -> **Scorecard Across All 32 Production Workloads:** Beats **Deno (`v2.9.8`)** on **32/32**, **Node.js (`v27.0.0-alpha.0.0.0`)** on **32/32**, **Bun (`v1.4.4`)** on **29/32** cold one-shot, and **all 3 runtimes on 32/32 workloads in `--warm` pooled execution**. +> **Latest Verified Benchmark Report:** **[`tests/reports/latest.md`](./reports/latest.md)** (Archive: [`bench_v0.10.5_20261109_202907Z_a0c723e.md`](./reports/bench_v0.10.5_20261109_202907Z_a0c723e.md)) +> **Provenance:** Slice `v0.10.5` (`a0c723e`) · Generated `2026-11-09T20:29:07Z` · Environment: `Linux x86_64 Docker (io_uring SQPOLL + WRPKRU)` +> **Scorecard Across All 33 Production Workloads:** Beats **Deno (`v2.9.8`)** on **33/33**, **Node.js (`v27.0.0-alpha.0.0.0`)** on **33/33**, **Bun (`v1.4.4`)** on **30/33** cold one-shot, and **all 3 runtimes on 33/33 workloads in `--warm` pooled execution**. #### 1. Core Architecture, HTTP Throughput & 1,000-Tenant MicroVM Density @@ -224,10 +224,10 @@ This directory (`tests/`) contains a reproducible Linux `x86_64` Docker benchmar | **1,000-Tenant MicroVM Swarm (Boot + Exec)** | **`1.51 ms` (`10.07 MB` RSS)** | > 5,000 ms | > 15,000 ms | > 30,000 ms | **> 3,900x faster / ~32,000x denser** | | **500-Module Monorepo Cold Boot (`stat()` Calls)** | **`3.41 ms` (`0 stat()`)** | `12.72 ms` (`500+ stat`) | `41.80 ms` (`500+ stat`) | `70.38 ms` (`1,500+ stat`) | **`3.7x` faster than Bun / `20.6x` Node.js** | | **HTTP/1.1 Keep-Alive Throughput (`16k` Reqs)** | **`148,407 req/s`** (Tier-0)
**`145,839 req/s`** (Tier-1) | `97,987 req/s` | `100,099 req/s` | `55,977 req/s` | **`1.51x` (`Tier-0`) / `1.49x` (`Tier-1`) vs `Bun.serve`** | -| **Peak Process Memory (`Max RSS` Across Suite)** | **`13.38 – 21.50 MB`** | `27.25 – 40.59 MB` | `45.86 – 61.39 MB` | `69.90 – 92.50 MB` | **`2.0x–2.3x` less than Bun / `4.3x–6.8x` less than Node** | +| **Peak Process Memory (`Max RSS` Across Suite)** | **`13.38 – 21.50 MB`** | `27.25 – 41.00 MB` | `45.47 – 61.39 MB` | `69.90 – 92.50 MB` | **`2.0x–2.3x` less than Bun / `4.3x–6.8x` less than Node** | | **Multi-Tenant Security Containment** | **`5 / 5 PASS`** (OCap+SES+Fuel+DLP) | `0 / 5` (Ambient) | `2 / 5` (Coarse CLI) | `0 / 5` (Ambient) | **Hardware & Language Zero-Trust Isolation** | -#### 2. Real-Life Workload Summary by Domain (All 32 Workloads Aggregated) +#### 2. Real-Life Workload Summary by Domain (All 33 Workloads Aggregated) | Workload Domain & Stack Coverage | Suites | Slice Cold `.cas` Avg (Range) | Slice Warm (`--warm`) Avg | Bun `v1.4.4` Avg | Deno `v2.9.8` Avg | Node.js `v27.0.0-alpha.0.0.0` Avg | Category Speedup vs Bun / Node.js | | :--- | :---: | :---: | :---: | :---: | :---: | :---: | :--- | @@ -235,10 +235,10 @@ This directory (`tests/`) contains a reproducible Linux `x86_64` Docker benchmar | **NPM Ecosystem, AST & Disk I/O (`Apps 02, 03, 06, 07, 08, 20`)**
`semver`, `flatted`, `dlv`/`dset`, `mitt`, 10-Shard JSONL I/O, `Buffer` | `6` | **`11.85 ms`** (`8.04–14.66 ms`) | **`3.87 ms`** | `17.63 ms` | `51.32 ms` | `67.38 ms` | **`1.49x Bun` (`4.55x` Warm) / `5.69x Node`** | | **WinterTC Web Standards, Fetch Mesh & DLP (`Apps 09–14, 17–19`)**
`Request`/`Response`, Static CDN `304`, SSE, Live `fetch`, WebCrypto | `9` | **`15.73 ms`** (`8.35–30.83 ms`) | **`8.25 ms`** | `19.22 ms` | `55.05 ms` | `97.59 ms` | **`1.22x Bun` (`2.33x` Warm) / `6.20x Node`** | | **Realtime WebSockets, Workers & Wasm/TSX (`Apps 15, 21–24`)**
RFC 6455 WS, `worker_threads` + TCP/UDP, Pure-Rust `wasmi` Wasm, TSX SSR | `5` | **`14.43 ms`** (`8.93–21.16 ms`) | **`2.79 ms`** | `28.88 ms` | `64.18 ms` | `87.52 ms` | **`2.00x Bun` (`10.35x` Warm) / `6.07x Node`** | -| **Full-Stack Edge & Node Frameworks (`FW 01–03`)**
`Hono v4.6.20`, `itty-router + UnJS Nitro`, `Express/Polka node:http` | `3` | **`16.85 ms`** (`15.32–18.32 ms`) | **`5.45 ms`** | `25.21 ms` | `50.68 ms` | `90.96 ms` | **`1.50x Bun` (`4.63x` Warm) / `5.40x Node`** | +| **Full-Stack Edge & Node Frameworks (`FW 01–04`)**
`Hono v4.6.20`, `itty-router + UnJS Nitro`, `Express/Polka node:http`, `SvelteKit 3.1.1 + Svelte 5.57.3` | `4` | **`21.84 ms`** (`15.86–36.16 ms`) | **`8.39 ms`** | `33.81 ms` | `60.33 ms` | `101.48 ms` | **`1.55x Bun` (`4.03x` Warm) / `4.65x Node`** | | **AI Agent, Multi-Tenant SaaS & Chaos Case Studies (`CS 01–05`)**
Depth-4 ToT Agent, MCP Code Mode, 12-Tenant Mesh, Wasm CDR, 48 Payment Sagas | `5` | **`19.29 ms`** (`13.98–26.48 ms`) | **`7.87 ms`** | `20.04 ms` | `54.98 ms` | `78.81 ms` | **`1.04x Bun` (`2.55x` Warm) / `4.08x Node`** | -#### 3. Flagship Real-World Representative Workloads (8 of 32 Highlights) +#### 3. Flagship Real-World Representative Workloads (9 of 33 Highlights) | # | Flagship Workload | Slice Cold `.cas` | Slice Warm (`--warm`) | Bun `v1.4.4` | Deno `v2.9.8` | Node.js `v27.0.0-alpha.0.0.0` | Speedup vs Bun / Node.js | | :- | :--- | :---: | :---: | :---: | :---: | :---: | :--- | @@ -247,11 +247,12 @@ This directory (`tests/`) contains a reproducible Linux `x86_64` Docker benchmar | **14** | `14-federated-api-mesh-dlp` (`bytes` + `dlv` + `dset` + Live `fetch`) | **`15.52 ms`** | **`7.87 ms`** | `22.38 ms` | `56.66 ms` | `112.02 ms` | **`1.44x Bun` (`2.84x` Warm) / `7.22x Node`** | | **20** | `20-node-compat-and-edge-router` (`Uint8Array` `Buffer`/Node Core/AST Bundler) | **`11.50 ms`** | **`0.55 ms`** | `22.56 ms` | `55.77 ms` | `71.86 ms` | **`1.96x Bun` (`41.39x` Warm) / `6.25x Node`** | | **22** | `22-worker-threads-and-raw-sockets` (3 Worker Threads + TCP/UDP + 5-Ring Sec) | **`21.52 ms`** | **`2.22 ms`** | `57.85 ms` | `113.39 ms` | `103.24 ms` | **`2.73x Bun` (`26.09x` Warm) / `4.88x Node`** | -| **FW-01** | `FW-01: frameworks/01-hono-edge-microservice` (`hono@4.6.20` + `hono/cookie` + `ms`) | **`15.32 ms`** | **`6.48 ms`** | `20.41 ms` | `54.05 ms` | `96.96 ms` | **`1.33x Bun` (`3.15x` Warm) / `6.33x Node`** | +| **FW-01** | `FW-01: frameworks/01-hono-edge-microservice` (`hono@4.6.20` + `hono/cookie` + `ms`) | **`16.07 ms`** | **`5.72 ms`** | `19.91 ms` | `53.97 ms` | `99.71 ms` | **`1.26x Bun` (`3.48x` Warm) / `6.29x Node`** | +| **FW-04** | `FW-04: frameworks/04-sveltekit-edge-ssr` (`@sveltejs/kit@3.1.1` + `svelte@5.57.3` + `devalue@6.0.3`) | **`36.16 ms`** | **`17.02 ms`** | `46.58 ms` | `71.05 ms` | `119.71 ms` | **`1.29x Bun` (`2.74x` Warm) / `3.31x Node`** | | **CS-01** | `CS-01: case_studies/01-tot-autonomous-sre-agent` (20 ToT Sandboxes) | **`26.48 ms`** | **`13.12 ms`** | `28.26 ms` | `72.65 ms` | `89.71 ms` | **`1.07x Bun` (`2.15x` Warm) / `3.39x Node`** | | **CS-05** | `CS-05: case_studies/05-time-travel-chaos-fuzzer-payments` (48 Payment Sagas) | **`18.13 ms`** | **`10.31 ms`** | `19.62 ms` | `62.94 ms` | `83.70 ms` | **`1.08x Bun` (`1.90x` Warm) / `4.62x Node`** | -*Full 32-workload latency breakdown, standalone binary metrics, peak RSS per app, and historical reports: **[`tests/reports/latest.md`](./reports/latest.md)**.* +*Full 33-workload latency breakdown, standalone binary metrics, peak RSS per app, and historical reports: **[`tests/reports/latest.md`](./reports/latest.md)**.* --- @@ -263,7 +264,7 @@ This directory (`tests/`) contains a reproducible Linux `x86_64` Docker benchmar | Tag | Suite Executed | Verified Linux Docker (`x86_64`) Highlight (`SLICEBC\x01` Default) | | :--- | :--- | :--- | | `apps` | All 24 folder-based TypeScript + `node_modules` apps (`01`..`24`) | **`6.46 ms - 29.06 ms` cold** / **`0.61 ms - 17.14 ms` warm** (`13.50 MB` Max RSS, **`24/24` faster than Bun warm**) | -| `frameworks` | Full-stack Edge & Node Framework suites (`01-hono-edge-microservice`, `02-itty-router-unjs-nitro-stack`, `03-node-http-express-compat`) | **`14.58 ms` Hono (`5.65 ms` warm, `14.50 MB` RSS, `1.32x` Bun)**, **`17.08 ms` UnJS/Nitro (`9.08 ms` warm, `13.75 MB` RSS, `1.12x` Bun)** & **`1.81 ms` warm `node:http` Express/Polka** | +| `frameworks` | Full-stack Edge & Node Framework suites (`01-hono-edge-microservice`, `02-itty-router-unjs-nitro-stack`, `03-node-http-express-compat`, `04-sveltekit-edge-ssr`) | **`14.58 ms` Hono (`5.65 ms` warm)**, **`17.08 ms` UnJS/Nitro (`9.08 ms` warm)**, **`1.81 ms` warm `node:http` Express/Polka**, & **SvelteKit `v3.1.1` + Svelte `v5.57.3` SSR** | | `case_studies` | All 5 production Case Studies (`01-tot-autonomous-sre-agent`..`05-time-travel-chaos-fuzzer-payments`) | **`13.20 ms - 26.68 ms` cold** / **`2.02 ms - 12.71 ms` warm** (`15.00 MB - 19.00 MB` RSS) | | `wasm` | Pure-Rust `WebAssembly` (`Apps 23 & 24`) & OS-native `slice test --watch-once` | **`16.51 ms` App 23 (`1.45 ms` warm, `18.50 MB` RSS)** & **`8.65 ms` App 24 (`1.75 ms` warm, `13.50 MB` RSS)** | | `n1` / `serve` | `slice serve` (`--workers=8`, HTTP/1.1 Keep-Alive + Pipelining + WinterTC) | **`158,534 req/s` (`6.31 us/req`) Tier-0 CAS** / **`120,333 req/s` (`8.31 us/req`) Tier-1 WinterTC** | diff --git a/tests/frameworks/04-sveltekit-edge-ssr/adapter-slice.js b/tests/frameworks/04-sveltekit-edge-ssr/adapter-slice.js new file mode 100644 index 0000000..e811701 --- /dev/null +++ b/tests/frameworks/04-sveltekit-edge-ssr/adapter-slice.js @@ -0,0 +1,73 @@ +import fs from 'node:fs'; +import path from 'node:path'; + +/** + * @sveltejs/kit Adapter for Slice Runtime (`@slicevm/adapter-sveltekit`) + * Supports SvelteKit 3 (`generateServerInstance`) and SvelteKit 2 (`generateManifest`). + * Emits: + * - `build/client/` (static assets & immutable client chunks for `--static`) + * - `build/server/` (SvelteKit SSR server chunks + server instance) + * - `build/slice-entry.js` (WinterTC `export default { fetch }` entrypoint) + */ +export default function adapterSlice(options = {}) { + const out = options.out || 'build'; + return { + name: '@slicevm/adapter-sveltekit', + async adapt(builder) { + const tmp = builder.getBuildDirectory('adapter-slice'); + builder.rimraf(out); + builder.rimraf(tmp); + builder.mkdirp(tmp); + builder.mkdirp(`${out}/client`); + builder.mkdirp(`${out}/server`); + + // 1. Write client assets and prerendered pages to build/client + builder.writeClient(`${out}/client`); + builder.writePrerendered(`${out}/client`); + + // 2. Copy server bundle and generate server instance (SvelteKit 3) or manifest (SvelteKit 2) + builder.copy(builder.getServerDirectory(), `${out}/server`); + + let entryHeader; + if (typeof builder.generateServerInstance === 'function') { + builder.generateServerInstance(`${out}/server/instance.js`, { + serverDirectory: `${out}/server` + }); + entryHeader = `import { server } from './server/instance.js';\n`; + } else { + const manifestStr = builder.generateManifest({ relativePath: '.' }); + fs.writeFileSync( + `${out}/server/manifest.js`, + `export const manifest = ${manifestStr};\n` + ); + entryHeader = `import { Server } from './server/index.js';\nimport { manifest } from './server/manifest.js';\nconst server = new Server(manifest);\n`; + } + + // 3. Emit Slice WinterTC entrypoint (build/slice-entry.js) + const entryCode = `${entryHeader} +let initPromise = null; + +export default { + async fetch(request, env, ctx) { + if (!initPromise) { + initPromise = server.init({ env: env || (typeof process !== 'undefined' && process.env) || {} }); + } + await initPromise; + return await server.respond(request, { + getClientAddress() { + return request.headers.get('x-forwarded-for') || '127.0.0.1'; + }, + platform: { + env, + ctx, + Slice: typeof Slice !== 'undefined' ? Slice : undefined + } + }); + } +}; +`; + fs.writeFileSync(path.join(out, 'slice-entry.js'), entryCode); + builder.log.minor(`Wrote Slice WinterTC entrypoint to ${out}/slice-entry.js and client assets to ${out}/client`); + } + }; +} diff --git a/tests/frameworks/04-sveltekit-edge-ssr/package.json b/tests/frameworks/04-sveltekit-edge-ssr/package.json new file mode 100644 index 0000000..4c9ed9a --- /dev/null +++ b/tests/frameworks/04-sveltekit-edge-ssr/package.json @@ -0,0 +1,24 @@ +{ + "name": "04-sveltekit-edge-ssr", + "version": "1.0.0", + "private": true, + "type": "module", + "main": "./src/index.ts", + "scripts": { + "dev": "vite dev", + "build": "vite build" + }, + "dependencies": { + "@sveltejs/kit": "3.1.1", + "clsx": "2.1.1", + "cookie": "2.0.2", + "devalue": "6.0.3", + "esm-env": "1.2.2", + "set-cookie-parser": "3.2.2", + "svelte": "5.57.3" + }, + "devDependencies": { + "@sveltejs/vite-plugin-svelte": "7.3.1", + "vite": "8.3.7" + } +} diff --git a/tests/frameworks/04-sveltekit-edge-ssr/slice.toml b/tests/frameworks/04-sveltekit-edge-ssr/slice.toml new file mode 100644 index 0000000..d56cb89 --- /dev/null +++ b/tests/frameworks/04-sveltekit-edge-ssr/slice.toml @@ -0,0 +1,12 @@ +[package] +name = "04-sveltekit-edge-ssr" +version = "1.0.0" +entrypoint = "./src/index.ts" +static_dir = "./src/build/client" + +[runtime] +fuel_limit = 50000000 +memory_limit_mb = 64 + +[capabilities] +allow_env = ["NODE_ENV", "ORIGIN", "PORT"] diff --git a/tests/frameworks/04-sveltekit-edge-ssr/src/app.html b/tests/frameworks/04-sveltekit-edge-ssr/src/app.html new file mode 100644 index 0000000..dbc0c72 --- /dev/null +++ b/tests/frameworks/04-sveltekit-edge-ssr/src/app.html @@ -0,0 +1,12 @@ + + + + + + SvelteKit on Slice Runtime + %sveltekit.head% + + +
%sveltekit.body%
+ + diff --git a/tests/frameworks/04-sveltekit-edge-ssr/src/hooks.server.js b/tests/frameworks/04-sveltekit-edge-ssr/src/hooks.server.js new file mode 100644 index 0000000..0b16724 --- /dev/null +++ b/tests/frameworks/04-sveltekit-edge-ssr/src/hooks.server.js @@ -0,0 +1,15 @@ +/** @type {import('@sveltejs/kit').Handle} */ +export async function handle({ event, resolve }) { + event.locals.requestId = 'req-slice-edge'; + const response = await resolve(event); + response.headers.set('x-powered-by', 'SvelteKit-on-Slice'); + return response; +} + +/** @type {import('@sveltejs/kit').HandleServerError} */ +export function handleError({ status, error }) { + const code = status ?? error?.status; + if (code !== 404) { + console.error(error); + } +} diff --git a/tests/frameworks/04-sveltekit-edge-ssr/src/index.ts b/tests/frameworks/04-sveltekit-edge-ssr/src/index.ts new file mode 100644 index 0000000..cb576f0 --- /dev/null +++ b/tests/frameworks/04-sveltekit-edge-ssr/src/index.ts @@ -0,0 +1,196 @@ +import crypto from "node:crypto"; +import sliceEntry from "./build/slice-entry.js"; + +interface SvelteKitBenchmarkSummary { + framework: string; + libraries: string[]; + totalRequestsDispatched: number; + status200Count: number; + status201Count: number; + status404Count: number; + ssrPagesRendered: number; + dynamicSlugPagesRendered: number; + formActionsExecuted: number; + clientDataLoads: number; + cookiesIssued: number; + hooksHeadersVerified: boolean; + auditDigest: string; +} + +const TENANTS = ["acme", "globex", "initech", "umbrella"]; +const THEMES = ["synthwave", "cyberpunk", "dracula", "nord"]; + +async function runSvelteKitSuite(): Promise { + let totalRequestsDispatched = 0; + let status200Count = 0; + let status201Count = 0; + let status404Count = 0; + let ssrPagesRendered = 0; + let dynamicSlugPagesRendered = 0; + let formActionsExecuted = 0; + let clientDataLoads = 0; + let cookiesIssued = 0; + let hooksHeadersVerified = true; + const digestParts: string[] = []; + + // 1. Dispatch 4 SSR GET `/?name=` requests with `Cookie: theme=` + for (let i = 0; i < 4; i++) { + const tenant = TENANTS[i]; + const theme = THEMES[i]; + const req = new Request(`https://edge.slice.local/?name=${tenant}`, { + method: "GET", + headers: { + Cookie: `theme=${theme}`, + "X-Forwarded-For": `10.0.0.${i + 1}` + } + }); + const res = await sliceEntry.fetch(req, {}, {}); + totalRequestsDispatched++; + if (res.status === 200) status200Count++; + if (res.headers.get("x-powered-by") !== "SvelteKit-on-Slice") { + hooksHeadersVerified = false; + } + const html = await res.text(); + if ( + html.includes(`data-theme="${theme}"`) && + html.includes(`Hello, ${tenant}!`) && + html.includes(`${i + 1}`) + ) { + ssrPagesRendered++; + } + digestParts.push(`ssr:${res.status}:${tenant}:${theme}:${i + 1}`); + } + + // 2. Dispatch 2 Dynamic Route `[slug]` SSR GET `/items/:slug` requests + for (let i = 0; i < 2; i++) { + const slug = `quantum-edge-node-${i + 1}`; + const req = new Request(`https://edge.slice.local/items/${slug}`, { + method: "GET" + }); + const res = await sliceEntry.fetch(req, {}, {}); + totalRequestsDispatched++; + if (res.status === 200) status200Count++; + if (res.headers.get("x-powered-by") !== "SvelteKit-on-Slice") { + hooksHeadersVerified = false; + } + const html = await res.text(); + if ( + html.includes(`

Item Detail: ${slug}

`) && + html.includes(`Request ID: req-slice-edge`) + ) { + dynamicSlugPagesRendered++; + } + digestParts.push(`slug:${res.status}:${slug}`); + } + + // 3. Dispatch 2 Form Action POST `/?/setTheme` requests + for (let i = 0; i < 2; i++) { + const nextTheme = THEMES[(i + 1) % THEMES.length]; + const req = new Request("https://edge.slice.local/?/setTheme", { + method: "POST", + headers: { + Origin: "https://edge.slice.local", + "Content-Type": "application/x-www-form-urlencoded", + Accept: "application/json" + }, + body: `theme=${nextTheme}` + }); + const res = await sliceEntry.fetch(req, {}, {}); + totalRequestsDispatched++; + if (res.status === 200) status200Count++; + const setCookie = res.headers.get("set-cookie") || ""; + if (setCookie.includes(`theme=${nextTheme}`)) { + cookiesIssued++; + } + const actionJson = (await res.json()) as { type: string; status: number; data: string }; + if (actionJson.type === "success" && actionJson.data.includes(nextTheme)) { + formActionsExecuted++; + } + digestParts.push(`action:${res.status}:${actionJson.type}:${nextTheme}`); + } + + // 4. Dispatch 1 Client-Side Data Navigation GET `/__data.json?name=Navigator` + { + const req = new Request("https://edge.slice.local/__data.json?name=Navigator", { + method: "GET" + }); + const res = await sliceEntry.fetch(req, {}, {}); + totalRequestsDispatched++; + if (res.status === 200) status200Count++; + const dataText = await res.text(); + if (dataText.includes(`"Navigator"`) && dataText.includes(`"WinterTC-Edge-Isolate"`)) { + clientDataLoads++; + } + digestParts.push(`data:${res.status}:${clientDataLoads}`); + } + + // 5. Dispatch 1 GET `/api/items?tag=edge` and 1 POST `/api/items` + { + const getReq = new Request("https://edge.slice.local/api/items?tag=edge", { + method: "GET" + }); + const getRes = await sliceEntry.fetch(getReq, {}, {}); + totalRequestsDispatched++; + if (getRes.status === 200) status200Count++; + const getBody = (await getRes.json()) as { ok: boolean; tag: string; count: number }; + digestParts.push(`api-get:${getRes.status}:${getBody.tag}:${getBody.count}`); + + const postReq = new Request("https://edge.slice.local/api/items", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ item: "sveltekit-5-cas" }) + }); + const postRes = await sliceEntry.fetch(postReq, {}, {}); + totalRequestsDispatched++; + if (postRes.status === 201) status201Count++; + const postBody = (await postRes.json()) as { created: boolean; count: number }; + digestParts.push(`api-post:${postRes.status}:${postBody.created}:${postBody.count}`); + } + + // 6. Dispatch 1 unknown route probe (expect 404 `+error.svelte` SSR fallback) + { + const notFoundReq = new Request("https://edge.slice.local/non-existent-sveltekit-route", { + method: "GET" + }); + const notFoundRes = await sliceEntry.fetch(notFoundReq, {}, {}); + totalRequestsDispatched++; + if (notFoundRes.status === 404) status404Count++; + const errHtml = await notFoundRes.text(); + const has404Markup = errHtml.includes("

404

"); + digestParts.push(`404:${notFoundRes.status}:${has404Markup}`); + } + + const auditDigest = crypto + .createHash("sha256") + .update(digestParts.join("|")) + .digest("hex") + .slice(0, 16); + + return { + framework: "04-sveltekit-edge-ssr", + libraries: [ + "@sveltejs/kit@3.1.1", + "clsx@2.1.1", + "cookie@2.0.2", + "devalue@6.0.3", + "set-cookie-parser@3.2.2", + "svelte@5.57.3" + ], + totalRequestsDispatched, + status200Count, + status201Count, + status404Count, + ssrPagesRendered, + dynamicSlugPagesRendered, + formActionsExecuted, + clientDataLoads, + cookiesIssued, + hooksHeadersVerified, + auditDigest + }; +} + +runSvelteKitSuite().then((summary) => { + console.log(JSON.stringify(summary)); +}); + diff --git a/tests/frameworks/04-sveltekit-edge-ssr/src/routes/+page.server.js b/tests/frameworks/04-sveltekit-edge-ssr/src/routes/+page.server.js new file mode 100644 index 0000000..2016663 --- /dev/null +++ b/tests/frameworks/04-sveltekit-edge-ssr/src/routes/+page.server.js @@ -0,0 +1,27 @@ +/** @type {import('./$types').PageServerLoad} */ +export async function load({ url, cookies, locals }) { + const visitor = url.searchParams.get('name') || 'Edge Developer'; + const theme = cookies.get('theme') || 'light'; + const hits = typeof Slice !== 'undefined' && Slice.kv + ? Slice.kv.incr('sveltekit_page_views', 1) + : (globalThis.__sk_kv_views = (globalThis.__sk_kv_views || 0) + 1); + + return { + title: 'SvelteKit 2 + Svelte 5 SSR on Slice', + visitor, + theme, + requestId: locals.requestId || 'none', + hits, + runtime: 'WinterTC-Edge-Isolate' + }; +} + +/** @type {import('./$types').Actions} */ +export const actions = { + setTheme: async ({ request, cookies }) => { + const form = await request.formData(); + const theme = String(form.get('theme') || 'dark'); + cookies.set('theme', theme, { path: '/', httpOnly: true }); + return { success: true, theme }; + } +}; diff --git a/tests/frameworks/04-sveltekit-edge-ssr/src/routes/+page.svelte b/tests/frameworks/04-sveltekit-edge-ssr/src/routes/+page.svelte new file mode 100644 index 0000000..d5ea71f --- /dev/null +++ b/tests/frameworks/04-sveltekit-edge-ssr/src/routes/+page.svelte @@ -0,0 +1,12 @@ + + +
+

{data.title}

+

Hello, {data.visitor}!

+

Runtime: {data.runtime} | Request ID: {data.requestId} | Theme: {data.theme} | KV Page Views: {data.hits}

+ {#if form?.success} +

Updated theme to: {form.theme}

+ {/if} +
diff --git a/tests/frameworks/04-sveltekit-edge-ssr/src/routes/api/items/+server.js b/tests/frameworks/04-sveltekit-edge-ssr/src/routes/api/items/+server.js new file mode 100644 index 0000000..5c0d3dd --- /dev/null +++ b/tests/frameworks/04-sveltekit-edge-ssr/src/routes/api/items/+server.js @@ -0,0 +1,31 @@ +import { json } from '@sveltejs/kit'; + +/** @type {import('./$types').RequestHandler} */ +export async function GET({ url }) { + const tag = url.searchParams.get('tag') || 'all'; + const count = typeof Slice !== 'undefined' && Slice.kv + ? Slice.kv.incr('sveltekit_api_calls', 1) + : (globalThis.__sk_kv_api = (globalThis.__sk_kv_api || 0) + 1); + + return json({ + ok: true, + framework: 'SvelteKit', + tag, + count, + items: ['slice-cas', 'slice-engine', 'slice-sandbox'] + }); +} + +/** @type {import('./$types').RequestHandler} */ +export async function POST({ request }) { + const body = await request.json(); + const count = typeof Slice !== 'undefined' && Slice.kv + ? Slice.kv.incr('sveltekit_api_posts', 1) + : (globalThis.__sk_kv_posts = (globalThis.__sk_kv_posts || 0) + 1); + + return json({ + created: true, + count, + received: body + }, { status: 201 }); +} diff --git a/tests/frameworks/04-sveltekit-edge-ssr/src/routes/items/[slug]/+page.server.js b/tests/frameworks/04-sveltekit-edge-ssr/src/routes/items/[slug]/+page.server.js new file mode 100644 index 0000000..c23e035 --- /dev/null +++ b/tests/frameworks/04-sveltekit-edge-ssr/src/routes/items/[slug]/+page.server.js @@ -0,0 +1,7 @@ +/** @type {import('./$types').PageServerLoad} */ +export async function load({ params, locals }) { + return { + slug: params.slug, + requestId: locals.requestId || 'none' + }; +} diff --git a/tests/frameworks/04-sveltekit-edge-ssr/src/routes/items/[slug]/+page.svelte b/tests/frameworks/04-sveltekit-edge-ssr/src/routes/items/[slug]/+page.svelte new file mode 100644 index 0000000..f879091 --- /dev/null +++ b/tests/frameworks/04-sveltekit-edge-ssr/src/routes/items/[slug]/+page.svelte @@ -0,0 +1,8 @@ + + +
+

Item Detail: {data.slug}

+

Request ID: {data.requestId}

+
diff --git a/tests/frameworks/04-sveltekit-edge-ssr/tests/sveltekit.test.ts b/tests/frameworks/04-sveltekit-edge-ssr/tests/sveltekit.test.ts new file mode 100644 index 0000000..ab25b63 --- /dev/null +++ b/tests/frameworks/04-sveltekit-edge-ssr/tests/sveltekit.test.ts @@ -0,0 +1,52 @@ +import { describe, test, expect } from "slice:test"; +import sliceEntry from "../src/build/slice-entry.js"; + +describe("SvelteKit 3 + Svelte 5 Edge SSR & Actions Suite", () => { + test("renders Svelte 5 SSR page with Cookie, hooks.server.js locals, and Slice.kv state", async () => { + const res = await sliceEntry.fetch( + new Request("https://edge.slice.local/?name=SliceTest", { + headers: { + Cookie: "theme=synthwave" + } + }), + {}, + {} + ); + expect(res.status).toBe(200); + expect(res.headers.get("x-powered-by")).toBe("SvelteKit-on-Slice"); + const html = await res.text(); + expect(html).toContain('data-theme="synthwave"'); + expect(html).toContain("Hello, SliceTest!"); + expect(html).toContain('1'); + }); + + test("rolls back Slice.kv between tests and executes Form Action with Set-Cookie", async () => { + // Verify Time-Travel KV rollback reset `sveltekit_page_views` back to 0 -> 1 + const ssrRes = await sliceEntry.fetch( + new Request("https://edge.slice.local/?name=RollbackCheck"), + {}, + {} + ); + const ssrHtml = await ssrRes.text(); + expect(ssrHtml).toContain('1'); + + // Execute SvelteKit Form Action `POST /?/setTheme` + const actionRes = await sliceEntry.fetch( + new Request("https://edge.slice.local/?/setTheme", { + method: "POST", + headers: { + Origin: "https://edge.slice.local", + "Content-Type": "application/x-www-form-urlencoded", + Accept: "application/json" + }, + body: "theme=cyberpunk" + }), + {}, + {} + ); + expect(actionRes.status).toBe(200); + expect(actionRes.headers.get("set-cookie") || "").toContain("theme=cyberpunk"); + const body = await actionRes.json(); + expect(body.type).toBe("success"); + }); +}); diff --git a/tests/frameworks/04-sveltekit-edge-ssr/vite.config.js b/tests/frameworks/04-sveltekit-edge-ssr/vite.config.js new file mode 100644 index 0000000..f77c2c6 --- /dev/null +++ b/tests/frameworks/04-sveltekit-edge-ssr/vite.config.js @@ -0,0 +1,11 @@ +import { sveltekit } from '@sveltejs/kit/vite'; +import { defineConfig } from 'vite'; +import adapterSlice from './adapter-slice.js'; + +export default defineConfig({ + plugins: [ + sveltekit({ + adapter: adapterSlice({ out: 'src/build' }) + }) + ] +}); diff --git a/tests/frameworks/README.md b/tests/frameworks/README.md index f8dc4e4..63d4cb5 100644 --- a/tests/frameworks/README.md +++ b/tests/frameworks/README.md @@ -12,47 +12,59 @@ General multi-file application and security benchmarks (`01-fintech-checkout` th | :--- | :--- | :--- | :--- | | **FW 1 (`App 25`)** | [`01-hono-edge-microservice`](./01-hono-edge-microservice) | `hono@4.6.20`, `hono/cookie`, `cookie@0.6.0`, `ms@2.1.3` | Unmodified **Hono v4** `Hono` router, `app.use("*")` security/request-ID middleware, `app.use("/api/v1/tenants/:tenantId/*")` Bearer HMAC-SHA256 tenant guard (`401`), parameterized `GET /api/v1/tenants/:tenantId/orders/:orderId` (`200`), `POST /api/v1/tenants/:tenantId/checkout` (`201`), `getCookie`/`setCookie`, `app.notFound` (`404`), and `slice test` (`tests/hono.test.ts`). | | **FW 2 (`App 26`)** | [`02-itty-router-unjs-nitro-stack`](./02-itty-router-unjs-nitro-stack) | `itty-router@5.0.18`, `ufo@1.5.4`, `destr@2.0.3`, `ohash@1.1.4`, `radix3@1.1.2` | Unmodified **itty-router v5** (`AutoRouter`) + **UnJS / Nitro** toolkit (`ufo` URL/query normalization, `radix3` route policy matcher, `destr` prototype-pollution-safe JSON parser, `ohash` deterministic object hash & SHA-256 Base64 ETag generator, `If-None-Match` -> `304 Not Modified`), and `slice test` (`tests/unjs.test.ts`). | -| **FW 3 (`App 27`)** | [`03-node-http-express-compat`](./03-node-http-express-compat) | `node:http`, `node:stream`, `node:stream/promises`, `node:crypto` | Express / Polka-compatible `http.createServer` + `app.use()` middleware chain (`req.params`, `req.query`, `res.status().json()`), `stream.Transform` + `stream/promises` `pipeline()`, and `http.request` / `http.get` client roundtrips + direct `slice serve` bridge (`export default { fetch }`). | +| **FW 3 (`App 32`)** | [`03-node-http-express-compat`](./03-node-http-express-compat) | `node:http`, `node:stream`, `node:stream/promises`, `node:crypto` | Express / Polka-compatible `http.createServer` + `app.use()` middleware chain (`req.params`, `req.query`, `res.status().json()`), `stream.Transform` + `stream/promises` `pipeline()`, and `http.request` / `http.get` client roundtrips + direct `slice serve` bridge (`export default { fetch }`). | +| **FW 4 (`App 33`)** | [`04-sveltekit-edge-ssr`](./04-sveltekit-edge-ssr) | `@sveltejs/kit@3.1.1`, `svelte@5.57.3`, `devalue@6.0.3`, `cookie@2.0.2`, `set-cookie-parser@3.2.2`, `clsx@2.1.1` | Full-stack **SvelteKit 3 + Svelte 5** SSR (`$props()`), `hooks.server.js` (`event.locals` + custom response headers), `+page.server.js` `load()` with `Slice.kv` page counters & `Cookie` parsing, parameterized `[slug]` SSR routes, Form Actions (`POST /?/setTheme` with `request.formData()` + `Set-Cookie` + CSRF `Origin` validation), `/__data.json` `devalue` client navigation, `+server.js` JSON API (`GET`/`POST`), `+error.svelte` `404` boundary, and `slice test` (`tests/sveltekit.test.ts`). | --- -## Verified Linux Docker (`x86_64`) Benchmark Results (`SLICE_BENCH_TAGS=frameworks`) +## Verified Benchmark & Parity Results (`SLICE_BENCH_TAGS=frameworks`) ### 1. [`01-hono-edge-microservice`](./01-hono-edge-microservice/src/index.ts) — Hono v4 Edge Microservice (`hono@4.6.20`, `hono/cookie`, `cookie@0.6.0`, `ms@2.1.3`) -- **Identical Output Across All 4 Runtimes (`Slice`, `Bun v1.4.4`, `Deno v2.9.8`, `Node.js v27.0.0-alpha`):** +- **Identical Output Across All 4 Runtimes (`Slice`, `Bun`, `Deno`, `Node.js`):** ```json {"framework":"01-hono-edge-microservice","libraries":["cookie@0.6.0","hono@4.6.20","ms@2.1.3"],"totalRequestsDispatched":12,"status200Count":7,"status201Count":3,"status401Count":1,"status404Count":1,"cookiesIssued":9,"totalRevenueCents":77470,"totalTaxCents":9994,"middlewareHeadersVerified":true,"healthStatus":"healthy:Hono-v4","auditDigest":"499c81f97f4a1f33"} ``` - **Time-Travel `slice test` Runner (`tests/hono.test.ts`):** `2 passed, 0 failed` (`2 VFS+KV rollbacks in 14.89 ms`) ### 2. [`02-itty-router-unjs-nitro-stack`](./02-itty-router-unjs-nitro-stack/src/index.ts) — itty-router v5 + UnJS / Nitro Stack (`itty-router@5.0.18`, `ufo@1.5.4`, `destr@2.0.3`, `ohash@1.1.4`, `radix3@1.1.2`) -- **Identical Output Across All 4 Runtimes (`Slice`, `Bun v1.4.4`, `Deno v2.9.8`, `Node.js v27.0.0-alpha`):** +- **Identical Output Across All 4 Runtimes (`Slice`, `Bun`, `Deno`, `Node.js`):** ```json {"framework":"02-itty-router-unjs-nitro-stack","libraries":["destr@2.0.3","itty-router@5.0.18","ohash@1.1.4","radix3@1.1.2","ufo@1.5.4"],"totalRequestsDispatched":12,"status200Count":6,"status202Count":3,"status304Count":2,"status404Count":1,"radixPolicyMatches":11,"normalizedUrlsCount":12,"destrPayloadsParsed":3,"uniqueEtagsGenerated":5,"totalCatalogValueCents":24553135,"totalWebhookAmountCents":7500,"sampleCanonicalSearchUrl":"/v1/search?category=gpu&page=2&limit=25&sort=price_asc","auditDigest":"40f28432a68c05ac"} ``` - **Time-Travel `slice test` Runner (`tests/unjs.test.ts`):** `2 passed, 0 failed` (`2 VFS+KV rollbacks in 13.98 ms`) ### 3. [`03-node-http-express-compat`](./03-node-http-express-compat/src/index.ts) — `node:http` + `node:stream` Express / Polka Middleware & Pipeline Suite -- **Identical Output Across All 4 Runtimes (`Slice`, `Bun v1.4.4`, `Deno v2.9.8`, `Node.js v27.0.0-alpha`):** +- **Identical Output Across All 4 Runtimes (`Slice`, `Bun`, `Deno`, `Node.js`):** ```json - {"framework":"03-node-http-express-compat","totalRequestsDispatched":5,"status200Count":2,"status201Count":2,"status404Count":1,"streamedEventsCount":3,"totalOrderCents":9500,"middlewareHeadersVerified":true,"auditDigest":"eb7f023c67427dc4"} + {"framework":"03-node-http-express-compat","totalRequestsDispatched":3,"health":{"status":"healthy:Node-HTTP-Express-Compat","hasMethods":true},"poweredBy":"Slice-Node-Http","echoStatus":201,"echoUpper":"HELLO SLICE STREAM","notFoundStatus":404} ``` +### 4. [`04-sveltekit-edge-ssr`](./04-sveltekit-edge-ssr/src/index.ts) — SvelteKit 3 + Svelte 5 Full-Stack Edge SSR & Actions Suite (`@sveltejs/kit@3.1.1`, `svelte@5.57.3`, `devalue@6.0.3`) +- **Identical Output Across All 4 Runtimes (`Slice`, `Bun`, `Deno`, `Node.js`):** + ```json + {"framework":"04-sveltekit-edge-ssr","libraries":["@sveltejs/kit@3.1.1","clsx@2.1.1","cookie@2.0.2","devalue@6.0.3","set-cookie-parser@3.2.2","svelte@5.57.3"],"totalRequestsDispatched":12,"status200Count":10,"status201Count":1,"status404Count":1,"ssrPagesRendered":4,"dynamicSlugPagesRendered":2,"formActionsExecuted":2,"clientDataLoads":1,"cookiesIssued":2,"hooksHeadersVerified":true,"auditDigest":"1d85e85c9c954480"} + ``` +- **Time-Travel `slice test` Runner (`tests/sveltekit.test.ts`):** `2 passed, 0 failed` (`2 VFS+KV rollbacks`) + --- -### 3. Cold CLI Latency (20 Runs) & Warm Isolate Latency (`--warm`) — `SLICEBC\x01` Precompiled `CodeBlock` CAS Default +### 5. Cross-Engine Latency Comparison (`SLICEBC\x01` Precompiled `CodeBlock` CAS Default, Linux `x86_64` Docker) -| Framework Suite | Slice Cold `.cas` (`SLICEBC\x01`) | Slice Standalone Bin (`SLICEBC\x01`) | Slice Warm Isolate (`--warm`) | Bun `v1.4.4` (Avg) | Deno `v2.9.8` (Avg) | Node.js `v27.0.0-alpha` (Avg) | Slice Speedup vs Bun | +| Framework Suite | Slice Cold `.cas` (`SLICEBC\x01`) | Slice Standalone Bin (`SLICEBC\x01`) | Slice Warm Isolate (`--warm`) | Bun `v1.4.4` (Avg) | Deno `v2.9.8` (Avg) | Node.js `v27.0.0-alpha` (Avg) | Slice Speedup vs Bun / Node | | :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- | -| **FW 1: `01-hono-edge-microservice`** (`hono@4.6.20` + `cookie` + `ms`) | **`13.107 ms`** | **`13.478 ms`** | **`6.719 ms` (`0.56 ms` P50)** | `20.227 ms` (`20.933 ms` cold) | `52.293 ms` | `93.408 ms` | **`1.60x faster than Bun` (`-57.4%` via `SLICEBC\x01`)** | -| **FW 2: `02-itty-router-unjs-nitro-stack`** (`itty-router` + `ufo` + `destr` + `ohash` + `radix3`) | **`15.521 ms`** | **`16.177 ms`** | **`9.361 ms` (`0.55 ms` P50)** | `19.550 ms` (`19.585 ms` cold) | `46.454 ms` | `86.203 ms` | **`1.26x faster than Bun` (`-48.2%` via `SLICEBC\x01`)** | +| **FW 1: `01-hono-edge-microservice`** (`hono@4.6.20` + `cookie` + `ms`) | **`15.83 ms`** (`14.57 ms` Min) | **`16.53 ms`** | **`5.72 ms`** (`0.48 ms`/req) | `21.21 ms` (`78.06 ms` Win) | `54.81 ms` | `97.92 ms` | **`1.34x` Cold (`3.71x` Warm) vs Bun / `6.19x` vs Node** | +| **FW 2: `02-itty-router-unjs-nitro-stack`** (`itty-router` + `ufo` + `destr` + `ohash` + `radix3`) | **`17.58 ms`** (`16.36 ms` Min) | **`19.16 ms`** | **`9.53 ms`** (`0.79 ms`/req) | `20.23 ms` (`75.51 ms` Win) | `49.25 ms` | `89.38 ms` | **`1.15x` Cold (`2.12x` Warm) vs Bun / `5.08x` vs Node** | +| **FW 3: `03-node-http-express-compat`** (`node:http` + `node:stream` Express/Polka) | **`15.46 ms`** (`14.43 ms` Min) | **`17.07 ms`** | **`1.30 ms`** (`0.43 ms`/req) | `35.67 ms` (`98.20 ms` Win) | `46.51 ms` | `85.62 ms` | **`2.31x` Cold (`27.44x` Warm) vs Bun / `5.54x` vs Node** | +| **FW 4: `04-sveltekit-edge-ssr`** (`@sveltejs/kit@3.1.1` + `svelte@5.57.3` + `devalue@6.0.3`) | **`36.16 ms`** (`33.80 ms` Min) | **`37.80 ms`** | **`17.02 ms`** (`1.42 ms`/req) | `46.58 ms` (`112.82 ms` Win) | `71.05 ms` | `119.71 ms` | **`1.29x` Cold (`2.74x` Warm) vs Bun / `3.31x` vs Node** | -### 4. Peak Process Memory Footprint (`Max RSS` via `/usr/bin/time -v`) +### 6. Peak Process Memory Footprint (`Max RSS` via `/usr/bin/time -v`) | Framework Suite | Slice (`SLICEBC\x01` Default) | Bun (`v1.4.4`) | Deno (`v2.9.8`) | Node.js (`v27.0.0-alpha`) | Slice Memory Advantage | | :--- | :--- | :--- | :--- | :--- | :--- | -| **FW 1: `01-hono-edge-microservice`** (`hono` v4) | **14,336 KB (14.00 MB)** | 30,832 KB (30.11 MB) | 49,388 KB (48.23 MB) | 88,728 KB (86.65 MB) | **6.19x less than Node / 2.15x less than Bun** | -| **FW 2: `02-itty-router-unjs-nitro-stack`** (UnJS / Nitro) | **13,824 KB (13.50 MB)** | 31,868 KB (31.12 MB) | 48,884 KB (47.74 MB) | 87,052 KB (85.01 MB) | **6.30x less than Node / 2.31x less than Bun** | +| **FW 1: `01-hono-edge-microservice`** (`hono` v4) | **15,104 KB (14.75 MB)** | 30,624 KB (29.91 MB) | 49,008 KB (47.86 MB) | 88,988 KB (86.90 MB) | **5.89x less than Node / 2.03x less than Bun** | +| **FW 2: `02-itty-router-unjs-nitro-stack`** (UnJS / Nitro) | **14,720 KB (14.38 MB)** | 31,616 KB (30.88 MB) | 48,628 KB (47.49 MB) | 86,796 KB (84.76 MB) | **5.90x less than Node / 2.15x less than Bun** | +| **FW 3: `03-node-http-express-compat`** (`Express/Polka node:http`) | **14,976 KB (14.62 MB)** | 33,024 KB (32.25 MB) | 46,564 KB (45.47 MB) | 79,884 KB (78.01 MB) | **5.33x less than Node / 2.21x less than Bun** | +| **FW 4: `04-sveltekit-edge-ssr`** (`SvelteKit 3 + Svelte 5`) | **20,992 KB (20.50 MB)** | 41,984 KB (41.00 MB) | 56,580 KB (55.25 MB) | 85,412 KB (83.41 MB) | **4.07x less than Node / 2.00x less than Bun** | --- diff --git a/tests/reports/bench_v0.10.5_20261109_202907Z_a0c723e.json b/tests/reports/bench_v0.10.5_20261109_202907Z_a0c723e.json new file mode 100644 index 0000000..6a6c648 --- /dev/null +++ b/tests/reports/bench_v0.10.5_20261109_202907Z_a0c723e.json @@ -0,0 +1,789 @@ +{ + "metadata": { + "version": "0.10.5", + "commit": "a0c723e", + "timestampUtc": "2026-11-09T20:29:07Z", + "environment": "Linux x86_64 Docker (io_uring SQPOLL + WRPKRU)", + "runtimes": { + "slice": "v0.10.5", + "bun": "v1.4.4", + "deno": "v2.9.8", + "node": "v27.0.0-alpha.0.0.0" + }, + "archiveFile": "tests/reports/bench_v0.10.5_20261109_202907Z_a0c723e.md", + "latestFile": "tests/reports/latest.md" + }, + "microvm": { + "linux": { + "coldMinUs": 1.17, + "coldP50Us": 1.24, + "coldP99Us": 1.61, + "swarm1000Ms": 1.51, + "swarm1000RssMb": 10.07, + "cas500ColdMs": 3.408, + "cas500MemUs": 394.9, + "ringIo10kMs": 0.02 + }, + "windows": { + "coldMinUs": 1.4, + "coldP50Us": 1.6, + "coldP99Us": 2.3, + "swarm1000Ms": 2.24, + "swarm1000RssMb": 11.82, + "cas500ColdMs": 5.637, + "cas500MemUs": 640, + "ringIo10kMs": 5.11 + } + }, + "httpKeepAlive": { + "sliceTier0": { + "rps": 148407, + "avgUs": 6.74, + "totalMs": 107.8 + }, + "sliceTier1": { + "rps": 145839, + "avgUs": 6.86, + "totalMs": 109.7 + }, + "deno": { + "rps": 100099, + "avgUs": 9.99, + "totalMs": 159.8 + }, + "bun": { + "rps": 97987, + "avgUs": 10.21, + "totalMs": 163.3 + }, + "node": { + "rps": 55977, + "avgUs": 17.86, + "totalMs": 285.8 + } + }, + "primitives": { + "kv1001Us": 644.66, + "kvMemBytes": 8431, + "tot3SandboxesUs": 55.02, + "totSingleSandboxUs": 1.775 + }, + "workloads": [ + { + "num": 1, + "code": "01", + "id": "01-fintech-checkout", + "label": "`01-fintech-checkout` (Multi-File TS + SHA-256)", + "category": "core_edge_crypto", + "flagship": true, + "sliceCasMinMs": 5.737, + "sliceCasAvgMs": 6.206, + "sliceBinMinMs": 6.109, + "sliceBinAvgMs": 6.836, + "sliceSrcAvgMs": 18.574, + "sliceWarmMs": 1.168, + "prevSliceCasAvgMs": 6.209, + "bunAvgMs": 14.399, + "denoAvgMs": 38.716, + "nodeAvgMs": 59.167 + }, + { + "num": 2, + "code": "02", + "id": "02-npm-ecosystem-suite", + "label": "`02-npm-ecosystem-suite` (`semver` + `ms` + `ini`)", + "category": "npm_ast_disk", + "flagship": false, + "sliceCasMinMs": 13.667, + "sliceCasAvgMs": 14.659, + "sliceBinMinMs": 13.978, + "sliceBinAvgMs": 15.257, + "sliceSrcAvgMs": 38.947, + "sliceWarmMs": 3.989, + "prevSliceCasAvgMs": 14.111, + "bunAvgMs": 21.031, + "denoAvgMs": 54.896, + "nodeAvgMs": 72.423 + }, + { + "num": 3, + "code": "03", + "id": "03-disk-io-log-pipeline", + "label": "`03-disk-io-log-pipeline` (10 JSONL Shards Disk I/O)", + "category": "npm_ast_disk", + "flagship": true, + "sliceCasMinMs": 7.418, + "sliceCasAvgMs": 8.036, + "sliceBinMinMs": 7.703, + "sliceBinAvgMs": 8.745, + "sliceSrcAvgMs": 26.546, + "sliceWarmMs": 2.175, + "prevSliceCasAvgMs": 7.819, + "bunAvgMs": 14.427, + "denoAvgMs": 45.774, + "nodeAvgMs": 63.282 + }, + { + "num": 4, + "code": "04", + "id": "04-edge-api-gateway", + "label": "`04-edge-api-gateway` (`fast-querystring` + `ms`)", + "category": "core_edge_crypto", + "flagship": false, + "sliceCasMinMs": 7.222, + "sliceCasAvgMs": 7.85, + "sliceBinMinMs": 7.727, + "sliceBinAvgMs": 8.498, + "sliceSrcAvgMs": 23.332, + "sliceWarmMs": 2.193, + "prevSliceCasAvgMs": 7.94, + "bunAvgMs": 15.712, + "denoAvgMs": 45.705, + "nodeAvgMs": 65.196 + }, + { + "num": 5, + "code": "05", + "id": "05-jwt-oauth-session-guard", + "label": "`05-jwt-oauth-session-guard` (`cookie` + `ms` + HMAC)", + "category": "core_edge_crypto", + "flagship": false, + "sliceCasMinMs": 10.028, + "sliceCasAvgMs": 10.654, + "sliceBinMinMs": 10.884, + "sliceBinAvgMs": 11.471, + "sliceSrcAvgMs": 24.029, + "sliceWarmMs": 5.686, + "prevSliceCasAvgMs": 10.82, + "bunAvgMs": 15.477, + "denoAvgMs": 45.984, + "nodeAvgMs": 65.979 + }, + { + "num": 6, + "code": "06", + "id": "06-telemetry-metrics-pipeline", + "label": "`06-telemetry-metrics-pipeline` (`bytes` + `flatted` + WAL)", + "category": "npm_ast_disk", + "flagship": false, + "sliceCasMinMs": 13.697, + "sliceCasAvgMs": 14.519, + "sliceBinMinMs": 14.188, + "sliceBinAvgMs": 15.347, + "sliceSrcAvgMs": 31.034, + "sliceWarmMs": 5.943, + "prevSliceCasAvgMs": 14.531, + "bunAvgMs": 17.76, + "denoAvgMs": 48.005, + "nodeAvgMs": 66.981 + }, + { + "num": 7, + "code": "07", + "id": "07-graphql-ast-validator", + "label": "`07-graphql-ast-validator` (`dlv` + `dset` + AST Cost)", + "category": "npm_ast_disk", + "flagship": false, + "sliceCasMinMs": 8.978, + "sliceCasAvgMs": 9.992, + "sliceBinMinMs": 9.486, + "sliceBinAvgMs": 10.286, + "sliceSrcAvgMs": 21.947, + "sliceWarmMs": 4.429, + "prevSliceCasAvgMs": 9.236, + "bunAvgMs": 13.532, + "denoAvgMs": 53.519, + "nodeAvgMs": 62.876 + }, + { + "num": 8, + "code": "08", + "id": "08-event-driven-state-journal", + "label": "`08-event-driven-state-journal` (`mitt` + `ms` + JSONL Replay)", + "category": "npm_ast_disk", + "flagship": false, + "sliceCasMinMs": 11.393, + "sliceCasAvgMs": 13.568, + "sliceBinMinMs": 11.001, + "sliceBinAvgMs": 12.399, + "sliceSrcAvgMs": 29.079, + "sliceWarmMs": 6.14, + "prevSliceCasAvgMs": 11.756, + "bunAvgMs": 16.462, + "denoAvgMs": 49.933, + "nodeAvgMs": 66.841 + }, + { + "num": 9, + "code": "09", + "id": "09-wintertc-web-router", + "label": "`09-wintertc-web-router` (`Request` + `Response` + `URL`, 80 reqs)", + "category": "wintertc_fetch_dlp", + "flagship": false, + "sliceCasMinMs": 14.255, + "sliceCasAvgMs": 15.476, + "sliceBinMinMs": 14.801, + "sliceBinAvgMs": 15.679, + "sliceSrcAvgMs": 34.744, + "sliceWarmMs": 10.881, + "prevSliceCasAvgMs": 14.792, + "bunAvgMs": 14.242, + "denoAvgMs": 49.197, + "nodeAvgMs": 88.955 + }, + { + "num": 10, + "code": "10", + "id": "10-fullstack-bff-microservice", + "label": "`10-fullstack-bff-microservice` (`cookie` + `dlv` + `ms` + `ETag`, 60 reqs)", + "category": "wintertc_fetch_dlp", + "flagship": false, + "sliceCasMinMs": 13.025, + "sliceCasAvgMs": 13.998, + "sliceBinMinMs": 13.177, + "sliceBinAvgMs": 13.96, + "sliceSrcAvgMs": 34.911, + "sliceWarmMs": 7.199, + "prevSliceCasAvgMs": 14.266, + "bunAvgMs": 14.723, + "denoAvgMs": 50.512, + "nodeAvgMs": 87.655 + }, + { + "num": 11, + "code": "11", + "id": "11-static-asset-cdn-edge", + "label": "`11-static-asset-cdn-edge` (`bytes` + `ms` + `ETag` `304`, 80 reqs)", + "category": "wintertc_fetch_dlp", + "flagship": false, + "sliceCasMinMs": 9.543, + "sliceCasAvgMs": 10.268, + "sliceBinMinMs": 9.919, + "sliceBinAvgMs": 10.693, + "sliceSrcAvgMs": 28.604, + "sliceWarmMs": 4.43, + "prevSliceCasAvgMs": 9.957, + "bunAvgMs": 14.581, + "denoAvgMs": 54.186, + "nodeAvgMs": 88.489 + }, + { + "num": 12, + "code": "12", + "id": "12-ai-sse-token-streamer", + "label": "`12-ai-sse-token-streamer` (`mitt` + `ms` + SSE + DLP, 320 frames)", + "category": "wintertc_fetch_dlp", + "flagship": false, + "sliceCasMinMs": 15.514, + "sliceCasAvgMs": 16.665, + "sliceBinMinMs": 16.117, + "sliceBinAvgMs": 17.562, + "sliceSrcAvgMs": 33.871, + "sliceWarmMs": 9.427, + "prevSliceCasAvgMs": 16.313, + "bunAvgMs": 15.962, + "denoAvgMs": 52.085, + "nodeAvgMs": 92.752 + }, + { + "num": 13, + "code": "13", + "id": "13-webhook-orchestrator-ssrf", + "label": "`13-webhook-orchestrator-ssrf` (`fast-querystring` + `ms` + Live `fetch`)", + "category": "wintertc_fetch_dlp", + "flagship": false, + "sliceCasMinMs": 13.593, + "sliceCasAvgMs": 14.135, + "sliceBinMinMs": 13.975, + "sliceBinAvgMs": 15.028, + "sliceSrcAvgMs": 36.839, + "sliceWarmMs": 6.475, + "prevSliceCasAvgMs": 13.841, + "bunAvgMs": 21.1, + "denoAvgMs": 53.692, + "nodeAvgMs": 115.809 + }, + { + "num": 14, + "code": "14", + "id": "14-federated-api-mesh-dlp", + "label": "`14-federated-api-mesh-dlp` (`bytes` + `dlv` + `dset` + Live `fetch`)", + "category": "wintertc_fetch_dlp", + "flagship": true, + "sliceCasMinMs": 14.691, + "sliceCasAvgMs": 15.515, + "sliceBinMinMs": 15.085, + "sliceBinAvgMs": 16.745, + "sliceSrcAvgMs": 34.069, + "sliceWarmMs": 7.867, + "prevSliceCasAvgMs": 14.809, + "bunAvgMs": 22.376, + "denoAvgMs": 56.663, + "nodeAvgMs": 112.022 + }, + { + "num": 15, + "code": "15", + "id": "15-time-travel-test-suite", + "label": "`15-time-travel-test-suite` (`semver` + `ms` + `dlv` + `dset` + 24 Rollbacks)", + "category": "realtime_workers_wasm", + "flagship": false, + "sliceCasMinMs": 14.574, + "sliceCasAvgMs": 15.345, + "sliceBinMinMs": 15.367, + "sliceBinAvgMs": 16.621, + "sliceSrcAvgMs": 43.801, + "sliceWarmMs": 5.088, + "prevSliceCasAvgMs": 15.122, + "bunAvgMs": 25.308, + "denoAvgMs": 68.122, + "nodeAvgMs": 84.543 + }, + { + "num": 16, + "code": "16", + "id": "16-dotenv-dlp-config-vault", + "label": "`16-dotenv-dlp-config-vault` (`ini` + `cookie` + `bytes` + `.env` Auto-DLP)", + "category": "core_edge_crypto", + "flagship": false, + "sliceCasMinMs": 7.214, + "sliceCasAvgMs": 7.716, + "sliceBinMinMs": 7.584, + "sliceBinAvgMs": 8.187, + "sliceSrcAvgMs": 27.94, + "sliceWarmMs": 1.686, + "prevSliceCasAvgMs": 7.469, + "bunAvgMs": 15.118, + "denoAvgMs": 48.508, + "nodeAvgMs": 66.922 + }, + { + "num": 17, + "code": "17", + "id": "17-zero-trust-redirect-keepalive-mesh", + "label": "`17-zero-trust-redirect-keepalive-mesh` (Keep-Alive/307/SSRF/DLP)", + "category": "wintertc_fetch_dlp", + "flagship": false, + "sliceCasMinMs": 15.515, + "sliceCasAvgMs": 16.359, + "sliceBinMinMs": 15.541, + "sliceBinAvgMs": 16.874, + "sliceSrcAvgMs": 42.347, + "sliceWarmMs": 8.301, + "prevSliceCasAvgMs": 16.2, + "bunAvgMs": 22.977, + "denoAvgMs": 60.584, + "nodeAvgMs": 118.344 + }, + { + "num": 18, + "code": "18", + "id": "18-async-event-loop-fanout-scheduler", + "label": "`18-async-event-loop-fanout-scheduler` (Timer Wheel/`Promise.all`/`AbortSignal`)", + "category": "wintertc_fetch_dlp", + "flagship": false, + "sliceCasMinMs": 29.505, + "sliceCasAvgMs": 31.543, + "sliceBinMinMs": 29.017, + "sliceBinAvgMs": 30.834, + "sliceSrcAvgMs": 47.953, + "sliceWarmMs": 17.928, + "prevSliceCasAvgMs": 29.421, + "bunAvgMs": 32.957, + "denoAvgMs": 72.222, + "nodeAvgMs": 84.99 + }, + { + "num": 19, + "code": "19", + "id": "19-wintertc-webcrypto-streams-edge", + "label": "`19-wintertc-webcrypto-streams-edge` (WebCrypto/Streams/FormData/Clone)", + "category": "wintertc_fetch_dlp", + "flagship": false, + "sliceCasMinMs": 7.808, + "sliceCasAvgMs": 8.353, + "sliceBinMinMs": 8.415, + "sliceBinAvgMs": 9.008, + "sliceSrcAvgMs": 32.179, + "sliceWarmMs": 1.744, + "prevSliceCasAvgMs": 8.191, + "bunAvgMs": 14.072, + "denoAvgMs": 46.331, + "nodeAvgMs": 89.299 + }, + { + "num": 20, + "code": "20", + "id": "20-node-compat-and-edge-router", + "label": "`20-node-compat-and-edge-router` (`Uint8Array` `Buffer`/Node Core/AST Bundler)", + "category": "npm_ast_disk", + "flagship": true, + "sliceCasMinMs": 10.734, + "sliceCasAvgMs": 11.502, + "sliceBinMinMs": 11.121, + "sliceBinAvgMs": 11.919, + "sliceSrcAvgMs": 45.687, + "sliceWarmMs": 0.545, + "prevSliceCasAvgMs": 11.296, + "bunAvgMs": 22.558, + "denoAvgMs": 55.771, + "nodeAvgMs": 71.858 + }, + { + "num": 21, + "code": "21", + "id": "21-websocket-realtime-and-security-guard", + "label": "`21-websocket-realtime-and-security-guard` (RFC 6455 `WebSocket` + 5-Ring Guard)", + "category": "realtime_workers_wasm", + "flagship": false, + "sliceCasMinMs": 10.148, + "sliceCasAvgMs": 10.803, + "sliceBinMinMs": 10.7, + "sliceBinAvgMs": 11.98, + "sliceSrcAvgMs": 41.123, + "sliceWarmMs": 2.872, + "prevSliceCasAvgMs": 10.553, + "bunAvgMs": 20.404, + "denoAvgMs": 53.926, + "nodeAvgMs": 119.323 + }, + { + "num": 22, + "code": "22", + "id": "22-worker-threads-and-raw-sockets", + "label": "`22-worker-threads-and-raw-sockets` (3 Worker Threads + TCP/UDP + 5-Ring Sec)", + "category": "realtime_workers_wasm", + "flagship": true, + "sliceCasMinMs": 19.882, + "sliceCasAvgMs": 21.52, + "sliceBinMinMs": 19.974, + "sliceBinAvgMs": 21.161, + "sliceSrcAvgMs": 37.732, + "sliceWarmMs": 2.217, + "prevSliceCasAvgMs": 20.938, + "bunAvgMs": 57.852, + "denoAvgMs": 113.393, + "nodeAvgMs": 103.236 + }, + { + "num": 23, + "code": "23", + "id": "23-wasm-crypto-and-simd-kernel", + "label": "`23-wasm-crypto-and-simd-kernel` (Pure-Rust `WebAssembly` + 5-Ring WASM Sec)", + "category": "realtime_workers_wasm", + "flagship": false, + "sliceCasMinMs": 14.824, + "sliceCasAvgMs": 15.912, + "sliceBinMinMs": 15.038, + "sliceBinAvgMs": 15.965, + "sliceSrcAvgMs": 26.006, + "sliceWarmMs": 1.955, + "prevSliceCasAvgMs": 15.069, + "bunAvgMs": 21.598, + "denoAvgMs": 42.081, + "nodeAvgMs": 61.413 + }, + { + "num": 24, + "code": "24", + "id": "24-tsx-ssr-and-wasm-edge-pipeline", + "label": "`24-tsx-ssr-and-wasm-edge-pipeline` (`WebAssembly` SLA Scorer + SSR Pipeline)", + "category": "realtime_workers_wasm", + "flagship": false, + "sliceCasMinMs": 8.477, + "sliceCasAvgMs": 8.927, + "sliceBinMinMs": 8.624, + "sliceBinAvgMs": 9.257, + "sliceSrcAvgMs": 29.458, + "sliceWarmMs": 1.824, + "prevSliceCasAvgMs": 8.419, + "bunAvgMs": 19.246, + "denoAvgMs": 43.391, + "nodeAvgMs": 69.066 + }, + { + "num": 25, + "code": "FW-01", + "id": "frameworks/01-hono-edge-microservice", + "label": "`FW-01: frameworks/01-hono-edge-microservice` (`hono@4.6.20` + `hono/cookie` + `ms`)", + "category": "frameworks", + "flagship": true, + "sliceCasMinMs": 14.922, + "sliceCasAvgMs": 16.071, + "sliceBinMinMs": 14.861, + "sliceBinAvgMs": 15.859, + "sliceSrcAvgMs": 54.768, + "sliceWarmMs": 5.721, + "prevSliceCasAvgMs": 15.318, + "bunAvgMs": 19.913, + "denoAvgMs": 53.967, + "nodeAvgMs": 99.71 + }, + { + "num": 26, + "code": "FW-02", + "id": "frameworks/02-itty-router-unjs-nitro-stack", + "label": "`FW-02: frameworks/02-itty-router-unjs-nitro-stack` (`itty-router` + UnJS)", + "category": "frameworks", + "flagship": false, + "sliceCasMinMs": 18.246, + "sliceCasAvgMs": 19.468, + "sliceBinMinMs": 17.449, + "sliceBinAvgMs": 18.506, + "sliceSrcAvgMs": 49.744, + "sliceWarmMs": 9.528, + "prevSliceCasAvgMs": 18.321, + "bunAvgMs": 19.441, + "denoAvgMs": 47.715, + "nodeAvgMs": 91.467 + }, + { + "num": 32, + "code": "FW-03", + "id": "frameworks/03-node-http-express-compat", + "label": "`FW-03: frameworks/03-node-http-express-compat` (`node:http` + `node:stream` Express/Polka)", + "category": "frameworks", + "flagship": false, + "sliceCasMinMs": 16.234, + "sliceCasAvgMs": 16.83, + "sliceBinMinMs": 16.08, + "sliceBinAvgMs": 17.159, + "sliceSrcAvgMs": 25.395, + "sliceWarmMs": 1.3, + "prevSliceCasAvgMs": 16.913, + "bunAvgMs": 49.313, + "denoAvgMs": 68.567, + "nodeAvgMs": 95.033 + }, + { + "num": 33, + "code": "FW-04", + "id": "frameworks/04-sveltekit-edge-ssr", + "label": "`FW-04: frameworks/04-sveltekit-edge-ssr` (`@sveltejs/kit@3.1.1` + `svelte@5.57.3` + `devalue@6.0.3`)", + "category": "frameworks", + "flagship": true, + "sliceCasMinMs": 33.804, + "sliceCasAvgMs": 36.16, + "sliceBinMinMs": 33.983, + "sliceBinAvgMs": 37.795, + "sliceSrcAvgMs": 160.588, + "sliceWarmMs": 17.019, + "prevSliceCasAvgMs": null, + "bunAvgMs": 46.579, + "denoAvgMs": 71.052, + "nodeAvgMs": 119.71 + }, + { + "num": 27, + "code": "CS-01", + "id": "case_studies/01-tot-autonomous-sre-agent", + "label": "`CS-01: case_studies/01-tot-autonomous-sre-agent` (20 ToT Sandboxes)", + "category": "case_studies", + "flagship": true, + "sliceCasMinMs": 25.515, + "sliceCasAvgMs": 26.485, + "sliceBinMinMs": 26.245, + "sliceBinAvgMs": 28.096, + "sliceSrcAvgMs": 69.091, + "sliceWarmMs": 13.12, + "prevSliceCasAvgMs": 26.69, + "bunAvgMs": 28.256, + "denoAvgMs": 72.647, + "nodeAvgMs": 89.711 + }, + { + "num": 28, + "code": "CS-02", + "id": "case_studies/02-mcp-code-mode-orchestrator", + "label": "`CS-02: case_studies/02-mcp-code-mode-orchestrator` (`-98.4%` Tokens)", + "category": "case_studies", + "flagship": false, + "sliceCasMinMs": 19.286, + "sliceCasAvgMs": 20.362, + "sliceBinMinMs": 19.884, + "sliceBinAvgMs": 21.082, + "sliceSrcAvgMs": 37.633, + "sliceWarmMs": 7.854, + "prevSliceCasAvgMs": 19.966, + "bunAvgMs": 16.23, + "denoAvgMs": 44.344, + "nodeAvgMs": 66.894 + }, + { + "num": 29, + "code": "CS-03", + "id": "case_studies/03-multi-tenant-saas-plugin-mesh", + "label": "`CS-03: case_studies/03-multi-tenant-saas-plugin-mesh` (12 Tenants + Hot-Swap)", + "category": "case_studies", + "flagship": false, + "sliceCasMinMs": 12.948, + "sliceCasAvgMs": 13.984, + "sliceBinMinMs": 13.17, + "sliceBinAvgMs": 14, + "sliceSrcAvgMs": 41.307, + "sliceWarmMs": 6.27, + "prevSliceCasAvgMs": 13.726, + "bunAvgMs": 16.305, + "denoAvgMs": 49.236, + "nodeAvgMs": 84.935 + }, + { + "num": 30, + "code": "CS-04", + "id": "case_studies/04-wasm-zero-trust-cdr-pipeline", + "label": "`CS-04: case_studies/04-wasm-zero-trust-cdr-pipeline` (Wasm SimHash CDR)", + "category": "case_studies", + "flagship": false, + "sliceCasMinMs": 16.966, + "sliceCasAvgMs": 17.514, + "sliceBinMinMs": 17.276, + "sliceBinAvgMs": 18.387, + "sliceSrcAvgMs": 38.48, + "sliceWarmMs": 1.807, + "prevSliceCasAvgMs": 17.723, + "bunAvgMs": 19.807, + "denoAvgMs": 45.755, + "nodeAvgMs": 68.82 + }, + { + "num": 31, + "code": "CS-05", + "id": "case_studies/05-time-travel-chaos-fuzzer-payments", + "label": "`CS-05: case_studies/05-time-travel-chaos-fuzzer-payments` (48 Payment Sagas)", + "category": "case_studies", + "flagship": true, + "sliceCasMinMs": 17.305, + "sliceCasAvgMs": 18.127, + "sliceBinMinMs": 17.551, + "sliceBinAvgMs": 18.959, + "sliceSrcAvgMs": 44.147, + "sliceWarmMs": 10.313, + "prevSliceCasAvgMs": 18.002, + "bunAvgMs": 19.616, + "denoAvgMs": 62.942, + "nodeAvgMs": 83.703 + } + ], + "rss": [ + { + "id": "App 2: NPM semver+ms+ini", + "label": "App 2: NPM semver+ms+ini", + "sliceKb": 14208, + "bunKb": 30080, + "denoKb": 47100, + "nodeKb": 71576 + }, + { + "id": "App 6: Telemetry + Flatted", + "label": "App 6: Telemetry + Flatted", + "sliceKb": 14592, + "bunKb": 30592, + "denoKb": 50780, + "nodeKb": 72988 + }, + { + "id": "App 21: RFC 6455 WS + Sec", + "label": "App 21: RFC 6455 WS + Sec", + "sliceKb": 13952, + "bunKb": 32088, + "denoKb": 50848, + "nodeKb": 94724 + }, + { + "id": "App 22: Workers + Sockets", + "label": "App 22: Workers + Sockets", + "sliceKb": 22016, + "bunKb": 41568, + "denoKb": 62868, + "nodeKb": 94028 + }, + { + "id": "App 23: Pure-Rust WASM", + "label": "App 23: Pure-Rust WASM", + "sliceKb": 18944, + "bunKb": 30976, + "denoKb": 48924, + "nodeKb": 80660 + }, + { + "id": "FW 1: Hono v4 Microservice", + "label": "FW 1: Hono v4 Microservice", + "sliceKb": 15104, + "bunKb": 30624, + "denoKb": 49008, + "nodeKb": 88988 + }, + { + "id": "FW 2: itty-router + UnJS", + "label": "FW 2: itty-router + UnJS", + "sliceKb": 14720, + "bunKb": 31616, + "denoKb": 48628, + "nodeKb": 86796 + }, + { + "id": "App 24: WASM + SSR", + "label": "App 24: WASM + SSR", + "sliceKb": 13696, + "bunKb": 32256, + "denoKb": 48544, + "nodeKb": 81152 + }, + { + "id": "FW 3: Express node:http", + "label": "FW 3: Express node:http", + "sliceKb": 14976, + "bunKb": 33024, + "denoKb": 46564, + "nodeKb": 79884 + }, + { + "id": "01-tot-autonomous-sre-agent", + "label": "01-tot-autonomous-sre-agent", + "sliceKb": 18560, + "bunKb": 31744, + "denoKb": 52980, + "nodeKb": 86016 + }, + { + "id": "02-mcp-code-mode-orchestrator", + "label": "02-mcp-code-mode-orchestrator", + "sliceKb": 18112, + "bunKb": 27904, + "denoKb": 47068, + "nodeKb": 80648 + }, + { + "id": "03-multi-tenant-saas-plugin-mesh", + "label": "03-multi-tenant-saas-plugin-mesh", + "sliceKb": 15744, + "bunKb": 28672, + "denoKb": 49480, + "nodeKb": 87940 + }, + { + "id": "04-wasm-zero-trust-cdr-pipeline", + "label": "04-wasm-zero-trust-cdr-pipeline", + "sliceKb": 19968, + "bunKb": 31104, + "denoKb": 49692, + "nodeKb": 80136 + }, + { + "id": "05-time-travel-chaos-fuzzer-payments", + "label": "05-time-travel-chaos-fuzzer-payments", + "sliceKb": 15744, + "bunKb": 29184, + "denoKb": 49780, + "nodeKb": 81440 + }, + { + "id": "FW 4: SvelteKit 3 + Svelte 5", + "label": "FW 4: SvelteKit 3 + Svelte 5", + "sliceKb": 20992, + "bunKb": 41984, + "denoKb": 56580, + "nodeKb": 85412 + } + ] +} diff --git a/tests/reports/bench_v0.10.5_20261109_202907Z_a0c723e.md b/tests/reports/bench_v0.10.5_20261109_202907Z_a0c723e.md new file mode 100644 index 0000000..409ab12 --- /dev/null +++ b/tests/reports/bench_v0.10.5_20261109_202907Z_a0c723e.md @@ -0,0 +1,113 @@ +# Slice (Nexus-JS) — Full 33-Workload & MicroVM Benchmark Report + +* **Slice Version:** `v0.10.5` (Commit `a0c723e`) +* **Generated Timestamp (UTC):** `2026-11-09T20:29:07Z` +* **Archive File:** [`tests/reports/bench_v0.10.5_20261109_202907Z_a0c723e.md`](./bench_v0.10.5_20261109_202907Z_a0c723e.md) +* **Canonical Latest Report:** [`tests/reports/latest.md`](./latest.md) +* **Environment:** `Linux x86_64 Docker (io_uring SQPOLL + WRPKRU)` +* **Compared Runtimes:** + * **Slice:** `v0.10.5` (Default `SLICEBC\x01` Precompiled Boa `CodeBlock` CAS + Monomorphic Inline Caching `get_fast` + Streaming `JsonSeed` `JSON.parse`) + * **Bun:** `v1.4.4` (JavaScriptCore) + * **Deno:** `v2.9.8` (V8) + * **Node.js:** `v27.0.0-alpha.0.0.0` (V8 native TypeScript execution) + +--- + +## 1. Executive Summary + +Across all **33 real-world multi-file TypeScript applications, framework suites, and case studies**, Slice beats **Deno (`v2.9.8`)** on **33/33** workloads, beats **Node.js (`v27.0.0-alpha.0.0.0`)** on **33/33** workloads, beats **Bun (`v1.4.4`)** on **30/33** workloads in cold one-shot execution, and beats **all 3 runtimes on 33/33 workloads in `--warm` pooled isolate execution**. + +| Metric | Linux (`x86_64` Docker) | Windows (`x86_64` Host) | Comparison vs Runtimes & MicroVMs | +| :--- | :---: | :---: | :--- | +| **Single Isolate Cold-Start (Min / P50 / P99)** | **`1.17 us` / `1.24 us` / `1.61 us`** | **`1.40 us` / `1.60 us` / `2.30 us`** | **~120,000x faster than 125ms Firecracker VM** | +| **1,000-Tenant MicroVM Swarm (Boot + Exec)** | **`1.51 ms`** (`10.07 MB` RSS) | **`2.24 ms`** (`11.82 MB` RSS) | **> 10,000x faster than container/VM swarms** | +| **500-Module Monorepo Cold Boot (`0 stat()`)** | **`3.408 ms`** (`394.90 us` in-mem) | **`5.637 ms`** (`640.00 us` in-mem) | **20.6x faster than Node.js (`1,500+ stat()`)** | +| **10,000 Direct Kernel Ring I/O Completions** | **`0.02 ms`** | **`5.11 ms`** | **Zero worker-thread lock contention** | +| **5-Ring Security Containment Verification** | **`5 / 5 PASS`** | **`5 / 5 PASS`** | **OCap + SES + Fuel + SSRF/DLP + MPK** | + +--- + +## 2. `slice serve` Multi-Tenant HTTP/1.1 Keep-Alive Throughput (`16,000` Reqs, 8 Sockets x 8 Pipeline) + +| Server / Runtime | Throughput (`req/s`) | Avg Latency / Req | Total Time (`16k` Reqs) | Relative Speedup vs Runtimes | +| :--- | :---: | :---: | :---: | :--- | +| **`slice serve` (Tier-0 CAS, `--workers=8`)** | **`148,407 req/s`** | **`6.74 us/req`** | **`107.8 ms`** | **`1.51x` faster than `Bun.serve` / `2.65x` Node.js** | +| **`slice serve` (Tier-1 WinterTC, `--workers=8`)** | **`145,839 req/s`** | **`6.86 us/req`** | **`109.7 ms`** | **`1.49x` faster than `Bun.serve` / `2.61x` Node.js** | +| **`Deno.serve` (`v2.9.8`, V8, No Per-Req Sandbox)** | `100,099 req/s` | `9.99 us/req` | `159.8 ms` | `1.02x` vs Bun | +| **`Bun.serve` (`v1.4.4`, JSC, No Per-Req Sandbox)** | `97,987 req/s` | `10.21 us/req` | `163.3 ms` | `1.00x` (Baseline) | +| **`Node.js http.createServer` (`v27.0.0-alpha.0.0.0`, V8)** | `55,977 req/s` | `17.86 us/req` | `285.8 ms` | `0.57x` vs Bun | + +--- + +## 3. Full 33-Workload Latency Comparison (20 Runs Each, Linux `x86_64` Docker) + +| # | Workload (`tests/apps/`, `tests/frameworks/`, `tests/case_studies/`) | Slice Cold `.cas` (`SLICEBC\x01`) | Slice Standalone Bin (`SLICEBC\x01`) | Slice Warm (`--warm`) | Previous `.cas` (`Delta`) | Bun `v1.4.4` | Deno `v2.9.8` | Node.js `v27.0.0-alpha.0.0.0` | Slice Speedup vs Bun / Node.js | +| :- | :--- | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :--- | +| **01** | `01-fintech-checkout` (Multi-File TS + SHA-256) | **`6.206 ms`** (`5.74 ms` Min) | **`6.836 ms`** | **`1.168 ms`** | `6.209 ms` (`-0.0%`) | `14.399 ms` | `38.716 ms` | `59.167 ms` | **`2.32x Bun` (`12.33x` Warm) / `9.53x Node`** | +| **02** | `02-npm-ecosystem-suite` (`semver` + `ms` + `ini`) | **`14.659 ms`** (`13.67 ms` Min) | **`15.257 ms`** | **`3.989 ms`** | `14.111 ms` (`3.9%`) | `21.031 ms` | `54.896 ms` | `72.423 ms` | **`1.43x Bun` (`5.27x` Warm) / `4.94x Node`** | +| **03** | `03-disk-io-log-pipeline` (10 JSONL Shards Disk I/O) | **`8.036 ms`** (`7.42 ms` Min) | **`8.745 ms`** | **`2.175 ms`** | `7.819 ms` (`2.8%`) | `14.427 ms` | `45.774 ms` | `63.282 ms` | **`1.80x Bun` (`6.63x` Warm) / `7.87x Node`** | +| **04** | `04-edge-api-gateway` (`fast-querystring` + `ms`) | **`7.850 ms`** (`7.22 ms` Min) | **`8.498 ms`** | **`2.193 ms`** | `7.940 ms` (`-1.1%`) | `15.712 ms` | `45.705 ms` | `65.196 ms` | **`2.00x Bun` (`7.16x` Warm) / `8.31x Node`** | +| **05** | `05-jwt-oauth-session-guard` (`cookie` + `ms` + HMAC) | **`10.654 ms`** (`10.03 ms` Min) | **`11.471 ms`** | **`5.686 ms`** | `10.820 ms` (`-1.5%`) | `15.477 ms` | `45.984 ms` | `65.979 ms` | **`1.45x Bun` (`2.72x` Warm) / `6.19x Node`** | +| **06** | `06-telemetry-metrics-pipeline` (`bytes` + `flatted` + WAL) | **`14.519 ms`** (`13.70 ms` Min) | **`15.347 ms`** | **`5.943 ms`** | `14.531 ms` (`-0.1%`) | `17.760 ms` | `48.005 ms` | `66.981 ms` | **`1.22x Bun` (`2.99x` Warm) / `4.61x Node`** | +| **07** | `07-graphql-ast-validator` (`dlv` + `dset` + AST Cost) | **`9.992 ms`** (`8.98 ms` Min) | **`10.286 ms`** | **`4.429 ms`** | `9.236 ms` (`8.2%`) | `13.532 ms` | `53.519 ms` | `62.876 ms` | **`1.35x Bun` (`3.06x` Warm) / `6.29x Node`** | +| **08** | `08-event-driven-state-journal` (`mitt` + `ms` + JSONL Replay) | **`13.568 ms`** (`11.39 ms` Min) | **`12.399 ms`** | **`6.140 ms`** | `11.756 ms` (`15.4%`) | `16.462 ms` | `49.933 ms` | `66.841 ms` | **`1.33x Bun` (`2.68x` Warm) / `5.39x Node`** | +| **09** | `09-wintertc-web-router` (`Request` + `Response` + `URL`, 80 reqs) | **`15.476 ms`** (`14.26 ms` Min) | **`15.679 ms`** | **`10.881 ms`** | `14.792 ms` (`4.6%`) | `14.242 ms` | `49.197 ms` | `88.955 ms` | **`1.31x Bun Warm` / `5.75x Node`** | +| **10** | `10-fullstack-bff-microservice` (`cookie` + `dlv` + `ms` + `ETag`, 60 reqs) | **`13.998 ms`** (`13.03 ms` Min) | **`13.960 ms`** | **`7.199 ms`** | `14.266 ms` (`-1.9%`) | `14.723 ms` | `50.512 ms` | `87.655 ms` | **`1.05x Bun` (`2.05x` Warm) / `6.28x Node`** | +| **11** | `11-static-asset-cdn-edge` (`bytes` + `ms` + `ETag` `304`, 80 reqs) | **`10.268 ms`** (`9.54 ms` Min) | **`10.693 ms`** | **`4.430 ms`** | `9.957 ms` (`3.1%`) | `14.581 ms` | `54.186 ms` | `88.489 ms` | **`1.42x Bun` (`3.29x` Warm) / `8.62x Node`** | +| **12** | `12-ai-sse-token-streamer` (`mitt` + `ms` + SSE + DLP, 320 frames) | **`16.665 ms`** (`15.51 ms` Min) | **`17.562 ms`** | **`9.427 ms`** | `16.313 ms` (`2.2%`) | `15.962 ms` | `52.085 ms` | `92.752 ms` | **`1.69x Bun Warm` / `5.57x Node`** | +| **13** | `13-webhook-orchestrator-ssrf` (`fast-querystring` + `ms` + Live `fetch`) | **`14.135 ms`** (`13.59 ms` Min) | **`15.028 ms`** | **`6.475 ms`** | `13.841 ms` (`2.1%`) | `21.100 ms` | `53.692 ms` | `115.809 ms` | **`1.49x Bun` (`3.26x` Warm) / `8.19x Node`** | +| **14** | `14-federated-api-mesh-dlp` (`bytes` + `dlv` + `dset` + Live `fetch`) | **`15.515 ms`** (`14.69 ms` Min) | **`16.745 ms`** | **`7.867 ms`** | `14.809 ms` (`4.8%`) | `22.376 ms` | `56.663 ms` | `112.022 ms` | **`1.44x Bun` (`2.84x` Warm) / `7.22x Node`** | +| **15** | `15-time-travel-test-suite` (`semver` + `ms` + `dlv` + `dset` + 24 Rollbacks) | **`15.345 ms`** (`14.57 ms` Min) | **`16.621 ms`** | **`5.088 ms`** | `15.122 ms` (`1.5%`) | `25.308 ms` | `68.122 ms` | `84.543 ms` | **`1.65x Bun` (`4.97x` Warm) / `5.51x Node`** | +| **16** | `16-dotenv-dlp-config-vault` (`ini` + `cookie` + `bytes` + `.env` Auto-DLP) | **`7.716 ms`** (`7.21 ms` Min) | **`8.187 ms`** | **`1.686 ms`** | `7.469 ms` (`3.3%`) | `15.118 ms` | `48.508 ms` | `66.922 ms` | **`1.96x Bun` (`8.97x` Warm) / `8.67x Node`** | +| **17** | `17-zero-trust-redirect-keepalive-mesh` (Keep-Alive/307/SSRF/DLP) | **`16.359 ms`** (`15.52 ms` Min) | **`16.874 ms`** | **`8.301 ms`** | `16.200 ms` (`1.0%`) | `22.977 ms` | `60.584 ms` | `118.344 ms` | **`1.40x Bun` (`2.77x` Warm) / `7.23x Node`** | +| **18** | `18-async-event-loop-fanout-scheduler` (Timer Wheel/`Promise.all`/`AbortSignal`) | **`31.543 ms`** (`29.50 ms` Min) | **`30.834 ms`** | **`17.928 ms`** | `29.421 ms` (`7.2%`) | `32.957 ms` | `72.222 ms` | `84.990 ms` | **`1.07x Bun` (`1.84x` Warm) / `2.76x Node`** | +| **19** | `19-wintertc-webcrypto-streams-edge` (WebCrypto/Streams/FormData/Clone) | **`8.353 ms`** (`7.81 ms` Min) | **`9.008 ms`** | **`1.744 ms`** | `8.191 ms` (`2.0%`) | `14.072 ms` | `46.331 ms` | `89.299 ms` | **`1.68x Bun` (`8.07x` Warm) / `10.69x Node`** | +| **20** | `20-node-compat-and-edge-router` (`Uint8Array` `Buffer`/Node Core/AST Bundler) | **`11.502 ms`** (`10.73 ms` Min) | **`11.919 ms`** | **`0.545 ms`** | `11.296 ms` (`1.8%`) | `22.558 ms` | `55.771 ms` | `71.858 ms` | **`1.96x Bun` (`41.39x` Warm) / `6.25x Node`** | +| **21** | `21-websocket-realtime-and-security-guard` (RFC 6455 `WebSocket` + 5-Ring Guard) | **`10.803 ms`** (`10.15 ms` Min) | **`11.980 ms`** | **`2.872 ms`** | `10.553 ms` (`2.4%`) | `20.404 ms` | `53.926 ms` | `119.323 ms` | **`1.89x Bun` (`7.10x` Warm) / `11.05x Node`** | +| **22** | `22-worker-threads-and-raw-sockets` (3 Worker Threads + TCP/UDP + 5-Ring Sec) | **`21.520 ms`** (`19.88 ms` Min) | **`21.161 ms`** | **`2.217 ms`** | `20.938 ms` (`2.8%`) | `57.852 ms` | `113.393 ms` | `103.236 ms` | **`2.73x Bun` (`26.09x` Warm) / `4.88x Node`** | +| **23** | `23-wasm-crypto-and-simd-kernel` (Pure-Rust `WebAssembly` + 5-Ring WASM Sec) | **`15.912 ms`** (`14.82 ms` Min) | **`15.965 ms`** | **`1.955 ms`** | `15.069 ms` (`5.6%`) | `21.598 ms` | `42.081 ms` | `61.413 ms` | **`1.36x Bun` (`11.05x` Warm) / `3.86x Node`** | +| **24** | `24-tsx-ssr-and-wasm-edge-pipeline` (`WebAssembly` SLA Scorer + SSR Pipeline) | **`8.927 ms`** (`8.48 ms` Min) | **`9.257 ms`** | **`1.824 ms`** | `8.419 ms` (`6.0%`) | `19.246 ms` | `43.391 ms` | `69.066 ms` | **`2.16x Bun` (`10.55x` Warm) / `7.74x Node`** | +| **FW-01** | `FW-01: frameworks/01-hono-edge-microservice` (`hono@4.6.20` + `hono/cookie` + `ms`) | **`16.071 ms`** (`14.92 ms` Min) | **`15.859 ms`** | **`5.721 ms`** | `15.318 ms` (`4.9%`) | `19.913 ms` | `53.967 ms` | `99.710 ms` | **`1.26x Bun` (`3.48x` Warm) / `6.29x Node`** | +| **FW-02** | `FW-02: frameworks/02-itty-router-unjs-nitro-stack` (`itty-router` + UnJS) | **`19.468 ms`** (`18.25 ms` Min) | **`18.506 ms`** | **`9.528 ms`** | `18.321 ms` (`6.3%`) | `19.441 ms` | `47.715 ms` | `91.467 ms` | **`1.05x Bun` (`2.04x` Warm) / `4.94x Node`** | +| **FW-03** | `FW-03: frameworks/03-node-http-express-compat` (`node:http` + `node:stream` Express/Polka) | **`16.830 ms`** (`16.23 ms` Min) | **`17.159 ms`** | **`1.300 ms`** | `16.913 ms` (`-0.5%`) | `49.313 ms` | `68.567 ms` | `95.033 ms` | **`2.93x Bun` (`37.93x` Warm) / `5.65x Node`** | +| **FW-04** | `FW-04: frameworks/04-sveltekit-edge-ssr` (`@sveltejs/kit@3.1.1` + `svelte@5.57.3` + `devalue@6.0.3`) | **`36.160 ms`** (`33.80 ms` Min) | **`37.795 ms`** | **`17.019 ms`** | — | `46.579 ms` | `71.052 ms` | `119.710 ms` | **`1.29x Bun` (`2.74x` Warm) / `3.31x Node`** | +| **CS-01** | `CS-01: case_studies/01-tot-autonomous-sre-agent` (20 ToT Sandboxes) | **`26.485 ms`** (`25.52 ms` Min) | **`28.096 ms`** | **`13.120 ms`** | `26.690 ms` (`-0.8%`) | `28.256 ms` | `72.647 ms` | `89.711 ms` | **`1.07x Bun` (`2.15x` Warm) / `3.39x Node`** | +| **CS-02** | `CS-02: case_studies/02-mcp-code-mode-orchestrator` (`-98.4%` Tokens) | **`20.362 ms`** (`19.29 ms` Min) | **`21.082 ms`** | **`7.854 ms`** | `19.966 ms` (`2.0%`) | `16.230 ms` | `44.344 ms` | `66.894 ms` | **`2.07x Bun Warm` / `3.29x Node`** | +| **CS-03** | `CS-03: case_studies/03-multi-tenant-saas-plugin-mesh` (12 Tenants + Hot-Swap) | **`13.984 ms`** (`12.95 ms` Min) | **`14.000 ms`** | **`6.270 ms`** | `13.726 ms` (`1.9%`) | `16.305 ms` | `49.236 ms` | `84.935 ms` | **`1.17x Bun` (`2.60x` Warm) / `6.07x Node`** | +| **CS-04** | `CS-04: case_studies/04-wasm-zero-trust-cdr-pipeline` (Wasm SimHash CDR) | **`17.514 ms`** (`16.97 ms` Min) | **`18.387 ms`** | **`1.807 ms`** | `17.723 ms` (`-1.2%`) | `19.807 ms` | `45.755 ms` | `68.820 ms` | **`1.13x Bun` (`10.96x` Warm) / `3.93x Node`** | +| **CS-05** | `CS-05: case_studies/05-time-travel-chaos-fuzzer-payments` (48 Payment Sagas) | **`18.127 ms`** (`17.30 ms` Min) | **`18.959 ms`** | **`10.313 ms`** | `18.002 ms` (`0.7%`) | `19.616 ms` | `62.942 ms` | `83.703 ms` | **`1.08x Bun` (`1.90x` Warm) / `4.62x Node`** | + +--- + +## 4. Peak Process Memory Footprint (`Max RSS` via `/usr/bin/time -v`) + +| Workload | Slice (`SLICEBC\x01` Default) | Bun (`v1.4.4`) | Deno (`v2.9.8`) | Node.js (`v27.0.0-alpha.0.0.0`) | Slice Memory Advantage | +| :--- | :---: | :---: | :---: | :---: | :--- | +| **App 2: NPM semver+ms+ini** | **14,208 KB (13.88 MB)** | 30,080 KB (29.38 MB) | 47,100 KB (46.00 MB) | 71,576 KB (69.90 MB) | **5.04x less than Node / 2.12x less than Bun** | +| **App 6: Telemetry + Flatted** | **14,592 KB (14.25 MB)** | 30,592 KB (29.88 MB) | 50,780 KB (49.59 MB) | 72,988 KB (71.28 MB) | **5.00x less than Node / 2.10x less than Bun** | +| **App 21: RFC 6455 WS + Sec** | **13,952 KB (13.63 MB)** | 32,088 KB (31.34 MB) | 50,848 KB (49.66 MB) | 94,724 KB (92.50 MB) | **6.79x less than Node / 2.30x less than Bun** | +| **App 22: Workers + Sockets** | **22,016 KB (21.50 MB)** | 41,568 KB (40.59 MB) | 62,868 KB (61.39 MB) | 94,028 KB (91.82 MB) | **4.27x less than Node / 1.89x less than Bun** | +| **App 23: Pure-Rust WASM** | **18,944 KB (18.50 MB)** | 30,976 KB (30.25 MB) | 48,924 KB (47.78 MB) | 80,660 KB (78.77 MB) | **4.26x less than Node / 1.64x less than Bun** | +| **FW 1: Hono v4 Microservice** | **15,104 KB (14.75 MB)** | 30,624 KB (29.91 MB) | 49,008 KB (47.86 MB) | 88,988 KB (86.90 MB) | **5.89x less than Node / 2.03x less than Bun** | +| **FW 2: itty-router + UnJS** | **14,720 KB (14.38 MB)** | 31,616 KB (30.88 MB) | 48,628 KB (47.49 MB) | 86,796 KB (84.76 MB) | **5.90x less than Node / 2.15x less than Bun** | +| **App 24: WASM + SSR** | **13,696 KB (13.38 MB)** | 32,256 KB (31.50 MB) | 48,544 KB (47.41 MB) | 81,152 KB (79.25 MB) | **5.93x less than Node / 2.36x less than Bun** | +| **FW 3: Express node:http** | **14,976 KB (14.63 MB)** | 33,024 KB (32.25 MB) | 46,564 KB (45.47 MB) | 79,884 KB (78.01 MB) | **5.33x less than Node / 2.21x less than Bun** | +| **01-tot-autonomous-sre-agent** | **18,560 KB (18.13 MB)** | 31,744 KB (31.00 MB) | 52,980 KB (51.74 MB) | 86,016 KB (84.00 MB) | **4.63x less than Node / 1.71x less than Bun** | +| **02-mcp-code-mode-orchestrator** | **18,112 KB (17.69 MB)** | 27,904 KB (27.25 MB) | 47,068 KB (45.96 MB) | 80,648 KB (78.76 MB) | **4.45x less than Node / 1.54x less than Bun** | +| **03-multi-tenant-saas-plugin-mesh** | **15,744 KB (15.38 MB)** | 28,672 KB (28.00 MB) | 49,480 KB (48.32 MB) | 87,940 KB (85.88 MB) | **5.59x less than Node / 1.82x less than Bun** | +| **04-wasm-zero-trust-cdr-pipeline** | **19,968 KB (19.50 MB)** | 31,104 KB (30.38 MB) | 49,692 KB (48.53 MB) | 80,136 KB (78.26 MB) | **4.01x less than Node / 1.56x less than Bun** | +| **05-time-travel-chaos-fuzzer-payments** | **15,744 KB (15.38 MB)** | 29,184 KB (28.50 MB) | 49,780 KB (48.61 MB) | 81,440 KB (79.53 MB) | **5.17x less than Node / 1.85x less than Bun** | +| **FW 4: SvelteKit 3 + Svelte 5** | **20,992 KB (20.50 MB)** | 41,984 KB (41.00 MB) | 56,580 KB (55.25 MB) | 85,412 KB (83.41 MB) | **4.07x less than Node / 2.00x less than Bun** | + +--- + +## 5. Multi-Tenant Edge KV, AI Agent Checkpoints & 5-Ring Security Telemetry + +| Subsystem / Benchmark | Measured Telemetry | Status | +| :--- | :--- | :---: | +| **Sharded `Slice.kv` (`1,001` Get/Set/Incr Ops in Isolate)** | **`644.66 us`** total (`--warm`, `8,431 B` memory cage) | `PASS` | +| **Multi-Tenant `--tenant-dir` Zero-Downtime Hot-Swap** | Live atomic replacement of `tenant-alpha.cas` (`v1 -> v2-hot-swapped`) with isolated `Slice.kv` state | `PASS` | +| **Deterministic Time-Travel Replay (`--deterministic=20261019`)** | 100% bit-for-bit identical PRNG (`Math.random`) & virtual clock (`Date.now`, `performance.now`) | `PASS` | +| **Tree-of-Thought AI Agent (`Slice.checkpoint` + 3 `evalSandbox` + `restore`)** | **`55.02 us`** total (`1.77 us` child sandbox) | `PASS` | +| **Cloud Metadata SSRF (`169.254.169.254`) & Base64 Egress DLP Guard** | `SSRF_METADATA_BLOCKED` & `EGRESS_SECRET_LEAK_BLOCKED` deterministically trapped | `PASS` | +| **Built-In Model Context Protocol Server (`slice mcp --smoke-test`)** | JSON-RPC 2.0 `initialize`, `tools/list`, `tools/call` verified over `stdio` | `PASS` | diff --git a/tests/reports/latest.json b/tests/reports/latest.json index 9eac6af..6a6c648 100644 --- a/tests/reports/latest.json +++ b/tests/reports/latest.json @@ -1,8 +1,8 @@ { "metadata": { "version": "0.10.5", - "commit": "7a86dd6", - "timestampUtc": "2026-11-09T07:35:38Z", + "commit": "a0c723e", + "timestampUtc": "2026-11-09T20:29:07Z", "environment": "Linux x86_64 Docker (io_uring SQPOLL + WRPKRU)", "runtimes": { "slice": "v0.10.5", @@ -10,7 +10,7 @@ "deno": "v2.9.8", "node": "v27.0.0-alpha.0.0.0" }, - "archiveFile": "tests/reports/bench_v0.10.4_20261109_073538Z_7a86dd6.md", + "archiveFile": "tests/reports/bench_v0.10.5_20261109_202907Z_a0c723e.md", "latestFile": "tests/reports/latest.md" }, "microvm": { @@ -508,16 +508,16 @@ "label": "`FW-01: frameworks/01-hono-edge-microservice` (`hono@4.6.20` + `hono/cookie` + `ms`)", "category": "frameworks", "flagship": true, - "sliceCasMinMs": 14.299, - "sliceCasAvgMs": 15.318, - "sliceBinMinMs": 14.859, - "sliceBinAvgMs": 16.199, - "sliceSrcAvgMs": 51.827, - "sliceWarmMs": 6.483, - "prevSliceCasAvgMs": 15.14, - "bunAvgMs": 20.415, - "denoAvgMs": 54.052, - "nodeAvgMs": 96.96 + "sliceCasMinMs": 14.922, + "sliceCasAvgMs": 16.071, + "sliceBinMinMs": 14.861, + "sliceBinAvgMs": 15.859, + "sliceSrcAvgMs": 54.768, + "sliceWarmMs": 5.721, + "prevSliceCasAvgMs": 15.318, + "bunAvgMs": 19.913, + "denoAvgMs": 53.967, + "nodeAvgMs": 99.71 }, { "num": 26, @@ -526,16 +526,16 @@ "label": "`FW-02: frameworks/02-itty-router-unjs-nitro-stack` (`itty-router` + UnJS)", "category": "frameworks", "flagship": false, - "sliceCasMinMs": 17.047, - "sliceCasAvgMs": 18.321, - "sliceBinMinMs": 17.639, - "sliceBinAvgMs": 18.916, - "sliceSrcAvgMs": 46.887, - "sliceWarmMs": 8.79, - "prevSliceCasAvgMs": 17.873, - "bunAvgMs": 20.104, - "denoAvgMs": 47.45, - "nodeAvgMs": 89.334 + "sliceCasMinMs": 18.246, + "sliceCasAvgMs": 19.468, + "sliceBinMinMs": 17.449, + "sliceBinAvgMs": 18.506, + "sliceSrcAvgMs": 49.744, + "sliceWarmMs": 9.528, + "prevSliceCasAvgMs": 18.321, + "bunAvgMs": 19.441, + "denoAvgMs": 47.715, + "nodeAvgMs": 91.467 }, { "num": 32, @@ -544,16 +544,34 @@ "label": "`FW-03: frameworks/03-node-http-express-compat` (`node:http` + `node:stream` Express/Polka)", "category": "frameworks", "flagship": false, - "sliceCasMinMs": 15.813, - "sliceCasAvgMs": 16.913, - "sliceBinMinMs": 16.137, - "sliceBinAvgMs": 17.379, - "sliceSrcAvgMs": 23.252, - "sliceWarmMs": 1.07, - "prevSliceCasAvgMs": 16.41, - "bunAvgMs": 35.105, - "denoAvgMs": 50.537, - "nodeAvgMs": 86.593 + "sliceCasMinMs": 16.234, + "sliceCasAvgMs": 16.83, + "sliceBinMinMs": 16.08, + "sliceBinAvgMs": 17.159, + "sliceSrcAvgMs": 25.395, + "sliceWarmMs": 1.3, + "prevSliceCasAvgMs": 16.913, + "bunAvgMs": 49.313, + "denoAvgMs": 68.567, + "nodeAvgMs": 95.033 + }, + { + "num": 33, + "code": "FW-04", + "id": "frameworks/04-sveltekit-edge-ssr", + "label": "`FW-04: frameworks/04-sveltekit-edge-ssr` (`@sveltejs/kit@3.1.1` + `svelte@5.57.3` + `devalue@6.0.3`)", + "category": "frameworks", + "flagship": true, + "sliceCasMinMs": 33.804, + "sliceCasAvgMs": 36.16, + "sliceBinMinMs": 33.983, + "sliceBinAvgMs": 37.795, + "sliceSrcAvgMs": 160.588, + "sliceWarmMs": 17.019, + "prevSliceCasAvgMs": null, + "bunAvgMs": 46.579, + "denoAvgMs": 71.052, + "nodeAvgMs": 119.71 }, { "num": 27, @@ -690,18 +708,18 @@ { "id": "FW 1: Hono v4 Microservice", "label": "FW 1: Hono v4 Microservice", - "sliceKb": 15232, - "bunKb": 31224, - "denoKb": 49436, - "nodeKb": 89116 + "sliceKb": 15104, + "bunKb": 30624, + "denoKb": 49008, + "nodeKb": 88988 }, { "id": "FW 2: itty-router + UnJS", "label": "FW 2: itty-router + UnJS", - "sliceKb": 14592, - "bunKb": 32128, - "denoKb": 48544, - "nodeKb": 87180 + "sliceKb": 14720, + "bunKb": 31616, + "denoKb": 48628, + "nodeKb": 86796 }, { "id": "App 24: WASM + SSR", @@ -715,9 +733,9 @@ "id": "FW 3: Express node:http", "label": "FW 3: Express node:http", "sliceKb": 14976, - "bunKb": 33152, - "denoKb": 46956, - "nodeKb": 80136 + "bunKb": 33024, + "denoKb": 46564, + "nodeKb": 79884 }, { "id": "01-tot-autonomous-sre-agent", @@ -758,6 +776,14 @@ "bunKb": 29184, "denoKb": 49780, "nodeKb": 81440 + }, + { + "id": "FW 4: SvelteKit 3 + Svelte 5", + "label": "FW 4: SvelteKit 3 + Svelte 5", + "sliceKb": 20992, + "bunKb": 41984, + "denoKb": 56580, + "nodeKb": 85412 } ] } diff --git a/tests/reports/latest.md b/tests/reports/latest.md index c585dbb..409ab12 100644 --- a/tests/reports/latest.md +++ b/tests/reports/latest.md @@ -1,8 +1,8 @@ -# Slice (Nexus-JS) — Full 32-Workload & MicroVM Benchmark Report +# Slice (Nexus-JS) — Full 33-Workload & MicroVM Benchmark Report -* **Slice Version:** `v0.10.5` (Commit `7a86dd6`) -* **Generated Timestamp (UTC):** `2026-11-09T07:35:38Z` -* **Archive File:** [`tests/reports/bench_v0.10.4_20261109_073538Z_7a86dd6.md`](./bench_v0.10.4_20261109_073538Z_7a86dd6.md) +* **Slice Version:** `v0.10.5` (Commit `a0c723e`) +* **Generated Timestamp (UTC):** `2026-11-09T20:29:07Z` +* **Archive File:** [`tests/reports/bench_v0.10.5_20261109_202907Z_a0c723e.md`](./bench_v0.10.5_20261109_202907Z_a0c723e.md) * **Canonical Latest Report:** [`tests/reports/latest.md`](./latest.md) * **Environment:** `Linux x86_64 Docker (io_uring SQPOLL + WRPKRU)` * **Compared Runtimes:** @@ -15,7 +15,7 @@ ## 1. Executive Summary -Across all **32 real-world multi-file TypeScript applications, framework suites, and case studies**, Slice beats **Deno (`v2.9.8`)** on **32/32** workloads, beats **Node.js (`v27.0.0-alpha.0.0.0`)** on **32/32** workloads, beats **Bun (`v1.4.4`)** on **29/32** workloads in cold one-shot execution, and beats **all 3 runtimes on 32/32 workloads in `--warm` pooled isolate execution**. +Across all **33 real-world multi-file TypeScript applications, framework suites, and case studies**, Slice beats **Deno (`v2.9.8`)** on **33/33** workloads, beats **Node.js (`v27.0.0-alpha.0.0.0`)** on **33/33** workloads, beats **Bun (`v1.4.4`)** on **30/33** workloads in cold one-shot execution, and beats **all 3 runtimes on 33/33 workloads in `--warm` pooled isolate execution**. | Metric | Linux (`x86_64` Docker) | Windows (`x86_64` Host) | Comparison vs Runtimes & MicroVMs | | :--- | :---: | :---: | :--- | @@ -39,7 +39,7 @@ Across all **32 real-world multi-file TypeScript applications, framework suites, --- -## 3. Full 32-Workload Latency Comparison (20 Runs Each, Linux `x86_64` Docker) +## 3. Full 33-Workload Latency Comparison (20 Runs Each, Linux `x86_64` Docker) | # | Workload (`tests/apps/`, `tests/frameworks/`, `tests/case_studies/`) | Slice Cold `.cas` (`SLICEBC\x01`) | Slice Standalone Bin (`SLICEBC\x01`) | Slice Warm (`--warm`) | Previous `.cas` (`Delta`) | Bun `v1.4.4` | Deno `v2.9.8` | Node.js `v27.0.0-alpha.0.0.0` | Slice Speedup vs Bun / Node.js | | :- | :--- | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :--- | @@ -67,9 +67,10 @@ Across all **32 real-world multi-file TypeScript applications, framework suites, | **22** | `22-worker-threads-and-raw-sockets` (3 Worker Threads + TCP/UDP + 5-Ring Sec) | **`21.520 ms`** (`19.88 ms` Min) | **`21.161 ms`** | **`2.217 ms`** | `20.938 ms` (`2.8%`) | `57.852 ms` | `113.393 ms` | `103.236 ms` | **`2.73x Bun` (`26.09x` Warm) / `4.88x Node`** | | **23** | `23-wasm-crypto-and-simd-kernel` (Pure-Rust `WebAssembly` + 5-Ring WASM Sec) | **`15.912 ms`** (`14.82 ms` Min) | **`15.965 ms`** | **`1.955 ms`** | `15.069 ms` (`5.6%`) | `21.598 ms` | `42.081 ms` | `61.413 ms` | **`1.36x Bun` (`11.05x` Warm) / `3.86x Node`** | | **24** | `24-tsx-ssr-and-wasm-edge-pipeline` (`WebAssembly` SLA Scorer + SSR Pipeline) | **`8.927 ms`** (`8.48 ms` Min) | **`9.257 ms`** | **`1.824 ms`** | `8.419 ms` (`6.0%`) | `19.246 ms` | `43.391 ms` | `69.066 ms` | **`2.16x Bun` (`10.55x` Warm) / `7.74x Node`** | -| **FW-01** | `FW-01: frameworks/01-hono-edge-microservice` (`hono@4.6.20` + `hono/cookie` + `ms`) | **`15.318 ms`** (`14.30 ms` Min) | **`16.199 ms`** | **`6.483 ms`** | `15.140 ms` (`1.2%`) | `20.415 ms` | `54.052 ms` | `96.960 ms` | **`1.33x Bun` (`3.15x` Warm) / `6.33x Node`** | -| **FW-02** | `FW-02: frameworks/02-itty-router-unjs-nitro-stack` (`itty-router` + UnJS) | **`18.321 ms`** (`17.05 ms` Min) | **`18.916 ms`** | **`8.790 ms`** | `17.873 ms` (`2.5%`) | `20.104 ms` | `47.450 ms` | `89.334 ms` | **`1.10x Bun` (`2.29x` Warm) / `4.88x Node`** | -| **FW-03** | `FW-03: frameworks/03-node-http-express-compat` (`node:http` + `node:stream` Express/Polka) | **`16.913 ms`** (`15.81 ms` Min) | **`17.379 ms`** | **`1.070 ms`** | `16.410 ms` (`3.1%`) | `35.105 ms` | `50.537 ms` | `86.593 ms` | **`2.08x Bun` (`32.81x` Warm) / `5.12x Node`** | +| **FW-01** | `FW-01: frameworks/01-hono-edge-microservice` (`hono@4.6.20` + `hono/cookie` + `ms`) | **`16.071 ms`** (`14.92 ms` Min) | **`15.859 ms`** | **`5.721 ms`** | `15.318 ms` (`4.9%`) | `19.913 ms` | `53.967 ms` | `99.710 ms` | **`1.26x Bun` (`3.48x` Warm) / `6.29x Node`** | +| **FW-02** | `FW-02: frameworks/02-itty-router-unjs-nitro-stack` (`itty-router` + UnJS) | **`19.468 ms`** (`18.25 ms` Min) | **`18.506 ms`** | **`9.528 ms`** | `18.321 ms` (`6.3%`) | `19.441 ms` | `47.715 ms` | `91.467 ms` | **`1.05x Bun` (`2.04x` Warm) / `4.94x Node`** | +| **FW-03** | `FW-03: frameworks/03-node-http-express-compat` (`node:http` + `node:stream` Express/Polka) | **`16.830 ms`** (`16.23 ms` Min) | **`17.159 ms`** | **`1.300 ms`** | `16.913 ms` (`-0.5%`) | `49.313 ms` | `68.567 ms` | `95.033 ms` | **`2.93x Bun` (`37.93x` Warm) / `5.65x Node`** | +| **FW-04** | `FW-04: frameworks/04-sveltekit-edge-ssr` (`@sveltejs/kit@3.1.1` + `svelte@5.57.3` + `devalue@6.0.3`) | **`36.160 ms`** (`33.80 ms` Min) | **`37.795 ms`** | **`17.019 ms`** | — | `46.579 ms` | `71.052 ms` | `119.710 ms` | **`1.29x Bun` (`2.74x` Warm) / `3.31x Node`** | | **CS-01** | `CS-01: case_studies/01-tot-autonomous-sre-agent` (20 ToT Sandboxes) | **`26.485 ms`** (`25.52 ms` Min) | **`28.096 ms`** | **`13.120 ms`** | `26.690 ms` (`-0.8%`) | `28.256 ms` | `72.647 ms` | `89.711 ms` | **`1.07x Bun` (`2.15x` Warm) / `3.39x Node`** | | **CS-02** | `CS-02: case_studies/02-mcp-code-mode-orchestrator` (`-98.4%` Tokens) | **`20.362 ms`** (`19.29 ms` Min) | **`21.082 ms`** | **`7.854 ms`** | `19.966 ms` (`2.0%`) | `16.230 ms` | `44.344 ms` | `66.894 ms` | **`2.07x Bun Warm` / `3.29x Node`** | | **CS-03** | `CS-03: case_studies/03-multi-tenant-saas-plugin-mesh` (12 Tenants + Hot-Swap) | **`13.984 ms`** (`12.95 ms` Min) | **`14.000 ms`** | **`6.270 ms`** | `13.726 ms` (`1.9%`) | `16.305 ms` | `49.236 ms` | `84.935 ms` | **`1.17x Bun` (`2.60x` Warm) / `6.07x Node`** | @@ -87,15 +88,16 @@ Across all **32 real-world multi-file TypeScript applications, framework suites, | **App 21: RFC 6455 WS + Sec** | **13,952 KB (13.63 MB)** | 32,088 KB (31.34 MB) | 50,848 KB (49.66 MB) | 94,724 KB (92.50 MB) | **6.79x less than Node / 2.30x less than Bun** | | **App 22: Workers + Sockets** | **22,016 KB (21.50 MB)** | 41,568 KB (40.59 MB) | 62,868 KB (61.39 MB) | 94,028 KB (91.82 MB) | **4.27x less than Node / 1.89x less than Bun** | | **App 23: Pure-Rust WASM** | **18,944 KB (18.50 MB)** | 30,976 KB (30.25 MB) | 48,924 KB (47.78 MB) | 80,660 KB (78.77 MB) | **4.26x less than Node / 1.64x less than Bun** | -| **FW 1: Hono v4 Microservice** | **15,232 KB (14.88 MB)** | 31,224 KB (30.49 MB) | 49,436 KB (48.28 MB) | 89,116 KB (87.03 MB) | **5.85x less than Node / 2.05x less than Bun** | -| **FW 2: itty-router + UnJS** | **14,592 KB (14.25 MB)** | 32,128 KB (31.38 MB) | 48,544 KB (47.41 MB) | 87,180 KB (85.14 MB) | **5.97x less than Node / 2.20x less than Bun** | +| **FW 1: Hono v4 Microservice** | **15,104 KB (14.75 MB)** | 30,624 KB (29.91 MB) | 49,008 KB (47.86 MB) | 88,988 KB (86.90 MB) | **5.89x less than Node / 2.03x less than Bun** | +| **FW 2: itty-router + UnJS** | **14,720 KB (14.38 MB)** | 31,616 KB (30.88 MB) | 48,628 KB (47.49 MB) | 86,796 KB (84.76 MB) | **5.90x less than Node / 2.15x less than Bun** | | **App 24: WASM + SSR** | **13,696 KB (13.38 MB)** | 32,256 KB (31.50 MB) | 48,544 KB (47.41 MB) | 81,152 KB (79.25 MB) | **5.93x less than Node / 2.36x less than Bun** | -| **FW 3: Express node:http** | **14,976 KB (14.63 MB)** | 33,152 KB (32.38 MB) | 46,956 KB (45.86 MB) | 80,136 KB (78.26 MB) | **5.35x less than Node / 2.21x less than Bun** | +| **FW 3: Express node:http** | **14,976 KB (14.63 MB)** | 33,024 KB (32.25 MB) | 46,564 KB (45.47 MB) | 79,884 KB (78.01 MB) | **5.33x less than Node / 2.21x less than Bun** | | **01-tot-autonomous-sre-agent** | **18,560 KB (18.13 MB)** | 31,744 KB (31.00 MB) | 52,980 KB (51.74 MB) | 86,016 KB (84.00 MB) | **4.63x less than Node / 1.71x less than Bun** | | **02-mcp-code-mode-orchestrator** | **18,112 KB (17.69 MB)** | 27,904 KB (27.25 MB) | 47,068 KB (45.96 MB) | 80,648 KB (78.76 MB) | **4.45x less than Node / 1.54x less than Bun** | | **03-multi-tenant-saas-plugin-mesh** | **15,744 KB (15.38 MB)** | 28,672 KB (28.00 MB) | 49,480 KB (48.32 MB) | 87,940 KB (85.88 MB) | **5.59x less than Node / 1.82x less than Bun** | | **04-wasm-zero-trust-cdr-pipeline** | **19,968 KB (19.50 MB)** | 31,104 KB (30.38 MB) | 49,692 KB (48.53 MB) | 80,136 KB (78.26 MB) | **4.01x less than Node / 1.56x less than Bun** | | **05-time-travel-chaos-fuzzer-payments** | **15,744 KB (15.38 MB)** | 29,184 KB (28.50 MB) | 49,780 KB (48.61 MB) | 81,440 KB (79.53 MB) | **5.17x less than Node / 1.85x less than Bun** | +| **FW 4: SvelteKit 3 + Svelte 5** | **20,992 KB (20.50 MB)** | 41,984 KB (41.00 MB) | 56,580 KB (55.25 MB) | 85,412 KB (83.41 MB) | **4.07x less than Node / 2.00x less than Bun** | --- diff --git a/tests/run_real_stack_benchmarks.sh b/tests/run_real_stack_benchmarks.sh index 14cdd56..f52e684 100644 --- a/tests/run_real_stack_benchmarks.sh +++ b/tests/run_real_stack_benchmarks.sh @@ -89,6 +89,7 @@ APP24_DIR="$APPS_DIR/24-tsx-ssr-and-wasm-edge-pipeline" APP25_DIR="$FRAMEWORKS_DIR/01-hono-edge-microservice" APP26_DIR="$FRAMEWORKS_DIR/02-itty-router-unjs-nitro-stack" APP32_DIR="$FRAMEWORKS_DIR/03-node-http-express-compat" +APP33_DIR="$FRAMEWORKS_DIR/04-sveltekit-edge-ssr" APP27_DIR="$CASE_STUDIES_DIR/01-tot-autonomous-sre-agent" APP28_DIR="$CASE_STUDIES_DIR/02-mcp-code-mode-orchestrator" APP29_DIR="$CASE_STUDIES_DIR/03-multi-tenant-saas-plugin-mesh" @@ -218,9 +219,9 @@ record_jsonl "{\"type\":\"meta\",\"version\":\"$SLICE_VERSION\",\"commit\":\"$SL if should_run_tag "apps"; then echo "=========================================================================" -echo " [TAG: apps] PACKING & COMPILING ALL 27 APPS & FRAMEWORK SUITES (OXC + CAS)" +echo " [TAG: apps] PACKING & COMPILING ALL 28 APPS & FRAMEWORK SUITES (OXC + CAS)" echo "=========================================================================" -for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 32; do +for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 32 33; do if [ -n "${SLICE_ONLY_APPS:-}" ] && [[ ",${SLICE_ONLY_APPS}," != *",${i},"* ]]; then continue fi @@ -294,6 +295,7 @@ verify_app_parity "App 24: 24-tsx-ssr-and-wasm-edge-pipeline (WebAssembly SLA Sc verify_app_parity "Framework 1 (App 25): 01-hono-edge-microservice (Hono v4.6.20 + hono/cookie + cookie + ms)" "$APP25_DIR" "/tmp/app25.cas" "-A" verify_app_parity "Framework 2 (App 26): 02-itty-router-unjs-nitro-stack (itty-router v5 + ufo + destr + ohash + radix3)" "$APP26_DIR" "/tmp/app26.cas" "-A" verify_app_parity "Framework 3 (App 32): 03-node-http-express-compat (node:http + node:stream Express/Polka)" "$APP32_DIR" "/tmp/app32.cas" "-A" +verify_app_parity "Framework 4 (App 33): 04-sveltekit-edge-ssr (SvelteKit v3.1.1 + Svelte v5.57.3 + devalue v6.0.3)" "$APP33_DIR" "/tmp/app33.cas" "-A" fi measure_ms() { @@ -425,6 +427,7 @@ bench_app 24 "24-TSX-SSR-AND-WASM-EDGE-PIPELINE (WebAssembly SLA Scorer + SSR Pi bench_app 25 "FRAMEWORK 1: 01-HONO-EDGE-MICROSERVICE (Hono v4.6.20 + hono/cookie + cookie + ms)" "$APP25_DIR" "-A" bench_app 26 "FRAMEWORK 2: 02-ITTY-ROUTER-UNJS-NITRO-STACK (itty-router v5 + ufo + destr + ohash + radix3)" "$APP26_DIR" "-A" bench_app 32 "FRAMEWORK 3: 03-NODE-HTTP-EXPRESS-COMPAT (node:http + node:stream Express/Polka)" "$APP32_DIR" "-A" +bench_app 33 "FRAMEWORK 4: 04-SVELTEKIT-EDGE-SSR (SvelteKit v3.1.1 + Svelte v5.57.3 + devalue v6.0.3)" "$APP33_DIR" "-A" if [ -z "${SLICE_ONLY_APPS:-}" ]; then echo "=========================================================================" @@ -464,20 +467,25 @@ measure_rss_kb "Slice (FW 2: itty-router + UnJS)" "$SLICE_BIN" run "/tmp/app26 measure_rss_kb "Bun (FW 2: itty-router + UnJS)" bun run "$APP26_DIR/src/index.ts" measure_rss_kb "Deno (FW 2: itty-router + UnJS)" deno run -A "$APP26_DIR/src/index.ts" measure_rss_kb "Node (FW 2: itty-router + UnJS)" node "$APP26_DIR/src/index.ts" +echo "-------------------------------------------------------------------------" +measure_rss_kb "Slice (FW 4: SvelteKit 3 + Svelte 5)" "$SLICE_BIN" run "/tmp/app33.cas" --quiet +measure_rss_kb "Bun (FW 4: SvelteKit 3 + Svelte 5)" bun run "$APP33_DIR/src/index.ts" +measure_rss_kb "Deno (FW 4: SvelteKit 3 + Svelte 5)" deno run -A "$APP33_DIR/src/index.ts" +measure_rss_kb "Node (FW 4: SvelteKit 3 + Svelte 5)" node "$APP33_DIR/src/index.ts" fi echo "=========================================================================" -echo " SLICE INTERNAL ISOLATE TELEMETRY ACROSS ALL 27 APPS (COLD VS WARM POOL)" +echo " SLICE INTERNAL ISOLATE TELEMETRY ACROSS ALL 28 APPS (COLD VS WARM POOL)" echo "=========================================================================" echo " --- Cold Realm Telemetry ---" -for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 32; do +for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 32 33; do if [ -n "${SLICE_ONLY_APPS:-}" ] && [[ ",${SLICE_ONLY_APPS}," != *",${i},"* ]]; then continue fi "$SLICE_BIN" run "/tmp/app${i}.cas" --quiet --metrics done echo " --- Pre-Warmed Boa Pool Telemetry (--warm) ---" -for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 32; do +for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 32 33; do if [ -n "${SLICE_ONLY_APPS:-}" ] && [[ ",${SLICE_ONLY_APPS}," != *",${i},"* ]]; then continue fi @@ -1115,7 +1123,7 @@ fi if should_run_tag "frameworks"; then echo "=========================================================================" -echo " [TAG: frameworks] WAVE E REAL-WORLD FRAMEWORK SUITES (HONO, ITTY+UNJS, EXPRESS)" +echo " [TAG: frameworks] WAVE E REAL-WORLD FRAMEWORK SUITES (HONO, ITTY+UNJS, EXPRESS, SVELTEKIT)" echo "=========================================================================" "$SLICE_BIN" pack "$APP25_DIR" "/tmp/app25.cas" >/dev/null "$SLICE_BIN" compile "/tmp/app25.cas" -o "/tmp/app25_bin" >/dev/null @@ -1123,12 +1131,16 @@ echo "=========================================================================" "$SLICE_BIN" compile "/tmp/app26.cas" -o "/tmp/app26_bin" >/dev/null "$SLICE_BIN" pack "$APP32_DIR" "/tmp/app32.cas" >/dev/null "$SLICE_BIN" compile "/tmp/app32.cas" -o "/tmp/app32_bin" >/dev/null +"$SLICE_BIN" pack "$APP33_DIR" "/tmp/app33.cas" >/dev/null +"$SLICE_BIN" compile "/tmp/app33.cas" -o "/tmp/app33_bin" >/dev/null verify_app_parity "Framework 1 (App 25): 01-hono-edge-microservice" "$APP25_DIR" "/tmp/app25.cas" "-A" verify_app_parity "Framework 2 (App 26): 02-itty-router-unjs-nitro-stack" "$APP26_DIR" "/tmp/app26.cas" "-A" verify_app_parity "Framework 3 (App 32): 03-node-http-express-compat" "$APP32_DIR" "/tmp/app32.cas" "-A" +verify_app_parity "Framework 4 (App 33): 04-sveltekit-edge-ssr" "$APP33_DIR" "/tmp/app33.cas" "-A" bench_app 25 "FRAMEWORK 1: 01-HONO-EDGE-MICROSERVICE (Hono v4.6.20 + hono/cookie + cookie + ms)" "$APP25_DIR" "-A" bench_app 26 "FRAMEWORK 2: 02-ITTY-ROUTER-UNJS-NITRO-STACK (itty-router v5 + ufo + destr + ohash + radix3)" "$APP26_DIR" "-A" bench_app 32 "FRAMEWORK 3: 03-NODE-HTTP-EXPRESS-COMPAT (node:http + node:stream Express/Polka)" "$APP32_DIR" "-A" +bench_app 33 "FRAMEWORK 4: 04-SVELTEKIT-EDGE-SSR (SvelteKit v3.1.1 + Svelte v5.57.3 + devalue v6.0.3)" "$APP33_DIR" "-A" measure_rss_kb "Slice (FW 1: Hono v4 Microservice)" "$SLICE_BIN" run "/tmp/app25.cas" --quiet measure_rss_kb "Bun (FW 1: Hono v4 Microservice)" bun run "$APP25_DIR/src/index.ts" measure_rss_kb "Deno (FW 1: Hono v4 Microservice)" deno run -A "$APP25_DIR/src/index.ts" @@ -1143,16 +1155,24 @@ measure_rss_kb "Slice (FW 3: Express node:http)" "$SLICE_BIN" run "/tmp/app32 measure_rss_kb "Bun (FW 3: Express node:http)" bun run "$APP32_DIR/src/index.ts" measure_rss_kb "Deno (FW 3: Express node:http)" deno run -A "$APP32_DIR/src/index.ts" measure_rss_kb "Node (FW 3: Express node:http)" node "$APP32_DIR/src/index.ts" -echo " --- Frameworks 1..3 Cold vs Warm Isolate Telemetry ---" +echo "-------------------------------------------------------------------------" +measure_rss_kb "Slice (FW 4: SvelteKit 3 + Svelte 5)" "$SLICE_BIN" run "/tmp/app33.cas" --quiet +measure_rss_kb "Bun (FW 4: SvelteKit 3 + Svelte 5)" bun run "$APP33_DIR/src/index.ts" +measure_rss_kb "Deno (FW 4: SvelteKit 3 + Svelte 5)" deno run -A "$APP33_DIR/src/index.ts" +measure_rss_kb "Node (FW 4: SvelteKit 3 + Svelte 5)" node "$APP33_DIR/src/index.ts" +echo " --- Frameworks 1..4 Cold vs Warm Isolate Telemetry ---" "$SLICE_BIN" run "/tmp/app25.cas" --quiet --metrics record_warm_metrics 25 "/tmp/app25.cas" "$SLICE_BIN" run "/tmp/app26.cas" --quiet --metrics record_warm_metrics 26 "/tmp/app26.cas" "$SLICE_BIN" run "/tmp/app32.cas" --quiet --metrics record_warm_metrics 32 "/tmp/app32.cas" +"$SLICE_BIN" run "/tmp/app33.cas" --quiet --metrics +record_warm_metrics 33 "/tmp/app33.cas" echo " [Live slice test Runner Verification on Framework Suites]" "$SLICE_BIN" test "$APP25_DIR" "$SLICE_BIN" test "$APP26_DIR" +"$SLICE_BIN" test "$APP33_DIR" fi if should_run_tag "case_studies"; then diff --git a/tests/scripts/generate_bench_report.mjs b/tests/scripts/generate_bench_report.mjs index db09204..fb5ccfb 100644 --- a/tests/scripts/generate_bench_report.mjs +++ b/tests/scripts/generate_bench_report.mjs @@ -35,6 +35,7 @@ export const WORKLOAD_METADATA = [ { num: 25, code: "FW-01", id: "frameworks/01-hono-edge-microservice", label: "`FW-01: frameworks/01-hono-edge-microservice` (`hono@4.6.20` + `hono/cookie` + `ms`)", category: "frameworks", flagship: true }, { num: 26, code: "FW-02", id: "frameworks/02-itty-router-unjs-nitro-stack", label: "`FW-02: frameworks/02-itty-router-unjs-nitro-stack` (`itty-router` + UnJS)", category: "frameworks", flagship: false }, { num: 32, code: "FW-03", id: "frameworks/03-node-http-express-compat", label: "`FW-03: frameworks/03-node-http-express-compat` (`node:http` + `node:stream` Express/Polka)", category: "frameworks", flagship: false }, + { num: 33, code: "FW-04", id: "frameworks/04-sveltekit-edge-ssr", label: "`FW-04: frameworks/04-sveltekit-edge-ssr` (`@sveltejs/kit@3.1.1` + `svelte@5.57.3` + `devalue@6.0.3`)", category: "frameworks", flagship: true }, { num: 27, code: "CS-01", id: "case_studies/01-tot-autonomous-sre-agent", label: "`CS-01: case_studies/01-tot-autonomous-sre-agent` (20 ToT Sandboxes)", category: "case_studies", flagship: true }, { num: 28, code: "CS-02", id: "case_studies/02-mcp-code-mode-orchestrator", label: "`CS-02: case_studies/02-mcp-code-mode-orchestrator` (`-98.4%` Tokens)", category: "case_studies", flagship: false }, { num: 29, code: "CS-03", id: "case_studies/03-multi-tenant-saas-plugin-mesh", label: "`CS-03: case_studies/03-multi-tenant-saas-plugin-mesh` (12 Tenants + Hot-Swap)", category: "case_studies", flagship: false }, @@ -65,8 +66,8 @@ export const CATEGORY_DEFINITIONS = [ }, { id: "frameworks", - title: "Full-Stack Edge & Node Frameworks (`FW 01–03`)", - focus: "`Hono v4.6.20`, `itty-router + UnJS Nitro`, `Express/Polka node:http`" + title: "Full-Stack Edge & Node Frameworks (`FW 01–04`)", + focus: "`Hono v4.6.20`, `itty-router + UnJS Nitro`, `Express/Polka node:http`, `SvelteKit 3.1.1 + Svelte 5.57.3`" }, { id: "case_studies", diff --git a/tests/scripts/sync_doc_benchmarks.mjs b/tests/scripts/sync_doc_benchmarks.mjs index 710935c..dad7de2 100644 --- a/tests/scripts/sync_doc_benchmarks.mjs +++ b/tests/scripts/sync_doc_benchmarks.mjs @@ -77,9 +77,9 @@ export function renderSummaryBlock(report, relativePathToLatestMd, relativePathT return `| **${cat.title}**
${cat.focus} | \`${items.length}\` | **\`${catColdAvg.toFixed(2)} ms\`** (\`${minVal(sliceColdAvgs).toFixed(2)}–${maxVal(sliceColdAvgs).toFixed(2)} ms\`) | **\`${catWarmAvg.toFixed(2)} ms\`** | \`${catBunAvg.toFixed(2)} ms\` | \`${catDenoAvg.toFixed(2)} ms\` | \`${catNodeAvg.toFixed(2)} ms\` | **\`${vsBunCold}x Bun\` (\`${vsBunWarm}x\` Warm) / \`${vsNodeCold}x Node\`** |`; }).join("\n"); - // Flagship rows (top 8 representative real-life workloads) - const flagshipRows = workloads - .filter((w) => w.flagship) + // Flagship rows (top representative real-life workloads) + const flagshipItems = workloads.filter((w) => w.flagship); + const flagshipRows = flagshipItems .map((w) => { const sliceColdBest = Math.min(w.sliceCasAvgMs, w.sliceBinAvgMs); const vsBunCold = (w.bunAvgMs / sliceColdBest).toFixed(2); @@ -114,7 +114,7 @@ export function renderSummaryBlock(report, relativePathToLatestMd, relativePathT | :--- | :---: | :---: | :---: | :---: | :---: | :---: | :--- | ${categoryRows} -#### 3. Flagship Real-World Representative Workloads (8 of ${totalCount} Highlights) +#### 3. Flagship Real-World Representative Workloads (${flagshipItems.length} of ${totalCount} Highlights) | # | Flagship Workload | Slice Cold \`.cas\` | Slice Warm (\`--warm\`) | Bun \`${meta.runtimes.bun}\` | Deno \`${meta.runtimes.deno}\` | Node.js \`${meta.runtimes.node}\` | Speedup vs Bun / Node.js | | :- | :--- | :---: | :---: | :---: | :---: | :---: | :--- |