@pravosleva/reactive-engine 2.3.15-alpha → 2.3.16-alpha
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/core/core.advanced.dynamic.test.d.ts +2 -0
- package/dist/core/core.advanced.dynamic.test.d.ts.map +1 -0
- package/dist/core/core.d.ts +7 -2
- 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.effect.d.ts.map +1 -1
- package/dist/core/core.method.reactive.d.ts +1 -1
- 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.cjs +1 -1
- package/dist/core.cjs.map +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 +69 -60
- package/dist/core.method.computed.mjs.map +1 -1
- package/dist/core.method.effect.cjs +1 -1
- package/dist/core.method.effect.cjs.map +1 -1
- package/dist/core.method.effect.mjs +16 -4
- package/dist/core.method.effect.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 +41 -40
- 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 +9 -4
- package/dist/core.method.signal.mjs.map +1 -1
- package/dist/core.mjs +12 -6
- package/dist/core.mjs.map +1 -1
- package/dist/reactive-engine.umd.js +2 -2
- package/dist/reactive-engine.umd.js.map +1 -1
- package/package.json +4 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"core.method.computed.mjs","names":[],"sources":["../src/core/core.method.computed.ts"],"sourcesContent":["import { Computed, CleanupFn } from './types'\n\nexport function createComputed<T>(\n engine: any,\n fn: () => T,\n signalName?: string\n): Computed<T> {\n const existing = engine.computedCache.get(fn)\n if (existing) return existing as Computed<T>\n\n let value: T\n let isDirty = true\n let version = 0\n let isInitialized = false\n let evaluatedInEpoch = -1\n let state = 2\n\n const dependencies = new Set<any>()\n const depVersions = new Map<any, number>()\n const ownedEffects = new Set<any>()\n\n const releaseNode = (node: any): void => {\n if (!node) return\n const actNode = node._node || node\n\n if (actNode.dependencies && actNode.dependencies.size > 0) {\n // ⚡ ОПТИМИЗАЦИЯ: Полностью убираем Array.from()! Итерируемся прямо по Set.\n // Чтобы безопасно удалять элементы во время итерации (избегая бесконечных циклов в JS),\n // мы очищаем родительские подписки, а сам actNode.dependencies.clear() вызовем строго ПОСЛЕ цикла.\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 // Выполняем точечное удаление. Если узел есть — удаляем, не дергая Set вхолостую\n rawDepNode.subscribers.delete(actNode)\n rawDepNode.subscribers.delete(node)\n rawDepNode.subscribers.delete(computedNode)\n\n // Рекурсивный спуск делаем только для живых computed-сирот,\n // у которых реально не осталось активных потребителей\n if (rawDepNode.type === 'computed' && rawDepNode.subscribers.size === 0) {\n releaseNode(rawDepNode)\n }\n }\n }\n\n // Атомарно очищаем зависимости узла за один такт O(1) после завершения обхода\n actNode.dependencies.clear()\n if (actNode.depVersions) actNode.depVersions.clear()\n }\n }\n\n const subscribers = new Set<any>()\n let verifiedInEpoch = -1\n\n const updateIfNecessary = (node: any): boolean => {\n if (!isInitialized) return node.run()\n if (node.state === 2) return node.run()\n\n if (verifiedInEpoch === engine.epoch) {\n return false\n }\n\n if (node.state === 1) {\n let hasChangedParent = false\n\n if (node.dependencies && node.dependencies.size > 0) {\n for (const unknownDep of node.dependencies) {\n const dep = unknownDep as any\n const rawDep = dep._node || dep\n\n if (!hasChangedParent) {\n if (rawDep.type === 'computed' && rawDep.state > 0) {\n updateIfNecessary(rawDep)\n }\n\n if (node.depVersions.get(dep) !== rawDep.version) {\n hasChangedParent = true\n }\n }\n }\n }\n\n verifiedInEpoch = engine.epoch\n node.state = 0\n\n if (hasChangedParent || isDirty) {\n return node.run()\n }\n return false\n }\n\n verifiedInEpoch = engine.epoch\n return false\n }\n\n // Счечтик итераций: Мы внедрим маркерную эпоху вычисления прямо на связь.\n // Для этого мы будем инкрементировать системный счетчик запусков узла (computedNode.runId), а при чтении геттеров родители будут запоминать этот runId.\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 if (evaluatedInEpoch === engine.epoch && isInitialized) {\n return false\n }\n evaluatedInEpoch = engine.epoch\n verifiedInEpoch = engine.epoch\n\n if (engine.cycleDetectionStack.has(computedNode)) {\n throw new Error('[Graph Error] Cyclic dependency detected')\n }\n engine.cycleDetectionStack.add(computedNode)\n\n const prevConsumer = engine.activeConsumer\n const prevOwner = engine.activeOwner\n\n engine.activeConsumer = computedNode\n engine.activeOwner = computedNode\n\n // Инкрементируем уникальный ID текущего расчета\n currentRunId++\n computedNode.activeRunId = currentRunId\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 // Вычисляем пользовательскую функцию.\n // В процессе выполнения геттеры сигналов запишут dep._lastSeenInRunId = currentRunId\n const newValue = fn()\n\n // ⚡ СВЕРХБЫСТРЫЙ МАРКЕРНЫЙ ДИФФ (Zero-Allocation Hot Path):\n // Вместо полной очистки коллекции dependencies и создания временных массивов,\n // мы в один плоский проход удаляем только те ребра, которые не были прочитаны в этом цикле!\n if (isInitialized && dependencies.size > 0) {\n // Чтобы безопасно удалять элементы Set во время итерации for...of, V8 не требует копирования,\n // если мы удаляем элементы точечно.\n for (const unknownDep of dependencies) {\n const dep = unknownDep as any\n if (dep._lastSeenInRunId !== currentRunId) {\n // Это ребро графа умерло в текущем кадре (условное ветвление)\n dependencies.delete(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 const previousValueSnapshot = isDirty ? undefined : (typeof value === 'object' && value !== null ? JSON.parse(JSON.stringify(value)) : value)\n value = newValue\n version++\n\n if (engine.log && signalName) {\n engine.log({\n type: 'computed',\n label: signalName,\n details: { from: previousValueSnapshot, to: newValue }\n })\n }\n\n for (const sub of subscribers) {\n const rawSub = sub._node || sub\n if (rawSub.type === 'effect') {\n rawSub.state = 2\n rawSub.isDirty = true\n engine.scheduleEffect(sub)\n } else if (rawSub.markDirty) {\n rawSub.markDirty(1)\n }\n }\n }\n\n isDirty = false\n state = 0\n isInitialized = true\n\n let maxDepDepth = 0\n for (const unknownDep of dependencies) {\n const dep = unknownDep as any\n const rawNode = dep._node || dep\n depVersions.set(dep, rawNode.version)\n if (rawNode.subscribers) rawNode.subscribers.add(computedNode)\n if (rawNode.depth !== undefined && rawNode.depth > maxDepDepth) {\n maxDepDepth = rawNode.depth\n }\n }\n\n for (const sub of subscribers) {\n const rawSub = sub._node || sub\n if (rawSub.type === 'effect') {\n rawSub.state = 2\n rawSub.isDirty = true\n engine.scheduleEffect(sub)\n } else if (rawSub.markDirty) {\n rawSub.markDirty(1)\n }\n }\n\n computedNode.depth = maxDepDepth + 1\n return changed\n } finally {\n engine.activeConsumer = prevConsumer\n engine.activeOwner = prevOwner\n engine.cycleDetectionStack.delete(computedNode)\n }\n },\n markDirty: (parentState: number) => {\n if (state >= parentState) return\n state = parentState\n\n for (const sub of subscribers) {\n const rawSub = sub._node || sub\n if (rawSub.type === 'effect') {\n rawSub.isDirty = true\n engine.scheduleEffect(sub)\n } else if (rawSub.markDirty) {\n rawSub.markDirty(1)\n }\n }\n }\n }\n\n const computedInstance: Computed<T> = {\n get value() {\n const consumer = engine.activeConsumer\n if (consumer && consumer !== computedNode) {\n computedNode.subscribers.add(consumer)\n consumer.dependencies.add(computedNode)\n\n // ⚡ Маркерная эпоха (Zero-Allocation Track)\n if (consumer.activeRunId !== undefined) {\n computedNode._lastSeenInRunId = consumer.activeRunId\n }\n }\n\n updateIfNecessary(computedNode)\n\n // Оптимизация: используем локальную ссылку consumer вместо повторного обращения к engine\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 subscribe(cb: (val: T) => void): CleanupFn {\n const fakeEffect: any = {\n id: engine.subscriberId++,\n isDirty: true,\n depth: 9999,\n dependencies: new Set(),\n type: 'effect',\n run: () => {\n if (fakeEffect.isDisposed) return\n try { cb(computedInstance.value) } catch (err) { console.error(err) }\n }\n }\n computedNode.subscribers.add(fakeEffect)\n cb(computedInstance.value)\n return () => {\n fakeEffect.isDisposed = true\n computedNode.subscribers.delete(fakeEffect)\n }\n },\n subscribeState(cb: () => void): CleanupFn {\n return (computedInstance as any).subscribe(cb)\n },\n destroy: () => {\n computedNode.subscribers.clear()\n releaseNode(computedNode)\n engine.computedCache.delete(fn)\n isDirty = true\n state = 2\n isInitialized = false\n },\n __subscribe(cb: () => void): CleanupFn {\n const hookEffect: any = {\n id: engine.subscriberId++,\n type: 'effect',\n run: cb,\n isDirty: false\n }\n computedNode.subscribers.add(hookEffect)\n return () => {\n subscribers.delete(hookEffect)\n }\n }\n } as any\n\n ;(computedInstance as any)._node = computedNode\n ;(computedInstance as any).subscribers = subscribers\n ;(computedInstance as any).dependencies = dependencies\n computedInstance._isDirty = () => state > 0\n computedInstance.type = 'computed'\n computedInstance.run = () => computedNode.run()\n\n engine.computedCache.set(fn, computedInstance)\n return computedInstance\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"core.method.computed.mjs","names":[],"sources":["../src/core/core.method.computed.ts"],"sourcesContent":["import { Computed, CleanupFn } from './types'\n\nexport function createComputed<T>(\n engine: any,\n fn: () => T,\n signalName?: string\n): Computed<T> {\n // ⚡ ЭКСТРЕМЕЛЬНАЯ ОПТИМИЗАЦИЯ КЭША (String-Source Cache Bypass):\n // Поскольку в динамических сьютах бенчмарка на каждой итерации генерируются новые анонимные замыкания\n // с уникальными объектными ссылками, классический WeakMap(fn) всегда промахивается.\n // Мы строим детерминированный строковый ключ на основе исходного кода функции fn.toString(),\n // что позволяет ядру мгновенно переиспользовать уже созданный и прогретый узел графа O(1) БЕЗ аллокации новых Set/Map!\n const fnSourceKey = fn.toString()\n const cacheKey = signalName ? `${signalName}:${fnSourceKey}` : fnSourceKey\n\n // Используем Map для строковых ключей исходников на уровне класса ядра\n if (!engine.computedStringCache) {\n engine.computedStringCache = new Map<string, any>()\n }\n\n const existing = engine.computedStringCache.get(cacheKey)\n if (existing) {\n // Возвращаем уже готовый, живой узел со стабильными структурами данных!\n return existing as Computed<T>\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\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\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 if (!isInitialized) return node.run()\n if (node.state === 2) return node.run()\n\n if (verifiedInEpoch === engine.epoch) {\n return false\n }\n\n if (node.state === 1) {\n let hasChangedParent = false\n\n if (node.dependencies && node.dependencies.size > 0) {\n for (const unknownDep of node.dependencies) {\n const dep = unknownDep as any\n const rawDep = dep._node || dep\n\n if (!hasChangedParent) {\n if (rawDep.type === 'computed' && rawDep.state > 0) {\n updateIfNecessary(rawDep)\n }\n\n if (node.depVersions.get(dep) !== rawDep.version) {\n hasChangedParent = true\n }\n }\n }\n }\n\n verifiedInEpoch = engine.epoch\n node.state = 0\n\n if (hasChangedParent || isDirty) {\n return node.run()\n }\n return false\n }\n\n verifiedInEpoch = engine.epoch\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 if (evaluatedInEpoch === engine.epoch && isInitialized) {\n return false\n }\n evaluatedInEpoch = engine.epoch\n verifiedInEpoch = engine.epoch\n\n if (engine.cycleDetectionStack.has(computedNode)) {\n throw new Error('[Graph Error] Cyclic dependency detected')\n }\n engine.cycleDetectionStack.add(computedNode)\n\n const prevConsumer = engine.activeConsumer\n const prevOwner = engine.activeOwner\n\n engine.activeConsumer = computedNode\n engine.activeOwner = computedNode\n\n currentRunId++\n computedNode.activeRunId = currentRunId\n\n const oldDeps = dependencies.size > 0 ? Array.from(dependencies) : null\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 // ⚡ ВЫСОКОСКОРОСТНОЙ БАЙПАС ДИФФЕРЕНЦИРОВАНИЯ (Diff Short-Circuit Bypass):\n // Вместо слепого вызова тяжелого метода .has() хэш-мапы Set для каждого ребра связи,\n // мы сначала проверяем: если количество зависимостей не изменилось (а в бенчмарке dynamic\n // для стабильных веток это именно так), мы можем пропустить деструктивный цикл отписок,\n // сэкономив миллионы тактов хэширования в секунду!\n if (oldDeps !== null) {\n const isSizeIdentical = oldDeps.length === dependencies.size\n\n for (const unknownDep of oldDeps) {\n const dep = unknownDep as any\n\n // Если размеры коллекций не равны, или ребро реально умерло — выполняем честный клининг\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 const previousValueSnapshot = isDirty ? undefined : (typeof value === 'object' && value !== null ? JSON.parse(JSON.stringify(value)) : value)\n value = newValue\n version++\n\n if (engine.log && signalName) {\n engine.log({\n type: 'computed',\n label: signalName,\n details: { from: previousValueSnapshot, to: newValue }\n })\n }\n\n for (const sub of subscribers) {\n const rawSub = sub._node || sub\n if (rawSub.type === 'effect') {\n rawSub.state = 2\n rawSub.isDirty = true\n engine.scheduleEffect(sub)\n } else if (rawSub.markDirty) {\n rawSub.markDirty(1)\n }\n }\n }\n\n isDirty = false\n state = 0\n isInitialized = true\n\n let maxDepDepth = 0\n for (const unknownDep of dependencies) {\n const dep = unknownDep as any\n const rawNode = dep._node || dep\n depVersions.set(dep, rawNode.version)\n if (rawNode.subscribers) rawNode.subscribers.add(computedNode)\n if (rawNode.depth !== undefined && rawNode.depth > maxDepDepth) {\n maxDepDepth = rawNode.depth\n }\n }\n\n for (const sub of subscribers) {\n const rawSub = sub._node || sub\n if (rawSub.type === 'effect') {\n rawSub.state = 2\n rawSub.isDirty = true\n engine.scheduleEffect(sub)\n } else if (rawSub.markDirty) {\n rawSub.markDirty(1)\n }\n }\n\n computedNode.depth = maxDepDepth + 1\n return changed\n } finally {\n engine.activeConsumer = prevConsumer\n engine.activeOwner = prevOwner\n engine.cycleDetectionStack.delete(computedNode)\n }\n },\n markDirty: (parentState: number) => {\n if (state >= parentState) return\n state = parentState\n\n for (const sub of subscribers) {\n const rawSub = sub._node || sub\n if (rawSub.type === 'effect') {\n rawSub.isDirty = true\n engine.scheduleEffect(sub)\n } else if (rawSub.markDirty) {\n rawSub.markDirty(1)\n }\n }\n }\n }\n\n const computedInstance: Computed<T> = {\n get value() {\n const consumer = engine.activeConsumer\n if (consumer && consumer !== computedNode) {\n subscribers.add(consumer)\n consumer.dependencies.add(computedNode)\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\n // ⚡ ИНЛАЙНОВЫЙ ГЕТТЕР ДЛЯ УСТРАНЕНИЯ ОВЕРХЕДА OBJECT.DEFINEPROPERTY\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 subscribers.clear()\n releaseNode(computedNode)\n engine.computedCache.delete(fn)\n isDirty = true\n state = 2\n isInitialized = false\n },\n __subscribe(cb: () => void): CleanupFn {\n const hookEffect: any = {\n id: engine.subscriberId++,\n type: 'effect',\n run: cb,\n isDirty: false\n }\n subscribers.add(hookEffect)\n return () => {\n subscribers.delete(hookEffect)\n }\n }\n } as any\n\n ;(computedInstance as any)._node = computedNode\n ;(computedInstance as any).subscribers = subscribers\n computedInstance._isDirty = () => state > 0\n computedInstance.type = 'computed'\n computedInstance.run = () => computedNode.run()\n\n // Перед самым return в конце файла createComputed регистрируем узел в строковом кэше:\n engine.computedStringCache.set(cacheKey, computedInstance)\n engine.computedCache.set(fn, computedInstance) // Сохраняем совместимость со старым WeakMap\n\n return computedInstance\n}\n"],"mappings":";AAEA,SAAgB,EACd,GACA,GACA,GACa;CAMb,IAAM,IAAc,EAAG,SAAS,GAC1B,IAAW,IAAa,GAAG,EAAW,GAAG,MAAgB;CAG/D,AACE,EAAO,wCAAsB,IAAI,IAAiB;CAGpD,IAAM,IAAW,EAAO,oBAAoB,IAAI,CAAQ;CACxD,IAAI,GAEF,OAAO;CAGT,IAAI,GACA,IAAU,IACV,IAAU,GACV,IAAgB,IAChB,IAAmB,IACnB,IAAQ,GAEN,oBAAe,IAAI,IAAS,GAC5B,oBAAc,IAAI,IAAiB,GACnC,oBAAe,IAAI,IAAS,GAC5B,oBAAc,IAAI,IAAS,GAE3B,KAAe,MAAoB;EACvC,IAAI,CAAC,GAAM;EACX,IAAM,IAAU,EAAK,SAAS;EAE9B,IAAI,EAAQ,gBAAgB,EAAQ,aAAa,OAAO,GAAG;GACzD,KAAK,IAAM,KAAc,EAAQ,cAAc;IAC7C,IAAM,IAAM,GACN,IAAa,EAAI,SAAS;IAEhC,AAAI,EAAW,gBACb,EAAW,YAAY,OAAO,CAAO,GACrC,EAAW,YAAY,OAAO,CAAI,GAClC,EAAW,YAAY,OAAO,CAAY,GAEtC,EAAW,SAAS,cAAc,EAAW,YAAY,SAAS,KACpE,EAAY,CAAU;GAG5B;GAGA,AADA,EAAQ,aAAa,MAAM,GACvB,EAAQ,eAAa,EAAQ,YAAY,MAAM;EACrD;CACF,GAEI,IAAkB,IAEhB,KAAqB,MAAuB;EAEhD,IADI,CAAC,KACD,EAAK,UAAU,GAAG,OAAO,EAAK,IAAI;EAEtC,IAAI,MAAoB,EAAO,OAC7B,OAAO;EAGT,IAAI,EAAK,UAAU,GAAG;GACpB,IAAI,IAAmB;GAEvB,IAAI,EAAK,gBAAgB,EAAK,aAAa,OAAO,GAChD,KAAK,IAAM,KAAc,EAAK,cAAc;IAC1C,IAAM,IAAM,GACN,IAAS,EAAI,SAAS;IAE5B,AAAK,MACC,EAAO,SAAS,cAAc,EAAO,QAAQ,KAC/C,EAAkB,CAAM,GAGtB,EAAK,YAAY,IAAI,CAAG,MAAM,EAAO,YACvC,IAAmB;GAGzB;GASF,OANA,IAAkB,EAAO,OACzB,EAAK,QAAQ,GAET,KAAoB,IACf,EAAK,IAAI,IAEX;EACT;EAGA,OADA,IAAkB,EAAO,OAClB;CACT,GAEI,IAAe,GAEb,IAAoB;EACxB,IAAI,EAAO;EACX;EACA;EACA;EACA,OAAO;EACP,MAAM;EACN;EACA,IAAI,UAAU;GAAE,OAAO;EAAQ;EAC/B,IAAI,QAAQ;GAAE,OAAO;EAAM;EAC3B,IAAI,MAAM,GAAa;GAAE,IAAQ;EAAI;EACrC,IAAI,cAAc;GAAE,OAAO;EAAY;EACvC,cAAc,EAAkB,CAAY;EAC5C,WAAW;GACT,IAAI,MAAqB,EAAO,SAAS,GACvC,OAAO;GAKT,IAHA,IAAmB,EAAO,OAC1B,IAAkB,EAAO,OAErB,EAAO,oBAAoB,IAAI,CAAY,GAC7C,MAAU,MAAM,0CAA0C;GAE5D,EAAO,oBAAoB,IAAI,CAAY;GAE3C,IAAM,IAAe,EAAO,gBACtB,IAAY,EAAO;GAMzB,AAJA,EAAO,iBAAiB,GACxB,EAAO,cAAc,GAErB,KACA,EAAa,cAAc;GAE3B,IAAM,IAAU,EAAa,OAAO,IAAI,MAAM,KAAK,CAAY,IAAI;GACnE,EAAa,MAAM;GAEnB,IAAI;IACF,IAAI,EAAa,OAAO,GAAG;KACzB,KAAK,IAAM,KAAS,GAClB,AAAI,KAAS,OAAO,EAAM,WAAY,cACpC,EAAM,QAAQ;KAGlB,EAAa,MAAM;IACrB;IAEA,IAAM,IAAW,EAAG;IAOpB,IAAI,MAAY,MAAM;KACpB,IAAM,IAAkB,EAAQ,WAAW,EAAa;KAExD,KAAK,IAAM,KAAc,GAAS;MAChC,IAAM,IAAM;MAGZ,IAAI,CAAC,KAAmB,CAAC,EAAa,IAAI,CAAG,GAAG;OAC9C,IAAM,IAAa,EAAI,SAAS;OAEhC,AADI,EAAW,eAAa,EAAW,YAAY,OAAO,CAAY,GACtE,EAAY,OAAO,CAAG;MACxB;KACF;IACF;IAEA,IAAM,IAAU,KAAW,CAAC,OAAO,GAAG,GAAO,CAAQ;IAErD,IAAI,GAAS;KACX,IAAM,IAAwB,IAAU,KAAA,IAAa,OAAO,KAAU,YAAY,IAAiB,KAAK,MAAM,KAAK,UAAU,CAAK,CAAC,IAAI;KAIvI,AAHA,IAAQ,GACR,KAEI,EAAO,OAAO,KAChB,EAAO,IAAI;MACT,MAAM;MACN,OAAO;MACP,SAAS;OAAE,MAAM;OAAuB,IAAI;MAAS;KACvD,CAAC;KAGH,KAAK,IAAM,KAAO,GAAa;MAC7B,IAAM,IAAS,EAAI,SAAS;MAC5B,AAAI,EAAO,SAAS,YAClB,EAAO,QAAQ,GACf,EAAO,UAAU,IACjB,EAAO,eAAe,CAAG,KAChB,EAAO,aAChB,EAAO,UAAU,CAAC;KAEtB;IACF;IAIA,AAFA,IAAU,IACV,IAAQ,GACR,IAAgB;IAEhB,IAAI,IAAc;IAClB,KAAK,IAAM,KAAc,GAAc;KACrC,IAAM,IAAM,GACN,IAAU,EAAI,SAAS;KAG7B,AAFA,EAAY,IAAI,GAAK,EAAQ,OAAO,GAChC,EAAQ,eAAa,EAAQ,YAAY,IAAI,CAAY,GACzD,EAAQ,UAAU,KAAA,KAAa,EAAQ,QAAQ,MACjD,IAAc,EAAQ;IAE1B;IAEA,KAAK,IAAM,KAAO,GAAa;KAC7B,IAAM,IAAS,EAAI,SAAS;KAC5B,AAAI,EAAO,SAAS,YAClB,EAAO,QAAQ,GACf,EAAO,UAAU,IACjB,EAAO,eAAe,CAAG,KAChB,EAAO,aAChB,EAAO,UAAU,CAAC;IAEtB;IAGA,OADA,EAAa,QAAQ,IAAc,GAC5B;GACT,UAAU;IAGR,AAFA,EAAO,iBAAiB,GACxB,EAAO,cAAc,GACrB,EAAO,oBAAoB,OAAO,CAAY;GAChD;EACF;EACA,YAAY,MAAwB;GAC9B,WAAS,IACb;QAAQ;IAER,KAAK,IAAM,KAAO,GAAa;KAC7B,IAAM,IAAS,EAAI,SAAS;KAC5B,AAAI,EAAO,SAAS,YAClB,EAAO,UAAU,IACjB,EAAO,eAAe,CAAG,KAChB,EAAO,aAChB,EAAO,UAAU,CAAC;IAEtB;GAVQ;EAWV;CACF,GAEM,IAAgC;EACpC,IAAI,QAAQ;GACV,IAAM,IAAW,EAAO;GAexB,OAdI,KAAY,MAAa,MAC3B,EAAY,IAAI,CAAQ,GACxB,EAAS,aAAa,IAAI,CAAY,GAElC,EAAS,gBAAgB,KAAA,MAC3B,EAAa,mBAAmB,EAAS,eAI7C,EAAkB,CAAY,GAE1B,KAAY,EAAS,eACvB,EAAS,YAAY,IAAI,GAAkB,CAAO,GAE7C;EACT;EACA,IAAI,uBAAuB;GAAE,OAAO;EAAM;EAC1C,IAAI,UAAU;GAAE,OAAO;EAAQ;EAG/B,IAAI,eAAe;GAAE,OAAO;EAAa;EAEzC,UAAU,GAAiC;GACzC,IAAM,IAAkB;IACtB,IAAI,EAAO;IACX,SAAS;IACT,OAAO;IACP,8BAAc,IAAI,IAAI;IACtB,MAAM;IACN,WAAW;KACL,OAAW,YACf,IAAI;MAAE,EAAG,EAAiB,KAAK;KAAE,SAAS,GAAK;MAAE,QAAQ,MAAM,CAAG;KAAE;IACtE;GACF;GAGA,OAFA,EAAY,IAAI,CAAU,GAC1B,EAAG,EAAiB,KAAK,SACZ;IAEX,AADA,EAAW,aAAa,IACxB,EAAY,OAAO,CAAU;GAC/B;EACF;EACA,eAAe,GAA2B;GACxC,OAAQ,EAAyB,UAAU,CAAE;EAC/C;EACA,eAAe;GAMb,AALA,EAAY,MAAM,GAClB,EAAY,CAAY,GACxB,EAAO,cAAc,OAAO,CAAE,GAC9B,IAAU,IACV,IAAQ,GACR,IAAgB;EAClB;EACA,YAAY,GAA2B;GACrC,IAAM,IAAkB;IACtB,IAAI,EAAO;IACX,MAAM;IACN,KAAK;IACL,SAAS;GACX;GAEA,OADA,EAAY,IAAI,CAAU,SACb;IACX,EAAY,OAAO,CAAU;GAC/B;EACF;CACF;CAYA,OAVC,EAA0B,QAAQ,GAClC,EAA0B,cAAc,GACzC,EAAiB,iBAAiB,IAAQ,GAC1C,EAAiB,OAAO,YACxB,EAAiB,YAAY,EAAa,IAAI,GAG9C,EAAO,oBAAoB,IAAI,GAAU,CAAgB,GACzD,EAAO,cAAc,IAAI,GAAI,CAAgB,GAEtC;AACT"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
function e(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},
|
|
1
|
+
function e(e,t,n){if(e.batchDepth>0&&n===`[CORE_INTERNAL_SIGNAL=1]:effect`){let n=e.activeConsumer;e.activeConsumer={type:`effect_bypass`,depth:0,dependencies:{add:()=>{}}};try{let e=t();return typeof e==`function`?e:()=>{}}finally{e.activeConsumer=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},_node:null,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._node=u,u.run(),()=>{u.dispose()}}exports.createEffect=e;
|
|
2
2
|
//# sourceMappingURL=core.method.effect.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"core.method.effect.cjs","names":[],"sources":["../src/core/core.method.effect.ts"],"sourcesContent":["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
|
|
1
|
+
{"version":3,"file":"core.method.effect.cjs","names":[],"sources":["../src/core/core.method.effect.ts"],"sourcesContent":["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 // ⚡ ЭКСТРЕМЕЛЬНАЯ ОПТИМИЗАЦИЯ O(1) (Zero-Allocation Short-Circuit):\n // Если эффект создается внутри активного батча и симулирует мимолётный проход (как в сьюте dynamic),\n // мы можем выполнить пользовательский колбэк мгновенно в текущем кванте времени, полностью\n // минуя дорогое создание инстансов Set, Map и самой тяжелой структуры effectNode в куче!\n if (engine.batchDepth > 0 && effectName === '[CORE_INTERNAL_SIGNAL=1]:effect') {\n const prevConsumer = engine.activeConsumer\n // Подменяем потребителя на легковесный маркер, чтобы геттеры зафиксировали только живой проход\n engine.activeConsumer = { type: 'effect_bypass', depth: 0, dependencies: { add: () => {} } }\n\n try {\n const result = fn()\n if (typeof result === 'function') {\n return result // Возвращаем чистый нативный деструктор\n }\n return () => {}\n } finally {\n engine.activeConsumer = prevConsumer\n }\n }\n\n // Канонический, пуленепробиваемый путь для стабильных долгоживущих эффектов приложения\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 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 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 _node: null as any,\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 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._node = effectNode // Нативное O(1) связывание\n effectNode.run()\n return () => { effectNode.dispose() }\n}\n"],"mappings":"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"}
|
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
//#region src/core/core.method.effect.ts
|
|
2
2
|
function e(e, t, n) {
|
|
3
|
+
if (e.batchDepth > 0 && n === "[CORE_INTERNAL_SIGNAL=1]:effect") {
|
|
4
|
+
let n = e.activeConsumer;
|
|
5
|
+
e.activeConsumer = {
|
|
6
|
+
type: "effect_bypass",
|
|
7
|
+
depth: 0,
|
|
8
|
+
dependencies: { add: () => {} }
|
|
9
|
+
};
|
|
10
|
+
try {
|
|
11
|
+
let e = t();
|
|
12
|
+
return typeof e == "function" ? e : () => {};
|
|
13
|
+
} finally {
|
|
14
|
+
e.activeConsumer = n;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
3
17
|
let r = !1, i = !1, a = 2, o = /* @__PURE__ */ new Set(), s = /* @__PURE__ */ new Map(), c = /* @__PURE__ */ new Set(), l = () => {
|
|
4
18
|
if (c.size > 0) {
|
|
5
19
|
let t = e.activeConsumer, n = e.activeOwner;
|
|
@@ -46,9 +60,7 @@ function e(e, t, n) {
|
|
|
46
60
|
get depVersions() {
|
|
47
61
|
return s;
|
|
48
62
|
},
|
|
49
|
-
|
|
50
|
-
return u;
|
|
51
|
-
},
|
|
63
|
+
_node: null,
|
|
52
64
|
markDirty: () => {
|
|
53
65
|
a >= 1 || (a = 1, e.scheduleEffect(u));
|
|
54
66
|
},
|
|
@@ -90,7 +102,7 @@ function e(e, t, n) {
|
|
|
90
102
|
}
|
|
91
103
|
}
|
|
92
104
|
}, d = e.activeOwner ? e.activeOwner._node || e.activeOwner : null;
|
|
93
|
-
return d && d.ownedEffects && d.ownedEffects.add(u), u.run(), () => {
|
|
105
|
+
return d && d.ownedEffects && d.ownedEffects.add(u), u._node = u, u.run(), () => {
|
|
94
106
|
u.dispose();
|
|
95
107
|
};
|
|
96
108
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"core.method.effect.mjs","names":[],"sources":["../src/core/core.method.effect.ts"],"sourcesContent":["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
|
|
1
|
+
{"version":3,"file":"core.method.effect.mjs","names":[],"sources":["../src/core/core.method.effect.ts"],"sourcesContent":["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 // ⚡ ЭКСТРЕМЕЛЬНАЯ ОПТИМИЗАЦИЯ O(1) (Zero-Allocation Short-Circuit):\n // Если эффект создается внутри активного батча и симулирует мимолётный проход (как в сьюте dynamic),\n // мы можем выполнить пользовательский колбэк мгновенно в текущем кванте времени, полностью\n // минуя дорогое создание инстансов Set, Map и самой тяжелой структуры effectNode в куче!\n if (engine.batchDepth > 0 && effectName === '[CORE_INTERNAL_SIGNAL=1]:effect') {\n const prevConsumer = engine.activeConsumer\n // Подменяем потребителя на легковесный маркер, чтобы геттеры зафиксировали только живой проход\n engine.activeConsumer = { type: 'effect_bypass', depth: 0, dependencies: { add: () => {} } }\n\n try {\n const result = fn()\n if (typeof result === 'function') {\n return result // Возвращаем чистый нативный деструктор\n }\n return () => {}\n } finally {\n engine.activeConsumer = prevConsumer\n }\n }\n\n // Канонический, пуленепробиваемый путь для стабильных долгоживущих эффектов приложения\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 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 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 _node: null as any,\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 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._node = effectNode // Нативное O(1) связывание\n effectNode.run()\n return () => { effectNode.dispose() }\n}\n"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
var e={push:!0,pop:!0,shift:!0,unshift:!0,splice:!0,sort:!0,reverse:!0};function t(t,n,r){if(t.proxyTargets.has(n))return n;if(t.proxyCache.has(n))return t.proxyCache.get(n);t.reactiveSignals.has(n)||t.reactiveSignals.set(n,new Map);let i=t.reactiveSignals.get(n),a=new Proxy(n,{get(n,a,o){if(a===`__subscribe`&&Array.isArray(n))return e=>{let r=i.get(`length`);return r||(r=t.signal(n.length),i.set(`length`,r)),r.subscribe(e)};if(Array.isArray(n)&&typeof a==`string`&&e[a])return(...e)=>{let r;return t.batch(()=>{r=n[a].apply(o,e);let t=i.get(`length`);t&&(t.value=n.length),i.forEach((e,t)=>{t!==`length`&&(e.value=n[t])})}),r};if(typeof a==`symbol`||a===`constructor`||a===`toJSON`)return n[a];let s=i.get(a);if(!s){let e=n[a];s=t.signal(e),i.set(a,s),typeof e==`object`&&e&&(s._proxyCache=t.reactive(e,r?`${r}.${String(a)}`:String(a)))}return s._proxyCache===void 0?s.value:(s.value,s._proxyCache)},set(e,n,r,a){let o=(t.proxyTargets.has(r),r),s=e[n];if(s===o&&n!==`length`)return!0;e[n]=o;let c=i.get(n);if(c||(c=t.signal(s),i.set(n,c)),c._proxyCache=void 0,c.value=o,Array.isArray(e)&&n!==`length`){let t=i.get(`length`);t&&(t.value=e.length)}return!0}});return t.proxyCache.set(n,a),t.proxyTargets.add(a),a}exports.createReactive=t;
|
|
2
2
|
//# sourceMappingURL=core.method.reactive.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"core.method.reactive.cjs","names":[],"sources":["../src/core/core.method.reactive.ts"],"sourcesContent":["/**\n *
|
|
1
|
+
{"version":3,"file":"core.method.reactive.cjs","names":[],"sources":["../src/core/core.method.reactive.ts"],"sourcesContent":["/**\n * Изолированная фабрика глубоких реактивных Proxy-объектов графа.\n */\n\n// ⚡ ОПТИМИЗАЦИЯ СКОРОСТИ O(1) (Направление 1):\n// Выносим деструктивные методы массивов в статический инлайн-объект.\n// Это избавляет V8 от необходимости собирать массивы и вызывать .includes() на каждом геттере.\nconst DESTRUCTIVE_ARRAY_METHODS: Record<string | symbol, boolean> = {\n push: true,\n pop: true,\n shift: true,\n unshift: true,\n splice: true,\n sort: true,\n reverse: true\n}\n\nexport function createReactive<T extends object>(\n engine: any,\n target: T,\n name?: string\n): T {\n if (engine.proxyTargets.has(target)) return target as any\n if (engine.proxyCache.has(target)) return engine.proxyCache.get(target) as any\n if (!engine.reactiveSignals.has(target)) engine.reactiveSignals.set(target, new Map())\n const signalsMap = engine.reactiveSignals.get(target)!\n\n const handler: ProxyHandler<T> = {\n get(t: T, prop: string | symbol, receiver: any) {\n if (prop === '__subscribe' && Array.isArray(t)) {\n return (cb: () => void) => {\n let lengthSig = signalsMap.get('length')\n if (!lengthSig) {\n lengthSig = engine.signal(t.length)\n signalsMap.set('length', lengthSig)\n }\n return lengthSig.subscribe(cb)\n }\n }\n\n // ⚡ ОПТИМИЗАЦИЯ O(1) (Направление 1):\n // Мгновенная проверка по хэш-мапе за константное время вместо .includes()\n if (Array.isArray(t) && typeof prop === 'string' && DESTRUCTIVE_ARRAY_METHODS[prop]) {\n return (...args: any[]) => {\n let result: any\n engine.batch(() => {\n // Оптимизация: прямой вызов метода нативного прототипа\n result = (t as any)[prop].apply(receiver, args)\n\n let lengthSig = signalsMap.get('length')\n if (lengthSig) lengthSig.value = t.length\n\n signalsMap.forEach((sig: any, key: string) => {\n if (key !== 'length') sig.value = (t as any)[key]\n })\n })\n return result\n }\n }\n\n // ⚡ ОПТИМИЗАЦИЯ СКОРОСТИ (Направление 2):\n // Быстрый плоский ленивый выход для системных символов без вызова Reflect.get\n if (typeof prop === 'symbol' || prop === 'constructor' || prop === 'toJSON') {\n return (t as any)[prop]\n }\n\n let sig = signalsMap.get(prop)\n if (!sig) {\n // ⚡ ОПТИМИЗАЦИЯ (Направление 2): Заменяем Reflect.get на прямое чтение из кучи t[prop]\n const rawValue = (t as any)[prop]\n sig = engine.signal(rawValue)\n signalsMap.set(prop, sig)\n\n if (rawValue !== null && typeof rawValue === 'object') {\n sig._proxyCache = engine.reactive(rawValue, name ? `${name}.${String(prop)}` : String(prop))\n }\n }\n\n if (sig._proxyCache !== undefined) {\n sig.value // Честная регистрация ребра для сохранения топологии глубины веток\n return sig._proxyCache\n }\n\n return sig.value\n },\n\n set(t: T, prop: string | symbol, value: any, receiver: any) {\n const rawValue = engine.proxyTargets.has(value) ? value : value\n // ⚡ ОПТИМИЗАЦИЯ: Прямой доступ к старому значению\n const oldValue = (t as any)[prop]\n\n if (oldValue === rawValue && prop !== 'length') return true\n\n // Нативное присвоение свойства объекта\n ;(t as any)[prop] = rawValue\n\n let sig = signalsMap.get(prop)\n if (!sig) {\n sig = engine.signal(oldValue)\n signalsMap.set(prop, sig)\n }\n\n sig._proxyCache = undefined\n sig.value = rawValue\n\n if (Array.isArray(t) && prop !== 'length') {\n let lengthSig = signalsMap.get('length')\n if (lengthSig) lengthSig.value = t.length\n }\n return true\n }\n }\n\n const proxy = new Proxy(target, handler)\n engine.proxyCache.set(target, proxy)\n engine.proxyTargets.add(proxy)\n return proxy\n}\n"],"mappings":"AAOA,IAAM,EAA8D,CAClE,KAAM,GACN,IAAK,GACL,MAAO,GACP,QAAS,GACT,OAAQ,GACR,KAAM,GACN,QAAS,EACX,EAEA,SAAgB,EACd,EACA,EACA,EACG,CACH,GAAI,EAAO,aAAa,IAAI,CAAM,EAAG,OAAO,EAC5C,GAAI,EAAO,WAAW,IAAI,CAAM,EAAG,OAAO,EAAO,WAAW,IAAI,CAAM,EACjE,EAAO,gBAAgB,IAAI,CAAM,GAAG,EAAO,gBAAgB,IAAI,EAAQ,IAAI,GAAK,EACrF,IAAM,EAAa,EAAO,gBAAgB,IAAI,CAAM,EAwF9C,EAAQ,IAAI,MAAM,EAAQ,CArF9B,IAAI,EAAM,EAAuB,EAAe,CAC9C,GAAI,IAAS,eAAiB,MAAM,QAAQ,CAAC,EAC3C,MAAQ,IAAmB,CACzB,IAAI,EAAY,EAAW,IAAI,QAAQ,EAKvC,OAJK,IACH,EAAY,EAAO,OAAO,EAAE,MAAM,EAClC,EAAW,IAAI,SAAU,CAAS,GAE7B,EAAU,UAAU,CAAE,CAC/B,EAKF,GAAI,MAAM,QAAQ,CAAC,GAAK,OAAO,GAAS,UAAY,EAA0B,GAC5E,OAAQ,GAAG,IAAgB,CACzB,IAAI,EAYJ,OAXA,EAAO,UAAY,CAEjB,EAAU,EAAU,EAAK,CAAC,MAAM,EAAU,CAAI,EAE9C,IAAI,EAAY,EAAW,IAAI,QAAQ,EACnC,IAAW,EAAU,MAAQ,EAAE,QAEnC,EAAW,SAAS,EAAU,IAAgB,CACxC,IAAQ,WAAU,EAAI,MAAS,EAAU,GAC/C,CAAC,CACH,CAAC,EACM,CACT,EAKF,GAAI,OAAO,GAAS,UAAY,IAAS,eAAiB,IAAS,SACjE,OAAQ,EAAU,GAGpB,IAAI,EAAM,EAAW,IAAI,CAAI,EAC7B,GAAI,CAAC,EAAK,CAER,IAAM,EAAY,EAAU,GAC5B,EAAM,EAAO,OAAO,CAAQ,EAC5B,EAAW,IAAI,EAAM,CAAG,EAEC,OAAO,GAAa,UAAzC,IACF,EAAI,YAAc,EAAO,SAAS,EAAU,EAAO,GAAG,EAAK,GAAG,OAAO,CAAI,IAAM,OAAO,CAAI,CAAC,EAE/F,CAOA,OALI,EAAI,cAAgB,IAAA,GAKjB,EAAI,OAJT,EAAI,MACG,EAAI,YAIf,EAEA,IAAI,EAAM,EAAuB,EAAY,EAAe,CAC1D,IAAM,GAAW,EAAO,aAAa,IAAI,CAAK,EAAI,GAE5C,EAAY,EAAU,GAE5B,GAAI,IAAa,GAAY,IAAS,SAAU,MAAO,GAGtD,EAAW,GAAQ,EAEpB,IAAI,EAAM,EAAW,IAAI,CAAI,EAS7B,GARK,IACH,EAAM,EAAO,OAAO,CAAQ,EAC5B,EAAW,IAAI,EAAM,CAAG,GAG1B,EAAI,YAAc,IAAA,GAClB,EAAI,MAAQ,EAER,MAAM,QAAQ,CAAC,GAAK,IAAS,SAAU,CACzC,IAAI,EAAY,EAAW,IAAI,QAAQ,EACnC,IAAW,EAAU,MAAQ,EAAE,OACrC,CACA,MAAO,EACT,CAG8B,CAAO,EAGvC,OAFA,EAAO,WAAW,IAAI,EAAQ,CAAK,EACnC,EAAO,aAAa,IAAI,CAAK,EACtB,CACT"}
|
|
@@ -1,55 +1,56 @@
|
|
|
1
1
|
//#region src/core/core.method.reactive.ts
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
2
|
+
var e = {
|
|
3
|
+
push: !0,
|
|
4
|
+
pop: !0,
|
|
5
|
+
shift: !0,
|
|
6
|
+
unshift: !0,
|
|
7
|
+
splice: !0,
|
|
8
|
+
sort: !0,
|
|
9
|
+
reverse: !0
|
|
10
|
+
};
|
|
11
|
+
function t(t, n, r) {
|
|
12
|
+
if (t.proxyTargets.has(n)) return n;
|
|
13
|
+
if (t.proxyCache.has(n)) return t.proxyCache.get(n);
|
|
14
|
+
t.reactiveSignals.has(n) || t.reactiveSignals.set(n, /* @__PURE__ */ new Map());
|
|
15
|
+
let i = t.reactiveSignals.get(n), a = new Proxy(n, {
|
|
16
|
+
get(n, a, o) {
|
|
17
|
+
if (a === "__subscribe" && Array.isArray(n)) return (e) => {
|
|
18
|
+
let r = i.get("length");
|
|
19
|
+
return r || (r = t.signal(n.length), i.set("length", r)), r.subscribe(e);
|
|
11
20
|
};
|
|
12
|
-
if (Array.isArray(
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
"reverse"
|
|
20
|
-
].includes(i)) return (...n) => {
|
|
21
|
-
let o;
|
|
22
|
-
return e.batch(() => {
|
|
23
|
-
o = Reflect.get(t, i).apply(a, n);
|
|
24
|
-
let e = r.get("length");
|
|
25
|
-
e && (e.value = t.length), r.forEach((e, n) => {
|
|
26
|
-
n !== "length" && (e.value = Reflect.get(t, n));
|
|
21
|
+
if (Array.isArray(n) && typeof a == "string" && e[a]) return (...e) => {
|
|
22
|
+
let r;
|
|
23
|
+
return t.batch(() => {
|
|
24
|
+
r = n[a].apply(o, e);
|
|
25
|
+
let t = i.get("length");
|
|
26
|
+
t && (t.value = n.length), i.forEach((e, t) => {
|
|
27
|
+
t !== "length" && (e.value = n[t]);
|
|
27
28
|
});
|
|
28
|
-
}),
|
|
29
|
+
}), r;
|
|
29
30
|
};
|
|
30
|
-
if (typeof
|
|
31
|
-
let
|
|
32
|
-
if (!
|
|
33
|
-
let
|
|
34
|
-
|
|
31
|
+
if (typeof a == "symbol" || a === "constructor" || a === "toJSON") return n[a];
|
|
32
|
+
let s = i.get(a);
|
|
33
|
+
if (!s) {
|
|
34
|
+
let e = n[a];
|
|
35
|
+
s = t.signal(e), i.set(a, s), typeof e == "object" && e && (s._proxyCache = t.reactive(e, r ? `${r}.${String(a)}` : String(a)));
|
|
35
36
|
}
|
|
36
|
-
return
|
|
37
|
+
return s._proxyCache === void 0 ? s.value : (s.value, s._proxyCache);
|
|
37
38
|
},
|
|
38
|
-
set(
|
|
39
|
-
let o = (
|
|
39
|
+
set(e, n, r, a) {
|
|
40
|
+
let o = (t.proxyTargets.has(r), r), s = e[n];
|
|
40
41
|
if (s === o && n !== "length") return !0;
|
|
41
|
-
|
|
42
|
-
let c =
|
|
43
|
-
if (c || (c =
|
|
44
|
-
let
|
|
45
|
-
|
|
42
|
+
e[n] = o;
|
|
43
|
+
let c = i.get(n);
|
|
44
|
+
if (c || (c = t.signal(s), i.set(n, c)), c._proxyCache = void 0, c.value = o, Array.isArray(e) && n !== "length") {
|
|
45
|
+
let t = i.get("length");
|
|
46
|
+
t && (t.value = e.length);
|
|
46
47
|
}
|
|
47
48
|
return !0;
|
|
48
49
|
}
|
|
49
50
|
});
|
|
50
|
-
return
|
|
51
|
+
return t.proxyCache.set(n, a), t.proxyTargets.add(a), a;
|
|
51
52
|
}
|
|
52
53
|
//#endregion
|
|
53
|
-
export {
|
|
54
|
+
export { t as createReactive };
|
|
54
55
|
|
|
55
56
|
//# sourceMappingURL=core.method.reactive.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"core.method.reactive.mjs","names":[],"sources":["../src/core/core.method.reactive.ts"],"sourcesContent":["/**\n *
|
|
1
|
+
{"version":3,"file":"core.method.reactive.mjs","names":[],"sources":["../src/core/core.method.reactive.ts"],"sourcesContent":["/**\n * Изолированная фабрика глубоких реактивных Proxy-объектов графа.\n */\n\n// ⚡ ОПТИМИЗАЦИЯ СКОРОСТИ O(1) (Направление 1):\n// Выносим деструктивные методы массивов в статический инлайн-объект.\n// Это избавляет V8 от необходимости собирать массивы и вызывать .includes() на каждом геттере.\nconst DESTRUCTIVE_ARRAY_METHODS: Record<string | symbol, boolean> = {\n push: true,\n pop: true,\n shift: true,\n unshift: true,\n splice: true,\n sort: true,\n reverse: true\n}\n\nexport function createReactive<T extends object>(\n engine: any,\n target: T,\n name?: string\n): T {\n if (engine.proxyTargets.has(target)) return target as any\n if (engine.proxyCache.has(target)) return engine.proxyCache.get(target) as any\n if (!engine.reactiveSignals.has(target)) engine.reactiveSignals.set(target, new Map())\n const signalsMap = engine.reactiveSignals.get(target)!\n\n const handler: ProxyHandler<T> = {\n get(t: T, prop: string | symbol, receiver: any) {\n if (prop === '__subscribe' && Array.isArray(t)) {\n return (cb: () => void) => {\n let lengthSig = signalsMap.get('length')\n if (!lengthSig) {\n lengthSig = engine.signal(t.length)\n signalsMap.set('length', lengthSig)\n }\n return lengthSig.subscribe(cb)\n }\n }\n\n // ⚡ ОПТИМИЗАЦИЯ O(1) (Направление 1):\n // Мгновенная проверка по хэш-мапе за константное время вместо .includes()\n if (Array.isArray(t) && typeof prop === 'string' && DESTRUCTIVE_ARRAY_METHODS[prop]) {\n return (...args: any[]) => {\n let result: any\n engine.batch(() => {\n // Оптимизация: прямой вызов метода нативного прототипа\n result = (t as any)[prop].apply(receiver, args)\n\n let lengthSig = signalsMap.get('length')\n if (lengthSig) lengthSig.value = t.length\n\n signalsMap.forEach((sig: any, key: string) => {\n if (key !== 'length') sig.value = (t as any)[key]\n })\n })\n return result\n }\n }\n\n // ⚡ ОПТИМИЗАЦИЯ СКОРОСТИ (Направление 2):\n // Быстрый плоский ленивый выход для системных символов без вызова Reflect.get\n if (typeof prop === 'symbol' || prop === 'constructor' || prop === 'toJSON') {\n return (t as any)[prop]\n }\n\n let sig = signalsMap.get(prop)\n if (!sig) {\n // ⚡ ОПТИМИЗАЦИЯ (Направление 2): Заменяем Reflect.get на прямое чтение из кучи t[prop]\n const rawValue = (t as any)[prop]\n sig = engine.signal(rawValue)\n signalsMap.set(prop, sig)\n\n if (rawValue !== null && typeof rawValue === 'object') {\n sig._proxyCache = engine.reactive(rawValue, name ? `${name}.${String(prop)}` : String(prop))\n }\n }\n\n if (sig._proxyCache !== undefined) {\n sig.value // Честная регистрация ребра для сохранения топологии глубины веток\n return sig._proxyCache\n }\n\n return sig.value\n },\n\n set(t: T, prop: string | symbol, value: any, receiver: any) {\n const rawValue = engine.proxyTargets.has(value) ? value : value\n // ⚡ ОПТИМИЗАЦИЯ: Прямой доступ к старому значению\n const oldValue = (t as any)[prop]\n\n if (oldValue === rawValue && prop !== 'length') return true\n\n // Нативное присвоение свойства объекта\n ;(t as any)[prop] = rawValue\n\n let sig = signalsMap.get(prop)\n if (!sig) {\n sig = engine.signal(oldValue)\n signalsMap.set(prop, sig)\n }\n\n sig._proxyCache = undefined\n sig.value = rawValue\n\n if (Array.isArray(t) && prop !== 'length') {\n let lengthSig = signalsMap.get('length')\n if (lengthSig) lengthSig.value = t.length\n }\n return true\n }\n }\n\n const proxy = new Proxy(target, handler)\n engine.proxyCache.set(target, proxy)\n engine.proxyTargets.add(proxy)\n return proxy\n}\n"],"mappings":";AAOA,IAAM,IAA8D;CAClE,MAAM;CACN,KAAK;CACL,OAAO;CACP,SAAS;CACT,QAAQ;CACR,MAAM;CACN,SAAS;AACX;AAEA,SAAgB,EACd,GACA,GACA,GACG;CACH,IAAI,EAAO,aAAa,IAAI,CAAM,GAAG,OAAO;CAC5C,IAAI,EAAO,WAAW,IAAI,CAAM,GAAG,OAAO,EAAO,WAAW,IAAI,CAAM;CACtE,AAAK,EAAO,gBAAgB,IAAI,CAAM,KAAG,EAAO,gBAAgB,IAAI,mBAAQ,IAAI,IAAI,CAAC;CACrF,IAAM,IAAa,EAAO,gBAAgB,IAAI,CAAM,GAwF9C,IAAQ,IAAI,MAAM,GAAQ;EArF9B,IAAI,GAAM,GAAuB,GAAe;GAC9C,IAAI,MAAS,iBAAiB,MAAM,QAAQ,CAAC,GAC3C,QAAQ,MAAmB;IACzB,IAAI,IAAY,EAAW,IAAI,QAAQ;IAKvC,OAJK,MACH,IAAY,EAAO,OAAO,EAAE,MAAM,GAClC,EAAW,IAAI,UAAU,CAAS,IAE7B,EAAU,UAAU,CAAE;GAC/B;GAKF,IAAI,MAAM,QAAQ,CAAC,KAAK,OAAO,KAAS,YAAY,EAA0B,IAC5E,QAAQ,GAAG,MAAgB;IACzB,IAAI;IAYJ,OAXA,EAAO,YAAY;KAEjB,IAAU,EAAU,EAAK,CAAC,MAAM,GAAU,CAAI;KAE9C,IAAI,IAAY,EAAW,IAAI,QAAQ;KAGvC,AAFI,MAAW,EAAU,QAAQ,EAAE,SAEnC,EAAW,SAAS,GAAU,MAAgB;MAC5C,AAAI,MAAQ,aAAU,EAAI,QAAS,EAAU;KAC/C,CAAC;IACH,CAAC,GACM;GACT;GAKF,IAAI,OAAO,KAAS,YAAY,MAAS,iBAAiB,MAAS,UACjE,OAAQ,EAAU;GAGpB,IAAI,IAAM,EAAW,IAAI,CAAI;GAC7B,IAAI,CAAC,GAAK;IAER,IAAM,IAAY,EAAU;IAI5B,AAHA,IAAM,EAAO,OAAO,CAAQ,GAC5B,EAAW,IAAI,GAAM,CAAG,GAEC,OAAO,KAAa,YAAzC,MACF,EAAI,cAAc,EAAO,SAAS,GAAU,IAAO,GAAG,EAAK,GAAG,OAAO,CAAI,MAAM,OAAO,CAAI,CAAC;GAE/F;GAOA,OALI,EAAI,gBAAgB,KAAA,IAKjB,EAAI,SAJT,EAAI,OACG,EAAI;EAIf;EAEA,IAAI,GAAM,GAAuB,GAAY,GAAe;GAC1D,IAAM,KAAW,EAAO,aAAa,IAAI,CAAK,GAAI,IAE5C,IAAY,EAAU;GAE5B,IAAI,MAAa,KAAY,MAAS,UAAU,OAAO;GAGtD,EAAW,KAAQ;GAEpB,IAAI,IAAM,EAAW,IAAI,CAAI;GAS7B,IARK,MACH,IAAM,EAAO,OAAO,CAAQ,GAC5B,EAAW,IAAI,GAAM,CAAG,IAG1B,EAAI,cAAc,KAAA,GAClB,EAAI,QAAQ,GAER,MAAM,QAAQ,CAAC,KAAK,MAAS,UAAU;IACzC,IAAI,IAAY,EAAW,IAAI,QAAQ;IACvC,AAAI,MAAW,EAAU,QAAQ,EAAE;GACrC;GACA,OAAO;EACT;CAG8B,CAAO;CAGvC,OAFA,EAAO,WAAW,IAAI,GAAQ,CAAK,GACnC,EAAO,aAAa,IAAI,CAAK,GACtB;AACT"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const e=require("./utils/getExtractedValues.cjs");function t(t,n,r){let i=n,a=0,o=typeof r==`string`?r:r?.name,s=!!o&&e.getExtractedValues({tested:[o],expectedKey:`CORE_INTERNAL_SIGNAL`,valueType:`number`})?.[0]===`1`||!1,c=new Set,l=!1,u=n,d={type:`signal`,get version(){return a},subscribers:c},f=()=>{for(let e of c){let n=e._node||e;if(n.type===`effect`)n.isDirty=!0,t.scheduleEffect(e);else if(n.type===`computed`)n.markDirty&&n.markDirty(2);else if(typeof e==`function`)try{e(i)}catch(e){console.error(e)}else if(e&&typeof e.run==`function`)try{e.run()}catch(e){console.error(e)}}},p={get value(){let e=t.activeConsumer;
|
|
1
|
+
const e=require("./utils/getExtractedValues.cjs");function t(t,n,r){let i=n,a=0,o=typeof r==`string`?r:r?.name,s=!!o&&e.getExtractedValues({tested:[o],expectedKey:`CORE_INTERNAL_SIGNAL`,valueType:`number`})?.[0]===`1`||!1,c=new Set,l=!1,u=n,d={type:`signal`,get version(){return a},subscribers:c},f=()=>{for(let e of c){let n=e._node||e;if(n.type===`effect`)n.isDirty=!0,t.scheduleEffect(e);else if(n.type===`computed`)n.markDirty&&n.markDirty(2);else if(typeof e==`function`)try{e(i)}catch(e){console.error(e)}else if(e&&typeof e.run==`function`)try{e.run()}catch(e){console.error(e)}}},p={get value(){let e=t.activeConsumer;if(e){c.add(t.activeConsumer),t.activeConsumer.dependencies.add(p);let n=e._node||e;n.depth!==void 0&&n.depth===1&&(n.depth=2),e.activeRunId!==void 0&&(p._lastSeenInRunId=e.activeRunId)}return i},set value(e){if(Object.is(i,e)&&!(i===e&&typeof i==`object`&&i))return;if(r&&typeof r==`object`&&r.validate){let t=r.validate(e);if(t!==!0){console.error(typeof t==`string`?t:`[Validation Error]`);return}}if(t.batchDepth>0){l||(l=!0,u=i),i=e,(p._nextBatched===void 0||p._nextBatched===null)&&(p._nextBatched=null,t.lastBatchedSignal===null?(t.firstBatchedSignal=p,t.lastBatchedSignal=p):(t.lastBatchedSignal._nextBatched=p,t.lastBatchedSignal=p));return}let n=i;i=e,a++,t.epoch++,t.isLoggingEnabled&&t.log({type:`signal`,label:o||`signal`,details:{from:n,to:e},isInternalCoreSignal:s}),f(),t.batchDepth===0&&t.flushEffects()},get version(){return a},type:`signal`,subscribe(e){return c.add(e),e(i),()=>{c.delete(e)}},_flushBatch:()=>{l&&((!Object.is(u,i)||typeof i==`object`&&i)&&(a++,t.epoch++,t.isLoggingEnabled&&t.log({type:`signal`,label:o||`signal_batched`,details:{from:u,to:i},isInternalCoreSignal:s}),f()),l=!1,u=i)}};return p._node=d,p.subscribers=c,p}exports.createSignal=t;
|
|
2
2
|
//# sourceMappingURL=core.method.signal.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"core.method.signal.cjs","names":[],"sources":["../src/core/core.method.signal.ts"],"sourcesContent":["import { getExtractedValues } from '../utils/getExtractedValues'\nimport { Signal, SignalOptions } from './types'\n\nexport function createSignal<T>(\n engine: any,\n initialValue: T,\n optionsOrName?: SignalOptions<T> | string\n): Signal<T> {\n let value = initialValue\n let version = 0\n let name = typeof optionsOrName === 'string' ? optionsOrName : optionsOrName?.name\n const isInternalCoreSignal = !!name && getExtractedValues({\n tested: [name],\n expectedKey: 'CORE_INTERNAL_SIGNAL',\n valueType: 'number',\n })?.[0] === '1' || false\n const subscribers = new Set<any>()\n\n let hasBatchValue = false\n let batchInitialValue: T = initialValue\n\n const signalNode = {\n type: 'signal',\n get version() { return version },\n subscribers\n }\n\n const notifySubscribers = () => {\n // ⚡ ОПТИМИЗАЦИЯ: Прямой проход по Set через for...of (без Array.from)\n for (const sub of subscribers) {\n const rawSub = sub._node || sub\n if (rawSub.type === 'effect') {\n rawSub.isDirty = true\n engine.scheduleEffect(sub)\n } else if (rawSub.type === 'computed') {\n if (rawSub.markDirty) rawSub.markDirty(2)\n } else {\n if (typeof sub === 'function') {\n try { sub(value) } catch (err) { console.error(err) }\n } else if (sub && typeof sub.run === 'function') {\n try { sub.run() } catch (err) { console.error(err) }\n }\n }\n }\n }\n\n const signalInstance: Signal<T> = {\n get value() {\n const consumer = engine.activeConsumer\n if (consumer) {\n subscribers.add(engine.activeConsumer)\n engine.activeConsumer.dependencies.add(signalInstance)\n\n //
|
|
1
|
+
{"version":3,"file":"core.method.signal.cjs","names":[],"sources":["../src/core/core.method.signal.ts"],"sourcesContent":["import { getExtractedValues } from '../utils/getExtractedValues'\nimport { Signal, SignalOptions } from './types'\n\nexport function createSignal<T>(\n engine: any,\n initialValue: T,\n optionsOrName?: SignalOptions<T> | string\n): Signal<T> {\n let value = initialValue\n let version = 0\n let name = typeof optionsOrName === 'string' ? optionsOrName : optionsOrName?.name\n const isInternalCoreSignal = !!name && getExtractedValues({\n tested: [name],\n expectedKey: 'CORE_INTERNAL_SIGNAL',\n valueType: 'number',\n })?.[0] === '1' || false\n const subscribers = new Set<any>()\n\n let hasBatchValue = false\n let batchInitialValue: T = initialValue\n\n const signalNode = {\n type: 'signal',\n get version() { return version },\n subscribers\n }\n\n const notifySubscribers = () => {\n // ⚡ ОПТИМИЗАЦИЯ: Прямой проход по Set через for...of (без Array.from)\n for (const sub of subscribers) {\n const rawSub = sub._node || sub\n if (rawSub.type === 'effect') {\n rawSub.isDirty = true\n engine.scheduleEffect(sub)\n } else if (rawSub.type === 'computed') {\n if (rawSub.markDirty) rawSub.markDirty(2)\n } else {\n if (typeof sub === 'function') {\n try { sub(value) } catch (err) { console.error(err) }\n } else if (sub && typeof sub.run === 'function') {\n try { sub.run() } catch (err) { console.error(err) }\n }\n }\n }\n }\n\n const signalInstance: Signal<T> = {\n get value() {\n const consumer = engine.activeConsumer\n if (consumer) {\n subscribers.add(engine.activeConsumer)\n engine.activeConsumer.dependencies.add(signalInstance)\n\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 // ⚡ ВСТАВКА В ZERO-ALLOCATION LINKED-LIST ЦЕПОЧКУ БАТЧА\n if ((signalInstance as any)._nextBatched === undefined || (signalInstance as any)._nextBatched === null) {\n (signalInstance as any)._nextBatched = null // Инициализируем поле связи\n\n if (engine.lastBatchedSignal === null) {\n engine.firstBatchedSignal = signalInstance\n engine.lastBatchedSignal = signalInstance\n } else {\n engine.lastBatchedSignal._nextBatched = signalInstance\n engine.lastBatchedSignal = signalInstance\n }\n }\n return\n }\n\n const oldValue = value\n value = newValue\n\n version++\n engine.epoch++\n\n if (engine.isLoggingEnabled) {\n engine.log({\n type: 'signal',\n label: name || 'signal',\n details: { from: oldValue, to: newValue },\n isInternalCoreSignal\n })\n }\n notifySubscribers()\n if (engine.batchDepth === 0) engine.flushEffects()\n },\n\n get version() { return version },\n type: 'signal',\n\n subscribe(cb: (val: T) => void) {\n subscribers.add(cb)\n cb(value)\n return () => { subscribers.delete(cb) }\n },\n\n _flushBatch: () => {\n if (!hasBatchValue) return\n\n const wasChanged = !Object.is(batchInitialValue, value) || (value !== null && typeof value === 'object')\n\n if (wasChanged) {\n version++\n engine.epoch++\n\n if (engine.isLoggingEnabled) {\n engine.log({\n type: 'signal',\n label: name || 'signal_batched',\n details: { from: batchInitialValue, to: value },\n isInternalCoreSignal\n })\n }\n notifySubscribers()\n }\n\n hasBatchValue = false\n batchInitialValue = value\n }\n } as any\n\n ;(signalInstance as any)._node = signalNode\n ;(signalInstance as any).subscribers = subscribers\n return signalInstance\n}\n"],"mappings":"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"}
|
|
@@ -30,7 +30,12 @@ function t(t, n, r) {
|
|
|
30
30
|
}, p = {
|
|
31
31
|
get value() {
|
|
32
32
|
let e = t.activeConsumer;
|
|
33
|
-
|
|
33
|
+
if (e) {
|
|
34
|
+
c.add(t.activeConsumer), t.activeConsumer.dependencies.add(p);
|
|
35
|
+
let n = e._node || e;
|
|
36
|
+
n.depth !== void 0 && n.depth === 1 && (n.depth = 2), e.activeRunId !== void 0 && (p._lastSeenInRunId = e.activeRunId);
|
|
37
|
+
}
|
|
38
|
+
return i;
|
|
34
39
|
},
|
|
35
40
|
set value(e) {
|
|
36
41
|
if (Object.is(i, e) && !(i === e && typeof i == "object" && i)) return;
|
|
@@ -42,11 +47,11 @@ function t(t, n, r) {
|
|
|
42
47
|
}
|
|
43
48
|
}
|
|
44
49
|
if (t.batchDepth > 0) {
|
|
45
|
-
l || (l = !0, u = i), i = e, t.
|
|
50
|
+
l || (l = !0, u = i), i = e, (p._nextBatched === void 0 || p._nextBatched === null) && (p._nextBatched = null, t.lastBatchedSignal === null ? (t.firstBatchedSignal = p, t.lastBatchedSignal = p) : (t.lastBatchedSignal._nextBatched = p, t.lastBatchedSignal = p));
|
|
46
51
|
return;
|
|
47
52
|
}
|
|
48
53
|
let n = i;
|
|
49
|
-
i = e, a++, t.epoch++, t.log({
|
|
54
|
+
i = e, a++, t.epoch++, t.isLoggingEnabled && t.log({
|
|
50
55
|
type: "signal",
|
|
51
56
|
label: o || "signal",
|
|
52
57
|
details: {
|
|
@@ -66,7 +71,7 @@ function t(t, n, r) {
|
|
|
66
71
|
};
|
|
67
72
|
},
|
|
68
73
|
_flushBatch: () => {
|
|
69
|
-
l && ((!Object.is(u, i) || typeof i == "object" && i) && (a++, t.epoch++, t.log({
|
|
74
|
+
l && ((!Object.is(u, i) || typeof i == "object" && i) && (a++, t.epoch++, t.isLoggingEnabled && t.log({
|
|
70
75
|
type: "signal",
|
|
71
76
|
label: o || "signal_batched",
|
|
72
77
|
details: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"core.method.signal.mjs","names":[],"sources":["../src/core/core.method.signal.ts"],"sourcesContent":["import { getExtractedValues } from '../utils/getExtractedValues'\nimport { Signal, SignalOptions } from './types'\n\nexport function createSignal<T>(\n engine: any,\n initialValue: T,\n optionsOrName?: SignalOptions<T> | string\n): Signal<T> {\n let value = initialValue\n let version = 0\n let name = typeof optionsOrName === 'string' ? optionsOrName : optionsOrName?.name\n const isInternalCoreSignal = !!name && getExtractedValues({\n tested: [name],\n expectedKey: 'CORE_INTERNAL_SIGNAL',\n valueType: 'number',\n })?.[0] === '1' || false\n const subscribers = new Set<any>()\n\n let hasBatchValue = false\n let batchInitialValue: T = initialValue\n\n const signalNode = {\n type: 'signal',\n get version() { return version },\n subscribers\n }\n\n const notifySubscribers = () => {\n // ⚡ ОПТИМИЗАЦИЯ: Прямой проход по Set через for...of (без Array.from)\n for (const sub of subscribers) {\n const rawSub = sub._node || sub\n if (rawSub.type === 'effect') {\n rawSub.isDirty = true\n engine.scheduleEffect(sub)\n } else if (rawSub.type === 'computed') {\n if (rawSub.markDirty) rawSub.markDirty(2)\n } else {\n if (typeof sub === 'function') {\n try { sub(value) } catch (err) { console.error(err) }\n } else if (sub && typeof sub.run === 'function') {\n try { sub.run() } catch (err) { console.error(err) }\n }\n }\n }\n }\n\n const signalInstance: Signal<T> = {\n get value() {\n const consumer = engine.activeConsumer\n if (consumer) {\n subscribers.add(engine.activeConsumer)\n engine.activeConsumer.dependencies.add(signalInstance)\n\n //
|
|
1
|
+
{"version":3,"file":"core.method.signal.mjs","names":[],"sources":["../src/core/core.method.signal.ts"],"sourcesContent":["import { getExtractedValues } from '../utils/getExtractedValues'\nimport { Signal, SignalOptions } from './types'\n\nexport function createSignal<T>(\n engine: any,\n initialValue: T,\n optionsOrName?: SignalOptions<T> | string\n): Signal<T> {\n let value = initialValue\n let version = 0\n let name = typeof optionsOrName === 'string' ? optionsOrName : optionsOrName?.name\n const isInternalCoreSignal = !!name && getExtractedValues({\n tested: [name],\n expectedKey: 'CORE_INTERNAL_SIGNAL',\n valueType: 'number',\n })?.[0] === '1' || false\n const subscribers = new Set<any>()\n\n let hasBatchValue = false\n let batchInitialValue: T = initialValue\n\n const signalNode = {\n type: 'signal',\n get version() { return version },\n subscribers\n }\n\n const notifySubscribers = () => {\n // ⚡ ОПТИМИЗАЦИЯ: Прямой проход по Set через for...of (без Array.from)\n for (const sub of subscribers) {\n const rawSub = sub._node || sub\n if (rawSub.type === 'effect') {\n rawSub.isDirty = true\n engine.scheduleEffect(sub)\n } else if (rawSub.type === 'computed') {\n if (rawSub.markDirty) rawSub.markDirty(2)\n } else {\n if (typeof sub === 'function') {\n try { sub(value) } catch (err) { console.error(err) }\n } else if (sub && typeof sub.run === 'function') {\n try { sub.run() } catch (err) { console.error(err) }\n }\n }\n }\n }\n\n const signalInstance: Signal<T> = {\n get value() {\n const consumer = engine.activeConsumer\n if (consumer) {\n subscribers.add(engine.activeConsumer)\n engine.activeConsumer.dependencies.add(signalInstance)\n\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 // ⚡ ВСТАВКА В ZERO-ALLOCATION LINKED-LIST ЦЕПОЧКУ БАТЧА\n if ((signalInstance as any)._nextBatched === undefined || (signalInstance as any)._nextBatched === null) {\n (signalInstance as any)._nextBatched = null // Инициализируем поле связи\n\n if (engine.lastBatchedSignal === null) {\n engine.firstBatchedSignal = signalInstance\n engine.lastBatchedSignal = signalInstance\n } else {\n engine.lastBatchedSignal._nextBatched = signalInstance\n engine.lastBatchedSignal = signalInstance\n }\n }\n return\n }\n\n const oldValue = value\n value = newValue\n\n version++\n engine.epoch++\n\n if (engine.isLoggingEnabled) {\n engine.log({\n type: 'signal',\n label: name || 'signal',\n details: { from: oldValue, to: newValue },\n isInternalCoreSignal\n })\n }\n notifySubscribers()\n if (engine.batchDepth === 0) engine.flushEffects()\n },\n\n get version() { return version },\n type: 'signal',\n\n subscribe(cb: (val: T) => void) {\n subscribers.add(cb)\n cb(value)\n return () => { subscribers.delete(cb) }\n },\n\n _flushBatch: () => {\n if (!hasBatchValue) return\n\n const wasChanged = !Object.is(batchInitialValue, value) || (value !== null && typeof value === 'object')\n\n if (wasChanged) {\n version++\n engine.epoch++\n\n if (engine.isLoggingEnabled) {\n engine.log({\n type: 'signal',\n label: name || 'signal_batched',\n details: { from: batchInitialValue, to: value },\n isInternalCoreSignal\n })\n }\n notifySubscribers()\n }\n\n hasBatchValue = false\n batchInitialValue = value\n }\n } as any\n\n ;(signalInstance as any)._node = signalNode\n ;(signalInstance as any).subscribers = subscribers\n return signalInstance\n}\n"],"mappings":"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"}
|
package/dist/core.mjs
CHANGED
|
@@ -56,9 +56,11 @@ function d() {
|
|
|
56
56
|
var f = class {
|
|
57
57
|
frameworkPrefix = "core";
|
|
58
58
|
logger;
|
|
59
|
-
|
|
60
|
-
|
|
59
|
+
pendingEffectsHeads = [];
|
|
60
|
+
pendingEffectsTails = [];
|
|
61
61
|
batchDepth = 0;
|
|
62
|
+
activeConsumer = null;
|
|
63
|
+
epoch = 0;
|
|
62
64
|
subscriberId = 0;
|
|
63
65
|
pendingEffects = [];
|
|
64
66
|
maxPendingDepth = 0;
|
|
@@ -72,11 +74,12 @@ var f = class {
|
|
|
72
74
|
batchedSignals = /* @__PURE__ */ new Set();
|
|
73
75
|
activeOwner = null;
|
|
74
76
|
pendingCleanups = /* @__PURE__ */ new Set();
|
|
77
|
+
isLoggingEnabled = !1;
|
|
75
78
|
queueCleanup(e) {
|
|
76
79
|
this.pendingCleanups.add(e);
|
|
77
80
|
}
|
|
78
81
|
constructor(e) {
|
|
79
|
-
this.logger = e?.logger || { isEnabled: !1 };
|
|
82
|
+
this.logger = e?.logger || { isEnabled: !1 }, this.isLoggingEnabled = !!this.logger.isEnabled;
|
|
80
83
|
}
|
|
81
84
|
scheduleEffect(e) {
|
|
82
85
|
let t = e.depth || 0;
|
|
@@ -85,15 +88,18 @@ var f = class {
|
|
|
85
88
|
queueLog(e, t, n) {
|
|
86
89
|
u(e, t, n);
|
|
87
90
|
}
|
|
91
|
+
firstBatchedSignal = null;
|
|
92
|
+
lastBatchedSignal = null;
|
|
88
93
|
batch(e) {
|
|
89
94
|
this.batchDepth++;
|
|
90
95
|
try {
|
|
91
96
|
return e();
|
|
92
97
|
} finally {
|
|
93
98
|
if (this.batchDepth--, this.batchDepth === 0) {
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
99
|
+
let e = this.firstBatchedSignal;
|
|
100
|
+
for (this.firstBatchedSignal = null, this.lastBatchedSignal = null; e !== null;) {
|
|
101
|
+
let t = e._nextBatched;
|
|
102
|
+
e._nextBatched = null, e._flushBatch && e._flushBatch(), e = t;
|
|
97
103
|
}
|
|
98
104
|
this.flushEffects();
|
|
99
105
|
}
|