style: use --- doc comments

This commit is contained in:
littensy 2025-05-12 02:20:41 -07:00
parent 72f936591e
commit 25728e589f
7 changed files with 77 additions and 119 deletions

View file

@ -6,34 +6,26 @@ type AtomMap = types.AtomMap
type SyncPayload = types.SyncPayload type SyncPayload = types.SyncPayload
type ClientOptions = { type ClientOptions = {
--[=[ --- The atoms to synchronize with the server.
The atoms to synchronize with the server.
]=]
atoms: AtomMap, atoms: AtomMap,
--[=[ --- Whether to ignore patches sent before the client has been hydrated.
Whether to ignore patches sent before the client has been hydrated. --- Default is `true`.
Default is `true`.
]=]
ignoreUnhydrated: boolean?, ignoreUnhydrated: boolean?,
} }
type ClientSyncer = { type ClientSyncer = {
--[=[ --- Applies a patch or initializes the state of the atoms with the given
Applies a patch or initializes the state of the atoms with the given --- payload from the server.
payload from the server. ---
--- @param ...payloads The patches or hydration payloads to apply.
@param ...payloads The patches or hydration payloads to apply.
]=]
sync: (self: ClientSyncer, ...SyncPayload) -> (), sync: (self: ClientSyncer, ...SyncPayload) -> (),
} }
--[=[ --- Creates a `ClientSyncer` object that receives patches from the server and
Creates a `ClientSyncer` object that receives patches from the server and --- applies them to the local state.
applies them to the local state. ---
--- @param options The atoms to synchronize with the server.
@param options The atoms to synchronize with the server. --- @return A `ClientSyncer` object.
@return A `ClientSyncer` object.
]=]
local function client(options: ClientOptions): ClientSyncer local function client(options: ClientOptions): ClientSyncer
local atoms = options.atoms local atoms = options.atoms
local ignoreUnhydrated = options.ignoreUnhydrated ~= false local ignoreUnhydrated = options.ignoreUnhydrated ~= false

View file

