@openclaw/discord 2026.9.8 → 2026.10.1-beta.2

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.
Files changed (147) hide show
  1. package/README.md +7 -0
  2. package/dist/.setup/{account-inspect-De8hOUxG.mjs → account-inspect-CjKqkDnH.mjs} +2 -2
  3. package/dist/.setup/{accounts-ChaMcixG.mjs → accounts-DXHCL8Zm.mjs} +9 -32
  4. package/dist/.setup/{active-turn-thread-route-fmHl1HNd.mjs → active-turn-thread-route-C4tp9noA.mjs} +5 -9
  5. package/dist/.setup/{activities-api-tvbsU2e3.mjs → activities-api-BL_hJ0JQ.mjs} +15 -18
  6. package/dist/.setup/{api-DVbJwZVt.mjs → api-_oznjffB.mjs} +1 -1
  7. package/dist/.setup/{approval-handler.runtime-DxCK2Rux.mjs → approval-handler.runtime-BilYSrRF.mjs} +22 -61
  8. package/dist/.setup/{approval-message-updates-BKFqavHZ.mjs → approval-message-updates-CgRwc2_Q.mjs} +2 -2
  9. package/dist/.setup/{audit-CLg9I71N.mjs → audit-DtvzxONM.mjs} +4 -4
  10. package/dist/.setup/{channel-access-C12aDZ0p.mjs → channel-access-BRp3Y-rF.mjs} +4 -17
  11. package/dist/.setup/{channel-type-DRCrEMss.mjs → channel-type-D1_b5UhU.mjs} +12 -16
  12. package/dist/.setup/{channel-DxlUVU9t.mjs → channel-z5lQMS_9.mjs} +79 -75
  13. package/dist/.setup/{channel.setup-CRo1GjV7.mjs → channel.setup-DBJtugJO.mjs} +14 -34
  14. package/dist/.setup/{components-Cq1PvIpN.mjs → components-CzXLR3QH.mjs} +56 -72
  15. package/dist/.setup/{config-schema-oxELUSDx.mjs → config-schema-CsemBDpS.mjs} +6 -17
  16. package/dist/.setup/{conversation-binding-route-Caz_XuFH.mjs → conversation-binding-route-Bi62ApSt.mjs} +1 -1
  17. package/dist/.setup/{directory-config-esqNn0Eo.mjs → directory-config-BH1LA-gi.mjs} +1 -1
  18. package/dist/.setup/{directory-live-DtKRHuGV.mjs → directory-live-C9xz7IPm.mjs} +10 -13
  19. package/dist/.setup/{discord-0xJYfdDD.mjs → discord-J7aRzq2Q.mjs} +101 -381
  20. package/dist/.setup/{doctor-BCl1H5tl.mjs → doctor-DxSAngJq.mjs} +31 -70
  21. package/dist/.setup/doctor-contract-Bg3NPAMw.mjs +137 -0
  22. package/dist/.setup/{handle-action-CUvQWnE7.mjs → handle-action-DlmFX-_G.mjs} +10 -11
  23. package/dist/.setup/{handle-action.guild-admin-Df-8gVle.mjs → handle-action.guild-admin-BnyqTczR.mjs} +67 -129
  24. package/dist/.setup/{live-policy-config-8Pv20CHc.mjs → live-policy-config-emmPNyh4.mjs} +1 -1
  25. package/dist/.setup/{message-handler-B-Jk4oDk.mjs → message-handler-BNToPZrx.mjs} +7 -6
  26. package/dist/.setup/{message-handler.preflight-v-__NSDq.mjs → message-handler.preflight-D0BcCyI7.mjs} +13 -23
  27. package/dist/.setup/{message-handler.preflight-pluralkit-CWLUBVcx.mjs → message-handler.preflight-pluralkit-D1g3eq0B.mjs} +5 -8
  28. package/dist/.setup/{message-handler.process-BNFFuChn.mjs → message-handler.process-CThRmCWK.mjs} +57 -96
  29. package/dist/.setup/{outbound-adapter-BobT-kse.mjs → outbound-adapter-BPq0c2wY.mjs} +11 -17
  30. package/dist/.setup/{outbound-session-route-zVGxxceg.mjs → outbound-session-route-DGPPKA0z.mjs} +21 -46
  31. package/dist/.setup/{presence-cache-Di3H3DIU.mjs → presence-cache-Dg3_dADn.mjs} +2 -4
  32. package/dist/.setup/{probe-LYrIHlBF.mjs → probe-DIRY8vh7.mjs} +17 -27
  33. package/dist/.setup/{provider-B_G5hASF.mjs → provider-D2OKMo0f.mjs} +273 -446
  34. package/dist/.setup/{provider-session.runtime-BYlTBFD2.mjs → provider-session.runtime-BupCTZQv.mjs} +3 -3
  35. package/dist/.setup/provider.runtime-BaW_JnfU.mjs +2 -0
  36. package/dist/.setup/{realtime-session.runtime-oUd9DOcz.mjs → realtime-session.runtime-D5RSC8Mm.mjs} +6 -8
  37. package/dist/.setup/{receive-recovery-CHPOsnLc.mjs → receive-recovery-GqF2PUN_.mjs} +1 -4
  38. package/dist/.setup/{resolve-allowlist-common-DPdRggu5.mjs → resolve-allowlist-common-DUYRrrVB.mjs} +5 -9
  39. package/dist/.setup/{resolve-channels-BFPNRmVv.mjs → resolve-channels--MUatisx.mjs} +3 -3
  40. package/dist/.setup/{resolve-users-0-aBuCy3.mjs → resolve-users-CxLcDmM0.mjs} +6 -9
  41. package/dist/.setup/{retry-pz_cSha2.mjs → retry-BKzO25k4.mjs} +27 -51
  42. package/dist/.setup/{runtime-sUksZ--Q.mjs → runtime-CerRBfaa.mjs} +2 -2
  43. package/dist/.setup/{runtime-FN000lxA.mjs → runtime-CwUA0RLr.mjs} +228 -255
  44. package/dist/.setup/{runtime-doctor-migrations-CshUGl36.mjs → runtime-doctor-migrations-BPV-R4G9.mjs} +6 -0
  45. package/dist/.setup/{security-audit-Cdaegq7C.mjs → security-audit-D42cp5N7.mjs} +21 -48
  46. package/dist/.setup/{send-CrfEI6Bs.mjs → send-2X7m2Zmw.mjs} +45 -58
  47. package/dist/.setup/{send.components-DxQAMfES.mjs → send.components-RqvgmCs3.mjs} +44 -90
  48. package/dist/.setup/{send.outbound-BISKnb-a.mjs → send.outbound-B4QHSEzm.mjs} +60 -98
  49. package/dist/.setup/{send.shared-DGFkbkQR.mjs → send.shared-BQIUh6Vn.mjs} +13 -20
  50. package/dist/.setup/{sender-identity-B9X5Vb9R.mjs → sender-identity-CooeYfAn.mjs} +1 -1
  51. package/dist/.setup/{session-key-normalization-wJgsKPNF.mjs → session-key-normalization-CCHGNSQw.mjs} +3 -9
  52. package/dist/.setup/setup-plugin-api-nn_giXvZ.mjs +3 -0
  53. package/dist/.setup/{shared-B3wZ4hN-.mjs → shared-CIJn6AEC.mjs} +7 -7
  54. package/dist/.setup/{subagent-hooks-nlUE9ow7.mjs → subagent-hooks-BYlVnxzy.mjs} +4 -9
  55. package/dist/.setup/{system-events-CdeZnvPV.mjs → system-events-CQ3if_pS.mjs} +2 -2
  56. package/dist/.setup/{target-resolver-BuLapkhy.mjs → target-resolver-Dzxf80Y3.mjs} +5 -13
  57. package/dist/.setup/targets-Lf8D55w-.mjs +3 -0
  58. package/dist/.setup/{thread-bindings-D7TfgjR_.mjs → thread-bindings-yNNlcUWE.mjs} +5 -6
  59. package/dist/.setup/{thread-bindings.manager-DN-NissX.mjs → thread-bindings.manager-plk0zJAW.mjs} +14 -20
  60. package/dist/.setup/{thread-bindings.session-updates-CshfKghV.mjs → thread-bindings.session-updates-C9aKtVs6.mjs} +295 -5
  61. package/dist/.setup/{timeouts-D86uWLt_.mjs → timeouts-pun7VJ02.mjs} +2 -15
  62. package/dist/.setup/{transcripts-source-p8EV179h.mjs → transcripts-source-CNWswry-.mjs} +31 -79
  63. package/dist/.setup/typing-CNlSKY5S.mjs +11 -0
  64. package/dist/.setup/{voice-runtime-B46rcwrG.mjs → voice-runtime-Bc75quiH.mjs} +62 -110
  65. package/dist/account-inspect-api.js +1 -1
  66. package/dist/action-runtime-api.js +1 -1
  67. package/dist/activities-api.js +1 -1
  68. package/dist/api.js +18 -18
  69. package/dist/channel-config-api.js +1 -1
  70. package/dist/channel-plugin-api.js +1 -1
  71. package/dist/control-ui/2afbdab1d3aa65a789d8a3eba666f4b1ec5df07073538fe30d6cf32093a1fb2d/index.js +1 -0
  72. package/dist/directory-contract-api.js +1 -1
  73. package/dist/doctor-contract-api.js +19 -128
  74. package/dist/index.js +1 -1
  75. package/dist/runtime-api.js +20 -21
  76. package/dist/security-audit-contract-api.js +1 -1
  77. package/dist/session-key-api.js +1 -1
  78. package/dist/setup-entry.js +1 -1
  79. package/dist/setup-plugin-api.js +1 -1
  80. package/dist/src/voice/audio-worker.runtime.js +6 -8
  81. package/dist/subagent-hooks-api.js +1 -1
  82. package/dist/transcripts-source-api.js +1 -1
  83. package/node_modules/libopus-wasm/CHANGELOG.md +8 -0
  84. package/node_modules/libopus-wasm/dist/discordjs.d.ts.map +1 -1
  85. package/node_modules/libopus-wasm/dist/discordjs.js +14 -2
  86. package/node_modules/libopus-wasm/dist/generated/libopus.generated.mjs +0 -0
  87. package/node_modules/libopus-wasm/dist/index.d.ts.map +1 -1
  88. package/node_modules/libopus-wasm/dist/index.js +55 -100
  89. package/node_modules/libopus-wasm/package.json +5 -5
  90. package/node_modules/undici/README.md +10 -1
  91. package/node_modules/undici/docs/docs/api/Agent.md +8 -8
  92. package/node_modules/undici/docs/docs/api/DiagnosticsChannel.md +9 -6
  93. package/node_modules/undici/docs/docs/api/Dispatcher.md +9 -0
  94. package/node_modules/undici/docs/docs/api/Errors.md +25 -0
  95. package/node_modules/undici/docs/docs/api/Fetch.md +10 -0
  96. package/node_modules/undici/docs/docs/api/Interceptors.md +4 -3
  97. package/node_modules/undici/docs/docs/api/Pool.md +5 -6
  98. package/node_modules/undici/docs/docs/index.md +10 -1
  99. package/node_modules/undici/lib/api/readable.js +1 -2
  100. package/node_modules/undici/lib/core/request.js +23 -2
  101. package/node_modules/undici/lib/core/util.js +0 -39
  102. package/node_modules/undici/lib/dispatcher/client-h1.js +11 -4
  103. package/node_modules/undici/lib/dispatcher/client-h2.js +52 -8
  104. package/node_modules/undici/lib/dispatcher/client.js +6 -1
  105. package/node_modules/undici/lib/dispatcher/env-http-proxy-agent.js +21 -6
  106. package/node_modules/undici/lib/dispatcher/pool-base.js +63 -2
  107. package/node_modules/undici/lib/dispatcher/pool.js +90 -7
  108. package/node_modules/undici/lib/dispatcher/proxy-agent.js +16 -3
  109. package/node_modules/undici/lib/handler/deduplication-handler.js +24 -11
  110. package/node_modules/undici/lib/handler/redirect-handler.js +5 -0
  111. package/node_modules/undici/lib/handler/retry-handler.js +72 -13
  112. package/node_modules/undici/lib/interceptor/cache.js +4 -1
  113. package/node_modules/undici/lib/interceptor/decompress.js +236 -69
  114. package/node_modules/undici/lib/web/cache/cache.js +17 -8
  115. package/node_modules/undici/lib/web/cache/cachestorage.js +11 -5
  116. package/node_modules/undici/lib/web/cookies/index.js +19 -7
  117. package/node_modules/undici/lib/web/cookies/util.js +3 -1
  118. package/node_modules/undici/lib/web/eventsource/eventsource.js +25 -1
  119. package/node_modules/undici/lib/web/fetch/body.js +22 -15
  120. package/node_modules/undici/lib/web/fetch/data-url.js +6 -6
  121. package/node_modules/undici/lib/web/fetch/formdata.js +30 -36
  122. package/node_modules/undici/lib/web/fetch/headers.js +34 -31
  123. package/node_modules/undici/lib/web/fetch/index.js +46 -25
  124. package/node_modules/undici/lib/web/fetch/request.js +74 -79
  125. package/node_modules/undici/lib/web/fetch/response.js +43 -44
  126. package/node_modules/undici/lib/web/fetch/util.js +7 -7
  127. package/node_modules/undici/lib/web/infra/index.js +16 -1
  128. package/node_modules/undici/lib/web/webidl/index.js +2 -14
  129. package/node_modules/undici/lib/web/websocket/connection.js +33 -12
  130. package/node_modules/undici/lib/web/websocket/events.js +43 -26
  131. package/node_modules/undici/lib/web/websocket/receiver.js +2 -0
  132. package/node_modules/undici/lib/web/websocket/stream/websocketerror.js +13 -10
  133. package/node_modules/undici/lib/web/websocket/stream/websocketstream.js +19 -4
  134. package/node_modules/undici/lib/web/websocket/websocket.js +44 -41
  135. package/node_modules/undici/package.json +1 -1
  136. package/node_modules/undici/types/diagnostics-channel.d.ts +2 -1
  137. package/node_modules/undici/types/interceptors.d.ts +1 -1
  138. package/node_modules/undici/types/webidl.d.ts +13 -7
  139. package/openclaw.plugin.json +6 -0
  140. package/package.json +12 -7
  141. package/dist/.setup/doctor-contract-CvvgwrrG.mjs +0 -409
  142. package/dist/.setup/model-picker-preference-primitives-BHT1LkR_.mjs +0 -37
  143. package/dist/.setup/provider.runtime-CUE3UxER.mjs +0 -2
  144. package/dist/.setup/setup-plugin-api-BQUBxbhe.mjs +0 -3
  145. package/dist/.setup/targets-0KUcEIYx.mjs +0 -3
  146. package/dist/.setup/thread-bindings.state-g6v9zAym.mjs +0 -331
  147. package/dist/.setup/typing-BiHCzBRu.mjs +0 -15
