@pravosleva/reactive-engine 1.6.0 → 1.7.0-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 (52) hide show
  1. package/dist/angular/ReactiveEngine4Angular.cjs +1 -1
  2. package/dist/angular/ReactiveEngine4Angular.cjs.map +1 -1
  3. package/dist/angular/ReactiveEngine4Angular.d.ts +16 -10
  4. package/dist/angular/ReactiveEngine4Angular.d.ts.map +1 -1
  5. package/dist/angular/ReactiveEngine4Angular.mjs +29 -5
  6. package/dist/angular/ReactiveEngine4Angular.mjs.map +1 -1
  7. package/dist/core/core.d.ts.map +1 -1
  8. package/dist/core.cjs +1 -1
  9. package/dist/core.cjs.map +1 -1
  10. package/dist/core.mjs +42 -25
  11. package/dist/core.mjs.map +1 -1
  12. package/dist/decorators/withStaleWhileRevalidate/withStaleWhileRevalidate.cjs +1 -1
  13. package/dist/decorators/withStaleWhileRevalidate/withStaleWhileRevalidate.cjs.map +1 -1
  14. package/dist/decorators/withStaleWhileRevalidate/withStaleWhileRevalidate.d.ts +7 -25
  15. package/dist/decorators/withStaleWhileRevalidate/withStaleWhileRevalidate.d.ts.map +1 -1
  16. package/dist/decorators/withStaleWhileRevalidate/withStaleWhileRevalidate.mjs +23 -8
  17. package/dist/decorators/withStaleWhileRevalidate/withStaleWhileRevalidate.mjs.map +1 -1
  18. package/dist/react/ReactiveEngine4React.cjs +1 -5
  19. package/dist/react/ReactiveEngine4React.cjs.map +1 -1
  20. package/dist/react/ReactiveEngine4React.d.ts +12 -18
  21. package/dist/react/ReactiveEngine4React.d.ts.map +1 -1
  22. package/dist/react/ReactiveEngine4React.mjs +27 -5
  23. package/dist/react/ReactiveEngine4React.mjs.map +1 -1
  24. package/dist/react/hooks/types.d.ts +4 -0
  25. package/dist/react/hooks/types.d.ts.map +1 -1
  26. package/dist/react/hooks/useReactiveSubscription/useReactiveSubscription.cjs +1 -1
  27. package/dist/react/hooks/useReactiveSubscription/useReactiveSubscription.cjs.map +1 -1
  28. package/dist/react/hooks/useReactiveSubscription/useReactiveSubscription.d.ts +4 -10
  29. package/dist/react/hooks/useReactiveSubscription/useReactiveSubscription.d.ts.map +1 -1
  30. package/dist/react/hooks/useReactiveSubscription/useReactiveSubscription.mjs +20 -11
  31. package/dist/react/hooks/useReactiveSubscription/useReactiveSubscription.mjs.map +1 -1
  32. package/dist/react/hooks/useReactiveValue/useReactiveValue.cjs +1 -1
  33. package/dist/react/hooks/useReactiveValue/useReactiveValue.cjs.map +1 -1
  34. package/dist/react/hooks/useReactiveValue/useReactiveValue.d.ts +10 -41
  35. package/dist/react/hooks/useReactiveValue/useReactiveValue.d.ts.map +1 -1
  36. package/dist/react/hooks/useReactiveValue/useReactiveValue.mjs +19 -10
  37. package/dist/react/hooks/useReactiveValue/useReactiveValue.mjs.map +1 -1
  38. package/dist/reactive-engine.umd.js +2 -2
  39. package/dist/reactive-engine.umd.js.map +1 -1
  40. package/dist/vue/ReactiveEngine4Vue.cjs +1 -1
  41. package/dist/vue/ReactiveEngine4Vue.cjs.map +1 -1
  42. package/dist/vue/ReactiveEngine4Vue.d.ts +21 -6
  43. package/dist/vue/ReactiveEngine4Vue.d.ts.map +1 -1
  44. package/dist/vue/ReactiveEngine4Vue.mjs +31 -8
  45. package/dist/vue/ReactiveEngine4Vue.mjs.map +1 -1
  46. package/dist/vue/composables/useReactiveValue.cjs +1 -1
  47. package/dist/vue/composables/useReactiveValue.cjs.map +1 -1
  48. package/dist/vue/composables/useReactiveValue.d.ts +4 -45
  49. package/dist/vue/composables/useReactiveValue.d.ts.map +1 -1
  50. package/dist/vue/composables/useReactiveValue.mjs +10 -5
  51. package/dist/vue/composables/useReactiveValue.mjs.map +1 -1
  52. package/package.json +1 -1
@@ -1,2 +1,2 @@
1
- const e=require("../core.cjs");let t=require("@angular/core");var n=class extends e.ReactiveEngine{frameworkPrefix=`angular`;use(e,n){let r=(0,t.signal)(e.value),i=e.subscribe(()=>{let t=e.value;r.set(t)}),a=()=>{(0,t.inject)(t.DestroyRef).onDestroy(()=>{i()})};return n?.injector?(0,t.runInInjectionContext)(n.injector,a):a(),r.asReadonly()}};exports.ReactiveEngine4Angular=n;
1
+ const e=require("../core.cjs");let t=require("@angular/core");var n=class extends e.ReactiveEngine{frameworkPrefix=`angular`;reactive(e,t){Reflect.has(e,`__subscribe`)||Object.defineProperty(e,"__subscribe",{get:()=>e=>this.effect(()=>{try{JSON.stringify(n)}catch{Object.values(n)}e()},`angular-proxy-internal-subscription`),configurable:!0,enumerable:!1});let n=super.reactive(e,t);return n}use(e,n){if(typeof e!=`object`||!e)return(0,t.signal)(e).asReadonly();let r=`subscribe`in e&&typeof e.subscribe==`function`,i=()=>{},a;if(r){let n=e;a=(0,t.signal)(n.value),i=n.subscribe(()=>{let e=n.value;a.set(e)})}else a=(0,t.signal)(e),`__subscribe`in e&&typeof e.__subscribe==`function`&&(i=e.__subscribe(()=>{a.set({...e})}));let o=()=>{(0,t.inject)(t.DestroyRef).onDestroy(()=>{i()})};return n?.injector?(0,t.runInInjectionContext)(n.injector,o):o(),a.asReadonly()}};exports.ReactiveEngine4Angular=n;
2
2
  //# sourceMappingURL=ReactiveEngine4Angular.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"ReactiveEngine4Angular.cjs","names":[],"sources":["../../src/angular/ReactiveEngine4Angular.ts"],"sourcesContent":["import { signal, inject, DestroyRef, Injector, runInInjectionContext, type Signal } from '@angular/core'\nimport { ReactiveEngine as OriginalReactiveEngine, type CleanupFn } from '../core/core'\n\n// Описываем интерфейс опций для Angular-адаптера\nexport interface AngularUseOptions {\n /**\n * Кастомный инжектор Angular.\n * Позволяет использовать .use() вне конструктора (например, в асинхронных функциях),\n * если передать текущий Injector вручную.\n */\n injector?: Injector;\n}\n\nexport class ReactiveEngine4Angular extends OriginalReactiveEngine {\n protected override frameworkPrefix = 'angular'\n\n /**\n * Использование реактивного значения в Angular компоненте или сервисе.\n * Возвращает стандартный Angular Signal.\n */\n public use<T>(\n item: { value: T; subscribe: (cb: (v: T) => void) => CleanupFn },\n options?: AngularUseOptions\n ): Signal<T> {\n // 1. Создаем локальный Angular Signal со стартовым значением\n const angularSignal = signal<T>(item.value)\n\n // 2. Подписываемся на изменения сигнала вашего ядра\n const unsubscribe = item.subscribe(() => {\n // Принудительно дергаем геттер .value, чтобы запустить Pull-вычисление ядра\n // и получить свежие данные, попутно запустив профайлер логгера computed!\n const freshValue = item.value\n angularSignal.set(freshValue)\n })\n\n // 3. Логика автоматической отписки через DestroyRef\n const registerCleanup = () => {\n const destroyRef = inject(DestroyRef)\n destroyRef.onDestroy(() => {\n unsubscribe()\n })\n }\n\n // 4. Если пользователь явно передал кастомный инжектор — выполняем регистрацию внутри его контекста\n if (options?.injector) {\n runInInjectionContext(options.injector, registerCleanup)\n } else {\n // Иначе штатно выполняем в текущем контексте (вызовет ошибку NG0203, если контекст не валиден)\n registerCleanup()\n }\n\n return angularSignal.asReadonly()\n }\n}\n"],"mappings":"8DAaA,IAAa,EAAb,cAA4C,EAAA,cAAuB,CACjE,gBAAqC,UAMrC,IACE,EACA,EACW,CAEX,IAAM,GAAA,EAAA,EAAA,OAAA,CAA0B,EAAK,KAAK,EAGpC,EAAc,EAAK,cAAgB,CAGvC,IAAM,EAAa,EAAK,MACxB,EAAc,IAAI,CAAU,CAC9B,CAAC,EAGK,MAAwB,EAE5B,EAAA,EAAA,OAAA,CAD0B,EAAA,UAC1B,CAAA,CAAW,cAAgB,CACzB,EAAY,CACd,CAAC,CACH,EAUA,OAPI,GAAS,UACX,EAAA,EAAA,sBAAA,CAAsB,EAAQ,SAAU,CAAe,EAGvD,EAAgB,EAGX,EAAc,WAAW,CAClC,CACF"}
