Repository navigation
Codegen: --vscode-extension flag to inline extraImports wiring #105
Description
Problem
The Node-CJS codegen (lib/codegen_node.ml, added by #35 / #90) emits a .cjs shim that wraps the compiled wasm module. The shim exposes an extraImports hook that callers populate with the concrete vscode-API bindings before activate fires:
// Inside the generated extension.cjs:
const extras = (typeof exports.extraImports === "function")
? exports.extraImports()
: {};
return { wasi_snapshot_preview1, ...extras };Today, every consumer hand-writes a wrapper file to install extraImports before vscode's extension host calls activate. The pattern is identical across the three current consumers:
// hyperpolymath/my-lang:vscode-extension/src/index.cjs
// hyperpolymath/standards:rsr-certifier/extensions/vscode/src/index.cjs
// hyperpolymath/affinescript:editors/vscode/src/index.cjs (still to land)
const shim = require("../out/extension.cjs");
const makeVscodeBindings = require("./affine-vscode-adapter.cjs");
// or: const makeVscodeBindings = require("@hyperpolymath/affine-vscode");
shim.extraImports = () => makeVscodeBindings(
require("vscode"),
require("vscode-languageclient/node"),
shim,
);
exports.activate = shim.activate;
exports.deactivate = shim.deactivate;This boilerplate is 100% mechanical and identical in every extension. It's what's left to manually wire — and it's the thing #35's original plan called out as belonging in codegen:
(Real wiring belongs in the codegen — Phase 3 will replace this manual hookup with auto-generated glue once
extension.affineis the source of truth for the extension entry point.)
— packages/affine-vscode/README.adoc
Proposed plan
Add a codegen flag, e.g. --vscode-extension, that opts into emitting the wiring inline so the generated .cjs is directly loadable as a VS Code extension's main:
affinescript compile src/extension.affine -o out/extension.cjs --vscode-extension
The emitted shim then includes the equivalent of:
// Inserted by --vscode-extension:
const makeVscodeBindings = require("@hyperpolymath/affine-vscode");
exports.extraImports = function() {
return makeVscodeBindings(
require("vscode"),
require("vscode-languageclient/node"),
exports,
);
};… with @hyperpolymath/affine-vscode listed in the extension's package.json dependencies. (Once the npm-publish follow-up lands — see the sibling follow-up issue — this is a normal npm install.)
Each consumer's package.json main then points directly at out/extension.cjs. No hand-written index.cjs, no vendored affine-vscode-adapter.cjs file.
Sub-flags
--vscode-extension-adapter <module-specifier>— override therequire()specifier for the adapter (useful for testing against a local checkout or for extensions that vendor their own).--vscode-extension-no-lc— for extensions that don't ship a language client (novscode-languageclient/nodedependency); the wiring skips thatrequireand passesnull.
Acceptance criteria
-
affinescript compile src/extension.affine -o out/extension.cjs --vscode-extensionemits a fully-wired CJS module. - A VS Code extension whose
package.jsonmainpoints at the unmodified generated.cjsactivates and disposes cleanly. - The pilot in
editors/vscode/is migrated off the hand-writtenindex.cjs(once that wrapper exists; this work and the affinescript-pilot port in [Repo] Port editors/vscode/src/extension.ts to .affine once #35 lands #63 likely coordinate). - my-lang and standards downstream PRs simplify accordingly (their
index.cjs+ vendored adapter both disappear). - Codegen tests cover the
--vscode-extensionflag.
Out of scope
- A general
--vscode-target-language-server-extensionshape for extensions that aren't language-server-shaped. This issue covers the LSP+commands pattern that the current adapter implements. - A browser-host webworker variant (Node-only for now).
Related
- Codegen origin: Add Node-target backend + vscode-API bindings to enable .affine VS Code extensions #35 (Phase 1 + Phase 2), feat: typed-wasm xmod + Node backend + extern + VS Code (#35, #42) #90 (PR)
- Phase-2 hook the boilerplate lives around: see
_buildImports()in the emitted.cjs - Consumer pattern that this would eliminate:
- Related follow-up: npm-publishing the adapter (sibling issue) is a prerequisite for the default
require("@hyperpolymath/affine-vscode")to resolve in consumer projects.
Activity
affine-vscode: align docs with --vscode-extension + npm publish manif…