@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
package/src/client/hydrate.ts
CHANGED
|
@@ -16,8 +16,8 @@
|
|
|
16
16
|
* 2. Unit tests can import it under happy-dom/JSDOM without triggering
|
|
17
17
|
* global mutation (no `document.querySelectorAll` on module eval).
|
|
18
18
|
*
|
|
19
|
-
* The bundled runtime entry (`client/runtime-entry.ts`)
|
|
20
|
-
* delegates strategy selection to `scheduleHydration()` here — SSR emits the
|
|
19
|
+
* The bundled runtime entry (`client/runtime-entry.ts`)
|
|
20
|
+
* delegates strategy selection to `scheduleHydration()` here — SSR emits the
|
|
21
21
|
* `data-hydrate` attribute, the runtime reads it and dispatches.
|
|
22
22
|
*
|
|
23
23
|
* Design contract:
|
package/src/client/index.ts
CHANGED
|
@@ -168,7 +168,7 @@ import { Link, NavLink } from "./Link";
|
|
|
168
168
|
|
|
169
169
|
/**
|
|
170
170
|
* Mandu Client namespace
|
|
171
|
-
* v0.8.0: Hydration is handled automatically (runtime-entry)
|
|
171
|
+
* v0.8.0: Hydration is handled automatically (runtime-entry)
|
|
172
172
|
* Note: Use `ManduClient` to avoid conflict with other Mandu exports
|
|
173
173
|
*/
|
|
174
174
|
export const ManduClient = {
|
package/src/client/island.ts
CHANGED
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
* Hydration을 위한 클라이언트 사이드 컴포넌트 정의
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import type { ReactNode } from "react";
|
|
7
|
-
import { serializeProps } from "./serialize";
|
|
8
|
-
import { getServerData as getGlobalServerData } from "./window-state";
|
|
6
|
+
import type { ReactNode } from "react";
|
|
7
|
+
import { serializeProps } from "./serialize";
|
|
8
|
+
import { getServerData as getGlobalServerData } from "./window-state";
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* Island 정의 타입
|
|
@@ -336,45 +336,45 @@ export interface PartialConfig {
|
|
|
336
336
|
/**
|
|
337
337
|
* Partial Island 정의 타입
|
|
338
338
|
*/
|
|
339
|
-
export interface PartialDefinition<TProps> {
|
|
340
|
-
/** Partial 고유 ID. 기본값은 component displayName/name 입니다. */
|
|
341
|
-
id?: string;
|
|
342
|
-
/** Partial 컴포넌트 */
|
|
343
|
-
component: React.ComponentType<TProps>;
|
|
344
|
-
/** 초기 props (SSR에서 전달) */
|
|
345
|
-
initialProps?: TProps;
|
|
346
|
-
/** 하이드레이션 우선순위 */
|
|
347
|
-
priority?: "immediate" | "visible" | "idle" | "interaction";
|
|
348
|
-
/** 명시적 번들 URL. 기본값은 `/.mandu/client/{id}.partial.js` 입니다. */
|
|
349
|
-
src?: string;
|
|
350
|
-
/** 에러 시 표시할 UI */
|
|
351
|
-
errorBoundary?: (error: Error, reset: () => void) => ReactNode;
|
|
352
|
-
/** 로딩 중 표시할 UI */
|
|
353
|
-
loading?: () => ReactNode;
|
|
354
|
-
}
|
|
339
|
+
export interface PartialDefinition<TProps> {
|
|
340
|
+
/** Partial 고유 ID. 기본값은 component displayName/name 입니다. */
|
|
341
|
+
id?: string;
|
|
342
|
+
/** Partial 컴포넌트 */
|
|
343
|
+
component: React.ComponentType<TProps>;
|
|
344
|
+
/** 초기 props (SSR에서 전달) */
|
|
345
|
+
initialProps?: TProps;
|
|
346
|
+
/** 하이드레이션 우선순위 */
|
|
347
|
+
priority?: "immediate" | "visible" | "idle" | "interaction";
|
|
348
|
+
/** 명시적 번들 URL. 기본값은 `/.mandu/client/{id}.partial.js` 입니다. */
|
|
349
|
+
src?: string;
|
|
350
|
+
/** 에러 시 표시할 UI */
|
|
351
|
+
errorBoundary?: (error: Error, reset: () => void) => ReactNode;
|
|
352
|
+
/** 로딩 중 표시할 UI */
|
|
353
|
+
loading?: () => ReactNode;
|
|
354
|
+
}
|
|
355
355
|
|
|
356
356
|
/**
|
|
357
357
|
* 컴파일된 Partial
|
|
358
358
|
*/
|
|
359
|
-
export interface CompiledPartial<TProps> {
|
|
359
|
+
export interface CompiledPartial<TProps> {
|
|
360
360
|
/** Partial 정의 */
|
|
361
361
|
definition: PartialDefinition<TProps>;
|
|
362
362
|
/** Mandu Partial 마커 */
|
|
363
363
|
__mandu_partial: true;
|
|
364
364
|
/** Partial ID */
|
|
365
|
-
__mandu_partial_id?: string;
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
function normalizePartialId(id: string): string {
|
|
369
|
-
return id
|
|
370
|
-
.trim()
|
|
371
|
-
.replace(/[^A-Za-z0-9_-]/g, "-")
|
|
372
|
-
.replace(/^-+|-+$/g, "") || "partial";
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
function priorityToHydrate(priority: NonNullable<PartialDefinition<unknown>["priority"]>): string {
|
|
376
|
-
return priority === "immediate" ? "load" : priority;
|
|
377
|
-
}
|
|
365
|
+
__mandu_partial_id?: string;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
function normalizePartialId(id: string): string {
|
|
369
|
+
return id
|
|
370
|
+
.trim()
|
|
371
|
+
.replace(/[^A-Za-z0-9_-]/g, "-")
|
|
372
|
+
.replace(/^-+|-+$/g, "") || "partial";
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
function priorityToHydrate(priority: NonNullable<PartialDefinition<unknown>["priority"]>): string {
|
|
376
|
+
return priority === "immediate" ? "load" : priority;
|
|
377
|
+
}
|
|
378
378
|
|
|
379
379
|
/**
|
|
380
380
|
* Partial Island 생성
|
|
@@ -399,56 +399,56 @@ function priorityToHydrate(priority: NonNullable<PartialDefinition<unknown>["pri
|
|
|
399
399
|
* }
|
|
400
400
|
* ```
|
|
401
401
|
*/
|
|
402
|
-
export function partial<TProps extends Record<string, unknown>>(
|
|
403
|
-
definition: PartialDefinition<TProps>
|
|
404
|
-
): CompiledPartial<TProps> & {
|
|
405
|
-
Render: React.ComponentType<TProps>;
|
|
406
|
-
} {
|
|
402
|
+
export function partial<TProps extends Record<string, unknown>>(
|
|
403
|
+
definition: PartialDefinition<TProps>
|
|
404
|
+
): CompiledPartial<TProps> & {
|
|
405
|
+
Render: React.ComponentType<TProps>;
|
|
406
|
+
} {
|
|
407
407
|
if (!definition.component) {
|
|
408
408
|
throw new Error("[Mandu Partial] component is required");
|
|
409
409
|
}
|
|
410
410
|
|
|
411
|
-
const partialId = normalizePartialId(
|
|
412
|
-
definition.id ||
|
|
413
|
-
definition.component.displayName ||
|
|
414
|
-
definition.component.name ||
|
|
415
|
-
"partial",
|
|
416
|
-
);
|
|
417
|
-
const normalizedDefinition: PartialDefinition<TProps> = {
|
|
418
|
-
...definition,
|
|
419
|
-
id: partialId,
|
|
420
|
-
};
|
|
421
|
-
|
|
422
|
-
const compiled: CompiledPartial<TProps> = {
|
|
423
|
-
definition: normalizedDefinition,
|
|
424
|
-
__mandu_partial: true,
|
|
425
|
-
__mandu_partial_id: partialId,
|
|
426
|
-
};
|
|
427
|
-
|
|
428
|
-
// Render 컴포넌트 생성
|
|
429
|
-
const React = require("react");
|
|
430
|
-
|
|
431
|
-
const RenderComponent: React.FC<TProps> = (props) => {
|
|
432
|
-
const renderProps = Object.keys(props).length > 0
|
|
433
|
-
? props
|
|
434
|
-
: (normalizedDefinition.initialProps ?? props);
|
|
435
|
-
const priority = normalizedDefinition.priority ?? "visible";
|
|
436
|
-
const bundleSrc = normalizedDefinition.src ?? `/.mandu/client/${partialId}.partial.js`;
|
|
437
|
-
|
|
438
|
-
return React.createElement(
|
|
439
|
-
"div",
|
|
440
|
-
{
|
|
441
|
-
"data-mandu-island": partialId,
|
|
442
|
-
"data-mandu-partial": partialId,
|
|
443
|
-
"data-mandu-src": bundleSrc,
|
|
444
|
-
"data-mandu-priority": priority,
|
|
445
|
-
"data-hydrate": priorityToHydrate(priority),
|
|
446
|
-
"data-props": serializeProps(renderProps),
|
|
447
|
-
style: { display: "contents" },
|
|
448
|
-
},
|
|
449
|
-
React.createElement(normalizedDefinition.component, renderProps),
|
|
450
|
-
);
|
|
451
|
-
};
|
|
411
|
+
const partialId = normalizePartialId(
|
|
412
|
+
definition.id ||
|
|
413
|
+
definition.component.displayName ||
|
|
414
|
+
definition.component.name ||
|
|
415
|
+
"partial",
|
|
416
|
+
);
|
|
417
|
+
const normalizedDefinition: PartialDefinition<TProps> = {
|
|
418
|
+
...definition,
|
|
419
|
+
id: partialId,
|
|
420
|
+
};
|
|
421
|
+
|
|
422
|
+
const compiled: CompiledPartial<TProps> = {
|
|
423
|
+
definition: normalizedDefinition,
|
|
424
|
+
__mandu_partial: true,
|
|
425
|
+
__mandu_partial_id: partialId,
|
|
426
|
+
};
|
|
427
|
+
|
|
428
|
+
// Render 컴포넌트 생성
|
|
429
|
+
const React = require("react");
|
|
430
|
+
|
|
431
|
+
const RenderComponent: React.FC<TProps> = (props) => {
|
|
432
|
+
const renderProps = Object.keys(props).length > 0
|
|
433
|
+
? props
|
|
434
|
+
: (normalizedDefinition.initialProps ?? props);
|
|
435
|
+
const priority = normalizedDefinition.priority ?? "visible";
|
|
436
|
+
const bundleSrc = normalizedDefinition.src ?? `/.mandu/client/${partialId}.partial.js`;
|
|
437
|
+
|
|
438
|
+
return React.createElement(
|
|
439
|
+
"div",
|
|
440
|
+
{
|
|
441
|
+
"data-mandu-island": partialId,
|
|
442
|
+
"data-mandu-partial": partialId,
|
|
443
|
+
"data-mandu-src": bundleSrc,
|
|
444
|
+
"data-mandu-priority": priority,
|
|
445
|
+
"data-hydrate": priorityToHydrate(priority),
|
|
446
|
+
"data-props": serializeProps(renderProps),
|
|
447
|
+
style: { display: "contents" },
|
|
448
|
+
},
|
|
449
|
+
React.createElement(normalizedDefinition.component, renderProps),
|
|
450
|
+
);
|
|
451
|
+
};
|
|
452
452
|
|
|
453
453
|
return Object.assign(compiled, { Render: RenderComponent });
|
|
454
454
|
}
|
|
@@ -1,55 +1,55 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Issue #192 — Hover prefetch helper
|
|
3
|
-
*
|
|
4
|
-
* Self-contained IIFE that watches `mouseover` events bubbling from
|
|
5
|
-
* internal `<a href="/...">` anchors and issues a one-shot
|
|
6
|
-
* `<link rel="prefetch" as="document">` per unique anchor. The browser
|
|
7
|
-
* cache services the subsequent full-reload navigation, so most
|
|
8
|
-
* above-the-fold links feel instantaneous without requiring a SPA
|
|
9
|
-
* runtime.
|
|
10
|
-
*
|
|
11
|
-
* Design choices (locked to keep the payload tiny — target ≤500 bytes
|
|
12
|
-
* minified + gzipped):
|
|
13
|
-
*
|
|
14
|
-
* 1. **WeakSet-based dedup**: we never attach per-anchor listeners;
|
|
15
|
-
* we use a single `document`-level capture listener and stamp
|
|
16
|
-
* each anchor we've seen into a `WeakSet`. Anchors removed from
|
|
17
|
-
* the DOM collect automatically.
|
|
18
|
-
*
|
|
19
|
-
* 2. **Scope: same-origin `/...` paths only**: we deliberately skip
|
|
20
|
-
* absolute URLs, `mailto:`, `tel:`, `javascript:`, hash-only
|
|
21
|
-
* fragments, and `#`-on-same-page links. The `a[href^="/"]`
|
|
22
|
-
* selector implicitly covers this and avoids a surprise
|
|
23
|
-
* cross-origin DNS lookup.
|
|
24
|
-
*
|
|
25
|
-
* 3. **Opt-out per-link via `data-no-prefetch`**: mirrors Next.js'
|
|
26
|
-
* `prefetch={false}` ergonomics while being framework-agnostic —
|
|
27
|
-
* works with plain `<a>` and with Mandu's `<Link>` component.
|
|
28
|
-
*
|
|
29
|
-
* 4. **`as="document"` hint**: the correct token for HTML documents
|
|
30
|
-
* that will be navigated to via a subsequent click. Without it
|
|
31
|
-
* Chrome 121+ logs a `rel=prefetch as=missing` warning.
|
|
32
|
-
*
|
|
33
|
-
* 5. **Capture phase + `passive: true`**: listening in the capture
|
|
34
|
-
* phase catches the event before any app-level bubble handlers
|
|
35
|
-
* can cancel it (defensive against apps that `stopPropagation`
|
|
36
|
-
* on `<a>`). `passive` ensures we can never accidentally block
|
|
37
|
-
* scroll.
|
|
38
|
-
*
|
|
39
|
-
* 6. **Inline, not external bundle**: the helper is under 1KB and
|
|
40
|
-
* emitting it as a `<script>` child (rather than
|
|
41
|
-
* `<script src=".../_prefetch.js">`) avoids one HTTP round-trip
|
|
42
|
-
* on every SSR response and keeps the module graph unchanged.
|
|
43
|
-
*
|
|
44
|
-
* The exported `PREFETCH_HELPER_SCRIPT` wraps the IIFE in a
|
|
45
|
-
* `<script>` tag, ready to paste into `<head>`. Callers MUST keep it
|
|
46
|
-
* nonce-aware if they plan to enable CSP (future work — right now the
|
|
47
|
-
* Fast Refresh preamble is the only inline script covered by Mandu's
|
|
48
|
-
* CSP header).
|
|
49
|
-
*/
|
|
50
|
-
|
|
51
|
-
/** Inner IIFE — exposed for unit tests that want to parse the source. */
|
|
52
|
-
export const PREFETCH_HELPER_BODY = `(function(){var s=new WeakSet();document.addEventListener("mouseover",function(e){var t=e.target;if(!t||typeof t.closest!=="function")return;var a=t.closest("a[href^='/']");if(!a||s.has(a))return;if(a.dataset&&a.dataset.noPrefetch!==undefined)return;if(a.hasAttribute&&a.hasAttribute("download"))return;if(a.target&&a.target!=="_self")return;s.add(a);try{var l=document.createElement("link");l.rel="prefetch";l.href=a.href;l.as="document";document.head.appendChild(l);}catch(_){}},{passive:true,capture:true});})();`;
|
|
53
|
-
|
|
54
|
-
/** Ready-to-inject `<script>` tag for SSR `<head>` injection. */
|
|
55
|
-
export const PREFETCH_HELPER_SCRIPT = `<script>${PREFETCH_HELPER_BODY}</script>`;
|
|
1
|
+
/**
|
|
2
|
+
* Issue #192 — Hover prefetch helper
|
|
3
|
+
*
|
|
4
|
+
* Self-contained IIFE that watches `mouseover` events bubbling from
|
|
5
|
+
* internal `<a href="/...">` anchors and issues a one-shot
|
|
6
|
+
* `<link rel="prefetch" as="document">` per unique anchor. The browser
|
|
7
|
+
* cache services the subsequent full-reload navigation, so most
|
|
8
|
+
* above-the-fold links feel instantaneous without requiring a SPA
|
|
9
|
+
* runtime.
|
|
10
|
+
*
|
|
11
|
+
* Design choices (locked to keep the payload tiny — target ≤500 bytes
|
|
12
|
+
* minified + gzipped):
|
|
13
|
+
*
|
|
14
|
+
* 1. **WeakSet-based dedup**: we never attach per-anchor listeners;
|
|
15
|
+
* we use a single `document`-level capture listener and stamp
|
|
16
|
+
* each anchor we've seen into a `WeakSet`. Anchors removed from
|
|
17
|
+
* the DOM collect automatically.
|
|
18
|
+
*
|
|
19
|
+
* 2. **Scope: same-origin `/...` paths only**: we deliberately skip
|
|
20
|
+
* absolute URLs, `mailto:`, `tel:`, `javascript:`, hash-only
|
|
21
|
+
* fragments, and `#`-on-same-page links. The `a[href^="/"]`
|
|
22
|
+
* selector implicitly covers this and avoids a surprise
|
|
23
|
+
* cross-origin DNS lookup.
|
|
24
|
+
*
|
|
25
|
+
* 3. **Opt-out per-link via `data-no-prefetch`**: mirrors Next.js'
|
|
26
|
+
* `prefetch={false}` ergonomics while being framework-agnostic —
|
|
27
|
+
* works with plain `<a>` and with Mandu's `<Link>` component.
|
|
28
|
+
*
|
|
29
|
+
* 4. **`as="document"` hint**: the correct token for HTML documents
|
|
30
|
+
* that will be navigated to via a subsequent click. Without it
|
|
31
|
+
* Chrome 121+ logs a `rel=prefetch as=missing` warning.
|
|
32
|
+
*
|
|
33
|
+
* 5. **Capture phase + `passive: true`**: listening in the capture
|
|
34
|
+
* phase catches the event before any app-level bubble handlers
|
|
35
|
+
* can cancel it (defensive against apps that `stopPropagation`
|
|
36
|
+
* on `<a>`). `passive` ensures we can never accidentally block
|
|
37
|
+
* scroll.
|
|
38
|
+
*
|
|
39
|
+
* 6. **Inline, not external bundle**: the helper is under 1KB and
|
|
40
|
+
* emitting it as a `<script>` child (rather than
|
|
41
|
+
* `<script src=".../_prefetch.js">`) avoids one HTTP round-trip
|
|
42
|
+
* on every SSR response and keeps the module graph unchanged.
|
|
43
|
+
*
|
|
44
|
+
* The exported `PREFETCH_HELPER_SCRIPT` wraps the IIFE in a
|
|
45
|
+
* `<script>` tag, ready to paste into `<head>`. Callers MUST keep it
|
|
46
|
+
* nonce-aware if they plan to enable CSP (future work — right now the
|
|
47
|
+
* Fast Refresh preamble is the only inline script covered by Mandu's
|
|
48
|
+
* CSP header).
|
|
49
|
+
*/
|
|
50
|
+
|
|
51
|
+
/** Inner IIFE — exposed for unit tests that want to parse the source. */
|
|
52
|
+
export const PREFETCH_HELPER_BODY = `(function(){var s=new WeakSet();document.addEventListener("mouseover",function(e){var t=e.target;if(!t||typeof t.closest!=="function")return;var a=t.closest("a[href^='/']");if(!a||s.has(a))return;if(a.dataset&&a.dataset.noPrefetch!==undefined)return;if(a.hasAttribute&&a.hasAttribute("download"))return;if(a.target&&a.target!=="_self")return;s.add(a);try{var l=document.createElement("link");l.rel="prefetch";l.href=a.href;l.as="document";document.head.appendChild(l);}catch(_){}},{passive:true,capture:true});})();`;
|
|
53
|
+
|
|
54
|
+
/** Ready-to-inject `<script>` tag for SSR `<head>` injection. */
|
|
55
|
+
export const PREFETCH_HELPER_SCRIPT = `<script>${PREFETCH_HELPER_BODY}</script>`;
|