1
+ {"version":3,"file":"ReactiveEngine4Angular.cjs","names":[],"sources":["../../src/angular/ReactiveEngine4Angular.ts"],"sourcesContent":["import { signal, inject, DestroyRef, Injector, runInInjectionContext, type Signal } from '@angular/core'\nimport { ReactiveEngine as OriginalReactiveEngine, type CleanupFn } from '../core/core'\n\nexport interface AngularUseOptions {\n injector?: Injector;\n}\n\n// Описываем строгий контракт для примитивов реактивного ядра (Signals / Computed)\nexport interface ISignalLike<V> {\n readonly value: V;\n subscribe: (cb: (v: V) => void) => CleanupFn;\n}\n\nexport class ReactiveEngine4Angular extends OriginalReactiveEngine {\n protected override frameworkPrefix = 'angular'\n\n /**\n * Переопределяем метод создания реактивных объектов для Angular-версии движка.\n * Безопасно внедряет скрытое свойство __subscribe в оригинальный граф без double-proxying.\n */\n public override reactive<T extends object>(target: T, name?: string): T {\n if (!Reflect.has(target, '__subscribe')) {\n Object.defineProperty(target, '__subscribe', {\n get: () => {\n return (cb: () => void) => {\n return this.effect(() => {\n try {\n JSON.stringify(originalProxy) // Глубокий прогрев геттеров ядра\n } catch (e) {\n Object.values(originalProxy as Record<string, unknown>)\n }\n cb() // Оповещаем Angular Signal о мутации внутренностей Proxy\n }, 'angular-proxy-internal-subscription')\n }\n },\n configurable: true,\n enumerable: false\n })\n }\n\n const originalProxy = super.reactive(target, name)\n return originalProxy\n }\n\n /**\n * Использование реактивного значения в Angular компоненте или сервисе.\n * Полиморфно поддерживает как атомарные Сигналы/Computed, так и глубокие реактивные Proxy-объекты.\n *\n * @template T\n * @param {T} item - Реактивный объект ядра (сигнал или прокси)\n * @param {AngularUseOptions} [options] - Опции инжектора Angular\n * @returns {T extends ISignalLike<infer V> ? Signal<V> : Signal<T>} - Стандартный Angular Signal (Readonly)\n */\n public use<T>(\n item: T,\n options?: AngularUseOptions\n ): T extends ISignalLike<infer V> ? Signal<V> : Signal<T> {\n if (item === null || item === undefined || typeof item !== 'object') {\n const angularSignal = signal(item)\n return angularSignal.asReadonly() as any\n }\n\n // Проверяем, реализует ли переданный объект интерфейс Сигнала (наличие метода subscribe)\n const isSignal = 'subscribe' in item && typeof (item as Record<string, unknown>).subscribe === 'function'\n\n let unsubscribe: CleanupFn = () => {}\n let angularSignal: any\n\n // ------------------------------------------------====\n // СЦЕНАРИЙ А: Передан примитивный Сигнал или Computed\n // ------------------------------------------------====\n if (isSignal) {\n const signalItem = (item as unknown) as ISignalLike<unknown>\n angularSignal = signal(signalItem.value)\n\n unsubscribe = signalItem.subscribe(() => {\n const freshValue = signalItem.value\n angularSignal.set(freshValue)\n })\n }\n // ------------------------------------------------====\n // СЦЕНАРИЙ Б: Передан Proxy-объект из метода reactive()\n // ------------------------------------------------====\n else {\n angularSignal = signal(item)\n\n if ('__subscribe' in item && typeof (item as Record<string, unknown>).__subscribe === 'function') {\n unsubscribe = ((item as Record<string, unknown>).__subscribe as (cb: () => void) => CleanupFn)(() => {\n // При мутации свойств или массивов Proxy делаем принудительный .set()\n // для создания новой внутренней зависимости внутри экосистемы Angular Signals\n angularSignal.set({ ...item })\n })\n }\n }\n\n // Автоматическая очистка через DestroyRef фреймворка\n const registerCleanup = () => {\n const destroyRef = inject(DestroyRef)\n destroyRef.onDestroy(() => {\n unsubscribe()\n })\n }\n\n if (options?.injector) {\n runInInjectionContext(options.injector, registerCleanup)\n } else {\n registerCleanup()\n }\n\n return angularSignal.asReadonly()\n }\n}\n"],"mappings":"8DAaA,IAAa,EAAb,cAA4C,EAAA,cAAuB,CACjE,gBAAqC,UAMrC,SAA2C,EAAW,EAAkB,CACjE,QAAQ,IAAI,EAAQ,aAAa,GACpC,OAAO,eAAe,EAAQ,cAAe,CAC3C,QACU,GACC,KAAK,WAAa,CACvB,GAAI,CACF,KAAK,UAAU,CAAa,CAC9B,MAAY,CACV,OAAO,OAAO,CAAwC,CACxD,CACA,EAAG,CACL,EAAG,qCAAqC,EAG5C,aAAc,GACd,WAAY,EACd,CAAC,EAGH,IAAM,EAAgB,MAAM,SAAS,EAAQ,CAAI,EACjD,OAAO,CACT,CAWA,IACE,EACA,EACwD,CACxD,GAA2C,OAAO,GAAS,WAAvD,EAEF,OAAA,EAAA,EAAA,OAAA,CAD6B,CACtB,CAAA,CAAc,WAAW,EAIlC,IAAM,EAAW,cAAe,GAAQ,OAAQ,EAAiC,WAAc,WAE3F,MAA+B,CAAC,EAChC,EAKJ,GAAI,EAAU,CACZ,IAAM,EAAc,EACpB,GAAA,EAAA,EAAA,OAAA,CAAuB,EAAW,KAAK,EAEvC,EAAc,EAAW,cAAgB,CACvC,IAAM,EAAa,EAAW,MAC9B,EAAc,IAAI,CAAU,CAC9B,CAAC,CACH,KAKE,IAAA,EAAA,EAAA,OAAA,CAAuB,CAAI,EAEvB,gBAAiB,GAAQ,OAAQ,EAAiC,aAAgB,aACpF,EAAgB,EAAiC,gBAAoD,CAGnG,EAAc,IAAI,CAAE,GAAG,CAAK,CAAC,CAC/B,CAAC,GAKL,IAAM,MAAwB,EAE5B,EAAA,EAAA,OAAA,CAD0B,EAAA,UAC1B,CAAA,CAAW,cAAgB,CACzB,EAAY,CACd,CAAC,CACH,EAQA,OANI,GAAS,UACX,EAAA,EAAA,sBAAA,CAAsB,EAAQ,SAAU,CAAe,EAEvD,EAAgB,EAGX,EAAc,WAAW,CAClC,CACF"}
@@ -1,22 +1,28 @@
1
1
  import { Injector, Signal } from '@angular/core';
2
2
  import { ReactiveEngine as OriginalReactiveEngine, CleanupFn } from '../core/core';
3
3
  export interface AngularUseOptions {
4
- /**
5
- * Кастомный инжектор Angular.
6
- * Позволяет использовать .use() вне конструктора (например, в асинхронных функциях),
7
- * если передать текущий Injector вручную.
8
- */
9
4
  injector?: Injector;
10
5
  }
