@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
package/src/runtime/ssr.ts
CHANGED
|
@@ -772,10 +772,11 @@ export function renderToHTML(element: ReactElement, options: SSROptions = {}): s
|
|
|
772
772
|
? generateFastRefreshPreambleTag(isDev, bundleManifest, resolvedCspNonce)
|
|
773
773
|
: "";
|
|
774
774
|
|
|
775
|
-
// Issue #191 β DevTools λ²λ€ (~1.15 MB) μ£Όμ
κ²°μ .
|
|
776
|
-
// -
|
|
777
|
-
// - `devtools === true` β κ°μ μ£Όμ
(
|
|
778
|
-
// - `devtools === false` β κ°μ μ€ν΅ (
|
|
775
|
+
// Issue #191 + #259 β DevTools λ²λ€ (~1.15 MB) μ£Όμ
κ²°μ .
|
|
776
|
+
// - κΈ°λ³Έ (dev only): νμ μ£Όμ
. SSR-only λλ©μμλ Kitchen ν¨λ μ¬μ© κ°λ₯.
|
|
777
|
+
// - `devtools === true` β κ°μ μ£Όμ
(μλ―Έ λ³ν μμ)
|
|
778
|
+
// - `devtools === false` β κ°μ μ€ν΅ (νμ μ 1.15 MB μ μ½)
|
|
779
|
+
// νλ‘λμ
λΉλλ `isDev` κ°λλ‘ 0 bytes 보μ₯.
|
|
779
780
|
// Cache-bust μ `manifest.buildTime` μ°μ , μμΌλ©΄ `Date.now()`.
|
|
780
781
|
let devtoolsScript = "";
|
|
781
782
|
if (isDev && shouldInjectDevtools(devtools, bundleManifest)) {
|
|
@@ -1039,27 +1040,27 @@ window.__MANDU_HMR_PORT__ = ${hmrPort};
|
|
|
1039
1040
|
}
|
|
1040
1041
|
|
|
1041
1042
|
/**
|
|
1042
|
-
* Issue #191 β Determine whether the dev-only `_devtools.js`
|
|
1043
|
-
* (~1.15 MB React dev runtime + Kitchen panel) should be injected
|
|
1044
|
-
* into the HTML response.
|
|
1043
|
+
* Issue #191 + #259 β Determine whether the dev-only `_devtools.js`
|
|
1044
|
+
* bundle (~1.15 MB React dev runtime + Kitchen panel) should be injected
|
|
1045
|
+
* into the HTML response. The caller gates with `isDev`, so this only
|
|
1046
|
+
* affects dev-mode responses (prod always skips, regardless of the
|
|
1047
|
+
* decision below).
|
|
1045
1048
|
*
|
|
1046
1049
|
* Decision table (`devtools` option Γ manifest shape):
|
|
1047
1050
|
*
|
|
1048
|
-
* | `devtools` | hasIslands | inject? | rationale
|
|
1049
|
-
*
|
|
1050
|
-
* | `true` | any | YES | explicit opt-in
|
|
1051
|
-
* | `false` | any | NO | explicit opt-out
|
|
1052
|
-
* | `undefined` | true | YES | default, hydration runtime
|
|
1053
|
-
* | `undefined` | false |
|
|
1054
|
-
* | `undefined` | no manifest|
|
|
1051
|
+
* | `devtools` | hasIslands | inject? | rationale |
|
|
1052
|
+
* |-------------|------------|---------|------------------------------|
|
|
1053
|
+
* | `true` | any | YES | explicit opt-in |
|
|
1054
|
+
* | `false` | any | NO | explicit opt-out |
|
|
1055
|
+
* | `undefined` | true | YES | default, hydration runtime |
|
|
1056
|
+
* | `undefined` | false | YES | dev DX: Kitchen on SSR pages |
|
|
1057
|
+
* | `undefined` | no manifest| YES | dev DX: Kitchen pre-build |
|
|
1055
1058
|
*
|
|
1056
|
-
*
|
|
1057
|
-
*
|
|
1058
|
-
*
|
|
1059
|
-
*
|
|
1060
|
-
*
|
|
1061
|
-
* `needsHydration()` is true (build.ts:70 filter).
|
|
1062
|
-
* Either non-empty β some route on this server hydrates β devtools useful.
|
|
1059
|
+
* #259 reverted the original #191 default (skip when no islands): SSR-only
|
|
1060
|
+
* landing/marketing pages are the exact place where Kitchen network/error
|
|
1061
|
+
* panels are most needed, and the 1.15 MB cost only applies in dev β prod
|
|
1062
|
+
* builds never emit `_devtools.js`. Users who explicitly want the old
|
|
1063
|
+
* behavior on a per-app basis can still set `dev.devtools: false`.
|
|
1063
1064
|
*
|
|
1064
1065
|
* @internal Exported via `_testOnly_shouldInjectDevtools` below so
|
|
1065
1066
|
* `tests/runtime/devtools-inject.test.ts` can table-test the matrix
|
|
@@ -1067,19 +1068,11 @@ window.__MANDU_HMR_PORT__ = ${hmrPort};
|
|
|
1067
1068
|
*/
|
|
1068
1069
|
function shouldInjectDevtools(
|
|
1069
1070
|
devtools: boolean | undefined,
|
|
1070
|
-
|
|
1071
|
+
_manifest: BundleManifest | undefined,
|
|
1071
1072
|
): boolean {
|
|
1072
|
-
// Explicit overrides take absolute precedence.
|
|
1073
1073
|
if (devtools === true) return true;
|
|
1074
1074
|
if (devtools === false) return false;
|
|
1075
|
-
|
|
1076
|
-
// Default behavior: inject only when there is at least one island.
|
|
1077
|
-
if (!manifest) return false;
|
|
1078
|
-
const hasIslandsMap =
|
|
1079
|
-
manifest.islands && Object.keys(manifest.islands).length > 0;
|
|
1080
|
-
const hasBundles =
|
|
1081
|
-
manifest.bundles && Object.keys(manifest.bundles).length > 0;
|
|
1082
|
-
return Boolean(hasIslandsMap || hasBundles);
|
|
1075
|
+
return true;
|
|
1083
1076
|
}
|
|
1084
1077
|
|
|
1085
1078
|
/**
|
|
@@ -80,10 +80,10 @@ export interface StreamingError {
|
|
|
80
80
|
export interface StreamingMetrics {
|
|
81
81
|
/** Shell readyκΉμ§ κ±Έλ¦° μκ° (ms) */
|
|
82
82
|
shellReadyTime: number;
|
|
83
|
-
/** All readyκΉμ§ κ±Έλ¦° μκ° (ms) */
|
|
84
|
-
allReadyTime: number;
|
|
85
|
-
/** Deferred chunk κ°μ */
|
|
86
|
-
deferredChunkCount: number;
|
|
83
|
+
/** All readyκΉμ§ κ±Έλ¦° μκ° (ms) */
|
|
84
|
+
allReadyTime: number;
|
|
85
|
+
/** Deferred chunk κ°μ */
|
|
86
|
+
deferredChunkCount: number;
|
|
87
87
|
/** μλ¬ λ°μ μ¬λΆ */
|
|
88
88
|
hasError: boolean;
|
|
89
89
|
/** μμ μκ° */
|
|
@@ -202,7 +202,7 @@ export interface StreamingSSROptions {
|
|
|
202
202
|
}
|
|
203
203
|
|
|
204
204
|
/**
|
|
205
|
-
* Issue #191 β Streaming-SSR mirror of `ssr.ts:shouldInjectDevtools`.
|
|
205
|
+
* Issue #191 + #259 β Streaming-SSR mirror of `ssr.ts:shouldInjectDevtools`.
|
|
206
206
|
* Kept in sync manually (tiny pure function, not worth a cross-module
|
|
207
207
|
* runtime import β the ssr.ts β streaming-ssr.ts re-export direction
|
|
208
208
|
* means a circular import here would force a refactor of the whole
|
|
@@ -211,16 +211,11 @@ export interface StreamingSSROptions {
|
|
|
211
211
|
*/
|
|
212
212
|
function shouldInjectDevtoolsStreaming(
|
|
213
213
|
devtools: boolean | undefined,
|
|
214
|
-
|
|
214
|
+
_manifest: BundleManifest | undefined,
|
|
215
215
|
): boolean {
|
|
216
216
|
if (devtools === true) return true;
|
|
217
217
|
if (devtools === false) return false;
|
|
218
|
-
|
|
219
|
-
const hasIslandsMap =
|
|
220
|
-
manifest.islands && Object.keys(manifest.islands).length > 0;
|
|
221
|
-
const hasBundles =
|
|
222
|
-
manifest.bundles && Object.keys(manifest.bundles).length > 0;
|
|
223
|
-
return Boolean(hasIslandsMap || hasBundles);
|
|
218
|
+
return true;
|
|
224
219
|
}
|
|
225
220
|
|
|
226
221
|
/**
|
|
@@ -778,10 +773,10 @@ function generateHTMLTailContent(options: StreamingSSROptions): string {
|
|
|
778
773
|
scripts.push(generateHMRScript(hmrPort));
|
|
779
774
|
}
|
|
780
775
|
|
|
781
|
-
// 11. Issue #191 β DevTools λ²λ€ (~1.15 MB) μ£Όμ
κ²°μ .
|
|
782
|
-
// -
|
|
783
|
-
// - `devtools ===
|
|
784
|
-
// -
|
|
776
|
+
// 11. Issue #191 + #259 β DevTools λ²λ€ (~1.15 MB) μ£Όμ
κ²°μ .
|
|
777
|
+
// - κΈ°λ³Έ (dev only): νμ μ£Όμ
. SSR-only λλ©μμλ Kitchen μ¬μ© κ°λ₯.
|
|
778
|
+
// - `devtools === false` β κ°μ μ€ν΅ (νμ μ 1.15 MB μ μ½).
|
|
779
|
+
// - νλ‘λμ
λΉλλ `isDev` κ°λλ‘ 0 bytes 보μ₯.
|
|
785
780
|
// - Cache-bust (`?v=buildTime`) λ‘ HMR ν stale λ°©μ§.
|
|
786
781
|
if (isDev && shouldInjectDevtoolsStreaming(devtools, bundleManifest)) {
|
|
787
782
|
scripts.push(generateStreamingDevtoolsScript(bundleManifest));
|
|
@@ -1001,9 +996,9 @@ export async function renderToStream(
|
|
|
1001
996
|
|
|
1002
997
|
// λ©νΈλ¦ μμ§
|
|
1003
998
|
const metrics: StreamingMetrics = {
|
|
1004
|
-
shellReadyTime: 0,
|
|
1005
|
-
allReadyTime: 0,
|
|
1006
|
-
deferredChunkCount: 0,
|
|
999
|
+
shellReadyTime: 0,
|
|
1000
|
+
allReadyTime: 0,
|
|
1001
|
+
deferredChunkCount: 0,
|
|
1007
1002
|
hasError: false,
|
|
1008
1003
|
startTime: Date.now(),
|
|
1009
1004
|
};
|
|
@@ -1379,9 +1374,9 @@ export async function renderWithDeferredData(
|
|
|
1379
1374
|
const encoder = new TextEncoder();
|
|
1380
1375
|
const startTime = Date.now();
|
|
1381
1376
|
|
|
1382
|
-
// μ€λΉλ deferred μ€ν¬λ¦½νΈλ₯Ό λ΄μ λ°°μ΄ (mutable)
|
|
1383
|
-
const readyScripts: string[] = [];
|
|
1384
|
-
let allDeferredSettled = false;
|
|
1377
|
+
// μ€λΉλ deferred μ€ν¬λ¦½νΈλ₯Ό λ΄μ λ°°μ΄ (mutable)
|
|
1378
|
+
const readyScripts: string[] = [];
|
|
1379
|
+
let allDeferredSettled = false;
|
|
1385
1380
|
|
|
1386
1381
|
// 1. Deferred promises λ³λ ¬ μμ (λ§μ§ μμ!)
|
|
1387
1382
|
const deferredEntries = Object.entries(deferredPromises);
|
|
@@ -1395,11 +1390,11 @@ export async function renderWithDeferredData(
|
|
|
1395
1390
|
);
|
|
1396
1391
|
const data = await Promise.race([promise, timeoutPromise]);
|
|
1397
1392
|
|
|
1398
|
-
// μ€ν¬λ¦½νΈ μμ± λ° μΆκ°
|
|
1399
|
-
const script = generateDeferredDataScript(routeId, key, data);
|
|
1400
|
-
readyScripts.push(script);
|
|
1401
|
-
|
|
1402
|
-
if (isDev) {
|
|
1393
|
+
// μ€ν¬λ¦½νΈ μμ± λ° μΆκ°
|
|
1394
|
+
const script = generateDeferredDataScript(routeId, key, data);
|
|
1395
|
+
readyScripts.push(script);
|
|
1396
|
+
|
|
1397
|
+
if (isDev) {
|
|
1403
1398
|
console.log(`[Mandu Streaming] Deferred ready: ${key} (${Date.now() - startTime}ms)`);
|
|
1404
1399
|
}
|
|
1405
1400
|
} catch (error) {
|
|
@@ -1473,22 +1468,22 @@ export async function renderWithDeferredData(
|
|
|
1473
1468
|
|
|
1474
1469
|
// μ΅μ’
λ©νΈλ¦ λ³΄κ³ (injectedCountκ° μ€μ λ©νΈλ¦)
|
|
1475
1470
|
if (onMetrics && baseMetrics) {
|
|
1476
|
-
onMetrics({
|
|
1477
|
-
...baseMetrics,
|
|
1478
|
-
deferredChunkCount: injectedCount,
|
|
1479
|
-
allReadyTime: Date.now() - startTime,
|
|
1480
|
-
});
|
|
1471
|
+
onMetrics({
|
|
1472
|
+
...baseMetrics,
|
|
1473
|
+
deferredChunkCount: injectedCount,
|
|
1474
|
+
allReadyTime: Date.now() - startTime,
|
|
1475
|
+
});
|
|
1481
1476
|
}
|
|
1482
1477
|
|
|
1483
1478
|
controller.close();
|
|
1484
1479
|
} catch (error) {
|
|
1485
1480
|
controller.error(error);
|
|
1486
1481
|
}
|
|
1487
|
-
},
|
|
1488
|
-
cancel() {
|
|
1489
|
-
void reader.cancel();
|
|
1490
|
-
},
|
|
1491
|
-
});
|
|
1482
|
+
},
|
|
1483
|
+
cancel() {
|
|
1484
|
+
void reader.cancel();
|
|
1485
|
+
},
|
|
1486
|
+
});
|
|
1492
1487
|
|
|
1493
1488
|
// Phase 7.2 R1 Agent C (H1): if the base stream produced a CSP
|
|
1494
1489
|
// nonce during shell emission, forward the matching header on the
|
package/src/runtime/trace.ts
CHANGED
|
@@ -1,144 +1,144 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Mandu Trace π§
|
|
3
|
-
* Lifecycle λ¨κ³λ³ μΆμ (μ΅μ
)
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import type { ManduContext } from "../filling/context";
|
|
7
|
-
|
|
8
|
-
export type TraceEvent =
|
|
9
|
-
| "request"
|
|
10
|
-
| "parse"
|
|
11
|
-
| "transform"
|
|
12
|
-
| "beforeHandle"
|
|
13
|
-
| "handle"
|
|
14
|
-
| "afterHandle"
|
|
15
|
-
| "mapResponse"
|
|
16
|
-
| "afterResponse"
|
|
17
|
-
| "error";
|
|
18
|
-
|
|
19
|
-
export type TracePhase = "begin" | "end" | "error";
|
|
20
|
-
|
|
21
|
-
export interface TraceEntry {
|
|
22
|
-
event: TraceEvent;
|
|
23
|
-
phase: TracePhase;
|
|
24
|
-
time: number;
|
|
25
|
-
name?: string;
|
|
26
|
-
error?: string;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export interface TraceCollector {
|
|
30
|
-
records: TraceEntry[];
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export interface TraceReportEntry {
|
|
34
|
-
event: TraceEvent;
|
|
35
|
-
name?: string;
|
|
36
|
-
start: number;
|
|
37
|
-
end: number;
|
|
38
|
-
duration: number;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
export interface TraceReport {
|
|
42
|
-
entries: TraceReportEntry[];
|
|
43
|
-
errors: TraceEntry[];
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
export const TRACE_KEY = "__mandu_trace";
|
|
47
|
-
|
|
48
|
-
const now = (): number => {
|
|
49
|
-
if (typeof performance !== "undefined" && typeof performance.now === "function") {
|
|
50
|
-
return performance.now();
|
|
51
|
-
}
|
|
52
|
-
return Date.now();
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
export function enableTrace(ctx: ManduContext): TraceCollector {
|
|
56
|
-
const existing = ctx.get<TraceCollector>(TRACE_KEY);
|
|
57
|
-
if (existing) return existing;
|
|
58
|
-
const collector: TraceCollector = { records: [] };
|
|
59
|
-
ctx.set(TRACE_KEY, collector);
|
|
60
|
-
return collector;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
export function getTrace(ctx: ManduContext): TraceCollector | undefined {
|
|
64
|
-
return ctx.get<TraceCollector>(TRACE_KEY);
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* Build a normalized trace report with durations
|
|
69
|
-
*/
|
|
70
|
-
export function buildTraceReport(collector: TraceCollector): TraceReport {
|
|
71
|
-
const entries: TraceReportEntry[] = [];
|
|
72
|
-
const errors: TraceEntry[] = [];
|
|
73
|
-
const stacks = new Map<string, TraceEntry[]>();
|
|
74
|
-
|
|
75
|
-
for (const record of collector.records) {
|
|
76
|
-
if (record.phase === "error") {
|
|
77
|
-
errors.push(record);
|
|
78
|
-
continue;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
const key = `${record.event}:${record.name ?? ""}`;
|
|
82
|
-
if (record.phase === "begin") {
|
|
83
|
-
const stack = stacks.get(key) ?? [];
|
|
84
|
-
stack.push(record);
|
|
85
|
-
stacks.set(key, stack);
|
|
86
|
-
continue;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
if (record.phase === "end") {
|
|
90
|
-
const stack = stacks.get(key);
|
|
91
|
-
const begin = stack?.pop();
|
|
92
|
-
if (!begin) continue;
|
|
93
|
-
entries.push({
|
|
94
|
-
event: record.event,
|
|
95
|
-
name: record.name,
|
|
96
|
-
start: begin.time,
|
|
97
|
-
end: record.time,
|
|
98
|
-
duration: record.time - begin.time,
|
|
99
|
-
});
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
return { entries, errors };
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
/**
|
|
107
|
-
* Convert trace report to JSON string
|
|
108
|
-
*/
|
|
109
|
-
export function formatTraceReport(report: TraceReport): string {
|
|
110
|
-
return JSON.stringify(report, null, 2);
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
export interface Tracer {
|
|
114
|
-
enabled: boolean;
|
|
115
|
-
begin: (event: TraceEvent, name?: string) => () => void;
|
|
116
|
-
error: (event: TraceEvent, err: unknown, name?: string) => void;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
const NOOP_TRACER: Tracer = {
|
|
120
|
-
enabled: false,
|
|
121
|
-
begin: () => () => {},
|
|
122
|
-
error: () => {},
|
|
123
|
-
};
|
|
124
|
-
|
|
125
|
-
export function createTracer(ctx: ManduContext, enabled?: boolean): Tracer {
|
|
126
|
-
const shouldEnable = Boolean(enabled) || ctx.has(TRACE_KEY);
|
|
127
|
-
if (!shouldEnable) return NOOP_TRACER;
|
|
128
|
-
|
|
129
|
-
const collector = enableTrace(ctx);
|
|
130
|
-
|
|
131
|
-
return {
|
|
132
|
-
enabled: true,
|
|
133
|
-
begin: (event, name) => {
|
|
134
|
-
collector.records.push({ event, phase: "begin", time: now(), name });
|
|
135
|
-
return () => {
|
|
136
|
-
collector.records.push({ event, phase: "end", time: now(), name });
|
|
137
|
-
};
|
|
138
|
-
},
|
|
139
|
-
error: (event, err, name) => {
|
|
140
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
141
|
-
collector.records.push({ event, phase: "error", time: now(), name, error: message });
|
|
142
|
-
},
|
|
143
|
-
};
|
|
144
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Mandu Trace π§
|
|
3
|
+
* Lifecycle λ¨κ³λ³ μΆμ (μ΅μ
)
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { ManduContext } from "../filling/context";
|
|
7
|
+
|
|
8
|
+
export type TraceEvent =
|
|
9
|
+
| "request"
|
|
10
|
+
| "parse"
|
|
11
|
+
| "transform"
|
|
12
|
+
| "beforeHandle"
|
|
13
|
+
| "handle"
|
|
14
|
+
| "afterHandle"
|
|
15
|
+
| "mapResponse"
|
|
16
|
+
| "afterResponse"
|
|
17
|
+
| "error";
|
|
18
|
+
|
|
19
|
+
export type TracePhase = "begin" | "end" | "error";
|
|
20
|
+
|
|
21
|
+
export interface TraceEntry {
|
|
22
|
+
event: TraceEvent;
|
|
23
|
+
phase: TracePhase;
|
|
24
|
+
time: number;
|
|
25
|
+
name?: string;
|
|
26
|
+
error?: string;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export interface TraceCollector {
|
|
30
|
+
records: TraceEntry[];
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export interface TraceReportEntry {
|
|
34
|
+
event: TraceEvent;
|
|
35
|
+
name?: string;
|
|
36
|
+
start: number;
|
|
37
|
+
end: number;
|
|
38
|
+
duration: number;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export interface TraceReport {
|
|
42
|
+
entries: TraceReportEntry[];
|
|
43
|
+
errors: TraceEntry[];
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export const TRACE_KEY = "__mandu_trace";
|
|
47
|
+
|
|
48
|
+
const now = (): number => {
|
|
49
|
+
if (typeof performance !== "undefined" && typeof performance.now === "function") {
|
|
50
|
+
return performance.now();
|
|
51
|
+
}
|
|
52
|
+
return Date.now();
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
export function enableTrace(ctx: ManduContext): TraceCollector {
|
|
56
|
+
const existing = ctx.get<TraceCollector>(TRACE_KEY);
|
|
57
|
+
if (existing) return existing;
|
|
58
|
+
const collector: TraceCollector = { records: [] };
|
|
59
|
+
ctx.set(TRACE_KEY, collector);
|
|
60
|
+
return collector;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export function getTrace(ctx: ManduContext): TraceCollector | undefined {
|
|
64
|
+
return ctx.get<TraceCollector>(TRACE_KEY);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Build a normalized trace report with durations
|
|
69
|
+
*/
|
|
70
|
+
export function buildTraceReport(collector: TraceCollector): TraceReport {
|
|
71
|
+
const entries: TraceReportEntry[] = [];
|
|
72
|
+
const errors: TraceEntry[] = [];
|
|
73
|
+
const stacks = new Map<string, TraceEntry[]>();
|
|
74
|
+
|
|
75
|
+
for (const record of collector.records) {
|
|
76
|
+
if (record.phase === "error") {
|
|
77
|
+
errors.push(record);
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const key = `${record.event}:${record.name ?? ""}`;
|
|
82
|
+
if (record.phase === "begin") {
|
|
83
|
+
const stack = stacks.get(key) ?? [];
|
|
84
|
+
stack.push(record);
|
|
85
|
+
stacks.set(key, stack);
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (record.phase === "end") {
|
|
90
|
+
const stack = stacks.get(key);
|
|
91
|
+
const begin = stack?.pop();
|
|
92
|
+
if (!begin) continue;
|
|
93
|
+
entries.push({
|
|
94
|
+
event: record.event,
|
|
95
|
+
name: record.name,
|
|
96
|
+
start: begin.time,
|
|
97
|
+
end: record.time,
|
|
98
|
+
duration: record.time - begin.time,
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
return { entries, errors };
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Convert trace report to JSON string
|
|
108
|
+
*/
|
|
109
|
+
export function formatTraceReport(report: TraceReport): string {
|
|
110
|
+
return JSON.stringify(report, null, 2);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export interface Tracer {
|
|
114
|
+
enabled: boolean;
|
|
115
|
+
begin: (event: TraceEvent, name?: string) => () => void;
|
|
116
|
+
error: (event: TraceEvent, err: unknown, name?: string) => void;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const NOOP_TRACER: Tracer = {
|
|
120
|
+
enabled: false,
|
|
121
|
+
begin: () => () => {},
|
|
122
|
+
error: () => {},
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
export function createTracer(ctx: ManduContext, enabled?: boolean): Tracer {
|
|
126
|
+
const shouldEnable = Boolean(enabled) || ctx.has(TRACE_KEY);
|
|
127
|
+
if (!shouldEnable) return NOOP_TRACER;
|
|
128
|
+
|
|
129
|
+
const collector = enableTrace(ctx);
|
|
130
|
+
|
|
131
|
+
return {
|
|
132
|
+
enabled: true,
|
|
133
|
+
begin: (event, name) => {
|
|
134
|
+
collector.records.push({ event, phase: "begin", time: now(), name });
|
|
135
|
+
return () => {
|
|
136
|
+
collector.records.push({ event, phase: "end", time: now(), name });
|
|
137
|
+
};
|
|
138
|
+
},
|
|
139
|
+
error: (event, err, name) => {
|
|
140
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
141
|
+
collector.records.push({ event, phase: "error", time: now(), name, error: message });
|
|
142
|
+
},
|
|
143
|
+
};
|
|
144
|
+
}
|