/** * Forces the immediate and synchronous execution of all pending reactive updates. * * Normally, changes to observed data sources (like proxied objects or arrays) * are processed asynchronously in a batch after a brief timeout (0ms). This function * allows you to bypass the timeout and process the update queue immediately. * * This can be useful in specific scenarios where you need the DOM to be updated * synchronously. * * This function is re-entrant, meaning it is safe to call `runQueue` from within * a function that is itself being executed as part of an update cycle triggered * by a previous (or the same) `runQueue` call. * * @example * ```typescript * const $data = A.proxy("before"); * * A('#', $data); * console.log(1, document.body.innerHTML); // before * * // Make an update that should cause the DOM to change. * $data.value = "after"; * * // Normally, the DOM update would happen after a timeout. * // But this causes an immediate update: * A.runQueue(); * * console.log(2, document.body.innerHTML); // after * ``` */ export declare function runQueue(): void; /** * Pause processing of reactive updates until the returned *thaw* function is called. * * While frozen, changes to observed data still accumulate, but no re-renders run. Freezes * stack: if there are multiple outstanding freezes, redraws resume only once the last one is * thawed. This is useful to batch an async burst of changes into a single update pass, or to * hold the UI steady (e.g. the dev tools use it for "freeze redraws"). * * @returns A function that releases this freeze. Calling it more than once has no effect. * * @example * ```typescript * const thaw = A.freeze(); * // ...make many changes without intermediate redraws... * thaw(); // redraws run now (if no other freezes remain) * ``` */ export declare function freeze(): () => void; /** * Creates a new string that has the opposite sort order compared to the input string. * * This is achieved by flipping the bits of each character code in the input string. * The resulting string is intended for use as a sort key, particularly with the * `makeKey` function in {@link onEach}, to achieve a descending sort order. * * **Warning:** The output string will likely contain non-printable characters or * appear as gibberish and should not be displayed to the user. * * @example * ```typescript * const $users = A.proxy([ * { id: 1, name: 'Charlie', score: 95 }, * { id: 2, name: 'Alice', score: 100 }, * { id: 3, name: 'Bob', score: 90 }, * ]); * * A.onEach($users, ($user) => { * A(`p#${$user.name}: ${$user.score}`); * }, ($user) => A.invertString($user.name)); // Reverse alphabetic order * ``` * * @param input The string whose sort order needs to be inverted. * @returns A new string that will sort in the reverse order of the input string. * @see {@link onEach} for usage with sorting. */ export declare function invertString(input: string): string; export declare function onEach(target: Map, render: (value: T, key: K) => void, makeKey?: (value: T, key: K) => SortKeyType): void; export declare function onEach(target: Set, render: (value: T) => void, makeKey?: (value: T) => SortKeyType): void; export declare function onEach(target: ReadonlyArray, render: (value: T, index: number) => void, makeKey?: (value: T, index: number) => SortKeyType): void; export declare function onEach(target: Record, render: (value: T, index: KeyToString) => void, makeKey?: (value: T, index: KeyToString) => SortKeyType): void; /** @private */ export declare const EMPTY: unique symbol; /** * Reactively checks if an observable array, object, Map, or Set is empty. * * This function not only returns the current emptiness state but also establishes * a reactive dependency. If the emptiness state of the `proxied` object or array * changes later (e.g., an item is added to an empty array, or the last property * is deleted from an object), the scope that called `isEmpty` will be automatically * scheduled for re-evaluation. * * @param proxied The observable array, object, Map, or Set to check. * @returns `true` if the array has length 0, the Map/Set has size 0, or the object has no own enumerable properties, `false` otherwise. * * @example * ```typescript * const $items = A.proxy([]); * * // Reactively display a message if the items array is empty * A('div', () => { * if (A.isEmpty($items)) { * A('p i#No items yet!'); * } else { * A.onEach($items, item => A('p#'+item)); * } * }); * * // Adding an item will automatically remove the "No items yet!" message * setInterval(() => { * if (!$items.length || Math.random()>0.5) $items.push('Item'); * else $items.length = 0; * }, 1000) * ``` */ export declare function isEmpty(proxied: TargetType): boolean; /** @private */ export interface ValueRef { value: T; } /** * Reactively counts the number of properties in an object. * * @param proxied The observable object to count. In case an `array`, `Map`, or `Set` is passed in, a {@link ref} to its `.length` or `.size` will be returned. * @returns an observable object for which the `value` property reflects the number of properties in `proxied` with a value other than `undefined`, or the collection size for arrays, Maps, and Sets. * * @example * ```typescript * const $items = A.proxy({x: 3, y: 7} as any); * const $count = A.count($items); * * // Create a DOM text node for the count: * A('div text=', $count); * //
2
* // Or we can use it in an {@link derive} function: * A(() => console.log("The count is now", $count.value)); * // The count is now 2 * * // Adding/removing items will update the count * $items.z = 12; * // Asynchronously, after 0ms: * //
3
* // The count is now 3 * ``` */ export declare function count(proxied: TargetType): ValueRef; /** * When `proxy` is called with a Promise, the returned object has this shape. */ export interface PromiseProxy { /** * True if the promise is still pending, false if it has resolved or rejected. */ busy: boolean; /** * If the promise has resolved, this contains the resolved value. */ value?: T; /** * If the promise has rejected, this contains the rejection error. */ error?: any; } export declare function proxy(target: Promise): PromiseProxy; export declare function proxy(target: Array): Array; export declare function proxy(target: T): T; export declare function proxy(target: T): ValueRef; /** * Returns the original, underlying data target from a reactive proxy created by {@link proxy}. * If the input `target` is not a proxy, it is returned directly. * * This is useful when you want to avoid triggering subscriptions during read operations or * re-executes during write operations. Using {@link peek} is an alternative way to achieve this. * * @param target - A proxied object, array, or any other value. * @returns The underlying (unproxied) data, or the input value if it wasn't a proxy. * @template T - The type of the target. * * @example * ```typescript * const $user = A.proxy({ name: 'Frank' }); * const rawUser = A.unproxy($user); * * // Log reactively * A(() => console.log('proxied', $user.name)); * // The following will only ever log once, as we're not subscribing to any observable * A(() => console.log('unproxied', rawUser.name)); * * // This cause the first log to run again: * setTimeout(() => $user.name += '!', 1000); * * // This doesn't cause any new logs: * setTimeout(() => rawUser.name += '?', 2000); * * // Both $user and rawUser end up as `{name: 'Frank!?'}` * setTimeout(() => { * console.log('final proxied', $user) * console.log('final unproxied', rawUser) * }, 3000); * ``` */ export declare function unproxy(target: T): T; /** * Recursively copies properties or array items from `src` to `dst`. * It's designed to work efficiently with reactive proxies created by {@link proxy}. * * - **Minimizes Updates:** When copying between objects/arrays (proxied or not), if a nested object * exists in `dst` with the same constructor as the corresponding object in `src`, `copy` * will recursively copy properties into the existing `dst` object instead of replacing it. * This minimizes change notifications for reactive (proxied) destinations. * - **Fast with Proxies:** When copying to/from proxied objects, `copy` uses Aberdeen internals * to speed things up (compared to a non-Aberdeen-aware deep copy). * * @param dst - The destination object/array/Map (proxied or unproxied). * @param src - The source object/array/Map (proxied or unproxied). It won't be modified. * @template T - The type of the objects being copied. * @returns `true` if any changes were made to `dst`, or `false` if not. * @throws Error if attempting to copy an array into a non-array or vice versa. * * @example Basic Copy * ```typescript * const $source = A.proxy({ a: 1, b: { c: 2 } }); * const $dest = A.proxy({ b: { d: 3 } }); * A.copy($dest, $source); * console.log($dest); // proxy({ a: 1, b: { c: 2 } }) * A.copy($dest, 'b', { e: 4 }); * console.log($dest); // proxy({ a: 1, b: { e: 4 } }) * ``` */ export declare function copy(dst: T, src: T): boolean; /** * Like above, but copies `src` into `dst[dstKey]`. This is useful if you're unsure if dst[dstKey] * already exists (as the right type of object) or if you don't want to subscribe to dst[dstKey]. * * @param dstKey - Optional key in `dst` to copy into. */ export declare function copy(dst: T, dstKey: keyof T, src: T[typeof dstKey]): boolean; /** * Like {@link copy}, but uses merge semantics. Properties in `dst` not present in `src` are kept. * `null`/`undefined` in `src` delete properties in `dst`. * * @example Basic merge * ```typescript * const source = { b: { c: 99 }, d: undefined }; // d: undefined will delete * const $dest = A.proxy({ a: 1, b: { x: 5 }, d: 4 }); * A.merge($dest, source); * A.merge($dest, 'b', { y: 6 }); // merge into $dest.b * A.merge($dest, 'c', { z: 7 }); // $dest.c doesn't exist yet, so it will just be assigned * console.log($dest); // proxy({ a: 1, b: { c: 99, x: 5, y: 6 }, c: { z: 7 } }) * ``` * */ export declare function merge(dst: T, value: Partial): boolean; export declare function merge(dst: T, dstKey: keyof T, value: Partial): boolean; /** * A symbol that controls how Aberdeen handles an object in copy operations and proxy wrapping. * * The **presence** of this symbol (regardless of its value) prevents deep-copying: the object is * stored and passed by reference in {@link clone} and {@link copy}. * * The **value** of the symbol controls proxy wrapping when the object is read from reactive state: * - **Truthy** (e.g. `true`): the object is fully opaque — it is not wrapped in a proxy, so its * properties are not observable. Use this for objects that break when proxied (e.g. class instances * with internal slots, Promises) or that must be invisible to Aberdeen's reactive system. * - **Falsy** (e.g. `false`): the object is still wrapped in a proxy, so reads on its properties * create reactive dependencies as normal — only deep-copying is suppressed. */ export declare const OPAQUE: unique symbol; /** * Use {@link OPAQUE} instead. This is an alias kept for backward compatibility. * * @deprecated */ export declare const NO_COPY: symbol; /** * A reactive object containing CSS variable definitions. * * Any property you assign to `cssVars` becomes available as a CSS custom property throughout your application. * * Use {@link setSpacingCssVars} to optionally initialize `cssVars[1]` through `cssVars[12]` with an exponential spacing scale. * * When you reference a CSS variable in Aberdeen using the `$` prefix (e.g., `$primary`), it automatically resolves to `var(--primary)`. * For numeric keys (which can't be used directly as CSS custom property names), Aberdeen prefixes them with `m` (e.g., `$3` becomes `var(--m3)`). * * When you add the first property to cssVars, Aberdeen automatically creates a reactive `