diff --git a/.changeset/flat-swans-turn.md b/.changeset/flat-swans-turn.md
index b84f3e8e32..47421585b0 100644
--- a/.changeset/flat-swans-turn.md
+++ b/.changeset/flat-swans-turn.md
@@ -2,4 +2,4 @@
"@latticexyz/store-sync": patch
---
-Refactored `syncToZustand` to use new Store config under the hood, removing compatibility layers and improving performance.
+Refactored package to use the new Store/World configs under the hood, removing compatibility layers and improving performance.
diff --git a/.changeset/fluffy-experts-heal.md b/.changeset/fluffy-experts-heal.md
new file mode 100644
index 0000000000..1c18a6542e
--- /dev/null
+++ b/.changeset/fluffy-experts-heal.md
@@ -0,0 +1,5 @@
+---
+"@latticexyz/store-indexer": patch
+---
+
+Updated return values to match updated types in `@latticexyz/store-sync`.
diff --git a/.changeset/real-pigs-work.md b/.changeset/real-pigs-work.md
deleted file mode 100644
index 50c5f5426e..0000000000
--- a/.changeset/real-pigs-work.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"@latticexyz/store-sync": patch
----
-
-Refactored `syncToRecs` to use new Store config under the hood, removing compatibility layers and improving performance.
diff --git a/packages/protocol-parser/src/exports/internal.ts b/packages/protocol-parser/src/exports/internal.ts
index 05f692c0ad..6f2d68af6b 100644
--- a/packages/protocol-parser/src/exports/internal.ts
+++ b/packages/protocol-parser/src/exports/internal.ts
@@ -29,3 +29,4 @@ export * from "../valueSchemaToHex";
export * from "../getKeySchema";
export * from "../getValueSchema";
export * from "../getSchemaTypes";
+export * from "../getSchemaPrimitives";
diff --git a/packages/protocol-parser/src/getKeySchema.ts b/packages/protocol-parser/src/getKeySchema.ts
index 1438b55374..1fe93d3d97 100644
--- a/packages/protocol-parser/src/getKeySchema.ts
+++ b/packages/protocol-parser/src/getKeySchema.ts
@@ -1,8 +1,10 @@
-import { Table } from "@latticexyz/config";
+import { Schema, Table } from "@latticexyz/config";
-export type getKeySchema
= {
- [fieldName in table["key"][number]]: table["schema"][fieldName];
-};
+export type getKeySchema = Table extends table
+ ? Schema
+ : {
+ readonly [fieldName in keyof table["schema"] & table["key"][number]]: table["schema"][fieldName];
+ };
export function getKeySchema(table: table): getKeySchema {
return Object.fromEntries(table.key.map((fieldName) => [fieldName, table.schema[fieldName]])) as getKeySchema;
diff --git a/packages/protocol-parser/src/getSchemaPrimitives.ts b/packages/protocol-parser/src/getSchemaPrimitives.ts
new file mode 100644
index 0000000000..1bd1453515
--- /dev/null
+++ b/packages/protocol-parser/src/getSchemaPrimitives.ts
@@ -0,0 +1,6 @@
+import { Schema } from "@latticexyz/config";
+import { SchemaAbiTypeToPrimitiveType } from "@latticexyz/schema-type/internal";
+
+export type getSchemaPrimitives = {
+ readonly [fieldName in keyof schema]: SchemaAbiTypeToPrimitiveType;
+};
diff --git a/packages/protocol-parser/src/getSchemaTypes.ts b/packages/protocol-parser/src/getSchemaTypes.ts
index 5f49606ccc..e44e8cf464 100644
--- a/packages/protocol-parser/src/getSchemaTypes.ts
+++ b/packages/protocol-parser/src/getSchemaTypes.ts
@@ -2,7 +2,7 @@ import { Schema } from "@latticexyz/config";
import { mapObject } from "@latticexyz/common/utils";
export type getSchemaTypes = {
- readonly [k in keyof schema]: schema[k]["type"];
+ readonly [fieldName in keyof schema]: schema[fieldName]["type"];
};
export function getSchemaTypes(schema: schema): getSchemaTypes {
diff --git a/packages/protocol-parser/src/getValueSchema.ts b/packages/protocol-parser/src/getValueSchema.ts
index 2a3d20afb1..543f84d972 100644
--- a/packages/protocol-parser/src/getValueSchema.ts
+++ b/packages/protocol-parser/src/getValueSchema.ts
@@ -1,8 +1,10 @@
-import { Table } from "@latticexyz/config";
+import { Schema, Table } from "@latticexyz/config";
-export type getValueSchema = {
- [fieldName in Exclude]: table["schema"][fieldName];
-};
+export type getValueSchema = Table extends table
+ ? Schema
+ : {
+ readonly [fieldName in Exclude]: table["schema"][fieldName];
+ };
export function getValueSchema(table: table): getValueSchema {
return Object.fromEntries(
diff --git a/packages/store-indexer/src/postgres/apiRoutes.ts b/packages/store-indexer/src/postgres/apiRoutes.ts
index 01a38f3e0d..749cae393f 100644
--- a/packages/store-indexer/src/postgres/apiRoutes.ts
+++ b/packages/store-indexer/src/postgres/apiRoutes.ts
@@ -3,7 +3,7 @@ import { Middleware } from "koa";
import Router from "@koa/router";
import compose from "koa-compose";
import { input } from "@latticexyz/store-sync/indexer-client";
-import { storeTables } from "@latticexyz/store-sync";
+import { schemasTable } from "@latticexyz/store-sync";
import { queryLogs } from "./queryLogs";
import { recordToLog } from "./recordToLog";
import { debug, error } from "../debug";
@@ -28,7 +28,7 @@ export function apiRoutes(database: Sql): Middleware {
}
try {
- options.filters = options.filters.length > 0 ? [...options.filters, { tableId: storeTables.Tables.tableId }] : [];
+ options.filters = options.filters.length > 0 ? [...options.filters, { tableId: schemasTable.tableId }] : [];
const records = await queryLogs(database, options ?? {}).execute();
benchmark("query records");
const logs = records.map(recordToLog);
diff --git a/packages/store-indexer/src/postgres/deprecated/createQueryAdapter.ts b/packages/store-indexer/src/postgres/deprecated/createQueryAdapter.ts
index 977be3e482..a3f5f76587 100644
--- a/packages/store-indexer/src/postgres/deprecated/createQueryAdapter.ts
+++ b/packages/store-indexer/src/postgres/deprecated/createQueryAdapter.ts
@@ -1,7 +1,7 @@
import { getAddress } from "viem";
import { PgDatabase } from "drizzle-orm/pg-core";
-import { TableWithRecords, isTableRegistrationLog, logToTable, storeTables } from "@latticexyz/store-sync";
-import { decodeKey, decodeValueArgs } from "@latticexyz/protocol-parser/internal";
+import { TableWithRecords, isTableRegistrationLog, logToTable, schemasTable } from "@latticexyz/store-sync";
+import { KeySchema, decodeKey, decodeValueArgs } from "@latticexyz/protocol-parser/internal";
import { QueryAdapter } from "@latticexyz/store-sync/trpc-indexer";
import { debug } from "../../debug";
import { getLogs } from "./getLogs";
@@ -25,19 +25,20 @@ export async function createQueryAdapter(database: PgDatabase): Promise 0 ? [...filters, { tableId: storeTables.Tables.tableId }] : [],
+ filters: filters.length > 0 ? [...filters, { tableId: schemasTable.tableId }] : [],
});
const tables = logs.filter(isTableRegistrationLog).map(logToTable);
const logsByTable = groupBy(logs, (log) => `${getAddress(log.address)}:${log.args.tableId}`);
- const tablesWithRecords: TableWithRecords[] = tables.map((table) => {
+ const tablesWithRecords: readonly TableWithRecords[] = tables.map((table) => {
const tableLogs = logsByTable.get(`${getAddress(table.address)}:${table.tableId}`) ?? [];
- const records = tableLogs.map((log) => ({
- key: decodeKey(table.keySchema, log.args.keyTuple),
- value: decodeValueArgs(table.valueSchema, log.args),
- }));
+ const records = tableLogs.map((log) => {
+ const key = decodeKey(table.keySchema as KeySchema, log.args.keyTuple);
+ const value = decodeValueArgs(table.valueSchema, log.args);
+ return { key, value, fields: { ...key, ...value } };
+ });
return {
...table,
diff --git a/packages/store-indexer/src/sqlite/apiRoutes.ts b/packages/store-indexer/src/sqlite/apiRoutes.ts
index 8bf13d8033..1c8e0aae6c 100644
--- a/packages/store-indexer/src/sqlite/apiRoutes.ts
+++ b/packages/store-indexer/src/sqlite/apiRoutes.ts
@@ -2,7 +2,7 @@ import { Middleware } from "koa";
import Router from "@koa/router";
import compose from "koa-compose";
import { input } from "@latticexyz/store-sync/indexer-client";
-import { storeTables, tablesWithRecordsToLogs } from "@latticexyz/store-sync";
+import { schemasTable, tablesWithRecordsToLogs } from "@latticexyz/store-sync";
import { debug } from "../debug";
import { createBenchmark } from "@latticexyz/common";
import { compress } from "../koa-middleware/compress";
@@ -28,7 +28,7 @@ export function apiRoutes(database: BaseSQLiteDatabase<"sync", any>): Middleware
}
try {
- options.filters = options.filters.length > 0 ? [...options.filters, { tableId: storeTables.Tables.tableId }] : [];
+ options.filters = options.filters.length > 0 ? [...options.filters, { tableId: schemasTable.tableId }] : [];
benchmark("parse config");
const { blockNumber, tables } = getTablesWithRecords(database, options);
benchmark("query tables with records");
diff --git a/packages/store-indexer/src/sqlite/getTablesWithRecords.ts b/packages/store-indexer/src/sqlite/getTablesWithRecords.ts
index a3de2112ae..eea6489ec6 100644
--- a/packages/store-indexer/src/sqlite/getTablesWithRecords.ts
+++ b/packages/store-indexer/src/sqlite/getTablesWithRecords.ts
@@ -3,7 +3,9 @@ import { BaseSQLiteDatabase } from "drizzle-orm/sqlite-core";
import { buildTable, chainState, getTables } from "@latticexyz/store-sync/sqlite";
import { Hex, getAddress } from "viem";
import { decodeDynamicField } from "@latticexyz/protocol-parser/internal";
-import { SyncFilter, TableWithRecords } from "@latticexyz/store-sync";
+import { SyncFilter, TableRecord, TableWithRecords } from "@latticexyz/store-sync";
+import { hexToResource } from "@latticexyz/common";
+import { mapObject } from "@latticexyz/common/utils";
// TODO: refactor sqlite and replace this with getLogs to match postgres (https://github.com/latticexyz/mud/issues/1970)
@@ -60,13 +62,18 @@ export function getTablesWithRecords(
(filter.key1 == null || filter.key1 === keyTuple[1]),
);
});
+ const resource = hexToResource(table.tableId);
return {
...table,
- records: filteredRecords.map((record) => ({
- key: Object.fromEntries(Object.entries(table.keySchema).map(([name]) => [name, record[name]])),
- value: Object.fromEntries(Object.entries(table.valueSchema).map(([name]) => [name, record[name]])),
- })),
- };
+ type: resource.type as never,
+ schema: mapObject({ ...table.keySchema, ...table.valueSchema }, (type) => ({ type, internalType: type })),
+ key: Object.keys(table.keySchema),
+ records: filteredRecords.map((record): TableRecord => {
+ const key = Object.fromEntries(Object.entries(table.keySchema).map(([name]) => [name, record[name]]));
+ const value = Object.fromEntries(Object.entries(table.valueSchema).map(([name]) => [name, record[name]]));
+ return { key, value, fields: { ...key, ...value } };
+ }),
+ } satisfies TableWithRecords;
});
return {
diff --git a/packages/store-sync/src/common.ts b/packages/store-sync/src/common.ts
index 6d9c2a0eb8..c616565eba 100644
--- a/packages/store-sync/src/common.ts
+++ b/packages/store-sync/src/common.ts
@@ -1,19 +1,23 @@
import { Address, Block, Hex, Log, PublicClient, TransactionReceipt } from "viem";
import { StoreEventsAbiItem, StoreEventsAbi } from "@latticexyz/store";
-import { resolveConfig } from "@latticexyz/store/internal";
import { Observable } from "rxjs";
import { UnionPick } from "@latticexyz/common/type-utils";
-import { KeySchema, TableRecord, ValueSchema } from "@latticexyz/protocol-parser/internal";
+import {
+ getKeySchema,
+ getSchemaPrimitives,
+ getSchemaTypes,
+ getValueSchema,
+} from "@latticexyz/protocol-parser/internal";
import storeConfig from "@latticexyz/store/mud.config";
import worldConfig from "@latticexyz/world/mud.config";
-import { flattenSchema } from "./flattenSchema";
import { Store as StoreConfig } from "@latticexyz/store";
-import { storeToV1 } from "@latticexyz/store/config/v2";
+import { Table as ConfigTable, Schema } from "@latticexyz/config";
-/** @internal Temporary workaround until we redo our config parsing and can pull this directly from the config (https://github.com/latticexyz/mud/issues/1668) */
-export const storeTables = resolveConfig(storeToV1(storeConfig)).tables;
-/** @internal Temporary workaround until we redo our config parsing and can pull this directly from the config (https://github.com/latticexyz/mud/issues/1668) */
-export const worldTables = resolveConfig(storeToV1(worldConfig)).tables;
+export const storeTables = storeConfig.tables;
+export type storeTables = typeof storeTables;
+
+export const worldTables = worldConfig.tables;
+export type worldTables = typeof worldTables;
export const internalTableIds = [...Object.values(storeTables), ...Object.values(worldTables)].map(
(table) => table.tableId,
@@ -22,19 +26,21 @@ export const internalTableIds = [...Object.values(storeTables), ...Object.values
export type ChainId = number;
export type WorldId = `${ChainId}:${Address}`;
-export type TableNamespace = string;
-export type TableName = string;
+export type TableRecord = {
+ readonly key: getSchemaPrimitives>;
+ readonly value: getSchemaPrimitives>;
+ readonly fields: getSchemaPrimitives;
+};
-export type Table = {
- address: Address;
- tableId: Hex;
- namespace: TableNamespace;
- name: TableName;
- keySchema: KeySchema;
- valueSchema: ValueSchema;
+export type Table = table & {
+ readonly address: Address;
+ readonly keySchema: getSchemaTypes>;
+ readonly valueSchema: getSchemaTypes>;
};
-export type TableWithRecords = Table & { records: TableRecord[] };
+export type TableWithRecords = Table & {
+ readonly records: readonly TableRecord[];
+};
export type StoreEventsLog = Log;
export type BlockLogs = { blockNumber: StoreEventsLog["blockNumber"]; logs: readonly StoreEventsLog[] };
@@ -127,10 +133,8 @@ export type StorageAdapterLog = Partial & UnionPick Promise;
-export const schemasTableId = storeTables.Tables.tableId;
export const schemasTable = {
- ...storeTables.Tables,
- // TODO: remove once we've got everything using the new Table shape
- keySchema: flattenSchema(storeTables.Tables.keySchema),
- valueSchema: flattenSchema(storeTables.Tables.valueSchema),
+ ...storeTables.store__Tables,
+ keySchema: getSchemaTypes(getKeySchema(storeTables.store__Tables)),
+ valueSchema: getSchemaTypes(getValueSchema(storeTables.store__Tables)),
};
diff --git a/packages/store-sync/src/flattenSchema.ts b/packages/store-sync/src/flattenSchema.ts
deleted file mode 100644
index cba8e6b81c..0000000000
--- a/packages/store-sync/src/flattenSchema.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-import { mapObject } from "@latticexyz/common/utils";
-import { ValueSchema } from "@latticexyz/store/internal";
-
-export function flattenSchema(
- schema: schema,
-): { readonly [k in keyof schema]: schema[k]["type"] } {
- return mapObject(schema, (value) => value.type);
-}
diff --git a/packages/store-sync/src/isTableRegistrationLog.ts b/packages/store-sync/src/isTableRegistrationLog.ts
index e7f9ac6acf..ac0ff9d347 100644
--- a/packages/store-sync/src/isTableRegistrationLog.ts
+++ b/packages/store-sync/src/isTableRegistrationLog.ts
@@ -1,4 +1,4 @@
-import { StorageAdapterLog, storeTables } from "./common";
+import { StorageAdapterLog, schemasTable } from "./common";
/**
* @internal
@@ -6,5 +6,5 @@ import { StorageAdapterLog, storeTables } from "./common";
export function isTableRegistrationLog(
log: StorageAdapterLog,
): log is StorageAdapterLog & { eventName: "Store_SetRecord" } {
- return log.eventName === "Store_SetRecord" && log.args.tableId === storeTables.Tables.tableId;
+ return log.eventName === "Store_SetRecord" && log.args.tableId === schemasTable.tableId;
}
diff --git a/packages/store-sync/src/logToTable.test.ts b/packages/store-sync/src/logToTable.test.ts
index 0feb33c786..c23cf1423f 100644
--- a/packages/store-sync/src/logToTable.test.ts
+++ b/packages/store-sync/src/logToTable.test.ts
@@ -22,12 +22,43 @@ describe("logToTable", () => {
).toMatchInlineSnapshot(`
{
"address": "0x3Aa5ebB10DC797CAC828524e59A333d0A371443c",
+ "key": [
+ "tableId",
+ ],
"keySchema": {
"tableId": "bytes32",
},
"name": "Tables",
"namespace": "mudstore",
+ "resourceId": "0x74626d756473746f72650000000000005461626c657300000000000000000000",
+ "schema": {
+ "abiEncodedFieldNames": {
+ "internalType": "bytes",
+ "type": "bytes",
+ },
+ "abiEncodedKeyNames": {
+ "internalType": "bytes",
+ "type": "bytes",
+ },
+ "fieldLayout": {
+ "internalType": "bytes32",
+ "type": "bytes32",
+ },
+ "keySchema": {
+ "internalType": "bytes32",
+ "type": "bytes32",
+ },
+ "tableId": {
+ "internalType": "bytes32",
+ "type": "bytes32",
+ },
+ "valueSchema": {
+ "internalType": "bytes32",
+ "type": "bytes32",
+ },
+ },
"tableId": "0x74626d756473746f72650000000000005461626c657300000000000000000000",
+ "type": "table",
"valueSchema": {
"abiEncodedFieldNames": "bytes",
"abiEncodedKeyNames": "bytes",
diff --git a/packages/store-sync/src/logToTable.ts b/packages/store-sync/src/logToTable.ts
index 6e9e1f5c47..9722e9bb63 100644
--- a/packages/store-sync/src/logToTable.ts
+++ b/packages/store-sync/src/logToTable.ts
@@ -1,7 +1,8 @@
-import { hexToSchema, decodeValue, ValueSchema } from "@latticexyz/protocol-parser/internal";
-import { Hex, concatHex, decodeAbiParameters, parseAbiParameters } from "viem";
+import { hexToSchema, decodeValue, getSchemaTypes } from "@latticexyz/protocol-parser/internal";
+import { concatHex, decodeAbiParameters, parseAbiParameters } from "viem";
import { StorageAdapterLog, Table, schemasTable } from "./common";
import { hexToResource } from "@latticexyz/common";
+import { Schema } from "@latticexyz/config";
/**
* @internal
@@ -12,34 +13,35 @@ export function logToTable(log: StorageAdapterLog & { eventName: "Store_SetRecor
console.warn("registerSchema event is expected to have only one key in key tuple, but got multiple", log);
}
- const table = hexToResource(tableId);
+ const resource = hexToResource(tableId);
const value = decodeValue(
- // TODO: remove cast when we have strong types for user types
- schemasTable.valueSchema as ValueSchema,
+ schemasTable.valueSchema,
concatHex([log.args.staticData, log.args.encodedLengths, log.args.dynamicData]),
);
- // TODO: remove cast when we have strong types for user types
- const keySchema = hexToSchema(value.keySchema as Hex);
+ const solidityKeySchema = hexToSchema(value.keySchema);
+ const solidityValueSchema = hexToSchema(value.valueSchema);
+ const keyNames = decodeAbiParameters(parseAbiParameters("string[]"), value.abiEncodedKeyNames)[0];
+ const fieldNames = decodeAbiParameters(parseAbiParameters("string[]"), value.abiEncodedFieldNames)[0];
- // TODO: remove cast when we have strong types for user types
- const valueSchema = hexToSchema(value.valueSchema as Hex);
+ const valueAbiTypes = [...solidityValueSchema.staticFields, ...solidityValueSchema.dynamicFields];
- // TODO: remove cast when we have strong types for user types
- const keyNames = decodeAbiParameters(parseAbiParameters("string[]"), value.abiEncodedKeyNames as Hex)[0];
+ const keySchema = Object.fromEntries(
+ solidityKeySchema.staticFields.map((abiType, i) => [keyNames[i], { type: abiType, internalType: abiType }]),
+ ) satisfies Schema;
- // TODO: remove cast when we have strong types for user types
- const fieldNames = decodeAbiParameters(parseAbiParameters("string[]"), value.abiEncodedFieldNames as Hex)[0];
-
- const valueAbiTypes = [...valueSchema.staticFields, ...valueSchema.dynamicFields];
+ const valueSchema = Object.fromEntries(
+ valueAbiTypes.map((abiType, i) => [fieldNames[i], { type: abiType, internalType: abiType }]),
+ ) satisfies Schema;
return {
address: log.address,
+ ...resource,
tableId,
- namespace: table.namespace,
- name: table.name,
- keySchema: Object.fromEntries(keySchema.staticFields.map((abiType, i) => [keyNames[i], abiType])),
- valueSchema: Object.fromEntries(valueAbiTypes.map((abiType, i) => [fieldNames[i], abiType])),
- };
+ schema: { ...keySchema, ...valueSchema },
+ key: Object.keys(keySchema),
+ keySchema: getSchemaTypes(keySchema),
+ valueSchema: getSchemaTypes(valueSchema),
+ } as never;
}
diff --git a/packages/store-sync/src/postgres-decoded/buildTable.test.ts b/packages/store-sync/src/postgres-decoded/buildTable.test.ts
index 1171b5323a..138e21d34b 100644
--- a/packages/store-sync/src/postgres-decoded/buildTable.test.ts
+++ b/packages/store-sync/src/postgres-decoded/buildTable.test.ts
@@ -3,11 +3,13 @@ import { buildTable } from "./buildTable";
import { getTableColumns } from "drizzle-orm";
import { getTableConfig } from "drizzle-orm/pg-core";
import { mapObject } from "@latticexyz/common/utils";
+import { resourceToHex } from "@latticexyz/common";
describe("buildTable", () => {
it("should create table from schema", async () => {
const table = buildTable({
address: "0xffffffffffffffffffffffffffffffffffffffff",
+ tableId: resourceToHex({ type: "table", namespace: "testNS", name: "UsersTable" }),
namespace: "testNS",
name: "UsersTable",
keySchema: { x: "uint32", y: "uint32" },
@@ -68,6 +70,7 @@ describe("buildTable", () => {
it("can create a singleton table", async () => {
const table = buildTable({
address: "0xffffffffffffffffffffffffffffffffffffffff",
+ tableId: resourceToHex({ type: "table", namespace: "testNS", name: "UsersTable" }),
namespace: "testNS",
name: "UsersTable",
keySchema: {},
diff --git a/packages/store-sync/src/postgres-decoded/buildTable.ts b/packages/store-sync/src/postgres-decoded/buildTable.ts
index 115be4b6d0..9d9ac37dee 100644
--- a/packages/store-sync/src/postgres-decoded/buildTable.ts
+++ b/packages/store-sync/src/postgres-decoded/buildTable.ts
@@ -1,55 +1,36 @@
import { PgColumnBuilderBase, PgTableWithColumns, pgSchema } from "drizzle-orm/pg-core";
-import { Address } from "viem";
import { snakeCase } from "change-case";
-import { KeySchema, ValueSchema } from "@latticexyz/protocol-parser/internal";
import { asBigInt, asHex } from "../postgres/columnTypes";
import { transformSchemaName } from "../postgres/transformSchemaName";
import { buildColumn } from "./buildColumn";
+import { PartialTable } from "./common";
export const metaColumns = {
__keyBytes: asHex("__key_bytes").primaryKey(),
__lastUpdatedBlockNumber: asBigInt("__last_updated_block_number", "numeric"),
} as const satisfies Record;
-type PgTableFromSchema = PgTableWithColumns<{
+type PgTableFromSchema = PgTableWithColumns<{
dialect: "pg";
name: string;
schema: string;
columns: {
// TODO: figure out column types
// eslint-disable-next-line @typescript-eslint/no-explicit-any
- [metaColumn in keyof typeof metaColumns]: any;
- } & {
- // TODO: figure out column types
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- [keyColumn in keyof TKeySchema]: any;
- } & {
- // TODO: figure out column types
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- [valueColumn in keyof TValueSchema]: any;
+ [metaColumn in keyof typeof metaColumns | keyof table["keySchema"] | keyof table["valueSchema"]]: any;
};
}>;
-type BuildTableOptions = {
- address: Address;
- namespace: string;
- name: string;
- keySchema: TKeySchema;
- valueSchema: TValueSchema;
-};
-
-type BuildTableResult = PgTableFromSchema<
- TKeySchema,
- TValueSchema
->;
+type BuildTableOptions = table;
+type BuildTableResult = PgTableFromSchema;
-export function buildTable({
+export function buildTable({
address,
namespace,
name,
keySchema,
valueSchema,
-}: BuildTableOptions): BuildTableResult {
+}: BuildTableOptions): BuildTableResult {
// We intentionally do not snake case the namespace due to potential conflicts
// with namespaces of a similar name (e.g. `MyNamespace` vs. `my_namespace`).
// TODO: consider snake case when we resolve https://github.com/latticexyz/mud/issues/1991
@@ -75,5 +56,5 @@ export function buildTable;
+ return table as never;
}
diff --git a/packages/store-sync/src/postgres-decoded/common.ts b/packages/store-sync/src/postgres-decoded/common.ts
new file mode 100644
index 0000000000..a18f8d4b05
--- /dev/null
+++ b/packages/store-sync/src/postgres-decoded/common.ts
@@ -0,0 +1,3 @@
+import { Table } from "../common";
+
+export type PartialTable = Pick;
diff --git a/packages/store-sync/src/postgres-decoded/createStorageAdapter.test.ts b/packages/store-sync/src/postgres-decoded/createStorageAdapter.test.ts
index 36e311b8d5..51f87ab84e 100644
--- a/packages/store-sync/src/postgres-decoded/createStorageAdapter.test.ts
+++ b/packages/store-sync/src/postgres-decoded/createStorageAdapter.test.ts
@@ -91,10 +91,19 @@ describe("createStorageAdapter", async () => {
[
{
"address": "0x7C78d585F136d7247f9deA68f60CE8A2D3F311E2",
+ "key": [],
"keySchema": {},
"name": "NumberList",
"namespace": "",
+ "resourceId": "0x746200000000000000000000000000004e756d6265724c697374000000000000",
+ "schema": {
+ "value": {
+ "internalType": "uint32[]",
+ "type": "uint32[]",
+ },
+ },
"tableId": "0x746200000000000000000000000000004e756d6265724c697374000000000000",
+ "type": "table",
"valueSchema": {
"value": "uint32[]",
},
diff --git a/packages/store-sync/src/postgres-decoded/createStorageAdapter.ts b/packages/store-sync/src/postgres-decoded/createStorageAdapter.ts
index c89db48889..4f40357dcd 100644
--- a/packages/store-sync/src/postgres-decoded/createStorageAdapter.ts
+++ b/packages/store-sync/src/postgres-decoded/createStorageAdapter.ts
@@ -7,7 +7,7 @@ import { debug } from "./debug";
import { StorageAdapter, StorageAdapterBlock } from "../common";
import { isTableRegistrationLog } from "../isTableRegistrationLog";
import { logToTable } from "../logToTable";
-import { decodeKey, decodeValueArgs } from "@latticexyz/protocol-parser/internal";
+import { KeySchema, decodeKey, decodeValueArgs } from "@latticexyz/protocol-parser/internal";
import { tables as internalTables } from "../postgres/tables";
import { createStorageAdapter as createBytesStorageAdapter } from "../postgres/createStorageAdapter";
import { setupTables } from "../postgres/setupTables";
@@ -66,7 +66,7 @@ export async function createStorageAdapter,
filters: { address: Hex | null; tableId: Hex | null }[] = [],
-): Promise {
+): Promise {
const conditions = filters.map((filter) =>
and(
filter.address != null ? eq(internalTables.recordsTable.address, filter.address) : undefined,
@@ -21,7 +22,7 @@ export async function getTables(
const records = await db
.select()
.from(internalTables.recordsTable)
- .where(and(eq(internalTables.recordsTable.tableId, storeTables.Tables.tableId), or(...conditions)));
+ .where(and(eq(internalTables.recordsTable.tableId, schemasTable.tableId), or(...conditions)));
const logs = records.map(
(record) =>
diff --git a/packages/store-sync/src/sqlite/buildTable.test.ts b/packages/store-sync/src/sqlite/buildTable.test.ts
index c68e5352d6..fda297abfd 100644
--- a/packages/store-sync/src/sqlite/buildTable.test.ts
+++ b/packages/store-sync/src/sqlite/buildTable.test.ts
@@ -1,10 +1,12 @@
import { describe, it, expect } from "vitest";
import { buildTable } from "./buildTable";
+import { resourceToHex } from "@latticexyz/common";
describe("buildTable", () => {
it("should create table from schema", async () => {
const table = buildTable({
address: "0xffffffffffffffffffffffffffffffffffffffff",
+ tableId: resourceToHex({ type: "table", namespace: "test", name: "users" }),
namespace: "test",
name: "users",
keySchema: { x: "uint32", y: "uint32" },
@@ -634,6 +636,7 @@ describe("buildTable", () => {
it("can create a singleton table", async () => {
const table = buildTable({
address: "0xffffffffffffffffffffffffffffffffffffffff",
+ tableId: resourceToHex({ type: "table", namespace: "test", name: "users" }),
namespace: "test",
name: "users",
keySchema: {},
diff --git a/packages/store-sync/src/sqlite/buildTable.ts b/packages/store-sync/src/sqlite/buildTable.ts
index eaf85b0fca..367221e7c7 100644
--- a/packages/store-sync/src/sqlite/buildTable.ts
+++ b/packages/store-sync/src/sqlite/buildTable.ts
@@ -1,9 +1,8 @@
import { SQLiteColumnBuilderBase, SQLiteTableWithColumns, sqliteTable } from "drizzle-orm/sqlite-core";
import { buildColumn } from "./buildColumn";
-import { Address } from "viem";
import { getTableName } from "./getTableName";
-import { KeySchema, ValueSchema } from "@latticexyz/protocol-parser/internal";
import { snakeCase } from "change-case";
+import { PartialTable } from "./common";
export const metaColumns = {
__key: buildColumn("__key", "bytes").primaryKey(),
@@ -15,45 +14,27 @@ export const metaColumns = {
__isDeleted: buildColumn("__isDeleted", "bool").notNull(),
} as const satisfies Record;
-type SQLiteTableFromSchema = SQLiteTableWithColumns<{
+type SQLiteTableFromSchema = SQLiteTableWithColumns<{
dialect: "sqlite";
name: string;
schema: string | undefined;
columns: {
// TODO: figure out column types
// eslint-disable-next-line @typescript-eslint/no-explicit-any
- [metaColumn in keyof typeof metaColumns]: any;
- } & {
- // TODO: figure out column types
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- [keyColumn in keyof TKeySchema]: any;
- } & {
- // TODO: figure out column types
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- [valueColumn in keyof TValueSchema]: any;
+ [metaColumn in keyof typeof metaColumns | keyof table["keySchema"] | keyof table["valueSchema"]]: any;
};
}>;
-type CreateSqliteTableOptions = {
- address: Address;
- namespace: string;
- name: string;
- keySchema: TKeySchema;
- valueSchema: TValueSchema;
-};
-
-type CreateSqliteTableResult = SQLiteTableFromSchema<
- TKeySchema,
- TValueSchema
->;
+type BuildTableOptions = table;
+type BuildTableResult = SQLiteTableFromSchema;
-export function buildTable({
+export function buildTable({
address,
namespace,
name,
keySchema,
valueSchema,
-}: CreateSqliteTableOptions): CreateSqliteTableResult {
+}: BuildTableOptions): BuildTableResult {
const tableName = getTableName(address, namespace, name);
const keyColumns = Object.fromEntries(
@@ -77,5 +58,5 @@ export function buildTable;
+ return table as never;
}
diff --git a/packages/store-sync/src/sqlite/common.ts b/packages/store-sync/src/sqlite/common.ts
new file mode 100644
index 0000000000..a18f8d4b05
--- /dev/null
+++ b/packages/store-sync/src/sqlite/common.ts
@@ -0,0 +1,3 @@
+import { Table } from "../common";
+
+export type PartialTable = Pick;
diff --git a/packages/store-sync/src/sqlite/getTables.ts b/packages/store-sync/src/sqlite/getTables.ts
index 01f9e90aa9..9228f4e631 100644
--- a/packages/store-sync/src/sqlite/getTables.ts
+++ b/packages/store-sync/src/sqlite/getTables.ts
@@ -1,13 +1,13 @@
import { BaseSQLiteDatabase } from "drizzle-orm/sqlite-core";
import { asc, inArray } from "drizzle-orm";
-import { Table } from "../common";
import { getTableName } from "./getTableName";
import { mudStoreTables } from "./internalTables";
+import { PartialTable } from "./common";
export function getTables(
db: BaseSQLiteDatabase<"sync", void>,
- conditions: Pick[] = [],
-): Table[] {
+ conditions: Pick[] = [],
+): PartialTable[] {
const ids = Array.from(
new Set(conditions.map((condition) => getTableName(condition.address, condition.namespace, condition.name))),
);
diff --git a/packages/store-sync/src/sqlite/internalTables.ts b/packages/store-sync/src/sqlite/internalTables.ts
index 97c826eead..6765e05646 100644
--- a/packages/store-sync/src/sqlite/internalTables.ts
+++ b/packages/store-sync/src/sqlite/internalTables.ts
@@ -1,6 +1,6 @@
import { blob, integer, sqliteTable, text } from "drizzle-orm/sqlite-core";
import { address, asHex, json } from "./columnTypes";
-import { KeySchema, ValueSchema } from "@latticexyz/protocol-parser/internal";
+import { PartialTable } from "./common";
export const chainState = sqliteTable("__chainState", {
schemaVersion: integer("schema_version").notNull().primaryKey(),
@@ -17,8 +17,8 @@ export const mudStoreTables = sqliteTable("__mudStoreTables", {
tableId: asHex("table_id").notNull(),
namespace: text("namespace").notNull(),
name: text("name").notNull(),
- keySchema: json("key_schema").notNull(),
- valueSchema: json("value_schema").notNull(),
+ keySchema: json("key_schema").notNull(),
+ valueSchema: json("value_schema").notNull(),
lastUpdatedBlockNumber: blob("last_updated_block_number", { mode: "bigint" }),
// TODO: last block hash?
lastError: text("last_error"),
diff --git a/packages/store-sync/src/sqlite/sqliteStorage.ts b/packages/store-sync/src/sqlite/sqliteStorage.ts
index 4dcc7a216b..cb77704c3e 100644
--- a/packages/store-sync/src/sqlite/sqliteStorage.ts
+++ b/packages/store-sync/src/sqlite/sqliteStorage.ts
@@ -13,7 +13,7 @@ import { StorageAdapter } from "../common";
import { isTableRegistrationLog } from "../isTableRegistrationLog";
import { logToTable } from "../logToTable";
import { hexToResource, resourceToLabel, spliceHex } from "@latticexyz/common";
-import { decodeKey, decodeValueArgs } from "@latticexyz/protocol-parser/internal";
+import { KeySchema, decodeKey, decodeValueArgs } from "@latticexyz/protocol-parser/internal";
// TODO: upgrade drizzle and use async sqlite interface for consistency
@@ -46,7 +46,12 @@ export async function sqliteStorage({
.values({
schemaVersion,
id: getTableName(table.address, table.namespace, table.name),
- ...table,
+ address: table.address,
+ tableId: table.tableId,
+ namespace: table.namespace,
+ name: table.name,
+ keySchema: table.keySchema,
+ valueSchema: table.valueSchema,
lastUpdatedBlockNumber: blockNumber,
})
.onConflictDoNothing()
@@ -97,7 +102,7 @@ export async function sqliteStorage({
const sqlTable = buildTable(table);
const uniqueKey = concatHex(log.args.keyTuple as Hex[]);
- const key = decodeKey(table.keySchema, log.args.keyTuple);
+ const key = decodeKey(table.keySchema as KeySchema, log.args.keyTuple);
if (log.eventName === "Store_SetRecord") {
const value = decodeValueArgs(table.valueSchema, log.args);
diff --git a/packages/store-sync/src/tableToLog.test.ts b/packages/store-sync/src/tableToLog.test.ts
index ca1f9de5f5..541b2e522b 100644
--- a/packages/store-sync/src/tableToLog.test.ts
+++ b/packages/store-sync/src/tableToLog.test.ts
@@ -1,19 +1,14 @@
/* eslint-disable max-len */
import { describe, it, expect } from "vitest";
import { tableToLog } from "./tableToLog";
-import { storeTables } from "./common";
-import { flattenSchema } from "./flattenSchema";
+import { schemasTable } from "./common";
describe("tableToLog", () => {
it("should convert a table object to table registration log", async () => {
expect(
tableToLog({
+ ...schemasTable,
address: "0x3Aa5ebB10DC797CAC828524e59A333d0A371443c",
- tableId: storeTables.Tables.tableId,
- namespace: storeTables.Tables.namespace,
- name: storeTables.Tables.name,
- keySchema: flattenSchema(storeTables.Tables.keySchema),
- valueSchema: flattenSchema(storeTables.Tables.valueSchema),
}),
).toMatchInlineSnapshot(`
{
diff --git a/packages/store-sync/src/tableToLog.ts b/packages/store-sync/src/tableToLog.ts
index adadbdfb0f..78fd24a320 100644
--- a/packages/store-sync/src/tableToLog.ts
+++ b/packages/store-sync/src/tableToLog.ts
@@ -6,8 +6,7 @@ import {
valueSchemaToHex,
} from "@latticexyz/protocol-parser/internal";
import { encodeAbiParameters, parseAbiParameters } from "viem";
-import { StorageAdapterLog, Table, storeTables } from "./common";
-import { flattenSchema } from "./flattenSchema";
+import { StorageAdapterLog, Table, schemasTable } from "./common";
/**
* @internal
@@ -17,11 +16,11 @@ export function tableToLog(table: Table): StorageAdapterLog & { eventName: "Stor
eventName: "Store_SetRecord",
address: table.address,
args: {
- tableId: storeTables.Tables.tableId,
- keyTuple: encodeKey(flattenSchema(storeTables.Tables.keySchema), { tableId: table.tableId }),
- ...encodeValueArgs(flattenSchema(storeTables.Tables.valueSchema), {
+ tableId: schemasTable.tableId,
+ keyTuple: encodeKey(schemasTable.keySchema, { tableId: table.tableId }),
+ ...encodeValueArgs(schemasTable.valueSchema, {
fieldLayout: valueSchemaToFieldLayoutHex(table.valueSchema),
- keySchema: keySchemaToHex(table.keySchema),
+ keySchema: keySchemaToHex(table.keySchema as never),
valueSchema: valueSchemaToHex(table.valueSchema),
abiEncodedKeyNames: encodeAbiParameters(parseAbiParameters("string[]"), [Object.keys(table.keySchema)]),
abiEncodedFieldNames: encodeAbiParameters(parseAbiParameters("string[]"), [Object.keys(table.valueSchema)]),
diff --git a/packages/store-sync/src/tablesWithRecordsToLogs.ts b/packages/store-sync/src/tablesWithRecordsToLogs.ts
index 0e8dc6f07a..789474ddaa 100644
--- a/packages/store-sync/src/tablesWithRecordsToLogs.ts
+++ b/packages/store-sync/src/tablesWithRecordsToLogs.ts
@@ -1,5 +1,11 @@
import { StorageAdapterLog, TableWithRecords } from "./common";
-import { encodeKey, encodeValueArgs } from "@latticexyz/protocol-parser/internal";
+import {
+ encodeKey,
+ encodeValueArgs,
+ getKeySchema,
+ getSchemaTypes,
+ getValueSchema,
+} from "@latticexyz/protocol-parser/internal";
import { tableToLog } from "./tableToLog";
/**
@@ -15,8 +21,9 @@ export function tablesWithRecordsToLogs(tables: readonly TableWithRecords[]): St
address: table.address,
args: {
tableId: table.tableId,
- keyTuple: encodeKey(table.keySchema, record.key),
- ...encodeValueArgs(table.valueSchema, record.value),
+ // TODO: migrate away from these helpers
+ keyTuple: encodeKey(getSchemaTypes(getKeySchema(table)) as never, record.key as never),
+ ...encodeValueArgs(getSchemaTypes(getValueSchema(table)), record.value),
},
}),
),
diff --git a/packages/store-sync/src/trpc-indexer/common.ts b/packages/store-sync/src/trpc-indexer/common.ts
index 63bcd22ec3..7e5334aead 100644
--- a/packages/store-sync/src/trpc-indexer/common.ts
+++ b/packages/store-sync/src/trpc-indexer/common.ts
@@ -6,8 +6,8 @@ export type QueryAdapter = {
* @deprecated
*/
findAll: (opts: { chainId: number; address?: Hex; filters?: readonly SyncFilter[] }) => Promise<{
- blockNumber: bigint | null;
- tables: readonly TableWithRecords[];
+ readonly blockNumber: bigint | null;
+ readonly tables: readonly TableWithRecords[];
}>;
getLogs: (opts: {
readonly chainId: number;
diff --git a/packages/store-sync/src/zustand/common.ts b/packages/store-sync/src/zustand/common.ts
index 5f5a64edc4..738efea940 100644
--- a/packages/store-sync/src/zustand/common.ts
+++ b/packages/store-sync/src/zustand/common.ts
@@ -1,5 +1,5 @@
import { Table } from "@latticexyz/config";
-import { SchemaToPrimitives, getKeySchema, getSchemaTypes, getValueSchema } from "@latticexyz/protocol-parser/internal";
+import { getKeySchema, getSchemaPrimitives, getValueSchema } from "@latticexyz/protocol-parser/internal";
import { Hex } from "viem";
export type RawRecord = {
@@ -17,9 +17,9 @@ export type TableRecord = {
readonly id: string;
readonly table: table;
readonly keyTuple: readonly Hex[];
- readonly key: SchemaToPrimitives>>;
- readonly value: SchemaToPrimitives>>;
- readonly fields: SchemaToPrimitives>;
+ readonly key: getSchemaPrimitives>;
+ readonly value: getSchemaPrimitives>;
+ readonly fields: getSchemaPrimitives;
};
export type { Table };
diff --git a/packages/store-sync/src/zustand/createStorageAdapter.test.ts b/packages/store-sync/src/zustand/createStorageAdapter.test.ts
index 63cf544712..16b8a6189d 100644
--- a/packages/store-sync/src/zustand/createStorageAdapter.test.ts
+++ b/packages/store-sync/src/zustand/createStorageAdapter.test.ts
@@ -2,7 +2,7 @@ import { beforeAll, describe, expect, it } from "vitest";
import { storeEventsAbi } from "@latticexyz/store";
import { createStorageAdapter } from "./createStorageAdapter";
import { createStore } from "./createStore";
-import { configV2 as config, deployMockGame } from "../../test/mockGame";
+import { config, deployMockGame } from "../../test/mockGame";
import { fetchAndStoreLogs } from "../fetchAndStoreLogs";
import { testClient } from "../../test/common";
import { getBlockNumber } from "viem/actions";
diff --git a/packages/store-sync/test/mockGame.ts b/packages/store-sync/test/mockGame.ts
index 29e2ca0fab..3cc49bbb44 100644
--- a/packages/store-sync/test/mockGame.ts
+++ b/packages/store-sync/test/mockGame.ts
@@ -1,14 +1,10 @@
import { execa } from "execa";
import { anvilRpcUrl } from "./common";
-import configV2 from "mock-game-contracts/mud.config";
-import { resolveConfig } from "@latticexyz/store/internal";
import { Hex, isHex } from "viem";
+import config from "mock-game-contracts/mud.config";
import worldAbi from "mock-game-contracts/out/IWorld.sol/IWorld.abi.json";
-import { storeToV1 } from "@latticexyz/store/config/v2";
-export { configV2 };
-export const config = resolveConfig(storeToV1(configV2));
-export { worldAbi };
+export { config, worldAbi };
export async function deployMockGame(): Promise {
console.log("deploying mock game to", anvilRpcUrl);
diff --git a/packages/store-sync/test/utils.ts b/packages/store-sync/test/utils.ts
index b9c002f620..becbcb47e6 100644
--- a/packages/store-sync/test/utils.ts
+++ b/packages/store-sync/test/utils.ts
@@ -4,25 +4,28 @@ import { foundry } from "viem/chains";
import initSqlJs from "sql.js";
import mudConfig from "../../../e2e/packages/contracts/mud.config";
import { createWorld } from "@latticexyz/recs";
-import { resolveConfig } from "@latticexyz/store/internal";
-import { RecsStorageAdapter, recsStorage } from "../src/recs";
+import {
+ CreateStorageAdapterResult as CreateRecsStorageAdapterResult,
+ createStorageAdapter as createRecsStorageAdapter,
+} from "../src/recs";
import { sqliteStorage } from "../src/sqlite";
-import { ZustandStore, createStorageAdapter, createStore } from "../src/zustand";
+import { ZustandStore, createStorageAdapter as createZustandStorageAdapter, createStore } from "../src/zustand";
import { StorageAdapter } from "../src";
-export const tables = resolveConfig(mudConfig).tables;
+export const tables = mudConfig.tables;
+export type tables = typeof tables;
-export function createRecsStorage(): RecsStorageAdapter {
- return recsStorage({ world: createWorld(), tables });
+export function createRecsStorage(): CreateRecsStorageAdapterResult {
+ return createRecsStorageAdapter({ world: createWorld(), tables });
}
export function createZustandStorage(): {
- useStore: ZustandStore;
+ useStore: ZustandStore;
storageAdapter: StorageAdapter;
} {
const useStore = createStore({ tables });
- return { useStore, storageAdapter: createStorageAdapter({ store: useStore }) };
+ return { useStore, storageAdapter: createZustandStorageAdapter({ store: useStore }) };
}
export async function createSqliteStorage(): Promise<{
diff --git a/tsconfig.paths.json b/tsconfig.paths.json
index 10fd1ec34f..70a8f9eb05 100644
--- a/tsconfig.paths.json
+++ b/tsconfig.paths.json
@@ -35,6 +35,7 @@
"@latticexyz/store/register": ["./packages/store/ts/register/index.ts"],
"@latticexyz/store/out/*": ["./packages/store/out/*"],
"@latticexyz/store/*": ["./packages/store/ts/exports/*.ts"],
+ "@latticexyz/store-sync": ["./packages/store-sync/src/index.ts"],
"@latticexyz/store-sync/*": ["./packages/store-sync/src/*"],
"@latticexyz/utils": ["./packages/utils/src/index.ts"],
"@latticexyz/world": ["./packages/world/ts/exports/index.ts"],