woby
Version:
A high-performance framework with fine-grained observable/signal-based reactivity for building rich applications.
1,500 lines • 55.5 kB
JavaScript
"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