UNPKG

woby

Version:

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

1,500 lines 55.5 kB
"use strict"; const setters = require("./setters-CMvyty0B.cjs"); const runtime = require("./create_element-BUG6undN.cjs"); const root = require("./root-B1uuIGIw.cjs"); let counter = 0; let resolve$1 = setters.noop$1; const batch = async (fn, stack) => { if (!counter) { setters.setBatch(new Promise((r) => resolve$1 = r)); } try { counter += 1; return await fn(); } finally { counter -= 1; if (!counter) { setters.setBatch(void 0); resolve$1(stack); } } }; const isObservableBoolean = (value) => { return setters.isFunction$1(value) && setters.SYMBOL_OBSERVABLE_BOOLEAN in value; }; const isObservableFrozen = (value) => { var _a, _b; return setters.isFunction$1(value) && (setters.SYMBOL_OBSERVABLE_FROZEN in value || !!((_b = (_a = value[setters.SYMBOL_OBSERVABLE_READABLE]) == null ? void 0 : _a.parent) == null ? void 0 : _b.disposed)); }; const isUntracked = (value) => { return setters.isFunction$1(value) && (setters.SYMBOL_UNTRACKED in value || setters.SYMBOL_UNTRACKED_UNWRAPPED in value); }; class Memo extends setters.Observer { /* CONSTRUCTOR */ constructor(fn, options) { super(); this.fn = fn; this.observable = new setters.Observable(setters.UNINITIALIZED, options, this); const { stack } = options ?? { stack: setters.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 !== setters.UNAVAILABLE) { this.observable.set(result); } } stale(status, stack) { const statusPrev = this.status; if (statusPrev >= status) return; this.status = status; if (statusPrev === setters.DIRTY_MAYBE_YES) return; this.observable.stale(setters.DIRTY_MAYBE_YES, stack); } } const memo = (fn, options) => { const stack = (options == null ? void 0 : options.stack) ?? setters.callStack(); if (isObservableFrozen(fn)) { return fn; } else if (isUntracked(fn)) { return setters.frozen(fn(stack)); } else { const memo2 = new Memo(fn, options); const observable2 = setters.readable(memo2.observable, stack); return observable2; } }; const boolean = (value) => { if (setters.isFunction$1(value)) { if (isObservableFrozen(value) || isUntracked(value)) { return !!value(); } else if (isObservableBoolean(value)) { return value; } else { const boolean2 = memo(() => !!value()); boolean2[setters.SYMBOL_OBSERVABLE_BOOLEAN] = true; return boolean2; } } else { return !!value; } }; const disposed = (stack) => { const observable2 = new setters.Observable(false); const toggle = () => observable2.set(true); setters.cleanup(toggle); return setters.readable(observable2); }; function resolve(value) { if (setters.isFunction$1(value)) { if (setters.SYMBOL_UNTRACKED_UNWRAPPED in value) { return resolve(value()); } else if (setters.SYMBOL_UNTRACKED in value) { return setters.frozen(resolve(value())); } else if (setters.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 = setters.frozen(-1); let MappedRoot$1 = class MappedRoot extends root.Root { }; class CacheKeyed { /* CONSTRUCTOR */ constructor(fn) { this.parent = setters.OWNER; this.suspense = setters.OWNER.get(setters.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) { setters.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 = setters.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) { setters.cleanup(() => mapped.dispose(true)); } mapped.wrap(() => { let index = DUMMY_INDEX$1; if (fnWithIndex) { mapped.index = new setters.Observable(i); index = setters.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[setters.SYMBOL_CACHED] = true; } if (resultsUncached) { results[setters.SYMBOL_UNCACHED] = true; } return results; }; this.roots = () => { return Array.from(this.cache.values()); }; this.fn = fn; this.fnWithIndex = fn.length > 1; if (this.suspense) { setters.lazySetAdd(this.parent, "roots", this.roots); } } } let Suspense$1 = class Suspense extends setters.Owner { /* CONSTRUCTOR */ constructor() { var _a; super(); this.parent = setters.OWNER; this.context = { ...setters.OWNER.context, [setters.SYMBOL_SUSPENSE]: this }; setters.lazyArrayPush(this.parent, "suspenses", this); this.suspended = ((_a = setters.OWNER.get(setters.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 = setters.callStack(); (_a = this.observable) == null ? void 0 : _a.set(!!suspendedNext); const notifyOwner = (owner) => { setters.lazyArrayEach(owner.contexts, notifyOwner); setters.lazyArrayEach(owner.observers, notifyObserver); setters.lazyArrayEach(owner.suspenses, notifySuspense); setters.lazySetEach(owner.roots, notifyRoot); }; const notifyObserver = (observer) => { if (observer instanceof setters.Effect) { if (observer.status === setters.DIRTY_MAYBE_YES || observer.status === setters.DIRTY_YES) { if (observer.init) { observer.update(stack); } else { observer.schedule(stack); } } } notifyOwner(observer); }; const notifyRoot = (root2) => { if (setters.isFunction$1(root2)) { root2().forEach(notifyOwner); } else { notifyOwner(root2); } }; 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(setters.get(condition)); setters.effect(toggle, { sync: true, stack }); return suspense2.wrap(fn, void 0, void 0, stack); }; const DUMMY_INDEX = setters.frozen(-1); class MappedRoot2 extends root.Root { } class CacheUnkeyed { /* CONSTRUCTOR */ constructor(fn, pooled) { this.parent = setters.OWNER; this.suspense = setters.OWNER.get(setters.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) { setters.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 = setters.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 setters.Observable(index); $index = setters.readable(mapped.index, stack); } const observable2 = mapped.value = new setters.Observable(value); const suspended2 = pooled2 ? new setters.Observable(false) : void 0; if (suspended2) suspended2.stack = stack; const $value = memo(() => setters.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) { setters.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[setters.SYMBOL_CACHED] = true; } if (resultsUncached) { results[setters.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) { setters.lazySetAdd(this.parent, "roots", this.roots); } } } function _for(values, fn, fallback = [], options) { const stack = setters.callStack(); if (setters.isArray$1(values) && !setters.isStore(values)) { const isUnkeyed = !!(options == null ? void 0 : options.unkeyed); return setters.frozen(setters.untrack(() => { if (values.length) { return values.map((value, index) => { return resolve(fn(isUnkeyed && !setters.isObservable(value) ? setters.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); setters.cleanup(dispose); const value = memo(() => { return setters.get(values) ?? []; }, { equals: (next, prev) => { return !!next && !!prev && !next.length && !prev.length && !setters.isStore(next) && !setters.isStore(prev); }, stack }); return memo(() => { const array = value(); if (setters.isStore(array)) { array[setters.SYMBOL_STORE_VALUES]; } return setters.untrack(() => { const results = map(array); return (results == null ? void 0 : results.length) ? results : resolve(fallback); }); }, { equals: (next, prev) => { return setters.isArray$1(next) && !!next[setters.SYMBOL_CACHED] && setters.isArray$1(prev) && setters.isEqual(next, prev); }, stack }); } } const warmup = (value) => { setters.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 (setters.is(value[0], condition)) return value[1]; } return fallback; }; function _switch(when, values, fallback) { const isDynamic = setters.isFunction$1(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 setters.frozen(resolve(value())); } else { return memo(() => resolve(setters.get(value))); } } else { const value = match(setters.get(when), values, fallback); return setters.frozen(resolve(value)); } } const ternary = (when, valueTrue, valueFalse) => { const condition = boolean(when); return _switch(condition, [[true, valueTrue], [valueFalse]]); }; function observable(value, options) { const stack = setters.callStack(); return setters.writable(new setters.Observable(value, options), stack); } const isObservableWritable = (value) => { return setters.isFunction$1(value) && setters.SYMBOL_OBSERVABLE_WRITABLE in value; }; const target = (observable2) => { if (setters.isFunction$1(observable2)) { return observable2[setters.SYMBOL_OBSERVABLE_READABLE] || observable2[setters.SYMBOL_OBSERVABLE_WRITABLE] || setters.UNAVAILABLE; } else { return observable2; } }; const readonly = (observable2, stack) => { if (isObservableWritable(observable2)) { return setters.readable(target(observable2), stack); } else { return observable2; } }; const isEqualForSelector = (a, b) => { if ((a === 0 || setters.is(a, -0)) && (b === 0 || setters.is(b, -0))) return true; return setters.is(a, b); }; class DisposableMap extends Map { constructor() { super(...arguments); this.disposed = false; } } class SelectedObservable extends setters.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 = setters.untrack(source); return (value) => { return isEqualForSelector(value, sourceValue) ? setters.OBSERVABLE_TRUE : setters.OBSERVABLE_FALSE; }; } let selecteds = new DisposableMap(); let selectedValue = setters.untrack(source); const stack = setters.callStack(); setters.effect((stack2) => { var _a, _b; const valuePrev = selectedValue; const valueNext = source(); if (isEqualForSelector(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; }; setters.cleanup(cleanupAll); return (value) => { let selected = selecteds.get(value); if (selected) { selected.count += 1; } else { const isSelected = isEqualForSelector(value, selectedValue); selected = new SelectedObservable(isSelected); selected.selecteds = selecteds; selected.source = value; selecteds.set(value, selected); } setters.cleanup(selected); return setters.readable(selected); }; }; const suspended = (stack) => { const suspense2 = setters.OWNER.get(setters.SYMBOL_SUSPENSE); if (!suspense2) return setters.OBSERVABLE_FALSE; const observable2 = suspense2.observable || (suspense2.observable = new setters.Observable(!!suspense2.suspended)); return setters.readable(observable2, stack); }; const tick = (stack) => { setters.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 { setters.OWNER.errorHandler = observable$1; return resolve(value); } }); }; function untracked(fn) { const untracked2 = setters.isFunction$1(fn) ? (...args) => setters.untrack(() => fn(...args)) : () => fn; untracked2[setters.SYMBOL_UNTRACKED] = true; return untracked2; } const mark = (msg, ref) => setters.DEBUGGER.verboseComment ? runtime.jsx("comment", { ref, data: msg }) : runtime.jsx("text", { ref }); const useAttached = (ref, match2) => { const isGiven = !!ref; if (!ref) ref = observable(); const parent = observable(null); const fn = () => { if (!setters.get(ref)) return; const updateParent = () => { var _a; let currentParent = ((_a = setters.get(ref)) == null ? void 0 : _a.parentNode) || null; if (match2) { while (currentParent) { if (match2(currentParent)) { parent(currentParent); return !!currentParent; } currentParent = currentParent.assignedSlot ?? currentParent.parentNode ?? currentParent.host; } parent(null); return false; } else { parent(currentParent); return !!currentParent; } }; if (updateParent()) return; const callback = (mutationsList, observer2) => { var _a; if (((_a = mutationsList[0]) == null ? void 0 : _a.type) === "childList") { if (updateParent()) { observer2.disconnect(); return; } } }; const observer = new MutationObserver(callback); const config = { childList: true, // Crucial: Watch for children being added/removed subtree: true // Optional: Watch all descendants, not just direct children }; observer.observe(document, config); return () => observer.disconnect(); }; if (setters.isObservable(ref)) setters.effect(fn); else fn(); return { parent, mount: isGiven ? void 0 : mark("attached", ref), ref }; }; const useLightDom = (ref) => { const { parent, mount, ref: r } = useAttached(ref, (parent2) => !!parent2.assignedSlot); return { lightDom: parent, mount, ref: r }; }; function useResolved(values, callback, resolveFunction) { const isResolvable = resolveFunction !== false && callback !== false ? setters.isFunction : setters.isObservable; const resolve2 = (value) => isResolvable(value) ? value() : value; if (setters.isArray(values)) { const resolved = values.map(resolve2); if (setters.isFunction(callback)) { return callback.apply(void 0, resolved); } else { return resolved; } } else { const resolved = resolve2(values); if (setters.isFunction(callback)) { return callback(resolved); } else { return resolved; } } } function useEventListener(target2, event, handler, options) { const stack = new Error(); return setters.effect((stack2) => { const fn = setters.get(handler, false); return useResolved([target2, event, options], (target22, event2, options2) => { const targets = setters.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 = setters.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)); setters.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 (setters.get(loop)) tick2(); setters.get(callback, false)(value); }; const tick2 = () => { tickId = setters.untrack(() => schedule(work)); }; const dispose = () => { setters.untrack(() => cancel(tickId)); }; setters.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 } = setters.CONTEXTS_DATA.get(Context) || { symbol: Symbol() }; const valueContext = setters.context(symbol); const value = setters.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 = setters.context(setters.SYMBOL_SUSPENSE_COLLECTOR); if (collector) { collector == null ? void 0 : collector.register(data); setters.cleanup(() => collector.unregister(data)); } return data; }, get: () => { return setters.context(setters.SYMBOL_SUSPENSE$1); }, wrap: (fn) => { const data = SuspenseContext.create(); return setters.context({ [setters.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); setters.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(); setters.useRenderEffect(() => { const disposed2 = setters.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(setters.castError(exception)); value(void 0); latest(void 0); resource(resourceRejected); }; const fetch2 = () => { try { const value2 = setters.get(fetcher()); if (setters.isPromise(value2)) { onPending(); value2.then(onResolve, onReject); value2.then(unsuspend, unsuspend); } else { onResolve(value2); } } catch (error2) { onReject(error2); } }; fetch2(); }, stack); return setters.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, setters.get(options)), stack }); }; const useIdleLoop = (callback, options) => { const stack = new Error(); return useScheduler({ callback, loop: true, cancel: cancelIdleCallback, schedule: (callback2) => requestIdleCallback(callback2, setters.get(options)), stack }); }; const useInterval = (callback, ms) => { const stack = new Error(); return useScheduler({ callback, cancel: clearInterval, schedule: (callback2) => setInterval(callback2, setters.get(ms)), stack }); }; const usePromise = (promise) => { return useResource(() => setters.get(promise)); }; const useTimeout = (callback, ms) => { const stack = new Error(); return useScheduler({ callback, once: true, cancel: clearTimeout, schedule: (callback2) => setTimeout(callback2, setters.get(ms)), stack }); }; function useMounted(ref) { const given = !!ref; const internalRef = ref ?? observable(); const isMounted = memo(() => !!setters.get(internalRef)); const mount = !given ? mark("mount", internalRef) : void 0; return { ref: internalRef, isMounted, mount }; } function useMountedContext(ctx, ref) { const { parent: provider, ref: rf, mount } = useAttached(ref, (p) => p.tagName === "CONTEXT-PROVIDER" && !!(p == null ? void 0 : p[ctx.symbol])); const context = memo(() => { var _a; if (!setters.get(provider)) return; return (_a = setters.get(provider)) == null ? void 0 : _a[ctx.symbol]; }); Object.defineProperties(context, { length: { value: 2, writable: false, enumerable: false, configurable: false } }); return Object.assign([context, mount], context, { mount, ref: rf, context }); } 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 setters.untrack(() => setters.isFunction(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 = setters.get(value); if (!guard(current)) return valueLast; return valueLast = current; }); return () => { const current = guarded(); if (setters.isNil(current)) throw new Error("The value never passed the type guard"); return current; }; }; const If = ({ when, fallback, children }) => { if (setters.isFunction(children) && !setters.isObservable(children) && !setters.isComponent(children)) { const truthy = useGuarded(when, setters.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(() => !!setters.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 = setters.castArray(children); const values = childrenWithValues.map((child) => child().metadata); return _switch(when, values, fallback); }; Switch.Case = ({ when, children }) => { const metadata = { metadata: [when, children] }; return setters.assign(() => children, metadata); }; Switch.Default = ({ children }) => { const metadata = { metadata: [children] }; return setters.assign(() => children, metadata); }; const Ternary = ({ when, children }) => { return ternary(when, children[0], children[1]); }; let cachedConstructedSheets = null; let stylesheetObserver = null; function convertAllDocumentStylesToConstructed() { if (cachedConstructedSheets) { return cachedConstructedSheets; } const constructedSheets = []; for (let i = 0; i < document.styleSheets.length; i++) { const sheet = document.styleSheets[i]; try { const newSheet = new CSSStyleSheet(); let allRules = ""; for (let j = 0; j < sheet.cssRules.length; j++) { const rule = sheet.cssRules[j]; allRules += rule.cssText; } newSheet.replaceSync(allRules); constructedSheets.push(newSheet); } catch (e) { console.warn("Could not copy stylesheet:", e); } } cachedConstructedSheets = constructedSheets; return constructedSheets; } function observeStylesheetChanges() { if (stylesheetObserver) { return; } stylesheetObserver = new MutationObserver(() => { cachedConstructedSheets = null; }); stylesheetObserver.observe(document.head, { childList: true, subtree: true }); stylesheetObserver.observe(document, { childList: true, subtree: true }); } function mv(target2, source) { const targetValue = target2; const sourceValue = source; if (typeof targetValue === "string" && typeof sourceValue === "string") return `${targetValue} ${sourceValue}`.trim(); else if (typeof targetValue === "object" && typeof sourceValue === "object") return { ...targetValue, ...sourceValue }; return source; } const set = (target2, source, merge2) => { if (merge2) target2(mv(setters.get(target2), setters.get(source))); else target2(setters.get(source)); }; const isObject = (obj) => { if (obj == void 0) return false; if (obj.constructor.name == "Object") { return true; } else { return false; } }; const assign = (target2, source, options) => { if (!source) return target2; const { condition: method = "all", copyByRef = true, keepTargetNoObservable = false, track = false, merge: merge2 = [], copyOptions = false } = options ?? {}; const m = merge2.reduce((acc, item) => (acc[item] = true, acc), {}); const keys = (() => { switch (method) { case "new": return Object.keys(source).filter((key) => !(key in target2)); case "old": return Object.keys(target2).filter((key) => key in source); case "empty": return Object.keys(source).filter((key) => { const targetValue = target2[key]; const sourceValue = source[key]; const isTargetEmpty = targetValue === void 0 || targetValue === null || targetValue === 0 || isNaN(targetValue) || targetValue === "" || setters.isArray(targetValue) && targetValue.length === 0; const isSourceNonEmpty = !(sourceValue === void 0 || sourceValue === null || sourceValue === 0 || isNaN(sourceValue) || sourceValue === "" || setters.isArray(sourceValue) && sourceValue.length === 0); return isTargetEmpty && isSourceNonEmpty; }); default: return Object.keys(source); } })(); keys.forEach((key) => { if (copyByRef) { if (setters.isObservable(target2[key])) { set(target2[key], source[key], m[key]); if (track && setters.isObservable(source[key])) setters.effect(() => { set(target2[key], source[key], m[key]); }); } else { const temp = setters.get(target2[key]); target2[key] = setters.isObservable(source[key]) || setters.isFunction(source[key]) ? source[key] : observable(source[key]); if (m[key]) target2[key](mv(temp, setters.get(source[key]))); } } else { if (typeof setters.get(source[key]) === "object" && isObject(setters.get(source[key]))) { if (setters.isObservable(target2[key])) { if (typeof setters.get(target2[key]) === "object") assign(setters.get(target2[key]), setters.get(source[key]), options); else { target2[key](assign({}, setters.get(source[key]), options)); if (track && setters.isObservable(source[key])) setters.effect(() => { target2[key](assign({}, setters.get(source[key]), options)); }); } } else { const temp = target2[key]; target2[key] = keepTargetNoObservable ? assign(m[key] ? temp : {}, setters.get(source[key]), options) : observable(assign(m[key] ? temp : {}, setters.get(source[key]), options)); if (track && setters.isObservable(target2[key]) && setters.isObservable(source[key])) setters.effect(() => { target2[key](assign(m[key] ? temp : {}, setters.get(source[key]), options)); }); } } else { if (setters.isObservable(target2[key])) { set(target2[key], source[key], m[key]); const temp = setters.get(target2[key]); if (track && setters.isObservable(source[key])) setters.effect(() => target2[key](m[key] ? mv(temp, setters.get(source[key])) : setters.get(source[key]))); } else { const temp = target2[key]; target2[key] = keepTargetNoObservable ? source[key] : target2[key] = setters.isObservable(source[key]) || setters.isFunction(source[key]) ? source[key] : observable(source[key]); if (m[key]) target2[key](mv(temp, setters.get(source[key]))); if (track && setters.isObservable(target2[key]) && setters.isObservable(source[key])) { if (target2[key] !== source[key]) setters.effect(() => target2[key](m[key] ? mv(temp, setters.get(source[key])) : setters.get(source[key]))); } } } } }); return target2; }; const isJsxProp = (props) => props && props[setters.SYMBOL_JSX]; const make = (obj, options = { inplace: false, convertFunction: false }) => { const { inplace = false, convertFunction = false } = options; const o = inplace ? obj : { ...obj }; Object.keys(o).forEach((k) => { if (setters.isObservable(o[k])) return; if (typeof o[k] === "function" && !convertFunction) return; if (convertFunction || typeof o[k] !== "function") { o[k] = observable(o[k]); } }); return o; }; const merge = (target2, source) => { return assign(target2, source, { condition: "new" }); }; const defaults = (defs, component) => { const defFactory = () => { const d = defs(); if (d.children !== void 0 && !setters.isObservable(d.children)) d.children = observable(d.children); if (!d.children) d.children = observable(); return d; }; const compFactory = Object.assign( (props) => component(isJsxProp(props) ? merge(make(props, { inplace: true, convertFunction: false }), defFactory()) : props), { [setters.SYMBOL_DEFAULT]: defFactory } ); return compFactory; }; observeStylesheetChanges(); const setObservableValue = (obj, key, value) => { if (setters.isObservable(obj[key])) { if (!isObservableWritable(obj[key])) return; const observable2 = obj[key]; const options = observable2[setters.SYMBOL_OBSERVABLE_WRITABLE].options; const { type, fromHtml } = options ?? {}; if (type) { switch (type) { case "number": obj[key](fromHtml ? fromHtml(value) : Number(value)); break; case "boolean": if (fromHtml) { obj[key](fromHtml(value)); } else { const lowerValue = value == null ? void 0 : value.toLowerCase(); obj[key](lowerValue === "true" || lowerValue === "1" || lowerValue === ""); } break; case "bigint": if (fromHtml) { obj[key](fromHtml(value)); } else { try { obj[key](BigInt(value)); } catch (e) { obj[key](value); } } break; case "object": if (fromHtml) { obj[key](fromHtml(value)); } else { try { obj[key](JSON.parse(value)); } catch (e) { obj[key](value); } } break; case "function": obj[key](fromHtml ? fromHtml(value) : value); break; case "symbol": obj[key](fromHtml ? fromHtml(value) : Symbol(value)); break; case "undefined": obj[key](fromHtml ? fromHtml(value) : void 0); break; default: obj[key](fromHtml ? fromHtml(value) : value); break; } } else { obj[key](fromHtml ? fromHtml(value) : value); } } else { obj[key] = value; } }; const setNestedProperty = (obj, path, value) => { if (path.startsWith("style.")) { const styleProperty = setters.kebabToCamelCase(path.slice(6)); if (obj.style) { obj.style[styleProperty] = value; } return; } if (path.includes(".")) { const keys = path.split(".").map((key) => setters.kebabToCamelCase(key)); const lastKey = keys.pop(); let target2 = obj; for (let i = 0; i < keys.length; i++) { const key = keys[i]; if (i === 0 && !(key in target2)) { if (!target2.props) { target2.props = {}; } if (!(key in target2.props) || typeof target2.props[key] !== "object" || target2.props[key] === null) { target2.props[key] = {}; } target2 = target2.props[key]; } else if (!(key in target2) || typeof target2[key] !== "object" || target2[key] === null) { target2[key] = {}; target2 = target2[key]; } else { target2 = target2[key]; } } if (lastKey) { setObservableValue(target2, lastKey, value); } return; } setObservableValue(obj, setters.kebabToCamelCase(path), value); }; const customElement = (tagName, component) => { var _a; const defaultPropsFn = component[setters.SYMBOL_DEFAULT]; if (!defaultPropsFn) { console.error(`Component ${tagName} is missing default props. Please use the 'defaults' helper function to provide default props.`); } const C = (_a = class extends HTMLElement { constructor(props) { super(); this.childs = []; this.props = !!props ? props : defaultPropsFn() || {}; C.observedAttributes = Object.keys(this.props); if (!runtime.isJsx(this.props)) { const shadowRoot = this.attachShadow({ mode: "open", serializable: true }); if (!(setters.get(this.props.children) instanceof HTMLSlotElement)) { this.slots = document.createElement("slot"); this.props.children(this.slots); } const ignoreStyle = this.props.ignoreStyle === true; if (!ignoreStyle) { const allSheets = convertAllDocumentStylesToConstructed(); shadowRoot.adoptedStyleSheets = allSheets; } setters.setChild(shadowRoot, runtime.createElement(component, this.props), setters.FragmentUtils.make(), setters.callStack("Custom element")); } else { setters.setChild(this, runtime.createElement(component, this.props), setters.FragmentUtils.make(), setters.callStack("Custom element")); } if (!this.propDict) { this.propDict = {}; Object.keys(this.props).forEach((k) => { const c = setters.camelToKebabCase(k); this.propDict[c] = k; this.propDict[k] = c; }); } } /** * Called when the element is added to the document * * Sets up attribute observation and initializes the element. */ connectedCallback() { const { observedAttributes } = C; const { props: p } = this; const aKeys = Object.keys(p).filter((k) => ( /* !isPureFunction(p[k]) && !isObject(p[k]) && */ k !== "children" && setters.isObservable(p[k]) )); const rKeys = Object.keys(p).filter((k) => setters.isPureFunction(p[k]) || setters.isObject(p[k])); rKeys.forEach((k) => this.removeAttribute(k)); for (const k of aKeys) if (!this.attributes[this.propDict[k]] || runtime.isJsx(p)) setters.setProp(this, this.propDict[k], p[k], setters.callStack("connectedCallback")); for (const attr of this.attributes) this.attributeChangedCallback1(attr.name, void 0, attr.value); const observer = new MutationObserver((mutations) => { mutations.forEach((m) => { if (m.type === "attributes") { const name = m.attributeName; const newValue = this.getAttribute(name); const oldValue = m.oldValue; this.attributeChangedCallback1(name, oldValue, newValue); } }); }); observer.observe(this, { attributes: true, attributeOldValue: true }); } /** * Called when the element is removed from the document * * Cleans up observers and resources. */ disconnectedCallback() { } /** * Called when an observed attribute changes * * Updates the corresponding prop and handles nested properties. * * @param name - The name of the changed attribute * @param oldValue - The previous value of the attribute * @param newValue - The new value of the attribute */ attributeChangedCallback1(name, oldValue, newValue) { if (oldValue === newValue) return; if (newValue === "[object Object]") return; const { props } = this; if (name.includes("$") || name.includes(".")) { const normalizedPath = setters.normalizePropertyPath(name); setNestedProperty(this, normalizedPath, newValue); const propName = setters.kebabToCamelCase(name.replace(/\$/g, ".").replace(/\./g, ".")); setObservableValue(props, propName, newValue); } else { const propName = setters.kebabToCamelCase(name); setObservableValue(this.props, propName, newValue); } } }, _a.__component__ = component, _a.observedAttributes = [], _a); const ec = customElements.get(tagName); if (!!ec) console.warn(`Element ${tagName} already exists. (ignore this in dev env), use ec.__component__ to find target component`); else customElements.define(tagName, C); return C; }; const hidden = { toHtml: (o) => void 0 }; const ContextProvider = defaults( () => ({ value: observable(void 0), children: observable(void 0), symbol: observable(void 0) }), ({ children }) => { return children; } ); customElement("context-provider", ContextProvider); function createContext(defaultValue) { const symbol = Symbol(); const Provider = ({ value, children }) => { return setters.context({ [symbol]: value }, () => { const ref = observable(); setters.effect(() => { if (!setters.get(ref)) return; setters.get(ref)[symbol] = value; return () => delete setters.get(ref)[symbol]; }); return runtime.jsx("context-provider", { ref, value, symbol: observable(symbol, hidden), children: resolve(children) //must resolve, for non dom }); }); }; const Context = { Provider, symbol }; setters.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 = setters.SYMBOLS_DIRECTIVES)[name] || (_a[name] = Symbol()); const Provider = ({ children }) => { return setters.context({ [symbol]: data }, () => { return resolve(children); }); }; const ref = (...args) => { return (element) => { fn(element, ...args); }; }; const register = () => { if (symbol in setters.DIRECTIVES) throw new Error('Directive "name" is already registered'); setters.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 = !setters.isFunction(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(setters.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 = component