@panorama-industries/effect-vercel-queue 0.0.0-stage → 0.1.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.
Files changed (123) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +13 -2
  3. package/dist/contracts/message-handling.d.ts +128 -0
  4. package/dist/contracts/message-handling.d.ts.map +1 -0
  5. package/dist/contracts/message-handling.js +4 -0
  6. package/dist/contracts/message-handling.js.map +1 -0
  7. package/dist/contracts/queue-api.d.ts +255 -0
  8. package/dist/contracts/queue-api.d.ts.map +1 -0
  9. package/dist/contracts/queue-api.js +18 -0
  10. package/dist/contracts/queue-api.js.map +1 -0
  11. package/dist/contracts/queue-config.d.ts +87 -0
  12. package/dist/contracts/queue-config.d.ts.map +1 -0
  13. package/dist/contracts/queue-config.js +7 -0
  14. package/dist/contracts/queue-config.js.map +1 -0
  15. package/dist/contracts/queue-consumer.d.ts +30 -0
  16. package/dist/contracts/queue-consumer.d.ts.map +1 -0
  17. package/dist/contracts/queue-consumer.js +15 -0
  18. package/dist/contracts/queue-consumer.js.map +1 -0
  19. package/dist/contracts/queue-domain.d.ts +171 -0
  20. package/dist/contracts/queue-domain.d.ts.map +1 -0
  21. package/dist/contracts/queue-domain.js +137 -0
  22. package/dist/contracts/queue-domain.js.map +1 -0
  23. package/dist/contracts/queue-poller.d.ts +169 -0
  24. package/dist/contracts/queue-poller.d.ts.map +1 -0
  25. package/dist/contracts/queue-poller.js +10 -0
  26. package/dist/contracts/queue-poller.js.map +1 -0
  27. package/dist/contracts/queue-producer.d.ts +23 -0
  28. package/dist/contracts/queue-producer.d.ts.map +1 -0
  29. package/dist/contracts/queue-producer.js +5 -0
  30. package/dist/contracts/queue-producer.js.map +1 -0
  31. package/dist/contracts/topic.d.ts +47 -0
  32. package/dist/contracts/topic.d.ts.map +1 -0
  33. package/dist/contracts/topic.js +34 -0
  34. package/dist/contracts/topic.js.map +1 -0
  35. package/dist/implementation/queue-api-live.d.ts +16 -0
  36. package/dist/implementation/queue-api-live.d.ts.map +1 -0
  37. package/dist/implementation/queue-api-live.js +326 -0
  38. package/dist/implementation/queue-api-live.js.map +1 -0
  39. package/dist/implementation/queue-config-live.d.ts +37 -0
  40. package/dist/implementation/queue-config-live.d.ts.map +1 -0
  41. package/dist/implementation/queue-config-live.js +99 -0
  42. package/dist/implementation/queue-config-live.js.map +1 -0
  43. package/dist/implementation/queue-consumer-live.d.ts +14 -0
  44. package/dist/implementation/queue-consumer-live.d.ts.map +1 -0
  45. package/dist/implementation/queue-consumer-live.js +56 -0
  46. package/dist/implementation/queue-consumer-live.js.map +1 -0
  47. package/dist/implementation/queue-live.d.ts +15 -0
  48. package/dist/implementation/queue-live.d.ts.map +1 -0
  49. package/dist/implementation/queue-live.js +16 -0
  50. package/dist/implementation/queue-live.js.map +1 -0
  51. package/dist/implementation/queue-poller-live.d.ts +14 -0
  52. package/dist/implementation/queue-poller-live.d.ts.map +1 -0
  53. package/dist/implementation/queue-poller-live.js +66 -0
  54. package/dist/implementation/queue-poller-live.js.map +1 -0
  55. package/dist/implementation/queue-producer-live.d.ts +9 -0
  56. package/dist/implementation/queue-producer-live.d.ts.map +1 -0
  57. package/dist/implementation/queue-producer-live.js +54 -0
  58. package/dist/implementation/queue-producer-live.js.map +1 -0
  59. package/dist/index.d.ts +16 -0
  60. package/dist/index.d.ts.map +1 -0
  61. package/dist/index.js +16 -0
  62. package/dist/index.js.map +1 -0
  63. package/dist/internal/cloud-event.d.ts +46 -0
  64. package/dist/internal/cloud-event.d.ts.map +1 -0
  65. package/dist/internal/cloud-event.js +140 -0
  66. package/dist/internal/cloud-event.js.map +1 -0
  67. package/dist/internal/lease.d.ts +23 -0
  68. package/dist/internal/lease.d.ts.map +1 -0
  69. package/dist/internal/lease.js +44 -0
  70. package/dist/internal/lease.js.map +1 -0
  71. package/dist/internal/multipart.d.ts +23 -0
  72. package/dist/internal/multipart.d.ts.map +1 -0
  73. package/dist/internal/multipart.js +205 -0
  74. package/dist/internal/multipart.js.map +1 -0
  75. package/dist/internal/process.d.ts +25 -0
  76. package/dist/internal/process.d.ts.map +1 -0
  77. package/dist/internal/process.js +95 -0
  78. package/dist/internal/process.js.map +1 -0
  79. package/dist/internal/queue-protocol.d.ts +38 -0
  80. package/dist/internal/queue-protocol.d.ts.map +1 -0
  81. package/dist/internal/queue-protocol.js +119 -0
  82. package/dist/internal/queue-protocol.js.map +1 -0
  83. package/dist/internal/version.d.ts +4 -0
  84. package/dist/internal/version.d.ts.map +1 -0
  85. package/dist/internal/version.js +4 -0
  86. package/dist/internal/version.js.map +1 -0
  87. package/dist/retry-policy.d.ts +26 -0
  88. package/dist/retry-policy.d.ts.map +1 -0
  89. package/dist/retry-policy.js +34 -0
  90. package/dist/retry-policy.js.map +1 -0
  91. package/dist/testing/index.d.ts +2 -0
  92. package/dist/testing/index.d.ts.map +1 -0
  93. package/dist/testing/index.js +2 -0
  94. package/dist/testing/index.js.map +1 -0
  95. package/dist/testing/test-queue.d.ts +74 -0
  96. package/dist/testing/test-queue.d.ts.map +1 -0
  97. package/dist/testing/test-queue.js +253 -0
  98. package/dist/testing/test-queue.js.map +1 -0
  99. package/package.json +59 -3
  100. package/src/contracts/message-handling.ts +68 -0
  101. package/src/contracts/queue-api.ts +199 -0
  102. package/src/contracts/queue-config.ts +47 -0
  103. package/src/contracts/queue-consumer.ts +40 -0
  104. package/src/contracts/queue-domain.ts +202 -0
  105. package/src/contracts/queue-poller.ts +76 -0
  106. package/src/contracts/queue-producer.ts +40 -0
  107. package/src/contracts/topic.ts +76 -0
  108. package/src/implementation/queue-api-live.ts +637 -0
  109. package/src/implementation/queue-config-live.ts +178 -0
  110. package/src/implementation/queue-consumer-live.ts +112 -0
  111. package/src/implementation/queue-live.ts +32 -0
  112. package/src/implementation/queue-poller-live.ts +130 -0
  113. package/src/implementation/queue-producer-live.ts +89 -0
  114. package/src/index.ts +19 -0
  115. package/src/internal/cloud-event.ts +244 -0
  116. package/src/internal/lease.ts +84 -0
  117. package/src/internal/multipart.ts +240 -0
  118. package/src/internal/process.ts +194 -0
  119. package/src/internal/queue-protocol.ts +169 -0
  120. package/src/internal/version.ts +5 -0
  121. package/src/retry-policy.ts +48 -0
  122. package/src/testing/index.ts +1 -0
  123. package/src/testing/test-queue.ts +469 -0
