@pravosleva/reactive-engine 2.5.0-alpha.4 → 2.5.0-alpha.6
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.
- package/dist/angular/index.cjs +1 -1
- package/dist/angular/index.cjs.map +1 -1
- package/dist/angular/index.mjs +1 -1
- package/dist/core/core.d.ts +8 -16
- package/dist/core/core.d.ts.map +1 -1
- package/dist/core/core.method.computed.d.ts.map +1 -1
- package/dist/core/core.method.reactive.d.ts +0 -3
- package/dist/core/core.method.reactive.d.ts.map +1 -1
- package/dist/core/core.method.signal.d.ts.map +1 -1
- package/dist/core/index.d.ts +0 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core.automatic.cjs +1 -1
- package/dist/core.automatic.cjs.map +1 -1
- package/dist/core.automatic.mjs +1 -1
- package/dist/core.cjs +1 -1
- package/dist/core.cjs.map +1 -1
- package/dist/core.global.cjs +1 -1
- package/dist/core.global.cjs.map +1 -1
- package/dist/core.global.mjs +1 -1
- package/dist/core.method.computed.cjs +1 -1
- package/dist/core.method.computed.cjs.map +1 -1
- package/dist/core.method.computed.mjs +68 -69
- package/dist/core.method.computed.mjs.map +1 -1
- package/dist/core.method.reactive.cjs +1 -1
- package/dist/core.method.reactive.cjs.map +1 -1
- package/dist/core.method.reactive.mjs +104 -45
- package/dist/core.method.reactive.mjs.map +1 -1
- package/dist/core.method.signal.cjs +1 -1
- package/dist/core.method.signal.cjs.map +1 -1
- package/dist/core.method.signal.mjs +38 -64
- package/dist/core.method.signal.mjs.map +1 -1
- package/dist/core.mjs +86 -192
- package/dist/core.mjs.map +1 -1
- package/dist/decorators/withThrottleComputed/withThrottleComputed.d.ts +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index2.cjs +1 -1
- package/dist/index2.mjs +5 -5
- package/dist/react/index.cjs +1 -1
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.mjs +1 -1
- package/dist/reactive-engine@2.5.0-alpha.6.umd.js +13 -0
- package/dist/reactive-engine@2.5.0-alpha.6.umd.js.map +1 -0
- package/dist/vue/index.cjs +1 -1
- package/dist/vue/index.cjs.map +1 -1
- package/dist/vue/index.mjs +1 -1
- package/package.json +1 -1
- package/dist/core.logger.cjs +0 -2
- package/dist/core.logger.cjs.map +0 -1
- package/dist/core.logger.mjs +0 -48
- package/dist/core.logger.mjs.map +0 -1
- package/dist/reactive-engine@2.5.0-alpha.4.umd.js +0 -13
- package/dist/reactive-engine@2.5.0-alpha.4.umd.js.map +0 -1
package/dist/core.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"core.mjs","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\n // ⚡ БЕЗОПАСНЫЙ TS-БАЙПАС: Динамически инкрементируем счетчик итерации\n if (!(this as any).batchIterationId) (this as any).batchIterationId = 0\n ;(this as any).batchIterationId++\n\n try {\n return fn()\n } finally {\n this.batchDepth--\n if (this.batchDepth === 0) {\n if (this.batchedSignals.size > 0) {\n for (const sig of this.batchedSignals) {\n if (sig._flushBatch) sig._flushBatch()\n }\n this.batchedSignals.clear()\n }\n\n this.flushEffects()\n\n // Полностью уничтожаем временный кэш итерации\n if ((this as any).batchComputedCache) {\n (this as any).batchComputedCache.clear();\n (this as any).batchComputedCache = null\n }\n }\n }\n }\n\n public flushEffects(): void {\n if (this.batchDepth > 0) return\n\n const prevConsumer = this.activeConsumer\n\n try {\n for (let depth = 0; depth <= this.maxPendingDepth; depth++) {\n const bucket = this.pendingEffects[depth]\n\n if (!bucket || bucket.size === 0) continue\n\n const effects = Array.from(bucket)\n bucket.clear()\n\n for (const effect of effects) {\n if (effect.isDisposed) continue\n\n // ⚡ ЗOЛОТOЙ СТАНДАРТ ОПТИМИЗАЦИИ (Early Dirty Check Bypass):\n // Переносим проверку грязи в самое начало цикла. Если эффект не был промаркирован\n // как DIRTY волной push-уведомлений, мы мгновенно пропускаем его, полностью\n // избавляя V8 от холостого обхода родителей и тяжелых хэш-поисков depVersions.get(dep).\n if (!effect.isDirty) continue\n\n if (effect.dependencies && effect.dependencies.size > 0) {\n let parentChanged = false\n\n for (const dep of effect.dependencies) {\n const rawNode = dep._node || dep\n\n if (rawNode.type === 'computed' && rawNode.state > 0) {\n if (rawNode.update) rawNode.update()\n }\n\n if (effect.depVersions && effect.depVersions.get(dep) !== rawNode.version) {\n parentChanged = true\n }\n }\n\n if (!parentChanged && effect.dependencies.size > 0) {\n effect.isDirty = false\n continue\n }\n }\n\n // Оригинальная проверка снизу убирается, так как она теперь стоит сверху\n try {\n effect.run()\n } catch (err) {\n throw err\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) depth = -1\n }\n }\n this.maxPendingDepth = 0\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
|
+
{"version":3,"file":"core.mjs","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'\nimport { executeUntrack } from './core.method.untrack'\nimport { createReactive } from './core.method.reactive'\nimport { createEffect } from './core.method.effect'\nimport { ReactiveDebounceLogger } from './core.logger'\n\ntype Constructor<T> = new (...args: any[]) => T\ntype Factory<T> = (engine: any) => T\ntype InjectionToken<T> = Constructor<T> | Factory<T> | symbol | string\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 public computedStringCache = new Map<string, 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 public cycleDetectionStack = new Set<unknown>()\n public batchedSignals = new Set<any>()\n public activeOwner: any = null\n public pendingCleanups = new Set<() => void>()\n public isLoggingEnabled = false\n public _poolArr: any[] = []\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 this.isLoggingEnabled = !!this.logger.isEnabled\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 batch<T>(fn: () => T): T {\n this.batchDepth++\n try {\n return fn()\n } finally {\n this.batchDepth--\n if (this.batchDepth === 0) {\n if (!(this as any).batchIterationId) (this as any).batchIterationId = 0\n ;(this as any).batchIterationId++\n\n if (this.batchedSignals.size > 0) {\n const changeFlags = new Map<any, boolean>()\n\n // Фаза 1: Фиксация версий\n for (const sig of this.batchedSignals) {\n if (sig._applyBatchValue) {\n changeFlags.set(sig, sig._applyBatchValue())\n }\n }\n\n // Атомарный сдвиг общей макро-эпохи ядра\n this.epoch++\n\n // Фаза 2: Каскадный пуш\n for (const sig of this.batchedSignals) {\n if (sig._flushBatch) {\n const changed = changeFlags.get(sig) ?? false\n sig._flushBatch(changed, true)\n }\n }\n this.batchedSignals.clear()\n }\n\n // Запускаем планировщик под единым защищенным барьером итерации\n this.flushEffects()\n }\n }\n }\n\n public flushEffects(): void {\n if (this.batchDepth > 0) return\n const prevConsumer = this.activeConsumer\n\n try {\n for (let depth = 0; depth <= this.maxPendingDepth; depth++) {\n const bucket = this.pendingEffects[depth]\n if (!bucket || bucket.size === 0) continue\n\n const effects = Array.from(bucket)\n bucket.clear()\n\n for (const effect of effects) {\n if (effect.isDisposed) continue\n if (!effect.isDirty) continue\n\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 try {\n effect.run()\n } catch (err) {\n throw err\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) depth = -1\n }\n }\n this.maxPendingDepth = 0\n } finally {\n this.activeConsumer = prevConsumer\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 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 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 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 ? ((optionsOrName as ResourceOptions<T, S>).name || 'unnamed_resource') : (optionsOrName as string) || 'unnamed_resource'\n\n const options: Partial<ResourceOptions<T, S>> = isOptionsObject ? (optionsOrName as ResourceOptions<T, S>) : {}\n const resetDataOnSourceChange = options.resetDataOnSourceChange ?? true\n const responseValidate = options.responseValidate\n const validateBeforeFetch = options.validateBeforeFetch\n\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 load = async (sValue: S, effectSignal: AbortSignal, isSourceChange = false) => {\n if (effectSignal.aborted) return\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' ? preValidationResult : 'Pre-fetch validation failed'\n state.value = { data: isSourceChange ? null : state.value.data, loading: false, error: errorMsg, isRetrying: false }\n return\n }\n }\n\n state.value = { data: (isSourceChange && resetDataOnSourceChange) ? null : state.value.data, loading: true, error: null, isRetrying: false }\n\n try {\n const data = await fetcher(sValue, effectSignal)\n if (effectSignal.aborted) return\n if (responseValidate) {\n const validationResult = responseValidate(data)\n if (validationResult === false || typeof validationResult === 'string') {\n const errorMsg = typeof validationResult === 'string' ? validationResult : 'Validation failed'\n state.value = { data: null, loading: false, error: errorMsg, isRetrying: false }\n return\n }\n }\n state.value = { data, loading: false, error: null, isRetrying: false }\n } catch (e: any) {\n if (effectSignal.aborted) return\n state.value = { data: null, loading: false, error: e.message || 'Fetch error', isRetrying: false }\n }\n }\n\n let activeController: AbortController | null = null\n\n this.effect(() => {\n const sValue = source ? source.value : undefined as S\n const controller = new AbortController()\n activeController = controller\n\n this.untrack(() => {\n load(sValue, controller.signal, true)\n })\n\n return () => controller.abort()\n })\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 activeController?.abort()\n const controller = new AbortController()\n activeController = controller\n load(source ? source.value : undefined as S, controller.signal, false)\n },\n subscribe: (cb: (val: ResourceState<T>) => void) => state.subscribe(cb)\n }\n }\n\n}\n\nexport class ReactiveEngineAutomatic extends ReactiveEngineCore {}\n"],"mappings":"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"}
|
|
@@ -58,7 +58,7 @@ interface ThrottleComputedOptions {
|
|
|
58
58
|
*/
|
|
59
59
|
export declare const withThrottleComputed: <T>(engine: ReactiveEngine, getter: () => T, options: ThrottleComputedOptions, signalName?: string) => {
|
|
60
60
|
readonly value: T;
|
|
61
|
-
subscribe: (cb: (val: T) => void) =>
|
|
61
|
+
subscribe: (cb: (val: T) => void) => any;
|
|
62
62
|
destroy: () => void;
|
|
63
63
|
};
|
|
64
64
|
export {};
|
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./core.cjs"),t=require("./core.automatic.cjs"),n=require("./core.autolog.cjs"),r=require("./core.global.cjs"),i=require("./AbstractService.cjs"),a=require("./BaseREServiceEnhanced.cjs"),o=require("./decorators/withCache/withCache.cjs"),s=require("./decorators/withDebounce/withDebounce.cjs"),c=require("./decorators/withLongPolling/withLongPolling.cjs"),l=require("./decorators/withThrottle/withThrottle.cjs"),u=require("./decorators/withThrottleComputed/withThrottleComputed.cjs"),d=require("./decorators/withThrottleAndCache/withThrottleAndCache.cjs"),f=require("./decorators/withStaleWhileRevalidate/withStaleWhileRevalidate.cjs"),p=require("./decorators/withValidation/withValidation.cjs");exports.AbstractService=i.AbstractService,exports.BaseREService=i.BaseREService,exports.BaseREServiceEnhanced=a.BaseREServiceEnhanced,exports.ReactiveEngine=t.ReactiveEngineAutomatic,exports.ReactiveEngineAutolog=n.ReactiveEngineAutolog,exports.ReactiveEngineAutomatic=t.ReactiveEngineAutomatic,exports.ReactiveEngineCore=e.
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./core.cjs"),t=require("./core.automatic.cjs"),n=require("./core.autolog.cjs"),r=require("./core.global.cjs"),i=require("./AbstractService.cjs"),a=require("./BaseREServiceEnhanced.cjs"),o=require("./decorators/withCache/withCache.cjs"),s=require("./decorators/withDebounce/withDebounce.cjs"),c=require("./decorators/withLongPolling/withLongPolling.cjs"),l=require("./decorators/withThrottle/withThrottle.cjs"),u=require("./decorators/withThrottleComputed/withThrottleComputed.cjs"),d=require("./decorators/withThrottleAndCache/withThrottleAndCache.cjs"),f=require("./decorators/withStaleWhileRevalidate/withStaleWhileRevalidate.cjs"),p=require("./decorators/withValidation/withValidation.cjs");exports.AbstractService=i.AbstractService,exports.BaseREService=i.BaseREService,exports.BaseREServiceEnhanced=a.BaseREServiceEnhanced,exports.ReactiveEngine=t.ReactiveEngineAutomatic,exports.ReactiveEngineAutolog=n.ReactiveEngineAutolog,exports.ReactiveEngineAutomatic=t.ReactiveEngineAutomatic,exports.ReactiveEngineCore=e.ReactiveEngineCore,exports.batch=r.batch,exports.computed=r.computed,exports.effect=r.effect,exports.resetGlobalReactiveEngine=r.resetGlobalReactiveEngine,exports.signal=r.signal,exports.untrack=r.untrack,exports.withCache=o.withCache,exports.withDebounce=s.withDebounce,exports.withLongPolling=c.withLongPolling,exports.withResourceValidation=p.withResourceValidation,exports.withStaleWhileRevalidate=f.withStaleWhileRevalidate,exports.withThrottle=l.withThrottle,exports.withThrottleAndCache=d.withThrottleAndCache,exports.withThrottleComputed=u.withThrottleComputed,exports.withValidation=p.withValidation;
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ReactiveEngineCore as e } from "./core.mjs";
|
|
2
2
|
import { ReactiveEngineAutomatic as t } from "./core.automatic.mjs";
|
|
3
3
|
import { ReactiveEngineAutolog as n } from "./core.autolog.mjs";
|
|
4
4
|
import { batch as r, computed as i, effect as a, resetGlobalReactiveEngine as o, signal as s, untrack as c } from "./core.global.mjs";
|
package/dist/index2.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
const e=require("./core.cjs");require("./core.automatic.cjs"),require("./core.autolog.cjs");const t=require("./core.global.cjs"),n=require("./AbstractService.cjs"),r=require("./BaseREServiceEnhanced.cjs");exports.AbstractService=n.AbstractService,exports.BaseREService=n.BaseREService,exports.BaseREServiceEnhanced=r.BaseREServiceEnhanced,exports.ReactiveEngineAutomatic=e.
|
|
1
|
+
const e=require("./core.cjs");require("./core.automatic.cjs"),require("./core.autolog.cjs");const t=require("./core.global.cjs"),n=require("./AbstractService.cjs"),r=require("./BaseREServiceEnhanced.cjs");exports.AbstractService=n.AbstractService,exports.BaseREService=n.BaseREService,exports.BaseREServiceEnhanced=r.BaseREServiceEnhanced,exports.ReactiveEngineAutomatic=e.ReactiveEngineAutomatic,exports.ReactiveEngineCore=e.ReactiveEngineCore,exports.batch=t.batch,exports.computed=t.computed,exports.effect=t.effect,exports.resetGlobalReactiveEngine=t.resetGlobalReactiveEngine,exports.signal=t.signal,exports.untrack=t.untrack;
|
package/dist/index2.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ReactiveEngineAutomatic as e, ReactiveEngineCore as t } from "./core.mjs";
|
|
2
2
|
import "./core.automatic.mjs";
|
|
3
3
|
import "./core.autolog.mjs";
|
|
4
|
-
import { batch as
|
|
5
|
-
import { AbstractService as
|
|
6
|
-
import { BaseREServiceEnhanced as
|
|
7
|
-
export {
|
|
4
|
+
import { batch as n, computed as r, effect as i, resetGlobalReactiveEngine as a, signal as o, untrack as s } from "./core.global.mjs";
|
|
5
|
+
import { AbstractService as c, BaseREService as l } from "./AbstractService.mjs";
|
|
6
|
+
import { BaseREServiceEnhanced as u } from "./BaseREServiceEnhanced.mjs";
|
|
7
|
+
export { c as AbstractService, l as BaseREService, u as BaseREServiceEnhanced, e as ReactiveEngineAutomatic, t as ReactiveEngineCore, n as batch, r as computed, i as effect, a as resetGlobalReactiveEngine, o as signal, s as untrack };
|
package/dist/react/index.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../core.cjs"),t=require("./hooks/useReactiveValue.cjs"),n=require("./hooks/useReactiveSubscription.cjs");var r=t.useReactiveValue,i=class extends e.
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../core.cjs"),t=require("./hooks/useReactiveValue.cjs"),n=require("./hooks/useReactiveSubscription.cjs");var r=t.useReactiveValue,i=class extends e.ReactiveEngineCore{use(e){return t.useReactiveValue(e)}};exports.ReactiveEngine=i,exports.use=r,exports.useReactiveSubscription=n.useReactiveSubscription,exports.useReactiveValue=t.useReactiveValue;
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|
package/dist/react/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":[],"sources":["../../src/react/index.ts"],"sourcesContent":["import { ReactiveEngineCore } from '../core/core'\nimport { useReactiveValue } from './hooks/useReactiveValue'\nimport { ISignalLike } from '../core/types'\n\nexport interface IUseReactiveHook {\n <V>(item: ISignalLike<V>): V;\n <T>(item: T): T;\n}\n\nexport const use: IUseReactiveHook = useReactiveValue as any\n\n/**\n * Расширенная версия движка ядра для ООП/DI паттернов в React-среде\n */\nexport class ReactiveEngine extends ReactiveEngineCore {\n public use<V>(item: ISignalLike<V>): V;\n public use<T>(item: T): T;\n public use(item: any): any {\n return useReactiveValue(item)\n }\n // Метод inject удален отсюда, так как он нативно наследуется из ReactiveEngineCore без хуков!\n}\n\nexport { useReactiveValue }\nexport { useReactiveSubscription } from './hooks/useReactiveSubscription'\n"],"mappings":"6LASA,IAAa,EAAwB,EAAA,iBAKxB,EAAb,cAAoC,EAAA,
|
|
1
|
+
{"version":3,"file":"index.cjs","names":[],"sources":["../../src/react/index.ts"],"sourcesContent":["import { ReactiveEngineCore } from '../core/core'\nimport { useReactiveValue } from './hooks/useReactiveValue'\nimport { ISignalLike } from '../core/types'\n\nexport interface IUseReactiveHook {\n <V>(item: ISignalLike<V>): V;\n <T>(item: T): T;\n}\n\nexport const use: IUseReactiveHook = useReactiveValue as any\n\n/**\n * Расширенная версия движка ядра для ООП/DI паттернов в React-среде\n */\nexport class ReactiveEngine extends ReactiveEngineCore {\n public use<V>(item: ISignalLike<V>): V;\n public use<T>(item: T): T;\n public use(item: any): any {\n return useReactiveValue(item)\n }\n // Метод inject удален отсюда, так как он нативно наследуется из ReactiveEngineCore без хуков!\n}\n\nexport { useReactiveValue }\nexport { useReactiveSubscription } from './hooks/useReactiveSubscription'\n"],"mappings":"6LASA,IAAa,EAAwB,EAAA,iBAKxB,EAAb,cAAoC,EAAA,kBAAmB,CAGrD,IAAW,EAAgB,CACzB,OAAO,EAAA,iBAAiB,CAAI,CAC9B,CAEF"}
|
package/dist/react/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ReactiveEngineCore as e } from "../core.mjs";
|
|
2
2
|
import { useReactiveValue as t } from "./hooks/useReactiveValue.mjs";
|
|
3
3
|
import { useReactiveSubscription as n } from "./hooks/useReactiveSubscription.mjs";
|
|
4
4
|
//#region src/react/index.ts
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* @pravosleva/reactive-engine v2.5.0-alpha.6
|
|
3
|
+
* High-performance transactional reactive engine with microtask batching.
|
|
4
|
+
*
|
|
5
|
+
* @license MIT
|
|
6
|
+
* @author pravosleva <selection4test@google.com>
|
|
7
|
+
* @homepage https://pravosleva.pro/reactive-engine
|
|
8
|
+
*
|
|
9
|
+
* @contact Telegram Channel: https://t.me/bash_exp_ru/3393
|
|
10
|
+
* @contact Developer Telegram: https://t.me/pravosleva
|
|
11
|
+
*/
|
|
12
|
+
(function(e,t){typeof exports==`object`&&typeof module<`u`?t(exports):typeof define==`function`&&define.amd?define([`exports`],t):(e=typeof globalThis<`u`?globalThis:e||self,t(e.ReactiveEngineLib={}))})(this,function(e){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});function t(e,t,n){let r=t.toString(),i=n?`${n}:${r}`:r;if(e.computedStringCache||=new Map,e.batchDepth>0){let t=e.computedStringCache.get(i);if(t)return t}let a=e.computedCache.get(t);if(a){let t=a._node||a;if(e.batchDepth===0)t.state=2;else return a}let o,s=!0,c=0,l=!1,u=-1,d=2,f=-1,p=new Set,m=new Map,h=new Set,g=new Set,_=e=>{if(!e)return;let t=e._node||e;if(t.dependencies&&t.dependencies.size>0){for(let n of t.dependencies){let r=n,i=r._node||r;i.subscribers&&(i.subscribers.delete(t),i.subscribers.delete(e),i.subscribers.delete(x),i.type===`computed`&&i.subscribers.size===0&&_(i))}t.dependencies.clear(),t.depVersions&&t.depVersions.clear()}},v=-1,y=t=>{let n=e.batchIterationId;if(n!==void 0&&f===n||u===e.epoch&&l&&d===0)return!1;if(!l||d===2)return t.run();if(v===e.epoch&&e.batchDepth===0)return!1;let r=!1;if(p&&p.size>0)for(let e of p){let t=e._node||e;if(t.type===`computed`&&t.update&&t.update(),e.hasBatchValue||m.get(e)!==t.version){r=!0;break}}return v=e.epoch,r||s?t.run():(d=0,!1)},b=0,x={id:e.subscriberId++,dependencies:p,subscribers:g,ownedEffects:h,depth:1,type:`computed`,fn:t,get version(){return c},get state(){return d},set state(e){d=e},get depVersions(){return m},update:()=>y(x),run:()=>{let r=e.batchIterationId;if(r!==void 0&&f===r||u===e.epoch&&l&&d===0)return!1;if(u=e.epoch,v=e.epoch,r!==void 0&&(f=r),e.cycleDetectionStack.has(x))throw Error(`[Graph Error] Cyclic dependency detected`);e.cycleDetectionStack.add(x);let i=e.activeConsumer,a=e.activeOwner;e.activeConsumer=x,e.activeOwner=x,b++,x.activeRunId=b,e._poolArr||=[];let g=e._poolArr;if(g.length=0,p.size>0)for(let e of p)g.push(e);p.clear();try{if(h.size>0){for(let e of h)e&&typeof e.dispose==`function`&&e.dispose();h.clear()}let r=t();if(g.length>0){let e=g.length===p.size;for(let t=0;t<g.length;t++){let n=g[t];if(!e||!p.has(n)){let e=n._node||n;e.subscribers&&e.subscribers.delete(x),m.delete(n)}}}let i=s||!Object.is(o,r);if(i){let t;e.log&&n&&e.logger&&e.logger.isEnabled&&(t=s?void 0:typeof o==`object`&&o?JSON.parse(JSON.stringify(o)):o),o=r,c++,e.log&&n&&e.log({type:`computed`,label:n,details:{from:t,to:r}})}s=!1,d=0,l=!0;let a=0;for(let e of p){let t=e,n=t._node||t;m.set(t,n.version),n.subscribers&&n.subscribers.add(x),n.depth!==void 0&&n.depth>a&&(a=n.depth)}return x.depth=a+1,i}finally{e.activeConsumer=i,e.activeOwner=a,e.cycleDetectionStack.delete(x)}},markDirty:t=>{if(!(d>=t)){d=t;for(let t of g){let n=t._node||t;n.type===`effect`?(n.isDirty=!0,e.scheduleEffect(t)):n.markDirty&&n.markDirty(1)}}}},S={get value(){let t=e.activeConsumer;if(t&&t!==x){g.add(t),t.dependencies.add(x);let e=x.depth||1,n=t._node||t;n.depth!==void 0&&e>=n.depth&&(n.depth=e+1),t.activeRunId!==void 0&&(x._lastSeenInRunId=t.activeRunId)}return y(x),t&&t.depVersions&&t.depVersions.set(S,c),o},get valueWithoutTracking(){return o},get version(){return c},get dependencies(){return p},subscribe(t){let n={id:e.subscriberId++,isDirty:!0,depth:9999,dependencies:new Set,type:`effect`,run:()=>{if(!n.isDisposed)try{t(S.value)}catch(e){console.error(e)}}};return g.add(n),t(S.value),()=>{n.isDisposed=!0,g.delete(n)}},subscribeState(e){return S.subscribe(e)},destroy:()=>{_(x),g&&g.clear(),e.computedCache.delete(t),e.computedStringCache&&e.computedStringCache.delete(i),s=!0,d=2,l=!1},__subscribe(t){let n={id:e.subscriberId++,type:`effect`,run:t,isDirty:!1};return g.add(n),()=>{g.delete(n)}}};return S.run=()=>x.run(),e.computedCache.set(t,S),e.batchDepth>0&&e.computedStringCache.set(i,S),S._node=x,S.subscribers=g,S}var n=({tested:e,expectedKey:t,valueType:n})=>{let r=[];if(!e||!Array.isArray(e))return r;for(let i=0,a=e.length;i<a;i++){let a=e[i];if(typeof a!=`string`)continue;let o;switch(n){case`number`:o=RegExp(`\\[${t}=(?<value>\\d+)\\]`,`g`);break;default:o=RegExp(`\\[${t}=(?<value>.*?)\\]`,`g`);break}for(let e of a.matchAll(o))e?.groups&&r.push(e.groups.value)}return r};function r(e,t,r){let i=t,a=0,o=typeof r==`string`?r:r?.name;o&&n({tested:[o],expectedKey:`CORE_INTERNAL_SIGNAL`,valueType:`number`})?.[0];let s=new Set,c=!1,l=t,u={type:`signal`,get version(){return a},subscribers:s},d=(t=2)=>{for(let n of s){let r=n._node||n;if(r.type===`effect`)r.isDirty=!0,e.scheduleEffect(n);else if(r.type===`computed`)r.markDirty&&r.markDirty(t);else if(typeof n==`function`)try{n(i)}catch(e){console.error(e)}else if(n&&typeof n.run==`function`)try{n.run()}catch(e){console.error(e)}}},f={get value(){let t=e.activeConsumer;if(t){s.add(e.activeConsumer),e.activeConsumer.dependencies.add(f);let n=t._node||t;n.depth!==void 0&&n.depth===1&&(n.depth=2),t.activeRunId!==void 0&&(f._lastSeenInRunId=t.activeRunId)}return i},set value(t){if(!(Object.is(i,t)&&!(i===t&&typeof i==`object`&&i))){if(r&&typeof r==`object`&&r.validate){let e=r.validate(t);if(e!==!0){console.error(typeof e==`string`?e:`[Validation Error]`);return}}if(e.batchDepth>0){c||(c=!0,l=i),i=t,f.hasBatchValue=!0,d(1),e.batchedSignals.add(f);return}i=t,a++,e.epoch++,d(2),e.batchDepth===0&&e.flushEffects()}},get version(){return a},type:`signal`,subscribe(e){return s.add(e),e(i),()=>{s.delete(e)}},_applyBatchValue:()=>c&&(!Object.is(l,i)||typeof i==`object`&&i)?(a++,!0):!1,_flushBatch:t=>{c&&(!Object.is(l,i)||typeof i==`object`&&i?(a++,t||e.epoch++,d(2)):d(0),c=!1,f.hasBatchValue=!1,l=i)}};return f._node=u,f.subscribers=s,f}function i(e,t){let n=e.activeConsumer;e.activeConsumer=null;try{return t()}finally{e.activeConsumer=n}}function a(e,t,n){if(typeof t!=`object`||!t)return t;if(e.proxyCache.has(t))return e.proxyCache.get(t);if(e.proxyTargets.has(t))return t;let r=new Map;e.reactiveSignals.set(t,r);let i=null;Array.isArray(t)&&(i=e.signal(t.length,`[RE-INTERNAL]:len:${n||`array`}`));let o={push(...n){let r=t;return e.batch(()=>{let e=Array.prototype.push.apply(r,n);return i&&(i.value=r.length),s(r,`length`),e})},pop(){let n=t;return e.batch(()=>{let e=Array.prototype.pop.apply(n);return i&&(i.value=n.length),s(n,`length`),e})},shift(){let n=t;return e.batch(()=>{let e=Array.prototype.shift.apply(n);return i&&(i.value=n.length),s(n,`length`),e})},unshift(...n){let r=t;return e.batch(()=>{let e=Array.prototype.unshift.apply(r,n);return i&&(i.value=r.length),s(r,`length`),e})},splice(...n){let r=t;return e.batch(()=>{let e=Array.prototype.splice.apply(r,n);return i&&(i.value=r.length),s(r,`length`),e})},reverse(){let n=t;return e.batch(()=>{let e=Array.prototype.reverse.apply(n);i&&(i.value=n.length);for(let e=0;e<n.length;e++)s(n,String(e)),s(n,String(e));return s(n,`length`),e})},sort(n){let r=t;return e.batch(()=>{let e=Array.prototype.sort.apply(r,[n]);return i&&(i.value=r.length),s(r,`length`),e})}};function s(t,n){let r=e.reactiveSignals.get(t);if(r){let e=r.get(n);e&&(e.value=(e.value||0)+1)}}let c=new Proxy(t,{get(t,s,c){if(s===`__isProxy`)return!0;if(s===`_target`)return t;if(s===`_lenSignal`)return i;if(Array.isArray(t)&&Object.prototype.hasOwnProperty.call(o,s))return o[s].bind(c);if(e.activeConsumer){let t=r.get(s);t||(t=e.signal(0,`reactive:${n||`object`}:${String(s)}`),r.set(s,t)),t.value,s===`length`&&i&&i.value}let l=Reflect.get(t,s,c);return typeof l==`object`&&l?a(e,l,`${n||`object`}.${String(s)}`):l},set(e,t,n,a){let o=Reflect.get(e,t,a);if(Object.is(o,n)&&t!==`length`)return!0;let s=Reflect.set(e,t,n,a);if(s){let n=r.get(t);n&&(n.value=(n.value||0)+1),Array.isArray(e)&&t!==`length`&&i&&(i.value=e.length)}return s},deleteProperty(e,t){let n=Reflect.has(e,t),a=Reflect.deleteProperty(e,t);if(a&&n){let n=r.get(t);n&&(n.value=(n.value||0)+1),Array.isArray(e)&&i&&(i.value=e.length)}return a},ownKeys(t){if(e.activeConsumer){let t=r.get(`__ownKeys__`);t||(t=e.signal(0,`reactive:${n||`object`}:__ownKeys__`),r.set(`__ownKeys__`,t)),t.value}return Reflect.ownKeys(t)}});return e.proxyCache.set(t,c),e.proxyTargets.add(c),c}function o(e,t,n){let r=!1,i=!1,a=2,o=new Set,s=new Map,c=new Set,l=()=>{if(c.size>0){let t=e.activeConsumer,n=e.activeOwner;e.activeConsumer=null,e.activeOwner=null;for(let e of c)e.dispose&&e.dispose();c.clear(),e.activeConsumer=t,e.activeOwner=n}if(u.cleanups.size>0){let t=e.activeConsumer;e.activeConsumer=null;for(let e of u.cleanups)try{e()}catch(e){console.error(e)}u.cleanups.clear(),e.activeConsumer=t}},u={id:e.subscriberId++,dependencies:o,ownedEffects:c,cleanups:new Set,type:`effect`,depth:0,label:n,get isDirty(){return a>0},set isDirty(e){e&&(a=2)},get isDisposed(){return r},set isDisposed(e){r=e},get state(){return a},set state(e){a=e},get depVersions(){return s},get _node(){return u},markDirty:()=>{a>=1||(a=1,e.scheduleEffect(u))},run:()=>{if(r||i)return;i=!0,l();let n=e.activeConsumer,c=e.activeOwner;e.activeConsumer=u,e.activeOwner=u;let d=o.size>0?Array.from(o):null;o.clear();try{a=0;let e=t();if(typeof e==`function`&&u.cleanups.add(e),d!==null)for(let e of d){let t=e;if(!o.has(t)){let e=t._node||t;e.subscribers&&e.subscribers.delete(u),s.delete(t)}}let n=0;for(let e of o){let t=e,r=t._node||t;s.set(t,r.version),r.subscribers&&r.subscribers.add(u),r.depth!==void 0&&r.depth>n&&(n=r.depth)}u.depth=n+1}finally{i=!1,e.activeConsumer=n,e.activeOwner=c}},dispose:()=>{if(!r){r=!0,u.isDisposed=!0,l();for(let e of o){let t=e._node||e;t.subscribers&&t.subscribers.delete(u)}o.clear(),s.clear()}}},d=e.activeOwner?e.activeOwner._node||e.activeOwner:null;return d&&d.ownedEffects&&d.ownedEffects.add(u),u.run(),()=>{u.dispose()}}var s=class{frameworkPrefix=`core`;logger;epoch=0;activeConsumer=null;batchDepth=0;subscriberId=0;pendingEffects=[];maxPendingDepth=0;computedCache=new WeakMap;computedStringCache=new Map;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;isLoggingEnabled=!1;_poolArr=[];queueCleanup(e){this.pendingCleanups.add(e)}constructor(e){this.logger=e?.logger||{isEnabled:!1},this.isLoggingEnabled=!!this.logger.isEnabled}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)}batch(e){this.batchDepth++;try{return e()}finally{if(this.batchDepth--,this.batchDepth===0){if(this.batchIterationId||=0,this.batchIterationId++,this.batchedSignals.size>0){let e=new Map;for(let t of this.batchedSignals)t._applyBatchValue&&e.set(t,t._applyBatchValue());this.epoch++;for(let t of this.batchedSignals)if(t._flushBatch){let n=e.get(t)??!1;t._flushBatch(n,!0)}this.batchedSignals.clear()}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&&e.isDirty){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}}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}}signal(e,t){return r(this,e,t)}computed(e,n){return t(this,e,n)}effect(e,t){return o(this,e,t)}untrack(e){return i(this,e)}reactive(e,t){return a(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`){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)}}resource(e,t,n){let r=n&&typeof n==`object`,i=r?n.name||`unnamed_resource`:n||`unnamed_resource`,a=r?n:{},o=a.resetDataOnSourceChange??!0,s=a.responseValidate,c=a.validateBeforeFetch,l=this.signal({data:null,loading:!0,error:null,isRetrying:!1},`[CORE_INTERNAL_SIGNAL=1]:resource:state:${i}`),u=async(t,n,r=!1)=>{if(!n.aborted){if(c){let e=c(t);if(e===!1||typeof e==`string`){if(n.aborted)return;let t=typeof e==`string`?e:`Pre-fetch validation failed`;l.value={data:r?null:l.value.data,loading:!1,error:t,isRetrying:!1};return}}l.value={data:r&&o?null:l.value.data,loading:!0,error:null,isRetrying:!1};try{let r=await e(t,n);if(n.aborted)return;if(s){let e=s(r);if(e===!1||typeof e==`string`){l.value={data:null,loading:!1,error:typeof e==`string`?e:`Validation failed`,isRetrying:!1};return}}l.value={data:r,loading:!1,error:null,isRetrying:!1}}catch(e){if(n.aborted)return;l.value={data:null,loading:!1,error:e.message||`Fetch error`,isRetrying:!1}}}},d=null;return this.effect(()=>{let e=t?t.value:void 0,n=new AbortController;return d=n,this.untrack(()=>{u(e,n.signal,!0)}),()=>n.abort()}),{get data(){return l.value.data},get loading(){return l.value.loading},get error(){return l.value.error},get isRetrying(){return l.value.isRetrying},get value(){return l.value},refetch:()=>{d?.abort();let e=new AbortController;d=e,u(t?t.value:void 0,e.signal,!1)},subscribe:e=>l.subscribe(e)}}},c=class extends s{},l=class extends s{},u=class extends l{autoLogQueue=[];isHardFlushScheduled=!1;queueLog(e,t,n){this.autoLogQueue.push({type:e,name:t,meta:n,timestamp:Date.now()}),this.isHardFlushScheduled||(this.isHardFlushScheduled=!0,queueMicrotask(()=>this.flushLogs()))}flushLogs(){this.isHardFlushScheduled=!1,this.autoLogQueue.length!==0&&(typeof process<`u`&&process.env.NODE_ENV!==`test`&&(console.group(`📊 [Autolog] Срез транзакций: ${this.autoLogQueue.length} операций`),this.autoLogQueue.forEach(e=>console.log(`[${e.type.toUpperCase()}] ${e.name}`,e.meta||``)),console.groupEnd()),this.autoLogQueue=[])}computed(e,t){let n=this,r=t||`unnamed_computed`,i=super.computed(e,t),a=!1,o={get value(){if(a)return i.value;let e=typeof performance<`u`?performance.now():0,t=i.value;return e&&n.queueLog(`computed`,r,{value:t,duration:`${(performance.now()-e).toFixed(3)}ms`}),t},subscribe:e=>i.subscribe(e),destroy(){a=!0,i.destroy()}};return`_node`in i&&Object.defineProperty(o,"_node",{value:i._node,enumerable:!1}),o}},d=new s({logger:{isEnabled:!1}}),f=(e,t)=>d.signal(e,t),p=(e,t)=>d.computed(e,t),m=(e,t)=>d.effect(e,t),h=e=>d.batch(e),g=e=>d.untrack(e);function _(){d=new s({logger:{isEnabled:!1}})}var v=class{engine;constructor(e){this.engine=e,this.onInit()}createNumericSignal(e,t){return this.engine.signal(e,{name:t,validate:e=>typeof e==`number`&&!isNaN(e)})}createComputed(e){return this.engine.computed(e)}createSignal(e,t){return this.engine.signal(e,t)}onInit(){}},y=v,b=class{engine;constructor(e){this.engine=e,setTimeout(()=>this.onInit(),0)}onInit(){}};e.AbstractService=v,e.BaseREService=y,e.BaseREServiceEnhanced=b,e.ReactiveEngine=l,e.ReactiveEngineAutolog=u,e.ReactiveEngineAutomatic=c,e.ReactiveEngineCore=s,e.batch=h,e.computed=p,e.effect=m,e.resetGlobalReactiveEngine=_,e.signal=f,e.untrack=g});
|
|
13
|
+
//# sourceMappingURL=reactive-engine@2.5.0-alpha.6.umd.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reactive-engine@2.5.0-alpha.6.umd.js","names":[],"sources":["../src/core/core.method.computed.ts","../src/utils/getExtractedValues.ts","../src/core/core.method.signal.ts","../src/core/core.method.untrack.ts","../src/core/core.method.reactive.ts","../src/core/core.method.effect.ts","../src/core/core.ts","../src/core/core.automatic.ts","../src/core/core.autolog.ts","../src/core/core.global.ts","../src/core/AbstractService.ts","../src/core/BaseREServiceEnhanced.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 fnSourceKey = fn.toString()\n const cacheKey = signalName ? `${signalName}:${fnSourceKey}` : fnSourceKey\n\n if (!engine.computedStringCache) {\n engine.computedStringCache = new Map<string, any>()\n }\n\n // 1. Изолированный транзакционный текстовый кэш батча (Защита DieHard от Churn)\n if (engine.batchDepth > 0) {\n const existingString = engine.computedStringCache.get(cacheKey)\n if (existingString) {\n return existingString as Computed<T>\n }\n }\n\n // 2. Канонический WeakMap путь (Главный источник правды связанных графов)\n const existingWeak = engine.computedCache.get(fn)\n if (existingWeak) {\n const actNode = existingWeak._node || existingWeak\n\n // ⚛️ ФИКС КОЛЛИЗИИ С ПОДПИСЧИКОМ: Если мы вне батча, мы ВСЕГДА принудительно\n // сбрасываем состояние узла в DIRTY (2), обязывая его честно выполнить fn()\n // и обновить лексический скоуп замыкания, независимо от живых подписчиков!\n if (engine.batchDepth === 0) {\n actNode.state = 2\n } else {\n return existingWeak as Computed<T>\n }\n }\n\n let value: T\n let isDirty = true\n let version = 0\n let isInitialized = false\n let evaluatedInEpoch = -1\n let state = 2 // 2 = DIRTY, 1 = CHECK, 0 = STABLE\n\n let lastEvaluatedIteration = -1\n\n const dependencies = new Set<any>()\n const depVersions = new Map<any, number>()\n const ownedEffects = new Set<any>()\n const subscribers = new Set<any>()\n\n const releaseNode = (node: any): void => {\n if (!node) return\n const actNode = node._node || node\n\n if (actNode.dependencies && actNode.dependencies.size > 0) {\n for (const unknownDep of actNode.dependencies) {\n const dep = unknownDep as any\n const rawDepNode = dep._node || dep\n\n if (rawDepNode.subscribers) {\n rawDepNode.subscribers.delete(actNode)\n rawDepNode.subscribers.delete(node)\n rawDepNode.subscribers.delete(computedNode)\n\n if (rawDepNode.type === 'computed' && rawDepNode.subscribers.size === 0) {\n releaseNode(rawDepNode)\n }\n }\n }\n actNode.dependencies.clear()\n if (actNode.depVersions) actNode.depVersions.clear()\n }\n }\n\n let verifiedInEpoch = -1\n\n const updateIfNecessary = (node: any): boolean => {\n const currentBatchIteration = engine['batchIterationId']\n if (currentBatchIteration !== undefined && lastEvaluatedIteration === currentBatchIteration) {\n return false\n }\n\n // ⚛️ ФИКС АЛМАЗНОГО ГЛИЧА: Сквозной аппаратный барьер по эпохе ядра изменений.\n // Если в рамках текущего кванта времени узел уже рассчитывался и перешел\n // в стабильный статус — повторный запуск ЖЕСТКО блокируется в любых режимах!\n if (evaluatedInEpoch === engine.epoch && isInitialized && state === 0) {\n return false\n }\n\n if (!isInitialized || state === 2) {\n return node.run()\n }\n\n if (verifiedInEpoch === engine.epoch && engine.batchDepth === 0) {\n return false\n }\n\n let hasChangedParent = false\n\n if (dependencies && dependencies.size > 0) {\n for (const dep of dependencies) {\n const rawDep = dep._node || dep\n\n if (rawDep.type === 'computed') {\n if (rawDep.update) rawDep.update()\n }\n\n if ((dep as any).hasBatchValue || depVersions.get(dep) !== rawDep.version) {\n hasChangedParent = true\n break\n }\n }\n }\n\n verifiedInEpoch = engine.epoch\n\n if (hasChangedParent || isDirty) {\n return node.run()\n }\n\n state = 0\n return false\n }\n\n let currentRunId = 0\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 const currentBatchIteration = engine['batchIterationId']\n if (currentBatchIteration !== undefined && lastEvaluatedIteration === currentBatchIteration) {\n return false\n }\n\n if (evaluatedInEpoch === engine.epoch && isInitialized && state === 0) {\n return false\n }\n evaluatedInEpoch = engine.epoch\n verifiedInEpoch = engine.epoch\n\n if (currentBatchIteration !== undefined) {\n lastEvaluatedIteration = currentBatchIteration\n }\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 currentRunId++\n computedNode.activeRunId = currentRunId\n\n if (!engine._poolArr) engine._poolArr = []\n const oldDeps = engine._poolArr\n oldDeps.length = 0\n\n if (dependencies.size > 0) {\n for (const dep of dependencies) {\n oldDeps.push(dep)\n }\n }\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 if (oldDeps.length > 0) {\n const isSizeIdentical = oldDeps.length === dependencies.size\n for (let i = 0; i < oldDeps.length; i++) {\n const dep = oldDeps[i]\n if (!isSizeIdentical || !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\n const changed = isDirty || !Object.is(value, newValue)\n\n if (changed) {\n let previousValueSnapshot = undefined\n if (engine.log && signalName && engine.logger && engine.logger.isEnabled) {\n previousValueSnapshot = isDirty ? undefined : (typeof value === 'object' && value !== null ? JSON.parse(JSON.stringify(value)) : value)\n }\n\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\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 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 const consumer = engine.activeConsumer\n if (consumer && consumer !== computedNode) {\n subscribers.add(consumer)\n consumer.dependencies.add(computedNode)\n\n const currentDepth = computedNode.depth || 1\n const consumerRaw = consumer._node || consumer\n if (consumerRaw.depth !== undefined && currentDepth >= consumerRaw.depth) {\n consumerRaw.depth = currentDepth + 1\n }\n\n if (consumer.activeRunId !== undefined) {\n computedNode._lastSeenInRunId = consumer.activeRunId\n }\n }\n\n updateIfNecessary(computedNode)\n\n if (consumer && consumer.depVersions) {\n consumer.depVersions.set(computedInstance, version)\n }\n return value\n },\n get valueWithoutTracking() { return value },\n get version() { return version },\n get dependencies() { return dependencies },\n\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 subscribers.add(fakeEffect)\n cb(computedInstance.value)\n return () => {\n fakeEffect.isDisposed = true\n subscribers.delete(fakeEffect)\n }\n },\n subscribeState(cb: () => void): CleanupFn {\n return (computedInstance as any).subscribe(cb)\n },\n destroy: () => {\n releaseNode(computedNode)\n if (subscribers) subscribers.clear()\n\n engine.computedCache.delete(fn)\n if (engine.computedStringCache) {\n engine.computedStringCache.delete(cacheKey)\n }\n\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 subscribers.add(hookEffect)\n return () => {\n subscribers.delete(hookEffect)\n }\n }\n } as any\n computedInstance.run = () => computedNode.run()\n engine.computedCache.set(fn, computedInstance)\n if (engine.batchDepth > 0) {\n engine.computedStringCache.set(cacheKey, computedInstance)\n }\n ;(computedInstance as any)._node = computedNode\n ;(computedInstance as any).subscribers = subscribers\n return computedInstance\n}\n","export const getExtractedValues = ({\n tested, expectedKey, valueType\n}: {\n tested: string[];\n expectedKey: string;\n valueType: 'number' | 'string';\n}): string[] => {\n const results: string[] = []\n if (!tested || !Array.isArray(tested)) return results // Предохранитель от пустых массивов\n\n for (let i = 0, max = tested.length; i < max; i++) {\n const t = tested[i]\n if (typeof t !== 'string') continue // ЗАЩИТА: Пропускаем всё, что не является валидной строкой\n\n let regex\n switch (valueType) {\n case 'number':\n regex = new RegExp(`\\\\[${expectedKey}=(?<value>\\\\d+)\\\\]`, 'g')\n break\n case 'string':\n default:\n regex = new RegExp(`\\\\[${expectedKey}=(?<value>.*?)\\\\]`, 'g')\n break\n }\n\n for (const n of t.matchAll(regex)) {\n if (n?.groups) { results.push(n.groups.value) }\n }\n }\n return results\n}\n","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\n const extracted = !!name ? getExtractedValues({\n tested: [name],\n expectedKey: 'CORE_INTERNAL_SIGNAL',\n valueType: 'number',\n })?.[0] : null\n const isInternalCoreSignal = extracted && extracted === '1'\n\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 = (parentState: number = 2) => {\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(parentState)\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 const consumer = engine.activeConsumer\n if (consumer) {\n subscribers.add(engine.activeConsumer)\n engine.activeConsumer.dependencies.add(signalInstance)\n\n const consumerRaw = consumer._node || consumer\n if (consumerRaw.depth !== undefined && consumerRaw.depth === 1) {\n consumerRaw.depth = 2\n }\n\n if (consumer.activeRunId !== undefined) {\n (signalInstance as any)._lastSeenInRunId = consumer.activeRunId\n }\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\n ;(signalInstance as any).hasBatchValue = true\n notifySubscribers(1) // Мягкая маркировка CHECK (1) интра-ран чтений батча\n\n engine.batchedSignals.add(signalInstance)\n return\n }\n\n const oldValue = value\n value = newValue\n\n version++\n engine.epoch++\n\n notifySubscribers(2)\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 // ⚛️ ФАЗА 1: Чистая фиксация новых версий\n _applyBatchValue: () => {\n if (!hasBatchValue) return false\n const wasChanged = !Object.is(batchInitialValue, value) || (value !== null && typeof value === 'object')\n if (wasChanged) {\n version++\n return true\n }\n return false\n },\n\n // ⚛️ ФАЗА 2: Чистый атомарный push-уведомитель\n _flushBatch: (isAlreadyEpochShifted?: boolean) => {\n if (!hasBatchValue) return\n\n const wasChanged = !Object.is(batchInitialValue, value) || (value !== null && typeof value === 'object')\n\n if (wasChanged) {\n version++\n if (!isAlreadyEpochShifted) {\n engine.epoch++\n }\n // Возвращаем DIRTY (2) для канонического домино-эффекта\n notifySubscribers(2)\n } else {\n notifySubscribers(0)\n }\n\n hasBatchValue = false\n ;(signalInstance as any).hasBatchValue = false\n batchInitialValue = value\n }\n\n } as any\n\n ;(signalInstance as any)._node = signalNode\n ;(signalInstance as any).subscribers = subscribers\n return signalInstance\n}\n","/**\n * Изолированный менеджер контекста untrack реактивного графа.\n * Временно замораживает автоматический сбор зависимостей, подменяя activeConsumer на null.\n */\nexport function executeUntrack<T>(engine: any, fn: () => T): T {\n const prevConsumer = engine.activeConsumer\n engine.activeConsumer = null\n try {\n return fn()\n } finally {\n engine.activeConsumer = prevConsumer\n }\n}\n","import { SignalOptions } from './types'\n\nexport function createReactive<T extends object>(\n engine: any,\n target: T,\n name?: string\n): T {\n if (target === null || typeof target !== 'object') {\n return target\n }\n\n // 1. Возвращаем уже существующий Proxy из кэша ядра\n if (engine.proxyCache.has(target)) {\n return engine.proxyCache.get(target) as T\n }\n if (engine.proxyTargets.has(target)) {\n return target\n }\n\n const signalMap = new Map<string | symbol, any>()\n engine.reactiveSignals.set(target, signalMap)\n\n // Внутренний скрытый сигнал длины для массивов\n let lenSignal: any = null\n if (Array.isArray(target)) {\n lenSignal = engine.signal(target.length, `[RE-INTERNAL]:len:${name || 'array'}`)\n }\n\n // ⚡ ВЫСОКОСКОРОСТНАЯ ИНСТРУМЕНТАЦИЯ НАТИВНЫХ МЕТОДОВ МАССИВОВ\n const arrayInstrumentations: Record<string | symbol, Function> = {\n push(...args: any[]) {\n const rawTarget = target as any\n return engine.batch(() => {\n const res = Array.prototype.push.apply(rawTarget, args)\n if (lenSignal) lenSignal.value = rawTarget.length\n // Пинаем подписчиков на свойства\n notifyKeyChange(rawTarget, 'length')\n return res\n })\n },\n pop() {\n const rawTarget = target as any\n return engine.batch(() => {\n const res = Array.prototype.pop.apply(rawTarget)\n if (lenSignal) lenSignal.value = rawTarget.length\n notifyKeyChange(rawTarget, 'length')\n return res\n })\n },\n shift() {\n const rawTarget = target as any\n return engine.batch(() => {\n const res = Array.prototype.shift.apply(rawTarget)\n if (lenSignal) lenSignal.value = rawTarget.length\n notifyKeyChange(rawTarget, 'length')\n return res\n })\n },\n unshift(...args: any[]) {\n const rawTarget = target as any\n return engine.batch(() => {\n const res = Array.prototype.unshift.apply(rawTarget, args)\n if (lenSignal) lenSignal.value = rawTarget.length\n notifyKeyChange(rawTarget, 'length')\n return res\n })\n },\n splice(...args: any[]) {\n const rawTarget = target as any\n return engine.batch(() => {\n // Приведение к any снимает строгую проверку кортежа аргументов [start, deleteCount]\n const res = (Array.prototype.splice as any).apply(rawTarget, args)\n if (lenSignal) lenSignal.value = rawTarget.length\n notifyKeyChange(rawTarget, 'length')\n return res\n })\n },\n reverse() {\n const rawTarget = target as any\n return engine.batch(() => {\n const res = Array.prototype.reverse.apply(rawTarget)\n if (lenSignal) {\n lenSignal.value = rawTarget.length\n }\n\n // ⚛️ ЧЕСТНЫЙ ПЕРЕБОР ИНДЕКСОВ: Оповещаем подписчиков, которые следят за\n // конкретными элементами массива по числовым ключам (state.numbers[0])\n for (let i = 0; i < rawTarget.length; i++) {\n notifyKeyChange(rawTarget, String(i))\n notifyKeyChange(rawTarget, String(i))\n }\n\n notifyKeyChange(rawTarget, 'length')\n return res\n })\n },\n sort(compareFn?: (a: any, b: any) => number) {\n const rawTarget = target as any\n return engine.batch(() => {\n const res = (Array.prototype.sort as any).apply(rawTarget, [compareFn])\n if (lenSignal) lenSignal.value = rawTarget.length\n notifyKeyChange(rawTarget, 'length')\n return res\n })\n }\n }\n\n function notifyKeyChange(rawTarget: any, key: string | symbol) {\n const map = engine.reactiveSignals.get(rawTarget)\n if (map) {\n const sig = map.get(key)\n if (sig) {\n // Симулируем пинок изменения объекта самому себе через инкремент версии\n sig.value = (sig.value || 0) + 1\n }\n }\n }\n\n const handler: ProxyHandler<any> = {\n get(rawTarget, key, receiver) {\n if (key === '__isProxy') return true\n if (key === '_target') return rawTarget\n if (key === '_lenSignal') return lenSignal\n\n // Если это массив и вызывается деструктивный метод — отдаем атомарный мутатор\n if (Array.isArray(rawTarget) && Object.prototype.hasOwnProperty.call(arrayInstrumentations, key)) {\n return arrayInstrumentations[key].bind(receiver)\n }\n\n // Если мы находимся в реактивном контексте — подписываем текущий ключ\n if (engine.activeConsumer) {\n let sig = signalMap.get(key)\n if (!sig) {\n sig = engine.signal(0, `reactive:${name || 'object'}:${String(key)}`)\n signalMap.set(key, sig)\n }\n // Считываем значение сигнала для автоматической регистрации ребра графа\n sig.value\n if (key === 'length' && lenSignal) {\n lenSignal.value\n }\n }\n\n const res = Reflect.get(rawTarget, key, receiver)\n\n // Ленивое глубокое Proxy-проксирование на лету\n if (res !== null && typeof res === 'object') {\n return createReactive(engine, res, `${name || 'object'}.${String(key)}`)\n }\n return res\n },\n\n set(rawTarget, key, newValue, receiver) {\n const oldValue = Reflect.get(rawTarget, key, receiver)\n\n // Прерываем холостые мутации примитивов по Object.is\n if (Object.is(oldValue, newValue) && key !== 'length') {\n return true\n }\n\n const res = Reflect.set(rawTarget, key, newValue, receiver)\n if (res) {\n // Каскадно уведомляем граф через скрытый сигнальный маркер ключа\n let sig = signalMap.get(key)\n if (sig) {\n sig.value = (sig.value || 0) + 1\n }\n if (Array.isArray(rawTarget) && key !== 'length' && lenSignal) {\n // Принудительно триггерим длину, если изменился индекс массива\n lenSignal.value = rawTarget.length\n }\n }\n return res\n },\n\n deleteProperty(rawTarget, key) {\n const hasKey = Reflect.has(rawTarget, key)\n const res = Reflect.deleteProperty(rawTarget, key)\n if (res && hasKey) {\n let sig = signalMap.get(key)\n if (sig) {\n sig.value = (sig.value || 0) + 1\n }\n if (Array.isArray(rawTarget) && lenSignal) {\n lenSignal.value = rawTarget.length\n }\n }\n return res\n },\n\n ownKeys(rawTarget) {\n if (engine.activeConsumer) {\n let sig = signalMap.get('__ownKeys__')\n if (!sig) {\n sig = engine.signal(0, `reactive:${name || 'object'}:__ownKeys__`)\n signalMap.set('__ownKeys__', sig)\n }\n sig.value\n }\n return Reflect.ownKeys(rawTarget)\n }\n }\n\n const proxy = new Proxy(target, handler)\n engine.proxyCache.set(target, proxy)\n engine.proxyTargets.add(proxy)\n\n return proxy as T\n}\n","import { IEffect, EffectFn, CleanupFn } from './types'\n\ninterface ICoreEffectNode extends IEffect {\n dependencies: Set<any>;\n depVersions: Map<any, number>;\n ownedEffects: Set<ICoreEffectNode>;\n type: string;\n depth: number;\n state: number;\n _node: any;\n dispose: () => void;\n}\n\nexport function createEffect(engine: any, fn: EffectFn, effectName?: string): () => void {\n let isDisposed = false\n let isRunning = false\n let state = 2 // 0 = STABLE, 1 = CHECK, 2 = DIRTY\n\n const dependencies = new Set<any>()\n const depVersions = new Map<any, number>()\n const ownedEffects = new Set<ICoreEffectNode>()\n\n const runCleanupPhase = () => {\n // Каскадное уничтожение вложенных детей через быстрый for...of\n if (ownedEffects.size > 0) {\n const prevConsumer = engine.activeConsumer\n const prevOwner = engine.activeOwner\n engine.activeConsumer = null\n engine.activeOwner = null\n\n for (const child of ownedEffects) {\n if (child.dispose) child.dispose()\n }\n ownedEffects.clear()\n\n engine.activeConsumer = prevConsumer\n engine.activeOwner = prevOwner\n }\n\n // Изоляция ошибок в деструкторах пользователя через быстрый for...of\n if (effectNode.cleanups.size > 0) {\n const prevConsumer = engine.activeConsumer\n engine.activeConsumer = null\n\n for (const cleanup of effectNode.cleanups) {\n try {\n cleanup()\n } catch (err) {\n console.error(err)\n }\n }\n\n effectNode.cleanups.clear()\n engine.activeConsumer = prevConsumer\n }\n }\n\n const effectNode: ICoreEffectNode = {\n id: engine.subscriberId++,\n dependencies,\n ownedEffects,\n cleanups: new Set<CleanupFn>(),\n type: 'effect',\n depth: 0,\n label: effectName,\n\n get isDirty(): boolean { return state > 0 },\n set isDirty(val: boolean) { if (val) state = 2 },\n\n get isDisposed(): boolean { return isDisposed },\n set isDisposed(val: boolean) { isDisposed = val },\n\n get state(): number { return state },\n set state(val: number) { state = val },\n get depVersions(): Map<any, number> { return depVersions },\n get _node(): any { return effectNode },\n\n markDirty: () => {\n if (state >= 1) return\n state = 1\n engine.scheduleEffect(effectNode)\n },\n\n run: () => {\n if (isDisposed || isRunning) return\n isRunning = true\n\n runCleanupPhase()\n\n const prevConsumer = engine.activeConsumer\n const prevOwner = engine.activeOwner\n\n engine.activeConsumer = effectNode\n engine.activeOwner = effectNode\n\n const oldDeps = dependencies.size > 0 ? Array.from(dependencies) : null\n dependencies.clear()\n\n try {\n state = 0 // Сбрасываем флаг грязи перед чтением графа\n\n const result = fn()\n if (typeof result === 'function') {\n effectNode.cleanups.add(result)\n }\n\n if (oldDeps !== null) {\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(effectNode)\n depVersions.delete(dep)\n }\n }\n }\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(effectNode)\n if (rawNode.depth !== undefined && rawNode.depth > maxDepDepth) {\n maxDepDepth = rawNode.depth\n }\n }\n effectNode.depth = maxDepDepth + 1\n\n } finally {\n isRunning = false\n engine.activeConsumer = prevConsumer\n engine.activeOwner = prevOwner\n }\n },\n\n dispose: () => {\n if (isDisposed) return\n isDisposed = true\n effectNode.isDisposed = true\n\n runCleanupPhase()\n\n // ⚡ ОПТИМИЗАЦИЯ: Замена .forEach на быстрый for...of при полном уничтожении эффекта\n for (const dep of dependencies) {\n const rawNode = dep._node || dep\n if (rawNode.subscribers) rawNode.subscribers.delete(effectNode)\n }\n dependencies.clear()\n depVersions.clear()\n }\n }\n\n const actualOwnerNode = engine.activeOwner ? (engine.activeOwner._node || engine.activeOwner) : null\n\n if (actualOwnerNode && actualOwnerNode.ownedEffects) {\n actualOwnerNode.ownedEffects.add(effectNode)\n }\n\n effectNode.run()\n\n return () => {\n effectNode.dispose()\n }\n}\n","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'\nimport { executeUntrack } from './core.method.untrack'\nimport { createReactive } from './core.method.reactive'\nimport { createEffect } from './core.method.effect'\nimport { ReactiveDebounceLogger } from './core.logger'\n\ntype Constructor<T> = new (...args: any[]) => T\ntype Factory<T> = (engine: any) => T\ntype InjectionToken<T> = Constructor<T> | Factory<T> | symbol | string\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 public computedStringCache = new Map<string, 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 public cycleDetectionStack = new Set<unknown>()\n public batchedSignals = new Set<any>()\n public activeOwner: any = null\n public pendingCleanups = new Set<() => void>()\n public isLoggingEnabled = false\n public _poolArr: any[] = []\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 this.isLoggingEnabled = !!this.logger.isEnabled\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 batch<T>(fn: () => T): T {\n this.batchDepth++\n try {\n return fn()\n } finally {\n this.batchDepth--\n if (this.batchDepth === 0) {\n if (!(this as any).batchIterationId) (this as any).batchIterationId = 0\n ;(this as any).batchIterationId++\n\n if (this.batchedSignals.size > 0) {\n const changeFlags = new Map<any, boolean>()\n\n // Фаза 1: Фиксация версий\n for (const sig of this.batchedSignals) {\n if (sig._applyBatchValue) {\n changeFlags.set(sig, sig._applyBatchValue())\n }\n }\n\n // Атомарный сдвиг общей макро-эпохи ядра\n this.epoch++\n\n // Фаза 2: Каскадный пуш\n for (const sig of this.batchedSignals) {\n if (sig._flushBatch) {\n const changed = changeFlags.get(sig) ?? false\n sig._flushBatch(changed, true)\n }\n }\n this.batchedSignals.clear()\n }\n\n // Запускаем планировщик под единым защищенным барьером итерации\n this.flushEffects()\n }\n }\n }\n\n public flushEffects(): void {\n if (this.batchDepth > 0) return\n const prevConsumer = this.activeConsumer\n\n try {\n for (let depth = 0; depth <= this.maxPendingDepth; depth++) {\n const bucket = this.pendingEffects[depth]\n if (!bucket || bucket.size === 0) continue\n\n const effects = Array.from(bucket)\n bucket.clear()\n\n for (const effect of effects) {\n if (effect.isDisposed) continue\n if (!effect.isDirty) continue\n\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 try {\n effect.run()\n } catch (err) {\n throw err\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) depth = -1\n }\n }\n this.maxPendingDepth = 0\n } finally {\n this.activeConsumer = prevConsumer\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 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 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 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 ? ((optionsOrName as ResourceOptions<T, S>).name || 'unnamed_resource') : (optionsOrName as string) || 'unnamed_resource'\n\n const options: Partial<ResourceOptions<T, S>> = isOptionsObject ? (optionsOrName as ResourceOptions<T, S>) : {}\n const resetDataOnSourceChange = options.resetDataOnSourceChange ?? true\n const responseValidate = options.responseValidate\n const validateBeforeFetch = options.validateBeforeFetch\n\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 load = async (sValue: S, effectSignal: AbortSignal, isSourceChange = false) => {\n if (effectSignal.aborted) return\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' ? preValidationResult : 'Pre-fetch validation failed'\n state.value = { data: isSourceChange ? null : state.value.data, loading: false, error: errorMsg, isRetrying: false }\n return\n }\n }\n\n state.value = { data: (isSourceChange && resetDataOnSourceChange) ? null : state.value.data, loading: true, error: null, isRetrying: false }\n\n try {\n const data = await fetcher(sValue, effectSignal)\n if (effectSignal.aborted) return\n if (responseValidate) {\n const validationResult = responseValidate(data)\n if (validationResult === false || typeof validationResult === 'string') {\n const errorMsg = typeof validationResult === 'string' ? validationResult : 'Validation failed'\n state.value = { data: null, loading: false, error: errorMsg, isRetrying: false }\n return\n }\n }\n state.value = { data, loading: false, error: null, isRetrying: false }\n } catch (e: any) {\n if (effectSignal.aborted) return\n state.value = { data: null, loading: false, error: e.message || 'Fetch error', isRetrying: false }\n }\n }\n\n let activeController: AbortController | null = null\n\n this.effect(() => {\n const sValue = source ? source.value : undefined as S\n const controller = new AbortController()\n activeController = controller\n\n this.untrack(() => {\n load(sValue, controller.signal, true)\n })\n\n return () => controller.abort()\n })\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 activeController?.abort()\n const controller = new AbortController()\n activeController = controller\n load(source ? source.value : undefined as S, controller.signal, false)\n },\n subscribe: (cb: (val: ResourceState<T>) => void) => state.subscribe(cb)\n }\n }\n\n}\n\nexport class ReactiveEngineAutomatic extends ReactiveEngineCore {}\n","import { ReactiveEngineCore } from './core'\n\nexport class ReactiveEngineAutomatic extends ReactiveEngineCore {}\n","import { ReactiveEngineAutomatic } from './core.automatic'\nimport { Computed } from './types'\n\n/**\n * 📊 REACTIVE ENGINE AUTOLOG (core.autolog)\n * Расширяет автоматический шедулер. Добавляет Enterprise-логирование,\n * замер производительности и Pull Duration каскадов графа.\n */\nexport class ReactiveEngineAutolog extends ReactiveEngineAutomatic {\n public autoLogQueue: Array<any> = []\n public isHardFlushScheduled = false\n\n public queueLog(type: string, name: string, meta?: any): void {\n this.autoLogQueue.push({ type, name, meta, timestamp: Date.now() })\n if (!this.isHardFlushScheduled) {\n this.isHardFlushScheduled = true\n queueMicrotask(() => this.flushLogs())\n }\n }\n\n public flushLogs(): void {\n this.isHardFlushScheduled = false\n if (this.autoLogQueue.length === 0) return\n if (typeof process !== 'undefined' && process.env.NODE_ENV !== 'test') {\n console.group(`📊 [Autolog] Срез транзакций: ${this.autoLogQueue.length} операций`)\n this.autoLogQueue.forEach(log => console.log(`[${log.type.toUpperCase()}] ${log.name}`, log.meta || ''))\n console.groupEnd()\n }\n this.autoLogQueue = []\n }\n\n public override computed<T>(fn: () => T, signalName?: string): Computed<T> {\n const engine = this\n const name = signalName || 'unnamed_computed'\n const originalComputed = super.computed(fn, signalName)\n let isDestroyed = false\n\n const autologComputedInstance: Computed<T> = {\n get value(): T {\n if (isDestroyed) return originalComputed.value\n const startTime = typeof performance !== 'undefined' ? performance.now() : 0\n const val = originalComputed.value\n\n if (startTime) {\n engine.queueLog('computed', name, { value: val, duration: `${(performance.now() - startTime).toFixed(3)}ms` })\n }\n return val\n },\n subscribe: (cb) => originalComputed.subscribe(cb),\n destroy() {\n isDestroyed = true\n originalComputed.destroy()\n }\n }\n\n if ('_node' in originalComputed) {\n Object.defineProperty(autologComputedInstance, '_node', {\n value: (originalComputed as any)._node,\n enumerable: false\n })\n }\n\n return autologComputedInstance\n }\n}\n","import { ReactiveEngineCore } from './core'\n\n// Единый глобальный инстанс по умолчанию\nlet globalEngine = new ReactiveEngineCore({ logger: { isEnabled: false } })\n\nexport const signal = <T>(initialValue: T, options?: any) => globalEngine.signal(initialValue, options)\nexport const computed = <T>(fn: () => T, name?: string) => globalEngine.computed(fn, name)\nexport const effect = (fn: () => any, name?: string) => globalEngine.effect(fn, name)\nexport const batch = <T>(fn: () => T): T => globalEngine.batch(fn)\nexport const untrack = <T>(fn: () => T): T => globalEngine.untrack(fn)\n\n/**\n * ⚡ ХУК ДЛЯ БЕНЧМАРКОВ И ТЕСТОВЫХ СРЕД:\n * Позволяет атомарно уничтожить старый граф реактивности и начать с чистого листа,\n * полностью исключая утечки памяти и пересечение эпох между тест-кейсами.\n */\nexport function resetGlobalReactiveEngine(): void {\n // Старый инстанс со всеми WeakMap и StringCache уходит в Garbage Collector\n globalEngine = new ReactiveEngineCore({ logger: { isEnabled: false } })\n}\n","import { ReactiveEngineAutomatic } from './core.automatic'\n\nexport abstract class AbstractService {\n constructor(protected engine: ReactiveEngineAutomatic) {\n // Вызываем метод инициализации, который можно переопределить в наследниках\n this.onInit()\n }\n\n // NOTE: Полезные хелперы для сокращения кода\n protected createNumericSignal(val: number, name: string) {\n return this.engine.signal(val, {\n name,\n validate: (v) => typeof v === 'number' && !isNaN(v)\n })\n }\n\n protected createComputed<T>(fn: () => T) {\n return this.engine.computed(fn)\n }\n\n protected createSignal<T>(val: T, name?: string) {\n return this.engine.signal(val, name)\n }\n\n // NOTE: Жизненный цикл: вызывается сразу после создания сервиса.\n // Удобно для инициализации сигналов, которые зависят от engine.\n protected onInit(): void { }\n}\n\nexport const BaseREService = AbstractService\n","import { ReactiveEngineCore } from './core'\n\nexport abstract class BaseREServiceEnhanced {\n constructor(protected engine: ReactiveEngineCore) {\n setTimeout(() => this.onInit(), 0)\n }\n\n protected onInit(): void { }\n}\n"],"mappings":"yRAEA,SAAgB,EACd,EACA,EACA,EACa,CACb,IAAM,EAAc,EAAG,SAAS,EAC1B,EAAW,EAAa,GAAG,EAAW,GAAG,IAAgB,EAO/D,GALA,AACE,EAAO,sBAAsB,IAAI,IAI/B,EAAO,WAAa,EAAG,CACzB,IAAM,EAAiB,EAAO,oBAAoB,IAAI,CAAQ,EAC9D,GAAI,EACF,OAAO,CAEX,CAGA,IAAM,EAAe,EAAO,cAAc,IAAI,CAAE,EAChD,GAAI,EAAc,CAChB,IAAM,EAAU,EAAa,OAAS,EAKtC,GAAI,EAAO,aAAe,EACxB,EAAQ,MAAQ,OAEhB,OAAO,CAEX,CAEA,IAAI,EACA,EAAU,GACV,EAAU,EACV,EAAgB,GAChB,EAAmB,GACnB,EAAQ,EAER,EAAyB,GAEvB,EAAe,IAAI,IACnB,EAAc,IAAI,IAClB,EAAe,IAAI,IACnB,EAAc,IAAI,IAElB,EAAe,GAAoB,CACvC,GAAI,CAAC,EAAM,OACX,IAAM,EAAU,EAAK,OAAS,EAE9B,GAAI,EAAQ,cAAgB,EAAQ,aAAa,KAAO,EAAG,CACzD,IAAK,IAAM,KAAc,EAAQ,aAAc,CAC7C,IAAM,EAAM,EACN,EAAa,EAAI,OAAS,EAE5B,EAAW,cACb,EAAW,YAAY,OAAO,CAAO,EACrC,EAAW,YAAY,OAAO,CAAI,EAClC,EAAW,YAAY,OAAO,CAAY,EAEtC,EAAW,OAAS,YAAc,EAAW,YAAY,OAAS,GACpE,EAAY,CAAU,EAG5B,CACA,EAAQ,aAAa,MAAM,EACvB,EAAQ,aAAa,EAAQ,YAAY,MAAM,CACrD,CACF,EAEI,EAAkB,GAEhB,EAAqB,GAAuB,CAChD,IAAM,EAAwB,EAAO,iBAQrC,GAPI,IAA0B,IAAA,IAAa,IAA2B,GAOlE,IAAqB,EAAO,OAAS,GAAiB,IAAU,EAClE,MAAO,GAGT,GAAI,CAAC,GAAiB,IAAU,EAC9B,OAAO,EAAK,IAAI,EAGlB,GAAI,IAAoB,EAAO,OAAS,EAAO,aAAe,EAC5D,MAAO,GAGT,IAAI,EAAmB,GAEvB,GAAI,GAAgB,EAAa,KAAO,EACtC,IAAK,IAAM,KAAO,EAAc,CAC9B,IAAM,EAAS,EAAI,OAAS,EAM5B,GAJI,EAAO,OAAS,YACd,EAAO,QAAQ,EAAO,OAAO,EAG9B,EAAY,eAAiB,EAAY,IAAI,CAAG,IAAM,EAAO,QAAS,CACzE,EAAmB,GACnB,KACF,CACF,CAUF,MAPA,GAAkB,EAAO,MAErB,GAAoB,EACf,EAAK,IAAI,GAGlB,EAAQ,EACD,GACT,EAEI,EAAe,EAEb,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,IAAM,EAAwB,EAAO,iBAKrC,GAJI,IAA0B,IAAA,IAAa,IAA2B,GAIlE,IAAqB,EAAO,OAAS,GAAiB,IAAU,EAClE,MAAO,GAST,GAPA,EAAmB,EAAO,MAC1B,EAAkB,EAAO,MAErB,IAA0B,IAAA,KAC5B,EAAyB,GAGvB,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,IACA,EAAa,YAAc,EAE3B,AAAsB,EAAO,WAAW,CAAC,EACzC,IAAM,EAAU,EAAO,SAGvB,GAFA,EAAQ,OAAS,EAEb,EAAa,KAAO,EACtB,IAAK,IAAM,KAAO,EAChB,EAAQ,KAAK,CAAG,EAGpB,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,GAAI,EAAQ,OAAS,EAAG,CACtB,IAAM,EAAkB,EAAQ,SAAW,EAAa,KACxD,IAAK,IAAI,EAAI,EAAG,EAAI,EAAQ,OAAQ,IAAK,CACvC,IAAM,EAAM,EAAQ,GACpB,GAAI,CAAC,GAAmB,CAAC,EAAa,IAAI,CAAG,EAAG,CAC9C,IAAM,EAAa,EAAI,OAAS,EAC5B,EAAW,aAAa,EAAW,YAAY,OAAO,CAAY,EACtE,EAAY,OAAO,CAAG,CACxB,CACF,CACF,CAEA,IAAM,EAAU,GAAW,CAAC,OAAO,GAAG,EAAO,CAAQ,EAErD,GAAI,EAAS,CACX,IAAI,EACA,EAAO,KAAO,GAAc,EAAO,QAAU,EAAO,OAAO,YAC7D,EAAwB,EAAU,IAAA,GAAa,OAAO,GAAU,UAAY,EAAiB,KAAK,MAAM,KAAK,UAAU,CAAK,CAAC,EAAI,GAGnI,EAAQ,EACR,IAEI,EAAO,KAAO,GAChB,EAAO,IAAI,CACT,KAAM,WACN,MAAO,EACP,QAAS,CAAE,KAAM,EAAuB,GAAI,CAAS,CACvD,CAAC,CAEL,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,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,CACV,IAAM,EAAW,EAAO,eACxB,GAAI,GAAY,IAAa,EAAc,CACzC,EAAY,IAAI,CAAQ,EACxB,EAAS,aAAa,IAAI,CAAY,EAEtC,IAAM,EAAe,EAAa,OAAS,EACrC,EAAc,EAAS,OAAS,EAClC,EAAY,QAAU,IAAA,IAAa,GAAgB,EAAY,QACjE,EAAY,MAAQ,EAAe,GAGjC,EAAS,cAAgB,IAAA,KAC3B,EAAa,iBAAmB,EAAS,YAE7C,CAOA,OALA,EAAkB,CAAY,EAE1B,GAAY,EAAS,aACvB,EAAS,YAAY,IAAI,EAAkB,CAAO,EAE7C,CACT,EACA,IAAI,sBAAuB,CAAE,OAAO,CAAM,EAC1C,IAAI,SAAU,CAAE,OAAO,CAAQ,EAC/B,IAAI,cAAe,CAAE,OAAO,CAAa,EAEzC,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,EAAY,IAAI,CAAU,EAC1B,EAAG,EAAiB,KAAK,MACZ,CACX,EAAW,WAAa,GACxB,EAAY,OAAO,CAAU,CAC/B,CACF,EACA,eAAe,EAA2B,CACxC,OAAQ,EAAyB,UAAU,CAAE,CAC/C,EACA,YAAe,CACb,EAAY,CAAY,EACpB,GAAa,EAAY,MAAM,EAEnC,EAAO,cAAc,OAAO,CAAE,EAC1B,EAAO,qBACT,EAAO,oBAAoB,OAAO,CAAQ,EAG5C,EAAU,GACV,EAAQ,EACR,EAAgB,EAClB,EACA,YAAY,EAA2B,CACrC,IAAM,EAAkB,CACtB,GAAI,EAAO,eACX,KAAM,SACN,IAAK,EACL,QAAS,EACX,EAEA,OADA,EAAY,IAAI,CAAU,MACb,CACX,EAAY,OAAO,CAAU,CAC/B,CACF,CACF,EAQA,MAPA,GAAiB,QAAY,EAAa,IAAI,EAC9C,EAAO,cAAc,IAAI,EAAI,CAAgB,EACzC,EAAO,WAAa,GACtB,EAAO,oBAAoB,IAAI,EAAU,CAAgB,EAE1D,EAA0B,MAAQ,EAClC,EAA0B,YAAc,EAClC,CACT,CC7VA,IAAa,GAAsB,CACjC,SAAQ,cAAa,eAKP,CACd,IAAM,EAAoB,CAAC,EAC3B,GAAI,CAAC,GAAU,CAAC,MAAM,QAAQ,CAAM,EAAG,OAAO,EAE9C,IAAK,IAAI,EAAI,EAAG,EAAM,EAAO,OAAQ,EAAI,EAAK,IAAK,CACjD,IAAM,EAAI,EAAO,GACjB,GAAI,OAAO,GAAM,SAAU,SAE3B,IAAI,EACJ,OAAQ,EAAR,CACA,IAAK,SACH,EAAY,OAAO,MAAM,EAAY,oBAAqB,GAAG,EAC7D,MAEF,QACE,EAAY,OAAO,MAAM,EAAY,mBAAoB,GAAG,EAC5D,KACF,CAEA,IAAK,IAAM,KAAK,EAAE,SAAS,CAAK,EAC1B,GAAG,QAAU,EAAQ,KAAK,EAAE,OAAO,KAAK,CAEhD,CACA,OAAO,CACT,EC3BA,SAAgB,EACd,EACA,EACA,EACW,CACX,IAAI,EAAQ,EACR,EAAU,EACV,EAAO,OAAO,GAAkB,SAAW,EAAgB,GAAe,KAE5D,GAAS,EAAmB,CAC5C,OAAQ,CAAC,CAAI,EACb,YAAa,uBACb,UAAW,QACb,CAAC,CAAC,GAAG,GAGL,IAAM,EAAc,IAAI,IAEpB,EAAgB,GAChB,EAAuB,EAErB,EAAa,CACjB,KAAM,SACN,IAAI,SAAU,CAAE,OAAO,CAAQ,EAC/B,aACF,EAEM,GAAqB,EAAsB,IAAM,CACrD,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,CAAW,OAElD,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,CACV,IAAM,EAAW,EAAO,eACxB,GAAI,EAAU,CACZ,EAAY,IAAI,EAAO,cAAc,EACrC,EAAO,eAAe,aAAa,IAAI,CAAc,EAErD,IAAM,EAAc,EAAS,OAAS,EAClC,EAAY,QAAU,IAAA,IAAa,EAAY,QAAU,IAC3D,EAAY,MAAQ,GAGlB,EAAS,cAAgB,IAAA,KAC3B,EAAwB,iBAAmB,EAAS,YAExD,CACA,OAAO,CACT,EAEA,IAAI,MAAM,EAAa,CAEjB,YAAO,GAAG,EAAO,CAAQ,GAAK,EADb,IAAU,GAA8B,OAAO,GAAU,UAAnC,IAG3C,IAAI,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,EAEP,EAAwB,cAAgB,GACzC,EAAkB,CAAC,EAEnB,EAAO,eAAe,IAAI,CAAc,EACxC,MACF,CAGA,EAAQ,EAER,IACA,EAAO,QAEP,EAAkB,CAAC,EACf,EAAO,aAAe,GAAG,EAAO,aAAa,CAvBjD,CAwBF,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,EAGA,qBACO,IACc,CAAC,OAAO,GAAG,EAAmB,CAAK,GAAwB,OAAO,GAAU,UAAnC,IAE1D,IACO,IAEF,GAIT,YAAc,GAAoC,CAC3C,IAEc,CAAC,OAAO,GAAG,EAAmB,CAAK,GAAwB,OAAO,GAAU,UAAnC,GAG1D,IACK,GACH,EAAO,QAGT,EAAkB,CAAC,GAEnB,EAAkB,CAAC,EAGrB,EAAgB,GACf,EAAwB,cAAgB,GACzC,EAAoB,EACtB,CAEF,EAIA,MAFC,GAAwB,MAAQ,EAChC,EAAwB,YAAc,EAChC,CACT,CClJA,SAAgB,EAAkB,EAAa,EAAgB,CAC7D,IAAM,EAAe,EAAO,eAC5B,EAAO,eAAiB,KACxB,GAAI,CACF,OAAO,EAAG,CACZ,QAAU,CACR,EAAO,eAAiB,CAC1B,CACF,CCVA,SAAgB,EACd,EACA,EACA,EACG,CACH,GAAuB,OAAO,GAAW,WAArC,EACF,OAAO,EAIT,GAAI,EAAO,WAAW,IAAI,CAAM,EAC9B,OAAO,EAAO,WAAW,IAAI,CAAM,EAErC,GAAI,EAAO,aAAa,IAAI,CAAM,EAChC,OAAO,EAGT,IAAM,EAAY,IAAI,IACtB,EAAO,gBAAgB,IAAI,EAAQ,CAAS,EAG5C,IAAI,EAAiB,KACjB,MAAM,QAAQ,CAAM,IACtB,EAAY,EAAO,OAAO,EAAO,OAAQ,qBAAqB,GAAQ,SAAS,GAIjF,IAAM,EAA2D,CAC/D,KAAK,GAAG,EAAa,CACnB,IAAM,EAAY,EAClB,OAAO,EAAO,UAAY,CACxB,IAAM,EAAM,MAAM,UAAU,KAAK,MAAM,EAAW,CAAI,EAItD,OAHI,IAAW,EAAU,MAAQ,EAAU,QAE3C,EAAgB,EAAW,QAAQ,EAC5B,CACT,CAAC,CACH,EACA,KAAM,CACJ,IAAM,EAAY,EAClB,OAAO,EAAO,UAAY,CACxB,IAAM,EAAM,MAAM,UAAU,IAAI,MAAM,CAAS,EAG/C,OAFI,IAAW,EAAU,MAAQ,EAAU,QAC3C,EAAgB,EAAW,QAAQ,EAC5B,CACT,CAAC,CACH,EACA,OAAQ,CACN,IAAM,EAAY,EAClB,OAAO,EAAO,UAAY,CACxB,IAAM,EAAM,MAAM,UAAU,MAAM,MAAM,CAAS,EAGjD,OAFI,IAAW,EAAU,MAAQ,EAAU,QAC3C,EAAgB,EAAW,QAAQ,EAC5B,CACT,CAAC,CACH,EACA,QAAQ,GAAG,EAAa,CACtB,IAAM,EAAY,EAClB,OAAO,EAAO,UAAY,CACxB,IAAM,EAAM,MAAM,UAAU,QAAQ,MAAM,EAAW,CAAI,EAGzD,OAFI,IAAW,EAAU,MAAQ,EAAU,QAC3C,EAAgB,EAAW,QAAQ,EAC5B,CACT,CAAC,CACH,EACA,OAAO,GAAG,EAAa,CACrB,IAAM,EAAY,EAClB,OAAO,EAAO,UAAY,CAExB,IAAM,EAAO,MAAM,UAAU,OAAe,MAAM,EAAW,CAAI,EAGjE,OAFI,IAAW,EAAU,MAAQ,EAAU,QAC3C,EAAgB,EAAW,QAAQ,EAC5B,CACT,CAAC,CACH,EACA,SAAU,CACR,IAAM,EAAY,EAClB,OAAO,EAAO,UAAY,CACxB,IAAM,EAAM,MAAM,UAAU,QAAQ,MAAM,CAAS,EAC/C,IACF,EAAU,MAAQ,EAAU,QAK9B,IAAK,IAAI,EAAI,EAAG,EAAI,EAAU,OAAQ,IACpC,EAAgB,EAAW,OAAO,CAAC,CAAC,EACpC,EAAgB,EAAW,OAAO,CAAC,CAAC,EAItC,OADA,EAAgB,EAAW,QAAQ,EAC5B,CACT,CAAC,CACH,EACA,KAAK,EAAwC,CAC3C,IAAM,EAAY,EAClB,OAAO,EAAO,UAAY,CACxB,IAAM,EAAO,MAAM,UAAU,KAAa,MAAM,EAAW,CAAC,CAAS,CAAC,EAGtE,OAFI,IAAW,EAAU,MAAQ,EAAU,QAC3C,EAAgB,EAAW,QAAQ,EAC5B,CACT,CAAC,CACH,CACF,EAEA,SAAS,EAAgB,EAAgB,EAAsB,CAC7D,IAAM,EAAM,EAAO,gBAAgB,IAAI,CAAS,EAChD,GAAI,EAAK,CACP,IAAM,EAAM,EAAI,IAAI,CAAG,EACnB,IAEF,EAAI,OAAS,EAAI,OAAS,GAAK,EAEnC,CACF,CAuFA,IAAM,EAAQ,IAAI,MAAM,EAAQ,CApF9B,IAAI,EAAW,EAAK,EAAU,CAC5B,GAAI,IAAQ,YAAa,MAAO,GAChC,GAAI,IAAQ,UAAW,OAAO,EAC9B,GAAI,IAAQ,aAAc,OAAO,EAGjC,GAAI,MAAM,QAAQ,CAAS,GAAK,OAAO,UAAU,eAAe,KAAK,EAAuB,CAAG,EAC7F,OAAO,EAAsB,EAAI,CAAC,KAAK,CAAQ,EAIjD,GAAI,EAAO,eAAgB,CACzB,IAAI,EAAM,EAAU,IAAI,CAAG,EACtB,IACH,EAAM,EAAO,OAAO,EAAG,YAAY,GAAQ,SAAS,GAAG,OAAO,CAAG,GAAG,EACpE,EAAU,IAAI,EAAK,CAAG,GAGxB,EAAI,MACA,IAAQ,UAAY,GACtB,EAAU,KAEd,CAEA,IAAM,EAAM,QAAQ,IAAI,EAAW,EAAK,CAAQ,EAMhD,OAHoB,OAAO,GAAQ,UAA/B,EACK,EAAe,EAAQ,EAAK,GAAG,GAAQ,SAAS,GAAG,OAAO,CAAG,GAAG,EAElE,CACT,EAEA,IAAI,EAAW,EAAK,EAAU,EAAU,CACtC,IAAM,EAAW,QAAQ,IAAI,EAAW,EAAK,CAAQ,EAGrD,GAAI,OAAO,GAAG,EAAU,CAAQ,GAAK,IAAQ,SAC3C,MAAO,GAGT,IAAM,EAAM,QAAQ,IAAI,EAAW,EAAK,EAAU,CAAQ,EAC1D,GAAI,EAAK,CAEP,IAAI,EAAM,EAAU,IAAI,CAAG,EACvB,IACF,EAAI,OAAS,EAAI,OAAS,GAAK,GAE7B,MAAM,QAAQ,CAAS,GAAK,IAAQ,UAAY,IAElD,EAAU,MAAQ,EAAU,OAEhC,CACA,OAAO,CACT,EAEA,eAAe,EAAW,EAAK,CAC7B,IAAM,EAAS,QAAQ,IAAI,EAAW,CAAG,EACnC,EAAM,QAAQ,eAAe,EAAW,CAAG,EACjD,GAAI,GAAO,EAAQ,CACjB,IAAI,EAAM,EAAU,IAAI,CAAG,EACvB,IACF,EAAI,OAAS,EAAI,OAAS,GAAK,GAE7B,MAAM,QAAQ,CAAS,GAAK,IAC9B,EAAU,MAAQ,EAAU,OAEhC,CACA,OAAO,CACT,EAEA,QAAQ,EAAW,CACjB,GAAI,EAAO,eAAgB,CACzB,IAAI,EAAM,EAAU,IAAI,aAAa,EAChC,IACH,EAAM,EAAO,OAAO,EAAG,YAAY,GAAQ,SAAS,aAAa,EACjE,EAAU,IAAI,cAAe,CAAG,GAElC,EAAI,KACN,CACA,OAAO,QAAQ,QAAQ,CAAS,CAClC,CAG8B,CAAO,EAIvC,OAHA,EAAO,WAAW,IAAI,EAAQ,CAAK,EACnC,EAAO,aAAa,IAAI,CAAK,EAEtB,CACT,CCnMA,SAAgB,EAAa,EAAa,EAAc,EAAiC,CACvF,IAAI,EAAa,GACb,EAAY,GACZ,EAAQ,EAEN,EAAe,IAAI,IACnB,EAAc,IAAI,IAClB,EAAe,IAAI,IAEnB,MAAwB,CAE5B,GAAI,EAAa,KAAO,EAAG,CACzB,IAAM,EAAe,EAAO,eACtB,EAAY,EAAO,YACzB,EAAO,eAAiB,KACxB,EAAO,YAAc,KAErB,IAAK,IAAM,KAAS,EACd,EAAM,SAAS,EAAM,QAAQ,EAEnC,EAAa,MAAM,EAEnB,EAAO,eAAiB,EACxB,EAAO,YAAc,CACvB,CAGA,GAAI,EAAW,SAAS,KAAO,EAAG,CAChC,IAAM,EAAe,EAAO,eAC5B,EAAO,eAAiB,KAExB,IAAK,IAAM,KAAW,EAAW,SAC/B,GAAI,CACF,EAAQ,CACV,OAAS,EAAK,CACZ,QAAQ,MAAM,CAAG,CACnB,CAGF,EAAW,SAAS,MAAM,EAC1B,EAAO,eAAiB,CAC1B,CACF,EAEM,EAA8B,CAClC,GAAI,EAAO,eACX,eACA,eACA,SAAU,IAAI,IACd,KAAM,SACN,MAAO,EACP,MAAO,EAEP,IAAI,SAAmB,CAAE,OAAO,EAAQ,CAAE,EAC1C,IAAI,QAAQ,EAAc,CAAM,IAAK,EAAQ,EAAE,EAE/C,IAAI,YAAsB,CAAE,OAAO,CAAW,EAC9C,IAAI,WAAW,EAAc,CAAE,EAAa,CAAI,EAEhD,IAAI,OAAgB,CAAE,OAAO,CAAM,EACnC,IAAI,MAAM,EAAa,CAAE,EAAQ,CAAI,EACrC,IAAI,aAAgC,CAAE,OAAO,CAAY,EACzD,IAAI,OAAa,CAAE,OAAO,CAAW,EAErC,cAAiB,CACX,GAAS,IACb,EAAQ,EACR,EAAO,eAAe,CAAU,EAClC,EAEA,QAAW,CACT,GAAI,GAAc,EAAW,OAC7B,EAAY,GAEZ,EAAgB,EAEhB,IAAM,EAAe,EAAO,eACtB,EAAY,EAAO,YAEzB,EAAO,eAAiB,EACxB,EAAO,YAAc,EAErB,IAAM,EAAU,EAAa,KAAO,EAAI,MAAM,KAAK,CAAY,EAAI,KACnE,EAAa,MAAM,EAEnB,GAAI,CACF,EAAQ,EAER,IAAM,EAAS,EAAG,EAKlB,GAJI,OAAO,GAAW,YACpB,EAAW,SAAS,IAAI,CAAM,EAG5B,IAAY,KACd,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,CAAU,EACpE,EAAY,OAAO,CAAG,CACxB,CACF,CAGF,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,CAAU,EACvD,EAAQ,QAAU,IAAA,IAAa,EAAQ,MAAQ,IACjD,EAAc,EAAQ,MAE1B,CACA,EAAW,MAAQ,EAAc,CAEnC,QAAU,CACR,EAAY,GACZ,EAAO,eAAiB,EACxB,EAAO,YAAc,CACvB,CACF,EAEA,YAAe,CACT,MAIJ,CAHA,EAAa,GACb,EAAW,WAAa,GAExB,EAAgB,EAGhB,IAAK,IAAM,KAAO,EAAc,CAC9B,IAAM,EAAU,EAAI,OAAS,EACzB,EAAQ,aAAa,EAAQ,YAAY,OAAO,CAAU,CAChE,CACA,EAAa,MAAM,EACnB,EAAY,MAAM,CARF,CASlB,CACF,EAEM,EAAkB,EAAO,YAAe,EAAO,YAAY,OAAS,EAAO,YAAe,KAQhG,OANI,GAAmB,EAAgB,cACrC,EAAgB,aAAa,IAAI,CAAU,EAG7C,EAAW,IAAI,MAEF,CACX,EAAW,QAAQ,CACrB,CACF,CCvJA,IAAa,EAAb,KAAgC,CAC9B,gBAA4B,OAC5B,OACA,MAAe,EACf,eAA6B,KAC7B,WAAoB,EACpB,aAAsB,EACtB,eAAqD,CAAC,EACtD,gBAAyB,EACzB,cAAuB,IAAI,QAC3B,oBAA6B,IAAI,IACjC,WAAqB,IAAI,IACzB,QAAkB,IAAI,IACtB,WAAqB,IAAI,QACzB,aAAuB,IAAI,QAC3B,gBAA0B,IAAI,QAC9B,oBAA6B,IAAI,IACjC,eAAwB,IAAI,IAC5B,YAA0B,KAC1B,gBAAyB,IAAI,IAC7B,iBAA0B,GAC1B,SAAyB,CAAC,EAE1B,aAAoB,EAA2B,CAC7C,KAAK,gBAAgB,IAAI,CAAO,CAClC,CAEA,YAAY,EAA4C,CACtD,KAAK,OAAS,GAAS,QAAU,CAAE,UAAW,EAAM,EACpD,KAAK,iBAAmB,CAAC,CAAC,KAAK,OAAO,SACxC,CAEA,eAAsB,EAAmB,CACvC,IAAM,EAAQ,EAAO,OAAS,EACzB,KAAK,eAAe,KACvB,KAAK,eAAe,GAAS,IAAI,KAEnC,KAAK,eAAe,EAAM,CAAE,IAAI,CAAM,EAClC,EAAQ,KAAK,kBACf,KAAK,gBAAkB,EAE3B,CAEA,MAAgB,EAAgB,CAC9B,KAAK,aACL,GAAI,CACF,OAAO,EAAG,CACZ,QAAU,CAER,GADA,KAAK,aACD,KAAK,aAAe,EAAG,CAIzB,GAHA,AAAqC,KAAc,mBAAmB,EACrE,KAAc,mBAEX,KAAK,eAAe,KAAO,EAAG,CAChC,IAAM,EAAc,IAAI,IAGxB,IAAK,IAAM,KAAO,KAAK,eACjB,EAAI,kBACN,EAAY,IAAI,EAAK,EAAI,iBAAiB,CAAC,EAK/C,KAAK,QAGL,IAAK,IAAM,KAAO,KAAK,eACrB,GAAI,EAAI,YAAa,CACnB,IAAM,EAAU,EAAY,IAAI,CAAG,GAAK,GACxC,EAAI,YAAY,EAAS,EAAI,CAC/B,CAEF,KAAK,eAAe,MAAM,CAC5B,CAGA,KAAK,aAAa,CACpB,CACF,CACF,CAEA,cAA4B,CAC1B,GAAI,KAAK,WAAa,EAAG,OACzB,IAAM,EAAe,KAAK,eAE1B,GAAI,CACF,IAAK,IAAI,EAAQ,EAAG,GAAS,KAAK,gBAAiB,IAAS,CAC1D,IAAM,EAAS,KAAK,eAAe,GACnC,GAAI,CAAC,GAAU,EAAO,OAAS,EAAG,SAElC,IAAM,EAAU,MAAM,KAAK,CAAM,EACjC,EAAO,MAAM,EAEb,IAAK,IAAM,KAAU,EACf,MAAO,YACN,EAAO,QAEZ,IAAI,EAAO,cAAgB,EAAO,aAAa,KAAO,EAAG,CACvD,IAAI,EAAgB,GACpB,IAAK,IAAM,KAAO,EAAO,aAAc,CACrC,IAAM,EAAU,EAAI,OAAS,EACzB,EAAQ,OAAS,YAAc,EAAQ,MAAQ,GAC7C,EAAQ,QAAQ,EAAQ,OAAO,EAEjC,EAAO,aAAe,EAAO,YAAY,IAAI,CAAG,IAAM,EAAQ,UAChE,EAAgB,GAEpB,CACA,GAAI,CAAC,GAAiB,EAAO,aAAa,KAAO,EAAG,CAClD,EAAO,QAAU,GACjB,QACF,CACF,CAEA,GAAI,CACF,EAAO,IAAI,CACb,OAAS,EAAK,CACZ,MAAM,CACR,CANA,CASF,GAAI,EAAQ,EAAG,CACb,IAAI,EAAoB,GACxB,IAAK,IAAI,EAAI,EAAG,EAAI,EAAO,IACzB,GAAI,KAAK,eAAe,IAAM,KAAK,eAAe,EAAE,CAAE,KAAO,EAAG,CAC9D,EAAoB,GACpB,KACF,CAEE,IAAmB,EAAQ,GACjC,CACF,CACA,KAAK,gBAAkB,CACzB,QAAU,CACR,KAAK,eAAiB,CACxB,CACF,CAEA,OAAiB,EAAiB,EAAsD,CACtF,OAAO,EAAgB,KAAM,EAAc,CAAa,CAC1D,CAEA,SAAmB,EAAa,EAAkC,CAChE,OAAO,EAAkB,KAAM,EAAI,CAAU,CAC/C,CAEA,OAAc,EAA4B,EAAiC,CACzE,OAAO,EAAa,KAAM,EAAI,CAAU,CAC1C,CAEA,QAAkB,EAAgB,CAChC,OAAO,EAAkB,KAAM,CAAE,CACnC,CAEA,SAAkC,EAAW,EAAkB,CAC7D,OAAO,EAAkB,KAAM,EAAQ,CAAI,CAC7C,CAEA,QAAkB,EAA0B,EAAsC,CAChF,KAAK,WAAW,IAAI,EAAO,CAAc,EACzC,KAAK,QAAQ,OAAO,CAAK,CAC3B,CAEA,OAAiB,EAA6B,CAC5C,GAAI,GAAiC,KAAM,MAAU,MAAM,2BAA2B,EACtF,GAAI,KAAK,QAAQ,IAAI,CAAK,EAAG,OAAO,KAAK,QAAQ,IAAI,CAAK,EAC1D,GAAI,KAAK,oBAAoB,IAAI,CAAK,EAAG,MAAU,MAAM,uCAAuC,EAChG,KAAK,oBAAoB,IAAI,CAAK,EAClC,GAAI,CACF,GAAI,KAAK,WAAW,IAAI,CAAK,EAAG,CAC9B,IAAM,EAAQ,KAAK,WAAW,IAAI,CAAK,EACvC,GAAI,OAAO,GAAU,WAAY,CAC/B,IAAM,EAAM,EAAM,SAAS,EAE3B,GAAI,EADY,EAAI,WAAW,QAAQ,GAAK,EAAI,WAAW,QAAQ,GAAM,EAAM,WAAa,EAAM,UAAU,cAAgB,GAAS,CAAC,EAAI,WAAW,UAAU,GAAK,CAAC,EAAI,SAAS,IAAI,GACxK,CACZ,IAAM,EAAY,EAAqB,IAAI,EAE3C,OADA,KAAK,QAAQ,IAAI,EAAO,CAAQ,EACzB,CACT,CACA,OAAO,CACT,CACA,OAAO,CACT,CACA,GAAI,OAAO,GAAU,WAAY,CAC/B,IAAM,EAAW,IAAK,EAAyB,IAAI,EAEnD,OADA,KAAK,QAAQ,IAAI,EAAO,CAAQ,EACzB,CACT,CACA,MAAU,MAAM,4BAA4B,CAC9C,QAAU,CACR,KAAK,oBAAoB,OAAO,CAAK,CACvC,CACF,CAEA,SACE,EACA,EACA,EACa,CACb,IAAM,EAAkB,GAAiB,OAAO,GAAkB,SAC5D,EAAqB,EAAoB,EAAwC,MAAQ,mBAAuB,GAA4B,mBAE5I,EAA0C,EAAmB,EAA0C,CAAC,EACxG,EAA0B,EAAQ,yBAA2B,GAC7D,EAAmB,EAAQ,iBAC3B,EAAsB,EAAQ,oBAE9B,EAAQ,KAAK,OACjB,CAAE,KAAM,KAAM,QAAS,GAAM,MAAO,KAAM,WAAY,EAAM,EAC5D,2CAA2C,GAC7C,EAEM,EAAO,MAAO,EAAW,EAA2B,EAAiB,KAAU,CAC/E,MAAa,QACjB,IAAI,EAAqB,CACvB,IAAM,EAAsB,EAAoB,CAAM,EACtD,GAAI,IAAwB,IAAS,OAAO,GAAwB,SAAU,CAC5E,GAAI,EAAa,QAAS,OAC1B,IAAM,EAAW,OAAO,GAAwB,SAAW,EAAsB,8BACjF,EAAM,MAAQ,CAAE,KAAM,EAAiB,KAAO,EAAM,MAAM,KAAM,QAAS,GAAO,MAAO,EAAU,WAAY,EAAM,EACnH,MACF,CACF,CAEA,EAAM,MAAQ,CAAE,KAAO,GAAkB,EAA2B,KAAO,EAAM,MAAM,KAAM,QAAS,GAAM,MAAO,KAAM,WAAY,EAAM,EAE3I,GAAI,CACF,IAAM,EAAO,MAAM,EAAQ,EAAQ,CAAY,EAC/C,GAAI,EAAa,QAAS,OAC1B,GAAI,EAAkB,CACpB,IAAM,EAAmB,EAAiB,CAAI,EAC9C,GAAI,IAAqB,IAAS,OAAO,GAAqB,SAAU,CAEtE,EAAM,MAAQ,CAAE,KAAM,KAAM,QAAS,GAAO,MAD3B,OAAO,GAAqB,SAAW,EAAmB,oBACd,WAAY,EAAM,EAC/E,MACF,CACF,CACA,EAAM,MAAQ,CAAE,OAAM,QAAS,GAAO,MAAO,KAAM,WAAY,EAAM,CACvE,OAAS,EAAQ,CACf,GAAI,EAAa,QAAS,OAC1B,EAAM,MAAQ,CAAE,KAAM,KAAM,QAAS,GAAO,MAAO,EAAE,SAAW,cAAe,WAAY,EAAM,CACnG,CAnBA,CAoBF,EAEI,EAA2C,KAc/C,OAZA,KAAK,WAAa,CAChB,IAAM,EAAS,EAAS,EAAO,MAAQ,IAAA,GACjC,EAAa,IAAI,gBAOvB,MANA,GAAmB,EAEnB,KAAK,YAAc,CACjB,EAAK,EAAQ,EAAW,OAAQ,EAAI,CACtC,CAAC,MAEY,EAAW,MAAM,CAChC,CAAC,EAEM,CACL,IAAI,MAAO,CAAE,OAAO,EAAM,MAAM,IAAK,EACrC,IAAI,SAAU,CAAE,OAAO,EAAM,MAAM,OAAQ,EAC3C,IAAI,OAAQ,CAAE,OAAO,EAAM,MAAM,KAAM,EACvC,IAAI,YAAa,CAAE,OAAO,EAAM,MAAM,UAAW,EACjD,IAAI,OAAQ,CAAE,OAAO,EAAM,KAAM,EACjC,YAAe,CACb,GAAkB,MAAM,EACxB,IAAM,EAAa,IAAI,gBACvB,EAAmB,EACnB,EAAK,EAAS,EAAO,MAAQ,IAAA,GAAgB,EAAW,OAAQ,EAAK,CACvE,EACA,UAAY,GAAwC,EAAM,UAAU,CAAE,CACxE,CACF,CAEF,EAEa,EAAb,cAA6C,CAAmB,CAAC,EChSpD,EAAb,cAA6C,CAAmB,CAAC,ECMpD,EAAb,cAA2C,CAAwB,CACjE,aAAkC,CAAC,EACnC,qBAA8B,GAE9B,SAAgB,EAAc,EAAc,EAAkB,CAC5D,KAAK,aAAa,KAAK,CAAE,OAAM,OAAM,OAAM,UAAW,KAAK,IAAI,CAAE,CAAC,EAC7D,KAAK,uBACR,KAAK,qBAAuB,GAC5B,mBAAqB,KAAK,UAAU,CAAC,EAEzC,CAEA,WAAyB,CACvB,KAAK,qBAAuB,GACxB,KAAK,aAAa,SAAW,IAC7B,OAAO,QAAY,KAAA,QAAA,IAAA,WAAwC,SAC7D,QAAQ,MAAM,iCAAiC,KAAK,aAAa,OAAO,UAAU,EAClF,KAAK,aAAa,QAAQ,GAAO,QAAQ,IAAI,IAAI,EAAI,KAAK,YAAY,EAAE,IAAI,EAAI,OAAQ,EAAI,MAAQ,EAAE,CAAC,EACvG,QAAQ,SAAS,GAEnB,KAAK,aAAe,CAAC,EACvB,CAEA,SAA4B,EAAa,EAAkC,CACzE,IAAM,EAAS,KACT,EAAO,GAAc,mBACrB,EAAmB,MAAM,SAAS,EAAI,CAAU,EAClD,EAAc,GAEZ,EAAuC,CAC3C,IAAI,OAAW,CACb,GAAI,EAAa,OAAO,EAAiB,MACzC,IAAM,EAAY,OAAO,YAAgB,IAAc,YAAY,IAAI,EAAI,EACrE,EAAM,EAAiB,MAK7B,OAHI,GACF,EAAO,SAAS,WAAY,EAAM,CAAE,MAAO,EAAK,SAAU,IAAI,YAAY,IAAI,EAAI,EAAA,CAAW,QAAQ,CAAC,EAAE,GAAI,CAAC,EAExG,CACT,EACA,UAAY,GAAO,EAAiB,UAAU,CAAE,EAChD,SAAU,CACR,EAAc,GACd,EAAiB,QAAQ,CAC3B,CACF,EASA,MAPI,UAAW,GACb,OAAO,eAAe,EAAyB,QAAS,CACtD,MAAQ,EAAyB,MACjC,WAAY,EACd,CAAC,EAGI,CACT,CACF,EC7DI,EAAe,IAAI,EAAmB,CAAE,OAAQ,CAAE,UAAW,EAAM,CAAE,CAAC,EAE7D,GAAa,EAAiB,IAAkB,EAAa,OAAO,EAAc,CAAO,EACzF,GAAe,EAAa,IAAkB,EAAa,SAAS,EAAI,CAAI,EAC5E,GAAU,EAAe,IAAkB,EAAa,OAAO,EAAI,CAAI,EACvE,EAAY,GAAmB,EAAa,MAAM,CAAE,EACpD,EAAc,GAAmB,EAAa,QAAQ,CAAE,EAOrE,SAAgB,GAAkC,CAEhD,EAAe,IAAI,EAAmB,CAAE,OAAQ,CAAE,UAAW,EAAM,CAAE,CAAC,CACxE,CCjBA,IAAsB,EAAtB,KAAsC,CACd,OAAtB,YAAY,EAA2C,CAAjC,KAAA,OAAA,EAEpB,KAAK,OAAO,CACd,CAGA,oBAA8B,EAAa,EAAc,CACvD,OAAO,KAAK,OAAO,OAAO,EAAK,CAC7B,OACA,SAAW,GAAM,OAAO,GAAM,UAAY,CAAC,MAAM,CAAC,CACpD,CAAC,CACH,CAEA,eAA4B,EAAa,CACvC,OAAO,KAAK,OAAO,SAAS,CAAE,CAChC,CAEA,aAA0B,EAAQ,EAAe,CAC/C,OAAO,KAAK,OAAO,OAAO,EAAK,CAAI,CACrC,CAIA,QAAyB,CAAE,CAC7B,EAEa,EAAgB,EC3BP,EAAtB,KAA4C,CACpB,OAAtB,YAAY,EAAsC,CAA5B,KAAA,OAAA,EACpB,eAAiB,KAAK,OAAO,EAAG,CAAC,CACnC,CAEA,QAAyB,CAAE,CAC7B"}
|
package/dist/vue/index.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../core.cjs"),t=require("./core.vue-adapter.cjs");let n=require("vue");var r=class extends e.
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../core.cjs"),t=require("./core.vue-adapter.cjs");let n=require("vue");var r=class extends e.ReactiveEngineAutomatic{frameworkPrefix=`vue-auto`;reactive(e,t){let n=e=>{if(!(!e||typeof e!=`object`||Symbol.iterator in e)){Reflect.has(e,`__subscribe`)||Object.defineProperty(e,"__subscribe",{get:()=>e=>this.effect(()=>{try{JSON.stringify(r)}catch{Object.values(r)}e()},`vue-proxy-internal-subscription`),configurable:!0,enumerable:!1}),Reflect.has(e,`__v_skip`)||Object.defineProperty(e,"__v_skip",{get:()=>!0,configurable:!0,enumerable:!1});for(let t in e)Object.prototype.hasOwnProperty.call(e,t)&&typeof e[t]==`object`&&n(e[t])}};n(e);let r=super.reactive(e,t);return r}use(e){if(typeof e!=`object`||!e)return(0,n.shallowRef)(e);if(`subscribe`in e&&typeof e.subscribe==`function`){let t=e,r=(0,n.shallowRef)(this.untrack(()=>t.value)),i=`__subscribe`in t&&typeof t.__subscribe==`function`?t.__subscribe(()=>{r.value=t.value,(0,n.triggerRef)(r)}):t.subscribe(e=>{r.value=e,(0,n.triggerRef)(r)});return(0,n.getCurrentInstance)()?(0,n.onUnmounted)(()=>i()):(0,n.getCurrentScope)()&&(0,n.onScopeDispose)(()=>i()),r}let t=(0,n.shallowRef)(e);if(`__subscribe`in e&&typeof e.__subscribe==`function`){let r=e.__subscribe(()=>{(0,n.triggerRef)(t)});(0,n.getCurrentInstance)()?(0,n.onUnmounted)(()=>r()):(0,n.getCurrentScope)()&&(0,n.onScopeDispose)(()=>r())}return t}};exports.ReactiveEngine=r,exports.useReactiveValue=t.useReactiveValue;
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|
package/dist/vue/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":[],"sources":["../../src/vue/index.ts"],"sourcesContent":["import { CleanupFn, ISignalLike } from '../core/types'\nimport { ReactiveEngineAutomatic } from '../core/core'\nimport { getCurrentInstance, getCurrentScope, onScopeDispose, onUnmounted, shallowRef, ShallowRef, triggerRef } from 'vue'\n\nexport { useReactiveValue } from './core.vue-adapter'\n\nclass ExtendedReactiveEngine extends ReactiveEngineAutomatic {\n protected override frameworkPrefix = 'vue-auto'\n\n public override reactive<T extends object>(target: T, name?: string): T {\n const injectVueMarkers = (obj: any) => {\n if (!obj || typeof obj !== 'object' || Symbol.iterator in obj) return\n\n if (!Reflect.has(obj, '__subscribe')) {\n Object.defineProperty(obj, '__subscribe', {\n get: () => {\n return (cb: () => void) => {\n return this.effect(() => {\n try {\n JSON.stringify(originalProxy)\n } catch (e) {\n Object.values(originalProxy as Record<string, unknown>)\n }\n cb()\n }, 'vue-proxy-internal-subscription')\n }\n },\n configurable: true,\n enumerable: false\n })\n }\n\n if (!Reflect.has(obj, '__v_skip')) {\n Object.defineProperty(obj, '__v_skip', {\n get: () => true,\n configurable: true,\n enumerable: false\n })\n }\n\n for (const key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key) && typeof obj[key] === 'object') {\n injectVueMarkers(obj[key])\n }\n }\n }\n\n injectVueMarkers(target)\n const originalProxy = super.reactive(target, name)\n return originalProxy\n }\n\n /**\n * Адаптирует примитивы реактивного ядра во Vue ShallowRef объекты.\n * Полностью изолирует начальное чтение от реактивного контекста ядра (Topological Isolation).\n */\n public use<T>(item: T): T extends ISignalLike<infer V> ? ShallowRef<V> : ShallowRef<T> {\n if (item === null || item === undefined || typeof item !== 'object') {\n return shallowRef(item) as any\n }\n\n const isSignal = 'subscribe' in item && typeof (item as Record<string, unknown>).subscribe === 'function'\n\n if (isSignal) {\n const signalItem = (item as unknown) as ISignalLike<unknown>\n \n // ⚛️ КЛЮЧЕВОЙ ФИКС: Чтение стартового значения оборачиваем в untrack(),\n // предотвращая ложные каскадные вызовы Pull-валидатора при инициализации!\n const initialValue = this.untrack(() => signalItem.value)\n const state = shallowRef(initialValue)\n\n // Используем пассивный хук __subscribe, если он доступен (для computed-нод),\n // чтобы избежать спама множественных push-уведомлений посреди транзакции\n const hasHook = '__subscribe' in signalItem && typeof (signalItem as any).__subscribe === 'function'\n \n const unsubscribe = hasHook \n ? (signalItem as any).__subscribe(() => {\n state.value = signalItem.value\n triggerRef(state)\n })\n : signalItem.subscribe((newValue) => {\n state.value = newValue\n triggerRef(state)\n })\n\n if (getCurrentInstance()) {\n onUnmounted(() => unsubscribe())\n } else if (getCurrentScope()) {\n onScopeDispose(() => unsubscribe())\n }\n\n return state as any\n }\n\n const state = shallowRef(item)\n\n if ('__subscribe' in item && typeof (item as Record<string, unknown>).__subscribe === 'function') {\n const unsubscribe = ((item as Record<string, unknown>).__subscribe as (cb: () => void) => CleanupFn)(() => {\n triggerRef(state)\n })\n\n if (getCurrentInstance()) {\n onUnmounted(() => unsubscribe())\n } else if (getCurrentScope()) {\n onScopeDispose(() => unsubscribe())\n }\n }\n\n return state as any\n }\n}\n\nexport { ExtendedReactiveEngine as ReactiveEngine }\n"],"mappings":"2JAMA,IAAM,EAAN,cAAqC,EAAA,
|
|
1
|
+
{"version":3,"file":"index.cjs","names":[],"sources":["../../src/vue/index.ts"],"sourcesContent":["import { CleanupFn, ISignalLike } from '../core/types'\nimport { ReactiveEngineAutomatic } from '../core/core'\nimport { getCurrentInstance, getCurrentScope, onScopeDispose, onUnmounted, shallowRef, ShallowRef, triggerRef } from 'vue'\n\nexport { useReactiveValue } from './core.vue-adapter'\n\nclass ExtendedReactiveEngine extends ReactiveEngineAutomatic {\n protected override frameworkPrefix = 'vue-auto'\n\n public override reactive<T extends object>(target: T, name?: string): T {\n const injectVueMarkers = (obj: any) => {\n if (!obj || typeof obj !== 'object' || Symbol.iterator in obj) return\n\n if (!Reflect.has(obj, '__subscribe')) {\n Object.defineProperty(obj, '__subscribe', {\n get: () => {\n return (cb: () => void) => {\n return this.effect(() => {\n try {\n JSON.stringify(originalProxy)\n } catch (e) {\n Object.values(originalProxy as Record<string, unknown>)\n }\n cb()\n }, 'vue-proxy-internal-subscription')\n }\n },\n configurable: true,\n enumerable: false\n })\n }\n\n if (!Reflect.has(obj, '__v_skip')) {\n Object.defineProperty(obj, '__v_skip', {\n get: () => true,\n configurable: true,\n enumerable: false\n })\n }\n\n for (const key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key) && typeof obj[key] === 'object') {\n injectVueMarkers(obj[key])\n }\n }\n }\n\n injectVueMarkers(target)\n const originalProxy = super.reactive(target, name)\n return originalProxy\n }\n\n /**\n * Адаптирует примитивы реактивного ядра во Vue ShallowRef объекты.\n * Полностью изолирует начальное чтение от реактивного контекста ядра (Topological Isolation).\n */\n public use<T>(item: T): T extends ISignalLike<infer V> ? ShallowRef<V> : ShallowRef<T> {\n if (item === null || item === undefined || typeof item !== 'object') {\n return shallowRef(item) as any\n }\n\n const isSignal = 'subscribe' in item && typeof (item as Record<string, unknown>).subscribe === 'function'\n\n if (isSignal) {\n const signalItem = (item as unknown) as ISignalLike<unknown>\n \n // ⚛️ КЛЮЧЕВОЙ ФИКС: Чтение стартового значения оборачиваем в untrack(),\n // предотвращая ложные каскадные вызовы Pull-валидатора при инициализации!\n const initialValue = this.untrack(() => signalItem.value)\n const state = shallowRef(initialValue)\n\n // Используем пассивный хук __subscribe, если он доступен (для computed-нод),\n // чтобы избежать спама множественных push-уведомлений посреди транзакции\n const hasHook = '__subscribe' in signalItem && typeof (signalItem as any).__subscribe === 'function'\n \n const unsubscribe = hasHook \n ? (signalItem as any).__subscribe(() => {\n state.value = signalItem.value\n triggerRef(state)\n })\n : signalItem.subscribe((newValue) => {\n state.value = newValue\n triggerRef(state)\n })\n\n if (getCurrentInstance()) {\n onUnmounted(() => unsubscribe())\n } else if (getCurrentScope()) {\n onScopeDispose(() => unsubscribe())\n }\n\n return state as any\n }\n\n const state = shallowRef(item)\n\n if ('__subscribe' in item && typeof (item as Record<string, unknown>).__subscribe === 'function') {\n const unsubscribe = ((item as Record<string, unknown>).__subscribe as (cb: () => void) => CleanupFn)(() => {\n triggerRef(state)\n })\n\n if (getCurrentInstance()) {\n onUnmounted(() => unsubscribe())\n } else if (getCurrentScope()) {\n onScopeDispose(() => unsubscribe())\n }\n }\n\n return state as any\n }\n}\n\nexport { ExtendedReactiveEngine as ReactiveEngine }\n"],"mappings":"2JAMA,IAAM,EAAN,cAAqC,EAAA,uBAAwB,CAC3D,gBAAqC,WAErC,SAA2C,EAAW,EAAkB,CACtE,IAAM,EAAoB,GAAa,CACjC,MAAC,GAAO,OAAO,GAAQ,UAAY,OAAO,YAAY,GAqB1D,CAnBK,QAAQ,IAAI,EAAK,aAAa,GACjC,OAAO,eAAe,EAAK,cAAe,CACxC,QACU,GACC,KAAK,WAAa,CACvB,GAAI,CACF,KAAK,UAAU,CAAa,CAC9B,MAAY,CACV,OAAO,OAAO,CAAwC,CACxD,CACA,EAAG,CACL,EAAG,iCAAiC,EAGxC,aAAc,GACd,WAAY,EACd,CAAC,EAGE,QAAQ,IAAI,EAAK,UAAU,GAC9B,OAAO,eAAe,EAAK,WAAY,CACrC,QAAW,GACX,aAAc,GACd,WAAY,EACd,CAAC,EAGH,IAAK,IAAM,KAAO,EACZ,OAAO,UAAU,eAAe,KAAK,EAAK,CAAG,GAAK,OAAO,EAAI,IAAS,UACxE,EAAiB,EAAI,EAAI,CAL1B,CAQL,EAEA,EAAiB,CAAM,EACvB,IAAM,EAAgB,MAAM,SAAS,EAAQ,CAAI,EACjD,OAAO,CACT,CAMA,IAAc,EAAyE,CACrF,GAA2C,OAAO,GAAS,WAAvD,EACF,OAAA,EAAA,EAAA,WAAA,CAAkB,CAAI,EAKxB,GAFiB,cAAe,GAAQ,OAAQ,EAAiC,WAAc,WAEjF,CACZ,IAAM,EAAc,EAKd,GAAA,EAAA,EAAA,WAAA,CADe,KAAK,YAAc,EAAW,KAC1B,CAAY,EAM/B,EAFU,gBAAiB,GAAc,OAAQ,EAAmB,aAAgB,WAGrF,EAAmB,gBAAkB,CACpC,EAAM,MAAQ,EAAW,OACzB,EAAA,EAAA,WAAA,CAAW,CAAK,CAClB,CAAC,EACD,EAAW,UAAW,GAAa,CACjC,EAAM,MAAQ,GACd,EAAA,EAAA,WAAA,CAAW,CAAK,CAClB,CAAC,EAQL,OANA,EAAA,EAAA,mBAAA,CAAuB,GACrB,EAAA,EAAA,YAAA,KAAkB,EAAY,CAAC,GAC1B,EAAA,EAAA,gBAAA,CAAoB,IACzB,EAAA,EAAA,eAAA,KAAqB,EAAY,CAAC,EAG7B,CACT,CAEA,IAAM,GAAA,EAAA,EAAA,WAAA,CAAmB,CAAI,EAE7B,GAAI,gBAAiB,GAAQ,OAAQ,EAAiC,aAAgB,WAAY,CAChG,IAAM,EAAgB,EAAiC,gBAAoD,EACzG,EAAA,EAAA,WAAA,CAAW,CAAK,CAClB,CAAC,GAED,EAAA,EAAA,mBAAA,CAAuB,GACrB,EAAA,EAAA,YAAA,KAAkB,EAAY,CAAC,GAC1B,EAAA,EAAA,gBAAA,CAAoB,IACzB,EAAA,EAAA,eAAA,KAAqB,EAAY,CAAC,CAEtC,CAEA,OAAO,CACT,CACF"}
|
package/dist/vue/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ReactiveEngineAutomatic as e } from "../core.mjs";
|
|
2
2
|
import { useReactiveValue as t } from "./core.vue-adapter.mjs";
|
|
3
3
|
import { getCurrentInstance as n, getCurrentScope as r, onScopeDispose as i, onUnmounted as a, shallowRef as o, triggerRef as s } from "vue";
|
|
4
4
|
//#region src/vue/index.ts
|
package/package.json
CHANGED
package/dist/core.logger.cjs
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
var e=class{static churnTracker=new Map;static TIME_WINDOW_MS=1e3;static CHURN_WARNING_THRESHOLD=3;static CHURN_CRITICAL_THRESHOLD=6;static isDeepEqual(e,t){return e===t?!0:typeof e!=`object`||typeof t!=`object`||e===null||t===null?!1:JSON.stringify(e)===JSON.stringify(t)}static analyzeSignalChurn(e){let t=Date.now();this.churnTracker.has(e)||this.churnTracker.set(e,[]);let n=this.churnTracker.get(e),r=t-this.TIME_WINDOW_MS,i=n.filter(e=>e>r);i.push(t),this.churnTracker.set(e,i);let a=i.length,o=(this.TIME_WINDOW_MS/1e3).toFixed(1);return a>=this.CHURN_CRITICAL_THRESHOLD?{marker:`🔴`,info:`[CRITICAL CHURN] (${a} изм./${o}s) — Нужен debounce!`}:a>=this.CHURN_WARNING_THRESHOLD?{marker:`🟡`,info:`[WARNING CHURN] (${a} изм./${o}s)`}:{marker:`🟢`,info:`[STABLE] (${a} изм./${o}s)`}}static processLog(e,t,n){let{type:r,label:i,details:a,isInternalCoreSignal:o=!1}=n;if(!e.isEnabled||o&&!e.isCoreOptimizationDebugEnabled)return;if(a&&`from`in a&&`to`in a&&this.isDeepEqual(a.from,a.to)){if(r===`computed`){t(r,`🔵 [IDLE PULL] ${i} (Значение кэша не изменилось)`,a);return}return}let s=``;if(r===`signal`||r===`resource`||r===`computed`){let e=this.analyzeSignalChurn(i);s=e.marker===`🟢`?` ${e.marker}`:` ${e.marker} ${e.info}`}t(r,`${i}${s}`,a)}};exports.ReactiveDebounceLogger=e;
|
|
2
|
-
//# sourceMappingURL=core.logger.cjs.map
|
package/dist/core.logger.cjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"core.logger.cjs","names":[],"sources":["../src/core/core.logger.ts"],"sourcesContent":["import { LogEventType } from \"./types\"\n\ninterface LogDetails {\n from?: unknown;\n to?: unknown;\n payload?: unknown;\n}\n\nexport class ReactiveDebounceLogger {\n private static churnTracker = new Map<string, number[]>()\n\n private static readonly TIME_WINDOW_MS = 1000\n private static readonly CHURN_WARNING_THRESHOLD = 3\n private static readonly CHURN_CRITICAL_THRESHOLD = 6\n\n private static isDeepEqual(a: unknown, b: unknown): boolean {\n if (a === b) return true\n if (typeof a !== 'object' || typeof b !== 'object' || a === null || b === null) return false\n return JSON.stringify(a) === JSON.stringify(b)\n }\n\n private static analyzeSignalChurn(label: string): { marker: string; info: string } {\n const now = Date.now()\n if (!this.churnTracker.has(label)) {\n this.churnTracker.set(label, [])\n }\n\n const history = this.churnTracker.get(label)!\n const cutoff = now - this.TIME_WINDOW_MS\n const activeHistory = history.filter(ts => ts > cutoff)\n activeHistory.push(now)\n this.churnTracker.set(label, activeHistory)\n\n const updateCount = activeHistory.length\n const intervalSec = (this.TIME_WINDOW_MS / 1000).toFixed(1)\n\n if (updateCount >= this.CHURN_CRITICAL_THRESHOLD) {\n return {\n marker: '🔴',\n info: `[CRITICAL CHURN] (${updateCount} изм./${intervalSec}s) — Нужен debounce!`\n }\n }\n\n if (updateCount >= this.CHURN_WARNING_THRESHOLD) {\n return {\n marker: '🟡',\n info: `[WARNING CHURN] (${updateCount} изм./${intervalSec}s)`\n }\n }\n\n return {\n marker: '🟢',\n info: `[STABLE] (${updateCount} изм./${intervalSec}s)`\n }\n }\n\n public static processLog(\n engineLogger: any,\n queueLogFn: Function,\n params: { type: LogEventType; label: string; details?: LogDetails; isInternalCoreSignal?: boolean }\n ) {\n const { type, label, details, isInternalCoreSignal = false } = params\n\n if (!engineLogger.isEnabled) return\n if (isInternalCoreSignal && !engineLogger.isCoreOptimizationDebugEnabled) return\n\n // 1. ОБРАБОТКА ХОЛОСТЫХ ВЫЗОВОВ (Value Equality Cut)\n if (details && 'from' in details && 'to' in details) {\n if (this.isDeepEqual(details.from, details.to)) {\n // ⚛️ ФИКС: Выводим холостые pull-вызовы вычислений ИСКЛЮЧИТЕЛЬНО в режиме тонкой отладки кэша!\n if (type === 'computed') {\n // if (engineLogger.isCoreOptimizationDebugEnabled) {\n // queueLogFn(type, `🔵 [IDLE PULL] ${label} (Значение кэша не изменилось)`, details);\n // }\n queueLogFn(type, `🔵 [IDLE PULL] ${label} (Значение кэша не изменилось)`, details)\n return\n }\n // Для остальных типов (batch, effect) холостой мусор полностью глушим\n return\n }\n }\n\n // 2. SIGNAL CHURN DETECTION: Обсчет частоты обновлений и дребезга\n let churnInfo = ''\n if (type === 'signal' || type === 'resource' || type === 'computed') {\n const churn = this.analyzeSignalChurn(label)\n churnInfo = churn.marker === '🟢' ? ` ${churn.marker}` : ` ${churn.marker} ${churn.info}`\n }\n\n // Отправляем очищенный лог в системную очередь\n queueLogFn(type, `${label}${churnInfo}`, details)\n }\n\n}\n\n"],"mappings":"AAQA,IAAa,EAAb,KAAoC,CAClC,OAAe,aAAe,IAAI,IAElC,OAAwB,eAAiB,IACzC,OAAwB,wBAA0B,EAClD,OAAwB,yBAA2B,EAEnD,OAAe,YAAY,EAAY,EAAqB,CAG1D,OAFI,IAAM,EAAU,GAChB,OAAO,GAAM,UAAY,OAAO,GAAM,UAAY,IAAM,MAAQ,IAAM,KAAa,GAChF,KAAK,UAAU,CAAC,IAAM,KAAK,UAAU,CAAC,CAC/C,CAEA,OAAe,mBAAmB,EAAiD,CACjF,IAAM,EAAM,KAAK,IAAI,EAChB,KAAK,aAAa,IAAI,CAAK,GAC9B,KAAK,aAAa,IAAI,EAAO,CAAC,CAAC,EAGjC,IAAM,EAAU,KAAK,aAAa,IAAI,CAAK,EACrC,EAAS,EAAM,KAAK,eACpB,EAAgB,EAAQ,OAAO,GAAM,EAAK,CAAM,EACtD,EAAc,KAAK,CAAG,EACtB,KAAK,aAAa,IAAI,EAAO,CAAa,EAE1C,IAAM,EAAc,EAAc,OAC5B,GAAe,KAAK,eAAiB,IAAA,CAAM,QAAQ,CAAC,EAgB1D,OAdI,GAAe,KAAK,yBACf,CACL,OAAQ,KACR,KAAM,qBAAqB,EAAY,QAAQ,EAAY,qBAC7D,EAGE,GAAe,KAAK,wBACf,CACL,OAAQ,KACR,KAAM,oBAAoB,EAAY,QAAQ,EAAY,GAC5D,EAGK,CACL,OAAQ,KACR,KAAM,aAAa,EAAY,QAAQ,EAAY,GACrD,CACF,CAEA,OAAc,WACZ,EACA,EACA,EACA,CACA,GAAM,CAAE,OAAM,QAAO,UAAS,uBAAuB,IAAU,EAG/D,GADI,CAAC,EAAa,WACd,GAAwB,CAAC,EAAa,+BAAgC,OAG1E,GAAI,GAAW,SAAU,GAAW,OAAQ,GACtC,KAAK,YAAY,EAAQ,KAAM,EAAQ,EAAE,EAAG,CAE9C,GAAI,IAAS,WAAY,CAIvB,EAAW,EAAM,kBAAkB,EAAM,gCAAiC,CAAO,EACjF,MACF,CAEA,MACF,CAIF,IAAI,EAAY,GAChB,GAAI,IAAS,UAAY,IAAS,YAAc,IAAS,WAAY,CACnE,IAAM,EAAQ,KAAK,mBAAmB,CAAK,EAC3C,EAAY,EAAM,SAAW,KAAO,IAAI,EAAM,SAAW,IAAI,EAAM,OAAO,GAAG,EAAM,MACrF,CAGA,EAAW,EAAM,GAAG,IAAQ,IAAa,CAAO,CAClD,CAEF"}
|
package/dist/core.logger.mjs
DELETED
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
//#region src/core/core.logger.ts
|
|
2
|
-
var e = class {
|
|
3
|
-
static churnTracker = /* @__PURE__ */ new Map();
|
|
4
|
-
static TIME_WINDOW_MS = 1e3;
|
|
5
|
-
static CHURN_WARNING_THRESHOLD = 3;
|
|
6
|
-
static CHURN_CRITICAL_THRESHOLD = 6;
|
|
7
|
-
static isDeepEqual(e, t) {
|
|
8
|
-
return e === t ? !0 : typeof e != "object" || typeof t != "object" || e === null || t === null ? !1 : JSON.stringify(e) === JSON.stringify(t);
|
|
9
|
-
}
|
|
10
|
-
static analyzeSignalChurn(e) {
|
|
11
|
-
let t = Date.now();
|
|
12
|
-
this.churnTracker.has(e) || this.churnTracker.set(e, []);
|
|
13
|
-
let n = this.churnTracker.get(e), r = t - this.TIME_WINDOW_MS, i = n.filter((e) => e > r);
|
|
14
|
-
i.push(t), this.churnTracker.set(e, i);
|
|
15
|
-
let a = i.length, o = (this.TIME_WINDOW_MS / 1e3).toFixed(1);
|
|
16
|
-
return a >= this.CHURN_CRITICAL_THRESHOLD ? {
|
|
17
|
-
marker: "🔴",
|
|
18
|
-
info: `[CRITICAL CHURN] (${a} изм./${o}s) — Нужен debounce!`
|
|
19
|
-
} : a >= this.CHURN_WARNING_THRESHOLD ? {
|
|
20
|
-
marker: "🟡",
|
|
21
|
-
info: `[WARNING CHURN] (${a} изм./${o}s)`
|
|
22
|
-
} : {
|
|
23
|
-
marker: "🟢",
|
|
24
|
-
info: `[STABLE] (${a} изм./${o}s)`
|
|
25
|
-
};
|
|
26
|
-
}
|
|
27
|
-
static processLog(e, t, n) {
|
|
28
|
-
let { type: r, label: i, details: a, isInternalCoreSignal: o = !1 } = n;
|
|
29
|
-
if (!e.isEnabled || o && !e.isCoreOptimizationDebugEnabled) return;
|
|
30
|
-
if (a && "from" in a && "to" in a && this.isDeepEqual(a.from, a.to)) {
|
|
31
|
-
if (r === "computed") {
|
|
32
|
-
t(r, `🔵 [IDLE PULL] ${i} (Значение кэша не изменилось)`, a);
|
|
33
|
-
return;
|
|
34
|
-
}
|
|
35
|
-
return;
|
|
36
|
-
}
|
|
37
|
-
let s = "";
|
|
38
|
-
if (r === "signal" || r === "resource" || r === "computed") {
|
|
39
|
-
let e = this.analyzeSignalChurn(i);
|
|
40
|
-
s = e.marker === "🟢" ? ` ${e.marker}` : ` ${e.marker} ${e.info}`;
|
|
41
|
-
}
|
|
42
|
-
t(r, `${i}${s}`, a);
|
|
43
|
-
}
|
|
44
|
-
};
|
|
45
|
-
//#endregion
|
|
46
|
-
export { e as ReactiveDebounceLogger };
|
|
47
|
-
|
|
48
|
-
//# sourceMappingURL=core.logger.mjs.map
|
package/dist/core.logger.mjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"core.logger.mjs","names":[],"sources":["../src/core/core.logger.ts"],"sourcesContent":["import { LogEventType } from \"./types\"\n\ninterface LogDetails {\n from?: unknown;\n to?: unknown;\n payload?: unknown;\n}\n\nexport class ReactiveDebounceLogger {\n private static churnTracker = new Map<string, number[]>()\n\n private static readonly TIME_WINDOW_MS = 1000\n private static readonly CHURN_WARNING_THRESHOLD = 3\n private static readonly CHURN_CRITICAL_THRESHOLD = 6\n\n private static isDeepEqual(a: unknown, b: unknown): boolean {\n if (a === b) return true\n if (typeof a !== 'object' || typeof b !== 'object' || a === null || b === null) return false\n return JSON.stringify(a) === JSON.stringify(b)\n }\n\n private static analyzeSignalChurn(label: string): { marker: string; info: string } {\n const now = Date.now()\n if (!this.churnTracker.has(label)) {\n this.churnTracker.set(label, [])\n }\n\n const history = this.churnTracker.get(label)!\n const cutoff = now - this.TIME_WINDOW_MS\n const activeHistory = history.filter(ts => ts > cutoff)\n activeHistory.push(now)\n this.churnTracker.set(label, activeHistory)\n\n const updateCount = activeHistory.length\n const intervalSec = (this.TIME_WINDOW_MS / 1000).toFixed(1)\n\n if (updateCount >= this.CHURN_CRITICAL_THRESHOLD) {\n return {\n marker: '🔴',\n info: `[CRITICAL CHURN] (${updateCount} изм./${intervalSec}s) — Нужен debounce!`\n }\n }\n\n if (updateCount >= this.CHURN_WARNING_THRESHOLD) {\n return {\n marker: '🟡',\n info: `[WARNING CHURN] (${updateCount} изм./${intervalSec}s)`\n }\n }\n\n return {\n marker: '🟢',\n info: `[STABLE] (${updateCount} изм./${intervalSec}s)`\n }\n }\n\n public static processLog(\n engineLogger: any,\n queueLogFn: Function,\n params: { type: LogEventType; label: string; details?: LogDetails; isInternalCoreSignal?: boolean }\n ) {\n const { type, label, details, isInternalCoreSignal = false } = params\n\n if (!engineLogger.isEnabled) return\n if (isInternalCoreSignal && !engineLogger.isCoreOptimizationDebugEnabled) return\n\n // 1. ОБРАБОТКА ХОЛОСТЫХ ВЫЗОВОВ (Value Equality Cut)\n if (details && 'from' in details && 'to' in details) {\n if (this.isDeepEqual(details.from, details.to)) {\n // ⚛️ ФИКС: Выводим холостые pull-вызовы вычислений ИСКЛЮЧИТЕЛЬНО в режиме тонкой отладки кэша!\n if (type === 'computed') {\n // if (engineLogger.isCoreOptimizationDebugEnabled) {\n // queueLogFn(type, `🔵 [IDLE PULL] ${label} (Значение кэша не изменилось)`, details);\n // }\n queueLogFn(type, `🔵 [IDLE PULL] ${label} (Значение кэша не изменилось)`, details)\n return\n }\n // Для остальных типов (batch, effect) холостой мусор полностью глушим\n return\n }\n }\n\n // 2. SIGNAL CHURN DETECTION: Обсчет частоты обновлений и дребезга\n let churnInfo = ''\n if (type === 'signal' || type === 'resource' || type === 'computed') {\n const churn = this.analyzeSignalChurn(label)\n churnInfo = churn.marker === '🟢' ? ` ${churn.marker}` : ` ${churn.marker} ${churn.info}`\n }\n\n // Отправляем очищенный лог в системную очередь\n queueLogFn(type, `${label}${churnInfo}`, details)\n }\n\n}\n\n"],"mappings":";AAQA,IAAa,IAAb,MAAoC;CAClC,OAAe,+BAAe,IAAI,IAAsB;CAExD,OAAwB,iBAAiB;CACzC,OAAwB,0BAA0B;CAClD,OAAwB,2BAA2B;CAEnD,OAAe,YAAY,GAAY,GAAqB;EAG1D,OAFI,MAAM,IAAU,KAChB,OAAO,KAAM,YAAY,OAAO,KAAM,YAAY,MAAM,QAAQ,MAAM,OAAa,KAChF,KAAK,UAAU,CAAC,MAAM,KAAK,UAAU,CAAC;CAC/C;CAEA,OAAe,mBAAmB,GAAiD;EACjF,IAAM,IAAM,KAAK,IAAI;EACrB,AAAK,KAAK,aAAa,IAAI,CAAK,KAC9B,KAAK,aAAa,IAAI,GAAO,CAAC,CAAC;EAGjC,IAAM,IAAU,KAAK,aAAa,IAAI,CAAK,GACrC,IAAS,IAAM,KAAK,gBACpB,IAAgB,EAAQ,QAAO,MAAM,IAAK,CAAM;EAEtD,AADA,EAAc,KAAK,CAAG,GACtB,KAAK,aAAa,IAAI,GAAO,CAAa;EAE1C,IAAM,IAAc,EAAc,QAC5B,KAAe,KAAK,iBAAiB,IAAA,CAAM,QAAQ,CAAC;EAgB1D,OAdI,KAAe,KAAK,2BACf;GACL,QAAQ;GACR,MAAM,qBAAqB,EAAY,QAAQ,EAAY;EAC7D,IAGE,KAAe,KAAK,0BACf;GACL,QAAQ;GACR,MAAM,oBAAoB,EAAY,QAAQ,EAAY;EAC5D,IAGK;GACL,QAAQ;GACR,MAAM,aAAa,EAAY,QAAQ,EAAY;EACrD;CACF;CAEA,OAAc,WACZ,GACA,GACA,GACA;EACA,IAAM,EAAE,SAAM,UAAO,YAAS,0BAAuB,OAAU;EAG/D,IADI,CAAC,EAAa,aACd,KAAwB,CAAC,EAAa,gCAAgC;EAG1E,IAAI,KAAW,UAAU,KAAW,QAAQ,KACtC,KAAK,YAAY,EAAQ,MAAM,EAAQ,EAAE,GAAG;GAE9C,IAAI,MAAS,YAAY;IAIvB,EAAW,GAAM,kBAAkB,EAAM,iCAAiC,CAAO;IACjF;GACF;GAEA;EACF;EAIF,IAAI,IAAY;EAChB,IAAI,MAAS,YAAY,MAAS,cAAc,MAAS,YAAY;GACnE,IAAM,IAAQ,KAAK,mBAAmB,CAAK;GAC3C,IAAY,EAAM,WAAW,OAAO,IAAI,EAAM,WAAW,IAAI,EAAM,OAAO,GAAG,EAAM;EACrF;EAGA,EAAW,GAAM,GAAG,IAAQ,KAAa,CAAO;CAClD;AAEF"}
|