@ -7,10 +7,6 @@ local validate = require(script.validate)
export type SyncPayload = types.SyncPayload export type SyncPayload = types.SyncPayload
--[=[
Synchronizes state between the client and server. The server sends patches
to the client, which applies them to its local state.
]=]
return { return {
client = client, client = client,
server = server, server = server,

View file

@ -1,12 +1,10 @@
local RunService = game:GetService("RunService") local RunService = game:GetService("RunService")
--[=[ --- Schedules a function to be called at a fixed interval of `seconds`.
Schedules a function to be called at a fixed interval of `seconds`. ---
--- @param callback The function to call.
@param callback The function to call. --- @param seconds The interval in seconds.
@param seconds The interval in seconds. --- @return A function that cancels the interval.
@return A function that cancels the interval.
]=]
local function interval(callback: () -> (), seconds: number): () -> () local function interval(callback: () -> (), seconds: number): () -> ()
if seconds < 0 then if seconds < 0 then
return function() end return function() end

View file

@ -2,26 +2,22 @@ local validate = require(script.Parent.validate)
local __DEV__ = _G.__DEV__ local __DEV__ = _G.__DEV__
--[=[ --- A special symbol that denotes the absence of a value. Used to represent
A special symbol that denotes the absence of a value. Used to represent --- deleted values in patches.
deleted values in patches.
]=]
local None = { __none = "__none" } local None = { __none = "__none" }
local function isNone(value: any): boolean local function isNone(value: any): boolean
return type(value) == "table" and value.__none == "__none" return type(value) == "table" and value.__none == "__none"
end end
--[=[ --- JSON serialization can drop the last values of a sparse array. For example,
JSON serialization can drop the last values of a sparse array. For example, --- `{ [1] = 1, [3] = 3 }` becomes `[1]` in some cases. Ambiguity in the
`{ [1] = 1, [3] = 3 }` becomes `[1]` in some cases. Ambiguity in the --- serialization of sparse arrays can be resolved by converting them to
serialization of sparse arrays can be resolved by converting them to --- dictionaries with string keys.
dictionaries with string keys. ---
--- The `apply` function will convert these dictionaries back into arrays as
The `apply` function will convert these dictionaries back into arrays as --- long as the target array is not sparse. This function ensures that the diff
long as the target array is not sparse. This function ensures that the diff --- function produces a patch that can be correctly applied.
function produces a patch that can be correctly applied.
]=]
local function stringifySparseArray(object: { any }): { [string | number]: any } local function stringifySparseArray(object: { any }): { [string | number]: any }
local maxn = table.maxn(object) local maxn = table.maxn(object)
@ -39,15 +35,13 @@ local function stringifySparseArray(object: { any }): { [string | number]: any }
return dictionary return dictionary
end end
--[=[ --- Compares two states and returns a patch that can be applied to the previous
Compares two states and returns a patch that can be applied to the previous --- state to produce the next state.
state to produce the next state. ---
--- @param prevState The previous state.
@param prevState The previous state. --- @param nextState The next state.
@param nextState The next state. --- @param serialize Whether to convert sparse arrays into dictionaries. Defaults to `true`.
@param serialize Whether to convert sparse arrays into dictionaries. Defaults to `true`. --- @returns A patch that can be applied to the previous state.
@returns A patch that can be applied to the previous state.
]=]
local function diff(prevState: { [any]: any }, nextState: { [any]: any }, serialize: boolean?) local function diff(prevState: { [any]: any }, nextState: { [any]: any }, serialize: boolean?)
serialize = serialize ~= false serialize = serialize ~= false
@ -79,13 +73,11 @@ local function diff(prevState: { [any]: any }, nextState: { [any]: any }, serial
return patches return patches
end end
--[=[ --- Applies a patch to a state and returns the next state.
Applies a patch to a state and returns the next state. ---
--- @param state The current state.
@param state The current state. --- @param patches The patches to apply.
@param patches The patches to apply. --- @returns The next state.
@returns The next state.
]=]
local function apply(state: any, patches: any): any local function apply(state: any, patches: any): any
if type(patches) == "table" and patches.__none == "__none" then if type(patches) == "table" and patches.__none == "__none" then
return nil return nil

View file

@ -9,65 +9,49 @@ type AtomMap = types.AtomMap
type SyncPayload = types.SyncPayload type SyncPayload = types.SyncPayload
type ServerOptions = { type ServerOptions = {
--[=[ --- The atoms to synchronize with the client.
The atoms to synchronize with the client.
]=]
atoms: AtomMap, atoms: AtomMap,
--[=[ --- The interval at which to send patches to the client, in seconds.
The interval at which to send patches to the client, in seconds. --- Defaults to `0` (patches are sent up to once per frame). Set to a
Defaults to `0` (patches are sent up to once per frame). Set to a --- negative value to disable automatic syncing.
negative value to disable automatic syncing.
]=]
interval: number?, interval: number?,
--[=[ --- Whether the history of state changes since the client's last update
Whether the history of state changes since the client's last update --- should be preserved. This is useful for values that change multiple times
should be preserved. This is useful for values that change multiple times --- per frame, where each individual change is important. Defaults to `false`.
per frame, where each individual change is important. Defaults to `false`.
]=]
preserveHistory: boolean?, preserveHistory: boolean?,
--[=[ --- When `true`, Charm will apply validation and serialize unsafe arrays
When `true`, Charm will apply validation and serialize unsafe arrays --- to address remote event argument limitations. Defaults to `true`.
to address remote event argument limitations. Defaults to `true`. ---
--- This option should be disabled if your network library uses a custom
This option should be disabled if your network library uses a custom --- serialization method (i.e. Zap, ByteNet) to prevent interference.
serialization method (i.e. Zap, ByteNet) to prevent interference.
]=]
autoSerialize: boolean?, autoSerialize: boolean?,
} }
type ServerSyncer = { type ServerSyncer = {
--[=[ --- Sets up a subscription to each atom that schedules a patch to be sent to
Sets up a subscription to each atom that schedules a patch to be sent to --- the client whenever the state changes. When a change occurs, the `callback`
the client whenever the state changes. When a change occurs, the `callback` --- is called with the player and the payload to send.
is called with the player and the payload to send. ---
--- Note that the `payload` object should not be mutated. If you need to
Note that the `payload` object should not be mutated. If you need to --- modify the payload, apply the changes to a copy of the object.
modify the payload, apply the changes to a copy of the object. ---
--- @param callback The function to call when the state changes.
@param callback The function to call when the state changes. --- @return A cleanup function that unsubscribes all listeners.
@return A cleanup function that unsubscribes all listeners.
]=]
connect: (self: ServerSyncer, callback: (player: Player, ...SyncPayload) -> ()) -> () -> (), connect: (self: ServerSyncer, callback: (player: Player, ...SyncPayload) -> ()) -> () -> (),
--[=[ --- Hydrates the client's state with the server's state. This should be
Hydrates the client's state with the server's state. This should be --- called when a player joins the game and requires the server's state.
called when a player joins the game and requires the server's state. ---
--- @param player The player to hydrate.
@param player The player to hydrate.
]=]
hydrate: (self: ServerSyncer, player: Player) -> (), hydrate: (self: ServerSyncer, player: Player) -> (),
--[=[ --- @deprecated For internal use only.
@deprecated For internal use only.
]=]
_sendPatch: (self: ServerSyncer, player: Player) -> (), _sendPatch: (self: ServerSyncer, player: Player) -> (),
} }
--[=[ --- Creates a `ServerSyncer` object that sends patches to the client and
Creates a `ServerSyncer` object that sends patches to the client and --- hydrates the client's state.
hydrates the client's state. ---
--- @param options The atoms to synchronize with the client.
@param options The atoms to synchronize with the client. --- @return A `ServerSyncer` object.
@return A `ServerSyncer` object.
]=]
local function server(options: ServerOptions): ServerSyncer local function server(options: ServerOptions): ServerSyncer
local atoms = options.atoms local atoms = options.atoms
local autoSerialize = options.autoSerialize ~= false local autoSerialize = options.autoSerialize ~= false

View file

@ -2,10 +2,8 @@ local Charm = require(script.Parent.Parent.Charm)
type Atom<T> = Charm.Atom<T> type Atom<T> = Charm.Atom<T>
--[=[ --- A payload that can be sent from the server to the client to synchronize
A payload that can be sent from the server to the client to synchronize --- state between the two.
state between the two.
]=]
export type SyncPayload = { export type SyncPayload = {
type: "init", type: "init",
data: { [string | number]: any }, data: { [string | number]: any },

View file

@ -27,13 +27,11 @@ local function isTableUnsafe(object: { [any]: any })
return false return false
end end
--[=[ --- Validates a value to ensure it can be synced over a remote event.
Validates a value to ensure it can be synced over a remote event. ---
--- @param value The value to validate.
@param value The value to validate. --- @param key The key of the value in the table.
@param key The key of the value in the table. --- @error Throws an error if the value cannot be synced.
@error Throws an error if the value cannot be synced.
]=]
local function validate(value: any, key: any) local function validate(value: any, key: any)
local typeOfKey = type(key) local typeOfKey = type(key)
local typeOfValue = type(value) local typeOfValue = type(value)