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

View file

@ -7,10 +7,6 @@ local validate = require(script.validate)
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 {
client = client,
server = server,

View file

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

View file

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

View file

@ -9,65 +9,49 @@ type AtomMap = types.AtomMap
type SyncPayload = types.SyncPayload
type ServerOptions = {
--[=[
The atoms to synchronize with the client.
]=]
--- The atoms to synchronize with the client.
atoms: AtomMap,
--[=[
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
negative value to disable automatic syncing.
]=]
--- 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
--- negative value to disable automatic syncing.
interval: number?,
--[=[
Whether the history of state changes since the client's last update
should be preserved. This is useful for values that change multiple times
per frame, where each individual change is important. Defaults to `false`.
]=]
--- Whether the history of state changes since the client's last update
--- should be preserved. This is useful for values that change multiple times
--- per frame, where each individual change is important. Defaults to `false`.
preserveHistory: boolean?,
--[=[
When `true`, Charm will apply validation and serialize unsafe arrays
to address remote event argument limitations. Defaults to `true`.
This option should be disabled if your network library uses a custom
serialization method (i.e. Zap, ByteNet) to prevent interference.
]=]
--- When `true`, Charm will apply validation and serialize unsafe arrays
--- to address remote event argument limitations. Defaults to `true`.
---
--- This option should be disabled if your network library uses a custom
--- serialization method (i.e. Zap, ByteNet) to prevent interference.
autoSerialize: boolean?,
}
type ServerSyncer = {
--[=[
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`
is called with the player and the payload to send.
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.
@param callback The function to call when the state changes.
@return A cleanup function that unsubscribes all listeners.
]=]
--- 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`
--- is called with the player and the payload to send.
---
--- 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.
---
--- @param callback The function to call when the state changes.
--- @return A cleanup function that unsubscribes all listeners.
connect: (self: ServerSyncer, callback: (player: Player, ...SyncPayload) -> ()) -> () -> (),
--[=[
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.
@param player The player to hydrate.
]=]
--- 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.
---
--- @param player The player to hydrate.
hydrate: (self: ServerSyncer, player: Player) -> (),
--[=[
@deprecated For internal use only.
]=]
--- @deprecated For internal use only.
_sendPatch: (self: ServerSyncer, player: Player) -> (),
}
--[=[
Creates a `ServerSyncer` object that sends patches to the client and
hydrates the client's state.
@param options The atoms to synchronize with the client.
@return A `ServerSyncer` object.
]=]
--- Creates a `ServerSyncer` object that sends patches to the client and
--- hydrates the client's state.
---
--- @param options The atoms to synchronize with the client.
--- @return A `ServerSyncer` object.
local function server(options: ServerOptions): ServerSyncer
local atoms = options.atoms
local autoSerialize = options.autoSerialize ~= false

View file

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

View file

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