diff --git a/packages/signalizejs/directives/src/index.ts b/packages/signalizejs/directives/src/index.ts index 5ad3c09f..42f0fd0 100755 --- a/packages/signalizejs/directives/src/index.ts +++ b/packages/signalizejs/directives/src/index.ts @@ -3,6 +3,7 @@ import type { Signalize, Scope } from 'signalizejs' declare module '..' { interface Signalize { directive: (name: string, data: Directive) => void + createDirectiveFunction: (options: CreateFunctionOptions) => () => Promise AsyncFunction: () => Promise } @@ -113,10 +114,10 @@ export default ($: Signalize): void => { const directive = directives[directiveName]; const elementScope = scope(element, (elementScope) => { if (!('directives' in elementScope)) { - elementScope.directives = []; + elementScope.directives = new Set(); } - elementScope.directives.push(directiveName); + elementScope.directives.add(directiveName); }); countdown --; @@ -262,20 +263,26 @@ export default ($: Signalize): void => { const newContextVariables: string[] = argumentsMatch[1].replace(/[[({})\]\s]/g, '').split(','); let unwatchSignalCallbacks = []; + const signalsToWatch = []; - const process = async (): Promise => { - const signalsToWatch = []; + for (const signal of Object.values(data)) { + if (typeof signal !== 'function') { + continue; + } - for (const signal of Object.values(data)) { - if (typeof signal !== 'function') { - continue; - } + const unwatch = signal.watch(() => { + signalsToWatch.push(signal); + unwatch(); + }, { execution: 'onGet' }) + } - const unwatch = signal.watch(() => { - signalsToWatch.push(signal); - unwatch(); - }, { execution: 'onGet' }) - } + const stackFn = createFunction({ + functionString: `return typeof ${argumentsMatch[3]} === 'function' ? ${argumentsMatch[3]}() : ${argumentsMatch[3]};`, + context: data, + element + }); + + const process = async (): Promise => { const directivesProcessingPromises = []; const processScope = async (scopeToProcess) => { const templateFragment = element.cloneNode(true).content; @@ -289,11 +296,6 @@ export default ($: Signalize): void => { } } - const stackFn = createFunction({ - functionString: `return typeof ${argumentsMatch[3]} === 'function' ? ${argumentsMatch[3]}() : ${argumentsMatch[3]};`, - context: data, - element - }); let stack = await stackFn(data); if (typeof stack === 'number') { @@ -364,7 +366,7 @@ export default ($: Signalize): void => { if (elementScope !== undefined && elementScope?.directives !== undefined) { elementScope.cleanup(); const directivesQueue = elementScope.directives; - elementScope.directives = []; + elementScope.directives.clear(); processElement(element, directivesQueue); } @@ -461,19 +463,15 @@ export default ($: Signalize): void => { nextElementSibling = nextElementToRemove; removeId++; } - - for (const unwatch of unwatchSignalCallbacks) { - unwatch(); - } - - unwatchSignalCallbacks = []; - for (const signalToWatch of signalsToWatch) { - unwatchSignalCallbacks.push(signalToWatch.watch(process)) - } } await process(); + unwatchSignalCallbacks = []; + for (const signalToWatch of signalsToWatch) { + unwatchSignalCallbacks.push(signalToWatch.watch(process)) + } + scope(element).cleanup(() => { for (const unwatch of unwatchSignalCallbacks) { unwatch(); @@ -695,6 +693,7 @@ export default ($: Signalize): void => { }) $.AsyncFunction = AsyncFunction; + $.createDirectiveFunction = createFunction; $.directive = directive; }) } diff --git a/packages/signalizejs/src/plugins/bind.ts b/packages/signalizejs/src/plugins/bind.ts index d0c09cc..d19395c 100755 --- a/packages/signalizejs/src/plugins/bind.ts +++ b/packages/signalizejs/src/plugins/bind.ts @@ -8,7 +8,7 @@ declare module '..' { } export default ($: Signalize): void => { - const { scope, Signal, on, off, task } = $; + const { scope, Signal, on, off } = $; const reactiveInputAttributes = ['value', 'checked']; const numericInputAttributes = ['range', 'number']; @@ -88,7 +88,7 @@ export default ($: Signalize): void => { } if (attributeBinderIsSignal === true) { - signalsToWatch.push(attributeBinder); + //signalsToWatch.push(attributeBinder); } if (attributeBinderIsSignal === true || signalsToWatch.length === 1) { @@ -119,10 +119,8 @@ export default ($: Signalize): void => { }; on('input', element, () => { - task(() => { - inputListener() - }); - }); + inputListener() + }, { passive: true }); if (elementScope instanceof Scope) { elementScope.cleanup(() => { diff --git a/packages/signalizejs/src/plugins/signal.ts b/packages/signalizejs/src/plugins/signal.ts index d04c253..94dfd02 100755 --- a/packages/signalizejs/src/plugins/signal.ts +++ b/packages/signalizejs/src/plugins/signal.ts @@ -32,6 +32,8 @@ export class Signal extends Function { onGet: new Set() }; + setTimeout = undefined; + constructor (defaultValue: T) { super() this.value = defaultValue; @@ -51,32 +53,35 @@ export class Signal extends Function { } set = (newValue: T): void => { - const oldValue = this.value; + clearTimeout(this.setTimeout); + this.setTimeout = setTimeout(() => { + const oldValue = this.value; - if (['string', 'number'].includes(typeof newValue) && newValue === oldValue) { - return; - } + if (['string', 'number'].includes(typeof newValue) && newValue === oldValue) { + return; + } - let settable = true; - for (const watcher of this.watchers.beforeSet) { - const watcherData = watcher({ newValue, oldValue }); - if (typeof watcherData !== 'undefined') { - settable = watcherData.settable ?? settable; - newValue = watcherData.value; + let settable = true; + for (const watcher of this.watchers.beforeSet) { + const watcherData = watcher({ newValue, oldValue }); + if (typeof watcherData !== 'undefined') { + settable = watcherData.settable ?? settable; + newValue = watcherData.value; + } + if (!settable) { + break; + } } + if (!settable) { - break; + return; } - } - if (!settable) { - return; - } - - this.value = newValue; - for (const watcher of this.watchers.afterSet) { - watcher({ newValue, oldValue }); - } + this.value = newValue; + for (const watcher of this.watchers.afterSet) { + watcher({ newValue, oldValue }) + } + }); } watch = (listener: BeforeSetSignalWatcher | AfterSetSignalWatcher, options: SignalWatcherOptions = {}): Unwatch => {