@secondlayer/subgraphs 1.0.0-beta.1 → 1.0.0-beta.2

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.
@@ -1503,7 +1503,7 @@ import {
1503
1503
  listSubgraphs as listSubgraphs2,
1504
1504
  updateSubgraphStatus as updateSubgraphStatus2
1505
1505
  } from "@secondlayer/shared/db/queries/subgraphs";
1506
- import { logger as logger8 } from "@secondlayer/shared/logger";
1506
+ import { logger as logger9 } from "@secondlayer/shared/logger";
1507
1507
  import { listen as listen2 } from "@secondlayer/shared/queue/listener";
1508
1508
 
1509
1509
  // src/runtime/emitter.ts
@@ -1513,10 +1513,98 @@ import {
1513
1513
  import {
1514
1514
  getSubscriptionSigningSecret
1515
1515
  } from "@secondlayer/shared/db/queries/subscriptions";
1516
- import { logger as logger7 } from "@secondlayer/shared/logger";
1516
+ import { logger as logger8 } from "@secondlayer/shared/logger";
1517
1517
  import { listen } from "@secondlayer/shared/queue/listener";
1518
1518
  import { sql as sql4 } from "kysely";
1519
1519
 
1520
+ // src/runtime/formats/index.ts
1521
+ import { logger as logger7 } from "@secondlayer/shared/logger";
1522
+
1523
+ // src/runtime/formats/cloudevents.ts
1524
+ function buildCloudEvents(outboxRow, _sub) {
1525
+ const event = {
1526
+ specversion: "1.0",
1527
+ type: outboxRow.event_type,
1528
+ source: `secondlayer:${outboxRow.subgraph_name}`,
1529
+ id: outboxRow.id,
1530
+ time: new Date(outboxRow.created_at).toISOString(),
1531
+ datacontenttype: "application/json",
1532
+ data: outboxRow.payload
1533
+ };
1534
+ return {
1535
+ body: JSON.stringify(event),
1536
+ headers: {
1537
+ "content-type": "application/cloudevents+json; charset=utf-8"
1538
+ }
1539
+ };
1540
+ }
1541
+
1542
+ // src/runtime/formats/cloudflare.ts
1543
+ import { decryptSecret } from "@secondlayer/shared/crypto/secrets";
1544
+ function resolveBearer(sub) {
1545
+ const cfg = sub.auth_config;
1546
+ if (cfg.tokenEnc) {
1547
+ try {
1548
+ return decryptSecret(Buffer.from(cfg.tokenEnc, "base64"));
1549
+ } catch {
1550
+ return null;
1551
+ }
1552
+ }
1553
+ return cfg.token ?? null;
1554
+ }
1555
+ function buildCloudflare(outboxRow, sub) {
1556
+ const body = JSON.stringify({
1557
+ params: {
1558
+ ...outboxRow.payload,
1559
+ _type: outboxRow.event_type,
1560
+ _outboxId: outboxRow.id
1561
+ }
1562
+ });
1563
+ const headers = {
1564
+ "content-type": "application/json"
1565
+ };
1566
+ const token = resolveBearer(sub);
1567
+ if (token)
1568
+ headers.authorization = `Bearer ${token}`;
1569
+ return { body, headers };
1570
+ }
1571
+
1572
+ // src/runtime/formats/inngest.ts
1573
+ var INNGEST_VERSION = "2026-04-23.v1";
1574
+ function buildInngest(outboxRow) {
1575
+ const event = {
1576
+ name: outboxRow.event_type,
1577
+ data: outboxRow.payload,
1578
+ id: outboxRow.id,
1579
+ ts: new Date(outboxRow.created_at).getTime(),
1580
+ v: INNGEST_VERSION
1581
+ };
1582
+ return {
1583
+ body: JSON.stringify([event]),
1584
+ headers: {
1585
+ "content-type": "application/json"
1586
+ }
1587
+ };
1588
+ }
1589
+
1590
+ // src/runtime/formats/raw.ts
1591
+ function buildRaw(outboxRow, sub) {
1592
+ const cfg = sub.auth_config;
1593
+ const headers = {
1594
+ "content-type": cfg.contentType ?? "application/json",
1595
+ ...cfg.headers ?? {}
1596
+ };
1597
+ if (cfg.authType === "bearer" && cfg.token) {
1598
+ headers.authorization = `Bearer ${cfg.token}`;
1599
+ } else if (cfg.authType === "basic" && cfg.basicAuth) {
1600
+ headers.authorization = `Basic ${cfg.basicAuth}`;
1601
+ }
1602
+ return {
1603
+ body: JSON.stringify(outboxRow.payload),
1604
+ headers
1605
+ };
1606
+ }
1607
+
1520
1608
  // src/runtime/formats/standard-webhooks.ts
1521
1609
  import { sign } from "@secondlayer/shared/crypto/standard-webhooks";
1522
1610
  function buildStandardWebhooks(outboxRow, signingSecret) {
@@ -1539,6 +1627,59 @@ function buildStandardWebhooks(outboxRow, signingSecret) {
1539
1627
  };
1540
1628
  }
1541
1629
 
1630
+ // src/runtime/formats/trigger.ts
1631
+ import { decryptSecret as decryptSecret2 } from "@secondlayer/shared/crypto/secrets";
1632
+ function resolveBearer2(sub) {
1633
+ const cfg = sub.auth_config;
1634
+ if (cfg.tokenEnc) {
1635
+ try {
1636
+ return decryptSecret2(Buffer.from(cfg.tokenEnc, "base64"));
1637
+ } catch {
1638
+ return null;
1639
+ }
1640
+ }
1641
+ return cfg.token ?? null;
1642
+ }
1643
+ function buildTrigger(outboxRow, sub) {
1644
+ const body = JSON.stringify({
1645
+ payload: outboxRow.payload,
1646
+ options: {
1647
+ idempotencyKey: outboxRow.id
1648
+ }
1649
+ });
1650
+ const headers = {
1651
+ "content-type": "application/json"
1652
+ };
1653
+ const token = resolveBearer2(sub);
1654
+ if (token)
1655
+ headers.authorization = `Bearer ${token}`;
1656
+ return { body, headers };
1657
+ }
1658
+
1659
+ // src/runtime/formats/index.ts
1660
+ function buildForFormat(outboxRow, sub, signingSecret) {
1661
+ switch (sub.format) {
1662
+ case "inngest":
1663
+ return buildInngest(outboxRow);
1664
+ case "trigger":
1665
+ return buildTrigger(outboxRow, sub);
1666
+ case "cloudflare":
1667
+ return buildCloudflare(outboxRow, sub);
1668
+ case "cloudevents":
1669
+ return buildCloudEvents(outboxRow, sub);
1670
+ case "raw":
1671
+ return buildRaw(outboxRow, sub);
1672
+ case "standard-webhooks":
1673
+ return buildStandardWebhooks(outboxRow, signingSecret);
1674
+ default:
1675
+ logger7.warn("Unknown subscription format, falling back to standard-webhooks", {
1676
+ format: sub.format,
1677
+ subscriptionId: sub.id
1678
+ });
1679
+ return buildStandardWebhooks(outboxRow, signingSecret);
1680
+ }
1681
+ }
1682
+
1542
1683
  // src/runtime/emitter.ts
1543
1684
  var BATCH_SIZE = 50;
1544
1685
  var BACKOFF_SECONDS = [30, 120, 600, 3600, 21600, 86400, 259200];
@@ -1547,7 +1688,7 @@ function nextDelaySeconds(attempt) {
1547
1688
  return BACKOFF_SECONDS[Math.min(attempt, BACKOFF_SECONDS.length - 1)];
1548
1689
  }
1549
1690
  async function dispatchOne(db, outboxRow, sub) {
1550
- const { body, headers } = buildStandardWebhooks(outboxRow, getSubscriptionSigningSecret(sub));
1691
+ const { body, headers } = buildForFormat(outboxRow, sub, getSubscriptionSigningSecret(sub));
1551
1692
  const start = performance.now();
1552
1693
  let statusCode = null;
1553
1694
  let error = null;
@@ -1625,7 +1766,7 @@ async function settleFailed(db, outboxRow, sub, errText) {
1625
1766
  updated_at: new Date
1626
1767
  }).where("id", "=", outboxRow.subscription_id).execute();
1627
1768
  if (shouldTripCircuit) {
1628
- logger7.warn("Subscription circuit tripped — paused after consecutive failures", {
1769
+ logger8.warn("Subscription circuit tripped — paused after consecutive failures", {
1629
1770
  subscription: sub.name,
1630
1771
  failures: newFailures
1631
1772
  });
@@ -1695,7 +1836,7 @@ async function drainForSub(db, state, sub, rows) {
1695
1836
  await settleFailed(db, row, sub, err);
1696
1837
  }
1697
1838
  } catch (err) {
1698
- logger7.error("Emitter dispatch crashed", {
1839
+ logger8.error("Emitter dispatch crashed", {
1699
1840
  outboxId: row.id,
1700
1841
  error: err instanceof Error ? err.message : String(err)
1701
1842
  });
@@ -1732,30 +1873,30 @@ async function startEmitter(opts) {
1732
1873
  };
1733
1874
  const pollIntervalMs = opts?.pollIntervalMs ?? 120000;
1734
1875
  const retentionIntervalMs = opts?.retentionIntervalMs ?? 60 * 60000;
1735
- logger7.info("[emitter] started", { id: emitterId });
1876
+ logger8.info("[emitter] started", { id: emitterId });
1736
1877
  await refreshMatcher(db).catch((err) => {
1737
- logger7.error("[emitter] initial matcher refresh failed", {
1878
+ logger8.error("[emitter] initial matcher refresh failed", {
1738
1879
  error: err instanceof Error ? err.message : String(err)
1739
1880
  });
1740
1881
  });
1741
1882
  const stopNew = await listen("subscriptions:new_outbox", () => {
1742
1883
  if (!state.running)
1743
1884
  return;
1744
- claimAndDrain(db, state, emitterId).catch((err) => logger7.error("[emitter] claim failed", {
1885
+ claimAndDrain(db, state, emitterId).catch((err) => logger8.error("[emitter] claim failed", {
1745
1886
  error: err instanceof Error ? err.message : String(err)
1746
1887
  }));
1747
1888
  });
1748
1889
  const stopChanged = await listen("subscriptions:changed", () => {
1749
1890
  if (!state.running)
1750
1891
  return;
1751
- refreshMatcher(db).catch((err) => logger7.error("[emitter] matcher refresh failed", {
1892
+ refreshMatcher(db).catch((err) => logger8.error("[emitter] matcher refresh failed", {
1752
1893
  error: err instanceof Error ? err.message : String(err)
1753
1894
  }));
1754
1895
  });
1755
1896
  const poll = setInterval(() => {
1756
1897
  if (!state.running)
1757
1898
  return;
1758
- claimAndDrain(db, state, emitterId).catch((err) => logger7.error("[emitter] poll claim failed", {
1899
+ claimAndDrain(db, state, emitterId).catch((err) => logger8.error("[emitter] poll claim failed", {
1759
1900
  error: err instanceof Error ? err.message : String(err)
1760
1901
  }));
1761
1902
  }, pollIntervalMs);
@@ -1763,7 +1904,7 @@ async function startEmitter(opts) {
1763
1904
  const retention = setInterval(() => {
1764
1905
  if (!state.running)
1765
1906
  return;
1766
- runRetention(db).catch((err) => logger7.error("[emitter] retention failed", {
1907
+ runRetention(db).catch((err) => logger8.error("[emitter] retention failed", {
1767
1908
  error: err instanceof Error ? err.message : String(err)
1768
1909
  }));
1769
1910
  }, retentionIntervalMs);
@@ -1773,7 +1914,7 @@ async function startEmitter(opts) {
1773
1914
  clearInterval(retention);
1774
1915
  await stopNew();
1775
1916
  await stopChanged();
1776
- logger7.info("[emitter] stopped", { id: emitterId });
1917
+ logger8.info("[emitter] stopped", { id: emitterId });
1777
1918
  };
1778
1919
  }
1779
1920
 
@@ -1811,7 +1952,7 @@ async function loadSubgraphDefinition(sg) {
1811
1952
  knownVersions.set(sg.name, sg.version);
1812
1953
  definitionCache.set(sg.name, def);
1813
1954
  if (prevVersion && prevVersion !== sg.version) {
1814
- logger8.info("Subgraph handler reloaded", {
1955
+ logger9.info("Subgraph handler reloaded", {
1815
1956
  subgraph: sg.name,
1816
1957
  from: prevVersion,
1817
1958
  to: sg.version
@@ -1831,7 +1972,7 @@ function cleanupCaches(active) {
1831
1972
  async function startSubgraphProcessor(opts) {
1832
1973
  const concurrency = opts?.concurrency ?? DEFAULT_CONCURRENCY;
1833
1974
  let running = true;
1834
- logger8.info("Starting subgraph processor", { concurrency });
1975
+ logger9.info("Starting subgraph processor", { concurrency });
1835
1976
  const targetDb = getTargetDb5();
1836
1977
  const activeSubgraphs = (await listSubgraphs2(targetDb)).filter((v) => v.status === "active");
1837
1978
  for (const sg of activeSubgraphs) {
@@ -1843,7 +1984,7 @@ async function startSubgraphProcessor(opts) {
1843
1984
  if (isHandlerNotFoundError(err)) {
1844
1985
  await updateSubgraphStatus2(targetDb, sg.name, "error");
1845
1986
  }
1846
- logger8.error("Subgraph catch-up failed on startup", {
1987
+ logger9.error("Subgraph catch-up failed on startup", {
1847
1988
  subgraph: sg.name,
1848
1989
  error: msg
1849
1990
  });
@@ -1864,7 +2005,7 @@ async function startSubgraphProcessor(opts) {
1864
2005
  if (isHandlerNotFoundError(err)) {
1865
2006
  await updateSubgraphStatus2(db, sg.name, "error");
1866
2007
  }
1867
- logger8.error("Subgraph processing failed", {
2008
+ logger9.error("Subgraph processing failed", {
1868
2009
  subgraph: sg.name,
1869
2010
  error: msg
1870
2011
  });
@@ -1881,7 +2022,7 @@ async function startSubgraphProcessor(opts) {
1881
2022
  await handleSubgraphReorg(blockHeight, loadSubgraphDefinition);
1882
2023
  }
1883
2024
  } catch (err) {
1884
- logger8.error("Subgraph reorg handling failed", {
2025
+ logger9.error("Subgraph reorg handling failed", {
1885
2026
  error: getErrorMessage3(err)
1886
2027
  });
1887
2028
  }
@@ -1897,7 +2038,7 @@ async function startSubgraphProcessor(opts) {
1897
2038
  const def = await loadSubgraphDefinition(sg);
1898
2039
  await catchUpSubgraph(def, sg.name);
1899
2040
  } catch (err) {
1900
- logger8.error("Subgraph poll processing failed", {
2041
+ logger9.error("Subgraph poll processing failed", {
1901
2042
  subgraph: sg.name,
1902
2043
  error: getErrorMessage3(err)
1903
2044
  });
@@ -1905,29 +2046,29 @@ async function startSubgraphProcessor(opts) {
1905
2046
  }
1906
2047
  }, POLL_INTERVAL_MS);
1907
2048
  const stopEmitter = await startEmitter();
1908
- logger8.info("Subgraph processor ready");
2049
+ logger9.info("Subgraph processor ready");
1909
2050
  return async () => {
1910
2051
  running = false;
1911
2052
  clearInterval(pollInterval);
1912
2053
  await stopListening();
1913
2054
  await stopReorgListening();
1914
2055
  await stopEmitter();
1915
- logger8.info("Subgraph processor stopped");
2056
+ logger9.info("Subgraph processor stopped");
1916
2057
  };
1917
2058
  }
1918
2059
 
1919
2060
  // src/service.ts
1920
- import { logger as logger9 } from "@secondlayer/shared/logger";
2061
+ import { logger as logger10 } from "@secondlayer/shared/logger";
1921
2062
  var processor = await startSubgraphProcessor({
1922
2063
  concurrency: Number.parseInt(process.env.SUBGRAPH_CONCURRENCY ?? "5")
1923
2064
  });
1924
2065
  var shutdown = async () => {
1925
- logger9.info("Shutting down subgraph processor...");
2066
+ logger10.info("Shutting down subgraph processor...");
1926
2067
  await processor();
1927
2068
  process.exit(0);
1928
2069
  };
1929
2070
  process.on("SIGINT", shutdown);
1930
2071
  process.on("SIGTERM", shutdown);
1931
2072
 
1932
- //# debugId=831A226FB3756A4564756E2164756E21
2073
+ //# debugId=7A75D8CAD29A70B464756E2164756E21
1933
2074
  //# sourceMappingURL=service.js.map