@jasonshimmy/vite-plugin-cer-app 0.23.1 → 0.24.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/dist/cli/checks/lighthouse.d.ts +26 -0
- package/dist/cli/checks/lighthouse.d.ts.map +1 -0
- package/dist/cli/checks/lighthouse.js +121 -0
- package/dist/cli/checks/lighthouse.js.map +1 -0
- package/dist/cli/checks/links.d.ts +12 -0
- package/dist/cli/checks/links.d.ts.map +1 -0
- package/dist/cli/checks/links.js +89 -0
- package/dist/cli/checks/links.js.map +1 -0
- package/dist/cli/checks/performance.d.ts +17 -0
- package/dist/cli/checks/performance.d.ts.map +1 -0
- package/dist/cli/checks/performance.js +61 -0
- package/dist/cli/checks/performance.js.map +1 -0
- package/dist/cli/commands/check.d.ts +3 -0
- package/dist/cli/commands/check.d.ts.map +1 -0
- package/dist/cli/commands/check.js +85 -0
- package/dist/cli/commands/check.js.map +1 -0
- package/dist/cli/commands/preview.d.ts.map +1 -1
- package/dist/cli/commands/preview.js +37 -4
- package/dist/cli/commands/preview.js.map +1 -1
- package/dist/cli/create/index.d.ts +11 -1
- package/dist/cli/create/index.d.ts.map +1 -1
- package/dist/cli/create/index.js +135 -65
- package/dist/cli/create/index.js.map +1 -1
- package/dist/cli/create/templates/spa/package.json.tpl +5 -3
- package/dist/cli/create/templates/ssg/cer.config.ts.tpl +2 -0
- package/dist/cli/create/templates/ssg/package.json.tpl +5 -3
- package/dist/cli/create/templates/ssr/package.json.tpl +5 -3
- package/dist/cli/index.js +2 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/plugin/build-ssg.d.ts +22 -4
- package/dist/plugin/build-ssg.d.ts.map +1 -1
- package/dist/plugin/build-ssg.js +273 -13
- package/dist/plugin/build-ssg.js.map +1 -1
- package/dist/plugin/content/parser.d.ts.map +1 -1
- package/dist/plugin/content/parser.js +54 -10
- package/dist/plugin/content/parser.js.map +1 -1
- package/dist/plugin/dev-server.d.ts +6 -1
- package/dist/plugin/dev-server.d.ts.map +1 -1
- package/dist/plugin/dev-server.js.map +1 -1
- package/dist/plugin/dts-generator.d.ts.map +1 -1
- package/dist/plugin/dts-generator.js +50 -8
- package/dist/plugin/dts-generator.js.map +1 -1
- package/dist/plugin/generated-dir.d.ts +2 -0
- package/dist/plugin/generated-dir.d.ts.map +1 -1
- package/dist/plugin/generated-dir.js +17 -6
- package/dist/plugin/generated-dir.js.map +1 -1
- package/dist/plugin/html-post-process.d.ts +35 -0
- package/dist/plugin/html-post-process.d.ts.map +1 -0
- package/dist/plugin/html-post-process.js +112 -0
- package/dist/plugin/html-post-process.js.map +1 -0
- package/dist/plugin/index.d.ts +9 -0
- package/dist/plugin/index.d.ts.map +1 -1
- package/dist/plugin/index.js +89 -14
- package/dist/plugin/index.js.map +1 -1
- package/dist/plugin/transforms/auto-import.d.ts.map +1 -1
- package/dist/plugin/transforms/auto-import.js +7 -0
- package/dist/plugin/transforms/auto-import.js.map +1 -1
- package/dist/plugin/transforms/prune-runtime-css.d.ts +8 -0
- package/dist/plugin/transforms/prune-runtime-css.d.ts.map +1 -0
- package/dist/plugin/transforms/prune-runtime-css.js +40 -0
- package/dist/plugin/transforms/prune-runtime-css.js.map +1 -0
- package/dist/runtime/app-template.d.ts +1 -4
- package/dist/runtime/app-template.d.ts.map +1 -1
- package/dist/runtime/app-template.js +211 -40
- package/dist/runtime/app-template.js.map +1 -1
- package/dist/runtime/composables/index.d.ts +4 -0
- package/dist/runtime/composables/index.d.ts.map +1 -1
- package/dist/runtime/composables/index.js +2 -0
- package/dist/runtime/composables/index.js.map +1 -1
- package/dist/runtime/composables/use-active-headings.d.ts +24 -0
- package/dist/runtime/composables/use-active-headings.d.ts.map +1 -0
- package/dist/runtime/composables/use-active-headings.js +112 -0
- package/dist/runtime/composables/use-active-headings.js.map +1 -0
- package/dist/runtime/composables/use-content-page.d.ts +45 -0
- package/dist/runtime/composables/use-content-page.d.ts.map +1 -0
- package/dist/runtime/composables/use-content-page.js +179 -0
- package/dist/runtime/composables/use-content-page.js.map +1 -0
- package/dist/runtime/composables/use-content-search.d.ts.map +1 -1
- package/dist/runtime/composables/use-content-search.js +1 -5
- package/dist/runtime/composables/use-content-search.js.map +1 -1
- package/dist/runtime/composables/use-fetch.d.ts +2 -1
- package/dist/runtime/composables/use-fetch.d.ts.map +1 -1
- package/dist/runtime/composables/use-fetch.js +112 -43
- package/dist/runtime/composables/use-fetch.js.map +1 -1
- package/dist/runtime/composables/use-head.d.ts.map +1 -1
- package/dist/runtime/composables/use-head.js +30 -6
- package/dist/runtime/composables/use-head.js.map +1 -1
- package/dist/runtime/composables/use-route.d.ts.map +1 -1
- package/dist/runtime/composables/use-route.js +39 -11
- package/dist/runtime/composables/use-route.js.map +1 -1
- package/dist/runtime/content/client.js +2 -2
- package/dist/runtime/content/client.js.map +1 -1
- package/dist/runtime/entry-server-template.d.ts +16 -1
- package/dist/runtime/entry-server-template.d.ts.map +1 -1
- package/dist/runtime/entry-server-template.js +120 -13
- package/dist/runtime/entry-server-template.js.map +1 -1
- package/dist/types/config.d.ts +53 -4
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/config.js.map +1 -1
- package/dist/types/middleware.d.ts +2 -2
- package/dist/types/middleware.d.ts.map +1 -1
- package/package.json +22 -19
- package/.github/copilot-instructions.md +0 -169
- package/.github/workflows/publish.yml +0 -257
- package/.nvmrc +0 -1
- package/CHANGELOG.md +0 -232
- package/CLAUDE.md +0 -113
- package/commits.txt +0 -1
- package/cypress.config.ts +0 -16
- package/docs/authentication.md +0 -285
- package/docs/cli.md +0 -324
- package/docs/components.md +0 -237
- package/docs/composables.md +0 -907
- package/docs/configuration.md +0 -667
- package/docs/content.md +0 -570
- package/docs/data-loading.md +0 -336
- package/docs/getting-started.md +0 -237
- package/docs/head-management.md +0 -212
- package/docs/i18n.md +0 -159
- package/docs/layouts.md +0 -224
- package/docs/middleware.md +0 -234
- package/docs/plugins.md +0 -170
- package/docs/rendering-modes.md +0 -377
- package/docs/routing.md +0 -485
- package/docs/server-api.md +0 -253
- package/docs/testing.md +0 -455
- package/docs/use-fetch.md +0 -183
- package/e2e/cypress/e2e/api.cy.ts +0 -123
- package/e2e/cypress/e2e/async-component.cy.ts +0 -27
- package/e2e/cypress/e2e/component-splitting.cy.ts +0 -50
- package/e2e/cypress/e2e/content.cy.ts +0 -425
- package/e2e/cypress/e2e/cookie.cy.ts +0 -85
- package/e2e/cypress/e2e/data.cy.ts +0 -158
- package/e2e/cypress/e2e/error-boundary.cy.ts +0 -88
- package/e2e/cypress/e2e/fouc.cy.ts +0 -254
- package/e2e/cypress/e2e/group-meta.cy.ts +0 -36
- package/e2e/cypress/e2e/head.cy.ts +0 -89
- package/e2e/cypress/e2e/i18n.cy.ts +0 -79
- package/e2e/cypress/e2e/interactive.cy.ts +0 -137
- package/e2e/cypress/e2e/isr-nested-runtime.cy.ts +0 -102
- package/e2e/cypress/e2e/jit-css-custom-colors.cy.ts +0 -43
- package/e2e/cypress/e2e/middleware-chain.cy.ts +0 -89
- package/e2e/cypress/e2e/middleware-status.cy.ts +0 -30
- package/e2e/cypress/e2e/middleware.cy.ts +0 -45
- package/e2e/cypress/e2e/navigate.cy.ts +0 -39
- package/e2e/cypress/e2e/observability.cy.ts +0 -77
- package/e2e/cypress/e2e/per-route-error.cy.ts +0 -42
- package/e2e/cypress/e2e/per-route-render.cy.ts +0 -70
- package/e2e/cypress/e2e/preview-hardening.cy.ts +0 -88
- package/e2e/cypress/e2e/routes.cy.ts +0 -128
- package/e2e/cypress/e2e/seo-meta.cy.ts +0 -108
- package/e2e/cypress/e2e/server-middleware.cy.ts +0 -46
- package/e2e/cypress/e2e/session-rotation.cy.ts +0 -25
- package/e2e/cypress/e2e/session.cy.ts +0 -73
- package/e2e/cypress/e2e/ssr-render-error.cy.ts +0 -68
- package/e2e/cypress/e2e/synthetic-404.cy.ts +0 -45
- package/e2e/cypress/e2e/use-page-data.cy.ts +0 -122
- package/e2e/cypress/e2e/use-state.cy.ts +0 -138
- package/e2e/cypress/support/commands.ts +0 -120
- package/e2e/cypress/support/e2e.ts +0 -10
- package/e2e/cypress/tsconfig.json +0 -14
- package/e2e/kitchen-sink/app/components/ks-badge.ts +0 -8
- package/e2e/kitchen-sink/app/composables/useKsCounter.ts +0 -9
- package/e2e/kitchen-sink/app/error.ts +0 -18
- package/e2e/kitchen-sink/app/layouts/admin.ts +0 -13
- package/e2e/kitchen-sink/app/layouts/default.ts +0 -25
- package/e2e/kitchen-sink/app/layouts/group.ts +0 -9
- package/e2e/kitchen-sink/app/layouts/minimal.ts +0 -7
- package/e2e/kitchen-sink/app/loading.ts +0 -9
- package/e2e/kitchen-sink/app/middleware/auth.ts +0 -9
- package/e2e/kitchen-sink/app/middleware/custom-log.ts +0 -4
- package/e2e/kitchen-sink/app/middleware/group-auth.ts +0 -7
- package/e2e/kitchen-sink/app/middleware/logger.ts +0 -14
- package/e2e/kitchen-sink/app/pages/(auth)/login.ts +0 -13
- package/e2e/kitchen-sink/app/pages/(auth)/protected.ts +0 -16
- package/e2e/kitchen-sink/app/pages/404.ts +0 -9
- package/e2e/kitchen-sink/app/pages/about.ts +0 -17
- package/e2e/kitchen-sink/app/pages/admin/_layout.ts +0 -1
- package/e2e/kitchen-sink/app/pages/admin/dashboard.ts +0 -11
- package/e2e/kitchen-sink/app/pages/async-component-error-test.ts +0 -18
- package/e2e/kitchen-sink/app/pages/async-component-test.ts +0 -18
- package/e2e/kitchen-sink/app/pages/blog/[slug].ts +0 -59
- package/e2e/kitchen-sink/app/pages/blog/index.ts +0 -51
- package/e2e/kitchen-sink/app/pages/content-blog.ts +0 -37
- package/e2e/kitchen-sink/app/pages/content-doc.ts +0 -42
- package/e2e/kitchen-sink/app/pages/content-fallback.ts +0 -36
- package/e2e/kitchen-sink/app/pages/content-guides.ts +0 -35
- package/e2e/kitchen-sink/app/pages/content-index.ts +0 -39
- package/e2e/kitchen-sink/app/pages/content-search.ts +0 -36
- package/e2e/kitchen-sink/app/pages/cookie-test.ts +0 -22
- package/e2e/kitchen-sink/app/pages/counter.ts +0 -17
- package/e2e/kitchen-sink/app/pages/group-auth-blocked.ts +0 -9
- package/e2e/kitchen-sink/app/pages/group-meta-test/_layout.ts +0 -6
- package/e2e/kitchen-sink/app/pages/group-meta-test/custom-mw.ts +0 -14
- package/e2e/kitchen-sink/app/pages/group-meta-test/page.ts +0 -9
- package/e2e/kitchen-sink/app/pages/group-meta-test/protected.ts +0 -8
- package/e2e/kitchen-sink/app/pages/head.ts +0 -20
- package/e2e/kitchen-sink/app/pages/i18n-test.ts +0 -14
- package/e2e/kitchen-sink/app/pages/index.ts +0 -27
- package/e2e/kitchen-sink/app/pages/isr-test.ts +0 -17
- package/e2e/kitchen-sink/app/pages/items/[id].ts +0 -20
- package/e2e/kitchen-sink/app/pages/jit-css-custom-colors-test.ts +0 -14
- package/e2e/kitchen-sink/app/pages/loader-error-test.ts +0 -13
- package/e2e/kitchen-sink/app/pages/loader-props-test.ts +0 -19
- package/e2e/kitchen-sink/app/pages/loader-response-error-test.ts +0 -13
- package/e2e/kitchen-sink/app/pages/middleware-chain-test.ts +0 -12
- package/e2e/kitchen-sink/app/pages/middleware-status-test.ts +0 -9
- package/e2e/kitchen-sink/app/pages/navigate-test.ts +0 -16
- package/e2e/kitchen-sink/app/pages/observability-test.ts +0 -25
- package/e2e/kitchen-sink/app/pages/per-route-error-test.error.ts +0 -13
- package/e2e/kitchen-sink/app/pages/per-route-error-test.ts +0 -15
- package/e2e/kitchen-sink/app/pages/plugin-dsd-test.ts +0 -10
- package/e2e/kitchen-sink/app/pages/render-error-test.ts +0 -12
- package/e2e/kitchen-sink/app/pages/render-server-test.ts +0 -12
- package/e2e/kitchen-sink/app/pages/render-spa-test.ts +0 -12
- package/e2e/kitchen-sink/app/pages/route-info.ts +0 -14
- package/e2e/kitchen-sink/app/pages/seo-test.ts +0 -23
- package/e2e/kitchen-sink/app/pages/session-rotation-test.ts +0 -25
- package/e2e/kitchen-sink/app/pages/use-state-test.ts +0 -37
- package/e2e/kitchen-sink/app/plugins/01.setup.ts +0 -7
- package/e2e/kitchen-sink/app/plugins/02.ks-plugin-components.ts +0 -27
- package/e2e/kitchen-sink/cer-auto-imports.d.ts +0 -51
- package/e2e/kitchen-sink/cer-env.d.ts +0 -35
- package/e2e/kitchen-sink/cer-tsconfig.json +0 -30
- package/e2e/kitchen-sink/cer.config.ts +0 -43
- package/e2e/kitchen-sink/content/01.guides/01.index.md +0 -8
- package/e2e/kitchen-sink/content/01.guides/02.intro.md +0 -8
- package/e2e/kitchen-sink/content/01.guides/10.advanced.md +0 -8
- package/e2e/kitchen-sink/content/blog/2026-04-01-hello.md +0 -26
- package/e2e/kitchen-sink/content/blog/2026-04-02-draft.md +0 -10
- package/e2e/kitchen-sink/content/blog/index.md +0 -8
- package/e2e/kitchen-sink/content/blog/no-frontmatter.md +0 -7
- package/e2e/kitchen-sink/content/docs/getting-started.md +0 -48
- package/e2e/kitchen-sink/content/index.md +0 -16
- package/e2e/kitchen-sink/server/api/echo.ts +0 -12
- package/e2e/kitchen-sink/server/api/health.ts +0 -3
- package/e2e/kitchen-sink/server/api/posts/[slug].ts +0 -11
- package/e2e/kitchen-sink/server/api/posts/index.ts +0 -5
- package/e2e/kitchen-sink/server/api/session.ts +0 -23
- package/e2e/kitchen-sink/server/data/posts.ts +0 -21
- package/e2e/kitchen-sink/server/middleware/01-headers.ts +0 -6
- package/e2e/kitchen-sink/server/middleware/02-status-test.ts +0 -10
- package/e2e/kitchen-sink/tsconfig.json +0 -3
- package/e2e/scripts/clean.mjs +0 -14
- package/eslint.config.ts +0 -22
- package/src/__tests__/cli/adapters/cloudflare-worker.integration.test.ts +0 -132
- package/src/__tests__/cli/adapters/cloudflare.test.ts +0 -332
- package/src/__tests__/cli/adapters/netlify-bridge.integration.test.ts +0 -139
- package/src/__tests__/cli/adapters/netlify.test.ts +0 -286
- package/src/__tests__/cli/adapters/vercel-launcher.integration.test.ts +0 -129
- package/src/__tests__/cli/adapters/vercel.test.ts +0 -263
- package/src/__tests__/cli/preview-hardening.test.ts +0 -265
- package/src/__tests__/cli/preview-isr.test.ts +0 -320
- package/src/__tests__/index.test.ts +0 -21
- package/src/__tests__/plugin/app-template.test.ts +0 -112
- package/src/__tests__/plugin/build-ssg-render.test.ts +0 -155
- package/src/__tests__/plugin/build-ssg.test.ts +0 -598
- package/src/__tests__/plugin/build-ssr.test.ts +0 -192
- package/src/__tests__/plugin/cer-app-plugin.test.ts +0 -552
- package/src/__tests__/plugin/content/emitter.test.ts +0 -117
- package/src/__tests__/plugin/content/loader.test.ts +0 -154
- package/src/__tests__/plugin/content/parser.test.ts +0 -381
- package/src/__tests__/plugin/content/path-utils.test.ts +0 -69
- package/src/__tests__/plugin/content/search.test.ts +0 -119
- package/src/__tests__/plugin/dev-server.test.ts +0 -813
- package/src/__tests__/plugin/dts-generator.test.ts +0 -394
- package/src/__tests__/plugin/entry-server-template.test.ts +0 -385
- package/src/__tests__/plugin/generated-dir.test.ts +0 -144
- package/src/__tests__/plugin/path-utils.test.ts +0 -411
- package/src/__tests__/plugin/resolve-config.test.ts +0 -200
- package/src/__tests__/plugin/scanner.test.ts +0 -186
- package/src/__tests__/plugin/transforms/auto-import.test.ts +0 -510
- package/src/__tests__/plugin/transforms/head-inject.test.ts +0 -178
- package/src/__tests__/plugin/virtual/composables.test.ts +0 -57
- package/src/__tests__/plugin/virtual/content-components.test.ts +0 -66
- package/src/__tests__/plugin/virtual/error.test.ts +0 -71
- package/src/__tests__/plugin/virtual/layouts.test.ts +0 -70
- package/src/__tests__/plugin/virtual/loading.test.ts +0 -72
- package/src/__tests__/plugin/virtual/middleware.test.ts +0 -83
- package/src/__tests__/plugin/virtual/plugins.test.ts +0 -129
- package/src/__tests__/plugin/virtual/routes.test.ts +0 -884
- package/src/__tests__/plugin/virtual/server-api.test.ts +0 -164
- package/src/__tests__/plugin/virtual/server-middleware.test.ts +0 -102
- package/src/__tests__/runtime/app-template.test.ts +0 -198
- package/src/__tests__/runtime/define-middleware.test.ts +0 -64
- package/src/__tests__/runtime/define-server-middleware.test.ts +0 -54
- package/src/__tests__/runtime/entry-client-template.test.ts +0 -61
- package/src/__tests__/runtime/isr-handler.test.ts +0 -338
- package/src/__tests__/runtime/oauth/handler.test.ts +0 -358
- package/src/__tests__/runtime/oauth/providers.test.ts +0 -47
- package/src/__tests__/runtime/oauth-index.test.ts +0 -43
- package/src/__tests__/runtime/use-auth.test.ts +0 -169
- package/src/__tests__/runtime/use-content-search-composable.test.ts +0 -405
- package/src/__tests__/runtime/use-content-search.test.ts +0 -163
- package/src/__tests__/runtime/use-content.test.ts +0 -226
- package/src/__tests__/runtime/use-cookie.test.ts +0 -277
- package/src/__tests__/runtime/use-fetch-component.test.ts +0 -214
- package/src/__tests__/runtime/use-fetch.test.ts +0 -377
- package/src/__tests__/runtime/use-head.test.ts +0 -266
- package/src/__tests__/runtime/use-inject-client.test.ts +0 -67
- package/src/__tests__/runtime/use-inject.test.ts +0 -66
- package/src/__tests__/runtime/use-locale.test.ts +0 -152
- package/src/__tests__/runtime/use-navigate.test.ts +0 -121
- package/src/__tests__/runtime/use-page-data.test.ts +0 -298
- package/src/__tests__/runtime/use-route.test.ts +0 -156
- package/src/__tests__/runtime/use-runtime-config.test.ts +0 -182
- package/src/__tests__/runtime/use-seo-meta.test.ts +0 -109
- package/src/__tests__/runtime/use-session.test.ts +0 -320
- package/src/__tests__/runtime/use-state.test.ts +0 -340
- package/src/__tests__/types/config.test.ts +0 -18
- package/src/cli/adapters/cloudflare.ts +0 -335
- package/src/cli/adapters/netlify.ts +0 -326
- package/src/cli/adapters/vercel.ts +0 -311
- package/src/cli/commands/adapt.ts +0 -84
- package/src/cli/commands/build.ts +0 -165
- package/src/cli/commands/dev.ts +0 -125
- package/src/cli/commands/generate.ts +0 -91
- package/src/cli/commands/preview-isr.ts +0 -172
- package/src/cli/commands/preview.ts +0 -489
- package/src/cli/create/index.ts +0 -275
- package/src/cli/create/templates/shared/.gitignore.tpl +0 -25
- package/src/cli/create/templates/shared/app/layouts/default.ts.tpl +0 -15
- package/src/cli/create/templates/shared/app/pages/index.ts.tpl +0 -8
- package/src/cli/create/templates/shared/index.html.tpl +0 -12
- package/src/cli/create/templates/shared/tsconfig.json.tpl +0 -6
- package/src/cli/create/templates/spa/cer.config.ts.tpl +0 -6
- package/src/cli/create/templates/spa/package.json.tpl +0 -18
- package/src/cli/create/templates/ssg/cer.config.ts.tpl +0 -10
- package/src/cli/create/templates/ssg/package.json.tpl +0 -19
- package/src/cli/create/templates/ssr/cer.config.ts.tpl +0 -6
- package/src/cli/create/templates/ssr/package.json.tpl +0 -18
- package/src/cli/index.ts +0 -22
- package/src/index.ts +0 -20
- package/src/plugin/build-ssg.ts +0 -336
- package/src/plugin/build-ssr.ts +0 -134
- package/src/plugin/content/emitter.ts +0 -50
- package/src/plugin/content/index.ts +0 -233
- package/src/plugin/content/parser.ts +0 -259
- package/src/plugin/content/path-utils.ts +0 -55
- package/src/plugin/content/scanner.ts +0 -26
- package/src/plugin/content/search.ts +0 -28
- package/src/plugin/dev-server.ts +0 -377
- package/src/plugin/dts-generator.ts +0 -273
- package/src/plugin/generated-dir.ts +0 -121
- package/src/plugin/index.ts +0 -553
- package/src/plugin/path-utils.ts +0 -186
- package/src/plugin/scanner.ts +0 -65
- package/src/plugin/transforms/auto-import.ts +0 -206
- package/src/plugin/transforms/head-inject.ts +0 -161
- package/src/plugin/virtual/composables.ts +0 -28
- package/src/plugin/virtual/content-components.ts +0 -83
- package/src/plugin/virtual/error.ts +0 -34
- package/src/plugin/virtual/layouts.ts +0 -41
- package/src/plugin/virtual/loading.ts +0 -32
- package/src/plugin/virtual/middleware.ts +0 -45
- package/src/plugin/virtual/plugins.ts +0 -46
- package/src/plugin/virtual/routes.ts +0 -514
- package/src/plugin/virtual/server-api.ts +0 -85
- package/src/plugin/virtual/server-middleware.ts +0 -44
- package/src/runtime/app-template.ts +0 -380
- package/src/runtime/composables/define-middleware.ts +0 -17
- package/src/runtime/composables/define-server-middleware.ts +0 -18
- package/src/runtime/composables/index.ts +0 -27
- package/src/runtime/composables/use-auth.ts +0 -125
- package/src/runtime/composables/use-content-search.ts +0 -205
- package/src/runtime/composables/use-content.ts +0 -146
- package/src/runtime/composables/use-cookie.ts +0 -135
- package/src/runtime/composables/use-fetch.ts +0 -438
- package/src/runtime/composables/use-head.ts +0 -212
- package/src/runtime/composables/use-inject.ts +0 -49
- package/src/runtime/composables/use-locale.ts +0 -109
- package/src/runtime/composables/use-navigate.ts +0 -58
- package/src/runtime/composables/use-page-data.ts +0 -93
- package/src/runtime/composables/use-route.ts +0 -71
- package/src/runtime/composables/use-runtime-config.ts +0 -123
- package/src/runtime/composables/use-seo-meta.ts +0 -80
- package/src/runtime/composables/use-session.ts +0 -186
- package/src/runtime/composables/use-state.ts +0 -92
- package/src/runtime/content/client.ts +0 -168
- package/src/runtime/entry-client-template.ts +0 -39
- package/src/runtime/entry-server-template.ts +0 -493
- package/src/runtime/isr-handler.ts +0 -184
- package/src/runtime/oauth/handler.ts +0 -407
- package/src/runtime/oauth/index.ts +0 -49
- package/src/runtime/oauth/providers.ts +0 -38
- package/src/types/api.ts +0 -40
- package/src/types/config.ts +0 -371
- package/src/types/content.ts +0 -66
- package/src/types/index.ts +0 -7
- package/src/types/middleware.ts +0 -63
- package/src/types/page.ts +0 -117
- package/src/types/plugin.ts +0 -34
- package/tsconfig.build.json +0 -10
- package/tsconfig.json +0 -19
- package/vitest.config.ts +0 -33
|
@@ -4,26 +4,28 @@
|
|
|
4
4
|
* Always written to `.cer/app.ts` on every dev/build so consumers
|
|
5
5
|
* automatically receive the latest bootstrap code on plugin update.
|
|
6
6
|
* This file is gitignored and should never be edited directly.
|
|
7
|
-
*
|
|
8
|
-
* @param customColors - Project-specific color families to register in the JIT
|
|
9
|
-
* CSS engine at runtime. Serialized as a JSON literal in the generated source.
|
|
10
7
|
*/
|
|
11
|
-
export function generateAppEntryTemplate(
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
|
|
8
|
+
export function generateAppEntryTemplate(globalImports = []) {
|
|
9
|
+
const integrationImports = [...new Set(globalImports)]
|
|
10
|
+
.map((specifier) => `import '${specifier.replace(/\\/g, '\\\\').replace(/'/g, "\\'")}'`)
|
|
11
|
+
.join('\n');
|
|
15
12
|
return `// AUTO-GENERATED by @jasonshimmy/vite-plugin-cer-app — do not edit.
|
|
16
13
|
// Regenerated automatically on every dev server start and build.
|
|
17
14
|
|
|
18
15
|
import '@jasonshimmy/custom-elements-runtime/css'
|
|
19
|
-
import 'virtual:cer-jit-css'
|
|
16
|
+
${integrationImports}${integrationImports ? '\n' : ''}import 'virtual:cer-jit-css'
|
|
17
|
+
// virtual:cer-jit-init must run before virtual:cer-layouts and virtual:cer-plugins
|
|
18
|
+
// so JIT CSS is enabled before those modules upgrade custom elements via
|
|
19
|
+
// customElements.define(). Static imports execute depth-first in module order,
|
|
20
|
+
// so placing this import here guarantees enableJITCSS() fires first.
|
|
21
|
+
import 'virtual:cer-jit-init'
|
|
20
22
|
import 'virtual:cer-content-components'
|
|
21
23
|
import routes from 'virtual:cer-routes'
|
|
22
24
|
import layouts from 'virtual:cer-layouts'
|
|
23
25
|
import plugins from 'virtual:cer-plugins'
|
|
24
26
|
import { hasLoading, loadingTag } from 'virtual:cer-loading'
|
|
25
27
|
import { hasError, errorTag } from 'virtual:cer-error'
|
|
26
|
-
import { runtimeConfig } from 'virtual:cer-app-config'
|
|
28
|
+
import { runtimeConfig, appConfig } from 'virtual:cer-app-config'
|
|
27
29
|
import {
|
|
28
30
|
component,
|
|
29
31
|
ref,
|
|
@@ -34,7 +36,6 @@ import {
|
|
|
34
36
|
registerBuiltinComponents,
|
|
35
37
|
} from '@jasonshimmy/custom-elements-runtime'
|
|
36
38
|
import { initRouter } from '@jasonshimmy/custom-elements-runtime/router'
|
|
37
|
-
import { enableJITCSS } from '@jasonshimmy/custom-elements-runtime/jit-css'
|
|
38
39
|
import { initRuntimeConfig } from '@jasonshimmy/vite-plugin-cer-app/composables'
|
|
39
40
|
|
|
40
41
|
const _cerProcess = (globalThis).process
|
|
@@ -53,10 +54,9 @@ const _cerRuntimeDev =
|
|
|
53
54
|
|
|
54
55
|
registerBuiltinComponents()
|
|
55
56
|
setDevMode(_cerRuntimeDev)
|
|
56
|
-
${enableJITCSSCall}
|
|
57
57
|
initRuntimeConfig(runtimeConfig)
|
|
58
58
|
|
|
59
|
-
const router = initRouter({ routes })
|
|
59
|
+
const router = initRouter({ ...appConfig.router, routes })
|
|
60
60
|
|
|
61
61
|
// Expose the router globally so useRoute() and navigateTo() can access it
|
|
62
62
|
// from any composable without circular imports.
|
|
@@ -69,10 +69,17 @@ const router = initRouter({ routes })
|
|
|
69
69
|
// the page element directly with the correct attributes (enabling useProps()).
|
|
70
70
|
let _currentPageTag = null
|
|
71
71
|
let _currentPageAttrs = {}
|
|
72
|
+
// Changes only when a page load successfully publishes. Keying the rendered
|
|
73
|
+
// page with this value prevents dynamic/catch-all routes that share one custom
|
|
74
|
+
// element tag from retaining loader-backed state from the previous URL.
|
|
75
|
+
let _currentPageKey = null
|
|
72
76
|
// The pathname this tag was loaded for — used to detect router-internal
|
|
73
77
|
// redirects (e.g. middleware returning '/login') so cer-layout-view falls
|
|
74
78
|
// back to <router-view> when the current route differs from what was pre-loaded.
|
|
75
79
|
let _currentPagePath = null
|
|
80
|
+
// Route chunks and loaders may resolve out of order during rapid navigation or
|
|
81
|
+
// initial hydration. Only the newest request is allowed to publish page state.
|
|
82
|
+
let _pageLoadVersion = 0
|
|
76
83
|
|
|
77
84
|
function _toLoaderAttrs(data) {
|
|
78
85
|
if (data === undefined || data === null || typeof data !== 'object') return {}
|
|
@@ -84,6 +91,7 @@ function _toLoaderAttrs(data) {
|
|
|
84
91
|
// Pre-loads the page module for \`path\`, calls its loader if present, and
|
|
85
92
|
// stores the results so cer-layout-view can pass them as element attributes.
|
|
86
93
|
async function _loadPageForPath(path, options = {}) {
|
|
94
|
+
const loadVersion = ++_pageLoadVersion
|
|
87
95
|
try {
|
|
88
96
|
const url = new URL(path, 'http://x')
|
|
89
97
|
const query = Object.fromEntries(url.searchParams)
|
|
@@ -91,26 +99,29 @@ async function _loadPageForPath(path, options = {}) {
|
|
|
91
99
|
const matched = router.matchRoute(url.pathname)
|
|
92
100
|
const route = matched?.route
|
|
93
101
|
if (!route?.load) {
|
|
102
|
+
if (loadVersion !== _pageLoadVersion) return
|
|
94
103
|
_currentPageTag = null
|
|
95
104
|
_currentPageAttrs = {}
|
|
105
|
+
_currentPageKey = null
|
|
96
106
|
_currentPagePath = url.pathname
|
|
97
107
|
return
|
|
98
108
|
}
|
|
99
109
|
const mod = await route.load()
|
|
100
|
-
|
|
101
|
-
_currentPagePath = url.pathname
|
|
110
|
+
if (loadVersion !== _pageLoadVersion) return
|
|
102
111
|
const params = matched.params ?? {}
|
|
103
112
|
let loaderAttrs = { ...params }
|
|
104
113
|
let loaderData = initialData
|
|
114
|
+
let hasFreshLoaderData = false
|
|
105
115
|
if (typeof mod.loader === 'function' && runLoader) {
|
|
106
116
|
try {
|
|
107
117
|
const data = await mod.loader({ params, query })
|
|
118
|
+
if (loadVersion !== _pageLoadVersion) return
|
|
108
119
|
if (data !== undefined && data !== null) {
|
|
109
120
|
loaderData = data
|
|
110
|
-
|
|
111
|
-
;(globalThis).__CER_DATA__ = data
|
|
121
|
+
hasFreshLoaderData = true
|
|
112
122
|
}
|
|
113
123
|
} catch (err) {
|
|
124
|
+
if (loadVersion !== _pageLoadVersion) return
|
|
114
125
|
// Loader errors are surfaced through currentError so the error boundary
|
|
115
126
|
// (app/error.ts) can display a meaningful message — consistent with how
|
|
116
127
|
// the server-side handler behaves when a loader throws.
|
|
@@ -121,11 +132,21 @@ async function _loadPageForPath(path, options = {}) {
|
|
|
121
132
|
// loader payload in globalThis.__CER_DATA__ / window.__CER_DATA__. Reuse it
|
|
122
133
|
// instead of re-running the loader on the client, then derive primitive attrs
|
|
123
134
|
// from that payload so useProps() stays consistent with usePageData().
|
|
135
|
+
if (loadVersion !== _pageLoadVersion) return
|
|
124
136
|
loaderAttrs = { ...loaderAttrs, ..._toLoaderAttrs(loaderData) }
|
|
137
|
+
if (hasFreshLoaderData) {
|
|
138
|
+
// Publish loader data only after confirming this is still the newest route.
|
|
139
|
+
;(globalThis).__CER_DATA__ = loaderData
|
|
140
|
+
}
|
|
141
|
+
_currentPageTag = mod.default ?? null
|
|
142
|
+
_currentPagePath = url.pathname
|
|
125
143
|
_currentPageAttrs = loaderAttrs
|
|
144
|
+
_currentPageKey = loadVersion
|
|
126
145
|
} catch {
|
|
146
|
+
if (loadVersion !== _pageLoadVersion) return
|
|
127
147
|
_currentPageTag = null
|
|
128
148
|
_currentPageAttrs = {}
|
|
149
|
+
_currentPageKey = null
|
|
129
150
|
_currentPagePath = null
|
|
130
151
|
}
|
|
131
152
|
}
|
|
@@ -143,9 +164,15 @@ const resetError = () => {
|
|
|
143
164
|
|
|
144
165
|
const _push = router.push.bind(router)
|
|
145
166
|
const _replace = router.replace.bind(router)
|
|
167
|
+
// Captures navigation intent synchronously, before route imports resolve or the
|
|
168
|
+
// History API changes the visible URL. Hydration uses this to avoid restoring a
|
|
169
|
+
// stale entry page over an already-requested navigation.
|
|
170
|
+
let _navigationIntent = 0
|
|
146
171
|
|
|
147
172
|
router.push = async (path) => {
|
|
173
|
+
const navigationIntent = ++_navigationIntent
|
|
148
174
|
isNavigating.value = true
|
|
175
|
+
_activateClientRouteRendering()
|
|
149
176
|
currentError.value = null
|
|
150
177
|
try {
|
|
151
178
|
// Clear stale loader data from the previous route before loading the new one.
|
|
@@ -153,29 +180,92 @@ router.push = async (path) => {
|
|
|
153
180
|
// correctly returns null instead of leaking the previous page's data.
|
|
154
181
|
delete (globalThis).__CER_DATA__
|
|
155
182
|
await _loadPageForPath(path)
|
|
183
|
+
if (navigationIntent !== _navigationIntent) return
|
|
156
184
|
await _push(path)
|
|
157
185
|
} catch (err) {
|
|
158
186
|
currentError.value = err instanceof Error ? err.message : String(err)
|
|
159
187
|
} finally {
|
|
160
|
-
isNavigating.value = false
|
|
188
|
+
if (navigationIntent === _navigationIntent) isNavigating.value = false
|
|
161
189
|
}
|
|
162
190
|
}
|
|
163
191
|
|
|
164
192
|
router.replace = async (path) => {
|
|
193
|
+
const navigationIntent = ++_navigationIntent
|
|
165
194
|
isNavigating.value = true
|
|
195
|
+
_activateClientRouteRendering()
|
|
166
196
|
currentError.value = null
|
|
167
197
|
try {
|
|
168
198
|
// Clear stale loader data from the previous route before loading the new one.
|
|
169
199
|
delete (globalThis).__CER_DATA__
|
|
170
200
|
await _loadPageForPath(path)
|
|
201
|
+
if (navigationIntent !== _navigationIntent) return
|
|
171
202
|
await _replace(path)
|
|
172
203
|
} catch (err) {
|
|
173
204
|
currentError.value = err instanceof Error ? err.message : String(err)
|
|
174
205
|
} finally {
|
|
175
|
-
isNavigating.value = false
|
|
206
|
+
if (navigationIntent === _navigationIntent) isNavigating.value = false
|
|
176
207
|
}
|
|
177
208
|
}
|
|
178
209
|
|
|
210
|
+
// Make ordinary internal links participate in client-side routing even when
|
|
211
|
+
// their owning custom element has not hydrated yet. The listener runs in the
|
|
212
|
+
// bubble phase so an upgraded component gets first refusal: handlers such as
|
|
213
|
+
// breadcrumbs can call preventDefault() and perform their own navigation.
|
|
214
|
+
// composedPath() is required because document-level delegation cannot otherwise
|
|
215
|
+
// discover an anchor rendered inside a shadow root.
|
|
216
|
+
document.addEventListener('click', (event) => {
|
|
217
|
+
if (
|
|
218
|
+
event.defaultPrevented ||
|
|
219
|
+
event.button !== 0 ||
|
|
220
|
+
event.metaKey ||
|
|
221
|
+
event.ctrlKey ||
|
|
222
|
+
event.shiftKey ||
|
|
223
|
+
event.altKey
|
|
224
|
+
) return
|
|
225
|
+
|
|
226
|
+
const anchor = event.composedPath().find(
|
|
227
|
+
(target) => target instanceof HTMLAnchorElement,
|
|
228
|
+
)
|
|
229
|
+
if (!anchor || anchor.hasAttribute('download')) return
|
|
230
|
+
if (anchor.getAttribute('aria-disabled') === 'true') return
|
|
231
|
+
|
|
232
|
+
const target = anchor.getAttribute('target')
|
|
233
|
+
if (target && target.toLowerCase() !== '_self') return
|
|
234
|
+
|
|
235
|
+
const href = anchor.getAttribute('href')
|
|
236
|
+
if (!href) return
|
|
237
|
+
|
|
238
|
+
let url
|
|
239
|
+
try {
|
|
240
|
+
url = new URL(href, window.location.href)
|
|
241
|
+
} catch {
|
|
242
|
+
return
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
if (
|
|
246
|
+
(url.protocol !== 'http:' && url.protocol !== 'https:') ||
|
|
247
|
+
url.origin !== window.location.origin
|
|
248
|
+
) return
|
|
249
|
+
|
|
250
|
+
const navigationPath = url.pathname + url.search + url.hash
|
|
251
|
+
|
|
252
|
+
// Same-page anchors do not need a loader or page-tree replacement. Use the
|
|
253
|
+
// underlying runtime router so its configured offset, retries, cancellation,
|
|
254
|
+
// and history state remain consistent with cross-route fragment navigation.
|
|
255
|
+
if (
|
|
256
|
+
url.pathname === window.location.pathname &&
|
|
257
|
+
url.search === window.location.search &&
|
|
258
|
+
url.hash
|
|
259
|
+
) {
|
|
260
|
+
event.preventDefault()
|
|
261
|
+
void _push(url.pathname + url.search + url.hash)
|
|
262
|
+
return
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
event.preventDefault()
|
|
266
|
+
void router.push(navigationPath)
|
|
267
|
+
})
|
|
268
|
+
|
|
179
269
|
// ─── Plugins ─────────────────────────────────────────────────────────────────
|
|
180
270
|
|
|
181
271
|
// Collect plugin-provided values so cer-layout-view can forward them into
|
|
@@ -190,14 +280,30 @@ const _pluginProvides = new Map()
|
|
|
190
280
|
|
|
191
281
|
// ─── <cer-layout-view> ───────────────────────────────────────────────────────
|
|
192
282
|
|
|
193
|
-
// True
|
|
194
|
-
//
|
|
195
|
-
//
|
|
283
|
+
// True while the upgraded SSR/SSG light DOM is the live application. The slot
|
|
284
|
+
// stays active after initial route setup so the framework does not construct a
|
|
285
|
+
// second, duplicate component tree. The first real navigation switches to the
|
|
286
|
+
// client-rendered route tree and releases the server DOM.
|
|
196
287
|
// Declared here (before component()) because customElements.define() upgrades
|
|
197
288
|
// existing DOM elements synchronously, so the render function reads this ref
|
|
198
289
|
// on the very first call — before _doHydrate has a chance to run.
|
|
199
290
|
const _cerHydrating = ref(true)
|
|
200
291
|
|
|
292
|
+
function _activateClientRouteRendering() {
|
|
293
|
+
if (!_cerHydrating.value) return
|
|
294
|
+
_cerHydrating.value = false
|
|
295
|
+
|
|
296
|
+
// The initial SSR tree lives in cer-layout-view's light DOM. Once its slot is
|
|
297
|
+
// no longer used, disconnect it so hidden components, listeners, and reactive
|
|
298
|
+
// state do not remain retained for the lifetime of the application. Queue the
|
|
299
|
+
// cleanup after the reactive render requested above so navigation never
|
|
300
|
+
// exposes a momentarily empty view.
|
|
301
|
+
const host = document.querySelector('cer-layout-view')
|
|
302
|
+
if (host?.childNodes.length) {
|
|
303
|
+
queueMicrotask(() => host.replaceChildren())
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
|
|
201
307
|
component('cer-layout-view', () => {
|
|
202
308
|
// Forward plugin-provided values into the component context so inject() in
|
|
203
309
|
// any descendant component can resolve them by walking up the DOM tree.
|
|
@@ -213,9 +319,9 @@ component('cer-layout-view', () => {
|
|
|
213
319
|
// store.subscribe() synchronously pushes the current route once on
|
|
214
320
|
// subscription. That initial callback is not a real navigation and must not
|
|
215
321
|
// tear down the SSR slot before _doHydrate has pre-loaded the page.
|
|
216
|
-
//
|
|
217
|
-
//
|
|
218
|
-
//
|
|
322
|
+
// Later state pushes update the stored route, but the SSR slot is released
|
|
323
|
+
// only by the wrapped push/replace methods on a real client navigation.
|
|
324
|
+
// initRouter's startup guard replay therefore cannot duplicate the tree.
|
|
219
325
|
unsub = router.subscribe((s) => {
|
|
220
326
|
const _isInitialSubscribePush = !_sawInitialRouteState
|
|
221
327
|
_sawInitialRouteState = true
|
|
@@ -223,7 +329,6 @@ component('cer-layout-view', () => {
|
|
|
223
329
|
current.value = s
|
|
224
330
|
return
|
|
225
331
|
}
|
|
226
|
-
if (_cerHydrating.value) _cerHydrating.value = false
|
|
227
332
|
current.value = s
|
|
228
333
|
})
|
|
229
334
|
})
|
|
@@ -263,7 +368,7 @@ component('cer-layout-view', () => {
|
|
|
263
368
|
// is rendered without stale pre-loaded state.
|
|
264
369
|
const _useDirectRender = _currentPageTag && _currentPagePath === current.value.path
|
|
265
370
|
const pageVnode = _useDirectRender
|
|
266
|
-
? { tag: _currentPageTag, props: { attrs: _currentPageAttrs }, children: [] }
|
|
371
|
+
? { tag: _currentPageTag, key: _currentPageKey, props: { attrs: _currentPageAttrs }, children: [] }
|
|
267
372
|
: { tag: 'router-view', props: {}, children: [] }
|
|
268
373
|
|
|
269
374
|
// Support nested layout chains: meta.layoutChain = ['default', 'admin']
|
|
@@ -306,36 +411,102 @@ for (const plugin of plugins) {
|
|
|
306
411
|
if (typeof window !== 'undefined') {
|
|
307
412
|
const _initMatch = router.matchRoute(window.location.pathname)
|
|
308
413
|
const _hydrateStrategy = _initMatch?.route?.meta?.hydrate ?? 'load'
|
|
414
|
+
const _entryHost = document.querySelector('cer-layout-view')
|
|
415
|
+
const _entryHasServerTree = Boolean(_entryHost && Array.from(_entryHost.childNodes).some(
|
|
416
|
+
(node) => node.nodeType === 1 || Boolean(node.textContent?.trim()),
|
|
417
|
+
))
|
|
418
|
+
const _entryServerTreePath = _entryHost?.getAttribute('data-cer-route')
|
|
419
|
+
const _entryServerTreeMatches = !_entryServerTreePath ||
|
|
420
|
+
decodeURIComponent(_entryServerTreePath) === window.location.pathname
|
|
421
|
+
const _canKeepStaticEntry = _entryHasServerTree && _entryServerTreeMatches
|
|
422
|
+
|
|
423
|
+
if (_hydrateStrategy === 'none' && _canKeepStaticEntry) {
|
|
424
|
+
// Matching static HTML only — leave the page output and loader data
|
|
425
|
+
// untouched. Load its module after the first paint so explicitly
|
|
426
|
+
// interactive descendants (breadcrumbs, TOCs, menus, etc.) can upgrade
|
|
427
|
+
// without putting the static page chunk on the critical rendering path.
|
|
428
|
+
const _loadStaticRouteModule = () => {
|
|
429
|
+
const _load = _initMatch?.route?.load
|
|
430
|
+
if (typeof _load === 'function') {
|
|
431
|
+
void _load().catch((error) => {
|
|
432
|
+
console.error('[cer-app] Failed to activate static route islands:', error)
|
|
433
|
+
})
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
if (typeof requestAnimationFrame === 'function') {
|
|
437
|
+
requestAnimationFrame(() => setTimeout(_loadStaticRouteModule, 0))
|
|
438
|
+
} else {
|
|
439
|
+
setTimeout(_loadStaticRouteModule, 0)
|
|
440
|
+
}
|
|
309
441
|
|
|
310
|
-
|
|
311
|
-
//
|
|
312
|
-
|
|
442
|
+
// The server marks the page host with data-cer-hydrate="none", so upgrading
|
|
443
|
+
// its custom element cannot trigger a second render. Keep __CER_DATA__
|
|
444
|
+
// available for nested static components as they upgrade; the first
|
|
445
|
+
// real client navigation clears it before rendering the destination route.
|
|
446
|
+
// A static host may serve another entry's HTML as its history fallback;
|
|
447
|
+
// that mismatched tree must go through normal client route activation.
|
|
313
448
|
} else {
|
|
314
449
|
const _doHydrate = async () => {
|
|
450
|
+
const _hydrationIntent = _navigationIntent
|
|
315
451
|
const _initPath = window.location.pathname + window.location.search + window.location.hash
|
|
452
|
+
const _hasInitialServerTree = _entryHasServerTree
|
|
453
|
+
const _serverTreePath = _entryServerTreePath
|
|
454
|
+
const _serverTreeMatchesEntry = !_serverTreePath ||
|
|
455
|
+
decodeURIComponent(_serverTreePath) === new URL(_initPath, window.location.origin).pathname
|
|
316
456
|
const _hasInitialLoaderData = Object.prototype.hasOwnProperty.call(globalThis, '__CER_DATA__')
|
|
317
457
|
// Pre-load the page module and run the loader so cer-layout-view renders
|
|
318
458
|
// the page tag directly with loader attrs (enables useProps() on hydration).
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
459
|
+
if (_hydrationIntent === 0) {
|
|
460
|
+
await _loadPageForPath(
|
|
461
|
+
_initPath,
|
|
462
|
+
_hasInitialLoaderData && _serverTreeMatchesEntry
|
|
463
|
+
? { runLoader: false, initialData: (globalThis).__CER_DATA__ }
|
|
464
|
+
: undefined,
|
|
465
|
+
)
|
|
466
|
+
}
|
|
325
467
|
// Only activate the initial route if the URL hasn't changed while we were
|
|
326
468
|
// loading the module asynchronously (e.g. a test or plugin navigated away
|
|
327
469
|
// before _doHydrate finished). Calling _replace with a stale path would
|
|
328
470
|
// override any navigation that happened during the async gap.
|
|
329
471
|
const _currentPath = window.location.pathname + window.location.search + window.location.hash
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
if (_currentPath === _initPath) {
|
|
472
|
+
if (
|
|
473
|
+
_navigationIntent === _hydrationIntent &&
|
|
474
|
+
_currentPath === _initPath
|
|
475
|
+
) {
|
|
335
476
|
// Use the original (unwrapped) replace so isNavigating stays false during
|
|
336
477
|
// the initial paint — the loading component must not flash over pre-rendered content.
|
|
337
478
|
await _replace(_initPath)
|
|
338
479
|
}
|
|
480
|
+
|
|
481
|
+
// An empty SPA shell has no server tree to retain. Middleware may also
|
|
482
|
+
// redirect either while the initial chunk loads or while _replace runs,
|
|
483
|
+
// making the SSR tree stale. This decision deliberately lives outside
|
|
484
|
+
// the URL-stability guard above: a newer URL must not be overwritten, but
|
|
485
|
+
// its resolved route still needs to replace the old server-rendered tree.
|
|
486
|
+
const _requestedInitialPath = new URL(_initPath, window.location.origin).pathname
|
|
487
|
+
const _resolvedInitialPath = router.getCurrent().path
|
|
488
|
+
const _urlLeftInitialEntry = _currentPath !== _initPath
|
|
489
|
+
if (
|
|
490
|
+
!_hasInitialServerTree ||
|
|
491
|
+
!_serverTreeMatchesEntry ||
|
|
492
|
+
_urlLeftInitialEntry ||
|
|
493
|
+
_resolvedInitialPath !== _requestedInitialPath
|
|
494
|
+
) {
|
|
495
|
+
if (
|
|
496
|
+
!_serverTreeMatchesEntry ||
|
|
497
|
+
_urlLeftInitialEntry ||
|
|
498
|
+
_resolvedInitialPath !== _requestedInitialPath
|
|
499
|
+
) {
|
|
500
|
+
delete (globalThis).__CER_DATA__
|
|
501
|
+
}
|
|
502
|
+
if (
|
|
503
|
+
_navigationIntent === _hydrationIntent &&
|
|
504
|
+
_currentPagePath !== _resolvedInitialPath
|
|
505
|
+
) {
|
|
506
|
+
await _loadPageForPath(_resolvedInitialPath)
|
|
507
|
+
}
|
|
508
|
+
_activateClientRouteRendering()
|
|
509
|
+
}
|
|
339
510
|
// The client entry marks the already-rendered entry URL so generated
|
|
340
511
|
// route middleware can skip the browser router's startup replay once.
|
|
341
512
|
// Clear any leftover flag after the first hydrated route commits so later
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app-template.js","sourceRoot":"","sources":["../../src/runtime/app-template.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"app-template.js","sourceRoot":"","sources":["../../src/runtime/app-template.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,MAAM,UAAU,wBAAwB,CAAC,gBAAmC,EAAE;IAC5E,MAAM,kBAAkB,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,aAAa,CAAC,CAAC;SACnD,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,WAAW,SAAS,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC;SACvF,IAAI,CAAC,IAAI,CAAC,CAAA;IACb,OAAO;;;;EAIP,kBAAkB,GAAG,kBAAkB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkhBpD,CAAA;AACD,CAAC"}
|
|
@@ -25,4 +25,8 @@ export type { LocaleComposable } from './use-locale.js';
|
|
|
25
25
|
export { queryContent, QueryBuilder } from './use-content.js';
|
|
26
26
|
export { useContentSearch } from './use-content-search.js';
|
|
27
27
|
export type { UseContentSearchReturn } from './use-content-search.js';
|
|
28
|
+
export { defineContentPageLoader, normalizeContentPath, useContentBreadcrumbs, useContentHeadings, useContentSeo, } from './use-content-page.js';
|
|
29
|
+
export type { ContentBreadcrumb, ContentBreadcrumbOptions, ContentPageData, ContentPageLoaderOptions, ContentSeoOptions, } from './use-content-page.js';
|
|
30
|
+
export { useActiveHeadings } from './use-active-headings.js';
|
|
31
|
+
export type { ActiveHeadingsOptions } from './use-active-headings.js';
|
|
28
32
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/runtime/composables/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAA;AAClG,YAAY,EAAE,SAAS,EAAE,MAAM,eAAe,CAAA;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAC3C,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAA;AACnG,YAAY,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAA;AAC7G,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAA;AACzD,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAA;AACtE,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAC9C,YAAY,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AACrD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAC3C,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAC/D,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAC7C,YAAY,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAA;AACzE,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AACvC,YAAY,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAC7D,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AACzC,YAAY,EAAE,eAAe,EAAE,cAAc,EAAE,cAAc,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAA;AAC7G,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AACzC,YAAY,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAC3C,YAAY,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAA;AACvD,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;AAC1D,YAAY,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/runtime/composables/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAA;AAClG,YAAY,EAAE,SAAS,EAAE,MAAM,eAAe,CAAA;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAC3C,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAA;AACnG,YAAY,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAA;AAC7G,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAA;AACzD,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAA;AACtE,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAC9C,YAAY,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AACrD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAC3C,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAC/D,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAC7C,YAAY,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAA;AACzE,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AACvC,YAAY,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAC7D,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AACzC,YAAY,EAAE,eAAe,EAAE,cAAc,EAAE,cAAc,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAA;AAC7G,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AACzC,YAAY,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAC3C,YAAY,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAA;AACvD,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;AAC1D,YAAY,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAA;AACrE,OAAO,EACL,uBAAuB,EACvB,oBAAoB,EACpB,qBAAqB,EACrB,kBAAkB,EAClB,aAAa,GACd,MAAM,uBAAuB,CAAA;AAC9B,YAAY,EACV,iBAAiB,EACjB,wBAAwB,EACxB,eAAe,EACf,wBAAwB,EACxB,iBAAiB,GAClB,MAAM,uBAAuB,CAAA;AAC9B,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AAC5D,YAAY,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAA"}
|
|
@@ -15,4 +15,6 @@ export { useState } from './use-state.js';
|
|
|
15
15
|
export { useLocale } from './use-locale.js';
|
|
16
16
|
export { queryContent, QueryBuilder } from './use-content.js';
|
|
17
17
|
export { useContentSearch } from './use-content-search.js';
|
|
18
|
+
export { defineContentPageLoader, normalizeContentPath, useContentBreadcrumbs, useContentHeadings, useContentSeo, } from './use-content-page.js';
|
|
19
|
+
export { useActiveHeadings } from './use-active-headings.js';
|
|
18
20
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/runtime/composables/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAA;AAElG,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAC3C,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAA;AAEnG,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAA;AACzD,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAA;AACtE,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAE9C,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAE3C,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAE7C,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AAEvC,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAEzC,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAEzC,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAE3C,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/runtime/composables/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAA;AAElG,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAC3C,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAA;AAEnG,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAA;AACzD,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAA;AACtE,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAE9C,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAE3C,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAE7C,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AAEvC,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAEzC,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAEzC,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAE3C,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;AAE1D,OAAO,EACL,uBAAuB,EACvB,oBAAoB,EACpB,qBAAqB,EACrB,kBAAkB,EAClB,aAAa,GACd,MAAM,uBAAuB,CAAA;AAQ9B,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { ContentHeading } from '../../types/content.js';
|
|
2
|
+
type HeadingSource = readonly ContentHeading[] | {
|
|
3
|
+
value: readonly ContentHeading[];
|
|
4
|
+
};
|
|
5
|
+
export interface ActiveHeadingsOptions {
|
|
6
|
+
/** DOM root containing the rendered headings. Defaults to document. */
|
|
7
|
+
root?: ParentNode | (() => ParentNode | null);
|
|
8
|
+
/** Sticky-header offset in pixels. Defaults to 0. */
|
|
9
|
+
offset?: number;
|
|
10
|
+
/** IntersectionObserver root, when observing inside a scroll container. */
|
|
11
|
+
observerRoot?: Element | null;
|
|
12
|
+
/** Override the observer margin. */
|
|
13
|
+
rootMargin?: string;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Tracks visible content headings with one IntersectionObserver. This avoids
|
|
17
|
+
* scroll-event layout reads and works with document, light-DOM, and shadow roots.
|
|
18
|
+
*/
|
|
19
|
+
export declare function useActiveHeadings(source: HeadingSource, options?: ActiveHeadingsOptions): {
|
|
20
|
+
activeIds: any;
|
|
21
|
+
isActive: (id: string) => any;
|
|
22
|
+
};
|
|
23
|
+
export {};
|
|
24
|
+
//# sourceMappingURL=use-active-headings.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-active-headings.d.ts","sourceRoot":"","sources":["../../../src/runtime/composables/use-active-headings.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAA;AAE5D,KAAK,aAAa,GAAG,SAAS,cAAc,EAAE,GAAG;IAAE,KAAK,EAAE,SAAS,cAAc,EAAE,CAAA;CAAE,CAAA;AAErF,MAAM,WAAW,qBAAqB;IACpC,uEAAuE;IACvE,IAAI,CAAC,EAAE,UAAU,GAAG,CAAC,MAAM,UAAU,GAAG,IAAI,CAAC,CAAA;IAC7C,qDAAqD;IACrD,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,2EAA2E;IAC3E,YAAY,CAAC,EAAE,OAAO,GAAG,IAAI,CAAA;IAC7B,oCAAoC;IACpC,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAiBD;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,aAAa,EAAE,OAAO,GAAE,qBAA0B;;mBA2FzE,MAAM;EAExB"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { nextTick, ref, useOnConnected, watch } from '@jasonshimmy/custom-elements-runtime';
|
|
2
|
+
function sourceValue(source) {
|
|
3
|
+
return Array.isArray(source)
|
|
4
|
+
? source
|
|
5
|
+
: source.value;
|
|
6
|
+
}
|
|
7
|
+
function resolveRoot(root) {
|
|
8
|
+
if (typeof root === 'function')
|
|
9
|
+
return root();
|
|
10
|
+
return root ?? (typeof document !== 'undefined' ? document : null);
|
|
11
|
+
}
|
|
12
|
+
function escapeAttribute(value) {
|
|
13
|
+
return value.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Tracks visible content headings with one IntersectionObserver. This avoids
|
|
17
|
+
* scroll-event layout reads and works with document, light-DOM, and shadow roots.
|
|
18
|
+
*/
|
|
19
|
+
export function useActiveHeadings(source, options = {}) {
|
|
20
|
+
const activeIds = ref([]);
|
|
21
|
+
const intersecting = new Set();
|
|
22
|
+
const headingTops = new Map();
|
|
23
|
+
useOnConnected(() => {
|
|
24
|
+
let observer = null;
|
|
25
|
+
let observationRevision = 0;
|
|
26
|
+
let disposed = false;
|
|
27
|
+
const observe = () => {
|
|
28
|
+
observer?.disconnect();
|
|
29
|
+
intersecting.clear();
|
|
30
|
+
headingTops.clear();
|
|
31
|
+
activeIds.value = [];
|
|
32
|
+
const headings = sourceValue(source);
|
|
33
|
+
const root = resolveRoot(options.root);
|
|
34
|
+
if (!root || headings.length === 0)
|
|
35
|
+
return;
|
|
36
|
+
// Establish a useful state immediately. IntersectionObserver callbacks
|
|
37
|
+
// are asynchronous, and on an entry navigation every heading may begin
|
|
38
|
+
// below the narrowed activation band even though the first section is
|
|
39
|
+
// the section the reader is approaching.
|
|
40
|
+
activeIds.value = [headings[0].id];
|
|
41
|
+
if (typeof IntersectionObserver === 'undefined') {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
observer = new IntersectionObserver((entries) => {
|
|
45
|
+
for (const entry of entries) {
|
|
46
|
+
const id = entry.target.id;
|
|
47
|
+
if (!id)
|
|
48
|
+
continue;
|
|
49
|
+
const top = entry.boundingClientRect?.top;
|
|
50
|
+
if (Number.isFinite(top))
|
|
51
|
+
headingTops.set(id, top);
|
|
52
|
+
if (entry.isIntersecting)
|
|
53
|
+
intersecting.add(id);
|
|
54
|
+
else
|
|
55
|
+
intersecting.delete(id);
|
|
56
|
+
}
|
|
57
|
+
const orderedIds = sourceValue(source).map((heading) => heading.id);
|
|
58
|
+
const visibleIds = orderedIds.filter((id) => intersecting.has(id));
|
|
59
|
+
if (visibleIds.length > 0) {
|
|
60
|
+
activeIds.value = visibleIds;
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
// When the activation band lies in the gap between headings, keep the
|
|
64
|
+
// most recently passed section selected. At the top of the article,
|
|
65
|
+
// where no heading has crossed the sticky-header line, select the first
|
|
66
|
+
// section instead of presenting an unexplained empty state.
|
|
67
|
+
const activationTop = options.offset ?? 0;
|
|
68
|
+
let fallback = orderedIds[0];
|
|
69
|
+
for (const id of orderedIds) {
|
|
70
|
+
const top = headingTops.get(id);
|
|
71
|
+
if (top !== undefined && top <= activationTop)
|
|
72
|
+
fallback = id;
|
|
73
|
+
}
|
|
74
|
+
activeIds.value = fallback ? [fallback] : [];
|
|
75
|
+
}, {
|
|
76
|
+
root: options.observerRoot ?? null,
|
|
77
|
+
rootMargin: options.rootMargin ?? `-${options.offset ?? 0}px 0px -60% 0px`,
|
|
78
|
+
threshold: [0, 1],
|
|
79
|
+
});
|
|
80
|
+
for (const heading of headings) {
|
|
81
|
+
const element = root.querySelector(`[id="${escapeAttribute(heading.id)}"]`);
|
|
82
|
+
if (element)
|
|
83
|
+
observer.observe(element);
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
const scheduleObserve = () => {
|
|
87
|
+
const revision = ++observationRevision;
|
|
88
|
+
// A child receives its new heading props while the parent page is still
|
|
89
|
+
// being patched. Waiting for the runtime's DOM queue prevents querying
|
|
90
|
+
// the outgoing article and permanently observing stale heading nodes.
|
|
91
|
+
void nextTick().then(() => {
|
|
92
|
+
if (!disposed && revision === observationRevision)
|
|
93
|
+
observe();
|
|
94
|
+
});
|
|
95
|
+
};
|
|
96
|
+
scheduleObserve();
|
|
97
|
+
const stop = watch(() => sourceValue(source), scheduleObserve);
|
|
98
|
+
return () => {
|
|
99
|
+
disposed = true;
|
|
100
|
+
observationRevision += 1;
|
|
101
|
+
stop?.();
|
|
102
|
+
observer?.disconnect();
|
|
103
|
+
intersecting.clear();
|
|
104
|
+
headingTops.clear();
|
|
105
|
+
};
|
|
106
|
+
});
|
|
107
|
+
return {
|
|
108
|
+
activeIds,
|
|
109
|
+
isActive: (id) => activeIds.value.includes(id),
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=use-active-headings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-active-headings.js","sourceRoot":"","sources":["../../../src/runtime/composables/use-active-headings.ts"],"names":[],"mappings":"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"}
|