mirror of
https://github.com/littensy/charm.git
synced 2026-10-20 17:51:37 +00:00
feat: export getter and setter types
This commit is contained in:
parent
3460618ee0
commit
00880bec55
2 changed files with 40 additions and 43 deletions
43
packages/charm/src/index.d.ts
vendored
43
packages/charm/src/index.d.ts
vendored
|
|
@ -1,4 +1,5 @@
|
||||||
type Key = string | number | symbol;
|
type Key = string | number | symbol;
|
||||||
|
|
||||||
type Cleanup = () => void;
|
type Cleanup = () => void;
|
||||||
|
|
||||||
export enum ReactiveFlags {
|
export enum ReactiveFlags {
|
||||||
|
|
@ -31,11 +32,15 @@ export interface Link {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Atom<T> {
|
export interface Atom<T> {
|
||||||
(newValue: T | ((currentValue: T) => T)): T;
|
(update: Update<T>): T;
|
||||||
(): T;
|
(): T;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type Setter<T> = (newValue: T | ((currentValue: T) => T)) => T;
|
export type Getter<T> = () => T;
|
||||||
|
|
||||||
|
export type Setter<T> = (update: Update<T>) => T;
|
||||||
|
|
||||||
|
export type Update<T> = ((currentValue: T) => T) | T;
|
||||||
|
|
||||||
export type Equals<T> = (current: T, incoming: T) => boolean;
|
export type Equals<T> = (current: T, incoming: T) => boolean;
|
||||||
|
|
||||||
|
|
@ -71,16 +76,8 @@ export const flags: {
|
||||||
* @returns A tuple containing the getter and setter functions for the signal.
|
* @returns A tuple containing the getter and setter functions for the signal.
|
||||||
* @see https://github.com/littensy/charm?tab=readme-ov-file#signalinitialValue-equals
|
* @see https://github.com/littensy/charm?tab=readme-ov-file#signalinitialValue-equals
|
||||||
*/
|
*/
|
||||||
export function signal<T>(
|
export function signal<T>(initialValue: T, equals?: Equals<T>): LuaTuple<[getter: Getter<T>, setter: Setter<T>]>;
|
||||||
initialValue: T,
|
export function signal<T>(): LuaTuple<[getter: Getter<T | undefined>, setter: Setter<T | undefined>]>;
|
||||||
equals?: Equals<T>,
|
|
||||||
): LuaTuple<[getter: () => T, setter: (newValue: T | ((currentValue: T) => T)) => T]>;
|
|
||||||
export function signal<T>(): LuaTuple<
|
|
||||||
[
|
|
||||||
getter: () => T | undefined,
|
|
||||||
setter: (newValue: T | undefined | ((currentValue?: T) => T | undefined)) => T | undefined,
|
|
||||||
]
|
|
||||||
>;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a reactive atom that acts as both a signal getter and setter.
|
* Creates a reactive atom that acts as both a signal getter and setter.
|
||||||
|
|
@ -102,7 +99,7 @@ export function atom<T>(): Atom<T | undefined>;
|
||||||
* @param getter A function that produces the next value.
|
* @param getter A function that produces the next value.
|
||||||
* @see https://github.com/littensy/charm?tab=readme-ov-file#computedgetter
|
* @see https://github.com/littensy/charm?tab=readme-ov-file#computedgetter
|
||||||
*/
|
*/
|
||||||
export function computed<T>(getter: (previousValue?: T) => T): () => T;
|
export function computed<T>(getter: (previousValue?: T) => T): Getter<T>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an effect that runs a callback in response to signal state changes.
|
* Creates an effect that runs a callback in response to signal state changes.
|
||||||
|
|
@ -205,7 +202,7 @@ export function batch<Args extends any[], Result>(fn: (...args: Args) => Result,
|
||||||
* @returns A function for disposing the effect.
|
* @returns A function for disposing the effect.
|
||||||
* @see https://github.com/littensy/charm?tab=readme-ov-file#listengetter-callback
|
* @see https://github.com/littensy/charm?tab=readme-ov-file#listengetter-callback
|
||||||
*/
|
*/
|
||||||
export function listen<T>(getter: () => T, fn: (value: T, previousValue: T | undefined) => void): Cleanup;
|
export function listen<T>(getter: Getter<T>, fn: (value: T, previousValue: T | undefined) => void): Cleanup;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an effect that only runs the callback when the value returned by the
|
* Creates an effect that only runs the callback when the value returned by the
|
||||||
|
|
@ -220,7 +217,7 @@ export function listen<T>(getter: () => T, fn: (value: T, previousValue: T | und
|
||||||
* @returns A function for disposing the effect.
|
* @returns A function for disposing the effect.
|
||||||
* @see https://github.com/littensy/charm?tab=readme-ov-file#subscribegetter-callback
|
* @see https://github.com/littensy/charm?tab=readme-ov-file#subscribegetter-callback
|
||||||
*/
|
*/
|
||||||
export function subscribe<T>(getter: () => T, fn: (value: T, previousValue: T) => void): Cleanup;
|
export function subscribe<T>(getter: Getter<T>, fn: (value: T, previousValue: T) => void): Cleanup;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new read-only signal that is computed by mapping over the entries
|
* Creates a new read-only signal that is computed by mapping over the entries
|
||||||
|
|
@ -232,19 +229,19 @@ export function subscribe<T>(getter: () => T, fn: (value: T, previousValue: T) =
|
||||||
* @see https://github.com/littensy/charm?tab=readme-ov-file#mappedgetter-mapper
|
* @see https://github.com/littensy/charm?tab=readme-ov-file#mappedgetter-mapper
|
||||||
*/
|
*/
|
||||||
export function mapped<VI, KI, VO, KO = KI>(
|
export function mapped<VI, KI, VO, KO = KI>(
|
||||||
getter: () => Map<KI, VI> | ReadonlyMap<KI, VI>,
|
getter: Getter<Map<KI, VI> | ReadonlyMap<KI, VI>>,
|
||||||
mapper: (value: VI, key: KI) => LuaTuple<[VO, KO]> | VO,
|
mapper: (value: VI, key: KI) => LuaTuple<[VO, KO]> | VO,
|
||||||
): () => ReadonlyMap<KO, VO>;
|
): Getter<ReadonlyMap<KO, VO>>;
|
||||||
// Overload for arrays
|
// Overload for arrays
|
||||||
export function mapped<VI, VO, K extends Key = number>(
|
export function mapped<VI, VO, K extends Key = number>(
|
||||||
getter: () => readonly VI[],
|
getter: Getter<readonly VI[]>,
|
||||||
mapper: (value: VI, key: number) => LuaTuple<[VO, K]> | VO,
|
mapper: (value: VI, key: number) => LuaTuple<[VO, K]> | VO,
|
||||||
): () => K extends number ? readonly VO[] : { readonly [P in K]: VO };
|
): Getter<K extends number ? readonly VO[] : { readonly [P in K]: VO }>;
|
||||||
// Overload for objects
|
// Overload for objects
|
||||||
export function mapped<VI, KI extends Key, VO, KO extends Key = KI>(
|
export function mapped<VI, KI extends Key, VO, KO extends Key = KI>(
|
||||||
getter: () => { readonly [K in KI]: VI },
|
getter: Getter<{ readonly [K in KI]: VI }>,
|
||||||
mapper: (value: VI, key: KI) => LuaTuple<[VO, KO]> | VO,
|
mapper: (value: VI, key: KI) => LuaTuple<[VO, KO]> | VO,
|
||||||
): () => { readonly [K in KO]: VO };
|
): Getter<{ readonly [K in KO]: VO }>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calls the callback function for each unique key in the table returned by the
|
* Calls the callback function for each unique key in the table returned by the
|
||||||
|
|
@ -263,12 +260,12 @@ export function mapped<VI, KI extends Key, VO, KO extends Key = KI>(
|
||||||
* @see https://github.com/littensy/charm?tab=readme-ov-file#observegetter-callback
|
* @see https://github.com/littensy/charm?tab=readme-ov-file#observegetter-callback
|
||||||
*/
|
*/
|
||||||
export function observe<V, K = number>(
|
export function observe<V, K = number>(
|
||||||
getter: () => Map<K, V> | ReadonlyMap<K, V> | readonly V[],
|
getter: Getter<Map<K, V> | ReadonlyMap<K, V> | readonly V[]>,
|
||||||
fn: (value: V, key: K) => Cleanup | void,
|
fn: (value: V, key: K) => Cleanup | void,
|
||||||
): Cleanup;
|
): Cleanup;
|
||||||
// Overload for objects
|
// Overload for objects
|
||||||
export function observe<V, K extends Key>(
|
export function observe<V, K extends Key>(
|
||||||
getter: () => { readonly [K in Key]: V },
|
getter: Getter<{ readonly [K in Key]: V }>,
|
||||||
fn: (value: V, key: K) => Cleanup | void,
|
fn: (value: V, key: K) => Cleanup | void,
|
||||||
): Cleanup;
|
): Cleanup;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,9 +16,12 @@ local checkDirty = system.checkDirty
|
||||||
local shallowPropagate = system.shallowPropagate
|
local shallowPropagate = system.shallowPropagate
|
||||||
local createReactiveSystem = system.createReactiveSystem
|
local createReactiveSystem = system.createReactiveSystem
|
||||||
|
|
||||||
type Cleanup = () -> ()
|
export type Getter<T> = () -> T
|
||||||
|
export type Setter<T> = (update: Update<T>) -> T
|
||||||
export type Atom<T = any> = (...((T) -> T) | T) -> T
|
export type Atom<T = any> = (...Update<T>) -> T
|
||||||
|
export type Update<T> = ((current: T) -> T) | T
|
||||||
|
export type Equals<T> = (current: T, incoming: T) -> boolean
|
||||||
|
export type Cleanup = () -> ()
|
||||||
|
|
||||||
type EffectScopeNode = ReactiveNode & {
|
type EffectScopeNode = ReactiveNode & {
|
||||||
cleanups: { Cleanup },
|
cleanups: { Cleanup },
|
||||||
|
|
@ -412,10 +415,7 @@ end
|
||||||
@return Setter function to update the signal value
|
@return Setter function to update the signal value
|
||||||
@see https://github.com/littensy/charm?tab=readme-ov-file#signalinitialValue-equals
|
@see https://github.com/littensy/charm?tab=readme-ov-file#signalinitialValue-equals
|
||||||
]]
|
]]
|
||||||
local function signal<T>(
|
local function signal<T>(initialValue: T, equals: Equals<T>?): (Getter<T>, Setter<T>)
|
||||||
initialValue: T,
|
|
||||||
equals: ((current: T, incoming: T) -> boolean)?
|
|
||||||
): (() -> T, (((T) -> T) | T) -> T)
|
|
||||||
local this: SignalNode = {
|
local this: SignalNode = {
|
||||||
currentValue = initialValue,
|
currentValue = initialValue,
|
||||||
pendingValue = initialValue,
|
pendingValue = initialValue,
|
||||||
|
|
@ -426,7 +426,7 @@ local function signal<T>(
|
||||||
deepFreeze(initialValue)
|
deepFreeze(initialValue)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function writeSignal(update: ((T) -> T) | T): T
|
local function writeSignal(update: Update<T>): T
|
||||||
local value: T
|
local value: T
|
||||||
|
|
||||||
-- Determine the new value based on whether the update is a function or
|
-- Determine the new value based on whether the update is a function or
|
||||||
|
|
@ -505,7 +505,7 @@ end
|
||||||
@param equals Optional comparator function to check for value changes
|
@param equals Optional comparator function to check for value changes
|
||||||
@see https://github.com/littensy/charm?tab=readme-ov-file#atominitialValue-equals
|
@see https://github.com/littensy/charm?tab=readme-ov-file#atominitialValue-equals
|
||||||
]]
|
]]
|
||||||
local function atom<T>(initialValue: T, equals: ((current: T, incoming: T) -> boolean)?): Atom<T>
|
local function atom<T>(initialValue: T, equals: Equals<T>?): Atom<T>
|
||||||
local get, set = signal(initialValue, equals)
|
local get, set = signal(initialValue, equals)
|
||||||
local function atomOper(...)
|
local function atomOper(...)
|
||||||
return if select("#", ...) == 0 then get() else set((...))
|
return if select("#", ...) == 0 then get() else set((...))
|
||||||
|
|
@ -522,7 +522,7 @@ end
|
||||||
@return A function that returns the cached value
|
@return A function that returns the cached value
|
||||||
@see https://github.com/littensy/charm?tab=readme-ov-file#computedgetter
|
@see https://github.com/littensy/charm?tab=readme-ov-file#computedgetter
|
||||||
]]
|
]]
|
||||||
local function computed<T>(getter: (previousValue: T?) -> T): () -> T
|
local function computed<T>(getter: (previousValue: T?) -> T): Getter<T>
|
||||||
local this: ComputedNode = {
|
local this: ComputedNode = {
|
||||||
flags = NONE,
|
flags = NONE,
|
||||||
getter = noYield(getter),
|
getter = noYield(getter),
|
||||||
|
|
@ -784,7 +784,7 @@ end
|
||||||
@param fn A signal or function that accesses signals
|
@param fn A signal or function that accesses signals
|
||||||
@return `fn` wrapped in a computed signal if needed
|
@return `fn` wrapped in a computed signal if needed
|
||||||
]]
|
]]
|
||||||
local function toComputed<T>(fn: () -> T): () -> T
|
local function toComputed<T>(fn: Getter<T>): Getter<T>
|
||||||
local name = debug.info(fn, "n")
|
local name = debug.info(fn, "n")
|
||||||
return if name == "readSignal" or name == "readComputed" or name == "atomOper" then fn else computed(fn)
|
return if name == "readSignal" or name == "readComputed" or name == "atomOper" then fn else computed(fn)
|
||||||
end
|
end
|
||||||
|
|
@ -802,7 +802,7 @@ end
|
||||||
@return A cleanup function that stops the effect
|
@return A cleanup function that stops the effect
|
||||||
@see https://github.com/littensy/charm?tab=readme-ov-file#listengetter-callback
|
@see https://github.com/littensy/charm?tab=readme-ov-file#listengetter-callback
|
||||||
]]
|
]]
|
||||||
local function listen<T>(getter: () -> T, fn: (state: T, previous: T?) -> ()): Cleanup
|
local function listen<T>(getter: Getter<T>, fn: (state: T, lastState: T?) -> ()): Cleanup
|
||||||
local tracked = toComputed(getter)
|
local tracked = toComputed(getter)
|
||||||
local current: T
|
local current: T
|
||||||
|
|
||||||
|
|
@ -826,7 +826,7 @@ end
|
||||||
@return A cleanup function that stops the effect
|
@return A cleanup function that stops the effect
|
||||||
@see https://github.com/littensy/charm?tab=readme-ov-file#subscribegetter-callback
|
@see https://github.com/littensy/charm?tab=readme-ov-file#subscribegetter-callback
|
||||||
]]
|
]]
|
||||||
local function subscribe<T>(getter: () -> T, fn: (state: T, lastState: T) -> ()): Cleanup
|
local function subscribe<T>(getter: Getter<T>, fn: (state: T, lastState: T) -> ()): Cleanup
|
||||||
local tracked = toComputed(getter)
|
local tracked = toComputed(getter)
|
||||||
local current: T
|
local current: T
|
||||||
local firstRun = true
|
local firstRun = true
|
||||||
|
|
@ -851,12 +851,12 @@ end
|
||||||
key is removed or the `observe()` effect is disposed. Effects created
|
key is removed or the `observe()` effect is disposed. Effects created
|
||||||
during the callback will also be bound to the lifetime of the key.
|
during the callback will also be bound to the lifetime of the key.
|
||||||
|
|
||||||
@param getter Function that returns a table
|
@param getter A signal or function that returns a table
|
||||||
@param fn Function that is called for each key added to the table
|
@param fn Function that is called for each key added to the table
|
||||||
@return A cleanup function that disposes scopes for all keys
|
@return A cleanup function that disposes scopes for all keys
|
||||||
@see https://github.com/littensy/charm?tab=readme-ov-file#observegetter-callback
|
@see https://github.com/littensy/charm?tab=readme-ov-file#observegetter-callback
|
||||||
]]
|
]]
|
||||||
local function observe<K, V>(getter: () -> { [K]: V }, fn: (item: V, key: K) -> ...Cleanup?): Cleanup
|
local function observe<K, V>(getter: Getter<{ [K]: V }>, fn: (item: V, key: K) -> ...Cleanup?): Cleanup
|
||||||
local innerScopes: { [K]: Cleanup } = {}
|
local innerScopes: { [K]: Cleanup } = {}
|
||||||
local disposed = false
|
local disposed = false
|
||||||
|
|
||||||
|
|
@ -907,11 +907,11 @@ end
|
||||||
of an existing atom. If the key is omitted from the mapper's return value,
|
of an existing atom. If the key is omitted from the mapper's return value,
|
||||||
the original key is preserved.
|
the original key is preserved.
|
||||||
|
|
||||||
@param getter Function that returns a table
|
@param getter A signal or function that returns a table
|
||||||
@param mapper Function that maps each entry from the source to a new entry in the mapped table
|
@param mapper Function that maps each entry from the source to a new entry in the mapped table
|
||||||
@see https://github.com/littensy/charm?tab=readme-ov-file#mappedgetter-mapper
|
@see https://github.com/littensy/charm?tab=readme-ov-file#mappedgetter-mapper
|
||||||
]]
|
]]
|
||||||
local function mapped<KI, VI, KO, VO>(getter: () -> { [KI]: VI }, mapper: (item: VI, key: KI) -> (VO, KO)): () -> { [KO]: VO }
|
local function mapped<KI, VI, KO, VO>(getter: Getter<{ [KI]: VI }>, mapper: (VI, KI) -> (VO, KO)): Getter<{ [KO]: VO }>
|
||||||
local currentInput: { [KI]: VI } = {}
|
local currentInput: { [KI]: VI } = {}
|
||||||
local keyCache: { [KI]: KO } = {}
|
local keyCache: { [KI]: KO } = {}
|
||||||
|
|
||||||
|
|
@ -984,9 +984,9 @@ return {
|
||||||
listen = listen,
|
listen = listen,
|
||||||
observe = observe,
|
observe = observe,
|
||||||
mapped = mapped :: (<KI, VI, KO, VO>(
|
mapped = mapped :: (<KI, VI, KO, VO>(
|
||||||
getter: () -> { [KI]: VI },
|
getter: Getter<{ [KI]: VI }>,
|
||||||
mapper: (item: VI, key: KI) -> (VO, KO)
|
mapper: (VI, KI) -> (VO, KO)
|
||||||
) -> () -> { [KO]: VO }) & (<K, VI, VO>(getter: () -> { [K]: VI }, mapper: (item: VI, key: K) -> VO) -> () -> { [K]: VO }),
|
) -> Getter<{ [KO]: VO }>) & (<K, VI, VO>(getter: Getter<{ [K]: VI }>, mapper: (VI, K) -> VO) -> Getter<{ [K]: VO }>),
|
||||||
onCleanup = onCleanup,
|
onCleanup = onCleanup,
|
||||||
getActiveSub = getActiveSub,
|
getActiveSub = getActiveSub,
|
||||||
setActiveSub = setActiveSub,
|
setActiveSub = setActiveSub,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue