Expose broad public API surface#760
Merged
malberts merged 1 commit intofrontend-extensibilityfrom Apr 23, 2026
Merged
Conversation
6da22a2 to
bd8f5d3
Compare
25d17ba to
e6e15b3
Compare
e6e15b3 to
701a307
Compare
10 tasks
701a307 to
df6be71
Compare
bd8f5d3 to
bb0782c
Compare
Re-export every TS module (via wildcard) and every Vue component under
resources/ext.neowiki/src/ from the public-api barrel. Extensions using
require('ext.neowiki') can now reach anything NeoWiki itself exposes -
domain types and services, application-layer lookups and repositories,
persistence serializers/deserializers, stores, composables, and the
full component library.
0.x / alpha stability contract: the surface is provisional and any
symbol may be renamed or removed without migration guidance. A
curation pass to narrow the public API is planned before production
stabilisation. Consumers should pin specific NeoWiki commits during
the alpha phase.
Bundle size impact: 240 KB -> 251 KB raw (+11 KB / +4%), 63 KB -> 66 KB
gzipped (+3 KB / +5%). Acceptable for the flexibility it provides
during alpha build-out.
Stacks on top of #754.
df6be71 to
9bc30d5
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacks on top of #754.
Responds to Jeroen's narrow-vs-broad review point: the alpha surface on
ext.neowikiis broadened so downstream consumers don't hit "not exported" friction during build-out. Curation (narrowing) is deferred to a pre-production gate.Change
Expands
resources/ext.neowiki/src/public-api.tsfrom the narrow 4-symbol barrel (what RedHerb's DateTime happens to need today) to a wildcard re-export of every TS module and every Vue component underresources/ext.neowiki/src/. Extensions viarequire('ext.neowiki')can now reach:Runtime-verified: 146 named exports on
require('ext.neowiki'). Spot-checked in the browser —newStringValue,SubjectValidator,RestSchemaRepository,useSubjectStore,Infobox,SchemaEditorDialog,ValueType,PropertyName,FrontendRegistrarall resolve.Implementation choices considered
A. Hand-curated (this PR)
public-api.tslists every module withexport * from './path'for TS files andexport { default as Name } from './path.vue'for Vue files. ~130 lines today, one line per source file.Pros: explicit; reviewer sees every public symbol in the diff; works in any bundler; compile error at the line when a collision is introduced; no build tooling.
Cons: one line of maintenance per new file — but see Maintenance discussion below.
B. Pre-build codegen script
A small Node/TS script globs
src/, applies exclude rules (tests,*.d.ts, etc.), and emitspublic-api.ts. Script is invoked either as an npmprebuildhook or a Vite plugin. The generated file is either checked in (noisy rename diffs, but reviewer-visible) or gitignored and regenerated on install/build (cleaner diffs, opaque to reviewers).Example script shape (pseudocode):
Then
"prebuild": "node scripts/generate-public-api.mjs"inpackage.json.Pros: zero per-file maintenance; guaranteed no-un-exported-files.
Cons: adds a script + build step; generated-and-gitignored hides the surface from reviewers (they have to run the build to see what's public); generated-and-checked-in is noisier than hand-curated on every file rename; debugging the generated file is awkward (not a place humans edit).
C. Vite
import.meta.globSingle-line exposure via Vite-specific syntax:
Consumers access by file path:
To flatten into a single namespace (closer to today's ergonomics), we'd post-process:
Pros: truly zero maintenance; accurate by construction.
Cons: Vite-specific (won't work with other bundlers if we ever swap); file-path-keyed access is awkward for consumers; flattening silently overwrites on name collisions (hand-curated would error at build); TypeScript can't see through the glob so type exports are lost — consumers get runtime values but no type info.
Maintenance: why A wins for us
Two points make the hand-curated / approach-A choice clearer than the pros/cons above suggest:
1. AI-assisted development kills the "one line per file" cost.
With Claude Code (or similar) in the dev loop:
Foo.tsbut no barrel line").The historical human-cognitive-load case against hand-curated no longer applies.
2. We plan to narrow the surface before production anyway.
Autogen's (approaches B/C) value is "automatically expose everything, forever". The moment we want a curated subset, autogen becomes impossible by definition — curation is inherently manual. Investing in autogen during alpha would just be temporary infrastructure with a guaranteed end-of-life when we switch to the stable contract. Sticking with hand-curated now means zero transition cost later: we simply delete the lines we don't want to expose.
So: autogen only makes sense if broad-forever is the plan. It isn't. Hand-curated is correct for this project's full trajectory.
Stability contract
The barrel comment explicitly calls out
0.x / alpha— anything can change without notice. Consumers should pin specific NeoWiki commits during the alpha phase. A curation pass to narrow the surface is planned before production stabilisation.Bundle impact
Modest. Acceptable for the flexibility it provides during alpha.
Test plan
make ts-buildgreen — ~260 modules transformed, no name collisions (wildcardexport *errors out on conflicts; there are none today)make ts-test— 684 tests passmake ts-lint— cleanWhat this PR does not validate
The runtime probe confirms that 146 names are now accessible via
require('ext.neowiki'). That's a bindings check, not a behavioural one. None of the newly-exposed symbols — stores, composables, domain services, repositories, or any of the Vue components beyondNeoNestedField— have been exercised from an actual extension-consumer context.Concretely, we have not verified:
useChangeDetection,useCloseConfirmation) function outside the components they were designed alongside.RestSchemaRepository,RestLayoutRepository, etc.) don't depend on NeoWiki-internal injected context that's absent when instantiated from extension code.RedHerb's DateTime today exercises exactly four symbols (
newStringValue,ValueType,NeoWikiServices,NeoNestedField) — the rest of the 146 are available but untested as a public contract. Expect bugs when consumers start actually using them; the alpha stability caveat covers this, but the gap is worth naming explicitly.Follow-ups
export *will error at build. Fine for now; worth a script/check if the source tree grows a lot.