@pravosleva/reactive-engine 2.3.0-alpha → 2.3.2-alpha

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../../src/core/core.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../../src/core/core.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"core.method.computed.d.ts","sourceRoot":"","sources":["../../src/core/core.method.computed.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAa,MAAM,SAAS,CAAA;AAE7C,wBAAgB,cAAc,CAAC,CAAC,EAC9B,MAAM,EAAE,GAAG,EACX,EAAE,EAAE,MAAM,CAAC,EACX,UAAU,CAAC,EAAE,MAAM,GAClB,QAAQ,CAAC,CAAC,CAAC,CA6Sb"}
1
+ {"version":3,"file":"core.method.computed.d.ts","sourceRoot":"","sources":["../../src/core/core.method.computed.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAa,MAAM,SAAS,CAAA;AAE7C,wBAAgB,cAAc,CAAC,CAAC,EAC9B,MAAM,EAAE,GAAG,EACX,EAAE,EAAE,MAAM,CAAC,EACX,UAAU,CAAC,EAAE,MAAM,GAClB,QAAQ,CAAC,CAAC,CAAC,CAoRb"}
@@ -1 +1 @@
1
- {"version":3,"file":"core.method.signal.d.ts","sourceRoot":"","sources":["../../src/core/core.method.signal.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AAE/C,wBAAgB,YAAY,CAAC,CAAC,EAC5B,MAAM,EAAE,GAAG,EACX,YAAY,EAAE,CAAC,EACf,aAAa,CAAC,EAAE,aAAa,CAAC,CAAC,CAAC,GAAG,MAAM,GACxC,MAAM,CAAC,CAAC,CAAC,CA6HX"}
1
+ {"version":3,"file":"core.method.signal.d.ts","sourceRoot":"","sources":["../../src/core/core.method.signal.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AAE/C,wBAAgB,YAAY,CAAC,CAAC,EAC5B,MAAM,EAAE,GAAG,EACX,YAAY,EAAE,CAAC,EACf,aAAa,CAAC,EAAE,aAAa,CAAC,CAAC,CAAC,GAAG,MAAM,GACxC,MAAM,CAAC,CAAC,CAAC,CA2HX"}
package/dist/core.cjs CHANGED
@@ -1,2 +1,2 @@
1
- const e=require("./utils/getExtractedValues.cjs"),t=require("./core.method.computed.cjs"),n=require("./core.method.signal.cjs"),r=require("./core.method.untrack.cjs"),i=require("./core.method.reactive.cjs"),a=require("./core.method.effect.cjs"),o=require("./core.logger.cjs");var s={signal:`background: #007acc; color: #fff; padding: 2px 6px; border-radius: 4px; font-weight: bold;`,computed:`background: #42b883; color: #fff; padding: 2px 6px; border-radius: 4px; font-weight: bold;`,effect:`background: #e01e5a; color: #fff; padding: 2px 6px; border-radius: 4px; font-weight: bold;`,batch:`background: #7952b3; color: #fff; padding: 2px 6px; border-radius: 4px; font-weight: bold;`,resource:`background: #d97706; color: #fff; padding: 2px 6px; border-radius: 4px; font-weight: bold;`,reactive:`background: #007acc; color: #fff; padding: 2px 6px; border-radius: 4px; font-weight: bold;`},c=null;function l(e){if(e===null)return`null`;if(e===void 0)return`undefined`;if(typeof e==`object`)try{return JSON.stringify(e)}catch{return`[Cyclic Object or Layer]`}return String(e)}function u(e,t,n){c||(c={id:Math.random().toString(36).substring(2,9),pendingLogQueue:[],isFlushing:!1},queueMicrotask(()=>d())),c.pendingLogQueue.push({type:e,label:t,from:n?.from,to:n?.to,payload:n?.payload,timestamp:Date.now()})}function d(){if(!c||c.isFlushing)return;c.isFlushing=!0;let e=c.pendingLogQueue;if(e.length===0){c=null;return}console.groupCollapsed(`%cREACTIVE TRANSACTION%c [id: ${c.id}] (${e.length} operations)`,`background: #7952b3; color: #fff; padding: 2px 6px; border-radius: 4px; font-weight: bold;`,`color: #888; font-weight: normal;`);for(let t of e){let e=s[t.type],n=t.from!==void 0||t.to!==void 0,r=`%c${t.type.toUpperCase()}%c ${t.label}`;n&&(t.from?r+=` ${l(t.from)} → ${l(t.to)}`:r+=` (${l(t.to)})`),t.payload===void 0?console.log(r,e,`color: inherit;`):(console.groupCollapsed(r,e,`color: inherit;`),console.log(`Payload:`,t.payload),console.groupEnd())}console.groupEnd(),c=null}var f=class{frameworkPrefix=`core`;logger;epoch=0;activeConsumer=null;batchDepth=0;subscriberId=0;pendingEffects=[];maxPendingDepth=0;computedCache=new WeakMap;diRegistry=new Map;diCache=new Map;proxyCache=new WeakMap;proxyTargets=new WeakSet;reactiveSignals=new WeakMap;cycleDetectionStack=new Set;batchedSignals=new Set;activeOwner=null;pendingCleanups=new Set;queueCleanup(e){this.pendingCleanups.add(e)}constructor(e){this.logger=e?.logger||{isEnabled:!1}}scheduleEffect(e){let t=e.depth||0;this.pendingEffects[t]||(this.pendingEffects[t]=new Set),this.pendingEffects[t].add(e),t>this.maxPendingDepth&&(this.maxPendingDepth=t)}queueLog(e,t,n){u(e,t,n)}batch(e){this.batchDepth++;try{return e()}finally{if(this.batchDepth--,this.batchDepth===0){let e=Array.from(this.batchedSignals);this.batchedSignals.clear(),e.forEach(e=>{e._flushBatch&&e._flushBatch()}),this.flushEffects()}}}flushEffects(){if(this.batchDepth>0)return;let e=this.activeConsumer;try{for(let e=0;e<=this.maxPendingDepth;e++){let t=this.pendingEffects[e];if(!t||t.size===0)continue;let n=Array.from(t);t.clear();for(let e of n)if(!e.isDisposed){if(e.dependencies&&e.dependencies.size>0){let t=!1;for(let n of e.dependencies){let r=n._node||n;r.type===`computed`&&r.state>0&&r.update&&r.update(),e.depVersions&&e.depVersions.get(n)!==r.version&&(t=!0)}if(!t&&e.dependencies.size>0){e.isDirty=!1;continue}}if(e.isDirty)try{e.run()}catch(e){throw e}}if(e>0){let t=!1;for(let n=0;n<e;n++)if(this.pendingEffects[n]&&this.pendingEffects[n].size>0){t=!0;break}t&&(e=-1)}}this.maxPendingDepth=0}finally{this.activeConsumer=e}}log({type:e,label:t,details:n,isInternalCoreSignal:r=!1}){o.ReactiveDebounceLogger.processLog(this.logger,u,{type:e,label:t,details:n,isInternalCoreSignal:r})}signal(e,t){return n.createSignal(this,e,t)}computed(e,n){return t.createComputed(this,e,n)}effect(e,t){return a.createEffect(this,e,t)}untrack(e){return r.executeUntrack(this,e)}reactive(e,t){return i.createReactive(this,e,t)}provide(e,t){this.diRegistry.set(e,t),this.diCache.delete(e)}inject(e){if(e==null)throw Error(`[DI Error] Token is empty`);if(this.diCache.has(e))return this.diCache.get(e);if(this.cycleDetectionStack.has(e))throw Error(`[DI Error] Cyclic dependency detected`);this.cycleDetectionStack.add(e);try{if(this.diRegistry.has(e)){let t=this.diRegistry.get(e);if(typeof t==`function`){if(t._isMockFunction){let n=t(this);return n===void 0?t:(this.diCache.set(e,n),n)}let n=t.toString();if(!(n.startsWith(`class `)||n.startsWith(`class{`)||t.prototype&&t.prototype.constructor===t&&!n.startsWith(`function`)&&!n.includes(`=>`))){let n=t(this);return this.diCache.set(e,n),n}return t}return t}if(typeof e==`function`){let t=new e(this);return this.diCache.set(e,t),t}throw Error(`[DI Error] Token not found`)}finally{this.cycleDetectionStack.delete(e)}}delay(e,t){return new Promise((n,r)=>{if(t.aborted)return r(new DOMException(`Aborted`,`AbortError`));let i=setTimeout(()=>{t.removeEventListener(`abort`,a),n()},e),a=()=>{clearTimeout(i),r(new DOMException(`Aborted`,`AbortError`))};t.addEventListener(`abort`,a,{once:!0})})}resource(t,n,r){let i=r&&typeof r==`object`,a=i?r.name||`unnamed_resource`:r||`unnamed_resource`,o=i?r:{},s=o.resetDataOnSourceChange??!0,c=o.responseValidate,l=o.validateBeforeFetch,u=this.signal({data:null,loading:!0,error:null,isRetrying:!1},`[CORE_INTERNAL_SIGNAL=1]:resource:state:${a}`),d=e=>{this.log({type:`resource`,label:a,details:{to:e,from:u.value}}),u.value=e},f=async(n,r,i=!1)=>{if(r.aborted)return;if(o.validateBeforeFetch&&o.validateBeforeFetch(n),l){let e=l(n);if(e===!1||typeof e==`string`){if(r.aborted)return;let t=typeof e==`string`?e:`Pre-fetch validation failed for resource`,n=i?null:this.untrack(()=>u.value.data);d({data:n,loading:!1,error:t,isRetrying:!1});return}}let f=i&&s?null:this.untrack(()=>u.value.data);d({data:f,loading:!0,error:null,isRetrying:!1});for(let i=0;i<=0;i++){if(r.aborted)return;let o=r;try{let e=await t(n,o);if(r.aborted)return;if(o.aborted)throw new DOMException(`The operation timed out.`,`TimeoutError`);if(c){let t=c(e);if(t===!1||typeof t==`string`){if(r.aborted)return;d({data:null,loading:!1,error:typeof t==`string`?t:`Validation failed`,isRetrying:!1});return}}if(r.aborted)return;d({data:e,loading:!1,error:null,isRetrying:!1});return}catch(t){if(r.aborted||t.name===`AbortError`&&r.aborted)return;let n=t.name===`TimeoutError`||t.name===`AbortError`||t.message?.includes(`timeout`),o=e.getExtractedValues({tested:[t.message],expectedKey:`THROW_CUSTOM_VALIDATION_ERROR_NO_RETRY`,valueType:`number`})?.[0]===`1`||!1,s=o&&e.getExtractedValues({tested:[t.message],expectedKey:`MESSAGE`,valueType:`string`})?.[0]||`Custom validation error`,c=o||t.name===`ValidationError`;if(i===0||c){if(r.aborted)return;let e=n?Error(`Request timed out after 1000ms`,{cause:t}):o?Error(s,{cause:t}):t;d({data:null,loading:!1,error:e instanceof Error?e.message:typeof e==`string`?e:`typeof finalError is ${typeof e}`,isRetrying:!1});return}else{if(r.aborted)return;let e=1e3*2**i;e=Math.min(e,3e5);let t=Math.random()*200;e+=t,d({data:u.value.data,loading:!0,error:null,isRetrying:!0}),console.warn(`[Resource Retry] "${a}" сбой по ${n?`таймауту`:`ошибке сети`}. Попытка ${i+1}/${i+1}...`);try{if(await this.delay(e,r),r.aborted)return}catch{return}}}}},p=null;return this.effect(()=>{let e=n?n.value:void 0,t=new AbortController;return p=t,this.untrack(()=>{f(e,t.signal,!0)}),()=>t.abort()},`[CORE_INTERNAL_SIGNAL=1]:effect`),{get data(){return u.value.data},get loading(){return u.value.loading},get error(){return u.value.error},get isRetrying(){return u.value.isRetrying},get value(){return u.value},refetch:()=>{p?.abort(),p=new AbortController,f(n?n.value:void 0,p.signal,!1)},subscribe:e=>u.subscribe(e)}}};exports.ReactiveEngine=f,exports.ReactiveEngineAutomatic=f,exports.ReactiveEngineCore=f,exports.flushLogs=d,exports.queueLog=u;
1
+ const e=require("./utils/getExtractedValues.cjs"),t=require("./core.method.computed.cjs"),n=require("./core.method.signal.cjs"),r=require("./core.method.untrack.cjs"),i=require("./core.method.reactive.cjs"),a=require("./core.method.effect.cjs"),o=require("./core.logger.cjs");var s={signal:`background: #007acc; color: #fff; padding: 2px 6px; border-radius: 4px; font-weight: bold;`,computed:`background: #42b883; color: #fff; padding: 2px 6px; border-radius: 4px; font-weight: bold;`,effect:`background: #e01e5a; color: #fff; padding: 2px 6px; border-radius: 4px; font-weight: bold;`,batch:`background: #7952b3; color: #fff; padding: 2px 6px; border-radius: 4px; font-weight: bold;`,resource:`background: #d97706; color: #fff; padding: 2px 6px; border-radius: 4px; font-weight: bold;`,reactive:`background: #007acc; color: #fff; padding: 2px 6px; border-radius: 4px; font-weight: bold;`},c=null;function l(e){if(e===null)return`null`;if(e===void 0)return`undefined`;if(typeof e==`object`)try{return JSON.stringify(e)}catch{return`[Cyclic Object or Layer]`}return String(e)}function u(e,t,n){c||(c={id:Math.random().toString(36).substring(2,9),pendingLogQueue:[],isFlushing:!1},queueMicrotask(()=>d())),c.pendingLogQueue.push({type:e,label:t,from:n?.from,to:n?.to,payload:n?.payload,timestamp:Date.now()})}function d(){if(!c||c.isFlushing)return;c.isFlushing=!0;let e=c.pendingLogQueue;if(e.length===0){c=null;return}console.groupCollapsed(`%cREACTIVE TRANSACTION%c [id: ${c.id}] (${e.length} operations)`,`background: #7952b3; color: #fff; padding: 2px 6px; border-radius: 4px; font-weight: bold;`,`color: #888; font-weight: normal;`);for(let t of e){let e=s[t.type],n=t.from!==void 0||t.to!==void 0,r=`%c${t.type.toUpperCase()}%c ${t.label}`;n&&(t.from?r+=` ${l(t.from)} → ${l(t.to)}`:r+=` (${l(t.to)})`),t.payload===void 0?console.log(r,e,`color: inherit;`):(console.groupCollapsed(r,e,`color: inherit;`),console.log(`Payload:`,t.payload),console.groupEnd())}console.groupEnd(),c=null}var f=class{frameworkPrefix=`core`;logger;epoch=0;activeConsumer=null;batchDepth=0;subscriberId=0;pendingEffects=[];maxPendingDepth=0;computedCache=new WeakMap;diRegistry=new Map;diCache=new Map;proxyCache=new WeakMap;proxyTargets=new WeakSet;reactiveSignals=new WeakMap;cycleDetectionStack=new Set;batchedSignals=new Set;activeOwner=null;pendingCleanups=new Set;queueCleanup(e){this.pendingCleanups.add(e)}constructor(e){this.logger=e?.logger||{isEnabled:!1}}scheduleEffect(e){let t=e.depth||0;this.pendingEffects[t]||(this.pendingEffects[t]=new Set),this.pendingEffects[t].add(e),t>this.maxPendingDepth&&(this.maxPendingDepth=t)}queueLog(e,t,n){u(e,t,n)}batch(e){this.batchDepth++;try{return e()}finally{if(this.batchDepth--,this.batchDepth===0){let e=Array.from(this.batchedSignals);this.batchedSignals.clear(),e.forEach(e=>{e._flushBatch&&e._flushBatch()}),this.flushEffects()}}}flushEffects(){if(this.batchDepth>0)return;let e=this.activeConsumer;try{for(let e=0;e<=this.maxPendingDepth;e++){let t=this.pendingEffects[e];if(!t||t.size===0)continue;let n=Array.from(t);t.clear();for(let e of n)if(!e.isDisposed){if(e.dependencies&&e.dependencies.size>0){let t=!1;for(let n of e.dependencies){let r=n._node||n;r.type===`computed`&&r.state>0&&r.update&&r.update(),e.depVersions&&e.depVersions.get(n)!==r.version&&(t=!0)}if(!t&&e.dependencies.size>0){e.isDirty=!1;continue}}if(e.isDirty)try{e.run()}catch(e){throw e}}if(e>0){let t=!1;for(let n=0;n<e;n++)if(this.pendingEffects[n]&&this.pendingEffects[n].size>0){t=!0;break}t&&(e=-1)}}this.maxPendingDepth=0}finally{this.activeConsumer=e}}log(e){!this.logger||!this.logger.isEnabled||o.ReactiveDebounceLogger.processLog(this.logger,u,e)}signal(e,t){return n.createSignal(this,e,t)}computed(e,n){return t.createComputed(this,e,n)}effect(e,t){return a.createEffect(this,e,t)}untrack(e){return r.executeUntrack(this,e)}reactive(e,t){return i.createReactive(this,e,t)}provide(e,t){this.diRegistry.set(e,t),this.diCache.delete(e)}inject(e){if(e==null)throw Error(`[DI Error] Token is empty`);if(this.diCache.has(e))return this.diCache.get(e);if(this.cycleDetectionStack.has(e))throw Error(`[DI Error] Cyclic dependency detected`);this.cycleDetectionStack.add(e);try{if(this.diRegistry.has(e)){let t=this.diRegistry.get(e);if(typeof t==`function`){if(t._isMockFunction){let n=t(this);return n===void 0?t:(this.diCache.set(e,n),n)}let n=t.toString();if(!(n.startsWith(`class `)||n.startsWith(`class{`)||t.prototype&&t.prototype.constructor===t&&!n.startsWith(`function`)&&!n.includes(`=>`))){let n=t(this);return this.diCache.set(e,n),n}return t}return t}if(typeof e==`function`){let t=new e(this);return this.diCache.set(e,t),t}throw Error(`[DI Error] Token not found`)}finally{this.cycleDetectionStack.delete(e)}}delay(e,t){return new Promise((n,r)=>{if(t.aborted)return r(new DOMException(`Aborted`,`AbortError`));let i=setTimeout(()=>{t.removeEventListener(`abort`,a),n()},e),a=()=>{clearTimeout(i),r(new DOMException(`Aborted`,`AbortError`))};t.addEventListener(`abort`,a,{once:!0})})}resource(t,n,r){let i=r&&typeof r==`object`,a=i?r.name||`unnamed_resource`:r||`unnamed_resource`,o=i?r:{},s=o.resetDataOnSourceChange??!0,c=o.responseValidate,l=o.validateBeforeFetch,u=this.signal({data:null,loading:!0,error:null,isRetrying:!1},`[CORE_INTERNAL_SIGNAL=1]:resource:state:${a}`),d=e=>{this.log({type:`resource`,label:a,details:{to:e,from:u.value}}),u.value=e},f=async(n,r,i=!1)=>{if(r.aborted)return;if(o.validateBeforeFetch&&o.validateBeforeFetch(n),l){let e=l(n);if(e===!1||typeof e==`string`){if(r.aborted)return;let t=typeof e==`string`?e:`Pre-fetch validation failed for resource`,n=i?null:this.untrack(()=>u.value.data);d({data:n,loading:!1,error:t,isRetrying:!1});return}}let f=i&&s?null:this.untrack(()=>u.value.data);d({data:f,loading:!0,error:null,isRetrying:!1});for(let i=0;i<=0;i++){if(r.aborted)return;let o=r;try{let e=await t(n,o);if(r.aborted)return;if(o.aborted)throw new DOMException(`The operation timed out.`,`TimeoutError`);if(c){let t=c(e);if(t===!1||typeof t==`string`){if(r.aborted)return;d({data:null,loading:!1,error:typeof t==`string`?t:`Validation failed`,isRetrying:!1});return}}if(r.aborted)return;d({data:e,loading:!1,error:null,isRetrying:!1});return}catch(t){if(r.aborted||t.name===`AbortError`&&r.aborted)return;let n=t.name===`TimeoutError`||t.name===`AbortError`||t.message?.includes(`timeout`),o=e.getExtractedValues({tested:[t.message],expectedKey:`THROW_CUSTOM_VALIDATION_ERROR_NO_RETRY`,valueType:`number`})?.[0]===`1`||!1,s=o&&e.getExtractedValues({tested:[t.message],expectedKey:`MESSAGE`,valueType:`string`})?.[0]||`Custom validation error`,c=o||t.name===`ValidationError`;if(i===0||c){if(r.aborted)return;let e=n?Error(`Request timed out after 1000ms`,{cause:t}):o?Error(s,{cause:t}):t;d({data:null,loading:!1,error:e instanceof Error?e.message:typeof e==`string`?e:`typeof finalError is ${typeof e}`,isRetrying:!1});return}else{if(r.aborted)return;let e=1e3*2**i;e=Math.min(e,3e5);let t=Math.random()*200;e+=t,d({data:u.value.data,loading:!0,error:null,isRetrying:!0}),console.warn(`[Resource Retry] "${a}" сбой по ${n?`таймауту`:`ошибке сети`}. Попытка ${i+1}/${i+1}...`);try{if(await this.delay(e,r),r.aborted)return}catch{return}}}}},p=null;return this.effect(()=>{let e=n?n.value:void 0,t=new AbortController;return p=t,this.untrack(()=>{f(e,t.signal,!0)}),()=>t.abort()},`[CORE_INTERNAL_SIGNAL=1]:effect`),{get data(){return u.value.data},get loading(){return u.value.loading},get error(){return u.value.error},get isRetrying(){return u.value.isRetrying},get value(){return u.value},refetch:()=>{p?.abort(),p=new AbortController,f(n?n.value:void 0,p.signal,!1)},subscribe:e=>u.subscribe(e)}}};exports.ReactiveEngine=f,exports.ReactiveEngineAutomatic=f,exports.ReactiveEngineCore=f,exports.flushLogs=d,exports.queueLog=u;
2
2
  //# sourceMappingURL=core.cjs.map
package/dist/core.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"core.cjs","names":[],"sources":["../src/core/core.ts"],"sourcesContent":["import { getExtractedValues } from '../utils/getExtractedValues'\nimport { Signal, Computed, IEffect, EngineLoggerOptions, LogEventType, CleanupFn, TransactionContext, LogRecord, SignalOptions, ResourceOptions, ResourceState, Resource } from './types'\nimport { createComputed } from './core.method.computed'\nimport { createSignal } from './core.method.signal'\n// import { executeBatch } from './core.method.batch'\nimport { executeUntrack } from './core.method.untrack'\nimport { createReactive } from './core.method.reactive'\nimport { createEffect } from './core.method.effect'\nimport { ReactiveDebounceLogger } from './core.logger'\n\n// Тип для конструктора класса\ntype Constructor<T> = new (...args: any[]) => T\n// Тип для фабричной функции зависимостей\ntype Factory<T> = (engine: any) => T\n// Универсальный тип токена DI\ntype InjectionToken<T> = Constructor<T> | Factory<T> | symbol | string\n\nconst badgeColors: Record<LogEventType, string> = {\n signal: 'background: #007acc; color: #fff; padding: 2px 6px; border-radius: 4px; font-weight: bold;',\n computed: 'background: #42b883; color: #fff; padding: 2px 6px; border-radius: 4px; font-weight: bold;',\n effect: 'background: #e01e5a; color: #fff; padding: 2px 6px; border-radius: 4px; font-weight: bold;',\n batch: 'background: #7952b3; color: #fff; padding: 2px 6px; border-radius: 4px; font-weight: bold;',\n resource: 'background: #d97706; color: #fff; padding: 2px 6px; border-radius: 4px; font-weight: bold;',\n reactive: 'background: #007acc; color: #fff; padding: 2px 6px; border-radius: 4px; font-weight: bold;'\n}\nlet currentTransaction: TransactionContext | null = null\nfunction safeValueToString(value: unknown): string {\n if (value === null) return 'null'\n if (value === undefined) return 'undefined'\n if (typeof value === 'object') {\n try {\n return JSON.stringify(value)\n } catch (e) {\n return '[Cyclic Object or Layer]'\n }\n }\n return String(value)\n}\nexport function queueLog(type: LogEventType, label: string, details?: { from?: unknown; to?: unknown; payload?: unknown }): void {\n if (!currentTransaction) {\n currentTransaction = { id: Math.random().toString(36).substring(2, 9), pendingLogQueue: [], isFlushing: false }\n queueMicrotask(() => flushLogs())\n }\n currentTransaction.pendingLogQueue.push({ type, label, from: details?.from, to: details?.to, payload: details?.payload, timestamp: Date.now() })\n}\nexport function flushLogs(): void {\n if (!currentTransaction || currentTransaction.isFlushing) return\n currentTransaction.isFlushing = true\n const queue = currentTransaction.pendingLogQueue\n if (queue.length === 0) {\n currentTransaction = null\n return\n }\n console.groupCollapsed(`%cREACTIVE TRANSACTION%c [id: ${currentTransaction.id}] (${queue.length} operations)`, 'background: #7952b3; color: #fff; padding: 2px 6px; border-radius: 4px; font-weight: bold;', 'color: #888; font-weight: normal;')\n for (const record of queue) {\n const colorStyle = badgeColors[record.type]\n const hasTransition = record.from !== undefined || record.to !== undefined\n let logMessage = `%c${record.type.toUpperCase()}%c ${record.label}`\n\n if (hasTransition) {\n if (!!record.from)\n logMessage += ` ${safeValueToString(record.from)} → ${safeValueToString(record.to)}`\n else logMessage += ` (${safeValueToString(record.to)})`\n }\n\n if (record.payload !== undefined) {\n console.groupCollapsed(logMessage, colorStyle, 'color: inherit;')\n console.log('Payload:', record.payload)\n console.groupEnd()\n } else {\n console.log(logMessage, colorStyle, 'color: inherit;')\n }\n }\n console.groupEnd()\n currentTransaction = null\n}\nexport class ReactiveEngineCore {\n protected frameworkPrefix = 'core'\n private logger: EngineLoggerOptions\n public epoch = 0\n public activeConsumer: any = null\n public batchDepth = 0\n public subscriberId = 0\n public pendingEffects: Array<Set<any> | undefined> = []\n public maxPendingDepth = 0\n public computedCache = new WeakMap<Function, any>()\n private diRegistry = new Map<unknown, unknown>()\n private diCache = new Map<unknown, unknown>()\n private proxyCache = new WeakMap<object, any>()\n private proxyTargets = new WeakSet<object>()\n private reactiveSignals = new WeakMap<object, Map<string | symbol, any>>()\n private cycleDetectionStack = new Set<unknown>()\n public batchedSignals = new Set<any>()\n public activeOwner: any = null\n // Системная очередь для отложенного батчинга деструкторов\n public pendingCleanups = new Set<() => void>()\n\n // Метод для регистрации отложенной очистки\n public queueCleanup(cleanup: () => void): void {\n this.pendingCleanups.add(cleanup)\n }\n\n constructor(options?: { logger?: EngineLoggerOptions }) {\n this.logger = options?.logger || { isEnabled: false }\n }\n\n public scheduleEffect(effect: any): void {\n const depth = effect.depth || 0\n if (!this.pendingEffects[depth]) {\n this.pendingEffects[depth] = new Set()\n }\n this.pendingEffects[depth]!.add(effect)\n if (depth > this.maxPendingDepth) {\n this.maxPendingDepth = depth\n }\n }\n\n public queueLog(type: LogEventType, label: string, details?: { from?: unknown; to?: unknown; payload?: unknown }): void {\n queueLog(type, label, details)\n }\n\n public batch<T>(fn: () => T): T {\n this.batchDepth++\n try {\n return fn()\n } finally {\n this.batchDepth--\n if (this.batchDepth === 0) {\n const signalsToFlush = Array.from(this.batchedSignals)\n this.batchedSignals.clear()\n\n signalsToFlush.forEach(sig => {\n if (sig._flushBatch) sig._flushBatch()\n })\n\n this.flushEffects()\n }\n }\n }\n\n public flushEffects(): void {\n // Если мы еще внутри батча — откладываем выполнение\n if (this.batchDepth > 0) return\n\n const prevConsumer = this.activeConsumer\n\n try {\n // Итерируемся по уровням глубины от 0 до maxPendingDepth\n for (let depth = 0; depth <= this.maxPendingDepth; depth++) {\n const bucket = this.pendingEffects[depth]\n\n // Если на текущей глубине нет запланированных эффектов, идем дальше\n if (!bucket || bucket.size === 0) continue\n\n // Извлекаем эффекты текущего уровня и сразу очищаем корзину\n const effects = Array.from(bucket)\n bucket.clear()\n\n for (const effect of effects) {\n if (effect.isDisposed) continue\n\n // Pull-валидация версий родителей перед запуском эффекта\n if (effect.dependencies && effect.dependencies.size > 0) {\n let parentChanged = false\n for (const dep of effect.dependencies) {\n const rawNode = dep._node || dep\n if (rawNode.type === 'computed' && rawNode.state > 0) {\n if (rawNode.update) rawNode.update()\n }\n if (effect.depVersions && effect.depVersions.get(dep) !== rawNode.version) {\n parentChanged = true\n }\n }\n if (!parentChanged && effect.dependencies.size > 0) {\n effect.isDirty = false\n continue\n }\n }\n\n if (!effect.isDirty) continue\n\n try {\n effect.run()\n } catch (err) {\n throw err\n }\n }\n\n // Если в процессе выполнения текущего уровня были добавлены новые эффекты\n // на этот же или более верхний уровень, сбрасываем указатель цикла,\n // чтобы гарантировать топологическую строгость.\n if (depth > 0) {\n let hasEarlierEffects = false\n for (let i = 0; i < depth; i++) {\n if (this.pendingEffects[i] && this.pendingEffects[i]!.size > 0) {\n hasEarlierEffects = true\n break\n }\n }\n if (hasEarlierEffects) {\n depth = -1 // Перезапустит цикл с 0 (учитывая depth++ в конце итерации)\n }\n }\n }\n\n // Полностью сбрасываем трекер максимальной глубины после завершения всех эффектов\n this.maxPendingDepth = 0\n\n } finally {\n this.activeConsumer = prevConsumer\n }\n }\n\n // public batch<T>(fn: () => T): T {\n // return executeBatch<T>(this, fn)\n // }\n\n private log ({ type, label, details, isInternalCoreSignal = false }: { type: LogEventType, label: string, details?: { from?: unknown; to?: unknown; payload?: unknown }, isInternalCoreSignal?: boolean }) {\n ReactiveDebounceLogger.processLog(this.logger, queueLog, {\n type,\n label,\n details,\n isInternalCoreSignal\n })\n }\n\n public signal<T>(initialValue: T, optionsOrName?: string | SignalOptions<T>): Signal<T> {\n return createSignal<T>(this, initialValue, optionsOrName)\n }\n\n public computed<T>(fn: () => T, signalName?: string): Computed<T> {\n // Просто делегируем вызов строго изолированной чистой функции\n return createComputed<T>(this, fn, signalName)\n }\n\n public effect(fn: () => void | CleanupFn, effectName?: string): () => void {\n return createEffect(this, fn, effectName)\n }\n\n public untrack<T>(fn: () => T): T {\n return executeUntrack<T>(this, fn)\n }\n\n public reactive<T extends object>(target: T, name?: string): T {\n return createReactive<T>(this, target, name)\n }\n\n public provide<T>(token: InjectionToken<T>, valueOrFactory: T | Factory<T>): void {\n this.diRegistry.set(token, valueOrFactory)\n this.diCache.delete(token)\n }\n\n public inject<T>(token: InjectionToken<T>): T {\n if (token === undefined || token === null) throw new Error('[DI Error] Token is empty')\n if (this.diCache.has(token)) return this.diCache.get(token) as T\n if (this.cycleDetectionStack.has(token)) throw new Error('[DI Error] Cyclic dependency detected')\n this.cycleDetectionStack.add(token)\n try {\n if (this.diRegistry.has(token)) {\n const entry = this.diRegistry.get(token)\n if (typeof entry === 'function') {\n if ((entry as any)._isMockFunction) {\n const mockRes = (entry as Function)(this)\n if (mockRes !== undefined) {\n this.diCache.set(token, mockRes)\n return mockRes as T\n }\n return entry as unknown as T\n }\n const str = entry.toString()\n const isClass = str.startsWith('class ') || str.startsWith('class{') || (entry.prototype && entry.prototype.constructor === entry && !str.startsWith('function') && !str.includes('=>'))\n if (!isClass) {\n const resolved = (entry as Factory<T>)(this)\n this.diCache.set(token, resolved)\n return resolved\n }\n return entry as unknown as T\n }\n return entry as T\n }\n if (typeof token === 'function') {\n const resolved = new (token as Constructor<T>)(this)\n this.diCache.set(token, resolved)\n return resolved\n }\n throw new Error('[DI Error] Token not found')\n } finally {\n this.cycleDetectionStack.delete(token)\n }\n }\n\n private delay(ms: number, signal: AbortSignal): Promise<void> {\n return new Promise((resolve, reject) => {\n if (signal.aborted) {\n return reject(new DOMException('Aborted', 'AbortError'))\n }\n\n const timeoutId = setTimeout(() => {\n signal.removeEventListener('abort', onAbort)\n resolve()\n }, ms)\n\n const onAbort = () => {\n clearTimeout(timeoutId)\n reject(new DOMException('Aborted', 'AbortError'))\n }\n\n signal.addEventListener('abort', onAbort, { once: true })\n })\n }\n\n public resource<T, S = void>(\n fetcher: (source: S, signal: AbortSignal) => Promise<T>,\n source?: { value: S },\n optionsOrName?: string | ResourceOptions<T, S>,\n ): Resource<T> {\n const isOptionsObject = optionsOrName && typeof optionsOrName === 'object'\n const resourceSignalName = isOptionsObject\n ? ((optionsOrName as ResourceOptions<T, S>).name || 'unnamed_resource')\n : (optionsOrName as string) || 'unnamed_resource'\n\n const options: Partial<ResourceOptions<T, S>> = isOptionsObject\n ? (optionsOrName as ResourceOptions<T, S>)\n : {}\n\n const resetDataOnSourceChange = options.resetDataOnSourceChange ?? true\n const responseValidate = options.responseValidate\n const validateBeforeFetch = options.validateBeforeFetch\n const retryCount = 0\n const baseDelay = 1000\n const useExponential = true\n const maxRetryDelay = 1000 * 60 * 5\n const timeoutMs = 1000\n const state = this.signal<ResourceState<T>>(\n { data: null, loading: true, error: null, isRetrying: false },\n `[CORE_INTERNAL_SIGNAL=1]:resource:state:${resourceSignalName}`\n )\n\n const updateResourceState = (nextState: ResourceState<T>) => {\n this.log({ type: 'resource', label: resourceSignalName, details: { to: nextState, from: state.value } })\n state.value = nextState\n }\n\n const load = async (sValue: S, effectSignal: AbortSignal, isSourceChange = false) => {\n if (effectSignal.aborted) return\n const isValid = options.validateBeforeFetch ? options.validateBeforeFetch(sValue) : true\n\n /**\n * 🧐 WIP_CORE: Есть два пути, ни один не будет ошибкой, если разкомментировать код ниже. Чуть бозже добавлю опци для более тонкой отладки ядра.\n *\n * - АКТИВНО: Разделяем мирную блокировку (false) и боевую ошибку (string): работать будет идеально, но без логов, связанных с пре-валидацией\n * - НЕАКТИВНО: Более очевидное логирование процессов пре-валидации (выставление ошибок и мониторинг разработчиком)\n */\n // --\n // if (isValid === false) {\n // // Если валидатор вернул строго false — мы тихо блокируем старт фетчера,\n // // переводя ресурс в состояние ПОКОЯ (loading: false, error: null).\n // // Это полностью ликвидирует генерацию ложных ошибок при монтировании!\n // state.value = {\n // loading: false,\n // data: null,\n // error: null, // Ошибки нет! Стейт стабилен.\n // isRetrying: false\n // }\n // return\n // }\n // if (typeof isValid === 'string') {\n // // Если валидатор вернул строку — это боевая декларативная ошибка валидации формы.\n // // Здесь мы честно переводим ресурс в стейт ошибки, как и требовалось ранее.\n // state.value = {\n // loading: false,\n // data: null,\n // error: 'Core internal stopper',\n // isRetrying: false\n // }\n // return\n // }\n // --\n if (validateBeforeFetch) {\n const preValidationResult = validateBeforeFetch(sValue)\n if (preValidationResult === false || typeof preValidationResult === 'string') {\n if (effectSignal.aborted) return\n const errorMsg = typeof preValidationResult === 'string'\n ? preValidationResult\n : 'Pre-fetch validation failed for resource'\n\n const currentData = isSourceChange ? null : this.untrack(() => state.value.data)\n updateResourceState({ data: currentData, loading: false, error: errorMsg, isRetrying: false })\n return\n }\n }\n const shouldClear = isSourceChange && resetDataOnSourceChange\n const currentData = shouldClear ? null : this.untrack(() => state.value.data)\n updateResourceState({ data: currentData, loading: true, error: null, isRetrying: false })\n for (let attempt = 0; attempt <= retryCount; attempt++) {\n if (effectSignal.aborted) return\n let combinedSignal = effectSignal\n try {\n const data = await fetcher(sValue, combinedSignal)\n if (effectSignal.aborted) return\n if (combinedSignal.aborted) {\n throw new DOMException('The operation timed out.', 'TimeoutError')\n }\n if (responseValidate) {\n const validationResult = responseValidate(data)\n if (validationResult === false || typeof validationResult === 'string') {\n if (effectSignal.aborted) return\n const errorMsg = typeof validationResult === 'string' ? validationResult : 'Validation failed'\n updateResourceState({ data: null, loading: false, error: errorMsg, isRetrying: false })\n return\n }\n }\n if (effectSignal.aborted) return\n updateResourceState({ data, loading: false, error: null, isRetrying: false })\n return\n } catch (e: unknown) {\n if (effectSignal.aborted || ((e as Error).name === 'AbortError' && effectSignal.aborted)) return\n const isTimeout = (e as Error).name === 'TimeoutError' || (e as Error).name === 'AbortError' || (e as Error).message?.includes('timeout')\n const isCustomValidationError = getExtractedValues({\n tested: [(e as Error).message], expectedKey: 'THROW_CUSTOM_VALIDATION_ERROR_NO_RETRY', valueType: 'number',\n })?.[0] === '1' || false\n const __defaultCustomValidationErrorMessage = 'Custom validation error'\n let customValidationErrorMessage: string = isCustomValidationError\n ? (getExtractedValues({\n tested: [(e as Error).message], expectedKey: 'MESSAGE', valueType: 'string',\n })?.[0] || __defaultCustomValidationErrorMessage)\n : __defaultCustomValidationErrorMessage\n const isFetchBodyValidationError = isCustomValidationError || (e as Error).name === 'ValidationError'\n if (attempt === retryCount || isFetchBodyValidationError) {\n if (effectSignal.aborted) return\n const finalError = isTimeout\n ? new Error(`Request timed out after ${timeoutMs}ms`, { cause: e })\n : isCustomValidationError\n ? new Error(customValidationErrorMessage, { cause: e })\n : e\n\n updateResourceState({\n data: null, loading: false,\n error: finalError instanceof Error ? finalError.message : typeof finalError === 'string' ? finalError : `typeof finalError is ${typeof finalError}`,\n isRetrying: false,\n })\n return\n } else {\n if (effectSignal.aborted) return\n let currentDelay = useExponential ? baseDelay * Math.pow(2, attempt) : baseDelay\n currentDelay = Math.min(currentDelay, maxRetryDelay)\n const jitter = Math.random() * 200\n currentDelay = currentDelay + jitter\n updateResourceState({ data: state.value.data, loading: true, error: null, isRetrying: true })\n const logReason = isTimeout ? 'таймауту' : 'ошибке сети'\n console.warn(`[Resource Retry] \"${resourceSignalName}\" сбой по ${logReason}. Попытка ${attempt + 1}/${retryCount > 0 ? retryCount + 1 : attempt + 1}...`)\n\n try {\n await this.delay(currentDelay, effectSignal)\n if (effectSignal.aborted) return\n } catch (delayError) {\n return\n }\n }\n }\n }\n }\n\n let activeEffectController: AbortController | null = null\n\n this.effect(() => {\n const sValue = source ? source.value : undefined as S\n const effectController = new AbortController()\n activeEffectController = effectController\n\n this.untrack(() => {\n load(sValue as S, effectController.signal, true)\n })\n\n return () => effectController.abort()\n }, '[CORE_INTERNAL_SIGNAL=1]:effect')\n\n return {\n get data() { return state.value.data },\n get loading() { return state.value.loading },\n get error() { return state.value.error },\n get isRetrying() { return state.value.isRetrying },\n get value() { return state.value },\n refetch: () => {\n activeEffectController?.abort()\n activeEffectController = new AbortController()\n load(source ? source.value : undefined as S, activeEffectController.signal, false)\n },\n subscribe: (cb: (val: ResourceState<T>) => void) => state.subscribe(cb)\n }\n }\n}\n\nexport { ReactiveEngineCore as ReactiveEngine, ReactiveEngineCore as ReactiveEngineAutomatic }\n"],"mappings":"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"}
1
+ {"version":3,"file":"core.cjs","names":[],"sources":["../src/core/core.ts"],"sourcesContent":["import { getExtractedValues } from '../utils/getExtractedValues'\nimport { Signal, Computed, IEffect, EngineLoggerOptions, LogEventType, CleanupFn, TransactionContext, LogRecord, SignalOptions, ResourceOptions, ResourceState, Resource } from './types'\nimport { createComputed } from './core.method.computed'\nimport { createSignal } from './core.method.signal'\n// import { executeBatch } from './core.method.batch'\nimport { executeUntrack } from './core.method.untrack'\nimport { createReactive } from './core.method.reactive'\nimport { createEffect } from './core.method.effect'\nimport { ReactiveDebounceLogger } from './core.logger'\n\n// Тип для конструктора класса\ntype Constructor<T> = new (...args: any[]) => T\n// Тип для фабричной функции зависимостей\ntype Factory<T> = (engine: any) => T\n// Универсальный тип токена DI\ntype InjectionToken<T> = Constructor<T> | Factory<T> | symbol | string\n\nconst badgeColors: Record<LogEventType, string> = {\n signal: 'background: #007acc; color: #fff; padding: 2px 6px; border-radius: 4px; font-weight: bold;',\n computed: 'background: #42b883; color: #fff; padding: 2px 6px; border-radius: 4px; font-weight: bold;',\n effect: 'background: #e01e5a; color: #fff; padding: 2px 6px; border-radius: 4px; font-weight: bold;',\n batch: 'background: #7952b3; color: #fff; padding: 2px 6px; border-radius: 4px; font-weight: bold;',\n resource: 'background: #d97706; color: #fff; padding: 2px 6px; border-radius: 4px; font-weight: bold;',\n reactive: 'background: #007acc; color: #fff; padding: 2px 6px; border-radius: 4px; font-weight: bold;'\n}\nlet currentTransaction: TransactionContext | null = null\nfunction safeValueToString(value: unknown): string {\n if (value === null) return 'null'\n if (value === undefined) return 'undefined'\n if (typeof value === 'object') {\n try {\n return JSON.stringify(value)\n } catch (e) {\n return '[Cyclic Object or Layer]'\n }\n }\n return String(value)\n}\nexport function queueLog(type: LogEventType, label: string, details?: { from?: unknown; to?: unknown; payload?: unknown }): void {\n if (!currentTransaction) {\n currentTransaction = { id: Math.random().toString(36).substring(2, 9), pendingLogQueue: [], isFlushing: false }\n queueMicrotask(() => flushLogs())\n }\n currentTransaction.pendingLogQueue.push({ type, label, from: details?.from, to: details?.to, payload: details?.payload, timestamp: Date.now() })\n}\nexport function flushLogs(): void {\n if (!currentTransaction || currentTransaction.isFlushing) return\n currentTransaction.isFlushing = true\n const queue = currentTransaction.pendingLogQueue\n if (queue.length === 0) {\n currentTransaction = null\n return\n }\n console.groupCollapsed(`%cREACTIVE TRANSACTION%c [id: ${currentTransaction.id}] (${queue.length} operations)`, 'background: #7952b3; color: #fff; padding: 2px 6px; border-radius: 4px; font-weight: bold;', 'color: #888; font-weight: normal;')\n for (const record of queue) {\n const colorStyle = badgeColors[record.type]\n const hasTransition = record.from !== undefined || record.to !== undefined\n let logMessage = `%c${record.type.toUpperCase()}%c ${record.label}`\n\n if (hasTransition) {\n if (!!record.from)\n logMessage += ` ${safeValueToString(record.from)} → ${safeValueToString(record.to)}`\n else logMessage += ` (${safeValueToString(record.to)})`\n }\n\n if (record.payload !== undefined) {\n console.groupCollapsed(logMessage, colorStyle, 'color: inherit;')\n console.log('Payload:', record.payload)\n console.groupEnd()\n } else {\n console.log(logMessage, colorStyle, 'color: inherit;')\n }\n }\n console.groupEnd()\n currentTransaction = null\n}\nexport class ReactiveEngineCore {\n protected frameworkPrefix = 'core'\n private logger: EngineLoggerOptions\n public epoch = 0\n public activeConsumer: any = null\n public batchDepth = 0\n public subscriberId = 0\n public pendingEffects: Array<Set<any> | undefined> = []\n public maxPendingDepth = 0\n public computedCache = new WeakMap<Function, any>()\n private diRegistry = new Map<unknown, unknown>()\n private diCache = new Map<unknown, unknown>()\n private proxyCache = new WeakMap<object, any>()\n private proxyTargets = new WeakSet<object>()\n private reactiveSignals = new WeakMap<object, Map<string | symbol, any>>()\n private cycleDetectionStack = new Set<unknown>()\n public batchedSignals = new Set<any>()\n public activeOwner: any = null\n // Системная очередь для отложенного батчинга деструкторов\n public pendingCleanups = new Set<() => void>()\n\n // Метод для регистрации отложенной очистки\n public queueCleanup(cleanup: () => void): void {\n this.pendingCleanups.add(cleanup)\n }\n\n constructor(options?: { logger?: EngineLoggerOptions }) {\n this.logger = options?.logger || { isEnabled: false }\n }\n\n public scheduleEffect(effect: any): void {\n const depth = effect.depth || 0\n if (!this.pendingEffects[depth]) {\n this.pendingEffects[depth] = new Set()\n }\n this.pendingEffects[depth]!.add(effect)\n if (depth > this.maxPendingDepth) {\n this.maxPendingDepth = depth\n }\n }\n\n public queueLog(type: LogEventType, label: string, details?: { from?: unknown; to?: unknown; payload?: unknown }): void {\n queueLog(type, label, details)\n }\n\n public batch<T>(fn: () => T): T {\n this.batchDepth++\n try {\n return fn()\n } finally {\n this.batchDepth--\n if (this.batchDepth === 0) {\n const signalsToFlush = Array.from(this.batchedSignals)\n this.batchedSignals.clear()\n\n signalsToFlush.forEach(sig => {\n if (sig._flushBatch) sig._flushBatch()\n })\n\n this.flushEffects()\n }\n }\n }\n\n public flushEffects(): void {\n // Если мы еще внутри батча — откладываем выполнение\n if (this.batchDepth > 0) return\n\n const prevConsumer = this.activeConsumer\n\n try {\n // Итерируемся по уровням глубины от 0 до maxPendingDepth\n for (let depth = 0; depth <= this.maxPendingDepth; depth++) {\n const bucket = this.pendingEffects[depth]\n\n // Если на текущей глубине нет запланированных эффектов, идем дальше\n if (!bucket || bucket.size === 0) continue\n\n // Извлекаем эффекты текущего уровня и сразу очищаем корзину\n const effects = Array.from(bucket)\n bucket.clear()\n\n for (const effect of effects) {\n if (effect.isDisposed) continue\n\n // Pull-валидация версий родителей перед запуском эффекта\n if (effect.dependencies && effect.dependencies.size > 0) {\n let parentChanged = false\n for (const dep of effect.dependencies) {\n const rawNode = dep._node || dep\n if (rawNode.type === 'computed' && rawNode.state > 0) {\n if (rawNode.update) rawNode.update()\n }\n if (effect.depVersions && effect.depVersions.get(dep) !== rawNode.version) {\n parentChanged = true\n }\n }\n if (!parentChanged && effect.dependencies.size > 0) {\n effect.isDirty = false\n continue\n }\n }\n\n if (!effect.isDirty) continue\n\n try {\n effect.run()\n } catch (err) {\n throw err\n }\n }\n\n // Если в процессе выполнения текущего уровня были добавлены новые эффекты\n // на этот же или более верхний уровень, сбрасываем указатель цикла,\n // чтобы гарантировать топологическую строгость.\n if (depth > 0) {\n let hasEarlierEffects = false\n for (let i = 0; i < depth; i++) {\n if (this.pendingEffects[i] && this.pendingEffects[i]!.size > 0) {\n hasEarlierEffects = true\n break\n }\n }\n if (hasEarlierEffects) {\n depth = -1 // Перезапустит цикл с 0 (учитывая depth++ в конце итерации)\n }\n }\n }\n\n // Полностью сбрасываем трекер максимальной глубины после завершения всех эффектов\n this.maxPendingDepth = 0\n\n } finally {\n this.activeConsumer = prevConsumer\n }\n }\n\n // public batch<T>(fn: () => T): T {\n // return executeBatch<T>(this, fn)\n // }\n\n private log (params: any) {\n if (!this.logger || !this.logger.isEnabled) return\n\n ReactiveDebounceLogger.processLog(this.logger, queueLog, params)\n }\n\n public signal<T>(initialValue: T, optionsOrName?: string | SignalOptions<T>): Signal<T> {\n return createSignal<T>(this, initialValue, optionsOrName)\n }\n\n public computed<T>(fn: () => T, signalName?: string): Computed<T> {\n // Просто делегируем вызов строго изолированной чистой функции\n return createComputed<T>(this, fn, signalName)\n }\n\n public effect(fn: () => void | CleanupFn, effectName?: string): () => void {\n return createEffect(this, fn, effectName)\n }\n\n public untrack<T>(fn: () => T): T {\n return executeUntrack<T>(this, fn)\n }\n\n public reactive<T extends object>(target: T, name?: string): T {\n return createReactive<T>(this, target, name)\n }\n\n public provide<T>(token: InjectionToken<T>, valueOrFactory: T | Factory<T>): void {\n this.diRegistry.set(token, valueOrFactory)\n this.diCache.delete(token)\n }\n\n public inject<T>(token: InjectionToken<T>): T {\n if (token === undefined || token === null) throw new Error('[DI Error] Token is empty')\n if (this.diCache.has(token)) return this.diCache.get(token) as T\n if (this.cycleDetectionStack.has(token)) throw new Error('[DI Error] Cyclic dependency detected')\n this.cycleDetectionStack.add(token)\n try {\n if (this.diRegistry.has(token)) {\n const entry = this.diRegistry.get(token)\n if (typeof entry === 'function') {\n if ((entry as any)._isMockFunction) {\n const mockRes = (entry as Function)(this)\n if (mockRes !== undefined) {\n this.diCache.set(token, mockRes)\n return mockRes as T\n }\n return entry as unknown as T\n }\n const str = entry.toString()\n const isClass = str.startsWith('class ') || str.startsWith('class{') || (entry.prototype && entry.prototype.constructor === entry && !str.startsWith('function') && !str.includes('=>'))\n if (!isClass) {\n const resolved = (entry as Factory<T>)(this)\n this.diCache.set(token, resolved)\n return resolved\n }\n return entry as unknown as T\n }\n return entry as T\n }\n if (typeof token === 'function') {\n const resolved = new (token as Constructor<T>)(this)\n this.diCache.set(token, resolved)\n return resolved\n }\n throw new Error('[DI Error] Token not found')\n } finally {\n this.cycleDetectionStack.delete(token)\n }\n }\n\n private delay(ms: number, signal: AbortSignal): Promise<void> {\n return new Promise((resolve, reject) => {\n if (signal.aborted) {\n return reject(new DOMException('Aborted', 'AbortError'))\n }\n\n const timeoutId = setTimeout(() => {\n signal.removeEventListener('abort', onAbort)\n resolve()\n }, ms)\n\n const onAbort = () => {\n clearTimeout(timeoutId)\n reject(new DOMException('Aborted', 'AbortError'))\n }\n\n signal.addEventListener('abort', onAbort, { once: true })\n })\n }\n\n public resource<T, S = void>(\n fetcher: (source: S, signal: AbortSignal) => Promise<T>,\n source?: { value: S },\n optionsOrName?: string | ResourceOptions<T, S>,\n ): Resource<T> {\n const isOptionsObject = optionsOrName && typeof optionsOrName === 'object'\n const resourceSignalName = isOptionsObject\n ? ((optionsOrName as ResourceOptions<T, S>).name || 'unnamed_resource')\n : (optionsOrName as string) || 'unnamed_resource'\n\n const options: Partial<ResourceOptions<T, S>> = isOptionsObject\n ? (optionsOrName as ResourceOptions<T, S>)\n : {}\n\n const resetDataOnSourceChange = options.resetDataOnSourceChange ?? true\n const responseValidate = options.responseValidate\n const validateBeforeFetch = options.validateBeforeFetch\n const retryCount = 0\n const baseDelay = 1000\n const useExponential = true\n const maxRetryDelay = 1000 * 60 * 5\n const timeoutMs = 1000\n const state = this.signal<ResourceState<T>>(\n { data: null, loading: true, error: null, isRetrying: false },\n `[CORE_INTERNAL_SIGNAL=1]:resource:state:${resourceSignalName}`\n )\n\n const updateResourceState = (nextState: ResourceState<T>) => {\n this.log({ type: 'resource', label: resourceSignalName, details: { to: nextState, from: state.value } })\n state.value = nextState\n }\n\n const load = async (sValue: S, effectSignal: AbortSignal, isSourceChange = false) => {\n if (effectSignal.aborted) return\n const isValid = options.validateBeforeFetch ? options.validateBeforeFetch(sValue) : true\n\n /**\n * 🧐 WIP_CORE: Есть два пути, ни один не будет ошибкой, если разкомментировать код ниже. Чуть бозже добавлю опци для более тонкой отладки ядра.\n *\n * - АКТИВНО: Разделяем мирную блокировку (false) и боевую ошибку (string): работать будет идеально, но без логов, связанных с пре-валидацией\n * - НЕАКТИВНО: Более очевидное логирование процессов пре-валидации (выставление ошибок и мониторинг разработчиком)\n */\n // --\n // if (isValid === false) {\n // // Если валидатор вернул строго false — мы тихо блокируем старт фетчера,\n // // переводя ресурс в состояние ПОКОЯ (loading: false, error: null).\n // // Это полностью ликвидирует генерацию ложных ошибок при монтировании!\n // state.value = {\n // loading: false,\n // data: null,\n // error: null, // Ошибки нет! Стейт стабилен.\n // isRetrying: false\n // }\n // return\n // }\n // if (typeof isValid === 'string') {\n // // Если валидатор вернул строку — это боевая декларативная ошибка валидации формы.\n // // Здесь мы честно переводим ресурс в стейт ошибки, как и требовалось ранее.\n // state.value = {\n // loading: false,\n // data: null,\n // error: 'Core internal stopper',\n // isRetrying: false\n // }\n // return\n // }\n // --\n if (validateBeforeFetch) {\n const preValidationResult = validateBeforeFetch(sValue)\n if (preValidationResult === false || typeof preValidationResult === 'string') {\n if (effectSignal.aborted) return\n const errorMsg = typeof preValidationResult === 'string'\n ? preValidationResult\n : 'Pre-fetch validation failed for resource'\n\n const currentData = isSourceChange ? null : this.untrack(() => state.value.data)\n updateResourceState({ data: currentData, loading: false, error: errorMsg, isRetrying: false })\n return\n }\n }\n const shouldClear = isSourceChange && resetDataOnSourceChange\n const currentData = shouldClear ? null : this.untrack(() => state.value.data)\n updateResourceState({ data: currentData, loading: true, error: null, isRetrying: false })\n for (let attempt = 0; attempt <= retryCount; attempt++) {\n if (effectSignal.aborted) return\n let combinedSignal = effectSignal\n try {\n const data = await fetcher(sValue, combinedSignal)\n if (effectSignal.aborted) return\n if (combinedSignal.aborted) {\n throw new DOMException('The operation timed out.', 'TimeoutError')\n }\n if (responseValidate) {\n const validationResult = responseValidate(data)\n if (validationResult === false || typeof validationResult === 'string') {\n if (effectSignal.aborted) return\n const errorMsg = typeof validationResult === 'string' ? validationResult : 'Validation failed'\n updateResourceState({ data: null, loading: false, error: errorMsg, isRetrying: false })\n return\n }\n }\n if (effectSignal.aborted) return\n updateResourceState({ data, loading: false, error: null, isRetrying: false })\n return\n } catch (e: unknown) {\n if (effectSignal.aborted || ((e as Error).name === 'AbortError' && effectSignal.aborted)) return\n const isTimeout = (e as Error).name === 'TimeoutError' || (e as Error).name === 'AbortError' || (e as Error).message?.includes('timeout')\n const isCustomValidationError = getExtractedValues({\n tested: [(e as Error).message], expectedKey: 'THROW_CUSTOM_VALIDATION_ERROR_NO_RETRY', valueType: 'number',\n })?.[0] === '1' || false\n const __defaultCustomValidationErrorMessage = 'Custom validation error'\n let customValidationErrorMessage: string = isCustomValidationError\n ? (getExtractedValues({\n tested: [(e as Error).message], expectedKey: 'MESSAGE', valueType: 'string',\n })?.[0] || __defaultCustomValidationErrorMessage)\n : __defaultCustomValidationErrorMessage\n const isFetchBodyValidationError = isCustomValidationError || (e as Error).name === 'ValidationError'\n if (attempt === retryCount || isFetchBodyValidationError) {\n if (effectSignal.aborted) return\n const finalError = isTimeout\n ? new Error(`Request timed out after ${timeoutMs}ms`, { cause: e })\n : isCustomValidationError\n ? new Error(customValidationErrorMessage, { cause: e })\n : e\n\n updateResourceState({\n data: null, loading: false,\n error: finalError instanceof Error ? finalError.message : typeof finalError === 'string' ? finalError : `typeof finalError is ${typeof finalError}`,\n isRetrying: false,\n })\n return\n } else {\n if (effectSignal.aborted) return\n let currentDelay = useExponential ? baseDelay * Math.pow(2, attempt) : baseDelay\n currentDelay = Math.min(currentDelay, maxRetryDelay)\n const jitter = Math.random() * 200\n currentDelay = currentDelay + jitter\n updateResourceState({ data: state.value.data, loading: true, error: null, isRetrying: true })\n const logReason = isTimeout ? 'таймауту' : 'ошибке сети'\n console.warn(`[Resource Retry] \"${resourceSignalName}\" сбой по ${logReason}. Попытка ${attempt + 1}/${retryCount > 0 ? retryCount + 1 : attempt + 1}...`)\n\n try {\n await this.delay(currentDelay, effectSignal)\n if (effectSignal.aborted) return\n } catch (delayError) {\n return\n }\n }\n }\n }\n }\n\n let activeEffectController: AbortController | null = null\n\n this.effect(() => {\n const sValue = source ? source.value : undefined as S\n const effectController = new AbortController()\n activeEffectController = effectController\n\n this.untrack(() => {\n load(sValue as S, effectController.signal, true)\n })\n\n return () => effectController.abort()\n }, '[CORE_INTERNAL_SIGNAL=1]:effect')\n\n return {\n get data() { return state.value.data },\n get loading() { return state.value.loading },\n get error() { return state.value.error },\n get isRetrying() { return state.value.isRetrying },\n get value() { return state.value },\n refetch: () => {\n activeEffectController?.abort()\n activeEffectController = new AbortController()\n load(source ? source.value : undefined as S, activeEffectController.signal, false)\n },\n subscribe: (cb: (val: ResourceState<T>) => void) => state.subscribe(cb)\n }\n }\n}\n\nexport { ReactiveEngineCore as ReactiveEngine, ReactiveEngineCore as ReactiveEngineAutomatic }\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- function e(e,t,n){let r=e.computedCache.get(t)?.deref();if(r)return r;let i,a=!0,o=0,s=!1,c=-1,l=2,u=new Set,d=new Map,f=new Set,p=e=>{if(!e)return;let t=e._node||e;if(t.dependencies&&t.dependencies.size>0){let n=Array.from(t.dependencies);t.dependencies.clear(),t.depVersions&&t.depVersions.clear(),n.forEach(n=>{let r=n._node||n;r.subscribers&&(r.subscribers.delete(t),r.subscribers.delete(e),r.subscribers.delete(g),r.type===`computed`&&r.subscribers.size===0&&p(r))})}},m=new class extends Set{delete(n){let r=super.delete(n);return this.size===0&&(l=2,a=!0,s=!1,p(g),e.computedCache.delete(t)),r}},h=e=>{if(!s||e.state===2)return e.run();if(e.state===1){let t=!1;for(let n of Array.from(e.dependencies||[])){let r=n._node||n;t||(r.type===`computed`&&r.state>0&&h(r),e.depVersions.get(n)!==r.version&&(t=!0))}return e.state=0,t||a?e.run():!1}return!1},g={id:e.subscriberId++,dependencies:u,subscribers:m,ownedEffects:f,depth:1,type:`computed`,fn:t,get version(){return o},get state(){return l},set state(e){l=e},get depVersions(){return d},update:()=>h(g),run:()=>{if(c===e.epoch&&s)return!1;if(c=e.epoch,e.cycleDetectionStack.has(g))throw Error(`[Graph Error] Cyclic dependency detected`);e.cycleDetectionStack.add(g);let r=e.activeConsumer,p=e.activeOwner;e.activeConsumer=g,e.activeOwner=g;let h=new Set(u);u.clear();try{f&&(f.forEach(e=>{e&&typeof e.dispose==`function`&&e.dispose()}),f.clear());let r=t();h.forEach(e=>{if(!u.has(e)){let t=e._node||e;t.subscribers&&t.subscribers.delete(g),d.delete(e)}});let c=a||!Object.is(i,r);if(c){let t=a?void 0:typeof i==`object`&&i?JSON.parse(JSON.stringify(i)):i;i=r,o++,e.log&&n&&e.log({type:`computed`,label:n,details:{from:t,to:r}}),m.forEach(t=>{let n=t._node||t;n.type===`effect`?(n.state=2,n.isDirty=!0,e.scheduleEffect(t)):n.markDirty&&n.markDirty(1)})}a=!1,l=0,s=!0;let p=0;return u.forEach(e=>{let t=e._node||e;d.set(e,t.version),t.subscribers&&t.subscribers.add(g),t.depth!==void 0&&t.depth>p&&(p=t.depth)}),m.forEach(t=>{let n=t._node||t;n.type===`effect`?(n.state=2,n.isDirty=!0,e.scheduleEffect(t)):n.markDirty&&n.markDirty(1)}),g.depth=p+1,c}finally{e.activeConsumer=r,e.activeOwner=p,e.cycleDetectionStack.delete(g)}},markDirty:t=>{l>=t||(l=t,m.forEach(t=>{let n=t._node||t;n.type===`effect`?(n.isDirty=!0,e.scheduleEffect(t)):n.markDirty&&n.markDirty(1)}))}},_={get value(){return e.activeConsumer&&e.activeConsumer!==g&&(g.subscribers.add(e.activeConsumer),e.activeConsumer.dependencies.add(g)),h(g),e.activeConsumer&&e.activeConsumer.depVersions&&e.activeConsumer.depVersions.set(_,o),i},get valueWithoutTracking(){return i},get version(){return o},subscribe(t){let n={id:e.subscriberId++,isDirty:!0,depth:9999,dependencies:new Set,type:`effect`,run:()=>{if(!n.isDisposed)try{t(_.value)}catch(e){console.error(e)}}};return g.subscribers.add(n),t(_.value),()=>{n.isDisposed=!0,g.subscribers.delete(n)}},subscribeState(e){return _.subscribe(e)},destroy:()=>{g.subscribers.clear(),p(g),e.computedCache.delete(t),a=!0,l=2,s=!1},__subscribe(t){let n={id:e.subscriberId++,type:`effect`,run:t,isDirty:!1};return g.subscribers.add(n),()=>{m.delete(n)}}};return _._node=g,_.subscribers=m,_.dependencies=u,_._isDirty=()=>l>0,_.type=`computed`,_.run=()=>g.run(),e.computedCache.set(t,new WeakRef(_)),_}exports.createComputed=e;
1
+ function e(e,t,n){let r=e.computedCache.get(t);if(r)return r;let i,a=!0,o=0,s=!1,c=-1,l=2,u=new Set,d=new Map,f=new Set,p=e=>{if(!e)return;let t=e._node||e;if(t.dependencies&&t.dependencies.size>0){let n=Array.from(t.dependencies);t.dependencies.clear(),t.depVersions&&t.depVersions.clear();for(let r of n){let n=r,i=n._node||n;i.subscribers&&(i.subscribers.delete(t),i.subscribers.delete(e),i.subscribers.delete(g),i.type===`computed`&&i.subscribers.size===0&&p(i))}}},m=new Set,h=e=>{if(!s||e.state===2)return e.run();if(e.state===1){let t=!1;if(e.dependencies&&e.dependencies.size>0)for(let n of e.dependencies){let r=n,i=r._node||r;t||(i.type===`computed`&&i.state>0&&h(i),e.depVersions.get(r)!==i.version&&(t=!0))}return e.state=0,t||a?e.run():!1}return!1},g={id:e.subscriberId++,dependencies:u,subscribers:m,ownedEffects:f,depth:1,type:`computed`,fn:t,get version(){return o},get state(){return l},set state(e){l=e},get depVersions(){return d},update:()=>h(g),run:()=>{if(c===e.epoch&&s)return!1;if(c=e.epoch,e.cycleDetectionStack.has(g))throw Error(`[Graph Error] Cyclic dependency detected`);e.cycleDetectionStack.add(g);let r=e.activeConsumer,p=e.activeOwner;e.activeConsumer=g,e.activeOwner=g;let h=new Set(u);u.clear();try{if(f.size>0){for(let e of f)e&&typeof e.dispose==`function`&&e.dispose();f.clear()}let r=t();for(let e of h){let t=e;if(!u.has(t)){let e=t._node||t;e.subscribers&&e.subscribers.delete(g),d.delete(t)}}let c=a||!Object.is(i,r);if(c){let t=a?void 0:typeof i==`object`&&i?JSON.parse(JSON.stringify(i)):i;i=r,o++,e.log&&n&&e.log({type:`computed`,label:n,details:{from:t,to:r}});for(let t of m){let n=t._node||t;n.type===`effect`?(n.state=2,n.isDirty=!0,e.scheduleEffect(t)):n.markDirty&&n.markDirty(1)}}a=!1,l=0,s=!0;let p=0;for(let e of u){let t=e,n=t._node||t;d.set(t,n.version),n.subscribers&&n.subscribers.add(g),n.depth!==void 0&&n.depth>p&&(p=n.depth)}for(let t of m){let n=t._node||t;n.type===`effect`?(n.state=2,n.isDirty=!0,e.scheduleEffect(t)):n.markDirty&&n.markDirty(1)}return g.depth=p+1,c}finally{e.activeConsumer=r,e.activeOwner=p,e.cycleDetectionStack.delete(g)}},markDirty:t=>{if(!(l>=t)){l=t;for(let t of m){let n=t._node||t;n.type===`effect`?(n.isDirty=!0,e.scheduleEffect(t)):n.markDirty&&n.markDirty(1)}}}},_={get value(){return e.activeConsumer&&e.activeConsumer!==g&&(g.subscribers.add(e.activeConsumer),e.activeConsumer.dependencies.add(g)),h(g),e.activeConsumer&&e.activeConsumer.depVersions&&e.activeConsumer.depVersions.set(_,o),i},get valueWithoutTracking(){return i},get version(){return o},subscribe(t){let n={id:e.subscriberId++,isDirty:!0,depth:9999,dependencies:new Set,type:`effect`,run:()=>{if(!n.isDisposed)try{t(_.value)}catch(e){console.error(e)}}};return g.subscribers.add(n),t(_.value),()=>{n.isDisposed=!0,g.subscribers.delete(n)}},subscribeState(e){return _.subscribe(e)},destroy:()=>{g.subscribers.clear(),p(g),e.computedCache.delete(t),a=!0,l=2,s=!1},__subscribe(t){let n={id:e.subscriberId++,type:`effect`,run:t,isDirty:!1};return g.subscribers.add(n),()=>{m.delete(n)}}};return _._node=g,_.subscribers=m,_.dependencies=u,_._isDirty=()=>l>0,_.type=`computed`,_.run=()=>g.run(),e.computedCache.set(t,_),_}exports.createComputed=e;
2
2
  //# sourceMappingURL=core.method.computed.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"core.method.computed.cjs","names":[],"sources":["../src/core/core.method.computed.ts"],"sourcesContent":["import { Computed, CleanupFn } from './types'\n\nexport function createComputed<T>(\n engine: any,\n fn: () => T,\n signalName?: string\n): Computed<T> {\n const cachedRef = engine.computedCache.get(fn)\n const existing = cachedRef?.deref()\n if (existing) return existing as Computed<T>\n\n let value: T\n let isDirty = true\n let version = 0\n let isInitialized = false\n\n // Канонический маркер эпохи вычисления кадра графа\n let evaluatedInEpoch = -1\n\n // 0 = STABLE, 1 = CHECK, 2 = DIRTY\n let state = 2\n\n const dependencies = new Set<any>()\n const depVersions = new Map<any, number>()\n const ownedEffects = new Set<any>()\n\n const releaseNode = (node: any): void => {\n if (!node) return\n const actNode = node._node || node\n if (actNode.dependencies && actNode.dependencies.size > 0) {\n const snapshotDeps = Array.from(actNode.dependencies)\n actNode.dependencies.clear()\n if (actNode.depVersions) actNode.depVersions.clear()\n\n snapshotDeps.forEach((dep: any) => {\n const rawDepNode = dep._node || dep\n if (rawDepNode.subscribers) {\n rawDepNode.subscribers.delete(actNode)\n rawDepNode.subscribers.delete(node)\n rawDepNode.subscribers.delete(computedNode)\n if (rawDepNode.type === 'computed' && rawDepNode.subscribers.size === 0) {\n releaseNode(rawDepNode)\n }\n }\n })\n }\n }\n\n const subscribers = new class extends Set<any> {\n override delete(val: any): boolean {\n const res = super.delete(val)\n if (this.size === 0) {\n state = 2\n isDirty = true\n isInitialized = false\n releaseNode(computedNode)\n engine.computedCache.delete(fn)\n }\n return res\n }\n }()\n\n // ⚡ КАНOНИЧЕСКИЙ АПДЕЙТЕР ГРАФА С ПОСЛЕДОВАТЕЛЬНЫМ ПРЕPЫВАНИЕМ (Pull)\n const updateIfNecessary = (node: any): boolean => {\n if (!isInitialized) return node.run()\n if (node.state === 2) return node.run()\n\n if (node.state === 1) {\n let hasChangedParent = false\n\n // Опрашиваем родителей ПОСЛЕДOВАТЕЛЬНO, строго по одному!\n for (const dep of Array.from(node.dependencies || [])) {\n const rawDep = (dep as any)._node || dep\n\n // Рекурсивно погружаемся в родителя, только если предыдущие еще не изменились\n if (!hasChangedParent) {\n if (rawDep.type === 'computed' && rawDep.state > 0) {\n updateIfNecessary(rawDep)\n }\n\n // Сверяем сохраненный слепок версии ребра с актуальной версией родителя\n if (node.depVersions.get(dep) !== rawDep.version) {\n hasChangedParent = true\n // 🎯 VALUE EQUALITY BREAK: Родитель изменился!\n // Прерываем опрос оставшихся родителей в этом цикле, чтобы не дергать\n // мёртвые ветки (узел c в тесте #193) холосто до перестройки графа!\n }\n }\n }\n\n // Намертво гасим стейт узла в стабильный (0) ДО вызова run(),\n // пресекая повторные фантомные заходы на чтении геттеров\n node.state = 0\n\n if (hasChangedParent || isDirty) {\n return node.run() // Пересчитываем узел, что вызовет динамический diff и отписку\n }\n return false // Value Equality Cut\n }\n return false\n }\n\n const computedNode: any = {\n id: engine.subscriberId++,\n dependencies,\n subscribers,\n ownedEffects,\n depth: 1,\n type: 'computed',\n fn,\n get version() { return version },\n get state() { return state },\n set state(val: number) { state = val },\n get depVersions() { return depVersions },\n update: () => updateIfNecessary(computedNode),\n run: () => {\n // 1. Быстрый выход, если узел уже актуализирован в рамках текущей эпохи кадра\n if (evaluatedInEpoch === engine.epoch && isInitialized) {\n return false\n }\n evaluatedInEpoch = engine.epoch\n\n // 2. Пуленепробиваемая защита от циклических зависимостей графа\n if (engine.cycleDetectionStack.has(computedNode)) {\n throw new Error('[Graph Error] Cyclic dependency detected')\n }\n engine.cycleDetectionStack.add(computedNode)\n\n const prevConsumer = engine.activeConsumer\n const prevOwner = engine.activeOwner\n\n // 3. Выставляем глобальные контексты Ядра строго ДО выполнения функции fn()\n engine.activeConsumer = computedNode\n engine.activeOwner = computedNode\n\n // 4. Снимаем слепок старых зависимостей перед оценкой кадра\n const oldDeps = new Set(dependencies)\n dependencies.clear()\n\n try {\n // 🌳 ФИКС КЕЙСА #242: Очищаем вложенные эффекты предыдущего кадра строго ДО оценки fn()\n if (ownedEffects) {\n ownedEffects.forEach(child => {\n if (child && typeof child.dispose === 'function') {\n child.dispose()\n }\n })\n ownedEffects.clear()\n }\n\n const newValue = fn()\n\n // 5. Дифференцируем внешние связи графа строго ПОСЛЕ вычисления fn()\n oldDeps.forEach(dep => {\n if (!dependencies.has(dep)) {\n const rawDepNode = dep._node || dep\n if (rawDepNode.subscribers) rawDepNode.subscribers.delete(computedNode)\n depVersions.delete(dep)\n }\n })\n\n const changed = isDirty || !Object.is(value, newValue)\n\n if (changed) {\n const previousValueSnapshot = isDirty ? undefined : (typeof value === 'object' && value !== null ? JSON.parse(JSON.stringify(value)) : value)\n value = newValue\n version++\n\n if (engine.log && signalName) {\n engine.log({\n type: 'computed',\n label: signalName,\n details: { from: previousValueSnapshot, to: newValue }\n })\n }\n\n subscribers.forEach(sub => {\n const rawSub = sub._node || sub\n if (rawSub.type === 'effect') {\n rawSub.state = 2\n rawSub.isDirty = true\n engine.scheduleEffect(sub)\n } else if (rawSub.markDirty) {\n rawSub.markDirty(1)\n }\n })\n }\n\n isDirty = false\n state = 0\n isInitialized = true\n\n let maxDepDepth = 0\n dependencies.forEach(dep => {\n const rawNode = dep._node || dep\n depVersions.set(dep, rawNode.version)\n if (rawNode.subscribers) rawNode.subscribers.add(computedNode)\n if (rawNode.depth !== undefined && rawNode.depth > maxDepDepth) {\n maxDepDepth = rawNode.depth\n }\n })\n\n subscribers.forEach(sub => {\n const rawSub = sub._node || sub\n if (rawSub.type === 'effect') {\n rawSub.state = 2\n rawSub.isDirty = true\n\n engine.scheduleEffect(sub)\n } else if (rawSub.markDirty) {\n rawSub.markDirty(1)\n }\n })\n\n computedNode.depth = maxDepDepth + 1\n return changed\n } finally {\n engine.activeConsumer = prevConsumer\n engine.activeOwner = prevOwner\n engine.cycleDetectionStack.delete(computedNode)\n }\n },\n markDirty: (parentState: number) => {\n if (state >= parentState) return\n state = parentState\n\n subscribers.forEach(sub => {\n const rawSub = sub._node || sub\n if (rawSub.type === 'effect') {\n rawSub.isDirty = true\n engine.scheduleEffect(sub)\n } else if (rawSub.markDirty) {\n rawSub.markDirty(1)\n }\n })\n }\n }\n\n const computedInstance: Computed<T> = {\n get value() {\n if (engine.activeConsumer && engine.activeConsumer !== computedNode) {\n computedNode.subscribers.add(engine.activeConsumer)\n engine.activeConsumer.dependencies.add(computedNode)\n }\n\n updateIfNecessary(computedNode)\n\n if (engine.activeConsumer && engine.activeConsumer.depVersions) {\n engine.activeConsumer.depVersions.set(computedInstance, version)\n }\n return value\n },\n get valueWithoutTracking() { return value },\n get version() { return version },\n subscribe(cb: (val: T) => void): CleanupFn {\n const fakeEffect: any = {\n id: engine.subscriberId++,\n isDirty: true,\n depth: 9999,\n dependencies: new Set(),\n type: 'effect',\n run: () => {\n if (fakeEffect.isDisposed) return\n try { cb(computedInstance.value) } catch (err) { console.error(err) }\n }\n }\n computedNode.subscribers.add(fakeEffect)\n cb(computedInstance.value)\n return () => {\n fakeEffect.isDisposed = true\n computedNode.subscribers.delete(fakeEffect)\n }\n },\n subscribeState(cb: () => void): CleanupFn {\n return (computedInstance as any).subscribe(cb)\n },\n destroy: () => {\n computedNode.subscribers.clear()\n releaseNode(computedNode)\n engine.computedCache.delete(fn)\n isDirty = true\n state = 2\n isInitialized = false\n },\n __subscribe(cb: () => void): CleanupFn {\n const hookEffect: any = {\n id: engine.subscriberId++,\n type: 'effect',\n run: cb,\n isDirty: false\n }\n computedNode.subscribers.add(hookEffect)\n return () => {\n subscribers.delete(hookEffect)\n }\n }\n } as any\n\n ;(computedInstance as any)._node = computedNode\n ;(computedInstance as any).subscribers = subscribers\n ;(computedInstance as any).dependencies = dependencies\n computedInstance._isDirty = () => state > 0\n computedInstance.type = 'computed'\n computedInstance.run = () => computedNode.run()\n\n engine.computedCache.set(fn, new WeakRef(computedInstance as any))\n return computedInstance\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"core.method.computed.cjs","names":[],"sources":["../src/core/core.method.computed.ts"],"sourcesContent":["import { Computed, CleanupFn } from './types'\n\nexport function createComputed<T>(\n engine: any,\n fn: () => T,\n signalName?: string\n): Computed<T> {\n const existing = engine.computedCache.get(fn)\n if (existing) return existing as Computed<T>\n\n let value: T\n let isDirty = true\n let version = 0\n let isInitialized = false\n // Маркер эпохи вычисления кадра графа\n let evaluatedInEpoch = -1\n // 0 = STABLE, 1 = CHECK, 2 = DIRTY\n let state = 2\n\n const dependencies = new Set<any>()\n const depVersions = new Map<any, number>()\n const ownedEffects = new Set<any>()\n\n const releaseNode = (node: any): void => {\n if (!node) return\n const actNode = node._node || node\n if (actNode.dependencies && actNode.dependencies.size > 0) {\n const snapshotDeps = Array.from(actNode.dependencies)\n actNode.dependencies.clear()\n if (actNode.depVersions) actNode.depVersions.clear()\n\n for (const unknownDep of snapshotDeps) {\n const dep = unknownDep as any\n const rawDepNode = dep._node || dep\n if (rawDepNode.subscribers) {\n rawDepNode.subscribers.delete(actNode)\n rawDepNode.subscribers.delete(node)\n rawDepNode.subscribers.delete(computedNode)\n if (rawDepNode.type === 'computed' && rawDepNode.subscribers.size === 0) {\n releaseNode(rawDepNode)\n }\n }\n }\n }\n }\n\n const subscribers = new Set<any>()\n\n const updateIfNecessary = (node: any): boolean => {\n if (!isInitialized) return node.run()\n if (node.state === 2) return node.run()\n\n if (node.state === 1) {\n let hasChangedParent = false\n\n if (node.dependencies && node.dependencies.size > 0) {\n for (const unknownDep of node.dependencies) {\n const dep = unknownDep as any\n const rawDep = dep._node || dep\n\n if (!hasChangedParent) {\n if (rawDep.type === 'computed' && rawDep.state > 0) {\n updateIfNecessary(rawDep)\n }\n\n if (node.depVersions.get(dep) !== rawDep.version) {\n hasChangedParent = true\n }\n }\n }\n }\n\n node.state = 0\n\n if (hasChangedParent || isDirty) {\n return node.run()\n }\n return false\n }\n return false\n }\n\n const computedNode: any = {\n id: engine.subscriberId++,\n dependencies,\n subscribers,\n ownedEffects,\n depth: 1,\n type: 'computed',\n fn,\n get version() { return version },\n get state() { return state },\n set state(val: number) { state = val },\n get depVersions() { return depVersions },\n update: () => updateIfNecessary(computedNode),\n run: () => {\n if (evaluatedInEpoch === engine.epoch && isInitialized) {\n return false\n }\n evaluatedInEpoch = engine.epoch\n\n if (engine.cycleDetectionStack.has(computedNode)) {\n throw new Error('[Graph Error] Cyclic dependency detected')\n }\n engine.cycleDetectionStack.add(computedNode)\n\n const prevConsumer = engine.activeConsumer\n const prevOwner = engine.activeOwner\n\n engine.activeConsumer = computedNode\n engine.activeOwner = computedNode\n\n const oldDeps = new Set(dependencies)\n dependencies.clear()\n\n try {\n if (ownedEffects.size > 0) {\n for (const child of ownedEffects) {\n if (child && typeof child.dispose === 'function') {\n child.dispose()\n }\n }\n ownedEffects.clear()\n }\n\n const newValue = fn()\n\n for (const unknownDep of oldDeps) {\n const dep = unknownDep as any\n if (!dependencies.has(dep)) {\n const rawDepNode = dep._node || dep\n if (rawDepNode.subscribers) rawDepNode.subscribers.delete(computedNode)\n depVersions.delete(dep)\n }\n }\n\n const changed = isDirty || !Object.is(value, newValue)\n\n if (changed) {\n const previousValueSnapshot = isDirty ? undefined : (typeof value === 'object' && value !== null ? JSON.parse(JSON.stringify(value)) : value)\n value = newValue\n version++\n\n if (engine.log && signalName) {\n engine.log({\n type: 'computed',\n label: signalName,\n details: { from: previousValueSnapshot, to: newValue }\n })\n }\n\n for (const sub of subscribers) {\n const rawSub = sub._node || sub\n if (rawSub.type === 'effect') {\n rawSub.state = 2\n rawSub.isDirty = true\n engine.scheduleEffect(sub)\n } else if (rawSub.markDirty) {\n rawSub.markDirty(1)\n }\n }\n }\n\n isDirty = false\n state = 0\n isInitialized = true\n\n let maxDepDepth = 0\n for (const unknownDep of dependencies) {\n const dep = unknownDep as any\n const rawNode = dep._node || dep\n depVersions.set(dep, rawNode.version)\n if (rawNode.subscribers) rawNode.subscribers.add(computedNode)\n if (rawNode.depth !== undefined && rawNode.depth > maxDepDepth) {\n maxDepDepth = rawNode.depth\n }\n }\n\n for (const sub of subscribers) {\n const rawSub = sub._node || sub\n if (rawSub.type === 'effect') {\n rawSub.state = 2\n rawSub.isDirty = true\n engine.scheduleEffect(sub)\n } else if (rawSub.markDirty) {\n rawSub.markDirty(1)\n }\n }\n\n computedNode.depth = maxDepDepth + 1\n return changed\n } finally {\n engine.activeConsumer = prevConsumer\n engine.activeOwner = prevOwner\n engine.cycleDetectionStack.delete(computedNode)\n }\n },\n markDirty: (parentState: number) => {\n if (state >= parentState) return\n state = parentState\n\n for (const sub of subscribers) {\n const rawSub = sub._node || sub\n if (rawSub.type === 'effect') {\n rawSub.isDirty = true\n engine.scheduleEffect(sub)\n } else if (rawSub.markDirty) {\n rawSub.markDirty(1)\n }\n }\n }\n }\n\n const computedInstance: Computed<T> = {\n get value() {\n if (engine.activeConsumer && engine.activeConsumer !== computedNode) {\n computedNode.subscribers.add(engine.activeConsumer)\n engine.activeConsumer.dependencies.add(computedNode)\n }\n\n updateIfNecessary(computedNode)\n\n if (engine.activeConsumer && engine.activeConsumer.depVersions) {\n engine.activeConsumer.depVersions.set(computedInstance, version)\n }\n return value\n },\n get valueWithoutTracking() { return value },\n get version() { return version },\n subscribe(cb: (val: T) => void): CleanupFn {\n const fakeEffect: any = {\n id: engine.subscriberId++,\n isDirty: true,\n depth: 9999,\n dependencies: new Set(),\n type: 'effect',\n run: () => {\n if (fakeEffect.isDisposed) return\n try { cb(computedInstance.value) } catch (err) { console.error(err) }\n }\n }\n computedNode.subscribers.add(fakeEffect)\n cb(computedInstance.value)\n return () => {\n fakeEffect.isDisposed = true\n computedNode.subscribers.delete(fakeEffect)\n }\n },\n subscribeState(cb: () => void): CleanupFn {\n return (computedInstance as any).subscribe(cb)\n },\n destroy: () => {\n computedNode.subscribers.clear()\n releaseNode(computedNode)\n engine.computedCache.delete(fn)\n isDirty = true\n state = 2\n isInitialized = false\n },\n __subscribe(cb: () => void): CleanupFn {\n const hookEffect: any = {\n id: engine.subscriberId++,\n type: 'effect',\n run: cb,\n isDirty: false\n }\n computedNode.subscribers.add(hookEffect)\n return () => {\n subscribers.delete(hookEffect)\n }\n }\n } as any\n\n ;(computedInstance as any)._node = computedNode\n ;(computedInstance as any).subscribers = subscribers\n ;(computedInstance as any).dependencies = dependencies\n computedInstance._isDirty = () => state > 0\n computedInstance.type = 'computed'\n computedInstance.run = () => computedNode.run()\n\n engine.computedCache.set(fn, computedInstance)\n return computedInstance\n}\n"],"mappings":"AAEA,SAAgB,EACd,EACA,EACA,EACa,CACb,IAAM,EAAW,EAAO,cAAc,IAAI,CAAE,EAC5C,GAAI,EAAU,OAAO,EAErB,IAAI,EACA,EAAU,GACV,EAAU,EACV,EAAgB,GAEhB,EAAmB,GAEnB,EAAQ,EAEN,EAAe,IAAI,IACnB,EAAc,IAAI,IAClB,EAAe,IAAI,IAEnB,EAAe,GAAoB,CACvC,GAAI,CAAC,EAAM,OACX,IAAM,EAAU,EAAK,OAAS,EAC9B,GAAI,EAAQ,cAAgB,EAAQ,aAAa,KAAO,EAAG,CACzD,IAAM,EAAe,MAAM,KAAK,EAAQ,YAAY,EACpD,EAAQ,aAAa,MAAM,EACvB,EAAQ,aAAa,EAAQ,YAAY,MAAM,EAEnD,IAAK,IAAM,KAAc,EAAc,CACrC,IAAM,EAAM,EACN,EAAa,EAAI,OAAS,EAC5B,EAAW,cACb,EAAW,YAAY,OAAO,CAAO,EACrC,EAAW,YAAY,OAAO,CAAI,EAClC,EAAW,YAAY,OAAO,CAAY,EACtC,EAAW,OAAS,YAAc,EAAW,YAAY,OAAS,GACpE,EAAY,CAAU,EAG5B,CACF,CACF,EAEM,EAAc,IAAI,IAElB,EAAqB,GAAuB,CAEhD,GADI,CAAC,GACD,EAAK,QAAU,EAAG,OAAO,EAAK,IAAI,EAEtC,GAAI,EAAK,QAAU,EAAG,CACpB,IAAI,EAAmB,GAEvB,GAAI,EAAK,cAAgB,EAAK,aAAa,KAAO,EAChD,IAAK,IAAM,KAAc,EAAK,aAAc,CAC1C,IAAM,EAAM,EACN,EAAS,EAAI,OAAS,EAEvB,IACC,EAAO,OAAS,YAAc,EAAO,MAAQ,GAC/C,EAAkB,CAAM,EAGtB,EAAK,YAAY,IAAI,CAAG,IAAM,EAAO,UACvC,EAAmB,IAGzB,CAQF,MALA,GAAK,MAAQ,EAET,GAAoB,EACf,EAAK,IAAI,EAEX,EACT,CACA,MAAO,EACT,EAEM,EAAoB,CACxB,GAAI,EAAO,eACX,eACA,cACA,eACA,MAAO,EACP,KAAM,WACN,KACA,IAAI,SAAU,CAAE,OAAO,CAAQ,EAC/B,IAAI,OAAQ,CAAE,OAAO,CAAM,EAC3B,IAAI,MAAM,EAAa,CAAE,EAAQ,CAAI,EACrC,IAAI,aAAc,CAAE,OAAO,CAAY,EACvC,WAAc,EAAkB,CAAY,EAC5C,QAAW,CACT,GAAI,IAAqB,EAAO,OAAS,EACvC,MAAO,GAIT,GAFA,EAAmB,EAAO,MAEtB,EAAO,oBAAoB,IAAI,CAAY,EAC7C,MAAU,MAAM,0CAA0C,EAE5D,EAAO,oBAAoB,IAAI,CAAY,EAE3C,IAAM,EAAe,EAAO,eACtB,EAAY,EAAO,YAEzB,EAAO,eAAiB,EACxB,EAAO,YAAc,EAErB,IAAM,EAAU,IAAI,IAAI,CAAY,EACpC,EAAa,MAAM,EAEnB,GAAI,CACF,GAAI,EAAa,KAAO,EAAG,CACzB,IAAK,IAAM,KAAS,EACd,GAAS,OAAO,EAAM,SAAY,YACpC,EAAM,QAAQ,EAGlB,EAAa,MAAM,CACrB,CAEA,IAAM,EAAW,EAAG,EAEpB,IAAK,IAAM,KAAc,EAAS,CAChC,IAAM,EAAM,EACZ,GAAI,CAAC,EAAa,IAAI,CAAG,EAAG,CAC1B,IAAM,EAAa,EAAI,OAAS,EAC5B,EAAW,aAAa,EAAW,YAAY,OAAO,CAAY,EACtE,EAAY,OAAO,CAAG,CACxB,CACF,CAEA,IAAM,EAAU,GAAW,CAAC,OAAO,GAAG,EAAO,CAAQ,EAErD,GAAI,EAAS,CACX,IAAM,EAAwB,EAAU,IAAA,GAAa,OAAO,GAAU,UAAY,EAAiB,KAAK,MAAM,KAAK,UAAU,CAAK,CAAC,EAAI,EACvI,EAAQ,EACR,IAEI,EAAO,KAAO,GAChB,EAAO,IAAI,CACT,KAAM,WACN,MAAO,EACP,QAAS,CAAE,KAAM,EAAuB,GAAI,CAAS,CACvD,CAAC,EAGH,IAAK,IAAM,KAAO,EAAa,CAC7B,IAAM,EAAS,EAAI,OAAS,EACxB,EAAO,OAAS,UAClB,EAAO,MAAQ,EACf,EAAO,QAAU,GACjB,EAAO,eAAe,CAAG,GAChB,EAAO,WAChB,EAAO,UAAU,CAAC,CAEtB,CACF,CAEA,EAAU,GACV,EAAQ,EACR,EAAgB,GAEhB,IAAI,EAAc,EAClB,IAAK,IAAM,KAAc,EAAc,CACrC,IAAM,EAAM,EACN,EAAU,EAAI,OAAS,EAC7B,EAAY,IAAI,EAAK,EAAQ,OAAO,EAChC,EAAQ,aAAa,EAAQ,YAAY,IAAI,CAAY,EACzD,EAAQ,QAAU,IAAA,IAAa,EAAQ,MAAQ,IACjD,EAAc,EAAQ,MAE1B,CAEA,IAAK,IAAM,KAAO,EAAa,CAC7B,IAAM,EAAS,EAAI,OAAS,EACxB,EAAO,OAAS,UAClB,EAAO,MAAQ,EACf,EAAO,QAAU,GACjB,EAAO,eAAe,CAAG,GAChB,EAAO,WAChB,EAAO,UAAU,CAAC,CAEtB,CAGA,MADA,GAAa,MAAQ,EAAc,EAC5B,CACT,QAAU,CACR,EAAO,eAAiB,EACxB,EAAO,YAAc,EACrB,EAAO,oBAAoB,OAAO,CAAY,CAChD,CACF,EACA,UAAY,GAAwB,CAC9B,QAAS,GACb,GAAQ,EAER,IAAK,IAAM,KAAO,EAAa,CAC7B,IAAM,EAAS,EAAI,OAAS,EACxB,EAAO,OAAS,UAClB,EAAO,QAAU,GACjB,EAAO,eAAe,CAAG,GAChB,EAAO,WAChB,EAAO,UAAU,CAAC,CAEtB,CAVQ,CAWV,CACF,EAEM,EAAgC,CACpC,IAAI,OAAQ,CAWV,OAVI,EAAO,gBAAkB,EAAO,iBAAmB,IACrD,EAAa,YAAY,IAAI,EAAO,cAAc,EAClD,EAAO,eAAe,aAAa,IAAI,CAAY,GAGrD,EAAkB,CAAY,EAE1B,EAAO,gBAAkB,EAAO,eAAe,aACjD,EAAO,eAAe,YAAY,IAAI,EAAkB,CAAO,EAE1D,CACT,EACA,IAAI,sBAAuB,CAAE,OAAO,CAAM,EAC1C,IAAI,SAAU,CAAE,OAAO,CAAQ,EAC/B,UAAU,EAAiC,CACzC,IAAM,EAAkB,CACtB,GAAI,EAAO,eACX,QAAS,GACT,MAAO,KACP,aAAc,IAAI,IAClB,KAAM,SACN,QAAW,CACL,MAAW,WACf,GAAI,CAAE,EAAG,EAAiB,KAAK,CAAE,OAAS,EAAK,CAAE,QAAQ,MAAM,CAAG,CAAE,CACtE,CACF,EAGA,OAFA,EAAa,YAAY,IAAI,CAAU,EACvC,EAAG,EAAiB,KAAK,MACZ,CACX,EAAW,WAAa,GACxB,EAAa,YAAY,OAAO,CAAU,CAC5C,CACF,EACA,eAAe,EAA2B,CACxC,OAAQ,EAAyB,UAAU,CAAE,CAC/C,EACA,YAAe,CACb,EAAa,YAAY,MAAM,EAC/B,EAAY,CAAY,EACxB,EAAO,cAAc,OAAO,CAAE,EAC9B,EAAU,GACV,EAAQ,EACR,EAAgB,EAClB,EACA,YAAY,EAA2B,CACrC,IAAM,EAAkB,CACtB,GAAI,EAAO,eACX,KAAM,SACN,IAAK,EACL,QAAS,EACX,EAEA,OADA,EAAa,YAAY,IAAI,CAAU,MAC1B,CACX,EAAY,OAAO,CAAU,CAC/B,CACF,CACF,EAUA,MARC,GAA0B,MAAQ,EAClC,EAA0B,YAAc,EACxC,EAA0B,aAAe,EAC1C,EAAiB,aAAiB,EAAQ,EAC1C,EAAiB,KAAO,WACxB,EAAiB,QAAY,EAAa,IAAI,EAE9C,EAAO,cAAc,IAAI,EAAI,CAAgB,EACtC,CACT"}
@@ -1,29 +1,25 @@
1
1
  //#region src/core/core.method.computed.ts
2
2
  function e(e, t, n) {
3
- let r = e.computedCache.get(t)?.deref();
3
+ let r = e.computedCache.get(t);
4
4
  if (r) return r;
5
5
  let i, a = !0, o = 0, s = !1, c = -1, l = 2, u = /* @__PURE__ */ new Set(), d = /* @__PURE__ */ new Map(), f = /* @__PURE__ */ new Set(), p = (e) => {
6
6
  if (!e) return;
7
7
  let t = e._node || e;
8
8
  if (t.dependencies && t.dependencies.size > 0) {
9
9
  let n = Array.from(t.dependencies);
10
- t.dependencies.clear(), t.depVersions && t.depVersions.clear(), n.forEach((n) => {
11
- let r = n._node || n;
12
- r.subscribers && (r.subscribers.delete(t), r.subscribers.delete(e), r.subscribers.delete(g), r.type === "computed" && r.subscribers.size === 0 && p(r));
13
- });
14
- }
15
- }, m = new class extends Set {
16
- delete(n) {
17
- let r = super.delete(n);
18
- return this.size === 0 && (l = 2, a = !0, s = !1, p(g), e.computedCache.delete(t)), r;
10
+ t.dependencies.clear(), t.depVersions && t.depVersions.clear();
11
+ for (let r of n) {
12
+ let n = r, i = n._node || n;
13
+ i.subscribers && (i.subscribers.delete(t), i.subscribers.delete(e), i.subscribers.delete(g), i.type === "computed" && i.subscribers.size === 0 && p(i));
14
+ }
19
15
  }
20
- }(), h = (e) => {
16
+ }, m = /* @__PURE__ */ new Set(), h = (e) => {
21
17
  if (!s || e.state === 2) return e.run();
22
18
  if (e.state === 1) {
23
19
  let t = !1;
24
- for (let n of Array.from(e.dependencies || [])) {
25
- let r = n._node || n;
26
- t || (r.type === "computed" && r.state > 0 && h(r), e.depVersions.get(n) !== r.version && (t = !0));
20
+ if (e.dependencies && e.dependencies.size > 0) for (let n of e.dependencies) {
21
+ let r = n, i = r._node || r;
22
+ t || (i.type === "computed" && i.state > 0 && h(i), e.depVersions.get(r) !== i.version && (t = !0));
27
23
  }
28
24
  return e.state = 0, t || a ? e.run() : !1;
29
25
  }
@@ -58,16 +54,18 @@ function e(e, t, n) {
58
54
  let h = new Set(u);
59
55
  u.clear();
60
56
  try {
61
- f && (f.forEach((e) => {
62
- e && typeof e.dispose == "function" && e.dispose();
63
- }), f.clear());
57
+ if (f.size > 0) {
58
+ for (let e of f) e && typeof e.dispose == "function" && e.dispose();
59
+ f.clear();
60
+ }
64
61
  let r = t();
65
- h.forEach((e) => {
66
- if (!u.has(e)) {
67
- let t = e._node || e;
68
- t.subscribers && t.subscribers.delete(g), d.delete(e);
62
+ for (let e of h) {
63
+ let t = e;
64
+ if (!u.has(t)) {
65
+ let e = t._node || t;
66
+ e.subscribers && e.subscribers.delete(g), d.delete(t);
69
67
  }
70
- });
68
+ }
71
69
  let c = a || !Object.is(i, r);
72
70
  if (c) {
73
71
  let t = a ? void 0 : typeof i == "object" && i ? JSON.parse(JSON.stringify(i)) : i;
@@ -78,29 +76,35 @@ function e(e, t, n) {
78
76
  from: t,
79
77
  to: r
80
78
  }
81
- }), m.forEach((t) => {
79
+ });
80
+ for (let t of m) {
82
81
  let n = t._node || t;
83
82
  n.type === "effect" ? (n.state = 2, n.isDirty = !0, e.scheduleEffect(t)) : n.markDirty && n.markDirty(1);
84
- });
83
+ }
85
84
  }
86
85
  a = !1, l = 0, s = !0;
87
86
  let p = 0;
88
- return u.forEach((e) => {
89
- let t = e._node || e;
90
- d.set(e, t.version), t.subscribers && t.subscribers.add(g), t.depth !== void 0 && t.depth > p && (p = t.depth);
91
- }), m.forEach((t) => {
87
+ for (let e of u) {
88
+ let t = e, n = t._node || t;
89
+ d.set(t, n.version), n.subscribers && n.subscribers.add(g), n.depth !== void 0 && n.depth > p && (p = n.depth);
90
+ }
91
+ for (let t of m) {
92
92
  let n = t._node || t;
93
93
  n.type === "effect" ? (n.state = 2, n.isDirty = !0, e.scheduleEffect(t)) : n.markDirty && n.markDirty(1);
94
- }), g.depth = p + 1, c;
94
+ }
95
+ return g.depth = p + 1, c;
95
96
  } finally {
96
97
  e.activeConsumer = r, e.activeOwner = p, e.cycleDetectionStack.delete(g);
97
98
  }
98
99
  },
99
100
  markDirty: (t) => {
100
- l >= t || (l = t, m.forEach((t) => {
101
- let n = t._node || t;
102
- n.type === "effect" ? (n.isDirty = !0, e.scheduleEffect(t)) : n.markDirty && n.markDirty(1);
103
- }));
101
+ if (!(l >= t)) {
102
+ l = t;
103
+ for (let t of m) {
104
+ let n = t._node || t;
105
+ n.type === "effect" ? (n.isDirty = !0, e.scheduleEffect(t)) : n.markDirty && n.markDirty(1);
106
+ }
107
+ }
104
108
  }
105
109
  }, _ = {
106
110
  get value() {
@@ -149,7 +153,7 @@ function e(e, t, n) {
149
153
  };
150
154
  }
151
155
  };
152
- return _._node = g, _.subscribers = m, _.dependencies = u, _._isDirty = () => l > 0, _.type = "computed", _.run = () => g.run(), e.computedCache.set(t, new WeakRef(_)), _;
156
+ return _._node = g, _.subscribers = m, _.dependencies = u, _._isDirty = () => l > 0, _.type = "computed", _.run = () => g.run(), e.computedCache.set(t, _), _;
153
157
  }
154
158
  //#endregion
155
159
  export { e as createComputed };
@@ -1 +1 @@
1
- {"version":3,"file":"core.method.computed.mjs","names":[],"sources":["../src/core/core.method.computed.ts"],"sourcesContent":["import { Computed, CleanupFn } from './types'\n\nexport function createComputed<T>(\n engine: any,\n fn: () => T,\n signalName?: string\n): Computed<T> {\n const cachedRef = engine.computedCache.get(fn)\n const existing = cachedRef?.deref()\n if (existing) return existing as Computed<T>\n\n let value: T\n let isDirty = true\n let version = 0\n let isInitialized = false\n\n // Канонический маркер эпохи вычисления кадра графа\n let evaluatedInEpoch = -1\n\n // 0 = STABLE, 1 = CHECK, 2 = DIRTY\n let state = 2\n\n const dependencies = new Set<any>()\n const depVersions = new Map<any, number>()\n const ownedEffects = new Set<any>()\n\n const releaseNode = (node: any): void => {\n if (!node) return\n const actNode = node._node || node\n if (actNode.dependencies && actNode.dependencies.size > 0) {\n const snapshotDeps = Array.from(actNode.dependencies)\n actNode.dependencies.clear()\n if (actNode.depVersions) actNode.depVersions.clear()\n\n snapshotDeps.forEach((dep: any) => {\n const rawDepNode = dep._node || dep\n if (rawDepNode.subscribers) {\n rawDepNode.subscribers.delete(actNode)\n rawDepNode.subscribers.delete(node)\n rawDepNode.subscribers.delete(computedNode)\n if (rawDepNode.type === 'computed' && rawDepNode.subscribers.size === 0) {\n releaseNode(rawDepNode)\n }\n }\n })\n }\n }\n\n const subscribers = new class extends Set<any> {\n override delete(val: any): boolean {\n const res = super.delete(val)\n if (this.size === 0) {\n state = 2\n isDirty = true\n isInitialized = false\n releaseNode(computedNode)\n engine.computedCache.delete(fn)\n }\n return res\n }\n }()\n\n // ⚡ КАНOНИЧЕСКИЙ АПДЕЙТЕР ГРАФА С ПОСЛЕДОВАТЕЛЬНЫМ ПРЕPЫВАНИЕМ (Pull)\n const updateIfNecessary = (node: any): boolean => {\n if (!isInitialized) return node.run()\n if (node.state === 2) return node.run()\n\n if (node.state === 1) {\n let hasChangedParent = false\n\n // Опрашиваем родителей ПОСЛЕДOВАТЕЛЬНO, строго по одному!\n for (const dep of Array.from(node.dependencies || [])) {\n const rawDep = (dep as any)._node || dep\n\n // Рекурсивно погружаемся в родителя, только если предыдущие еще не изменились\n if (!hasChangedParent) {\n if (rawDep.type === 'computed' && rawDep.state > 0) {\n updateIfNecessary(rawDep)\n }\n\n // Сверяем сохраненный слепок версии ребра с актуальной версией родителя\n if (node.depVersions.get(dep) !== rawDep.version) {\n hasChangedParent = true\n // 🎯 VALUE EQUALITY BREAK: Родитель изменился!\n // Прерываем опрос оставшихся родителей в этом цикле, чтобы не дергать\n // мёртвые ветки (узел c в тесте #193) холосто до перестройки графа!\n }\n }\n }\n\n // Намертво гасим стейт узла в стабильный (0) ДО вызова run(),\n // пресекая повторные фантомные заходы на чтении геттеров\n node.state = 0\n\n if (hasChangedParent || isDirty) {\n return node.run() // Пересчитываем узел, что вызовет динамический diff и отписку\n }\n return false // Value Equality Cut\n }\n return false\n }\n\n const computedNode: any = {\n id: engine.subscriberId++,\n dependencies,\n subscribers,\n ownedEffects,\n depth: 1,\n type: 'computed',\n fn,\n get version() { return version },\n get state() { return state },\n set state(val: number) { state = val },\n get depVersions() { return depVersions },\n update: () => updateIfNecessary(computedNode),\n run: () => {\n // 1. Быстрый выход, если узел уже актуализирован в рамках текущей эпохи кадра\n if (evaluatedInEpoch === engine.epoch && isInitialized) {\n return false\n }\n evaluatedInEpoch = engine.epoch\n\n // 2. Пуленепробиваемая защита от циклических зависимостей графа\n if (engine.cycleDetectionStack.has(computedNode)) {\n throw new Error('[Graph Error] Cyclic dependency detected')\n }\n engine.cycleDetectionStack.add(computedNode)\n\n const prevConsumer = engine.activeConsumer\n const prevOwner = engine.activeOwner\n\n // 3. Выставляем глобальные контексты Ядра строго ДО выполнения функции fn()\n engine.activeConsumer = computedNode\n engine.activeOwner = computedNode\n\n // 4. Снимаем слепок старых зависимостей перед оценкой кадра\n const oldDeps = new Set(dependencies)\n dependencies.clear()\n\n try {\n // 🌳 ФИКС КЕЙСА #242: Очищаем вложенные эффекты предыдущего кадра строго ДО оценки fn()\n if (ownedEffects) {\n ownedEffects.forEach(child => {\n if (child && typeof child.dispose === 'function') {\n child.dispose()\n }\n })\n ownedEffects.clear()\n }\n\n const newValue = fn()\n\n // 5. Дифференцируем внешние связи графа строго ПОСЛЕ вычисления fn()\n oldDeps.forEach(dep => {\n if (!dependencies.has(dep)) {\n const rawDepNode = dep._node || dep\n if (rawDepNode.subscribers) rawDepNode.subscribers.delete(computedNode)\n depVersions.delete(dep)\n }\n })\n\n const changed = isDirty || !Object.is(value, newValue)\n\n if (changed) {\n const previousValueSnapshot = isDirty ? undefined : (typeof value === 'object' && value !== null ? JSON.parse(JSON.stringify(value)) : value)\n value = newValue\n version++\n\n if (engine.log && signalName) {\n engine.log({\n type: 'computed',\n label: signalName,\n details: { from: previousValueSnapshot, to: newValue }\n })\n }\n\n subscribers.forEach(sub => {\n const rawSub = sub._node || sub\n if (rawSub.type === 'effect') {\n rawSub.state = 2\n rawSub.isDirty = true\n engine.scheduleEffect(sub)\n } else if (rawSub.markDirty) {\n rawSub.markDirty(1)\n }\n })\n }\n\n isDirty = false\n state = 0\n isInitialized = true\n\n let maxDepDepth = 0\n dependencies.forEach(dep => {\n const rawNode = dep._node || dep\n depVersions.set(dep, rawNode.version)\n if (rawNode.subscribers) rawNode.subscribers.add(computedNode)\n if (rawNode.depth !== undefined && rawNode.depth > maxDepDepth) {\n maxDepDepth = rawNode.depth\n }\n })\n\n subscribers.forEach(sub => {\n const rawSub = sub._node || sub\n if (rawSub.type === 'effect') {\n rawSub.state = 2\n rawSub.isDirty = true\n\n engine.scheduleEffect(sub)\n } else if (rawSub.markDirty) {\n rawSub.markDirty(1)\n }\n })\n\n computedNode.depth = maxDepDepth + 1\n return changed\n } finally {\n engine.activeConsumer = prevConsumer\n engine.activeOwner = prevOwner\n engine.cycleDetectionStack.delete(computedNode)\n }\n },\n markDirty: (parentState: number) => {\n if (state >= parentState) return\n state = parentState\n\n subscribers.forEach(sub => {\n const rawSub = sub._node || sub\n if (rawSub.type === 'effect') {\n rawSub.isDirty = true\n engine.scheduleEffect(sub)\n } else if (rawSub.markDirty) {\n rawSub.markDirty(1)\n }\n })\n }\n }\n\n const computedInstance: Computed<T> = {\n get value() {\n if (engine.activeConsumer && engine.activeConsumer !== computedNode) {\n computedNode.subscribers.add(engine.activeConsumer)\n engine.activeConsumer.dependencies.add(computedNode)\n }\n\n updateIfNecessary(computedNode)\n\n if (engine.activeConsumer && engine.activeConsumer.depVersions) {\n engine.activeConsumer.depVersions.set(computedInstance, version)\n }\n return value\n },\n get valueWithoutTracking() { return value },\n get version() { return version },\n subscribe(cb: (val: T) => void): CleanupFn {\n const fakeEffect: any = {\n id: engine.subscriberId++,\n isDirty: true,\n depth: 9999,\n dependencies: new Set(),\n type: 'effect',\n run: () => {\n if (fakeEffect.isDisposed) return\n try { cb(computedInstance.value) } catch (err) { console.error(err) }\n }\n }\n computedNode.subscribers.add(fakeEffect)\n cb(computedInstance.value)\n return () => {\n fakeEffect.isDisposed = true\n computedNode.subscribers.delete(fakeEffect)\n }\n },\n subscribeState(cb: () => void): CleanupFn {\n return (computedInstance as any).subscribe(cb)\n },\n destroy: () => {\n computedNode.subscribers.clear()\n releaseNode(computedNode)\n engine.computedCache.delete(fn)\n isDirty = true\n state = 2\n isInitialized = false\n },\n __subscribe(cb: () => void): CleanupFn {\n const hookEffect: any = {\n id: engine.subscriberId++,\n type: 'effect',\n run: cb,\n isDirty: false\n }\n computedNode.subscribers.add(hookEffect)\n return () => {\n subscribers.delete(hookEffect)\n }\n }\n } as any\n\n ;(computedInstance as any)._node = computedNode\n ;(computedInstance as any).subscribers = subscribers\n ;(computedInstance as any).dependencies = dependencies\n computedInstance._isDirty = () => state > 0\n computedInstance.type = 'computed'\n computedInstance.run = () => computedNode.run()\n\n engine.computedCache.set(fn, new WeakRef(computedInstance as any))\n return computedInstance\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"core.method.computed.mjs","names":[],"sources":["../src/core/core.method.computed.ts"],"sourcesContent":["import { Computed, CleanupFn } from './types'\n\nexport function createComputed<T>(\n engine: any,\n fn: () => T,\n signalName?: string\n): Computed<T> {\n const existing = engine.computedCache.get(fn)\n if (existing) return existing as Computed<T>\n\n let value: T\n let isDirty = true\n let version = 0\n let isInitialized = false\n // Маркер эпохи вычисления кадра графа\n let evaluatedInEpoch = -1\n // 0 = STABLE, 1 = CHECK, 2 = DIRTY\n let state = 2\n\n const dependencies = new Set<any>()\n const depVersions = new Map<any, number>()\n const ownedEffects = new Set<any>()\n\n const releaseNode = (node: any): void => {\n if (!node) return\n const actNode = node._node || node\n if (actNode.dependencies && actNode.dependencies.size > 0) {\n const snapshotDeps = Array.from(actNode.dependencies)\n actNode.dependencies.clear()\n if (actNode.depVersions) actNode.depVersions.clear()\n\n for (const unknownDep of snapshotDeps) {\n const dep = unknownDep as any\n const rawDepNode = dep._node || dep\n if (rawDepNode.subscribers) {\n rawDepNode.subscribers.delete(actNode)\n rawDepNode.subscribers.delete(node)\n rawDepNode.subscribers.delete(computedNode)\n if (rawDepNode.type === 'computed' && rawDepNode.subscribers.size === 0) {\n releaseNode(rawDepNode)\n }\n }\n }\n }\n }\n\n const subscribers = new Set<any>()\n\n const updateIfNecessary = (node: any): boolean => {\n if (!isInitialized) return node.run()\n if (node.state === 2) return node.run()\n\n if (node.state === 1) {\n let hasChangedParent = false\n\n if (node.dependencies && node.dependencies.size > 0) {\n for (const unknownDep of node.dependencies) {\n const dep = unknownDep as any\n const rawDep = dep._node || dep\n\n if (!hasChangedParent) {\n if (rawDep.type === 'computed' && rawDep.state > 0) {\n updateIfNecessary(rawDep)\n }\n\n if (node.depVersions.get(dep) !== rawDep.version) {\n hasChangedParent = true\n }\n }\n }\n }\n\n node.state = 0\n\n if (hasChangedParent || isDirty) {\n return node.run()\n }\n return false\n }\n return false\n }\n\n const computedNode: any = {\n id: engine.subscriberId++,\n dependencies,\n subscribers,\n ownedEffects,\n depth: 1,\n type: 'computed',\n fn,\n get version() { return version },\n get state() { return state },\n set state(val: number) { state = val },\n get depVersions() { return depVersions },\n update: () => updateIfNecessary(computedNode),\n run: () => {\n if (evaluatedInEpoch === engine.epoch && isInitialized) {\n return false\n }\n evaluatedInEpoch = engine.epoch\n\n if (engine.cycleDetectionStack.has(computedNode)) {\n throw new Error('[Graph Error] Cyclic dependency detected')\n }\n engine.cycleDetectionStack.add(computedNode)\n\n const prevConsumer = engine.activeConsumer\n const prevOwner = engine.activeOwner\n\n engine.activeConsumer = computedNode\n engine.activeOwner = computedNode\n\n const oldDeps = new Set(dependencies)\n dependencies.clear()\n\n try {\n if (ownedEffects.size > 0) {\n for (const child of ownedEffects) {\n if (child && typeof child.dispose === 'function') {\n child.dispose()\n }\n }\n ownedEffects.clear()\n }\n\n const newValue = fn()\n\n for (const unknownDep of oldDeps) {\n const dep = unknownDep as any\n if (!dependencies.has(dep)) {\n const rawDepNode = dep._node || dep\n if (rawDepNode.subscribers) rawDepNode.subscribers.delete(computedNode)\n depVersions.delete(dep)\n }\n }\n\n const changed = isDirty || !Object.is(value, newValue)\n\n if (changed) {\n const previousValueSnapshot = isDirty ? undefined : (typeof value === 'object' && value !== null ? JSON.parse(JSON.stringify(value)) : value)\n value = newValue\n version++\n\n if (engine.log && signalName) {\n engine.log({\n type: 'computed',\n label: signalName,\n details: { from: previousValueSnapshot, to: newValue }\n })\n }\n\n for (const sub of subscribers) {\n const rawSub = sub._node || sub\n if (rawSub.type === 'effect') {\n rawSub.state = 2\n rawSub.isDirty = true\n engine.scheduleEffect(sub)\n } else if (rawSub.markDirty) {\n rawSub.markDirty(1)\n }\n }\n }\n\n isDirty = false\n state = 0\n isInitialized = true\n\n let maxDepDepth = 0\n for (const unknownDep of dependencies) {\n const dep = unknownDep as any\n const rawNode = dep._node || dep\n depVersions.set(dep, rawNode.version)\n if (rawNode.subscribers) rawNode.subscribers.add(computedNode)\n if (rawNode.depth !== undefined && rawNode.depth > maxDepDepth) {\n maxDepDepth = rawNode.depth\n }\n }\n\n for (const sub of subscribers) {\n const rawSub = sub._node || sub\n if (rawSub.type === 'effect') {\n rawSub.state = 2\n rawSub.isDirty = true\n engine.scheduleEffect(sub)\n } else if (rawSub.markDirty) {\n rawSub.markDirty(1)\n }\n }\n\n computedNode.depth = maxDepDepth + 1\n return changed\n } finally {\n engine.activeConsumer = prevConsumer\n engine.activeOwner = prevOwner\n engine.cycleDetectionStack.delete(computedNode)\n }\n },\n markDirty: (parentState: number) => {\n if (state >= parentState) return\n state = parentState\n\n for (const sub of subscribers) {\n const rawSub = sub._node || sub\n if (rawSub.type === 'effect') {\n rawSub.isDirty = true\n engine.scheduleEffect(sub)\n } else if (rawSub.markDirty) {\n rawSub.markDirty(1)\n }\n }\n }\n }\n\n const computedInstance: Computed<T> = {\n get value() {\n if (engine.activeConsumer && engine.activeConsumer !== computedNode) {\n computedNode.subscribers.add(engine.activeConsumer)\n engine.activeConsumer.dependencies.add(computedNode)\n }\n\n updateIfNecessary(computedNode)\n\n if (engine.activeConsumer && engine.activeConsumer.depVersions) {\n engine.activeConsumer.depVersions.set(computedInstance, version)\n }\n return value\n },\n get valueWithoutTracking() { return value },\n get version() { return version },\n subscribe(cb: (val: T) => void): CleanupFn {\n const fakeEffect: any = {\n id: engine.subscriberId++,\n isDirty: true,\n depth: 9999,\n dependencies: new Set(),\n type: 'effect',\n run: () => {\n if (fakeEffect.isDisposed) return\n try { cb(computedInstance.value) } catch (err) { console.error(err) }\n }\n }\n computedNode.subscribers.add(fakeEffect)\n cb(computedInstance.value)\n return () => {\n fakeEffect.isDisposed = true\n computedNode.subscribers.delete(fakeEffect)\n }\n },\n subscribeState(cb: () => void): CleanupFn {\n return (computedInstance as any).subscribe(cb)\n },\n destroy: () => {\n computedNode.subscribers.clear()\n releaseNode(computedNode)\n engine.computedCache.delete(fn)\n isDirty = true\n state = 2\n isInitialized = false\n },\n __subscribe(cb: () => void): CleanupFn {\n const hookEffect: any = {\n id: engine.subscriberId++,\n type: 'effect',\n run: cb,\n isDirty: false\n }\n computedNode.subscribers.add(hookEffect)\n return () => {\n subscribers.delete(hookEffect)\n }\n }\n } as any\n\n ;(computedInstance as any)._node = computedNode\n ;(computedInstance as any).subscribers = subscribers\n ;(computedInstance as any).dependencies = dependencies\n computedInstance._isDirty = () => state > 0\n computedInstance.type = 'computed'\n computedInstance.run = () => computedNode.run()\n\n engine.computedCache.set(fn, computedInstance)\n return computedInstance\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- const e=require("./utils/getExtractedValues.cjs");function t(t,n,r){let i=n,a=0,o=typeof r==`string`?r:r?.name,s=!!o&&e.getExtractedValues({tested:[o],expectedKey:`CORE_INTERNAL_SIGNAL`,valueType:`number`})?.[0]===`1`||!1,c=new Set,l=!1,u=n,d={type:`signal`,get version(){return a},subscribers:c},f=()=>{Array.from(c).forEach(e=>{let n=e._node||e;if(n.type===`effect`)n.isDirty=!0,t.scheduleEffect(e);else if(n.type===`computed`)n.markDirty&&n.markDirty(2);else if(typeof e==`function`)try{e(i)}catch(e){console.error(e)}else if(e&&typeof e.run==`function`)try{e.run()}catch(e){console.error(e)}})},p={get value(){return t.activeConsumer&&(c.add(t.activeConsumer),t.activeConsumer.dependencies.add(p)),i},set value(e){if(Object.is(i,e)&&!(i===e&&typeof i==`object`&&i))return;if(r&&typeof r==`object`&&r.validate){let t=r.validate(e);if(t!==!0){console.error(typeof t==`string`?t:`[Validation Error]`);return}}if(t.batchDepth>0){l||(l=!0,u=i),i=e,t.batchedSignals.add(p);return}let n=i;i=e,a++,t.epoch++,t.log({type:`signal`,label:o||`signal`,details:{from:n,to:e},isInternalCoreSignal:s}),f(),t.batchDepth===0&&t.flushEffects()},get version(){return a},type:`signal`,subscribe(e){return c.add(e),e(i),()=>{c.delete(e)}},_flushBatch:()=>{l&&((!Object.is(u,i)||typeof i==`object`&&i)&&(a++,t.epoch++,t.log({type:`signal`,label:o||`signal_batched`,details:{from:u,to:i},isInternalCoreSignal:s}),f()),l=!1,u=i)}};return p._node=d,p.subscribers=c,p}exports.createSignal=t;
1
+ const e=require("./utils/getExtractedValues.cjs");function t(t,n,r){let i=n,a=0,o=typeof r==`string`?r:r?.name,s=!!o&&e.getExtractedValues({tested:[o],expectedKey:`CORE_INTERNAL_SIGNAL`,valueType:`number`})?.[0]===`1`||!1,c=new Set,l=!1,u=n,d={type:`signal`,get version(){return a},subscribers:c},f=()=>{for(let e of c){let n=e._node||e;if(n.type===`effect`)n.isDirty=!0,t.scheduleEffect(e);else if(n.type===`computed`)n.markDirty&&n.markDirty(2);else if(typeof e==`function`)try{e(i)}catch(e){console.error(e)}else if(e&&typeof e.run==`function`)try{e.run()}catch(e){console.error(e)}}},p={get value(){return t.activeConsumer&&(c.add(t.activeConsumer),t.activeConsumer.dependencies.add(p)),i},set value(e){if(Object.is(i,e)&&!(i===e&&typeof i==`object`&&i))return;if(r&&typeof r==`object`&&r.validate){let t=r.validate(e);if(t!==!0){console.error(typeof t==`string`?t:`[Validation Error]`);return}}if(t.batchDepth>0){l||(l=!0,u=i),i=e,t.batchedSignals.add(p);return}let n=i;i=e,a++,t.epoch++,t.log({type:`signal`,label:o||`signal`,details:{from:n,to:e},isInternalCoreSignal:s}),f(),t.batchDepth===0&&t.flushEffects()},get version(){return a},type:`signal`,subscribe(e){return c.add(e),e(i),()=>{c.delete(e)}},_flushBatch:()=>{l&&((!Object.is(u,i)||typeof i==`object`&&i)&&(a++,t.epoch++,t.log({type:`signal`,label:o||`signal_batched`,details:{from:u,to:i},isInternalCoreSignal:s}),f()),l=!1,u=i)}};return p._node=d,p.subscribers=c,p}exports.createSignal=t;
2
2
  //# sourceMappingURL=core.method.signal.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"core.method.signal.cjs","names":[],"sources":["../src/core/core.method.signal.ts"],"sourcesContent":["import { getExtractedValues } from '../utils/getExtractedValues'\nimport { Signal, SignalOptions } from './types'\n\nexport function createSignal<T>(\n engine: any,\n initialValue: T,\n optionsOrName?: SignalOptions<T> | string\n): Signal<T> {\n let value = initialValue\n let version = 0\n let name = typeof optionsOrName === 'string' ? optionsOrName : optionsOrName?.name\n const isInternalCoreSignal = !!name && getExtractedValues({\n tested: [name],\n expectedKey: 'CORE_INTERNAL_SIGNAL',\n valueType: 'number',\n })?.[0] === '1' || false\n const subscribers = new Set<any>()\n\n // Транзакционные слепки\n let hasBatchValue = false\n let batchInitialValue: T = initialValue\n\n const signalNode = {\n type: 'signal',\n get version() { return version },\n subscribers\n }\n\n const notifySubscribers = () => {\n // Делаем безопасную итерацию через создание массива, защищая от удаления на лету\n Array.from(subscribers).forEach((sub: any) => {\n const rawSub = sub._node || sub\n if (rawSub.type === 'effect') {\n rawSub.isDirty = true\n engine.scheduleEffect(sub)\n } else if (rawSub.type === 'computed') {\n if (rawSub.markDirty) rawSub.markDirty(2) // Прямой пин DIRTY\n } else {\n // Обычные внешние подписки (React, Angular, колбэки)\n if (typeof sub === 'function') {\n try { sub(value) } catch (err) { console.error(err) }\n } else if (sub && typeof sub.run === 'function') {\n try { sub.run() } catch (err) { console.error(err) }\n }\n }\n })\n }\n\n const signalInstance: Signal<T> = {\n get value() {\n if (engine.activeConsumer) {\n subscribers.add(engine.activeConsumer)\n engine.activeConsumer.dependencies.add(signalInstance)\n }\n return value\n },\n\n set value(newValue: T) {\n const isObjectKick = value === newValue && value !== null && typeof value === 'object'\n if (Object.is(value, newValue) && !isObjectKick) return\n\n if (optionsOrName && typeof optionsOrName === 'object' && optionsOrName.validate) {\n const validation = optionsOrName.validate(newValue)\n if (validation !== true) {\n console.error(typeof validation === 'string' ? validation : '[Validation Error]')\n return\n }\n }\n\n if (engine.batchDepth > 0) {\n if (!hasBatchValue) {\n hasBatchValue = true\n batchInitialValue = value\n }\n value = newValue\n engine.batchedSignals.add(signalInstance)\n return\n }\n\n const oldValue = value\n value = newValue\n\n version++\n engine.epoch++\n\n engine.log({\n type: 'signal',\n label: name || 'signal',\n details: { from: oldValue, to: newValue },\n isInternalCoreSignal\n })\n\n notifySubscribers()\n if (engine.batchDepth === 0) engine.flushEffects()\n },\n\n get version() { return version },\n type: 'signal',\n\n subscribe(cb: (val: T) => void) {\n subscribers.add(cb)\n cb(value)\n return () => { subscribers.delete(cb) }\n },\n\n _flushBatch: () => {\n if (!hasBatchValue) return\n\n const wasChanged = !Object.is(batchInitialValue, value) || (value !== null && typeof value === 'object')\n\n if (wasChanged) {\n version++\n engine.epoch++\n\n engine.log({\n type: 'signal',\n label: name || 'signal_batched',\n details: { from: batchInitialValue, to: value },\n isInternalCoreSignal\n })\n\n notifySubscribers()\n }\n\n hasBatchValue = false\n batchInitialValue = value\n }\n } as any\n\n ;(signalInstance as any)._node = signalNode\n ;(signalInstance as any).subscribers = subscribers\n return signalInstance\n}\n"],"mappings":"kDAGA,SAAgB,EACd,EACA,EACA,EACW,CACX,IAAI,EAAQ,EACR,EAAU,EACV,EAAO,OAAO,GAAkB,SAAW,EAAgB,GAAe,KACxE,EAAuB,CAAC,CAAC,GAAQ,EAAA,mBAAmB,CACxD,OAAQ,CAAC,CAAI,EACb,YAAa,uBACb,UAAW,QACb,CAAC,CAAC,GAAG,KAAO,KAAO,GACb,EAAc,IAAI,IAGpB,EAAgB,GAChB,EAAuB,EAErB,EAAa,CACjB,KAAM,SACN,IAAI,SAAU,CAAE,OAAO,CAAQ,EAC/B,aACF,EAEM,MAA0B,CAE9B,MAAM,KAAK,CAAW,CAAC,CAAC,QAAS,GAAa,CAC5C,IAAM,EAAS,EAAI,OAAS,EAC5B,GAAI,EAAO,OAAS,SAClB,EAAO,QAAU,GACjB,EAAO,eAAe,CAAG,OACpB,GAAI,EAAO,OAAS,WACrB,EAAO,WAAW,EAAO,UAAU,CAAC,OAGxC,GAAI,OAAO,GAAQ,WACjB,GAAI,CAAE,EAAI,CAAK,CAAE,OAAS,EAAK,CAAE,QAAQ,MAAM,CAAG,CAAE,MAC/C,GAAI,GAAO,OAAO,EAAI,KAAQ,WACnC,GAAI,CAAE,EAAI,IAAI,CAAE,OAAS,EAAK,CAAE,QAAQ,MAAM,CAAG,CAAE,CAGzD,CAAC,CACH,EAEM,EAA4B,CAChC,IAAI,OAAQ,CAKV,OAJI,EAAO,iBACT,EAAY,IAAI,EAAO,cAAc,EACrC,EAAO,eAAe,aAAa,IAAI,CAAc,GAEhD,CACT,EAEA,IAAI,MAAM,EAAa,CAErB,GAAI,OAAO,GAAG,EAAO,CAAQ,GAAK,EADb,IAAU,GAA8B,OAAO,GAAU,UAAnC,GACM,OAEjD,GAAI,GAAiB,OAAO,GAAkB,UAAY,EAAc,SAAU,CAChF,IAAM,EAAa,EAAc,SAAS,CAAQ,EAClD,GAAI,IAAe,GAAM,CACvB,QAAQ,MAAM,OAAO,GAAe,SAAW,EAAa,oBAAoB,EAChF,MACF,CACF,CAEA,GAAI,EAAO,WAAa,EAAG,CACpB,IACH,EAAgB,GAChB,EAAoB,GAEtB,EAAQ,EACR,EAAO,eAAe,IAAI,CAAc,EACxC,MACF,CAEA,IAAM,EAAW,EACjB,EAAQ,EAER,IACA,EAAO,QAEP,EAAO,IAAI,CACT,KAAM,SACN,MAAO,GAAQ,SACf,QAAS,CAAE,KAAM,EAAU,GAAI,CAAS,EACxC,sBACF,CAAC,EAED,EAAkB,EACd,EAAO,aAAe,GAAG,EAAO,aAAa,CACnD,EAEA,IAAI,SAAU,CAAE,OAAO,CAAQ,EAC/B,KAAM,SAEN,UAAU,EAAsB,CAG9B,OAFA,EAAY,IAAI,CAAE,EAClB,EAAG,CAAK,MACK,CAAE,EAAY,OAAO,CAAE,CAAE,CACxC,EAEA,gBAAmB,CACZ,KAEc,CAAC,OAAO,GAAG,EAAmB,CAAK,GAAwB,OAAO,GAAU,UAAnC,KAG1D,IACA,EAAO,QAEP,EAAO,IAAI,CACT,KAAM,SACN,MAAO,GAAQ,iBACf,QAAS,CAAE,KAAM,EAAmB,GAAI,CAAM,EAC9C,sBACF,CAAC,EAED,EAAkB,GAGpB,EAAgB,GAChB,EAAoB,EACtB,CACF,EAIA,MAFC,GAAwB,MAAQ,EAChC,EAAwB,YAAc,EAChC,CACT"}
1
+ {"version":3,"file":"core.method.signal.cjs","names":[],"sources":["../src/core/core.method.signal.ts"],"sourcesContent":["import { getExtractedValues } from '../utils/getExtractedValues'\nimport { Signal, SignalOptions } from './types'\n\nexport function createSignal<T>(\n engine: any,\n initialValue: T,\n optionsOrName?: SignalOptions<T> | string\n): Signal<T> {\n let value = initialValue\n let version = 0\n let name = typeof optionsOrName === 'string' ? optionsOrName : optionsOrName?.name\n const isInternalCoreSignal = !!name && getExtractedValues({\n tested: [name],\n expectedKey: 'CORE_INTERNAL_SIGNAL',\n valueType: 'number',\n })?.[0] === '1' || false\n const subscribers = new Set<any>()\n\n let hasBatchValue = false\n let batchInitialValue: T = initialValue\n\n const signalNode = {\n type: 'signal',\n get version() { return version },\n subscribers\n }\n\n const notifySubscribers = () => {\n // ⚡ Максимальное ускорение: Прямой проход по Set через for...of (без Array.from)\n for (const sub of subscribers) {\n const rawSub = sub._node || sub\n if (rawSub.type === 'effect') {\n rawSub.isDirty = true\n engine.scheduleEffect(sub)\n } else if (rawSub.type === 'computed') {\n if (rawSub.markDirty) rawSub.markDirty(2)\n } else {\n if (typeof sub === 'function') {\n try { sub(value) } catch (err) { console.error(err) }\n } else if (sub && typeof sub.run === 'function') {\n try { sub.run() } catch (err) { console.error(err) }\n }\n }\n }\n }\n\n const signalInstance: Signal<T> = {\n get value() {\n if (engine.activeConsumer) {\n subscribers.add(engine.activeConsumer)\n engine.activeConsumer.dependencies.add(signalInstance)\n }\n return value\n },\n\n set value(newValue: T) {\n const isObjectKick = value === newValue && value !== null && typeof value === 'object'\n if (Object.is(value, newValue) && !isObjectKick) return\n\n if (optionsOrName && typeof optionsOrName === 'object' && optionsOrName.validate) {\n const validation = optionsOrName.validate(newValue)\n if (validation !== true) {\n console.error(typeof validation === 'string' ? validation : '[Validation Error]')\n return\n }\n }\n\n if (engine.batchDepth > 0) {\n if (!hasBatchValue) {\n hasBatchValue = true\n batchInitialValue = value\n }\n value = newValue\n engine.batchedSignals.add(signalInstance)\n return\n }\n\n const oldValue = value\n value = newValue\n\n version++\n engine.epoch++\n\n engine.log({\n type: 'signal',\n label: name || 'signal',\n details: { from: oldValue, to: newValue },\n isInternalCoreSignal\n })\n\n notifySubscribers()\n if (engine.batchDepth === 0) engine.flushEffects()\n },\n\n get version() { return version },\n type: 'signal',\n\n subscribe(cb: (val: T) => void) {\n subscribers.add(cb)\n cb(value)\n return () => { subscribers.delete(cb) }\n },\n\n _flushBatch: () => {\n if (!hasBatchValue) return\n\n const wasChanged = !Object.is(batchInitialValue, value) || (value !== null && typeof value === 'object')\n\n if (wasChanged) {\n version++\n engine.epoch++\n\n engine.log({\n type: 'signal',\n label: name || 'signal_batched',\n details: { from: batchInitialValue, to: value },\n isInternalCoreSignal\n })\n\n notifySubscribers()\n }\n\n hasBatchValue = false\n batchInitialValue = value\n }\n } as any\n\n ;(signalInstance as any)._node = signalNode\n ;(signalInstance as any).subscribers = subscribers\n return signalInstance\n}\n"],"mappings":"kDAGA,SAAgB,EACd,EACA,EACA,EACW,CACX,IAAI,EAAQ,EACR,EAAU,EACV,EAAO,OAAO,GAAkB,SAAW,EAAgB,GAAe,KACxE,EAAuB,CAAC,CAAC,GAAQ,EAAA,mBAAmB,CACxD,OAAQ,CAAC,CAAI,EACb,YAAa,uBACb,UAAW,QACb,CAAC,CAAC,GAAG,KAAO,KAAO,GACb,EAAc,IAAI,IAEpB,EAAgB,GAChB,EAAuB,EAErB,EAAa,CACjB,KAAM,SACN,IAAI,SAAU,CAAE,OAAO,CAAQ,EAC/B,aACF,EAEM,MAA0B,CAE9B,IAAK,IAAM,KAAO,EAAa,CAC7B,IAAM,EAAS,EAAI,OAAS,EAC5B,GAAI,EAAO,OAAS,SAClB,EAAO,QAAU,GACjB,EAAO,eAAe,CAAG,OACpB,GAAI,EAAO,OAAS,WACrB,EAAO,WAAW,EAAO,UAAU,CAAC,OAExC,GAAI,OAAO,GAAQ,WACjB,GAAI,CAAE,EAAI,CAAK,CAAE,OAAS,EAAK,CAAE,QAAQ,MAAM,CAAG,CAAE,MAC/C,GAAI,GAAO,OAAO,EAAI,KAAQ,WACnC,GAAI,CAAE,EAAI,IAAI,CAAE,OAAS,EAAK,CAAE,QAAQ,MAAM,CAAG,CAAE,CAGzD,CACF,EAEM,EAA4B,CAChC,IAAI,OAAQ,CAKV,OAJI,EAAO,iBACT,EAAY,IAAI,EAAO,cAAc,EACrC,EAAO,eAAe,aAAa,IAAI,CAAc,GAEhD,CACT,EAEA,IAAI,MAAM,EAAa,CAErB,GAAI,OAAO,GAAG,EAAO,CAAQ,GAAK,EADb,IAAU,GAA8B,OAAO,GAAU,UAAnC,GACM,OAEjD,GAAI,GAAiB,OAAO,GAAkB,UAAY,EAAc,SAAU,CAChF,IAAM,EAAa,EAAc,SAAS,CAAQ,EAClD,GAAI,IAAe,GAAM,CACvB,QAAQ,MAAM,OAAO,GAAe,SAAW,EAAa,oBAAoB,EAChF,MACF,CACF,CAEA,GAAI,EAAO,WAAa,EAAG,CACpB,IACH,EAAgB,GAChB,EAAoB,GAEtB,EAAQ,EACR,EAAO,eAAe,IAAI,CAAc,EACxC,MACF,CAEA,IAAM,EAAW,EACjB,EAAQ,EAER,IACA,EAAO,QAEP,EAAO,IAAI,CACT,KAAM,SACN,MAAO,GAAQ,SACf,QAAS,CAAE,KAAM,EAAU,GAAI,CAAS,EACxC,sBACF,CAAC,EAED,EAAkB,EACd,EAAO,aAAe,GAAG,EAAO,aAAa,CACnD,EAEA,IAAI,SAAU,CAAE,OAAO,CAAQ,EAC/B,KAAM,SAEN,UAAU,EAAsB,CAG9B,OAFA,EAAY,IAAI,CAAE,EAClB,EAAG,CAAK,MACK,CAAE,EAAY,OAAO,CAAE,CAAE,CACxC,EAEA,gBAAmB,CACZ,KAEc,CAAC,OAAO,GAAG,EAAmB,CAAK,GAAwB,OAAO,GAAU,UAAnC,KAG1D,IACA,EAAO,QAEP,EAAO,IAAI,CACT,KAAM,SACN,MAAO,GAAQ,iBACf,QAAS,CAAE,KAAM,EAAmB,GAAI,CAAM,EAC9C,sBACF,CAAC,EAED,EAAkB,GAGpB,EAAgB,GAChB,EAAoB,EACtB,CACF,EAIA,MAFC,GAAwB,MAAQ,EAChC,EAAwB,YAAc,EAChC,CACT"}
@@ -12,7 +12,7 @@ function t(t, n, r) {
12
12
  },
13
13
  subscribers: c
14
14
  }, f = () => {
15
- Array.from(c).forEach((e) => {
15
+ for (let e of c) {
16
16
  let n = e._node || e;
17
17
  if (n.type === "effect") n.isDirty = !0, t.scheduleEffect(e);
18
18
  else if (n.type === "computed") n.markDirty && n.markDirty(2);
@@ -26,7 +26,7 @@ function t(t, n, r) {
26
26
  } catch (e) {
27
27
  console.error(e);
28
28
  }
29
- });
29
+ }
30
30
  }, p = {
31
31
  get value() {
32
32
  return t.activeConsumer && (c.add(t.activeConsumer), t.activeConsumer.dependencies.add(p)), i;
@@ -1 +1 @@
1
- {"version":3,"file":"core.method.signal.mjs","names":[],"sources":["../src/core/core.method.signal.ts"],"sourcesContent":["import { getExtractedValues } from '../utils/getExtractedValues'\nimport { Signal, SignalOptions } from './types'\n\nexport function createSignal<T>(\n engine: any,\n initialValue: T,\n optionsOrName?: SignalOptions<T> | string\n): Signal<T> {\n let value = initialValue\n let version = 0\n let name = typeof optionsOrName === 'string' ? optionsOrName : optionsOrName?.name\n const isInternalCoreSignal = !!name && getExtractedValues({\n tested: [name],\n expectedKey: 'CORE_INTERNAL_SIGNAL',\n valueType: 'number',\n })?.[0] === '1' || false\n const subscribers = new Set<any>()\n\n // Транзакционные слепки\n let hasBatchValue = false\n let batchInitialValue: T = initialValue\n\n const signalNode = {\n type: 'signal',\n get version() { return version },\n subscribers\n }\n\n const notifySubscribers = () => {\n // Делаем безопасную итерацию через создание массива, защищая от удаления на лету\n Array.from(subscribers).forEach((sub: any) => {\n const rawSub = sub._node || sub\n if (rawSub.type === 'effect') {\n rawSub.isDirty = true\n engine.scheduleEffect(sub)\n } else if (rawSub.type === 'computed') {\n if (rawSub.markDirty) rawSub.markDirty(2) // Прямой пин DIRTY\n } else {\n // Обычные внешние подписки (React, Angular, колбэки)\n if (typeof sub === 'function') {\n try { sub(value) } catch (err) { console.error(err) }\n } else if (sub && typeof sub.run === 'function') {\n try { sub.run() } catch (err) { console.error(err) }\n }\n }\n })\n }\n\n const signalInstance: Signal<T> = {\n get value() {\n if (engine.activeConsumer) {\n subscribers.add(engine.activeConsumer)\n engine.activeConsumer.dependencies.add(signalInstance)\n }\n return value\n },\n\n set value(newValue: T) {\n const isObjectKick = value === newValue && value !== null && typeof value === 'object'\n if (Object.is(value, newValue) && !isObjectKick) return\n\n if (optionsOrName && typeof optionsOrName === 'object' && optionsOrName.validate) {\n const validation = optionsOrName.validate(newValue)\n if (validation !== true) {\n console.error(typeof validation === 'string' ? validation : '[Validation Error]')\n return\n }\n }\n\n if (engine.batchDepth > 0) {\n if (!hasBatchValue) {\n hasBatchValue = true\n batchInitialValue = value\n }\n value = newValue\n engine.batchedSignals.add(signalInstance)\n return\n }\n\n const oldValue = value\n value = newValue\n\n version++\n engine.epoch++\n\n engine.log({\n type: 'signal',\n label: name || 'signal',\n details: { from: oldValue, to: newValue },\n isInternalCoreSignal\n })\n\n notifySubscribers()\n if (engine.batchDepth === 0) engine.flushEffects()\n },\n\n get version() { return version },\n type: 'signal',\n\n subscribe(cb: (val: T) => void) {\n subscribers.add(cb)\n cb(value)\n return () => { subscribers.delete(cb) }\n },\n\n _flushBatch: () => {\n if (!hasBatchValue) return\n\n const wasChanged = !Object.is(batchInitialValue, value) || (value !== null && typeof value === 'object')\n\n if (wasChanged) {\n version++\n engine.epoch++\n\n engine.log({\n type: 'signal',\n label: name || 'signal_batched',\n details: { from: batchInitialValue, to: value },\n isInternalCoreSignal\n })\n\n notifySubscribers()\n }\n\n hasBatchValue = false\n batchInitialValue = value\n }\n } as any\n\n ;(signalInstance as any)._node = signalNode\n ;(signalInstance as any).subscribers = subscribers\n return signalInstance\n}\n"],"mappings":";;AAGA,SAAgB,EACd,GACA,GACA,GACW;CACX,IAAI,IAAQ,GACR,IAAU,GACV,IAAO,OAAO,KAAkB,WAAW,IAAgB,GAAe,MACxE,IAAuB,CAAC,CAAC,KAAQ,EAAmB;EACxD,QAAQ,CAAC,CAAI;EACb,aAAa;EACb,WAAW;CACb,CAAC,CAAC,GAAG,OAAO,OAAO,IACb,oBAAc,IAAI,IAAS,GAG7B,IAAgB,IAChB,IAAuB,GAErB,IAAa;EACjB,MAAM;EACN,IAAI,UAAU;GAAE,OAAO;EAAQ;EAC/B;CACF,GAEM,UAA0B;EAE9B,MAAM,KAAK,CAAW,CAAC,CAAC,SAAS,MAAa;GAC5C,IAAM,IAAS,EAAI,SAAS;GAC5B,IAAI,EAAO,SAAS,UAElB,AADA,EAAO,UAAU,IACjB,EAAO,eAAe,CAAG;QACpB,IAAI,EAAO,SAAS,YACrB,EAAO,aAAW,EAAO,UAAU,CAAC;QAGxC,IAAI,OAAO,KAAQ,YACjB,IAAI;IAAE,EAAI,CAAK;GAAE,SAAS,GAAK;IAAE,QAAQ,MAAM,CAAG;GAAE;QAC/C,IAAI,KAAO,OAAO,EAAI,OAAQ,YACnC,IAAI;IAAE,EAAI,IAAI;GAAE,SAAS,GAAK;IAAE,QAAQ,MAAM,CAAG;GAAE;EAGzD,CAAC;CACH,GAEM,IAA4B;EAChC,IAAI,QAAQ;GAKV,OAJI,EAAO,mBACT,EAAY,IAAI,EAAO,cAAc,GACrC,EAAO,eAAe,aAAa,IAAI,CAAc,IAEhD;EACT;EAEA,IAAI,MAAM,GAAa;GAErB,IAAI,OAAO,GAAG,GAAO,CAAQ,KAAK,EADb,MAAU,KAA8B,OAAO,KAAU,YAAnC,IACM;GAEjD,IAAI,KAAiB,OAAO,KAAkB,YAAY,EAAc,UAAU;IAChF,IAAM,IAAa,EAAc,SAAS,CAAQ;IAClD,IAAI,MAAe,IAAM;KACvB,QAAQ,MAAM,OAAO,KAAe,WAAW,IAAa,oBAAoB;KAChF;IACF;GACF;GAEA,IAAI,EAAO,aAAa,GAAG;IAMzB,AALK,MACH,IAAgB,IAChB,IAAoB,IAEtB,IAAQ,GACR,EAAO,eAAe,IAAI,CAAc;IACxC;GACF;GAEA,IAAM,IAAW;GAcjB,AAbA,IAAQ,GAER,KACA,EAAO,SAEP,EAAO,IAAI;IACT,MAAM;IACN,OAAO,KAAQ;IACf,SAAS;KAAE,MAAM;KAAU,IAAI;IAAS;IACxC;GACF,CAAC,GAED,EAAkB,GACd,EAAO,eAAe,KAAG,EAAO,aAAa;EACnD;EAEA,IAAI,UAAU;GAAE,OAAO;EAAQ;EAC/B,MAAM;EAEN,UAAU,GAAsB;GAG9B,OAFA,EAAY,IAAI,CAAE,GAClB,EAAG,CAAK,SACK;IAAE,EAAY,OAAO,CAAE;GAAE;EACxC;EAEA,mBAAmB;GACZ,OAEc,CAAC,OAAO,GAAG,GAAmB,CAAK,KAAwB,OAAO,KAAU,YAAnC,OAG1D,KACA,EAAO,SAEP,EAAO,IAAI;IACT,MAAM;IACN,OAAO,KAAQ;IACf,SAAS;KAAE,MAAM;KAAmB,IAAI;IAAM;IAC9C;GACF,CAAC,GAED,EAAkB,IAGpB,IAAgB,IAChB,IAAoB;EACtB;CACF;CAIA,OAFC,EAAwB,QAAQ,GAChC,EAAwB,cAAc,GAChC;AACT"}
1
+ {"version":3,"file":"core.method.signal.mjs","names":[],"sources":["../src/core/core.method.signal.ts"],"sourcesContent":["import { getExtractedValues } from '../utils/getExtractedValues'\nimport { Signal, SignalOptions } from './types'\n\nexport function createSignal<T>(\n engine: any,\n initialValue: T,\n optionsOrName?: SignalOptions<T> | string\n): Signal<T> {\n let value = initialValue\n let version = 0\n let name = typeof optionsOrName === 'string' ? optionsOrName : optionsOrName?.name\n const isInternalCoreSignal = !!name && getExtractedValues({\n tested: [name],\n expectedKey: 'CORE_INTERNAL_SIGNAL',\n valueType: 'number',\n })?.[0] === '1' || false\n const subscribers = new Set<any>()\n\n let hasBatchValue = false\n let batchInitialValue: T = initialValue\n\n const signalNode = {\n type: 'signal',\n get version() { return version },\n subscribers\n }\n\n const notifySubscribers = () => {\n // ⚡ Максимальное ускорение: Прямой проход по Set через for...of (без Array.from)\n for (const sub of subscribers) {\n const rawSub = sub._node || sub\n if (rawSub.type === 'effect') {\n rawSub.isDirty = true\n engine.scheduleEffect(sub)\n } else if (rawSub.type === 'computed') {\n if (rawSub.markDirty) rawSub.markDirty(2)\n } else {\n if (typeof sub === 'function') {\n try { sub(value) } catch (err) { console.error(err) }\n } else if (sub && typeof sub.run === 'function') {\n try { sub.run() } catch (err) { console.error(err) }\n }\n }\n }\n }\n\n const signalInstance: Signal<T> = {\n get value() {\n if (engine.activeConsumer) {\n subscribers.add(engine.activeConsumer)\n engine.activeConsumer.dependencies.add(signalInstance)\n }\n return value\n },\n\n set value(newValue: T) {\n const isObjectKick = value === newValue && value !== null && typeof value === 'object'\n if (Object.is(value, newValue) && !isObjectKick) return\n\n if (optionsOrName && typeof optionsOrName === 'object' && optionsOrName.validate) {\n const validation = optionsOrName.validate(newValue)\n if (validation !== true) {\n console.error(typeof validation === 'string' ? validation : '[Validation Error]')\n return\n }\n }\n\n if (engine.batchDepth > 0) {\n if (!hasBatchValue) {\n hasBatchValue = true\n batchInitialValue = value\n }\n value = newValue\n engine.batchedSignals.add(signalInstance)\n return\n }\n\n const oldValue = value\n value = newValue\n\n version++\n engine.epoch++\n\n engine.log({\n type: 'signal',\n label: name || 'signal',\n details: { from: oldValue, to: newValue },\n isInternalCoreSignal\n })\n\n notifySubscribers()\n if (engine.batchDepth === 0) engine.flushEffects()\n },\n\n get version() { return version },\n type: 'signal',\n\n subscribe(cb: (val: T) => void) {\n subscribers.add(cb)\n cb(value)\n return () => { subscribers.delete(cb) }\n },\n\n _flushBatch: () => {\n if (!hasBatchValue) return\n\n const wasChanged = !Object.is(batchInitialValue, value) || (value !== null && typeof value === 'object')\n\n if (wasChanged) {\n version++\n engine.epoch++\n\n engine.log({\n type: 'signal',\n label: name || 'signal_batched',\n details: { from: batchInitialValue, to: value },\n isInternalCoreSignal\n })\n\n notifySubscribers()\n }\n\n hasBatchValue = false\n batchInitialValue = value\n }\n } as any\n\n ;(signalInstance as any)._node = signalNode\n ;(signalInstance as any).subscribers = subscribers\n return signalInstance\n}\n"],"mappings":";;AAGA,SAAgB,EACd,GACA,GACA,GACW;CACX,IAAI,IAAQ,GACR,IAAU,GACV,IAAO,OAAO,KAAkB,WAAW,IAAgB,GAAe,MACxE,IAAuB,CAAC,CAAC,KAAQ,EAAmB;EACxD,QAAQ,CAAC,CAAI;EACb,aAAa;EACb,WAAW;CACb,CAAC,CAAC,GAAG,OAAO,OAAO,IACb,oBAAc,IAAI,IAAS,GAE7B,IAAgB,IAChB,IAAuB,GAErB,IAAa;EACjB,MAAM;EACN,IAAI,UAAU;GAAE,OAAO;EAAQ;EAC/B;CACF,GAEM,UAA0B;EAE9B,KAAK,IAAM,KAAO,GAAa;GAC7B,IAAM,IAAS,EAAI,SAAS;GAC5B,IAAI,EAAO,SAAS,UAElB,AADA,EAAO,UAAU,IACjB,EAAO,eAAe,CAAG;QACpB,IAAI,EAAO,SAAS,YACrB,EAAO,aAAW,EAAO,UAAU,CAAC;QAExC,IAAI,OAAO,KAAQ,YACjB,IAAI;IAAE,EAAI,CAAK;GAAE,SAAS,GAAK;IAAE,QAAQ,MAAM,CAAG;GAAE;QAC/C,IAAI,KAAO,OAAO,EAAI,OAAQ,YACnC,IAAI;IAAE,EAAI,IAAI;GAAE,SAAS,GAAK;IAAE,QAAQ,MAAM,CAAG;GAAE;EAGzD;CACF,GAEM,IAA4B;EAChC,IAAI,QAAQ;GAKV,OAJI,EAAO,mBACT,EAAY,IAAI,EAAO,cAAc,GACrC,EAAO,eAAe,aAAa,IAAI,CAAc,IAEhD;EACT;EAEA,IAAI,MAAM,GAAa;GAErB,IAAI,OAAO,GAAG,GAAO,CAAQ,KAAK,EADb,MAAU,KAA8B,OAAO,KAAU,YAAnC,IACM;GAEjD,IAAI,KAAiB,OAAO,KAAkB,YAAY,EAAc,UAAU;IAChF,IAAM,IAAa,EAAc,SAAS,CAAQ;IAClD,IAAI,MAAe,IAAM;KACvB,QAAQ,MAAM,OAAO,KAAe,WAAW,IAAa,oBAAoB;KAChF;IACF;GACF;GAEA,IAAI,EAAO,aAAa,GAAG;IAMzB,AALK,MACH,IAAgB,IAChB,IAAoB,IAEtB,IAAQ,GACR,EAAO,eAAe,IAAI,CAAc;IACxC;GACF;GAEA,IAAM,IAAW;GAcjB,AAbA,IAAQ,GAER,KACA,EAAO,SAEP,EAAO,IAAI;IACT,MAAM;IACN,OAAO,KAAQ;IACf,SAAS;KAAE,MAAM;KAAU,IAAI;IAAS;IACxC;GACF,CAAC,GAED,EAAkB,GACd,EAAO,eAAe,KAAG,EAAO,aAAa;EACnD;EAEA,IAAI,UAAU;GAAE,OAAO;EAAQ;EAC/B,MAAM;EAEN,UAAU,GAAsB;GAG9B,OAFA,EAAY,IAAI,CAAE,GAClB,EAAG,CAAK,SACK;IAAE,EAAY,OAAO,CAAE;GAAE;EACxC;EAEA,mBAAmB;GACZ,OAEc,CAAC,OAAO,GAAG,GAAmB,CAAK,KAAwB,OAAO,KAAU,YAAnC,OAG1D,KACA,EAAO,SAEP,EAAO,IAAI;IACT,MAAM;IACN,OAAO,KAAQ;IACf,SAAS;KAAE,MAAM;KAAmB,IAAI;IAAM;IAC9C;GACF,CAAC,GAED,EAAkB,IAGpB,IAAgB,IAChB,IAAoB;EACtB;CACF;CAIA,OAFC,EAAwB,QAAQ,GAChC,EAAwB,cAAc,GAChC;AACT"}