Repository navigation
refactor(objectql): move the compatibility-API bodies out of engine.ts into engine-compatibility-api.ts (#25522 cut 8) - #26229
Conversation
…s into engine-compatibility-api.ts (#25522 cut 8) registerObject, getConfigs, introspectDatasource, syncSchemas, syncObjectSchema and removePackage move unedited into a new module; each method keeps its name, signature, docblock and position and hands the body the members it reads through CompatibilityApiHost. The federated injected-column reader pin re-keys the two schema-sync rows to the module. Claude-Session: https://claude.ai/code/session_012CWiXJotHHDyeTL3Hea2Ad Co-authored-by: Claude <noreply@anthropic.com>
📓 Docs Drift CheckThis PR changes 1 package(s): 2 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:
What this run could not see
Coarse fallback — 19 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 978afcf71fe91d8c3bc021565eb2322338292423 && git checkout 978afcf71fe91d8c3bc021565eb2322338292423
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin f143cd8809aa2f26e2a2d9bccd4a9b17ad51c07a 9fce8d910e6ce5cd3eb90f3154af2733f8f3ccf7 && git checkout -B drift-repro f143cd8809aa2f26e2a2d9bccd4a9b17ad51c07a && git merge --no-ff 9fce8d910e6ce5cd3eb90f3154af2733f8f3ccf7
node scripts/docs-audit/affected-docs.mjs --json f143cd8809aa2f26e2a2d9bccd4a9b17ad51c07a
|
席位核对ACCEPT · The maintainer's standing authorisation for landing reviewed PRs, verbatim: 「按照 pm-dispatch 规则复核过的都授权」.
Generated by Claude Code |
Requested by Leehom · project thread
Part of #25522
Clause-②: no
Metadata-protocol: none
Ruling-ref: 6348891160
Cut 8 of the
packages/objectql/src/engine.tssplit (#24586 ruling A, recorded in6270097840). The claim is6419652034. Six bodies of the "Compatibility API" section move unedited into a new module,packages/objectql/src/engine-compatibility-api.ts:registerObject,getConfigs,introspectDatasource,syncSchemas,syncObjectSchemaandremovePackage. No behaviour changes. #25522 stays open for the later cuts.Branch
claude/project-thread-4vp88a(the card thread's harness-pinned branch), cut fromorigin/mainat7111e14ac, which contains cut 7's merge (dbfb52a66, #26160).Why this area (the fresh seam table)
Measured on
origin/main7111e14ac.engine.tsis 23,165 lines, 7,359 of them (31.8%) from the last 30 days (git blame -s --since=2026-09-26T15:20Z).scripts/pm/git-history.mjs count(window covered, exit 0): 126 commits in 30 days, 32 in 7.class ObjectQLholds 318 members, 255 methods and accessors plus the constructor. Sections are cut 1's contiguous member ranges, re-located by first member name, docblocks included. The measuring script, run on cut 7's based1ea2363f, reproduces cut 7's table and move screen byte for byte, so the readings compare. "inferred public" stays; "U" countsthis.FIELD.delete/insert/update(sites (AST, casts stripped); "private statics" stay.| range | section | first … last member | lines | 30-day lines | methods | inferred public | U | private statics |
| 4758-4983 | Instance state and constructor |
txStore…constructor| 226 | 50 | 0 (0 public) | - | 0 | - || 4984-5006 | Status and registry accessor |
getStatus…registry| 23 | 0 | 2 (2 public) | getStatus | 0 | - || 5007-5350 | Hook and function registry |
registerHook…triggerHooks| 344 | 6 | 16 (16 public) | registerHook, triggerHooks | 1 | - || 5351-5706 | Hook dispatch internals |
hasHooksFor…assertBulkPerRowHookBudget| 356 | 61 | 7 (0 public) | - | 0 | - || 5707-5867 | Action registry and activation |
registerAction…setActionActive| 161 | 19 | 10 (10 public) | - | 1 | - || 5868-6149 | Registered resolvers and write-gate probes |
_heldFileResolver…registerInsertRecomputeListener| 282 | 116 | 6 (6 public) | - | 0 | - || 6150-6903 | Readable-ids security and permission/formula resolution |
readableIdsSecurityReported…resolveDefaultPermissions| 754 | 546 | 15 (2 public) | - | 0 | - || 6904-7010 | Authz invalidation and middleware registration |
writeEpoch…hasObjectMiddleware| 107 | 18 | 4 (4 public) | - | 0 | - || 7011-7246 | Execution plumbing (middleware, session, provenance, users) |
executeWithMiddleware…buildUser| 236 | 37 | 7 (0 public) | - | 0 | - || 7247-7577 | Driver options and engine posture |
buildDriverOptions…resolveEnginePosture| 331 | 209 | 6 (0 public) | - | 0 | - || 7578-7787 | Organization probe and system-insert organization |
probeInstallOrganizations…transactionCoversDriverFor| 210 | 45 | 4 (0 public) | - | 0 | - || 7788-8153 | Field defaults |
resolveNowDefault…defaultFieldEntries| 366 | 4 | 6 (0 public) | - | 0 | - || 8154-8766 | Autonumber |
applyAutonumbers…seedAutonumber| 613 | 80 | 6 (0 public) | - | 1 | - || 8767-9431 | Package, app, plugin and driver registration |
registrationConversionWarned…registerDriver| 665 | 170 | 6 (3 public) | registerApp, registerDriver | 0 | - || 9432-9640 | Datasource registry |
supplyFileColumnsMovedResolver…listUnavailableDatasources| 209 | 1 | 8 (7 public) | - | 3 | - || 9641-9792 | Write guard and realtime publish |
assertWriteAllowed…publishBulkDataEvent| 152 | 18 | 4 (1 public) | - | 0 | - || 9793-9891 | Validation-message i18n |
setI18nService…objectDisplayLabel| 99 | 14 | 4 (1 public) | - | 0 | - || 9892-10984 | Referential integrity and master-detail resolution |
assertReferencesResolve…masterDeclaredFields| 1093 | 429 | 12 (0 public) | - | 0 | - || 10985-11100 | Dangling-reference and cascade inspection |
inspectDanglingReferences…inspectCascadeDelete| 116 | 48 | 2 (2 public) | - | 0 | - || 11101-11195 | Crypto and tenancy providers |
setCryptoProvider…setTenancyPostureProvider| 95 | 20 | 4 (4 public) | - | 1 | - || 11196-11615 | Secret and internal-field handling |
encryptSecretFields…resolveInternalField| 420 | 61 | 9 (3 public) | - | 0 | - || 11616-11684 | Schema lookup and filter judging |
getSchema…judgeFilter| 69 | 48 | 3 (2 public) | - | 0 | - || 11685-11950 | Datasource routing |
LIFECYCLE_DATASOURCE…setDatasourceMapping| 266 | 20 | 8 (3 public) | setDatasourceMapping | 0 | - || 11951-12118 | Lifecycle init and health |
init…resolvePrimaryDatasource| 168 | 16 | 3 (3 public) | init | 0 | - || 12119-12192 | Media and value-shape presence |
objectHasMediaField…valueShapeStrictFor| 74 | 13 | 4 (0 public) | - | 0 | mediaFieldPresence, coveredValueFieldPresence || 12193-12875 | Migration flags and attestations |
isFileReferencesMigrationVerified…wasDatastoreCreatedFromEmpty| 683 | 81 | 17 (8 public) | - | 0 | - || 12876-12898 | destroy |
destroy…destroy| 23 | 0 | 1 (1 public) | destroy | 0 | - || 12899-12917 | Expand/cascade limits (statics) |
MAX_EXPAND_DEPTH…MAX_BULK_PER_ROW_HOOK_ROWS| 19 | 0 | 0 (0 public) | - | 0 | MAX_EXPAND_DEPTH, MAX_CASCADE_DEPTH || 12918-13368 | Roll-up summaries |
autonumberCounters…recomputeSummaries| 451 | 0 | 7 (1 public) | - | 0 | - || 13369-13622 | Related-record expansion |
expandRelatedRecords…expandRelatedRecords| 254 | 10 | 1 (0 public) | - | 0 | - || 13623-14066 | File-reference hydration |
resolveFileReferences…readParentDerivedFiles| 444 | 310 | 5 (0 public) | - | 0 | - || 14067-14545 | Query lowering |
resolveWhereTokens…requireFindOnePredicate| 479 | 272 | 9 (0 public) | - | 0 | - || 14546-15102 | find / findOne |
find…staticReadonlyCreateStrip| 557 | 142 | 4 (2 public) | - | 0 | - || 15103-15760 | validate |
validate…validate| 658 | 447 | 1 (1 public) | - | 0 | - || 15761-17107 | insert / insertMany |
readUpdatePriorRow…insertMany| 1347 | 439 | 3 (2 public) | - | 1 | - || 17108-19041 | update |
update…update| 1934 | 275 | 1 (1 public) | - | 0 | - || 19042-20582 | Delete cascade and reference walking |
planCascadeAtomicity…organizationOwnedRowCounts| 1541 | 733 | 22 (1 public) | - | 0 | storedReferenceIncludes, remainderAfterMemberRemoval, referenceCheckContext, outlivesOrganization, keepsOrganizationReference, organizationCountContext || 20583-21152 | delete |
delete…delete| 570 | 47 | 1 (1 public) | - | 0 | - || 21153-21772 | count / aggregate |
count…aggregate| 620 | 236 | 3 (2 public) | - | 0 | - || 21773-22081 | execute and transactions |
execute…enforceTransactionOrigin| 309 | 74 | 8 (2 public) | - | 0 | - || 22082-22447 | Compatibility API |
registerObject…create| 366 | 41 | 16 (16 public) | - | 0 | - |The per-method move screen for every section, and the full pricing, are in the project file
pm-orders/server/25522-cut8-seam-table.md. A body stays if any of these holds: an inferred-return public method, a U site, a private-static read, anobjectql/src/engine.ts#NAMEpointer underpackages/spec/**ordocs/adr/**, athis.update(/this.insert(/this.delete(self-call, or a static. Bodies earlier cuts moved count as stubs, not as movable.Pricing (net
engine.tslines): a stub costs a comment, the host literal's open and close and the.call, plus two lines per field read (aread*closure and a getter) and one per method read (a late-bound closure); a body that reads no member costs two; the import adds about three.syncSchemas); no field writes, so one getter-only host; nopackages/specpointerbuildSession43,buildProvenance9,buildEvalUser6,buildUser8 (no member reads)count58,rejectCredentialAggregation38What stays in the section:
getDriverByName(ADR-0096 cites it asengine.ts#getDriverByName);create(a static factory);createContext, which passes the engine itself toScopedContext, a classengine.tsdefines, so its body would need a value import of the engine (a run-time cycle); andunregisterObject,getObject,getDriverForObject,dropObjectSchema,datasource,onandclose, whose stubs would cost as much as their bodies or more.The shape (#23050 shape B, as cuts 1 to 7 apply it)
fn.call(host, …), marked[#25522 cut 8]. All six are public with declared return types, so none is an inferred-return public member.CompatibilityApiHostis new:_registry,drivers,hooks,logger,getDriverForObject,removeActionsByPackage, each typed as the class member (ObjectQL['_registry']). Each moved function types itsthisas thePickof exactly the members its body reads, and each stub annotates its literal asThisParameterTypeof that function. There is no cast, and no member changes visibility.syncSchemasandsyncObjectSchemacall the publicgetDriverForObject, which a caller may override).registerObjectkeeps its default parameter (packageId: string = '__runtime__') on both the method and the function; the stub passes the value it received.ObjectQLas a TYPE only and nothing re-exports it. Its value imports areStorageNameMapping(@objectstack/spec/system) andisFederatedObject(./federated-object.js), the same bindingsengine.tsuses; both still have readers inengine.ts, so its import list is unchanged apart from the new module import.Net lines (the seat's rule)
engine.tsgoes from 23,165 to 23,095 lines, net -70 (46 added, 116 removed). The module is 225 lines: the header and host interface (about 66), six one-line docblocks, and the 116 moved body lines with their signatures. With the two re-keyed rows of the reader pin, the diff is 391 changed lines over 3 files (+273 / -118), far under the 3,000-line human-merge threshold.The published
.d.tsdoes not change (ruling6348891160)Base:
@objectstack/objectqlbuilt withengine.tsrestored from7111e14acand the new module removed (tree only; restored withgit checkout HEAD --, blob hashes compared,git statusclean). Head: built at9fce8d910. The headdist/index.mjscarriessyncSchemas.call(hostonce and the base build has it zero times, so each leg built the source it names. All six declaration files are byte-identical, and equal to the hashes cut 7 recorded:core.d.ts1d20303a455a909e4b55fd0802fb0b0bcb59ec51784daf27d5ef4c0659410953index.d.ts0454d5e70b156d8effbf27b8915587c7cbee241dcd7d698013c0a4c369a02aa5util-CVzOGxAn.d.ts85ef1cbec2b016d5f7afabaa21689c86c6dffc573076fdfdeb8ea0f1a1b1ad53core.d.mtsef178bf0725eccc2f358f082ce13dc5122a6d5a53c19ef630017256f67de03b4index.d.mtsccf900240aa137abe72f82b8abfc872d42c5645467400134c580285f2a3b3090util-CVzOGxAn.d.mts85ef1cbec2b016d5f7afabaa21689c86c6dffc573076fdfdeb8ea0f1a1b1ad53Positive control: every moved member is public, so the control edits a moved member's published signature instead of its visibility: widening the stub
getConfigs()'s declared return to aRecordofServiceObject | undefined(anchor landed once, 0 / 1 after) and rebuilding changed all six hashes and the chunk name (util-CPRlCSiG.d.ts00b673476de74bfc…,index.d.ts4097f6aa775e78e4…), and the widened type appears in the util chunk. Restored withgit checkout HEAD --, blob hash compared, rebuilt, and all six files compared equal to the head build again. Export lists are the same for ESM and CJS at both ends:.182 names (sorted sha256881616cc17…) and./core54 (393e806906…). No moved name, and notCompatibilityApiHost, is exported.Proof of move-only
A TypeScript-AST leaf-token compare (recursive
getChildren, JSDoc skipped) of baseengine.ts(7111e14ac) against the head module:this, default value included), return type, type parameters and body tokens are SAME,asyncmatches, and every body line equals the base line less two leading spaces, comments included:registerObject72 tokens / 9 lines,getConfigs57 / 8,introspectDatasource58 / 8,syncSchemas312 / 63,syncObjectSchema117 / 17,removePackage79 / 11.=== 'function'to!== 'function'on thesyncSchemaprobe in the movedsyncSchemasreports DIFFER on its body tokens; editing only one comment in the movedsyncObjectSchemafails the line rule. Both exit 1, and the module was restored fromHEADand its blob hash compared after each.Readers of the moved lines
packages/objectql/src/federated-injected-column-readers.test.tskeys every federated-predicate use in@objectstack/objectql's source asFILE#FUNCTION :: SEAM. The two schema-sync rows move fromengine.ts#syncSchemas/engine.ts#syncObjectSchematoengine-compatibility-api.ts#syncSchemas/#syncObjectSchema, with the same disposition and reason. Control: with the base copy of the test restored over this head, it goes red naming exactly those two new keys (1 failed / 4 passed), so the pin does read the moved code; restored fromHEAD, blob hash compared.scripts/adr-anchors/entry describes a moved body: the engine entry's one paragraph is the transaction seam, and its ids stay cited inengine.ts. So no entry is added.check-adr-anchorsat base7111e14ac: 89 anchored files, 1,881 decision-letter citations; at head: 89 anchored files, 1,881 decision-letter citations (resolving citations 59,157 → 59,159, the module header's two ADR ids). The moved bodies cite no decision letter.objectql/src/engine.ts#NAMEpointer underpackages/spec/**ordocs/adr/**names the six. Prose that names a method withObjectQL.orengine.(ADR-0015 onObjectQL.syncObjectSchema,federated-object.ts,plugin.ts,error-code-ledger.zod.tscomments, the durability checker'ssyncObjectSchemavocabulary) still resolves, because every method stays on the class.durability-read-invention.baseline.jsonnamesreferenceExistsonly, andquery-options-erasurereports its key set unchanged with the file counts held. The tests that assert the moved bodies' runtime messages (external-write-gate.test.ts,schema-sync-durability-log-level.test.ts,sync-schemas-federated-object.test.ts) assert behaviour, not source text, and pass.Acceptance notes
createContext(8 body lines) was priced at about -6 by cut 7; it handsthis(the engine) toScopedContext, whichengine.tsdefines, so the body cannot move without a value import of the engine. Left in the class.removePackagemutates the hook map through the getter (this.hooks.set(…)), the same object, so the write lands where it did; it is not a field assignment, and no setter is needed.pr_create: 36 PRs are open; none touchespackages/objectql/src/**. build(tsconfig): split the shared base out of the root tsconfig (#26092 part 1) #26203 editspackages/objectql/tsconfig*.json, chore(packages): publishing metadata for the 73 published packages — per-format types, sideEffects, publishConfig, and 18 missing READMEs #26198 and chore: version packages #25640 editpackages/objectql/package.json(and the changelog), outside this PR's files.origin/mainmoved 15 commits after the base, none onpackages/objectql/**; the onlyscripts/adr-anchors/**change is the driver-sql pair from refactor(driver-sql): move applyIndexDriftOp and restoreBareIndexAfterFailedTighten into sql-driver-schema-sync.ts (#25521 cut 8) #26169.dispatch-gatesprinted no stale-tree warning, somainwas not merged in.buildSession,buildProvenance,buildEvalUser,buildUser, none reading a member), then Autonumber (about -75, warmer). Migration flags still needs a setter ruling.Verification
At
9fce8d910:pnpm --filter @objectstack/objectql typecheck(tsc --noEmit+check:test-typecheck, 39 files / 233 errors / 64 pinned signatures held): VERDICT command-exit 0.pnpm exec eslint --no-inline-config packages/objectql: exit 0.pnpm --filter @objectstack/objectql exec vitest run --project local --maxWorkers=2: 471 files, 8,774 tests passed (VERDICT command-exit 0). A focused verbose run offederated-injected-column-readers.test.ts,sync-schemas-federated-object.test.ts,schema-sync-durability-log-level.test.tsandexternal-write-gate.test.ts: 4 files, 28 tests passed..d.tsfiles are byte-identical, so no dependant can see a difference. CI'sTypeScript Type Checkcovers them.9fce8d910:dispatch-gates --commandsderived 62 families on the real diff. Every one was run, each exit code captured before any pipe, then reconciled with--ran: 62 accounted for, 61 run, 1 NOT MEASURED. NOT MEASURED (CI runs it):check:dual-build-cjs-loads, exit 3, PREREQUISITE NOT MET (it needs every package'sdist/; the export lists above answer it for objectql).check:lean-entry-closurefirst exited 3 for want of objectql'sdist/and was re-run green after the head build (15 packages, the admitted set held). Named readings:check-system-context-censusOK (151 read sites, 144 of 144 symbols cited),check:logger-receiver-detachOK (3,737 files, 0 detaches),check:durability-log-levelexit 0,check:query-options-erasureexit 0 (key set verified, no files added),check-engine-split-ratio --days 9097.6%.9fce8d910:check-adr-anchorsat base and head (above),check-adr-symbol-anchors(2,660 anchors resolve),check-tenant-audit-census(243 write call sites),check-nul-bytes,check-platform-checklist --changed-from origin/main(13 anchors judged, 0 lost) andcheck-commit-card-trailers --range origin/main..HEAD.test:repowas not run locally; CI'sTest Coreruns it.skip-changeset: move-only. The published.d.tsfiles and export lists are byte-identical,liveness/and every other published path are untouched, and the module's runtime is the same code under a different file name.Generated by Claude Code