@qorejs/qore 0.7.0 → 0.7.2

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 (86) hide show
  1. package/README.md +170 -52
  2. package/dist/src/core/iterable.d.ts +1 -0
  3. package/dist/src/core/iterable.js +17 -0
  4. package/dist/src/core/response-runtime.d.ts +2 -0
  5. package/dist/src/core/response-runtime.js +233 -0
  6. package/dist/src/core/response-state.d.ts +3 -0
  7. package/dist/src/core/response-state.js +37 -0
  8. package/dist/src/core/response-types.d.ts +73 -0
  9. package/dist/src/core/response-types.js +1 -0
  10. package/dist/src/core/response.d.ts +4 -0
  11. package/dist/src/core/response.js +26 -0
  12. package/dist/src/core/signal-context.d.ts +10 -0
  13. package/dist/src/core/signal-context.js +69 -0
  14. package/dist/src/core/signal-nodes.d.ts +45 -0
  15. package/dist/src/core/signal-nodes.js +197 -0
  16. package/dist/src/core/signal-scheduler.d.ts +2 -0
  17. package/dist/src/core/signal-scheduler.js +19 -0
  18. package/dist/src/core/signal-types.d.ts +19 -0
  19. package/dist/src/core/signal-types.js +1 -0
  20. package/dist/src/core/signal.d.ts +19 -0
  21. package/dist/src/core/signal.js +41 -0
  22. package/dist/src/core/stream-backpressure.d.ts +3 -0
  23. package/dist/src/core/stream-backpressure.js +36 -0
  24. package/dist/src/core/stream-buffer.d.ts +17 -0
  25. package/dist/src/core/stream-buffer.js +162 -0
  26. package/dist/src/core/stream-iterator.d.ts +6 -0
  27. package/dist/src/core/stream-iterator.js +14 -0
  28. package/dist/src/core/stream-lifecycle.d.ts +10 -0
  29. package/dist/src/core/stream-lifecycle.js +28 -0
  30. package/dist/src/core/stream-queue.d.ts +17 -0
  31. package/dist/src/core/stream-queue.js +62 -0
  32. package/dist/src/core/stream-runtime.d.ts +2 -0
  33. package/dist/src/core/stream-runtime.js +127 -0
  34. package/dist/src/core/stream-source.d.ts +2 -0
  35. package/dist/src/core/stream-source.js +28 -0
  36. package/dist/src/core/stream-state.d.ts +4 -0
  37. package/dist/src/core/stream-state.js +20 -0
  38. package/dist/src/core/stream-types.d.ts +61 -0
  39. package/dist/src/core/stream-types.js +1 -0
  40. package/dist/src/core/stream.d.ts +11 -0
  41. package/dist/src/core/stream.js +90 -0
  42. package/dist/src/dom/app.d.ts +38 -0
  43. package/dist/src/dom/app.js +102 -0
  44. package/dist/src/dom/dom.d.ts +13 -0
  45. package/dist/src/dom/dom.js +197 -0
  46. package/dist/src/dom/properties.d.ts +3 -0
  47. package/dist/src/dom/properties.js +147 -0
  48. package/dist/src/dom/reactive.d.ts +6 -0
  49. package/dist/src/dom/reactive.js +14 -0
  50. package/dist/src/dom/response-view.d.ts +4 -0
  51. package/dist/src/dom/response-view.js +37 -0
  52. package/dist/src/dom/scope.d.ts +10 -0
  53. package/dist/src/dom/scope.js +49 -0
  54. package/dist/src/dom/types.d.ts +34 -0
  55. package/dist/src/dom/types.js +1 -0
  56. package/dist/src/index.d.ts +16 -0
  57. package/dist/src/index.js +10 -0
  58. package/dist/src/providers/anthropic.d.ts +2 -0
  59. package/dist/src/providers/anthropic.js +102 -0
  60. package/dist/src/providers/openai.d.ts +2 -0
  61. package/dist/src/providers/openai.js +96 -0
  62. package/dist/src/providers/sse-adapter.d.ts +2 -0
  63. package/dist/src/providers/sse-adapter.js +83 -0
  64. package/dist/src/providers/sse-env.d.ts +4 -0
  65. package/dist/src/providers/sse-env.js +33 -0
  66. package/dist/src/providers/sse-parser.d.ts +5 -0
  67. package/dist/src/providers/sse-parser.js +99 -0
  68. package/dist/src/providers/sse.d.ts +4 -0
  69. package/dist/src/providers/sse.js +3 -0
  70. package/dist/src/providers/types.d.ts +94 -0
  71. package/dist/src/providers/types.js +1 -0
  72. package/dist/src/shared/utils.d.ts +2 -0
  73. package/dist/src/shared/utils.js +32 -0
  74. package/package.json +25 -11
  75. package/src/anthropic.js +0 -122
  76. package/src/app.js +0 -123
  77. package/src/dom.js +0 -527
  78. package/src/index.d.ts +0 -405
  79. package/src/index.js +0 -10
  80. package/src/iterable.js +0 -20
  81. package/src/openai.js +0 -112
  82. package/src/response.js +0 -312
  83. package/src/signal.js +0 -328
  84. package/src/sse.js +0 -264
  85. package/src/stream.js +0 -582
  86. package/src/utils.js +0 -39
