@lovrozagar/honey 0.6.8 → 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 +408 -148
- 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 +1887 -1756
- 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 +253 -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-rust/sse.rs
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
/* Code generated by honey. DO NOT EDIT. */
|
|
2
2
|
|
|
3
3
|
use crate::errors::{raise_for_status, Error};
|
|
4
|
-
use bytes::Bytes;
|
|
5
4
|
use futures_util::StreamExt;
|
|
6
5
|
|
|
7
|
-
/// SseEvent represents a single server-sent event.
|
|
6
|
+
/// SseEvent represents a single server-sent event. `id` is the last event id
|
|
7
|
+
/// seen on the stream so far (the spec's sticky "last event ID buffer").
|
|
8
|
+
#[derive(Debug, Clone, Default, PartialEq)]
|
|
8
9
|
pub struct SseEvent {
|
|
9
10
|
pub data: String,
|
|
10
11
|
pub event: String,
|
|
@@ -12,156 +13,176 @@ pub struct SseEvent {
|
|
|
12
13
|
pub retry: i32,
|
|
13
14
|
}
|
|
14
15
|
|
|
15
|
-
///
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
pub fn parse_sse_stream(
|
|
19
|
-
resp: reqwest::Response,
|
|
20
|
-
) -> impl futures_util::Stream<Item = Result<SseEvent, Error>> {
|
|
21
|
-
async_stream::stream! {
|
|
22
|
-
let status = resp.status().as_u16();
|
|
23
|
-
if !(200..300).contains(&status) {
|
|
24
|
-
let body = resp.bytes().await.unwrap_or_default().to_vec();
|
|
25
|
-
if let Some(err) = raise_for_status(status, body) {
|
|
26
|
-
yield Err(err);
|
|
27
|
-
}
|
|
28
|
-
return;
|
|
29
|
-
}
|
|
16
|
+
/// Largest single line, and largest data of one event.
|
|
17
|
+
pub const SSE_MAX_LINE: usize = 1024 * 1024;
|
|
18
|
+
pub const SSE_MAX_EVENT: usize = 8 * 1024 * 1024;
|
|
30
19
|
|
|
31
|
-
|
|
32
|
-
|
|
20
|
+
/// SseParser is an incremental WHATWG event-stream parser. Lines end in CRLF,
|
|
21
|
+
/// LF or CR; a blank line dispatches; a final event without its blank line is
|
|
22
|
+
/// never dispatched; `id` is sticky; `retry` needs ASCII digits; field values
|
|
23
|
+
/// are not trimmed. Each input byte is scanned once.
|
|
24
|
+
#[derive(Debug, Default)]
|
|
25
|
+
pub struct SseParser {
|
|
26
|
+
line: Vec<u8>,
|
|
27
|
+
pending_cr: bool,
|
|
28
|
+
started: bool,
|
|
29
|
+
data: String,
|
|
30
|
+
has_data: bool,
|
|
31
|
+
event: String,
|
|
32
|
+
last_id: String,
|
|
33
|
+
retry: i32,
|
|
34
|
+
}
|
|
33
35
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
36
|
+
impl SseParser {
|
|
37
|
+
pub fn new() -> Self {
|
|
38
|
+
Self::default()
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/// feed consumes a chunk and returns every event it completes.
|
|
42
|
+
pub fn feed(&mut self, chunk: &[u8]) -> Result<Vec<SseEvent>, Error> {
|
|
43
|
+
let mut out = Vec::new();
|
|
44
|
+
for &b in chunk {
|
|
45
|
+
if self.pending_cr {
|
|
46
|
+
self.pending_cr = false;
|
|
47
|
+
if b == b'\n' {
|
|
48
|
+
continue;
|
|
39
49
|
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
buf.drain(..end);
|
|
50
|
-
let block_str = String::from_utf8_lossy(&block);
|
|
51
|
-
let trimmed = block_str.trim();
|
|
52
|
-
if !trimmed.is_empty() {
|
|
53
|
-
if let Some(ev) = parse_sse_block(trimmed) {
|
|
54
|
-
yield Ok(ev);
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
}
|
|
50
|
+
}
|
|
51
|
+
match b {
|
|
52
|
+
b'\n' | b'\r' => {
|
|
53
|
+
if b == b'\r' {
|
|
54
|
+
self.pending_cr = true;
|
|
55
|
+
}
|
|
56
|
+
let line = std::mem::take(&mut self.line);
|
|
57
|
+
if let Some(ev) = self.process(&line)? {
|
|
58
|
+
out.push(ev);
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
let block_str = String::from_utf8_lossy(&buf);
|
|
67
|
-
let trimmed = block_str.trim();
|
|
68
|
-
if !trimmed.is_empty() {
|
|
69
|
-
if let Some(ev) = parse_sse_block(trimmed) {
|
|
70
|
-
yield Ok(ev);
|
|
61
|
+
_ => {
|
|
62
|
+
if self.line.len() >= SSE_MAX_LINE {
|
|
63
|
+
return Err(Error::Other("sse line exceeds 1 MiB".into()));
|
|
64
|
+
}
|
|
65
|
+
self.line.push(b);
|
|
71
66
|
}
|
|
72
67
|
}
|
|
73
68
|
}
|
|
69
|
+
Ok(out)
|
|
74
70
|
}
|
|
75
|
-
}
|
|
76
71
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
if buf.len() < dlen {
|
|
84
|
-
continue;
|
|
85
|
-
}
|
|
86
|
-
for i in 0..=(buf.len() - dlen) {
|
|
87
|
-
if &buf[i..i + dlen] == *delim {
|
|
88
|
-
return Some((i, i + dlen));
|
|
72
|
+
fn process(&mut self, raw: &[u8]) -> Result<Option<SseEvent>, Error> {
|
|
73
|
+
let mut line = String::from_utf8_lossy(raw).into_owned();
|
|
74
|
+
if !self.started {
|
|
75
|
+
self.started = true;
|
|
76
|
+
if let Some(rest) = line.strip_prefix('\u{feff}') {
|
|
77
|
+
line = rest.to_string();
|
|
89
78
|
}
|
|
90
79
|
}
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
/// parse_sse_block parses a single SSE message block into an SseEvent.
|
|
96
|
-
/// Mirrors Go parseSSEBlock line-for-line:
|
|
97
|
-
/// - colon-prefix lines are comments and skipped
|
|
98
|
-
/// - field/val split on first colon; leading space stripped from val
|
|
99
|
-
/// - data lines joined with \n
|
|
100
|
-
/// - id containing null byte (\0) is ignored per spec
|
|
101
|
-
/// - retry parsed as non-negative i32
|
|
102
|
-
pub(crate) fn parse_sse_block(block: &str) -> Option<SseEvent> {
|
|
103
|
-
let mut data = String::new();
|
|
104
|
-
let mut has_data = false;
|
|
105
|
-
let mut event = String::new();
|
|
106
|
-
let mut id = String::new();
|
|
107
|
-
let mut retry: i32 = 0;
|
|
108
|
-
let mut is_comment = true;
|
|
109
|
-
|
|
110
|
-
for raw_line in block.split('\n') {
|
|
111
|
-
let line = raw_line.trim_end_matches('\r');
|
|
80
|
+
if line.is_empty() {
|
|
81
|
+
return Ok(self.dispatch());
|
|
82
|
+
}
|
|
112
83
|
if line.starts_with(':') {
|
|
113
|
-
|
|
84
|
+
return Ok(None);
|
|
114
85
|
}
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
(f, v)
|
|
122
|
-
} else {
|
|
123
|
-
(line, "")
|
|
86
|
+
let (field, value) = match line.find(':') {
|
|
87
|
+
Some(i) => {
|
|
88
|
+
let v = &line[i + 1..];
|
|
89
|
+
(&line[..i], v.strip_prefix(' ').unwrap_or(v))
|
|
90
|
+
}
|
|
91
|
+
None => (line.as_str(), ""),
|
|
124
92
|
};
|
|
125
|
-
|
|
126
93
|
match field {
|
|
127
94
|
"data" => {
|
|
128
|
-
if has_data {
|
|
129
|
-
data.push('\n');
|
|
130
|
-
data.push_str(val);
|
|
131
|
-
} else {
|
|
132
|
-
data = val.to_string();
|
|
133
|
-
has_data = true;
|
|
95
|
+
if self.has_data {
|
|
96
|
+
self.data.push('\n');
|
|
134
97
|
}
|
|
98
|
+
if self.data.len() + value.len() > SSE_MAX_EVENT {
|
|
99
|
+
return Err(Error::Other("sse event exceeds 8 MiB".into()));
|
|
100
|
+
}
|
|
101
|
+
self.data.push_str(value);
|
|
102
|
+
self.has_data = true;
|
|
135
103
|
}
|
|
136
|
-
"event" =>
|
|
137
|
-
event = val.to_string();
|
|
138
|
-
}
|
|
104
|
+
"event" => self.event = value.to_string(),
|
|
139
105
|
"id" => {
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
id = val.to_string();
|
|
106
|
+
if !value.contains('\0') {
|
|
107
|
+
self.last_id = value.to_string();
|
|
143
108
|
}
|
|
144
109
|
}
|
|
145
110
|
"retry" => {
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
retry = n;
|
|
111
|
+
if !value.is_empty() && value.bytes().all(|c| c.is_ascii_digit()) {
|
|
112
|
+
if let Ok(n) = value.parse::<i32>() {
|
|
113
|
+
self.retry = n;
|
|
150
114
|
}
|
|
151
115
|
}
|
|
152
116
|
}
|
|
153
117
|
_ => {}
|
|
154
118
|
}
|
|
119
|
+
Ok(None)
|
|
155
120
|
}
|
|
156
121
|
|
|
157
|
-
|
|
158
|
-
|
|
122
|
+
fn dispatch(&mut self) -> Option<SseEvent> {
|
|
123
|
+
let ev = if self.has_data {
|
|
124
|
+
Some(SseEvent {
|
|
125
|
+
data: std::mem::take(&mut self.data),
|
|
126
|
+
event: std::mem::take(&mut self.event),
|
|
127
|
+
id: self.last_id.clone(),
|
|
128
|
+
retry: self.retry,
|
|
129
|
+
})
|
|
130
|
+
} else {
|
|
131
|
+
None
|
|
132
|
+
};
|
|
133
|
+
self.data.clear();
|
|
134
|
+
self.has_data = false;
|
|
135
|
+
self.event.clear();
|
|
136
|
+
self.retry = 0;
|
|
137
|
+
ev
|
|
159
138
|
}
|
|
139
|
+
}
|
|
160
140
|
|
|
161
|
-
|
|
141
|
+
/// parse_sse_text parses complete text; used by the conformance vectors.
|
|
142
|
+
pub fn parse_sse_text(chunks: &[&str]) -> Result<Vec<SseEvent>, Error> {
|
|
143
|
+
let mut p = SseParser::new();
|
|
144
|
+
let mut out = Vec::new();
|
|
145
|
+
for c in chunks {
|
|
146
|
+
out.extend(p.feed(c.as_bytes())?);
|
|
147
|
+
}
|
|
148
|
+
Ok(out)
|
|
162
149
|
}
|
|
163
150
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
151
|
+
/// parse_sse_stream returns a Stream of SseEvent values read from a reqwest Response.
|
|
152
|
+
/// On non-2xx response it yields a typed error immediately then terminates.
|
|
153
|
+
pub fn parse_sse_stream(
|
|
154
|
+
resp: reqwest::Response,
|
|
155
|
+
) -> impl futures_util::Stream<Item = Result<SseEvent, Error>> {
|
|
156
|
+
async_stream::stream! {
|
|
157
|
+
let status = resp.status().as_u16();
|
|
158
|
+
if !(200..300).contains(&status) {
|
|
159
|
+
let body = resp.bytes().await.unwrap_or_default().to_vec();
|
|
160
|
+
if let Some(err) = raise_for_status(status, body) {
|
|
161
|
+
yield Err(err);
|
|
162
|
+
}
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
let mut byte_stream = resp.bytes_stream();
|
|
167
|
+
let mut parser = SseParser::new();
|
|
168
|
+
while let Some(chunk) = byte_stream.next().await {
|
|
169
|
+
match chunk {
|
|
170
|
+
Err(e) => {
|
|
171
|
+
yield Err(Error::Transport(e));
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
Ok(bytes) => match parser.feed(&bytes) {
|
|
175
|
+
Ok(events) => {
|
|
176
|
+
for ev in events {
|
|
177
|
+
yield Ok(ev);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
Err(e) => {
|
|
181
|
+
yield Err(e);
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
},
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
package/src/client-rust/ws.rs
CHANGED
|
@@ -20,16 +20,17 @@ pub const WS_STATUS_PROTOCOL_ERROR: u16 = 1002;
|
|
|
20
20
|
type WsStream = WebSocketStream<tokio_tungstenite::MaybeTlsStream<tokio::net::TcpStream>>;
|
|
21
21
|
|
|
22
22
|
type WsHandler = Box<dyn Fn(&[u8]) + Send + Sync>;
|
|
23
|
-
type
|
|
23
|
+
type SharedHandler = std::sync::Arc<dyn Fn(&[u8]) + Send + Sync>;
|
|
24
|
+
type HandlerMap = Mutex<HashMap<String, Vec<SharedHandler>>>;
|
|
24
25
|
|
|
25
|
-
/// TypedWebSocket wraps a tokio-tungstenite connection with
|
|
26
|
-
///
|
|
27
|
-
///
|
|
26
|
+
/// TypedWebSocket wraps a tokio-tungstenite connection with an event fanout
|
|
27
|
+
/// system that mirrors the TS client's .on() escape hatch: "message" handlers
|
|
28
|
+
/// get each payload, "close" handlers the close reason, "error" handlers the
|
|
29
|
+
/// error text.
|
|
28
30
|
pub struct TypedWebSocket {
|
|
29
31
|
conn: WsStream,
|
|
30
|
-
send_buffer: Option<Vec<u8>>,
|
|
31
|
-
once: AtomicBool,
|
|
32
32
|
handlers: HandlerMap,
|
|
33
|
+
closed: AtomicBool,
|
|
33
34
|
}
|
|
34
35
|
|
|
35
36
|
impl TypedWebSocket {
|
|
@@ -37,12 +38,29 @@ impl TypedWebSocket {
|
|
|
37
38
|
pub fn new(conn: WsStream) -> Self {
|
|
38
39
|
TypedWebSocket {
|
|
39
40
|
conn,
|
|
40
|
-
send_buffer: None,
|
|
41
|
-
once: AtomicBool::new(false),
|
|
42
41
|
handlers: Mutex::new(HashMap::new()),
|
|
42
|
+
closed: AtomicBool::new(false),
|
|
43
43
|
}
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
+
/// send_text writes a text frame as-is.
|
|
47
|
+
pub async fn send_text(&mut self, text: &str) -> Result<(), Error> {
|
|
48
|
+
use futures_util::SinkExt;
|
|
49
|
+
self.conn
|
|
50
|
+
.send(Message::Text(text.to_string()))
|
|
51
|
+
.await
|
|
52
|
+
.map_err(|e| Error::Other(e.to_string()))
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/// send_binary writes a binary frame as-is.
|
|
56
|
+
pub async fn send_binary(&mut self, data: &[u8]) -> Result<(), Error> {
|
|
57
|
+
use futures_util::SinkExt;
|
|
58
|
+
self.conn
|
|
59
|
+
.send(Message::Binary(data.to_vec()))
|
|
60
|
+
.await
|
|
61
|
+
.map_err(|e| Error::Other(e.to_string()))
|
|
62
|
+
}
|
|
63
|
+
|
|
46
64
|
/// send serialises data to JSON and writes it to the WebSocket connection.
|
|
47
65
|
/// Accepts any serde_json::Value or JSON-serializable payload pre-encoded as Value.
|
|
48
66
|
pub async fn send(&mut self, data: &serde_json::Value) -> Result<(), Error> {
|
|
@@ -64,15 +82,21 @@ impl TypedWebSocket {
|
|
|
64
82
|
.map_err(|e| Error::Other(e.to_string()))
|
|
65
83
|
}
|
|
66
84
|
|
|
67
|
-
/// close sends a WebSocket close frame with the given status code and reason
|
|
85
|
+
/// close sends a WebSocket close frame with the given status code and reason
|
|
86
|
+
/// (truncated to the 123 bytes a close frame can carry).
|
|
68
87
|
pub async fn close(&mut self, code: u16, reason: &str) -> Result<(), Error> {
|
|
69
88
|
use futures_util::SinkExt;
|
|
70
89
|
use tokio_tungstenite::tungstenite::protocol::frame::coding::CloseCode;
|
|
71
90
|
use tokio_tungstenite::tungstenite::protocol::CloseFrame;
|
|
91
|
+
let mut end = reason.len().min(123);
|
|
92
|
+
while !reason.is_char_boundary(end) {
|
|
93
|
+
end -= 1;
|
|
94
|
+
}
|
|
72
95
|
let frame = CloseFrame {
|
|
73
96
|
code: CloseCode::from(code),
|
|
74
|
-
reason: reason.to_string().into(),
|
|
97
|
+
reason: reason[..end].to_string().into(),
|
|
75
98
|
};
|
|
99
|
+
self.fire_close(&reason[..end]);
|
|
76
100
|
self.conn
|
|
77
101
|
.send(Message::Close(Some(frame)))
|
|
78
102
|
.await
|
|
@@ -80,28 +104,19 @@ impl TypedWebSocket {
|
|
|
80
104
|
}
|
|
81
105
|
|
|
82
106
|
/// read reads the next message from the connection.
|
|
83
|
-
/// On the first call, any pre-OPEN buffered send is flushed via AtomicBool compare_exchange.
|
|
84
107
|
pub async fn read(&mut self) -> Result<Vec<u8>, Error> {
|
|
85
|
-
use futures_util::
|
|
86
|
-
|
|
87
|
-
/* flush send_buffer exactly once on first read — mirrors Go sync.Once */
|
|
88
|
-
if self
|
|
89
|
-
.once
|
|
90
|
-
.compare_exchange(false, true, Ordering::AcqRel, Ordering::Relaxed)
|
|
91
|
-
.is_ok()
|
|
92
|
-
{
|
|
93
|
-
if let Some(buf) = self.send_buffer.take() {
|
|
94
|
-
let _ = self
|
|
95
|
-
.conn
|
|
96
|
-
.send(Message::Text(String::from_utf8_lossy(&buf).into_owned()))
|
|
97
|
-
.await;
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
|
|
108
|
+
use futures_util::StreamExt;
|
|
101
109
|
loop {
|
|
102
110
|
match self.conn.next().await {
|
|
103
|
-
None =>
|
|
104
|
-
|
|
111
|
+
None => {
|
|
112
|
+
self.fire_close("");
|
|
113
|
+
return Err(Error::Closed { code: 1006, reason: String::new() });
|
|
114
|
+
}
|
|
115
|
+
Some(Err(e)) => {
|
|
116
|
+
let msg = e.to_string();
|
|
117
|
+
self.fanout("error", msg.as_bytes());
|
|
118
|
+
return Err(Error::Other(msg));
|
|
119
|
+
}
|
|
105
120
|
Some(Ok(msg)) => {
|
|
106
121
|
let data = match msg {
|
|
107
122
|
Message::Text(t) => t.into_bytes(),
|
|
@@ -111,7 +126,8 @@ impl TypedWebSocket {
|
|
|
111
126
|
Some(f) => (u16::from(f.code), f.reason.into_owned()),
|
|
112
127
|
None => (1005, String::new()),
|
|
113
128
|
};
|
|
114
|
-
|
|
129
|
+
self.fire_close(&reason);
|
|
130
|
+
return Err(Error::Closed { code, reason });
|
|
115
131
|
}
|
|
116
132
|
_ => continue,
|
|
117
133
|
};
|
|
@@ -125,19 +141,27 @@ impl TypedWebSocket {
|
|
|
125
141
|
/// on registers an event handler for a named event.
|
|
126
142
|
/// Supported events: "message", "close", "error", "open".
|
|
127
143
|
pub fn on(&mut self, event: &str, handler: WsHandler) {
|
|
128
|
-
let mut handlers = self.handlers.lock().
|
|
144
|
+
let mut handlers = self.handlers.lock().unwrap_or_else(|p| p.into_inner());
|
|
129
145
|
handlers
|
|
130
146
|
.entry(event.to_string())
|
|
131
147
|
.or_default()
|
|
132
|
-
.push(handler);
|
|
148
|
+
.push(std::sync::Arc::from(handler));
|
|
133
149
|
}
|
|
134
150
|
|
|
151
|
+
fn fire_close(&self, reason: &str) {
|
|
152
|
+
if !self.closed.swap(true, Ordering::AcqRel) {
|
|
153
|
+
self.fanout("close", reason.as_bytes());
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/// fanout calls handlers outside the lock, so a panicking handler cannot poison it.
|
|
135
158
|
fn fanout(&self, event: &str, data: &[u8]) {
|
|
136
|
-
let
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
159
|
+
let hs: Vec<SharedHandler> = {
|
|
160
|
+
let handlers = self.handlers.lock().unwrap_or_else(|p| p.into_inner());
|
|
161
|
+
handlers.get(event).cloned().unwrap_or_default()
|
|
162
|
+
};
|
|
163
|
+
for h in hs {
|
|
164
|
+
h(data);
|
|
141
165
|
}
|
|
142
166
|
}
|
|
143
167
|
}
|