woonplan-packages-redishelper 2.1.4 → 2.1.51

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.
@@ -1,3 +1,3 @@
1
- {
2
- "svn.ignoreMissingSvnWarning": true
1
+ {
2
+ "svn.ignoreMissingSvnWarning": true
3
3
  }
@@ -0,0 +1,54 @@
1
+
2
+ import { Broker } from "./main";
3
+ interface JsonStringifiedMap{
4
+ dataType : 'Map',
5
+ value : any[]
6
+ }
7
+
8
+ interface RedisMessage{
9
+ [index: string]: any;
10
+ }
11
+ interface Struct{
12
+ [index: string]: any;
13
+ }
14
+
15
+ interface RedisConfig{
16
+ REDISURL: string | number | undefined
17
+ REDISPW: string | undefined
18
+ }
19
+
20
+ interface RedisStreamEntry{
21
+ id : string
22
+ message:RedisMessage
23
+ }
24
+
25
+ type StreamMessage = [
26
+ string, StreamMessageParameters
27
+ ]
28
+
29
+ type StreamMessageParameters = string[]
30
+ type StreamResponse = [
31
+ string, StreamMessage[]
32
+ ]
33
+
34
+ interface DecypheredParameters{
35
+ [index:string] : string | number
36
+ }
37
+
38
+ interface DecypheredMessage{
39
+ id : string
40
+ parameters : DecypheredParameters
41
+ }
42
+
43
+ interface DecypheredResponse{
44
+ stream : string,
45
+ messages : DecypheredMessage[]
46
+ }
47
+
48
+ interface RollbarConfig{
49
+ accessToken : string
50
+ environment : string
51
+ }
52
+
53
+
54
+ export { RollbarConfig,DecypheredResponse,DecypheredMessage, DecypheredParameters, StreamMessage, StreamResponse, Struct, JsonStringifiedMap, RedisConfig, Broker }
@@ -0,0 +1,63 @@
1
+ /// <reference types="node" />
2
+ import IORedis, { Redis } from "ioredis";
3
+ import Rollbar from "rollbar";
4
+ import Listener from "./Listener";
5
+ import { DecypheredMessage, DecypheredParameters, DecypheredResponse, RedisConfig, RollbarConfig, StreamMessage, StreamResponse, Struct } from "../types";
6
+ declare type Rejector = (reason?: any) => void;
7
+ declare type Resolver = (value?: any) => void;
8
+ export default class Broker {
9
+ redisConfig: RedisConfig;
10
+ rollbar?: Rollbar;
11
+ consumername: string;
12
+ listeners: Map<string, Listener>;
13
+ writer: Redis;
14
+ reader: Redis;
15
+ listprefix: string;
16
+ service: string;
17
+ subscriptions: string[];
18
+ rejectors: Map<string, Rejector>;
19
+ resolvers: Map<string, Resolver>;
20
+ timeouts: Map<string, NodeJS.Timeout>;
21
+ requestendpoint?: Function;
22
+ constructor(redisConfig: RedisConfig, rollbarConfig: RollbarConfig, service: string, consumer: string);
23
+ get requeststream(): string;
24
+ getRequestStream(service: string): string;
25
+ createClient(): IORedis;
26
+ createSetWatcher(setname: string, callback: Function, finishedCallback?: Function, itemsPerCall?: number): void;
27
+ setRequestEndpoint(callback: Function): this;
28
+ getRequestCallback(callback: Function): (id: string, parameters: DecypheredParameters) => Promise<number | null>;
29
+ publish(channel: string, result: string): Promise<number>;
30
+ createGroup(stream: string, group: string): Promise<void>;
31
+ addListener(stream: string, callback: Function, group?: string, deleteOnCompletion?: boolean): this;
32
+ createListener(client: Redis, stream: string, callback: Function, group?: string, deleteOnCompletion?: boolean): Promise<void>;
33
+ addListListener(event: string, callback: Function, finishedevent?: string, itemsPerCall?: number): this;
34
+ getList(listname: string, start?: number, stop?: number): Promise<string[]>;
35
+ getSet(listname: string): Promise<string[]>;
36
+ throwError(error: Error): void;
37
+ sendMessage(stream: string, data: Struct, updatecontactid?: string): Promise<string | null>;
38
+ sendMessageAndSubscribeForResponse(channel: string, target: string, messagedata: Struct, n?: number): Promise<unknown>;
39
+ getRequest(targetservice: string, key: string, data: Struct, timeout?: number): Promise<unknown>;
40
+ getApiRequest(endpoint: string, method: "GET" | "POST" | "PUT" | "DELETE", data: {}, jwt?: string, timeout?: number): Promise<unknown>;
41
+ requestMessageResponse(channel: string, resolver: Resolver, rejector: Rejector, timeout: NodeJS.Timeout): void;
42
+ cleanupMessageReponse(channel: string): void;
43
+ onMessage(channel: string, message: any): void;
44
+ unsubscribe(channel: string): void;
45
+ setupTimeout(resolve: (value?: any) => void, channel: string, n?: number): NodeJS.Timeout;
46
+ subscribe(channel: string): Promise<unknown>;
47
+ getRequestSubscriptionName(messageid: string): string;
48
+ setKey(key: string, value: any): Promise<"OK" | undefined>;
49
+ readKey(key: string): Promise<string | null>;
50
+ deleteKey(key: string): Promise<number | undefined>;
51
+ sendListEvent(event: string, listitems: any[], data?: Struct, listname?: string): Promise<string | null | undefined>;
52
+ addToSet(listitems: any[], listname?: string): Promise<string>;
53
+ addToList(listitems: any[], listname?: string): Promise<string>;
54
+ getListChannel(event: string): string;
55
+ getStreamMessages(stream: string): Promise<DecypheredMessage[]>;
56
+ getStreamInfo(stream: string, count?: number): Promise<any[] | null>;
57
+ filterStream(stream: string, key: string, value: any): Promise<DecypheredMessage[]>;
58
+ decypherResponse(...responses: StreamResponse[]): DecypheredResponse[];
59
+ decyperMessages(messages: StreamMessage[]): DecypheredMessage[];
60
+ decypherParameters(parameters: string[]): DecypheredParameters;
61
+ isSetPickedUp(setname: string): Promise<boolean>;
62
+ }
63
+ export {};
@@ -0,0 +1,347 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ const class_validator_1 = require("class-validator");
5
+ const ioredis_1 = tslib_1.__importDefault(require("ioredis"));
6
+ const rollbar_1 = tslib_1.__importDefault(require("rollbar"));
7
+ const utils_1 = require("../services/utils");
8
+ const Listener_1 = tslib_1.__importDefault(require("./Listener"));
9
+ const ListListener_1 = tslib_1.__importDefault(require("./ListListener"));
10
+ const crypto_1 = require("crypto");
11
+ const lock_1 = require("../services/lock");
12
+ const SetWatcher_1 = tslib_1.__importDefault(require("./SetWatcher"));
13
+ class Broker {
14
+ constructor(redisConfig, rollbarConfig, service, consumer) {
15
+ this.consumername = '';
16
+ this.listeners = new Map();
17
+ this.listprefix = 'listUpdated';
18
+ this.subscriptions = [];
19
+ this.rejectors = new Map;
20
+ this.resolvers = new Map;
21
+ this.timeouts = new Map;
22
+ this.redisConfig = redisConfig;
23
+ this.rollbar = new rollbar_1.default({
24
+ accessToken: rollbarConfig.accessToken,
25
+ environment: rollbarConfig.environment,
26
+ });
27
+ this.writer = new ioredis_1.default({
28
+ host: redisConfig.REDISURL,
29
+ password: redisConfig.REDISPW ?? ''
30
+ });
31
+ this.reader = new ioredis_1.default({
32
+ host: redisConfig.REDISURL,
33
+ password: redisConfig.REDISPW ?? ''
34
+ });
35
+ (0, lock_1.setupLock)(redisConfig);
36
+ this.reader.on('message', (channel, message) => this.onMessage.call(this, channel, message));
37
+ this.consumername = consumer;
38
+ this.service = service;
39
+ }
40
+ get requeststream() {
41
+ return this.getRequestStream(this.service);
42
+ }
43
+ getRequestStream(service) {
44
+ return `keyRequestedFrom${(0, utils_1.capitalizeFirstLetter)(service)}Service`;
45
+ }
46
+ createClient() {
47
+ return new ioredis_1.default({
48
+ host: this.redisConfig.REDISURL,
49
+ password: this.redisConfig.REDISPW ?? ''
50
+ });
51
+ }
52
+ createSetWatcher(setname, callback, finishedCallback, itemsPerCall = 1) {
53
+ new SetWatcher_1.default(this.createClient.call(this), setname, callback, finishedCallback, itemsPerCall);
54
+ }
55
+ setRequestEndpoint(callback) {
56
+ this.addListener(this.requeststream, this.getRequestCallback(callback), this.service);
57
+ this.addListener(this.requeststream, this.getRequestCallback(callback), this.service);
58
+ this.addListener(this.requeststream, this.getRequestCallback(callback), this.service);
59
+ this.addListener(this.requeststream, this.getRequestCallback(callback), this.service);
60
+ this.addListener(this.requeststream, this.getRequestCallback(callback), this.service);
61
+ return this;
62
+ }
63
+ getRequestCallback(callback) {
64
+ return async (id, parameters) => {
65
+ let result = null;
66
+ try {
67
+ result = await callback(id, parameters);
68
+ }
69
+ catch (error) {
70
+ this.throwError(error);
71
+ result = JSON.stringify({
72
+ rejected: true,
73
+ error: {
74
+ title: error?.message ?? ''
75
+ }
76
+ });
77
+ }
78
+ finally {
79
+ if (!parameters.messageid)
80
+ return null;
81
+ const channel = this.getRequestSubscriptionName(parameters.messageid);
82
+ return this.publish(channel, result);
83
+ }
84
+ };
85
+ }
86
+ publish(channel, result) {
87
+ return this.writer.publish(channel, result);
88
+ }
89
+ async createGroup(stream, group) {
90
+ try {
91
+ await this.writer.xgroup('CREATE', stream, group, '$', 'MKSTREAM');
92
+ return;
93
+ }
94
+ catch {
95
+ return;
96
+ }
97
+ }
98
+ addListener(stream, callback, group, deleteOnCompletion = false) {
99
+ const client = new ioredis_1.default({
100
+ host: this.redisConfig.REDISURL,
101
+ password: this.redisConfig.REDISPW ?? ''
102
+ });
103
+ this.createListener.call(this, client, stream, callback, group, deleteOnCompletion);
104
+ // dont wait for the result of create listener, just return this so we can chain
105
+ return this;
106
+ }
107
+ async createListener(client, stream, callback, group, deleteOnCompletion = false) {
108
+ if (group)
109
+ await this.createGroup.call(this, stream, group);
110
+ this.listeners.set(stream, new Listener_1.default(this, client, stream, callback, group, deleteOnCompletion));
111
+ console.log(`redishelper : listener added for ${stream}`);
112
+ }
113
+ addListListener(event, callback, finishedevent = '', itemsPerCall = 1) {
114
+ const client = new ioredis_1.default({
115
+ host: this.redisConfig.REDISURL,
116
+ password: this.redisConfig.REDISPW ?? ''
117
+ });
118
+ const channel = this.getListChannel(event);
119
+ this.listeners.set(channel, new ListListener_1.default(this, client, channel, callback, finishedevent, itemsPerCall));
120
+ console.log(`redishelper : listlistener added for ${channel}`);
121
+ return this;
122
+ }
123
+ async getList(listname, start = 0, stop = -1) {
124
+ const list = await this.reader.lrange(listname, start, stop);
125
+ return list;
126
+ }
127
+ async getSet(listname) {
128
+ const set = await this.reader.smembers(listname);
129
+ return set;
130
+ }
131
+ throwError(error) {
132
+ if (!this.rollbar)
133
+ throw new Error('Rollbar not initialized');
134
+ this.rollbar.error(error);
135
+ }
136
+ sendMessage(stream, data, updatecontactid) {
137
+ let msg = '';
138
+ if (data.request)
139
+ msg = data.request;
140
+ if (data.endpoint)
141
+ msg = data.endpoint;
142
+ console.log(`sending message : ${msg} to ${stream}`);
143
+ return this.writer.xadd(stream, '*', ...(0, utils_1.createRedisMessage)({
144
+ ...data,
145
+ redishelper_producer: this.consumername,
146
+ redishelper_updatecontactid: updatecontactid ?? undefined
147
+ }));
148
+ }
149
+ async sendMessageAndSubscribeForResponse(channel, target, messagedata, n = 2000) {
150
+ await this.subscribe(channel);
151
+ // send the message to the correct service
152
+ this.sendMessage(target, messagedata);
153
+ let resolver;
154
+ let rejecter;
155
+ // create a promise to be able to pass on to resolve later
156
+ const promise = new Promise((r, rj) => {
157
+ resolver = r;
158
+ rejecter = rj;
159
+ });
160
+ if (!resolver || !rejecter)
161
+ return null;
162
+ //setup a timeout
163
+ const timeout = this.setupTimeout(resolver, channel, n);
164
+ //setup a response
165
+ this.requestMessageResponse(channel, resolver, rejecter, timeout);
166
+ // return a promise that will resolve when the message returns or times out
167
+ return promise;
168
+ }
169
+ async getRequest(targetservice, key, data, timeout = 2000) {
170
+ // create a message id to subscribe to
171
+ const messageid = (0, crypto_1.randomUUID)();
172
+ //subscribe to message response
173
+ const channel = this.getRequestSubscriptionName(messageid);
174
+ return this.sendMessageAndSubscribeForResponse.call(this, channel, this.getRequestStream(targetservice), {
175
+ request: key,
176
+ messageid: messageid,
177
+ data: (0, utils_1.sanitizeValue)(data)
178
+ }, timeout);
179
+ }
180
+ async getApiRequest(endpoint, method, data, jwt = '', timeout = 2000) {
181
+ // create a message id to subscribe to
182
+ const messageid = (0, crypto_1.randomUUID)();
183
+ //subscribe to message response
184
+ const channel = this.getRequestSubscriptionName(messageid);
185
+ return this.sendMessageAndSubscribeForResponse.call(this, channel, this.getRequestStream('api'), {
186
+ endpoint: endpoint,
187
+ method: method,
188
+ messageid: messageid,
189
+ data: data,
190
+ jwt: jwt
191
+ }, timeout);
192
+ }
193
+ requestMessageResponse(channel, resolver, rejector, timeout) {
194
+ this.resolvers.set(channel, resolver);
195
+ this.rejectors.set(channel, rejector);
196
+ this.timeouts.set(channel, timeout);
197
+ }
198
+ cleanupMessageReponse(channel) {
199
+ this.resolvers.delete(channel);
200
+ this.rejectors.delete(channel);
201
+ this.timeouts.delete(channel);
202
+ }
203
+ onMessage(channel, message) {
204
+ const rejector = this.rejectors.get(channel);
205
+ const resolver = this.resolvers.get(channel);
206
+ const timeout = this.timeouts.get(channel);
207
+ if (!rejector || !resolver || !timeout) {
208
+ this.cleanupMessageReponse.call(this, channel);
209
+ return;
210
+ }
211
+ // check if the request has been rejected
212
+ if ((0, class_validator_1.isJSON)(message)) {
213
+ const resolvemessage = JSON.parse(message);
214
+ if (typeof resolvemessage == 'object' &&
215
+ resolvemessage.rejected !== undefined &&
216
+ (0, class_validator_1.isBoolean)(resolvemessage.rejected) &&
217
+ resolvemessage.rejected === true) {
218
+ console.log(resolvemessage);
219
+ if (resolvemessage.error !== undefined &&
220
+ typeof resolvemessage.error == 'object' &&
221
+ resolvemessage.error.title !== undefined && (0, class_validator_1.isString)(resolvemessage.error.title)) {
222
+ rejector(resolvemessage.error.title);
223
+ }
224
+ else {
225
+ rejector('unknown-reason');
226
+ }
227
+ clearTimeout(timeout);
228
+ return;
229
+ }
230
+ }
231
+ if (message.length)
232
+ resolver(message);
233
+ else
234
+ resolver(null);
235
+ this.unsubscribe(channel);
236
+ clearTimeout(timeout);
237
+ }
238
+ unsubscribe(channel) {
239
+ this.reader.unsubscribe(channel);
240
+ this.subscriptions = this.subscriptions.filter(s => s != channel);
241
+ }
242
+ setupTimeout(resolve, channel, n = 2000) {
243
+ return setTimeout(() => {
244
+ if (!this.subscriptions.includes(channel))
245
+ return;
246
+ console.log(`sub timedout: ${channel}`);
247
+ resolve(null);
248
+ this.unsubscribe(channel);
249
+ }, n);
250
+ }
251
+ subscribe(channel) {
252
+ this.subscriptions.push(channel);
253
+ return this.reader.subscribe(channel);
254
+ }
255
+ getRequestSubscriptionName(messageid) {
256
+ return `messageresponse${messageid}`;
257
+ }
258
+ async setKey(key, value) {
259
+ try {
260
+ return await this.writer.set(key, (0, utils_1.sanitizeValue)(value));
261
+ }
262
+ catch { }
263
+ return;
264
+ }
265
+ async readKey(key) {
266
+ try {
267
+ return await this.writer.get(key);
268
+ }
269
+ catch { }
270
+ return null;
271
+ }
272
+ async deleteKey(key) {
273
+ try {
274
+ return await this.writer.del(key);
275
+ }
276
+ catch { }
277
+ return;
278
+ }
279
+ async sendListEvent(event, listitems, data = {}, listname = "") {
280
+ if (listitems.length == 0)
281
+ return;
282
+ // if a listname exist, we first empty it
283
+ if (listname.length > 0)
284
+ await this.deleteKey.call(this, listname);
285
+ const list = await this.addToSet.call(this, listitems, listname.length > 0 ? listname : undefined);
286
+ return this.sendMessage(this.getListChannel(event), {
287
+ ...data,
288
+ listname: list
289
+ });
290
+ }
291
+ async addToSet(listitems, listname) {
292
+ const list = listname ?? (0, crypto_1.randomUUID)();
293
+ await this.writer.sadd(list, ...listitems.map(utils_1.sanitizeValue));
294
+ return list;
295
+ }
296
+ async addToList(listitems, listname) {
297
+ const list = listname ?? (0, crypto_1.randomUUID)();
298
+ await this.writer.lpush(list, ...listitems.map(utils_1.sanitizeValue));
299
+ return list;
300
+ }
301
+ getListChannel(event) {
302
+ return `${this.listprefix}${event}`;
303
+ }
304
+ async getStreamMessages(stream) {
305
+ const streaminfo = await this.getStreamInfo.call(this, stream);
306
+ if (!streaminfo || !(0, class_validator_1.isArray)(streaminfo) || streaminfo.length < 10)
307
+ return [];
308
+ const params = this.decypherParameters(streaminfo);
309
+ if (!params.entries)
310
+ return [];
311
+ return this.decyperMessages(params.entries);
312
+ }
313
+ getStreamInfo(stream, count = 0) {
314
+ return this.reader.xinfo('STREAM', stream, 'FULL', 'COUNT', count);
315
+ }
316
+ async filterStream(stream, key, value) {
317
+ const messages = await this.getStreamMessages.call(this, stream);
318
+ return messages.filter(message => message.parameters?.[key] != null && message.parameters[key] == value);
319
+ }
320
+ decypherResponse(...responses) {
321
+ return responses.reduce((resp, response) => [
322
+ ...resp,
323
+ {
324
+ stream: response[0],
325
+ messages: this.decyperMessages(response[1])
326
+ }
327
+ ], []);
328
+ }
329
+ decyperMessages(messages) {
330
+ return messages.map((message) => ({
331
+ id: message[0],
332
+ parameters: this.decypherParameters(message[1])
333
+ }));
334
+ }
335
+ decypherParameters(parameters) {
336
+ return parameters.reduce((params, v, n) => (n == 0 || (n % 2 == 0)) && parameters.length >= n + 1 ? ({
337
+ ...params,
338
+ [v]: parameters[n + 1]
339
+ }) : params, {});
340
+ }
341
+ async isSetPickedUp(setname) {
342
+ const pickedup = await this.reader.get((0, utils_1.getSetPickedUpName)(setname));
343
+ return pickedup !== null;
344
+ }
345
+ }
346
+ exports.default = Broker;
347
+ //# sourceMappingURL=Broker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Broker.js","sourceRoot":"","sources":["../../../src/classes/Broker.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import { Redis } from "ioredis";
2
+ import { DecypheredMessage, DecypheredResponse, StreamResponse } from "../types";
3
+ import Broker from "./Broker";
4
+ export default abstract class BrokerClient {
5
+ broker: Broker;
6
+ client: Redis;
7
+ group: string | null;
8
+ stream: string | null;
9
+ callback: Function;
10
+ deleteOnCompletion: boolean;
11
+ constructor(broker: Broker, client: Redis, callback: Function, stream?: string | null, group?: string | null, deleteOnCompletion?: boolean);
12
+ throwError(error: any): void;
13
+ decypherResponse(...responses: StreamResponse[]): DecypheredResponse[];
14
+ getGroupResponse(): Promise<StreamResponse[] | null>;
15
+ getResponse(lastid: string): Promise<StreamResponse[] | null>;
16
+ listenToStream(lastid?: string): Promise<Broker | null>;
17
+ acknowledge(id: string): Promise<number> | null;
18
+ delete(id: string): Promise<number> | null;
19
+ abstract streamCallback(message: DecypheredMessage): Promise<any | null>;
20
+ }
@@ -0,0 +1,68 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ class BrokerClient {
4
+ constructor(broker, client, callback, stream = null, group = null, deleteOnCompletion = false) {
5
+ this.group = null;
6
+ this.stream = null;
7
+ this.deleteOnCompletion = false;
8
+ this.broker = broker;
9
+ this.client = client;
10
+ this.stream = stream;
11
+ this.group = group;
12
+ this.callback = callback;
13
+ this.deleteOnCompletion = deleteOnCompletion;
14
+ this.listenToStream.call(this);
15
+ }
16
+ throwError(error) {
17
+ return this.broker.throwError(error);
18
+ }
19
+ decypherResponse(...responses) {
20
+ return this.broker.decypherResponse(...responses);
21
+ }
22
+ async getGroupResponse() {
23
+ if (!this.group || !this.stream)
24
+ return null;
25
+ return await this.client.xreadgroup('GROUP', this.group, this.broker.consumername, 'COUNT', 1, 'BLOCK', 0, 'STREAMS', this.stream, '>');
26
+ }
27
+ async getResponse(lastid) {
28
+ if (!this.stream)
29
+ return null;
30
+ return await this.client.xread("BLOCK", 0, "STREAMS", this.stream, lastid);
31
+ }
32
+ async listenToStream(lastid = '$') {
33
+ const responses = await (!this.group ? this.getResponse.call(this, lastid) : this.getGroupResponse.call(this));
34
+ if (!responses)
35
+ return null;
36
+ const streamResponses = this.decypherResponse(...responses);
37
+ const messages = streamResponses.flatMap(r => r.messages);
38
+ await Promise.all(messages.map(async (message) => {
39
+ try {
40
+ await this.streamCallback(message);
41
+ }
42
+ catch (e) {
43
+ // report to rollbarr
44
+ this.broker.throwError(e);
45
+ }
46
+ finally {
47
+ await this.acknowledge.call(this, message.id);
48
+ if (this.deleteOnCompletion)
49
+ await this.delete.call(this, message.id);
50
+ }
51
+ }));
52
+ return this.listenToStream.call(this, messages[messages.length - 1]?.id ?? '$');
53
+ }
54
+ acknowledge(id) {
55
+ if (!this.group || !this.stream)
56
+ return null;
57
+ console.log(`xack ${id}`);
58
+ return this.client.xack(this.stream, this.group, id);
59
+ }
60
+ delete(id) {
61
+ if (!this.stream)
62
+ return null;
63
+ console.log(`del ${id}`);
64
+ return this.client.xdel(this.stream, id);
65
+ }
66
+ }
67
+ exports.default = BrokerClient;
68
+ //# sourceMappingURL=BrokerClient.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BrokerClient.js","sourceRoot":"","sources":["../../../src/classes/BrokerClient.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import { Redis } from "ioredis";
2
+ import { DecypheredMessage } from "../types";
3
+ import Broker from "./Broker";
4
+ import BrokerClient from "./BrokerClient";
5
+ export default class ListListener extends BrokerClient {
6
+ finishedevent: string;
7
+ itemsPerCall: number;
8
+ constructor(broker: Broker, client: Redis, stream: string, callback: Function, finishedevent: string | undefined, itemsPerCall: number);
9
+ streamCallback(message: DecypheredMessage): Promise<void | Function | null>;
10
+ }
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ const BrokerClient_1 = tslib_1.__importDefault(require("./BrokerClient"));
5
+ const ListRunner_1 = tslib_1.__importDefault(require("./ListRunner"));
6
+ class ListListener extends BrokerClient_1.default {
7
+ constructor(broker, client, stream, callback, finishedevent = '', itemsPerCall) {
8
+ super(broker, client, callback, stream);
9
+ this.finishedevent = finishedevent;
10
+ this.itemsPerCall = itemsPerCall;
11
+ }
12
+ async streamCallback(message) {
13
+ const listrunnercallback = await this.callback(message.id, message.parameters);
14
+ if (message.parameters.listname) {
15
+ const runner = new ListRunner_1.default(this.client, message.parameters.listname, listrunnercallback, message.parameters, this.finishedevent, this.itemsPerCall);
16
+ return await runner.run();
17
+ }
18
+ return null;
19
+ }
20
+ }
21
+ exports.default = ListListener;
22
+ //# sourceMappingURL=ListListener.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ListListener.js","sourceRoot":"","sources":["../../../src/classes/ListListener.ts"],"names":[],"mappings":";;;AAGA,0EAAyC;AACzC,sEAAqC;AAErC,MAAqB,YAAa,SAAQ,sBAAY;IAGpD,YAAa,MAAa,EAAE,MAAY,EAAE,MAAa,EAAE,QAAiB,EAAE,gBAAuB,EAAE,EAAE,YAAmB;QACxH,KAAK,CAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAE,CAAA;QACzC,IAAI,CAAC,aAAa,GAAG,aAAa,CAAA;QAClC,IAAI,CAAC,YAAY,GAAG,YAAY,CAAA;IAClC,CAAC;IAED,KAAK,CAAC,cAAc,CAAE,OAAyB;QAC7C,MAAM,kBAAkB,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAE,OAAO,CAAC,EAAE,EAAE,OAAO,CAAC,UAAU,CAAE,CAAA;QAEhF,IAAI,OAAO,CAAC,UAAU,CAAC,QAAQ,EAAE;YAC/B,MAAM,MAAM,GAAG,IAAI,oBAAU,CAAE,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,UAAU,CAAC,QAAkB,EAAE,kBAAkB,EAAE,OAAO,CAAC,UAAU,EAAE,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC,YAAY,CAAE,CAAA;YAClK,OAAO,MAAM,MAAM,CAAC,GAAG,EAAE,CAAA;SAC1B;QAED,OAAO,IAAI,CAAA;IACb,CAAC;CACF;AAnBD,+BAmBC"}
@@ -0,0 +1,19 @@
1
+ import { Redis } from "ioredis";
2
+ import { DecypheredParameters } from "../types";
3
+ export default class ListRunner {
4
+ listname: string;
5
+ itemsDone: number;
6
+ itemsPerCall: number;
7
+ callback: Function;
8
+ client: Redis;
9
+ params: DecypheredParameters;
10
+ finishedevent: string;
11
+ constructor(client: Redis, listname: string, callback: Function, params: DecypheredParameters, finishedevent?: string, itemsPerCall?: number);
12
+ run(): Promise<Function | void>;
13
+ nextitems(listname: string): Promise<string[] | null>;
14
+ addItemsToInProgress(items: string[]): Promise<string[]>;
15
+ get inProgressSetName(): string;
16
+ handleFinished(): Promise<void>;
17
+ removeItemsFromToDo(items: string[]): Promise<number>;
18
+ removeItemsFromInProgress(items: string[]): Promise<number>;
19
+ }