Skip to content

Import the Fable runtime through a version-free bridge - #65

Merged
bitsforthought merged 4 commits into
mainfrom
maintenance/fable-library-bridge
Oct 10, 2026
Merged

bitsforthought merged 4 commits into
mainfrom
maintenance/fable-library-bridge

Conversation

@bitsforthought

Copy link
Copy Markdown
Owner

Why

Handwritten TypeScript imported the Fable runtime through versioned paths (fable-library-ts.5.1.0/...), so every Fable upgrade broke them with TS2307. This is one of the failures in #61.

What

  • scripts/GenerateFableLibraryBridge.fsx runs after each Fable compilation and writes one re-exporting module per runtime module to src/generated/fable-library/.
    • It reads the version from Fable's own first-party output and fails clearly when it finds no version, several versions or a missing runtime directory. It never picks the newest directory, since that may be stale.
    • It recreates the bridge directory on every run. Modules with a default export also re-export the default.
    • Its self-test covers the pure helpers, the exact error messages and the file-system behaviour, using a temporary tree.
  • The six handwritten imports now use generated/fable-library/<Module>.
  • An ESLint no-restricted-imports rule rejects fable_modules/fable-library-ts.* paths.
  • The Fable target, BuildSelfTest, AGENTS.md, the typescript-style skill and docs/build.md are updated.

Validation

  • npm run validate "--" --ci passes.
  • Dry run with Bump fable and Fable.Core #61's Fable 5.20.0 on this branch: it bridged 66 modules and produced no TS2307 errors.
  • Three-model adversarial review: clean after one fix round.

Follow-up

After this PR merges, comment @dependabot rebase on #61. That PR will still fail because Fable 5.20.0's own runtime has Temporal and number/bigint type errors; those need a separate fix.

Handwritten TypeScript imported Fable's runtime through paths such as
src/generated/fable_modules/fable-library-ts.5.1.0/List, so every Fable
upgrade broke those imports with TS2307 (as in Dependabot's #61).

After each Fable compilation, the new GenerateFableLibraryBridge.fsx script
writes one re-exporting module per runtime module to
src/generated/fable-library/. It reads the runtime version from Fable's own
first-party output and fails clearly when no version, several versions, or a
missing runtime directory is found, rather than picking the newest directory,
which may be stale. Re-exporting the same runtime copy keeps a single identity
for runtime classes. The bridge directory is recreated on each run so modules
removed by an upgrade do not linger.

Handwritten imports now use the bridge, an ESLint rule rejects versioned
runtime paths, and the Fable target, its build self-test, AGENTS.md, the
typescript-style skill and docs/build.md describe the new step.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 69277274-81a0-4daf-a296-338ec77f649f
Comment thread scripts/GenerateFableLibraryBridge.fsx Resolved
Comment thread scripts/GenerateFableLibraryBridge.fsx Resolved
Comment thread scripts/GenerateFableLibraryBridge.fsx Resolved
Separate command parsing, pure bridge logic, file-system operations and
self-tests into internal modules so the generator is easier to review.
Use raw interpolated literals for generated imports while preserving their
exact contents and trailing newlines. Clarify the regex word boundary and
pin its rejection of identifiers beginning with default in a self-test.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 69277274-81a0-4daf-a296-338ec77f649f
Comment thread scripts/GenerateFableLibraryBridge.fsx Resolved
Comment thread scripts/GenerateFableLibraryBridge.fsx Resolved
Comment thread scripts/GenerateFableLibraryBridge.fsx Resolved
Comment thread scripts/GenerateFableLibraryBridge.fsx Resolved
Comment thread scripts/GenerateFableLibraryBridge.fsx Resolved
Comment thread scripts/GenerateFableLibraryBridge.fsx Resolved
Comment thread scripts/GenerateFableLibraryBridge.fsx Resolved
Detect default exports with the installed TypeScript compiler rather than
matching source text, so commented-out exports cannot create invalid bridge
imports. Batch runtime sources through one Node process and validate the
returned classifications with explicit errors and regression assertions.

Clarify the read-only plan and plural writer names, defer enumeration until
the parser batch requires a snapshot, and simplify record construction and
fixture paths. Name recursive deletion explicitly. Preserve the generated
bridge contents and existing command and runtime-resolution contracts.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 69277274-81a0-4daf-a296-338ec77f649f
@bitsforthought bitsforthought self-assigned this Oct 10, 2026
Use a conditional expression inside the raw interpolated bridge template
rather than concatenating templates. Keep the default-export literal in a
named binding because F# rejects triple-quoted literals inside interpolation
expressions. Preserve the generated contents and trailing newlines.

Open the relevant dependencies at internal module boundaries so record
construction uses inferred types rather than qualified field names.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 69277274-81a0-4daf-a296-338ec77f649f
@bitsforthought
bitsforthought merged commit f11eb09 into main Oct 10, 2026
2 checks passed
@bitsforthought
bitsforthought deleted the maintenance/fable-library-bridge branch October 10, 2026 21:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant