forked from latticexyz/mud
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(store-sync): recs sync adapter (latticexyz#3486)
- Loading branch information
Showing
11 changed files
with
196 additions
and
84 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
--- | ||
"@latticexyz/store-sync": patch | ||
--- | ||
|
||
Added an RECS sync adapter to be used with `SyncProvider` in React apps. | ||
|
||
```tsx | ||
import { WagmiProvider } from "wagmi"; | ||
import { QueryClientProvider } from "@tanstack/react-query"; | ||
import { SyncProvider } from "@latticexyz/store-sync/react"; | ||
import { createSyncAdapter } from "@latticexyz/store-sync/recs"; | ||
import { createWorld } from "@latticexyz/recs"; | ||
import config from "./mud.config"; | ||
|
||
const world = createWorld(); | ||
const { syncAdapter, components } = createSyncAdapter({ world, config }); | ||
|
||
export function App() { | ||
return ( | ||
<WagmiProvider config={wagmiConfig}> | ||
<QueryClientProvider client={queryClient}> | ||
<SyncProvider chainId={chainId} address={worldAddress} startBlock={startBlock} adapter={syncAdapter}> | ||
{children} | ||
</SyncProvider> | ||
</QueryClientProvider> | ||
</WagmiProvider> | ||
); | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,14 @@ | ||
import { Metadata } from "@latticexyz/recs"; | ||
import { KeySchema, ValueSchema } from "@latticexyz/protocol-parser/internal"; | ||
import { Table } from "@latticexyz/config"; | ||
|
||
export type StoreComponentMetadata = Metadata & { | ||
componentName: string; | ||
tableName: string; | ||
table: Table; | ||
// TODO: migrate to store's KeySchema/ValueSchema | ||
/** @deprecated Derive this schema from `component.metadata.table` instead. */ | ||
keySchema: KeySchema; | ||
/** @deprecated Derive this schema from `component.metadata.table` instead. */ | ||
valueSchema: ValueSchema; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
import { Component as RecsComponent, World as RecsWorld, getComponentValue, setComponent } from "@latticexyz/recs"; | ||
import { createStorageAdapter } from "./createStorageAdapter"; | ||
import { SyncStep } from "../SyncStep"; | ||
import { SyncAdapter } from "../common"; | ||
import { createStoreSync } from "../createStoreSync"; | ||
import { singletonEntity } from "./singletonEntity"; | ||
import { Store as StoreConfig } from "@latticexyz/store"; | ||
import { registerComponents } from "./registerComponents"; | ||
|
||
export type CreateSyncAdapterOptions<config extends StoreConfig> = { | ||
world: RecsWorld; | ||
config: config; | ||
}; | ||
|
||
export function createSyncAdapter<const config extends StoreConfig>({ | ||
world, | ||
config, | ||
}: CreateSyncAdapterOptions<config>): { | ||
syncAdapter: SyncAdapter; | ||
components: registerComponents<config>; | ||
} { | ||
const components = registerComponents({ world, config }); | ||
|
||
const syncAdapter: SyncAdapter = (opts) => { | ||
// TODO: clear component values? | ||
|
||
const { storageAdapter } = createStorageAdapter({ | ||
world, | ||
tables: {}, | ||
shouldSkipUpdateStream: (): boolean => { | ||
const value = getComponentValue(components.SyncProgress, singletonEntity); | ||
console.log("should skip update?", value); | ||
return value?.step !== SyncStep.LIVE; | ||
}, | ||
}); | ||
|
||
return createStoreSync({ | ||
...opts, | ||
storageAdapter, | ||
onProgress: ({ step, percentage, latestBlockNumber, lastBlockNumberProcessed, message }) => { | ||
// already live, no need for more progress updates | ||
if (getComponentValue(components.SyncProgress, singletonEntity)?.step === SyncStep.LIVE) return; | ||
|
||
console.log("setting component", { step, percentage }); | ||
setComponent(components.SyncProgress, singletonEntity, { | ||
step, | ||
percentage, | ||
latestBlockNumber, | ||
lastBlockNumberProcessed, | ||
message, | ||
}); | ||
|
||
// when we switch to live, trigger update for all entities in all components | ||
if (step === SyncStep.LIVE) { | ||
for (const _component of Object.values(components)) { | ||
// downcast component for easier calling of generic methods on all components | ||
const component = _component as RecsComponent; | ||
for (const entity of component.entities()) { | ||
const value = getComponentValue(component, entity); | ||
component.update$.next({ component, entity, value: [value, value] }); | ||
} | ||
} | ||
} | ||
}, | ||
}); | ||
}; | ||
|
||
return { syncAdapter, components }; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,13 @@ | ||
export * from "./common"; | ||
export * from "./createStorageAdapter"; | ||
export * from "./createSyncAdapter"; | ||
export * from "./decodeEntity"; | ||
export * from "./encodeEntity"; | ||
export * from "./entityToHexKeyTuple"; | ||
export * from "./hexKeyTupleToEntity"; | ||
export * from "./isStoreComponent"; | ||
export * from "./createStorageAdapter"; | ||
export * from "./registerComponents"; | ||
export * from "./singletonEntity"; | ||
export * from "./syncToRecs"; | ||
export * from "./tableToComponent"; | ||
export * from "./tablesToComponents"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import { World as RecsWorld } from "@latticexyz/recs"; | ||
import { mudTables } from "../common"; | ||
import { tablesToComponents } from "./tablesToComponents"; | ||
import { Store as StoreConfig } from "@latticexyz/store"; | ||
import { merge } from "@ark/util"; | ||
import { configToTables } from "../configToTables"; | ||
import { defineInternalComponents } from "./defineInternalComponents"; | ||
import { Tables } from "@latticexyz/config"; | ||
|
||
export type registerComponents<config extends StoreConfig, extraTables extends Tables = {}> = merge< | ||
merge< | ||
merge<tablesToComponents<configToTables<config>>, tablesToComponents<extraTables>>, | ||
tablesToComponents<mudTables> | ||
>, | ||
ReturnType<typeof defineInternalComponents> | ||
>; | ||
|
||
export function registerComponents<const config extends StoreConfig, const extraTables extends Tables = {}>({ | ||
world, | ||
config, | ||
extraTables = {} as extraTables, | ||
}: { | ||
world: RecsWorld; | ||
config: config; | ||
extraTables?: extraTables; | ||
}): registerComponents<config, extraTables> { | ||
return { | ||
...tablesToComponents(world, configToTables(config) as configToTables<config>), | ||
...tablesToComponents(world, extraTables), | ||
...tablesToComponents(world, mudTables), | ||
...defineInternalComponents(world), | ||
} as never; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.