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