@lovrozagar/honey 0.6.5 → 0.7.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 +514 -192
- package/bin/honey.js +25 -0
- package/dist/accepts.d.ts +7 -1
- package/dist/accepts.d.ts.map +1 -1
- package/dist/accepts.js +126 -0
- package/dist/accepts.js.map +1 -0
- package/dist/body-kind.d.ts +26 -0
- package/dist/body-kind.d.ts.map +1 -0
- package/dist/body-kind.js +70 -0
- package/dist/body-kind.js.map +1 -0
- package/dist/body-limit.d.ts +5 -1
- package/dist/body-limit.d.ts.map +1 -1
- package/dist/body-limit.js +126 -0
- package/dist/body-limit.js.map +1 -0
- package/dist/build/index.d.ts +19 -3
- package/dist/build/index.d.ts.map +1 -1
- package/dist/build/index.js +173 -0
- package/dist/build/index.js.map +1 -0
- package/dist/cli-args.d.ts +33 -0
- package/dist/cli-args.d.ts.map +1 -0
- package/dist/cli-args.js +102 -0
- package/dist/cli-args.js.map +1 -0
- package/dist/cli-go/auth.go +26 -0
- package/dist/cli-go/config.go +192 -0
- package/dist/cli-go/errors.go +75 -0
- package/dist/cli-go/multipart.go +79 -0
- package/dist/cli-go/output.go +163 -0
- package/dist/cli-go/root.go +30 -0
- package/dist/cli-go/stream.go +88 -0
- package/dist/cli-go/version.go +5 -0
- package/dist/cli.d.ts +1 -1
- package/dist/cli.js +209 -0
- package/dist/cli.js.map +1 -0
- package/dist/client/defaults.js +48 -0
- package/dist/client/defaults.js.map +1 -0
- package/dist/client/error.d.ts +35 -0
- package/dist/client/error.d.ts.map +1 -1
- package/dist/client/error.js +71 -0
- package/dist/client/error.js.map +1 -0
- package/dist/client/http.d.ts +67 -8
- package/dist/client/http.d.ts.map +1 -1
- package/dist/client/http.js +571 -0
- package/dist/client/http.js.map +1 -0
- package/dist/client/index.d.ts +3 -2
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +95 -0
- package/dist/client/index.js.map +1 -0
- package/dist/client/path.d.ts +26 -0
- package/dist/client/path.d.ts.map +1 -0
- package/dist/client/path.js +163 -0
- package/dist/client/path.js.map +1 -0
- package/dist/client/redirect-policy.d.ts +12 -0
- package/dist/client/redirect-policy.d.ts.map +1 -0
- package/dist/client/redirect-policy.js +20 -0
- package/dist/client/redirect-policy.js.map +1 -0
- package/dist/client/sdk.d.ts +36 -0
- package/dist/client/sdk.d.ts.map +1 -1
- package/dist/client/sdk.js +292 -0
- package/dist/client/sdk.js.map +1 -0
- package/dist/client/sse.d.ts +13 -0
- package/dist/client/sse.d.ts.map +1 -1
- package/dist/client/sse.js +129 -0
- package/dist/client/sse.js.map +1 -0
- package/dist/client/types.js +2 -0
- package/dist/client/types.js.map +1 -0
- package/dist/client/ws.d.ts +9 -2
- package/dist/client/ws.d.ts.map +1 -1
- package/dist/client/ws.js +112 -0
- package/dist/client/ws.js.map +1 -0
- package/dist/client-go/errors.go +236 -0
- package/dist/client-go/export.go +44 -0
- package/dist/client-go/invalidation.go +371 -0
- package/dist/client-go/nullable.go +62 -0
- package/dist/client-go/realtime.go +354 -0
- package/dist/client-go/result.go +20 -0
- package/dist/client-go/runtime.go +975 -0
- package/dist/client-go/sse.go +159 -0
- package/dist/client-go/transport.go +495 -0
- package/dist/client-go/ws.go +128 -0
- package/dist/client-info.d.ts +36 -0
- package/dist/client-info.d.ts.map +1 -0
- package/dist/client-info.js +53 -0
- package/dist/client-info.js.map +1 -0
- package/dist/client-mcp/README.md +10 -0
- package/dist/client-mcp/server.ts +221 -0
- package/dist/client-mcp/types.ts +19 -0
- package/dist/client-python/_errors.py +115 -0
- package/dist/client-python/_invalidation.py +494 -0
- package/dist/client-python/_realtime.py +179 -0
- package/dist/client-python/_runtime.py +860 -0
- package/dist/client-python/_sse.py +155 -0
- package/dist/client-python/_transport.py +366 -0
- package/dist/client-python/_ws.py +159 -0
- package/dist/client-python/py.typed +0 -0
- package/dist/client-rust/errors.rs +220 -0
- package/dist/client-rust/invalidation.rs +412 -0
- package/dist/client-rust/invalidation_sync.rs +93 -0
- package/dist/client-rust/nullable.rs +17 -0
- package/dist/client-rust/realtime.rs +702 -0
- package/dist/client-rust/result.rs +22 -0
- package/dist/client-rust/runtime.rs +980 -0
- package/dist/client-rust/runtime_sync.rs +484 -0
- package/dist/client-rust/sse.rs +188 -0
- package/dist/client-rust/ws.rs +167 -0
- package/dist/codegen-go-cli.d.ts.map +1 -1
- package/dist/codegen-go-cli.js +964 -0
- package/dist/codegen-go-cli.js.map +1 -0
- package/dist/codegen-go.d.ts +15 -3
- package/dist/codegen-go.d.ts.map +1 -1
- package/dist/codegen-go.js +872 -0
- package/dist/codegen-go.js.map +1 -0
- package/dist/codegen-hash.js +9 -0
- package/dist/codegen-hash.js.map +1 -0
- package/dist/codegen-ir.d.ts +69 -2
- package/dist/codegen-ir.d.ts.map +1 -1
- package/dist/codegen-ir.js +661 -0
- package/dist/codegen-ir.js.map +1 -0
- package/dist/codegen-lang.d.ts +65 -0
- package/dist/codegen-lang.d.ts.map +1 -0
- package/dist/codegen-lang.js +526 -0
- package/dist/codegen-lang.js.map +1 -0
- package/dist/codegen-load.d.ts +31 -0
- package/dist/codegen-load.d.ts.map +1 -0
- package/dist/codegen-load.js +138 -0
- package/dist/codegen-load.js.map +1 -0
- package/dist/codegen-loaders.js +55 -0
- package/dist/codegen-loaders.js.map +1 -0
- package/dist/codegen-mcp.d.ts.map +1 -1
- package/dist/codegen-mcp.js +368 -0
- package/dist/codegen-mcp.js.map +1 -0
- package/dist/codegen-python.d.ts +13 -1
- package/dist/codegen-python.d.ts.map +1 -1
- package/dist/codegen-python.js +828 -0
- package/dist/codegen-python.js.map +1 -0
- package/dist/codegen-route-tree-intern.d.ts +15 -5
- package/dist/codegen-route-tree-intern.d.ts.map +1 -1
- package/dist/codegen-route-tree-intern.js +221 -0
- package/dist/codegen-route-tree-intern.js.map +1 -0
- package/dist/codegen-rust.d.ts.map +1 -1
- package/dist/codegen-rust.js +1293 -0
- package/dist/codegen-rust.js.map +1 -0
- package/dist/codegen-sanitize.d.ts.map +1 -1
- package/dist/codegen-sanitize.js +56 -0
- package/dist/codegen-sanitize.js.map +1 -0
- package/dist/codegen-schema-naming.d.ts +5 -0
- package/dist/codegen-schema-naming.d.ts.map +1 -1
- package/dist/codegen-schema-naming.js +150 -0
- package/dist/codegen-schema-naming.js.map +1 -0
- package/dist/codegen-sdk-model.d.ts +71 -0
- package/dist/codegen-sdk-model.d.ts.map +1 -0
- package/dist/codegen-sdk-model.js +179 -0
- package/dist/codegen-sdk-model.js.map +1 -0
- package/dist/codegen.d.ts +41 -23
- package/dist/codegen.d.ts.map +1 -1
- package/dist/codegen.js +4610 -0
- package/dist/codegen.js.map +1 -0
- package/dist/context.d.ts +36 -6
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +242 -0
- package/dist/context.js.map +1 -0
- package/dist/cookie-sign.d.ts +16 -2
- package/dist/cookie-sign.d.ts.map +1 -1
- package/dist/cookie-sign.js +104 -0
- package/dist/cookie-sign.js.map +1 -0
- package/dist/cookie.d.ts +12 -0
- package/dist/cookie.d.ts.map +1 -1
- package/dist/cookie.js +138 -0
- package/dist/cookie.js.map +1 -0
- package/dist/cors.d.ts +1 -0
- package/dist/cors.d.ts.map +1 -1
- package/dist/cors.js +87 -0
- package/dist/cors.js.map +1 -0
- package/dist/crypto.d.ts +6 -1
- package/dist/crypto.d.ts.map +1 -1
- package/dist/crypto.js +38 -0
- package/dist/crypto.js.map +1 -0
- package/dist/csrf.d.ts +19 -0
- package/dist/csrf.d.ts.map +1 -1
- package/dist/csrf.js +79 -0
- package/dist/csrf.js.map +1 -0
- package/dist/curl-logger.d.ts +14 -3
- package/dist/curl-logger.d.ts.map +1 -1
- package/dist/curl-logger.js +199 -0
- package/dist/curl-logger.js.map +1 -0
- package/dist/detect-runtime.js +13 -0
- package/dist/detect-runtime.js.map +1 -0
- package/dist/dict.d.ts +11 -0
- package/dist/dict.d.ts.map +1 -0
- package/dist/dict.js +13 -0
- package/dist/dict.js.map +1 -0
- package/dist/error.d.ts.map +1 -1
- package/dist/error.js +44 -0
- package/dist/error.js.map +1 -0
- package/dist/errors.js +39 -0
- package/dist/errors.js.map +1 -0
- package/dist/etag.d.ts +2 -0
- package/dist/etag.d.ts.map +1 -1
- package/dist/etag.js +82 -0
- package/dist/etag.js.map +1 -0
- package/dist/feature-detect.d.ts +25 -0
- package/dist/feature-detect.d.ts.map +1 -0
- package/dist/feature-detect.js +144 -0
- package/dist/feature-detect.js.map +1 -0
- package/dist/feature-load.js +36 -0
- package/dist/feature-load.js.map +1 -0
- package/dist/feature-slots.d.ts +44 -0
- package/dist/feature-slots.d.ts.map +1 -0
- package/dist/feature-slots.js +48 -0
- package/dist/feature-slots.js.map +1 -0
- package/dist/fetch-request.d.ts +10 -0
- package/dist/fetch-request.d.ts.map +1 -0
- package/dist/fetch-request.js +13 -0
- package/dist/fetch-request.js.map +1 -0
- package/dist/gen-process.d.ts +15 -0
- package/dist/gen-process.d.ts.map +1 -0
- package/dist/gen-process.js +43 -0
- package/dist/gen-process.js.map +1 -0
- package/dist/gen-write.d.ts +19 -0
- package/dist/gen-write.d.ts.map +1 -0
- package/dist/gen-write.js +120 -0
- package/dist/gen-write.js.map +1 -0
- package/dist/glob.d.ts +21 -0
- package/dist/glob.d.ts.map +1 -0
- package/dist/glob.js +115 -0
- package/dist/glob.js.map +1 -0
- package/dist/go-type-emitter.d.ts +18 -4
- package/dist/go-type-emitter.d.ts.map +1 -1
- package/dist/go-type-emitter.js +594 -0
- package/dist/go-type-emitter.js.map +1 -0
- package/dist/honey-response.d.ts.map +1 -1
- package/dist/honey-response.js +338 -0
- package/dist/honey-response.js.map +1 -0
- package/dist/i18n-slot.d.ts +8 -0
- package/dist/i18n-slot.d.ts.map +1 -1
- package/dist/i18n-slot.js +14 -0
- package/dist/i18n-slot.js.map +1 -0
- package/dist/i18n.d.ts +3 -0
- package/dist/i18n.d.ts.map +1 -1
- package/dist/i18n.js +250 -0
- package/dist/i18n.js.map +1 -0
- package/dist/index.d.ts +410 -149
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2324 -0
- package/dist/index.js.map +1 -0
- package/dist/init.d.ts +3 -5
- package/dist/init.d.ts.map +1 -1
- package/dist/init.js +140 -0
- package/dist/init.js.map +1 -0
- package/dist/input.js +4 -0
- package/dist/input.js.map +1 -0
- package/dist/invalidate-check.d.ts +11 -0
- package/dist/invalidate-check.d.ts.map +1 -1
- package/dist/invalidate-check.js +163 -0
- package/dist/invalidate-check.js.map +1 -0
- package/dist/invoke-user.d.ts +35 -0
- package/dist/invoke-user.d.ts.map +1 -0
- package/dist/invoke-user.js +73 -0
- package/dist/invoke-user.js.map +1 -0
- package/dist/ip-restrict.d.ts +13 -1
- package/dist/ip-restrict.d.ts.map +1 -1
- package/dist/ip-restrict.js +60 -0
- package/dist/ip-restrict.js.map +1 -0
- package/dist/ip.d.ts +39 -0
- package/dist/ip.d.ts.map +1 -0
- package/dist/ip.js +209 -0
- package/dist/ip.js.map +1 -0
- package/dist/logger.d.ts.map +1 -1
- package/dist/logger.js +113 -0
- package/dist/logger.js.map +1 -0
- package/dist/media-type.d.ts +30 -0
- package/dist/media-type.d.ts.map +1 -0
- package/dist/media-type.js +97 -0
- package/dist/media-type.js.map +1 -0
- package/dist/meta-spec-merge.d.ts +32 -0
- package/dist/meta-spec-merge.d.ts.map +1 -0
- package/dist/meta-spec-merge.js +68 -0
- package/dist/meta-spec-merge.js.map +1 -0
- package/dist/meta-spec.d.ts +16 -3
- package/dist/meta-spec.d.ts.map +1 -1
- package/dist/meta-spec.js +535 -0
- package/dist/meta-spec.js.map +1 -0
- package/dist/middleware.d.ts +23 -6
- package/dist/middleware.d.ts.map +1 -1
- package/dist/middleware.js +253 -0
- package/dist/middleware.js.map +1 -0
- package/dist/node-request.d.ts +57 -12
- package/dist/node-request.d.ts.map +1 -1
- package/dist/node-request.js +407 -0
- package/dist/node-request.js.map +1 -0
- package/dist/node.d.ts +20 -3
- package/dist/node.d.ts.map +1 -1
- package/dist/node.js +396 -0
- package/dist/node.js.map +1 -0
- package/dist/openapi/collect.d.ts +6 -3
- package/dist/openapi/collect.d.ts.map +1 -1
- package/dist/openapi/collect.js +30 -0
- package/dist/openapi/collect.js.map +1 -0
- package/dist/openapi/docs-page.d.ts +42 -0
- package/dist/openapi/docs-page.d.ts.map +1 -0
- package/dist/openapi/docs-page.js +80 -0
- package/dist/openapi/docs-page.js.map +1 -0
- package/dist/openapi/document.d.ts +4 -0
- package/dist/openapi/document.d.ts.map +1 -1
- package/dist/openapi/document.js +785 -0
- package/dist/openapi/document.js.map +1 -0
- package/dist/openapi/json-schema-slot.d.ts +7 -0
- package/dist/openapi/json-schema-slot.d.ts.map +1 -1
- package/dist/openapi/json-schema-slot.js +38 -0
- package/dist/openapi/json-schema-slot.js.map +1 -0
- package/dist/openapi/register.d.ts.map +1 -1
- package/dist/openapi/register.js +20 -0
- package/dist/openapi/register.js.map +1 -0
- package/dist/openapi/scalar.d.ts +3 -1
- package/dist/openapi/scalar.d.ts.map +1 -1
- package/dist/openapi/scalar.js +21 -0
- package/dist/openapi/scalar.js.map +1 -0
- package/dist/openapi/serve.d.ts +9 -0
- package/dist/openapi/serve.d.ts.map +1 -0
- package/dist/openapi/serve.js +36 -0
- package/dist/openapi/serve.js.map +1 -0
- package/dist/openapi/spec-factory.d.ts +30 -1
- package/dist/openapi/spec-factory.d.ts.map +1 -1
- package/dist/openapi/spec-factory.js +52 -0
- package/dist/openapi/spec-factory.js.map +1 -0
- package/dist/openapi/spec.d.ts +14 -5
- package/dist/openapi/spec.d.ts.map +1 -1
- package/dist/openapi/spec.js +50 -0
- package/dist/openapi/spec.js.map +1 -0
- package/dist/openapi/swagger.d.ts +3 -1
- package/dist/openapi/swagger.d.ts.map +1 -1
- package/dist/openapi/swagger.js +22 -0
- package/dist/openapi/swagger.js.map +1 -0
- package/dist/pattern.d.ts +71 -0
- package/dist/pattern.d.ts.map +1 -0
- package/dist/pattern.js +239 -0
- package/dist/pattern.js.map +1 -0
- package/dist/peer.d.ts +17 -0
- package/dist/peer.d.ts.map +1 -0
- package/dist/peer.js +50 -0
- package/dist/peer.js.map +1 -0
- package/dist/plugin.d.ts +67 -16
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +649 -0
- package/dist/plugin.js.map +1 -0
- package/dist/powered-by.d.ts.map +1 -1
- package/dist/powered-by.js +11 -0
- package/dist/powered-by.js.map +1 -0
- package/dist/pretty-json.d.ts.map +1 -1
- package/dist/pretty-json.js +47 -0
- package/dist/pretty-json.js.map +1 -0
- package/dist/producer-stream.d.ts +47 -0
- package/dist/producer-stream.d.ts.map +1 -0
- package/dist/producer-stream.js +267 -0
- package/dist/producer-stream.js.map +1 -0
- package/dist/proxy.d.ts +47 -8
- package/dist/proxy.d.ts.map +1 -1
- package/dist/proxy.js +274 -0
- package/dist/proxy.js.map +1 -0
- package/dist/python-type-emitter.d.ts +14 -1
- package/dist/python-type-emitter.d.ts.map +1 -1
- package/dist/python-type-emitter.js +157 -0
- package/dist/python-type-emitter.js.map +1 -0
- package/dist/realtime/bus.d.ts +17 -1
- package/dist/realtime/bus.d.ts.map +1 -1
- package/dist/realtime/bus.js +112 -0
- package/dist/realtime/bus.js.map +1 -0
- package/dist/realtime/register.d.ts +3 -0
- package/dist/realtime/register.d.ts.map +1 -0
- package/dist/realtime/register.js +10 -0
- package/dist/realtime/register.js.map +1 -0
- package/dist/realtime/route.d.ts +65 -26
- package/dist/realtime/route.d.ts.map +1 -1
- package/dist/realtime/route.js +72 -0
- package/dist/realtime/route.js.map +1 -0
- package/dist/realtime/server.d.ts +43 -0
- package/dist/realtime/server.d.ts.map +1 -0
- package/dist/realtime/server.js +255 -0
- package/dist/realtime/server.js.map +1 -0
- package/dist/request-id.d.ts +7 -0
- package/dist/request-id.d.ts.map +1 -1
- package/dist/request-id.js +16 -0
- package/dist/request-id.js.map +1 -0
- package/dist/request-limits.d.ts +3 -0
- package/dist/request-limits.d.ts.map +1 -0
- package/dist/request-limits.js +3 -0
- package/dist/request-limits.js.map +1 -0
- package/dist/request-path.d.ts +33 -0
- package/dist/request-path.d.ts.map +1 -0
- package/dist/request-path.js +178 -0
- package/dist/request-path.js.map +1 -0
- package/dist/request-to-curl.d.ts +7 -1
- package/dist/request-to-curl.d.ts.map +1 -1
- package/dist/request-to-curl.js +48 -0
- package/dist/request-to-curl.js.map +1 -0
- package/dist/response.d.ts +25 -2
- package/dist/response.d.ts.map +1 -1
- package/dist/response.js +313 -0
- package/dist/response.js.map +1 -0
- package/dist/rust-type-emitter.d.ts +14 -2
- package/dist/rust-type-emitter.d.ts.map +1 -1
- package/dist/rust-type-emitter.js +463 -0
- package/dist/rust-type-emitter.js.map +1 -0
- package/dist/secure-headers.d.ts.map +1 -1
- package/dist/secure-headers.js +53 -0
- package/dist/secure-headers.js.map +1 -0
- package/dist/serve-register.d.ts +4 -0
- package/dist/serve-register.d.ts.map +1 -1
- package/dist/serve-register.js +9 -0
- package/dist/serve-register.js.map +1 -0
- package/dist/serve-slot.d.ts +3 -0
- package/dist/serve-slot.d.ts.map +1 -1
- package/dist/serve-slot.js +52 -0
- package/dist/serve-slot.js.map +1 -0
- package/dist/serve.d.ts +18 -1
- package/dist/serve.d.ts.map +1 -1
- package/dist/serve.js +157 -0
- package/dist/serve.js.map +1 -0
- package/dist/server-timing.d.ts.map +1 -1
- package/dist/server-timing.js +51 -0
- package/dist/server-timing.js.map +1 -0
- package/dist/static.d.ts +9 -0
- package/dist/static.d.ts.map +1 -1
- package/dist/static.js +102 -0
- package/dist/static.js.map +1 -0
- package/dist/telemetry/otel.d.ts +2 -0
- package/dist/telemetry/otel.d.ts.map +1 -1
- package/dist/telemetry/otel.js +135 -0
- package/dist/telemetry/otel.js.map +1 -0
- package/dist/testing.d.ts +12 -0
- package/dist/testing.d.ts.map +1 -1
- package/dist/testing.js +124 -0
- package/dist/testing.js.map +1 -0
- package/dist/timeout.d.ts +6 -0
- package/dist/timeout.d.ts.map +1 -1
- package/dist/timeout.js +36 -0
- package/dist/timeout.js.map +1 -0
- package/dist/tree.d.ts +133 -36
- package/dist/tree.d.ts.map +1 -1
- package/dist/tree.js +437 -0
- package/dist/tree.js.map +1 -0
- package/dist/trust.d.ts +21 -0
- package/dist/trust.d.ts.map +1 -0
- package/dist/trust.js +100 -0
- package/dist/trust.js.map +1 -0
- package/dist/ts-type-emitter.d.ts.map +1 -1
- package/dist/ts-type-emitter.js +150 -0
- package/dist/ts-type-emitter.js.map +1 -0
- package/dist/type-emitter.d.ts +16 -2
- package/dist/type-emitter.d.ts.map +1 -1
- package/dist/type-emitter.js +729 -0
- package/dist/type-emitter.js.map +1 -0
- package/dist/type-extractor.d.ts +8 -4
- package/dist/type-extractor.d.ts.map +1 -1
- package/dist/type-extractor.js +776 -0
- package/dist/type-extractor.js.map +1 -0
- package/dist/types.d.ts +7 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +96 -0
- package/dist/types.js.map +1 -0
- package/dist/validation.d.ts +14 -2
- package/dist/validation.d.ts.map +1 -1
- package/dist/validation.js +335 -0
- package/dist/validation.js.map +1 -0
- package/dist/with-headers.d.ts +15 -0
- package/dist/with-headers.d.ts.map +1 -0
- package/dist/with-headers.js +45 -0
- package/dist/with-headers.js.map +1 -0
- package/dist/ws/bun.d.ts +11 -5
- package/dist/ws/bun.d.ts.map +1 -1
- package/dist/ws/bun.js +82 -0
- package/dist/ws/bun.js.map +1 -0
- package/dist/ws/cloudflare.d.ts +25 -3
- package/dist/ws/cloudflare.d.ts.map +1 -1
- package/dist/ws/cloudflare.js +117 -0
- package/dist/ws/cloudflare.js.map +1 -0
- package/dist/ws/deno.d.ts +4 -4
- package/dist/ws/deno.d.ts.map +1 -1
- package/dist/ws/deno.js +133 -0
- package/dist/ws/deno.js.map +1 -0
- package/dist/ws/node.d.ts +20 -3
- package/dist/ws/node.d.ts.map +1 -1
- package/dist/ws/node.js +173 -0
- package/dist/ws/node.js.map +1 -0
- package/dist/ws/session.d.ts +11 -0
- package/dist/ws/session.d.ts.map +1 -0
- package/dist/ws/session.js +60 -0
- package/dist/ws/session.js.map +1 -0
- package/dist/ws/shared.d.ts +65 -0
- package/dist/ws/shared.d.ts.map +1 -0
- package/dist/ws/shared.js +103 -0
- package/dist/ws/shared.js.map +1 -0
- package/dist/ws-origin.d.ts +20 -0
- package/dist/ws-origin.d.ts.map +1 -0
- package/dist/ws-origin.js +41 -0
- package/dist/ws-origin.js.map +1 -0
- package/dist/yaml.d.ts +15 -1
- package/dist/yaml.d.ts.map +1 -1
- package/dist/yaml.js +101 -0
- package/dist/yaml.js.map +1 -0
- package/docs/invalidate-spec.md +13 -1
- package/docs/meta-spec.md +36 -12
- package/docs/packaging.md +43 -24
- package/docs/regression-matrix/README.md +32 -0
- package/docs/regression-matrix/review.md +44 -0
- package/docs/regression-matrix/ws1-3.md +97 -0
- package/docs/regression-matrix/ws4-8.md +107 -0
- package/docs/regression-matrix/ws9-12.md +266 -0
- package/docs/sdk.md +102 -52
- package/package.json +183 -52
- package/src/accepts.ts +91 -33
- package/src/body-kind.ts +67 -0
- package/src/body-limit.ts +102 -87
- package/src/build/index.ts +104 -54
- package/src/cli-args.ts +123 -0
- package/src/cli-go/auth.go +12 -1
- package/src/cli-go/config.go +29 -2
- package/src/cli-go/errors.go +28 -10
- package/src/cli-go/multipart.go +51 -27
- package/src/cli-go/output.go +58 -4
- package/src/cli-go/root.go +1 -1
- package/src/cli-go/version.go +2 -2
- package/src/cli.ts +154 -148
- package/src/client/error.ts +56 -1
- package/src/client/http.ts +479 -256
- package/src/client/index.ts +55 -17
- package/src/client/path.ts +169 -0
- package/src/client/redirect-policy.ts +19 -0
- package/src/client/sdk.ts +180 -101
- package/src/client/sse.ts +92 -66
- package/src/client/ws.ts +67 -31
- package/src/client-go/errors.go +41 -12
- package/src/client-go/export.go +44 -0
- package/src/client-go/invalidation.go +52 -54
- package/src/client-go/nullable.go +62 -0
- package/src/client-go/realtime.go +147 -110
- package/src/client-go/runtime.go +646 -88
- package/src/client-go/sse.go +104 -94
- package/src/client-go/transport.go +67 -27
- package/src/client-go/ws.go +49 -25
- package/src/client-info.ts +79 -0
- package/src/client-mcp/server.ts +133 -3
- package/src/client-python/_invalidation.py +207 -291
- package/src/client-python/_realtime.py +63 -40
- package/src/client-python/_runtime.py +501 -119
- package/src/client-python/_sse.py +130 -74
- package/src/client-python/_transport.py +37 -9
- package/src/client-python/_ws.py +50 -22
- package/src/client-rust/errors.rs +21 -1
- package/src/client-rust/invalidation.rs +202 -231
- package/src/client-rust/invalidation_sync.rs +16 -229
- package/src/client-rust/nullable.rs +17 -0
- package/src/client-rust/realtime.rs +217 -217
- package/src/client-rust/runtime.rs +602 -177
- package/src/client-rust/runtime_sync.rs +169 -145
- package/src/client-rust/sse.rs +142 -121
- package/src/client-rust/ws.rs +61 -37
- package/src/codegen-go-cli.ts +607 -728
- package/src/codegen-go.ts +710 -770
- package/src/codegen-ir.ts +381 -75
- package/src/codegen-lang.ts +517 -0
- package/src/codegen-load.ts +150 -0
- package/src/codegen-mcp.ts +207 -108
- package/src/codegen-python.ts +684 -816
- package/src/codegen-route-tree-intern.ts +51 -25
- package/src/codegen-rust.ts +946 -1240
- package/src/codegen-sanitize.ts +0 -4
- package/src/codegen-schema-naming.ts +19 -6
- package/src/codegen-sdk-model.ts +228 -0
- package/src/codegen.ts +1488 -1140
- package/src/context.ts +130 -11
- package/src/cookie-sign.ts +85 -16
- package/src/cookie.ts +66 -11
- package/src/cors.ts +55 -54
- package/src/crypto.ts +27 -5
- package/src/csrf.ts +57 -25
- package/src/curl-logger.ts +155 -114
- package/src/dict.ts +12 -0
- package/src/error.ts +4 -2
- package/src/etag.ts +58 -34
- package/src/feature-detect.ts +147 -0
- package/src/feature-slots.ts +70 -0
- package/src/fetch-request.ts +13 -0
- package/src/gen-process.ts +42 -0
- package/src/gen-write.ts +127 -0
- package/src/glob.ts +109 -0
- package/src/go-type-emitter.ts +406 -155
- package/src/honey-response.ts +36 -9
- package/src/i18n-slot.ts +10 -0
- package/src/i18n.ts +98 -23
- package/src/index.ts +1893 -1761
- package/src/init.ts +40 -28
- package/src/invalidate-check.ts +42 -4
- package/src/invoke-user.ts +95 -0
- package/src/ip-restrict.ts +47 -161
- package/src/ip.ts +194 -0
- package/src/logger.ts +65 -36
- package/src/media-type.ts +104 -0
- package/src/meta-spec-merge.ts +80 -0
- package/src/meta-spec.ts +0 -0
- package/src/middleware.ts +112 -12
- package/src/node-request.ts +242 -52
- package/src/node.ts +318 -75
- package/src/openapi/collect.ts +19 -44
- package/src/openapi/docs-page.ts +89 -0
- package/src/openapi/document.ts +503 -224
- package/src/openapi/json-schema-slot.ts +40 -0
- package/src/openapi/register.ts +7 -2
- package/src/openapi/scalar.ts +11 -10
- package/src/openapi/serve.ts +39 -0
- package/src/openapi/spec-factory.ts +50 -1
- package/src/openapi/spec.ts +53 -30
- package/src/openapi/swagger.ts +12 -11
- package/src/pattern.ts +245 -0
- package/src/peer.ts +53 -0
- package/src/plugin.ts +270 -185
- package/src/powered-by.ts +2 -2
- package/src/pretty-json.ts +25 -9
- package/src/producer-stream.ts +296 -0
- package/src/proxy.ts +271 -55
- package/src/python-type-emitter.ts +68 -56
- package/src/realtime/bus.ts +56 -9
- package/src/realtime/register.ts +13 -0
- package/src/realtime/route.ts +129 -80
- package/src/realtime/server.ts +298 -0
- package/src/request-id.ts +13 -3
- package/src/request-limits.ts +2 -0
- package/src/request-path.ts +165 -0
- package/src/request-to-curl.ts +28 -7
- package/src/response.ts +143 -103
- package/src/rust-type-emitter.ts +265 -170
- package/src/secure-headers.ts +8 -4
- package/src/serve-register.ts +4 -0
- package/src/serve-slot.ts +38 -0
- package/src/serve.ts +113 -25
- package/src/server-timing.ts +11 -7
- package/src/static.ts +85 -32
- package/src/telemetry/otel.ts +29 -7
- package/src/testing.ts +76 -14
- package/src/timeout.ts +15 -7
- package/src/tree.ts +405 -333
- package/src/trust.ts +117 -0
- package/src/ts-type-emitter.ts +18 -12
- package/src/type-emitter.ts +227 -89
- package/src/type-extractor.ts +562 -424
- package/src/types.ts +8 -0
- package/src/validation.ts +221 -96
- package/src/with-headers.ts +45 -0
- package/src/ws/bun.ts +53 -15
- package/src/ws/cloudflare.ts +81 -19
- package/src/ws/deno.ts +124 -36
- package/src/ws/node.ts +173 -79
- package/src/ws/session.ts +73 -0
- package/src/ws/shared.ts +140 -0
- package/src/ws-origin.ts +53 -0
- package/src/yaml.ts +45 -22
- package/dist/client-mcp/server.d.ts +0 -10
- package/dist/client-mcp/server.d.ts.map +0 -1
- package/dist/client-mcp/types.d.ts +0 -16
- package/dist/client-mcp/types.d.ts.map +0 -1
- package/dist/cloudflare/realtime.d.ts +0 -30
- package/dist/cloudflare/realtime.d.ts.map +0 -1
- package/dist/realtime/buffer.d.ts +0 -18
- package/dist/realtime/buffer.d.ts.map +0 -1
- package/dist/realtime/longpoll.d.ts +0 -23
- package/dist/realtime/longpoll.d.ts.map +0 -1
- package/dist/realtime/protocol.d.ts +0 -50
- package/dist/realtime/protocol.d.ts.map +0 -1
- package/dist/realtime/runtime.d.ts +0 -74
- package/dist/realtime/runtime.d.ts.map +0 -1
- package/src/cloudflare/realtime.ts +0 -234
- package/src/realtime/buffer.ts +0 -101
- package/src/realtime/longpoll.ts +0 -148
- package/src/realtime/protocol.ts +0 -128
- package/src/realtime/runtime.ts +0 -427
package/src/client/sdk.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ClientConfig, RequestMeta } from "./http.ts"
|
|
2
|
-
import { HTTPClient
|
|
2
|
+
import { HTTPClient } from "./http.ts"
|
|
3
|
+
import { compilePattern, hasPlaceholder, interpolatePartial, interpolatePath } from "./path.ts"
|
|
3
4
|
import { createTypedWebSocket } from "./ws.ts"
|
|
4
5
|
|
|
5
6
|
type ServiceEntry = {
|
|
@@ -27,57 +28,147 @@ function bridge<T>(value: object): T {
|
|
|
27
28
|
return value as T
|
|
28
29
|
}
|
|
29
30
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
return path.replace(/\{(\w+)\}/g, ":$1")
|
|
31
|
+
function own<T>(record: Record<string, T>, key: string): T | undefined {
|
|
32
|
+
return Object.hasOwn(record, key) ? record[key] : undefined
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
|
|
35
|
+
/**
|
|
36
|
+
* Resolve invalidation targets by substituting the mutation's params. Params that are absent
|
|
37
|
+
* stay placeholders, so a partially resolved target is a narrower pattern, never dropped:
|
|
38
|
+
* `PUT /orgs/{org}` invalidating `GET /orgs/:org/members/:id` marks `GET /orgs/acme/members/:id`.
|
|
39
|
+
*/
|
|
36
40
|
export function resolveInvalidationTargets(
|
|
37
41
|
targets: readonly string[],
|
|
38
42
|
params: Record<string, string> | undefined,
|
|
39
43
|
): string[] {
|
|
40
44
|
const resolved: string[] = []
|
|
41
45
|
for (const target of targets) {
|
|
42
|
-
|
|
46
|
+
const spaceIdx = target.indexOf(" ")
|
|
47
|
+
if (spaceIdx === -1 || !params) {
|
|
43
48
|
resolved.push(target)
|
|
44
49
|
continue
|
|
45
50
|
}
|
|
46
|
-
const spaceIdx = target.indexOf(" ")
|
|
47
51
|
const targetMethod = target.slice(0, spaceIdx)
|
|
48
52
|
const targetPath = target.slice(spaceIdx + 1)
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
}
|
|
56
|
-
return encodeURIComponent(val)
|
|
57
|
-
})
|
|
58
|
-
if (hasUnresolved) continue
|
|
59
|
-
resolved.push(`${targetMethod} ${replaced}`)
|
|
53
|
+
try {
|
|
54
|
+
resolved.push(`${targetMethod} ${interpolatePartial(targetPath, params)}`)
|
|
55
|
+
} catch {
|
|
56
|
+
/* a param value that is not a path segment cannot address a resource; keep the pattern */
|
|
57
|
+
resolved.push(target)
|
|
58
|
+
}
|
|
60
59
|
}
|
|
61
60
|
return resolved
|
|
62
61
|
}
|
|
63
62
|
|
|
64
|
-
|
|
65
|
-
const patternRegexCache = new Map<string, RegExp>()
|
|
66
|
-
|
|
67
|
-
/* test if a concrete path matches a route pattern; escapes regex metacharacters in the pattern */
|
|
63
|
+
/** Test if a concrete path matches a route pattern (`:name`, `{name}`, `*`); literal text is escaped. */
|
|
68
64
|
export function pathMatchesPattern(concretePath: string, pattern: string): boolean {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
65
|
+
return compilePattern(pattern).test(concretePath)
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/* Bound memory: an entry remembers the last N mutations that marked it, and which concrete
|
|
69
|
+
paths have already refreshed against a pattern-level mark. */
|
|
70
|
+
const MAX_INVALIDATED_BY = 32
|
|
71
|
+
const MAX_REFRESHED = 1024
|
|
72
|
+
|
|
73
|
+
type StaleEntry = {
|
|
74
|
+
by: Set<string>
|
|
75
|
+
/** Concrete paths that have read once since this pattern was marked (pattern entries only). */
|
|
76
|
+
refreshed?: Set<string>
|
|
77
|
+
seq: number
|
|
78
|
+
until: number
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Stale marks, split by kind so a concrete key is never re-read as a pattern (a path may
|
|
83
|
+
* contain `:`), and a lookup scans only patterns for its own method.
|
|
84
|
+
*/
|
|
85
|
+
export class StaleIndex {
|
|
86
|
+
readonly exact = new Map<string, StaleEntry>()
|
|
87
|
+
readonly patterns = new Map<string, Map<string, StaleEntry>>()
|
|
88
|
+
|
|
89
|
+
mark(target: string, mutation: string, seq: number, until: number): void {
|
|
90
|
+
const spaceIdx = target.indexOf(" ")
|
|
91
|
+
const method = target.slice(0, spaceIdx)
|
|
92
|
+
const path = target.slice(spaceIdx + 1)
|
|
93
|
+
const isPattern = hasPlaceholder(path)
|
|
94
|
+
let table: Map<string, StaleEntry>
|
|
95
|
+
if (isPattern) {
|
|
96
|
+
table = this.patterns.get(method) ?? new Map()
|
|
97
|
+
this.patterns.set(method, table)
|
|
98
|
+
} else {
|
|
99
|
+
table = this.exact
|
|
100
|
+
}
|
|
101
|
+
const existing = table.get(target)
|
|
102
|
+
if (existing) {
|
|
103
|
+
existing.by.delete(mutation)
|
|
104
|
+
existing.by.add(mutation)
|
|
105
|
+
if (existing.by.size > MAX_INVALIDATED_BY) {
|
|
106
|
+
const oldest = existing.by.values().next().value
|
|
107
|
+
if (oldest !== undefined) existing.by.delete(oldest)
|
|
108
|
+
}
|
|
109
|
+
existing.until = until
|
|
110
|
+
existing.seq = seq
|
|
111
|
+
/* a new mutation re-marks every instance */
|
|
112
|
+
if (existing.refreshed) existing.refreshed.clear()
|
|
113
|
+
} else {
|
|
114
|
+
table.set(target, { by: new Set([mutation]), refreshed: isPattern ? new Set() : undefined, seq, until })
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
lookup(
|
|
119
|
+
concreteSelector: string,
|
|
120
|
+
concretePath: string,
|
|
121
|
+
method: string,
|
|
122
|
+
now: number,
|
|
123
|
+
): { by: string[]; isStale: boolean } {
|
|
124
|
+
const by = new Set<string>()
|
|
125
|
+
const exact = this.exact.get(concreteSelector)
|
|
126
|
+
if (exact) {
|
|
127
|
+
if (exact.until > now) for (const m of exact.by) by.add(m)
|
|
128
|
+
else this.exact.delete(concreteSelector)
|
|
129
|
+
}
|
|
130
|
+
const table = this.patterns.get(method)
|
|
131
|
+
if (table) {
|
|
132
|
+
for (const [key, entry] of table) {
|
|
133
|
+
if (entry.until <= now) {
|
|
134
|
+
table.delete(key)
|
|
135
|
+
continue
|
|
136
|
+
}
|
|
137
|
+
if (entry.refreshed?.has(concretePath)) continue
|
|
138
|
+
if (pathMatchesPattern(concretePath, key.slice(key.indexOf(" ") + 1))) {
|
|
139
|
+
for (const m of entry.by) by.add(m)
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
return { by: [...by], isStale: by.size > 0 }
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* A successful stale read clears the mark for that resource only: the exact entry, and this
|
|
148
|
+
* concrete path's share of any pattern entry. Marks newer than the read's snapshot stay.
|
|
149
|
+
*/
|
|
150
|
+
clear(concreteSelector: string, concretePath: string, method: string, snapshot: number): void {
|
|
151
|
+
const exact = this.exact.get(concreteSelector)
|
|
152
|
+
if (exact && exact.seq <= snapshot) this.exact.delete(concreteSelector)
|
|
153
|
+
const table = this.patterns.get(method)
|
|
154
|
+
if (!table) return
|
|
155
|
+
for (const [key, entry] of table) {
|
|
156
|
+
if (entry.seq > snapshot || !entry.refreshed) continue
|
|
157
|
+
if (!pathMatchesPattern(concretePath, key.slice(key.indexOf(" ") + 1))) continue
|
|
158
|
+
if (entry.refreshed.size >= MAX_REFRESHED) {
|
|
159
|
+
const oldest = entry.refreshed.values().next().value
|
|
160
|
+
if (oldest !== undefined) entry.refreshed.delete(oldest)
|
|
161
|
+
}
|
|
162
|
+
entry.refreshed.add(concretePath)
|
|
163
|
+
}
|
|
76
164
|
}
|
|
77
|
-
return re.test(concretePath)
|
|
78
165
|
}
|
|
79
166
|
|
|
80
|
-
|
|
167
|
+
/**
|
|
168
|
+
* Two-tier stale lookup over a flat map (kept for compatibility): exact concrete match, then
|
|
169
|
+
* pattern entries for the same method. Keys are classified by their template placeholders,
|
|
170
|
+
* not by containing `:`. Expired entries are swept.
|
|
171
|
+
*/
|
|
81
172
|
export function lookupStale(
|
|
82
173
|
staleMap: Map<string, { by: string[]; seq: number; until: number }>,
|
|
83
174
|
concreteSelector: string,
|
|
@@ -85,30 +176,33 @@ export function lookupStale(
|
|
|
85
176
|
method: string,
|
|
86
177
|
now: number,
|
|
87
178
|
): { by: string[]; isStale: boolean } {
|
|
88
|
-
const allBy
|
|
89
|
-
const expired: string[] = []
|
|
90
|
-
|
|
91
|
-
const exact = staleMap.get(concreteSelector)
|
|
92
|
-
if (exact && exact.until > now) allBy.push(...exact.by)
|
|
93
|
-
else if (exact) expired.push(concreteSelector)
|
|
94
|
-
|
|
179
|
+
const allBy = new Set<string>()
|
|
95
180
|
for (const [key, entry] of staleMap) {
|
|
96
181
|
if (entry.until <= now) {
|
|
97
|
-
|
|
182
|
+
staleMap.delete(key)
|
|
183
|
+
continue
|
|
184
|
+
}
|
|
185
|
+
if (key === concreteSelector) {
|
|
186
|
+
for (const m of entry.by) allBy.add(m)
|
|
98
187
|
continue
|
|
99
188
|
}
|
|
100
|
-
if (!key.includes(":")) continue
|
|
101
189
|
const spaceIdx = key.indexOf(" ")
|
|
102
|
-
|
|
190
|
+
if (key.slice(0, spaceIdx) !== method) continue
|
|
103
191
|
const keyPattern = key.slice(spaceIdx + 1)
|
|
104
|
-
if (
|
|
105
|
-
|
|
106
|
-
allBy.push(...entry.by)
|
|
192
|
+
if (hasPlaceholder(keyPattern) && pathMatchesPattern(concretePath, keyPattern)) {
|
|
193
|
+
for (const m of entry.by) allBy.add(m)
|
|
107
194
|
}
|
|
108
195
|
}
|
|
109
|
-
|
|
196
|
+
return { by: [...allBy], isStale: allBy.size > 0 }
|
|
197
|
+
}
|
|
110
198
|
|
|
111
|
-
|
|
199
|
+
function isServiceEntry(node: unknown): node is ServiceEntry {
|
|
200
|
+
return (
|
|
201
|
+
typeof node === "object" &&
|
|
202
|
+
node !== null &&
|
|
203
|
+
typeof (node as Record<string, unknown>)["method"] === "string" &&
|
|
204
|
+
typeof (node as Record<string, unknown>)["path"] === "string"
|
|
205
|
+
)
|
|
112
206
|
}
|
|
113
207
|
|
|
114
208
|
export function createSDK<T = Record<string, Record<string, (...args: unknown[]) => unknown>>>(
|
|
@@ -117,15 +211,15 @@ export function createSDK<T = Record<string, Record<string, (...args: unknown[])
|
|
|
117
211
|
): T {
|
|
118
212
|
const http = new HTTPClient(config)
|
|
119
213
|
const staleTime = config.invalidation?.staleTime ?? 0
|
|
120
|
-
const
|
|
121
|
-
const staleUntil = hasInvalidation ? new Map<string, { by: string[]; seq: number; until: number }>() : null
|
|
214
|
+
const stale = staleTime > 0 ? new StaleIndex() : null
|
|
122
215
|
|
|
123
216
|
let invalidationSeq = 0
|
|
124
217
|
|
|
125
218
|
const rootCache = new Map<string, object>()
|
|
126
219
|
|
|
127
220
|
function buildLeafFn(entry: ServiceEntry, namePath: string[]): Function {
|
|
128
|
-
|
|
221
|
+
/* Paths keep their template; HTTPClient interpolates `{name}` and `:name` alike. */
|
|
222
|
+
const path = entry.path
|
|
129
223
|
const method = entry.method
|
|
130
224
|
let fn: Function
|
|
131
225
|
|
|
@@ -151,13 +245,12 @@ export function createSDK<T = Record<string, Record<string, (...args: unknown[])
|
|
|
151
245
|
fn = async (input?: Record<string, unknown>) => {
|
|
152
246
|
const opts = input ?? {}
|
|
153
247
|
const params = opts["params"] as Record<string, string> | undefined
|
|
154
|
-
const concretePath =
|
|
248
|
+
const concretePath = interpolatePath(path, params ?? {})
|
|
155
249
|
const concreteSelector = `${method} ${concretePath}`
|
|
156
250
|
let requestMeta: RequestMeta | undefined
|
|
157
251
|
|
|
158
|
-
if (
|
|
159
|
-
const
|
|
160
|
-
const { by, isStale } = lookupStale(staleUntil, concreteSelector, concretePath, method, now)
|
|
252
|
+
if (stale) {
|
|
253
|
+
const { by, isStale } = stale.lookup(concreteSelector, concretePath, method, Date.now())
|
|
161
254
|
requestMeta = { invalidatedBy: by, isStale, selector: concreteSelector, seqSnapshot: invalidationSeq }
|
|
162
255
|
}
|
|
163
256
|
|
|
@@ -166,7 +259,7 @@ export function createSDK<T = Record<string, Record<string, (...args: unknown[])
|
|
|
166
259
|
? await http.request(method, path, opts, requestMeta)
|
|
167
260
|
: await http.requestSafe(method, path, opts, requestMeta)
|
|
168
261
|
|
|
169
|
-
if (
|
|
262
|
+
if (stale) {
|
|
170
263
|
const isSuccess =
|
|
171
264
|
config.throwOnError === true
|
|
172
265
|
? true
|
|
@@ -176,34 +269,13 @@ export function createSDK<T = Record<string, Record<string, (...args: unknown[])
|
|
|
176
269
|
if (entry.invalidate && entry.invalidate.length > 0) {
|
|
177
270
|
const seq = ++invalidationSeq
|
|
178
271
|
const until = Date.now() + staleTime
|
|
179
|
-
const
|
|
180
|
-
|
|
181
|
-
for (const target of resolved) {
|
|
182
|
-
const existing = staleUntil.get(target)
|
|
183
|
-
if (existing) {
|
|
184
|
-
if (!existing.by.includes(mutationSelector)) existing.by.push(mutationSelector)
|
|
185
|
-
existing.until = until
|
|
186
|
-
existing.seq = seq
|
|
187
|
-
} else {
|
|
188
|
-
staleUntil.set(target, { by: [mutationSelector], seq, until })
|
|
189
|
-
}
|
|
272
|
+
for (const target of resolveInvalidationTargets(entry.invalidate, params)) {
|
|
273
|
+
stale.mark(target, concreteSelector, seq, until)
|
|
190
274
|
}
|
|
191
275
|
}
|
|
192
276
|
|
|
193
277
|
if (requestMeta?.isStale) {
|
|
194
|
-
|
|
195
|
-
const exact = staleUntil.get(concreteSelector)
|
|
196
|
-
if (exact && exact.seq <= snapshot) staleUntil.delete(concreteSelector)
|
|
197
|
-
const toDelete: string[] = []
|
|
198
|
-
for (const [key, staleEntry] of staleUntil) {
|
|
199
|
-
if (staleEntry.seq > snapshot) continue
|
|
200
|
-
if (!key.includes(":")) continue
|
|
201
|
-
const spaceIdx = key.indexOf(" ")
|
|
202
|
-
const keyMethod = key.slice(0, spaceIdx)
|
|
203
|
-
const keyPattern = key.slice(spaceIdx + 1)
|
|
204
|
-
if (keyMethod === method && pathMatchesPattern(concretePath, keyPattern)) toDelete.push(key)
|
|
205
|
-
}
|
|
206
|
-
for (const key of toDelete) staleUntil.delete(key)
|
|
278
|
+
stale.clear(concreteSelector, concretePath, method, requestMeta.seqSnapshot)
|
|
207
279
|
}
|
|
208
280
|
}
|
|
209
281
|
}
|
|
@@ -216,27 +288,39 @@ export function createSDK<T = Record<string, Record<string, (...args: unknown[])
|
|
|
216
288
|
return fn
|
|
217
289
|
}
|
|
218
290
|
|
|
291
|
+
/** Own keys only: names like `toString` or `constructor` must not resolve through the prototype. */
|
|
292
|
+
function resolveChild(node: Record<string, unknown>, key: string | symbol, namePath: string[]): unknown {
|
|
293
|
+
if (typeof key === "symbol" || key === "then") return undefined
|
|
294
|
+
const child = own(node, key)
|
|
295
|
+
if (child === undefined) {
|
|
296
|
+
if (key === "toString" || key === "toJSON")
|
|
297
|
+
return () => `[object HoneySDK${namePath.length ? ` ${namePath.join(".")}` : ""}]`
|
|
298
|
+
return undefined
|
|
299
|
+
}
|
|
300
|
+
return child
|
|
301
|
+
}
|
|
302
|
+
|
|
219
303
|
function makeNodeProxy(node: ServiceMapNode, namePath: string[]): object {
|
|
220
304
|
const actionCache = new Map<string, Function>()
|
|
221
305
|
const childCache = new Map<string, object>()
|
|
222
306
|
return new Proxy({} as Record<string, unknown>, {
|
|
223
307
|
get(_, key: string | symbol) {
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
308
|
+
const child = resolveChild(node as Record<string, unknown>, key, namePath)
|
|
309
|
+
if (child === undefined || typeof child === "function") return child
|
|
310
|
+
const name = key as string
|
|
227
311
|
|
|
228
|
-
if (
|
|
229
|
-
const cached = actionCache.get(
|
|
312
|
+
if (isServiceEntry(child)) {
|
|
313
|
+
const cached = actionCache.get(name)
|
|
230
314
|
if (cached) return cached
|
|
231
|
-
const fn = buildLeafFn(child
|
|
232
|
-
actionCache.set(
|
|
315
|
+
const fn = buildLeafFn(child, [...namePath, name])
|
|
316
|
+
actionCache.set(name, fn)
|
|
233
317
|
return fn
|
|
234
318
|
}
|
|
235
319
|
|
|
236
|
-
const cached = childCache.get(
|
|
320
|
+
const cached = childCache.get(name)
|
|
237
321
|
if (cached) return cached
|
|
238
|
-
const childProxy = makeNodeProxy(child as ServiceMapNode, [...namePath,
|
|
239
|
-
childCache.set(
|
|
322
|
+
const childProxy = makeNodeProxy(child as ServiceMapNode, [...namePath, name])
|
|
323
|
+
childCache.set(name, childProxy)
|
|
240
324
|
return childProxy
|
|
241
325
|
},
|
|
242
326
|
})
|
|
@@ -247,23 +331,18 @@ export function createSDK<T = Record<string, Record<string, (...args: unknown[])
|
|
|
247
331
|
{},
|
|
248
332
|
{
|
|
249
333
|
get(_target, key: string | symbol) {
|
|
250
|
-
|
|
334
|
+
const node = resolveChild(serviceMap as Record<string, unknown>, key, [])
|
|
335
|
+
if (node === undefined || typeof node === "function") return node
|
|
336
|
+
const name = key as string
|
|
251
337
|
|
|
252
|
-
const cached = rootCache.get(
|
|
338
|
+
const cached = rootCache.get(name)
|
|
253
339
|
if (cached) return cached
|
|
254
340
|
|
|
255
|
-
const
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
let result: object
|
|
259
|
-
if (typeof (node as Record<string, unknown>)["method"] === "string") {
|
|
260
|
-
const fn = buildLeafFn(node as ServiceEntry, [key as string])
|
|
261
|
-
result = fn as unknown as object
|
|
262
|
-
} else {
|
|
263
|
-
result = makeNodeProxy(node, [key as string])
|
|
264
|
-
}
|
|
341
|
+
const result = isServiceEntry(node)
|
|
342
|
+
? (buildLeafFn(node, [name]) as unknown as object)
|
|
343
|
+
: makeNodeProxy(node as ServiceMapNode, [name])
|
|
265
344
|
|
|
266
|
-
rootCache.set(
|
|
345
|
+
rootCache.set(name, result)
|
|
267
346
|
return result
|
|
268
347
|
},
|
|
269
348
|
},
|
package/src/client/sse.ts
CHANGED
|
@@ -1,102 +1,128 @@
|
|
|
1
1
|
export type SSEEvent = {
|
|
2
2
|
data: string
|
|
3
3
|
event?: string
|
|
4
|
+
/** The last event ID (sticky across events, as `EventSource.lastEventId`). Absent while empty. */
|
|
4
5
|
id?: string
|
|
5
6
|
retry?: number
|
|
6
7
|
}
|
|
7
8
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
const DEFAULT_MAX_BUFFER = 1024 * 1024
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Parse a `text/event-stream` body per the WHATWG HTML "event stream interpretation" rules:
|
|
13
|
+
*
|
|
14
|
+
* - lines end at CRLF, LF or CR (a CR at a chunk boundary waits for a possible LF);
|
|
15
|
+
* - a leading BOM is skipped;
|
|
16
|
+
* - `id` persists across events until changed, and an `id` containing NUL is ignored;
|
|
17
|
+
* - `retry` is accepted only when it is all ASCII digits;
|
|
18
|
+
* - an event still open when the stream ends is discarded, never dispatched.
|
|
19
|
+
*
|
|
20
|
+
* `maxBufferSize` caps both an unterminated line and the data of one event (UTF-16 code
|
|
21
|
+
* units); exceeding it throws.
|
|
22
|
+
*/
|
|
23
|
+
export async function* parseSSEStream(
|
|
24
|
+
stream: ReadableStream<Uint8Array>,
|
|
25
|
+
opts?: { maxBufferSize?: number },
|
|
26
|
+
): AsyncGenerator<SSEEvent, void, undefined> {
|
|
27
|
+
const decoder = new TextDecoder()
|
|
28
|
+
const reader = stream.getReader()
|
|
29
|
+
const maxBuffer = opts?.maxBufferSize ?? DEFAULT_MAX_BUFFER
|
|
30
|
+
|
|
31
|
+
let pending = ""
|
|
32
|
+
let first = true
|
|
33
|
+
let data: string[] = []
|
|
34
|
+
let dataSize = 0
|
|
35
|
+
let hasData = false
|
|
12
36
|
let event: string | undefined
|
|
13
|
-
let
|
|
37
|
+
let lastId = ""
|
|
14
38
|
let retry: number | undefined
|
|
15
39
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
if (colonIdx === -1) {
|
|
24
|
-
field = line
|
|
25
|
-
val = ""
|
|
26
|
-
} else {
|
|
27
|
-
field = line.slice(0, colonIdx)
|
|
28
|
-
val = line.slice(colonIdx + 1)
|
|
29
|
-
if (val.startsWith(" ")) val = val.slice(1)
|
|
40
|
+
const dispatch = (): SSEEvent | undefined => {
|
|
41
|
+
const out = hasData ? ({ data: data.join("\n") } as SSEEvent) : undefined
|
|
42
|
+
if (out) {
|
|
43
|
+
if (event !== undefined && event !== "") out.event = event
|
|
44
|
+
if (lastId !== "") out.id = lastId
|
|
45
|
+
if (retry !== undefined) out.retry = retry
|
|
46
|
+
retry = undefined
|
|
30
47
|
}
|
|
48
|
+
data = []
|
|
49
|
+
dataSize = 0
|
|
50
|
+
hasData = false
|
|
51
|
+
event = undefined
|
|
52
|
+
return out
|
|
53
|
+
}
|
|
31
54
|
|
|
55
|
+
const processLine = (line: string): void => {
|
|
56
|
+
if (line.charCodeAt(0) === 58 /* : */) return
|
|
57
|
+
const colon = line.indexOf(":")
|
|
58
|
+
const field = colon === -1 ? line : line.slice(0, colon)
|
|
59
|
+
let value = colon === -1 ? "" : line.slice(colon + 1)
|
|
60
|
+
if (value.charCodeAt(0) === 32) value = value.slice(1)
|
|
32
61
|
switch (field) {
|
|
33
62
|
case "data":
|
|
34
|
-
|
|
63
|
+
dataSize += value.length + 1
|
|
64
|
+
if (dataSize > maxBuffer) throw new Error(`SSE event exceeded ${maxBuffer} characters`)
|
|
65
|
+
data.push(value)
|
|
66
|
+
hasData = true
|
|
35
67
|
break
|
|
36
68
|
case "event":
|
|
37
|
-
event =
|
|
69
|
+
event = value
|
|
38
70
|
break
|
|
39
71
|
case "id":
|
|
40
|
-
|
|
41
|
-
if (!val.includes("\0")) id = val
|
|
72
|
+
if (!value.includes("\0")) lastId = value
|
|
42
73
|
break
|
|
43
|
-
case "retry":
|
|
44
|
-
|
|
45
|
-
if (Number.isFinite(n) && n >= 0) retry = n
|
|
74
|
+
case "retry":
|
|
75
|
+
if (/^\d+$/.test(value)) retry = Number(value)
|
|
46
76
|
break
|
|
47
|
-
}
|
|
48
77
|
}
|
|
49
78
|
}
|
|
50
79
|
|
|
51
|
-
if (isComment || data === undefined) return undefined
|
|
52
|
-
|
|
53
|
-
const sse: SSEEvent = { data }
|
|
54
|
-
if (event !== undefined) sse.event = event
|
|
55
|
-
if (id !== undefined) sse.id = id
|
|
56
|
-
if (retry !== undefined) sse.retry = retry
|
|
57
|
-
return sse
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
const DEFAULT_MAX_BUFFER = 1024 * 1024
|
|
61
|
-
|
|
62
|
-
export async function* parseSSEStream(
|
|
63
|
-
stream: ReadableStream<Uint8Array>,
|
|
64
|
-
opts?: { maxBufferSize?: number },
|
|
65
|
-
): AsyncGenerator<SSEEvent, void, undefined> {
|
|
66
|
-
const decoder = new TextDecoder()
|
|
67
|
-
const reader = stream.getReader()
|
|
68
|
-
let buffer = ""
|
|
69
|
-
const maxBuffer = opts?.maxBufferSize ?? DEFAULT_MAX_BUFFER
|
|
70
|
-
|
|
71
80
|
try {
|
|
72
81
|
while (true) {
|
|
73
82
|
const { done, value } = await reader.read()
|
|
74
83
|
if (done) break
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
84
|
+
pending += decoder.decode(value, { stream: true })
|
|
85
|
+
if (first && pending.length > 0) {
|
|
86
|
+
if (pending.charCodeAt(0) === 0xfeff) pending = pending.slice(1)
|
|
87
|
+
first = false
|
|
79
88
|
}
|
|
80
89
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
if (
|
|
90
|
+
let start = 0
|
|
91
|
+
while (start < pending.length) {
|
|
92
|
+
let end = start
|
|
93
|
+
while (end < pending.length) {
|
|
94
|
+
const c = pending.charCodeAt(end)
|
|
95
|
+
if (c === 10 || c === 13) break
|
|
96
|
+
end++
|
|
97
|
+
}
|
|
98
|
+
if (end === pending.length) break
|
|
99
|
+
/* A CR as the last character may be the first half of CRLF. */
|
|
100
|
+
if (pending.charCodeAt(end) === 13 && end === pending.length - 1) break
|
|
101
|
+
const line = pending.slice(start, end)
|
|
102
|
+
start = end + (pending.charCodeAt(end) === 13 && pending.charCodeAt(end + 1) === 10 ? 2 : 1)
|
|
103
|
+
if (line === "") {
|
|
104
|
+
const out = dispatch()
|
|
105
|
+
if (out) yield out
|
|
106
|
+
} else {
|
|
107
|
+
processLine(line)
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
pending = pending.slice(start)
|
|
111
|
+
if (pending.length > maxBuffer) {
|
|
112
|
+
throw new Error(`SSE buffer exceeded ${maxBuffer} characters`)
|
|
90
113
|
}
|
|
91
114
|
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
115
|
+
/* A lone CR held back at the end of the stream still terminates its line. */
|
|
116
|
+
if (pending.endsWith("\r")) {
|
|
117
|
+
const line = pending.slice(0, -1)
|
|
118
|
+
if (line === "") {
|
|
119
|
+
const out = dispatch()
|
|
120
|
+
if (out) yield out
|
|
121
|
+
}
|
|
97
122
|
}
|
|
123
|
+
/* Anything else still open is an incomplete event: discard it. */
|
|
98
124
|
} finally {
|
|
99
|
-
await reader.cancel()
|
|
125
|
+
await reader.cancel().catch(() => {})
|
|
100
126
|
reader.releaseLock()
|
|
101
127
|
}
|
|
102
128
|
}
|