Repository navigation
fix(core): one declaration serves both module formats, so exports give types per condition - #26279
Conversation
…e types per condition Core's declaration pass runs once, for CJS; the ESM .d.ts files are one-line re-exports of the .d.cts ones, so ObjectKernel has one identity whichever resolution mode reaches it. exports now hands each condition its own types, and the two core rows leave TYPED_EXEMPTIONS in check-dual-build-cjs-loads (shrink-only: the entries are now correct). Claude-Session: https://claude.ai/code/session_01VPkxx6ackwXchvtVNidtum Co-authored-by: Claude <noreply@anthropic.com>
…from the .d.cts Putting the declarations in the .d.cts made core's own imports of @objectstack/spec resolve through spec's require condition, and spec's twin declarations then failed driver-memory's build (TS2345). With the ESM .d.ts as the one declaration, everything core's types import resolves as before. Claude-Session: https://claude.ai/code/session_01VPkxx6ackwXchvtVNidtum Co-authored-by: Claude <noreply@anthropic.com>
…d on Claude-Session: https://claude.ai/code/session_01VPkxx6ackwXchvtVNidtum Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VPkxx6ackwXchvtVNidtum Co-authored-by: Claude <noreply@anthropic.com>
📓 Docs Drift Check2 anchor(s) derived from 1 changed package(s); no hand-written page names any of them. What this run could not see
Coarse fallback — 29 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): Which tree this was computed onThis run read A worktree cut from an older # while this PR is open — GitHub drops the merge commit once it closes
git fetch origin b1c3eff61833c9b01c6c0854622cb00c215def33 && git checkout b1c3eff61833c9b01c6c0854622cb00c215def33
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 4f7e0414a8d44b139cf5c9bc7e37f207f1db1327 01ec8f2e9e6fd8fcd658552ecec8ede97dae1e8d && git checkout -B drift-repro 4f7e0414a8d44b139cf5c9bc7e37f207f1db1327 && git merge --no-ff 01ec8f2e9e6fd8fcd658552ecec8ede97dae1e8d
node scripts/docs-audit/affected-docs.mjs --json 4f7e0414a8d44b139cf5c9bc7e37f207f1db1327 |
席位核对 · ACCEPT · devx seat 2 · 2026-10-26T18:37ZSeat
Generated by Claude Code |
Requested by Steve · project thread
Fixes #26205
Clause-②: no
Metadata-protocol: none
@objectstack/corewas the one published package still handing arequireconsumer its ESM-kind declaration (attwFalseESMon.and./logger). Serving the.d.ctsper condition, as #26198 did for 38 other packages, broke consumers, becausedist/index.d.tsanddist/index.d.ctswere two separate declarations of the same classes andObjectKernel'sprivate pluginsmakes the two copies incompatible types.What changed
packages/core/tsup.config.ts: the declaration pass runs once, for ESM only (adts: { only: true }half). The JS half (ESM + CJS, unchanged options) writesdist/index.d.ctsanddist/logger.d.ctsin itsonSuccessas one line each,export * from './index.js';/'./logger.js'. The declaration half never emits a.d.cts, so the two halves tsup runs concurrently never write the same file, andcleanstays on the JS half only (tsup's clean keeps declaration files).packages/core/package.json: both subpaths become{ import: { types, default }, require: { types, default } }, the shape chore(packages): publishing metadata for the 73 published packages — per-format types, sideEffects, publishConfig, and 18 missing READMEs #26198 used. No subpath added or removed, no JavaScript target moved; the top-levelmain/typesare unchanged.scripts/check-dual-build-cjs-loads.mjs: the two@objectstack/corerows leaveTYPED_EXEMPTIONS. The table is shrink-only and the scan reports a row whose entry now resolves a CommonJS declaration as stale, so they go in the same PR; the header paragraph that described core's block now says where the cure lives. This file was added to the claim's file surface by the seat before the edit..changeset/26205-core-one-declaration-per-condition.md:@objectstack/corepatch.Why this direction and not the reverse
Tried first the other way round: declarations in the
.d.cts,index.d.tsre-exporting./index.cjs(ESM may import CJS in every TypeScript mode). That made core's own imports of@objectstack/specresolve through spec'srequirecondition, and spec's own twin declarations then failed@objectstack/driver-memory's build:TS2345atsrc/memory-driver.ts:1469,ComposedReadableIdsnot assignable to itself. Keeping the declarations in the ESM.d.tsmeans everything core's types import resolves exactly as it did when both conditions read the.d.ts.The cost of this direction is TS1479 inside core's
.d.ctsfor a CommonJS consumer onmodule: node16(or on TypeScript 5.6 undernodenext). A consumer CJS file plus ESM file importing core in both resolution modes and assigningObjectKernelacross them, compiled against this branch's build and againstorigin/main's:origin/main,skipLibCheck: trueskipLibCheck: trueskipLibCheck: false.d.cts.d.cts.d.ctsSo the diagnostic that
origin/mainraises at the consumer's import, where no option silences it, moves into the package, whereskipLibCheckdoes. The cross-modeObjectKernelassignments type-check in every cell. (The 5.6 runs also print errors fromai/@ai-sdkand@objectstack/specdeclarations withskipLibCheck: false; those are unchanged by this PR and not counted above.)Acceptance
origin/main(f2e70836): with only the export map split and the declaration build unchanged,pnpm --filter @objectstack/plugin-dev buildexits 1 withsrc/dev-plugin.ts(523,32): error TS2345: Argument of type 'ObjectQLPlugin' is not assignable to parameter of type 'Plugin'.; unsplit, exit 0.@arethetypeswrong/cli0.18.5) on thepnpm packtarball of core: before 3 problems (FalseESM× 2,NoResolutionon./loggerundernode10), after 1 (NoResolutionon./loggerundernode10). FalseESM: 2 → 0. The remainingnode10row is the known no-exports-support class, left out of scope as in chore(packages): publishing metadata for the 73 published packages — per-format types, sideEffects, publishConfig, and 18 missing READMEs #26198.pnpm --filter @objectstack/plugin-dev build: exit 0 at01ec8f2e(inside the force build below).packages/core/distlists the same 12 file names before and after (plus its two.build-input-hash*stamps), and the packed tarball the same 18 paths,diffclean. What changed is content only:index.d.cts579,364 → 28 bytes andlogger.d.cts3,963 → 29 bytes (now re-exports);index.d.tsandlogger.d.tsare the same declarations as before.Verification
All at head
01ec8f2e, which mergesorigin/mainat0453fabe(that brought in #26203's tsconfig base change to core and plugin-dev):turbo run build --force --filter='./packages/**': 75 of 75 tasks successful, including@objectstack/verify,@objectstack/plugin-devand@objectstack/driver-memory, the three builds that met this hazard before.pnpm --filter @objectstack/core typecheckexit 0;pnpm --filter @objectstack/core test: 121 files, 2,778 tests passed.dispatch-gates --commandsderived 93 families for this diff; every one exits 0, and--ranreconciles at 93 derived, 93 run, 0 NOT-MEASURED (exit codes recorded).check-plugin-teardown-shape.mjs --self-testfirst refused on the shallow clone (exit 3) and passed aftergit fetch --unshallow. Named for this diff:check:dual-build-cjs-loads(self-test 93 cases; scan: 112 require entry points across 69 packages, 112 require conditions resolve a CommonJS-flavouredtypesthat exists),check:dts-closure,check:lean-entry-closure,check:published-files,check-dts-emitted.mjs --self-test,check-empty-changeset.mjs,check-adr-0087-registration.mjs.pnpm lintfirst) and the type-check lanes are CI's.Acceptance notes
packages/plugins/plugin-dev/**,ui/**or any governed surface is touched.Generated by Claude Code