@othree.io/stethoscope 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/.gitlab-ci.yml +29 -0
- package/README.md +1 -0
- package/lib/aws.d.ts +107 -0
- package/lib/aws.d.ts.map +1 -0
- package/lib/aws.js +195 -0
- package/lib/aws.js.map +1 -0
- package/lib/index.d.ts +21 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +54 -0
- package/lib/index.js.map +1 -0
- package/lib/results-processor.d.ts +43 -0
- package/lib/results-processor.d.ts.map +1 -0
- package/lib/results-processor.js +71 -0
- package/lib/results-processor.js.map +1 -0
- package/package.json +36 -0
- package/release.config.js +4 -0
package/.gitlab-ci.yml
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
image: node:14-alpine
|
|
2
|
+
|
|
3
|
+
cache:
|
|
4
|
+
key: ${CI_PIPELINE_ID}
|
|
5
|
+
paths:
|
|
6
|
+
- node_modules/
|
|
7
|
+
- lib/
|
|
8
|
+
|
|
9
|
+
build:
|
|
10
|
+
stage: build
|
|
11
|
+
script:
|
|
12
|
+
- npm install && npm run build
|
|
13
|
+
|
|
14
|
+
test:
|
|
15
|
+
stage: test
|
|
16
|
+
script:
|
|
17
|
+
- npm test
|
|
18
|
+
|
|
19
|
+
deploy:
|
|
20
|
+
image: node:20
|
|
21
|
+
stage: deploy
|
|
22
|
+
variables:
|
|
23
|
+
NPM_CONFIG_USERCONFIG: '$CI_PROJECT_DIR/.npmrc'
|
|
24
|
+
script:
|
|
25
|
+
- cat $NPM > .npmrc
|
|
26
|
+
- npx semantic-release
|
|
27
|
+
only:
|
|
28
|
+
refs:
|
|
29
|
+
- main
|
package/README.md
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# stethoscope
|
package/lib/aws.d.ts
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
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
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aws.d.ts","sourceRoot":"","sources":["../src/aws.ts"],"names":[],"mappings":"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"}
|
package/lib/aws.js
ADDED
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.processSQSEventAndHandleResults = exports.toSQSBatchResponse = exports.handleErrors = exports.handleExponentialBackoff = exports.processSQSEvent = exports.groupRecords = exports.NoGroupSymbol = void 0;
|
|
4
|
+
const optional_1 = require("@othree.io/optional");
|
|
5
|
+
const async_1 = require("async");
|
|
6
|
+
const results_processor_1 = require("./results-processor");
|
|
7
|
+
/**
|
|
8
|
+
* A unique symbol representing no group.
|
|
9
|
+
*/
|
|
10
|
+
exports.NoGroupSymbol = Symbol('NoGroupSymbol');
|
|
11
|
+
/**
|
|
12
|
+
* A constant representing the limit for parallel processing.
|
|
13
|
+
* @const {number}
|
|
14
|
+
*/
|
|
15
|
+
const LIMIT = 10;
|
|
16
|
+
/**
|
|
17
|
+
* The initial value for grouped records.
|
|
18
|
+
* @const {Record<Key, Array<SQSRecord>>}
|
|
19
|
+
*/
|
|
20
|
+
const InitialValue = Object.freeze({});
|
|
21
|
+
/**
|
|
22
|
+
* Groups SQS records by their MessageGroupId attribute.
|
|
23
|
+
* @param {Array<SQSRecord>} records - The SQS records to group.
|
|
24
|
+
* @returns {GroupedRecords} The grouped records.
|
|
25
|
+
*/
|
|
26
|
+
const groupRecords = (records) => {
|
|
27
|
+
const groupedRecords = records.reduce(((acum, current) => {
|
|
28
|
+
const key = (0, optional_1.Optional)(current.attributes.MessageGroupId).orElse(exports.NoGroupSymbol);
|
|
29
|
+
return {
|
|
30
|
+
...acum,
|
|
31
|
+
[key]: (0, optional_1.Optional)(acum[key])
|
|
32
|
+
.map(_ => [..._, current])
|
|
33
|
+
.orElse([current]),
|
|
34
|
+
};
|
|
35
|
+
}), InitialValue);
|
|
36
|
+
return groupedRecords;
|
|
37
|
+
};
|
|
38
|
+
exports.groupRecords = groupRecords;
|
|
39
|
+
/**
|
|
40
|
+
* Processes an SQS event.
|
|
41
|
+
* @template Input, Output
|
|
42
|
+
* @param {RunProcess<Input, Output>} process - The process function.
|
|
43
|
+
* @returns A function that takes groupRecords, getProcessInput, getProcessResults and returns a function that processes an SQS event.
|
|
44
|
+
*/
|
|
45
|
+
const processSQSEvent = (process) => (groupRecords) => (getProcessInput) => (getProcessResults) => async (event) => {
|
|
46
|
+
const groupedRecords = groupRecords(event.Records);
|
|
47
|
+
const groupedResults = await (0, async_1.mapLimit)(Reflect.ownKeys(groupedRecords), LIMIT, async (key) => {
|
|
48
|
+
const values = groupedRecords[key];
|
|
49
|
+
const initialResults = {
|
|
50
|
+
[results_processor_1.ProcessResultAction.none]: [],
|
|
51
|
+
[results_processor_1.ProcessResultAction.failure]: [],
|
|
52
|
+
[results_processor_1.ProcessResultAction.success]: [],
|
|
53
|
+
[results_processor_1.ProcessResultAction.retry]: []
|
|
54
|
+
};
|
|
55
|
+
const processResults = await (0, async_1.reduce)(values, initialResults, async (acum, current) => {
|
|
56
|
+
const maybeInput = await getProcessInput(current);
|
|
57
|
+
if (maybeInput.isEmpty) {
|
|
58
|
+
const processResult = {
|
|
59
|
+
request: undefined,
|
|
60
|
+
action: results_processor_1.ProcessResultAction.failure,
|
|
61
|
+
result: undefined,
|
|
62
|
+
error: new Error('Failed to get input'),
|
|
63
|
+
};
|
|
64
|
+
const messageResult = {
|
|
65
|
+
message: current,
|
|
66
|
+
result: processResult,
|
|
67
|
+
};
|
|
68
|
+
const results = {
|
|
69
|
+
...acum,
|
|
70
|
+
[processResult.action]: [...acum[processResult.action], messageResult],
|
|
71
|
+
};
|
|
72
|
+
return results;
|
|
73
|
+
}
|
|
74
|
+
const input = maybeInput.get();
|
|
75
|
+
/*
|
|
76
|
+
if it is an actual grouped message it means it's a fifo queue and
|
|
77
|
+
if there's already a message for retry (retry action) on a previous message
|
|
78
|
+
then next messages need to be retried.
|
|
79
|
+
Return retry so that the message is placed back into the queue
|
|
80
|
+
*/
|
|
81
|
+
if (key !== exports.NoGroupSymbol && acum.retry.length > 0) {
|
|
82
|
+
const messageResult = {
|
|
83
|
+
message: current,
|
|
84
|
+
result: {
|
|
85
|
+
request: maybeInput.orElse(undefined),
|
|
86
|
+
action: results_processor_1.ProcessResultAction.retry,
|
|
87
|
+
result: undefined,
|
|
88
|
+
error: undefined,
|
|
89
|
+
},
|
|
90
|
+
};
|
|
91
|
+
const results = {
|
|
92
|
+
...acum,
|
|
93
|
+
[messageResult.result.action]: [...acum[messageResult.result.action], messageResult],
|
|
94
|
+
};
|
|
95
|
+
return results;
|
|
96
|
+
}
|
|
97
|
+
const processResult = await process(input)
|
|
98
|
+
.then(maybeResult => getProcessResults(input, maybeResult));
|
|
99
|
+
const messageResult = {
|
|
100
|
+
message: current,
|
|
101
|
+
result: processResult,
|
|
102
|
+
};
|
|
103
|
+
const results = {
|
|
104
|
+
...acum,
|
|
105
|
+
[processResult.action]: [...acum[processResult.action], messageResult],
|
|
106
|
+
};
|
|
107
|
+
return results;
|
|
108
|
+
});
|
|
109
|
+
const groupResults = {
|
|
110
|
+
group: key,
|
|
111
|
+
results: processResults,
|
|
112
|
+
};
|
|
113
|
+
return groupResults;
|
|
114
|
+
});
|
|
115
|
+
return groupedResults;
|
|
116
|
+
};
|
|
117
|
+
exports.processSQSEvent = processSQSEvent;
|
|
118
|
+
/**
|
|
119
|
+
* Handles exponential backoff for message visibility timeout changes.
|
|
120
|
+
* @param {Function} changeMessageVisibility - Function to change message visibility timeout.
|
|
121
|
+
* @returns {Function} A function that takes timeouts and returns a function to handle exponential backoff.
|
|
122
|
+
*/
|
|
123
|
+
const handleExponentialBackoff = (changeMessageVisibility) => (getQueueUrl) => (timeouts) => async (groupResults) => {
|
|
124
|
+
await Promise.allSettled(groupResults.map(async (results) => {
|
|
125
|
+
await (0, async_1.forEachSeries)(results.results.retry, async (messageResult) => {
|
|
126
|
+
const receiveCount = Number(messageResult.message.attributes.ApproximateReceiveCount);
|
|
127
|
+
const timeoutIndex = receiveCount - 1 >= timeouts.length ? timeouts.length - 1 : receiveCount - 1;
|
|
128
|
+
const visibilityTimeout = timeouts[timeoutIndex];
|
|
129
|
+
await changeMessageVisibility({
|
|
130
|
+
receiptHandle: messageResult.message.receiptHandle,
|
|
131
|
+
queue: getQueueUrl({
|
|
132
|
+
queueArn: messageResult.message.eventSourceARN
|
|
133
|
+
}).queueUrl,
|
|
134
|
+
timeout: visibilityTimeout,
|
|
135
|
+
});
|
|
136
|
+
});
|
|
137
|
+
}));
|
|
138
|
+
return groupResults;
|
|
139
|
+
};
|
|
140
|
+
exports.handleExponentialBackoff = handleExponentialBackoff;
|
|
141
|
+
/**
|
|
142
|
+
* Handles errors by notifying with the provided notifyError function.
|
|
143
|
+
* @template Input, Output
|
|
144
|
+
* @param {Function} notifyError - Function to notify about the error.
|
|
145
|
+
* @returns {Function} A function to handle errors.
|
|
146
|
+
*/
|
|
147
|
+
const handleErrors = (notifyError) => async (groupResults) => {
|
|
148
|
+
await Promise.allSettled(groupResults.map(async (results) => {
|
|
149
|
+
await (0, async_1.forEachSeries)(results.results.failure, async (messageResult) => {
|
|
150
|
+
await notifyError({
|
|
151
|
+
request: messageResult.message,
|
|
152
|
+
error: {
|
|
153
|
+
message: messageResult.result.error.message,
|
|
154
|
+
name: messageResult.result.error.name,
|
|
155
|
+
stack: messageResult.result.error.stack,
|
|
156
|
+
},
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
}));
|
|
160
|
+
return groupResults;
|
|
161
|
+
};
|
|
162
|
+
exports.handleErrors = handleErrors;
|
|
163
|
+
/**
|
|
164
|
+
* Converts group results to an SQS batch response.
|
|
165
|
+
* @template Input, Output
|
|
166
|
+
* @param {Array<GroupResults<Input, Output>>} groupResults - The group results.
|
|
167
|
+
* @returns {Promise<SQSBatchResponse>} The SQS batch response.
|
|
168
|
+
*/
|
|
169
|
+
const toSQSBatchResponse = async (groupResults) => {
|
|
170
|
+
const response = {
|
|
171
|
+
batchItemFailures: groupResults.map(_ => _.results.retry)
|
|
172
|
+
.flat()
|
|
173
|
+
.map(_ => {
|
|
174
|
+
return {
|
|
175
|
+
itemIdentifier: _.message.receiptHandle,
|
|
176
|
+
};
|
|
177
|
+
}),
|
|
178
|
+
};
|
|
179
|
+
return response;
|
|
180
|
+
};
|
|
181
|
+
exports.toSQSBatchResponse = toSQSBatchResponse;
|
|
182
|
+
/**
|
|
183
|
+
* Processes an SQS event and handles results including exponential backoff and errors.
|
|
184
|
+
* @template Input, Output
|
|
185
|
+
* @param {Function} processSQSEvent - Function to process the SQS event.
|
|
186
|
+
* @returns {Function} A function that takes handlers and returns a function to process the SQS event and handle results.
|
|
187
|
+
*/
|
|
188
|
+
const processSQSEventAndHandleResults = (processSQSEvent) => (handleExponentialBackoff) => (handleErrors) => (toSQSBatchResponse) => async (event) => {
|
|
189
|
+
return processSQSEvent(event)
|
|
190
|
+
.then(handleErrors)
|
|
191
|
+
.then(handleExponentialBackoff)
|
|
192
|
+
.then(toSQSBatchResponse);
|
|
193
|
+
};
|
|
194
|
+
exports.processSQSEventAndHandleResults = processSQSEventAndHandleResults;
|
|
195
|
+
//# sourceMappingURL=aws.js.map
|
package/lib/aws.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aws.js","sourceRoot":"","sources":["../src/aws.ts"],"names":[],"mappings":";;;AAEA,kDAA4C;AAC5C,iCAAqD;AACrD,2DAK4B;AAQ5B;;GAEG;AACU,QAAA,aAAa,GAAkB,MAAM,CAAC,eAAe,CAAC,CAAA;AAEnE;;;GAGG;AACH,MAAM,KAAK,GAAG,EAAE,CAAA;AAoDhB;;;GAGG;AACH,MAAM,YAAY,GAAkC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;AAErE;;;;GAIG;AACI,MAAM,YAAY,GAAG,CAAC,OAAyB,EAAkB,EAAE;IACtE,MAAM,cAAc,GAAmB,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE;QACrE,MAAM,GAAG,GAAG,IAAA,mBAAQ,EAAM,OAAO,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC,MAAM,CAAC,qBAAa,CAAC,CAAA;QAElF,OAAO;YACH,GAAG,IAAI;YACP,CAAC,GAAG,CAAC,EAAE,IAAA,mBAAQ,EAAC,IAAI,CAAC,GAAG,CAAC,CAAC;iBACrB,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC;iBACzB,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC;SACzB,CAAA;IACL,CAAC,CAAC,EAAE,YAAY,CAAC,CAAA;IAEjB,OAAO,cAAc,CAAA;AACzB,CAAC,CAAA;AAbY,QAAA,YAAY,gBAaxB;AAED;;;;;GAKG;AACI,MAAM,eAAe,GAAG,CAAgB,OAAkC,EAAE,EAAE,CACjF,CAAC,YAA2D,EAAE,EAAE,CAC5D,CAAC,eAA6C,EAAE,EAAE,CAC9C,CAAC,iBAAmD,EAAE,EAAE,CACpD,KAAK,EAAE,KAAe,EAA+C,EAAE;IAEnE,MAAM,cAAc,GAAG,YAAY,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;IAElD,MAAM,cAAc,GAAG,MAAM,IAAA,gBAAQ,EAAC,OAAO,CAAC,OAAO,CAAC,cAAc,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,GAAQ,EAAE,EAAE;QAC7F,MAAM,MAAM,GAAG,cAAc,CAAC,GAAG,CAAC,CAAA;QAElC,MAAM,cAAc,GAA2B;YAC3C,CAAC,uCAAmB,CAAC,IAAI,CAAC,EAAE,EAAE;YAC9B,CAAC,uCAAmB,CAAC,OAAO,CAAC,EAAE,EAAE;YACjC,CAAC,uCAAmB,CAAC,OAAO,CAAC,EAAE,EAAE;YACjC,CAAC,uCAAmB,CAAC,KAAK,CAAC,EAAE,EAAE;SAClC,CAAA;QACD,MAAM,cAAc,GAAG,MAAM,IAAA,cAAM,EAAC,MAAM,EAAE,cAAc,EAAE,KAAK,EAAE,IAA4B,EAAE,OAAkB,EAAE,EAAE;YACnH,MAAM,UAAU,GAAG,MAAM,eAAe,CAAC,OAAO,CAAC,CAAA;YAEjD,IAAI,UAAU,CAAC,OAAO,EAAE,CAAC;gBACrB,MAAM,aAAa,GAA8D;oBAC7E,OAAO,EAAE,SAAU;oBACnB,MAAM,EAAE,uCAAmB,CAAC,OAAO;oBACnC,MAAM,EAAE,SAAS;oBACjB,KAAK,EAAE,IAAI,KAAK,CAAC,qBAAqB,CAAC;iBAC1C,CAAA;gBAED,MAAM,aAAa,GAAiC;oBAChD,OAAO,EAAE,OAAO;oBAChB,MAAM,EAAE,aAAa;iBACxB,CAAA;gBAED,MAAM,OAAO,GAA2B;oBACpC,GAAG,IAAI;oBACP,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE,aAAa,CAAC;iBACzE,CAAA;gBAED,OAAO,OAAO,CAAA;YAClB,CAAC;YAED,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAA;YAE9B;;;;;eAKG;YACH,IAAI,GAAG,KAAK,qBAAa,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACjD,MAAM,aAAa,GAAiC;oBAChD,OAAO,EAAE,OAAO;oBAChB,MAAM,EAAE;wBACJ,OAAO,EAAE,UAAU,CAAC,MAAM,CAAC,SAAU,CAAC;wBACtC,MAAM,EAAE,uCAAmB,CAAC,KAAK;wBACjC,MAAM,EAAE,SAAS;wBACjB,KAAK,EAAE,SAAS;qBACnB;iBACJ,CAAA;gBAED,MAAM,OAAO,GAA2B;oBACpC,GAAG,IAAI;oBACP,CAAC,aAAa,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,aAAa,CAAC;iBACvF,CAAA;gBAED,OAAO,OAAO,CAAA;YAClB,CAAC;YAED,MAAM,aAAa,GAAkC,MAAM,OAAO,CAAC,KAAK,CAAC;iBACpE,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,iBAAiB,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC,CAAA;YAE/D,MAAM,aAAa,GAAiC;gBAChD,OAAO,EAAE,OAAO;gBAChB,MAAM,EAAE,aAAa;aACxB,CAAA;YAED,MAAM,OAAO,GAA2B;gBACpC,GAAG,IAAI;gBACP,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE,aAAa,CAAC;aACzE,CAAA;YAED,OAAO,OAAO,CAAA;QAClB,CAAC,CAAC,CAAA;QAEF,MAAM,YAAY,GAAgC;YAC9C,KAAK,EAAE,GAAG;YACV,OAAO,EAAE,cAAc;SAC1B,CAAA;QACD,OAAO,YAAY,CAAA;IACvB,CAAC,CAAC,CAAA;IAEF,OAAO,cAAc,CAAA;AACzB,CAAC,CAAA;AA5FJ,QAAA,eAAe,mBA4FX;AAEjB;;;;GAIG;AACI,MAAM,wBAAwB,GAAG,CAAC,uBAAoG,EAAE,EAAE,CAC7I,CAAC,WAAwD,EAAE,EAAE,CACzD,CAAC,QAAuB,EAAE,EAAE,CACxB,KAAK,EAAiB,YAAgD,EAA+C,EAAE;IACnH,MAAM,OAAO,CAAC,UAAU,CAAC,YAAY,CAAC,GAAG,CAAC,KAAK,EAAC,OAAO,EAAC,EAAE;QACtD,MAAM,IAAA,qBAAa,EAAC,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,EAAC,aAAa,EAAC,EAAE;YAC7D,MAAM,YAAY,GAAG,MAAM,CAAC,aAAa,CAAC,OAAO,CAAC,UAAU,CAAC,uBAAuB,CAAC,CAAA;YACrF,MAAM,YAAY,GAAG,YAAY,GAAG,CAAC,IAAI,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,YAAY,GAAG,CAAC,CAAA;YAEjG,MAAM,iBAAiB,GAAG,QAAQ,CAAC,YAAY,CAAC,CAAA;YAEhD,MAAM,uBAAuB,CAAC;gBAC1B,aAAa,EAAE,aAAa,CAAC,OAAO,CAAC,aAAa;gBAClD,KAAK,EAAE,WAAW,CAAC;oBACf,QAAQ,EAAE,aAAa,CAAC,OAAO,CAAC,cAAc;iBACjD,CAAC,CAAC,QAAQ;gBACX,OAAO,EAAE,iBAAiB;aAC7B,CAAC,CAAA;QACN,CAAC,CAAC,CAAA;IACN,CAAC,CAAC,CAAC,CAAA;IAEH,OAAO,YAAY,CAAA;AACvB,CAAC,CAAA;AAtBA,QAAA,wBAAwB,4BAsBxB;AAgBb;;;;;GAKG;AACI,MAAM,YAAY,GAAG,CAAgB,WAA6E,EAAE,EAAE,CACzH,KAAK,EAAE,YAAgD,EAA+C,EAAE;IACpG,MAAM,OAAO,CAAC,UAAU,CAAC,YAAY,CAAC,GAAG,CAAC,KAAK,EAAC,OAAO,EAAC,EAAE;QACtD,MAAM,IAAA,qBAAa,EAAC,OAAO,CAAC,OAAO,CAAC,OAAO,EAAE,KAAK,EAAC,aAAa,EAAC,EAAE;YAC/D,MAAM,WAAW,CAAC;gBACd,OAAO,EAAE,aAAa,CAAC,OAAO;gBAC9B,KAAK,EAAE;oBACH,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,KAAM,CAAC,OAAO;oBAC5C,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,KAAM,CAAC,IAAI;oBACtC,KAAK,EAAE,aAAa,CAAC,MAAM,CAAC,KAAM,CAAC,KAAK;iBAC3C;aACJ,CAAC,CAAA;QACN,CAAC,CAAC,CAAA;IACN,CAAC,CAAC,CAAC,CAAA;IAEH,OAAO,YAAY,CAAA;AACvB,CAAC,CAAA;AAhBQ,QAAA,YAAY,gBAgBpB;AAEL;;;;;GAKG;AACI,MAAM,kBAAkB,GAAG,KAAK,EAAiB,YAAgD,EAA6B,EAAE;IACnI,MAAM,QAAQ,GAAqB;QAC/B,iBAAiB,EAAE,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC;aACpD,IAAI,EAAE;aACN,GAAG,CAAC,CAAC,CAAC,EAAE;YACL,OAAO;gBACH,cAAc,EAAE,CAAC,CAAC,OAAO,CAAC,aAAa;aAC1C,CAAA;QACL,CAAC,CAAC;KACT,CAAA;IAED,OAAO,QAAQ,CAAA;AACnB,CAAC,CAAA;AAZY,QAAA,kBAAkB,sBAY9B;AAED;;;;;GAKG;AACI,MAAM,+BAA+B,GAAG,CAAgB,eAAiF,EAAE,EAAE,CAChJ,CAAC,wBAA2H,EAAE,EAAE,CAC5H,CAAC,YAA+G,EAAE,EAAE,CAChH,CAAC,kBAAmG,EAAE,EAAE,CACpG,KAAK,EAAE,KAAe,EAA6B,EAAE;IACjD,OAAO,eAAe,CAAC,KAAK,CAAC;SACxB,IAAI,CAAC,YAAY,CAAC;SAClB,IAAI,CAAC,wBAAwB,CAAC;SAC9B,IAAI,CAAC,kBAAkB,CAAC,CAAA;AACjC,CAAC,CAAA;AATJ,QAAA,+BAA+B,mCAS3B"}
|
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { RunProcess } from './aws';
|
|
2
|
+
import { SQSRecord } from 'aws-lambda';
|
|
3
|
+
import { LoggingProps } from '@othree.io/journal';
|
|
4
|
+
export * from './results-processor';
|
|
5
|
+
export * as aws from './aws';
|
|
6
|
+
/**
|
|
7
|
+
* Interface representing the configuration for an SQS Process.
|
|
8
|
+
* @interface
|
|
9
|
+
*/
|
|
10
|
+
export interface SQSProcessConfiguration {
|
|
11
|
+
readonly dlqUrl: string;
|
|
12
|
+
readonly exponentialTimeouts: Array<number>;
|
|
13
|
+
}
|
|
14
|
+
type Log = <Input, Output>(fn: (...args: Input[]) => Promise<Output>) => (context: string, loggingProps?: LoggingProps) => (...args: Input[]) => Promise<Output>;
|
|
15
|
+
/**
|
|
16
|
+
* Processes SQS messages with the given configuration and handlers.
|
|
17
|
+
* @param {SQSProcessConfiguration} configuration - The SQS configuration.
|
|
18
|
+
* @returns {Function} A function that takes a didItFail function and returns a function to process SQS events.
|
|
19
|
+
*/
|
|
20
|
+
export declare const processSqs: (log?: Log) => (configuration: SQSProcessConfiguration) => (didItFail: (error: Error) => boolean) => <Input, Output>(runProcess: RunProcess<Input, Output>) => (getProcessInput: RunProcess<SQSRecord, Input>) => (...args: import("aws-lambda").SQSEvent[]) => Promise<import("aws-lambda").SQSBatchResponse>;
|
|
21
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAMH,UAAU,EACb,MAAM,OAAO,CAAA;AACd,OAAO,EAAC,SAAS,EAAC,MAAM,YAAY,CAAA;AAKpC,OAAO,EAAC,YAAY,EAAC,MAAM,oBAAoB,CAAA;AAG/C,cAAc,qBAAqB,CAAA;AACnC,OAAO,KAAK,GAAG,MAAM,OAAO,CAAA;AAE5B;;;GAGG;AACH,MAAM,WAAW,uBAAuB;IACpC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,mBAAmB,EAAE,KAAK,CAAC,MAAM,CAAC,CAAA;CAC9C;AAED,KAAK,GAAG,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,YAAY,KAAK,CAAC,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,OAAO,CAAC,MAAM,CAAC,CAAA;AAChK;;;;GAIG;AACH,eAAO,MAAM,UAAU,GAAI,MAAM,GAAG,MAC/B,eAAe,uBAAuB,MAClC,WAAW,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,MAChC,KAAK,EAAE,MAAM,EAAE,YAAY,UAAU,CAAC,KAAK,EAAE,MAAM,CAAC,MAChD,iBAAiB,UAAU,CAAC,SAAS,EAAE,KAAK,CAAC,iGA2B7C,CAAA"}
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.processSqs = exports.aws = void 0;
|
|
18
|
+
const aws_1 = require("./aws");
|
|
19
|
+
const results_processor_1 = require("./results-processor");
|
|
20
|
+
const client_sqs_1 = require("@aws-sdk/client-sqs");
|
|
21
|
+
const awsome_1 = require("@othree.io/awsome");
|
|
22
|
+
const optional_1 = require("@othree.io/optional");
|
|
23
|
+
const sqs_1 = require("@othree.io/awsome/lib/sqs");
|
|
24
|
+
__exportStar(require("./results-processor"), exports);
|
|
25
|
+
exports.aws = require("./aws");
|
|
26
|
+
/**
|
|
27
|
+
* Processes SQS messages with the given configuration and handlers.
|
|
28
|
+
* @param {SQSProcessConfiguration} configuration - The SQS configuration.
|
|
29
|
+
* @returns {Function} A function that takes a didItFail function and returns a function to process SQS events.
|
|
30
|
+
*/
|
|
31
|
+
const processSqs = (log) => (configuration) => (didItFail) => (runProcess) => (getProcessInput) => {
|
|
32
|
+
const maybeLog = (0, optional_1.Optional)(log);
|
|
33
|
+
const processSQSEventFn = maybeLog
|
|
34
|
+
.map(_ => _((0, aws_1.processSQSEvent)(runProcess)(aws_1.groupRecords)(getProcessInput)((0, results_processor_1.getProcessResults)(didItFail)))('processSQSEvent'))
|
|
35
|
+
.orElse((0, aws_1.processSQSEvent)(runProcess)(aws_1.groupRecords)(getProcessInput)((0, results_processor_1.getProcessResults)(didItFail)));
|
|
36
|
+
const sqsClient = new client_sqs_1.SQSClient({});
|
|
37
|
+
const changeMessageVisibilityTimeout = maybeLog
|
|
38
|
+
.map(_ => _(awsome_1.sqs.changeMessageVisibilityTimeout(sqsClient))('changeMessageVisibilityTimeout'))
|
|
39
|
+
.orElse(awsome_1.sqs.changeMessageVisibilityTimeout(sqsClient));
|
|
40
|
+
const handleExponentialBackoffFn = maybeLog
|
|
41
|
+
.map(_ => _((0, aws_1.handleExponentialBackoff)(changeMessageVisibilityTimeout)(sqs_1.getQueueUrl)(configuration.exponentialTimeouts))('handleExponentialBackoff'))
|
|
42
|
+
.orElse((0, aws_1.handleExponentialBackoff)(changeMessageVisibilityTimeout)(sqs_1.getQueueUrl)(configuration.exponentialTimeouts));
|
|
43
|
+
const sendDLQMessage = awsome_1.sqs.send(sqsClient, {
|
|
44
|
+
QueueUrl: configuration.dlqUrl,
|
|
45
|
+
})()()()();
|
|
46
|
+
const handleErrorsFn = maybeLog
|
|
47
|
+
.map(_ => _((0, aws_1.handleErrors)(sendDLQMessage))('handleErrors'))
|
|
48
|
+
.orElse((0, aws_1.handleErrors)(sendDLQMessage));
|
|
49
|
+
return maybeLog
|
|
50
|
+
.map(_ => _((0, aws_1.processSQSEventAndHandleResults)(processSQSEventFn)(handleExponentialBackoffFn)(handleErrorsFn)(aws_1.toSQSBatchResponse))('processSQSEventAndHandleResults'))
|
|
51
|
+
.orElse((0, aws_1.processSQSEventAndHandleResults)(processSQSEventFn)(handleExponentialBackoffFn)(handleErrorsFn)(aws_1.toSQSBatchResponse));
|
|
52
|
+
};
|
|
53
|
+
exports.processSqs = processSqs;
|
|
54
|
+
//# sourceMappingURL=index.js.map
|
package/lib/index.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,+BAOc;AAEd,2DAAqD;AACrD,oDAA6C;AAC7C,8CAAqC;AACrC,kDAA4C;AAE5C,mDAAqD;AAErD,sDAAmC;AACnC,+BAA4B;AAY5B;;;;GAIG;AACI,MAAM,UAAU,GAAG,CAAC,GAAS,EAAE,EAAE,CACpC,CAAC,aAAsC,EAAE,EAAE,CACvC,CAAC,SAAoC,EAAE,EAAE,CACrC,CAAgB,UAAqC,EAAE,EAAE,CACrD,CAAC,eAA6C,EAAE,EAAE;IAC9C,MAAM,QAAQ,GAAG,IAAA,mBAAQ,EAAC,GAAG,CAAC,CAAA;IAC9B,MAAM,iBAAiB,GAAG,QAAQ;SAC7B,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAA,qBAAe,EAAgB,UAAU,CAAC,CAAC,kBAAY,CAAC,CAAC,eAAe,CAAC,CAAC,IAAA,qCAAiB,EAAC,SAAS,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC;SACvI,MAAM,CAAC,IAAA,qBAAe,EAAgB,UAAU,CAAC,CAAC,kBAAY,CAAC,CAAC,eAAe,CAAC,CAAC,IAAA,qCAAiB,EAAC,SAAS,CAAC,CAAC,CAAC,CAAA;IAEpH,MAAM,SAAS,GAAG,IAAI,sBAAS,CAAC,EAAE,CAAC,CAAA;IAEnC,MAAM,8BAA8B,GAAG,QAAQ;SAC1C,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,YAAG,CAAC,8BAA8B,CAAC,SAAS,CAAC,CAAC,CAAC,gCAAgC,CAAC,CAAC;SAC5F,MAAM,CAAC,YAAG,CAAC,8BAA8B,CAAC,SAAS,CAAC,CAAC,CAAA;IAE1D,MAAM,0BAA0B,GAAG,QAAQ;SACtC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAA,8BAAwB,EAAC,8BAA8B,CAAC,CAAC,iBAAW,CAAC,CAAC,aAAa,CAAC,mBAAmB,CAAC,CAAC,CAAC,0BAA0B,CAAC,CAAC;SACjJ,MAAM,CAAC,IAAA,8BAAwB,EAAC,8BAA8B,CAAC,CAAC,iBAAW,CAAC,CAAC,aAAa,CAAC,mBAAmB,CAAC,CAAC,CAAA;IAErH,MAAM,cAAc,GAAG,YAAG,CAAC,IAAI,CAAC,SAAS,EAAE;QACvC,QAAQ,EAAE,aAAa,CAAC,MAAM;KACjC,CAAC,EAAE,EAAE,EAAE,EAAE,CAAA;IAEV,MAAM,cAAc,GAAG,QAAQ;SAC1B,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAA,kBAAY,EAAgB,cAAc,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC;SACxE,MAAM,CAAC,IAAA,kBAAY,EAAgB,cAAc,CAAC,CAAC,CAAA;IAExD,OAAO,QAAQ;SACV,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAA,qCAA+B,EAAgB,iBAAiB,CAAC,CAAC,0BAAiC,CAAC,CAAC,cAAc,CAAC,CAAC,wBAAkB,CAAC,CAAC,CAAC,iCAAiC,CAAC,CAAC;SACxL,MAAM,CAAC,IAAA,qCAA+B,EAAgB,iBAAiB,CAAC,CAAC,0BAAiC,CAAC,CAAC,cAAc,CAAC,CAAC,wBAAkB,CAAC,CAAC,CAAA;AACzJ,CAAC,CAAA;AA/BJ,QAAA,UAAU,cA+BN"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { Optional } from '@othree.io/optional';
|
|
2
|
+
/**
|
|
3
|
+
* Enumeration representing possible process result actions.
|
|
4
|
+
* @enum {string}
|
|
5
|
+
*/
|
|
6
|
+
export declare enum ProcessResultAction {
|
|
7
|
+
success = "success",
|
|
8
|
+
failure = "failure",
|
|
9
|
+
none = "none",
|
|
10
|
+
retry = "retry"
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Represents the result of a process with different possible outcomes.
|
|
14
|
+
* @interface
|
|
15
|
+
* @template Input - The type of the input for the process.
|
|
16
|
+
* @template Output - The type of the output of a successful process.
|
|
17
|
+
* @template Action - The type of action representing the result's status.
|
|
18
|
+
*/
|
|
19
|
+
export interface ProcessResult<Input, Output, Action extends ProcessResultAction> {
|
|
20
|
+
readonly request: Input;
|
|
21
|
+
readonly action: Action;
|
|
22
|
+
readonly result: Action extends ProcessResultAction.success ? Output : void;
|
|
23
|
+
readonly error: Action extends ProcessResultAction.failure ? Error : void;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Represents different possible process results.
|
|
27
|
+
* @typedef {ProcessResult<Input, Output, ProcessResultAction.failure> |
|
|
28
|
+
* ProcessResult<Input, Output, ProcessResultAction.success> |
|
|
29
|
+
* ProcessResult<Input, Output, ProcessResultAction.none> |
|
|
30
|
+
* ProcessResult<Input, Output, ProcessResultAction.retry> |} ProcessResults
|
|
31
|
+
* @template Input - The type of the input for the process.
|
|
32
|
+
* @template Output - The type of the output of a successful process.
|
|
33
|
+
*/
|
|
34
|
+
export type ProcessResults<Input, Output> = ProcessResult<Input, Output, ProcessResultAction.failure> | ProcessResult<Input, Output, ProcessResultAction.success> | ProcessResult<Input, Output, ProcessResultAction.none> | ProcessResult<Input, Output, ProcessResultAction.retry>;
|
|
35
|
+
export type GetProcessResults<Input, Output> = (input: Input, maybeResult: Optional<Output>) => Promise<ProcessResults<Input, Output>>;
|
|
36
|
+
/**
|
|
37
|
+
* Generates process results based on input, possible result, and error handling.
|
|
38
|
+
*
|
|
39
|
+
* @param {Function} didItFail - The input data for the process.
|
|
40
|
+
* @template Function - Generates process results based on input, possible result, and error handling.
|
|
41
|
+
*/
|
|
42
|
+
export declare const getProcessResults: (didItFail: (error: Error) => boolean) => <Input, Output>(input: Input, maybeResult: Optional<Output>) => Promise<ProcessResults<Input, Output>>;
|
|
43
|
+
//# 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;;;GAGG;AACH,oBAAY,mBAAmB;IAC3B,OAAO,YAAY;IACnB,OAAO,YAAY;IACnB,IAAI,SAAS;IACb,KAAK,UAAU;CAClB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,mBAAmB;IAC5E,QAAQ,CAAC,OAAO,EAAE,KAAK,CAAA;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,SAAS,mBAAmB,CAAC,OAAO,GAAG,MAAM,GAAG,IAAI,CAAA;IAC3E,QAAQ,CAAC,KAAK,EAAE,MAAM,SAAS,mBAAmB,CAAC,OAAO,GAAG,KAAK,GAAG,IAAI,CAAA;CAC5E;AAED;;;;;;;;GAQG;AACH,MAAM,MAAM,cAAc,CAAC,KAAK,EAAE,MAAM,IAAI,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,mBAAmB,CAAC,OAAO,CAAC,GAC/F,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,mBAAmB,CAAC,OAAO,CAAC,GACzD,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,mBAAmB,CAAC,IAAI,CAAC,GACtD,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,mBAAmB,CAAC,KAAK,CAAC,CAAA;AAG7D,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;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,GAAI,WAAW,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,MAS3D,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,71 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getProcessResults = exports.ProcessResultAction = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Enumeration representing possible process result actions.
|
|
6
|
+
* @enum {string}
|
|
7
|
+
*/
|
|
8
|
+
var ProcessResultAction;
|
|
9
|
+
(function (ProcessResultAction) {
|
|
10
|
+
ProcessResultAction["success"] = "success";
|
|
11
|
+
ProcessResultAction["failure"] = "failure";
|
|
12
|
+
ProcessResultAction["none"] = "none";
|
|
13
|
+
ProcessResultAction["retry"] = "retry";
|
|
14
|
+
})(ProcessResultAction || (exports.ProcessResultAction = ProcessResultAction = {}));
|
|
15
|
+
/**
|
|
16
|
+
* Generates process results based on input, possible result, and error handling.
|
|
17
|
+
*
|
|
18
|
+
* @param {Function} didItFail - The input data for the process.
|
|
19
|
+
* @template Function - Generates process results based on input, possible result, and error handling.
|
|
20
|
+
*/
|
|
21
|
+
const getProcessResults = (didItFail) =>
|
|
22
|
+
/**
|
|
23
|
+
* Generates process results based on input, possible result, and error handling.
|
|
24
|
+
*
|
|
25
|
+
* @param {Input} input - The input data for the process.
|
|
26
|
+
* @param {Optional<Output>} maybeResult - The optional result of the process.
|
|
27
|
+
* @returns {Promise<ProcessResults<Input, Output>>} A promise resolving to process results.
|
|
28
|
+
* @template Output - The type of the output of a successful process.
|
|
29
|
+
*/
|
|
30
|
+
async (input, maybeResult) => {
|
|
31
|
+
return maybeResult
|
|
32
|
+
.map(result => {
|
|
33
|
+
const successfulResult = {
|
|
34
|
+
request: input,
|
|
35
|
+
action: ProcessResultAction.success,
|
|
36
|
+
result: result,
|
|
37
|
+
error: undefined,
|
|
38
|
+
};
|
|
39
|
+
return successfulResult;
|
|
40
|
+
})
|
|
41
|
+
.orMap(() => {
|
|
42
|
+
const noResult = {
|
|
43
|
+
request: input,
|
|
44
|
+
action: ProcessResultAction.none,
|
|
45
|
+
result: undefined,
|
|
46
|
+
error: undefined,
|
|
47
|
+
};
|
|
48
|
+
return noResult;
|
|
49
|
+
})
|
|
50
|
+
.catchAsync(async (error) => {
|
|
51
|
+
if (didItFail(error)) {
|
|
52
|
+
const failureResult = {
|
|
53
|
+
request: input,
|
|
54
|
+
action: ProcessResultAction.failure,
|
|
55
|
+
result: undefined,
|
|
56
|
+
error: error,
|
|
57
|
+
};
|
|
58
|
+
return failureResult;
|
|
59
|
+
}
|
|
60
|
+
const retryResult = {
|
|
61
|
+
request: input,
|
|
62
|
+
action: ProcessResultAction.retry,
|
|
63
|
+
result: undefined,
|
|
64
|
+
error: undefined,
|
|
65
|
+
};
|
|
66
|
+
return retryResult;
|
|
67
|
+
})
|
|
68
|
+
.then(_ => _.get());
|
|
69
|
+
};
|
|
70
|
+
exports.getProcessResults = getProcessResults;
|
|
71
|
+
//# sourceMappingURL=results-processor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"results-processor.js","sourceRoot":"","sources":["../src/results-processor.ts"],"names":[],"mappings":";;;AAEA;;;GAGG;AACH,IAAY,mBAKX;AALD,WAAY,mBAAmB;IAC3B,0CAAmB,CAAA;IACnB,0CAAmB,CAAA;IACnB,oCAAa,CAAA;IACb,sCAAe,CAAA;AACnB,CAAC,EALW,mBAAmB,mCAAnB,mBAAmB,QAK9B;AAiCD;;;;;GAKG;AACI,MAAM,iBAAiB,GAAG,CAAC,SAAoC,EAAE,EAAE;AACtE;;;;;;;GAOG;AACH,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,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;YACnB,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;AAnDQ,QAAA,iBAAiB,qBAmDzB"}
|
package/package.json
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@othree.io/stethoscope",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Stethoscope",
|
|
5
|
+
"main": "lib/index.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"test": "jest",
|
|
8
|
+
"build": "tsc",
|
|
9
|
+
"semantic-release": "semantic-release"
|
|
10
|
+
},
|
|
11
|
+
"keywords": [
|
|
12
|
+
"stethoscope"
|
|
13
|
+
],
|
|
14
|
+
"author": "othree",
|
|
15
|
+
"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"
|
|
21
|
+
},
|
|
22
|
+
"devDependencies": {
|
|
23
|
+
"@types/async": "^3.2.24",
|
|
24
|
+
"@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",
|
|
29
|
+
"semantic-release": "^21.1.1",
|
|
30
|
+
"ts-jest": "^29.0.5",
|
|
31
|
+
"typescript": "^5.0.2"
|
|
32
|
+
},
|
|
33
|
+
"publishConfig": {
|
|
34
|
+
"access": "public"
|
|
35
|
+
}
|
|
36
|
+
}
|