@eclesia/indexer-engine 2.14.4 → 2.16.0

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 (121) hide show
  1. package/dist/_virtual/rolldown_runtime.cjs +20 -15
  2. package/dist/_virtual/rolldown_runtime.mjs +10 -30
  3. package/dist/constants.cjs +31 -2
  4. package/dist/constants.cjs.map +1 -1
  5. package/dist/constants.d.cts +27 -3
  6. package/dist/constants.d.cts.map +1 -1
  7. package/dist/constants.d.mts +27 -3
  8. package/dist/constants.d.mts.map +1 -1
  9. package/dist/constants.mjs +27 -3
  10. package/dist/constants.mjs.map +1 -1
  11. package/dist/emitter/index.cjs +25 -7
  12. package/dist/emitter/index.cjs.map +1 -1
  13. package/dist/emitter/index.d.cts +8 -1
  14. package/dist/emitter/index.d.cts.map +1 -1
  15. package/dist/emitter/index.d.mts +8 -1
  16. package/dist/emitter/index.d.mts.map +1 -1
  17. package/dist/emitter/index.mjs +25 -7
  18. package/dist/emitter/index.mjs.map +1 -1
  19. package/dist/index.cjs +6 -0
  20. package/dist/index.d.cts +3 -3
  21. package/dist/index.d.mts +3 -3
  22. package/dist/index.mjs +3 -3
  23. package/dist/indexer/index.cjs +498 -225
  24. package/dist/indexer/index.cjs.map +1 -1
  25. package/dist/indexer/index.d.cts +111 -7
  26. package/dist/indexer/index.d.cts.map +1 -1
  27. package/dist/indexer/index.d.mts +111 -7
  28. package/dist/indexer/index.d.mts.map +1 -1
  29. package/dist/indexer/index.mjs +496 -224
  30. package/dist/indexer/index.mjs.map +1 -1
  31. package/dist/metrics/index.cjs +14 -0
  32. package/dist/metrics/index.cjs.map +1 -1
  33. package/dist/metrics/index.d.cts +7 -0
  34. package/dist/metrics/index.d.cts.map +1 -1
  35. package/dist/metrics/index.d.mts +7 -0
  36. package/dist/metrics/index.d.mts.map +1 -1
  37. package/dist/metrics/index.mjs +14 -0
  38. package/dist/metrics/index.mjs.map +1 -1
  39. package/dist/mocks/index.cjs +3 -1
  40. package/dist/mocks/index.cjs.map +1 -1
  41. package/dist/mocks/index.d.cts +2 -2
  42. package/dist/mocks/index.d.mts +2 -2
  43. package/dist/mocks/index.mjs +4 -2
  44. package/dist/mocks/index.mjs.map +1 -1
  45. package/dist/mocks/rpc-client.cjs +185 -20
  46. package/dist/mocks/rpc-client.cjs.map +1 -1
  47. package/dist/mocks/rpc-client.d.cts +26 -10
  48. package/dist/mocks/rpc-client.d.cts.map +1 -1
  49. package/dist/mocks/rpc-client.d.mts +26 -10
  50. package/dist/mocks/rpc-client.d.mts.map +1 -1
  51. package/dist/mocks/rpc-client.mjs +184 -22
  52. package/dist/mocks/rpc-client.mjs.map +1 -1
  53. package/dist/promise-queue/index.cjs +10 -4
  54. package/dist/promise-queue/index.cjs.map +1 -1
  55. package/dist/promise-queue/index.d.cts +1 -4
  56. package/dist/promise-queue/index.d.cts.map +1 -1
  57. package/dist/promise-queue/index.d.mts +1 -4
  58. package/dist/promise-queue/index.d.mts.map +1 -1
  59. package/dist/promise-queue/index.mjs +10 -4
  60. package/dist/promise-queue/index.mjs.map +1 -1
  61. package/dist/types/index.cjs.map +1 -1
  62. package/dist/types/index.d.cts +28 -5
  63. package/dist/types/index.d.cts.map +1 -1
  64. package/dist/types/index.d.mts +28 -5
  65. package/dist/types/index.d.mts.map +1 -1
  66. package/dist/types/index.mjs.map +1 -1
  67. package/dist/utils/index.cjs +6 -1
  68. package/dist/utils/index.cjs.map +1 -1
  69. package/dist/utils/index.d.cts +3 -2
  70. package/dist/utils/index.d.mts +3 -2
  71. package/dist/utils/index.mjs +7 -2
  72. package/dist/utils/index.mjs.map +1 -1
  73. package/dist/utils/text.cjs +31 -0
  74. package/dist/utils/text.cjs.map +1 -1
  75. package/dist/utils/text.d.cts +24 -1
  76. package/dist/utils/text.d.cts.map +1 -1
  77. package/dist/utils/text.d.mts +24 -1
  78. package/dist/utils/text.d.mts.map +1 -1
  79. package/dist/utils/text.mjs +30 -1
  80. package/dist/utils/text.mjs.map +1 -1
  81. package/dist/utils/timeout.cjs +32 -0
  82. package/dist/utils/timeout.cjs.map +1 -0
  83. package/dist/utils/timeout.d.cts +18 -0
  84. package/dist/utils/timeout.d.cts.map +1 -0
  85. package/dist/utils/timeout.d.mts +18 -0
  86. package/dist/utils/timeout.d.mts.map +1 -0
  87. package/dist/utils/timeout.mjs +30 -0
  88. package/dist/utils/timeout.mjs.map +1 -0
  89. package/package.json +35 -34
  90. package/dist/node_modules/.pnpm/@cosmjs_encoding@0.36.0/node_modules/@cosmjs/encoding/build/ascii.cjs +0 -32
  91. package/dist/node_modules/.pnpm/@cosmjs_encoding@0.36.0/node_modules/@cosmjs/encoding/build/ascii.cjs.map +0 -1
  92. package/dist/node_modules/.pnpm/@cosmjs_encoding@0.36.0/node_modules/@cosmjs/encoding/build/ascii.mjs +0 -29
  93. package/dist/node_modules/.pnpm/@cosmjs_encoding@0.36.0/node_modules/@cosmjs/encoding/build/ascii.mjs.map +0 -1
  94. package/dist/node_modules/.pnpm/@cosmjs_encoding@0.36.0/node_modules/@cosmjs/encoding/build/base64.cjs +0 -67
  95. package/dist/node_modules/.pnpm/@cosmjs_encoding@0.36.0/node_modules/@cosmjs/encoding/build/base64.cjs.map +0 -1
  96. package/dist/node_modules/.pnpm/@cosmjs_encoding@0.36.0/node_modules/@cosmjs/encoding/build/base64.mjs +0 -64
  97. package/dist/node_modules/.pnpm/@cosmjs_encoding@0.36.0/node_modules/@cosmjs/encoding/build/base64.mjs.map +0 -1
  98. package/dist/node_modules/.pnpm/@cosmjs_encoding@0.36.0/node_modules/@cosmjs/encoding/build/bech32.cjs +0 -80
  99. package/dist/node_modules/.pnpm/@cosmjs_encoding@0.36.0/node_modules/@cosmjs/encoding/build/bech32.cjs.map +0 -1
  100. package/dist/node_modules/.pnpm/@cosmjs_encoding@0.36.0/node_modules/@cosmjs/encoding/build/bech32.mjs +0 -77
  101. package/dist/node_modules/.pnpm/@cosmjs_encoding@0.36.0/node_modules/@cosmjs/encoding/build/bech32.mjs.map +0 -1
  102. package/dist/node_modules/.pnpm/@cosmjs_encoding@0.36.0/node_modules/@cosmjs/encoding/build/hex.cjs +0 -33
  103. package/dist/node_modules/.pnpm/@cosmjs_encoding@0.36.0/node_modules/@cosmjs/encoding/build/hex.cjs.map +0 -1
  104. package/dist/node_modules/.pnpm/@cosmjs_encoding@0.36.0/node_modules/@cosmjs/encoding/build/hex.mjs +0 -30
  105. package/dist/node_modules/.pnpm/@cosmjs_encoding@0.36.0/node_modules/@cosmjs/encoding/build/hex.mjs.map +0 -1
  106. package/dist/node_modules/.pnpm/@cosmjs_encoding@0.36.0/node_modules/@cosmjs/encoding/build/index.cjs +0 -106
  107. package/dist/node_modules/.pnpm/@cosmjs_encoding@0.36.0/node_modules/@cosmjs/encoding/build/index.cjs.map +0 -1
  108. package/dist/node_modules/.pnpm/@cosmjs_encoding@0.36.0/node_modules/@cosmjs/encoding/build/index.mjs +0 -103
  109. package/dist/node_modules/.pnpm/@cosmjs_encoding@0.36.0/node_modules/@cosmjs/encoding/build/index.mjs.map +0 -1
  110. package/dist/node_modules/.pnpm/@cosmjs_encoding@0.36.0/node_modules/@cosmjs/encoding/build/rfc3339.cjs +0 -52
  111. package/dist/node_modules/.pnpm/@cosmjs_encoding@0.36.0/node_modules/@cosmjs/encoding/build/rfc3339.cjs.map +0 -1
  112. package/dist/node_modules/.pnpm/@cosmjs_encoding@0.36.0/node_modules/@cosmjs/encoding/build/rfc3339.mjs +0 -49
  113. package/dist/node_modules/.pnpm/@cosmjs_encoding@0.36.0/node_modules/@cosmjs/encoding/build/rfc3339.mjs.map +0 -1
  114. package/dist/node_modules/.pnpm/@cosmjs_encoding@0.36.0/node_modules/@cosmjs/encoding/build/utf8.cjs +0 -31
  115. package/dist/node_modules/.pnpm/@cosmjs_encoding@0.36.0/node_modules/@cosmjs/encoding/build/utf8.cjs.map +0 -1
  116. package/dist/node_modules/.pnpm/@cosmjs_encoding@0.36.0/node_modules/@cosmjs/encoding/build/utf8.mjs +0 -28
  117. package/dist/node_modules/.pnpm/@cosmjs_encoding@0.36.0/node_modules/@cosmjs/encoding/build/utf8.mjs.map +0 -1
  118. package/dist/node_modules/.pnpm/base64-js@1.5.1/node_modules/base64-js/index.cjs +0 -98
  119. package/dist/node_modules/.pnpm/base64-js@1.5.1/node_modules/base64-js/index.cjs.map +0 -1
  120. package/dist/node_modules/.pnpm/base64-js@1.5.1/node_modules/base64-js/index.mjs +0 -95
  121. package/dist/node_modules/.pnpm/base64-js@1.5.1/node_modules/base64-js/index.mjs.map +0 -1
@@ -5,24 +5,30 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
6
  var __getProtoOf = Object.getPrototypeOf;
7
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __commonJS = (cb, mod) => function() {
9
- return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
10
- };
11
- var __export = (all) => {
8
+ var __export = (all, symbols) => {
12
9
  let target = {};
13
- for (var name in all) __defProp(target, name, {
14
- get: all[name],
15
- enumerable: true
16
- });
10
+ for (var name in all) {
11
+ __defProp(target, name, {
12
+ get: all[name],
13
+ enumerable: true
14
+ });
15
+ }
16
+ if (symbols) {
17
+ __defProp(target, Symbol.toStringTag, { value: "Module" });
18
+ }
17
19
  return target;
18
20
  };
19
21
  var __copyProps = (to, from, except, desc) => {
20
- if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
21
- key = keys[i];
22
- if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
23
- get: ((k) => from[k]).bind(null, key),
24
- enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
25
- });
22
+ if (from && typeof from === "object" || typeof from === "function") {
23
+ for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
24
+ key = keys[i];
25
+ if (!__hasOwnProp.call(to, key) && key !== except) {
26
+ __defProp(to, key, {
27
+ get: ((k) => from[k]).bind(null, key),
28
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
29
+ });
30
+ }
31
+ }
26
32
  }
27
33
  return to;
28
34
  };
