@artblocks/abx-indexer 0.1.0-alpha.9 → 0.1.1

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/CHANGELOG.md ADDED
@@ -0,0 +1,167 @@
1
+ # @artblocks/abx-indexer
2
+
3
+ ## 0.1.1
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies [7947ba9]
8
+ - @artblocks/abx-sdk@0.2.0
9
+
10
+ ## 0.1.0
11
+
12
+ ### Patch Changes
13
+
14
+ - 8f35dae: Prepare package metadata, release notes, and public-facing source comments for the initial public
15
+ source release.
16
+ - 719b9fe: Make the bundled skill read network and sponsorship support from CLI capabilities and the live
17
+ service descriptor instead of a hardcoded network list. Refresh public documentation references in
18
+ the published packages.
19
+ - Updated dependencies [21e3d6c]
20
+ - Updated dependencies [22abce8]
21
+ - Updated dependencies [4d5e2b1]
22
+ - Updated dependencies [56973c4]
23
+ - Updated dependencies [2290b0a]
24
+ - Updated dependencies [b9197bc]
25
+ - Updated dependencies [8ccbede]
26
+ - Updated dependencies [d925eb1]
27
+ - Updated dependencies [ea57f7a]
28
+ - Updated dependencies [3ddba71]
29
+ - Updated dependencies [8f35dae]
30
+ - Updated dependencies [719b9fe]
31
+ - Updated dependencies [9065128]
32
+ - Updated dependencies [c2400a7]
33
+ - Updated dependencies [3d7fe3c]
34
+ - Updated dependencies [7b462e2]
35
+ - Updated dependencies [ddb2e0b]
36
+ - Updated dependencies [4512962]
37
+ - Updated dependencies [76cfc6a]
38
+ - Updated dependencies [5522192]
39
+ - @artblocks/abx-sdk@0.1.0
40
+
41
+ ## 0.1.0-alpha.50
42
+
43
+ ### Patch Changes
44
+
45
+ - 719b9fe: Make the bundled skill read network and sponsorship support from CLI capabilities and the live
46
+ service descriptor instead of a hardcoded network list. Refresh public documentation references in
47
+ the published packages.
48
+ - Updated dependencies [719b9fe]
49
+ - @artblocks/abx-sdk@0.1.0-alpha.49
50
+
51
+ ## 0.1.0-alpha.49
52
+
53
+ ### Patch Changes
54
+
55
+ - Updated dependencies [4d5e2b1]
56
+ - @artblocks/abx-sdk@0.1.0-alpha.48
57
+
58
+ ## 0.1.0-alpha.48
59
+
60
+ ### Patch Changes
61
+
62
+ - Updated dependencies [56973c4]
63
+ - @artblocks/abx-sdk@0.1.0-alpha.47
64
+
65
+ ## 0.1.0-alpha.47
66
+
67
+ ### Patch Changes
68
+
69
+ - Updated dependencies [ddb2e0b]
70
+ - Updated dependencies [76cfc6a]
71
+ - @artblocks/abx-sdk@0.1.0-alpha.46
72
+
73
+ ## 0.1.0-alpha.46
74
+
75
+ ### Patch Changes
76
+
77
+ - Updated dependencies [d925eb1]
78
+ - @artblocks/abx-sdk@0.1.0-alpha.45
79
+
80
+ ## 0.1.0-alpha.45
81
+
82
+ ### Patch Changes
83
+
84
+ - Updated dependencies [22abce8]
85
+ - @artblocks/abx-sdk@0.1.0-alpha.44
86
+
87
+ ## 0.1.0-alpha.44
88
+
89
+ ### Patch Changes
90
+
91
+ - Updated dependencies [2290b0a]
92
+ - @artblocks/abx-sdk@0.1.0-alpha.43
93
+
94
+ ## 0.1.0-alpha.43
95
+
96
+ ### Patch Changes
97
+
98
+ - Updated dependencies [ea57f7a]
99
+ - @artblocks/abx-sdk@0.1.0-alpha.42
100
+
101
+ ## 0.1.0-alpha.42
102
+
103
+ ### Patch Changes
104
+
105
+ - Updated dependencies [8ccbede]
106
+ - @artblocks/abx-sdk@0.1.0-alpha.41
107
+
108
+ ## 0.1.0-alpha.41
109
+
110
+ ### Patch Changes
111
+
112
+ - Updated dependencies [b9197bc]
113
+ - @artblocks/abx-sdk@0.1.0-alpha.40
114
+
115
+ ## 0.1.0-alpha.40
116
+
117
+ ### Patch Changes
118
+
119
+ - Updated dependencies [3d7fe3c]
120
+ - Updated dependencies [7b462e2]
121
+ - @artblocks/abx-sdk@0.1.0-alpha.39
122
+
123
+ ## 0.1.0-alpha.39
124
+
125
+ ### Patch Changes
126
+
127
+ - Updated dependencies [c2400a7]
128
+ - @artblocks/abx-sdk@0.1.0-alpha.38
129
+
130
+ ## 0.1.0-alpha.38
131
+
132
+ ### Patch Changes
133
+
134
+ - Updated dependencies [4512962]
135
+ - @artblocks/abx-sdk@0.1.0-alpha.37
136
+
137
+ ## 0.1.0-alpha.37
138
+
139
+ ### Patch Changes
140
+
141
+ - Updated dependencies [5522192]
142
+ - @artblocks/abx-sdk@0.1.0-alpha.36
143
+
144
+ ## 0.1.0-alpha.36
145
+
146
+ ### Patch Changes
147
+
148
+ - Updated dependencies [21e3d6c]
149
+ - Updated dependencies [a73922c]
150
+ - @artblocks/abx-sdk@0.1.0-alpha.35
151
+
152
+ ## 0.1.0-alpha.35
153
+
154
+ ### Patch Changes
155
+
156
+ - Updated dependencies [3ddba71]
157
+ - Updated dependencies [9065128]
158
+ - @artblocks/abx-sdk@0.1.0-alpha.34
159
+
160
+ ## 0.1.0-alpha.34
161
+
162
+ ### Patch Changes
163
+
164
+ - 9242a05: Prepare package metadata, release notes, and public-facing source comments for the initial public
165
+ source release.
166
+ - Updated dependencies [9242a05]
167
+ - @artblocks/abx-sdk@0.1.0-alpha.33
package/dist/index.d.ts CHANGED
@@ -4,6 +4,6 @@
4
4
  * Replays the event spine from chain into a disposable, rebuildable projection.
