@pravosleva/reactive-engine 1.0.3-beta → 1.2.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.
- package/README.md +119 -28
- package/dist/angular/ReactiveEngine4Angular.cjs +2 -0
- package/dist/angular/ReactiveEngine4Angular.cjs.map +1 -0
- package/dist/angular/ReactiveEngine4Angular.d.ts +21 -0
- package/dist/angular/ReactiveEngine4Angular.d.ts.map +1 -0
- package/dist/angular/ReactiveEngine4Angular.mjs +19 -0
- package/dist/angular/ReactiveEngine4Angular.mjs.map +1 -0
- package/dist/angular/ReactiveEngine4Angular.test.d.ts +2 -0
- package/dist/angular/ReactiveEngine4Angular.test.d.ts.map +1 -0
- package/dist/angular/index.cjs +1 -0
- package/dist/angular/index.d.ts +3 -0
- package/dist/angular/index.d.ts.map +1 -0
- package/dist/angular/index.mjs +2 -0
- package/dist/react/ReactiveEngine4React.cjs.map +1 -1
- package/dist/react/ReactiveEngine4React.d.ts +4 -0
- package/dist/react/ReactiveEngine4React.d.ts.map +1 -1
- package/dist/react/ReactiveEngine4React.mjs.map +1 -1
- package/dist/vue/ReactiveEngine4Vue.cjs +2 -0
- package/dist/vue/ReactiveEngine4Vue.cjs.map +1 -0
- package/dist/vue/ReactiveEngine4Vue.d.ts +12 -0
- package/dist/vue/ReactiveEngine4Vue.d.ts.map +1 -0
- package/dist/vue/ReactiveEngine4Vue.mjs +19 -0
- package/dist/vue/ReactiveEngine4Vue.mjs.map +1 -0
- package/dist/vue/ReactiveEngine4Vue.test.d.ts +2 -0
- package/dist/vue/ReactiveEngine4Vue.test.d.ts.map +1 -0
- package/dist/vue/index.cjs +1 -0
- package/dist/vue/index.d.ts +2 -0
- package/dist/vue/index.d.ts.map +1 -0
- package/dist/vue/index.mjs +2 -0
- package/package.json +24 -2
package/README.md
CHANGED
|
@@ -2,25 +2,62 @@
|
|
|
2
2
|
A lightweight, type-safe reactive engine built with TypeScript, featuring Dependency Injection and seamless React integration.
|
|
3
3
|
|
|
4
4
|
## Instruction
|
|
5
|
-
- 🇬🇧 [In English](https://
|
|
6
|
-
- 🇷🇺 [In Russian](https://
|
|
5
|
+
- 🇬🇧 [In English](https://pravosleva.pro/reactive-engine/en)
|
|
6
|
+
- 🇷🇺 [In Russian](https://pravosleva.pro/reactive-engine)
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
|
|
9
|
+
## 🎯 What Problems This Library Solves
|
|
10
|
+
|
|
11
|
+
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:
|
|
12
|
+
|
|
13
|
+
1. **Unnecessary Over-Rendering:**
|
|
14
|
+
> * *The Problem:* React Context API and traditional immutability-based stores (Redux/Zustand) force all components reading from that state slice to re-render whenever even a single deeply nested property changes.
|
|
15
|
+
> * *The Solution:* Fine-grained reactivity. Components micro-subscribe only to the specific primitive signals they display. State mutations update strictly the necessary DOM nodes.
|
|
16
|
+
|
|
17
|
+
2. **UI Tearing and Lags in React 18+:**
|
|
18
|
+
> * *The Problem:* Under React Concurrent Mode, standard external state managers can lead to UI tearing, where different parts of the screen temporarily display asynchronous, mismatching data.
|
|
19
|
+
> * *The Solution:* The `useReactiveValue` hook is built on top of native `useSyncExternalStore`. This ensures absolute cross-component synchronization, shielding your interface from glitches and tearing.
|
|
20
|
+
|
|
21
|
+
3. **Expensive CPU Re-calculations:**
|
|
22
|
+
> * *The Problem:* Heavy array filtration, sorting, or data analytics functions trigger re-evaluations on every parent re-render or whenever unrelated props shift.
|
|
23
|
+
> * *The Solution:* Lazy `Computed` properties with O(1) computation caching. The logic evaluates *only* when its underlying dependency signals change.
|
|
24
|
+
|
|
25
|
+
4. **Network Request Flooding (Race Conditions):**
|
|
26
|
+
> * *The Problem:* A user rapidly clicking through catalog filters or pagination options spawns cascades of overlapping network requests. An older, slower request might resolve *after* a newer one, overwriting fresh data (Race Condition).
|
|
27
|
+
> * *The Solution:* The `Resource` utility automatically orchestrates native `AbortController` instances. Whenever dependency signals change, the previous pending fetch request is instantly cancelled at the browser's system level.
|
|
28
|
+
|
|
29
|
+
5. **Cascading UI Updates (Render Cascades):**
|
|
30
|
+
> * *The Problem:* Updating 3–4 connected state parameters inside a single event handler prompts 3–4 sequential UI update ticks, clogging the Event Loop.
|
|
31
|
+
> * *The Solution:* 100% out-of-the-box automatic batching. The engine bundles all consecutive synchronous and asynchronous modifications into a single microtask, triggering exactly 1 final unified re-render.
|
|
32
|
+
|
|
33
|
+
6. **Memory Leaks in Dynamic Architectures:**
|
|
34
|
+
> * *The Problem:* Dynamically instantiating computed properties (e.g., dynamically filtering an active tab) accumulates abandoned reactive effects in memory that continue to listen to global state updates forever.
|
|
35
|
+
> * *The Solution:* Built-in memory cleanup and computation memoization inside the core engine. The library hooks automatically trigger `.destroy()` on component unmount, seamlessly purging dead reactive effects from RAM.
|
|
9
36
|
|
|
10
37
|
## 📦 Installation
|
|
11
38
|
|
|
12
39
|
Install the package via your favorite package manager:
|
|
13
40
|
|
|
14
41
|
```bash
|
|
15
|
-
npm install @pravosleva/reactive-engine
|
|
16
|
-
# or
|
|
17
42
|
yarn add @pravosleva/reactive-engine
|
|
18
|
-
# or
|
|
19
|
-
pnpm add @pravosleva/reactive-engine
|
|
20
43
|
```
|
|
21
44
|
|
|
45
|
+
## `peerDependencies`
|
|
46
|
+
|
|
47
|
+
```json
|
|
48
|
+
{
|
|
49
|
+
"@angular/core": ">=16.0.0",
|
|
50
|
+
"react": "^18.0.0 || ^19.2.0",
|
|
51
|
+
"react-dom": "^18.0.0 || ^19.2.0",
|
|
52
|
+
"vue": ">=3.2.0"
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## React
|
|
57
|
+
|
|
22
58
|
```tsx
|
|
23
|
-
import { AbstractService
|
|
59
|
+
import { AbstractService } from '@pravosleva/reactive-engine'
|
|
60
|
+
import { ReactiveEngine } from '@pravosleva/reactive-engine/react'
|
|
24
61
|
|
|
25
62
|
class Logic extends AbstractService {
|
|
26
63
|
public counter = this.engine.signal<number>(0, 'example-01:signal:counter');
|
|
@@ -48,30 +85,84 @@ export const Example001 = () => {
|
|
|
48
85
|
}
|
|
49
86
|
```
|
|
50
87
|
|
|
51
|
-
##
|
|
88
|
+
## Vue 3
|
|
52
89
|
|
|
53
|
-
|
|
90
|
+
```vue
|
|
91
|
+
<script setup lang="ts">
|
|
92
|
+
import { AbstractService } from '@pravosleva/reactive-engine'
|
|
93
|
+
import { ReactiveEngine as ReactiveEngine4Vue } from '@pravosleva/reactive-engine/vue'
|
|
54
94
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
> * *The Solution:* Fine-grained reactivity. Components micro-subscribe only to the specific primitive signals they display. State mutations update strictly the necessary DOM nodes.
|
|
95
|
+
class CounterLogic extends AbstractService {
|
|
96
|
+
public counter = this.engine.signal<number>(0, 'vue-example:counter');
|
|
58
97
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
98
|
+
public inc = () => {
|
|
99
|
+
this.counter.value += 1
|
|
100
|
+
}
|
|
101
|
+
}
|
|
62
102
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
103
|
+
const engine = new ReactiveEngine4Vue()
|
|
104
|
+
const logic = engine.inject(CounterLogic)
|
|
105
|
+
const counter = engine.use(logic.counter)
|
|
106
|
+
</script>
|
|
66
107
|
|
|
67
|
-
|
|
68
|
-
>
|
|
69
|
-
>
|
|
108
|
+
<template>
|
|
109
|
+
<div>
|
|
110
|
+
<div>Vue 3 Signal Example</div>
|
|
70
111
|
|
|
71
|
-
|
|
72
|
-
>
|
|
73
|
-
> * *The Solution:* 100% out-of-the-box automatic batching. The engine bundles all consecutive synchronous and asynchronous modifications into a single microtask, triggering exactly 1 final unified re-render.
|
|
112
|
+
<!-- Убираем .value, доверяем автоматическому развертыванию Vue -->
|
|
113
|
+
<code>{{ counter }}</code>
|
|
74
114
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
115
|
+
<div>
|
|
116
|
+
<button @click="logic.inc">
|
|
117
|
+
INC
|
|
118
|
+
</button>
|
|
119
|
+
</div>
|
|
120
|
+
</div>
|
|
121
|
+
</template>
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## Angular
|
|
125
|
+
|
|
126
|
+
```ts
|
|
127
|
+
import { Component } from '@angular/core'
|
|
128
|
+
import { AbstractService } from '@pravosleva/reactive-engine'
|
|
129
|
+
import { ReactiveEngine as ReactiveEngine4Angular } from '@pravosleva/reactive-engine/angular'
|
|
130
|
+
|
|
131
|
+
// 1. Описываем изолированную бизнес-логику (Ядро/Сервис) — код 1-в-1 как в React/Vue
|
|
132
|
+
class CounterLogic extends AbstractService {
|
|
133
|
+
public counter = this.engine.signal<number>(0, 'angular-example:counter');
|
|
134
|
+
|
|
135
|
+
public inc = () => {
|
|
136
|
+
this.counter.value += 1;
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
@Component({
|
|
141
|
+
selector: 'app-counter-example',
|
|
142
|
+
standalone: true,
|
|
143
|
+
// В шаблоне Angular Signals вызываются как функции: counter()
|
|
144
|
+
template: `
|
|
145
|
+
<div class="unit stack2">
|
|
146
|
+
<div class="absoluteUnitLabel">Angular 16+ Signal Example</div>
|
|
147
|
+
<code>{{ counter() }}</code>
|
|
148
|
+
<div class="catSection">
|
|
149
|
+
<button (click)="logic.inc()" class="btn neonBtn neonBtn--primary neonBtn--outlined">
|
|
150
|
+
INC (Angular)
|
|
151
|
+
</button>
|
|
152
|
+
</div>
|
|
153
|
+
</div>
|
|
154
|
+
`,
|
|
155
|
+
styleUrls: ['./ui.common.module.scss', './ui.button.module.scss'] // Ваши SCSS стили
|
|
156
|
+
})
|
|
157
|
+
export class AngularCounterComponent {
|
|
158
|
+
// 2. Инициализируем Angular-версию движка
|
|
159
|
+
private engine = new ReactiveEngine4Angular();
|
|
160
|
+
|
|
161
|
+
// 3. Внедряем сервис из DI-контейнера
|
|
162
|
+
public logic = this.engine.inject(CounterLogic);
|
|
163
|
+
|
|
164
|
+
// 4. Превращаем сигнал ядра в нативный Angular Signal через метод .use()
|
|
165
|
+
// Метод inject(DestroyRef) под капотом use() отработает корректно, так как мы находимся в фазе инициализации класса
|
|
166
|
+
public counter = this.engine.use(this.logic.counter);
|
|
167
|
+
}
|
|
168
|
+
```
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
const e=require("../core.cjs");let t=require("@angular/core");var n=class extends e.ReactiveEngine{use(e,n){let r=(0,t.signal)(e.value),i=e.subscribe(e=>{r.set(e)}),a=()=>{(0,t.inject)(t.DestroyRef).onDestroy(()=>{i()})};return n?.injector?(0,t.runInInjectionContext)(n.injector,a):a(),r.asReadonly()}};exports.ReactiveEngine4Angular=n;
|
|
2
|
+
//# sourceMappingURL=ReactiveEngine4Angular.cjs.map
|
|
@@ -0,0 +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 /**\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((newValue) => {\n angularSignal.set(newValue); // Обновляем значение внутри Angular\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,CAKjE,IACE,EACA,EACW,CAEX,IAAM,GAAA,EAAA,EAAA,OAAA,CAA0B,EAAK,KAAK,EAGpC,EAAc,EAAK,UAAW,GAAa,CAC/C,EAAc,IAAI,CAAQ,CAC5B,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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Injector, Signal } from '@angular/core';
|
|
2
|
+
import { ReactiveEngine as OriginalReactiveEngine, CleanupFn } from '../core/core';
|
|
3
|
+
export interface AngularUseOptions {
|
|
4
|
+
/**
|
|
5
|
+
* Кастомный инжектор Angular.
|
|
6
|
+
* Позволяет использовать .use() вне конструктора (например, в асинхронных функциях),
|
|
7
|
+
* если передать текущий Injector вручную.
|
|
8
|
+
*/
|
|
9
|
+
injector?: Injector;
|
|
10
|
+
}
|
|
11
|
+
export declare class ReactiveEngine4Angular extends OriginalReactiveEngine {
|
|
12
|
+
/**
|
|
13
|
+
* Использование реактивного значения в Angular компоненте или сервисе.
|
|
14
|
+
* Возвращает стандартный Angular Signal.
|
|
15
|
+
*/
|
|
16
|
+
use<T>(item: {
|
|
17
|
+
value: T;
|
|
18
|
+
subscribe: (cb: (v: T) => void) => CleanupFn;
|
|
19
|
+
}, options?: AngularUseOptions): Signal<T>;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=ReactiveEngine4Angular.d.ts.map
|
|
@@ -0,0 +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,CAAC;AACzG,OAAO,EAAE,cAAc,IAAI,sBAAsB,EAAE,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AAGxF,MAAM,WAAW,iBAAiB;IAChC;;;;OAIG;IACH,QAAQ,CAAC,EAAE,QAAQ,CAAC;CACrB;AAED,qBAAa,sBAAuB,SAAQ,sBAAsB;IAChE;;;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;CA2Bb"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { ReactiveEngine as e } from "../core.mjs";
|
|
2
|
+
import { DestroyRef as t, inject as n, runInInjectionContext as r, signal as i } from "@angular/core";
|
|
3
|
+
//#region src/angular/ReactiveEngine4Angular.ts
|
|
4
|
+
var a = class extends e {
|
|
5
|
+
use(e, a) {
|
|
6
|
+
let o = i(e.value), s = e.subscribe((e) => {
|
|
7
|
+
o.set(e);
|
|
8
|
+
}), c = () => {
|
|
9
|
+
n(t).onDestroy(() => {
|
|
10
|
+
s();
|
|
11
|
+
});
|
|
12
|
+
};
|
|
13
|
+
return a?.injector ? r(a.injector, c) : c(), o.asReadonly();
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
//#endregion
|
|
17
|
+
export { a as ReactiveEngine4Angular };
|
|
18
|
+
|
|
19
|
+
//# sourceMappingURL=ReactiveEngine4Angular.mjs.map
|
|
@@ -0,0 +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 /**\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((newValue) => {\n angularSignal.set(newValue); // Обновляем значение внутри Angular\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;CAKjE,IACE,GACA,GACW;EAEX,IAAM,IAAgB,EAAU,EAAK,KAAK,GAGpC,IAAc,EAAK,WAAW,MAAa;GAC/C,EAAc,IAAI,CAAQ;EAC5B,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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ReactiveEngine4Angular.test.d.ts","sourceRoot":"","sources":["../../src/angular/ReactiveEngine4Angular.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./ReactiveEngine4Angular.cjs");exports.ReactiveEngine=e.ReactiveEngine4Angular;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/angular/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAA;AAEjE,OAAO,EAAE,sBAAsB,IAAI,cAAc,EAAE,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ReactiveEngine4React.cjs","names":[],"sources":["../../src/react/ReactiveEngine4React.ts"],"sourcesContent":["import { useState as useStateFromReact, useEffect as useEffectFromReact } from 'react'\nimport { ReactiveEngine as OriginalReactiveEngine, CleanupFn } from '../core/core'\n\nexport class ReactiveEngine4React extends OriginalReactiveEngine {\n // Описываем строгие типы для адаптеров React, чтобы не ломать встроенные типы React.\n private reactAdapters: {\n useState: typeof useStateFromReact;\n useEffect: typeof useEffectFromReact;\n } = {\n useState: useStateFromReact,\n useEffect: useEffectFromReact,\n };\n\n /**\n * Установка адаптеров React.\n * @function setReactAdapters\n * @param {Function} useState - Функция useState из React.\n * @param {Function} useEffect - Функция useEffect из React.\n * @returns {void}\n * @source\n */\n public setReactAdapters(\n useState: typeof useStateFromReact,\n useEffect: typeof useEffectFromReact\n ): void {\n this.reactAdapters = { useState, useEffect };\n }\n\n /**\n * Использование реактивного значения в React компоненте.\n * @template T\n * @function use\n * @param {{ value: T; subscribe: (cb: (v: T) => void) => CleanupFn }} item - Реактивный объект.\n * @returns {T} - Значение реактивного объекта.\n * @source\n */\n public use<T>(item: { value: T; subscribe: (cb: (v: T) => void) => CleanupFn }): T {\n if (!this.reactAdapters) {\n throw new Error(\"[React Error]: Адаптеры React не установлены. Вызовите engine.setReactAdapters(useState, useEffect).\");\n }\n\n // NOTE: (защита) проверяем, что нам передали объект сигнала\n if (!item || typeof item.subscribe !== 'function') {\n const errorMsg = `\n [Reactive Error]: engine.use() получил некорректный объект!\n Скорее всего, вы пытаетесь подписаться на свойство сервиса, которое не было инициализировано.\n Проверьте, что в классе написано: public mySignal = this.engine.signal(...)\n `;\n console.error(errorMsg, { item });\n throw new Error(errorMsg);\n }\n const [val, setVal] = this.reactAdapters.useState(item.value);\n\n this.reactAdapters.useEffect(\n () => {\n return item.subscribe(setVal);\n },\n [item]\n );\n\n return val;\n }\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"ReactiveEngine4React.cjs","names":[],"sources":["../../src/react/ReactiveEngine4React.ts"],"sourcesContent":["import { useState as useStateFromReact, useEffect as useEffectFromReact } from 'react'\nimport { ReactiveEngine as OriginalReactiveEngine, CleanupFn } from '../core/core'\n\n/**\n * Класс адаптера для интеграции реактивного движка с React.\n * Наследует функциональность оригинального реактивного движка и предоставляет специализированные методы для работы с React.\n */\nexport class ReactiveEngine4React extends OriginalReactiveEngine {\n // Описываем строгие типы для адаптеров React, чтобы не ломать встроенные типы React.\n private reactAdapters: {\n useState: typeof useStateFromReact;\n useEffect: typeof useEffectFromReact;\n } = {\n useState: useStateFromReact,\n useEffect: useEffectFromReact,\n };\n\n /**\n * Установка адаптеров React.\n * @function setReactAdapters\n * @param {Function} useState - Функция useState из React.\n * @param {Function} useEffect - Функция useEffect из React.\n * @returns {void}\n * @source\n */\n public setReactAdapters(\n useState: typeof useStateFromReact,\n useEffect: typeof useEffectFromReact\n ): void {\n this.reactAdapters = { useState, useEffect };\n }\n\n /**\n * Использование реактивного значения в React компоненте.\n * @template T\n * @function use\n * @param {{ value: T; subscribe: (cb: (v: T) => void) => CleanupFn }} item - Реактивный объект.\n * @returns {T} - Значение реактивного объекта.\n * @source\n */\n public use<T>(item: { value: T; subscribe: (cb: (v: T) => void) => CleanupFn }): T {\n if (!this.reactAdapters) {\n throw new Error(\"[React Error]: Адаптеры React не установлены. Вызовите engine.setReactAdapters(useState, useEffect).\");\n }\n\n // NOTE: (защита) проверяем, что нам передали объект сигнала\n if (!item || typeof item.subscribe !== 'function') {\n const errorMsg = `\n [Reactive Error]: engine.use() получил некорректный объект!\n Скорее всего, вы пытаетесь подписаться на свойство сервиса, которое не было инициализировано.\n Проверьте, что в классе написано: public mySignal = this.engine.signal(...)\n `;\n console.error(errorMsg, { item });\n throw new Error(errorMsg);\n }\n const [val, setVal] = this.reactAdapters.useState(item.value);\n\n this.reactAdapters.useEffect(\n () => {\n return item.subscribe(setVal);\n },\n [item]\n );\n\n return val;\n }\n}\n"],"mappings":"sDAOA,IAAa,EAAb,cAA0C,EAAA,cAAuB,CAE/D,cAGI,CACA,SAAU,EAAA,SACV,UAAW,EAAA,SACb,EAUF,iBACE,EACA,EACM,CACN,KAAK,cAAgB,CAAE,WAAU,WAAU,CAC7C,CAUA,IAAc,EAAqE,CACjF,GAAI,CAAC,KAAK,cACR,MAAU,MAAM,sGAAsG,EAIxH,GAAI,CAAC,GAAQ,OAAO,EAAK,WAAc,WAAY,CACjD,IAAM,EAAW;;;;QAMjB,MADA,QAAQ,MAAM,EAAU,CAAE,MAAK,CAAC,EACtB,MAAM,CAAQ,CAC1B,CACA,GAAM,CAAC,EAAK,GAAU,KAAK,cAAc,SAAS,EAAK,KAAK,EAS5D,OAPA,KAAK,cAAc,cAER,EAAK,UAAU,CAAM,EAE9B,CAAC,CAAI,CACP,EAEO,CACT,CACF"}
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { useState as useStateFromReact, useEffect as useEffectFromReact } from 'react';
|
|
2
2
|
import { ReactiveEngine as OriginalReactiveEngine, CleanupFn } from '../core/core';
|
|
3
|
+
/**
|
|
4
|
+
* Класс адаптера для интеграции реактивного движка с React.
|
|
5
|
+
* Наследует функциональность оригинального реактивного движка и предоставляет специализированные методы для работы с React.
|
|
6
|
+
*/
|
|
3
7
|
export declare class ReactiveEngine4React extends OriginalReactiveEngine {
|
|
4
8
|
private reactAdapters;
|
|
5
9
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ReactiveEngine4React.d.ts","sourceRoot":"","sources":["../../src/react/ReactiveEngine4React.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,IAAI,iBAAiB,EAAE,SAAS,IAAI,kBAAkB,EAAE,MAAM,OAAO,CAAA;AACtF,OAAO,EAAE,cAAc,IAAI,sBAAsB,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AAElF,qBAAa,oBAAqB,SAAQ,sBAAsB;IAE9D,OAAO,CAAC,aAAa,CAMjB;IAEJ;;;;;;;OAOG;IACI,gBAAgB,CACrB,QAAQ,EAAE,OAAO,iBAAiB,EAClC,SAAS,EAAE,OAAO,kBAAkB,GACnC,IAAI;IAIP;;;;;;;OAOG;IACI,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE;QAAE,KAAK,EAAE,CAAC,CAAC;QAAC,SAAS,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,IAAI,KAAK,SAAS,CAAA;KAAE,GAAG,CAAC;CA0BnF"}
|
|
1
|
+
{"version":3,"file":"ReactiveEngine4React.d.ts","sourceRoot":"","sources":["../../src/react/ReactiveEngine4React.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,IAAI,iBAAiB,EAAE,SAAS,IAAI,kBAAkB,EAAE,MAAM,OAAO,CAAA;AACtF,OAAO,EAAE,cAAc,IAAI,sBAAsB,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AAElF;;;GAGG;AACH,qBAAa,oBAAqB,SAAQ,sBAAsB;IAE9D,OAAO,CAAC,aAAa,CAMjB;IAEJ;;;;;;;OAOG;IACI,gBAAgB,CACrB,QAAQ,EAAE,OAAO,iBAAiB,EAClC,SAAS,EAAE,OAAO,kBAAkB,GACnC,IAAI;IAIP;;;;;;;OAOG;IACI,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE;QAAE,KAAK,EAAE,CAAC,CAAC;QAAC,SAAS,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,IAAI,KAAK,SAAS,CAAA;KAAE,GAAG,CAAC;CA0BnF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ReactiveEngine4React.mjs","names":[],"sources":["../../src/react/ReactiveEngine4React.ts"],"sourcesContent":["import { useState as useStateFromReact, useEffect as useEffectFromReact } from 'react'\nimport { ReactiveEngine as OriginalReactiveEngine, CleanupFn } from '../core/core'\n\nexport class ReactiveEngine4React extends OriginalReactiveEngine {\n // Описываем строгие типы для адаптеров React, чтобы не ломать встроенные типы React.\n private reactAdapters: {\n useState: typeof useStateFromReact;\n useEffect: typeof useEffectFromReact;\n } = {\n useState: useStateFromReact,\n useEffect: useEffectFromReact,\n };\n\n /**\n * Установка адаптеров React.\n * @function setReactAdapters\n * @param {Function} useState - Функция useState из React.\n * @param {Function} useEffect - Функция useEffect из React.\n * @returns {void}\n * @source\n */\n public setReactAdapters(\n useState: typeof useStateFromReact,\n useEffect: typeof useEffectFromReact\n ): void {\n this.reactAdapters = { useState, useEffect };\n }\n\n /**\n * Использование реактивного значения в React компоненте.\n * @template T\n * @function use\n * @param {{ value: T; subscribe: (cb: (v: T) => void) => CleanupFn }} item - Реактивный объект.\n * @returns {T} - Значение реактивного объекта.\n * @source\n */\n public use<T>(item: { value: T; subscribe: (cb: (v: T) => void) => CleanupFn }): T {\n if (!this.reactAdapters) {\n throw new Error(\"[React Error]: Адаптеры React не установлены. Вызовите engine.setReactAdapters(useState, useEffect).\");\n }\n\n // NOTE: (защита) проверяем, что нам передали объект сигнала\n if (!item || typeof item.subscribe !== 'function') {\n const errorMsg = `\n [Reactive Error]: engine.use() получил некорректный объект!\n Скорее всего, вы пытаетесь подписаться на свойство сервиса, которое не было инициализировано.\n Проверьте, что в классе написано: public mySignal = this.engine.signal(...)\n `;\n console.error(errorMsg, { item });\n throw new Error(errorMsg);\n }\n const [val, setVal] = this.reactAdapters.useState(item.value);\n\n this.reactAdapters.useEffect(\n () => {\n return item.subscribe(setVal);\n },\n [item]\n );\n\n return val;\n }\n}\n"],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"ReactiveEngine4React.mjs","names":[],"sources":["../../src/react/ReactiveEngine4React.ts"],"sourcesContent":["import { useState as useStateFromReact, useEffect as useEffectFromReact } from 'react'\nimport { ReactiveEngine as OriginalReactiveEngine, CleanupFn } from '../core/core'\n\n/**\n * Класс адаптера для интеграции реактивного движка с React.\n * Наследует функциональность оригинального реактивного движка и предоставляет специализированные методы для работы с React.\n */\nexport class ReactiveEngine4React extends OriginalReactiveEngine {\n // Описываем строгие типы для адаптеров React, чтобы не ломать встроенные типы React.\n private reactAdapters: {\n useState: typeof useStateFromReact;\n useEffect: typeof useEffectFromReact;\n } = {\n useState: useStateFromReact,\n useEffect: useEffectFromReact,\n };\n\n /**\n * Установка адаптеров React.\n * @function setReactAdapters\n * @param {Function} useState - Функция useState из React.\n * @param {Function} useEffect - Функция useEffect из React.\n * @returns {void}\n * @source\n */\n public setReactAdapters(\n useState: typeof useStateFromReact,\n useEffect: typeof useEffectFromReact\n ): void {\n this.reactAdapters = { useState, useEffect };\n }\n\n /**\n * Использование реактивного значения в React компоненте.\n * @template T\n * @function use\n * @param {{ value: T; subscribe: (cb: (v: T) => void) => CleanupFn }} item - Реактивный объект.\n * @returns {T} - Значение реактивного объекта.\n * @source\n */\n public use<T>(item: { value: T; subscribe: (cb: (v: T) => void) => CleanupFn }): T {\n if (!this.reactAdapters) {\n throw new Error(\"[React Error]: Адаптеры React не установлены. Вызовите engine.setReactAdapters(useState, useEffect).\");\n }\n\n // NOTE: (защита) проверяем, что нам передали объект сигнала\n if (!item || typeof item.subscribe !== 'function') {\n const errorMsg = `\n [Reactive Error]: engine.use() получил некорректный объект!\n Скорее всего, вы пытаетесь подписаться на свойство сервиса, которое не было инициализировано.\n Проверьте, что в классе написано: public mySignal = this.engine.signal(...)\n `;\n console.error(errorMsg, { item });\n throw new Error(errorMsg);\n }\n const [val, setVal] = this.reactAdapters.useState(item.value);\n\n this.reactAdapters.useEffect(\n () => {\n return item.subscribe(setVal);\n },\n [item]\n );\n\n return val;\n }\n}\n"],"mappings":";;;AAOA,IAAa,IAAb,cAA0C,EAAuB;CAE/D,gBAGI;EACU;EACC;CACb;CAUF,iBACE,GACA,GACM;EACN,KAAK,gBAAgB;GAAE;GAAU;EAAU;CAC7C;CAUA,IAAc,GAAqE;EACjF,IAAI,CAAC,KAAK,eACR,MAAU,MAAM,sGAAsG;EAIxH,IAAI,CAAC,KAAQ,OAAO,EAAK,aAAc,YAAY;GACjD,IAAM,IAAW;GAMjB,MADA,QAAQ,MAAM,GAAU,EAAE,QAAK,CAAC,GACtB,MAAM,CAAQ;EAC1B;EACA,IAAM,CAAC,GAAK,KAAU,KAAK,cAAc,SAAS,EAAK,KAAK;EAS5D,OAPA,KAAK,cAAc,gBAER,EAAK,UAAU,CAAM,GAE9B,CAAC,CAAI,CACP,GAEO;CACT;AACF"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
const e=require("../core.cjs");let t=require("vue");var n=class extends e.ReactiveEngine{use(e){let n=(0,t.shallowRef)(e.value),r=e.subscribe(e=>{n.value=e,(0,t.triggerRef)(n)});return(0,t.getCurrentInstance)()?(0,t.onUnmounted)(()=>{r()}):(0,t.getCurrentScope)()&&(0,t.onScopeDispose)(()=>{r()}),n}};exports.ReactiveEngine4Vue=n;
|
|
2
|
+
//# sourceMappingURL=ReactiveEngine4Vue.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ReactiveEngine4Vue.cjs","names":[],"sources":["../../src/vue/ReactiveEngine4Vue.ts"],"sourcesContent":["import { shallowRef, onUnmounted, getCurrentInstance, getCurrentScope, onScopeDispose, triggerRef, type ShallowRef } from 'vue'\nimport { ReactiveEngine as OriginalReactiveEngine, type CleanupFn } from '../core/core'\n\nexport class ReactiveEngine4Vue extends OriginalReactiveEngine {\n /**\n * Использование реактивного значения в Vue компоненте или EffectScope.\n */\n public use<T>(item: { value: T; subscribe: (cb: (v: T) => void) => CleanupFn }): ShallowRef<T> {\n // Создаем локальную Vue-реактивную обертку со стартовым значением сигнала\n const state = shallowRef(item.value)\n\n // Подписываемся на изменения сигнала ядра\n const unsubscribe = item.subscribe((newValue) => {\n state.value = newValue // Обновляем Vue-реактивную переменную\n triggerRef(state) // 👈 ПРИНУДИТЕЛЬНО заставляем Vue перерисовать шаблон\n })\n\n // Проверяем наличие активного компонента ИЛИ active области видимости эффектов\n\n // 1. Если мы находимся внутри жизненного цикла компонента Vue (setup)\n if (getCurrentInstance()) {\n // Автоматически отписываемся при размонтировании Vue-компонента\n onUnmounted(() => {\n unsubscribe()\n })\n }\n // 2. Иначе, если мы находимся внутри изолированного EffectScope (например, в Pinia или в тестах)\n else if (getCurrentScope()) {\n onScopeDispose(() => {\n unsubscribe()\n })\n }\n\n return state\n }\n}\n"],"mappings":"oDAGA,IAAa,EAAb,cAAwC,EAAA,cAAuB,CAI7D,IAAc,EAAiF,CAE7F,IAAM,GAAA,EAAA,EAAA,WAAA,CAAmB,EAAK,KAAK,EAG7B,EAAc,EAAK,UAAW,GAAa,CAC/C,EAAM,MAAQ,GACd,EAAA,EAAA,WAAA,CAAW,CAAK,CAClB,CAAC,EAkBD,OAbA,EAAA,EAAA,mBAAA,CAAuB,GAErB,EAAA,EAAA,YAAA,KAAkB,CAChB,EAAY,CACd,CAAC,GAGE,EAAA,EAAA,gBAAA,CAAoB,IACvB,EAAA,EAAA,eAAA,KAAqB,CACnB,EAAY,CACd,CAAC,EAGI,CACT,CACF"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { ShallowRef } from 'vue';
|
|
2
|
+
import { ReactiveEngine as OriginalReactiveEngine, CleanupFn } from '../core/core';
|
|
3
|
+
export declare class ReactiveEngine4Vue extends OriginalReactiveEngine {
|
|
4
|
+
/**
|
|
5
|
+
* Использование реактивного значения в Vue компоненте или EffectScope.
|
|
6
|
+
*/
|
|
7
|
+
use<T>(item: {
|
|
8
|
+
value: T;
|
|
9
|
+
subscribe: (cb: (v: T) => void) => CleanupFn;
|
|
10
|
+
}): ShallowRef<T>;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=ReactiveEngine4Vue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ReactiveEngine4Vue.d.ts","sourceRoot":"","sources":["../../src/vue/ReactiveEngine4Vue.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4F,KAAK,UAAU,EAAE,MAAM,KAAK,CAAA;AAC/H,OAAO,EAAE,cAAc,IAAI,sBAAsB,EAAE,KAAK,SAAS,EAAE,MAAM,cAAc,CAAA;AAEvF,qBAAa,kBAAmB,SAAQ,sBAAsB;IAC5D;;OAEG;IACI,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE;QAAE,KAAK,EAAE,CAAC,CAAC;QAAC,SAAS,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,IAAI,KAAK,SAAS,CAAA;KAAE,GAAG,UAAU,CAAC,CAAC,CAAC;CA4B/F"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { ReactiveEngine as e } from "../core.mjs";
|
|
2
|
+
import { getCurrentInstance as t, getCurrentScope as n, onScopeDispose as r, onUnmounted as i, shallowRef as a, triggerRef as o } from "vue";
|
|
3
|
+
//#region src/vue/ReactiveEngine4Vue.ts
|
|
4
|
+
var s = class extends e {
|
|
5
|
+
use(e) {
|
|
6
|
+
let s = a(e.value), c = e.subscribe((e) => {
|
|
7
|
+
s.value = e, o(s);
|
|
8
|
+
});
|
|
9
|
+
return t() ? i(() => {
|
|
10
|
+
c();
|
|
11
|
+
}) : n() && r(() => {
|
|
12
|
+
c();
|
|
13
|
+
}), s;
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
//#endregion
|
|
17
|
+
export { s as ReactiveEngine4Vue };
|
|
18
|
+
|
|
19
|
+
//# sourceMappingURL=ReactiveEngine4Vue.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ReactiveEngine4Vue.mjs","names":[],"sources":["../../src/vue/ReactiveEngine4Vue.ts"],"sourcesContent":["import { shallowRef, onUnmounted, getCurrentInstance, getCurrentScope, onScopeDispose, triggerRef, type ShallowRef } from 'vue'\nimport { ReactiveEngine as OriginalReactiveEngine, type CleanupFn } from '../core/core'\n\nexport class ReactiveEngine4Vue extends OriginalReactiveEngine {\n /**\n * Использование реактивного значения в Vue компоненте или EffectScope.\n */\n public use<T>(item: { value: T; subscribe: (cb: (v: T) => void) => CleanupFn }): ShallowRef<T> {\n // Создаем локальную Vue-реактивную обертку со стартовым значением сигнала\n const state = shallowRef(item.value)\n\n // Подписываемся на изменения сигнала ядра\n const unsubscribe = item.subscribe((newValue) => {\n state.value = newValue // Обновляем Vue-реактивную переменную\n triggerRef(state) // 👈 ПРИНУДИТЕЛЬНО заставляем Vue перерисовать шаблон\n })\n\n // Проверяем наличие активного компонента ИЛИ active области видимости эффектов\n\n // 1. Если мы находимся внутри жизненного цикла компонента Vue (setup)\n if (getCurrentInstance()) {\n // Автоматически отписываемся при размонтировании Vue-компонента\n onUnmounted(() => {\n unsubscribe()\n })\n }\n // 2. Иначе, если мы находимся внутри изолированного EffectScope (например, в Pinia или в тестах)\n else if (getCurrentScope()) {\n onScopeDispose(() => {\n unsubscribe()\n })\n }\n\n return state\n }\n}\n"],"mappings":";;;AAGA,IAAa,IAAb,cAAwC,EAAuB;CAI7D,IAAc,GAAiF;EAE7F,IAAM,IAAQ,EAAW,EAAK,KAAK,GAG7B,IAAc,EAAK,WAAW,MAAa;GAE/C,AADA,EAAM,QAAQ,GACd,EAAW,CAAK;EAClB,CAAC;EAkBD,OAbI,EAAmB,IAErB,QAAkB;GAChB,EAAY;EACd,CAAC,IAGM,EAAgB,KACvB,QAAqB;GACnB,EAAY;EACd,CAAC,GAGI;CACT;AACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ReactiveEngine4Vue.test.d.ts","sourceRoot":"","sources":["../../src/vue/ReactiveEngine4Vue.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./ReactiveEngine4Vue.cjs");exports.ReactiveEngine=e.ReactiveEngine4Vue;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/vue/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,IAAI,cAAc,EAAE,MAAM,sBAAsB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pravosleva/reactive-engine",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.2-beta",
|
|
4
4
|
"engines": {
|
|
5
5
|
"node": ">=22.20.0"
|
|
6
6
|
},
|
|
@@ -34,6 +34,16 @@
|
|
|
34
34
|
"import": "./dist/react/index.mjs",
|
|
35
35
|
"require": "./dist/react/index.cjs"
|
|
36
36
|
},
|
|
37
|
+
"./vue": {
|
|
38
|
+
"types": "./dist/vue/index.d.ts",
|
|
39
|
+
"import": "./dist/vue/index.mjs",
|
|
40
|
+
"require": "./dist/vue/index.cjs"
|
|
41
|
+
},
|
|
42
|
+
"./angular": {
|
|
43
|
+
"types": "./dist/angular/index.d.ts",
|
|
44
|
+
"import": "./dist/angular/index.mjs",
|
|
45
|
+
"require": "./dist/angular/index.cjs"
|
|
46
|
+
},
|
|
37
47
|
"./package.json": "./package.json"
|
|
38
48
|
},
|
|
39
49
|
"files": [
|
|
@@ -54,8 +64,10 @@
|
|
|
54
64
|
"docs:preview": "vitepress preview docs"
|
|
55
65
|
},
|
|
56
66
|
"peerDependencies": {
|
|
67
|
+
"@angular/core": ">=16.0.0",
|
|
57
68
|
"react": "^18.0.0 || ^19.2.0",
|
|
58
|
-
"react-dom": "^18.0.0 || ^19.2.0"
|
|
69
|
+
"react-dom": "^18.0.0 || ^19.2.0",
|
|
70
|
+
"vue": ">=3.2.0"
|
|
59
71
|
},
|
|
60
72
|
"peerDependenciesMeta": {
|
|
61
73
|
"react": {
|
|
@@ -63,9 +75,16 @@
|
|
|
63
75
|
},
|
|
64
76
|
"react-dom": {
|
|
65
77
|
"optional": true
|
|
78
|
+
},
|
|
79
|
+
"vue": {
|
|
80
|
+
"optional": true
|
|
81
|
+
},
|
|
82
|
+
"@angular/core": {
|
|
83
|
+
"optional": true
|
|
66
84
|
}
|
|
67
85
|
},
|
|
68
86
|
"devDependencies": {
|
|
87
|
+
"@angular/core": "^22.1.1",
|
|
69
88
|
"@googlemaps/js-api-loader": "^2.1.1",
|
|
70
89
|
"@googlemaps/markerclusterer": "^2.6.2",
|
|
71
90
|
"@microsoft/api-extractor": "^7.58.9",
|
|
@@ -79,7 +98,10 @@
|
|
|
79
98
|
"@types/react-dom": "^19.2.0",
|
|
80
99
|
"@types/three": "^0.185.1",
|
|
81
100
|
"@vitejs/plugin-react": "^5.0.4",
|
|
101
|
+
"@vitejs/plugin-vue": "^6.0.8",
|
|
82
102
|
"@vitest/ui": "^4.1.10",
|
|
103
|
+
"@vue/language-core": "^3.3.9",
|
|
104
|
+
"@vue/test-utils": "^2.4.11",
|
|
83
105
|
"@yandex/ymaps3-clusterer": "^0.0.12",
|
|
84
106
|
"clsx": "^2.1.1",
|
|
85
107
|
"eslint-plugin-import-x": "^4.17.1",
|