@@ -33,6 +39,5 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
33
39
 
34
40
  //#endregion
35
41
 
36
- exports.__commonJS = __commonJS;
37
42
  exports.__export = __export;
38
43
  exports.__toESM = __toESM;
@@ -1,38 +1,18 @@
1
- import { createRequire } from "node:module";
2
-
3
1
  //#region rolldown:runtime
4
- var __create = Object.create;
5
2
  var __defProp = Object.defineProperty;
6
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
7
- var __getOwnPropNames = Object.getOwnPropertyNames;
8
- var __getProtoOf = Object.getPrototypeOf;
9
- var __hasOwnProp = Object.prototype.hasOwnProperty;
10
- var __commonJS = (cb, mod) => function() {
11
- return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
12
- };
13
- var __export = (all) => {
3
+ var __export = (all, symbols) => {
14
4
  let target = {};
15
- for (var name in all) __defProp(target, name, {
16
- get: all[name],
17
- enumerable: true
18
- });
19
- return target;
20
- };
21
- var __copyProps = (to, from, except, desc) => {
22
- if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
23
- key = keys[i];
24
- if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
25
- get: ((k) => from[k]).bind(null, key),
26
- enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
5
+ for (var name in all) {
6
+ __defProp(target, name, {
7
+ get: all[name],
8
+ enumerable: true
27
9
  });
28
10
  }
29
- return to;
11
+ if (symbols) {
12
+ __defProp(target, Symbol.toStringTag, { value: "Module" });
13
+ }
14
+ return target;
30
15
  };
31
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
32
- value: mod,
33
- enumerable: true
34
- }) : target, mod));
35
- var __require = /* @__PURE__ */ createRequire(import.meta.url);
36
16
 
37
17
  //#endregion
38
- export { __commonJS, __export, __require, __toESM };
18
+ export { __export };
@@ -37,11 +37,35 @@ const CONNECT_TIMEOUT_MS = 1e4;
37
37
  */
38
38
  const RPC_TIMEOUT_MS = 2e4;
39
39
  /**
40
- * Timeout for block queue dequeue operations in milliseconds
41
- * If no block is available within this time, an error will be thrown
40
+ * @deprecated Waiting for a block is no longer bounded by a timeout: an idle chain is not an
41
+ * error. Kept as an export for compatibility; see IDLE_CHECK_INTERVAL_MS.
42
42
  */
43
43
  const QUEUE_DEQUEUE_TIMEOUT_MS = 3e4;
44
44
  /**
45
+ * How long the indexer waits without any block announcement before checking the chain height.
46
+ * If the chain has moved on without us the subscription is dead and a recovery is triggered;
47
+ * if the chain is simply idle (halt, upgrade) the indexer reports WAITING and checks again.
48
+ */
49
+ const IDLE_CHECK_INTERVAL_MS = 3e4;
50
+ /**
51
+ * Delay before the first restart after a failure; doubles on every consecutive failure
52
+ */
53
+ const RETRY_BASE_DELAY_MS = 5e3;
54
+ /**
55
+ * Upper bound for the restart delay
56
+ */
57
+ const RETRY_MAX_DELAY_MS = 3e5;
58
+ /**
59
+ * Consecutive processing failures on the same block before the indexer gives up with a
60
+ * fatal-error. A block that keeps failing after its data was fetched is a bug or bad data, not
61
+ * an outage, and retrying it forever hides the problem.
62
+ */
63
+ const MAX_FAILURES_PER_BLOCK = 5;
64
+ /**
65
+ * Address the health check and metrics servers bind to unless configured otherwise
66
+ */
67
+ const DEFAULT_BIND_HOST = "0.0.0.0";
68
+ /**
45
69
  * Number of successful transactions before recycling the database client
46
70
  * Prevents long-running connection issues and stale connections
47
71
  */
@@ -72,13 +96,18 @@ const GENESIS_BATCH_SIZE = 1e3;
72
96
  exports.CONNECT_TIMEOUT_MS = CONNECT_TIMEOUT_MS;
73
97
  exports.DB_CLIENT_RECYCLE_COUNT = DB_CLIENT_RECYCLE_COUNT;
74
98
  exports.DEFAULT_BATCH_SIZE = DEFAULT_BATCH_SIZE;
99
+ exports.DEFAULT_BIND_HOST = DEFAULT_BIND_HOST;
75
100
  exports.DEFAULT_HEALTH_CHECK_PORT = DEFAULT_HEALTH_CHECK_PORT;
76
101
  exports.DEFAULT_POLLING_INTERVAL_MS = DEFAULT_POLLING_INTERVAL_MS;
77
102
  exports.DEFAULT_PROMETHEUS_PORT = DEFAULT_PROMETHEUS_PORT;
78
103
  exports.DEFAULT_START_HEIGHT = DEFAULT_START_HEIGHT;
79
104
  exports.GENESIS_BATCH_SIZE = GENESIS_BATCH_SIZE;
105
+ exports.IDLE_CHECK_INTERVAL_MS = IDLE_CHECK_INTERVAL_MS;
106
+ exports.MAX_FAILURES_PER_BLOCK = MAX_FAILURES_PER_BLOCK;
80
107
  exports.PAGINATION_LIMITS = PAGINATION_LIMITS;
81
108
  exports.PERIODIC_INTERVALS = PERIODIC_INTERVALS;
82
109
  exports.QUEUE_DEQUEUE_TIMEOUT_MS = QUEUE_DEQUEUE_TIMEOUT_MS;
110
+ exports.RETRY_BASE_DELAY_MS = RETRY_BASE_DELAY_MS;
111
+ exports.RETRY_MAX_DELAY_MS = RETRY_MAX_DELAY_MS;
83
112
  exports.RPC_TIMEOUT_MS = RPC_TIMEOUT_MS;
84
113
  //# sourceMappingURL=constants.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"constants.cjs","names":[],"sources":["../src/constants.ts"],"sourcesContent":["/**\n * Configuration constants for the Eclesia indexer\n * These values control performance, timeouts, and connection management\n */\n\n/**\n * Number of blocks to prefetch and keep in the processing queue\n * Higher values increase memory usage but improve throughput\n * Recommended range: 300-1000 depending on block size and available memory\n */\nexport const DEFAULT_BATCH_SIZE = 500;\n\n/**\n * Default start height for indexing when no previous height is found\n */\nexport const DEFAULT_START_HEIGHT = 1;\n\n/**\n * Default port for health check HTTP server\n */\nexport const DEFAULT_HEALTH_CHECK_PORT = 8888;\n\n/**\n * Default port for Prometheus metrics server\n */\nexport const DEFAULT_PROMETHEUS_PORT = 9090;\n\n/**\n * Default polling interval in milliseconds when using polling mode instead of WebSocket\n */\nexport const DEFAULT_POLLING_INTERVAL_MS = 5000;\n\n/**\n * Timeout for connecting to the Tendermint RPC in milliseconds\n * If connection is not established within this time, it will be aborted\n */\nexport const CONNECT_TIMEOUT_MS = 10000;\n\n/**\n * Timeout for RPC calls in milliseconds\n * If a call takes longer than this, it will be rejected\n */\nexport const RPC_TIMEOUT_MS = 20000;\n\n/**\n * Timeout for block queue dequeue operations in milliseconds\n * If no block is available within this time, an error will be thrown\n */\nexport const QUEUE_DEQUEUE_TIMEOUT_MS = 30000;\n\n/**\n * Number of successful transactions before recycling the database client\n * Prevents long-running connection issues and stale connections\n */\nexport const DB_CLIENT_RECYCLE_COUNT = 1500;\n\n/**\n * Block intervals for periodic event emission\n * Used for operations that should run at regular block intervals\n */\nexport const PERIODIC_INTERVALS = {\n /** Emit periodic event every 50 blocks */\n SMALL: 50,\n /** Emit periodic event every 100 blocks */\n MEDIUM: 100,\n /** Emit periodic event every 1000 blocks - used for performance logging */\n LARGE: 1000,\n} as const;\n\n/**\n * Pagination limits for blockchain queries\n */\nexport const PAGINATION_LIMITS = {\n /** Default limit for validator queries */\n VALIDATORS: 1000n,\n /** Default limit for delegation queries */\n DELEGATIONS: 250n,\n} as const;\n\n/**\n * Batch size for streaming genesis file processing\n * Number of entries to process at once from genesis JSON\n */\nexport const GENESIS_BATCH_SIZE = 1000;\n"],"mappings":";;;;;;;;;;;AAUA,MAAa,qBAAqB;;;;AAKlC,MAAa,uBAAuB;;;;AAKpC,MAAa,4BAA4B;;;;AAKzC,MAAa,0BAA0B;;;;AAKvC,MAAa,8BAA8B;;;;;AAM3C,MAAa,qBAAqB;;;;;AAMlC,MAAa,iBAAiB;;;;;AAM9B,MAAa,2BAA2B;;;;;AAMxC,MAAa,0BAA0B;;;;;AAMvC,MAAa,qBAAqB;CAEhC,OAAO;CAEP,QAAQ;CAER,OAAO;CACR;;;;AAKD,MAAa,oBAAoB;CAE/B,YAAY;CAEZ,aAAa;CACd;;;;;AAMD,MAAa,qBAAqB"}
1
+ {"version":3,"file":"constants.cjs","names":[],"sources":["../src/constants.ts"],"sourcesContent":["/**\n * Configuration constants for the Eclesia indexer\n * These values control performance, timeouts, and connection management\n */\n\n/**\n * Number of blocks to prefetch and keep in the processing queue\n * Higher values increase memory usage but improve throughput\n * Recommended range: 300-1000 depending on block size and available memory\n */\nexport const DEFAULT_BATCH_SIZE = 500;\n\n/**\n * Default start height for indexing when no previous height is found\n */\nexport const DEFAULT_START_HEIGHT = 1;\n\n/**\n * Default port for health check HTTP server\n */\nexport const DEFAULT_HEALTH_CHECK_PORT = 8888;\n\n/**\n * Default port for Prometheus metrics server\n */\nexport const DEFAULT_PROMETHEUS_PORT = 9090;\n\n/**\n * Default polling interval in milliseconds when using polling mode instead of WebSocket\n */\nexport const DEFAULT_POLLING_INTERVAL_MS = 5000;\n\n/**\n * Timeout for connecting to the Tendermint RPC in milliseconds\n * If connection is not established within this time, it will be aborted\n */\nexport const CONNECT_TIMEOUT_MS = 10000;\n\n/**\n * Timeout for RPC calls in milliseconds\n * If a call takes longer than this, it will be rejected\n */\nexport const RPC_TIMEOUT_MS = 20000;\n\n/**\n * @deprecated Waiting for a block is no longer bounded by a timeout: an idle chain is not an\n * error. Kept as an export for compatibility; see IDLE_CHECK_INTERVAL_MS.\n */\nexport const QUEUE_DEQUEUE_TIMEOUT_MS = 30000;\n\n/**\n * How long the indexer waits without any block announcement before checking the chain height.\n * If the chain has moved on without us the subscription is dead and a recovery is triggered;\n * if the chain is simply idle (halt, upgrade) the indexer reports WAITING and checks again.\n */\nexport const IDLE_CHECK_INTERVAL_MS = 30000;\n\n/**\n * Delay before the first restart after a failure; doubles on every consecutive failure\n */\nexport const RETRY_BASE_DELAY_MS = 5000;\n\n/**\n * Upper bound for the restart delay\n */\nexport const RETRY_MAX_DELAY_MS = 300000;\n\n/**\n * Consecutive processing failures on the same block before the indexer gives up with a\n * fatal-error. A block that keeps failing after its data was fetched is a bug or bad data, not\n * an outage, and retrying it forever hides the problem.\n */\nexport const MAX_FAILURES_PER_BLOCK = 5;\n\n/**\n * Address the health check and metrics servers bind to unless configured otherwise\n */\nexport const DEFAULT_BIND_HOST = \"0.0.0.0\";\n\n/**\n * Number of successful transactions before recycling the database client\n * Prevents long-running connection issues and stale connections\n */\nexport const DB_CLIENT_RECYCLE_COUNT = 1500;\n\n/**\n * Block intervals for periodic event emission\n * Used for operations that should run at regular block intervals\n */\nexport const PERIODIC_INTERVALS = {\n /** Emit periodic event every 50 blocks */\n SMALL: 50,\n /** Emit periodic event every 100 blocks */\n MEDIUM: 100,\n /** Emit periodic event every 1000 blocks - used for performance logging */\n LARGE: 1000,\n} as const;\n\n/**\n * Pagination limits for blockchain queries\n */\nexport const PAGINATION_LIMITS = {\n /** Default limit for validator queries */\n VALIDATORS: 1000n,\n /** Default limit for delegation queries */\n DELEGATIONS: 250n,\n} as const;\n\n/**\n * Batch size for streaming genesis file processing\n * Number of entries to process at once from genesis JSON\n */\nexport const GENESIS_BATCH_SIZE = 1000;\n"],"mappings":";;;;;;;;;;;AAUA,MAAa,qBAAqB;;;;AAKlC,MAAa,uBAAuB;;;;AAKpC,MAAa,4BAA4B;;;;AAKzC,MAAa,0BAA0B;;;;AAKvC,MAAa,8BAA8B;;;;;AAM3C,MAAa,qBAAqB;;;;;AAMlC,MAAa,iBAAiB;;;;;AAM9B,MAAa,2BAA2B;;;;;;AAOxC,MAAa,yBAAyB;;;;AAKtC,MAAa,sBAAsB;;;;AAKnC,MAAa,qBAAqB;;;;;;AAOlC,MAAa,yBAAyB;;;;AAKtC,MAAa,oBAAoB;;;;;AAMjC,MAAa,0BAA0B;;;;;AAMvC,MAAa,qBAAqB;CAEhC,OAAO;CAEP,QAAQ;CAER,OAAO;CACR;;;;AAKD,MAAa,oBAAoB;CAE/B,YAAY;CAEZ,aAAa;CACd;;;;;AAMD,MAAa,qBAAqB"}
@@ -36,10 +36,34 @@ declare const CONNECT_TIMEOUT_MS = 10000;
36
36
  */