5
5
  * The canonical re-index: how every service onboards or exits a project.
6
6
  */
7
- export { SelfHostIndexer, type IndexResult } from './indexer.js';
7
+ export { SelfHostIndexer, DEFAULT_INCREMENTAL_VACUUM_PAGES, DEFAULT_VACUUM_INTERVAL_MS, type IndexResult, type ReindexOptions, } from './indexer.js';
8
8
  export { SqliteStore, type Store, type ProjectRegistration, type EffectStatusRow, type EffectArtifactRow, } from './store.js';
9
9
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAC,eAAe,EAAE,KAAK,WAAW,EAAC,MAAM,cAAc,CAAC;AAC/D,OAAO,EACL,WAAW,EACX,KAAK,KAAK,EACV,KAAK,mBAAmB,EACxB,KAAK,eAAe,EACpB,KAAK,iBAAiB,GACvB,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EACL,eAAe,EACf,gCAAgC,EAChC,0BAA0B,EAC1B,KAAK,WAAW,EAChB,KAAK,cAAc,GACpB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,WAAW,EACX,KAAK,KAAK,EACV,KAAK,mBAAmB,EACxB,KAAK,eAAe,EACpB,KAAK,iBAAiB,GACvB,MAAM,YAAY,CAAC"}
package/dist/index.js CHANGED
@@ -4,6 +4,6 @@
4
4
  * Replays the event spine from chain into a disposable, rebuildable projection.
5
5
  * The canonical re-index: how every service onboards or exits a project.
6
6
  */
7
- export { SelfHostIndexer } from './indexer.js';
7
+ export { SelfHostIndexer, DEFAULT_INCREMENTAL_VACUUM_PAGES, DEFAULT_VACUUM_INTERVAL_MS, } from './indexer.js';
8
8
  export { SqliteStore, } from './store.js';
9
9
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAC,eAAe,EAAmB,MAAM,cAAc,CAAC;AAC/D,OAAO,EACL,WAAW,GAKZ,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EACL,eAAe,EACf,gCAAgC,EAChC,0BAA0B,GAG3B,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,WAAW,GAKZ,MAAM,YAAY,CAAC"}
package/dist/indexer.d.ts CHANGED
@@ -1,10 +1,45 @@
1
- import { type Address, type ProjectState, type PublicClient } from '@artblocks/abx-sdk';
1
+ import { type Address, type GetLogsAdaptiveOptions, type ProjectState, type PublicClient, type ReconstructBlockTag } from '@artblocks/abx-sdk';
2
+ import type { Log } from 'viem';
2
3
  import { type IndexStatusRow, type Store, type ProjectRegistration } from './store.js';
4
+ export interface ReindexOptions {
5
+ full?: boolean;
6
+ readUriDocuments?: boolean;
7
+ rpcUrl?: string;
8
+ /** Already-fetched logs for this project covering {@link toBlock}. Skips the
9
+ * per-project `eth_getLogs` — the watch loop that scanned the registered set
10
+ * holds the delta and should be the only getLogs. */
11
+ logs?: readonly Log[];
12
+ /** Inclusive scan head `logs` cover. Required with `logs`. */
13
+ toBlock?: bigint;
14
+ /**
15
+ * Stop the scan boundary at this block tag instead of chain head (the default, unchanged
16
+ * behavior). Resolved to a concrete block number BEFORE scanning (`resolveBlockTag` in the SDK),
17
+ * so the stored watermark (`ProjectState.toBlock`) is always a literal number, never the tag —
18
+ * see {@link ReconstructBlockTag}. Ignored when `logs` is supplied: that path's own `toBlock` is
19
+ * the caller's already-resolved scan head, from a watch loop that has nothing to do with a
20
+ * per-project tag choice.
21
+ */
22
+ blockTag?: ReconstructBlockTag;
23
+ /** See {@link GetLogsAdaptiveOptions.onChunk} — the only progress signal during a large scan. */
24
+ onChunk?: GetLogsAdaptiveOptions['onChunk'];
25
+ }
3
26
  export interface IndexResult {
4
27
  state: ProjectState;
5
28
  elapsedMs: number;
6
29
  mode: 'full' | 'incremental';
7
30
  }
