3.2 KiB
Feature templates — features.ts
Purpose
Owns every renderer that produces a per-feature file in the scaffolded
output: i18n, networking (basic + full), api, api-schemas,
storage, auth, form-builder, and r3f. The renderers are pure
functions over ProjectOptions; the r3f renderer additionally branches
on options.r3fModules to wire camera / physics / particles / character
/ pathfinding subsystems into the emitted scene.
The companion templates.ts module covers the project-level renderers;
the two together replace the upstream src/templates/*.ts and
src/templates/features/*.ts blob set. renderFeature(feature, options) is the single dispatch entry the generator uses; individual
render*Feature helpers are exported for tools that want to render a
single feature in isolation (for example, a "show me the API skeleton"
preview pane in an IDE extension).
Features
- Eight per-feature renderers — every closed
FeatureModulevalue has a dedicated implementation. renderNetworkFeaturevsrenderNetworkFullFeatureselected byoptions.networkingComplexity.renderR3fFeaturecomposes the camera / physics / particles imports- scene fragments based on
options.r3fModules.
- scene fragments based on
featurePath(feature)returns the canonical output path for each feature (the generator uses this to assemble the file list).
Usage: Basic
import { renderFeature, featurePath } from "@suaveplan/electrobun/templates";
const content = renderFeature("i18n", opts);
const path = featurePath("i18n");
// path === "src/features/i18n.ts"
Usage: Advanced
import {
featurePath,
renderFeature,
} from "@suaveplan/electrobun/templates";
const featureFiles = opts.features.map((f) => ({
path: featurePath(f),
content: renderFeature(f, opts),
}));
API Reference
renderI18nFeature(),renderNetworkFeature(),renderNetworkFullFeature(),renderApiFeature(),renderApiSchemasFeature(),renderStorageFeature(),renderAuthFeature(),renderFormBuilderFeature(),renderR3fFeature(options).renderFeature(feature: FeatureModule, options: ProjectOptions): string— dispatch table.featurePath(feature: FeatureModule): string.
Implementation Notes
The r3f renderer is the only one whose output is materially shaped by
ProjectOptions beyond the basic "the feature is enabled" toggle. The
imports and scene fragments are assembled by joining arrays of strings,
which makes the relative ordering deterministic and the diff-noise low
when a new R3F module is added: the test for "r3f renderer emits the
requested modules" pins the order so a refactor cannot silently
re-shuffle imports.
The networking renderer dispatches on options.networkingComplexity
rather than options.networking because the upstream contract used
"basic" / "full" to gate the full mesh layer. Keeping the same
contract means downstream electrobun projects already on the
networkingComplexity shape do not need to migrate.
featurePath lives here rather than in the generator because the
mapping is per-feature; the generator consumes it as a thin lookup. If
a future feature lands with a non-default output path, the change is
local to features.ts.