@devbro/pashmak 0.1.11 → 0.1.12
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/dist/app/console/migrate/make_migration.tpl +5 -5
- package/dist/app/console/queue/GenerateMigrateCommand.d.mts +9 -0
- package/dist/app/console/queue/GenerateMigrateCommand.mjs +51 -0
- package/dist/app/console/queue/GenerateMigrateCommand.mjs.map +1 -0
- package/dist/app/console/queue/queue_migration.tpl +19 -0
- package/dist/bin/app/console/DefaultCommand.cjs +160 -21
- package/dist/bin/app/console/KeyGenerateCommand.cjs +160 -21
- package/dist/bin/app/console/StartCommand.cjs +163 -24
- package/dist/bin/app/console/generate/GenerateControllerCommand.cjs +160 -21
- package/dist/bin/app/console/generate/index.cjs +160 -21
- package/dist/bin/app/console/index.cjs +162 -23
- package/dist/bin/app/console/migrate/GenerateMigrateCommand.cjs +160 -21
- package/dist/bin/app/console/migrate/MigrateCommand.cjs +161 -22
- package/dist/bin/app/console/migrate/MigrateRollbackCommand.cjs +160 -21
- package/dist/bin/app/console/migrate/index.cjs +160 -21
- package/dist/bin/app/console/queue/GenerateMigrateCommand.cjs +752 -0
- package/dist/bin/facades.cjs +163 -22
- package/dist/bin/factories.cjs +707 -0
- package/dist/bin/index.cjs +178 -28
- package/dist/bin/middlewares.cjs +161 -22
- package/dist/bin/queue.cjs +99 -0
- package/dist/facades.d.mts +3 -1
- package/dist/facades.mjs +15 -27
- package/dist/facades.mjs.map +1 -1
- package/dist/factories.d.mts +20 -0
- package/dist/factories.mjs +83 -0
- package/dist/factories.mjs.map +1 -0
- package/dist/queue.d.mts +15 -0
- package/dist/queue.mjs +73 -0
- package/dist/queue.mjs.map +1 -0
- package/package.json +7 -1
package/dist/bin/index.cjs
CHANGED
|
@@ -561,8 +561,165 @@ var init_http = __esm({
|
|
|
561
561
|
}
|
|
562
562
|
});
|
|
563
563
|
|
|
564
|
+
// src/queue.mts
|
|
565
|
+
var queue_exports = {};
|
|
566
|
+
__export(queue_exports, {
|
|
567
|
+
DatabaseTransport: () => DatabaseTransport
|
|
568
|
+
});
|
|
569
|
+
var import_neko_sql, DatabaseTransport;
|
|
570
|
+
var init_queue = __esm({
|
|
571
|
+
"src/queue.mts"() {
|
|
572
|
+
"use strict";
|
|
573
|
+
__reExport(queue_exports, require("@devbro/neko-queue"));
|
|
574
|
+
import_neko_sql = require("@devbro/neko-sql");
|
|
575
|
+
DatabaseTransport = class {
|
|
576
|
+
// default to 100 messages per fetch
|
|
577
|
+
constructor(db_config) {
|
|
578
|
+
this.db_config = db_config;
|
|
579
|
+
}
|
|
580
|
+
static {
|
|
581
|
+
__name(this, "DatabaseTransport");
|
|
582
|
+
}
|
|
583
|
+
listenInterval = 6e4;
|
|
584
|
+
// default to 1 minute
|
|
585
|
+
messageLimit = 100;
|
|
586
|
+
setListenInterval(interval) {
|
|
587
|
+
this.listenInterval = interval;
|
|
588
|
+
}
|
|
589
|
+
setMessageLimit(limit) {
|
|
590
|
+
this.messageLimit = limit;
|
|
591
|
+
}
|
|
592
|
+
async dispatch(channel, message) {
|
|
593
|
+
const conn = new import_neko_sql.PostgresqlConnection(this.db_config);
|
|
594
|
+
try {
|
|
595
|
+
await conn.connect();
|
|
596
|
+
let q = conn.getQuery();
|
|
597
|
+
await q.table("queue_messages").insert({
|
|
598
|
+
channel,
|
|
599
|
+
message,
|
|
600
|
+
processed: false,
|
|
601
|
+
created_at: /* @__PURE__ */ new Date(),
|
|
602
|
+
updated_at: /* @__PURE__ */ new Date(),
|
|
603
|
+
last_tried_at: null,
|
|
604
|
+
process_message: ""
|
|
605
|
+
});
|
|
606
|
+
} finally {
|
|
607
|
+
await conn.disconnect();
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
async listen(channel, callback) {
|
|
611
|
+
return new Promise(async (resolve, reject) => {
|
|
612
|
+
setInterval(async () => {
|
|
613
|
+
const conn = new import_neko_sql.PostgresqlConnection(this.db_config);
|
|
614
|
+
try {
|
|
615
|
+
await conn.connect();
|
|
616
|
+
let q = conn.getQuery();
|
|
617
|
+
let messages = await q.table("queue_messages").whereOp("channel", "=", channel).whereOp("processed", "=", false).limit(this.messageLimit).orderBy("last_tried_at", "asc").get();
|
|
618
|
+
for (let msg of messages) {
|
|
619
|
+
try {
|
|
620
|
+
await callback(msg.message);
|
|
621
|
+
await q.table("queue_messages").whereOp("id", "=", msg.id).update({
|
|
622
|
+
processed: true,
|
|
623
|
+
updated_at: /* @__PURE__ */ new Date()
|
|
624
|
+
});
|
|
625
|
+
} catch (error) {
|
|
626
|
+
await q.table("queue_messages").whereOp("id", "=", msg.id).update({
|
|
627
|
+
processed: false,
|
|
628
|
+
last_tried_at: /* @__PURE__ */ new Date(),
|
|
629
|
+
process_message: error.message || "Error processing message"
|
|
630
|
+
});
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
} finally {
|
|
634
|
+
await conn.disconnect();
|
|
635
|
+
}
|
|
636
|
+
}, this.listenInterval);
|
|
637
|
+
});
|
|
638
|
+
}
|
|
639
|
+
};
|
|
640
|
+
}
|
|
641
|
+
});
|
|
642
|
+
|
|
643
|
+
// src/factories.mts
|
|
644
|
+
var import_neko_mailer, import_neko_queue, import_neko_queue2, FlexibleFactory, MailerFactory, QueueFactory;
|
|
645
|
+
var init_factories = __esm({
|
|
646
|
+
"src/factories.mts"() {
|
|
647
|
+
"use strict";
|
|
648
|
+
import_neko_mailer = require("@devbro/neko-mailer");
|
|
649
|
+
init_facades();
|
|
650
|
+
import_neko_queue = require("@devbro/neko-queue");
|
|
651
|
+
import_neko_queue2 = require("@devbro/neko-queue");
|
|
652
|
+
init_queue();
|
|
653
|
+
FlexibleFactory = class {
|
|
654
|
+
static {
|
|
655
|
+
__name(this, "FlexibleFactory");
|
|
656
|
+
}
|
|
657
|
+
registry = /* @__PURE__ */ new Map();
|
|
658
|
+
register(key, ctor) {
|
|
659
|
+
this.registry.set(key, ctor);
|
|
660
|
+
}
|
|
661
|
+
create(key, ...args) {
|
|
662
|
+
const ctor = this.registry.get(key);
|
|
663
|
+
if (!ctor) {
|
|
664
|
+
throw new Error(`No factory registered for key: ${key}`);
|
|
665
|
+
}
|
|
666
|
+
return new ctor(...args);
|
|
667
|
+
}
|
|
668
|
+
};
|
|
669
|
+
MailerFactory = class _MailerFactory {
|
|
670
|
+
static {
|
|
671
|
+
__name(this, "MailerFactory");
|
|
672
|
+
}
|
|
673
|
+
static instance = new FlexibleFactory();
|
|
674
|
+
static register(key, factory) {
|
|
675
|
+
_MailerFactory.instance.register(key, factory);
|
|
676
|
+
}
|
|
677
|
+
static create(key, ...args) {
|
|
678
|
+
return _MailerFactory.instance.create(key, ...args);
|
|
679
|
+
}
|
|
680
|
+
};
|
|
681
|
+
MailerFactory.register("logger", (opt) => {
|
|
682
|
+
return new import_neko_mailer.FunctionProvider((mail) => {
|
|
683
|
+
logger().info({
|
|
684
|
+
msg: "Sending email",
|
|
685
|
+
mail
|
|
686
|
+
});
|
|
687
|
+
});
|
|
688
|
+
});
|
|
689
|
+
MailerFactory.register("SES", (opt) => {
|
|
690
|
+
return new import_neko_mailer.SESProvider(opt);
|
|
691
|
+
});
|
|
692
|
+
MailerFactory.register("SMTP", (opt) => {
|
|
693
|
+
return new import_neko_mailer.SMTPProvider(opt);
|
|
694
|
+
});
|
|
695
|
+
MailerFactory.register("MEMORY", (opt) => {
|
|
696
|
+
return new import_neko_mailer.MemoryProvider();
|
|
697
|
+
});
|
|
698
|
+
QueueFactory = class _QueueFactory {
|
|
699
|
+
static {
|
|
700
|
+
__name(this, "QueueFactory");
|
|
701
|
+
}
|
|
702
|
+
static instance = new FlexibleFactory();
|
|
703
|
+
static register(key, factory) {
|
|
704
|
+
_QueueFactory.instance.register(key, factory);
|
|
705
|
+
}
|
|
706
|
+
static create(key, ...args) {
|
|
707
|
+
return _QueueFactory.instance.create(key, ...args);
|
|
708
|
+
}
|
|
709
|
+
};
|
|
710
|
+
QueueFactory.register("database", (opt) => {
|
|
711
|
+
let transport = new DatabaseTransport(opt);
|
|
712
|
+
return new import_neko_queue.QueueConnection(transport);
|
|
713
|
+
});
|
|
714
|
+
QueueFactory.register("memory", (opt) => {
|
|
715
|
+
let transport = new import_neko_queue2.MemoryTransport(opt);
|
|
716
|
+
return new import_neko_queue.QueueConnection(transport);
|
|
717
|
+
});
|
|
718
|
+
}
|
|
719
|
+
});
|
|
720
|
+
|
|
564
721
|
// src/facades.mts
|
|
565
|
-
var import_neko_scheduler, import_neko_helper, import_neko_context2, import_neko_storage,
|
|
722
|
+
var import_neko_scheduler, import_neko_helper, import_neko_context2, import_neko_storage, import_neko_mailer2, import_neko_config, import_clipanion, yup, import_neko_logger, router, scheduler, db, storage, cli, httpServer, logger, mailer, queue;
|
|
566
723
|
var init_facades = __esm({
|
|
567
724
|
"src/facades.mts"() {
|
|
568
725
|
"use strict";
|
|
@@ -571,13 +728,14 @@ var init_facades = __esm({
|
|
|
571
728
|
import_neko_helper = require("@devbro/neko-helper");
|
|
572
729
|
import_neko_context2 = require("@devbro/neko-context");
|
|
573
730
|
import_neko_storage = require("@devbro/neko-storage");
|
|
574
|
-
|
|
731
|
+
import_neko_mailer2 = require("@devbro/neko-mailer");
|
|
575
732
|
import_neko_config = require("@devbro/neko-config");
|
|
576
733
|
import_clipanion = require("clipanion");
|
|
577
734
|
init_http();
|
|
578
735
|
init_http();
|
|
579
736
|
yup = __toESM(require("yup"), 1);
|
|
580
737
|
import_neko_logger = require("@devbro/neko-logger");
|
|
738
|
+
init_factories();
|
|
581
739
|
router = (0, import_neko_helper.createSingleton)(() => new Router());
|
|
582
740
|
scheduler = (0, import_neko_helper.createSingleton)(() => {
|
|
583
741
|
const rc = new import_neko_scheduler.Scheduler();
|
|
@@ -648,27 +806,19 @@ var init_facades = __esm({
|
|
|
648
806
|
});
|
|
649
807
|
mailer = (0, import_neko_helper.createSingleton)((label) => {
|
|
650
808
|
const mailer_config = import_neko_config.config.get(["mailer", label].join("."));
|
|
651
|
-
let provider
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
provider = new import_neko_mailer.SMTPProvider(mailer_config.config);
|
|
663
|
-
} else if (mailer_config.provider === "MEMORY") {
|
|
664
|
-
provider = new import_neko_mailer.MemoryProvider();
|
|
665
|
-
}
|
|
666
|
-
if (!provider) {
|
|
667
|
-
throw new Error(
|
|
668
|
-
`cannot initiate mailer provider: ${mailer_config?.provider}`
|
|
669
|
-
);
|
|
809
|
+
let provider = MailerFactory.create(
|
|
810
|
+
mailer_config.provider,
|
|
811
|
+
mailer_config.config
|
|
812
|
+
);
|
|
813
|
+
const rc = new import_neko_mailer2.Mailer(provider);
|
|
814
|
+
return rc;
|
|
815
|
+
});
|
|
816
|
+
queue = (0, import_neko_helper.createSingleton)(async (label) => {
|
|
817
|
+
const queue_config = import_neko_config.config.get(["queues", label].join("."));
|
|
818
|
+
if (!queue_config) {
|
|
819
|
+
throw new Error(`Queue configuration for '${label}' not found`);
|
|
670
820
|
}
|
|
671
|
-
const rc =
|
|
821
|
+
const rc = await QueueFactory.create(queue_config.type, queue_config);
|
|
672
822
|
return rc;
|
|
673
823
|
});
|
|
674
824
|
}
|
|
@@ -2052,14 +2202,14 @@ var init_migrate = __esm({
|
|
|
2052
2202
|
});
|
|
2053
2203
|
|
|
2054
2204
|
// src/app/console/StartCommand.mts
|
|
2055
|
-
var import_clipanion5, import_neko_config5,
|
|
2205
|
+
var import_clipanion5, import_neko_config5, import_neko_sql2, StartCommand;
|
|
2056
2206
|
var init_StartCommand = __esm({
|
|
2057
2207
|
"src/app/console/StartCommand.mts"() {
|
|
2058
2208
|
"use strict";
|
|
2059
2209
|
import_clipanion5 = require("clipanion");
|
|
2060
2210
|
import_neko_config5 = require("@devbro/neko-config");
|
|
2061
2211
|
init_facades();
|
|
2062
|
-
|
|
2212
|
+
import_neko_sql2 = require("@devbro/neko-sql");
|
|
2063
2213
|
StartCommand = class extends import_clipanion5.Command {
|
|
2064
2214
|
static {
|
|
2065
2215
|
__name(this, "StartCommand");
|
|
@@ -2078,7 +2228,7 @@ var init_StartCommand = __esm({
|
|
|
2078
2228
|
}
|
|
2079
2229
|
logger().info(`Starting Server
|
|
2080
2230
|
`);
|
|
2081
|
-
|
|
2231
|
+
import_neko_sql2.PostgresqlConnection.defaults.idleTimeoutMillis = 1e4;
|
|
2082
2232
|
if (this.scheduler || this.all) {
|
|
2083
2233
|
logger().info(`starting scheduler
|
|
2084
2234
|
`);
|
|
@@ -2441,12 +2591,12 @@ var DatabaseServiceProvider_exports = {};
|
|
|
2441
2591
|
__export(DatabaseServiceProvider_exports, {
|
|
2442
2592
|
DatabaseServiceProvider: () => DatabaseServiceProvider
|
|
2443
2593
|
});
|
|
2444
|
-
var
|
|
2594
|
+
var import_neko_sql3, import_neko_orm, import_neko_context5, import_neko_config7, DatabaseServiceProvider;
|
|
2445
2595
|
var init_DatabaseServiceProvider = __esm({
|
|
2446
2596
|
"src/DatabaseServiceProvider.mts"() {
|
|
2447
2597
|
"use strict";
|
|
2448
2598
|
init_dist();
|
|
2449
|
-
|
|
2599
|
+
import_neko_sql3 = require("@devbro/neko-sql");
|
|
2450
2600
|
import_neko_orm = require("@devbro/neko-orm");
|
|
2451
2601
|
import_neko_context5 = require("@devbro/neko-context");
|
|
2452
2602
|
import_neko_config7 = require("@devbro/neko-config");
|
|
@@ -2483,7 +2633,7 @@ var init_DatabaseServiceProvider = __esm({
|
|
|
2483
2633
|
return _DatabaseServiceProvider.instance;
|
|
2484
2634
|
}
|
|
2485
2635
|
async getConnection(db_config) {
|
|
2486
|
-
const conn = new
|
|
2636
|
+
const conn = new import_neko_sql3.PostgresqlConnection(db_config);
|
|
2487
2637
|
if (!await conn.connect()) {
|
|
2488
2638
|
throw new Error("Failed to connect to the database");
|
|
2489
2639
|
}
|
package/dist/bin/middlewares.cjs
CHANGED
|
@@ -458,7 +458,7 @@ var import_neko_scheduler = require("@devbro/neko-scheduler");
|
|
|
458
458
|
var import_neko_helper = require("@devbro/neko-helper");
|
|
459
459
|
var import_neko_context2 = require("@devbro/neko-context");
|
|
460
460
|
var import_neko_storage = require("@devbro/neko-storage");
|
|
461
|
-
var
|
|
461
|
+
var import_neko_mailer2 = require("@devbro/neko-mailer");
|
|
462
462
|
var import_neko_config = require("@devbro/neko-config");
|
|
463
463
|
var import_clipanion = require("clipanion");
|
|
464
464
|
|
|
@@ -469,6 +469,153 @@ __reExport(http_exports, require("@devbro/neko-http"));
|
|
|
469
469
|
// src/facades.mts
|
|
470
470
|
var yup = __toESM(require("yup"), 1);
|
|
471
471
|
var import_neko_logger = require("@devbro/neko-logger");
|
|
472
|
+
|
|
473
|
+
// src/factories.mts
|
|
474
|
+
var import_neko_mailer = require("@devbro/neko-mailer");
|
|
475
|
+
var import_neko_queue = require("@devbro/neko-queue");
|
|
476
|
+
var import_neko_queue2 = require("@devbro/neko-queue");
|
|
477
|
+
|
|
478
|
+
// src/queue.mts
|
|
479
|
+
var queue_exports = {};
|
|
480
|
+
__export(queue_exports, {
|
|
481
|
+
DatabaseTransport: () => DatabaseTransport
|
|
482
|
+
});
|
|
483
|
+
__reExport(queue_exports, require("@devbro/neko-queue"));
|
|
484
|
+
var import_neko_sql = require("@devbro/neko-sql");
|
|
485
|
+
var DatabaseTransport = class {
|
|
486
|
+
// default to 100 messages per fetch
|
|
487
|
+
constructor(db_config) {
|
|
488
|
+
this.db_config = db_config;
|
|
489
|
+
}
|
|
490
|
+
static {
|
|
491
|
+
__name(this, "DatabaseTransport");
|
|
492
|
+
}
|
|
493
|
+
listenInterval = 6e4;
|
|
494
|
+
// default to 1 minute
|
|
495
|
+
messageLimit = 100;
|
|
496
|
+
setListenInterval(interval) {
|
|
497
|
+
this.listenInterval = interval;
|
|
498
|
+
}
|
|
499
|
+
setMessageLimit(limit) {
|
|
500
|
+
this.messageLimit = limit;
|
|
501
|
+
}
|
|
502
|
+
async dispatch(channel, message) {
|
|
503
|
+
const conn = new import_neko_sql.PostgresqlConnection(this.db_config);
|
|
504
|
+
try {
|
|
505
|
+
await conn.connect();
|
|
506
|
+
let q = conn.getQuery();
|
|
507
|
+
await q.table("queue_messages").insert({
|
|
508
|
+
channel,
|
|
509
|
+
message,
|
|
510
|
+
processed: false,
|
|
511
|
+
created_at: /* @__PURE__ */ new Date(),
|
|
512
|
+
updated_at: /* @__PURE__ */ new Date(),
|
|
513
|
+
last_tried_at: null,
|
|
514
|
+
process_message: ""
|
|
515
|
+
});
|
|
516
|
+
} finally {
|
|
517
|
+
await conn.disconnect();
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
async listen(channel, callback) {
|
|
521
|
+
return new Promise(async (resolve, reject) => {
|
|
522
|
+
setInterval(async () => {
|
|
523
|
+
const conn = new import_neko_sql.PostgresqlConnection(this.db_config);
|
|
524
|
+
try {
|
|
525
|
+
await conn.connect();
|
|
526
|
+
let q = conn.getQuery();
|
|
527
|
+
let messages = await q.table("queue_messages").whereOp("channel", "=", channel).whereOp("processed", "=", false).limit(this.messageLimit).orderBy("last_tried_at", "asc").get();
|
|
528
|
+
for (let msg of messages) {
|
|
529
|
+
try {
|
|
530
|
+
await callback(msg.message);
|
|
531
|
+
await q.table("queue_messages").whereOp("id", "=", msg.id).update({
|
|
532
|
+
processed: true,
|
|
533
|
+
updated_at: /* @__PURE__ */ new Date()
|
|
534
|
+
});
|
|
535
|
+
} catch (error) {
|
|
536
|
+
await q.table("queue_messages").whereOp("id", "=", msg.id).update({
|
|
537
|
+
processed: false,
|
|
538
|
+
last_tried_at: /* @__PURE__ */ new Date(),
|
|
539
|
+
process_message: error.message || "Error processing message"
|
|
540
|
+
});
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
} finally {
|
|
544
|
+
await conn.disconnect();
|
|
545
|
+
}
|
|
546
|
+
}, this.listenInterval);
|
|
547
|
+
});
|
|
548
|
+
}
|
|
549
|
+
};
|
|
550
|
+
|
|
551
|
+
// src/factories.mts
|
|
552
|
+
var FlexibleFactory = class {
|
|
553
|
+
static {
|
|
554
|
+
__name(this, "FlexibleFactory");
|
|
555
|
+
}
|
|
556
|
+
registry = /* @__PURE__ */ new Map();
|
|
557
|
+
register(key, ctor) {
|
|
558
|
+
this.registry.set(key, ctor);
|
|
559
|
+
}
|
|
560
|
+
create(key, ...args) {
|
|
561
|
+
const ctor = this.registry.get(key);
|
|
562
|
+
if (!ctor) {
|
|
563
|
+
throw new Error(`No factory registered for key: ${key}`);
|
|
564
|
+
}
|
|
565
|
+
return new ctor(...args);
|
|
566
|
+
}
|
|
567
|
+
};
|
|
568
|
+
var MailerFactory = class _MailerFactory {
|
|
569
|
+
static {
|
|
570
|
+
__name(this, "MailerFactory");
|
|
571
|
+
}
|
|
572
|
+
static instance = new FlexibleFactory();
|
|
573
|
+
static register(key, factory) {
|
|
574
|
+
_MailerFactory.instance.register(key, factory);
|
|
575
|
+
}
|
|
576
|
+
static create(key, ...args) {
|
|
577
|
+
return _MailerFactory.instance.create(key, ...args);
|
|
578
|
+
}
|
|
579
|
+
};
|
|
580
|
+
MailerFactory.register("logger", (opt) => {
|
|
581
|
+
return new import_neko_mailer.FunctionProvider((mail) => {
|
|
582
|
+
logger().info({
|
|
583
|
+
msg: "Sending email",
|
|
584
|
+
mail
|
|
585
|
+
});
|
|
586
|
+
});
|
|
587
|
+
});
|
|
588
|
+
MailerFactory.register("SES", (opt) => {
|
|
589
|
+
return new import_neko_mailer.SESProvider(opt);
|
|
590
|
+
});
|
|
591
|
+
MailerFactory.register("SMTP", (opt) => {
|
|
592
|
+
return new import_neko_mailer.SMTPProvider(opt);
|
|
593
|
+
});
|
|
594
|
+
MailerFactory.register("MEMORY", (opt) => {
|
|
595
|
+
return new import_neko_mailer.MemoryProvider();
|
|
596
|
+
});
|
|
597
|
+
var QueueFactory = class _QueueFactory {
|
|
598
|
+
static {
|
|
599
|
+
__name(this, "QueueFactory");
|
|
600
|
+
}
|
|
601
|
+
static instance = new FlexibleFactory();
|
|
602
|
+
static register(key, factory) {
|
|
603
|
+
_QueueFactory.instance.register(key, factory);
|
|
604
|
+
}
|
|
605
|
+
static create(key, ...args) {
|
|
606
|
+
return _QueueFactory.instance.create(key, ...args);
|
|
607
|
+
}
|
|
608
|
+
};
|
|
609
|
+
QueueFactory.register("database", (opt) => {
|
|
610
|
+
let transport = new DatabaseTransport(opt);
|
|
611
|
+
return new import_neko_queue.QueueConnection(transport);
|
|
612
|
+
});
|
|
613
|
+
QueueFactory.register("memory", (opt) => {
|
|
614
|
+
let transport = new import_neko_queue2.MemoryTransport(opt);
|
|
615
|
+
return new import_neko_queue.QueueConnection(transport);
|
|
616
|
+
});
|
|
617
|
+
|
|
618
|
+
// src/facades.mts
|
|
472
619
|
var router = (0, import_neko_helper.createSingleton)(() => new Router());
|
|
473
620
|
var scheduler = (0, import_neko_helper.createSingleton)(() => {
|
|
474
621
|
const rc = new import_neko_scheduler.Scheduler();
|
|
@@ -539,27 +686,19 @@ var logger = (0, import_neko_helper.createSingleton)((label) => {
|
|
|
539
686
|
});
|
|
540
687
|
var mailer = (0, import_neko_helper.createSingleton)((label) => {
|
|
541
688
|
const mailer_config = import_neko_config.config.get(["mailer", label].join("."));
|
|
542
|
-
let provider
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
provider = new import_neko_mailer.MemoryProvider();
|
|
556
|
-
}
|
|
557
|
-
if (!provider) {
|
|
558
|
-
throw new Error(
|
|
559
|
-
`cannot initiate mailer provider: ${mailer_config?.provider}`
|
|
560
|
-
);
|
|
561
|
-
}
|
|
562
|
-
const rc = new import_neko_mailer.Mailer(provider);
|
|
689
|
+
let provider = MailerFactory.create(
|
|
690
|
+
mailer_config.provider,
|
|
691
|
+
mailer_config.config
|
|
692
|
+
);
|
|
693
|
+
const rc = new import_neko_mailer2.Mailer(provider);
|
|
694
|
+
return rc;
|
|
695
|
+
});
|
|
696
|
+
var queue = (0, import_neko_helper.createSingleton)(async (label) => {
|
|
697
|
+
const queue_config = import_neko_config.config.get(["queues", label].join("."));
|
|
698
|
+
if (!queue_config) {
|
|
699
|
+
throw new Error(`Queue configuration for '${label}' not found`);
|
|
700
|
+
}
|
|
701
|
+
const rc = await QueueFactory.create(queue_config.type, queue_config);
|
|
563
702
|
return rc;
|
|
564
703
|
});
|
|
565
704
|
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
11
|
+
var __copyProps = (to, from, except, desc) => {
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
+
for (let key of __getOwnPropNames(from))
|
|
14
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
|
|
20
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
21
|
+
|
|
22
|
+
// src/queue.mts
|
|
23
|
+
var queue_exports = {};
|
|
24
|
+
__export(queue_exports, {
|
|
25
|
+
DatabaseTransport: () => DatabaseTransport
|
|
26
|
+
});
|
|
27
|
+
module.exports = __toCommonJS(queue_exports);
|
|
28
|
+
__reExport(queue_exports, require("@devbro/neko-queue"), module.exports);
|
|
29
|
+
var import_neko_sql = require("@devbro/neko-sql");
|
|
30
|
+
var DatabaseTransport = class {
|
|
31
|
+
// default to 100 messages per fetch
|
|
32
|
+
constructor(db_config) {
|
|
33
|
+
this.db_config = db_config;
|
|
34
|
+
}
|
|
35
|
+
static {
|
|
36
|
+
__name(this, "DatabaseTransport");
|
|
37
|
+
}
|
|
38
|
+
listenInterval = 6e4;
|
|
39
|
+
// default to 1 minute
|
|
40
|
+
messageLimit = 100;
|
|
41
|
+
setListenInterval(interval) {
|
|
42
|
+
this.listenInterval = interval;
|
|
43
|
+
}
|
|
44
|
+
setMessageLimit(limit) {
|
|
45
|
+
this.messageLimit = limit;
|
|
46
|
+
}
|
|
47
|
+
async dispatch(channel, message) {
|
|
48
|
+
const conn = new import_neko_sql.PostgresqlConnection(this.db_config);
|
|
49
|
+
try {
|
|
50
|
+
await conn.connect();
|
|
51
|
+
let q = conn.getQuery();
|
|
52
|
+
await q.table("queue_messages").insert({
|
|
53
|
+
channel,
|
|
54
|
+
message,
|
|
55
|
+
processed: false,
|
|
56
|
+
created_at: /* @__PURE__ */ new Date(),
|
|
57
|
+
updated_at: /* @__PURE__ */ new Date(),
|
|
58
|
+
last_tried_at: null,
|
|
59
|
+
process_message: ""
|
|
60
|
+
});
|
|
61
|
+
} finally {
|
|
62
|
+
await conn.disconnect();
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
async listen(channel, callback) {
|
|
66
|
+
return new Promise(async (resolve, reject) => {
|
|
67
|
+
setInterval(async () => {
|
|
68
|
+
const conn = new import_neko_sql.PostgresqlConnection(this.db_config);
|
|
69
|
+
try {
|
|
70
|
+
await conn.connect();
|
|
71
|
+
let q = conn.getQuery();
|
|
72
|
+
let messages = await q.table("queue_messages").whereOp("channel", "=", channel).whereOp("processed", "=", false).limit(this.messageLimit).orderBy("last_tried_at", "asc").get();
|
|
73
|
+
for (let msg of messages) {
|
|
74
|
+
try {
|
|
75
|
+
await callback(msg.message);
|
|
76
|
+
await q.table("queue_messages").whereOp("id", "=", msg.id).update({
|
|
77
|
+
processed: true,
|
|
78
|
+
updated_at: /* @__PURE__ */ new Date()
|
|
79
|
+
});
|
|
80
|
+
} catch (error) {
|
|
81
|
+
await q.table("queue_messages").whereOp("id", "=", msg.id).update({
|
|
82
|
+
processed: false,
|
|
83
|
+
last_tried_at: /* @__PURE__ */ new Date(),
|
|
84
|
+
process_message: error.message || "Error processing message"
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
} finally {
|
|
89
|
+
await conn.disconnect();
|
|
90
|
+
}
|
|
91
|
+
}, this.listenInterval);
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
96
|
+
0 && (module.exports = {
|
|
97
|
+
DatabaseTransport,
|
|
98
|
+
...require("@devbro/neko-queue")
|
|
99
|
+
});
|
package/dist/facades.d.mts
CHANGED
|
@@ -7,6 +7,7 @@ import { Storage } from '@devbro/neko-storage';
|
|
|
7
7
|
import { Mailer } from '@devbro/neko-mailer';
|
|
8
8
|
import { HttpServer } from '@devbro/neko-http';
|
|
9
9
|
import { Logger } from '@devbro/neko-logger';
|
|
10
|
+
import { QueueConnection } from '@devbro/neko-queue';
|
|
10
11
|
|
|
11
12
|
declare const router: (label?: string, ...args: any[]) => Router;
|
|
12
13
|
declare const scheduler: (label?: string, ...args: any[]) => Scheduler;
|
|
@@ -16,5 +17,6 @@ declare const cli: (label?: string, ...args: any[]) => Cli<clipanion.BaseContext
|
|
|
16
17
|
declare const httpServer: (label?: string, ...args: any[]) => HttpServer;
|
|
17
18
|
declare const logger: (label?: string, ...args: any[]) => Logger;
|
|
18
19
|
declare const mailer: (label?: string, ...args: any[]) => Mailer;
|
|
20
|
+
declare const queue: (label?: string, ...args: any[]) => Promise<QueueConnection<any>>;
|
|
19
21
|
|
|
20
|
-
export { cli, db, httpServer, logger, mailer, router, scheduler, storage };
|
|
22
|
+
export { cli, db, httpServer, logger, mailer, queue, router, scheduler, storage };
|
package/dist/facades.mjs
CHANGED
|
@@ -5,19 +5,14 @@ import { Scheduler } from "@devbro/neko-scheduler";
|
|
|
5
5
|
import { createSingleton } from "@devbro/neko-helper";
|
|
6
6
|
import { ctx, ctxSafe } from "@devbro/neko-context";
|
|
7
7
|
import { StorageFactory } from "@devbro/neko-storage";
|
|
8
|
-
import {
|
|
9
|
-
Mailer,
|
|
10
|
-
FunctionProvider,
|
|
11
|
-
SESProvider,
|
|
12
|
-
SMTPProvider,
|
|
13
|
-
MemoryProvider
|
|
14
|
-
} from "@devbro/neko-mailer";
|
|
8
|
+
import { Mailer } from "@devbro/neko-mailer";
|
|
15
9
|
import { config } from "@devbro/neko-config";
|
|
16
10
|
import { Cli } from "clipanion";
|
|
17
11
|
import { HttpServer } from "./http.mjs";
|
|
18
12
|
import { HttpError } from "./http.mjs";
|
|
19
13
|
import * as yup from "yup";
|
|
20
14
|
import { Logger } from "@devbro/neko-logger";
|
|
15
|
+
import { MailerFactory, QueueFactory } from "./factories.mts";
|
|
21
16
|
const router = createSingleton(() => new Router());
|
|
22
17
|
const scheduler = createSingleton(() => {
|
|
23
18
|
const rc = new Scheduler();
|
|
@@ -88,35 +83,28 @@ const logger = createSingleton((label) => {
|
|
|
88
83
|
});
|
|
89
84
|
const mailer = createSingleton((label) => {
|
|
90
85
|
const mailer_config = config.get(["mailer", label].join("."));
|
|
91
|
-
let provider
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
msg: "Sending email",
|
|
96
|
-
mail
|
|
97
|
-
});
|
|
98
|
-
});
|
|
99
|
-
} else if (mailer_config.provider === "SES") {
|
|
100
|
-
provider = new SESProvider(mailer_config.config);
|
|
101
|
-
} else if (mailer_config.provider === "SMTP") {
|
|
102
|
-
provider = new SMTPProvider(mailer_config.config);
|
|
103
|
-
} else if (mailer_config.provider === "MEMORY") {
|
|
104
|
-
provider = new MemoryProvider();
|
|
105
|
-
}
|
|
106
|
-
if (!provider) {
|
|
107
|
-
throw new Error(
|
|
108
|
-
`cannot initiate mailer provider: ${mailer_config?.provider}`
|
|
109
|
-
);
|
|
110
|
-
}
|
|
86
|
+
let provider = MailerFactory.create(
|
|
87
|
+
mailer_config.provider,
|
|
88
|
+
mailer_config.config
|
|
89
|
+
);
|
|
111
90
|
const rc = new Mailer(provider);
|
|
112
91
|
return rc;
|
|
113
92
|
});
|
|
93
|
+
const queue = createSingleton(async (label) => {
|
|
94
|
+
const queue_config = config.get(["queues", label].join("."));
|
|
95
|
+
if (!queue_config) {
|
|
96
|
+
throw new Error(`Queue configuration for '${label}' not found`);
|
|
97
|
+
}
|
|
98
|
+
const rc = await QueueFactory.create(queue_config.type, queue_config);
|
|
99
|
+
return rc;
|
|
100
|
+
});
|
|
114
101
|
export {
|
|
115
102
|
cli,
|
|
116
103
|
db,
|
|
117
104
|
httpServer,
|
|
118
105
|
logger,
|
|
119
106
|
mailer,
|
|
107
|
+
queue,
|
|
120
108
|
router,
|
|
121
109
|
scheduler,
|
|
122
110
|
storage
|