bmlt-query-client 1.4.1 → 1.4.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.
- package/.claude/settings.local.json +12 -5
- package/CHANGELOG.md +8 -1
- package/CLAUDE.md +39 -0
- package/dist/app.d.ts +9 -3
- package/dist/app.js +12 -10
- package/dist/app.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,10 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"permissions": {
|
|
3
3
|
"allow": [
|
|
4
|
-
"Bash(
|
|
4
|
+
"Bash(npm view:*)",
|
|
5
|
+
"Bash(npm ls *)",
|
|
6
|
+
"Bash(curl -s https://raw.githubusercontent.com/qmhc/unplugin-dts/main/README.md)",
|
|
7
|
+
"Bash(curl -s https://raw.githubusercontent.com/qmhc/unplugin-dts/main/docs/en/migration-v4-to-v5.md)",
|
|
8
|
+
"Bash(npm run *)",
|
|
9
|
+
"Bash(npm test *)",
|
|
10
|
+
"Bash(tar -xzf bmlt-query-client-1.4.0.tgz)",
|
|
11
|
+
"Bash(grep -nA 12 '\"scripts\"' /Users/patrick/workspace/git/bmlt-enabled/bmlt-query-client/package.json)",
|
|
12
|
+
"Bash(grep -nA 3 \"interface Format\" /Users/patrick/workspace/git/bmlt-enabled/crumb-widget/node_modules/bmlt-query-client/dist/app.d.ts)",
|
|
13
|
+
"Bash(grep -nA 30 \"^function makeMeeting\\\\|^function rawMeeting\\\\|^function rawFormat\\\\|^function makeFormat\\\\|^ function makeGeoMeeting\\\\|^ function makeFormat\" src/tests/unit/format.test.ts src/tests/unit/data.svelte.test.ts src/tests/unit/Controls.svelte.test.ts)",
|
|
14
|
+
"Bash(grep -nA 30 \"^function makeMeeting\" src/tests/unit/MapView.svelte.test.ts src/tests/unit/MeetingDetail.svelte.test.ts src/tests/unit/MeetingList.svelte.test.ts)"
|
|
5
15
|
]
|
|
6
|
-
}
|
|
7
|
-
"disabledMcpjsonServers": [
|
|
8
|
-
"laravel-boost"
|
|
9
|
-
]
|
|
16
|
+
}
|
|
10
17
|
}
|
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,12 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [1.4.2] - 2026-05-19
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
|
|
13
|
+
- `countUniqueGroups` now matches crouton's long-standing definition: groups are identified by `(service_body, normalized meeting name, location)` — physical coordinates for in-person/hybrid (`venue_type !== 2`), virtual link + additional info for virtual (`venue_type === 2`). The previous algorithm keyed only on `(service_body, name)`, which under-counted whenever two distinct home groups happened to share a name but met at different locations (real-world example: MCANA returned 12 groups vs. crouton's 17 for the same 30 meetings). Bug; widget headers and downstream callers now agree with crouton.
|
|
14
|
+
|
|
9
15
|
## [1.4.1] - 2026-05-15
|
|
10
16
|
|
|
11
17
|
### Fixed
|
|
@@ -92,7 +98,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
|
92
98
|
- Zero external runtime dependencies — p-queue and p-retry are bundled via Vite.
|
|
93
99
|
- ES module only; native `fetch` API; TypeScript declarations included.
|
|
94
100
|
|
|
95
|
-
[Unreleased]: https://github.com/bmlt-enabled/bmlt-query-client/compare/v1.4.
|
|
101
|
+
[Unreleased]: https://github.com/bmlt-enabled/bmlt-query-client/compare/v1.4.2...HEAD
|
|
102
|
+
[1.4.2]: https://github.com/bmlt-enabled/bmlt-query-client/compare/v1.4.1...v1.4.2
|
|
96
103
|
[1.4.1]: https://github.com/bmlt-enabled/bmlt-query-client/compare/v1.4.0...v1.4.1
|
|
97
104
|
[1.4.0]: https://github.com/bmlt-enabled/bmlt-query-client/compare/v1.3.0...v1.4.0
|
|
98
105
|
[1.3.0]: https://github.com/bmlt-enabled/bmlt-query-client/compare/v1.2.0...v1.3.0
|
package/CLAUDE.md
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
## Project Overview
|
|
6
|
+
|
|
7
|
+
TypeScript client library for querying BMLT (Basic Meeting List Tool) servers with built-in Nominatim geocoding. Published to NPM as `bmlt-query-client`. ESM-only, targets Node.js 20+ and modern browsers (ES2020).
|
|
8
|
+
|
|
9
|
+
## Commands
|
|
10
|
+
|
|
11
|
+
- **Build:** `npm run build` (Vite → `dist/app.js` single ES module + type declarations)
|
|
12
|
+
- **Test:** `npm test` (Vitest, runs integration tests against live server `https://latest.aws.bmlt.app/main_server`)
|
|
13
|
+
- **Lint:** `npm run lint`
|
|
14
|
+
- **Format:** `npm run format` (Prettier) / `npm run format:check`
|
|
15
|
+
- **Type check:** `npm run type-check` (tsc --noEmit)
|
|
16
|
+
- **Clean:** `npm run clean` (removes dist/)
|
|
17
|
+
|
|
18
|
+
Tests hit a real BMLT server and Nominatim, so they require network access and have 15-second timeouts.
|
|
19
|
+
|
|
20
|
+
## Architecture
|
|
21
|
+
|
|
22
|
+
**Entry point:** `src/index.ts` — re-exports everything from the modules below.
|
|
23
|
+
|
|
24
|
+
**Core modules:**
|
|
25
|
+
|
|
26
|
+
- `src/client/bmlt-client.ts` — **BmltClient** class. Main API client wrapping all BMLT endpoints (searchMeetings, getFormats, getServiceBodies, getChanges, getFieldKeys, getFieldValues, getNAWSDump, getServerInfo, getCoverageArea). Also provides geocoded search methods (searchMeetingsByAddress, searchMeetingsByCoordinates) and reverse geocoding.
|
|
27
|
+
- `src/client/query-builder.ts` — **MeetingQueryBuilder** (fluent/chainable query API) and **QuickSearch** (convenience presets like today(), weekend(), virtual()). QueryBuilder holds a reference to BmltClient and delegates execution.
|
|
28
|
+
- `src/services/geocoding.ts` — **GeocodingService** wrapping Nominatim OpenStreetMap API with rate limiting (p-queue) and retry logic (p-retry).
|
|
29
|
+
- `src/utils/url-builder.ts` — URL construction and parameter validation for BMLT API calls.
|
|
30
|
+
- `src/utils/errors.ts` — **BmltQueryError** custom error class with BmltErrorType enum, plus ErrorFactory, ErrorHandler, and RetryHandler utilities.
|
|
31
|
+
- `src/types/` — TypeScript interfaces and enums: BmltDataFormat, BmltEndpoint, Weekday (1-7, Sun-Sat), VenueType (1-3), SortKey, Language, request/response interfaces.
|
|
32
|
+
|
|
33
|
+
**Build output:** Vite bundles all dependencies (including p-queue, p-retry) into a single `dist/app.js` with no externals, plus `dist/app.d.ts` type declarations.
|
|
34
|
+
|
|
35
|
+
## Code Style
|
|
36
|
+
|
|
37
|
+
- Strict TypeScript (`strict: true` in tsconfig)
|
|
38
|
+
- Prettier: single quotes, trailing commas (es5), 100 char print width, 2-space indent, no semicolons optional (semi: true)
|
|
39
|
+
- ESLint: prefer-const, no-var enforced
|
package/dist/app.d.ts
CHANGED
|
@@ -304,9 +304,15 @@ export declare interface Coordinates {
|
|
|
304
304
|
/**
|
|
305
305
|
* Count unique groups across a list of meetings.
|
|
306
306
|
*
|
|
307
|
-
* A "group" is identified by the combination of service body
|
|
308
|
-
* (case-insensitive, trimmed),
|
|
309
|
-
*
|
|
307
|
+
* A "group" is identified by the combination of service body, meeting name
|
|
308
|
+
* (case-insensitive, trimmed), and meeting location — physical coordinates
|
|
309
|
+
* for in-person/hybrid (venue_type !== 2), or the virtual meeting link plus
|
|
310
|
+
* additional info for virtual (venue_type === 2). Multiple weekly meetings of
|
|
311
|
+
* the same group count once; two distinct groups that happen to share a name
|
|
312
|
+
* but meet at different locations count separately. Matches the long-standing
|
|
313
|
+
* "group_id" definition used by crouton.
|
|
314
|
+
*
|
|
315
|
+
* Meetings missing a service body or name are skipped.
|
|
310
316
|
*/
|
|
311
317
|
export declare function countUniqueGroups(meetings: Meeting[]): number;
|
|
312
318
|
|
package/dist/app.js
CHANGED
|
@@ -555,7 +555,10 @@ var ye = /* @__PURE__ */ new WeakMap(), w = /* @__PURE__ */ new WeakMap(), T = /
|
|
|
555
555
|
return b(L, this) === b(R, this) && b(I, this).size > 0 || this.isRateLimited && b(I, this).size > 0;
|
|
556
556
|
}
|
|
557
557
|
get runningTasks() {
|
|
558
|
-
return [...b(B, this).values()].map((e) => ({
|
|
558
|
+
return [...b(B, this).values()].map((e) => ({
|
|
559
|
+
...e,
|
|
560
|
+
timeoutRemaining: e.timeout ? Math.max(0, e.startTime + e.timeout - Date.now()) : void 0
|
|
561
|
+
}));
|
|
559
562
|
}
|
|
560
563
|
};
|
|
561
564
|
function we(e) {
|
|
@@ -1517,15 +1520,14 @@ function pt(e, t = {}) {
|
|
|
1517
1520
|
return a;
|
|
1518
1521
|
}
|
|
1519
1522
|
function mt(e) {
|
|
1520
|
-
let t = /* @__PURE__ */ new
|
|
1521
|
-
for (let
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
return n;
|
|
1523
|
+
let t = /* @__PURE__ */ new Set();
|
|
1524
|
+
for (let n of e) {
|
|
1525
|
+
let e = n.service_body_bigint, r = n.meeting_name;
|
|
1526
|
+
if (!e || !r) continue;
|
|
1527
|
+
let i = r.trim().toLowerCase(), a = n.venue_type === 2 ? `${n.virtual_meeting_link ?? ""}|${n.virtual_meeting_additional_info ?? ""}` : `${n.latitude.toFixed(6)}|${n.longitude.toFixed(6)}`;
|
|
1528
|
+
t.add(`${e}|${i}|${a}`);
|
|
1529
|
+
}
|
|
1530
|
+
return t.size;
|
|
1529
1531
|
}
|
|
1530
1532
|
//#endregion
|
|
1531
1533
|
export { ct as BmltClient, q as BmltDataFormat, J as BmltEndpoint, Ue as BmltErrorType, G as BmltQueryError, K as ErrorFactory, We as ErrorHandler, Ke as GeocodingService, Je as Language, $ as MeetingQueryBuilder, lt as QuickSearch, Ge as RetryHandler, qe as SortKey, X as VenueType, Y as Weekday, Ye as buildBmltURL, mt as countUniqueGroups, $e as extractIds, pt as findDuplicateMeetings, et as formatTimeValue, rt as kilometersToMiles, nt as milesToKilometers, Xe as normalizeParameters, tt as validateCoordinates, Ze as validateEndpointFormat, Z as validateRadius, Qe as validateServerURL };
|
package/dist/app.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app.js","names":["EventEmitter"],"sources":["../node_modules/is-network-error/index.js","../node_modules/p-retry/index.js","../node_modules/eventemitter3/index.js","../node_modules/eventemitter3/index.mjs","../node_modules/p-timeout/index.js","../node_modules/p-queue/dist/lower-bound.js","../node_modules/p-queue/dist/priority-queue.js","../node_modules/p-queue/dist/index.js","../src/utils/errors.ts","../src/services/geocoding.ts","../src/types/base.ts","../src/utils/url-builder.ts","../src/utils/transforms.ts","../src/client/bmlt-client.ts","../src/client/query-builder.ts","../src/utils/meetings.ts"],"sourcesContent":["const objectToString = Object.prototype.toString;\n\nconst isError = value => objectToString.call(value) === '[object Error]';\n\nconst errorMessages = new Set([\n\t'network error', // Chrome\n\t'NetworkError when attempting to fetch resource.', // Firefox\n\t'The Internet connection appears to be offline.', // Safari 16\n\t'Network request failed', // `cross-fetch`\n\t'fetch failed', // Undici (Node.js)\n\t'terminated', // Undici (Node.js)\n\t' A network error occurred.', // Bun (WebKit)\n\t'Network connection lost', // Cloudflare Workers (fetch)\n]);\n\nexport default function isNetworkError(error) {\n\tconst isValid = error\n\t\t&& isError(error)\n\t\t&& error.name === 'TypeError'\n\t\t&& typeof error.message === 'string';\n\n\tif (!isValid) {\n\t\treturn false;\n\t}\n\n\tconst {message, stack} = error;\n\n\t// Safari 17+ has generic message but no stack for network errors\n\tif (message === 'Load failed' || (message.startsWith('Load failed (') && message.endsWith(')'))) {\n\t\treturn stack === undefined\n\t\t\t// Sentry adds its own stack trace to the fetch error, so also check for that\n\t\t\t|| '__sentry_captured__' in error;\n\t}\n\n\t// Deno network errors start with specific text\n\tif (message.startsWith('error sending request for url')) {\n\t\treturn true;\n\t}\n\n\t// Chrome: exact \"Failed to fetch\" or with hostname: \"Failed to fetch (example.com)\"\n\tif (message === 'Failed to fetch' || (message.startsWith('Failed to fetch (') && message.endsWith(')'))) {\n\t\treturn true;\n\t}\n\n\t// Standard network error messages\n\treturn errorMessages.has(message);\n}\n","import isNetworkError from 'is-network-error';\n\nfunction validateRetries(retries) {\n\tif (typeof retries === 'number') {\n\t\tif (retries < 0) {\n\t\t\tthrow new TypeError('Expected `retries` to be a non-negative number.');\n\t\t}\n\n\t\tif (Number.isNaN(retries)) {\n\t\t\tthrow new TypeError('Expected `retries` to be a valid number or Infinity, got NaN.');\n\t\t}\n\t} else if (retries !== undefined) {\n\t\tthrow new TypeError('Expected `retries` to be a number or Infinity.');\n\t}\n}\n\nfunction validateNumberOption(name, value, {min = 0, allowInfinity = false} = {}) {\n\tif (value === undefined) {\n\t\treturn;\n\t}\n\n\tif (typeof value !== 'number' || Number.isNaN(value)) {\n\t\tthrow new TypeError(`Expected \\`${name}\\` to be a number${allowInfinity ? ' or Infinity' : ''}.`);\n\t}\n\n\tif (!allowInfinity && !Number.isFinite(value)) {\n\t\tthrow new TypeError(`Expected \\`${name}\\` to be a finite number.`);\n\t}\n\n\tif (value < min) {\n\t\tthrow new TypeError(`Expected \\`${name}\\` to be \\u2265 ${min}.`);\n\t}\n}\n\nfunction validateFunctionOption(name, value) {\n\tif (value === undefined) {\n\t\treturn;\n\t}\n\n\tif (typeof value !== 'function') {\n\t\tthrow new TypeError(`Expected \\`${name}\\` to be a function.`);\n\t}\n}\n\nexport class AbortError extends Error {\n\tconstructor(message) {\n\t\tsuper();\n\n\t\tif (message instanceof Error) {\n\t\t\tthis.originalError = message;\n\t\t\t({message} = message);\n\t\t} else {\n\t\t\tthis.originalError = new Error(message);\n\t\t\tthis.originalError.stack = this.stack;\n\t\t}\n\n\t\tthis.name = 'AbortError';\n\t\tthis.message = message;\n\t}\n}\n\nfunction calculateDelay(retriesConsumed, options) {\n\tconst attempt = Math.max(1, retriesConsumed + 1);\n\tconst random = options.randomize ? (Math.random() + 1) : 1;\n\n\tlet timeout = Math.round(random * options.minTimeout * (options.factor ** (attempt - 1)));\n\ttimeout = Math.min(timeout, options.maxTimeout);\n\n\treturn timeout;\n}\n\nfunction calculateRemainingTime(start, max) {\n\tif (!Number.isFinite(max)) {\n\t\treturn max;\n\t}\n\n\treturn max - (performance.now() - start);\n}\n\nasync function delayForRetry(delay, options) {\n\tif (delay <= 0) {\n\t\treturn;\n\t}\n\n\tawait new Promise((resolve, reject) => {\n\t\tconst onAbort = () => {\n\t\t\tclearTimeout(timeoutToken);\n\t\t\toptions.signal?.removeEventListener('abort', onAbort);\n\t\t\treject(options.signal.reason);\n\t\t};\n\n\t\tconst timeoutToken = setTimeout(() => {\n\t\t\toptions.signal?.removeEventListener('abort', onAbort);\n\t\t\tresolve();\n\t\t}, delay);\n\n\t\tif (options.unref) {\n\t\t\ttimeoutToken.unref?.();\n\t\t}\n\n\t\toptions.signal?.addEventListener('abort', onAbort, {once: true});\n\t});\n}\n\nasync function onAttemptFailure({error, attemptNumber, retriesConsumed, startTime, options}) {\n\tconst normalizedError = error instanceof Error\n\t\t? error\n\t\t: new TypeError(`Non-error was thrown: \"${error}\". You should only throw errors.`);\n\n\tif (normalizedError instanceof AbortError) {\n\t\tthrow normalizedError.originalError;\n\t}\n\n\tconst retriesLeft = Number.isFinite(options.retries)\n\t\t? Math.max(0, options.retries - retriesConsumed)\n\t\t: options.retries;\n\n\tconst maxRetryTime = options.maxRetryTime ?? Number.POSITIVE_INFINITY;\n\tconst delayTime = calculateDelay(retriesConsumed, options);\n\tconst remainingTimeBeforeCallbacks = calculateRemainingTime(startTime, maxRetryTime);\n\n\tif (remainingTimeBeforeCallbacks <= 0) {\n\t\tconst context = Object.freeze({\n\t\t\terror: normalizedError,\n\t\t\tattemptNumber,\n\t\t\tretriesLeft,\n\t\t\tretriesConsumed,\n\t\t\tretryDelay: 0,\n\t\t});\n\n\t\tawait options.onFailedAttempt(context);\n\n\t\tthrow normalizedError;\n\t}\n\n\tconst consumeRetryContext = Object.freeze({\n\t\terror: normalizedError,\n\t\tattemptNumber,\n\t\tretriesLeft,\n\t\tretriesConsumed,\n\t\tretryDelay: retriesLeft > 0 ? delayTime : 0,\n\t});\n\n\tconst consumeRetry = await options.shouldConsumeRetry(consumeRetryContext);\n\tconst effectiveDelay = consumeRetry && retriesLeft > 0 ? delayTime : 0;\n\tconst context = Object.freeze({\n\t\terror: normalizedError,\n\t\tattemptNumber,\n\t\tretriesLeft,\n\t\tretriesConsumed,\n\t\tretryDelay: effectiveDelay,\n\t});\n\n\tawait options.onFailedAttempt(context);\n\n\tif (calculateRemainingTime(startTime, maxRetryTime) <= 0) {\n\t\tthrow normalizedError;\n\t}\n\n\tconst remainingTime = calculateRemainingTime(startTime, maxRetryTime);\n\n\tif (remainingTime <= 0 || retriesLeft <= 0) {\n\t\tthrow normalizedError;\n\t}\n\n\tif (normalizedError instanceof TypeError && !isNetworkError(normalizedError)) {\n\t\tthrow normalizedError;\n\t}\n\n\tif (!await options.shouldRetry(context)) {\n\t\tthrow normalizedError;\n\t}\n\n\tconst remainingTimeAfterShouldRetry = calculateRemainingTime(startTime, maxRetryTime);\n\n\tif (remainingTimeAfterShouldRetry <= 0) {\n\t\tthrow normalizedError;\n\t}\n\n\tif (!consumeRetry) {\n\t\toptions.signal?.throwIfAborted();\n\t\treturn false;\n\t}\n\n\tconst finalDelay = Math.min(effectiveDelay, remainingTimeAfterShouldRetry);\n\n\toptions.signal?.throwIfAborted();\n\n\tawait delayForRetry(finalDelay, options);\n\n\toptions.signal?.throwIfAborted();\n\n\treturn true;\n}\n\nexport default async function pRetry(input, options = {}) {\n\toptions = {...options};\n\n\tvalidateRetries(options.retries);\n\n\tif (Object.hasOwn(options, 'forever')) {\n\t\tthrow new Error('The `forever` option is no longer supported. For many use-cases, you can set `retries: Infinity` instead.');\n\t}\n\n\toptions.retries ??= 10;\n\toptions.factor ??= 2;\n\toptions.minTimeout ??= 1000;\n\toptions.maxTimeout ??= Number.POSITIVE_INFINITY;\n\toptions.maxRetryTime ??= Number.POSITIVE_INFINITY;\n\toptions.randomize ??= false;\n\toptions.onFailedAttempt ??= () => {};\n\toptions.shouldRetry ??= () => true;\n\toptions.shouldConsumeRetry ??= () => true;\n\n\t// Validate numeric options and normalize edge cases\n\tvalidateFunctionOption('onFailedAttempt', options.onFailedAttempt);\n\tvalidateFunctionOption('shouldRetry', options.shouldRetry);\n\tvalidateFunctionOption('shouldConsumeRetry', options.shouldConsumeRetry);\n\tvalidateNumberOption('factor', options.factor, {min: 0, allowInfinity: false});\n\tvalidateNumberOption('minTimeout', options.minTimeout, {min: 0, allowInfinity: false});\n\tvalidateNumberOption('maxTimeout', options.maxTimeout, {min: 0, allowInfinity: true});\n\tvalidateNumberOption('maxRetryTime', options.maxRetryTime, {min: 0, allowInfinity: true});\n\n\t// Treat non-positive factor as 1 to avoid zero backoff or negative behavior\n\tif (!(options.factor > 0)) {\n\t\toptions.factor = 1;\n\t}\n\n\toptions.signal?.throwIfAborted();\n\n\tlet attemptNumber = 0;\n\tlet retriesConsumed = 0;\n\tconst startTime = performance.now();\n\n\twhile (Number.isFinite(options.retries) ? retriesConsumed <= options.retries : true) {\n\t\tattemptNumber++;\n\n\t\ttry {\n\t\t\toptions.signal?.throwIfAborted();\n\n\t\t\tconst result = await input(attemptNumber);\n\n\t\t\toptions.signal?.throwIfAborted();\n\n\t\t\treturn result;\n\t\t} catch (error) {\n\t\t\tif (await onAttemptFailure({\n\t\t\t\terror,\n\t\t\t\tattemptNumber,\n\t\t\t\tretriesConsumed,\n\t\t\t\tstartTime,\n\t\t\t\toptions,\n\t\t\t})) {\n\t\t\t\tretriesConsumed++;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Should not reach here, but in case it does, throw an error\n\tthrow new Error('Retry attempts exhausted without throwing an error.');\n}\n\nexport function makeRetriable(function_, options) {\n\treturn function (...arguments_) {\n\t\treturn pRetry(() => function_.apply(this, arguments_), options);\n\t};\n}\n","'use strict';\n\nvar has = Object.prototype.hasOwnProperty\n , prefix = '~';\n\n/**\n * Constructor to create a storage for our `EE` objects.\n * An `Events` instance is a plain object whose properties are event names.\n *\n * @constructor\n * @private\n */\nfunction Events() {}\n\n//\n// We try to not inherit from `Object.prototype`. In some engines creating an\n// instance in this way is faster than calling `Object.create(null)` directly.\n// If `Object.create(null)` is not supported we prefix the event names with a\n// character to make sure that the built-in object properties are not\n// overridden or used as an attack vector.\n//\nif (Object.create) {\n Events.prototype = Object.create(null);\n\n //\n // This hack is needed because the `__proto__` property is still inherited in\n // some old browsers like Android 4, iPhone 5.1, Opera 11 and Safari 5.\n //\n if (!new Events().__proto__) prefix = false;\n}\n\n/**\n * Representation of a single event listener.\n *\n * @param {Function} fn The listener function.\n * @param {*} context The context to invoke the listener with.\n * @param {Boolean} [once=false] Specify if the listener is a one-time listener.\n * @constructor\n * @private\n */\nfunction EE(fn, context, once) {\n this.fn = fn;\n this.context = context;\n this.once = once || false;\n}\n\n/**\n * Add a listener for a given event.\n *\n * @param {EventEmitter} emitter Reference to the `EventEmitter` instance.\n * @param {(String|Symbol)} event The event name.\n * @param {Function} fn The listener function.\n * @param {*} context The context to invoke the listener with.\n * @param {Boolean} once Specify if the listener is a one-time listener.\n * @returns {EventEmitter}\n * @private\n */\nfunction addListener(emitter, event, fn, context, once) {\n if (typeof fn !== 'function') {\n throw new TypeError('The listener must be a function');\n }\n\n var listener = new EE(fn, context || emitter, once)\n , evt = prefix ? prefix + event : event;\n\n if (!emitter._events[evt]) emitter._events[evt] = listener, emitter._eventsCount++;\n else if (!emitter._events[evt].fn) emitter._events[evt].push(listener);\n else emitter._events[evt] = [emitter._events[evt], listener];\n\n return emitter;\n}\n\n/**\n * Clear event by name.\n *\n * @param {EventEmitter} emitter Reference to the `EventEmitter` instance.\n * @param {(String|Symbol)} evt The Event name.\n * @private\n */\nfunction clearEvent(emitter, evt) {\n if (--emitter._eventsCount === 0) emitter._events = new Events();\n else delete emitter._events[evt];\n}\n\n/**\n * Minimal `EventEmitter` interface that is molded against the Node.js\n * `EventEmitter` interface.\n *\n * @constructor\n * @public\n */\nfunction EventEmitter() {\n this._events = new Events();\n this._eventsCount = 0;\n}\n\n/**\n * Return an array listing the events for which the emitter has registered\n * listeners.\n *\n * @returns {Array}\n * @public\n */\nEventEmitter.prototype.eventNames = function eventNames() {\n var names = []\n , events\n , name;\n\n if (this._eventsCount === 0) return names;\n\n for (name in (events = this._events)) {\n if (has.call(events, name)) names.push(prefix ? name.slice(1) : name);\n }\n\n if (Object.getOwnPropertySymbols) {\n return names.concat(Object.getOwnPropertySymbols(events));\n }\n\n return names;\n};\n\n/**\n * Return the listeners registered for a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @returns {Array} The registered listeners.\n * @public\n */\nEventEmitter.prototype.listeners = function listeners(event) {\n var evt = prefix ? prefix + event : event\n , handlers = this._events[evt];\n\n if (!handlers) return [];\n if (handlers.fn) return [handlers.fn];\n\n for (var i = 0, l = handlers.length, ee = new Array(l); i < l; i++) {\n ee[i] = handlers[i].fn;\n }\n\n return ee;\n};\n\n/**\n * Return the number of listeners listening to a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @returns {Number} The number of listeners.\n * @public\n */\nEventEmitter.prototype.listenerCount = function listenerCount(event) {\n var evt = prefix ? prefix + event : event\n , listeners = this._events[evt];\n\n if (!listeners) return 0;\n if (listeners.fn) return 1;\n return listeners.length;\n};\n\n/**\n * Calls each of the listeners registered for a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @returns {Boolean} `true` if the event had listeners, else `false`.\n * @public\n */\nEventEmitter.prototype.emit = function emit(event, a1, a2, a3, a4, a5) {\n var evt = prefix ? prefix + event : event;\n\n if (!this._events[evt]) return false;\n\n var listeners = this._events[evt]\n , len = arguments.length\n , args\n , i;\n\n if (listeners.fn) {\n if (listeners.once) this.removeListener(event, listeners.fn, undefined, true);\n\n switch (len) {\n case 1: return listeners.fn.call(listeners.context), true;\n case 2: return listeners.fn.call(listeners.context, a1), true;\n case 3: return listeners.fn.call(listeners.context, a1, a2), true;\n case 4: return listeners.fn.call(listeners.context, a1, a2, a3), true;\n case 5: return listeners.fn.call(listeners.context, a1, a2, a3, a4), true;\n case 6: return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true;\n }\n\n for (i = 1, args = new Array(len -1); i < len; i++) {\n args[i - 1] = arguments[i];\n }\n\n listeners.fn.apply(listeners.context, args);\n } else {\n var length = listeners.length\n , j;\n\n for (i = 0; i < length; i++) {\n if (listeners[i].once) this.removeListener(event, listeners[i].fn, undefined, true);\n\n switch (len) {\n case 1: listeners[i].fn.call(listeners[i].context); break;\n case 2: listeners[i].fn.call(listeners[i].context, a1); break;\n case 3: listeners[i].fn.call(listeners[i].context, a1, a2); break;\n case 4: listeners[i].fn.call(listeners[i].context, a1, a2, a3); break;\n default:\n if (!args) for (j = 1, args = new Array(len -1); j < len; j++) {\n args[j - 1] = arguments[j];\n }\n\n listeners[i].fn.apply(listeners[i].context, args);\n }\n }\n }\n\n return true;\n};\n\n/**\n * Add a listener for a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @param {Function} fn The listener function.\n * @param {*} [context=this] The context to invoke the listener with.\n * @returns {EventEmitter} `this`.\n * @public\n */\nEventEmitter.prototype.on = function on(event, fn, context) {\n return addListener(this, event, fn, context, false);\n};\n\n/**\n * Add a one-time listener for a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @param {Function} fn The listener function.\n * @param {*} [context=this] The context to invoke the listener with.\n * @returns {EventEmitter} `this`.\n * @public\n */\nEventEmitter.prototype.once = function once(event, fn, context) {\n return addListener(this, event, fn, context, true);\n};\n\n/**\n * Remove the listeners of a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @param {Function} fn Only remove the listeners that match this function.\n * @param {*} context Only remove the listeners that have this context.\n * @param {Boolean} once Only remove one-time listeners.\n * @returns {EventEmitter} `this`.\n * @public\n */\nEventEmitter.prototype.removeListener = function removeListener(event, fn, context, once) {\n var evt = prefix ? prefix + event : event;\n\n if (!this._events[evt]) return this;\n if (!fn) {\n clearEvent(this, evt);\n return this;\n }\n\n var listeners = this._events[evt];\n\n if (listeners.fn) {\n if (\n listeners.fn === fn &&\n (!once || listeners.once) &&\n (!context || listeners.context === context)\n ) {\n clearEvent(this, evt);\n }\n } else {\n for (var i = 0, events = [], length = listeners.length; i < length; i++) {\n if (\n listeners[i].fn !== fn ||\n (once && !listeners[i].once) ||\n (context && listeners[i].context !== context)\n ) {\n events.push(listeners[i]);\n }\n }\n\n //\n // Reset the array, or remove it completely if we have no more listeners.\n //\n if (events.length) this._events[evt] = events.length === 1 ? events[0] : events;\n else clearEvent(this, evt);\n }\n\n return this;\n};\n\n/**\n * Remove all listeners, or those of the specified event.\n *\n * @param {(String|Symbol)} [event] The event name.\n * @returns {EventEmitter} `this`.\n * @public\n */\nEventEmitter.prototype.removeAllListeners = function removeAllListeners(event) {\n var evt;\n\n if (event) {\n evt = prefix ? prefix + event : event;\n if (this._events[evt]) clearEvent(this, evt);\n } else {\n this._events = new Events();\n this._eventsCount = 0;\n }\n\n return this;\n};\n\n//\n// Alias methods names because people roll like that.\n//\nEventEmitter.prototype.off = EventEmitter.prototype.removeListener;\nEventEmitter.prototype.addListener = EventEmitter.prototype.on;\n\n//\n// Expose the prefix.\n//\nEventEmitter.prefixed = prefix;\n\n//\n// Allow `EventEmitter` to be imported as module namespace.\n//\nEventEmitter.EventEmitter = EventEmitter;\n\n//\n// Expose the module.\n//\nif ('undefined' !== typeof module) {\n module.exports = EventEmitter;\n}\n","import EventEmitter from './index.js'\n\nexport { EventEmitter }\nexport default EventEmitter\n","export class TimeoutError extends Error {\n\tname = 'TimeoutError';\n\n\tconstructor(message, options) {\n\t\tsuper(message, options);\n\t\tError.captureStackTrace?.(this, TimeoutError);\n\t}\n}\n\nconst getAbortedReason = signal => signal.reason ?? new DOMException('This operation was aborted.', 'AbortError');\n\nexport default function pTimeout(promise, options) {\n\tconst {\n\t\tmilliseconds,\n\t\tfallback,\n\t\tmessage,\n\t\tcustomTimers = {setTimeout, clearTimeout},\n\t\tsignal,\n\t} = options;\n\n\tlet timer;\n\tlet abortHandler;\n\n\tconst wrappedPromise = new Promise((resolve, reject) => {\n\t\tif (typeof milliseconds !== 'number' || Math.sign(milliseconds) !== 1) {\n\t\t\tthrow new TypeError(`Expected \\`milliseconds\\` to be a positive number, got \\`${milliseconds}\\``);\n\t\t}\n\n\t\tif (signal?.aborted) {\n\t\t\treject(getAbortedReason(signal));\n\t\t\treturn;\n\t\t}\n\n\t\tif (signal) {\n\t\t\tabortHandler = () => {\n\t\t\t\treject(getAbortedReason(signal));\n\t\t\t};\n\n\t\t\tsignal.addEventListener('abort', abortHandler, {once: true});\n\t\t}\n\n\t\t// Use .then() instead of async IIFE to preserve stack traces\n\t\t// eslint-disable-next-line promise/prefer-await-to-then, promise/prefer-catch\n\t\tpromise.then(resolve, reject);\n\n\t\tif (milliseconds === Number.POSITIVE_INFINITY) {\n\t\t\treturn;\n\t\t}\n\n\t\t// We create the error outside of `setTimeout` to preserve the stack trace.\n\t\tconst timeoutError = new TimeoutError();\n\n\t\t// `.call(undefined, ...)` is needed for custom timers to avoid context issues\n\t\ttimer = customTimers.setTimeout.call(undefined, () => {\n\t\t\tif (fallback) {\n\t\t\t\ttry {\n\t\t\t\t\tresolve(fallback());\n\t\t\t\t} catch (error) {\n\t\t\t\t\treject(error);\n\t\t\t\t}\n\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (typeof promise.cancel === 'function') {\n\t\t\t\tpromise.cancel();\n\t\t\t}\n\n\t\t\tif (message === false) {\n\t\t\t\tresolve();\n\t\t\t} else if (message instanceof Error) {\n\t\t\t\treject(message);\n\t\t\t} else {\n\t\t\t\ttimeoutError.message = message ?? `Promise timed out after ${milliseconds} milliseconds`;\n\t\t\t\treject(timeoutError);\n\t\t\t}\n\t\t}, milliseconds);\n\t});\n\n\t// eslint-disable-next-line promise/prefer-await-to-then\n\tconst cancelablePromise = wrappedPromise.finally(() => {\n\t\tcancelablePromise.clear();\n\t\tif (abortHandler && signal) {\n\t\t\tsignal.removeEventListener('abort', abortHandler);\n\t\t}\n\t});\n\n\tcancelablePromise.clear = () => {\n\t\t// `.call(undefined, ...)` is needed for custom timers to avoid context issues\n\t\tcustomTimers.clearTimeout.call(undefined, timer);\n\t\ttimer = undefined;\n\t};\n\n\treturn cancelablePromise;\n}\n","// Port of lower_bound from https://en.cppreference.com/w/cpp/algorithm/lower_bound\n// Used to compute insertion index to keep queue sorted after insertion\nexport default function lowerBound(array, value, comparator) {\n let first = 0;\n let count = array.length;\n while (count > 0) {\n const step = Math.trunc(count / 2);\n let it = first + step;\n if (comparator(array[it], value) <= 0) {\n first = ++it;\n count -= step + 1;\n }\n else {\n count = step;\n }\n }\n return first;\n}\n","import lowerBound from './lower-bound.js';\nconst compactionThreshold = 100;\nexport default class PriorityQueue {\n #queue = [];\n // The queue is stored as a sorted array, but dequeued items are left before `#head` until compaction. Only items from `#head` onward are live, which keeps repeated dequeues amortized O(1).\n #head = 0;\n enqueue(run, options) {\n const { priority = 0, id, } = options ?? {};\n const { size } = this;\n const element = {\n priority,\n id,\n run,\n };\n if (size === 0) {\n // When the queue is logically empty, discard any consumed prefix before accepting new work.\n this.#queue.length = 0;\n this.#head = 0;\n this.#queue.push(element);\n return;\n }\n if (this.#queue.at(-1).priority >= priority) {\n // Same-priority and lower-priority items belong after the current tail. Appending preserves FIFO order for equal priorities.\n this.#queue.push(element);\n return;\n }\n // Binary insertion must run on the live sorted range only.\n this.#compact();\n const index = lowerBound(this.#queue, element, (a, b) => b.priority - a.priority);\n this.#queue.splice(index, 0, element);\n }\n setPriority(id, priority) {\n // A dequeued item with the same id is no longer part of the queue.\n const index = this.#queue.findIndex((element, index) => index >= this.#head && element.id === id);\n if (index === -1) {\n throw new ReferenceError(`No promise function with the id \"${id}\" exists in the queue.`);\n }\n const [item] = this.#queue.splice(index, 1);\n this.enqueue(item.run, { priority, id });\n }\n remove(idOrRun) {\n const index = this.#queue.findIndex((element, index) => {\n // The consumed prefix may still contain references that should not be removable.\n if (index < this.#head) {\n return false;\n }\n if (typeof idOrRun === 'string') {\n return element.id === idOrRun;\n }\n return element.run === idOrRun;\n });\n if (index !== -1) {\n this.#queue.splice(index, 1);\n }\n }\n dequeue() {\n if (this.#head === this.#queue.length) {\n return undefined;\n }\n const item = this.#queue[this.#head];\n this.#head++;\n if (this.#head === this.#queue.length) {\n // Fully drained queues are reset immediately so the next enqueue starts from a clean array.\n this.#queue.length = 0;\n this.#head = 0;\n }\n else if (this.#head > compactionThreshold && this.#head > this.#queue.length / 2) {\n // Keep repeated dequeues cheap, but stop the consumed prefix from growing without bound.\n this.#compact();\n }\n return item?.run;\n }\n filter(options) {\n const result = [];\n for (let index = this.#head; index < this.#queue.length; index++) {\n const element = this.#queue[index];\n if (element.priority === options.priority) {\n result.push(element.run);\n }\n }\n return result;\n }\n get size() {\n return this.#queue.length - this.#head;\n }\n #compact() {\n // Compaction restores the invariant that the whole array is the live sorted range.\n if (this.#head === 0) {\n return;\n }\n this.#queue.splice(0, this.#head);\n this.#head = 0;\n }\n}\n","import { EventEmitter } from 'eventemitter3';\nimport pTimeout from 'p-timeout';\nimport PriorityQueue from './priority-queue.js';\n/**\nPromise queue with concurrency control.\n*/\nexport default class PQueue extends EventEmitter {\n #carryoverIntervalCount;\n #isIntervalIgnored;\n #intervalCount = 0;\n #intervalCap;\n #rateLimitedInInterval = false;\n #rateLimitFlushScheduled = false;\n #interval;\n #intervalEnd = 0;\n #lastExecutionTime = 0;\n #intervalId;\n #timeoutId;\n #strict;\n // Circular buffer implementation for better performance\n #strictTicks = [];\n #strictTicksStartIndex = 0;\n #queue;\n #queueClass;\n #pending = 0;\n // The `!` is needed because of https://github.com/microsoft/TypeScript/issues/32194\n #concurrency;\n #isPaused;\n // Use to assign a unique identifier to a promise function, if not explicitly specified\n #idAssigner = 1n;\n // Track currently running tasks for debugging\n #runningTasks = new Map();\n #queueAbortListenerCleanupFunctions = new Set();\n /**\n Get or set the default timeout for all tasks. Can be changed at runtime.\n\n Operations will throw a `TimeoutError` if they don't complete within the specified time.\n\n The timeout begins when the operation is dequeued and starts execution, not while it's waiting in the queue.\n\n @example\n ```\n const queue = new PQueue({timeout: 5000});\n\n // Change timeout for all future tasks\n queue.timeout = 10000;\n ```\n */\n timeout;\n constructor(options) {\n super();\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n options = {\n carryoverIntervalCount: false,\n intervalCap: Number.POSITIVE_INFINITY,\n interval: 0,\n concurrency: Number.POSITIVE_INFINITY,\n autoStart: true,\n queueClass: PriorityQueue,\n strict: false,\n ...options,\n };\n if (!(typeof options.intervalCap === 'number' && options.intervalCap >= 1)) {\n throw new TypeError(`Expected \\`intervalCap\\` to be a number from 1 and up, got \\`${options.intervalCap?.toString() ?? ''}\\` (${typeof options.intervalCap})`);\n }\n if (options.interval === undefined || !(Number.isFinite(options.interval) && options.interval >= 0)) {\n throw new TypeError(`Expected \\`interval\\` to be a finite number >= 0, got \\`${options.interval?.toString() ?? ''}\\` (${typeof options.interval})`);\n }\n if (options.strict && options.interval === 0) {\n throw new TypeError('The `strict` option requires a non-zero `interval`');\n }\n if (options.strict && options.intervalCap === Number.POSITIVE_INFINITY) {\n throw new TypeError('The `strict` option requires a finite `intervalCap`');\n }\n // TODO: Remove this fallback in the next major version\n // eslint-disable-next-line @typescript-eslint/no-deprecated\n this.#carryoverIntervalCount = options.carryoverIntervalCount ?? options.carryoverConcurrencyCount ?? false;\n this.#isIntervalIgnored = options.intervalCap === Number.POSITIVE_INFINITY || options.interval === 0;\n this.#intervalCap = options.intervalCap;\n this.#interval = options.interval;\n this.#strict = options.strict;\n this.#queue = new options.queueClass();\n this.#queueClass = options.queueClass;\n this.concurrency = options.concurrency;\n if (options.timeout !== undefined && !(Number.isFinite(options.timeout) && options.timeout > 0)) {\n throw new TypeError(`Expected \\`timeout\\` to be a positive finite number, got \\`${options.timeout}\\` (${typeof options.timeout})`);\n }\n this.timeout = options.timeout;\n this.#isPaused = options.autoStart === false;\n this.#setupRateLimitTracking();\n }\n #cleanupStrictTicks(now) {\n // Remove ticks outside the current interval window using circular buffer approach\n while (this.#strictTicksStartIndex < this.#strictTicks.length) {\n const oldestTick = this.#strictTicks[this.#strictTicksStartIndex];\n if (oldestTick !== undefined && now - oldestTick >= this.#interval) {\n this.#strictTicksStartIndex++;\n }\n else {\n break;\n }\n }\n // Compact the array when it becomes inefficient or fully consumed\n // Compact when: (start index is large AND more than half wasted) OR all ticks expired\n const shouldCompact = (this.#strictTicksStartIndex > 100 && this.#strictTicksStartIndex > this.#strictTicks.length / 2)\n || this.#strictTicksStartIndex === this.#strictTicks.length;\n if (shouldCompact) {\n this.#strictTicks = this.#strictTicks.slice(this.#strictTicksStartIndex);\n this.#strictTicksStartIndex = 0;\n }\n }\n // Helper methods for interval consumption\n #consumeIntervalSlot(now) {\n if (this.#strict) {\n this.#strictTicks.push(now);\n }\n else {\n this.#intervalCount++;\n }\n }\n #rollbackIntervalSlot() {\n if (this.#strict) {\n // Pop from the end of the actual data (not from start index)\n if (this.#strictTicks.length > this.#strictTicksStartIndex) {\n this.#strictTicks.pop();\n }\n }\n else if (this.#intervalCount > 0) {\n this.#intervalCount--;\n }\n }\n #getActiveTicksCount() {\n return this.#strictTicks.length - this.#strictTicksStartIndex;\n }\n get #doesIntervalAllowAnother() {\n if (this.#isIntervalIgnored) {\n return true;\n }\n if (this.#strict) {\n // Cleanup already done by #isIntervalPausedAt before this is called\n return this.#getActiveTicksCount() < this.#intervalCap;\n }\n return this.#intervalCount < this.#intervalCap;\n }\n get #doesConcurrentAllowAnother() {\n return this.#pending < this.#concurrency;\n }\n #next() {\n this.#pending--;\n if (this.#pending === 0) {\n this.emit('pendingZero');\n }\n this.#tryToStartAnother();\n this.emit('next');\n }\n #onResumeInterval() {\n // Clear timeout ID before processing to prevent race condition\n // Must clear before #onInterval to allow new timeouts to be scheduled\n this.#timeoutId = undefined;\n this.#onInterval();\n this.#initializeIntervalIfNeeded();\n }\n #isIntervalPausedAt(now) {\n // Strict mode: check if we need to wait for oldest tick to age out\n if (this.#strict) {\n this.#cleanupStrictTicks(now);\n // If at capacity, need to wait for oldest tick to age out\n const activeTicksCount = this.#getActiveTicksCount();\n if (activeTicksCount >= this.#intervalCap) {\n const oldestTick = this.#strictTicks[this.#strictTicksStartIndex];\n // After cleanup, remaining ticks are within interval, so delay is always > 0\n const delay = this.#interval - (now - oldestTick);\n this.#createIntervalTimeout(delay);\n return true;\n }\n return false;\n }\n // Fixed window mode (original logic)\n if (this.#intervalId === undefined) {\n const delay = this.#intervalEnd - now;\n if (delay < 0) {\n // If the interval has expired while idle, check if we should enforce the interval\n // from the last task execution. This ensures proper spacing between tasks even\n // when the queue becomes empty and then new tasks are added.\n if (this.#lastExecutionTime > 0) {\n const timeSinceLastExecution = now - this.#lastExecutionTime;\n if (timeSinceLastExecution < this.#interval) {\n // Not enough time has passed since the last task execution\n this.#createIntervalTimeout(this.#interval - timeSinceLastExecution);\n return true;\n }\n }\n // Enough time has passed or no previous execution, allow execution\n this.#intervalCount = (this.#carryoverIntervalCount) ? this.#pending : 0;\n }\n else {\n // Act as the interval is pending\n this.#createIntervalTimeout(delay);\n return true;\n }\n }\n return false;\n }\n #createIntervalTimeout(delay) {\n if (this.#timeoutId !== undefined) {\n return;\n }\n this.#timeoutId = setTimeout(() => {\n this.#onResumeInterval();\n }, delay);\n }\n #clearIntervalTimer() {\n if (this.#intervalId) {\n clearInterval(this.#intervalId);\n this.#intervalId = undefined;\n }\n }\n #clearTimeoutTimer() {\n if (this.#timeoutId) {\n clearTimeout(this.#timeoutId);\n this.#timeoutId = undefined;\n }\n }\n #tryToStartAnother() {\n if (this.#queue.size === 0) {\n // We can clear the interval (\"pause\")\n // Because we can redo it later (\"resume\")\n this.#clearIntervalTimer();\n this.emit('empty');\n if (this.#pending === 0) {\n // Clear timeout as well when completely idle\n this.#clearTimeoutTimer();\n // Compact strict ticks when idle to free memory\n if (this.#strict && this.#strictTicksStartIndex > 0) {\n const now = Date.now();\n this.#cleanupStrictTicks(now);\n }\n this.emit('idle');\n }\n return false;\n }\n let taskStarted = false;\n if (!this.#isPaused) {\n const now = Date.now();\n const canInitializeInterval = !this.#isIntervalPausedAt(now);\n if (this.#doesIntervalAllowAnother && this.#doesConcurrentAllowAnother) {\n const job = this.#queue.dequeue();\n if (!this.#isIntervalIgnored) {\n this.#consumeIntervalSlot(now);\n this.#scheduleRateLimitUpdate();\n }\n this.emit('active');\n job();\n if (canInitializeInterval) {\n this.#initializeIntervalIfNeeded();\n }\n taskStarted = true;\n }\n }\n return taskStarted;\n }\n #initializeIntervalIfNeeded() {\n if (this.#isIntervalIgnored || this.#intervalId !== undefined) {\n return;\n }\n // Strict mode uses timeouts instead of interval timers\n if (this.#strict) {\n return;\n }\n this.#intervalId = setInterval(() => {\n this.#onInterval();\n }, this.#interval);\n this.#intervalEnd = Date.now() + this.#interval;\n }\n #onInterval() {\n // Non-strict mode uses interval timers and intervalCount\n if (!this.#strict) {\n if (this.#intervalCount === 0 && this.#pending === 0 && this.#intervalId) {\n this.#clearIntervalTimer();\n }\n this.#intervalCount = this.#carryoverIntervalCount ? this.#pending : 0;\n }\n this.#processQueue();\n this.#scheduleRateLimitUpdate();\n }\n /**\n Executes all queued functions until it reaches the limit.\n */\n #processQueue() {\n // eslint-disable-next-line no-empty\n while (this.#tryToStartAnother()) { }\n }\n get concurrency() {\n return this.#concurrency;\n }\n set concurrency(newConcurrency) {\n if (!(typeof newConcurrency === 'number' && newConcurrency >= 1)) {\n throw new TypeError(`Expected \\`concurrency\\` to be a number from 1 and up, got \\`${newConcurrency}\\` (${typeof newConcurrency})`);\n }\n this.#concurrency = newConcurrency;\n this.#processQueue();\n }\n /**\n Updates the priority of a promise function by its id, affecting its execution order. Requires a defined concurrency limit to take effect.\n\n For example, this can be used to prioritize a promise function to run earlier.\n\n ```js\n import PQueue from 'p-queue';\n\n const queue = new PQueue({concurrency: 1});\n\n queue.add(async () => '🦄', {priority: 1});\n queue.add(async () => '🦀', {priority: 0, id: '🦀'});\n queue.add(async () => '🦄', {priority: 1});\n queue.add(async () => '🦄', {priority: 1});\n\n queue.setPriority('🦀', 2);\n ```\n\n In this case, the promise function with `id: '🦀'` runs second.\n\n You can also deprioritize a promise function to delay its execution:\n\n ```js\n import PQueue from 'p-queue';\n\n const queue = new PQueue({concurrency: 1});\n\n queue.add(async () => '🦄', {priority: 1});\n queue.add(async () => '🦀', {priority: 1, id: '🦀'});\n queue.add(async () => '🦄');\n queue.add(async () => '🦄', {priority: 0});\n\n queue.setPriority('🦀', -1);\n ```\n Here, the promise function with `id: '🦀'` executes last.\n */\n setPriority(id, priority) {\n if (typeof priority !== 'number' || !Number.isFinite(priority)) {\n throw new TypeError(`Expected \\`priority\\` to be a finite number, got \\`${priority}\\` (${typeof priority})`);\n }\n this.#queue.setPriority(id, priority);\n }\n async add(function_, options = {}) {\n // Create a copy to avoid mutating the original options object\n options = {\n timeout: this.timeout,\n ...options,\n // Assign unique ID if not provided\n id: options.id ?? (this.#idAssigner++).toString(),\n };\n return new Promise((resolve, reject) => {\n // Create a unique symbol for tracking this task\n const taskSymbol = Symbol(`task-${options.id}`);\n let cleanupQueueAbortHandler = () => undefined;\n const run = async () => {\n // Task is now running — remove the queued-state abort listener\n cleanupQueueAbortHandler();\n this.#pending++;\n // Track this running task\n this.#runningTasks.set(taskSymbol, {\n id: options.id,\n priority: options.priority ?? 0, // Match priority-queue default\n startTime: Date.now(),\n timeout: options.timeout,\n });\n let eventListener;\n try {\n // Check abort signal - if aborted, need to decrement the counter\n // that was incremented in tryToStartAnother\n try {\n options.signal?.throwIfAborted();\n }\n catch (error) {\n this.#rollbackIntervalConsumption();\n // Clean up tracking before throwing\n this.#runningTasks.delete(taskSymbol);\n throw error;\n }\n this.#lastExecutionTime = Date.now();\n let operation = function_({ signal: options.signal });\n if (options.timeout) {\n operation = pTimeout(Promise.resolve(operation), {\n milliseconds: options.timeout,\n message: `Task timed out after ${options.timeout}ms (queue has ${this.#pending} running, ${this.#queue.size} waiting)`,\n });\n }\n if (options.signal) {\n const { signal } = options;\n operation = Promise.race([operation, new Promise((_resolve, reject) => {\n eventListener = () => {\n reject(signal.reason);\n };\n signal.addEventListener('abort', eventListener, { once: true });\n })]);\n }\n const result = await operation;\n resolve(result);\n this.emit('completed', result);\n }\n catch (error) {\n reject(error);\n this.emit('error', error);\n }\n finally {\n // Clean up abort event listener\n if (eventListener) {\n options.signal?.removeEventListener('abort', eventListener);\n }\n // Remove from running tasks\n this.#runningTasks.delete(taskSymbol);\n // Use queueMicrotask to prevent deep recursion while maintaining timing\n queueMicrotask(() => {\n this.#next();\n });\n }\n };\n this.#queue.enqueue(run, options);\n const removeQueuedTask = () => {\n if (this.#queue instanceof PriorityQueue) {\n this.#queue.remove(run);\n return;\n }\n this.#queue.remove?.(options.id); // Intentionally best-effort: queued abort removal is only supported for queue classes that implement `.remove()`.\n };\n // Handle abort while task is waiting in the queue\n if (options.signal) {\n const { signal } = options;\n const queueAbortHandler = () => {\n cleanupQueueAbortHandler();\n removeQueuedTask();\n reject(signal.reason);\n this.#tryToStartAnother();\n this.emit('next');\n };\n cleanupQueueAbortHandler = () => {\n signal.removeEventListener('abort', queueAbortHandler);\n this.#queueAbortListenerCleanupFunctions.delete(cleanupQueueAbortHandler);\n };\n if (signal.aborted) {\n queueAbortHandler();\n return;\n }\n signal.addEventListener('abort', queueAbortHandler, { once: true });\n this.#queueAbortListenerCleanupFunctions.add(cleanupQueueAbortHandler);\n }\n this.emit('add');\n this.#tryToStartAnother();\n });\n }\n async addAll(functions, options) {\n return Promise.all(functions.map(async (function_) => this.add(function_, options)));\n }\n /**\n Start (or resume) executing enqueued tasks within concurrency limit. No need to call this if queue is not paused (via `options.autoStart = false` or by `.pause()` method.)\n */\n start() {\n if (!this.#isPaused) {\n return this;\n }\n this.#isPaused = false;\n this.#processQueue();\n return this;\n }\n /**\n Put queue execution on hold.\n */\n pause() {\n this.#isPaused = true;\n }\n /**\n Clear the queue.\n */\n clear() {\n for (const cleanupQueueAbortHandler of this.#queueAbortListenerCleanupFunctions) {\n cleanupQueueAbortHandler();\n }\n this.#queue = new this.#queueClass();\n // Clear interval timer since queue is now empty (consistent with #tryToStartAnother)\n this.#clearIntervalTimer();\n // Note: We preserve strict mode rate-limiting state (ticks and timeout)\n // because clear() only clears queued tasks, not rate limit history.\n // This ensures that rate limits are still enforced after clearing the queue.\n // Note: We don't clear #runningTasks as those tasks are still running\n // They will be removed when they complete in the finally block\n // Force synchronous update since clear() should have immediate effect\n this.#updateRateLimitState();\n // Emit events so waiters (onEmpty, onIdle, onSizeLessThan) can resolve\n this.emit('empty');\n if (this.#pending === 0) {\n this.#clearTimeoutTimer();\n this.emit('idle');\n }\n this.emit('next');\n }\n /**\n Can be called multiple times. Useful if you for example add additional items at a later time.\n\n @returns A promise that settles when the queue becomes empty.\n */\n async onEmpty() {\n // Instantly resolve if the queue is empty\n if (this.#queue.size === 0) {\n return;\n }\n await this.#onEvent('empty');\n }\n /**\n @returns A promise that settles when the queue size is less than the given limit: `queue.size < limit`.\n\n If you want to avoid having the queue grow beyond a certain size you can `await queue.onSizeLessThan()` before adding a new item.\n\n Note that this only limits the number of items waiting to start. There could still be up to `concurrency` jobs already running that this call does not include in its calculation.\n */\n async onSizeLessThan(limit) {\n // Instantly resolve if the queue is empty.\n if (this.#queue.size < limit) {\n return;\n }\n await this.#onEvent('next', () => this.#queue.size < limit);\n }\n /**\n The difference with `.onEmpty` is that `.onIdle` guarantees that all work from the queue has finished. `.onEmpty` merely signals that the queue is empty, but it could mean that some promises haven't completed yet.\n\n @returns A promise that settles when the queue becomes empty, and all promises have completed; `queue.size === 0 && queue.pending === 0`.\n */\n async onIdle() {\n // Instantly resolve if none pending and if nothing else is queued\n if (this.#pending === 0 && this.#queue.size === 0) {\n return;\n }\n await this.#onEvent('idle');\n }\n /**\n The difference with `.onIdle` is that `.onPendingZero` only waits for currently running tasks to finish, ignoring queued tasks.\n\n @returns A promise that settles when all currently running tasks have completed; `queue.pending === 0`.\n */\n async onPendingZero() {\n if (this.#pending === 0) {\n return;\n }\n await this.#onEvent('pendingZero');\n }\n /**\n @returns A promise that settles when the queue becomes rate-limited due to intervalCap.\n */\n async onRateLimit() {\n if (this.isRateLimited) {\n return;\n }\n await this.#onEvent('rateLimit');\n }\n /**\n @returns A promise that settles when the queue is no longer rate-limited.\n */\n async onRateLimitCleared() {\n if (!this.isRateLimited) {\n return;\n }\n await this.#onEvent('rateLimitCleared');\n }\n /**\n @returns A promise that rejects when any task in the queue errors.\n\n Use with `Promise.race([queue.onError(), queue.onIdle()])` to fail fast on the first error while still resolving normally when the queue goes idle.\n\n Important: The promise returned by `add()` still rejects. You must handle each `add()` promise (for example, `.catch(() => {})`) to avoid unhandled rejections.\n\n @example\n ```\n import PQueue from 'p-queue';\n\n const queue = new PQueue({concurrency: 2});\n\n queue.add(() => fetchData(1)).catch(() => {});\n queue.add(() => fetchData(2)).catch(() => {});\n queue.add(() => fetchData(3)).catch(() => {});\n\n // Stop processing on first error\n try {\n await Promise.race([\n queue.onError(),\n queue.onIdle()\n ]);\n } catch (error) {\n queue.pause(); // Stop processing remaining tasks\n console.error('Queue failed:', error);\n }\n ```\n */\n // eslint-disable-next-line @typescript-eslint/promise-function-async\n onError() {\n return new Promise((_resolve, reject) => {\n const handleError = (error) => {\n this.off('error', handleError);\n reject(error);\n };\n this.on('error', handleError);\n });\n }\n async #onEvent(event, filter) {\n return new Promise(resolve => {\n const listener = () => {\n if (filter && !filter()) {\n return;\n }\n this.off(event, listener);\n resolve();\n };\n this.on(event, listener);\n });\n }\n /**\n Size of the queue, the number of queued items waiting to run.\n */\n get size() {\n return this.#queue.size;\n }\n /**\n Size of the queue, filtered by the given options.\n\n For example, this can be used to find the number of items remaining in the queue with a specific priority level.\n */\n sizeBy(options) {\n // eslint-disable-next-line unicorn/no-array-callback-reference\n return this.#queue.filter(options).length;\n }\n /**\n Number of running items (no longer in the queue).\n */\n get pending() {\n return this.#pending;\n }\n /**\n Whether the queue is currently paused.\n */\n get isPaused() {\n return this.#isPaused;\n }\n #setupRateLimitTracking() {\n // Only schedule updates when rate limiting is enabled\n if (this.#isIntervalIgnored) {\n return;\n }\n // Wire up to lifecycle events that affect rate limit state\n // Only 'add' and 'next' can actually change rate limit state\n this.on('add', () => {\n if (this.#queue.size > 0) {\n this.#scheduleRateLimitUpdate();\n }\n });\n this.on('next', () => {\n this.#scheduleRateLimitUpdate();\n });\n }\n #scheduleRateLimitUpdate() {\n // Skip if rate limiting is not enabled or already scheduled\n if (this.#isIntervalIgnored || this.#rateLimitFlushScheduled) {\n return;\n }\n this.#rateLimitFlushScheduled = true;\n queueMicrotask(() => {\n this.#rateLimitFlushScheduled = false;\n this.#updateRateLimitState();\n });\n }\n #rollbackIntervalConsumption() {\n if (this.#isIntervalIgnored) {\n return;\n }\n this.#rollbackIntervalSlot();\n this.#scheduleRateLimitUpdate();\n }\n #updateRateLimitState() {\n const previous = this.#rateLimitedInInterval;\n // Early exit if rate limiting is disabled or queue is empty\n if (this.#isIntervalIgnored || this.#queue.size === 0) {\n if (previous) {\n this.#rateLimitedInInterval = false;\n this.emit('rateLimitCleared');\n }\n return;\n }\n // Get the current count based on mode\n let count;\n if (this.#strict) {\n const now = Date.now();\n this.#cleanupStrictTicks(now);\n count = this.#getActiveTicksCount();\n }\n else {\n count = this.#intervalCount;\n }\n const shouldBeRateLimited = count >= this.#intervalCap;\n if (shouldBeRateLimited !== previous) {\n this.#rateLimitedInInterval = shouldBeRateLimited;\n this.emit(shouldBeRateLimited ? 'rateLimit' : 'rateLimitCleared');\n }\n }\n /**\n Whether the queue is currently rate-limited due to intervalCap.\n */\n get isRateLimited() {\n return this.#rateLimitedInInterval;\n }\n /**\n Whether the queue is saturated. Returns `true` when:\n - All concurrency slots are occupied and tasks are waiting, OR\n - The queue is rate-limited and tasks are waiting\n\n Useful for detecting backpressure and potential hanging tasks.\n\n ```js\n import PQueue from 'p-queue';\n\n const queue = new PQueue({concurrency: 2});\n\n // Backpressure handling\n if (queue.isSaturated) {\n console.log('Queue is saturated, waiting for capacity...');\n await queue.onSizeLessThan(queue.concurrency);\n }\n\n // Monitoring for stuck tasks\n setInterval(() => {\n if (queue.isSaturated) {\n console.warn(`Queue saturated: ${queue.pending} running, ${queue.size} waiting`);\n }\n }, 60000);\n ```\n */\n get isSaturated() {\n return (this.#pending === this.#concurrency && this.#queue.size > 0)\n || (this.isRateLimited && this.#queue.size > 0);\n }\n /**\n The tasks currently being executed. Each task includes its `id`, `priority`, `startTime`, and `timeout` (if set).\n\n Returns an array of task info objects.\n\n ```js\n import PQueue from 'p-queue';\n\n const queue = new PQueue({concurrency: 2});\n\n // Add tasks with IDs for better debugging\n queue.add(() => fetchUser(123), {id: 'user-123'});\n queue.add(() => fetchPosts(456), {id: 'posts-456', priority: 1});\n\n // Check what's running\n console.log(queue.runningTasks);\n // => [{\n // id: 'user-123',\n // priority: 0,\n // startTime: 1759253001716,\n // timeout: undefined\n // }, {\n // id: 'posts-456',\n // priority: 1,\n // startTime: 1759253001916,\n // timeout: undefined\n // }]\n ```\n */\n get runningTasks() {\n // Return fresh array with fresh objects to prevent mutations\n return [...this.#runningTasks.values()].map(task => ({ ...task }));\n }\n}\nexport { default as PriorityQueue } from './priority-queue.js';\n/**\nError thrown when a task times out.\n\n@example\n```\nimport PQueue, {TimeoutError} from 'p-queue';\n\nconst queue = new PQueue({timeout: 1000});\n\ntry {\n await queue.add(() => someTask());\n} catch (error) {\n if (error instanceof TimeoutError) {\n console.log('Task timed out');\n }\n}\n```\n*/\nexport { TimeoutError } from 'p-timeout';\n","/**\n * Comprehensive error handling for BMLT Query Client\n */\n\nexport enum BmltErrorType {\n API_ERROR = 'ApiError',\n NETWORK_ERROR = 'NetworkError',\n VALIDATION_ERROR = 'ValidationError',\n GEOCODING_ERROR = 'GeocodingError',\n RATE_LIMIT_ERROR = 'RateLimitError',\n TIMEOUT_ERROR = 'TimeoutError',\n AUTHENTICATION_ERROR = 'AuthenticationError',\n SERVER_ERROR = 'ServerError',\n CLIENT_ERROR = 'ClientError',\n CONFIGURATION_ERROR = 'ConfigurationError',\n}\n\nexport class BmltQueryError extends Error {\n public readonly type: BmltErrorType;\n public readonly statusCode?: number;\n public readonly response?: unknown;\n public readonly originalError?: Error;\n public readonly context?: Record<string, unknown>;\n\n constructor(\n type: BmltErrorType,\n message: string,\n options: {\n statusCode?: number;\n response?: unknown;\n originalError?: Error;\n context?: Record<string, unknown>;\n } = {}\n ) {\n super(message);\n this.name = 'BmltQueryError';\n this.type = type;\n this.statusCode = options.statusCode;\n this.response = options.response;\n this.originalError = options.originalError;\n this.context = options.context;\n\n // Ensure proper prototype chain for instanceof checks\n Object.setPrototypeOf(this, BmltQueryError.prototype);\n }\n\n /**\n * Check if error is of a specific type\n */\n isType(type: BmltErrorType): boolean {\n return this.type === type;\n }\n\n /**\n * Check if error is retryable\n */\n isRetryable(): boolean {\n const retryableTypes = [\n BmltErrorType.NETWORK_ERROR,\n BmltErrorType.TIMEOUT_ERROR,\n BmltErrorType.RATE_LIMIT_ERROR,\n BmltErrorType.SERVER_ERROR,\n ];\n return retryableTypes.includes(this.type);\n }\n\n /**\n * Check if error is a client-side error (4xx)\n */\n isClientError(): boolean {\n return this.statusCode !== undefined && this.statusCode >= 400 && this.statusCode < 500;\n }\n\n /**\n * Check if error is a server-side error (5xx)\n */\n isServerError(): boolean {\n return this.statusCode !== undefined && this.statusCode >= 500;\n }\n\n /**\n * Get a user-friendly error message\n */\n getUserMessage(): string {\n switch (this.type) {\n case BmltErrorType.NETWORK_ERROR:\n return 'Unable to connect to the BMLT server. Please check your internet connection and try again.';\n\n case BmltErrorType.TIMEOUT_ERROR:\n return 'The request timed out. Please try again later.';\n\n case BmltErrorType.RATE_LIMIT_ERROR:\n return 'Too many requests. Please wait a moment and try again.';\n\n case BmltErrorType.GEOCODING_ERROR:\n return 'Unable to find the specified address. Please check the address and try again.';\n\n case BmltErrorType.VALIDATION_ERROR:\n return 'Invalid input provided. Please check your parameters and try again.';\n\n case BmltErrorType.AUTHENTICATION_ERROR:\n return 'Authentication failed. Please check your credentials.';\n\n case BmltErrorType.SERVER_ERROR:\n return 'The BMLT server encountered an error. Please try again later.';\n\n case BmltErrorType.API_ERROR:\n if (this.statusCode === 404) {\n return 'The requested resource was not found.';\n }\n return 'An error occurred while communicating with the BMLT server.';\n\n case BmltErrorType.CONFIGURATION_ERROR:\n return 'Invalid configuration. Please check your settings.';\n\n default:\n return this.message || 'An unexpected error occurred.';\n }\n }\n\n /**\n * Convert error to JSON for logging\n */\n toJSON() {\n return {\n name: this.name,\n type: this.type,\n message: this.message,\n statusCode: this.statusCode,\n response: this.response,\n context: this.context,\n stack: this.stack,\n originalError: this.originalError\n ? {\n name: this.originalError.name,\n message: this.originalError.message,\n stack: this.originalError.stack,\n }\n : undefined,\n };\n }\n}\n\n/**\n * Factory class for creating specific error types\n */\nexport class ErrorFactory {\n static createApiError(\n message: string,\n statusCode?: number,\n response?: unknown,\n originalError?: Error\n ): BmltQueryError {\n let type: BmltErrorType;\n\n if (statusCode) {\n if (statusCode >= 500) {\n type = BmltErrorType.SERVER_ERROR;\n } else if (statusCode === 401 || statusCode === 403) {\n type = BmltErrorType.AUTHENTICATION_ERROR;\n } else if (statusCode === 429) {\n type = BmltErrorType.RATE_LIMIT_ERROR;\n } else if (statusCode >= 400) {\n type = BmltErrorType.CLIENT_ERROR;\n } else {\n type = BmltErrorType.API_ERROR;\n }\n } else {\n type = BmltErrorType.API_ERROR;\n }\n\n return new BmltQueryError(type, message, {\n statusCode,\n response,\n originalError,\n });\n }\n\n static createNetworkError(message: string, originalError?: Error): BmltQueryError {\n return new BmltQueryError(BmltErrorType.NETWORK_ERROR, message, {\n originalError,\n });\n }\n\n static createTimeoutError(message: string, originalError?: Error): BmltQueryError {\n return new BmltQueryError(BmltErrorType.TIMEOUT_ERROR, message, {\n originalError,\n });\n }\n\n static createValidationError(message: string, context?: Record<string, unknown>): BmltQueryError {\n return new BmltQueryError(BmltErrorType.VALIDATION_ERROR, message, {\n context,\n });\n }\n\n static createGeocodingError(\n message: string,\n originalError?: Error,\n context?: Record<string, unknown>\n ): BmltQueryError {\n return new BmltQueryError(BmltErrorType.GEOCODING_ERROR, message, {\n originalError,\n context,\n });\n }\n\n static createRateLimitError(\n message: string,\n statusCode?: number,\n response?: unknown\n ): BmltQueryError {\n return new BmltQueryError(BmltErrorType.RATE_LIMIT_ERROR, message, {\n statusCode,\n response,\n });\n }\n\n static createConfigurationError(\n message: string,\n context?: Record<string, unknown>\n ): BmltQueryError {\n return new BmltQueryError(BmltErrorType.CONFIGURATION_ERROR, message, {\n context,\n });\n }\n}\n\n/**\n * Error handler utility class\n */\nexport class ErrorHandler {\n /**\n * Handle and transform fetch errors\n */\n static handleFetchError(error: unknown, response?: Response): BmltQueryError {\n // Handle AbortError (timeout)\n if (error instanceof Error && error.name === 'AbortError') {\n return ErrorFactory.createTimeoutError('Request timeout', error);\n }\n\n // Handle TypeError (network errors)\n if (error instanceof TypeError) {\n return ErrorFactory.createNetworkError('Network connection failed', error);\n }\n\n if (response && !response.ok) {\n // Server responded with error status\n const message = `HTTP ${response.status}: ${response.statusText}`;\n return ErrorFactory.createApiError(message, response.status, undefined, error as Error);\n }\n\n // Handle other errors\n if (error instanceof Error) {\n return ErrorFactory.createApiError(error.message, undefined, undefined, error);\n }\n\n // Fallback for unknown errors\n return ErrorFactory.createApiError(\n 'Unknown error occurred',\n undefined,\n undefined,\n new Error(String(error))\n );\n }\n\n /**\n * @deprecated Use handleFetchError instead\n */\n static handleAxiosError(error: any): BmltQueryError {\n return ErrorHandler.handleFetchError(error);\n }\n\n /**\n * Handle validation errors with detailed context\n */\n static handleValidationError(\n field: string,\n value: unknown,\n expectedType: string,\n constraints?: string[]\n ): BmltQueryError {\n let message = `Invalid ${field}: expected ${expectedType}`;\n\n if (constraints && constraints.length > 0) {\n message += ` (${constraints.join(', ')})`;\n }\n\n return ErrorFactory.createValidationError(message, {\n field,\n value,\n expectedType,\n constraints,\n });\n }\n\n /**\n * Handle endpoint validation errors\n */\n static handleEndpointError(endpoint: string, format: string): BmltQueryError {\n const message = `Invalid endpoint/format combination: ${endpoint} with ${format}`;\n return ErrorFactory.createValidationError(message, {\n endpoint,\n format,\n });\n }\n\n /**\n * Handle URL validation errors\n */\n static handleUrlError(url: string, reason: string): BmltQueryError {\n const message = `Invalid URL: ${reason}`;\n return ErrorFactory.createValidationError(message, {\n url,\n reason,\n });\n }\n\n /**\n * Handle coordinate validation errors\n */\n static handleCoordinateError(\n latitude?: number,\n longitude?: number,\n reason?: string\n ): BmltQueryError {\n const message = reason || 'Invalid coordinates provided';\n return ErrorFactory.createValidationError(message, {\n latitude,\n longitude,\n reason,\n });\n }\n\n /**\n * Wrap and enhance existing errors\n */\n static wrapError(\n originalError: Error,\n context: string,\n additionalContext?: Record<string, unknown>\n ): BmltQueryError {\n const message = `${context}: ${originalError.message}`;\n\n // Try to preserve the original error type if it's already a BmltQueryError\n if (originalError instanceof BmltQueryError) {\n return new BmltQueryError(originalError.type, message, {\n statusCode: originalError.statusCode,\n response: originalError.response,\n originalError: originalError.originalError || originalError,\n context: {\n ...originalError.context,\n ...additionalContext,\n },\n });\n }\n\n // Default to API error for unknown errors\n return ErrorFactory.createApiError(message, undefined, undefined, originalError);\n }\n}\n\n/**\n * Retry utility for handling retryable errors\n */\nexport interface RetryOptions {\n maxRetries: number;\n baseDelay: number;\n maxDelay: number;\n factor: number;\n onRetry?: (error: BmltQueryError, attempt: number) => void;\n}\n\nexport class RetryHandler {\n static async withRetry<T>(operation: () => Promise<T>, options: RetryOptions): Promise<T> {\n const { maxRetries, baseDelay, maxDelay, factor, onRetry } = options;\n\n let lastError: BmltQueryError;\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n try {\n return await operation();\n } catch (error) {\n const bmltError =\n error instanceof BmltQueryError\n ? error\n : ErrorHandler.wrapError(error as Error, 'Operation failed');\n\n lastError = bmltError;\n\n // Don't retry if it's the last attempt or error is not retryable\n if (attempt === maxRetries || !bmltError.isRetryable()) {\n throw bmltError;\n }\n\n // Calculate delay for next attempt\n const delay = Math.min(baseDelay * Math.pow(factor, attempt), maxDelay);\n\n // Call retry callback if provided\n if (onRetry) {\n onRetry(bmltError, attempt + 1);\n }\n\n // Wait before retrying\n await new Promise(resolve => setTimeout(resolve, delay));\n }\n }\n\n throw lastError!;\n }\n}\n","/**\n * Nominatim geocoding service with retry logic and rate limiting\n */\n\nimport pRetry from 'p-retry';\nimport PQueue from 'p-queue';\nimport { GeocodeResult, GeocodeOptions, RateLimitOptions, BmltError, Coordinates } from '../types';\nimport { BmltQueryError, BmltErrorType, ErrorHandler } from '../utils/errors';\n\nexport interface NominatimResponse {\n place_id: number;\n licence: string;\n osm_type: string;\n osm_id: number;\n lat: string;\n lon: string;\n display_name: string;\n address?: {\n house_number?: string;\n road?: string;\n neighbourhood?: string;\n suburb?: string;\n city?: string;\n town?: string;\n village?: string;\n county?: string;\n state?: string;\n postcode?: string;\n country?: string;\n country_code?: string;\n };\n importance?: number;\n boundingbox: string[];\n}\n\nexport class GeocodingService {\n private baseURL: string;\n private queue: PQueue;\n private readonly defaultOptions: Required<Omit<GeocodeOptions, 'viewbox'>> & {\n viewbox?: [number, number, number, number];\n };\n\n constructor(options: GeocodeOptions & RateLimitOptions = {}) {\n const {\n retryCount = 3,\n timeout = 10000,\n userAgent = 'bmlt-query-client/1.0.0',\n countryCode = 'us',\n viewbox,\n bounded = false,\n intervalCap = 1,\n interval = 1000, // 1 second between requests\n concurrency = 1,\n carryoverConcurrencyCount = false,\n ...rateLimitOptions\n } = options;\n\n this.defaultOptions = {\n retryCount,\n timeout,\n userAgent,\n countryCode,\n viewbox,\n bounded,\n };\n\n this.baseURL = 'https://nominatim.openstreetmap.org';\n\n this.queue = new PQueue({\n intervalCap,\n interval,\n concurrency,\n carryoverConcurrencyCount,\n ...rateLimitOptions,\n });\n }\n\n /**\n * Make a fetch request with timeout and error handling\n */\n private async fetchWithTimeout<T>(url: string, timeout: number, userAgent: string): Promise<T> {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), timeout);\n\n try {\n const response = await fetch(url, {\n method: 'GET',\n headers: {\n 'User-Agent': userAgent,\n },\n signal: controller.signal,\n });\n\n if (!response.ok) {\n if (response.status === 429) {\n const error: BmltError = new Error('Rate limit exceeded for geocoding service');\n error.name = 'RateLimitError';\n error.statusCode = 429;\n throw error;\n }\n\n if (response.status >= 400) {\n const error: BmltError = new Error(\n `Geocoding service error: ${response.status} ${response.statusText}`\n );\n error.name = 'GeocodingError';\n error.statusCode = response.status;\n throw error;\n }\n }\n\n const data = await response.json();\n return data as T;\n } catch (error) {\n if (error instanceof Error && error.name === 'AbortError') {\n const timeoutError: BmltError = new Error('Request timeout during geocoding');\n timeoutError.name = 'TimeoutError';\n throw timeoutError;\n }\n\n if (error instanceof TypeError) {\n const networkError: BmltError = new Error('Network error occurred during geocoding');\n networkError.name = 'NetworkError';\n throw networkError;\n }\n\n throw error;\n } finally {\n clearTimeout(timeoutId);\n }\n }\n\n /**\n * Geocode an address using Nominatim\n */\n async geocode(address: string, options: Partial<GeocodeOptions> = {}): Promise<GeocodeResult> {\n const geocodeOptions = { ...this.defaultOptions, ...options };\n\n return this.queue.add(async (): Promise<GeocodeResult> => {\n return pRetry(\n async () => {\n try {\n // Build search parameters with region bias\n const searchParams: Record<string, string | number> = {\n q: address,\n format: 'json',\n addressdetails: 1,\n limit: 1,\n dedupe: 1,\n };\n\n // Add country code bias if specified\n if (geocodeOptions.countryCode) {\n searchParams.countrycodes = geocodeOptions.countryCode;\n }\n\n // Add viewbox if specified\n if (geocodeOptions.viewbox) {\n searchParams.viewbox = geocodeOptions.viewbox.join(',');\n if (geocodeOptions.bounded) {\n searchParams.bounded = 1;\n }\n }\n\n // Build URL with parameters\n const searchUrl = new URL(`${this.baseURL}/search`);\n Object.entries(searchParams).forEach(([key, value]) => {\n searchUrl.searchParams.append(key, String(value));\n });\n\n const response = await this.fetchWithTimeout<NominatimResponse[]>(\n searchUrl.toString(),\n geocodeOptions.timeout,\n geocodeOptions.userAgent\n );\n\n if (!response || response.length === 0) {\n throw new BmltQueryError(\n BmltErrorType.GEOCODING_ERROR,\n `No results found for address: ${address}`\n );\n }\n\n // Always take the first result (most relevant based on search parameters)\n const result = response[0];\n const coordinates: Coordinates = {\n latitude: parseFloat(result.lat),\n longitude: parseFloat(result.lon),\n };\n\n // Validate coordinates\n if (isNaN(coordinates.latitude) || isNaN(coordinates.longitude)) {\n const error: BmltError = new Error(\n 'Invalid coordinates received from geocoding service'\n );\n error.name = 'GeocodingError';\n throw error;\n }\n\n if (\n coordinates.latitude < -90 ||\n coordinates.latitude > 90 ||\n coordinates.longitude < -180 ||\n coordinates.longitude > 180\n ) {\n const error: BmltError = new Error('Coordinates out of valid range');\n error.name = 'GeocodingError';\n throw error;\n }\n\n return {\n coordinates,\n display_name: result.display_name,\n confidence: result.importance,\n address: result.address\n ? {\n house_number: result.address.house_number,\n road: result.address.road,\n neighbourhood: result.address.neighbourhood,\n suburb: result.address.suburb,\n city: result.address.city || result.address.town || result.address.village,\n county: result.address.county,\n state: result.address.state,\n postcode: result.address.postcode,\n country: result.address.country,\n }\n : undefined,\n };\n } catch (error) {\n // Re-throw errors from fetchWithTimeout or validation\n throw error;\n }\n },\n {\n retries: geocodeOptions.retryCount,\n factor: 2,\n minTimeout: 1000,\n maxTimeout: 10000,\n onFailedAttempt: error => {\n console.warn(\n `Geocoding attempt ${error.attemptNumber} failed. ${error.retriesLeft} retries left. Error: ${error.error.message}`\n );\n },\n }\n );\n }) as Promise<GeocodeResult>;\n }\n\n /**\n * Batch geocode multiple addresses\n */\n async batchGeocode(\n addresses: string[],\n options: Partial<GeocodeOptions> = {}\n ): Promise<GeocodeResult[]> {\n const promises = addresses.map(address =>\n this.geocode(address, options).catch(error => {\n console.warn(`Failed to geocode address \"${address}\":`, error.message);\n return null;\n })\n );\n\n const results = await Promise.all(promises);\n return results.filter((result): result is GeocodeResult => result !== null);\n }\n\n /**\n * Reverse geocode coordinates to an address\n */\n async reverseGeocode(\n coordinates: Coordinates,\n options: Partial<GeocodeOptions> = {}\n ): Promise<GeocodeResult> {\n const geocodeOptions = { ...this.defaultOptions, ...options };\n\n return this.queue.add(async (): Promise<GeocodeResult> => {\n return pRetry(\n async () => {\n try {\n // Build URL with parameters\n const reverseUrl = new URL(`${this.baseURL}/reverse`);\n reverseUrl.searchParams.append('lat', String(coordinates.latitude));\n reverseUrl.searchParams.append('lon', String(coordinates.longitude));\n reverseUrl.searchParams.append('format', 'json');\n reverseUrl.searchParams.append('addressdetails', '1');\n\n const response = await this.fetchWithTimeout<NominatimResponse>(\n reverseUrl.toString(),\n geocodeOptions.timeout,\n geocodeOptions.userAgent\n );\n\n if (!response) {\n const error: BmltError = new Error(\n `No results found for coordinates: ${coordinates.latitude}, ${coordinates.longitude}`\n );\n error.name = 'GeocodingError';\n throw error;\n }\n\n const result = response;\n\n return {\n coordinates: {\n latitude: parseFloat(result.lat),\n longitude: parseFloat(result.lon),\n },\n display_name: result.display_name,\n confidence: result.importance,\n address: result.address\n ? {\n house_number: result.address.house_number,\n road: result.address.road,\n neighbourhood: result.address.neighbourhood,\n suburb: result.address.suburb,\n city: result.address.city || result.address.town || result.address.village,\n county: result.address.county,\n state: result.address.state,\n postcode: result.address.postcode,\n country: result.address.country,\n }\n : undefined,\n };\n } catch (error) {\n // Re-throw errors from fetchWithTimeout\n throw error;\n }\n },\n {\n retries: geocodeOptions.retryCount,\n factor: 2,\n minTimeout: 1000,\n maxTimeout: 10000,\n }\n );\n }) as Promise<GeocodeResult>;\n }\n\n /**\n * Get the current queue size\n */\n getQueueSize(): number {\n return this.queue.size;\n }\n\n /**\n * Get the number of pending operations\n */\n getPendingCount(): number {\n return this.queue.pending;\n }\n\n /**\n * Clear the queue\n */\n clearQueue(): void {\n this.queue.clear();\n }\n\n /**\n * Set concurrency limit\n */\n setConcurrency(concurrency: number): void {\n this.queue.concurrency = concurrency;\n }\n\n /**\n * Get the current user agent string\n */\n getUserAgent(): string {\n return this.defaultOptions.userAgent;\n }\n\n /**\n * Set the user agent string for geocoding requests\n */\n setUserAgent(userAgent: string): void {\n if (!userAgent || userAgent.trim().length === 0) {\n throw new Error('User agent must be a non-empty string');\n }\n this.defaultOptions.userAgent = userAgent.trim();\n }\n}\n","/**\n * Base types and enums for BMLT API\n */\n\nexport enum BmltDataFormat {\n JSON = 'json',\n JSONP = 'jsonp',\n TSML = 'tsml',\n CSV = 'csv',\n}\n\nexport enum BmltEndpoint {\n GET_SEARCH_RESULTS = 'GetSearchResults',\n GET_FORMATS = 'GetFormats',\n GET_SERVICE_BODIES = 'GetServiceBodies',\n GET_CHANGES = 'GetChanges',\n GET_FIELD_KEYS = 'GetFieldKeys',\n GET_FIELD_VALUES = 'GetFieldValues',\n GET_NAWS_DUMP = 'GetNAWSDump',\n GET_SERVER_INFO = 'GetServerInfo',\n GET_COVERAGE_AREA = 'GetCoverageArea',\n}\n\nexport enum Weekday {\n SUNDAY = 1,\n MONDAY = 2,\n TUESDAY = 3,\n WEDNESDAY = 4,\n THURSDAY = 5,\n FRIDAY = 6,\n SATURDAY = 7,\n}\n\nexport enum VenueType {\n IN_PERSON = 1,\n VIRTUAL = 2,\n HYBRID = 3,\n}\n\nexport enum SortKey {\n WEEKDAY = 'weekday',\n TIME = 'time',\n TOWN = 'town',\n STATE = 'state',\n WEEKDAY_STATE = 'weekday_state',\n}\n\nexport enum Language {\n DANISH = 'da',\n GERMAN = 'de',\n GREEK = 'el',\n ENGLISH = 'en',\n SPANISH = 'es',\n PERSIAN = 'fa',\n FRENCH = 'fr',\n ITALIAN = 'it',\n POLISH = 'pl',\n PORTUGUESE = 'pt',\n RUSSIAN = 'ru',\n SWEDISH = 'sv',\n}\n\nexport interface Coordinates {\n latitude: number;\n longitude: number;\n}\n\nexport interface BmltError extends Error {\n statusCode?: number;\n response?: unknown;\n}\n\nexport interface GeocodeOptions {\n retryCount?: number;\n timeout?: number;\n userAgent?: string;\n /** Country code for region bias (e.g., 'us', 'ca', 'gb') */\n countryCode?: string;\n /** Viewbox for region bias [minLon, minLat, maxLon, maxLat] */\n viewbox?: [number, number, number, number];\n /** Bounded search - restrict results to viewbox */\n bounded?: boolean;\n}\n\nexport interface RateLimitOptions {\n intervalCap?: number;\n interval?: number;\n carryoverConcurrencyCount?: boolean;\n concurrency?: number;\n}\n","/**\n * Utility functions for building BMLT API URLs and handling parameters\n */\n\nimport { BmltDataFormat, BmltEndpoint } from '../types';\n\nexport interface URLBuilderOptions {\n serverURL: string;\n format: BmltDataFormat;\n endpoint: BmltEndpoint;\n parameters?: Record<string, unknown>;\n}\n\n/**\n * Build a BMLT API URL with parameters\n */\nexport function buildBmltURL(options: URLBuilderOptions): string {\n const { serverURL, format, endpoint, parameters = {} } = options;\n\n // Ensure server URL ends with slash\n const baseURL = serverURL.endsWith('/') ? serverURL : `${serverURL}/`;\n\n // Build the base endpoint URL\n const endpointURL = `${baseURL}client_interface/${format}/`;\n\n // Convert parameters to query string\n const queryParams = new URLSearchParams();\n queryParams.set('switcher', endpoint);\n\n // Add other parameters\n Object.entries(parameters).forEach(([key, value]) => {\n if (value !== undefined && value !== null) {\n if (Array.isArray(value)) {\n // Handle array parameters\n value.forEach((item, index) => {\n if (typeof item === 'number' || typeof item === 'string') {\n queryParams.append(`${key}[]`, item.toString());\n }\n });\n } else if (typeof value === 'boolean') {\n queryParams.set(key, value ? '1' : '0');\n } else {\n queryParams.set(key, value.toString());\n }\n }\n });\n\n return `${endpointURL}?${queryParams.toString()}`;\n}\n\n/**\n * Normalize parameter values for BMLT API\n */\nexport function normalizeParameters(params: Record<string, unknown>): Record<string, unknown> {\n const normalized: Record<string, unknown> = {};\n\n Object.entries(params).forEach(([key, value]) => {\n if (value !== undefined && value !== null) {\n // Handle array parameters with positive/negative values\n if (Array.isArray(value)) {\n normalized[key] = value.map(item => {\n if (typeof item === 'number') {\n return item;\n } else if (typeof item === 'string') {\n const num = parseFloat(item);\n return isNaN(num) ? item : num;\n }\n return item;\n });\n }\n // Handle boolean parameters\n else if (typeof value === 'boolean') {\n normalized[key] = value;\n }\n // Handle numeric strings\n else if (typeof value === 'string') {\n const num = parseFloat(value);\n if (!isNaN(num) && isFinite(num)) {\n normalized[key] = num;\n } else {\n normalized[key] = value;\n }\n }\n // Keep other values as-is\n else {\n normalized[key] = value;\n }\n }\n });\n\n return normalized;\n}\n\n/**\n * Validate endpoint/format combinations\n */\nexport function validateEndpointFormat(endpoint: BmltEndpoint, format: BmltDataFormat): void {\n const validCombinations: Record<BmltEndpoint, BmltDataFormat[]> = {\n [BmltEndpoint.GET_SEARCH_RESULTS]: [\n BmltDataFormat.JSON,\n BmltDataFormat.JSONP,\n BmltDataFormat.TSML,\n ],\n [BmltEndpoint.GET_FORMATS]: [BmltDataFormat.JSON, BmltDataFormat.JSONP],\n [BmltEndpoint.GET_SERVICE_BODIES]: [BmltDataFormat.JSON, BmltDataFormat.JSONP],\n [BmltEndpoint.GET_CHANGES]: [BmltDataFormat.JSON, BmltDataFormat.JSONP],\n [BmltEndpoint.GET_FIELD_KEYS]: [BmltDataFormat.JSON, BmltDataFormat.JSONP],\n [BmltEndpoint.GET_FIELD_VALUES]: [BmltDataFormat.JSON, BmltDataFormat.JSONP],\n [BmltEndpoint.GET_NAWS_DUMP]: [BmltDataFormat.CSV],\n [BmltEndpoint.GET_SERVER_INFO]: [BmltDataFormat.JSON, BmltDataFormat.JSONP],\n [BmltEndpoint.GET_COVERAGE_AREA]: [BmltDataFormat.JSON, BmltDataFormat.JSONP],\n };\n\n const validFormats = validCombinations[endpoint];\n if (!validFormats.includes(format)) {\n throw new Error(\n `Invalid format '${format}' for endpoint '${endpoint}'. Valid formats: ${validFormats.join(', ')}`\n );\n }\n}\n\n/**\n * Clean and validate a server URL\n */\nexport function validateServerURL(url: string): string {\n try {\n const urlObj = new URL(url);\n if (!['http:', 'https:'].includes(urlObj.protocol)) {\n throw new Error('Server URL must use http or https protocol');\n }\n\n // Return the URL without trailing slash for consistency\n return urlObj.href.replace(/\\/$/, '');\n } catch (error) {\n const validationError = new Error(`Invalid server URL: ${url}`);\n validationError.cause = error;\n throw validationError;\n }\n}\n\n/**\n * Extract numeric IDs from various parameter formats\n */\nexport function extractIds(value: unknown): number[] {\n if (typeof value === 'number') {\n return [value];\n }\n\n if (typeof value === 'string') {\n // Handle comma-separated values\n return value\n .split(',')\n .map(id => parseInt(id.trim(), 10))\n .filter(id => !isNaN(id));\n }\n\n if (Array.isArray(value)) {\n return value\n .map(item => (typeof item === 'number' ? item : parseInt(String(item), 10)))\n .filter(id => !isNaN(id));\n }\n\n return [];\n}\n\n/**\n * Format time values for BMLT API\n */\nexport function formatTimeValue(\n hours?: number,\n minutes?: number\n): { hours?: number; minutes?: number } {\n const result: { hours?: number; minutes?: number } = {};\n\n if (typeof hours === 'number') {\n if (hours < 0 || hours > 23) {\n throw new Error('Hours must be between 0 and 23');\n }\n result.hours = hours;\n }\n\n if (typeof minutes === 'number') {\n if (minutes < 0 || minutes > 59) {\n throw new Error('Minutes must be between 0 and 59');\n }\n result.minutes = minutes;\n }\n\n return result;\n}\n\n/**\n * Validate coordinate values\n */\nexport function validateCoordinates(latitude: number, longitude: number): void {\n if (typeof latitude !== 'number' || isNaN(latitude)) {\n throw new Error('Latitude must be a valid number');\n }\n\n if (typeof longitude !== 'number' || isNaN(longitude)) {\n throw new Error('Longitude must be a valid number');\n }\n\n if (latitude < -90 || latitude > 90) {\n throw new Error('Latitude must be between -90 and 90 degrees');\n }\n\n if (longitude < -180 || longitude > 180) {\n throw new Error('Longitude must be between -180 and 180 degrees');\n }\n}\n\n/**\n * Validate radius values\n */\nexport function validateRadius(radius: number): void {\n if (typeof radius !== 'number' || isNaN(radius)) {\n throw new Error('Radius must be a valid number');\n }\n\n if (radius <= 0) {\n throw new Error('Radius must be greater than 0');\n }\n}\n\n/**\n * Convert miles to kilometers\n */\nexport function milesToKilometers(miles: number): number {\n return miles * 1.60934;\n}\n\n/**\n * Convert kilometers to miles\n */\nexport function kilometersToMiles(km: number): number {\n return km / 1.60934;\n}\n","/**\n * Response transforms — BMLT serializes numeric fields as quoted strings.\n * These converters give consumers idiomatic typed numbers.\n */\n\nimport type { Meeting, ServerInfo, CoverageArea } from '../types/responses';\n\nconst num = (v: unknown): number => (typeof v === 'number' ? v : parseFloat(v as string));\n\nconst optNum = (v: unknown): number | undefined => {\n if (v === undefined || v === null || v === '') return undefined;\n return num(v);\n};\n\nexport function transformMeeting(raw: unknown): Meeting {\n const r = raw as Record<string, unknown>;\n return {\n ...(r as unknown as Meeting),\n weekday_tinyint: num(r.weekday_tinyint),\n venue_type: num(r.venue_type),\n published: num(r.published),\n latitude: num(r.latitude),\n longitude: num(r.longitude),\n distance_in_km: optNum(r.distance_in_km),\n distance_in_miles: optNum(r.distance_in_miles),\n };\n}\n\nexport function transformServerInfo(raw: unknown): ServerInfo {\n const r = raw as Record<string, unknown>;\n return {\n ...(r as unknown as ServerInfo),\n versionInt: num(r.versionInt),\n centerLongitude: num(r.centerLongitude),\n centerLatitude: num(r.centerLatitude),\n centerZoom: num(r.centerZoom),\n semanticAdmin: num(r.semanticAdmin),\n changesPerMeeting: num(r.changesPerMeeting),\n };\n}\n\nexport function transformCoverageArea(raw: unknown): CoverageArea {\n const r = raw as Record<string, unknown>;\n return {\n nw_corner_longitude: num(r.nw_corner_longitude),\n nw_corner_latitude: num(r.nw_corner_latitude),\n se_corner_longitude: num(r.se_corner_longitude),\n se_corner_latitude: num(r.se_corner_latitude),\n };\n}\n","/**\n * Main BMLT client class for querying BMLT servers\n */\n\nimport { GeocodingService } from '../services/geocoding';\nimport {\n BmltDataFormat,\n BmltEndpoint,\n BmltError,\n Meeting,\n Format,\n MeetingsWithFormats,\n ServiceBody,\n Change,\n ServerInfo,\n CoverageArea,\n FieldKey,\n FieldValue,\n SearchResultsParams,\n GeographicSearchParams,\n FormatsParams,\n ServiceBodiesParams,\n ChangesParams,\n FieldValuesParams,\n NAWSDumpParams,\n GeocodeOptions,\n RateLimitOptions,\n Coordinates,\n} from '../types';\nimport {\n buildBmltURL,\n validateEndpointFormat,\n validateServerURL,\n validateCoordinates,\n validateRadius,\n} from '../utils/url-builder';\nimport { ErrorHandler } from '../utils/errors';\nimport { transformMeeting, transformServerInfo, transformCoverageArea } from '../utils/transforms';\n\nexport interface BmltClientOptions {\n /** Server URL */\n serverURL: string;\n\n /** Default data format */\n defaultFormat?: BmltDataFormat;\n\n /** HTTP request timeout in milliseconds */\n timeout?: number;\n\n /** User agent string */\n userAgent?: string;\n\n /** Geocoding options */\n geocodingOptions?: GeocodeOptions & RateLimitOptions;\n\n /** Enable automatic geocoding for address searches */\n enableGeocoding?: boolean;\n}\n\nexport class BmltClient {\n private timeout: number;\n private userAgent: string;\n private readonly geocodingService?: GeocodingService;\n private serverURL: string;\n private defaultFormat: BmltDataFormat;\n\n constructor(options: BmltClientOptions) {\n const {\n serverURL,\n defaultFormat = BmltDataFormat.JSON,\n timeout = 30000,\n userAgent = 'bmlt-query-client/1.0.0',\n geocodingOptions = {},\n enableGeocoding = true,\n } = options;\n\n // Validate and normalize server URL\n this.serverURL = validateServerURL(serverURL);\n this.defaultFormat = defaultFormat;\n this.timeout = timeout;\n this.userAgent = userAgent;\n\n // Initialize geocoding service if enabled\n if (enableGeocoding) {\n this.geocodingService = new GeocodingService(geocodingOptions);\n }\n }\n\n /**\n * Fetch a URL and parse the response according to format\n */\n private async fetchAndParse<T>(\n url: string,\n format: BmltDataFormat,\n parameters: Record<string, unknown> = {}\n ): Promise<T> {\n let response: Response | undefined;\n\n try {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n try {\n response = await fetch(url, {\n method: 'GET',\n headers: { 'User-Agent': this.userAgent },\n signal: controller.signal,\n });\n } finally {\n clearTimeout(timeoutId);\n }\n\n if (!response.ok) {\n throw ErrorHandler.handleFetchError(\n new Error(`HTTP ${response.status}: ${response.statusText}`),\n response\n );\n }\n\n const responseText = await response.text();\n\n if (format === BmltDataFormat.CSV) return responseText as T;\n\n if (format === BmltDataFormat.JSONP) {\n const callbackName = (parameters.callback as string) || 'callback';\n const jsonMatch = responseText.match(new RegExp(`${callbackName}\\\\((.+)\\\\);?$`));\n if (!jsonMatch) throw new Error('Invalid JSONP response format');\n return JSON.parse(jsonMatch[1]) as T;\n }\n\n if (format === BmltDataFormat.JSON || format === BmltDataFormat.TSML) {\n return JSON.parse(responseText) as T;\n }\n\n return responseText as T;\n } catch (error) {\n throw ErrorHandler.handleFetchError(error, response);\n }\n }\n\n /**\n * Make a request to the BMLT API\n */\n private async makeRequest<T>(\n endpoint: BmltEndpoint,\n parameters: Record<string, unknown> = {},\n format: BmltDataFormat = this.defaultFormat\n ): Promise<T> {\n validateEndpointFormat(endpoint, format);\n const url = buildBmltURL({ serverURL: this.serverURL, format, endpoint, parameters });\n return this.fetchAndParse<T>(url, format, parameters);\n }\n\n /**\n * Execute a raw BMLT query string against the server.\n *\n * Pass the query exactly as you'd append it to a BMLT URL. The switcher\n * can be written with or without the key name:\n *\n * // bare endpoint name — most common shorthand\n * client.rawQuery('GetSearchResults&venue_types=2&meeting_key=location_nation&meeting_key_value[]=USA&meeting_key_value[]=US')\n *\n * // explicit switcher= key also works\n * client.rawQuery('switcher=GetSearchResults&venue_types=2')\n */\n async rawQuery<T = unknown>(\n queryString: string,\n format: BmltDataFormat = this.defaultFormat\n ): Promise<T> {\n const baseURL = this.serverURL.endsWith('/') ? this.serverURL : `${this.serverURL}/`;\n const endpointURL = `${baseURL}client_interface/${format}/`;\n\n // If the first token has no '=' it is a bare endpoint name; prepend switcher=\n const firstSegment = queryString.split('&')[0];\n const normalized = firstSegment.includes('=') ? queryString : `switcher=${queryString}`;\n\n return this.fetchAndParse<T>(`${endpointURL}?${normalized}`, format);\n }\n\n /**\n * Search for meetings\n */\n async searchMeetings(params: SearchResultsParams = {}): Promise<Meeting[]> {\n const { format = this.defaultFormat, ...searchParams } = params;\n const result = await this.makeRequest<unknown[]>(\n BmltEndpoint.GET_SEARCH_RESULTS,\n searchParams,\n format\n );\n return result.map(transformMeeting);\n }\n\n /**\n * Search for meetings and return both meetings and the formats they reference in a\n * single request. Uses get_used_formats=true so the server wraps the response as\n * { meetings: Meeting[], formats: Format[] } instead of a bare Meeting[].\n *\n * This replaces the common pattern of Promise.all([getFormats(), searchMeetings()])\n * with a single round-trip, which matters for large servers where getFormats() can\n * return hundreds of unused format records.\n */\n async searchMeetingsWithFormats(\n params: Omit<SearchResultsParams, 'get_used_formats' | 'get_formats_only'> = {}\n ): Promise<MeetingsWithFormats> {\n const { format = this.defaultFormat, ...searchParams } = params;\n const result = await this.makeRequest<{ meetings: unknown[]; formats: Format[] }>(\n BmltEndpoint.GET_SEARCH_RESULTS,\n { ...searchParams, get_used_formats: true },\n format\n );\n return {\n meetings: result.meetings.map(transformMeeting),\n formats: result.formats,\n };\n }\n\n /**\n * Search for meetings by geographic location using geocoding\n */\n async searchMeetingsByAddress(params: GeographicSearchParams): Promise<Meeting[]> {\n if (!this.geocodingService) {\n throw new Error('Geocoding is not enabled. Initialize client with enableGeocoding: true');\n }\n\n const { address, radiusMiles, radiusKm, sortByDistance = true, searchParams = {} } = params;\n\n // Geocode the address\n const geocodeResult = await this.geocodingService.geocode(address);\n\n // Build search parameters with coordinates\n const geoSearchParams: SearchResultsParams = {\n ...searchParams,\n lat_val: geocodeResult.coordinates.latitude,\n long_val: geocodeResult.coordinates.longitude,\n sort_results_by_distance: sortByDistance,\n };\n\n // Add radius parameter\n if (radiusMiles !== undefined) {\n validateRadius(radiusMiles);\n geoSearchParams.geo_width = radiusMiles;\n } else if (radiusKm !== undefined) {\n validateRadius(radiusKm);\n geoSearchParams.geo_width_km = radiusKm;\n }\n\n return this.searchMeetings(geoSearchParams);\n }\n\n /**\n * Search for meetings by coordinates\n */\n async searchMeetingsByCoordinates(\n coordinates: Coordinates,\n radiusMiles?: number,\n radiusKm?: number,\n searchParams: Omit<\n SearchResultsParams,\n 'lat_val' | 'long_val' | 'geo_width' | 'geo_width_km'\n > = {}\n ): Promise<Meeting[]> {\n validateCoordinates(coordinates.latitude, coordinates.longitude);\n\n const geoSearchParams: SearchResultsParams = {\n ...searchParams,\n lat_val: coordinates.latitude,\n long_val: coordinates.longitude,\n sort_results_by_distance: true,\n };\n\n if (radiusMiles !== undefined) {\n validateRadius(radiusMiles);\n geoSearchParams.geo_width = radiusMiles;\n } else if (radiusKm !== undefined) {\n validateRadius(radiusKm);\n geoSearchParams.geo_width_km = radiusKm;\n }\n\n return this.searchMeetings(geoSearchParams);\n }\n\n /**\n * Get available meeting formats\n */\n async getFormats(params: FormatsParams = {}): Promise<Format[]> {\n const { format = this.defaultFormat, ...formatParams } = params;\n return this.makeRequest<Format[]>(BmltEndpoint.GET_FORMATS, formatParams, format);\n }\n\n /**\n * Get service bodies\n */\n async getServiceBodies(params: ServiceBodiesParams = {}): Promise<ServiceBody[]> {\n const { format = this.defaultFormat, ...serviceParams } = params;\n return this.makeRequest<ServiceBody[]>(BmltEndpoint.GET_SERVICE_BODIES, serviceParams, format);\n }\n\n /**\n * Get meeting changes within a date range\n */\n async getChanges(params: ChangesParams = {}): Promise<Change[]> {\n const { format = this.defaultFormat, ...changeParams } = params;\n return this.makeRequest<Change[]>(BmltEndpoint.GET_CHANGES, changeParams, format);\n }\n\n /**\n * Get available field keys\n */\n async getFieldKeys(): Promise<FieldKey[]> {\n return this.makeRequest<FieldKey[]>(BmltEndpoint.GET_FIELD_KEYS);\n }\n\n /**\n * Get field values for a specific field key\n */\n async getFieldValues(params: FieldValuesParams): Promise<FieldValue[]> {\n const { format = this.defaultFormat, ...fieldParams } = params;\n return this.makeRequest<FieldValue[]>(BmltEndpoint.GET_FIELD_VALUES, fieldParams, format);\n }\n\n /**\n * Get NAWS dump for a service body (CSV format only)\n */\n async getNAWSDump(params: NAWSDumpParams): Promise<string> {\n return this.makeRequest<string>(BmltEndpoint.GET_NAWS_DUMP, params, BmltDataFormat.CSV);\n }\n\n /**\n * Get server information\n */\n async getServerInfo(): Promise<ServerInfo> {\n const result = await this.makeRequest<unknown[]>(BmltEndpoint.GET_SERVER_INFO);\n return transformServerInfo(result[0]);\n }\n\n /**\n * Get server coverage area\n */\n async getCoverageArea(): Promise<CoverageArea> {\n const result = await this.makeRequest<unknown[]>(BmltEndpoint.GET_COVERAGE_AREA);\n return transformCoverageArea(result[0]);\n }\n\n /**\n * Geocode an address using the built-in geocoding service\n */\n async geocodeAddress(address: string, options?: Partial<GeocodeOptions>) {\n if (!this.geocodingService) {\n throw new Error('Geocoding is not enabled. Initialize client with enableGeocoding: true');\n }\n\n return this.geocodingService.geocode(address, options);\n }\n\n /**\n * Reverse geocode coordinates to an address\n */\n async reverseGeocode(coordinates: Coordinates, options?: Partial<GeocodeOptions>) {\n if (!this.geocodingService) {\n throw new Error('Geocoding is not enabled. Initialize client with enableGeocoding: true');\n }\n\n return this.geocodingService.reverseGeocode(coordinates, options);\n }\n\n /**\n * Get the server URL\n */\n getServerURL(): string {\n return this.serverURL;\n }\n\n /**\n * Update the server URL\n */\n setServerURL(url: string): void {\n this.serverURL = validateServerURL(url);\n }\n\n /**\n * Get the default data format\n */\n getDefaultFormat(): BmltDataFormat {\n return this.defaultFormat;\n }\n\n /**\n * Set the default data format\n */\n setDefaultFormat(format: BmltDataFormat): void {\n this.defaultFormat = format;\n }\n\n /**\n * Get geocoding service statistics\n */\n getGeocodingStats() {\n if (!this.geocodingService) {\n return null;\n }\n\n return {\n queueSize: this.geocodingService.getQueueSize(),\n pendingCount: this.geocodingService.getPendingCount(),\n };\n }\n\n /**\n * Clear the geocoding queue\n */\n clearGeocodingQueue(): void {\n if (this.geocodingService) {\n this.geocodingService.clearQueue();\n }\n }\n\n /**\n * Get the current user agent string\n */\n getUserAgent(): string {\n return this.userAgent;\n }\n\n /**\n * Set the user agent string for HTTP requests\n */\n setUserAgent(userAgent: string): void {\n if (!userAgent || userAgent.trim().length === 0) {\n throw new Error('User agent must be a non-empty string');\n }\n this.userAgent = userAgent.trim();\n\n // Also update the geocoding service user agent if it exists\n if (this.geocodingService) {\n this.geocodingService.setUserAgent(this.userAgent);\n }\n }\n\n /**\n * Get the current timeout setting\n */\n getTimeout(): number {\n return this.timeout;\n }\n\n /**\n * Set the timeout for HTTP requests\n */\n setTimeout(timeout: number): void {\n if (!Number.isInteger(timeout) || timeout <= 0) {\n throw new Error('Timeout must be a positive integer');\n }\n this.timeout = timeout;\n }\n}\n","/**\n * Fluent query builder for BMLT meeting searches\n */\n\nimport {\n SearchResultsParams,\n Meeting,\n MeetingsWithFormats,\n Weekday,\n VenueType,\n SortKey,\n Language,\n BmltDataFormat,\n Coordinates,\n} from '../types';\nimport { BmltClient } from './bmlt-client';\n\nexport class MeetingQueryBuilder {\n private params: SearchResultsParams = {};\n private client: BmltClient;\n\n constructor(client: BmltClient) {\n this.client = client;\n }\n\n /**\n * Include or exclude specific meeting IDs\n */\n meetingIds(ids: number | number[], exclude = false): this {\n if (Array.isArray(ids)) {\n this.params.meeting_ids = exclude ? ids.map(id => -id) : ids;\n } else {\n this.params.meeting_ids = exclude ? -ids : ids;\n }\n return this;\n }\n\n /**\n * Include meetings on specific weekdays\n */\n onWeekdays(...days: Weekday[]): this {\n this.params.weekdays = days.length === 1 ? days[0] : days;\n return this;\n }\n\n /**\n * Exclude meetings on specific weekdays\n */\n notOnWeekdays(...days: Weekday[]): this {\n const excludeDays = days.map(day => -day);\n this.params.weekdays = excludeDays.length === 1 ? excludeDays[0] : excludeDays;\n return this;\n }\n\n /**\n * Filter by venue types\n */\n venueTypes(...types: VenueType[]): this {\n this.params.venue_types = types.length === 1 ? types[0] : types;\n return this;\n }\n\n /**\n * Include only in-person meetings\n */\n inPersonOnly(): this {\n return this.venueTypes(VenueType.IN_PERSON);\n }\n\n /**\n * Include only virtual meetings\n */\n virtualOnly(): this {\n return this.venueTypes(VenueType.VIRTUAL);\n }\n\n /**\n * Include only hybrid meetings\n */\n hybridOnly(): this {\n return this.venueTypes(VenueType.HYBRID);\n }\n\n /**\n * Include virtual and hybrid meetings\n */\n virtualOrHybrid(): this {\n return this.venueTypes(VenueType.VIRTUAL, VenueType.HYBRID);\n }\n\n /**\n * Filter by meeting formats\n */\n formats(formatIds: number | number[], exclude = false): this {\n if (Array.isArray(formatIds)) {\n this.params.formats = exclude ? formatIds.map(id => -id) : formatIds;\n } else {\n this.params.formats = exclude ? -formatIds : formatIds;\n }\n return this;\n }\n\n /**\n * Use OR logic for format matching instead of AND\n */\n anyFormat(): this {\n this.params.formats_comparison_operator = 'OR';\n return this;\n }\n\n /**\n * Filter by service bodies\n */\n serviceBodies(serviceBodyIds: number | number[], exclude = false): this {\n if (Array.isArray(serviceBodyIds)) {\n this.params.services = exclude ? serviceBodyIds.map(id => -id) : serviceBodyIds;\n } else {\n this.params.services = exclude ? -serviceBodyIds : serviceBodyIds;\n }\n return this;\n }\n\n /**\n * Include child service bodies\n */\n includeChildServiceBodies(): this {\n this.params.recursive = true;\n return this;\n }\n\n /**\n * Search for specific text\n */\n searchText(text: string): this {\n this.params.SearchString = text;\n return this;\n }\n\n /**\n * Search by address using server-side geocoding (StringSearchIsAnAddress=1).\n * Note: typically broken on most BMLT servers because their Google API key uses\n * HTTP referer restrictions rather than server IP allowlisting. Prefer\n * BmltClient.searchMeetingsByAddress() which uses Nominatim client-side.\n */\n searchAddress(address: string, radius?: number): this {\n this.params.SearchString = address;\n this.params.StringSearchIsAnAddress = true;\n if (radius !== undefined) this.params.SearchStringRadius = radius;\n return this;\n }\n\n /**\n * Meetings starting after specific time\n */\n startingAfter(hours: number, minutes = 0): this {\n this.params.StartsAfterH = hours;\n this.params.StartsAfterM = minutes;\n return this;\n }\n\n /**\n * Meetings starting before specific time\n */\n startingBefore(hours: number, minutes = 0): this {\n this.params.StartsBeforeH = hours;\n this.params.StartsBeforeM = minutes;\n return this;\n }\n\n /**\n * Meetings ending before specific time\n */\n endingBefore(hours: number, minutes = 0): this {\n this.params.EndsBeforeH = hours;\n this.params.EndsBeforeM = minutes;\n return this;\n }\n\n /**\n * Minimum meeting duration\n */\n minimumDuration(hours = 0, minutes = 0): this {\n if (hours > 0) this.params.MinDurationH = hours;\n if (minutes > 0) this.params.MinDurationM = minutes;\n return this;\n }\n\n /**\n * Maximum meeting duration\n */\n maximumDuration(hours = 0, minutes = 0): this {\n if (hours > 0) this.params.MaxDurationH = hours;\n if (minutes > 0) this.params.MaxDurationM = minutes;\n return this;\n }\n\n /**\n * Search within geographic area by coordinates\n */\n nearCoordinates(coordinates: Coordinates, radiusMiles?: number, radiusKm?: number): this {\n this.params.lat_val = coordinates.latitude;\n this.params.long_val = coordinates.longitude;\n\n if (radiusMiles !== undefined) {\n this.params.geo_width = radiusMiles;\n } else if (radiusKm !== undefined) {\n this.params.geo_width_km = radiusKm;\n }\n\n return this;\n }\n\n /**\n * Search for specific field value; pass an array to match any of multiple values\n */\n fieldValue(fieldKey: string, value: string | string[]): this {\n this.params.meeting_key = fieldKey;\n this.params.meeting_key_value = value;\n return this;\n }\n\n /**\n * Return only specific fields\n */\n selectFields(...fields: string[]): this {\n this.params.data_field_key = fields.join(',');\n return this;\n }\n\n /**\n * Sort results by specific fields\n */\n sortBy(...fields: string[]): this {\n this.params.sort_keys = fields.join(',');\n return this;\n }\n\n /**\n * Sort by predefined aliases\n */\n sortByAlias(alias: SortKey): this {\n this.params.sort_key = alias;\n return this;\n }\n\n /**\n * Sort by distance (requires geographic search)\n */\n sortByDistance(): this {\n this.params.sort_results_by_distance = true;\n return this;\n }\n\n /**\n * Set pagination\n */\n paginate(pageSize: number, pageNumber = 1): this {\n this.params.page_size = pageSize;\n this.params.page_num = pageNumber;\n return this;\n }\n\n /**\n * Include unpublished meetings\n */\n includeUnpublished(): this {\n this.params.advanced_published = 0;\n return this;\n }\n\n /**\n * Include only unpublished meetings\n */\n unpublishedOnly(): this {\n this.params.advanced_published = -1;\n return this;\n }\n\n /**\n * Set language for format names\n */\n language(lang: Language): this {\n this.params.lang_enum = lang;\n return this;\n }\n\n /**\n * Set response format\n */\n format(format: BmltDataFormat): this {\n this.params.format = format;\n return this;\n }\n\n /**\n * Include formats used in search results\n */\n includeFormats(): this {\n this.params.get_used_formats = true;\n return this;\n }\n\n /**\n * Return only formats (requires includeFormats)\n */\n formatsOnly(): this {\n this.params.get_used_formats = true;\n this.params.get_formats_only = true;\n return this;\n }\n\n /**\n * Filter by root server IDs (aggregator mode)\n */\n rootServerIds(serverIds: number | number[], exclude = false): this {\n if (Array.isArray(serverIds)) {\n this.params.root_server_ids = exclude ? serverIds.map(id => -id) : serverIds;\n } else {\n this.params.root_server_ids = exclude ? -serverIds : serverIds;\n }\n return this;\n }\n\n /**\n * Get the current query parameters\n */\n getParams(): SearchResultsParams {\n return { ...this.params };\n }\n\n /**\n * Reset the query builder\n */\n reset(): this {\n this.params = {};\n return this;\n }\n\n /**\n * Clone the current query builder\n */\n clone(): MeetingQueryBuilder {\n const cloned = new MeetingQueryBuilder(this.client);\n cloned.params = { ...this.params };\n return cloned;\n }\n\n /**\n * Execute the search and return results\n */\n async execute(): Promise<Meeting[]> {\n return this.client.searchMeetings(this.params);\n }\n\n /**\n * Execute the search and return both meetings and the formats they reference\n * in a single request. Equivalent to execute() but avoids a separate getFormats() call.\n */\n async executeWithFormats(): Promise<MeetingsWithFormats> {\n const { get_used_formats, get_formats_only, ...params } = this.params;\n return this.client.searchMeetingsWithFormats(params);\n }\n\n /**\n * Execute the search by geocoding an address first\n */\n async executeNearAddress(\n address: string,\n radiusMiles?: number,\n radiusKm?: number,\n sortByDistance = true\n ): Promise<Meeting[]> {\n return this.client.searchMeetingsByAddress({\n address,\n radiusMiles,\n radiusKm,\n sortByDistance,\n searchParams: this.params,\n });\n }\n}\n\n/**\n * Convenience methods for common search patterns\n */\nexport class QuickSearch {\n private client: BmltClient;\n\n constructor(client: BmltClient) {\n this.client = client;\n }\n\n /**\n * Search for today's meetings\n */\n today(): MeetingQueryBuilder {\n const today = new Date().getDay();\n const weekday = today === 0 ? Weekday.SUNDAY : (today as Weekday);\n return new MeetingQueryBuilder(this.client).onWeekdays(weekday);\n }\n\n /**\n * Search for weekend meetings\n */\n weekend(): MeetingQueryBuilder {\n return new MeetingQueryBuilder(this.client).onWeekdays(Weekday.SATURDAY, Weekday.SUNDAY);\n }\n\n /**\n * Search for weekday meetings\n */\n weekdays(): MeetingQueryBuilder {\n return new MeetingQueryBuilder(this.client).onWeekdays(\n Weekday.MONDAY,\n Weekday.TUESDAY,\n Weekday.WEDNESDAY,\n Weekday.THURSDAY,\n Weekday.FRIDAY\n );\n }\n\n /**\n * Search for evening meetings (after 5 PM)\n */\n evening(): MeetingQueryBuilder {\n return new MeetingQueryBuilder(this.client).startingAfter(17);\n }\n\n /**\n * Search for morning meetings (before 12 PM)\n */\n morning(): MeetingQueryBuilder {\n return new MeetingQueryBuilder(this.client).startingBefore(12);\n }\n\n /**\n * Search for virtual meetings only\n */\n virtual(): MeetingQueryBuilder {\n return new MeetingQueryBuilder(this.client).virtualOnly();\n }\n\n /**\n * Search for in-person meetings only\n */\n inPerson(): MeetingQueryBuilder {\n return new MeetingQueryBuilder(this.client).inPersonOnly();\n }\n\n /**\n * Search by meeting name or location\n */\n byText(searchText: string): MeetingQueryBuilder {\n return new MeetingQueryBuilder(this.client).searchText(searchText);\n }\n}\n","/**\n * Utility functions for working with Meeting arrays\n */\n\nimport { Meeting } from '../types';\n\n/** A single meeting paired with the index of the list it came from */\nexport interface DuplicateMeetingEntry {\n meeting: Meeting;\n /** Index of the source list in the array passed to findDuplicateMeetings */\n listIndex: number;\n}\n\n/** A group of meetings from different lists that match on the comparison key */\nexport interface DuplicateMeetingGroup {\n /** Composite key used for matching */\n key: string;\n /** All matching entries, one per occurrence across the lists */\n entries: DuplicateMeetingEntry[];\n}\n\nexport interface FindDuplicatesOptions {\n /**\n * Meeting fields used to build the composite comparison key.\n * Defaults to weekday, start time, meeting name, and location.\n */\n fields?: Array<keyof Meeting>;\n\n /**\n * Normalize string values before comparing (lowercase + trim).\n * Defaults to true.\n */\n normalize?: boolean;\n}\n\nconst DEFAULT_FIELDS: Array<keyof Meeting> = [\n 'weekday_tinyint',\n 'start_time',\n 'meeting_name',\n 'location_text',\n];\n\nfunction normalizeValue(value: unknown, normalize: boolean): string {\n const str = value === null || value === undefined ? '' : String(value);\n return normalize ? str.toLowerCase().trim() : str;\n}\n\nfunction buildKey(meeting: Meeting, fields: Array<keyof Meeting>, normalize: boolean): string {\n return fields.map(field => normalizeValue(meeting[field], normalize)).join(' | ');\n}\n\n/**\n * Find meetings that appear in more than one of the provided lists.\n *\n * Comparison is done via a composite key built from the specified fields\n * (default: weekday, start time, meeting name, location). Only groups that\n * span at least two different lists are returned.\n *\n * @example\n * const duplicates = findDuplicateMeetings([listA, listB]);\n * for (const group of duplicates) {\n * console.log(`Duplicate: ${group.key}`);\n * for (const { meeting, listIndex } of group.entries) {\n * console.log(` List ${listIndex}: id=${meeting.id_bigint}`);\n * }\n * }\n */\nexport function findDuplicateMeetings(\n meetingLists: Meeting[][],\n options: FindDuplicatesOptions = {}\n): DuplicateMeetingGroup[] {\n const { fields = DEFAULT_FIELDS, normalize = true } = options;\n\n // Build a map from composite key -> entries\n const keyMap = new Map<string, DuplicateMeetingEntry[]>();\n\n for (let listIndex = 0; listIndex < meetingLists.length; listIndex++) {\n for (const meeting of meetingLists[listIndex]) {\n const key = buildKey(meeting, fields, normalize);\n if (!keyMap.has(key)) {\n keyMap.set(key, []);\n }\n keyMap.get(key)!.push({ meeting, listIndex });\n }\n }\n\n // Keep only groups that appear in at least 2 distinct lists\n const result: DuplicateMeetingGroup[] = [];\n for (const [key, entries] of keyMap) {\n const listIndices = new Set(entries.map(e => e.listIndex));\n if (listIndices.size >= 2) {\n result.push({ key, entries });\n }\n }\n\n return result;\n}\n\n/**\n * Count unique groups across a list of meetings.\n *\n * A \"group\" is identified by the combination of service body and meeting name\n * (case-insensitive, trimmed), so multiple weekly meetings of the same group\n * count once.\n */\nexport function countUniqueGroups(meetings: Meeting[]): number {\n const namesByServiceBody = new Map<string, Set<string>>();\n\n for (const { service_body_bigint: sbId, meeting_name: name } of meetings) {\n if (!sbId || !name) continue;\n const normalized = name.trim().toLowerCase();\n if (!namesByServiceBody.has(sbId)) {\n namesByServiceBody.set(sbId, new Set());\n }\n namesByServiceBody.get(sbId)!.add(normalized);\n }\n\n let total = 0;\n for (const names of namesByServiceBody.values()) {\n total += names.size;\n }\n return total;\n}\n"],"x_google_ignoreList":[0,1,2,3,4,5,6,7],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"app.js","names":["EventEmitter"],"sources":["../node_modules/is-network-error/index.js","../node_modules/p-retry/index.js","../node_modules/eventemitter3/index.js","../node_modules/eventemitter3/index.mjs","../node_modules/p-timeout/index.js","../node_modules/p-queue/dist/lower-bound.js","../node_modules/p-queue/dist/priority-queue.js","../node_modules/p-queue/dist/index.js","../src/utils/errors.ts","../src/services/geocoding.ts","../src/types/base.ts","../src/utils/url-builder.ts","../src/utils/transforms.ts","../src/client/bmlt-client.ts","../src/client/query-builder.ts","../src/utils/meetings.ts"],"sourcesContent":["const objectToString = Object.prototype.toString;\n\nconst isError = value => objectToString.call(value) === '[object Error]';\n\nconst errorMessages = new Set([\n\t'network error', // Chrome\n\t'NetworkError when attempting to fetch resource.', // Firefox\n\t'The Internet connection appears to be offline.', // Safari 16\n\t'Network request failed', // `cross-fetch`\n\t'fetch failed', // Undici (Node.js)\n\t'terminated', // Undici (Node.js)\n\t' A network error occurred.', // Bun (WebKit)\n\t'Network connection lost', // Cloudflare Workers (fetch)\n]);\n\nexport default function isNetworkError(error) {\n\tconst isValid = error\n\t\t&& isError(error)\n\t\t&& error.name === 'TypeError'\n\t\t&& typeof error.message === 'string';\n\n\tif (!isValid) {\n\t\treturn false;\n\t}\n\n\tconst {message, stack} = error;\n\n\t// Safari 17+ has generic message but no stack for network errors\n\tif (message === 'Load failed' || (message.startsWith('Load failed (') && message.endsWith(')'))) {\n\t\treturn stack === undefined\n\t\t\t// Sentry adds its own stack trace to the fetch error, so also check for that\n\t\t\t|| '__sentry_captured__' in error;\n\t}\n\n\t// Deno network errors start with specific text\n\tif (message.startsWith('error sending request for url')) {\n\t\treturn true;\n\t}\n\n\t// Chrome: exact \"Failed to fetch\" or with hostname: \"Failed to fetch (example.com)\"\n\tif (message === 'Failed to fetch' || (message.startsWith('Failed to fetch (') && message.endsWith(')'))) {\n\t\treturn true;\n\t}\n\n\t// Standard network error messages\n\treturn errorMessages.has(message);\n}\n","import isNetworkError from 'is-network-error';\n\nfunction validateRetries(retries) {\n\tif (typeof retries === 'number') {\n\t\tif (retries < 0) {\n\t\t\tthrow new TypeError('Expected `retries` to be a non-negative number.');\n\t\t}\n\n\t\tif (Number.isNaN(retries)) {\n\t\t\tthrow new TypeError('Expected `retries` to be a valid number or Infinity, got NaN.');\n\t\t}\n\t} else if (retries !== undefined) {\n\t\tthrow new TypeError('Expected `retries` to be a number or Infinity.');\n\t}\n}\n\nfunction validateNumberOption(name, value, {min = 0, allowInfinity = false} = {}) {\n\tif (value === undefined) {\n\t\treturn;\n\t}\n\n\tif (typeof value !== 'number' || Number.isNaN(value)) {\n\t\tthrow new TypeError(`Expected \\`${name}\\` to be a number${allowInfinity ? ' or Infinity' : ''}.`);\n\t}\n\n\tif (!allowInfinity && !Number.isFinite(value)) {\n\t\tthrow new TypeError(`Expected \\`${name}\\` to be a finite number.`);\n\t}\n\n\tif (value < min) {\n\t\tthrow new TypeError(`Expected \\`${name}\\` to be \\u2265 ${min}.`);\n\t}\n}\n\nfunction validateFunctionOption(name, value) {\n\tif (value === undefined) {\n\t\treturn;\n\t}\n\n\tif (typeof value !== 'function') {\n\t\tthrow new TypeError(`Expected \\`${name}\\` to be a function.`);\n\t}\n}\n\nexport class AbortError extends Error {\n\tconstructor(message) {\n\t\tsuper();\n\n\t\tif (message instanceof Error) {\n\t\t\tthis.originalError = message;\n\t\t\t({message} = message);\n\t\t} else {\n\t\t\tthis.originalError = new Error(message);\n\t\t\tthis.originalError.stack = this.stack;\n\t\t}\n\n\t\tthis.name = 'AbortError';\n\t\tthis.message = message;\n\t}\n}\n\nfunction calculateDelay(retriesConsumed, options) {\n\tconst attempt = Math.max(1, retriesConsumed + 1);\n\tconst random = options.randomize ? (Math.random() + 1) : 1;\n\n\tlet timeout = Math.round(random * options.minTimeout * (options.factor ** (attempt - 1)));\n\ttimeout = Math.min(timeout, options.maxTimeout);\n\n\treturn timeout;\n}\n\nfunction calculateRemainingTime(start, max) {\n\tif (!Number.isFinite(max)) {\n\t\treturn max;\n\t}\n\n\treturn max - (performance.now() - start);\n}\n\nasync function delayForRetry(delay, options) {\n\tif (delay <= 0) {\n\t\treturn;\n\t}\n\n\tawait new Promise((resolve, reject) => {\n\t\tconst onAbort = () => {\n\t\t\tclearTimeout(timeoutToken);\n\t\t\toptions.signal?.removeEventListener('abort', onAbort);\n\t\t\treject(options.signal.reason);\n\t\t};\n\n\t\tconst timeoutToken = setTimeout(() => {\n\t\t\toptions.signal?.removeEventListener('abort', onAbort);\n\t\t\tresolve();\n\t\t}, delay);\n\n\t\tif (options.unref) {\n\t\t\ttimeoutToken.unref?.();\n\t\t}\n\n\t\toptions.signal?.addEventListener('abort', onAbort, {once: true});\n\t});\n}\n\nasync function onAttemptFailure({error, attemptNumber, retriesConsumed, startTime, options}) {\n\tconst normalizedError = error instanceof Error\n\t\t? error\n\t\t: new TypeError(`Non-error was thrown: \"${error}\". You should only throw errors.`);\n\n\tif (normalizedError instanceof AbortError) {\n\t\tthrow normalizedError.originalError;\n\t}\n\n\tconst retriesLeft = Number.isFinite(options.retries)\n\t\t? Math.max(0, options.retries - retriesConsumed)\n\t\t: options.retries;\n\n\tconst maxRetryTime = options.maxRetryTime ?? Number.POSITIVE_INFINITY;\n\tconst delayTime = calculateDelay(retriesConsumed, options);\n\tconst remainingTimeBeforeCallbacks = calculateRemainingTime(startTime, maxRetryTime);\n\n\tif (remainingTimeBeforeCallbacks <= 0) {\n\t\tconst context = Object.freeze({\n\t\t\terror: normalizedError,\n\t\t\tattemptNumber,\n\t\t\tretriesLeft,\n\t\t\tretriesConsumed,\n\t\t\tretryDelay: 0,\n\t\t});\n\n\t\tawait options.onFailedAttempt(context);\n\n\t\tthrow normalizedError;\n\t}\n\n\tconst consumeRetryContext = Object.freeze({\n\t\terror: normalizedError,\n\t\tattemptNumber,\n\t\tretriesLeft,\n\t\tretriesConsumed,\n\t\tretryDelay: retriesLeft > 0 ? delayTime : 0,\n\t});\n\n\tconst consumeRetry = await options.shouldConsumeRetry(consumeRetryContext);\n\tconst effectiveDelay = consumeRetry && retriesLeft > 0 ? delayTime : 0;\n\tconst context = Object.freeze({\n\t\terror: normalizedError,\n\t\tattemptNumber,\n\t\tretriesLeft,\n\t\tretriesConsumed,\n\t\tretryDelay: effectiveDelay,\n\t});\n\n\tawait options.onFailedAttempt(context);\n\n\tif (calculateRemainingTime(startTime, maxRetryTime) <= 0) {\n\t\tthrow normalizedError;\n\t}\n\n\tconst remainingTime = calculateRemainingTime(startTime, maxRetryTime);\n\n\tif (remainingTime <= 0 || retriesLeft <= 0) {\n\t\tthrow normalizedError;\n\t}\n\n\tif (normalizedError instanceof TypeError && !isNetworkError(normalizedError)) {\n\t\tthrow normalizedError;\n\t}\n\n\tif (!await options.shouldRetry(context)) {\n\t\tthrow normalizedError;\n\t}\n\n\tconst remainingTimeAfterShouldRetry = calculateRemainingTime(startTime, maxRetryTime);\n\n\tif (remainingTimeAfterShouldRetry <= 0) {\n\t\tthrow normalizedError;\n\t}\n\n\tif (!consumeRetry) {\n\t\toptions.signal?.throwIfAborted();\n\t\treturn false;\n\t}\n\n\tconst finalDelay = Math.min(effectiveDelay, remainingTimeAfterShouldRetry);\n\n\toptions.signal?.throwIfAborted();\n\n\tawait delayForRetry(finalDelay, options);\n\n\toptions.signal?.throwIfAborted();\n\n\treturn true;\n}\n\nexport default async function pRetry(input, options = {}) {\n\toptions = {...options};\n\n\tvalidateRetries(options.retries);\n\n\tif (Object.hasOwn(options, 'forever')) {\n\t\tthrow new Error('The `forever` option is no longer supported. For many use-cases, you can set `retries: Infinity` instead.');\n\t}\n\n\toptions.retries ??= 10;\n\toptions.factor ??= 2;\n\toptions.minTimeout ??= 1000;\n\toptions.maxTimeout ??= Number.POSITIVE_INFINITY;\n\toptions.maxRetryTime ??= Number.POSITIVE_INFINITY;\n\toptions.randomize ??= false;\n\toptions.onFailedAttempt ??= () => {};\n\toptions.shouldRetry ??= () => true;\n\toptions.shouldConsumeRetry ??= () => true;\n\n\t// Validate numeric options and normalize edge cases\n\tvalidateFunctionOption('onFailedAttempt', options.onFailedAttempt);\n\tvalidateFunctionOption('shouldRetry', options.shouldRetry);\n\tvalidateFunctionOption('shouldConsumeRetry', options.shouldConsumeRetry);\n\tvalidateNumberOption('factor', options.factor, {min: 0, allowInfinity: false});\n\tvalidateNumberOption('minTimeout', options.minTimeout, {min: 0, allowInfinity: false});\n\tvalidateNumberOption('maxTimeout', options.maxTimeout, {min: 0, allowInfinity: true});\n\tvalidateNumberOption('maxRetryTime', options.maxRetryTime, {min: 0, allowInfinity: true});\n\n\t// Treat non-positive factor as 1 to avoid zero backoff or negative behavior\n\tif (!(options.factor > 0)) {\n\t\toptions.factor = 1;\n\t}\n\n\toptions.signal?.throwIfAborted();\n\n\tlet attemptNumber = 0;\n\tlet retriesConsumed = 0;\n\tconst startTime = performance.now();\n\n\twhile (Number.isFinite(options.retries) ? retriesConsumed <= options.retries : true) {\n\t\tattemptNumber++;\n\n\t\ttry {\n\t\t\toptions.signal?.throwIfAborted();\n\n\t\t\tconst result = await input(attemptNumber);\n\n\t\t\toptions.signal?.throwIfAborted();\n\n\t\t\treturn result;\n\t\t} catch (error) {\n\t\t\tif (await onAttemptFailure({\n\t\t\t\terror,\n\t\t\t\tattemptNumber,\n\t\t\t\tretriesConsumed,\n\t\t\t\tstartTime,\n\t\t\t\toptions,\n\t\t\t})) {\n\t\t\t\tretriesConsumed++;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Should not reach here, but in case it does, throw an error\n\tthrow new Error('Retry attempts exhausted without throwing an error.');\n}\n\nexport function makeRetriable(function_, options) {\n\treturn function (...arguments_) {\n\t\treturn pRetry(() => function_.apply(this, arguments_), options);\n\t};\n}\n","'use strict';\n\nvar has = Object.prototype.hasOwnProperty\n , prefix = '~';\n\n/**\n * Constructor to create a storage for our `EE` objects.\n * An `Events` instance is a plain object whose properties are event names.\n *\n * @constructor\n * @private\n */\nfunction Events() {}\n\n//\n// We try to not inherit from `Object.prototype`. In some engines creating an\n// instance in this way is faster than calling `Object.create(null)` directly.\n// If `Object.create(null)` is not supported we prefix the event names with a\n// character to make sure that the built-in object properties are not\n// overridden or used as an attack vector.\n//\nif (Object.create) {\n Events.prototype = Object.create(null);\n\n //\n // This hack is needed because the `__proto__` property is still inherited in\n // some old browsers like Android 4, iPhone 5.1, Opera 11 and Safari 5.\n //\n if (!new Events().__proto__) prefix = false;\n}\n\n/**\n * Representation of a single event listener.\n *\n * @param {Function} fn The listener function.\n * @param {*} context The context to invoke the listener with.\n * @param {Boolean} [once=false] Specify if the listener is a one-time listener.\n * @constructor\n * @private\n */\nfunction EE(fn, context, once) {\n this.fn = fn;\n this.context = context;\n this.once = once || false;\n}\n\n/**\n * Add a listener for a given event.\n *\n * @param {EventEmitter} emitter Reference to the `EventEmitter` instance.\n * @param {(String|Symbol)} event The event name.\n * @param {Function} fn The listener function.\n * @param {*} context The context to invoke the listener with.\n * @param {Boolean} once Specify if the listener is a one-time listener.\n * @returns {EventEmitter}\n * @private\n */\nfunction addListener(emitter, event, fn, context, once) {\n if (typeof fn !== 'function') {\n throw new TypeError('The listener must be a function');\n }\n\n var listener = new EE(fn, context || emitter, once)\n , evt = prefix ? prefix + event : event;\n\n if (!emitter._events[evt]) emitter._events[evt] = listener, emitter._eventsCount++;\n else if (!emitter._events[evt].fn) emitter._events[evt].push(listener);\n else emitter._events[evt] = [emitter._events[evt], listener];\n\n return emitter;\n}\n\n/**\n * Clear event by name.\n *\n * @param {EventEmitter} emitter Reference to the `EventEmitter` instance.\n * @param {(String|Symbol)} evt The Event name.\n * @private\n */\nfunction clearEvent(emitter, evt) {\n if (--emitter._eventsCount === 0) emitter._events = new Events();\n else delete emitter._events[evt];\n}\n\n/**\n * Minimal `EventEmitter` interface that is molded against the Node.js\n * `EventEmitter` interface.\n *\n * @constructor\n * @public\n */\nfunction EventEmitter() {\n this._events = new Events();\n this._eventsCount = 0;\n}\n\n/**\n * Return an array listing the events for which the emitter has registered\n * listeners.\n *\n * @returns {Array}\n * @public\n */\nEventEmitter.prototype.eventNames = function eventNames() {\n var names = []\n , events\n , name;\n\n if (this._eventsCount === 0) return names;\n\n for (name in (events = this._events)) {\n if (has.call(events, name)) names.push(prefix ? name.slice(1) : name);\n }\n\n if (Object.getOwnPropertySymbols) {\n return names.concat(Object.getOwnPropertySymbols(events));\n }\n\n return names;\n};\n\n/**\n * Return the listeners registered for a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @returns {Array} The registered listeners.\n * @public\n */\nEventEmitter.prototype.listeners = function listeners(event) {\n var evt = prefix ? prefix + event : event\n , handlers = this._events[evt];\n\n if (!handlers) return [];\n if (handlers.fn) return [handlers.fn];\n\n for (var i = 0, l = handlers.length, ee = new Array(l); i < l; i++) {\n ee[i] = handlers[i].fn;\n }\n\n return ee;\n};\n\n/**\n * Return the number of listeners listening to a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @returns {Number} The number of listeners.\n * @public\n */\nEventEmitter.prototype.listenerCount = function listenerCount(event) {\n var evt = prefix ? prefix + event : event\n , listeners = this._events[evt];\n\n if (!listeners) return 0;\n if (listeners.fn) return 1;\n return listeners.length;\n};\n\n/**\n * Calls each of the listeners registered for a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @returns {Boolean} `true` if the event had listeners, else `false`.\n * @public\n */\nEventEmitter.prototype.emit = function emit(event, a1, a2, a3, a4, a5) {\n var evt = prefix ? prefix + event : event;\n\n if (!this._events[evt]) return false;\n\n var listeners = this._events[evt]\n , len = arguments.length\n , args\n , i;\n\n if (listeners.fn) {\n if (listeners.once) this.removeListener(event, listeners.fn, undefined, true);\n\n switch (len) {\n case 1: return listeners.fn.call(listeners.context), true;\n case 2: return listeners.fn.call(listeners.context, a1), true;\n case 3: return listeners.fn.call(listeners.context, a1, a2), true;\n case 4: return listeners.fn.call(listeners.context, a1, a2, a3), true;\n case 5: return listeners.fn.call(listeners.context, a1, a2, a3, a4), true;\n case 6: return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true;\n }\n\n for (i = 1, args = new Array(len -1); i < len; i++) {\n args[i - 1] = arguments[i];\n }\n\n listeners.fn.apply(listeners.context, args);\n } else {\n var length = listeners.length\n , j;\n\n for (i = 0; i < length; i++) {\n if (listeners[i].once) this.removeListener(event, listeners[i].fn, undefined, true);\n\n switch (len) {\n case 1: listeners[i].fn.call(listeners[i].context); break;\n case 2: listeners[i].fn.call(listeners[i].context, a1); break;\n case 3: listeners[i].fn.call(listeners[i].context, a1, a2); break;\n case 4: listeners[i].fn.call(listeners[i].context, a1, a2, a3); break;\n default:\n if (!args) for (j = 1, args = new Array(len -1); j < len; j++) {\n args[j - 1] = arguments[j];\n }\n\n listeners[i].fn.apply(listeners[i].context, args);\n }\n }\n }\n\n return true;\n};\n\n/**\n * Add a listener for a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @param {Function} fn The listener function.\n * @param {*} [context=this] The context to invoke the listener with.\n * @returns {EventEmitter} `this`.\n * @public\n */\nEventEmitter.prototype.on = function on(event, fn, context) {\n return addListener(this, event, fn, context, false);\n};\n\n/**\n * Add a one-time listener for a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @param {Function} fn The listener function.\n * @param {*} [context=this] The context to invoke the listener with.\n * @returns {EventEmitter} `this`.\n * @public\n */\nEventEmitter.prototype.once = function once(event, fn, context) {\n return addListener(this, event, fn, context, true);\n};\n\n/**\n * Remove the listeners of a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @param {Function} fn Only remove the listeners that match this function.\n * @param {*} context Only remove the listeners that have this context.\n * @param {Boolean} once Only remove one-time listeners.\n * @returns {EventEmitter} `this`.\n * @public\n */\nEventEmitter.prototype.removeListener = function removeListener(event, fn, context, once) {\n var evt = prefix ? prefix + event : event;\n\n if (!this._events[evt]) return this;\n if (!fn) {\n clearEvent(this, evt);\n return this;\n }\n\n var listeners = this._events[evt];\n\n if (listeners.fn) {\n if (\n listeners.fn === fn &&\n (!once || listeners.once) &&\n (!context || listeners.context === context)\n ) {\n clearEvent(this, evt);\n }\n } else {\n for (var i = 0, events = [], length = listeners.length; i < length; i++) {\n if (\n listeners[i].fn !== fn ||\n (once && !listeners[i].once) ||\n (context && listeners[i].context !== context)\n ) {\n events.push(listeners[i]);\n }\n }\n\n //\n // Reset the array, or remove it completely if we have no more listeners.\n //\n if (events.length) this._events[evt] = events.length === 1 ? events[0] : events;\n else clearEvent(this, evt);\n }\n\n return this;\n};\n\n/**\n * Remove all listeners, or those of the specified event.\n *\n * @param {(String|Symbol)} [event] The event name.\n * @returns {EventEmitter} `this`.\n * @public\n */\nEventEmitter.prototype.removeAllListeners = function removeAllListeners(event) {\n var evt;\n\n if (event) {\n evt = prefix ? prefix + event : event;\n if (this._events[evt]) clearEvent(this, evt);\n } else {\n this._events = new Events();\n this._eventsCount = 0;\n }\n\n return this;\n};\n\n//\n// Alias methods names because people roll like that.\n//\nEventEmitter.prototype.off = EventEmitter.prototype.removeListener;\nEventEmitter.prototype.addListener = EventEmitter.prototype.on;\n\n//\n// Expose the prefix.\n//\nEventEmitter.prefixed = prefix;\n\n//\n// Allow `EventEmitter` to be imported as module namespace.\n//\nEventEmitter.EventEmitter = EventEmitter;\n\n//\n// Expose the module.\n//\nif ('undefined' !== typeof module) {\n module.exports = EventEmitter;\n}\n","import EventEmitter from './index.js'\n\nexport { EventEmitter }\nexport default EventEmitter\n","export class TimeoutError extends Error {\n\tname = 'TimeoutError';\n\n\tconstructor(message, options) {\n\t\tsuper(message, options);\n\t\tError.captureStackTrace?.(this, TimeoutError);\n\t}\n}\n\nconst getAbortedReason = signal => signal.reason ?? new DOMException('This operation was aborted.', 'AbortError');\n\nexport default function pTimeout(promise, options) {\n\tconst {\n\t\tmilliseconds,\n\t\tfallback,\n\t\tmessage,\n\t\tcustomTimers = {setTimeout, clearTimeout},\n\t\tsignal,\n\t} = options;\n\n\tlet timer;\n\tlet abortHandler;\n\n\tconst wrappedPromise = new Promise((resolve, reject) => {\n\t\tif (typeof milliseconds !== 'number' || Math.sign(milliseconds) !== 1) {\n\t\t\tthrow new TypeError(`Expected \\`milliseconds\\` to be a positive number, got \\`${milliseconds}\\``);\n\t\t}\n\n\t\tif (signal?.aborted) {\n\t\t\treject(getAbortedReason(signal));\n\t\t\treturn;\n\t\t}\n\n\t\tif (signal) {\n\t\t\tabortHandler = () => {\n\t\t\t\treject(getAbortedReason(signal));\n\t\t\t};\n\n\t\t\tsignal.addEventListener('abort', abortHandler, {once: true});\n\t\t}\n\n\t\t// Use .then() instead of async IIFE to preserve stack traces\n\t\t// eslint-disable-next-line promise/prefer-await-to-then, promise/prefer-catch\n\t\tpromise.then(resolve, reject);\n\n\t\tif (milliseconds === Number.POSITIVE_INFINITY) {\n\t\t\treturn;\n\t\t}\n\n\t\t// We create the error outside of `setTimeout` to preserve the stack trace.\n\t\tconst timeoutError = new TimeoutError();\n\n\t\t// `.call(undefined, ...)` is needed for custom timers to avoid context issues\n\t\ttimer = customTimers.setTimeout.call(undefined, () => {\n\t\t\tif (fallback) {\n\t\t\t\ttry {\n\t\t\t\t\tresolve(fallback());\n\t\t\t\t} catch (error) {\n\t\t\t\t\treject(error);\n\t\t\t\t}\n\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (typeof promise.cancel === 'function') {\n\t\t\t\tpromise.cancel();\n\t\t\t}\n\n\t\t\tif (message === false) {\n\t\t\t\tresolve();\n\t\t\t} else if (message instanceof Error) {\n\t\t\t\treject(message);\n\t\t\t} else {\n\t\t\t\ttimeoutError.message = message ?? `Promise timed out after ${milliseconds} milliseconds`;\n\t\t\t\treject(timeoutError);\n\t\t\t}\n\t\t}, milliseconds);\n\t});\n\n\t// eslint-disable-next-line promise/prefer-await-to-then\n\tconst cancelablePromise = wrappedPromise.finally(() => {\n\t\tcancelablePromise.clear();\n\t\tif (abortHandler && signal) {\n\t\t\tsignal.removeEventListener('abort', abortHandler);\n\t\t}\n\t});\n\n\tcancelablePromise.clear = () => {\n\t\t// `.call(undefined, ...)` is needed for custom timers to avoid context issues\n\t\tcustomTimers.clearTimeout.call(undefined, timer);\n\t\ttimer = undefined;\n\t};\n\n\treturn cancelablePromise;\n}\n","// Port of lower_bound from https://en.cppreference.com/w/cpp/algorithm/lower_bound\n// Used to compute insertion index to keep queue sorted after insertion\nexport default function lowerBound(array, value, comparator) {\n let first = 0;\n let count = array.length;\n while (count > 0) {\n const step = Math.trunc(count / 2);\n let it = first + step;\n if (comparator(array[it], value) <= 0) {\n first = ++it;\n count -= step + 1;\n }\n else {\n count = step;\n }\n }\n return first;\n}\n","import lowerBound from './lower-bound.js';\nconst compactionThreshold = 100;\nexport default class PriorityQueue {\n #queue = [];\n // The queue is stored as a sorted array, but dequeued items are left before `#head` until compaction. Only items from `#head` onward are live, which keeps repeated dequeues amortized O(1).\n #head = 0;\n enqueue(run, options) {\n const { priority = 0, id, } = options ?? {};\n const { size } = this;\n const element = {\n priority,\n id,\n run,\n };\n if (size === 0) {\n // When the queue is logically empty, discard any consumed prefix before accepting new work.\n this.#queue.length = 0;\n this.#head = 0;\n this.#queue.push(element);\n return;\n }\n if (this.#queue.at(-1).priority >= priority) {\n // Same-priority and lower-priority items belong after the current tail. Appending preserves FIFO order for equal priorities.\n this.#queue.push(element);\n return;\n }\n // Binary insertion must run on the live sorted range only.\n this.#compact();\n const index = lowerBound(this.#queue, element, (a, b) => b.priority - a.priority);\n this.#queue.splice(index, 0, element);\n }\n setPriority(id, priority) {\n // A dequeued item with the same id is no longer part of the queue.\n const index = this.#queue.findIndex((element, index) => index >= this.#head && element.id === id);\n if (index === -1) {\n throw new ReferenceError(`No promise function with the id \"${id}\" exists in the queue.`);\n }\n const [item] = this.#queue.splice(index, 1);\n this.enqueue(item.run, { priority, id });\n }\n remove(idOrRun) {\n const index = this.#queue.findIndex((element, index) => {\n // The consumed prefix may still contain references that should not be removable.\n if (index < this.#head) {\n return false;\n }\n if (typeof idOrRun === 'string') {\n return element.id === idOrRun;\n }\n return element.run === idOrRun;\n });\n if (index !== -1) {\n this.#queue.splice(index, 1);\n }\n }\n dequeue() {\n if (this.#head === this.#queue.length) {\n return undefined;\n }\n const item = this.#queue[this.#head];\n this.#head++;\n if (this.#head === this.#queue.length) {\n // Fully drained queues are reset immediately so the next enqueue starts from a clean array.\n this.#queue.length = 0;\n this.#head = 0;\n }\n else if (this.#head > compactionThreshold && this.#head > this.#queue.length / 2) {\n // Keep repeated dequeues cheap, but stop the consumed prefix from growing without bound.\n this.#compact();\n }\n return item?.run;\n }\n filter(options) {\n const result = [];\n for (let index = this.#head; index < this.#queue.length; index++) {\n const element = this.#queue[index];\n if (element.priority === options.priority) {\n result.push(element.run);\n }\n }\n return result;\n }\n get size() {\n return this.#queue.length - this.#head;\n }\n #compact() {\n // Compaction restores the invariant that the whole array is the live sorted range.\n if (this.#head === 0) {\n return;\n }\n this.#queue.splice(0, this.#head);\n this.#head = 0;\n }\n}\n","import { EventEmitter } from 'eventemitter3';\nimport pTimeout from 'p-timeout';\nimport PriorityQueue from './priority-queue.js';\n/**\nPromise queue with concurrency control.\n*/\nexport default class PQueue extends EventEmitter {\n #carryoverIntervalCount;\n #isIntervalIgnored;\n #intervalCount = 0;\n #intervalCap;\n #rateLimitedInInterval = false;\n #rateLimitFlushScheduled = false;\n #interval;\n #intervalEnd = 0;\n #lastExecutionTime = 0;\n #intervalId;\n #timeoutId;\n #strict;\n // Circular buffer implementation for better performance\n #strictTicks = [];\n #strictTicksStartIndex = 0;\n #queue;\n #queueClass;\n #pending = 0;\n // The `!` is needed because of https://github.com/microsoft/TypeScript/issues/32194\n #concurrency;\n #isPaused;\n // Use to assign a unique identifier to a promise function, if not explicitly specified\n #idAssigner = 1n;\n // Track currently running tasks for debugging\n #runningTasks = new Map();\n #queueAbortListenerCleanupFunctions = new Set();\n /**\n Get or set the default timeout for all tasks. Can be changed at runtime.\n\n Operations will throw a `TimeoutError` if they don't complete within the specified time.\n\n The timeout begins when the operation is dequeued and starts execution, not while it's waiting in the queue.\n\n @example\n ```\n const queue = new PQueue({timeout: 5000});\n\n // Change timeout for all future tasks\n queue.timeout = 10000;\n ```\n */\n timeout;\n constructor(options) {\n super();\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n options = {\n carryoverIntervalCount: false,\n intervalCap: Number.POSITIVE_INFINITY,\n interval: 0,\n concurrency: Number.POSITIVE_INFINITY,\n autoStart: true,\n queueClass: PriorityQueue,\n strict: false,\n ...options,\n };\n if (!(typeof options.intervalCap === 'number' && options.intervalCap >= 1)) {\n throw new TypeError(`Expected \\`intervalCap\\` to be a number from 1 and up, got \\`${options.intervalCap?.toString() ?? ''}\\` (${typeof options.intervalCap})`);\n }\n if (options.interval === undefined || !(Number.isFinite(options.interval) && options.interval >= 0)) {\n throw new TypeError(`Expected \\`interval\\` to be a finite number >= 0, got \\`${options.interval?.toString() ?? ''}\\` (${typeof options.interval})`);\n }\n if (options.strict && options.interval === 0) {\n throw new TypeError('The `strict` option requires a non-zero `interval`');\n }\n if (options.strict && options.intervalCap === Number.POSITIVE_INFINITY) {\n throw new TypeError('The `strict` option requires a finite `intervalCap`');\n }\n // TODO: Remove this fallback in the next major version\n // eslint-disable-next-line @typescript-eslint/no-deprecated\n this.#carryoverIntervalCount = options.carryoverIntervalCount ?? options.carryoverConcurrencyCount ?? false;\n this.#isIntervalIgnored = options.intervalCap === Number.POSITIVE_INFINITY || options.interval === 0;\n this.#intervalCap = options.intervalCap;\n this.#interval = options.interval;\n this.#strict = options.strict;\n this.#queue = new options.queueClass();\n this.#queueClass = options.queueClass;\n this.concurrency = options.concurrency;\n if (options.timeout !== undefined && !(Number.isFinite(options.timeout) && options.timeout > 0)) {\n throw new TypeError(`Expected \\`timeout\\` to be a positive finite number, got \\`${options.timeout}\\` (${typeof options.timeout})`);\n }\n this.timeout = options.timeout;\n this.#isPaused = options.autoStart === false;\n this.#setupRateLimitTracking();\n }\n #cleanupStrictTicks(now) {\n // Remove ticks outside the current interval window using circular buffer approach\n while (this.#strictTicksStartIndex < this.#strictTicks.length) {\n const oldestTick = this.#strictTicks[this.#strictTicksStartIndex];\n if (oldestTick !== undefined && now - oldestTick >= this.#interval) {\n this.#strictTicksStartIndex++;\n }\n else {\n break;\n }\n }\n // Compact the array when it becomes inefficient or fully consumed\n // Compact when: (start index is large AND more than half wasted) OR all ticks expired\n const shouldCompact = (this.#strictTicksStartIndex > 100 && this.#strictTicksStartIndex > this.#strictTicks.length / 2)\n || this.#strictTicksStartIndex === this.#strictTicks.length;\n if (shouldCompact) {\n this.#strictTicks = this.#strictTicks.slice(this.#strictTicksStartIndex);\n this.#strictTicksStartIndex = 0;\n }\n }\n // Helper methods for interval consumption\n #consumeIntervalSlot(now) {\n if (this.#strict) {\n this.#strictTicks.push(now);\n }\n else {\n this.#intervalCount++;\n }\n }\n #rollbackIntervalSlot() {\n if (this.#strict) {\n // Pop from the end of the actual data (not from start index)\n if (this.#strictTicks.length > this.#strictTicksStartIndex) {\n this.#strictTicks.pop();\n }\n }\n else if (this.#intervalCount > 0) {\n this.#intervalCount--;\n }\n }\n #getActiveTicksCount() {\n return this.#strictTicks.length - this.#strictTicksStartIndex;\n }\n get #doesIntervalAllowAnother() {\n if (this.#isIntervalIgnored) {\n return true;\n }\n if (this.#strict) {\n // Cleanup already done by #isIntervalPausedAt before this is called\n return this.#getActiveTicksCount() < this.#intervalCap;\n }\n return this.#intervalCount < this.#intervalCap;\n }\n get #doesConcurrentAllowAnother() {\n return this.#pending < this.#concurrency;\n }\n #next() {\n this.#pending--;\n if (this.#pending === 0) {\n this.emit('pendingZero');\n }\n this.#tryToStartAnother();\n this.emit('next');\n }\n #onResumeInterval() {\n // Clear timeout ID before processing to prevent race condition\n // Must clear before #onInterval to allow new timeouts to be scheduled\n this.#timeoutId = undefined;\n this.#onInterval();\n this.#initializeIntervalIfNeeded();\n }\n #isIntervalPausedAt(now) {\n // Strict mode: check if we need to wait for oldest tick to age out\n if (this.#strict) {\n this.#cleanupStrictTicks(now);\n // If at capacity, need to wait for oldest tick to age out\n const activeTicksCount = this.#getActiveTicksCount();\n if (activeTicksCount >= this.#intervalCap) {\n const oldestTick = this.#strictTicks[this.#strictTicksStartIndex];\n // After cleanup, remaining ticks are within interval, so delay is always > 0\n const delay = this.#interval - (now - oldestTick);\n this.#createIntervalTimeout(delay);\n return true;\n }\n return false;\n }\n // Fixed window mode (original logic)\n if (this.#intervalId === undefined) {\n const delay = this.#intervalEnd - now;\n if (delay < 0) {\n // If the interval has expired while idle, check if we should enforce the interval\n // from the last task execution. This ensures proper spacing between tasks even\n // when the queue becomes empty and then new tasks are added.\n if (this.#lastExecutionTime > 0) {\n const timeSinceLastExecution = now - this.#lastExecutionTime;\n if (timeSinceLastExecution < this.#interval) {\n // Not enough time has passed since the last task execution\n this.#createIntervalTimeout(this.#interval - timeSinceLastExecution);\n return true;\n }\n }\n // Enough time has passed or no previous execution, allow execution\n this.#intervalCount = (this.#carryoverIntervalCount) ? this.#pending : 0;\n }\n else {\n // Act as the interval is pending\n this.#createIntervalTimeout(delay);\n return true;\n }\n }\n return false;\n }\n #createIntervalTimeout(delay) {\n if (this.#timeoutId !== undefined) {\n return;\n }\n this.#timeoutId = setTimeout(() => {\n this.#onResumeInterval();\n }, delay);\n }\n #clearIntervalTimer() {\n if (this.#intervalId) {\n clearInterval(this.#intervalId);\n this.#intervalId = undefined;\n }\n }\n #clearTimeoutTimer() {\n if (this.#timeoutId) {\n clearTimeout(this.#timeoutId);\n this.#timeoutId = undefined;\n }\n }\n #tryToStartAnother() {\n if (this.#queue.size === 0) {\n // We can clear the interval (\"pause\")\n // Because we can redo it later (\"resume\")\n this.#clearIntervalTimer();\n this.emit('empty');\n if (this.#pending === 0) {\n // Clear timeout as well when completely idle\n this.#clearTimeoutTimer();\n // Compact strict ticks when idle to free memory\n if (this.#strict && this.#strictTicksStartIndex > 0) {\n const now = Date.now();\n this.#cleanupStrictTicks(now);\n }\n this.emit('idle');\n }\n return false;\n }\n let taskStarted = false;\n if (!this.#isPaused) {\n const now = Date.now();\n const canInitializeInterval = !this.#isIntervalPausedAt(now);\n if (this.#doesIntervalAllowAnother && this.#doesConcurrentAllowAnother) {\n const job = this.#queue.dequeue();\n if (!this.#isIntervalIgnored) {\n this.#consumeIntervalSlot(now);\n this.#scheduleRateLimitUpdate();\n }\n this.emit('active');\n job();\n if (canInitializeInterval) {\n this.#initializeIntervalIfNeeded();\n }\n taskStarted = true;\n }\n }\n return taskStarted;\n }\n #initializeIntervalIfNeeded() {\n if (this.#isIntervalIgnored || this.#intervalId !== undefined) {\n return;\n }\n // Strict mode uses timeouts instead of interval timers\n if (this.#strict) {\n return;\n }\n this.#intervalId = setInterval(() => {\n this.#onInterval();\n }, this.#interval);\n this.#intervalEnd = Date.now() + this.#interval;\n }\n #onInterval() {\n // Non-strict mode uses interval timers and intervalCount\n if (!this.#strict) {\n if (this.#intervalCount === 0 && this.#pending === 0 && this.#intervalId) {\n this.#clearIntervalTimer();\n }\n this.#intervalCount = this.#carryoverIntervalCount ? this.#pending : 0;\n }\n this.#processQueue();\n this.#scheduleRateLimitUpdate();\n }\n /**\n Executes all queued functions until it reaches the limit.\n */\n #processQueue() {\n // eslint-disable-next-line no-empty\n while (this.#tryToStartAnother()) { }\n }\n get concurrency() {\n return this.#concurrency;\n }\n set concurrency(newConcurrency) {\n if (!(typeof newConcurrency === 'number' && newConcurrency >= 1)) {\n throw new TypeError(`Expected \\`concurrency\\` to be a number from 1 and up, got \\`${newConcurrency}\\` (${typeof newConcurrency})`);\n }\n this.#concurrency = newConcurrency;\n this.#processQueue();\n }\n /**\n Updates the priority of a promise function by its id, affecting its execution order. Requires a defined concurrency limit to take effect.\n\n For example, this can be used to prioritize a promise function to run earlier.\n\n ```js\n import PQueue from 'p-queue';\n\n const queue = new PQueue({concurrency: 1});\n\n queue.add(async () => '🦄', {priority: 1});\n queue.add(async () => '🦀', {priority: 0, id: '🦀'});\n queue.add(async () => '🦄', {priority: 1});\n queue.add(async () => '🦄', {priority: 1});\n\n queue.setPriority('🦀', 2);\n ```\n\n In this case, the promise function with `id: '🦀'` runs second.\n\n You can also deprioritize a promise function to delay its execution:\n\n ```js\n import PQueue from 'p-queue';\n\n const queue = new PQueue({concurrency: 1});\n\n queue.add(async () => '🦄', {priority: 1});\n queue.add(async () => '🦀', {priority: 1, id: '🦀'});\n queue.add(async () => '🦄');\n queue.add(async () => '🦄', {priority: 0});\n\n queue.setPriority('🦀', -1);\n ```\n Here, the promise function with `id: '🦀'` executes last.\n */\n setPriority(id, priority) {\n if (typeof priority !== 'number' || !Number.isFinite(priority)) {\n throw new TypeError(`Expected \\`priority\\` to be a finite number, got \\`${priority}\\` (${typeof priority})`);\n }\n this.#queue.setPriority(id, priority);\n }\n async add(function_, options = {}) {\n // Create a copy to avoid mutating the original options object\n options = {\n timeout: this.timeout,\n ...options,\n // Assign unique ID if not provided\n id: options.id ?? (this.#idAssigner++).toString(),\n };\n return new Promise((resolve, reject) => {\n // Create a unique symbol for tracking this task\n const taskSymbol = Symbol(`task-${options.id}`);\n let cleanupQueueAbortHandler = () => undefined;\n const run = async () => {\n // Task is now running — remove the queued-state abort listener\n cleanupQueueAbortHandler();\n this.#pending++;\n // Track this running task\n this.#runningTasks.set(taskSymbol, {\n id: options.id,\n priority: options.priority ?? 0, // Match priority-queue default\n startTime: Date.now(),\n timeout: options.timeout,\n });\n let eventListener;\n try {\n // Check abort signal - if aborted, need to decrement the counter\n // that was incremented in tryToStartAnother\n try {\n options.signal?.throwIfAborted();\n }\n catch (error) {\n this.#rollbackIntervalConsumption();\n // Clean up tracking before throwing\n this.#runningTasks.delete(taskSymbol);\n throw error;\n }\n this.#lastExecutionTime = Date.now();\n let operation = function_({ signal: options.signal });\n if (options.timeout) {\n operation = pTimeout(Promise.resolve(operation), {\n milliseconds: options.timeout,\n message: `Task timed out after ${options.timeout}ms (queue has ${this.#pending} running, ${this.#queue.size} waiting)`,\n });\n }\n if (options.signal) {\n const { signal } = options;\n operation = Promise.race([operation, new Promise((_resolve, reject) => {\n eventListener = () => {\n reject(signal.reason);\n };\n signal.addEventListener('abort', eventListener, { once: true });\n })]);\n }\n const result = await operation;\n resolve(result);\n this.emit('completed', result);\n }\n catch (error) {\n reject(error);\n this.emit('error', error);\n }\n finally {\n // Clean up abort event listener\n if (eventListener) {\n options.signal?.removeEventListener('abort', eventListener);\n }\n // Remove from running tasks\n this.#runningTasks.delete(taskSymbol);\n // Use queueMicrotask to prevent deep recursion while maintaining timing\n queueMicrotask(() => {\n this.#next();\n });\n }\n };\n this.#queue.enqueue(run, options);\n const removeQueuedTask = () => {\n if (this.#queue instanceof PriorityQueue) {\n this.#queue.remove(run);\n return;\n }\n this.#queue.remove?.(options.id); // Intentionally best-effort: queued abort removal is only supported for queue classes that implement `.remove()`.\n };\n // Handle abort while task is waiting in the queue\n if (options.signal) {\n const { signal } = options;\n const queueAbortHandler = () => {\n cleanupQueueAbortHandler();\n removeQueuedTask();\n reject(signal.reason);\n this.#tryToStartAnother();\n this.emit('next');\n };\n cleanupQueueAbortHandler = () => {\n signal.removeEventListener('abort', queueAbortHandler);\n this.#queueAbortListenerCleanupFunctions.delete(cleanupQueueAbortHandler);\n };\n if (signal.aborted) {\n queueAbortHandler();\n return;\n }\n signal.addEventListener('abort', queueAbortHandler, { once: true });\n this.#queueAbortListenerCleanupFunctions.add(cleanupQueueAbortHandler);\n }\n this.emit('add');\n this.#tryToStartAnother();\n });\n }\n async addAll(functions, options) {\n return Promise.all(functions.map(async (function_) => this.add(function_, options)));\n }\n /**\n Start (or resume) executing enqueued tasks within concurrency limit. No need to call this if queue is not paused (via `options.autoStart = false` or by `.pause()` method.)\n */\n start() {\n if (!this.#isPaused) {\n return this;\n }\n this.#isPaused = false;\n this.#processQueue();\n return this;\n }\n /**\n Put queue execution on hold.\n */\n pause() {\n this.#isPaused = true;\n }\n /**\n Clear the queue.\n */\n clear() {\n for (const cleanupQueueAbortHandler of this.#queueAbortListenerCleanupFunctions) {\n cleanupQueueAbortHandler();\n }\n this.#queue = new this.#queueClass();\n // Clear interval timer since queue is now empty (consistent with #tryToStartAnother)\n this.#clearIntervalTimer();\n // Note: We preserve strict mode rate-limiting state (ticks and timeout)\n // because clear() only clears queued tasks, not rate limit history.\n // This ensures that rate limits are still enforced after clearing the queue.\n // Note: We don't clear #runningTasks as those tasks are still running\n // They will be removed when they complete in the finally block\n // Force synchronous update since clear() should have immediate effect\n this.#updateRateLimitState();\n // Emit events so waiters (onEmpty, onIdle, onSizeLessThan) can resolve\n this.emit('empty');\n if (this.#pending === 0) {\n this.#clearTimeoutTimer();\n this.emit('idle');\n }\n this.emit('next');\n }\n /**\n Can be called multiple times. Useful if you for example add additional items at a later time.\n\n @returns A promise that settles when the queue becomes empty.\n */\n async onEmpty() {\n // Instantly resolve if the queue is empty\n if (this.#queue.size === 0) {\n return;\n }\n await this.#onEvent('empty');\n }\n /**\n @returns A promise that settles when the queue size is less than the given limit: `queue.size < limit`.\n\n If you want to avoid having the queue grow beyond a certain size you can `await queue.onSizeLessThan()` before adding a new item.\n\n Note that this only limits the number of items waiting to start. There could still be up to `concurrency` jobs already running that this call does not include in its calculation.\n */\n async onSizeLessThan(limit) {\n // Instantly resolve if the queue is empty.\n if (this.#queue.size < limit) {\n return;\n }\n await this.#onEvent('next', () => this.#queue.size < limit);\n }\n /**\n The difference with `.onEmpty` is that `.onIdle` guarantees that all work from the queue has finished. `.onEmpty` merely signals that the queue is empty, but it could mean that some promises haven't completed yet.\n\n @returns A promise that settles when the queue becomes empty, and all promises have completed; `queue.size === 0 && queue.pending === 0`.\n */\n async onIdle() {\n // Instantly resolve if none pending and if nothing else is queued\n if (this.#pending === 0 && this.#queue.size === 0) {\n return;\n }\n await this.#onEvent('idle');\n }\n /**\n The difference with `.onIdle` is that `.onPendingZero` only waits for currently running tasks to finish, ignoring queued tasks.\n\n @returns A promise that settles when all currently running tasks have completed; `queue.pending === 0`.\n */\n async onPendingZero() {\n if (this.#pending === 0) {\n return;\n }\n await this.#onEvent('pendingZero');\n }\n /**\n @returns A promise that settles when the queue becomes rate-limited due to intervalCap.\n */\n async onRateLimit() {\n if (this.isRateLimited) {\n return;\n }\n await this.#onEvent('rateLimit');\n }\n /**\n @returns A promise that settles when the queue is no longer rate-limited.\n */\n async onRateLimitCleared() {\n if (!this.isRateLimited) {\n return;\n }\n await this.#onEvent('rateLimitCleared');\n }\n /**\n @returns A promise that rejects when any task in the queue errors.\n\n Use with `Promise.race([queue.onError(), queue.onIdle()])` to fail fast on the first error while still resolving normally when the queue goes idle.\n\n Important: The promise returned by `add()` still rejects. You must handle each `add()` promise (for example, `.catch(() => {})`) to avoid unhandled rejections.\n\n @example\n ```\n import PQueue from 'p-queue';\n\n const queue = new PQueue({concurrency: 2});\n\n queue.add(() => fetchData(1)).catch(() => {});\n queue.add(() => fetchData(2)).catch(() => {});\n queue.add(() => fetchData(3)).catch(() => {});\n\n // Stop processing on first error\n try {\n await Promise.race([\n queue.onError(),\n queue.onIdle()\n ]);\n } catch (error) {\n queue.pause(); // Stop processing remaining tasks\n console.error('Queue failed:', error);\n }\n ```\n */\n // eslint-disable-next-line @typescript-eslint/promise-function-async\n onError() {\n return new Promise((_resolve, reject) => {\n const handleError = (error) => {\n this.off('error', handleError);\n reject(error);\n };\n this.on('error', handleError);\n });\n }\n async #onEvent(event, filter) {\n return new Promise(resolve => {\n const listener = () => {\n if (filter && !filter()) {\n return;\n }\n this.off(event, listener);\n resolve();\n };\n this.on(event, listener);\n });\n }\n /**\n Size of the queue, the number of queued items waiting to run.\n */\n get size() {\n return this.#queue.size;\n }\n /**\n Size of the queue, filtered by the given options.\n\n For example, this can be used to find the number of items remaining in the queue with a specific priority level.\n */\n sizeBy(options) {\n // eslint-disable-next-line unicorn/no-array-callback-reference\n return this.#queue.filter(options).length;\n }\n /**\n Number of running items (no longer in the queue).\n */\n get pending() {\n return this.#pending;\n }\n /**\n Whether the queue is currently paused.\n */\n get isPaused() {\n return this.#isPaused;\n }\n #setupRateLimitTracking() {\n // Only schedule updates when rate limiting is enabled\n if (this.#isIntervalIgnored) {\n return;\n }\n // Wire up to lifecycle events that affect rate limit state\n // Only 'add' and 'next' can actually change rate limit state\n this.on('add', () => {\n if (this.#queue.size > 0) {\n this.#scheduleRateLimitUpdate();\n }\n });\n this.on('next', () => {\n this.#scheduleRateLimitUpdate();\n });\n }\n #scheduleRateLimitUpdate() {\n // Skip if rate limiting is not enabled or already scheduled\n if (this.#isIntervalIgnored || this.#rateLimitFlushScheduled) {\n return;\n }\n this.#rateLimitFlushScheduled = true;\n queueMicrotask(() => {\n this.#rateLimitFlushScheduled = false;\n this.#updateRateLimitState();\n });\n }\n #rollbackIntervalConsumption() {\n if (this.#isIntervalIgnored) {\n return;\n }\n this.#rollbackIntervalSlot();\n this.#scheduleRateLimitUpdate();\n }\n #updateRateLimitState() {\n const previous = this.#rateLimitedInInterval;\n // Early exit if rate limiting is disabled or queue is empty\n if (this.#isIntervalIgnored || this.#queue.size === 0) {\n if (previous) {\n this.#rateLimitedInInterval = false;\n this.emit('rateLimitCleared');\n }\n return;\n }\n // Get the current count based on mode\n let count;\n if (this.#strict) {\n const now = Date.now();\n this.#cleanupStrictTicks(now);\n count = this.#getActiveTicksCount();\n }\n else {\n count = this.#intervalCount;\n }\n const shouldBeRateLimited = count >= this.#intervalCap;\n if (shouldBeRateLimited !== previous) {\n this.#rateLimitedInInterval = shouldBeRateLimited;\n this.emit(shouldBeRateLimited ? 'rateLimit' : 'rateLimitCleared');\n }\n }\n /**\n Whether the queue is currently rate-limited due to intervalCap.\n */\n get isRateLimited() {\n return this.#rateLimitedInInterval;\n }\n /**\n Whether the queue is saturated. Returns `true` when:\n - All concurrency slots are occupied and tasks are waiting, OR\n - The queue is rate-limited and tasks are waiting\n\n Useful for detecting backpressure and potential hanging tasks.\n\n ```js\n import PQueue from 'p-queue';\n\n const queue = new PQueue({concurrency: 2});\n\n // Backpressure handling\n if (queue.isSaturated) {\n console.log('Queue is saturated, waiting for capacity...');\n await queue.onSizeLessThan(queue.concurrency);\n }\n\n // Monitoring for stuck tasks\n setInterval(() => {\n if (queue.isSaturated) {\n console.warn(`Queue saturated: ${queue.pending} running, ${queue.size} waiting`);\n }\n }, 60000);\n ```\n */\n get isSaturated() {\n return (this.#pending === this.#concurrency && this.#queue.size > 0)\n || (this.isRateLimited && this.#queue.size > 0);\n }\n /**\n The tasks currently being executed. Each task includes its `id`, `priority`, `startTime`, `timeout` (if set), and `timeoutRemaining` (milliseconds until the task times out, or `undefined` if no timeout is set).\n\n Returns an array of task info objects.\n\n ```js\n import PQueue from 'p-queue';\n\n const queue = new PQueue({concurrency: 2, timeout: 10000});\n\n // Add tasks with IDs for better debugging\n queue.add(() => fetchUser(123), {id: 'user-123'});\n queue.add(() => fetchPosts(456), {id: 'posts-456', priority: 1});\n\n // Check what's running\n console.log(queue.runningTasks);\n // => [{\n // id: 'user-123',\n // priority: 0,\n // startTime: 1759253001716,\n // timeout: 10000,\n // timeoutRemaining: 9700\n // }, {\n // id: 'posts-456',\n // priority: 1,\n // startTime: 1759253001916,\n // timeout: 10000,\n // timeoutRemaining: 9900\n // }]\n ```\n */\n get runningTasks() {\n // Return fresh array with fresh objects to prevent mutations\n return [...this.#runningTasks.values()].map(task => ({\n ...task,\n timeoutRemaining: task.timeout ? Math.max(0, task.startTime + task.timeout - Date.now()) : undefined,\n }));\n }\n}\nexport { default as PriorityQueue } from './priority-queue.js';\n/**\nError thrown when a task times out.\n\n@example\n```\nimport PQueue, {TimeoutError} from 'p-queue';\n\nconst queue = new PQueue({timeout: 1000});\n\ntry {\n await queue.add(() => someTask());\n} catch (error) {\n if (error instanceof TimeoutError) {\n console.log('Task timed out');\n }\n}\n```\n*/\nexport { TimeoutError } from 'p-timeout';\n","/**\n * Comprehensive error handling for BMLT Query Client\n */\n\nexport enum BmltErrorType {\n API_ERROR = 'ApiError',\n NETWORK_ERROR = 'NetworkError',\n VALIDATION_ERROR = 'ValidationError',\n GEOCODING_ERROR = 'GeocodingError',\n RATE_LIMIT_ERROR = 'RateLimitError',\n TIMEOUT_ERROR = 'TimeoutError',\n AUTHENTICATION_ERROR = 'AuthenticationError',\n SERVER_ERROR = 'ServerError',\n CLIENT_ERROR = 'ClientError',\n CONFIGURATION_ERROR = 'ConfigurationError',\n}\n\nexport class BmltQueryError extends Error {\n public readonly type: BmltErrorType;\n public readonly statusCode?: number;\n public readonly response?: unknown;\n public readonly originalError?: Error;\n public readonly context?: Record<string, unknown>;\n\n constructor(\n type: BmltErrorType,\n message: string,\n options: {\n statusCode?: number;\n response?: unknown;\n originalError?: Error;\n context?: Record<string, unknown>;\n } = {}\n ) {\n super(message);\n this.name = 'BmltQueryError';\n this.type = type;\n this.statusCode = options.statusCode;\n this.response = options.response;\n this.originalError = options.originalError;\n this.context = options.context;\n\n // Ensure proper prototype chain for instanceof checks\n Object.setPrototypeOf(this, BmltQueryError.prototype);\n }\n\n /**\n * Check if error is of a specific type\n */\n isType(type: BmltErrorType): boolean {\n return this.type === type;\n }\n\n /**\n * Check if error is retryable\n */\n isRetryable(): boolean {\n const retryableTypes = [\n BmltErrorType.NETWORK_ERROR,\n BmltErrorType.TIMEOUT_ERROR,\n BmltErrorType.RATE_LIMIT_ERROR,\n BmltErrorType.SERVER_ERROR,\n ];\n return retryableTypes.includes(this.type);\n }\n\n /**\n * Check if error is a client-side error (4xx)\n */\n isClientError(): boolean {\n return this.statusCode !== undefined && this.statusCode >= 400 && this.statusCode < 500;\n }\n\n /**\n * Check if error is a server-side error (5xx)\n */\n isServerError(): boolean {\n return this.statusCode !== undefined && this.statusCode >= 500;\n }\n\n /**\n * Get a user-friendly error message\n */\n getUserMessage(): string {\n switch (this.type) {\n case BmltErrorType.NETWORK_ERROR:\n return 'Unable to connect to the BMLT server. Please check your internet connection and try again.';\n\n case BmltErrorType.TIMEOUT_ERROR:\n return 'The request timed out. Please try again later.';\n\n case BmltErrorType.RATE_LIMIT_ERROR:\n return 'Too many requests. Please wait a moment and try again.';\n\n case BmltErrorType.GEOCODING_ERROR:\n return 'Unable to find the specified address. Please check the address and try again.';\n\n case BmltErrorType.VALIDATION_ERROR:\n return 'Invalid input provided. Please check your parameters and try again.';\n\n case BmltErrorType.AUTHENTICATION_ERROR:\n return 'Authentication failed. Please check your credentials.';\n\n case BmltErrorType.SERVER_ERROR:\n return 'The BMLT server encountered an error. Please try again later.';\n\n case BmltErrorType.API_ERROR:\n if (this.statusCode === 404) {\n return 'The requested resource was not found.';\n }\n return 'An error occurred while communicating with the BMLT server.';\n\n case BmltErrorType.CONFIGURATION_ERROR:\n return 'Invalid configuration. Please check your settings.';\n\n default:\n return this.message || 'An unexpected error occurred.';\n }\n }\n\n /**\n * Convert error to JSON for logging\n */\n toJSON() {\n return {\n name: this.name,\n type: this.type,\n message: this.message,\n statusCode: this.statusCode,\n response: this.response,\n context: this.context,\n stack: this.stack,\n originalError: this.originalError\n ? {\n name: this.originalError.name,\n message: this.originalError.message,\n stack: this.originalError.stack,\n }\n : undefined,\n };\n }\n}\n\n/**\n * Factory class for creating specific error types\n */\nexport class ErrorFactory {\n static createApiError(\n message: string,\n statusCode?: number,\n response?: unknown,\n originalError?: Error\n ): BmltQueryError {\n let type: BmltErrorType;\n\n if (statusCode) {\n if (statusCode >= 500) {\n type = BmltErrorType.SERVER_ERROR;\n } else if (statusCode === 401 || statusCode === 403) {\n type = BmltErrorType.AUTHENTICATION_ERROR;\n } else if (statusCode === 429) {\n type = BmltErrorType.RATE_LIMIT_ERROR;\n } else if (statusCode >= 400) {\n type = BmltErrorType.CLIENT_ERROR;\n } else {\n type = BmltErrorType.API_ERROR;\n }\n } else {\n type = BmltErrorType.API_ERROR;\n }\n\n return new BmltQueryError(type, message, {\n statusCode,\n response,\n originalError,\n });\n }\n\n static createNetworkError(message: string, originalError?: Error): BmltQueryError {\n return new BmltQueryError(BmltErrorType.NETWORK_ERROR, message, {\n originalError,\n });\n }\n\n static createTimeoutError(message: string, originalError?: Error): BmltQueryError {\n return new BmltQueryError(BmltErrorType.TIMEOUT_ERROR, message, {\n originalError,\n });\n }\n\n static createValidationError(message: string, context?: Record<string, unknown>): BmltQueryError {\n return new BmltQueryError(BmltErrorType.VALIDATION_ERROR, message, {\n context,\n });\n }\n\n static createGeocodingError(\n message: string,\n originalError?: Error,\n context?: Record<string, unknown>\n ): BmltQueryError {\n return new BmltQueryError(BmltErrorType.GEOCODING_ERROR, message, {\n originalError,\n context,\n });\n }\n\n static createRateLimitError(\n message: string,\n statusCode?: number,\n response?: unknown\n ): BmltQueryError {\n return new BmltQueryError(BmltErrorType.RATE_LIMIT_ERROR, message, {\n statusCode,\n response,\n });\n }\n\n static createConfigurationError(\n message: string,\n context?: Record<string, unknown>\n ): BmltQueryError {\n return new BmltQueryError(BmltErrorType.CONFIGURATION_ERROR, message, {\n context,\n });\n }\n}\n\n/**\n * Error handler utility class\n */\nexport class ErrorHandler {\n /**\n * Handle and transform fetch errors\n */\n static handleFetchError(error: unknown, response?: Response): BmltQueryError {\n // Handle AbortError (timeout)\n if (error instanceof Error && error.name === 'AbortError') {\n return ErrorFactory.createTimeoutError('Request timeout', error);\n }\n\n // Handle TypeError (network errors)\n if (error instanceof TypeError) {\n return ErrorFactory.createNetworkError('Network connection failed', error);\n }\n\n if (response && !response.ok) {\n // Server responded with error status\n const message = `HTTP ${response.status}: ${response.statusText}`;\n return ErrorFactory.createApiError(message, response.status, undefined, error as Error);\n }\n\n // Handle other errors\n if (error instanceof Error) {\n return ErrorFactory.createApiError(error.message, undefined, undefined, error);\n }\n\n // Fallback for unknown errors\n return ErrorFactory.createApiError(\n 'Unknown error occurred',\n undefined,\n undefined,\n new Error(String(error))\n );\n }\n\n /**\n * @deprecated Use handleFetchError instead\n */\n static handleAxiosError(error: any): BmltQueryError {\n return ErrorHandler.handleFetchError(error);\n }\n\n /**\n * Handle validation errors with detailed context\n */\n static handleValidationError(\n field: string,\n value: unknown,\n expectedType: string,\n constraints?: string[]\n ): BmltQueryError {\n let message = `Invalid ${field}: expected ${expectedType}`;\n\n if (constraints && constraints.length > 0) {\n message += ` (${constraints.join(', ')})`;\n }\n\n return ErrorFactory.createValidationError(message, {\n field,\n value,\n expectedType,\n constraints,\n });\n }\n\n /**\n * Handle endpoint validation errors\n */\n static handleEndpointError(endpoint: string, format: string): BmltQueryError {\n const message = `Invalid endpoint/format combination: ${endpoint} with ${format}`;\n return ErrorFactory.createValidationError(message, {\n endpoint,\n format,\n });\n }\n\n /**\n * Handle URL validation errors\n */\n static handleUrlError(url: string, reason: string): BmltQueryError {\n const message = `Invalid URL: ${reason}`;\n return ErrorFactory.createValidationError(message, {\n url,\n reason,\n });\n }\n\n /**\n * Handle coordinate validation errors\n */\n static handleCoordinateError(\n latitude?: number,\n longitude?: number,\n reason?: string\n ): BmltQueryError {\n const message = reason || 'Invalid coordinates provided';\n return ErrorFactory.createValidationError(message, {\n latitude,\n longitude,\n reason,\n });\n }\n\n /**\n * Wrap and enhance existing errors\n */\n static wrapError(\n originalError: Error,\n context: string,\n additionalContext?: Record<string, unknown>\n ): BmltQueryError {\n const message = `${context}: ${originalError.message}`;\n\n // Try to preserve the original error type if it's already a BmltQueryError\n if (originalError instanceof BmltQueryError) {\n return new BmltQueryError(originalError.type, message, {\n statusCode: originalError.statusCode,\n response: originalError.response,\n originalError: originalError.originalError || originalError,\n context: {\n ...originalError.context,\n ...additionalContext,\n },\n });\n }\n\n // Default to API error for unknown errors\n return ErrorFactory.createApiError(message, undefined, undefined, originalError);\n }\n}\n\n/**\n * Retry utility for handling retryable errors\n */\nexport interface RetryOptions {\n maxRetries: number;\n baseDelay: number;\n maxDelay: number;\n factor: number;\n onRetry?: (error: BmltQueryError, attempt: number) => void;\n}\n\nexport class RetryHandler {\n static async withRetry<T>(operation: () => Promise<T>, options: RetryOptions): Promise<T> {\n const { maxRetries, baseDelay, maxDelay, factor, onRetry } = options;\n\n let lastError: BmltQueryError;\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n try {\n return await operation();\n } catch (error) {\n const bmltError =\n error instanceof BmltQueryError\n ? error\n : ErrorHandler.wrapError(error as Error, 'Operation failed');\n\n lastError = bmltError;\n\n // Don't retry if it's the last attempt or error is not retryable\n if (attempt === maxRetries || !bmltError.isRetryable()) {\n throw bmltError;\n }\n\n // Calculate delay for next attempt\n const delay = Math.min(baseDelay * Math.pow(factor, attempt), maxDelay);\n\n // Call retry callback if provided\n if (onRetry) {\n onRetry(bmltError, attempt + 1);\n }\n\n // Wait before retrying\n await new Promise(resolve => setTimeout(resolve, delay));\n }\n }\n\n throw lastError!;\n }\n}\n","/**\n * Nominatim geocoding service with retry logic and rate limiting\n */\n\nimport pRetry from 'p-retry';\nimport PQueue from 'p-queue';\nimport { GeocodeResult, GeocodeOptions, RateLimitOptions, BmltError, Coordinates } from '../types';\nimport { BmltQueryError, BmltErrorType, ErrorHandler } from '../utils/errors';\n\nexport interface NominatimResponse {\n place_id: number;\n licence: string;\n osm_type: string;\n osm_id: number;\n lat: string;\n lon: string;\n display_name: string;\n address?: {\n house_number?: string;\n road?: string;\n neighbourhood?: string;\n suburb?: string;\n city?: string;\n town?: string;\n village?: string;\n county?: string;\n state?: string;\n postcode?: string;\n country?: string;\n country_code?: string;\n };\n importance?: number;\n boundingbox: string[];\n}\n\nexport class GeocodingService {\n private baseURL: string;\n private queue: PQueue;\n private readonly defaultOptions: Required<Omit<GeocodeOptions, 'viewbox'>> & {\n viewbox?: [number, number, number, number];\n };\n\n constructor(options: GeocodeOptions & RateLimitOptions = {}) {\n const {\n retryCount = 3,\n timeout = 10000,\n userAgent = 'bmlt-query-client/1.0.0',\n countryCode = 'us',\n viewbox,\n bounded = false,\n intervalCap = 1,\n interval = 1000, // 1 second between requests\n concurrency = 1,\n carryoverConcurrencyCount = false,\n ...rateLimitOptions\n } = options;\n\n this.defaultOptions = {\n retryCount,\n timeout,\n userAgent,\n countryCode,\n viewbox,\n bounded,\n };\n\n this.baseURL = 'https://nominatim.openstreetmap.org';\n\n this.queue = new PQueue({\n intervalCap,\n interval,\n concurrency,\n carryoverConcurrencyCount,\n ...rateLimitOptions,\n });\n }\n\n /**\n * Make a fetch request with timeout and error handling\n */\n private async fetchWithTimeout<T>(url: string, timeout: number, userAgent: string): Promise<T> {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), timeout);\n\n try {\n const response = await fetch(url, {\n method: 'GET',\n headers: {\n 'User-Agent': userAgent,\n },\n signal: controller.signal,\n });\n\n if (!response.ok) {\n if (response.status === 429) {\n const error: BmltError = new Error('Rate limit exceeded for geocoding service');\n error.name = 'RateLimitError';\n error.statusCode = 429;\n throw error;\n }\n\n if (response.status >= 400) {\n const error: BmltError = new Error(\n `Geocoding service error: ${response.status} ${response.statusText}`\n );\n error.name = 'GeocodingError';\n error.statusCode = response.status;\n throw error;\n }\n }\n\n const data = await response.json();\n return data as T;\n } catch (error) {\n if (error instanceof Error && error.name === 'AbortError') {\n const timeoutError: BmltError = new Error('Request timeout during geocoding');\n timeoutError.name = 'TimeoutError';\n throw timeoutError;\n }\n\n if (error instanceof TypeError) {\n const networkError: BmltError = new Error('Network error occurred during geocoding');\n networkError.name = 'NetworkError';\n throw networkError;\n }\n\n throw error;\n } finally {\n clearTimeout(timeoutId);\n }\n }\n\n /**\n * Geocode an address using Nominatim\n */\n async geocode(address: string, options: Partial<GeocodeOptions> = {}): Promise<GeocodeResult> {\n const geocodeOptions = { ...this.defaultOptions, ...options };\n\n return this.queue.add(async (): Promise<GeocodeResult> => {\n return pRetry(\n async () => {\n try {\n // Build search parameters with region bias\n const searchParams: Record<string, string | number> = {\n q: address,\n format: 'json',\n addressdetails: 1,\n limit: 1,\n dedupe: 1,\n };\n\n // Add country code bias if specified\n if (geocodeOptions.countryCode) {\n searchParams.countrycodes = geocodeOptions.countryCode;\n }\n\n // Add viewbox if specified\n if (geocodeOptions.viewbox) {\n searchParams.viewbox = geocodeOptions.viewbox.join(',');\n if (geocodeOptions.bounded) {\n searchParams.bounded = 1;\n }\n }\n\n // Build URL with parameters\n const searchUrl = new URL(`${this.baseURL}/search`);\n Object.entries(searchParams).forEach(([key, value]) => {\n searchUrl.searchParams.append(key, String(value));\n });\n\n const response = await this.fetchWithTimeout<NominatimResponse[]>(\n searchUrl.toString(),\n geocodeOptions.timeout,\n geocodeOptions.userAgent\n );\n\n if (!response || response.length === 0) {\n throw new BmltQueryError(\n BmltErrorType.GEOCODING_ERROR,\n `No results found for address: ${address}`\n );\n }\n\n // Always take the first result (most relevant based on search parameters)\n const result = response[0];\n const coordinates: Coordinates = {\n latitude: parseFloat(result.lat),\n longitude: parseFloat(result.lon),\n };\n\n // Validate coordinates\n if (isNaN(coordinates.latitude) || isNaN(coordinates.longitude)) {\n const error: BmltError = new Error(\n 'Invalid coordinates received from geocoding service'\n );\n error.name = 'GeocodingError';\n throw error;\n }\n\n if (\n coordinates.latitude < -90 ||\n coordinates.latitude > 90 ||\n coordinates.longitude < -180 ||\n coordinates.longitude > 180\n ) {\n const error: BmltError = new Error('Coordinates out of valid range');\n error.name = 'GeocodingError';\n throw error;\n }\n\n return {\n coordinates,\n display_name: result.display_name,\n confidence: result.importance,\n address: result.address\n ? {\n house_number: result.address.house_number,\n road: result.address.road,\n neighbourhood: result.address.neighbourhood,\n suburb: result.address.suburb,\n city: result.address.city || result.address.town || result.address.village,\n county: result.address.county,\n state: result.address.state,\n postcode: result.address.postcode,\n country: result.address.country,\n }\n : undefined,\n };\n } catch (error) {\n // Re-throw errors from fetchWithTimeout or validation\n throw error;\n }\n },\n {\n retries: geocodeOptions.retryCount,\n factor: 2,\n minTimeout: 1000,\n maxTimeout: 10000,\n onFailedAttempt: error => {\n console.warn(\n `Geocoding attempt ${error.attemptNumber} failed. ${error.retriesLeft} retries left. Error: ${error.error.message}`\n );\n },\n }\n );\n }) as Promise<GeocodeResult>;\n }\n\n /**\n * Batch geocode multiple addresses\n */\n async batchGeocode(\n addresses: string[],\n options: Partial<GeocodeOptions> = {}\n ): Promise<GeocodeResult[]> {\n const promises = addresses.map(address =>\n this.geocode(address, options).catch(error => {\n console.warn(`Failed to geocode address \"${address}\":`, error.message);\n return null;\n })\n );\n\n const results = await Promise.all(promises);\n return results.filter((result): result is GeocodeResult => result !== null);\n }\n\n /**\n * Reverse geocode coordinates to an address\n */\n async reverseGeocode(\n coordinates: Coordinates,\n options: Partial<GeocodeOptions> = {}\n ): Promise<GeocodeResult> {\n const geocodeOptions = { ...this.defaultOptions, ...options };\n\n return this.queue.add(async (): Promise<GeocodeResult> => {\n return pRetry(\n async () => {\n try {\n // Build URL with parameters\n const reverseUrl = new URL(`${this.baseURL}/reverse`);\n reverseUrl.searchParams.append('lat', String(coordinates.latitude));\n reverseUrl.searchParams.append('lon', String(coordinates.longitude));\n reverseUrl.searchParams.append('format', 'json');\n reverseUrl.searchParams.append('addressdetails', '1');\n\n const response = await this.fetchWithTimeout<NominatimResponse>(\n reverseUrl.toString(),\n geocodeOptions.timeout,\n geocodeOptions.userAgent\n );\n\n if (!response) {\n const error: BmltError = new Error(\n `No results found for coordinates: ${coordinates.latitude}, ${coordinates.longitude}`\n );\n error.name = 'GeocodingError';\n throw error;\n }\n\n const result = response;\n\n return {\n coordinates: {\n latitude: parseFloat(result.lat),\n longitude: parseFloat(result.lon),\n },\n display_name: result.display_name,\n confidence: result.importance,\n address: result.address\n ? {\n house_number: result.address.house_number,\n road: result.address.road,\n neighbourhood: result.address.neighbourhood,\n suburb: result.address.suburb,\n city: result.address.city || result.address.town || result.address.village,\n county: result.address.county,\n state: result.address.state,\n postcode: result.address.postcode,\n country: result.address.country,\n }\n : undefined,\n };\n } catch (error) {\n // Re-throw errors from fetchWithTimeout\n throw error;\n }\n },\n {\n retries: geocodeOptions.retryCount,\n factor: 2,\n minTimeout: 1000,\n maxTimeout: 10000,\n }\n );\n }) as Promise<GeocodeResult>;\n }\n\n /**\n * Get the current queue size\n */\n getQueueSize(): number {\n return this.queue.size;\n }\n\n /**\n * Get the number of pending operations\n */\n getPendingCount(): number {\n return this.queue.pending;\n }\n\n /**\n * Clear the queue\n */\n clearQueue(): void {\n this.queue.clear();\n }\n\n /**\n * Set concurrency limit\n */\n setConcurrency(concurrency: number): void {\n this.queue.concurrency = concurrency;\n }\n\n /**\n * Get the current user agent string\n */\n getUserAgent(): string {\n return this.defaultOptions.userAgent;\n }\n\n /**\n * Set the user agent string for geocoding requests\n */\n setUserAgent(userAgent: string): void {\n if (!userAgent || userAgent.trim().length === 0) {\n throw new Error('User agent must be a non-empty string');\n }\n this.defaultOptions.userAgent = userAgent.trim();\n }\n}\n","/**\n * Base types and enums for BMLT API\n */\n\nexport enum BmltDataFormat {\n JSON = 'json',\n JSONP = 'jsonp',\n TSML = 'tsml',\n CSV = 'csv',\n}\n\nexport enum BmltEndpoint {\n GET_SEARCH_RESULTS = 'GetSearchResults',\n GET_FORMATS = 'GetFormats',\n GET_SERVICE_BODIES = 'GetServiceBodies',\n GET_CHANGES = 'GetChanges',\n GET_FIELD_KEYS = 'GetFieldKeys',\n GET_FIELD_VALUES = 'GetFieldValues',\n GET_NAWS_DUMP = 'GetNAWSDump',\n GET_SERVER_INFO = 'GetServerInfo',\n GET_COVERAGE_AREA = 'GetCoverageArea',\n}\n\nexport enum Weekday {\n SUNDAY = 1,\n MONDAY = 2,\n TUESDAY = 3,\n WEDNESDAY = 4,\n THURSDAY = 5,\n FRIDAY = 6,\n SATURDAY = 7,\n}\n\nexport enum VenueType {\n IN_PERSON = 1,\n VIRTUAL = 2,\n HYBRID = 3,\n}\n\nexport enum SortKey {\n WEEKDAY = 'weekday',\n TIME = 'time',\n TOWN = 'town',\n STATE = 'state',\n WEEKDAY_STATE = 'weekday_state',\n}\n\nexport enum Language {\n DANISH = 'da',\n GERMAN = 'de',\n GREEK = 'el',\n ENGLISH = 'en',\n SPANISH = 'es',\n PERSIAN = 'fa',\n FRENCH = 'fr',\n ITALIAN = 'it',\n POLISH = 'pl',\n PORTUGUESE = 'pt',\n RUSSIAN = 'ru',\n SWEDISH = 'sv',\n}\n\nexport interface Coordinates {\n latitude: number;\n longitude: number;\n}\n\nexport interface BmltError extends Error {\n statusCode?: number;\n response?: unknown;\n}\n\nexport interface GeocodeOptions {\n retryCount?: number;\n timeout?: number;\n userAgent?: string;\n /** Country code for region bias (e.g., 'us', 'ca', 'gb') */\n countryCode?: string;\n /** Viewbox for region bias [minLon, minLat, maxLon, maxLat] */\n viewbox?: [number, number, number, number];\n /** Bounded search - restrict results to viewbox */\n bounded?: boolean;\n}\n\nexport interface RateLimitOptions {\n intervalCap?: number;\n interval?: number;\n carryoverConcurrencyCount?: boolean;\n concurrency?: number;\n}\n","/**\n * Utility functions for building BMLT API URLs and handling parameters\n */\n\nimport { BmltDataFormat, BmltEndpoint } from '../types';\n\nexport interface URLBuilderOptions {\n serverURL: string;\n format: BmltDataFormat;\n endpoint: BmltEndpoint;\n parameters?: Record<string, unknown>;\n}\n\n/**\n * Build a BMLT API URL with parameters\n */\nexport function buildBmltURL(options: URLBuilderOptions): string {\n const { serverURL, format, endpoint, parameters = {} } = options;\n\n // Ensure server URL ends with slash\n const baseURL = serverURL.endsWith('/') ? serverURL : `${serverURL}/`;\n\n // Build the base endpoint URL\n const endpointURL = `${baseURL}client_interface/${format}/`;\n\n // Convert parameters to query string\n const queryParams = new URLSearchParams();\n queryParams.set('switcher', endpoint);\n\n // Add other parameters\n Object.entries(parameters).forEach(([key, value]) => {\n if (value !== undefined && value !== null) {\n if (Array.isArray(value)) {\n // Handle array parameters\n value.forEach((item, index) => {\n if (typeof item === 'number' || typeof item === 'string') {\n queryParams.append(`${key}[]`, item.toString());\n }\n });\n } else if (typeof value === 'boolean') {\n queryParams.set(key, value ? '1' : '0');\n } else {\n queryParams.set(key, value.toString());\n }\n }\n });\n\n return `${endpointURL}?${queryParams.toString()}`;\n}\n\n/**\n * Normalize parameter values for BMLT API\n */\nexport function normalizeParameters(params: Record<string, unknown>): Record<string, unknown> {\n const normalized: Record<string, unknown> = {};\n\n Object.entries(params).forEach(([key, value]) => {\n if (value !== undefined && value !== null) {\n // Handle array parameters with positive/negative values\n if (Array.isArray(value)) {\n normalized[key] = value.map(item => {\n if (typeof item === 'number') {\n return item;\n } else if (typeof item === 'string') {\n const num = parseFloat(item);\n return isNaN(num) ? item : num;\n }\n return item;\n });\n }\n // Handle boolean parameters\n else if (typeof value === 'boolean') {\n normalized[key] = value;\n }\n // Handle numeric strings\n else if (typeof value === 'string') {\n const num = parseFloat(value);\n if (!isNaN(num) && isFinite(num)) {\n normalized[key] = num;\n } else {\n normalized[key] = value;\n }\n }\n // Keep other values as-is\n else {\n normalized[key] = value;\n }\n }\n });\n\n return normalized;\n}\n\n/**\n * Validate endpoint/format combinations\n */\nexport function validateEndpointFormat(endpoint: BmltEndpoint, format: BmltDataFormat): void {\n const validCombinations: Record<BmltEndpoint, BmltDataFormat[]> = {\n [BmltEndpoint.GET_SEARCH_RESULTS]: [\n BmltDataFormat.JSON,\n BmltDataFormat.JSONP,\n BmltDataFormat.TSML,\n ],\n [BmltEndpoint.GET_FORMATS]: [BmltDataFormat.JSON, BmltDataFormat.JSONP],\n [BmltEndpoint.GET_SERVICE_BODIES]: [BmltDataFormat.JSON, BmltDataFormat.JSONP],\n [BmltEndpoint.GET_CHANGES]: [BmltDataFormat.JSON, BmltDataFormat.JSONP],\n [BmltEndpoint.GET_FIELD_KEYS]: [BmltDataFormat.JSON, BmltDataFormat.JSONP],\n [BmltEndpoint.GET_FIELD_VALUES]: [BmltDataFormat.JSON, BmltDataFormat.JSONP],\n [BmltEndpoint.GET_NAWS_DUMP]: [BmltDataFormat.CSV],\n [BmltEndpoint.GET_SERVER_INFO]: [BmltDataFormat.JSON, BmltDataFormat.JSONP],\n [BmltEndpoint.GET_COVERAGE_AREA]: [BmltDataFormat.JSON, BmltDataFormat.JSONP],\n };\n\n const validFormats = validCombinations[endpoint];\n if (!validFormats.includes(format)) {\n throw new Error(\n `Invalid format '${format}' for endpoint '${endpoint}'. Valid formats: ${validFormats.join(', ')}`\n );\n }\n}\n\n/**\n * Clean and validate a server URL\n */\nexport function validateServerURL(url: string): string {\n try {\n const urlObj = new URL(url);\n if (!['http:', 'https:'].includes(urlObj.protocol)) {\n throw new Error('Server URL must use http or https protocol');\n }\n\n // Return the URL without trailing slash for consistency\n return urlObj.href.replace(/\\/$/, '');\n } catch (error) {\n const validationError = new Error(`Invalid server URL: ${url}`);\n validationError.cause = error;\n throw validationError;\n }\n}\n\n/**\n * Extract numeric IDs from various parameter formats\n */\nexport function extractIds(value: unknown): number[] {\n if (typeof value === 'number') {\n return [value];\n }\n\n if (typeof value === 'string') {\n // Handle comma-separated values\n return value\n .split(',')\n .map(id => parseInt(id.trim(), 10))\n .filter(id => !isNaN(id));\n }\n\n if (Array.isArray(value)) {\n return value\n .map(item => (typeof item === 'number' ? item : parseInt(String(item), 10)))\n .filter(id => !isNaN(id));\n }\n\n return [];\n}\n\n/**\n * Format time values for BMLT API\n */\nexport function formatTimeValue(\n hours?: number,\n minutes?: number\n): { hours?: number; minutes?: number } {\n const result: { hours?: number; minutes?: number } = {};\n\n if (typeof hours === 'number') {\n if (hours < 0 || hours > 23) {\n throw new Error('Hours must be between 0 and 23');\n }\n result.hours = hours;\n }\n\n if (typeof minutes === 'number') {\n if (minutes < 0 || minutes > 59) {\n throw new Error('Minutes must be between 0 and 59');\n }\n result.minutes = minutes;\n }\n\n return result;\n}\n\n/**\n * Validate coordinate values\n */\nexport function validateCoordinates(latitude: number, longitude: number): void {\n if (typeof latitude !== 'number' || isNaN(latitude)) {\n throw new Error('Latitude must be a valid number');\n }\n\n if (typeof longitude !== 'number' || isNaN(longitude)) {\n throw new Error('Longitude must be a valid number');\n }\n\n if (latitude < -90 || latitude > 90) {\n throw new Error('Latitude must be between -90 and 90 degrees');\n }\n\n if (longitude < -180 || longitude > 180) {\n throw new Error('Longitude must be between -180 and 180 degrees');\n }\n}\n\n/**\n * Validate radius values\n */\nexport function validateRadius(radius: number): void {\n if (typeof radius !== 'number' || isNaN(radius)) {\n throw new Error('Radius must be a valid number');\n }\n\n if (radius <= 0) {\n throw new Error('Radius must be greater than 0');\n }\n}\n\n/**\n * Convert miles to kilometers\n */\nexport function milesToKilometers(miles: number): number {\n return miles * 1.60934;\n}\n\n/**\n * Convert kilometers to miles\n */\nexport function kilometersToMiles(km: number): number {\n return km / 1.60934;\n}\n","/**\n * Response transforms — BMLT serializes numeric fields as quoted strings.\n * These converters give consumers idiomatic typed numbers.\n */\n\nimport type { Meeting, ServerInfo, CoverageArea } from '../types/responses';\n\nconst num = (v: unknown): number => (typeof v === 'number' ? v : parseFloat(v as string));\n\nconst optNum = (v: unknown): number | undefined => {\n if (v === undefined || v === null || v === '') return undefined;\n return num(v);\n};\n\nexport function transformMeeting(raw: unknown): Meeting {\n const r = raw as Record<string, unknown>;\n return {\n ...(r as unknown as Meeting),\n weekday_tinyint: num(r.weekday_tinyint),\n venue_type: num(r.venue_type),\n published: num(r.published),\n latitude: num(r.latitude),\n longitude: num(r.longitude),\n distance_in_km: optNum(r.distance_in_km),\n distance_in_miles: optNum(r.distance_in_miles),\n };\n}\n\nexport function transformServerInfo(raw: unknown): ServerInfo {\n const r = raw as Record<string, unknown>;\n return {\n ...(r as unknown as ServerInfo),\n versionInt: num(r.versionInt),\n centerLongitude: num(r.centerLongitude),\n centerLatitude: num(r.centerLatitude),\n centerZoom: num(r.centerZoom),\n semanticAdmin: num(r.semanticAdmin),\n changesPerMeeting: num(r.changesPerMeeting),\n };\n}\n\nexport function transformCoverageArea(raw: unknown): CoverageArea {\n const r = raw as Record<string, unknown>;\n return {\n nw_corner_longitude: num(r.nw_corner_longitude),\n nw_corner_latitude: num(r.nw_corner_latitude),\n se_corner_longitude: num(r.se_corner_longitude),\n se_corner_latitude: num(r.se_corner_latitude),\n };\n}\n","/**\n * Main BMLT client class for querying BMLT servers\n */\n\nimport { GeocodingService } from '../services/geocoding';\nimport {\n BmltDataFormat,\n BmltEndpoint,\n BmltError,\n Meeting,\n Format,\n MeetingsWithFormats,\n ServiceBody,\n Change,\n ServerInfo,\n CoverageArea,\n FieldKey,\n FieldValue,\n SearchResultsParams,\n GeographicSearchParams,\n FormatsParams,\n ServiceBodiesParams,\n ChangesParams,\n FieldValuesParams,\n NAWSDumpParams,\n GeocodeOptions,\n RateLimitOptions,\n Coordinates,\n} from '../types';\nimport {\n buildBmltURL,\n validateEndpointFormat,\n validateServerURL,\n validateCoordinates,\n validateRadius,\n} from '../utils/url-builder';\nimport { ErrorHandler } from '../utils/errors';\nimport { transformMeeting, transformServerInfo, transformCoverageArea } from '../utils/transforms';\n\nexport interface BmltClientOptions {\n /** Server URL */\n serverURL: string;\n\n /** Default data format */\n defaultFormat?: BmltDataFormat;\n\n /** HTTP request timeout in milliseconds */\n timeout?: number;\n\n /** User agent string */\n userAgent?: string;\n\n /** Geocoding options */\n geocodingOptions?: GeocodeOptions & RateLimitOptions;\n\n /** Enable automatic geocoding for address searches */\n enableGeocoding?: boolean;\n}\n\nexport class BmltClient {\n private timeout: number;\n private userAgent: string;\n private readonly geocodingService?: GeocodingService;\n private serverURL: string;\n private defaultFormat: BmltDataFormat;\n\n constructor(options: BmltClientOptions) {\n const {\n serverURL,\n defaultFormat = BmltDataFormat.JSON,\n timeout = 30000,\n userAgent = 'bmlt-query-client/1.0.0',\n geocodingOptions = {},\n enableGeocoding = true,\n } = options;\n\n // Validate and normalize server URL\n this.serverURL = validateServerURL(serverURL);\n this.defaultFormat = defaultFormat;\n this.timeout = timeout;\n this.userAgent = userAgent;\n\n // Initialize geocoding service if enabled\n if (enableGeocoding) {\n this.geocodingService = new GeocodingService(geocodingOptions);\n }\n }\n\n /**\n * Fetch a URL and parse the response according to format\n */\n private async fetchAndParse<T>(\n url: string,\n format: BmltDataFormat,\n parameters: Record<string, unknown> = {}\n ): Promise<T> {\n let response: Response | undefined;\n\n try {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n try {\n response = await fetch(url, {\n method: 'GET',\n headers: { 'User-Agent': this.userAgent },\n signal: controller.signal,\n });\n } finally {\n clearTimeout(timeoutId);\n }\n\n if (!response.ok) {\n throw ErrorHandler.handleFetchError(\n new Error(`HTTP ${response.status}: ${response.statusText}`),\n response\n );\n }\n\n const responseText = await response.text();\n\n if (format === BmltDataFormat.CSV) return responseText as T;\n\n if (format === BmltDataFormat.JSONP) {\n const callbackName = (parameters.callback as string) || 'callback';\n const jsonMatch = responseText.match(new RegExp(`${callbackName}\\\\((.+)\\\\);?$`));\n if (!jsonMatch) throw new Error('Invalid JSONP response format');\n return JSON.parse(jsonMatch[1]) as T;\n }\n\n if (format === BmltDataFormat.JSON || format === BmltDataFormat.TSML) {\n return JSON.parse(responseText) as T;\n }\n\n return responseText as T;\n } catch (error) {\n throw ErrorHandler.handleFetchError(error, response);\n }\n }\n\n /**\n * Make a request to the BMLT API\n */\n private async makeRequest<T>(\n endpoint: BmltEndpoint,\n parameters: Record<string, unknown> = {},\n format: BmltDataFormat = this.defaultFormat\n ): Promise<T> {\n validateEndpointFormat(endpoint, format);\n const url = buildBmltURL({ serverURL: this.serverURL, format, endpoint, parameters });\n return this.fetchAndParse<T>(url, format, parameters);\n }\n\n /**\n * Execute a raw BMLT query string against the server.\n *\n * Pass the query exactly as you'd append it to a BMLT URL. The switcher\n * can be written with or without the key name:\n *\n * // bare endpoint name — most common shorthand\n * client.rawQuery('GetSearchResults&venue_types=2&meeting_key=location_nation&meeting_key_value[]=USA&meeting_key_value[]=US')\n *\n * // explicit switcher= key also works\n * client.rawQuery('switcher=GetSearchResults&venue_types=2')\n */\n async rawQuery<T = unknown>(\n queryString: string,\n format: BmltDataFormat = this.defaultFormat\n ): Promise<T> {\n const baseURL = this.serverURL.endsWith('/') ? this.serverURL : `${this.serverURL}/`;\n const endpointURL = `${baseURL}client_interface/${format}/`;\n\n // If the first token has no '=' it is a bare endpoint name; prepend switcher=\n const firstSegment = queryString.split('&')[0];\n const normalized = firstSegment.includes('=') ? queryString : `switcher=${queryString}`;\n\n return this.fetchAndParse<T>(`${endpointURL}?${normalized}`, format);\n }\n\n /**\n * Search for meetings\n */\n async searchMeetings(params: SearchResultsParams = {}): Promise<Meeting[]> {\n const { format = this.defaultFormat, ...searchParams } = params;\n const result = await this.makeRequest<unknown[]>(\n BmltEndpoint.GET_SEARCH_RESULTS,\n searchParams,\n format\n );\n return result.map(transformMeeting);\n }\n\n /**\n * Search for meetings and return both meetings and the formats they reference in a\n * single request. Uses get_used_formats=true so the server wraps the response as\n * { meetings: Meeting[], formats: Format[] } instead of a bare Meeting[].\n *\n * This replaces the common pattern of Promise.all([getFormats(), searchMeetings()])\n * with a single round-trip, which matters for large servers where getFormats() can\n * return hundreds of unused format records.\n */\n async searchMeetingsWithFormats(\n params: Omit<SearchResultsParams, 'get_used_formats' | 'get_formats_only'> = {}\n ): Promise<MeetingsWithFormats> {\n const { format = this.defaultFormat, ...searchParams } = params;\n const result = await this.makeRequest<{ meetings: unknown[]; formats: Format[] }>(\n BmltEndpoint.GET_SEARCH_RESULTS,\n { ...searchParams, get_used_formats: true },\n format\n );\n return {\n meetings: result.meetings.map(transformMeeting),\n formats: result.formats,\n };\n }\n\n /**\n * Search for meetings by geographic location using geocoding\n */\n async searchMeetingsByAddress(params: GeographicSearchParams): Promise<Meeting[]> {\n if (!this.geocodingService) {\n throw new Error('Geocoding is not enabled. Initialize client with enableGeocoding: true');\n }\n\n const { address, radiusMiles, radiusKm, sortByDistance = true, searchParams = {} } = params;\n\n // Geocode the address\n const geocodeResult = await this.geocodingService.geocode(address);\n\n // Build search parameters with coordinates\n const geoSearchParams: SearchResultsParams = {\n ...searchParams,\n lat_val: geocodeResult.coordinates.latitude,\n long_val: geocodeResult.coordinates.longitude,\n sort_results_by_distance: sortByDistance,\n };\n\n // Add radius parameter\n if (radiusMiles !== undefined) {\n validateRadius(radiusMiles);\n geoSearchParams.geo_width = radiusMiles;\n } else if (radiusKm !== undefined) {\n validateRadius(radiusKm);\n geoSearchParams.geo_width_km = radiusKm;\n }\n\n return this.searchMeetings(geoSearchParams);\n }\n\n /**\n * Search for meetings by coordinates\n */\n async searchMeetingsByCoordinates(\n coordinates: Coordinates,\n radiusMiles?: number,\n radiusKm?: number,\n searchParams: Omit<\n SearchResultsParams,\n 'lat_val' | 'long_val' | 'geo_width' | 'geo_width_km'\n > = {}\n ): Promise<Meeting[]> {\n validateCoordinates(coordinates.latitude, coordinates.longitude);\n\n const geoSearchParams: SearchResultsParams = {\n ...searchParams,\n lat_val: coordinates.latitude,\n long_val: coordinates.longitude,\n sort_results_by_distance: true,\n };\n\n if (radiusMiles !== undefined) {\n validateRadius(radiusMiles);\n geoSearchParams.geo_width = radiusMiles;\n } else if (radiusKm !== undefined) {\n validateRadius(radiusKm);\n geoSearchParams.geo_width_km = radiusKm;\n }\n\n return this.searchMeetings(geoSearchParams);\n }\n\n /**\n * Get available meeting formats\n */\n async getFormats(params: FormatsParams = {}): Promise<Format[]> {\n const { format = this.defaultFormat, ...formatParams } = params;\n return this.makeRequest<Format[]>(BmltEndpoint.GET_FORMATS, formatParams, format);\n }\n\n /**\n * Get service bodies\n */\n async getServiceBodies(params: ServiceBodiesParams = {}): Promise<ServiceBody[]> {\n const { format = this.defaultFormat, ...serviceParams } = params;\n return this.makeRequest<ServiceBody[]>(BmltEndpoint.GET_SERVICE_BODIES, serviceParams, format);\n }\n\n /**\n * Get meeting changes within a date range\n */\n async getChanges(params: ChangesParams = {}): Promise<Change[]> {\n const { format = this.defaultFormat, ...changeParams } = params;\n return this.makeRequest<Change[]>(BmltEndpoint.GET_CHANGES, changeParams, format);\n }\n\n /**\n * Get available field keys\n */\n async getFieldKeys(): Promise<FieldKey[]> {\n return this.makeRequest<FieldKey[]>(BmltEndpoint.GET_FIELD_KEYS);\n }\n\n /**\n * Get field values for a specific field key\n */\n async getFieldValues(params: FieldValuesParams): Promise<FieldValue[]> {\n const { format = this.defaultFormat, ...fieldParams } = params;\n return this.makeRequest<FieldValue[]>(BmltEndpoint.GET_FIELD_VALUES, fieldParams, format);\n }\n\n /**\n * Get NAWS dump for a service body (CSV format only)\n */\n async getNAWSDump(params: NAWSDumpParams): Promise<string> {\n return this.makeRequest<string>(BmltEndpoint.GET_NAWS_DUMP, params, BmltDataFormat.CSV);\n }\n\n /**\n * Get server information\n */\n async getServerInfo(): Promise<ServerInfo> {\n const result = await this.makeRequest<unknown[]>(BmltEndpoint.GET_SERVER_INFO);\n return transformServerInfo(result[0]);\n }\n\n /**\n * Get server coverage area\n */\n async getCoverageArea(): Promise<CoverageArea> {\n const result = await this.makeRequest<unknown[]>(BmltEndpoint.GET_COVERAGE_AREA);\n return transformCoverageArea(result[0]);\n }\n\n /**\n * Geocode an address using the built-in geocoding service\n */\n async geocodeAddress(address: string, options?: Partial<GeocodeOptions>) {\n if (!this.geocodingService) {\n throw new Error('Geocoding is not enabled. Initialize client with enableGeocoding: true');\n }\n\n return this.geocodingService.geocode(address, options);\n }\n\n /**\n * Reverse geocode coordinates to an address\n */\n async reverseGeocode(coordinates: Coordinates, options?: Partial<GeocodeOptions>) {\n if (!this.geocodingService) {\n throw new Error('Geocoding is not enabled. Initialize client with enableGeocoding: true');\n }\n\n return this.geocodingService.reverseGeocode(coordinates, options);\n }\n\n /**\n * Get the server URL\n */\n getServerURL(): string {\n return this.serverURL;\n }\n\n /**\n * Update the server URL\n */\n setServerURL(url: string): void {\n this.serverURL = validateServerURL(url);\n }\n\n /**\n * Get the default data format\n */\n getDefaultFormat(): BmltDataFormat {\n return this.defaultFormat;\n }\n\n /**\n * Set the default data format\n */\n setDefaultFormat(format: BmltDataFormat): void {\n this.defaultFormat = format;\n }\n\n /**\n * Get geocoding service statistics\n */\n getGeocodingStats() {\n if (!this.geocodingService) {\n return null;\n }\n\n return {\n queueSize: this.geocodingService.getQueueSize(),\n pendingCount: this.geocodingService.getPendingCount(),\n };\n }\n\n /**\n * Clear the geocoding queue\n */\n clearGeocodingQueue(): void {\n if (this.geocodingService) {\n this.geocodingService.clearQueue();\n }\n }\n\n /**\n * Get the current user agent string\n */\n getUserAgent(): string {\n return this.userAgent;\n }\n\n /**\n * Set the user agent string for HTTP requests\n */\n setUserAgent(userAgent: string): void {\n if (!userAgent || userAgent.trim().length === 0) {\n throw new Error('User agent must be a non-empty string');\n }\n this.userAgent = userAgent.trim();\n\n // Also update the geocoding service user agent if it exists\n if (this.geocodingService) {\n this.geocodingService.setUserAgent(this.userAgent);\n }\n }\n\n /**\n * Get the current timeout setting\n */\n getTimeout(): number {\n return this.timeout;\n }\n\n /**\n * Set the timeout for HTTP requests\n */\n setTimeout(timeout: number): void {\n if (!Number.isInteger(timeout) || timeout <= 0) {\n throw new Error('Timeout must be a positive integer');\n }\n this.timeout = timeout;\n }\n}\n","/**\n * Fluent query builder for BMLT meeting searches\n */\n\nimport {\n SearchResultsParams,\n Meeting,\n MeetingsWithFormats,\n Weekday,\n VenueType,\n SortKey,\n Language,\n BmltDataFormat,\n Coordinates,\n} from '../types';\nimport { BmltClient } from './bmlt-client';\n\nexport class MeetingQueryBuilder {\n private params: SearchResultsParams = {};\n private client: BmltClient;\n\n constructor(client: BmltClient) {\n this.client = client;\n }\n\n /**\n * Include or exclude specific meeting IDs\n */\n meetingIds(ids: number | number[], exclude = false): this {\n if (Array.isArray(ids)) {\n this.params.meeting_ids = exclude ? ids.map(id => -id) : ids;\n } else {\n this.params.meeting_ids = exclude ? -ids : ids;\n }\n return this;\n }\n\n /**\n * Include meetings on specific weekdays\n */\n onWeekdays(...days: Weekday[]): this {\n this.params.weekdays = days.length === 1 ? days[0] : days;\n return this;\n }\n\n /**\n * Exclude meetings on specific weekdays\n */\n notOnWeekdays(...days: Weekday[]): this {\n const excludeDays = days.map(day => -day);\n this.params.weekdays = excludeDays.length === 1 ? excludeDays[0] : excludeDays;\n return this;\n }\n\n /**\n * Filter by venue types\n */\n venueTypes(...types: VenueType[]): this {\n this.params.venue_types = types.length === 1 ? types[0] : types;\n return this;\n }\n\n /**\n * Include only in-person meetings\n */\n inPersonOnly(): this {\n return this.venueTypes(VenueType.IN_PERSON);\n }\n\n /**\n * Include only virtual meetings\n */\n virtualOnly(): this {\n return this.venueTypes(VenueType.VIRTUAL);\n }\n\n /**\n * Include only hybrid meetings\n */\n hybridOnly(): this {\n return this.venueTypes(VenueType.HYBRID);\n }\n\n /**\n * Include virtual and hybrid meetings\n */\n virtualOrHybrid(): this {\n return this.venueTypes(VenueType.VIRTUAL, VenueType.HYBRID);\n }\n\n /**\n * Filter by meeting formats\n */\n formats(formatIds: number | number[], exclude = false): this {\n if (Array.isArray(formatIds)) {\n this.params.formats = exclude ? formatIds.map(id => -id) : formatIds;\n } else {\n this.params.formats = exclude ? -formatIds : formatIds;\n }\n return this;\n }\n\n /**\n * Use OR logic for format matching instead of AND\n */\n anyFormat(): this {\n this.params.formats_comparison_operator = 'OR';\n return this;\n }\n\n /**\n * Filter by service bodies\n */\n serviceBodies(serviceBodyIds: number | number[], exclude = false): this {\n if (Array.isArray(serviceBodyIds)) {\n this.params.services = exclude ? serviceBodyIds.map(id => -id) : serviceBodyIds;\n } else {\n this.params.services = exclude ? -serviceBodyIds : serviceBodyIds;\n }\n return this;\n }\n\n /**\n * Include child service bodies\n */\n includeChildServiceBodies(): this {\n this.params.recursive = true;\n return this;\n }\n\n /**\n * Search for specific text\n */\n searchText(text: string): this {\n this.params.SearchString = text;\n return this;\n }\n\n /**\n * Search by address using server-side geocoding (StringSearchIsAnAddress=1).\n * Note: typically broken on most BMLT servers because their Google API key uses\n * HTTP referer restrictions rather than server IP allowlisting. Prefer\n * BmltClient.searchMeetingsByAddress() which uses Nominatim client-side.\n */\n searchAddress(address: string, radius?: number): this {\n this.params.SearchString = address;\n this.params.StringSearchIsAnAddress = true;\n if (radius !== undefined) this.params.SearchStringRadius = radius;\n return this;\n }\n\n /**\n * Meetings starting after specific time\n */\n startingAfter(hours: number, minutes = 0): this {\n this.params.StartsAfterH = hours;\n this.params.StartsAfterM = minutes;\n return this;\n }\n\n /**\n * Meetings starting before specific time\n */\n startingBefore(hours: number, minutes = 0): this {\n this.params.StartsBeforeH = hours;\n this.params.StartsBeforeM = minutes;\n return this;\n }\n\n /**\n * Meetings ending before specific time\n */\n endingBefore(hours: number, minutes = 0): this {\n this.params.EndsBeforeH = hours;\n this.params.EndsBeforeM = minutes;\n return this;\n }\n\n /**\n * Minimum meeting duration\n */\n minimumDuration(hours = 0, minutes = 0): this {\n if (hours > 0) this.params.MinDurationH = hours;\n if (minutes > 0) this.params.MinDurationM = minutes;\n return this;\n }\n\n /**\n * Maximum meeting duration\n */\n maximumDuration(hours = 0, minutes = 0): this {\n if (hours > 0) this.params.MaxDurationH = hours;\n if (minutes > 0) this.params.MaxDurationM = minutes;\n return this;\n }\n\n /**\n * Search within geographic area by coordinates\n */\n nearCoordinates(coordinates: Coordinates, radiusMiles?: number, radiusKm?: number): this {\n this.params.lat_val = coordinates.latitude;\n this.params.long_val = coordinates.longitude;\n\n if (radiusMiles !== undefined) {\n this.params.geo_width = radiusMiles;\n } else if (radiusKm !== undefined) {\n this.params.geo_width_km = radiusKm;\n }\n\n return this;\n }\n\n /**\n * Search for specific field value; pass an array to match any of multiple values\n */\n fieldValue(fieldKey: string, value: string | string[]): this {\n this.params.meeting_key = fieldKey;\n this.params.meeting_key_value = value;\n return this;\n }\n\n /**\n * Return only specific fields\n */\n selectFields(...fields: string[]): this {\n this.params.data_field_key = fields.join(',');\n return this;\n }\n\n /**\n * Sort results by specific fields\n */\n sortBy(...fields: string[]): this {\n this.params.sort_keys = fields.join(',');\n return this;\n }\n\n /**\n * Sort by predefined aliases\n */\n sortByAlias(alias: SortKey): this {\n this.params.sort_key = alias;\n return this;\n }\n\n /**\n * Sort by distance (requires geographic search)\n */\n sortByDistance(): this {\n this.params.sort_results_by_distance = true;\n return this;\n }\n\n /**\n * Set pagination\n */\n paginate(pageSize: number, pageNumber = 1): this {\n this.params.page_size = pageSize;\n this.params.page_num = pageNumber;\n return this;\n }\n\n /**\n * Include unpublished meetings\n */\n includeUnpublished(): this {\n this.params.advanced_published = 0;\n return this;\n }\n\n /**\n * Include only unpublished meetings\n */\n unpublishedOnly(): this {\n this.params.advanced_published = -1;\n return this;\n }\n\n /**\n * Set language for format names\n */\n language(lang: Language): this {\n this.params.lang_enum = lang;\n return this;\n }\n\n /**\n * Set response format\n */\n format(format: BmltDataFormat): this {\n this.params.format = format;\n return this;\n }\n\n /**\n * Include formats used in search results\n */\n includeFormats(): this {\n this.params.get_used_formats = true;\n return this;\n }\n\n /**\n * Return only formats (requires includeFormats)\n */\n formatsOnly(): this {\n this.params.get_used_formats = true;\n this.params.get_formats_only = true;\n return this;\n }\n\n /**\n * Filter by root server IDs (aggregator mode)\n */\n rootServerIds(serverIds: number | number[], exclude = false): this {\n if (Array.isArray(serverIds)) {\n this.params.root_server_ids = exclude ? serverIds.map(id => -id) : serverIds;\n } else {\n this.params.root_server_ids = exclude ? -serverIds : serverIds;\n }\n return this;\n }\n\n /**\n * Get the current query parameters\n */\n getParams(): SearchResultsParams {\n return { ...this.params };\n }\n\n /**\n * Reset the query builder\n */\n reset(): this {\n this.params = {};\n return this;\n }\n\n /**\n * Clone the current query builder\n */\n clone(): MeetingQueryBuilder {\n const cloned = new MeetingQueryBuilder(this.client);\n cloned.params = { ...this.params };\n return cloned;\n }\n\n /**\n * Execute the search and return results\n */\n async execute(): Promise<Meeting[]> {\n return this.client.searchMeetings(this.params);\n }\n\n /**\n * Execute the search and return both meetings and the formats they reference\n * in a single request. Equivalent to execute() but avoids a separate getFormats() call.\n */\n async executeWithFormats(): Promise<MeetingsWithFormats> {\n const { get_used_formats, get_formats_only, ...params } = this.params;\n return this.client.searchMeetingsWithFormats(params);\n }\n\n /**\n * Execute the search by geocoding an address first\n */\n async executeNearAddress(\n address: string,\n radiusMiles?: number,\n radiusKm?: number,\n sortByDistance = true\n ): Promise<Meeting[]> {\n return this.client.searchMeetingsByAddress({\n address,\n radiusMiles,\n radiusKm,\n sortByDistance,\n searchParams: this.params,\n });\n }\n}\n\n/**\n * Convenience methods for common search patterns\n */\nexport class QuickSearch {\n private client: BmltClient;\n\n constructor(client: BmltClient) {\n this.client = client;\n }\n\n /**\n * Search for today's meetings\n */\n today(): MeetingQueryBuilder {\n const today = new Date().getDay();\n const weekday = today === 0 ? Weekday.SUNDAY : (today as Weekday);\n return new MeetingQueryBuilder(this.client).onWeekdays(weekday);\n }\n\n /**\n * Search for weekend meetings\n */\n weekend(): MeetingQueryBuilder {\n return new MeetingQueryBuilder(this.client).onWeekdays(Weekday.SATURDAY, Weekday.SUNDAY);\n }\n\n /**\n * Search for weekday meetings\n */\n weekdays(): MeetingQueryBuilder {\n return new MeetingQueryBuilder(this.client).onWeekdays(\n Weekday.MONDAY,\n Weekday.TUESDAY,\n Weekday.WEDNESDAY,\n Weekday.THURSDAY,\n Weekday.FRIDAY\n );\n }\n\n /**\n * Search for evening meetings (after 5 PM)\n */\n evening(): MeetingQueryBuilder {\n return new MeetingQueryBuilder(this.client).startingAfter(17);\n }\n\n /**\n * Search for morning meetings (before 12 PM)\n */\n morning(): MeetingQueryBuilder {\n return new MeetingQueryBuilder(this.client).startingBefore(12);\n }\n\n /**\n * Search for virtual meetings only\n */\n virtual(): MeetingQueryBuilder {\n return new MeetingQueryBuilder(this.client).virtualOnly();\n }\n\n /**\n * Search for in-person meetings only\n */\n inPerson(): MeetingQueryBuilder {\n return new MeetingQueryBuilder(this.client).inPersonOnly();\n }\n\n /**\n * Search by meeting name or location\n */\n byText(searchText: string): MeetingQueryBuilder {\n return new MeetingQueryBuilder(this.client).searchText(searchText);\n }\n}\n","/**\n * Utility functions for working with Meeting arrays\n */\n\nimport { Meeting } from '../types';\n\n/** A single meeting paired with the index of the list it came from */\nexport interface DuplicateMeetingEntry {\n meeting: Meeting;\n /** Index of the source list in the array passed to findDuplicateMeetings */\n listIndex: number;\n}\n\n/** A group of meetings from different lists that match on the comparison key */\nexport interface DuplicateMeetingGroup {\n /** Composite key used for matching */\n key: string;\n /** All matching entries, one per occurrence across the lists */\n entries: DuplicateMeetingEntry[];\n}\n\nexport interface FindDuplicatesOptions {\n /**\n * Meeting fields used to build the composite comparison key.\n * Defaults to weekday, start time, meeting name, and location.\n */\n fields?: Array<keyof Meeting>;\n\n /**\n * Normalize string values before comparing (lowercase + trim).\n * Defaults to true.\n */\n normalize?: boolean;\n}\n\nconst DEFAULT_FIELDS: Array<keyof Meeting> = [\n 'weekday_tinyint',\n 'start_time',\n 'meeting_name',\n 'location_text',\n];\n\nfunction normalizeValue(value: unknown, normalize: boolean): string {\n const str = value === null || value === undefined ? '' : String(value);\n return normalize ? str.toLowerCase().trim() : str;\n}\n\nfunction buildKey(meeting: Meeting, fields: Array<keyof Meeting>, normalize: boolean): string {\n return fields.map(field => normalizeValue(meeting[field], normalize)).join(' | ');\n}\n\n/**\n * Find meetings that appear in more than one of the provided lists.\n *\n * Comparison is done via a composite key built from the specified fields\n * (default: weekday, start time, meeting name, location). Only groups that\n * span at least two different lists are returned.\n *\n * @example\n * const duplicates = findDuplicateMeetings([listA, listB]);\n * for (const group of duplicates) {\n * console.log(`Duplicate: ${group.key}`);\n * for (const { meeting, listIndex } of group.entries) {\n * console.log(` List ${listIndex}: id=${meeting.id_bigint}`);\n * }\n * }\n */\nexport function findDuplicateMeetings(\n meetingLists: Meeting[][],\n options: FindDuplicatesOptions = {}\n): DuplicateMeetingGroup[] {\n const { fields = DEFAULT_FIELDS, normalize = true } = options;\n\n // Build a map from composite key -> entries\n const keyMap = new Map<string, DuplicateMeetingEntry[]>();\n\n for (let listIndex = 0; listIndex < meetingLists.length; listIndex++) {\n for (const meeting of meetingLists[listIndex]) {\n const key = buildKey(meeting, fields, normalize);\n if (!keyMap.has(key)) {\n keyMap.set(key, []);\n }\n keyMap.get(key)!.push({ meeting, listIndex });\n }\n }\n\n // Keep only groups that appear in at least 2 distinct lists\n const result: DuplicateMeetingGroup[] = [];\n for (const [key, entries] of keyMap) {\n const listIndices = new Set(entries.map(e => e.listIndex));\n if (listIndices.size >= 2) {\n result.push({ key, entries });\n }\n }\n\n return result;\n}\n\n/**\n * Count unique groups across a list of meetings.\n *\n * A \"group\" is identified by the combination of service body, meeting name\n * (case-insensitive, trimmed), and meeting location — physical coordinates\n * for in-person/hybrid (venue_type !== 2), or the virtual meeting link plus\n * additional info for virtual (venue_type === 2). Multiple weekly meetings of\n * the same group count once; two distinct groups that happen to share a name\n * but meet at different locations count separately. Matches the long-standing\n * \"group_id\" definition used by crouton.\n *\n * Meetings missing a service body or name are skipped.\n */\nexport function countUniqueGroups(meetings: Meeting[]): number {\n const seen = new Set<string>();\n\n for (const meeting of meetings) {\n const sbId = meeting.service_body_bigint;\n const name = meeting.meeting_name;\n if (!sbId || !name) continue;\n\n const normalizedName = name.trim().toLowerCase();\n const location =\n meeting.venue_type === 2\n ? `${meeting.virtual_meeting_link ?? ''}|${meeting.virtual_meeting_additional_info ?? ''}`\n : `${meeting.latitude.toFixed(6)}|${meeting.longitude.toFixed(6)}`;\n\n seen.add(`${sbId}|${normalizedName}|${location}`);\n }\n\n return seen.size;\n}\n"],"x_google_ignoreList":[0,1,2,3,4,5,6,7],"mappings":"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"}
|
package/package.json
CHANGED