openai 7.5.0 → 7.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/CHANGELOG.md +117 -0
- package/README.md +46 -2
- package/auth/index.d.mts +1 -1
- package/auth/index.d.mts.map +1 -1
- package/auth/index.d.ts +1 -1
- package/auth/index.d.ts.map +1 -1
- package/auth/index.js.map +1 -1
- package/auth/index.mjs.map +1 -1
- package/auth/subject-token-providers.d.mts.map +1 -1
- package/auth/subject-token-providers.d.ts.map +1 -1
- package/auth/subject-token-providers.js +176 -4
- package/auth/subject-token-providers.js.map +1 -1
- package/auth/subject-token-providers.mjs +176 -4
- package/auth/subject-token-providers.mjs.map +1 -1
- package/auth/types.d.mts +17 -0
- package/auth/types.d.mts.map +1 -1
- package/auth/types.d.ts +17 -0
- package/auth/types.d.ts.map +1 -1
- package/auth/workload-identity-auth.d.mts.map +1 -1
- package/auth/workload-identity-auth.d.ts.map +1 -1
- package/auth/workload-identity-auth.js +80 -7
- package/auth/workload-identity-auth.js.map +1 -1
- package/auth/workload-identity-auth.mjs +80 -7
- package/auth/workload-identity-auth.mjs.map +1 -1
- package/auth/x509-transport.d.mts +5 -0
- package/auth/x509-transport.d.mts.map +1 -0
- package/auth/x509-transport.d.ts +5 -0
- package/auth/x509-transport.d.ts.map +1 -0
- package/auth/x509-transport.js +39 -0
- package/auth/x509-transport.js.map +1 -0
- package/auth/x509-transport.mjs +36 -0
- package/auth/x509-transport.mjs.map +1 -0
- package/azure.d.mts +11 -2
- package/azure.d.mts.map +1 -1
- package/azure.d.ts +11 -2
- package/azure.d.ts.map +1 -1
- package/azure.js +7 -1
- package/azure.js.map +1 -1
- package/azure.mjs +7 -1
- package/azure.mjs.map +1 -1
- package/bedrock.d.mts +6 -2
- package/bedrock.d.mts.map +1 -1
- package/bedrock.d.ts +6 -2
- package/bedrock.d.ts.map +1 -1
- package/bedrock.js +34 -4
- package/bedrock.js.map +1 -1
- package/bedrock.mjs +35 -5
- package/bedrock.mjs.map +1 -1
- package/beta/realtime/internal-base.d.mts +2 -0
- package/beta/realtime/internal-base.d.mts.map +1 -1
- package/beta/realtime/internal-base.d.ts +2 -0
- package/beta/realtime/internal-base.d.ts.map +1 -1
- package/beta/realtime/internal-base.js +15 -0
- package/beta/realtime/internal-base.js.map +1 -1
- package/beta/realtime/internal-base.mjs +14 -0
- package/beta/realtime/internal-base.mjs.map +1 -1
- package/beta/realtime/websocket.d.mts +11 -5
- package/beta/realtime/websocket.d.mts.map +1 -1
- package/beta/realtime/websocket.d.ts +11 -5
- package/beta/realtime/websocket.d.ts.map +1 -1
- package/beta/realtime/websocket.js +106 -31
- package/beta/realtime/websocket.js.map +1 -1
- package/beta/realtime/websocket.mjs +107 -32
- package/beta/realtime/websocket.mjs.map +1 -1
- package/beta/realtime/ws.d.mts +0 -2
- package/beta/realtime/ws.d.mts.map +1 -1
- package/beta/realtime/ws.d.ts +0 -2
- package/beta/realtime/ws.d.ts.map +1 -1
- package/beta/realtime/ws.js +24 -5
- package/beta/realtime/ws.js.map +1 -1
- package/beta/realtime/ws.mjs +25 -6
- package/beta/realtime/ws.mjs.map +1 -1
- package/client.d.mts +17 -2
- package/client.d.mts.map +1 -1
- package/client.d.ts +17 -2
- package/client.d.ts.map +1 -1
- package/client.js +422 -70
- package/client.js.map +1 -1
- package/client.mjs +423 -71
- package/client.mjs.map +1 -1
- package/core/EventEmitter.d.mts.map +1 -1
- package/core/EventEmitter.d.ts.map +1 -1
- package/core/EventEmitter.js +67 -9
- package/core/EventEmitter.js.map +1 -1
- package/core/EventEmitter.mjs +68 -10
- package/core/EventEmitter.mjs.map +1 -1
- package/core/streaming.d.mts +1 -0
- package/core/streaming.d.mts.map +1 -1
- package/core/streaming.d.ts +1 -0
- package/core/streaming.d.ts.map +1 -1
- package/core/streaming.js +216 -26
- package/core/streaming.js.map +1 -1
- package/core/streaming.mjs +216 -26
- package/core/streaming.mjs.map +1 -1
- package/helpers/audio.d.mts +5 -5
- package/helpers/audio.d.mts.map +1 -1
- package/helpers/audio.d.ts +5 -5
- package/helpers/audio.d.ts.map +1 -1
- package/helpers/audio.js +93 -22
- package/helpers/audio.js.map +1 -1
- package/helpers/audio.mjs +93 -22
- package/helpers/audio.mjs.map +1 -1
- package/helpers/standard-schema.d.mts.map +1 -1
- package/helpers/standard-schema.d.ts.map +1 -1
- package/helpers/standard-schema.js +34 -14
- package/helpers/standard-schema.js.map +1 -1
- package/helpers/standard-schema.mjs +35 -15
- package/helpers/standard-schema.mjs.map +1 -1
- package/helpers/zod-v3-strict-schema.d.mts +7 -0
- package/helpers/zod-v3-strict-schema.d.mts.map +1 -0
- package/helpers/zod-v3-strict-schema.d.ts +7 -0
- package/helpers/zod-v3-strict-schema.d.ts.map +1 -0
- package/helpers/zod-v3-strict-schema.js +403 -0
- package/helpers/zod-v3-strict-schema.js.map +1 -0
- package/helpers/zod-v3-strict-schema.mjs +399 -0
- package/helpers/zod-v3-strict-schema.mjs.map +1 -0
- package/helpers/zod.d.mts.map +1 -1
- package/helpers/zod.d.ts.map +1 -1
- package/helpers/zod.js +11 -3
- package/helpers/zod.js.map +1 -1
- package/helpers/zod.mjs +12 -4
- package/helpers/zod.mjs.map +1 -1
- package/index.d.mts +1 -1
- package/index.d.mts.map +1 -1
- package/index.d.ts +1 -1
- package/index.d.ts.map +1 -1
- package/index.js.map +1 -1
- package/index.mjs.map +1 -1
- package/internal/assistant-stream-delta.d.mts.map +1 -1
- package/internal/assistant-stream-delta.d.ts.map +1 -1
- package/internal/assistant-stream-delta.js +28 -8
- package/internal/assistant-stream-delta.js.map +1 -1
- package/internal/assistant-stream-delta.mjs +28 -8
- package/internal/assistant-stream-delta.mjs.map +1 -1
- package/internal/auth/x509-token-exchange.d.mts +16 -0
- package/internal/auth/x509-token-exchange.d.mts.map +1 -0
- package/internal/auth/x509-token-exchange.d.ts +16 -0
- package/internal/auth/x509-token-exchange.d.ts.map +1 -0
- package/internal/auth/x509-token-exchange.js +246 -0
- package/internal/auth/x509-token-exchange.js.map +1 -0
- package/internal/auth/x509-token-exchange.mjs +243 -0
- package/internal/auth/x509-token-exchange.mjs.map +1 -0
- package/internal/auth/x509-transport-capability.d.mts +37 -0
- package/internal/auth/x509-transport-capability.d.mts.map +1 -0
- package/internal/auth/x509-transport-capability.d.ts +37 -0
- package/internal/auth/x509-transport-capability.d.ts.map +1 -0
- package/internal/auth/x509-transport-capability.js +169 -0
- package/internal/auth/x509-transport-capability.js.map +1 -0
- package/internal/auth/x509-transport-capability.mjs +164 -0
- package/internal/auth/x509-transport-capability.mjs.map +1 -0
- package/internal/auth/x509-transport-registry.d.mts +63 -0
- package/internal/auth/x509-transport-registry.d.mts.map +1 -0
- package/internal/auth/x509-transport-registry.d.ts +63 -0
- package/internal/auth/x509-transport-registry.d.ts.map +1 -0
- package/internal/auth/x509-transport-registry.js +53 -0
- package/internal/auth/x509-transport-registry.js.map +1 -0
- package/internal/auth/x509-transport-registry.mjs +48 -0
- package/internal/auth/x509-transport-registry.mjs.map +1 -0
- package/internal/auth/x509-transport-state-browser.d.mts +21 -0
- package/internal/auth/x509-transport-state-browser.d.mts.map +1 -0
- package/internal/auth/x509-transport-state-browser.d.ts +21 -0
- package/internal/auth/x509-transport-state-browser.d.ts.map +1 -0
- package/internal/auth/x509-transport-state-browser.js +30 -0
- package/internal/auth/x509-transport-state-browser.js.map +1 -0
- package/internal/auth/x509-transport-state-browser.mjs +27 -0
- package/internal/auth/x509-transport-state-browser.mjs.map +1 -0
- package/internal/auth/x509-transport-state.cjs +30 -0
- package/internal/auth/x509-transport-state.cjs.map +1 -0
- package/internal/auth/x509-transport-state.d.cts +21 -0
- package/internal/auth/x509-transport-state.d.cts.map +1 -0
- package/internal/auth/x509-workload-identity-auth.d.mts +128 -0
- package/internal/auth/x509-workload-identity-auth.d.mts.map +1 -0
- package/internal/auth/x509-workload-identity-auth.d.ts +128 -0
- package/internal/auth/x509-workload-identity-auth.d.ts.map +1 -0
- package/internal/auth/x509-workload-identity-auth.js +767 -0
- package/internal/auth/x509-workload-identity-auth.js.map +1 -0
- package/internal/auth/x509-workload-identity-auth.mjs +757 -0
- package/internal/auth/x509-workload-identity-auth.mjs.map +1 -0
- package/internal/bedrock.d.mts +2 -0
- package/internal/bedrock.d.mts.map +1 -1
- package/internal/bedrock.d.ts +2 -0
- package/internal/bedrock.d.ts.map +1 -1
- package/internal/bedrock.js +169 -5
- package/internal/bedrock.js.map +1 -1
- package/internal/bedrock.mjs +168 -5
- package/internal/bedrock.mjs.map +1 -1
- package/internal/data-residency.d.mts +12 -0
- package/internal/data-residency.d.mts.map +1 -0
- package/internal/data-residency.d.ts +12 -0
- package/internal/data-residency.d.ts.map +1 -0
- package/internal/data-residency.js +34 -0
- package/internal/data-residency.js.map +1 -0
- package/internal/data-residency.mjs +30 -0
- package/internal/data-residency.mjs.map +1 -0
- package/internal/multipart-encoding.d.mts +8 -0
- package/internal/multipart-encoding.d.mts.map +1 -0
- package/internal/multipart-encoding.d.ts +8 -0
- package/internal/multipart-encoding.d.ts.map +1 -0
- package/internal/multipart-encoding.js +51 -0
- package/internal/multipart-encoding.js.map +1 -0
- package/internal/multipart-encoding.mjs +48 -0
- package/internal/multipart-encoding.mjs.map +1 -0
- package/internal/qs/utils.d.mts.map +1 -1
- package/internal/qs/utils.d.ts.map +1 -1
- package/internal/qs/utils.js +307 -10
- package/internal/qs/utils.js.map +1 -1
- package/internal/qs/utils.mjs +307 -10
- package/internal/qs/utils.mjs.map +1 -1
- package/internal/request-options.d.mts +7 -0
- package/internal/request-options.d.mts.map +1 -1
- package/internal/request-options.d.ts +7 -0
- package/internal/request-options.d.ts.map +1 -1
- package/internal/request-options.js +43 -1
- package/internal/request-options.js.map +1 -1
- package/internal/request-options.mjs +42 -1
- package/internal/request-options.mjs.map +1 -1
- package/internal/responses/canonical-output-text.js +3 -3
- package/internal/responses/canonical-output-text.js.map +1 -1
- package/internal/responses/canonical-output-text.mjs +3 -3
- package/internal/responses/canonical-output-text.mjs.map +1 -1
- package/internal/responses/response-accumulator.d.mts +1 -1
- package/internal/responses/response-accumulator.d.mts.map +1 -1
- package/internal/responses/response-accumulator.d.ts +1 -1
- package/internal/responses/response-accumulator.d.ts.map +1 -1
- package/internal/responses/response-accumulator.js +331 -25
- package/internal/responses/response-accumulator.js.map +1 -1
- package/internal/responses/response-accumulator.mjs +331 -25
- package/internal/responses/response-accumulator.mjs.map +1 -1
- package/internal/tslib.js +6 -0
- package/internal/tslib.mjs +6 -1
- package/internal/uploads.d.mts +10 -6
- package/internal/uploads.d.mts.map +1 -1
- package/internal/uploads.d.ts +10 -6
- package/internal/uploads.d.ts.map +1 -1
- package/internal/uploads.js +65 -24
- package/internal/uploads.js.map +1 -1
- package/internal/uploads.mjs +65 -24
- package/internal/uploads.mjs.map +1 -1
- package/internal/utils/env.d.mts.map +1 -1
- package/internal/utils/env.d.ts.map +1 -1
- package/internal/utils/env.js +9 -4
- package/internal/utils/env.js.map +1 -1
- package/internal/utils/env.mjs +9 -4
- package/internal/utils/env.mjs.map +1 -1
- package/internal/ws.d.mts.map +1 -1
- package/internal/ws.d.ts.map +1 -1
- package/internal/ws.js +23 -1
- package/internal/ws.js.map +1 -1
- package/internal/ws.mjs +23 -1
- package/internal/ws.mjs.map +1 -1
- package/lib/AbstractChatCompletionRunner.d.mts.map +1 -1
- package/lib/AbstractChatCompletionRunner.d.ts.map +1 -1
- package/lib/AbstractChatCompletionRunner.js +32 -7
- package/lib/AbstractChatCompletionRunner.js.map +1 -1
- package/lib/AbstractChatCompletionRunner.mjs +34 -9
- package/lib/AbstractChatCompletionRunner.mjs.map +1 -1
- package/lib/AssistantStream.d.mts.map +1 -1
- package/lib/AssistantStream.d.ts.map +1 -1
- package/lib/AssistantStream.js +211 -23
- package/lib/AssistantStream.js.map +1 -1
- package/lib/AssistantStream.mjs +211 -23
- package/lib/AssistantStream.mjs.map +1 -1
- package/lib/ChatCompletionStream.d.mts +1 -1
- package/lib/ChatCompletionStream.d.mts.map +1 -1
- package/lib/ChatCompletionStream.d.ts +1 -1
- package/lib/ChatCompletionStream.d.ts.map +1 -1
- package/lib/ChatCompletionStream.js +1118 -67
- package/lib/ChatCompletionStream.js.map +1 -1
- package/lib/ChatCompletionStream.mjs +1119 -68
- package/lib/ChatCompletionStream.mjs.map +1 -1
- package/lib/EventEmitter.d.mts.map +1 -1
- package/lib/EventEmitter.d.ts.map +1 -1
- package/lib/EventEmitter.js +67 -9
- package/lib/EventEmitter.js.map +1 -1
- package/lib/EventEmitter.mjs +68 -10
- package/lib/EventEmitter.mjs.map +1 -1
- package/lib/EventStream.d.mts +4 -0
- package/lib/EventStream.d.mts.map +1 -1
- package/lib/EventStream.d.ts +4 -0
- package/lib/EventStream.d.ts.map +1 -1
- package/lib/EventStream.js +1096 -11
- package/lib/EventStream.js.map +1 -1
- package/lib/EventStream.mjs +1097 -12
- package/lib/EventStream.mjs.map +1 -1
- package/lib/ResponsesParser.d.mts.map +1 -1
- package/lib/ResponsesParser.d.ts.map +1 -1
- package/lib/ResponsesParser.js +1 -1
- package/lib/ResponsesParser.js.map +1 -1
- package/lib/ResponsesParser.mjs +1 -1
- package/lib/ResponsesParser.mjs.map +1 -1
- package/lib/Util.d.mts +2 -0
- package/lib/Util.d.mts.map +1 -1
- package/lib/Util.d.ts +2 -0
- package/lib/Util.d.ts.map +1 -1
- package/lib/Util.js +7 -4
- package/lib/Util.js.map +1 -1
- package/lib/Util.mjs +7 -4
- package/lib/Util.mjs.map +1 -1
- package/lib/assistant-run-polling.d.mts +12 -0
- package/lib/assistant-run-polling.d.mts.map +1 -0
- package/lib/assistant-run-polling.d.ts +12 -0
- package/lib/assistant-run-polling.d.ts.map +1 -0
- package/lib/assistant-run-polling.js +17 -0
- package/lib/assistant-run-polling.js.map +1 -0
- package/lib/assistant-run-polling.mjs +14 -0
- package/lib/assistant-run-polling.mjs.map +1 -0
- package/lib/embeddings.d.mts +18 -0
- package/lib/embeddings.d.mts.map +1 -0
- package/lib/embeddings.d.ts +18 -0
- package/lib/embeddings.d.ts.map +1 -0
- package/lib/embeddings.js +50 -0
- package/lib/embeddings.js.map +1 -0
- package/lib/embeddings.mjs +47 -0
- package/lib/embeddings.mjs.map +1 -0
- package/lib/file-processing.d.mts +10 -0
- package/lib/file-processing.d.mts.map +1 -0
- package/lib/file-processing.d.ts +10 -0
- package/lib/file-processing.d.ts.map +1 -0
- package/lib/file-processing.js +30 -0
- package/lib/file-processing.js.map +1 -0
- package/lib/file-processing.mjs +27 -0
- package/lib/file-processing.mjs.map +1 -0
- package/lib/parser.d.mts.map +1 -1
- package/lib/parser.d.ts.map +1 -1
- package/lib/parser.js +16 -4
- package/lib/parser.js.map +1 -1
- package/lib/parser.mjs +16 -4
- package/lib/parser.mjs.map +1 -1
- package/lib/polling.d.mts +20 -0
- package/lib/polling.d.mts.map +1 -0
- package/lib/polling.d.ts +20 -0
- package/lib/polling.d.ts.map +1 -0
- package/lib/polling.js +130 -0
- package/lib/polling.js.map +1 -0
- package/lib/polling.mjs +127 -0
- package/lib/polling.mjs.map +1 -0
- package/lib/responses/ResponseStream.d.mts.map +1 -1
- package/lib/responses/ResponseStream.d.ts.map +1 -1
- package/lib/responses/ResponseStream.js +21 -11
- package/lib/responses/ResponseStream.js.map +1 -1
- package/lib/responses/ResponseStream.mjs +21 -11
- package/lib/responses/ResponseStream.mjs.map +1 -1
- package/lib/vector-store-polling.d.mts +22 -0
- package/lib/vector-store-polling.d.mts.map +1 -0
- package/lib/vector-store-polling.d.ts +22 -0
- package/lib/vector-store-polling.d.ts.map +1 -0
- package/lib/vector-store-polling.js +24 -0
- package/lib/vector-store-polling.js.map +1 -0
- package/lib/vector-store-polling.mjs +20 -0
- package/lib/vector-store-polling.mjs.map +1 -0
- package/lib/vector-store-upload.d.mts +17 -0
- package/lib/vector-store-upload.d.mts.map +1 -0
- package/lib/vector-store-upload.d.ts +17 -0
- package/lib/vector-store-upload.d.ts.map +1 -0
- package/lib/vector-store-upload.js +37 -0
- package/lib/vector-store-upload.js.map +1 -0
- package/lib/vector-store-upload.mjs +34 -0
- package/lib/vector-store-upload.mjs.map +1 -0
- package/lib/webhook-signature.d.mts +15 -0
- package/lib/webhook-signature.d.mts.map +1 -0
- package/lib/webhook-signature.d.ts +15 -0
- package/lib/webhook-signature.d.ts.map +1 -0
- package/lib/webhook-signature.js +125 -0
- package/lib/webhook-signature.js.map +1 -0
- package/lib/webhook-signature.mjs +121 -0
- package/lib/webhook-signature.mjs.map +1 -0
- package/package.json +14 -1
- package/realtime/internal-base.d.mts +2 -0
- package/realtime/internal-base.d.mts.map +1 -1
- package/realtime/internal-base.d.ts +2 -0
- package/realtime/internal-base.d.ts.map +1 -1
- package/realtime/internal-base.js +15 -0
- package/realtime/internal-base.js.map +1 -1
- package/realtime/internal-base.mjs +14 -0
- package/realtime/internal-base.mjs.map +1 -1
- package/realtime/websocket.d.mts +3 -2
- package/realtime/websocket.d.mts.map +1 -1
- package/realtime/websocket.d.ts +3 -2
- package/realtime/websocket.d.ts.map +1 -1
- package/realtime/websocket.js +90 -26
- package/realtime/websocket.js.map +1 -1
- package/realtime/websocket.mjs +91 -27
- package/realtime/websocket.mjs.map +1 -1
- package/realtime/ws.d.mts.map +1 -1
- package/realtime/ws.d.ts.map +1 -1
- package/realtime/ws.js +9 -1
- package/realtime/ws.js.map +1 -1
- package/realtime/ws.mjs +10 -2
- package/realtime/ws.mjs.map +1 -1
- package/resources/admin/organization/index.d.mts +2 -2
- package/resources/admin/organization/index.d.mts.map +1 -1
- package/resources/admin/organization/index.d.ts +2 -2
- package/resources/admin/organization/index.d.ts.map +1 -1
- package/resources/admin/organization/index.js.map +1 -1
- package/resources/admin/organization/index.mjs.map +1 -1
- package/resources/admin/organization/organization.d.mts +4 -4
- package/resources/admin/organization/organization.d.mts.map +1 -1
- package/resources/admin/organization/organization.d.ts +4 -4
- package/resources/admin/organization/organization.d.ts.map +1 -1
- package/resources/admin/organization/organization.js.map +1 -1
- package/resources/admin/organization/organization.mjs.map +1 -1
- package/resources/admin/organization/projects/index.d.mts +1 -1
- package/resources/admin/organization/projects/index.d.mts.map +1 -1
- package/resources/admin/organization/projects/index.d.ts +1 -1
- package/resources/admin/organization/projects/index.d.ts.map +1 -1
- package/resources/admin/organization/projects/index.js.map +1 -1
- package/resources/admin/organization/projects/index.mjs.map +1 -1
- package/resources/admin/organization/projects/projects.d.mts +22 -5
- package/resources/admin/organization/projects/projects.d.mts.map +1 -1
- package/resources/admin/organization/projects/projects.d.ts +22 -5
- package/resources/admin/organization/projects/projects.d.ts.map +1 -1
- package/resources/admin/organization/projects/projects.js.map +1 -1
- package/resources/admin/organization/projects/projects.mjs.map +1 -1
- package/resources/admin/organization/usage.d.mts +62 -1
- package/resources/admin/organization/usage.d.mts.map +1 -1
- package/resources/admin/organization/usage.d.ts +62 -1
- package/resources/admin/organization/usage.d.ts.map +1 -1
- package/resources/admin/organization/usage.js.map +1 -1
- package/resources/admin/organization/usage.mjs.map +1 -1
- package/resources/beta/responses/internal-base.d.mts.map +1 -1
- package/resources/beta/responses/internal-base.d.ts.map +1 -1
- package/resources/beta/responses/internal-base.js +2 -0
- package/resources/beta/responses/internal-base.js.map +1 -1
- package/resources/beta/responses/internal-base.mjs +2 -0
- package/resources/beta/responses/internal-base.mjs.map +1 -1
- package/resources/beta/responses/responses.d.mts +17 -20
- package/resources/beta/responses/responses.d.mts.map +1 -1
- package/resources/beta/responses/responses.d.ts +17 -20
- package/resources/beta/responses/responses.d.ts.map +1 -1
- package/resources/beta/responses/responses.js.map +1 -1
- package/resources/beta/responses/responses.mjs.map +1 -1
- package/resources/beta/threads/runs/index.d.mts +1 -1
- package/resources/beta/threads/runs/index.d.mts.map +1 -1
- package/resources/beta/threads/runs/index.d.ts +1 -1
- package/resources/beta/threads/runs/index.d.ts.map +1 -1
- package/resources/beta/threads/runs/runs.d.mts.map +1 -1
- package/resources/beta/threads/runs/runs.d.ts.map +1 -1
- package/resources/beta/threads/runs/runs.js +2 -43
- package/resources/beta/threads/runs/runs.js.map +1 -1
- package/resources/beta/threads/runs/runs.mjs +2 -43
- package/resources/beta/threads/runs/runs.mjs.map +1 -1
- package/resources/chat/completions/completions.d.mts +6 -0
- package/resources/chat/completions/completions.d.mts.map +1 -1
- package/resources/chat/completions/completions.d.ts +6 -0
- package/resources/chat/completions/completions.d.ts.map +1 -1
- package/resources/chat/completions/completions.js.map +1 -1
- package/resources/chat/completions/completions.mjs.map +1 -1
- package/resources/embeddings.d.mts.map +1 -1
- package/resources/embeddings.d.ts.map +1 -1
- package/resources/embeddings.js +2 -36
- package/resources/embeddings.js.map +1 -1
- package/resources/embeddings.mjs +2 -36
- package/resources/embeddings.mjs.map +1 -1
- package/resources/files.d.mts.map +1 -1
- package/resources/files.d.ts.map +1 -1
- package/resources/files.js +2 -15
- package/resources/files.js.map +1 -1
- package/resources/files.mjs +2 -15
- package/resources/files.mjs.map +1 -1
- package/resources/images.d.mts +12 -22
- package/resources/images.d.mts.map +1 -1
- package/resources/images.d.ts +12 -22
- package/resources/images.d.ts.map +1 -1
- package/resources/realtime/calls.d.mts +23 -1
- package/resources/realtime/calls.d.mts.map +1 -1
- package/resources/realtime/calls.d.ts +23 -1
- package/resources/realtime/calls.d.ts.map +1 -1
- package/resources/realtime/calls.js +24 -0
- package/resources/realtime/calls.js.map +1 -1
- package/resources/realtime/calls.mjs +24 -0
- package/resources/realtime/calls.mjs.map +1 -1
- package/resources/realtime/index.d.mts +1 -1
- package/resources/realtime/index.d.mts.map +1 -1
- package/resources/realtime/index.d.ts +1 -1
- package/resources/realtime/index.d.ts.map +1 -1
- package/resources/realtime/index.js.map +1 -1
- package/resources/realtime/index.mjs +1 -1
- package/resources/realtime/index.mjs.map +1 -1
- package/resources/realtime/realtime.d.mts +5 -4
- package/resources/realtime/realtime.d.mts.map +1 -1
- package/resources/realtime/realtime.d.ts +5 -4
- package/resources/realtime/realtime.d.ts.map +1 -1
- package/resources/realtime/realtime.js.map +1 -1
- package/resources/realtime/realtime.mjs.map +1 -1
- package/resources/responses/internal-base.d.mts.map +1 -1
- package/resources/responses/internal-base.d.ts.map +1 -1
- package/resources/responses/internal-base.js +2 -0
- package/resources/responses/internal-base.js.map +1 -1
- package/resources/responses/internal-base.mjs +2 -0
- package/resources/responses/internal-base.mjs.map +1 -1
- package/resources/responses/responses.d.mts +17 -20
- package/resources/responses/responses.d.mts.map +1 -1
- package/resources/responses/responses.d.ts +17 -20
- package/resources/responses/responses.d.ts.map +1 -1
- package/resources/responses/responses.js.map +1 -1
- package/resources/responses/responses.mjs.map +1 -1
- package/resources/vector-stores/file-batches.d.mts.map +1 -1
- package/resources/vector-stores/file-batches.d.ts.map +1 -1
- package/resources/vector-stores/file-batches.js +4 -61
- package/resources/vector-stores/file-batches.js.map +1 -1
- package/resources/vector-stores/file-batches.mjs +4 -61
- package/resources/vector-stores/file-batches.mjs.map +1 -1
- package/resources/vector-stores/files.d.mts +1 -1
- package/resources/vector-stores/files.d.mts.map +1 -1
- package/resources/vector-stores/files.d.ts +1 -1
- package/resources/vector-stores/files.d.ts.map +1 -1
- package/resources/vector-stores/files.js +2 -35
- package/resources/vector-stores/files.js.map +1 -1
- package/resources/vector-stores/files.mjs +2 -35
- package/resources/vector-stores/files.mjs.map +1 -1
- package/resources/webhooks/webhooks.d.mts.map +1 -1
- package/resources/webhooks/webhooks.d.ts.map +1 -1
- package/resources/webhooks/webhooks.js +5 -43
- package/resources/webhooks/webhooks.js.map +1 -1
- package/resources/webhooks/webhooks.mjs +5 -43
- package/resources/webhooks/webhooks.mjs.map +1 -1
- package/src/auth/index.ts +6 -1
- package/src/auth/subject-token-providers.ts +196 -4
- package/src/auth/types.ts +24 -0
- package/src/auth/workload-identity-auth.ts +104 -7
- package/src/auth/x509-transport.ts +49 -0
- package/src/azure.ts +22 -1
- package/src/bedrock.ts +49 -5
- package/src/beta/realtime/internal-base.ts +15 -0
- package/src/beta/realtime/websocket.ts +148 -40
- package/src/beta/realtime/ws.ts +31 -13
- package/src/client.ts +536 -92
- package/src/core/EventEmitter.ts +91 -7
- package/src/core/streaming.ts +226 -30
- package/src/helpers/audio.ts +93 -22
- package/src/helpers/standard-schema.ts +50 -16
- package/src/helpers/zod-v3-strict-schema.ts +514 -0
- package/src/helpers/zod.ts +17 -4
- package/src/index.ts +1 -1
- package/src/internal/assistant-stream-delta.ts +33 -10
- package/src/internal/auth/x509-token-exchange.ts +310 -0
- package/src/internal/auth/x509-transport-capability.ts +219 -0
- package/src/internal/auth/x509-transport-registry.ts +118 -0
- package/src/internal/auth/x509-transport-state-browser.ts +36 -0
- package/src/internal/auth/x509-transport-state.cts +36 -0
- package/src/internal/auth/x509-workload-identity-auth.ts +958 -0
- package/src/internal/bedrock.ts +182 -5
- package/src/internal/data-residency.ts +44 -0
- package/src/internal/multipart-encoding.ts +53 -0
- package/src/internal/qs/utils.ts +375 -13
- package/src/internal/request-options.ts +52 -1
- package/src/internal/responses/canonical-output-text.ts +3 -3
- package/src/internal/responses/response-accumulator.ts +411 -24
- package/src/internal/uploads.ts +81 -26
- package/src/internal/utils/env.ts +9 -5
- package/src/internal/ws.ts +24 -3
- package/src/lib/AbstractChatCompletionRunner.ts +33 -6
- package/src/lib/AssistantStream.ts +262 -22
- package/src/lib/ChatCompletionStream.ts +1467 -103
- package/src/lib/EventEmitter.ts +91 -7
- package/src/lib/EventStream.ts +1483 -10
- package/src/lib/ResponsesParser.ts +4 -1
- package/src/lib/Util.ts +7 -5
- package/src/lib/assistant-run-polling.ts +27 -0
- package/src/lib/embeddings.ts +65 -0
- package/src/lib/file-processing.ts +36 -0
- package/src/lib/parser.ts +19 -4
- package/src/lib/polling.ts +144 -0
- package/src/lib/responses/ResponseStream.ts +22 -10
- package/src/lib/vector-store-polling.ts +46 -0
- package/src/lib/vector-store-upload.ts +53 -0
- package/src/lib/webhook-signature.ts +164 -0
- package/src/realtime/internal-base.ts +15 -0
- package/src/realtime/websocket.ts +130 -27
- package/src/realtime/ws.ts +15 -2
- package/src/resources/admin/organization/index.ts +2 -0
- package/src/resources/admin/organization/organization.ts +4 -0
- package/src/resources/admin/organization/projects/index.ts +1 -0
- package/src/resources/admin/organization/projects/projects.ts +37 -4
- package/src/resources/admin/organization/usage.ts +83 -0
- package/src/resources/beta/responses/internal-base.ts +2 -0
- package/src/resources/beta/responses/responses.ts +19 -22
- package/src/resources/beta/threads/runs/index.ts +1 -1
- package/src/resources/beta/threads/runs/runs.ts +2 -45
- package/src/resources/chat/completions/completions.ts +7 -0
- package/src/resources/embeddings.ts +2 -42
- package/src/resources/files.ts +2 -19
- package/src/resources/images.ts +12 -22
- package/src/resources/realtime/api.md +1 -0
- package/src/resources/realtime/calls.ts +46 -0
- package/src/resources/realtime/index.ts +7 -1
- package/src/resources/realtime/realtime.ts +5 -3
- package/src/resources/responses/internal-base.ts +2 -0
- package/src/resources/responses/responses.ts +19 -22
- package/src/resources/vector-stores/file-batches.ts +8 -77
- package/src/resources/vector-stores/files.ts +3 -43
- package/src/resources/webhooks/webhooks.ts +5 -61
- package/src/version.ts +1 -1
- package/version.d.mts +1 -1
- package/version.d.ts +1 -1
- package/version.js +1 -1
- package/version.mjs +1 -1
package/src/lib/EventStream.ts
CHANGED
|
@@ -1,4 +1,454 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
APIConnectionError,
|
|
3
|
+
APIConnectionTimeoutError,
|
|
4
|
+
APIError,
|
|
5
|
+
APIUserAbortError,
|
|
6
|
+
AuthenticationError,
|
|
7
|
+
BadRequestError,
|
|
8
|
+
ConflictError,
|
|
9
|
+
ContentFilterFinishReasonError,
|
|
10
|
+
InternalServerError,
|
|
11
|
+
InvalidWebhookSignatureError,
|
|
12
|
+
LengthFinishReasonError,
|
|
13
|
+
NotFoundError,
|
|
14
|
+
OAuthError,
|
|
15
|
+
OpenAIError,
|
|
16
|
+
PermissionDeniedError,
|
|
17
|
+
RateLimitError,
|
|
18
|
+
SubjectTokenProviderError,
|
|
19
|
+
UnprocessableEntityError,
|
|
20
|
+
} from '../error';
|
|
21
|
+
|
|
22
|
+
const MAX_BUFFERED_ITERATOR_EVENTS = 4096;
|
|
23
|
+
const MAX_BUFFERED_ITERATOR_BYTES = 8 * 1024 * 1024;
|
|
24
|
+
// Typed-array own-key enumeration materializes every dense index before custom keys.
|
|
25
|
+
const MAX_INSPECTABLE_TYPED_ARRAY_ELEMENTS = 4096;
|
|
26
|
+
// Structured JSON may nest 128 levels before stream-event wrappers are added.
|
|
27
|
+
const MAX_BUFFERED_EVENT_DEPTH = 256;
|
|
28
|
+
const bufferedJSONStringify = JSON.stringify;
|
|
29
|
+
const bufferedJSONParse = JSON.parse;
|
|
30
|
+
const sdkOwnedBufferedEventArguments = new WeakSet<object>();
|
|
31
|
+
|
|
32
|
+
const typedArrayBufferGetter = Object.getOwnPropertyDescriptor(
|
|
33
|
+
Object.getPrototypeOf(Uint8Array.prototype) as object,
|
|
34
|
+
'buffer',
|
|
35
|
+
)?.get;
|
|
36
|
+
const typedArrayLengthGetter = Object.getOwnPropertyDescriptor(
|
|
37
|
+
Object.getPrototypeOf(Uint8Array.prototype) as object,
|
|
38
|
+
'length',
|
|
39
|
+
)?.get;
|
|
40
|
+
const dataViewBufferGetter = Object.getOwnPropertyDescriptor(DataView.prototype, 'buffer')?.get;
|
|
41
|
+
const symbolDescriptionGetter = Object.getOwnPropertyDescriptor(Symbol.prototype, 'description')?.get;
|
|
42
|
+
const dateTimestampGetter = Date.prototype.getTime;
|
|
43
|
+
const arrayBufferByteLengthGetter = Object.getOwnPropertyDescriptor(ArrayBuffer.prototype, 'byteLength')?.get;
|
|
44
|
+
const sharedArrayBufferByteLengthGetter =
|
|
45
|
+
typeof SharedArrayBuffer === 'function'
|
|
46
|
+
? Object.getOwnPropertyDescriptor(SharedArrayBuffer.prototype, 'byteLength')?.get
|
|
47
|
+
: undefined;
|
|
48
|
+
// V8 uses the same trusted lazy-stack accessor pair for native Error instances.
|
|
49
|
+
const errorStackDescriptor = Object.getOwnPropertyDescriptor(new Error('native stack descriptor'), 'stack');
|
|
50
|
+
const functionToString = Function.prototype.toString;
|
|
51
|
+
const objectToString = Object.prototype.toString;
|
|
52
|
+
const errorBrandDescriptor = Object.getOwnPropertyDescriptor(Error, 'isError');
|
|
53
|
+
const nativeErrorBrand =
|
|
54
|
+
errorBrandDescriptor && 'value' in errorBrandDescriptor && typeof errorBrandDescriptor.value === 'function'
|
|
55
|
+
? (errorBrandDescriptor.value as (value: unknown) => boolean)
|
|
56
|
+
: undefined;
|
|
57
|
+
const nativeErrorConstructorSource = functionToString.call(Error);
|
|
58
|
+
const nativeDateConstructorSource = functionToString.call(Date);
|
|
59
|
+
const nativeFunctionConstructorSource = functionToString.call(Function);
|
|
60
|
+
const trustedIntrinsicPrototypes = new Set<object>([
|
|
61
|
+
APIConnectionError.prototype,
|
|
62
|
+
APIConnectionTimeoutError.prototype,
|
|
63
|
+
APIError.prototype,
|
|
64
|
+
OpenAIError.prototype,
|
|
65
|
+
APIUserAbortError.prototype,
|
|
66
|
+
AuthenticationError.prototype,
|
|
67
|
+
BadRequestError.prototype,
|
|
68
|
+
ConflictError.prototype,
|
|
69
|
+
ContentFilterFinishReasonError.prototype,
|
|
70
|
+
InternalServerError.prototype,
|
|
71
|
+
InvalidWebhookSignatureError.prototype,
|
|
72
|
+
LengthFinishReasonError.prototype,
|
|
73
|
+
NotFoundError.prototype,
|
|
74
|
+
OAuthError.prototype,
|
|
75
|
+
PermissionDeniedError.prototype,
|
|
76
|
+
RateLimitError.prototype,
|
|
77
|
+
SubjectTokenProviderError.prototype,
|
|
78
|
+
UnprocessableEntityError.prototype,
|
|
79
|
+
]);
|
|
80
|
+
const trustedNativeConstructorSources = new Set<string>();
|
|
81
|
+
const canonicalIntrinsicDescriptors = new Map<string, ReadonlyMap<PropertyKey, PropertyDescriptor>>();
|
|
82
|
+
const foreignErrorStackDescriptors = new WeakMap<object, PropertyDescriptor>();
|
|
83
|
+
|
|
84
|
+
type NativeErrorConstructor = (...args: never[]) => unknown;
|
|
85
|
+
|
|
86
|
+
function captureNativeProxyDetector(): ((value: object) => boolean) | undefined {
|
|
87
|
+
if (typeof process === 'undefined') {
|
|
88
|
+
return undefined;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
try {
|
|
92
|
+
const loader = Object.getOwnPropertyDescriptor(process, 'getBuiltinModule');
|
|
93
|
+
if (!loader || !('value' in loader) || typeof loader.value !== 'function') {
|
|
94
|
+
return undefined;
|
|
95
|
+
}
|
|
96
|
+
const util: unknown = Reflect.apply(loader.value, process, ['node:util']);
|
|
97
|
+
if (typeof util !== 'object' || util === null) {
|
|
98
|
+
return undefined;
|
|
99
|
+
}
|
|
100
|
+
const types = Object.getOwnPropertyDescriptor(util, 'types');
|
|
101
|
+
if (!types || !('value' in types) || typeof types.value !== 'object' || types.value === null) {
|
|
102
|
+
return undefined;
|
|
103
|
+
}
|
|
104
|
+
const detector = Object.getOwnPropertyDescriptor(types.value, 'isProxy');
|
|
105
|
+
if (!detector || !('value' in detector) || typeof detector.value !== 'function') {
|
|
106
|
+
return undefined;
|
|
107
|
+
}
|
|
108
|
+
return detector.value as (value: object) => boolean;
|
|
109
|
+
} catch {
|
|
110
|
+
return undefined;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// Transparent proxies have no portable ECMAScript brand. Newer Node runtimes
|
|
115
|
+
// expose one without adding a Node-only import to browser-compatible bundles.
|
|
116
|
+
const nativeProxyDetector = captureNativeProxyDetector();
|
|
117
|
+
|
|
118
|
+
function rememberTrustedIntrinsic(constructor: unknown): void {
|
|
119
|
+
if (typeof constructor !== 'function') {
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const prototypeDescriptor = Object.getOwnPropertyDescriptor(constructor, 'prototype');
|
|
124
|
+
if (
|
|
125
|
+
!prototypeDescriptor ||
|
|
126
|
+
!('value' in prototypeDescriptor) ||
|
|
127
|
+
(typeof prototypeDescriptor.value !== 'object' && typeof prototypeDescriptor.value !== 'function')
|
|
128
|
+
) {
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
trustedIntrinsicPrototypes.add(prototypeDescriptor.value as object);
|
|
133
|
+
const source = functionToString.call(constructor);
|
|
134
|
+
if (
|
|
135
|
+
/^function [A-Za-z_$][\w$]*\(\) \{ \[native code\] \}$/u.test(source) &&
|
|
136
|
+
prototypeDescriptor.configurable === false &&
|
|
137
|
+
prototypeDescriptor.writable === false
|
|
138
|
+
) {
|
|
139
|
+
trustedNativeConstructorSources.add(source);
|
|
140
|
+
const descriptors = new Map<PropertyKey, PropertyDescriptor>();
|
|
141
|
+
for (const key of Reflect.ownKeys(prototypeDescriptor.value)) {
|
|
142
|
+
const descriptor = Object.getOwnPropertyDescriptor(prototypeDescriptor.value, key);
|
|
143
|
+
if (descriptor) {
|
|
144
|
+
descriptors.set(key, descriptor);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
canonicalIntrinsicDescriptors.set(source, descriptors);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
for (const constructor of [
|
|
152
|
+
Object,
|
|
153
|
+
Function,
|
|
154
|
+
Array,
|
|
155
|
+
Date,
|
|
156
|
+
Map,
|
|
157
|
+
Set,
|
|
158
|
+
ArrayBuffer,
|
|
159
|
+
DataView,
|
|
160
|
+
Error,
|
|
161
|
+
EvalError,
|
|
162
|
+
RangeError,
|
|
163
|
+
ReferenceError,
|
|
164
|
+
SyntaxError,
|
|
165
|
+
TypeError,
|
|
166
|
+
URIError,
|
|
167
|
+
Uint8Array,
|
|
168
|
+
Uint8ClampedArray,
|
|
169
|
+
Uint16Array,
|
|
170
|
+
Uint32Array,
|
|
171
|
+
Int8Array,
|
|
172
|
+
Int16Array,
|
|
173
|
+
Int32Array,
|
|
174
|
+
Float32Array,
|
|
175
|
+
Float64Array,
|
|
176
|
+
]) {
|
|
177
|
+
rememberTrustedIntrinsic(constructor);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
for (const name of [
|
|
181
|
+
'SharedArrayBuffer',
|
|
182
|
+
'AggregateError',
|
|
183
|
+
'Float16Array',
|
|
184
|
+
'BigInt64Array',
|
|
185
|
+
'BigUint64Array',
|
|
186
|
+
'Blob',
|
|
187
|
+
'File',
|
|
188
|
+
'Headers',
|
|
189
|
+
] as const) {
|
|
190
|
+
const descriptor = Object.getOwnPropertyDescriptor(globalThis, name);
|
|
191
|
+
if (descriptor && 'value' in descriptor) {
|
|
192
|
+
rememberTrustedIntrinsic(descriptor.value);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
const typedArrayConstructorDescriptor = Object.getOwnPropertyDescriptor(
|
|
197
|
+
Object.getPrototypeOf(Uint8Array.prototype) as object,
|
|
198
|
+
'constructor',
|
|
199
|
+
);
|
|
200
|
+
if (typedArrayConstructorDescriptor && 'value' in typedArrayConstructorDescriptor) {
|
|
201
|
+
rememberTrustedIntrinsic(typedArrayConstructorDescriptor.value);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
if (typeof Buffer === 'function') {
|
|
205
|
+
rememberTrustedIntrinsic(Buffer);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
const blobInternalHandlePrototype = (() => {
|
|
209
|
+
if (typeof Blob !== 'function') {
|
|
210
|
+
return undefined;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
try {
|
|
214
|
+
const blob = new Blob([]);
|
|
215
|
+
for (const key of Object.getOwnPropertySymbols(blob)) {
|
|
216
|
+
const descriptor = Object.getOwnPropertyDescriptor(blob, key);
|
|
217
|
+
if (descriptor && 'value' in descriptor && typeof descriptor.value === 'object' && descriptor.value) {
|
|
218
|
+
return Object.getPrototypeOf(descriptor.value) as object;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
} catch {
|
|
222
|
+
return undefined;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
return undefined;
|
|
226
|
+
})();
|
|
227
|
+
const mapEntries = Map.prototype.entries;
|
|
228
|
+
const setValues = Set.prototype.values;
|
|
229
|
+
const headersEntriesDescriptor =
|
|
230
|
+
typeof Headers === 'function' ? Object.getOwnPropertyDescriptor(Headers.prototype, 'entries') : undefined;
|
|
231
|
+
const headersEntries =
|
|
232
|
+
headersEntriesDescriptor &&
|
|
233
|
+
'value' in headersEntriesDescriptor &&
|
|
234
|
+
typeof headersEntriesDescriptor.value === 'function'
|
|
235
|
+
? (headersEntriesDescriptor.value as typeof Headers.prototype.entries)
|
|
236
|
+
: undefined;
|
|
237
|
+
const retainedStorageBrands = new Set([
|
|
238
|
+
'ArrayBuffer',
|
|
239
|
+
'SharedArrayBuffer',
|
|
240
|
+
'Blob',
|
|
241
|
+
'File',
|
|
242
|
+
'Map',
|
|
243
|
+
'Date',
|
|
244
|
+
'Set',
|
|
245
|
+
'Headers',
|
|
246
|
+
]);
|
|
247
|
+
|
|
248
|
+
interface TrustedForeignIntrinsic {
|
|
249
|
+
constructor: NativeErrorConstructor;
|
|
250
|
+
descriptors: ReadonlyMap<PropertyKey, PropertyDescriptor>;
|
|
251
|
+
functionPrototype: object;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
function getTrustedForeignIntrinsic(prototype: object): TrustedForeignIntrinsic | undefined {
|
|
255
|
+
const descriptor = Object.getOwnPropertyDescriptor(prototype, 'constructor');
|
|
256
|
+
if (!descriptor || !('value' in descriptor) || typeof descriptor.value !== 'function') {
|
|
257
|
+
return undefined;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
const constructor = descriptor.value as NativeErrorConstructor;
|
|
261
|
+
const source = functionToString.call(constructor);
|
|
262
|
+
const descriptors = canonicalIntrinsicDescriptors.get(source);
|
|
263
|
+
if (!trustedNativeConstructorSources.has(source) || !descriptors) {
|
|
264
|
+
return undefined;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
const constructorPrototype = Object.getOwnPropertyDescriptor(constructor, 'prototype');
|
|
268
|
+
if (
|
|
269
|
+
!constructorPrototype ||
|
|
270
|
+
!('value' in constructorPrototype) ||
|
|
271
|
+
constructorPrototype.value !== prototype ||
|
|
272
|
+
constructorPrototype.configurable !== false ||
|
|
273
|
+
constructorPrototype.writable !== false
|
|
274
|
+
) {
|
|
275
|
+
return undefined;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
return { constructor, descriptors, functionPrototype: Object.getPrototypeOf(constructor) as object };
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
function isTrustedIntrinsicPrototype(prototype: object): boolean {
|
|
282
|
+
return trustedIntrinsicPrototypes.has(prototype) || getTrustedForeignIntrinsic(prototype) !== undefined;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
function isCanonicalIntrinsicFunction(
|
|
286
|
+
value: unknown,
|
|
287
|
+
canonical: unknown,
|
|
288
|
+
functionPrototype: object,
|
|
289
|
+
): boolean {
|
|
290
|
+
if (canonical === undefined) {
|
|
291
|
+
return value === undefined;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
if (typeof value !== 'function' || typeof canonical !== 'function') {
|
|
295
|
+
return false;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
const source = functionToString.call(canonical);
|
|
299
|
+
if (functionToString.call(value) !== source) {
|
|
300
|
+
return false;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
const actualFunctionPrototype = Object.getPrototypeOf(value) as object;
|
|
304
|
+
if (actualFunctionPrototype === functionPrototype) {
|
|
305
|
+
return true;
|
|
306
|
+
}
|
|
307
|
+
if (!/^function [A-Za-z_$][\w$]*\(\) \{ \[native code\] \}$/u.test(source)) {
|
|
308
|
+
return false;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
const intrinsic = getTrustedForeignIntrinsic(actualFunctionPrototype);
|
|
312
|
+
return (
|
|
313
|
+
intrinsic !== undefined &&
|
|
314
|
+
functionToString.call(intrinsic.constructor) === nativeFunctionConstructorSource
|
|
315
|
+
);
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
function isCanonicalIntrinsicDescriptor(
|
|
319
|
+
descriptor: PropertyDescriptor,
|
|
320
|
+
canonical: PropertyDescriptor | undefined,
|
|
321
|
+
functionPrototype: object,
|
|
322
|
+
): boolean {
|
|
323
|
+
if (
|
|
324
|
+
!canonical ||
|
|
325
|
+
descriptor.configurable !== canonical.configurable ||
|
|
326
|
+
descriptor.enumerable !== canonical.enumerable ||
|
|
327
|
+
'value' in descriptor !== 'value' in canonical
|
|
328
|
+
) {
|
|
329
|
+
return false;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
if ('value' in descriptor && 'value' in canonical) {
|
|
333
|
+
if (descriptor.writable !== canonical.writable) {
|
|
334
|
+
return false;
|
|
335
|
+
}
|
|
336
|
+
if (typeof canonical.value === 'function') {
|
|
337
|
+
return isCanonicalIntrinsicFunction(descriptor.value, canonical.value, functionPrototype);
|
|
338
|
+
}
|
|
339
|
+
if (canonical.value !== null && typeof canonical.value === 'object') {
|
|
340
|
+
return false;
|
|
341
|
+
}
|
|
342
|
+
return Object.is(descriptor.value, canonical.value);
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
return (
|
|
346
|
+
isCanonicalIntrinsicFunction(descriptor.get, canonical.get, functionPrototype) &&
|
|
347
|
+
isCanonicalIntrinsicFunction(descriptor.set, canonical.set, functionPrototype)
|
|
348
|
+
);
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
function hasNativeErrorBrand(current: object): boolean {
|
|
352
|
+
if (nativeErrorBrand) {
|
|
353
|
+
return nativeErrorBrand.call(Error, current);
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
let prototype: object | null = current;
|
|
357
|
+
for (let depth = 0; prototype !== null && depth < MAX_BUFFERED_EVENT_DEPTH; depth += 1) {
|
|
358
|
+
if (Object.getOwnPropertyDescriptor(prototype, Symbol.toStringTag)) {
|
|
359
|
+
return false;
|
|
360
|
+
}
|
|
361
|
+
prototype = Object.getPrototypeOf(prototype) as object | null;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
return prototype === null && objectToString.call(current) === '[object Error]';
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
function getVerifiedForeignErrorConstructor(
|
|
368
|
+
current: object,
|
|
369
|
+
stackDescriptor: PropertyDescriptor,
|
|
370
|
+
): { constructor: NativeErrorConstructor; prototype: object } | undefined {
|
|
371
|
+
if (typeof stackDescriptor.get !== 'function' || typeof stackDescriptor.set !== 'function') {
|
|
372
|
+
return undefined;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
let prototype = Object.getPrototypeOf(current) as object | null;
|
|
376
|
+
for (let depth = 0; prototype !== null && depth < MAX_BUFFERED_EVENT_DEPTH; depth += 1) {
|
|
377
|
+
const descriptor = Object.getOwnPropertyDescriptor(prototype, 'constructor');
|
|
378
|
+
if (descriptor && 'value' in descriptor && typeof descriptor.value === 'function') {
|
|
379
|
+
const constructor = descriptor.value as NativeErrorConstructor;
|
|
380
|
+
if (
|
|
381
|
+
functionToString.call(constructor) === nativeErrorConstructorSource &&
|
|
382
|
+
isTrustedIntrinsicPrototype(prototype)
|
|
383
|
+
) {
|
|
384
|
+
const functionPrototype = Object.getPrototypeOf(constructor) as object;
|
|
385
|
+
if (
|
|
386
|
+
Object.getPrototypeOf(stackDescriptor.get) === functionPrototype &&
|
|
387
|
+
Object.getPrototypeOf(stackDescriptor.set) === functionPrototype
|
|
388
|
+
) {
|
|
389
|
+
return { constructor, prototype };
|
|
390
|
+
}
|
|
391
|
+
return undefined;
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
prototype = Object.getPrototypeOf(prototype) as object | null;
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
return undefined;
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
function isTrustedNativeErrorStack(current: object, descriptor: PropertyDescriptor): boolean {
|
|
401
|
+
if (!hasNativeErrorBrand(current)) {
|
|
402
|
+
return false;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
if (
|
|
406
|
+
errorStackDescriptor &&
|
|
407
|
+
!('value' in errorStackDescriptor) &&
|
|
408
|
+
typeof errorStackDescriptor.get === 'function' &&
|
|
409
|
+
Object.prototype.isPrototypeOf.call(Error.prototype, current) &&
|
|
410
|
+
descriptor.get === errorStackDescriptor.get &&
|
|
411
|
+
descriptor.set === errorStackDescriptor.set
|
|
412
|
+
) {
|
|
413
|
+
return true;
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
const verified = getVerifiedForeignErrorConstructor(current, descriptor);
|
|
417
|
+
if (!verified) {
|
|
418
|
+
return false;
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
let canonicalDescriptor = foreignErrorStackDescriptors.get(verified.prototype);
|
|
422
|
+
if (!canonicalDescriptor) {
|
|
423
|
+
const canonical = Reflect.construct(verified.constructor, []) as unknown;
|
|
424
|
+
if (
|
|
425
|
+
typeof canonical !== 'object' ||
|
|
426
|
+
canonical === null ||
|
|
427
|
+
!hasNativeErrorBrand(canonical) ||
|
|
428
|
+
Object.getPrototypeOf(canonical) !== verified.prototype
|
|
429
|
+
) {
|
|
430
|
+
return false;
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
canonicalDescriptor = Object.getOwnPropertyDescriptor(canonical, 'stack');
|
|
434
|
+
if (
|
|
435
|
+
!canonicalDescriptor ||
|
|
436
|
+
'value' in canonicalDescriptor ||
|
|
437
|
+
typeof canonicalDescriptor.get !== 'function' ||
|
|
438
|
+
typeof canonicalDescriptor.set !== 'function'
|
|
439
|
+
) {
|
|
440
|
+
return false;
|
|
441
|
+
}
|
|
442
|
+
foreignErrorStackDescriptors.set(verified.prototype, canonicalDescriptor);
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
return descriptor.get === canonicalDescriptor.get && descriptor.set === canonicalDescriptor.set;
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
type RetainedStorage = {
|
|
449
|
+
bytes: number;
|
|
450
|
+
kind: 'typed-array' | 'data-view' | 'buffer' | 'blob' | 'map' | 'date' | 'set' | 'headers';
|
|
451
|
+
};
|
|
2
452
|
|
|
3
453
|
type EventQueue<Value> = {
|
|
4
454
|
readonly length: number;
|
|
@@ -44,6 +494,840 @@ function createEventQueue<Value>(): EventQueue<Value> {
|
|
|
44
494
|
};
|
|
45
495
|
}
|
|
46
496
|
|
|
497
|
+
function getRetainedStorageBrand(current: object): string | undefined {
|
|
498
|
+
let prototype = Object.getPrototypeOf(current) as object | null;
|
|
499
|
+
|
|
500
|
+
for (let depth = 0; prototype !== null && depth < MAX_BUFFERED_EVENT_DEPTH; depth += 1) {
|
|
501
|
+
if (prototype === Date.prototype) {
|
|
502
|
+
return 'Date';
|
|
503
|
+
}
|
|
504
|
+
if (!trustedIntrinsicPrototypes.has(prototype)) {
|
|
505
|
+
const constructor = Object.getOwnPropertyDescriptor(prototype, 'constructor');
|
|
506
|
+
if (
|
|
507
|
+
constructor &&
|
|
508
|
+
'value' in constructor &&
|
|
509
|
+
typeof constructor.value === 'function' &&
|
|
510
|
+
functionToString.call(constructor.value) === nativeDateConstructorSource &&
|
|
511
|
+
getTrustedForeignIntrinsic(prototype)
|
|
512
|
+
) {
|
|
513
|
+
return 'Date';
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
const descriptor = Object.getOwnPropertyDescriptor(prototype, Symbol.toStringTag);
|
|
518
|
+
if (
|
|
519
|
+
descriptor &&
|
|
520
|
+
'value' in descriptor &&
|
|
521
|
+
typeof descriptor.value === 'string' &&
|
|
522
|
+
retainedStorageBrands.has(descriptor.value)
|
|
523
|
+
) {
|
|
524
|
+
return descriptor.value;
|
|
525
|
+
}
|
|
526
|
+
prototype = Object.getPrototypeOf(prototype) as object | null;
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
return undefined;
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
function estimateRetainedBufferBytes(
|
|
533
|
+
current: object,
|
|
534
|
+
visit: (value: unknown, depth: number) => void,
|
|
535
|
+
depth: number,
|
|
536
|
+
): RetainedStorage | undefined {
|
|
537
|
+
if (ArrayBuffer.isView(current)) {
|
|
538
|
+
let buffer: unknown;
|
|
539
|
+
let kind: RetainedStorage['kind'] = 'typed-array';
|
|
540
|
+
|
|
541
|
+
try {
|
|
542
|
+
buffer = typedArrayBufferGetter?.call(current) as unknown;
|
|
543
|
+
} catch {
|
|
544
|
+
kind = 'data-view';
|
|
545
|
+
buffer = dataViewBufferGetter?.call(current) as unknown;
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
if (typeof buffer !== 'object' || buffer === null) {
|
|
549
|
+
return { bytes: Number.POSITIVE_INFINITY, kind };
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
// Even a one-byte cross-realm view retains its complete backing allocation.
|
|
553
|
+
visit(buffer, depth + 1);
|
|
554
|
+
return { bytes: 0, kind };
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
const brand = getRetainedStorageBrand(current);
|
|
558
|
+
if (!brand) {
|
|
559
|
+
return undefined;
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
let getter: (() => unknown) | undefined;
|
|
563
|
+
const kind: RetainedStorage['kind'] = 'buffer';
|
|
564
|
+
switch (brand) {
|
|
565
|
+
case 'ArrayBuffer': {
|
|
566
|
+
getter = arrayBufferByteLengthGetter;
|
|
567
|
+
break;
|
|
568
|
+
}
|
|
569
|
+
case 'SharedArrayBuffer': {
|
|
570
|
+
getter = sharedArrayBufferByteLengthGetter;
|
|
571
|
+
break;
|
|
572
|
+
}
|
|
573
|
+
case 'Blob':
|
|
574
|
+
case 'File': {
|
|
575
|
+
// Blob slices can retain an arbitrarily larger native backing allocation,
|
|
576
|
+
// and neither browser nor Node exposes its extent or ownership. Detached
|
|
577
|
+
// queues must fail closed; waiting readers bypass retained-size inspection.
|
|
578
|
+
return { bytes: Number.POSITIVE_INFINITY, kind: 'blob' };
|
|
579
|
+
}
|
|
580
|
+
case 'Map': {
|
|
581
|
+
return { bytes: 0, kind: 'map' };
|
|
582
|
+
}
|
|
583
|
+
case 'Date': {
|
|
584
|
+
Reflect.apply(dateTimestampGetter, current, []);
|
|
585
|
+
return { bytes: 8, kind: 'date' };
|
|
586
|
+
}
|
|
587
|
+
case 'Set': {
|
|
588
|
+
return { bytes: 0, kind: 'set' };
|
|
589
|
+
}
|
|
590
|
+
case 'Headers': {
|
|
591
|
+
return { bytes: 0, kind: 'headers' };
|
|
592
|
+
}
|
|
593
|
+
default: {
|
|
594
|
+
return undefined;
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
const bytes = getter?.call(current);
|
|
599
|
+
return {
|
|
600
|
+
bytes:
|
|
601
|
+
typeof bytes === 'number' && Number.isSafeInteger(bytes) && bytes >= 0
|
|
602
|
+
? bytes
|
|
603
|
+
: Number.POSITIVE_INFINITY,
|
|
604
|
+
kind,
|
|
605
|
+
};
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
function visitHiddenEventValues(
|
|
609
|
+
current: object,
|
|
610
|
+
kind: RetainedStorage['kind'] | undefined,
|
|
611
|
+
visit: (value: unknown, overhead: number) => boolean,
|
|
612
|
+
): boolean {
|
|
613
|
+
if (kind === 'map') {
|
|
614
|
+
for (const [key, entry] of mapEntries.call(current)) {
|
|
615
|
+
if (!visit(key, 8) || !visit(entry, 8)) {
|
|
616
|
+
return false;
|
|
617
|
+
}
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
if (kind === 'set') {
|
|
622
|
+
for (const entry of setValues.call(current)) {
|
|
623
|
+
if (!visit(entry, 8)) {
|
|
624
|
+
return false;
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
if (kind === 'headers') {
|
|
630
|
+
if (!headersEntries) {
|
|
631
|
+
return false;
|
|
632
|
+
}
|
|
633
|
+
for (const [name, value] of headersEntries.call(current as Headers)) {
|
|
634
|
+
if (!visit(name, 8) || !visit(value, 8)) {
|
|
635
|
+
return false;
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
return true;
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
function getInspectableEventKeys(
|
|
644
|
+
current: object,
|
|
645
|
+
kind: RetainedStorage['kind'] | undefined,
|
|
646
|
+
availableBytes: number,
|
|
647
|
+
): (string | symbol)[] | undefined {
|
|
648
|
+
if (Array.isArray(current)) {
|
|
649
|
+
const descriptor = Object.getOwnPropertyDescriptor(current, 'length');
|
|
650
|
+
const length: unknown = descriptor && 'value' in descriptor ? descriptor.value : undefined;
|
|
651
|
+
if (
|
|
652
|
+
typeof length !== 'number' ||
|
|
653
|
+
!Number.isSafeInteger(length) ||
|
|
654
|
+
length < 0 ||
|
|
655
|
+
length > Math.floor(availableBytes / 16)
|
|
656
|
+
) {
|
|
657
|
+
return undefined;
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
if (kind !== 'typed-array') {
|
|
662
|
+
return Reflect.ownKeys(current);
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
const length: unknown = typedArrayLengthGetter?.call(current);
|
|
666
|
+
if (
|
|
667
|
+
typeof length !== 'number' ||
|
|
668
|
+
!Number.isSafeInteger(length) ||
|
|
669
|
+
length < 0 ||
|
|
670
|
+
length > MAX_INSPECTABLE_TYPED_ARRAY_ELEMENTS
|
|
671
|
+
) {
|
|
672
|
+
return undefined;
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
return Reflect.ownKeys(current).filter((key) => {
|
|
676
|
+
if (typeof key !== 'string') {
|
|
677
|
+
return true;
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
const index = Number(key);
|
|
681
|
+
return !Number.isInteger(index) || index < 0 || index >= length || String(index) !== key;
|
|
682
|
+
});
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
function visitInspectableEventProperties(
|
|
686
|
+
current: object,
|
|
687
|
+
kind: RetainedStorage['kind'] | undefined,
|
|
688
|
+
depth: number,
|
|
689
|
+
availableBytes: () => number,
|
|
690
|
+
charge: (bytes: number) => boolean,
|
|
691
|
+
visit: (value: unknown, depth: number, isBlobInternalHandle?: boolean) => void,
|
|
692
|
+
): boolean {
|
|
693
|
+
const keys = getInspectableEventKeys(current, kind, availableBytes());
|
|
694
|
+
if (keys === undefined) {
|
|
695
|
+
return false;
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
for (const key of keys) {
|
|
699
|
+
if (!charge(typeof key === 'string' ? key.length * 2 + 8 : 8)) {
|
|
700
|
+
return false;
|
|
701
|
+
}
|
|
702
|
+
if (typeof key === 'symbol') {
|
|
703
|
+
visit(key, depth + 1);
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
const descriptor = Object.getOwnPropertyDescriptor(current, key);
|
|
707
|
+
if (!descriptor) {
|
|
708
|
+
return false;
|
|
709
|
+
}
|
|
710
|
+
if (!('value' in descriptor)) {
|
|
711
|
+
if (key === 'stack' && isTrustedNativeErrorStack(current, descriptor)) {
|
|
712
|
+
continue;
|
|
713
|
+
}
|
|
714
|
+
return false;
|
|
715
|
+
}
|
|
716
|
+
visit(descriptor.value, depth + 1, kind === 'blob');
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
return true;
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
function visitRetainedEventPrototypes(
|
|
723
|
+
current: object,
|
|
724
|
+
depth: number,
|
|
725
|
+
isBlobInternalHandle: boolean,
|
|
726
|
+
visited: WeakSet<object>,
|
|
727
|
+
availableBytes: () => number,
|
|
728
|
+
charge: (bytes: number) => boolean,
|
|
729
|
+
visit: (value: unknown, depth: number, isBlobInternalHandle?: boolean) => void,
|
|
730
|
+
retainPrototype: (prototype: object, inspect: () => boolean) => boolean,
|
|
731
|
+
): boolean {
|
|
732
|
+
let prototype = Object.getPrototypeOf(current) as object | null;
|
|
733
|
+
|
|
734
|
+
for (let prototypeDepth = depth + 1; prototype !== null; prototypeDepth += 1) {
|
|
735
|
+
if (prototypeDepth >= MAX_BUFFERED_EVENT_DEPTH) {
|
|
736
|
+
return false;
|
|
737
|
+
}
|
|
738
|
+
if (
|
|
739
|
+
trustedIntrinsicPrototypes.has(prototype) ||
|
|
740
|
+
(isBlobInternalHandle && prototype === blobInternalHandlePrototype)
|
|
741
|
+
) {
|
|
742
|
+
return true;
|
|
743
|
+
}
|
|
744
|
+
if (visited.has(prototype)) {
|
|
745
|
+
visit(prototype, prototypeDepth);
|
|
746
|
+
return availableBytes() >= 0;
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
visited.add(prototype);
|
|
750
|
+
const retainedPrototype = prototype;
|
|
751
|
+
const retained = retainPrototype(retainedPrototype, () => {
|
|
752
|
+
if (!charge(16)) {
|
|
753
|
+
return false;
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
const intrinsic = getTrustedForeignIntrinsic(retainedPrototype);
|
|
757
|
+
if (!intrinsic) {
|
|
758
|
+
return visitInspectableEventProperties(
|
|
759
|
+
retainedPrototype,
|
|
760
|
+
undefined,
|
|
761
|
+
prototypeDepth,
|
|
762
|
+
availableBytes,
|
|
763
|
+
charge,
|
|
764
|
+
visit,
|
|
765
|
+
);
|
|
766
|
+
}
|
|
767
|
+
|
|
768
|
+
for (const key of Reflect.ownKeys(retainedPrototype)) {
|
|
769
|
+
const descriptor = Object.getOwnPropertyDescriptor(retainedPrototype, key);
|
|
770
|
+
if (!descriptor) {
|
|
771
|
+
return false;
|
|
772
|
+
}
|
|
773
|
+
if (
|
|
774
|
+
isCanonicalIntrinsicDescriptor(
|
|
775
|
+
descriptor,
|
|
776
|
+
intrinsic.descriptors.get(key),
|
|
777
|
+
intrinsic.functionPrototype,
|
|
778
|
+
)
|
|
779
|
+
) {
|
|
780
|
+
continue;
|
|
781
|
+
}
|
|
782
|
+
if (!charge(typeof key === 'string' ? key.length * 2 + 8 : 8) || !('value' in descriptor)) {
|
|
783
|
+
return false;
|
|
784
|
+
}
|
|
785
|
+
if (typeof key === 'symbol') {
|
|
786
|
+
visit(key, prototypeDepth + 1);
|
|
787
|
+
}
|
|
788
|
+
visit(descriptor.value, prototypeDepth + 1);
|
|
789
|
+
}
|
|
790
|
+
|
|
791
|
+
return availableBytes() >= 0;
|
|
792
|
+
});
|
|
793
|
+
if (!retained) {
|
|
794
|
+
return false;
|
|
795
|
+
}
|
|
796
|
+
|
|
797
|
+
prototype = Object.getPrototypeOf(retainedPrototype) as object | null;
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
return true;
|
|
801
|
+
}
|
|
802
|
+
|
|
803
|
+
type BufferedRetainedIdentity = object | symbol;
|
|
804
|
+
|
|
805
|
+
type BufferedInspectedNode = {
|
|
806
|
+
bytes: number;
|
|
807
|
+
edges: Set<BufferedRetainedIdentity>;
|
|
808
|
+
};
|
|
809
|
+
|
|
810
|
+
type BufferedInspectedGraph = {
|
|
811
|
+
scalarBytes: number;
|
|
812
|
+
roots: Set<BufferedRetainedIdentity>;
|
|
813
|
+
nodes: Map<BufferedRetainedIdentity, BufferedInspectedNode>;
|
|
814
|
+
};
|
|
815
|
+
|
|
816
|
+
type BufferedLedgerEntry = {
|
|
817
|
+
scalarBytes: number;
|
|
818
|
+
roots: Set<BufferedRetainedIdentity>;
|
|
819
|
+
identities: Set<BufferedRetainedIdentity>;
|
|
820
|
+
};
|
|
821
|
+
|
|
822
|
+
type BufferedLedgerRecord = BufferedInspectedNode & {
|
|
823
|
+
owners: Set<BufferedLedgerEntry>;
|
|
824
|
+
};
|
|
825
|
+
|
|
826
|
+
type BufferedLedgerChange = {
|
|
827
|
+
node: BufferedInspectedNode;
|
|
828
|
+
ownerDelta: number;
|
|
829
|
+
};
|
|
830
|
+
|
|
831
|
+
const BUFFERED_LEDGER_ENTRY_BYTES = 32;
|
|
832
|
+
const BUFFERED_LEDGER_NODE_BYTES = 32;
|
|
833
|
+
const BUFFERED_LEDGER_EDGE_BYTES = 8;
|
|
834
|
+
const BUFFERED_LEDGER_OWNER_BYTES = 16;
|
|
835
|
+
const MAX_BUFFERED_LEDGER_RECONCILIATION_WORK = 128 * 1024;
|
|
836
|
+
|
|
837
|
+
function inspectBufferedEventGraph(
|
|
838
|
+
value: unknown,
|
|
839
|
+
remainingBytes: number,
|
|
840
|
+
): BufferedInspectedGraph | undefined {
|
|
841
|
+
let bytes = 0;
|
|
842
|
+
let scalarBytes = 0;
|
|
843
|
+
const visited = new WeakSet<object>();
|
|
844
|
+
const visitedSymbols = new Set<symbol>();
|
|
845
|
+
const roots = new Set<BufferedRetainedIdentity>();
|
|
846
|
+
const nodes = new Map<BufferedRetainedIdentity, BufferedInspectedNode>();
|
|
847
|
+
let activeNode: BufferedInspectedNode | undefined;
|
|
848
|
+
const availableBytes = (): number => remainingBytes - bytes;
|
|
849
|
+
const charge = (amount: number): boolean => {
|
|
850
|
+
if (!Number.isSafeInteger(amount) || amount < 0) {
|
|
851
|
+
bytes = remainingBytes + 1;
|
|
852
|
+
return false;
|
|
853
|
+
}
|
|
854
|
+
|
|
855
|
+
bytes += amount;
|
|
856
|
+
if (activeNode) {
|
|
857
|
+
activeNode.bytes += amount;
|
|
858
|
+
} else {
|
|
859
|
+
scalarBytes += amount;
|
|
860
|
+
}
|
|
861
|
+
return bytes <= remainingBytes;
|
|
862
|
+
};
|
|
863
|
+
const addIdentity = (identity: BufferedRetainedIdentity): void => {
|
|
864
|
+
if (activeNode) {
|
|
865
|
+
activeNode.edges.add(identity);
|
|
866
|
+
} else {
|
|
867
|
+
roots.add(identity);
|
|
868
|
+
}
|
|
869
|
+
};
|
|
870
|
+
const retainIdentity = (identity: BufferedRetainedIdentity, inspect: () => boolean): boolean => {
|
|
871
|
+
addIdentity(identity);
|
|
872
|
+
const node: BufferedInspectedNode = { bytes: 0, edges: new Set() };
|
|
873
|
+
nodes.set(identity, node);
|
|
874
|
+
const previous = activeNode;
|
|
875
|
+
activeNode = node;
|
|
876
|
+
try {
|
|
877
|
+
return inspect();
|
|
878
|
+
} finally {
|
|
879
|
+
activeNode = previous;
|
|
880
|
+
}
|
|
881
|
+
};
|
|
882
|
+
|
|
883
|
+
const visitSymbol = (current: symbol): void => {
|
|
884
|
+
if (visitedSymbols.has(current)) {
|
|
885
|
+
addIdentity(current);
|
|
886
|
+
charge(8);
|
|
887
|
+
return;
|
|
888
|
+
}
|
|
889
|
+
visitedSymbols.add(current);
|
|
890
|
+
|
|
891
|
+
if (
|
|
892
|
+
!retainIdentity(current, () => {
|
|
893
|
+
if (!symbolDescriptionGetter) {
|
|
894
|
+
return false;
|
|
895
|
+
}
|
|
896
|
+
const description = Reflect.apply(symbolDescriptionGetter, current, []) as string | undefined;
|
|
897
|
+
return charge(8 + (description?.length ?? 0) * 2);
|
|
898
|
+
})
|
|
899
|
+
) {
|
|
900
|
+
bytes = remainingBytes + 1;
|
|
901
|
+
}
|
|
902
|
+
};
|
|
903
|
+
|
|
904
|
+
const visit = (current: unknown, depth: number, isBlobInternalHandle = false): void => {
|
|
905
|
+
if (bytes > remainingBytes) {
|
|
906
|
+
return;
|
|
907
|
+
}
|
|
908
|
+
|
|
909
|
+
if (typeof current === 'string') {
|
|
910
|
+
charge(current.length * 2);
|
|
911
|
+
return;
|
|
912
|
+
}
|
|
913
|
+
|
|
914
|
+
if (typeof current === 'symbol') {
|
|
915
|
+
visitSymbol(current);
|
|
916
|
+
return;
|
|
917
|
+
}
|
|
918
|
+
|
|
919
|
+
if (typeof current === 'function') {
|
|
920
|
+
bytes = remainingBytes + 1;
|
|
921
|
+
return;
|
|
922
|
+
}
|
|
923
|
+
|
|
924
|
+
if (current === null || typeof current !== 'object') {
|
|
925
|
+
charge(8);
|
|
926
|
+
return;
|
|
927
|
+
}
|
|
928
|
+
|
|
929
|
+
if (nativeProxyDetector?.(current)) {
|
|
930
|
+
bytes = remainingBytes + 1;
|
|
931
|
+
return;
|
|
932
|
+
}
|
|
933
|
+
|
|
934
|
+
if (depth >= MAX_BUFFERED_EVENT_DEPTH) {
|
|
935
|
+
bytes = remainingBytes + 1;
|
|
936
|
+
return;
|
|
937
|
+
}
|
|
938
|
+
|
|
939
|
+
if (visited.has(current)) {
|
|
940
|
+
addIdentity(current);
|
|
941
|
+
charge(8);
|
|
942
|
+
return;
|
|
943
|
+
}
|
|
944
|
+
visited.add(current);
|
|
945
|
+
|
|
946
|
+
if (
|
|
947
|
+
!retainIdentity(current, () => {
|
|
948
|
+
if (!charge(16)) {
|
|
949
|
+
return false;
|
|
950
|
+
}
|
|
951
|
+
|
|
952
|
+
const retainedStorage = estimateRetainedBufferBytes(current, visit, depth);
|
|
953
|
+
if (
|
|
954
|
+
!visitRetainedEventPrototypes(
|
|
955
|
+
current,
|
|
956
|
+
depth,
|
|
957
|
+
isBlobInternalHandle,
|
|
958
|
+
visited,
|
|
959
|
+
availableBytes,
|
|
960
|
+
charge,
|
|
961
|
+
visit,
|
|
962
|
+
retainIdentity,
|
|
963
|
+
)
|
|
964
|
+
) {
|
|
965
|
+
return false;
|
|
966
|
+
}
|
|
967
|
+
if (retainedStorage !== undefined && !charge(retainedStorage.bytes)) {
|
|
968
|
+
return false;
|
|
969
|
+
}
|
|
970
|
+
|
|
971
|
+
if (
|
|
972
|
+
!visitHiddenEventValues(current, retainedStorage?.kind, (hiddenValue, overhead) => {
|
|
973
|
+
if (!charge(overhead)) {
|
|
974
|
+
return false;
|
|
975
|
+
}
|
|
976
|
+
visit(hiddenValue, depth + 1);
|
|
977
|
+
return bytes <= remainingBytes;
|
|
978
|
+
})
|
|
979
|
+
) {
|
|
980
|
+
return false;
|
|
981
|
+
}
|
|
982
|
+
|
|
983
|
+
return visitInspectableEventProperties(
|
|
984
|
+
current,
|
|
985
|
+
retainedStorage?.kind,
|
|
986
|
+
depth,
|
|
987
|
+
availableBytes,
|
|
988
|
+
charge,
|
|
989
|
+
visit,
|
|
990
|
+
);
|
|
991
|
+
})
|
|
992
|
+
) {
|
|
993
|
+
bytes = remainingBytes + 1;
|
|
994
|
+
}
|
|
995
|
+
};
|
|
996
|
+
|
|
997
|
+
try {
|
|
998
|
+
visit(value, 0);
|
|
999
|
+
} catch {
|
|
1000
|
+
return undefined;
|
|
1001
|
+
}
|
|
1002
|
+
|
|
1003
|
+
return bytes <= remainingBytes ? { scalarBytes, roots, nodes } : undefined;
|
|
1004
|
+
}
|
|
1005
|
+
|
|
1006
|
+
function areBufferedRetainedEdgesEqual(
|
|
1007
|
+
first: Set<BufferedRetainedIdentity>,
|
|
1008
|
+
second: Set<BufferedRetainedIdentity>,
|
|
1009
|
+
): boolean {
|
|
1010
|
+
if (first.size !== second.size) {
|
|
1011
|
+
return false;
|
|
1012
|
+
}
|
|
1013
|
+
for (const identity of first) {
|
|
1014
|
+
if (!second.has(identity)) {
|
|
1015
|
+
return false;
|
|
1016
|
+
}
|
|
1017
|
+
}
|
|
1018
|
+
return true;
|
|
1019
|
+
}
|
|
1020
|
+
|
|
1021
|
+
function getBufferedLedgerNodeBytes(node: BufferedInspectedNode, owners: number): number {
|
|
1022
|
+
return (
|
|
1023
|
+
node.bytes +
|
|
1024
|
+
BUFFERED_LEDGER_NODE_BYTES +
|
|
1025
|
+
node.edges.size * BUFFERED_LEDGER_EDGE_BYTES +
|
|
1026
|
+
owners * BUFFERED_LEDGER_OWNER_BYTES
|
|
1027
|
+
);
|
|
1028
|
+
}
|
|
1029
|
+
|
|
1030
|
+
function getBufferedLedgerEntryBytes(entry: Pick<BufferedLedgerEntry, 'scalarBytes' | 'roots'>): number {
|
|
1031
|
+
return BUFFERED_LEDGER_ENTRY_BYTES + entry.scalarBytes + entry.roots.size * BUFFERED_LEDGER_EDGE_BYTES;
|
|
1032
|
+
}
|
|
1033
|
+
|
|
1034
|
+
function collectBufferedLedgerIdentities(
|
|
1035
|
+
roots: Set<BufferedRetainedIdentity>,
|
|
1036
|
+
candidate: Map<BufferedRetainedIdentity, BufferedInspectedNode>,
|
|
1037
|
+
records: Map<BufferedRetainedIdentity, BufferedLedgerRecord>,
|
|
1038
|
+
work: { remaining: number },
|
|
1039
|
+
): Set<BufferedRetainedIdentity> | undefined {
|
|
1040
|
+
const identities = new Set<BufferedRetainedIdentity>();
|
|
1041
|
+
const pending = [...roots];
|
|
1042
|
+
|
|
1043
|
+
while (pending.length) {
|
|
1044
|
+
work.remaining -= 1;
|
|
1045
|
+
if (work.remaining < 0) {
|
|
1046
|
+
return undefined;
|
|
1047
|
+
}
|
|
1048
|
+
|
|
1049
|
+
const identity = pending.pop()!;
|
|
1050
|
+
if (identities.has(identity)) {
|
|
1051
|
+
continue;
|
|
1052
|
+
}
|
|
1053
|
+
const node = candidate.get(identity) ?? records.get(identity);
|
|
1054
|
+
if (!node) {
|
|
1055
|
+
return undefined;
|
|
1056
|
+
}
|
|
1057
|
+
identities.add(identity);
|
|
1058
|
+
for (const edge of node.edges) {
|
|
1059
|
+
pending.push(edge);
|
|
1060
|
+
}
|
|
1061
|
+
}
|
|
1062
|
+
|
|
1063
|
+
return identities;
|
|
1064
|
+
}
|
|
1065
|
+
|
|
1066
|
+
function getBufferedLedgerChange(
|
|
1067
|
+
identity: BufferedRetainedIdentity,
|
|
1068
|
+
graph: BufferedInspectedGraph,
|
|
1069
|
+
records: Map<BufferedRetainedIdentity, BufferedLedgerRecord>,
|
|
1070
|
+
changes: Map<BufferedRetainedIdentity, BufferedLedgerChange>,
|
|
1071
|
+
node?: BufferedInspectedNode,
|
|
1072
|
+
): BufferedLedgerChange | undefined {
|
|
1073
|
+
const existing = changes.get(identity);
|
|
1074
|
+
if (existing) {
|
|
1075
|
+
if (node) {
|
|
1076
|
+
existing.node = node;
|
|
1077
|
+
}
|
|
1078
|
+
return existing;
|
|
1079
|
+
}
|
|
1080
|
+
|
|
1081
|
+
const current = node ?? graph.nodes.get(identity) ?? records.get(identity);
|
|
1082
|
+
if (!current) {
|
|
1083
|
+
return undefined;
|
|
1084
|
+
}
|
|
1085
|
+
const update = { node: current, ownerDelta: 0 };
|
|
1086
|
+
changes.set(identity, update);
|
|
1087
|
+
return update;
|
|
1088
|
+
}
|
|
1089
|
+
|
|
1090
|
+
function findBufferedLedgerAffectedOwners(
|
|
1091
|
+
entry: BufferedLedgerEntry,
|
|
1092
|
+
graph: BufferedInspectedGraph,
|
|
1093
|
+
records: Map<BufferedRetainedIdentity, BufferedLedgerRecord>,
|
|
1094
|
+
changes: Map<BufferedRetainedIdentity, BufferedLedgerChange>,
|
|
1095
|
+
work: { remaining: number },
|
|
1096
|
+
): Set<BufferedLedgerEntry> | undefined {
|
|
1097
|
+
const affected = new Set<BufferedLedgerEntry>([entry]);
|
|
1098
|
+
|
|
1099
|
+
for (const [identity, node] of graph.nodes) {
|
|
1100
|
+
work.remaining -= 1;
|
|
1101
|
+
if (work.remaining < 0) {
|
|
1102
|
+
return undefined;
|
|
1103
|
+
}
|
|
1104
|
+
|
|
1105
|
+
const previous = records.get(identity);
|
|
1106
|
+
if (!previous) {
|
|
1107
|
+
continue;
|
|
1108
|
+
}
|
|
1109
|
+
const changedEdges = !areBufferedRetainedEdgesEqual(previous.edges, node.edges);
|
|
1110
|
+
if (previous.bytes !== node.bytes || changedEdges) {
|
|
1111
|
+
getBufferedLedgerChange(identity, graph, records, changes, node);
|
|
1112
|
+
}
|
|
1113
|
+
if (!changedEdges) {
|
|
1114
|
+
continue;
|
|
1115
|
+
}
|
|
1116
|
+
for (const owner of previous.owners) {
|
|
1117
|
+
work.remaining -= 1;
|
|
1118
|
+
if (work.remaining < 0) {
|
|
1119
|
+
return undefined;
|
|
1120
|
+
}
|
|
1121
|
+
affected.add(owner);
|
|
1122
|
+
}
|
|
1123
|
+
}
|
|
1124
|
+
|
|
1125
|
+
return affected;
|
|
1126
|
+
}
|
|
1127
|
+
|
|
1128
|
+
function updateBufferedLedgerMembershipChanges(
|
|
1129
|
+
owner: BufferedLedgerEntry,
|
|
1130
|
+
next: Set<BufferedRetainedIdentity>,
|
|
1131
|
+
graph: BufferedInspectedGraph,
|
|
1132
|
+
records: Map<BufferedRetainedIdentity, BufferedLedgerRecord>,
|
|
1133
|
+
changes: Map<BufferedRetainedIdentity, BufferedLedgerChange>,
|
|
1134
|
+
work: { remaining: number },
|
|
1135
|
+
): boolean {
|
|
1136
|
+
for (const identity of owner.identities) {
|
|
1137
|
+
work.remaining -= 1;
|
|
1138
|
+
if (work.remaining < 0) {
|
|
1139
|
+
return false;
|
|
1140
|
+
}
|
|
1141
|
+
if (!next.has(identity)) {
|
|
1142
|
+
const update = getBufferedLedgerChange(identity, graph, records, changes);
|
|
1143
|
+
if (!update) {
|
|
1144
|
+
return false;
|
|
1145
|
+
}
|
|
1146
|
+
update.ownerDelta -= 1;
|
|
1147
|
+
}
|
|
1148
|
+
}
|
|
1149
|
+
|
|
1150
|
+
for (const identity of next) {
|
|
1151
|
+
work.remaining -= 1;
|
|
1152
|
+
if (work.remaining < 0) {
|
|
1153
|
+
return false;
|
|
1154
|
+
}
|
|
1155
|
+
if (!owner.identities.has(identity)) {
|
|
1156
|
+
const update = getBufferedLedgerChange(identity, graph, records, changes);
|
|
1157
|
+
if (!update) {
|
|
1158
|
+
return false;
|
|
1159
|
+
}
|
|
1160
|
+
update.ownerDelta += 1;
|
|
1161
|
+
}
|
|
1162
|
+
}
|
|
1163
|
+
|
|
1164
|
+
return true;
|
|
1165
|
+
}
|
|
1166
|
+
|
|
1167
|
+
function collectBufferedLedgerMemberships(
|
|
1168
|
+
entry: BufferedLedgerEntry,
|
|
1169
|
+
graph: BufferedInspectedGraph,
|
|
1170
|
+
affected: Set<BufferedLedgerEntry>,
|
|
1171
|
+
records: Map<BufferedRetainedIdentity, BufferedLedgerRecord>,
|
|
1172
|
+
changes: Map<BufferedRetainedIdentity, BufferedLedgerChange>,
|
|
1173
|
+
work: { remaining: number },
|
|
1174
|
+
): Map<BufferedLedgerEntry, Set<BufferedRetainedIdentity>> | undefined {
|
|
1175
|
+
const memberships = new Map<BufferedLedgerEntry, Set<BufferedRetainedIdentity>>();
|
|
1176
|
+
|
|
1177
|
+
for (const owner of affected) {
|
|
1178
|
+
const roots = owner === entry ? graph.roots : owner.roots;
|
|
1179
|
+
const next = collectBufferedLedgerIdentities(roots, graph.nodes, records, work);
|
|
1180
|
+
if (!next || !updateBufferedLedgerMembershipChanges(owner, next, graph, records, changes, work)) {
|
|
1181
|
+
return undefined;
|
|
1182
|
+
}
|
|
1183
|
+
memberships.set(owner, next);
|
|
1184
|
+
}
|
|
1185
|
+
|
|
1186
|
+
return memberships;
|
|
1187
|
+
}
|
|
1188
|
+
|
|
1189
|
+
function projectBufferedLedgerBytes(
|
|
1190
|
+
currentBytes: number,
|
|
1191
|
+
entry: BufferedLedgerEntry,
|
|
1192
|
+
graph: BufferedInspectedGraph,
|
|
1193
|
+
isNew: boolean,
|
|
1194
|
+
changes: Map<BufferedRetainedIdentity, BufferedLedgerChange>,
|
|
1195
|
+
records: Map<BufferedRetainedIdentity, BufferedLedgerRecord>,
|
|
1196
|
+
): number | undefined {
|
|
1197
|
+
let projected =
|
|
1198
|
+
currentBytes - (isNew ? 0 : getBufferedLedgerEntryBytes(entry)) + getBufferedLedgerEntryBytes(graph);
|
|
1199
|
+
|
|
1200
|
+
for (const [identity, update] of changes) {
|
|
1201
|
+
const previous = records.get(identity);
|
|
1202
|
+
const owners = (previous?.owners.size ?? 0) + update.ownerDelta;
|
|
1203
|
+
if (owners < 0) {
|
|
1204
|
+
return undefined;
|
|
1205
|
+
}
|
|
1206
|
+
if (previous) {
|
|
1207
|
+
projected -= getBufferedLedgerNodeBytes(previous, previous.owners.size);
|
|
1208
|
+
}
|
|
1209
|
+
if (owners) {
|
|
1210
|
+
projected += getBufferedLedgerNodeBytes(update.node, owners);
|
|
1211
|
+
}
|
|
1212
|
+
}
|
|
1213
|
+
|
|
1214
|
+
return Number.isSafeInteger(projected) && projected >= 0 && projected <= MAX_BUFFERED_ITERATOR_BYTES
|
|
1215
|
+
? projected
|
|
1216
|
+
: undefined;
|
|
1217
|
+
}
|
|
1218
|
+
|
|
1219
|
+
function applyBufferedLedgerChanges(
|
|
1220
|
+
records: Map<BufferedRetainedIdentity, BufferedLedgerRecord>,
|
|
1221
|
+
changes: Map<BufferedRetainedIdentity, BufferedLedgerChange>,
|
|
1222
|
+
memberships: Map<BufferedLedgerEntry, Set<BufferedRetainedIdentity>>,
|
|
1223
|
+
): void {
|
|
1224
|
+
for (const [identity, update] of changes) {
|
|
1225
|
+
const previous = records.get(identity);
|
|
1226
|
+
const owners = (previous?.owners.size ?? 0) + update.ownerDelta;
|
|
1227
|
+
if (!owners) {
|
|
1228
|
+
continue;
|
|
1229
|
+
}
|
|
1230
|
+
if (previous) {
|
|
1231
|
+
previous.bytes = update.node.bytes;
|
|
1232
|
+
previous.edges = update.node.edges;
|
|
1233
|
+
} else {
|
|
1234
|
+
records.set(identity, {
|
|
1235
|
+
bytes: update.node.bytes,
|
|
1236
|
+
edges: update.node.edges,
|
|
1237
|
+
owners: new Set(),
|
|
1238
|
+
});
|
|
1239
|
+
}
|
|
1240
|
+
}
|
|
1241
|
+
|
|
1242
|
+
for (const [owner, next] of memberships) {
|
|
1243
|
+
for (const identity of owner.identities) {
|
|
1244
|
+
if (!next.has(identity)) {
|
|
1245
|
+
records.get(identity)?.owners.delete(owner);
|
|
1246
|
+
}
|
|
1247
|
+
}
|
|
1248
|
+
for (const identity of next) {
|
|
1249
|
+
if (!owner.identities.has(identity)) {
|
|
1250
|
+
records.get(identity)!.owners.add(owner);
|
|
1251
|
+
}
|
|
1252
|
+
}
|
|
1253
|
+
owner.identities = next;
|
|
1254
|
+
}
|
|
1255
|
+
|
|
1256
|
+
for (const identity of changes.keys()) {
|
|
1257
|
+
if (records.get(identity)?.owners.size === 0) {
|
|
1258
|
+
records.delete(identity);
|
|
1259
|
+
}
|
|
1260
|
+
}
|
|
1261
|
+
}
|
|
1262
|
+
|
|
1263
|
+
/**
|
|
1264
|
+
* Account for queue-owned identities once while charging bounded ownership and
|
|
1265
|
+
* edge metadata. Shared topology changes are reconciled for every queued owner.
|
|
1266
|
+
*/
|
|
1267
|
+
function createBufferedEventLedger(): {
|
|
1268
|
+
retain: (graph: BufferedInspectedGraph) => BufferedLedgerEntry | undefined;
|
|
1269
|
+
refresh: (entry: BufferedLedgerEntry, graph: BufferedInspectedGraph) => boolean;
|
|
1270
|
+
release: (entry: BufferedLedgerEntry) => void;
|
|
1271
|
+
clear: () => void;
|
|
1272
|
+
} {
|
|
1273
|
+
const records = new Map<BufferedRetainedIdentity, BufferedLedgerRecord>();
|
|
1274
|
+
let bytes = 0;
|
|
1275
|
+
|
|
1276
|
+
const reconcile = (entry: BufferedLedgerEntry, graph: BufferedInspectedGraph, isNew: boolean): boolean => {
|
|
1277
|
+
const work = { remaining: MAX_BUFFERED_LEDGER_RECONCILIATION_WORK };
|
|
1278
|
+
const changes = new Map<BufferedRetainedIdentity, BufferedLedgerChange>();
|
|
1279
|
+
const affected = findBufferedLedgerAffectedOwners(entry, graph, records, changes, work);
|
|
1280
|
+
if (!affected) {
|
|
1281
|
+
return false;
|
|
1282
|
+
}
|
|
1283
|
+
const memberships = collectBufferedLedgerMemberships(entry, graph, affected, records, changes, work);
|
|
1284
|
+
if (!memberships) {
|
|
1285
|
+
return false;
|
|
1286
|
+
}
|
|
1287
|
+
const projectedBytes = projectBufferedLedgerBytes(bytes, entry, graph, isNew, changes, records);
|
|
1288
|
+
if (projectedBytes === undefined) {
|
|
1289
|
+
return false;
|
|
1290
|
+
}
|
|
1291
|
+
|
|
1292
|
+
applyBufferedLedgerChanges(records, changes, memberships);
|
|
1293
|
+
entry.scalarBytes = graph.scalarBytes;
|
|
1294
|
+
entry.roots = graph.roots;
|
|
1295
|
+
bytes = projectedBytes;
|
|
1296
|
+
return true;
|
|
1297
|
+
};
|
|
1298
|
+
|
|
1299
|
+
const release = (entry: BufferedLedgerEntry): void => {
|
|
1300
|
+
bytes -= getBufferedLedgerEntryBytes(entry);
|
|
1301
|
+
for (const identity of entry.identities) {
|
|
1302
|
+
const record = records.get(identity);
|
|
1303
|
+
if (!record?.owners.delete(entry)) {
|
|
1304
|
+
continue;
|
|
1305
|
+
}
|
|
1306
|
+
bytes -= BUFFERED_LEDGER_OWNER_BYTES;
|
|
1307
|
+
if (record.owners.size === 0) {
|
|
1308
|
+
bytes -= getBufferedLedgerNodeBytes(record, 0);
|
|
1309
|
+
records.delete(identity);
|
|
1310
|
+
}
|
|
1311
|
+
}
|
|
1312
|
+
entry.identities.clear();
|
|
1313
|
+
};
|
|
1314
|
+
|
|
1315
|
+
return {
|
|
1316
|
+
retain(graph) {
|
|
1317
|
+
const entry: BufferedLedgerEntry = { scalarBytes: 0, roots: new Set(), identities: new Set() };
|
|
1318
|
+
return reconcile(entry, graph, true) ? entry : undefined;
|
|
1319
|
+
},
|
|
1320
|
+
refresh(entry, graph) {
|
|
1321
|
+
return reconcile(entry, graph, false);
|
|
1322
|
+
},
|
|
1323
|
+
release,
|
|
1324
|
+
clear() {
|
|
1325
|
+
records.clear();
|
|
1326
|
+
bytes = 0;
|
|
1327
|
+
},
|
|
1328
|
+
};
|
|
1329
|
+
}
|
|
1330
|
+
|
|
47
1331
|
/** An abortable event stream with typed listeners, asynchronous iteration, and lifecycle state. */
|
|
48
1332
|
export class EventStream<EventTypes extends BaseEvents> {
|
|
49
1333
|
/** Controls the underlying request; aborting this controller cancels the stream. */
|
|
@@ -63,6 +1347,13 @@ export class EventStream<EventTypes extends BaseEvents> {
|
|
|
63
1347
|
[Event in keyof EventTypes]?: EventListeners<EventTypes, Event>;
|
|
64
1348
|
} = Object.create(null);
|
|
65
1349
|
#abortListeners: { signal: AbortSignal; listener: () => void }[] = [];
|
|
1350
|
+
#emittedListenerRegistrations = new WeakMap<
|
|
1351
|
+
object,
|
|
1352
|
+
{ event: PropertyKey; registration: { removed?: boolean; detached?: boolean } }
|
|
1353
|
+
>();
|
|
1354
|
+
#pendingListenerCleanup = new Set<PropertyKey>();
|
|
1355
|
+
#pendingBufferedEventChecks = new Set<() => void>();
|
|
1356
|
+
#listenerDispatchDepth = 0;
|
|
66
1357
|
|
|
67
1358
|
#ended = false;
|
|
68
1359
|
#errored = false;
|
|
@@ -193,7 +1484,21 @@ export class EventStream<EventTypes extends BaseEvents> {
|
|
|
193
1484
|
if (!listeners) {
|
|
194
1485
|
return this;
|
|
195
1486
|
}
|
|
196
|
-
|
|
1487
|
+
|
|
1488
|
+
const emittedRegistration = this.#emittedListenerRegistrations.get(listener as object);
|
|
1489
|
+
if (
|
|
1490
|
+
emittedRegistration?.event === event &&
|
|
1491
|
+
!emittedRegistration.registration.removed &&
|
|
1492
|
+
!emittedRegistration.registration.detached
|
|
1493
|
+
) {
|
|
1494
|
+
this.#removeEmittedListener(
|
|
1495
|
+
event,
|
|
1496
|
+
emittedRegistration.registration as EventListeners<EventTypes, Event>[number],
|
|
1497
|
+
);
|
|
1498
|
+
return this;
|
|
1499
|
+
}
|
|
1500
|
+
|
|
1501
|
+
const index = listeners.findIndex((l) => !l.removed && l.listener === listener);
|
|
197
1502
|
if (index !== -1) {
|
|
198
1503
|
listeners.splice(index, 1);
|
|
199
1504
|
}
|
|
@@ -211,6 +1516,52 @@ export class EventStream<EventTypes extends BaseEvents> {
|
|
|
211
1516
|
return this;
|
|
212
1517
|
}
|
|
213
1518
|
|
|
1519
|
+
#onceForEmitted<Event extends keyof EventTypes>(
|
|
1520
|
+
event: Event,
|
|
1521
|
+
listener: EventListener<EventTypes, Event>,
|
|
1522
|
+
): void {
|
|
1523
|
+
const previousListeners = this.#listeners[event];
|
|
1524
|
+
const previousLength = previousListeners?.length ?? 0;
|
|
1525
|
+
this.once(event, listener);
|
|
1526
|
+
const listeners = this.#listeners[event];
|
|
1527
|
+
const [registration] = listeners?.slice(-1) ?? [];
|
|
1528
|
+
if (
|
|
1529
|
+
(previousListeners === undefined || listeners === previousListeners) &&
|
|
1530
|
+
listeners?.length === previousLength + 1 &&
|
|
1531
|
+
registration?.listener === listener &&
|
|
1532
|
+
registration.once
|
|
1533
|
+
) {
|
|
1534
|
+
this.#emittedListenerRegistrations.set(listener as object, { event, registration });
|
|
1535
|
+
}
|
|
1536
|
+
}
|
|
1537
|
+
|
|
1538
|
+
#removeEmittedListener<Event extends keyof EventTypes>(
|
|
1539
|
+
event: Event,
|
|
1540
|
+
registration: EventListeners<EventTypes, Event>[number],
|
|
1541
|
+
): void {
|
|
1542
|
+
if (registration.removed) {
|
|
1543
|
+
return;
|
|
1544
|
+
}
|
|
1545
|
+
|
|
1546
|
+
registration.removed = true;
|
|
1547
|
+
this.#emittedListenerRegistrations.delete(registration.listener as object);
|
|
1548
|
+
this.#pendingListenerCleanup.add(event);
|
|
1549
|
+
if (this.#listenerDispatchDepth === 0) {
|
|
1550
|
+
this.#cleanupEmittedListeners();
|
|
1551
|
+
}
|
|
1552
|
+
}
|
|
1553
|
+
|
|
1554
|
+
#cleanupEmittedListeners(): void {
|
|
1555
|
+
for (const event of this.#pendingListenerCleanup) {
|
|
1556
|
+
const eventType = event as keyof EventTypes;
|
|
1557
|
+
const listeners = this.#listeners[eventType];
|
|
1558
|
+
if (listeners) {
|
|
1559
|
+
this.#listeners[eventType] = listeners.filter((listener) => !listener.removed) as any;
|
|
1560
|
+
}
|
|
1561
|
+
}
|
|
1562
|
+
this.#pendingListenerCleanup.clear();
|
|
1563
|
+
}
|
|
1564
|
+
|
|
214
1565
|
/**
|
|
215
1566
|
* This is similar to `.once()`, but returns a Promise that resolves the next time
|
|
216
1567
|
* the event is triggered, instead of calling a listener callback.
|
|
@@ -247,9 +1598,9 @@ export class EventStream<EventTypes extends BaseEvents> {
|
|
|
247
1598
|
};
|
|
248
1599
|
|
|
249
1600
|
if (event !== 'error') {
|
|
250
|
-
this
|
|
1601
|
+
this.#onceForEmitted('error', onError as EventListener<EventTypes, 'error'>);
|
|
251
1602
|
}
|
|
252
|
-
this
|
|
1603
|
+
this.#onceForEmitted(event, onEvent as EventListener<EventTypes, Event>);
|
|
253
1604
|
});
|
|
254
1605
|
}
|
|
255
1606
|
|
|
@@ -271,7 +1622,14 @@ export class EventStream<EventTypes extends BaseEvents> {
|
|
|
271
1622
|
type Parameters = EventParameters<EventTypes, Event>;
|
|
272
1623
|
return this._createIterator<Parameters>(
|
|
273
1624
|
(push) => {
|
|
274
|
-
const onEvent = (...args: Parameters) =>
|
|
1625
|
+
const onEvent = (...args: Parameters) => {
|
|
1626
|
+
sdkOwnedBufferedEventArguments.add(args);
|
|
1627
|
+
try {
|
|
1628
|
+
push(args);
|
|
1629
|
+
} finally {
|
|
1630
|
+
sdkOwnedBufferedEventArguments.delete(args);
|
|
1631
|
+
}
|
|
1632
|
+
};
|
|
275
1633
|
this.on(event, onEvent as EventListener<EventTypes, Event>);
|
|
276
1634
|
return () => this.off(event, onEvent as EventListener<EventTypes, Event>);
|
|
277
1635
|
},
|
|
@@ -292,6 +1650,10 @@ export class EventStream<EventTypes extends BaseEvents> {
|
|
|
292
1650
|
* here: the iterator ends when the stream ends, listeners are removed on
|
|
293
1651
|
* end/return, and a terminal error is retained until buffered values have
|
|
294
1652
|
* drained so it is surfaced even when no reader was waiting when it fired.
|
|
1653
|
+
* Detached consumers have bounded event and byte queues; exceeding either
|
|
1654
|
+
* limit fails the stream and aborts its underlying request. Detached queues
|
|
1655
|
+
* also reject accessor-backed payloads because getter closures cannot be
|
|
1656
|
+
* safely sized without executing untrusted code.
|
|
295
1657
|
*/
|
|
296
1658
|
protected _createIterator<T>(
|
|
297
1659
|
attach: (push: (value: T) => void) => () => void,
|
|
@@ -306,9 +1668,16 @@ export class EventStream<EventTypes extends BaseEvents> {
|
|
|
306
1668
|
resolve: (result: Result) => void;
|
|
307
1669
|
reject: (error: OpenAIError) => void;
|
|
308
1670
|
};
|
|
1671
|
+
type BufferedEvent = {
|
|
1672
|
+
retention: BufferedLedgerEntry;
|
|
1673
|
+
active: boolean;
|
|
1674
|
+
check: (() => void) | undefined;
|
|
1675
|
+
};
|
|
309
1676
|
|
|
310
1677
|
const pushQueue = createEventQueue<T>();
|
|
1678
|
+
const bufferedEventSizes = createEventQueue<BufferedEvent>();
|
|
311
1679
|
const readQueue = createEventQueue<Reader>();
|
|
1680
|
+
const bufferedLedger = createBufferedEventLedger();
|
|
312
1681
|
let ended = this.ended;
|
|
313
1682
|
let failure: OpenAIError | undefined;
|
|
314
1683
|
let failureDelivered = false;
|
|
@@ -337,6 +1706,44 @@ export class EventStream<EventTypes extends BaseEvents> {
|
|
|
337
1706
|
this.off('abort', onFailure);
|
|
338
1707
|
}
|
|
339
1708
|
};
|
|
1709
|
+
const deactivateBufferedEvent = (entry: BufferedEvent): void => {
|
|
1710
|
+
entry.active = false;
|
|
1711
|
+
if (entry.check) {
|
|
1712
|
+
this.#pendingBufferedEventChecks.delete(entry.check);
|
|
1713
|
+
entry.check = undefined;
|
|
1714
|
+
}
|
|
1715
|
+
};
|
|
1716
|
+
const failBufferedEvents = (discardRetained = false): OpenAIError => {
|
|
1717
|
+
if (discardRetained) {
|
|
1718
|
+
while (bufferedEventSizes.length) {
|
|
1719
|
+
deactivateBufferedEvent(bufferedEventSizes.dequeue()!);
|
|
1720
|
+
}
|
|
1721
|
+
pushQueue.clear();
|
|
1722
|
+
bufferedLedger.clear();
|
|
1723
|
+
}
|
|
1724
|
+
|
|
1725
|
+
const error = new OpenAIError(
|
|
1726
|
+
`Event stream iterator buffer limit exceeded (${MAX_BUFFERED_ITERATOR_EVENTS} events or ${MAX_BUFFERED_ITERATOR_BYTES} bytes); consume events as they arrive.`,
|
|
1727
|
+
);
|
|
1728
|
+
try {
|
|
1729
|
+
this.#handleError(error);
|
|
1730
|
+
} finally {
|
|
1731
|
+
this.controller.abort();
|
|
1732
|
+
}
|
|
1733
|
+
return error;
|
|
1734
|
+
};
|
|
1735
|
+
|
|
1736
|
+
const revalidateBufferedEvent = (value: T, entry: BufferedEvent): void => {
|
|
1737
|
+
if (!entry.active || this.#ended) {
|
|
1738
|
+
return;
|
|
1739
|
+
}
|
|
1740
|
+
|
|
1741
|
+
const graph = inspectBufferedEventGraph(value, MAX_BUFFERED_ITERATOR_BYTES);
|
|
1742
|
+
if (!graph || !bufferedLedger.refresh(entry.retention, graph)) {
|
|
1743
|
+
failBufferedEvents(true);
|
|
1744
|
+
}
|
|
1745
|
+
};
|
|
1746
|
+
|
|
340
1747
|
const push = (value: T) => {
|
|
341
1748
|
if (ended) {
|
|
342
1749
|
return;
|
|
@@ -345,7 +1752,36 @@ export class EventStream<EventTypes extends BaseEvents> {
|
|
|
345
1752
|
if (reader) {
|
|
346
1753
|
reader.resolve({ value, done: false });
|
|
347
1754
|
} else {
|
|
1755
|
+
if (pushQueue.length >= MAX_BUFFERED_ITERATOR_EVENTS) {
|
|
1756
|
+
failBufferedEvents();
|
|
1757
|
+
return;
|
|
1758
|
+
}
|
|
1759
|
+
const graph = inspectBufferedEventGraph(value, MAX_BUFFERED_ITERATOR_BYTES);
|
|
1760
|
+
const retention = graph && bufferedLedger.retain(graph);
|
|
1761
|
+
if (!retention) {
|
|
1762
|
+
failBufferedEvents();
|
|
1763
|
+
return;
|
|
1764
|
+
}
|
|
1765
|
+
|
|
1766
|
+
if (typeof value === 'object' && value !== null && sdkOwnedBufferedEventArguments.has(value)) {
|
|
1767
|
+
const argumentsTuple = value as unknown[];
|
|
1768
|
+
for (let index = 0; index < argumentsTuple.length; index += 1) {
|
|
1769
|
+
const argument = argumentsTuple[index];
|
|
1770
|
+
if (typeof argument === 'string') {
|
|
1771
|
+
argumentsTuple[index] = bufferedJSONParse(bufferedJSONStringify(argument)) as string;
|
|
1772
|
+
}
|
|
1773
|
+
}
|
|
1774
|
+
}
|
|
1775
|
+
|
|
1776
|
+
const entry: BufferedEvent = { retention, active: true, check: undefined };
|
|
348
1777
|
pushQueue.enqueue(value);
|
|
1778
|
+
bufferedEventSizes.enqueue(entry);
|
|
1779
|
+
const check = () => {
|
|
1780
|
+
entry.check = undefined;
|
|
1781
|
+
revalidateBufferedEvent(value, entry);
|
|
1782
|
+
};
|
|
1783
|
+
entry.check = check;
|
|
1784
|
+
this.#pendingBufferedEventChecks.add(check);
|
|
349
1785
|
}
|
|
350
1786
|
};
|
|
351
1787
|
const onFailure = (error: OpenAIError) => {
|
|
@@ -377,7 +1813,17 @@ export class EventStream<EventTypes extends BaseEvents> {
|
|
|
377
1813
|
return {
|
|
378
1814
|
next: (): Promise<Result> => {
|
|
379
1815
|
if (pushQueue.length) {
|
|
380
|
-
|
|
1816
|
+
const value = pushQueue.dequeue()!;
|
|
1817
|
+
const entry = bufferedEventSizes.dequeue()!;
|
|
1818
|
+
deactivateBufferedEvent(entry);
|
|
1819
|
+
const graph = inspectBufferedEventGraph(value, MAX_BUFFERED_ITERATOR_BYTES);
|
|
1820
|
+
if (!graph || !bufferedLedger.refresh(entry.retention, graph)) {
|
|
1821
|
+
const error = failBufferedEvents(true);
|
|
1822
|
+
failureDelivered = true;
|
|
1823
|
+
return Promise.reject(error);
|
|
1824
|
+
}
|
|
1825
|
+
bufferedLedger.release(entry.retention);
|
|
1826
|
+
return Promise.resolve({ value, done: false });
|
|
381
1827
|
}
|
|
382
1828
|
|
|
383
1829
|
if (failure && !failureDelivered) {
|
|
@@ -395,7 +1841,11 @@ export class EventStream<EventTypes extends BaseEvents> {
|
|
|
395
1841
|
},
|
|
396
1842
|
return: () => {
|
|
397
1843
|
ended = true;
|
|
1844
|
+
while (bufferedEventSizes.length) {
|
|
1845
|
+
deactivateBufferedEvent(bufferedEventSizes.dequeue()!);
|
|
1846
|
+
}
|
|
398
1847
|
pushQueue.clear();
|
|
1848
|
+
bufferedLedger.clear();
|
|
399
1849
|
cleanup();
|
|
400
1850
|
finishReaders();
|
|
401
1851
|
if (onReturn) {
|
|
@@ -443,7 +1893,7 @@ export class EventStream<EventTypes extends BaseEvents> {
|
|
|
443
1893
|
|
|
444
1894
|
/** Returns whether an event currently has one or more registered listeners. */
|
|
445
1895
|
protected _hasListeners<Event extends keyof EventTypes>(event: Event): boolean {
|
|
446
|
-
return Boolean(this.#listeners[event]?.
|
|
1896
|
+
return Boolean(this.#listeners[event]?.some((listener) => !listener.removed));
|
|
447
1897
|
}
|
|
448
1898
|
|
|
449
1899
|
/** Dispatches a connection, failure, cancellation, or completion lifecycle event. */
|
|
@@ -469,9 +1919,30 @@ export class EventStream<EventTypes extends BaseEvents> {
|
|
|
469
1919
|
|
|
470
1920
|
const listeners: EventListeners<EventTypes, Event> | undefined = this.#listeners[event];
|
|
471
1921
|
if (listeners) {
|
|
472
|
-
this.#listeners[event] = listeners.filter((
|
|
473
|
-
|
|
474
|
-
|
|
1922
|
+
this.#listeners[event] = listeners.filter((listener) => {
|
|
1923
|
+
if (listener.once) {
|
|
1924
|
+
listener.detached = true;
|
|
1925
|
+
}
|
|
1926
|
+
return !listener.once && !listener.removed;
|
|
1927
|
+
}) as any;
|
|
1928
|
+
this.#listenerDispatchDepth += 1;
|
|
1929
|
+
try {
|
|
1930
|
+
for (const registration of listeners as any) {
|
|
1931
|
+
if (!registration.removed) {
|
|
1932
|
+
registration.listener(...(args as any));
|
|
1933
|
+
}
|
|
1934
|
+
}
|
|
1935
|
+
} finally {
|
|
1936
|
+
this.#listenerDispatchDepth -= 1;
|
|
1937
|
+
if (this.#listenerDispatchDepth === 0) {
|
|
1938
|
+
this.#cleanupEmittedListeners();
|
|
1939
|
+
for (const check of this.#pendingBufferedEventChecks) {
|
|
1940
|
+
this.#pendingBufferedEventChecks.delete(check);
|
|
1941
|
+
if (!this.#ended) {
|
|
1942
|
+
check();
|
|
1943
|
+
}
|
|
1944
|
+
}
|
|
1945
|
+
}
|
|
475
1946
|
}
|
|
476
1947
|
}
|
|
477
1948
|
|
|
@@ -517,6 +1988,8 @@ type EventListener<Events, EventType extends keyof Events> = Events[EventType];
|
|
|
517
1988
|
type EventListeners<Events, EventType extends keyof Events> = {
|
|
518
1989
|
listener: EventListener<Events, EventType>;
|
|
519
1990
|
once?: boolean;
|
|
1991
|
+
removed?: boolean;
|
|
1992
|
+
detached?: boolean;
|
|
520
1993
|
}[];
|
|
521
1994
|
|
|
522
1995
|
/** The positional listener arguments associated with a named event. */
|