37
37
  declare const RPC_TIMEOUT_MS = 20000;
38
38
  /**
39
- * Timeout for block queue dequeue operations in milliseconds
40
- * If no block is available within this time, an error will be thrown
39
+ * @deprecated Waiting for a block is no longer bounded by a timeout: an idle chain is not an
40
+ * error. Kept as an export for compatibility; see IDLE_CHECK_INTERVAL_MS.
41
41
  */
42
42
  declare const QUEUE_DEQUEUE_TIMEOUT_MS = 30000;
43
+ /**
44
+ * How long the indexer waits without any block announcement before checking the chain height.
45
+ * If the chain has moved on without us the subscription is dead and a recovery is triggered;
46
+ * if the chain is simply idle (halt, upgrade) the indexer reports WAITING and checks again.
47
+ */
48
+ declare const IDLE_CHECK_INTERVAL_MS = 30000;
49
+ /**
50
+ * Delay before the first restart after a failure; doubles on every consecutive failure
51
+ */
52
+ declare const RETRY_BASE_DELAY_MS = 5000;
53
+ /**
54
+ * Upper bound for the restart delay
55
+ */
56
+ declare const RETRY_MAX_DELAY_MS = 300000;
57
+ /**
58
+ * Consecutive processing failures on the same block before the indexer gives up with a
59
+ * fatal-error. A block that keeps failing after its data was fetched is a bug or bad data, not
60
+ * an outage, and retrying it forever hides the problem.
61
+ */
62
+ declare const MAX_FAILURES_PER_BLOCK = 5;
63
+ /**
64
+ * Address the health check and metrics servers bind to unless configured otherwise
65
+ */
66
+ declare const DEFAULT_BIND_HOST = "0.0.0.0";
43
67
  /**
44
68
  * Number of successful transactions before recycling the database client
45
69
  * Prevents long-running connection issues and stale connections
@@ -72,5 +96,5 @@ declare const PAGINATION_LIMITS: {
72
96
  */
73
97
  declare const GENESIS_BATCH_SIZE = 1000;
74
98
  //#endregion
75
- export { CONNECT_TIMEOUT_MS, DB_CLIENT_RECYCLE_COUNT, DEFAULT_BATCH_SIZE, DEFAULT_HEALTH_CHECK_PORT, DEFAULT_POLLING_INTERVAL_MS, DEFAULT_PROMETHEUS_PORT, DEFAULT_START_HEIGHT, GENESIS_BATCH_SIZE, PAGINATION_LIMITS, PERIODIC_INTERVALS, QUEUE_DEQUEUE_TIMEOUT_MS, RPC_TIMEOUT_MS };
99
+ export { CONNECT_TIMEOUT_MS, DB_CLIENT_RECYCLE_COUNT, DEFAULT_BATCH_SIZE, DEFAULT_BIND_HOST, DEFAULT_HEALTH_CHECK_PORT, DEFAULT_POLLING_INTERVAL_MS, DEFAULT_PROMETHEUS_PORT, DEFAULT_START_HEIGHT, GENESIS_BATCH_SIZE, IDLE_CHECK_INTERVAL_MS, MAX_FAILURES_PER_BLOCK, PAGINATION_LIMITS, PERIODIC_INTERVALS, QUEUE_DEQUEUE_TIMEOUT_MS, RETRY_BASE_DELAY_MS, RETRY_MAX_DELAY_MS, RPC_TIMEOUT_MS };
76
100
  //# sourceMappingURL=constants.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"constants.d.cts","names":[],"sources":["../src/constants.ts"],"sourcesContent":[],"mappings":";;AAUA;AAKA;AAKA;AAKA;AAKA;AAMA;AAMA;AAMA;AAMa,cA5CA,kBAAA,GA4CuB,GAAA;AAMpC;AAYA;AAWA;cApEa,oBAAA;;;;cAKA,yBAAA;;;;cAKA,uBAAA;;;;cAKA,2BAAA;;;;;cAMA,kBAAA;;;;;cAMA,cAAA;;;;;cAMA,wBAAA;;;;;cAMA,uBAAA;;;;;cAMA;;;;;;;;;;;cAYA;;;;;;;;;;cAWA,kBAAA"}
1
+ {"version":3,"file":"constants.d.cts","names":[],"sources":["../src/constants.ts"],"sourcesContent":[],"mappings":";;AAUA;AAKA;AAKA;AAKA;AAKA;AAMA;AAMA;AAMA;AAOa,cA7CA,kBAAA,GA6CsB,GAAA;AAKnC;AAKA;AAOA;AAKa,cA9DA,oBAAA,GA8DiB,CAAA;AAM9B;AAMA;AAYA;AAWa,cA5FA,yBAAA,GA4FkB,IAAA;;;;cAvFlB,uBAAA;;;;cAKA,2BAAA;;;;;cAMA,kBAAA;;;;;cAMA,cAAA;;;;;cAMA,wBAAA;;;;;;cAOA,sBAAA;;;;cAKA,mBAAA;;;;cAKA,kBAAA;;;;;;cAOA,sBAAA;;;;cAKA,iBAAA;;;;;cAMA,uBAAA;;;;;cAMA;;;;;;;;;;;cAYA;;;;;;;;;;cAWA,kBAAA"}
@@ -36,10 +36,34 @@ declare const CONNECT_TIMEOUT_MS = 10000;
36
36
  */
37
37
  declare const RPC_TIMEOUT_MS = 20000;
38
38
  /**
39
- * Timeout for block queue dequeue operations in milliseconds
40
- * If no block is available within this time, an error will be thrown
39
+ * @deprecated Waiting for a block is no longer bounded by a timeout: an idle chain is not an
40
+ * error. Kept as an export for compatibility; see IDLE_CHECK_INTERVAL_MS.
41
41
  */
42
42
  declare const QUEUE_DEQUEUE_TIMEOUT_MS = 30000;
43
+ /**
44
+ * How long the indexer waits without any block announcement before checking the chain height.
45
+ * If the chain has moved on without us the subscription is dead and a recovery is triggered;
46
+ * if the chain is simply idle (halt, upgrade) the indexer reports WAITING and checks again.
47
+ */
48
+ declare const IDLE_CHECK_INTERVAL_MS = 30000;
49
+ /**
50
+ * Delay before the first restart after a failure; doubles on every consecutive failure
51
+ */
52
+ declare const RETRY_BASE_DELAY_MS = 5000;
53
+ /**
54
+ * Upper bound for the restart delay
55
+ */
56
+ declare const RETRY_MAX_DELAY_MS = 300000;
57
+ /**
58
+ * Consecutive processing failures on the same block before the indexer gives up with a
59
+ * fatal-error. A block that keeps failing after its data was fetched is a bug or bad data, not
60
+ * an outage, and retrying it forever hides the problem.
61
+ */
62
+ declare const MAX_FAILURES_PER_BLOCK = 5;
63
+ /**
64
+ * Address the health check and metrics servers bind to unless configured otherwise
65
+ */
66
+ declare const DEFAULT_BIND_HOST = "0.0.0.0";
43
67
  /**
44
68
  * Number of successful transactions before recycling the database client
45
69
  * Prevents long-running connection issues and stale connections
@@ -72,5 +96,5 @@ declare const PAGINATION_LIMITS: {
72
96
  */
73
97
  declare const GENESIS_BATCH_SIZE = 1000;
74
98
  //#endregion
75
- export { CONNECT_TIMEOUT_MS, DB_CLIENT_RECYCLE_COUNT, DEFAULT_BATCH_SIZE, DEFAULT_HEALTH_CHECK_PORT, DEFAULT_POLLING_INTERVAL_MS, DEFAULT_PROMETHEUS_PORT, DEFAULT_START_HEIGHT, GENESIS_BATCH_SIZE, PAGINATION_LIMITS, PERIODIC_INTERVALS, QUEUE_DEQUEUE_TIMEOUT_MS, RPC_TIMEOUT_MS };
99
+ export { CONNECT_TIMEOUT_MS, DB_CLIENT_RECYCLE_COUNT, DEFAULT_BATCH_SIZE, DEFAULT_BIND_HOST, DEFAULT_HEALTH_CHECK_PORT, DEFAULT_POLLING_INTERVAL_MS, DEFAULT_PROMETHEUS_PORT, DEFAULT_START_HEIGHT, GENESIS_BATCH_SIZE, IDLE_CHECK_INTERVAL_MS, MAX_FAILURES_PER_BLOCK, PAGINATION_LIMITS, PERIODIC_INTERVALS, QUEUE_DEQUEUE_TIMEOUT_MS, RETRY_BASE_DELAY_MS, RETRY_MAX_DELAY_MS, RPC_TIMEOUT_MS };
76
100
  //# sourceMappingURL=constants.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"constants.d.mts","names":[],"sources":["../src/constants.ts"],"sourcesContent":[],"mappings":";;AAUA;AAKA;AAKA;AAKA;AAKA;AAMA;AAMA;AAMA;AAMa,cA5CA,kBAAA,GA4CuB,GAAA;AAMpC;AAYA;AAWA;cApEa,oBAAA;;;;cAKA,yBAAA;;;;cAKA,uBAAA;;;;cAKA,2BAAA;;;;;cAMA,kBAAA;;;;;cAMA,cAAA;;;;;cAMA,wBAAA;;;;;cAMA,uBAAA;;;;;cAMA;;;;;;;;;;;cAYA;;;;;;;;;;cAWA,kBAAA"}
