@latticexyz/store-indexer 2.0.0-main-1b5eb0d0 → 2.0.0-main-34203e4e
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.
@@ -1,3 +1,3 @@
|
|
1
1
|
#!/usr/bin/env node
|
2
|
-
import{a as T}from"../chunk-LOFAZSVJ.js";import{a as A,c as k}from"../chunk-2E5MDUA2.js";import"dotenv/config";import{z as
|
2
|
+
import{a as T}from"../chunk-LOFAZSVJ.js";import{a as A,c as k}from"../chunk-2E5MDUA2.js";import"dotenv/config";import{z as f}from"zod";import O from"fastify";import{fastifyTRPCPlugin as Q}from"@trpc/server/adapters/fastify";import{createAppRouter as U}from"@latticexyz/store-sync/trpc-indexer";import{getAddress as S}from"viem";import{isTableRegistrationLog as B,logToTable as v,storeTables as N}from"@latticexyz/store-sync";import{decodeKey as w,decodeValueArgs as $}from"@latticexyz/protocol-parser";import{tables as o}from"@latticexyz/store-sync/postgres";import{and as R,asc as L,eq as n,or as D}from"drizzle-orm";import{decodeDynamicField as I}from"@latticexyz/protocol-parser";import{bigIntMax as P}from"@latticexyz/common/utils";async function y(a,{chainId:s,address:r,filters:d=[]}){let g=d.length?d.map(e=>R(r!=null?n(o.recordsTable.address,r):void 0,n(o.recordsTable.tableId,e.tableId),e.key0!=null?n(o.recordsTable.key0,e.key0):void 0,e.key1!=null?n(o.recordsTable.key1,e.key1):void 0)):r!=null?[n(o.recordsTable.address,r)]:[],m=(await a.select().from(o.chainTable).where(n(o.chainTable.chainId,s)).limit(1).execute().then(e=>e.find(()=>!0)))?.lastUpdatedBlockNumber??0n,p=await a.select().from(o.recordsTable).where(D(...g)).orderBy(L(o.recordsTable.lastUpdatedBlockNumber)),b=p.reduce((e,u)=>P(e,u.lastUpdatedBlockNumber??0n),m),t=p.filter(e=>!e.isDeleted).map(e=>({address:e.address,eventName:"Store_SetRecord",args:{tableId:e.tableId,keyTuple:I("bytes32[]",e.keyBytes),staticData:e.staticData??"0x",encodedLengths:e.encodedLengths??"0x",dynamicData:e.dynamicData??"0x"}}));return{blockNumber:b,logs:t}}import{groupBy as z}from"@latticexyz/common/utils";async function x(a){return{async getLogs(r){return y(a,r)},async findAll(r){let d=r.filters??[],{blockNumber:g,logs:l}=await y(a,{...r,filters:d.length>0?[...d,{tableId:N.Tables.tableId}]:[]}),m=l.filter(B).map(v),p=z(l,t=>`${S(t.address)}:${t.args.tableId}`),b=m.map(t=>{let u=(p.get(`${S(t.address)}:${t.tableId}`)??[]).map(h=>({key:w(t.keySchema,h.args.keyTuple),value:$(t.valueSchema,h.args)}));return{...t,records:u}});return T("findAll: decoded %d logs across %d tables",l.length,m.length),{blockNumber:g,tables:b}}}}import{drizzle as q}from"drizzle-orm/postgres-js";import E from"postgres";var i=k(f.intersection(A,f.object({DATABASE_URL:f.string()}))),H=q(E(i.DATABASE_URL)),c=O({maxParamLength:5e3});await c.register(import("@fastify/cors"));c.get("/healthz",(a,s)=>s.code(200).send());c.get("/readyz",(a,s)=>s.code(200).send());c.register(Q,{prefix:"/trpc",trpcOptions:{router:U(),createContext:async()=>({queryAdapter:await x(H)})}});await c.listen({host:i.HOST,port:i.PORT});console.log(`postgres indexer frontend listening on http://${i.HOST}:${i.PORT}`);
|
3
3
|
//# sourceMappingURL=postgres-frontend.js.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["../../bin/postgres-frontend.ts","../../src/postgres/createQueryAdapter.ts","../../src/postgres/getLogs.ts"],"sourcesContent":["#!/usr/bin/env node\nimport \"dotenv/config\";\nimport { z } from \"zod\";\nimport fastify from \"fastify\";\nimport { fastifyTRPCPlugin } from \"@trpc/server/adapters/fastify\";\nimport { AppRouter, createAppRouter } from \"@latticexyz/store-sync/trpc-indexer\";\nimport { createQueryAdapter } from \"../src/postgres/createQueryAdapter\";\nimport { drizzle } from \"drizzle-orm/postgres-js\";\nimport postgres from \"postgres\";\nimport { frontendEnvSchema, parseEnv } from \"./parseEnv\";\n\nconst env = parseEnv(\n z.intersection(\n frontendEnvSchema,\n z.object({\n DATABASE_URL: z.string(),\n })\n )\n);\n\nconst database = drizzle(postgres(env.DATABASE_URL));\n\n// @see https://fastify.dev/docs/latest/\nconst server = fastify({\n maxParamLength: 5000,\n});\n\nawait server.register(import(\"@fastify/cors\"));\n\n// k8s healthchecks\nserver.get(\"/healthz\", (req, res) => res.code(200).send());\nserver.get(\"/readyz\", (req, res) => res.code(200).send());\n\n// @see https://trpc.io/docs/server/adapters/fastify\nserver.register(fastifyTRPCPlugin<AppRouter>, {\n prefix: \"/trpc\",\n trpcOptions: {\n router: createAppRouter(),\n createContext: async () => ({\n queryAdapter: await createQueryAdapter(database),\n }),\n },\n});\n\nawait server.listen({ host: env.HOST, port: env.PORT });\nconsole.log(`postgres indexer frontend listening on http://${env.HOST}:${env.PORT}`);\n","import { getAddress } from \"viem\";\nimport { PgDatabase } from \"drizzle-orm/pg-core\";\nimport { TableWithRecords, isTableRegistrationLog, logToTable, storeTables } from \"@latticexyz/store-sync\";\nimport { decodeKey, decodeValueArgs } from \"@latticexyz/protocol-parser\";\nimport { QueryAdapter } from \"@latticexyz/store-sync/trpc-indexer\";\nimport { debug } from \"../debug\";\nimport { getLogs } from \"./getLogs\";\nimport { groupBy } from \"@latticexyz/common/utils\";\n\n/**\n * Creates a query adapter for the tRPC server/client to query data from Postgres.\n *\n * @param {PgDatabase<any>} database Postgres database object from Drizzle\n * @returns {Promise<QueryAdapter>} A set of methods used by tRPC endpoints.\n */\nexport async function createQueryAdapter(database: PgDatabase<any>): Promise<QueryAdapter> {\n const adapter: QueryAdapter = {\n async getLogs(opts) {\n return getLogs(database, opts);\n },\n async findAll(opts) {\n const filters = opts.filters ?? [];\n const { blockNumber, logs } = await getLogs(database, {\n ...opts,\n // make sure we're always retrieving `store.Tables` table, so we can decode table values\n filters: filters.length > 0 ? [...filters, { tableId: storeTables.Tables.tableId }] : [],\n });\n\n const tables = logs.filter(isTableRegistrationLog).map(logToTable);\n\n const logsByTable = groupBy(logs, (log) => `${getAddress(log.address)}:${log.args.tableId}`);\n\n const tablesWithRecords: TableWithRecords[] = tables.map((table) => {\n const tableLogs = logsByTable.get(`${getAddress(table.address)}:${table.tableId}`) ?? [];\n const records = tableLogs.map((log) => ({\n key: decodeKey(table.keySchema, log.args.keyTuple),\n value: decodeValueArgs(table.valueSchema, log.args),\n }));\n\n return {\n ...table,\n records,\n };\n });\n\n debug(\"findAll: decoded %d logs across %d tables\", logs.length, tables.length);\n\n return {\n blockNumber,\n tables: tablesWithRecords,\n };\n },\n };\n return adapter;\n}\n","import { PgDatabase } from \"drizzle-orm/pg-core\";\nimport { Hex } from \"viem\";\nimport { StorageAdapterLog, SyncFilter } from \"@latticexyz/store-sync\";\nimport { tables } from \"@latticexyz/store-sync/postgres\";\nimport { and, eq, or } from \"drizzle-orm\";\nimport { decodeDynamicField } from \"@latticexyz/protocol-parser\";\nimport { bigIntMax } from \"@latticexyz/common/utils\";\n\nexport async function getLogs(\n database: PgDatabase<any>,\n {\n chainId,\n address,\n filters = [],\n }: {\n readonly chainId: number;\n readonly address?: Hex;\n readonly filters?: readonly SyncFilter[];\n }\n): Promise<{ blockNumber: bigint; logs: (StorageAdapterLog & { eventName: \"Store_SetRecord\" })[] }> {\n const conditions = filters.length\n ? filters.map((filter) =>\n and(\n address != null ? eq(tables.recordsTable.address, address) : undefined,\n eq(tables.recordsTable.tableId, filter.tableId),\n filter.key0 != null ? eq(tables.recordsTable.key0, filter.key0) : undefined,\n filter.key1 != null ? eq(tables.recordsTable.key1, filter.key1) : undefined\n )\n )\n : address != null\n ? [eq(tables.recordsTable.address, address)]\n : [];\n\n // Query for the block number that the indexer (i.e. chain) is at, in case the\n // indexer is further along in the chain than a given store/table's last updated\n // block number. We'll then take the highest block number between the indexer's\n // chain state and all the records in the query (in case the records updated\n // between these queries). Using just the highest block number from the queries\n // could potentially signal to the client an older-than-necessary block number,\n // for stores/tables that haven't seen recent activity.\n // TODO: move the block number query into the records query for atomicity so we don't have to merge them here\n const chainState = await database\n .select()\n .from(tables.chainTable)\n .where(eq(tables.chainTable.chainId, chainId))\n .limit(1)\n .execute()\n // Get the first record in a way that returns a possible `undefined`\n // TODO: move this to `.findFirst` after upgrading drizzle or `rows[0]` after enabling `noUncheckedIndexedAccess: true`\n .then((rows) => rows.find(() => true));\n const indexerBlockNumber = chainState?.lastUpdatedBlockNumber ?? 0n;\n\n const records = await database\n .select()\n .from(tables.recordsTable)\n .where(or(...conditions));\n\n const blockNumber = records.reduce(\n (max, record) => bigIntMax(max, record.lastUpdatedBlockNumber ?? 0n),\n indexerBlockNumber\n );\n\n const logs = records\n // TODO: add this to the query, assuming we can optimize with an index\n .filter((record) => !record.isDeleted)\n .map(\n (record) =>\n ({\n address: record.address,\n eventName: \"Store_SetRecord\",\n args: {\n tableId: record.tableId,\n keyTuple: decodeDynamicField(\"bytes32[]\", record.keyBytes),\n staticData: record.staticData ?? \"0x\",\n encodedLengths: record.encodedLengths ?? \"0x\",\n dynamicData: record.dynamicData ?? \"0x\",\n },\n } as const)\n );\n\n return { blockNumber, logs };\n}\n"],"mappings":"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","names":["z","fastify","fastifyTRPCPlugin","createAppRouter","getAddress","isTableRegistrationLog","logToTable","storeTables","decodeKey","decodeValueArgs","tables","and","eq","or","decodeDynamicField","bigIntMax","getLogs","database","chainId","address","filters","conditions","filter","indexerBlockNumber","rows","records","blockNumber","max","record","logs","groupBy","createQueryAdapter","database","opts","getLogs","filters","blockNumber","logs","storeTables","tables","isTableRegistrationLog","logToTable","logsByTable","log","getAddress","tablesWithRecords","table","records","decodeKey","decodeValueArgs","debug","drizzle","postgres","env","parseEnv","z","frontendEnvSchema","database","drizzle","postgres","server","fastify","req","res","fastifyTRPCPlugin","createAppRouter","createQueryAdapter"]}
|
1
|
+
{"version":3,"sources":["../../bin/postgres-frontend.ts","../../src/postgres/createQueryAdapter.ts","../../src/postgres/getLogs.ts"],"sourcesContent":["#!/usr/bin/env node\nimport \"dotenv/config\";\nimport { z } from \"zod\";\nimport fastify from \"fastify\";\nimport { fastifyTRPCPlugin } from \"@trpc/server/adapters/fastify\";\nimport { AppRouter, createAppRouter } from \"@latticexyz/store-sync/trpc-indexer\";\nimport { createQueryAdapter } from \"../src/postgres/createQueryAdapter\";\nimport { drizzle } from \"drizzle-orm/postgres-js\";\nimport postgres from \"postgres\";\nimport { frontendEnvSchema, parseEnv } from \"./parseEnv\";\n\nconst env = parseEnv(\n z.intersection(\n frontendEnvSchema,\n z.object({\n DATABASE_URL: z.string(),\n })\n )\n);\n\nconst database = drizzle(postgres(env.DATABASE_URL));\n\n// @see https://fastify.dev/docs/latest/\nconst server = fastify({\n maxParamLength: 5000,\n});\n\nawait server.register(import(\"@fastify/cors\"));\n\n// k8s healthchecks\nserver.get(\"/healthz\", (req, res) => res.code(200).send());\nserver.get(\"/readyz\", (req, res) => res.code(200).send());\n\n// @see https://trpc.io/docs/server/adapters/fastify\nserver.register(fastifyTRPCPlugin<AppRouter>, {\n prefix: \"/trpc\",\n trpcOptions: {\n router: createAppRouter(),\n createContext: async () => ({\n queryAdapter: await createQueryAdapter(database),\n }),\n },\n});\n\nawait server.listen({ host: env.HOST, port: env.PORT });\nconsole.log(`postgres indexer frontend listening on http://${env.HOST}:${env.PORT}`);\n","import { getAddress } from \"viem\";\nimport { PgDatabase } from \"drizzle-orm/pg-core\";\nimport { TableWithRecords, isTableRegistrationLog, logToTable, storeTables } from \"@latticexyz/store-sync\";\nimport { decodeKey, decodeValueArgs } from \"@latticexyz/protocol-parser\";\nimport { QueryAdapter } from \"@latticexyz/store-sync/trpc-indexer\";\nimport { debug } from \"../debug\";\nimport { getLogs } from \"./getLogs\";\nimport { groupBy } from \"@latticexyz/common/utils\";\n\n/**\n * Creates a query adapter for the tRPC server/client to query data from Postgres.\n *\n * @param {PgDatabase<any>} database Postgres database object from Drizzle\n * @returns {Promise<QueryAdapter>} A set of methods used by tRPC endpoints.\n */\nexport async function createQueryAdapter(database: PgDatabase<any>): Promise<QueryAdapter> {\n const adapter: QueryAdapter = {\n async getLogs(opts) {\n return getLogs(database, opts);\n },\n async findAll(opts) {\n const filters = opts.filters ?? [];\n const { blockNumber, logs } = await getLogs(database, {\n ...opts,\n // make sure we're always retrieving `store.Tables` table, so we can decode table values\n filters: filters.length > 0 ? [...filters, { tableId: storeTables.Tables.tableId }] : [],\n });\n\n const tables = logs.filter(isTableRegistrationLog).map(logToTable);\n\n const logsByTable = groupBy(logs, (log) => `${getAddress(log.address)}:${log.args.tableId}`);\n\n const tablesWithRecords: TableWithRecords[] = tables.map((table) => {\n const tableLogs = logsByTable.get(`${getAddress(table.address)}:${table.tableId}`) ?? [];\n const records = tableLogs.map((log) => ({\n key: decodeKey(table.keySchema, log.args.keyTuple),\n value: decodeValueArgs(table.valueSchema, log.args),\n }));\n\n return {\n ...table,\n records,\n };\n });\n\n debug(\"findAll: decoded %d logs across %d tables\", logs.length, tables.length);\n\n return {\n blockNumber,\n tables: tablesWithRecords,\n };\n },\n };\n return adapter;\n}\n","import { PgDatabase } from \"drizzle-orm/pg-core\";\nimport { Hex } from \"viem\";\nimport { StorageAdapterLog, SyncFilter } from \"@latticexyz/store-sync\";\nimport { tables } from \"@latticexyz/store-sync/postgres\";\nimport { and, asc, eq, or } from \"drizzle-orm\";\nimport { decodeDynamicField } from \"@latticexyz/protocol-parser\";\nimport { bigIntMax } from \"@latticexyz/common/utils\";\n\nexport async function getLogs(\n database: PgDatabase<any>,\n {\n chainId,\n address,\n filters = [],\n }: {\n readonly chainId: number;\n readonly address?: Hex;\n readonly filters?: readonly SyncFilter[];\n }\n): Promise<{ blockNumber: bigint; logs: (StorageAdapterLog & { eventName: \"Store_SetRecord\" })[] }> {\n const conditions = filters.length\n ? filters.map((filter) =>\n and(\n address != null ? eq(tables.recordsTable.address, address) : undefined,\n eq(tables.recordsTable.tableId, filter.tableId),\n filter.key0 != null ? eq(tables.recordsTable.key0, filter.key0) : undefined,\n filter.key1 != null ? eq(tables.recordsTable.key1, filter.key1) : undefined\n )\n )\n : address != null\n ? [eq(tables.recordsTable.address, address)]\n : [];\n\n // Query for the block number that the indexer (i.e. chain) is at, in case the\n // indexer is further along in the chain than a given store/table's last updated\n // block number. We'll then take the highest block number between the indexer's\n // chain state and all the records in the query (in case the records updated\n // between these queries). Using just the highest block number from the queries\n // could potentially signal to the client an older-than-necessary block number,\n // for stores/tables that haven't seen recent activity.\n // TODO: move the block number query into the records query for atomicity so we don't have to merge them here\n const chainState = await database\n .select()\n .from(tables.chainTable)\n .where(eq(tables.chainTable.chainId, chainId))\n .limit(1)\n .execute()\n // Get the first record in a way that returns a possible `undefined`\n // TODO: move this to `.findFirst` after upgrading drizzle or `rows[0]` after enabling `noUncheckedIndexedAccess: true`\n .then((rows) => rows.find(() => true));\n const indexerBlockNumber = chainState?.lastUpdatedBlockNumber ?? 0n;\n\n const records = await database\n .select()\n .from(tables.recordsTable)\n .where(or(...conditions))\n .orderBy(asc(tables.recordsTable.lastUpdatedBlockNumber));\n\n const blockNumber = records.reduce(\n (max, record) => bigIntMax(max, record.lastUpdatedBlockNumber ?? 0n),\n indexerBlockNumber\n );\n\n const logs = records\n // TODO: add this to the query, assuming we can optimize with an index\n .filter((record) => !record.isDeleted)\n .map(\n (record) =>\n ({\n address: record.address,\n eventName: \"Store_SetRecord\",\n args: {\n tableId: record.tableId,\n keyTuple: decodeDynamicField(\"bytes32[]\", record.keyBytes),\n staticData: record.staticData ?? \"0x\",\n encodedLengths: record.encodedLengths ?? \"0x\",\n dynamicData: record.dynamicData ?? \"0x\",\n },\n } as const)\n );\n\n return { blockNumber, logs };\n}\n"],"mappings":";yFACA,MAAO,gBACP,OAAS,KAAAA,MAAS,MAClB,OAAOC,MAAa,UACpB,OAAS,qBAAAC,MAAyB,gCAClC,OAAoB,mBAAAC,MAAuB,sCCL3C,OAAS,cAAAC,MAAkB,OAE3B,OAA2B,0BAAAC,EAAwB,cAAAC,EAAY,eAAAC,MAAmB,yBAClF,OAAS,aAAAC,EAAW,mBAAAC,MAAuB,8BCA3C,OAAS,UAAAC,MAAc,kCACvB,OAAS,OAAAC,EAAK,OAAAC,EAAK,MAAAC,EAAI,MAAAC,MAAU,cACjC,OAAS,sBAAAC,MAA0B,8BACnC,OAAS,aAAAC,MAAiB,2BAE1B,eAAsBC,EACpBC,EACA,CACE,QAAAC,EACA,QAAAC,EACA,QAAAC,EAAU,CAAC,CACb,EAKkG,CAClG,IAAMC,EAAaD,EAAQ,OACvBA,EAAQ,IAAKE,GACXZ,EACES,GAAW,KAAOP,EAAGH,EAAO,aAAa,QAASU,CAAO,EAAI,OAC7DP,EAAGH,EAAO,aAAa,QAASa,EAAO,OAAO,EAC9CA,EAAO,MAAQ,KAAOV,EAAGH,EAAO,aAAa,KAAMa,EAAO,IAAI,EAAI,OAClEA,EAAO,MAAQ,KAAOV,EAAGH,EAAO,aAAa,KAAMa,EAAO,IAAI,EAAI,MACpE,CACF,EACAH,GAAW,KACX,CAACP,EAAGH,EAAO,aAAa,QAASU,CAAO,CAAC,EACzC,CAAC,EAmBCI,GATa,MAAMN,EACtB,OAAO,EACP,KAAKR,EAAO,UAAU,EACtB,MAAMG,EAAGH,EAAO,WAAW,QAASS,CAAO,CAAC,EAC5C,MAAM,CAAC,EACP,QAAQ,EAGR,KAAMM,GAASA,EAAK,KAAK,IAAM,EAAI,CAAC,IACA,wBAA0B,GAE3DC,EAAU,MAAMR,EACnB,OAAO,EACP,KAAKR,EAAO,YAAY,EACxB,MAAMI,EAAG,GAAGQ,CAAU,CAAC,EACvB,QAAQV,EAAIF,EAAO,aAAa,sBAAsB,CAAC,EAEpDiB,EAAcD,EAAQ,OAC1B,CAACE,EAAKC,IAAWb,EAAUY,EAAKC,EAAO,wBAA0B,EAAE,EACnEL,CACF,EAEMM,EAAOJ,EAEV,OAAQG,GAAW,CAACA,EAAO,SAAS,EACpC,IACEA,IACE,CACC,QAASA,EAAO,QAChB,UAAW,kBACX,KAAM,CACJ,QAASA,EAAO,QAChB,SAAUd,EAAmB,YAAac,EAAO,QAAQ,EACzD,WAAYA,EAAO,YAAc,KACjC,eAAgBA,EAAO,gBAAkB,KACzC,YAAaA,EAAO,aAAe,IACrC,CACF,EACJ,EAEF,MAAO,CAAE,YAAAF,EAAa,KAAAG,CAAK,CAC7B,CD3EA,OAAS,WAAAC,MAAe,2BAQxB,eAAsBC,EAAmBC,EAAkD,CAsCzF,MArC8B,CAC5B,MAAM,QAAQC,EAAM,CAClB,OAAOC,EAAQF,EAAUC,CAAI,CAC/B,EACA,MAAM,QAAQA,EAAM,CAClB,IAAME,EAAUF,EAAK,SAAW,CAAC,EAC3B,CAAE,YAAAG,EAAa,KAAAC,CAAK,EAAI,MAAMH,EAAQF,EAAU,CACpD,GAAGC,EAEH,QAASE,EAAQ,OAAS,EAAI,CAAC,GAAGA,EAAS,CAAE,QAASG,EAAY,OAAO,OAAQ,CAAC,EAAI,CAAC,CACzF,CAAC,EAEKC,EAASF,EAAK,OAAOG,CAAsB,EAAE,IAAIC,CAAU,EAE3DC,EAAcZ,EAAQO,EAAOM,GAAQ,GAAGC,EAAWD,EAAI,OAAO,KAAKA,EAAI,KAAK,SAAS,EAErFE,EAAwCN,EAAO,IAAKO,GAAU,CAElE,IAAMC,GADYL,EAAY,IAAI,GAAGE,EAAWE,EAAM,OAAO,KAAKA,EAAM,SAAS,GAAK,CAAC,GAC7D,IAAKH,IAAS,CACtC,IAAKK,EAAUF,EAAM,UAAWH,EAAI,KAAK,QAAQ,EACjD,MAAOM,EAAgBH,EAAM,YAAaH,EAAI,IAAI,CACpD,EAAE,EAEF,MAAO,CACL,GAAGG,EACH,QAAAC,CACF,CACF,CAAC,EAED,OAAAG,EAAM,4CAA6Cb,EAAK,OAAQE,EAAO,MAAM,EAEtE,CACL,YAAAH,EACA,OAAQS,CACV,CACF,CACF,CAEF,CD/CA,OAAS,WAAAM,MAAe,0BACxB,OAAOC,MAAc,WAGrB,IAAMC,EAAMC,EACVC,EAAE,aACAC,EACAD,EAAE,OAAO,CACP,aAAcA,EAAE,OAAO,CACzB,CAAC,CACH,CACF,EAEME,EAAWC,EAAQC,EAASN,EAAI,YAAY,CAAC,EAG7CO,EAASC,EAAQ,CACrB,eAAgB,GAClB,CAAC,EAED,MAAMD,EAAO,SAAS,OAAO,eAAe,CAAC,EAG7CA,EAAO,IAAI,WAAY,CAACE,EAAKC,IAAQA,EAAI,KAAK,GAAG,EAAE,KAAK,CAAC,EACzDH,EAAO,IAAI,UAAW,CAACE,EAAKC,IAAQA,EAAI,KAAK,GAAG,EAAE,KAAK,CAAC,EAGxDH,EAAO,SAASI,EAA8B,CAC5C,OAAQ,QACR,YAAa,CACX,OAAQC,EAAgB,EACxB,cAAe,UAAa,CAC1B,aAAc,MAAMC,EAAmBT,CAAQ,CACjD,EACF,CACF,CAAC,EAED,MAAMG,EAAO,OAAO,CAAE,KAAMP,EAAI,KAAM,KAAMA,EAAI,IAAK,CAAC,EACtD,QAAQ,IAAI,iDAAiDA,EAAI,QAAQA,EAAI,MAAM","names":["z","fastify","fastifyTRPCPlugin","createAppRouter","getAddress","isTableRegistrationLog","logToTable","storeTables","decodeKey","decodeValueArgs","tables","and","asc","eq","or","decodeDynamicField","bigIntMax","getLogs","database","chainId","address","filters","conditions","filter","indexerBlockNumber","rows","records","blockNumber","max","record","logs","groupBy","createQueryAdapter","database","opts","getLogs","filters","blockNumber","logs","storeTables","tables","isTableRegistrationLog","logToTable","logsByTable","log","getAddress","tablesWithRecords","table","records","decodeKey","decodeValueArgs","debug","drizzle","postgres","env","parseEnv","z","frontendEnvSchema","database","drizzle","postgres","server","fastify","req","res","fastifyTRPCPlugin","createAppRouter","createQueryAdapter"]}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@latticexyz/store-indexer",
|
3
|
-
"version": "2.0.0-main-
|
3
|
+
"version": "2.0.0-main-34203e4e",
|
4
4
|
"description": "Minimal Typescript indexer for Store",
|
5
5
|
"repository": {
|
6
6
|
"type": "git",
|
@@ -32,11 +32,11 @@
|
|
32
32
|
"superjson": "^1.12.4",
|
33
33
|
"viem": "1.14.0",
|
34
34
|
"zod": "^3.21.4",
|
35
|
-
"@latticexyz/block-logs-stream": "2.0.0-main-
|
36
|
-
"@latticexyz/common": "2.0.0-main-
|
37
|
-
"@latticexyz/protocol-parser": "2.0.0-main-
|
38
|
-
"@latticexyz/store": "2.0.0-main-
|
39
|
-
"@latticexyz/store-sync": "2.0.0-main-
|
35
|
+
"@latticexyz/block-logs-stream": "2.0.0-main-34203e4e",
|
36
|
+
"@latticexyz/common": "2.0.0-main-34203e4e",
|
37
|
+
"@latticexyz/protocol-parser": "2.0.0-main-34203e4e",
|
38
|
+
"@latticexyz/store": "2.0.0-main-34203e4e",
|
39
|
+
"@latticexyz/store-sync": "2.0.0-main-34203e4e"
|
40
40
|
},
|
41
41
|
"devDependencies": {
|
42
42
|
"@types/better-sqlite3": "^7.6.4",
|
package/src/postgres/getLogs.ts
CHANGED
@@ -2,7 +2,7 @@ import { PgDatabase } from "drizzle-orm/pg-core";
|
|
2
2
|
import { Hex } from "viem";
|
3
3
|
import { StorageAdapterLog, SyncFilter } from "@latticexyz/store-sync";
|
4
4
|
import { tables } from "@latticexyz/store-sync/postgres";
|
5
|
-
import { and, eq, or } from "drizzle-orm";
|
5
|
+
import { and, asc, eq, or } from "drizzle-orm";
|
6
6
|
import { decodeDynamicField } from "@latticexyz/protocol-parser";
|
7
7
|
import { bigIntMax } from "@latticexyz/common/utils";
|
8
8
|
|
@@ -53,7 +53,8 @@ export async function getLogs(
|
|
53
53
|
const records = await database
|
54
54
|
.select()
|
55
55
|
.from(tables.recordsTable)
|
56
|
-
.where(or(...conditions))
|
56
|
+
.where(or(...conditions))
|
57
|
+
.orderBy(asc(tables.recordsTable.lastUpdatedBlockNumber));
|
57
58
|
|
58
59
|
const blockNumber = records.reduce(
|
59
60
|
(max, record) => bigIntMax(max, record.lastUpdatedBlockNumber ?? 0n),
|