@mandujs/core 0.53.3 → 0.54.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +654 -654
- package/package.json +2 -2
- package/src/a11y/__tests__/run-audit.test.ts +333 -333
- package/src/a11y/fix-hints.ts +76 -76
- package/src/a11y/index.ts +18 -18
- package/src/a11y/run-audit.ts +394 -394
- package/src/a11y/types.ts +125 -125
- package/src/auth/__tests__/login.test.ts +1 -1
- package/src/auth/__tests__/password.test.ts +122 -122
- package/src/auth/__tests__/tokens.test.ts +274 -274
- package/src/auth/__tests__/verification.test.ts +274 -274
- package/src/auth/index.ts +76 -76
- package/src/auth/login.ts +225 -225
- package/src/auth/password.ts +120 -120
- package/src/auth/reset.ts +243 -243
- package/src/auth/tokens.ts +612 -612
- package/src/auth/verification.ts +253 -253
- package/src/brain/__tests__/redactor.test.ts +94 -94
- package/src/brain/adapters/__tests__/_helpers.ts +83 -83
- package/src/brain/adapters/__tests__/anthropic-oauth.test.ts +196 -196
- package/src/brain/adapters/__tests__/chatgpt-auth.test.ts +193 -193
- package/src/brain/adapters/__tests__/openai-oauth.test.ts +209 -209
- package/src/brain/adapters/__tests__/resolver.test.ts +143 -143
- package/src/brain/adapters/anthropic-oauth.ts +1 -1
- package/src/brain/adapters/chatgpt-auth.ts +300 -300
- package/src/brain/adapters/index.ts +319 -319
- package/src/brain/adapters/oauth-flow.ts +439 -439
- package/src/brain/consent.ts +240 -240
- package/src/brain/credentials.ts +396 -396
- package/src/bundler/__tests__/build-runner.ts +113 -113
- package/src/bundler/__tests__/dev-reliability.test.ts +619 -619
- package/src/bundler/__tests__/extended-watch.test.ts +711 -711
- package/src/bundler/__tests__/fast-refresh.test.ts +10 -10
- package/src/bundler/__tests__/hdr.test.ts +353 -353
- package/src/bundler/__tests__/hmr-client.test.ts +532 -532
- package/src/bundler/__tests__/manifest-schema.test.ts +266 -266
- package/src/bundler/__tests__/prod-smoke.test.ts +138 -138
- package/src/bundler/__tests__/reverse-import-graph.test.ts +519 -519
- package/src/bundler/__tests__/slot-dispatch.test.ts +573 -573
- package/src/bundler/__tests__/url-cap-and-slot-regex.test.ts +286 -286
- package/src/bundler/__tests__/vendor-cache.test.ts +455 -455
- package/src/bundler/budget.ts +404 -404
- package/src/bundler/build.test.ts +179 -179
- package/src/bundler/build.ts +55 -55
- package/src/bundler/dev.ts +42 -42
- package/src/bundler/manifest-schema.ts +301 -301
- package/src/bundler/plugins/__tests__/block-generated-imports.test.ts +263 -263
- package/src/bundler/plugins/__tests__/react-compiler-config.test.ts +83 -83
- package/src/bundler/plugins/__tests__/react-compiler-lint.test.ts +110 -110
- package/src/bundler/plugins/block-generated-imports.ts +155 -155
- package/src/bundler/plugins/index.ts +83 -83
- package/src/bundler/plugins/react-compiler-config.ts +108 -108
- package/src/bundler/plugins/react-compiler-lint.ts +253 -253
- package/src/bundler/plugins/react-compiler.ts +162 -162
- package/src/bundler/reverse-import-graph.ts +339 -339
- package/src/bundler/safe-build.test.ts +201 -201
- package/src/bundler/safe-build.ts +103 -103
- package/src/bundler/scenario-matrix.ts +229 -229
- package/src/bundler/types.ts +10 -10
- package/src/bundler/vendor-cache-types.ts +130 -130
- package/src/bundler/vendor-cache.ts +526 -526
- package/src/change/snapshot.ts +18 -18
- package/src/client/Form.tsx +105 -105
- package/src/client/Link.tsx +9 -9
- package/src/client/__tests__/use-sse.test.ts +153 -153
- package/src/client/globals.ts +1 -1
- package/src/client/hooks.ts +362 -362
- package/src/client/hydrate.ts +340 -340
- package/src/client/prefetch-helper.ts +55 -55
- package/src/client/router.ts +11 -11
- package/src/client/runtime.ts +47 -47
- package/src/client/serialize.ts +404 -404
- package/src/client/use-fetch.ts +6 -6
- package/src/client/use-head.ts +197 -197
- package/src/client/use-sse.ts +378 -378
- package/src/client/window-state.ts +101 -101
- package/src/components/Image.tsx +162 -162
- package/src/config/validate.ts +3 -3
- package/src/config/watcher.ts +311 -311
- package/src/constants.ts +40 -40
- package/src/content/collection.ts +8 -8
- package/src/content/content-layer.ts +7 -7
- package/src/content/data-store.ts +245 -245
- package/src/content/frontmatter.ts +189 -189
- package/src/content/loader-context.ts +171 -171
- package/src/content/loaders/api.ts +216 -216
- package/src/content/loaders/file.ts +172 -172
- package/src/content/loaders/glob.ts +253 -253
- package/src/content/loaders/index.ts +34 -34
- package/src/content/loaders/types.ts +137 -137
- package/src/content/meta-store.ts +209 -209
- package/src/content/prebuild.test.ts +571 -571
- package/src/content/prebuild.ts +636 -636
- package/src/content/schema.ts +20 -20
- package/src/content/sidebar.ts +630 -630
- package/src/content/slug.ts +110 -110
- package/src/content/types.ts +282 -282
- package/src/content/watcher.ts +135 -135
- package/src/contract/client-safe.test.ts +42 -42
- package/src/contract/client-safe.ts +114 -114
- package/src/contract/define.ts +11 -11
- package/src/contract/index.ts +1 -1
- package/src/contract/normalize.test.ts +276 -276
- package/src/contract/normalize.ts +410 -410
- package/src/contract/registry.test.ts +206 -206
- package/src/contract/route-helpers.ts +1 -1
- package/src/contract/rpc.ts +443 -443
- package/src/contract/schema.ts +48 -48
- package/src/contract/types.ts +58 -58
- package/src/db/__tests__/db.test.ts +482 -482
- package/src/db/index.ts +138 -138
- package/src/db/migrations/history-table.ts +345 -345
- package/src/db/migrations/index.ts +3 -3
- package/src/db/migrations/lock.ts +324 -324
- package/src/db/migrations/runner.ts +650 -650
- package/src/deploy/cache.ts +140 -140
- package/src/deploy/compile/vercel.ts +344 -344
- package/src/deploy/index.ts +87 -87
- package/src/deploy/inference/brain.ts +268 -268
- package/src/deploy/inference/context.ts +182 -182
- package/src/deploy/inference/filling-extract.ts +245 -245
- package/src/deploy/inference/heuristic.ts +182 -182
- package/src/deploy/intent.ts +173 -173
- package/src/deploy/plan.ts +178 -178
- package/src/design/__tests__/agents-link.test.ts +109 -109
- package/src/design/__tests__/extract-patch-diff.test.ts +265 -265
- package/src/design/__tests__/lint.test.ts +110 -110
- package/src/design/__tests__/parser.test.ts +195 -195
- package/src/design/__tests__/tailwind-theme.test.ts +229 -229
- package/src/design/agents-link.ts +165 -165
- package/src/design/diff.ts +138 -138
- package/src/design/extract.ts +285 -285
- package/src/design/index.ts +102 -102
- package/src/design/lint.ts +209 -209
- package/src/design/parser.ts +555 -555
- package/src/design/patch.ts +241 -241
- package/src/design/scaffold.ts +147 -147
- package/src/design/tailwind-theme.ts +441 -441
- package/src/design/types.ts +210 -210
- package/src/desktop/__tests__/webview-fallback.test.ts +254 -254
- package/src/desktop/__tests__/window.test.ts +248 -248
- package/src/desktop/__tests__/worker.test.ts +266 -266
- package/src/desktop/index.ts +43 -43
- package/src/desktop/types.ts +158 -158
- package/src/desktop/worker.ts +180 -180
- package/src/dev-error-overlay/__tests__/overlay-injector.test.ts +241 -241
- package/src/dev-error-overlay/index.ts +30 -30
- package/src/dev-error-overlay/overlay-injector.ts +243 -243
- package/src/dev-error-overlay/overlay-styles.ts +52 -52
- package/src/dev-error-overlay/types.ts +66 -66
- package/src/devtools/ai/context-builder.ts +375 -375
- package/src/devtools/ai/index.ts +25 -25
- package/src/devtools/ai/mcp-connector.ts +25 -25
- package/src/devtools/client/catchers/error-catcher.ts +344 -344
- package/src/devtools/client/catchers/index.ts +18 -18
- package/src/devtools/client/components/index.ts +39 -39
- package/src/devtools/client/components/mandu-character.tsx +331 -331
- package/src/devtools/client/components/overlay.tsx +368 -368
- package/src/devtools/client/components/panel/errors-panel.tsx +259 -259
- package/src/devtools/client/components/panel/guard-panel.tsx +30 -30
- package/src/devtools/client/components/panel/islands-panel.tsx +320 -320
- package/src/devtools/client/components/panel/network-panel.tsx +291 -291
- package/src/devtools/client/components/panel/panel-container.tsx +500 -500
- package/src/devtools/client/components/panel/preview-panel.tsx +46 -46
- package/src/devtools/client/filters/context-filters.ts +282 -282
- package/src/devtools/client/filters/index.ts +16 -16
- package/src/devtools/client/index.ts +63 -63
- package/src/devtools/client/persistence.ts +335 -335
- package/src/devtools/hook/create-hook.ts +207 -207
- package/src/devtools/hook/index.ts +13 -13
- package/src/devtools/index.ts +439 -439
- package/src/devtools/init.ts +265 -265
- package/src/devtools/protocol.ts +237 -237
- package/src/devtools/server/index.ts +17 -17
- package/src/devtools/server/source-context.ts +450 -450
- package/src/devtools/types.ts +35 -35
- package/src/devtools/worker/index.ts +25 -25
- package/src/devtools/worker/redaction-worker.ts +233 -233
- package/src/devtools/worker/worker-manager.ts +410 -410
- package/src/diagnose/__tests__/checks.test.ts +451 -451
- package/src/diagnose/checks.ts +832 -832
- package/src/diagnose/index.ts +17 -17
- package/src/diagnose/run.ts +93 -93
- package/src/diagnose/types.ts +53 -53
- package/src/email/__tests__/email.test.ts +355 -355
- package/src/email/index.ts +282 -282
- package/src/email/smtp.ts +64 -64
- package/src/error/domains.ts +265 -265
- package/src/error/result.ts +60 -60
- package/src/error/types.ts +6 -6
- package/src/errors/extractor.ts +409 -409
- package/src/errors/index.ts +19 -19
- package/src/filling/__tests__/session-sqlite.test.ts +454 -454
- package/src/filling/auth.ts +308 -308
- package/src/filling/cookie-codec.ts +299 -299
- package/src/filling/deps.ts +265 -265
- package/src/filling/session-sqlite.ts +617 -617
- package/src/filling/sse.ts +5 -5
- package/src/filling/ws.ts +78 -78
- package/src/generator/index.ts +3 -3
- package/src/guard/__tests__/design-inline-class.test.ts +219 -219
- package/src/guard/__tests__/tsgolint-bridge.test.ts +347 -347
- package/src/guard/analyzer.ts +360 -360
- package/src/guard/auto-correct.ts +1 -1
- package/src/guard/contract-guard.ts +9 -9
- package/src/guard/define-rule.ts +243 -243
- package/src/guard/design-inline-class.ts +393 -393
- package/src/guard/file-type.test.ts +24 -24
- package/src/guard/graph.ts +1 -1
- package/src/guard/healing.ts +36 -36
- package/src/guard/presets/atomic.ts +70 -70
- package/src/guard/presets/clean.ts +77 -77
- package/src/guard/presets/fsd.ts +79 -79
- package/src/guard/presets/hexagonal.ts +68 -68
- package/src/guard/reporter.ts +442 -442
- package/src/guard/rule-presets.ts +379 -379
- package/src/guard/semantic-slots.ts +1 -1
- package/src/guard/suggestions.ts +358 -358
- package/src/guard/tsgolint-bridge.ts +512 -512
- package/src/guard/types.ts +348 -348
- package/src/guard/watcher.ts +405 -405
- package/src/i18n/define.ts +126 -126
- package/src/i18n/index.ts +52 -52
- package/src/i18n/message-registry.ts +173 -173
- package/src/i18n/types.ts +112 -112
- package/src/id/index.ts +105 -105
- package/src/index.ts +2 -2
- package/src/kitchen/api/agent-devtools-api.ts +779 -544
- package/src/kitchen/api/errors-grouping.ts +126 -0
- package/src/kitchen/kitchen-handler.ts +192 -63
- package/src/kitchen/kitchen-ui.ts +842 -464
- package/src/logging/index.ts +22 -22
- package/src/logging/transports.ts +365 -365
- package/src/middleware/bridge.ts +147 -147
- package/src/middleware/compose.ts +134 -134
- package/src/middleware/compress.ts +62 -62
- package/src/middleware/cors.ts +47 -47
- package/src/middleware/csrf.ts +328 -328
- package/src/middleware/define.ts +132 -132
- package/src/middleware/jwt.ts +134 -134
- package/src/middleware/logger.ts +58 -58
- package/src/middleware/oauth/__tests__/oauth.test.ts +1 -1
- package/src/middleware/oauth/index.ts +505 -505
- package/src/middleware/oauth/providers.ts +115 -115
- package/src/middleware/rate-limit/index.ts +522 -522
- package/src/middleware/rate-limit/sqlite-store.ts +382 -382
- package/src/middleware/scheduler-cron.ts +96 -96
- package/src/middleware/secure/__tests__/secure.test.ts +360 -360
- package/src/middleware/secure/csp.ts +193 -193
- package/src/middleware/session.ts +174 -174
- package/src/middleware/timeout.ts +55 -55
- package/src/observability/logger-adapter.ts +36 -36
- package/src/observability/sqlite-store.ts +254 -254
- package/src/openapi/generator.ts +1 -1
- package/src/openapi/openapi.test.ts +43 -43
- package/src/perf/__tests__/user-marks.test.ts +354 -354
- package/src/perf/index.ts +133 -133
- package/src/plugins/__tests__/lifecycle-integration.test.ts +272 -272
- package/src/plugins/__tests__/runner.test.ts +409 -409
- package/src/plugins/define.ts +124 -124
- package/src/plugins/examples/dep-check-plugin.ts +80 -80
- package/src/plugins/examples/prerender-cache-plugin.ts +111 -111
- package/src/plugins/examples/sitemap-plugin.ts +65 -65
- package/src/plugins/runner.ts +361 -361
- package/src/plugins/types.ts +368 -368
- package/src/report/index.ts +1 -1
- package/src/resource/__tests__/generator.test.ts +32 -32
- package/src/resource/ddl/__tests__/diff.test.ts +639 -639
- package/src/resource/ddl/__tests__/emit.test.ts +823 -823
- package/src/resource/ddl/__tests__/snapshot.test.ts +499 -499
- package/src/resource/ddl/emit.ts +559 -559
- package/src/resource/ddl/persistence-types.ts +218 -218
- package/src/resource/ddl/type-map.ts +223 -223
- package/src/resource/ddl/types.ts +232 -232
- package/src/resource/generator-repo.ts +630 -630
- package/src/resource/schema.ts +1 -1
- package/src/router/fs-patterns.test.ts +96 -96
- package/src/router/fs-routes.ts +6 -6
- package/src/routes/index.ts +74 -74
- package/src/routes/metadata-routes.ts +427 -427
- package/src/routes/types.ts +341 -341
- package/src/runtime/__tests__/error-boundary-redaction.test.ts +141 -141
- package/src/runtime/__tests__/hdr-client.test.ts +223 -223
- package/src/runtime/__tests__/http-errors.test.ts +117 -117
- package/src/runtime/__tests__/not-found.test.ts +152 -152
- package/src/runtime/adapter.ts +47 -47
- package/src/runtime/boundary.tsx +252 -252
- package/src/runtime/cache.ts +494 -494
- package/src/runtime/compose.ts +222 -222
- package/src/runtime/fast-refresh-runtime.ts +322 -322
- package/src/runtime/handler.ts +65 -65
- package/src/runtime/handlers.ts +300 -300
- package/src/runtime/http-errors.ts +113 -113
- package/src/runtime/image-handler.ts +1 -1
- package/src/runtime/lifecycle.ts +381 -381
- package/src/runtime/logger.test.ts +345 -345
- package/src/runtime/middleware.ts +264 -264
- package/src/runtime/not-found.ts +93 -93
- package/src/runtime/openapi-endpoint.ts +236 -236
- package/src/runtime/ppr.ts +74 -74
- package/src/runtime/registry.ts +171 -171
- package/src/runtime/router.ts +105 -105
- package/src/runtime/server.ts +67 -67
- package/src/runtime/shims.ts +48 -48
- package/src/runtime/trace.ts +144 -144
- package/src/scheduler/validate.ts +169 -169
- package/src/seo/index.ts +219 -219
- package/src/seo/integration/ssr.ts +306 -306
- package/src/seo/render/basic.ts +435 -435
- package/src/seo/render/index.ts +143 -143
- package/src/seo/render/jsonld.ts +539 -539
- package/src/seo/render/opengraph.ts +197 -197
- package/src/seo/render/robots.ts +116 -116
- package/src/seo/render/sitemap.ts +137 -137
- package/src/seo/render/twitter.ts +127 -127
- package/src/seo/resolve/opengraph.ts +143 -143
- package/src/seo/resolve/robots.ts +73 -73
- package/src/seo/resolve/title.ts +94 -94
- package/src/seo/resolve/twitter.ts +73 -73
- package/src/seo/resolve/url.ts +104 -104
- package/src/seo/routes/index.ts +290 -290
- package/src/seo/types.ts +588 -588
- package/src/slot/validator.ts +39 -39
- package/src/storage/s3/__tests__/s3.test.ts +479 -479
- package/src/storage/s3/index.ts +412 -412
- package/src/testing/__tests__/assertions.test.ts +632 -632
- package/src/testing/__tests__/reporter.test.ts +454 -454
- package/src/testing/assertions.ts +986 -986
- package/src/testing/db.ts +157 -157
- package/src/testing/mocks.ts +203 -203
- package/src/testing/session.ts +190 -190
- package/src/types/branded.ts +56 -56
- package/src/types/index.ts +1 -1
- package/src/utils/safe-io.ts +188 -188
- package/src/utils/string-safe.ts +298 -298
- package/src/watcher/watcher.ts +18 -18
|
@@ -1,229 +1,229 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Phase 7.0 — 36-scenario HMR test matrix (3 project forms × 12 change kinds)
|
|
3
|
-
*
|
|
4
|
-
* This module is the SINGLE SOURCE OF TRUTH for the matrix that:
|
|
5
|
-
* - Agent E (R2) builds the Playwright test harness around
|
|
6
|
-
* - Agent F (R3) asserts latency targets against
|
|
7
|
-
* - Any future regression test iterates over
|
|
8
|
-
*
|
|
9
|
-
* The matrix intentionally enumerates every combination even when a cell
|
|
10
|
-
* is trivially n/a (e.g. `island.client.tsx` in a pure-SSG project with
|
|
11
|
-
* zero islands) — `expectedBehavior: "n/a"` keeps the matrix square so
|
|
12
|
-
* the iteration loop doesn't need per-cell conditionals.
|
|
13
|
-
*
|
|
14
|
-
* References:
|
|
15
|
-
* docs/bun/phase-7-team-plan.md §3.3
|
|
16
|
-
* docs/bun/phase-7-diagnostics/performance-reliability.md §4 (매트릭스 초안)
|
|
17
|
-
*/
|
|
18
|
-
|
|
19
|
-
// ============================================
|
|
20
|
-
// Dimensions
|
|
21
|
-
// ============================================
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Three representative project shapes. Each R2 E fixture corresponds to
|
|
25
|
-
* one of these.
|
|
26
|
-
*/
|
|
27
|
-
export const PROJECT_FORMS = [
|
|
28
|
-
"pure-ssg", // no hydration, SSR → HTML only
|
|
29
|
-
"hybrid", // some pages with islands, some SSR-only
|
|
30
|
-
"full-interactive", // every route has at least one island
|
|
31
|
-
] as const;
|
|
32
|
-
|
|
33
|
-
export type ProjectForm = (typeof PROJECT_FORMS)[number];
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* File change kinds the matrix covers. Order matters only for stable
|
|
37
|
-
* report output — the iterating test runner relies on `for (const k of
|
|
38
|
-
* CHANGE_KINDS)`.
|
|
39
|
-
*
|
|
40
|
-
* Kept in sync with `docs/bun/phase-7-diagnostics/performance-reliability.md §4`.
|
|
41
|
-
*/
|
|
42
|
-
export const CHANGE_KINDS = [
|
|
43
|
-
"app/page.tsx",
|
|
44
|
-
"app/slot.ts",
|
|
45
|
-
"app/layout.tsx",
|
|
46
|
-
"app/contract.ts", // Agent D new coverage
|
|
47
|
-
"spec/resource.ts", // Agent D new coverage
|
|
48
|
-
"app/middleware.ts", // Agent D new coverage
|
|
49
|
-
"island.client.tsx",
|
|
50
|
-
"src/shared/**",
|
|
51
|
-
"src/top-level.ts", // Agent A new coverage (B1 fix)
|
|
52
|
-
"css",
|
|
53
|
-
"mandu.config.ts", // Agent D new coverage
|
|
54
|
-
".env", // Agent D new coverage
|
|
55
|
-
] as const;
|
|
56
|
-
|
|
57
|
-
export type ChangeKind = (typeof CHANGE_KINDS)[number];
|
|
58
|
-
|
|
59
|
-
// ============================================
|
|
60
|
-
// Cell shape
|
|
61
|
-
// ============================================
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* Every matrix cell's expected outcome. The test harness picks the
|
|
65
|
-
* right assertion strategy based on this field.
|
|
66
|
-
*
|
|
67
|
-
* - `"island-update"` : expect `island-update` WS message; DOM patch
|
|
68
|
-
* without full navigation; form/scroll preserved.
|
|
69
|
-
* - `"full-reload"` : expect `full-reload` or `reload` WS message;
|
|
70
|
-
* fresh HTML; previous state cleared.
|
|
71
|
-
* - `"prerender-regen"` : Pure-SSR common-dir path; expect #188 fix —
|
|
72
|
-
* new HTML reachable after reload.
|
|
73
|
-
* - `"css-update"` : expect `css-update`; <link> re-timestamped; no
|
|
74
|
-
* full reload.
|
|
75
|
-
* - `"server-restart"` : expect `mandu.config.ts` / `.env` auto-restart;
|
|
76
|
-
* dev server responds on same port after delay.
|
|
77
|
-
* - `"code-regen"` : expect contract/resource artifact regenerated
|
|
78
|
-
* AND handler re-registered (no browser event
|
|
79
|
-
* needed unless UI-visible).
|
|
80
|
-
* - `"n/a"` : combination impossible in that project form
|
|
81
|
-
* (e.g. island change in pure-ssg).
|
|
82
|
-
*/
|
|
83
|
-
export type ExpectedBehavior =
|
|
84
|
-
| "island-update"
|
|
85
|
-
| "full-reload"
|
|
86
|
-
| "prerender-regen"
|
|
87
|
-
| "css-update"
|
|
88
|
-
| "server-restart"
|
|
89
|
-
| "code-regen"
|
|
90
|
-
| "n/a";
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* A single matrix cell. Agent E materializes one Playwright test per
|
|
94
|
-
* cell; Agent F measures `REBUILD_TOTAL` on the same cells and asserts
|
|
95
|
-
* latency against the target.
|
|
96
|
-
*/
|
|
97
|
-
export interface ScenarioCell {
|
|
98
|
-
projectForm: ProjectForm;
|
|
99
|
-
changeKind: ChangeKind;
|
|
100
|
-
expectedBehavior: ExpectedBehavior;
|
|
101
|
-
/**
|
|
102
|
-
* Target `REBUILD_TOTAL` P95 in ms. `null` for `n/a` cells or
|
|
103
|
-
* `server-restart` (restart time varies by project startup).
|
|
104
|
-
*/
|
|
105
|
-
latencyTargetMs: number | null;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
// ============================================
|
|
109
|
-
// The 36 cells
|
|
110
|
-
// ============================================
|
|
111
|
-
|
|
112
|
-
/** Total cell count — mirrored in tests so they fail loudly if the
|
|
113
|
-
* matrix shape changes.
|
|
114
|
-
*
|
|
115
|
-
* NOTE: Declared BEFORE `SCENARIO_CELLS` so `buildMatrix()` — which runs
|
|
116
|
-
* during the `SCENARIO_CELLS` initializer and references this constant
|
|
117
|
-
* for its sanity check — does not hit a TDZ ReferenceError. The pair is
|
|
118
|
-
* still conceptually "matrix shape" metadata; they're co-located. */
|
|
119
|
-
export const EXPECTED_CELL_COUNT = PROJECT_FORMS.length * CHANGE_KINDS.length;
|
|
120
|
-
|
|
121
|
-
/**
|
|
122
|
-
* Pre-computed matrix. Derived once at module load so importers don't
|
|
123
|
-
* pay the lookup cost per test.
|
|
124
|
-
*/
|
|
125
|
-
export const SCENARIO_CELLS: readonly ScenarioCell[] = buildMatrix();
|
|
126
|
-
|
|
127
|
-
/** Look up a single cell. O(n) — matrix is small. */
|
|
128
|
-
export function findCell(
|
|
129
|
-
projectForm: ProjectForm,
|
|
130
|
-
changeKind: ChangeKind,
|
|
131
|
-
): ScenarioCell {
|
|
132
|
-
const cell = SCENARIO_CELLS.find(
|
|
133
|
-
(c) => c.projectForm === projectForm && c.changeKind === changeKind,
|
|
134
|
-
);
|
|
135
|
-
if (!cell) {
|
|
136
|
-
throw new Error(
|
|
137
|
-
`No scenario cell for ${projectForm} × ${changeKind}. Add it to scenario-matrix.ts.`,
|
|
138
|
-
);
|
|
139
|
-
}
|
|
140
|
-
return cell;
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
// ============================================
|
|
144
|
-
// Matrix construction
|
|
145
|
-
// ============================================
|
|
146
|
-
|
|
147
|
-
function buildMatrix(): ScenarioCell[] {
|
|
148
|
-
const cells: ScenarioCell[] = [];
|
|
149
|
-
for (const projectForm of PROJECT_FORMS) {
|
|
150
|
-
for (const changeKind of CHANGE_KINDS) {
|
|
151
|
-
cells.push({
|
|
152
|
-
projectForm,
|
|
153
|
-
changeKind,
|
|
154
|
-
expectedBehavior: classifyBehavior(projectForm, changeKind),
|
|
155
|
-
latencyTargetMs: classifyTarget(projectForm, changeKind),
|
|
156
|
-
});
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
if (cells.length !== EXPECTED_CELL_COUNT) {
|
|
160
|
-
throw new Error(
|
|
161
|
-
`scenario-matrix.ts built ${cells.length} cells, expected ${EXPECTED_CELL_COUNT}.`,
|
|
162
|
-
);
|
|
163
|
-
}
|
|
164
|
-
return cells;
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
function classifyBehavior(
|
|
168
|
-
projectForm: ProjectForm,
|
|
169
|
-
changeKind: ChangeKind,
|
|
170
|
-
): ExpectedBehavior {
|
|
171
|
-
// Island changes only apply to forms with islands.
|
|
172
|
-
if (changeKind === "island.client.tsx") {
|
|
173
|
-
return projectForm === "pure-ssg" ? "n/a" : "island-update";
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
// CSS is always style-swap.
|
|
177
|
-
if (changeKind === "css") return "css-update";
|
|
178
|
-
|
|
179
|
-
// Config / env always restart.
|
|
180
|
-
if (changeKind === "mandu.config.ts" || changeKind === ".env") {
|
|
181
|
-
return "server-restart";
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
// Contract / resource trigger code-gen + handler re-register.
|
|
185
|
-
if (changeKind === "app/contract.ts" || changeKind === "spec/resource.ts") {
|
|
186
|
-
return "code-regen";
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
// src/shared + src/top-level in pure-SSG needs the #188 prerender path.
|
|
190
|
-
if (
|
|
191
|
-
projectForm === "pure-ssg" &&
|
|
192
|
-
(changeKind === "src/shared/**" || changeKind === "src/top-level.ts")
|
|
193
|
-
) {
|
|
194
|
-
return "prerender-regen";
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
// Everything else is a full reload (SSR-rendered page, layout, slot,
|
|
198
|
-
// middleware, common deps in hybrid/interactive projects). Full reload
|
|
199
|
-
// is the honest fallback — SSR has no React state to preserve.
|
|
200
|
-
return "full-reload";
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
function classifyTarget(
|
|
204
|
-
projectForm: ProjectForm,
|
|
205
|
-
changeKind: ChangeKind,
|
|
206
|
-
): number | null {
|
|
207
|
-
const behavior = classifyBehavior(projectForm, changeKind);
|
|
208
|
-
switch (behavior) {
|
|
209
|
-
case "n/a":
|
|
210
|
-
return null;
|
|
211
|
-
case "island-update":
|
|
212
|
-
return 50; // HMR_PERF_TARGETS.ISLAND_REBUILD_P95_MS
|
|
213
|
-
case "css-update":
|
|
214
|
-
return 100; // HMR_PERF_TARGETS.CSS_REBUILD_P95_MS
|
|
215
|
-
case "server-restart":
|
|
216
|
-
return null; // project-dependent, not an HMR target
|
|
217
|
-
case "code-regen":
|
|
218
|
-
return 400; // regen is heavier than a plain rebuild
|
|
219
|
-
case "prerender-regen":
|
|
220
|
-
return 400; // fan-out across all prerendered routes
|
|
221
|
-
case "full-reload":
|
|
222
|
-
// src/shared in hybrid/interactive → common-dir rebuild (400ms),
|
|
223
|
-
// otherwise a single SSR page (200ms).
|
|
224
|
-
if (changeKind === "src/shared/**" || changeKind === "src/top-level.ts") {
|
|
225
|
-
return 400; // HMR_PERF_TARGETS.COMMON_DIR_REBUILD_P95_MS
|
|
226
|
-
}
|
|
227
|
-
return 200; // HMR_PERF_TARGETS.SSR_REBUILD_P95_MS
|
|
228
|
-
}
|
|
229
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Phase 7.0 — 36-scenario HMR test matrix (3 project forms × 12 change kinds)
|
|
3
|
+
*
|
|
4
|
+
* This module is the SINGLE SOURCE OF TRUTH for the matrix that:
|
|
5
|
+
* - Agent E (R2) builds the Playwright test harness around
|
|
6
|
+
* - Agent F (R3) asserts latency targets against
|
|
7
|
+
* - Any future regression test iterates over
|
|
8
|
+
*
|
|
9
|
+
* The matrix intentionally enumerates every combination even when a cell
|
|
10
|
+
* is trivially n/a (e.g. `island.client.tsx` in a pure-SSG project with
|
|
11
|
+
* zero islands) — `expectedBehavior: "n/a"` keeps the matrix square so
|
|
12
|
+
* the iteration loop doesn't need per-cell conditionals.
|
|
13
|
+
*
|
|
14
|
+
* References:
|
|
15
|
+
* docs/bun/phase-7-team-plan.md §3.3
|
|
16
|
+
* docs/bun/phase-7-diagnostics/performance-reliability.md §4 (매트릭스 초안)
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
// ============================================
|
|
20
|
+
// Dimensions
|
|
21
|
+
// ============================================
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Three representative project shapes. Each R2 E fixture corresponds to
|
|
25
|
+
* one of these.
|
|
26
|
+
*/
|
|
27
|
+
export const PROJECT_FORMS = [
|
|
28
|
+
"pure-ssg", // no hydration, SSR → HTML only
|
|
29
|
+
"hybrid", // some pages with islands, some SSR-only
|
|
30
|
+
"full-interactive", // every route has at least one island
|
|
31
|
+
] as const;
|
|
32
|
+
|
|
33
|
+
export type ProjectForm = (typeof PROJECT_FORMS)[number];
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* File change kinds the matrix covers. Order matters only for stable
|
|
37
|
+
* report output — the iterating test runner relies on `for (const k of
|
|
38
|
+
* CHANGE_KINDS)`.
|
|
39
|
+
*
|
|
40
|
+
* Kept in sync with `docs/bun/phase-7-diagnostics/performance-reliability.md §4`.
|
|
41
|
+
*/
|
|
42
|
+
export const CHANGE_KINDS = [
|
|
43
|
+
"app/page.tsx",
|
|
44
|
+
"app/slot.ts",
|
|
45
|
+
"app/layout.tsx",
|
|
46
|
+
"app/contract.ts", // Agent D new coverage
|
|
47
|
+
"spec/resource.ts", // Agent D new coverage
|
|
48
|
+
"app/middleware.ts", // Agent D new coverage
|
|
49
|
+
"island.client.tsx",
|
|
50
|
+
"src/shared/**",
|
|
51
|
+
"src/top-level.ts", // Agent A new coverage (B1 fix)
|
|
52
|
+
"css",
|
|
53
|
+
"mandu.config.ts", // Agent D new coverage
|
|
54
|
+
".env", // Agent D new coverage
|
|
55
|
+
] as const;
|
|
56
|
+
|
|
57
|
+
export type ChangeKind = (typeof CHANGE_KINDS)[number];
|
|
58
|
+
|
|
59
|
+
// ============================================
|
|
60
|
+
// Cell shape
|
|
61
|
+
// ============================================
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Every matrix cell's expected outcome. The test harness picks the
|
|
65
|
+
* right assertion strategy based on this field.
|
|
66
|
+
*
|
|
67
|
+
* - `"island-update"` : expect `island-update` WS message; DOM patch
|
|
68
|
+
* without full navigation; form/scroll preserved.
|
|
69
|
+
* - `"full-reload"` : expect `full-reload` or `reload` WS message;
|
|
70
|
+
* fresh HTML; previous state cleared.
|
|
71
|
+
* - `"prerender-regen"` : Pure-SSR common-dir path; expect #188 fix —
|
|
72
|
+
* new HTML reachable after reload.
|
|
73
|
+
* - `"css-update"` : expect `css-update`; <link> re-timestamped; no
|
|
74
|
+
* full reload.
|
|
75
|
+
* - `"server-restart"` : expect `mandu.config.ts` / `.env` auto-restart;
|
|
76
|
+
* dev server responds on same port after delay.
|
|
77
|
+
* - `"code-regen"` : expect contract/resource artifact regenerated
|
|
78
|
+
* AND handler re-registered (no browser event
|
|
79
|
+
* needed unless UI-visible).
|
|
80
|
+
* - `"n/a"` : combination impossible in that project form
|
|
81
|
+
* (e.g. island change in pure-ssg).
|
|
82
|
+
*/
|
|
83
|
+
export type ExpectedBehavior =
|
|
84
|
+
| "island-update"
|
|
85
|
+
| "full-reload"
|
|
86
|
+
| "prerender-regen"
|
|
87
|
+
| "css-update"
|
|
88
|
+
| "server-restart"
|
|
89
|
+
| "code-regen"
|
|
90
|
+
| "n/a";
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* A single matrix cell. Agent E materializes one Playwright test per
|
|
94
|
+
* cell; Agent F measures `REBUILD_TOTAL` on the same cells and asserts
|
|
95
|
+
* latency against the target.
|
|
96
|
+
*/
|
|
97
|
+
export interface ScenarioCell {
|
|
98
|
+
projectForm: ProjectForm;
|
|
99
|
+
changeKind: ChangeKind;
|
|
100
|
+
expectedBehavior: ExpectedBehavior;
|
|
101
|
+
/**
|
|
102
|
+
* Target `REBUILD_TOTAL` P95 in ms. `null` for `n/a` cells or
|
|
103
|
+
* `server-restart` (restart time varies by project startup).
|
|
104
|
+
*/
|
|
105
|
+
latencyTargetMs: number | null;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// ============================================
|
|
109
|
+
// The 36 cells
|
|
110
|
+
// ============================================
|
|
111
|
+
|
|
112
|
+
/** Total cell count — mirrored in tests so they fail loudly if the
|
|
113
|
+
* matrix shape changes.
|
|
114
|
+
*
|
|
115
|
+
* NOTE: Declared BEFORE `SCENARIO_CELLS` so `buildMatrix()` — which runs
|
|
116
|
+
* during the `SCENARIO_CELLS` initializer and references this constant
|
|
117
|
+
* for its sanity check — does not hit a TDZ ReferenceError. The pair is
|
|
118
|
+
* still conceptually "matrix shape" metadata; they're co-located. */
|
|
119
|
+
export const EXPECTED_CELL_COUNT = PROJECT_FORMS.length * CHANGE_KINDS.length;
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Pre-computed matrix. Derived once at module load so importers don't
|
|
123
|
+
* pay the lookup cost per test.
|
|
124
|
+
*/
|
|
125
|
+
export const SCENARIO_CELLS: readonly ScenarioCell[] = buildMatrix();
|
|
126
|
+
|
|
127
|
+
/** Look up a single cell. O(n) — matrix is small. */
|
|
128
|
+
export function findCell(
|
|
129
|
+
projectForm: ProjectForm,
|
|
130
|
+
changeKind: ChangeKind,
|
|
131
|
+
): ScenarioCell {
|
|
132
|
+
const cell = SCENARIO_CELLS.find(
|
|
133
|
+
(c) => c.projectForm === projectForm && c.changeKind === changeKind,
|
|
134
|
+
);
|
|
135
|
+
if (!cell) {
|
|
136
|
+
throw new Error(
|
|
137
|
+
`No scenario cell for ${projectForm} × ${changeKind}. Add it to scenario-matrix.ts.`,
|
|
138
|
+
);
|
|
139
|
+
}
|
|
140
|
+
return cell;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// ============================================
|
|
144
|
+
// Matrix construction
|
|
145
|
+
// ============================================
|
|
146
|
+
|
|
147
|
+
function buildMatrix(): ScenarioCell[] {
|
|
148
|
+
const cells: ScenarioCell[] = [];
|
|
149
|
+
for (const projectForm of PROJECT_FORMS) {
|
|
150
|
+
for (const changeKind of CHANGE_KINDS) {
|
|
151
|
+
cells.push({
|
|
152
|
+
projectForm,
|
|
153
|
+
changeKind,
|
|
154
|
+
expectedBehavior: classifyBehavior(projectForm, changeKind),
|
|
155
|
+
latencyTargetMs: classifyTarget(projectForm, changeKind),
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
if (cells.length !== EXPECTED_CELL_COUNT) {
|
|
160
|
+
throw new Error(
|
|
161
|
+
`scenario-matrix.ts built ${cells.length} cells, expected ${EXPECTED_CELL_COUNT}.`,
|
|
162
|
+
);
|
|
163
|
+
}
|
|
164
|
+
return cells;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
function classifyBehavior(
|
|
168
|
+
projectForm: ProjectForm,
|
|
169
|
+
changeKind: ChangeKind,
|
|
170
|
+
): ExpectedBehavior {
|
|
171
|
+
// Island changes only apply to forms with islands.
|
|
172
|
+
if (changeKind === "island.client.tsx") {
|
|
173
|
+
return projectForm === "pure-ssg" ? "n/a" : "island-update";
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// CSS is always style-swap.
|
|
177
|
+
if (changeKind === "css") return "css-update";
|
|
178
|
+
|
|
179
|
+
// Config / env always restart.
|
|
180
|
+
if (changeKind === "mandu.config.ts" || changeKind === ".env") {
|
|
181
|
+
return "server-restart";
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// Contract / resource trigger code-gen + handler re-register.
|
|
185
|
+
if (changeKind === "app/contract.ts" || changeKind === "spec/resource.ts") {
|
|
186
|
+
return "code-regen";
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// src/shared + src/top-level in pure-SSG needs the #188 prerender path.
|
|
190
|
+
if (
|
|
191
|
+
projectForm === "pure-ssg" &&
|
|
192
|
+
(changeKind === "src/shared/**" || changeKind === "src/top-level.ts")
|
|
193
|
+
) {
|
|
194
|
+
return "prerender-regen";
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// Everything else is a full reload (SSR-rendered page, layout, slot,
|
|
198
|
+
// middleware, common deps in hybrid/interactive projects). Full reload
|
|
199
|
+
// is the honest fallback — SSR has no React state to preserve.
|
|
200
|
+
return "full-reload";
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
function classifyTarget(
|
|
204
|
+
projectForm: ProjectForm,
|
|
205
|
+
changeKind: ChangeKind,
|
|
206
|
+
): number | null {
|
|
207
|
+
const behavior = classifyBehavior(projectForm, changeKind);
|
|
208
|
+
switch (behavior) {
|
|
209
|
+
case "n/a":
|
|
210
|
+
return null;
|
|
211
|
+
case "island-update":
|
|
212
|
+
return 50; // HMR_PERF_TARGETS.ISLAND_REBUILD_P95_MS
|
|
213
|
+
case "css-update":
|
|
214
|
+
return 100; // HMR_PERF_TARGETS.CSS_REBUILD_P95_MS
|
|
215
|
+
case "server-restart":
|
|
216
|
+
return null; // project-dependent, not an HMR target
|
|
217
|
+
case "code-regen":
|
|
218
|
+
return 400; // regen is heavier than a plain rebuild
|
|
219
|
+
case "prerender-regen":
|
|
220
|
+
return 400; // fan-out across all prerendered routes
|
|
221
|
+
case "full-reload":
|
|
222
|
+
// src/shared in hybrid/interactive → common-dir rebuild (400ms),
|
|
223
|
+
// otherwise a single SSR page (200ms).
|
|
224
|
+
if (changeKind === "src/shared/**" || changeKind === "src/top-level.ts") {
|
|
225
|
+
return 400; // HMR_PERF_TARGETS.COMMON_DIR_REBUILD_P95_MS
|
|
226
|
+
}
|
|
227
|
+
return 200; // HMR_PERF_TARGETS.SSR_REBUILD_P95_MS
|
|
228
|
+
}
|
|
229
|
+
}
|
package/src/bundler/types.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type * as __ManduBunTypes0 from "bun";
|
|
2
|
-
import type * as __ManduPluginsHooksTypes1 from "../plugins/hooks";
|
|
1
|
+
import type * as __ManduBunTypes0 from "bun";
|
|
2
|
+
import type * as __ManduPluginsHooksTypes1 from "../plugins/hooks";
|
|
3
3
|
/**
|
|
4
4
|
* Mandu Bundler Types
|
|
5
5
|
*/
|
|
@@ -123,14 +123,14 @@ export interface IslandFileEntry {
|
|
|
123
123
|
/**
|
|
124
124
|
* 번들러 옵션
|
|
125
125
|
*/
|
|
126
|
-
export interface BundlerOptions {
|
|
127
|
-
/**
|
|
128
|
-
* Build mode. This controls development-only transforms such as React
|
|
129
|
-
* Fast Refresh independently from minification.
|
|
130
|
-
*/
|
|
131
|
-
mode?: "development" | "production";
|
|
132
|
-
/** 코드 압축 여부 (기본: production에서 true) */
|
|
133
|
-
minify?: boolean;
|
|
126
|
+
export interface BundlerOptions {
|
|
127
|
+
/**
|
|
128
|
+
* Build mode. This controls development-only transforms such as React
|
|
129
|
+
* Fast Refresh independently from minification.
|
|
130
|
+
*/
|
|
131
|
+
mode?: "development" | "production";
|
|
132
|
+
/** 코드 압축 여부 (기본: production에서 true) */
|
|
133
|
+
minify?: boolean;
|
|
134
134
|
/** 소스맵 생성 여부 */
|
|
135
135
|
sourcemap?: boolean;
|
|
136
136
|
/** 파일 감시 모드 */
|