diff --git a/.github/workflows/bun.yml b/.github/workflows/bun.yml new file mode 100644 index 00000000..a403939a --- /dev/null +++ b/.github/workflows/bun.yml @@ -0,0 +1,65 @@ +name: Bun + +# Bun-native verification alongside the existing Node toolchain (build.yml is +# intentionally untouched to preserve the upstream merge path). +# +# Pinned Bun: 1.3.14 (revision 1.3.14+0d9b296af) — the release this port is +# verified against. Update the pin only together with docs/BUN_COMPATIBILITY.md. + +on: + push: + branches: [main, feat/bun-compat] + pull_request: + +jobs: + test: + runs-on: ${{ matrix.os }} + + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest] + bun-version: ['1.3.14'] + + steps: + - name: Check out + uses: actions/checkout@v6 + + - name: Setup Node + uses: actions/setup-node@v6 + with: + node-version: 24 + + - name: Setup Bun + uses: oven-sh/setup-bun@v2 + with: + bun-version: ${{ matrix.bun-version }} + + - name: Install (bun) + run: bun install + + - name: Build (node + yakumo) + run: |- + node --expose-internals --import tsx --import @cordisjs/unyaml \ + node_modules/yakumo/lib/cli.js esbuild + node --expose-internals --import tsx --import @cordisjs/unyaml \ + node_modules/yakumo/lib/cli.js tsc + + - name: Bun behavioral suite + run: bun test tests/bun + + # Downstream integration fixture for oven-sh/bun#32856 + # (import.meta.hot for bun --hot). Install is best-effort: PR artifact + # availability varies, and tests/bun/hot.spec.ts skips cleanly when the + # binary is absent — but a real failure in it fails CI. + - name: Install bun#32856 PR build (best effort) + run: bunx bun-pr 32856 + continue-on-error: true + + - name: bun#32856 integration suite + run: bun test tests/bun/hot.spec.ts + + - name: Node suite stays green alongside + run: |- + node --expose-internals --import tsx --import @cordisjs/unyaml \ + node_modules/yakumo/lib/cli.js vitest --import tsx diff --git a/bench/cold-loader.mjs b/bench/cold-loader.mjs new file mode 100644 index 00000000..f76a2b09 --- /dev/null +++ b/bench/cold-loader.mjs @@ -0,0 +1,22 @@ +// cold-start app: Loader + Include + 3 TypeScript plugins from config dir +import { Context } from 'cordis' +import Loader from '@cordisjs/plugin-loader' + +const dir = process.argv[2] +const ctx = new Context() +ctx.baseUrl = new URL('.', pathFromDir(dir)).href + +const fiber = await ctx.plugin(Loader) +await ctx.loader.create({ + name: '@cordisjs/plugin-include', + config: { path: './cordis.yml', enableLogs: false }, +}) +await ctx.loader.await() +console.log('READY') +await new Promise(r => setTimeout(r, 5)) +await fiber.dispose() +process.exit(0) + +function pathFromDir(d) { + return 'file://' + (d.endsWith('/') ? d : d + '/') +} diff --git a/bench/cold-min.mjs b/bench/cold-min.mjs new file mode 100644 index 00000000..b8684e1e --- /dev/null +++ b/bench/cold-min.mjs @@ -0,0 +1,8 @@ +// cold-start app: minimal (Context + 3 plugins) +import { Context } from 'cordis' +const ctx = new Context() +const p = c => { c.on('x', () => {}) } +await ctx.plugin(p); await ctx.plugin(p); await ctx.plugin(p) +console.log('READY') +await new Promise(r => setTimeout(r, 5)) +process.exit(0) diff --git a/bench/compare.mjs b/bench/compare.mjs new file mode 100644 index 00000000..0f194152 --- /dev/null +++ b/bench/compare.mjs @@ -0,0 +1,54 @@ +#!/usr/bin/env node +/** + * Compare bench passes across runtimes into a multi-config table. + * + * Reads bench/results/