@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.
Files changed (31) hide show
  1. package/dist/app/console/migrate/make_migration.tpl +5 -5
  2. package/dist/app/console/queue/GenerateMigrateCommand.d.mts +9 -0
  3. package/dist/app/console/queue/GenerateMigrateCommand.mjs +51 -0
  4. package/dist/app/console/queue/GenerateMigrateCommand.mjs.map +1 -0
  5. package/dist/app/console/queue/queue_migration.tpl +19 -0
  6. package/dist/bin/app/console/DefaultCommand.cjs +160 -21
  7. package/dist/bin/app/console/KeyGenerateCommand.cjs +160 -21
  8. package/dist/bin/app/console/StartCommand.cjs +163 -24
  9. package/dist/bin/app/console/generate/GenerateControllerCommand.cjs +160 -21
  10. package/dist/bin/app/console/generate/index.cjs +160 -21
  11. package/dist/bin/app/console/index.cjs +162 -23
  12. package/dist/bin/app/console/migrate/GenerateMigrateCommand.cjs +160 -21
  13. package/dist/bin/app/console/migrate/MigrateCommand.cjs +161 -22
  14. package/dist/bin/app/console/migrate/MigrateRollbackCommand.cjs +160 -21
  15. package/dist/bin/app/console/migrate/index.cjs +160 -21
  16. package/dist/bin/app/console/queue/GenerateMigrateCommand.cjs +752 -0
  17. package/dist/bin/facades.cjs +163 -22
  18. package/dist/bin/factories.cjs +707 -0
  19. package/dist/bin/index.cjs +178 -28
  20. package/dist/bin/middlewares.cjs +161 -22
  21. package/dist/bin/queue.cjs +99 -0
  22. package/dist/facades.d.mts +3 -1
  23. package/dist/facades.mjs +15 -27
  24. package/dist/facades.mjs.map +1 -1
  25. package/dist/factories.d.mts +20 -0
  26. package/dist/factories.mjs +83 -0
  27. package/dist/factories.mjs.map +1 -0
  28. package/dist/queue.d.mts +15 -0
  29. package/dist/queue.mjs +73 -0
  30. package/dist/queue.mjs.map +1 -0
  31. package/package.json +7 -1
@@ -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, import_neko_mailer, import_neko_config, import_clipanion, yup, import_neko_logger, router, scheduler, db, storage, cli, httpServer, logger, mailer;
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
- import_neko_mailer = require("@devbro/neko-mailer");
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
- if (mailer_config.provider === "logger") {
653
- provider = new import_neko_mailer.FunctionProvider((mail) => {
654
- logger().info({
655
- msg: "Sending email",
656
- mail
657
- });
658
- });
659
- } else if (mailer_config.provider === "SES") {
660
- provider = new import_neko_mailer.SESProvider(mailer_config.config);
661
- } else if (mailer_config.provider === "SMTP") {
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 = new import_neko_mailer.Mailer(provider);
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, import_neko_sql, StartCommand;
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
- import_neko_sql = require("@devbro/neko-sql");
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
- import_neko_sql.PostgresqlConnection.defaults.idleTimeoutMillis = 1e4;
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 import_neko_sql2, import_neko_orm, import_neko_context5, import_neko_config7, DatabaseServiceProvider;
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
- import_neko_sql2 = require("@devbro/neko-sql");
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 import_neko_sql2.PostgresqlConnection(db_config);
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
  }
@@ -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 import_neko_mailer = require("@devbro/neko-mailer");
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
- if (mailer_config.provider === "logger") {
544
- provider = new import_neko_mailer.FunctionProvider((mail) => {
545
- logger().info({
546
- msg: "Sending email",
547
- mail
548
- });
549
- });
550
- } else if (mailer_config.provider === "SES") {
551
- provider = new import_neko_mailer.SESProvider(mailer_config.config);
552
- } else if (mailer_config.provider === "SMTP") {
553
- provider = new import_neko_mailer.SMTPProvider(mailer_config.config);
554
- } else if (mailer_config.provider === "MEMORY") {
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
+ });
@@ -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
- if (mailer_config.provider === "logger") {
93
- provider = new FunctionProvider((mail) => {
94
- logger().info({
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