silgi 0.43.29 → 0.50.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +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 +313 -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 -92
- 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,59 @@
|
|
|
1
|
+
//#region src/plugins/analytics/alerts.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Analytics Alerts — configurable alerting with sliding window evaluation.
|
|
4
|
+
*/
|
|
5
|
+
interface AlertRule {
|
|
6
|
+
/** Unique name for this alert. */
|
|
7
|
+
name: string;
|
|
8
|
+
/** Condition to evaluate. */
|
|
9
|
+
condition: 'error_rate' | 'latency_p95' | 'latency_avg' | 'error_count' | 'request_count' | 'no_requests';
|
|
10
|
+
/** Threshold value. For rates: percentage (0-100). For latency: milliseconds. For counts: absolute number. */
|
|
11
|
+
threshold: number;
|
|
12
|
+
/** Evaluation window in seconds (default: 300 = 5 minutes). */
|
|
13
|
+
windowSeconds?: number;
|
|
14
|
+
/** Cooldown between repeated alerts in seconds (default: 3600 = 1 hour). */
|
|
15
|
+
cooldownSeconds?: number;
|
|
16
|
+
/** Optional: only evaluate for a specific procedure. */
|
|
17
|
+
procedure?: string;
|
|
18
|
+
/** Actions to execute when alert fires. */
|
|
19
|
+
actions: AlertAction[];
|
|
20
|
+
}
|
|
21
|
+
type AlertAction = {
|
|
22
|
+
type: 'webhook';
|
|
23
|
+
url: string;
|
|
24
|
+
headers?: Record<string, string>;
|
|
25
|
+
} | {
|
|
26
|
+
type: 'slack';
|
|
27
|
+
webhookUrl: string;
|
|
28
|
+
channel?: string;
|
|
29
|
+
} | {
|
|
30
|
+
type: 'console';
|
|
31
|
+
};
|
|
32
|
+
interface AlertEvent {
|
|
33
|
+
rule: string;
|
|
34
|
+
condition: string;
|
|
35
|
+
value: number;
|
|
36
|
+
threshold: number;
|
|
37
|
+
procedure?: string;
|
|
38
|
+
timestamp: number;
|
|
39
|
+
message: string;
|
|
40
|
+
}
|
|
41
|
+
interface AlertState {
|
|
42
|
+
lastFired: number;
|
|
43
|
+
lastValue: number;
|
|
44
|
+
}
|
|
45
|
+
declare class AlertEngine {
|
|
46
|
+
#private;
|
|
47
|
+
constructor(rules: AlertRule[]);
|
|
48
|
+
/** Record a sample for window evaluation. */
|
|
49
|
+
record(durationMs: number, isError: boolean, procedure: string): void;
|
|
50
|
+
/** Evaluate all rules against current window data. */
|
|
51
|
+
evaluate(): void;
|
|
52
|
+
/** Get alert history. */
|
|
53
|
+
getHistory(): AlertEvent[];
|
|
54
|
+
/** Get current alert states. */
|
|
55
|
+
getStates(): Record<string, AlertState>;
|
|
56
|
+
dispose(): void;
|
|
57
|
+
}
|
|
58
|
+
//#endregion
|
|
59
|
+
export { AlertEngine, AlertRule };
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
//#region src/plugins/analytics/alerts.ts
|
|
2
|
+
var AlertEngine = class {
|
|
3
|
+
#rules;
|
|
4
|
+
#state = /* @__PURE__ */ new Map();
|
|
5
|
+
#samples = [];
|
|
6
|
+
#maxWindowMs;
|
|
7
|
+
#timer = null;
|
|
8
|
+
#history = [];
|
|
9
|
+
constructor(rules) {
|
|
10
|
+
this.#rules = rules;
|
|
11
|
+
this.#maxWindowMs = Math.max(...rules.map((r) => (r.windowSeconds ?? 300) * 1e3), 3e5);
|
|
12
|
+
this.#timer = setInterval(() => this.evaluate(), 3e4);
|
|
13
|
+
if (typeof this.#timer === "object" && "unref" in this.#timer) this.#timer.unref();
|
|
14
|
+
}
|
|
15
|
+
/** Record a sample for window evaluation. */
|
|
16
|
+
record(durationMs, isError, procedure) {
|
|
17
|
+
const now = Date.now();
|
|
18
|
+
this.#samples.push({
|
|
19
|
+
timestamp: now,
|
|
20
|
+
durationMs,
|
|
21
|
+
isError,
|
|
22
|
+
procedure
|
|
23
|
+
});
|
|
24
|
+
const cutoff = now - this.#maxWindowMs;
|
|
25
|
+
while (this.#samples.length > 0 && this.#samples[0].timestamp < cutoff) this.#samples.shift();
|
|
26
|
+
}
|
|
27
|
+
/** Evaluate all rules against current window data. */
|
|
28
|
+
evaluate() {
|
|
29
|
+
const now = Date.now();
|
|
30
|
+
for (const rule of this.#rules) {
|
|
31
|
+
const windowMs = (rule.windowSeconds ?? 300) * 1e3;
|
|
32
|
+
const cooldownMs = (rule.cooldownSeconds ?? 3600) * 1e3;
|
|
33
|
+
const cutoff = now - windowMs;
|
|
34
|
+
const state = this.#state.get(rule.name);
|
|
35
|
+
if (state && now - state.lastFired < cooldownMs) continue;
|
|
36
|
+
let samples = this.#samples.filter((s) => s.timestamp >= cutoff);
|
|
37
|
+
if (rule.procedure) samples = samples.filter((s) => s.procedure.includes(rule.procedure));
|
|
38
|
+
const value = this.#computeValue(rule.condition, samples);
|
|
39
|
+
if (value === null) continue;
|
|
40
|
+
if (!this.#checkThreshold(rule.condition, value, rule.threshold)) continue;
|
|
41
|
+
const event = {
|
|
42
|
+
rule: rule.name,
|
|
43
|
+
condition: rule.condition,
|
|
44
|
+
value,
|
|
45
|
+
threshold: rule.threshold,
|
|
46
|
+
procedure: rule.procedure,
|
|
47
|
+
timestamp: now,
|
|
48
|
+
message: `Alert "${rule.name}": ${rule.condition} is ${formatValue(rule.condition, value)} (threshold: ${formatValue(rule.condition, rule.threshold)})`
|
|
49
|
+
};
|
|
50
|
+
this.#state.set(rule.name, {
|
|
51
|
+
lastFired: now,
|
|
52
|
+
lastValue: value
|
|
53
|
+
});
|
|
54
|
+
this.#history.push(event);
|
|
55
|
+
if (this.#history.length > 1e3) this.#history.shift();
|
|
56
|
+
for (const action of rule.actions) this.#executeAction(action, event);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
#computeValue(condition, samples) {
|
|
60
|
+
if (samples.length === 0) return condition === "no_requests" ? 0 : null;
|
|
61
|
+
switch (condition) {
|
|
62
|
+
case "error_rate": return samples.filter((s) => s.isError).length / samples.length * 100;
|
|
63
|
+
case "error_count": return samples.filter((s) => s.isError).length;
|
|
64
|
+
case "request_count": return samples.length;
|
|
65
|
+
case "no_requests": return samples.length;
|
|
66
|
+
case "latency_avg": return samples.reduce((sum, s) => sum + s.durationMs, 0) / samples.length;
|
|
67
|
+
case "latency_p95": {
|
|
68
|
+
const sorted = samples.map((s) => s.durationMs).sort((a, b) => a - b);
|
|
69
|
+
const idx = Math.ceil(sorted.length * .95) - 1;
|
|
70
|
+
return sorted[Math.max(0, idx)];
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
#checkThreshold(condition, value, threshold) {
|
|
75
|
+
if (condition === "no_requests") return value <= threshold;
|
|
76
|
+
return value >= threshold;
|
|
77
|
+
}
|
|
78
|
+
async #executeAction(action, event) {
|
|
79
|
+
try {
|
|
80
|
+
switch (action.type) {
|
|
81
|
+
case "console":
|
|
82
|
+
console.warn(`[silgi:alert] ${event.message}`);
|
|
83
|
+
break;
|
|
84
|
+
case "webhook":
|
|
85
|
+
await fetch(action.url, {
|
|
86
|
+
method: "POST",
|
|
87
|
+
headers: {
|
|
88
|
+
"content-type": "application/json",
|
|
89
|
+
...action.headers
|
|
90
|
+
},
|
|
91
|
+
body: JSON.stringify(event)
|
|
92
|
+
});
|
|
93
|
+
break;
|
|
94
|
+
case "slack":
|
|
95
|
+
await fetch(action.webhookUrl, {
|
|
96
|
+
method: "POST",
|
|
97
|
+
headers: { "content-type": "application/json" },
|
|
98
|
+
body: JSON.stringify({
|
|
99
|
+
channel: action.channel,
|
|
100
|
+
text: event.message,
|
|
101
|
+
blocks: [{
|
|
102
|
+
type: "section",
|
|
103
|
+
text: {
|
|
104
|
+
type: "mrkdwn",
|
|
105
|
+
text: `🚨 *${event.rule}*\n${event.message}`
|
|
106
|
+
}
|
|
107
|
+
}]
|
|
108
|
+
})
|
|
109
|
+
});
|
|
110
|
+
break;
|
|
111
|
+
}
|
|
112
|
+
} catch (err) {
|
|
113
|
+
console.error(`[silgi:alert] Failed to execute ${action.type} action: ${err instanceof Error ? err.message : err}`);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
/** Get alert history. */
|
|
117
|
+
getHistory() {
|
|
118
|
+
return this.#history;
|
|
119
|
+
}
|
|
120
|
+
/** Get current alert states. */
|
|
121
|
+
getStates() {
|
|
122
|
+
const result = {};
|
|
123
|
+
for (const [name, state] of this.#state) result[name] = state;
|
|
124
|
+
return result;
|
|
125
|
+
}
|
|
126
|
+
dispose() {
|
|
127
|
+
if (this.#timer) clearInterval(this.#timer);
|
|
128
|
+
this.#timer = null;
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
function formatValue(condition, value) {
|
|
132
|
+
switch (condition) {
|
|
133
|
+
case "error_rate": return `${value.toFixed(1)}%`;
|
|
134
|
+
case "latency_avg":
|
|
135
|
+
case "latency_p95": return `${value.toFixed(1)}ms`;
|
|
136
|
+
default: return String(value);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
//#endregion
|
|
140
|
+
export { AlertEngine };
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { CostTracker } from "./cost.mjs";
|
|
2
|
+
import { AlertEngine } from "./alerts.mjs";
|
|
3
|
+
import { AnalyticsOptions, AnalyticsSnapshot, ErrorEntry, RequestEntry, TaskExecution } from "./types.mjs";
|
|
4
|
+
import { AnalyticsSSEHub } from "./sse.mjs";
|
|
5
|
+
import { TimeSeriesAggregator } from "./timeseries.mjs";
|
|
6
|
+
|
|
7
|
+
//#region src/plugins/analytics/collector.d.ts
|
|
8
|
+
declare class AnalyticsCollector {
|
|
9
|
+
#private;
|
|
10
|
+
/** SSE hub for real-time streaming */
|
|
11
|
+
sseHub: AnalyticsSSEHub;
|
|
12
|
+
/** Multi-tier time-series aggregation */
|
|
13
|
+
timeseries: TimeSeriesAggregator;
|
|
14
|
+
/** Alert engine */
|
|
15
|
+
alertEngine: AlertEngine | null;
|
|
16
|
+
/** Cost tracker */
|
|
17
|
+
costTracker: CostTracker;
|
|
18
|
+
constructor(options?: AnalyticsOptions);
|
|
19
|
+
/** Check if a path is server-side ignored (from config). */
|
|
20
|
+
isIgnored(pathname: string): boolean;
|
|
21
|
+
/** Check if a path is hidden in the dashboard (from runtime API). */
|
|
22
|
+
isHidden(pathname: string): boolean;
|
|
23
|
+
addHiddenPath(path: string): void;
|
|
24
|
+
removeHiddenPath(path: string): void;
|
|
25
|
+
getHiddenPaths(): string[];
|
|
26
|
+
record(path: string, durationMs: number): void;
|
|
27
|
+
recordError(path: string, durationMs: number, errorMsg: string): void;
|
|
28
|
+
recordDetailedError(entry: Omit<ErrorEntry, 'id'>): void;
|
|
29
|
+
recordDetailedRequest(entry: Omit<RequestEntry, 'id'>): void;
|
|
30
|
+
recordTask(entry: Omit<TaskExecution, 'id'>): void;
|
|
31
|
+
getTaskExecutions(): Promise<TaskExecution[]>;
|
|
32
|
+
getErrors(): Promise<ErrorEntry[]>;
|
|
33
|
+
getRequests(): Promise<RequestEntry[]>;
|
|
34
|
+
dispose(): Promise<void>;
|
|
35
|
+
toJSON(): AnalyticsSnapshot;
|
|
36
|
+
}
|
|
37
|
+
//#endregion
|
|
38
|
+
export { AnalyticsCollector };
|
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
import { matchesPathPrefix, round } from "./utils.mjs";
|
|
2
|
+
import { AlertEngine } from "./alerts.mjs";
|
|
3
|
+
import { CostTracker } from "./cost.mjs";
|
|
4
|
+
import { AnalyticsSSEHub } from "./sse.mjs";
|
|
5
|
+
import { AnalyticsStore } from "./store.mjs";
|
|
6
|
+
import { TimeSeriesAggregator } from "./timeseries.mjs";
|
|
7
|
+
import { RingBuffer } from "./types.mjs";
|
|
8
|
+
//#region src/plugins/analytics/collector.ts
|
|
9
|
+
/**
|
|
10
|
+
* AnalyticsCollector — in-memory metrics aggregation.
|
|
11
|
+
*
|
|
12
|
+
* Tracks per-procedure counts, latencies, errors, tasks.
|
|
13
|
+
* Backed by AnalyticsStore for persistence.
|
|
14
|
+
*/
|
|
15
|
+
/** Internal in-memory buffer caps — not user-configurable */
|
|
16
|
+
const MEM_MAX_REQUESTS = 1e4;
|
|
17
|
+
const MEM_MAX_ERRORS = 1e4;
|
|
18
|
+
const MEM_MAX_TASKS = 1e4;
|
|
19
|
+
var AnalyticsCollector = class {
|
|
20
|
+
#procedures = /* @__PURE__ */ new Map();
|
|
21
|
+
#startTime = Date.now();
|
|
22
|
+
#totalRequests = 0;
|
|
23
|
+
#totalErrors = 0;
|
|
24
|
+
#bufferSize;
|
|
25
|
+
#historySeconds;
|
|
26
|
+
#timeSeries = [];
|
|
27
|
+
#currentWindow;
|
|
28
|
+
#errors = [];
|
|
29
|
+
#nextErrorId = 1;
|
|
30
|
+
#requests = [];
|
|
31
|
+
#nextRequestId = 1;
|
|
32
|
+
#taskExecutions = [];
|
|
33
|
+
#nextTaskId = 1;
|
|
34
|
+
#taskStats = /* @__PURE__ */ new Map();
|
|
35
|
+
#store;
|
|
36
|
+
#counterFlushCounter = 0;
|
|
37
|
+
/** Server-side ignore — from config, prevents recording entirely */
|
|
38
|
+
#ignorePaths;
|
|
39
|
+
/** Client-side hide — from dashboard, filters display only */
|
|
40
|
+
#hiddenPaths = /* @__PURE__ */ new Set();
|
|
41
|
+
/** SSE hub for real-time streaming */
|
|
42
|
+
sseHub;
|
|
43
|
+
/** Multi-tier time-series aggregation */
|
|
44
|
+
timeseries;
|
|
45
|
+
/** Alert engine */
|
|
46
|
+
alertEngine = null;
|
|
47
|
+
/** Cost tracker */
|
|
48
|
+
costTracker;
|
|
49
|
+
constructor(options = {}) {
|
|
50
|
+
this.#bufferSize = options.bufferSize ?? 1024;
|
|
51
|
+
this.#historySeconds = options.historySeconds ?? 120;
|
|
52
|
+
this.#ignorePaths = new Set((options.ignorePaths ?? []).map((p) => p.startsWith("/") ? p.slice(1) : p));
|
|
53
|
+
this.#currentWindow = {
|
|
54
|
+
time: Math.floor(Date.now() / 1e3),
|
|
55
|
+
count: 0,
|
|
56
|
+
errors: 0
|
|
57
|
+
};
|
|
58
|
+
this.sseHub = new AnalyticsSSEHub();
|
|
59
|
+
this.sseHub.startStatsBroadcast(() => this.toJSON());
|
|
60
|
+
this.timeseries = new TimeSeriesAggregator();
|
|
61
|
+
this.costTracker = new CostTracker(options.budgets, (rule, current) => {
|
|
62
|
+
if (this.alertEngine) console.warn(`[silgi:budget] "${rule.name}" exceeded: $${current.toFixed(2)} / $${rule.limit}`);
|
|
63
|
+
});
|
|
64
|
+
if (options.alerts && options.alerts.length > 0) this.alertEngine = new AlertEngine(options.alerts);
|
|
65
|
+
this.#store = new AnalyticsStore(options.flushInterval ?? 5e3, options.retentionDays ?? 30);
|
|
66
|
+
this.#store.hydrate().then((c) => {
|
|
67
|
+
this.#totalRequests += c.totalRequests;
|
|
68
|
+
this.#totalErrors += c.totalErrors;
|
|
69
|
+
});
|
|
70
|
+
this.#store.loadHiddenPaths().then((paths) => {
|
|
71
|
+
for (const p of paths) this.#hiddenPaths.add(p);
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
/** Check if a path is server-side ignored (from config). */
|
|
75
|
+
isIgnored(pathname) {
|
|
76
|
+
if (this.#ignorePaths.size === 0) return false;
|
|
77
|
+
return matchesPathPrefix(pathname, this.#ignorePaths);
|
|
78
|
+
}
|
|
79
|
+
/** Check if a path is hidden in the dashboard (from runtime API). */
|
|
80
|
+
isHidden(pathname) {
|
|
81
|
+
if (this.#hiddenPaths.size === 0) return false;
|
|
82
|
+
return matchesPathPrefix(pathname, this.#hiddenPaths);
|
|
83
|
+
}
|
|
84
|
+
addHiddenPath(path) {
|
|
85
|
+
const normalized = path.startsWith("/") ? path.slice(1) : path;
|
|
86
|
+
this.#hiddenPaths.add(normalized);
|
|
87
|
+
this.#store.saveHiddenPaths([...this.#hiddenPaths]);
|
|
88
|
+
}
|
|
89
|
+
removeHiddenPath(path) {
|
|
90
|
+
const normalized = path.startsWith("/") ? path.slice(1) : path;
|
|
91
|
+
this.#hiddenPaths.delete(normalized);
|
|
92
|
+
this.#store.saveHiddenPaths([...this.#hiddenPaths]);
|
|
93
|
+
}
|
|
94
|
+
getHiddenPaths() {
|
|
95
|
+
return [...this.#hiddenPaths];
|
|
96
|
+
}
|
|
97
|
+
record(path, durationMs) {
|
|
98
|
+
this.#totalRequests++;
|
|
99
|
+
const entry = this.#getOrCreate(path);
|
|
100
|
+
entry.count++;
|
|
101
|
+
entry.latencies.push(durationMs);
|
|
102
|
+
this.#tick(false);
|
|
103
|
+
this.timeseries.record(durationMs, false);
|
|
104
|
+
this.alertEngine?.record(durationMs, false, path);
|
|
105
|
+
}
|
|
106
|
+
recordError(path, durationMs, errorMsg) {
|
|
107
|
+
this.#totalRequests++;
|
|
108
|
+
this.#totalErrors++;
|
|
109
|
+
const entry = this.#getOrCreate(path);
|
|
110
|
+
entry.count++;
|
|
111
|
+
entry.errors++;
|
|
112
|
+
entry.latencies.push(durationMs);
|
|
113
|
+
entry.lastError = errorMsg;
|
|
114
|
+
entry.lastErrorTime = Date.now();
|
|
115
|
+
this.#tick(true);
|
|
116
|
+
this.timeseries.record(durationMs, true);
|
|
117
|
+
this.alertEngine?.record(durationMs, true, path);
|
|
118
|
+
}
|
|
119
|
+
recordDetailedError(entry) {
|
|
120
|
+
const full = {
|
|
121
|
+
...entry,
|
|
122
|
+
id: this.#nextErrorId++
|
|
123
|
+
};
|
|
124
|
+
this.#errors.push(full);
|
|
125
|
+
if (this.#errors.length > MEM_MAX_ERRORS) this.#errors.shift();
|
|
126
|
+
this.#store.enqueueError(full);
|
|
127
|
+
this.sseHub.broadcast({
|
|
128
|
+
type: "error",
|
|
129
|
+
data: full
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
recordDetailedRequest(entry) {
|
|
133
|
+
const full = {
|
|
134
|
+
...entry,
|
|
135
|
+
id: this.#nextRequestId++
|
|
136
|
+
};
|
|
137
|
+
this.#requests.push(full);
|
|
138
|
+
if (this.#requests.length > MEM_MAX_REQUESTS) this.#requests.shift();
|
|
139
|
+
this.#store.enqueueRequest(full);
|
|
140
|
+
this.sseHub.broadcast({
|
|
141
|
+
type: "request",
|
|
142
|
+
data: full
|
|
143
|
+
});
|
|
144
|
+
this.#flushCountersIfNeeded();
|
|
145
|
+
}
|
|
146
|
+
recordTask(entry) {
|
|
147
|
+
const full = {
|
|
148
|
+
...entry,
|
|
149
|
+
id: this.#nextTaskId++
|
|
150
|
+
};
|
|
151
|
+
this.#taskExecutions.push(full);
|
|
152
|
+
if (this.#taskExecutions.length > MEM_MAX_TASKS) this.#taskExecutions.shift();
|
|
153
|
+
this.sseHub.broadcast({
|
|
154
|
+
type: "task",
|
|
155
|
+
data: full
|
|
156
|
+
});
|
|
157
|
+
let stats = this.#taskStats.get(entry.taskName);
|
|
158
|
+
if (!stats) {
|
|
159
|
+
stats = {
|
|
160
|
+
runs: 0,
|
|
161
|
+
errors: 0,
|
|
162
|
+
totalDuration: 0,
|
|
163
|
+
lastRun: 0
|
|
164
|
+
};
|
|
165
|
+
this.#taskStats.set(entry.taskName, stats);
|
|
166
|
+
}
|
|
167
|
+
stats.runs++;
|
|
168
|
+
if (entry.status === "error") stats.errors++;
|
|
169
|
+
stats.totalDuration += entry.durationMs;
|
|
170
|
+
stats.lastRun = entry.timestamp;
|
|
171
|
+
}
|
|
172
|
+
async getTaskExecutions() {
|
|
173
|
+
return [...this.#taskExecutions];
|
|
174
|
+
}
|
|
175
|
+
#getOrCreate(path) {
|
|
176
|
+
let entry = this.#procedures.get(path);
|
|
177
|
+
if (!entry) {
|
|
178
|
+
entry = {
|
|
179
|
+
count: 0,
|
|
180
|
+
errors: 0,
|
|
181
|
+
latencies: new RingBuffer(this.#bufferSize),
|
|
182
|
+
lastError: null,
|
|
183
|
+
lastErrorTime: 0
|
|
184
|
+
};
|
|
185
|
+
this.#procedures.set(path, entry);
|
|
186
|
+
}
|
|
187
|
+
return entry;
|
|
188
|
+
}
|
|
189
|
+
#tick(isError) {
|
|
190
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
191
|
+
if (now !== this.#currentWindow.time) {
|
|
192
|
+
if (this.#currentWindow.count > 0) {
|
|
193
|
+
this.#timeSeries.push({ ...this.#currentWindow });
|
|
194
|
+
if (this.#timeSeries.length > this.#historySeconds) this.#timeSeries.shift();
|
|
195
|
+
}
|
|
196
|
+
this.#currentWindow = {
|
|
197
|
+
time: now,
|
|
198
|
+
count: 0,
|
|
199
|
+
errors: 0
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
this.#currentWindow.count++;
|
|
203
|
+
if (isError) this.#currentWindow.errors++;
|
|
204
|
+
}
|
|
205
|
+
getErrors() {
|
|
206
|
+
return this.#store.getErrors();
|
|
207
|
+
}
|
|
208
|
+
getRequests() {
|
|
209
|
+
return this.#store.getRequests();
|
|
210
|
+
}
|
|
211
|
+
#flushCountersIfNeeded() {
|
|
212
|
+
if (++this.#counterFlushCounter % 50 === 0) this.#store.saveCounters(this.#totalRequests, this.#totalErrors);
|
|
213
|
+
}
|
|
214
|
+
async dispose() {
|
|
215
|
+
await this.#store.saveCounters(this.#totalRequests, this.#totalErrors);
|
|
216
|
+
await this.#store.dispose();
|
|
217
|
+
}
|
|
218
|
+
toJSON() {
|
|
219
|
+
const uptimeSeconds = (Date.now() - this.#startTime) / 1e3;
|
|
220
|
+
const procedures = {};
|
|
221
|
+
let totalLatencySum = 0;
|
|
222
|
+
let totalLatencyCount = 0;
|
|
223
|
+
for (const [path, entry] of this.#procedures) {
|
|
224
|
+
const avg = entry.latencies.avg();
|
|
225
|
+
procedures[path] = {
|
|
226
|
+
count: entry.count,
|
|
227
|
+
errors: entry.errors,
|
|
228
|
+
errorRate: entry.count > 0 ? round(entry.errors / entry.count * 100) : 0,
|
|
229
|
+
latency: {
|
|
230
|
+
avg: round(avg),
|
|
231
|
+
p50: round(entry.latencies.percentile(50)),
|
|
232
|
+
p95: round(entry.latencies.percentile(95)),
|
|
233
|
+
p99: round(entry.latencies.percentile(99))
|
|
234
|
+
},
|
|
235
|
+
lastError: entry.lastError,
|
|
236
|
+
lastErrorTime: entry.lastErrorTime || null
|
|
237
|
+
};
|
|
238
|
+
totalLatencySum += avg * entry.latencies.count;
|
|
239
|
+
totalLatencyCount += entry.latencies.count;
|
|
240
|
+
}
|
|
241
|
+
return {
|
|
242
|
+
uptime: Math.round(uptimeSeconds),
|
|
243
|
+
totalRequests: this.#totalRequests,
|
|
244
|
+
totalErrors: this.#totalErrors,
|
|
245
|
+
errorRate: this.#totalRequests > 0 ? round(this.#totalErrors / this.#totalRequests * 100) : 0,
|
|
246
|
+
requestsPerSecond: uptimeSeconds > 0 ? round(this.#totalRequests / uptimeSeconds) : 0,
|
|
247
|
+
avgLatency: totalLatencyCount > 0 ? round(totalLatencySum / totalLatencyCount) : 0,
|
|
248
|
+
procedures,
|
|
249
|
+
timeSeries: this.#currentWindow.count > 0 ? [...this.#timeSeries, this.#currentWindow] : [...this.#timeSeries],
|
|
250
|
+
tasks: this.#taskSnapshotJSON()
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
#taskSnapshotJSON() {
|
|
254
|
+
let totalRuns = 0;
|
|
255
|
+
let totalErrors = 0;
|
|
256
|
+
const tasks = {};
|
|
257
|
+
for (const [name, s] of this.#taskStats) {
|
|
258
|
+
totalRuns += s.runs;
|
|
259
|
+
totalErrors += s.errors;
|
|
260
|
+
tasks[name] = {
|
|
261
|
+
runs: s.runs,
|
|
262
|
+
errors: s.errors,
|
|
263
|
+
avgDurationMs: s.runs > 0 ? round(s.totalDuration / s.runs) : 0,
|
|
264
|
+
lastRun: s.lastRun || null
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
return {
|
|
268
|
+
totalRuns,
|
|
269
|
+
totalErrors,
|
|
270
|
+
tasks
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
};
|
|
274
|
+
//#endregion
|
|
275
|
+
export { AnalyticsCollector };
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
//#region src/plugins/analytics/cost.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Analytics Cost Tracking — span cost metadata and budget monitoring.
|
|
4
|
+
*/
|
|
5
|
+
interface SpanCost {
|
|
6
|
+
/** Number of tokens/units consumed. */
|
|
7
|
+
units?: number;
|
|
8
|
+
/** Cost in dollars. */
|
|
9
|
+
amount: number;
|
|
10
|
+
/** Cost currency (default: USD). */
|
|
11
|
+
currency?: string;
|
|
12
|
+
/** Provider name (e.g., 'openai', 'anthropic', 'aws'). */
|
|
13
|
+
provider?: string;
|
|
14
|
+
}
|
|
15
|
+
interface CostBucket {
|
|
16
|
+
time: number;
|
|
17
|
+
totalAmount: number;
|
|
18
|
+
byProvider: Record<string, number>;
|
|
19
|
+
byProcedure: Record<string, number>;
|
|
20
|
+
byKind: Record<string, number>;
|
|
21
|
+
}
|
|
22
|
+
interface CostSummary {
|
|
23
|
+
totalAmount: number;
|
|
24
|
+
todayAmount: number;
|
|
25
|
+
byProvider: Record<string, number>;
|
|
26
|
+
byProcedure: Record<string, number>;
|
|
27
|
+
byKind: Record<string, number>;
|
|
28
|
+
dailyBuckets: CostBucket[];
|
|
29
|
+
}
|
|
30
|
+
interface BudgetRule {
|
|
31
|
+
/** Unique name. */
|
|
32
|
+
name: string;
|
|
33
|
+
/** Budget limit in dollars. */
|
|
34
|
+
limit: number;
|
|
35
|
+
/** Period: 'daily' | 'weekly' | 'monthly'. */
|
|
36
|
+
period: 'daily' | 'weekly' | 'monthly';
|
|
37
|
+
/** Optional: scope to a specific provider. */
|
|
38
|
+
provider?: string;
|
|
39
|
+
/** Optional: scope to a specific procedure. */
|
|
40
|
+
procedure?: string;
|
|
41
|
+
}
|
|
42
|
+
declare class CostTracker {
|
|
43
|
+
#private;
|
|
44
|
+
constructor(budgetRules?: BudgetRule[], onBudgetExceeded?: (rule: BudgetRule, current: number) => void);
|
|
45
|
+
/** Record a cost from a span. */
|
|
46
|
+
record(cost: SpanCost, procedure: string, kind: string): void;
|
|
47
|
+
/** Get cost summary. */
|
|
48
|
+
getSummary(): CostSummary;
|
|
49
|
+
/** Export for persistence. */
|
|
50
|
+
toJSON(): {
|
|
51
|
+
dailyBuckets: CostBucket[];
|
|
52
|
+
currentDay: CostBucket | null;
|
|
53
|
+
};
|
|
54
|
+
/** Restore from persistence. */
|
|
55
|
+
hydrate(data: {
|
|
56
|
+
dailyBuckets?: CostBucket[];
|
|
57
|
+
currentDay?: CostBucket | null;
|
|
58
|
+
}): void;
|
|
59
|
+
}
|
|
60
|
+
//#endregion
|
|
61
|
+
export { BudgetRule, CostTracker, SpanCost };
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
//#region src/plugins/analytics/cost.ts
|
|
2
|
+
const DAY_MS = 864e5;
|
|
3
|
+
const MAX_DAILY_BUCKETS = 30;
|
|
4
|
+
var CostTracker = class {
|
|
5
|
+
#dailyBuckets = [];
|
|
6
|
+
#currentDay = null;
|
|
7
|
+
#budgetRules;
|
|
8
|
+
#onBudgetExceeded;
|
|
9
|
+
constructor(budgetRules = [], onBudgetExceeded) {
|
|
10
|
+
this.#budgetRules = budgetRules;
|
|
11
|
+
this.#onBudgetExceeded = onBudgetExceeded;
|
|
12
|
+
}
|
|
13
|
+
/** Record a cost from a span. */
|
|
14
|
+
record(cost, procedure, kind) {
|
|
15
|
+
const now = Date.now();
|
|
16
|
+
const dayStart = now - now % DAY_MS;
|
|
17
|
+
if (!this.#currentDay || this.#currentDay.time !== dayStart) {
|
|
18
|
+
if (this.#currentDay) {
|
|
19
|
+
this.#dailyBuckets.push(this.#currentDay);
|
|
20
|
+
if (this.#dailyBuckets.length > MAX_DAILY_BUCKETS) this.#dailyBuckets.shift();
|
|
21
|
+
}
|
|
22
|
+
this.#currentDay = {
|
|
23
|
+
time: dayStart,
|
|
24
|
+
totalAmount: 0,
|
|
25
|
+
byProvider: {},
|
|
26
|
+
byProcedure: {},
|
|
27
|
+
byKind: {}
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
this.#currentDay.totalAmount += cost.amount;
|
|
31
|
+
const provider = cost.provider ?? "unknown";
|
|
32
|
+
this.#currentDay.byProvider[provider] = (this.#currentDay.byProvider[provider] ?? 0) + cost.amount;
|
|
33
|
+
this.#currentDay.byProcedure[procedure] = (this.#currentDay.byProcedure[procedure] ?? 0) + cost.amount;
|
|
34
|
+
this.#currentDay.byKind[kind] = (this.#currentDay.byKind[kind] ?? 0) + cost.amount;
|
|
35
|
+
this.#checkBudgets();
|
|
36
|
+
}
|
|
37
|
+
/** Get cost summary. */
|
|
38
|
+
getSummary() {
|
|
39
|
+
const allBuckets = this.#currentDay ? [...this.#dailyBuckets, this.#currentDay] : [...this.#dailyBuckets];
|
|
40
|
+
const summary = {
|
|
41
|
+
totalAmount: 0,
|
|
42
|
+
todayAmount: this.#currentDay?.totalAmount ?? 0,
|
|
43
|
+
byProvider: {},
|
|
44
|
+
byProcedure: {},
|
|
45
|
+
byKind: {},
|
|
46
|
+
dailyBuckets: allBuckets
|
|
47
|
+
};
|
|
48
|
+
for (const bucket of allBuckets) {
|
|
49
|
+
summary.totalAmount += bucket.totalAmount;
|
|
50
|
+
for (const [k, v] of Object.entries(bucket.byProvider)) summary.byProvider[k] = (summary.byProvider[k] ?? 0) + v;
|
|
51
|
+
for (const [k, v] of Object.entries(bucket.byProcedure)) summary.byProcedure[k] = (summary.byProcedure[k] ?? 0) + v;
|
|
52
|
+
for (const [k, v] of Object.entries(bucket.byKind)) summary.byKind[k] = (summary.byKind[k] ?? 0) + v;
|
|
53
|
+
}
|
|
54
|
+
return summary;
|
|
55
|
+
}
|
|
56
|
+
/** Export for persistence. */
|
|
57
|
+
toJSON() {
|
|
58
|
+
return {
|
|
59
|
+
dailyBuckets: this.#dailyBuckets,
|
|
60
|
+
currentDay: this.#currentDay
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
/** Restore from persistence. */
|
|
64
|
+
hydrate(data) {
|
|
65
|
+
if (Array.isArray(data.dailyBuckets)) this.#dailyBuckets = data.dailyBuckets;
|
|
66
|
+
if (data.currentDay) this.#currentDay = data.currentDay;
|
|
67
|
+
}
|
|
68
|
+
#checkBudgets() {
|
|
69
|
+
if (!this.#onBudgetExceeded) return;
|
|
70
|
+
const now = Date.now();
|
|
71
|
+
for (const rule of this.#budgetRules) {
|
|
72
|
+
let amount = 0;
|
|
73
|
+
const buckets = this.#currentDay ? [...this.#dailyBuckets, this.#currentDay] : this.#dailyBuckets;
|
|
74
|
+
let cutoff;
|
|
75
|
+
switch (rule.period) {
|
|
76
|
+
case "daily":
|
|
77
|
+
cutoff = now - DAY_MS;
|
|
78
|
+
break;
|
|
79
|
+
case "weekly":
|
|
80
|
+
cutoff = now - 7 * DAY_MS;
|
|
81
|
+
break;
|
|
82
|
+
case "monthly":
|
|
83
|
+
cutoff = now - 30 * DAY_MS;
|
|
84
|
+
break;
|
|
85
|
+
}
|
|
86
|
+
for (const bucket of buckets) {
|
|
87
|
+
if (bucket.time < cutoff) continue;
|
|
88
|
+
if (rule.provider) amount += bucket.byProvider[rule.provider] ?? 0;
|
|
89
|
+
else if (rule.procedure) amount += bucket.byProcedure[rule.procedure] ?? 0;
|
|
90
|
+
else amount += bucket.totalAmount;
|
|
91
|
+
}
|
|
92
|
+
if (amount >= rule.limit) this.#onBudgetExceeded(rule, amount);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
//#endregion
|
|
97
|
+
export { CostTracker };
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { ErrorEntry, RequestEntry } from "./types.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/plugins/analytics/export.d.ts
|
|
4
|
+
declare function errorToMarkdown(e: ErrorEntry): string;
|
|
5
|
+
declare function requestToMarkdown(r: RequestEntry): string;
|
|
6
|
+
//#endregion
|
|
7
|
+
export { errorToMarkdown, requestToMarkdown };
|