Repository navigation
Commit 7097859
test: load package barrels at module top so the collect phase pays for them (#21480)
Fixes #21457
Clause-②: no
## What this changes
Five test files, test-only. Every case that loaded a package barrel with
a dynamic import inside its body now gets that barrel from a module-top
load, so the load is charged to vitest's collect phase instead of the
case's 5000ms window (AGENTS.md: 「Clocked windows measure behaviour,
never loading」). The shape and the reasoning are the core precedent's,
`packages/core/src/service-resolution-discriminator.contract.test.ts`;
no helper was added. No timeout, retry, skip, `vitest.config.ts`, source
or gate change.
| site (line numbers at `7e7e64b1`) | change |
|---|---|
| `packages/objectql/src/system-write-organization.test.ts:506` |
`import * as barrel from './index.js'` at module top; the case is now
synchronous and still asserts, by identity, that both names come from
the barrel |
| `packages/core/src/security/platform-admin.test.ts:279` | `import * as
securityEntry from './index.js'` at module top; the case still probes
presence and absence on the security entry |
| `packages/lint/src/validate-predicate-path-refs.test.ts:376` | `import
* as barrel from './index.js'` at module top |
|
`packages/plugins/plugin-sharing/src/translations/serving-seam.test.ts:86`
and `:100` | one static import plus one module-top re-evaluation under a
mock, see below |
| `packages/lint/src/lazy-deps.test.ts:190` | the triage's named
exception: keeps its in-case import, and one comment line now says why |
### The one site where the hoist was not mechanical:
`serving-seam.test.ts`
Hoisting changed what this file observes, so it was not a plain move.
The `:86` case evaluated the barrel against a MOVED source: a
`beforeEach` ran `vi.resetModules()`, then the case ran
`vi.doMock('./en.objects.generated.js', ...)` and imported the barrel. A
static import cannot be mocked per case. The resolution keeps each
assertion's meaning:
- `:100` ("substitutes nothing while the source has not moved") reads a
static `import { SharingTranslations } from './index.js'`, which is the
barrel as committed.
- `:86` ("SERVES the current source when the source moves under the
recorded leaf") reads `servedAfterSourceMoved`. That value is produced
at module top by the same four steps the `beforeEach` and the case used
to perform: `vi.resetModules()`, `vi.doMock(...)`, `await
import('./index.js')`, `vi.doUnmock(...)`. A top-level await in a test
module runs during collection; the repo already uses that shape in
`packages/cli/test/score-lint-crash.test.ts` and
`packages/mcp/src/__tests__/plugin-execution-context.test.ts`.
- The `beforeEach` is removed. It existed only to isolate the two
in-case imports, and no case imports anything now.
So one `await import('./index.js')` remains in that file, at column 0 at
module top and not inside a case. The triage pin is about loads inside a
case.
**Ablation** (one-time, on the committed tree,
`scripts/ablation-replace.mjs` in WRAP mode with its own restore proof):
deleting the module-top `vi.resetModules();` turns exactly the `:86`
case red, `AssertionError: expected 'Token' to be 'Share token'`, with 1
failed and 4 passed. Without the reset, the import returns the copy the
static import cached. The restore was proven: blob `9d8e14d9fe22` equals
HEAD's, and `git diff HEAD` is empty.
## Measured
Every reading was taken on this container's shared box. Other agents'
work ran alongside, and the verify lock excluded only other locked runs,
so the absolute numbers are shared-box seconds. The signal is the
per-case drop.
**Per-case duration, run alone** (one file plus `-t`, vitest JSON
reporter; the number in brackets is the same case in a whole-file run):
| case | before (`7e7e64b1`) | after (`8e8b3bb6`) |
|---|---|---|
| objectql barrel case | 1669 ms (1556) | 2.4 ms (0.1) |
| core security-entry case | 1695 ms (1837) | 2.1 ms (0.1) |
| lint predicate barrel case | 57 ms (68) | 5.2 ms (0.4) |
| sharing `:86` | 107 ms (134) | 1.5 ms (0.3) |
| sharing `:100` | 114 ms (57) | 1.4 ms (0.2) |
| lint lazy-deps in-process case (the exception, unchanged) | 8372 ms |
8296 ms |
**In the package's whole suite.** CI's Test Core runs each of these four
packages whole on its shard; only `@objectstack/cli` takes file-level
slices. So the whole-suite run is their shard. The readings are on
`2d2204d764`; for the before leg, the edited file(s) were restored
tree-only from `7e7e64b1`.
| case | before | after | suite, both legs |
|---|---|---|---|
| objectql (`--project local`) | 614 ms | 0.1 ms | 366 files, 7383 tests
passed |
| core (both projects) | 313 ms | 0.3 ms | 79 files, 2204 tests passed |
| lint predicate | 34 ms | 0.2 ms | 119 files, 5619 tests passed |
| lint lazy-deps (the exception) | 5476 ms | 5544 ms | same run |
| sharing `:86` / `:100` | 99 / 56 ms | 0.2 / 0.2 ms | 38 files, 954
tests passed |
The load did not disappear. It moved into the collect phase, which
vitest 4's summary calls "import". For example, objectql's single-case
run went from import 7.84s and tests 1.67s to import 10.02s and tests
4ms.
Nobody had measured the other five sites before this. At these readings,
only the objectql and core cases carried a load large enough to matter
(1.5 to 1.8 s alone). The lazy-deps case is not under the default window
at all: it already runs under `COLD_LOAD_TIMEOUT_MS = 30_000`, and it
measures 5.5 to 8.4 s.
## Verification
- `pnpm test` per package on `2d2204d764`: core 76 files / 2156 tests,
lint 119 / 5619, plugin-sharing 38 / 954, all passed. objectql `vitest
run --project local`, which is its `test` script: 366 / 7383 passed.
- `pnpm typecheck` for all four packages: exit 0, and
`check:test-typecheck` OK in each. All five files are in their package's
`tsconfig.test.json` program (`tsc --listFiles`), and none of them
carries an error.
- Gates: `dispatch-gates --commands` derived 63 commands from this tree,
the same list as the PM's derivation. All 63 were run and all exit 0.
`check:i18n` and `check:dual-build-cjs-loads` first answered
PREREQUISITE NOT MET (exit 3); after a turbo cache replay of their build
closure, both re-ran green. The `--ran` reconciliation: 63 derived, 63
run, 0 NOT-MEASURED, 0 UNRUN.
- ESLint, narrowed with the narrowing proven: `eslint --no-inline-config
--format json` over the five files on `2d2204d764` linted 5 files (none
reported as ignored), with 0 errors and 0 warnings. `eslint.config.mjs`
enables no type-aware linting (no `parserOptions.project`, no
`projectService`), so this diff cannot change a verdict on any file it
does not touch. The repo-wide `pnpm lint` is CI's.
- Pin grep, `git grep -n "await import('\./index" --
'packages/**/*.test.ts' ':!packages/spec'`, gives 3 hits: the core
precedent's own comment, `lazy-deps.test.ts:191` (the named exception)
and `serving-seam.test.ts:84` (at module top). The spec side, as the
control, gives 45 hits.
- `check:test-source-alias` does not flag this shape. Per the triage
ruling, that is recorded here and the gate is not widened. It is green
on this tree.
## Acceptance notes
- **Same family, other spellings.** These sites are outside this card's
ruled pattern and outside its claimed files. Each is an in-case barrel
load, measured alone on `2d2204d764`:
-
`packages/services/service-analytics/src/__tests__/dataset-compare-kind-refusal.test.ts:220`,
`../index.js`: 568 ms;
- `packages/plugins/plugin-email/src/send-template.test.ts:336` and
`:342`, `./transports/index.js`: 37 ms and 1 ms;
-
`packages/metadata/src/loaders/overlay-index-single-producer.test.ts:150`,
`../migrations/index.js`: 24 ms.
None is near the window. They are noted here and not filed.
- **Base:** the branch was cut at `7e7e64b1` and merged with
`origin/main` at `49524f6906`.
---
_Generated by [Claude
Code](https://claude.ai/code/session_01DDZNkDVwPQnevTFcYE47H3)_
Co-authored-by: Claude <noreply@anthropic.com>1 parent cc07862 commit 7097859
5 files changed
Lines changed: 64 additions & 19 deletions
File tree
- packages
- core/src/security
- lint/src
- objectql/src
- plugins/plugin-sharing/src/translations
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
23 | 23 | | |
24 | 24 | | |
25 | 25 | | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
26 | 37 | | |
27 | 38 | | |
28 | 39 | | |
| |||
275 | 286 | | |
276 | 287 | | |
277 | 288 | | |
278 | | - | |
279 | | - | |
| 289 | + | |
| 290 | + | |
280 | 291 | | |
281 | 292 | | |
282 | 293 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
180 | 180 | | |
181 | 181 | | |
182 | 182 | | |
| 183 | + | |
183 | 184 | | |
184 | 185 | | |
185 | 186 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
26 | 26 | | |
27 | 27 | | |
28 | 28 | | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
29 | 40 | | |
30 | 41 | | |
31 | 42 | | |
| |||
372 | 383 | | |
373 | 384 | | |
374 | 385 | | |
375 | | - | |
376 | | - | |
| 386 | + | |
377 | 387 | | |
378 | 388 | | |
379 | 389 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
44 | 44 | | |
45 | 45 | | |
46 | 46 | | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
47 | 58 | | |
48 | 59 | | |
49 | 60 | | |
| |||
499 | 510 | | |
500 | 511 | | |
501 | 512 | | |
502 | | - | |
| 513 | + | |
503 | 514 | | |
504 | 515 | | |
505 | 516 | | |
506 | | - | |
| 517 | + | |
507 | 518 | | |
508 | 519 | | |
509 | 520 | | |
| |||
Lines changed: 25 additions & 13 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
35 | 35 | | |
36 | 36 | | |
37 | 37 | | |
38 | | - | |
| 38 | + | |
39 | 39 | | |
40 | 40 | | |
41 | 41 | | |
42 | 42 | | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
43 | 52 | | |
44 | 53 | | |
45 | 54 | | |
| |||
64 | 73 | | |
65 | 74 | | |
66 | 75 | | |
67 | | - | |
68 | | - | |
69 | | - | |
70 | | - | |
71 | | - | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
72 | 86 | | |
| 87 | + | |
73 | 88 | | |
74 | 89 | | |
75 | 90 | | |
| |||
81 | 96 | | |
82 | 97 | | |
83 | 98 | | |
84 | | - | |
85 | | - | |
86 | | - | |
87 | | - | |
| 99 | + | |
| 100 | + | |
88 | 101 | | |
89 | 102 | | |
90 | 103 | | |
91 | | - | |
| 104 | + | |
92 | 105 | | |
93 | 106 | | |
94 | 107 | | |
95 | 108 | | |
96 | 109 | | |
97 | 110 | | |
98 | 111 | | |
99 | | - | |
100 | | - | |
| 112 | + | |
101 | 113 | | |
102 | 114 | | |
103 | 115 | | |
0 commit comments