UNPKG

woby

Version:

A high-performance framework with fine-grained observable/signal-based reactivity for building rich applications.

1,120 lines (1,118 loc) 36.1 kB
import { aK as setBatch, aL as noop, aM as isFunction, aN as SYMBOL_OBSERVABLE_BOOLEAN, Z as SYMBOL_OBSERVABLE_FROZEN, _ as SYMBOL_OBSERVABLE_READABLE, $ as SYMBOL_UNTRACKED, w as SYMBOL_UNTRACKED_UNWRAPPED, aO as Observer, aP as Observable, aQ as UNINITIALIZED, C as callStack, aR as UNAVAILABLE, aS as DIRTY_MAYBE_YES, aT as frozen, aU as readable, R as cleanup, Y as SYMBOL_OBSERVABLE, y as OWNER, z as SYMBOL_SUSPENSE, B as lazySetDelete, aV as SYMBOL_CACHED, N as SYMBOL_UNCACHED, A as lazySetAdd, O as Owner, aW as lazyArrayPush, aX as lazyArrayEach, aY as lazySetEach, aZ as Effect, a_ as DIRTY_YES, J as effect, E as get, a$ as isArray, W as isStore, u as untrack, V as isObservable, b0 as isEqual, b1 as SYMBOL_STORE_VALUES, b2 as is, b3 as writable, a0 as SYMBOL_OBSERVABLE_WRITABLE, b4 as OBSERVABLE_TRUE, b5 as OBSERVABLE_FALSE, b6 as Scheduler, a7 as isArray$1, i as isFunction$1, ab as castArray, a1 as CONTEXTS_DATA, H as context, aj as isNil, I as SYMBOL_SUSPENSE_COLLECTOR, a3 as SYMBOL_SUSPENSE$1, G as useRenderEffect, h as assign, b7 as useCheapDisposed, ak as isPromise, ac as castError, af as isComponent, an as isTruthy, a4 as SYMBOLS_DIRECTIVES, a2 as DIRECTIVES, n as isObject } from "./setters-Ddu0s6oK.js"; import { R as Root } from "./root-B8Ruf358.js"; let counter = 0; let resolve$1 = noop; const batch = async (fn, stack) => { if (!counter) { setBatch(new Promise((r) => resolve$1 = r)); } try { counter += 1; return await fn(); } finally { counter -= 1; if (!counter) { setBatch(void 0); resolve$1(stack); } } }; const isObservableBoolean = (value) => { return isFunction(value) && SYMBOL_OBSERVABLE_BOOLEAN in value; }; const isObservableFrozen = (value) => { var _a, _b; return isFunction(value) && (SYMBOL_OBSERVABLE_FROZEN in value || !!((_b = (_a = value[SYMBOL_OBSERVABLE_READABLE]) == null ? void 0 : _a.parent) == null ? void 0 : _b.disposed)); }; const isUntracked = (value) => { return isFunction(value) && (SYMBOL_UNTRACKED in value || SYMBOL_UNTRACKED_UNWRAPPED in value); }; class Memo extends Observer { /* CONSTRUCTOR */ constructor(fn, options) { super(); this.fn = fn; this.observable = new Observable(UNINITIALIZED, options, this); const { stack } = options ?? { stack: callStack("Memo init") }; if ((options == null ? void 0 : options.sync) === true) { this.sync = true; this.update(stack); } } /* API */ run(stack) { const result = super.refresh(this.fn, stack); if (!this.disposed && this.observables.empty()) { this.disposed = true; } if (result !== UNAVAILABLE) { this.observable.set(result); } } stale(status, stack) { const statusPrev = this.status; if (statusPrev >= status) return; this.status = status; if (statusPrev === DIRTY_MAYBE_YES) return; this.observable.stale(DIRTY_MAYBE_YES, stack); } } const memo = (fn, options) => { const stack = (options == null ? void 0 : options.stack) ?? callStack(); if (isObservableFrozen(fn)) { return fn; } else if (isUntracked(fn)) { return frozen(fn(stack)); } else { const memo2 = new Memo(fn, options); const observable2 = readable(memo2.observable, stack); return observable2; } }; const boolean = (value) => { if (isFunction(value)) { if (isObservableFrozen(value) || isUntracked(value)) { return !!value(); } else if (isObservableBoolean(value)) { return value; } else { const boolean2 = memo(() => !!value()); boolean2[SYMBOL_OBSERVABLE_BOOLEAN] = true; return boolean2; } } else { return !!value; } }; const disposed = (stack) => { const observable2 = new Observable(false); const toggle = () => observable2.set(true); cleanup(toggle); return readable(observable2); }; function resolve(value) { if (isFunction(value)) { if (SYMBOL_UNTRACKED_UNWRAPPED in value) { return resolve(value()); } else if (SYMBOL_UNTRACKED in value) { return frozen(resolve(value())); } else if (SYMBOL_OBSERVABLE in value) { return value; } else { return memo(() => resolve(value())); } } if (value instanceof Array) { const resolved = new Array(value.length); for (let i = 0, l = resolved.length; i < l; i++) { resolved[i] = resolve(value[i]); } return resolved; } else { return value; } } const DUMMY_INDEX$1 = frozen(-1); let MappedRoot$1 = class MappedRoot extends Root { }; class CacheKeyed { /* CONSTRUCTOR */ constructor(fn) { this.parent = OWNER; this.suspense = OWNER.get(SYMBOL_SUSPENSE); this.cache = /* @__PURE__ */ new Map(); this.bool = false; this.prevCount = 0; this.reuseCount = 0; this.nextCount = 0; this.cleanup = () => { if (!this.prevCount) return; if (this.prevCount === this.reuseCount) return; const { cache, bool } = this; if (!cache.size) return; if (this.nextCount) { cache.forEach((mapped, value) => { if (mapped.bool === bool) return; mapped.dispose(true); cache.delete(value); }); } else { this.cache.forEach((mapped) => { mapped.dispose(true); }); this.cache = /* @__PURE__ */ new Map(); } }; this.dispose = () => { if (this.suspense) { lazySetDelete(this.parent, "roots", this.roots); } this.prevCount = this.cache.size; this.reuseCount = 0; this.nextCount = 0; this.cleanup(); }; this.before = () => { this.bool = !this.bool; this.reuseCount = 0; this.nextCount = 0; }; this.after = (values) => { this.nextCount = values.length; this.cleanup(); this.prevCount = this.nextCount; this.reuseCount = 0; }; this.map = (values) => { var _a; this.before(); const { cache, bool, fn: fn2, fnWithIndex } = this; const results = new Array(values.length); let resultsCached = true; let resultsUncached = true; let reuseCount = 0; const stack = callStack(); for (let i = 0, l = values.length; i < l; i++) { const value = values[i]; const cached = cache.get(value); if (cached && cached.bool !== bool) { resultsUncached = false; reuseCount += 1; cached.bool = bool; (_a = cached.index) == null ? void 0 : _a.set(i); results[i] = cached.result; } else { resultsCached = false; const mapped = new MappedRoot$1(false); if (cached) { cleanup(() => mapped.dispose(true)); } mapped.wrap(() => { let index = DUMMY_INDEX$1; if (fnWithIndex) { mapped.index = new Observable(i); index = readable(mapped.index, stack); } const result = results[i] = resolve(fn2(value, index)); mapped.bool = bool; mapped.result = result; if (!cached) { cache.set(value, mapped); } }, void 0, void 0, stack); } } this.reuseCount = reuseCount; this.after(values); if (resultsCached) { results[SYMBOL_CACHED] = true; } if (resultsUncached) { results[SYMBOL_UNCACHED] = true; } return results; }; this.roots = () => { return Array.from(this.cache.values()); }; this.fn = fn; this.fnWithIndex = fn.length > 1; if (this.suspense) { lazySetAdd(this.parent, "roots", this.roots); } } } let Suspense$1 = class Suspense extends Owner { /* CONSTRUCTOR */ constructor() { var _a; super(); this.parent = OWNER; this.context = { ...OWNER.context, [SYMBOL_SUSPENSE]: this }; lazyArrayPush(this.parent, "suspenses", this); this.suspended = ((_a = OWNER.get(SYMBOL_SUSPENSE)) == null ? void 0 : _a.suspended) || 0; } /* API */ toggle(force) { var _a; if (!this.suspended && !force) return; const suspendedPrev = this.suspended; const suspendedNext = suspendedPrev + (force ? 1 : -1); this.suspended = suspendedNext; if (!!suspendedPrev === !!suspendedNext) return; const stack = callStack(); (_a = this.observable) == null ? void 0 : _a.set(!!suspendedNext); const notifyOwner = (owner) => { lazyArrayEach(owner.contexts, notifyOwner); lazyArrayEach(owner.observers, notifyObserver); lazyArrayEach(owner.suspenses, notifySuspense); lazySetEach(owner.roots, notifyRoot); }; const notifyObserver = (observer) => { if (observer instanceof Effect) { if (observer.status === DIRTY_MAYBE_YES || observer.status === DIRTY_YES) { if (observer.init) { observer.update(stack); } else { observer.schedule(stack); } } } notifyOwner(observer); }; const notifyRoot = (root) => { if (isFunction(root)) { root().forEach(notifyOwner); } else { notifyOwner(root); } }; const notifySuspense = (suspense2) => { suspense2.toggle(force); }; notifyOwner(this); } wrap(fn, owner, observer, stack) { return super.wrap(fn, this, void 0, stack); } }; const suspense = (when, fn, stack) => { const suspense2 = new Suspense$1(); const condition = boolean(when); const toggle = () => suspense2.toggle(get(condition)); effect(toggle, { sync: true, stack }); return suspense2.wrap(fn, void 0, void 0, stack); }; const DUMMY_INDEX = frozen(-1); class MappedRoot2 extends Root { } class CacheUnkeyed { /* CONSTRUCTOR */ constructor(fn, pooled) { this.parent = OWNER; this.suspense = OWNER.get(SYMBOL_SUSPENSE); this.cache = /* @__PURE__ */ new Map(); this.pool = []; this.poolMaxSize = 0; this.cleanup = () => { let pooled2 = 0; let poolable = Math.max(0, this.pooled ? this.poolMaxSize - this.pool.length : 0); this.cache.forEach((mapped) => { var _a; if (poolable > 0 && pooled2++ < poolable) { (_a = mapped.suspended) == null ? void 0 : _a.set(true); this.pool.push(mapped); } else { mapped.dispose(true); } }); }; this.dispose = () => { if (this.suspense) { lazySetDelete(this.parent, "roots", this.roots); } this.cache.forEach((mapped) => { mapped.dispose(true); }); this.pool.forEach((mapped) => { mapped.dispose(true); }); }; this.map = (values) => { var _a, _b, _c, _d, _e, _f; const { cache, fn: fn2, fnWithIndex } = this; const cacheNext = /* @__PURE__ */ new Map(); const results = new Array(values.length); const pool = this.pool; const pooled2 = this.pooled; let resultsCached = true; let resultsUncached = true; let leftovers = []; const stack = callStack(); if (cache.size) { for (let i = 0, l = values.length; i < l; i++) { const value = values[i]; const cached = cache.get(value); if (cached) { resultsUncached = false; cache.delete(value); cacheNext.set(value, cached); (_a = cached.index) == null ? void 0 : _a.set(i); results[i] = cached.result; } else { leftovers.push(i); } } } else { leftovers = new Array(results.length); } outer: for (let i = 0, l = leftovers.length; i < l; i++) { const index = leftovers[i] || i; const value = values[index]; const isDuplicate = cacheNext.has(value); if (!isDuplicate) { for (const [key, mapped2] of cache.entries()) { cache.delete(key); cacheNext.set(value, mapped2); (_b = mapped2.index) == null ? void 0 : _b.set(index); (_c = mapped2.value) == null ? void 0 : _c.set(value); results[index] = mapped2.result; continue outer; } } resultsCached = false; let mapped; if (pooled2 && pool.length) { mapped = pool.pop(); (_d = mapped.index) == null ? void 0 : _d.set(index); (_e = mapped.value) == null ? void 0 : _e.set(value); (_f = mapped.suspended) == null ? void 0 : _f.set(false); results[index] = mapped.result; } else { mapped = new MappedRoot2(false); mapped.wrap(() => { let $index = DUMMY_INDEX; if (fnWithIndex) { mapped.index = new Observable(index); $index = readable(mapped.index, stack); } const observable2 = mapped.value = new Observable(value); const suspended2 = pooled2 ? new Observable(false) : void 0; if (suspended2) suspended2.stack = stack; const $value = memo(() => get(observable2.get())); const result = results[index] = suspended2 ? suspense(() => suspended2.get(), () => resolve(fn2($value, $index)), stack) : resolve(fn2($value, $index)); mapped.value = observable2; mapped.result = result; mapped.suspended = suspended2; }, void 0, void 0, stack); } if (isDuplicate) { cleanup(() => mapped.dispose(true)); } else { cacheNext.set(value, mapped); } } this.poolMaxSize = Math.max(this.poolMaxSize, results.length); this.cleanup(); this.cache = cacheNext; if (resultsCached) { results[SYMBOL_CACHED] = true; } if (resultsUncached) { results[SYMBOL_UNCACHED] = true; } return results; }; this.roots = () => { return [...this.cache.values(), ...this.pool.values()]; }; this.fn = fn; this.fnWithIndex = fn.length > 1; this.pooled = pooled; if (this.suspense) { lazySetAdd(this.parent, "roots", this.roots); } } } function _for(values, fn, fallback = [], options) { const stack = callStack(); if (isArray(values) && !isStore(values)) { const isUnkeyed = !!(options == null ? void 0 : options.unkeyed); return frozen(untrack(() => { if (values.length) { return values.map((value, index) => { return resolve(fn(isUnkeyed && !isObservable(value) ? frozen(value) : value, index)); }); } else { return resolve(fallback); } })); } else { const { dispose, map } = (options == null ? void 0 : options.unkeyed) ? new CacheUnkeyed(fn, !!options.pooled) : new CacheKeyed(fn); cleanup(dispose); const value = memo(() => { return get(values) ?? []; }, { equals: (next, prev) => { return !!next && !!prev && !next.length && !prev.length && !isStore(next) && !isStore(prev); }, stack }); return memo(() => { const array = value(); if (isStore(array)) { array[SYMBOL_STORE_VALUES]; } return untrack(() => { const results = map(array); return (results == null ? void 0 : results.length) ? results : resolve(fallback); }); }, { equals: (next, prev) => { return isArray(next) && !!next[SYMBOL_CACHED] && isArray(prev) && isEqual(next, prev); }, stack }); } } const warmup = (value) => { untrack(value); return value; }; const match = (condition, values, fallback) => { for (let i = 0, l = values.length; i < l; i++) { const value = values[i]; if (value.length === 1) return value[0]; if (is(value[0], condition)) return value[1]; } return fallback; }; function _switch(when, values, fallback) { const isDynamic = isFunction(when) && !isObservableFrozen(when) && !isUntracked(when); if (isDynamic) { if (isObservableBoolean(when)) { return memo(() => resolve(match(when(), values, fallback))); } const value = warmup(memo(() => match(when(), values, fallback))); if (isObservableFrozen(value)) { return frozen(resolve(value())); } else { return memo(() => resolve(get(value))); } } else { const value = match(get(when), values, fallback); return frozen(resolve(value)); } } const ternary = (when, valueTrue, valueFalse) => { const condition = boolean(when); return _switch(condition, [[true, valueTrue], [valueFalse]]); }; function observable(value, options) { const stack = callStack(); return writable(new Observable(value, options), stack); } const isObservableWritable = (value) => { return isFunction(value) && SYMBOL_OBSERVABLE_WRITABLE in value; }; const target = (observable2) => { if (isFunction(observable2)) { return observable2[SYMBOL_OBSERVABLE_READABLE] || observable2[SYMBOL_OBSERVABLE_WRITABLE] || UNAVAILABLE; } else { return observable2; } }; const readonly = (observable2, stack) => { if (isObservableWritable(observable2)) { return readable(target(observable2), stack); } else { return observable2; } }; class DisposableMap extends Map { constructor() { super(...arguments); this.disposed = false; } } class SelectedObservable extends Observable { constructor() { super(...arguments); this.count = 1; } /* API */ call() { if (this.selecteds.disposed) return; this.count -= 1; if (this.count) return; this.selecteds.delete(this.source); } } const selector = (source) => { source = warmup(memo(source)); if (isObservableFrozen(source)) { const sourceValue = untrack(source); return (value) => { return value === sourceValue ? OBSERVABLE_TRUE : OBSERVABLE_FALSE; }; } let selecteds = new DisposableMap(); let selectedValue = untrack(source); const stack = callStack(); effect((stack2) => { var _a, _b; const valuePrev = selectedValue; const valueNext = source(); if (is(valuePrev, valueNext)) return; selectedValue = valueNext; (_a = selecteds.get(valuePrev)) == null ? void 0 : _a.set(false); (_b = selecteds.get(valueNext)) == null ? void 0 : _b.set(true); }, { suspense: false, sync: true, stack }); const cleanupAll = () => { selecteds.disposed = true; }; cleanup(cleanupAll); return (value) => { let selected = selecteds.get(value); if (selected) { selected.count += 1; } else { selected = new SelectedObservable(value === selectedValue); selected.selecteds = selecteds; selected.source = value; selecteds.set(value, selected); } cleanup(selected); return readable(selected); }; }; const suspended = (stack) => { const suspense2 = OWNER.get(SYMBOL_SUSPENSE); if (!suspense2) return OBSERVABLE_FALSE; const observable2 = suspense2.observable || (suspense2.observable = new Observable(!!suspense2.suspended)); return readable(observable2, stack); }; const tick = (stack) => { Scheduler.flush(stack); }; const tryCatch = (value, fn) => { const observable$1 = observable(); return memo((stack) => { const error = observable$1(); if (error) { const reset = () => observable$1(void 0); const options = { error, reset }; return resolve(fn(options)); } else { OWNER.errorHandler = observable$1; return resolve(value); } }); }; function untracked(fn) { const untracked2 = isFunction(fn) ? (...args) => untrack(() => fn(...args)) : () => fn; untracked2[SYMBOL_UNTRACKED] = true; return untracked2; } function useResolved(values, callback, resolveFunction) { const isResolvable = resolveFunction !== false && callback !== false ? isFunction$1 : isObservable; const resolve2 = (value) => isResolvable(value) ? value() : value; if (isArray$1(values)) { const resolved = values.map(resolve2); if (isFunction$1(callback)) { return callback.apply(void 0, resolved); } else { return resolved; } } else { const resolved = resolve2(values); if (isFunction$1(callback)) { return callback(resolved); } else { return resolved; } } } function useEventListener(target2, event, handler, options) { const stack = new Error(); return effect((stack2) => { const fn = get(handler, false); return useResolved([target2, event, options], (target22, event2, options2) => { const targets = castArray(target22); targets.forEach((target3) => { target3 == null ? void 0 : target3.addEventListener(event2, fn, options2); }); return (stack3) => { targets.forEach((target3) => { target3 == null ? void 0 : target3.removeEventListener(event2, fn, options2); }); }; }); }, { sync: "init", stack }); } const useAbortController = (signals = []) => { signals = castArray(signals); const controller = new AbortController(); const abort = controller.abort.bind(controller); const aborted = signals.some((signal) => signal.aborted); if (aborted) { abort(); } else { signals.forEach((signal) => useEventListener(signal, "abort", abort)); cleanup(abort); } return controller; }; const useAbortSignal = (signals = []) => { return useAbortController(signals).signal; }; const useScheduler = ({ loop, once, callback, cancel, schedule, stack }) => { let executed = false; let suspended$1 = suspended(stack); let tickId; const work = (value) => { executed = true; if (get(loop)) tick2(); get(callback, false)(value); }; const tick2 = () => { tickId = untrack(() => schedule(work)); }; const dispose = () => { untrack(() => cancel(tickId)); }; effect(() => { if (once && executed) return; if (suspended$1()) return; tick2(); return dispose; }, { suspense: false, stack }); return dispose; }; const useAnimationFrame = (callback) => { const stack = new Error(); return useScheduler({ callback, once: true, cancel: cancelAnimationFrame, schedule: requestAnimationFrame, stack }); }; const useAnimationLoop = (callback) => { const stack = new Error(); return useScheduler({ callback, loop: true, cancel: cancelAnimationFrame, schedule: requestAnimationFrame, stack }); }; function useContext(Context) { const { symbol, defaultValue } = CONTEXTS_DATA.get(Context) || { symbol: Symbol() }; const valueContext = context(symbol); const value = isNil(valueContext) ? defaultValue : valueContext; return value; } const SuspenseContext = { create: () => { const count = observable(0); const active = memo(() => !!count()); const increment = (nr = 1) => count((prev) => prev + nr); const decrement = (nr = -1) => queueMicrotask(() => count((prev) => prev + nr)); const data = { active, increment, decrement }; const collector = context(SYMBOL_SUSPENSE_COLLECTOR); if (collector) { collector == null ? void 0 : collector.register(data); cleanup(() => collector.unregister(data)); } return data; }, get: () => { return context(SYMBOL_SUSPENSE$1); }, wrap: (fn) => { const data = SuspenseContext.create(); return context({ [SYMBOL_SUSPENSE$1]: data }, () => { return resolve(() => fn(data)); }); } }; class SuspenseManager { constructor() { this.suspenses = /* @__PURE__ */ new Map(); this.change = (suspense2, nr) => { const counter2 = this.suspenses.get(suspense2) || 0; const counterNext = Math.max(0, counter2 + nr); if (counter2 === counterNext) return; if (counterNext) { this.suspenses.set(suspense2, counterNext); } else { this.suspenses.delete(suspense2); } if (nr > 0) { suspense2.increment(nr); } else { suspense2.decrement(nr); } }; this.suspend = () => { const suspense2 = SuspenseContext.get(); if (!suspense2) return; this.change(suspense2, 1); cleanup(() => { this.change(suspense2, -1); }); }; this.unsuspend = () => { this.suspenses.forEach((counter2, suspense2) => { this.change(suspense2, -counter2); }); }; } } const useResource = (fetcher) => { const pending = observable(true); const error = observable(); const value = observable(); const latest = observable(); const { suspend, unsuspend } = new SuspenseManager(); const resourcePending = { pending: true, get value() { return void suspend(); }, get latest() { return latest() ?? void suspend(); } }; const resourceRejected = { pending: false, get error() { return error(); }, get value() { throw error(); }, get latest() { throw error(); } }; const resourceResolved = { pending: false, get value() { return value(); }, get latest() { return value(); } }; const resourceFunction = { pending: () => pending(), error: () => error(), value: () => resource().value, latest: () => resource().latest }; const resource = observable(resourcePending); const stack = new Error(); useRenderEffect(() => { const disposed2 = useCheapDisposed(); const onPending = () => { pending(true); error(void 0); value(void 0); resource(resourcePending); }; const onResolve = (result) => { if (disposed2()) return; pending(false); error(void 0); value(() => result); latest(() => result); resource(resourceResolved); }; const onReject = (exception) => { if (disposed2()) return; pending(false); error(castError(exception)); value(void 0); latest(void 0); resource(resourceRejected); }; const fetch2 = () => { try { const value2 = get(fetcher()); if (isPromise(value2)) { onPending(); value2.then(onResolve, onReject); value2.then(unsuspend, unsuspend); } else { onResolve(value2); } } catch (error2) { onReject(error2); } }; fetch2(); }, stack); return assign(readonly(resource, stack), resourceFunction); }; const useFetch = (request, init) => { return useResource(() => { return useResolved([request, init], (request2, init2 = {}) => { const signal = useAbortSignal(init2.signal || []); init2.signal = signal; return fetch(request2, init2); }); }); }; const useIdleCallback = (callback, options) => { const stack = new Error(); return useScheduler({ callback, once: true, cancel: cancelIdleCallback, schedule: (callback2) => requestIdleCallback(callback2, get(options)), stack }); }; const useIdleLoop = (callback, options) => { const stack = new Error(); return useScheduler({ callback, loop: true, cancel: cancelIdleCallback, schedule: (callback2) => requestIdleCallback(callback2, get(options)), stack }); }; const useInterval = (callback, ms) => { const stack = new Error(); return useScheduler({ callback, cancel: clearInterval, schedule: (callback2) => setInterval(callback2, get(ms)), stack }); }; const usePromise = (promise) => { return useResource(() => get(promise)); }; const useTimeout = (callback, ms) => { const stack = new Error(); return useScheduler({ callback, once: true, cancel: clearTimeout, schedule: (callback2) => setTimeout(callback2, get(ms)), stack }); }; const ErrorBoundary = ({ fallback, children }) => { return tryCatch(children, (props) => { const error = props.error instanceof Error ? props.error : new Error(String(props.error ?? "Unknown error")); const newProps = { error, reset: props.reset }; return untrack(() => isFunction$1(fallback) ? fallback(newProps) : fallback); }); }; function For({ values, fallback, unkeyed, children }) { return _for(values, children, fallback, { unkeyed }); } const useGuarded = (value, guard) => { let valueLast; const guarded = memo(() => { const current = get(value); if (!guard(current)) return valueLast; return valueLast = current; }); return () => { const current = guarded(); if (isNil(current)) throw new Error("The value never passed the type guard"); return current; }; }; const If = ({ when, fallback, children }) => { if (isFunction$1(children) && !isObservable(children) && !isComponent(children)) { const truthy = useGuarded(when, isTruthy); return ternary(when, untracked(() => children(truthy)), fallback); } else { return ternary(when, children, fallback); } }; const Suspense2 = ({ when, fallback, children }) => { return SuspenseContext.wrap((suspense$1) => { const condition = memo(() => !!get(when) || suspense$1.active()); const stack = new Error(); const childrenSuspended = suspense(condition, () => resolve(children), stack); return ternary(condition, fallback, childrenSuspended); }); }; const Switch = ({ when, fallback, children }) => { const childrenWithValues = castArray(children); const values = childrenWithValues.map((child) => child().metadata); return _switch(when, values, fallback); }; Switch.Case = ({ when, children }) => { const metadata = { metadata: [when, children] }; return assign(() => children, metadata); }; Switch.Default = ({ children }) => { const metadata = { metadata: [children] }; return assign(() => children, metadata); }; const Ternary = ({ when, children }) => { return ternary(when, children[0], children[1]); }; function createContext(defaultValue) { const symbol = Symbol(); const Provider = ({ value, children }) => { return context({ [symbol]: value }, () => { return resolve(children); }); }; const Context = { Provider, symbol }; CONTEXTS_DATA.set(Context, { symbol, defaultValue }); return Context; } const createDirective = (name, fn, options) => { var _a; const immediate = !!(options == null ? void 0 : options.immediate); const data = { fn, immediate }; const symbol = (_a = SYMBOLS_DIRECTIVES)[name] || (_a[name] = Symbol()); const Provider = ({ children }) => { return context({ [symbol]: data }, () => { return resolve(children); }); }; const ref = (...args) => { return (element) => { fn(element, ...args); }; }; const register = () => { if (symbol in DIRECTIVES) throw new Error('Directive "name" is already registered'); DIRECTIVES[symbol] = data; }; return { Provider, ref, register }; }; const COMPONENT_RE = /^_?[A-Z][a-zA-Z0-9$_-]*$/; const SYMBOL_AS = "__hmr_as__"; const SYMBOL_COLD_COMPONENT = Symbol("HMR.Cold"); const SYMBOL_HOT_COMPONENT = Symbol("HMR.Hot"); const SYMBOL_HOT_ID = Symbol("HMR.ID"); const SOURCES = /* @__PURE__ */ new WeakMap(); const hmr = (accept, component) => { if (accept) { const cached = component[SYMBOL_HOT_COMPONENT]; if (cached) return cached; const isProvider = !isFunction$1(component) && "Provider" in component; if (isProvider) return component; const createHotComponent = (path) => { return (...args) => { return memo((stack2) => { var _a; const component2 = path.reduce((component3, key) => component3[key], ((_a = SOURCES.get(id(stack2))) == null ? void 0 : _a()) || source()); const result = resolve(untrack(() => component2(...args))); return result; }); }; }; const createHotComponentDeep = (component2, path) => { const cached2 = component2[SYMBOL_HOT_COMPONENT]; if (cached2) return cached2; const hot2 = component2[SYMBOL_HOT_COMPONENT] = createHotComponent(path); for (const key in component2) { const value = component2[key]; if (isFunction$1(value) && COMPONENT_RE.test(key)) { hot2[key] = createHotComponentDeep(value, [...path, key]); } else { hot2[key] = value; } } return hot2; }; const onAccept = (module) => { var _a, _b; const hot2 = module[component[SYMBOL_AS]] || module[component.name] || module.default; if (!hot2) return console.error(`[hmr] Failed to handle update for "${component.name}" component: `, component); const cold2 = hot2[SYMBOL_COLD_COMPONENT] || hot2; (_a = hot2[SYMBOL_HOT_ID]) == null ? void 0 : _a.call(hot2, id()); (_b = SOURCES.get(id())) == null ? void 0 : _b(() => cold2); }; const id = observable({}); const source = observable(component); const stack = new Error(); SOURCES.set(id(stack), source); const cold = component[SYMBOL_COLD_COMPONENT] || component; const hot = createHotComponentDeep(component, []); cold[SYMBOL_HOT_COMPONENT] = hot; hot[SYMBOL_COLD_COMPONENT] = cold; hot[SYMBOL_HOT_COMPONENT] = hot; hot[SYMBOL_HOT_ID] = id; accept(onAccept); return hot; } else { return component; } }; var n = function(t2, s, r, e) { var u; s[0] = 0; for (var h = 1; h < s.length; h++) { var p = s[h++], a = s[h] ? (s[0] |= p ? 1 : 2, r[s[h++]]) : s[++h]; 3 === p ? e[0] = a : 4 === p ? e[1] = Object.assign(e[1] || {}, a) : 5 === p ? (e[1] = e[1] || {})[s[++h]] = a : 6 === p ? e[1][s[++h]] += a + "" : p ? (u = t2.apply(a, n(t2, a, r, ["", null])), e.push(u), a[0] ? s[0] |= 2 : (s[h - 2] = 0, s[h] = u)) : e.push(a); } return e; }, t = /* @__PURE__ */ new Map(); function htm(s) { var r = t.get(this); return r || (r = /* @__PURE__ */ new Map(), t.set(this, r)), (r = n(this, r.get(s) || (r.set(s, r = function(n2) { for (var t2, s2, r2 = 1, e = "", u = "", h = [0], p = function(n3) { 1 === r2 && (n3 || (e = e.replace(/^\s*\n\s*|\s*\n\s*$/g, ""))) ? h.push(0, n3, e) : 3 === r2 && (n3 || e) ? (h.push(3, n3, e), r2 = 2) : 2 === r2 && "..." === e && n3 ? h.push(4, n3, 0) : 2 === r2 && e && !n3 ? h.push(5, 0, true, e) : r2 >= 5 && ((e || !n3 && 5 === r2) && (h.push(r2, 0, e, s2), r2 = 6), n3 && (h.push(r2, n3, 0, s2), r2 = 6)), e = ""; }, a = 0; a < n2.length; a++) { a && (1 === r2 && p(), p(a)); for (var l = 0; l < n2[a].length; l++) t2 = n2[a][l], 1 === r2 ? "<" === t2 ? (p(), h = [h], r2 = 3) : e += t2 : 4 === r2 ? "--" === e && ">" === t2 ? (r2 = 1, e = "") : e = t2 + e[0] : u ? t2 === u ? u = "" : e += t2 : '"' === t2 || "'" === t2 ? u = t2 : ">" === t2 ? (p(), r2 = 1) : r2 && ("=" === t2 ? (r2 = 5, s2 = e, e = "") : "/" === t2 && (r2 < 5 || ">" === n2[a][l + 1]) ? (p(), 3 === r2 && (h = h[0]), r2 = h, (h = h[0]).push(2, 0, r2), r2 = 0) : " " === t2 || " " === t2 || "\n" === t2 || "\r" === t2 ? (p(), r2 = 2) : e += t2), 3 === r2 && "!--" === e && (r2 = 4, h = h[0]); } return p(), h; }(s)), r), arguments, [])).length > 1 ? r : r[0]; } function mergeStyles(style = {}, css = "") { const re = /([^:;]+)\s*:\s*([^;(]+(?:\(.*?\))?);?/igm; const genObj = (css2 = "") => { let match2; if (isObject(css2)) return css2; else { const style2 = {}; while (match2 = re.exec(css2)) { const [, property, value] = match2; const trimmedProperty = property.trim(); const trimmedValue = value.trim(); style2[trimmedProperty] = trimmedValue; } return style2; } }; const sty = genObj(style); return Object.assign(sty, genObj(css)); } export { createContext as A, createDirective as B, hmr as C, tick as D, ErrorBoundary as E, For as F, mergeStyles as G, suspense as H, If as I, isObservableWritable as J, Suspense2 as S, Ternary as T, useResolved as a, boolean as b, Switch as c, useAbortController as d, useAbortSignal as e, useAnimationFrame as f, useAnimationLoop as g, htm as h, useContext as i, disposed as j, useEventListener as k, useFetch as l, memo as m, useIdleCallback as n, observable as o, useIdleLoop as p, useInterval as q, resolve as r, usePromise as s, readonly as t, useResource as u, selector as v, suspended as w, useTimeout as x, untracked as y, batch as z }; //# sourceMappingURL=merge_style-CyMhMoCQ.js.map