1
+ {"version":3,"file":"constants.d.mts","names":[],"sources":["../src/constants.ts"],"sourcesContent":[],"mappings":";;AAUA;AAKA;AAKA;AAKA;AAKA;AAMA;AAMA;AAMA;AAOa,cA7CA,kBAAA,GA6CsB,GAAA;AAKnC;AAKA;AAOA;AAKa,cA9DA,oBAAA,GA8DiB,CAAA;AAM9B;AAMA;AAYA;AAWa,cA5FA,yBAAA,GA4FkB,IAAA;;;;cAvFlB,uBAAA;;;;cAKA,2BAAA;;;;;cAMA,kBAAA;;;;;cAMA,cAAA;;;;;cAMA,wBAAA;;;;;;cAOA,sBAAA;;;;cAKA,mBAAA;;;;cAKA,kBAAA;;;;;;cAOA,sBAAA;;;;cAKA,iBAAA;;;;;cAMA,uBAAA;;;;;cAMA;;;;;;;;;;;cAYA;;;;;;;;;;cAWA,kBAAA"}
@@ -36,11 +36,35 @@ const CONNECT_TIMEOUT_MS = 1e4;
36
36
  */
37
37
  const RPC_TIMEOUT_MS = 2e4;
38
38
  /**
39
- * Timeout for block queue dequeue operations in milliseconds
40
- * If no block is available within this time, an error will be thrown
39
+ * @deprecated Waiting for a block is no longer bounded by a timeout: an idle chain is not an
40
+ * error. Kept as an export for compatibility; see IDLE_CHECK_INTERVAL_MS.
41
41
  */
42
42
  const QUEUE_DEQUEUE_TIMEOUT_MS = 3e4;
43
43
  /**
44
+ * How long the indexer waits without any block announcement before checking the chain height.
45
+ * If the chain has moved on without us the subscription is dead and a recovery is triggered;
46
+ * if the chain is simply idle (halt, upgrade) the indexer reports WAITING and checks again.
47
+ */
48
+ const IDLE_CHECK_INTERVAL_MS = 3e4;
49
+ /**
50
+ * Delay before the first restart after a failure; doubles on every consecutive failure
51
+ */
52
+ const RETRY_BASE_DELAY_MS = 5e3;
53
+ /**
54
+ * Upper bound for the restart delay
55
+ */
56
+ const RETRY_MAX_DELAY_MS = 3e5;
57
+ /**
58
+ * Consecutive processing failures on the same block before the indexer gives up with a
59
+ * fatal-error. A block that keeps failing after its data was fetched is a bug or bad data, not
60
+ * an outage, and retrying it forever hides the problem.
61
+ */
62
+ const MAX_FAILURES_PER_BLOCK = 5;
63
+ /**
64
+ * Address the health check and metrics servers bind to unless configured otherwise
65
+ */
66
+ const DEFAULT_BIND_HOST = "0.0.0.0";
67
+ /**
44
68
  * Number of successful transactions before recycling the database client
45
69
  * Prevents long-running connection issues and stale connections
46
70
  */
@@ -68,5 +92,5 @@ const PAGINATION_LIMITS = {
68
92
  const GENESIS_BATCH_SIZE = 1e3;
69
93
 
70
94
  //#endregion
71
- export { CONNECT_TIMEOUT_MS, DB_CLIENT_RECYCLE_COUNT, DEFAULT_BATCH_SIZE, DEFAULT_HEALTH_CHECK_PORT, DEFAULT_POLLING_INTERVAL_MS, DEFAULT_PROMETHEUS_PORT, DEFAULT_START_HEIGHT, GENESIS_BATCH_SIZE, PAGINATION_LIMITS, PERIODIC_INTERVALS, QUEUE_DEQUEUE_TIMEOUT_MS, RPC_TIMEOUT_MS };
95
+ export { CONNECT_TIMEOUT_MS, DB_CLIENT_RECYCLE_COUNT, DEFAULT_BATCH_SIZE, DEFAULT_BIND_HOST, DEFAULT_HEALTH_CHECK_PORT, DEFAULT_POLLING_INTERVAL_MS, DEFAULT_PROMETHEUS_PORT, DEFAULT_START_HEIGHT, GENESIS_BATCH_SIZE, IDLE_CHECK_INTERVAL_MS, MAX_FAILURES_PER_BLOCK, PAGINATION_LIMITS, PERIODIC_INTERVALS, QUEUE_DEQUEUE_TIMEOUT_MS, RETRY_BASE_DELAY_MS, RETRY_MAX_DELAY_MS, RPC_TIMEOUT_MS };
72
96
  //# sourceMappingURL=constants.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"constants.mjs","names":[],"sources":["../src/constants.ts"],"sourcesContent":["/**\n * Configuration constants for the Eclesia indexer\n * These values control performance, timeouts, and connection management\n */\n\n/**\n * Number of blocks to prefetch and keep in the processing queue\n * Higher values increase memory usage but improve throughput\n * Recommended range: 300-1000 depending on block size and available memory\n */\nexport const DEFAULT_BATCH_SIZE = 500;\n\n/**\n * Default start height for indexing when no previous height is found\n */\nexport const DEFAULT_START_HEIGHT = 1;\n\n/**\n * Default port for health check HTTP server\n */\nexport const DEFAULT_HEALTH_CHECK_PORT = 8888;\n\n/**\n * Default port for Prometheus metrics server\n */\nexport const DEFAULT_PROMETHEUS_PORT = 9090;\n\n/**\n * Default polling interval in milliseconds when using polling mode instead of WebSocket\n */\nexport const DEFAULT_POLLING_INTERVAL_MS = 5000;\n\n/**\n * Timeout for connecting to the Tendermint RPC in milliseconds\n * If connection is not established within this time, it will be aborted\n */\nexport const CONNECT_TIMEOUT_MS = 10000;\n\n/**\n * Timeout for RPC calls in milliseconds\n * If a call takes longer than this, it will be rejected\n */\nexport const RPC_TIMEOUT_MS = 20000;\n\n/**\n * Timeout for block queue dequeue operations in milliseconds\n * If no block is available within this time, an error will be thrown\n */\nexport const QUEUE_DEQUEUE_TIMEOUT_MS = 30000;\n\n/**\n * Number of successful transactions before recycling the database client\n * Prevents long-running connection issues and stale connections\n */\nexport const DB_CLIENT_RECYCLE_COUNT = 1500;\n\n/**\n * Block intervals for periodic event emission\n * Used for operations that should run at regular block intervals\n */\nexport const PERIODIC_INTERVALS = {\n /** Emit periodic event every 50 blocks */\n SMALL: 50,\n /** Emit periodic event every 100 blocks */\n MEDIUM: 100,\n /** Emit periodic event every 1000 blocks - used for performance logging */\n LARGE: 1000,\n} as const;\n\n/**\n * Pagination limits for blockchain queries\n */\nexport const PAGINATION_LIMITS = {\n /** Default limit for validator queries */\n VALIDATORS: 1000n,\n /** Default limit for delegation queries */\n DELEGATIONS: 250n,\n} as const;\n\n/**\n * Batch size for streaming genesis file processing\n * Number of entries to process at once from genesis JSON\n */\nexport const GENESIS_BATCH_SIZE = 1000;\n"],"mappings":";;;;;;;;;;AAUA,MAAa,qBAAqB;;;;AAKlC,MAAa,uBAAuB;;;;AAKpC,MAAa,4BAA4B;;;;AAKzC,MAAa,0BAA0B;;;;AAKvC,MAAa,8BAA8B;;;;;AAM3C,MAAa,qBAAqB;;;;;AAMlC,MAAa,iBAAiB;;;;;AAM9B,MAAa,2BAA2B;;;;;AAMxC,MAAa,0BAA0B;;;;;AAMvC,MAAa,qBAAqB;CAEhC,OAAO;CAEP,QAAQ;CAER,OAAO;CACR;;;;AAKD,MAAa,oBAAoB;CAE/B,YAAY;CAEZ,aAAa;CACd;;;;;AAMD,MAAa,qBAAqB"}
1
+ {"version":3,"file":"constants.mjs","names":[],"sources":["../src/constants.ts"],"sourcesContent":["/**\n * Configuration constants for the Eclesia indexer\n * These values control performance, timeouts, and connection management\n */\n\n/**\n * Number of blocks to prefetch and keep in the processing queue\n * Higher values increase memory usage but improve throughput\n * Recommended range: 300-1000 depending on block size and available memory\n */\nexport const DEFAULT_BATCH_SIZE = 500;\n\n/**\n * Default start height for indexing when no previous height is found\n */\nexport const DEFAULT_START_HEIGHT = 1;\n\n/**\n * Default port for health check HTTP server\n */\nexport const DEFAULT_HEALTH_CHECK_PORT = 8888;\n\n/**\n * Default port for Prometheus metrics server\n */\nexport const DEFAULT_PROMETHEUS_PORT = 9090;\n\n/**\n * Default polling interval in milliseconds when using polling mode instead of WebSocket\n */\nexport const DEFAULT_POLLING_INTERVAL_MS = 5000;\n\n/**\n * Timeout for connecting to the Tendermint RPC in milliseconds\n * If connection is not established within this time, it will be aborted\n */\nexport const CONNECT_TIMEOUT_MS = 10000;\n\n/**\n * Timeout for RPC calls in milliseconds\n * If a call takes longer than this, it will be rejected\n */\nexport const RPC_TIMEOUT_MS = 20000;\n\n/**\n * @deprecated Waiting for a block is no longer bounded by a timeout: an idle chain is not an\n * error. Kept as an export for compatibility; see IDLE_CHECK_INTERVAL_MS.\n */\nexport const QUEUE_DEQUEUE_TIMEOUT_MS = 30000;\n\n/**\n * How long the indexer waits without any block announcement before checking the chain height.\n * If the chain has moved on without us the subscription is dead and a recovery is triggered;\n * if the chain is simply idle (halt, upgrade) the indexer reports WAITING and checks again.\n */\nexport const IDLE_CHECK_INTERVAL_MS = 30000;\n\n/**\n * Delay before the first restart after a failure; doubles on every consecutive failure\n */\nexport const RETRY_BASE_DELAY_MS = 5000;\n\n/**\n * Upper bound for the restart delay\n */\nexport const RETRY_MAX_DELAY_MS = 300000;\n\n/**\n * Consecutive processing failures on the same block before the indexer gives up with a\n * fatal-error. A block that keeps failing after its data was fetched is a bug or bad data, not\n * an outage, and retrying it forever hides the problem.\n */\nexport const MAX_FAILURES_PER_BLOCK = 5;\n\n/**\n * Address the health check and metrics servers bind to unless configured otherwise\n */\nexport const DEFAULT_BIND_HOST = \"0.0.0.0\";\n\n/**\n * Number of successful transactions before recycling the database client\n * Prevents long-running connection issues and stale connections\n */\nexport const DB_CLIENT_RECYCLE_COUNT = 1500;\n\n/**\n * Block intervals for periodic event emission\n * Used for operations that should run at regular block intervals\n */\nexport const PERIODIC_INTERVALS = {\n /** Emit periodic event every 50 blocks */\n SMALL: 50,\n /** Emit periodic event every 100 blocks */\n MEDIUM: 100,\n /** Emit periodic event every 1000 blocks - used for performance logging */\n LARGE: 1000,\n} as const;\n\n/**\n * Pagination limits for blockchain queries\n */\nexport const PAGINATION_LIMITS = {\n /** Default limit for validator queries */\n VALIDATORS: 1000n,\n /** Default limit for delegation queries */\n DELEGATIONS: 250n,\n} as const;\n\n/**\n * Batch size for streaming genesis file processing\n * Number of entries to process at once from genesis JSON\n */\nexport const GENESIS_BATCH_SIZE = 1000;\n"],"mappings":";;;;;;;;;;AAUA,MAAa,qBAAqB;;;;AAKlC,MAAa,uBAAuB;;;;AAKpC,MAAa,4BAA4B;;;;AAKzC,MAAa,0BAA0B;;;;AAKvC,MAAa,8BAA8B;;;;;AAM3C,MAAa,qBAAqB;;;;;AAMlC,MAAa,iBAAiB;;;;;AAM9B,MAAa,2BAA2B;;;;;;AAOxC,MAAa,yBAAyB;;;;AAKtC,MAAa,sBAAsB;;;;AAKnC,MAAa,qBAAqB;;;;;;AAOlC,MAAa,yBAAyB;;;;AAKtC,MAAa,oBAAoB;;;;;AAMjC,MAAa,0BAA0B;;;;;AAMvC,MAAa,qBAAqB;CAEhC,OAAO;CAEP,QAAQ;CAER,OAAO;CACR;;;;AAKD,MAAa,oBAAoB;CAE/B,YAAY;CAEZ,aAAa;CACd;;;;;AAMD,MAAa,qBAAqB"}
@@ -11,8 +11,17 @@ var EclesiaEmitter = class {
11
11
  emitter = new events.EventEmitter();
12
12
  /** Map tracking the number of handlers registered for each event type */
13
13
  handled = /* @__PURE__ */ new Map();
14
- /** WeakMap storing wrapper functions for proper cleanup */
14
+ /** Wrappers registered per handler and event name, so off() removes exactly what on() added */
15
15
  handlerMap = /* @__PURE__ */ new WeakMap();
16
+ /** Raw handlers per event name in registration order, for callers that await them one by one */
17
+ rawHandlers = /* @__PURE__ */ new Map();
18
+ /**
19
+ * Handlers registered for an event, in registration order.
20
+ * @param eventName - Event name
21
+ */
22
+ handlersFor(eventName) {
23
+ return this.rawHandlers.get(eventName) ?? [];
24
+ }
16
25
  /**
17
26
  * Creates a new EclesiaEmitter instance
18
27
  * Sets max listeners to 0 (unlimited) to handle many modules
@@ -47,18 +56,27 @@ var EclesiaEmitter = class {
47
56
  });
48
57
  }
49
58
  };
50
- this.handlerMap.set(handler, wrapper);
59
+ const byEvent = this.handlerMap.get(handler) ?? /* @__PURE__ */ new Map();
60
+ const wrappers = byEvent.get(eventName) ?? [];
61
+ wrappers.push(wrapper);
62
+ byEvent.set(eventName, wrappers);
63
+ this.handlerMap.set(handler, byEvent);
64
+ const raw = this.rawHandlers.get(eventName) ?? [];
65
+ raw.push(handler);
66
+ this.rawHandlers.set(eventName, raw);
51
67
  this.emitter.on(eventName, wrapper);
52
68
  }
53
69
  off(eventName, handler) {
70
+ const wrappers = this.handlerMap.get(handler)?.get(eventName);
71
+ if (!wrappers || wrappers.length === 0) return;
72
+ const wrapper = wrappers.pop();
73
+ this.emitter.off(eventName, wrapper);
74
+ const raw = this.rawHandlers.get(eventName) ?? [];
75
+ const index = raw.lastIndexOf(handler);
76
+ if (index >= 0) raw.splice(index, 1);
54
77
  const count = this.handled.get(eventName);
55
78
  if (count && count > 1) this.handled.set(eventName, count - 1);
56
79
  else this.handled.delete(eventName);
57
- const wrapper = this.handlerMap.get(handler);
58
- if (wrapper) {
59
- this.emitter.off(eventName, wrapper);
60
- this.handlerMap.delete(handler);
61
- }
62
80
  }
63
81
  };
