@openclaw/whatsapp 2026.5.31-beta.2 → 2026.5.31-beta.4

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 (112) hide show
  1. package/dist/api.js +8 -8
  2. package/dist/{channel-DA2BAIo5.js → channel-BbtRTgNk.js} +1 -1
  3. package/dist/channel-plugin-api.js +1 -1
  4. package/dist/{channel.runtime-Q1LZDB5s.js → channel.runtime-Cf2UgrhZ.js} +3 -3
  5. package/dist/{channel.setup-DHXOo4h5.js → channel.setup-DaIyWos-.js} +1 -1
  6. package/dist/{connection-controller-Bnm4INld.js → connection-controller-B07CNCkw.js} +1 -1
  7. package/dist/{login-2fuBM7Je.js → login-CRtqboZq.js} +2 -2
  8. package/dist/{login-qr-B1o7GFy8.js → login-qr-B27eAPhh.js} +8 -4
  9. package/dist/login-qr-runtime.js +5 -5
  10. package/dist/{monitor-BVRq04Dt.js → monitor-CnioHf5V.js} +34 -28
  11. package/dist/runtime-api.js +3 -3
  12. package/dist/{session-DyGWNClj.js → session-mBuvPUCy.js} +27 -18
  13. package/dist/{setup-core-OvPMaAsx.js → setup-core-C3XZ2KBH.js} +5 -5
  14. package/dist/{setup-finalize-Dk23pfKc.js → setup-finalize-B7FVDzwJ.js} +2 -2
  15. package/dist/setup-plugin-api.js +1 -1
  16. package/dist/{setup-surface-F-jVrH8u.js → setup-surface-CGTWO_-E.js} +1 -1
  17. package/node_modules/audio-buffer/.eslintrc.json +44 -0
  18. package/node_modules/audio-buffer/.github/workflows/node.js.yml +31 -0
  19. package/node_modules/audio-buffer/.travis.yml +7 -0
  20. package/node_modules/{@audio/decode-opus → audio-buffer}/LICENSE +2 -5
  21. package/node_modules/audio-buffer/index.js +76 -0
  22. package/node_modules/audio-buffer/package.json +37 -0
  23. package/node_modules/audio-buffer/readme.md +56 -0
  24. package/node_modules/audio-decode/.eslintrc.json +43 -0
  25. package/node_modules/audio-decode/.github/workflows/test.js.yml +20 -11
  26. package/node_modules/audio-decode/.travis.yml +13 -0
  27. package/node_modules/audio-decode/audio-decode.d.ts +10 -48
  28. package/node_modules/audio-decode/audio-decode.js +77 -193
  29. package/node_modules/audio-decode/package.json +21 -49
  30. package/node_modules/audio-decode/readme.md +29 -129
  31. package/node_modules/audio-decode/tea.yaml +6 -0
  32. package/node_modules/audio-decode/test-case.js +11 -0
  33. package/node_modules/audio-decode/test.html +10 -29
  34. package/node_modules/audio-decode/test.js +107 -0
  35. package/node_modules/node-wav/README.md +35 -0
  36. package/node_modules/node-wav/file.wav +0 -0
  37. package/node_modules/node-wav/index.js +291 -0
  38. package/node_modules/node-wav/package.json +29 -0
  39. package/node_modules/node-wav/tests/file1.wav +0 -0
  40. package/node_modules/node-wav/tests/test.js +66 -0
  41. package/node_modules/node-wav/x.js +12 -0
  42. package/node_modules/node-wav/x.json +86702 -0
  43. package/node_modules/node-wav/x.js~ +13 -0
  44. package/npm-shrinkwrap.json +32 -149
  45. package/package.json +5 -5
  46. package/node_modules/@audio/decode-aac/LICENSE +0 -9
  47. package/node_modules/@audio/decode-aac/README.md +0 -60
  48. package/node_modules/@audio/decode-aac/decode-aac.d.ts +0 -16
  49. package/node_modules/@audio/decode-aac/decode-aac.js +0 -391
  50. package/node_modules/@audio/decode-aac/package.json +0 -47
  51. package/node_modules/@audio/decode-aac/src/aac.wasm.cjs +0 -0
  52. package/node_modules/@audio/decode-aiff/LICENSE +0 -21
  53. package/node_modules/@audio/decode-aiff/README.md +0 -53
  54. package/node_modules/@audio/decode-aiff/decode-aiff.d.ts +0 -16
  55. package/node_modules/@audio/decode-aiff/decode-aiff.js +0 -583
  56. package/node_modules/@audio/decode-aiff/package.json +0 -42
  57. package/node_modules/@audio/decode-amr/LICENSE +0 -191
  58. package/node_modules/@audio/decode-amr/README.md +0 -65
  59. package/node_modules/@audio/decode-amr/decode-amr.d.ts +0 -16
  60. package/node_modules/@audio/decode-amr/decode-amr.js +0 -159
  61. package/node_modules/@audio/decode-amr/package.json +0 -48
  62. package/node_modules/@audio/decode-amr/src/amr.wasm.cjs +0 -0
  63. package/node_modules/@audio/decode-caf/LICENSE +0 -21
  64. package/node_modules/@audio/decode-caf/README.md +0 -55
  65. package/node_modules/@audio/decode-caf/decode-caf.d.ts +0 -16
  66. package/node_modules/@audio/decode-caf/decode-caf.js +0 -190
  67. package/node_modules/@audio/decode-caf/package.json +0 -43
  68. package/node_modules/@audio/decode-flac/LICENSE +0 -25
  69. package/node_modules/@audio/decode-flac/README.md +0 -23
  70. package/node_modules/@audio/decode-flac/decode-flac.d.ts +0 -16
  71. package/node_modules/@audio/decode-flac/decode-flac.js +0 -2994
  72. package/node_modules/@audio/decode-flac/meta.js +0 -115
  73. package/node_modules/@audio/decode-flac/package.json +0 -49
  74. package/node_modules/@audio/decode-mp3/LICENSE +0 -25
  75. package/node_modules/@audio/decode-mp3/README.md +0 -23
  76. package/node_modules/@audio/decode-mp3/decode-mp3.d.ts +0 -16
  77. package/node_modules/@audio/decode-mp3/decode-mp3.js +0 -868
  78. package/node_modules/@audio/decode-mp3/meta.js +0 -143
  79. package/node_modules/@audio/decode-mp3/package.json +0 -50
  80. package/node_modules/@audio/decode-opus/README.md +0 -23
  81. package/node_modules/@audio/decode-opus/decode-opus.d.ts +0 -16
  82. package/node_modules/@audio/decode-opus/decode-opus.js +0 -3179
  83. package/node_modules/@audio/decode-opus/package.json +0 -47
  84. package/node_modules/@audio/decode-qoa/LICENSE +0 -25
  85. package/node_modules/@audio/decode-qoa/README.md +0 -21
  86. package/node_modules/@audio/decode-qoa/decode-qoa.d.ts +0 -16
  87. package/node_modules/@audio/decode-qoa/decode-qoa.js +0 -278
  88. package/node_modules/@audio/decode-qoa/package.json +0 -46
  89. package/node_modules/@audio/decode-vorbis/LICENSE +0 -25
  90. package/node_modules/@audio/decode-vorbis/README.md +0 -23
  91. package/node_modules/@audio/decode-vorbis/decode-vorbis.d.ts +0 -16
  92. package/node_modules/@audio/decode-vorbis/decode-vorbis.js +0 -2984
  93. package/node_modules/@audio/decode-vorbis/package.json +0 -47
  94. package/node_modules/@audio/decode-wav/decode-wav.js +0 -104
  95. package/node_modules/@audio/decode-wav/meta.js +0 -114
  96. package/node_modules/@audio/decode-wav/package.json +0 -27
  97. package/node_modules/@audio/decode-webm/LICENSE +0 -21
  98. package/node_modules/@audio/decode-webm/README.md +0 -57
  99. package/node_modules/@audio/decode-webm/decode-webm.d.ts +0 -16
  100. package/node_modules/@audio/decode-webm/decode-webm.js +0 -3964
  101. package/node_modules/@audio/decode-webm/package.json +0 -51
  102. package/node_modules/@audio/decode-wma/LICENSE +0 -12
  103. package/node_modules/@audio/decode-wma/README.md +0 -76
  104. package/node_modules/@audio/decode-wma/decode-wma.d.ts +0 -33
  105. package/node_modules/@audio/decode-wma/decode-wma.js +0 -525
  106. package/node_modules/@audio/decode-wma/package.json +0 -47
  107. package/node_modules/@audio/decode-wma/src/wma.wasm.cjs +0 -0
  108. package/node_modules/audio-decode/.claude/settings.json +0 -204
  109. package/node_modules/audio-decode/.gitmodules +0 -9
  110. package/node_modules/audio-decode/meta.js +0 -11
  111. package/node_modules/audio-decode/stream.d.ts +0 -15
  112. package/node_modules/audio-decode/stream.js +0 -1
