Skip to content

build(sdk): replace tsdown bundler with tsgo file-by-file build#1496

Draft
toiroakr wants to merge 2 commits into
mainfrom
chore/build-with-tsgo
Draft

build(sdk): replace tsdown bundler with tsgo file-by-file build#1496
toiroakr wants to merge 2 commits into
mainfrom
chore/build-with-tsgo

Conversation

@toiroakr

@toiroakr toiroakr commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

Summary

Replace the tsdown bundler build of @tailor-platform/sdk with a tsgo (file-by-file ESM) build plus a Node postbuild script. Clean build drops from ~22s to ~6s.

This is exploratory. It changes how the package is published (no longer bundled), so the trade-offs below need review before merging.

What changed

  • Build: tsgo -p tsconfig.build.json emits per-file ESM; scripts/build-tsgo.mjs orchestrates tsgo + postbuild.
  • postbuild (scripts/postbuild-tsgo.mjs) replicates what tsdown's config/plugins did: rename .js->.mjs / .d.ts->.d.mts, rewrite all relative module specifiers (incl. bare ./.. and .yml->.yml.mjs), emit YAML files as runtime .mjs modules, add CLI shebangs + exec bit, inject the runtime-globals triple-slash banner on configure/index.d.mts only, copy the ERD viewer assets, and vendor the private tailor-proto package into dist/_proto.
  • Types: annotate initOperatorClient's return type so the per-file .d.mts emit keeps OperatorClient instead of collapsing to Client<any>.
  • Metrics: remove the Sonda bundle-size analysis and the redundant measure:bundle script + its sdk-metrics "Bundle Size" CI job. Deployed function-bundle sizes are already guarded by example's bundled_execution.test.ts ("bundled JS files should not be excessively large"), which asserts the real deploy artifacts stay small and free of unwanted deps (e.g. zod).
  • Deps: remove tsdown and sonda. Delete tsdown.config.ts, the old root Sonda measure script, and the stale .sonda ignore. Add explicit knip entries (tsdown previously drove entry detection).

Verification

  • pnpm check (build, generate, lint, typecheck:go, knip, jsdoc, zod-isolation, import-cycles) exits 0.
  • pnpm test:unit: 2865 tests pass.
  • publint --strict clean; CLI smoke (node dist/cli/index.mjs --help) works.

Trade-offs / review points

  1. Bundling dropped: dependencies are no longer inlined; they resolve from the consumer's node_modules at runtime. The published package now has a real dependency tree instead of a vendored bundle. This is the core methodology change to evaluate.
  2. Private proto vendoring: tailor-proto (private, unpublished) is copied into dist/_proto and its specifiers rewritten, since it can't resolve from npm. Review whether vendoring is the desired distribution strategy.
  3. tsgo exit code ignored: build-tsgo.mjs tolerates tsgo's non-zero exit (non-fatal TS4023 on politty re-exports, TS5096 on allowImportingTsExtensions) and gates on emitted-file presence. Type correctness is still enforced by pnpm typecheck/CI; a genuine emit failure that still leaves the entry files could slip past the build gate.

Notes

Supersedes the interim "make Sonda opt-in on tsdown" approach by removing tsdown entirely.

@changeset-bot

changeset-bot Bot commented Jun 17, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: fcc0c6b

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 2 packages
Name Type
@tailor-platform/sdk Patch
@tailor-platform/create-sdk Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@toiroakr
toiroakr force-pushed the chore/build-with-tsgo branch from be469a0 to e2a74a3 Compare June 18, 2026 00:11
Build with tsgo (file-by-file ESM emit) plus a postbuild script instead
of the tsdown bundler. The postbuild renames to .mjs/.d.mts, rewrites
module specifiers, emits YAML files as runtime modules, adds CLI shebangs
(and the exec bit), injects the runtime-globals banner on
configure/index.d.mts only, copies ERD viewer assets, and vendors the
private @tailor-platform/tailor-proto package into dist/_proto so the
unbundled output stays self-contained.

Annotate initOperatorClient's return type so the declaration emit keeps
OperatorClient instead of collapsing to Client<any> under file-by-file
emit.

Remove tsdown and sonda, and drop the redundant measure:bundle metric
with its sdk-metrics Bundle Size CI job: deployed function-bundle sizes
are already guarded by example's bundled_execution size test. Add
explicit knip entries that tsdown's plugins previously provided.

Clean build ~6s (was ~22s).
@toiroakr
toiroakr force-pushed the chore/build-with-tsgo branch from e2a74a3 to 62901f6 Compare June 18, 2026 01:22
@pkg-pr-new

pkg-pr-new Bot commented Jun 18, 2026

Copy link
Copy Markdown

Open in StackBlitz

pnpm add https://pkg.pr.new/@tailor-platform/create-sdk@fcc0c6b
pnpm add https://pkg.pr.new/@tailor-platform/sdk@fcc0c6b

commit: fcc0c6b

The postbuild specifier rewrite matched raw text, so import-like text
inside string literals and comments was rewritten too — corrupting the
generated migration-script template (`./db` -> `./db.mjs`). Locate
specifiers via the oxc AST (static import/export, dynamic import, and
type-level `import()`), leaving template/comment text untouched.

Also harden the build:
- derive the post-emit existence check from every package.json
  exports/bin entry instead of four hand-listed ones, so a broken emit
  of any published entry is caught despite the ignored tsgo exit code
- align the tsconfig.build.json `@tailor-proto` path alias with the
  canonical tsconfig.json mapping (was a doubled `tailor/v1` segment)
- anchor the sourceMappingURL rewrite per-line so trailing content
  cannot leave a stale `.js.map` reference
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