@molecule/api-queue-memory 1.0.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/LICENSE ADDED
@@ -0,0 +1,115 @@
1
+ Apache License
2
+ Version 2.0, January 2004
3
+ http://www.apache.org/licenses/
4
+
5
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6
+
7
+ 1. Definitions.
8
+
9
+ "License" shall mean the terms and conditions for use, reproduction,
10
+ and distribution as defined by Sections 1 through 9 of this document.
11
+
12
+ "Licensor" shall mean the copyright owner or entity authorized by
13
+ the copyright owner that is granting the License.
14
+
15
+ "Legal Entity" shall mean the union of the acting entity and all
16
+ other entities that control, are controlled by, or are under common
17
+ control with that entity. For the purposes of this definition,
18
+ "control" means (i) the power, direct or indirect, to cause the
19
+ direction or management of such entity, whether by contract or
20
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
21
+ outstanding shares, or (iii) beneficial ownership of such entity.
22
+
23
+ "You" (or "Your") shall mean an individual or Legal Entity
24
+ exercising permissions granted by this License.
25
+
26
+ "Source" form shall mean the preferred form for making modifications,
27
+ including but not limited to software source code, documentation
28
+ source, and configuration files.
29
+
30
+ "Object" form shall mean any form resulting from mechanical
31
+ transformation or translation of a Source form, including but
32
+ not limited to compiled object code, generated documentation,
33
+ and conversions to other media types.
34
+
35
+ "Work" shall mean the work of authorship, whether in Source or
36
+ Object form, made available under the License, as indicated by a
37
+ copyright notice that is included in or attached to the work.
38
+
39
+ "Derivative Works" shall mean any work, whether in Source or Object
40
+ form, that is based on (or derived from) the Work and for which the
41
+ editorial revisions, annotations, elaborations, or other modifications
42
+ represent, as a whole, an original work of authorship.
43
+
44
+ "Contribution" shall mean any work of authorship, including the
45
+ original version of the Work and any modifications or additions
46
+ to that Work, that is intentionally submitted to the Licensor for
47
+ inclusion in the Work by the copyright owner or by an individual or
48
+ Legal Entity authorized to submit on behalf of the copyright owner.
49
+
50
+ "Contributor" shall mean Licensor and any individual or Legal Entity
51
+ on behalf of whom a Contribution has been received by the Licensor and
52
+ subsequently incorporated within the Work.
53
+
54
+ 2. Grant of Copyright License. Subject to the terms and conditions of
55
+ this License, each Contributor hereby grants to You a perpetual,
56
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
57
+ copyright license to reproduce, prepare Derivative Works of,
58
+ publicly display, publicly perform, sublicense, and distribute the
59
+ Work and such Derivative Works in Source or Object form.
60
+
61
+ 3. Grant of Patent License. Subject to the terms and conditions of
62
+ this License, each Contributor hereby grants to You a perpetual,
63
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
64
+ patent license to make, have made, use, offer to sell, sell, import,
65
+ and otherwise transfer the Work.
66
+
67
+ 4. Redistribution. You may reproduce and distribute copies of the
68
+ Work or Derivative Works thereof in any medium, with or without
69
+ modifications, and in Source or Object form, provided that You
70
+ meet the following conditions:
71
+
72
+ (a) You must give any other recipients of the Work or
73
+ Derivative Works a copy of this License; and
74
+
75
+ (b) You must cause any modified files to carry prominent notices
76
+ stating that You changed the files; and
77
+
78
+ (c) You must retain, in the Source form of any Derivative Works
79
+ that You distribute, all copyright, patent, trademark, and
80
+ attribution notices from the Source form of the Work,
81
+ excluding those notices that do not pertain to any part of
82
+ the Derivative Works; and
83
+
84
+ (d) If the Work includes a "NOTICE" text file as part of its
85
+ distribution, then any Derivative Works that You distribute must
86
+ include a readable copy of the attribution notices contained
87
+ within such NOTICE file.
88
+
89
+ 5. Submission of Contributions.
90
+
91
+ 6. Trademarks. This License does not grant permission to use the trade
92
+ names, trademarks, service marks, or product names of the Licensor.
93
+
94
+ 7. Disclaimer of Warranty. Unless required by applicable law or
95
+ agreed to in writing, Licensor provides the Work on an "AS IS" BASIS,
96
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND.
97
+
98
+ 8. Limitation of Liability. In no event and under no legal theory shall
99
+ any Contributor be liable to You for damages.
100
+
101
+ 9. Accepting Warranty or Additional Liability.
102
+
103
+ Copyright 2026 Molecule Dev, Inc.
104
+
105
+ Licensed under the Apache License, Version 2.0 (the "License");
106
+ you may not use this file except in compliance with the License.
107
+ You may obtain a copy of the License at
108
+
109
+ http://www.apache.org/licenses/LICENSE-2.0
110
+
111
+ Unless required by applicable law or agreed to in writing, software
112
+ distributed under the License is distributed on an "AS IS" BASIS,
113
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
114
+ See the License for the specific language governing permissions and
115
+ limitations under the License.
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=browser-guard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser-guard.d.ts","sourceRoot":"","sources":["../src/browser-guard.ts"],"names":[],"mappings":"AAuBA,OAAO,EAAE,CAAA"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Browser guard — `@molecule/api-queue-memory` is SERVER-ONLY.
3
+ *
4
+ * Generated by scripts/gen-browser-guards.mjs (workspace root) — edit THAT, not this.
5
+ * Evaluating a server package in a browser bundle is always an import-graph mistake
6
+ * (node APIs, secrets); without this guard it surfaces as a cryptic downstream crash
7
+ * ("Buffer is not defined") far from the culprit. Throwing here names the package and
8
+ * the fix at the exact moment the client bundle evaluates it. jsdom tests and SSR are
9
+ * unaffected: the throw requires browser globals AND the absence of a node runtime.
10
+ */
11
+ const g = globalThis;
12
+ if (g.window !== undefined && g.document !== undefined && !g.process?.versions?.node) {
13
+ throw new Error('@molecule/api-queue-memory is SERVER-ONLY: it was bundled into browser/client code. Import it only ' +
14
+ 'from server code (a server route/function or your API), or dynamic-import it inside ' +
15
+ 'the server handler — never from components or shared client modules, and never ' +
16
+ 'polyfill Buffer/process to silence this.');
17
+ }
18
+ export {};
19
+ //# sourceMappingURL=browser-guard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser-guard.js","sourceRoot":"","sources":["../src/browser-guard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,MAAM,CAAC,GAAG,UAIT,CAAA;AACD,IAAI,CAAC,CAAC,MAAM,KAAK,SAAS,IAAI,CAAC,CAAC,QAAQ,KAAK,SAAS,IAAI,CAAC,CAAC,CAAC,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IACrF,MAAM,IAAI,KAAK,CACb,qGAAqG;QACnG,sFAAsF;QACtF,iFAAiF;QACjF,0CAA0C,CAC7C,CAAA;AACH,CAAC"}
@@ -0,0 +1,61 @@
1
+ /**
2
+ * In-memory queue provider for molecule.dev.
3
+ *
4
+ * A zero-dependency, zero-configuration, in-process queue provider for
5
+ * development and testing — no broker, no credentials, no environment
6
+ * variables. Implements the full `@molecule/api-queue` contract with
7
+ * SQS-style semantics: named queues, at-least-once delivery via visibility
8
+ * leases, delayed messages (`delaySeconds`), redelivery on subscriber
9
+ * handler failure or `nack()`, a bounded delivery cap with optional
10
+ * dead-letter routing, FIFO group ordering + deduplication, long-polling
11
+ * `receive()`, and `maxMessages`-bounded subscriber concurrency.
12
+ *
13
+ * @example
14
+ * ```typescript
15
+ * import { setProvider, queue } from '@molecule/api-queue'
16
+ * import { provider } from '@molecule/api-queue-memory'
17
+ *
18
+ * setProvider(provider) // no configuration, no env vars
19
+ *
20
+ * const emails = queue('emails')
21
+ * const unsubscribe = emails.subscribe(async (message) => {
22
+ * await deliver(message.body)
23
+ * await message.ack() // handler success also auto-acks
24
+ * })
25
+ *
26
+ * await emails.send({ body: { to: 'a@b.c' } })
27
+ * await emails.send({ body: { to: 'later@b.c' }, delaySeconds: 60 })
28
+ * ```
29
+ *
30
+ * @remarks
31
+ * Single-process and DEV-ONLY. Messages live in this process's memory: there
32
+ * is NO persistence (everything is lost on restart) and NO cross-instance
33
+ * delivery, so it must not be used for multi-instance production — swap in
34
+ * `@molecule/api-queue-redis`, `@molecule/api-queue-rabbitmq`, or
35
+ * `@molecule/api-queue-sqs` for production workloads. Delivery is
36
+ * at-least-once: a message whose visibility lease expires without `ack()` is
37
+ * redelivered (with an incremented `receiveCount`), and a message delivered
38
+ * more than `maxReceiveCount` times (default 3) is routed to the queue's
39
+ * dead-letter queue when one was configured via `createQueue()` — otherwise
40
+ * it is dropped with an error log. Message bodies are `structuredClone`d on
41
+ * send and per delivery (like a real broker's serialization), so bodies must
42
+ * be structured-cloneable and post-send mutations never leak to consumers.
43
+ * `QueueCreateOptions.maxMessageSize` is not enforced (nothing is
44
+ * serialized). `close()` clears all timers, resolves pending long-polls with
45
+ * `[]`, and stops all delivery.
46
+ *
47
+ * Two distinct redelivery delays (both `MemoryQueueOptions`, provider-wide):
48
+ * an explicit `nack()` redelivers per `redeliveryDelaySeconds` (default `0`
49
+ * — a deliberate caller decision, honored immediately), while an UNCAUGHT
50
+ * `subscribe()` handler throw redelivers per
51
+ * `handlerFailureRedeliveryDelaySeconds` (default `1` — an unplanned failure
52
+ * gets a real retry window instead of burning all `maxReceiveCount` attempts
53
+ * within milliseconds, mirroring the Redis bond's `attempts: 3, backoff:
54
+ * { type: 'exponential', delay: 1000 }`).
55
+ *
56
+ * @module
57
+ */
58
+ export * from './browser-guard.js';
59
+ export * from './provider.js';
60
+ export * from './types.js';
61
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwDG;AAEH,cAAc,oBAAoB,CAAA;AAClC,cAAc,eAAe,CAAA;AAC7B,cAAc,YAAY,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,61 @@
1
+ /**
2
+ * In-memory queue provider for molecule.dev.
3
+ *
4
+ * A zero-dependency, zero-configuration, in-process queue provider for
5
+ * development and testing — no broker, no credentials, no environment
6
+ * variables. Implements the full `@molecule/api-queue` contract with
7
+ * SQS-style semantics: named queues, at-least-once delivery via visibility
8
+ * leases, delayed messages (`delaySeconds`), redelivery on subscriber
9
+ * handler failure or `nack()`, a bounded delivery cap with optional
10
+ * dead-letter routing, FIFO group ordering + deduplication, long-polling
11
+ * `receive()`, and `maxMessages`-bounded subscriber concurrency.
12
+ *
13
+ * @example
14
+ * ```typescript
15
+ * import { setProvider, queue } from '@molecule/api-queue'
16
+ * import { provider } from '@molecule/api-queue-memory'
17
+ *
18
+ * setProvider(provider) // no configuration, no env vars
19
+ *
20
+ * const emails = queue('emails')
21
+ * const unsubscribe = emails.subscribe(async (message) => {
22
+ * await deliver(message.body)
23
+ * await message.ack() // handler success also auto-acks
24
+ * })
25
+ *
26
+ * await emails.send({ body: { to: 'a@b.c' } })
27
+ * await emails.send({ body: { to: 'later@b.c' }, delaySeconds: 60 })
28
+ * ```
29
+ *
30
+ * @remarks
31
+ * Single-process and DEV-ONLY. Messages live in this process's memory: there
32
+ * is NO persistence (everything is lost on restart) and NO cross-instance
33
+ * delivery, so it must not be used for multi-instance production — swap in
34
+ * `@molecule/api-queue-redis`, `@molecule/api-queue-rabbitmq`, or
35
+ * `@molecule/api-queue-sqs` for production workloads. Delivery is
36
+ * at-least-once: a message whose visibility lease expires without `ack()` is
37
+ * redelivered (with an incremented `receiveCount`), and a message delivered
38
+ * more than `maxReceiveCount` times (default 3) is routed to the queue's
39
+ * dead-letter queue when one was configured via `createQueue()` — otherwise
40
+ * it is dropped with an error log. Message bodies are `structuredClone`d on
41
+ * send and per delivery (like a real broker's serialization), so bodies must
42
+ * be structured-cloneable and post-send mutations never leak to consumers.
43
+ * `QueueCreateOptions.maxMessageSize` is not enforced (nothing is
44
+ * serialized). `close()` clears all timers, resolves pending long-polls with
45
+ * `[]`, and stops all delivery.
46
+ *
47
+ * Two distinct redelivery delays (both `MemoryQueueOptions`, provider-wide):
48
+ * an explicit `nack()` redelivers per `redeliveryDelaySeconds` (default `0`
49
+ * — a deliberate caller decision, honored immediately), while an UNCAUGHT
50
+ * `subscribe()` handler throw redelivers per
51
+ * `handlerFailureRedeliveryDelaySeconds` (default `1` — an unplanned failure
52
+ * gets a real retry window instead of burning all `maxReceiveCount` attempts
53
+ * within milliseconds, mirroring the Redis bond's `attempts: 3, backoff:
54
+ * { type: 'exponential', delay: 1000 }`).
55
+ *
56
+ * @module
57
+ */
58
+ export * from './browser-guard.js';
59
+ export * from './provider.js';
60
+ export * from './types.js';
61
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwDG;AAEH,cAAc,oBAAoB,CAAA;AAClC,cAAc,eAAe,CAAA;AAC7B,cAAc,YAAY,CAAA"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * In-memory queue provider implementation.
3
+ *
4
+ * A zero-dependency, zero-configuration queue provider for development and
5
+ * testing. No broker process, no credentials, no environment variables.
6
+ *
7
+ * @module
8
+ */
9
+ import type { QueueProvider } from '@molecule/api-queue';
10
+ import type { MemoryQueueOptions } from './types.js';
11
+ /**
12
+ * Creates an in-memory queue provider. Queues are created implicitly on first
13
+ * access (like the Redis bond) or explicitly via `createQueue()` with FIFO,
14
+ * visibility-timeout, retention, and dead-letter options. All state lives in
15
+ * this process and is lost on restart.
16
+ *
17
+ * @param options - Optional delivery defaults (visibility timeout, delivery cap, nack redelivery delay, handler-failure redelivery delay). Everything defaults sensibly — no configuration is required.
18
+ * @returns A `QueueProvider` backed by in-process queues.
19
+ */
20
+ export declare const createProvider: (options?: MemoryQueueOptions) => QueueProvider;
21
+ /**
22
+ * Lazily-initialized in-memory queue provider proxy that creates the provider on first access.
23
+ */
24
+ export declare const provider: QueueProvider;
25
+ //# sourceMappingURL=provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../src/provider.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAA6B,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAGnF,OAAO,KAAK,EAAqB,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAEvE;;;;;;;;GAQG;AACH,eAAO,MAAM,cAAc,GAAI,UAAU,kBAAkB,KAAG,aA2D7D,CAAA;AAKD;;GAEG;AACH,eAAO,MAAM,QAAQ,EAAE,aAUrB,CAAA"}
@@ -0,0 +1,88 @@
1
+ /**
2
+ * In-memory queue provider implementation.
3
+ *
4
+ * A zero-dependency, zero-configuration queue provider for development and
5
+ * testing. No broker process, no credentials, no environment variables.
6
+ *
7
+ * @module
8
+ */
9
+ import { createQueue } from './queue.js';
10
+ /**
11
+ * Creates an in-memory queue provider. Queues are created implicitly on first
12
+ * access (like the Redis bond) or explicitly via `createQueue()` with FIFO,
13
+ * visibility-timeout, retention, and dead-letter options. All state lives in
14
+ * this process and is lost on restart.
15
+ *
16
+ * @param options - Optional delivery defaults (visibility timeout, delivery cap, nack redelivery delay, handler-failure redelivery delay). Everything defaults sensibly — no configuration is required.
17
+ * @returns A `QueueProvider` backed by in-process queues.
18
+ */
19
+ export const createProvider = (options) => {
20
+ const visibilityTimeoutSeconds = options?.visibilityTimeoutSeconds ?? 30;
21
+ const maxReceiveCount = options?.maxReceiveCount ?? 3;
22
+ const redeliveryDelaySeconds = options?.redeliveryDelaySeconds ?? 0;
23
+ const handlerFailureRedeliveryDelaySeconds = options?.handlerFailureRedeliveryDelaySeconds ?? 1;
24
+ const handles = new Map();
25
+ const getOrCreateQueue = (name, createOptions) => {
26
+ let handle = handles.get(name);
27
+ if (!handle) {
28
+ handle = createQueue(name, {
29
+ defaultVisibilityTimeoutSeconds: createOptions?.visibilityTimeout ?? visibilityTimeoutSeconds,
30
+ maxReceiveCount,
31
+ redeliveryDelaySeconds,
32
+ handlerFailureRedeliveryDelaySeconds,
33
+ fifo: createOptions?.fifo ?? false,
34
+ messageRetentionSeconds: createOptions?.messageRetentionSeconds,
35
+ deadLetterQueue: createOptions?.deadLetterQueue,
36
+ resolveQueue: (dlqName) => getOrCreateQueue(dlqName),
37
+ });
38
+ handles.set(name, handle);
39
+ }
40
+ return handle.queue;
41
+ };
42
+ const provider = {
43
+ queue(name) {
44
+ return getOrCreateQueue(name);
45
+ },
46
+ async listQueues() {
47
+ return Array.from(handles.keys());
48
+ },
49
+ async createQueue(name, createOptions) {
50
+ // Like the Redis bond: returns the existing queue when already created
51
+ // (creation options only apply to a queue's first creation).
52
+ return getOrCreateQueue(name, createOptions);
53
+ },
54
+ async deleteQueue(name) {
55
+ const handle = handles.get(name);
56
+ if (handle) {
57
+ handle.close();
58
+ handles.delete(name);
59
+ }
60
+ },
61
+ async close() {
62
+ for (const handle of handles.values()) {
63
+ handle.close();
64
+ }
65
+ handles.clear();
66
+ },
67
+ };
68
+ return provider;
69
+ };
70
+ /** Lazily-initialized in-memory queue provider, created on first property access via a Proxy. */
71
+ let _provider = null;
72
+ /**
73
+ * Lazily-initialized in-memory queue provider proxy that creates the provider on first access.
74
+ */
75
+ export const provider = new Proxy({}, {
76
+ get(_, prop, receiver) {
77
+ if (!_provider)
78
+ _provider = createProvider();
79
+ return Reflect.get(_provider, prop, receiver);
80
+ },
81
+ // set trap: methods run with `this` bound to the proxy — without it, instance-state writes land on the dummy target and are lost (see api-push-notifications-web-push)
82
+ set(_, prop, value) {
83
+ if (!_provider)
84
+ _provider = createProvider();
85
+ return Reflect.set(_provider, prop, value);
86
+ },
87
+ });
88
+ //# sourceMappingURL=provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.js","sourceRoot":"","sources":["../src/provider.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * In-memory queue implementation.
3
+ *
4
+ * SQS-style visibility-lease semantics over an in-process message list:
5
+ * messages are leased (invisible) on delivery and return to the queue when
6
+ * the lease expires without an `ack()`, giving at-least-once delivery with
7
+ * redelivery on subscriber handler failure. A single lazily-armed
8
+ * `setTimeout` per queue drives delayed visibility and lease reclaim; it is
9
+ * tracked, `unref()`d, and cleared on `close()` so nothing leaks.
10
+ *
11
+ * @module
12
+ */
13
+ import type { MemoryQueueConfig, MemoryQueueHandle } from './types.js';
14
+ /**
15
+ * Creates an in-memory `Queue` with SQS-style visibility-lease delivery:
16
+ * send/sendBatch (with `delaySeconds` and FIFO group/dedup support), pull
17
+ * `receive()` (with long polling via `waitTimeSeconds`), push `subscribe()`
18
+ * (with `maxMessages`-bounded concurrency, auto-ack on handler success, and
19
+ * redelivery on handler failure), `size()`, and `purge()`. Messages
20
+ * exceeding the delivery cap are routed to the configured dead-letter queue
21
+ * or dropped with an error log.
22
+ *
23
+ * @param queueName - The queue name.
24
+ * @param config - Resolved queue configuration (defaults, FIFO mode, DLQ, queue resolver).
25
+ * @returns A handle with the `Queue` and an internal `close()` for the provider.
26
+ */
27
+ export declare const createQueue: (queueName: string, config: MemoryQueueConfig) => MemoryQueueHandle;
28
+ //# sourceMappingURL=queue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queue.d.ts","sourceRoot":"","sources":["../src/queue.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAWH,OAAO,KAAK,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AA8DtE;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,WAAW,GAAI,WAAW,MAAM,EAAE,QAAQ,iBAAiB,KAAG,iBAsW1E,CAAA"}
package/dist/queue.js ADDED
@@ -0,0 +1,369 @@
1
+ /**
2
+ * In-memory queue implementation.
3
+ *
4
+ * SQS-style visibility-lease semantics over an in-process message list:
5
+ * messages are leased (invisible) on delivery and return to the queue when
6
+ * the lease expires without an `ack()`, giving at-least-once delivery with
7
+ * redelivery on subscriber handler failure. A single lazily-armed
8
+ * `setTimeout` per queue drives delayed visibility and lease reclaim; it is
9
+ * tracked, `unref()`d, and cleared on `close()` so nothing leaks.
10
+ *
11
+ * @module
12
+ */
13
+ import { getLogger } from '@molecule/api-bond';
14
+ const logger = getLogger();
15
+ /**
16
+ * How long (ms) a FIFO `deduplicationId` suppresses duplicate sends —
17
+ * mirrors SQS's 5-minute deduplication window.
18
+ */
19
+ const DEDUP_WINDOW_MS = 5 * 60_000;
20
+ /**
21
+ * Creates an in-memory `Queue` with SQS-style visibility-lease delivery:
22
+ * send/sendBatch (with `delaySeconds` and FIFO group/dedup support), pull
23
+ * `receive()` (with long polling via `waitTimeSeconds`), push `subscribe()`
24
+ * (with `maxMessages`-bounded concurrency, auto-ack on handler success, and
25
+ * redelivery on handler failure), `size()`, and `purge()`. Messages
26
+ * exceeding the delivery cap are routed to the configured dead-letter queue
27
+ * or dropped with an error log.
28
+ *
29
+ * @param queueName - The queue name.
30
+ * @param config - Resolved queue configuration (defaults, FIFO mode, DLQ, queue resolver).
31
+ * @returns A handle with the `Queue` and an internal `close()` for the provider.
32
+ */
33
+ export const createQueue = (queueName, config) => {
34
+ const messages = [];
35
+ const subscribers = new Map();
36
+ const waiters = new Set();
37
+ const dedupIds = new Map();
38
+ let wakeTimer = null;
39
+ let closed = false;
40
+ const maxReceiveCount = () => config.deadLetterQueue?.maxReceiveCount ?? config.maxReceiveCount;
41
+ const isStored = (message) => messages.includes(message);
42
+ const removeMessage = (message) => {
43
+ const index = messages.indexOf(message);
44
+ if (index !== -1)
45
+ messages.splice(index, 1);
46
+ };
47
+ const pruneDedup = (now) => {
48
+ for (const [key, entry] of dedupIds) {
49
+ if (entry.expiresAt <= now)
50
+ dedupIds.delete(key);
51
+ }
52
+ };
53
+ /**
54
+ * Routes a delivery-cap-exceeded message to the dead-letter queue when one
55
+ * is configured (and isn't this queue itself), otherwise drops it loudly.
56
+ */
57
+ const deadLetter = (message) => {
58
+ removeMessage(message);
59
+ const dlqName = config.deadLetterQueue?.name;
60
+ if (dlqName && dlqName !== queueName) {
61
+ logger.warn(`Memory queue "${queueName}": message ${message.id} exceeded ${maxReceiveCount()} deliveries — routing to dead-letter queue "${dlqName}"`);
62
+ config
63
+ .resolveQueue(dlqName)
64
+ .send({
65
+ id: message.id,
66
+ body: message.body,
67
+ attributes: message.attributes,
68
+ groupId: message.groupId,
69
+ })
70
+ .catch((error) => {
71
+ logger.error(`Memory queue "${queueName}": failed to dead-letter message ${message.id} to "${dlqName}"`, error);
72
+ });
73
+ }
74
+ else {
75
+ logger.error(`Memory queue "${queueName}": message ${message.id} exceeded ${maxReceiveCount()} deliveries and no dead-letter queue is configured — message dropped`);
76
+ }
77
+ };
78
+ /**
79
+ * Collects and leases up to `max` deliverable messages, applying delayed
80
+ * visibility, retention expiry, FIFO group head-of-line blocking, and the
81
+ * dead-letter delivery cap. Mutates lease state (at-least-once bookkeeping).
82
+ */
83
+ const leaseMessages = (max, visibilityTimeoutMs) => {
84
+ if (max <= 0)
85
+ return [];
86
+ const now = Date.now();
87
+ const leased = [];
88
+ const blockedGroups = new Set();
89
+ if (config.fifo) {
90
+ for (const message of messages) {
91
+ if (message.leaseExpiresAt !== null && message.leaseExpiresAt > now) {
92
+ blockedGroups.add(message.groupId ?? '');
93
+ }
94
+ }
95
+ }
96
+ // Iterate a copy — retention expiry and dead-lettering splice the array.
97
+ for (const message of [...messages]) {
98
+ if (leased.length >= max)
99
+ break;
100
+ if (message.leaseExpiresAt !== null && message.leaseExpiresAt > now)
101
+ continue;
102
+ if (config.messageRetentionSeconds !== undefined &&
103
+ message.sentAt.getTime() + config.messageRetentionSeconds * 1000 <= now) {
104
+ removeMessage(message);
105
+ logger.debug(`Memory queue "${queueName}": message ${message.id} exceeded retention (${config.messageRetentionSeconds}s) — discarded`);
106
+ continue;
107
+ }
108
+ if (config.fifo) {
109
+ const group = message.groupId ?? '';
110
+ if (blockedGroups.has(group))
111
+ continue;
112
+ // Head-of-line: later messages in this group must not overtake this
113
+ // one, whether it's delivered now, still delayed, or dead-lettered.
114
+ blockedGroups.add(group);
115
+ }
116
+ if (message.visibleAt > now)
117
+ continue;
118
+ if (message.receiveCount >= maxReceiveCount()) {
119
+ deadLetter(message);
120
+ continue;
121
+ }
122
+ message.leaseExpiresAt = now + visibilityTimeoutMs;
123
+ message.receiveCount += 1;
124
+ message.receiptHandle = crypto.randomUUID();
125
+ leased.push(message);
126
+ }
127
+ return leased;
128
+ };
129
+ /**
130
+ * Wraps a leased message for the consumer. `ack()`/`nack()` only act while
131
+ * this delivery's receipt handle is still current — once the lease expires
132
+ * and the message is redelivered, stale receipts become documented no-ops
133
+ * (making `ack()` idempotent and late acks after redelivery harmless).
134
+ */
135
+ const toReceivedMessage = (message) => {
136
+ const receipt = message.receiptHandle;
137
+ return {
138
+ id: message.id,
139
+ body: structuredClone(message.body),
140
+ receiptHandle: receipt,
141
+ attributes: message.attributes ? { ...message.attributes } : undefined,
142
+ receiveCount: message.receiveCount,
143
+ sentTimestamp: message.sentAt,
144
+ async ack() {
145
+ if (message.receiptHandle === receipt && isStored(message)) {
146
+ removeMessage(message);
147
+ pump();
148
+ }
149
+ },
150
+ async nack() {
151
+ if (message.receiptHandle === receipt && isStored(message)) {
152
+ message.leaseExpiresAt = null;
153
+ message.visibleAt = Date.now() + config.redeliveryDelaySeconds * 1000;
154
+ pump();
155
+ }
156
+ },
157
+ };
158
+ };
159
+ /**
160
+ * Leases a message to a subscriber and runs its handler. Handler success
161
+ * auto-acks (a no-op if the handler already acked or the lease rotated);
162
+ * handler failure logs and returns the message for redelivery.
163
+ */
164
+ const dispatch = (subscriber, message) => {
165
+ const received = toReceivedMessage(message);
166
+ const receipt = message.receiptHandle;
167
+ void (async () => {
168
+ try {
169
+ await subscriber.handler(received);
170
+ if (message.receiptHandle === receipt && isStored(message)) {
171
+ removeMessage(message);
172
+ }
173
+ }
174
+ catch (error) {
175
+ logger.warn(`Memory queue "${queueName}": subscriber handler failed for message ${message.id} — scheduling redelivery in ${config.handlerFailureRedeliveryDelaySeconds}s`, error);
176
+ if (message.receiptHandle === receipt && isStored(message)) {
177
+ message.leaseExpiresAt = null;
178
+ // An uncaught throw is an UNPLANNED failure (e.g. a transient
179
+ // downstream 503) — give it a real retry window instead of the
180
+ // instant redelivery an explicit nack() gets. With the default
181
+ // maxReceiveCount of 3, a 0-delay default here would burn every
182
+ // attempt within milliseconds and drop the message with no real
183
+ // chance to recover.
184
+ message.visibleAt = Date.now() + config.handlerFailureRedeliveryDelaySeconds * 1000;
185
+ }
186
+ }
187
+ finally {
188
+ subscriber.active -= 1;
189
+ pump();
190
+ }
191
+ })();
192
+ };
193
+ /**
194
+ * Arms the single wake timer for the earliest future event (delayed
195
+ * visibility or lease expiry) — only while someone (subscriber or long-poll
196
+ * waiter) is waiting for delivery; a fully idle queue holds no timer.
197
+ */
198
+ const scheduleNextWake = () => {
199
+ if (wakeTimer) {
200
+ clearTimeout(wakeTimer);
201
+ wakeTimer = null;
202
+ }
203
+ if (closed)
204
+ return;
205
+ if (subscribers.size === 0 && waiters.size === 0)
206
+ return;
207
+ const now = Date.now();
208
+ let next = Infinity;
209
+ for (const message of messages) {
210
+ if (message.leaseExpiresAt !== null && message.leaseExpiresAt > now) {
211
+ next = Math.min(next, message.leaseExpiresAt);
212
+ }
213
+ else if (message.visibleAt > now) {
214
+ next = Math.min(next, message.visibleAt);
215
+ }
216
+ }
217
+ if (!Number.isFinite(next))
218
+ return;
219
+ wakeTimer = setTimeout(() => {
220
+ wakeTimer = null;
221
+ pump();
222
+ }, Math.max(1, next - now));
223
+ wakeTimer.unref?.();
224
+ };
225
+ /**
226
+ * Delivery engine: dispatches deliverable messages to subscribers with free
227
+ * capacity, satisfies pending long-poll waiters, then re-arms the wake
228
+ * timer. Called after every state change.
229
+ */
230
+ const pump = () => {
231
+ if (closed)
232
+ return;
233
+ for (const subscriber of subscribers.values()) {
234
+ while (subscriber.active < subscriber.concurrency) {
235
+ const [message] = leaseMessages(1, subscriber.visibilityTimeoutMs);
236
+ if (!message)
237
+ break;
238
+ subscriber.active += 1;
239
+ dispatch(subscriber, message);
240
+ }
241
+ }
242
+ for (const waiter of [...waiters]) {
243
+ const leased = leaseMessages(waiter.maxMessages, waiter.visibilityTimeoutMs);
244
+ if (leased.length > 0) {
245
+ waiters.delete(waiter);
246
+ clearTimeout(waiter.timer);
247
+ waiter.resolve(leased.map((message) => toReceivedMessage(message)));
248
+ }
249
+ }
250
+ scheduleNextWake();
251
+ };
252
+ const assertOpen = () => {
253
+ if (closed) {
254
+ throw new Error(`Memory queue "${queueName}" is closed`);
255
+ }
256
+ };
257
+ const queue = {
258
+ name: queueName,
259
+ async send(message) {
260
+ assertOpen();
261
+ const now = Date.now();
262
+ if (config.fifo && message.deduplicationId) {
263
+ pruneDedup(now);
264
+ const existing = dedupIds.get(message.deduplicationId);
265
+ if (existing)
266
+ return existing.id;
267
+ }
268
+ const id = message.id ?? crypto.randomUUID();
269
+ const stored = {
270
+ id,
271
+ // Clone like a real broker serializes — post-send mutations of the
272
+ // caller's object must not affect what consumers receive.
273
+ body: structuredClone(message.body),
274
+ attributes: message.attributes ? { ...message.attributes } : undefined,
275
+ groupId: message.groupId,
276
+ sentAt: new Date(now),
277
+ visibleAt: now + (message.delaySeconds ?? 0) * 1000,
278
+ leaseExpiresAt: null,
279
+ receiveCount: 0,
280
+ receiptHandle: '',
281
+ };
282
+ messages.push(stored);
283
+ if (config.fifo && message.deduplicationId) {
284
+ dedupIds.set(message.deduplicationId, { id, expiresAt: now + DEDUP_WINDOW_MS });
285
+ }
286
+ pump();
287
+ return id;
288
+ },
289
+ async sendBatch(batch) {
290
+ const ids = [];
291
+ for (const message of batch) {
292
+ ids.push(await this.send(message));
293
+ }
294
+ return ids;
295
+ },
296
+ async receive(options) {
297
+ if (closed)
298
+ return [];
299
+ const maxMessages = options?.maxMessages ?? 10;
300
+ const visibilityTimeoutMs = (options?.visibilityTimeout ?? config.defaultVisibilityTimeoutSeconds) * 1000;
301
+ const leased = leaseMessages(maxMessages, visibilityTimeoutMs);
302
+ if (leased.length > 0 || !options?.waitTimeSeconds) {
303
+ scheduleNextWake();
304
+ return leased.map((message) => toReceivedMessage(message));
305
+ }
306
+ // Long poll: resolve as soon as a message becomes available, or with
307
+ // `[]` when `waitTimeSeconds` elapses (or the queue closes).
308
+ const waitTimeMs = options.waitTimeSeconds * 1000;
309
+ return new Promise((resolve) => {
310
+ const waiter = {
311
+ maxMessages,
312
+ visibilityTimeoutMs,
313
+ resolve: resolve,
314
+ timer: setTimeout(() => {
315
+ waiters.delete(waiter);
316
+ resolve([]);
317
+ }, waitTimeMs),
318
+ };
319
+ waiter.timer.unref?.();
320
+ waiters.add(waiter);
321
+ scheduleNextWake();
322
+ });
323
+ },
324
+ subscribe(handler, options) {
325
+ assertOpen();
326
+ const subscriberId = crypto.randomUUID();
327
+ const subscriber = {
328
+ handler: handler,
329
+ concurrency: options?.maxMessages ?? 1,
330
+ visibilityTimeoutMs: (options?.visibilityTimeout ?? config.defaultVisibilityTimeoutSeconds) * 1000,
331
+ active: 0,
332
+ };
333
+ subscribers.set(subscriberId, subscriber);
334
+ pump();
335
+ return () => {
336
+ subscribers.delete(subscriberId);
337
+ scheduleNextWake();
338
+ };
339
+ },
340
+ async size() {
341
+ // Ready + delayed + in-flight, mirroring the Redis bond's
342
+ // waiting + active + delayed job counts.
343
+ return messages.length;
344
+ },
345
+ async purge() {
346
+ messages.length = 0;
347
+ scheduleNextWake();
348
+ },
349
+ };
350
+ const close = () => {
351
+ if (closed)
352
+ return;
353
+ closed = true;
354
+ if (wakeTimer) {
355
+ clearTimeout(wakeTimer);
356
+ wakeTimer = null;
357
+ }
358
+ for (const waiter of waiters) {
359
+ clearTimeout(waiter.timer);
360
+ waiter.resolve([]);
361
+ }
362
+ waiters.clear();
363
+ subscribers.clear();
364
+ messages.length = 0;
365
+ dedupIds.clear();
366
+ };
367
+ return { queue, close };
368
+ };
369
+ //# sourceMappingURL=queue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queue.js","sourceRoot":"","sources":["../src/queue.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAA;AAW9C,MAAM,MAAM,GAAG,SAAS,EAAE,CAAA;AAE1B;;;GAGG;AACH,MAAM,eAAe,GAAG,CAAC,GAAG,MAAM,CAAA;AAsDlC;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,SAAiB,EAAE,MAAyB,EAAqB,EAAE;IAC7F,MAAM,QAAQ,GAAoB,EAAE,CAAA;IACpC,MAAM,WAAW,GAAG,IAAI,GAAG,EAA2B,CAAA;IACtD,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAA;IACjC,MAAM,QAAQ,GAAG,IAAI,GAAG,EAA6C,CAAA;IACrE,IAAI,SAAS,GAAyC,IAAI,CAAA;IAC1D,IAAI,MAAM,GAAG,KAAK,CAAA;IAElB,MAAM,eAAe,GAAG,GAAW,EAAE,CACnC,MAAM,CAAC,eAAe,EAAE,eAAe,IAAI,MAAM,CAAC,eAAe,CAAA;IAEnE,MAAM,QAAQ,GAAG,CAAC,OAAsB,EAAW,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAA;IAEhF,MAAM,aAAa,GAAG,CAAC,OAAsB,EAAQ,EAAE;QACrD,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;QACvC,IAAI,KAAK,KAAK,CAAC,CAAC;YAAE,QAAQ,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAA;IAC7C,CAAC,CAAA;IAED,MAAM,UAAU,GAAG,CAAC,GAAW,EAAQ,EAAE;QACvC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,QAAQ,EAAE,CAAC;YACpC,IAAI,KAAK,CAAC,SAAS,IAAI,GAAG;gBAAE,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;QAClD,CAAC;IACH,CAAC,CAAA;IAED;;;OAGG;IACH,MAAM,UAAU,GAAG,CAAC,OAAsB,EAAQ,EAAE;QAClD,aAAa,CAAC,OAAO,CAAC,CAAA;QACtB,MAAM,OAAO,GAAG,MAAM,CAAC,eAAe,EAAE,IAAI,CAAA;QAC5C,IAAI,OAAO,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YACrC,MAAM,CAAC,IAAI,CACT,iBAAiB,SAAS,cAAc,OAAO,CAAC,EAAE,aAAa,eAAe,EAAE,+CAA+C,OAAO,GAAG,CAC1I,CAAA;YACD,MAAM;iBACH,YAAY,CAAC,OAAO,CAAC;iBACrB,IAAI,CAAC;gBACJ,EAAE,EAAE,OAAO,CAAC,EAAE;gBACd,IAAI,EAAE,OAAO,CAAC,IAAI;gBAClB,UAAU,EAAE,OAAO,CAAC,UAAU;gBAC9B,OAAO,EAAE,OAAO,CAAC,OAAO;aACzB,CAAC;iBACD,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;gBACf,MAAM,CAAC,KAAK,CACV,iBAAiB,SAAS,oCAAoC,OAAO,CAAC,EAAE,QAAQ,OAAO,GAAG,EAC1F,KAAK,CACN,CAAA;YACH,CAAC,CAAC,CAAA;QACN,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,KAAK,CACV,iBAAiB,SAAS,cAAc,OAAO,CAAC,EAAE,aAAa,eAAe,EAAE,sEAAsE,CACvJ,CAAA;QACH,CAAC;IACH,CAAC,CAAA;IAED;;;;OAIG;IACH,MAAM,aAAa,GAAG,CAAC,GAAW,EAAE,mBAA2B,EAAmB,EAAE;QAClF,IAAI,GAAG,IAAI,CAAC;YAAE,OAAO,EAAE,CAAA;QACvB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;QACtB,MAAM,MAAM,GAAoB,EAAE,CAAA;QAClC,MAAM,aAAa,GAAG,IAAI,GAAG,EAAU,CAAA;QACvC,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;YAChB,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;gBAC/B,IAAI,OAAO,CAAC,cAAc,KAAK,IAAI,IAAI,OAAO,CAAC,cAAc,GAAG,GAAG,EAAE,CAAC;oBACpE,aAAa,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,IAAI,EAAE,CAAC,CAAA;gBAC1C,CAAC;YACH,CAAC;QACH,CAAC;QACD,yEAAyE;QACzE,KAAK,MAAM,OAAO,IAAI,CAAC,GAAG,QAAQ,CAAC,EAAE,CAAC;YACpC,IAAI,MAAM,CAAC,MAAM,IAAI,GAAG;gBAAE,MAAK;YAC/B,IAAI,OAAO,CAAC,cAAc,KAAK,IAAI,IAAI,OAAO,CAAC,cAAc,GAAG,GAAG;gBAAE,SAAQ;YAC7E,IACE,MAAM,CAAC,uBAAuB,KAAK,SAAS;gBAC5C,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE,GAAG,MAAM,CAAC,uBAAuB,GAAG,IAAI,IAAI,GAAG,EACvE,CAAC;gBACD,aAAa,CAAC,OAAO,CAAC,CAAA;gBACtB,MAAM,CAAC,KAAK,CACV,iBAAiB,SAAS,cAAc,OAAO,CAAC,EAAE,wBAAwB,MAAM,CAAC,uBAAuB,gBAAgB,CACzH,CAAA;gBACD,SAAQ;YACV,CAAC;YACD,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;gBAChB,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,IAAI,EAAE,CAAA;gBACnC,IAAI,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC;oBAAE,SAAQ;gBACtC,oEAAoE;gBACpE,oEAAoE;gBACpE,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;YAC1B,CAAC;YACD,IAAI,OAAO,CAAC,SAAS,GAAG,GAAG;gBAAE,SAAQ;YACrC,IAAI,OAAO,CAAC,YAAY,IAAI,eAAe,EAAE,EAAE,CAAC;gBAC9C,UAAU,CAAC,OAAO,CAAC,CAAA;gBACnB,SAAQ;YACV,CAAC;YACD,OAAO,CAAC,cAAc,GAAG,GAAG,GAAG,mBAAmB,CAAA;YAClD,OAAO,CAAC,YAAY,IAAI,CAAC,CAAA;YACzB,OAAO,CAAC,aAAa,GAAG,MAAM,CAAC,UAAU,EAAE,CAAA;YAC3C,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;QACtB,CAAC;QACD,OAAO,MAAM,CAAA;IACf,CAAC,CAAA;IAED;;;;;OAKG;IACH,MAAM,iBAAiB,GAAG,CAAI,OAAsB,EAAsB,EAAE;QAC1E,MAAM,OAAO,GAAG,OAAO,CAAC,aAAa,CAAA;QACrC,OAAO;YACL,EAAE,EAAE,OAAO,CAAC,EAAE;YACd,IAAI,EAAE,eAAe,CAAC,OAAO,CAAC,IAAI,CAAM;YACxC,aAAa,EAAE,OAAO;YACtB,UAAU,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,SAAS;YACtE,YAAY,EAAE,OAAO,CAAC,YAAY;YAClC,aAAa,EAAE,OAAO,CAAC,MAAM;YAE7B,KAAK,CAAC,GAAG;gBACP,IAAI,OAAO,CAAC,aAAa,KAAK,OAAO,IAAI,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;oBAC3D,aAAa,CAAC,OAAO,CAAC,CAAA;oBACtB,IAAI,EAAE,CAAA;gBACR,CAAC;YACH,CAAC;YAED,KAAK,CAAC,IAAI;gBACR,IAAI,OAAO,CAAC,aAAa,KAAK,OAAO,IAAI,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;oBAC3D,OAAO,CAAC,cAAc,GAAG,IAAI,CAAA;oBAC7B,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,sBAAsB,GAAG,IAAI,CAAA;oBACrE,IAAI,EAAE,CAAA;gBACR,CAAC;YACH,CAAC;SACF,CAAA;IACH,CAAC,CAAA;IAED;;;;OAIG;IACH,MAAM,QAAQ,GAAG,CAAC,UAA2B,EAAE,OAAsB,EAAQ,EAAE;QAC7E,MAAM,QAAQ,GAAG,iBAAiB,CAAU,OAAO,CAAC,CAAA;QACpD,MAAM,OAAO,GAAG,OAAO,CAAC,aAAa,CAAA;QACrC,KAAK,CAAC,KAAK,IAAI,EAAE;YACf,IAAI,CAAC;gBACH,MAAM,UAAU,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAA;gBAClC,IAAI,OAAO,CAAC,aAAa,KAAK,OAAO,IAAI,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;oBAC3D,aAAa,CAAC,OAAO,CAAC,CAAA;gBACxB,CAAC;YACH,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,CAAC,IAAI,CACT,iBAAiB,SAAS,4CAA4C,OAAO,CAAC,EAAE,+BAA+B,MAAM,CAAC,oCAAoC,GAAG,EAC7J,KAAK,CACN,CAAA;gBACD,IAAI,OAAO,CAAC,aAAa,KAAK,OAAO,IAAI,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;oBAC3D,OAAO,CAAC,cAAc,GAAG,IAAI,CAAA;oBAC7B,8DAA8D;oBAC9D,+DAA+D;oBAC/D,+DAA+D;oBAC/D,gEAAgE;oBAChE,gEAAgE;oBAChE,qBAAqB;oBACrB,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,oCAAoC,GAAG,IAAI,CAAA;gBACrF,CAAC;YACH,CAAC;oBAAS,CAAC;gBACT,UAAU,CAAC,MAAM,IAAI,CAAC,CAAA;gBACtB,IAAI,EAAE,CAAA;YACR,CAAC;QACH,CAAC,CAAC,EAAE,CAAA;IACN,CAAC,CAAA;IAED;;;;OAIG;IACH,MAAM,gBAAgB,GAAG,GAAS,EAAE;QAClC,IAAI,SAAS,EAAE,CAAC;YACd,YAAY,CAAC,SAAS,CAAC,CAAA;YACvB,SAAS,GAAG,IAAI,CAAA;QAClB,CAAC;QACD,IAAI,MAAM;YAAE,OAAM;QAClB,IAAI,WAAW,CAAC,IAAI,KAAK,CAAC,IAAI,OAAO,CAAC,IAAI,KAAK,CAAC;YAAE,OAAM;QACxD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;QACtB,IAAI,IAAI,GAAG,QAAQ,CAAA;QACnB,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;YAC/B,IAAI,OAAO,CAAC,cAAc,KAAK,IAAI,IAAI,OAAO,CAAC,cAAc,GAAG,GAAG,EAAE,CAAC;gBACpE,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,cAAc,CAAC,CAAA;YAC/C,CAAC;iBAAM,IAAI,OAAO,CAAC,SAAS,GAAG,GAAG,EAAE,CAAC;gBACnC,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,SAAS,CAAC,CAAA;YAC1C,CAAC;QACH,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC;YAAE,OAAM;QAClC,SAAS,GAAG,UAAU,CACpB,GAAG,EAAE;YACH,SAAS,GAAG,IAAI,CAAA;YAChB,IAAI,EAAE,CAAA;QACR,CAAC,EACD,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,GAAG,GAAG,CAAC,CACxB,CAAA;QACD,SAAS,CAAC,KAAK,EAAE,EAAE,CAAA;IACrB,CAAC,CAAA;IAED;;;;OAIG;IACH,MAAM,IAAI,GAAG,GAAS,EAAE;QACtB,IAAI,MAAM;YAAE,OAAM;QAClB,KAAK,MAAM,UAAU,IAAI,WAAW,CAAC,MAAM,EAAE,EAAE,CAAC;YAC9C,OAAO,UAAU,CAAC,MAAM,GAAG,UAAU,CAAC,WAAW,EAAE,CAAC;gBAClD,MAAM,CAAC,OAAO,CAAC,GAAG,aAAa,CAAC,CAAC,EAAE,UAAU,CAAC,mBAAmB,CAAC,CAAA;gBAClE,IAAI,CAAC,OAAO;oBAAE,MAAK;gBACnB,UAAU,CAAC,MAAM,IAAI,CAAC,CAAA;gBACtB,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC,CAAA;YAC/B,CAAC;QACH,CAAC;QACD,KAAK,MAAM,MAAM,IAAI,CAAC,GAAG,OAAO,CAAC,EAAE,CAAC;YAClC,MAAM,MAAM,GAAG,aAAa,CAAC,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,mBAAmB,CAAC,CAAA;YAC5E,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACtB,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;gBACtB,YAAY,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;gBAC1B,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,iBAAiB,CAAU,OAAO,CAAC,CAAC,CAAC,CAAA;YAC9E,CAAC;QACH,CAAC;QACD,gBAAgB,EAAE,CAAA;IACpB,CAAC,CAAA;IAED,MAAM,UAAU,GAAG,GAAS,EAAE;QAC5B,IAAI,MAAM,EAAE,CAAC;YACX,MAAM,IAAI,KAAK,CAAC,iBAAiB,SAAS,aAAa,CAAC,CAAA;QAC1D,CAAC;IACH,CAAC,CAAA;IAED,MAAM,KAAK,GAAU;QACnB,IAAI,EAAE,SAAS;QAEf,KAAK,CAAC,IAAI,CAAc,OAAwB;YAC9C,UAAU,EAAE,CAAA;YACZ,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;YACtB,IAAI,MAAM,CAAC,IAAI,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC;gBAC3C,UAAU,CAAC,GAAG,CAAC,CAAA;gBACf,MAAM,QAAQ,GAAG,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,eAAe,CAAC,CAAA;gBACtD,IAAI,QAAQ;oBAAE,OAAO,QAAQ,CAAC,EAAE,CAAA;YAClC,CAAC;YACD,MAAM,EAAE,GAAG,OAAO,CAAC,EAAE,IAAI,MAAM,CAAC,UAAU,EAAE,CAAA;YAC5C,MAAM,MAAM,GAAkB;gBAC5B,EAAE;gBACF,mEAAmE;gBACnE,0DAA0D;gBAC1D,IAAI,EAAE,eAAe,CAAC,OAAO,CAAC,IAAI,CAAC;gBACnC,UAAU,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,SAAS;gBACtE,OAAO,EAAE,OAAO,CAAC,OAAO;gBACxB,MAAM,EAAE,IAAI,IAAI,CAAC,GAAG,CAAC;gBACrB,SAAS,EAAE,GAAG,GAAG,CAAC,OAAO,CAAC,YAAY,IAAI,CAAC,CAAC,GAAG,IAAI;gBACnD,cAAc,EAAE,IAAI;gBACpB,YAAY,EAAE,CAAC;gBACf,aAAa,EAAE,EAAE;aAClB,CAAA;YACD,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;YACrB,IAAI,MAAM,CAAC,IAAI,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC;gBAC3C,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,eAAe,EAAE,EAAE,EAAE,EAAE,SAAS,EAAE,GAAG,GAAG,eAAe,EAAE,CAAC,CAAA;YACjF,CAAC;YACD,IAAI,EAAE,CAAA;YACN,OAAO,EAAE,CAAA;QACX,CAAC;QAED,KAAK,CAAC,SAAS,CAAc,KAAwB;YACnD,MAAM,GAAG,GAAa,EAAE,CAAA;YACxB,KAAK,MAAM,OAAO,IAAI,KAAK,EAAE,CAAC;gBAC5B,GAAG,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAA;YACpC,CAAC;YACD,OAAO,GAAG,CAAA;QACZ,CAAC;QAED,KAAK,CAAC,OAAO,CAAc,OAAwB;YACjD,IAAI,MAAM;gBAAE,OAAO,EAAE,CAAA;YACrB,MAAM,WAAW,GAAG,OAAO,EAAE,WAAW,IAAI,EAAE,CAAA;YAC9C,MAAM,mBAAmB,GACvB,CAAC,OAAO,EAAE,iBAAiB,IAAI,MAAM,CAAC,+BAA+B,CAAC,GAAG,IAAI,CAAA;YAC/E,MAAM,MAAM,GAAG,aAAa,CAAC,WAAW,EAAE,mBAAmB,CAAC,CAAA;YAC9D,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,eAAe,EAAE,CAAC;gBACnD,gBAAgB,EAAE,CAAA;gBAClB,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,iBAAiB,CAAI,OAAO,CAAC,CAAC,CAAA;YAC/D,CAAC;YACD,qEAAqE;YACrE,6DAA6D;YAC7D,MAAM,UAAU,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAA;YACjD,OAAO,IAAI,OAAO,CAAuB,CAAC,OAAO,EAAE,EAAE;gBACnD,MAAM,MAAM,GAAW;oBACrB,WAAW;oBACX,mBAAmB;oBACnB,OAAO,EAAE,OAAyD;oBAClE,KAAK,EAAE,UAAU,CAAC,GAAG,EAAE;wBACrB,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;wBACtB,OAAO,CAAC,EAAE,CAAC,CAAA;oBACb,CAAC,EAAE,UAAU,CAAC;iBACf,CAAA;gBACD,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,EAAE,CAAA;gBACtB,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;gBACnB,gBAAgB,EAAE,CAAA;YACpB,CAAC,CAAC,CAAA;QACJ,CAAC;QAED,SAAS,CAAc,OAA0B,EAAE,OAAwB;YACzE,UAAU,EAAE,CAAA;YACZ,MAAM,YAAY,GAAG,MAAM,CAAC,UAAU,EAAE,CAAA;YACxC,MAAM,UAAU,GAAoB;gBAClC,OAAO,EAAE,OAAkC;gBAC3C,WAAW,EAAE,OAAO,EAAE,WAAW,IAAI,CAAC;gBACtC,mBAAmB,EACjB,CAAC,OAAO,EAAE,iBAAiB,IAAI,MAAM,CAAC,+BAA+B,CAAC,GAAG,IAAI;gBAC/E,MAAM,EAAE,CAAC;aACV,CAAA;YACD,WAAW,CAAC,GAAG,CAAC,YAAY,EAAE,UAAU,CAAC,CAAA;YACzC,IAAI,EAAE,CAAA;YACN,OAAO,GAAG,EAAE;gBACV,WAAW,CAAC,MAAM,CAAC,YAAY,CAAC,CAAA;gBAChC,gBAAgB,EAAE,CAAA;YACpB,CAAC,CAAA;QACH,CAAC;QAED,KAAK,CAAC,IAAI;YACR,0DAA0D;YAC1D,yCAAyC;YACzC,OAAO,QAAQ,CAAC,MAAM,CAAA;QACxB,CAAC;QAED,KAAK,CAAC,KAAK;YACT,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAA;YACnB,gBAAgB,EAAE,CAAA;QACpB,CAAC;KACF,CAAA;IAED,MAAM,KAAK,GAAG,GAAS,EAAE;QACvB,IAAI,MAAM;YAAE,OAAM;QAClB,MAAM,GAAG,IAAI,CAAA;QACb,IAAI,SAAS,EAAE,CAAC;YACd,YAAY,CAAC,SAAS,CAAC,CAAA;YACvB,SAAS,GAAG,IAAI,CAAA;QAClB,CAAC;QACD,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;YAC7B,YAAY,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;YAC1B,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;QACpB,CAAC;QACD,OAAO,CAAC,KAAK,EAAE,CAAA;QACf,WAAW,CAAC,KAAK,EAAE,CAAA;QACnB,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAA;QACnB,QAAQ,CAAC,KAAK,EAAE,CAAA;IAClB,CAAC,CAAA;IAED,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAA;AACzB,CAAC,CAAA"}
@@ -0,0 +1,109 @@
1
+ /**
2
+ * Type definitions for the in-memory queue provider.
3
+ *
4
+ * @module
5
+ */
6
+ import type { Queue, QueueCreateOptions } from '@molecule/api-queue';
7
+ export type { MessageHandler, Queue, QueueCreateOptions, QueueMessage, QueueProvider, ReceivedMessage, ReceiveOptions, } from '@molecule/api-queue';
8
+ /**
9
+ * Options for creating an in-memory queue provider.
10
+ *
11
+ * All options have working defaults — the provider is fully functional with
12
+ * zero configuration and zero environment variables.
13
+ */
14
+ export interface MemoryQueueOptions {
15
+ /**
16
+ * Default visibility timeout in seconds applied to received/dispatched
17
+ * messages when `ReceiveOptions.visibilityTimeout` is not given.
18
+ * A leased (in-flight) message whose lease expires without an `ack()`
19
+ * becomes visible again and is redelivered (at-least-once delivery).
20
+ * Defaults to `30`.
21
+ */
22
+ visibilityTimeoutSeconds?: number;
23
+ /**
24
+ * Maximum number of times a message may be delivered before it is routed
25
+ * to the queue's dead-letter queue (when configured via
26
+ * `QueueCreateOptions.deadLetterQueue`) or dropped with an error log.
27
+ * Mirrors the Redis bond's `attempts: 3`. Defaults to `3`.
28
+ */
29
+ maxReceiveCount?: number;
30
+ /**
31
+ * Delay in seconds before a message is redelivered after an explicit
32
+ * `nack()` (a pull `receive()` consumer's deliberate "put this back now").
33
+ * Defaults to `0` (immediate redelivery) — an explicit `nack()` is a
34
+ * caller decision that should be honored right away, not throttled.
35
+ */
36
+ redeliveryDelaySeconds?: number;
37
+ /**
38
+ * Delay in seconds before a message is redelivered after an UNCAUGHT
39
+ * `subscribe()` handler failure (a thrown error) — distinct from
40
+ * `redeliveryDelaySeconds` because a throw is an unplanned failure (e.g. a
41
+ * downstream 503) that deserves a real retry window, mirroring the Redis
42
+ * bond's `attempts: 3, backoff: { type: 'exponential', delay: 1000 }`.
43
+ * Defaults to `1`. With the default `maxReceiveCount` of `3`, a
44
+ * `redeliveryDelaySeconds` of `0` would burn all delivery attempts within
45
+ * milliseconds and drop the message with no real chance for a transient
46
+ * downstream failure to recover — this option exists so "retry" means a
47
+ * few real seconds apart, not a hot loop.
48
+ */
49
+ handlerFailureRedeliveryDelaySeconds?: number;
50
+ }
51
+ /**
52
+ * Internal configuration for a single in-memory queue instance, resolved by
53
+ * the provider from `MemoryQueueOptions` and per-queue `QueueCreateOptions`.
54
+ */
55
+ export interface MemoryQueueConfig {
56
+ /**
57
+ * Default visibility timeout in seconds for leases without an explicit
58
+ * `ReceiveOptions.visibilityTimeout`.
59
+ */
60
+ defaultVisibilityTimeoutSeconds: number;
61
+ /**
62
+ * Maximum deliveries before dead-lettering/dropping. Overridden per queue
63
+ * by `deadLetterQueue.maxReceiveCount` when a dead-letter queue is set.
64
+ */
65
+ maxReceiveCount: number;
66
+ /**
67
+ * Delay in seconds before redelivery after an explicit `nack()`.
68
+ */
69
+ redeliveryDelaySeconds: number;
70
+ /**
71
+ * Delay in seconds before redelivery after an uncaught `subscribe()`
72
+ * handler failure.
73
+ */
74
+ handlerFailureRedeliveryDelaySeconds: number;
75
+ /**
76
+ * Whether this queue enforces FIFO semantics (per-`groupId` ordered,
77
+ * head-of-line-blocking delivery plus `deduplicationId` deduplication).
78
+ */
79
+ fifo: boolean;
80
+ /**
81
+ * Optional retention period in seconds; messages older than this are
82
+ * discarded when next scanned.
83
+ */
84
+ messageRetentionSeconds?: number;
85
+ /**
86
+ * Optional dead-letter queue for messages exceeding the delivery cap.
87
+ */
88
+ deadLetterQueue?: QueueCreateOptions['deadLetterQueue'];
89
+ /**
90
+ * Resolves another queue by name — used to route dead-lettered messages.
91
+ */
92
+ resolveQueue: (name: string) => Queue;
93
+ }
94
+ /**
95
+ * Handle pairing a `Queue` with the internal lifecycle control the provider
96
+ * uses to shut it down (`close()` is not part of the core `Queue` interface).
97
+ */
98
+ export interface MemoryQueueHandle {
99
+ /**
100
+ * The in-memory queue implementation.
101
+ */
102
+ queue: Queue;
103
+ /**
104
+ * Stops all timers, resolves pending long-polls with `[]`, discards all
105
+ * messages and subscribers, and rejects further sends.
106
+ */
107
+ close(): void;
108
+ }
109
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAA;AAGpE,YAAY,EACV,cAAc,EACd,KAAK,EACL,kBAAkB,EAClB,YAAY,EACZ,aAAa,EACb,eAAe,EACf,cAAc,GACf,MAAM,qBAAqB,CAAA;AAE5B;;;;;GAKG;AACH,MAAM,WAAW,kBAAkB;IACjC;;;;;;OAMG;IACH,wBAAwB,CAAC,EAAE,MAAM,CAAA;IAEjC;;;;;OAKG;IACH,eAAe,CAAC,EAAE,MAAM,CAAA;IAExB;;;;;OAKG;IACH,sBAAsB,CAAC,EAAE,MAAM,CAAA;IAE/B;;;;;;;;;;;OAWG;IACH,oCAAoC,CAAC,EAAE,MAAM,CAAA;CAC9C;AAED;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAChC;;;OAGG;IACH,+BAA+B,EAAE,MAAM,CAAA;IAEvC;;;OAGG;IACH,eAAe,EAAE,MAAM,CAAA;IAEvB;;OAEG;IACH,sBAAsB,EAAE,MAAM,CAAA;IAE9B;;;OAGG;IACH,oCAAoC,EAAE,MAAM,CAAA;IAE5C;;;OAGG;IACH,IAAI,EAAE,OAAO,CAAA;IAEb;;;OAGG;IACH,uBAAuB,CAAC,EAAE,MAAM,CAAA;IAEhC;;OAEG;IACH,eAAe,CAAC,EAAE,kBAAkB,CAAC,iBAAiB,CAAC,CAAA;IAEvD;;OAEG;IACH,YAAY,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,KAAK,CAAA;CACtC;AAED;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAChC;;OAEG;IACH,KAAK,EAAE,KAAK,CAAA;IAEZ;;;OAGG;IACH,KAAK,IAAI,IAAI,CAAA;CACd"}
package/dist/types.js ADDED
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Type definitions for the in-memory queue provider.
3
+ *
4
+ * @module
5
+ */
6
+ export {};
7
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
package/package.json ADDED
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "@molecule/api-queue-memory",
3
+ "version": "1.0.0",
4
+ "description": "In-memory queue provider for molecule.dev.",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "scripts": {
9
+ "build": "tsc",
10
+ "test": "vitest run",
11
+ "test:watch": "vitest"
12
+ },
13
+ "exports": {
14
+ ".": {
15
+ "types": "./dist/index.d.ts",
16
+ "import": "./dist/index.js"
17
+ }
18
+ },
19
+ "files": [
20
+ "dist"
21
+ ],
22
+ "keywords": [
23
+ "molecule",
24
+ "queue",
25
+ "memory",
26
+ "messaging"
27
+ ],
28
+ "license": "Apache-2.0",
29
+ "peerDependencies": {
30
+ "@molecule/api-bond": "^1.0.0",
31
+ "@molecule/api-queue": "^1.0.0"
32
+ },
33
+ "devDependencies": {
34
+ "@types/node": "26.1.2",
35
+ "typescript": "6.0.3",
36
+ "vitest": "4.1.10"
37
+ },
38
+ "repository": {
39
+ "type": "git",
40
+ "url": "https://github.com/molecule-dev/molecule.git",
41
+ "directory": "packages/api/bonds/queue/memory"
42
+ },
43
+ "homepage": "https://github.com/molecule-dev/molecule/tree/main/packages/api/bonds/queue/memory",
44
+ "bugs": "https://github.com/molecule-dev/molecule/issues",
45
+ "publishConfig": {
46
+ "access": "public"
47
+ }
48
+ }