import { type BoundMap, type DOMAttributeValue, type ObjectToFunctionPropertyNames, type Observable, type Reference, type Subscription, type UnwrapRef } from "@knyt/artisan"; import type { PropertyChangePayload, ReactiveControllerHost } from "@knyt/tasker"; import type { PropertiesDefinition, PropertyDefinition, PropertyName, ReactiveProperties, ReactiveProperty } from "./types"; /** * This symbol is used to attach the reactive adapter to an element. * * @remarks * * This symbol must be in the runtime-wide symbol registry * (`Symbol.for`) so that the reactive adapter can be * accessed from within different contexts. * * @internal scope: workspace */ export declare const __reactiveAdapter: unique symbol; /** * Determines how the reactive adapter will handle updates. * * @internal scope: workspace */ export declare enum ReactiveUpdateMode { /** * Automatically request an update on the host when a property changes. * * @public */ Reactive = "reactive", /** * Does not automatically request an update when a property changes. * However, an event will still be emitted when a property changes. * * @public */ Manual = "manual" } declare enum ReactivePropertyChangeOrigin { /** * The property change originated from a property setter. */ Property = 0, /** * The property change originated from an attribute change. */ Attribute = 1 } /** * An object with reactive properties. * * @internal scope: workspace */ export type Reactive = { [__reactiveAdapter]: ReactiveAdapter; }; declare enum HookName { Update = "update", UpdateRequest = "updateRequested" } /** * A reactive adapter for managing reactive properties on an element. * * @internal scope: workspace */ export declare class ReactiveAdapter = Record> { #private; readonly isPropertyUpdating$: Reference.Readonly; constructor({ reactiveProperties, hooks, options, }: { reactiveProperties: ReactiveProperties; hooks: ReactiveAdapter.Hooks; options: ReactiveAdapter.Options; }); /** * Check if a property name is a valid reactive property. * * @internal scope: workspace */ isValidPropName(name: PropertyName): name is Exclude; /** * Get the value of a reactive property. */ getProp(name: K): Props[K] | undefined; /** * Set the value of a reactive property. */ setProp(name: K, value: Props[K]): void; /** * Set the values of multiple reactive properties at once. * * @public */ setProps(props: Partial): void; /** * Set the values of multiple reactive properties at once, * filtering out any invalid property names. * * @internal scope: package */ setPropsSafely(props: Partial): void; /** * Create an observable that emits property changes */ observePropChange(): Observable.WithSubscription>; /** * @internal scope: package */ _findPropConfig(propertyName: K): ReactiveProperty | undefined; /** * Create a reference to a reactive property value. * * @remarks * * This method is used to create a reference to a reactive property value * that will automatically update when the property value changes. */ refProp(propertyName: K): Reference.WithSubscription; refProp(propertyName: K, transform: (value: Props[K]) => T): Reference.SubscriberRetaining; refProp(propertyName: K, fallback: NonNullable extends (...args: any[]) => any ? never : NonNullable): Reference.SubscriberRetaining, Props[K]>; _refPropOnly(propertyName: K): Reference.WithSubscription; /** * Subscribe to property changes on the element. * * @beta */ onPropChange(propertyName: K, callback: (currentValue: Props[K], previousValue: Props[K]) => void): Subscription; onPropChange(listener: (payload: PropertyChangePayload) => void): Subscription; /** * Set a reactive property value from a property setter or an attribute change. */ _setReactivePropertyValue(changeOrigin: ReactivePropertyChangeOrigin, config: T, nextValue: PropertyDefinition.ToValue | undefined): void; /** * Get a reactive property value. * * @internal scope: package */ _getReactivePropertyValue(config: T): PropertyDefinition.ToValue | undefined; /** * Retrieves the changed properties since the last call to this method, * and resets the changed properties map. */ _flushChangedProperties(hookName: `${HookName}`): BoundMap.Readonly; /** * Get all reactive property values as an object. * * @remarks * Useful for accessing multiple properties at once. For best type safety, * prefer accessing individual properties directly. * * @public */ getProps(): Props; /** * Set the attribute values from reactive properties that have attribute names. * * @remarks * * While this method can technically be called at any time, it is primarily * intended to be called after the host has been fully constructed. This is * because attributes cannot be set on an element during its construction phase, * and doing so will result in the browser throwing an error. */ syncAttributeValues(): void; /** * Creates a dictionary of attribute names and their corresponding values * based on the reactive properties that have an associated attribute name. */ getAttributeValues(): Record; /** * Set attribute values on the element using the provided attribute values * using the hooks defined in the constructor. */ setAttributeValues(attributeValues: Record): void; /** * @internal scope: package */ _setPropertyFromAttributeChange(name: string, _prevAttributeValue: DOMAttributeValue, nextAttributeValue: DOMAttributeValue): void; /** * Creates a reference that maps a property value to a transformed value. * * @deprecated Use `mapRef` instead. */ mapProp

(propertyName: P, transform: (value: Props[P]) => T): Reference.SubscriberRetaining; /** * @deprecated Use `unwrapRef` instead. */ unwrapProp(propertyName: K): Reference.Unwrapped | undefined>; /** * @see https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_custom_elements */ handleAttributeChanged(name: string, previousValue: DOMAttributeValue, nextValue: DOMAttributeValue): void; /** * Get a snapshot of the internal state and configuration * of the reactive adapter. * * @internal scope: workspace */ getInternalSnapshot(): ReactiveAdapter.InternalSnapshot; } export declare namespace ReactiveAdapter { /** * @internal scope: workspace */ type Options = { updateMode?: `${ReactiveUpdateMode}`; }; /** * A set of hooks that can be used to interact with the element. * * @remarks * * These hooks are used to interact with the element in a way that is * compatible with the reactive adapter. They are used to perform actions * such as setting attributes, removing attributes, and requesting updates. * * @internal scope: package */ type Hooks = { isConnected?: HTMLElement["isConnected"]; removeAttribute?: HTMLElement["removeAttribute"]; setAttribute?: HTMLElement["setAttribute"]; requestUpdate?: ReactiveControllerHost["requestUpdate"]; }; /** * @internal scope: workspace */ type InternalSnapshot = { state: Record; hooks: ReactiveAdapter.Hooks; options: ReactiveAdapter.Options; }; } /** * Enables reactivity for a class instance. * * @remarks * * This function sets up reactive properties on the class prototype, * but only once per prototype. Each instance gets its own * `ReactiveAdapter`, so state is not shared. The check for * prototype reactivity adds miniscule overhead. * * @internal scope: package */ export declare function withReactivity({ instance, properties, hooks, options, }: { instance: T; properties: PropertiesDefinition

; hooks: ReactiveAdapter.Hooks; options: ReactiveAdapter.Options; }): void; /** * Updates the reactive properties defined on a prototype. * * @remarks * * This is useful for scenarios where the properties * definition has changed (such as during HMR), * and we need to update the prototype to reflect * those changes. * * This is typically only called when HMR is enabled. * * @internal scope: workspace */ export declare function updatePrototypeReactivity

({ proto, nextProperties, }: { proto: object; nextProperties: PropertiesDefinition

; }): void; /** * Sets up reactivity on an instance that already has * reactive properties defined on its prototype. * * @remarks * * This is useful for scenarios where the reactive properties * on the constructor prototype have changed, and we need * to update the instance to reflect those changes. * * This is typically only called when HMR is enabled. * * @internal scope: workspace */ export declare function updateInstanceReactivity({ instance, }: { instance: T; }): void; type MixableMemberName = ObjectToFunctionPropertyNames; export declare function applyReactiveMixin(Constructor: T, members?: MixableMemberName[]): void; export {}; //# sourceMappingURL=Reactive.d.ts.map