64
82
 
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["EventEmitter"],"sources":["../../src/emitter/index.ts"],"sourcesContent":["import {\n EventEmitter,\n} from \"node:events\";\n\nimport {\n WithHeightAndUUID,\n} from \"../types/index.js\";\n\n/**\n * Custom event emitter that provides type-safe event handling for blockchain indexing\n * Extends Node.js EventEmitter with UUID tracking and error handling capabilities\n */\nexport class EclesiaEmitter {\n /** Internal Node.js EventEmitter instance */\n private emitter = new EventEmitter();\n\n /** Map tracking the number of handlers registered for each event type */\n public handled = new Map<string, number>();\n\n /** WeakMap storing wrapper functions for proper cleanup */\n private handlerMap = new WeakMap();\n\n /**\n * Creates a new EclesiaEmitter instance\n * Sets max listeners to 0 (unlimited) to handle many modules\n */\n constructor() {\n this.emitter.setMaxListeners(0);\n }\n\n emit<EType extends keyof (WithHeightAndUUID<EventMap>) & string>(\n eventName: EType,\n eventArg: WithHeightAndUUID<EventMap>[EType] & {\n uuid?: string\n },\n ) {\n if (this.handled.has(eventName)) {\n this.emitter.emit(\n eventName, eventArg,\n );\n }\n else {\n this.emitter.emit(\n \"_unhandled\", {\n type: eventName as string,\n event: eventArg,\n uuid: eventArg.uuid,\n },\n );\n }\n }\n\n on<TEventName extends keyof WithHeightAndUUID<EventMap> & string | \"_unhandled\">(\n eventName: TEventName,\n handler: TEventName extends \"_unhandled\"\n ? (eventArg: {\n type: string\n event: unknown\n uuid: string\n }) => void\n : (eventArg: TEventName extends keyof WithHeightAndUUID<EventMap> ? WithHeightAndUUID<EventMap>[TEventName] : never) => void,\n ) {\n const count = this.handled.get(eventName);\n if (count) {\n this.handled.set(\n eventName, count + 1,\n );\n }\n else {\n this.handled.set(\n eventName, 1,\n );\n }\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const wrapper = async (eventData: any) => {\n try {\n await handler(eventData);\n if (eventName !== \"uuid\" && eventName !== \"_unhandled\" && eventData.uuid) {\n this.emit(\n \"uuid\", {\n status: true,\n uuid: eventData.uuid,\n },\n );\n }\n }\n catch (error) {\n if (eventName !== \"uuid\" && eventName !== \"_unhandled\" && eventData.uuid) {\n this.emit(\n \"uuid\", {\n status: false,\n error: error as string,\n uuid: eventData.uuid,\n },\n );\n }\n }\n };\n this.handlerMap.set(\n handler, wrapper,\n );\n this.emitter.on(\n eventName, wrapper,\n );\n }\n\n off<TEventName extends keyof WithHeightAndUUID<EventMap> & string>(\n eventName: TEventName,\n handler: (eventArg: WithHeightAndUUID<EventMap>[TEventName]) => void,\n ) {\n const count = this.handled.get(eventName);\n if (count && count > 1) {\n this.handled.set(\n eventName, count - 1,\n );\n }\n else {\n this.handled.delete(eventName);\n }\n const wrapper = this.handlerMap.get(handler);\n if (wrapper) {\n this.emitter.off(\n eventName, wrapper,\n );\n this.handlerMap.delete(handler);\n }\n }\n}\n"],"mappings":";;;;;;;;AAYA,IAAa,iBAAb,MAA4B;;CAE1B,AAAQ,UAAU,IAAIA,qBAAc;;CAGpC,AAAO,0BAAU,IAAI,KAAqB;;CAG1C,AAAQ,6BAAa,IAAI,SAAS;;;;;CAMlC,cAAc;AACZ,OAAK,QAAQ,gBAAgB,EAAE;;CAGjC,KACE,WACA,UAGA;AACA,MAAI,KAAK,QAAQ,IAAI,UAAU,CAC7B,MAAK,QAAQ,KACX,WAAW,SACZ;MAGD,MAAK,QAAQ,KACX,cAAc;GACZ,MAAM;GACN,OAAO;GACP,MAAM,SAAS;GAChB,CACF;;CAIL,GACE,WACA,SAOA;EACA,MAAM,QAAQ,KAAK,QAAQ,IAAI,UAAU;AACzC,MAAI,MACF,MAAK,QAAQ,IACX,WAAW,QAAQ,EACpB;MAGD,MAAK,QAAQ,IACX,WAAW,EACZ;EAGH,MAAM,UAAU,OAAO,cAAmB;AACxC,OAAI;AACF,UAAM,QAAQ,UAAU;AACxB,QAAI,cAAc,UAAU,cAAc,gBAAgB,UAAU,KAClE,MAAK,KACH,QAAQ;KACN,QAAQ;KACR,MAAM,UAAU;KACjB,CACF;YAGE,OAAO;AACZ,QAAI,cAAc,UAAU,cAAc,gBAAgB,UAAU,KAClE,MAAK,KACH,QAAQ;KACN,QAAQ;KACD;KACP,MAAM,UAAU;KACjB,CACF;;;AAIP,OAAK,WAAW,IACd,SAAS,QACV;AACD,OAAK,QAAQ,GACX,WAAW,QACZ;;CAGH,IACE,WACA,SACA;EACA,MAAM,QAAQ,KAAK,QAAQ,IAAI,UAAU;AACzC,MAAI,SAAS,QAAQ,EACnB,MAAK,QAAQ,IACX,WAAW,QAAQ,EACpB;MAGD,MAAK,QAAQ,OAAO,UAAU;EAEhC,MAAM,UAAU,KAAK,WAAW,IAAI,QAAQ;AAC5C,MAAI,SAAS;AACX,QAAK,QAAQ,IACX,WAAW,QACZ;AACD,QAAK,WAAW,OAAO,QAAQ"}
1
+ {"version":3,"file":"index.cjs","names":["EventEmitter"],"sources":["../../src/emitter/index.ts"],"sourcesContent":["import {\n EventEmitter,\n} from \"node:events\";\n\nimport {\n WithHeightAndUUID,\n} from \"../types/index.js\";\n\n/**\n * Custom event emitter that provides type-safe event handling for blockchain indexing\n * Extends Node.js EventEmitter with UUID tracking and error handling capabilities\n */\nexport class EclesiaEmitter {\n /** Internal Node.js EventEmitter instance */\n private emitter = new EventEmitter();\n\n /** Map tracking the number of handlers registered for each event type */\n public handled = new Map<string, number>();\n\n /** Wrappers registered per handler and event name, so off() removes exactly what on() added */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private handlerMap = new WeakMap<object, Map<string, Array<(eventData: any) => Promise<void>>>>();\n\n /** Raw handlers per event name in registration order, for callers that await them one by one */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private rawHandlers = new Map<string, Array<(eventData: any) => unknown>>();\n\n /**\n * Handlers registered for an event, in registration order.\n * @param eventName - Event name\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n handlersFor(eventName: string): ReadonlyArray<(eventData: any) => unknown> {\n return this.rawHandlers.get(eventName) ?? [];\n }\n\n /**\n * Creates a new EclesiaEmitter instance\n * Sets max listeners to 0 (unlimited) to handle many modules\n */\n constructor() {\n this.emitter.setMaxListeners(0);\n }\n\n emit<EType extends keyof (WithHeightAndUUID<EventMap>) & string>(\n eventName: EType,\n eventArg: WithHeightAndUUID<EventMap>[EType] & {\n uuid?: string\n },\n ) {\n if (this.handled.has(eventName)) {\n this.emitter.emit(\n eventName, eventArg,\n );\n }\n else {\n this.emitter.emit(\n \"_unhandled\", {\n type: eventName as string,\n event: eventArg,\n uuid: eventArg.uuid,\n },\n );\n }\n }\n\n on<TEventName extends keyof WithHeightAndUUID<EventMap> & string | \"_unhandled\">(\n eventName: TEventName,\n handler: TEventName extends \"_unhandled\"\n ? (eventArg: {\n type: string\n event: unknown\n uuid: string\n }) => void\n : (eventArg: TEventName extends keyof WithHeightAndUUID<EventMap> ? WithHeightAndUUID<EventMap>[TEventName] : never) => void,\n ) {\n const count = this.handled.get(eventName);\n if (count) {\n this.handled.set(\n eventName, count + 1,\n );\n }\n else {\n this.handled.set(\n eventName, 1,\n );\n }\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const wrapper = async (eventData: any) => {\n try {\n await handler(eventData);\n if (eventName !== \"uuid\" && eventName !== \"_unhandled\" && eventData.uuid) {\n this.emit(\n \"uuid\", {\n status: true,\n uuid: eventData.uuid,\n },\n );\n }\n }\n catch (error) {\n if (eventName !== \"uuid\" && eventName !== \"_unhandled\" && eventData.uuid) {\n this.emit(\n \"uuid\", {\n status: false,\n error: error as string,\n uuid: eventData.uuid,\n },\n );\n }\n }\n };\n const byEvent = this.handlerMap.get(handler) ?? new Map();\n const wrappers = byEvent.get(eventName) ?? [];\n wrappers.push(wrapper);\n byEvent.set(eventName, wrappers);\n this.handlerMap.set(handler, byEvent);\n const raw = this.rawHandlers.get(eventName) ?? [];\n raw.push(handler as (eventData: unknown) => unknown);\n this.rawHandlers.set(eventName, raw);\n this.emitter.on(\n eventName, wrapper,\n );\n }\n\n off<TEventName extends keyof WithHeightAndUUID<EventMap> & string>(\n eventName: TEventName,\n handler: (eventArg: WithHeightAndUUID<EventMap>[TEventName]) => void,\n ) {\n const wrappers = this.handlerMap.get(handler)?.get(eventName);\n if (!wrappers || wrappers.length === 0) {\n // Never registered for this event: nothing to remove, and the handled count must not\n // drop, or emit() would route to _unhandled while real handlers are still attached\n return;\n }\n const wrapper = wrappers.pop()!;\n this.emitter.off(\n eventName, wrapper,\n );\n const raw = this.rawHandlers.get(eventName) ?? [];\n const index = raw.lastIndexOf(handler as (eventData: unknown) => unknown);\n if (index >= 0) {\n raw.splice(index, 1);\n }\n const count = this.handled.get(eventName);\n if (count && count > 1) {\n this.handled.set(\n eventName, count - 1,\n );\n }\n else {\n this.handled.delete(eventName);\n }\n }\n}\n"],"mappings":";;;;;;;;AAYA,IAAa,iBAAb,MAA4B;;CAE1B,AAAQ,UAAU,IAAIA,qBAAc;;CAGpC,AAAO,0BAAU,IAAI,KAAqB;;CAI1C,AAAQ,6BAAa,IAAI,SAAwE;;CAIjG,AAAQ,8BAAc,IAAI,KAAiD;;;;;CAO3E,YAAY,WAA+D;AACzE,SAAO,KAAK,YAAY,IAAI,UAAU,IAAI,EAAE;;;;;;CAO9C,cAAc;AACZ,OAAK,QAAQ,gBAAgB,EAAE;;CAGjC,KACE,WACA,UAGA;AACA,MAAI,KAAK,QAAQ,IAAI,UAAU,CAC7B,MAAK,QAAQ,KACX,WAAW,SACZ;MAGD,MAAK,QAAQ,KACX,cAAc;GACZ,MAAM;GACN,OAAO;GACP,MAAM,SAAS;GAChB,CACF;;CAIL,GACE,WACA,SAOA;EACA,MAAM,QAAQ,KAAK,QAAQ,IAAI,UAAU;AACzC,MAAI,MACF,MAAK,QAAQ,IACX,WAAW,QAAQ,EACpB;MAGD,MAAK,QAAQ,IACX,WAAW,EACZ;EAGH,MAAM,UAAU,OAAO,cAAmB;AACxC,OAAI;AACF,UAAM,QAAQ,UAAU;AACxB,QAAI,cAAc,UAAU,cAAc,gBAAgB,UAAU,KAClE,MAAK,KACH,QAAQ;KACN,QAAQ;KACR,MAAM,UAAU;KACjB,CACF;YAGE,OAAO;AACZ,QAAI,cAAc,UAAU,cAAc,gBAAgB,UAAU,KAClE,MAAK,KACH,QAAQ;KACN,QAAQ;KACD;KACP,MAAM,UAAU;KACjB,CACF;;;EAIP,MAAM,UAAU,KAAK,WAAW,IAAI,QAAQ,oBAAI,IAAI,KAAK;EACzD,MAAM,WAAW,QAAQ,IAAI,UAAU,IAAI,EAAE;AAC7C,WAAS,KAAK,QAAQ;AACtB,UAAQ,IAAI,WAAW,SAAS;AAChC,OAAK,WAAW,IAAI,SAAS,QAAQ;EACrC,MAAM,MAAM,KAAK,YAAY,IAAI,UAAU,IAAI,EAAE;AACjD,MAAI,KAAK,QAA2C;AACpD,OAAK,YAAY,IAAI,WAAW,IAAI;AACpC,OAAK,QAAQ,GACX,WAAW,QACZ;;CAGH,IACE,WACA,SACA;EACA,MAAM,WAAW,KAAK,WAAW,IAAI,QAAQ,EAAE,IAAI,UAAU;AAC7D,MAAI,CAAC,YAAY,SAAS,WAAW,EAGnC;EAEF,MAAM,UAAU,SAAS,KAAK;AAC9B,OAAK,QAAQ,IACX,WAAW,QACZ;EACD,MAAM,MAAM,KAAK,YAAY,IAAI,UAAU,IAAI,EAAE;EACjD,MAAM,QAAQ,IAAI,YAAY,QAA2C;AACzE,MAAI,SAAS,EACX,KAAI,OAAO,OAAO,EAAE;EAEtB,MAAM,QAAQ,KAAK,QAAQ,IAAI,UAAU;AACzC,MAAI,SAAS,QAAQ,EACnB,MAAK,QAAQ,IACX,WAAW,QAAQ,EACpB;MAGD,MAAK,QAAQ,OAAO,UAAU"}
@@ -11,8 +11,15 @@ declare class EclesiaEmitter {
11
11
  private emitter;
12
12
  /** Map tracking the number of handlers registered for each event type */
13
13
  handled: Map<string, number>;
14
- /** WeakMap storing wrapper functions for proper cleanup */
14
+ /** Wrappers registered per handler and event name, so off() removes exactly what on() added */
15
15
  private handlerMap;
16
+ /** Raw handlers per event name in registration order, for callers that await them one by one */
17
+ private rawHandlers;
18
+ /**
19
+ * Handlers registered for an event, in registration order.
20
+ * @param eventName - Event name
21
+ */
22
+ handlersFor(eventName: string): ReadonlyArray<(eventData: any) => unknown>;
16
23
  /**
17
24
  * Creates a new EclesiaEmitter instance
18
25
  * Sets max listeners to 0 (unlimited) to handle many modules
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.cts","names":[],"sources":["../../src/emitter/index.ts"],"sourcesContent":[],"mappings":";;;;;;AAYA;;AAkB8C,cAlBjC,cAAA,CAkBiC;EAAlB;EACb,QAAA,OAAA;EACiB;EAAlB,OAAA,EAfE,GAeF,CAAA,MAAA,EAAA,MAAA,CAAA;EAA4B;EAoBM,QAAA,UAAA;EAAlB;;;;EAQgC,WAAA,CAAA;EAAlB,IAAA,CAAA,cAAA,MAAA,CA9BhB,iBA8BgB,CA9BE,QA8BF,CAAA,CAAA,GAAA,MAAA,CAAA,CAAA,SAAA,EA7B7B,KA6B6B,EAAA,QAAA,EA5B9B,iBA4B8B,CA5BZ,QA4BY,CAAA,CA5BF,KA4BE,CAAA,GAAA;IAAgD,IAAA,CAAA,EAAA,MAAA;EAAlB,CAAA,CAAA,EAAA,IAAA;EAA4B,EAAA,CAAA,mBAAA,MARxE,iBAQwE,CARtD,QAQsD,CAAA,GAAA,MAAA,GAAA,YAAA,CAAA,CAAA,SAAA,EAPvF,UAOuF,EAAA,OAAA,EANzF,UAMyF,SAAA,YAAA,GAAA,CAAA,QAAA,EAAA;IA8CrD,IAAA,EAAA,MAAA;IAAlB,KAAA,EAAA,OAAA;IAChB,IAAA,EAAA,MAAA;EAC2B,CAAA,EAAA,GAAA,IAAA,GAAA,CAAA,QAAA,EAhDvB,UAgDuB,SAAA,MAhDE,iBAgDF,CAhDoB,QAgDpB,CAAA,GAhDgC,iBAgDhC,CAhDkD,QAgDlD,CAAA,CAhD4D,UAgD5D,CAAA,GAAA,KAAA,EAAA,GAAA,IAAA,CAAA,EAAA,IAAA;EAAlB,GAAA,CAAA,mBAAA,MAFO,iBAEP,CAFyB,QAEzB,CAAA,GAAA,MAAA,CAAA,CAAA,SAAA,EADT,UACS,EAAA,OAAA,EAAA,CAAA,QAAA,EAAA,iBAAA,CAAkB,QAAlB,CAAA,CAA4B,UAA5B,CAAA,EAAA,GAAA,IAAA,CAAA,EAAA,IAAA"}
1
+ {"version":3,"file":"index.d.cts","names":[],"sources":["../../src/emitter/index.ts"],"sourcesContent":[],"mappings":";;;;;;AAYA;;AAoBkC,cApBrB,cAAA,CAoBqB;EAYY;EAAlB,QAAA,OAAA;EACb;EACiB,OAAA,EA7BhB,GA6BgB,CAAA,MAAA,EAAA,MAAA,CAAA;EAAlB;EAA4B,QAAA,UAAA;EAoBM;EAAlB,QAAA,WAAA;EACf;;;;EAO6B,WAAA,CAAA,SAAA,EAAA,MAAA,CAAA,EA1CV,aA0CU,CAAA,CAAA,SAAA,EAAA,GAAA,EAAA,GAAA,OAAA,CAAA;EAAgD;;;;EAmD7D,WAAA,CAAA;EAChB,IAAA,CAAA,cAAA,MAAA,CAlFa,iBAkFb,CAlF+B,QAkF/B,CAAA,CAAA,GAAA,MAAA,CAAA,CAAA,SAAA,EAjFA,KAiFA,EAAA,QAAA,EAhFD,iBAgFC,CAhFiB,QAgFjB,CAAA,CAhF2B,KAgF3B,CAAA,GAAA;IAC2B,IAAA,CAAA,EAAA,MAAA;EAAlB,CAAA,CAAA,EAAA,IAAA;EAA4B,EAAA,CAAA,mBAAA,MA7DtB,iBA6DsB,CA7DJ,QA6DI,CAAA,GAAA,MAAA,GAAA,YAAA,CAAA,CAAA,SAAA,EA5DrC,UA4DqC,EAAA,OAAA,EA3DvC,UA2DuC,SAAA,YAAA,GAAA,CAAA,QAAA,EAAA;IAAU,IAAA,EAAA,MAAA;;;0BArD3C,yBAAyB,kBAAkB,YAAY,kBAAkB,UAAU;+BAmDvE,kBAAkB,+BAClC,gCACS,kBAAkB,UAAU"}
@@ -11,8 +11,15 @@ declare class EclesiaEmitter {
11
11
  private emitter;
12
12
  /** Map tracking the number of handlers registered for each event type */
13
13
  handled: Map<string, number>;
14
- /** WeakMap storing wrapper functions for proper cleanup */
14
+ /** Wrappers registered per handler and event name, so off() removes exactly what on() added */
15
15
  private handlerMap;
16
+ /** Raw handlers per event name in registration order, for callers that await them one by one */
17
+ private rawHandlers;
18
+ /**
19
+ * Handlers registered for an event, in registration order.
20
+ * @param eventName - Event name
21
+ */
22
+ handlersFor(eventName: string): ReadonlyArray<(eventData: any) => unknown>;
16
23
  /**
17
24
  * Creates a new EclesiaEmitter instance
18
25
  * Sets max listeners to 0 (unlimited) to handle many modules
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/emitter/index.ts"],"sourcesContent":[],"mappings":";;;;;;AAYA;;AAkB8C,cAlBjC,cAAA,CAkBiC;EAAlB;EACb,QAAA,OAAA;EACiB;EAAlB,OAAA,EAfE,GAeF,CAAA,MAAA,EAAA,MAAA,CAAA;EAA4B;EAoBM,QAAA,UAAA;EAAlB;;;;EAQgC,WAAA,CAAA;EAAlB,IAAA,CAAA,cAAA,MAAA,CA9BhB,iBA8BgB,CA9BE,QA8BF,CAAA,CAAA,GAAA,MAAA,CAAA,CAAA,SAAA,EA7B7B,KA6B6B,EAAA,QAAA,EA5B9B,iBA4B8B,CA5BZ,QA4BY,CAAA,CA5BF,KA4BE,CAAA,GAAA;IAAgD,IAAA,CAAA,EAAA,MAAA;EAAlB,CAAA,CAAA,EAAA,IAAA;EAA4B,EAAA,CAAA,mBAAA,MARxE,iBAQwE,CARtD,QAQsD,CAAA,GAAA,MAAA,GAAA,YAAA,CAAA,CAAA,SAAA,EAPvF,UAOuF,EAAA,OAAA,EANzF,UAMyF,SAAA,YAAA,GAAA,CAAA,QAAA,EAAA;IA8CrD,IAAA,EAAA,MAAA;IAAlB,KAAA,EAAA,OAAA;IAChB,IAAA,EAAA,MAAA;EAC2B,CAAA,EAAA,GAAA,IAAA,GAAA,CAAA,QAAA,EAhDvB,UAgDuB,SAAA,MAhDE,iBAgDF,CAhDoB,QAgDpB,CAAA,GAhDgC,iBAgDhC,CAhDkD,QAgDlD,CAAA,CAhD4D,UAgD5D,CAAA,GAAA,KAAA,EAAA,GAAA,IAAA,CAAA,EAAA,IAAA;EAAlB,GAAA,CAAA,mBAAA,MAFO,iBAEP,CAFyB,QAEzB,CAAA,GAAA,MAAA,CAAA,CAAA,SAAA,EADT,UACS,EAAA,OAAA,EAAA,CAAA,QAAA,EAAA,iBAAA,CAAkB,QAAlB,CAAA,CAA4B,UAA5B,CAAA,EAAA,GAAA,IAAA,CAAA,EAAA,IAAA"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/emitter/index.ts"],"sourcesContent":[],"mappings":";;;;;;AAYA;;AAoBkC,cApBrB,cAAA,CAoBqB;EAYY;EAAlB,QAAA,OAAA;EACb;EACiB,OAAA,EA7BhB,GA6BgB,CAAA,MAAA,EAAA,MAAA,CAAA;EAAlB;EAA4B,QAAA,UAAA;EAoBM;EAAlB,QAAA,WAAA;EACf;;;;EAO6B,WAAA,CAAA,SAAA,EAAA,MAAA,CAAA,EA1CV,aA0CU,CAAA,CAAA,SAAA,EAAA,GAAA,EAAA,GAAA,OAAA,CAAA;EAAgD;;;;EAmD7D,WAAA,CAAA;EAChB,IAAA,CAAA,cAAA,MAAA,CAlFa,iBAkFb,CAlF+B,QAkF/B,CAAA,CAAA,GAAA,MAAA,CAAA,CAAA,SAAA,EAjFA,KAiFA,EAAA,QAAA,EAhFD,iBAgFC,CAhFiB,QAgFjB,CAAA,CAhF2B,KAgF3B,CAAA,GAAA;IAC2B,IAAA,CAAA,EAAA,MAAA;EAAlB,CAAA,CAAA,EAAA,IAAA;EAA4B,EAAA,CAAA,mBAAA,MA7DtB,iBA6DsB,CA7DJ,QA6DI,CAAA,GAAA,MAAA,GAAA,YAAA,CAAA,CAAA,SAAA,EA5DrC,UA4DqC,EAAA,OAAA,EA3DvC,UA2DuC,SAAA,YAAA,GAAA,CAAA,QAAA,EAAA;IAAU,IAAA,EAAA,MAAA;;;0BArD3C,yBAAyB,kBAAkB,YAAY,kBAAkB,UAAU;+BAmDvE,kBAAkB,+BAClC,gCACS,kBAAkB,UAAU"}
@@ -10,8 +10,17 @@ var EclesiaEmitter = class {
10
10
  emitter = new EventEmitter();
11
11
  /** Map tracking the number of handlers registered for each event type */
12
12
  handled = /* @__PURE__ */ new Map();
13
- /** WeakMap storing wrapper functions for proper cleanup */
13
+ /** Wrappers registered per handler and event name, so off() removes exactly what on() added */
14
14
  handlerMap = /* @__PURE__ */ new WeakMap();
15
+ /** Raw handlers per event name in registration order, for callers that await them one by one */
16
+ rawHandlers = /* @__PURE__ */ new Map();
17
+ /**
18
+ * Handlers registered for an event, in registration order.
19
+ * @param eventName - Event name
20
+ */
21
+ handlersFor(eventName) {
22
+ return this.rawHandlers.get(eventName) ?? [];
23
+ }
15
24
  /**
16
25
  * Creates a new EclesiaEmitter instance
17
26
  * Sets max listeners to 0 (unlimited) to handle many modules
@@ -46,18 +55,27 @@ var EclesiaEmitter = class {
46
55
  });
47
56
  }
48
57
  };
49
- this.handlerMap.set(handler, wrapper);
58
+ const byEvent = this.handlerMap.get(handler) ?? /* @__PURE__ */ new Map();
59
+ const wrappers = byEvent.get(eventName) ?? [];
60
+ wrappers.push(wrapper);
61
+ byEvent.set(eventName, wrappers);
62
+ this.handlerMap.set(handler, byEvent);
63
+ const raw = this.rawHandlers.get(eventName) ?? [];
64
+ raw.push(handler);
65
+ this.rawHandlers.set(eventName, raw);
50
66
  this.emitter.on(eventName, wrapper);
51
67
  }
