refactor: refine types and code

This commit is contained in:
Richard 2024-03-27 23:49:33 -07:00
parent 33ecae2f50
commit 382bc3a904
6 changed files with 30 additions and 26 deletions

View file

@ -7,7 +7,7 @@ return function()
local client = sync.client({ atoms = { a = a } })
client:sync({
type = "set",
type = "init",
data = { a = 2 },
})

View file

@ -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()

36
src/index.d.ts vendored
View file

@ -76,34 +76,36 @@ declare namespace Charm {
// Sync
const sync: {
client(options: ClientOptions): ClientSyncer;
server(options: ServerOptions): ServerSyncer;
client: <T extends Record<string, Atom<any>>>(options: ClientOptions<T>) => ClientSyncer<T>;
server: <T extends Record<string, Atom<any>>>(options: ServerOptions<T>) => ServerSyncer<T>;
collect: (root: Instance) => Record<string, Atom<any>>;
};
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<T> = {
readonly [P in keyof T]?: (T[P] extends object ? SyncPatch<T[P]> : T[P]) | (T[P] extends undefined ? None : never);
};
type SyncPayload<T> = { type: "init"; data: T } | { type: "patch"; data: SyncPatch<T> };
interface ClientOptions<T extends Record<string, Atom<any>>> {
atoms: T;
}
interface ClientOptions {
atoms: Record<string, Atom<any>>;
}
interface ServerOptions {
atoms: Record<string, Atom<any>>;
interface ServerOptions<T extends Record<string, Atom<any>>> {
atoms: T;
interval?: number;
}
interface ClientSyncer {
sync(payload: SyncPayload): void;
interface ClientSyncer<T extends Record<string, Atom<any>>> {
sync(payload: SyncPayload<T>): void;
}
interface ServerSyncer {
connect(callback: (player: Player, payload: SyncPayload) => void): Cleanup;
interface ServerSyncer<T extends Record<string, Atom<any>>> {
connect(callback: (player: Player, payload: SyncPayload<T>) => void): Cleanup;
hydrate(player: Player): void;
}
}

View file

@ -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,
}

View file

@ -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

View file

@ -9,7 +9,7 @@ export type AtomOptions<T> = {
}
export type SyncPayload = {
type: "patch" | "set",
type: "patch" | "init",
data: { [any]: any },
}