@automagik/omni 2.260915.3 → 2.260915.5

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/index.js CHANGED
@@ -137289,7 +137289,7 @@ import { fileURLToPath } from "url";
137289
137289
  // package.json
137290
137290
  var package_default = {
137291
137291
  name: "@automagik/omni",
137292
- version: "2.260915.3",
137292
+ version: "2.260915.5",
137293
137293
  repository: {
137294
137294
  type: "git",
137295
137295
  url: "git+https://github.com/automagik-dev/omni.git",
@@ -250986,7 +250986,7 @@ var init_sentry_scrub = __esm(() => {
250986
250986
  var require_package7 = __commonJS((exports, module) => {
250987
250987
  module.exports = {
250988
250988
  name: "@omni/api",
250989
- version: "2.260915.3",
250989
+ version: "2.260915.5",
250990
250990
  private: true,
250991
250991
  type: "module",
250992
250992
  exports: {
@@ -369798,6 +369798,7 @@ class DeadLetterService {
369798
369798
  get db() {
369799
369799
  return scopedHandle(this.pool);
369800
369800
  }
369801
+ warnedNoBus = false;
369801
369802
  constructor(pool, eventBus) {
369802
369803
  this.pool = pool;
369803
369804
  this.eventBus = eventBus;
@@ -369883,6 +369884,12 @@ class DeadLetterService {
369883
369884
  }
369884
369885
  async publishSystemEvent(result) {
369885
369886
  if (!this.eventBus) {
369887
+ if (!this.warnedNoBus) {
369888
+ this.warnedNoBus = true;
369889
+ log102.warn("No event bus: dead letter announcements disabled \u2014 no system.dead_letter will be published", {
369890
+ deadLetterId: result.id
369891
+ });
369892
+ }
369886
369893
  return;
369887
369894
  }
369888
369895
  try {
@@ -370012,6 +370019,13 @@ class DeadLetterService {
370012
370019
  const [result] = await this.db.select({ count: sql`count(*)::int` }).from(deadLetterEvents).where(eq(deadLetterEvents.status, "pending"));
370013
370020
  return result?.count ?? 0;
370014
370021
  }
370022
+ async getPendingSummary() {
370023
+ const [result] = await this.db.select({
370024
+ pending: sql`count(*)::int`,
370025
+ oldest: sql`min(${deadLetterEvents.createdAt})`
370026
+ }).from(deadLetterEvents).where(eq(deadLetterEvents.status, "pending"));
370027
+ return { pending: result?.pending ?? 0, oldestPendingAt: result?.oldest ? new Date(result.oldest) : null };
370028
+ }
370015
370029
  async getStats() {
370016
370030
  const [totals] = await this.db.select({
370017
370031
  total: sql`count(*)::int`,
@@ -376546,6 +376560,25 @@ function getPluginsDegradedReason() {
376546
376560
  var pluginsDegraded = false, pluginsDegradedReason = null;
376547
376561
 
376548
376562
  // ../api/src/routes/health.ts
376563
+ async function checkDeadLetters(services) {
376564
+ if (!services)
376565
+ return { status: "ok", details: { available: false } };
376566
+ try {
376567
+ const { pending: pending2, oldestPendingAt } = await services.deadLetters.getPendingSummary();
376568
+ const oldestPendingAgeSeconds = oldestPendingAt ? Math.floor((Date.now() - oldestPendingAt.getTime()) / 1000) : null;
376569
+ const details = { pending: pending2, oldestPendingAgeSeconds };
376570
+ if (pending2 >= DEAD_LETTER_PENDING_THRESHOLD) {
376571
+ return { status: "error", details, error: `${pending2} pending dead letters` };
376572
+ }
376573
+ if (oldestPendingAgeSeconds !== null && oldestPendingAgeSeconds >= DEAD_LETTER_MAX_AGE_SECONDS) {
376574
+ return { status: "error", details, error: `oldest pending dead letter is ${oldestPendingAgeSeconds}s old` };
376575
+ }
376576
+ return { status: "ok", details };
376577
+ } catch (error3) {
376578
+ healthLog.warn("Dead letter health query failed", { error: String(error3) });
376579
+ return { status: "ok", details: { available: false } };
376580
+ }
376581
+ }
376549
376582
  function freshnessFor(oldestUpdateMs) {
376550
376583
  if (oldestUpdateMs === null)
376551
376584
  return "current";
@@ -376580,7 +376613,8 @@ var import__package2, healthLog, VERSION5, startTime2, healthRoutes, getHealth =
376580
376613
  }
376581
376614
  const pluginsFailed = arePluginsDegraded();
376582
376615
  const pluginsCheck = pluginsFailed ? { status: "error", error: getPluginsDegradedReason() ?? "Plugin initialization failed" } : { status: "ok" };
376583
- const hasErrors = dbCheck.status === "error" || natsCheck.status === "error" || pluginsFailed;
376616
+ const deadLettersCheck = await checkDeadLetters(c.get("services"));
376617
+ const hasErrors = dbCheck.status === "error" || natsCheck.status === "error" || pluginsFailed || deadLettersCheck.status === "error";
376584
376618
  const status = hasErrors ? "degraded" : "healthy";
376585
376619
  const response = {
376586
376620
  status,
@@ -376590,11 +376624,12 @@ var import__package2, healthLog, VERSION5, startTime2, healthRoutes, getHealth =
376590
376624
  checks: {
376591
376625
  database: dbCheck,
376592
376626
  nats: natsCheck,
376593
- plugins: pluginsCheck
376627
+ plugins: pluginsCheck,
376628
+ deadLetters: deadLettersCheck
376594
376629
  }
376595
376630
  };
376596
376631
  return c.json(response, status === "healthy" ? 200 : 503);
376597
- }, LAGGING_AFTER_MS = 60000, STALE_AFTER_MS;
376632
+ }, DEAD_LETTER_PENDING_THRESHOLD = 50, DEAD_LETTER_MAX_AGE_SECONDS, LAGGING_AFTER_MS = 60000, STALE_AFTER_MS;
376598
376633
  var init_health2 = __esm(() => {
376599
376634
  init_src();
376600
376635
  init_src5();
@@ -376606,6 +376641,7 @@ var init_health2 = __esm(() => {
376606
376641
  VERSION5 = import__package2.default.version;
376607
376642
  startTime2 = Date.now();
376608
376643
  healthRoutes = new Hono2;
376644
+ DEAD_LETTER_MAX_AGE_SECONDS = 24 * 60 * 60;
376609
376645
  healthRoutes.get("/health", getHealth);
376610
376646
  healthRoutes.get("/info", async (c) => {
376611
376647
  return c.json({
@@ -398266,6 +398302,11 @@ async function setupEventPersistence(eventBus, db2) {
398266
398302
  durable: "event-persistence-connector",
398267
398303
  startFrom: "new"
398268
398304
  });
398305
+ await eventBus.subscribePattern("system.dead_letter", (event) => journalInternalEvent(db2, event), {
398306
+ ...CONSUMER_OPTIONS,
398307
+ durable: "event-persistence-dead-letter",
398308
+ startFrom: "new"
398309
+ });
398269
398310
  log128.info("Event persistence initialized - listening for message events");
398270
398311
  } catch (error3) {
398271
398312
  log128.error("Failed to set up event persistence", { error: String(error3) });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@automagik/omni",
3
- "version": "2.260915.3",
3
+ "version": "2.260915.5",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/automagik-dev/omni.git",