package/dist/api.js CHANGED
@@ -4,16 +4,16 @@ import { a as normalizeWhatsAppAllowFromEntries, c as normalizeWhatsAppTarget, i
4
4
  import { t as resolveWhatsAppOutboundTarget } from "./resolve-outbound-target-CcdugbDf.js";
5
5
  import "./send-DSlVXKL_.js";
6
6
  import { c as assertWebChannel, d as markdownToWhatsApp, f as resolveJidToE164, l as isSelfChatMode, m as toWhatsappJidWithLid, n as normalizeE164, p as toWhatsappJid, r as resolveUserPath, u as jidToE164 } from "./text-runtime-Dk37KYHj.js";
7
- import { n as WHATSAPP_LEGACY_OUTBOUND_SEND_DEP_KEYS, t as whatsappPlugin } from "./channel-DA2BAIo5.js";
7
+ import { n as WHATSAPP_LEGACY_OUTBOUND_SEND_DEP_KEYS, t as whatsappPlugin } from "./channel-BbtRTgNk.js";
8
8
  import { t as whatsappCommandPolicy } from "./command-policy-BIOSHySD.js";
9
- import { a as resolveWhatsAppGroupRequireMention, o as resolveWhatsAppGroupToolPolicy, s as resolveWhatsAppGroupIntroHint } from "./setup-core-OvPMaAsx.js";
9
+ import { a as resolveWhatsAppGroupRequireMention, o as resolveWhatsAppGroupToolPolicy, s as resolveWhatsAppGroupIntroHint } from "./setup-core-C3XZ2KBH.js";
10
10
  import "./config-schema-CROZuhT-.js";
11
- import { t as whatsappSetupPlugin } from "./channel.setup-DHXOo4h5.js";
11
+ import { t as whatsappSetupPlugin } from "./channel.setup-DaIyWos-.js";
12
12
  import { t as DEFAULT_WEB_MEDIA_BYTES } from "./constants-HU41RHGI.js";
13
13
  import { n as listWhatsAppDirectoryGroupsFromConfig, r as listWhatsAppDirectoryPeersFromConfig } from "./directory-config-Dijefxc3.js";
14
14
  import { n as testing } from "./access-control-C53zKYSN.js";
15
15
  import { m as extractText, t as createWebSendApi } from "./send-api-Bjn-h80j.js";
16
- import { r as waitForWaConnection, t as createWaSocket } from "./session-DyGWNClj.js";
16
+ import { r as waitForWaConnection, t as createWaSocket } from "./session-mBuvPUCy.js";
17
17
  import "openclaw/plugin-sdk/channel-actions";
18
18
  import "openclaw/plugin-sdk/account-resolution";
19
19
  import "openclaw/plugin-sdk/core";
@@ -105,18 +105,18 @@ async function startWhatsAppQaDriverSession(params) {
105
105
  async sendText(to, text) {
106
106
  return { messageId: (await sendApi.sendMessage(to, text)).messageId };
107
107
  },
108
- async waitForMessage(params) {
109
- const existing = observedMessages.find(params.match);
108
+ async waitForMessage(paramsLocal) {
109
+ const existing = observedMessages.find(paramsLocal.match);
110
110
  if (existing) return existing;
111
111
  return await new Promise((resolve, reject) => {
112
112
  const waiter = {
113
- predicate: params.match,
113
+ predicate: paramsLocal.match,
114
114
  resolve,
115
115
  reject,
116
116
  timeout: setTimeout(() => {
117
117
  removeWaiter(waiter);
118
118
  reject(/* @__PURE__ */ new Error("timed out waiting for WhatsApp QA driver message"));
119
- }, params.timeoutMs)
119
+ }, paramsLocal.timeoutMs)
120
120
  };
121
121
  waiters.push(waiter);
122
122
  });
@@ -9,7 +9,7 @@ import { p as toWhatsappJid } from "./text-runtime-Dk37KYHj.js";
9
9
  import { t as createWhatsAppLoginTool } from "./agent-tools-login-BX7eHgDm.js";
10
10
  import { i as lookupInboundMessageMetaForTarget } from "./quoted-message-CveINB35.js";
11
11
  import { t as whatsappCommandPolicy } from "./command-policy-BIOSHySD.js";
12
- import { a as resolveWhatsAppGroupRequireMention, c as resolveWhatsAppMentionStripRegexes, i as whatsappSetupWizardProxy, l as formatWhatsAppConfigAllowFromEntries, n as createWhatsAppPluginBase, o as resolveWhatsAppGroupToolPolicy, r as loadWhatsAppChannelRuntime, s as resolveWhatsAppGroupIntroHint, t as whatsappSetupAdapter } from "./setup-core-OvPMaAsx.js";
12
+ import { a as resolveWhatsAppGroupRequireMention, c as resolveWhatsAppMentionStripRegexes, i as whatsappSetupWizardProxy, l as formatWhatsAppConfigAllowFromEntries, n as createWhatsAppPluginBase, o as resolveWhatsAppGroupToolPolicy, r as loadWhatsAppChannelRuntime, s as resolveWhatsAppGroupIntroHint, t as whatsappSetupAdapter } from "./setup-core-C3XZ2KBH.js";
13
13
  import { f as readWebAuthExistsForDecision, n as WHATSAPP_AUTH_UNSTABLE_CODE } from "./auth-store-CZ22aNcV.js";
14
14
  import { t as detectWhatsAppLegacyStateMigrations } from "./state-migrations-D_BmQUR9.js";
15
15
  import { createActionGate as createActionGate$1 } from "openclaw/plugin-sdk/channel-actions";
@@ -1,2 +1,2 @@
1
- import { t as whatsappPlugin } from "./channel-DA2BAIo5.js";
1
+ import { t as whatsappPlugin } from "./channel-BbtRTgNk.js";
2
2
  export { whatsappPlugin };
@@ -1,9 +1,9 @@
1
1
  import { startWebLoginWithQr as startWebLoginWithQr$1, waitForWebLogin as waitForWebLogin$1 } from "./login-qr-runtime.js";
2
2
  import { c as logoutWeb$1, d as readWebAuthExistsBestEffort$1, f as readWebAuthExistsForDecision$1, g as readWebSelfId$1, h as readWebAuthState$1, m as readWebAuthSnapshotBestEffort$1, o as getWebAuthAgeMs$1, p as readWebAuthSnapshot$1, s as logWebSelfId$1, x as webAuthExists$1 } from "./auth-store-CZ22aNcV.js";
3
3
  import { t as getActiveWebListener$1 } from "./active-listener-CFwkn3ho.js";
4
- import { t as monitorWebChannel$1 } from "./monitor-BVRq04Dt.js";
5
- import { t as loginWeb$1 } from "./login-2fuBM7Je.js";
6
- import { whatsappSetupWizard as whatsappSetupWizard$1 } from "./setup-surface-F-jVrH8u.js";
4
+ import { t as monitorWebChannel$1 } from "./monitor-CnioHf5V.js";
5
+ import { t as loginWeb$1 } from "./login-CRtqboZq.js";
6
+ import { whatsappSetupWizard as whatsappSetupWizard$1 } from "./setup-surface-CGTWO_-E.js";
7
7
  //#region extensions/whatsapp/src/channel.runtime.ts
8
8
  function getActiveWebListener(...args) {
9
9
  return getActiveWebListener$1(...args);
@@ -1,4 +1,4 @@
1
- import { a as resolveWhatsAppGroupRequireMention, i as whatsappSetupWizardProxy, n as createWhatsAppPluginBase, o as resolveWhatsAppGroupToolPolicy, s as resolveWhatsAppGroupIntroHint, t as whatsappSetupAdapter } from "./setup-core-OvPMaAsx.js";
1
+ import { a as resolveWhatsAppGroupRequireMention, i as whatsappSetupWizardProxy, n as createWhatsAppPluginBase, o as resolveWhatsAppGroupToolPolicy, s as resolveWhatsAppGroupIntroHint, t as whatsappSetupAdapter } from "./setup-core-C3XZ2KBH.js";
2
2
  import { t as detectWhatsAppLegacyStateMigrations } from "./state-migrations-D_BmQUR9.js";
3
3
  //#region extensions/whatsapp/src/channel.setup.ts
4
4
  async function isWhatsAppAuthConfigured(account) {
@@ -1,6 +1,6 @@
1
1
  import { a as unregisterWhatsAppConnectionController, i as registerWhatsAppConnectionController, n as getStatusCode, t as formatError } from "./session-errors-CbsoQqoy.js";
2
2
  import { c as logoutWeb } from "./auth-store-CZ22aNcV.js";
3
- import { r as waitForWaConnection, t as createWaSocket } from "./session-DyGWNClj.js";
3
+ import { r as waitForWaConnection, t as createWaSocket } from "./session-mBuvPUCy.js";
4
4
  import { computeBackoff, info, sleepWithAbort } from "openclaw/plugin-sdk/runtime-env";
5
5
  import { clamp } from "openclaw/plugin-sdk/text-utility-runtime";
6
6
  import { DisconnectReason } from "baileys";
@@ -1,8 +1,8 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.js";
2
2
  import { a as resolveWhatsAppAccount } from "./accounts-DgViSyJx.js";
3
3
  import { b as restoreCredsFromBackupIfNeeded } from "./auth-store-CZ22aNcV.js";
4
- import { a as renderQrTerminal, i as resolveWhatsAppSocketTiming, t as createWaSocket } from "./session-DyGWNClj.js";
5
- import { a as closeWaSocketSoon, o as waitForWhatsAppLoginResult } from "./connection-controller-Bnm4INld.js";
4
+ import { a as renderQrTerminal, i as resolveWhatsAppSocketTiming, t as createWaSocket } from "./session-mBuvPUCy.js";
5
+ import { a as closeWaSocketSoon, o as waitForWhatsAppLoginResult } from "./connection-controller-B07CNCkw.js";
6
6
  import { formatCliCommand } from "openclaw/plugin-sdk/cli-runtime";
7
7
  import { logInfo } from "openclaw/plugin-sdk/logging-core";
8
8
  import { danger, defaultRuntime, success } from "openclaw/plugin-sdk/runtime-env";
@@ -1,7 +1,7 @@
1
1
  import { a as resolveWhatsAppAccount } from "./accounts-DgViSyJx.js";
2
2
  import { f as readWebAuthExistsForDecision, g as readWebSelfId, n as WHATSAPP_AUTH_UNSTABLE_CODE } from "./auth-store-CZ22aNcV.js";
3
- import { i as resolveWhatsAppSocketTiming, t as createWaSocket } from "./session-DyGWNClj.js";
4
- import { i as closeWaSocket, o as waitForWhatsAppLoginResult, t as WHATSAPP_LOGGED_OUT_QR_MESSAGE } from "./connection-controller-Bnm4INld.js";
3
+ import { i as resolveWhatsAppSocketTiming, t as createWaSocket } from "./session-mBuvPUCy.js";
4
+ import { i as closeWaSocket, o as waitForWhatsAppLoginResult, t as WHATSAPP_LOGGED_OUT_QR_MESSAGE } from "./connection-controller-B07CNCkw.js";
5
5
  import { logInfo } from "openclaw/plugin-sdk/logging-core";
6
6
  import { danger, defaultRuntime, info, success } from "openclaw/plugin-sdk/runtime-env";
7
7
  import { renderQrPngDataUrl } from "openclaw/plugin-sdk/media-runtime";
@@ -10,7 +10,9 @@ import { randomUUID } from "node:crypto";
10
10
  import { getRuntimeConfig } from "openclaw/plugin-sdk/runtime-config-snapshot";
11
11
  //#region extensions/whatsapp/src/login-qr.ts
12
12
  function waitForNextTask() {
13
- return new Promise((resolve) => setImmediate(resolve));
13
+ return new Promise((resolve) => {
14
+ setImmediate(resolve);
15
+ });
14
16
  }
15
17
  const ACTIVE_LOGIN_TTL_MS = 3 * 6e4;
16
18
  const MAX_QR_RENDER_CHASES = 10;
@@ -376,7 +378,9 @@ async function waitForWebLogin(opts = {}) {
376
378
  connected: false,
377
379
  message: "Still waiting for the QR scan. Let me know when you’ve scanned it."
378
380
  };
379
- const timeout = new Promise((resolve) => setTimeout(() => resolve("timeout"), remaining));
381
+ const timeout = new Promise((resolve) => {
382
+ setTimeout(() => resolve("timeout"), remaining);
383
+ });
380
384
  const result = await Promise.race([
381
385
  login.waitPromise.then(() => "done"),
382
386
  login.qrUpdatePromise.then(() => "qr-update"),
@@ -1,16 +1,16 @@
1
1
  //#region extensions/whatsapp/login-qr-runtime.ts
2
2
  let loginQrModulePromise = null;
3
3
  function loadLoginQrModule() {
4
- loginQrModulePromise ??= import("./login-qr-B1o7GFy8.js");
4
+ loginQrModulePromise ??= import("./login-qr-B27eAPhh.js");
5
5
  return loginQrModulePromise;
6
6
  }
7
7
  async function startWebLoginWithQr(...args) {
8
- const { startWebLoginWithQr } = await loadLoginQrModule();
9
- return await startWebLoginWithQr(...args);
8
+ const { startWebLoginWithQr: startWebLoginWithQrLocal } = await loadLoginQrModule();
9
+ return await startWebLoginWithQrLocal(...args);
10
10
  }
11
11
  async function waitForWebLogin(...args) {
12
- const { waitForWebLogin } = await loadLoginQrModule();
13
- return await waitForWebLogin(...args);
12
+ const { waitForWebLogin: waitForWebLoginLocal } = await loadLoginQrModule();
13
+ return await waitForWebLoginLocal(...args);
14
14
  }
15
15
  //#endregion
16
16
  export { startWebLoginWithQr, waitForWebLogin };
@@ -10,12 +10,12 @@ import { a as getSelfIdentity, c as resolveComparableIdentity, i as getReplyCont
10
10
  import { n as resolveWhatsAppGroupsConfigPath } from "./group-config-path-BGyzT9Lg.js";
11
11
  import { i as resolveWhatsAppInboundPolicy, r as resolveWhatsAppCommandAuthorized, t as checkInboundAccessControl } from "./access-control-C53zKYSN.js";
12
12
  import { a as mayContainWhatsAppOutboundMention, c as describeReplyContext, d as extractLocationData, f as extractMediaPlaceholder, h as hasInboundUserContent, i as addWhatsAppOutboundMentionsToContent, l as extractContactContext, m as extractText, n as listWhatsAppSendResultMessageIds, o as resolveWhatsAppOutboundMentions, p as extractMentionedJids, r as normalizeWhatsAppSendResult, s as addWhatsAppImagePreviewFields, t as createWebSendApi, u as extractContextInfo } from "./send-api-Bjn-h80j.js";
13
- import { i as resolveWhatsAppSocketTiming, r as waitForWaConnection, t as createWaSocket } from "./session-DyGWNClj.js";
13
+ import { i as resolveWhatsAppSocketTiming, r as waitForWaConnection, t as createWaSocket } from "./session-mBuvPUCy.js";
14
14
  import { t as BufferJSON } from "./session.runtime-LZFdq3yb.js";
15
- import { c as computeBackoff, d as resolveReconnectPolicy, f as sleepWithAbort, l as newConnectionId, n as WHATSAPP_WATCHDOG_TIMEOUT_ERROR, r as WhatsAppConnectionController, s as DEFAULT_RECONNECT_POLICY, u as resolveHeartbeatSeconds } from "./connection-controller-Bnm4INld.js";
15
+ import { c as computeBackoff, d as resolveReconnectPolicy, f as sleepWithAbort, l as newConnectionId, n as WHATSAPP_WATCHDOG_TIMEOUT_ERROR, r as WhatsAppConnectionController, s as DEFAULT_RECONNECT_POLICY, u as resolveHeartbeatSeconds } from "./connection-controller-B07CNCkw.js";
16
16
  import { resolveAccountEntry } from "openclaw/plugin-sdk/account-core";
17
17
  import { normalizeLowercaseStringOrEmpty, normalizeStringEntries, uniqueStrings } from "openclaw/plugin-sdk/string-coerce-runtime";
18
- import { createChannelMessageReplyPipeline, createDurableInboundReceiveJournal, createMessageReceiptFromOutboundResults, deliverInboundReplyWithMessageSendContext, resolveChannelMessageSourceReplyDeliveryMode } from "openclaw/plugin-sdk/channel-outbound";
18
+ import { createChannelMessageReplyPipeline, createDurableInboundReceiveJournalFromQueue, createMessageReceiptFromOutboundResults, deliverInboundReplyWithMessageSendContext, resolveChannelMessageSourceReplyDeliveryMode } from "openclaw/plugin-sdk/channel-outbound";
19
19
  import { filterSupplementalContextItems, resolvePinnedMainDmOwnerFromAllowlist } from "openclaw/plugin-sdk/security-runtime";
20
20
  import { DEFAULT_TIMING, createAckReactionHandle, createStatusReactionController, logAckFailure, removeAckReactionHandleAfterReply, shouldAckReactionForWhatsApp } from "openclaw/plugin-sdk/channel-feedback";
21
21
  import { formatCliCommand } from "openclaw/plugin-sdk/cli-runtime";
@@ -159,21 +159,21 @@ function deserializeWhatsAppDurableInboundMessage(message) {
159
159
  return JSON.parse(JSON.stringify(message), BufferJSON.reviver);
160
160
  }
161
161
  function createWhatsAppDurableInboundReceiveJournal(accountId) {
162
- const runtime = getWhatsAppRuntime();
163
162
  const accountPart = hashNamespacePart(accountId);
164
- return createDurableInboundReceiveJournal({
165
- pendingStore: runtime.state.openKeyedStore({
166
- namespace: `inbound.v1.pending.${accountPart}`,
167
- maxEntries: WHATSAPP_DURABLE_INBOUND_PENDING_MAX_ENTRIES,
168
- defaultTtlMs: WHATSAPP_DURABLE_INBOUND_PENDING_TTL_MS
169
- }),
170
- completedStore: runtime.state.openKeyedStore({
171
- namespace: `inbound.v1.completed.${accountPart}`,
172
- maxEntries: WHATSAPP_DURABLE_INBOUND_COMPLETED_MAX_ENTRIES,
173
- defaultTtlMs: WHATSAPP_DURABLE_INBOUND_COMPLETED_TTL_MS
163
+ const runtime = getWhatsAppRuntime();
164
+ return createDurableInboundReceiveJournalFromQueue({
165
+ queue: runtime.state.openChannelIngressQueue({
166
+ accountId: accountPart,
167
+ stateDir: runtime.state.resolveStateDir()
174
168
  }),
175
- pendingTtlMs: WHATSAPP_DURABLE_INBOUND_PENDING_TTL_MS,
176
- completedTtlMs: WHATSAPP_DURABLE_INBOUND_COMPLETED_TTL_MS
169
+ retention: {
170
+ pendingTtlMs: WHATSAPP_DURABLE_INBOUND_PENDING_TTL_MS,
171
+ completedTtlMs: WHATSAPP_DURABLE_INBOUND_COMPLETED_TTL_MS,
172
+ failedTtlMs: WHATSAPP_DURABLE_INBOUND_PENDING_TTL_MS,
173
+ pendingMaxEntries: WHATSAPP_DURABLE_INBOUND_PENDING_MAX_ENTRIES,
174
+ completedMaxEntries: WHATSAPP_DURABLE_INBOUND_COMPLETED_MAX_ENTRIES,
175
+ failedMaxEntries: WHATSAPP_DURABLE_INBOUND_PENDING_MAX_ENTRIES
176
+ }
177
177
  });
178
178
  }
179
179
  //#endregion
@@ -766,12 +766,12 @@ async function attachWebInboxToSocket(options) {
766
766
  logWhatsAppVerbose(options.verbose, `Presence update failed: ${String(err)}`);
767
767
  }
768
768
  };
769
- const reply = async (text, options) => {
769
+ const reply = async (text, optionsResult) => {
770
770
  const resolved = await resolveOutboundMentionsForGroup(chatJid, text);
771
- return normalizeWhatsAppSendResult(await sendTrackedMessage(chatJid, addWhatsAppOutboundMentionsToContent({ text: resolved.text }, resolved.mentionedJids), options), "text");
771
+ return normalizeWhatsAppSendResult(await sendTrackedMessage(chatJid, addWhatsAppOutboundMentionsToContent({ text: resolved.text }, resolved.mentionedJids), optionsResult), "text");
772
772
  };
773
- const sendMedia = async (payload, options) => {
774
- return normalizeWhatsAppSendResult(await sendTrackedMessage(chatJid, await applyOutboundMentionsToContent(chatJid, await addWhatsAppImagePreviewFields(payload)), options), "media");
773
+ const sendMedia = async (payload, optionsValue) => {
774
+ return normalizeWhatsAppSendResult(await sendTrackedMessage(chatJid, await applyOutboundMentionsToContent(chatJid, await addWhatsAppImagePreviewFields(payload)), optionsValue), "media");
775
775
  };
776
776
  const timestamp = inbound.messageTimestampMs;
777
777
  const mentionedJids = extractMentionedJids(msg.message);
@@ -983,11 +983,11 @@ async function attachWebInboxToSocket(options) {
983
983
  },
984
984
  ...createWebSendApi({
985
985
  sock: {
986
- sendMessage: (jid, content, options) => sendTrackedMessage(jid, content, options),
987
- sendPresenceUpdate: async (presence, jid) => {
986
+ sendMessage: (jid, content, optionsLocal) => sendTrackedMessage(jid, content, optionsLocal),
987
+ sendPresenceUpdate: async (presenceLocal, jid) => {
988
988
  const currentSock = getCurrentSock();
989
989
  if (!currentSock) throw new Error(RECONNECT_IN_PROGRESS_ERROR);
990
- return currentSock.sendPresenceUpdate(presence, jid);
990
+ return currentSock.sendPresenceUpdate(presenceLocal, jid);
991
991
  }
992
992
  },
993
993
  defaultAccountId: options.accountId,
@@ -2384,7 +2384,9 @@ async function finalizeWhatsAppStatusReaction(params) {
2384
2384
  if (params.outcome === "done") {
2385
2385
  await params.controller.setDone();
2386
2386
  if (params.removeAckAfterReply) {
2387
- await new Promise((resolve) => setTimeout(resolve, params.timing.doneHoldMs));
2387
+ await new Promise((resolve) => {
2388
+ setTimeout(resolve, params.timing.doneHoldMs);
2389
+ });
2388
2390
  await params.controller.clear();
2389
2391
  } else await params.controller.restoreInitial();
2390
2392
  return;
@@ -2392,12 +2394,16 @@ async function finalizeWhatsAppStatusReaction(params) {
2392
2394
  await params.controller.setError();
2393
2395
  if (params.hasFinalResponse) {
2394
2396
  if (params.removeAckAfterReply) {
2395
- await new Promise((resolve) => setTimeout(resolve, params.timing.errorHoldMs));
2397
+ await new Promise((resolve) => {
2398
+ setTimeout(resolve, params.timing.errorHoldMs);
2399
+ });
2396
2400
  await params.controller.clear();
2397
2401
  } else await params.controller.restoreInitial();
2398
2402
  return;
2399
2403
  }
2400
- if (params.removeAckAfterReply) await new Promise((resolve) => setTimeout(resolve, params.timing.errorHoldMs));
2404
+ if (params.removeAckAfterReply) await new Promise((resolve) => {
2405
+ setTimeout(resolve, params.timing.errorHoldMs);
2406
+ });
2401
2407
  await params.controller.restoreInitial();
2402
2408
  }
2403
2409
  //#endregion
@@ -3235,7 +3241,7 @@ async function monitorWebChannel(verbose, listenerFactory = attachWebInboxToSock
3235
3241
  try {
3236
3242
  connection = await controller.openConnection({
3237
3243
  connectionId,
3238
- createListener: async ({ sock, connection }) => {
3244
+ createListener: async ({ sock, connection: connectionLocal }) => {
3239
3245
  const onMessage = createWebOnMessageHandler({
3240
3246
  cfg,
3241
3247
  loadConfig: loadCurrentMonitorConfig,
@@ -3246,7 +3252,7 @@ async function monitorWebChannel(verbose, listenerFactory = attachWebInboxToSock
3246
3252
  groupHistories,
3247
3253
  groupMemberNames,
3248
3254
  echoTracker,
3249
- backgroundTasks: connection.backgroundTasks,
3255
+ backgroundTasks: connectionLocal.backgroundTasks,
3250
3256
  replyResolver: activeReplyResolver,
3251
3257
  replyLogger,
3252
3258
  baseMentionConfig,
@@ -8,9 +8,9 @@ import { t as createWhatsAppLoginTool } from "./agent-tools-login-BX7eHgDm.js";
8
8
  import { C as waitForCredsSaveQueue, T as writeCredsJsonAtomically, _ as readWebSelfIdentity, a as formatWhatsAppWebAuthStatusState, b as restoreCredsFromBackupIfNeeded, c as logoutWeb, d as readWebAuthExistsBestEffort, f as readWebAuthExistsForDecision, g as readWebSelfId, h as readWebAuthState, l as pickWebChannel, m as readWebAuthSnapshotBestEffort, n as WHATSAPP_AUTH_UNSTABLE_CODE, o as getWebAuthAgeMs, p as readWebAuthSnapshot, r as WhatsAppAuthUnstableError, s as logWebSelfId, t as WA_WEB_AUTH_DIR, u as readCredsJsonRaw, v as readWebSelfIdentityForDecision, w as waitForCredsSaveQueueWithTimeout, x as webAuthExists, y as resolveDefaultWebAuthDir } from "./auth-store-CZ22aNcV.js";
9
9
  import { t as DEFAULT_WEB_MEDIA_BYTES } from "./constants-HU41RHGI.js";
10
10
  import { d as extractLocationData, f as extractMediaPlaceholder, l as extractContactContext, m as extractText } from "./send-api-Bjn-h80j.js";
11
- import { n as newConnectionId, r as waitForWaConnection, t as createWaSocket } from "./session-DyGWNClj.js";
11
+ import { n as newConnectionId, r as waitForWaConnection, t as createWaSocket } from "./session-mBuvPUCy.js";
12
12
  import { n as resolveWebAccountId, t as getActiveWebListener } from "./active-listener-CFwkn3ho.js";
13
- import { a as loadWebMediaRaw, c as monitorWebInbox, i as loadWebMedia, l as resetWebInboundDedupe, n as LocalMediaAccessError, o as optimizeImageToJpeg, r as getDefaultLocalRoots, s as optimizeImageToPng, t as monitorWebChannel } from "./monitor-BVRq04Dt.js";
14
- import { t as loginWeb } from "./login-2fuBM7Je.js";
13
+ import { a as loadWebMediaRaw, c as monitorWebInbox, i as loadWebMedia, l as resetWebInboundDedupe, n as LocalMediaAccessError, o as optimizeImageToJpeg, r as getDefaultLocalRoots, s as optimizeImageToPng, t as monitorWebChannel } from "./monitor-CnioHf5V.js";
14
+ import { t as loginWeb } from "./login-CRtqboZq.js";
15
15
  import { HEARTBEAT_PROMPT, HEARTBEAT_TOKEN, SILENT_REPLY_TOKEN, stripHeartbeatToken } from "openclaw/plugin-sdk/reply-runtime";
16
16
  export { DEFAULT_WEB_MEDIA_BYTES, HEARTBEAT_PROMPT, HEARTBEAT_TOKEN, LocalMediaAccessError, SILENT_REPLY_TOKEN, WA_WEB_AUTH_DIR, WHATSAPP_AUTH_UNSTABLE_CODE, WhatsAppAuthUnstableError, createWaSocket, createWhatsAppLoginTool, extractContactContext, extractLocationData, extractMediaPlaceholder, extractText, formatError, formatWhatsAppWebAuthStatusState, getActiveWebListener, getDefaultLocalRoots, getStatusCode, getWebAuthAgeMs, handleWhatsAppAction, hasWebCredsSync, loadWebMedia, loadWebMediaRaw, logWebSelfId, loginWeb, logoutWeb, monitorWebChannel, monitorWebInbox, newConnectionId, optimizeImageToJpeg, optimizeImageToPng, pickWebChannel, readCredsJsonRaw, readWebAuthExistsBestEffort, readWebAuthExistsForDecision, readWebAuthSnapshot, readWebAuthSnapshotBestEffort, readWebAuthState, readWebSelfId, readWebSelfIdentity, readWebSelfIdentityForDecision, resetWebInboundDedupe, resolveDefaultWebAuthDir, resolveWebAccountId, resolveWebCredsBackupPath, resolveWebCredsPath, restoreCredsFromBackupIfNeeded, sendMessageWhatsApp, sendPollWhatsApp, sendReactionWhatsApp, sendTypingWhatsApp, setWhatsAppRuntime, startWebLoginWithQr, stripHeartbeatToken, waitForCredsSaveQueue, waitForCredsSaveQueueWithTimeout, waitForWaConnection, waitForWebLogin, webAuthExists, whatsAppActionRuntime, writeCredsJsonAtomically };
@@ -110,25 +110,27 @@ async function createWaSocket(printQr, verbose, opts = {}) {
110
110
  fetchAgent
111
111
  });
112
112
  sock.ev.on("creds.update", () => enqueueSaveCreds(authDir, saveCreds, sessionLogger));
113
- sock.ev.on("connection.update", async (update) => {
114
- try {
115
- const { connection, lastDisconnect, qr } = update;
116
- if (qr) {
117
- opts.onQr?.(qr);
118
- if (printQr) {
119
- console.log("Open the WhatsApp app, go to Linked Devices, then scan this QR:");
120
- printTerminalQr(qr).catch((err) => {
121
- sessionLogger.warn({ error: String(err) }, "failed rendering WhatsApp QR");
122
- });
113
+ sock.ev.on("connection.update", (update) => {
114
+ (async () => {
115
+ try {
116
+ const { connection, lastDisconnect, qr } = update;
117
+ if (qr) {
118
+ opts.onQr?.(qr);
119
+ if (printQr) {
120
+ console.log("Open the WhatsApp app, go to Linked Devices, then scan this QR:");
121
+ printTerminalQr(qr).catch((err) => {
122
+ sessionLogger.warn({ error: String(err) }, "failed rendering WhatsApp QR");
123
+ });
124
+ }
123
125
  }
126
+ if (connection === "close") {
127
+ if (getStatusCode(lastDisconnect?.error) === LOGGED_OUT_STATUS) console.error(danger(`WhatsApp session logged out. Run: ${formatCliCommand("openclaw channels login")}`));
128
+ }
129
+ if (connection === "open" && verbose) console.log(success("WhatsApp Web connected."));
130
+ } catch (err) {
131
+ sessionLogger.error({ error: String(err) }, "connection.update handler error");
124
132
  }
125
- if (connection === "close") {
126
- if (getStatusCode(lastDisconnect?.error) === LOGGED_OUT_STATUS) console.error(danger(`WhatsApp session logged out. Run: ${formatCliCommand("openclaw channels login")}`));
127
- }
128
- if (connection === "open" && verbose) console.log(success("WhatsApp Web connected."));
129
- } catch (err) {
130
- sessionLogger.error({ error: String(err) }, "connection.update handler error");
131
- }
133
+ })();
132
134
  });
133
135
  if (sock.ws && typeof sock.ws.on === "function") sock.ws.on("error", (err) => {
134
136
  sessionLogger.error({ error: String(err) }, "WebSocket error");
@@ -194,7 +196,7 @@ async function waitForWaConnection(sock) {
194
196
  }
195
197
  if (update.connection === "close") {
196
198
  evWithOff.off?.("connection.update", handler);
197
- reject(update.lastDisconnect ?? /* @__PURE__ */ new Error("Connection closed"));
199
+ reject(toLintErrorObject(update.lastDisconnect ?? /* @__PURE__ */ new Error("Connection closed"), "Non-Error rejection"));
198
200
  }
199
201
  };
200
202
  sock.ev.on("connection.update", handler);
@@ -203,5 +205,12 @@ async function waitForWaConnection(sock) {
203
205
  function newConnectionId() {
204
206
  return randomUUID();
205
207
  }
208
+ function toLintErrorObject(value, fallbackMessage) {
209
+ if (value instanceof Error) return value;
210
+ if (typeof value === "string") return new Error(value);
211
+ const error = new Error(fallbackMessage, { cause: value });
212
+ if (typeof value === "object" && value !== null || typeof value === "function") Object.assign(error, value);
213
+ return error;
214
+ }
206
215
  //#endregion
207
216
  export { renderQrTerminal as a, resolveWhatsAppSocketTiming as i, newConnectionId as n, waitForWaConnection as r, createWaSocket as t };
@@ -99,10 +99,10 @@ async function applyWhatsAppSecurityConfigFixes(params) {
99
99
  //#region extensions/whatsapp/src/shared.ts
100
100
  const WHATSAPP_CHANNEL = "whatsapp";
101
101
  async function loadWhatsAppChannelRuntime() {
102
- return await import("./channel.runtime-Q1LZDB5s.js");
102
+ return await import("./channel.runtime-Cf2UgrhZ.js");
103
103
  }
104
104
  async function loadWhatsAppSetupSurface() {
105
- return await import("./setup-surface-F-jVrH8u.js");
105
+ return await import("./setup-surface-CGTWO_-E.js");
106
106
  }
107
107
  const whatsappSetupWizardProxy = createWhatsAppSetupWizardProxy(async () => (await loadWhatsAppSetupSurface()).whatsappSetupWizard);
108
108
  const whatsappConfigAdapter = createScopedChannelConfigAdapter({
@@ -265,9 +265,9 @@ function createWhatsAppPluginBase(params) {
265
265
  deriveLegacySessionChatType,
266
266
  resolveLegacyGroupSessionKey,
267
267
  isLegacyGroupSessionKey,
268
- canonicalizeLegacySessionKey: (params) => canonicalizeLegacySessionKey({
269
- key: params.key,
270
- agentId: params.agentId
268
+ canonicalizeLegacySessionKey: (paramsLocal) => canonicalizeLegacySessionKey({
269
+ key: paramsLocal.key,
270
+ agentId: paramsLocal.agentId
271
271
  })
272
272
  },
273
273
  secrets: {
@@ -2,7 +2,7 @@ import { r as resolveDefaultWhatsAppAccountId } from "./account-ids-CB5SOWjc.js"
2
2
  import { r as hasWebCredsSync } from "./creds-files-B1kSWtBg.js";
3
3
  import { a as resolveWhatsAppAccount, o as resolveWhatsAppAuthDir } from "./accounts-DgViSyJx.js";
4
4
  import { a as normalizeWhatsAppAllowFromEntries, o as normalizeWhatsAppAllowFromEntry } from "./normalize-target-bVWjgftN.js";
5
- import { t as whatsappSetupAdapter } from "./setup-core-OvPMaAsx.js";
5
+ import { t as whatsappSetupAdapter } from "./setup-core-C3XZ2KBH.js";
6
6
  import { DEFAULT_ACCOUNT_ID, createSetupTranslator, splitSetupEntries } from "openclaw/plugin-sdk/setup";
7
7
  import { formatCliCommand, formatDocsLink } from "openclaw/plugin-sdk/setup-tools";
8
8
  //#region extensions/whatsapp/src/setup-finalize.ts
@@ -280,7 +280,7 @@ async function finalizeWhatsAppSetup(params) {
280
280
  message: linked ? t("wizard.whatsapp.relinkPrompt") : t("wizard.whatsapp.linkNowPrompt"),
281
281
  initialValue: !linked
282
282
  })) try {
283
- const { loginWeb } = await import("./login-2fuBM7Je.js").then((n) => n.n);
283
+ const { loginWeb } = await import("./login-CRtqboZq.js").then((n) => n.n);
284
284
  await loginWeb(false, void 0, params.runtime, accountId);
285
285
  } catch (error) {
286
286
  params.runtime.error(`WhatsApp login failed: ${String(error)}`);
@@ -1,2 +1,2 @@
1
- import { t as whatsappSetupPlugin } from "./channel.setup-DHXOo4h5.js";
1
+ import { t as whatsappSetupPlugin } from "./channel.setup-DaIyWos-.js";
2
2
  export { whatsappSetupPlugin };
@@ -36,7 +36,7 @@ const whatsappSetupWizard = {
36
36
  },
37
37
  resolveShouldPromptAccountIds: ({ shouldPromptAccountIds }) => shouldPromptAccountIds,
38
38
  credentials: [],
39
- finalize: async (params) => await (await import("./setup-finalize-Dk23pfKc.js")).finalizeWhatsAppSetup(params),
39
+ finalize: async (params) => await (await import("./setup-finalize-B7FVDzwJ.js")).finalizeWhatsAppSetup(params),
40
40
  disable: (cfg) => setSetupChannelEnabled(cfg, channel, false),
41
41
  onAccountRecorded: (accountId, options) => {
42
42
  options?.onAccountId?.(channel, accountId);
@@ -0,0 +1,44 @@
1
+ {
2
+ "env": {
3
+ "browser": true,
4
+ "node": true,
5
+ "commonjs": true,
6
+ "es6": true
7
+ },
8
+ "extends": "eslint:recommended",
9
+ "rules": {
10
+ "strict": 2,
11
+ "indent": 0,
12
+ "linebreak-style": 0,
13
+ "quotes": 0,
14
+ "semi": 0,
15
+ "no-cond-assign": 1,
16
+ "no-constant-condition": 1,
17
+ "no-duplicate-case": 1,
18
+ "no-empty": 1,
19
+ "no-ex-assign": 1,
20
+ "no-extra-boolean-cast": 1,
21
+ "no-extra-semi": 1,
22
+ "no-fallthrough": 1,
23
+ "no-func-assign": 1,
24
+ "no-global-assign": 1,
25
+ "no-implicit-globals": 2,
26
+ "no-inner-declarations": ["error", "functions"],
27
+ "no-irregular-whitespace": 2,
28
+ "no-loop-func": 1,
29
+ "no-magic-numbers": ["warn", { "ignore": [1, 0, -1], "ignoreArrayIndexes": true}],
30
+ "no-multi-str": 1,
31
+ "no-mixed-spaces-and-tabs": 1,
32
+ "no-proto": 1,
33
+ "no-sequences": 1,
34
+ "no-throw-literal": 1,
35
+ "no-unmodified-loop-condition": 1,
36
+ "no-useless-call": 1,
37
+ "no-void": 1,
38
+ "no-with": 2,
39
+ "wrap-iife": 1,
40
+ "no-redeclare": 1,
41
+ "no-unused-vars": ["error", { "vars": "all", "args": "none" }],
42
+ "no-sparse-arrays": 1
43
+ }
44
+ }
@@ -0,0 +1,31 @@
1
+ # This workflow will do a clean installation of node dependencies, cache/restore them, build the source code and run tests across different versions of node
2
+ # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-nodejs
3
+
4
+ name: Test
5
+
6
+ on:
7
+ push:
8
+ branches: [ "master" ]
9
+ pull_request:
10
+ branches: [ "master" ]
11
+
12
+ jobs:
13
+ build:
14
+
15
+ runs-on: ubuntu-latest
16
+
17
+ strategy:
18
+ matrix:
19
+ node-version: [14.x, 16.x, 18.x]
20
+ # See supported Node.js release schedule at https://nodejs.org/en/about/releases/
21
+
22
+ steps:
23
+ - uses: actions/checkout@v3
24
+ - name: Use Node.js ${{ matrix.node-version }}
25
+ uses: actions/setup-node@v3
26
+ with:
27
+ node-version: ${{ matrix.node-version }}
28
+ cache: 'npm'
29
+ - run: npm ci
30
+ - run: npm run build --if-present
31
+ - run: npm test
@@ -0,0 +1,7 @@
1
+ sudo: false
2
+ language: node_js
3
+ node_js:
4
+ - 'node'
5
+ - '6'
6
+ - '5'
7
+ - '4'
@@ -1,10 +1,6 @@
1
- This work is offered to Krishna (https://github.com/krishnized/license).
2
-
3
- ---
4
-
5
1
  The MIT License (MIT)
2
+ Copyright (c) 2018 Dmitry Yvanov <df.creative@gmail.com>
6
3
 
7
- Copyright (c) 2025 audiojs
8
4
 
9
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
10
6
  of this software and associated documentation files (the "Software"), to deal
@@ -23,3 +19,4 @@ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
23
19
  DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
24
20
  OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
25
21
  OR OTHER DEALINGS IN THE SOFTWARE.
22
+
@@ -0,0 +1,76 @@
1
+ /**
2
+ * AudioBuffer class
3
+ */
4
+ export default class AudioBuffer {
5
+ /**
6
+ * Create AudioBuffer instance.
7
+ * @constructor
8
+ * @param {Object} options - buffer init options.
9
+ * @param {number} options.length - buffer length in samples.
10
+ * @param {number} options.sampleRate - buffer sample rate.
11
+ * @param {number} options.numberOfChannels - number of channels.
12
+ */
13
+ constructor(options) {
14
+ if (!options) throw TypeError('options argument is required')
15
+ if (!options.sampleRate) throw TypeError('options.sampleRate is required')
16
+ if (options.sampleRate < 3000 || options.sampleRate > 768000) throw TypeError('options.sampleRate must be within 3000..768000')
17
+ if (!options.length) throw TypeError('options.length must be more than 0')
18
+
19
+ this.sampleRate = options.sampleRate
20
+ this.numberOfChannels = options.numberOfChannels || 1
21
+ this.length = options.length | 0
22
+ this.duration = this.length / this.sampleRate
23
+
24
+ //data is stored as a planar sequence
25
+ this._data = new Float32Array(this.length * this.numberOfChannels)
26
+
27
+ //channels data is cached as subarrays
28
+ this._channelData = []
29
+ for (let c = 0; c < this.numberOfChannels; c++) {
30
+ this._channelData.push(this._data.subarray(c * this.length, (c+1) * this.length))
31
+ }
32
+ }
33
+
34
+ /**
35
+ * Return data associated with the channel.
36
+ * @param {number} channel - Channel index, starting from 0.
37
+ * @return {Float32Array} Array containing the data.
38
+ */
39
+ getChannelData (channel) {
40
+ if (channel >= this.numberOfChannels || channel < 0 || channel == null) throw Error('Cannot getChannelData: channel number (' + channel + ') exceeds number of channels (' + this.numberOfChannels + ')');
41
+
42
+ return this._channelData[channel]
43
+ }
44
+
45
+
46
+ /**
47
+ * Place data to the destination buffer, starting from the position.
48
+ * @param {Float32Array} destination - Destination array to write data to.
49
+ * @param {number} channelNumber - Channel to take data from.
50
+ * @param {number} startInChannel - Data offset in channel to read from.
51
+ */
52
+ copyFromChannel (destination, channelNumber, startInChannel) {
53
+ if (startInChannel == null) startInChannel = 0;
54
+ var data = this._channelData[channelNumber]
55
+ for (var i = startInChannel, j = 0; i < this.length && j < destination.length; i++, j++) {
56
+ destination[j] = data[i];
57
+ }
58
+ }
59
+
60
+
61
+ /**
62
+ * Place data from the source to the channel, starting (in self) from the position.
63
+ * @param {Float32Array | Array} source - source array to read data from.
64
+ * @param {number} channelNumber - channel index to copy data to.
65
+ * @param {number} startInChannel - offset in channel to copy data to.
66
+ */
67
+ copyToChannel (source, channelNumber, startInChannel) {
68
+ var data = this._channelData[channelNumber]
69
+
70
+ if (!startInChannel) startInChannel = 0;
71
+
72
+ for (var i = startInChannel, j = 0; i < this.length && j < source.length; i++, j++) {
73
+ data[i] = source[j];
74
+ }
75
+ }
76
+ }