@spinajs/queue 2.0.44

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/README.md ADDED
@@ -0,0 +1,11 @@
1
+ # `jobs`
2
+
3
+ > TODO: description
4
+
5
+ ## Usage
6
+
7
+ ```
8
+ const jobs = require('jobs');
9
+
10
+ // TODO: DEMONSTRATE API
11
+ ```
@@ -0,0 +1,11 @@
1
+ import { Constructor } from '@spinajs/di';
2
+ import { IQueueMessage, QueueClient, QueueMessage } from './interfaces';
3
+ /**
4
+ * Empty queue, does nothing.
5
+ * Use it, if you want to route or dismiss messages sent by queue service
6
+ */
7
+ export declare class BlackHoleQueueClient extends QueueClient {
8
+ emit(_event: IQueueMessage): Promise<void>;
9
+ subscribe(_channel: string | Constructor<QueueMessage>, _callback: (e: IQueueMessage) => Promise<void>, _subscriptionId?: string, _durable?: boolean): Promise<void>;
10
+ unsubscribe(_channel: string | Constructor<QueueMessage>): void;
11
+ }
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.BlackHoleQueueClient = void 0;
10
+ const di_1 = require("@spinajs/di");
11
+ const interfaces_1 = require("./interfaces");
12
+ /**
13
+ * Empty queue, does nothing.
14
+ * Use it, if you want to route or dismiss messages sent by queue service
15
+ */
16
+ let BlackHoleQueueClient = class BlackHoleQueueClient extends interfaces_1.QueueClient {
17
+ emit(_event) {
18
+ return Promise.resolve();
19
+ }
20
+ subscribe(_channel, _callback, _subscriptionId, _durable) {
21
+ return Promise.resolve();
22
+ }
23
+ unsubscribe(_channel) { }
24
+ };
25
+ BlackHoleQueueClient = __decorate([
26
+ (0, di_1.NewInstance)(),
27
+ (0, di_1.Injectable)(interfaces_1.QueueClient)
28
+ ], BlackHoleQueueClient);
29
+ exports.BlackHoleQueueClient = BlackHoleQueueClient;
30
+ //# sourceMappingURL=BlackHoleQueueClient.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BlackHoleQueueClient.js","sourceRoot":"","sources":["../src/BlackHoleQueueClient.ts"],"names":[],"mappings":";;;;;;;;;AAAA,oCAAmE;AACnE,6CAAwE;AAExE;;;GAGG;AAGH,IAAa,oBAAoB,GAAjC,MAAa,oBAAqB,SAAQ,wBAAW;IAC5C,IAAI,CAAC,MAAqB;QAC/B,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;IAC3B,CAAC;IACM,SAAS,CAAC,QAA4C,EAAE,SAA8C,EAAE,eAAwB,EAAE,QAAkB;QACzJ,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;IAC3B,CAAC;IACM,WAAW,CAAC,QAA4C,IAAS,CAAC;CAC1E,CAAA;AARY,oBAAoB;IAFhC,IAAA,gBAAW,GAAE;IACb,IAAA,eAAU,EAAC,wBAAW,CAAC;GACX,oBAAoB,CAQhC;AARY,oDAAoB"}
@@ -0,0 +1,4 @@
1
+ import { Bootstrapper } from '@spinajs/di';
2
+ export declare class QueueBootstrapper extends Bootstrapper {
3
+ bootstrap(): Promise<void>;
4
+ }
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.QueueBootstrapper = void 0;
10
+ /* eslint-disable @typescript-eslint/require-await */
11
+ const di_1 = require("@spinajs/di");
12
+ const Queue_2022_10_18_01_13_00_1 = require("./migrations/Queue_2022_10_18_01_13_00");
13
+ const JobModel_1 = require("./models/JobModel");
14
+ let QueueBootstrapper = class QueueBootstrapper extends di_1.Bootstrapper {
15
+ async bootstrap() {
16
+ di_1.DI.register(JobModel_1.JobModel).asValue('__models__');
17
+ di_1.DI.register(Queue_2022_10_18_01_13_00_1.Queue_2022_10_18_01_13_00).asValue('__migrations__');
18
+ return;
19
+ }
20
+ };
21
+ QueueBootstrapper = __decorate([
22
+ (0, di_1.Injectable)(di_1.Bootstrapper)
23
+ ], QueueBootstrapper);
24
+ exports.QueueBootstrapper = QueueBootstrapper;
25
+ //# sourceMappingURL=bootstrap.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bootstrap.js","sourceRoot":"","sources":["../src/bootstrap.ts"],"names":[],"mappings":";;;;;;;;;AAAA,qDAAqD;AACrD,oCAA2D;AAC3D,sFAAmF;AACnF,gDAA6C;AAG7C,IAAa,iBAAiB,GAA9B,MAAa,iBAAkB,SAAQ,iBAAY;IAC1C,KAAK,CAAC,SAAS;QACpB,OAAE,CAAC,QAAQ,CAAC,mBAAQ,CAAC,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;QAC5C,OAAE,CAAC,QAAQ,CAAC,qDAAyB,CAAC,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC;QACjE,OAAO;IACT,CAAC;CACF,CAAA;AANY,iBAAiB;IAD7B,IAAA,eAAU,EAAC,iBAAY,CAAC;GACZ,iBAAiB,CAM7B;AANY,8CAAiB"}
File without changes
@@ -0,0 +1,19 @@
1
+ //import { join, normalize, resolve } from 'path';
2
+ // function dir(path: string) {
3
+ // return resolve(normalize(join(__dirname, path)));
4
+ // }
5
+ module.exports = {
6
+ queue: {
7
+ // by default, all messages are sent to black hole
8
+ // becouse some modules use queues to pass events eg. user login
9
+ // but not always in project we want to use queue or have queue server
10
+ default: 'black-hole',
11
+ connections: [
12
+ {
13
+ name: 'black-hole',
14
+ service: 'BlackHoleQueueClient',
15
+ },
16
+ ],
17
+ },
18
+ };
19
+ //# sourceMappingURL=queue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queue.js","sourceRoot":"","sources":["../../src/config/queue.ts"],"names":[],"mappings":"AAAA,kDAAkD;AAElD,+BAA+B;AAC/B,sDAAsD;AACtD,IAAI;AAEJ,MAAM,CAAC,OAAO,GAAG;IACf,KAAK,EAAE;QACL,kDAAkD;QAClD,gEAAgE;QAChE,sEAAsE;QACtE,OAAO,EAAE,YAAY;QACrB,WAAW,EAAE;YACX;gBACE,IAAI,EAAE,YAAY;gBAClB,OAAO,EAAE,sBAAsB;aAChC;SACF;KACF;CACF,CAAC"}
@@ -0,0 +1,16 @@
1
+ export interface IEventOption {
2
+ durable?: boolean;
3
+ }
4
+ /**
5
+ *
6
+ * Mark class as job
7
+ *
8
+ * @param connection - job connection name for use, if not set default connection is used
9
+ */
10
+ export declare function Job(): (target: any) => void;
11
+ /**
12
+ * Mark class as event
13
+ *
14
+ * @param connection - event connection name for use, if not set default connection is used
15
+ */
16
+ export declare function Event(options?: IEventOption): (target: any) => void;
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Event = exports.Job = void 0;
4
+ /**
5
+ *
6
+ * Mark class as job
7
+ *
8
+ * @param connection - job connection name for use, if not set default connection is used
9
+ */
10
+ function Job() {
11
+ return (target) => {
12
+ if (!Reflect.hasMetadata('queue:options', target)) {
13
+ Reflect.defineMetadata('queue:options', {
14
+ type: 'job',
15
+ }, target);
16
+ }
17
+ };
18
+ }
19
+ exports.Job = Job;
20
+ /**
21
+ * Mark class as event
22
+ *
23
+ * @param connection - event connection name for use, if not set default connection is used
24
+ */
25
+ function Event(options) {
26
+ return (target) => {
27
+ if (!Reflect.hasMetadata('queue:options', target)) {
28
+ Reflect.defineMetadata('queue:options', Object.assign(Object.assign({}, options), { type: 'event' }), target);
29
+ }
30
+ };
31
+ }
32
+ exports.Event = Event;
33
+ //# sourceMappingURL=decorators.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decorators.js","sourceRoot":"","sources":["../src/decorators.ts"],"names":[],"mappings":";;;AAIA;;;;;GAKG;AACH,SAAgB,GAAG;IACjB,OAAO,CAAC,MAAW,EAAE,EAAE;QACrB,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,eAAe,EAAE,MAAM,CAAC,EAAE;YACjD,OAAO,CAAC,cAAc,CACpB,eAAe,EACf;gBACE,IAAI,EAAE,KAAK;aACZ,EACD,MAAM,CACP,CAAC;SACH;IACH,CAAC,CAAC;AACJ,CAAC;AAZD,kBAYC;AAED;;;;GAIG;AACH,SAAgB,KAAK,CAAC,OAAsB;IAC1C,OAAO,CAAC,MAAW,EAAE,EAAE;QACrB,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,eAAe,EAAE,MAAM,CAAC,EAAE;YACjD,OAAO,CAAC,cAAc,CACpB,eAAe,kCAEV,OAAO,KACV,IAAI,EAAE,OAAO,KAEf,MAAM,CACP,CAAC;SACH;IACH,CAAC,CAAC;AACJ,CAAC;AAbD,sBAaC"}
package/lib/index.d.ts ADDED
@@ -0,0 +1,38 @@
1
+ import { Constructor } from '@spinajs/di';
2
+ import { Log } from '@spinajs/log';
3
+ import { QueueClient, QueueJob, QueueEvent, IQueueMessage, QueueMessage, QueueService } from './interfaces';
4
+ export * from './BlackHoleQueueClient';
5
+ export * from './interfaces';
6
+ export * from './decorators';
7
+ export * from './models/JobModel';
8
+ export * from './migrations/Queue_2022_10_18_01_13_00';
9
+ export declare class DefaultQueueService extends QueueService {
10
+ protected Log: Log;
11
+ protected Connections: Map<string, QueueClient>;
12
+ dispose(): Promise<void>;
13
+ emit(event: IQueueMessage | QueueEvent | QueueJob): Promise<void>;
14
+ stopConsuming(event: Constructor<QueueMessage>): Promise<void>;
15
+ /**
16
+ *
17
+ * Starts to consume events/jobs from connection
18
+ *
19
+ * NOTE: When consuming events, we can have multiple event types on same channel, couse
20
+ * subscribe function filters it out, and event can be handled in another subscription
21
+ *
22
+ * When consuming jobs, multiple jobs on same channel can have unpredictible behavior becouse
23
+ * job can be executed once even with multiple subscribers, so filtering it out
24
+ * prevents from executing it on other subscriptions
25
+ *
26
+ * @param event - event type to consume
27
+ * @param callback - optional callback when job is consumet, mandatory for events
28
+ * @param subscriptionId - optional subscription id if consuming durable events
29
+ * @param durable - is durable event, if not set, this value default to event decorator options
30
+ */
31
+ consume<T extends QueueMessage>(event: Constructor<QueueMessage>, callback?: (message: T) => Promise<void>, subscriptionId?: string, durable?: boolean): Promise<void>;
32
+ /**
33
+ * Get specific queue client connection. If no connection param is provided, default is returned.
34
+ * @param connection - connection name to obtain
35
+ * @returns
36
+ */
37
+ get(connection?: string): QueueClient;
38
+ }
package/lib/index.js ADDED
@@ -0,0 +1,169 @@
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 __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
14
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
15
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
16
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
17
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
18
+ };
19
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
20
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
21
+ };
22
+ var __metadata = (this && this.__metadata) || function (k, v) {
23
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.DefaultQueueService = void 0;
27
+ const exceptions_1 = require("@spinajs/exceptions");
28
+ const di_1 = require("@spinajs/di");
29
+ const log_1 = require("@spinajs/log");
30
+ const interfaces_1 = require("./interfaces");
31
+ const JobModel_1 = require("./models/JobModel");
32
+ const uuid_1 = require("uuid");
33
+ const configuration_1 = require("@spinajs/configuration");
34
+ const luxon_1 = require("luxon");
35
+ __exportStar(require("./BlackHoleQueueClient"), exports);
36
+ __exportStar(require("./interfaces"), exports);
37
+ __exportStar(require("./decorators"), exports);
38
+ __exportStar(require("./models/JobModel"), exports);
39
+ __exportStar(require("./migrations/Queue_2022_10_18_01_13_00"), exports);
40
+ let DefaultQueueService = class DefaultQueueService extends interfaces_1.QueueService {
41
+ async dispose() {
42
+ this.Connections.forEach(async (val) => {
43
+ await val.dispose();
44
+ });
45
+ this.Connections.clear();
46
+ }
47
+ async emit(event) {
48
+ const connections = this.getConnectionsForMessage(event);
49
+ for (let c of connections) {
50
+ if ((0, interfaces_1.isJob)(event)) {
51
+ const jModel = new JobModel_1.JobModel();
52
+ jModel.JobId = (0, uuid_1.v4)();
53
+ jModel.Name = event.Name;
54
+ jModel.Status = 'created';
55
+ jModel.Progress = 0;
56
+ jModel.Connection = c;
57
+ await jModel.insert();
58
+ event.JobId = jModel.JobId;
59
+ }
60
+ this.Connections.get(c).emit(event);
61
+ this.Log.trace(`Emitted message ${event.Name}, type: ${event.Type} to connection ${c}`);
62
+ }
63
+ }
64
+ async stopConsuming(event) {
65
+ this.getConnectionsForMessage(event).forEach((c) => this.Connections.get(c).unsubscribe(event));
66
+ }
67
+ /**
68
+ *
69
+ * Starts to consume events/jobs from connection
70
+ *
71
+ * NOTE: When consuming events, we can have multiple event types on same channel, couse
72
+ * subscribe function filters it out, and event can be handled in another subscription
73
+ *
74
+ * When consuming jobs, multiple jobs on same channel can have unpredictible behavior becouse
75
+ * job can be executed once even with multiple subscribers, so filtering it out
76
+ * prevents from executing it on other subscriptions
77
+ *
78
+ * @param event - event type to consume
79
+ * @param callback - optional callback when job is consumet, mandatory for events
80
+ * @param subscriptionId - optional subscription id if consuming durable events
81
+ * @param durable - is durable event, if not set, this value default to event decorator options
82
+ */
83
+ async consume(event, callback, subscriptionId, durable) {
84
+ var _a;
85
+ const options = Reflect.getMetadata('queue:options', event);
86
+ const self = this;
87
+ if (!options) {
88
+ throw new exceptions_1.InvalidArgument(`Type ${event.name} is not defined as Job or Event type. Use proper decorator to configure queue events`);
89
+ }
90
+ const { durable: eDurable } = options;
91
+ const connections = this.getConnectionsForMessage(event);
92
+ if ((eDurable || durable) && !subscriptionId) {
93
+ throw new exceptions_1.InvalidArgument('subscriptionId should be set when using durable events');
94
+ }
95
+ for (let c of connections) {
96
+ const conn = this.Connections.get(c);
97
+ if (!conn) {
98
+ throw new di_1.ServiceNotFound(`Queue connection ${c} not found. Please check your configuration before consuming events from this connection.`);
99
+ }
100
+ await conn.subscribe(event, async (e) => {
101
+ if (e.Name === event.name) {
102
+ const ev = di_1.DI.resolve(event);
103
+ ev.hydrate(e);
104
+ /**
105
+ * Handle job type of message
106
+ * To preserve result & handle delay, errors etc..
107
+ */
108
+ if (ev instanceof interfaces_1.QueueJob) {
109
+ let jobResult = null;
110
+ const jModel = await JobModel_1.JobModel.where({ JobId: ev.JobId }).firstOrThrow(new exceptions_1.UnexpectedServerError(`No model found for jobId ${ev.JobId}`));
111
+ jModel.Status = 'executing';
112
+ jModel.ExecutedAt = luxon_1.DateTime.now();
113
+ try {
114
+ // update executing state
115
+ await jModel.update();
116
+ jobResult = await ev.execute(onProgress);
117
+ jModel.Result = jobResult;
118
+ jModel.Status = 'success';
119
+ jModel.FinishedAt = luxon_1.DateTime.now();
120
+ jModel.Progress = 100;
121
+ this.Log.trace(`Job ${event.name} processed with result ${JSON.stringify(jModel.Result)}`);
122
+ }
123
+ catch (err) {
124
+ this.Log.error(err, `Cannot execute job ${event.name}`);
125
+ jModel.Result = {
126
+ message: err.message,
127
+ };
128
+ jModel.Status = 'error';
129
+ }
130
+ await jModel.update();
131
+ async function onProgress(p) {
132
+ jModel.Progress = p;
133
+ await jModel.update();
134
+ self.Log.trace(`Job ${event.name}:${jModel.JobId} progress: ${p}%`);
135
+ }
136
+ }
137
+ if (!callback && ev instanceof interfaces_1.QueueEvent) {
138
+ throw new exceptions_1.InvalidArgument('when subscribing to events, callback cannot be null. Subscriber should handle event in callback function !');
139
+ }
140
+ this.Log.trace(`Queue message ${event.name} processed`);
141
+ if (callback) {
142
+ return callback(ev);
143
+ }
144
+ }
145
+ }, subscriptionId, (_a = durable !== null && durable !== void 0 ? durable : eDurable) !== null && _a !== void 0 ? _a : false);
146
+ }
147
+ }
148
+ /**
149
+ * Get specific queue client connection. If no connection param is provided, default is returned.
150
+ * @param connection - connection name to obtain
151
+ * @returns
152
+ */
153
+ get(connection) {
154
+ return this.Connections.get(`${connection !== null && connection !== void 0 ? connection : this.Configuration.default}`);
155
+ }
156
+ };
157
+ __decorate([
158
+ (0, log_1.Logger)('queue'),
159
+ __metadata("design:type", log_1.Log)
160
+ ], DefaultQueueService.prototype, "Log", void 0);
161
+ __decorate([
162
+ (0, configuration_1.AutoinjectService)('queue.connections', interfaces_1.QueueClient),
163
+ __metadata("design:type", Map)
164
+ ], DefaultQueueService.prototype, "Connections", void 0);
165
+ DefaultQueueService = __decorate([
166
+ (0, di_1.Injectable)(interfaces_1.QueueService)
167
+ ], DefaultQueueService);
168
+ exports.DefaultQueueService = DefaultQueueService;
169
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,207 @@
1
+ import { AsyncService, Constructor, IInstanceCheck, IMappableService } from '@spinajs/di';
2
+ import { DateTime } from 'luxon';
3
+ import { Log } from '@spinajs/log';
4
+ export declare enum QueueMessageType {
5
+ Job = "JOB",
6
+ Event = "EVENT"
7
+ }
8
+ export interface IQueueMessage {
9
+ CreatedAt: DateTime;
10
+ Name: string;
11
+ Type: QueueMessageType;
12
+ /**
13
+ * The time in milliseconds that a message will wait before being scheduled to be delivered by the broker
14
+ */
15
+ ScheduleDelay?: number;
16
+ /**
17
+ * The time in milliseconds to wait after the start time to wait before scheduling the message again
18
+ */
19
+ SchedulePeriod?: number;
20
+ /**
21
+ * The number of times to repeat scheduling a message for delivery
22
+ */
23
+ ScheduleRepeat?: number;
24
+ /**
25
+ * Use a Cron entry to set the schedule
26
+ */
27
+ ScheduleCron?: string;
28
+ }
29
+ export interface IQueueJob extends IQueueMessage {
30
+ RetryCount: number;
31
+ JobId?: string;
32
+ }
33
+ export declare abstract class QueueService extends AsyncService {
34
+ protected Configuration: IQueueConfiguration;
35
+ abstract emit(event: IQueueMessage | QueueEvent | QueueJob): Promise<void>;
36
+ abstract consume<T extends QueueMessage>(event: Constructor<QueueMessage>, callback?: (message: T) => Promise<void>, subscriptionId?: string, durable?: boolean): Promise<void>;
37
+ abstract stopConsuming(event: Constructor<QueueMessage>): Promise<void>;
38
+ abstract get(connection?: string): QueueClient;
39
+ protected getConnectionsForMessage(event: IQueueMessage | Constructor<QueueMessage>): string[];
40
+ }
41
+ export declare function isJob(event: IQueueMessage): event is QueueJob;
42
+ /**
43
+ * Events are messages send via queue, we do not want to track it, dont care about result, no retry policy on failed execution etc.
44
+ */
45
+ export declare abstract class QueueMessage implements IQueueMessage {
46
+ [key: string]: any;
47
+ CreatedAt: DateTime;
48
+ Name: string;
49
+ Type: QueueMessageType;
50
+ /**
51
+ * The time in milliseconds that a message will wait before being scheduled to be delivered by the broker
52
+ */
53
+ ScheduleDelay: number;
54
+ /**
55
+ * The time in milliseconds to wait after the start time to wait before scheduling the message again
56
+ */
57
+ SchedulePeriod: number;
58
+ /**
59
+ * The number of times to repeat scheduling a message for delivery
60
+ */
61
+ ScheduleRepeat: number;
62
+ /**
63
+ * Use a Cron entry to set the schedule
64
+ */
65
+ ScheduleCron: string;
66
+ constructor();
67
+ hydrate(payload: any): void;
68
+ }
69
+ /**
70
+ * events provides a simple observer implementation, allowing you to subscribe and listen
71
+ * for various events that occur in your application. Events serve as a great way to decouple
72
+ * various aspects of your application, since a single event can have multiple listeners that do not depend on each other.
73
+ *
74
+ * we can register multiple listeners for a single event and the event helper will dispatch the event to all of its registered
75
+ * listeners without us calling them explicitly. where in case of Jobs we would have to call them each one explicitly.
76
+ */
77
+ export declare abstract class QueueEvent extends QueueMessage {
78
+ constructor();
79
+ static emit<T extends typeof QueueMessage>(this: T, val: Partial<InstanceType<T>>, options?: IMessageOptions): Promise<void>;
80
+ }
81
+ /**
82
+ * Jobs are executed only once even if multiple listeners waiting for it. usually used for single method call
83
+ * or time consuming tasks, that need to checked for result and tracked
84
+ *
85
+ * Job results are preserved
86
+ */
87
+ export declare abstract class QueueJob extends QueueMessage implements IQueueJob {
88
+ JobId: string;
89
+ /**
90
+ * Retry count on job failure
91
+ */
92
+ RetryCount: number;
93
+ constructor();
94
+ abstract execute(progress: (p: number) => Promise<void>): Promise<unknown>;
95
+ static emit<T extends typeof QueueMessage>(this: T, val: Partial<InstanceType<T>>, options?: IMessageOptions): Promise<void>;
96
+ }
97
+ export declare abstract class QueueClient extends AsyncService implements IInstanceCheck, IMappableService {
98
+ Options: IQueueConnectionOptions;
99
+ protected Log: Log;
100
+ protected Routing: IQueueMessageRoutingOptions;
101
+ get Name(): string;
102
+ get ServiceName(): string;
103
+ constructor(Options: IQueueConnectionOptions);
104
+ __checkInstance__(creationOptions: any): boolean;
105
+ /**
106
+ *
107
+ * Dispatches event to queue
108
+ *
109
+ * @param event - event to dispatch
110
+ */
111
+ abstract emit(event: IQueueMessage): Promise<void>;
112
+ /**
113
+ *
114
+ * Subscribes to ALL channels that event is assignet to in routing table
115
+ *
116
+ */
117
+ abstract subscribe(event: Constructor<QueueMessage>, callback: (e: IQueueMessage) => Promise<void>, subscriptionId?: string, durable?: boolean): Promise<void>;
118
+ /**
119
+ * Subscribes for specific channel in queue server
120
+ *
121
+ * @param channel - specified channel to subscribe
122
+ * @param callback - callback executet when message arrives
123
+ * @param subscriptionId - id to identify subscription when using durable events
124
+ * @param durable - is durable event ?
125
+ */
126
+ abstract subscribe(channel: string, callback: (e: IQueueMessage) => Promise<void>, subscriptionId?: string, durable?: boolean): Promise<void>;
127
+ abstract unsubscribe(event: Constructor<QueueMessage>): void;
128
+ abstract unsubscribe(channel: string): void;
129
+ /**
130
+ *
131
+ * Gets event channel from routing table or default if non is set
132
+ *
133
+ * @param event - event to check
134
+ */
135
+ getChannelForMessage(event: IQueueMessage | Constructor<QueueMessage>): string[];
136
+ }
137
+ export interface IQueueMessageRoutingOptions {
138
+ [key: string]: string | IMessageRoutingOption | string[] | IMessageRoutingOption[];
139
+ }
140
+ export interface IQueueConfiguration {
141
+ default: string;
142
+ /**
143
+ * Message routing eg. where event/job with given type ( name ) will be send to
144
+ * eg. job Email will be sent to /task/mails channel in broker
145
+ * If no routing for message is provided, it will be sent to default one.
146
+ *
147
+ * Also here deat letter channel for message can be configured
148
+ *
149
+ * Message can be router in multiple destinations
150
+ */
151
+ routing?: IQueueMessageRoutingOptions;
152
+ connections: IQueueConnectionOptions[];
153
+ }
154
+ export interface IMessageRoutingOption {
155
+ channel?: string;
156
+ deadLetterChannel?: string;
157
+ connection?: string;
158
+ }
159
+ export interface IQueueConnectionOptions {
160
+ transport: string;
161
+ name: string;
162
+ login?: string;
163
+ password?: string;
164
+ host?: string;
165
+ port?: number;
166
+ queue?: string;
167
+ options?: any;
168
+ type: 'event' | 'job';
169
+ debug?: boolean;
170
+ /**
171
+ * Default topic ( events ) channel in broker
172
+ * If no routing for specified event is provided
173
+ * it will be send to this channel
174
+ */
175
+ defaultTopicChannel?: string;
176
+ /**
177
+ * Default queue ( job ) channel in broker
178
+ * If no routing for specified job is provided
179
+ * it will be send to this channel
180
+ */
181
+ defaultQueueChannel?: string;
182
+ /**
183
+ * If job fails at client side and we dont send ack
184
+ * broker will try to send job again ( and probably will fail again )
185
+ * In such event, it will reschedule job to deat letter queue for further processing
186
+ * and for unblocking source queue
187
+ */
188
+ defaultQueueDeadLetterChannel?: string;
189
+ }
190
+ export interface IMessageOptions {
191
+ /**
192
+ * The time in milliseconds that a message will wait before being scheduled to be delivered by the broker
193
+ */
194
+ ScheduleDelay: number;
195
+ /**
196
+ * The time in milliseconds to wait after the start time to wait before scheduling the message again
197
+ */
198
+ SchedulePeriod: number;
199
+ /**
200
+ * The number of times to repeat scheduling a message for delivery
201
+ */
202
+ ScheduleRepeat: number;
203
+ /**
204
+ * Use a Cron entry to set the schedule
205
+ */
206
+ ScheduleCron: string;
207
+ }
@@ -0,0 +1,162 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.QueueClient = exports.QueueJob = exports.QueueEvent = exports.QueueMessage = exports.isJob = exports.QueueService = exports.QueueMessageType = void 0;
16
+ const di_1 = require("@spinajs/di");
17
+ const luxon_1 = require("luxon");
18
+ const lodash_1 = __importDefault(require("lodash"));
19
+ const log_1 = require("@spinajs/log");
20
+ const configuration_1 = require("@spinajs/configuration");
21
+ var QueueMessageType;
22
+ (function (QueueMessageType) {
23
+ QueueMessageType["Job"] = "JOB";
24
+ QueueMessageType["Event"] = "EVENT";
25
+ })(QueueMessageType = exports.QueueMessageType || (exports.QueueMessageType = {}));
26
+ class QueueService extends di_1.AsyncService {
27
+ getConnectionsForMessage(event) {
28
+ var _a, _b;
29
+ const option = (_b = this.Configuration.routing[(_a = event.Name) !== null && _a !== void 0 ? _a : event.name]) !== null && _b !== void 0 ? _b : this.Configuration.default;
30
+ if (lodash_1.default.isString(option)) {
31
+ return [this.Configuration.default];
32
+ }
33
+ if (lodash_1.default.isArray(option)) {
34
+ return lodash_1.default.uniq(option.map((x) => {
35
+ if (lodash_1.default.isString(x)) {
36
+ return this.Configuration.default;
37
+ }
38
+ if (x.connection) {
39
+ return x.connection;
40
+ }
41
+ }));
42
+ }
43
+ }
44
+ }
45
+ __decorate([
46
+ (0, configuration_1.Config)('queue'),
47
+ __metadata("design:type", Object)
48
+ ], QueueService.prototype, "Configuration", void 0);
49
+ exports.QueueService = QueueService;
50
+ function isJob(event) {
51
+ return event.Type === QueueMessageType.Job;
52
+ }
53
+ exports.isJob = isJob;
54
+ /**
55
+ * Events are messages send via queue, we do not want to track it, dont care about result, no retry policy on failed execution etc.
56
+ */
57
+ class QueueMessage {
58
+ constructor() {
59
+ this.CreatedAt = luxon_1.DateTime.now();
60
+ }
61
+ hydrate(payload) {
62
+ Object.assign(this, payload);
63
+ }
64
+ }
65
+ exports.QueueMessage = QueueMessage;
66
+ /**
67
+ * events provides a simple observer implementation, allowing you to subscribe and listen
68
+ * for various events that occur in your application. Events serve as a great way to decouple
69
+ * various aspects of your application, since a single event can have multiple listeners that do not depend on each other.
70
+ *
71
+ * we can register multiple listeners for a single event and the event helper will dispatch the event to all of its registered
72
+ * listeners without us calling them explicitly. where in case of Jobs we would have to call them each one explicitly.
73
+ */
74
+ class QueueEvent extends QueueMessage {
75
+ constructor() {
76
+ super();
77
+ this.Type = QueueMessageType.Event;
78
+ }
79
+ static async emit(val, options) {
80
+ var _a;
81
+ const queue = await di_1.DI.resolve(QueueService);
82
+ const message = Object.assign(Object.assign(Object.assign({}, val), { Type: QueueMessageType.Event, CreatedAt: (_a = val.CreatedAt) !== null && _a !== void 0 ? _a : luxon_1.DateTime.now(), Name: this.name }), options);
83
+ // partial of queue job always is queue message
84
+ await queue.emit(message);
85
+ }
86
+ }
87
+ exports.QueueEvent = QueueEvent;
88
+ /**
89
+ * Jobs are executed only once even if multiple listeners waiting for it. usually used for single method call
90
+ * or time consuming tasks, that need to checked for result and tracked
91
+ *
92
+ * Job results are preserved
93
+ */
94
+ class QueueJob extends QueueMessage {
95
+ constructor() {
96
+ super();
97
+ this.Type = QueueMessageType.Job;
98
+ this.Name = this.constructor.name;
99
+ }
100
+ static async emit(val, options) {
101
+ var _a;
102
+ const queue = await di_1.DI.resolve(QueueService);
103
+ const message = Object.assign(Object.assign(Object.assign({}, val), { Type: QueueMessageType.Job, CreatedAt: (_a = val.CreatedAt) !== null && _a !== void 0 ? _a : luxon_1.DateTime.now(), Name: this.name }), options);
104
+ // partial of queue job always is queue message
105
+ await queue.emit(message);
106
+ }
107
+ }
108
+ exports.QueueJob = QueueJob;
109
+ class QueueClient extends di_1.AsyncService {
110
+ constructor(Options) {
111
+ super();
112
+ this.Options = Options;
113
+ }
114
+ get Name() {
115
+ return this.Options.name;
116
+ }
117
+ get ServiceName() {
118
+ return this.Options.name;
119
+ }
120
+ __checkInstance__(creationOptions) {
121
+ return this.Options.name === creationOptions[0].name;
122
+ }
123
+ /**
124
+ *
125
+ * Gets event channel from routing table or default if non is set
126
+ *
127
+ * @param event - event to check
128
+ */
129
+ getChannelForMessage(event) {
130
+ var _a, _b;
131
+ const options = Reflect.getMetadata('queue:options', event);
132
+ const eName = (_a = event.Name) !== null && _a !== void 0 ? _a : event.name;
133
+ const isJob = event.Type ? event.Type === QueueMessageType.Job : options ? options.type === 'job' : false;
134
+ const rOption = this.Routing[eName];
135
+ if (!rOption) {
136
+ return [isJob ? this.Options.defaultQueueChannel : this.Options.defaultTopicChannel];
137
+ }
138
+ if (lodash_1.default.isString(rOption)) {
139
+ return [rOption];
140
+ }
141
+ if (lodash_1.default.isArray(rOption)) {
142
+ return lodash_1.default.uniq(rOption.map((x) => {
143
+ var _a;
144
+ if (lodash_1.default.isString(x)) {
145
+ return x;
146
+ }
147
+ return ((_a = x.channel) !== null && _a !== void 0 ? _a : isJob) ? this.Options.defaultQueueChannel : this.Options.defaultTopicChannel;
148
+ }));
149
+ }
150
+ return [((_b = rOption.channel) !== null && _b !== void 0 ? _b : isJob) ? this.Options.defaultQueueChannel : this.Options.defaultTopicChannel];
151
+ }
152
+ }
153
+ __decorate([
154
+ (0, log_1.Logger)('queue'),
155
+ __metadata("design:type", log_1.Log)
156
+ ], QueueClient.prototype, "Log", void 0);
157
+ __decorate([
158
+ (0, configuration_1.Config)('queue.routing'),
159
+ __metadata("design:type", Object)
160
+ ], QueueClient.prototype, "Routing", void 0);
161
+ exports.QueueClient = QueueClient;
162
+ //# sourceMappingURL=interfaces.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interfaces.js","sourceRoot":"","sources":["../src/interfaces.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import { OrmMigration, OrmDriver } from '@spinajs/orm';
2
+ export declare class Queue_2022_10_18_01_13_00 extends OrmMigration {
3
+ up(connection: OrmDriver): Promise<void>;
4
+ down(_connection: OrmDriver): Promise<void>;
5
+ }
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.Queue_2022_10_18_01_13_00 = void 0;
10
+ /* eslint-disable @typescript-eslint/no-unused-vars */
11
+ const orm_1 = require("@spinajs/orm");
12
+ let Queue_2022_10_18_01_13_00 = class Queue_2022_10_18_01_13_00 extends orm_1.OrmMigration {
13
+ async up(connection) {
14
+ await connection.schema().createTable('queue_jobs', (table) => {
15
+ table.int('Id').primaryKey().autoIncrement();
16
+ table.uuid('JobId').notNull();
17
+ table.string('Name', 32).notNull();
18
+ table.string('Result');
19
+ table.enum('Status', ['error', 'success', 'created', 'executing']).notNull().default().value('created');
20
+ table.int('Progress').notNull().default().value(0);
21
+ table.string('Connection').notNull();
22
+ table.timestamp('CreatedAt').notNull().default().dateTime();
23
+ table.timestamp('ExecutedAt');
24
+ table.timestamp('FinishedAt');
25
+ });
26
+ await connection.index().unique().table('queue_jobs').name('queue_jobs_job_id').columns(['JobId']);
27
+ }
28
+ // tslint:disable-next-line: no-empty
29
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
30
+ async down(_connection) { }
31
+ };
32
+ Queue_2022_10_18_01_13_00 = __decorate([
33
+ (0, orm_1.Migration)('queue')
34
+ ], Queue_2022_10_18_01_13_00);
35
+ exports.Queue_2022_10_18_01_13_00 = Queue_2022_10_18_01_13_00;
36
+ //# sourceMappingURL=Queue_2022_10_18_01_13_00.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Queue_2022_10_18_01_13_00.js","sourceRoot":"","sources":["../../src/migrations/Queue_2022_10_18_01_13_00.ts"],"names":[],"mappings":";;;;;;;;;AAAA,sDAAsD;AACtD,sCAAkE;AAGlE,IAAa,yBAAyB,GAAtC,MAAa,yBAA0B,SAAQ,kBAAY;IAClD,KAAK,CAAC,EAAE,CAAC,UAAqB;QACnC,MAAM,UAAU,CAAC,MAAM,EAAE,CAAC,WAAW,CAAC,YAAY,EAAE,CAAC,KAAK,EAAE,EAAE;YAC5D,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,CAAC,aAAa,EAAE,CAAC;YAC7C,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,CAAC;YAC9B,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC;YACnC,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YACvB,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,WAAW,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;YACxG,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YACnD,KAAK,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,OAAO,EAAE,CAAC;YACrC,KAAK,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,CAAC;YAC5D,KAAK,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;YAC9B,KAAK,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;QAChC,CAAC,CAAC,CAAC;QAEH,MAAM,UAAU,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;IACrG,CAAC;IAED,qCAAqC;IACrC,gEAAgE;IACzD,KAAK,CAAC,IAAI,CAAC,WAAsB,IAAkB,CAAC;CAC5D,CAAA;AArBY,yBAAyB;IADrC,IAAA,eAAS,EAAC,OAAO,CAAC;GACN,yBAAyB,CAqBrC;AArBY,8DAAyB"}
@@ -0,0 +1,19 @@
1
+ import { DateTime } from 'luxon';
2
+ import { ModelBase } from '@spinajs/orm';
3
+ /**
4
+ * Base modele for users used by ACL
5
+ *
6
+ * To add / extend fields simply extend this model and register as default user model in ACL service
7
+ */
8
+ export declare class JobModel<T> extends ModelBase {
9
+ Id: number;
10
+ JobId: string;
11
+ Name: string;
12
+ Result: T;
13
+ Status: 'error' | 'success' | 'created' | 'executing';
14
+ Progress: number;
15
+ Connection: string;
16
+ CreatedAt: DateTime;
17
+ ExecutedAt: DateTime;
18
+ FinishedAt: DateTime;
19
+ }
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.JobModel = void 0;
13
+ const luxon_1 = require("luxon");
14
+ const orm_1 = require("@spinajs/orm");
15
+ /**
16
+ * Base modele for users used by ACL
17
+ *
18
+ * To add / extend fields simply extend this model and register as default user model in ACL service
19
+ */
20
+ let JobModel = class JobModel extends orm_1.ModelBase {
21
+ };
22
+ __decorate([
23
+ (0, orm_1.Primary)(),
24
+ __metadata("design:type", Number)
25
+ ], JobModel.prototype, "Id", void 0);
26
+ __decorate([
27
+ (0, orm_1.Json)(),
28
+ __metadata("design:type", Object)
29
+ ], JobModel.prototype, "Result", void 0);
30
+ __decorate([
31
+ (0, orm_1.CreatedAt)(),
32
+ __metadata("design:type", luxon_1.DateTime)
33
+ ], JobModel.prototype, "CreatedAt", void 0);
34
+ __decorate([
35
+ (0, orm_1.DateTime)(),
36
+ __metadata("design:type", luxon_1.DateTime)
37
+ ], JobModel.prototype, "ExecutedAt", void 0);
38
+ __decorate([
39
+ (0, orm_1.DateTime)(),
40
+ __metadata("design:type", luxon_1.DateTime)
41
+ ], JobModel.prototype, "FinishedAt", void 0);
42
+ JobModel = __decorate([
43
+ (0, orm_1.Connection)('queue'),
44
+ (0, orm_1.Model)('queue_jobs')
45
+ ], JobModel);
46
+ exports.JobModel = JobModel;
47
+ //# sourceMappingURL=JobModel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"JobModel.js","sourceRoot":"","sources":["../../src/models/JobModel.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,iCAAiC;AACjC,sCAAsG;AAEtG;;;;GAIG;AAGH,IAAa,QAAQ,GAArB,MAAa,QAAY,SAAQ,eAAS;CAyBzC,CAAA;AAvBC;IADC,IAAA,aAAO,GAAE;;oCACQ;AAOlB;IADC,IAAA,UAAI,GAAE;;wCACU;AASjB;IADC,IAAA,eAAS,GAAE;8BACM,gBAAQ;2CAAC;AAG3B;IADC,IAAA,cAAE,GAAE;8BACc,gBAAQ;4CAAC;AAG5B;IADC,IAAA,cAAE,GAAE;8BACc,gBAAQ;4CAAC;AAxBjB,QAAQ;IAFpB,IAAA,gBAAU,EAAC,OAAO,CAAC;IACnB,IAAA,WAAK,EAAC,YAAY,CAAC;GACP,QAAQ,CAyBpB;AAzBY,4BAAQ"}
package/package.json ADDED
@@ -0,0 +1,53 @@
1
+ {
2
+ "name": "@spinajs/queue",
3
+ "version": "2.0.44",
4
+ "description": "queue sending & pulling made easy",
5
+ "main": "lib/index.js",
6
+ "private": false,
7
+ "scripts": {
8
+ "build": "npm run clean && npm run compile",
9
+ "compile": "tsc -p tsconfig.build.json",
10
+ "clean": "",
11
+ "test": "ts-mocha -p tsconfig.json test/**/*.test.ts",
12
+ "coverage": "nyc npm run test",
13
+ "build-docs": "rimraf docs && typedoc --options typedoc.json src/",
14
+ "prepare": "npm run build",
15
+ "format": "prettier --write \"src/**/*.ts\"",
16
+ "lint": "eslint -c .eslintrc.js --ext .ts src --fix",
17
+ "prepublishOnly": "npm test && npm run lint",
18
+ "preversion": "npm run lint",
19
+ "version": "npm run format && git add -A src",
20
+ "postversion": "git push && git push --tags"
21
+ },
22
+ "files": [
23
+ "lib/**/*"
24
+ ],
25
+ "types": "lib",
26
+ "repository": {
27
+ "type": "git",
28
+ "url": "git+https://github.com/spinajs/main.git"
29
+ },
30
+ "keywords": [
31
+ "spinajs",
32
+ "http"
33
+ ],
34
+ "author": "SpinaJS <spinajs@coderush.pl> (https://github.com/spinajs/main)",
35
+ "license": "MIT",
36
+ "bugs": {
37
+ "url": "https://github.com/spinajs/main/issues"
38
+ },
39
+ "homepage": "https://github.com/spinajs/main#readme",
40
+ "devDependencies": {
41
+ "@types/luxon": "^2.3.1",
42
+ "@types/node": "^16.11.11"
43
+ },
44
+ "dependencies": {
45
+ "@spinajs/configuration": "^2.0.44",
46
+ "@spinajs/di": "^2.0.44",
47
+ "@spinajs/exceptions": "^2.0.39",
48
+ "@spinajs/log": "^2.0.44",
49
+ "eventemitter3": "^4.0.7",
50
+ "luxon": "^3.2.1"
51
+ },
52
+ "gitHead": "1857a6e3626e0fed22ffb0b44b48d587c79898db"
53
+ }