52
68
  off(eventName, handler) {
69
+ const wrappers = this.handlerMap.get(handler)?.get(eventName);
70
+ if (!wrappers || wrappers.length === 0) return;
71
+ const wrapper = wrappers.pop();
72
+ this.emitter.off(eventName, wrapper);
73
+ const raw = this.rawHandlers.get(eventName) ?? [];
74
+ const index = raw.lastIndexOf(handler);
75
+ if (index >= 0) raw.splice(index, 1);
53
76
  const count = this.handled.get(eventName);
54
77
  if (count && count > 1) this.handled.set(eventName, count - 1);
55
78
  else this.handled.delete(eventName);
56
- const wrapper = this.handlerMap.get(handler);
57
- if (wrapper) {
58
- this.emitter.off(eventName, wrapper);
59
- this.handlerMap.delete(handler);
60
- }
61
79
  }
62
80
  };
63
81
 
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../../src/emitter/index.ts"],"sourcesContent":["import {\n EventEmitter,\n} from \"node:events\";\n\nimport {\n WithHeightAndUUID,\n} from \"../types/index.js\";\n\n/**\n * Custom event emitter that provides type-safe event handling for blockchain indexing\n * Extends Node.js EventEmitter with UUID tracking and error handling capabilities\n */\nexport class EclesiaEmitter {\n /** Internal Node.js EventEmitter instance */\n private emitter = new EventEmitter();\n\n /** Map tracking the number of handlers registered for each event type */\n public handled = new Map<string, number>();\n\n /** WeakMap storing wrapper functions for proper cleanup */\n private handlerMap = new WeakMap();\n\n /**\n * Creates a new EclesiaEmitter instance\n * Sets max listeners to 0 (unlimited) to handle many modules\n */\n constructor() {\n this.emitter.setMaxListeners(0);\n }\n\n emit<EType extends keyof (WithHeightAndUUID<EventMap>) & string>(\n eventName: EType,\n eventArg: WithHeightAndUUID<EventMap>[EType] & {\n uuid?: string\n },\n ) {\n if (this.handled.has(eventName)) {\n this.emitter.emit(\n eventName, eventArg,\n );\n }\n else {\n this.emitter.emit(\n \"_unhandled\", {\n type: eventName as string,\n event: eventArg,\n uuid: eventArg.uuid,\n },\n );\n }\n }\n\n on<TEventName extends keyof WithHeightAndUUID<EventMap> & string | \"_unhandled\">(\n eventName: TEventName,\n handler: TEventName extends \"_unhandled\"\n ? (eventArg: {\n type: string\n event: unknown\n uuid: string\n }) => void\n : (eventArg: TEventName extends keyof WithHeightAndUUID<EventMap> ? WithHeightAndUUID<EventMap>[TEventName] : never) => void,\n ) {\n const count = this.handled.get(eventName);\n if (count) {\n this.handled.set(\n eventName, count + 1,\n );\n }\n else {\n this.handled.set(\n eventName, 1,\n );\n }\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const wrapper = async (eventData: any) => {\n try {\n await handler(eventData);\n if (eventName !== \"uuid\" && eventName !== \"_unhandled\" && eventData.uuid) {\n this.emit(\n \"uuid\", {\n status: true,\n uuid: eventData.uuid,\n },\n );\n }\n }\n catch (error) {\n if (eventName !== \"uuid\" && eventName !== \"_unhandled\" && eventData.uuid) {\n this.emit(\n \"uuid\", {\n status: false,\n error: error as string,\n uuid: eventData.uuid,\n },\n );\n }\n }\n };\n this.handlerMap.set(\n handler, wrapper,\n );\n this.emitter.on(\n eventName, wrapper,\n );\n }\n\n off<TEventName extends keyof WithHeightAndUUID<EventMap> & string>(\n eventName: TEventName,\n handler: (eventArg: WithHeightAndUUID<EventMap>[TEventName]) => void,\n ) {\n const count = this.handled.get(eventName);\n if (count && count > 1) {\n this.handled.set(\n eventName, count - 1,\n );\n }\n else {\n this.handled.delete(eventName);\n }\n const wrapper = this.handlerMap.get(handler);\n if (wrapper) {\n this.emitter.off(\n eventName, wrapper,\n );\n this.handlerMap.delete(handler);\n }\n }\n}\n"],"mappings":";;;;;;;AAYA,IAAa,iBAAb,MAA4B;;CAE1B,AAAQ,UAAU,IAAI,cAAc;;CAGpC,AAAO,0BAAU,IAAI,KAAqB;;CAG1C,AAAQ,6BAAa,IAAI,SAAS;;;;;CAMlC,cAAc;AACZ,OAAK,QAAQ,gBAAgB,EAAE;;CAGjC,KACE,WACA,UAGA;AACA,MAAI,KAAK,QAAQ,IAAI,UAAU,CAC7B,MAAK,QAAQ,KACX,WAAW,SACZ;MAGD,MAAK,QAAQ,KACX,cAAc;GACZ,MAAM;GACN,OAAO;GACP,MAAM,SAAS;GAChB,CACF;;CAIL,GACE,WACA,SAOA;EACA,MAAM,QAAQ,KAAK,QAAQ,IAAI,UAAU;AACzC,MAAI,MACF,MAAK,QAAQ,IACX,WAAW,QAAQ,EACpB;MAGD,MAAK,QAAQ,IACX,WAAW,EACZ;EAGH,MAAM,UAAU,OAAO,cAAmB;AACxC,OAAI;AACF,UAAM,QAAQ,UAAU;AACxB,QAAI,cAAc,UAAU,cAAc,gBAAgB,UAAU,KAClE,MAAK,KACH,QAAQ;KACN,QAAQ;KACR,MAAM,UAAU;KACjB,CACF;YAGE,OAAO;AACZ,QAAI,cAAc,UAAU,cAAc,gBAAgB,UAAU,KAClE,MAAK,KACH,QAAQ;KACN,QAAQ;KACD;KACP,MAAM,UAAU;KACjB,CACF;;;AAIP,OAAK,WAAW,IACd,SAAS,QACV;AACD,OAAK,QAAQ,GACX,WAAW,QACZ;;CAGH,IACE,WACA,SACA;EACA,MAAM,QAAQ,KAAK,QAAQ,IAAI,UAAU;AACzC,MAAI,SAAS,QAAQ,EACnB,MAAK,QAAQ,IACX,WAAW,QAAQ,EACpB;MAGD,MAAK,QAAQ,OAAO,UAAU;EAEhC,MAAM,UAAU,KAAK,WAAW,IAAI,QAAQ;AAC5C,MAAI,SAAS;AACX,QAAK,QAAQ,IACX,WAAW,QACZ;AACD,QAAK,WAAW,OAAO,QAAQ"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../src/emitter/index.ts"],"sourcesContent":["import {\n EventEmitter,\n} from \"node:events\";\n\nimport {\n WithHeightAndUUID,\n} from \"../types/index.js\";\n\n/**\n * Custom event emitter that provides type-safe event handling for blockchain indexing\n * Extends Node.js EventEmitter with UUID tracking and error handling capabilities\n */\nexport class EclesiaEmitter {\n /** Internal Node.js EventEmitter instance */\n private emitter = new EventEmitter();\n\n /** Map tracking the number of handlers registered for each event type */\n public handled = new Map<string, number>();\n\n /** Wrappers registered per handler and event name, so off() removes exactly what on() added */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private handlerMap = new WeakMap<object, Map<string, Array<(eventData: any) => Promise<void>>>>();\n\n /** Raw handlers per event name in registration order, for callers that await them one by one */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private rawHandlers = new Map<string, Array<(eventData: any) => unknown>>();\n\n /**\n * Handlers registered for an event, in registration order.\n * @param eventName - Event name\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n handlersFor(eventName: string): ReadonlyArray<(eventData: any) => unknown> {\n return this.rawHandlers.get(eventName) ?? [];\n }\n\n /**\n * Creates a new EclesiaEmitter instance\n * Sets max listeners to 0 (unlimited) to handle many modules\n */\n constructor() {\n this.emitter.setMaxListeners(0);\n }\n\n emit<EType extends keyof (WithHeightAndUUID<EventMap>) & string>(\n eventName: EType,\n eventArg: WithHeightAndUUID<EventMap>[EType] & {\n uuid?: string\n },\n ) {\n if (this.handled.has(eventName)) {\n this.emitter.emit(\n eventName, eventArg,\n );\n }\n else {\n this.emitter.emit(\n \"_unhandled\", {\n type: eventName as string,\n event: eventArg,\n uuid: eventArg.uuid,\n },\n );\n }\n }\n\n on<TEventName extends keyof WithHeightAndUUID<EventMap> & string | \"_unhandled\">(\n eventName: TEventName,\n handler: TEventName extends \"_unhandled\"\n ? (eventArg: {\n type: string\n event: unknown\n uuid: string\n }) => void\n : (eventArg: TEventName extends keyof WithHeightAndUUID<EventMap> ? WithHeightAndUUID<EventMap>[TEventName] : never) => void,\n ) {\n const count = this.handled.get(eventName);\n if (count) {\n this.handled.set(\n eventName, count + 1,\n );\n }\n else {\n this.handled.set(\n eventName, 1,\n );\n }\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const wrapper = async (eventData: any) => {\n try {\n await handler(eventData);\n if (eventName !== \"uuid\" && eventName !== \"_unhandled\" && eventData.uuid) {\n this.emit(\n \"uuid\", {\n status: true,\n uuid: eventData.uuid,\n },\n );\n }\n }\n catch (error) {\n if (eventName !== \"uuid\" && eventName !== \"_unhandled\" && eventData.uuid) {\n this.emit(\n \"uuid\", {\n status: false,\n error: error as string,\n uuid: eventData.uuid,\n },\n );\n }\n }\n };\n const byEvent = this.handlerMap.get(handler) ?? new Map();\n const wrappers = byEvent.get(eventName) ?? [];\n wrappers.push(wrapper);\n byEvent.set(eventName, wrappers);\n this.handlerMap.set(handler, byEvent);\n const raw = this.rawHandlers.get(eventName) ?? [];\n raw.push(handler as (eventData: unknown) => unknown);\n this.rawHandlers.set(eventName, raw);\n this.emitter.on(\n eventName, wrapper,\n );\n }\n\n off<TEventName extends keyof WithHeightAndUUID<EventMap> & string>(\n eventName: TEventName,\n handler: (eventArg: WithHeightAndUUID<EventMap>[TEventName]) => void,\n ) {\n const wrappers = this.handlerMap.get(handler)?.get(eventName);\n if (!wrappers || wrappers.length === 0) {\n // Never registered for this event: nothing to remove, and the handled count must not\n // drop, or emit() would route to _unhandled while real handlers are still attached\n return;\n }\n const wrapper = wrappers.pop()!;\n this.emitter.off(\n eventName, wrapper,\n );\n const raw = this.rawHandlers.get(eventName) ?? [];\n const index = raw.lastIndexOf(handler as (eventData: unknown) => unknown);\n if (index >= 0) {\n raw.splice(index, 1);\n }\n const count = this.handled.get(eventName);\n if (count && count > 1) {\n this.handled.set(\n eventName, count - 1,\n );\n }\n else {\n this.handled.delete(eventName);\n }\n }\n}\n"],"mappings":";;;;;;;AAYA,IAAa,iBAAb,MAA4B;;CAE1B,AAAQ,UAAU,IAAI,cAAc;;CAGpC,AAAO,0BAAU,IAAI,KAAqB;;CAI1C,AAAQ,6BAAa,IAAI,SAAwE;;CAIjG,AAAQ,8BAAc,IAAI,KAAiD;;;;;CAO3E,YAAY,WAA+D;AACzE,SAAO,KAAK,YAAY,IAAI,UAAU,IAAI,EAAE;;;;;;CAO9C,cAAc;AACZ,OAAK,QAAQ,gBAAgB,EAAE;;CAGjC,KACE,WACA,UAGA;AACA,MAAI,KAAK,QAAQ,IAAI,UAAU,CAC7B,MAAK,QAAQ,KACX,WAAW,SACZ;MAGD,MAAK,QAAQ,KACX,cAAc;GACZ,MAAM;GACN,OAAO;GACP,MAAM,SAAS;GAChB,CACF;;CAIL,GACE,WACA,SAOA;EACA,MAAM,QAAQ,KAAK,QAAQ,IAAI,UAAU;AACzC,MAAI,MACF,MAAK,QAAQ,IACX,WAAW,QAAQ,EACpB;MAGD,MAAK,QAAQ,IACX,WAAW,EACZ;EAGH,MAAM,UAAU,OAAO,cAAmB;AACxC,OAAI;AACF,UAAM,QAAQ,UAAU;AACxB,QAAI,cAAc,UAAU,cAAc,gBAAgB,UAAU,KAClE,MAAK,KACH,QAAQ;KACN,QAAQ;KACR,MAAM,UAAU;KACjB,CACF;YAGE,OAAO;AACZ,QAAI,cAAc,UAAU,cAAc,gBAAgB,UAAU,KAClE,MAAK,KACH,QAAQ;KACN,QAAQ;KACD;KACP,MAAM,UAAU;KACjB,CACF;;;EAIP,MAAM,UAAU,KAAK,WAAW,IAAI,QAAQ,oBAAI,IAAI,KAAK;EACzD,MAAM,WAAW,QAAQ,IAAI,UAAU,IAAI,EAAE;AAC7C,WAAS,KAAK,QAAQ;AACtB,UAAQ,IAAI,WAAW,SAAS;AAChC,OAAK,WAAW,IAAI,SAAS,QAAQ;EACrC,MAAM,MAAM,KAAK,YAAY,IAAI,UAAU,IAAI,EAAE;AACjD,MAAI,KAAK,QAA2C;AACpD,OAAK,YAAY,IAAI,WAAW,IAAI;AACpC,OAAK,QAAQ,GACX,WAAW,QACZ;;CAGH,IACE,WACA,SACA;EACA,MAAM,WAAW,KAAK,WAAW,IAAI,QAAQ,EAAE,IAAI,UAAU;AAC7D,MAAI,CAAC,YAAY,SAAS,WAAW,EAGnC;EAEF,MAAM,UAAU,SAAS,KAAK;AAC9B,OAAK,QAAQ,IACX,WAAW,QACZ;EACD,MAAM,MAAM,KAAK,YAAY,IAAI,UAAU,IAAI,EAAE;EACjD,MAAM,QAAQ,IAAI,YAAY,QAA2C;AACzE,MAAI,SAAS,EACX,KAAI,OAAO,OAAO,EAAE;EAEtB,MAAM,QAAQ,KAAK,QAAQ,IAAI,UAAU;AACzC,MAAI,SAAS,QAAQ,EACnB,MAAK,QAAQ,IACX,WAAW,QAAQ,EACpB;MAGD,MAAK,QAAQ,OAAO,UAAU"}
package/dist/index.cjs CHANGED
@@ -15,6 +15,7 @@ exports.CircularBuffer = require_index$3.CircularBuffer;
15
15
  exports.ConfigurationError = require_index$1.ConfigurationError;
