silgi 0.43.28 → 0.50.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +103 -1
- package/dist/_virtual/_rolldown/runtime.mjs +5 -0
- package/dist/adapters/_fetch-adapter.d.mts +18 -0
- package/dist/adapters/_fetch-adapter.mjs +53 -0
- package/dist/adapters/astro.d.mts +15 -0
- package/dist/adapters/astro.mjs +31 -0
- package/dist/adapters/aws-lambda.d.mts +42 -0
- package/dist/adapters/aws-lambda.mjs +92 -0
- package/dist/adapters/express.d.mts +16 -0
- package/dist/adapters/express.mjs +110 -0
- package/dist/adapters/message-port.d.mts +42 -0
- package/dist/adapters/message-port.mjs +132 -0
- package/dist/adapters/nestjs.d.mts +25 -0
- package/dist/adapters/nestjs.mjs +83 -0
- package/dist/adapters/nextjs.d.mts +14 -0
- package/dist/adapters/nextjs.mjs +29 -0
- package/dist/adapters/peer.d.mts +27 -0
- package/dist/adapters/peer.mjs +36 -0
- package/dist/adapters/remix.d.mts +15 -0
- package/dist/adapters/remix.mjs +30 -0
- package/dist/adapters/solidstart.d.mts +12 -0
- package/dist/adapters/solidstart.mjs +29 -0
- package/dist/adapters/sveltekit.d.mts +14 -0
- package/dist/adapters/sveltekit.mjs +30 -0
- package/dist/broker/index.d.mts +62 -0
- package/dist/broker/index.mjs +153 -0
- package/dist/broker/nats.d.mts +33 -0
- package/dist/broker/nats.mjs +31 -0
- package/dist/broker/redis.d.mts +51 -0
- package/dist/broker/redis.mjs +92 -0
- package/dist/builder.d.mts +55 -0
- package/dist/builder.mjs +70 -0
- package/dist/callable.d.mts +19 -0
- package/dist/callable.mjs +42 -0
- package/dist/caller.mjs +90 -0
- package/dist/client/adapters/fetch/index.d.mts +15 -0
- package/dist/client/adapters/fetch/index.mjs +57 -0
- package/dist/client/adapters/ofetch/index.d.mts +55 -0
- package/dist/client/adapters/ofetch/index.mjs +91 -0
- package/dist/client/adapters/websocket/index.d.mts +20 -0
- package/dist/client/adapters/websocket/index.mjs +101 -0
- package/dist/client/client.d.mts +37 -0
- package/dist/client/client.mjs +80 -0
- package/dist/client/consume.d.mts +50 -0
- package/dist/client/consume.mjs +66 -0
- package/dist/client/dynamic-link.d.mts +16 -0
- package/dist/client/dynamic-link.mjs +19 -0
- package/dist/client/index.d.mts +6 -0
- package/dist/client/index.mjs +5 -0
- package/dist/client/interceptor.d.mts +31 -0
- package/dist/client/interceptor.mjs +34 -0
- package/dist/client/openapi.d.mts +29 -0
- package/dist/client/openapi.mjs +89 -0
- package/dist/client/plugins/batch.d.mts +26 -0
- package/dist/client/plugins/batch.mjs +64 -0
- package/dist/client/plugins/circuit-breaker.d.mts +24 -0
- package/dist/client/plugins/circuit-breaker.mjs +60 -0
- package/dist/client/plugins/csrf.d.mts +13 -0
- package/dist/client/plugins/csrf.mjs +20 -0
- package/dist/client/plugins/dedupe.d.mts +10 -0
- package/dist/client/plugins/dedupe.mjs +28 -0
- package/dist/client/plugins/index.d.mts +8 -0
- package/dist/client/plugins/index.mjs +8 -0
- package/dist/client/plugins/otel.d.mts +12 -0
- package/dist/client/plugins/otel.mjs +27 -0
- package/dist/client/plugins/retry.d.mts +34 -0
- package/dist/client/plugins/retry.mjs +79 -0
- package/dist/client/plugins/timeout.d.mts +10 -0
- package/dist/client/plugins/timeout.mjs +14 -0
- package/dist/client/server.d.mts +16 -0
- package/dist/client/server.mjs +59 -0
- package/dist/client/types.d.mts +29 -0
- package/dist/codec/devalue.d.mts +21 -0
- package/dist/codec/devalue.mjs +33 -0
- package/dist/codec/msgpack.d.mts +18 -0
- package/dist/codec/msgpack.mjs +45 -0
- package/dist/codec/sanitize.mjs +38 -0
- package/dist/codegen/emitters.d.mts +51 -0
- package/dist/codegen/emitters.mjs +143 -0
- package/dist/codegen/generate.d.mts +25 -0
- package/dist/codegen/generate.mjs +224 -0
- package/dist/codegen/index.d.mts +44 -0
- package/dist/codegen/index.mjs +103 -0
- package/dist/codegen/parse.d.mts +124 -0
- package/dist/codegen/parse.mjs +135 -0
- package/dist/codegen/preserve.d.mts +21 -0
- package/dist/codegen/preserve.mjs +62 -0
- package/dist/codegen/schema-to-code.d.mts +57 -0
- package/dist/codegen/schema-to-code.mjs +167 -0
- package/dist/compile.d.mts +46 -0
- package/dist/compile.mjs +332 -0
- package/dist/core/codec.mjs +67 -0
- package/dist/core/context-bridge.mjs +11 -0
- package/dist/core/dispatch.mjs +62 -0
- package/dist/core/error.d.mts +99 -60
- package/dist/core/error.mjs +125 -92
- package/dist/core/handler.d.mts +6 -0
- package/dist/core/handler.mjs +153 -0
- package/dist/core/input.mjs +49 -0
- package/dist/core/iterator.d.mts +17 -0
- package/dist/core/iterator.mjs +79 -0
- package/dist/core/router-utils.mjs +22 -0
- package/dist/core/schema.d.mts +20 -0
- package/dist/core/schema.mjs +33 -0
- package/dist/core/serve.d.mts +51 -0
- package/dist/core/serve.mjs +76 -0
- package/dist/core/sse.d.mts +18 -0
- package/dist/core/sse.mjs +110 -0
- package/dist/core/storage.d.mts +17 -4
- package/dist/core/storage.mjs +60 -13
- package/dist/core/task.d.mts +62 -0
- package/dist/core/task.mjs +165 -0
- package/dist/core/trace-map.d.mts +13 -0
- package/dist/core/trace-map.mjs +13 -0
- package/dist/core/url.mjs +28 -0
- package/dist/core/utils.mjs +24 -0
- package/dist/index.d.mts +17 -21
- package/dist/index.mjs +14 -22
- package/dist/integrations/ai/index.d.mts +25 -0
- package/dist/integrations/ai/index.mjs +117 -0
- package/dist/integrations/better-auth/index.d.mts +41 -0
- package/dist/integrations/better-auth/index.mjs +331 -0
- package/dist/integrations/drizzle/index.d.mts +27 -0
- package/dist/integrations/drizzle/index.mjs +285 -0
- package/dist/integrations/hey-api/index.d.mts +2 -0
- package/dist/integrations/hey-api/index.mjs +2 -0
- package/dist/integrations/hey-api/to-client.d.mts +20 -0
- package/dist/integrations/hey-api/to-client.mjs +39 -0
- package/dist/integrations/pinia-colada/general-utils.d.mts +13 -0
- package/dist/integrations/pinia-colada/general-utils.mjs +9 -0
- package/dist/integrations/pinia-colada/index.d.mts +6 -0
- package/dist/integrations/pinia-colada/index.mjs +5 -0
- package/dist/integrations/pinia-colada/key.d.mts +11 -0
- package/dist/integrations/pinia-colada/key.mjs +11 -0
- package/dist/integrations/pinia-colada/procedure-utils.d.mts +25 -0
- package/dist/integrations/pinia-colada/procedure-utils.mjs +33 -0
- package/dist/integrations/pinia-colada/router-utils.d.mts +17 -0
- package/dist/integrations/pinia-colada/router-utils.mjs +30 -0
- package/dist/integrations/pinia-colada/types.d.mts +25 -0
- package/dist/integrations/react/index.d.mts +83 -0
- package/dist/integrations/react/index.mjs +196 -0
- package/dist/integrations/tanstack-query/index.d.mts +120 -0
- package/dist/integrations/tanstack-query/index.mjs +100 -0
- package/dist/integrations/tanstack-query/ssr.d.mts +60 -0
- package/dist/integrations/tanstack-query/ssr.mjs +102 -0
- package/dist/integrations/zod/converter.d.mts +75 -0
- package/dist/integrations/zod/converter.mjs +345 -0
- package/dist/integrations/zod/index.d.mts +2 -0
- package/dist/integrations/zod/index.mjs +2 -0
- package/dist/lazy.d.mts +22 -0
- package/dist/lazy.mjs +34 -0
- package/dist/lifecycle.d.mts +36 -0
- package/dist/lifecycle.mjs +46 -0
- package/dist/map-input.d.mts +17 -0
- package/dist/map-input.mjs +47 -0
- package/dist/plugins/analytics/accumulator.d.mts +24 -0
- package/dist/plugins/analytics/accumulator.mjs +91 -0
- package/dist/plugins/analytics/alerts.d.mts +59 -0
- package/dist/plugins/analytics/alerts.mjs +140 -0
- package/dist/plugins/analytics/collector.d.mts +38 -0
- package/dist/plugins/analytics/collector.mjs +275 -0
- package/dist/plugins/analytics/cost.d.mts +61 -0
- package/dist/plugins/analytics/cost.mjs +97 -0
- package/dist/plugins/analytics/export.d.mts +7 -0
- package/dist/plugins/analytics/export.mjs +86 -0
- package/dist/plugins/analytics/normalize.mjs +144 -0
- package/dist/plugins/analytics/query.mjs +164 -0
- package/dist/plugins/analytics/request-id.mjs +34 -0
- package/dist/plugins/analytics/routes.d.mts +11 -0
- package/dist/plugins/analytics/routes.mjs +211 -0
- package/dist/plugins/analytics/sse.d.mts +31 -0
- package/dist/plugins/analytics/sse.mjs +74 -0
- package/dist/plugins/analytics/store.mjs +103 -0
- package/dist/plugins/analytics/timeseries.d.mts +50 -0
- package/dist/plugins/analytics/timeseries.mjs +169 -0
- package/dist/plugins/analytics/trace.d.mts +48 -0
- package/dist/plugins/analytics/trace.mjs +83 -0
- package/dist/plugins/analytics/types.d.mts +145 -0
- package/dist/plugins/analytics/types.mjs +40 -0
- package/dist/plugins/analytics/utils.d.mts +4 -0
- package/dist/plugins/analytics/utils.mjs +56 -0
- package/dist/plugins/analytics.d.mts +18 -0
- package/dist/plugins/analytics.mjs +188 -0
- package/dist/plugins/batch-server.d.mts +20 -0
- package/dist/plugins/batch-server.mjs +91 -0
- package/dist/plugins/body-limit.d.mts +19 -0
- package/dist/plugins/body-limit.mjs +49 -0
- package/dist/plugins/cache.d.mts +170 -0
- package/dist/plugins/cache.mjs +212 -0
- package/dist/plugins/coerce.d.mts +24 -0
- package/dist/plugins/coerce.mjs +70 -0
- package/dist/plugins/cookies.d.mts +14 -0
- package/dist/plugins/cookies.mjs +48 -0
- package/dist/plugins/cors.d.mts +43 -0
- package/dist/plugins/cors.mjs +62 -0
- package/dist/plugins/file-upload.d.mts +38 -0
- package/dist/plugins/file-upload.mjs +102 -0
- package/dist/plugins/index.d.mts +18 -0
- package/dist/plugins/index.mjs +17 -0
- package/dist/plugins/otel.d.mts +35 -0
- package/dist/plugins/otel.mjs +40 -0
- package/dist/plugins/pino.d.mts +60 -0
- package/dist/plugins/pino.mjs +42 -0
- package/dist/plugins/pubsub.d.mts +50 -0
- package/dist/plugins/pubsub.mjs +53 -0
- package/dist/plugins/ratelimit.d.mts +53 -0
- package/dist/plugins/ratelimit.mjs +92 -0
- package/dist/plugins/signing.d.mts +41 -0
- package/dist/plugins/signing.mjs +118 -0
- package/dist/plugins/strict-get.d.mts +10 -0
- package/dist/plugins/strict-get.mjs +33 -0
- package/dist/scalar.d.mts +49 -0
- package/dist/scalar.mjs +311 -0
- package/dist/silgi.d.mts +144 -0
- package/dist/silgi.mjs +164 -0
- package/dist/trpc-interop.d.mts +22 -0
- package/dist/trpc-interop.mjs +68 -0
- package/dist/types.d.mts +108 -0
- package/dist/ws.d.mts +88 -0
- package/dist/ws.mjs +205 -0
- package/lib/dashboard/index.html +120 -0
- package/lib/ocache.d.mts +1 -0
- package/lib/ocache.mjs +1 -0
- package/lib/ofetch.d.mts +1 -0
- package/lib/ofetch.mjs +1 -0
- package/lib/srvx.d.mts +1 -0
- package/lib/srvx.mjs +1 -0
- package/lib/unstorage.d.mts +1 -0
- package/lib/unstorage.mjs +1 -0
- package/package.json +314 -150
- package/dist/build.d.mts +0 -3
- package/dist/build.mjs +0 -4
- package/dist/cli/build/build.mjs +0 -15
- package/dist/cli/build/dev.d.mts +0 -10
- package/dist/cli/build/dev.mjs +0 -91
- package/dist/cli/build/prepare.d.mts +0 -6
- package/dist/cli/build/prepare.mjs +0 -15
- package/dist/cli/commands/commands.mjs +0 -90
- package/dist/cli/commands/env.mjs +0 -53
- package/dist/cli/commands/init.mjs +0 -84
- package/dist/cli/commands/install.mjs +0 -52
- package/dist/cli/commands/prepare.mjs +0 -65
- package/dist/cli/commands/reset.mjs +0 -46
- package/dist/cli/commands/run.mjs +0 -31
- package/dist/cli/commands/watch.mjs +0 -153
- package/dist/cli/config/defaults.mjs +0 -117
- package/dist/cli/config/index.d.mts +0 -3
- package/dist/cli/config/index.mjs +0 -4
- package/dist/cli/config/loader.d.mts +0 -6
- package/dist/cli/config/loader.mjs +0 -71
- package/dist/cli/config/resolvers/compatibility.mjs +0 -71
- package/dist/cli/config/resolvers/imports.mjs +0 -35
- package/dist/cli/config/resolvers/paths.mjs +0 -98
- package/dist/cli/config/resolvers/storage.mjs +0 -23
- package/dist/cli/config/resolvers/url.mjs +0 -9
- package/dist/cli/config/types.d.mts +0 -14
- package/dist/cli/config/types.mjs +0 -147
- package/dist/cli/core/apiful.mjs +0 -36
- package/dist/cli/core/devServer.mjs +0 -10
- package/dist/cli/core/env.mjs +0 -68
- package/dist/cli/core/installPackage.mjs +0 -60
- package/dist/cli/core/runtimeConfig.mjs +0 -70
- package/dist/cli/core/scan.mjs +0 -35
- package/dist/cli/core/silgi.mjs +0 -111
- package/dist/cli/framework/emptyFramework.mjs +0 -7
- package/dist/cli/framework/h3.mjs +0 -55
- package/dist/cli/framework/index.mjs +0 -15
- package/dist/cli/framework/nitro.mjs +0 -24
- package/dist/cli/framework/nuxt.mjs +0 -10
- package/dist/cli/index.d.mts +0 -1
- package/dist/cli/index.mjs +0 -29
- package/dist/cli/module/exportScan.mjs +0 -180
- package/dist/cli/module/install.mjs +0 -49
- package/dist/cli/module/scan.mjs +0 -193
- package/dist/cli/scan/prepareCommands.mjs +0 -40
- package/dist/cli/scan/prepareConfigs.mjs +0 -33
- package/dist/cli/scan/prepareCoreFile.mjs +0 -118
- package/dist/cli/scan/prepareScanFile.mjs +0 -59
- package/dist/cli/scan/prepareSchema.mjs +0 -128
- package/dist/cli/scan/scanExportFile.mjs +0 -288
- package/dist/cli/scan/writeCoreFile.mjs +0 -22
- package/dist/cli/scan/writeTypesAndFiles.mjs +0 -72
- package/dist/cli/utils/cancel.mjs +0 -14
- package/dist/cli/utils/common.mjs +0 -15
- package/dist/cli/utils/compatibility.mjs +0 -33
- package/dist/cli/utils/debug.mjs +0 -11
- package/dist/cli/utils/ignore.mjs +0 -56
- package/dist/cli/utils/processManager.mjs +0 -170
- package/dist/cli/utils/readScanFile.mjs +0 -58
- package/dist/cli/utils/storage.mjs +0 -23
- package/dist/core/context.d.mts +0 -30
- package/dist/core/context.mjs +0 -32
- package/dist/core/createSilgi.d.mts +0 -6
- package/dist/core/createSilgi.mjs +0 -153
- package/dist/core/event.d.mts +0 -26
- package/dist/core/event.mjs +0 -44
- package/dist/core/index.d.mts +0 -25
- package/dist/core/index.mjs +0 -30
- package/dist/core/orchestrate.mjs +0 -115
- package/dist/core/response.d.mts +0 -20
- package/dist/core/response.mjs +0 -105
- package/dist/core/silgi.d.mts +0 -19
- package/dist/core/silgi.mjs +0 -141
- package/dist/core/silgiApp.d.mts +0 -9
- package/dist/core/silgiApp.mjs +0 -23
- package/dist/core/unctx.d.mts +0 -21
- package/dist/core/unctx.mjs +0 -35
- package/dist/core/utils/event-stream.d.mts +0 -53
- package/dist/core/utils/event-stream.mjs +0 -38
- package/dist/core/utils/event.d.mts +0 -8
- package/dist/core/utils/event.mjs +0 -12
- package/dist/core/utils/internal/event-stream.d.mts +0 -45
- package/dist/core/utils/internal/event-stream.mjs +0 -137
- package/dist/core/utils/internal/obj.mjs +0 -9
- package/dist/core/utils/internal/object.mjs +0 -29
- package/dist/core/utils/internal/query.mjs +0 -73
- package/dist/core/utils/internal/req.mjs +0 -35
- package/dist/core/utils/merge.d.mts +0 -14
- package/dist/core/utils/merge.mjs +0 -27
- package/dist/core/utils/middleware.d.mts +0 -14
- package/dist/core/utils/middleware.mjs +0 -12
- package/dist/core/utils/request.mjs +0 -35
- package/dist/core/utils/resolver.d.mts +0 -7
- package/dist/core/utils/resolver.mjs +0 -29
- package/dist/core/utils/runtime.d.mts +0 -7
- package/dist/core/utils/runtime.mjs +0 -20
- package/dist/core/utils/sanitize.mjs +0 -22
- package/dist/core/utils/schema.d.mts +0 -34
- package/dist/core/utils/schema.mjs +0 -33
- package/dist/core/utils/service.d.mts +0 -13
- package/dist/core/utils/service.mjs +0 -19
- package/dist/core/utils/shared.d.mts +0 -6
- package/dist/core/utils/shared.mjs +0 -7
- package/dist/core/utils/storage.d.mts +0 -24
- package/dist/core/utils/storage.mjs +0 -54
- package/dist/kit/add/add-commands.d.mts +0 -6
- package/dist/kit/add/add-commands.mjs +0 -12
- package/dist/kit/add/add-core-file.d.mts +0 -9
- package/dist/kit/add/add-core-file.mjs +0 -11
- package/dist/kit/add/add-imports.d.mts +0 -14
- package/dist/kit/add/add-imports.mjs +0 -56
- package/dist/kit/add/add-npm.d.mts +0 -14
- package/dist/kit/add/add-npm.mjs +0 -23
- package/dist/kit/define.d.mts +0 -28
- package/dist/kit/define.mjs +0 -25
- package/dist/kit/errors.d.mts +0 -6
- package/dist/kit/errors.mjs +0 -11
- package/dist/kit/esm.d.mts +0 -11
- package/dist/kit/esm.mjs +0 -21
- package/dist/kit/fs.d.mts +0 -4
- package/dist/kit/fs.mjs +0 -13
- package/dist/kit/function-utils.d.mts +0 -27
- package/dist/kit/function-utils.mjs +0 -75
- package/dist/kit/gen.d.mts +0 -5
- package/dist/kit/gen.mjs +0 -26
- package/dist/kit/hash.d.mts +0 -4
- package/dist/kit/hash.mjs +0 -10
- package/dist/kit/index.d.mts +0 -22
- package/dist/kit/index.mjs +0 -23
- package/dist/kit/isFramework.d.mts +0 -6
- package/dist/kit/isFramework.mjs +0 -21
- package/dist/kit/logger.d.mts +0 -6
- package/dist/kit/logger.mjs +0 -10
- package/dist/kit/migration.d.mts +0 -113
- package/dist/kit/migration.mjs +0 -301
- package/dist/kit/module.d.mts +0 -14
- package/dist/kit/module.mjs +0 -53
- package/dist/kit/path.d.mts +0 -7
- package/dist/kit/path.mjs +0 -26
- package/dist/kit/preset.d.mts +0 -8
- package/dist/kit/preset.mjs +0 -11
- package/dist/kit/resolve.d.mts +0 -37
- package/dist/kit/resolve.mjs +0 -82
- package/dist/kit/template.d.mts +0 -19
- package/dist/kit/template.mjs +0 -91
- package/dist/kit/useRequest.d.mts +0 -19
- package/dist/kit/useRequest.mjs +0 -63
- package/dist/kit/utils.d.mts +0 -34
- package/dist/kit/utils.mjs +0 -91
- package/dist/package.mjs +0 -176
- package/dist/presets/_all.gen.d.mts +0 -6
- package/dist/presets/_all.gen.mjs +0 -18
- package/dist/presets/_resolve.d.mts +0 -12
- package/dist/presets/_resolve.mjs +0 -57
- package/dist/presets/_types.gen.d.mts +0 -8
- package/dist/presets/_types.gen.mjs +0 -5
- package/dist/presets/h3/preset.d.mts +0 -6
- package/dist/presets/h3/preset.mjs +0 -35
- package/dist/presets/hono/preset.d.mts +0 -6
- package/dist/presets/hono/preset.mjs +0 -30
- package/dist/presets/index.d.mts +0 -3
- package/dist/presets/index.mjs +0 -3
- package/dist/presets/nitro/preset.d.mts +0 -6
- package/dist/presets/nitro/preset.mjs +0 -37
- package/dist/presets/npmpackage/preset.d.mts +0 -6
- package/dist/presets/npmpackage/preset.mjs +0 -29
- package/dist/presets/nuxt/preset.d.mts +0 -6
- package/dist/presets/nuxt/preset.mjs +0 -41
- package/dist/runtime/index.d.mts +0 -4
- package/dist/runtime/index.mjs +0 -5
- package/dist/runtime/internal/config.d.mts +0 -11
- package/dist/runtime/internal/config.mjs +0 -97
- package/dist/runtime/internal/debug.d.mts +0 -6
- package/dist/runtime/internal/debug.mjs +0 -11
- package/dist/runtime/internal/defu.d.mts +0 -4
- package/dist/runtime/internal/defu.mjs +0 -9
- package/dist/runtime/internal/index.d.mts +0 -7
- package/dist/runtime/internal/index.mjs +0 -8
- package/dist/runtime/internal/nitro.d.mts +0 -6
- package/dist/runtime/internal/nitro.mjs +0 -36
- package/dist/runtime/internal/nuxt.d.mts +0 -12
- package/dist/runtime/internal/nuxt.mjs +0 -16
- package/dist/runtime/internal/ofetch.d.mts +0 -8
- package/dist/runtime/internal/ofetch.mjs +0 -39
- package/dist/runtime/internal/plugin.d.mts +0 -7
- package/dist/runtime/internal/plugin.mjs +0 -8
- package/dist/types/cliConfig.d.mts +0 -288
- package/dist/types/cliConfig.mjs +0 -0
- package/dist/types/cliHooks.d.mts +0 -142
- package/dist/types/cliHooks.mjs +0 -0
- package/dist/types/compatibility.d.mts +0 -13
- package/dist/types/compatibility.mjs +0 -0
- package/dist/types/config.d.mts +0 -46
- package/dist/types/config.mjs +0 -0
- package/dist/types/dotenv.d.mts +0 -29
- package/dist/types/dotenv.mjs +0 -0
- package/dist/types/event.d.mts +0 -63
- package/dist/types/event.mjs +0 -0
- package/dist/types/global.d.mts +0 -24
- package/dist/types/global.mjs +0 -0
- package/dist/types/helper.d.mts +0 -25
- package/dist/types/helper.mjs +0 -0
- package/dist/types/hooks.d.mts +0 -37
- package/dist/types/hooks.mjs +0 -0
- package/dist/types/index.d.mts +0 -26
- package/dist/types/index.mjs +0 -0
- package/dist/types/kits.d.mts +0 -32
- package/dist/types/kits.mjs +0 -0
- package/dist/types/middleware.d.mts +0 -31
- package/dist/types/middleware.mjs +0 -0
- package/dist/types/module.d.mts +0 -102
- package/dist/types/module.mjs +0 -0
- package/dist/types/preset.d.mts +0 -20
- package/dist/types/preset.mjs +0 -0
- package/dist/types/route.d.mts +0 -59
- package/dist/types/route.mjs +0 -0
- package/dist/types/runtime/index.d.mts +0 -5
- package/dist/types/runtime/index.mjs +0 -0
- package/dist/types/runtime/nuxt.d.mts +0 -13
- package/dist/types/runtime/nuxt.mjs +0 -0
- package/dist/types/runtime/ofetch.d.mts +0 -14
- package/dist/types/runtime/ofetch.mjs +0 -0
- package/dist/types/runtime/plugin.d.mts +0 -8
- package/dist/types/runtime/plugin.mjs +0 -0
- package/dist/types/runtime/silgi.d.mts +0 -11
- package/dist/types/runtime/silgi.mjs +0 -0
- package/dist/types/schema.d.mts +0 -86
- package/dist/types/schema.mjs +0 -0
- package/dist/types/service.d.mts +0 -102
- package/dist/types/service.mjs +0 -0
- package/dist/types/shared.d.mts +0 -19
- package/dist/types/shared.mjs +0 -0
- package/dist/types/silgi.d.mts +0 -71
- package/dist/types/silgi.mjs +0 -0
- package/dist/types/silgiCLI.d.mts +0 -118
- package/dist/types/silgiCLI.mjs +0 -0
- package/dist/types/standard-schema.d.mts +0 -61
- package/dist/types/standard-schema.mjs +0 -0
- package/dist/types/storage.d.mts +0 -30
- package/dist/types/storage.mjs +0 -0
- package/dist/types/tree-kill.d.mts +0 -18
- package/dist/types/tree-kill.mjs +0 -0
- package/lib/config.d.mts +0 -7
- package/lib/config.mjs +0 -5
- package/lib/meta.d.mts +0 -4
- package/lib/meta.mjs +0 -6
- package/lib/runtime-meta.d.mts +0 -4
- package/lib/runtime-meta.mjs +0 -32
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { encodeEventMessage } from "../../core/sse.mjs";
|
|
2
|
+
//#region src/plugins/analytics/sse.ts
|
|
3
|
+
/**
|
|
4
|
+
* Analytics SSE — real-time event streaming for the analytics dashboard.
|
|
5
|
+
*/
|
|
6
|
+
var AnalyticsSSEHub = class {
|
|
7
|
+
#clients = /* @__PURE__ */ new Set();
|
|
8
|
+
#statsInterval = null;
|
|
9
|
+
#getStats = null;
|
|
10
|
+
constructor() {}
|
|
11
|
+
/** Start periodic stats broadcast. */
|
|
12
|
+
startStatsBroadcast(getStats, intervalMs = 5e3) {
|
|
13
|
+
this.#getStats = getStats;
|
|
14
|
+
this.#statsInterval = setInterval(() => {
|
|
15
|
+
if (this.#clients.size > 0 && this.#getStats) this.broadcast({
|
|
16
|
+
type: "stats",
|
|
17
|
+
data: this.#getStats()
|
|
18
|
+
});
|
|
19
|
+
}, intervalMs);
|
|
20
|
+
if (typeof this.#statsInterval === "object" && "unref" in this.#statsInterval) this.#statsInterval.unref();
|
|
21
|
+
}
|
|
22
|
+
/** Broadcast an event to all connected clients. */
|
|
23
|
+
broadcast(event) {
|
|
24
|
+
if (this.#clients.size === 0) return;
|
|
25
|
+
const message = encodeEventMessage({
|
|
26
|
+
event: event.type,
|
|
27
|
+
data: JSON.stringify(event.data)
|
|
28
|
+
});
|
|
29
|
+
for (const controller of this.#clients) try {
|
|
30
|
+
controller.enqueue(message);
|
|
31
|
+
} catch {
|
|
32
|
+
this.#clients.delete(controller);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
/** Create an SSE ReadableStream for a new client connection. */
|
|
36
|
+
createStream() {
|
|
37
|
+
let controller;
|
|
38
|
+
let keepAliveTimer;
|
|
39
|
+
return new ReadableStream({
|
|
40
|
+
start: (ctrl) => {
|
|
41
|
+
controller = ctrl;
|
|
42
|
+
this.#clients.add(controller);
|
|
43
|
+
controller.enqueue(encodeEventMessage({ comment: "connected" }));
|
|
44
|
+
keepAliveTimer = setInterval(() => {
|
|
45
|
+
try {
|
|
46
|
+
controller.enqueue(encodeEventMessage({ comment: "keepalive" }));
|
|
47
|
+
} catch {
|
|
48
|
+
clearInterval(keepAliveTimer);
|
|
49
|
+
this.#clients.delete(controller);
|
|
50
|
+
}
|
|
51
|
+
}, 15e3);
|
|
52
|
+
if (typeof keepAliveTimer === "object" && "unref" in keepAliveTimer) keepAliveTimer.unref();
|
|
53
|
+
},
|
|
54
|
+
cancel: () => {
|
|
55
|
+
clearInterval(keepAliveTimer);
|
|
56
|
+
this.#clients.delete(controller);
|
|
57
|
+
}
|
|
58
|
+
}).pipeThrough(new TextEncoderStream());
|
|
59
|
+
}
|
|
60
|
+
/** Number of connected clients. */
|
|
61
|
+
get clientCount() {
|
|
62
|
+
return this.#clients.size;
|
|
63
|
+
}
|
|
64
|
+
dispose() {
|
|
65
|
+
if (this.#statsInterval) clearInterval(this.#statsInterval);
|
|
66
|
+
this.#statsInterval = null;
|
|
67
|
+
for (const controller of this.#clients) try {
|
|
68
|
+
controller.close();
|
|
69
|
+
} catch {}
|
|
70
|
+
this.#clients.clear();
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
//#endregion
|
|
74
|
+
export { AnalyticsSSEHub };
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { useStorage } from "../../core/storage.mjs";
|
|
2
|
+
import { isTrackedRequestPath } from "./utils.mjs";
|
|
3
|
+
import { normalizeErrorEntries, normalizeRequestEntries } from "./normalize.mjs";
|
|
4
|
+
//#region src/plugins/analytics/store.ts
|
|
5
|
+
/**
|
|
6
|
+
* Persistent analytics storage — flush/hydrate to unstorage.
|
|
7
|
+
*/
|
|
8
|
+
var AnalyticsStore = class {
|
|
9
|
+
#storage;
|
|
10
|
+
#pendingRequests = [];
|
|
11
|
+
#pendingErrors = [];
|
|
12
|
+
#retentionMs;
|
|
13
|
+
#timer = null;
|
|
14
|
+
#flushing = false;
|
|
15
|
+
constructor(flushInterval, retentionDays) {
|
|
16
|
+
this.#storage = useStorage("data");
|
|
17
|
+
this.#retentionMs = retentionDays * 864e5;
|
|
18
|
+
this.#timer = setInterval(() => this.flush(), flushInterval);
|
|
19
|
+
if (typeof this.#timer === "object" && "unref" in this.#timer) this.#timer.unref();
|
|
20
|
+
}
|
|
21
|
+
enqueueRequest(entry) {
|
|
22
|
+
this.#pendingRequests.push(entry);
|
|
23
|
+
}
|
|
24
|
+
enqueueError(entry) {
|
|
25
|
+
this.#pendingErrors.push(entry);
|
|
26
|
+
}
|
|
27
|
+
async flush() {
|
|
28
|
+
if (this.#flushing) return;
|
|
29
|
+
const requests = this.#pendingRequests.splice(0);
|
|
30
|
+
const errors = this.#pendingErrors.splice(0);
|
|
31
|
+
if (requests.length === 0 && errors.length === 0) return;
|
|
32
|
+
this.#flushing = true;
|
|
33
|
+
try {
|
|
34
|
+
const cutoff = Date.now() - this.#retentionMs;
|
|
35
|
+
if (requests.length > 0) {
|
|
36
|
+
const merged = [...normalizeRequestEntries(await this.#storage.getItem("analytics:requests")).filter((entry) => isTrackedRequestPath(entry.path)), ...requests].filter((e) => e.timestamp >= cutoff);
|
|
37
|
+
await this.#storage.setItem("analytics:requests", merged);
|
|
38
|
+
}
|
|
39
|
+
if (errors.length > 0) {
|
|
40
|
+
const merged = [...normalizeErrorEntries(await this.#storage.getItem("analytics:errors")).filter((entry) => isTrackedRequestPath(entry.procedure)), ...errors].filter((e) => e.timestamp >= cutoff);
|
|
41
|
+
await this.#storage.setItem("analytics:errors", merged);
|
|
42
|
+
}
|
|
43
|
+
} catch {
|
|
44
|
+
this.#pendingRequests.unshift(...requests);
|
|
45
|
+
this.#pendingErrors.unshift(...errors);
|
|
46
|
+
} finally {
|
|
47
|
+
this.#flushing = false;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
async getRequests() {
|
|
51
|
+
const cutoff = Date.now() - this.#retentionMs;
|
|
52
|
+
const stored = normalizeRequestEntries(await this.#storage.getItem("analytics:requests")).filter((entry) => isTrackedRequestPath(entry.path) && entry.timestamp >= cutoff);
|
|
53
|
+
const pending = this.#pendingRequests.filter((entry) => isTrackedRequestPath(entry.path) && entry.timestamp >= cutoff);
|
|
54
|
+
if (pending.length === 0) return stored;
|
|
55
|
+
return [...stored, ...pending];
|
|
56
|
+
}
|
|
57
|
+
async getErrors() {
|
|
58
|
+
const cutoff = Date.now() - this.#retentionMs;
|
|
59
|
+
const stored = normalizeErrorEntries(await this.#storage.getItem("analytics:errors")).filter((entry) => isTrackedRequestPath(entry.procedure) && entry.timestamp >= cutoff);
|
|
60
|
+
const pending = this.#pendingErrors.filter((entry) => isTrackedRequestPath(entry.procedure) && entry.timestamp >= cutoff);
|
|
61
|
+
if (pending.length === 0) return stored;
|
|
62
|
+
return [...stored, ...pending];
|
|
63
|
+
}
|
|
64
|
+
async hydrate() {
|
|
65
|
+
try {
|
|
66
|
+
return await this.#storage.getItem("analytics:counters") ?? {
|
|
67
|
+
totalRequests: 0,
|
|
68
|
+
totalErrors: 0
|
|
69
|
+
};
|
|
70
|
+
} catch {
|
|
71
|
+
return {
|
|
72
|
+
totalRequests: 0,
|
|
73
|
+
totalErrors: 0
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
async saveCounters(totalRequests, totalErrors) {
|
|
78
|
+
try {
|
|
79
|
+
await this.#storage.setItem("analytics:counters", {
|
|
80
|
+
totalRequests,
|
|
81
|
+
totalErrors
|
|
82
|
+
});
|
|
83
|
+
} catch {}
|
|
84
|
+
}
|
|
85
|
+
async loadHiddenPaths() {
|
|
86
|
+
try {
|
|
87
|
+
const paths = await this.#storage.getItem("analytics:hiddenPaths");
|
|
88
|
+
return Array.isArray(paths) ? paths : [];
|
|
89
|
+
} catch {
|
|
90
|
+
return [];
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
saveHiddenPaths(paths) {
|
|
94
|
+
this.#storage.setItem("analytics:hiddenPaths", paths).catch(() => {});
|
|
95
|
+
}
|
|
96
|
+
async dispose() {
|
|
97
|
+
if (this.#timer) clearInterval(this.#timer);
|
|
98
|
+
this.#timer = null;
|
|
99
|
+
await this.flush();
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
//#endregion
|
|
103
|
+
export { AnalyticsStore };
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
//#region src/plugins/analytics/timeseries.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Analytics Time-Series — multi-tier bucketed aggregation with automatic downsampling.
|
|
4
|
+
*
|
|
5
|
+
* Three tiers:
|
|
6
|
+
* - minute: 1-minute buckets, last 60 minutes
|
|
7
|
+
* - hour: 1-hour buckets, last 24 hours
|
|
8
|
+
* - day: 1-day buckets, last 30 days
|
|
9
|
+
*/
|
|
10
|
+
interface TimeSeriesBucket {
|
|
11
|
+
time: number;
|
|
12
|
+
count: number;
|
|
13
|
+
errors: number;
|
|
14
|
+
totalLatency: number;
|
|
15
|
+
minLatency: number;
|
|
16
|
+
maxLatency: number;
|
|
17
|
+
}
|
|
18
|
+
interface TimeSeriesSnapshot {
|
|
19
|
+
time: number;
|
|
20
|
+
count: number;
|
|
21
|
+
errors: number;
|
|
22
|
+
errorRate: number;
|
|
23
|
+
avgLatency: number;
|
|
24
|
+
minLatency: number;
|
|
25
|
+
maxLatency: number;
|
|
26
|
+
}
|
|
27
|
+
type TimeRange = '1h' | '6h' | '24h' | '7d' | '30d';
|
|
28
|
+
declare class TimeSeriesAggregator {
|
|
29
|
+
#private;
|
|
30
|
+
constructor();
|
|
31
|
+
/** Record a request. */
|
|
32
|
+
record(durationMs: number, isError: boolean): void;
|
|
33
|
+
/** Get time-series for a given range. */
|
|
34
|
+
query(range: TimeRange): TimeSeriesSnapshot[];
|
|
35
|
+
/** Export state for persistence. */
|
|
36
|
+
toJSON(): {
|
|
37
|
+
minutes: TimeSeriesBucket[];
|
|
38
|
+
hours: TimeSeriesBucket[];
|
|
39
|
+
days: TimeSeriesBucket[];
|
|
40
|
+
};
|
|
41
|
+
/** Restore from persisted state. */
|
|
42
|
+
hydrate(data: {
|
|
43
|
+
minutes?: TimeSeriesBucket[];
|
|
44
|
+
hours?: TimeSeriesBucket[];
|
|
45
|
+
days?: TimeSeriesBucket[];
|
|
46
|
+
}): void;
|
|
47
|
+
dispose(): void;
|
|
48
|
+
}
|
|
49
|
+
//#endregion
|
|
50
|
+
export { TimeSeriesAggregator };
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
//#region src/plugins/analytics/timeseries.ts
|
|
2
|
+
const MINUTE_MS = 6e4;
|
|
3
|
+
const HOUR_MS = 36e5;
|
|
4
|
+
const DAY_MS = 864e5;
|
|
5
|
+
const MAX_MINUTE_BUCKETS = 60;
|
|
6
|
+
const MAX_HOUR_BUCKETS = 24;
|
|
7
|
+
const MAX_DAY_BUCKETS = 30;
|
|
8
|
+
var TimeSeriesAggregator = class {
|
|
9
|
+
#minutes = [];
|
|
10
|
+
#hours = [];
|
|
11
|
+
#days = [];
|
|
12
|
+
#currentMinute = null;
|
|
13
|
+
#rollupTimer = null;
|
|
14
|
+
constructor() {
|
|
15
|
+
this.#rollupTimer = setInterval(() => this.#rollup(), MINUTE_MS);
|
|
16
|
+
if (typeof this.#rollupTimer === "object" && "unref" in this.#rollupTimer) this.#rollupTimer.unref();
|
|
17
|
+
}
|
|
18
|
+
/** Record a request. */
|
|
19
|
+
record(durationMs, isError) {
|
|
20
|
+
const now = Date.now();
|
|
21
|
+
const minuteStart = now - now % MINUTE_MS;
|
|
22
|
+
if (!this.#currentMinute || this.#currentMinute.time !== minuteStart) {
|
|
23
|
+
if (this.#currentMinute) {
|
|
24
|
+
this.#minutes.push(this.#currentMinute);
|
|
25
|
+
if (this.#minutes.length > MAX_MINUTE_BUCKETS) this.#minutes.shift();
|
|
26
|
+
}
|
|
27
|
+
this.#currentMinute = createBucket(minuteStart);
|
|
28
|
+
}
|
|
29
|
+
this.#currentMinute.count++;
|
|
30
|
+
if (isError) this.#currentMinute.errors++;
|
|
31
|
+
this.#currentMinute.totalLatency += durationMs;
|
|
32
|
+
if (durationMs < this.#currentMinute.minLatency) this.#currentMinute.minLatency = durationMs;
|
|
33
|
+
if (durationMs > this.#currentMinute.maxLatency) this.#currentMinute.maxLatency = durationMs;
|
|
34
|
+
}
|
|
35
|
+
/** Get time-series for a given range. */
|
|
36
|
+
query(range) {
|
|
37
|
+
this.#flushCurrentMinute();
|
|
38
|
+
switch (range) {
|
|
39
|
+
case "1h": return this.#minutes.map(toSnapshot);
|
|
40
|
+
case "6h": {
|
|
41
|
+
const cutoff = Date.now() - 6 * HOUR_MS;
|
|
42
|
+
const hourData = this.#hours.filter((b) => b.time >= cutoff).map(toSnapshot);
|
|
43
|
+
const minuteData = this.#minutes.map(toSnapshot);
|
|
44
|
+
return [...hourData, ...minuteData];
|
|
45
|
+
}
|
|
46
|
+
case "24h": return this.#hours.map(toSnapshot);
|
|
47
|
+
case "7d": {
|
|
48
|
+
const cutoff = Date.now() - 7 * DAY_MS;
|
|
49
|
+
return this.#days.filter((b) => b.time >= cutoff).map(toSnapshot);
|
|
50
|
+
}
|
|
51
|
+
case "30d": return this.#days.map(toSnapshot);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
/** Export state for persistence. */
|
|
55
|
+
toJSON() {
|
|
56
|
+
this.#flushCurrentMinute();
|
|
57
|
+
return {
|
|
58
|
+
minutes: this.#minutes,
|
|
59
|
+
hours: this.#hours,
|
|
60
|
+
days: this.#days
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
/** Restore from persisted state. */
|
|
64
|
+
hydrate(data) {
|
|
65
|
+
if (Array.isArray(data.minutes)) this.#minutes = data.minutes;
|
|
66
|
+
if (Array.isArray(data.hours)) this.#hours = data.hours;
|
|
67
|
+
if (Array.isArray(data.days)) this.#days = data.days;
|
|
68
|
+
}
|
|
69
|
+
#flushCurrentMinute() {
|
|
70
|
+
if (this.#currentMinute && this.#currentMinute.count > 0) {
|
|
71
|
+
const minuteStart = Date.now() - Date.now() % MINUTE_MS;
|
|
72
|
+
if (this.#currentMinute.time !== minuteStart) {
|
|
73
|
+
this.#minutes.push(this.#currentMinute);
|
|
74
|
+
if (this.#minutes.length > MAX_MINUTE_BUCKETS) this.#minutes.shift();
|
|
75
|
+
this.#currentMinute = null;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
#rollup() {
|
|
80
|
+
const now = Date.now();
|
|
81
|
+
const hourStart = now - now % HOUR_MS;
|
|
82
|
+
const completedMinutes = this.#minutes.filter((b) => b.time < hourStart);
|
|
83
|
+
if (completedMinutes.length > 0) {
|
|
84
|
+
const byHour = /* @__PURE__ */ new Map();
|
|
85
|
+
for (const b of completedMinutes) {
|
|
86
|
+
const hStart = b.time - b.time % HOUR_MS;
|
|
87
|
+
const arr = byHour.get(hStart);
|
|
88
|
+
if (arr) arr.push(b);
|
|
89
|
+
else byHour.set(hStart, [b]);
|
|
90
|
+
}
|
|
91
|
+
for (const [hStart, buckets] of byHour) {
|
|
92
|
+
const existing = this.#hours.find((h) => h.time === hStart);
|
|
93
|
+
if (existing) mergeBucketInto(existing, buckets);
|
|
94
|
+
else {
|
|
95
|
+
this.#hours.push(mergeBuckets(hStart, buckets));
|
|
96
|
+
if (this.#hours.length > MAX_HOUR_BUCKETS) this.#hours.shift();
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
this.#minutes = this.#minutes.filter((b) => b.time >= hourStart);
|
|
100
|
+
}
|
|
101
|
+
const dayStart = now - now % DAY_MS;
|
|
102
|
+
const completedHours = this.#hours.filter((b) => b.time < dayStart);
|
|
103
|
+
if (completedHours.length > 0) {
|
|
104
|
+
const byDay = /* @__PURE__ */ new Map();
|
|
105
|
+
for (const b of completedHours) {
|
|
106
|
+
const dStart = b.time - b.time % DAY_MS;
|
|
107
|
+
const arr = byDay.get(dStart);
|
|
108
|
+
if (arr) arr.push(b);
|
|
109
|
+
else byDay.set(dStart, [b]);
|
|
110
|
+
}
|
|
111
|
+
for (const [dStart, buckets] of byDay) {
|
|
112
|
+
const existing = this.#days.find((d) => d.time === dStart);
|
|
113
|
+
if (existing) mergeBucketInto(existing, buckets);
|
|
114
|
+
else {
|
|
115
|
+
this.#days.push(mergeBuckets(dStart, buckets));
|
|
116
|
+
if (this.#days.length > MAX_DAY_BUCKETS) this.#days.shift();
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
this.#hours = this.#hours.filter((b) => b.time >= dayStart);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
dispose() {
|
|
123
|
+
if (this.#rollupTimer) clearInterval(this.#rollupTimer);
|
|
124
|
+
this.#rollupTimer = null;
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
function createBucket(time) {
|
|
128
|
+
return {
|
|
129
|
+
time,
|
|
130
|
+
count: 0,
|
|
131
|
+
errors: 0,
|
|
132
|
+
totalLatency: 0,
|
|
133
|
+
minLatency: Infinity,
|
|
134
|
+
maxLatency: 0
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
function mergeBuckets(time, buckets) {
|
|
138
|
+
const merged = createBucket(time);
|
|
139
|
+
for (const b of buckets) {
|
|
140
|
+
merged.count += b.count;
|
|
141
|
+
merged.errors += b.errors;
|
|
142
|
+
merged.totalLatency += b.totalLatency;
|
|
143
|
+
if (b.minLatency < merged.minLatency) merged.minLatency = b.minLatency;
|
|
144
|
+
if (b.maxLatency > merged.maxLatency) merged.maxLatency = b.maxLatency;
|
|
145
|
+
}
|
|
146
|
+
return merged;
|
|
147
|
+
}
|
|
148
|
+
function mergeBucketInto(target, buckets) {
|
|
149
|
+
for (const b of buckets) {
|
|
150
|
+
target.count += b.count;
|
|
151
|
+
target.errors += b.errors;
|
|
152
|
+
target.totalLatency += b.totalLatency;
|
|
153
|
+
if (b.minLatency < target.minLatency) target.minLatency = b.minLatency;
|
|
154
|
+
if (b.maxLatency > target.maxLatency) target.maxLatency = b.maxLatency;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
function toSnapshot(b) {
|
|
158
|
+
return {
|
|
159
|
+
time: b.time,
|
|
160
|
+
count: b.count,
|
|
161
|
+
errors: b.errors,
|
|
162
|
+
errorRate: b.count > 0 ? b.errors / b.count * 100 : 0,
|
|
163
|
+
avgLatency: b.count > 0 ? b.totalLatency / b.count : 0,
|
|
164
|
+
minLatency: b.minLatency === Infinity ? 0 : b.minLatency,
|
|
165
|
+
maxLatency: b.maxLatency
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
//#endregion
|
|
169
|
+
export { TimeSeriesAggregator };
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { SpanKind, TraceSpan } from "./types.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/plugins/analytics/trace.d.ts
|
|
4
|
+
declare class RequestTrace {
|
|
5
|
+
spans: TraceSpan[];
|
|
6
|
+
/** Procedure-level input — set via `setProcedureInput()` or `trace(..., { procedure: { input } })` */
|
|
7
|
+
procedureInput: unknown;
|
|
8
|
+
/** Procedure-level output — set via `setProcedureOutput()` or `trace(..., { procedure: { output } })` */
|
|
9
|
+
procedureOutput: unknown;
|
|
10
|
+
/** @internal Start time — used by integrations (drizzle etc.) for span offset calculation */
|
|
11
|
+
readonly t0: number;
|
|
12
|
+
trace<T>(name: string, fn: () => T | Promise<T>, opts?: {
|
|
13
|
+
kind?: SpanKind;
|
|
14
|
+
detail?: string;
|
|
15
|
+
input?: unknown;
|
|
16
|
+
output?: unknown | ((result: T) => unknown);
|
|
17
|
+
procedure?: {
|
|
18
|
+
input?: unknown;
|
|
19
|
+
output?: unknown | ((result: T) => unknown);
|
|
20
|
+
};
|
|
21
|
+
}): Promise<T>;
|
|
22
|
+
totalByKind(kind: SpanKind): number;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Standalone trace function — works with or without analytics.
|
|
26
|
+
*
|
|
27
|
+
* ```ts
|
|
28
|
+
* import { trace } from 'silgi/analytics'
|
|
29
|
+
*
|
|
30
|
+
* const listUsers = s.$resolve(async ({ ctx }) => {
|
|
31
|
+
* return await trace(ctx, 'db.users.findMany', () => db.users.findMany())
|
|
32
|
+
* // or with explicit kind:
|
|
33
|
+
* return await trace(ctx, 'findUsers', () => db.users.findMany(), { kind: 'db', detail: 'SELECT * FROM users' })
|
|
34
|
+
* })
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
declare function trace<T>(ctx: Record<string, unknown>, name: string, fn: () => T | Promise<T>, opts?: {
|
|
38
|
+
kind?: SpanKind;
|
|
39
|
+
detail?: string;
|
|
40
|
+
input?: unknown;
|
|
41
|
+
output?: unknown | ((result: T) => unknown);
|
|
42
|
+
procedure?: {
|
|
43
|
+
input?: unknown;
|
|
44
|
+
output?: unknown | ((result: T) => unknown);
|
|
45
|
+
};
|
|
46
|
+
}): Promise<T>;
|
|
47
|
+
//#endregion
|
|
48
|
+
export { RequestTrace, trace };
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { round } from "./utils.mjs";
|
|
2
|
+
//#region src/plugins/analytics/trace.ts
|
|
3
|
+
/**
|
|
4
|
+
* Request-level tracing — span collection and standalone trace() helper.
|
|
5
|
+
*/
|
|
6
|
+
var RequestTrace = class {
|
|
7
|
+
spans = [];
|
|
8
|
+
/** Procedure-level input — set via `setProcedureInput()` or `trace(..., { procedure: { input } })` */
|
|
9
|
+
procedureInput = void 0;
|
|
10
|
+
/** Procedure-level output — set via `setProcedureOutput()` or `trace(..., { procedure: { output } })` */
|
|
11
|
+
procedureOutput = void 0;
|
|
12
|
+
/** @internal Start time — used by integrations (drizzle etc.) for span offset calculation */
|
|
13
|
+
t0 = performance.now();
|
|
14
|
+
async trace(name, fn, opts) {
|
|
15
|
+
const start = performance.now();
|
|
16
|
+
const kind = opts?.kind ?? guessKind(name);
|
|
17
|
+
try {
|
|
18
|
+
const result = await fn();
|
|
19
|
+
this.spans.push({
|
|
20
|
+
name,
|
|
21
|
+
kind,
|
|
22
|
+
durationMs: round(performance.now() - start),
|
|
23
|
+
startOffsetMs: round(start - this.t0),
|
|
24
|
+
detail: opts?.detail,
|
|
25
|
+
input: opts?.input,
|
|
26
|
+
output: typeof opts?.output === "function" ? opts.output(result) : opts?.output
|
|
27
|
+
});
|
|
28
|
+
if (opts?.procedure) {
|
|
29
|
+
if (opts.procedure.input !== void 0) this.procedureInput = opts.procedure.input;
|
|
30
|
+
const po = opts.procedure.output;
|
|
31
|
+
if (po !== void 0) this.procedureOutput = typeof po === "function" ? po(result) : po;
|
|
32
|
+
}
|
|
33
|
+
return result;
|
|
34
|
+
} catch (err) {
|
|
35
|
+
this.spans.push({
|
|
36
|
+
name,
|
|
37
|
+
kind,
|
|
38
|
+
durationMs: round(performance.now() - start),
|
|
39
|
+
startOffsetMs: round(start - this.t0),
|
|
40
|
+
detail: opts?.detail,
|
|
41
|
+
input: opts?.input,
|
|
42
|
+
error: err instanceof Error ? err.message : String(err)
|
|
43
|
+
});
|
|
44
|
+
if (opts?.procedure?.input !== void 0) this.procedureInput = opts.procedure.input;
|
|
45
|
+
throw err;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
totalByKind(kind) {
|
|
49
|
+
let total = 0;
|
|
50
|
+
for (const s of this.spans) if (s.kind === kind) total += s.durationMs;
|
|
51
|
+
return round(total);
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
function guessKind(name) {
|
|
55
|
+
const lower = name.toLowerCase();
|
|
56
|
+
if (lower.startsWith("db.") || lower.includes("sql") || lower.includes("prisma") || lower.includes("drizzle") || lower.includes("query") || lower.includes("mongo")) return "db";
|
|
57
|
+
if (lower.startsWith("http.") || lower.includes("fetch") || lower.includes("api.")) return "http";
|
|
58
|
+
if (lower.startsWith("cache.") || lower.includes("redis") || lower.includes("memcache")) return "cache";
|
|
59
|
+
if (lower.includes("queue") || lower.includes("publish") || lower.includes("nats") || lower.includes("kafka")) return "queue";
|
|
60
|
+
if (lower.includes("email") || lower.includes("smtp") || lower.includes("ses")) return "email";
|
|
61
|
+
if (lower.includes("ai") || lower.includes("llm") || lower.includes("openai") || lower.includes("gemini")) return "ai";
|
|
62
|
+
return "custom";
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Standalone trace function — works with or without analytics.
|
|
66
|
+
*
|
|
67
|
+
* ```ts
|
|
68
|
+
* import { trace } from 'silgi/analytics'
|
|
69
|
+
*
|
|
70
|
+
* const listUsers = s.$resolve(async ({ ctx }) => {
|
|
71
|
+
* return await trace(ctx, 'db.users.findMany', () => db.users.findMany())
|
|
72
|
+
* // or with explicit kind:
|
|
73
|
+
* return await trace(ctx, 'findUsers', () => db.users.findMany(), { kind: 'db', detail: 'SELECT * FROM users' })
|
|
74
|
+
* })
|
|
75
|
+
* ```
|
|
76
|
+
*/
|
|
77
|
+
async function trace(ctx, name, fn, opts) {
|
|
78
|
+
const reqTrace = ctx.__analyticsTrace;
|
|
79
|
+
if (reqTrace) return reqTrace.trace(name, fn, opts);
|
|
80
|
+
return fn();
|
|
81
|
+
}
|
|
82
|
+
//#endregion
|
|
83
|
+
export { RequestTrace, trace };
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { BudgetRule, SpanCost } from "./cost.mjs";
|
|
2
|
+
import { AlertRule } from "./alerts.mjs";
|
|
3
|
+
|
|
4
|
+
//#region src/plugins/analytics/types.d.ts
|
|
5
|
+
interface TimeWindow {
|
|
6
|
+
time: number;
|
|
7
|
+
count: number;
|
|
8
|
+
errors: number;
|
|
9
|
+
}
|
|
10
|
+
type SpanKind = 'db' | 'http' | 'cache' | 'queue' | 'email' | 'ai' | 'custom';
|
|
11
|
+
interface TraceSpan {
|
|
12
|
+
name: string;
|
|
13
|
+
kind: SpanKind;
|
|
14
|
+
durationMs: number;
|
|
15
|
+
startOffsetMs?: number;
|
|
16
|
+
detail?: string;
|
|
17
|
+
input?: unknown;
|
|
18
|
+
output?: unknown;
|
|
19
|
+
error?: string;
|
|
20
|
+
/** Structured key-value attributes (db.name, auth.operation, user.id, etc.) */
|
|
21
|
+
attributes?: Record<string, string | number | boolean>;
|
|
22
|
+
/** Cost metadata for this span (tokens, price, provider). */
|
|
23
|
+
cost?: SpanCost;
|
|
24
|
+
}
|
|
25
|
+
interface ErrorEntry {
|
|
26
|
+
id: number;
|
|
27
|
+
/** Links back to the RequestEntry that produced this error. */
|
|
28
|
+
requestId: string;
|
|
29
|
+
timestamp: number;
|
|
30
|
+
procedure: string;
|
|
31
|
+
error: string;
|
|
32
|
+
code: string;
|
|
33
|
+
status: number;
|
|
34
|
+
stack: string;
|
|
35
|
+
input: unknown;
|
|
36
|
+
headers: Record<string, string>;
|
|
37
|
+
durationMs: number;
|
|
38
|
+
spans: TraceSpan[];
|
|
39
|
+
}
|
|
40
|
+
/** A single procedure call within an HTTP request. */
|
|
41
|
+
interface ProcedureCall {
|
|
42
|
+
procedure: string;
|
|
43
|
+
durationMs: number;
|
|
44
|
+
status: number;
|
|
45
|
+
input: unknown;
|
|
46
|
+
output: unknown;
|
|
47
|
+
spans: TraceSpan[];
|
|
48
|
+
error?: string;
|
|
49
|
+
}
|
|
50
|
+
/** An HTTP request containing one or more procedure calls. */
|
|
51
|
+
interface RequestEntry {
|
|
52
|
+
id: number;
|
|
53
|
+
/** Unique request ID (returned in x-request-id response header). */
|
|
54
|
+
requestId: string;
|
|
55
|
+
/** Persistent session ID (from cookie — survives browser restart). */
|
|
56
|
+
sessionId: string;
|
|
57
|
+
timestamp: number;
|
|
58
|
+
durationMs: number;
|
|
59
|
+
method: string;
|
|
60
|
+
url: string;
|
|
61
|
+
path: string;
|
|
62
|
+
ip: string;
|
|
63
|
+
headers: Record<string, string>;
|
|
64
|
+
responseHeaders: Record<string, string>;
|
|
65
|
+
userAgent: string;
|
|
66
|
+
status: number;
|
|
67
|
+
procedures: ProcedureCall[];
|
|
68
|
+
isBatch: boolean;
|
|
69
|
+
/** Trace ID for correlating related requests across services. */
|
|
70
|
+
traceId?: string;
|
|
71
|
+
/** Parent request ID — links child requests to the originating request. */
|
|
72
|
+
parentRequestId?: string;
|
|
73
|
+
}
|
|
74
|
+
/** A background task execution record. */
|
|
75
|
+
interface TaskExecution {
|
|
76
|
+
id: number;
|
|
77
|
+
taskName: string;
|
|
78
|
+
trigger: 'dispatch' | 'cron' | 'http';
|
|
79
|
+
timestamp: number;
|
|
80
|
+
durationMs: number;
|
|
81
|
+
status: 'success' | 'error';
|
|
82
|
+
error?: string;
|
|
83
|
+
input?: unknown;
|
|
84
|
+
output?: unknown;
|
|
85
|
+
spans: TraceSpan[];
|
|
86
|
+
}
|
|
87
|
+
interface AnalyticsOptions {
|
|
88
|
+
/** Latency samples to keep per procedure (default: 1024) */
|
|
89
|
+
bufferSize?: number;
|
|
90
|
+
/** Time-series history in seconds (default: 120) */
|
|
91
|
+
historySeconds?: number;
|
|
92
|
+
/**
|
|
93
|
+
* Protect dashboard access.
|
|
94
|
+
* - `string` — secret token checked against `Authorization: Bearer <token>` header or `?token=` query param
|
|
95
|
+
* - `(req: Request) => boolean | Promise<boolean>` — custom auth function
|
|
96
|
+
* - `undefined` — no auth (open access, NOT recommended in production)
|
|
97
|
+
*/
|
|
98
|
+
auth?: string | ((req: Request) => boolean | Promise<boolean>);
|
|
99
|
+
/** Interval in ms between storage flushes (default: 5000) */
|
|
100
|
+
flushInterval?: number;
|
|
101
|
+
/** Days to retain entries in storage (default: 30). Entries older than this are pruned on flush. */
|
|
102
|
+
retentionDays?: number;
|
|
103
|
+
/** Path prefixes to exclude from tracking. Can also be managed at runtime via the dashboard or API. */
|
|
104
|
+
ignorePaths?: string[];
|
|
105
|
+
/** Alert rules — fire actions when conditions are met within a sliding window. */
|
|
106
|
+
alerts?: AlertRule[];
|
|
107
|
+
/** Budget rules for cost tracking. */
|
|
108
|
+
budgets?: BudgetRule[];
|
|
109
|
+
}
|
|
110
|
+
interface ProcedureSnapshot {
|
|
111
|
+
count: number;
|
|
112
|
+
errors: number;
|
|
113
|
+
errorRate: number;
|
|
114
|
+
latency: {
|
|
115
|
+
avg: number;
|
|
116
|
+
p50: number;
|
|
117
|
+
p95: number;
|
|
118
|
+
p99: number;
|
|
119
|
+
};
|
|
120
|
+
lastError: string | null;
|
|
121
|
+
lastErrorTime: number | null;
|
|
122
|
+
}
|
|
123
|
+
interface TaskSnapshot {
|
|
124
|
+
totalRuns: number;
|
|
125
|
+
totalErrors: number;
|
|
126
|
+
tasks: Record<string, {
|
|
127
|
+
runs: number;
|
|
128
|
+
errors: number;
|
|
129
|
+
avgDurationMs: number;
|
|
130
|
+
lastRun: number | null;
|
|
131
|
+
}>;
|
|
132
|
+
}
|
|
133
|
+
interface AnalyticsSnapshot {
|
|
134
|
+
uptime: number;
|
|
135
|
+
totalRequests: number;
|
|
136
|
+
totalErrors: number;
|
|
137
|
+
errorRate: number;
|
|
138
|
+
requestsPerSecond: number;
|
|
139
|
+
avgLatency: number;
|
|
140
|
+
procedures: Record<string, ProcedureSnapshot>;
|
|
141
|
+
timeSeries: TimeWindow[];
|
|
142
|
+
tasks: TaskSnapshot;
|
|
143
|
+
}
|
|
144
|
+
//#endregion
|
|
145
|
+
export { AnalyticsOptions, AnalyticsSnapshot, ErrorEntry, ProcedureCall, ProcedureSnapshot, RequestEntry, SpanKind, TaskExecution, TaskSnapshot, TraceSpan };
|