@mandujs/core 0.54.32 → 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 +127 -211
- 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
package/src/bundler/css.ts
CHANGED
|
@@ -15,41 +15,62 @@
|
|
|
15
15
|
import { spawn } from "bun";
|
|
16
16
|
import path from "path";
|
|
17
17
|
import fs from "fs/promises";
|
|
18
|
-
import { watch as fsWatch, type FSWatcher } from "fs";
|
|
18
|
+
import { existsSync, watch as fsWatch, type FSWatcher } from "fs";
|
|
19
19
|
import { withPerf } from "../perf";
|
|
20
20
|
|
|
21
|
-
/**
|
|
22
|
-
* Tailwind CLI 실행 명령어를 결정한다.
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
* `
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
21
|
+
/**
|
|
22
|
+
* Tailwind CLI 실행 명령어를 결정한다. 프로젝트에 설치된 CLI 엔트리가
|
|
23
|
+
* 있으면 직접 실행해 `bun x`의 네트워크 조회와 전역 캐시 잠금을 피한다.
|
|
24
|
+
* 로컬 엔트리가 없을 때만 `bun x`로 fallback한다.
|
|
25
|
+
* Windows에서 Bun.spawn은 PATH 기반 명령어 해석이 불안정하므로 (#152)
|
|
26
|
+
* `bun run mandu` 환경에서는 process.execPath (bun 절대 경로)를 사용한다.
|
|
27
|
+
* Standalone Mandu binary에서는 process.execPath가 mandu.exe를 가리키므로
|
|
28
|
+
* `mandu x @tailwindcss/cli`로 오해석된다. 이 경우 PATH에서 Bun을 찾는다.
|
|
29
|
+
*/
|
|
30
|
+
function isBunExecutable(executablePath: string | undefined): boolean {
|
|
31
|
+
if (!executablePath) return false;
|
|
32
|
+
// `path.basename()` only understands the current host separator. Tests,
|
|
33
|
+
// wrappers, and cross-compiled binaries can still hand us a Windows path on
|
|
34
|
+
// POSIX (or vice versa), so normalize both separators before inspecting it.
|
|
35
|
+
const base = path.posix.basename(executablePath.replace(/\\/g, "/")).toLowerCase();
|
|
36
|
+
return base === "bun" || base === "bun.exe";
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
type WhichExecutable = (command: string) => string | null | undefined;
|
|
40
|
+
|
|
41
|
+
function resolveBunExecutable(
|
|
42
|
+
execPath = process.execPath,
|
|
43
|
+
which: WhichExecutable = (command) => Bun.which(command),
|
|
44
|
+
): string {
|
|
45
|
+
if (isBunExecutable(execPath)) return execPath;
|
|
46
|
+
const fromPath = which("bun");
|
|
47
|
+
if (fromPath) return fromPath;
|
|
48
|
+
return process.platform === "win32" ? "bun.exe" : "bun";
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function getTailwindCommand(
|
|
52
|
+
args: string[],
|
|
53
|
+
execPath = process.execPath,
|
|
54
|
+
which?: WhichExecutable,
|
|
55
|
+
rootDir?: string,
|
|
56
|
+
fileExists: (candidate: string) => boolean = existsSync,
|
|
57
|
+
): string[] {
|
|
58
|
+
const bunExecutable = resolveBunExecutable(execPath, which);
|
|
59
|
+
if (rootDir && args[0] === "@tailwindcss/cli") {
|
|
60
|
+
const localEntry = path.join(
|
|
61
|
+
rootDir,
|
|
62
|
+
"node_modules",
|
|
63
|
+
"@tailwindcss",
|
|
64
|
+
"cli",
|
|
65
|
+
"dist",
|
|
66
|
+
"index.mjs",
|
|
67
|
+
);
|
|
68
|
+
if (fileExists(localEntry)) {
|
|
69
|
+
return [bunExecutable, localEntry, ...args.slice(1)];
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return [bunExecutable, "x", ...args];
|
|
73
|
+
}
|
|
53
74
|
|
|
54
75
|
// ========== Types ==========
|
|
55
76
|
|
|
@@ -144,7 +165,7 @@ async function runCSSBuild(
|
|
|
144
165
|
if (minify) args.push("--minify");
|
|
145
166
|
|
|
146
167
|
try {
|
|
147
|
-
const proc = spawn(getTailwindCommand(args), {
|
|
168
|
+
const proc = spawn(getTailwindCommand(args, process.execPath, undefined, rootDir), {
|
|
148
169
|
cwd: rootDir,
|
|
149
170
|
stdout: "pipe",
|
|
150
171
|
stderr: "pipe",
|
|
@@ -344,13 +365,13 @@ export function getCSSServerPath(): string {
|
|
|
344
365
|
/**
|
|
345
366
|
* CSS 링크 태그 생성
|
|
346
367
|
*/
|
|
347
|
-
export function generateCSSLinkTag(isDev: boolean = false): string {
|
|
348
|
-
const cacheBust = isDev ? `?t=${Date.now()}` : "";
|
|
349
|
-
return `<link rel="stylesheet" href="${SERVER_CSS_PATH}${cacheBust}">`;
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
export const __private = {
|
|
353
|
-
getTailwindCommand,
|
|
354
|
-
isBunExecutable,
|
|
355
|
-
resolveBunExecutable,
|
|
356
|
-
};
|
|
368
|
+
export function generateCSSLinkTag(isDev: boolean = false): string {
|
|
369
|
+
const cacheBust = isDev ? `?t=${Date.now()}` : "";
|
|
370
|
+
return `<link rel="stylesheet" href="${SERVER_CSS_PATH}${cacheBust}">`;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
export const __private = {
|
|
374
|
+
getTailwindCommand,
|
|
375
|
+
isBunExecutable,
|
|
376
|
+
resolveBunExecutable,
|
|
377
|
+
};
|
package/src/bundler/dev.ts
CHANGED
|
@@ -6,7 +6,7 @@ import type * as __ManduContentCollectionTypes0 from "../content/collection";
|
|
|
6
6
|
|
|
7
7
|
import type { RoutesManifest } from "../spec/schema";
|
|
8
8
|
import { buildClientBundles } from "./build";
|
|
9
|
-
import type { BundleResult } from "./types";
|
|
9
|
+
import type { BundleManifest, BundleResult } from "./types";
|
|
10
10
|
import { PORTS, TIMEOUTS } from "../constants";
|
|
11
11
|
import { mark, measure, withPerf } from "../perf";
|
|
12
12
|
import { HMR_PERF } from "../perf/hmr-markers";
|
|
@@ -21,13 +21,13 @@ import {
|
|
|
21
21
|
scanFileImports,
|
|
22
22
|
DEFAULT_MAX_CLOSURE_DEPTH,
|
|
23
23
|
} from "./reverse-import-graph";
|
|
24
|
-
import path from "path";
|
|
25
|
-
import fs from "fs";
|
|
26
|
-
import { LRUCache } from "../utils/lru-cache";
|
|
27
|
-
import { registerCacheSize, unregisterCacheSize } from "../observability/metrics";
|
|
28
|
-
export { generateFastRefreshPreamble } from "./fast-refresh-preamble";
|
|
29
|
-
|
|
30
|
-
/**
|
|
24
|
+
import path from "path";
|
|
25
|
+
import fs from "fs";
|
|
26
|
+
import { LRUCache } from "../utils/lru-cache";
|
|
27
|
+
import { registerCacheSize, unregisterCacheSize } from "../observability/metrics";
|
|
28
|
+
export { generateFastRefreshPreamble } from "./fast-refresh-preamble";
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
31
|
* #184: 공통 디렉토리 변경 시 사용하는 sentinel.
|
|
32
32
|
* `onSSRChange`에 특정 파일 경로 대신 이 상수를 전달하면 "전체 SSR 레지스트리 invalidate" 의미.
|
|
33
33
|
*/
|
|
@@ -137,12 +137,21 @@ export interface RebuildResult {
|
|
|
137
137
|
}
|
|
138
138
|
|
|
139
139
|
export interface DevBundler {
|
|
140
|
-
/** 초기 빌드 결과 */
|
|
141
|
-
initialBuild: BundleResult;
|
|
142
|
-
/** Reverse import graph initial seed completion for deterministic tests. */
|
|
143
|
-
reverseGraphReady: Promise<void>;
|
|
144
|
-
/** 파일 감시 중지 */
|
|
145
|
-
close: () => void;
|
|
140
|
+
/** 초기 빌드 결과 */
|
|
141
|
+
initialBuild: BundleResult;
|
|
142
|
+
/** Reverse import graph initial seed completion for deterministic tests. */
|
|
143
|
+
reverseGraphReady: Promise<void>;
|
|
144
|
+
/** 파일 감시 중지 */
|
|
145
|
+
close: () => void;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
function replaceBundleManifest(
|
|
149
|
+
target: BundleManifest,
|
|
150
|
+
source: BundleManifest,
|
|
151
|
+
): void {
|
|
152
|
+
const mutable = target as unknown as Record<string, unknown>;
|
|
153
|
+
for (const key of Object.keys(mutable)) delete mutable[key];
|
|
154
|
+
Object.assign(mutable, source);
|
|
146
155
|
}
|
|
147
156
|
|
|
148
157
|
/**
|
|
@@ -420,11 +429,16 @@ export async function startDevBundler(options: DevBundlerOptions): Promise<DevBu
|
|
|
420
429
|
reactCompiler,
|
|
421
430
|
});
|
|
422
431
|
|
|
423
|
-
if (initialBuild.success) {
|
|
424
|
-
console.log(`✅ Built ${initialBuild.stats.bundleCount} islands`);
|
|
425
|
-
} else {
|
|
426
|
-
console.error("⚠️ Initial build had errors:", initialBuild.errors);
|
|
427
|
-
|
|
432
|
+
if (initialBuild.success) {
|
|
433
|
+
console.log(`✅ Built ${initialBuild.stats.bundleCount} islands`);
|
|
434
|
+
} else {
|
|
435
|
+
console.error("⚠️ Initial build had errors:", initialBuild.errors);
|
|
436
|
+
onError?.(
|
|
437
|
+
new Error(
|
|
438
|
+
`Initial client bundle build failed:\n${initialBuild.errors.join("\n")}`,
|
|
439
|
+
),
|
|
440
|
+
);
|
|
441
|
+
}
|
|
428
442
|
|
|
429
443
|
// clientModule 경로에서 routeId 매핑 생성
|
|
430
444
|
const clientModuleToRoute = new Map<string, string>();
|
|
@@ -650,8 +664,8 @@ export async function startDevBundler(options: DevBundlerOptions): Promise<DevBu
|
|
|
650
664
|
// surface typed-only stubs that have no source yet); misses simply
|
|
651
665
|
// keep the legacy "silent drop" behavior so no project is made
|
|
652
666
|
// worse by turning this on.
|
|
653
|
-
const reverseGraph = new ReverseImportGraph();
|
|
654
|
-
let reverseGraphSeedPromise: Promise<void> | null = null;
|
|
667
|
+
const reverseGraph = new ReverseImportGraph();
|
|
668
|
+
let reverseGraphSeedPromise: Promise<void> | null = null;
|
|
655
669
|
|
|
656
670
|
/**
|
|
657
671
|
* Re-scan a single file's imports and update its row in the
|
|
@@ -1243,15 +1257,15 @@ export async function startDevBundler(options: DevBundlerOptions): Promise<DevBu
|
|
|
1243
1257
|
* stay silent. Dispatch is idempotent — each root is touched at
|
|
1244
1258
|
* most once per change via the `dispatched` set.
|
|
1245
1259
|
*/
|
|
1246
|
-
const dispatchByTransitiveImporters = async (
|
|
1247
|
-
changedFile: string,
|
|
1248
|
-
): Promise<number> => {
|
|
1249
|
-
const absChanged = path.resolve(rootDir, changedFile);
|
|
1250
|
-
if (reverseGraphSeedPromise) {
|
|
1251
|
-
await reverseGraphSeedPromise;
|
|
1252
|
-
}
|
|
1253
|
-
|
|
1254
|
-
// Refresh the changed file's OWN imports first. A leaf edit can
|
|
1260
|
+
const dispatchByTransitiveImporters = async (
|
|
1261
|
+
changedFile: string,
|
|
1262
|
+
): Promise<number> => {
|
|
1263
|
+
const absChanged = path.resolve(rootDir, changedFile);
|
|
1264
|
+
if (reverseGraphSeedPromise) {
|
|
1265
|
+
await reverseGraphSeedPromise;
|
|
1266
|
+
}
|
|
1267
|
+
|
|
1268
|
+
// Refresh the changed file's OWN imports first. A leaf edit can
|
|
1255
1269
|
// legitimately add or remove imports (e.g. switching a barrel
|
|
1256
1270
|
// from `./en` to `./ko`); the reverse graph must track that so
|
|
1257
1271
|
// the NEXT unknown-file change uses the correct set.
|
|
@@ -1338,8 +1352,9 @@ export async function startDevBundler(options: DevBundlerOptions): Promise<DevBu
|
|
|
1338
1352
|
reactCompiler,
|
|
1339
1353
|
});
|
|
1340
1354
|
const buildTime = performance.now() - startTime;
|
|
1341
|
-
if (result.success) {
|
|
1342
|
-
|
|
1355
|
+
if (result.success) {
|
|
1356
|
+
replaceBundleManifest(initialBuild.manifest, result.manifest);
|
|
1357
|
+
console.log(
|
|
1343
1358
|
`✅ Rebuilt ${targetIds.length} island(s) in ${buildTime.toFixed(0)}ms`,
|
|
1344
1359
|
);
|
|
1345
1360
|
for (const targetId of targetIds) {
|
|
@@ -1399,8 +1414,9 @@ export async function startDevBundler(options: DevBundlerOptions): Promise<DevBu
|
|
|
1399
1414
|
|
|
1400
1415
|
const buildTime = performance.now() - startTime;
|
|
1401
1416
|
|
|
1402
|
-
if (result.success) {
|
|
1403
|
-
|
|
1417
|
+
if (result.success) {
|
|
1418
|
+
replaceBundleManifest(initialBuild.manifest, result.manifest);
|
|
1419
|
+
// #184: common dir 변경은 SSR 모듈 캐시 invalidation이 필요 — wildcard 시그널
|
|
1404
1420
|
// 빌드 성공한 경우에만 SSR 레지스트리를 clear (실패 시 마지막 good state 유지)
|
|
1405
1421
|
// 주의: Bun의 transitive ESM 캐시는 프로세스 레벨이라 이 시그널만으로는
|
|
1406
1422
|
// `src/shared/**`을 transitive하게 import하는 SSR 모듈까지 완전히 갱신되지 않음.
|
|
@@ -1525,8 +1541,9 @@ export async function startDevBundler(options: DevBundlerOptions): Promise<DevBu
|
|
|
1525
1541
|
|
|
1526
1542
|
const buildTime = performance.now() - startTime;
|
|
1527
1543
|
|
|
1528
|
-
if (result.success) {
|
|
1529
|
-
|
|
1544
|
+
if (result.success) {
|
|
1545
|
+
replaceBundleManifest(initialBuild.manifest, result.manifest);
|
|
1546
|
+
console.log(`✅ Rebuilt in ${buildTime.toFixed(0)}ms`);
|
|
1530
1547
|
onRebuild?.({
|
|
1531
1548
|
routeId,
|
|
1532
1549
|
success: true,
|
|
@@ -1663,17 +1680,17 @@ export async function startDevBundler(options: DevBundlerOptions): Promise<DevBu
|
|
|
1663
1680
|
// and the first user edit can't race the seed (first event goes
|
|
1664
1681
|
// through the 100 ms debounce, by which point the scan has finished
|
|
1665
1682
|
// for any realistic project size).
|
|
1666
|
-
reverseGraphSeedPromise = seedReverseGraph().catch((err) => {
|
|
1667
|
-
console.warn(
|
|
1668
|
-
"[Mandu HMR] reverse import-graph seed skipped:",
|
|
1669
|
-
err instanceof Error ? err.message : String(err),
|
|
1670
|
-
);
|
|
1671
|
-
});
|
|
1672
|
-
|
|
1673
|
-
return {
|
|
1674
|
-
initialBuild,
|
|
1675
|
-
reverseGraphReady: reverseGraphSeedPromise,
|
|
1676
|
-
close: () => {
|
|
1683
|
+
reverseGraphSeedPromise = seedReverseGraph().catch((err) => {
|
|
1684
|
+
console.warn(
|
|
1685
|
+
"[Mandu HMR] reverse import-graph seed skipped:",
|
|
1686
|
+
err instanceof Error ? err.message : String(err),
|
|
1687
|
+
);
|
|
1688
|
+
});
|
|
1689
|
+
|
|
1690
|
+
return {
|
|
1691
|
+
initialBuild,
|
|
1692
|
+
reverseGraphReady: reverseGraphSeedPromise,
|
|
1693
|
+
close: () => {
|
|
1677
1694
|
// B6: clear all per-file timers to release event-loop refs.
|
|
1678
1695
|
// Phase 17 — `LRUCache.clear()` fires the registered `onEvict`
|
|
1679
1696
|
// (`clearTimeout(timer)`) for every entry before dropping them,
|
|
@@ -1738,9 +1755,12 @@ export interface HMRMessage {
|
|
|
1738
1755
|
data?: {
|
|
1739
1756
|
routeId?: string;
|
|
1740
1757
|
layoutPath?: string;
|
|
1741
|
-
cssPath?: string;
|
|
1742
|
-
message?: string;
|
|
1743
|
-
|
|
1758
|
+
cssPath?: string;
|
|
1759
|
+
message?: string;
|
|
1760
|
+
name?: string;
|
|
1761
|
+
stack?: string;
|
|
1762
|
+
kind?: "build" | "guard" | "css" | "prebuild";
|
|
1763
|
+
timestamp?: number;
|
|
1744
1764
|
file?: string;
|
|
1745
1765
|
violations?: Array<{ line: number; message: string }>;
|
|
1746
1766
|
changeType?: "add" | "change" | "delete";
|
|
@@ -1820,8 +1840,16 @@ export function createHMRServer(
|
|
|
1820
1840
|
//
|
|
1821
1841
|
// Monotonic counter; resets to 0 on server boot (restart is a full
|
|
1822
1842
|
// reload anyway so clients can't meaningfully resume across it).
|
|
1823
|
-
let lastRebuildId = 0;
|
|
1824
|
-
const replayBuffer: HMRReplayEnvelope[] = [];
|
|
1843
|
+
let lastRebuildId = 0;
|
|
1844
|
+
const replayBuffer: HMRReplayEnvelope[] = [];
|
|
1845
|
+
let latestBuildError: HMRMessage | null = null;
|
|
1846
|
+
|
|
1847
|
+
const sendConnected = (ws: { send: (data: string) => void }): void => {
|
|
1848
|
+
ws.send(
|
|
1849
|
+
JSON.stringify({ type: "connected", data: { timestamp: Date.now(), id: lastRebuildId } }),
|
|
1850
|
+
);
|
|
1851
|
+
if (latestBuildError) ws.send(JSON.stringify(latestBuildError));
|
|
1852
|
+
};
|
|
1825
1853
|
|
|
1826
1854
|
/** Drop envelopes older than `REPLAY_MAX_AGE_MS`. Called opportunistically. */
|
|
1827
1855
|
const pruneOldReplays = (): void => {
|
|
@@ -1887,18 +1915,14 @@ export function createHMRServer(
|
|
|
1887
1915
|
ws: { send: (data: string) => void },
|
|
1888
1916
|
since: number | null,
|
|
1889
1917
|
): void => {
|
|
1890
|
-
if (since === null) {
|
|
1891
|
-
ws
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
return;
|
|
1895
|
-
}
|
|
1918
|
+
if (since === null) {
|
|
1919
|
+
sendConnected(ws);
|
|
1920
|
+
return;
|
|
1921
|
+
}
|
|
1896
1922
|
// Already caught up — nothing to replay but still greet.
|
|
1897
|
-
if (since >= lastRebuildId) {
|
|
1898
|
-
ws
|
|
1899
|
-
|
|
1900
|
-
);
|
|
1901
|
-
return;
|
|
1923
|
+
if (since >= lastRebuildId) {
|
|
1924
|
+
sendConnected(ws);
|
|
1925
|
+
return;
|
|
1902
1926
|
}
|
|
1903
1927
|
pruneOldReplays();
|
|
1904
1928
|
const oldestId = replayBuffer.length > 0 ? replayBuffer[0]!.id : null;
|
|
@@ -1916,9 +1940,7 @@ export function createHMRServer(
|
|
|
1916
1940
|
}
|
|
1917
1941
|
// Replay every envelope strictly newer than `since`.
|
|
1918
1942
|
mark(HMR_PERF.HMR_REPLAY_FLUSH);
|
|
1919
|
-
ws
|
|
1920
|
-
JSON.stringify({ type: "connected", data: { timestamp: Date.now(), id: lastRebuildId } }),
|
|
1921
|
-
);
|
|
1943
|
+
sendConnected(ws);
|
|
1922
1944
|
for (const env of replayBuffer) {
|
|
1923
1945
|
if (env.id <= since) continue;
|
|
1924
1946
|
// Wrap in a thin envelope so the client can see the id; keep the
|
|
@@ -2171,11 +2193,21 @@ export function createHMRServer(
|
|
|
2171
2193
|
envelopeId = envelope.id;
|
|
2172
2194
|
}
|
|
2173
2195
|
|
|
2174
|
-
const outgoing: HMRMessage =
|
|
2175
|
-
envelopeId !== undefined
|
|
2176
|
-
? { ...message, data: { ...(message.data ?? {}), id: envelopeId } }
|
|
2177
|
-
: message;
|
|
2178
|
-
|
|
2196
|
+
const outgoing: HMRMessage =
|
|
2197
|
+
envelopeId !== undefined
|
|
2198
|
+
? { ...message, data: { ...(message.data ?? {}), id: envelopeId } }
|
|
2199
|
+
: message;
|
|
2200
|
+
if (outgoing.type === "error") {
|
|
2201
|
+
latestBuildError = outgoing;
|
|
2202
|
+
} else if (
|
|
2203
|
+
outgoing.type === "reload" ||
|
|
2204
|
+
outgoing.type === "full-reload" ||
|
|
2205
|
+
outgoing.type === "island-update" ||
|
|
2206
|
+
outgoing.type === "layout-update"
|
|
2207
|
+
) {
|
|
2208
|
+
latestBuildError = null;
|
|
2209
|
+
}
|
|
2210
|
+
const payload = JSON.stringify(outgoing);
|
|
2179
2211
|
fanout(payload);
|
|
2180
2212
|
measure(HMR_PERF.HMR_BROADCAST, HMR_PERF.HMR_BROADCAST);
|
|
2181
2213
|
},
|
|
@@ -2217,8 +2249,8 @@ export function createHMRServer(
|
|
|
2217
2249
|
};
|
|
2218
2250
|
}
|
|
2219
2251
|
|
|
2220
|
-
/**
|
|
2221
|
-
* HMR 클라이언트 스크립트 생성
|
|
2252
|
+
/**
|
|
2253
|
+
* HMR 클라이언트 스크립트 생성
|
|
2222
2254
|
* 브라우저에서 실행되어 HMR 서버와 연결.
|
|
2223
2255
|
*
|
|
2224
2256
|
* Phase 7.0 R1 Agent C additions:
|
|
@@ -1,47 +1,47 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Small runtime-safe Fast Refresh preamble helper.
|
|
3
|
-
*
|
|
4
|
-
* Keep this separate from `bundler/dev.ts`: SSR runtimes import the helper
|
|
5
|
-
* while edge bundles must not pull the dev bundler, build graph, or TypeScript
|
|
6
|
-
* compiler into production worker output.
|
|
7
|
-
*/
|
|
8
|
-
export function generateFastRefreshPreamble(
|
|
9
|
-
glueUrl: string,
|
|
10
|
-
runtimeUrl: string,
|
|
11
|
-
): string {
|
|
12
|
-
// Both URLs must be non-empty. If either is missing (e.g. vendor
|
|
13
|
-
// shim build failed), the caller should skip this preamble entirely.
|
|
14
|
-
if (!glueUrl || !runtimeUrl) {
|
|
15
|
-
return `<script>/* Mandu Fast Refresh: missing runtime assets, preamble skipped */</script>`;
|
|
16
|
-
}
|
|
17
|
-
// JSON.stringify escapes the URLs safely for inline `<script>`:
|
|
18
|
-
// - quotes produce a valid JS string literal
|
|
19
|
-
// - forward-slashes / backslashes are handled
|
|
20
|
-
// We also `split('</')` to avoid a stray `</script>` sequence in the
|
|
21
|
-
// URL bytes breaking the enclosing tag. This is the same defense
|
|
22
|
-
// Vite uses in its own preamble emitter.
|
|
23
|
-
const glueLit = JSON.stringify(glueUrl).split("</").join('<"+"/');
|
|
24
|
-
const runtimeLit = JSON.stringify(runtimeUrl).split("</").join('<"+"/');
|
|
25
|
-
return `<script>
|
|
26
|
-
// Phase 7.1 B-3 React Fast Refresh preamble (Mandu dev-only)
|
|
27
|
-
(function () {
|
|
28
|
-
if (typeof window === "undefined") return;
|
|
29
|
-
// Install inert stubs so transformed modules that run BEFORE the
|
|
30
|
-
// async runtime upgrade don't hit ReferenceError on $RefreshReg$.
|
|
31
|
-
if (!window.$RefreshReg$) window.$RefreshReg$ = function () {};
|
|
32
|
-
if (!window.$RefreshSig$) window.$RefreshSig$ = function () { return function (t) { return t; }; };
|
|
33
|
-
// Async-load the glue; failures are reported but never throw out of
|
|
34
|
-
// the preamble — a missing runtime degrades to full-reload HMR.
|
|
35
|
-
import(${glueLit})
|
|
36
|
-
.then(function (mod) {
|
|
37
|
-
var runtimeImport = function () { return import(${runtimeLit}); };
|
|
38
|
-
if (mod && typeof mod.installGlobal === "function") {
|
|
39
|
-
return mod.installGlobal({ runtimeImport: runtimeImport });
|
|
40
|
-
}
|
|
41
|
-
})
|
|
42
|
-
.catch(function (err) {
|
|
43
|
-
console.error("[Mandu Fast Refresh] preamble failed:", err);
|
|
44
|
-
});
|
|
45
|
-
})();
|
|
46
|
-
</script>`;
|
|
47
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Small runtime-safe Fast Refresh preamble helper.
|
|
3
|
+
*
|
|
4
|
+
* Keep this separate from `bundler/dev.ts`: SSR runtimes import the helper
|
|
5
|
+
* while edge bundles must not pull the dev bundler, build graph, or TypeScript
|
|
6
|
+
* compiler into production worker output.
|
|
7
|
+
*/
|
|
8
|
+
export function generateFastRefreshPreamble(
|
|
9
|
+
glueUrl: string,
|
|
10
|
+
runtimeUrl: string,
|
|
11
|
+
): string {
|
|
12
|
+
// Both URLs must be non-empty. If either is missing (e.g. vendor
|
|
13
|
+
// shim build failed), the caller should skip this preamble entirely.
|
|
14
|
+
if (!glueUrl || !runtimeUrl) {
|
|
15
|
+
return `<script>/* Mandu Fast Refresh: missing runtime assets, preamble skipped */</script>`;
|
|
16
|
+
}
|
|
17
|
+
// JSON.stringify escapes the URLs safely for inline `<script>`:
|
|
18
|
+
// - quotes produce a valid JS string literal
|
|
19
|
+
// - forward-slashes / backslashes are handled
|
|
20
|
+
// We also `split('</')` to avoid a stray `</script>` sequence in the
|
|
21
|
+
// URL bytes breaking the enclosing tag. This is the same defense
|
|
22
|
+
// Vite uses in its own preamble emitter.
|
|
23
|
+
const glueLit = JSON.stringify(glueUrl).split("</").join('<"+"/');
|
|
24
|
+
const runtimeLit = JSON.stringify(runtimeUrl).split("</").join('<"+"/');
|
|
25
|
+
return `<script>
|
|
26
|
+
// Phase 7.1 B-3 React Fast Refresh preamble (Mandu dev-only)
|
|
27
|
+
(function () {
|
|
28
|
+
if (typeof window === "undefined") return;
|
|
29
|
+
// Install inert stubs so transformed modules that run BEFORE the
|
|
30
|
+
// async runtime upgrade don't hit ReferenceError on $RefreshReg$.
|
|
31
|
+
if (!window.$RefreshReg$) window.$RefreshReg$ = function () {};
|
|
32
|
+
if (!window.$RefreshSig$) window.$RefreshSig$ = function () { return function (t) { return t; }; };
|
|
33
|
+
// Async-load the glue; failures are reported but never throw out of
|
|
34
|
+
// the preamble — a missing runtime degrades to full-reload HMR.
|
|
35
|
+
import(${glueLit})
|
|
36
|
+
.then(function (mod) {
|
|
37
|
+
var runtimeImport = function () { return import(${runtimeLit}); };
|
|
38
|
+
if (mod && typeof mod.installGlobal === "function") {
|
|
39
|
+
return mod.installGlobal({ runtimeImport: runtimeImport });
|
|
40
|
+
}
|
|
41
|
+
})
|
|
42
|
+
.catch(function (err) {
|
|
43
|
+
console.error("[Mandu Fast Refresh] preamble failed:", err);
|
|
44
|
+
});
|
|
45
|
+
})();
|
|
46
|
+
</script>`;
|
|
47
|
+
}
|