16
16
  exports.DB_CLIENT_RECYCLE_COUNT = require_constants.DB_CLIENT_RECYCLE_COUNT;
17
17
  exports.DEFAULT_BATCH_SIZE = require_constants.DEFAULT_BATCH_SIZE;
18
+ exports.DEFAULT_BIND_HOST = require_constants.DEFAULT_BIND_HOST;
18
19
  exports.DEFAULT_HEALTH_CHECK_PORT = require_constants.DEFAULT_HEALTH_CHECK_PORT;
19
20
  exports.DEFAULT_POLLING_INTERVAL_MS = require_constants.DEFAULT_POLLING_INTERVAL_MS;
20
21
  exports.DEFAULT_PROMETHEUS_PORT = require_constants.DEFAULT_PROMETHEUS_PORT;
@@ -22,10 +23,13 @@ exports.DEFAULT_START_HEIGHT = require_constants.DEFAULT_START_HEIGHT;
22
23
  exports.DatabaseError = require_index$1.DatabaseError;
23
24
  exports.EcleciaIndexer = require_index$6.EcleciaIndexer;
24
25
  exports.EclesiaEmitter = require_index.EclesiaEmitter;
26
+ exports.EclesiaIndexer = require_index$6.EclesiaIndexer;
25
27
  exports.GENESIS_BATCH_SIZE = require_constants.GENESIS_BATCH_SIZE;
