Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for multiple namespaces in one config #994

Closed
dk1a opened this issue Jun 5, 2023 · 6 comments
Closed

Add support for multiple namespaces in one config #994

dk1a opened this issue Jun 5, 2023 · 6 comments
Assignees
Labels
refactor Clean up code without adding or removing features

Comments

@dk1a
Copy link
Contributor

dk1a commented Jun 5, 2023

I talk about tables because I think what works for them will work for systems, tables are more prevalent in the config, and systems have no sync to worry about. But u can see them both in the examples.
The examples are slightly contrived to show what happens when key and name differ

Current state

mudConfig tables have

  • Record key which represents the library name. It's used for most client stuff
  • namespace and name, which are used for on-chain tableId
  • tableId which is composed of namespace+name. It's used for all on-chain stuff

namespace is currently global (but #971 aims to change it)

Record key and name are sometimes used interchangeably (like in store-cache), but they can currently be different, which can lead to problems.

export default mudConfig({
  namespace: "",
  tables: {
    CounterTableN: {
      schema: "uint32",
    },
    // Until namespace overrides, CounterTableNamespaced must be manually deployed in PostDeploy
  },
  systems: {
    IncrementSystem: {
      name: "Increment",
      openAccess: true,
    },
  },
  excludeSystems: [
    // Until namespace overrides, this system must be manually deployed in PostDeploy
    "IncrementNamespacedSystem",
  ],
});

Solution 1

Keep table key and name separate and make the separation stronger

  1. Explicitly name table key as tableKey, and table name as name
  2. Never use them interchangeably, because they can differ
  3. Most client things would use tableKey, but some (like subscriptions) would still have name around, since sync works with the whole world and not just what's in the config
  4. Per-table namespace overrides just work (since namespace+name has to be unique, not namespace+tableKey, you won't get ambiguity even with an existing world)
  5. All on-chain things use name as before
export default mudConfig({
  namespace: "",
  tables: {
    CounterTableN: "uint32",
    CounterTableNamespaced: {
      // name can't actually be specified for tables, but it will be effectively different from tableKey because <=16 length limit
      // name: "CounterTableN"
      namespace: "namespace",
      schema: "uint32",
    }
  },
  systems: {
    IncrementSystem: {
      name: "Increment",
      openAccess: true,
    },
    IncrementNamespacedSystem: {
      namespace: "namespace",
      name: "Increment",
      openAccess: true,
    }
  },
});

Solution 2

Unify table key and name

  1. Remove name from table config
  2. name and tableKey can not differ, so have zod check that tableKey.length <= 16
  3. Everything uses name, which is also tableKey
  4. Per-table namespace overrides must be made to work , see 2.1 and 2.2
  5. All on-chain things use name as before

Sub-solution 2.1

Keep only 1 root namespace

  1. No per-table namespace overrides, you must make a separate config for a separate namespace
  2. We have to allow multiple mud.config in one package (this is a separate issue, which would particularly affect cli and client)
// first config (there're 2)
export default mudConfig({
  namespace: "",
  tables: {
    CounterTableN: "uint32",
  },
  systems: {
    Increment: {
      openAccess: true,
    },
  },
});
// second config (there're 2)
export default mudConfig({
  namespace: "namespace",
  tables: {
    CounterTableN: "uint32",
  },
  systems: {
    Increment: {
      openAccess: true,
    }
  },
});

Sub-solution 2.2

Make tables config option grouped by namespace

  1. Rather than per-table namespace, we get per-namespace table
  2. This does not depend on having multiple mud.config in one package
export default mudConfig({
  tables: {
    "": {
      CounterTableN: "uint32",
    },
    "namespace": {
      CounterTableN: "uint32",
    }
  },
  systems: {
    "": {
      Increment: {
        openAccess: true,
      },
    },
    "namespace": {
      Increment: {
        openAccess: true,
      },
    },
  },
});
@dk1a
Copy link
Contributor Author

dk1a commented Jun 5, 2023

1 seems like the simplest option that mostly preserves the status quo
2.1 strongly depends on a separate issue that's probably bigger than this one, so hard to say
2.2 I kinda like this, but for both 2.1 and 2.2 being restricted to short file names feels bad

I currently prefer 1 but may have missed something and curious about your opinions

@alvrs
Copy link
Member

alvrs commented Jun 5, 2023

One thought i'd like to throw in the pot: eventually we should have something that allows devs to "download" a mud config of an existing world (ie mud config --worldAddress 0x1234 -> generates a mud.config.ts with all the tables and systems of that world). This would improve the dev ex for extending existing worlds, because now our client libs can have strong types based on the config of the existing world.

With this in mind we'll have to find a way to support non-unique names for tables and systems. With option 1 we'd have to somehow generate a unique name for the table key, probably something like concatenating namespace and name. What I don't like about this approach is that it's harder to explain what the difference between key and name is, and what each are used for.

My personal favorite is approach 2.2, or slight variation (let's call it 2.3, see below), because it maps the concept of namespaces and names well to the datastructure being used (namespaces have to be unique, names have to be unique within a namespace).

Approach 2.3:

export default mudConfig({
  namespaces: {
    "": {
      tables: {
        CounterTableN: "uint32",
      },
      systems: {
        Increment: {
          openAccess: true
        }
      }
    },
    "namespace": {
      tables: {
        CounterTableN: "uint32"
      },
      systems: {
        Increment: {
          openAccess: true
        }
      }
    }
  }
});

Potentially we could also allow a top level "tables" / "systems" key for the root namespace, and only nest in the namespaces key for non-root namespaces, but not sure about that yet.

One nice side effect of approach 2.3 is it's possible to use the table schema shortcuts also for namespaced tables.

@holic
Copy link
Member

holic commented Jun 5, 2023

Very into the idea of 2.3, with:

  • explicit parity of table key + table name (including 16 char enforcement of both name + namespace)
  • namespace-grouped tables/systems (helps with code organization/visualization)
  • would love to see a "shortcut" of top-level tables/systems that assume namespace ""
    • or, if not, maybe we give a name to the root namespace?
    • maybe you can only use the "shortcut" if you only have root-level tables/systems (OR)

@dk1a
Copy link
Contributor Author

dk1a commented Jun 5, 2023

Good points, especially about the downloading - didn't think of that.
btw fun fact about 2.2 is I started writing it like 2.3, but then changed midway because of my status quo bias here.
I agree with 2.3, and since we seem to have consensus already I can make a PR some time soon, wanna deal with a few other things 1st though

@alvrs alvrs added the refactor Clean up code without adding or removing features label Jun 12, 2023
This was referenced Jul 6, 2023
@alvrs alvrs changed the title Proposal: what to do with tableKey, namespace, name Add support for multiple namespaces in one config Jul 10, 2023
@alvrs alvrs added this to the MUD stable milestone Jul 10, 2023
@alvrs alvrs self-assigned this Oct 6, 2023
@holic holic self-assigned this Feb 16, 2024
@holic holic removed their assignment Feb 27, 2024
@holic holic removed this from the MUD v2 stable release milestone Mar 20, 2024
@alvrs alvrs added this to the MUD 2.2 milestone Mar 28, 2024
@alvrs
Copy link
Member

alvrs commented May 21, 2024

Update: new config has type support for multiple namespaces, but not enabled yet because of codegen limitations (tables can have the same name in different namespaces, which would lead to file name conflicts). Codegen support is being added in #2840

@alvrs alvrs assigned holic and unassigned alvrs May 21, 2024
@holic holic removed their assignment May 24, 2024
@holic
Copy link
Member

holic commented Jul 29, 2024

done in #2968

@holic holic closed this as completed Jul 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
refactor Clean up code without adding or removing features
Projects
Status: Done
Status: No status
Development

Successfully merging a pull request may close this issue.

4 participants