6
+ export interface ISignalLike<V> {
7
+ readonly value: V;
8
+ subscribe: (cb: (v: V) => void) => CleanupFn;
9
+ }
11
10
  export declare class ReactiveEngine4Angular extends OriginalReactiveEngine {
12
11
  protected frameworkPrefix: string;
12
+ /**
13
+ * Переопределяем метод создания реактивных объектов для Angular-версии движка.
14
+ * Безопасно внедряет скрытое свойство __subscribe в оригинальный граф без double-proxying.
15
+ */
16
+ reactive<T extends object>(target: T, name?: string): T;
13
17
  /**
14
18
  * Использование реактивного значения в Angular компоненте или сервисе.
15
- * Возвращает стандартный Angular Signal.
19
+ * Полиморфно поддерживает как атомарные Сигналы/Computed, так и глубокие реактивные Proxy-объекты.
20
+ *
21
+ * @template T
22
+ * @param {T} item - Реактивный объект ядра (сигнал или прокси)
23
+ * @param {AngularUseOptions} [options] - Опции инжектора Angular
24
+ * @returns {T extends ISignalLike<infer V> ? Signal<V> : Signal<T>} - Стандартный Angular Signal (Readonly)
16
25
  */
17
- use<T>(item: {
18
- value: T;
19
- subscribe: (cb: (v: T) => void) => CleanupFn;
20
- }, options?: AngularUseOptions): Signal<T>;
26
+ use<T>(item: T, options?: AngularUseOptions): T extends ISignalLike<infer V> ? Signal<V> : Signal<T>;
21
27
  }
22
28
  //# sourceMappingURL=ReactiveEngine4Angular.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ReactiveEngine4Angular.d.ts","sourceRoot":"","sources":["../../src/angular/ReactiveEngine4Angular.ts"],"names":[],"mappings":"AAAA,OAAO,EAA8B,QAAQ,EAAyB,KAAK,MAAM,EAAE,MAAM,eAAe,CAAA;AACxG,OAAO,EAAE,cAAc,IAAI,sBAAsB,EAAE,KAAK,SAAS,EAAE,MAAM,cAAc,CAAA;AAGvF,MAAM,WAAW,iBAAiB;IAChC;;;;OAIG;IACH,QAAQ,CAAC,EAAE,QAAQ,CAAC;CACrB;AAED,qBAAa,sBAAuB,SAAQ,sBAAsB;IAChE,UAAmB,eAAe,SAAY;IAE9C;;;OAGG;IACI,GAAG,CAAC,CAAC,EACV,IAAI,EAAE;QAAE,KAAK,EAAE,CAAC,CAAC;QAAC,SAAS,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,IAAI,KAAK,SAAS,CAAA;KAAE,EAChE,OAAO,CAAC,EAAE,iBAAiB,GAC1B,MAAM,CAAC,CAAC,CAAC;CA8Bb"}
1
+ {"version":3,"file":"ReactiveEngine4Angular.d.ts","sourceRoot":"","sources":["../../src/angular/ReactiveEngine4Angular.ts"],"names":[],"mappings":"AAAA,OAAO,EAA8B,QAAQ,EAAyB,KAAK,MAAM,EAAE,MAAM,eAAe,CAAA;AACxG,OAAO,EAAE,cAAc,IAAI,sBAAsB,EAAE,KAAK,SAAS,EAAE,MAAM,cAAc,CAAA;AAEvF,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,EAAE,QAAQ,CAAC;CACrB;AAGD,MAAM,WAAW,WAAW,CAAC,CAAC;IAC5B,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC;IAClB,SAAS,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,IAAI,KAAK,SAAS,CAAC;CAC9C;AAED,qBAAa,sBAAuB,SAAQ,sBAAsB;IAChE,UAAmB,eAAe,SAAY;IAE9C;;;OAGG;IACa,QAAQ,CAAC,CAAC,SAAS,MAAM,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,CAAC;IAwBvE;;;;;;;;OAQG;IACI,GAAG,CAAC,CAAC,EACV,IAAI,EAAE,CAAC,EACP,OAAO,CAAC,EAAE,iBAAiB,GAC1B,CAAC,SAAS,WAAW,CAAC,MAAM,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC;CAuD1D"}
@@ -3,16 +3,40 @@ import { DestroyRef as t, inject as n, runInInjectionContext as r, signal as i }
3
3
  //#region src/angular/ReactiveEngine4Angular.ts
