@bumail/queue 0.10.0 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +27 -1
- package/dist/chunks/{index-sz13a17b.js → index-t6q7zxgj.js} +14 -3
- package/dist/chunks/{index-sz13a17b.js.map → index-t6q7zxgj.js.map} +4 -4
- package/dist/contract/checks.d.ts +4 -0
- package/dist/contract/checks.d.ts.map +1 -1
- package/dist/contract/queue-store.d.ts +15 -7
- package/dist/contract/queue-store.d.ts.map +1 -1
- package/dist/contract/types.d.ts +5 -0
- package/dist/contract/types.d.ts.map +1 -1
- package/dist/errors.d.ts +3 -1
- package/dist/errors.d.ts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +64 -26
- package/dist/index.js.map +4 -4
- package/dist/memory/index.js +10 -6
- package/dist/memory/index.js.map +3 -3
- package/dist/memory/store.d.ts +2 -2
- package/dist/memory/store.d.ts.map +1 -1
- package/dist/postgres/complete.d.ts +13 -0
- package/dist/postgres/complete.d.ts.map +1 -0
- package/dist/postgres/index.js +85 -74
- package/dist/postgres/index.js.map +6 -5
- package/dist/postgres/store.d.ts +2 -2
- package/dist/postgres/store.d.ts.map +1 -1
- package/dist/queue/deliver.d.ts.map +1 -1
- package/dist/queue/notify.d.ts +35 -6
- package/dist/queue/notify.d.ts.map +1 -1
- package/dist/redis/complete.d.ts +11 -0
- package/dist/redis/complete.d.ts.map +1 -0
- package/dist/redis/index.js +133 -110
- package/dist/redis/index.js.map +7 -6
- package/dist/redis/scripts.d.ts +8 -5
- package/dist/redis/scripts.d.ts.map +1 -1
- package/dist/redis/store.d.ts +2 -2
- package/dist/redis/store.d.ts.map +1 -1
- package/dist/sqlite/index.js +29 -20
- package/dist/sqlite/index.js.map +5 -4
- package/dist/sqlite/insert.d.ts +5 -0
- package/dist/sqlite/insert.d.ts.map +1 -0
- package/dist/sqlite/store.d.ts +2 -2
- package/dist/sqlite/store.d.ts.map +1 -1
- package/docs/guide.md +29 -0
- package/docs/roadmap.md +36 -10
- package/docs/troubleshooting.md +64 -1
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -313,6 +313,31 @@ control character in it.
|
|
|
313
313
|
- **It sends what you enqueue, to anyone.** The queue is not a relay
|
|
314
314
|
policy: enqueue only what an authenticated user submitted, or what your
|
|
315
315
|
own server writes, never what an unauthenticated client handed you.
|
|
316
|
+
- **A custom `QueueStore` must port `complete` (0.11, breaking).**
|
|
317
|
+
`complete(id, owner, result, dsns)` takes the DSN items the outcome
|
|
318
|
+
calls for and returns `{ item, dsns }`, or `undefined` for a lost lease.
|
|
319
|
+
Store the outcome and the DSNs in one step, so a crash cannot leave one
|
|
320
|
+
without the other; a store that returns the bare item still works, but
|
|
321
|
+
the queue reports `Queue store outdated` on the `error` event and adds
|
|
322
|
+
each DSN with `add`, outside that step. The stores of this package are
|
|
323
|
+
atomic. DSNs ignore `limits.maxItems`: a full queue still bounces, and the
|
|
324
|
+
count may exceed the limit by the DSNs it holds. They are delivered at least once; see [Writing a
|
|
325
|
+
store](./docs/guide.md#writing-a-store). The `this.*` calls below are
|
|
326
|
+
your store's own helpers, a sketch.
|
|
327
|
+
|
|
328
|
+
```ts
|
|
329
|
+
async complete(id, owner, result, dsns) {
|
|
330
|
+
// refuse a bad DSN (INVALID) before opening a connection or a transaction
|
|
331
|
+
for (const dsn of dsns) this.check(dsn);
|
|
332
|
+
return this.transaction(async () => {
|
|
333
|
+
const item = await this.apply(id, owner, result); // undefined on a lost lease
|
|
334
|
+
if (!item) return undefined; // writes no DSN
|
|
335
|
+
const stored = [];
|
|
336
|
+
for (const dsn of dsns) stored.push(await this.insert(dsn)); // in order
|
|
337
|
+
return { item, dsns: stored };
|
|
338
|
+
});
|
|
339
|
+
}
|
|
340
|
+
```
|
|
316
341
|
|
|
317
342
|
## API
|
|
318
343
|
|
|
@@ -324,7 +349,8 @@ control character in it.
|
|
|
324
349
|
| `deliveredDsn(input)`, `DeliveredDsnInput`, `DeliveredRecipient` | the `delivered` DSN for a local delivery: the bytes to enqueue, or `undefined` when no recipient asked for `SUCCESS` |
|
|
325
350
|
| `failedDsn(input)`, `FailedDsnInput`, `FailedRecipient`, `DEFAULT_MAX_RETURN` | the `failed` DSN for a recipient the application could not deliver locally: the bytes to enqueue, or `undefined` for a null reverse-path or when no recipient asked for failures; `DEFAULT_MAX_RETURN` is the 64 KiB a DSN returns of the original by default |
|
|
326
351
|
| `QueueEvents`, `QueueListener`, `RecipientEvent` (`route`, `fallback`, `mxReply`, `mayHaveReachedMx`, `mayHaveReachedFallback`), `DeferredEvent`, `DsnEvent`, `QueueErrorEvent` | the events |
|
|
327
|
-
| `QueueStore` | the contract a store answers: `add`, `get`, `list`, `count`, `readMessage`, `claim`, `renew`, `complete`, `reschedule`, `cancel` |
|
|
352
|
+
| `QueueStore` | the contract a store answers: `add`, `get`, `list`, `count`, `readMessage`, `claim`, `renew`, `complete(id, owner, result, dsns)`, `reschedule`, `cancel` |
|
|
353
|
+
| `Completed` (`item`, `dsns`) | what `complete` returns: the item as it now stands, and the DSN items it stored in the same step, in the order given; `undefined` when the lease was lost |
|
|
328
354
|
| `QueueItem`, `RecipientState`, `RecipientStatus`, `FinalStatus`, `Diagnostic`, `Lease` | an item, and where each recipient stands |
|
|
329
355
|
| `NewQueueItem`, `AddOptions`, `ClaimRequest`, `AttemptResult`, `RecipientUpdate`, `QueueListOptions` | what a store takes |
|
|
330
356
|
| `QueueError`, `QueueErrorCode` | `INVALID`, `MESSAGE_TOO_BIG`, `TOO_MANY_RECIPIENTS`, `QUEUE_FULL`, `CLOSED`, `LEASE_LOST`, `MESSAGE_UNREADABLE` |
|
|
@@ -148,6 +148,17 @@ function checkUpdate(update) {
|
|
|
148
148
|
checkStorable(`reply.${name}`, value);
|
|
149
149
|
}
|
|
150
150
|
}
|
|
151
|
+
function checkDsns(dsns) {
|
|
152
|
+
if (!Array.isArray(dsns))
|
|
153
|
+
throw invalid("dsns must be an array");
|
|
154
|
+
for (const dsn of dsns)
|
|
155
|
+
checkNewItem(dsn);
|
|
156
|
+
}
|
|
157
|
+
function checkComplete(owner, result, dsns) {
|
|
158
|
+
checkOwner(owner);
|
|
159
|
+
checkResult(result);
|
|
160
|
+
checkDsns(dsns);
|
|
161
|
+
}
|
|
151
162
|
function checkNewItem(item) {
|
|
152
163
|
if (typeof item !== "object" || item === null) {
|
|
153
164
|
throw invalid("A new item is an object");
|
|
@@ -267,7 +278,7 @@ function newItem(id, item) {
|
|
|
267
278
|
}
|
|
268
279
|
var claimable = (item, now) => item.nextAttemptAt <= now && (item.lease === undefined || item.lease.expiresAt <= now);
|
|
269
280
|
|
|
270
|
-
export { hasControl, replaceControls, cleanText, isStorable, asciiText, QueueError2, invalid, checkTime, checkOwner, checkNewItem, checkMaxItems, checkClaim,
|
|
281
|
+
export { hasControl, replaceControls, cleanText, isStorable, asciiText, QueueError2, invalid, checkTime, checkOwner, checkComplete, checkNewItem, checkMaxItems, checkClaim, checkList, isDone, applyAttempt, newItem, claimable };
|
|
271
282
|
|
|
272
|
-
//# debugId=
|
|
273
|
-
//# sourceMappingURL=index-
|
|
283
|
+
//# debugId=17F888FDC5191A2364756E2164756E21
|
|
284
|
+
//# sourceMappingURL=index-t6q7zxgj.js.map
|
|
@@ -3,12 +3,12 @@
|
|
|
3
3
|
"sources": ["../src/text.ts", "../src/errors.ts", "../src/contract/storable.ts", "../src/contract/dsn-checks.ts", "../src/contract/checks.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
5
|
"/** Text from the other side, made safe to keep and to write in a header field. */\n\n/** C0, DEL and C1: every control character, CR, LF and TAB included. */\nconst isControl = (code: number) =>\n\tcode < 0x20 || (code >= 0x7f && code <= 0x9f);\n\n/** Whether the text holds a control character. */\nexport function hasControl(text: string): boolean {\n\tfor (let i = 0; i < text.length; i++) {\n\t\tif (isControl(text.charCodeAt(i))) return true;\n\t}\n\treturn false;\n}\n\n/** Each control character replaced by `by`. */\nexport function replaceControls(text: string, by: string): string {\n\tlet out = '';\n\tfor (let i = 0; i < text.length; i++) {\n\t\tout += isControl(text.charCodeAt(i)) ? by : (text[i] as string);\n\t}\n\treturn out;\n}\n\n/**\n * Every control character (CR and LF included) as a space, a lone\n * surrogate as U+FFFD, runs of space as one, cut at `max` characters with\n * `...`, never inside a surrogate pair: what a reply leaves in an item,\n * an event and a DSN.\n */\nexport function cleanText(text: string, max: number): string {\n\tconst clean = replaceControls(text.toWellFormed(), ' ')\n\t\t.replace(/ {2,}/g, ' ')\n\t\t.trim();\n\treturn clean.length > max ? `${cut(clean, max - 3)}...` : clean;\n}\n\n/**\n * The first `length` UTF-16 units, never ending inside a surrogate pair:\n * a lone surrogate is text no store can keep (PostgreSQL's `jsonb` refuses\n * it), nor any UTF-8 encode.\n */\nfunction cut(text: string, length: number): string {\n\tconst head = text.slice(0, length);\n\tconst last = head.charCodeAt(head.length - 1);\n\treturn last >= 0xd800 && last <= 0xdbff ? head.slice(0, -1) : head;\n}\n\n/**\n * Text every store can keep: no NUL (PostgreSQL's `text` and `jsonb` hold\n * none) and no lone surrogate. `cleanText`'s output always is.\n */\nexport const isStorable = (text: string): boolean =>\n\ttext.isWellFormed() && !text.includes('\\0');\n\n/** `cleanText`, then anything not printable ASCII as `?`: for a `message/delivery-status` field. */\nexport const asciiText = (text: string, max: number): string =>\n\tcleanText(text, max).replace(/[^ -~]/g, '?');\n",
|
|
6
|
-
"/**\n * Why the queue or a store refused a call. `INVALID`: an option or an\n * argument it cannot take. `MESSAGE_TOO_BIG`, `TOO_MANY_RECIPIENTS` and\n * `QUEUE_FULL`: a limit `enqueue` enforces. `CLOSED`: a store used after\n * `close()`. `LEASE_LOST`: given to the `error` event when another worker\n * took an item before its outcome was recorded — or, once the lease's\n * expiry passed, when the item is gone: lost or cancelled.\n * `MESSAGE_UNREADABLE`: given to the `error` event when the store holds an\n * item but not its message, whose pending recipients then fail.\n */\nexport type QueueErrorCode =\n\t| 'INVALID'\n\t| 'MESSAGE_TOO_BIG'\n\t| 'TOO_MANY_RECIPIENTS'\n\t| 'QUEUE_FULL'\n\t| 'CLOSED'\n\t| 'LEASE_LOST'\n\t| 'MESSAGE_UNREADABLE';\n\n/** Thrown by the queue and by every store, whichever answers the contract, with the same codes. */\nexport class QueueError extends Error {\n\toverride readonly name = 'QueueError';\n\treadonly code: QueueErrorCode;\n\n\tconstructor(code: QueueErrorCode, message: string) {\n\t\tsuper(message);\n\t\tthis.code = code;\n\t}\n}\n\n/** `INVALID`, for an option or an argument. */\nexport const invalid = (message: string) => new QueueError('INVALID', message);\n",
|
|
6
|
+
"/**\n * Why the queue or a store refused a call. `INVALID`: an option or an\n * argument it cannot take, or, given to the `error` event, a store that\n * answers an older contract (`complete` returning the item alone, without\n * the DSNs). `MESSAGE_TOO_BIG`, `TOO_MANY_RECIPIENTS` and\n * `QUEUE_FULL`: a limit `enqueue` enforces. `CLOSED`: a store used after\n * `close()`. `LEASE_LOST`: given to the `error` event when another worker\n * took an item before its outcome was recorded — or, once the lease's\n * expiry passed, when the item is gone: lost or cancelled.\n * `MESSAGE_UNREADABLE`: given to the `error` event when the store holds an\n * item but not its message, whose pending recipients then fail.\n */\nexport type QueueErrorCode =\n\t| 'INVALID'\n\t| 'MESSAGE_TOO_BIG'\n\t| 'TOO_MANY_RECIPIENTS'\n\t| 'QUEUE_FULL'\n\t| 'CLOSED'\n\t| 'LEASE_LOST'\n\t| 'MESSAGE_UNREADABLE';\n\n/** Thrown by the queue and by every store, whichever answers the contract, with the same codes. */\nexport class QueueError extends Error {\n\toverride readonly name = 'QueueError';\n\treadonly code: QueueErrorCode;\n\n\tconstructor(code: QueueErrorCode, message: string) {\n\t\tsuper(message);\n\t\tthis.code = code;\n\t}\n}\n\n/** `INVALID`, for an option or an argument. */\nexport const invalid = (message: string) => new QueueError('INVALID', message);\n",
|
|
7
7
|
"import { invalid } from '../errors';\nimport { isStorable } from '../text';\n\n/**\n * Text a store keeps: refused, the same way by every store, when it holds\n * a NUL or a lone surrogate, which PostgreSQL cannot keep and no UTF-8\n * encode can carry.\n */\nexport function checkStorable(name: string, text: string): void {\n\tif (!isStorable(text)) {\n\t\tthrow invalid(\n\t\t\t`${name} holds a NUL or a lone surrogate, which a store cannot keep`,\n\t\t);\n\t}\n}\n",
|
|
8
8
|
"// The value rules (and utf8OrcptLength, RFC 6533) repeat packages/smtp/src/server/dsn-params.ts, packages/smtp/src/client/dsn.ts and\n// packages/jmap/src/submission/dsn.ts (AGENTS.md, Deliberate duplications); this copy guards the contract.\nimport { invalid } from '../errors';\nimport { checkStorable } from './storable';\nimport type { NewQueueItem, RecipientDsn } from './types';\n\nconst EVENTS: readonly unknown[] = ['SUCCESS', 'FAILURE', 'DELAY'];\n\n/**\n * The length the xtext of `text` takes on the wire (RFC 3461 §4): one\n * character for each byte of its UTF-8 form in `!` to `~` but `+` and `=`,\n * three for any other.\n */\nfunction xtextLength(text: string): number {\n\tlet length = 0;\n\tfor (const byte of new TextEncoder().encode(text)) {\n\t\tlength +=\n\t\t\tbyte >= 33 && byte <= 126 && byte !== 0x2b && byte !== 0x3d ? 1 : 3;\n\t}\n\treturn length;\n}\n\n/**\n * The length of a `utf-8` ORCPT address in its `utf-8-addr-unitext` form (RFC\n * 6533 §3), the shortest one: raw UTF-8 octets for a non-ASCII character, one\n * for printable ASCII but `\\`, `+` and `=`, and `\\x{HH}` (6) for the rest.\n * The SMTP server counts the value as sent, which is this for a unitext one.\n */\nfunction utf8OrcptLength(text: string): number {\n\tlet length = 0;\n\tfor (const char of text) {\n\t\tconst code = char.codePointAt(0) as number;\n\t\tif (code > 0x7f) length += new TextEncoder().encode(char).length;\n\t\telse\n\t\t\tlength +=\n\t\t\t\tcode >= 0x21 &&\n\t\t\t\tcode !== 0x5c &&\n\t\t\t\tcode !== 0x2b &&\n\t\t\t\tcode !== 0x3d &&\n\t\t\t\tcode < 0x7f\n\t\t\t\t\t? 1\n\t\t\t\t\t: 6;\n\t}\n\treturn length;\n}\n\n/** One recipient's `NOTIFY` (RFC 3461 §4.1) and `ORCPT` (§4.2). */\nfunction checkRecipientDsn(entry: RecipientDsn, to: readonly string[]): void {\n\tconst { address, notify, orcpt } = entry ?? {};\n\tif (typeof address !== 'string' || !to.includes(address)) {\n\t\tthrow invalid(\n\t\t\t`recipients names ${JSON.stringify(address)}, which is not in to`,\n\t\t);\n\t}\n\tif (notify !== undefined && notify !== 'NEVER') {\n\t\tconst events: readonly unknown[] = Array.isArray(notify) ? notify : [];\n\t\tif (\n\t\t\tevents.length === 0 ||\n\t\t\tevents.some((e, i) => !EVENTS.includes(e) || events.indexOf(e) !== i)\n\t\t) {\n\t\t\tthrow invalid(\n\t\t\t\t`notify of ${address} must be 'NEVER' or a list of 'SUCCESS', 'FAILURE', 'DELAY', each once`,\n\t\t\t);\n\t\t}\n\t}\n\tif (orcpt === undefined) return;\n\tif (\n\t\ttypeof orcpt !== 'object' ||\n\t\torcpt === null ||\n\t\ttypeof orcpt.type !== 'string' ||\n\t\t!/^[A-Za-z0-9-]+$/.test(orcpt.type) ||\n\t\ttypeof orcpt.address !== 'string' ||\n\t\torcpt.address === ''\n\t) {\n\t\tthrow invalid(`orcpt of ${address} must be { type, address }`);\n\t}\n\t// RFC 3461 §4.2: \"The entire ORCPT parameter MAY be up to 500 characters in length\", as sent.\n\tconst encoded =\n\t\torcpt.type.toLowerCase() === 'utf-8'\n\t\t\t? utf8OrcptLength(orcpt.address)\n\t\t\t: xtextLength(orcpt.address);\n\tif (orcpt.type.length + 1 + encoded > 500) {\n\t\tthrow invalid(`orcpt of ${address} is over 500 characters once encoded`);\n\t}\n\tcheckStorable('orcpt.type', orcpt.type);\n\tcheckStorable('orcpt.address', orcpt.address);\n}\n\n/** `ret`, `envid` and `recipients` of a new item. */\nexport function checkDsnParams(item: NewQueueItem): void {\n\tconst { ret, envid, recipients } = item;\n\tif (ret !== undefined && ret !== 'FULL' && ret !== 'HDRS') {\n\t\tthrow invalid(`ret must be 'FULL' or 'HDRS', not ${String(ret)}`);\n\t}\n\tif (\n\t\tenvid !== undefined &&\n\t\t(typeof envid !== 'string' ||\n\t\t\t!/^[ -~]{1,100}$/.test(envid) ||\n\t\t\t// RFC 3461 §4.4: \"The ENVID parameter MAY be up to 100 characters in length\", as sent.\n\t\t\txtextLength(envid) > 100)\n\t) {\n\t\tthrow invalid(\n\t\t\t'envid must be 1 to 100 printable ASCII characters, at most 100 once encoded as xtext',\n\t\t);\n\t}\n\tif (recipients === undefined) return;\n\tif (!Array.isArray(recipients)) {\n\t\tthrow invalid('recipients must be an array of { address, notify, orcpt }');\n\t}\n\tconst seen = new Set<string>();\n\tfor (const entry of recipients) {\n\t\tcheckRecipientDsn(entry, item.to);\n\t\tif (seen.has(entry.address)) {\n\t\t\tthrow invalid(`recipients names ${entry.address} twice`);\n\t\t}\n\t\tseen.add(entry.address);\n\t}\n}\n",
|
|
9
|
-
"import { invalid } from '../errors';\nimport { checkDsnParams } from './dsn-checks';\nimport { checkStorable } from './storable';\n\nexport { checkStorable };\n\nimport type {\n\tAttemptResult,\n\tClaimRequest,\n\tDiagnostic,\n\tNewQueueItem,\n\tQueueItem,\n\tQueueListOptions,\n\tRecipientState,\n\tRecipientUpdate,\n} from './types';\n\n/** What every store checks the same way, so each refuses the same input with the same error. */\n\nconst isTime = (value: unknown): value is number =>\n\ttypeof value === 'number' && Number.isFinite(value);\n\n/** A time in milliseconds since the epoch, or `INVALID` naming it. */\nexport function checkTime(name: string, value: unknown): number {\n\tif (!isTime(value)) throw invalid(`${name} must be a finite number`);\n\treturn value;\n}\n\n/** A lease owner: a non-empty string. */\nexport function checkOwner(owner: unknown): string {\n\tif (typeof owner !== 'string' || owner === '') {\n\t\tthrow invalid('owner must be a non-empty string');\n\t}\n\tcheckStorable('owner', owner);\n\treturn owner;\n}\n\n/** Every text of a recipient's outcome. */\nfunction checkUpdate(update: RecipientUpdate): void {\n\tcheckStorable('A recipient', update.address);\n\tfor (const key of ['mayHaveReachedMx', 'mayHaveReachedFallback'] as const) {\n\t\tconst mark = update[key] as unknown;\n\t\tif (mark !== undefined && mark !== true) {\n\t\t\tthrow invalid(`${key} must be true or absent`);\n\t\t}\n\t}\n\tconst reply = update.reply as Partial<Diagnostic> | undefined;\n\tif (reply === undefined) return;\n\tif (\n\t\ttypeof reply !== 'object' ||\n\t\treply === null ||\n\t\ttypeof reply.text !== 'string'\n\t) {\n\t\tthrow invalid('A reply is an object with a text');\n\t}\n\tcheckStorable('reply.text', reply.text);\n\tfor (const name of ['status', 'host'] as const) {\n\t\tconst value = reply[name];\n\t\tif (value === undefined) continue;\n\t\tif (typeof value !== 'string')\n\t\t\tthrow invalid(`reply.${name} must be a string`);\n\t\tcheckStorable(`reply.${name}`, value);\n\t}\n}\n\nexport function checkNewItem(item: NewQueueItem): void {\n\tif (typeof item !== 'object' || item === null) {\n\t\tthrow invalid('A new item is an object');\n\t}\n\tif (typeof item.from !== 'string') throw invalid('from must be a string');\n\tcheckStorable('from', item.from);\n\tconst to = item.to as unknown;\n\tif (\n\t\t!Array.isArray(to) ||\n\t\tto.length === 0 ||\n\t\t!to.every((a) => typeof a === 'string' && a !== '')\n\t) {\n\t\tthrow invalid('to must be a non-empty array of addresses');\n\t}\n\tfor (const address of to as string[]) checkStorable('A recipient', address);\n\tif (!(item.message instanceof Uint8Array)) {\n\t\tthrow invalid('message must be a Uint8Array');\n\t}\n\tcheckTime('createdAt', item.createdAt);\n\tcheckDsnParams(item);\n}\n\n/** `maxItems`: a positive integer, or nothing. */\nexport function checkMaxItems(max: unknown): number | undefined {\n\tif (max === undefined) return undefined;\n\tif (typeof max !== 'number' || !Number.isInteger(max) || max < 1) {\n\t\tthrow invalid(`maxItems must be an integer of at least 1, not ${max}`);\n\t}\n\treturn max;\n}\n\nexport function checkClaim(request: ClaimRequest): void {\n\tif (typeof request !== 'object' || request === null) {\n\t\tthrow invalid('A claim is an object');\n\t}\n\tcheckOwner(request.owner);\n\tcheckTime('now', request.now);\n\tif (!isTime(request.leaseMs) || request.leaseMs <= 0) {\n\t\tthrow invalid('leaseMs must be a positive number');\n\t}\n}\n\nexport function checkResult(result: AttemptResult): void {\n\tif (typeof result !== 'object' || result === null) {\n\t\tthrow invalid('An attempt result is an object');\n\t}\n\tcheckTime('now', result.now);\n\tcheckTime('nextAttemptAt', result.nextAttemptAt);\n\tif (!Number.isInteger(result.attempts) || result.attempts < 0) {\n\t\tthrow invalid('attempts must be an integer of at least 0');\n\t}\n\tif (typeof result.delayNotified !== 'boolean') {\n\t\tthrow invalid('delayNotified must be true or false');\n\t}\n\tconst statuses = ['delivered', 'deferred', 'failed'];\n\tif (\n\t\t!Array.isArray(result.recipients) ||\n\t\t!result.recipients.every(\n\t\t\t(u) => typeof u?.address === 'string' && statuses.includes(u.status),\n\t\t)\n\t) {\n\t\tthrow invalid(\n\t\t\t'recipients must be an array of { address, status: delivered, deferred or failed }',\n\t\t);\n\t}\n\tfor (const update of result.recipients) checkUpdate(update);\n}\n\n/** The offset and limit of a list: integers, the limit 1 to 1000. */\nexport function checkList(options: QueueListOptions = {}): {\n\toffset: number;\n\tlimit: number;\n} {\n\tconst offset = options.offset ?? 0;\n\tconst limit = options.limit ?? 100;\n\tif (!Number.isInteger(offset) || offset < 0) {\n\t\tthrow invalid(`offset must be an integer of at least 0, not ${offset}`);\n\t}\n\tif (!Number.isInteger(limit) || limit < 1 || limit > 1000) {\n\t\tthrow invalid(`limit must be an integer from 1 to 1000, not ${limit}`);\n\t}\n\treturn { offset, limit };\n}\n\n/** Every recipient is `delivered` or `failed`. */\nexport const isDone = (item: Pick<QueueItem, 'recipients'>): boolean =>\n\titem.recipients.every(\n\t\t(r) => r.status === 'delivered' || r.status === 'failed',\n\t);\n\n/**\n * The item once an attempt is recorded: its recipients' outcomes, a final\n * state never changed again, the schedule, and no lease.\n */\nexport function applyAttempt(\n\titem: QueueItem,\n\tresult: AttemptResult,\n): QueueItem {\n\tconst updates = new Map(result.recipients.map((u) => [u.address, u]));\n\tconst recipients = item.recipients.map((r): RecipientState => {\n\t\tconst update = updates.get(r.address);\n\t\tif (!update || r.status === 'delivered' || r.status === 'failed') return r;\n\t\treturn {\n\t\t\taddress: r.address,\n\t\t\tstatus: update.status,\n\t\t\t...(r.notify === undefined ? {} : { notify: r.notify }),\n\t\t\t...(r.orcpt === undefined ? {} : { orcpt: r.orcpt }),\n\t\t\t...(update.reply ? { reply: update.reply } : {}),\n\t\t\tupdatedAt: result.now,\n\t\t\t...(r.mayHaveReachedMx || update.mayHaveReachedMx\n\t\t\t\t? { mayHaveReachedMx: true as const }\n\t\t\t\t: {}),\n\t\t\t...(r.mayHaveReachedFallback || update.mayHaveReachedFallback\n\t\t\t\t? { mayHaveReachedFallback: true as const }\n\t\t\t\t: {}),\n\t\t};\n\t});\n\tconst { lease: _, ...rest } = item;\n\treturn {\n\t\t...rest,\n\t\trecipients,\n\t\tnextAttemptAt: result.nextAttemptAt,\n\t\tattempts: result.attempts,\n\t\tdelayNotified: result.delayNotified,\n\t};\n}\n\n/** A new item as a store first keeps it. */\nexport function newItem(id: string, item: NewQueueItem): QueueItem {\n\tconst dsn = new Map(item.recipients?.map((r) => [r.address, r]));\n\treturn {\n\t\tid,\n\t\tfrom: item.from,\n\t\trecipients: item.to.map((address): RecipientState => {\n\t\t\tconst { notify, orcpt } = dsn.get(address) ?? {};\n\t\t\treturn {\n\t\t\t\taddress,\n\t\t\t\tstatus: 'pending',\n\t\t\t\t...(notify === undefined\n\t\t\t\t\t? {}\n\t\t\t\t\t: { notify: notify === 'NEVER' ? notify : [...notify] }),\n\t\t\t\t...(orcpt === undefined\n\t\t\t\t\t? {}\n\t\t\t\t\t: { orcpt: { type: orcpt.type, address: orcpt.address } }),\n\t\t\t};\n\t\t}),\n\t\tsize: item.message.length,\n\t\tcreatedAt: item.createdAt,\n\t\tnextAttemptAt: item.createdAt,\n\t\tattempts: 0,\n\t\tdelayNotified: false,\n\t\t...(item.ret === undefined ? {} : { ret: item.ret }),\n\t\t...(item.envid === undefined ? {} : { envid: item.envid }),\n\t};\n}\n\n/** Whether a lease, if any, leaves the item free to claim at `now`. */\nexport const claimable = (item: QueueItem, now: number): boolean =>\n\titem.nextAttemptAt <= now &&\n\t(item.lease === undefined || item.lease.expiresAt <= now);\n"
|
|
9
|
+
"import { invalid } from '../errors';\nimport { checkDsnParams } from './dsn-checks';\nimport { checkStorable } from './storable';\n\nexport { checkStorable };\n\nimport type {\n\tAttemptResult,\n\tClaimRequest,\n\tDiagnostic,\n\tNewQueueItem,\n\tQueueItem,\n\tQueueListOptions,\n\tRecipientState,\n\tRecipientUpdate,\n} from './types';\n\n/** What every store checks the same way, so each refuses the same input with the same error. */\n\nconst isTime = (value: unknown): value is number =>\n\ttypeof value === 'number' && Number.isFinite(value);\n\n/** A time in milliseconds since the epoch, or `INVALID` naming it. */\nexport function checkTime(name: string, value: unknown): number {\n\tif (!isTime(value)) throw invalid(`${name} must be a finite number`);\n\treturn value;\n}\n\n/** A lease owner: a non-empty string. */\nexport function checkOwner(owner: unknown): string {\n\tif (typeof owner !== 'string' || owner === '') {\n\t\tthrow invalid('owner must be a non-empty string');\n\t}\n\tcheckStorable('owner', owner);\n\treturn owner;\n}\n\n/** Every text of a recipient's outcome. */\nfunction checkUpdate(update: RecipientUpdate): void {\n\tcheckStorable('A recipient', update.address);\n\tfor (const key of ['mayHaveReachedMx', 'mayHaveReachedFallback'] as const) {\n\t\tconst mark = update[key] as unknown;\n\t\tif (mark !== undefined && mark !== true) {\n\t\t\tthrow invalid(`${key} must be true or absent`);\n\t\t}\n\t}\n\tconst reply = update.reply as Partial<Diagnostic> | undefined;\n\tif (reply === undefined) return;\n\tif (\n\t\ttypeof reply !== 'object' ||\n\t\treply === null ||\n\t\ttypeof reply.text !== 'string'\n\t) {\n\t\tthrow invalid('A reply is an object with a text');\n\t}\n\tcheckStorable('reply.text', reply.text);\n\tfor (const name of ['status', 'host'] as const) {\n\t\tconst value = reply[name];\n\t\tif (value === undefined) continue;\n\t\tif (typeof value !== 'string')\n\t\t\tthrow invalid(`reply.${name} must be a string`);\n\t\tcheckStorable(`reply.${name}`, value);\n\t}\n}\n\n/** The DSN items `complete` takes: an array, each as `add` checks an item. */\nexport function checkDsns(dsns: readonly NewQueueItem[]): void {\n\tif (!Array.isArray(dsns)) throw invalid('dsns must be an array');\n\tfor (const dsn of dsns) checkNewItem(dsn);\n}\n\n/** What `complete` checks before any I/O, in this order: the owner, the result, the DSNs. */\nexport function checkComplete(\n\towner: unknown,\n\tresult: AttemptResult,\n\tdsns: readonly NewQueueItem[],\n): void {\n\tcheckOwner(owner);\n\tcheckResult(result);\n\tcheckDsns(dsns);\n}\n\nexport function checkNewItem(item: NewQueueItem): void {\n\tif (typeof item !== 'object' || item === null) {\n\t\tthrow invalid('A new item is an object');\n\t}\n\tif (typeof item.from !== 'string') throw invalid('from must be a string');\n\tcheckStorable('from', item.from);\n\tconst to = item.to as unknown;\n\tif (\n\t\t!Array.isArray(to) ||\n\t\tto.length === 0 ||\n\t\t!to.every((a) => typeof a === 'string' && a !== '')\n\t) {\n\t\tthrow invalid('to must be a non-empty array of addresses');\n\t}\n\tfor (const address of to as string[]) checkStorable('A recipient', address);\n\tif (!(item.message instanceof Uint8Array)) {\n\t\tthrow invalid('message must be a Uint8Array');\n\t}\n\tcheckTime('createdAt', item.createdAt);\n\tcheckDsnParams(item);\n}\n\n/** `maxItems`: a positive integer, or nothing. */\nexport function checkMaxItems(max: unknown): number | undefined {\n\tif (max === undefined) return undefined;\n\tif (typeof max !== 'number' || !Number.isInteger(max) || max < 1) {\n\t\tthrow invalid(`maxItems must be an integer of at least 1, not ${max}`);\n\t}\n\treturn max;\n}\n\nexport function checkClaim(request: ClaimRequest): void {\n\tif (typeof request !== 'object' || request === null) {\n\t\tthrow invalid('A claim is an object');\n\t}\n\tcheckOwner(request.owner);\n\tcheckTime('now', request.now);\n\tif (!isTime(request.leaseMs) || request.leaseMs <= 0) {\n\t\tthrow invalid('leaseMs must be a positive number');\n\t}\n}\n\nexport function checkResult(result: AttemptResult): void {\n\tif (typeof result !== 'object' || result === null) {\n\t\tthrow invalid('An attempt result is an object');\n\t}\n\tcheckTime('now', result.now);\n\tcheckTime('nextAttemptAt', result.nextAttemptAt);\n\tif (!Number.isInteger(result.attempts) || result.attempts < 0) {\n\t\tthrow invalid('attempts must be an integer of at least 0');\n\t}\n\tif (typeof result.delayNotified !== 'boolean') {\n\t\tthrow invalid('delayNotified must be true or false');\n\t}\n\tconst statuses = ['delivered', 'deferred', 'failed'];\n\tif (\n\t\t!Array.isArray(result.recipients) ||\n\t\t!result.recipients.every(\n\t\t\t(u) => typeof u?.address === 'string' && statuses.includes(u.status),\n\t\t)\n\t) {\n\t\tthrow invalid(\n\t\t\t'recipients must be an array of { address, status: delivered, deferred or failed }',\n\t\t);\n\t}\n\tfor (const update of result.recipients) checkUpdate(update);\n}\n\n/** The offset and limit of a list: integers, the limit 1 to 1000. */\nexport function checkList(options: QueueListOptions = {}): {\n\toffset: number;\n\tlimit: number;\n} {\n\tconst offset = options.offset ?? 0;\n\tconst limit = options.limit ?? 100;\n\tif (!Number.isInteger(offset) || offset < 0) {\n\t\tthrow invalid(`offset must be an integer of at least 0, not ${offset}`);\n\t}\n\tif (!Number.isInteger(limit) || limit < 1 || limit > 1000) {\n\t\tthrow invalid(`limit must be an integer from 1 to 1000, not ${limit}`);\n\t}\n\treturn { offset, limit };\n}\n\n/** Every recipient is `delivered` or `failed`. */\nexport const isDone = (item: Pick<QueueItem, 'recipients'>): boolean =>\n\titem.recipients.every(\n\t\t(r) => r.status === 'delivered' || r.status === 'failed',\n\t);\n\n/**\n * The item once an attempt is recorded: its recipients' outcomes, a final\n * state never changed again, the schedule, and no lease.\n */\nexport function applyAttempt(\n\titem: QueueItem,\n\tresult: AttemptResult,\n): QueueItem {\n\tconst updates = new Map(result.recipients.map((u) => [u.address, u]));\n\tconst recipients = item.recipients.map((r): RecipientState => {\n\t\tconst update = updates.get(r.address);\n\t\tif (!update || r.status === 'delivered' || r.status === 'failed') return r;\n\t\treturn {\n\t\t\taddress: r.address,\n\t\t\tstatus: update.status,\n\t\t\t...(r.notify === undefined ? {} : { notify: r.notify }),\n\t\t\t...(r.orcpt === undefined ? {} : { orcpt: r.orcpt }),\n\t\t\t...(update.reply ? { reply: update.reply } : {}),\n\t\t\tupdatedAt: result.now,\n\t\t\t...(r.mayHaveReachedMx || update.mayHaveReachedMx\n\t\t\t\t? { mayHaveReachedMx: true as const }\n\t\t\t\t: {}),\n\t\t\t...(r.mayHaveReachedFallback || update.mayHaveReachedFallback\n\t\t\t\t? { mayHaveReachedFallback: true as const }\n\t\t\t\t: {}),\n\t\t};\n\t});\n\tconst { lease: _, ...rest } = item;\n\treturn {\n\t\t...rest,\n\t\trecipients,\n\t\tnextAttemptAt: result.nextAttemptAt,\n\t\tattempts: result.attempts,\n\t\tdelayNotified: result.delayNotified,\n\t};\n}\n\n/** A new item as a store first keeps it. */\nexport function newItem(id: string, item: NewQueueItem): QueueItem {\n\tconst dsn = new Map(item.recipients?.map((r) => [r.address, r]));\n\treturn {\n\t\tid,\n\t\tfrom: item.from,\n\t\trecipients: item.to.map((address): RecipientState => {\n\t\t\tconst { notify, orcpt } = dsn.get(address) ?? {};\n\t\t\treturn {\n\t\t\t\taddress,\n\t\t\t\tstatus: 'pending',\n\t\t\t\t...(notify === undefined\n\t\t\t\t\t? {}\n\t\t\t\t\t: { notify: notify === 'NEVER' ? notify : [...notify] }),\n\t\t\t\t...(orcpt === undefined\n\t\t\t\t\t? {}\n\t\t\t\t\t: { orcpt: { type: orcpt.type, address: orcpt.address } }),\n\t\t\t};\n\t\t}),\n\t\tsize: item.message.length,\n\t\tcreatedAt: item.createdAt,\n\t\tnextAttemptAt: item.createdAt,\n\t\tattempts: 0,\n\t\tdelayNotified: false,\n\t\t...(item.ret === undefined ? {} : { ret: item.ret }),\n\t\t...(item.envid === undefined ? {} : { envid: item.envid }),\n\t};\n}\n\n/** Whether a lease, if any, leaves the item free to claim at `now`. */\nexport const claimable = (item: QueueItem, now: number): boolean =>\n\titem.nextAttemptAt <= now &&\n\t(item.lease === undefined || item.lease.expiresAt <= now);\n"
|
|
10
10
|
],
|
|
11
|
-
"mappings": ";AAGA,IAAM,YAAY,CAAC,SAClB,OAAO,MAAS,QAAQ,OAAQ,QAAQ;AAGlC,SAAS,UAAU,CAAC,MAAuB;AAAA,EACjD,SAAS,IAAI,EAAG,IAAI,KAAK,QAAQ,KAAK;AAAA,IACrC,IAAI,UAAU,KAAK,WAAW,CAAC,CAAC;AAAA,MAAG,OAAO;AAAA,EAC3C;AAAA,EACA,OAAO;AAAA;AAID,SAAS,eAAe,CAAC,MAAc,IAAoB;AAAA,EACjE,IAAI,MAAM;AAAA,EACV,SAAS,IAAI,EAAG,IAAI,KAAK,QAAQ,KAAK;AAAA,IACrC,OAAO,UAAU,KAAK,WAAW,CAAC,CAAC,IAAI,KAAM,KAAK;AAAA,EACnD;AAAA,EACA,OAAO;AAAA;AASD,SAAS,SAAS,CAAC,MAAc,KAAqB;AAAA,EAC5D,MAAM,QAAQ,gBAAgB,KAAK,aAAa,GAAG,GAAG,EACpD,QAAQ,UAAU,GAAG,EACrB,KAAK;AAAA,EACP,OAAO,MAAM,SAAS,MAAM,GAAG,IAAI,OAAO,MAAM,CAAC,SAAS;AAAA;AAQ3D,SAAS,GAAG,CAAC,MAAc,QAAwB;AAAA,EAClD,MAAM,OAAO,KAAK,MAAM,GAAG,MAAM;AAAA,EACjC,MAAM,OAAO,KAAK,WAAW,KAAK,SAAS,CAAC;AAAA,EAC5C,OAAO,QAAQ,SAAU,QAAQ,QAAS,KAAK,MAAM,GAAG,EAAE,IAAI;AAAA;AAOxD,IAAM,aAAa,CAAC,SAC1B,KAAK,aAAa,KAAK,CAAC,KAAK,SAAS,MAAI;AAGpC,IAAM,YAAY,CAAC,MAAc,QACvC,UAAU,MAAM,GAAG,EAAE,QAAQ,WAAW,GAAG;;;
|
|
12
|
-
"debugId": "
|
|
11
|
+
"mappings": ";AAGA,IAAM,YAAY,CAAC,SAClB,OAAO,MAAS,QAAQ,OAAQ,QAAQ;AAGlC,SAAS,UAAU,CAAC,MAAuB;AAAA,EACjD,SAAS,IAAI,EAAG,IAAI,KAAK,QAAQ,KAAK;AAAA,IACrC,IAAI,UAAU,KAAK,WAAW,CAAC,CAAC;AAAA,MAAG,OAAO;AAAA,EAC3C;AAAA,EACA,OAAO;AAAA;AAID,SAAS,eAAe,CAAC,MAAc,IAAoB;AAAA,EACjE,IAAI,MAAM;AAAA,EACV,SAAS,IAAI,EAAG,IAAI,KAAK,QAAQ,KAAK;AAAA,IACrC,OAAO,UAAU,KAAK,WAAW,CAAC,CAAC,IAAI,KAAM,KAAK;AAAA,EACnD;AAAA,EACA,OAAO;AAAA;AASD,SAAS,SAAS,CAAC,MAAc,KAAqB;AAAA,EAC5D,MAAM,QAAQ,gBAAgB,KAAK,aAAa,GAAG,GAAG,EACpD,QAAQ,UAAU,GAAG,EACrB,KAAK;AAAA,EACP,OAAO,MAAM,SAAS,MAAM,GAAG,IAAI,OAAO,MAAM,CAAC,SAAS;AAAA;AAQ3D,SAAS,GAAG,CAAC,MAAc,QAAwB;AAAA,EAClD,MAAM,OAAO,KAAK,MAAM,GAAG,MAAM;AAAA,EACjC,MAAM,OAAO,KAAK,WAAW,KAAK,SAAS,CAAC;AAAA,EAC5C,OAAO,QAAQ,SAAU,QAAQ,QAAS,KAAK,MAAM,GAAG,EAAE,IAAI;AAAA;AAOxD,IAAM,aAAa,CAAC,SAC1B,KAAK,aAAa,KAAK,CAAC,KAAK,SAAS,MAAI;AAGpC,IAAM,YAAY,CAAC,MAAc,QACvC,UAAU,MAAM,GAAG,EAAE,QAAQ,WAAW,GAAG;;;AClCrC,MAAM,oBAAmB,MAAM;AAAA,EACnB,OAAO;AAAA,EAChB;AAAA,EAET,WAAW,CAAC,MAAsB,SAAiB;AAAA,IAClD,MAAM,OAAO;AAAA,IACb,KAAK,OAAO;AAAA;AAEd;AAGO,IAAM,UAAU,CAAC,YAAoB,IAAI,YAAW,WAAW,OAAO;;;ACzBtE,SAAS,aAAa,CAAC,MAAc,MAAoB;AAAA,EAC/D,IAAI,CAAC,WAAW,IAAI,GAAG;AAAA,IACtB,MAAM,QACL,GAAG,iEACJ;AAAA,EACD;AAAA;;;ACPD,IAAM,SAA6B,CAAC,WAAW,WAAW,OAAO;AAOjE,SAAS,WAAW,CAAC,MAAsB;AAAA,EAC1C,IAAI,SAAS;AAAA,EACb,WAAW,QAAQ,IAAI,YAAY,EAAE,OAAO,IAAI,GAAG;AAAA,IAClD,UACC,QAAQ,MAAM,QAAQ,OAAO,SAAS,MAAQ,SAAS,KAAO,IAAI;AAAA,EACpE;AAAA,EACA,OAAO;AAAA;AASR,SAAS,eAAe,CAAC,MAAsB;AAAA,EAC9C,IAAI,SAAS;AAAA,EACb,WAAW,QAAQ,MAAM;AAAA,IACxB,MAAM,OAAO,KAAK,YAAY,CAAC;AAAA,IAC/B,IAAI,OAAO;AAAA,MAAM,UAAU,IAAI,YAAY,EAAE,OAAO,IAAI,EAAE;AAAA,IAC1D;AAAA,MACC,UACC,QAAQ,MACR,SAAS,MACT,SAAS,MACT,SAAS,MACT,OAAO,MACJ,IACA;AAAA,EACN;AAAA,EACA,OAAO;AAAA;AAIR,SAAS,iBAAiB,CAAC,OAAqB,IAA6B;AAAA,EAC5E,QAAQ,SAAS,QAAQ,UAAU,SAAS,CAAC;AAAA,EAC7C,IAAI,OAAO,YAAY,YAAY,CAAC,GAAG,SAAS,OAAO,GAAG;AAAA,IACzD,MAAM,QACL,oBAAoB,KAAK,UAAU,OAAO,uBAC3C;AAAA,EACD;AAAA,EACA,IAAI,WAAW,aAAa,WAAW,SAAS;AAAA,IAC/C,MAAM,SAA6B,MAAM,QAAQ,MAAM,IAAI,SAAS,CAAC;AAAA,IACrE,IACC,OAAO,WAAW,KAClB,OAAO,KAAK,CAAC,GAAG,MAAM,CAAC,OAAO,SAAS,CAAC,KAAK,OAAO,QAAQ,CAAC,MAAM,CAAC,GACnE;AAAA,MACD,MAAM,QACL,aAAa,+EACd;AAAA,IACD;AAAA,EACD;AAAA,EACA,IAAI,UAAU;AAAA,IAAW;AAAA,EACzB,IACC,OAAO,UAAU,YACjB,UAAU,QACV,OAAO,MAAM,SAAS,YACtB,CAAC,kBAAkB,KAAK,MAAM,IAAI,KAClC,OAAO,MAAM,YAAY,YACzB,MAAM,YAAY,IACjB;AAAA,IACD,MAAM,QAAQ,YAAY,mCAAmC;AAAA,EAC9D;AAAA,EAEA,MAAM,UACL,MAAM,KAAK,YAAY,MAAM,UAC1B,gBAAgB,MAAM,OAAO,IAC7B,YAAY,MAAM,OAAO;AAAA,EAC7B,IAAI,MAAM,KAAK,SAAS,IAAI,UAAU,KAAK;AAAA,IAC1C,MAAM,QAAQ,YAAY,6CAA6C;AAAA,EACxE;AAAA,EACA,cAAc,cAAc,MAAM,IAAI;AAAA,EACtC,cAAc,iBAAiB,MAAM,OAAO;AAAA;AAItC,SAAS,cAAc,CAAC,MAA0B;AAAA,EACxD,QAAQ,KAAK,OAAO,eAAe;AAAA,EACnC,IAAI,QAAQ,aAAa,QAAQ,UAAU,QAAQ,QAAQ;AAAA,IAC1D,MAAM,QAAQ,qCAAqC,OAAO,GAAG,GAAG;AAAA,EACjE;AAAA,EACA,IACC,UAAU,cACT,OAAO,UAAU,YACjB,CAAC,iBAAiB,KAAK,KAAK,KAE5B,YAAY,KAAK,IAAI,MACrB;AAAA,IACD,MAAM,QACL,sFACD;AAAA,EACD;AAAA,EACA,IAAI,eAAe;AAAA,IAAW;AAAA,EAC9B,IAAI,CAAC,MAAM,QAAQ,UAAU,GAAG;AAAA,IAC/B,MAAM,QAAQ,2DAA2D;AAAA,EAC1E;AAAA,EACA,MAAM,OAAO,IAAI;AAAA,EACjB,WAAW,SAAS,YAAY;AAAA,IAC/B,kBAAkB,OAAO,KAAK,EAAE;AAAA,IAChC,IAAI,KAAK,IAAI,MAAM,OAAO,GAAG;AAAA,MAC5B,MAAM,QAAQ,oBAAoB,MAAM,eAAe;AAAA,IACxD;AAAA,IACA,KAAK,IAAI,MAAM,OAAO;AAAA,EACvB;AAAA;;;ACjGD,IAAM,SAAS,CAAC,UACf,OAAO,UAAU,YAAY,OAAO,SAAS,KAAK;AAG5C,SAAS,SAAS,CAAC,MAAc,OAAwB;AAAA,EAC/D,IAAI,CAAC,OAAO,KAAK;AAAA,IAAG,MAAM,QAAQ,GAAG,8BAA8B;AAAA,EACnE,OAAO;AAAA;AAID,SAAS,UAAU,CAAC,OAAwB;AAAA,EAClD,IAAI,OAAO,UAAU,YAAY,UAAU,IAAI;AAAA,IAC9C,MAAM,QAAQ,kCAAkC;AAAA,EACjD;AAAA,EACA,cAAc,SAAS,KAAK;AAAA,EAC5B,OAAO;AAAA;AAIR,SAAS,WAAW,CAAC,QAA+B;AAAA,EACnD,cAAc,eAAe,OAAO,OAAO;AAAA,EAC3C,WAAW,OAAO,CAAC,oBAAoB,wBAAwB,GAAY;AAAA,IAC1E,MAAM,OAAO,OAAO;AAAA,IACpB,IAAI,SAAS,aAAa,SAAS,MAAM;AAAA,MACxC,MAAM,QAAQ,GAAG,4BAA4B;AAAA,IAC9C;AAAA,EACD;AAAA,EACA,MAAM,QAAQ,OAAO;AAAA,EACrB,IAAI,UAAU;AAAA,IAAW;AAAA,EACzB,IACC,OAAO,UAAU,YACjB,UAAU,QACV,OAAO,MAAM,SAAS,UACrB;AAAA,IACD,MAAM,QAAQ,kCAAkC;AAAA,EACjD;AAAA,EACA,cAAc,cAAc,MAAM,IAAI;AAAA,EACtC,WAAW,QAAQ,CAAC,UAAU,MAAM,GAAY;AAAA,IAC/C,MAAM,QAAQ,MAAM;AAAA,IACpB,IAAI,UAAU;AAAA,MAAW;AAAA,IACzB,IAAI,OAAO,UAAU;AAAA,MACpB,MAAM,QAAQ,SAAS,uBAAuB;AAAA,IAC/C,cAAc,SAAS,QAAQ,KAAK;AAAA,EACrC;AAAA;AAIM,SAAS,SAAS,CAAC,MAAqC;AAAA,EAC9D,IAAI,CAAC,MAAM,QAAQ,IAAI;AAAA,IAAG,MAAM,QAAQ,uBAAuB;AAAA,EAC/D,WAAW,OAAO;AAAA,IAAM,aAAa,GAAG;AAAA;AAIlC,SAAS,aAAa,CAC5B,OACA,QACA,MACO;AAAA,EACP,WAAW,KAAK;AAAA,EAChB,YAAY,MAAM;AAAA,EAClB,UAAU,IAAI;AAAA;AAGR,SAAS,YAAY,CAAC,MAA0B;AAAA,EACtD,IAAI,OAAO,SAAS,YAAY,SAAS,MAAM;AAAA,IAC9C,MAAM,QAAQ,yBAAyB;AAAA,EACxC;AAAA,EACA,IAAI,OAAO,KAAK,SAAS;AAAA,IAAU,MAAM,QAAQ,uBAAuB;AAAA,EACxE,cAAc,QAAQ,KAAK,IAAI;AAAA,EAC/B,MAAM,KAAK,KAAK;AAAA,EAChB,IACC,CAAC,MAAM,QAAQ,EAAE,KACjB,GAAG,WAAW,KACd,CAAC,GAAG,MAAM,CAAC,MAAM,OAAO,MAAM,YAAY,MAAM,EAAE,GACjD;AAAA,IACD,MAAM,QAAQ,2CAA2C;AAAA,EAC1D;AAAA,EACA,WAAW,WAAW;AAAA,IAAgB,cAAc,eAAe,OAAO;AAAA,EAC1E,IAAI,EAAE,KAAK,mBAAmB,aAAa;AAAA,IAC1C,MAAM,QAAQ,8BAA8B;AAAA,EAC7C;AAAA,EACA,UAAU,aAAa,KAAK,SAAS;AAAA,EACrC,eAAe,IAAI;AAAA;AAIb,SAAS,aAAa,CAAC,KAAkC;AAAA,EAC/D,IAAI,QAAQ;AAAA,IAAW;AAAA,EACvB,IAAI,OAAO,QAAQ,YAAY,CAAC,OAAO,UAAU,GAAG,KAAK,MAAM,GAAG;AAAA,IACjE,MAAM,QAAQ,kDAAkD,KAAK;AAAA,EACtE;AAAA,EACA,OAAO;AAAA;AAGD,SAAS,UAAU,CAAC,SAA6B;AAAA,EACvD,IAAI,OAAO,YAAY,YAAY,YAAY,MAAM;AAAA,IACpD,MAAM,QAAQ,sBAAsB;AAAA,EACrC;AAAA,EACA,WAAW,QAAQ,KAAK;AAAA,EACxB,UAAU,OAAO,QAAQ,GAAG;AAAA,EAC5B,IAAI,CAAC,OAAO,QAAQ,OAAO,KAAK,QAAQ,WAAW,GAAG;AAAA,IACrD,MAAM,QAAQ,mCAAmC;AAAA,EAClD;AAAA;AAGM,SAAS,WAAW,CAAC,QAA6B;AAAA,EACxD,IAAI,OAAO,WAAW,YAAY,WAAW,MAAM;AAAA,IAClD,MAAM,QAAQ,gCAAgC;AAAA,EAC/C;AAAA,EACA,UAAU,OAAO,OAAO,GAAG;AAAA,EAC3B,UAAU,iBAAiB,OAAO,aAAa;AAAA,EAC/C,IAAI,CAAC,OAAO,UAAU,OAAO,QAAQ,KAAK,OAAO,WAAW,GAAG;AAAA,IAC9D,MAAM,QAAQ,2CAA2C;AAAA,EAC1D;AAAA,EACA,IAAI,OAAO,OAAO,kBAAkB,WAAW;AAAA,IAC9C,MAAM,QAAQ,qCAAqC;AAAA,EACpD;AAAA,EACA,MAAM,WAAW,CAAC,aAAa,YAAY,QAAQ;AAAA,EACnD,IACC,CAAC,MAAM,QAAQ,OAAO,UAAU,KAChC,CAAC,OAAO,WAAW,MAClB,CAAC,MAAM,OAAO,GAAG,YAAY,YAAY,SAAS,SAAS,EAAE,MAAM,CACpE,GACC;AAAA,IACD,MAAM,QACL,mFACD;AAAA,EACD;AAAA,EACA,WAAW,UAAU,OAAO;AAAA,IAAY,YAAY,MAAM;AAAA;AAIpD,SAAS,SAAS,CAAC,UAA4B,CAAC,GAGrD;AAAA,EACD,MAAM,SAAS,QAAQ,UAAU;AAAA,EACjC,MAAM,QAAQ,QAAQ,SAAS;AAAA,EAC/B,IAAI,CAAC,OAAO,UAAU,MAAM,KAAK,SAAS,GAAG;AAAA,IAC5C,MAAM,QAAQ,gDAAgD,QAAQ;AAAA,EACvE;AAAA,EACA,IAAI,CAAC,OAAO,UAAU,KAAK,KAAK,QAAQ,KAAK,QAAQ,MAAM;AAAA,IAC1D,MAAM,QAAQ,gDAAgD,OAAO;AAAA,EACtE;AAAA,EACA,OAAO,EAAE,QAAQ,MAAM;AAAA;AAIjB,IAAM,SAAS,CAAC,SACtB,KAAK,WAAW,MACf,CAAC,MAAM,EAAE,WAAW,eAAe,EAAE,WAAW,QACjD;AAMM,SAAS,YAAY,CAC3B,MACA,QACY;AAAA,EACZ,MAAM,UAAU,IAAI,IAAI,OAAO,WAAW,IAAI,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC;AAAA,EACpE,MAAM,aAAa,KAAK,WAAW,IAAI,CAAC,MAAsB;AAAA,IAC7D,MAAM,SAAS,QAAQ,IAAI,EAAE,OAAO;AAAA,IACpC,IAAI,CAAC,UAAU,EAAE,WAAW,eAAe,EAAE,WAAW;AAAA,MAAU,OAAO;AAAA,IACzE,OAAO;AAAA,MACN,SAAS,EAAE;AAAA,MACX,QAAQ,OAAO;AAAA,SACX,EAAE,WAAW,YAAY,CAAC,IAAI,EAAE,QAAQ,EAAE,OAAO;AAAA,SACjD,EAAE,UAAU,YAAY,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM;AAAA,SAC9C,OAAO,QAAQ,EAAE,OAAO,OAAO,MAAM,IAAI,CAAC;AAAA,MAC9C,WAAW,OAAO;AAAA,SACd,EAAE,oBAAoB,OAAO,mBAC9B,EAAE,kBAAkB,KAAc,IAClC,CAAC;AAAA,SACA,EAAE,0BAA0B,OAAO,yBACpC,EAAE,wBAAwB,KAAc,IACxC,CAAC;AAAA,IACL;AAAA,GACA;AAAA,EACD,QAAQ,OAAO,MAAM,SAAS;AAAA,EAC9B,OAAO;AAAA,OACH;AAAA,IACH;AAAA,IACA,eAAe,OAAO;AAAA,IACtB,UAAU,OAAO;AAAA,IACjB,eAAe,OAAO;AAAA,EACvB;AAAA;AAIM,SAAS,OAAO,CAAC,IAAY,MAA+B;AAAA,EAClE,MAAM,MAAM,IAAI,IAAI,KAAK,YAAY,IAAI,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC;AAAA,EAC/D,OAAO;AAAA,IACN;AAAA,IACA,MAAM,KAAK;AAAA,IACX,YAAY,KAAK,GAAG,IAAI,CAAC,YAA4B;AAAA,MACpD,QAAQ,QAAQ,UAAU,IAAI,IAAI,OAAO,KAAK,CAAC;AAAA,MAC/C,OAAO;AAAA,QACN;AAAA,QACA,QAAQ;AAAA,WACJ,WAAW,YACZ,CAAC,IACD,EAAE,QAAQ,WAAW,UAAU,SAAS,CAAC,GAAG,MAAM,EAAE;AAAA,WACnD,UAAU,YACX,CAAC,IACD,EAAE,OAAO,EAAE,MAAM,MAAM,MAAM,SAAS,MAAM,QAAQ,EAAE;AAAA,MAC1D;AAAA,KACA;AAAA,IACD,MAAM,KAAK,QAAQ;AAAA,IACnB,WAAW,KAAK;AAAA,IAChB,eAAe,KAAK;AAAA,IACpB,UAAU;AAAA,IACV,eAAe;AAAA,OACX,KAAK,QAAQ,YAAY,CAAC,IAAI,EAAE,KAAK,KAAK,IAAI;AAAA,OAC9C,KAAK,UAAU,YAAY,CAAC,IAAI,EAAE,OAAO,KAAK,MAAM;AAAA,EACzD;AAAA;AAIM,IAAM,YAAY,CAAC,MAAiB,QAC1C,KAAK,iBAAiB,QACrB,KAAK,UAAU,aAAa,KAAK,MAAM,aAAa;",
|
|
12
|
+
"debugId": "17F888FDC5191A2364756E2164756E21",
|
|
13
13
|
"names": []
|
|
14
14
|
}
|
|
@@ -5,6 +5,10 @@ import type { AttemptResult, ClaimRequest, NewQueueItem, QueueItem, QueueListOpt
|
|
|
5
5
|
export declare function checkTime(name: string, value: unknown): number;
|
|
6
6
|
/** A lease owner: a non-empty string. */
|
|
7
7
|
export declare function checkOwner(owner: unknown): string;
|
|
8
|
+
/** The DSN items `complete` takes: an array, each as `add` checks an item. */
|
|
9
|
+
export declare function checkDsns(dsns: readonly NewQueueItem[]): void;
|
|
10
|
+
/** What `complete` checks before any I/O, in this order: the owner, the result, the DSNs. */
|
|
11
|
+
export declare function checkComplete(owner: unknown, result: AttemptResult, dsns: readonly NewQueueItem[]): void;
|
|
8
12
|
export declare function checkNewItem(item: NewQueueItem): void;
|
|
9
13
|
/** `maxItems`: a positive integer, or nothing. */
|
|
10
14
|
export declare function checkMaxItems(max: unknown): number | undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"checks.d.ts","sourceRoot":"","sources":["../../src/contract/checks.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3C,OAAO,EAAE,aAAa,EAAE,CAAC;AAEzB,OAAO,KAAK,EACX,aAAa,EACb,YAAY,EAEZ,YAAY,EACZ,SAAS,EACT,gBAAgB,EAGhB,MAAM,SAAS,CAAC;AAOjB,sEAAsE;AACtE,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,MAAM,CAG9D;AAED,yCAAyC;AACzC,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAMjD;AA8BD,wBAAgB,YAAY,CAAC,IAAI,EAAE,YAAY,GAAG,IAAI,CAoBrD;AAED,kDAAkD;AAClD,wBAAgB,aAAa,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAM9D;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI,CAStD;AAED,wBAAgB,WAAW,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI,CAwBvD;AAED,qEAAqE;AACrE,wBAAgB,SAAS,CAAC,OAAO,GAAE,gBAAqB,GAAG;IAC1D,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACd,CAUA;AAED,kDAAkD;AAClD,eAAO,MAAM,MAAM,GAAI,MAAM,IAAI,CAAC,SAAS,EAAE,YAAY,CAAC,KAAG,OAG3D,CAAC;AAEH;;;GAGG;AACH,wBAAgB,YAAY,CAC3B,IAAI,EAAE,SAAS,EACf,MAAM,EAAE,aAAa,GACnB,SAAS,CA4BX;AAED,4CAA4C;AAC5C,wBAAgB,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,GAAG,SAAS,CA0BjE;AAED,uEAAuE;AACvE,eAAO,MAAM,SAAS,GAAI,MAAM,SAAS,EAAE,KAAK,MAAM,KAAG,OAEC,CAAC"}
|
|
1
|
+
{"version":3,"file":"checks.d.ts","sourceRoot":"","sources":["../../src/contract/checks.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3C,OAAO,EAAE,aAAa,EAAE,CAAC;AAEzB,OAAO,KAAK,EACX,aAAa,EACb,YAAY,EAEZ,YAAY,EACZ,SAAS,EACT,gBAAgB,EAGhB,MAAM,SAAS,CAAC;AAOjB,sEAAsE;AACtE,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,MAAM,CAG9D;AAED,yCAAyC;AACzC,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAMjD;AA8BD,8EAA8E;AAC9E,wBAAgB,SAAS,CAAC,IAAI,EAAE,SAAS,YAAY,EAAE,GAAG,IAAI,CAG7D;AAED,6FAA6F;AAC7F,wBAAgB,aAAa,CAC5B,KAAK,EAAE,OAAO,EACd,MAAM,EAAE,aAAa,EACrB,IAAI,EAAE,SAAS,YAAY,EAAE,GAC3B,IAAI,CAIN;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,YAAY,GAAG,IAAI,CAoBrD;AAED,kDAAkD;AAClD,wBAAgB,aAAa,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAM9D;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI,CAStD;AAED,wBAAgB,WAAW,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI,CAwBvD;AAED,qEAAqE;AACrE,wBAAgB,SAAS,CAAC,OAAO,GAAE,gBAAqB,GAAG;IAC1D,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACd,CAUA;AAED,kDAAkD;AAClD,eAAO,MAAM,MAAM,GAAI,MAAM,IAAI,CAAC,SAAS,EAAE,YAAY,CAAC,KAAG,OAG3D,CAAC;AAEH;;;GAGG;AACH,wBAAgB,YAAY,CAC3B,IAAI,EAAE,SAAS,EACf,MAAM,EAAE,aAAa,GACnB,SAAS,CA4BX;AAED,4CAA4C;AAC5C,wBAAgB,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,GAAG,SAAS,CA0BjE;AAED,uEAAuE;AACvE,eAAO,MAAM,SAAS,GAAI,MAAM,SAAS,EAAE,KAAK,MAAM,KAAG,OAEC,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AddOptions, AttemptResult, ClaimRequest, NewQueueItem, QueueItem, QueueListOptions } from './types';
|
|
1
|
+
import type { AddOptions, AttemptResult, ClaimRequest, Completed, NewQueueItem, QueueItem, QueueListOptions } from './types';
|
|
2
2
|
/**
|
|
3
3
|
* Where the queue keeps its items, made for several workers, in one
|
|
4
4
|
* process or many, sharing one store. A worker **claims** a due item: it
|
|
@@ -48,13 +48,21 @@ export interface QueueStore {
|
|
|
48
48
|
renew(id: string, owner: string, expiresAt: number): Promise<boolean>;
|
|
49
49
|
/**
|
|
50
50
|
* Records an attempt: each recipient's outcome, the next attempt and the
|
|
51
|
-
* count, and lets go of the lease —
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
51
|
+
* count, and lets go of the lease — and inserts `dsns`, the DSN items
|
|
52
|
+
* the outcome calls for — in one step, while `owner` holds it: the
|
|
53
|
+
* outcome and its DSNs are both stored, or neither is. Returns the item
|
|
54
|
+
* as it now stands, done (every recipient final, and the item dropped) or
|
|
55
|
+
* not, with the inserted DSN items in the order given; `undefined` when
|
|
56
|
+
* `owner` no longer holds the lease, and then nothing is inserted: the
|
|
57
|
+
* lease is the idempotency token, so a DSN is inserted once per outcome.
|
|
58
|
+
*
|
|
59
|
+
* The DSNs ignore `maxItems`: a full queue loses no bounce. Each goes
|
|
60
|
+
* through the checks of `add`; one that fails them refuses the whole call
|
|
61
|
+
* with `INVALID`, with nothing recorded. The store gives them their ids.
|
|
62
|
+
* A recipient's `mayHaveReachedMx` and `mayHaveReachedFallback` marks,
|
|
63
|
+
* once recorded, are kept.
|
|
56
64
|
*/
|
|
57
|
-
complete(id: string, owner: string, result: AttemptResult): Promise<
|
|
65
|
+
complete(id: string, owner: string, result: AttemptResult, dsns: readonly NewQueueItem[]): Promise<Completed | undefined>;
|
|
58
66
|
/**
|
|
59
67
|
* Moves the next attempt to `at`. With `owner`, only while that owner
|
|
60
68
|
* holds the lease, which it lets go of: a worker giving an item back.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"queue-store.d.ts","sourceRoot":"","sources":["../../src/contract/queue-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,UAAU,EACV,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,SAAS,EACT,gBAAgB,EAChB,MAAM,SAAS,CAAC;AAEjB;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,UAAU;IAC1B;;;;;;OAMG;IACH,GAAG,CAAC,IAAI,EAAE,YAAY,EAAE,OAAO,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;IAElE,gGAAgG;IAChG,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC,CAAC;IAEhD,0DAA0D;IAC1D,IAAI,CAAC,OAAO,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;IAEvD,sCAAsC;IACtC,KAAK,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAEzB;;;;OAIG;IACH,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAAC;IAEzD;;;;;OAKG;IACH,KAAK,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC,CAAC;IAE7D;;;OAGG;IACH,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAEtE
|
|
1
|
+
{"version":3,"file":"queue-store.d.ts","sourceRoot":"","sources":["../../src/contract/queue-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,UAAU,EACV,aAAa,EACb,YAAY,EACZ,SAAS,EACT,YAAY,EACZ,SAAS,EACT,gBAAgB,EAChB,MAAM,SAAS,CAAC;AAEjB;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,UAAU;IAC1B;;;;;;OAMG;IACH,GAAG,CAAC,IAAI,EAAE,YAAY,EAAE,OAAO,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;IAElE,gGAAgG;IAChG,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC,CAAC;IAEhD,0DAA0D;IAC1D,IAAI,CAAC,OAAO,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;IAEvD,sCAAsC;IACtC,KAAK,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAEzB;;;;OAIG;IACH,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAAC;IAEzD;;;;;OAKG;IACH,KAAK,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC,CAAC;IAE7D;;;OAGG;IACH,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAEtE;;;;;;;;;;;;;;;OAeG;IACH,QAAQ,CACP,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,aAAa,EACrB,IAAI,EAAE,SAAS,YAAY,EAAE,GAC3B,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC,CAAC;IAElC;;;;;OAKG;IACH,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAErE,0FAA0F;IAC1F,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC,CAAC;CACnD"}
|
package/dist/contract/types.d.ts
CHANGED
|
@@ -101,6 +101,11 @@ export interface QueueItem {
|
|
|
101
101
|
/** Present while a worker holds the item. */
|
|
102
102
|
readonly lease?: Lease;
|
|
103
103
|
}
|
|
104
|
+
/** What `complete` returns: the item as it now stands, and the DSN items it inserted in the same step, in the order given. */
|
|
105
|
+
export interface Completed {
|
|
106
|
+
readonly item: QueueItem;
|
|
107
|
+
readonly dsns: readonly QueueItem[];
|
|
108
|
+
}
|
|
104
109
|
/** What `add` takes. */
|
|
105
110
|
export interface NewQueueItem {
|
|
106
111
|
readonly from: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/contract/types.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/contract/types.ts"],"names":[],"mappings":"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"}
|
package/dist/errors.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Why the queue or a store refused a call. `INVALID`: an option or an
|
|
3
|
-
* argument it cannot take
|
|
3
|
+
* argument it cannot take, or, given to the `error` event, a store that
|
|
4
|
+
* answers an older contract (`complete` returning the item alone, without
|
|
5
|
+
* the DSNs). `MESSAGE_TOO_BIG`, `TOO_MANY_RECIPIENTS` and
|
|
4
6
|
* `QUEUE_FULL`: a limit `enqueue` enforces. `CLOSED`: a store used after
|
|
5
7
|
* `close()`. `LEASE_LOST`: given to the `error` event when another worker
|
|
6
8
|
* took an item before its outcome was recorded — or, once the lease's
|
package/dist/errors.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,cAAc,GACvB,SAAS,GACT,iBAAiB,GACjB,qBAAqB,GACrB,YAAY,GACZ,QAAQ,GACR,YAAY,GACZ,oBAAoB,CAAC;AAExB,mGAAmG;AACnG,qBAAa,UAAW,SAAQ,KAAK;IACpC,SAAkB,IAAI,gBAAgB;IACtC,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC;gBAElB,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM;CAIjD;AAED,+CAA+C;AAC/C,eAAO,MAAM,OAAO,GAAI,SAAS,MAAM,eAAuC,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export type { QueueStore } from './contract/queue-store';
|
|
2
|
-
export type { AddOptions, AttemptResult, ClaimRequest, Diagnostic, FinalStatus, Lease, NewQueueItem, NotifyEvent, OriginalRecipient, QueueItem, QueueListOptions, RecipientDsn, RecipientNotify, RecipientState, RecipientStatus, RecipientUpdate, RetMode, } from './contract/types';
|
|
2
|
+
export type { AddOptions, AttemptResult, ClaimRequest, Completed, Diagnostic, FinalStatus, Lease, NewQueueItem, NotifyEvent, OriginalRecipient, QueueItem, QueueListOptions, RecipientDsn, RecipientNotify, RecipientState, RecipientStatus, RecipientUpdate, RetMode, } from './contract/types';
|
|
3
3
|
export { type DeliveredDsnInput, type DeliveredRecipient, deliveredDsn, } from './dsn/delivered';
|
|
4
4
|
export { type FailedDsnInput, type FailedRecipient, failedDsn, } from './dsn/failed';
|
|
5
5
|
export { DEFAULT_MAX_RETURN } from './dsn/policy';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACzD,YAAY,EACX,UAAU,EACV,aAAa,EACb,YAAY,EACZ,UAAU,EACV,WAAW,EACX,KAAK,EACL,YAAY,EACZ,WAAW,EACX,iBAAiB,EACjB,SAAS,EACT,gBAAgB,EAChB,YAAY,EACZ,eAAe,EACf,cAAc,EACd,eAAe,EACf,eAAe,EACf,OAAO,GACP,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACN,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,EACvB,YAAY,GACZ,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACN,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,SAAS,GACT,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,KAAK,cAAc,EAAE,MAAM,UAAU,CAAC;AAC3D,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACrE,YAAY,EACX,aAAa,EACb,QAAQ,EACR,eAAe,EACf,WAAW,EACX,aAAa,EACb,cAAc,GACd,MAAM,gBAAgB,CAAC;AACxB,YAAY,EACX,KAAK,EACL,UAAU,EACV,WAAW,EACX,YAAY,EACZ,aAAa,EACb,KAAK,EACL,MAAM,EACN,SAAS,GACT,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,WAAW,EAAE,KAAK,KAAK,EAAE,MAAM,eAAe,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACzD,YAAY,EACX,UAAU,EACV,aAAa,EACb,YAAY,EACZ,SAAS,EACT,UAAU,EACV,WAAW,EACX,KAAK,EACL,YAAY,EACZ,WAAW,EACX,iBAAiB,EACjB,SAAS,EACT,gBAAgB,EAChB,YAAY,EACZ,eAAe,EACf,cAAc,EACd,eAAe,EACf,eAAe,EACf,OAAO,GACP,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACN,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,EACvB,YAAY,GACZ,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACN,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,SAAS,GACT,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,KAAK,cAAc,EAAE,MAAM,UAAU,CAAC;AAC3D,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACrE,YAAY,EACX,aAAa,EACb,QAAQ,EACR,eAAe,EACf,WAAW,EACX,aAAa,EACb,cAAc,GACd,MAAM,gBAAgB,CAAC;AACxB,YAAY,EACX,KAAK,EACL,UAAU,EACV,WAAW,EACX,YAAY,EACZ,aAAa,EACb,KAAK,EACL,MAAM,EACN,SAAS,GACT,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,WAAW,EAAE,KAAK,KAAK,EAAE,MAAM,eAAe,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
QueueError2,
|
|
7
7
|
invalid,
|
|
8
8
|
checkOwner
|
|
9
|
-
} from "./chunks/index-
|
|
9
|
+
} from "./chunks/index-t6q7zxgj.js";
|
|
10
10
|
|
|
11
11
|
// src/dsn/build.ts
|
|
12
12
|
import {
|
|
@@ -938,12 +938,12 @@ function reported(r, kind) {
|
|
|
938
938
|
text: [reply.text, ...said].filter((t) => t !== "").join(" ")
|
|
939
939
|
};
|
|
940
940
|
}
|
|
941
|
-
|
|
941
|
+
function dsnsFor(ctx, item, message, kind, recipients, now, failures) {
|
|
942
942
|
const states = new Map(item.recipients.map((r) => [r.address, r]));
|
|
943
943
|
const wanted = recipients.filter((r) => asked(kind, states.get(r.address)?.notify));
|
|
944
944
|
if (item.from === "" || wanted.length === 0)
|
|
945
|
-
return;
|
|
946
|
-
const { settings
|
|
945
|
+
return [];
|
|
946
|
+
const { settings } = ctx;
|
|
947
947
|
try {
|
|
948
948
|
const lastAttempt = new Date(now);
|
|
949
949
|
const dsn = buildDsn({
|
|
@@ -969,21 +969,61 @@ async function notify(ctx, item, message, kind, recipients, now) {
|
|
|
969
969
|
returnContent: kind === "relayed" ? "headers" : returnOf(item.ret, settings.dsn.returnContent),
|
|
970
970
|
maxReturn: settings.limits.maxDsnReturn
|
|
971
971
|
});
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
972
|
+
return [
|
|
973
|
+
{
|
|
974
|
+
item: { from: "", to: [item.from], message: dsn, createdAt: now },
|
|
975
|
+
kind,
|
|
976
|
+
to: item.from,
|
|
977
|
+
recipients: wanted.map((r) => r.address)
|
|
978
|
+
}
|
|
979
|
+
];
|
|
980
|
+
} catch (error) {
|
|
981
|
+
failures.push(error);
|
|
982
|
+
return [];
|
|
983
|
+
}
|
|
984
|
+
}
|
|
985
|
+
function dsnsOf(ctx, item, message, settled, now) {
|
|
986
|
+
const failures = [];
|
|
987
|
+
const build = (kind, recipients) => dsnsFor(ctx, item, message, kind, recipients, now, failures);
|
|
988
|
+
const pending = [
|
|
989
|
+
...build("failed", settled.failed),
|
|
990
|
+
...build("relayed", settled.delivered.filter((u) => u.dsnOffered === false)),
|
|
991
|
+
...settled.delayDsn ? build("delayed", settled.deferred) : []
|
|
992
|
+
];
|
|
993
|
+
return { pending, failures };
|
|
994
|
+
}
|
|
995
|
+
async function tellDsns(ctx, item, pending, completed) {
|
|
996
|
+
const { store, events } = ctx;
|
|
997
|
+
const stored = completed.dsns;
|
|
998
|
+
const outdated = !Array.isArray(stored);
|
|
999
|
+
if (outdated && pending.length > 0) {
|
|
1000
|
+
const error = new QueueError2("INVALID", "Queue store outdated: complete returned the item alone, not { item, dsns }; its DSNs are added one by one, outside the step that records the outcome");
|
|
1001
|
+
events.emit("error", { error, id: item.id });
|
|
1002
|
+
}
|
|
1003
|
+
for (const [index, dsn] of pending.entries()) {
|
|
1004
|
+
let id;
|
|
1005
|
+
if (outdated) {
|
|
1006
|
+
try {
|
|
1007
|
+
id = (await store.add(dsn.item)).id;
|
|
1008
|
+
} catch (error) {
|
|
1009
|
+
events.emit("error", { error, id: item.id });
|
|
1010
|
+
continue;
|
|
1011
|
+
}
|
|
1012
|
+
} else {
|
|
1013
|
+
id = stored[index]?.id;
|
|
1014
|
+
if (id === undefined) {
|
|
1015
|
+
const error = new QueueError2("INVALID", `The queue store stored ${stored.length} of the ${pending.length} DSNs of ${item.id}: a ${dsn.kind} DSN to ${dsn.to} is lost`);
|
|
1016
|
+
events.emit("error", { error, id: item.id });
|
|
1017
|
+
continue;
|
|
1018
|
+
}
|
|
1019
|
+
}
|
|
978
1020
|
events.emit("dsn", {
|
|
979
|
-
kind,
|
|
980
|
-
id
|
|
1021
|
+
kind: dsn.kind,
|
|
1022
|
+
id,
|
|
981
1023
|
of: item.id,
|
|
982
|
-
to:
|
|
983
|
-
recipients:
|
|
1024
|
+
to: dsn.to,
|
|
1025
|
+
recipients: dsn.recipients
|
|
984
1026
|
});
|
|
985
|
-
} catch (error) {
|
|
986
|
-
events.emit("error", { error, id: item.id });
|
|
987
1027
|
}
|
|
988
1028
|
}
|
|
989
1029
|
|
|
@@ -1116,9 +1156,10 @@ async function record(ctx, item, updates, skipped, message, used) {
|
|
|
1116
1156
|
const { settings, store, events } = ctx;
|
|
1117
1157
|
const now = settings.now();
|
|
1118
1158
|
const settled = settle(item, updates, skipped, now, settings);
|
|
1119
|
-
const
|
|
1159
|
+
const { pending, failures } = dsnsOf(ctx, item, message, settled, now);
|
|
1160
|
+
const completed = await store.complete(item.id, settings.owner, settled.result, pending.map((p) => p.item));
|
|
1120
1161
|
ctx.recorded();
|
|
1121
|
-
if (!
|
|
1162
|
+
if (!completed && await store.get(item.id) === undefined) {
|
|
1122
1163
|
const lapse = await ctx.leaseLapsed(now);
|
|
1123
1164
|
if (lapse) {
|
|
1124
1165
|
events.emit("error", { error: goneAfter(lapse, item.id), id: item.id });
|
|
@@ -1129,7 +1170,7 @@ async function record(ctx, item, updates, skipped, message, used) {
|
|
|
1129
1170
|
emitOutcomes(events, item, settled, used);
|
|
1130
1171
|
return;
|
|
1131
1172
|
}
|
|
1132
|
-
if (!
|
|
1173
|
+
if (!completed) {
|
|
1133
1174
|
const error = new QueueError2("LEASE_LOST", `The lease on ${item.id} was lost before its outcome was recorded; another worker will try it again`);
|
|
1134
1175
|
events.emit("error", { error, id: item.id });
|
|
1135
1176
|
return;
|
|
@@ -1138,12 +1179,9 @@ async function record(ctx, item, updates, skipped, message, used) {
|
|
|
1138
1179
|
events.emit("error", { error: unreadableError(item.id), id: item.id });
|
|
1139
1180
|
}
|
|
1140
1181
|
emitOutcomes(events, item, settled, used);
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
await
|
|
1144
|
-
if (settled.delayDsn) {
|
|
1145
|
-
await notify(ctx, item, message, "delayed", settled.deferred, now);
|
|
1146
|
-
}
|
|
1182
|
+
for (const error of failures)
|
|
1183
|
+
events.emit("error", { error, id: item.id });
|
|
1184
|
+
await tellDsns(ctx, item, pending, completed);
|
|
1147
1185
|
}
|
|
1148
1186
|
|
|
1149
1187
|
// src/queue/lease.ts
|
|
@@ -1438,5 +1476,5 @@ export {
|
|
|
1438
1476
|
failedDsn
|
|
1439
1477
|
};
|
|
1440
1478
|
|
|
1441
|
-
//# debugId=
|
|
1479
|
+
//# debugId=9190A6EB36D3FC0664756E2164756E21
|
|
1442
1480
|
//# sourceMappingURL=index.js.map
|