From 382bc3a90466da8e4dfa1d8e742d61668563a779 Mon Sep 17 00:00:00 2001 From: Richard Date: Wed, 27 Mar 2024 23:49:33 -0700 Subject: [PATCH] refactor: refine types and code --- src/__tests__/sync/client.spec.luau | 2 +- src/__tests__/sync/server.spec.luau | 2 +- src/index.d.ts | 36 +++++++++++++++-------------- src/init.luau | 8 +++---- src/sync/server.luau | 6 +++-- src/types.luau | 2 +- 6 files changed, 30 insertions(+), 26 deletions(-) diff --git a/src/__tests__/sync/client.spec.luau b/src/__tests__/sync/client.spec.luau index ea961f8..5aac613 100644 --- a/src/__tests__/sync/client.spec.luau +++ b/src/__tests__/sync/client.spec.luau @@ -7,7 +7,7 @@ return function() local client = sync.client({ atoms = { a = a } }) client:sync({ - type = "set", + type = "init", data = { a = 2 }, }) diff --git a/src/__tests__/sync/server.spec.luau b/src/__tests__/sync/server.spec.luau index 972d78b..206773c 100644 --- a/src/__tests__/sync/server.spec.luau +++ b/src/__tests__/sync/server.spec.luau @@ -17,7 +17,7 @@ return function() server:hydrate(target) expect(player).to.equal(target) - expect(payload.type).to.equal("set") + expect(payload.type).to.equal("init") expect(payload.data.a).to.equal(1) disconnect() diff --git a/src/index.d.ts b/src/index.d.ts index 89ebe1c..eb3e721 100644 --- a/src/index.d.ts +++ b/src/index.d.ts @@ -76,34 +76,36 @@ declare namespace Charm { // Sync const sync: { - client(options: ClientOptions): ClientSyncer; - server(options: ServerOptions): ServerSyncer; + client: >>(options: ClientOptions) => ClientSyncer; + server: >>(options: ServerOptions) => ServerSyncer; + collect: (root: Instance) => Record>; }; - interface SyncPatch { - [key: string | number | symbol]: SyncPatch | { __none: "__none" } | string | number | boolean | undefined; + interface None { + __none: "__none"; } - interface SyncPayload { - type: "set" | "patch"; - data: SyncPatch; + type SyncPatch = { + readonly [P in keyof T]?: (T[P] extends object ? SyncPatch : T[P]) | (T[P] extends undefined ? None : never); + }; + + type SyncPayload = { type: "init"; data: T } | { type: "patch"; data: SyncPatch }; + + interface ClientOptions>> { + atoms: T; } - interface ClientOptions { - atoms: Record>; - } - - interface ServerOptions { - atoms: Record>; + interface ServerOptions>> { + atoms: T; interval?: number; } - interface ClientSyncer { - sync(payload: SyncPayload): void; + interface ClientSyncer>> { + sync(payload: SyncPayload): void; } - interface ServerSyncer { - connect(callback: (player: Player, payload: SyncPayload) => void): Cleanup; + interface ServerSyncer>> { + connect(callback: (player: Player, payload: SyncPayload) => void): Cleanup; hydrate(player: Player): void; } } diff --git a/src/init.luau b/src/init.luau index 9747c78..00ba0b3 100644 --- a/src/init.luau +++ b/src/init.luau @@ -21,16 +21,16 @@ export type SyncPayload = types.SyncPayload return { atom = atom, + capture = capture, derive = derive, effect = effect, isAtom = isAtom, map = map, observe = observe, - subscribe = subscribe, - unwrap = unwrap, - capture = capture, - sync = sync, useAtom = useAtom, useAtomState = useAtomState, useSetAtom = useSetAtom, + subscribe = subscribe, + sync = sync, + unwrap = unwrap, } diff --git a/src/sync/server.luau b/src/sync/server.luau index db6645e..51dabb4 100644 --- a/src/sync/server.luau +++ b/src/sync/server.luau @@ -42,10 +42,12 @@ local function server(options: ServerOptions): ServerSyncer state = getState() if state ~= previous then + local diffs = patch.diff(previous, state) + for _, player in Players:GetPlayers() do callback(player, { type = "patch", - data = patch.diff(previous, state), + data = diffs, }) end end @@ -66,7 +68,7 @@ local function server(options: ServerOptions): ServerSyncer assert(sync, "connect() must be called before hydrate()") sync(player, { - type = "set", + type = "init", data = getState(), }) end diff --git a/src/types.luau b/src/types.luau index ee08b65..f475b0f 100644 --- a/src/types.luau +++ b/src/types.luau @@ -9,7 +9,7 @@ export type AtomOptions = { } export type SyncPayload = { - type: "patch" | "set", + type: "patch" | "init", data: { [any]: any }, }