@qorejs/qore 1.0.6 → 2.0.0
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/MIGRATION.md +124 -0
- package/README.md +70 -40
- package/README.zh-CN.md +24 -12
- package/dist/src/core/response-types.d.ts +6 -2
- package/dist/src/core/response-types.d.ts.map +1 -1
- package/dist/src/core/stream-types.d.ts +18 -2
- package/dist/src/core/stream-types.d.ts.map +1 -1
- package/dist/src/core/stream.d.ts +1 -1
- package/dist/src/core/stream.d.ts.map +1 -1
- package/dist/src/core/stream.js +123 -9
- package/dist/src/core/stream.js.map +1 -1
- package/dist/src/dom.d.ts +6 -0
- package/dist/src/dom.d.ts.map +1 -0
- package/dist/src/dom.js +5 -0
- package/dist/src/dom.js.map +1 -0
- package/dist/src/index.d.ts +3 -18
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +0 -12
- package/dist/src/index.js.map +1 -1
- package/dist/src/providers.d.ts +8 -0
- package/dist/src/providers.d.ts.map +1 -0
- package/dist/src/providers.js +8 -0
- package/dist/src/providers.js.map +1 -0
- package/dist/src/react.d.ts +63 -0
- package/dist/src/react.d.ts.map +1 -0
- package/dist/src/react.js +123 -0
- package/dist/src/react.js.map +1 -0
- package/dist/src/server.d.ts +3 -0
- package/dist/src/server.d.ts.map +1 -0
- package/dist/src/server.js +3 -0
- package/dist/src/server.js.map +1 -0
- package/dist/src/shared/utils.d.ts +2 -1
- package/dist/src/shared/utils.d.ts.map +1 -1
- package/dist/src/shared/utils.js.map +1 -1
- package/dist/src/signals.d.ts +4 -0
- package/dist/src/signals.d.ts.map +1 -0
- package/dist/src/signals.js +3 -0
- package/dist/src/signals.js.map +1 -0
- package/docs/api.md +42 -7
- package/docs/architecture.md +36 -34
- package/docs/comparisons.md +23 -20
- package/docs/concepts.md +6 -14
- package/docs/providers.md +19 -1
- package/docs/react.md +23 -7
- package/docs/runtime.md +49 -0
- package/package.json +35 -4
package/docs/architecture.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Architecture
|
|
2
2
|
|
|
3
|
-
Qore
|
|
3
|
+
Qore owns streamed state. Host frameworks own rendering and component lifecycle.
|
|
4
4
|
|
|
5
5
|
```text
|
|
6
6
|
Provider / AsyncIterable
|
|
@@ -9,49 +9,51 @@ Provider / AsyncIterable
|
|
|
9
9
|
Qore Stream Runtime
|
|
10
10
|
|
|
|
11
11
|
v
|
|
12
|
-
Readonly
|
|
12
|
+
Readonly state + subscriptions
|
|
13
13
|
|
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
+--> React adapter --> React components
|
|
15
|
+
+--> Host framework integration
|
|
16
|
+
+--> Optional DOM renderer --> text nodes
|
|
16
17
|
```
|
|
17
18
|
|
|
18
|
-
##
|
|
19
|
-
|
|
20
|
-
Providers expose streaming data as async iterables. Qore ships adapters for OpenAI, Anthropic, OpenRouter, DeepSeek, Ollama, generic SSE, and generic line-delimited streams.
|
|
21
|
-
|
|
22
|
-
Adapters should run on the server or another trusted runtime when they need API keys.
|
|
23
|
-
|
|
24
|
-
## Stream Runtime
|
|
19
|
+
## Package boundaries
|
|
25
20
|
|
|
26
|
-
|
|
21
|
+
- `@qorejs/qore`: accumulation, stream lifecycle, event projections, backpressure,
|
|
22
|
+
async iteration, and stream inspection.
|
|
23
|
+
- `@qorejs/qore/react`: React external-store hooks with cached snapshots and cleanup.
|
|
24
|
+
- `@qorejs/qore/dom`: optional browser-only rendering, lists, mounting and DOM properties.
|
|
25
|
+
- `@qorejs/qore/signals`: optional mutable signals, computed values, effects and scopes.
|
|
26
|
+
- `@qorejs/qore/providers`: optional vendor and generic SSE/NDJSON adapters.
|
|
27
|
+
- `@qorejs/qore/server`: optional SSE response serialization.
|
|
27
28
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
-
|
|
31
|
-
- backpressure buffering
|
|
32
|
-
- async iterator bridging
|
|
33
|
-
- reducer-based accumulation
|
|
34
|
-
- development-time stream inspection through `globalThis.__QORE_DEVTOOLS__`
|
|
29
|
+
These are independently importable subpaths in one package. Core has no runtime
|
|
30
|
+
import of DOM, provider, server or React entrypoints. React is an optional peer,
|
|
31
|
+
so non-React users do not need to install it.
|
|
35
32
|
|
|
36
|
-
##
|
|
37
|
-
|
|
38
|
-
Every `QoreStream` is a readonly signal:
|
|
39
|
-
|
|
40
|
-
```js
|
|
41
|
-
const answer = stream(model.chat('hello'));
|
|
42
|
-
answer();
|
|
43
|
-
```
|
|
33
|
+
## Internal state
|
|
44
34
|
|
|
45
|
-
|
|
35
|
+
The runtime still uses the existing reactive engine internally. Moving its public
|
|
36
|
+
UI primitives to `/signals` avoids requiring applications to adopt a second state
|
|
37
|
+
API. It does not claim that dependency tracking has been removed from the runtime.
|
|
38
|
+
The DOM renderer and stream core share the same engine instance.
|
|
46
39
|
|
|
47
|
-
|
|
40
|
+
Streams expose readonly values through `answer()`, `peek()` and `subscribe()`;
|
|
41
|
+
applications cannot write the runtime-owned lifecycle fields. Subscription cleanup
|
|
42
|
+
and stream cancellation are distinct: observing an externally owned stream does
|
|
43
|
+
not transfer ownership. The React managed hook aborts the streams it creates.
|
|
48
44
|
|
|
49
|
-
|
|
45
|
+
## Integration boundaries
|
|
50
46
|
|
|
51
|
-
|
|
47
|
+
Provider API keys belong on a server or trusted runtime. Browsers consume an
|
|
48
|
+
application endpoint. `/server` can serialize that endpoint as SSE.
|
|
52
49
|
|
|
53
|
-
|
|
50
|
+
React supplies its renderer and hydration. Managed hooks start work in client
|
|
51
|
+
effects; snapshot hooks provide deterministic server fallbacks. Qore's optional
|
|
52
|
+
DOM renderer has no SSR or hydration implementation, and adding a full framework
|
|
53
|
+
stack is outside the current roadmap.
|
|
54
54
|
|
|
55
|
-
|
|
55
|
+
## Resource limits
|
|
56
56
|
|
|
57
|
-
|
|
57
|
+
`maxItems` bounds collection values, not full chunk history or iterator backlog.
|
|
58
|
+
Backpressure governs the producer buffer. Do not treat either option as a total
|
|
59
|
+
memory bound; retention and multicasting semantics remain separate runtime work.
|
package/docs/comparisons.md
CHANGED
|
@@ -1,35 +1,38 @@
|
|
|
1
1
|
# Comparisons
|
|
2
2
|
|
|
3
|
-
Qore
|
|
3
|
+
Qore focuses on streamed interface state and integrates with existing UI frameworks.
|
|
4
4
|
|
|
5
5
|
## React / Vercel AI SDK
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
The Qore React adapter exposes streams through `useSyncExternalStore`. Updates
|
|
8
|
+
still use React rendering and reconciliation. Qore adds stream lifecycle and event
|
|
9
|
+
projection contracts; it does not make React render like a direct DOM renderer.
|
|
8
10
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
Token -> Hook state -> Component render -> Reconcile
|
|
11
|
+
The optional `/dom` renderer can update a dependent text node directly. That is a
|
|
12
|
+
separate integration path, not a property of all Qore integrations.
|
|
12
13
|
|
|
13
|
-
|
|
14
|
-
Token -> Stream signal -> Text node
|
|
15
|
-
```
|
|
14
|
+
## Solid and Vue
|
|
16
15
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
Solid has excellent fine-grained reactivity. Qore's difference is the native stream primitive: a stream is already a signal and an async iterable.
|
|
22
|
-
|
|
23
|
-
## Vue
|
|
24
|
-
|
|
25
|
-
Vue refs are ergonomic, but provider streams still need to be adapted into state by user code. Qore makes that adaptation the default primitive.
|
|
16
|
+
Their reactive systems already own application state and rendering. Applications
|
|
17
|
+
can bridge Qore subscriptions into native signals or refs and dispose subscriptions
|
|
18
|
+
with their framework lifecycle. They do not need Qore's optional `/signals` or
|
|
19
|
+
`/dom` APIs. Qore's responsibility is stream consumption and lifecycle.
|
|
26
20
|
|
|
27
21
|
## RxJS
|
|
28
22
|
|
|
29
|
-
|
|
23
|
+
Stream composition overlaps with observable libraries. Qore's particular contract
|
|
24
|
+
combines the current accumulated value, subscriptions, async iteration and lifecycle.
|
|
25
|
+
Choose based on required stream semantics and integration costs.
|
|
30
26
|
|
|
31
27
|
## When Not To Use Qore
|
|
32
28
|
|
|
33
|
-
|
|
29
|
+
An existing application with adequate stream handling may not need another runtime.
|
|
30
|
+
Qore does not provide routing, forms, an application component ecosystem, or its own
|
|
31
|
+
SSR/hydration stack. The standalone DOM renderer is optional.
|
|
32
|
+
|
|
33
|
+
## Benchmark Language
|
|
34
34
|
|
|
35
|
-
|
|
35
|
+
The current benchmark compares fine-grained stream updates with snapshot-style
|
|
36
|
+
transcript rewrites. It is not an optimized React, Vue or Solid comparison and does
|
|
37
|
+
not establish a framework-wide performance ranking. Measure real workloads,
|
|
38
|
+
including parsing, rendering, interaction latency and retained memory.
|
package/docs/concepts.md
CHANGED
|
@@ -10,19 +10,9 @@ A stream is how data moves. A signal is how UI reacts. Qore treats them as one r
|
|
|
10
10
|
|
|
11
11
|
## The Problem
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
fetch -> state snapshot -> render
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
AI and realtime interfaces are different. The useful data often arrives as a sequence:
|
|
20
|
-
|
|
21
|
-
```text
|
|
22
|
-
token -> token -> tool event -> status -> token -> done
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
If each chunk has to be copied into component state, reconciled, and rerendered as a transcript snapshot, the runtime path becomes wider than the problem needs.
|
|
13
|
+
AI and realtime interfaces receive sequences of tokens, tool events, status,
|
|
14
|
+
diffs and terminal events. A runtime can centralize accumulation and lifecycle
|
|
15
|
+
while the existing UI framework continues to manage components and rendering.
|
|
26
16
|
|
|
27
17
|
## The Qore Model
|
|
28
18
|
|
|
@@ -43,9 +33,11 @@ The same value is:
|
|
|
43
33
|
- an async iterable
|
|
44
34
|
- a lifecycle-aware stream state
|
|
45
35
|
|
|
46
|
-
|
|
36
|
+
The optional `@qorejs/qore/dom` renderer can bind directly to streamed data:
|
|
47
37
|
|
|
48
38
|
```js
|
|
39
|
+
import { h, text } from '@qorejs/qore/dom';
|
|
40
|
+
|
|
49
41
|
h('article', {}, text(() => answer()));
|
|
50
42
|
```
|
|
51
43
|
|
package/docs/providers.md
CHANGED
|
@@ -45,7 +45,8 @@ Supported adapters:
|
|
|
45
45
|
## Example
|
|
46
46
|
|
|
47
47
|
```js
|
|
48
|
-
import { createOpenAI
|
|
48
|
+
import { createOpenAI } from '@qorejs/qore/providers';
|
|
49
|
+
import { stream } from '@qorejs/qore';
|
|
49
50
|
|
|
50
51
|
const openai = createOpenAI({
|
|
51
52
|
apiKey: process.env.OPENAI_API_KEY,
|
|
@@ -56,3 +57,20 @@ const answer = stream(openai.chat('Explain stream = signal'));
|
|
|
56
57
|
```
|
|
57
58
|
|
|
58
59
|
Keep this code on the server when it uses real secrets.
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
## Server Boundary
|
|
63
|
+
|
|
64
|
+
Provider adapters are designed for server-side or otherwise trusted runtimes. A browser application should not receive provider API keys. The recommended production path is:
|
|
65
|
+
|
|
66
|
+
```text
|
|
67
|
+
Browser UI -> your SSE / NDJSON endpoint -> provider adapter -> model provider
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Then the browser consumes your endpoint as a Qore stream:
|
|
71
|
+
|
|
72
|
+
```ts
|
|
73
|
+
const answer = stream(fetch('/api/agent').then((response) => response.body));
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
For a complete application boundary example, see [`examples/server-sse-to-qore-client.ts`](../examples/server-sse-to-qore-client.ts).
|
package/docs/react.md
CHANGED
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
Qore's core runtime is framework-neutral. The React adapter lets React apps consume Qore streams without treating streaming as a special rendering case.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
The hooks ship with Qore 2 at `@qorejs/qore/react`. The separate
|
|
6
|
+
`@qorejs/react` package is an unpublished compatibility wrapper, not an installation requirement.
|
|
6
7
|
|
|
7
8
|
```bash
|
|
8
|
-
|
|
9
|
-
npm i @qorejs/qore @qorejs/react
|
|
9
|
+
npm i @qorejs/qore react react-dom
|
|
10
10
|
```
|
|
11
11
|
|
|
12
12
|
## Why It Exists
|
|
@@ -30,7 +30,7 @@ Use `useQoreStream` when a component owns the stream lifecycle.
|
|
|
30
30
|
|
|
31
31
|
```tsx
|
|
32
32
|
import { stream } from '@qorejs/qore';
|
|
33
|
-
import { useQoreStream } from '@qorejs/react';
|
|
33
|
+
import { useQoreStream } from '@qorejs/qore/react';
|
|
34
34
|
|
|
35
35
|
export function Answer({ prompt }: { prompt: string }) {
|
|
36
36
|
const answer = useQoreStream(
|
|
@@ -57,7 +57,7 @@ Use `useQoreStreamSnapshot` when the stream is created outside React and the com
|
|
|
57
57
|
|
|
58
58
|
```tsx
|
|
59
59
|
import type { QoreStream } from '@qorejs/qore';
|
|
60
|
-
import { useQoreStreamSnapshot } from '@qorejs/react';
|
|
60
|
+
import { useQoreStreamSnapshot } from '@qorejs/qore/react';
|
|
61
61
|
|
|
62
62
|
export function Transcript({ answer }: { answer: QoreStream<string, string> }) {
|
|
63
63
|
const snapshot = useQoreStreamSnapshot(answer, { initialValue: '' });
|
|
@@ -74,7 +74,7 @@ Use `useQoreSignalSelector` when a React component only needs one derived slice
|
|
|
74
74
|
|
|
75
75
|
```tsx
|
|
76
76
|
import type { QoreStream } from '@qorejs/qore';
|
|
77
|
-
import { useQoreSignalSelector } from '@qorejs/react';
|
|
77
|
+
import { useQoreSignalSelector } from '@qorejs/qore/react';
|
|
78
78
|
|
|
79
79
|
function TokenCounter({ answer }: { answer: QoreStream<string, string> }) {
|
|
80
80
|
const tokenCount = useQoreSignalSelector(answer.chunks, (chunks) => chunks.length);
|
|
@@ -90,7 +90,7 @@ Use `useQoreSignal` for any Qore readonly signal.
|
|
|
90
90
|
|
|
91
91
|
```tsx
|
|
92
92
|
import type { ReadonlySignal } from '@qorejs/qore';
|
|
93
|
-
import { useQoreSignal } from '@qorejs/react';
|
|
93
|
+
import { useQoreSignal } from '@qorejs/qore/react';
|
|
94
94
|
|
|
95
95
|
export function Counter({ count }: { count: ReadonlySignal<number> }) {
|
|
96
96
|
const value = useQoreSignal(count);
|
|
@@ -103,3 +103,19 @@ export function Counter({ count }: { count: ReadonlySignal<number> }) {
|
|
|
103
103
|
Provider adapters are still intended for server-side or trusted runtimes. In browser React apps, stream from your own SSE or NDJSON endpoint instead of exposing provider API keys.
|
|
104
104
|
|
|
105
105
|
Keep dependency arrays honest. If the stream factory reads `prompt`, `model`, `conversationId`, or auth/session state, include those values in the dependency list.
|
|
106
|
+
|
|
107
|
+
## Snapshot and rendering contract
|
|
108
|
+
|
|
109
|
+
The adapter caches emitted snapshots so repeated React reads receive the same
|
|
110
|
+
reference, including stream chunk arrays. Subscription setup reads the current
|
|
111
|
+
source through immediate delivery, covering updates between render and subscribe.
|
|
112
|
+
Selectors may use `isEqual` to retain an equivalent selected value.
|
|
113
|
+
|
|
114
|
+
`useQoreStreamSnapshot` uses `initialValue` and idle lifecycle fields during server
|
|
115
|
+
rendering and hydration. Network work for `useQoreStream` starts in an effect on the
|
|
116
|
+
client. For `useQoreSignal` and selectors, supply `getServerSnapshot` when the server
|
|
117
|
+
value differs from the client source. Keep request-specific streams out of shared
|
|
118
|
+
server globals. These hooks do not bypass React rendering.
|
|
119
|
+
|
|
120
|
+
`maxItems` bounds a collection's displayed value, not its retained chunk history
|
|
121
|
+
or iterator queue. This release does not introduce bounded total stream memory.
|
package/docs/runtime.md
CHANGED
|
@@ -50,6 +50,55 @@ stream.switchMap(promptChanges, (prompt) => openai.chat(prompt));
|
|
|
50
50
|
|
|
51
51
|
The composed result is still a stream signal.
|
|
52
52
|
|
|
53
|
+
## Structured JSON
|
|
54
|
+
|
|
55
|
+
AI providers increasingly return structured output as streamed text. Keep that
|
|
56
|
+
boundary reactive too:
|
|
57
|
+
|
|
58
|
+
```ts
|
|
59
|
+
const result = stream.json<{ title: string; items: string[] }>(provider.chat(prompt), {
|
|
60
|
+
validate(value): value is { title: string; items: string[] } {
|
|
61
|
+
return typeof value === 'object'
|
|
62
|
+
&& value !== null
|
|
63
|
+
&& 'title' in value
|
|
64
|
+
&& 'items' in value;
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
result(); // null until valid JSON is available, then the parsed object
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
`stream.json()` parses the accumulated text after each chunk. It publishes valid
|
|
72
|
+
JSON as signal state and fails the stream if the source completes without valid
|
|
73
|
+
JSON. It intentionally does not pretend that arbitrary half-written JSON can be
|
|
74
|
+
parsed safely.
|
|
75
|
+
|
|
76
|
+
For event streams that arrive as line-delimited JSON, use `stream.ndjson()`:
|
|
77
|
+
|
|
78
|
+
```ts
|
|
79
|
+
const events = stream.ndjson<{ type: string; value: unknown }>(agentEvents);
|
|
80
|
+
|
|
81
|
+
events(); // accumulated structured events
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Each valid line is published as a chunk and added to the signal array. Blank
|
|
85
|
+
lines are ignored, and an invalid final line fails the stream while keeping the
|
|
86
|
+
events that were already safely published.
|
|
87
|
+
|
|
88
|
+
## Bounded Collections
|
|
89
|
+
|
|
90
|
+
Agent timelines, logs, and tool-event feeds can run much longer than a chat
|
|
91
|
+
answer. Use `maxItems` when the UI only needs the latest window:
|
|
92
|
+
|
|
93
|
+
```ts
|
|
94
|
+
const timeline = stream.events(agent.run(task), { maxItems: 200 });
|
|
95
|
+
const logs = stream.ndjson(logSource, { maxItems: 500 });
|
|
96
|
+
const rows = stream.list(rowSource, { maxItems: 100 });
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
The current signal value keeps the newest items. Async iteration, chunk history,
|
|
100
|
+
and `chunkCount()` still reflect the full stream lifecycle.
|
|
101
|
+
|
|
53
102
|
## Event Streams
|
|
54
103
|
|
|
55
104
|
Provider streams are only the transport boundary. Agent interfaces need a richer runtime surface: text tokens, tool calls, status updates, reasoning notes, diffs, artifacts, retries, and errors can all be modeled as typed events.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@qorejs/qore",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "Qore is a reactive stream runtime for AI-native interfaces.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/src/index.js",
|
|
@@ -10,14 +10,35 @@
|
|
|
10
10
|
"types": "./dist/src/index.d.ts",
|
|
11
11
|
"import": "./dist/src/index.js"
|
|
12
12
|
},
|
|
13
|
-
"./package.json": "./package.json"
|
|
13
|
+
"./package.json": "./package.json",
|
|
14
|
+
"./signals": {
|
|
15
|
+
"types": "./dist/src/signals.d.ts",
|
|
16
|
+
"import": "./dist/src/signals.js"
|
|
17
|
+
},
|
|
18
|
+
"./dom": {
|
|
19
|
+
"types": "./dist/src/dom.d.ts",
|
|
20
|
+
"import": "./dist/src/dom.js"
|
|
21
|
+
},
|
|
22
|
+
"./providers": {
|
|
23
|
+
"types": "./dist/src/providers.d.ts",
|
|
24
|
+
"import": "./dist/src/providers.js"
|
|
25
|
+
},
|
|
26
|
+
"./server": {
|
|
27
|
+
"types": "./dist/src/server.d.ts",
|
|
28
|
+
"import": "./dist/src/server.js"
|
|
29
|
+
},
|
|
30
|
+
"./react": {
|
|
31
|
+
"types": "./dist/src/react.d.ts",
|
|
32
|
+
"import": "./dist/src/react.js"
|
|
33
|
+
}
|
|
14
34
|
},
|
|
15
35
|
"files": [
|
|
16
36
|
"dist/src",
|
|
17
37
|
"README.md",
|
|
18
38
|
"README.zh-CN.md",
|
|
19
39
|
"docs",
|
|
20
|
-
"LICENSE"
|
|
40
|
+
"LICENSE",
|
|
41
|
+
"MIGRATION.md"
|
|
21
42
|
],
|
|
22
43
|
"sideEffects": false,
|
|
23
44
|
"scripts": {
|
|
@@ -58,7 +79,6 @@
|
|
|
58
79
|
"anthropic",
|
|
59
80
|
"deepseek",
|
|
60
81
|
"ollama",
|
|
61
|
-
"framework",
|
|
62
82
|
"async-iterable"
|
|
63
83
|
],
|
|
64
84
|
"homepage": "https://qorejs.dev/",
|
|
@@ -77,7 +97,18 @@
|
|
|
77
97
|
"@playwright/test": "^1.60.0",
|
|
78
98
|
"@types/node": "^25.6.0",
|
|
79
99
|
"@types/react": "^19.2.17",
|
|
100
|
+
"@types/react-dom": "^19.2.3",
|
|
101
|
+
"esbuild": "^0.25.12",
|
|
80
102
|
"react": "^19.2.7",
|
|
103
|
+
"react-dom": "^19.2.7",
|
|
81
104
|
"typescript": "^6.0.3"
|
|
105
|
+
},
|
|
106
|
+
"peerDependencies": {
|
|
107
|
+
"react": ">=18.2.0"
|
|
108
|
+
},
|
|
109
|
+
"peerDependenciesMeta": {
|
|
110
|
+
"react": {
|
|
111
|
+
"optional": true
|
|
112
|
+
}
|
|
82
113
|
}
|
|
83
114
|
}
|