From cdc084a569d0640de213b0c19fd433cd9b84e318 Mon Sep 17 00:00:00 2001 From: Kevin Ingersoll Date: Fri, 19 Jul 2024 11:59:27 +0100 Subject: [PATCH 01/26] config to zustand tables --- packages/store-sync/package.json | 1 + ...ByLabel.test.ts => configToTables.test.ts} | 11 ++++--- .../store-sync/src/zustand/configToTables.ts | 30 ++++++++++++++++++ .../store-sync/src/zustand/getAllTables.ts | 31 ++++++++++--------- .../store-sync/src/zustand/tablesByLabel.ts | 9 ------ pnpm-lock.yaml | 3 ++ 6 files changed, 58 insertions(+), 27 deletions(-) rename packages/store-sync/src/zustand/{tablesByLabel.test.ts => configToTables.test.ts} (63%) create mode 100644 packages/store-sync/src/zustand/configToTables.ts delete mode 100644 packages/store-sync/src/zustand/tablesByLabel.ts diff --git a/packages/store-sync/package.json b/packages/store-sync/package.json index 17a41ceb44..daf2a74bc8 100644 --- a/packages/store-sync/package.json +++ b/packages/store-sync/package.json @@ -62,6 +62,7 @@ "test:ci": "vitest --run" }, "dependencies": { + "@arktype/util": "0.0.40", "@latticexyz/block-logs-stream": "workspace:*", "@latticexyz/common": "workspace:*", "@latticexyz/config": "workspace:*", diff --git a/packages/store-sync/src/zustand/tablesByLabel.test.ts b/packages/store-sync/src/zustand/configToTables.test.ts similarity index 63% rename from packages/store-sync/src/zustand/tablesByLabel.test.ts rename to packages/store-sync/src/zustand/configToTables.test.ts index 8082b9992c..3104083307 100644 --- a/packages/store-sync/src/zustand/tablesByLabel.test.ts +++ b/packages/store-sync/src/zustand/configToTables.test.ts @@ -1,10 +1,10 @@ import { describe, expect, it } from "vitest"; -import { tablesByLabel } from "./tablesByLabel"; +import { configToTables } from "./configToTables"; import { defineWorld } from "@latticexyz/world"; import { resourceToHex } from "@latticexyz/common"; -describe("tablesByLabel", () => { - it("maps table label to component name", async () => { +describe("configToTables", () => { + it("flattens tables from single namespace", async () => { const config = defineWorld({ namespace: "app", tables: { @@ -12,7 +12,7 @@ describe("tablesByLabel", () => { }, }); - const tables = tablesByLabel(config.tables); + const tables = configToTables(config); expect(tables.ExceedsResourceNameSizeLimit.tableId).toBe( resourceToHex({ type: "table", @@ -23,4 +23,7 @@ describe("tablesByLabel", () => { expect(tables.ExceedsResourceNameSizeLimit.label).toBe("ExceedsResourceNameSizeLimit"); expect(tables.ExceedsResourceNameSizeLimit.name).toBe("ExceedsResourceN"); }); + + // TODO: add test with multiple namespaces + // TODO: add test where the label is the same for two tables in different namespaces to make sure TS + runtime agree on which takes precedence }); diff --git a/packages/store-sync/src/zustand/configToTables.ts b/packages/store-sync/src/zustand/configToTables.ts new file mode 100644 index 0000000000..4f7f46268c --- /dev/null +++ b/packages/store-sync/src/zustand/configToTables.ts @@ -0,0 +1,30 @@ +import { satisfy, show } from "@arktype/util"; +import { Tables } from "@latticexyz/config"; +import { Store } from "@latticexyz/store"; + +type flattenedTableKeys = config extends { readonly namespaces: infer namespaces } + ? { + [namespaceLabel in keyof namespaces]: namespaces[namespaceLabel] extends { readonly tables: infer tables } + ? `${namespaceLabel & string}__${keyof tables & string}` + : never; + }[keyof namespaces] + : never; + +// TODO: figure out how TS handles overlapping table labels so we can make runtime match +// TODO: move satisfy to type test + +export type configToTables = satisfy< + Tables, + { + readonly [key in flattenedTableKeys as key extends `${string}__${infer tableLabel}` + ? tableLabel + : never]: key extends `${infer namespaceLabel}__${infer tableLabel}` + ? config["namespaces"][namespaceLabel]["tables"][tableLabel] + : never; + } +>; + +export function configToTables(config: config): show> { + const tables = Object.values(config.namespaces).flatMap((namespace) => Object.values(namespace.tables)); + return Object.fromEntries(tables.map((table) => [table.label, table])) as never; +} diff --git a/packages/store-sync/src/zustand/getAllTables.ts b/packages/store-sync/src/zustand/getAllTables.ts index d050127f3b..31c0e30b0a 100644 --- a/packages/store-sync/src/zustand/getAllTables.ts +++ b/packages/store-sync/src/zustand/getAllTables.ts @@ -1,28 +1,31 @@ import { Store as StoreConfig } from "@latticexyz/store"; import { Tables } from "@latticexyz/config"; -import { tablesByLabel } from "./tablesByLabel"; import { mergeRight } from "./mergeRight"; import storeConfig from "@latticexyz/store/mud.config"; import worldConfig from "@latticexyz/world/mud.config"; +import { configToTables } from "./configToTables"; +import { satisfy, show } from "@arktype/util"; -const storeTables = storeConfig.tables; -type storeTables = typeof storeTables; +type mudTables = mergeRight, configToTables>; +const mudTables = { + ...configToTables(storeConfig), + ...configToTables(worldConfig), +}; -const worldTables = worldConfig.tables; -type worldTables = typeof worldTables; - -export type getAllTables = tablesByLabel< - mergeRight>> +// TODO: validate that extraTables keys correspond to table labels? +// TODO: move satisfy to type test +export type getAllTables = satisfy< + Tables, + mergeRight, mergeRight> >; export function getAllTables( config: config, extraTables: extraTables, -): getAllTables { - return tablesByLabel({ - ...config.tables, +): show> { + return { + ...configToTables(config), ...extraTables, - ...storeTables, - ...worldTables, - }) as never; + ...mudTables, + } as never; } diff --git a/packages/store-sync/src/zustand/tablesByLabel.ts b/packages/store-sync/src/zustand/tablesByLabel.ts deleted file mode 100644 index d247ef3223..0000000000 --- a/packages/store-sync/src/zustand/tablesByLabel.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { Tables } from "@latticexyz/config"; - -export type tablesByLabel = { - readonly [key in string & keyof tables as tables[key]["label"]]: tables[key]; -}; - -export function tablesByLabel(tables: tables): tablesByLabel { - return Object.fromEntries(Object.entries(tables).map(([, table]) => [table.label, table])) as never; -} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6733c1e6c4..b7824886e9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -874,6 +874,9 @@ importers: packages/store-sync: dependencies: + '@arktype/util': + specifier: 0.0.40 + version: 0.0.40 '@latticexyz/block-logs-stream': specifier: workspace:* version: link:../block-logs-stream From 8f0d01cb8fafa3472ca810a8845c318622d327a8 Mon Sep 17 00:00:00 2001 From: alvrs Date: Fri, 19 Jul 2024 15:14:16 +0200 Subject: [PATCH 02/26] fix configToTables --- .../src/zustand/configToTables.test.ts | 38 ++++++++++++++++--- .../store-sync/src/zustand/configToTables.ts | 23 +++++------ 2 files changed, 42 insertions(+), 19 deletions(-) diff --git a/packages/store-sync/src/zustand/configToTables.test.ts b/packages/store-sync/src/zustand/configToTables.test.ts index 3104083307..9d9372379a 100644 --- a/packages/store-sync/src/zustand/configToTables.test.ts +++ b/packages/store-sync/src/zustand/configToTables.test.ts @@ -1,7 +1,21 @@ -import { describe, expect, it } from "vitest"; -import { configToTables } from "./configToTables"; +import { describe, it } from "vitest"; +import { configToTables, flattenedTableKeys } from "./configToTables"; import { defineWorld } from "@latticexyz/world"; import { resourceToHex } from "@latticexyz/common"; +import { attest } from "@arktype/attest"; + +describe("flattenedTableKeys", () => { + it("returns flattened table keys", () => { + const config = defineWorld({ + namespace: "app", + tables: { + ExceedsResourceNameSizeLimit: "bytes32", + Table2: "address", + }, + }); + attest<"app__ExceedsResourceNameSizeLimit" | "app__Table2", flattenedTableKeys>(); + }); +}); describe("configToTables", () => { it("flattens tables from single namespace", async () => { @@ -9,19 +23,33 @@ describe("configToTables", () => { namespace: "app", tables: { ExceedsResourceNameSizeLimit: "bytes32", + Table2: "address", }, }); const tables = configToTables(config); - expect(tables.ExceedsResourceNameSizeLimit.tableId).toBe( + + attest<"ExceedsResourceNameSizeLimit" | "Table2", keyof typeof tables>(); + + attest(tables.ExceedsResourceNameSizeLimit.tableId).equals( resourceToHex({ type: "table", namespace: "app", name: "ExceedsResourceN", }), ); - expect(tables.ExceedsResourceNameSizeLimit.label).toBe("ExceedsResourceNameSizeLimit"); - expect(tables.ExceedsResourceNameSizeLimit.name).toBe("ExceedsResourceN"); + attest(tables.ExceedsResourceNameSizeLimit.label).equals("ExceedsResourceNameSizeLimit"); + attest(tables.ExceedsResourceNameSizeLimit.name).equals("ExceedsResourceN"); + + attest(tables.Table2.tableId).equals( + resourceToHex({ + type: "table", + namespace: "app", + name: "Table2", + }), + ); + attest(tables.Table2.label).equals("Table2"); + attest(tables.Table2.name).equals("Table2"); }); // TODO: add test with multiple namespaces diff --git a/packages/store-sync/src/zustand/configToTables.ts b/packages/store-sync/src/zustand/configToTables.ts index 4f7f46268c..0b6de61d5e 100644 --- a/packages/store-sync/src/zustand/configToTables.ts +++ b/packages/store-sync/src/zustand/configToTables.ts @@ -1,8 +1,7 @@ -import { satisfy, show } from "@arktype/util"; -import { Tables } from "@latticexyz/config"; +import { show } from "@arktype/util"; import { Store } from "@latticexyz/store"; -type flattenedTableKeys = config extends { readonly namespaces: infer namespaces } +export type flattenedTableKeys = config extends { readonly namespaces: infer namespaces } ? { [namespaceLabel in keyof namespaces]: namespaces[namespaceLabel] extends { readonly tables: infer tables } ? `${namespaceLabel & string}__${keyof tables & string}` @@ -11,18 +10,14 @@ type flattenedTableKeys = config extends { readonly namesp : never; // TODO: figure out how TS handles overlapping table labels so we can make runtime match -// TODO: move satisfy to type test -export type configToTables = satisfy< - Tables, - { - readonly [key in flattenedTableKeys as key extends `${string}__${infer tableLabel}` - ? tableLabel - : never]: key extends `${infer namespaceLabel}__${infer tableLabel}` - ? config["namespaces"][namespaceLabel]["tables"][tableLabel] - : never; - } ->; +export type configToTables = { + readonly [key in flattenedTableKeys as key extends `${string}__${infer tableLabel}` + ? tableLabel + : never]: key extends `${infer namespaceLabel}__${infer tableLabel}` + ? config["namespaces"][namespaceLabel]["tables"][tableLabel] + : never; +}; export function configToTables(config: config): show> { const tables = Object.values(config.namespaces).flatMap((namespace) => Object.values(namespace.tables)); From 95f8e252b024301ace561e20fc0900286ffedf15 Mon Sep 17 00:00:00 2001 From: Kevin Ingersoll Date: Fri, 19 Jul 2024 18:01:46 +0100 Subject: [PATCH 03/26] test in CI --- test/ts-benchmarks/package.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/ts-benchmarks/package.json b/test/ts-benchmarks/package.json index 0a03af156c..3b07e8d6e8 100644 --- a/test/ts-benchmarks/package.json +++ b/test/ts-benchmarks/package.json @@ -4,7 +4,9 @@ "private": true, "license": "MIT", "scripts": { - "bench": "tsx ./bench" + "bench": "tsx ./bench", + "test": "pnpm run bench", + "test:ci": "pnpm run test" }, "devDependencies": { "@latticexyz/recs": "workspace:*", From 9f622f866a9b49983586465037a626070623c539 Mon Sep 17 00:00:00 2001 From: Kevin Ingersoll Date: Fri, 19 Jul 2024 18:10:29 +0100 Subject: [PATCH 04/26] use arktype for consistency for now --- package.json | 2 +- pnpm-lock.yaml | 40 ++++++++++++++++++------------------- test/ts-benchmarks/bench.ts | 2 +- 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/package.json b/package.json index 4235b8fbe1..8fb713c04c 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,7 @@ "package.json": "pnpm sort-package-json" }, "devDependencies": { - "@ark/attest": "0.9.2", + "@arktype/attest": "0.9.1", "@changesets/cli": "^2.26.1", "@types/node": "^18.15.11", "@typescript-eslint/eslint-plugin": "7.1.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6d818afc26..0ce9ff51b0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,9 +8,9 @@ importers: .: devDependencies: - '@ark/attest': - specifier: 0.9.2 - version: 0.9.2(typescript@5.4.2) + '@arktype/attest': + specifier: 0.9.1 + version: 0.9.1(typescript@5.4.2) '@changesets/cli': specifier: ^2.26.1 version: 2.26.1 @@ -1199,12 +1199,6 @@ packages: resolution: {integrity: sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==} engines: {node: '>=6.0.0'} - '@ark/attest@0.9.2': - resolution: {integrity: sha512-AgwTHTmRMKiEWFeXIHtNb87KISPwACn+kUrAxlqyRx+0/opXA1qnEn/hKCyB61zWPfcur4dB0GUnx+ILDCl5Dg==} - hasBin: true - peerDependencies: - typescript: '*' - '@ark/fs@0.1.0': resolution: {integrity: sha512-A7zoIqcO8dPKbzYruYuCro1J4Ai/20rwlIJv2ExbKOBl/XowczKnNV8bh+6azOkkieeZJdrnSXSfNklVHf7zoA==} @@ -1220,6 +1214,12 @@ packages: peerDependencies: typescript: '*' + '@arktype/attest@0.9.1': + resolution: {integrity: sha512-ueMMH3BJfyPg3Lt+wmel0C1NGGq2k+Aq7AXZw0eTiF8524p+0PK3pVr4Vwa5OfsZ7cTYJ+GJHC4wrcH1mZ24tg==} + hasBin: true + peerDependencies: + typescript: '*' + '@arktype/fs@0.0.19': resolution: {integrity: sha512-ZEiSc6DgJANSgMTee9lueumCH/3gIikJWT8wlN8CyVk/IDFKFbJb3/BHj906Aw+APvCc8oyvu+2Hanshkgh4Bg==} @@ -6942,17 +6942,6 @@ snapshots: '@jridgewell/gen-mapping': 0.3.3 '@jridgewell/trace-mapping': 0.3.18 - '@ark/attest@0.9.2(typescript@5.4.2)': - dependencies: - '@ark/fs': 0.1.0 - '@ark/util': 0.1.0 - '@typescript/analyze-trace': 0.10.1 - '@typescript/vfs': 1.5.3(typescript@5.4.2) - arktype: 2.0.0-beta.0 - typescript: 5.4.2 - transitivePeerDependencies: - - supports-color - '@ark/fs@0.1.0': {} '@ark/schema@0.2.0': @@ -6972,6 +6961,17 @@ snapshots: transitivePeerDependencies: - supports-color + '@arktype/attest@0.9.1(typescript@5.4.2)': + dependencies: + '@ark/fs': 0.1.0 + '@ark/util': 0.1.0 + '@typescript/analyze-trace': 0.10.1 + '@typescript/vfs': 1.5.3(typescript@5.4.2) + arktype: 2.0.0-beta.0 + typescript: 5.4.2 + transitivePeerDependencies: + - supports-color + '@arktype/fs@0.0.19': {} '@arktype/schema@0.1.2': diff --git a/test/ts-benchmarks/bench.ts b/test/ts-benchmarks/bench.ts index 2537213f55..fbca81a013 100644 --- a/test/ts-benchmarks/bench.ts +++ b/test/ts-benchmarks/bench.ts @@ -1,4 +1,4 @@ -import { bench } from "@ark/attest"; +import { bench } from "@arktype/attest"; import { syncToRecs } from "@latticexyz/store-sync/recs"; import { syncToZustand } from "@latticexyz/store-sync/zustand"; import { Hex, type PublicClient } from "viem"; From a7680e39b1cb441bd34ac1cb2b5c858f50474d15 Mon Sep 17 00:00:00 2001 From: Kevin Ingersoll Date: Fri, 19 Jul 2024 18:16:42 +0100 Subject: [PATCH 05/26] add test for getAllTables --- .../store-sync/src/zustand/configToTables.ts | 3 +++ .../src/zustand/getAllTables.test.ts | 20 +++++++++++++++++++ .../store-sync/src/zustand/getAllTables.ts | 9 ++++----- 3 files changed, 27 insertions(+), 5 deletions(-) create mode 100644 packages/store-sync/src/zustand/getAllTables.test.ts diff --git a/packages/store-sync/src/zustand/configToTables.ts b/packages/store-sync/src/zustand/configToTables.ts index 0b6de61d5e..0658947714 100644 --- a/packages/store-sync/src/zustand/configToTables.ts +++ b/packages/store-sync/src/zustand/configToTables.ts @@ -1,6 +1,9 @@ import { show } from "@arktype/util"; import { Store } from "@latticexyz/store"; +/** + * @internal + */ export type flattenedTableKeys = config extends { readonly namespaces: infer namespaces } ? { [namespaceLabel in keyof namespaces]: namespaces[namespaceLabel] extends { readonly tables: infer tables } diff --git a/packages/store-sync/src/zustand/getAllTables.test.ts b/packages/store-sync/src/zustand/getAllTables.test.ts new file mode 100644 index 0000000000..5e96cab123 --- /dev/null +++ b/packages/store-sync/src/zustand/getAllTables.test.ts @@ -0,0 +1,20 @@ +import { describe, it } from "vitest"; +import { defineWorld } from "@latticexyz/world"; +import { attest } from "@arktype/attest"; +import { getAllTables } from "./getAllTables"; +import { Tables } from "@latticexyz/config"; + +describe("getAllTables", () => { + it("returns combined tables", () => { + const config = defineWorld({ + namespace: "app", + tables: { + ExceedsResourceNameSizeLimit: "bytes32", + Table2: "address", + }, + }); + const tables = getAllTables(config, {}); + attest(); + attest(); + }); +}); diff --git a/packages/store-sync/src/zustand/getAllTables.ts b/packages/store-sync/src/zustand/getAllTables.ts index 31c0e30b0a..c8634d1355 100644 --- a/packages/store-sync/src/zustand/getAllTables.ts +++ b/packages/store-sync/src/zustand/getAllTables.ts @@ -4,7 +4,7 @@ import { mergeRight } from "./mergeRight"; import storeConfig from "@latticexyz/store/mud.config"; import worldConfig from "@latticexyz/world/mud.config"; import { configToTables } from "./configToTables"; -import { satisfy, show } from "@arktype/util"; +import { show } from "@arktype/util"; type mudTables = mergeRight, configToTables>; const mudTables = { @@ -13,10 +13,9 @@ const mudTables = { }; // TODO: validate that extraTables keys correspond to table labels? -// TODO: move satisfy to type test -export type getAllTables = satisfy< - Tables, - mergeRight, mergeRight> +export type getAllTables = mergeRight< + configToTables, + mergeRight >; export function getAllTables( From 47a63918c429a8c408a185b2b052f3b1fd4555e0 Mon Sep 17 00:00:00 2001 From: Kevin Ingersoll Date: Fri, 19 Jul 2024 18:23:38 +0100 Subject: [PATCH 06/26] add a generic test, align attest versions --- .../src/zustand/getAllTables.test.ts | 6 +- packages/store/package.json | 2 +- packages/world/package.json | 2 +- pnpm-lock.yaml | 64 ++----------------- 4 files changed, 11 insertions(+), 63 deletions(-) diff --git a/packages/store-sync/src/zustand/getAllTables.test.ts b/packages/store-sync/src/zustand/getAllTables.test.ts index 5e96cab123..03be33bcae 100644 --- a/packages/store-sync/src/zustand/getAllTables.test.ts +++ b/packages/store-sync/src/zustand/getAllTables.test.ts @@ -1,10 +1,14 @@ import { describe, it } from "vitest"; -import { defineWorld } from "@latticexyz/world"; +import { World, defineWorld } from "@latticexyz/world"; import { attest } from "@arktype/attest"; import { getAllTables } from "./getAllTables"; import { Tables } from "@latticexyz/config"; describe("getAllTables", () => { + it("type satisfies Tables", () => { + attest>(); + }); + it("returns combined tables", () => { const config = defineWorld({ namespace: "app", diff --git a/packages/store/package.json b/packages/store/package.json index c8d841d09e..b41dac9879 100644 --- a/packages/store/package.json +++ b/packages/store/package.json @@ -69,7 +69,7 @@ "viem": "2.9.20" }, "devDependencies": { - "@arktype/attest": "0.7.5", + "@arktype/attest": "0.9.1", "@latticexyz/abi-ts": "workspace:*", "@latticexyz/gas-report": "workspace:*", "@types/ejs": "^3.1.1", diff --git a/packages/world/package.json b/packages/world/package.json index 54d5b5cc1f..6cf126b7a7 100644 --- a/packages/world/package.json +++ b/packages/world/package.json @@ -70,7 +70,7 @@ "viem": "2.9.20" }, "devDependencies": { - "@arktype/attest": "0.7.5", + "@arktype/attest": "0.9.1", "@latticexyz/abi-ts": "workspace:*", "@latticexyz/gas-report": "workspace:*", "@types/ejs": "^3.1.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0ce9ff51b0..75a074f20f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -727,8 +727,8 @@ importers: version: 2.9.20(typescript@5.4.2)(zod@3.23.7) devDependencies: '@arktype/attest': - specifier: 0.7.5 - version: 0.7.5(typescript@5.4.2) + specifier: 0.9.1 + version: 0.9.1(typescript@5.4.2) '@latticexyz/abi-ts': specifier: workspace:* version: link:../abi-ts @@ -1031,8 +1031,8 @@ importers: version: 2.9.20(typescript@5.4.2)(zod@3.23.7) devDependencies: '@arktype/attest': - specifier: 0.7.5 - version: 0.7.5(typescript@5.4.2) + specifier: 0.9.1 + version: 0.9.1(typescript@5.4.2) '@latticexyz/abi-ts': specifier: workspace:* version: link:../abi-ts @@ -1208,33 +1208,15 @@ packages: '@ark/util@0.1.0': resolution: {integrity: sha512-qCLYICQoCy3kEKDVwirQp8qvxhY7NJd8BhhoHaj1l3wCFAk9NUbcDsxAkPStZEMdPI/d7NcbGJe8SWZuRG2twQ==} - '@arktype/attest@0.7.5': - resolution: {integrity: sha512-ZOF9uqLbvoVO6RHhlByJEBBj5qhWLpaCK/wWa5guD1OQR1/a7JZ9jCrDAcaASt6tYBA3dGhDerXhc7FcDWlRQw==} - hasBin: true - peerDependencies: - typescript: '*' - '@arktype/attest@0.9.1': resolution: {integrity: sha512-ueMMH3BJfyPg3Lt+wmel0C1NGGq2k+Aq7AXZw0eTiF8524p+0PK3pVr4Vwa5OfsZ7cTYJ+GJHC4wrcH1mZ24tg==} hasBin: true peerDependencies: typescript: '*' - '@arktype/fs@0.0.19': - resolution: {integrity: sha512-ZEiSc6DgJANSgMTee9lueumCH/3gIikJWT8wlN8CyVk/IDFKFbJb3/BHj906Aw+APvCc8oyvu+2Hanshkgh4Bg==} - - '@arktype/schema@0.1.2': - resolution: {integrity: sha512-ggvxs5P0toqd/4/XK76URQrtyOYpbYcLhirEZeTso6FxkloPa0lT+whPg7DNQj5qi2OQXLUHBYKMx9DOb13ViQ==} - - '@arktype/util@0.0.38': - resolution: {integrity: sha512-IvYMGnkUASJllRk3mdBVgckomKx2LNsDTrWCxz04EBK1OuU+4fJ/smSjxgZVWfopNXZds9sHNxZgTJOIw7GvJw==} - '@arktype/util@0.0.40': resolution: {integrity: sha512-dwC3xZh9Bz6LWSJq71AUoh06zB0qM65N4zS/NNogbumhbO55yot7yqDlv0qeBMNOWXj/gX7l7l58v0EqEaXN2w==} - '@arktype/util@0.0.41': - resolution: {integrity: sha512-0YURzJ42v+lhlP1t5Dj90YezETRTCdFU0oM4xMVpYsmPx/DHJzr9n7AX1QPAlYWH4wY7hYY3gwai3O+8VntPgw==} - '@aws-crypto/ie11-detection@3.0.0': resolution: {integrity: sha512-341lBBkiY1DfDNKai/wXM3aujNBkXR7tq1URPQDL9wi3AUbI80NR74uF1TXHMm7po1AcnFk8iu2S2IeU/+/A+Q==} @@ -2741,9 +2723,6 @@ packages: resolution: {integrity: sha512-RnlSOPh14QbopGCApgkSx5UBgGda5MX1cHqp2fsqfiDyCwGL/m1jaeB9fzu7didVS81LQqGZZuxFBcg8YU8EVw==} hasBin: true - '@typescript/vfs@1.5.0': - resolution: {integrity: sha512-AJS307bPgbsZZ9ggCT3wwpg3VbTKMFNHfaY/uF0ahSkYYrPF2dSSKDNIDIQAHm9qJqbLvCsSJH7yN4Vs/CsMMg==} - '@typescript/vfs@1.5.3': resolution: {integrity: sha512-OSZ/o3wwD5VPZVdGGsXWk7sRGRtwrGnqA4zwmb33FTs7Wxmad0QTkQCbaNyqWA8hL09TCwAthdp8yjFA5G1lvw==} peerDependencies: @@ -2963,9 +2942,6 @@ packages: arktype@2.0.0-beta.0: resolution: {integrity: sha512-fE3ssMiXjr/bLqFPzlDhRlXngdyHQreu7p7i8+dtcY1CA+f8WrVUcue6JxywhnqEJXPG4HOcIwQcC+q4VfeUMQ==} - arktype@2.0.0-dev.11: - resolution: {integrity: sha512-k+WVQoHsHsTyTiVQkO201mxLQxyXHmy3buJW8TXLOkr4X2yOUCp0K1SBscuG9OEJoc8MjpvoIharjPHEkFI7kg==} - array-includes@3.1.6: resolution: {integrity: sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw==} engines: {node: '>= 0.4'} @@ -6950,17 +6926,6 @@ snapshots: '@ark/util@0.1.0': {} - '@arktype/attest@0.7.5(typescript@5.4.2)': - dependencies: - '@arktype/fs': 0.0.19 - '@arktype/util': 0.0.41 - '@typescript/analyze-trace': 0.10.1 - '@typescript/vfs': 1.5.0 - arktype: 2.0.0-dev.11 - typescript: 5.4.2 - transitivePeerDependencies: - - supports-color - '@arktype/attest@0.9.1(typescript@5.4.2)': dependencies: '@ark/fs': 0.1.0 @@ -6972,18 +6937,8 @@ snapshots: transitivePeerDependencies: - supports-color - '@arktype/fs@0.0.19': {} - - '@arktype/schema@0.1.2': - dependencies: - '@arktype/util': 0.0.38 - - '@arktype/util@0.0.38': {} - '@arktype/util@0.0.40': {} - '@arktype/util@0.0.41': {} - '@aws-crypto/ie11-detection@3.0.0': dependencies: tslib: 1.14.1 @@ -8982,12 +8937,6 @@ snapshots: treeify: 1.1.0 yargs: 16.2.0 - '@typescript/vfs@1.5.0': - dependencies: - debug: 4.3.4 - transitivePeerDependencies: - - supports-color - '@typescript/vfs@1.5.3(typescript@5.4.2)': dependencies: debug: 4.3.4 @@ -9194,11 +9143,6 @@ snapshots: '@ark/schema': 0.2.0 '@ark/util': 0.1.0 - arktype@2.0.0-dev.11: - dependencies: - '@arktype/schema': 0.1.2 - '@arktype/util': 0.0.38 - array-includes@3.1.6: dependencies: call-bind: 1.0.2 From c6bbe215caad4e2d8b38912763e15cbea5f2a810 Mon Sep 17 00:00:00 2001 From: Kevin Ingersoll Date: Fri, 19 Jul 2024 18:41:37 +0100 Subject: [PATCH 07/26] simplify type --- packages/store-sync/src/zustand/syncToZustand.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/packages/store-sync/src/zustand/syncToZustand.ts b/packages/store-sync/src/zustand/syncToZustand.ts index 61e75fd2ed..8b46b487b0 100644 --- a/packages/store-sync/src/zustand/syncToZustand.ts +++ b/packages/store-sync/src/zustand/syncToZustand.ts @@ -9,10 +9,7 @@ import { Store as StoreConfig } from "@latticexyz/store"; import { Tables } from "@latticexyz/config"; import { getAllTables } from "./getAllTables"; -type SyncToZustandOptions = Omit< - SyncOptions, - "address" | "config" -> & { +type SyncToZustandOptions = SyncOptions & { // require address for now to keep the data model + retrieval simpler address: Address; config: config; From d071167b18034912b2bac811d5472d3c853b57d7 Mon Sep 17 00:00:00 2001 From: Kevin Ingersoll Date: Fri, 19 Jul 2024 18:45:57 +0100 Subject: [PATCH 08/26] Revert "simplify type" This reverts commit c6bbe215caad4e2d8b38912763e15cbea5f2a810. --- packages/store-sync/src/zustand/syncToZustand.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/store-sync/src/zustand/syncToZustand.ts b/packages/store-sync/src/zustand/syncToZustand.ts index 8b46b487b0..61e75fd2ed 100644 --- a/packages/store-sync/src/zustand/syncToZustand.ts +++ b/packages/store-sync/src/zustand/syncToZustand.ts @@ -9,7 +9,10 @@ import { Store as StoreConfig } from "@latticexyz/store"; import { Tables } from "@latticexyz/config"; import { getAllTables } from "./getAllTables"; -type SyncToZustandOptions = SyncOptions & { +type SyncToZustandOptions = Omit< + SyncOptions, + "address" | "config" +> & { // require address for now to keep the data model + retrieval simpler address: Address; config: config; From d1b1d8b2dcf23b1b16f4ed9d4c147013afb24f35 Mon Sep 17 00:00:00 2001 From: Kevin Ingersoll Date: Fri, 19 Jul 2024 19:02:36 +0100 Subject: [PATCH 09/26] fix attest --- package.json | 2 +- packages/store-sync/vitest.config.ts | 2 +- packages/store-sync/vitestSetup.ts | 1 + packages/store/package.json | 2 +- packages/world/package.json | 2 +- pnpm-lock.yaml | 84 ++++++++++++++-------------- 6 files changed, 48 insertions(+), 45 deletions(-) create mode 100644 packages/store-sync/vitestSetup.ts diff --git a/package.json b/package.json index 8fb713c04c..0191d6afa9 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,7 @@ "package.json": "pnpm sort-package-json" }, "devDependencies": { - "@arktype/attest": "0.9.1", + "@arktype/attest": "0.7.5", "@changesets/cli": "^2.26.1", "@types/node": "^18.15.11", "@typescript-eslint/eslint-plugin": "7.1.1", diff --git a/packages/store-sync/vitest.config.ts b/packages/store-sync/vitest.config.ts index ebc97d5e06..0913de5c2d 100644 --- a/packages/store-sync/vitest.config.ts +++ b/packages/store-sync/vitest.config.ts @@ -2,7 +2,7 @@ import { defineConfig } from "vitest/config"; export default defineConfig({ test: { - globalSetup: ["test/globalSetup.ts"], + globalSetup: ["vitestSetup.ts", "test/globalSetup.ts"], setupFiles: ["test/setup.ts"], // Temporarily set a low teardown timeout because anvil hangs otherwise // Could move this timeout to anvil setup after https://github.com/wevm/anvil.js/pull/46 diff --git a/packages/store-sync/vitestSetup.ts b/packages/store-sync/vitestSetup.ts new file mode 100644 index 0000000000..13353cdfd6 --- /dev/null +++ b/packages/store-sync/vitestSetup.ts @@ -0,0 +1 @@ +export { setup, cleanup as teardown } from "@arktype/attest"; diff --git a/packages/store/package.json b/packages/store/package.json index b41dac9879..c8d841d09e 100644 --- a/packages/store/package.json +++ b/packages/store/package.json @@ -69,7 +69,7 @@ "viem": "2.9.20" }, "devDependencies": { - "@arktype/attest": "0.9.1", + "@arktype/attest": "0.7.5", "@latticexyz/abi-ts": "workspace:*", "@latticexyz/gas-report": "workspace:*", "@types/ejs": "^3.1.1", diff --git a/packages/world/package.json b/packages/world/package.json index 6cf126b7a7..54d5b5cc1f 100644 --- a/packages/world/package.json +++ b/packages/world/package.json @@ -70,7 +70,7 @@ "viem": "2.9.20" }, "devDependencies": { - "@arktype/attest": "0.9.1", + "@arktype/attest": "0.7.5", "@latticexyz/abi-ts": "workspace:*", "@latticexyz/gas-report": "workspace:*", "@types/ejs": "^3.1.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 75a074f20f..2bd78dea95 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,8 +9,8 @@ importers: .: devDependencies: '@arktype/attest': - specifier: 0.9.1 - version: 0.9.1(typescript@5.4.2) + specifier: 0.7.5 + version: 0.7.5(typescript@5.4.2) '@changesets/cli': specifier: ^2.26.1 version: 2.26.1 @@ -727,8 +727,8 @@ importers: version: 2.9.20(typescript@5.4.2)(zod@3.23.7) devDependencies: '@arktype/attest': - specifier: 0.9.1 - version: 0.9.1(typescript@5.4.2) + specifier: 0.7.5 + version: 0.7.5(typescript@5.4.2) '@latticexyz/abi-ts': specifier: workspace:* version: link:../abi-ts @@ -1031,8 +1031,8 @@ importers: version: 2.9.20(typescript@5.4.2)(zod@3.23.7) devDependencies: '@arktype/attest': - specifier: 0.9.1 - version: 0.9.1(typescript@5.4.2) + specifier: 0.7.5 + version: 0.7.5(typescript@5.4.2) '@latticexyz/abi-ts': specifier: workspace:* version: link:../abi-ts @@ -1199,24 +1199,27 @@ packages: resolution: {integrity: sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==} engines: {node: '>=6.0.0'} - '@ark/fs@0.1.0': - resolution: {integrity: sha512-A7zoIqcO8dPKbzYruYuCro1J4Ai/20rwlIJv2ExbKOBl/XowczKnNV8bh+6azOkkieeZJdrnSXSfNklVHf7zoA==} - - '@ark/schema@0.2.0': - resolution: {integrity: sha512-IkNWCSHdjaoemMXpps4uFHEAQzwJPbTAS8K2vcQpk90sa+eNBuPSVyB/81/Qyl1VYW0iX3ceGC5NL/OznQv1jg==} - - '@ark/util@0.1.0': - resolution: {integrity: sha512-qCLYICQoCy3kEKDVwirQp8qvxhY7NJd8BhhoHaj1l3wCFAk9NUbcDsxAkPStZEMdPI/d7NcbGJe8SWZuRG2twQ==} - - '@arktype/attest@0.9.1': - resolution: {integrity: sha512-ueMMH3BJfyPg3Lt+wmel0C1NGGq2k+Aq7AXZw0eTiF8524p+0PK3pVr4Vwa5OfsZ7cTYJ+GJHC4wrcH1mZ24tg==} + '@arktype/attest@0.7.5': + resolution: {integrity: sha512-ZOF9uqLbvoVO6RHhlByJEBBj5qhWLpaCK/wWa5guD1OQR1/a7JZ9jCrDAcaASt6tYBA3dGhDerXhc7FcDWlRQw==} hasBin: true peerDependencies: typescript: '*' + '@arktype/fs@0.0.19': + resolution: {integrity: sha512-ZEiSc6DgJANSgMTee9lueumCH/3gIikJWT8wlN8CyVk/IDFKFbJb3/BHj906Aw+APvCc8oyvu+2Hanshkgh4Bg==} + + '@arktype/schema@0.1.2': + resolution: {integrity: sha512-ggvxs5P0toqd/4/XK76URQrtyOYpbYcLhirEZeTso6FxkloPa0lT+whPg7DNQj5qi2OQXLUHBYKMx9DOb13ViQ==} + + '@arktype/util@0.0.38': + resolution: {integrity: sha512-IvYMGnkUASJllRk3mdBVgckomKx2LNsDTrWCxz04EBK1OuU+4fJ/smSjxgZVWfopNXZds9sHNxZgTJOIw7GvJw==} + '@arktype/util@0.0.40': resolution: {integrity: sha512-dwC3xZh9Bz6LWSJq71AUoh06zB0qM65N4zS/NNogbumhbO55yot7yqDlv0qeBMNOWXj/gX7l7l58v0EqEaXN2w==} + '@arktype/util@0.0.41': + resolution: {integrity: sha512-0YURzJ42v+lhlP1t5Dj90YezETRTCdFU0oM4xMVpYsmPx/DHJzr9n7AX1QPAlYWH4wY7hYY3gwai3O+8VntPgw==} + '@aws-crypto/ie11-detection@3.0.0': resolution: {integrity: sha512-341lBBkiY1DfDNKai/wXM3aujNBkXR7tq1URPQDL9wi3AUbI80NR74uF1TXHMm7po1AcnFk8iu2S2IeU/+/A+Q==} @@ -2723,10 +2726,8 @@ packages: resolution: {integrity: sha512-RnlSOPh14QbopGCApgkSx5UBgGda5MX1cHqp2fsqfiDyCwGL/m1jaeB9fzu7didVS81LQqGZZuxFBcg8YU8EVw==} hasBin: true - '@typescript/vfs@1.5.3': - resolution: {integrity: sha512-OSZ/o3wwD5VPZVdGGsXWk7sRGRtwrGnqA4zwmb33FTs7Wxmad0QTkQCbaNyqWA8hL09TCwAthdp8yjFA5G1lvw==} - peerDependencies: - typescript: '*' + '@typescript/vfs@1.5.0': + resolution: {integrity: sha512-AJS307bPgbsZZ9ggCT3wwpg3VbTKMFNHfaY/uF0ahSkYYrPF2dSSKDNIDIQAHm9qJqbLvCsSJH7yN4Vs/CsMMg==} '@ungap/structured-clone@1.2.0': resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} @@ -2939,8 +2940,8 @@ packages: arktype@1.0.29-alpha: resolution: {integrity: sha512-glMLgVhIQRSkR3tymiS+POAcWVJH09sfrgic0jHnyFL8BlhHAJZX2BzdImU9zYr1y9NBqy+U93ZNrRTHXsKRDw==} - arktype@2.0.0-beta.0: - resolution: {integrity: sha512-fE3ssMiXjr/bLqFPzlDhRlXngdyHQreu7p7i8+dtcY1CA+f8WrVUcue6JxywhnqEJXPG4HOcIwQcC+q4VfeUMQ==} + arktype@2.0.0-dev.11: + resolution: {integrity: sha512-k+WVQoHsHsTyTiVQkO201mxLQxyXHmy3buJW8TXLOkr4X2yOUCp0K1SBscuG9OEJoc8MjpvoIharjPHEkFI7kg==} array-includes@3.1.6: resolution: {integrity: sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw==} @@ -6918,27 +6919,29 @@ snapshots: '@jridgewell/gen-mapping': 0.3.3 '@jridgewell/trace-mapping': 0.3.18 - '@ark/fs@0.1.0': {} - - '@ark/schema@0.2.0': + '@arktype/attest@0.7.5(typescript@5.4.2)': dependencies: - '@ark/util': 0.1.0 - - '@ark/util@0.1.0': {} - - '@arktype/attest@0.9.1(typescript@5.4.2)': - dependencies: - '@ark/fs': 0.1.0 - '@ark/util': 0.1.0 + '@arktype/fs': 0.0.19 + '@arktype/util': 0.0.41 '@typescript/analyze-trace': 0.10.1 - '@typescript/vfs': 1.5.3(typescript@5.4.2) - arktype: 2.0.0-beta.0 + '@typescript/vfs': 1.5.0 + arktype: 2.0.0-dev.11 typescript: 5.4.2 transitivePeerDependencies: - supports-color + '@arktype/fs@0.0.19': {} + + '@arktype/schema@0.1.2': + dependencies: + '@arktype/util': 0.0.38 + + '@arktype/util@0.0.38': {} + '@arktype/util@0.0.40': {} + '@arktype/util@0.0.41': {} + '@aws-crypto/ie11-detection@3.0.0': dependencies: tslib: 1.14.1 @@ -8937,10 +8940,9 @@ snapshots: treeify: 1.1.0 yargs: 16.2.0 - '@typescript/vfs@1.5.3(typescript@5.4.2)': + '@typescript/vfs@1.5.0': dependencies: debug: 4.3.4 - typescript: 5.4.2 transitivePeerDependencies: - supports-color @@ -9138,10 +9140,10 @@ snapshots: arktype@1.0.29-alpha: {} - arktype@2.0.0-beta.0: + arktype@2.0.0-dev.11: dependencies: - '@ark/schema': 0.2.0 - '@ark/util': 0.1.0 + '@arktype/schema': 0.1.2 + '@arktype/util': 0.0.38 array-includes@3.1.6: dependencies: From 04e1c8718da471071bb05c2cff0fe9eb2fabd926 Mon Sep 17 00:00:00 2001 From: Kevin Ingersoll Date: Sat, 20 Jul 2024 09:11:19 +0100 Subject: [PATCH 10/26] use arktype util's merge --- packages/store-sync/package.json | 2 +- .../store-sync/src/zustand/getAllTables.test.ts | 15 +++++++++++++++ packages/store-sync/src/zustand/getAllTables.ts | 9 ++++----- packages/store-sync/src/zustand/mergeRight.ts | 7 ------- pnpm-lock.yaml | 9 +++++++-- 5 files changed, 27 insertions(+), 15 deletions(-) delete mode 100644 packages/store-sync/src/zustand/mergeRight.ts diff --git a/packages/store-sync/package.json b/packages/store-sync/package.json index daf2a74bc8..3247a5fb34 100644 --- a/packages/store-sync/package.json +++ b/packages/store-sync/package.json @@ -62,7 +62,7 @@ "test:ci": "vitest --run" }, "dependencies": { - "@arktype/util": "0.0.40", + "@arktype/util": "0.1.0", "@latticexyz/block-logs-stream": "workspace:*", "@latticexyz/common": "workspace:*", "@latticexyz/config": "workspace:*", diff --git a/packages/store-sync/src/zustand/getAllTables.test.ts b/packages/store-sync/src/zustand/getAllTables.test.ts index 03be33bcae..e43e5b169a 100644 --- a/packages/store-sync/src/zustand/getAllTables.test.ts +++ b/packages/store-sync/src/zustand/getAllTables.test.ts @@ -3,6 +3,8 @@ import { World, defineWorld } from "@latticexyz/world"; import { attest } from "@arktype/attest"; import { getAllTables } from "./getAllTables"; import { Tables } from "@latticexyz/config"; +import storeConfig from "@latticexyz/store/mud.config"; +import worldConfig from "@latticexyz/world/mud.config"; describe("getAllTables", () => { it("type satisfies Tables", () => { @@ -21,4 +23,17 @@ describe("getAllTables", () => { attest(); attest(); }); + + it("prioritizes MUD tables over user defined ones", () => { + const config = defineWorld({ + namespace: "app", + tables: { + StoreHooks: "bool", + NamespaceOwner: "bool", + }, + }); + const tables = getAllTables(config, {}); + attest(tables.StoreHooks).equals(storeConfig.namespaces.store.tables.StoreHooks); + attest(tables.NamespaceOwner).equals(worldConfig.namespaces.world.tables.NamespaceOwner); + }); }); diff --git a/packages/store-sync/src/zustand/getAllTables.ts b/packages/store-sync/src/zustand/getAllTables.ts index c8634d1355..d5ec2a4fcc 100644 --- a/packages/store-sync/src/zustand/getAllTables.ts +++ b/packages/store-sync/src/zustand/getAllTables.ts @@ -1,21 +1,20 @@ import { Store as StoreConfig } from "@latticexyz/store"; import { Tables } from "@latticexyz/config"; -import { mergeRight } from "./mergeRight"; import storeConfig from "@latticexyz/store/mud.config"; import worldConfig from "@latticexyz/world/mud.config"; import { configToTables } from "./configToTables"; -import { show } from "@arktype/util"; +import { merge, show } from "@arktype/util"; -type mudTables = mergeRight, configToTables>; +type mudTables = merge, configToTables>; const mudTables = { ...configToTables(storeConfig), ...configToTables(worldConfig), }; // TODO: validate that extraTables keys correspond to table labels? -export type getAllTables = mergeRight< +export type getAllTables = merge< configToTables, - mergeRight + merge >; export function getAllTables( diff --git a/packages/store-sync/src/zustand/mergeRight.ts b/packages/store-sync/src/zustand/mergeRight.ts deleted file mode 100644 index b45ef5e54a..0000000000 --- a/packages/store-sync/src/zustand/mergeRight.ts +++ /dev/null @@ -1,7 +0,0 @@ -export type mergeRight = { - readonly [key in keyof left | keyof right]: key extends keyof right - ? right[key] - : key extends keyof left - ? left[key] - : never; -}; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2bd78dea95..4391fc9bb5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -881,8 +881,8 @@ importers: packages/store-sync: dependencies: '@arktype/util': - specifier: 0.0.40 - version: 0.0.40 + specifier: 0.1.0 + version: 0.1.0 '@latticexyz/block-logs-stream': specifier: workspace:* version: link:../block-logs-stream @@ -1220,6 +1220,9 @@ packages: '@arktype/util@0.0.41': resolution: {integrity: sha512-0YURzJ42v+lhlP1t5Dj90YezETRTCdFU0oM4xMVpYsmPx/DHJzr9n7AX1QPAlYWH4wY7hYY3gwai3O+8VntPgw==} + '@arktype/util@0.1.0': + resolution: {integrity: sha512-t5jCNbspCF/XizGfmM5fn+86IMtQgCB2Px3Y1E8ckm5AjTECyI7Aj5pV6e9iL8qXF9FdKA53FBLRzAZUqYBnCw==} + '@aws-crypto/ie11-detection@3.0.0': resolution: {integrity: sha512-341lBBkiY1DfDNKai/wXM3aujNBkXR7tq1URPQDL9wi3AUbI80NR74uF1TXHMm7po1AcnFk8iu2S2IeU/+/A+Q==} @@ -6942,6 +6945,8 @@ snapshots: '@arktype/util@0.0.41': {} + '@arktype/util@0.1.0': {} + '@aws-crypto/ie11-detection@3.0.0': dependencies: tslib: 1.14.1 From 13f7ca7de6421de9ec36f691871342300a034404 Mon Sep 17 00:00:00 2001 From: Kevin Ingersoll Date: Sat, 20 Jul 2024 09:17:33 +0100 Subject: [PATCH 11/26] fix tests --- packages/store-sync/src/zustand/getAllTables.test.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/packages/store-sync/src/zustand/getAllTables.test.ts b/packages/store-sync/src/zustand/getAllTables.test.ts index e43e5b169a..9232c4f309 100644 --- a/packages/store-sync/src/zustand/getAllTables.test.ts +++ b/packages/store-sync/src/zustand/getAllTables.test.ts @@ -5,10 +5,11 @@ import { getAllTables } from "./getAllTables"; import { Tables } from "@latticexyz/config"; import storeConfig from "@latticexyz/store/mud.config"; import worldConfig from "@latticexyz/world/mud.config"; +import { satisfy } from "@arktype/util"; describe("getAllTables", () => { it("type satisfies Tables", () => { - attest>(); + attest, satisfy>>(); }); it("returns combined tables", () => { @@ -20,8 +21,10 @@ describe("getAllTables", () => { }, }); const tables = getAllTables(config, {}); - attest(); - attest(); + attest>(); + + type expectedKeys = "ExceedsResourceNameSizeLimit" | "Table2" | "StoreHooks" | "NamespaceOwner"; + attest(); }); it("prioritizes MUD tables over user defined ones", () => { From 9a8bda1f0c6f925effd81be4dcbeb2235d4e4ee4 Mon Sep 17 00:00:00 2001 From: Kevin Ingersoll Date: Sat, 20 Jul 2024 09:20:21 +0100 Subject: [PATCH 12/26] update bench --- test/ts-benchmarks/bench.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/ts-benchmarks/bench.ts b/test/ts-benchmarks/bench.ts index fbca81a013..d0b24b509f 100644 --- a/test/ts-benchmarks/bench.ts +++ b/test/ts-benchmarks/bench.ts @@ -28,7 +28,7 @@ bench("syncToRecs", async () => { }); return t; -}).types([20704, "instantiations"]); +}).types([21188, "instantiations"]); bench("syncToZustand", async () => { const config = defineWorld({ @@ -52,4 +52,4 @@ bench("syncToZustand", async () => { }); return t; -}).types([20728, "instantiations"]); +}).types([21214, "instantiations"]); From 3a2e8104161890affaae32e8503bbda89a9aa6f0 Mon Sep 17 00:00:00 2001 From: Kevin Ingersoll Date: Sat, 20 Jul 2024 09:25:53 +0100 Subject: [PATCH 13/26] don't expose flattened tables --- .../store-sync/src/zustand/configToTables.test.ts | 15 +-------------- packages/store-sync/src/zustand/configToTables.ts | 5 +---- 2 files changed, 2 insertions(+), 18 deletions(-) diff --git a/packages/store-sync/src/zustand/configToTables.test.ts b/packages/store-sync/src/zustand/configToTables.test.ts index 9d9372379a..5e393bb507 100644 --- a/packages/store-sync/src/zustand/configToTables.test.ts +++ b/packages/store-sync/src/zustand/configToTables.test.ts @@ -1,22 +1,9 @@ import { describe, it } from "vitest"; -import { configToTables, flattenedTableKeys } from "./configToTables"; +import { configToTables } from "./configToTables"; import { defineWorld } from "@latticexyz/world"; import { resourceToHex } from "@latticexyz/common"; import { attest } from "@arktype/attest"; -describe("flattenedTableKeys", () => { - it("returns flattened table keys", () => { - const config = defineWorld({ - namespace: "app", - tables: { - ExceedsResourceNameSizeLimit: "bytes32", - Table2: "address", - }, - }); - attest<"app__ExceedsResourceNameSizeLimit" | "app__Table2", flattenedTableKeys>(); - }); -}); - describe("configToTables", () => { it("flattens tables from single namespace", async () => { const config = defineWorld({ diff --git a/packages/store-sync/src/zustand/configToTables.ts b/packages/store-sync/src/zustand/configToTables.ts index 0658947714..aa08ee327d 100644 --- a/packages/store-sync/src/zustand/configToTables.ts +++ b/packages/store-sync/src/zustand/configToTables.ts @@ -1,10 +1,7 @@ import { show } from "@arktype/util"; import { Store } from "@latticexyz/store"; -/** - * @internal - */ -export type flattenedTableKeys = config extends { readonly namespaces: infer namespaces } +type flattenedTableKeys = config extends { readonly namespaces: infer namespaces } ? { [namespaceLabel in keyof namespaces]: namespaces[namespaceLabel] extends { readonly tables: infer tables } ? `${namespaceLabel & string}__${keyof tables & string}` From dc7c3e1bb9149cfe4d2b6a803c523322fc08a08e Mon Sep 17 00:00:00 2001 From: Kevin Ingersoll Date: Sat, 20 Jul 2024 10:07:23 +0100 Subject: [PATCH 14/26] use namespaced tables in recs --- .../src/{zustand => }/configToTables.test.ts | 0 .../src/{zustand => }/configToTables.ts | 0 .../src/{zustand => }/getAllTables.test.ts | 9 +++--- .../src/{zustand => }/getAllTables.ts | 14 ++-------- .../src/recs/createStorageAdapter.ts | 28 +++++++------------ packages/store-sync/src/recs/syncToRecs.ts | 20 +++++++------ .../store-sync/src/recs/tablesToComponents.ts | 9 +++--- .../store-sync/src/zustand/syncToZustand.ts | 15 ++++++---- packages/store/ts/config/v2/input.ts | 2 +- packages/store/ts/config/v2/store.test.ts | 5 ++++ .../ts/config/v2/storeWithShorthands.test.ts | 7 ++++- .../store/ts/config/v2/storeWithShorthands.ts | 9 ++++-- 12 files changed, 63 insertions(+), 55 deletions(-) rename packages/store-sync/src/{zustand => }/configToTables.test.ts (100%) rename packages/store-sync/src/{zustand => }/configToTables.ts (100%) rename packages/store-sync/src/{zustand => }/getAllTables.test.ts (81%) rename packages/store-sync/src/{zustand => }/getAllTables.ts (55%) diff --git a/packages/store-sync/src/zustand/configToTables.test.ts b/packages/store-sync/src/configToTables.test.ts similarity index 100% rename from packages/store-sync/src/zustand/configToTables.test.ts rename to packages/store-sync/src/configToTables.test.ts diff --git a/packages/store-sync/src/zustand/configToTables.ts b/packages/store-sync/src/configToTables.ts similarity index 100% rename from packages/store-sync/src/zustand/configToTables.ts rename to packages/store-sync/src/configToTables.ts diff --git a/packages/store-sync/src/zustand/getAllTables.test.ts b/packages/store-sync/src/getAllTables.test.ts similarity index 81% rename from packages/store-sync/src/zustand/getAllTables.test.ts rename to packages/store-sync/src/getAllTables.test.ts index 9232c4f309..b27a05da2a 100644 --- a/packages/store-sync/src/zustand/getAllTables.test.ts +++ b/packages/store-sync/src/getAllTables.test.ts @@ -1,15 +1,16 @@ import { describe, it } from "vitest"; -import { World, defineWorld } from "@latticexyz/world"; +import { defineWorld } from "@latticexyz/world"; import { attest } from "@arktype/attest"; import { getAllTables } from "./getAllTables"; import { Tables } from "@latticexyz/config"; import storeConfig from "@latticexyz/store/mud.config"; import worldConfig from "@latticexyz/world/mud.config"; import { satisfy } from "@arktype/util"; +import { configToTables } from "./configToTables"; describe("getAllTables", () => { it("type satisfies Tables", () => { - attest, satisfy>>(); + attest, satisfy>>(); }); it("returns combined tables", () => { @@ -20,7 +21,7 @@ describe("getAllTables", () => { Table2: "address", }, }); - const tables = getAllTables(config, {}); + const tables = getAllTables(configToTables(config)); attest>(); type expectedKeys = "ExceedsResourceNameSizeLimit" | "Table2" | "StoreHooks" | "NamespaceOwner"; @@ -35,7 +36,7 @@ describe("getAllTables", () => { NamespaceOwner: "bool", }, }); - const tables = getAllTables(config, {}); + const tables = getAllTables(configToTables(config)); attest(tables.StoreHooks).equals(storeConfig.namespaces.store.tables.StoreHooks); attest(tables.NamespaceOwner).equals(worldConfig.namespaces.world.tables.NamespaceOwner); }); diff --git a/packages/store-sync/src/zustand/getAllTables.ts b/packages/store-sync/src/getAllTables.ts similarity index 55% rename from packages/store-sync/src/zustand/getAllTables.ts rename to packages/store-sync/src/getAllTables.ts index d5ec2a4fcc..44a6691b56 100644 --- a/packages/store-sync/src/zustand/getAllTables.ts +++ b/packages/store-sync/src/getAllTables.ts @@ -1,4 +1,3 @@ -import { Store as StoreConfig } from "@latticexyz/store"; import { Tables } from "@latticexyz/config"; import storeConfig from "@latticexyz/store/mud.config"; import worldConfig from "@latticexyz/world/mud.config"; @@ -12,18 +11,11 @@ const mudTables = { }; // TODO: validate that extraTables keys correspond to table labels? -export type getAllTables = merge< - configToTables, - merge ->; +export type getAllTables = merge; -export function getAllTables( - config: config, - extraTables: extraTables, -): show> { +export function getAllTables(tables: tables): show> { return { - ...configToTables(config), - ...extraTables, + ...tables, ...mudTables, } as never; } diff --git a/packages/store-sync/src/recs/createStorageAdapter.ts b/packages/store-sync/src/recs/createStorageAdapter.ts index 4213af8651..232349cdf3 100644 --- a/packages/store-sync/src/recs/createStorageAdapter.ts +++ b/packages/store-sync/src/recs/createStorageAdapter.ts @@ -1,4 +1,4 @@ -import { Table } from "@latticexyz/config"; +import { Tables } from "@latticexyz/config"; import { debug } from "./debug"; import { World as RecsWorld, getComponentValue, hasComponent, removeComponent, setComponent } from "@latticexyz/recs"; import { defineInternalComponents } from "./defineInternalComponents"; @@ -11,40 +11,32 @@ import { logToTable } from "../logToTable"; import { hexKeyTupleToEntity } from "./hexKeyTupleToEntity"; import { StorageAdapter, StorageAdapterBlock } from "../common"; import { singletonEntity } from "./singletonEntity"; -import storeConfig from "@latticexyz/store/mud.config"; -import worldConfig from "@latticexyz/world/mud.config"; import { tablesToComponents } from "./tablesToComponents"; +import { getAllTables } from "../getAllTables"; +import { merge } from "@arktype/util"; -const storeTables = storeConfig.tables; -const worldTables = worldConfig.tables; - -export type CreateStorageAdapterOptions> = { +export type CreateStorageAdapterOptions = { world: RecsWorld; tables: tables; shouldSkipUpdateStream?: () => boolean; }; -export type CreateStorageAdapterResult> = { +export type CreateStorageAdapterResult = { storageAdapter: StorageAdapter; - components: tablesToComponents & - tablesToComponents & - tablesToComponents & - ReturnType; + components: merge>, ReturnType>; }; -export function createStorageAdapter>({ +export function createStorageAdapter({ world, tables, shouldSkipUpdateStream, }: CreateStorageAdapterOptions): CreateStorageAdapterResult { world.registerEntity({ id: singletonEntity }); - const components = { - ...tablesToComponents(world, tables), - ...tablesToComponents(world, storeTables), - ...tablesToComponents(world, worldTables), + const components: CreateStorageAdapterResult["components"] = { + ...tablesToComponents(world, getAllTables(tables)), ...defineInternalComponents(world), - }; + } as never; async function recsStorageAdapter({ logs }: StorageAdapterBlock): Promise { const newTables = logs.filter(isTableRegistrationLog).map(logToTable); diff --git a/packages/store-sync/src/recs/syncToRecs.ts b/packages/store-sync/src/recs/syncToRecs.ts index e8f63f7d6d..f043cb899a 100644 --- a/packages/store-sync/src/recs/syncToRecs.ts +++ b/packages/store-sync/src/recs/syncToRecs.ts @@ -1,4 +1,4 @@ -import { Table } from "@latticexyz/config"; +import { Tables } from "@latticexyz/config"; import { Store as StoreConfig } from "@latticexyz/store"; import { Component as RecsComponent, World as RecsWorld, getComponentValue, setComponent } from "@latticexyz/recs"; import { SyncOptions, SyncResult } from "../common"; @@ -6,30 +6,34 @@ import { CreateStorageAdapterResult, createStorageAdapter } from "./createStorag import { createStoreSync } from "../createStoreSync"; import { singletonEntity } from "./singletonEntity"; import { SyncStep } from "../SyncStep"; +import { getAllTables } from "../getAllTables"; +import { configToTables } from "../configToTables"; +import { merge } from "@arktype/util"; -type SyncToRecsOptions> = SyncOptions & { +type SyncToRecsOptions = SyncOptions & { world: RecsWorld; config: config; tables?: extraTables; startSync?: boolean; }; -type SyncToRecsResult> = SyncResult & { - components: CreateStorageAdapterResult["components"]; +type SyncToRecsResult = SyncResult & { + components: CreateStorageAdapterResult, extraTables>>>["components"]; stopSync: () => void; }; -export async function syncToRecs>({ +export async function syncToRecs({ world, config, tables: extraTables, startSync = true, ...syncOptions }: SyncToRecsOptions): Promise> { - const tables = { - ...config.tables, + const tables: getAllTables, extraTables>> = getAllTables({ + // TODO: rework SyncToRecsOption intersection to remove config being possibly undefined + ...configToTables(config as config), ...extraTables, - } as config["tables"] & extraTables; + }) as never; const { storageAdapter, components } = createStorageAdapter({ world, diff --git a/packages/store-sync/src/recs/tablesToComponents.ts b/packages/store-sync/src/recs/tablesToComponents.ts index a3634c4e99..378273f6f9 100644 --- a/packages/store-sync/src/recs/tablesToComponents.ts +++ b/packages/store-sync/src/recs/tablesToComponents.ts @@ -1,15 +1,16 @@ -import { Table } from "@latticexyz/config"; +import { Tables } from "@latticexyz/config"; import { tableToComponent } from "./tableToComponent"; import { World } from "@latticexyz/recs"; +import { show } from "@arktype/util"; -export type tablesToComponents> = { +export type tablesToComponents = { [label in keyof tables as tables[label]["label"]]: tableToComponent; }; -export function tablesToComponents>( +export function tablesToComponents( world: World, tables: tables, -): tablesToComponents { +): show> { return Object.fromEntries( Object.entries(tables).map(([, table]) => [table.label, tableToComponent(world, table)]), ) as never; diff --git a/packages/store-sync/src/zustand/syncToZustand.ts b/packages/store-sync/src/zustand/syncToZustand.ts index 61e75fd2ed..01a6171940 100644 --- a/packages/store-sync/src/zustand/syncToZustand.ts +++ b/packages/store-sync/src/zustand/syncToZustand.ts @@ -7,7 +7,9 @@ import { Address } from "viem"; import { SyncStep } from "../SyncStep"; import { Store as StoreConfig } from "@latticexyz/store"; import { Tables } from "@latticexyz/config"; -import { getAllTables } from "./getAllTables"; +import { getAllTables } from "../getAllTables"; +import { merge } from "@arktype/util"; +import { configToTables } from "../configToTables"; type SyncToZustandOptions = Omit< SyncOptions, @@ -17,13 +19,13 @@ type SyncToZustandOptions>; + store?: ZustandStore, extraTables>>>; startSync?: boolean; }; type SyncToZustandResult = SyncResult & { - tables: getAllTables; - useStore: ZustandStore>; + tables: getAllTables, extraTables>>; + useStore: ZustandStore, extraTables>>>; stopSync: () => void; }; @@ -34,7 +36,10 @@ export async function syncToZustand): Promise> { - const tables = getAllTables(config, extraTables); + const tables: getAllTables, extraTables>> = getAllTables({ + ...configToTables(config), + ...extraTables, + }); const useStore = store ?? createStore({ tables }); const storageAdapter = createStorageAdapter({ store: useStore }); diff --git a/packages/store/ts/config/v2/input.ts b/packages/store/ts/config/v2/input.ts index 7a721c9503..058b07bba1 100644 --- a/packages/store/ts/config/v2/input.ts +++ b/packages/store/ts/config/v2/input.ts @@ -88,5 +88,5 @@ export type TablesWithShorthandsInput = { }; export type StoreWithShorthandsInput = show< - Omit & { readonly tables: TablesWithShorthandsInput } + Omit & { readonly tables?: TablesWithShorthandsInput } >; diff --git a/packages/store/ts/config/v2/store.test.ts b/packages/store/ts/config/v2/store.test.ts index 44c0f1037a..55eff2a974 100644 --- a/packages/store/ts/config/v2/store.test.ts +++ b/packages/store/ts/config/v2/store.test.ts @@ -516,6 +516,11 @@ describe("defineStore", () => { attest>(); }); + it("should accept an empty input", () => { + const config = defineStore({}); + attest>(); + }); + it("should use the global namespace instead for tables", () => { const config = defineStore({ namespace: "namespace", diff --git a/packages/store/ts/config/v2/storeWithShorthands.test.ts b/packages/store/ts/config/v2/storeWithShorthands.test.ts index ba266970c3..963e4e4c52 100644 --- a/packages/store/ts/config/v2/storeWithShorthands.test.ts +++ b/packages/store/ts/config/v2/storeWithShorthands.test.ts @@ -56,7 +56,7 @@ describe("defineStoreWithShorthands", () => { }); it("should satisfy the output type", () => { - const config = defineStore({ + const config = defineStoreWithShorthands({ tables: { Name: { schema: { id: "address" }, key: ["id"] } }, userTypes: { CustomType: { type: "address", filePath: "path/to/file" } }, }); @@ -64,6 +64,11 @@ describe("defineStoreWithShorthands", () => { attest>(); }); + it("should accept an empty input", () => { + const config = defineStoreWithShorthands({}); + attest>(); + }); + it("should accept a user type as input and expand it", () => { const config = defineStoreWithShorthands({ tables: { Name: "CustomType" }, diff --git a/packages/store/ts/config/v2/storeWithShorthands.ts b/packages/store/ts/config/v2/storeWithShorthands.ts index c5bfeacaea..37b1bb5472 100644 --- a/packages/store/ts/config/v2/storeWithShorthands.ts +++ b/packages/store/ts/config/v2/storeWithShorthands.ts @@ -32,11 +32,14 @@ export function resolveStoreWithShorthands { const scope = extendedScope(store); + const tables = store.tables + ? mapObject(store.tables, (table) => { + return isTableShorthandInput(table) ? resolveTableShorthand(table, scope) : table; + }) + : null; const fullConfig = { ...store, - tables: mapObject(store.tables, (table) => { - return isTableShorthandInput(table) ? resolveTableShorthand(table, scope) : table; - }), + ...(tables ? { tables } : null), }; validateStore(fullConfig); From 8e09362741b510cf2673ec1e449380abc08a3aa2 Mon Sep 17 00:00:00 2001 From: Kevin Ingersoll Date: Sat, 20 Jul 2024 10:12:54 +0100 Subject: [PATCH 15/26] ensure no overlapping table labels between store/world --- packages/store-sync/src/getAllTables.test.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/packages/store-sync/src/getAllTables.test.ts b/packages/store-sync/src/getAllTables.test.ts index b27a05da2a..c54e0938ce 100644 --- a/packages/store-sync/src/getAllTables.test.ts +++ b/packages/store-sync/src/getAllTables.test.ts @@ -13,6 +13,14 @@ describe("getAllTables", () => { attest, satisfy>>(); }); + it("has no overlapping table labels", () => { + // TODO: is there a better way to write this test? + attest< + true, + keyof configToTables & keyof configToTables extends never ? true : false + >(); + }); + it("returns combined tables", () => { const config = defineWorld({ namespace: "app", From d0792d4e2bdf582e088cb49b070dfd1250a2bff9 Mon Sep 17 00:00:00 2001 From: Kevin Ingersoll Date: Sat, 20 Jul 2024 10:19:09 +0100 Subject: [PATCH 16/26] omit --- packages/store-sync/src/recs/syncToRecs.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/store-sync/src/recs/syncToRecs.ts b/packages/store-sync/src/recs/syncToRecs.ts index f043cb899a..4d75c6ed6d 100644 --- a/packages/store-sync/src/recs/syncToRecs.ts +++ b/packages/store-sync/src/recs/syncToRecs.ts @@ -10,7 +10,7 @@ import { getAllTables } from "../getAllTables"; import { configToTables } from "../configToTables"; import { merge } from "@arktype/util"; -type SyncToRecsOptions = SyncOptions & { +type SyncToRecsOptions = Omit & { world: RecsWorld; config: config; tables?: extraTables; @@ -30,8 +30,7 @@ export async function syncToRecs): Promise> { const tables: getAllTables, extraTables>> = getAllTables({ - // TODO: rework SyncToRecsOption intersection to remove config being possibly undefined - ...configToTables(config as config), + ...configToTables(config), ...extraTables, }) as never; From 90935c28b032d3aa847a4d205454d3a5e619f8e4 Mon Sep 17 00:00:00 2001 From: Kevin Ingersoll Date: Sat, 20 Jul 2024 15:55:22 +0100 Subject: [PATCH 17/26] clean up --- packages/store-sync/src/common.test.ts | 15 ++++++ packages/store-sync/src/common.ts | 21 ++++---- packages/store-sync/src/getAllTables.test.ts | 51 ------------------- packages/store-sync/src/getAllTables.ts | 21 -------- .../src/recs/createStorageAdapter.ts | 7 ++- packages/store-sync/src/recs/syncToRecs.ts | 16 +++--- .../store-sync/src/zustand/syncToZustand.ts | 18 +++---- test/ts-benchmarks/bench.ts | 2 +- 8 files changed, 46 insertions(+), 105 deletions(-) create mode 100644 packages/store-sync/src/common.test.ts delete mode 100644 packages/store-sync/src/getAllTables.test.ts delete mode 100644 packages/store-sync/src/getAllTables.ts diff --git a/packages/store-sync/src/common.test.ts b/packages/store-sync/src/common.test.ts new file mode 100644 index 0000000000..144f84346e --- /dev/null +++ b/packages/store-sync/src/common.test.ts @@ -0,0 +1,15 @@ +import { describe, it } from "vitest"; +import { attest } from "@arktype/attest"; +import storeConfig from "@latticexyz/store/mud.config"; +import worldConfig from "@latticexyz/world/mud.config"; +import { configToTables } from "./configToTables"; + +describe("mudTables", () => { + it("has no overlapping table labels", () => { + // TODO: is there a better way to write this test? + attest< + true, + keyof configToTables & keyof configToTables extends never ? true : false + >(); + }); +}); diff --git a/packages/store-sync/src/common.ts b/packages/store-sync/src/common.ts index 4ecfe26fd9..48349ee83a 100644 --- a/packages/store-sync/src/common.ts +++ b/packages/store-sync/src/common.ts @@ -12,16 +12,15 @@ import storeConfig from "@latticexyz/store/mud.config"; import worldConfig from "@latticexyz/world/mud.config"; import { Store as StoreConfig } from "@latticexyz/store"; import { Table as ConfigTable, Schema } from "@latticexyz/config"; +import { configToTables } from "./configToTables"; -export const storeTables = storeConfig.tables; -export type storeTables = typeof storeTables; - -export const worldTables = worldConfig.tables; -export type worldTables = typeof worldTables; +export const mudTables = { + ...configToTables(storeConfig), + ...configToTables(worldConfig), +}; +export type mudTables = typeof mudTables; -export const internalTableIds = [...Object.values(storeTables), ...Object.values(worldTables)].map( - (table) => table.tableId, -); +export const internalTableIds = Object.values(mudTables).map((table) => table.tableId); export type ChainId = number; export type WorldId = `${ChainId}:${Address}`; @@ -137,7 +136,7 @@ export type StorageAdapterBlock = { blockNumber: BlockLogs["blockNumber"]; logs: export type StorageAdapter = (block: StorageAdapterBlock) => Promise; export const schemasTable = { - ...storeTables.store__Tables, - keySchema: getSchemaTypes(getKeySchema(storeTables.store__Tables)), - valueSchema: getSchemaTypes(getValueSchema(storeTables.store__Tables)), + ...mudTables.Tables, + keySchema: getSchemaTypes(getKeySchema(mudTables.Tables)), + valueSchema: getSchemaTypes(getValueSchema(mudTables.Tables)), }; diff --git a/packages/store-sync/src/getAllTables.test.ts b/packages/store-sync/src/getAllTables.test.ts deleted file mode 100644 index c54e0938ce..0000000000 --- a/packages/store-sync/src/getAllTables.test.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { describe, it } from "vitest"; -import { defineWorld } from "@latticexyz/world"; -import { attest } from "@arktype/attest"; -import { getAllTables } from "./getAllTables"; -import { Tables } from "@latticexyz/config"; -import storeConfig from "@latticexyz/store/mud.config"; -import worldConfig from "@latticexyz/world/mud.config"; -import { satisfy } from "@arktype/util"; -import { configToTables } from "./configToTables"; - -describe("getAllTables", () => { - it("type satisfies Tables", () => { - attest, satisfy>>(); - }); - - it("has no overlapping table labels", () => { - // TODO: is there a better way to write this test? - attest< - true, - keyof configToTables & keyof configToTables extends never ? true : false - >(); - }); - - it("returns combined tables", () => { - const config = defineWorld({ - namespace: "app", - tables: { - ExceedsResourceNameSizeLimit: "bytes32", - Table2: "address", - }, - }); - const tables = getAllTables(configToTables(config)); - attest>(); - - type expectedKeys = "ExceedsResourceNameSizeLimit" | "Table2" | "StoreHooks" | "NamespaceOwner"; - attest(); - }); - - it("prioritizes MUD tables over user defined ones", () => { - const config = defineWorld({ - namespace: "app", - tables: { - StoreHooks: "bool", - NamespaceOwner: "bool", - }, - }); - const tables = getAllTables(configToTables(config)); - attest(tables.StoreHooks).equals(storeConfig.namespaces.store.tables.StoreHooks); - attest(tables.NamespaceOwner).equals(worldConfig.namespaces.world.tables.NamespaceOwner); - }); -}); diff --git a/packages/store-sync/src/getAllTables.ts b/packages/store-sync/src/getAllTables.ts deleted file mode 100644 index 44a6691b56..0000000000 --- a/packages/store-sync/src/getAllTables.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { Tables } from "@latticexyz/config"; -import storeConfig from "@latticexyz/store/mud.config"; -import worldConfig from "@latticexyz/world/mud.config"; -import { configToTables } from "./configToTables"; -import { merge, show } from "@arktype/util"; - -type mudTables = merge, configToTables>; -const mudTables = { - ...configToTables(storeConfig), - ...configToTables(worldConfig), -}; - -// TODO: validate that extraTables keys correspond to table labels? -export type getAllTables = merge; - -export function getAllTables(tables: tables): show> { - return { - ...tables, - ...mudTables, - } as never; -} diff --git a/packages/store-sync/src/recs/createStorageAdapter.ts b/packages/store-sync/src/recs/createStorageAdapter.ts index 232349cdf3..3bc7ea236b 100644 --- a/packages/store-sync/src/recs/createStorageAdapter.ts +++ b/packages/store-sync/src/recs/createStorageAdapter.ts @@ -9,10 +9,9 @@ import { Hex, size } from "viem"; import { isTableRegistrationLog } from "../isTableRegistrationLog"; import { logToTable } from "../logToTable"; import { hexKeyTupleToEntity } from "./hexKeyTupleToEntity"; -import { StorageAdapter, StorageAdapterBlock } from "../common"; +import { StorageAdapter, StorageAdapterBlock, mudTables } from "../common"; import { singletonEntity } from "./singletonEntity"; import { tablesToComponents } from "./tablesToComponents"; -import { getAllTables } from "../getAllTables"; import { merge } from "@arktype/util"; export type CreateStorageAdapterOptions = { @@ -23,7 +22,7 @@ export type CreateStorageAdapterOptions = { export type CreateStorageAdapterResult = { storageAdapter: StorageAdapter; - components: merge>, ReturnType>; + components: merge>, ReturnType>; }; export function createStorageAdapter({ @@ -34,7 +33,7 @@ export function createStorageAdapter({ world.registerEntity({ id: singletonEntity }); const components: CreateStorageAdapterResult["components"] = { - ...tablesToComponents(world, getAllTables(tables)), + ...tablesToComponents(world, { ...tables, ...mudTables }), ...defineInternalComponents(world), } as never; diff --git a/packages/store-sync/src/recs/syncToRecs.ts b/packages/store-sync/src/recs/syncToRecs.ts index 4d75c6ed6d..8b922382d8 100644 --- a/packages/store-sync/src/recs/syncToRecs.ts +++ b/packages/store-sync/src/recs/syncToRecs.ts @@ -1,24 +1,23 @@ import { Tables } from "@latticexyz/config"; import { Store as StoreConfig } from "@latticexyz/store"; import { Component as RecsComponent, World as RecsWorld, getComponentValue, setComponent } from "@latticexyz/recs"; -import { SyncOptions, SyncResult } from "../common"; +import { SyncOptions, SyncResult, mudTables } from "../common"; import { CreateStorageAdapterResult, createStorageAdapter } from "./createStorageAdapter"; import { createStoreSync } from "../createStoreSync"; import { singletonEntity } from "./singletonEntity"; import { SyncStep } from "../SyncStep"; -import { getAllTables } from "../getAllTables"; import { configToTables } from "../configToTables"; import { merge } from "@arktype/util"; -type SyncToRecsOptions = Omit & { +export type SyncToRecsOptions = Omit & { world: RecsWorld; config: config; tables?: extraTables; startSync?: boolean; }; -type SyncToRecsResult = SyncResult & { - components: CreateStorageAdapterResult, extraTables>>>["components"]; +export type SyncToRecsResult = SyncResult & { + components: CreateStorageAdapterResult, extraTables>, mudTables>>["components"]; stopSync: () => void; }; @@ -29,10 +28,11 @@ export async function syncToRecs): Promise> { - const tables: getAllTables, extraTables>> = getAllTables({ + const tables = { ...configToTables(config), ...extraTables, - }) as never; + ...mudTables, + }; const { storageAdapter, components } = createStorageAdapter({ world, @@ -80,7 +80,7 @@ export async function syncToRecs = Omit< +export type SyncToZustandOptions = Omit< SyncOptions, "address" | "config" > & { @@ -19,13 +18,13 @@ type SyncToZustandOptions, extraTables>>>; + store?: ZustandStore, extraTables>, mudTables>>; startSync?: boolean; }; -type SyncToZustandResult = SyncResult & { - tables: getAllTables, extraTables>>; - useStore: ZustandStore, extraTables>>>; +export type SyncToZustandResult = SyncResult & { + tables: merge, extraTables>, mudTables>; + useStore: ZustandStore, extraTables>, mudTables>>; stopSync: () => void; }; @@ -36,10 +35,11 @@ export async function syncToZustand): Promise> { - const tables: getAllTables, extraTables>> = getAllTables({ + const tables: merge, extraTables>, mudTables> = { ...configToTables(config), ...extraTables, - }); + ...mudTables, + }; const useStore = store ?? createStore({ tables }); const storageAdapter = createStorageAdapter({ store: useStore }); diff --git a/test/ts-benchmarks/bench.ts b/test/ts-benchmarks/bench.ts index d0b24b509f..637c5ee6dc 100644 --- a/test/ts-benchmarks/bench.ts +++ b/test/ts-benchmarks/bench.ts @@ -28,7 +28,7 @@ bench("syncToRecs", async () => { }); return t; -}).types([21188, "instantiations"]); +}).types([21231, "instantiations"]); bench("syncToZustand", async () => { const config = defineWorld({ From 58b25cd54f345a68fa376c4aa2ae816e83935828 Mon Sep 17 00:00:00 2001 From: Kevin Ingersoll Date: Sat, 20 Jul 2024 15:57:20 +0100 Subject: [PATCH 18/26] export more types --- packages/store-sync/src/postgres-decoded/syncToPostgres.ts | 4 ++-- packages/store-sync/src/postgres/syncToPostgres.ts | 4 ++-- packages/store-sync/src/sqlite/syncToSqlite.ts | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/store-sync/src/postgres-decoded/syncToPostgres.ts b/packages/store-sync/src/postgres-decoded/syncToPostgres.ts index a413faa593..6f42469ed9 100644 --- a/packages/store-sync/src/postgres-decoded/syncToPostgres.ts +++ b/packages/store-sync/src/postgres-decoded/syncToPostgres.ts @@ -4,7 +4,7 @@ import { SyncOptions, SyncResult } from "../common"; import { createStorageAdapter } from "./createStorageAdapter"; import { createStoreSync } from "../createStoreSync"; -type SyncToPostgresOptions = SyncOptions & { +export type SyncToPostgresOptions = SyncOptions & { /** * [Postgres database object from Drizzle][0]. * @@ -15,7 +15,7 @@ type SyncToPostgresOptions = SyncOptio startSync?: boolean; }; -type SyncToPostgresResult = SyncResult & { +export type SyncToPostgresResult = SyncResult & { stopSync: () => void; }; diff --git a/packages/store-sync/src/postgres/syncToPostgres.ts b/packages/store-sync/src/postgres/syncToPostgres.ts index a413faa593..6f42469ed9 100644 --- a/packages/store-sync/src/postgres/syncToPostgres.ts +++ b/packages/store-sync/src/postgres/syncToPostgres.ts @@ -4,7 +4,7 @@ import { SyncOptions, SyncResult } from "../common"; import { createStorageAdapter } from "./createStorageAdapter"; import { createStoreSync } from "../createStoreSync"; -type SyncToPostgresOptions = SyncOptions & { +export type SyncToPostgresOptions = SyncOptions & { /** * [Postgres database object from Drizzle][0]. * @@ -15,7 +15,7 @@ type SyncToPostgresOptions = SyncOptio startSync?: boolean; }; -type SyncToPostgresResult = SyncResult & { +export type SyncToPostgresResult = SyncResult & { stopSync: () => void; }; diff --git a/packages/store-sync/src/sqlite/syncToSqlite.ts b/packages/store-sync/src/sqlite/syncToSqlite.ts index 5c32249664..406e5eb98c 100644 --- a/packages/store-sync/src/sqlite/syncToSqlite.ts +++ b/packages/store-sync/src/sqlite/syncToSqlite.ts @@ -4,7 +4,7 @@ import { SyncOptions, SyncResult } from "../common"; import { sqliteStorage } from "./sqliteStorage"; import { createStoreSync } from "../createStoreSync"; -type SyncToSqliteOptions = SyncOptions & { +export type SyncToSqliteOptions = SyncOptions & { /** * [SQLite database object from Drizzle][0]. * @@ -15,7 +15,7 @@ type SyncToSqliteOptions = SyncOptions startSync?: boolean; }; -type SyncToSqliteResult = SyncResult & { +export type SyncToSqliteResult = SyncResult & { stopSync: () => void; }; From bfb835e450581e29b67cf8abbdfc7f8341a6843d Mon Sep 17 00:00:00 2001 From: Kevin Ingersoll Date: Sat, 20 Jul 2024 16:11:46 +0100 Subject: [PATCH 19/26] don't break compat --- packages/store-sync/src/recs/createStorageAdapter.ts | 10 +++++----- packages/store-sync/src/recs/syncToRecs.ts | 11 +++++------ 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/packages/store-sync/src/recs/createStorageAdapter.ts b/packages/store-sync/src/recs/createStorageAdapter.ts index 3bc7ea236b..a029ce9b80 100644 --- a/packages/store-sync/src/recs/createStorageAdapter.ts +++ b/packages/store-sync/src/recs/createStorageAdapter.ts @@ -9,7 +9,7 @@ import { Hex, size } from "viem"; import { isTableRegistrationLog } from "../isTableRegistrationLog"; import { logToTable } from "../logToTable"; import { hexKeyTupleToEntity } from "./hexKeyTupleToEntity"; -import { StorageAdapter, StorageAdapterBlock, mudTables } from "../common"; +import { StorageAdapter, StorageAdapterBlock } from "../common"; import { singletonEntity } from "./singletonEntity"; import { tablesToComponents } from "./tablesToComponents"; import { merge } from "@arktype/util"; @@ -22,7 +22,7 @@ export type CreateStorageAdapterOptions = { export type CreateStorageAdapterResult = { storageAdapter: StorageAdapter; - components: merge>, ReturnType>; + components: merge, ReturnType>; }; export function createStorageAdapter({ @@ -32,10 +32,10 @@ export function createStorageAdapter({ }: CreateStorageAdapterOptions): CreateStorageAdapterResult { world.registerEntity({ id: singletonEntity }); - const components: CreateStorageAdapterResult["components"] = { - ...tablesToComponents(world, { ...tables, ...mudTables }), + const components = { + ...tablesToComponents(world, tables), ...defineInternalComponents(world), - } as never; + }; async function recsStorageAdapter({ logs }: StorageAdapterBlock): Promise { const newTables = logs.filter(isTableRegistrationLog).map(logToTable); diff --git a/packages/store-sync/src/recs/syncToRecs.ts b/packages/store-sync/src/recs/syncToRecs.ts index 8b922382d8..e7f8dc1d19 100644 --- a/packages/store-sync/src/recs/syncToRecs.ts +++ b/packages/store-sync/src/recs/syncToRecs.ts @@ -1,7 +1,7 @@ import { Tables } from "@latticexyz/config"; import { Store as StoreConfig } from "@latticexyz/store"; import { Component as RecsComponent, World as RecsWorld, getComponentValue, setComponent } from "@latticexyz/recs"; -import { SyncOptions, SyncResult, mudTables } from "../common"; +import { SyncOptions, SyncResult } from "../common"; import { CreateStorageAdapterResult, createStorageAdapter } from "./createStorageAdapter"; import { createStoreSync } from "../createStoreSync"; import { singletonEntity } from "./singletonEntity"; @@ -17,7 +17,7 @@ export type SyncToRecsOptions = SyncResult & { - components: CreateStorageAdapterResult, extraTables>, mudTables>>["components"]; + components: CreateStorageAdapterResult, extraTables>>["components"]; stopSync: () => void; }; @@ -28,11 +28,10 @@ export async function syncToRecs): Promise> { - const tables = { + const tables: merge, extraTables> = { ...configToTables(config), ...extraTables, - ...mudTables, - }; + } as never; const { storageAdapter, components } = createStorageAdapter({ world, @@ -80,7 +79,7 @@ export async function syncToRecs Date: Sat, 20 Jul 2024 16:20:54 +0100 Subject: [PATCH 20/26] fix components, make it more consistent --- packages/store-sync/src/recs/syncToRecs.ts | 10 +++++----- packages/store-sync/src/zustand/syncToZustand.ts | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/store-sync/src/recs/syncToRecs.ts b/packages/store-sync/src/recs/syncToRecs.ts index e7f8dc1d19..5756657cce 100644 --- a/packages/store-sync/src/recs/syncToRecs.ts +++ b/packages/store-sync/src/recs/syncToRecs.ts @@ -21,17 +21,17 @@ export type SyncToRecsResult void; }; -export async function syncToRecs({ +export async function syncToRecs({ world, config, - tables: extraTables, + tables: extraTables = {} as extraTables, startSync = true, ...syncOptions }: SyncToRecsOptions): Promise> { - const tables: merge, extraTables> = { + const tables = { ...configToTables(config), ...extraTables, - } as never; + }; const { storageAdapter, components } = createStorageAdapter({ world, @@ -81,5 +81,5 @@ export async function syncToRecs = Omit< +export type SyncToZustandOptions = Omit< SyncOptions, "address" | "config" > & { @@ -22,7 +22,7 @@ export type SyncToZustandOptions = SyncResult & { +export type SyncToZustandResult = SyncResult & { tables: merge, extraTables>, mudTables>; useStore: ZustandStore, extraTables>, mudTables>>; stopSync: () => void; From d4730349a1195fa938fa24211a6bb62222ae69cf Mon Sep 17 00:00:00 2001 From: Kevin Ingersoll Date: Sat, 20 Jul 2024 16:31:05 +0100 Subject: [PATCH 21/26] restore mud tables --- packages/store-sync/src/recs/syncToRecs.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/store-sync/src/recs/syncToRecs.ts b/packages/store-sync/src/recs/syncToRecs.ts index 5756657cce..891d3309f0 100644 --- a/packages/store-sync/src/recs/syncToRecs.ts +++ b/packages/store-sync/src/recs/syncToRecs.ts @@ -1,7 +1,7 @@ import { Tables } from "@latticexyz/config"; import { Store as StoreConfig } from "@latticexyz/store"; import { Component as RecsComponent, World as RecsWorld, getComponentValue, setComponent } from "@latticexyz/recs"; -import { SyncOptions, SyncResult } from "../common"; +import { SyncOptions, SyncResult, mudTables } from "../common"; import { CreateStorageAdapterResult, createStorageAdapter } from "./createStorageAdapter"; import { createStoreSync } from "../createStoreSync"; import { singletonEntity } from "./singletonEntity"; @@ -17,7 +17,7 @@ export type SyncToRecsOptions = SyncResult & { - components: CreateStorageAdapterResult, extraTables>>["components"]; + components: CreateStorageAdapterResult, extraTables>, mudTables>>["components"]; stopSync: () => void; }; @@ -31,6 +31,7 @@ export async function syncToRecs Date: Sat, 20 Jul 2024 08:43:15 -0700 Subject: [PATCH 22/26] Create khaki-wolves-perform.md --- .changeset/khaki-wolves-perform.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 .changeset/khaki-wolves-perform.md diff --git a/.changeset/khaki-wolves-perform.md b/.changeset/khaki-wolves-perform.md new file mode 100644 index 0000000000..fb57c56217 --- /dev/null +++ b/.changeset/khaki-wolves-perform.md @@ -0,0 +1,18 @@ +--- +"@latticexyz/store-sync": patch +--- + +Refactored `syncToRecs` and `syncToZustand` to use tables from config namespaces output. This is a precursor for supporting multiple namespaces. + +Note for library authors: If you were using `createStorageAdapter` from `@latticexyz/store-sync/recs`, this helper no longer appends MUD's built-in tables from Store and World packages. This behavior was moved into `syncToRecs` for consistency with `syncToZustand` and makes `createStorageAdapter` less opinionated. + +```diff + import { createStorageAdapter } from "@latticexyz/store-sync/recs"; ++import { mudTables } from "@latticexyz/store-sync"; + + createStorageAdapter({ +- tables, ++ tables: { ...tables, ...mudTables }, + ... + }); +``` From d2ff2d6b6d69dabc5f0e75c655a7a02766c7d726 Mon Sep 17 00:00:00 2001 From: Kevin Ingersoll Date: Sat, 20 Jul 2024 16:45:27 +0100 Subject: [PATCH 23/26] make shorthand expansion more consistent --- packages/store-sync/src/index.ts | 1 + .../store/ts/config/v2/storeWithShorthands.ts | 1 + .../world/ts/config/v2/worldWithShorthands.ts | 15 ++++++++++----- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/packages/store-sync/src/index.ts b/packages/store-sync/src/index.ts index 7efbf9258d..b69f95f5ce 100644 --- a/packages/store-sync/src/index.ts +++ b/packages/store-sync/src/index.ts @@ -1,4 +1,5 @@ export * from "./common"; +export * from "./configToTables"; export * from "./createStoreSync"; export * from "./SyncStep"; export * from "./isTableRegistrationLog"; diff --git a/packages/store/ts/config/v2/storeWithShorthands.ts b/packages/store/ts/config/v2/storeWithShorthands.ts index 37b1bb5472..74413c6127 100644 --- a/packages/store/ts/config/v2/storeWithShorthands.ts +++ b/packages/store/ts/config/v2/storeWithShorthands.ts @@ -37,6 +37,7 @@ export function resolveStoreWithShorthands { const scope = extendedScope(world); - const tables = mapObject(world.tables ?? {}, (table) => { - return isTableShorthandInput(table) ? resolveTableShorthand(table, scope) : table; - }); + const tables = world.tables + ? mapObject(world.tables, (table) => { + return isTableShorthandInput(table) ? resolveTableShorthand(table, scope) : table; + }) + : null; - const fullConfig = { ...world, tables }; - validateWorld(fullConfig); + const fullConfig = { + ...world, + ...(tables ? { tables } : null), + }; + validateWorld(fullConfig); return resolveWorld(fullConfig) as never; } From a857402895cbdc0277994e2fdc1e858aef98fdde Mon Sep 17 00:00:00 2001 From: Kevin Ingersoll Date: Sat, 20 Jul 2024 08:46:56 -0700 Subject: [PATCH 24/26] Update khaki-wolves-perform.md --- .changeset/khaki-wolves-perform.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.changeset/khaki-wolves-perform.md b/.changeset/khaki-wolves-perform.md index fb57c56217..f580f34c24 100644 --- a/.changeset/khaki-wolves-perform.md +++ b/.changeset/khaki-wolves-perform.md @@ -6,6 +6,8 @@ Refactored `syncToRecs` and `syncToZustand` to use tables from config namespaces Note for library authors: If you were using `createStorageAdapter` from `@latticexyz/store-sync/recs`, this helper no longer appends MUD's built-in tables from Store and World packages. This behavior was moved into `syncToRecs` for consistency with `syncToZustand` and makes `createStorageAdapter` less opinionated. +You can achieve the previous behavior with: + ```diff import { createStorageAdapter } from "@latticexyz/store-sync/recs"; +import { mudTables } from "@latticexyz/store-sync"; From 646b479a1a81bcca991a22588dd3ec164177da4d Mon Sep 17 00:00:00 2001 From: Kevin Ingersoll Date: Sat, 20 Jul 2024 16:48:47 +0100 Subject: [PATCH 25/26] as const --- packages/store-sync/src/common.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/store-sync/src/common.ts b/packages/store-sync/src/common.ts index 48349ee83a..740935e2c9 100644 --- a/packages/store-sync/src/common.ts +++ b/packages/store-sync/src/common.ts @@ -17,7 +17,7 @@ import { configToTables } from "./configToTables"; export const mudTables = { ...configToTables(storeConfig), ...configToTables(worldConfig), -}; +} as const; export type mudTables = typeof mudTables; export const internalTableIds = Object.values(mudTables).map((table) => table.tableId); From 95256588fb82401df8ea645267872ae338967290 Mon Sep 17 00:00:00 2001 From: Kevin Ingersoll Date: Sat, 20 Jul 2024 16:56:57 +0100 Subject: [PATCH 26/26] better test --- packages/store-sync/src/common.test.ts | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/packages/store-sync/src/common.test.ts b/packages/store-sync/src/common.test.ts index 144f84346e..efee4e1e2f 100644 --- a/packages/store-sync/src/common.test.ts +++ b/packages/store-sync/src/common.test.ts @@ -1,15 +1,12 @@ import { describe, it } from "vitest"; import { attest } from "@arktype/attest"; +import { isDisjoint } from "@arktype/util"; import storeConfig from "@latticexyz/store/mud.config"; import worldConfig from "@latticexyz/world/mud.config"; import { configToTables } from "./configToTables"; describe("mudTables", () => { it("has no overlapping table labels", () => { - // TODO: is there a better way to write this test? - attest< - true, - keyof configToTables & keyof configToTables extends never ? true : false - >(); + attest, keyof configToTables>>(); }); });