31
+ /** Bounded per-pass reclaim for {@link SelfHostIndexer.runIncrementalVacuum} — ~100 pages is ~400KB
32
+ * at SQLite's default 4096-byte page size, cheap enough to run synchronously without a request or a
33
+ * watch tick noticing, while a long-running node with a large freelist still drains it over several
34
+ * passes instead of never. */
35
+ export declare const DEFAULT_INCREMENTAL_VACUUM_PAGES = 100;
36
+ /** Default cadence for automatic SQLite maintenance (see
37
+ * {@link SelfHostIndexer.startVacuumMaintenance}). Deliberately far coarser than the chain watcher's
38
+ * poll (`ABX_WATCH_INTERVAL_MS`, 12s by default): freed pages accumulate slowly (a reclaim, a
39
+ * dropped projection, a pruned bound artifact), so there is nothing to gain from touching the file
40
+ * every tick — and this is process-internal scheduling, not an operator-facing knob, so it isn't
41
+ * read from the environment the way the watcher's interval is. */
42
+ export declare const DEFAULT_VACUUM_INTERVAL_MS: number;
8
43
  /**
9
44
  * The reference indexer (Layer 3). It does one thing well: replay the event
10
45
  * spine from chain into the store. Because every state change rides a standard,
@@ -19,6 +54,16 @@ export declare class SelfHostIndexer {
19
54
  /** Catch-up runs in flight, per lowercased address — see {@link reindexShared}. */
20
55
  private inFlight;
21
56
  constructor(store?: Store);
57
+ /**
58
+ * The pooled read client for a chain, or — with `rpcUrl` — one pinned to a SINGLE endpoint.
59
+ *
60
+ * The default (no `rpcUrl`) is a viem `fallback` across every configured endpoint, which fails
61
+ * over on an *error*. It does not fail over on a successful empty answer, which is exactly what an
62
+ * endpoint that has pruned its log history returns for an old block: `[]`, HTTP 200. Pinning one
63
+ * endpoint is how a caller can re-run the same scan against each in turn and find one that holds
64
+ * the history (see the CLI's empty-scan recovery). Pooled per (chain, endpoint) so the pinned
65
+ * clients don't evict the shared one.
66
+ */
22
67
  private client;
23
68
  /** The RPC client for a chain — exposed for reads that aren't a reindex (e.g. deploy-block
24
69
  * discovery in the admin control plane). Reuses the same pooled client as `reindex`. */
