import type { Dep, EffectFn, EffectOptions, EffectRunner, Subscriber } from './types'; /** Create a dependency slot (see {@link Dep}). */ export declare function createDep(): Dep; export declare const CLEAN = 0; /** A direct source definitely changed: must re-run / recompute. */ export declare const DIRTY: number; /** A computed source was invalidated: validate before running. */ export declare const MAYBE_DIRTY: number; /** Cycle guard: this computed's getter is currently executing. */ export declare const COMPUTING: number; /** * The computed's last refresh threw. A computed normally propagates * downstream only on its first dirtying per wave; an errored computed * stays DIRTY across waves, which would suppress that propagation and * wedge its subscribers after a transient getter error. This bit forces * one extra downstream propagation per mark (cleared on propagation, so * cycle termination is preserved) until a refresh succeeds. */ export declare const ERRORED: number; /** * Pull-validate a subscriber whose sources are all "maybe dirty": * refresh computed sources and report whether any source's version * actually advanced past the version recorded at track time. */ export declare function sourcesChanged(sub: Subscriber): boolean; export declare let currentSubscriber: Subscriber | null; export declare function setCurrentSubscriber(effect: Subscriber | null): void; export declare function getCurrentSubscriber(): Subscriber | null; /** * Batch multiple reactive updates into a single flush. * Effects are deferred until the batch completes, avoiding redundant re-renders. * * @example * ```ts * batch(() => { * count.value++; * name.value = 'Alice'; * }); // effects run once after both updates * ``` */ export declare function batch(fn: () => void): void; /** * Imperative batch bounds for hot paths that cannot afford a closure per * call (array mutator instrumentations, multi-dep writes). Callers MUST * pair them in try/finally — an unbalanced startBatch leaves batchDepth * stuck and effects never flush again. * @internal */ export declare function startBatch(): void; /** @internal see {@link startBatch} */ export declare function endBatch(): void; /** * Test-only override for the dev-mode runaway-wave limit (the default is * deliberately too large to reach in a unit test). Pass `null` to restore. * @internal */ export declare function setMaxWaveEffectRuns(limit: number | null): void; /** * Register a callback invoked at the end of every notification wave * (after all pending effects have run). Used by renderers to drain a * deduplicated job queue filled via the effect `scheduler` option. * * @internal exported via `@sigx/reactivity/internals` */ export declare function setFlushHandler(fn: (() => void) | null): void; /** * Full teardown — used on disposal (runner.stop, scope stop), NOT on * re-runs (those use startTracking/endTracking link reuse). Also repairs * dep.active pointers in case the subscriber is stopped mid-own-run. */ export declare function cleanup(effect: Subscriber): void; /** * Open a re-run's tracking window: install each existing link as its * dep's `active` link (saving the previous one for LIFO restore) and * clear its `seen` flag. track() then reuses installed links with a * single identity compare — no allocation, no Set operations — and * endTracking() sweeps whatever wasn't re-read. */ export declare function startTracking(sub: Subscriber): void; /** * Close a tracking window: restore each dep's previous `active` link * (LIFO — nested runs are strictly stacked), keep re-read links, and * unsubscribe from deps that were not read this run. */ export declare function endTracking(sub: Subscriber): void; export declare function track(dep: Dep): void; /** * Two-pass push: first MARK the whole downstream graph (computeds become * maybe-dirty, effects are queued and deduped), then FLUSH the queued * effects. Marking everything before running anything is what makes a * diamond (s → c1,c2 → e) glitch-free and single-run: when `e` executes, * both branches already know they must (re)validate. * * Effects still flush synchronously before the signal write returns * (unless an outer batch() is open), so write-then-assert code keeps * working unchanged. */ export declare function trigger(dep: Dep): void; /** * Create a reactive effect that re-runs whenever its tracked dependencies change. * Returns a runner with a `.stop()` method to dispose the effect. * * @example * ```ts * const count = signal(0); * const runner = effect(() => console.log(count.value)); * count.value++; // logs: 1 * runner.stop(); * ``` */ export declare function effect(fn: EffectFn, options?: EffectOptions): EffectRunner; /** * Create an effect WITHOUT registering it with the active effect scope. * For composite primitives (e.g. `watch`) that register their own, more * complete disposer with the scope instead. * @internal */ export declare function rawEffect(fn: EffectFn): EffectRunner; /** * Register a disposer with the currently-active effect scope, if any. * * When a `collectSetupScope()` region is active (component setup), the disposer * is captured into a lazily-allocated array instead — so a setup that creates * no reactions allocates nothing. * @internal */ export declare function registerWithActiveScope(dispose: () => void): void; /** * Register an arbitrary disposer with the currently-active scope — the * component setup being collected, or the innermost running `effectScope()`. * Returns `false` (without retaining `fn`) when no scope is active; the * caller owns the teardown itself then. * * This is the same registration path `effect()` and `watch()` use for their * own disposers, exposed for non-reactive resources (event listeners, timers, * observers) whose lifetime must match the owning scope's. * * @example * ```ts * function useIntervalFn(fn: () => void, ms: number) { * const id = setInterval(fn, ms); * onScopeDispose(() => clearInterval(id)); * } * * const scope = effectScope(); * scope.run(() => useIntervalFn(tick, 1000)); * scope.stop(); // interval cleared * ``` */ export declare function onScopeDispose(fn: () => void): boolean; /** * Execute a function without tracking any reactive dependencies. * Useful for reading signals inside an effect without creating a subscription. * * @example * ```ts * effect(() => { * const val = untrack(() => someSignal.value); // not tracked * }); * ``` */ export declare function untrack(fn: () => T): T; /** * Run `fn` (a component's setup) capturing every `effect()`, `watch()`, and * non-detached `effectScope()` it creates synchronously. The collected * disposers are retrievable via {@link takeSetupDisposers} immediately after — * the renderer stores them and runs them on unmount, tying setup reactions to * the component's lifetime. * * Zero-allocation for reaction-less setups: the backing array is created only * on the first registration. The region is detached — it owns its reactions * regardless of any outer effect scope active at mount time. * @internal */ export declare function collectSetupScope(fn: () => T): T; /** * Retrieve (and clear) the disposers collected by the most recent * {@link collectSetupScope} call, or `null` if it created no reactions. * @internal */ export declare function takeSetupDisposers(): (() => void)[] | null; /** * Create an effect scope that collects reactive effects for bulk disposal. * Effects and watchers created synchronously inside `run()` are disposed by * `stop()`. Scopes created inside another scope's `run()` are stopped with * their parent unless created with `effectScope(true)` (detached). * * @example * ```ts * const scope = effectScope(); * scope.run(() => { * effect(() => console.log(count.value)); * effect(() => console.log(name.value)); * }); * scope.stop(); // disposes both effects * ``` */ export declare function effectScope(detached?: boolean): { run(fn: () => T): T | undefined; stop(): void; }; //# sourceMappingURL=effect.d.ts.map