@@ -0,0 +1,205 @@
1
+ import { Data, Effect, Option, Stream } from "effect";
2
+ export class MultipartMixedError extends Data.TaggedError("MultipartMixedError") {
3
+ }
4
+ const maxHeaderSize = 65_536;
5
+ const encoder = new TextEncoder();
6
+ const latin1 = new TextDecoder("latin1");
7
+ export const boundaryFromContentType = (contentType) => {
8
+ const match = /boundary=(?:"([^"]+)"|([^;]+))/i.exec(contentType);
9
+ return Option.fromNullishOr(match?.[1] ?? match?.[2]);
10
+ };
11
+ const concatBytes = (chunks) => {
12
+ const out = new Uint8Array(chunks.reduce((total, chunk) => total + chunk.length, 0));
13
+ let offset = 0;
14
+ for (const chunk of chunks) {
15
+ out.set(chunk, offset);
16
+ offset += chunk.length;
17
+ }
18
+ return out;
19
+ };
20
+ export const encodeMultipartMixed = (boundary, parts) => concatBytes([
21
+ ...parts.flatMap((part) => [
22
+ encoder.encode(`--${boundary}\r\n${part.headers.map(([name, value]) => `${name}: ${value}\r\n`).join("")}\r\n`),
23
+ part.body,
24
+ encoder.encode("\r\n"),
25
+ ]),
26
+ encoder.encode(`--${boundary}--\r\n`),
27
+ ]);
28
+ const indexOf = (haystack, needle, from) => {
29
+ const last = haystack.length - needle.length;
30
+ const first = needle[0];
31
+ outer: for (let i = Math.max(0, from); i <= last; i++) {
32
+ if (haystack[i] !== first)
33
+ continue;
34
+ for (let j = 1; j < needle.length; j++) {
35
+ if (haystack[i + j] !== needle[j])
36
+ continue outer;
37
+ }
38
+ return i;
39
+ }
40
+ return -1;
41
+ };
42
+ const startsWith = (haystack, needle) => haystack.length >= needle.length && indexOf(haystack.subarray(0, needle.length), needle, 0) === 0;
43
+ const parseHeaders = (bytes) => {
44
+ const headers = {};
45
+ for (const line of latin1.decode(bytes).trim().split(/\r?\n/)) {
46
+ const colon = line.indexOf(":");
47
+ if (colon <= 0)
48
+ continue;
49
+ const name = line.slice(0, colon).trim().toLowerCase();
50
+ const value = line.slice(colon + 1).trim();
51
+ headers[name] = name in headers ? `${headers[name]}, ${value}` : value;
52
+ }
53
+ return headers;
54
+ };
55
+ const crlfcrlf = encoder.encode("\r\n\r\n");
56
+ const lflf = encoder.encode("\n\n");
57
+ const growableBuffer = () => {
58
+ let storage = new Uint8Array(0);
59
+ let start = 0;
60
+ let end = 0;
61
+ return {
62
+ view: () => storage.subarray(start, end),
63
+ append: (chunk) => {
64
+ const length = end - start;
65
+ if (end + chunk.length > storage.length) {
66
+ const next = new Uint8Array(Math.max(storage.length * 2, length + chunk.length, 1024));
67
+ next.set(storage.subarray(start, end));
68
+ storage = next;
69
+ start = 0;
70
+ end = length;
71
+ }
72
+ storage.set(chunk, end);
73
+ end += chunk.length;
74
+ },
75
+ consume: (count) => {
76
+ start += count;
77
+ if (start === end) {
78
+ start = 0;
79
+ end = 0;
80
+ }
81
+ },
82
+ clear: () => {
83
+ start = 0;
84
+ end = 0;
85
+ },
86
+ };
87
+ };
88
+ const mixedParser = (boundary) => {
89
+ const opening = encoder.encode(`--${boundary}`);
90
+ const delimiter = encoder.encode(`\r\n--${boundary}`);
91
+ const buffer = growableBuffer();
92
+ let state = "start";
93
+ let searchFrom = 0;
94
+ let headers = {};
95
+ const failure = (message) => Effect.fail(new MultipartMixedError({ message }));
96
+ const step = (parts) => {
97
+ const bytes = buffer.view();
98
+ switch (state) {
99
+ case "start": {
100
+ if (bytes.length < opening.length)
101
+ return "wait";
102
+ if (!startsWith(bytes, opening)) {
103
+ return Option.some("Invalid multipart stream: missing initial boundary");
104
+ }
105
+ buffer.consume(opening.length);
106
+ state = "afterBoundary";
107
+ return Option.none();
108
+ }
109
+ case "afterBoundary": {
110
+ if (bytes.length < 2)
111
+ return "wait";
112
+ if (bytes[0] === 45 && bytes[1] === 45) {
113
+ state = "done";
114
+ buffer.clear();
115
+ return "wait";
116
+ }
117
+ if (bytes[0] === 13 && bytes[1] === 10) {
118
+ buffer.consume(2);
119
+ }
120
+ else if (bytes[0] === 10) {
121
+ buffer.consume(1);
122
+ }
123
+ else {
124
+ return Option.some("Invalid character after multipart boundary");
125
+ }
126
+ state = "headers";
127
+ return Option.none();
128
+ }
129
+ case "headers": {
130
+ let end = -1;
131
+ let skip = 0;
132
+ if (bytes[0] === 13 && bytes[1] === 10) {
133
+ end = 0;
134
+ skip = 2;
135
+ }
136
+ else if (bytes[0] === 10) {
137
+ end = 0;
138
+ skip = 1;
139
+ }
140
+ else {
141
+ const crlf = indexOf(bytes, crlfcrlf, 0);
142
+ const lf = indexOf(bytes, lflf, 0);
143
+ if (crlf !== -1 && (lf === -1 || crlf < lf)) {
144
+ end = crlf;
145
+ skip = 4;
146
+ }
147
+ else {
148
+ end = lf;
149
+ skip = 2;
150
+ }
151
+ }
152
+ if (end === -1) {
153
+ return bytes.length > maxHeaderSize
154
+ ? Option.some("Multipart part headers are too large")
155
+ : "wait";
156
+ }
157
+ headers = parseHeaders(bytes.subarray(0, end));
158
+ buffer.consume(end + skip);
159
+ searchFrom = 0;
160
+ state = "body";
161
+ return Option.none();
162
+ }
163
+ case "body": {
164
+ const end = indexOf(bytes, delimiter, searchFrom);
165
+ if (end === -1) {
166
+ searchFrom = Math.max(0, bytes.length - delimiter.length + 1);
167
+ return "wait";
168
+ }
169
+ parts.push({ headers, body: bytes.slice(0, end) });
170
+ buffer.consume(end + delimiter.length);
171
+ state = "afterBoundary";
172
+ return Option.none();
173
+ }
174
+ case "done":
175
+ return "wait";
176
+ }
177
+ };
178
+ const push = (chunk) => {
179
+ if (state === "done")
180
+ return Effect.succeed([]);
181
+ buffer.append(chunk);
182
+ const parts = [];
183
+ while (true) {
184
+ const result = step(parts);
185
+ if (result === "wait")
186
+ return Effect.succeed(parts);
187
+ if (Option.isSome(result))
188
+ return failure(result.value);
189
+ }
190
+ };
191
+ const finish = Effect.suspend(() => {
192
+ if (state === "done")
193
+ return Effect.void;
194
+ return failure(state === "start"
195
+ ? "Invalid multipart stream: missing initial boundary"
196
+ : "Unexpected end of multipart stream");
197
+ });
198
+ return { push, finish };
199
+ };
200
+ /** Parses a `multipart/mixed` body as it streams in, emitting each part once it is complete. */
201
+ export const decodeMultipartMixed = (boundary) => (source) => Stream.suspend(() => {
202
+ const parser = mixedParser(boundary);
203
+ return source.pipe(Stream.mapEffect(parser.push), Stream.flattenIterable, Stream.concat(Stream.fromEffectDrain(parser.finish)));
204
+ });
205
+ //# sourceMappingURL=multipart.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"multipart.js","sourceRoot":"","sources":["../../src/internal/multipart.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ import type { Tracer } from "effect";
2
+ import { Effect } from "effect";
3
+ import { Headers } from "effect/http";
4
+ import type { ConsumeOptions, MessageHandler } from "../contracts/message-handling.ts";
5
+ import type { QueueApi, QueueLeaseError } from "../contracts/queue-api.ts";
6
+ import type { ReceivedMessage } from "../contracts/queue-domain.ts";
7
+ import type { Topic } from "../contracts/topic.ts";
8
+ import type { LeaseDeadline } from "./lease.ts";
9
+ import { PayloadDecodeFailed } from "../contracts/queue-domain.ts";
10
+ export interface Delivery {
11
+ readonly message: ReceivedMessage;
12
+ readonly deadline: LeaseDeadline;
13
+ }
14
+ /** Errors a processed delivery can end with once its error policy answered `Fail`. */
15
+ export type ProcessError<E> = E | PayloadDecodeFailed | QueueLeaseError;
16
+ /**
17
+ * Leases, decodes, handles and settles one delivered message, following `@vercel/queue`'s
18
+ * `ConsumerGroup.processMessage`.
19
+ */
20
+ export declare const processDelivery: <A, I, E, R, R2>(api: QueueApi["Service"], topic: Topic<A, I>, handler: MessageHandler<A, E, R>, options: ConsumeOptions<E, R2>, delivery: Delivery) => Effect.Effect<void, ProcessError<E>, R | R2>;
21
+ /** Links the producer's span, delivered in `x-vercel-queue-traceparent`, without parenting to it. */
22
+ export declare const producerLinks: (headers: Headers.Headers) => ReadonlyArray<Tracer.SpanLink>;
23
+ /** Runs `self` in a consumer-kind `vqs.process` span, as `@vercel/queue`'s `withConsumerSpan`. */
24
+ export declare const withProcessSpan: (links: ReadonlyArray<Tracer.SpanLink>) => <A, E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R>;
25
+ //# sourceMappingURL=process.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"process.d.ts","sourceRoot":"","sources":["../../src/internal/process.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAErC,OAAO,EAAY,MAAM,EAAkB,MAAM,QAAQ,CAAC;AAC1D,OAAO,EAAE,OAAO,EAAoB,MAAM,aAAa,CAAC;AAExD,OAAO,KAAK,EAEV,cAAc,EACd,cAAc,EACf,MAAM,kCAAkC,CAAC;AAC1C,OAAO,KAAK,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC3E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AACpE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAGhD,OAAO,EAAmB,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAGpF,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,OAAO,EAAE,eAAe,CAAC;IAClC,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC;CAClC;AAED,sFAAsF;AACtF,MAAM,MAAM,YAAY,CAAC,CAAC,IAAI,CAAC,GAAG,mBAAmB,GAAG,eAAe,CAAC;AAexE;;;GAGG;AACH,eAAO,MAAM,eAAe,GAAI,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,OACvC,QAAQ,CAAC,SAAS,CAAC,SACjB,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,WACT,cAAc,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,WACvB,cAAc,CAAC,CAAC,EAAE,EAAE,CAAC,YACpB,QAAQ,KACjB,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,EAAE,CAsH7C,CAAC;AAIF,qGAAqG;AACrG,eAAO,MAAM,aAAa,YAAa,OAAO,CAAC,OAAO,KAAG,aAAa,CAAC,MAAM,CAAC,QAAQ,CAOrF,CAAC;AAEF,kGAAkG;AAClG,eAAO,MAAM,eAAe,UAClB,aAAa,CAAC,MAAM,CAAC,QAAQ,CAAC,MACrC,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,KAAG,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAQ1D,CAAC"}
@@ -0,0 +1,95 @@
1
+ import { Duration, Effect, Option, Schema } from "effect";
2
+ import { Headers, HttpTraceContext } from "effect/http";
3
+ import { RetryDirective } from "../contracts/message-handling.js";
4
+ import { MessageMetadata, PayloadDecodeFailed } from "../contracts/queue-domain.js";
5
+ import { keepLeaseAlive, leaseVisibilityTimeout } from "./lease.js";
6
+ const escalate = (forPolicy, error) => ({ forPolicy, error });
7
+ const toPolicy = (error) => escalate(Option.some(error), error);
8
+ /**
9
+ * Leases, decodes, handles and settles one delivered message, following `@vercel/queue`'s
10
+ * `ConsumerGroup.processMessage`.
11
+ */
12
+ export const processDelivery = (api, topic, handler, options, delivery) => {
13
+ const { handle, metadata, body } = delivery.message;
14
+ const timeout = leaseVisibilityTimeout(options.visibilityTimeout);
15
+ const maxReruns = Math.max(0, Math.floor(options.experimentalMaxCoalescedReruns ?? 0));
16
+ const decode = Schema.decodeEffect(topic.wire)(body).pipe(Effect.mapError((error) => new PayloadDecodeFailed({
17
+ topic: handle.topic,
18
+ messageId: handle.messageId,
19
+ message: error.message,
20
+ })));
21
+ const runHandler = (payload, meta, deadline) => Effect.scoped(keepLeaseAlive(api, handle, timeout, deadline).pipe(Effect.andThen(handler(payload, meta)))).pipe(Effect.mapError(toPolicy));
22
+ const settleFailure = (error) => Effect.fail(escalate(Option.none(), error));
23
+ const acknowledge = (rerun, coalescedCount) => api
24
+ .acknowledge(handle, coalescedCount > 0 ? { experimentalIfCoalesced: coalescedCount } : undefined)
25
+ .pipe(Effect.as(Option.none()), Effect.catchReason("MessageNotAvailable", "ConcurrencyCoalescedPending", (reason, error) => rerun > maxReruns
26
+ ? Effect.fail(escalate(Option.some(reason), error))
27
+ : Effect.succeed(Option.some(reason.coalescedCount))), Effect.catchTags({
28
+ MessageNotAvailable: settleFailure,
29
+ MessageNotFound: settleFailure,
30
+ VercelApiError: settleFailure,
31
+ ConsumerRegistryNotConfigured: settleFailure,
32
+ }));
33
+ const attempt = Effect.gen(function* () {
34
+ const payload = yield* Effect.mapError(decode, toPolicy);
35
+ yield* runHandler(payload, metadata, delivery.deadline);
36
+ let coalescedCount = 0;
37
+ for (let rerun = 1;; rerun++) {
38
+ const refused = yield* acknowledge(rerun, coalescedCount);
39
+ if (Option.isNone(refused))
40
+ return;
41
+ coalescedCount = refused.value;
42
+ yield* runHandler(payload, new MessageMetadata({
43
+ messageId: metadata.messageId,
44
+ deliveryCount: metadata.deliveryCount,
45
+ createdAt: metadata.createdAt,
46
+ expiresAt: metadata.expiresAt,
47
+ topic: metadata.topic,
48
+ consumerGroup: metadata.consumerGroup,
49
+ region: metadata.region,
50
+ ...(metadata.experimentalHandoffCount === undefined
51
+ ? {}
52
+ : { experimentalHandoffCount: metadata.experimentalHandoffCount }),
53
+ experimentalCoalesced: { rerun, coalescedCount },
54
+ }), Option.some("expired"));
55
+ }
56
+ });
57
+ const chooseDirective = (error) => options.onError === undefined
58
+ ? Effect.succeed(RetryDirective.Fail())
59
+ : options
60
+ .onError(error, metadata)
61
+ .pipe(Effect.catchDefect((defect) => Effect.logWarning("Queue error policy failed; failing the delivery", defect).pipe(Effect.as(RetryDirective.Fail()))));
62
+ const applyDirective = (directive, error) => RetryDirective.$match(directive, {
63
+ Acknowledge: () => api
64
+ .acknowledge(handle)
65
+ .pipe(Effect.catch((cause) => Effect.logWarning("Failed to acknowledge message", cause))),
66
+ RetryAfter: ({ delay }) => api.changeVisibility(handle, delay).pipe(Effect.asVoid, Effect.catch((cause) => Effect.logWarning("Failed to reschedule message for retry", cause))),
67
+ ExperimentalHandoff: () => api.changeVisibility(handle, Duration.zero, { experimentalHandoff: true }).pipe(Effect.asVoid, Effect.catch((cause) => Effect.logWarning("Failed to hand off message", cause))),
68
+ Fail: () => Effect.fail(error),
69
+ });
70
+ return attempt.pipe(Effect.catch(({ forPolicy, error }) => Option.match(forPolicy, {
71
+ onNone: () => Effect.fail(error),
72
+ onSome: (cause) => chooseDirective(cause).pipe(Effect.flatMap((directive) => applyDirective(directive, error))),
73
+ })), Effect.annotateLogs({ module: "QueueConsumer", messageId: handle.messageId }));
74
+ };
75
+ const PRODUCER_TRACEPARENT = "x-vercel-queue-traceparent";
76
+ /** Links the producer's span, delivered in `x-vercel-queue-traceparent`, without parenting to it. */
77
+ export const producerLinks = (headers) => {
78
+ const traceparent = headers[PRODUCER_TRACEPARENT];
79
+ if (!traceparent)
80
+ return [];
81
+ return Option.match(HttpTraceContext.w3c(Headers.fromInput({ traceparent })), {
82
+ onNone: () => [],
83
+ onSome: (span) => [{ span, attributes: {} }],
84
+ });
85
+ };
86
+ /** Runs `self` in a consumer-kind `vqs.process` span, as `@vercel/queue`'s `withConsumerSpan`. */
87
+ export const withProcessSpan = (links) => (self) => Effect.withSpan(self, "vqs.process", {
88
+ kind: "consumer",
89
+ links,
90
+ attributes: {
91
+ "messaging.system": "vercel-queue",
92
+ "messaging.operation": "process",
93
+ },
94
+ });
95
+ //# sourceMappingURL=process.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"process.js","sourceRoot":"","sources":["../../src/internal/process.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ import { DateTime, Duration, Option } from "effect";
2
+ import type { OutgoingMessage } from "../contracts/queue-api.ts";
3
+ export declare const errorCodeHeader = "Vqs-Error-Code";
4
+ export declare const apiBaseUrl: (url: URL) => string;
5
+ export declare const topicPath: (topic: string, ...segments: ReadonlyArray<string>) => string;
6
+ export declare const wholeSeconds: (input: Duration.Input) => number;
7
+ /** A case-insensitive header set with the same overwrite semantics as `Headers.set`. */
8
+ export declare class HeaderSet {
9
+ private readonly entries;
10
+ constructor(init?: Readonly<Record<string, string>>);
11
+ set(name: string, value: string): this;
12
+ delete(name: string): this;
13
+ get(name: string): string | undefined;
14
+ toRecord(): Record<string, string>;
15
+ /** Entries sorted by name, as `Headers` iterates them. */
16
+ sorted(): Array<readonly [string, string]>;
17
+ }
18
+ export declare const messageHeaders: (custom: Readonly<Record<string, string>>, message: OutgoingMessage) => HeaderSet;
19
+ export declare const retryAfterFromHeader: (value: string | undefined, nowMillis: number) => Option.Option<Duration.Duration>;
20
+ export interface ErrorBody {
21
+ readonly text: string;
22
+ readonly message: string;
23
+ readonly originalMessageId: Option.Option<string>;
24
+ }
25
+ export declare const errorBodyOf: (text: string, contentType: string | undefined) => ErrorBody;
26
+ export declare const coalescedPendingCount: (errorCode: string | undefined, coalescedHeader: string | undefined, text: string) => Option.Option<number>;
27
+ export interface QueuePartHeaders {
28
+ readonly messageId: string;
29
+ readonly receiptHandle: string;
30
+ readonly deliveryCount: number;
31
+ readonly timestamp: string;
32
+ readonly expiresAt: Option.Option<string>;
33
+ readonly contentType: string;
34
+ readonly handoffCount: Option.Option<number>;
35
+ }
36
+ export declare const queuePartHeaders: (headers: Readonly<Record<string, string>>) => Option.Option<QueuePartHeaders>;
37
+ export declare const parseDate: (value: string) => Option.Option<DateTime.Utc>;
38
+ //# sourceMappingURL=queue-protocol.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queue-protocol.d.ts","sourceRoot":"","sources":["../../src/internal/queue-protocol.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAqB,MAAM,QAAQ,CAAC;AAEvE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAEjE,eAAO,MAAM,eAAe,mBAAmB,CAAC;AAEhD,eAAO,MAAM,UAAU,QAAS,GAAG,KAAG,MAC2B,CAAC;AAElE,eAAO,MAAM,SAAS,UAAW,MAAM,eAAe,aAAa,CAAC,MAAM,CAAC,KAAG,MACK,CAAC;AAEpF,eAAO,MAAM,YAAY,UAAW,QAAQ,CAAC,KAAK,KAAG,MACiB,CAAC;AAIvE,wFAAwF;AACxF,qBAAa,SAAS;IACpB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA6B;IAErD,YAAY,IAAI,GAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAM,EAEtD;IAED,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAGrC;IAED,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAGzB;IAED,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAEpC;IAED,QAAQ,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAEjC;IAED,0DAA0D;IAC1D,MAAM,IAAI,KAAK,CAAC,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAEzC;CACF;AAOD,eAAO,MAAM,cAAc,WACjB,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,WAC/B,eAAe,KACvB,SAiBF,CAAC;AAEF,eAAO,MAAM,oBAAoB,UACxB,MAAM,GAAG,SAAS,aACd,MAAM,KAChB,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAQjC,CAAC;AAEF,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;CACnD;AAMD,eAAO,MAAM,WAAW,SAAU,MAAM,eAAe,MAAM,GAAG,SAAS,KAAG,SAoB3E,CAAC;AAOF,eAAO,MAAM,qBAAqB,cACrB,MAAM,GAAG,SAAS,mBACZ,MAAM,GAAG,SAAS,QAC7B,MAAM,KACX,MAAM,CAAC,MAAM,CAAC,MAAM,CAKtB,CAAC;AAEF,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC1C,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;CAC9C;AAED,eAAO,MAAM,gBAAgB,YAClB,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,KACxC,MAAM,CAAC,MAAM,CAAC,gBAAgB,CAgBhC,CAAC;AAEF,eAAO,MAAM,SAAS,UAAW,MAAM,KAAG,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CACpC,CAAC"}
@@ -0,0 +1,119 @@
1
+ import { DateTime, Duration, Option, Predicate, Schema } from "effect";
2
+ export const errorCodeHeader = "Vqs-Error-Code";
3
+ export const apiBaseUrl = (url) => `${url.origin}${url.pathname.replace(/\/+$/, "")}/api/v3/topic`;
4
+ export const topicPath = (topic, ...segments) => [topic, ...segments].map((segment) => `/${encodeURIComponent(segment)}`).join("");
5
+ export const wholeSeconds = (input) => Math.ceil(Duration.toMillis(Duration.fromInputUnsafe(input)) / 1000);
6
+ const trimHeaderValue = (value) => value.replace(/^[\t\n\r ]+|[\t\n\r ]+$/g, "");
7
+ /** A case-insensitive header set with the same overwrite semantics as `Headers.set`. */
8
+ export class HeaderSet {
9
+ entries = new Map();
10
+ constructor(init = {}) {
11
+ for (const [name, value] of Object.entries(init))
12
+ this.set(name, value);
13
+ }
14
+ set(name, value) {
15
+ this.entries.set(name.toLowerCase(), trimHeaderValue(value));
16
+ return this;
17
+ }
18
+ delete(name) {
19
+ this.entries.delete(name.toLowerCase());
20
+ return this;
21
+ }
22
+ get(name) {
23
+ return this.entries.get(name.toLowerCase());
24
+ }
25
+ toRecord() {
26
+ return Object.fromEntries(this.entries);
27
+ }
28
+ /** Entries sorted by name, as `Headers` iterates them. */
29
+ sorted() {
30
+ return [...this.entries].toSorted(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0));
31
+ }
32
+ }
33
+ const isReservedMessageHeader = (name) => {
34
+ const lower = name.toLowerCase();
35
+ return lower === "authorization" || lower === "content-type" || lower.startsWith("vqs-");
36
+ };
37
+ export const messageHeaders = (custom, message) => {
38
+ const headers = new HeaderSet(custom).delete("authorization");
39
+ for (const [name, value] of Object.entries(message.headers ?? {})) {
40
+ if (!isReservedMessageHeader(name))
41
+ headers.set(name, value);
42
+ }
43
+ headers.set("content-type", message.contentType);
44
+ if (message.idempotencyKey)
45
+ headers.set("vqs-idempotency-key", message.idempotencyKey);
46
+ if (message.retention !== undefined) {
47
+ headers.set("vqs-retention-seconds", String(wholeSeconds(message.retention)));
48
+ }
49
+ if (message.delay !== undefined) {
50
+ headers.set("vqs-delay-seconds", String(wholeSeconds(message.delay)));
51
+ }
52
+ if (message.experimentalConcurrencyKey) {
53
+ headers.set("vqs-experimental-concurrency-key", message.experimentalConcurrencyKey);
54
+ }
55
+ return headers;
56
+ };
57
+ export const retryAfterFromHeader = (value, nowMillis) => {
58
+ if (!value)
59
+ return Option.none();
60
+ const seconds = Number(value);
61
+ if (Number.isFinite(seconds) && seconds >= 0)
62
+ return Option.some(Duration.seconds(seconds));
63
+ const dateMillis = Date.parse(value);
64
+ return Number.isNaN(dateMillis)
65
+ ? Option.none()
66
+ : Option.some(Duration.millis(Math.max(0, dateMillis - nowMillis)));
67
+ };
68
+ const decodeJsonObject = Schema.decodeUnknownOption(Schema.fromJsonString(Schema.Record(Schema.String, Schema.Unknown)));
69
+ export const errorBodyOf = (text, contentType) => {
70
+ const plain = { text, message: text, originalMessageId: Option.none() };
71
+ if (!contentType?.toLowerCase().includes("json"))
72
+ return plain;
73
+ return Option.match(decodeJsonObject(text), {
74
+ onNone: () => plain,
75
+ onSome: (body) => {
76
+ const error = body["error"];
77
+ const message = Predicate.isString(error)
78
+ ? error
79
+ : Predicate.isObject(error) && Predicate.isString(error["message"])
80
+ ? error["message"]
81
+ : text;
82
+ const original = body["originalMessageId"];
83
+ return {
84
+ text,
85
+ message,
86
+ originalMessageId: Predicate.isString(original) ? Option.some(original) : Option.none(),
87
+ };
88
+ },
89
+ });
90
+ };
91
+ const positiveInt = (value) => Predicate.isNumber(value) && Number.isInteger(value) && value > 0
92
+ ? Option.some(value)
93
+ : Option.none();
94
+ export const coalescedPendingCount = (errorCode, coalescedHeader, text) => {
95
+ if (errorCode !== "concurrency_coalesced_pending")
96
+ return Option.none();
97
+ return Option.orElse(positiveInt(Number(coalescedHeader ?? null)), () => Option.flatMap(decodeJsonObject(text), (body) => positiveInt(body["coalescedCount"])));
98
+ };
99
+ export const queuePartHeaders = (headers) => {
100
+ const messageId = headers["vqs-message-id"];
101
+ const timestamp = headers["vqs-timestamp"];
102
+ const receiptHandle = headers["vqs-receipt-handle"];
103
+ if (!messageId || !timestamp || !receiptHandle)
104
+ return Option.none();
105
+ const deliveryCount = Number.parseInt(headers["vqs-delivery-count"] || "0", 10);
106
+ if (Number.isNaN(deliveryCount))
107
+ return Option.none();
108
+ return Option.some({
109
+ messageId,
110
+ receiptHandle,
111
+ deliveryCount,
112
+ timestamp,
113
+ expiresAt: Option.fromUndefinedOr(headers["vqs-expires-at"] || undefined),
114
+ contentType: headers["content-type"] || "application/octet-stream",
115
+ handoffCount: positiveInt(Number(headers["vqs-experimental-handoff-count"] || Number.NaN)),
116
+ });
117
+ };
118
+ export const parseDate = (value) => DateTime.make(new Date(value));
119
+ //# sourceMappingURL=queue-protocol.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queue-protocol.js","sourceRoot":"","sources":["../../src/internal/queue-protocol.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export declare const packageName = "@panorama-industries/effect-vercel-queue";
2
+ export declare const packageVersion = "0.1.0";
3
+ export declare const userAgent = "@panorama-industries/effect-vercel-queue/0.1.0";
4
+ //# sourceMappingURL=version.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../src/internal/version.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,WAAW,6CAA6C,CAAC;AAEtE,eAAO,MAAM,cAAc,UAAU,CAAC;AAEtC,eAAO,MAAM,SAAS,mDAAqC,CAAC"}
@@ -0,0 +1,4 @@
1
+ export const packageName = "@panorama-industries/effect-vercel-queue";
2
+ export const packageVersion = "0.1.0";
3
+ export const userAgent = `${packageName}/${packageVersion}`;
4
+ //# sourceMappingURL=version.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../../src/internal/version.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,WAAW,GAAG,0CAA0C,CAAC;AAEtE,MAAM,CAAC,MAAM,cAAc,GAAG,OAAO,CAAC;AAEtC,MAAM,CAAC,MAAM,SAAS,GAAG,GAAG,WAAW,IAAI,cAAc,EAAE,CAAC"}
@@ -0,0 +1,26 @@
1
+ import { Effect, Schedule } from "effect";
2
+ import type { MessageMetadata } from "./contracts/queue-domain.ts";
3
+ import { RetryDirective } from "./contracts/message-handling.ts";
4
+ /**
5
+ * Build an `onError` policy that redelivers failed messages on a `Schedule`.
6
+ *
7
+ * The n-th failed delivery (`deliveryCount` minus experimental handoffs, which do not count as
8
+ * retries) waits for the schedule's n-th delay: the policy answers `RetryAfter(delay)` while the
9
+ * schedule continues and `onExhausted` once it is done. The schedule receives the error as input
10
+ * and is stepped from a fresh state on every call, all at the current time, so elapsed-time
11
+ * schedules see no elapsed time.
12
+ *
13
+ * ```ts
14
+ * consumer.handler(Orders, fulfil, {
15
+ * onError: retryOnSchedule(Schedule.exponential("1 second").pipe(Schedule.upTo({ times: 5 }))),
16
+ * });
17
+ * ```
18
+ *
19
+ * @param schedule - Delay of each retry; its outputs are ignored.
20
+ * @param options.onExhausted - Directive once the schedule is done. Default: `Acknowledge`, so the
21
+ * message is dropped.
22
+ */
23
+ export declare const retryOnSchedule: <Out, In, R>(schedule: Schedule.Schedule<Out, In, never, R>, options?: {
24
+ readonly onExhausted?: RetryDirective;
25
+ }) => (error: In, metadata: MessageMetadata) => Effect.Effect<RetryDirective, never, R>;
26
+ //# sourceMappingURL=retry-policy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry-policy.d.ts","sourceRoot":"","sources":["../src/retry-policy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,MAAM,EAAgB,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAE/D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAEnE,OAAO,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AAEjE;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,eAAe,GACzB,GAAG,EAAE,EAAE,EAAE,CAAC,YACC,QAAQ,CAAC,QAAQ,CAAC,GAAG,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,YACpC;IAAE,QAAQ,CAAC,WAAW,CAAC,EAAE,cAAc,CAAA;CAAE,aAE7C,EAAE,YAAY,eAAe,KAAG,MAAM,CAAC,MAAM,CAAC,cAAc,EAAE,KAAK,EAAE,CAAC,CAiB1E,CAAC"}
@@ -0,0 +1,34 @@
1
+ import { Clock, Effect, Option, Pull, Schedule } from "effect";
2
+ import { RetryDirective } from "./contracts/message-handling.js";
3
+ /**
4
+ * Build an `onError` policy that redelivers failed messages on a `Schedule`.
5
+ *
6
+ * The n-th failed delivery (`deliveryCount` minus experimental handoffs, which do not count as
7
+ * retries) waits for the schedule's n-th delay: the policy answers `RetryAfter(delay)` while the
8
+ * schedule continues and `onExhausted` once it is done. The schedule receives the error as input
9
+ * and is stepped from a fresh state on every call, all at the current time, so elapsed-time
10
+ * schedules see no elapsed time.
11
+ *
12
+ * ```ts
13
+ * consumer.handler(Orders, fulfil, {
14
+ * onError: retryOnSchedule(Schedule.exponential("1 second").pipe(Schedule.upTo({ times: 5 }))),
15
+ * });
16
+ * ```
17
+ *
18
+ * @param schedule - Delay of each retry; its outputs are ignored.
19
+ * @param options.onExhausted - Directive once the schedule is done. Default: `Acknowledge`, so the
20
+ * message is dropped.
21
+ */
22
+ export const retryOnSchedule = (schedule, options) => (error, metadata) => Effect.gen(function* () {
23
+ const step = yield* Schedule.toStep(schedule);
24
+ const now = yield* Clock.currentTimeMillis;
25
+ const attempt = Math.max(1, metadata.deliveryCount - (metadata.experimentalHandoffCount ?? 0));
26
+ let delay = Option.none();
27
+ for (let n = 0; n < attempt; n++) {
28
+ delay = yield* step(now, error).pipe(Effect.map(([, duration]) => Option.some(RetryDirective.RetryAfter({ delay: duration }))), Pull.catchDone(() => Effect.succeed(Option.none())));
29
+ if (Option.isNone(delay))
30
+ break;
31
+ }
32
+ return Option.getOrElse(delay, () => options?.onExhausted ?? RetryDirective.Acknowledge());
33
+ });
34
+ //# sourceMappingURL=retry-policy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry-policy.js","sourceRoot":"","sources":["../src/retry-policy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAI/D,OAAO,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AAEjE;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,CAAC,MAAM,eAAe,GAC1B,CACE,QAA8C,EAC9C,OAAmD,EACnD,EAAE,CACJ,CAAC,KAAS,EAAE,QAAyB,EAA2C,EAAE,CAChF,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IAClB,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC9C,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,KAAK,CAAC,iBAAiB,CAAC;IAC3C,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CACtB,CAAC,EACD,QAAQ,CAAC,aAAa,GAAG,CAAC,QAAQ,CAAC,wBAAwB,IAAI,CAAC,CAAC,CAClE,CAAC;IACF,IAAI,KAAK,GAAG,MAAM,CAAC,IAAI,EAAkB,CAAC;IAC1C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,EAAE,CAAC,EAAE,EAAE,CAAC;QACjC,KAAK,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,IAAI,CAClC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,EACzF,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,EAAkB,CAAC,CAAC,CACpE,CAAC;QACF,IAAI,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC;YAAE,MAAM;IAClC,CAAC;IACD,OAAO,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC,OAAO,EAAE,WAAW,IAAI,cAAc,CAAC,WAAW,EAAE,CAAC,CAAC;AAC7F,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export * from "./test-queue.ts";
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/testing/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC"}