@@ -34,9 +79,7 @@ export declare class SelfHostIndexer {
34
79
  * replay. `{full: true}` forces a replay from the deploy block (the durability
35
80
  * proof, and what runs automatically when there's no prior state). Idempotent.
36
81
  */
37
- reindex(address: Address, opts?: {
38
- full?: boolean;
39
- }): Promise<IndexResult>;
82
+ reindex(address: Address, opts?: ReindexOptions): Promise<IndexResult>;
40
83
  /**
41
84
  * {@link reindex}, but concurrent calls for the same project COALESCE into one run.
42
85
  *
@@ -46,9 +89,7 @@ export declare class SelfHostIndexer {
46
89
  * the bottleneck — so the second caller joins the first run instead. A caller that needs a *full*
47
90
  * replay while an incremental is in flight gets its replay queued after it, never dropped.
48
91
  */
49
- reindexShared(address: Address, opts?: {
50
- full?: boolean;
51
- }): Promise<IndexResult>;
92
+ reindexShared(address: Address, opts?: ReindexOptions): Promise<IndexResult>;
52
93
  /** Is a catch-up for this project running right now? (Lets a caller answer "still backfilling"
53
94
  * without starting more work.) */
54
95
  isCatchingUp(address: Address): boolean;
@@ -61,14 +102,44 @@ export declare class SelfHostIndexer {
61
102
  indexStatus(address: Address): IndexStatusRow;
62
103
  private track;
63
104
  /** Re-index every registered project. */
64
- reindexAll(opts?: {
65
- full?: boolean;
66
- }): Promise<IndexResult[]>;
105
+ reindexAll(opts?: ReindexOptions): Promise<IndexResult[]>;
67
106
  getProject(address: Address): ProjectState | null;
68
107
  /** Throw away a project's reconstructed projection, keeping its registration — the next
69
108
  * {@link reindex} then rebuilds it from the deploy block. The projection is a disposable cache of
70
109
  * chain state; this is how you prove it (`abx demo` deletes and replays to show identical state). */
71
110
  dropProjection(address: Address): void;
72
111
  listProjects(): ProjectState[];
112
+ /**
113
+ * Run one bounded `PRAGMA incremental_vacuum` pass, delegating to {@link SqliteStore.runIncrementalVacuum}.
114
+ * A no-op (returns 0) for any `Store` implementation that isn't a `SqliteStore` — vacuuming is a
115
+ * SQLite-specific concern, so a Postgres-backed deploy (which owns its own manual VACUUM story)
116
+ * simply has nothing to do here. Exposed on its own (not just via {@link startVacuumMaintenance})
117
+ * so a caller can also run one pass on demand — e.g. right after `abx vacuum convert`, to reclaim
118
+ * whatever the full VACUUM already didn't (it shouldn't leave anything, but this makes "did it
119
+ * work" independently checkable).
120
+ */
121
+ runIncrementalVacuum(maxPages?: number): number;
122
+ /**
123
+ * Start automatic SQLite maintenance: {@link runIncrementalVacuum} on its own
124
+ * timer, decoupled from the chain watcher's poll loop (`packages/token-api/src/watcher.ts`) so a
125
+ * reclaim pass can never sit inline with a request or a watch tick — it runs BETWEEN them, on
126
+ * whatever cadence the caller (or the default) picks, and a slow pass only ever delays the next
127
+ * pass, never a request being served concurrently (`node:sqlite`'s `DatabaseSync` is synchronous,
128
+ * but each pass is bounded — see `SqliteStore.runIncrementalVacuum` — precisely so that's cheap).
129
+ *
130
+ * `abx serve` is the intended caller, started once alongside `startChainWatcher`. Safe to call
131
+ * unconditionally: for a non-`SqliteStore` backend this still returns a working `stop()`, it just
132
+ * schedules calls that are themselves no-ops (see {@link runIncrementalVacuum}).
133
+ *
134
+ * A failed pass is logged and swallowed — maintenance must never be the thing that takes a node
135
+ * down; the freelist simply waits for the next pass.
136
+ */
137
+ startVacuumMaintenance(opts?: {
138
+ intervalMs?: number;
139
+ maxPages?: number;
140
+ log?: (line: string) => void;
141
+ }): {
142
+ stop(): void;
143
+ };
73
144
  }
74
145
  //# sourceMappingURL=indexer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"indexer.d.ts","sourceRoot":"","sources":["../src/indexer.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,OAAO,EACZ,KAAK,YAAY,EACjB,KAAK,YAAY,EAClB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAc,KAAK,cAAc,EAAE,KAAK,KAAK,EAAE,KAAK,mBAAmB,EAAC,MAAM,YAAY,CAAC;AAElG,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,YAAY,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,GAAG,aAAa,CAAC;CAC9B;AAED;;;;;;;GAOG;AACH,qBAAa,eAAe;IAC1B,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IACtB,OAAO,CAAC,OAAO,CAAmC;IAClD,mFAAmF;IACnF,OAAO,CAAC,QAAQ,CAAqE;gBAEzE,KAAK,CAAC,EAAE,KAAK;IAIzB,OAAO,CAAC,MAAM;IAMd;6FACyF;IACzF,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,YAAY;IAI5C;;6DAEyD;IACzD,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC,mBAAmB,EAAE,cAAc,CAAC,GAAG,mBAAmB;IAO7E;;;;;;OAMG;IACG,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,GAAE;QAAC,IAAI,CAAC,EAAE,OAAO,CAAA;KAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IAiDlF;;;;;;;;OAQG;IACH,aAAa,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,GAAE;QAAC,IAAI,CAAC,EAAE,OAAO,CAAA;KAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IAYlF;uCACmC;IACnC,YAAY,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO;IAIvC;;;;;OAKG;IACH,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,cAAc;IAU7C,OAAO,CAAC,KAAK;IAoBb,yCAAyC;IACnC,UAAU,CAAC,IAAI,GAAE;QAAC,IAAI,CAAC,EAAE,OAAO,CAAA;KAAM,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IAQrE,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,YAAY,GAAG,IAAI;IAIjD;;0GAEsG;IACtG,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAItC,YAAY,IAAI,YAAY,EAAE;CAG/B"}
1
+ {"version":3,"file":"indexer.d.ts","sourceRoot":"","sources":["../src/indexer.ts"],"names":[],"mappings":"AAAA,OAAO,EAML,KAAK,OAAO,EACZ,KAAK,sBAAsB,EAC3B,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,KAAK,mBAAmB,EACzB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAC,GAAG,EAAC,MAAM,MAAM,CAAC;AAC9B,OAAO,EAAc,KAAK,cAAc,EAAE,KAAK,KAAK,EAAE,KAAK,mBAAmB,EAAC,MAAM,YAAY,CAAC;AAElG,MAAM,WAAW,cAAc;IAC7B,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;0DAEsD;IACtD,IAAI,CAAC,EAAE,SAAS,GAAG,EAAE,CAAC;IACtB,8DAA8D;IAC9D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;;;;OAOG;IACH,QAAQ,CAAC,EAAE,mBAAmB,CAAC;IAC/B,iGAAiG;IACjG,OAAO,CAAC,EAAE,sBAAsB,CAAC,SAAS,CAAC,CAAC;CAC7C;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,YAAY,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,GAAG,aAAa,CAAC;CAC9B;AAED;;;+BAG+B;AAC/B,eAAO,MAAM,gCAAgC,MAAM,CAAC;AAEpD;;;;;mEAKmE;AACnE,eAAO,MAAM,0BAA0B,QAAa,CAAC;AAErD;;;;;;;GAOG;AACH,qBAAa,eAAe;IAC1B,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IACtB,OAAO,CAAC,OAAO,CAAmC;IAClD,mFAAmF;IACnF,OAAO,CAAC,QAAQ,CAAqE;gBAEzE,KAAK,CAAC,EAAE,KAAK;IAIzB;;;;;;;;;OASG;IACH,OAAO,CAAC,MAAM;IAOd;6FACyF;IACzF,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,YAAY;IAI5C;;6DAEyD;IACzD,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC,mBAAmB,EAAE,cAAc,CAAC,GAAG,mBAAmB;IAO7E;;;;;;OAMG;IACG,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,GAAE,cAAmB,GAAG,OAAO,CAAC,WAAW,CAAC;IA2FhF;;;;;;;;OAQG;IACH,aAAa,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,GAAE,cAAmB,GAAG,OAAO,CAAC,WAAW,CAAC;IAYhF;uCACmC;IACnC,YAAY,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO;IAIvC;;;;;OAKG;IACH,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,cAAc;IAU7C,OAAO,CAAC,KAAK;IAoBb,yCAAyC;IACnC,UAAU,CAAC,IAAI,GAAE,cAAmB,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IAQnE,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,YAAY,GAAG,IAAI;IAIjD;;0GAEsG;IACtG,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAItC,YAAY,IAAI,YAAY,EAAE;IAO9B;;;;;;;;OAQG;IACH,oBAAoB,CAAC,QAAQ,GAAE,MAAyC,GAAG,MAAM;IAIjF;;;;;;;;;;;;;;OAcG;IACH,sBAAsB,CAAC,IAAI,GAAE;QAAC,UAAU,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;KAAM,GAAG;QAAC,IAAI,IAAI,IAAI,CAAA;KAAC;CAiB1H"}
package/dist/indexer.js CHANGED
@@ -1,5 +1,17 @@
1
- import { classifyIndexError, makePublicClient, reconstructIncremental, reconstructProject, } from '@artblocks/abx-sdk';
1
+ import { classifyIndexError, makePublicClient, reconstructFromLogs, reconstructIncremental, reconstructProject, } from '@artblocks/abx-sdk';
2
2
  import { SqliteStore } from './store.js';
3
+ /** Bounded per-pass reclaim for {@link SelfHostIndexer.runIncrementalVacuum} — ~100 pages is ~400KB
4
+ * at SQLite's default 4096-byte page size, cheap enough to run synchronously without a request or a
5
+ * watch tick noticing, while a long-running node with a large freelist still drains it over several
6
+ * passes instead of never. */
7
+ export const DEFAULT_INCREMENTAL_VACUUM_PAGES = 100;
8
+ /** Default cadence for automatic SQLite maintenance (see
9
+ * {@link SelfHostIndexer.startVacuumMaintenance}). Deliberately far coarser than the chain watcher's
10
+ * poll (`ABX_WATCH_INTERVAL_MS`, 12s by default): freed pages accumulate slowly (a reclaim, a
11
+ * dropped projection, a pruned bound artifact), so there is nothing to gain from touching the file
12
+ * every tick — and this is process-internal scheduling, not an operator-facing knob, so it isn't
13
+ * read from the environment the way the watcher's interval is. */
14
+ export const DEFAULT_VACUUM_INTERVAL_MS = 5 * 60_000;
3
15
  /**
4
16
  * The reference indexer (Layer 3). It does one thing well: replay the event
5
17
  * spine from chain into the store. Because every state change rides a standard,
@@ -16,10 +28,21 @@ export class SelfHostIndexer {
16
28
  constructor(store) {
17
29
  this.store = store ?? new SqliteStore();
18
30
  }
19
- client(chainKey) {
20
- let c = this.clients.get(chainKey);
31
+ /**
32
+ * The pooled read client for a chain, or — with `rpcUrl` — one pinned to a SINGLE endpoint.
33
+ *
34
+ * The default (no `rpcUrl`) is a viem `fallback` across every configured endpoint, which fails
35
+ * over on an *error*. It does not fail over on a successful empty answer, which is exactly what an
36
+ * endpoint that has pruned its log history returns for an old block: `[]`, HTTP 200. Pinning one
37
+ * endpoint is how a caller can re-run the same scan against each in turn and find one that holds
38
+ * the history (see the CLI's empty-scan recovery). Pooled per (chain, endpoint) so the pinned
39
+ * clients don't evict the shared one.
40
+ */
41
+ client(chainKey, rpcUrl) {
42
+ const key = rpcUrl ? `${chainKey}|${rpcUrl}` : chainKey;
43
+ let c = this.clients.get(key);
21
44
  if (!c)
22
- this.clients.set(chainKey, (c = makePublicClient({ chainKey })));
45
+ this.clients.set(key, (c = makePublicClient({ chainKey, rpcUrl })));
23
46
  return c;
24
47
  }
25
48
  /** The RPC client for a chain — exposed for reads that aren't a reindex (e.g. deploy-block
@@ -64,15 +87,54 @@ export class SelfHostIndexer {
64
87
  let state;
65
88
  let mode;
66
89
  try {
67
- if (incremental) {
68
- state = await reconstructIncremental(this.client(reg.chainKey), prior, { factory });
90
+ if (incremental && opts.logs !== undefined) {
91
+ if (opts.toBlock === undefined) {
92
+ throw new Error('reindex({logs}) requires toBlock — the inclusive scan head those logs cover');
93
+ }
94
+ state = await reconstructFromLogs(this.client(reg.chainKey, opts.rpcUrl), prior, opts.logs, {
95
+ factory,
96
+ readUriDocuments: opts.readUriDocuments,
97
+ toBlock: opts.toBlock,
98
+ });
99
+ mode = 'incremental';
100
+ }
101
+ else if (incremental) {
102
+ state = await reconstructIncremental(this.client(reg.chainKey, opts.rpcUrl), prior, {
103
+ factory,
104
+ readUriDocuments: opts.readUriDocuments,
105
+ onChunk: opts.onChunk,
106
+ toBlock: opts.blockTag,
107
+ });
69
108
  mode = 'incremental';
70
109
  }
71
110
  else {
72
- state = await reconstructProject(this.client(reg.chainKey), {
111
+ state = await reconstructProject(this.client(reg.chainKey, opts.rpcUrl), {
73
112
  address,
74
113
  fromBlock: BigInt(reg.fromBlock),
75
114
  factory,
115
+ readUriDocuments: opts.readUriDocuments,
116
+ onChunk: opts.onChunk,
117
+ toBlock: opts.blockTag,
118
+ });
119
+ mode = 'full';
120
+ }
121
+ // Self-heal, never loop: an incremental fold that yields FEWER events than what's already
122
+ // stored signals a damaged projection. `eventCount` can only grow with append-only chain
123
+ // history, so a decrease is
124
+ // never legitimate — discard the bad fold before it's written, and repair with exactly ONE
125
+ // full replay from the deploy block. That result is written unconditionally, even in the
126
+ // (pathological) case where it too looks smaller: a full reconstruct from chain is
127
+ // definitionally correct, so there is nothing left to fall back to and no second attempt.
128
+ if (mode === 'incremental' && prior && state.eventCount < prior.eventCount) {
129
+ console.error(`[indexer] ${address}: an incremental fold produced ${state.eventCount} events, fewer than the ` +
130
+ `${prior.eventCount} already stored — discarding it and falling back to one full reconstruct.`);
131
+ state = await reconstructProject(this.client(reg.chainKey, opts.rpcUrl), {
132
+ address,
133
+ fromBlock: BigInt(reg.fromBlock),
134
+ factory,
135
+ readUriDocuments: opts.readUriDocuments,
136
+ onChunk: opts.onChunk,
137
+ toBlock: opts.blockTag,
76
138
  });
77
139
  mode = 'full';
78
140
  }
@@ -88,7 +150,9 @@ export class SelfHostIndexer {
88
150
  });
89
151
  throw err;
90
152
  }
91
- this.store.putProject(state);
153
+ // A full replay is the repair path — it purges + rebuilds the append-only event log so a
154
+ // reorg-replaced event can't survive as a stale row (incremental writes never delete).
155
+ this.store.putProject(state, { fullReplay: mode === 'full' });
92
156
  const now = new Date().toISOString();
93
157
  this.store.setIndexStatus(address, { status: 'live', error: null, attempts: 0, lastAttemptAt: now, lastIndexedAt: now });
94
158
  return { state, elapsedMs: Date.now() - started, mode };
@@ -172,5 +236,53 @@ export class SelfHostIndexer {
172
236
  listProjects() {
173
237
  return this.store.listProjects();
174
238
  }
239
+ // ── SQLite maintenance — the bounded-automatic half; the explicit one-time
240
+ // conversion for a pre-existing store lives on `SqliteStore.vacuumConvert` / `abx vacuum convert`.
241
+ /**
242
+ * Run one bounded `PRAGMA incremental_vacuum` pass, delegating to {@link SqliteStore.runIncrementalVacuum}.
243
+ * A no-op (returns 0) for any `Store` implementation that isn't a `SqliteStore` — vacuuming is a
244
+ * SQLite-specific concern, so a Postgres-backed deploy (which owns its own manual VACUUM story)
245
+ * simply has nothing to do here. Exposed on its own (not just via {@link startVacuumMaintenance})
246
+ * so a caller can also run one pass on demand — e.g. right after `abx vacuum convert`, to reclaim
247
+ * whatever the full VACUUM already didn't (it shouldn't leave anything, but this makes "did it
248
+ * work" independently checkable).
249
+ */
250
+ runIncrementalVacuum(maxPages = DEFAULT_INCREMENTAL_VACUUM_PAGES) {
251
+ return this.store instanceof SqliteStore ? this.store.runIncrementalVacuum(maxPages) : 0;
252
+ }
253
+ /**
254
+ * Start automatic SQLite maintenance: {@link runIncrementalVacuum} on its own
255
+ * timer, decoupled from the chain watcher's poll loop (`packages/token-api/src/watcher.ts`) so a
256
+ * reclaim pass can never sit inline with a request or a watch tick — it runs BETWEEN them, on
257
+ * whatever cadence the caller (or the default) picks, and a slow pass only ever delays the next
258
+ * pass, never a request being served concurrently (`node:sqlite`'s `DatabaseSync` is synchronous,
259
+ * but each pass is bounded — see `SqliteStore.runIncrementalVacuum` — precisely so that's cheap).
260
+ *
261
+ * `abx serve` is the intended caller, started once alongside `startChainWatcher`. Safe to call
262
+ * unconditionally: for a non-`SqliteStore` backend this still returns a working `stop()`, it just
263
+ * schedules calls that are themselves no-ops (see {@link runIncrementalVacuum}).
264
+ *
265
+ * A failed pass is logged and swallowed — maintenance must never be the thing that takes a node
266
+ * down; the freelist simply waits for the next pass.
267
+ */
268
+ startVacuumMaintenance(opts = {}) {
269
+ const intervalMs = opts.intervalMs ?? DEFAULT_VACUUM_INTERVAL_MS;
270
+ const maxPages = opts.maxPages ?? DEFAULT_INCREMENTAL_VACUUM_PAGES;
271
+ const log = opts.log ?? ((line) => console.error(`[maintenance] ${line}`));
272
+ const timer = setInterval(() => {
273
+ try {
274
+ const reclaimed = this.runIncrementalVacuum(maxPages);
275
+ if (reclaimed > 0)
276
+ log(`incremental_vacuum reclaimed ${reclaimed} page(s)`);
277
+ }
278
+ catch (err) {
279
+ log(`incremental_vacuum failed (will retry next pass): ${err.message}`);
280
+ }
281
+ }, intervalMs);
282
+ // Never keeps the process alive on its own — a plain background convenience, not a reason `abx
283
+ // serve` (or a test) would hang waiting for it.
284
+ timer.unref?.();
285
+ return { stop: () => clearInterval(timer) };
286
+ }
175
287
  }
176
288
  //# sourceMappingURL=indexer.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"indexer.js","sourceRoot":"","sources":["../src/indexer.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,sBAAsB,EACtB,kBAAkB,GAInB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAC,WAAW,EAA4D,MAAM,YAAY,CAAC;AAQlG;;;;;;;GAOG;AACH,MAAM,OAAO,eAAe;IACjB,KAAK,CAAQ;IACd,OAAO,GAAG,IAAI,GAAG,EAAwB,CAAC;IAClD,mFAAmF;IAC3E,QAAQ,GAAG,IAAI,GAAG,EAA0D,CAAC;IAErF,YAAY,KAAa;QACvB,IAAI,CAAC,KAAK,GAAG,KAAK,IAAI,IAAI,WAAW,EAAE,CAAC;IAC1C,CAAC;IAEO,MAAM,CAAC,QAAgB;QAC7B,IAAI,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACnC,IAAI,CAAC,CAAC;YAAE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC,GAAG,gBAAgB,CAAC,EAAC,QAAQ,EAAC,CAAC,CAAC,CAAC,CAAC;QACvE,OAAO,CAAC,CAAC;IACX,CAAC;IAED;6FACyF;IACzF,YAAY,CAAC,QAAgB;QAC3B,OAAO,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC/B,CAAC;IAED;;6DAEyD;IACzD,QAAQ,CAAC,GAA8C;QACrD,MAAM,IAAI,GAAwB,EAAC,GAAG,GAAG,EAAE,YAAY,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAC,CAAC;QACnF,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QAC1B,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC;YAAE,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,OAAO,EAAE,EAAC,MAAM,EAAE,QAAQ,EAAC,CAAC,CAAC;QAC1G,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,OAAO,CAAC,OAAgB,EAAE,OAAyB,EAAE;QACzD,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;QAChD,+FAA+F;QAC/F,+FAA+F;QAC/F,IAAI,CAAC,GAAG;YAAE,MAAM,IAAI,KAAK,CAAC,GAAG,OAAO,+DAA+D,OAAO,EAAE,CAAC,CAAC;QAE9G,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC3B,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC,CAAC,CAAE,GAAG,CAAC,OAAmB,CAAC,CAAC,CAAC,SAAS,CAAC;QACnE,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;QAChE,MAAM,WAAW,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,KAAK,CAAC,WAAW,IAAI,KAAK,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAC9E,MAAM,QAAQ,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,EAAE,QAAQ,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;QACzE,4FAA4F;QAC5F,4FAA4F;QAC5F,gDAAgD;QAChD,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,EAAE,EAAC,MAAM,EAAE,aAAa,EAAE,QAAQ,EAAE,aAAa,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAC,CAAC,CAAC;QACjH,CAAC;QAED,IAAI,KAAmB,CAAC;QACxB,IAAI,IAA4B,CAAC;QACjC,IAAI,CAAC;YACH,IAAI,WAAW,EAAE,CAAC;gBAChB,KAAK,GAAG,MAAM,sBAAsB,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,KAAM,EAAE,EAAC,OAAO,EAAC,CAAC,CAAC;gBACnF,IAAI,GAAG,aAAa,CAAC;YACvB,CAAC;iBAAM,CAAC;gBACN,KAAK,GAAG,MAAM,kBAAkB,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE;oBAC1D,OAAO;oBACP,SAAS,EAAE,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC;oBAChC,OAAO;iBACR,CAAC,CAAC;gBACH,IAAI,GAAG,MAAM,CAAC;YAChB,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,8FAA8F;YAC9F,yEAAyE;YACzE,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,EAAE;gBACjC,MAAM,EAAE,QAAQ;gBAChB,KAAK,EAAE,kBAAkB,CAAC,GAAG,CAAC;gBAC9B,QAAQ;gBACR,aAAa,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;aACxC,CAAC,CAAC;YACH,MAAM,GAAG,CAAC;QACZ,CAAC;QACD,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QAC7B,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QACrC,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,EAAE,EAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,EAAE,aAAa,EAAE,GAAG,EAAE,aAAa,EAAE,GAAG,EAAC,CAAC,CAAC;QACvH,OAAO,EAAC,KAAK,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,EAAE,IAAI,EAAC,CAAC;IACxD,CAAC;IAED;;;;;;;;OAQG;IACH,aAAa,CAAC,OAAgB,EAAE,OAAyB,EAAE;QACzD,MAAM,GAAG,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;QAClC,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACvC,IAAI,OAAO,EAAE,CAAC;YACZ,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,OAAO,CAAC,IAAI;gBAAE,OAAO,OAAO,CAAC,OAAO,CAAC;YACvD,gFAAgF;YAChF,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC;YAC/F,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;QACxC,CAAC;QACD,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACnE,CAAC;IAED;uCACmC;IACnC,YAAY,CAAC,OAAgB;QAC3B,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;IAClD,CAAC;IAED;;;;;OAKG;IACH,WAAW,CAAC,OAAgB;QAC1B,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;QAC/C,IAAI,GAAG;YAAE,OAAO,GAAG,CAAC;QACpB,OAAO;YACL,OAAO,EAAE,OAAO,CAAC,WAAW,EAAE;YAC9B,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ;YAC1D,QAAQ,EAAE,CAAC;SACZ,CAAC;IACJ,CAAC;IAEO,KAAK,CAAC,GAAW,EAAE,OAA6B,EAAE,IAAa;QACrE,8FAA8F;QAC9F,2DAA2D;QAC3D,MAAM,MAAM,GAAG,GAAG,EAAE;YAClB,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,OAAO,KAAK,OAAO;gBAAE,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC7E,CAAC,CAAC;QACF,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAC1B,CAAC,CAAC,EAAE,EAAE;YACJ,MAAM,EAAE,CAAC;YACT,OAAO,CAAC,CAAC;QACX,CAAC,EACD,CAAC,CAAC,EAAE,EAAE;YACJ,MAAM,EAAE,CAAC;YACT,MAAM,CAAC,CAAC;QACV,CAAC,CACF,CAAC;QACF,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,EAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAC,CAAC,CAAC;QACjD,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,yCAAyC;IACzC,KAAK,CAAC,UAAU,CAAC,OAAyB,EAAE;QAC1C,MAAM,GAAG,GAAkB,EAAE,CAAC;QAC9B,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,iBAAiB,EAAE,EAAE,CAAC;YACjD,GAAG,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAkB,EAAE,IAAI,CAAC,CAAC,CAAC;QAC7D,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC;IAED,UAAU,CAAC,OAAgB;QACzB,OAAO,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;IACxC,CAAC;IAED;;0GAEsG;IACtG,cAAc,CAAC,OAAgB;QAC7B,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;IACrC,CAAC;IAED,YAAY;QACV,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,EAAE,CAAC;IACnC,CAAC;CACF"}
1
+ {"version":3,"file":"indexer.js","sourceRoot":"","sources":["../src/indexer.ts"],"names":[],"mappings":"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"}