mirror of
				https://github.com/jaandrle/deka-dom-el
				synced 2025-11-03 22:59:16 +01:00 
			
		
		
		
	⚡ wip
This commit is contained in:
		
							
								
								
									
										131
									
								
								dist/dde-with-signals.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										131
									
								
								dist/dde-with-signals.js
									
									
									
									
										vendored
									
									
								
							@@ -2,9 +2,22 @@
 | 
			
		||||
(()=> {
 | 
			
		||||
// src/signals-lib/common.js
 | 
			
		||||
var signals_global = {
 | 
			
		||||
	/**
 | 
			
		||||
	* Checks if a value is a signal
 | 
			
		||||
	* @param {any} attributes - Value to check
 | 
			
		||||
	* @returns {boolean} Whether the value is a signal
 | 
			
		||||
	*/
 | 
			
		||||
	isSignal(attributes) {
 | 
			
		||||
		return false;
 | 
			
		||||
	},
 | 
			
		||||
	/**
 | 
			
		||||
	* Processes an attribute that might be reactive
 | 
			
		||||
	* @param {Element} obj - Element that owns the attribute
 | 
			
		||||
	* @param {string} key - Attribute name
 | 
			
		||||
	* @param {any} attr - Attribute value
 | 
			
		||||
	* @param {Function} set - Function to set the attribute
 | 
			
		||||
	* @returns {any} Processed attribute value
 | 
			
		||||
	*/
 | 
			
		||||
	processReactiveAttribute(obj, key, attr, set) {
 | 
			
		||||
		return attr;
 | 
			
		||||
	}
 | 
			
		||||
@@ -49,6 +62,19 @@ function observedAttributes(instance, observedAttribute2) {
 | 
			
		||||
function kebabToCamel(name) {
 | 
			
		||||
	return name.replace(/-./g, (x) => x[1].toUpperCase());
 | 
			
		||||
}
 | 
			
		||||
var Defined = class extends Error {
 | 
			
		||||
	constructor() {
 | 
			
		||||
		super();
 | 
			
		||||
		const [curr, ...rest] = this.stack.split("\n");
 | 
			
		||||
		const curr_file = curr.slice(curr.indexOf("@"), curr.indexOf(".js:") + 4);
 | 
			
		||||
		const curr_lib = curr_file.includes("src/dom-common.js") ? "src/" : curr_file;
 | 
			
		||||
		this.stack = rest.find((l) => !l.includes(curr_lib)) || curr;
 | 
			
		||||
	}
 | 
			
		||||
	get compact() {
 | 
			
		||||
		const { stack } = this;
 | 
			
		||||
		return stack.slice(0, stack.indexOf("@") + 1) + "\u2026" + stack.slice(stack.lastIndexOf("/"));
 | 
			
		||||
	}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// src/dom-common.js
 | 
			
		||||
var enviroment = {
 | 
			
		||||
@@ -87,26 +113,55 @@ var scopes = [{
 | 
			
		||||
	prevent: true
 | 
			
		||||
}];
 | 
			
		||||
var scope = {
 | 
			
		||||
	/**
 | 
			
		||||
	* Gets the current scope
 | 
			
		||||
	* @returns {Object} Current scope context
 | 
			
		||||
	*/
 | 
			
		||||
	get current() {
 | 
			
		||||
		return scopes[scopes.length - 1];
 | 
			
		||||
	},
 | 
			
		||||
	/**
 | 
			
		||||
	* Gets the host element of the current scope
 | 
			
		||||
	* @returns {Function} Host accessor function
 | 
			
		||||
	*/
 | 
			
		||||
	get host() {
 | 
			
		||||
		return this.current.host;
 | 
			
		||||
	},
 | 
			
		||||
	/**
 | 
			
		||||
	* Prevents default behavior in the current scope
 | 
			
		||||
	* @returns {Object} Current scope context
 | 
			
		||||
	*/
 | 
			
		||||
	preventDefault() {
 | 
			
		||||
		const { current } = this;
 | 
			
		||||
		current.prevent = true;
 | 
			
		||||
		return current;
 | 
			
		||||
	},
 | 
			
		||||
	/**
 | 
			
		||||
	* Gets a copy of the current scope stack
 | 
			
		||||
	* @returns {Array} Copy of scope stack
 | 
			
		||||
	*/
 | 
			
		||||
	get state() {
 | 
			
		||||
		return [...scopes];
 | 
			
		||||
	},
 | 
			
		||||
	/**
 | 
			
		||||
	* Pushes a new scope to the stack
 | 
			
		||||
	* @param {Object} [s={}] - Scope object to push
 | 
			
		||||
	* @returns {number} New length of the scope stack
 | 
			
		||||
	*/
 | 
			
		||||
	push(s = {}) {
 | 
			
		||||
		return scopes.push(Object.assign({}, this.current, { prevent: false }, s));
 | 
			
		||||
	},
 | 
			
		||||
	/**
 | 
			
		||||
	* Pushes the root scope to the stack
 | 
			
		||||
	* @returns {number} New length of the scope stack
 | 
			
		||||
	*/
 | 
			
		||||
	pushRoot() {
 | 
			
		||||
		return scopes.push(scopes[0]);
 | 
			
		||||
	},
 | 
			
		||||
	/**
 | 
			
		||||
	* Pops the current scope from the stack
 | 
			
		||||
	* @returns {Object|undefined} Popped scope or undefined if only one scope remains
 | 
			
		||||
	*/
 | 
			
		||||
	pop() {
 | 
			
		||||
		if (scopes.length === 1) return;
 | 
			
		||||
		return scopes.pop();
 | 
			
		||||
@@ -338,12 +393,22 @@ function connectionsChangesObserverConstructor() {
 | 
			
		||||
	};
 | 
			
		||||
	const observer = new enviroment.M(observerListener(stop));
 | 
			
		||||
	return {
 | 
			
		||||
		/**
 | 
			
		||||
		* Creates an observer for a specific element
 | 
			
		||||
		* @param {Element} element - Element to observe
 | 
			
		||||
		* @returns {Function} Cleanup function
 | 
			
		||||
		*/
 | 
			
		||||
		observe(element) {
 | 
			
		||||
			const o = new enviroment.M(observerListener(() => {
 | 
			
		||||
			}));
 | 
			
		||||
			o.observe(element, { childList: true, subtree: true });
 | 
			
		||||
			return () => o.disconnect();
 | 
			
		||||
		},
 | 
			
		||||
		/**
 | 
			
		||||
		* Register a connection listener for an element
 | 
			
		||||
		* @param {Element} element - Element to watch
 | 
			
		||||
		* @param {Function} listener - Callback for connection event
 | 
			
		||||
		*/
 | 
			
		||||
		onConnected(element, listener) {
 | 
			
		||||
			start();
 | 
			
		||||
			const listeners = getElementStore(element);
 | 
			
		||||
@@ -351,6 +416,11 @@ function connectionsChangesObserverConstructor() {
 | 
			
		||||
			listeners.connected.add(listener);
 | 
			
		||||
			listeners.length_c += 1;
 | 
			
		||||
		},
 | 
			
		||||
		/**
 | 
			
		||||
		* Unregister a connection listener
 | 
			
		||||
		* @param {Element} element - Element being watched
 | 
			
		||||
		* @param {Function} listener - Callback to remove
 | 
			
		||||
		*/
 | 
			
		||||
		offConnected(element, listener) {
 | 
			
		||||
			if (!store.has(element)) return;
 | 
			
		||||
			const ls = store.get(element);
 | 
			
		||||
@@ -359,6 +429,11 @@ function connectionsChangesObserverConstructor() {
 | 
			
		||||
			ls.length_c -= 1;
 | 
			
		||||
			cleanWhenOff(element, ls);
 | 
			
		||||
		},
 | 
			
		||||
		/**
 | 
			
		||||
		* Register a disconnection listener for an element
 | 
			
		||||
		* @param {Element} element - Element to watch
 | 
			
		||||
		* @param {Function} listener - Callback for disconnection event
 | 
			
		||||
		*/
 | 
			
		||||
		onDisconnected(element, listener) {
 | 
			
		||||
			start();
 | 
			
		||||
			const listeners = getElementStore(element);
 | 
			
		||||
@@ -366,6 +441,11 @@ function connectionsChangesObserverConstructor() {
 | 
			
		||||
			listeners.disconnected.add(listener);
 | 
			
		||||
			listeners.length_d += 1;
 | 
			
		||||
		},
 | 
			
		||||
		/**
 | 
			
		||||
		* Unregister a disconnection listener
 | 
			
		||||
		* @param {Element} element - Element being watched
 | 
			
		||||
		* @param {Function} listener - Callback to remove
 | 
			
		||||
		*/
 | 
			
		||||
		offDisconnected(element, listener) {
 | 
			
		||||
			if (!store.has(element)) return;
 | 
			
		||||
			const ls = store.get(element);
 | 
			
		||||
@@ -572,20 +652,13 @@ on.attributeChanged = function(listener, options) {
 | 
			
		||||
 | 
			
		||||
// src/signals-lib/helpers.js
 | 
			
		||||
var mark = "__dde_signal";
 | 
			
		||||
var SignalDefined = class extends Error {
 | 
			
		||||
	constructor() {
 | 
			
		||||
		super();
 | 
			
		||||
		const [curr, ...rest] = this.stack.split("\n");
 | 
			
		||||
		const curr_file = curr.slice(curr.indexOf("@"), curr.indexOf(".js:") + 4);
 | 
			
		||||
		this.stack = rest.find((l) => !l.includes(curr_file));
 | 
			
		||||
	}
 | 
			
		||||
};
 | 
			
		||||
var queueSignalWrite = /* @__PURE__ */ (() => {
 | 
			
		||||
	let pendingSignals = /* @__PURE__ */ new Set();
 | 
			
		||||
	let scheduled = false;
 | 
			
		||||
	function flushSignals() {
 | 
			
		||||
		scheduled = false;
 | 
			
		||||
		for (const signal2 of pendingSignals) {
 | 
			
		||||
			pendingSignals.delete(signal2);
 | 
			
		||||
			const M = signal2[mark];
 | 
			
		||||
			if (M) M.listeners.forEach((l) => l(M.value));
 | 
			
		||||
		}
 | 
			
		||||
@@ -623,7 +696,6 @@ function signal(value, actions) {
 | 
			
		||||
			removeSignalListener(dep_signal, contextReWatch);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	;
 | 
			
		||||
	deps.set(out[mark], contextReWatch);
 | 
			
		||||
	deps.set(contextReWatch, /* @__PURE__ */ new Set([out]));
 | 
			
		||||
	contextReWatch();
 | 
			
		||||
@@ -673,36 +745,27 @@ signal.clear = function(...signals2) {
 | 
			
		||||
};
 | 
			
		||||
var key_reactive = "__dde_reactive";
 | 
			
		||||
var storeMemo = /* @__PURE__ */ new WeakMap();
 | 
			
		||||
function memo(key, fun, cache) {
 | 
			
		||||
function memo(key, fun, host = fun) {
 | 
			
		||||
	if (typeof key !== "string") key = JSON.stringify(key);
 | 
			
		||||
	if (!cache) {
 | 
			
		||||
		const keyStore = scope.host();
 | 
			
		||||
		if (storeMemo.has(keyStore))
 | 
			
		||||
			cache = storeMemo.get(keyStore);
 | 
			
		||||
		else {
 | 
			
		||||
			cache = {};
 | 
			
		||||
			storeMemo.set(keyStore, cache);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if (!storeMemo.has(host)) storeMemo.set(host, {});
 | 
			
		||||
	const cache = storeMemo.get(host);
 | 
			
		||||
	return hasOwn(cache, key) ? cache[key] : cache[key] = fun();
 | 
			
		||||
}
 | 
			
		||||
signal.el = function(s, map) {
 | 
			
		||||
	const mark_start = createElement.mark({ type: "reactive" }, true);
 | 
			
		||||
	const mark_start = createElement.mark({ type: "reactive", source: new Defined().compact }, true);
 | 
			
		||||
	const mark_end = mark_start.end;
 | 
			
		||||
	const out = enviroment.D.createDocumentFragment();
 | 
			
		||||
	out.append(mark_start, mark_end);
 | 
			
		||||
	const { current } = scope;
 | 
			
		||||
	let cache = {};
 | 
			
		||||
	const reRenderReactiveElement = (v) => {
 | 
			
		||||
		if (!mark_start.parentNode || !mark_end.parentNode)
 | 
			
		||||
			return removeSignalListener(s, reRenderReactiveElement);
 | 
			
		||||
		let cache_tmp = cache;
 | 
			
		||||
		cache = {};
 | 
			
		||||
		const cache = {};
 | 
			
		||||
		scope.push(current);
 | 
			
		||||
		let els = map(v, function useCache(key, fun) {
 | 
			
		||||
			return cache[key] = memo(key, fun, cache_tmp);
 | 
			
		||||
			return cache[key] = memo(key, fun, reRenderReactiveElement);
 | 
			
		||||
		});
 | 
			
		||||
		cache_tmp = {};
 | 
			
		||||
		storeMemo.set(reRenderReactiveElement, cache);
 | 
			
		||||
		scope.pop();
 | 
			
		||||
		if (!Array.isArray(els))
 | 
			
		||||
			els = [els];
 | 
			
		||||
@@ -719,10 +782,6 @@ signal.el = function(s, map) {
 | 
			
		||||
	addSignalListener(s, reRenderReactiveElement);
 | 
			
		||||
	removeSignalsFromElements(s, reRenderReactiveElement, mark_start, map);
 | 
			
		||||
	reRenderReactiveElement(s());
 | 
			
		||||
	current.host(on.disconnected(() => (
 | 
			
		||||
		/*! This clears memoized elements in S.el when the host is disconnected */
 | 
			
		||||
		cache = {}
 | 
			
		||||
	)));
 | 
			
		||||
	return out;
 | 
			
		||||
};
 | 
			
		||||
function requestCleanUpReactives(host) {
 | 
			
		||||
@@ -764,6 +823,15 @@ signal.observedAttributes = function(element) {
 | 
			
		||||
};
 | 
			
		||||
var signals_config = {
 | 
			
		||||
	isSignal,
 | 
			
		||||
	/**
 | 
			
		||||
	* Processes attributes that might be signals
 | 
			
		||||
	*
 | 
			
		||||
	* @param {Element} element - Element with the attribute
 | 
			
		||||
	* @param {string} key - Attribute name
 | 
			
		||||
	* @param {any} attrs - Attribute value (possibly a signal)
 | 
			
		||||
	* @param {Function} set - Function to set attribute value
 | 
			
		||||
	* @returns {any} Processed attribute value
 | 
			
		||||
	*/
 | 
			
		||||
	processReactiveAttribute(element, key, attrs, set) {
 | 
			
		||||
		if (!isSignal(attrs)) return attrs;
 | 
			
		||||
		const l = (attr) => {
 | 
			
		||||
@@ -802,6 +870,9 @@ function create(is_readonly, value, actions) {
 | 
			
		||||
	return SI;
 | 
			
		||||
}
 | 
			
		||||
var protoSigal = Object.assign(/* @__PURE__ */ Object.create(null), {
 | 
			
		||||
	/**
 | 
			
		||||
	* Prevents signal propagation
 | 
			
		||||
	*/
 | 
			
		||||
	stopPropagation() {
 | 
			
		||||
		this.skip = true;
 | 
			
		||||
	}
 | 
			
		||||
@@ -823,7 +894,7 @@ function toSignal(s, value, actions, readonly = false) {
 | 
			
		||||
			onclear,
 | 
			
		||||
			host,
 | 
			
		||||
			listeners: /* @__PURE__ */ new Set(),
 | 
			
		||||
			defined: new SignalDefined().stack,
 | 
			
		||||
			defined: new Defined().stack,
 | 
			
		||||
			readonly
 | 
			
		||||
		},
 | 
			
		||||
		enumerable: false,
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										67
									
								
								dist/dde.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										67
									
								
								dist/dde.js
									
									
									
									
										vendored
									
									
								
							@@ -2,9 +2,22 @@
 | 
			
		||||
(()=> {
 | 
			
		||||
// src/signals-lib/common.js
 | 
			
		||||
var signals_global = {
 | 
			
		||||
	/**
 | 
			
		||||
	* Checks if a value is a signal
 | 
			
		||||
	* @param {any} attributes - Value to check
 | 
			
		||||
	* @returns {boolean} Whether the value is a signal
 | 
			
		||||
	*/
 | 
			
		||||
	isSignal(attributes) {
 | 
			
		||||
		return false;
 | 
			
		||||
	},
 | 
			
		||||
	/**
 | 
			
		||||
	* Processes an attribute that might be reactive
 | 
			
		||||
	* @param {Element} obj - Element that owns the attribute
 | 
			
		||||
	* @param {string} key - Attribute name
 | 
			
		||||
	* @param {any} attr - Attribute value
 | 
			
		||||
	* @param {Function} set - Function to set the attribute
 | 
			
		||||
	* @returns {any} Processed attribute value
 | 
			
		||||
	*/
 | 
			
		||||
	processReactiveAttribute(obj, key, attr, set) {
 | 
			
		||||
		return attr;
 | 
			
		||||
	}
 | 
			
		||||
@@ -80,26 +93,55 @@ var scopes = [{
 | 
			
		||||
	prevent: true
 | 
			
		||||
}];
 | 
			
		||||
var scope = {
 | 
			
		||||
	/**
 | 
			
		||||
	* Gets the current scope
 | 
			
		||||
	* @returns {Object} Current scope context
 | 
			
		||||
	*/
 | 
			
		||||
	get current() {
 | 
			
		||||
		return scopes[scopes.length - 1];
 | 
			
		||||
	},
 | 
			
		||||
	/**
 | 
			
		||||
	* Gets the host element of the current scope
 | 
			
		||||
	* @returns {Function} Host accessor function
 | 
			
		||||
	*/
 | 
			
		||||
	get host() {
 | 
			
		||||
		return this.current.host;
 | 
			
		||||
	},
 | 
			
		||||
	/**
 | 
			
		||||
	* Prevents default behavior in the current scope
 | 
			
		||||
	* @returns {Object} Current scope context
 | 
			
		||||
	*/
 | 
			
		||||
	preventDefault() {
 | 
			
		||||
		const { current } = this;
 | 
			
		||||
		current.prevent = true;
 | 
			
		||||
		return current;
 | 
			
		||||
	},
 | 
			
		||||
	/**
 | 
			
		||||
	* Gets a copy of the current scope stack
 | 
			
		||||
	* @returns {Array} Copy of scope stack
 | 
			
		||||
	*/
 | 
			
		||||
	get state() {
 | 
			
		||||
		return [...scopes];
 | 
			
		||||
	},
 | 
			
		||||
	/**
 | 
			
		||||
	* Pushes a new scope to the stack
 | 
			
		||||
	* @param {Object} [s={}] - Scope object to push
 | 
			
		||||
	* @returns {number} New length of the scope stack
 | 
			
		||||
	*/
 | 
			
		||||
	push(s = {}) {
 | 
			
		||||
		return scopes.push(Object.assign({}, this.current, { prevent: false }, s));
 | 
			
		||||
	},
 | 
			
		||||
	/**
 | 
			
		||||
	* Pushes the root scope to the stack
 | 
			
		||||
	* @returns {number} New length of the scope stack
 | 
			
		||||
	*/
 | 
			
		||||
	pushRoot() {
 | 
			
		||||
		return scopes.push(scopes[0]);
 | 
			
		||||
	},
 | 
			
		||||
	/**
 | 
			
		||||
	* Pops the current scope from the stack
 | 
			
		||||
	* @returns {Object|undefined} Popped scope or undefined if only one scope remains
 | 
			
		||||
	*/
 | 
			
		||||
	pop() {
 | 
			
		||||
		if (scopes.length === 1) return;
 | 
			
		||||
		return scopes.pop();
 | 
			
		||||
@@ -331,12 +373,22 @@ function connectionsChangesObserverConstructor() {
 | 
			
		||||
	};
 | 
			
		||||
	const observer = new enviroment.M(observerListener(stop));
 | 
			
		||||
	return {
 | 
			
		||||
		/**
 | 
			
		||||
		* Creates an observer for a specific element
 | 
			
		||||
		* @param {Element} element - Element to observe
 | 
			
		||||
		* @returns {Function} Cleanup function
 | 
			
		||||
		*/
 | 
			
		||||
		observe(element) {
 | 
			
		||||
			const o = new enviroment.M(observerListener(() => {
 | 
			
		||||
			}));
 | 
			
		||||
			o.observe(element, { childList: true, subtree: true });
 | 
			
		||||
			return () => o.disconnect();
 | 
			
		||||
		},
 | 
			
		||||
		/**
 | 
			
		||||
		* Register a connection listener for an element
 | 
			
		||||
		* @param {Element} element - Element to watch
 | 
			
		||||
		* @param {Function} listener - Callback for connection event
 | 
			
		||||
		*/
 | 
			
		||||
		onConnected(element, listener) {
 | 
			
		||||
			start();
 | 
			
		||||
			const listeners = getElementStore(element);
 | 
			
		||||
@@ -344,6 +396,11 @@ function connectionsChangesObserverConstructor() {
 | 
			
		||||
			listeners.connected.add(listener);
 | 
			
		||||
			listeners.length_c += 1;
 | 
			
		||||
		},
 | 
			
		||||
		/**
 | 
			
		||||
		* Unregister a connection listener
 | 
			
		||||
		* @param {Element} element - Element being watched
 | 
			
		||||
		* @param {Function} listener - Callback to remove
 | 
			
		||||
		*/
 | 
			
		||||
		offConnected(element, listener) {
 | 
			
		||||
			if (!store.has(element)) return;
 | 
			
		||||
			const ls = store.get(element);
 | 
			
		||||
@@ -352,6 +409,11 @@ function connectionsChangesObserverConstructor() {
 | 
			
		||||
			ls.length_c -= 1;
 | 
			
		||||
			cleanWhenOff(element, ls);
 | 
			
		||||
		},
 | 
			
		||||
		/**
 | 
			
		||||
		* Register a disconnection listener for an element
 | 
			
		||||
		* @param {Element} element - Element to watch
 | 
			
		||||
		* @param {Function} listener - Callback for disconnection event
 | 
			
		||||
		*/
 | 
			
		||||
		onDisconnected(element, listener) {
 | 
			
		||||
			start();
 | 
			
		||||
			const listeners = getElementStore(element);
 | 
			
		||||
@@ -359,6 +421,11 @@ function connectionsChangesObserverConstructor() {
 | 
			
		||||
			listeners.disconnected.add(listener);
 | 
			
		||||
			listeners.length_d += 1;
 | 
			
		||||
		},
 | 
			
		||||
		/**
 | 
			
		||||
		* Unregister a disconnection listener
 | 
			
		||||
		* @param {Element} element - Element being watched
 | 
			
		||||
		* @param {Function} listener - Callback to remove
 | 
			
		||||
		*/
 | 
			
		||||
		offDisconnected(element, listener) {
 | 
			
		||||
			if (!store.has(element)) return;
 | 
			
		||||
			const ls = store.get(element);
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										131
									
								
								dist/esm-with-signals.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										131
									
								
								dist/esm-with-signals.js
									
									
									
									
										vendored
									
									
								
							@@ -1,8 +1,21 @@
 | 
			
		||||
// src/signals-lib/common.js
 | 
			
		||||
var signals_global = {
 | 
			
		||||
	/**
 | 
			
		||||
	* Checks if a value is a signal
 | 
			
		||||
	* @param {any} attributes - Value to check
 | 
			
		||||
	* @returns {boolean} Whether the value is a signal
 | 
			
		||||
	*/
 | 
			
		||||
	isSignal(attributes) {
 | 
			
		||||
		return false;
 | 
			
		||||
	},
 | 
			
		||||
	/**
 | 
			
		||||
	* Processes an attribute that might be reactive
 | 
			
		||||
	* @param {Element} obj - Element that owns the attribute
 | 
			
		||||
	* @param {string} key - Attribute name
 | 
			
		||||
	* @param {any} attr - Attribute value
 | 
			
		||||
	* @param {Function} set - Function to set the attribute
 | 
			
		||||
	* @returns {any} Processed attribute value
 | 
			
		||||
	*/
 | 
			
		||||
	processReactiveAttribute(obj, key, attr, set) {
 | 
			
		||||
		return attr;
 | 
			
		||||
	}
 | 
			
		||||
@@ -47,6 +60,19 @@ function observedAttributes(instance, observedAttribute2) {
 | 
			
		||||
function kebabToCamel(name) {
 | 
			
		||||
	return name.replace(/-./g, (x) => x[1].toUpperCase());
 | 
			
		||||
}
 | 
			
		||||
var Defined = class extends Error {
 | 
			
		||||
	constructor() {
 | 
			
		||||
		super();
 | 
			
		||||
		const [curr, ...rest] = this.stack.split("\n");
 | 
			
		||||
		const curr_file = curr.slice(curr.indexOf("@"), curr.indexOf(".js:") + 4);
 | 
			
		||||
		const curr_lib = curr_file.includes("src/dom-common.js") ? "src/" : curr_file;
 | 
			
		||||
		this.stack = rest.find((l) => !l.includes(curr_lib)) || curr;
 | 
			
		||||
	}
 | 
			
		||||
	get compact() {
 | 
			
		||||
		const { stack } = this;
 | 
			
		||||
		return stack.slice(0, stack.indexOf("@") + 1) + "\u2026" + stack.slice(stack.lastIndexOf("/"));
 | 
			
		||||
	}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// src/dom-common.js
 | 
			
		||||
var enviroment = {
 | 
			
		||||
@@ -85,26 +111,55 @@ var scopes = [{
 | 
			
		||||
	prevent: true
 | 
			
		||||
}];
 | 
			
		||||
var scope = {
 | 
			
		||||
	/**
 | 
			
		||||
	* Gets the current scope
 | 
			
		||||
	* @returns {Object} Current scope context
 | 
			
		||||
	*/
 | 
			
		||||
	get current() {
 | 
			
		||||
		return scopes[scopes.length - 1];
 | 
			
		||||
	},
 | 
			
		||||
	/**
 | 
			
		||||
	* Gets the host element of the current scope
 | 
			
		||||
	* @returns {Function} Host accessor function
 | 
			
		||||
	*/
 | 
			
		||||
	get host() {
 | 
			
		||||
		return this.current.host;
 | 
			
		||||
	},
 | 
			
		||||
	/**
 | 
			
		||||
	* Prevents default behavior in the current scope
 | 
			
		||||
	* @returns {Object} Current scope context
 | 
			
		||||
	*/
 | 
			
		||||
	preventDefault() {
 | 
			
		||||
		const { current } = this;
 | 
			
		||||
		current.prevent = true;
 | 
			
		||||
		return current;
 | 
			
		||||
	},
 | 
			
		||||
	/**
 | 
			
		||||
	* Gets a copy of the current scope stack
 | 
			
		||||
	* @returns {Array} Copy of scope stack
 | 
			
		||||
	*/
 | 
			
		||||
	get state() {
 | 
			
		||||
		return [...scopes];
 | 
			
		||||
	},
 | 
			
		||||
	/**
 | 
			
		||||
	* Pushes a new scope to the stack
 | 
			
		||||
	* @param {Object} [s={}] - Scope object to push
 | 
			
		||||
	* @returns {number} New length of the scope stack
 | 
			
		||||
	*/
 | 
			
		||||
	push(s = {}) {
 | 
			
		||||
		return scopes.push(Object.assign({}, this.current, { prevent: false }, s));
 | 
			
		||||
	},
 | 
			
		||||
	/**
 | 
			
		||||
	* Pushes the root scope to the stack
 | 
			
		||||
	* @returns {number} New length of the scope stack
 | 
			
		||||
	*/
 | 
			
		||||
	pushRoot() {
 | 
			
		||||
		return scopes.push(scopes[0]);
 | 
			
		||||
	},
 | 
			
		||||
	/**
 | 
			
		||||
	* Pops the current scope from the stack
 | 
			
		||||
	* @returns {Object|undefined} Popped scope or undefined if only one scope remains
 | 
			
		||||
	*/
 | 
			
		||||
	pop() {
 | 
			
		||||
		if (scopes.length === 1) return;
 | 
			
		||||
		return scopes.pop();
 | 
			
		||||
@@ -336,12 +391,22 @@ function connectionsChangesObserverConstructor() {
 | 
			
		||||
	};
 | 
			
		||||
	const observer = new enviroment.M(observerListener(stop));
 | 
			
		||||
	return {
 | 
			
		||||
		/**
 | 
			
		||||
		* Creates an observer for a specific element
 | 
			
		||||
		* @param {Element} element - Element to observe
 | 
			
		||||
		* @returns {Function} Cleanup function
 | 
			
		||||
		*/
 | 
			
		||||
		observe(element) {
 | 
			
		||||
			const o = new enviroment.M(observerListener(() => {
 | 
			
		||||
			}));
 | 
			
		||||
			o.observe(element, { childList: true, subtree: true });
 | 
			
		||||
			return () => o.disconnect();
 | 
			
		||||
		},
 | 
			
		||||
		/**
 | 
			
		||||
		* Register a connection listener for an element
 | 
			
		||||
		* @param {Element} element - Element to watch
 | 
			
		||||
		* @param {Function} listener - Callback for connection event
 | 
			
		||||
		*/
 | 
			
		||||
		onConnected(element, listener) {
 | 
			
		||||
			start();
 | 
			
		||||
			const listeners = getElementStore(element);
 | 
			
		||||
@@ -349,6 +414,11 @@ function connectionsChangesObserverConstructor() {
 | 
			
		||||
			listeners.connected.add(listener);
 | 
			
		||||
			listeners.length_c += 1;
 | 
			
		||||
		},
 | 
			
		||||
		/**
 | 
			
		||||
		* Unregister a connection listener
 | 
			
		||||
		* @param {Element} element - Element being watched
 | 
			
		||||
		* @param {Function} listener - Callback to remove
 | 
			
		||||
		*/
 | 
			
		||||
		offConnected(element, listener) {
 | 
			
		||||
			if (!store.has(element)) return;
 | 
			
		||||
			const ls = store.get(element);
 | 
			
		||||
@@ -357,6 +427,11 @@ function connectionsChangesObserverConstructor() {
 | 
			
		||||
			ls.length_c -= 1;
 | 
			
		||||
			cleanWhenOff(element, ls);
 | 
			
		||||
		},
 | 
			
		||||
		/**
 | 
			
		||||
		* Register a disconnection listener for an element
 | 
			
		||||
		* @param {Element} element - Element to watch
 | 
			
		||||
		* @param {Function} listener - Callback for disconnection event
 | 
			
		||||
		*/
 | 
			
		||||
		onDisconnected(element, listener) {
 | 
			
		||||
			start();
 | 
			
		||||
			const listeners = getElementStore(element);
 | 
			
		||||
@@ -364,6 +439,11 @@ function connectionsChangesObserverConstructor() {
 | 
			
		||||
			listeners.disconnected.add(listener);
 | 
			
		||||
			listeners.length_d += 1;
 | 
			
		||||
		},
 | 
			
		||||
		/**
 | 
			
		||||
		* Unregister a disconnection listener
 | 
			
		||||
		* @param {Element} element - Element being watched
 | 
			
		||||
		* @param {Function} listener - Callback to remove
 | 
			
		||||
		*/
 | 
			
		||||
		offDisconnected(element, listener) {
 | 
			
		||||
			if (!store.has(element)) return;
 | 
			
		||||
			const ls = store.get(element);
 | 
			
		||||
@@ -570,20 +650,13 @@ on.attributeChanged = function(listener, options) {
 | 
			
		||||
 | 
			
		||||
// src/signals-lib/helpers.js
 | 
			
		||||
var mark = "__dde_signal";
 | 
			
		||||
var SignalDefined = class extends Error {
 | 
			
		||||
	constructor() {
 | 
			
		||||
		super();
 | 
			
		||||
		const [curr, ...rest] = this.stack.split("\n");
 | 
			
		||||
		const curr_file = curr.slice(curr.indexOf("@"), curr.indexOf(".js:") + 4);
 | 
			
		||||
		this.stack = rest.find((l) => !l.includes(curr_file));
 | 
			
		||||
	}
 | 
			
		||||
};
 | 
			
		||||
var queueSignalWrite = /* @__PURE__ */ (() => {
 | 
			
		||||
	let pendingSignals = /* @__PURE__ */ new Set();
 | 
			
		||||
	let scheduled = false;
 | 
			
		||||
	function flushSignals() {
 | 
			
		||||
		scheduled = false;
 | 
			
		||||
		for (const signal2 of pendingSignals) {
 | 
			
		||||
			pendingSignals.delete(signal2);
 | 
			
		||||
			const M = signal2[mark];
 | 
			
		||||
			if (M) M.listeners.forEach((l) => l(M.value));
 | 
			
		||||
		}
 | 
			
		||||
@@ -621,7 +694,6 @@ function signal(value, actions) {
 | 
			
		||||
			removeSignalListener(dep_signal, contextReWatch);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	;
 | 
			
		||||
	deps.set(out[mark], contextReWatch);
 | 
			
		||||
	deps.set(contextReWatch, /* @__PURE__ */ new Set([out]));
 | 
			
		||||
	contextReWatch();
 | 
			
		||||
@@ -671,36 +743,27 @@ signal.clear = function(...signals2) {
 | 
			
		||||
};
 | 
			
		||||
var key_reactive = "__dde_reactive";
 | 
			
		||||
var storeMemo = /* @__PURE__ */ new WeakMap();
 | 
			
		||||
function memo(key, fun, cache) {
 | 
			
		||||
function memo(key, fun, host = fun) {
 | 
			
		||||
	if (typeof key !== "string") key = JSON.stringify(key);
 | 
			
		||||
	if (!cache) {
 | 
			
		||||
		const keyStore = scope.host();
 | 
			
		||||
		if (storeMemo.has(keyStore))
 | 
			
		||||
			cache = storeMemo.get(keyStore);
 | 
			
		||||
		else {
 | 
			
		||||
			cache = {};
 | 
			
		||||
			storeMemo.set(keyStore, cache);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if (!storeMemo.has(host)) storeMemo.set(host, {});
 | 
			
		||||
	const cache = storeMemo.get(host);
 | 
			
		||||
	return hasOwn(cache, key) ? cache[key] : cache[key] = fun();
 | 
			
		||||
}
 | 
			
		||||
signal.el = function(s, map) {
 | 
			
		||||
	const mark_start = createElement.mark({ type: "reactive" }, true);
 | 
			
		||||
	const mark_start = createElement.mark({ type: "reactive", source: new Defined().compact }, true);
 | 
			
		||||
	const mark_end = mark_start.end;
 | 
			
		||||
	const out = enviroment.D.createDocumentFragment();
 | 
			
		||||
	out.append(mark_start, mark_end);
 | 
			
		||||
	const { current } = scope;
 | 
			
		||||
	let cache = {};
 | 
			
		||||
	const reRenderReactiveElement = (v) => {
 | 
			
		||||
		if (!mark_start.parentNode || !mark_end.parentNode)
 | 
			
		||||
			return removeSignalListener(s, reRenderReactiveElement);
 | 
			
		||||
		let cache_tmp = cache;
 | 
			
		||||
		cache = {};
 | 
			
		||||
		const cache = {};
 | 
			
		||||
		scope.push(current);
 | 
			
		||||
		let els = map(v, function useCache(key, fun) {
 | 
			
		||||
			return cache[key] = memo(key, fun, cache_tmp);
 | 
			
		||||
			return cache[key] = memo(key, fun, reRenderReactiveElement);
 | 
			
		||||
		});
 | 
			
		||||
		cache_tmp = {};
 | 
			
		||||
		storeMemo.set(reRenderReactiveElement, cache);
 | 
			
		||||
		scope.pop();
 | 
			
		||||
		if (!Array.isArray(els))
 | 
			
		||||
			els = [els];
 | 
			
		||||
@@ -717,10 +780,6 @@ signal.el = function(s, map) {
 | 
			
		||||
	addSignalListener(s, reRenderReactiveElement);
 | 
			
		||||
	removeSignalsFromElements(s, reRenderReactiveElement, mark_start, map);
 | 
			
		||||
	reRenderReactiveElement(s());
 | 
			
		||||
	current.host(on.disconnected(() => (
 | 
			
		||||
		/*! This clears memoized elements in S.el when the host is disconnected */
 | 
			
		||||
		cache = {}
 | 
			
		||||
	)));
 | 
			
		||||
	return out;
 | 
			
		||||
};
 | 
			
		||||
function requestCleanUpReactives(host) {
 | 
			
		||||
@@ -762,6 +821,15 @@ signal.observedAttributes = function(element) {
 | 
			
		||||
};
 | 
			
		||||
var signals_config = {
 | 
			
		||||
	isSignal,
 | 
			
		||||
	/**
 | 
			
		||||
	* Processes attributes that might be signals
 | 
			
		||||
	*
 | 
			
		||||
	* @param {Element} element - Element with the attribute
 | 
			
		||||
	* @param {string} key - Attribute name
 | 
			
		||||
	* @param {any} attrs - Attribute value (possibly a signal)
 | 
			
		||||
	* @param {Function} set - Function to set attribute value
 | 
			
		||||
	* @returns {any} Processed attribute value
 | 
			
		||||
	*/
 | 
			
		||||
	processReactiveAttribute(element, key, attrs, set) {
 | 
			
		||||
		if (!isSignal(attrs)) return attrs;
 | 
			
		||||
		const l = (attr) => {
 | 
			
		||||
@@ -800,6 +868,9 @@ function create(is_readonly, value, actions) {
 | 
			
		||||
	return SI;
 | 
			
		||||
}
 | 
			
		||||
var protoSigal = Object.assign(/* @__PURE__ */ Object.create(null), {
 | 
			
		||||
	/**
 | 
			
		||||
	* Prevents signal propagation
 | 
			
		||||
	*/
 | 
			
		||||
	stopPropagation() {
 | 
			
		||||
		this.skip = true;
 | 
			
		||||
	}
 | 
			
		||||
@@ -821,7 +892,7 @@ function toSignal(s, value, actions, readonly = false) {
 | 
			
		||||
			onclear,
 | 
			
		||||
			host,
 | 
			
		||||
			listeners: /* @__PURE__ */ new Set(),
 | 
			
		||||
			defined: new SignalDefined().stack,
 | 
			
		||||
			defined: new Defined().stack,
 | 
			
		||||
			readonly
 | 
			
		||||
		},
 | 
			
		||||
		enumerable: false,
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										67
									
								
								dist/esm.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										67
									
								
								dist/esm.js
									
									
									
									
										vendored
									
									
								
							@@ -1,8 +1,21 @@
 | 
			
		||||
// src/signals-lib/common.js
 | 
			
		||||
var signals_global = {
 | 
			
		||||
	/**
 | 
			
		||||
	* Checks if a value is a signal
 | 
			
		||||
	* @param {any} attributes - Value to check
 | 
			
		||||
	* @returns {boolean} Whether the value is a signal
 | 
			
		||||
	*/
 | 
			
		||||
	isSignal(attributes) {
 | 
			
		||||
		return false;
 | 
			
		||||
	},
 | 
			
		||||
	/**
 | 
			
		||||
	* Processes an attribute that might be reactive
 | 
			
		||||
	* @param {Element} obj - Element that owns the attribute
 | 
			
		||||
	* @param {string} key - Attribute name
 | 
			
		||||
	* @param {any} attr - Attribute value
 | 
			
		||||
	* @param {Function} set - Function to set the attribute
 | 
			
		||||
	* @returns {any} Processed attribute value
 | 
			
		||||
	*/
 | 
			
		||||
	processReactiveAttribute(obj, key, attr, set) {
 | 
			
		||||
		return attr;
 | 
			
		||||
	}
 | 
			
		||||
@@ -78,26 +91,55 @@ var scopes = [{
 | 
			
		||||
	prevent: true
 | 
			
		||||
}];
 | 
			
		||||
var scope = {
 | 
			
		||||
	/**
 | 
			
		||||
	* Gets the current scope
 | 
			
		||||
	* @returns {Object} Current scope context
 | 
			
		||||
	*/
 | 
			
		||||
	get current() {
 | 
			
		||||
		return scopes[scopes.length - 1];
 | 
			
		||||
	},
 | 
			
		||||
	/**
 | 
			
		||||
	* Gets the host element of the current scope
 | 
			
		||||
	* @returns {Function} Host accessor function
 | 
			
		||||
	*/
 | 
			
		||||
	get host() {
 | 
			
		||||
		return this.current.host;
 | 
			
		||||
	},
 | 
			
		||||
	/**
 | 
			
		||||
	* Prevents default behavior in the current scope
 | 
			
		||||
	* @returns {Object} Current scope context
 | 
			
		||||
	*/
 | 
			
		||||
	preventDefault() {
 | 
			
		||||
		const { current } = this;
 | 
			
		||||
		current.prevent = true;
 | 
			
		||||
		return current;
 | 
			
		||||
	},
 | 
			
		||||
	/**
 | 
			
		||||
	* Gets a copy of the current scope stack
 | 
			
		||||
	* @returns {Array} Copy of scope stack
 | 
			
		||||
	*/
 | 
			
		||||
	get state() {
 | 
			
		||||
		return [...scopes];
 | 
			
		||||
	},
 | 
			
		||||
	/**
 | 
			
		||||
	* Pushes a new scope to the stack
 | 
			
		||||
	* @param {Object} [s={}] - Scope object to push
 | 
			
		||||
	* @returns {number} New length of the scope stack
 | 
			
		||||
	*/
 | 
			
		||||
	push(s = {}) {
 | 
			
		||||
		return scopes.push(Object.assign({}, this.current, { prevent: false }, s));
 | 
			
		||||
	},
 | 
			
		||||
	/**
 | 
			
		||||
	* Pushes the root scope to the stack
 | 
			
		||||
	* @returns {number} New length of the scope stack
 | 
			
		||||
	*/
 | 
			
		||||
	pushRoot() {
 | 
			
		||||
		return scopes.push(scopes[0]);
 | 
			
		||||
	},
 | 
			
		||||
	/**
 | 
			
		||||
	* Pops the current scope from the stack
 | 
			
		||||
	* @returns {Object|undefined} Popped scope or undefined if only one scope remains
 | 
			
		||||
	*/
 | 
			
		||||
	pop() {
 | 
			
		||||
		if (scopes.length === 1) return;
 | 
			
		||||
		return scopes.pop();
 | 
			
		||||
@@ -329,12 +371,22 @@ function connectionsChangesObserverConstructor() {
 | 
			
		||||
	};
 | 
			
		||||
	const observer = new enviroment.M(observerListener(stop));
 | 
			
		||||
	return {
 | 
			
		||||
		/**
 | 
			
		||||
		* Creates an observer for a specific element
 | 
			
		||||
		* @param {Element} element - Element to observe
 | 
			
		||||
		* @returns {Function} Cleanup function
 | 
			
		||||
		*/
 | 
			
		||||
		observe(element) {
 | 
			
		||||
			const o = new enviroment.M(observerListener(() => {
 | 
			
		||||
			}));
 | 
			
		||||
			o.observe(element, { childList: true, subtree: true });
 | 
			
		||||
			return () => o.disconnect();
 | 
			
		||||
		},
 | 
			
		||||
		/**
 | 
			
		||||
		* Register a connection listener for an element
 | 
			
		||||
		* @param {Element} element - Element to watch
 | 
			
		||||
		* @param {Function} listener - Callback for connection event
 | 
			
		||||
		*/
 | 
			
		||||
		onConnected(element, listener) {
 | 
			
		||||
			start();
 | 
			
		||||
			const listeners = getElementStore(element);
 | 
			
		||||
@@ -342,6 +394,11 @@ function connectionsChangesObserverConstructor() {
 | 
			
		||||
			listeners.connected.add(listener);
 | 
			
		||||
			listeners.length_c += 1;
 | 
			
		||||
		},
 | 
			
		||||
		/**
 | 
			
		||||
		* Unregister a connection listener
 | 
			
		||||
		* @param {Element} element - Element being watched
 | 
			
		||||
		* @param {Function} listener - Callback to remove
 | 
			
		||||
		*/
 | 
			
		||||
		offConnected(element, listener) {
 | 
			
		||||
			if (!store.has(element)) return;
 | 
			
		||||
			const ls = store.get(element);
 | 
			
		||||
@@ -350,6 +407,11 @@ function connectionsChangesObserverConstructor() {
 | 
			
		||||
			ls.length_c -= 1;
 | 
			
		||||
			cleanWhenOff(element, ls);
 | 
			
		||||
		},
 | 
			
		||||
		/**
 | 
			
		||||
		* Register a disconnection listener for an element
 | 
			
		||||
		* @param {Element} element - Element to watch
 | 
			
		||||
		* @param {Function} listener - Callback for disconnection event
 | 
			
		||||
		*/
 | 
			
		||||
		onDisconnected(element, listener) {
 | 
			
		||||
			start();
 | 
			
		||||
			const listeners = getElementStore(element);
 | 
			
		||||
@@ -357,6 +419,11 @@ function connectionsChangesObserverConstructor() {
 | 
			
		||||
			listeners.disconnected.add(listener);
 | 
			
		||||
			listeners.length_d += 1;
 | 
			
		||||
		},
 | 
			
		||||
		/**
 | 
			
		||||
		* Unregister a disconnection listener
 | 
			
		||||
		* @param {Element} element - Element being watched
 | 
			
		||||
		* @param {Function} listener - Callback to remove
 | 
			
		||||
		*/
 | 
			
		||||
		offDisconnected(element, listener) {
 | 
			
		||||
			if (!store.has(element)) return;
 | 
			
		||||
			const ls = store.get(element);
 | 
			
		||||
 
 | 
			
		||||
@@ -53,7 +53,8 @@
 | 
			
		||||
		"globals": {
 | 
			
		||||
			"requestIdleCallback": false,
 | 
			
		||||
			"AbortController": false,
 | 
			
		||||
			"AbortSignal": false
 | 
			
		||||
			"AbortSignal": false,
 | 
			
		||||
			"FinalizationRegistry": false
 | 
			
		||||
		}
 | 
			
		||||
	},
 | 
			
		||||
	"size-limit": [
 | 
			
		||||
@@ -65,7 +66,7 @@
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"path": "./signals.js",
 | 
			
		||||
			"limit": "12 kB",
 | 
			
		||||
			"limit": "12.5 kB",
 | 
			
		||||
			"gzip": false,
 | 
			
		||||
			"brotli": false
 | 
			
		||||
		},
 | 
			
		||||
 
 | 
			
		||||
@@ -62,3 +62,21 @@ export function observedAttributes(instance, observedAttribute){
 | 
			
		||||
 * @returns {string} The camelCase string
 | 
			
		||||
 */
 | 
			
		||||
function kebabToCamel(name){ return name.replace(/-./g, x=> x[1].toUpperCase()); }
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Error class for definition tracking
 | 
			
		||||
 * Shows the correct stack trace for debugging (signal) creation
 | 
			
		||||
 */
 | 
			
		||||
export class Defined extends Error{
 | 
			
		||||
	constructor(){
 | 
			
		||||
		super();
 | 
			
		||||
		const [ curr, ...rest ]= this.stack.split("\n");
 | 
			
		||||
		const curr_file= curr.slice(curr.indexOf("@"), curr.indexOf(".js:")+4);
 | 
			
		||||
		const curr_lib= curr_file.includes("src/helpers.js") ? "src/" : curr_file;
 | 
			
		||||
		this.stack= rest.find(l=> !l.includes(curr_lib)) || curr;
 | 
			
		||||
	}
 | 
			
		||||
	get compact(){
 | 
			
		||||
		const { stack }= this;
 | 
			
		||||
		return stack.slice(0, stack.indexOf("@")+1)+"…"+stack.slice(stack.lastIndexOf("/"));
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -4,19 +4,6 @@
 | 
			
		||||
 */
 | 
			
		||||
export const mark= "__dde_signal";
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Error class for signal definition tracking
 | 
			
		||||
 * Shows the correct stack trace for debugging signal creation
 | 
			
		||||
 */
 | 
			
		||||
export class SignalDefined extends Error{
 | 
			
		||||
	constructor(){
 | 
			
		||||
		super();
 | 
			
		||||
		const [ curr, ...rest ]= this.stack.split("\n");
 | 
			
		||||
		const curr_file= curr.slice(curr.indexOf("@"), curr.indexOf(".js:")+4);
 | 
			
		||||
		this.stack= rest.find(l=> !l.includes(curr_file));
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Batches signal updates to improve performance
 | 
			
		||||
 * @type {Function}
 | 
			
		||||
@@ -32,6 +19,7 @@ export const queueSignalWrite= (()=> {
 | 
			
		||||
	function flushSignals() {
 | 
			
		||||
		scheduled = false;
 | 
			
		||||
		for(const signal of pendingSignals){
 | 
			
		||||
			pendingSignals.delete(signal);
 | 
			
		||||
			const M = signal[mark];
 | 
			
		||||
			if(M) M.listeners.forEach(l => l(M.value));
 | 
			
		||||
		}
 | 
			
		||||
@@ -47,5 +35,5 @@ export const queueSignalWrite= (()=> {
 | 
			
		||||
		if(scheduled) return;
 | 
			
		||||
		scheduled = true;
 | 
			
		||||
		queueMicrotask(flushSignals);
 | 
			
		||||
	}
 | 
			
		||||
	};
 | 
			
		||||
})();
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
import { SignalDefined, queueSignalWrite, mark } from "./helpers.js";
 | 
			
		||||
import { queueSignalWrite, mark } from "./helpers.js";
 | 
			
		||||
export { mark };
 | 
			
		||||
import { hasOwn } from "../helpers.js";
 | 
			
		||||
import { hasOwn, Defined } from "../helpers.js";
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Checks if a value is a signal
 | 
			
		||||
@@ -62,7 +62,7 @@ export function signal(value, actions){
 | 
			
		||||
			if(deps_curr.has(dep_signal)) continue;
 | 
			
		||||
			removeSignalListener(dep_signal, contextReWatch);
 | 
			
		||||
		}
 | 
			
		||||
	};
 | 
			
		||||
	}
 | 
			
		||||
	deps.set(out[mark], contextReWatch);
 | 
			
		||||
	deps.set(contextReWatch, new Set([ out ]));
 | 
			
		||||
	contextReWatch();
 | 
			
		||||
@@ -159,51 +159,42 @@ import { on } from "../events.js";
 | 
			
		||||
const storeMemo= new WeakMap();
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Memoizes a function result by key
 | 
			
		||||
 * Memoizes a function result
 | 
			
		||||
 *
 | 
			
		||||
 * @param {string|any} key - Cache key (non-strings will be stringified)
 | 
			
		||||
 * @param {string|unknown} key - Cache key (non-strings will be stringified)
 | 
			
		||||
 * @param {Function} fun - Function to compute value
 | 
			
		||||
 * @param {Object} [cache] - Optional explicit cache object
 | 
			
		||||
 * @returns {any} Cached or computed result
 | 
			
		||||
 * @param {keyof storeMemo} [host= fun]
 | 
			
		||||
 * @returns {unknown} Cached or computed result
 | 
			
		||||
 */
 | 
			
		||||
export function memo(key, fun, cache){
 | 
			
		||||
export function memo(key, fun, host= fun){
 | 
			
		||||
	if(typeof key!=="string") key= JSON.stringify(key);
 | 
			
		||||
	if(!cache) {
 | 
			
		||||
		const keyStore= scope.host();
 | 
			
		||||
		if(storeMemo.has(keyStore))
 | 
			
		||||
			cache= storeMemo.get(keyStore);
 | 
			
		||||
		else {
 | 
			
		||||
			cache= {};
 | 
			
		||||
			storeMemo.set(keyStore, cache);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if (!storeMemo.has(host)) storeMemo.set(host, {});
 | 
			
		||||
	const cache= storeMemo.get(host);
 | 
			
		||||
	return hasOwn(cache, key) ? cache[key] : (cache[key]= fun());
 | 
			
		||||
}
 | 
			
		||||
// TODO: third argument for handle `cache_tmp` in re-render
 | 
			
		||||
/**
 | 
			
		||||
 * Creates a reactive DOM element that re-renders when signal changes
 | 
			
		||||
 *
 | 
			
		||||
 * @TODO Third argument for handle `cache_tmp` in re-render
 | 
			
		||||
 * @param {function} s - Signal to watch
 | 
			
		||||
 * @param {Function} map - Function mapping signal value to DOM elements
 | 
			
		||||
 * @returns {DocumentFragment} Fragment containing reactive elements
 | 
			
		||||
 */
 | 
			
		||||
signal.el= function(s, map){
 | 
			
		||||
	const mark_start= el.mark({ type: "reactive" }, true);
 | 
			
		||||
	const mark_start= el.mark({ type: "reactive", source: new Defined().compact }, true);
 | 
			
		||||
	const mark_end= mark_start.end;
 | 
			
		||||
	const out= env.D.createDocumentFragment();
 | 
			
		||||
	out.append(mark_start, mark_end);
 | 
			
		||||
	const { current }= scope;
 | 
			
		||||
	let cache= {};
 | 
			
		||||
	const reRenderReactiveElement= v=> {
 | 
			
		||||
		if(!mark_start.parentNode || !mark_end.parentNode) // === `isConnected` or wasn’t yet rendered
 | 
			
		||||
			return removeSignalListener(s, reRenderReactiveElement);
 | 
			
		||||
		let cache_tmp= cache; // will be reused in the useCache or removed in the while loop on the end
 | 
			
		||||
		cache= {};
 | 
			
		||||
		const cache= {}; // remove unused els from cache
 | 
			
		||||
		scope.push(current);
 | 
			
		||||
		let els= map(v, function useCache(key, fun){
 | 
			
		||||
			return cache[key]= memo(key, fun, cache_tmp);
 | 
			
		||||
			return (cache[key]= memo(key, fun, reRenderReactiveElement));
 | 
			
		||||
		});
 | 
			
		||||
		cache_tmp= {};
 | 
			
		||||
		storeMemo.set(reRenderReactiveElement, cache);
 | 
			
		||||
		scope.pop();
 | 
			
		||||
		if(!Array.isArray(els))
 | 
			
		||||
			els= [ els ];
 | 
			
		||||
@@ -220,9 +211,6 @@ signal.el= function(s, map){
 | 
			
		||||
	addSignalListener(s, reRenderReactiveElement);
 | 
			
		||||
	removeSignalsFromElements(s, reRenderReactiveElement, mark_start, map);
 | 
			
		||||
	reRenderReactiveElement(s());
 | 
			
		||||
	current.host(on.disconnected(()=>
 | 
			
		||||
		/*! This clears memoized elements in S.el when the host is disconnected */
 | 
			
		||||
		cache= {}));
 | 
			
		||||
	return out;
 | 
			
		||||
};
 | 
			
		||||
/**
 | 
			
		||||
@@ -407,7 +395,7 @@ function toSignal(s, value, actions, readonly= false){
 | 
			
		||||
		value: {
 | 
			
		||||
			value, actions, onclear, host,
 | 
			
		||||
			listeners: new Set(),
 | 
			
		||||
			defined: (new SignalDefined()).stack,
 | 
			
		||||
			defined: new Defined().stack,
 | 
			
		||||
			readonly
 | 
			
		||||
		},
 | 
			
		||||
		enumerable: false,
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user