4
4
  var a = class extends e {
5
5
  frameworkPrefix = "angular";
6
+ reactive(e, t) {
7
+ Reflect.has(e, "__subscribe") || Object.defineProperty(e, "__subscribe", {
8
+ get: () => (e) => this.effect(() => {
9
+ try {
10
+ JSON.stringify(n);
11
+ } catch {
12
+ Object.values(n);
13
+ }
14
+ e();
15
+ }, "angular-proxy-internal-subscription"),
16
+ configurable: !0,
17
+ enumerable: !1
18
+ });
19
+ let n = super.reactive(e, t);
20
+ return n;
21
+ }
6
22
  use(e, a) {
7
- let o = i(e.value), s = e.subscribe(() => {
8
- let t = e.value;
9
- o.set(t);
10
- }), c = () => {
23
+ if (typeof e != "object" || !e) return i(e).asReadonly();
24
+ let o = "subscribe" in e && typeof e.subscribe == "function", s = () => {}, c;
25
+ if (o) {
26
+ let t = e;
27
+ c = i(t.value), s = t.subscribe(() => {
28
+ let e = t.value;
29
+ c.set(e);
30
+ });
31
+ } else c = i(e), "__subscribe" in e && typeof e.__subscribe == "function" && (s = e.__subscribe(() => {
32
+ c.set({ ...e });
33
+ }));
34
+ let l = () => {
11
35
  n(t).onDestroy(() => {
12
36
  s();
13
37
  });
14
38
  };
15
- return a?.injector ? r(a.injector, c) : c(), o.asReadonly();
39
+ return a?.injector ? r(a.injector, l) : l(), c.asReadonly();
16
40
  }
17
41
  };
18
42
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"ReactiveEngine4Angular.mjs","names":[],"sources":["../../src/angular/ReactiveEngine4Angular.ts"],"sourcesContent":["import { signal, inject, DestroyRef, Injector, runInInjectionContext, type Signal } from '@angular/core'\nimport { ReactiveEngine as OriginalReactiveEngine, type CleanupFn } from '../core/core'\n\n// Описываем интерфейс опций для Angular-адаптера\nexport interface AngularUseOptions {\n /**\n * Кастомный инжектор Angular.\n * Позволяет использовать .use() вне конструктора (например, в асинхронных функциях),\n * если передать текущий Injector вручную.\n */\n injector?: Injector;\n}\n\nexport class ReactiveEngine4Angular extends OriginalReactiveEngine {\n protected override frameworkPrefix = 'angular'\n\n /**\n * Использование реактивного значения в Angular компоненте или сервисе.\n * Возвращает стандартный Angular Signal.\n */\n public use<T>(\n item: { value: T; subscribe: (cb: (v: T) => void) => CleanupFn },\n options?: AngularUseOptions\n ): Signal<T> {\n // 1. Создаем локальный Angular Signal со стартовым значением\n const angularSignal = signal<T>(item.value)\n\n // 2. Подписываемся на изменения сигнала вашего ядра\n const unsubscribe = item.subscribe(() => {\n // Принудительно дергаем геттер .value, чтобы запустить Pull-вычисление ядра\n // и получить свежие данные, попутно запустив профайлер логгера computed!\n const freshValue = item.value\n angularSignal.set(freshValue)\n })\n\n // 3. Логика автоматической отписки через DestroyRef\n const registerCleanup = () => {\n const destroyRef = inject(DestroyRef)\n destroyRef.onDestroy(() => {\n unsubscribe()\n })\n }\n\n // 4. Если пользователь явно передал кастомный инжектор — выполняем регистрацию внутри его контекста\n if (options?.injector) {\n runInInjectionContext(options.injector, registerCleanup)\n } else {\n // Иначе штатно выполняем в текущем контексте (вызовет ошибку NG0203, если контекст не валиден)\n registerCleanup()\n }\n\n return angularSignal.asReadonly()\n }\n}\n"],"mappings":";;;AAaA,IAAa,IAAb,cAA4C,EAAuB;CACjE,kBAAqC;CAMrC,IACE,GACA,GACW;EAEX,IAAM,IAAgB,EAAU,EAAK,KAAK,GAGpC,IAAc,EAAK,gBAAgB;GAGvC,IAAM,IAAa,EAAK;GACxB,EAAc,IAAI,CAAU;EAC9B,CAAC,GAGK,UAAwB;GAE5B,EAD0B,CAC1B,CAAA,CAAW,gBAAgB;IACzB,EAAY;GACd,CAAC;EACH;EAUA,OAPI,GAAS,WACX,EAAsB,EAAQ,UAAU,CAAe,IAGvD,EAAgB,GAGX,EAAc,WAAW;CAClC;AACF"}
1
+ {"version":3,"file":"ReactiveEngine4Angular.mjs","names":[],"sources":["../../src/angular/ReactiveEngine4Angular.ts"],"sourcesContent":["import { signal, inject, DestroyRef, Injector, runInInjectionContext, type Signal } from '@angular/core'\nimport { ReactiveEngine as OriginalReactiveEngine, type CleanupFn } from '../core/core'\n\nexport interface AngularUseOptions {\n injector?: Injector;\n}\n\n// Описываем строгий контракт для примитивов реактивного ядра (Signals / Computed)\nexport interface ISignalLike<V> {\n readonly value: V;\n subscribe: (cb: (v: V) => void) => CleanupFn;\n}\n\nexport class ReactiveEngine4Angular extends OriginalReactiveEngine {\n protected override frameworkPrefix = 'angular'\n\n /**\n * Переопределяем метод создания реактивных объектов для Angular-версии движка.\n * Безопасно внедряет скрытое свойство __subscribe в оригинальный граф без double-proxying.\n */\n public override reactive<T extends object>(target: T, name?: string): T {\n if (!Reflect.has(target, '__subscribe')) {\n Object.defineProperty(target, '__subscribe', {\n get: () => {\n return (cb: () => void) => {\n return this.effect(() => {\n try {\n JSON.stringify(originalProxy) // Глубокий прогрев геттеров ядра\n } catch (e) {\n Object.values(originalProxy as Record<string, unknown>)\n }\n cb() // Оповещаем Angular Signal о мутации внутренностей Proxy\n }, 'angular-proxy-internal-subscription')\n }\n },\n configurable: true,\n enumerable: false\n })\n }\n\n const originalProxy = super.reactive(target, name)\n return originalProxy\n }\n\n /**\n * Использование реактивного значения в Angular компоненте или сервисе.\n * Полиморфно поддерживает как атомарные Сигналы/Computed, так и глубокие реактивные Proxy-объекты.\n *\n * @template T\n * @param {T} item - Реактивный объект ядра (сигнал или прокси)\n * @param {AngularUseOptions} [options] - Опции инжектора Angular\n * @returns {T extends ISignalLike<infer V> ? Signal<V> : Signal<T>} - Стандартный Angular Signal (Readonly)\n */\n public use<T>(\n item: T,\n options?: AngularUseOptions\n ): T extends ISignalLike<infer V> ? Signal<V> : Signal<T> {\n if (item === null || item === undefined || typeof item !== 'object') {\n const angularSignal = signal(item)\n return angularSignal.asReadonly() as any\n }\n\n // Проверяем, реализует ли переданный объект интерфейс Сигнала (наличие метода subscribe)\n const isSignal = 'subscribe' in item && typeof (item as Record<string, unknown>).subscribe === 'function'\n\n let unsubscribe: CleanupFn = () => {}\n let angularSignal: any\n\n // ------------------------------------------------====\n // СЦЕНАРИЙ А: Передан примитивный Сигнал или Computed\n // ------------------------------------------------====\n if (isSignal) {\n const signalItem = (item as unknown) as ISignalLike<unknown>\n angularSignal = signal(signalItem.value)\n\n unsubscribe = signalItem.subscribe(() => {\n const freshValue = signalItem.value\n angularSignal.set(freshValue)\n })\n }\n // ------------------------------------------------====\n // СЦЕНАРИЙ Б: Передан Proxy-объект из метода reactive()\n // ------------------------------------------------====\n else {\n angularSignal = signal(item)\n\n if ('__subscribe' in item && typeof (item as Record<string, unknown>).__subscribe === 'function') {\n unsubscribe = ((item as Record<string, unknown>).__subscribe as (cb: () => void) => CleanupFn)(() => {\n // При мутации свойств или массивов Proxy делаем принудительный .set()\n // для создания новой внутренней зависимости внутри экосистемы Angular Signals\n angularSignal.set({ ...item })\n })\n }\n }\n\n // Автоматическая очистка через DestroyRef фреймворка\n const registerCleanup = () => {\n const destroyRef = inject(DestroyRef)\n destroyRef.onDestroy(() => {\n unsubscribe()\n })\n }\n\n if (options?.injector) {\n runInInjectionContext(options.injector, registerCleanup)\n } else {\n registerCleanup()\n }\n\n return angularSignal.asReadonly()\n }\n}\n"],"mappings":";;;AAaA,IAAa,IAAb,cAA4C,EAAuB;CACjE,kBAAqC;CAMrC,SAA2C,GAAW,GAAkB;EACtE,AAAK,QAAQ,IAAI,GAAQ,aAAa,KACpC,OAAO,eAAe,GAAQ,eAAe;GAC3C,YACU,MACC,KAAK,aAAa;IACvB,IAAI;KACF,KAAK,UAAU,CAAa;IAC9B,QAAY;KACV,OAAO,OAAO,CAAwC;IACxD;IACA,EAAG;GACL,GAAG,qCAAqC;GAG5C,cAAc;GACd,YAAY;EACd,CAAC;EAGH,IAAM,IAAgB,MAAM,SAAS,GAAQ,CAAI;EACjD,OAAO;CACT;CAWA,IACE,GACA,GACwD;EACxD,IAA2C,OAAO,KAAS,aAAvD,GAEF,OADsB,EAAO,CACtB,CAAA,CAAc,WAAW;EAIlC,IAAM,IAAW,eAAe,KAAQ,OAAQ,EAAiC,aAAc,YAE3F,UAA+B,CAAC,GAChC;EAKJ,IAAI,GAAU;GACZ,IAAM,IAAc;GAGpB,AAFA,IAAgB,EAAO,EAAW,KAAK,GAEvC,IAAc,EAAW,gBAAgB;IACvC,IAAM,IAAa,EAAW;IAC9B,EAAc,IAAI,CAAU;GAC9B,CAAC;EACH,OAOE,AAFA,IAAgB,EAAO,CAAI,GAEvB,iBAAiB,KAAQ,OAAQ,EAAiC,eAAgB,eACpF,IAAgB,EAAiC,kBAAoD;GAGnG,EAAc,IAAI,EAAE,GAAG,EAAK,CAAC;EAC/B,CAAC;EAKL,IAAM,UAAwB;GAE5B,EAD0B,CAC1B,CAAA,CAAW,gBAAgB;IACzB,EAAY;GACd,CAAC;EACH;EAQA,OANI,GAAS,WACX,EAAsB,EAAQ,UAAU,CAAe,IAEvD,EAAgB,GAGX,EAAc,WAAW;CAClC;AACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../../src/core/core.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../../src/core/core.ts"],"names":[],"mappings":"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"}
package/dist/core.cjs CHANGED
@@ -1,2 +1,2 @@
1
- const e=require("./utils/getExtractedValues.cjs");var t=class{frameworkPrefix=`core`;activeEffect=null;isBatching=!1;pendingEffects=new Set;services=new Map;factories=new Map;proxyCache=new WeakMap;allEffects=new Set;loggerOptions;pendingLogQueue=[];lastTransactionDuration=null;signalMutationCounts=new Map;lastComputedDurations=new Map;effectExecutionCounts=new Map;batchTickCounts=0;constructor(e){this.loggerOptions=e?.logger}log(t,n,r){if(!this.loggerOptions?.isEnabled)return;if(!this.loggerOptions?.isCoreOptimizationDebugEnabled){let t=e.getExtractedValues({expectedKey:`CORE_INTERNAL_SIGNAL`,tested:[n],valueType:`number`})?.[0]===`1`,r=e.getExtractedValues({expectedKey:`CORE_INTERNAL_EFFECT`,tested:[n],valueType:`number`})?.[0]===`1`;if(t||r)return}if(this.loggerOptions.filter&&!(this.loggerOptions.filter instanceof RegExp?this.loggerOptions.filter:new RegExp(this.loggerOptions.filter.replace(/^\/|\/$/g,``))).test(n))return;let i={signal:`background: #007acc; color: #fff; padding: 2px 6px; border-radius: 4px; font-weight: bold;`,computed:`background: #42b883; color: #fff; padding: 2px 6px; border-radius: 4px; font-weight: bold;`,effect:`background: #e01e5a; color: #fff; padding: 2px 6px; border-radius: 4px; font-weight: bold;`,batch:`background: #7952b3; color: #fff; padding: 2px 6px; border-radius: 4px; font-weight: bold;`,resource:`background: #d97706; color: #fff; padding: 2px 6px; border-radius: 4px; font-weight: bold;`,reactive:`background: #007acc; color: #fff; padding: 2px 6px; border-radius: 4px; font-weight: bold;`},a=``,o=`color: #aaa; font-weight: normal;`;switch(t){case`signal`:{let s=e.getExtractedValues({tested:[n],expectedKey:`CORE_INTERNAL_SIGNAL`,valueType:`number`})?.[0]===`1`,c=n,l=(this.signalMutationCounts.get(c)||0)+1;this.signalMutationCounts.set(c,l);let u=r,d=u.subscribers&&u.subscribers.length>0?u.subscribers.every(t=>t?e.getExtractedValues({tested:[t],expectedKey:`IS_OPTIMIZED`,valueType:`number`})?.[0]===`1`:!1):!1,f=l>50,p=s?`COMPUTED_INTERNAL`:`SIGNAL`;a=` 🔄 Изменений ${s?`кэша`:`сигнала`}: ${l}${f?` ⚠️ (high noise — обнаружен дребезг/спам значений!)`:``}`,f&&(o=`color: orange; font-weight: bold;`,d||(r.__performance_advice__={issue:`Сигнал [${c}] обновляется слишком часто (${l} раз за такт). Это приводит к избыточным ререндерам UI.`,solution:`Оберните чтение этого сигнала в декоратор сжатия потока данных 'withThrottleComputed'`,example:`public throttled = withThrottleComputed(this.engine, () => this.yourSignalName.value, { limit: 300 });`})),console.groupCollapsed(`%c${p}%c [${c}]%c${a}`,s?`background: #42b883; color: #fff; padding: 2px 6px; border-radius: 4px; font-weight: bold;`:i[t],`color: #aaa; font-weight: bold;`,o),console.log(`Данные (Payload):`,r),this.loggerOptions.traceTime&&typeof performance<`u`&&console.log(`Тайминг рантайма:`,`${performance.now().toFixed(2)} ms`),console.groupEnd();return}case`computed`:{let e=r;if(e&&`to`in e){let t=e.to;a=` 🧮 Значение: ${typeof t==`object`&&t?`{...}`:String(t)}`}else if(e&&`duration`in e){let t=parseFloat(e.duration);if(!isNaN(t)){let r=this.lastComputedDurations.get(n);if(r!==void 0&&r>0){let n=(t-r)/r*100;n>5?(a=` 🔴 Замедление: +${n.toFixed(1)}% (${e.duration})`,o=`color: #e01e5a; font-weight: bold;`):n<-5?(a=` 🟢 Ускорение: ${n.toFixed(1)}% (${e.duration})`,o=`color: #42b883; font-weight: bold;`):(a=` 🟢 Стабильно (${e.duration})`,o=`color: #42b883; font-weight: bold;`)}else a=` ⚪ Первый расчет (${e.duration})`;this.lastComputedDurations.set(n,t)}}break}case`effect`:{let e=(this.effectExecutionCounts.get(n)||0)+1;this.effectExecutionCounts.set(n,e);let t=e>30,i=r;a=` 🟢 Стабильно${i&&`duration`in i?` (${i.duration})`:``} | 🚀 Вызовов: ${e}${t?` ⚠️ (heavy re-renders)`:``}`,o=`color: #42b883; font-weight: bold;`,t&&(o=`color: #ff4a4a; font-weight: bold;`);break}case`batch`:this.batchTickCounts+=1,a=` 📦 Номер транзакции: #${this.batchTickCounts}`;break;case`resource`:{let e=r;if(e.loading)a=` ⏳ ЗАГРУЗКА (fetching...)`,o=`color: #d97706; font-weight: bold;`;else if(e.error)a=` 🔴 ОШИБКА: ${e.error.message||`Unknown Error`}`,o=`color: #ff4a4a; font-weight: bold;`;else{let t=e.data;a=` 🟢 УСПЕХ (data: ${typeof t==`object`&&t?`{...}`:String(t)})`,o=`color: #42b883; font-weight: bold;`}break}default:break}console.groupCollapsed(`%c${t.toUpperCase()}%c [${n}]%c${a}`,i[t],`color: #aaa; font-weight: bold;`,o),console.log(`Данные (Payload):`,r),this.loggerOptions.traceTime&&typeof performance<`u`&&console.log(`Тайминг рантайма:`,`${performance.now().toFixed(2)} ms`),console.groupEnd()}onSignalChange;provide(e,t){typeof t==`function`&&!t.prototype?this.factories.set(e,t):this.services.set(e,t)}inject(e){if(!e)throw Error(`[DI Error]: Вы пытаетесь внедрить пустой токен (undefined/null). Проверьте импорты.`);let t=e;if(this.services.has(t))return this.services.get(t);try{let n=this.factories.get(t);if(n){let e=n(this);return this.services.set(t,e),e}if(typeof e==`function`&&e.prototype){let n=new e(this);return this.services.set(t,n),n}throw Error(`Service not found: ${String(e)}`)}catch(t){throw Error(`[DI Error]: Не удалось создать сервис ${String(e)}. Ошибка: ${t?.message||`No e?.message`}`)}}queueLog(e,t,n){this.loggerOptions?.isEnabled&&this.pendingLogQueue.push({type:e,name:t,detail:n})}flushLogs(){if(!this.loggerOptions?.isEnabled||this.pendingLogQueue.length===0)return;let e=typeof performance<`u`?performance.now():0,t=this.pendingLogQueue;if(this.loggerOptions.filter)try{let e;if(this.loggerOptions.filter instanceof RegExp)e=this.loggerOptions.filter;else{let t=this.loggerOptions.filter.replace(/^\/|\/$/g,``);e=new RegExp(t)}t=t.filter(t=>e.test(t.name))}catch(e){console.warn(`[Logger Error]: Некорректный паттерн фильтрации логов`,e)}if(t.length===0){this.pendingLogQueue=[];return}let n=``,r=``,i=`color: #aaa; font-weight: normal;`;if(this.loggerOptions.traceTime&&e){let t=performance.now()-e;if(n=` | Duration: ${t.toFixed(3)} ms`,this.lastTransactionDuration!==null&&this.lastTransactionDuration>0){let e=(t-this.lastTransactionDuration)/this.lastTransactionDuration*100;e>.1?(r=` 🔴 +${e.toFixed(1)}%`,i=`color: #e01e5a; font-weight: bold;`):e<-.1?(r=` 🟢 ${e.toFixed(1)}%`,i=`color: #42b883; font-weight: bold;`):(r=` 🟢 stable`,i=`color: #42b883; font-weight: bold;`)}else r=` ⚪ first`;this.lastTransactionDuration=t}console.groupCollapsed(`%cREACTIVE TRANSACTION${this.loggerOptions.instanceName?` ${this.loggerOptions.instanceName}`:``}%c Microtask Tick (Size: ${t.length}${n})%c${r}`,`background: #7952b3; color: #fff; padding: 2px 6px; border-radius: 4px; font-weight: bold;`,`color: #aaa; font-weight: normal;`,i),t.forEach(e=>{this.log(e.type,e.name,e.detail)}),this.loggerOptions.traceTime&&typeof performance<`u`&&console.log(`%c[Execution Timestamp]: ${performance.now().toFixed(2)} ms`,`color: #7952b3; font-weight: bold;`),console.groupEnd(),this.pendingLogQueue=[]}signal(e,t){let n=this,r=e,i=new Set,a=typeof t==`string`?{name:t}:t||{},o=a.name||`unnamed_signal`;return{get value(){if(n.activeEffect){let e=n.activeEffect;i.has(e)||(i.add(e),e.cleanups.add(()=>{i.delete(e)}))}return r},set value(e){if(r===e)return;if(a.validate){let t=a.validate(e);if(t===!1||typeof t==`string`){let n=typeof t==`string`?t:`[Validation Error]: Некорректное значение для сигнала "${o}"`;console.error(`%c${n}`,`color: orange; font-weight: bold;`,{received:e,current:r});return}}let t=r;r=e,n.onSignalChange?.(o,e,t);let s=Array.from(i).map(e=>e.label||`unnamed_effect`);n.queueLog?.(`signal`,o,{from:t,to:e,subscribersCount:i.size,subscribers:s}),i.forEach(e=>n.pendingEffects.add(e)),n.isBatching||(n.isBatching=!0,queueMicrotask(()=>{for(let e of n.pendingEffects)n.pendingEffects.delete(e),e.run();n.isBatching=!1,n.flushLogs?.()}))},subscribe(e){return n.effect(()=>{e(this.value)},`${n.frameworkPrefix}:use:${o}`)}}}effect(e,t){let n=this,r=!0,i={label:t,cleanups:new Set,run(){let t=Array.from(this.cleanups);this.cleanups.clear(),t.forEach(e=>e());let i=n.activeEffect;n.activeEffect=this;let a=performance.now();n.safeRun(this,()=>{let t=e();typeof t==`function`&&this.cleanups.add(t)}),n.activeEffect=i;let o=performance.now()-a;if(!r&&n.loggerOptions?.isEnabled){let e=n.loggerOptions.filter;(!e||e instanceof RegExp&&this.label&&e.test(this.label))&&typeof n.queueLog==`function`&&n.queueLog(`effect`,this.label||`unnamed-efect-0`,{name:this.label||`unnamed-efect-0`,type:`effect`,detail:{status:`stable`,duration:`${o.toFixed(3)}ms`,timestamp:a}})}r=!1}};return this.allEffects.add(i),i.run(),()=>{i.cleanups.forEach(e=>e()),n.pendingEffects.delete(i),n.allEffects.delete(i)}}computedCache=new Map;cleanupRegistry=new FinalizationRegistry(e=>{e()});computed(e,t){if(this.computedCache.has(e)){let t=this.computedCache.get(e)?.deref();if(t)return t}let n=this,r=t||`unnamed_computed`,i=this.signal(void 0,`[CORE_INTERNAL_SIGNAL=1]:${r}`),a=!0,o,s=this.effect(()=>{o=e(),a=!1;let t=typeof performance<`u`&&performance.now()?`0.010ms`:`N/A`;typeof n.queueLog==`function`&&n.queueLog(`computed`,r,{value:o,duration:t}),i.value=o},`[CORE_INTERNAL_EFFECT=1]:${r}`),c=Array.from(this.allEffects)[this.allEffects.size-1],l=()=>{s(),c&&n.allEffects.delete(c),n.computedCache.delete(e)},u={get value(){return a&&(o=e(),a=!1,i.value=o),i.value},subscribe:e=>i.subscribe(e),destroy(){s(),l(),n.computedCache.delete(e)}};return this.cleanupRegistry.register(u,l),this.computedCache.set(e,new WeakRef(u)),u}reactive(e,t=`reactive`){if(this.proxyCache.has(e))return this.proxyCache.get(e);let n=this,r=new Map,i=new Proxy(e,{get(e,i,a){if(n.activeEffect){let e=n.activeEffect;r.has(i)||r.set(i,new Set);let t=r.get(i);t.has(e)||(t.add(e),e.cleanups.add(()=>{t.delete(e)}))}let o=Reflect.get(e,i,a);return typeof o==`object`&&o?n.reactive(o,`${t}.${String(i)}`):o},set(e,i,a,o){let s=Reflect.get(e,i,o);if(s===a)return!0;if(s!==a){Reflect.set(e,i,a,o),n.onSignalChange?.(`${t}.${String(i)}`,a,s);let c=r.get(i);(c?Array.from(c):[]).forEach(e=>{n.isBatching?n.pendingEffects.add(e):(n.pendingEffects.add(e),n.isBatching||(n.isBatching=!0,queueMicrotask(()=>{for(let e of n.pendingEffects)n.pendingEffects.delete(e),e.run();n.isBatching=!1,n.flushLogs?.()})))}),n.queueLog?.(`reactive`,`${t}.${String(i)}`,{action:`set`,property:String(i),oldValue:s,newValue:a})}return!0}});return this.proxyCache.set(e,i),i}batch(e){e()}delay(e,t){return new Promise((n,r)=>{if(t.aborted)return r(new DOMException(`Aborted`,`AbortError`));let i=setTimeout(()=>{t.removeEventListener(`abort`,a),n()},e),a=()=>{clearTimeout(i),r(new DOMException(`Aborted`,`AbortError`))};t.addEventListener(`abort`,a,{once:!0})})}resource(t,n,r){let i=r&&typeof r==`object`,a=i?r.name:r||`unnamed_resource`,o=i?r:{},s=o.resetDataOnSourceChange??!0,c=o.responseValidate,l=o.validateBeforeFetch,u=o.retryCount??0,d=o.retryDelay??1e3,f=o.isExponentialBackoffEnabled??!1,p=o.maxRetryDelay??3e4,m=o.timeout,h=this.signal({data:null,loading:!0,error:null,isRetrying:!1},`[CORE_INTERNAL_SIGNAL=1]:resource:state:${a}`),g=e=>{h.value=e,typeof this.queueLog==`function`&&this.queueLog(`resource`,a,{loading:e.loading,data:e.data,error:e.error,isRetrying:e.isRetrying})},_=async(n,r,i=!1)=>{if(r.aborted)return;if(l){let e=l(n);if(e===!1||typeof e==`string`){if(r.aborted)return;let t=typeof e==`string`?e:`Pre-fetch validation failed for resource`,n=i?null:this.untrack(()=>h.value.data);g({data:n,loading:!1,error:Error(t),isRetrying:!1});return}}let o=i&&s?null:this.untrack(()=>h.value.data);g({data:o,loading:!0,error:null,isRetrying:!1});for(let i=0;i<=u;i++){if(r.aborted)return;let o=r;try{if(m&&m>0){let e=AbortSignal.timeout(m);o=AbortSignal.any([r,e])}let e=await t(n,o);if(r.aborted)return;if(o.aborted)throw new DOMException(`The operation timed out.`,`TimeoutError`);if(c){let t=c(e);if(t===!1||typeof t==`string`){if(r.aborted)return;g({data:null,loading:!1,error:Error(typeof t==`string`?t:`Validation failed`),isRetrying:!1});return}}if(r.aborted)return;g({data:e,loading:!1,error:null,isRetrying:!1});return}catch(t){if(r.aborted||t.name===`AbortError`&&r.aborted)return;let n=t.name===`TimeoutError`||t.name===`AbortError`||t.message?.includes(`timeout`),o=e.getExtractedValues({tested:[t.message],expectedKey:`THROW_CUSTOM_VALIDATION_ERROR_NO_RETRY`,valueType:`number`})?.[0]===`1`||!1,s=o&&e.getExtractedValues({tested:[t.message],expectedKey:`MESSAGE`,valueType:`string`})?.[0]||`Custom validation error`,c=o||t.name===`ValidationError`;if(i===u||c){if(r.aborted)return;let e=n?Error(`Request timed out after ${m}ms`,{cause:t}):o?Error(s,{cause:t}):t;g({data:null,loading:!1,error:e,isRetrying:!1});return}else{if(r.aborted)return;let e=f?d*2**i:d;e=Math.min(e,p);let t=Math.random()*200;e+=t,g({data:h.value.data,loading:!0,error:null,isRetrying:!0}),console.warn(`[Resource Retry] "${a}" сбой по ${n?`таймауту`:`ошибке сети`}. Попытка ${i+1}/${u+1}...`);try{if(await this.delay(e,r),r.aborted)return}catch{return}}}}},v=null;return this.effect(()=>{let e=n?n.value:void 0,t=new AbortController;return v=t,this.untrack(()=>{_(e,t.signal,!0)}),()=>t.abort()},`[dev]`),{get data(){return h.value.data},get loading(){return h.value.loading},get error(){return h.value.error},get isRetrying(){return h.value.isRetrying},get value(){return h.value},refetch:()=>{v?.abort(),v=new AbortController,_(n?n.value:void 0,v.signal,!1)},subscribe:e=>h.subscribe(e)}}untrack(e){let t=this.activeEffect;this.activeEffect=null;try{return e()}finally{this.activeEffect=t}}safeRun(e,t){try{t()}catch(e){console.error(`%c[Reactive Error] %cОшибка в эффекте/computed:`,`color: white; background: red; padding: 2px 4px; border-radius: 3px;`,`font-weight: bold;`,e)}}};exports.ReactiveEngine=t;
1
+ const e=require("./utils/getExtractedValues.cjs");var t=class{frameworkPrefix=`core`;activeEffect=null;isBatching=!1;pendingEffects=new Set;services=new Map;factories=new Map;proxyCache=new WeakMap;allEffects=new Set;loggerOptions;pendingLogQueue=[];lastTransactionDuration=null;signalMutationCounts=new Map;lastComputedDurations=new Map;effectExecutionCounts=new Map;batchTickCounts=0;constructor(e){this.loggerOptions=e?.logger}log(t,n,r){if(!this.loggerOptions?.isEnabled)return;if(!this.loggerOptions?.isCoreOptimizationDebugEnabled){let t=e.getExtractedValues({expectedKey:`CORE_INTERNAL_SIGNAL`,tested:[n],valueType:`number`})?.[0]===`1`,r=e.getExtractedValues({expectedKey:`CORE_INTERNAL_EFFECT`,tested:[n],valueType:`number`})?.[0]===`1`;if(t||r)return}if(this.loggerOptions.filter&&!(this.loggerOptions.filter instanceof RegExp?this.loggerOptions.filter:new RegExp(this.loggerOptions.filter.replace(/^\/|\/$/g,``))).test(n))return;let i={signal:`background: #007acc; color: #fff; padding: 2px 6px; border-radius: 4px; font-weight: bold;`,computed:`background: #42b883; color: #fff; padding: 2px 6px; border-radius: 4px; font-weight: bold;`,effect:`background: #e01e5a; color: #fff; padding: 2px 6px; border-radius: 4px; font-weight: bold;`,batch:`background: #7952b3; color: #fff; padding: 2px 6px; border-radius: 4px; font-weight: bold;`,resource:`background: #d97706; color: #fff; padding: 2px 6px; border-radius: 4px; font-weight: bold;`,reactive:`background: #007acc; color: #fff; padding: 2px 6px; border-radius: 4px; font-weight: bold;`},a=``,o=`color: #aaa; font-weight: normal;`;switch(t){case`signal`:{let s=e.getExtractedValues({tested:[n],expectedKey:`CORE_INTERNAL_SIGNAL`,valueType:`number`})?.[0]===`1`,c=n,l=(this.signalMutationCounts.get(c)||0)+1;this.signalMutationCounts.set(c,l);let u=r,d=u.subscribers&&u.subscribers.length>0?u.subscribers.every(t=>t?e.getExtractedValues({tested:[t],expectedKey:`IS_OPTIMIZED`,valueType:`number`})?.[0]===`1`:!1):!1,f=l>50,p=s?`COMPUTED_INTERNAL`:`SIGNAL`;a=` 🔄 Изменений ${s?`кэша`:`сигнала`}: ${l}${f?` ⚠️ (high noise — обнаружен дребезг/спам значений!)`:``}`,f&&(o=`color: orange; font-weight: bold;`,d||(r.__performance_advice__={issue:`Сигнал [${c}] обновляется слишком часто (${l} раз за такт). Это приводит к избыточным ререндерам UI.`,solution:`Оберните чтение этого сигнала в декоратор сжатия потока данных 'withThrottleComputed'`,example:`public throttled = withThrottleComputed(this.engine, () => this.yourSignalName.value, { limit: 300 });`})),console.groupCollapsed(`%c${p}%c [${c}]%c${a}`,s?`background: #42b883; color: #fff; padding: 2px 6px; border-radius: 4px; font-weight: bold;`:i[t],`color: #aaa; font-weight: bold;`,o),console.log(`Данные (Payload):`,r),this.loggerOptions.traceTime&&typeof performance<`u`&&console.log(`Тайминг рантайма:`,`${performance.now().toFixed(2)} ms`),console.groupEnd();return}case`computed`:{let e=r;if(e&&`to`in e){let t=e.to;a=` 🧮 Значение: ${typeof t==`object`&&t?`{...}`:String(t)}`}else if(e&&`duration`in e){let t=parseFloat(e.duration);if(!isNaN(t)){let r=this.lastComputedDurations.get(n);if(r!==void 0&&r>0){let n=(t-r)/r*100;n>5?(a=` 🔴 Замедление: +${n.toFixed(1)}% (${e.duration})`,o=`color: #e01e5a; font-weight: bold;`):n<-5?(a=` 🟢 Ускорение: ${n.toFixed(1)}% (${e.duration})`,o=`color: #42b883; font-weight: bold;`):(a=` 🟢 Стабильно (${e.duration})`,o=`color: #42b883; font-weight: bold;`)}else a=` ⚪ Первый расчет (${e.duration})`;this.lastComputedDurations.set(n,t)}}break}case`effect`:{let e=(this.effectExecutionCounts.get(n)||0)+1;this.effectExecutionCounts.set(n,e);let t=e>30,i=r;a=` 🟢 Стабильно${i&&`duration`in i?` (${i.duration})`:``} | 🚀 Вызовов: ${e}${t?` ⚠️ (heavy re-renders)`:``}`,o=`color: #42b883; font-weight: bold;`,t&&(o=`color: #ff4a4a; font-weight: bold;`);break}case`batch`:this.batchTickCounts+=1,a=` 📦 Номер транзакции: #${this.batchTickCounts}`;break;case`resource`:{let e=r;if(e.loading)a=` ⏳ ЗАГРУЗКА (fetching...)`,o=`color: #d97706; font-weight: bold;`;else if(e.error)a=` 🔴 ОШИБКА: ${e.error.message||`Unknown Error`}`,o=`color: #ff4a4a; font-weight: bold;`;else{let t=e.data;a=` 🟢 УСПЕХ (data: ${typeof t==`object`&&t?`{...}`:String(t)})`,o=`color: #42b883; font-weight: bold;`}break}default:break}console.groupCollapsed(`%c${t.toUpperCase()}%c [${n}]%c${a}`,i[t],`color: #aaa; font-weight: bold;`,o),console.log(`Данные (Payload):`,r),this.loggerOptions.traceTime&&typeof performance<`u`&&console.log(`Тайминг рантайма:`,`${performance.now().toFixed(2)} ms`),console.groupEnd()}onSignalChange;provide(e,t){typeof t==`function`&&!t.prototype?this.factories.set(e,t):this.services.set(e,t)}inject(e){if(!e)throw Error(`[DI Error]: Вы пытаетесь внедрить пустой токен (undefined/null). Проверьте импорты.`);let t=e;if(this.services.has(t))return this.services.get(t);try{let n=this.factories.get(t);if(n){let e=n(this);return this.services.set(t,e),e}if(typeof e==`function`&&e.prototype){let n=new e(this);return this.services.set(t,n),n}throw Error(`Service not found: ${String(e)}`)}catch(t){throw Error(`[DI Error]: Не удалось создать сервис ${String(e)}. Ошибка: ${t?.message||`No e?.message`}`)}}queueLog(e,t,n){this.loggerOptions?.isEnabled&&this.pendingLogQueue.push({type:e,name:t,detail:n})}flushLogs(){if(!this.loggerOptions?.isEnabled||this.pendingLogQueue.length===0)return;let e=typeof performance<`u`?performance.now():0,t=this.pendingLogQueue;if(this.loggerOptions.filter)try{let e;if(this.loggerOptions.filter instanceof RegExp)e=this.loggerOptions.filter;else{let t=this.loggerOptions.filter.replace(/^\/|\/$/g,``);e=new RegExp(t)}t=t.filter(t=>e.test(t.name))}catch(e){console.warn(`[Logger Error]: Некорректный паттерн фильтрации логов`,e)}if(t.length===0){this.pendingLogQueue=[];return}let n=``,r=``,i=`color: #aaa; font-weight: normal;`;if(this.loggerOptions.traceTime&&e){let t=performance.now()-e;if(n=` | Duration: ${t.toFixed(3)} ms`,this.lastTransactionDuration!==null&&this.lastTransactionDuration>0){let e=(t-this.lastTransactionDuration)/this.lastTransactionDuration*100;e>.1?(r=` 🔴 +${e.toFixed(1)}%`,i=`color: #e01e5a; font-weight: bold;`):e<-.1?(r=` 🟢 ${e.toFixed(1)}%`,i=`color: #42b883; font-weight: bold;`):(r=` 🟢 stable`,i=`color: #42b883; font-weight: bold;`)}else r=` ⚪ first`;this.lastTransactionDuration=t}console.groupCollapsed(`%cREACTIVE TRANSACTION${this.loggerOptions.instanceName?` ${this.loggerOptions.instanceName}`:``}%c Microtask Tick (Size: ${t.length}${n})%c${r}`,`background: #7952b3; color: #fff; padding: 2px 6px; border-radius: 4px; font-weight: bold;`,`color: #aaa; font-weight: normal;`,i),t.forEach(e=>{this.log(e.type,e.name,e.detail)}),this.loggerOptions.traceTime&&typeof performance<`u`&&console.log(`%c[Execution Timestamp]: ${performance.now().toFixed(2)} ms`,`color: #7952b3; font-weight: bold;`),console.groupEnd(),this.pendingLogQueue=[]}signal(e,t){let n=this,r=e,i=new Set,a=typeof t==`string`?{name:t}:t||{},o=a.name||`unnamed_signal`;return{get value(){if(n.activeEffect){let e=n.activeEffect;i.has(e)||(i.add(e),e.cleanups.add(()=>{i.delete(e)}))}return r},set value(e){if(a?.validate&&a.validate(e)!==!0){let t=a.validate(e);console.error(`[ReactiveEngine] Validation failed for signal "${o}": ${typeof t==`string`?t:`Unknown reason`}`,{value:e});return}if((e===null||typeof e!=`object`&&typeof e!=`function`)&&r===e)return;let t=r;r=e,n.onSignalChange?.(o,e,t),i.forEach(e=>{e!==n.activeEffect&&(n.isBatching?n.pendingEffects.add(e):(n.pendingEffects.add(e),n.isBatching||(n.isBatching=!0,queueMicrotask(()=>{for(let e of n.pendingEffects)n.pendingEffects.delete(e),e.run();n.isBatching=!1,n.flushLogs?.()}))))})},subscribe(e){return n.effect(()=>{e(this.value)},`${n.frameworkPrefix}:use:${o}`)}}}effect(e,t){let n=this,r=!0,i={label:t,cleanups:new Set,run(){let t=Array.from(this.cleanups);this.cleanups.clear(),t.forEach(e=>e());let i=n.activeEffect;n.activeEffect=this;let a=performance.now();n.safeRun(this,()=>{let t=e();typeof t==`function`&&this.cleanups.add(t)}),n.activeEffect=i;let o=performance.now()-a;if(!r&&n.loggerOptions?.isEnabled){let e=n.loggerOptions.filter;(!e||e instanceof RegExp&&this.label&&e.test(this.label))&&typeof n.queueLog==`function`&&n.queueLog(`effect`,this.label||`unnamed-efect-0`,{name:this.label||`unnamed-efect-0`,type:`effect`,detail:{status:`stable`,duration:`${o.toFixed(3)}ms`,timestamp:a}})}r=!1}};return this.allEffects.add(i),i.run(),()=>{i.cleanups.forEach(e=>e()),n.pendingEffects.delete(i),n.allEffects.delete(i)}}computedCache=new Map;cleanupRegistry=new FinalizationRegistry(e=>{e()});computed(e,t){if(this.computedCache.has(e)){let t=this.computedCache.get(e)?.deref();if(t)return t}let n=this,r=t||`unnamed_computed`,i=this.signal(void 0,`[CORE_INTERNAL_SIGNAL=1]:${r}`),a=!0,o,s=this.effect(()=>{o=e(),a=!1;let t=typeof performance<`u`&&performance.now()?`0.010ms`:`N/A`;typeof n.queueLog==`function`&&n.queueLog(`computed`,r,{value:o,duration:t}),i.value=o},`[CORE_INTERNAL_EFFECT=1]:${r}`),c=Array.from(this.allEffects)[this.allEffects.size-1],l=()=>{s(),c&&n.allEffects.delete(c),n.computedCache.delete(e)},u={get value(){return a&&(o=e(),a=!1,i.value=o),i.value},subscribe:e=>i.subscribe(e),destroy(){s(),l(),n.computedCache.delete(e)}};return this.cleanupRegistry.register(u,l),this.computedCache.set(e,new WeakRef(u)),u}reactive(e,t=`reactive`){if(this.proxyCache.has(e))return this.proxyCache.get(e);let n=this,r=new Map,i=new Proxy(e,{get(e,i,a){if(n.activeEffect){let e=n.activeEffect;r.has(i)||r.set(i,new Set);let t=r.get(i);t.has(e)||(t.add(e),e.cleanups.add(()=>{t.delete(e)}))}if(Array.isArray(e)&&typeof i==`string`&&[`push`,`pop`,`shift`,`unshift`,`splice`,`sort`,`reverse`].includes(i)){let t=e[i];return function(...a){let o=n.isBatching;n.isBatching=!0;let s=t.apply(e,a);return r.forEach((e,t)=>{t!==i&&Array.from(e).forEach(e=>{e!==n.activeEffect&&n.pendingEffects.add(e)})}),n.isBatching=o,!n.isBatching&&n.pendingEffects.size>0&&(n.isBatching=!0,queueMicrotask(()=>{for(let e of n.pendingEffects)n.pendingEffects.delete(e),e.run();n.isBatching=!1,n.flushLogs?.()})),s}}let o=Reflect.get(e,i,a);return typeof o==`object`&&o?n.reactive(o,`${t}.${String(i)}`):o},set(e,i,a,o){let s=Reflect.get(e,i,o);if(s===a)return!0;if(s!==a){Reflect.set(e,i,a,o),n.onSignalChange?.(`${t}.${String(i)}`,a,s);let c=r.get(i),l=c?Array.from(c):[];if(Array.isArray(e)){let e=r.get(`length`);e&&l.push(...Array.from(e))}l.forEach(e=>{e!==n.activeEffect&&(n.isBatching?n.pendingEffects.add(e):(n.pendingEffects.add(e),n.isBatching||(n.isBatching=!0,queueMicrotask(()=>{for(let e of n.pendingEffects)n.pendingEffects.delete(e),e.run();n.isBatching=!1,n.flushLogs?.()}))))}),n.queueLog?.(`reactive`,`${t}.${String(i)}`,{action:`set`,property:String(i),oldValue:s,newValue:a})}return!0}});return this.proxyCache.set(e,i),i}batch(e){e()}delay(e,t){return new Promise((n,r)=>{if(t.aborted)return r(new DOMException(`Aborted`,`AbortError`));let i=setTimeout(()=>{t.removeEventListener(`abort`,a),n()},e),a=()=>{clearTimeout(i),r(new DOMException(`Aborted`,`AbortError`))};t.addEventListener(`abort`,a,{once:!0})})}resource(t,n,r){let i=r&&typeof r==`object`,a=i?r.name:r||`unnamed_resource`,o=i?r:{},s=o.resetDataOnSourceChange??!0,c=o.responseValidate,l=o.validateBeforeFetch,u=o.retryCount??0,d=o.retryDelay??1e3,f=o.isExponentialBackoffEnabled??!1,p=o.maxRetryDelay??3e4,m=o.timeout,h=this.signal({data:null,loading:!0,error:null,isRetrying:!1},`[CORE_INTERNAL_SIGNAL=1]:resource:state:${a}`),g=e=>{h.value=e,typeof this.queueLog==`function`&&this.queueLog(`resource`,a,{loading:e.loading,data:e.data,error:e.error,isRetrying:e.isRetrying})},_=async(n,r,i=!1)=>{if(r.aborted)return;if(l){let e=l(n);if(e===!1||typeof e==`string`){if(r.aborted)return;let t=typeof e==`string`?e:`Pre-fetch validation failed for resource`,n=i?null:this.untrack(()=>h.value.data);g({data:n,loading:!1,error:Error(t),isRetrying:!1});return}}let o=i&&s?null:this.untrack(()=>h.value.data);g({data:o,loading:!0,error:null,isRetrying:!1});for(let i=0;i<=u;i++){if(r.aborted)return;let o=r;try{if(m&&m>0){let e=AbortSignal.timeout(m);o=AbortSignal.any([r,e])}let e=await t(n,o);if(r.aborted)return;if(o.aborted)throw new DOMException(`The operation timed out.`,`TimeoutError`);if(c){let t=c(e);if(t===!1||typeof t==`string`){if(r.aborted)return;g({data:null,loading:!1,error:Error(typeof t==`string`?t:`Validation failed`),isRetrying:!1});return}}if(r.aborted)return;g({data:e,loading:!1,error:null,isRetrying:!1});return}catch(t){if(r.aborted||t.name===`AbortError`&&r.aborted)return;let n=t.name===`TimeoutError`||t.name===`AbortError`||t.message?.includes(`timeout`),o=e.getExtractedValues({tested:[t.message],expectedKey:`THROW_CUSTOM_VALIDATION_ERROR_NO_RETRY`,valueType:`number`})?.[0]===`1`||!1,s=o&&e.getExtractedValues({tested:[t.message],expectedKey:`MESSAGE`,valueType:`string`})?.[0]||`Custom validation error`,c=o||t.name===`ValidationError`;if(i===u||c){if(r.aborted)return;let e=n?Error(`Request timed out after ${m}ms`,{cause:t}):o?Error(s,{cause:t}):t;g({data:null,loading:!1,error:e,isRetrying:!1});return}else{if(r.aborted)return;let e=f?d*2**i:d;e=Math.min(e,p);let t=Math.random()*200;e+=t,g({data:h.value.data,loading:!0,error:null,isRetrying:!0}),console.warn(`[Resource Retry] "${a}" сбой по ${n?`таймауту`:`ошибке сети`}. Попытка ${i+1}/${u+1}...`);try{if(await this.delay(e,r),r.aborted)return}catch{return}}}}},v=null;return this.effect(()=>{let e=n?n.value:void 0,t=new AbortController;return v=t,this.untrack(()=>{_(e,t.signal,!0)}),()=>t.abort()},`[dev]`),{get data(){return h.value.data},get loading(){return h.value.loading},get error(){return h.value.error},get isRetrying(){return h.value.isRetrying},get value(){return h.value},refetch:()=>{v?.abort(),v=new AbortController,_(n?n.value:void 0,v.signal,!1)},subscribe:e=>h.subscribe(e)}}untrack(e){let t=this.activeEffect;this.activeEffect=null;try{return e()}finally{this.activeEffect=t}}safeRun(e,t){try{t()}catch(e){console.error(`%c[Reactive Error] %cОшибка в эффекте/computed:`,`color: white; background: red; padding: 2px 4px; border-radius: 3px;`,`font-weight: bold;`,e)}}};exports.ReactiveEngine=t;
2
2
  //# sourceMappingURL=core.cjs.map