26
28
  exports.GenesisError = require_index$1.GenesisError;
29
+ exports.IDLE_CHECK_INTERVAL_MS = require_constants.IDLE_CHECK_INTERVAL_MS;
27
30
  exports.IndexerError = require_index$1.IndexerError;
28
31
  exports.IndexerMetrics = require_index$2.IndexerMetrics;
32
+ exports.MAX_FAILURES_PER_BLOCK = require_constants.MAX_FAILURES_PER_BLOCK;
29
33
  Object.defineProperty(exports, 'Mocks', {
30
34
  enumerable: true,
31
35
  get: function () {
@@ -37,6 +41,8 @@ exports.PAGINATION_LIMITS = require_constants.PAGINATION_LIMITS;
37
41
  exports.PERIODIC_INTERVALS = require_constants.PERIODIC_INTERVALS;
38
42
  exports.PromiseQueue = require_index$3.PromiseQueue;
39
43
  exports.QUEUE_DEQUEUE_TIMEOUT_MS = require_constants.QUEUE_DEQUEUE_TIMEOUT_MS;
44
+ exports.RETRY_BASE_DELAY_MS = require_constants.RETRY_BASE_DELAY_MS;
45
+ exports.RETRY_MAX_DELAY_MS = require_constants.RETRY_MAX_DELAY_MS;
40
46
  exports.RPCError = require_index$1.RPCError;
41
47
  exports.RPC_TIMEOUT_MS = require_constants.RPC_TIMEOUT_MS;
42
48
  Object.defineProperty(exports, 'Types', {