vona-module-a-queue 5.0.9 → 5.0.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,70 @@
1
+ import type { BeanScopeUtil, TypeModuleConfig } from 'vona';
2
+ /** startup: begin */
3
+ import type { IDecoratorStartupOptions } from 'vona-module-a-startup';
4
+ import type { config } from '../config/config.ts';
5
+ /** service: end */
6
+ /** service: begin */
7
+ import type { ServiceQueue } from '../service/queue.ts';
8
+ /** service: end */
9
+ /** service: begin */
10
+ /** monkey: end */
11
+ /** scope: begin */
12
+ import { BeanScopeBase } from 'vona';
13
+ import 'vona';
14
+ import 'vona';
15
+ import 'vona';
16
+ export * from '../bean/startup.loadQueueWorkers.ts';
17
+ declare module 'vona-module-a-startup' {
18
+ interface IStartupRecord {
19
+ 'a-queue:loadQueueWorkers': IDecoratorStartupOptions;
20
+ }
21
+ }
22
+ declare module 'vona-module-a-queue' {
23
+ interface StartupLoadQueueWorkers {
24
+ }
25
+ }
26
+ /** service: end */
27
+ /** config: begin */
28
+ export * from '../config/config.ts';
29
+ declare module 'vona-module-a-web' {
30
+ interface IServiceRecord {
31
+ 'a-queue:queue': never;
32
+ }
33
+ }
34
+ declare module 'vona-module-a-queue' {
35
+ interface ServiceQueue {
36
+ }
37
+ }
38
+ export interface IModuleService {
39
+ queue: ServiceQueue;
40
+ }
41
+ declare module 'vona' {
42
+ interface IBeanRecordGeneral {
43
+ 'a-queue.service.queue': ServiceQueue;
44
+ }
45
+ }
46
+ /** config: end */
47
+ /** monkey: begin */
48
+ export * from '../monkey.ts';
49
+ /** startup: end */
50
+ /** service: begin */
51
+ export * from '../service/queue.ts';
52
+ export declare class ScopeModuleAQueue extends BeanScopeBase {
53
+ }
54
+ export interface ScopeModuleAQueue {
55
+ util: BeanScopeUtil;
56
+ config: TypeModuleConfig<typeof config>;
57
+ service: IModuleService;
58
+ }
59
+ declare module 'vona' {
60
+ interface IBeanScopeRecord {
61
+ 'a-queue': ScopeModuleAQueue;
62
+ }
63
+ interface IBeanScopeContainer {
64
+ queue: ScopeModuleAQueue;
65
+ }
66
+ interface IBeanScopeConfig {
67
+ 'a-queue': ReturnType<typeof config>;
68
+ }
69
+ }
70
+ /** scope: end */
@@ -0,0 +1,2 @@
1
+ export declare const __ThisModule__ = "a-queue";
2
+ export { ScopeModuleAQueue as ScopeModule } from './index.ts';
@@ -0,0 +1,5 @@
1
+ import type { IStartupExecute } from 'vona-module-a-startup';
2
+ import { BeanBase } from 'vona';
3
+ export declare class StartupLoadQueueWorkers extends BeanBase implements IStartupExecute {
4
+ execute(): Promise<void>;
5
+ }
@@ -0,0 +1,5 @@
1
+ import type * as Bull from 'bullmq';
2
+ import type { VonaApplication } from 'vona';
3
+ export declare function config(_app: VonaApplication): {
4
+ worker: Bull.WorkerOptions;
5
+ };
@@ -0,0 +1,3 @@
1
+ export * from './.metadata/index.ts';
2
+ export * from './lib/index.ts';
3
+ export * from './types/index.ts';
package/dist/index.js ADDED
@@ -0,0 +1,334 @@
1
+ import { BeanInfo, BeanBase, BeanSimple, uuidv4, deepExtend, instanceDesp, beanFullNameFromOnionName, BeanScopeBase, createBeanDecorator } from 'vona';
2
+ import { Scope } from 'vona-module-a-bean';
3
+ import { Startup } from 'vona-module-a-startup';
4
+ import * as Bull from 'bullmq';
5
+ import { Service } from 'vona-module-a-web';
6
+
7
+ var _dec$2, _dec2$2, _class$2;
8
+ let StartupLoadQueueWorkers = (_dec$2 = Startup({
9
+ instance: true,
10
+ after: true
11
+ }), _dec2$2 = BeanInfo({
12
+ module: "a-queue"
13
+ }), _dec$2(_class$2 = _dec2$2(_class$2 = class StartupLoadQueueWorkers extends BeanBase {
14
+ async execute() {
15
+ // load queue workers
16
+ if (!this.app.meta.isTest) {
17
+ this.scope.service.queue.loadQueueWorkers(this.ctx.instanceName);
18
+ }
19
+ }
20
+ }) || _class$2) || _class$2);
21
+
22
+ function config(_app) {
23
+ return {
24
+ worker: {
25
+ lockDuration: 30 * 1000,
26
+ maxStalledCount: 1000,
27
+ stalledInterval: 10 * 1000
28
+ }
29
+ };
30
+ }
31
+
32
+ const __ThisModule__ = 'a-queue';
33
+
34
+ class Monkey extends BeanSimple {
35
+ async appClose() {
36
+ const scopeSelf = this.bean.scope(__ThisModule__);
37
+ await scopeSelf.service.queue.clearWorkers();
38
+ }
39
+ async appClosed() {
40
+ const scopeSelf = this.bean.scope(__ThisModule__);
41
+ await scopeSelf.service.queue.clearQueues();
42
+ }
43
+ }
44
+
45
+ var _dec$1, _dec2$1, _class$1;
46
+ let ServiceQueue = (_dec$1 = Service(), _dec2$1 = BeanInfo({
47
+ module: "a-queue"
48
+ }), _dec$1(_class$1 = _dec2$1(_class$1 = class ServiceQueue extends BeanBase {
49
+ constructor(...args) {
50
+ super(...args);
51
+ this._workers = {};
52
+ this._queues = {};
53
+ this._queueCallbacks = {};
54
+ }
55
+ push(info) {
56
+ if (!info.options?.dbInfo) throw new Error('should specify the options.dbInfo');
57
+ this._queuePush(info, false);
58
+ }
59
+
60
+ // { locale, instanceName, module, queueName,queueNameSub,data }
61
+ pushAsync(info) {
62
+ if (!info.options?.dbInfo) throw new Error('should specify the options.dbInfo');
63
+ return this._queuePush(info, true);
64
+ }
65
+ loadQueueWorkers(instanceName) {
66
+ for (const queueItem of this.bean.onion.queue.getOnionsEnabled()) {
67
+ const info = {
68
+ queueName: queueItem.name,
69
+ data: undefined,
70
+ options: {
71
+ instanceName
72
+ }
73
+ };
74
+ this._ensureWorker(info);
75
+ }
76
+ }
77
+ async clearWorkers() {
78
+ for (const queueKey in this._workers) {
79
+ const _worker = this._workers[queueKey];
80
+ await _worker.worker.close();
81
+ }
82
+ this._workers = {};
83
+ }
84
+ async clearQueues() {
85
+ for (const queueKey in this._queues) {
86
+ const _queue = this._queues[queueKey];
87
+ await _queue.queue.close();
88
+ await _queue.queueEvents.close();
89
+ }
90
+ this._queues = {};
91
+ }
92
+ _createWorker(info, queueKey) {
93
+ const app = this.app;
94
+ // worker
95
+ const _worker = {};
96
+ // prefix
97
+ const prefix = `bull_${app.name}:queue`;
98
+ // queue config
99
+ const queueConfig = app.bean.onion.queue.getOnionOptions(info.queueName);
100
+ // queueConfig.options: queue/worker/job/redlock
101
+ const workerOptions = queueConfig?.options?.worker;
102
+ const redlockOptions = queueConfig?.options?.redlock;
103
+ const _redlockOptions = Object.assign({}, this.$scope.redlock.config.redlock.options, redlockOptions);
104
+ const _lockTTL = redlockOptions?.lockTTL ?? this.$scope.redlock.config.redlock.lockTTL;
105
+
106
+ // redlock
107
+ if (!queueConfig?.concurrency) {
108
+ _worker.redlock = this.$scope.redlock.service.redlock.create(_redlockOptions);
109
+ }
110
+
111
+ // create work
112
+ const connectionWorker = app.bean.redis.get('queue');
113
+ const _workerOptions = Object.assign({}, this.scope.config.worker, workerOptions, {
114
+ prefix,
115
+ connection: connectionWorker
116
+ });
117
+ _worker.workerOptions = _workerOptions;
118
+ _worker.worker = new Bull.Worker(queueKey, async job => {
119
+ // concurrency
120
+ if (queueConfig?.concurrency) {
121
+ return await this._performTask(job);
122
+ }
123
+ // redlock
124
+ const info = job.data;
125
+ const queueNameSub = info.options?.queueNameSub;
126
+ const _lockResource = `queue:${queueKey}${queueNameSub ? `#${queueNameSub}` : ''}`;
127
+ return await this.$scope.redlock.service.redlock.lock(_lockResource, async () => {
128
+ return await this._performTask(job);
129
+ }, {
130
+ // instanceName: job.data.instanceName, // need not
131
+ redlock: _worker.redlock,
132
+ lockTTL: _lockTTL
133
+ });
134
+ }, _workerOptions);
135
+ _worker.worker.on('failed', (_job, err) => {
136
+ this.$logger.error(err);
137
+ });
138
+ _worker.worker.on('error', err => {
139
+ if (err.message && err.message.includes('Missing lock for job')) {
140
+ const workerInner = _worker.worker;
141
+ if (!workerInner.running) {
142
+ _worker.worker.run().catch(err => {
143
+ this.$logger.error(err);
144
+ });
145
+ }
146
+ }
147
+ });
148
+
149
+ // ok
150
+ return _worker;
151
+ }
152
+ _createQueue(info, queueKey) {
153
+ const app = this.app;
154
+ // queue
155
+ const _queue = {};
156
+ // prefix
157
+ const prefix = `bull_${app.name}:queue`;
158
+ // queue config
159
+ const queueConfig = app.bean.onion.queue.getOnionOptions(info.queueName);
160
+ // queueConfig.options: queue/worker/job/limiter
161
+ const queueOptions = queueConfig?.options?.queue;
162
+
163
+ // create queue
164
+ const connectionQueue = app.bean.redis.get('queue');
165
+ const _queueOptions = Object.assign({}, queueOptions, {
166
+ prefix,
167
+ connection: connectionQueue
168
+ });
169
+ _queue.config = queueConfig;
170
+ _queue.options = _queueOptions;
171
+ _queue.queue = new Bull.Queue(queueKey, _queueOptions);
172
+
173
+ // create events
174
+ const connectionEvents = app.bean.redis.get('queue');
175
+ const _queueEventsOptions = {
176
+ prefix,
177
+ connection: connectionEvents
178
+ };
179
+ _queue.queueEventsOptions = _queueEventsOptions;
180
+ _queue.queueEvents = new Bull.QueueEvents(queueKey, _queueEventsOptions);
181
+ _queue.queueEvents.on('completed', ({
182
+ jobId,
183
+ returnvalue
184
+ }) => {
185
+ this._callCallback(jobId, undefined, returnvalue);
186
+ });
187
+ _queue.queueEvents.on('failed', ({
188
+ jobId,
189
+ failedReason
190
+ }) => {
191
+ this._callCallback(jobId, failedReason, undefined);
192
+ });
193
+
194
+ // ok
195
+ return _queue;
196
+ }
197
+ _ensureWorker(info) {
198
+ // queueKey
199
+ const queueKey = this._combineQueueKey(info);
200
+ // worker
201
+ if (!this._workers[queueKey]) {
202
+ this._workers[queueKey] = this._createWorker(info, queueKey);
203
+ }
204
+ }
205
+ _ensureQueue(info) {
206
+ // worker
207
+ this._ensureWorker(info);
208
+ // queueKey
209
+ const queueKey = this._combineQueueKey(info);
210
+ // queue
211
+ if (!this._queues[queueKey]) {
212
+ this._queues[queueKey] = this._createQueue(info, queueKey);
213
+ }
214
+ // ok
215
+ return this._queues[queueKey];
216
+ }
217
+ getQueue(queueName, instanceName) {
218
+ return this._getQueue({
219
+ queueName,
220
+ data: undefined,
221
+ options: {
222
+ instanceName: instanceName ?? this.ctx.instanceName
223
+ }
224
+ });
225
+ }
226
+ _getQueue(info) {
227
+ return this._ensureQueue(info).queue;
228
+ }
229
+ _callCallback(jobId, failedReason, data) {
230
+ const _callback = this._queueCallbacks[jobId];
231
+ if (_callback) {
232
+ delete this._queueCallbacks[jobId];
233
+ _callback.callback(failedReason ? new Error(failedReason) : undefined, data);
234
+ }
235
+ }
236
+ async _queuePush(info, isAsync) {
237
+ // queue config
238
+ const queueConfig = this.bean.onion.queue.getOnionOptions(info.queueName);
239
+ // queueConfig.options: queue/worker/job/limiter
240
+ const jobOptionsBase = queueConfig?.options?.job;
241
+ // queue
242
+ const queue = this._getQueue(info);
243
+ // job
244
+ const jobId = info.options?.jobOptions?.jobId || uuidv4();
245
+ const jobName = info.options?.jobName || jobId;
246
+ const jobOptions = deepExtend({
247
+ jobId
248
+ }, jobOptionsBase, info.options?.jobOptions);
249
+ // should not change info, hold original info.options?.jobName, info.options?.jobOptions
250
+ // info = deepExtend({}, info, { options: { jobName, jobOptions } });
251
+ // not async
252
+ if (!isAsync) {
253
+ // add job
254
+ queue.add(jobName, info, jobOptions);
255
+ return undefined;
256
+ }
257
+ // async
258
+ return new Promise((resolve, reject) => {
259
+ // callback
260
+ this._queueCallbacks[jobId] = {
261
+ info,
262
+ callback: (err, data) => {
263
+ if (err) return reject(err);
264
+ resolve(data);
265
+ }
266
+ };
267
+ // add job
268
+ return queue.add(jobName, info, jobOptions);
269
+ });
270
+ }
271
+ _combineQueueKey(info) {
272
+ const instanceName = instanceDesp(info.options?.instanceName);
273
+ return `${instanceName}||${beanFullNameFromOnionName(info.queueName, 'queue')}`;
274
+ }
275
+ async _performTask(job) {
276
+ const info = job.data;
277
+ // queue config
278
+ const queueItem = this.bean.onion.queue.getOnionSlice(info.queueName);
279
+ const queueConfig = this.bean.onion.queue.getOnionOptions(info.queueName);
280
+ // execute
281
+ return await this.bean.executor.newCtx(async () => {
282
+ const beanFullName = queueItem.beanOptions.beanFullName;
283
+ const beanInstance = this.app.bean._getBean(beanFullName);
284
+ return await beanInstance.execute(info.data, info.options, job);
285
+ }, {
286
+ dbInfo: info.options?.dbInfo,
287
+ locale: info.options?.locale,
288
+ instanceName: info.options?.instanceName,
289
+ extraData: info.options?.extraData,
290
+ transaction: queueConfig?.transaction
291
+ });
292
+ }
293
+ getRepeatKey(jobName, repeat) {
294
+ const endDate = repeat.endDate ? new Date(repeat.endDate).getTime() : '';
295
+ const tz = repeat.tz || '';
296
+ const pattern = repeat.pattern;
297
+ const suffix = pattern || String(repeat.every) || '';
298
+ return `${jobName}:${endDate}:${tz}:${suffix}`;
299
+ }
300
+ prepareJobInfo(queueName, data, options) {
301
+ options = this.$scope.executor.service.executor.prepareGeneralInfo(options);
302
+ // info
303
+ return {
304
+ queueName,
305
+ data,
306
+ options
307
+ };
308
+ }
309
+ }) || _class$1) || _class$1);
310
+
311
+ var _dec, _dec2, _class;
312
+ let ScopeModuleAQueue = (_dec = Scope(), _dec2 = BeanInfo({
313
+ module: "a-queue"
314
+ }), _dec(_class = _dec2(_class = class ScopeModuleAQueue extends BeanScopeBase {}) || _class) || _class);
315
+
316
+ /** scope: end */
317
+
318
+ class BeanQueueBase extends BeanBase {
319
+ async pushAsync(data, options) {
320
+ return await this.$scope.queue.service.queue.pushAsync(this.$scope.queue.service.queue.prepareJobInfo(this.$onionName, data, options));
321
+ }
322
+ push(data, options) {
323
+ return this.$scope.queue.service.queue.push(this.$scope.queue.service.queue.prepareJobInfo(this.$onionName, data, options));
324
+ }
325
+ getQueue(instanceName) {
326
+ return this.$scope.queue.service.queue.getQueue(this.$onionName, instanceName);
327
+ }
328
+ }
329
+
330
+ function Queue(options) {
331
+ return createBeanDecorator('queue', options);
332
+ }
333
+
334
+ export { BeanQueueBase, Monkey, Queue, ScopeModuleAQueue, ServiceQueue, StartupLoadQueueWorkers, config };
@@ -0,0 +1,7 @@
1
+ import type { IQueuePushOptions } from '../types/queue.ts';
2
+ import { BeanBase } from 'vona';
3
+ export declare class BeanQueueBase<DATA = unknown, RESULT = unknown> extends BeanBase {
4
+ pushAsync(data: DATA, options?: IQueuePushOptions): Promise<RESULT>;
5
+ push(data: DATA, options?: IQueuePushOptions): void;
6
+ getQueue(instanceName?: string): import("bullmq").Queue<any, any, string, any, any, string>;
7
+ }
@@ -0,0 +1,2 @@
1
+ export * from './beanQueueBase.ts';
2
+ export * from './queue.ts';
@@ -0,0 +1,2 @@
1
+ import type { IDecoratorQueueOptions } from '../types/queue.ts';
2
+ export declare function Queue(options?: IDecoratorQueueOptions): ClassDecorator;
@@ -0,0 +1,6 @@
1
+ import type { IMonkeyAppClose, IMonkeyAppClosed } from 'vona';
2
+ import { BeanSimple } from 'vona';
3
+ export declare class Monkey extends BeanSimple implements IMonkeyAppClose, IMonkeyAppClosed {
4
+ appClose(): Promise<void>;
5
+ appClosed(): Promise<void>;
6
+ }
@@ -0,0 +1,25 @@
1
+ import type { IQueueCallbacks, IQueueJobContext, IQueuePushOptions, IQueueQueue, IQueueQueues, IQueueRecord, IQueueWork, IQueueWorks, TypeQueueJob } from '../types/queue.ts';
2
+ import * as Bull from 'bullmq';
3
+ import { BeanBase } from 'vona';
4
+ export declare class ServiceQueue extends BeanBase {
5
+ _workers: IQueueWorks;
6
+ _queues: IQueueQueues;
7
+ _queueCallbacks: IQueueCallbacks;
8
+ push<DATA>(info: IQueueJobContext<DATA>): void;
9
+ pushAsync<DATA, RESULT>(info: IQueueJobContext<DATA>): Promise<RESULT>;
10
+ loadQueueWorkers(instanceName?: string | undefined | null): void;
11
+ clearWorkers(): Promise<void>;
12
+ clearQueues(): Promise<void>;
13
+ _createWorker<DATA>(info: IQueueJobContext<DATA>, queueKey: string): IQueueWork;
14
+ _createQueue<DATA>(info: IQueueJobContext<DATA>, queueKey: string): IQueueQueue;
15
+ _ensureWorker<DATA>(info: IQueueJobContext<DATA>): void;
16
+ _ensureQueue<DATA>(info: IQueueJobContext<DATA>): IQueueQueue;
17
+ getQueue(queueName: keyof IQueueRecord, instanceName?: string | undefined | null): Bull.Queue<any, any, string, any, any, string>;
18
+ _getQueue<DATA>(info: IQueueJobContext<DATA>): Bull.Queue<any, any, string, any, any, string>;
19
+ _callCallback<DATA>(jobId: string | number, failedReason: string | undefined, data: DATA | undefined): void;
20
+ _queuePush<DATA, RESULT>(info: IQueueJobContext<DATA>, isAsync: boolean): Promise<RESULT>;
21
+ _combineQueueKey<DATA>(info: IQueueJobContext<DATA>): string;
22
+ _performTask<DATA, RESULT>(job: TypeQueueJob<DATA, RESULT>): Promise<unknown>;
23
+ getRepeatKey(jobName: string, repeat: Bull.RepeatOptions): string;
24
+ prepareJobInfo<DATA>(queueName: keyof IQueueRecord, data: DATA, options?: IQueuePushOptions): IQueueJobContext<DATA>;
25
+ }
@@ -0,0 +1 @@
1
+ export * from './queue.ts';
@@ -0,0 +1,71 @@
1
+ import type Redlock from '@sesamecare-oss/redlock';
2
+ import type * as Bull from 'bullmq';
3
+ import type { OmitNever } from 'vona';
4
+ import type { IGeneralInfoOptions } from 'vona-module-a-executor';
5
+ import type { IOnionOptionsEnable, ServiceOnion } from 'vona-module-a-onion';
6
+ export interface IQueuePushOptions extends IGeneralInfoOptions {
7
+ queueNameSub?: string;
8
+ jobName?: string;
9
+ jobOptions?: Bull.JobsOptions;
10
+ }
11
+ export type TypeQueueJob<DATA = unknown, RESULT = unknown> = Bull.Job<IQueueJobContext<DATA>, RESULT>;
12
+ export interface IQueueExecute<DATA = unknown, RESULT = unknown> {
13
+ execute: (data: DATA, options?: IQueuePushOptions, job?: TypeQueueJob<DATA, RESULT>) => Promise<RESULT>;
14
+ }
15
+ export interface IQueueJobContext<DATA> {
16
+ queueName: keyof IQueueRecord;
17
+ data: DATA;
18
+ options?: IQueuePushOptions;
19
+ }
20
+ export interface IQueueWork {
21
+ redlock: Redlock.Redlock;
22
+ worker: Bull.Worker;
23
+ workerOptions: Bull.WorkerOptions;
24
+ }
25
+ export interface IQueueWorks {
26
+ [queueKey: string]: IQueueWork;
27
+ }
28
+ export interface IQueueQueue {
29
+ config?: IDecoratorQueueOptions;
30
+ options: Bull.QueueOptions;
31
+ queue: Bull.Queue;
32
+ queueEvents: Bull.QueueEvents;
33
+ queueEventsOptions: Bull.QueueEventsOptions;
34
+ }
35
+ export interface IQueueQueues {
36
+ [queueKey: string]: IQueueQueue;
37
+ }
38
+ export interface IQueueCallback<DATA, RESULT> {
39
+ info: IQueueJobContext<DATA>;
40
+ callback: (err: Error | undefined, data: RESULT | undefined) => void;
41
+ }
42
+ export interface IQueueCallbacks {
43
+ [jobId: string | number]: IQueueCallback<unknown, unknown>;
44
+ }
45
+ export interface IQueueRecord {
46
+ }
47
+ export interface IDecoratorQueueOptions extends IOnionOptionsEnable {
48
+ concurrency?: boolean;
49
+ transaction?: boolean;
50
+ options?: {
51
+ queue?: Bull.QueueOptions;
52
+ worker?: Partial<Bull.WorkerOptions>;
53
+ redlock?: Redlock.Redlock & {
54
+ lockTTL?: number;
55
+ };
56
+ job?: Bull.JobsOptions;
57
+ };
58
+ }
59
+ declare module 'vona-module-a-onion' {
60
+ interface BeanOnion {
61
+ queue: ServiceOnion<IDecoratorQueueOptions, keyof IQueueRecord>;
62
+ }
63
+ }
64
+ declare module 'vona' {
65
+ interface ConfigOnions {
66
+ queue: OmitNever<IQueueRecord>;
67
+ }
68
+ interface IBeanSceneRecord {
69
+ queue: never;
70
+ }
71
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "vona-module-a-queue",
3
3
  "type": "module",
4
- "version": "5.0.9",
4
+ "version": "5.0.11",
5
5
  "title": "a-queue",
6
6
  "vonaModule": {
7
7
  "dependencies": {},
@@ -43,8 +43,12 @@
43
43
  "dependencies": {
44
44
  "bullmq": "^5.49.1"
45
45
  },
46
+ "devDependencies": {
47
+ "clean-package": "^2.2.0",
48
+ "rimraf": "^6.0.1"
49
+ },
46
50
  "scripts": {
47
- "clean": "rimraf dist tsconfig.tsbuildinfo",
48
- "tsc:publish": "npm run clean && tsc"
51
+ "clean": "rimraf dist tsconfig.build.tsbuildinfo",
52
+ "tsc:publish": "npm run clean && vona :bin:buildModule && tsc -p tsconfig.build.json"
49
53
  }
50
54
  }