@mandujs/core 0.53.2 → 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 -380
- package/src/diagnose/checks.ts +832 -720
- package/src/diagnose/index.ts +17 -16
- package/src/diagnose/run.ts +93 -91
- 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/ssr.ts +24 -31
- package/src/runtime/streaming-ssr.ts +32 -37
- 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,162 +1,162 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Bundler plugin — React Compiler (#240).
|
|
3
|
-
*
|
|
4
|
-
* Auto-memoizes React components at build time via the official
|
|
5
|
-
* `babel-plugin-react-compiler`. Runs as a Bun `onLoad` transform:
|
|
6
|
-
* source → Babel + react-compiler → transformed code → Bun's remaining
|
|
7
|
-
* pipeline.
|
|
8
|
-
*
|
|
9
|
-
* Ported inline rather than depending on `bun-plugin-react-compiler`
|
|
10
|
-
* (single-maintainer, 9★ at 2026-04). The substantive logic is ~60
|
|
11
|
-
* lines; keeping it in-repo avoids the supply-chain risk without adding
|
|
12
|
-
* real maintenance cost.
|
|
13
|
-
*
|
|
14
|
-
* ## Scope
|
|
15
|
-
*
|
|
16
|
-
* Only invoked by the bundler's island / `"use client"` / partial build
|
|
17
|
-
* paths. Server-rendered files (`page.tsx` + `layout.tsx` SSR) never
|
|
18
|
-
* hit this plugin because React Compiler's memoization is a re-render
|
|
19
|
-
* optimization; SSR renders once and serializes to HTML. See
|
|
20
|
-
* `bundler/build.ts` for the gate.
|
|
21
|
-
*
|
|
22
|
-
* ## Opt-in
|
|
23
|
-
*
|
|
24
|
-
* Disabled by default. Projects enable via `mandu.config.ts`:
|
|
25
|
-
*
|
|
26
|
-
* ```ts
|
|
27
|
-
* export default {
|
|
28
|
-
* experimental: {
|
|
29
|
-
* reactCompiler: { enabled: true },
|
|
30
|
-
* },
|
|
31
|
-
* } satisfies ManduConfig;
|
|
32
|
-
* ```
|
|
33
|
-
*
|
|
34
|
-
* Failure mode: if `@babel/core` or `babel-plugin-react-compiler` are
|
|
35
|
-
* missing, the plugin returns the original source verbatim and logs
|
|
36
|
-
* once per build. This preserves the "enable the flag → try it" UX
|
|
37
|
-
* without blocking anyone who forgot to install the peer deps.
|
|
38
|
-
*/
|
|
39
|
-
|
|
40
|
-
import type { BunPlugin } from "bun";
|
|
41
|
-
import fs from "node:fs/promises";
|
|
42
|
-
|
|
43
|
-
export interface ReactCompilerPluginOptions {
|
|
44
|
-
/**
|
|
45
|
-
* File filter — only matching paths get the transform. Default:
|
|
46
|
-
* `.jsx` / `.tsx`. The bundler's own client-path gate narrows this
|
|
47
|
-
* further; the regex here is a belt-and-braces check.
|
|
48
|
-
*/
|
|
49
|
-
filter?: RegExp;
|
|
50
|
-
/**
|
|
51
|
-
* Options forwarded to `babel-plugin-react-compiler`. Common keys:
|
|
52
|
-
* - `compilationMode: "annotation" | "infer" | "all"`
|
|
53
|
-
* - `target: "19" | "18" | "17"`
|
|
54
|
-
* - `panicThreshold: "none" | "all_errors" | "critical_errors"`
|
|
55
|
-
* Omit to use react-compiler defaults (`compilationMode: "infer"` +
|
|
56
|
-
* `target` derived from the installed `react` version).
|
|
57
|
-
*/
|
|
58
|
-
reactCompilerConfig?: Record<string, unknown>;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
const DEFAULT_FILTER = /\.(?:jsx|tsx)$/;
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* Create the Bun plugin instance. Dynamic imports inside `onLoad` keep
|
|
65
|
-
* `@babel/core` out of the bundler's import graph when the plugin is
|
|
66
|
-
* never activated — the cost is a one-shot `await import()` on first
|
|
67
|
-
* use, which Bun caches.
|
|
68
|
-
*/
|
|
69
|
-
export function reactCompiler(
|
|
70
|
-
options: ReactCompilerPluginOptions = {},
|
|
71
|
-
): BunPlugin {
|
|
72
|
-
const filter = options.filter ?? DEFAULT_FILTER;
|
|
73
|
-
const compilerConfig = options.reactCompilerConfig;
|
|
74
|
-
|
|
75
|
-
// `@babel/core` + `babel-plugin-react-compiler` are optional peer
|
|
76
|
-
// dependencies — keep them out of the type graph so projects that
|
|
77
|
-
// don't enable the compiler never need `@types/babel__core`.
|
|
78
|
-
type BabelLike = { transformAsync: (src: string, opts: unknown) => Promise<{ code?: string | null } | null> };
|
|
79
|
-
let babelMod: BabelLike | null = null;
|
|
80
|
-
let compilerPlugin: unknown = null;
|
|
81
|
-
let resolutionFailed = false;
|
|
82
|
-
|
|
83
|
-
const resolveBabel = async (): Promise<boolean> => {
|
|
84
|
-
if (resolutionFailed) return false;
|
|
85
|
-
if (babelMod && compilerPlugin) return true;
|
|
86
|
-
try {
|
|
87
|
-
// Both imports are peerDependencies declared `optional: true` so
|
|
88
|
-
// projects without React Compiler never pay the install cost. We
|
|
89
|
-
// import each separately so a missing react-compiler package
|
|
90
|
-
// doesn't mask a Babel install failure.
|
|
91
|
-
if (!babelMod) {
|
|
92
|
-
const mod = (await import(/* @vite-ignore */ "@babel/core" as string)) as unknown as BabelLike;
|
|
93
|
-
babelMod = mod;
|
|
94
|
-
}
|
|
95
|
-
if (!compilerPlugin) {
|
|
96
|
-
const cm = (await import(/* @vite-ignore */ "babel-plugin-react-compiler" as string)) as unknown as {
|
|
97
|
-
default?: unknown;
|
|
98
|
-
};
|
|
99
|
-
compilerPlugin = cm.default ?? cm;
|
|
100
|
-
}
|
|
101
|
-
return true;
|
|
102
|
-
} catch (err) {
|
|
103
|
-
resolutionFailed = true;
|
|
104
|
-
console.warn(
|
|
105
|
-
"[Mandu React Compiler] Peer dependency missing — skipping transform. " +
|
|
106
|
-
"Install @babel/core + babel-plugin-react-compiler to enable. " +
|
|
107
|
-
`Reason: ${err instanceof Error ? err.message : String(err)}`,
|
|
108
|
-
);
|
|
109
|
-
return false;
|
|
110
|
-
}
|
|
111
|
-
};
|
|
112
|
-
|
|
113
|
-
return {
|
|
114
|
-
name: "mandu:react-compiler",
|
|
115
|
-
setup(build) {
|
|
116
|
-
build.onLoad({ filter }, async ({ path: filePath }) => {
|
|
117
|
-
const ok = await resolveBabel();
|
|
118
|
-
if (!ok || !babelMod || !compilerPlugin) return undefined;
|
|
119
|
-
|
|
120
|
-
let source: string;
|
|
121
|
-
try {
|
|
122
|
-
source = await fs.readFile(filePath, "utf-8");
|
|
123
|
-
} catch {
|
|
124
|
-
// Bun will surface the original read error when it retries
|
|
125
|
-
// the load itself; returning undefined gives it the chance.
|
|
126
|
-
return undefined;
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
try {
|
|
130
|
-
const result = await babelMod.transformAsync(source, {
|
|
131
|
-
filename: filePath,
|
|
132
|
-
sourceMaps: "inline",
|
|
133
|
-
babelrc: false,
|
|
134
|
-
configFile: false,
|
|
135
|
-
parserOpts: {
|
|
136
|
-
plugins: [
|
|
137
|
-
"jsx",
|
|
138
|
-
"typescript",
|
|
139
|
-
"explicitResourceManagement",
|
|
140
|
-
],
|
|
141
|
-
},
|
|
142
|
-
plugins: [[compilerPlugin, compilerConfig ?? {}]],
|
|
143
|
-
});
|
|
144
|
-
if (!result?.code) return undefined;
|
|
145
|
-
return {
|
|
146
|
-
contents: result.code,
|
|
147
|
-
loader: filePath.endsWith(".tsx") ? "tsx" : "jsx",
|
|
148
|
-
};
|
|
149
|
-
} catch (err) {
|
|
150
|
-
// Return original so Bun falls back to its normal transform —
|
|
151
|
-
// react-compiler skips plenty of components by design
|
|
152
|
-
// ("15% bailout") and we don't want a bailout to kill the
|
|
153
|
-
// build. Log once per file path with the reason.
|
|
154
|
-
console.warn(
|
|
155
|
-
`[Mandu React Compiler] skip ${filePath}: ${err instanceof Error ? err.message : String(err)}`,
|
|
156
|
-
);
|
|
157
|
-
return undefined;
|
|
158
|
-
}
|
|
159
|
-
});
|
|
160
|
-
},
|
|
161
|
-
};
|
|
162
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Bundler plugin — React Compiler (#240).
|
|
3
|
+
*
|
|
4
|
+
* Auto-memoizes React components at build time via the official
|
|
5
|
+
* `babel-plugin-react-compiler`. Runs as a Bun `onLoad` transform:
|
|
6
|
+
* source → Babel + react-compiler → transformed code → Bun's remaining
|
|
7
|
+
* pipeline.
|
|
8
|
+
*
|
|
9
|
+
* Ported inline rather than depending on `bun-plugin-react-compiler`
|
|
10
|
+
* (single-maintainer, 9★ at 2026-04). The substantive logic is ~60
|
|
11
|
+
* lines; keeping it in-repo avoids the supply-chain risk without adding
|
|
12
|
+
* real maintenance cost.
|
|
13
|
+
*
|
|
14
|
+
* ## Scope
|
|
15
|
+
*
|
|
16
|
+
* Only invoked by the bundler's island / `"use client"` / partial build
|
|
17
|
+
* paths. Server-rendered files (`page.tsx` + `layout.tsx` SSR) never
|
|
18
|
+
* hit this plugin because React Compiler's memoization is a re-render
|
|
19
|
+
* optimization; SSR renders once and serializes to HTML. See
|
|
20
|
+
* `bundler/build.ts` for the gate.
|
|
21
|
+
*
|
|
22
|
+
* ## Opt-in
|
|
23
|
+
*
|
|
24
|
+
* Disabled by default. Projects enable via `mandu.config.ts`:
|
|
25
|
+
*
|
|
26
|
+
* ```ts
|
|
27
|
+
* export default {
|
|
28
|
+
* experimental: {
|
|
29
|
+
* reactCompiler: { enabled: true },
|
|
30
|
+
* },
|
|
31
|
+
* } satisfies ManduConfig;
|
|
32
|
+
* ```
|
|
33
|
+
*
|
|
34
|
+
* Failure mode: if `@babel/core` or `babel-plugin-react-compiler` are
|
|
35
|
+
* missing, the plugin returns the original source verbatim and logs
|
|
36
|
+
* once per build. This preserves the "enable the flag → try it" UX
|
|
37
|
+
* without blocking anyone who forgot to install the peer deps.
|
|
38
|
+
*/
|
|
39
|
+
|
|
40
|
+
import type { BunPlugin } from "bun";
|
|
41
|
+
import fs from "node:fs/promises";
|
|
42
|
+
|
|
43
|
+
export interface ReactCompilerPluginOptions {
|
|
44
|
+
/**
|
|
45
|
+
* File filter — only matching paths get the transform. Default:
|
|
46
|
+
* `.jsx` / `.tsx`. The bundler's own client-path gate narrows this
|
|
47
|
+
* further; the regex here is a belt-and-braces check.
|
|
48
|
+
*/
|
|
49
|
+
filter?: RegExp;
|
|
50
|
+
/**
|
|
51
|
+
* Options forwarded to `babel-plugin-react-compiler`. Common keys:
|
|
52
|
+
* - `compilationMode: "annotation" | "infer" | "all"`
|
|
53
|
+
* - `target: "19" | "18" | "17"`
|
|
54
|
+
* - `panicThreshold: "none" | "all_errors" | "critical_errors"`
|
|
55
|
+
* Omit to use react-compiler defaults (`compilationMode: "infer"` +
|
|
56
|
+
* `target` derived from the installed `react` version).
|
|
57
|
+
*/
|
|
58
|
+
reactCompilerConfig?: Record<string, unknown>;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const DEFAULT_FILTER = /\.(?:jsx|tsx)$/;
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Create the Bun plugin instance. Dynamic imports inside `onLoad` keep
|
|
65
|
+
* `@babel/core` out of the bundler's import graph when the plugin is
|
|
66
|
+
* never activated — the cost is a one-shot `await import()` on first
|
|
67
|
+
* use, which Bun caches.
|
|
68
|
+
*/
|
|
69
|
+
export function reactCompiler(
|
|
70
|
+
options: ReactCompilerPluginOptions = {},
|
|
71
|
+
): BunPlugin {
|
|
72
|
+
const filter = options.filter ?? DEFAULT_FILTER;
|
|
73
|
+
const compilerConfig = options.reactCompilerConfig;
|
|
74
|
+
|
|
75
|
+
// `@babel/core` + `babel-plugin-react-compiler` are optional peer
|
|
76
|
+
// dependencies — keep them out of the type graph so projects that
|
|
77
|
+
// don't enable the compiler never need `@types/babel__core`.
|
|
78
|
+
type BabelLike = { transformAsync: (src: string, opts: unknown) => Promise<{ code?: string | null } | null> };
|
|
79
|
+
let babelMod: BabelLike | null = null;
|
|
80
|
+
let compilerPlugin: unknown = null;
|
|
81
|
+
let resolutionFailed = false;
|
|
82
|
+
|
|
83
|
+
const resolveBabel = async (): Promise<boolean> => {
|
|
84
|
+
if (resolutionFailed) return false;
|
|
85
|
+
if (babelMod && compilerPlugin) return true;
|
|
86
|
+
try {
|
|
87
|
+
// Both imports are peerDependencies declared `optional: true` so
|
|
88
|
+
// projects without React Compiler never pay the install cost. We
|
|
89
|
+
// import each separately so a missing react-compiler package
|
|
90
|
+
// doesn't mask a Babel install failure.
|
|
91
|
+
if (!babelMod) {
|
|
92
|
+
const mod = (await import(/* @vite-ignore */ "@babel/core" as string)) as unknown as BabelLike;
|
|
93
|
+
babelMod = mod;
|
|
94
|
+
}
|
|
95
|
+
if (!compilerPlugin) {
|
|
96
|
+
const cm = (await import(/* @vite-ignore */ "babel-plugin-react-compiler" as string)) as unknown as {
|
|
97
|
+
default?: unknown;
|
|
98
|
+
};
|
|
99
|
+
compilerPlugin = cm.default ?? cm;
|
|
100
|
+
}
|
|
101
|
+
return true;
|
|
102
|
+
} catch (err) {
|
|
103
|
+
resolutionFailed = true;
|
|
104
|
+
console.warn(
|
|
105
|
+
"[Mandu React Compiler] Peer dependency missing — skipping transform. " +
|
|
106
|
+
"Install @babel/core + babel-plugin-react-compiler to enable. " +
|
|
107
|
+
`Reason: ${err instanceof Error ? err.message : String(err)}`,
|
|
108
|
+
);
|
|
109
|
+
return false;
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
return {
|
|
114
|
+
name: "mandu:react-compiler",
|
|
115
|
+
setup(build) {
|
|
116
|
+
build.onLoad({ filter }, async ({ path: filePath }) => {
|
|
117
|
+
const ok = await resolveBabel();
|
|
118
|
+
if (!ok || !babelMod || !compilerPlugin) return undefined;
|
|
119
|
+
|
|
120
|
+
let source: string;
|
|
121
|
+
try {
|
|
122
|
+
source = await fs.readFile(filePath, "utf-8");
|
|
123
|
+
} catch {
|
|
124
|
+
// Bun will surface the original read error when it retries
|
|
125
|
+
// the load itself; returning undefined gives it the chance.
|
|
126
|
+
return undefined;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
try {
|
|
130
|
+
const result = await babelMod.transformAsync(source, {
|
|
131
|
+
filename: filePath,
|
|
132
|
+
sourceMaps: "inline",
|
|
133
|
+
babelrc: false,
|
|
134
|
+
configFile: false,
|
|
135
|
+
parserOpts: {
|
|
136
|
+
plugins: [
|
|
137
|
+
"jsx",
|
|
138
|
+
"typescript",
|
|
139
|
+
"explicitResourceManagement",
|
|
140
|
+
],
|
|
141
|
+
},
|
|
142
|
+
plugins: [[compilerPlugin, compilerConfig ?? {}]],
|
|
143
|
+
});
|
|
144
|
+
if (!result?.code) return undefined;
|
|
145
|
+
return {
|
|
146
|
+
contents: result.code,
|
|
147
|
+
loader: filePath.endsWith(".tsx") ? "tsx" : "jsx",
|
|
148
|
+
};
|
|
149
|
+
} catch (err) {
|
|
150
|
+
// Return original so Bun falls back to its normal transform —
|
|
151
|
+
// react-compiler skips plenty of components by design
|
|
152
|
+
// ("15% bailout") and we don't want a bailout to kill the
|
|
153
|
+
// build. Log once per file path with the reason.
|
|
154
|
+
console.warn(
|
|
155
|
+
`[Mandu React Compiler] skip ${filePath}: ${err instanceof Error ? err.message : String(err)}`,
|
|
156
|
+
);
|
|
157
|
+
return undefined;
|
|
158
|
+
}
|
|
159
|
+
});
|
|
160
|
+
},
|
|
161
|
+
};
|
|
162
|
+
}
|