@pravosleva/reactive-engine 0.4.2-beta → 1.0.1-beta

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.
Files changed (141) hide show
  1. package/README.md +29 -0
  2. package/dist/AbstractService.cjs +2 -0
  3. package/dist/AbstractService.cjs.map +1 -0
  4. package/dist/AbstractService.mjs +24 -0
  5. package/dist/AbstractService.mjs.map +1 -0
  6. package/dist/BaseREServiceEnhanced.cjs +2 -0
  7. package/dist/BaseREServiceEnhanced.cjs.map +1 -0
  8. package/dist/BaseREServiceEnhanced.mjs +12 -0
  9. package/dist/BaseREServiceEnhanced.mjs.map +1 -0
  10. package/dist/_react-bindings.d.ts +17 -0
  11. package/dist/_react-bindings.d.ts.map +1 -0
  12. package/dist/_virtual/_rolldown/runtime.cjs +1 -0
  13. package/dist/core/AbstractService.d.ts +11 -0
  14. package/dist/core/AbstractService.d.ts.map +1 -0
  15. package/dist/core/BaseREServiceEnhanced.d.ts +7 -0
  16. package/dist/core/BaseREServiceEnhanced.d.ts.map +1 -0
  17. package/dist/core/core.d.ts +282 -0
  18. package/dist/core/core.d.ts.map +1 -0
  19. package/dist/core/core.test.d.ts +2 -0
  20. package/dist/core/core.test.d.ts.map +1 -0
  21. package/dist/core/index.d.ts +5 -0
  22. package/dist/core/index.d.ts.map +1 -0
  23. package/dist/core/types.d.ts +92 -0
  24. package/dist/core/types.d.ts.map +1 -0
  25. package/dist/core.cjs +2 -0
  26. package/dist/core.cjs.map +1 -0
  27. package/dist/core.mjs +286 -0
  28. package/dist/core.mjs.map +1 -0
  29. package/dist/decorators/index.d.ts +6 -0
  30. package/dist/decorators/index.d.ts.map +1 -0
  31. package/dist/decorators/withCache/index.d.ts +2 -0
  32. package/dist/decorators/withCache/index.d.ts.map +1 -0
  33. package/dist/decorators/withCache/withCache.d.ts +13 -0
  34. package/dist/decorators/withCache/withCache.d.ts.map +1 -0
  35. package/dist/decorators/withCache/withCache.test.d.ts +2 -0
  36. package/dist/decorators/withCache/withCache.test.d.ts.map +1 -0
  37. package/dist/decorators/withDebounce/index.d.ts +2 -0
  38. package/dist/decorators/withDebounce/index.d.ts.map +1 -0
  39. package/dist/decorators/withDebounce/withDebounce.d.ts +12 -0
  40. package/dist/decorators/withDebounce/withDebounce.d.ts.map +1 -0
  41. package/dist/decorators/withDebounce/withDebounce.test.d.ts +2 -0
  42. package/dist/decorators/withDebounce/withDebounce.test.d.ts.map +1 -0
  43. package/dist/decorators/withLongPolling/index.d.ts +2 -0
  44. package/dist/decorators/withLongPolling/index.d.ts.map +1 -0
  45. package/dist/decorators/withLongPolling/withLongPolling.d.ts +28 -0
  46. package/dist/decorators/withLongPolling/withLongPolling.d.ts.map +1 -0
  47. package/dist/decorators/withLongPolling/withLongPolling.test.d.ts +2 -0
  48. package/dist/decorators/withLongPolling/withLongPolling.test.d.ts.map +1 -0
  49. package/dist/decorators/withThrottle/index.d.ts +2 -0
  50. package/dist/decorators/withThrottle/index.d.ts.map +1 -0
  51. package/dist/decorators/withThrottle/withThrottle.d.ts +12 -0
  52. package/dist/decorators/withThrottle/withThrottle.d.ts.map +1 -0
  53. package/dist/decorators/withThrottle/withThrottle.test.d.ts +2 -0
  54. package/dist/decorators/withThrottle/withThrottle.test.d.ts.map +1 -0
  55. package/dist/decorators/withThrottleAndCache/index.d.ts +2 -0
  56. package/dist/decorators/withThrottleAndCache/index.d.ts.map +1 -0
  57. package/dist/decorators/withThrottleAndCache/withThrottleAndCache.d.ts +13 -0
  58. package/dist/decorators/withThrottleAndCache/withThrottleAndCache.d.ts.map +1 -0
  59. package/dist/decorators/withThrottleAndCache/withThrottleAndCache.test.d.ts +2 -0
  60. package/dist/decorators/withThrottleAndCache/withThrottleAndCache.test.d.ts.map +1 -0
  61. package/dist/index.cjs +1 -6
  62. package/dist/index.d.ts +2 -605
  63. package/dist/index.d.ts.map +1 -0
  64. package/dist/index.mjs +4 -541
  65. package/dist/react/ReactiveEngine4React.cjs +6 -0
  66. package/dist/react/ReactiveEngine4React.cjs.map +1 -0
  67. package/dist/react/ReactiveEngine4React.d.ts +27 -0
  68. package/dist/react/ReactiveEngine4React.d.ts.map +1 -0
  69. package/dist/react/ReactiveEngine4React.mjs +28 -0
  70. package/dist/react/ReactiveEngine4React.mjs.map +1 -0
  71. package/dist/react/core.react.test.d.ts +2 -0
  72. package/dist/react/core.react.test.d.ts.map +1 -0
  73. package/dist/react/createObserver.cjs +2 -0
  74. package/dist/react/createObserver.cjs.map +1 -0
  75. package/dist/react/createObserver.d.ts +70 -0
  76. package/dist/react/createObserver.d.ts.map +1 -0
  77. package/dist/react/createObserver.mjs +62 -0
  78. package/dist/react/createObserver.mjs.map +1 -0
  79. package/dist/react/createObserver.test.d.ts +2 -0
  80. package/dist/react/createObserver.test.d.ts.map +1 -0
  81. package/dist/react/hooks/FilteredCatalog.test.d.ts +2 -0
  82. package/dist/react/hooks/FilteredCatalog.test.d.ts.map +1 -0
  83. package/dist/react/hooks/index.cjs +1 -0
  84. package/dist/react/hooks/index.d.ts +4 -0
  85. package/dist/react/hooks/index.d.ts.map +1 -0
  86. package/dist/react/hooks/index.mjs +7 -0
  87. package/dist/react/hooks/types.d.ts +16 -0
  88. package/dist/react/hooks/types.d.ts.map +1 -0
  89. package/dist/react/hooks/useReactiveSubscription/index.cjs +1 -0
  90. package/dist/react/hooks/useReactiveSubscription/index.d.ts +2 -0
  91. package/dist/react/hooks/useReactiveSubscription/index.d.ts.map +1 -0
  92. package/dist/react/hooks/useReactiveSubscription/index.mjs +2 -0
  93. package/dist/react/hooks/useReactiveSubscription/useReactiveSubscription.cjs +2 -0
  94. package/dist/react/hooks/useReactiveSubscription/useReactiveSubscription.cjs.map +1 -0
  95. package/dist/react/hooks/useReactiveSubscription/useReactiveSubscription.d.ts +10 -0
  96. package/dist/react/hooks/useReactiveSubscription/useReactiveSubscription.d.ts.map +1 -0
  97. package/dist/react/hooks/useReactiveSubscription/useReactiveSubscription.mjs +14 -0
  98. package/dist/react/hooks/useReactiveSubscription/useReactiveSubscription.mjs.map +1 -0
  99. package/dist/react/hooks/useReactiveSubscription/useReactiveSubscription.test.d.ts +2 -0
  100. package/dist/react/hooks/useReactiveSubscription/useReactiveSubscription.test.d.ts.map +1 -0
  101. package/dist/react/hooks/useReactiveValue/index.cjs +1 -0
  102. package/dist/react/hooks/useReactiveValue/index.d.ts +2 -0
  103. package/dist/react/hooks/useReactiveValue/index.d.ts.map +1 -0
  104. package/dist/react/hooks/useReactiveValue/index.mjs +2 -0
  105. package/dist/react/hooks/useReactiveValue/useReactiveValue.cjs +2 -0
  106. package/dist/react/hooks/useReactiveValue/useReactiveValue.cjs.map +1 -0
  107. package/dist/react/hooks/useReactiveValue/useReactiveValue.d.ts +16 -0
  108. package/dist/react/hooks/useReactiveValue/useReactiveValue.d.ts.map +1 -0
  109. package/dist/react/hooks/useReactiveValue/useReactiveValue.mjs +12 -0
  110. package/dist/react/hooks/useReactiveValue/useReactiveValue.mjs.map +1 -0
  111. package/dist/react/hooks/useReactiveValue/useReactiveValue.test.d.ts +2 -0
  112. package/dist/react/hooks/useReactiveValue/useReactiveValue.test.d.ts.map +1 -0
  113. package/dist/react/hooks/useReactiveValue0/index.cjs +1 -0
  114. package/dist/react/hooks/useReactiveValue0/index.d.ts +2 -0
  115. package/dist/react/hooks/useReactiveValue0/index.d.ts.map +1 -0
  116. package/dist/react/hooks/useReactiveValue0/index.mjs +2 -0
  117. package/dist/react/hooks/useReactiveValue0/useReactiveValue0.cjs +2 -0
  118. package/dist/react/hooks/useReactiveValue0/useReactiveValue0.cjs.map +1 -0
  119. package/dist/react/hooks/useReactiveValue0/useReactiveValue0.d.ts +15 -0
  120. package/dist/react/hooks/useReactiveValue0/useReactiveValue0.d.ts.map +1 -0
  121. package/dist/react/hooks/useReactiveValue0/useReactiveValue0.mjs +20 -0
  122. package/dist/react/hooks/useReactiveValue0/useReactiveValue0.mjs.map +1 -0
  123. package/dist/react/index.cjs +1 -0
  124. package/dist/react/index.d.ts +4 -0
  125. package/dist/react/index.d.ts.map +1 -0
  126. package/dist/react/index.mjs +7 -0
  127. package/dist/react/types.d.ts +2 -0
  128. package/dist/react/types.d.ts.map +1 -0
  129. package/dist/utils/getExtractedValues.cjs +2 -0
  130. package/dist/utils/getExtractedValues.cjs.map +1 -0
  131. package/dist/utils/getExtractedValues.d.ts +6 -0
  132. package/dist/utils/getExtractedValues.d.ts.map +1 -0
  133. package/dist/utils/getExtractedValues.mjs +21 -0
  134. package/dist/utils/getExtractedValues.mjs.map +1 -0
  135. package/dist/utils/index.d.ts +2 -0
  136. package/dist/utils/index.d.ts.map +1 -0
  137. package/package.json +17 -3
  138. package/dist/index.cjs.map +0 -1
  139. package/dist/index.iife.js +0 -6
  140. package/dist/index.iife.js.map +0 -1
  141. package/dist/index.mjs.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createObserver.cjs","names":[],"sources":["../../src/react/createObserver.tsx"],"sourcesContent":["import React, { useSyncExternalStore, useMemo, useEffect, useRef } from 'react'\nimport { ReactiveEngine } from '../core'\n\n/**\n * Свойства для инлайн-компонента {@link Observer}.\n */\ninterface ObserverProps {\n /**\n * Функция-рендер, возвращающая JSX-разметку.\n * Сигналы, прочитанные внутри этого коллбека, будут автоматически отслеживаться.\n */\n children: () => React.ReactNode;\n}\n\n/**\n * Фабрика для создания инлайн-компонента `<Observer>`.\n *\n * @param engine - Экземпляр реактивного движка {@link ReactiveEngine}.\n * @returns Специальный React-компонент для точечной изоляции реактивных обновлений в JSX.\n *\n * @example\n * ```tsx\n * import { createObserverComponent, engine } from '@pravosleva/reactive-engine';\n *\n * const Observer = createObserverComponent(engine);\n * const priceSignal = engine.signal(100);\n *\n * export const MyComponent = () => {\n * return (\n * <div>\n * <h1>Статический тяжелый контент (не перерисовывается)</h1>\n * <Observer>\n * {() => <span>Живая цена: {priceSignal.value}</span>}\n * </Observer>\n * </div>\n * );\n * };\n * ```\n */\nexport const createObserverComponent = (engine: ReactiveEngine) => {\n return ({ children }: ObserverProps): any => {\n const versionRef = useRef(0);\n const onStoreChangeRef = useRef<(() => void) | null>(null);\n\n // Ссылки для удержания инстанса эффекта и функции отписки\n const unsubscribeRef = useRef<(() => void) | null>(null);\n const effectObjRef = useRef<any>(null);\n\n // 1. Создаем стабильный мост подписки для React ОДИН раз за жизнь компонента\n const storeBridge = useMemo(() => {\n return {\n subscribe(onStoreChange: () => void) {\n onStoreChangeRef.current = onStoreChange;\n return () => {\n onStoreChangeRef.current = null;\n if (unsubscribeRef.current) {\n unsubscribeRef.current();\n unsubscribeRef.current = null;\n effectObjRef.current = null;\n }\n };\n },\n getSnapshot() {\n return versionRef.current;\n }\n };\n }, []);\n\n // Очистка при полном размонтировании из DOM\n useEffect(() => {\n return () => {\n if (unsubscribeRef.current) unsubscribeRef.current();\n };\n }, []);\n\n // 2. ЛЕЗИ-ИНИЦИАЛИЗАЦИЯ: Создаем реактивный эффект ядра ровно 1 раз.\n // Этот эффект будет жить вечно вместе с компонентом и никогда не сбросит свои подписки!\n if (!unsubscribeRef.current) {\n unsubscribeRef.current = engine.effect(() => {\n // Если этот эффект триггерится асинхронно из-за изменения сигнала в ядре:\n if (onStoreChangeRef.current) {\n versionRef.current++; // Инкрементируем версию снапшота для React\n\n // Мягко пушим React на ререндер через микрозадачу\n queueMicrotask(() => {\n if (onStoreChangeRef.current) {\n onStoreChangeRef.current();\n }\n });\n }\n });\n\n // Хак: Вытаскиваем ссылку на сам объект эффекта, который только что зарегился в ядре\n effectObjRef.current = Array.from((engine as any).allEffects).pop();\n }\n\n // 3. ГЛАВНАЯ МАГИЯ: Каждый раз, когда React заходит на рендер (включая StrictMode),\n // мы вручную подменяем activeEffect ядра на НАШ долгоживущий эффект на время выполнения children().\n // Это заставляет ядро автоматически ДОБАВЛЯТЬ новые сигналы в зависимости и никогда не терять старые!\n const prevActiveEffect = (engine as any).activeEffect;\n (engine as any).activeEffect = effectObjRef.current;\n\n let result: React.ReactNode = null;\n try {\n result = children(); // Синхронно выполняем рендер компонента и собираем сигналы\n } finally {\n // Возвращаем глобальный контекст ядра в исходное состояние\n (engine as any).activeEffect = prevActiveEffect;\n }\n\n // Подключаем нативныйuseSyncExternalStore к нашей стабильной версии стейта\n useSyncExternalStore(storeBridge.subscribe, storeBridge.getSnapshot);\n\n return result as unknown as React.ReactElement;\n };\n};\n\ninterface TriggerProps {\n engine: ReactiveEngine;\n Component: React.ComponentType<any>;\n props: any;\n onTrigger: () => void;\n}\n\n/**\n * Вспомогательный компонент, изолирующий выполнение пользовательского компонента\n * от функции safeRun движка во время сбора реактивных зависимостей.\n */\nconst ReactiveRenderTrigger = ({ engine, Component, props, onTrigger }: TriggerProps) => {\n let renderedElement: React.ReactNode = null;\n\n // 1. Создаем эффект движка. Он инициализируется пустым, чтобы не оборачивать\n // вызов компонента в safeRun и не ломать правила хуков React.\n const unsub = engine.effect(() => {\n // Этот коллбек сработает, когда изменятся сигналы, считанные в JSX ниже\n onTrigger();\n });\n\n // Преобразуем инстанс движка в any, чтобы достучаться до внутренних (private/protected) свойств\n const enginePrivate = engine as any;\n\n // 2. Извлекаем объект созданного эффекта из внутренней коллекции движка.\n // Если у вас свойство называется иначе, проверьте имя в коде: this.allEffects.add(effectObj);\n const allEffectsArray = Array.from(enginePrivate.allEffects || []);\n const currentEffectObj = allEffectsArray[allEffectsArray.length - 1];\n\n // Определяем точное имя свойства активного эффекта.\n // Если в коде класса оно написано как activeEffect, то используем его через any.\n const activeEffectKey = 'activeEffect' in enginePrivate ? 'activeEffect' : '_activeEffect';\n\n const prevActive = enginePrivate[activeEffectKey];\n enginePrivate[activeEffectKey] = currentEffectObj;\n\n try {\n // 3. Вызываем компонент напрямую в экосистеме React.\n // Все внутренние хуки (useEffect, useRef) теперь работают штатно.\n if (typeof Component === 'function' && !Component.prototype?.isReactComponent) {\n renderedElement = (Component as Function)(props);\n } else {\n renderedElement = React.createElement(Component, props);\n }\n } finally {\n // 4. Возвращаем движок в исходное состояние и подчищаем временный эффект\n enginePrivate[activeEffectKey] = prevActive;\n unsub();\n }\n\n return renderedElement;\n};\n\n/**\n * Функция высшего порядка (HOC) для автоматического отслеживания сигналов внутри React-компонента.\n * Полный аналог `observer` из MobX.\n *\n * @template P - Объект пропсов оборачиваемого компонента.\n * @param engine - Экземпляр реактивного движка {@link ReactiveEngine}.\n * @returns Функция-декоратор, преобразующая обычный компонент в реактивный.\n *\n * @example\n * ```tsx\n * import { createObserver } from '@pravosleva/reactive-engine';\n * import { engine } from '~/utils/ReactiveEngine'; // Ваш локальный экземпляр движка\n *\n * const observer = createObserver(engine);\n * const counterSignal = engine.signal(0);\n *\n * // Компонент автоматически перерисуется при изменении counterSignal.value\n * export const CounterView = observer(() => {\n * return (\n * <div>\n * <p>Счетчик: {counterSignal.value}</p>\n * <button onClick={() => counterSignal.value++}>+1</button>\n * </div>\n * );\n * });\n * ```\n *\n * @source\n */\nexport const createObserver = (engine: ReactiveEngine) => {\n return <P extends object>(Component: React.ComponentType<P>): React.ComponentType<P> => {\n\n const ObserverComponent = (props: P) => {\n const versionRef = useRef(0);\n const enginePrivate = engine as any;\n\n // Опеределяем внутреннее имя свойства активного эффекта в вашем движке\n const activeEffectKey = 'activeEffect' in enginePrivate ? 'activeEffect' : '_activeEffect';\n\n // Хранилище для инстанса долгоживущего эффекта движка\n const effectObjRef = useRef<any>(null);\n\n // Интеграция с подписками React 18+ через useSyncExternalStore\n const { subscribe, getSnapshot } = useMemo(() => {\n return {\n subscribe: (onStoreChange: () => void) => {\n // Создаем ОДИН долгоживущий эффект на весь жизненный цикл компонента.\n // Он уничтожится только тогда, когда React размонтирует компонент.\n const unsub = engine.effect(() => {\n // При изменении сигналов инкрементируем версию и уведомляем React\n versionRef.current++;\n onStoreChange();\n });\n\n // Нам нужно получить объект этого эффекта.\n // Из вашего кода метода `effect`: эффект добавляется в `this.allEffects.add(effectObj)`.\n const allEffectsArray = Array.from(enginePrivate.allEffects || []);\n effectObjRef.current = allEffectsArray[allEffectsArray.length - 1];\n\n return () => {\n unsub(); // Чистим эффект при размонтировании\n effectObjRef.current = null;\n };\n },\n getSnapshot: () => versionRef.current\n };\n }, []);\n\n // Подписываем компонент. React сам управляет вызовами subscribe/unsubscribe в StrictMode.\n useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n\n // --- ФАЗА СБОРА ЗАВИСИМОСТЕЙ ---\n // Если эффект уже создан (компонент смонтирован), мы временно подставляем его в движок.\n // Если это самый первый рендер (эффекта еще нет в subscribe), мы берем временный \"заглушечный\"\n // объект эффекта, чтобы движок не упал, а сигналы зарегистрировали чтение.\n const fallbackEffect = { cleanups: new Set(), run: () => { } };\n const currentEffect = effectObjRef.current || fallbackEffect;\n\n // Перед рендером подменяем активный эффект\n const prevActive = enginePrivate[activeEffectKey];\n enginePrivate[activeEffectKey] = currentEffect;\n\n let renderedElement: React.ReactNode = null;\n try {\n // Вызываем компонент напрямую. Хуки типа useEffect работают идеально,\n // так как они не обернуты в safeRun движка.\n if (typeof Component === 'function' && !Component.prototype?.isReactComponent) {\n renderedElement = (Component as Function)(props);\n } else {\n renderedElement = React.createElement(Component, props);\n }\n } finally {\n // После рендера возвращаем исходное состояние движка\n enginePrivate[activeEffectKey] = prevActive;\n }\n\n return renderedElement;\n };\n\n ObserverComponent.displayName = `Observer(${Component.displayName || Component.name || 'Component'})`;\n return ObserverComponent as React.ComponentType<P>;\n };\n};\n"],"mappings":"6FAuCA,IAAa,EAA2B,IAC9B,CAAE,cAAmC,CAC3C,IAAM,GAAA,EAAA,EAAA,OAAA,CAAoB,CAAC,EACrB,GAAA,EAAA,EAAA,OAAA,CAA+C,IAAI,EAGnD,GAAA,EAAA,EAAA,OAAA,CAA6C,IAAI,EACjD,GAAA,EAAA,EAAA,OAAA,CAA2B,IAAI,EAG/B,GAAA,EAAA,EAAA,QAAA,MACG,CACL,UAAU,EAA2B,CAEnC,MADA,GAAiB,QAAU,MACd,CACX,EAAiB,QAAU,KACvB,EAAe,UACjB,EAAe,QAAQ,EACvB,EAAe,QAAU,KACzB,EAAa,QAAU,KAE3B,CACF,EACA,aAAc,CACZ,OAAO,EAAW,OACpB,CACF,GACC,CAAC,CAAC,GAGL,EAAA,EAAA,UAAA,SACe,CACP,EAAe,SAAS,EAAe,QAAQ,CACrD,EACC,CAAC,CAAC,EAIA,EAAe,UAClB,EAAe,QAAU,EAAO,WAAa,CAEvC,EAAiB,UACnB,EAAW,UAGX,mBAAqB,CACf,EAAiB,SACnB,EAAiB,QAAQ,CAE7B,CAAC,EAEL,CAAC,EAGD,EAAa,QAAU,MAAM,KAAM,EAAe,UAAU,CAAC,CAAC,IAAI,GAMpE,IAAM,EAAoB,EAAe,aACzC,EAAgB,aAAe,EAAa,QAE5C,IAAI,EAA0B,KAC9B,GAAI,CACF,EAAS,EAAS,CACpB,QAAU,CAER,EAAgB,aAAe,CACjC,CAKA,OAFA,EAAA,EAAA,qBAAA,CAAqB,EAAY,UAAW,EAAY,WAAW,EAE5D,CACT,EAqFW,EAAkB,GACH,GAA8D,CAEtF,IAAM,EAAqB,GAAa,CACtC,IAAM,GAAA,EAAA,EAAA,OAAA,CAAoB,CAAC,EACrB,EAAgB,EAGhB,EAAkB,iBAAkB,EAAgB,eAAiB,gBAGrE,GAAA,EAAA,EAAA,OAAA,CAA2B,IAAI,EAG/B,CAAE,YAAW,gBAAA,EAAA,EAAA,QAAA,MACV,CACL,UAAY,GAA8B,CAGxC,IAAM,EAAQ,EAAO,WAAa,CAEhC,EAAW,UACX,EAAc,CAChB,CAAC,EAIK,EAAkB,MAAM,KAAK,EAAc,YAAc,CAAC,CAAC,EAGjE,MAFA,GAAa,QAAU,EAAgB,EAAgB,OAAS,OAEnD,CACX,EAAM,EACN,EAAa,QAAU,IACzB,CACF,EACA,gBAAmB,EAAW,OAChC,GACC,CAAC,CAAC,GAGL,EAAA,EAAA,qBAAA,CAAqB,EAAW,EAAa,CAAW,EAMxD,IAAM,EAAiB,CAAE,SAAU,IAAI,IAAO,QAAW,CAAE,CAAE,EACvD,EAAgB,EAAa,SAAW,EAGxC,EAAa,EAAc,GACjC,EAAc,GAAmB,EAEjC,IAAI,EAAmC,KACvC,GAAI,CAGF,AAGE,EAHE,OAAO,GAAc,YAAc,CAAC,EAAU,WAAW,iBACxC,EAAuB,CAAK,EAE7B,EAAA,QAAM,cAAc,EAAW,CAAK,CAE1D,QAAU,CAER,EAAc,GAAmB,CACnC,CAEA,OAAO,CACT,EAGA,MADA,GAAkB,YAAc,YAAY,EAAU,aAAe,EAAU,MAAQ,YAAY,GAC5F,CACT"}
@@ -0,0 +1,70 @@
1
+ import { default as React } from 'react';
2
+ import { ReactiveEngine } from '../core';
3
+ /**
4
+ * Свойства для инлайн-компонента {@link Observer}.
5
+ */
6
+ interface ObserverProps {
7
+ /**
8
+ * Функция-рендер, возвращающая JSX-разметку.
9
+ * Сигналы, прочитанные внутри этого коллбека, будут автоматически отслеживаться.
10
+ */
11
+ children: () => React.ReactNode;
12
+ }
13
+ /**
14
+ * Фабрика для создания инлайн-компонента `<Observer>`.
15
+ *
16
+ * @param engine - Экземпляр реактивного движка {@link ReactiveEngine}.
17
+ * @returns Специальный React-компонент для точечной изоляции реактивных обновлений в JSX.
18
+ *
19
+ * @example
20
+ * ```tsx
21
+ * import { createObserverComponent, engine } from '@pravosleva/reactive-engine';
22
+ *
23
+ * const Observer = createObserverComponent(engine);
24
+ * const priceSignal = engine.signal(100);
25
+ *
26
+ * export const MyComponent = () => {
27
+ * return (
28
+ * <div>
29
+ * <h1>Статический тяжелый контент (не перерисовывается)</h1>
30
+ * <Observer>
31
+ * {() => <span>Живая цена: {priceSignal.value}</span>}
32
+ * </Observer>
33
+ * </div>
34
+ * );
35
+ * };
36
+ * ```
37
+ */
38
+ export declare const createObserverComponent: (engine: ReactiveEngine) => ({ children }: ObserverProps) => any;
39
+ /**
40
+ * Функция высшего порядка (HOC) для автоматического отслеживания сигналов внутри React-компонента.
41
+ * Полный аналог `observer` из MobX.
42
+ *
43
+ * @template P - Объект пропсов оборачиваемого компонента.
44
+ * @param engine - Экземпляр реактивного движка {@link ReactiveEngine}.
45
+ * @returns Функция-декоратор, преобразующая обычный компонент в реактивный.
46
+ *
47
+ * @example
48
+ * ```tsx
49
+ * import { createObserver } from '@pravosleva/reactive-engine';
50
+ * import { engine } from '~/utils/ReactiveEngine'; // Ваш локальный экземпляр движка
51
+ *
52
+ * const observer = createObserver(engine);
53
+ * const counterSignal = engine.signal(0);
54
+ *
55
+ * // Компонент автоматически перерисуется при изменении counterSignal.value
56
+ * export const CounterView = observer(() => {
57
+ * return (
58
+ * <div>
59
+ * <p>Счетчик: {counterSignal.value}</p>
60
+ * <button onClick={() => counterSignal.value++}>+1</button>
61
+ * </div>
62
+ * );
63
+ * });
64
+ * ```
65
+ *
66
+ * @source
67
+ */
68
+ export declare const createObserver: (engine: ReactiveEngine) => <P extends object>(Component: React.ComponentType<P>) => React.ComponentType<P>;
69
+ export {};
70
+ //# sourceMappingURL=createObserver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createObserver.d.ts","sourceRoot":"","sources":["../../src/react/createObserver.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA2D,MAAM,OAAO,CAAA;AAC/E,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AAExC;;GAEG;AACH,UAAU,aAAa;IACrB;;;OAGG;IACH,QAAQ,EAAE,MAAM,KAAK,CAAC,SAAS,CAAC;CACjC;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,eAAO,MAAM,uBAAuB,GAAI,QAAQ,cAAc,MACpD,cAAc,aAAa,KAAG,GA2EvC,CAAC;AAuDF;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,eAAO,MAAM,cAAc,GAAI,QAAQ,cAAc,MAC3C,CAAC,SAAS,MAAM,EAAE,WAAW,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,KAAG,KAAK,CAAC,aAAa,CAAC,CAAC,CAwEpF,CAAC"}
@@ -0,0 +1,62 @@
1
+ import e, { useEffect as t, useMemo as n, useRef as r, useSyncExternalStore as i } from "react";
2
+ //#region src/react/createObserver.tsx
3
+ var a = (e) => ({ children: a }) => {
4
+ let o = r(0), s = r(null), c = r(null), l = r(null), u = n(() => ({
5
+ subscribe(e) {
6
+ return s.current = e, () => {
7
+ s.current = null, c.current && (c.current(), c.current = null, l.current = null);
8
+ };
9
+ },
10
+ getSnapshot() {
11
+ return o.current;
12
+ }
13
+ }), []);
14
+ t(() => () => {
15
+ c.current && c.current();
16
+ }, []), c.current || (c.current = e.effect(() => {
17
+ s.current && (o.current++, queueMicrotask(() => {
18
+ s.current && s.current();
19
+ }));
20
+ }), l.current = Array.from(e.allEffects).pop());
21
+ let d = e.activeEffect;
22
+ e.activeEffect = l.current;
23
+ let f = null;
24
+ try {
25
+ f = a();
26
+ } finally {
27
+ e.activeEffect = d;
28
+ }
29
+ return i(u.subscribe, u.getSnapshot), f;
30
+ }, o = (t) => (a) => {
31
+ let o = (o) => {
32
+ let s = r(0), c = t, l = "activeEffect" in c ? "activeEffect" : "_activeEffect", u = r(null), { subscribe: d, getSnapshot: f } = n(() => ({
33
+ subscribe: (e) => {
34
+ let n = t.effect(() => {
35
+ s.current++, e();
36
+ }), r = Array.from(c.allEffects || []);
37
+ return u.current = r[r.length - 1], () => {
38
+ n(), u.current = null;
39
+ };
40
+ },
41
+ getSnapshot: () => s.current
42
+ }), []);
43
+ i(d, f, f);
44
+ let p = {
45
+ cleanups: /* @__PURE__ */ new Set(),
46
+ run: () => {}
47
+ }, m = u.current || p, h = c[l];
48
+ c[l] = m;
49
+ let g = null;
50
+ try {
51
+ g = typeof a == "function" && !a.prototype?.isReactComponent ? a(o) : e.createElement(a, o);
52
+ } finally {
53
+ c[l] = h;
54
+ }
55
+ return g;
56
+ };
57
+ return o.displayName = `Observer(${a.displayName || a.name || "Component"})`, o;
58
+ };
59
+ //#endregion
60
+ export { o as createObserver, a as createObserverComponent };
61
+
62
+ //# sourceMappingURL=createObserver.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createObserver.mjs","names":[],"sources":["../../src/react/createObserver.tsx"],"sourcesContent":["import React, { useSyncExternalStore, useMemo, useEffect, useRef } from 'react'\nimport { ReactiveEngine } from '../core'\n\n/**\n * Свойства для инлайн-компонента {@link Observer}.\n */\ninterface ObserverProps {\n /**\n * Функция-рендер, возвращающая JSX-разметку.\n * Сигналы, прочитанные внутри этого коллбека, будут автоматически отслеживаться.\n */\n children: () => React.ReactNode;\n}\n\n/**\n * Фабрика для создания инлайн-компонента `<Observer>`.\n *\n * @param engine - Экземпляр реактивного движка {@link ReactiveEngine}.\n * @returns Специальный React-компонент для точечной изоляции реактивных обновлений в JSX.\n *\n * @example\n * ```tsx\n * import { createObserverComponent, engine } from '@pravosleva/reactive-engine';\n *\n * const Observer = createObserverComponent(engine);\n * const priceSignal = engine.signal(100);\n *\n * export const MyComponent = () => {\n * return (\n * <div>\n * <h1>Статический тяжелый контент (не перерисовывается)</h1>\n * <Observer>\n * {() => <span>Живая цена: {priceSignal.value}</span>}\n * </Observer>\n * </div>\n * );\n * };\n * ```\n */\nexport const createObserverComponent = (engine: ReactiveEngine) => {\n return ({ children }: ObserverProps): any => {\n const versionRef = useRef(0);\n const onStoreChangeRef = useRef<(() => void) | null>(null);\n\n // Ссылки для удержания инстанса эффекта и функции отписки\n const unsubscribeRef = useRef<(() => void) | null>(null);\n const effectObjRef = useRef<any>(null);\n\n // 1. Создаем стабильный мост подписки для React ОДИН раз за жизнь компонента\n const storeBridge = useMemo(() => {\n return {\n subscribe(onStoreChange: () => void) {\n onStoreChangeRef.current = onStoreChange;\n return () => {\n onStoreChangeRef.current = null;\n if (unsubscribeRef.current) {\n unsubscribeRef.current();\n unsubscribeRef.current = null;\n effectObjRef.current = null;\n }\n };\n },\n getSnapshot() {\n return versionRef.current;\n }\n };\n }, []);\n\n // Очистка при полном размонтировании из DOM\n useEffect(() => {\n return () => {\n if (unsubscribeRef.current) unsubscribeRef.current();\n };\n }, []);\n\n // 2. ЛЕЗИ-ИНИЦИАЛИЗАЦИЯ: Создаем реактивный эффект ядра ровно 1 раз.\n // Этот эффект будет жить вечно вместе с компонентом и никогда не сбросит свои подписки!\n if (!unsubscribeRef.current) {\n unsubscribeRef.current = engine.effect(() => {\n // Если этот эффект триггерится асинхронно из-за изменения сигнала в ядре:\n if (onStoreChangeRef.current) {\n versionRef.current++; // Инкрементируем версию снапшота для React\n\n // Мягко пушим React на ререндер через микрозадачу\n queueMicrotask(() => {\n if (onStoreChangeRef.current) {\n onStoreChangeRef.current();\n }\n });\n }\n });\n\n // Хак: Вытаскиваем ссылку на сам объект эффекта, который только что зарегился в ядре\n effectObjRef.current = Array.from((engine as any).allEffects).pop();\n }\n\n // 3. ГЛАВНАЯ МАГИЯ: Каждый раз, когда React заходит на рендер (включая StrictMode),\n // мы вручную подменяем activeEffect ядра на НАШ долгоживущий эффект на время выполнения children().\n // Это заставляет ядро автоматически ДОБАВЛЯТЬ новые сигналы в зависимости и никогда не терять старые!\n const prevActiveEffect = (engine as any).activeEffect;\n (engine as any).activeEffect = effectObjRef.current;\n\n let result: React.ReactNode = null;\n try {\n result = children(); // Синхронно выполняем рендер компонента и собираем сигналы\n } finally {\n // Возвращаем глобальный контекст ядра в исходное состояние\n (engine as any).activeEffect = prevActiveEffect;\n }\n\n // Подключаем нативныйuseSyncExternalStore к нашей стабильной версии стейта\n useSyncExternalStore(storeBridge.subscribe, storeBridge.getSnapshot);\n\n return result as unknown as React.ReactElement;\n };\n};\n\ninterface TriggerProps {\n engine: ReactiveEngine;\n Component: React.ComponentType<any>;\n props: any;\n onTrigger: () => void;\n}\n\n/**\n * Вспомогательный компонент, изолирующий выполнение пользовательского компонента\n * от функции safeRun движка во время сбора реактивных зависимостей.\n */\nconst ReactiveRenderTrigger = ({ engine, Component, props, onTrigger }: TriggerProps) => {\n let renderedElement: React.ReactNode = null;\n\n // 1. Создаем эффект движка. Он инициализируется пустым, чтобы не оборачивать\n // вызов компонента в safeRun и не ломать правила хуков React.\n const unsub = engine.effect(() => {\n // Этот коллбек сработает, когда изменятся сигналы, считанные в JSX ниже\n onTrigger();\n });\n\n // Преобразуем инстанс движка в any, чтобы достучаться до внутренних (private/protected) свойств\n const enginePrivate = engine as any;\n\n // 2. Извлекаем объект созданного эффекта из внутренней коллекции движка.\n // Если у вас свойство называется иначе, проверьте имя в коде: this.allEffects.add(effectObj);\n const allEffectsArray = Array.from(enginePrivate.allEffects || []);\n const currentEffectObj = allEffectsArray[allEffectsArray.length - 1];\n\n // Определяем точное имя свойства активного эффекта.\n // Если в коде класса оно написано как activeEffect, то используем его через any.\n const activeEffectKey = 'activeEffect' in enginePrivate ? 'activeEffect' : '_activeEffect';\n\n const prevActive = enginePrivate[activeEffectKey];\n enginePrivate[activeEffectKey] = currentEffectObj;\n\n try {\n // 3. Вызываем компонент напрямую в экосистеме React.\n // Все внутренние хуки (useEffect, useRef) теперь работают штатно.\n if (typeof Component === 'function' && !Component.prototype?.isReactComponent) {\n renderedElement = (Component as Function)(props);\n } else {\n renderedElement = React.createElement(Component, props);\n }\n } finally {\n // 4. Возвращаем движок в исходное состояние и подчищаем временный эффект\n enginePrivate[activeEffectKey] = prevActive;\n unsub();\n }\n\n return renderedElement;\n};\n\n/**\n * Функция высшего порядка (HOC) для автоматического отслеживания сигналов внутри React-компонента.\n * Полный аналог `observer` из MobX.\n *\n * @template P - Объект пропсов оборачиваемого компонента.\n * @param engine - Экземпляр реактивного движка {@link ReactiveEngine}.\n * @returns Функция-декоратор, преобразующая обычный компонент в реактивный.\n *\n * @example\n * ```tsx\n * import { createObserver } from '@pravosleva/reactive-engine';\n * import { engine } from '~/utils/ReactiveEngine'; // Ваш локальный экземпляр движка\n *\n * const observer = createObserver(engine);\n * const counterSignal = engine.signal(0);\n *\n * // Компонент автоматически перерисуется при изменении counterSignal.value\n * export const CounterView = observer(() => {\n * return (\n * <div>\n * <p>Счетчик: {counterSignal.value}</p>\n * <button onClick={() => counterSignal.value++}>+1</button>\n * </div>\n * );\n * });\n * ```\n *\n * @source\n */\nexport const createObserver = (engine: ReactiveEngine) => {\n return <P extends object>(Component: React.ComponentType<P>): React.ComponentType<P> => {\n\n const ObserverComponent = (props: P) => {\n const versionRef = useRef(0);\n const enginePrivate = engine as any;\n\n // Опеределяем внутреннее имя свойства активного эффекта в вашем движке\n const activeEffectKey = 'activeEffect' in enginePrivate ? 'activeEffect' : '_activeEffect';\n\n // Хранилище для инстанса долгоживущего эффекта движка\n const effectObjRef = useRef<any>(null);\n\n // Интеграция с подписками React 18+ через useSyncExternalStore\n const { subscribe, getSnapshot } = useMemo(() => {\n return {\n subscribe: (onStoreChange: () => void) => {\n // Создаем ОДИН долгоживущий эффект на весь жизненный цикл компонента.\n // Он уничтожится только тогда, когда React размонтирует компонент.\n const unsub = engine.effect(() => {\n // При изменении сигналов инкрементируем версию и уведомляем React\n versionRef.current++;\n onStoreChange();\n });\n\n // Нам нужно получить объект этого эффекта.\n // Из вашего кода метода `effect`: эффект добавляется в `this.allEffects.add(effectObj)`.\n const allEffectsArray = Array.from(enginePrivate.allEffects || []);\n effectObjRef.current = allEffectsArray[allEffectsArray.length - 1];\n\n return () => {\n unsub(); // Чистим эффект при размонтировании\n effectObjRef.current = null;\n };\n },\n getSnapshot: () => versionRef.current\n };\n }, []);\n\n // Подписываем компонент. React сам управляет вызовами subscribe/unsubscribe в StrictMode.\n useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n\n // --- ФАЗА СБОРА ЗАВИСИМОСТЕЙ ---\n // Если эффект уже создан (компонент смонтирован), мы временно подставляем его в движок.\n // Если это самый первый рендер (эффекта еще нет в subscribe), мы берем временный \"заглушечный\"\n // объект эффекта, чтобы движок не упал, а сигналы зарегистрировали чтение.\n const fallbackEffect = { cleanups: new Set(), run: () => { } };\n const currentEffect = effectObjRef.current || fallbackEffect;\n\n // Перед рендером подменяем активный эффект\n const prevActive = enginePrivate[activeEffectKey];\n enginePrivate[activeEffectKey] = currentEffect;\n\n let renderedElement: React.ReactNode = null;\n try {\n // Вызываем компонент напрямую. Хуки типа useEffect работают идеально,\n // так как они не обернуты в safeRun движка.\n if (typeof Component === 'function' && !Component.prototype?.isReactComponent) {\n renderedElement = (Component as Function)(props);\n } else {\n renderedElement = React.createElement(Component, props);\n }\n } finally {\n // После рендера возвращаем исходное состояние движка\n enginePrivate[activeEffectKey] = prevActive;\n }\n\n return renderedElement;\n };\n\n ObserverComponent.displayName = `Observer(${Component.displayName || Component.name || 'Component'})`;\n return ObserverComponent as React.ComponentType<P>;\n };\n};\n"],"mappings":";;AAuCA,IAAa,KAA2B,OAC9B,EAAE,kBAAmC;CAC3C,IAAM,IAAa,EAAO,CAAC,GACrB,IAAmB,EAA4B,IAAI,GAGnD,IAAiB,EAA4B,IAAI,GACjD,IAAe,EAAY,IAAI,GAG/B,IAAc,SACX;EACL,UAAU,GAA2B;GAEnC,OADA,EAAiB,UAAU,SACd;IAEX,AADA,EAAiB,UAAU,MACvB,EAAe,YACjB,EAAe,QAAQ,GACvB,EAAe,UAAU,MACzB,EAAa,UAAU;GAE3B;EACF;EACA,cAAc;GACZ,OAAO,EAAW;EACpB;CACF,IACC,CAAC,CAAC;CAWL,AARA,cACe;EACX,AAAI,EAAe,WAAS,EAAe,QAAQ;CACrD,GACC,CAAC,CAAC,GAIA,EAAe,YAClB,EAAe,UAAU,EAAO,aAAa;EAE3C,AAAI,EAAiB,YACnB,EAAW,WAGX,qBAAqB;GACnB,AAAI,EAAiB,WACnB,EAAiB,QAAQ;EAE7B,CAAC;CAEL,CAAC,GAGD,EAAa,UAAU,MAAM,KAAM,EAAe,UAAU,CAAC,CAAC,IAAI;CAMpE,IAAM,IAAoB,EAAe;CACzC,EAAgB,eAAe,EAAa;CAE5C,IAAI,IAA0B;CAC9B,IAAI;EACF,IAAS,EAAS;CACpB,UAAU;EAER,EAAgB,eAAe;CACjC;CAKA,OAFA,EAAqB,EAAY,WAAW,EAAY,WAAW,GAE5D;AACT,GAqFW,KAAkB,OACH,MAA8D;CAEtF,IAAM,KAAqB,MAAa;EACtC,IAAM,IAAa,EAAO,CAAC,GACrB,IAAgB,GAGhB,IAAkB,kBAAkB,IAAgB,iBAAiB,iBAGrE,IAAe,EAAY,IAAI,GAG/B,EAAE,cAAW,mBAAgB,SAC1B;GACL,YAAY,MAA8B;IAGxC,IAAM,IAAQ,EAAO,aAAa;KAGhC,AADA,EAAW,WACX,EAAc;IAChB,CAAC,GAIK,IAAkB,MAAM,KAAK,EAAc,cAAc,CAAC,CAAC;IAGjE,OAFA,EAAa,UAAU,EAAgB,EAAgB,SAAS,UAEnD;KAEX,AADA,EAAM,GACN,EAAa,UAAU;IACzB;GACF;GACA,mBAAmB,EAAW;EAChC,IACC,CAAC,CAAC;EAGL,EAAqB,GAAW,GAAa,CAAW;EAMxD,IAAM,IAAiB;GAAE,0BAAU,IAAI,IAAI;GAAG,WAAW,CAAE;EAAE,GACvD,IAAgB,EAAa,WAAW,GAGxC,IAAa,EAAc;EACjC,EAAc,KAAmB;EAEjC,IAAI,IAAmC;EACvC,IAAI;GAGF,AAGE,IAHE,OAAO,KAAc,cAAc,CAAC,EAAU,WAAW,mBACxC,EAAuB,CAAK,IAE7B,EAAM,cAAc,GAAW,CAAK;EAE1D,UAAU;GAER,EAAc,KAAmB;EACnC;EAEA,OAAO;CACT;CAGA,OADA,EAAkB,cAAc,YAAY,EAAU,eAAe,EAAU,QAAQ,YAAY,IAC5F;AACT"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=createObserver.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createObserver.test.d.ts","sourceRoot":"","sources":["../../src/react/createObserver.test.tsx"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=FilteredCatalog.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FilteredCatalog.test.d.ts","sourceRoot":"","sources":["../../../src/react/hooks/FilteredCatalog.test.tsx"],"names":[],"mappings":""}
@@ -0,0 +1 @@
1
+ const e=require("./useReactiveSubscription/useReactiveSubscription.cjs");require("./useReactiveSubscription/index.cjs");const t=require("./useReactiveValue/useReactiveValue.cjs");require("./useReactiveValue/index.cjs");const n=require("./useReactiveValue0/useReactiveValue0.cjs");require("./useReactiveValue0/index.cjs"),exports.useReactiveSubscription=e.useReactiveSubscription,exports.useReactiveValue=t.useReactiveValue,exports.useReactiveValue0=n.useReactiveValue0;
@@ -0,0 +1,4 @@
1
+ export * from './useReactiveSubscription';
2
+ export * from './useReactiveValue';
3
+ export * from './useReactiveValue0';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/react/hooks/index.ts"],"names":[],"mappings":"AAAA,cAAc,2BAA2B,CAAA;AACzC,cAAc,oBAAoB,CAAA;AAClC,cAAc,qBAAqB,CAAA"}
@@ -0,0 +1,7 @@
1
+ import { useReactiveSubscription as e } from "./useReactiveSubscription/useReactiveSubscription.mjs";
2
+ import "./useReactiveSubscription/index.mjs";
3
+ import { useReactiveValue as t } from "./useReactiveValue/useReactiveValue.mjs";
4
+ import "./useReactiveValue/index.mjs";
5
+ import { useReactiveValue0 as n } from "./useReactiveValue0/useReactiveValue0.mjs";
6
+ import "./useReactiveValue0/index.mjs";
7
+ export { e as useReactiveSubscription, t as useReactiveValue, n as useReactiveValue0 };
@@ -0,0 +1,16 @@
1
+ import { CleanupFn } from '../../core';
2
+ /**
3
+ * Общий интерфейс-контракт для любого реактивного объекта библиотеки,
4
+ * у которого есть чтение значения, метод подписки и опциональный метод уничтожения.
5
+ */
6
+ export interface ObservableItem<T> {
7
+ readonly value: T;
8
+ subscribe: (cb: (val: T) => void) => CleanupFn;
9
+ destroy?: () => void;
10
+ }
11
+ /**
12
+ * Тип-союз: на вход хука можно подать либо сам реактивный объект,
13
+ * либо функцию-фабрику, которая его лениво возвращает.
14
+ */
15
+ export type ReactiveInput<T> = ObservableItem<T> | (() => ObservableItem<T>);
16
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/react/hooks/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,SAAS,EAAE,MAAM,YAAY,CAAC;AAE/C;;;GAGG;AACH,MAAM,WAAW,cAAc,CAAC,CAAC;IAC/B,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC;IAClB,SAAS,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,IAAI,KAAK,SAAS,CAAC;IAC/C,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACtB;AAED;;;GAGG;AACH,MAAM,MAAM,aAAa,CAAC,CAAC,IAAI,cAAc,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC"}
@@ -0,0 +1 @@
1
+ const e=require("./useReactiveSubscription.cjs");exports.useReactiveSubscription=e.useReactiveSubscription;
@@ -0,0 +1,2 @@
1
+ export * from './useReactiveSubscription';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/react/hooks/useReactiveSubscription/index.ts"],"names":[],"mappings":"AAAA,cAAc,2BAA2B,CAAA"}
@@ -0,0 +1,2 @@
1
+ import { useReactiveSubscription as e } from "./useReactiveSubscription.mjs";
2
+ export { e as useReactiveSubscription };
@@ -0,0 +1,2 @@
1
+ let e=require("react");var t=(t,n)=>{let r=(0,e.useRef)(n);(0,e.useEffect)(()=>{r.current=n},[n]),(0,e.useEffect)(()=>t.subscribe(e=>{r.current(e)}),[t])};exports.useReactiveSubscription=t;
2
+ //# sourceMappingURL=useReactiveSubscription.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useReactiveSubscription.cjs","names":[],"sources":["../../../../src/react/hooks/useReactiveSubscription/useReactiveSubscription.ts"],"sourcesContent":["import { useEffect, useRef } from 'react'\nimport { Signal, CleanupFn } from '../../../core'\n\n/**\n * Универсальный хук для подписки на изменения Signal, Computed или Resource.\n * @template T Тип данных внутри реактивного контейнера\n * @param {Signal<T> | { subscribe: (cb: (val: T) => void) => CleanupFn }} signal Объект подписки\n * @param {(val: T) => void} callback Функция обратного вызова, принимающая новое значение\n * @source\n */\nexport const useReactiveSubscription = <T>(\n signal: Pick<Signal<T>, 'subscribe'>,\n callback: (val: T) => void\n): void => {\n // Сохраняем актуальный callback в ref, чтобы не перезапускать эффект при его изменении\n const callbackRef = useRef(callback)\n\n useEffect(() => {\n callbackRef.current = callback\n }, [callback])\n\n useEffect(() => {\n // Подписываемся один раз при изменении самого signal\n const unsubscribe: CleanupFn = signal.subscribe((val) => {\n callbackRef.current(val)\n })\n\n // Возвращаем функцию очистки для автоматической отписки при размонтировании\n return unsubscribe\n }, [signal])\n}\n"],"mappings":"uBAUA,IAAa,GACX,EACA,IACS,CAET,IAAM,GAAA,EAAA,EAAA,OAAA,CAAqB,CAAQ,GAEnC,EAAA,EAAA,UAAA,KAAgB,CACd,EAAY,QAAU,CACxB,EAAG,CAAC,CAAQ,CAAC,GAEb,EAAA,EAAA,UAAA,KAEiC,EAAO,UAAW,GAAQ,CACvD,EAAY,QAAQ,CAAG,CACzB,CAGO,EACN,CAAC,CAAM,CAAC,CACb"}
@@ -0,0 +1,10 @@
1
+ import { Signal } from '../../../core';
2
+ /**
3
+ * Универсальный хук для подписки на изменения Signal, Computed или Resource.
4
+ * @template T Тип данных внутри реактивного контейнера
5
+ * @param {Signal<T> | { subscribe: (cb: (val: T) => void) => CleanupFn }} signal Объект подписки
6
+ * @param {(val: T) => void} callback Функция обратного вызова, принимающая новое значение
7
+ * @source
8
+ */
9
+ export declare const useReactiveSubscription: <T>(signal: Pick<Signal<T>, "subscribe">, callback: (val: T) => void) => void;
10
+ //# sourceMappingURL=useReactiveSubscription.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useReactiveSubscription.d.ts","sourceRoot":"","sources":["../../../../src/react/hooks/useReactiveSubscription/useReactiveSubscription.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAa,MAAM,eAAe,CAAA;AAEjD;;;;;;GAMG;AACH,eAAO,MAAM,uBAAuB,GAAI,CAAC,EACvC,QAAQ,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,WAAW,CAAC,EACpC,UAAU,CAAC,GAAG,EAAE,CAAC,KAAK,IAAI,KACzB,IAiBF,CAAA"}
@@ -0,0 +1,14 @@
1
+ import { useEffect as e, useRef as t } from "react";
2
+ //#region src/react/hooks/useReactiveSubscription/useReactiveSubscription.ts
3
+ var n = (n, r) => {
4
+ let i = t(r);
5
+ e(() => {
6
+ i.current = r;
7
+ }, [r]), e(() => n.subscribe((e) => {
8
+ i.current(e);
9
+ }), [n]);
10
+ };
11
+ //#endregion
12
+ export { n as useReactiveSubscription };
13
+
14
+ //# sourceMappingURL=useReactiveSubscription.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useReactiveSubscription.mjs","names":[],"sources":["../../../../src/react/hooks/useReactiveSubscription/useReactiveSubscription.ts"],"sourcesContent":["import { useEffect, useRef } from 'react'\nimport { Signal, CleanupFn } from '../../../core'\n\n/**\n * Универсальный хук для подписки на изменения Signal, Computed или Resource.\n * @template T Тип данных внутри реактивного контейнера\n * @param {Signal<T> | { subscribe: (cb: (val: T) => void) => CleanupFn }} signal Объект подписки\n * @param {(val: T) => void} callback Функция обратного вызова, принимающая новое значение\n * @source\n */\nexport const useReactiveSubscription = <T>(\n signal: Pick<Signal<T>, 'subscribe'>,\n callback: (val: T) => void\n): void => {\n // Сохраняем актуальный callback в ref, чтобы не перезапускать эффект при его изменении\n const callbackRef = useRef(callback)\n\n useEffect(() => {\n callbackRef.current = callback\n }, [callback])\n\n useEffect(() => {\n // Подписываемся один раз при изменении самого signal\n const unsubscribe: CleanupFn = signal.subscribe((val) => {\n callbackRef.current(val)\n })\n\n // Возвращаем функцию очистки для автоматической отписки при размонтировании\n return unsubscribe\n }, [signal])\n}\n"],"mappings":";;AAUA,IAAa,KACX,GACA,MACS;CAET,IAAM,IAAc,EAAO,CAAQ;CAMnC,AAJA,QAAgB;EACd,EAAY,UAAU;CACxB,GAAG,CAAC,CAAQ,CAAC,GAEb,QAEiC,EAAO,WAAW,MAAQ;EACvD,EAAY,QAAQ,CAAG;CACzB,CAGO,GACN,CAAC,CAAM,CAAC;AACb"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=useReactiveSubscription.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useReactiveSubscription.test.d.ts","sourceRoot":"","sources":["../../../../src/react/hooks/useReactiveSubscription/useReactiveSubscription.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1 @@
1
+ const e=require("./useReactiveValue.cjs");exports.useReactiveValue=e.useReactiveValue;
@@ -0,0 +1,2 @@
1
+ export * from './useReactiveValue';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/react/hooks/useReactiveValue/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAA"}
@@ -0,0 +1,2 @@
1
+ import { useReactiveValue as e } from "./useReactiveValue.mjs";
2
+ export { e as useReactiveValue };
@@ -0,0 +1,2 @@
1
+ let e=require("react");var t=t=>{let n=(0,e.useMemo)(()=>typeof t==`function`?t():t,[t]),r=(0,e.useCallback)(e=>n.subscribe(e),[n]),i=(0,e.useCallback)(()=>n.value,[n]);return(0,e.useEffect)(()=>()=>{n&&typeof n.destroy==`function`&&n.destroy()},[n]),(0,e.useSyncExternalStore)(r,i)};exports.useReactiveValue=t;
2
+ //# sourceMappingURL=useReactiveValue.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useReactiveValue.cjs","names":[],"sources":["../../../../src/react/hooks/useReactiveValue/useReactiveValue.ts"],"sourcesContent":["import { useSyncExternalStore, useCallback, useMemo, useEffect } from 'react'\nimport { CleanupFn } from '../../../core'\n\ninterface ObservableItem<T> {\n readonly value: T;\n subscribe: (cb: (val: T) => void) => CleanupFn\n destroy?: () => void\n}\n\ntype ReactiveInput<T> = ObservableItem<T> | (() => ObservableItem<T>)\n\n/**\n * Хук для извлечения значения из Signal/Computed/Resource и авто-ререндера компонента.\n * Поддерживает React 18+ и ленивые фабрики без утечек памяти.\n *\n * @source\n */\nexport const useReactiveValue = <T>(input: ReactiveInput<T>): T => {\n // 1. Всегда получаем чистый объект, даже если передали функцию-фабрику () => engine.computed(...)\n const reactiveItem = useMemo(() => {\n return typeof input === 'function' ? input() : input\n }, [input])\n\n // 2. Стабилизируем функции для useSyncExternalStore\n const subscribe = useCallback(\n (reactCallback: () => void) => {\n return reactiveItem.subscribe(reactCallback)\n },\n [reactiveItem]\n )\n\n const getSnapshot = useCallback(() => {\n return reactiveItem.value\n }, [reactiveItem])\n\n // 3. Автоматически подчищаем динамические вычисления при размонтировании\n useEffect(() => {\n return () => {\n if (reactiveItem && typeof reactiveItem.destroy === 'function') {\n reactiveItem.destroy()\n }\n }\n }, [reactiveItem])\n\n return useSyncExternalStore(subscribe, getSnapshot)\n}\n"],"mappings":"uBAiBA,IAAa,EAAuB,GAA+B,CAEjE,IAAM,GAAA,EAAA,EAAA,QAAA,KACG,OAAO,GAAU,WAAa,EAAM,EAAI,EAC9C,CAAC,CAAK,CAAC,EAGJ,GAAA,EAAA,EAAA,YAAA,CACH,GACQ,EAAa,UAAU,CAAa,EAE7C,CAAC,CAAY,CACf,EAEM,GAAA,EAAA,EAAA,YAAA,KACG,EAAa,MACnB,CAAC,CAAY,CAAC,EAWjB,OARA,EAAA,EAAA,UAAA,SACe,CACP,GAAgB,OAAO,EAAa,SAAY,YAClD,EAAa,QAAQ,CAEzB,EACC,CAAC,CAAY,CAAC,GAEjB,EAAA,EAAA,qBAAA,CAA4B,EAAW,CAAW,CACpD"}
@@ -0,0 +1,16 @@
1
+ import { CleanupFn } from '../../../core';
2
+ interface ObservableItem<T> {
3
+ readonly value: T;
4
+ subscribe: (cb: (val: T) => void) => CleanupFn;
5
+ destroy?: () => void;
6
+ }
7
+ type ReactiveInput<T> = ObservableItem<T> | (() => ObservableItem<T>);
8
+ /**
9
+ * Хук для извлечения значения из Signal/Computed/Resource и авто-ререндера компонента.
10
+ * Поддерживает React 18+ и ленивые фабрики без утечек памяти.
11
+ *
12
+ * @source
13
+ */
14
+ export declare const useReactiveValue: <T>(input: ReactiveInput<T>) => T;
15
+ export {};
16
+ //# sourceMappingURL=useReactiveValue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useReactiveValue.d.ts","sourceRoot":"","sources":["../../../../src/react/hooks/useReactiveValue/useReactiveValue.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAA;AAEzC,UAAU,cAAc,CAAC,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC;IAClB,SAAS,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,IAAI,KAAK,SAAS,CAAA;IAC9C,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;CACrB;AAED,KAAK,aAAa,CAAC,CAAC,IAAI,cAAc,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,cAAc,CAAC,CAAC,CAAC,CAAC,CAAA;AAErE;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,GAAI,CAAC,EAAE,OAAO,aAAa,CAAC,CAAC,CAAC,KAAG,CA4B7D,CAAA"}
@@ -0,0 +1,12 @@
1
+ import { useCallback as e, useEffect as t, useMemo as n, useSyncExternalStore as r } from "react";
2
+ //#region src/react/hooks/useReactiveValue/useReactiveValue.ts
3
+ var i = (i) => {
4
+ let a = n(() => typeof i == "function" ? i() : i, [i]), o = e((e) => a.subscribe(e), [a]), s = e(() => a.value, [a]);
5
+ return t(() => () => {
6
+ a && typeof a.destroy == "function" && a.destroy();
7
+ }, [a]), r(o, s);
8
+ };
9
+ //#endregion
10
+ export { i as useReactiveValue };
11
+
12
+ //# sourceMappingURL=useReactiveValue.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useReactiveValue.mjs","names":[],"sources":["../../../../src/react/hooks/useReactiveValue/useReactiveValue.ts"],"sourcesContent":["import { useSyncExternalStore, useCallback, useMemo, useEffect } from 'react'\nimport { CleanupFn } from '../../../core'\n\ninterface ObservableItem<T> {\n readonly value: T;\n subscribe: (cb: (val: T) => void) => CleanupFn\n destroy?: () => void\n}\n\ntype ReactiveInput<T> = ObservableItem<T> | (() => ObservableItem<T>)\n\n/**\n * Хук для извлечения значения из Signal/Computed/Resource и авто-ререндера компонента.\n * Поддерживает React 18+ и ленивые фабрики без утечек памяти.\n *\n * @source\n */\nexport const useReactiveValue = <T>(input: ReactiveInput<T>): T => {\n // 1. Всегда получаем чистый объект, даже если передали функцию-фабрику () => engine.computed(...)\n const reactiveItem = useMemo(() => {\n return typeof input === 'function' ? input() : input\n }, [input])\n\n // 2. Стабилизируем функции для useSyncExternalStore\n const subscribe = useCallback(\n (reactCallback: () => void) => {\n return reactiveItem.subscribe(reactCallback)\n },\n [reactiveItem]\n )\n\n const getSnapshot = useCallback(() => {\n return reactiveItem.value\n }, [reactiveItem])\n\n // 3. Автоматически подчищаем динамические вычисления при размонтировании\n useEffect(() => {\n return () => {\n if (reactiveItem && typeof reactiveItem.destroy === 'function') {\n reactiveItem.destroy()\n }\n }\n }, [reactiveItem])\n\n return useSyncExternalStore(subscribe, getSnapshot)\n}\n"],"mappings":";;AAiBA,IAAa,KAAuB,MAA+B;CAEjE,IAAM,IAAe,QACZ,OAAO,KAAU,aAAa,EAAM,IAAI,GAC9C,CAAC,CAAK,CAAC,GAGJ,IAAY,GACf,MACQ,EAAa,UAAU,CAAa,GAE7C,CAAC,CAAY,CACf,GAEM,IAAc,QACX,EAAa,OACnB,CAAC,CAAY,CAAC;CAWjB,OARA,cACe;EACX,AAAI,KAAgB,OAAO,EAAa,WAAY,cAClD,EAAa,QAAQ;CAEzB,GACC,CAAC,CAAY,CAAC,GAEV,EAAqB,GAAW,CAAW;AACpD"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=useReactiveValue.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useReactiveValue.test.d.ts","sourceRoot":"","sources":["../../../../src/react/hooks/useReactiveValue/useReactiveValue.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1 @@
1
+ const e=require("./useReactiveValue0.cjs");exports.useReactiveValue0=e.useReactiveValue0;
@@ -0,0 +1,2 @@
1
+ export * from './useReactiveValue0';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/react/hooks/useReactiveValue0/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAA"}
@@ -0,0 +1,2 @@
1
+ import { useReactiveValue0 as e } from "./useReactiveValue0.mjs";
2
+ export { e as useReactiveValue0 };
@@ -0,0 +1,2 @@
1
+ let e=require("react");var t=t=>{let n=(0,e.useMemo)(()=>typeof t==`function`?t():t,[t]),[r,i]=(0,e.useState)(n.value),a=(0,e.useRef)(i);return(0,e.useEffect)(()=>{a.current=i},[i]),(0,e.useEffect)(()=>{a.current(n.value);let e=n.subscribe(e=>{a.current(e)});return()=>{e(),n&&typeof n.destroy==`function`&&n.destroy()}},[n]),r};exports.useReactiveValue0=t;
2
+ //# sourceMappingURL=useReactiveValue0.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useReactiveValue0.cjs","names":[],"sources":["../../../../src/react/hooks/useReactiveValue0/useReactiveValue0.ts"],"sourcesContent":["import { useState, useEffect, useRef, useMemo } from 'react'\nimport { CleanupFn } from '../../../core'\n\ninterface ObservableItem<T> {\n readonly value: T\n subscribe: (cb: (val: T) => void) => CleanupFn\n destroy?: () => void\n}\n\ntype ReactiveInput<T> = ObservableItem<T> | (() => ObservableItem<T>)\n\n/**\n * Fallback хук для извлечения значения из сигналов. Поддерживает React 16.8+.\n *\n * @source\n */\nexport const useReactiveValue0 = <T>(input: ReactiveInput<T>): T => {\n const reactiveItem = useMemo(() => {\n return typeof input === 'function' ? input() : input\n }, [input])\n\n const [state, setState] = useState<T>(reactiveItem.value)\n const setStateRef = useRef(setState)\n\n useEffect(() => {\n setStateRef.current = setState\n }, [setState])\n\n useEffect(() => {\n setStateRef.current(reactiveItem.value)\n\n const unsubscribe = reactiveItem.subscribe((newValue) => {\n setStateRef.current(newValue)\n })\n\n return () => {\n unsubscribe();\n if (reactiveItem && typeof reactiveItem.destroy === 'function') {\n reactiveItem.destroy()\n }\n }\n }, [reactiveItem])\n\n return state\n}\n"],"mappings":"uBAgBA,IAAa,EAAwB,GAA+B,CAClE,IAAM,GAAA,EAAA,EAAA,QAAA,KACG,OAAO,GAAU,WAAa,EAAM,EAAI,EAC9C,CAAC,CAAK,CAAC,EAEJ,CAAC,EAAO,IAAA,EAAA,EAAA,SAAA,CAAwB,EAAa,KAAK,EAClD,GAAA,EAAA,EAAA,OAAA,CAAqB,CAAQ,EAqBnC,OAnBA,EAAA,EAAA,UAAA,KAAgB,CACd,EAAY,QAAU,CACxB,EAAG,CAAC,CAAQ,CAAC,GAEb,EAAA,EAAA,UAAA,KAAgB,CACd,EAAY,QAAQ,EAAa,KAAK,EAEtC,IAAM,EAAc,EAAa,UAAW,GAAa,CACvD,EAAY,QAAQ,CAAQ,CAC9B,CAAC,EAED,UAAa,CACX,EAAY,EACR,GAAgB,OAAO,EAAa,SAAY,YAClD,EAAa,QAAQ,CAEzB,CACF,EAAG,CAAC,CAAY,CAAC,EAEV,CACT"}
@@ -0,0 +1,15 @@
1
+ import { CleanupFn } from '../../../core';
2
+ interface ObservableItem<T> {
3
+ readonly value: T;
4
+ subscribe: (cb: (val: T) => void) => CleanupFn;
5
+ destroy?: () => void;
6
+ }
7
+ type ReactiveInput<T> = ObservableItem<T> | (() => ObservableItem<T>);
8
+ /**
9
+ * Fallback хук для извлечения значения из сигналов. Поддерживает React 16.8+.
10
+ *
11
+ * @source
12
+ */
13
+ export declare const useReactiveValue0: <T>(input: ReactiveInput<T>) => T;
14
+ export {};
15
+ //# sourceMappingURL=useReactiveValue0.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useReactiveValue0.d.ts","sourceRoot":"","sources":["../../../../src/react/hooks/useReactiveValue0/useReactiveValue0.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAA;AAEzC,UAAU,cAAc,CAAC,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAA;IACjB,SAAS,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,IAAI,KAAK,SAAS,CAAA;IAC9C,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;CACrB;AAED,KAAK,aAAa,CAAC,CAAC,IAAI,cAAc,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,cAAc,CAAC,CAAC,CAAC,CAAC,CAAA;AAErE;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,GAAI,CAAC,EAAE,OAAO,aAAa,CAAC,CAAC,CAAC,KAAG,CA4B9D,CAAA"}
@@ -0,0 +1,20 @@
1
+ import { useEffect as e, useMemo as t, useRef as n, useState as r } from "react";
2
+ //#region src/react/hooks/useReactiveValue0/useReactiveValue0.ts
3
+ var i = (i) => {
4
+ let a = t(() => typeof i == "function" ? i() : i, [i]), [o, s] = r(a.value), c = n(s);
5
+ return e(() => {
6
+ c.current = s;
7
+ }, [s]), e(() => {
8
+ c.current(a.value);
9
+ let e = a.subscribe((e) => {
10
+ c.current(e);
11
+ });
12
+ return () => {
13
+ e(), a && typeof a.destroy == "function" && a.destroy();
14
+ };
15
+ }, [a]), o;
16
+ };
17
+ //#endregion
18
+ export { i as useReactiveValue0 };
19
+
20
+ //# sourceMappingURL=useReactiveValue0.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useReactiveValue0.mjs","names":[],"sources":["../../../../src/react/hooks/useReactiveValue0/useReactiveValue0.ts"],"sourcesContent":["import { useState, useEffect, useRef, useMemo } from 'react'\nimport { CleanupFn } from '../../../core'\n\ninterface ObservableItem<T> {\n readonly value: T\n subscribe: (cb: (val: T) => void) => CleanupFn\n destroy?: () => void\n}\n\ntype ReactiveInput<T> = ObservableItem<T> | (() => ObservableItem<T>)\n\n/**\n * Fallback хук для извлечения значения из сигналов. Поддерживает React 16.8+.\n *\n * @source\n */\nexport const useReactiveValue0 = <T>(input: ReactiveInput<T>): T => {\n const reactiveItem = useMemo(() => {\n return typeof input === 'function' ? input() : input\n }, [input])\n\n const [state, setState] = useState<T>(reactiveItem.value)\n const setStateRef = useRef(setState)\n\n useEffect(() => {\n setStateRef.current = setState\n }, [setState])\n\n useEffect(() => {\n setStateRef.current(reactiveItem.value)\n\n const unsubscribe = reactiveItem.subscribe((newValue) => {\n setStateRef.current(newValue)\n })\n\n return () => {\n unsubscribe();\n if (reactiveItem && typeof reactiveItem.destroy === 'function') {\n reactiveItem.destroy()\n }\n }\n }, [reactiveItem])\n\n return state\n}\n"],"mappings":";;AAgBA,IAAa,KAAwB,MAA+B;CAClE,IAAM,IAAe,QACZ,OAAO,KAAU,aAAa,EAAM,IAAI,GAC9C,CAAC,CAAK,CAAC,GAEJ,CAAC,GAAO,KAAY,EAAY,EAAa,KAAK,GAClD,IAAc,EAAO,CAAQ;CAqBnC,OAnBA,QAAgB;EACd,EAAY,UAAU;CACxB,GAAG,CAAC,CAAQ,CAAC,GAEb,QAAgB;EACd,EAAY,QAAQ,EAAa,KAAK;EAEtC,IAAM,IAAc,EAAa,WAAW,MAAa;GACvD,EAAY,QAAQ,CAAQ;EAC9B,CAAC;EAED,aAAa;GAEX,AADA,EAAY,GACR,KAAgB,OAAO,EAAa,WAAY,cAClD,EAAa,QAAQ;EAEzB;CACF,GAAG,CAAC,CAAY,CAAC,GAEV;AACT"}
@@ -0,0 +1 @@
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./createObserver.cjs"),t=require("./ReactiveEngine4React.cjs"),n=require("./hooks/useReactiveSubscription/useReactiveSubscription.cjs"),r=require("./hooks/useReactiveValue/useReactiveValue.cjs"),i=require("./hooks/useReactiveValue0/useReactiveValue0.cjs");require("./hooks/index.cjs"),exports.ReactiveEngine=t.ReactiveEngine,exports.createObserver=e.createObserver,exports.createObserverComponent=e.createObserverComponent,exports.useReactiveSubscription=n.useReactiveSubscription,exports.useReactiveValue=r.useReactiveValue,exports.useReactiveValue0=i.useReactiveValue0;
@@ -0,0 +1,4 @@
1
+ export * from './createObserver';
2
+ export * from './ReactiveEngine4React';
3
+ export * from './hooks';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAA;AAChC,cAAc,wBAAwB,CAAA;AACtC,cAAc,SAAS,CAAA"}
@@ -0,0 +1,7 @@
1
+ import { createObserver as e, createObserverComponent as t } from "./createObserver.mjs";
2
+ import { ReactiveEngine as n } from "./ReactiveEngine4React.mjs";
3
+ import { useReactiveSubscription as r } from "./hooks/useReactiveSubscription/useReactiveSubscription.mjs";
4
+ import { useReactiveValue as i } from "./hooks/useReactiveValue/useReactiveValue.mjs";
5
+ import { useReactiveValue0 as a } from "./hooks/useReactiveValue0/useReactiveValue0.mjs";
6
+ import "./hooks/index.mjs";
7
+ export { n as ReactiveEngine, e as createObserver, t as createObserverComponent, r as useReactiveSubscription, i as useReactiveValue, a as useReactiveValue0 };
@@ -0,0 +1,2 @@
1
+ export * from './hooks/types';
2
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/react/types.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAA"}
@@ -0,0 +1,2 @@
1
+ var e=({tested:e,expectedKey:t,valueType:n})=>{let r=[];for(let i=0,a=e.length;i<a;i++){let a=e[i],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};exports.getExtractedValues=e;
2
+ //# sourceMappingURL=getExtractedValues.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getExtractedValues.cjs","names":[],"sources":["../../src/utils/getExtractedValues.ts"],"sourcesContent":["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 for (let i = 0, max = tested.length; i < max; i++) {\n const t = tested[i];\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 // NOTE: \"Ленивый\" квантификатор -> \".*?\" будет искать минимальное количество символов до следующего экранированного \"]\"\n regex = new RegExp(`\\\\[${expectedKey}=(?<value>.*?)\\\\]`, 'g');\n break;\n }\n\n // eslint-disable-next-line no-restricted-syntax\n for (const n of t.matchAll(regex)) {\n if (n?.groups) { results.push(n.groups.value); }\n }\n }\n return results;\n};\n"],"mappings":"AAAA,IAAa,GAAsB,CACjC,SAAQ,cAAa,eAKP,CACd,IAAM,EAAoB,CAAC,EAC3B,IAAK,IAAI,EAAI,EAAG,EAAM,EAAO,OAAQ,EAAI,EAAK,IAAK,CACjD,IAAM,EAAI,EAAO,GACb,EACJ,OAAQ,EAAR,CACE,IAAK,SACH,EAAY,OAAO,MAAM,EAAY,oBAAqB,GAAG,EAC7D,MAEF,QAEE,EAAY,OAAO,MAAM,EAAY,mBAAoB,GAAG,EAC5D,KACJ,CAGA,IAAK,IAAM,KAAK,EAAE,SAAS,CAAK,EAC1B,GAAG,QAAU,EAAQ,KAAK,EAAE,OAAO,KAAK,CAEhD,CACA,OAAO,CACT"}
@@ -0,0 +1,6 @@
1
+ export declare const getExtractedValues: ({ tested, expectedKey, valueType }: {
2
+ tested: string[];
3
+ expectedKey: string;
4
+ valueType: "number" | "string";
5
+ }) => string[];
6
+ //# sourceMappingURL=getExtractedValues.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getExtractedValues.d.ts","sourceRoot":"","sources":["../../src/utils/getExtractedValues.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,kBAAkB,GAAI,oCAEhC;IACD,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,QAAQ,GAAG,QAAQ,CAAC;CAChC,KAAG,MAAM,EAsBT,CAAC"}
@@ -0,0 +1,21 @@
1
+ //#region src/utils/getExtractedValues.ts
2
+ var e = ({ tested: e, expectedKey: t, valueType: n }) => {
3
+ let r = [];
4
+ for (let i = 0, a = e.length; i < a; i++) {
5
+ let a = e[i], o;
6
+ switch (n) {
7
+ case "number":
8
+ o = RegExp(`\\[${t}=(?<value>\\d+)\\]`, "g");
9
+ break;
10
+ default:
11
+ o = RegExp(`\\[${t}=(?<value>.*?)\\]`, "g");
12
+ break;
13
+ }
14
+ for (let e of a.matchAll(o)) e?.groups && r.push(e.groups.value);
15
+ }
16
+ return r;
17
+ };
18
+ //#endregion
19
+ export { e as getExtractedValues };
20
+
21
+ //# sourceMappingURL=getExtractedValues.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getExtractedValues.mjs","names":[],"sources":["../../src/utils/getExtractedValues.ts"],"sourcesContent":["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 for (let i = 0, max = tested.length; i < max; i++) {\n const t = tested[i];\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 // NOTE: \"Ленивый\" квантификатор -> \".*?\" будет искать минимальное количество символов до следующего экранированного \"]\"\n regex = new RegExp(`\\\\[${expectedKey}=(?<value>.*?)\\\\]`, 'g');\n break;\n }\n\n // eslint-disable-next-line no-restricted-syntax\n for (const n of t.matchAll(regex)) {\n if (n?.groups) { results.push(n.groups.value); }\n }\n }\n return results;\n};\n"],"mappings":";AAAA,IAAa,KAAsB,EACjC,WAAQ,gBAAa,mBAKP;CACd,IAAM,IAAoB,CAAC;CAC3B,KAAK,IAAI,IAAI,GAAG,IAAM,EAAO,QAAQ,IAAI,GAAK,KAAK;EACjD,IAAM,IAAI,EAAO,IACb;EACJ,QAAQ,GAAR;GACE,KAAK;IACH,IAAY,OAAO,MAAM,EAAY,qBAAqB,GAAG;IAC7D;GAEF;IAEE,IAAY,OAAO,MAAM,EAAY,oBAAoB,GAAG;IAC5D;EACJ;EAGA,KAAK,IAAM,KAAK,EAAE,SAAS,CAAK,GAC9B,AAAI,GAAG,UAAU,EAAQ,KAAK,EAAE,OAAO,KAAK;CAEhD;CACA,OAAO;AACT"}
@@ -0,0 +1,2 @@
1
+ export * from './getExtractedValues';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,sBAAsB,CAAA"}