@secondlayer/subgraphs 3.20.0 → 3.22.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.
- package/dist/src/index.d.ts +188 -16
- package/dist/src/index.js +369 -41
- package/dist/src/index.js.map +12 -11
- package/dist/src/runtime/block-processor.d.ts +100 -13
- package/dist/src/runtime/block-processor.js +208 -22
- package/dist/src/runtime/block-processor.js.map +9 -8
- package/dist/src/runtime/catchup.d.ts +100 -13
- package/dist/src/runtime/catchup.js +208 -22
- package/dist/src/runtime/catchup.js.map +9 -8
- package/dist/src/runtime/context.d.ts +34 -8
- package/dist/src/runtime/context.js +25 -12
- package/dist/src/runtime/context.js.map +4 -4
- package/dist/src/runtime/processor.js +213 -22
- package/dist/src/runtime/processor.js.map +10 -9
- package/dist/src/runtime/reindex.d.ts +100 -13
- package/dist/src/runtime/reindex.js +208 -22
- package/dist/src/runtime/reindex.js.map +9 -8
- package/dist/src/runtime/reorg.d.ts +100 -13
- package/dist/src/runtime/reorg.js +213 -22
- package/dist/src/runtime/reorg.js.map +10 -9
- package/dist/src/runtime/replay.js +29 -6
- package/dist/src/runtime/replay.js.map +3 -3
- package/dist/src/runtime/runner.d.ts +125 -17
- package/dist/src/runtime/runner.js +100 -3
- package/dist/src/runtime/runner.js.map +5 -4
- package/dist/src/runtime/source-matcher.d.ts +98 -11
- package/dist/src/runtime/source-matcher.js +30 -6
- package/dist/src/runtime/source-matcher.js.map +3 -3
- package/dist/src/schema/index.d.ts +100 -13
- package/dist/src/schema/index.js +171 -20
- package/dist/src/schema/index.js.map +5 -5
- package/dist/src/service.js +213 -22
- package/dist/src/service.js.map +10 -9
- package/dist/src/testing/index.d.ts +620 -0
- package/dist/src/testing/index.js +1297 -0
- package/dist/src/testing/index.js.map +16 -0
- package/dist/src/triggers/index.d.ts +87 -9
- package/dist/src/types.d.ts +101 -14
- package/dist/src/validate.d.ts +136 -14
- package/dist/src/validate.js +158 -19
- package/dist/src/validate.js.map +3 -3
- package/package.json +7 -5
|
@@ -100,6 +100,18 @@ function emitJournalDDL(schemaName) {
|
|
|
100
100
|
`CREATE INDEX IF NOT EXISTS idx_${schemaName}_journal_height ON ${schemaName}._journal (block_height)`
|
|
101
101
|
];
|
|
102
102
|
}
|
|
103
|
+
function emitFactoryDDL(schemaName) {
|
|
104
|
+
return [
|
|
105
|
+
`CREATE TABLE IF NOT EXISTS ${schemaName}._factory_addresses (
|
|
106
|
+
source_name TEXT NOT NULL,
|
|
107
|
+
address TEXT NOT NULL,
|
|
108
|
+
block_height BIGINT NOT NULL,
|
|
109
|
+
_created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
110
|
+
PRIMARY KEY (source_name, address)
|
|
111
|
+
)`,
|
|
112
|
+
`CREATE INDEX IF NOT EXISTS idx_${schemaName}_factory_height ON ${schemaName}._factory_addresses (block_height)`
|
|
113
|
+
];
|
|
114
|
+
}
|
|
103
115
|
function emitForeignKeyDDL(schemaName, tableName, tableDef) {
|
|
104
116
|
return (tableDef.relations ?? []).map((rel) => {
|
|
105
117
|
const constraintName = `fk_${schemaName}_${tableName}_${rel.name}`;
|
|
@@ -118,6 +130,9 @@ function generateSubgraphSQL(def, schemaNameOverride) {
|
|
|
118
130
|
statements.push(...emitTableDDL(schemaName, tableName, tableDef));
|
|
119
131
|
}
|
|
120
132
|
statements.push(...emitJournalDDL(schemaName));
|
|
133
|
+
if (Object.values(def.sources ?? {}).some((src) => src.factory !== undefined)) {
|
|
134
|
+
statements.push(...emitFactoryDDL(schemaName));
|
|
135
|
+
}
|
|
121
136
|
for (const [tableName, tableDef] of Object.entries(def.schema)) {
|
|
122
137
|
statements.push(...emitForeignKeyDDL(schemaName, tableName, tableDef));
|
|
123
138
|
}
|
|
@@ -262,23 +277,21 @@ class SubgraphContext {
|
|
|
262
277
|
formatUnits(value, decimals) {
|
|
263
278
|
return formatUnits(value, decimals);
|
|
264
279
|
}
|
|
265
|
-
async
|
|
266
|
-
this.validateTable(table);
|
|
280
|
+
async readRows(table, where, limit) {
|
|
267
281
|
const qualifiedTable = `"${this.pgSchemaName}"."${table}"`;
|
|
268
282
|
const { clause } = buildWhereClause(where);
|
|
269
|
-
const query = `SELECT * FROM ${qualifiedTable} WHERE ${clause} LIMIT
|
|
283
|
+
const query = `SELECT * FROM ${qualifiedTable} WHERE ${clause}${limit !== undefined ? ` LIMIT ${limit}` : ""}`;
|
|
270
284
|
const { rows } = await sql.raw(query).execute(this.db);
|
|
271
|
-
|
|
272
|
-
|
|
285
|
+
return rows.map((r) => this.coerceRow(table, r));
|
|
286
|
+
}
|
|
287
|
+
async findOne(table, where) {
|
|
288
|
+
this.validateTable(table);
|
|
289
|
+
const row = (await this.readRows(table, where, 1))[0] ?? null;
|
|
290
|
+
return this.overlayOne(table, where, row);
|
|
273
291
|
}
|
|
274
292
|
async findMany(table, where) {
|
|
275
293
|
this.validateTable(table);
|
|
276
|
-
|
|
277
|
-
const { clause } = buildWhereClause(where);
|
|
278
|
-
const query = `SELECT * FROM ${qualifiedTable} WHERE ${clause}`;
|
|
279
|
-
const { rows } = await sql.raw(query).execute(this.db);
|
|
280
|
-
const dbRows = rows.map((r) => this.coerceRow(table, r));
|
|
281
|
-
return this.overlayMany(table, where, dbRows);
|
|
294
|
+
return this.overlayMany(table, where, await this.readRows(table, where));
|
|
282
295
|
}
|
|
283
296
|
overlayOne(table, where, dbRow) {
|
|
284
297
|
if (this.ops.length === 0)
|
|
@@ -758,6 +771,87 @@ import {
|
|
|
758
771
|
deserializeCV as deserializeCV2,
|
|
759
772
|
toCamelCase
|
|
760
773
|
} from "@secondlayer/stacks/clarity";
|
|
774
|
+
|
|
775
|
+
// src/runtime/print-validate.ts
|
|
776
|
+
var COLUMN_TYPES = new Set([
|
|
777
|
+
"text",
|
|
778
|
+
"uint",
|
|
779
|
+
"int",
|
|
780
|
+
"principal",
|
|
781
|
+
"boolean",
|
|
782
|
+
"timestamp",
|
|
783
|
+
"jsonb"
|
|
784
|
+
]);
|
|
785
|
+
function isColumnType(field) {
|
|
786
|
+
return typeof field === "string" && COLUMN_TYPES.has(field);
|
|
787
|
+
}
|
|
788
|
+
function matchesField(field, value) {
|
|
789
|
+
if (isColumnType(field)) {
|
|
790
|
+
switch (field) {
|
|
791
|
+
case "uint":
|
|
792
|
+
case "int":
|
|
793
|
+
return typeof value === "bigint" || typeof value === "number";
|
|
794
|
+
case "boolean":
|
|
795
|
+
return typeof value === "boolean";
|
|
796
|
+
case "text":
|
|
797
|
+
case "principal":
|
|
798
|
+
case "timestamp":
|
|
799
|
+
return typeof value === "string" || typeof value === "number" || typeof value === "bigint";
|
|
800
|
+
case "jsonb":
|
|
801
|
+
return value !== undefined;
|
|
802
|
+
}
|
|
803
|
+
}
|
|
804
|
+
if (typeof field !== "object" || field === null)
|
|
805
|
+
return false;
|
|
806
|
+
if ("optional" in field) {
|
|
807
|
+
return value === undefined || value === null || matchesField(field.type, value);
|
|
808
|
+
}
|
|
809
|
+
if ("tuple" in field) {
|
|
810
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
811
|
+
return false;
|
|
812
|
+
}
|
|
813
|
+
return matchesTopic(field.tuple, value).ok;
|
|
814
|
+
}
|
|
815
|
+
if ("list" in field) {
|
|
816
|
+
return Array.isArray(value) && value.every((item) => matchesField(field.list, item));
|
|
817
|
+
}
|
|
818
|
+
return false;
|
|
819
|
+
}
|
|
820
|
+
function matchesTopic(declared, data) {
|
|
821
|
+
for (const [name, field] of Object.entries(declared)) {
|
|
822
|
+
const present = name in data;
|
|
823
|
+
const optional = typeof field === "object" && field !== null && "optional" in field;
|
|
824
|
+
if (!present) {
|
|
825
|
+
if (optional)
|
|
826
|
+
continue;
|
|
827
|
+
return { ok: false, reason: `missing declared field "${name}"` };
|
|
828
|
+
}
|
|
829
|
+
if (!matchesField(field, data[name])) {
|
|
830
|
+
return {
|
|
831
|
+
ok: false,
|
|
832
|
+
reason: `field "${name}" does not match its declared type (got ${describe(data[name])})`
|
|
833
|
+
};
|
|
834
|
+
}
|
|
835
|
+
}
|
|
836
|
+
return { ok: true };
|
|
837
|
+
}
|
|
838
|
+
function describe(value) {
|
|
839
|
+
if (value === null)
|
|
840
|
+
return "null";
|
|
841
|
+
if (Array.isArray(value))
|
|
842
|
+
return "array";
|
|
843
|
+
return typeof value;
|
|
844
|
+
}
|
|
845
|
+
function validatePrintPayload(prints, topic, data) {
|
|
846
|
+
if (!prints)
|
|
847
|
+
return { ok: true };
|
|
848
|
+
const declared = prints[topic];
|
|
849
|
+
if (!declared)
|
|
850
|
+
return { ok: true };
|
|
851
|
+
return matchesTopic(declared, data);
|
|
852
|
+
}
|
|
853
|
+
|
|
854
|
+
// src/runtime/runner.ts
|
|
761
855
|
var DEFAULT_ERROR_THRESHOLD = 50;
|
|
762
856
|
function camelCase(str) {
|
|
763
857
|
return str.replace(/-([a-z0-9])/g, (_, c) => c.toUpperCase());
|
|
@@ -1002,6 +1096,7 @@ function buildEventPayload(filter, tx, event) {
|
|
|
1002
1096
|
async function runHandlers(subgraph, matched, ctx, opts) {
|
|
1003
1097
|
let processed = 0;
|
|
1004
1098
|
let errors = 0;
|
|
1099
|
+
let skipped = 0;
|
|
1005
1100
|
const threshold = opts?.errorThreshold ?? DEFAULT_ERROR_THRESHOLD;
|
|
1006
1101
|
const filterLookup = new Map;
|
|
1007
1102
|
if (!Array.isArray(subgraph.sources)) {
|
|
@@ -1026,7 +1121,7 @@ async function runHandlers(subgraph, matched, ctx, opts) {
|
|
|
1026
1121
|
errors,
|
|
1027
1122
|
threshold
|
|
1028
1123
|
});
|
|
1029
|
-
return { processed, errors };
|
|
1124
|
+
return { processed, errors, ...skipped > 0 ? { skipped } : {} };
|
|
1030
1125
|
}
|
|
1031
1126
|
const handler = subgraph.handlers[sourceName] ?? subgraph.handlers["*"] ?? null;
|
|
1032
1127
|
if (!handler) {
|
|
@@ -1082,6 +1177,21 @@ async function runHandlers(subgraph, matched, ctx, opts) {
|
|
|
1082
1177
|
if (event !== null && filter?.type === "print_event" && filter.topic && payload.topic !== filter.topic) {
|
|
1083
1178
|
continue;
|
|
1084
1179
|
}
|
|
1180
|
+
if (event !== null && filter?.type === "print_event" && filter.prints) {
|
|
1181
|
+
const printPayload = payload;
|
|
1182
|
+
const verdict = validatePrintPayload(filter.prints, printPayload.topic ?? "", printPayload.data ?? {});
|
|
1183
|
+
if (!verdict.ok) {
|
|
1184
|
+
skipped++;
|
|
1185
|
+
logger2.warn("Print payload does not match declared prints schema", {
|
|
1186
|
+
subgraph: subgraph.name,
|
|
1187
|
+
sourceName,
|
|
1188
|
+
topic: printPayload.topic,
|
|
1189
|
+
txId: tx.tx_id,
|
|
1190
|
+
reason: verdict.reason
|
|
1191
|
+
});
|
|
1192
|
+
continue;
|
|
1193
|
+
}
|
|
1194
|
+
}
|
|
1085
1195
|
await handler(payload, ctx);
|
|
1086
1196
|
processed++;
|
|
1087
1197
|
} catch (err) {
|
|
@@ -1096,11 +1206,14 @@ async function runHandlers(subgraph, matched, ctx, opts) {
|
|
|
1096
1206
|
});
|
|
1097
1207
|
}
|
|
1098
1208
|
}
|
|
1099
|
-
return { processed, errors };
|
|
1209
|
+
return { processed, errors, ...skipped > 0 ? { skipped } : {} };
|
|
1100
1210
|
}
|
|
1101
1211
|
|
|
1102
1212
|
// src/runtime/source-matcher.ts
|
|
1103
1213
|
var patternCache = new Map;
|
|
1214
|
+
function matchAny(value, pattern) {
|
|
1215
|
+
return Array.isArray(pattern) ? pattern.some((p) => matchPattern(value, p)) : matchPattern(value, pattern);
|
|
1216
|
+
}
|
|
1104
1217
|
function matchPattern(value, pattern) {
|
|
1105
1218
|
if (!pattern.includes("*"))
|
|
1106
1219
|
return value === pattern;
|
|
@@ -1113,6 +1226,22 @@ function matchPattern(value, pattern) {
|
|
|
1113
1226
|
return re.test(value);
|
|
1114
1227
|
}
|
|
1115
1228
|
var EMPTY_SET = new Set;
|
|
1229
|
+
function factoryAllows(filter, contractId, factoryContracts) {
|
|
1230
|
+
if (!filter.factory)
|
|
1231
|
+
return true;
|
|
1232
|
+
if (!contractId)
|
|
1233
|
+
return false;
|
|
1234
|
+
return (factoryContracts.get(filter.factory.from) ?? EMPTY_SET).has(contractId);
|
|
1235
|
+
}
|
|
1236
|
+
function readPath(payload, path) {
|
|
1237
|
+
let cur = payload;
|
|
1238
|
+
for (const key of path.split(".")) {
|
|
1239
|
+
if (cur === null || typeof cur !== "object")
|
|
1240
|
+
return;
|
|
1241
|
+
cur = cur[key];
|
|
1242
|
+
}
|
|
1243
|
+
return cur;
|
|
1244
|
+
}
|
|
1116
1245
|
function traitAllows(filter, contractId, traitContracts) {
|
|
1117
1246
|
const trait = filter.trait;
|
|
1118
1247
|
if (!trait)
|
|
@@ -1124,7 +1253,7 @@ function traitAllows(filter, contractId, traitContracts) {
|
|
|
1124
1253
|
function assetContract(assetId) {
|
|
1125
1254
|
return assetId?.split("::")[0];
|
|
1126
1255
|
}
|
|
1127
|
-
function matchFilter(filter, transactions, eventsByTx, traitContracts) {
|
|
1256
|
+
function matchFilter(filter, transactions, eventsByTx, traitContracts, factoryContracts = new Map) {
|
|
1128
1257
|
const results = [];
|
|
1129
1258
|
switch (filter.type) {
|
|
1130
1259
|
case "stx_transfer":
|
|
@@ -1251,9 +1380,11 @@ function matchFilter(filter, transactions, eventsByTx, traitContracts) {
|
|
|
1251
1380
|
if (tx.type !== "contract_call")
|
|
1252
1381
|
continue;
|
|
1253
1382
|
if (filter.contractId) {
|
|
1254
|
-
if (!tx.contract_id || !
|
|
1383
|
+
if (!tx.contract_id || !matchAny(tx.contract_id, filter.contractId))
|
|
1255
1384
|
continue;
|
|
1256
1385
|
}
|
|
1386
|
+
if (!factoryAllows(filter, tx.contract_id, factoryContracts))
|
|
1387
|
+
continue;
|
|
1257
1388
|
if (filter.functionName) {
|
|
1258
1389
|
if (!tx.function_name || !matchPattern(tx.function_name, filter.functionName))
|
|
1259
1390
|
continue;
|
|
@@ -1300,11 +1431,13 @@ function matchFilter(filter, transactions, eventsByTx, traitContracts) {
|
|
|
1300
1431
|
return false;
|
|
1301
1432
|
const printContractId = data.contract_identifier ?? data.contract_id;
|
|
1302
1433
|
if (filter.contractId) {
|
|
1303
|
-
if (!printContractId || !
|
|
1434
|
+
if (!printContractId || !matchAny(printContractId, filter.contractId))
|
|
1304
1435
|
return false;
|
|
1305
1436
|
}
|
|
1306
1437
|
if (!traitAllows(filter, printContractId, traitContracts))
|
|
1307
1438
|
return false;
|
|
1439
|
+
if (!factoryAllows(filter, printContractId, factoryContracts))
|
|
1440
|
+
return false;
|
|
1308
1441
|
return true;
|
|
1309
1442
|
});
|
|
1310
1443
|
if (matched.length > 0) {
|
|
@@ -1316,7 +1449,7 @@ function matchFilter(filter, transactions, eventsByTx, traitContracts) {
|
|
|
1316
1449
|
}
|
|
1317
1450
|
return results;
|
|
1318
1451
|
}
|
|
1319
|
-
function matchSources(sources, transactions, events, traitContracts = new Map) {
|
|
1452
|
+
function matchSources(sources, transactions, events, traitContracts = new Map, factoryContracts = new Map) {
|
|
1320
1453
|
const eventsByTx = new Map;
|
|
1321
1454
|
for (const event of events) {
|
|
1322
1455
|
const list = eventsByTx.get(event.tx_id) ?? [];
|
|
@@ -1326,7 +1459,7 @@ function matchSources(sources, transactions, events, traitContracts = new Map) {
|
|
|
1326
1459
|
const seen = new Set;
|
|
1327
1460
|
const results = [];
|
|
1328
1461
|
for (const [sourceName, filter] of Object.entries(sources)) {
|
|
1329
|
-
const matches = matchFilter(filter, transactions, eventsByTx, traitContracts);
|
|
1462
|
+
const matches = matchFilter(filter, transactions, eventsByTx, traitContracts, factoryContracts);
|
|
1330
1463
|
for (const match of matches) {
|
|
1331
1464
|
const dedupeKey = `${match.tx.tx_id}:${sourceName}`;
|
|
1332
1465
|
if (!seen.has(dedupeKey)) {
|
|
@@ -1981,6 +2114,57 @@ async function resolveRoute(subgraphName, targetDb) {
|
|
|
1981
2114
|
function invalidateSubgraphRoute(subgraphName) {
|
|
1982
2115
|
routeCache.delete(subgraphName);
|
|
1983
2116
|
}
|
|
2117
|
+
async function resolveFactoryContracts(subgraph, blockHeight, schemaName, db, txs, evts) {
|
|
2118
|
+
const factories = new Map;
|
|
2119
|
+
for (const source of Object.values(subgraph.sources)) {
|
|
2120
|
+
const factory = source.factory;
|
|
2121
|
+
if (factory)
|
|
2122
|
+
factories.set(factory.from, factory);
|
|
2123
|
+
}
|
|
2124
|
+
const resolved = new Map;
|
|
2125
|
+
const discovered = [];
|
|
2126
|
+
if (factories.size === 0)
|
|
2127
|
+
return { resolved, discovered };
|
|
2128
|
+
for (const [discoveringSource, factory] of factories) {
|
|
2129
|
+
const known = new Set;
|
|
2130
|
+
try {
|
|
2131
|
+
const rows = await sql3`
|
|
2132
|
+
SELECT address FROM ${sql3.raw(`"${schemaName}"."_factory_addresses"`)}
|
|
2133
|
+
WHERE source_name = ${discoveringSource} AND block_height <= ${blockHeight}
|
|
2134
|
+
`.execute(db);
|
|
2135
|
+
for (const row of rows.rows)
|
|
2136
|
+
known.add(row.address);
|
|
2137
|
+
} catch {}
|
|
2138
|
+
const discovering = subgraph.sources[factory.from];
|
|
2139
|
+
if (discovering) {
|
|
2140
|
+
const matches = matchSources({ [factory.from]: discovering }, txs, evts, new Map, new Map);
|
|
2141
|
+
for (const match of matches) {
|
|
2142
|
+
for (const event of match.events ?? []) {
|
|
2143
|
+
const payload = buildEventPayload(discovering, match.tx, event);
|
|
2144
|
+
const value = readPath(payload, factory.field);
|
|
2145
|
+
if (typeof value === "string" && value.length > 0 && !known.has(value)) {
|
|
2146
|
+
known.add(value);
|
|
2147
|
+
discovered.push({ sourceName: discoveringSource, address: value });
|
|
2148
|
+
}
|
|
2149
|
+
}
|
|
2150
|
+
}
|
|
2151
|
+
}
|
|
2152
|
+
resolved.set(discoveringSource, known);
|
|
2153
|
+
}
|
|
2154
|
+
return { resolved, discovered };
|
|
2155
|
+
}
|
|
2156
|
+
async function persistFactoryDiscoveries(schemaName, db, blockHeight, discovered) {
|
|
2157
|
+
if (discovered.length === 0)
|
|
2158
|
+
return;
|
|
2159
|
+
for (const { sourceName, address } of discovered) {
|
|
2160
|
+
await sql3`
|
|
2161
|
+
INSERT INTO ${sql3.raw(`"${schemaName}"."_factory_addresses"`)}
|
|
2162
|
+
(source_name, address, block_height)
|
|
2163
|
+
VALUES (${sourceName}, ${address}, ${blockHeight})
|
|
2164
|
+
ON CONFLICT (source_name, address) DO NOTHING
|
|
2165
|
+
`.execute(db);
|
|
2166
|
+
}
|
|
2167
|
+
}
|
|
1984
2168
|
async function resolveTraitContracts(subgraph, blockHeight, db) {
|
|
1985
2169
|
const traits = new Set;
|
|
1986
2170
|
for (const source of Object.values(subgraph.sources)) {
|
|
@@ -2067,8 +2251,11 @@ async function processBlock(subgraph, subgraphName, blockHeight, opts) {
|
|
|
2067
2251
|
txs = data.txs;
|
|
2068
2252
|
evts = data.events;
|
|
2069
2253
|
}
|
|
2254
|
+
const route = await resolveRoute(subgraphName, targetDb);
|
|
2255
|
+
const schemaName = route.schemaName;
|
|
2070
2256
|
const traitContracts = await resolveTraitContracts(subgraph, blockHeight, targetDb);
|
|
2071
|
-
const
|
|
2257
|
+
const { resolved: factoryContracts, discovered } = await resolveFactoryContracts(subgraph, blockHeight, schemaName, targetDb, txs, evts);
|
|
2258
|
+
const matched = matchSources(subgraph.sources, txs, evts, traitContracts, factoryContracts);
|
|
2072
2259
|
result.matched = matched.length;
|
|
2073
2260
|
if (matched.length === 0) {
|
|
2074
2261
|
if (!opts?.skipProgressUpdate) {
|
|
@@ -2076,8 +2263,6 @@ async function processBlock(subgraph, subgraphName, blockHeight, opts) {
|
|
|
2076
2263
|
}
|
|
2077
2264
|
return result;
|
|
2078
2265
|
}
|
|
2079
|
-
const route = await resolveRoute(subgraphName, targetDb);
|
|
2080
|
-
const schemaName = route.schemaName;
|
|
2081
2266
|
const blockMeta = {
|
|
2082
2267
|
height: block.height,
|
|
2083
2268
|
hash: block.hash,
|
|
@@ -2135,6 +2320,7 @@ async function processBlock(subgraph, subgraphName, blockHeight, opts) {
|
|
|
2135
2320
|
});
|
|
2136
2321
|
result.processed = runResult.processed;
|
|
2137
2322
|
result.errors = runResult.errors;
|
|
2323
|
+
await persistFactoryDiscoveries(schemaName, route.dataDb, blockHeight, discovered);
|
|
2138
2324
|
await targetDb.transaction().execute(async (tx) => {
|
|
2139
2325
|
if (manifest && manifest.count > 0) {
|
|
2140
2326
|
await emitSubscriptionOutbox(tx, subgraphName, manifest, matcher, block.height);
|
|
@@ -3133,6 +3319,11 @@ async function handleSubgraphReorg(blockHeight, loadSubgraphDef) {
|
|
|
3133
3319
|
await client.unsafe(`DELETE FROM "${schemaName}"."${tableName}" WHERE "_block_height" >= $1`, [blockHeight]);
|
|
3134
3320
|
}
|
|
3135
3321
|
}
|
|
3322
|
+
await client.unsafe(`DO $$ BEGIN
|
|
3323
|
+
IF to_regclass('"${schemaName}"."_factory_addresses"') IS NOT NULL THEN
|
|
3324
|
+
DELETE FROM "${schemaName}"."_factory_addresses" WHERE block_height >= ${Number(blockHeight)};
|
|
3325
|
+
END IF;
|
|
3326
|
+
END $$`);
|
|
3136
3327
|
for (const [tableName, rows] of Object.entries(revertedByTable)) {
|
|
3137
3328
|
if (rows.length === 0)
|
|
3138
3329
|
continue;
|
|
@@ -3671,5 +3862,5 @@ export {
|
|
|
3671
3862
|
startSubgraphOperationRunner
|
|
3672
3863
|
};
|
|
3673
3864
|
|
|
3674
|
-
//# debugId=
|
|
3865
|
+
//# debugId=88213910F34356E564756E2164756E21
|
|
3675
3866
|
//# sourceMappingURL=processor.js.map
|