@@ -8,12 +8,12 @@ import {
88 getSchemaTypes ,
99 getValueSchema ,
1010 getKeySchema ,
11- KeySchema ,
1211} from "@latticexyz/protocol-parser/internal" ;
1312import { debug } from "./debug" ;
1413import { getTables } from "./getTables" ;
1514import pRetry from "p-retry" ;
1615import { Table } from "@latticexyz/config" ;
16+ import { isDefined } from "@latticexyz/common/utils" ;
1717
1818export async function ensureTables ( {
1919 client,
@@ -24,15 +24,56 @@ export async function ensureTables({
2424 readonly worldDeploy : WorldDeploy ;
2525 readonly tables : readonly Table [ ] ;
2626} ) : Promise < readonly Hex [ ] > {
27- const worldTables = await getTables ( { client, worldDeploy } ) ;
28- const worldTableIds = worldTables . map ( ( table ) => table . tableId ) ;
27+ const configTables = new Map (
28+ tables . map ( ( table ) => {
29+ const keySchema = getSchemaTypes ( getKeySchema ( table ) ) ;
30+ const valueSchema = getSchemaTypes ( getValueSchema ( table ) ) ;
31+ const keySchemaHex = keySchemaToHex ( keySchema ) ;
32+ const valueSchemaHex = valueSchemaToHex ( valueSchema ) ;
33+ return [
34+ table . tableId ,
35+ {
36+ ...table ,
37+ keySchema,
38+ keySchemaHex,
39+ valueSchema,
40+ valueSchemaHex,
41+ } ,
42+ ] ;
43+ } ) ,
44+ ) ;
2945
30- const existingTables = tables . filter ( ( table ) => worldTableIds . includes ( table . tableId ) ) ;
46+ const worldTables = await getTables ( { client, worldDeploy } ) ;
47+ const existingTables = worldTables . filter ( ( { tableId } ) => configTables . has ( tableId ) ) ;
3148 if ( existingTables . length ) {
3249 debug ( "existing tables:" , existingTables . map ( resourceToLabel ) . join ( ", " ) ) ;
50+
51+ const schemaErrors = existingTables
52+ . map ( ( table ) => {
53+ const configTable = configTables . get ( table . tableId ) ! ;
54+ if ( table . keySchemaHex !== configTable . keySchemaHex || table . valueSchemaHex !== configTable . valueSchemaHex ) {
55+ return [
56+ `"${ resourceToLabel ( table ) } " table:` ,
57+ ` Registered schema: ${ JSON . stringify ( { schema : getSchemaTypes ( table . schema ) , key : table . key } ) } ` ,
58+ ` Config schema: ${ JSON . stringify ( { schema : getSchemaTypes ( configTable . schema ) , key : configTable . key } ) } ` ,
59+ ] . join ( "\n" ) ;
60+ }
61+ } )
62+ . filter ( isDefined ) ;
63+
64+ if ( schemaErrors . length ) {
65+ throw new Error (
66+ [
67+ "Table schemas are immutable, but found registered tables with a different schema than what you have configured." ,
68+ ...schemaErrors ,
69+ "You can either update your config with the registered schema or change the table name to register a new table." ,
70+ ] . join ( "\n\n" ) + "\n" ,
71+ ) ;
72+ }
3373 }
3474
35- const missingTables = tables . filter ( ( table ) => ! worldTableIds . includes ( table . tableId ) ) ;
75+ const existingTableIds = new Set ( existingTables . map ( ( { tableId } ) => tableId ) ) ;
76+ const missingTables = tables . filter ( ( table ) => ! existingTableIds . has ( table . tableId ) ) ;
3677 if ( missingTables . length ) {
3778 debug ( "registering tables:" , missingTables . map ( resourceToLabel ) . join ( ", " ) ) ;
3879 return await Promise . all (
@@ -50,7 +91,7 @@ export async function ensureTables({
5091 args : [
5192 table . tableId ,
5293 valueSchemaToFieldLayoutHex ( valueSchema ) ,
53- keySchemaToHex ( keySchema as KeySchema ) ,
94+ keySchemaToHex ( keySchema ) ,
5495 valueSchemaToHex ( valueSchema ) ,
5596 Object . keys ( keySchema ) ,
5697 Object . keys ( valueSchema ) ,
0 commit comments