@mandujs/core 0.54.31 → 0.55.0-beta.1
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 +106 -210
- package/scripts/postinstall-lock.ts +153 -153
- 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 +15 -15
- package/src/a11y/types.ts +125 -125
- package/src/agent/__tests__/apply.test.ts +224 -0
- package/src/agent/__tests__/context.test.ts +97 -98
- package/src/agent/apply.ts +1031 -0
- package/src/agent/context.ts +552 -552
- package/src/agent/index.ts +4 -3
- package/src/agent/plan.ts +161 -243
- package/src/agent/repair.ts +239 -162
- package/src/agent/sync.ts +197 -198
- package/src/agent/types.ts +242 -94
- package/src/agent/verify.ts +55 -55
- package/src/auth/__tests__/login.test.ts +1 -1
- package/src/auth/__tests__/password.test.ts +15 -5
- package/src/auth/__tests__/reset.test.ts +2 -2
- 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 +14 -2
- 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/brain/doctor/analyzer.ts +7 -7
- package/src/bundler/__snapshots__/build.test.ts.snap +5 -5
- package/src/bundler/__tests__/build-runner.ts +166 -166
- package/src/bundler/__tests__/client-boundary-transform.test.ts +524 -524
- package/src/bundler/__tests__/cold-start.test.ts +60 -60
- package/src/bundler/__tests__/css.test.ts +49 -20
- 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 +24 -24
- package/src/bundler/__tests__/generation.test.ts +447 -0
- package/src/bundler/__tests__/hdr.test.ts +24 -18
- package/src/bundler/__tests__/hmr-client.test.ts +62 -24
- package/src/bundler/__tests__/jsx-runtime-shim.test.ts +179 -140
- package/src/bundler/__tests__/manifest-schema.test.ts +305 -266
- package/src/bundler/__tests__/prod-smoke.test.ts +138 -138
- package/src/bundler/__tests__/reverse-import-graph.test.ts +42 -42
- 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/analyzer.ts +15 -15
- package/src/bundler/budget.ts +404 -404
- package/src/bundler/build.test.ts +898 -915
- package/src/bundler/build.ts +113 -24
- package/src/bundler/client-boundary-transform.ts +977 -977
- package/src/bundler/css.ts +65 -44
- package/src/bundler/dev.ts +105 -73
- package/src/bundler/fast-refresh-preamble.ts +47 -47
- package/src/bundler/generation.ts +602 -0
- package/src/bundler/index.ts +3 -3
- package/src/bundler/manifest-schema.ts +55 -40
- package/src/bundler/plugins/__tests__/block-generated-imports.test.ts +13 -13
- 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 +16 -15
- 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/prerender.ts +29 -9
- package/src/bundler/reverse-import-graph.ts +339 -339
- package/src/bundler/safe-build.test.ts +1 -1
- package/src/bundler/safe-build.ts +103 -103
- package/src/bundler/scenario-matrix.ts +229 -229
- package/src/bundler/types.ts +58 -56
- 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__/props-serialization.test.ts +37 -37
- 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 +2 -2
- package/src/client/index.ts +1 -1
- package/src/client/island.ts +79 -79
- package/src/client/prefetch-helper.ts +55 -55
- package/src/client/props-serialization.ts +233 -233
- package/src/client/runtime-entry.ts +598 -598
- package/src/client/runtime.ts +1 -1
- package/src/client/serialize.ts +50 -50
- 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-compat.ts +3 -0
- package/src/components/Image.tsx +162 -162
- package/src/config/validate.ts +1 -1
- package/src/config/watcher.ts +311 -311
- package/src/constants.ts +40 -40
- package/src/content/collection.ts +9 -9
- 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/generate-types.ts +1 -1
- package/src/content/index.ts +2 -2
- 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/types.ts +58 -58
- package/src/db/__tests__/db.test.ts +9 -9
- package/src/db/index.ts +2 -2
- 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 +82 -82
- 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__/smoke.test.ts +2 -2
- package/src/desktop/__tests__/webview-fallback.test.ts +12 -32
- package/src/desktop/__tests__/window.test.ts +20 -99
- 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/webview-fallback.ts +17 -4
- package/src/desktop/window.ts +17 -8
- 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/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 +16 -16
- package/src/devtools/client/components/panel/network-panel.tsx +291 -291
- package/src/devtools/client/components/panel/panel-container.tsx +1 -1
- 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/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/types.ts +35 -35
- package/src/devtools/worker/index.ts +25 -25
- package/src/devtools/worker/redaction-worker.ts +233 -233
- package/src/diagnose/__tests__/checks.test.ts +136 -136
- package/src/diagnose/checks.ts +185 -185
- package/src/diagnose/index.ts +17 -17
- package/src/diagnose/run.ts +10 -10
- 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/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 +5 -1
- package/src/filling/auth.ts +308 -308
- package/src/filling/body-parse.test.ts +60 -60
- package/src/filling/cookie-codec.ts +5 -3
- package/src/filling/deps.ts +265 -265
- package/src/filling/head-method.test.ts +154 -154
- 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/generate.ts +30 -30
- package/src/generator/index.ts +3 -3
- package/src/generator/templates.test.ts +48 -48
- package/src/generator/templates.ts +219 -219
- 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/check.ts +39 -24
- package/src/guard/config-guard.ts +13 -13
- 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/fs-routes-policy.ts +51 -51
- package/src/guard/graph.ts +1 -1
- package/src/guard/healing.ts +36 -36
- package/src/guard/index.ts +11 -11
- 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/__tests__/id.test.ts +3 -3
- package/src/id/index.ts +105 -105
- package/src/index.ts +9 -48
- package/src/internal/client-boundary.ts +266 -266
- package/src/internal/index.ts +2 -2
- package/src/kitchen/api/agent-devtools-api.ts +779 -779
- package/src/kitchen/api/bundle-inspector.ts +179 -0
- package/src/kitchen/api/errors-grouping.ts +126 -126
- package/src/kitchen/api/file-api.ts +11 -11
- package/src/kitchen/kitchen-handler.ts +36 -0
- package/src/kitchen/kitchen-ui.ts +456 -0
- 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/perf/user-marks.ts +1 -1
- 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 +7 -7
- package/src/resource/__tests__/schema.test.ts +14 -14
- package/src/resource/ddl/__tests__/diff.test.ts +639 -639
- package/src/resource/ddl/__tests__/emit.test.ts +165 -165
- package/src/resource/ddl/__tests__/snapshot.test.ts +499 -499
- package/src/resource/ddl/emit.ts +146 -146
- 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/generator-schema.ts +11 -11
- package/src/resource/generators/slot.ts +72 -72
- package/src/resource/schema.ts +21 -21
- package/src/router/client-entry.test.ts +227 -227
- package/src/router/client-entry.ts +218 -218
- package/src/router/fs-patterns.test.ts +96 -96
- package/src/router/fs-routes.test.ts +532 -532
- package/src/router/fs-routes.ts +53 -53
- package/src/router/fs-scanner.ts +216 -216
- package/src/router/fs-types.ts +19 -19
- package/src/router/route-source-analyzer.ts +521 -521
- 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__/devtools-adapter.test.ts +68 -68
- 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__/inline-client-hydration.test.ts +237 -237
- package/src/runtime/__tests__/not-found.test.ts +152 -152
- package/src/runtime/__tests__/observability-lifecycle.test.ts +103 -103
- package/src/runtime/__tests__/page-render-response.test.ts +517 -517
- package/src/runtime/__tests__/request-middleware.test.ts +70 -70
- package/src/runtime/__tests__/searchparams-page-props.test.ts +81 -81
- 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/devtools-adapter.ts +68 -68
- package/src/runtime/escape.ts +34 -34
- package/src/runtime/fast-refresh-runtime.ts +322 -322
- package/src/runtime/fast-refresh-types.ts +1 -1
- package/src/runtime/handler.ts +65 -65
- package/src/runtime/handlers.ts +30 -11
- 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/observability-lifecycle.ts +290 -290
- package/src/runtime/openapi-endpoint.ts +236 -236
- package/src/runtime/page-render-response.ts +287 -274
- package/src/runtime/ppr.ts +74 -74
- package/src/runtime/rate-limit.ts +1 -1
- package/src/runtime/redirect.ts +1 -1
- package/src/runtime/registry.ts +171 -171
- package/src/runtime/request-middleware.ts +31 -31
- package/src/runtime/router.test.ts +4 -4
- package/src/runtime/router.ts +10 -10
- package/src/runtime/server.ts +39 -20
- package/src/runtime/shims.ts +48 -48
- package/src/runtime/ssr.ts +43 -17
- package/src/runtime/static-files.ts +369 -289
- package/src/runtime/streaming-ssr.ts +219 -180
- package/src/runtime/trace.ts +144 -144
- package/src/scheduler/__tests__/scheduler.test.ts +12 -11
- package/src/scheduler/index.ts +11 -5
- 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/spec/schema.ts +35 -35
- 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/index.ts +9 -3
- package/src/testing/lcov.ts +192 -0
- 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/__tests__/watcher.test.ts +59 -59
- package/src/watcher/watcher.ts +61 -61
|
@@ -31,7 +31,7 @@ async function makeEntry(name: string, body = "export const x = 1;\n"): Promise<
|
|
|
31
31
|
return file;
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
describe("safeBuild", () => {
|
|
34
|
+
describe.skipIf(process.env.MANDU_SKIP_BUNDLER_TESTS === "1")("safeBuild", () => {
|
|
35
35
|
it("returns the same BuildOutput shape as Bun.build", async () => {
|
|
36
36
|
const entry = await makeEntry("a");
|
|
37
37
|
const result = await safeBuild({
|
|
@@ -1,103 +1,103 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Concurrency-limited wrapper around `Bun.build`.
|
|
3
|
-
*
|
|
4
|
-
* Why this exists:
|
|
5
|
-
* - `Bun.build` exhibits failure modes under high concurrent invocation —
|
|
6
|
-
* observed as `AggregateError: Bundle failed` with missing output shims
|
|
7
|
-
* (e.g. `_react-dom-client.js`) when 5+ builds fire in parallel and
|
|
8
|
-
* multiple test worker processes pile on simultaneously.
|
|
9
|
-
* - Our own `buildClientBundles` fans out vendor-shim builds via `Promise.all`
|
|
10
|
-
* (5 concurrent). Combined with parallel test workers or concurrent dev-mode
|
|
11
|
-
* rebuilds, total concurrent `Bun.build` invocations can exceed what the
|
|
12
|
-
* runtime/OS resolves reliably, yielding intermittent failures that are
|
|
13
|
-
* hard to diagnose.
|
|
14
|
-
*
|
|
15
|
-
* Design:
|
|
16
|
-
* - Process-wide semaphore. Default cap: `2` concurrent `Bun.build` per
|
|
17
|
-
* process. Tunable via `MANDU_BUN_BUILD_CONCURRENCY` (positive integer).
|
|
18
|
-
* - FIFO queue — no priority, no cancellation. Callers get `Bun.build`'s
|
|
19
|
-
* `BuildOutput` result (or exception) transparently.
|
|
20
|
-
* - In-process only. Cross-worker coordination is not this module's job;
|
|
21
|
-
* per-worker throttling already prevents the observed failure modes in
|
|
22
|
-
* our test matrix.
|
|
23
|
-
*
|
|
24
|
-
* Correctness — slot handoff:
|
|
25
|
-
* - The semaphore does slot *handoff* rather than release-then-acquire. When
|
|
26
|
-
* a build completes with waiters queued, the slot is transferred directly
|
|
27
|
-
* to the next waiter (active count never drops). A previous revision had
|
|
28
|
-
* a classic acquire race: `releaseSlot()` decremented `active` before the
|
|
29
|
-
* waiter's `active++` ran, which opened a microtask-sized window where a
|
|
30
|
-
* concurrent `safeBuild()` call could observe `active < max`, skip the
|
|
31
|
-
* wait, and join in — yielding `cap+1` concurrent builds.
|
|
32
|
-
*/
|
|
33
|
-
|
|
34
|
-
import type { BuildConfig, BuildOutput } from "bun";
|
|
35
|
-
|
|
36
|
-
const DEFAULT_MAX_CONCURRENT = 2;
|
|
37
|
-
|
|
38
|
-
function parseMaxConcurrent(): number {
|
|
39
|
-
const raw = process.env.MANDU_BUN_BUILD_CONCURRENCY;
|
|
40
|
-
if (!raw) return DEFAULT_MAX_CONCURRENT;
|
|
41
|
-
const parsed = Number.parseInt(raw, 10);
|
|
42
|
-
if (!Number.isFinite(parsed) || parsed < 1) return DEFAULT_MAX_CONCURRENT;
|
|
43
|
-
return parsed;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
const maxConcurrent = parseMaxConcurrent();
|
|
47
|
-
let active = 0;
|
|
48
|
-
const waiters: Array<() => void> = [];
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* Acquire a slot. When `active < max`, increment synchronously and return.
|
|
52
|
-
* Otherwise, queue and await a direct handoff from a completing build —
|
|
53
|
-
* the completing build does NOT decrement `active`; it resolves our waiter,
|
|
54
|
-
* and `active` stays at `max` through the transition. This prevents a
|
|
55
|
-
* microtask-window race where a third caller could see `active < max` and
|
|
56
|
-
* skip the wait entirely.
|
|
57
|
-
*/
|
|
58
|
-
function acquireSlot(): Promise<void> {
|
|
59
|
-
if (active < maxConcurrent) {
|
|
60
|
-
active++;
|
|
61
|
-
return Promise.resolve();
|
|
62
|
-
}
|
|
63
|
-
return new Promise<void>((resolve) => {
|
|
64
|
-
waiters.push(resolve);
|
|
65
|
-
});
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* Release a slot. If a waiter is queued, hand the slot off directly (keep
|
|
70
|
-
* `active` at `max`, resolve the waiter). Otherwise decrement `active`.
|
|
71
|
-
*/
|
|
72
|
-
function releaseSlot(): void {
|
|
73
|
-
const next = waiters.shift();
|
|
74
|
-
if (next) {
|
|
75
|
-
// Direct handoff — `active` stays at max, waiter resumes holding the slot.
|
|
76
|
-
next();
|
|
77
|
-
} else {
|
|
78
|
-
active--;
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
/**
|
|
83
|
-
* Runs `Bun.build(options)` subject to a process-wide concurrency cap.
|
|
84
|
-
* Preserves the exact return type and error semantics of `Bun.build`.
|
|
85
|
-
*
|
|
86
|
-
* Note: this wrapper only caps concurrency *within* a single process. Test
|
|
87
|
-
* harnesses that spawn multiple worker processes still see each worker run
|
|
88
|
-
* up to `maxConcurrent` concurrent builds — see Phase 0.6 for cross-process
|
|
89
|
-
* coordination work.
|
|
90
|
-
*/
|
|
91
|
-
export async function safeBuild(options: BuildConfig): Promise<BuildOutput> {
|
|
92
|
-
await acquireSlot();
|
|
93
|
-
try {
|
|
94
|
-
return await Bun.build(options);
|
|
95
|
-
} finally {
|
|
96
|
-
releaseSlot();
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
/** Exposed for tests — not part of the public API. */
|
|
101
|
-
export function _getConcurrencyState() {
|
|
102
|
-
return { active, queued: waiters.length, max: maxConcurrent };
|
|
103
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Concurrency-limited wrapper around `Bun.build`.
|
|
3
|
+
*
|
|
4
|
+
* Why this exists:
|
|
5
|
+
* - `Bun.build` exhibits failure modes under high concurrent invocation —
|
|
6
|
+
* observed as `AggregateError: Bundle failed` with missing output shims
|
|
7
|
+
* (e.g. `_react-dom-client.js`) when 5+ builds fire in parallel and
|
|
8
|
+
* multiple test worker processes pile on simultaneously.
|
|
9
|
+
* - Our own `buildClientBundles` fans out vendor-shim builds via `Promise.all`
|
|
10
|
+
* (5 concurrent). Combined with parallel test workers or concurrent dev-mode
|
|
11
|
+
* rebuilds, total concurrent `Bun.build` invocations can exceed what the
|
|
12
|
+
* runtime/OS resolves reliably, yielding intermittent failures that are
|
|
13
|
+
* hard to diagnose.
|
|
14
|
+
*
|
|
15
|
+
* Design:
|
|
16
|
+
* - Process-wide semaphore. Default cap: `2` concurrent `Bun.build` per
|
|
17
|
+
* process. Tunable via `MANDU_BUN_BUILD_CONCURRENCY` (positive integer).
|
|
18
|
+
* - FIFO queue — no priority, no cancellation. Callers get `Bun.build`'s
|
|
19
|
+
* `BuildOutput` result (or exception) transparently.
|
|
20
|
+
* - In-process only. Cross-worker coordination is not this module's job;
|
|
21
|
+
* per-worker throttling already prevents the observed failure modes in
|
|
22
|
+
* our test matrix.
|
|
23
|
+
*
|
|
24
|
+
* Correctness — slot handoff:
|
|
25
|
+
* - The semaphore does slot *handoff* rather than release-then-acquire. When
|
|
26
|
+
* a build completes with waiters queued, the slot is transferred directly
|
|
27
|
+
* to the next waiter (active count never drops). A previous revision had
|
|
28
|
+
* a classic acquire race: `releaseSlot()` decremented `active` before the
|
|
29
|
+
* waiter's `active++` ran, which opened a microtask-sized window where a
|
|
30
|
+
* concurrent `safeBuild()` call could observe `active < max`, skip the
|
|
31
|
+
* wait, and join in — yielding `cap+1` concurrent builds.
|
|
32
|
+
*/
|
|
33
|
+
|
|
34
|
+
import type { BuildConfig, BuildOutput } from "bun";
|
|
35
|
+
|
|
36
|
+
const DEFAULT_MAX_CONCURRENT = 2;
|
|
37
|
+
|
|
38
|
+
function parseMaxConcurrent(): number {
|
|
39
|
+
const raw = process.env.MANDU_BUN_BUILD_CONCURRENCY;
|
|
40
|
+
if (!raw) return DEFAULT_MAX_CONCURRENT;
|
|
41
|
+
const parsed = Number.parseInt(raw, 10);
|
|
42
|
+
if (!Number.isFinite(parsed) || parsed < 1) return DEFAULT_MAX_CONCURRENT;
|
|
43
|
+
return parsed;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const maxConcurrent = parseMaxConcurrent();
|
|
47
|
+
let active = 0;
|
|
48
|
+
const waiters: Array<() => void> = [];
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Acquire a slot. When `active < max`, increment synchronously and return.
|
|
52
|
+
* Otherwise, queue and await a direct handoff from a completing build —
|
|
53
|
+
* the completing build does NOT decrement `active`; it resolves our waiter,
|
|
54
|
+
* and `active` stays at `max` through the transition. This prevents a
|
|
55
|
+
* microtask-window race where a third caller could see `active < max` and
|
|
56
|
+
* skip the wait entirely.
|
|
57
|
+
*/
|
|
58
|
+
function acquireSlot(): Promise<void> {
|
|
59
|
+
if (active < maxConcurrent) {
|
|
60
|
+
active++;
|
|
61
|
+
return Promise.resolve();
|
|
62
|
+
}
|
|
63
|
+
return new Promise<void>((resolve) => {
|
|
64
|
+
waiters.push(resolve);
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Release a slot. If a waiter is queued, hand the slot off directly (keep
|
|
70
|
+
* `active` at `max`, resolve the waiter). Otherwise decrement `active`.
|
|
71
|
+
*/
|
|
72
|
+
function releaseSlot(): void {
|
|
73
|
+
const next = waiters.shift();
|
|
74
|
+
if (next) {
|
|
75
|
+
// Direct handoff — `active` stays at max, waiter resumes holding the slot.
|
|
76
|
+
next();
|
|
77
|
+
} else {
|
|
78
|
+
active--;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Runs `Bun.build(options)` subject to a process-wide concurrency cap.
|
|
84
|
+
* Preserves the exact return type and error semantics of `Bun.build`.
|
|
85
|
+
*
|
|
86
|
+
* Note: this wrapper only caps concurrency *within* a single process. Test
|
|
87
|
+
* harnesses that spawn multiple worker processes still see each worker run
|
|
88
|
+
* up to `maxConcurrent` concurrent builds — see Phase 0.6 for cross-process
|
|
89
|
+
* coordination work.
|
|
90
|
+
*/
|
|
91
|
+
export async function safeBuild(options: BuildConfig): Promise<BuildOutput> {
|
|
92
|
+
await acquireSlot();
|
|
93
|
+
try {
|
|
94
|
+
return await Bun.build(options);
|
|
95
|
+
} finally {
|
|
96
|
+
releaseSlot();
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/** Exposed for tests — not part of the public API. */
|
|
101
|
+
export function _getConcurrencyState() {
|
|
102
|
+
return { active, queued: waiters.length, max: maxConcurrent };
|
|
103
|
+
}
|