create-jen-app 1.2.3 → 1.2.4
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/colors.js +0 -17
- package/dist/create.js +5 -17
- package/dist/generator.js +14 -31
- package/dist/index.js +6 -1
- package/package.json +1 -1
- package/templates/ssr-isr/README.md +77 -0
- package/templates/ssr-isr/build.js +118 -0
- package/templates/ssr-isr/jen.config.ts +109 -0
- package/templates/ssr-isr/jenjs.d.ts +22 -0
- package/templates/ssr-isr/lib/api/(hello).js +9 -0
- package/templates/ssr-isr/lib/auth/cookie-utils.js +79 -0
- package/templates/ssr-isr/lib/auth/index.js +2 -0
- package/templates/ssr-isr/lib/auth/jwt.js +57 -0
- package/templates/ssr-isr/lib/auth/session.js +92 -0
- package/templates/ssr-isr/lib/build/asset-hashing.d.ts +10 -0
- package/templates/ssr-isr/lib/build/asset-hashing.js +25 -0
- package/templates/ssr-isr/lib/build/asset-manifest.d.ts +11 -0
- package/templates/ssr-isr/lib/build/asset-manifest.js +21 -0
- package/templates/{static → ssr-isr}/lib/build/build.d.ts +1 -1
- package/templates/ssr-isr/lib/build/build.js +141 -0
- package/templates/{static → ssr-isr}/lib/build/island-hydration.d.ts +8 -5
- package/templates/ssr-isr/lib/build/island-hydration.js +44 -0
- package/templates/ssr-isr/lib/build/minifier.d.ts +20 -0
- package/templates/ssr-isr/lib/build/minifier.js +46 -0
- package/templates/ssr-isr/lib/build/page-renderer.d.ts +17 -0
- package/templates/ssr-isr/lib/build/page-renderer.js +28 -0
- package/templates/ssr-isr/lib/build/production-build.d.ts +10 -0
- package/templates/ssr-isr/lib/build/production-build.js +13 -0
- package/templates/ssr-isr/lib/build/ssg-pipeline.d.ts +15 -0
- package/templates/ssr-isr/lib/build/ssg-pipeline.js +113 -0
- package/templates/ssr-isr/lib/build-tools/build-site.js +36 -0
- package/templates/ssr-isr/lib/cache/index.js +10 -0
- package/templates/ssr-isr/lib/cache/memory.js +40 -0
- package/templates/ssr-isr/lib/cache/redis.js +61 -0
- package/templates/ssr-isr/lib/cli/banner.js +28 -0
- package/templates/ssr-isr/lib/cli/templates/ssg/jen.config.js +32 -0
- package/templates/ssr-isr/lib/cli/templates/ssg/site/index.js +9 -0
- package/templates/ssr-isr/lib/cli/templates/ssr/jen.config.js +32 -0
- package/templates/ssr-isr/lib/cli/templates/ssr/site/index.js +9 -0
- package/templates/ssr-isr/lib/compilers/esbuild-plugins.js +111 -0
- package/templates/ssr-isr/lib/compilers/svelte.js +44 -0
- package/templates/ssr-isr/lib/compilers/vue.js +90 -0
- package/templates/ssr-isr/lib/core/http.js +71 -0
- package/templates/ssr-isr/lib/core/middleware-hooks.js +97 -0
- package/templates/ssr-isr/lib/core/paths.js +39 -0
- package/templates/ssr-isr/lib/core/routes/match.js +47 -0
- package/templates/ssr-isr/lib/core/routes/scan.js +190 -0
- package/templates/ssr-isr/lib/core/types.js +1 -0
- package/templates/ssr-isr/lib/css/compiler.js +74 -0
- package/templates/ssr-isr/lib/db/connector.js +42 -0
- package/templates/ssr-isr/lib/db/drivers/jdb.js +44 -0
- package/templates/ssr-isr/lib/db/drivers/sql.js +182 -0
- package/templates/ssr-isr/lib/db/index.js +48 -0
- package/templates/ssr-isr/lib/db/types.js +1 -0
- package/templates/ssr-isr/lib/graphql/index.js +52 -0
- package/templates/ssr-isr/lib/graphql/resolvers.js +25 -0
- package/templates/ssr-isr/lib/graphql/schema.js +35 -0
- package/templates/ssr-isr/lib/i18n/en.json +4 -0
- package/templates/ssr-isr/lib/i18n/es.json +4 -0
- package/templates/ssr-isr/lib/i18n/index.js +15 -0
- package/templates/ssr-isr/lib/import/jen-import.js +161 -0
- package/templates/ssr-isr/lib/index.js +116 -0
- package/templates/ssr-isr/lib/jdb/engine.js +275 -0
- package/templates/ssr-isr/lib/jdb/index.js +34 -0
- package/templates/ssr-isr/lib/jdb/types.js +1 -0
- package/templates/ssr-isr/lib/jdb/utils.js +176 -0
- package/templates/{static → ssr-isr}/lib/middleware/builtins/body-parser.js +0 -17
- package/templates/ssr-isr/lib/middleware/builtins/cors.js +54 -0
- package/templates/{static → ssr-isr}/lib/middleware/builtins/logger.js +0 -17
- package/templates/{static → ssr-isr}/lib/middleware/builtins/rate-limit.js +0 -17
- package/templates/{static → ssr-isr}/lib/middleware/builtins/request-id.js +0 -17
- package/templates/{static → ssr-isr}/lib/middleware/builtins/security-headers.js +0 -17
- package/templates/ssr-isr/lib/middleware/context.js +124 -0
- package/templates/{static → ssr-isr}/lib/middleware/decorators.js +0 -17
- package/templates/{static → ssr-isr}/lib/middleware/errors/handler.js +0 -17
- package/templates/ssr-isr/lib/middleware/errors/http-error.js +10 -0
- package/templates/ssr-isr/lib/middleware/kernel.js +85 -0
- package/templates/ssr-isr/lib/middleware/pipeline.js +148 -0
- package/templates/ssr-isr/lib/middleware/registry.js +85 -0
- package/templates/ssr-isr/lib/middleware/response.js +107 -0
- package/templates/ssr-isr/lib/middleware/types.d.ts +1 -0
- package/templates/ssr-isr/lib/middleware/types.js +1 -0
- package/templates/ssr-isr/lib/middleware/utils/matcher.js +13 -0
- package/templates/{static → ssr-isr}/lib/native/bundle.js +0 -17
- package/templates/{static → ssr-isr}/lib/native/dev-server.js +0 -17
- package/templates/{static → ssr-isr}/lib/native/index.js +0 -17
- package/templates/{static → ssr-isr}/lib/native/optimizer.js +0 -17
- package/templates/ssr-isr/lib/native/style-compiler.js +19 -0
- package/templates/ssr-isr/lib/plugin/loader.js +36 -0
- package/templates/ssr-isr/lib/runtime/client-runtime.js +25 -0
- package/templates/ssr-isr/lib/runtime/hmr.js +59 -0
- package/templates/ssr-isr/lib/runtime/hydrate.js +55 -0
- package/templates/ssr-isr/lib/runtime/island-hydration-client.js +146 -0
- package/templates/ssr-isr/lib/runtime/islands.js +110 -0
- package/templates/ssr-isr/lib/runtime/render.js +244 -0
- package/templates/ssr-isr/lib/server/api-routes.js +237 -0
- package/templates/ssr-isr/lib/server/api.js +108 -0
- package/templates/ssr-isr/lib/server/app.js +438 -0
- package/templates/ssr-isr/lib/server/runtimeServe.js +169 -0
- package/templates/ssr-isr/lib/server/ssr.js +202 -0
- package/templates/ssr-isr/lib/shared/log.js +64 -0
- package/templates/ssr-isr/package.json +23 -0
- package/templates/ssr-isr/server.js +128 -0
- package/templates/ssr-isr/site/pages/(index).tsx +11 -0
- package/templates/ssr-isr/site/styles/global.scss +37 -0
- package/templates/ssr-isr/tsconfig.json +39 -0
- package/templates/static/build.js +30 -18
- package/templates/static/jen.config.ts +0 -18
- package/templates/static/jenjs.d.ts +0 -18
- package/templates/static/lib/api/(hello).js +0 -17
- package/templates/static/lib/api/examples/files/[...slug].js +22 -0
- package/templates/static/lib/api/examples/hello.js +11 -0
- package/templates/static/lib/api/examples/posts/[id].js +37 -0
- package/templates/static/lib/api/examples/posts.js +37 -0
- package/templates/static/lib/api/examples/search.js +23 -0
- package/templates/static/lib/api/index.js +41 -0
- package/templates/static/lib/api/loader.js +234 -0
- package/templates/static/lib/api/router.js +259 -0
- package/templates/static/lib/assets/types.js +1 -0
- package/templates/static/lib/auth/cookie-utils.js +3 -16
- package/templates/static/lib/auth/index.js +0 -17
- package/templates/static/lib/auth/jwt.js +0 -17
- package/templates/static/lib/auth/session.js +0 -17
- package/templates/static/lib/build/asset-hashing.js +44 -36
- package/templates/static/lib/build/asset-manifest.js +16 -33
- package/templates/static/lib/build/build.js +270 -125
- package/templates/static/lib/build/bundle-analyzer-ui.js +417 -0
- package/templates/static/lib/build/bundle-analyzer.js +945 -0
- package/templates/static/lib/build/code-splitter.js +194 -0
- package/templates/static/lib/build/feature-analyzer.js +190 -0
- package/templates/static/lib/build/feature-gate.js +257 -0
- package/templates/static/lib/build/island-hydration.js +17 -35
- package/templates/static/lib/build/lazy-loader.js +322 -0
- package/templates/static/lib/build/minifier.js +40 -59
- package/templates/static/lib/build/page-renderer.js +23 -40
- package/templates/static/lib/build/production-build.js +9 -26
- package/templates/static/lib/build/rust-hashing.js +71 -0
- package/templates/static/lib/build/script-optimizer.js +285 -0
- package/templates/static/lib/build/ssg-pipeline.js +100 -106
- package/templates/static/lib/build/vercel-output.js +298 -0
- package/templates/static/lib/build-tools/build-site.js +0 -17
- package/templates/static/lib/cache/index.js +0 -17
- package/templates/static/lib/cache/memory.js +0 -17
- package/templates/static/lib/cache/redis.js +0 -17
- package/templates/static/lib/cli/banner.js +0 -17
- package/templates/static/lib/cli/templates/ssg/jen.config.js +0 -17
- package/templates/static/lib/cli/templates/ssr/jen.config.js +0 -17
- package/templates/static/lib/client/Image.js +42 -0
- package/templates/static/lib/client/Link.js +190 -0
- package/templates/static/lib/client/PWA.js +46 -0
- package/templates/static/lib/client/Seo.js +97 -0
- package/templates/static/lib/client/index.js +9 -0
- package/templates/static/lib/client/useNavigation.js +25 -0
- package/templates/static/lib/client/useRouter.js +64 -0
- package/templates/static/lib/client-routing/Link.js +17 -0
- package/templates/static/lib/client-routing/index.js +19 -0
- package/templates/static/lib/client-routing/router.js +151 -0
- package/templates/static/lib/client-routing/signal.js +147 -0
- package/templates/static/lib/compilers/esbuild-plugins.js +0 -17
- package/templates/static/lib/compilers/svelte.js +0 -17
- package/templates/static/lib/compilers/vue.js +0 -17
- package/templates/static/lib/core/config.js +0 -17
- package/templates/static/lib/core/feature-guard.js +136 -0
- package/templates/static/lib/core/features.js +99 -0
- package/templates/static/lib/core/http.js +0 -17
- package/templates/static/lib/core/layouts/index.js +10 -0
- package/templates/static/lib/core/layouts/render.js +158 -0
- package/templates/static/lib/core/layouts/scan.js +112 -0
- package/templates/static/lib/core/layouts/types.js +1 -0
- package/templates/static/lib/core/lifecycle.js +129 -0
- package/templates/static/lib/core/loader-schema.js +81 -0
- package/templates/static/lib/core/middleware-hooks.js +0 -17
- package/templates/static/lib/core/paths.js +0 -17
- package/templates/static/lib/core/routes/advanced.js +114 -0
- package/templates/static/lib/core/routes/handlers.js +181 -0
- package/templates/static/lib/core/routes/match.js +89 -17
- package/templates/static/lib/core/routes/orchestrator.js +171 -0
- package/templates/static/lib/core/routes/rendering-config.js +131 -0
- package/templates/static/lib/core/routes/scan.js +0 -17
- package/templates/static/lib/core/types.js +0 -17
- package/templates/static/lib/css/compiler.js +1 -18
- package/templates/static/lib/data-fetching/cache.js +223 -0
- package/templates/static/lib/data-fetching/client.js +202 -0
- package/templates/static/lib/data-fetching/feature-guard.js +29 -0
- package/templates/static/lib/data-fetching/graphql.js +265 -0
- package/templates/static/lib/data-fetching/index.js +57 -0
- package/templates/static/lib/data-fetching/rest.js +256 -0
- package/templates/static/lib/data-fetching/server.js +182 -0
- package/templates/static/lib/data-fetching/types.js +5 -0
- package/templates/static/lib/db/connector.js +0 -17
- package/templates/static/lib/db/drivers/jdb.js +0 -17
- package/templates/static/lib/db/drivers/sql.js +0 -17
- package/templates/static/lib/db/index.js +0 -17
- package/templates/static/lib/db/types.js +0 -17
- package/templates/static/lib/devtools/component-tree.js +106 -0
- package/templates/static/lib/devtools/devtools.js +638 -0
- package/templates/static/lib/devtools/event-bus.js +29 -0
- package/templates/static/lib/devtools/event-logger.js +67 -0
- package/templates/static/lib/devtools/index.js +9 -0
- package/templates/static/lib/devtools/integration.js +149 -0
- package/templates/static/lib/devtools/performance.js +84 -0
- package/templates/static/lib/devtools/persistence.js +57 -0
- package/templates/static/lib/devtools/plugins.js +97 -0
- package/templates/static/lib/devtools/search.js +89 -0
- package/templates/static/lib/devtools/ui.js +769 -0
- package/templates/static/lib/features/api/handler.js +10 -0
- package/templates/static/lib/features/api/index.js +5 -0
- package/templates/static/lib/features/api/types.js +4 -0
- package/templates/static/lib/features/middleware/compiled.js +7 -0
- package/templates/static/lib/features/middleware/index.js +5 -0
- package/templates/static/lib/features/middleware/types.js +4 -0
- package/templates/static/lib/fonts/index.js +46 -0
- package/templates/static/lib/fonts/inject.js +125 -0
- package/templates/static/lib/fonts/loader.js +196 -0
- package/templates/static/lib/fonts/types.js +1 -0
- package/templates/static/lib/graphql/index.js +1 -18
- package/templates/static/lib/graphql/resolvers.js +20 -13
- package/templates/static/lib/graphql/schema.js +0 -17
- package/templates/static/lib/i18n/index.js +7 -19
- package/templates/static/lib/import/jen-import.js +1 -18
- package/templates/static/lib/index.js +79 -125
- package/templates/static/lib/jdb/engine.js +0 -17
- package/templates/static/lib/jdb/index.js +1 -18
- package/templates/static/lib/jdb/types.js +0 -17
- package/templates/static/lib/jdb/utils.js +0 -17
- package/templates/static/lib/middleware/builtins/cors.js +3 -16
- package/templates/static/lib/middleware/context.js +0 -17
- package/templates/static/lib/middleware/kernel.js +117 -25
- package/templates/static/lib/middleware/pipeline.js +0 -17
- package/templates/static/lib/middleware/registry.js +0 -17
- package/templates/static/lib/middleware/response.js +0 -17
- package/templates/static/lib/plugin/examples/analytics-plugin.js +183 -0
- package/templates/static/lib/plugin/examples/cdn-upload-plugin.js +94 -0
- package/templates/static/lib/plugin/loader.js +0 -17
- package/templates/static/lib/plugin/plugin-manager.js +177 -0
- package/templates/static/lib/plugin/types.js +28 -0
- package/templates/static/lib/runtime/client-runtime.js +0 -17
- package/templates/static/lib/runtime/hmr.js +0 -17
- package/templates/static/lib/runtime/hydrate.js +0 -17
- package/templates/static/lib/runtime/island-hydration-client.js +0 -17
- package/templates/static/lib/runtime/islands.js +0 -17
- package/templates/static/lib/runtime/render.js +208 -50
- package/templates/static/lib/security/security-config.js +60 -0
- package/templates/static/lib/security/security-middleware.js +229 -0
- package/templates/static/lib/server/api-routes.js +153 -43
- package/templates/static/lib/server/api.js +0 -17
- package/templates/static/lib/server/app.js +539 -223
- package/templates/static/lib/server/isr.js +365 -0
- package/templates/static/lib/server/runtimeServe.js +31 -24
- package/templates/static/lib/server/ssr.js +98 -22
- package/templates/static/lib/server-actions/handler.js +180 -0
- package/templates/static/lib/server-actions/index.js +19 -0
- package/templates/static/lib/server-actions/middleware.js +146 -0
- package/templates/static/lib/server-actions/scan.js +152 -0
- package/templates/static/lib/server-actions/types.js +1 -0
- package/templates/static/lib/server-actions/validators.js +156 -0
- package/templates/static/lib/shared/log.js +19 -20
- package/templates/static/lib/telemetry/api/rate-limiter.js +32 -0
- package/templates/static/lib/telemetry/api/validator.js +67 -0
- package/templates/static/lib/telemetry/client.js +121 -0
- package/templates/static/lib/telemetry/tests/rate-limiter.test.js +46 -0
- package/templates/static/lib/telemetry/tests/validator.test.js +62 -0
- package/templates/static/lib/vendor/glob/glob.js +4766 -0
- package/templates/static/lib/vendor/preact/LICENSE +21 -0
- package/templates/static/lib/vendor/preact/preact.module.js +797 -0
- package/templates/static/lib/vendor/sass/sass.node.mjs +212 -0
- package/templates/static/package.json +4 -0
- package/templates/static/server.js +22 -22
- package/templates/static/site/(home).tsx +0 -18
- package/templates/static/tsconfig.json +5 -1
- package/templates/static/.esbuild/jen.config.js +0 -19
- package/templates/static/lib/build/asset-hashing.d.ts +0 -10
- package/templates/static/lib/build/asset-manifest.d.ts +0 -11
- package/templates/static/lib/build/minifier.d.ts +0 -20
- package/templates/static/lib/build/page-renderer.d.ts +0 -17
- package/templates/static/lib/build/production-build.d.ts +0 -10
- package/templates/static/lib/build/ssg-pipeline.d.ts +0 -15
- package/templates/static/lib/middleware/errors/http-error.js +0 -27
- package/templates/static/lib/middleware/types.js +0 -18
- package/templates/static/lib/middleware/utils/matcher.js +0 -30
- package/templates/static/lib/native/style-compiler.js +0 -36
- /package/templates/{static → ssr-isr}/lib/api/(hello).d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/auth/cookie-utils.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/auth/index.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/auth/jwt.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/auth/session.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/build-tools/build-site.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/cache/index.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/cache/memory.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/cache/redis.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/cli/banner.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/cli/templates/ssg/jen.config.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/cli/templates/ssg/site/index.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/cli/templates/ssr/jen.config.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/cli/templates/ssr/site/index.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/compilers/esbuild-plugins.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/compilers/svelte.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/compilers/vue.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/core/config.d.ts +0 -0
- /package/templates/{static/lib/middleware/types.d.ts → ssr-isr/lib/core/config.js} +0 -0
- /package/templates/{static → ssr-isr}/lib/core/http.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/core/middleware-hooks.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/core/paths.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/core/routes/match.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/core/routes/scan.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/core/types.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/css/compiler.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/db/connector.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/db/drivers/jdb.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/db/drivers/sql.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/db/index.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/db/types.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/graphql/index.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/graphql/resolvers.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/graphql/schema.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/i18n/index.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/import/jen-import.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/index.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/jdb/engine.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/jdb/index.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/jdb/types.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/jdb/utils.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/middleware/builtins/body-parser.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/middleware/builtins/cors.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/middleware/builtins/logger.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/middleware/builtins/rate-limit.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/middleware/builtins/request-id.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/middleware/builtins/security-headers.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/middleware/context.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/middleware/decorators.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/middleware/errors/handler.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/middleware/errors/http-error.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/middleware/kernel.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/middleware/pipeline.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/middleware/registry.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/middleware/response.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/middleware/utils/matcher.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/native/bundle.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/native/dev-server.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/native/index.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/native/optimizer.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/native/style-compiler.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/plugin/loader.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/runtime/client-runtime.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/runtime/hmr.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/runtime/hydrate.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/runtime/island-hydration-client.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/runtime/islands.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/runtime/render.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/server/api-routes.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/server/api.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/server/app.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/server/runtimeServe.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/server/ssr.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/shared/log.d.ts +0 -0
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import { matchRoute } from "./match.js";
|
|
2
|
+
import {
|
|
3
|
+
getAdvancedRouteConfig,
|
|
4
|
+
validateQueryParams,
|
|
5
|
+
processQueryParams,
|
|
6
|
+
} from "./advanced.js";
|
|
7
|
+
import {
|
|
8
|
+
getRedirect,
|
|
9
|
+
getNotFoundHandler,
|
|
10
|
+
send404,
|
|
11
|
+
sendRedirect,
|
|
12
|
+
createDefault404Html,
|
|
13
|
+
} from "./handlers.js";
|
|
14
|
+
import { log } from "../../shared/log.js";
|
|
15
|
+
/**
|
|
16
|
+
* Advanced routing orchestrator that handles:
|
|
17
|
+
* - Dynamic route matching with parameter extraction
|
|
18
|
+
* - Query parameter parsing and validation
|
|
19
|
+
* - Catch-all routes
|
|
20
|
+
* - Middleware guards
|
|
21
|
+
* - Redirects (app-level and route-level)
|
|
22
|
+
* - 404 handling
|
|
23
|
+
*/
|
|
24
|
+
export class AdvancedRouter {
|
|
25
|
+
routes;
|
|
26
|
+
config;
|
|
27
|
+
constructor(routes, config) {
|
|
28
|
+
this.routes = routes;
|
|
29
|
+
this.config = config;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Resolve a request pathname to a route match, redirect, or 404
|
|
33
|
+
*
|
|
34
|
+
* @param pathname URL pathname
|
|
35
|
+
* @param url Full URL object
|
|
36
|
+
* @param headers Request headers
|
|
37
|
+
* @param cookies Parsed cookies
|
|
38
|
+
* @returns Route resolution result
|
|
39
|
+
*/
|
|
40
|
+
async resolve(pathname, url, headers, cookies) {
|
|
41
|
+
log.info(`[Router] Resolving: ${pathname}`);
|
|
42
|
+
// Step 1: Check application-level redirects
|
|
43
|
+
if (this.config.redirects) {
|
|
44
|
+
const redirect = getRedirect(pathname, this.config.redirects);
|
|
45
|
+
if (redirect) {
|
|
46
|
+
log.info(`[Router] Redirect: ${pathname} -> ${redirect.to}`);
|
|
47
|
+
return {
|
|
48
|
+
type: "redirect",
|
|
49
|
+
location: redirect.to,
|
|
50
|
+
status: redirect.status,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
// Step 2: Match against routes
|
|
55
|
+
const match = matchRoute(this.routes, pathname);
|
|
56
|
+
if (!match) {
|
|
57
|
+
log.info(`[Router] No route match for: ${pathname}`);
|
|
58
|
+
return { type: "not_found", pathname };
|
|
59
|
+
}
|
|
60
|
+
// Parse query parameters
|
|
61
|
+
const query = {};
|
|
62
|
+
for (const [k, v] of url.searchParams.entries()) query[k] = v;
|
|
63
|
+
// Step 3: Load advanced route config
|
|
64
|
+
const advancedConfig = await getAdvancedRouteConfig(match.route.filePath);
|
|
65
|
+
// Step 4: Handle route-level redirects
|
|
66
|
+
if (advancedConfig.redirect) {
|
|
67
|
+
const guardCtx = {
|
|
68
|
+
route: match.route,
|
|
69
|
+
params: match.params,
|
|
70
|
+
query,
|
|
71
|
+
url,
|
|
72
|
+
headers,
|
|
73
|
+
cookies,
|
|
74
|
+
};
|
|
75
|
+
const target =
|
|
76
|
+
typeof advancedConfig.redirect.to === "function"
|
|
77
|
+
? advancedConfig.redirect.to(guardCtx)
|
|
78
|
+
: advancedConfig.redirect.to;
|
|
79
|
+
const status = advancedConfig.redirect.status ?? 301;
|
|
80
|
+
log.info(`[Router] Route redirect: ${pathname} -> ${target} (${status})`);
|
|
81
|
+
return {
|
|
82
|
+
type: "redirect",
|
|
83
|
+
location: target,
|
|
84
|
+
status,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
// Step 5: Validate query parameters
|
|
88
|
+
if (advancedConfig.querySchema) {
|
|
89
|
+
const validation = validateQueryParams(query, advancedConfig.querySchema);
|
|
90
|
+
if (!validation.valid) {
|
|
91
|
+
log.warn(
|
|
92
|
+
`[Router] Query validation failed: ${validation.errors.join(", ")}`,
|
|
93
|
+
);
|
|
94
|
+
// For now, log but don't block. In strict mode, this could return 400.
|
|
95
|
+
}
|
|
96
|
+
// Apply defaults and type coercion
|
|
97
|
+
const processed = processQueryParams(query, advancedConfig.querySchema);
|
|
98
|
+
Object.assign(query, processed);
|
|
99
|
+
}
|
|
100
|
+
// Step 6: Run middleware guards
|
|
101
|
+
if (advancedConfig.guards && advancedConfig.guards.length > 0) {
|
|
102
|
+
const guardCtx = {
|
|
103
|
+
route: match.route,
|
|
104
|
+
params: match.params,
|
|
105
|
+
query,
|
|
106
|
+
url,
|
|
107
|
+
headers,
|
|
108
|
+
cookies,
|
|
109
|
+
};
|
|
110
|
+
for (const guard of advancedConfig.guards) {
|
|
111
|
+
const result = await guard(guardCtx);
|
|
112
|
+
if (result !== true) {
|
|
113
|
+
// Guard blocked or redirected
|
|
114
|
+
log.info(
|
|
115
|
+
`[Router] Guard blocked: ${pathname} (status: ${result.status})`,
|
|
116
|
+
);
|
|
117
|
+
return {
|
|
118
|
+
type: "redirect",
|
|
119
|
+
location: result.location || "/",
|
|
120
|
+
status: result.status,
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
log.info(`[Router] Matched: ${pathname} -> ${match.route.urlPath}`);
|
|
126
|
+
return {
|
|
127
|
+
type: "matched",
|
|
128
|
+
route: match.route,
|
|
129
|
+
params: match.params,
|
|
130
|
+
query,
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Handle a 404 response
|
|
135
|
+
*
|
|
136
|
+
* @param res ServerResponse object
|
|
137
|
+
* @param pathname Path that was not found
|
|
138
|
+
*/
|
|
139
|
+
async handle404(res, pathname) {
|
|
140
|
+
const notFoundConfig = getNotFoundHandler(this.config, pathname);
|
|
141
|
+
if (notFoundConfig) {
|
|
142
|
+
log.info(`[Router] Using custom 404 handler for: ${pathname}`);
|
|
143
|
+
send404(res, notFoundConfig, pathname);
|
|
144
|
+
} else {
|
|
145
|
+
log.info(`[Router] Using default 404 handler for: ${pathname}`);
|
|
146
|
+
const html = createDefault404Html(pathname);
|
|
147
|
+
send404(res, { html }, pathname);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Handle a redirect response
|
|
152
|
+
*
|
|
153
|
+
* @param res ServerResponse object
|
|
154
|
+
* @param location Target URL
|
|
155
|
+
* @param status HTTP status code
|
|
156
|
+
*/
|
|
157
|
+
handleRedirect(res, location, status) {
|
|
158
|
+
log.info(`[Router] Sending redirect: ${location} (${status})`);
|
|
159
|
+
sendRedirect(res, location, status);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Create an advanced router from framework config and routes
|
|
164
|
+
*
|
|
165
|
+
* @param routes Scanned route entries
|
|
166
|
+
* @param config Framework configuration
|
|
167
|
+
* @returns AdvancedRouter instance
|
|
168
|
+
*/
|
|
169
|
+
export function createAdvancedRouter(routes, config) {
|
|
170
|
+
return new AdvancedRouter(routes, config);
|
|
171
|
+
}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Route-level rendering configuration detection
|
|
3
|
+
*
|
|
4
|
+
* Allows routes to specify their rendering strategy via exported config:
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* // pages/(home).tsx
|
|
8
|
+
* export const rendering = "ssg";
|
|
9
|
+
* export const revalidate = 3600; // ISR revalidation in seconds
|
|
10
|
+
*
|
|
11
|
+
* export default function Home() { ... }
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* Extract rendering configuration from a route module.
|
|
15
|
+
* Safely handles modules that don't specify rendering config.
|
|
16
|
+
*
|
|
17
|
+
* @param module Route module (imported component)
|
|
18
|
+
* @param defaultMode Default rendering mode if not specified
|
|
19
|
+
* @param defaultRevalidate Default revalidation seconds for ISR
|
|
20
|
+
* @returns Route rendering configuration
|
|
21
|
+
*/
|
|
22
|
+
export function extractRenderingConfig(
|
|
23
|
+
module,
|
|
24
|
+
defaultMode = "ssg",
|
|
25
|
+
defaultRevalidate = 3600,
|
|
26
|
+
) {
|
|
27
|
+
const mode = module?.rendering || defaultMode;
|
|
28
|
+
// Validate mode
|
|
29
|
+
const validModes = ["ssg", "ssr", "isr", "ppr"];
|
|
30
|
+
if (!validModes.includes(mode)) {
|
|
31
|
+
console.warn(
|
|
32
|
+
`Invalid rendering mode: ${mode}, defaulting to ${defaultMode}`,
|
|
33
|
+
);
|
|
34
|
+
return { mode: defaultMode, revalidateSeconds: defaultRevalidate };
|
|
35
|
+
}
|
|
36
|
+
// Extract revalidation time if mode is ISR
|
|
37
|
+
let revalidateSeconds;
|
|
38
|
+
if (mode === "isr") {
|
|
39
|
+
revalidateSeconds =
|
|
40
|
+
typeof module?.revalidate === "number"
|
|
41
|
+
? module.revalidate
|
|
42
|
+
: defaultRevalidate;
|
|
43
|
+
}
|
|
44
|
+
return { mode, revalidateSeconds };
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Cached rendering configs to avoid repeated module evaluations.
|
|
48
|
+
* Maps file path → rendering config.
|
|
49
|
+
*/
|
|
50
|
+
const configCache = new Map();
|
|
51
|
+
/**
|
|
52
|
+
* Clear the rendering config cache.
|
|
53
|
+
* Useful during development when routes change.
|
|
54
|
+
*/
|
|
55
|
+
export function clearRenderingConfigCache() {
|
|
56
|
+
configCache.clear();
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Get rendering config for a route, with caching.
|
|
60
|
+
* Attempts to dynamically import and evaluate the route module.
|
|
61
|
+
*
|
|
62
|
+
* In a production SSR environment, route modules are pre-compiled.
|
|
63
|
+
* In a build environment, we need to safely evaluate modules.
|
|
64
|
+
*
|
|
65
|
+
* @param filePath Absolute path to route file
|
|
66
|
+
* @param defaultMode Default rendering mode
|
|
67
|
+
* @param defaultRevalidate Default revalidation seconds
|
|
68
|
+
* @returns Rendering configuration promise
|
|
69
|
+
*/
|
|
70
|
+
export async function getRenderingConfig(
|
|
71
|
+
filePath,
|
|
72
|
+
defaultMode = "ssg",
|
|
73
|
+
defaultRevalidate = 3600,
|
|
74
|
+
) {
|
|
75
|
+
// Check cache first
|
|
76
|
+
if (configCache.has(filePath)) {
|
|
77
|
+
return configCache.get(filePath);
|
|
78
|
+
}
|
|
79
|
+
try {
|
|
80
|
+
// Attempt to import the module
|
|
81
|
+
// This works in ESM environments with proper module resolution
|
|
82
|
+
const module = await import(`file://${filePath}`);
|
|
83
|
+
const config = extractRenderingConfig(
|
|
84
|
+
module,
|
|
85
|
+
defaultMode,
|
|
86
|
+
defaultRevalidate,
|
|
87
|
+
);
|
|
88
|
+
// Cache for future lookups
|
|
89
|
+
configCache.set(filePath, config);
|
|
90
|
+
return config;
|
|
91
|
+
} catch (err) {
|
|
92
|
+
// If import fails, return default config
|
|
93
|
+
// This can happen if module has syntax errors or imports unavailable at build time
|
|
94
|
+
const config = {
|
|
95
|
+
mode: defaultMode,
|
|
96
|
+
revalidateSeconds: defaultMode === "isr" ? defaultRevalidate : undefined,
|
|
97
|
+
};
|
|
98
|
+
configCache.set(filePath, config);
|
|
99
|
+
return config;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Synchronously get rendering config (for build-time use).
|
|
104
|
+
* Falls back to default if module can't be imported.
|
|
105
|
+
*
|
|
106
|
+
* Note: This uses a synchronous require-like approach and may not work
|
|
107
|
+
* in all environments. Prefer async getRenderingConfig() when possible.
|
|
108
|
+
*
|
|
109
|
+
* @param filePath Absolute path to route file
|
|
110
|
+
* @param defaultMode Default rendering mode
|
|
111
|
+
* @param defaultRevalidate Default revalidation seconds
|
|
112
|
+
* @returns Rendering configuration
|
|
113
|
+
*/
|
|
114
|
+
export function getRenderingConfigSync(
|
|
115
|
+
filePath,
|
|
116
|
+
defaultMode = "ssg",
|
|
117
|
+
defaultRevalidate = 3600,
|
|
118
|
+
) {
|
|
119
|
+
// Check cache first
|
|
120
|
+
if (configCache.has(filePath)) {
|
|
121
|
+
return configCache.get(filePath);
|
|
122
|
+
}
|
|
123
|
+
// In sync context, we can't dynamically import
|
|
124
|
+
// Return default config
|
|
125
|
+
const config = {
|
|
126
|
+
mode: defaultMode,
|
|
127
|
+
revalidateSeconds: defaultMode === "isr" ? defaultRevalidate : undefined,
|
|
128
|
+
};
|
|
129
|
+
configCache.set(filePath, config);
|
|
130
|
+
return config;
|
|
131
|
+
}
|
|
@@ -1,20 +1,3 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* This file is part of Jen.js.
|
|
3
|
-
* Copyright (C) 2026 oopsio
|
|
4
|
-
*
|
|
5
|
-
* This program is free software: you can redistribute it and/or modify
|
|
6
|
-
* it under the terms of the GNU General Public License as published by
|
|
7
|
-
* the Free Software Foundation, either version 3 of the License, or
|
|
8
|
-
* (at your option) any later version.
|
|
9
|
-
*
|
|
10
|
-
* This program is distributed in the hope that it will be useful,
|
|
11
|
-
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
-
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13
|
-
* GNU General Public License for more details.
|
|
14
|
-
*
|
|
15
|
-
* You should have received a copy of the GNU General Public License
|
|
16
|
-
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
17
|
-
*/
|
|
18
1
|
import { readdirSync, statSync } from "node:fs";
|
|
19
2
|
import { join, relative, sep } from "node:path";
|
|
20
3
|
/**
|
|
@@ -1,18 +1 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* This file is part of Jen.js.
|
|
3
|
-
* Copyright (C) 2026 oopsio
|
|
4
|
-
*
|
|
5
|
-
* This program is free software: you can redistribute it and/or modify
|
|
6
|
-
* it under the terms of the GNU General Public License as published by
|
|
7
|
-
* the Free Software Foundation, either version 3 of the License, or
|
|
8
|
-
* (at your option) any later version.
|
|
9
|
-
*
|
|
10
|
-
* This program is distributed in the hope that it will be useful,
|
|
11
|
-
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
-
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13
|
-
* GNU General Public License for more details.
|
|
14
|
-
*
|
|
15
|
-
* You should have received a copy of the GNU General Public License
|
|
16
|
-
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
17
|
-
*/
|
|
18
1
|
export {};
|
|
@@ -1,22 +1,5 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* This file is part of Jen.js.
|
|
3
|
-
* Copyright (C) 2026 oopsio
|
|
4
|
-
*
|
|
5
|
-
* This program is free software: you can redistribute it and/or modify
|
|
6
|
-
* it under the terms of the GNU General Public License as published by
|
|
7
|
-
* the Free Software Foundation, either version 3 of the License, or
|
|
8
|
-
* (at your option) any later version.
|
|
9
|
-
*
|
|
10
|
-
* This program is distributed in the hope that it will be useful,
|
|
11
|
-
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
-
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13
|
-
* GNU General Public License for more details.
|
|
14
|
-
*
|
|
15
|
-
* You should have received a copy of the GNU General Public License
|
|
16
|
-
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
17
|
-
*/
|
|
18
1
|
import { compile, compileString } from "sass";
|
|
19
|
-
import { globSync } from "glob";
|
|
2
|
+
import { globSync } from "../vendor/glob/glob.js";
|
|
20
3
|
import { writeFileSync, existsSync, mkdirSync } from "node:fs";
|
|
21
4
|
import { dirname, join, relative } from "node:path";
|
|
22
5
|
import { log } from "../shared/log.js";
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* In-memory cache implementation for data fetching.
|
|
3
|
+
* Supports TTL-based expiration and tag-based invalidation.
|
|
4
|
+
* Suitable for development and single-process deployments.
|
|
5
|
+
*/
|
|
6
|
+
export class MemoryDataCache {
|
|
7
|
+
store = new Map();
|
|
8
|
+
tags = new Map();
|
|
9
|
+
/**
|
|
10
|
+
* Retrieves a cached value by key.
|
|
11
|
+
* Returns null if key doesn't exist or entry has expired.
|
|
12
|
+
*/
|
|
13
|
+
async get(key) {
|
|
14
|
+
const entry = this.store.get(key);
|
|
15
|
+
if (!entry) return null;
|
|
16
|
+
// Check expiration
|
|
17
|
+
const now = Date.now();
|
|
18
|
+
if (now - entry.timestamp > entry.ttl) {
|
|
19
|
+
this.store.delete(key);
|
|
20
|
+
this.cleanupTags(key);
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
return entry.data;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Stores a value in cache with optional TTL and tags.
|
|
27
|
+
*/
|
|
28
|
+
async set(
|
|
29
|
+
key,
|
|
30
|
+
value,
|
|
31
|
+
ttl = 60000, // 1 minute default
|
|
32
|
+
tags,
|
|
33
|
+
) {
|
|
34
|
+
const entry = {
|
|
35
|
+
data: value,
|
|
36
|
+
timestamp: Date.now(),
|
|
37
|
+
ttl,
|
|
38
|
+
tags,
|
|
39
|
+
};
|
|
40
|
+
this.store.set(key, entry);
|
|
41
|
+
// Register tags for invalidation
|
|
42
|
+
if (tags) {
|
|
43
|
+
for (const tag of tags) {
|
|
44
|
+
if (!this.tags.has(tag)) {
|
|
45
|
+
this.tags.set(tag, new Set());
|
|
46
|
+
}
|
|
47
|
+
this.tags.get(tag).add(key);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Deletes a specific cache entry.
|
|
53
|
+
*/
|
|
54
|
+
async delete(key) {
|
|
55
|
+
this.store.delete(key);
|
|
56
|
+
this.cleanupTags(key);
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Clears all cache entries.
|
|
60
|
+
*/
|
|
61
|
+
async clear() {
|
|
62
|
+
this.store.clear();
|
|
63
|
+
this.tags.clear();
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Invalidates all cache entries with specified tags.
|
|
67
|
+
* Useful for mass cache busting after data mutations.
|
|
68
|
+
*/
|
|
69
|
+
async invalidate(tags) {
|
|
70
|
+
const keysToDelete = new Set();
|
|
71
|
+
for (const tag of tags) {
|
|
72
|
+
const keys = this.tags.get(tag);
|
|
73
|
+
if (keys) {
|
|
74
|
+
for (const key of keys) {
|
|
75
|
+
keysToDelete.add(key);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
for (const key of keysToDelete) {
|
|
80
|
+
this.store.delete(key);
|
|
81
|
+
}
|
|
82
|
+
// Clean up tag mappings
|
|
83
|
+
for (const tag of tags) {
|
|
84
|
+
this.tags.delete(tag);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Internal helper to clean up tag references when a key is deleted.
|
|
89
|
+
*/
|
|
90
|
+
cleanupTags(key) {
|
|
91
|
+
for (const keySet of this.tags.values()) {
|
|
92
|
+
keySet.delete(key);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Returns cache statistics for debugging.
|
|
97
|
+
*/
|
|
98
|
+
getStats() {
|
|
99
|
+
return {
|
|
100
|
+
size: this.store.size,
|
|
101
|
+
tags: this.tags.size,
|
|
102
|
+
memory: this.estimateMemory(),
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Rough estimate of memory usage (for monitoring).
|
|
107
|
+
*/
|
|
108
|
+
estimateMemory() {
|
|
109
|
+
let bytes = 0;
|
|
110
|
+
for (const [key, entry] of this.store) {
|
|
111
|
+
bytes += key.length * 2; // Rough UTF-16 estimate
|
|
112
|
+
bytes += JSON.stringify(entry.data).length;
|
|
113
|
+
}
|
|
114
|
+
return bytes;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* NoOp cache implementation that doesn't cache anything.
|
|
119
|
+
* Used when caching is disabled or for testing.
|
|
120
|
+
*/
|
|
121
|
+
export class NoOpCache {
|
|
122
|
+
async get() {
|
|
123
|
+
return null;
|
|
124
|
+
}
|
|
125
|
+
async set() {
|
|
126
|
+
// No-op
|
|
127
|
+
}
|
|
128
|
+
async delete() {
|
|
129
|
+
// No-op
|
|
130
|
+
}
|
|
131
|
+
async clear() {
|
|
132
|
+
// No-op
|
|
133
|
+
}
|
|
134
|
+
async invalidate() {
|
|
135
|
+
// No-op
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Creates a cache key from a URL and optional parameters.
|
|
140
|
+
* Ensures consistent key generation across requests.
|
|
141
|
+
*/
|
|
142
|
+
export function createCacheKey(url, options) {
|
|
143
|
+
let key = url;
|
|
144
|
+
if (options?.method && options.method !== "GET") {
|
|
145
|
+
key += `|${options.method}`;
|
|
146
|
+
}
|
|
147
|
+
if (options?.body) {
|
|
148
|
+
const bodyStr =
|
|
149
|
+
typeof options.body === "string"
|
|
150
|
+
? options.body
|
|
151
|
+
: JSON.stringify(options.body);
|
|
152
|
+
key += `|${hashString(bodyStr)}`;
|
|
153
|
+
}
|
|
154
|
+
if (options?.headers) {
|
|
155
|
+
const headerStr = JSON.stringify(options.headers);
|
|
156
|
+
key += `|${hashString(headerStr)}`;
|
|
157
|
+
}
|
|
158
|
+
return key;
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Simple hash function for generating consistent cache keys.
|
|
162
|
+
*/
|
|
163
|
+
function hashString(str) {
|
|
164
|
+
let hash = 0;
|
|
165
|
+
for (let i = 0; i < str.length; i++) {
|
|
166
|
+
const char = str.charCodeAt(i);
|
|
167
|
+
hash = (hash << 5) - hash + char;
|
|
168
|
+
hash = hash & hash; // Convert to 32bit integer
|
|
169
|
+
}
|
|
170
|
+
return Math.abs(hash).toString(36);
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Cache strategy executor for handling different cache modes.
|
|
174
|
+
*/
|
|
175
|
+
export async function executeCacheStrategy(
|
|
176
|
+
strategy,
|
|
177
|
+
{ key, cache, fetchFn, ttl = 60000, tags },
|
|
178
|
+
) {
|
|
179
|
+
switch (strategy) {
|
|
180
|
+
case "cache-first": {
|
|
181
|
+
const cached = await cache.get(key);
|
|
182
|
+
if (cached !== null) {
|
|
183
|
+
return { data: cached, cached: true };
|
|
184
|
+
}
|
|
185
|
+
const fresh = await fetchFn();
|
|
186
|
+
await cache.set(key, fresh, ttl, tags);
|
|
187
|
+
return { data: fresh, cached: false };
|
|
188
|
+
}
|
|
189
|
+
case "network-first": {
|
|
190
|
+
try {
|
|
191
|
+
const fresh = await fetchFn();
|
|
192
|
+
await cache.set(key, fresh, ttl, tags);
|
|
193
|
+
return { data: fresh, cached: false };
|
|
194
|
+
} catch (error) {
|
|
195
|
+
const cached = await cache.get(key);
|
|
196
|
+
if (cached !== null) {
|
|
197
|
+
return { data: cached, cached: true };
|
|
198
|
+
}
|
|
199
|
+
throw error;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
case "stale-while-revalidate": {
|
|
203
|
+
const cached = await cache.get(key);
|
|
204
|
+
// Return cached immediately, revalidate in background
|
|
205
|
+
if (cached !== null) {
|
|
206
|
+
fetchFn()
|
|
207
|
+
.then((fresh) => cache.set(key, fresh, ttl, tags))
|
|
208
|
+
.catch(() => {
|
|
209
|
+
/* Silently fail background revalidation */
|
|
210
|
+
});
|
|
211
|
+
return { data: cached, cached: true };
|
|
212
|
+
}
|
|
213
|
+
const fresh = await fetchFn();
|
|
214
|
+
await cache.set(key, fresh, ttl, tags);
|
|
215
|
+
return { data: fresh, cached: false };
|
|
216
|
+
}
|
|
217
|
+
case "no-cache":
|
|
218
|
+
default: {
|
|
219
|
+
const fresh = await fetchFn();
|
|
220
|
+
return { data: fresh, cached: false };
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
}
|