@secondlayer/subgraphs 3.25.1 → 3.26.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/dist/src/index.d.ts +31 -18
- package/dist/src/index.js +32 -12
- package/dist/src/index.js.map +4 -4
- package/dist/src/runtime/block-processor.js +29 -9
- package/dist/src/runtime/block-processor.js.map +3 -3
- package/dist/src/runtime/catchup.js +29 -9
- package/dist/src/runtime/catchup.js.map +3 -3
- package/dist/src/runtime/context.d.ts +20 -0
- package/dist/src/runtime/context.js +29 -9
- package/dist/src/runtime/context.js.map +3 -3
- package/dist/src/runtime/processor.js +33 -14
- package/dist/src/runtime/processor.js.map +5 -5
- package/dist/src/runtime/reindex.d.ts +59 -3
- package/dist/src/runtime/reindex.js +33 -12
- package/dist/src/runtime/reindex.js.map +4 -4
- package/dist/src/runtime/reorg.js +29 -9
- package/dist/src/runtime/reorg.js.map +3 -3
- package/dist/src/runtime/runner.d.ts +20 -0
- package/dist/src/service.js +33 -14
- package/dist/src/service.js.map +5 -5
- package/dist/src/testing/index.js +29 -9
- package/dist/src/testing/index.js.map +3 -3
- package/package.json +1 -1
package/dist/src/index.d.ts
CHANGED
|
@@ -459,9 +459,28 @@ declare function filterFieldsByType(): Array<{
|
|
|
459
459
|
type: string
|
|
460
460
|
fields: string[]
|
|
461
461
|
}>;
|
|
462
|
+
/** A (decoded event type, optional contract scope) pair the sparse probe
|
|
463
|
+
* checks. Contract scoping is what makes token-subgraph reindexes leap over
|
|
464
|
+
* everything that isn't their token. */
|
|
465
|
+
type SparseProbeTarget = {
|
|
466
|
+
eventType: string
|
|
467
|
+
contractId?: string
|
|
468
|
+
};
|
|
469
|
+
/** Sparse scanning is sound only when EVERY source is an event-type filter —
|
|
470
|
+
* a contract_call/contract_deploy source matches transactions, which the
|
|
471
|
+
* event probe can't see. */
|
|
472
|
+
declare function canSparseScan(subgraph: SubgraphDefinition): boolean;
|
|
473
|
+
/** Probe targets for a subgraph's filters: decoded type + contract scope when\\n* the filter pins one (assetIdentifier "SP….contract::asset" or contractId). */
|
|
474
|
+
declare function sparseProbeTargets(subgraph: SubgraphDefinition): SparseProbeTarget[];
|
|
462
475
|
interface ReindexOptions {
|
|
463
|
-
|
|
464
|
-
|
|
476
|
+
/**
|
|
477
|
+
* Policy floor on the walk's first block — NOT a caller-supplied range.
|
|
478
|
+
* Free-tier accounts may not reindex below their registered `start_block`
|
|
479
|
+
* (see `resolveGenesisPolicy` on the API side); this raises the walk start
|
|
480
|
+
* and can never lower it. There is deliberately no `toBlock` counterpart:
|
|
481
|
+
* a reindex always runs to chain tip. See {@link resolveBlockRange}.
|
|
482
|
+
*/
|
|
483
|
+
startBlockFloor?: number;
|
|
465
484
|
schemaName?: string;
|
|
466
485
|
/** Op row to receive processed_events on each progress flush. */
|
|
467
486
|
operationId?: string;
|
|
@@ -470,6 +489,13 @@ interface ReindexOptions {
|
|
|
470
489
|
/**
|
|
471
490
|
* Reindex a subgraph by dropping its tables, recreating them, and reprocessing
|
|
472
491
|
* all historical blocks through the handler pipeline.
|
|
492
|
+
*
|
|
493
|
+
* Always whole-subgraph: `[start_block, chain tip]`. There is no ranged
|
|
494
|
+
* reindex — the drop cannot be scoped to a range without re-running delta
|
|
495
|
+
* handlers (`ctx.increment` / `ctx.update` / `ctx.patchOrInsert`) over rows
|
|
496
|
+
* that were never removed, which is the exact double-count hazard `backfill`
|
|
497
|
+
* already refuses. Use `backfillSubgraph` for ranged, additive work.
|
|
498
|
+
*
|
|
473
499
|
* Supports cancellation via AbortSignal — on shutdown abort, status stays
|
|
474
500
|
* "reindexing" for auto-resume; on user cancel, status resets to "active".
|
|
475
501
|
*/
|
|
@@ -1076,10 +1102,10 @@ declare function generateIndexSchema(target: IndexCodegenTarget, opts?: IndexCod
|
|
|
1076
1102
|
/** Index tables available to codegen, for help text and validation. */
|
|
1077
1103
|
declare const INDEX_CODEGEN_TABLES: readonly string[];
|
|
1078
1104
|
import { pgSchemaName } from "@secondlayer/shared/db/queries/subgraphs";
|
|
1079
|
-
import { Database as
|
|
1105
|
+
import { Database as Database3 } from "@secondlayer/shared/db";
|
|
1080
1106
|
import { ByoBreakingChangeDetails } from "@secondlayer/shared/errors";
|
|
1081
|
-
import { Kysely as
|
|
1082
|
-
type AnyDb =
|
|
1107
|
+
import { Kysely as Kysely3 } from "kysely";
|
|
1108
|
+
type AnyDb = Kysely3<Database3>;
|
|
1083
1109
|
interface TableDiff {
|
|
1084
1110
|
/** Tables added to the schema */
|
|
1085
1111
|
addedTables: string[];
|
|
@@ -1200,17 +1226,4 @@ declare function deploySchema(db: AnyDb, def: SubgraphDefinition, handlerPath: s
|
|
|
1200
1226
|
/** Non-fatal caveats the caller should surface (e.g. handler grafts at tip). */
|
|
1201
1227
|
warnings?: string[]
|
|
1202
1228
|
}>;
|
|
1203
|
-
/** A (decoded event type, optional contract scope) pair the sparse probe
|
|
1204
|
-
* checks. Contract scoping is what makes token-subgraph reindexes leap over
|
|
1205
|
-
* everything that isn't their token. */
|
|
1206
|
-
type SparseProbeTarget = {
|
|
1207
|
-
eventType: string
|
|
1208
|
-
contractId?: string
|
|
1209
|
-
};
|
|
1210
|
-
/** Sparse scanning is sound only when EVERY source is an event-type filter —
|
|
1211
|
-
* a contract_call/contract_deploy source matches transactions, which the
|
|
1212
|
-
* event probe can't see. */
|
|
1213
|
-
declare function canSparseScan(subgraph: SubgraphDefinition): boolean;
|
|
1214
|
-
/** Probe targets for a subgraph's filters: decoded type + contract scope when\\n* the filter pins one (assetIdentifier "SP….contract::asset" or contractId). */
|
|
1215
|
-
declare function sparseProbeTargets(subgraph: SubgraphDefinition): SparseProbeTarget[];
|
|
1216
1229
|
export { validateSubgraphDefinition, validatePrintPayload, sparseProbeTargets, resumeReindex, renderDeployPlan, reindexSubgraph, readContractAt, pgSchemaName, inferPrintTopics, hasBreakingChanges, generateSubgraphSQL, generatePrismaSchema, generateKyselySchema, generateIndexSchema, generateDrizzleSchema, filterFieldsByType, diffSchema, deploySchema, defineSubgraph, defineSchema, canSparseScan, camelizeDataKey, backfillSubgraph, WriteRow, WhereInput, TypedSubgraphDefinition, TypedSubgraphContext, TypedHandlers, TxMeta, TableDiff, SystemRow, SubscribeOptions, SubgraphTableClient, SubgraphTable, SubgraphSchema, SubgraphHandler, SubgraphFilter, SubgraphDefinition, SubgraphContext, SubgraphColumn, StxTransferPayload, StxTransferFilter, StxMintPayload, StxMintFilter, StxLockPayload, StxLockFilter, StxBurnPayload, StxBurnFilter, SparseProbeTarget, RowValue, ReindexOptions, PrismaGenOptions, PrintValidationResult, PrintSample, PrintFieldToTS, PrintField, PrintEventPayload, PrintEventFor, PrintEventFilter, PrintDataOf, NftTransferPayload, NftTransferFilter, NftMintPayload, NftMintFilter, NftBurnPayload, NftBurnFilter, KyselyGenOptions, InferredTopicSchema, InferredPrintField, InferTableRow, InferSubgraphClient, InferContext, InferColumnType, IndexCodegenTarget, IndexCodegenOptions, INDEX_CODEGEN_TABLES, GeneratedSQL, FtTransferPayload, FtTransferFilter, FtMintPayload, FtMintFilter, FtBurnPayload, FtBurnFilter, FindManyOptions, FactoryScope, EventForFilter, ErasedChainReadClient, DrizzleGenOptions, DeployPlan, DeployDiff, ContractDeployPayload, ContractDeployFilter, ContractCallPayload, ContractCallFilter, ContractCallEvent, ComputedValue, ComparisonFilter, ColumnType, ColumnToTS, ColumnDiff, ChainReadOptions, ChainReadMethods, ChainReadError, ChainReadClient, ChainReadCacheMode, ByoMigrationPlan, ByoBreakingChangeError, AnyEvent, AggregateSpec, AggregateResult };
|
package/dist/src/index.js
CHANGED
|
@@ -820,14 +820,10 @@ class SubgraphContext {
|
|
|
820
820
|
this.ops.length = 0;
|
|
821
821
|
const statements = this.buildStatements(opsToFlush);
|
|
822
822
|
if ("isTransaction" in this.db) {
|
|
823
|
-
|
|
824
|
-
await sql.raw(stmt).execute(this.db);
|
|
825
|
-
}
|
|
823
|
+
await this.execStatements(this.db, statements);
|
|
826
824
|
} else {
|
|
827
825
|
await this.db.transaction().execute(async (tx) => {
|
|
828
|
-
|
|
829
|
-
await sql.raw(stmt).execute(tx);
|
|
830
|
-
}
|
|
826
|
+
await this.execStatements(tx, statements);
|
|
831
827
|
});
|
|
832
828
|
}
|
|
833
829
|
const writes = opsToFlush.map((op, rowIndex) => {
|
|
@@ -846,6 +842,25 @@ class SubgraphContext {
|
|
|
846
842
|
});
|
|
847
843
|
return { count: opsToFlush.length, writes };
|
|
848
844
|
}
|
|
845
|
+
async execStatements(executor, statements) {
|
|
846
|
+
const affected = (r) => r.numAffectedRows ?? 0n;
|
|
847
|
+
for (const stmt of statements) {
|
|
848
|
+
if (typeof stmt === "string") {
|
|
849
|
+
await sql.raw(stmt).execute(executor);
|
|
850
|
+
continue;
|
|
851
|
+
}
|
|
852
|
+
const updated = await sql.raw(stmt.update).execute(executor);
|
|
853
|
+
if (affected(updated) > 0n)
|
|
854
|
+
continue;
|
|
855
|
+
const inserted = await sql.raw(stmt.insert).execute(executor);
|
|
856
|
+
if (affected(inserted) > 0n)
|
|
857
|
+
continue;
|
|
858
|
+
const retried = await sql.raw(stmt.update).execute(executor);
|
|
859
|
+
if (affected(retried) === 0n) {
|
|
860
|
+
throw new Error(`increment could not be applied to ${this.pgSchemaName}.${stmt.table} where ${stmt.keyPred}: row neither updated nor inserted`);
|
|
861
|
+
}
|
|
862
|
+
}
|
|
863
|
+
}
|
|
849
864
|
prepareInsert(op) {
|
|
850
865
|
const upsertKeys = op.data._upsert_keys;
|
|
851
866
|
const data = { ...op.data };
|
|
@@ -925,7 +940,6 @@ class SubgraphContext {
|
|
|
925
940
|
for (const r of batch.rows.values()) {
|
|
926
941
|
const keyPred = batch.keyCols.map((k) => `"${k}" = ${escapeLiteral(r.keys[k])}`).join(" AND ");
|
|
927
942
|
const updSet = batch.deltaCols.map((c) => `"${c}" = COALESCE("${c}", 0) + (${String(r.deltas[c] ?? 0n)})`).join(", ");
|
|
928
|
-
statements.push(`UPDATE ${qualifiedTable} SET ${updSet} WHERE ${keyPred}`);
|
|
929
943
|
const insertVals = [
|
|
930
944
|
...batch.keyCols.map((k) => escapeLiteral(r.keys[k])),
|
|
931
945
|
...batch.deltaCols.map((c) => String(r.deltas[c] ?? 0n)),
|
|
@@ -933,7 +947,13 @@ class SubgraphContext {
|
|
|
933
947
|
escapeLiteral(r.meta.txId),
|
|
934
948
|
"NOW()"
|
|
935
949
|
];
|
|
936
|
-
statements.push(
|
|
950
|
+
statements.push({
|
|
951
|
+
kind: "increment",
|
|
952
|
+
table: batch.table,
|
|
953
|
+
keyPred,
|
|
954
|
+
update: `UPDATE ${qualifiedTable} SET ${updSet} WHERE ${keyPred}`,
|
|
955
|
+
insert: `INSERT INTO ${qualifiedTable} (${cols.map((c) => `"${c}"`).join(", ")}) ` + `SELECT ${insertVals.join(", ")} ` + `WHERE NOT EXISTS (SELECT 1 FROM ${qualifiedTable} WHERE ${keyPred})`
|
|
956
|
+
});
|
|
937
957
|
}
|
|
938
958
|
incBatch = null;
|
|
939
959
|
incBatchKey = "";
|
|
@@ -3568,9 +3588,9 @@ async function processBlockRange(def, opts) {
|
|
|
3568
3588
|
return { blocksProcessed, totalEventsProcessed, totalErrors, aborted };
|
|
3569
3589
|
}
|
|
3570
3590
|
async function resolveBlockRange(source, def, opts) {
|
|
3571
|
-
const
|
|
3572
|
-
const
|
|
3573
|
-
return { fromBlock, toBlock };
|
|
3591
|
+
const definitionStart = def.startBlock ?? 1;
|
|
3592
|
+
const fromBlock = opts?.startBlockFloor != null ? Math.max(definitionStart, opts.startBlockFloor) : definitionStart;
|
|
3593
|
+
return { fromBlock, toBlock: await source.getTip() };
|
|
3574
3594
|
}
|
|
3575
3595
|
async function clearReindexMetadata(db, subgraphName) {
|
|
3576
3596
|
await db.updateTable("subgraphs").set({ reindex_from_block: null, reindex_to_block: null }).where("name", "=", subgraphName).execute();
|
|
@@ -5086,5 +5106,5 @@ export {
|
|
|
5086
5106
|
ByoBreakingChangeError
|
|
5087
5107
|
};
|
|
5088
5108
|
|
|
5089
|
-
//# debugId=
|
|
5109
|
+
//# debugId=7F2918CDE1AF5BC064756E2164756E21
|
|
5090
5110
|
//# sourceMappingURL=index.js.map
|