Skip to content

Commit

Permalink
refactor(store,world): move/rename v2 config output types (#2432)
Browse files Browse the repository at this point in the history
  • Loading branch information
holic authored Mar 14, 2024
1 parent 6f9bdab commit dc4a48e
Show file tree
Hide file tree
Showing 20 changed files with 111 additions and 94 deletions.
7 changes: 2 additions & 5 deletions packages/query/src/common.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
import { SchemaAbiType } from "@latticexyz/schema-type";
import { ResolvedTableConfig } from "@latticexyz/store/config/v2";

export type Schema = { readonly [key: string]: { readonly type: SchemaAbiType } };
import { Table, Schema } from "@latticexyz/store/config/v2";

export type schemaAbiTypes<schema extends Schema> = {
[key in keyof schema]: schema[key]["type"];
};

export type TableRecord<table extends ResolvedTableConfig = ResolvedTableConfig> = {
export type TableRecord<table extends Table = Table> = {
readonly table: table;
readonly fields: schemaAbiTypes<table["schema"]>;
};
6 changes: 3 additions & 3 deletions packages/query/src/findSubjects.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { encodeAbiParameters } from "viem";
import { ResolvedTableConfig } from "@latticexyz/store/config/v2";
import { Table } from "@latticexyz/store/config/v2";
import { groupBy, uniqueBy } from "@latticexyz/common/utils";
import { Query, QueryResultSubject } from "./api";
import { matchesCondition } from "./matchesCondition";
Expand All @@ -9,7 +9,7 @@ import { TableRecord } from "./common";
// This also assumes we have full records, which may not always be the case and we may need some way to request records for a given table subject
// We don't carry around config types here for ease, they get handled by the wrapping `query` function

export type FindSubjectsParameters<table extends ResolvedTableConfig> = {
export type FindSubjectsParameters<table extends Table> = {
readonly records: readonly TableRecord<table>[];
readonly query: Query;
};
Expand All @@ -20,7 +20,7 @@ export type FindSubjectsResult = {

// TODO: make condition types smarter? so condition literal matches the field primitive type

export function findSubjects<table extends ResolvedTableConfig>({
export function findSubjects<table extends Table>({
records: initialRecords,
query,
}: FindSubjectsParameters<table>): FindSubjectsResult {
Expand Down
6 changes: 3 additions & 3 deletions packages/query/src/matchesCondition.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { ResolvedTableConfig } from "@latticexyz/store/config/v2";
import { Table } from "@latticexyz/store/config/v2";
import { ComparisonCondition, ConditionLiteral, QueryCondition } from "./api";
import { TableRecord } from "./common";

export type MatchedSubject<table extends ResolvedTableConfig = ResolvedTableConfig> = {
export type MatchedSubject<table extends Table = Table> = {
readonly subject: readonly string[];
readonly records: readonly TableRecord<table>[];
};
Expand All @@ -18,7 +18,7 @@ const comparisons = {

// TODO: adapt this to return matching records, not just a boolean

export function matchesCondition<table extends ResolvedTableConfig = ResolvedTableConfig>(
export function matchesCondition<table extends Table = Table>(
condition: QueryCondition,
subject: MatchedSubject<table>,
): boolean {
Expand Down
10 changes: 5 additions & 5 deletions packages/store-sync/src/query-cache/common.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ResolvedStoreConfig, ResolvedTableConfig } from "@latticexyz/store/config/v2";
import { Config, Table } from "@latticexyz/store/config/v2";
import { SchemaAbiType, SchemaAbiTypeToPrimitiveType } from "@latticexyz/schema-type";
import { ComparisonCondition, InCondition } from "@latticexyz/query";

Expand All @@ -10,11 +10,11 @@ export type subjectSchemaToPrimitive<tuple> = {
[key in keyof tuple]: tuple[key] extends SchemaAbiType ? SchemaAbiTypeToPrimitiveType<tuple[key]> : never;
};

export type Tables = ResolvedStoreConfig["tables"];
export type Tables = Config["tables"];

export type TableSubjectItem<table extends ResolvedTableConfig = ResolvedTableConfig> = keyof table["schema"];
export type TableSubjectItem<table extends Table = Table> = keyof table["schema"];

export type TableSubject<table extends ResolvedTableConfig = ResolvedTableConfig> = readonly [
export type TableSubject<table extends Table = Table> = readonly [
TableSubjectItem<table>,
...TableSubjectItem<table>[],
];
Expand All @@ -23,7 +23,7 @@ export type schemaAbiTypes<schema extends Record<string, { readonly type: Schema
[key in keyof schema]: schema[key]["type"];
};

type tableConditions<tableName extends string, table extends ResolvedTableConfig = ResolvedTableConfig> = {
type tableConditions<tableName extends string, table extends Table = Table> = {
[field in keyof table["schema"]]:
| [
`${tableName}.${field & string}`,
Expand Down
6 changes: 3 additions & 3 deletions packages/store-sync/src/query-cache/createStore.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { StoreApi, UseBoundStore, create } from "zustand";
import { ResolvedTableConfig } from "@latticexyz/store/config/v2";
import { Table } from "@latticexyz/store/config/v2";
import { Tables, schemaAbiTypes } from "./common";
import { Hex } from "viem";

export type RawTableRecord<table extends ResolvedTableConfig = ResolvedTableConfig> = {
export type RawTableRecord<table extends Table = Table> = {
readonly table: table;
/** @internal Internal unique ID */
readonly id: string;
Expand All @@ -13,7 +13,7 @@ export type RawTableRecord<table extends ResolvedTableConfig = ResolvedTableConf
readonly dynamicData: Hex;
};

export type TableRecord<table extends ResolvedTableConfig = ResolvedTableConfig> = {
export type TableRecord<table extends Table = Table> = {
readonly table: table;
/** @internal Internal unique ID */
readonly id: string;
Expand Down
4 changes: 2 additions & 2 deletions packages/store-sync/src/query-cache/getTables.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { resourceToHex } from "@latticexyz/common";
import { ResolvedStoreConfig } from "@latticexyz/store/config/v2";
import { Config } from "@latticexyz/store/config/v2";

// TODO(alvrs): table resolver doesn't yet provide `tableId` so we'll use this helper to inject it for now

export function getTables<config extends ResolvedStoreConfig>(config: config): config["tables"] {
export function getTables<config extends Config>(config: config): config["tables"] {
const tables = Object.fromEntries(
Object.entries(config.tables).map(([tableName, table]) => [
tableName,
Expand Down
6 changes: 3 additions & 3 deletions packages/store-sync/src/query-cache/syncToQueryCache.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { SyncOptions, SyncResult } from "../common";
import { createStoreSync } from "../createStoreSync";
import { Address } from "viem";
import { ResolvedStoreConfig } from "@latticexyz/store/config/v2";
import { Config } from "@latticexyz/store/config/v2";
import { createStore } from "./createStore";
import { createStorageAdapter } from "./createStorageAdapter";
import { getTables } from "./getTables";

type SyncToQueryCacheOptions<config extends ResolvedStoreConfig> = Omit<SyncOptions, "config"> & {
type SyncToQueryCacheOptions<config extends Config> = Omit<SyncOptions, "config"> & {
// require address for now to keep the data model + retrieval simpler
address: Address;
config: config;
Expand All @@ -17,7 +17,7 @@ type SyncToQueryCacheResult = SyncResult & {
stopSync: () => void;
};

export async function syncToQueryCache<config extends ResolvedStoreConfig>({
export async function syncToQueryCache<config extends Config>({
config,
startSync = true,
...syncOptions
Expand Down
1 change: 1 addition & 0 deletions packages/store/ts/config/v2/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ export * from "./tableShorthand";
export * from "./tableFull";
export * from "./table";
export * from "./store";
export * from "./output";
53 changes: 53 additions & 0 deletions packages/store/ts/config/v2/output.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { DynamicAbiType, StaticAbiType } from "@latticexyz/schema-type";
import { Hex } from "viem";

// Although we could import `SchemaAbiType` from `@latticexyz/schema-type` here, we "redefine" this here
// so that our downstream type errors give back `AbiType` instead of the union of all possible ABI types.
//
// This is a bit of a TS compiler hack and we should figure out a better long-term approach.
export type AbiType = StaticAbiType | DynamicAbiType;

export type UserTypes = {
readonly [userTypeName: string]: AbiType;
};

export type Enums = {
readonly [enumName: string]: readonly [string, ...string[]];
};

export type Schema = {
readonly [fieldName: string]: {
/** the Solidity primitive ABI type */
readonly type: AbiType;
/** the user defined type or Solidity primitive ABI type */
readonly internalType: string;
};
};

export type KeySchema = {
readonly [keyName: string]: {
/** the Solidity primitive ABI type */
readonly type: StaticAbiType;
/** the user defined type or Solidity primitive ABI type */
readonly internalType: string;
};
};

export type Table = {
readonly tableId: Hex;
readonly primaryKey: readonly string[];
readonly schema: Schema;
/** @deprecated Use `schema` and `primaryKey` */
readonly keySchema: KeySchema;
/** @deprecated Use `schema` and `primaryKey` */
readonly valueSchema: Schema;
};

export type Config = {
readonly tables: {
readonly [namespacedTableName: string]: Table;
};
readonly userTypes: UserTypes;
readonly enums: Enums;
readonly namespace: string;
};
7 changes: 4 additions & 3 deletions packages/store/ts/config/v2/schema.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { describe, it } from "vitest";
import { ResolvedSchemaConfig, resolveSchema } from "./schema";
import { resolveSchema } from "./schema";
import { Schema } from "./output";
import { extendScope, AbiTypeScope } from "./scope";
import { attest } from "@arktype/attest";

Expand Down Expand Up @@ -41,9 +42,9 @@ describe("resolveSchema", () => {
.type.errors(`Type '"NotACustomType"' is not assignable to type 'AbiType | "CustomType"'.`);
});

it("should extend the ResolvedSchema type", () => {
it("should extend the output Schema type", () => {
const scope = extendScope(AbiTypeScope, { CustomType: "address" });
const resolved = resolveSchema({ regular: "uint256", user: "CustomType" }, scope);
attest<true, typeof resolved extends ResolvedSchemaConfig ? true : false>();
attest<true, typeof resolved extends Schema ? true : false>();
});
});
21 changes: 1 addition & 20 deletions packages/store/ts/config/v2/schema.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { evaluate } from "@arktype/util";
import { AbiType, AbiTypeScope } from "./scope";
import { AbiTypeScope } from "./scope";
import { hasOwnKey } from "./generics";
import { StaticAbiType } from "@latticexyz/schema-type";

export type SchemaInput<scope extends AbiTypeScope = AbiTypeScope> = {
[key: string]: keyof scope["types"];
Expand Down Expand Up @@ -42,21 +41,3 @@ export function isSchemaInput<scope extends AbiTypeScope = AbiTypeScope>(
): input is SchemaInput<scope> {
return typeof input === "object" && input != null && Object.values(input).every((key) => hasOwnKey(scope.types, key));
}

export type ResolvedSchemaConfig = {
readonly [key: string]: {
/** the Solidity primitive ABI type */
readonly type: AbiType;
/** the user defined type or Solidity primitive ABI type */
readonly internalType: string;
};
};

export type ResolvedKeySchemaConfig = {
readonly [key: string]: {
/** the Solidity primitive ABI type */
readonly type: StaticAbiType;
/** the user defined type or Solidity primitive ABI type */
readonly internalType: string;
};
};
5 changes: 2 additions & 3 deletions packages/store/ts/config/v2/scope.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { Dict, evaluate } from "@arktype/util";
import { SchemaInput } from "./schema";
import { StaticAbiType, DynamicAbiType, schemaAbiTypes } from "@latticexyz/schema-type";

export type AbiType = StaticAbiType | DynamicAbiType;
import { StaticAbiType, schemaAbiTypes } from "@latticexyz/schema-type";
import { AbiType } from "./output";

export const EmptyScope = { types: {} } as const satisfies ScopeOptions;
export type EmptyScope = typeof EmptyScope;
Expand Down
7 changes: 4 additions & 3 deletions packages/store/ts/config/v2/store.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { describe, it } from "vitest";
import { ResolvedStoreConfig, resolveStoreConfig } from "./store";
import { resolveStoreConfig } from "./store";
import { Config } from "./output";
import { attest } from "@arktype/attest";
import { Hex } from "viem";

Expand Down Expand Up @@ -687,8 +688,8 @@ describe("resolveStoreConfig", () => {
attest<"custom">(config.namespace).equals("custom");
});

it("should extend the ResolvedStoreConfig type", () => {
it("should extend the output Config type", () => {
const config = resolveStoreConfig({ tables: { Name: "CustomType" }, userTypes: { CustomType: "address" } });
attest<true, typeof config extends ResolvedStoreConfig ? true : false>();
attest<true, typeof config extends Config ? true : false>();
});
});
17 changes: 4 additions & 13 deletions packages/store/ts/config/v2/store.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
import { Dict, evaluate, narrow } from "@arktype/util";
import { evaluate, narrow } from "@arktype/util";
import { get, hasOwnKey } from "./generics";
import { SchemaInput } from "./schema";
import { AbiType, AbiTypeScope, extendScope } from "./scope";
import { ResolvedTableConfig, TableInput, resolveTableConfig, validateTableConfig } from "./table";
import { AbiTypeScope, extendScope } from "./scope";
import { TableInput, resolveTableConfig, validateTableConfig } from "./table";
import { isSchemaAbiType } from "@latticexyz/schema-type";

export type UserTypes = Dict<string, AbiType>;
export type Enums = Dict<string, string[]>;
import { UserTypes, Enums } from "./output";

export type StoreConfigInput<userTypes extends UserTypes = UserTypes, enums extends Enums = Enums> = {
namespace?: string;
Expand Down Expand Up @@ -119,10 +117,3 @@ export function resolveStoreConfig<const input>(input: validateStoreConfig<input
namespace: hasOwnKey(input, "namespace") ? input["namespace"] : "",
} as resolveStoreConfig<input>;
}

export type ResolvedStoreConfig = {
readonly tables: Dict<string, ResolvedTableConfig>;
readonly userTypes: UserTypes;
readonly enums: Dict<string, readonly [string, ...string[]]>;
readonly namespace: string;
};
7 changes: 4 additions & 3 deletions packages/store/ts/config/v2/table.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { describe, it } from "vitest";
import { attest } from "@arktype/attest";
import { ResolvedTableConfig, resolveTableConfig } from "./table";
import { resolveTableConfig } from "./table";
import { Table } from "./output";
import { AbiTypeScope, extendScope } from "./scope";
import { Hex } from "viem";

Expand Down Expand Up @@ -372,9 +373,9 @@ describe("resolveTableConfig", () => {
.type.errors(`Type '"NotAKey"' is not assignable to type '"key" | "age"'`);
});

it("should extend the ResolvedStoreConfig type", () => {
it("should extend the output Table type", () => {
const scope = extendScope(AbiTypeScope, { CustomString: "string", CustomNumber: "uint256" });
const table = resolveTableConfig({ key: "CustomNumber", name: "CustomString", age: "CustomNumber" }, scope);
attest<true, typeof table extends ResolvedTableConfig ? true : false>();
attest<true, typeof table extends Table ? true : false>();
});
});
11 changes: 1 addition & 10 deletions packages/store/ts/config/v2/table.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { ErrorMessage, evaluate } from "@arktype/util";
import { ResolvedKeySchemaConfig, ResolvedSchemaConfig, SchemaInput } from "./schema";
import { SchemaInput } from "./schema";
import { AbiTypeScope } from "./scope";
import {
TableShorthandInput,
Expand All @@ -8,7 +8,6 @@ import {
validateTableShorthand,
} from "./tableShorthand";
import { TableFullInput, ValidKeys, isTableFullInput, resolveTableFullConfig, validateTableFull } from "./tableFull";
import { Hex } from "viem";

export type NoStaticKeyFieldError =
ErrorMessage<"Invalid schema. Expected a `key` field with a static ABI type or an explicit `primaryKey` option.">;
Expand Down Expand Up @@ -60,11 +59,3 @@ export function resolveTableConfig<input, scope extends AbiTypeScope = AbiTypeSc

throw new Error("Invalid config input");
}

export type ResolvedTableConfig = {
readonly tableId: Hex;
readonly primaryKey: readonly string[];
readonly schema: ResolvedSchemaConfig;
readonly keySchema: ResolvedKeySchemaConfig;
readonly valueSchema: ResolvedSchemaConfig;
};
1 change: 1 addition & 0 deletions packages/world/ts/config/v2/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export * from "./world";
export * from "./output";
11 changes: 11 additions & 0 deletions packages/world/ts/config/v2/output.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { Config as StoreConfig, Table } from "@latticexyz/store/config/v2";

export type Config = StoreConfig & {
readonly namespaces: {
readonly [namespace: string]: {
readonly tables: {
readonly [tableName: string]: Table;
};
};
};
};
Loading

0 comments on commit dc4a48e

Please sign in to comment.