feat(interop): support Bun and Deno as JavaScript bridge hosts - #190
Conversation
Projects can set javascript.host to bun or deno so the Node runtime bridge spawns the chosen interpreter with host-specific argv, permissions, and RPC transport. Bun and Deno bootstrap E2E tests run in CI via test:bridge-host-e2e, with Deno pinned via .deno-version. feat(interop)!: ship compiled legacy modules without tsx at runtime Add javascript.legacyModules.format (compiled or typescript) and esbuild precompile of legacy TypeScript into .forst/js at compile time. Production defaults to compiled bundles, so deployed apps no longer require tsx unless typescript format is explicitly chosen on Node. forst build -o copies .forst/js beside the output binary. BREAKING CHANGE: node.loader is deprecated; use javascript.legacyModules.format. The default runtime mode is compiled JavaScript, not tsx-backed TypeScript source. Set javascript.legacyModules.format to typescript to restore the previous behavior. feat(imports): safe local names for node imports with LSP quickfixes Node imports now derive and validate local binding names (reserved words, invalid identifiers, collisions). The typechecker reports clear diagnostics and the LSP offers quickfixes to apply suggested aliases. Examples and docs use explicit import "./path" node syntax throughout.
|
Preview deployment for your docs. Learn more about Mintlify Previews.
💡 Tip: Enable Workflows to automatically generate PRs for you. |
|
Important Review skippedToo many files! This PR contains 431 files, which is 331 over the limit of 100. To get a review, reduce the PR to 100 files or fewer by splitting it into smaller PRs or changing its base branch. Upgrade to a paid plan to raise the limit. Usage-priced reviews support at most 300 files. ⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: ⛔ Files ignored due to path filters (4)
📒 Files selected for processing (431)
You can disable this status message by setting the Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
…forst/runtime Replace Node-branded interop vocabulary with host-neutral naming across syntax, configuration, npm, Go packages, docs, and CI. Import opt-in is now the `js` suffix; ftconfig uses a single `bridge` section; the script-side npm package is `@forst/runtime` with `forst-runtime-bootstrap` and `forst-runtime-index` bins. Rename `forst/nodert` to `forst/bridgert` and `internal/nodeinterop` to `internal/bridgeinterop`. Rename examples to `bridge-interop`, move Forst→JS docs under `/interop/bridge/`, and update release-please, publish workflows, and Taskfile targets accordingly. Install esbuild in CI for compiled legacy-module precompile tests; fix indexer interpreter selection so host-mode app binaries (e.g. remix-serve) are not used for compile-time indexing. BREAKING CHANGE: Migrate in one step — no compatibility shims remain. 1. Replace `import "./path" node` with `import "./path" js`. 2. Collapse `ftconfig.node` and `ftconfig.javascript` into `bridge` (use `bridge.legacyModules.format` instead of `node.loader`). 3. `npm install @forst/runtime` and remove `@forst/node-runtime`. 4. Rename deploy env vars `FORST_NODE_*` to `FORST_BRIDGE_*`. 5. Point bootstrap defaults to `node_modules/@forst/runtime/dist/bootstrap.js`. 6. Replace CLI flag `-require-no-node` with `-require-no-bridge`.
Compiled bridge modules now resolve from a configurable directory instead of
being tied to the Go binary path. Esbuild still writes bundles to `.forst/js`
under the project boundary at compile time. Runtime loads them from
`FORST_BRIDGE_MODULES_DIR`, `bridge.legacyModules.dir`, or the default
`{FORST_ROOT}/.forst/js`.
Manifest module IDs are relative to the compiled modules directory (for example
`legacy/payment.js`). Initialize RPC and spawn pass `modulesDir` separately
from `boundaryRoot`. The TypeScript runtime resolves `.js` modules under that
directory with the same path jail rules. Deno spawn includes the directory in
read permissions.
`forst build -o` records `compiledModulesDir` and related fields in
`manifest.json` and no longer copies `.forst/js` beside the binary. Missing
compiled module directories produce a clear error that names
`FORST_BRIDGE_MODULES_DIR`.
BREAKING CHANGE: Compiled module manifest IDs no longer use a `.forst/js/`
prefix. Deployments must ship the compiled modules tree separately and set
`FORST_BRIDGE_MODULES_DIR` or `bridge.legacyModules.dir` when it is not at the
default path under `FORST_ROOT`.
… GitHub links Restructure the documentation navigation by splitting JavaScript interop into two clear sections: calling Forst from JavaScript under invoke docs and calling JavaScript from Forst under bridge docs. Set up redirects for legacy node interop paths. Streamline the hand-written Go section in the Go interop guide while expanding the caveats section to cover generic APIs, interface satisfaction, unsafe usage, opaque structs, and sandbox limitations in detail. Replace local task command references across all documentation pages with direct links to the corresponding example source files on GitHub.
Compiled legacy modules remap manifest exports to .js, but codegen still passed .ts module IDs to bridgert and caused forbidden manifest errors at runtime. BridgeCallTarget now carries a runtime ModuleID (.js when compiled) and a SourceModuleID (.ts) for TypeScript index lookups and wrapper codegen. Rename generated bridge companions and internal APIs from node to bridge without deprecated aliases: forst_0_bridge_runtime.gen.go, forstBridgeManifestJSON, forst_bridge_* wrappers, ForstBridgeWaitForShutdown, CompileWithBridgeRuntime, NeedsBridgeRuntime, BridgeCallTarget, and related compiler, typechecker, transformer, and bridgert symbols. Refresh bridge-interop example goldens accordingly. Harden bridgert tests by skipping Deno spawn hooks when deno is absent, resetting supervisorCfg in test teardown, and clearing FORST_BRIDGE_ATTACH_ONLY in the bootstrap death/respawn test. BREAKING CHANGE: Generated bridge companion filenames and symbols use bridge instead of node. Internal compiler and typechecker entry points and types were renamed to Bridge* (for example CompileWithBridgeRuntime and BridgeCallTarget); update any code or tests that referenced the old names.
… e2e Default empty hostSocket resolution now uses .forst/bridge.sock to match ftconfig, and the multipackage-dev reload e2e waits on bridge.sock.ready instead of the obsolete node.sock.ready path. Drop legacyNodeRuntimeOutputPath companion cleanup and the matching gitattributes linguist rule; keep only the immediate prior bridge runtime filename. Fix devserver tests after the Node→Bridge config rename by using c.Bridge.HostMode and compiled legacy/counter.js in the reload reattach fixture so host spawn without tsx can load modules under the default compiled format.
Projects can set
javascript.hosttobunordenoso the Node runtime bridgespawns the chosen interpreter with host-specific argv, permissions, and RPC
transport. Bun and Deno bootstrap E2E tests run in CI via
test:bridge-host-e2e, with Deno pinned via.deno-version.feat(interop)!: ship compiled legacy modules without tsx at runtime
Add
javascript.legacyModules.format(compiledortypescript) and esbuildprecompile of legacy TypeScript into
.forst/jsat compile time. Productiondefaults to compiled bundles, so deployed apps no longer require
tsxunlesstypescriptformat is explicitly chosen on Node.forst build -ocopies.forst/jsbeside the output binary.BREAKING CHANGE:
node.loaderis deprecated; usejavascript.legacyModules.format.The default runtime mode is compiled JavaScript, not
tsx-backed TypeScript source.Set
javascript.legacyModules.formattotypescriptto restore the previous behavior.feat(imports): safe local names for node imports with LSP quickfixes
Node imports now derive and validate local binding names (reserved words,
invalid identifiers, collisions). The typechecker reports clear diagnostics
and the LSP offers quickfixes to apply suggested aliases. Examples and docs
use explicit
import "./path" nodesyntax throughout.