Skip to content

Commit

Permalink
feat(config,store,world): add namespaceLabel to table config (#3039)
Browse files Browse the repository at this point in the history
  • Loading branch information
alvrs authored Aug 16, 2024
1 parent 5dafc63 commit 57bf8c3
Show file tree
Hide file tree
Showing 11 changed files with 67 additions and 12 deletions.
9 changes: 9 additions & 0 deletions .changeset/warm-carrots-compare.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
"@latticexyz/config": patch
"@latticexyz/store-sync": patch
"@latticexyz/store": patch
"@latticexyz/world": patch
---

Add a strongly typed `namespaceLabel` to the table config output.
It corresponds to the `label` of the namespace the table belongs to and can't be set manually.
4 changes: 2 additions & 2 deletions packages/cli/src/deploy/getTables.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ import {
import { Schema, Table } from "@latticexyz/config";
import storeConfig from "@latticexyz/store/mud.config";

// TODO: add label once we register it onchain
type DeployedTable = Omit<Table, "label">;
// TODO: add label and namespaceLabel once we register it onchain
type DeployedTable = Omit<Table, "label" | "namespaceLabel">;

export async function getTables({
client,
Expand Down
1 change: 1 addition & 0 deletions packages/config/src/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export type Table = {
readonly label: string;
readonly type: satisfy<ResourceType, "table" | "offchainTable">;
readonly namespace: string;
readonly namespaceLabel: string;
readonly name: string;
readonly tableId: Hex;
readonly schema: Schema;
Expand Down
4 changes: 2 additions & 2 deletions packages/store-sync/src/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ export const internalTableIds = Object.values(mudTables).map((table) => table.ta
export type ChainId = number;
export type WorldId = `${ChainId}:${Address}`;

// TODO: add label once we register it onchain
export type DeployedTable = Omit<ConfigTable, "label">;
// TODO: add label and namespaceLabel once we register it onchain
export type DeployedTable = Omit<ConfigTable, "label" | "namespaceLabel">;

export type TableRecord<table extends DeployedTable = DeployedTable> = {
readonly key: getSchemaPrimitives<getKeySchema<table>>;
Expand Down
4 changes: 4 additions & 0 deletions packages/store-sync/src/zustand/createStorageAdapter.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ describe("createStorageAdapter", async () => {
"label": "Position",
"name": "Position",
"namespace": "",
"namespaceLabel": "",
"schema": {
"player": {
"internalType": "address",
Expand Down Expand Up @@ -113,6 +114,7 @@ describe("createStorageAdapter", async () => {
"label": "Position",
"name": "Position",
"namespace": "",
"namespaceLabel": "",
"schema": {
"player": {
"internalType": "address",
Expand Down Expand Up @@ -164,6 +166,7 @@ describe("createStorageAdapter", async () => {
"label": "Position",
"name": "Position",
"namespace": "",
"namespaceLabel": "",
"schema": {
"player": {
"internalType": "address",
Expand Down Expand Up @@ -215,6 +218,7 @@ describe("createStorageAdapter", async () => {
"label": "Position",
"name": "Position",
"namespace": "",
"namespaceLabel": "",
"schema": {
"player": {
"internalType": "address",
Expand Down
7 changes: 6 additions & 1 deletion packages/store/ts/config/v2/input.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ export type TableInput = {
* Defaults to the nearest namespace in the config or root namespace if not set.
*/
readonly namespace?: string;
/**
* Human-readable namespace label.
* Defaults to the nearest namespace in the config or root namespace if not set.
*/
readonly namespaceLabel?: string;
/**
* Table name used in table's resource ID.
* Defaults to the first 16 characters of `label` if not set.
Expand All @@ -47,7 +52,7 @@ export type TableShorthandInput = SchemaInput | string;
export type TablesInput = {
// remove label and namespace as these are set contextually
// and allow defining a table using shorthand
readonly [label: string]: Omit<TableInput, "label" | "namespace"> | TableShorthandInput;
readonly [label: string]: Omit<TableInput, "label" | "namespace" | "namespaceLabel"> | TableShorthandInput;
};

export type CodegenInput = Partial<Codegen>;
Expand Down
10 changes: 5 additions & 5 deletions packages/store/ts/config/v2/namespace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export type resolveNamespace<input, scope extends Scope = AbiTypeScope> = input
{
readonly [label in keyof input["tables"]]: mergeIfUndefined<
expandTableShorthand<input["tables"][label]>,
{ readonly namespace: string }
{ readonly namespace: string; readonly namespaceLabel: input["label"] }
>;
},
scope
Expand All @@ -49,14 +49,14 @@ export function resolveNamespace<const input extends NamespaceInput, scope exten
input: input,
scope: scope = AbiTypeScope as never,
): resolveNamespace<input, scope> {
const label = input.label;
const namespace = input.namespace ?? label.slice(0, 14);
const namespaceLabel = input.label;
const namespace = input.namespace ?? namespaceLabel.slice(0, 14);
return {
label,
label: namespaceLabel,
namespace,
tables: resolveTables(
flatMorph(input.tables ?? {}, (label, table) => {
return [label, mergeIfUndefined(expandTableShorthand(table, scope), { namespace })];
return [label, mergeIfUndefined(expandTableShorthand(table, scope), { namespace, namespaceLabel })];
}),
scope,
),
Expand Down
8 changes: 8 additions & 0 deletions packages/store/ts/config/v2/store.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ describe("defineStore", () => {
label: "Example",
type: "table",
namespace: "",
namespaceLabel: "",
name: "Example",
tableId: "0x746200000000000000000000000000004578616d706c65000000000000000000",
schema: {
Expand All @@ -47,6 +48,7 @@ describe("defineStore", () => {
label: "Example",
type: "table",
namespace: "",
namespaceLabel: "",
name: "Example",
tableId: "0x746200000000000000000000000000004578616d706c65000000000000000000",
schema: {
Expand Down Expand Up @@ -80,6 +82,7 @@ describe("defineStore", () => {
readonly Example: {
readonly label: "Example"
readonly type: "table"
readonly namespaceLabel: ""
readonly namespace: string
readonly name: string
readonly tableId: \`0x\${string}\`
Expand Down Expand Up @@ -113,6 +116,7 @@ describe("defineStore", () => {
readonly Example: {
readonly label: "Example"
readonly type: "table"
readonly namespaceLabel: ""
readonly namespace: string
readonly name: string
readonly tableId: \`0x\${string}\`
Expand Down Expand Up @@ -180,6 +184,7 @@ describe("defineStore", () => {
label: "Example",
type: "table",
namespace: "",
namespaceLabel: "root",
name: "Example",
tableId: "0x746200000000000000000000000000004578616d706c65000000000000000000",
schema: {
Expand All @@ -199,6 +204,7 @@ describe("defineStore", () => {
label: "Example",
type: "table",
namespace: "",
namespaceLabel: "root",
name: "Example",
tableId: "0x746200000000000000000000000000004578616d706c65000000000000000000",
schema: {
Expand Down Expand Up @@ -232,6 +238,7 @@ describe("defineStore", () => {
readonly Example: {
readonly label: "Example"
readonly type: "table"
readonly namespaceLabel: "root"
readonly namespace: string
readonly name: string
readonly tableId: \`0x\${string}\`
Expand Down Expand Up @@ -265,6 +272,7 @@ describe("defineStore", () => {
readonly root__Example: {
readonly label: "Example"
readonly type: "table"
readonly namespaceLabel: "root"
readonly namespace: string
readonly name: string
readonly tableId: \`0x\${string}\`
Expand Down
3 changes: 3 additions & 0 deletions packages/store/ts/config/v2/table.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ describe("resolveTable", () => {
label: "",
type: "table",
namespace: "" as string,
namespaceLabel: "",
name: "" as string,
tableId: resourceToHex({ type: "table", namespace: "", name: "" }),
schema: {
Expand All @@ -82,6 +83,7 @@ describe("resolveTable", () => {
label: "",
type: "table",
namespace: "" as string,
namespaceLabel: "",
name: "" as string,
tableId: resourceToHex({ type: "table", namespace: "", name: "" }),
schema: {
Expand Down Expand Up @@ -113,6 +115,7 @@ describe("resolveTable", () => {
label: "",
type: "table",
namespace: "" as string,
namespaceLabel: "",
name: "" as string,
tableId: resourceToHex({ type: "table", namespace: "", name: "" }),
schema: {
Expand Down
21 changes: 19 additions & 2 deletions packages/store/ts/config/v2/table.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,18 @@ export function validateTable<input, scope extends Scope = AbiTypeScope>(
if (hasOwnKey(input, "namespace") && typeof input.namespace === "string" && input.namespace.length > 14) {
throw new Error(`Table \`namespace\` must fit into a \`bytes14\`, but "${input.namespace}" is too long.`);
}

if (
hasOwnKey(input, "namespaceLabel") &&
typeof input.namespaceLabel === "string" &&
(!hasOwnKey(input, "namespace") || typeof input.namespace !== "string") &&
input.namespaceLabel.length > 14
) {
throw new Error(
`Table \`namespace\` defaults to \`namespaceLabel\`, but must fit into a \`bytes14\` and "${input.namespaceLabel}" is too long. Provide explicit \`namespace\` override.`,
);
}

if (hasOwnKey(input, "name") && typeof input.name === "string" && input.name.length > 16) {
throw new Error(`Table \`name\` must fit into a \`bytes16\`, but "${input.name}" is too long.`);
}
Expand Down Expand Up @@ -140,6 +152,9 @@ export type resolveTable<input, scope extends Scope = Scope> = input extends Tab
? {
readonly label: input["label"];
readonly type: undefined extends input["type"] ? typeof TABLE_DEFAULTS.type : input["type"];
readonly namespaceLabel: undefined extends input["namespaceLabel"]
? typeof TABLE_DEFAULTS.namespace
: input["namespaceLabel"];
readonly namespace: string;
readonly name: string;
readonly tableId: Hex;
Expand All @@ -156,16 +171,18 @@ export function resolveTable<input extends TableInput, scope extends Scope = Abi
input: input,
scope: scope = AbiTypeScope as unknown as scope,
): resolveTable<input, scope> {
const namespaceLabel = input.namespaceLabel ?? TABLE_DEFAULTS.namespace;
const namespace = input.namespace ?? namespaceLabel;
const label = input.label;
const type = input.type ?? TABLE_DEFAULTS.type;
const namespace = input.namespace ?? TABLE_DEFAULTS.namespace;
const name = input.name ?? label.slice(0, 16);
const type = input.type ?? TABLE_DEFAULTS.type;
const tableId = resourceToHex({ type, namespace, name });

return {
label,
type,
namespace,
namespaceLabel,
name,
tableId,
schema: resolveSchema(input.schema, scope),
Expand Down
8 changes: 8 additions & 0 deletions packages/world/ts/config/v2/world.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ describe("defineWorld", () => {
Example: {
label: "Example",
type: "table",
namespaceLabel: "",
namespace: "",
name: "Example",
tableId: "0x746200000000000000000000000000004578616d706c65000000000000000000",
Expand All @@ -163,6 +164,7 @@ describe("defineWorld", () => {
Example: {
label: "Example",
type: "table",
namespaceLabel: "",
namespace: "",
name: "Example",
tableId: "0x746200000000000000000000000000004578616d706c65000000000000000000",
Expand Down Expand Up @@ -205,6 +207,7 @@ describe("defineWorld", () => {
readonly Example: {
readonly label: "Example"
readonly type: "table"
readonly namespaceLabel: ""
readonly namespace: string
readonly name: string
readonly tableId: \`0x\${string}\`
Expand Down Expand Up @@ -255,6 +258,7 @@ describe("defineWorld", () => {
readonly Example: {
readonly label: "Example"
readonly type: "table"
readonly namespaceLabel: ""
readonly namespace: string
readonly name: string
readonly tableId: \`0x\${string}\`
Expand Down Expand Up @@ -324,6 +328,7 @@ describe("defineWorld", () => {
Example: {
label: "Example",
type: "table",
namespaceLabel: "root",
namespace: "",
name: "Example",
tableId: "0x746200000000000000000000000000004578616d706c65000000000000000000",
Expand All @@ -344,6 +349,7 @@ describe("defineWorld", () => {
root__Example: {
label: "Example",
type: "table",
namespaceLabel: "root",
namespace: "",
name: "Example",
tableId: "0x746200000000000000000000000000004578616d706c65000000000000000000",
Expand Down Expand Up @@ -386,6 +392,7 @@ describe("defineWorld", () => {
readonly root__Example: {
readonly label: "Example"
readonly type: "table"
readonly namespaceLabel: "root"
readonly namespace: string
readonly name: string
readonly tableId: \`0x\${string}\`
Expand Down Expand Up @@ -436,6 +443,7 @@ describe("defineWorld", () => {
readonly Example: {
readonly label: "Example"
readonly type: "table"
readonly namespaceLabel: "root"
readonly namespace: string
readonly name: string
readonly tableId: \`0x\${string}\`
Expand Down

0 comments on commit 57bf8c3

Please sign in to comment.