diff --git a/src/charm/src/computed.luau b/src/charm/src/computed.luau index 7fed8f7..e786c45 100644 --- a/src/charm/src/computed.luau +++ b/src/charm/src/computed.luau @@ -1,21 +1,20 @@ local atom = require(script.Parent.atom) local store = require(script.Parent.store) local types = require(script.Parent.types) -type Atom = types.Atom type AtomOptions = types.AtomOptions -type Molecule = types.Molecule +type Selector = types.Selector --[=[ Creates a read-only atom that derives its state from one or more atoms. Used to avoid unnecessary recomputations if multiple listeners depend on - the same molecule. - - @param molecule The function that produces the state. + the same atoms. + + @param callback The function that produces the state. @param options Optional configuration. @return A new read-only atom. ]=] -local function computed(molecule: Molecule, options: AtomOptions?): Molecule - local dependencies, state = store.capture(molecule) +local function computed(callback: Selector, options: AtomOptions?): Selector + local dependencies, state = store.capture(callback) local computedAtom = atom(state, options) local computedRef = setmetatable({ current = computedAtom }, { __mode = "v" }) @@ -24,7 +23,7 @@ local function computed(molecule: Molecule, options: AtomOptions?): Mol if computedAtom then store.disconnect(dependencies, listener) - dependencies, state = store.capture(molecule) + dependencies, state = store.capture(callback) store.connect(dependencies, listener, computedAtom) computedAtom(state) end diff --git a/src/charm/src/effect.luau b/src/charm/src/effect.luau index ae36188..1b822b7 100644 --- a/src/charm/src/effect.luau +++ b/src/charm/src/effect.luau @@ -9,7 +9,7 @@ type Cleanup = () -> () @param callback The function to run. @return A function that unsubscribes the callback. ]=] -local function effect(callback: () -> (() -> ())?): () -> () +local function effect(callback: () -> Cleanup?): Cleanup local dependencies, cleanup = store.capture(callback) local disconnected = false diff --git a/src/charm/src/init.luau b/src/charm/src/init.luau index 1cb6c02..cf144e3 100644 --- a/src/charm/src/init.luau +++ b/src/charm/src/init.luau @@ -8,7 +8,8 @@ local subscribe = require(script.subscribe) local types = require(script.types) export type Atom = types.Atom -export type Molecule = types.Molecule +export type Molecule = types.Selector +export type Selector = types.Selector export type SyncPayload = types.SyncPayload return { diff --git a/src/charm/src/mapped.luau b/src/charm/src/mapped.luau index c7a2496..1f1e977 100644 --- a/src/charm/src/mapped.luau +++ b/src/charm/src/mapped.luau @@ -3,12 +3,12 @@ local effect = require(script.Parent.effect) local store = require(script.Parent.store) local types = require(script.Parent.types) type Atom = types.Atom -type Molecule = types.Molecule +type Selector = types.Selector type Map = - ((fn: Molecule<{ [K0]: V0 }>, mapper: (V0, K0) -> (V1?, K1)) -> Molecule<{ [K1]: V1 }>) - & ((fn: Molecule<{ [K0]: V0 }>, mapper: (V0, K0) -> V1?) -> Molecule<{ [K0]: V1 }>) - & ((fn: Molecule<{ [K0]: V0 }>, mapper: (V0, K0) -> (V1?, K1?)) -> Molecule<{ [K1]: V1 }>) + ((fn: Selector<{ [K0]: V0 }>, mapper: (V0, K0) -> (V1?, K1)) -> Selector<{ [K1]: V1 }>) + & ((fn: Selector<{ [K0]: V0 }>, mapper: (V0, K0) -> V1?) -> Selector<{ [K0]: V1 }>) + & ((fn: Selector<{ [K0]: V0 }>, mapper: (V0, K0) -> (V1?, K1?)) -> Selector<{ [K1]: V1 }>) --[=[ Maps each entry in the atom's state to a new key-value pair. If the `mapper` @@ -16,11 +16,11 @@ type Map = When the atom changes, the `mapper` is called for each entry in the state to compute the new state. - @param molecule The atom or molecule to map. + @param callback The atom or selector to map. @param mapper The function that maps each entry. @return A new atom with the mapped state. ]=] -local function mapped(molecule: Molecule<{ [K0]: V0 }>, mapper: (V0, K0) -> (V1?, K1?)): Molecule<{ [K1]: V1 }> +local function mapped(callback: Selector<{ [K0]: V0 }>, mapper: (V0, K0) -> (V1?, K1?)): Selector<{ [K1]: V1 }> local mappedAtom = atom({}) local mappedAtomRef = setmetatable({ current = mappedAtom }, { __mode = "v" }) local prevMappedItems: { [K1]: V1 } = {} @@ -31,7 +31,7 @@ local function mapped(molecule: Molecule<{ [K0]: V0 }>, mapper: return unsubscribe() end - local items = molecule() + local items = callback() local mappedItems = table.clone(store.peek(mappedAtomRef.current)) local mappedKeys = {} diff --git a/src/charm/src/observe.luau b/src/charm/src/observe.luau index ea326ef..d2cfeb4 100644 --- a/src/charm/src/observe.luau +++ b/src/charm/src/observe.luau @@ -1,6 +1,6 @@ local effect = require(script.Parent.effect) local types = require(script.Parent.types) -type Molecule = types.Molecule +type Selector = types.Selector local function noop() end @@ -13,7 +13,7 @@ local function noop() end @param factory The function that tracks the lifecycle of each item. @return A function that unsubscribes all instances. ]=] -local function observe(molecule: Molecule<{ [K]: V }>, factory: (value: V, key: K) -> (() -> ())?): () -> () +local function observe(molecule: Selector<{ [K]: V }>, factory: (value: V, key: K) -> (() -> ())?): () -> () local connections: { [K]: () -> () } = {} local unsubscribe = effect(function() diff --git a/src/charm/src/subscribe.luau b/src/charm/src/subscribe.luau index 8f13ddd..d34df22 100644 --- a/src/charm/src/subscribe.luau +++ b/src/charm/src/subscribe.luau @@ -1,6 +1,6 @@ local store = require(script.Parent.store) local types = require(script.Parent.types) -type Molecule = types.Molecule +type Selector = types.Selector --[=[ Subscribes to changes in the given atom or molecule. The callback is @@ -11,7 +11,7 @@ type Molecule = types.Molecule @param callback The function to call when the state changes. @return A function that unsubscribes the callback. ]=] -local function subscribe(molecule: Molecule, callback: (state: T, prev: T) -> ()): () -> () +local function subscribe(molecule: Selector, callback: (state: T, prev: T) -> ()): () -> () local dependencies, state = store.capture(molecule) local disconnected = false diff --git a/src/charm/src/types.luau b/src/charm/src/types.luau index 16d19f2..fd3ba6b 100644 --- a/src/charm/src/types.luau +++ b/src/charm/src/types.luau @@ -9,7 +9,7 @@ export type WeakMap = typeof(setmetatable({} :: { [K]: V }, { __mode = "k" @param state The next state or a function that produces the next state. @return The current state, if no arguments are provided. ]=] -export type Atom = (() -> T) & (state: T | (T) -> T) -> T +export type Atom = (state: (T | (T) -> T)?) -> T --[=[ A function that depends on one or more atoms and produces a state. Can be @@ -18,7 +18,7 @@ export type Atom = (() -> T) & (state: T | (T) -> T) -> T @template State The type of the state. @return The current state. ]=] -export type Molecule = () -> T +export type Selector = () -> T --[=[ Optional configuration for creating an atom.