@othree.io/stethoscope 1.0.0 → 2.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.
@@ -0,0 +1,20 @@
1
+ import { Optional } from '@othree.io/optional';
2
+ export declare const ProcessResultAction: {
3
+ readonly success: "success";
4
+ readonly failure: "failure";
5
+ readonly none: "none";
6
+ readonly retry: "retry";
7
+ };
8
+ export type ProcessResultAction = typeof ProcessResultAction[keyof typeof ProcessResultAction];
9
+ export type ProcessResult<Input, Output, Action extends ProcessResultAction> = Readonly<{
10
+ request: Input;
11
+ action: Action;
12
+ result: Action extends 'success' ? Output : void;
13
+ error: Action extends 'failure' ? Error : void;
14
+ }>;
15
+ export type ProcessResults<Input, Output> = ProcessResult<Input, Output, 'failure'> | ProcessResult<Input, Output, 'success'> | ProcessResult<Input, Output, 'none'> | ProcessResult<Input, Output, 'retry'>;
16
+ export type GetProcessResults<Input, Output> = (input: Input, maybeResult: Optional<Output>) => Promise<ProcessResults<Input, Output>>;
17
+ export declare const getProcessResults: (deps: {
18
+ didItFail: (error: Error) => boolean;
19
+ }) => <Input, Output>(input: Input, maybeResult: Optional<Output>) => Promise<ProcessResults<Input, Output>>;
20
+ //# sourceMappingURL=results-processor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"results-processor.d.ts","sourceRoot":"","sources":["../../src/results-processor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,QAAQ,EAAC,MAAM,qBAAqB,CAAA;AAE5C,eAAO,MAAM,mBAAmB;;;;;CAKtB,CAAA;AAEV,MAAM,MAAM,mBAAmB,GAAG,OAAO,mBAAmB,CAAC,MAAM,OAAO,mBAAmB,CAAC,CAAA;AAE9F,MAAM,MAAM,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,mBAAmB,IAAI,QAAQ,CAAC;IACpF,OAAO,EAAE,KAAK,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,SAAS,SAAS,GAAG,MAAM,GAAG,IAAI,CAAA;IAChD,KAAK,EAAE,MAAM,SAAS,SAAS,GAAG,KAAK,GAAG,IAAI,CAAA;CACjD,CAAC,CAAA;AAEF,MAAM,MAAM,cAAc,CAAC,KAAK,EAAE,MAAM,IAAI,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,CAAC,GAC7E,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,CAAC,GACvC,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,GACpC,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,CAAA;AAG3C,MAAM,MAAM,iBAAiB,CAAC,KAAK,EAAE,MAAM,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,QAAQ,CAAC,MAAM,CAAC,KAAK,OAAO,CAAC,cAAc,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAA;AAEtI,eAAO,MAAM,iBAAiB,GAAI,MAAM;IACpC,SAAS,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,CAAA;CACvC,MACU,KAAK,EAAE,MAAM,EAAE,OAAO,KAAK,EAAE,aAAa,QAAQ,CAAC,MAAM,CAAC,KAAG,OAAO,CAAC,cAAc,CAAC,KAAK,EAAE,MAAM,CAAC,CA0CxG,CAAA"}
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getProcessResults = exports.ProcessResultAction = void 0;
4
+ exports.ProcessResultAction = {
5
+ success: 'success',
6
+ failure: 'failure',
7
+ none: 'none',
8
+ retry: 'retry',
9
+ };
10
+ const getProcessResults = (deps) => async (input, maybeResult) => {
11
+ return maybeResult
12
+ .map(result => {
13
+ const successfulResult = {
14
+ request: input,
15
+ action: exports.ProcessResultAction.success,
16
+ result: result,
17
+ error: undefined,
18
+ };
19
+ return successfulResult;
20
+ })
21
+ .orMap(() => {
22
+ const noResult = {
23
+ request: input,
24
+ action: exports.ProcessResultAction.none,
25
+ result: undefined,
26
+ error: undefined,
27
+ };
28
+ return noResult;
29
+ })
30
+ .catchAsync(async (error) => {
31
+ if (deps.didItFail(error)) {
32
+ const failureResult = {
33
+ request: input,
34
+ action: exports.ProcessResultAction.failure,
35
+ result: undefined,
36
+ error: error,
37
+ };
38
+ return failureResult;
39
+ }
40
+ const retryResult = {
41
+ request: input,
42
+ action: exports.ProcessResultAction.retry,
43
+ result: undefined,
44
+ error: undefined,
45
+ };
46
+ return retryResult;
47
+ })
48
+ .then(_ => _.get());
49
+ };
50
+ exports.getProcessResults = getProcessResults;
51
+ //# sourceMappingURL=results-processor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"results-processor.js","sourceRoot":"","sources":["../../src/results-processor.ts"],"names":[],"mappings":";;;AAEa,QAAA,mBAAmB,GAAG;IAC/B,OAAO,EAAE,SAAS;IAClB,OAAO,EAAE,SAAS;IAClB,IAAI,EAAE,MAAM;IACZ,KAAK,EAAE,OAAO;CACR,CAAA;AAmBH,MAAM,iBAAiB,GAAG,CAAC,IAEjC,EAAE,EAAE,CACD,KAAK,EAAiB,KAAY,EAAE,WAA6B,EAA0C,EAAE;IACzG,OAAO,WAAW;SACb,GAAG,CAAC,MAAM,CAAC,EAAE;QACV,MAAM,gBAAgB,GAAkC;YACpD,OAAO,EAAE,KAAK;YACd,MAAM,EAAE,2BAAmB,CAAC,OAAO;YACnC,MAAM,EAAE,MAAM;YACd,KAAK,EAAE,SAAS;SACnB,CAAA;QAED,OAAO,gBAAgB,CAAA;IAC3B,CAAC,CAAC;SACD,KAAK,CAAC,GAAG,EAAE;QACR,MAAM,QAAQ,GAAkC;YAC5C,OAAO,EAAE,KAAK;YACd,MAAM,EAAE,2BAAmB,CAAC,IAAI;YAChC,MAAM,EAAE,SAAS;YACjB,KAAK,EAAE,SAAS;SACnB,CAAA;QACD,OAAO,QAAQ,CAAA;IACnB,CAAC,CAAC;SACD,UAAU,CAAC,KAAK,EAAC,KAAK,EAAC,EAAE;QACtB,IAAI,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;YACxB,MAAM,aAAa,GAAkC;gBACjD,OAAO,EAAE,KAAK;gBACd,MAAM,EAAE,2BAAmB,CAAC,OAAO;gBACnC,MAAM,EAAE,SAAS;gBACjB,KAAK,EAAE,KAAK;aACf,CAAA;YAED,OAAO,aAAa,CAAA;QACxB,CAAC;QAED,MAAM,WAAW,GAAkC;YAC/C,OAAO,EAAE,KAAK;YACd,MAAM,EAAE,2BAAmB,CAAC,KAAK;YACjC,MAAM,EAAE,SAAS;YACjB,KAAK,EAAE,SAAS;SACnB,CAAA;QACD,OAAO,WAAW,CAAA;IACtB,CAAC,CAAC;SACD,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAA;AAC3B,CAAC,CAAA;AA7CQ,QAAA,iBAAiB,qBA6CzB"}
package/lib/esm/aws.js ADDED
@@ -0,0 +1,151 @@
1
+ import { Optional } from '@othree.io/optional';
2
+ import { ProcessResultAction, } from './results-processor';
3
+ export const NoGroupSymbol = Symbol('NoGroupSymbol');
4
+ const LIMIT = 10;
5
+ const InitialValue = Object.freeze({});
6
+ const appendToResults = (accumulated, action, messageResult) => {
7
+ return {
8
+ none: accumulated.none,
9
+ success: accumulated.success,
10
+ failure: accumulated.failure,
11
+ retry: accumulated.retry,
12
+ [action]: [].concat(accumulated[action], messageResult),
13
+ };
14
+ };
15
+ export const groupRecords = (records) => {
16
+ const groupedRecords = records.reduce(((acum, current) => {
17
+ const key = Optional(current.attributes.MessageGroupId).orElse(NoGroupSymbol);
18
+ const existing = Optional(acum[key]);
19
+ const updated = existing
20
+ .map(_ => [].concat(_, current))
21
+ .orElse([current]);
22
+ const result = {};
23
+ Reflect.ownKeys(acum).forEach(k => { result[k] = acum[k]; });
24
+ result[key] = updated;
25
+ return result;
26
+ }), InitialValue);
27
+ return groupedRecords;
28
+ };
29
+ const processInBatches = async (items, limit, fn) => {
30
+ const results = [];
31
+ for (let i = 0; i < items.length; i += limit) {
32
+ const batch = items.slice(i, i + limit);
33
+ const batchResults = await Promise.all(batch.map(fn));
34
+ results.push(...batchResults);
35
+ }
36
+ return results;
37
+ };
38
+ export const processSQSEvent = (deps) => async (event) => {
39
+ const groupedRecords = deps.groupRecords(event.Records);
40
+ const groupedResults = await processInBatches(Reflect.ownKeys(groupedRecords), LIMIT, async (key) => {
41
+ const values = groupedRecords[key];
42
+ let accumulated = {
43
+ [ProcessResultAction.none]: [],
44
+ [ProcessResultAction.failure]: [],
45
+ [ProcessResultAction.success]: [],
46
+ [ProcessResultAction.retry]: [],
47
+ };
48
+ for (const current of values) {
49
+ const maybeInput = await deps.getProcessInput(current);
50
+ if (maybeInput.isEmpty) {
51
+ const processResult = {
52
+ request: undefined,
53
+ action: ProcessResultAction.failure,
54
+ result: undefined,
55
+ error: Optional(maybeInput.getError()).orElse(new Error('Failed to get input')),
56
+ };
57
+ const messageResult = {
58
+ message: current,
59
+ result: processResult,
60
+ };
61
+ accumulated = appendToResults(accumulated, processResult.action, messageResult);
62
+ continue;
63
+ }
64
+ const input = maybeInput.get();
65
+ /*
66
+ if it is an actual grouped message it means it's a fifo queue and
67
+ if there's already a message for retry (retry action) on a previous message
68
+ then next messages need to be retried.
69
+ Return retry so that the message is placed back into the queue
70
+ */
71
+ if (key !== NoGroupSymbol && accumulated.retry.length > 0) {
72
+ const messageResult = {
73
+ message: current,
74
+ result: {
75
+ request: maybeInput.orElse(undefined),
76
+ action: ProcessResultAction.retry,
77
+ result: undefined,
78
+ error: undefined,
79
+ },
80
+ };
81
+ accumulated = appendToResults(accumulated, messageResult.result.action, messageResult);
82
+ continue;
83
+ }
84
+ const processResult = await deps.process(input)
85
+ .then(maybeResult => deps.getProcessResults(input, maybeResult));
86
+ const messageResult = {
87
+ message: current,
88
+ result: processResult,
89
+ };
90
+ accumulated = appendToResults(accumulated, processResult.action, messageResult);
91
+ }
92
+ const groupResults = {
93
+ group: key,
94
+ results: accumulated,
95
+ };
96
+ return groupResults;
97
+ });
98
+ return groupedResults;
99
+ };
100
+ export const handleExponentialBackoff = (deps) => async (groupResults) => {
101
+ await Promise.allSettled(groupResults.map(async (results) => {
102
+ for (const messageResult of results.results.retry) {
103
+ const receiveCount = Number(messageResult.message.attributes.ApproximateReceiveCount);
104
+ const timeoutIndex = receiveCount - 1 >= deps.timeouts.length ? deps.timeouts.length - 1 : receiveCount - 1;
105
+ const visibilityTimeout = deps.timeouts[timeoutIndex];
106
+ await deps.getQueueUrl({
107
+ queueArn: messageResult.message.eventSourceARN
108
+ }).mapAsync(async (queueUrlOutput) => {
109
+ await deps.changeMessageVisibility({
110
+ receiptHandle: messageResult.message.receiptHandle,
111
+ queue: queueUrlOutput.queueUrl,
112
+ timeout: visibilityTimeout,
113
+ });
114
+ });
115
+ }
116
+ }));
117
+ return groupResults;
118
+ };
119
+ export const handleErrors = (deps) => async (groupResults) => {
120
+ await Promise.allSettled(groupResults.map(async (results) => {
121
+ for (const messageResult of results.results.failure) {
122
+ await deps.notifyError({
123
+ request: messageResult.message,
124
+ error: {
125
+ message: messageResult.result.error.message,
126
+ name: messageResult.result.error.name,
127
+ stack: messageResult.result.error.stack,
128
+ },
129
+ });
130
+ }
131
+ }));
132
+ return groupResults;
133
+ };
134
+ export const toSQSBatchResponse = async (groupResults) => {
135
+ return {
136
+ batchItemFailures: groupResults.map(_ => _.results.retry)
137
+ .flat()
138
+ .map(_ => {
139
+ return {
140
+ itemIdentifier: _.message.messageId,
141
+ };
142
+ }),
143
+ };
144
+ };
145
+ export const processSQSEventAndHandleResults = (deps) => async (event) => {
146
+ return deps.processSQSEvent(event)
147
+ .then(deps.handleErrors)
148
+ .then(deps.handleExponentialBackoff)
149
+ .then(deps.toSQSBatchResponse);
150
+ };
151
+ //# sourceMappingURL=aws.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aws.js","sourceRoot":"","sources":["../../src/aws.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ import { groupRecords, handleErrors, handleExponentialBackoff, processSQSEvent, processSQSEventAndHandleResults, toSQSBatchResponse, } from './aws';
2
+ import { getProcessResults } from './results-processor';
3
+ import { Optional } from '@othree.io/optional';
4
+ import { sqs } from '@othree.io/awsome';
5
+ export * from './results-processor';
6
+ export * as aws from './aws';
7
+ const wrapWithLog = (maybeLog, fn, name) => {
8
+ return maybeLog
9
+ .map(_ => _(fn)(name))
10
+ .orElse(fn);
11
+ };
12
+ export const processSqs = (deps) => {
13
+ const maybeLog = Optional(deps.log);
14
+ const processSQSEventFn = wrapWithLog(maybeLog, processSQSEvent({
15
+ process: deps.runProcess,
16
+ groupRecords,
17
+ getProcessInput: deps.getProcessInput,
18
+ getProcessResults: getProcessResults({ didItFail: deps.didItFail }),
19
+ }), 'processSQSEvent');
20
+ const changeMessageVisibilityTimeout = wrapWithLog(maybeLog, sqs.changeMessageVisibilityTimeout({ client: deps.sqsClient }), 'changeMessageVisibilityTimeout');
21
+ const handleExponentialBackoffFn = wrapWithLog(maybeLog, handleExponentialBackoff({
22
+ changeMessageVisibility: changeMessageVisibilityTimeout,
23
+ getQueueUrl: sqs.getQueueUrl,
24
+ timeouts: deps.configuration.exponentialTimeouts,
25
+ }), 'handleExponentialBackoff');
26
+ const sendDLQMessage = sqs.send({
27
+ client: deps.sqsClient,
28
+ configuration: { QueueUrl: deps.configuration.dlqUrl },
29
+ });
30
+ const handleErrorsFn = wrapWithLog(maybeLog, handleErrors({
31
+ notifyError: sendDLQMessage,
32
+ }), 'handleErrors');
33
+ return wrapWithLog(maybeLog, processSQSEventAndHandleResults({
34
+ processSQSEvent: processSQSEventFn,
35
+ handleExponentialBackoff: handleExponentialBackoffFn,
36
+ handleErrors: handleErrorsFn,
37
+ toSQSBatchResponse,
38
+ }), 'processSQSEventAndHandleResults');
39
+ };
40
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAEH,YAAY,EACZ,YAAY,EACZ,wBAAwB,EACxB,eAAe,EACf,+BAA+B,EAE/B,kBAAkB,GACrB,MAAM,OAAO,CAAA;AAEd,OAAO,EAAC,iBAAiB,EAAC,MAAM,qBAAqB,CAAA;AAErD,OAAO,EAAC,QAAQ,EAAC,MAAM,qBAAqB,CAAA;AAE5C,OAAO,EAAC,GAAG,EAAC,MAAM,mBAAmB,CAAA;AAErC,cAAc,qBAAqB,CAAA;AACnC,OAAO,KAAK,GAAG,MAAM,OAAO,CAAA;AAS5B,MAAM,WAAW,GAAG,CAAI,QAAuB,EAAE,EAAK,EAAE,IAAY,EAAK,EAAE;IACvE,OAAO,QAAQ;SACV,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAS,CAAC,CAAC,IAAI,CAAM,CAAC;SACjC,MAAM,CAAC,EAAE,CAAC,CAAA;AACnB,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,UAAU,GAAG,CAAgB,IAOzC,EAAE,EAAE;IACD,MAAM,QAAQ,GAAG,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IAEnC,MAAM,iBAAiB,GAAG,WAAW,CACjC,QAAQ,EACR,eAAe,CAAgB;QAC3B,OAAO,EAAE,IAAI,CAAC,UAAU;QACxB,YAAY;QACZ,eAAe,EAAE,IAAI,CAAC,eAAe;QACrC,iBAAiB,EAAE,iBAAiB,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC;KACtE,CAAC,EACF,iBAAiB,CACpB,CAAA;IAED,MAAM,8BAA8B,GAAG,WAAW,CAC9C,QAAQ,EACR,GAAG,CAAC,8BAA8B,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC,EAC9D,gCAAgC,CACnC,CAAA;IAED,MAAM,0BAA0B,GAAG,WAAW,CAC1C,QAAQ,EACR,wBAAwB,CAAgB;QACpC,uBAAuB,EAAE,8BAA8B;QACvD,WAAW,EAAE,GAAG,CAAC,WAAW;QAC5B,QAAQ,EAAE,IAAI,CAAC,aAAa,CAAC,mBAAmB;KACnD,CAAC,EACF,0BAA0B,CAC7B,CAAA;IAED,MAAM,cAAc,GAAG,GAAG,CAAC,IAAI,CAA0B;QACrD,MAAM,EAAE,IAAI,CAAC,SAAS;QACtB,aAAa,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE;KACzD,CAAC,CAAA;IAEF,MAAM,cAAc,GAAG,WAAW,CAC9B,QAAQ,EACR,YAAY,CAAgB;QACxB,WAAW,EAAE,cAAc;KAC9B,CAAC,EACF,cAAc,CACjB,CAAA;IAED,OAAO,WAAW,CACd,QAAQ,EACR,+BAA+B,CAAgB;QAC3C,eAAe,EAAE,iBAAiB;QAClC,wBAAwB,EAAE,0BAA0B;QACpD,YAAY,EAAE,cAAc;QAC5B,kBAAkB;KACrB,CAAC,EACF,iCAAiC,CACpC,CAAA;AACL,CAAC,CAAA"}
@@ -0,0 +1,47 @@
1
+ export const ProcessResultAction = {
2
+ success: 'success',
3
+ failure: 'failure',
4
+ none: 'none',
5
+ retry: 'retry',
6
+ };
7
+ export const getProcessResults = (deps) => async (input, maybeResult) => {
8
+ return maybeResult
9
+ .map(result => {
10
+ const successfulResult = {
11
+ request: input,
12
+ action: ProcessResultAction.success,
13
+ result: result,
14
+ error: undefined,
15
+ };
16
+ return successfulResult;
17
+ })
18
+ .orMap(() => {
19
+ const noResult = {
20
+ request: input,
21
+ action: ProcessResultAction.none,
22
+ result: undefined,
23
+ error: undefined,
24
+ };
25
+ return noResult;
26
+ })
27
+ .catchAsync(async (error) => {
28
+ if (deps.didItFail(error)) {
29
+ const failureResult = {
30
+ request: input,
31
+ action: ProcessResultAction.failure,
32
+ result: undefined,
33
+ error: error,
34
+ };
35
+ return failureResult;
36
+ }
37
+ const retryResult = {
38
+ request: input,
39
+ action: ProcessResultAction.retry,
40
+ result: undefined,
41
+ error: undefined,
42
+ };
43
+ return retryResult;
44
+ })
45
+ .then(_ => _.get());
46
+ };
47
+ //# sourceMappingURL=results-processor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"results-processor.js","sourceRoot":"","sources":["../../src/results-processor.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,mBAAmB,GAAG;IAC/B,OAAO,EAAE,SAAS;IAClB,OAAO,EAAE,SAAS;IAClB,IAAI,EAAE,MAAM;IACZ,KAAK,EAAE,OAAO;CACR,CAAA;AAmBV,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,IAEjC,EAAE,EAAE,CACD,KAAK,EAAiB,KAAY,EAAE,WAA6B,EAA0C,EAAE;IACzG,OAAO,WAAW;SACb,GAAG,CAAC,MAAM,CAAC,EAAE;QACV,MAAM,gBAAgB,GAAkC;YACpD,OAAO,EAAE,KAAK;YACd,MAAM,EAAE,mBAAmB,CAAC,OAAO;YACnC,MAAM,EAAE,MAAM;YACd,KAAK,EAAE,SAAS;SACnB,CAAA;QAED,OAAO,gBAAgB,CAAA;IAC3B,CAAC,CAAC;SACD,KAAK,CAAC,GAAG,EAAE;QACR,MAAM,QAAQ,GAAkC;YAC5C,OAAO,EAAE,KAAK;YACd,MAAM,EAAE,mBAAmB,CAAC,IAAI;YAChC,MAAM,EAAE,SAAS;YACjB,KAAK,EAAE,SAAS;SACnB,CAAA;QACD,OAAO,QAAQ,CAAA;IACnB,CAAC,CAAC;SACD,UAAU,CAAC,KAAK,EAAC,KAAK,EAAC,EAAE;QACtB,IAAI,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;YACxB,MAAM,aAAa,GAAkC;gBACjD,OAAO,EAAE,KAAK;gBACd,MAAM,EAAE,mBAAmB,CAAC,OAAO;gBACnC,MAAM,EAAE,SAAS;gBACjB,KAAK,EAAE,KAAK;aACf,CAAA;YAED,OAAO,aAAa,CAAA;QACxB,CAAC;QAED,MAAM,WAAW,GAAkC;YAC/C,OAAO,EAAE,KAAK;YACd,MAAM,EAAE,mBAAmB,CAAC,KAAK;YACjC,MAAM,EAAE,SAAS;YACjB,KAAK,EAAE,SAAS;SACnB,CAAA;QACD,OAAO,WAAW,CAAA;IACtB,CAAC,CAAC;SACD,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAA;AAC3B,CAAC,CAAA"}
package/package.json CHANGED
@@ -1,11 +1,20 @@
1
1
  {
2
2
  "name": "@othree.io/stethoscope",
3
- "version": "1.0.0",
3
+ "version": "2.0.0",
4
4
  "description": "Stethoscope",
5
- "main": "lib/index.js",
5
+ "main": "lib/cjs/index.js",
6
+ "module": "lib/esm/index.js",
7
+ "types": "lib/cjs/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./lib/cjs/index.d.ts",
11
+ "require": "./lib/cjs/index.js",
12
+ "import": "./lib/esm/index.js"
13
+ }
14
+ },
6
15
  "scripts": {
7
- "test": "jest",
8
- "build": "tsc",
16
+ "test": "vitest run --coverage",
17
+ "build": "tsc && tsc -p tsconfig.esm.json",
9
18
  "semantic-release": "semantic-release"
10
19
  },
