@pravosleva/reactive-engine 0.4.2-beta → 1.0.2-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 +5 -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
package/README.md CHANGED
@@ -19,6 +19,35 @@ yarn add @pravosleva/reactive-engine
19
19
  pnpm add @pravosleva/reactive-engine
20
20
  ```
21
21
 
22
+ ```tsx
23
+ import { AbstractService, ReactiveEngine } from '@pravosleva/reactive-engine'
24
+
25
+ class Logic extends AbstractService {
26
+ public counter = this.engine.signal<number>(0, 'example-01:signal:counter');
27
+
28
+ public inc() {
29
+ this.counter.value += 1
30
+ }
31
+ }
32
+
33
+ const engine = new ReactiveEngine()
34
+
35
+ export const Example001 = () => {
36
+ const logic = engine.inject(Logic)
37
+ const counter = engine.use(logic.counter)
38
+
39
+ return (
40
+ <div>
41
+ <div>Signal example</div>
42
+ <code>{counter}</code>
43
+ <div className={baseClasses.catSection}>
44
+ <button onClick={() => logic.inc()}>+ INC</button>
45
+ </div>
46
+ </div>
47
+ )
48
+ }
49
+ ```
50
+
22
51
  ## 🎯 What Problems This Library Solves
23
52
 
24
53
  When building large-scale React applications, developers constantly run into architectural bottlenecks imposed by built-in state tools. `@pravosleva/reactive-engine` is designed to elegantly solve the following pain points:
@@ -0,0 +1,2 @@
1
+ var e=class{engine;constructor(e){this.engine=e,this.onInit()}createNumericSignal(e,t){return this.engine.signal(e,{name:t,validate:e=>typeof e==`number`&&!isNaN(e)})}createComputed(e){return this.engine.computed(e)}createSignal(e,t){return this.engine.signal(e,t)}onInit(){}},t=e;exports.AbstractService=e,exports.BaseREService=t;
2
+ //# sourceMappingURL=AbstractService.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AbstractService.cjs","names":[],"sources":["../src/core/AbstractService.ts"],"sourcesContent":["import { ReactiveEngine } from './core';\n\nexport abstract class AbstractService {\n constructor(protected engine: ReactiveEngine) {\n // Вызываем метод инициализации, который можно переопределить в наследниках\n this.onInit();\n }\n\n // NOTE: Полезные хелперы для сокращения кода\n protected createNumericSignal(val: number, name: string) {\n return this.engine.signal(val, {\n name,\n validate: (v) => typeof v === 'number' && !isNaN(v)\n });\n }\n\n protected createComputed<T>(fn: () => T) {\n return this.engine.computed(fn);\n }\n\n protected createSignal<T>(val: T, name?: string) {\n return this.engine.signal(val, name);\n }\n\n // NOTE: Жизненный цикл: вызывается сразу после создания сервиса.\n // Удобно для инициализации сигналов, которые зависят от engine.\n protected onInit(): void { }\n}\n\nexport const BaseREService = AbstractService\n"],"mappings":"AAEA,IAAsB,EAAtB,KAAsC,CACd,OAAtB,YAAY,EAAkC,CAAxB,KAAA,OAAA,EAEpB,KAAK,OAAO,CACd,CAGA,oBAA8B,EAAa,EAAc,CACvD,OAAO,KAAK,OAAO,OAAO,EAAK,CAC7B,OACA,SAAW,GAAM,OAAO,GAAM,UAAY,CAAC,MAAM,CAAC,CACpD,CAAC,CACH,CAEA,eAA4B,EAAa,CACvC,OAAO,KAAK,OAAO,SAAS,CAAE,CAChC,CAEA,aAA0B,EAAQ,EAAe,CAC/C,OAAO,KAAK,OAAO,OAAO,EAAK,CAAI,CACrC,CAIA,QAAyB,CAAE,CAC7B,EAEa,EAAgB"}
@@ -0,0 +1,24 @@
1
+ //#region src/core/AbstractService.ts
2
+ var e = class {
3
+ engine;
4
+ constructor(e) {
5
+ this.engine = e, this.onInit();
6
+ }
7
+ createNumericSignal(e, t) {
8
+ return this.engine.signal(e, {
9
+ name: t,
10
+ validate: (e) => typeof e == "number" && !isNaN(e)
11
+ });
12
+ }
13
+ createComputed(e) {
14
+ return this.engine.computed(e);
15
+ }
16
+ createSignal(e, t) {
17
+ return this.engine.signal(e, t);
18
+ }
19
+ onInit() {}
20
+ }, t = e;
21
+ //#endregion
22
+ export { e as AbstractService, t as BaseREService };
23
+
24
+ //# sourceMappingURL=AbstractService.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AbstractService.mjs","names":[],"sources":["../src/core/AbstractService.ts"],"sourcesContent":["import { ReactiveEngine } from './core';\n\nexport abstract class AbstractService {\n constructor(protected engine: ReactiveEngine) {\n // Вызываем метод инициализации, который можно переопределить в наследниках\n this.onInit();\n }\n\n // NOTE: Полезные хелперы для сокращения кода\n protected createNumericSignal(val: number, name: string) {\n return this.engine.signal(val, {\n name,\n validate: (v) => typeof v === 'number' && !isNaN(v)\n });\n }\n\n protected createComputed<T>(fn: () => T) {\n return this.engine.computed(fn);\n }\n\n protected createSignal<T>(val: T, name?: string) {\n return this.engine.signal(val, name);\n }\n\n // NOTE: Жизненный цикл: вызывается сразу после создания сервиса.\n // Удобно для инициализации сигналов, которые зависят от engine.\n protected onInit(): void { }\n}\n\nexport const BaseREService = AbstractService\n"],"mappings":";AAEA,IAAsB,IAAtB,MAAsC;CACd;CAAtB,YAAY,GAAkC;EAE5C,AAFoB,KAAA,SAAA,GAEpB,KAAK,OAAO;CACd;CAGA,oBAA8B,GAAa,GAAc;EACvD,OAAO,KAAK,OAAO,OAAO,GAAK;GAC7B;GACA,WAAW,MAAM,OAAO,KAAM,YAAY,CAAC,MAAM,CAAC;EACpD,CAAC;CACH;CAEA,eAA4B,GAAa;EACvC,OAAO,KAAK,OAAO,SAAS,CAAE;CAChC;CAEA,aAA0B,GAAQ,GAAe;EAC/C,OAAO,KAAK,OAAO,OAAO,GAAK,CAAI;CACrC;CAIA,SAAyB,CAAE;AAC7B,GAEa,IAAgB"}
@@ -0,0 +1,2 @@
1
+ var e=class{engine;constructor(e){this.engine=e,setTimeout(()=>this.onInit(),0)}onInit(){}};exports.BaseREServiceEnhanced=e;
2
+ //# sourceMappingURL=BaseREServiceEnhanced.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BaseREServiceEnhanced.cjs","names":[],"sources":["../src/core/BaseREServiceEnhanced.ts"],"sourcesContent":["import { ReactiveEngine } from './core';\n\nexport abstract class BaseREServiceEnhanced {\n constructor(protected engine: ReactiveEngine) {\n setTimeout(() => this.onInit(), 0)\n }\n\n protected onInit(): void { }\n}\n"],"mappings":"AAEA,IAAsB,EAAtB,KAA4C,CACpB,OAAtB,YAAY,EAAkC,CAAxB,KAAA,OAAA,EACpB,eAAiB,KAAK,OAAO,EAAG,CAAC,CACnC,CAEA,QAAyB,CAAE,CAC7B"}
@@ -0,0 +1,12 @@
1
+ //#region src/core/BaseREServiceEnhanced.ts
2
+ var e = class {
3
+ engine;
4
+ constructor(e) {
5
+ this.engine = e, setTimeout(() => this.onInit(), 0);
6
+ }
7
+ onInit() {}
8
+ };
9
+ //#endregion
10
+ export { e as BaseREServiceEnhanced };
11
+
12
+ //# sourceMappingURL=BaseREServiceEnhanced.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BaseREServiceEnhanced.mjs","names":[],"sources":["../src/core/BaseREServiceEnhanced.ts"],"sourcesContent":["import { ReactiveEngine } from './core';\n\nexport abstract class BaseREServiceEnhanced {\n constructor(protected engine: ReactiveEngine) {\n setTimeout(() => this.onInit(), 0)\n }\n\n protected onInit(): void { }\n}\n"],"mappings":";AAEA,IAAsB,IAAtB,MAA4C;CACpB;CAAtB,YAAY,GAAkC;EAC5C,AADoB,KAAA,SAAA,GACpB,iBAAiB,KAAK,OAAO,GAAG,CAAC;CACnC;CAEA,SAAyB,CAAE;AAC7B"}
@@ -0,0 +1,17 @@
1
+ import { ReactiveEngine } from './react';
2
+ import { Signal, Computed, Resource } from './core';
3
+ export declare const engine: ReactiveEngine;
4
+ /**
5
+ * Хук для получения текущего значения Signal и его авто-обновления в React.
6
+ */
7
+ export declare function useSignal<T>(signal: Signal<T>): T;
8
+ /**
9
+ * Хук для получения значения вычисляемого свойства Computed.
10
+ */
11
+ export declare function useComputed<T>(computed: Computed<T>): T;
12
+ /**
13
+ * Хук для реактивного отслеживания асинхронного ресурса.
14
+ * Возвращает объект состояния { data, loading, error }
15
+ */
16
+ export declare function useResource<T>(resource: Resource<T>): import('./core').ResourceState<T>;
17
+ //# sourceMappingURL=_react-bindings.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_react-bindings.d.ts","sourceRoot":"","sources":["../src/_react-bindings.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAQpD,eAAO,MAAM,MAAM,gBAAuB,CAAC;AAK3C;;GAEG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAGjD;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAEvD;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,qCAGnD"}
@@ -0,0 +1 @@
1
+ var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},s=(n,r,a)=>(a=n==null?{}:e(i(n)),o(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n));exports.__toESM=s;
@@ -0,0 +1,11 @@
1
+ import { ReactiveEngine } from './core';
2
+ export declare abstract class AbstractService {
3
+ protected engine: ReactiveEngine;
4
+ constructor(engine: ReactiveEngine);
5
+ protected createNumericSignal(val: number, name: string): import('./core').Signal<number>;
6
+ protected createComputed<T>(fn: () => T): import('./core').Computed<T>;
7
+ protected createSignal<T>(val: T, name?: string): import('./core').Signal<T>;
8
+ protected onInit(): void;
9
+ }
10
+ export declare const BaseREService: typeof AbstractService;
11
+ //# sourceMappingURL=AbstractService.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AbstractService.d.ts","sourceRoot":"","sources":["../../src/core/AbstractService.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAC;AAExC,8BAAsB,eAAe;IACvB,SAAS,CAAC,MAAM,EAAE,cAAc;gBAAtB,MAAM,EAAE,cAAc;IAM5C,SAAS,CAAC,mBAAmB,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM;IAOvD,SAAS,CAAC,cAAc,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC;IAIvC,SAAS,CAAC,YAAY,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,CAAC,EAAE,MAAM;IAM/C,SAAS,CAAC,MAAM,IAAI,IAAI;CACzB;AAED,eAAO,MAAM,aAAa,wBAAkB,CAAA"}
@@ -0,0 +1,7 @@
1
+ import { ReactiveEngine } from './core';
2
+ export declare abstract class BaseREServiceEnhanced {
3
+ protected engine: ReactiveEngine;
4
+ constructor(engine: ReactiveEngine);
5
+ protected onInit(): void;
6
+ }
7
+ //# sourceMappingURL=BaseREServiceEnhanced.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BaseREServiceEnhanced.d.ts","sourceRoot":"","sources":["../../src/core/BaseREServiceEnhanced.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAC;AAExC,8BAAsB,qBAAqB;IAC7B,SAAS,CAAC,MAAM,EAAE,cAAc;gBAAtB,MAAM,EAAE,cAAc;IAI5C,SAAS,CAAC,MAAM,IAAI,IAAI;CACzB"}
@@ -0,0 +1,282 @@
1
+ import { ResourceOptions, ResourceState, SignalOptions } from './types';
2
+ /**
3
+ * Интерфейс для сигнала.
4
+ * @template T
5
+ * @interface Signal<T>
6
+ */
7
+ export interface Signal<T> {
8
+ /**
9
+ * Значение сигнала.
10
+ * @type {T}
11
+ */
12
+ value: T;
13
+ /**
14
+ * Подписка на изменение значения сигнала.
15
+ * @function subscribe
16
+ * @param {Function} cb - Коллбек функция для обработки изменения.
17
+ * @returns {CleanupFn} - Функция для очистки подписки.
18
+ */
19
+ subscribe: (cb: (val: T) => void) => CleanupFn;
20
+ }
21
+ export type CleanupFn = () => void;
22
+ export type EffectFn = () => CleanupFn | void;
23
+ export type Token<T> = string | symbol | {
24
+ new (engine: ReactiveEngine, ...args: any[]): T;
25
+ };
26
+ export type Factory<T> = (engine: ReactiveEngine) => T;
27
+ /**
28
+ * Интерфейс для вычисляемого значения.
29
+ * @template T
30
+ * @interface Computed<T>
31
+ */
32
+ export interface Computed<T> {
33
+ /**
34
+ * Только читаемое значение вычисляемого значения.
35
+ * @type {T}
36
+ */
37
+ readonly value: T;
38
+ /**
39
+ * Подписка на изменение вычисляемого значения.
40
+ * @function subscribe
41
+ * @param {Function} cb - Коллбек функция для обработки изменения.
42
+ * @returns {CleanupFn} - Функция для очистки подписки.
43
+ */
44
+ subscribe: (cb: (val: T) => void) => CleanupFn;
45
+ /**
46
+ * Принудительное уничтожение вычисляемого значения и его эффекта для предотвращения утечек памяти.
47
+ */
48
+ destroy: () => void;
49
+ }
50
+ /**
51
+ * Интерфейс для эффекта.
52
+ * @interface IEffect
53
+ */
54
+ export interface IEffect {
55
+ run: () => void;
56
+ label?: string;
57
+ cleanups: Set<CleanupFn>;
58
+ }
59
+ /**
60
+ * Интерфейс для ресурса.
61
+ * @template T
62
+ * @interface Resource<T>
63
+ */
64
+ export interface Resource<T> extends ResourceState<T> {
65
+ /**
66
+ * Перезагрузка ресурса.
67
+ * @function refetch
68
+ * @returns {void}
69
+ */
70
+ refetch: () => void;
71
+ /**
72
+ * Подписка на изменение состояния ресурса.
73
+ * @function subscribe
74
+ * @param {Function} cb - Коллбек функция для обработки изменения.
75
+ * @returns {CleanupFn} - Функция для очистки подписки.
76
+ */
77
+ subscribe: (cb: (val: ResourceState<T>) => void) => CleanupFn;
78
+ /**
79
+ * Только читаемое состояние ресурса.
80
+ * @type {ResourceState<T>}
81
+ */
82
+ readonly value: ResourceState<T>;
83
+ }
84
+ /**
85
+ * Класс `ReactiveEngine` представляет собой реактивную систему, которая позволяет создавать и управлять реактивными объектами,
86
+ * сигналами, эффектами, асинхронными ресурсами и другими реактивными примитивами. Реактивные механизмы облегчают разработку
87
+ * сложных пользовательских интерфейсов и приложений, автоматически отслеживая зависимости между данными и реактивно обновляя UI.
88
+ *
89
+ * Основные возможности `ReactiveEngine` включают:
90
+ * - **Сигналы (Signals)**: Реактивные переменные с поддержкой подписки на изменения.
91
+ * - **Эффекты (Effects)**: Автоматические функции, которые выполняются при изменении зависимых сигналов.
92
+ * - **Ресурсы (Resources)**: Асинхронные ресурсы с поддержкой повторных попыток и валидации.
93
+ * - **Прокси-объекты (Proxy Objects)**: Реактивное обертывание объектов для отслеживания изменений свойств.
94
+ * - **Интеграция с React**: Удобные методы для интеграции реактивного ядра с компонентами React.
95
+ *
96
+ * Пример использования:
97
+ *
98
+ * ```javascript
99
+ * const engine = new ReactiveEngine();
100
+ * const count = engine.signal(0);
101
+ *
102
+ * engine.effect(() => {
103
+ * console.log(`Count is ${count.value}`);
104
+ * });
105
+ *
106
+ * count.value++; // Выведет: Count is 1
107
+ * ```
108
+ *
109
+ * @class
110
+ */
111
+ export declare class ReactiveEngine {
112
+ private activeEffect;
113
+ private isBatching;
114
+ private pendingEffects;
115
+ private services;
116
+ private factories;
117
+ private proxyCache;
118
+ private allEffects;
119
+ /**
120
+ * Коллбек для уведомления об изменении сигнала.
121
+ * Использование unknown вместо any гарантирует безопасную работу с типами prev/next.
122
+ */
123
+ onSignalChange?: (name: string, next: unknown, prev: unknown) => void;
124
+ /**
125
+ * DI: Регистрация зависимости.
126
+ * @template T
127
+ * @function provide
128
+ * @param {Token<T>} token - Токен для зависимости.
129
+ * @param {T | Factory<T>} valueOrFactory - Значение или фабрика для создания сервиса.
130
+ * @returns {void}
131
+ * @source
132
+ */
133
+ provide<T>(token: Token<T>, valueOrFactory: T | Factory<T>): void;
134
+ /**
135
+ * DI: Инъекция; Получение сервиса по токену.
136
+ * @template T
137
+ * @function inject
138
+ * @param {Token<T>} token - Токен для зависимости.
139
+ * @returns {T} - Сервис.
140
+ * @source
141
+ */
142
+ inject<T>(token: Token<T>): T;
143
+ /**
144
+ * Создание сигнала.
145
+ * @template T
146
+ * @function signal
147
+ * @param {T} initialValue - Начальное значение сигнала.
148
+ * @param {string | SignalOptions<T>} [optionsOrName] - Имя или опции сигнала.
149
+ * @returns {Signal<T>} - Сигнал.
150
+ * @source
151
+ */
152
+ signal<T>(initialValue: T, optionsOrName?: string | SignalOptions<T>): Signal<T>;
153
+ /**
154
+ * Создание эффекта.
155
+ * @function effect
156
+ * @param {EffectFn} fn - Функция эффекта.
157
+ * @param {string} [label] - Необязательная метка для логирования и отладки.
158
+ * @returns {CleanupFn} - Функция для очистки эффекта.
159
+ * @source
160
+ */
161
+ effect(fn: EffectFn, label?: string): CleanupFn;
162
+ private computedCache;
163
+ private cleanupRegistry;
164
+ /**
165
+ * Создание вычисляемого значения.
166
+ * @template T
167
+ * @function computed
168
+ * @param {Function} fn - Функция для вычисления значения.
169
+ * @param {string} [signalName] - Имя сигнала.
170
+ * @returns {Computed<T>} - Вычисляемое значение с методом destroy.
171
+ * @source
172
+ */
173
+ computed<T>(fn: () => T, signalName?: string): Computed<T>;
174
+ /**
175
+ * Создание реактивного объекта (Proxy).
176
+ * @template T
177
+ * @function reactive
178
+ * @param {T} target - Целевой объект для проксирования.
179
+ * @param {string} [name] - Имя проксируемого объекта.
180
+ * @returns {T} - Реактивный объект.
181
+ * @source
182
+ */
183
+ reactive<T extends object>(target: T, name?: string): T;
184
+ /**
185
+ * Группировка изменений. (Оставил для обратной совместимости)
186
+ * @function batch
187
+ * @param {Function} fn - Функция для выполнения в группе.
188
+ * @returns {void}
189
+ * @source
190
+ */
191
+ batch(fn: () => void): void;
192
+ /**
193
+ * Вспомогательная функция для задержки (sleep), чувствительная к AbortSignal
194
+ *
195
+ * Вызов new DOMException('Aborted', 'AbortError') гарантирует,
196
+ * что ваша кастомная пауза между ретраями this.delay притворяется для движка JavaScript
197
+ * точно таким же нативным процессом отмены, как и fetch().
198
+ * Это делает реактивное ядро бесшовным и избавляет от необходимости
199
+ * писать кучу разных проверок под каждый тип ошибки.
200
+ */
201
+ private delay;
202
+ /**
203
+ * Создание асинхронного ресурса. Типы на входе: <T - формат ответа, S - источник изменений (сигнал либо computed-кортеж из зачений сигналов через конструкцию `.value`)>
204
+ *
205
+ * Explained 👉 {@link https://github.com/garage-13/reactive-engine/blob/main/README_EN.md#1-async-resources-dependent-on-multiple-signals}
206
+ *
207
+ * @template T, S
208
+ * @see {@link https://github.com/garage-13/reactive-engine/blob/main/examples/200-resource/Example200.tsx Реализация базового компонента Example200}
209
+ * @see {@link https://github.com/garage-13/reactive-engine/blob/main/examples/201-multi-resource/service.secondary.ts Сложный пример зависимости ресурсов через computed}
210
+ * @function resource
211
+ * @param {Function} fetcher - Асинхронная функция для загрузки данных.
212
+ * @param {{ value: S }} [source] - Источник данных.
213
+ * @param {string | ResourceOptions<T>} [optionsOrName] - Имя сигнала или объект конфигурации `{ name: string; validate: (res) => boolean | string; resetDataOnSourceChange?: boolean }`.
214
+ * @returns {Resource<T>} - Асинхронный ресурс.
215
+ *
216
+ * @example
217
+ * // Базовый вызов со строкой (обратная совместимость):
218
+ * const res = engine.resource(fetcher, source, 'my-resource-name');
219
+ *
220
+ * @example
221
+ * // Современный вызов с валидацией ответа:
222
+ * const res = engine.resource(fetcher, source, {
223
+ * name: 'my-resource-name',
224
+ * resetDataOnSourceChange: true, // true by default
225
+ * responseValidate: (data) => !!data || 'Данные пусты', // Проверяйте формат в соотв. с дженериком
226
+ * });
227
+ *
228
+ * @example
229
+ * // (Экспериментальная фича)
230
+ * // В теле fetcher можно выкинуть ошибку в виде
231
+ * // `throw new Error('[THROW_CUSTOM_VALIDATION_ERROR_NO_RETRY=1][MESSAGE=Your msg]')`
232
+ * // Причина: Особенности внутренней реализации определения харакрера ошибки и необходимость делать retry (если такая опция передана)
233
+ * // Рекомендуем вместо этого использовать `validateBeforeFetch` в опциях при создании ресурса.
234
+ * const res = engine.resource(
235
+ * async (counterValue, abortSignal) => {
236
+ * if (counterValue === 0)
237
+ * throw new Error([
238
+ * '[THROW_CUSTOM_VALIDATION_ERROR_NO_RETRY=1]', // Иначе запустится механизм retry (напр. по причине отсутствия сети, далее в этом же примере)
239
+ * `[MESSAGE=Stop for count value ${counterValue} - excepted from fetcher fn body]`,
240
+ * ].join(' '))
241
+ * const res = await fetch(
242
+ * [
243
+ * `${BASE_API_URL}/profile/search`,
244
+ * '?',
245
+ * [
246
+ * `counter=${counterValue}`,
247
+ * '_responseDelay=2000',
248
+ * ].join('&')
249
+ * ].join(''),
250
+ * { signal: abortSignal }
251
+ * )
252
+ * if (!res.ok) throw new Error(`HTTP error! status: ${res.status}`)
253
+ * return res.json()
254
+ * },
255
+ * this.counter,
256
+ * )
257
+ * @source
258
+ */
259
+ resource<T, S = void>(fetcher: (source: S, signal: AbortSignal) => Promise<T>, source?: {
260
+ value: S;
261
+ }, optionsOrName?: string | ResourceOptions<T, S>): Resource<T>;
262
+ /**
263
+ * Выполняет функцию без отслеживания зависимостей.
264
+ * @template T
265
+ * @function untrack
266
+ * @param {Function} fn - Функция для выполнения.
267
+ * @returns {T} - Результат выполнения функции.
268
+ * @source
269
+ */
270
+ untrack<T>(fn: () => T): T;
271
+ /**
272
+ * Безопасное выполнение функции.
273
+ * @private
274
+ * @function safeRun
275
+ * @param {IEffect} effect - Эффект.
276
+ * @param {Function} fn - Функция для выполнения.
277
+ * @returns {void}
278
+ * @source
279
+ */
280
+ private safeRun;
281
+ }
282
+ //# sourceMappingURL=core.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../../src/core/core.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=core.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"core.test.d.ts","sourceRoot":"","sources":["../../src/core/core.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,5 @@
1
+ export * from './core';
2
+ export * from './types';
3
+ export * from './AbstractService';
4
+ export * from './BaseREServiceEnhanced';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA,cAAc,QAAQ,CAAA;AACtB,cAAc,SAAS,CAAA;AACvB,cAAc,mBAAmB,CAAA;AACjC,cAAc,yBAAyB,CAAA"}
@@ -0,0 +1,92 @@
1
+ export interface ResourceState<T> {
2
+ data: T | null;
3
+ loading: boolean;
4
+ error: any | null;
5
+ }
6
+ /**
7
+ * Функция для очистки эффекта.
8
+ * @typedef {() => void} CleanupFn
9
+ */
10
+ /**
11
+ * Функция эффекта, которая может возвращать функцию очистки.
12
+ * @typedef {() => CleanupFn | void} EffectFn
13
+ */
14
+ /**
15
+ * Токен для зависимости.
16
+ * @typedef {string | symbol | { new(engine: ReactiveEngine, ...args: any[]): T }} Token<T>
17
+ */
18
+ /**
19
+ * Фабрика для создания сервиса.
20
+ * @template T
21
+ * @typedef {(engine: ReactiveEngine) => T} Factory<T>
22
+ */
23
+ /**
24
+ * Интерфейс для состояния ресурса.
25
+ * @template T Data format
26
+ * @interface ResourceState<T>
27
+ */
28
+ export interface ResourceState<T> {
29
+ /**
30
+ * Данные ресурса.
31
+ * @type {T | null}
32
+ */
33
+ data: T | null;
34
+ /**
35
+ * Состояние загрузки ресурса.
36
+ * @type {boolean}
37
+ */
38
+ loading: boolean;
39
+ /**
40
+ * Ошибка ресурса.
41
+ * @type {any | null}
42
+ */
43
+ error: any | null;
44
+ /** Флаг активного процесса повторных попыток после сбоя сети */
45
+ isRetrying: boolean;
46
+ }
47
+ export interface ResourceOptions<T, S> {
48
+ name: string;
49
+ /** Автоматически сбрасывать data в null при изменении source. По умолчанию: true */
50
+ resetDataOnSourceChange?: boolean;
51
+ /** Функция для валидации успешного ответа сервера перед его сохранением в стейт.
52
+ *
53
+ * Варианты возвращаемого значения:
54
+ * - true 👉 все ок
55
+ * - false 👉 в error попадет стандартный текст ошибки
56
+ * - string 👉 попадет в поле error
57
+ * */
58
+ responseValidate?: (responseData: T) => boolean | string;
59
+ /** Функция валидации входных зависимостей (source) перед запуском fetch.
60
+ * Если возвращает false или string (текст ошибки) — запрос и ретраи блокируются. */
61
+ validateBeforeFetch?: (sourceValue: S) => boolean | string;
62
+ /** Настройка лимита повторов retry. */
63
+ retryCount?: number;
64
+ /** Настройка задержки первого повтора retry. */
65
+ retryDelay?: number;
66
+ /** Включить экспоненциальное увеличение задержки (каждая попытка ждет в 2 раза дольше). По умолчанию: false */
67
+ isExponentialBackoffEnabled?: boolean;
68
+ /** Максимальный лимит ожидания между попытками в миллисекундах. По умолчанию: 30000 (30 секунд) */
69
+ maxRetryDelay?: number;
70
+ /** Максимальное время ожидания ответа сервера в миллисекундах. По умолчанию: отсутствует (бесконечно) */
71
+ timeout?: number;
72
+ }
73
+ /**
74
+ * Интерфейс для опций сигнала.
75
+ * @template T
76
+ * @interface SignalOptions<T>
77
+ */
78
+ export interface SignalOptions<T> {
79
+ /**
80
+ * Имя сигнала.
81
+ * @type {string}
82
+ */
83
+ name?: string;
84
+ /**
85
+ * Валидатор значения сигнала.
86
+ * @function validate
87
+ * @param {T} val - Значение для валидации.
88
+ * @returns {boolean | string} - Результат валидации.
89
+ */
90
+ validate?: (val: T) => boolean | string;
91
+ }
92
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,aAAa,CAAC,CAAC;IAC9B,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,GAAG,GAAG,IAAI,CAAC;CACnB;AAED;;;GAGG;AAEH;;;GAGG;AAEH;;;GAGG;AAEH;;;;GAIG;AAEH;;;;GAIG;AACH,MAAM,WAAW,aAAa,CAAC,CAAC;IAC9B;;;OAGG;IACH,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC;IAEf;;;OAGG;IACH,OAAO,EAAE,OAAO,CAAC;IAEjB;;;OAGG;IACH,KAAK,EAAE,GAAG,GAAG,IAAI,CAAC;IAElB,gEAAgE;IAChE,UAAU,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,eAAe,CAAC,CAAC,EAAE,CAAC;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,oFAAoF;IACpF,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC;;;;;;SAMK;IACL,gBAAgB,CAAC,EAAE,CAAC,YAAY,EAAE,CAAC,KAAK,OAAO,GAAG,MAAM,CAAC;IACzD;wFACoF;IACpF,mBAAmB,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC,KAAK,OAAO,GAAG,MAAM,CAAC;IAC3D,uCAAuC;IACvC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gDAAgD;IAChD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,+GAA+G;IAC/G,2BAA2B,CAAC,EAAE,OAAO,CAAC;IACtC,mGAAmG;IACnG,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,yGAAyG;IACzG,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;GAIG;AACH,MAAM,WAAW,aAAa,CAAC,CAAC;IAC9B;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,OAAO,GAAG,MAAM,CAAC;CACzC"}
package/dist/core.cjs ADDED
@@ -0,0 +1,2 @@
1
+ const e=require("./utils/getExtractedValues.cjs");var t=class{activeEffect=null;isBatching=!1;pendingEffects=new Set;services=new Map;factories=new Map;proxyCache=new WeakMap;allEffects=new Set;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`}`)}}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(){return n.activeEffect&&i.add(n.activeEffect),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),i.forEach(e=>n.pendingEffects.add(e)),n.isBatching||(n.isBatching=!0,queueMicrotask(()=>{let e=Array.from(n.pendingEffects);n.pendingEffects.clear(),n.isBatching=!1,e.forEach(e=>e.run())}))},subscribe(e){return n.effect(()=>{e(this.value)})}}}effect(e,t){let n=this,r={label:t,cleanups:new Set,run(){this.cleanups.forEach(e=>e()),this.cleanups.clear();let t=n.activeEffect;n.activeEffect=this,n.safeRun(this,()=>{let t=e();typeof t==`function`&&this.cleanups.add(t)}),n.activeEffect=t}};return this.allEffects.add(r),r.run(),()=>{r.cleanups.forEach(e=>e()),n.pendingEffects.delete(r),n.allEffects.delete(r)}}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=this.signal(void 0,t||`unnamed_computed`),i=this.effect(()=>{let t=e();r.value=t}),a=Array.from(this.allEffects)[this.allEffects.size-1],o=()=>{i(),a&&n.allEffects.delete(a),n.computedCache.delete(e)},s={get value(){return r.value},subscribe:e=>r.subscribe(e),destroy(){o()}};return this.cleanupRegistry.register(s,o),this.computedCache.set(e,new WeakRef(s)),s}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){n.activeEffect&&(r.has(i)||r.set(i,new Set),r.get(i).add(n.activeEffect));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);return s===a||s!==a&&(Reflect.set(e,i,a,o),n.onSignalChange?.(`${t}.${String(i)}`,a,s),r.get(i)?.forEach(e=>n.isBatching?n.pendingEffects.add(e):e.run())),!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},a),g=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);h.value={data:n,loading:!1,error:Error(t),isRetrying:!1};return}}let o=i&&s?null:this.untrack(()=>h.value.data);h.value={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;h.value={data:null,loading:!1,error:Error(typeof t==`string`?t:`Validation failed`),isRetrying:!1};return}}if(r.aborted)return;h.value={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;h.value={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,h.value={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}}}}},_=null;return this.effect(()=>{let e=n?n.value:void 0,t=new AbortController;return _=t,this.untrack(()=>{g(e,t.signal,!0)}),()=>t.abort()}),{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:()=>{_?.abort(),_=new AbortController,g(n?n.value:void 0,_.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
+ //# sourceMappingURL=core.cjs.map