From 9ba552cb6c41ff4dadbd08ebe4a10d09e9ea0f1b Mon Sep 17 00:00:00 2001 From: richard <56808540+littensy@users.noreply.github.com> Date: Fri, 20 Sep 2024 15:32:20 -0700 Subject: [PATCH] fix(sync): block patches before initial hydration (#21) --- .github/workflows/ci.yml | 4 ++-- .github/workflows/release.yml | 4 ++-- aftman.toml | 11 ----------- rokit.toml | 12 ++++++++++++ src/index.d.ts | 5 +++++ src/sync/client.luau | 17 ++++++++++++++++- 6 files changed, 37 insertions(+), 16 deletions(-) delete mode 100644 aftman.toml create mode 100644 rokit.toml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a8561d3..b6cdec7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,8 +18,8 @@ jobs: with: version: 8.15.4 - - name: Install Aftman - uses: ok-nick/setup-aftman@v0.4.2 + - name: Install Rokit + uses: CompeyDev/setup-rokit@v0.1.2 - name: Install dependencies run: | diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d02e659..a179663 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -10,8 +10,8 @@ jobs: steps: - uses: actions/checkout@v4 - - name: Install Aftman - uses: ok-nick/setup-aftman@v0.4.2 + - name: Install Rokit + uses: CompeyDev/setup-rokit@v0.1.2 - name: Install dependencies run: wally install diff --git a/aftman.toml b/aftman.toml deleted file mode 100644 index 187b7df..0000000 --- a/aftman.toml +++ /dev/null @@ -1,11 +0,0 @@ -# This file lists tools managed by Aftman, a cross-platform toolchain manager. -# For more information, see https://github.com/LPGhatguy/aftman - -# To add a new tool, add an entry to this table. -[tools] -wally = "UpliftGames/wally@0.3.2" -rojo = "rojo-rbx/rojo@7.4.1" -wally-package-types = "JohnnyMorganz/wally-package-types@1.3.1" -stylua = "johnnymorganz/stylua@0.20.0" -selene = "Kampfkarren/selene@0.26.1" -luau-lsp = "johnnymorganz/luau-lsp@1.27.1" diff --git a/rokit.toml b/rokit.toml new file mode 100644 index 0000000..0df6c48 --- /dev/null +++ b/rokit.toml @@ -0,0 +1,12 @@ +# This file lists tools managed by Rokit, a toolchain manager for Roblox projects. +# For more information, see https://github.com/rojo-rbx/rokit + +# New tools can be added by running `rokit add ` in a terminal. + +[tools] +wally = "UpliftGames/wally@0.3.2" +rojo = "rojo-rbx/rojo@7.4.4" +wally-package-types = "JohnnyMorganz/wally-package-types@1.3.2" +stylua = "johnnymorganz/stylua@0.20.0" +selene = "Kampfkarren/selene@0.27.1" +luau-lsp = "johnnymorganz/luau-lsp@1.32.4" diff --git a/src/index.d.ts b/src/index.d.ts index 5aedfac..95f9e99 100644 --- a/src/index.d.ts +++ b/src/index.d.ts @@ -290,6 +290,11 @@ declare namespace Charm { * The atoms to synchronize with the server. */ atoms: Atoms; + /** + * Whether to ignore patches sent before the client has been hydrated. + * Defaults to `true`. + */ + ignoreUnhydrated?: boolean; } interface ServerOptions { diff --git a/src/sync/client.luau b/src/sync/client.luau index ce6993e..a5901d3 100644 --- a/src/sync/client.luau +++ b/src/sync/client.luau @@ -9,6 +9,11 @@ type ClientOptions = { The atoms to synchronize with the server. ]=] atoms: { [string]: Atom }, + --[=[ + Whether to ignore patches sent before the client has been hydrated. + Default is `true`. + ]=] + ignoreUnhydrated: boolean?, } type ClientSyncer = { @@ -30,12 +35,22 @@ type ClientSyncer = { ]=] local function client(options: ClientOptions): ClientSyncer local atoms = options.atoms + local ignoreUnhydrated = options.ignoreUnhydrated ~= false local self = {} :: ClientSyncer + local hydrated = false -- Apply the state changes sent by the server. function self:sync(...) for index = 1, select("#", ...) do - local payload = select(index, ...) + local payload: SyncPayload = select(index, ...) + + if ignoreUnhydrated and payload.type == "patch" and not hydrated then + -- If the client is not initialized, ignore patches. This is + -- to prevent patching incomplete state. + continue + end + + hydrated = true store.batch(function() for key, state in next, payload.data do