11
20
  "keywords": [
@@ -13,22 +22,20 @@
13
22
  ],
14
23
  "author": "othree",
15
24
  "license": "ISC",
16
- "dependencies": {
17
- "@othree.io/awsome": "^1.3.0",
18
- "@othree.io/journal": "^1.0.0",
19
- "@othree.io/optional": "^2.2.0",
20
- "async": "^3.2.5"
25
+ "peerDependencies": {
26
+ "@othree.io/awsome": "^4.0.0",
27
+ "@othree.io/journal": "^2.0.0",
28
+ "@othree.io/optional": "^2.3.3"
21
29
  },
22
30
  "devDependencies": {
23
- "@types/async": "^3.2.24",
31
+ "@othree.io/awsome": "^4.0.0",
32
+ "@othree.io/journal": "^2.0.0",
33
+ "@othree.io/optional": "^2.3.3",
24
34
  "@types/aws-lambda": "^8.10.137",
25
- "@types/jest": "^29.5.0",
26
- "docdash": "^2.0.1",
27
- "jest": "^29.5.0",
28
- "jsdoc": "^4.0.2",
35
+ "@vitest/coverage-v8": "^3.0.0",
29
36
  "semantic-release": "^21.1.1",
30
- "ts-jest": "^29.0.5",
31
- "typescript": "^5.0.2"
37
+ "typescript": "^5.0.2",
38
+ "vitest": "^3.0.0"
32
39
  },
33
40
  "publishConfig": {
34
41
  "access": "public"
package/lib/aws.d.ts DELETED
@@ -1,107 +0,0 @@
1
- /** @module sqs */
2
- import { SQSBatchResponse, SQSEvent, SQSRecord } from 'aws-lambda';
3
- import { Optional } from '@othree.io/optional';
4
- import { GetProcessResults, ProcessResultAction, ProcessResults } from './results-processor';
5
- import { ChangeMessageVisibilityTimeoutRequest, GetQueueUrlInput, QueueUrlOutput } from '@othree.io/awsome/lib/sqs';
6
- /**
7
- * A unique symbol representing no group.
8
- */
9
- export declare const NoGroupSymbol: unique symbol;
10
- /**
11
- * Type definition for a function that processes input and returns a promise of an optional output.
12
- * @template Input, Output
13
- * @typedef {Function}
14
- * @param {Input} input - The input to process.
15
- * @returns {Promise<Optional<Output>>}
16
- */
17
- export type RunProcess<Input, Output> = (input: Input) => Promise<Optional<Output>>;
18
- /**
19
- * Type definition for a key, which can be a string or a symbol.
20
- * @typedef {string | symbol} Key
21
- */
22
- export type Key = string | symbol;
23
- /**
24
- * Interface representing the result of a message processing.
25
- * @template Input, Output
26
- * @interface
27
- */
28
- export interface MessageResult<Input, Output> {
29
- readonly message: SQSRecord;
30
- readonly result: ProcessResults<Input, Output>;
31
- }
32
- /**
33
- * Type definition for the results of processing messages, grouped by action.
34
- * @template Input, Output
35
- * @typedef {Object.<ProcessResultAction, Array<MessageResult<Input, Output>>>} Results
36
- */
37
- export type Results<Input, Output> = {
38
- readonly [key in ProcessResultAction]: Array<MessageResult<Input, Output>>;
39
- };
40
- /**
41
- * Interface representing the grouped results of processing messages.
42
- * @template Input, Output
43
- * @interface
44
- */
45
- export interface GroupResults<Input, Output> {
46
- readonly group: Key;
47
- readonly results: Results<Input, Output>;
48
- }
49
- /**
50
- * Type definition for grouped records.
51
- * @typedef {Record<Key, Array<SQSRecord>>} GroupedRecords
52
- */
53
- export type GroupedRecords = Record<Key, Array<SQSRecord>>;
54
- /**
55
- * Groups SQS records by their MessageGroupId attribute.
56
- * @param {Array<SQSRecord>} records - The SQS records to group.
57
- * @returns {GroupedRecords} The grouped records.
58
- */
59
- export declare const groupRecords: (records: Array<SQSRecord>) => GroupedRecords;
60
- /**
61
- * Processes an SQS event.
62
- * @template Input, Output
63
- * @param {RunProcess<Input, Output>} process - The process function.
64
- * @returns A function that takes groupRecords, getProcessInput, getProcessResults and returns a function that processes an SQS event.
65
- */
66
- export declare const processSQSEvent: <Input, Output>(process: RunProcess<Input, Output>) => (groupRecords: (records: Array<SQSRecord>) => GroupedRecords) => (getProcessInput: RunProcess<SQSRecord, Input>) => (getProcessResults: GetProcessResults<Input, Output>) => (event: SQSEvent) => Promise<Array<GroupResults<Input, Output>>>;
67
- /**
68
- * Handles exponential backoff for message visibility timeout changes.
69
- * @param {Function} changeMessageVisibility - Function to change message visibility timeout.
70
- * @returns {Function} A function that takes timeouts and returns a function to handle exponential backoff.
71
- */
72
- export declare const handleExponentialBackoff: (changeMessageVisibility: (request: ChangeMessageVisibilityTimeoutRequest) => Promise<Optional<true>>) => (getQueueUrl: (input: GetQueueUrlInput) => QueueUrlOutput) => (timeouts: Array<number>) => <Input, Output>(groupResults: Array<GroupResults<Input, Output>>) => Promise<Array<GroupResults<Input, Output>>>;
73
- /**
74
- * Represents an error message.
75
- * @interface
76
- * @template Input - The input type for the process.
77
- */
78
- export interface ErrorMessage<Input> {
79
- readonly request: Input;
80
- readonly error: {
81
- readonly name: string;
82
- readonly message: string;
83
- readonly stack?: string;
84
- };
85
- }
86
- /**
87
- * Handles errors by notifying with the provided notifyError function.
88
- * @template Input, Output
89
- * @param {Function} notifyError - Function to notify about the error.
90
- * @returns {Function} A function to handle errors.
91
- */
92
- export declare const handleErrors: <Input, Output>(notifyError: (payload: ErrorMessage<SQSRecord>) => Promise<Optional<boolean>>) => (groupResults: Array<GroupResults<Input, Output>>) => Promise<Array<GroupResults<Input, Output>>>;
93
- /**
94
- * Converts group results to an SQS batch response.
95
- * @template Input, Output
96
- * @param {Array<GroupResults<Input, Output>>} groupResults - The group results.
97
- * @returns {Promise<SQSBatchResponse>} The SQS batch response.
98
- */
99
- export declare const toSQSBatchResponse: <Input, Output>(groupResults: Array<GroupResults<Input, Output>>) => Promise<SQSBatchResponse>;
100
- /**
101
- * Processes an SQS event and handles results including exponential backoff and errors.
102
- * @template Input, Output
103
- * @param {Function} processSQSEvent - Function to process the SQS event.
104
- * @returns {Function} A function that takes handlers and returns a function to process the SQS event and handle results.
105
- */
106
- export declare const processSQSEventAndHandleResults: <Input, Output>(processSQSEvent: (event: SQSEvent) => Promise<Array<GroupResults<Input, Output>>>) => (handleExponentialBackoff: (groupResults: Array<GroupResults<Input, Output>>) => Promise<Array<GroupResults<Input, Output>>>) => (handleErrors: (groupResults: Array<GroupResults<Input, Output>>) => Promise<Array<GroupResults<Input, Output>>>) => (toSQSBatchResponse: (groupResults: Array<GroupResults<Input, Output>>) => Promise<SQSBatchResponse>) => (event: SQSEvent) => Promise<SQSBatchResponse>;
107
- //# sourceMappingURL=aws.d.ts.map
package/lib/aws.d.ts.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"aws.d.ts","sourceRoot":"","sources":["../src/aws.ts"],"names":[],"mappings":"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"}