@@ -0,0 +1,73 @@
1
+ import type { ComputedSignal, Signal } from './signal.js';
2
+ export type MaybePromise<T> = T | Promise<T>;
3
+ export type ResponseStatus = 'idle' | 'pending' | 'streaming' | 'completed' | 'error' | 'aborted';
4
+ export type GlobalAbortSignal = typeof globalThis extends {
5
+ AbortSignal: infer T;
6
+ } ? T extends {
7
+ prototype: infer P;
8
+ } ? P : unknown : {
9
+ aborted: boolean;
10
+ reason?: unknown;
11
+ };
12
+ export interface ResponseSnapshot<TChunk = unknown, TValue = unknown> {
13
+ status: ResponseStatus;
14
+ value: TValue;
15
+ error: Error | null;
16
+ chunks: TChunk[];
17
+ startedAt: number | null;
18
+ finishedAt: number | null;
19
+ chunkCount: number;
20
+ }
21
+ export interface ResponseRunOptions<TValue> {
22
+ resetValue?: boolean;
23
+ nextSeed?: TValue;
24
+ }
25
+ export type SourceLike<T> = T | Iterable<T> | AsyncIterable<T> | null | undefined;
26
+ export interface ResponseReactiveState<TChunk, TValue> {
27
+ status: Signal<ResponseStatus>;
28
+ value: Signal<TValue>;
29
+ error: Signal<Error | null>;
30
+ chunks: Signal<TChunk[]>;
31
+ startedAt: Signal<number | null>;
32
+ finishedAt: Signal<number | null>;
33
+ pending: ComputedSignal<boolean>;
34
+ streaming: ComputedSignal<boolean>;
35
+ completed: ComputedSignal<boolean>;
36
+ failed: ComputedSignal<boolean>;
37
+ aborted: ComputedSignal<boolean>;
38
+ chunkCount: ComputedSignal<number>;
39
+ }
40
+ export interface ResponseConsumeContext<TChunk, TValue> {
41
+ signal: GlobalAbortSignal;
42
+ response: ResponseState<TChunk, TValue>;
43
+ }
44
+ export interface ResponseExecutorContext<TChunk, TValue> {
45
+ readonly signal: GlobalAbortSignal;
46
+ response: ResponseState<TChunk, TValue>;
47
+ push(chunk: TChunk): TValue;
48
+ complete(): TValue;
49
+ fail(reason?: unknown): Error | TValue;
50
+ abort(reason?: unknown): TValue;
51
+ }
52
+ export type ResponseSourceFactory<TChunk, TValue> = (context: ResponseConsumeContext<TChunk, TValue>) => MaybePromise<SourceLike<TChunk>>;
53
+ export type ResponseSource<TChunk, TValue> = SourceLike<TChunk> | ResponseSourceFactory<TChunk, TValue>;
54
+ export interface CreateResponseOptions<TChunk, TValue> {
55
+ seed: TValue;
56
+ reduce: (currentValue: TValue, chunk: TChunk, index: number) => TValue;
57
+ }
58
+ export interface ResponseState<TChunk = unknown, TValue = unknown> extends ResponseReactiveState<TChunk, TValue> {
59
+ reset(nextSeed?: TValue): TValue;
60
+ push(chunk: TChunk): TValue;
61
+ complete(): TValue;
62
+ fail(reason?: unknown): Error | TValue;
63
+ abort(reason?: unknown): TValue;
64
+ run(executor: (context: ResponseExecutorContext<TChunk, TValue>) => MaybePromise<unknown>, options?: ResponseRunOptions<TValue>): Promise<TValue>;
65
+ consume(source: ResponseSource<TChunk, TValue>, options?: ResponseRunOptions<TValue>): Promise<TValue>;
66
+ snapshot(): ResponseSnapshot<TChunk, TValue>;
67
+ }
68
+ export interface ResponseFactory {
69
+ create<TChunk, TValue>(options: CreateResponseOptions<TChunk, TValue>): ResponseState<TChunk, TValue>;
70
+ text<TChunk = string>(seed?: string): ResponseState<TChunk, string>;
71
+ list<TChunk>(seed?: TChunk[]): ResponseState<TChunk, TChunk[]>;
72
+ latest<TChunk>(seed?: TChunk | null): ResponseState<TChunk, TChunk | null>;
73
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,4 @@
1
+ import type { ResponseFactory } from './response-types.js';
2
+ export { createResponse } from './response-runtime.js';
3
+ export type { CreateResponseOptions, GlobalAbortSignal, MaybePromise, ResponseConsumeContext, ResponseExecutorContext, ResponseFactory, ResponseReactiveState, ResponseRunOptions, ResponseSnapshot, ResponseSource, ResponseSourceFactory, ResponseState, ResponseStatus, SourceLike } from './response-types.js';
4
+ export declare const response: ResponseFactory;
@@ -0,0 +1,26 @@
1
+ import { createResponse } from './response-runtime.js';
2
+ // Ship a few common reducers as convenience constructors on top of createResponse.
3
+ export { createResponse } from './response-runtime.js';
4
+ export const response = {
5
+ create(options) {
6
+ return createResponse(options);
7
+ },
8
+ text(seed = '') {
9
+ return createResponse({
10
+ seed,
11
+ reduce: (currentValue, chunk) => currentValue + String(chunk)
12
+ });
13
+ },
14
+ list(seed = []) {
15
+ return createResponse({
16
+ seed,
17
+ reduce: (currentValue, chunk) => [...currentValue, chunk]
18
+ });
19
+ },
20
+ latest(seed = null) {
21
+ return createResponse({
22
+ seed,
23
+ reduce: (_, chunk) => chunk
24
+ });
25
+ }
26
+ };
@@ -0,0 +1,10 @@
1
+ import type { ReactiveObserver } from './signal-types.js';
2
+ export declare const READ: unique symbol;
3
+ export declare function getActiveObserver(): ReactiveObserver | null;
4
+ export declare function setActiveObserver(observer: ReactiveObserver | null): void;
5
+ export declare function withActiveObserver<T>(observer: ReactiveObserver | null, fn: () => T): T;
6
+ export declare function cleanupObserver(observer: ReactiveObserver): void;
7
+ export declare function scheduleObserver(observer: ReactiveObserver): void;
8
+ export declare function removePendingObserver(observer: ReactiveObserver): void;
9
+ export declare function batch<T>(fn: () => T): T;
10
+ export declare function untrack<T>(fn: () => T): T;
@@ -0,0 +1,69 @@
1
+ // Use a sentinel so signals can still store undefined as a real value.
2
+ export const READ = Symbol('qore.signal.read');
3
+ let activeObserver = null;
4
+ let batchDepth = 0;
5
+ const pendingObservers = new Set();
6
+ export function getActiveObserver() {
7
+ return activeObserver;
8
+ }
9
+ export function setActiveObserver(observer) {
10
+ activeObserver = observer;
11
+ }
12
+ export function withActiveObserver(observer, fn) {
13
+ const previousObserver = activeObserver;
14
+ activeObserver = observer;
15
+ try {
16
+ return fn();
17
+ }
18
+ finally {
19
+ activeObserver = previousObserver;
20
+ }
21
+ }
22
+ // Remove this observer from every dependency it tracked during the last run.
23
+ export function cleanupObserver(observer) {
24
+ for (const dep of observer.deps) {
25
+ dep.subscribers.delete(observer);
26
+ }
27
+ observer.deps.clear();
28
+ }
29
+ // Queue observer work during batching, otherwise notify immediately.
30
+ export function scheduleObserver(observer) {
31
+ if (!observer.active) {
32
+ return;
33
+ }
34
+ if (batchDepth > 0) {
35
+ pendingObservers.add(observer);
36
+ return;
37
+ }
38
+ observer.schedule();
39
+ }
40
+ export function removePendingObserver(observer) {
41
+ pendingObservers.delete(observer);
42
+ }
43
+ // Flush batched observer work in FIFO-like waves until the queue is empty.
44
+ function flushObservers() {
45
+ while (pendingObservers.size > 0) {
46
+ const queue = Array.from(pendingObservers);
47
+ pendingObservers.clear();
48
+ for (const observer of queue) {
49
+ observer.schedule();
50
+ }
51
+ }
52
+ }
53
+ // Batch synchronous updates so dependent observers only re-run once afterward.
54
+ export function batch(fn) {
55
+ batchDepth += 1;
56
+ try {
57
+ return fn();
58
+ }
59
+ finally {
60
+ batchDepth -= 1;
61
+ if (batchDepth === 0) {
62
+ flushObservers();
63
+ }
64
+ }
65
+ }
66
+ // Read signals without subscribing the current observer to them.
67
+ export function untrack(fn) {
68
+ return withActiveObserver(null, fn);
69
+ }
@@ -0,0 +1,45 @@
1
+ import type { Cleanup, EffectCallback, EffectOptions, ObserverDependency, ReactiveObserver, SignalListener, SubscribeOptions } from './signal-types.js';
2
+ export declare class SignalNode<T> implements ObserverDependency {
3
+ value: T;
4
+ subscribers: Set<ReactiveObserver>;
5
+ listeners: Set<SignalListener<T>>;
6
+ constructor(initialValue: T);
7
+ get(): T;
8
+ peek(): T;
9
+ set(nextValue: T): T;
10
+ update(updater: (currentValue: T) => T): T;
11
+ subscribe(listener: SignalListener<T>, options?: SubscribeOptions): Cleanup;
12
+ emit(): void;
13
+ }
14
+ export declare class ComputedNode<T> implements ObserverDependency, ReactiveObserver {
15
+ getter: () => T;
16
+ subscribers: Set<ReactiveObserver>;
17
+ listeners: Set<SignalListener<T>>;
18
+ deps: Set<ObserverDependency>;
19
+ active: boolean;
20
+ initialized: boolean;
21
+ value: T;
22
+ constructor(getter: () => T);
23
+ get(): T;
24
+ peek(): T;
25
+ schedule(): void;
26
+ notify(): void;
27
+ subscribe(listener: SignalListener<T>, options?: SubscribeOptions): Cleanup;
28
+ recompute(): void;
29
+ stop(): void;
30
+ }
31
+ export declare class EffectNode implements ReactiveObserver {
32
+ fn: EffectCallback;
33
+ scheduler: EffectOptions['scheduler'];
34
+ deps: Set<ObserverDependency>;
35
+ active: boolean;
36
+ scheduled: boolean;
37
+ running: boolean;
38
+ needsRun: boolean;
39
+ cleanup: Cleanup | null;
40
+ constructor(fn: EffectCallback, options?: EffectOptions);
41
+ schedule(): void;
42
+ notify(): void;
43
+ run(): void;
44
+ stop(): void;
45
+ }
@@ -0,0 +1,197 @@
1
+ import { cleanupObserver, getActiveObserver, removePendingObserver, scheduleObserver, withActiveObserver } from './signal-context.js';
2
+ import { scheduleEffectRun } from './signal-scheduler.js';
3
+ // A mutable signal node stores a value and fan-outs updates to listeners and observers.
4
+ export class SignalNode {
5
+ value;
6
+ subscribers = new Set();
7
+ listeners = new Set();
8
+ constructor(initialValue) {
9
+ this.value = initialValue;
10
+ }
11
+ get() {
12
+ const activeObserver = getActiveObserver();
13
+ if (activeObserver) {
14
+ this.subscribers.add(activeObserver);
15
+ activeObserver.deps.add(this);
16
+ }
17
+ return this.value;
18
+ }
19
+ peek() {
20
+ return this.value;
21
+ }
22
+ set(nextValue) {
23
+ if (Object.is(this.value, nextValue)) {
24
+ return this.value;
25
+ }
26
+ this.value = nextValue;
27
+ this.emit();
28
+ return this.value;
29
+ }
30
+ update(updater) {
31
+ return this.set(updater(this.value));
32
+ }
33
+ subscribe(listener, options = {}) {
34
+ const { immediate = true } = options;
35
+ this.listeners.add(listener);
36
+ if (immediate) {
37
+ listener(this.value);
38
+ }
39
+ return () => {
40
+ this.listeners.delete(listener);
41
+ };
42
+ }
43
+ // Snapshot listeners first so resubscription during notification cannot loop forever.
44
+ emit() {
45
+ for (const listener of Array.from(this.listeners)) {
46
+ listener(this.value);
47
+ }
48
+ for (const observer of Array.from(this.subscribers)) {
49
+ scheduleObserver(observer);
50
+ }
51
+ }
52
+ }
53
+ // A computed node re-runs its getter whenever one of its dependencies changes.
54
+ export class ComputedNode {
55
+ getter;
56
+ subscribers = new Set();
57
+ listeners = new Set();
58
+ deps = new Set();
59
+ active = true;
60
+ initialized = false;
61
+ value;
62
+ constructor(getter) {
63
+ this.getter = getter;
64
+ this.recompute();
65
+ }
66
+ get() {
67
+ const activeObserver = getActiveObserver();
68
+ if (activeObserver) {
69
+ this.subscribers.add(activeObserver);
70
+ activeObserver.deps.add(this);
71
+ }
72
+ return this.value;
73
+ }
74
+ peek() {
75
+ return this.value;
76
+ }
77
+ schedule() {
78
+ this.notify();
79
+ }
80
+ notify() {
81
+ this.recompute();
82
+ }
83
+ subscribe(listener, options = {}) {
84
+ const { immediate = true } = options;
85
+ this.listeners.add(listener);
86
+ if (immediate) {
87
+ listener(this.value);
88
+ }
89
+ return () => {
90
+ this.listeners.delete(listener);
91
+ };
92
+ }
93
+ // Recompute under dependency tracking and notify downstream observers only on change.
94
+ recompute() {
95
+ if (!this.active) {
96
+ return;
97
+ }
98
+ const previousValue = this.value;
99
+ cleanupObserver(this);
100
+ withActiveObserver(this, () => {
101
+ const nextValue = this.getter();
102
+ const changed = !this.initialized || !Object.is(previousValue, nextValue);
103
+ this.value = nextValue;
104
+ this.initialized = true;
105
+ if (!changed) {
106
+ return;
107
+ }
108
+ for (const listener of Array.from(this.listeners)) {
109
+ listener(this.value);
110
+ }
111
+ for (const observer of Array.from(this.subscribers)) {
112
+ scheduleObserver(observer);
113
+ }
114
+ });
115
+ }
116
+ stop() {
117
+ if (!this.active) {
118
+ return;
119
+ }
120
+ this.active = false;
121
+ cleanupObserver(this);
122
+ removePendingObserver(this);
123
+ this.subscribers.clear();
124
+ this.listeners.clear();
125
+ }
126
+ }
127
+ // Effects are observers with optional cleanup that re-run when dependencies change.
128
+ export class EffectNode {
129
+ fn;
130
+ scheduler;
131
+ deps = new Set();
132
+ active = true;
133
+ scheduled = false;
134
+ running = false;
135
+ needsRun = false;
136
+ cleanup = null;
137
+ constructor(fn, options = {}) {
138
+ this.fn = fn;
139
+ this.scheduler = options.scheduler ?? 'sync';
140
+ this.run();
141
+ }
142
+ schedule() {
143
+ if (!this.active) {
144
+ return;
145
+ }
146
+ if (this.running) {
147
+ this.needsRun = true;
148
+ return;
149
+ }
150
+ if (this.scheduled) {
151
+ return;
152
+ }
153
+ this.scheduled = true;
154
+ scheduleEffectRun(this.scheduler, () => {
155
+ this.scheduled = false;
156
+ this.run();
157
+ });
158
+ }
159
+ notify() {
160
+ this.run();
161
+ }
162
+ // Execute the effect under tracking and remember any returned cleanup callback.
163
+ run() {
164
+ if (!this.active) {
165
+ return;
166
+ }
167
+ this.running = true;
168
+ this.needsRun = false;
169
+ cleanupObserver(this);
170
+ if (typeof this.cleanup === 'function') {
171
+ this.cleanup();
172
+ this.cleanup = null;
173
+ }
174
+ withActiveObserver(this, () => {
175
+ const maybeCleanup = this.fn();
176
+ this.cleanup = typeof maybeCleanup === 'function' ? maybeCleanup : null;
177
+ });
178
+ this.running = false;
179
+ if (this.needsRun && this.active) {
180
+ this.schedule();
181
+ }
182
+ }
183
+ stop() {
184
+ if (!this.active) {
185
+ return;
186
+ }
187
+ this.active = false;
188
+ this.scheduled = false;
189
+ this.needsRun = false;
190
+ cleanupObserver(this);
191
+ removePendingObserver(this);
192
+ if (typeof this.cleanup === 'function') {
193
+ this.cleanup();
194
+ this.cleanup = null;
195
+ }
196
+ }
197
+ }
@@ -0,0 +1,2 @@
1
+ import type { EffectScheduler } from './signal-types.js';
2
+ export declare function scheduleEffectRun(scheduler: EffectScheduler | undefined, run: () => void): void;
@@ -0,0 +1,19 @@
1
+ export function scheduleEffectRun(scheduler, run) {
2
+ if (typeof scheduler === 'function') {
3
+ scheduler(run);
4
+ return;
5
+ }
6
+ if (scheduler === 'microtask') {
7
+ queueMicrotask(run);
8
+ return;
9
+ }
10
+ if (scheduler === 'raf') {
11
+ if (typeof requestAnimationFrame === 'function') {
12
+ requestAnimationFrame(() => run());
13
+ return;
14
+ }
15
+ queueMicrotask(run);
16
+ return;
17
+ }
18
+ run();
19
+ }
@@ -0,0 +1,19 @@
1
+ export interface SubscribeOptions {
2
+ immediate?: boolean;
3
+ }
4
+ export type SignalListener<T> = (value: T) => void;
5
+ export type Cleanup = () => void;
6
+ export type EffectCallback = () => void | Cleanup;
7
+ export type EffectScheduler = 'sync' | 'microtask' | 'raf' | ((run: () => void) => void);
8
+ export interface EffectOptions {
9
+ scheduler?: EffectScheduler;
10
+ }
11
+ export interface ObserverDependency {
12
+ subscribers: Set<ReactiveObserver>;
13
+ }
14
+ export interface ReactiveObserver {
15
+ deps: Set<ObserverDependency>;
16
+ active: boolean;
17
+ schedule(): void;
18
+ notify(): void;
19
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,19 @@
1
+ import type { Cleanup, EffectCallback, EffectOptions, SubscribeOptions } from './signal-types.js';
2
+ export interface ReadonlySignal<T> {
3
+ (): T;
4
+ peek(): T;
5
+ subscribe(listener: (value: T) => void, options?: SubscribeOptions): Cleanup;
6
+ }
7
+ export interface Signal<T> extends ReadonlySignal<T> {
8
+ (nextValue: T): T;
9
+ set(nextValue: T): T;
10
+ update(updater: (currentValue: T) => T): T;
11
+ }
12
+ export interface ComputedSignal<T> extends ReadonlySignal<T> {
13
+ stop(): void;
14
+ }
15
+ export declare function signal<T>(initialValue: T): Signal<T>;
16
+ export declare function computed<T>(getter: () => T): ComputedSignal<T>;
17
+ export declare function effect(fn: EffectCallback, options?: EffectOptions): Cleanup;
18
+ export { batch, untrack } from './signal-context.js';
19
+ export declare function isSignal<T = unknown>(value: unknown): value is ReadonlySignal<T>;
@@ -0,0 +1,41 @@
1
+ import { batch, READ, untrack } from './signal-context.js';
2
+ import { ComputedNode, EffectNode, SignalNode } from './signal-nodes.js';
3
+ // Create a mutable signal function with helper methods attached to it.
4
+ export function signal(initialValue) {
5
+ const node = new SignalNode(initialValue);
6
+ const readWriteSignal = ((nextValue = READ) => {
7
+ if (nextValue === READ) {
8
+ return node.get();
9
+ }
10
+ return node.set(nextValue);
11
+ });
12
+ readWriteSignal.set = (nextValue) => node.set(nextValue);
13
+ readWriteSignal.update = (updater) => node.update(updater);
14
+ readWriteSignal.peek = () => node.peek();
15
+ readWriteSignal.subscribe = (listener, options) => node.subscribe(listener, options);
16
+ return readWriteSignal;
17
+ }
18
+ // Create a read-only computed signal backed by dependency tracking.
19
+ export function computed(getter) {
20
+ const node = new ComputedNode(getter);
21
+ const readOnlySignal = ((nextValue = READ) => {
22
+ if (nextValue !== READ) {
23
+ throw new Error('Computed signals are read-only');
24
+ }
25
+ return node.get();
26
+ });
27
+ readOnlySignal.peek = () => node.peek();
28
+ readOnlySignal.subscribe = (listener, options) => node.subscribe(listener, options);
29
+ readOnlySignal.stop = () => node.stop();
30
+ return readOnlySignal;
31
+ }
32
+ // Run a reactive effect and return a disposer for it.
33
+ export function effect(fn, options = {}) {
34
+ const node = new EffectNode(fn, options);
35
+ return () => node.stop();
36
+ }
37
+ export { batch, untrack } from './signal-context.js';
38
+ // Detect Qore signal-like values by their callable shape plus peek helper.
39
+ export function isSignal(value) {
40
+ return typeof value === 'function' && typeof value.peek === 'function';
41
+ }
@@ -0,0 +1,3 @@
1
+ import type { BackpressureOptions, Deferred, NormalizedBackpressure } from './stream-types.js';
2
+ export declare function normalizeBackpressure(backpressure: number | BackpressureOptions | null | undefined): NormalizedBackpressure;
3
+ export declare function createDeferred<T>(): Deferred<T>;
@@ -0,0 +1,36 @@
1
+ // Normalize backpressure into one consistent shape the runtime can enforce.
2
+ export function normalizeBackpressure(backpressure) {
3
+ if (backpressure == null) {
4
+ return {
5
+ interval: 0,
6
+ buffer: Infinity,
7
+ overflow: 'wait'
8
+ };
9
+ }
10
+ const options = typeof backpressure === 'number'
11
+ ? { interval: backpressure }
12
+ : backpressure;
13
+ const interval = options.interval ?? 0;
14
+ const buffer = options.buffer ?? Infinity;
15
+ const overflow = options.overflow ?? 'wait';
16
+ if (!Number.isFinite(interval) || interval < 0) {
17
+ throw new TypeError('Qore stream backpressure.interval must be a non-negative finite number');
18
+ }
19
+ if (buffer !== Infinity && (!Number.isInteger(buffer) || buffer < 1)) {
20
+ throw new TypeError('Qore stream backpressure.buffer must be a positive integer or Infinity');
21
+ }
22
+ if (!['wait', 'drop-oldest', 'drop-newest', 'error'].includes(overflow)) {
23
+ throw new TypeError('Qore stream backpressure.overflow must be one of "wait", "drop-oldest", "drop-newest", or "error"');
24
+ }
25
+ return { interval, buffer, overflow };
26
+ }
27
+ // Build a deferred promise so queue operations can wait for capacity or completion.
28
+ export function createDeferred() {
29
+ let resolve;
30
+ let reject;
31
+ const promise = new Promise((nextResolve, nextReject) => {
32
+ resolve = nextResolve;
33
+ reject = nextReject;
34
+ });
35
+ return { promise, resolve, reject };
36
+ }
@@ -0,0 +1,17 @@
1
+ import type { NormalizedBackpressure } from './stream-types.js';
2
+ export interface StreamBuffer<TChunk, TValue> {
3
+ push(chunk: TChunk): Promise<TValue>;
4
+ flush(result?: TValue): TValue;
5
+ flushScheduled(): Promise<void>;
6
+ }
7
+ export declare function createStreamBuffer<TChunk, TValue>({ enqueueChunk, fail, isTerminated, pressure, readCurrent, recordDrop, signal, updateBuffered, writeChunk }: {
8
+ enqueueChunk(chunk: TChunk): void;
9
+ fail(error: unknown): Error | TValue;
10
+ isTerminated(): boolean;
11
+ pressure: NormalizedBackpressure;
12
+ readCurrent(): TValue;
13
+ recordDrop(): void;
14
+ signal: AbortSignal;
15
+ updateBuffered(count: number): void;
16
+ writeChunk(chunk: TChunk): TValue;
17
+ }): StreamBuffer<TChunk, TValue>;