UNPKG

alien-dom

Version:

Next-generation JSX client renderer with observable data primitives, immediate DOM references, and more.

1,836 lines (1,804 loc) 124 kB
var __defProp = Object.defineProperty; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __publicField = (obj, key, value) => { __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); return value; }; // ../node_modules/.pnpm/@alloc+is@3.1.2/node_modules/@alloc/is/dist/is.mjs var { toString } = Object.prototype; var isArray = Array.isArray; var isBoolean = (value) => value === true || value === false; var isClass = (value) => isFunction(value) && value.toString().startsWith("class "); var isFunction = isOfType("function"); var isNan = Number.isNaN; var isNumber = (value) => isNumberLike(value) && !isNan(value); var isNumberLike = isOfType("number"); var isObject = isOfType("object"); var isObjectOrFunction = (value) => !!value && (isObject(value) || isFunction(value)); var isPromise = isObjectOfType("Promise"); var isPromiseLike = (value) => !!value && isFunction(value.then); var isString = isOfType("string"); var isPlainObject = (value) => { if (getObjectType(value) !== "Object") { return false; } const proto = Object.getPrototypeOf(value); return proto === null || proto === Object.getPrototypeOf({}); }; var isWhat = (value) => value === null ? "null" : isObjectOrFunction(value) ? getObjectType(value) || "Object" : typeof value; function isOfType(type) { return (value) => typeof value === type; } function isObjectOfType(type) { return (value) => getObjectType(value) === type; } function getObjectType(value) { const type = toString.call(value).slice(8, -1); if (type) { return type; } } // internal/constants.ts var kElementNodeType = 1; var kFragmentNodeType = 11; var kTextNodeType = 3; var kCommentNodeType = 8; var kAlienNodeType = Symbol.for("alien:nodeType"); var kShadowRootNodeType = 99; var kDeferredNodeType = 98; var kChildrenNodeType = 97; var kTemplateNodeType = 96; // internal/duck.ts function canMatch(node) { return typeof node.matches == "function"; } function hasForEach(arg) { return typeof arg.forEach == "function"; } function isIterable(arg) { return typeof arg[Symbol.iterator] == "function"; } function isArrayLike(obj) { return isObjectOrFunction(obj) && typeof obj.length === "number" && typeof obj.nodeType !== "number"; } function hasTagName(node, tagName) { return node && node.tagName === tagName; } function isNode(val) { return isObjectOrFunction(val) && isNumber(val.nodeType); } function isElement(node) { return node.nodeType === kElementNodeType; } function isFragment(node) { return node.nodeType === kFragmentNodeType; } function isTextNode(node) { return node.nodeType === kTextNodeType; } function isComment(node) { return node.nodeType === kCommentNodeType; } function isDocument(node) { return node.nodeType === 9; } // internal/privateSymbol.ts var hasOwn = Function.call.bind(Object.prototype.hasOwnProperty); var definePrivateSymbol = (name) => Symbol.for("alien:" + name); var bindPrivateSymbol = (property) => [ (target) => getPrivate(target, property), (target, value) => setPrivate(target, property, value) ]; var hasPrivate = (target, property) => hasOwn(target, property); var getPrivate = (target, property) => ( // Ensure the property is defined on the target directly, so we can avoid a // prototype lookup when the property is undefined. hasOwn(target, property) ? target[property] : void 0 ); var setPrivate = (target, property, value) => Object.defineProperty(target, property, { value, configurable: true }); // internal/symbols.ts var kAlienEffects = definePrivateSymbol("effects"); var kAlienElementKey = definePrivateSymbol("elementKey"); var kAlienElementPosition = definePrivateSymbol("elementPosition"); var kAlienElementTags = definePrivateSymbol("elementTags"); var kAlienFragmentKeys = definePrivateSymbol("fragmentKeys"); var kAlienFragmentNodes = definePrivateSymbol("fragmentNodes"); var kAlienHostProps = definePrivateSymbol("hostProps"); var kAlienInitialContext = definePrivateSymbol("initialContext"); var kAlienMemo = definePrivateSymbol("memo"); var kAlienParentFragment = definePrivateSymbol("parentFragment"); var kAlienRenderFunc = definePrivateSymbol("renderFunc"); var kAlienStateless = definePrivateSymbol("stateless"); var kAlienThunkResult = definePrivateSymbol("thunkResult"); var kAlienUnmountHandler = definePrivateSymbol("unmountHandler"); var [getElementKey, setElementKey] = bindPrivateSymbol(kAlienElementKey); var [getElementPosition, setElementPosition] = bindPrivateSymbol( kAlienElementPosition ); var [getElementTags, setElementTags] = bindPrivateSymbol(kAlienElementTags); var [getFragmentKeys, setFragmentKeys] = bindPrivateSymbol(kAlienFragmentKeys); var [getFragmentNodes, setFragmentNodes] = bindPrivateSymbol(kAlienFragmentNodes); var [getHostProps, setHostProps] = bindPrivateSymbol(kAlienHostProps); var [getParentFragment, setParentFragment] = bindPrivateSymbol(kAlienParentFragment); // functions/getElementIdentity.ts function getElementIdentity(element) { return getElementKey(element) ?? getElementPosition(element); } // internal/binaryInsert.ts function binaryInsert(array, insertValue, comparator) { if (array.length === 0 || comparator(array[0], insertValue) >= 0) { array.splice(0, 0, insertValue); return array; } else if (array.length > 0 && comparator(array[array.length - 1], insertValue) <= 0) { array.splice(array.length, 0, insertValue); return array; } let left = 0, right = array.length; let leftLast = 0, rightLast = right; while (left < right) { const inPos = Math.floor((right + left) / 2); const compared = comparator(array[inPos], insertValue); if (compared < 0) { left = inPos; } else if (compared > 0) { right = inPos; } else { right = inPos; left = inPos; } if (leftLast === left && rightLast === right) { break; } leftLast = left; rightLast = right; } array.splice(right, 0, insertValue); return array; } // addons/domObserver.ts var observersByRoot = /* @__PURE__ */ new WeakMap(); function observeDescendants(rootNode) { let result = observersByRoot.get(rootNode); if (!result) { const onAdded = /* @__PURE__ */ new Set(); const onRemoved = /* @__PURE__ */ new Set(); let queued = false; const added = /* @__PURE__ */ new Set(); const removed = /* @__PURE__ */ new Set(); const observer = new MutationObserver((mutations) => { for (const mutation of mutations) { for (const node of Array.from(mutation.addedNodes)) { if (isElement(node) || getElementIdentity(node)) { removed.delete(node) || added.add(node); } } for (const node of Array.from(mutation.removedNodes)) { if (isElement(node) || getElementIdentity(node)) { added.delete(node) || removed.add(node); } } } if (!queued) { queued = true; queueMicrotask(() => { queued = false; if (!added.size && !removed.size) { return; } const lastAdded = [...added]; const lastRemoved = [...removed]; added.clear(); removed.clear(); lastAdded.forEach((node) => { onAdded.forEach((listener) => listener(node)); }); lastRemoved.forEach((node) => { onRemoved.forEach((listener) => listener(node)); }); }); } }); observer.observe(rootNode, { childList: true, subtree: true }); observersByRoot.set( rootNode, result = { rootNode, onAdded, onRemoved, dispose() { observer.disconnect(); } } ); } return result; } function matchDescendants(target, selector, effect) { return observeNewDescendants(target, (parentNode) => { if (isElement(parentNode)) { parentNode.matches(selector) && effect(parentNode); parentNode.querySelectorAll(selector).forEach(effect); } }); } function observeNewChildren(target, listener) { return observeNewDescendants(target, (childNode) => { if (childNode.parentElement == target) { listener(childNode); } }); } function observeRemovedChildren(target, listener) { return observeRemovedDescendants(target, (childNode) => { if (childNode.parentElement == target) { listener(childNode); } }); } var observeNewDescendants = /* @__PURE__ */ defineEffectType( (target, callback) => { const observer = observeDescendants(target); observer.onAdded.add(callback); return () => removeElementListener(observer, "onAdded", callback); } ); var observeRemovedDescendants = /* @__PURE__ */ defineEffectType( (target, callback) => { const observer = observeDescendants(target); observer.onRemoved.add(callback); return () => removeElementListener(observer, "onRemoved", callback); } ); var onMount = (target, effect, rootNode = document) => createElementObserver(target, "onAdded", effect, rootNode); var onUnmount = (target, effect, rootNode = target.getRootNode()) => createElementObserver(target, "onRemoved", effect, rootNode); var depthFirstBatch = null; var createElementObserver = /* @__PURE__ */ defineEffectType( (target, key, effect, rootNode) => { const self = getCurrentEffect(); if (key == "onAdded" == target.isConnected) { self?.context?.remove(self); return effect(); } let depth = key == "onRemoved" ? getElementDepth(target) : null; function listener(parentNode) { if (parentNode === target || parentNode.contains(target)) { if (self?.context) { self.context.remove(self); } else { dispose(); } const batch = depthFirstBatch ||= []; if (!batch.length) { queueMicrotask(() => { depthFirstBatch = null; batch.forEach(([effect2]) => effect2()); }); } depth ??= getElementDepth(target); binaryInsert( batch, [effect, depth, target, key], ([, a], [, b]) => b - a ); } } const observer = observeDescendants(rootNode); observer[key].add(listener); function dispose() { removeElementListener(observer, key, listener); } return dispose; } ); function getElementDepth(elem, stopAt) { let depth = 0; while (elem.parentElement && elem.parentElement != stopAt) { depth++; elem = elem.parentElement; } return depth; } function removeElementListener(observer, key, listener) { if (observer[key].delete(listener) && !(observer.onAdded.size + observer.onRemoved.size)) { observersByRoot.delete(observer.rootNode); observer.dispose(); } } // internal/util.ts var set = Reflect.set; var defineProperty = Object.defineProperty; var noop = () => void 0; var keys = Object.keys; function decamelize(s, separator) { return s.replace(/[A-Z]/g, (match) => separator + match.toLowerCase()); } function at(arr, index) { return index < 0 ? arr[arr.length + index] : arr[index]; } function lastValue(array) { return array[array.length - 1]; } function toArray(a) { return isArray(a) ? a : [a]; } function forEach(arg, callback) { if (arg == null) return; if (hasForEach(arg)) { arg.forEach(callback); } else { callback(arg); } } function createState(init, params) { return isClass2(init) ? new init(...params) : init(...params); } function isClass2(arg) { return /^(class[ {]|function [A-Z])/.test(arg.toString()); } function compareNodeWithTag(node, tag) { if (tag === Fragment) { return isFragment(node); } if (isString(tag)) { return compareNodeNames(node.nodeName, tag); } if (isTemplateNode(tag)) { return node.nodeName === tag.template.nodeName; } const tags = getElementTags(node); return tags != null && tags.has(tag); } function compareNodeNames(fromNodeName, toNodeName) { if (fromNodeName !== toNodeName) { const fromCodeStart = fromNodeName.charCodeAt(0); const toCodeStart = toNodeName.charCodeAt(0); if (fromCodeStart <= 90 && toCodeStart >= 97) { return fromNodeName === toNodeName.toUpperCase(); } if (toCodeStart <= 90 && fromCodeStart >= 97) { return toNodeName === fromNodeName.toUpperCase(); } return false; } return true; } // core/disposable.ts function attachDisposer(object, dispose) { defineProperty(object, "dispose", { value: dispose, configurable: true, enumerable: true }); return object; } function isDisposable(arg) { return typeof arg.dispose === "function"; } function createDisposable(args, dispose, thisArg) { return { dispose: dispose.bind(thisArg, ...args), args, thisArg }; } function mergeDisposables(...objects) { return { objects, dispose() { for (const object of objects) { object.dispose(); } } }; } // internal/stack.ts var expectLastValue = (stack, message) => () => { const value = stack[stack.length - 1]; if (value === null) { throw Error(message); } return value; }; // internal/global.ts var currentEffects = [null]; var currentComponent = [null]; var currentNodeStore = [null]; var expectCurrentComponent = expectLastValue( currentComponent, "Component instance not found" ); // internal/linkedList.ts var LinkedList = class { first = null; last = null; add(item, prepend) { if (this.first) { if (prepend) { item.next = this.first; this.first.prev = item; this.first = item; } else { item.prev = this.last; if (this.last) { this.last.next = item; } this.last = item; } } else { this.first = this.last = item; } } remove(item) { if (item.prev) { item.prev.next = item.next; } else { this.first = item.next; } if (item.next) { item.next.prev = item.prev; } else { this.last = item.prev; } } forEach(callback, context) { let item = this.first; while (item) { const { prev } = item; callback.call(context, item); item = prev ? item.prev === prev ? item.next : prev.next : item === this.first ? item.next : this.first; } } }; // hooks/internal/useConstructor.ts function useConstructor(T) { const component = expectCurrentComponent(); const index = component.nextHookIndex++; return component.hooks[index] ||= new T(); } // functions/depsHaveChanged.ts function depsHaveChanged(deps, prevDeps) { if (deps === void 0 || prevDeps === void 0 || deps.length !== prevDeps.length) { return true; } if (deps !== prevDeps && deps.length > 0) { for (let i = 0; i < deps.length; i++) if (!Object.is(deps[i], prevDeps[i])) { return true; } } return false; } // functions/typeChecking.ts function isJSXChild(value) { if (value === null || value === void 0) { return false; } if (typeof value === "function") { return true; } return isNode(value); } // core/observable.ts var kRefType = Symbol.for("refType"); var hooks; var setObservableHooks = (newHooks) => { hooks = newHooks || false; } ; var unseenAccess = (ref2) => ref2._value; var nextDebugId = 1; var access = unseenAccess; var ReadonlyRef = class { constructor(_value, debugId) { this._value = _value; this.debugId = debugId ?? nextDebugId++; } debugId; _observers = /* @__PURE__ */ new Set(); get _depth() { return 0; } /** * In addition to adding/removing an observer, computed refs use this method * to switch between eager and lazy computation mode. */ _isObserved(observer, isObserved) { if (isObserved === this._observers.has(observer)) { return; } if (hooks) { peek(hooks.isObserved, this, observer, isObserved); } if (isObserved) { this._observers.add(observer); } else { this._observers.delete(observer); } } get [kRefType]() { return "ReadonlyRef"; } peek() { return this._value; } /** * Create a `ComputedRef` whose value is derived from `this.value` using the * given function. */ computedMap(compute) { return computed(() => compute(this.value)); } computedIf(trueValue, falseValue) { return computed( () => this.value ? evaluateInput(trueValue) : falseValue !== void 0 ? evaluateInput(falseValue) : void 0 ); } /** * Create a `ComputedRef` that uses the first argument if `this.value` is * falsy. Otherwise, undefined is used. Function arguments are called within * the `computed` function. */ computedElse(falseValue) { return computed(() => this.value ? void 0 : evaluateInput(falseValue)); } }; var Ref = class extends ReadonlyRef { get [kRefType]() { return "Ref"; } set(arg) { if (isFunction(arg)) { arg = arg(this.peek()); } this.value = arg; return arg; } /** Use the negation operator on the current value. */ toggle() { return this.value = !this.peek(); } }; function getValue() { return access(this); } function setValue(newValue) { const oldValue = this._value; if (newValue !== oldValue) { this._value = newValue; this._observers.forEach((observer) => { observer.observe(this, newValue, oldValue); updateHasSideEffects ||= !observer.isObservablyPure(); }); if (updateQueue.size > 0) { scheduleUpdates(); } } } Object.defineProperties(ReadonlyRef.prototype, { 0: { get: getValue }, [Symbol.iterator]: { value: function* () { yield this[0]; yield this[1]; } }, value: { get: getValue } }); Object.defineProperties(Ref.prototype, { 1: { get() { return this.set.bind(this); } }, value: { get: getValue, set: setValue } }); function assignPrototype(prototype, newProperties) { for (const key in newProperties) { Object.defineProperty(prototype, key, { value: newProperties[key], writable: true, configurable: true }); } } var ReadonlyArrayRef = class extends ReadonlyRef { get [kRefType]() { return "ArrayRef"; } }; var ArrayRef = class extends ReadonlyArrayRef { _arrayObservers = null; _produceOperation = noop; }; var numberRE = /^\d+$/; var kLengthRef = /* @__PURE__ */ definePrivateSymbol("lengthRef"); var updateLengthRef = (ref2, oldArray, newArray) => { if (ref2 && oldArray.length !== newArray.length) { ref2.value = newArray.length; } }; var arrayTraps = { get(target, key) { if (key === Symbol.iterator) { return () => target.value[Symbol.iterator](); } if (typeof key === "string" && numberRE.test(key)) { return target._value[+key]; } if (key === "length") { if (access === unseenAccess) { return target._value.length; } let lengthRef = getPrivate(target, kLengthRef); if (!lengthRef) { setPrivate( target, kLengthRef, lengthRef = new Ref(target._value.length) ); } return lengthRef.value; } return Reflect.get(target, key); }, set(target, key, newValue) { if (typeof key === "string" && numberRE.test(key)) { const index = +key; const oldArray = target._value; const isExpanding = index >= oldArray.length; if (isExpanding || newValue !== oldArray[index]) { const newArray = oldArray.slice(); newArray[index] = newValue; setValue.call(target, newArray); if (isExpanding) { updateLengthRef(getPrivate(target, kLengthRef), oldArray, newArray); } if (target._arrayObservers) { notifyArrayObservers(target, { type: "replace", index, newValue }); } } return true; } if (key === "length") { const oldArray = target._value; const delta = newValue - oldArray.length; if (delta) { const newArray = oldArray.slice(0, newValue); if (delta > 0) { newArray.length = newValue; } setValue.call(target, newArray); updateLengthRef(getPrivate(target, kLengthRef), oldArray, newArray); if (target._arrayObservers) { notifyArrayObservers( target, newValue > oldArray.length ? { type: "add", index: oldArray.length, count: delta, newArray } : { type: "remove", index: newValue, count: -delta, oldArray } ); } } return true; } if (key === "value") { const oldArray = target._value; if (newValue !== oldArray) { setValue.call(target, newValue); updateLengthRef(getPrivate(target, kLengthRef), oldArray, newValue); if (target._arrayObservers) { notifyArrayObservers(target, { type: "rebase", newArray: newValue, oldArray }); } } return true; } return Reflect.set(target, key, newValue); }, has(target, key) { if (typeof key === "string" && numberRE.test(key)) { return +key < target._value.length; } return Reflect.has(target, key); } }; var arrayRef = (init, debugId) => { arrayRef = (init2, debugId2) => new Proxy(new ArrayRef(init2 || [], debugId2), arrayTraps); const arrayMutator = (name) => function(...args) { const oldArray = this._value; const newArray = oldArray.slice(); const result = newArray[name](...args); setValue.call(this, newArray); updateLengthRef(getPrivate(this, kLengthRef), oldArray, newArray); if (this._arrayObservers) { const operation = this._produceOperation(name, args, oldArray, newArray); if (operation) { notifyArrayObservers(this, operation); } } return result; }; const arrayEnumerator = (name) => function(...args) { return this.value[name](...args); }; const createMethodReducer = (createMethod) => (methods, key) => { methods[key] = createMethod(key); return methods; }; assignPrototype(ArrayRef.prototype, { [kRefType]: "ArrayRef", observe(index) { return computed( () => this.value[index], isString(this.debugId) ? `${this.debugId}[${index}]` : void 0 ); }, ...[ "copyWithin", "fill", "pop", "push", "reverse", "shift", "sort", "splice", "unshift" ].reduce(createMethodReducer(arrayMutator), {}), ...[ "at", "concat", "entries", "every", "filter", "find", "findIndex", "flat", "flatMap", "forEach", "includes", "indexOf", "join", "keys", "lastIndexOf", "map", "reduce", "reduceRight", "slice", "some", "values" ].reduce(createMethodReducer(arrayEnumerator), {}) }); return arrayRef(init, debugId); }; var RefMap = class { _map; _sizeRef; _keysRef; constructor(entries) { this._map = new Map( entries && Array.from(entries, (entry) => [entry[0], ref(entry[1])]) ); this._sizeRef = ref(this._map.size); this._keysRef = arrayRef(Array.from(this._map.keys())); } get size() { return this._sizeRef.value; } get(key) { return computed(() => { const value = this._map.get(key); if (value) { return value.value; } computed(() => this._keysRef.includes(key)).value; return void 0; }).value; } peek(key) { return this._map.get(key)?.peek(); } peekSize() { return this._sizeRef.peek(); } set(key, newValue) { let value = this._map.get(key); if (value) { value.value = newValue; } else { this._map.set(key, value = ref(newValue)); this._keysRef.push(key); this._sizeRef.value++; } } delete(key) { if (this._map.delete(key)) { const keys2 = this._keysRef.peek(); this._keysRef.splice(keys2.indexOf(key), 1); this._sizeRef.value--; } } clear() { this._map.clear(); this._keysRef.length = 0; this._sizeRef.value = 0; } forEach(callback) { this._map.forEach((value, key) => callback(value.value, key, this)); } [Symbol.iterator]() { const keys2 = this._keysRef.value; let index = 0; return { next: () => { if (index < keys2.length) { const key = keys2[index++]; const value = this._map.get(key); return { value: [key, value.peek()], done: false }; } return { value: void 0, done: true }; } }; } }; var passThrough = (result) => result; var alwaysFalse = () => false; var nextObserverId = 1; var Observer = class { id = nextObserverId++; refs = /* @__PURE__ */ new Set(); depth = 0; constructor() { this.isObservablyPure ||= alwaysFalse; this.nextCompute ||= noop; this.didObserve ||= noop; this.willUpdate ||= noop; this.onUpdate ||= passThrough; } _access(ref2, oldRefs) { ref2._isObserved(this, true); oldRefs.delete(ref2); this.refs.add(ref2); this.depth = Math.max(this.depth, ref2._depth + 1); return ref2._value; } _update(sync, oldRefs) { this.refs.clear(); this.depth = 0; let error; let result; try { result = this.nextCompute(oldRefs); oldRefs.forEach((ref2) => { ref2._isObserved(this, false); }); result = this.onUpdate(result); } catch (e) { error = e; if (!sync) { console.error(error); } } if (hooks) { peek(hooks.didUpdate, this, error, result); } if (sync) { if (error) throw error; return result; } } /** * Run the `compute` function synchronously, observing any accessed refs. If * no `compute` function is provided, the last used `compute` function will be * reused. * * When those refs change, the `compute` function will run again in the next * microtask (unless you call this method before then). */ update(compute) { updateQueue.delete(this); const oldRefs = new Set(this.refs); const parentAccess = access; access = (ref2) => this._access(ref2, oldRefs); try { if (compute) { this.nextCompute = compute; } return this._update(true, oldRefs); } finally { access = parentAccess; } } /** Called when a ref has a new value. */ observe(ref2, newValue, oldValue) { if (hooks) { hooks.observe(this, ref2, newValue, oldValue); } this.didObserve(ref2, newValue, oldValue); this.scheduleUpdate(ref2, newValue, oldValue); } scheduleUpdate(ref2, newValue, oldValue) { if (!updateQueue.has(this)) { updateQueue.add(this); if (ref2) { this.willUpdate(ref2, newValue, oldValue); } else { updateHasSideEffects ||= !this.isObservablyPure(); scheduleUpdates(); } } } /** * Note: A disposed observer can still be reused. */ dispose() { updateQueue.delete(this); this.refs.forEach((ref2) => { ref2._isObserved(this, false); }); this.refs = /* @__PURE__ */ new Set(); } /** * Returns a bound `dispose` method. */ get destructor() { return this.dispose.bind(this); } }; var ArrayObserver = class extends Observer { constructor(target, compute) { super(); this.target = target; this.compute = compute; addArrayObserver(target, this); } operations = []; onOperation(operation) { forEach(operation, (operation2) => { if (operation2.type === "rebase") { this.operations.length = 0; } this.operations.push(operation2); this.scheduleUpdate(); }); } nextCompute() { const operations = [...this.operations]; this.operations.length = 0; this.compute(operations, this.target); } dispose() { super.dispose(); removeArrayObserver(this.target, this); } }; /** * When an `ArrayRef` is observed by an `ArrayObserver` (not to be confused * with a normal `Observer`), the `ArrayRef` will call this `produceOperation` * static method to produce the `ArrayOperation` set for a given mutation. */ __publicField(ArrayObserver, "produceOperation", (method, args, oldArray, newArray) => { switch (method) { case "push": return args.length > 0 && { type: "add", index: oldArray.length, count: args.length, newArray }; case "pop": return oldArray.length > 0 && { type: "remove", index: oldArray.length - 1, count: 1, oldArray }; case "shift": return oldArray.length > 0 && { type: "remove", index: 0, count: 1, oldArray }; case "unshift": return args.length > 0 && { type: "add", index: 0, count: args.length, newArray }; case "splice": let [start, deleteCount] = args; if (start < 0) { start = Math.max(0, oldArray.length + start); } const addOperation = args.length > 2 && { type: "add", index: start, count: args.length - 2, newArray }; const removeOperation = deleteCount > 0 && { type: "remove", index: start, count: Math.max(0, Math.min(deleteCount, oldArray.length - start)), oldArray }; return addOperation && removeOperation ? [removeOperation, addOperation] : addOperation || removeOperation; case "copyWithin": case "fill": case "reverse": case "sort": return { type: "rebase", oldArray, newArray }; } throw Error("Unknown array method: " + method); }); function addArrayObserver(ref2, observer) { ref2._arrayObservers ||= /* @__PURE__ */ new Set(); ref2._arrayObservers.add(observer); if (ref2._produceOperation === noop) { ref2._produceOperation = ArrayObserver.produceOperation; } } function removeArrayObserver(ref2, observer) { ref2._arrayObservers.delete(observer); if (ref2._arrayObservers.size === 0) { ref2._arrayObservers = null; } } function notifyArrayObservers(ref2, operation) { ref2._arrayObservers.forEach((observer) => { observer.onOperation(operation); }); } var emptySymbol = Symbol("empty"); var _ComputedRef = class extends ReadonlyRef { constructor(compute, debugId) { super(emptySymbol, debugId); this.compute = compute; } _observer = null; get _depth() { return this._observer?.depth ?? 0; } _isObserved(observer, isObserved) { if (isObserved && !this._observer) { this._observer = new _ComputedRef.Observer(this); this._observer.update(); } super._isObserved(observer, isObserved); if (!isObserved && !this._observers.size) { this._observer?.dispose(); this._observer = null; this._value = emptySymbol; } } get [kRefType]() { return "ComputedRef"; } get value() { if (access !== unseenAccess) { if (this._observer && this._value === emptySymbol) { this._observer.update(); } return super.value; } return this.peek(); } /** * Get the current value without observing it. If the ref is empty, the * `compute` function will run immediately. */ peek() { if (this._value === emptySymbol) { if (!this._observer) { return peek(this.compute); } this._observer.update(); } return this._value; } /** * Clear the current value. If the ref is observed, the `compute` function * will run again in the next microtask. */ clear() { if (this._observer) { this._observer.scheduleUpdate(); } else { this._value = emptySymbol; } } }; var ComputedRef = _ComputedRef; __publicField(ComputedRef, "Observer", class extends Observer { constructor(ref2) { super(); this.ref = ref2; } oldValue = emptySymbol; // The computed ref is cleared immediately upon an observed ref being // changed to prevent peeks from returning a possibly stale value. willUpdate() { this.oldValue = this.ref._value; this.ref._value = emptySymbol; } nextCompute() { return this.ref.compute(); } onUpdate(result) { this.ref._value = this.oldValue; this.oldValue = void 0; setValue.call(this.ref, result); return result; } }); var LensRef = class extends Ref { constructor(source, sink, debugId) { super(null, debugId); if (isFunction(source)) { source = new ComputedRef(source); } if (isRef(sink)) { sink = Reflect.set.bind(Reflect, sink, "value"); } defineProperty(this, "peek", { configurable: true, value: source.peek.bind(source) }); defineProperty(this, "value", { configurable: true, get: Reflect.get.bind(Reflect, source, "value"), set: sink }); } get [kRefType]() { return "LensRef"; } }; var TargetObserver = class extends Observer { constructor(target, onChange) { super(); this.target = target; this.onChange = onChange; } oldValue = emptySymbol; willUpdate(_ref, _newValue, oldValue) { if (this.oldValue === emptySymbol) { this.oldValue = oldValue; } } nextCompute() { return access(this.target); } onUpdate(newValue) { if (this.oldValue !== emptySymbol) { const { oldValue } = this; this.oldValue = emptySymbol; if (newValue !== oldValue) { peek(TargetObserver.onChange, this, newValue, oldValue); } } } static onChange(observer, newValue, oldValue) { observer.onChange(newValue, oldValue, observer.target); } }; var updateQueue = /* @__PURE__ */ new Set(); var updateScheduled = false; var updateHasSideEffects = false; function scheduleUpdates() { if (!updateScheduled) { updateScheduled = true; queueMicrotask(processUpdates); } } function sortObservers(a, b) { if (a.depth < b.depth) { return -1; } if (b.depth < a.depth) { return 1; } return a.id - b.id; } function processUpdates() { updateScheduled = false; const devError = Error("Cycle detected"); let skipPureObservers = false; let currentObserver; let oldRefs; const parentAccess = access; access = (ref2) => currentObserver._access(ref2, oldRefs); const update = (observer) => { if (skipPureObservers && observer.isObservablyPure()) { return; } if (updateQueue.delete(observer)) { oldRefs = new Set(observer.refs); currentObserver = observer; currentObserver._update(false, oldRefs); } }; for (let loops = 0; updateQueue.size > 0; loops++) { if (loops > 100) { updateQueue.clear(); throw devError || Error("Cycle detected"); } if (updateQueue.size) { skipPureObservers = updateHasSideEffects; updateHasSideEffects = false; const updatedObservers = [...updateQueue].sort(sortObservers); updatedObservers.forEach(update); } } access = parentAccess; } function collectAccessedRefs(fn, accessedRefs) { const parentAccess = access; access = (ref2) => { accessedRefs.add(ref2); return parentAccess(ref2); }; try { return fn(); } finally { access = parentAccess; } } var ref = (value, debugId) => new Ref(value, debugId); var refMap = (entries) => new RefMap(entries); var computed = (compute, debugId) => new ComputedRef(compute, debugId); var computedEvery = (inputs, debugId) => new ComputedRef(() => inputs.every(evaluateInput), debugId); var computedSome = (inputs, debugId) => new ComputedRef(() => inputs.some(evaluateInput), debugId); var lens = (compute, set2, debugId) => new LensRef(compute, set2, debugId); function observe(arg1, arg2) { let observer; if (isFunction(arg1)) { observer = new Observer(); observer.update(arg1); } else { observer = new TargetObserver(arg1, arg2); observer.update(); } return observer; } var observeArrayOperations = (arrayRef2, handler) => new ArrayObserver(arrayRef2, handler); function isReadonlyRef(arg) { return isRef(arg) && !Object.getOwnPropertyDescriptor(arg, "value").set; } function isRef(value) { return Boolean(value) && value[kRefType] !== void 0; } function isArrayRef(value) { return Boolean(value) && value[kRefType] === "ArrayRef"; } function guardRef(value, guard) { return isRef(value) ? guard(value.peek()) : guard(value); } function peek(arg1, ...rest) { if (access === unseenAccess) { return isFunction(arg1) ? arg1(...rest) : arg1[rest[0]]; } const parentAccess = access; access = unseenAccess; try { if (isFunction(arg1)) { return arg1(...rest); } return arg1[rest[0]]; } finally { access = parentAccess; } } var unref = (arg) => isRef(arg) ? arg.value : arg; var evaluateInput = (arg) => unref(isFunction(arg) ? arg() : arg); function when(condition, effect) { const value = condition.peek(); if (value) { return attachDisposer( effect ? Promise.resolve().then(() => effect(value)) : Promise.resolve(value), noop ); } let observer; return attachDisposer( new Promise((resolve, reject) => { observer = observe(condition, (value2) => { if (!value2) return; observer.dispose(); if (effect) { try { resolve(effect(value2)); } catch (error) { reject(error); } } else { resolve(value2); } }); }), () => { observer.dispose(); } ); } // hooks/useDepsArray.ts function useDepsArray(deps) { const component = expectCurrentComponent(); const index = component.nextHookIndex++; const prevDeps = component.hooks[index]; component.hooks[index] = deps; return depsHaveChanged(deps, prevDeps); } // internal/onceMounted.ts var pendingCallbacks = /* @__PURE__ */ new WeakMap(); function onceMounted(node, callback) { if (node.isConnected) { callback(node); } else { const callbacks = pendingCallbacks.get(node); if (callbacks) { if (isFunction(callbacks)) { pendingCallbacks.set(node, /* @__PURE__ */ new Set([callbacks, callback])); } else { callbacks.add(callback); } } else { pendingCallbacks.set(node, callback); } return () => { const callbacks2 = pendingCallbacks.get(node); if (isFunction(callbacks2)) { pendingCallbacks.delete(node); } else if (callbacks2) { callbacks2.delete(callback); if (callbacks2.size === 0) { pendingCallbacks.delete(node); } } }; } } function notifyMounted(node) { if (node.isConnected) { notifyMountedRecursive(node); } else if (isFragment(node)) { const childNodes = getFragmentNodes(node); if (childNodes) { for (const childNode of childNodes) if (childNode?.isConnected) { notifyMountedRecursive(childNode); } } } } function notifyMountedRecursive(node) { const callbacks = pendingCallbacks.get(node); if (callbacks) { pendingCallbacks.delete(node); if (isFunction(callbacks)) { try { callbacks(node); } catch (error) { console.error(error); } } else { for (const callback of callbacks) { try { callback(node); } catch (error) { console.error(error); } } } } if (isElement(node)) { for (let i = 0; i < node.childNodes.length; i++) { notifyMountedRecursive(node.childNodes[i]); } } } // internal/elementProxy.ts var kElementProxyType = Symbol.for("ElementProxy"); var InternalElementProxy = class { /** The element that was set. */ _element = null; /** * Pending effects that will be called when an element is set. They exist when * `onceElementExists` is called before an element has been set. */ _pendingEffects = null; constructor(effect) { if (effect) { onceElementExists(this, effect); } } get [kElementProxyType]() { return true; } toElement() { return this._element; } setElement(element) { const pendingEffects = this._pendingEffects; this._pendingEffects = null; this._element = element; if (element) { pendingEffects?.forEach((effect) => effect(element)); } } // This must be named `dispose` for HMR to clear it on updates. dispose() { this._pendingEffects = null; } }; function onceElementExists(ref2, effect) { let dispose; if (ref2._element) { return effect(ref2._element); } const pendingEffect = (element) => { dispose = effect(element); }; const pendingEffects = ref2._pendingEffects ||= /* @__PURE__ */ new Set(); pendingEffects.add(pendingEffect); return () => { pendingEffects.delete(pendingEffect); dispose?.(); }; } // addons/elementProxy.ts function createElementProxy(effect) { const ref2 = new InternalElementProxy(effect); return new Proxy(ref2, { get(target, prop) { if (prop === kElementProxyType) { return true; } if (ref2._element && prop in ref2._element) { const value = ref2._element[prop]; return typeof value === "function" ? value.bind(ref2._element) : value; } return target[prop]; }, set(target, prop, value) { if (ref2._element && prop in ref2._element) { target = ref2._element; } return Reflect.set(target, prop, value); } }); } var isElementProxy = (arg) => !!(arg && arg[kElementProxyType]); // core/unmount.ts function unmount(node, skipRemove, keepComponent) { if (isElementProxy(node)) { node = node.toElement(); } if (node?.isConnected) { if (isFragment(node)) { const childNodes = getFragmentNodes(node) || Array.from(node.childNodes); for (let i = childNodes.length - 1; i >= 0; i--) { const childNode = childNodes[i]; if (childNode) { unmountTree(childNode, skipRemove); } } } else { unmountTree(node, skipRemove, keepComponent); } } } function unmountTree(node, skipRemove, keepComponent) { if (!skipRemove) { node.remove(); } if (isElement(node)) { for (let childNode = node.lastChild; childNode; childNode = childNode.previousSibling) { unmountTree(childNode, true); } const hostProps = getHostProps(node); hostProps?.unmount(); } const effects = getPrivate(node, kAlienEffects); effects?.disable(true); const tags = getElementTags(node); if (tags) { for (const component of tags.values()) { if (component === keepComponent) break; component.dispose(); } } const unmountHandler = getPrivate(node, kAlienUnmountHandler); unmountHandler?.(); } // core/mount.ts function mount(parent, node) { while (parent.lastChild) { unmount(parent.lastChild); } mountLastChild(parent, node); } function mountLastChild(parent, node) { const wasConnected = node.isConnected; parent.appendChild(node); if (!wasConnected) { notifyMounted(node); } } function mountFirstChild(parent, node) { const wasConnected = node.isConnected; parent.insertBefore(node, parent.firstChild); if (!wasConnected) { notifyMounted(node); } } function mountBeforeNode(sibling, node) { const wasConnected = node.isConnected; sibling.before(node); if (!wasConnected) { notifyMounted(node); } } function mountAfterNode(sibling, node) { const wasConnected = node.isConnected; sibling.after(node); if (!wasConnected) { notifyMounted(node); } } function mountReplacementNode(oldNode, newNode) { const wasConnected = newNode.isConnected; oldNode.replaceWith(newNode); unmount(oldNode, true); if (!wasConnected) { notifyMounted(newNode); } } // internal/fromElementThunk.ts function fromElementThunk(thunk, keepDeferred) { if (!hasPrivate(thunk, kAlienThunkResult)) { const component = lastValue(currentComponent); if (!component) { return thunk(); } defineProperty(thunk, kAlienThunkResult, { get() { let result = component.newMemos ? component.newMemos.get(thunk) : void 0; if (result === void 0) { result = thunk(); if (isDeferredNode(result)) { if (keepDeferred) { return result; } result = evaluateDeferredNode(result); } component.newMemos ||= /* @__PURE__ */ new Map(); component.newMemos.set(thunk, result); } return result; } }); } return getPrivate(thunk, kAlienThunkResult); } // internal/context.ts var currentContext = /* @__PURE__ */ new Map(); function forwardContext(context, isRerender) { const oldValues = new Map(currentContext); context.forEach((value, key) => { const ref2 = currentContext.get(key); if (isRerender && ref2) { context.set(key, ref2); } else { currentContext.set(key, value); } }); return () => { context.forEach((_, key) => { const oldValue = oldValues.get(key); if (oldValue) { currentContext.set(key, oldValue); } else { currentContext.delete(key); } }); }; } function getContext(context) { if (context) { return currentContext.get(context); } return currentContext; } function setContext(context, value) { if (context instanceof Map) { const oldContext = currentContext; currentContext = context; return oldContext; } const oldValue = currentContext.get(context); if (value) { currentContext.set(context, value); } else { currentContext.delete(context); } return oldValue; } // jsx-dom/evaluateChild.ts function evaluateChild(child) { if (isDeferredNode(child)) { child = evaluateDeferredNode(child); } else { const key = getElementKey(child); if (key != null) { const update = findNodeUpdate(key); if (update) { if (isElement(child) && compareNodeWithTag(child, update.tag)) { morph(child, update); } else { child = evaluateDeferredNode(update); } } } } return child; } function findNodeUpdate(key) { let update; let component = lastValue(currentComponent); if (component) { do { if (update = component.updates?.get(key)) break; } while (component = component.parent); } else { const nodeStore = lastValue(currentNodeStore); update = nodeStore?.getNodeUpdateForKey(key); } return update; } // jsx-dom/appendChild.ts function appendChild(child, parent) { if (child === null) { return; } if (isNode(child)) { child = evaluateChild(child); if (isFragment(parent) && !getParentFragment(child)) { setParentFragment(child, parent); } if (hasTagName(parent, "TEMPLATE")) { parent.content.appendChild(child); } else { parent.appendChild(child); notifyMounted(child); } return child; } if (isDeferredNode(child)) { child = evaluateDeferredNode(child); return appendChild(child, parent); } if (isShadowRoot(child)) { const shadowRoot = parent.attachShadow(child.props); const ancestorShadowRoot = setContext( ShadowRootContext, ref(shadowRoot) ); try { for (const shadowChild of child.children) { appendChild(shadowChild, shadowRoot); } } finally { setContext(ShadowRootContext, ancestorShadowRoot); } } } // internal/guid.ts var nextId = Number.MIN_SAFE_INTEGER; function createGuid(container, key, force, generateId) { if (!container) { return nextId += nextId === -1 ? 2 : 1; } if (key == null) { throw Error("A key must be provided when a container is provided"); } let guid = peek(container, key); if (!guid || force) { guid = generateId ? generateId() : nextId += nextId === -1 ? 2 : 1; } return guid; } // internal/traversal.ts function findFirstElement(node, end) { while (node && !isElement(node)) { if (node === end) { return null; } node = node.nextSibling; } return node; } function findLastElement(node, start) { while (node && !isElement(node)) { if (node === start) { return null; } node = node.previousSibling; } return node; } // jsx-dom/resolveSelected.ts function resolveSelected(node) { if (!node.hasAttribute("multiple")) { var selectedIndex = -1; var i = 0; var curChild = node.firstChild; var optgroup; while (curChild) { if (hasTagName(curChild, "OPTGROUP")) { optgroup = curChild; curChild = optgroup.firstChild; } else { if (hasTagName(curChild, "OPTION")) { if (curChild.hasAttribute("selected")) { selectedIndex = i; break; } i++; } curChild = curChild.nextSibling; if (!curChild && optgroup) { curChild = optgroup.nextSibling; optgroup = null; } } } node.selectedIndex = selectedIndex; } } // morphdom/morphComposite.ts function morphComposite(fromParentNode, toParentNode) { const tags = getElementTags(fromParentNode); const childComponent = tags?.get(toParentNode.tag); if (childComponent) { childComponent.replaceProps(toParentNode.props); toParentNode.context?.forEach((ref2, key) => { const targetRef = childComponent.context.get(key); if (targetRef) { targetRef.value = ref2.peek(); } }); return fromParentNode; } return evaluateDeferredNode(toParentNode); } // morphdom/morphChildren.ts var defaultNextSibling = (node) => node.nextSibling; function morphChildren(fromParentNode, toChildNodes, component = null, options = {}) { if (!fromParentNode.childNodes.length) { if (!toChildNodes || !toChildNodes.length) { return; } } else { toChildNodes ||= []; } const { getFromKey = getElementIdentity, onChildNode = noop } = options; if (!isArray(toChildNodes)) { toChildNodes = Array.