refactor: reorganize repo, create deep-charm

This commit is contained in:
littensy 2026-02-24 19:49:34 -08:00
parent d741640d28
commit 89478f679c
64 changed files with 913 additions and 744 deletions

View file

@ -2,8 +2,8 @@ local Charm = require("../Charm")
local patch = require("./patch")
local types = require("./types")
type ReactiveProxy<T = {}> = Charm.ReactiveProxy<T>
type SyncPayload = types.SyncPayload
type ReactiveProxy<T = {}> = types.ReactiveProxy<T>
local trackedSignals: { [string]: (any) -> any } = {}
local trackedReactives: { [string]: ReactiveProxy } = {}

View file

@ -4,8 +4,6 @@ local patch = require("./patch")
local types = require("./types")
local utils = require("./utils")
type ReactiveProxy<T = {}> = Charm.ReactiveProxy<T>
type SyncPayload = types.SyncPayload
type SyncStatus = number
@ -36,9 +34,21 @@ local clients: { [any]: ClientKeys } = {}
local connection: RBXScriptConnection?
local syncCallback: ((client: any, payloads: { SyncPayload }) -> ())?
--[[
Manually converts a reactive proxy to its raw representation to potentially
support custom implementations of reactive proxies.
]]
local function toRaw<T>(value: T): T
if type(value) == "table" and type(value.__target) == "table" and type(value.__track) == "function" then
value.__track()
return toRaw(value.__target)
end
return value
end
local function trackSignal<T>(key: string, getter: () -> T, identifier: unknown)
if trackedStates[key] then
-- Ignore duplicates, but warn against name collisions
-- Warn against name collisions with conflicting signals or proxies
if trackedStates[key].identifier ~= identifier then
warn("[Charm] Attempted to sync different states with the same key:", key)
end
@ -47,12 +57,12 @@ local function trackSignal<T>(key: string, getter: () -> T, identifier: unknown)
local trackedState: TrackedState<T>
local initialValue = getter()
local rawInitialValue = Charm.toRaw(initialValue)
local rawInitialValue = toRaw(initialValue)
local snapshot = if initialValue ~= rawInitialValue then utils.deepCopy(rawInitialValue) else initialValue
local dispose = Charm.effect(function()
local newValue = getter()
local rawValue = Charm.toRaw(newValue)
local rawValue = toRaw(newValue)
local isReactive = newValue ~= rawValue
if not trackedState then

View file

@ -18,4 +18,13 @@ export type SyncPayload =
]]
export type None = { __none: "__none" }
export type ReactiveProxy<T = any> = typeof(setmetatable(
{} :: {
__track: () -> (),
__target: T,
__signals: { [unknown]: () -> unknown },
},
{} :: { __index: T }
))
return {}