gorsee 0.2.4 → 0.2.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +261 -213
- package/dist-pkg/ai/artifact-lifecycle.d.ts +25 -0
- package/dist-pkg/ai/artifact-lifecycle.js +98 -0
- package/dist-pkg/ai/bridge.d.ts +26 -0
- package/dist-pkg/ai/bridge.js +82 -0
- package/dist-pkg/ai/bundle.d.ts +46 -0
- package/dist-pkg/ai/bundle.js +247 -0
- package/dist-pkg/ai/contracts.d.ts +1 -0
- package/dist-pkg/ai/contracts.js +1 -0
- package/dist-pkg/ai/ide.d.ts +37 -0
- package/dist-pkg/ai/ide.js +56 -0
- package/dist-pkg/ai/index.d.ts +85 -0
- package/dist-pkg/ai/index.js +267 -0
- package/dist-pkg/ai/json.d.ts +6 -0
- package/dist-pkg/ai/json.js +14 -0
- package/dist-pkg/ai/mcp.d.ts +28 -0
- package/dist-pkg/ai/mcp.js +152 -0
- package/dist-pkg/ai/session-pack.d.ts +28 -0
- package/dist-pkg/ai/session-pack.js +57 -0
- package/dist-pkg/ai/store.d.ts +67 -0
- package/dist-pkg/ai/store.js +174 -0
- package/dist-pkg/ai/summary.d.ts +57 -0
- package/dist-pkg/ai/summary.js +148 -0
- package/dist-pkg/ai/watch.d.ts +15 -0
- package/dist-pkg/ai/watch.js +66 -0
- package/dist-pkg/auth/action-tokens.d.ts +50 -0
- package/dist-pkg/auth/action-tokens.js +79 -0
- package/dist-pkg/auth/index.d.ts +70 -0
- package/dist-pkg/auth/index.js +199 -0
- package/dist-pkg/auth/redis-session-store.d.ts +7 -0
- package/dist-pkg/auth/redis-session-store.js +42 -0
- package/dist-pkg/auth/signing.d.ts +4 -0
- package/dist-pkg/auth/signing.js +33 -0
- package/dist-pkg/auth/sqlite-session-store.d.ts +12 -0
- package/dist-pkg/auth/sqlite-session-store.js +83 -0
- package/dist-pkg/auth/store-utils.d.ts +2 -0
- package/dist-pkg/auth/store-utils.js +20 -0
- package/dist-pkg/bin/gorsee.js +2 -0
- package/dist-pkg/build/backends/experimental-rolldown.d.ts +6 -0
- package/dist-pkg/build/backends/experimental-rolldown.js +9 -0
- package/dist-pkg/build/backends/register.d.ts +7 -0
- package/dist-pkg/build/backends/register.js +24 -0
- package/dist-pkg/build/backends/rolldown.d.ts +16 -0
- package/dist-pkg/build/backends/rolldown.js +176 -0
- package/dist-pkg/build/client-backend.d.ts +31 -0
- package/dist-pkg/build/client-backend.js +97 -0
- package/dist-pkg/build/client.d.ts +12 -0
- package/dist-pkg/build/client.js +93 -0
- package/dist-pkg/build/css-modules.d.ts +10 -0
- package/dist-pkg/build/css-modules.js +51 -0
- package/dist-pkg/build/devalue-parse.d.ts +1 -0
- package/dist-pkg/build/devalue-parse.js +1 -0
- package/dist-pkg/build/diagnostics.d.ts +20 -0
- package/dist-pkg/build/diagnostics.js +35 -0
- package/dist-pkg/build/fixtures.d.ts +7 -0
- package/dist-pkg/build/fixtures.js +60 -0
- package/dist-pkg/build/framework-imports.d.ts +4 -0
- package/dist-pkg/build/framework-imports.js +58 -0
- package/dist-pkg/build/init.d.ts +1 -0
- package/dist-pkg/build/init.js +6 -0
- package/dist-pkg/build/manifest.d.ts +3 -0
- package/dist-pkg/build/manifest.js +23 -0
- package/dist-pkg/build/parity.d.ts +32 -0
- package/dist-pkg/build/parity.js +71 -0
- package/dist-pkg/build/plugin.d.ts +11 -0
- package/dist-pkg/build/plugin.js +8 -0
- package/dist-pkg/build/readiness.d.ts +11 -0
- package/dist-pkg/build/readiness.js +18 -0
- package/dist-pkg/build/route-client-transform.d.ts +17 -0
- package/dist-pkg/build/route-client-transform.js +48 -0
- package/dist-pkg/build/route-metadata.d.ts +6 -0
- package/dist-pkg/build/route-metadata.js +8 -0
- package/dist-pkg/build/rpc-transform.d.ts +1 -0
- package/dist-pkg/build/rpc-transform.js +44 -0
- package/dist-pkg/build/server-bundle.d.ts +4 -0
- package/dist-pkg/build/server-bundle.js +261 -0
- package/dist-pkg/build/server-strip.d.ts +2 -0
- package/dist-pkg/build/server-strip.js +32 -0
- package/dist-pkg/build/ssg.d.ts +12 -0
- package/dist-pkg/build/ssg.js +36 -0
- package/dist-pkg/cli/bun-plugin.d.ts +2 -0
- package/dist-pkg/cli/bun-plugin.js +14 -0
- package/dist-pkg/cli/canonical-import-rewrite.d.ts +18 -0
- package/dist-pkg/cli/canonical-import-rewrite.js +94 -0
- package/dist-pkg/cli/canonical-imports.d.ts +8 -0
- package/dist-pkg/cli/canonical-imports.js +131 -0
- package/dist-pkg/cli/check-ast.d.ts +20 -0
- package/dist-pkg/cli/check-ast.js +126 -0
- package/dist-pkg/cli/cmd-ai.d.ts +4 -0
- package/dist-pkg/cli/cmd-ai.js +290 -0
- package/dist-pkg/cli/cmd-build.d.ts +12 -0
- package/dist-pkg/cli/cmd-build.js +198 -0
- package/dist-pkg/cli/cmd-check.d.ts +25 -0
- package/dist-pkg/cli/cmd-check.js +573 -0
- package/dist-pkg/cli/cmd-create.d.ts +6 -0
- package/dist-pkg/cli/cmd-create.js +600 -0
- package/dist-pkg/cli/cmd-deploy.d.ts +6 -0
- package/dist-pkg/cli/cmd-deploy.js +381 -0
- package/dist-pkg/cli/cmd-dev.d.ts +5 -0
- package/dist-pkg/cli/cmd-dev.js +5 -0
- package/dist-pkg/cli/cmd-docs.d.ts +50 -0
- package/dist-pkg/cli/cmd-docs.js +122 -0
- package/dist-pkg/cli/cmd-generate.d.ts +12 -0
- package/dist-pkg/cli/cmd-generate.js +320 -0
- package/dist-pkg/cli/cmd-migrate.d.ts +7 -0
- package/dist-pkg/cli/cmd-migrate.js +42 -0
- package/dist-pkg/cli/cmd-routes.d.ts +6 -0
- package/dist-pkg/cli/cmd-routes.js +24 -0
- package/dist-pkg/cli/cmd-start.d.ts +13 -0
- package/dist-pkg/cli/cmd-start.js +32 -0
- package/dist-pkg/cli/cmd-test.d.ts +20 -0
- package/dist-pkg/cli/cmd-test.js +103 -0
- package/dist-pkg/cli/cmd-typegen.d.ts +7 -0
- package/dist-pkg/cli/cmd-typegen.js +66 -0
- package/dist-pkg/cli/cmd-upgrade.d.ts +38 -0
- package/dist-pkg/cli/cmd-upgrade.js +232 -0
- package/dist-pkg/cli/context.d.ts +4 -0
- package/dist-pkg/cli/context.js +4 -0
- package/dist-pkg/cli/framework-md.d.ts +1 -0
- package/dist-pkg/cli/framework-md.js +391 -0
- package/dist-pkg/cli/index.d.ts +6 -0
- package/dist-pkg/cli/index.js +106 -0
- package/dist-pkg/cli/release-version.d.ts +2 -0
- package/dist-pkg/cli/release-version.js +33 -0
- package/dist-pkg/client.d.ts +16 -0
- package/dist-pkg/client.js +71 -0
- package/dist-pkg/compat.d.ts +1 -0
- package/dist-pkg/compat.js +1 -0
- package/dist-pkg/compiler/analysis-backend.d.ts +20 -0
- package/dist-pkg/compiler/analysis-backend.js +164 -0
- package/dist-pkg/compiler/backends/experimental-oxc.d.ts +6 -0
- package/dist-pkg/compiler/backends/experimental-oxc.js +9 -0
- package/dist-pkg/compiler/backends/oxc.d.ts +16 -0
- package/dist-pkg/compiler/backends/oxc.js +198 -0
- package/dist-pkg/compiler/backends/register.d.ts +7 -0
- package/dist-pkg/compiler/backends/register.js +22 -0
- package/dist-pkg/compiler/fixtures.d.ts +2 -0
- package/dist-pkg/compiler/fixtures.js +118 -0
- package/dist-pkg/compiler/init.d.ts +1 -0
- package/dist-pkg/compiler/init.js +6 -0
- package/dist-pkg/compiler/module-analysis.d.ts +13 -0
- package/dist-pkg/compiler/module-analysis.js +50 -0
- package/dist-pkg/compiler/parity.d.ts +35 -0
- package/dist-pkg/compiler/parity.js +89 -0
- package/dist-pkg/compiler/readiness.d.ts +11 -0
- package/dist-pkg/compiler/readiness.js +18 -0
- package/dist-pkg/compiler/route-facts.d.ts +34 -0
- package/dist-pkg/compiler/route-facts.js +75 -0
- package/dist-pkg/content/index.d.ts +27 -0
- package/dist-pkg/content/index.js +287 -0
- package/dist-pkg/db/index.d.ts +3 -0
- package/dist-pkg/db/index.js +6 -0
- package/dist-pkg/db/migrate.d.ts +7 -0
- package/dist-pkg/db/migrate.js +53 -0
- package/dist-pkg/db/postgres.d.ts +29 -0
- package/dist-pkg/db/postgres.js +59 -0
- package/dist-pkg/db/sqlite.d.ts +10 -0
- package/dist-pkg/db/sqlite.js +22 -0
- package/dist-pkg/deploy/cloudflare.d.ts +8 -0
- package/{src/deploy/cloudflare.ts → dist-pkg/deploy/cloudflare.js} +24 -26
- package/dist-pkg/deploy/conformance.d.ts +21 -0
- package/dist-pkg/deploy/conformance.js +98 -0
- package/dist-pkg/deploy/dockerfile.d.ts +3 -0
- package/{src/deploy/dockerfile.ts → dist-pkg/deploy/dockerfile.js} +8 -10
- package/dist-pkg/deploy/fly.d.ts +3 -0
- package/{src/deploy/fly.ts → dist-pkg/deploy/fly.js} +11 -12
- package/dist-pkg/deploy/index.d.ts +6 -0
- package/dist-pkg/deploy/index.js +26 -0
- package/dist-pkg/deploy/netlify.d.ts +2 -0
- package/{src/deploy/netlify.ts → dist-pkg/deploy/netlify.js} +17 -11
- package/dist-pkg/deploy/runtime.d.ts +2 -0
- package/dist-pkg/deploy/runtime.js +3 -0
- package/dist-pkg/deploy/vercel.d.ts +22 -0
- package/dist-pkg/deploy/vercel.js +53 -0
- package/dist-pkg/dev/error-overlay.d.ts +1 -0
- package/{src/dev/error-overlay.ts → dist-pkg/dev/error-overlay.js} +13 -23
- package/dist-pkg/dev/hmr.d.ts +30 -0
- package/dist-pkg/dev/hmr.js +86 -0
- package/dist-pkg/dev/partial-handler.d.ts +9 -0
- package/dist-pkg/dev/partial-handler.js +24 -0
- package/dist-pkg/dev/request-handler.d.ts +30 -0
- package/dist-pkg/dev/request-handler.js +67 -0
- package/dist-pkg/dev/watcher.d.ts +6 -0
- package/dist-pkg/dev/watcher.js +34 -0
- package/dist-pkg/dev.d.ts +11 -0
- package/dist-pkg/dev.js +268 -0
- package/dist-pkg/env/index.d.ts +3 -0
- package/dist-pkg/env/index.js +57 -0
- package/dist-pkg/errors/catalog.d.ts +9 -0
- package/{src/errors/catalog.ts → dist-pkg/errors/catalog.js} +8 -24
- package/dist-pkg/errors/formatter.d.ts +22 -0
- package/dist-pkg/errors/formatter.js +43 -0
- package/dist-pkg/errors/index.d.ts +2 -0
- package/dist-pkg/errors/index.js +2 -0
- package/dist-pkg/forms/action.d.ts +15 -0
- package/dist-pkg/forms/action.js +20 -0
- package/dist-pkg/forms/index.d.ts +4 -0
- package/dist-pkg/forms/index.js +12 -0
- package/dist-pkg/i18n/index.d.ts +61 -0
- package/dist-pkg/i18n/index.js +147 -0
- package/dist-pkg/index-client.d.ts +1 -0
- package/dist-pkg/index-client.js +1 -0
- package/dist-pkg/index.d.ts +32 -0
- package/dist-pkg/index.js +79 -0
- package/dist-pkg/jsx-runtime-client.d.ts +8 -0
- package/dist-pkg/jsx-runtime-client.js +1 -0
- package/dist-pkg/jsx-runtime.d.ts +13 -0
- package/dist-pkg/jsx-runtime.js +5 -0
- package/dist-pkg/jsx-types-html.d.ts +221 -0
- package/dist-pkg/jsx-types-html.js +0 -0
- package/dist-pkg/log/index.d.ts +8 -0
- package/dist-pkg/log/index.js +55 -0
- package/dist-pkg/plugins/drizzle.d.ts +16 -0
- package/dist-pkg/plugins/drizzle.js +50 -0
- package/dist-pkg/plugins/index.d.ts +62 -0
- package/dist-pkg/plugins/index.js +147 -0
- package/dist-pkg/plugins/lucia.d.ts +26 -0
- package/dist-pkg/plugins/lucia.js +63 -0
- package/dist-pkg/plugins/prisma.d.ts +14 -0
- package/dist-pkg/plugins/prisma.js +57 -0
- package/dist-pkg/plugins/resend.d.ts +21 -0
- package/dist-pkg/plugins/resend.js +45 -0
- package/dist-pkg/plugins/s3.d.ts +18 -0
- package/dist-pkg/plugins/s3.js +63 -0
- package/dist-pkg/plugins/stripe.d.ts +32 -0
- package/dist-pkg/plugins/stripe.js +69 -0
- package/dist-pkg/plugins/tailwind.d.ts +15 -0
- package/dist-pkg/plugins/tailwind.js +58 -0
- package/dist-pkg/prod.d.ts +21 -0
- package/dist-pkg/prod.js +347 -0
- package/dist-pkg/reactive/computed.d.ts +3 -0
- package/dist-pkg/reactive/computed.js +15 -0
- package/dist-pkg/reactive/data.d.ts +25 -0
- package/dist-pkg/reactive/data.js +56 -0
- package/dist-pkg/reactive/diagnostics.d.ts +100 -0
- package/dist-pkg/reactive/diagnostics.js +363 -0
- package/dist-pkg/reactive/effect.d.ts +3 -0
- package/dist-pkg/reactive/effect.js +6 -0
- package/dist-pkg/reactive/index.d.ts +9 -0
- package/dist-pkg/reactive/index.js +18 -0
- package/dist-pkg/reactive/live.d.ts +15 -0
- package/dist-pkg/reactive/live.js +58 -0
- package/dist-pkg/reactive/optimistic.d.ts +20 -0
- package/dist-pkg/reactive/optimistic.js +54 -0
- package/dist-pkg/reactive/resource.d.ts +25 -0
- package/dist-pkg/reactive/resource.js +97 -0
- package/dist-pkg/reactive/signal.d.ts +4 -0
- package/dist-pkg/reactive/signal.js +17 -0
- package/dist-pkg/reactive/store.d.ts +6 -0
- package/dist-pkg/reactive/store.js +19 -0
- package/dist-pkg/router/index.d.ts +2 -0
- package/dist-pkg/router/index.js +2 -0
- package/dist-pkg/router/matcher.d.ts +7 -0
- package/dist-pkg/router/matcher.js +40 -0
- package/dist-pkg/router/scanner.d.ts +14 -0
- package/dist-pkg/router/scanner.js +141 -0
- package/dist-pkg/routes/index.d.ts +1 -0
- package/dist-pkg/routes/index.js +10 -0
- package/dist-pkg/runtime/app-config.d.ts +26 -0
- package/dist-pkg/runtime/app-config.js +69 -0
- package/dist-pkg/runtime/client.d.ts +3 -0
- package/dist-pkg/runtime/client.js +31 -0
- package/dist-pkg/runtime/devtools.d.ts +64 -0
- package/dist-pkg/runtime/devtools.js +132 -0
- package/dist-pkg/runtime/error-boundary.d.ts +6 -0
- package/dist-pkg/runtime/error-boundary.js +17 -0
- package/dist-pkg/runtime/event-replay.d.ts +3 -0
- package/{src/runtime/event-replay.ts → dist-pkg/runtime/event-replay.js} +7 -22
- package/dist-pkg/runtime/event-source.d.ts +7 -0
- package/dist-pkg/runtime/event-source.js +24 -0
- package/dist-pkg/runtime/form.d.ts +24 -0
- package/dist-pkg/runtime/form.js +59 -0
- package/dist-pkg/runtime/head.d.ts +7 -0
- package/dist-pkg/runtime/head.js +90 -0
- package/dist-pkg/runtime/html-escape.d.ts +7 -0
- package/dist-pkg/runtime/html-escape.js +39 -0
- package/dist-pkg/runtime/hydration.d.ts +15 -0
- package/dist-pkg/runtime/hydration.js +103 -0
- package/dist-pkg/runtime/image.d.ts +49 -0
- package/dist-pkg/runtime/image.js +144 -0
- package/dist-pkg/runtime/index.d.ts +17 -0
- package/dist-pkg/runtime/index.js +59 -0
- package/dist-pkg/runtime/island-hydrator.d.ts +12 -0
- package/dist-pkg/runtime/island-hydrator.js +49 -0
- package/dist-pkg/runtime/island.d.ts +19 -0
- package/dist-pkg/runtime/island.js +36 -0
- package/dist-pkg/runtime/jsx-runtime.d.ts +12 -0
- package/dist-pkg/runtime/jsx-runtime.js +173 -0
- package/dist-pkg/runtime/link.d.ts +16 -0
- package/dist-pkg/runtime/link.js +47 -0
- package/dist-pkg/runtime/project.d.ts +37 -0
- package/dist-pkg/runtime/project.js +36 -0
- package/dist-pkg/runtime/renderable.d.ts +6 -0
- package/dist-pkg/runtime/renderable.js +0 -0
- package/dist-pkg/runtime/router.d.ts +47 -0
- package/dist-pkg/runtime/router.js +476 -0
- package/dist-pkg/runtime/server.d.ts +8 -0
- package/dist-pkg/runtime/server.js +71 -0
- package/dist-pkg/runtime/stream.d.ts +29 -0
- package/dist-pkg/runtime/stream.js +106 -0
- package/dist-pkg/runtime/suspense.d.ts +6 -0
- package/dist-pkg/runtime/suspense.js +16 -0
- package/dist-pkg/runtime/typed-routes.d.ts +24 -0
- package/dist-pkg/runtime/typed-routes.js +77 -0
- package/dist-pkg/runtime/validated-form.d.ts +40 -0
- package/dist-pkg/runtime/validated-form.js +120 -0
- package/dist-pkg/security/cors.d.ts +10 -0
- package/dist-pkg/security/cors.js +56 -0
- package/dist-pkg/security/csrf.d.ts +9 -0
- package/dist-pkg/security/csrf.js +53 -0
- package/dist-pkg/security/headers.d.ts +11 -0
- package/dist-pkg/security/headers.js +31 -0
- package/dist-pkg/security/index.d.ts +5 -0
- package/dist-pkg/security/index.js +5 -0
- package/dist-pkg/security/rate-limit.d.ts +10 -0
- package/dist-pkg/security/rate-limit.js +49 -0
- package/dist-pkg/security/redis-rate-limit.d.ts +14 -0
- package/dist-pkg/security/redis-rate-limit.js +23 -0
- package/dist-pkg/server/action.d.ts +21 -0
- package/dist-pkg/server/action.js +64 -0
- package/dist-pkg/server/cache-utils.d.ts +2 -0
- package/dist-pkg/server/cache-utils.js +26 -0
- package/dist-pkg/server/cache.d.ts +33 -0
- package/dist-pkg/server/cache.js +236 -0
- package/dist-pkg/server/compress.d.ts +2 -0
- package/dist-pkg/server/compress.js +49 -0
- package/dist-pkg/server/endpoint-execution.d.ts +28 -0
- package/dist-pkg/server/endpoint-execution.js +37 -0
- package/dist-pkg/server/etag.d.ts +3 -0
- package/dist-pkg/server/etag.js +18 -0
- package/dist-pkg/server/guard.d.ts +16 -0
- package/dist-pkg/server/guard.js +45 -0
- package/dist-pkg/server/html-shell.d.ts +12 -0
- package/dist-pkg/server/html-shell.js +52 -0
- package/dist-pkg/server/index.d.ts +36 -0
- package/dist-pkg/server/index.js +170 -0
- package/dist-pkg/server/jobs.d.ts +41 -0
- package/dist-pkg/server/jobs.js +81 -0
- package/dist-pkg/server/manifest.d.ts +19 -0
- package/dist-pkg/server/manifest.js +36 -0
- package/dist-pkg/server/middleware.d.ts +39 -0
- package/dist-pkg/server/middleware.js +122 -0
- package/dist-pkg/server/mime.d.ts +1 -0
- package/{src/server/mime.ts → dist-pkg/server/mime.js} +6 -17
- package/dist-pkg/server/not-found.d.ts +6 -0
- package/dist-pkg/server/not-found.js +24 -0
- package/dist-pkg/server/page-render.d.ts +29 -0
- package/dist-pkg/server/page-render.js +67 -0
- package/dist-pkg/server/partial-navigation.d.ts +4 -0
- package/dist-pkg/server/partial-navigation.js +16 -0
- package/dist-pkg/server/pipe.d.ts +9 -0
- package/dist-pkg/server/pipe.js +32 -0
- package/dist-pkg/server/redis-cache-store.d.ts +10 -0
- package/dist-pkg/server/redis-cache-store.js +73 -0
- package/dist-pkg/server/redis-client.d.ts +37 -0
- package/dist-pkg/server/redis-client.js +37 -0
- package/dist-pkg/server/request-policy.d.ts +55 -0
- package/dist-pkg/server/request-policy.js +216 -0
- package/dist-pkg/server/request-preflight.d.ts +23 -0
- package/dist-pkg/server/request-preflight.js +45 -0
- package/dist-pkg/server/request-security-policy.d.ts +17 -0
- package/dist-pkg/server/request-security-policy.js +34 -0
- package/dist-pkg/server/request-surface.d.ts +8 -0
- package/dist-pkg/server/request-surface.js +19 -0
- package/dist-pkg/server/route-request.d.ts +31 -0
- package/dist-pkg/server/route-request.js +112 -0
- package/dist-pkg/server/route-response.d.ts +22 -0
- package/dist-pkg/server/route-response.js +58 -0
- package/dist-pkg/server/rpc-hash.d.ts +2 -0
- package/dist-pkg/server/rpc-hash.js +7 -0
- package/dist-pkg/server/rpc-protocol.d.ts +22 -0
- package/dist-pkg/server/rpc-protocol.js +28 -0
- package/dist-pkg/server/rpc-utils.d.ts +2 -0
- package/dist-pkg/server/rpc-utils.js +26 -0
- package/dist-pkg/server/rpc.d.ts +20 -0
- package/dist-pkg/server/rpc.js +147 -0
- package/dist-pkg/server/runtime-dispatch.d.ts +19 -0
- package/dist-pkg/server/runtime-dispatch.js +67 -0
- package/dist-pkg/server/server-execution.d.ts +22 -0
- package/dist-pkg/server/server-execution.js +53 -0
- package/dist-pkg/server/sqlite-cache-store.d.ts +13 -0
- package/dist-pkg/server/sqlite-cache-store.js +88 -0
- package/dist-pkg/server/sse.d.ts +9 -0
- package/dist-pkg/server/sse.js +34 -0
- package/dist-pkg/server/static-file.d.ts +9 -0
- package/dist-pkg/server/static-file.js +43 -0
- package/dist-pkg/server/ws.d.ts +18 -0
- package/dist-pkg/server/ws.js +40 -0
- package/dist-pkg/server-entry.d.ts +19 -0
- package/dist-pkg/server-entry.js +93 -0
- package/dist-pkg/testing/index.d.ts +98 -0
- package/dist-pkg/testing/index.js +254 -0
- package/dist-pkg/types/index.d.ts +4 -0
- package/dist-pkg/types/index.js +4 -0
- package/dist-pkg/types/safe-html.d.ts +7 -0
- package/dist-pkg/types/safe-html.js +19 -0
- package/dist-pkg/types/safe-sql.d.ts +8 -0
- package/dist-pkg/types/safe-sql.js +14 -0
- package/dist-pkg/types/safe-url.d.ts +7 -0
- package/dist-pkg/types/safe-url.js +20 -0
- package/dist-pkg/types/user-input.d.ts +9 -0
- package/dist-pkg/types/user-input.js +3 -0
- package/dist-pkg/unsafe/index.d.ts +12 -0
- package/dist-pkg/unsafe/index.js +6 -0
- package/package.json +101 -45
- package/bin/gorsee.js +0 -2
- package/src/auth/index.ts +0 -178
- package/src/auth/redis-session-store.ts +0 -46
- package/src/auth/sqlite-session-store.ts +0 -98
- package/src/auth/store-utils.ts +0 -21
- package/src/build/client.ts +0 -139
- package/src/build/css-modules.ts +0 -69
- package/src/build/devalue-parse.ts +0 -2
- package/src/build/manifest.ts +0 -34
- package/src/build/route-metadata.ts +0 -12
- package/src/build/rpc-transform.ts +0 -62
- package/src/build/server-strip.ts +0 -87
- package/src/build/ssg.ts +0 -70
- package/src/cli/bun-plugin.ts +0 -58
- package/src/cli/cmd-build.ts +0 -153
- package/src/cli/cmd-check.ts +0 -239
- package/src/cli/cmd-create.ts +0 -328
- package/src/cli/cmd-deploy.ts +0 -149
- package/src/cli/cmd-dev.ts +0 -13
- package/src/cli/cmd-docs.ts +0 -152
- package/src/cli/cmd-generate.ts +0 -155
- package/src/cli/cmd-migrate.ts +0 -53
- package/src/cli/cmd-routes.ts +0 -36
- package/src/cli/cmd-start.ts +0 -30
- package/src/cli/cmd-test.ts +0 -129
- package/src/cli/cmd-typegen.ts +0 -93
- package/src/cli/cmd-upgrade.ts +0 -143
- package/src/cli/context.ts +0 -12
- package/src/cli/framework-md.ts +0 -223
- package/src/cli/index.ts +0 -107
- package/src/client.ts +0 -26
- package/src/db/index.ts +0 -2
- package/src/db/migrate.ts +0 -89
- package/src/db/sqlite.ts +0 -40
- package/src/deploy/index.ts +0 -31
- package/src/deploy/vercel.ts +0 -94
- package/src/dev/hmr.ts +0 -31
- package/src/dev/partial-handler.ts +0 -52
- package/src/dev/request-handler.ts +0 -127
- package/src/dev/watcher.ts +0 -48
- package/src/dev.ts +0 -208
- package/src/env/index.ts +0 -74
- package/src/errors/formatter.ts +0 -63
- package/src/errors/index.ts +0 -2
- package/src/i18n/index.ts +0 -72
- package/src/index-client.ts +0 -4
- package/src/index.ts +0 -43
- package/src/jsx-runtime-client.ts +0 -13
- package/src/jsx-runtime.ts +0 -20
- package/src/jsx-types-html.ts +0 -242
- package/src/log/index.ts +0 -44
- package/src/plugins/drizzle.ts +0 -84
- package/src/plugins/index.ts +0 -86
- package/src/plugins/lucia.ts +0 -111
- package/src/plugins/prisma.ts +0 -85
- package/src/plugins/resend.ts +0 -78
- package/src/plugins/s3.ts +0 -102
- package/src/plugins/stripe.ts +0 -133
- package/src/plugins/tailwind.ts +0 -92
- package/src/prod.ts +0 -252
- package/src/reactive/computed.ts +0 -7
- package/src/reactive/effect.ts +0 -7
- package/src/reactive/index.ts +0 -7
- package/src/reactive/live.ts +0 -97
- package/src/reactive/optimistic.ts +0 -83
- package/src/reactive/resource.ts +0 -138
- package/src/reactive/signal.ts +0 -20
- package/src/reactive/store.ts +0 -36
- package/src/router/index.ts +0 -2
- package/src/router/matcher.ts +0 -53
- package/src/router/scanner.ts +0 -206
- package/src/runtime/client.ts +0 -28
- package/src/runtime/error-boundary.ts +0 -35
- package/src/runtime/form.ts +0 -49
- package/src/runtime/head.ts +0 -113
- package/src/runtime/html-escape.ts +0 -30
- package/src/runtime/hydration.ts +0 -95
- package/src/runtime/image.ts +0 -48
- package/src/runtime/index.ts +0 -12
- package/src/runtime/island-hydrator.ts +0 -84
- package/src/runtime/island.ts +0 -88
- package/src/runtime/jsx-runtime.ts +0 -167
- package/src/runtime/link.ts +0 -45
- package/src/runtime/project.ts +0 -73
- package/src/runtime/router.ts +0 -224
- package/src/runtime/server.ts +0 -102
- package/src/runtime/stream.ts +0 -182
- package/src/runtime/suspense.ts +0 -37
- package/src/runtime/typed-routes.ts +0 -26
- package/src/runtime/validated-form.ts +0 -106
- package/src/security/cors.ts +0 -80
- package/src/security/csrf.ts +0 -85
- package/src/security/headers.ts +0 -50
- package/src/security/index.ts +0 -4
- package/src/security/rate-limit.ts +0 -80
- package/src/server/action.ts +0 -48
- package/src/server/cache-utils.ts +0 -23
- package/src/server/cache.ts +0 -125
- package/src/server/compress.ts +0 -60
- package/src/server/etag.ts +0 -23
- package/src/server/guard.ts +0 -69
- package/src/server/html-shell.ts +0 -69
- package/src/server/index.ts +0 -57
- package/src/server/manifest.ts +0 -36
- package/src/server/middleware.ts +0 -159
- package/src/server/not-found.ts +0 -35
- package/src/server/page-render.ts +0 -123
- package/src/server/pipe.ts +0 -46
- package/src/server/redis-cache-store.ts +0 -87
- package/src/server/redis-client.ts +0 -71
- package/src/server/request-preflight.ts +0 -45
- package/src/server/route-request.ts +0 -72
- package/src/server/rpc-hash.ts +0 -17
- package/src/server/rpc-utils.ts +0 -27
- package/src/server/rpc.ts +0 -177
- package/src/server/sqlite-cache-store.ts +0 -109
- package/src/server/sse.ts +0 -96
- package/src/server/static-file.ts +0 -63
- package/src/server/ws.ts +0 -56
- package/src/server-entry.ts +0 -36
- package/src/testing/index.ts +0 -74
- package/src/types/index.ts +0 -4
- package/src/types/safe-html.ts +0 -32
- package/src/types/safe-sql.ts +0 -28
- package/src/types/safe-url.ts +0 -40
- package/src/types/user-input.ts +0 -12
- package/src/unsafe/index.ts +0 -18
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
type Awaitable<T> = T | Promise<T>
|
|
2
|
-
|
|
3
|
-
export interface RedisLikeClient {
|
|
4
|
-
get(key: string): Awaitable<string | null>
|
|
5
|
-
set(key: string, value: string): Awaitable<unknown>
|
|
6
|
-
del(key: string): Awaitable<number>
|
|
7
|
-
keys(pattern: string): Awaitable<string[]>
|
|
8
|
-
expire?(key: string, seconds: number): Awaitable<number>
|
|
9
|
-
ttl?(key: string): Awaitable<number>
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export function buildRedisKey(prefix: string, key: string): string {
|
|
13
|
-
return `${prefix}:${key}`
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export function stripRedisPrefix(prefix: string, key: string): string {
|
|
17
|
-
const expected = `${prefix}:`
|
|
18
|
-
return key.startsWith(expected) ? key.slice(expected.length) : key
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export interface NodeRedisClientLike {
|
|
22
|
-
get(key: string): Awaitable<string | null>
|
|
23
|
-
set(key: string, value: string): Awaitable<unknown>
|
|
24
|
-
del(key: string): Awaitable<number>
|
|
25
|
-
keys(pattern: string): Awaitable<string[]>
|
|
26
|
-
expire?(key: string, seconds: number): Awaitable<number>
|
|
27
|
-
ttl?(key: string): Awaitable<number>
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export interface IORedisClientLike {
|
|
31
|
-
get(key: string): Awaitable<string | null>
|
|
32
|
-
set(key: string, value: string): Awaitable<unknown>
|
|
33
|
-
del(key: string): Awaitable<number>
|
|
34
|
-
keys(pattern: string): Awaitable<string[]>
|
|
35
|
-
expire?(key: string, seconds: number): Awaitable<number>
|
|
36
|
-
ttl?(key: string): Awaitable<number>
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
export function createNodeRedisLikeClient(client: NodeRedisClientLike): RedisLikeClient {
|
|
40
|
-
return {
|
|
41
|
-
get: (key) => client.get(key),
|
|
42
|
-
set: (key, value) => client.set(key, value),
|
|
43
|
-
del: (key) => client.del(key),
|
|
44
|
-
keys: (pattern) => client.keys(pattern),
|
|
45
|
-
expire: client.expire ? (key, seconds) => client.expire!(key, seconds) : undefined,
|
|
46
|
-
ttl: client.ttl ? (key) => client.ttl!(key) : undefined,
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
export function createIORedisLikeClient(client: IORedisClientLike): RedisLikeClient {
|
|
51
|
-
return createNodeRedisLikeClient(client)
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
export async function deleteExpiredRedisKeys(
|
|
55
|
-
client: RedisLikeClient,
|
|
56
|
-
pattern: string,
|
|
57
|
-
now: number,
|
|
58
|
-
parseCreatedAt: (value: string) => number | undefined,
|
|
59
|
-
maxEntryAgeMs: number,
|
|
60
|
-
): Promise<number> {
|
|
61
|
-
let deleted = 0
|
|
62
|
-
for (const key of await client.keys(pattern)) {
|
|
63
|
-
const raw = await client.get(key)
|
|
64
|
-
if (raw === null) continue
|
|
65
|
-
const createdAt = parseCreatedAt(raw)
|
|
66
|
-
if (createdAt === undefined) continue
|
|
67
|
-
if (createdAt > now - maxEntryAgeMs) continue
|
|
68
|
-
deleted += await client.del(key)
|
|
69
|
-
}
|
|
70
|
-
return deleted
|
|
71
|
-
}
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import { handleRPCRequest, handleRPCRequestWithRegistry, type RPCRegistry } from "./rpc.ts"
|
|
2
|
-
|
|
3
|
-
interface RateLimitResult {
|
|
4
|
-
allowed: boolean
|
|
5
|
-
resetAt: number
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
interface RateLimiterLike {
|
|
9
|
-
check(key: string): RateLimitResult
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export function createRateLimitResponse(
|
|
13
|
-
rateLimiter: RateLimiterLike,
|
|
14
|
-
key: string,
|
|
15
|
-
): Response | null {
|
|
16
|
-
const result = rateLimiter.check(key)
|
|
17
|
-
if (result.allowed) return null
|
|
18
|
-
|
|
19
|
-
return new Response("Too Many Requests", {
|
|
20
|
-
status: 429,
|
|
21
|
-
headers: {
|
|
22
|
-
"Retry-After": String(Math.ceil((result.resetAt - Date.now()) / 1000)),
|
|
23
|
-
},
|
|
24
|
-
})
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export function applyResponseHeaders(
|
|
28
|
-
response: Response,
|
|
29
|
-
headers: Record<string, string>,
|
|
30
|
-
): Response {
|
|
31
|
-
for (const key in headers) response.headers.set(key, headers[key]!)
|
|
32
|
-
return response
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export async function handleRPCWithHeaders(
|
|
36
|
-
request: Request,
|
|
37
|
-
headers: Record<string, string>,
|
|
38
|
-
registry?: Pick<RPCRegistry, "getHandler">,
|
|
39
|
-
): Promise<Response | null> {
|
|
40
|
-
const response = registry
|
|
41
|
-
? await handleRPCRequestWithRegistry(request, registry)
|
|
42
|
-
: await handleRPCRequest(request)
|
|
43
|
-
if (!response) return null
|
|
44
|
-
return applyResponseHeaders(response, headers)
|
|
45
|
-
}
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
import { createContext, runMiddlewareChain, RedirectError, type Context, type MiddlewareFn } from "./middleware.ts"
|
|
2
|
-
import { resolvePageRoute, type ResolvedPageRoute } from "./page-render.ts"
|
|
3
|
-
import type { MatchResult } from "../router/matcher.ts"
|
|
4
|
-
|
|
5
|
-
type RouteModule = Record<string, unknown>
|
|
6
|
-
|
|
7
|
-
interface RouteRequestContext {
|
|
8
|
-
match: MatchResult
|
|
9
|
-
request: Request
|
|
10
|
-
mod: RouteModule
|
|
11
|
-
ctx: Context
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
interface ResolvedRouteRequestContext extends RouteRequestContext {
|
|
15
|
-
resolved: ResolvedPageRoute
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
interface RouteRequestOptions {
|
|
19
|
-
match: MatchResult
|
|
20
|
-
request: Request
|
|
21
|
-
extraMiddlewares?: MiddlewareFn[]
|
|
22
|
-
onPartialRequest: (ctx: ResolvedRouteRequestContext) => Promise<Response>
|
|
23
|
-
onPageRequest: (ctx: ResolvedRouteRequestContext) => Promise<Response>
|
|
24
|
-
onRouteError?: (error: unknown, ctx: ResolvedRouteRequestContext) => Promise<Response>
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export async function handleRouteRequest(options: RouteRequestOptions): Promise<Response> {
|
|
28
|
-
const { match, request, extraMiddlewares = [], onPartialRequest, onPageRequest, onRouteError } = options
|
|
29
|
-
const mod = await import(match.route.filePath)
|
|
30
|
-
const ctx = createContext(request, match.params)
|
|
31
|
-
let routeCtx: ResolvedRouteRequestContext | undefined
|
|
32
|
-
|
|
33
|
-
if (typeof mod.GET === "function" && request.method === "GET") return (mod.GET as Function)(ctx)
|
|
34
|
-
if (typeof mod.POST === "function" && request.method === "POST") return (mod.POST as Function)(ctx)
|
|
35
|
-
|
|
36
|
-
try {
|
|
37
|
-
const resolved = await resolvePageRoute(mod, match, ctx)
|
|
38
|
-
if (!resolved) return new Response("Route has no default export", { status: 500 })
|
|
39
|
-
|
|
40
|
-
routeCtx = { match, request, mod, ctx, resolved }
|
|
41
|
-
const currentRouteCtx = routeCtx
|
|
42
|
-
const middlewares = await loadRouteMiddlewares(match, extraMiddlewares)
|
|
43
|
-
|
|
44
|
-
return await runMiddlewareChain(middlewares, ctx, async () => {
|
|
45
|
-
if (request.headers.get("X-Gorsee-Navigate") === "partial") {
|
|
46
|
-
return onPartialRequest(currentRouteCtx)
|
|
47
|
-
}
|
|
48
|
-
return onPageRequest(currentRouteCtx)
|
|
49
|
-
})
|
|
50
|
-
} catch (error) {
|
|
51
|
-
if (error instanceof RedirectError) {
|
|
52
|
-
return new Response(null, {
|
|
53
|
-
status: error.status,
|
|
54
|
-
headers: { Location: error.url },
|
|
55
|
-
})
|
|
56
|
-
}
|
|
57
|
-
if (onRouteError && routeCtx) return onRouteError(error, routeCtx)
|
|
58
|
-
throw error
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
async function loadRouteMiddlewares(
|
|
63
|
-
match: MatchResult,
|
|
64
|
-
extraMiddlewares: MiddlewareFn[],
|
|
65
|
-
): Promise<MiddlewareFn[]> {
|
|
66
|
-
const middlewares = [...extraMiddlewares]
|
|
67
|
-
for (const mwPath of match.route.middlewarePaths) {
|
|
68
|
-
const mwMod = await import(mwPath)
|
|
69
|
-
if (typeof mwMod.default === "function") middlewares.push(mwMod.default)
|
|
70
|
-
}
|
|
71
|
-
return middlewares
|
|
72
|
-
}
|
package/src/server/rpc-hash.ts
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
// Shared RPC hash function -- must produce identical IDs on server and client
|
|
2
|
-
// ID = sha256(filePath + ":" + callIndex).slice(0, 12)
|
|
3
|
-
|
|
4
|
-
import { createHash } from "node:crypto"
|
|
5
|
-
|
|
6
|
-
export function hashRPC(filePath: string, index: number): string {
|
|
7
|
-
return createHash("sha256")
|
|
8
|
-
.update(`${filePath}:${index}`)
|
|
9
|
-
.digest("hex")
|
|
10
|
-
.slice(0, 12)
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
// Scan source for server() call positions and return their hashes
|
|
14
|
-
export function scanServerCalls(source: string, filePath: string): string[] {
|
|
15
|
-
const matches = [...source.matchAll(/\bserver\s*\(\s*(?=async\s|function\s)/g)]
|
|
16
|
-
return matches.map((_, i) => hashRPC(filePath, i))
|
|
17
|
-
}
|
package/src/server/rpc-utils.ts
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import type { RPCRegistry } from "./rpc.ts"
|
|
2
|
-
|
|
3
|
-
export function createScopedRPCRegistry(registry: RPCRegistry, scope: string): RPCRegistry {
|
|
4
|
-
const prefix = `${scope}:`
|
|
5
|
-
const fileCounters = new Map<string, number>()
|
|
6
|
-
const scopedIds = new Set<string>()
|
|
7
|
-
return {
|
|
8
|
-
getHandler: (id) => registry.getHandler(prefix + id),
|
|
9
|
-
setHandler: (id, fn) => {
|
|
10
|
-
const scopedId = prefix + id
|
|
11
|
-
scopedIds.add(scopedId)
|
|
12
|
-
registry.setHandler(scopedId, fn)
|
|
13
|
-
},
|
|
14
|
-
deleteHandler: (id) => {
|
|
15
|
-
const scopedId = prefix + id
|
|
16
|
-
scopedIds.delete(scopedId)
|
|
17
|
-
registry.deleteHandler(scopedId)
|
|
18
|
-
},
|
|
19
|
-
clear: () => {
|
|
20
|
-
for (const scopedId of scopedIds) registry.deleteHandler(scopedId)
|
|
21
|
-
scopedIds.clear()
|
|
22
|
-
fileCounters.clear()
|
|
23
|
-
},
|
|
24
|
-
getFileCallCount: (file) => fileCounters.get(file) ?? 0,
|
|
25
|
-
setFileCallCount: (file, count) => { fileCounters.set(file, count) },
|
|
26
|
-
}
|
|
27
|
-
}
|
package/src/server/rpc.ts
DELETED
|
@@ -1,177 +0,0 @@
|
|
|
1
|
-
// server() function + RPC registry
|
|
2
|
-
// On server: registers function for RPC with hash(filePath:index)
|
|
3
|
-
// On client: replaced by build plugin with fetch() stub
|
|
4
|
-
|
|
5
|
-
import { stringify } from "devalue"
|
|
6
|
-
import { hashRPC } from "./rpc-hash.ts"
|
|
7
|
-
|
|
8
|
-
export interface ServerOptions {
|
|
9
|
-
middleware?: unknown[]
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export type RPCHandler = (...args: unknown[]) => Promise<unknown>
|
|
13
|
-
|
|
14
|
-
export interface RPCRegistry {
|
|
15
|
-
getHandler(id: string): RPCHandler | undefined
|
|
16
|
-
setHandler(id: string, fn: RPCHandler): void
|
|
17
|
-
deleteHandler(id: string): void
|
|
18
|
-
clear(): void
|
|
19
|
-
getFileCallCount(file: string): number
|
|
20
|
-
setFileCallCount(file: string, count: number): void
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export function createMemoryRPCRegistry(): RPCRegistry {
|
|
24
|
-
const rpcHandlers = new Map<string, RPCHandler>()
|
|
25
|
-
const fileCallCounters = new Map<string, number>()
|
|
26
|
-
return {
|
|
27
|
-
getHandler: (id) => rpcHandlers.get(id),
|
|
28
|
-
setHandler: (id, fn) => { rpcHandlers.set(id, fn) },
|
|
29
|
-
deleteHandler: (id) => { rpcHandlers.delete(id) },
|
|
30
|
-
clear: () => {
|
|
31
|
-
rpcHandlers.clear()
|
|
32
|
-
fileCallCounters.clear()
|
|
33
|
-
},
|
|
34
|
-
getFileCallCount: (file) => fileCallCounters.get(file) ?? 0,
|
|
35
|
-
setFileCallCount: (file, count) => { fileCallCounters.set(file, count) },
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
const defaultRPCRegistry = createMemoryRPCRegistry()
|
|
40
|
-
|
|
41
|
-
export function __registerRPC(id: string, fn: RPCHandler): void {
|
|
42
|
-
defaultRPCRegistry.setHandler(id, fn)
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
export function __resetRPCState(): void {
|
|
46
|
-
defaultRPCRegistry.clear()
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
export function getRPCHandler(id: string): RPCHandler | undefined {
|
|
50
|
-
return defaultRPCRegistry.getHandler(id)
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
function getCallerFile(): string | null {
|
|
54
|
-
const orig = Error.prepareStackTrace
|
|
55
|
-
Error.prepareStackTrace = (_err, stack) => stack
|
|
56
|
-
const err = new Error()
|
|
57
|
-
const stack = err.stack as unknown as NodeJS.CallSite[]
|
|
58
|
-
Error.prepareStackTrace = orig
|
|
59
|
-
|
|
60
|
-
// Walk up stack: 0=getCallerFile, 1=server(), 2=caller (route file)
|
|
61
|
-
for (let i = 2; i < stack.length; i++) {
|
|
62
|
-
const file = stack[i]?.getFileName()
|
|
63
|
-
if (file && !file.includes("/server/rpc.ts") && !file.includes("node_modules")) {
|
|
64
|
-
return file
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
return null
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
// server() wrapper -- registers with hash-based ID matching client transform
|
|
71
|
-
export function server<TArgs extends unknown[], TReturn>(
|
|
72
|
-
fn: (...args: TArgs) => Promise<TReturn>,
|
|
73
|
-
_options?: ServerOptions
|
|
74
|
-
): (...args: TArgs) => Promise<TReturn> {
|
|
75
|
-
const callerFile = getCallerFile()
|
|
76
|
-
if (callerFile) {
|
|
77
|
-
const counter = defaultRPCRegistry.getFileCallCount(callerFile)
|
|
78
|
-
defaultRPCRegistry.setFileCallCount(callerFile, counter + 1)
|
|
79
|
-
const id = hashRPC(callerFile, counter)
|
|
80
|
-
defaultRPCRegistry.setHandler(id, fn as (...args: unknown[]) => Promise<unknown>)
|
|
81
|
-
}
|
|
82
|
-
return fn
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
export async function handleRPCRequestWithRegistry(
|
|
86
|
-
request: Request,
|
|
87
|
-
registry: Pick<RPCRegistry, "getHandler">,
|
|
88
|
-
): Promise<Response | null> {
|
|
89
|
-
const url = new URL(request.url)
|
|
90
|
-
const match = url.pathname.match(/^\/api\/_rpc\/([a-zA-Z0-9]+)$/)
|
|
91
|
-
if (!match) return null
|
|
92
|
-
|
|
93
|
-
const id = match[1]!
|
|
94
|
-
const handler = registry.getHandler(id)
|
|
95
|
-
|
|
96
|
-
if (!handler) {
|
|
97
|
-
return new Response(JSON.stringify({ error: `RPC handler not found: ${id}` }), {
|
|
98
|
-
status: 404,
|
|
99
|
-
headers: { "Content-Type": "application/json" },
|
|
100
|
-
})
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
try {
|
|
104
|
-
const MAX_RPC_BODY = 1024 * 1024 // 1MB
|
|
105
|
-
let args: unknown[] = []
|
|
106
|
-
if (request.method === "POST") {
|
|
107
|
-
const contentLength = Number(request.headers.get("content-length") ?? "0")
|
|
108
|
-
if (contentLength > MAX_RPC_BODY) {
|
|
109
|
-
return new Response(JSON.stringify({ error: "Request body too large" }), {
|
|
110
|
-
status: 413,
|
|
111
|
-
headers: { "Content-Type": "application/json" },
|
|
112
|
-
})
|
|
113
|
-
}
|
|
114
|
-
// Read body with actual size limit (Content-Length can be spoofed)
|
|
115
|
-
const reader = request.body?.getReader()
|
|
116
|
-
let bodyBytes = 0
|
|
117
|
-
const chunks: Uint8Array[] = []
|
|
118
|
-
if (reader) {
|
|
119
|
-
while (true) {
|
|
120
|
-
const { done, value } = await reader.read()
|
|
121
|
-
if (done) break
|
|
122
|
-
bodyBytes += value.byteLength
|
|
123
|
-
if (bodyBytes > MAX_RPC_BODY) {
|
|
124
|
-
reader.cancel()
|
|
125
|
-
return new Response(JSON.stringify({ error: "Request body too large" }), {
|
|
126
|
-
status: 413,
|
|
127
|
-
headers: { "Content-Type": "application/json" },
|
|
128
|
-
})
|
|
129
|
-
}
|
|
130
|
-
chunks.push(value)
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
const body = new TextDecoder().decode(
|
|
134
|
-
chunks.length === 1 ? chunks[0] : Buffer.concat(chunks),
|
|
135
|
-
)
|
|
136
|
-
if (body) {
|
|
137
|
-
let parsed: unknown
|
|
138
|
-
try {
|
|
139
|
-
parsed = JSON.parse(body)
|
|
140
|
-
} catch {
|
|
141
|
-
return new Response(JSON.stringify({ error: "Invalid JSON in request body" }), {
|
|
142
|
-
status: 400,
|
|
143
|
-
headers: { "Content-Type": "application/json" },
|
|
144
|
-
})
|
|
145
|
-
}
|
|
146
|
-
if (!Array.isArray(parsed)) {
|
|
147
|
-
return new Response(JSON.stringify({ error: "RPC args must be an array" }), {
|
|
148
|
-
status: 400,
|
|
149
|
-
headers: { "Content-Type": "application/json" },
|
|
150
|
-
})
|
|
151
|
-
}
|
|
152
|
-
args = parsed
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
const result = await handler(...args)
|
|
157
|
-
const serialized = stringify(result)
|
|
158
|
-
|
|
159
|
-
return new Response(serialized, {
|
|
160
|
-
status: 200,
|
|
161
|
-
headers: { "Content-Type": "application/json" },
|
|
162
|
-
})
|
|
163
|
-
} catch (err) {
|
|
164
|
-
// Don't leak internal error details to the client
|
|
165
|
-
const isDev = process.env.NODE_ENV !== "production"
|
|
166
|
-
const message = isDev && err instanceof Error ? err.message : "Internal server error"
|
|
167
|
-
return new Response(JSON.stringify({ error: message }), {
|
|
168
|
-
status: 500,
|
|
169
|
-
headers: { "Content-Type": "application/json" },
|
|
170
|
-
})
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
// RPC HTTP handler
|
|
175
|
-
export async function handleRPCRequest(request: Request): Promise<Response | null> {
|
|
176
|
-
return handleRPCRequestWithRegistry(request, defaultRPCRegistry)
|
|
177
|
-
}
|
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
import { Database } from "bun:sqlite"
|
|
2
|
-
import type { CacheEntry, CacheStore } from "./cache.ts"
|
|
3
|
-
|
|
4
|
-
interface SQLiteCacheStoreOptions {
|
|
5
|
-
maxEntryAgeMs?: number
|
|
6
|
-
pruneExpiredOnInit?: boolean
|
|
7
|
-
pruneExpiredOnGet?: boolean
|
|
8
|
-
pruneExpiredOnSet?: boolean
|
|
9
|
-
pruneExpiredOnKeys?: boolean
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
function ensureCacheTable(sqlite: Database): void {
|
|
13
|
-
sqlite.run(`
|
|
14
|
-
CREATE TABLE IF NOT EXISTS gorsee_route_cache (
|
|
15
|
-
cache_key TEXT PRIMARY KEY,
|
|
16
|
-
body TEXT NOT NULL,
|
|
17
|
-
headers TEXT NOT NULL,
|
|
18
|
-
status INTEGER NOT NULL,
|
|
19
|
-
created_at INTEGER NOT NULL,
|
|
20
|
-
revalidating INTEGER NOT NULL DEFAULT 0
|
|
21
|
-
)
|
|
22
|
-
`)
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
function pruneExpiredRows(sqlite: Database, maxEntryAgeMs: number, now: number = Date.now()): number {
|
|
26
|
-
const cutoff = now - maxEntryAgeMs
|
|
27
|
-
const result = sqlite.prepare("DELETE FROM gorsee_route_cache WHERE created_at <= ?1").run(cutoff)
|
|
28
|
-
return (result as { changes?: number }).changes ?? 0
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export function createSQLiteCacheStore(
|
|
32
|
-
path = ":memory:",
|
|
33
|
-
options: SQLiteCacheStoreOptions = {},
|
|
34
|
-
): CacheStore & { close(): void; deleteExpired(now?: number): number } {
|
|
35
|
-
const sqlite = new Database(path)
|
|
36
|
-
sqlite.run("PRAGMA journal_mode=WAL;")
|
|
37
|
-
ensureCacheTable(sqlite)
|
|
38
|
-
const {
|
|
39
|
-
maxEntryAgeMs = 24 * 60 * 60 * 1000,
|
|
40
|
-
pruneExpiredOnInit = true,
|
|
41
|
-
pruneExpiredOnGet = true,
|
|
42
|
-
pruneExpiredOnSet = true,
|
|
43
|
-
pruneExpiredOnKeys = true,
|
|
44
|
-
} = options
|
|
45
|
-
|
|
46
|
-
if (pruneExpiredOnInit) pruneExpiredRows(sqlite, maxEntryAgeMs)
|
|
47
|
-
|
|
48
|
-
return {
|
|
49
|
-
async get(key) {
|
|
50
|
-
if (pruneExpiredOnGet) pruneExpiredRows(sqlite, maxEntryAgeMs)
|
|
51
|
-
const row = sqlite.prepare(`
|
|
52
|
-
SELECT body, headers, status, created_at, revalidating
|
|
53
|
-
FROM gorsee_route_cache
|
|
54
|
-
WHERE cache_key = ?1
|
|
55
|
-
`).get(key) as {
|
|
56
|
-
body: string
|
|
57
|
-
headers: string
|
|
58
|
-
status: number
|
|
59
|
-
created_at: number
|
|
60
|
-
revalidating: number
|
|
61
|
-
} | null
|
|
62
|
-
if (!row) return undefined
|
|
63
|
-
return {
|
|
64
|
-
body: row.body,
|
|
65
|
-
headers: JSON.parse(row.headers) as Record<string, string>,
|
|
66
|
-
status: row.status,
|
|
67
|
-
createdAt: row.created_at,
|
|
68
|
-
revalidating: row.revalidating === 1,
|
|
69
|
-
}
|
|
70
|
-
},
|
|
71
|
-
async set(key, entry) {
|
|
72
|
-
if (pruneExpiredOnSet) pruneExpiredRows(sqlite, maxEntryAgeMs)
|
|
73
|
-
sqlite.prepare(`
|
|
74
|
-
INSERT INTO gorsee_route_cache (cache_key, body, headers, status, created_at, revalidating)
|
|
75
|
-
VALUES (?1, ?2, ?3, ?4, ?5, ?6)
|
|
76
|
-
ON CONFLICT(cache_key) DO UPDATE SET
|
|
77
|
-
body = excluded.body,
|
|
78
|
-
headers = excluded.headers,
|
|
79
|
-
status = excluded.status,
|
|
80
|
-
created_at = excluded.created_at,
|
|
81
|
-
revalidating = excluded.revalidating
|
|
82
|
-
`).run(
|
|
83
|
-
key,
|
|
84
|
-
entry.body,
|
|
85
|
-
JSON.stringify(entry.headers),
|
|
86
|
-
entry.status,
|
|
87
|
-
entry.createdAt,
|
|
88
|
-
entry.revalidating ? 1 : 0,
|
|
89
|
-
)
|
|
90
|
-
},
|
|
91
|
-
async delete(key) {
|
|
92
|
-
sqlite.prepare("DELETE FROM gorsee_route_cache WHERE cache_key = ?1").run(key)
|
|
93
|
-
},
|
|
94
|
-
async clear() {
|
|
95
|
-
sqlite.prepare("DELETE FROM gorsee_route_cache").run()
|
|
96
|
-
},
|
|
97
|
-
async keys() {
|
|
98
|
-
if (pruneExpiredOnKeys) pruneExpiredRows(sqlite, maxEntryAgeMs)
|
|
99
|
-
const rows = sqlite.prepare("SELECT cache_key FROM gorsee_route_cache").all() as Array<{ cache_key: string }>
|
|
100
|
-
return rows.map((row) => row.cache_key)
|
|
101
|
-
},
|
|
102
|
-
deleteExpired(now = Date.now()) {
|
|
103
|
-
return pruneExpiredRows(sqlite, maxEntryAgeMs, now)
|
|
104
|
-
},
|
|
105
|
-
close() {
|
|
106
|
-
sqlite.close()
|
|
107
|
-
},
|
|
108
|
-
}
|
|
109
|
-
}
|
package/src/server/sse.ts
DELETED
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
import { createSignal, type SignalGetter } from "../reactive/signal.ts"
|
|
2
|
-
|
|
3
|
-
export interface SSEOptions {
|
|
4
|
-
headers?: Record<string, string>
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
export interface SSEStream {
|
|
8
|
-
response: Response
|
|
9
|
-
send: (event: string, data: unknown) => void
|
|
10
|
-
close: () => void
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export function createSSEStream(options?: SSEOptions): SSEStream {
|
|
14
|
-
let controller: ReadableStreamDefaultController<Uint8Array> | null = null
|
|
15
|
-
const encoder = new TextEncoder()
|
|
16
|
-
|
|
17
|
-
const stream = new ReadableStream<Uint8Array>({
|
|
18
|
-
start(ctrl) {
|
|
19
|
-
controller = ctrl
|
|
20
|
-
},
|
|
21
|
-
cancel() {
|
|
22
|
-
controller = null
|
|
23
|
-
},
|
|
24
|
-
})
|
|
25
|
-
|
|
26
|
-
const response = new Response(stream, {
|
|
27
|
-
headers: {
|
|
28
|
-
"Content-Type": "text/event-stream",
|
|
29
|
-
"Cache-Control": "no-cache",
|
|
30
|
-
Connection: "keep-alive",
|
|
31
|
-
...options?.headers,
|
|
32
|
-
},
|
|
33
|
-
})
|
|
34
|
-
|
|
35
|
-
function send(event: string, data: unknown): void {
|
|
36
|
-
if (!controller) return
|
|
37
|
-
const payload = `event: ${event}\ndata: ${JSON.stringify(data)}\n\n`
|
|
38
|
-
controller.enqueue(encoder.encode(payload))
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
function close(): void {
|
|
42
|
-
if (controller) {
|
|
43
|
-
controller.close()
|
|
44
|
-
controller = null
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
return { response, send, close }
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
// --- Client-side: reactive EventSource signal ---
|
|
52
|
-
|
|
53
|
-
export interface EventSourceSignal<T> {
|
|
54
|
-
readonly value: SignalGetter<T>
|
|
55
|
-
readonly connected: SignalGetter<boolean>
|
|
56
|
-
close: () => void
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
export function createEventSource<T>(
|
|
60
|
-
url: string,
|
|
61
|
-
event: string,
|
|
62
|
-
initialValue: T,
|
|
63
|
-
): EventSourceSignal<T> {
|
|
64
|
-
const [value, setValue] = createSignal<T>(initialValue)
|
|
65
|
-
const [connected, setConnected] = createSignal(false)
|
|
66
|
-
|
|
67
|
-
if (typeof globalThis.EventSource === "undefined") {
|
|
68
|
-
return { value, connected, close: () => {} }
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
const source = new EventSource(url)
|
|
72
|
-
|
|
73
|
-
source.addEventListener("open", () => {
|
|
74
|
-
setConnected(true)
|
|
75
|
-
})
|
|
76
|
-
|
|
77
|
-
source.addEventListener(event, (e: MessageEvent) => {
|
|
78
|
-
try {
|
|
79
|
-
const parsed = JSON.parse(String(e.data)) as T
|
|
80
|
-
setValue(parsed)
|
|
81
|
-
} catch {
|
|
82
|
-
// ignore malformed messages
|
|
83
|
-
}
|
|
84
|
-
})
|
|
85
|
-
|
|
86
|
-
source.addEventListener("error", () => {
|
|
87
|
-
setConnected(false)
|
|
88
|
-
})
|
|
89
|
-
|
|
90
|
-
function close(): void {
|
|
91
|
-
source.close()
|
|
92
|
-
setConnected(false)
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
return { value, connected, close }
|
|
96
|
-
}
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
import { getMimeType } from "./mime.ts"
|
|
2
|
-
import { fileETag, isNotModified } from "./etag.ts"
|
|
3
|
-
import { resolve } from "node:path"
|
|
4
|
-
|
|
5
|
-
export interface StaticFileOptions {
|
|
6
|
-
contentType?: string
|
|
7
|
-
cacheControl?: string
|
|
8
|
-
request?: Request
|
|
9
|
-
etag?: boolean
|
|
10
|
-
extraHeaders?: Record<string, string>
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export async function serveStaticFile(
|
|
14
|
-
rootDir: string,
|
|
15
|
-
relativePath: string,
|
|
16
|
-
options: StaticFileOptions = {},
|
|
17
|
-
): Promise<Response | null> {
|
|
18
|
-
const {
|
|
19
|
-
contentType,
|
|
20
|
-
cacheControl,
|
|
21
|
-
request,
|
|
22
|
-
etag = false,
|
|
23
|
-
extraHeaders = {},
|
|
24
|
-
} = options
|
|
25
|
-
|
|
26
|
-
try {
|
|
27
|
-
const filePath = resolve(rootDir, relativePath)
|
|
28
|
-
if (!filePath.startsWith(rootDir)) return null
|
|
29
|
-
|
|
30
|
-
const file = Bun.file(filePath)
|
|
31
|
-
if (!await file.exists()) return null
|
|
32
|
-
|
|
33
|
-
const headers: Record<string, string> = {
|
|
34
|
-
"Content-Type": contentType ?? getMimeType(filePath),
|
|
35
|
-
...extraHeaders,
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
if (cacheControl) headers["Cache-Control"] = cacheControl
|
|
39
|
-
|
|
40
|
-
if (etag) {
|
|
41
|
-
const tag = await fileETag(filePath)
|
|
42
|
-
if (tag && request && isNotModified(request, tag)) {
|
|
43
|
-
return new Response(null, { status: 304, headers: extraHeaders })
|
|
44
|
-
}
|
|
45
|
-
if (tag) headers["ETag"] = tag
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
return new Response(file, { headers })
|
|
49
|
-
} catch {
|
|
50
|
-
return null
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
export async function servePrefixedStaticFile(
|
|
55
|
-
pathname: string,
|
|
56
|
-
prefix: string,
|
|
57
|
-
rootDir: string,
|
|
58
|
-
options: StaticFileOptions = {},
|
|
59
|
-
): Promise<Response | null> {
|
|
60
|
-
if (!pathname.startsWith(prefix)) return null
|
|
61
|
-
const relativePath = pathname.slice(prefix.length)
|
|
62
|
-
return serveStaticFile(rootDir, relativePath, options)
|
|
63
|
-
}
|