@@ -46,6 +46,7 @@ const DEFAULT_CHANNELS = 2;
46
46
  const DEFAULT_FRAME_DURATION_MS = 20;
47
47
  const MAX_PACKET_DURATION_MS = 120;
48
48
  const DEFAULT_MAX_PACKET_BYTES = 4000;
49
+ const MIN_I32 = -0x8000_0000;
49
50
  const MAX_I32 = 0x7fff_ffff;
50
51
  const DEFAULT_SAMPLE_RATE = 48_000;
51
52
  const DECODER_INTEGER_CTL_REQUESTS = new Set(Object.values(DecoderCtl));
@@ -110,6 +111,31 @@ export async function getPacketInfo(packet, options = {}) {
110
111
  module._free(packetPtr);
111
112
  }
112
113
  }
114
+ class WasmBuffer {
115
+ module;
116
+ #bytes = 0;
117
+ #ptr = 0;
118
+ constructor(module) {
119
+ this.module = module;
120
+ }
121
+ ensure(requiredBytes) {
122
+ if (this.#ptr !== 0 && this.#bytes >= requiredBytes) {
123
+ return this.#ptr;
124
+ }
125
+ const nextPtr = checkedMalloc(this.module, requiredBytes);
126
+ this.free();
127
+ this.#ptr = nextPtr;
128
+ this.#bytes = requiredBytes;
129
+ return this.#ptr;
130
+ }
131
+ free() {
132
+ if (this.#ptr !== 0) {
133
+ this.module._free(this.#ptr);
134
+ }
135
+ this.#ptr = 0;
136
+ this.#bytes = 0;
137
+ }
138
+ }
113
139
  class WasmOpusEncoder {
114
140
  application;
115
141
  channels;
@@ -117,18 +143,18 @@ class WasmOpusEncoder {
117
143
  sampleRate;
118
144
  #freed = false;
119
145
  #module;
120
- #packetBytes = 0;
121
- #packetPtr = 0;
122
- #pcmBytes = 0;
123
- #pcmPtr = 0;
146
+ #packet;
147
+ #pcm;
124
148
  #ptr;
125
149
  constructor(module, options) {
126
150
  this.#module = module;
151
+ this.#packet = new WasmBuffer(module);
152
+ this.#pcm = new WasmBuffer(module);
127
153
  this.application = options.application;
128
154
  this.channels = options.channels;
129
155
  this.frameSize = options.frameSize;
130
156
  this.sampleRate = options.sampleRate;
131
- const errorPtr = module._malloc(4);
157
+ const errorPtr = checkedMalloc(module, 4);
132
158
  try {
133
159
  const ptr = module._oc_create_encoder(options.sampleRate, options.channels, options.application, errorPtr);
134
160
  const error = module.HEAP32[errorPtr >> 2] ?? 0;
@@ -176,8 +202,8 @@ class WasmOpusEncoder {
176
202
  }
177
203
  const maxPacketBytes = options.maxPacketBytes ?? DEFAULT_MAX_PACKET_BYTES;
178
204
  validateIntegerRange(maxPacketBytes, 1, MAX_I32, "maxPacketBytes");
179
- const pcmPtr = this.#ensurePcmBytes(pcmBytes.byteLength);
180
- const packetPtr = this.#ensurePacketBytes(maxPacketBytes);
205
+ const pcmPtr = this.#pcm.ensure(pcmBytes.byteLength);
206
+ const packetPtr = this.#packet.ensure(maxPacketBytes);
181
207
  this.#module.HEAPU8.set(pcmBytes, pcmPtr);
182
208
  const encodedBytes = this.#module._oc_encode(this.#ptr, pcmPtr, frameSize, packetPtr, maxPacketBytes);
183
209
  if (encodedBytes < 0) {
@@ -195,8 +221,8 @@ class WasmOpusEncoder {
195
221
  }
196
222
  const maxPacketBytes = options.maxPacketBytes ?? DEFAULT_MAX_PACKET_BYTES;
197
223
  validateIntegerRange(maxPacketBytes, 1, MAX_I32, "maxPacketBytes");
198
- const pcmPtr = this.#ensurePcmBytes(pcm.byteLength);
199
- const packetPtr = this.#ensurePacketBytes(maxPacketBytes);
224
+ const pcmPtr = this.#pcm.ensure(pcm.byteLength);
225
+ const packetPtr = this.#packet.ensure(maxPacketBytes);
200
226
  this.#module.HEAPF32.set(pcm, pcmPtr >> 2);
201
227
  const encodedBytes = this.#module._oc_encode_float(this.#ptr, pcmPtr, frameSize, packetPtr, maxPacketBytes);
202
228
  if (encodedBytes < 0) {
@@ -213,7 +239,7 @@ class WasmOpusEncoder {
213
239
  encoderCtl(request, value) {
214
240
  this.#assertLive();
215
241
  validateInteger(request, "request");
216
- validateInteger(value, "value");
242
+ validateIntegerRange(value, MIN_I32, MAX_I32, "value");
217
243
  if (!ENCODER_INTEGER_CTL_REQUESTS.has(request)) {
218
244
  throw new RangeError("encoderCtl only supports integer setter requests");
219
245
  }
@@ -280,7 +306,8 @@ class WasmOpusEncoder {
280
306
  if (this.#freed) {
281
307
  return;
282
308
  }
283
- this.#freeScratch();
309
+ this.#packet.free();
310
+ this.#pcm.free();
284
311
  this.#module._oc_destroy_encoder(this.#ptr);
285
312
  this.#freed = true;
286
313
  }
@@ -297,42 +324,6 @@ class WasmOpusEncoder {
297
324
  throw createOpusError(this.#module, code, operation);
298
325
  }
299
326
  }
300
- #ensurePacketBytes(requiredBytes) {
301
- if (this.#packetPtr !== 0 && this.#packetBytes >= requiredBytes) {
302
- return this.#packetPtr;
303
- }
304
- const nextPtr = checkedMalloc(this.#module, requiredBytes);
305
- if (this.#packetPtr !== 0) {
306
- this.#module._free(this.#packetPtr);
307
- }
308
- this.#packetPtr = nextPtr;
309
- this.#packetBytes = requiredBytes;
310
- return this.#packetPtr;
311
- }
312
- #ensurePcmBytes(requiredBytes) {
313
- if (this.#pcmPtr !== 0 && this.#pcmBytes >= requiredBytes) {
314
- return this.#pcmPtr;
315
- }
316
- const nextPtr = checkedMalloc(this.#module, requiredBytes);
317
- if (this.#pcmPtr !== 0) {
318
- this.#module._free(this.#pcmPtr);
319
- }
320
- this.#pcmPtr = nextPtr;
321
- this.#pcmBytes = requiredBytes;
322
- return this.#pcmPtr;
323
- }
324
- #freeScratch() {
325
- if (this.#packetPtr !== 0) {
326
- this.#module._free(this.#packetPtr);
327
- }
328
- if (this.#pcmPtr !== 0) {
329
- this.#module._free(this.#pcmPtr);
330
- }
331
- this.#packetPtr = 0;
332
- this.#packetBytes = 0;
333
- this.#pcmPtr = 0;
334
- this.#pcmBytes = 0;
335
- }
336
327
  }
337
328
  class WasmOpusDecoder {
338
329
  channels;
@@ -340,17 +331,17 @@ class WasmOpusDecoder {
340
331
  sampleRate;
341
332
  #freed = false;
342
333
  #module;
343
- #packetBytes = 0;
344
- #packetPtr = 0;
345
- #pcmBytes = 0;
346
- #pcmPtr = 0;
334
+ #packet;
335
+ #pcm;
347
336
  #ptr;
348
337
  constructor(module, options) {
349
338
  this.#module = module;
339
+ this.#packet = new WasmBuffer(module);
340
+ this.#pcm = new WasmBuffer(module);
350
341
  this.channels = options.channels;
351
342
  this.maxFrameSize = options.maxFrameSize;
352
343
  this.sampleRate = options.sampleRate;
353
- const errorPtr = module._malloc(4);
344
+ const errorPtr = checkedMalloc(module, 4);
354
345
  try {
355
346
  const ptr = module._oc_create_decoder(options.sampleRate, options.channels, errorPtr);
356
347
  const error = module.HEAP32[errorPtr >> 2] ?? 0;
@@ -367,7 +358,7 @@ class WasmOpusDecoder {
367
358
  this.#assertLive();
368
359
  const frameSize = this.#resolveDecodeFrameSize(packet, options);
369
360
  const pcmBytes = frameSize * this.channels * 2;
370
- const pcmPtr = this.#ensurePcmBytes(pcmBytes);
361
+ const pcmPtr = this.#pcm.ensure(pcmBytes);
371
362
  const { packetLength, packetPtr } = this.#copyPacket(packet, options.decodeFec);
372
363
  const decodedSamples = this.#module._oc_decode(this.#ptr, packetPtr, packetLength, pcmPtr, frameSize, options.decodeFec ? 1 : 0);
373
364
  if (decodedSamples < 0) {
@@ -380,7 +371,7 @@ class WasmOpusDecoder {
380
371
  this.#assertLive();
381
372
  const frameSize = this.#resolveDecodeFrameSize(packet, options);
382
373
  const pcmBytes = frameSize * this.channels * 4;
383
- const pcmPtr = this.#ensurePcmBytes(pcmBytes);
374
+ const pcmPtr = this.#pcm.ensure(pcmBytes);
384
375
  const { packetLength, packetPtr } = this.#copyPacket(packet, options.decodeFec);
385
376
  const decodedSamples = this.#module._oc_decode_float(this.#ptr, packetPtr, packetLength, pcmPtr, frameSize, options.decodeFec ? 1 : 0);
386
377
  if (decodedSamples < 0) {
@@ -404,7 +395,7 @@ class WasmOpusDecoder {
404
395
  decoderCtl(request, value) {
405
396
  this.#assertLive();
406
397
  validateInteger(request, "request");
407
- validateInteger(value, "value");
398
+ validateIntegerRange(value, MIN_I32, MAX_I32, "value");
408
399
  if (!DECODER_INTEGER_CTL_REQUESTS.has(request)) {
409
400
  throw new RangeError("decoderCtl only supports integer setter requests");
410
401
  }
@@ -417,7 +408,8 @@ class WasmOpusDecoder {
417
408
  if (this.#freed) {
418
409
  return;
419
410
  }
420
- this.#freeScratch();
411
+ this.#packet.free();
412
+ this.#pcm.free();
421
413
  this.#module._oc_destroy_decoder(this.#ptr);
422
414
  this.#freed = true;
423
415
  }
@@ -439,46 +431,10 @@ class WasmOpusDecoder {
439
431
  if (packet.byteLength === 0) {
440
432
  throw new RangeError("packet must not be empty; use null or decodePacketLoss() for PLC");
441
433
  }
442
- const packetPtr = this.#ensurePacketBytes(packet.byteLength);
434
+ const packetPtr = this.#packet.ensure(packet.byteLength);
443
435
  this.#module.HEAPU8.set(packet, packetPtr);
444
436
  return { packetLength: packet.byteLength, packetPtr };
445
437
  }
446
- #ensurePacketBytes(requiredBytes) {
447
- if (this.#packetPtr !== 0 && this.#packetBytes >= requiredBytes) {
448
- return this.#packetPtr;
449
- }
450
- const nextPtr = checkedMalloc(this.#module, requiredBytes);
451
- if (this.#packetPtr !== 0) {
452
- this.#module._free(this.#packetPtr);
453
- }
454
- this.#packetPtr = nextPtr;
455
- this.#packetBytes = requiredBytes;
456
- return this.#packetPtr;
457
- }
458
- #ensurePcmBytes(requiredBytes) {
459
- if (this.#pcmPtr !== 0 && this.#pcmBytes >= requiredBytes) {
460
- return this.#pcmPtr;
461
- }
462
- const nextPtr = checkedMalloc(this.#module, requiredBytes);
463
- if (this.#pcmPtr !== 0) {
464
- this.#module._free(this.#pcmPtr);
465
- }
466
- this.#pcmPtr = nextPtr;
467
- this.#pcmBytes = requiredBytes;
468
- return this.#pcmPtr;
469
- }
470
- #freeScratch() {
471
- if (this.#packetPtr !== 0) {
472
- this.#module._free(this.#packetPtr);
473
- }
474
- if (this.#pcmPtr !== 0) {
475
- this.#module._free(this.#pcmPtr);
476
- }
477
- this.#packetPtr = 0;
478
- this.#packetBytes = 0;
479
- this.#pcmPtr = 0;
480
- this.#pcmBytes = 0;
481
- }
482
438
  #resolveDecodeFrameSize(packet, options) {
483
439
  const frameSize = packet === null || options.decodeFec
484
440
  ? (options.frameSize ?? options.maxFrameSize ?? samplesForDuration(this.sampleRate, DEFAULT_FRAME_DURATION_MS))
@@ -550,6 +506,10 @@ function normalizeEncoderOptions(options) {
550
506
  const sampleRate = options.sampleRate ?? DEFAULT_SAMPLE_RATE;
551
507
  const channels = options.channels ?? DEFAULT_CHANNELS;
552
508
  validateCodecOptions({ channels, sampleRate });
509
+ const application = options.application ?? Application.Audio;
510
+ if (!Object.values(Application).includes(application)) {
511
+ throw new RangeError("application must be Application.Voip, Application.Audio, or Application.RestrictedLowDelay");
512
+ }
553
513
  const frameSize = options.frameSize ?? samplesForDuration(sampleRate, DEFAULT_FRAME_DURATION_MS);
554
514
  validateEncodeFrameSize(frameSize, sampleRate, "frameSize");
555
515
  if (options.maxBandwidth !== undefined) {
@@ -564,7 +524,7 @@ function normalizeEncoderOptions(options) {
564
524
  throw new RangeError("signal must be Signal.Auto, Signal.Voice, or Signal.Music");
565
525
  }
566
526
  return {
567
- application: options.application ?? Application.Audio,
527
+ application,
568
528
  bitrate: normalizeBitrate(options.bitrate ?? 64_000),
569
529
  channels,
570
530
  complexity,
@@ -608,7 +568,7 @@ function normalizeBitrate(bitrate) {
608
568
  if (bitrate === Bitrate.Auto || bitrate === Bitrate.Max) {
609
569
  return bitrate;
610
570
  }
611
- validatePositiveInteger(bitrate, "bitrate");
571
+ validateIntegerRange(bitrate, 1, MAX_I32, "bitrate");
612
572
  return bitrate;
613
573
  }
614
574
  function validateBandwidth(bandwidth, name) {
@@ -646,11 +606,6 @@ function validateInteger(value, name) {
646
606
  throw new RangeError(`${name} must be an integer`);
647
607
  }
648
608
  }
649
- function validatePositiveInteger(value, name) {
650
- if (!Number.isInteger(value) || value <= 0) {
651
- throw new RangeError(`${name} must be a positive integer`);
652
- }
653
- }
654
609
  function validateIntegerRange(value, min, max, name) {
655
610
  if (!Number.isInteger(value) || value < min || value > max) {
656
611
  throw new RangeError(`${name} must be an integer from ${min} to ${max}`);
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "libopus-wasm",
3
- "version": "0.4.0",
3
+ "version": "0.4.1",
4
4
  "description": "Small, modern WASM bindings for libopus raw packet encode/decode.",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -36,11 +36,11 @@
36
36
  ],
37
37
  "devDependencies": {
38
38
  "@discordjs/opus": "0.10.0",
39
- "@types/node": "26.4.1",
40
- "@vitest/coverage-v8": "5.0.0",
39
+ "@types/node": "26.6.2",
40
+ "@vitest/coverage-v8": "5.0.1",
41
41
  "typescript": "^7.0.2",
42
- "vite": "8.2.2",
43
- "vitest": "5.0.0"
42
+ "vite": "8.3.0",
43
+ "vitest": "5.0.1"
44
44
  },
45
45
  "engines": {
46
46
  "node": ">=22"
@@ -378,7 +378,16 @@ The `body` mixins are the most common way to format the request/response body. M
378
378
  > The body returned from `undici.request` does not implement `.formData()`.
379
379
 
380
380
  > [!WARNING]
381
- > Calling `body.formData()` on a fetch response causes undici to buffer and parse the entire body. Since this is dictated by the spec, `body.formData()` must only be called on responses from trusted servers.
381
+ > The body mixins `.arrayBuffer()`, `.blob()`, `.bytes()`, `.json()`, `.text()`,
382
+ > and `.formData()` buffer the entire body in memory before returning. Where
383
+ > applicable, they also decode or parse the payload and retain that
384
+ > representation in memory. Calling these methods therefore means trusting that
385
+ > the response body is small enough to fit in the available memory. Do not use
386
+ > them for responses from untrusted or user-controlled sources. Instead, consume
387
+ > the response body as a stream and enforce an application-specific size limit:
388
+ > use `response.body` for fetch responses or the `body` returned by
389
+ > `undici.request()`. For streaming decoded text, use `body.textStream()` on a
390
+ > fetch `Request` or `Response`.
382
391
 
383
392
  Example usage:
384
393
 
@@ -56,16 +56,16 @@ changes:
56
56
  `Infinity`, no limit is enforced. Must be a number greater than `0`.
57
57
  **Default:** `Infinity`.
58
58
 
59
- `Agent` inherits all {PoolOptions} (and therefore all {ClientOptions}). The
60
- per-origin {Pool} it creates uses the default unlimited `connections`, so
61
- concurrent requests to the same origin are spread across separate {Client}
62
- instances on separate sockets.
59
+ `Agent` inherits all {PoolOptions} (and therefore all {ClientOptions}). Each
60
+ origin gets a separate {Pool}, with `connections` acting as the maximum number
61
+ of clients that pool may create.
63
62
 
64
63
  > [!NOTE]
65
- > Because each concurrent request to an origin may use a different {Client},
66
- > HTTP/2 multiplexing on a shared session does not apply unless `connections` is
67
- > set to a small value (for example `connections: 1`). See {PoolOptions} and
68
- > {ClientOptions} for the full set of inherited options such as `allowH2`
64
+ > For an h2-capable HTTPS origin, the per-origin pool waits for the first TLS
65
+ > connection to finish ALPN negotiation. If the server selects h2, concurrent
66
+ > requests share that session up to `maxConcurrentStreams`. If it selects
67
+ > HTTP/1.1, normal connection fan-out resumes up to `connections`. See
68
+ > {PoolOptions} and {ClientOptions} for inherited options such as `allowH2`
69
69
  > (default `true`) and `maxConcurrentStreams` (default `100`).
70
70
 
71
71
  ### `agent.closed`
@@ -120,7 +120,8 @@ diagnosticsChannel.channel('undici:request:bodySent').subscribe(({ request }) =>
120
120
  added: v6.3.0
121
121
  -->
122
122
 
123
- Published after the response headers have been received.
123
+ Published after the response headers have been received. This includes a
124
+ successful CONNECT or protocol upgrade response.
124
125
 
125
126
  * `message` {Object}
126
127
  * `request` {Object} The same object published by
@@ -128,8 +129,9 @@ Published after the response headers have been received.
128
129
  * `response` {Object} The response being received.
129
130
  * `statusCode` {number} The HTTP status code.
130
131
  * `statusText` {string} The HTTP status message.
131
- * `headers` {Buffer[]} The raw response headers as an array of buffers,
132
- alternating between header name and value.
132
+ * `headers` {Buffer[]|Object} HTTP/1.1 response headers are an array of
133
+ buffers alternating between header name and value. HTTP/2 response
134
+ headers are an object.
133
135
 
134
136
  ```mjs
135
137
  import diagnosticsChannel from 'node:diagnostics_channel'
@@ -137,7 +139,7 @@ import diagnosticsChannel from 'node:diagnostics_channel'
137
139
  diagnosticsChannel.channel('undici:request:headers').subscribe(({ request, response }) => {
138
140
  console.log('statusCode', response.statusCode)
139
141
  console.log(response.statusText)
140
- console.log(response.headers.map((x) => x.toString()))
142
+ console.log(response.headers)
141
143
  })
142
144
  ```
143
145
 
@@ -168,8 +170,9 @@ diagnosticsChannel.channel('undici:request:bodyChunkReceived').subscribe(({ requ
168
170
  added: v6.3.0
169
171
  -->
170
172
 
171
- Published after the response body and trailers have been received, that is, once
172
- the response has fully completed.
173
+ Published once the response has fully completed. After an upgraded socket has
174
+ been passed to the request handler, this event is published with an empty
175
+ `trailers` array.
173
176
 
174
177
  * `message` {Object}
175
178
  * `request` {Object} The same object published by
@@ -466,6 +466,15 @@ example, calling `text()` after `json()` throws a `TypeError`. The body also
466
466
  provides `dump({ limit })`, which discards up to `limit` bytes (default
467
467
  `131072`) without destroying the socket.
468
468
 
469
+ > [!WARNING]
470
+ > The `arrayBuffer()`, `blob()`, `bytes()`, `json()`, and `text()` methods buffer
471
+ > the entire body in memory before returning. Where applicable, they also decode
472
+ > or parse the payload and retain that representation in memory. Calling these
473
+ > methods therefore means trusting that the body is small enough to fit in the
474
+ > available memory. Do not use them for bodies received from untrusted or
475
+ > user-controlled sources. Instead, process `body` as a `Readable` stream and
476
+ > enforce an application-specific size limit.
477
+
469
478
  The body is always a `Readable`, even when empty. Deserializing an empty body
470
479
  with `json()` throws. To guard against this, verify the status code is not `204`
471
480
  and the `content-type` header starts with `application/json` before calling
@@ -446,6 +446,31 @@ The response returned an error status code. This is raised, for example, when th
446
446
  * `headers` {Object|string[]|null} The response headers. (optional)
447
447
  * `body` {Object|string|null} The response body. (optional)
448
448
 
449
+ ## Class: `ProxyConnectionError`
450
+
451
+ <!-- YAML
452
+ added: v8.10.1
453
+ changes:
454
+ - version: v8.10.1
455
+ pr-url: https://github.com/nodejs/undici/pull/5707
456
+ description: Added to fail the request instead of retrying forever when the proxy connection is torn down.
457
+ -->
458
+
459
+ * Extends: {UndiciError}
460
+
461
+ A connection to the proxy failed in a way that cannot be recovered on the
462
+ same connection, so the request fails instead of being retried.
463
+
464
+ * `name` {string} Always `'ProxyConnectionError'`.
465
+ * `code` {string} Always `'UND_ERR_PRX_CONN'`.
466
+ * `cause` {Error} The underlying error that caused the proxy connection to fail.
467
+
468
+ ### `new ProxyConnectionError(cause[, message[, options]])`
469
+
470
+ * `cause` {Error} The underlying error. (optional)
471
+ * `message` {string} The error message. (optional)
472
+ * `options` {Object} Additional `Error` options merged with `cause`. (optional)
473
+
449
474
  ## Class: `SecureProxyConnectionError`
450
475
 
451
476
  <!-- YAML
@@ -596,6 +596,16 @@ properties for reading a body. Each consuming method reads the body once; after
596
596
  the body has been consumed, [`bodyUsed`](#bodybodyused) becomes `true` and
597
597
  calling another consuming method throws a `TypeError`.
598
598
 
599
+ > [!WARNING]
600
+ > The `arrayBuffer()`, `blob()`, `bytes()`, `formData()`, `json()`, and `text()`
601
+ > methods buffer the entire body in memory before returning. Where applicable,
602
+ > they also decode or parse the payload and retain that representation in
603
+ > memory. Calling these methods therefore means trusting that the body is small
604
+ > enough to fit in the available memory. Do not use them for bodies received
605
+ > from untrusted or user-controlled sources. Instead, process `body.body` or
606
+ > `body.textStream()` incrementally and enforce an application-specific size
607
+ > limit.
608
+
599
609
  ### `body.arrayBuffer()`
600
610
 
601
611
  <!-- YAML
@@ -210,9 +210,10 @@ Automatically decompresses response bodies encoded with `gzip`, `x-gzip`,
210
210
  skipped. **Default:** `[204, 304]`.
211
211
  * `skipErrorResponses` {boolean} When `true`, responses with a status code
212
212
  >= 400 are not decompressed. **Default:** `true`.
213
- * `maxSize` {number} Maximum decompressed response size in bytes. The request
214
- fails with a `ResponseExceededMaxSizeError` if the decoded body exceeds
215
- this limit. **Default:** `67108864` (64 MiB).
213
+ * `maxSize` {number} Maximum decompressed response size in bytes for each
214
+ decompression stage. The request fails with a
215
+ `ResponseExceededMaxSizeError` if a stage exceeds this limit. Set to `0` to
216
+ disable the limit. **Default:** `0`.
216
217
 
217
218
  **Returns:** {Dispatcher.DispatcherComposeInterceptor}
218
219
 
@@ -73,12 +73,11 @@ connector shared by every pooled client.
73
73
 
74
74
  > [!NOTE]
75
75
  > `Pool` inherits all {ClientOptions}, including `allowH2` and
76
- > `maxConcurrentStreams`. With the default unlimited `connections`, the pool
77
- > opens a new client - and therefore a new TCP/TLS socket - per concurrent
78
- > dispatch, which defeats HTTP/2 multiplexing over a shared session. To benefit
79
- > from h2 multiplexing on a single session, cap `connections` (for example
80
- > `connections: 1`) so that concurrent requests share a session up to
81
- > `maxConcurrentStreams`.
76
+ > `maxConcurrentStreams`. For an h2-capable HTTPS origin, the pool waits for
77
+ > the first TLS connection to finish ALPN negotiation before opening more
78
+ > clients. If the server selects h2, concurrent requests share that session up
79
+ > to `maxConcurrentStreams`. If it selects HTTP/1.1, the pool resumes normal
80
+ > connection fan-out up to `connections`.
82
81
 
83
82
  ```mjs
84
83
  import { Pool } from 'undici'
@@ -380,7 +380,16 @@ The `body` mixins are the most common way to format the request/response body. M
380
380
  > The body returned from `undici.request` does not implement `.formData()`.
381
381
 
382
382
  > [!WARNING]
383
- > Calling `body.formData()` on a fetch response causes undici to buffer and parse the entire body. Since this is dictated by the spec, `body.formData()` must only be called on responses from trusted servers.
383
+ > The body mixins `.arrayBuffer()`, `.blob()`, `.bytes()`, `.json()`, `.text()`,
384
+ > and `.formData()` buffer the entire body in memory before returning. Where
385
+ > applicable, they also decode or parse the payload and retain that
386
+ > representation in memory. Calling these methods therefore means trusting that
387
+ > the response body is small enough to fit in the available memory. Do not use
388
+ > them for responses from untrusted or user-controlled sources. Instead, consume
389
+ > the response body as a stream and enforce an application-specific size limit:
390
+ > use `response.body` for fetch responses or the `body` returned by
391
+ > `undici.request()`. For streaming decoded text, use `body.textStream()` on a
392
+ > fetch `Request` or `Response`.
384
393
 
385
394
  Example usage:
386
395
 
@@ -5,7 +5,6 @@ const { addAbortListener } = require('node:events')
5
5
  const { Readable } = require('node:stream')
6
6
  const { RequestAbortedError, NotSupportedError, InvalidArgumentError, AbortError } = require('../core/errors')
7
7
  const util = require('../core/util')
8
- const { ReadableStreamFrom } = require('../core/util')
9
8
 
10
9
  const kConsume = Symbol('kConsume')
11
10
  const kReading = Symbol('kReading')
@@ -246,7 +245,7 @@ class BodyReadable extends Readable {
246
245
  */
247
246
  get body () {
248
247
  if (!this[kBody]) {
249
- this[kBody] = ReadableStreamFrom(this)
248
+ this[kBody] = ReadableStream.from(this)
250
249
  if (this[kConsume]) {
251
250
  // TODO: Is this the best way to force a lock?
252
251
  this[kBody].getReader() // Ensure stream is locked.
@@ -368,10 +368,22 @@ class Request {
368
368
  }
369
369
  }
370
370
 
371
- onRequestUpgrade (statusCode, headers, socket) {
371
+ /**
372
+ * @param {number} statusCode
373
+ * @param {Buffer[]|string[]|import('../../types/header.d.ts').IncomingHttpHeaders} headers
374
+ * @param {import('node:stream').Duplex} socket
375
+ * @param {string} [statusText]
376
+ */
377
+ onRequestUpgrade (statusCode, headers, socket, statusText = '') {
378
+ this.onFinally()
379
+
372
380
  assert(!this.aborted)
373
381
  assert(!this.completed)
374
382
 
383
+ if (channels.headers.hasSubscribers) {
384
+ channels.headers.publish({ request: this, response: { statusCode, headers, statusText } })
385
+ }
386
+
375
387
  const controller = this[kController]
376
388
  if (controller) {
377
389
  controller.rawHeaders = headers
@@ -379,7 +391,16 @@ class Request {
379
391
 
380
392
  const parsedHeaders = Array.isArray(headers) ? parseHeaders(headers) : headers
381
393
 
382
- return this[kHandler].onRequestUpgrade?.(controller, statusCode, parsedHeaders, socket)
394
+ const result = this[kHandler].onRequestUpgrade?.(controller, statusCode, parsedHeaders, socket)
395
+
396
+ if (!this.aborted) {
397
+ this.completed = true
398
+ if (channels.trailers.hasSubscribers) {
399
+ channels.trailers.publish({ request: this, trailers: [] })
400
+ }
401
+ }
402
+
403
+ return result
383
404
  }
384
405
 
385
406
  onResponseEnd (trailers) {
@@ -644,44 +644,6 @@ function getSocketInfo (socket) {
644
644
  }
645
645
  }
646
646
 
647
- /**
648
- * @param {Iterable} iterable
649
- * @returns {ReadableStream}
650
- */
651
- function ReadableStreamFrom (iterable) {
652
- // We cannot use ReadableStream.from here because it does not return a byte stream.
653
-
654
- let iterator
655
- return new ReadableStream(
656
- {
657
- start () {
658
- iterator = iterable[Symbol.asyncIterator]()
659
- },
660
- pull (controller) {
661
- return iterator.next().then(({ done, value }) => {
662
- if (done) {
663
- return queueMicrotask(() => {
664
- controller.close()
665
- controller.byobRequest?.respond(0)
666
- })
667
- } else {
668
- const buf = Buffer.isBuffer(value) ? value : Buffer.from(value)
669
- if (buf.byteLength) {
670
- return controller.enqueue(new Uint8Array(buf))
671
- } else {
672
- return this.pull(controller)
673
- }
674
- }
675
- })
676
- },
677
- cancel () {
678
- return iterator.return()
679
- },
680
- type: 'bytes'
681
- }
682
- )
683
- }
684
-
685
647
  /**
686
648
  * The object should be a FormData instance and contains all the required
687
649
  * methods.
@@ -1026,7 +988,6 @@ module.exports = {
1026
988
  destroy,
1027
989
  bodyLength,
1028
990
  deepClone,
1029
- ReadableStreamFrom,
1030
991
  isBuffer,
1031
992
  assertRequestHandler,
1032
993
  getSocketInfo,