@tstdl/base 0.91.3 → 0.91.4
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/data-structures/circular-buffer.d.ts +17 -17
- package/data-structures/circular-buffer.js +16 -16
- package/data-structures/collection.d.ts +16 -7
- package/data-structures/collection.js +28 -25
- package/package.json +5 -5
- package/signals/implementation/computed.js +3 -1
- package/signals/implementation/configure.js +1 -1
- package/signals/implementation/equality.js +7 -1
- package/signals/implementation/graph.js +15 -9
- package/signals/implementation/index.d.ts +1 -0
- package/signals/implementation/index.js +1 -0
- package/signals/implementation/signal.d.ts +1 -36
- package/signals/implementation/signal.js +2 -39
- package/signals/implementation/to-signal.d.ts +12 -8
- package/signals/implementation/to-signal.js +10 -7
- package/signals/implementation/watch.d.ts +1 -2
- package/signals/implementation/watch.js +8 -2
- package/signals/implementation/writable-signal.d.ts +48 -0
- package/signals/implementation/writable-signal.js +33 -0
- package/signals/operators/derive-async.d.ts +5 -5
- package/signals/to-lazy-signal.js +3 -12
- package/utils/function/memoize.d.ts +2 -2
- package/utils/function/memoize.js +2 -2
- package/utils/reactive-value-to-signal.d.ts +5 -5
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type
|
|
2
|
-
import type
|
|
1
|
+
import { type Observable } from 'rxjs';
|
|
2
|
+
import { type CancellationSignal } from '../cancellation/token.js';
|
|
3
3
|
import { Collection } from './collection.js';
|
|
4
4
|
export declare class CircularBuffer<T> extends Collection<T, CircularBuffer<T>> {
|
|
5
5
|
private readonly maxBufferSizeSubject;
|
|
@@ -7,31 +7,31 @@ export declare class CircularBuffer<T> extends Collection<T, CircularBuffer<T>>
|
|
|
7
7
|
private backingArray;
|
|
8
8
|
private writeIndex;
|
|
9
9
|
private readIndex;
|
|
10
|
-
/**
|
|
10
|
+
/** Emits overwritten items */
|
|
11
11
|
readonly overflow$: Observable<T>;
|
|
12
|
-
/**
|
|
12
|
+
/** Emits count of free slots in the buffer */
|
|
13
13
|
readonly freeSlots$: Observable<number>;
|
|
14
|
-
/**
|
|
14
|
+
/** Emits when the buffer is full */
|
|
15
15
|
readonly onFull$: Observable<void>;
|
|
16
|
-
/**
|
|
16
|
+
/** Emits when the buffer has free slots */
|
|
17
17
|
readonly onFreeSlots$: Observable<void>;
|
|
18
|
-
/**
|
|
18
|
+
/** Emits whether the buffer is full */
|
|
19
19
|
readonly isFull$: Observable<boolean>;
|
|
20
|
-
/**
|
|
20
|
+
/** Emits whether the buffer has free slots */
|
|
21
21
|
readonly hasFreeSlots$: Observable<boolean>;
|
|
22
|
-
/**
|
|
22
|
+
/** Resolves when the buffer is full */
|
|
23
23
|
get $onFull(): Promise<void>;
|
|
24
|
-
/**
|
|
24
|
+
/** Resolves when the buffer has items */
|
|
25
25
|
get $onFreeSlots(): Promise<void>;
|
|
26
|
-
/**
|
|
26
|
+
/** Size of buffer */
|
|
27
27
|
get bufferSize(): number;
|
|
28
|
-
/**
|
|
28
|
+
/** Size of buffer */
|
|
29
29
|
get maxBufferSize(): number;
|
|
30
|
-
/**
|
|
30
|
+
/** Count of free slots in buffer */
|
|
31
31
|
get freeSlots(): number;
|
|
32
|
-
/**
|
|
32
|
+
/** Whether the buffer is full */
|
|
33
33
|
get isFull(): boolean;
|
|
34
|
-
/**
|
|
34
|
+
/** Whether the buffer has free slots */
|
|
35
35
|
get hasFreeSlots(): boolean;
|
|
36
36
|
constructor(maxBufferSize?: number);
|
|
37
37
|
includes(item: T): boolean;
|
|
@@ -41,10 +41,10 @@ export declare class CircularBuffer<T> extends Collection<T, CircularBuffer<T>>
|
|
|
41
41
|
tryRemove(): T | undefined;
|
|
42
42
|
clone(newMaxBufferSize?: number | undefined): CircularBuffer<T>;
|
|
43
43
|
items(): IterableIterator<T>;
|
|
44
|
-
/**
|
|
44
|
+
/** Yields all items from the buffer and removes them */
|
|
45
45
|
consume(): IterableIterator<T>;
|
|
46
46
|
/**
|
|
47
|
-
*
|
|
47
|
+
* Yields all items from the buffer, removes them and waits fore more
|
|
48
48
|
* @param cancellationSignal token to cancel iteration
|
|
49
49
|
* @param yieldOutstandingItems whether to yield all outstanding items or exit immdiately when {@link cancellationSignal} is set
|
|
50
50
|
* @returns
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import { BehaviorSubject, Subject, distinctUntilChanged, filter, first, firstValueFrom, from, map, race } from 'rxjs';
|
|
1
2
|
import { CancellationToken } from '../cancellation/token.js';
|
|
2
3
|
import { isArray, isDefined, isUndefined } from '../utils/type-guards.js';
|
|
3
|
-
import { BehaviorSubject, Subject, distinctUntilChanged, filter, first, firstValueFrom, from, map, race } from 'rxjs';
|
|
4
4
|
import { Collection } from './collection.js';
|
|
5
5
|
export class CircularBuffer extends Collection {
|
|
6
6
|
maxBufferSizeSubject;
|
|
@@ -8,46 +8,46 @@ export class CircularBuffer extends Collection {
|
|
|
8
8
|
backingArray;
|
|
9
9
|
writeIndex;
|
|
10
10
|
readIndex;
|
|
11
|
-
/**
|
|
11
|
+
/** Emits overwritten items */
|
|
12
12
|
overflow$;
|
|
13
|
-
/**
|
|
13
|
+
/** Emits count of free slots in the buffer */
|
|
14
14
|
freeSlots$;
|
|
15
|
-
/**
|
|
15
|
+
/** Emits when the buffer is full */
|
|
16
16
|
onFull$;
|
|
17
|
-
/**
|
|
17
|
+
/** Emits when the buffer has free slots */
|
|
18
18
|
onFreeSlots$;
|
|
19
|
-
/**
|
|
19
|
+
/** Emits whether the buffer is full */
|
|
20
20
|
isFull$;
|
|
21
|
-
/**
|
|
21
|
+
/** Emits whether the buffer has free slots */
|
|
22
22
|
hasFreeSlots$;
|
|
23
|
-
/**
|
|
23
|
+
/** Resolves when the buffer is full */
|
|
24
24
|
get $onFull() {
|
|
25
25
|
return firstValueFrom(this.onFull$);
|
|
26
26
|
}
|
|
27
|
-
/**
|
|
27
|
+
/** Resolves when the buffer has items */
|
|
28
28
|
get $onFreeSlots() {
|
|
29
29
|
return firstValueFrom(this.onFreeSlots$);
|
|
30
30
|
}
|
|
31
|
-
/**
|
|
31
|
+
/** Size of buffer */
|
|
32
32
|
get bufferSize() {
|
|
33
33
|
return this.backingArray.length;
|
|
34
34
|
}
|
|
35
|
-
/**
|
|
35
|
+
/** Size of buffer */
|
|
36
36
|
get maxBufferSize() {
|
|
37
37
|
return this.maxBufferSizeSubject.value ?? Infinity;
|
|
38
38
|
}
|
|
39
|
-
/**
|
|
39
|
+
/** Count of free slots in buffer */
|
|
40
40
|
get freeSlots() {
|
|
41
41
|
if (isUndefined(this.maxBufferSize)) {
|
|
42
42
|
return Infinity;
|
|
43
43
|
}
|
|
44
44
|
return this.bufferSize - this.size;
|
|
45
45
|
}
|
|
46
|
-
/**
|
|
46
|
+
/** Whether the buffer is full */
|
|
47
47
|
get isFull() {
|
|
48
48
|
return this.freeSlots == 0;
|
|
49
49
|
}
|
|
50
|
-
/**
|
|
50
|
+
/** Whether the buffer has free slots */
|
|
51
51
|
get hasFreeSlots() {
|
|
52
52
|
return this.freeSlots > 0;
|
|
53
53
|
}
|
|
@@ -134,14 +134,14 @@ export class CircularBuffer extends Collection {
|
|
|
134
134
|
subscription.unsubscribe();
|
|
135
135
|
}
|
|
136
136
|
}
|
|
137
|
-
/**
|
|
137
|
+
/** Yields all items from the buffer and removes them */
|
|
138
138
|
*consume() {
|
|
139
139
|
while (this.size > 0) {
|
|
140
140
|
yield this.tryRemove();
|
|
141
141
|
}
|
|
142
142
|
}
|
|
143
143
|
/**
|
|
144
|
-
*
|
|
144
|
+
* Yields all items from the buffer, removes them and waits fore more
|
|
145
145
|
* @param cancellationSignal token to cancel iteration
|
|
146
146
|
* @param yieldOutstandingItems whether to yield all outstanding items or exit immdiately when {@link cancellationSignal} is set
|
|
147
147
|
* @returns
|
|
@@ -1,24 +1,33 @@
|
|
|
1
|
-
import type { ToJson } from '../interfaces.js';
|
|
2
1
|
import { type Observable } from 'rxjs';
|
|
2
|
+
import type { ToJson } from '../interfaces.js';
|
|
3
|
+
import { type Signal } from '../signals/index.js';
|
|
3
4
|
export declare abstract class Collection<T, TThis extends Collection<T, TThis> = Collection<T, any>> implements Iterable<T>, ToJson {
|
|
4
5
|
private readonly sizeSubject;
|
|
5
6
|
private readonly changeSubject;
|
|
6
7
|
private readonly clearSubject;
|
|
7
|
-
/** Emits collection on subscribe and change */
|
|
8
|
-
readonly observe$: Observable<TThis>;
|
|
9
8
|
/** Emits size of collection */
|
|
10
9
|
readonly size$: Observable<number>;
|
|
10
|
+
/** Size of collection */
|
|
11
|
+
readonly $size: Signal<number>;
|
|
11
12
|
/** Emits collection on change */
|
|
12
13
|
readonly change$: Observable<TThis>;
|
|
14
|
+
/** Emits collection on subscribe and change */
|
|
15
|
+
readonly observe$: Observable<TThis>;
|
|
16
|
+
/** Notifies on change */
|
|
17
|
+
readonly $observe: Signal<TThis>;
|
|
13
18
|
readonly clear$: Observable<TThis>;
|
|
14
|
-
/** Emits when the collection is empty */
|
|
15
|
-
readonly onEmpty$: Observable<void>;
|
|
16
|
-
/** Emits when the collection has items */
|
|
17
|
-
readonly onItems$: Observable<void>;
|
|
18
19
|
/** Emits whether the collection is empty */
|
|
19
20
|
readonly isEmpty$: Observable<boolean>;
|
|
21
|
+
/** Whether the collection is empty */
|
|
22
|
+
readonly $isEmpty: Signal<boolean>;
|
|
20
23
|
/** Emits whether the collection has items */
|
|
21
24
|
readonly hasItems$: Observable<boolean>;
|
|
25
|
+
/** Whether the collection has items */
|
|
26
|
+
readonly $hasItems: Signal<boolean>;
|
|
27
|
+
/** Emits when the collection is empty */
|
|
28
|
+
readonly onEmpty$: Observable<undefined>;
|
|
29
|
+
/** Emits when the collection has items */
|
|
30
|
+
readonly onItems$: Observable<undefined>;
|
|
22
31
|
/** Resolves when the collection is empty */
|
|
23
32
|
get $onEmpty(): Promise<void>;
|
|
24
33
|
/** Resolves when the collection has items */
|
|
@@ -1,24 +1,34 @@
|
|
|
1
1
|
import { BehaviorSubject, Subject, distinctUntilChanged, filter, firstValueFrom, map, startWith } from 'rxjs';
|
|
2
|
+
import { toLazySignal } from '../signals/index.js';
|
|
3
|
+
import { lazyProperty } from '../utils/object/lazy-property.js';
|
|
2
4
|
export class Collection {
|
|
3
|
-
sizeSubject;
|
|
4
|
-
changeSubject;
|
|
5
|
-
clearSubject;
|
|
6
|
-
/** Emits collection on subscribe and change */
|
|
7
|
-
observe$;
|
|
5
|
+
sizeSubject = new BehaviorSubject(0);
|
|
6
|
+
changeSubject = new Subject();
|
|
7
|
+
clearSubject = new Subject();
|
|
8
8
|
/** Emits size of collection */
|
|
9
|
-
size
|
|
9
|
+
size$ = this.sizeSubject.asObservable();
|
|
10
|
+
/** Size of collection */
|
|
11
|
+
$size;
|
|
10
12
|
/** Emits collection on change */
|
|
11
|
-
change
|
|
13
|
+
change$ = this.changeSubject.asObservable();
|
|
14
|
+
/** Emits collection on subscribe and change */
|
|
15
|
+
observe$ = this.change$.pipe(startWith(this)); // eslint-disable-line @typescript-eslint/no-unnecessary-type-assertion
|
|
16
|
+
/** Notifies on change */
|
|
17
|
+
$observe;
|
|
12
18
|
/* Emits collection on clear */
|
|
13
|
-
clear
|
|
14
|
-
/** Emits when the collection is empty */
|
|
15
|
-
onEmpty$;
|
|
16
|
-
/** Emits when the collection has items */
|
|
17
|
-
onItems$;
|
|
19
|
+
clear$ = this.clearSubject.asObservable();
|
|
18
20
|
/** Emits whether the collection is empty */
|
|
19
|
-
isEmpty
|
|
21
|
+
isEmpty$ = this.size$.pipe(map(() => this.isEmpty), distinctUntilChanged());
|
|
22
|
+
/** Whether the collection is empty */
|
|
23
|
+
$isEmpty;
|
|
20
24
|
/** Emits whether the collection has items */
|
|
21
|
-
hasItems
|
|
25
|
+
hasItems$ = this.size$.pipe(map(() => this.hasItems), distinctUntilChanged());
|
|
26
|
+
/** Whether the collection has items */
|
|
27
|
+
$hasItems;
|
|
28
|
+
/** Emits when the collection is empty */
|
|
29
|
+
onEmpty$ = this.isEmpty$.pipe(filter((isEmpty) => isEmpty), map(() => undefined));
|
|
30
|
+
/** Emits when the collection has items */
|
|
31
|
+
onItems$ = this.hasItems$.pipe(filter((hasItems) => hasItems), map(() => undefined));
|
|
22
32
|
/** Resolves when the collection is empty */
|
|
23
33
|
get $onEmpty() {
|
|
24
34
|
return firstValueFrom(this.onEmpty$);
|
|
@@ -40,17 +50,10 @@ export class Collection {
|
|
|
40
50
|
return this.size > 0;
|
|
41
51
|
}
|
|
42
52
|
constructor() {
|
|
43
|
-
this.
|
|
44
|
-
this.
|
|
45
|
-
this.
|
|
46
|
-
this
|
|
47
|
-
this.change$ = this.changeSubject.asObservable();
|
|
48
|
-
this.clear$ = this.clearSubject.asObservable();
|
|
49
|
-
this.observe$ = this.change$.pipe(startWith(this));
|
|
50
|
-
this.isEmpty$ = this.size$.pipe(map(() => this.isEmpty), distinctUntilChanged());
|
|
51
|
-
this.hasItems$ = this.size$.pipe(map(() => this.hasItems), distinctUntilChanged());
|
|
52
|
-
this.onEmpty$ = this.isEmpty$.pipe(filter((isEmpty) => isEmpty), map(() => undefined));
|
|
53
|
-
this.onItems$ = this.hasItems$.pipe(filter((hasItems) => hasItems), map(() => undefined));
|
|
53
|
+
lazyProperty(this, '$size', () => toLazySignal(this.size$, { requireSync: true }));
|
|
54
|
+
lazyProperty(this, '$observe', () => toLazySignal(this.observe$, { equal: () => false, requireSync: true }));
|
|
55
|
+
lazyProperty(this, '$isEmpty', () => toLazySignal(this.isEmpty$, { requireSync: true }));
|
|
56
|
+
lazyProperty(this, '$hasItems', () => toLazySignal(this.hasItems$, { requireSync: true }));
|
|
54
57
|
}
|
|
55
58
|
[Symbol.iterator]() {
|
|
56
59
|
return this.items();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tstdl/base",
|
|
3
|
-
"version": "0.91.
|
|
3
|
+
"version": "0.91.4",
|
|
4
4
|
"author": "Patrick Hein",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -108,10 +108,10 @@
|
|
|
108
108
|
},
|
|
109
109
|
"dependencies": {
|
|
110
110
|
"disposablestack": "1.1",
|
|
111
|
-
"luxon": "^3.
|
|
111
|
+
"luxon": "^3.5",
|
|
112
112
|
"reflect-metadata": "^0.2",
|
|
113
113
|
"rxjs": "^7.8",
|
|
114
|
-
"type-fest": "4.
|
|
114
|
+
"type-fest": "4.24"
|
|
115
115
|
},
|
|
116
116
|
"devDependencies": {
|
|
117
117
|
"@mxssfd/typedoc-theme": "1.1",
|
|
@@ -142,7 +142,7 @@
|
|
|
142
142
|
"@zxcvbn-ts/language-de": "^3.0",
|
|
143
143
|
"@zxcvbn-ts/language-en": "^3.0",
|
|
144
144
|
"chroma-js": "^2.6",
|
|
145
|
-
"drizzle-orm": "^0.
|
|
145
|
+
"drizzle-orm": "^0.33",
|
|
146
146
|
"handlebars": "^4.7",
|
|
147
147
|
"koa": "^2.15",
|
|
148
148
|
"minio": "^8.0",
|
|
@@ -150,7 +150,7 @@
|
|
|
150
150
|
"mongodb": "^6.8",
|
|
151
151
|
"nodemailer": "^6.9",
|
|
152
152
|
"pg": "^8.12",
|
|
153
|
-
"playwright": "^1.
|
|
153
|
+
"playwright": "^1.46",
|
|
154
154
|
"preact": "^10.23",
|
|
155
155
|
"preact-render-to-string": "^6.5",
|
|
156
156
|
"undici": "^6.19",
|
|
@@ -67,7 +67,9 @@ const COMPUTED_NODE = {
|
|
|
67
67
|
finally {
|
|
68
68
|
consumerAfterComputation(node, prevConsumer);
|
|
69
69
|
}
|
|
70
|
-
if (oldValue !== UNSET &&
|
|
70
|
+
if (oldValue !== UNSET &&
|
|
71
|
+
oldValue !== ERRORED &&
|
|
72
|
+
newValue !== ERRORED &&
|
|
71
73
|
node.equal(oldValue, newValue)) {
|
|
72
74
|
// No change to `valueVersion` - old and new values are
|
|
73
75
|
// semantically equivalent.
|
|
@@ -2,10 +2,10 @@ import { configureSignals } from '../api.js';
|
|
|
2
2
|
import { isSignal } from './api.js';
|
|
3
3
|
import { computed } from './computed.js';
|
|
4
4
|
import { effect } from './effect.js';
|
|
5
|
-
import { signal } from './signal.js';
|
|
6
5
|
import { toObservable } from './to-observable.js';
|
|
7
6
|
import { toSignal } from './to-signal.js';
|
|
8
7
|
import { untracked } from './untracked.js';
|
|
8
|
+
import { signal } from './writable-signal.js';
|
|
9
9
|
export function configureDefaultSignalsImplementation() {
|
|
10
10
|
configureSignals({
|
|
11
11
|
signal,
|
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright Google LLC All Rights Reserved.
|
|
4
|
+
*
|
|
5
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
6
|
+
* found in the LICENSE file at https://angular.io/license
|
|
7
|
+
*/
|
|
2
8
|
/**
|
|
3
9
|
* The default equality function used for `signal` and `computed`, which uses referential equality.
|
|
4
10
|
*/
|
|
@@ -85,8 +85,9 @@ export function producerAccessed(node) {
|
|
|
85
85
|
activeConsumer.producerNode[idx] = node;
|
|
86
86
|
// If the active consumer is live, then add it as a live consumer. If not, then use 0 as a
|
|
87
87
|
// placeholder value.
|
|
88
|
-
activeConsumer.producerIndexOfThis[idx] =
|
|
89
|
-
|
|
88
|
+
activeConsumer.producerIndexOfThis[idx] = consumerIsLive(activeConsumer)
|
|
89
|
+
? producerAddLiveConsumer(node, activeConsumer, idx)
|
|
90
|
+
: 0;
|
|
90
91
|
}
|
|
91
92
|
activeConsumer.producerLastReadVersion[idx] = node.version;
|
|
92
93
|
}
|
|
@@ -176,7 +177,9 @@ export function consumerBeforeComputation(node) {
|
|
|
176
177
|
*/
|
|
177
178
|
export function consumerAfterComputation(node, prevConsumer) {
|
|
178
179
|
setActiveConsumer(prevConsumer);
|
|
179
|
-
if (!node ||
|
|
180
|
+
if (!node ||
|
|
181
|
+
node.producerNode === undefined ||
|
|
182
|
+
node.producerIndexOfThis === undefined ||
|
|
180
183
|
node.producerLastReadVersion === undefined) {
|
|
181
184
|
return;
|
|
182
185
|
}
|
|
@@ -234,8 +237,10 @@ export function consumerDestroy(node) {
|
|
|
234
237
|
}
|
|
235
238
|
}
|
|
236
239
|
// Truncate all the arrays to drop all connection from this node to the graph.
|
|
237
|
-
node.producerNode.length =
|
|
238
|
-
|
|
240
|
+
node.producerNode.length =
|
|
241
|
+
node.producerLastReadVersion.length =
|
|
242
|
+
node.producerIndexOfThis.length =
|
|
243
|
+
0;
|
|
239
244
|
if (node.liveConsumerNode) {
|
|
240
245
|
node.liveConsumerNode.length = node.liveConsumerIndexOfThis.length = 0;
|
|
241
246
|
}
|
|
@@ -248,8 +253,7 @@ export function consumerDestroy(node) {
|
|
|
248
253
|
*/
|
|
249
254
|
function producerAddLiveConsumer(node, consumer, indexOfThis) {
|
|
250
255
|
assertProducerNode(node);
|
|
251
|
-
|
|
252
|
-
if (node.liveConsumerNode.length === 0) {
|
|
256
|
+
if (node.liveConsumerNode.length === 0 && isConsumerNode(node)) {
|
|
253
257
|
// When going from 0 to 1 live consumers, we become a live consumer to our producers.
|
|
254
258
|
for (let i = 0; i < node.producerNode.length; i++) {
|
|
255
259
|
node.producerIndexOfThis[i] = producerAddLiveConsumer(node.producerNode[i], node, i);
|
|
@@ -263,11 +267,10 @@ function producerAddLiveConsumer(node, consumer, indexOfThis) {
|
|
|
263
267
|
*/
|
|
264
268
|
function producerRemoveLiveConsumerAtIndex(node, idx) {
|
|
265
269
|
assertProducerNode(node);
|
|
266
|
-
assertConsumerNode(node);
|
|
267
270
|
if (idx >= node.liveConsumerNode.length) {
|
|
268
271
|
throw new Error(`Assertion error: active consumer index ${idx} is out of bounds of ${node.liveConsumerNode.length} consumers)`);
|
|
269
272
|
}
|
|
270
|
-
if (node.liveConsumerNode.length === 1) {
|
|
273
|
+
if (node.liveConsumerNode.length === 1 && isConsumerNode(node)) {
|
|
271
274
|
// When removing the last live consumer, we will no longer be live. We need to remove
|
|
272
275
|
// ourselves from our producers' tracking (which may cause consumer-producers to lose
|
|
273
276
|
// liveness as well).
|
|
@@ -304,3 +307,6 @@ function assertProducerNode(node) {
|
|
|
304
307
|
node.liveConsumerNode ??= [];
|
|
305
308
|
node.liveConsumerIndexOfThis ??= [];
|
|
306
309
|
}
|
|
310
|
+
function isConsumerNode(node) {
|
|
311
|
+
return node.producerNode !== undefined;
|
|
312
|
+
}
|
|
@@ -5,14 +5,12 @@
|
|
|
5
5
|
* Use of this source code is governed by an MIT-style license that can be
|
|
6
6
|
* found in the LICENSE file at https://angular.io/license
|
|
7
7
|
*/
|
|
8
|
-
import type { Signal } from './api.js';
|
|
9
8
|
import type { ValueEqualityFn } from './equality.js';
|
|
10
9
|
import type { ReactiveNode } from './graph.js';
|
|
11
10
|
import { SIGNAL } from './graph.js';
|
|
12
11
|
export interface SignalNode<T> extends ReactiveNode {
|
|
13
12
|
value: T;
|
|
14
13
|
equal: ValueEqualityFn<T>;
|
|
15
|
-
readonly [SIGNAL]: SignalNode<T>;
|
|
16
14
|
}
|
|
17
15
|
export type SignalBaseGetter<T> = (() => T) & {
|
|
18
16
|
readonly [SIGNAL]: unknown;
|
|
@@ -28,37 +26,4 @@ export declare function setPostSignalSetFn(fn: (() => void) | null): (() => void
|
|
|
28
26
|
export declare function signalGetFn<T>(this: SignalNode<T>): T;
|
|
29
27
|
export declare function signalSetFn<T>(node: SignalNode<T>, newValue: T): void;
|
|
30
28
|
export declare function signalUpdateFn<T>(node: SignalNode<T>, updater: (value: T) => T): void;
|
|
31
|
-
export declare
|
|
32
|
-
/**
|
|
33
|
-
* A `Signal` with a value that can be mutated via a setter interface.
|
|
34
|
-
*/
|
|
35
|
-
export interface WritableSignal<T> extends Signal<T> {
|
|
36
|
-
/**
|
|
37
|
-
* Directly set the signal to a new value, and notify any dependents.
|
|
38
|
-
*/
|
|
39
|
-
set(value: T): void;
|
|
40
|
-
/**
|
|
41
|
-
* Update the value of the signal based on its current value, and
|
|
42
|
-
* notify any dependents.
|
|
43
|
-
*/
|
|
44
|
-
update(updateFn: (value: T) => T): void;
|
|
45
|
-
/**
|
|
46
|
-
* Returns a readonly version of this signal. Readonly signals can be accessed to read their value
|
|
47
|
-
* but can't be changed using set or update methods. The readonly signals do _not_ have
|
|
48
|
-
* any built-in mechanism that would prevent deep-mutation of their value.
|
|
49
|
-
*/
|
|
50
|
-
asReadonly(): Signal<T>;
|
|
51
|
-
}
|
|
52
|
-
/**
|
|
53
|
-
* Options passed to the `signal` creation function.
|
|
54
|
-
*/
|
|
55
|
-
export interface CreateSignalOptions<T> {
|
|
56
|
-
/**
|
|
57
|
-
* A comparison function which defines equality for signal values.
|
|
58
|
-
*/
|
|
59
|
-
equal?: ValueEqualityFn<T>;
|
|
60
|
-
}
|
|
61
|
-
/**
|
|
62
|
-
* Create a `Signal` that can be set or updated directly.
|
|
63
|
-
*/
|
|
64
|
-
export declare function signal<T>(initialValue: T, options?: CreateSignalOptions<T>): WritableSignal<T>;
|
|
29
|
+
export declare const SIGNAL_NODE: SignalNode<unknown>;
|
|
@@ -35,13 +35,7 @@ export function signalSetFn(node, newValue) {
|
|
|
35
35
|
if (!producerUpdatesAllowed()) {
|
|
36
36
|
throwInvalidWriteToSignalError();
|
|
37
37
|
}
|
|
38
|
-
|
|
39
|
-
if (Object.is(value, newValue)) {
|
|
40
|
-
if (!node.equal(value, newValue)) {
|
|
41
|
-
console.warn('Signal value equality implementations should always return `true` for values that are the same according to `Object.is` but returned `false` instead.');
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
else if (!node.equal(value, newValue)) {
|
|
38
|
+
if (!node.equal(node.value, newValue)) {
|
|
45
39
|
node.value = newValue;
|
|
46
40
|
signalValueChanged(node);
|
|
47
41
|
}
|
|
@@ -52,15 +46,7 @@ export function signalUpdateFn(node, updater) {
|
|
|
52
46
|
}
|
|
53
47
|
signalSetFn(node, updater(node.value));
|
|
54
48
|
}
|
|
55
|
-
export
|
|
56
|
-
if (!producerUpdatesAllowed()) {
|
|
57
|
-
throwInvalidWriteToSignalError();
|
|
58
|
-
}
|
|
59
|
-
// Mutate bypasses equality checks as it's by definition changing the value.
|
|
60
|
-
mutator(node.value);
|
|
61
|
-
signalValueChanged(node);
|
|
62
|
-
}
|
|
63
|
-
const SIGNAL_NODE = {
|
|
49
|
+
export const SIGNAL_NODE = {
|
|
64
50
|
...REACTIVE_NODE,
|
|
65
51
|
equal: defaultEquals,
|
|
66
52
|
value: undefined,
|
|
@@ -71,26 +57,3 @@ function signalValueChanged(node) {
|
|
|
71
57
|
producerNotifyConsumers(node);
|
|
72
58
|
postSignalSetFn?.();
|
|
73
59
|
}
|
|
74
|
-
/**
|
|
75
|
-
* Create a `Signal` that can be set or updated directly.
|
|
76
|
-
*/
|
|
77
|
-
export function signal(initialValue, options) {
|
|
78
|
-
const signalFn = createSignal(initialValue);
|
|
79
|
-
const node = signalFn[SIGNAL];
|
|
80
|
-
if (options?.equal) {
|
|
81
|
-
node.equal = options.equal;
|
|
82
|
-
}
|
|
83
|
-
signalFn.set = (newValue) => signalSetFn(node, newValue);
|
|
84
|
-
signalFn.update = (updateFn) => signalUpdateFn(node, updateFn);
|
|
85
|
-
signalFn.asReadonly = signalAsReadonlyFn.bind(signalFn);
|
|
86
|
-
return signalFn;
|
|
87
|
-
}
|
|
88
|
-
function signalAsReadonlyFn() {
|
|
89
|
-
const node = this[SIGNAL];
|
|
90
|
-
if (node.readonlyFn === undefined) {
|
|
91
|
-
const readonlyFn = () => this();
|
|
92
|
-
readonlyFn[SIGNAL] = node;
|
|
93
|
-
node.readonlyFn = readonlyFn;
|
|
94
|
-
}
|
|
95
|
-
return node.readonlyFn;
|
|
96
|
-
}
|
|
@@ -7,10 +7,8 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import type { Observable, Subscribable } from 'rxjs';
|
|
9
9
|
import type { Signal } from './api.js';
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
*/
|
|
13
|
-
export interface ToSignalOptions {
|
|
10
|
+
import { ValueEqualityFn } from './equality.js';
|
|
11
|
+
export interface ToSignalOptions<T> {
|
|
14
12
|
/**
|
|
15
13
|
* Initial value for the signal produced by `toSignal`.
|
|
16
14
|
*
|
|
@@ -35,21 +33,27 @@ export interface ToSignalOptions {
|
|
|
35
33
|
* the behavior of the `async` pipe.
|
|
36
34
|
*/
|
|
37
35
|
rejectErrors?: boolean;
|
|
36
|
+
/**
|
|
37
|
+
* A comparison function which defines equality for values emitted by the observable.
|
|
38
|
+
*
|
|
39
|
+
* Equality comparisons are executed against the initial value if one is provided.
|
|
40
|
+
*/
|
|
41
|
+
equal?: ValueEqualityFn<T>;
|
|
38
42
|
}
|
|
39
43
|
export declare function toSignal<T>(source: Observable<T> | Subscribable<T>): Signal<T | undefined>;
|
|
40
|
-
export declare function toSignal<T>(source: Observable<T> | Subscribable<T>, options: ToSignalOptions & {
|
|
44
|
+
export declare function toSignal<T>(source: Observable<T> | Subscribable<T>, options: NoInfer<ToSignalOptions<T | undefined>> & {
|
|
41
45
|
initialValue?: undefined;
|
|
42
46
|
requireSync?: false;
|
|
43
47
|
}): Signal<T | undefined>;
|
|
44
|
-
export declare function toSignal<T>(source: Observable<T> | Subscribable<T>, options: ToSignalOptions & {
|
|
48
|
+
export declare function toSignal<T>(source: Observable<T> | Subscribable<T>, options: NoInfer<ToSignalOptions<T | null>> & {
|
|
45
49
|
initialValue?: null;
|
|
46
50
|
requireSync?: false;
|
|
47
51
|
}): Signal<T | null>;
|
|
48
|
-
export declare function toSignal<T>(source: Observable<T> | Subscribable<T>, options: ToSignalOptions & {
|
|
52
|
+
export declare function toSignal<T>(source: Observable<T> | Subscribable<T>, options: NoInfer<ToSignalOptions<T>> & {
|
|
49
53
|
initialValue?: undefined;
|
|
50
54
|
requireSync: true;
|
|
51
55
|
}): Signal<T>;
|
|
52
|
-
export declare function toSignal<T, const U extends T>(source: Observable<T> | Subscribable<T>, options: ToSignalOptions & {
|
|
56
|
+
export declare function toSignal<T, const U extends T>(source: Observable<T> | Subscribable<T>, options: NoInfer<ToSignalOptions<T | U>> & {
|
|
53
57
|
initialValue: U;
|
|
54
58
|
requireSync?: false;
|
|
55
59
|
}): Signal<T | U>;
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { registerFinalization } from '../../memory/finalization.js';
|
|
3
3
|
import { assertNotInReactiveContext } from './asserts.js';
|
|
4
4
|
import { computed } from './computed.js';
|
|
5
|
-
import { signal } from './signal.js';
|
|
5
|
+
import { signal } from './writable-signal.js';
|
|
6
6
|
/**
|
|
7
7
|
* Get the current value of an `Observable` as a reactive `Signal`.
|
|
8
8
|
*
|
|
@@ -18,16 +18,17 @@ import { signal } from './signal.js';
|
|
|
18
18
|
export function toSignal(source, options) {
|
|
19
19
|
assertNotInReactiveContext(toSignal, 'Invoking `toSignal` causes new subscriptions every time. ' +
|
|
20
20
|
'Consider moving `toSignal` outside of the reactive context and read the signal value where needed.');
|
|
21
|
+
const equal = makeToSignalEqual(options?.equal);
|
|
21
22
|
// Note: T is the Observable value type, and U is the initial value type. They don't have to be
|
|
22
23
|
// the same - the returned signal gives values of type `T`.
|
|
23
24
|
let state;
|
|
24
25
|
if (options?.requireSync) {
|
|
25
26
|
// Initially the signal is in a `NoValue` state.
|
|
26
|
-
state = signal({ kind: StateKind.NoValue });
|
|
27
|
+
state = signal({ kind: StateKind.NoValue }, { equal });
|
|
27
28
|
}
|
|
28
29
|
else {
|
|
29
30
|
// If an initial value was passed, use it. Otherwise, use `undefined` as the initial value.
|
|
30
|
-
state = signal({ kind: StateKind.Value, value: options?.initialValue });
|
|
31
|
+
state = signal({ kind: StateKind.Value, value: options?.initialValue }, { equal });
|
|
31
32
|
}
|
|
32
33
|
// Note: This code cannot run inside a reactive context (see assertion above). If we'd support
|
|
33
34
|
// this, we would subscribe to the observable outside of the current reactive context, avoiding
|
|
@@ -36,8 +37,8 @@ export function toSignal(source, options) {
|
|
|
36
37
|
// subscription. Additional context (related to async pipe):
|
|
37
38
|
// https://github.com/angular/angular/pull/50522.
|
|
38
39
|
const sub = source.subscribe({
|
|
39
|
-
next: value => state.set({ kind: StateKind.Value, value }),
|
|
40
|
-
error: error => {
|
|
40
|
+
next: (value) => state.set({ kind: StateKind.Value, value }),
|
|
41
|
+
error: (error) => {
|
|
41
42
|
if (options?.rejectErrors) {
|
|
42
43
|
// Kick the error back to RxJS. It will be caught and rethrown in a macrotask, which causes
|
|
43
44
|
// the error to end up as an uncaught exception.
|
|
@@ -62,13 +63,15 @@ export function toSignal(source, options) {
|
|
|
62
63
|
throw current.error;
|
|
63
64
|
case StateKind.NoValue:
|
|
64
65
|
// This shouldn't really happen because the error is thrown on creation.
|
|
65
|
-
// TODO(alxhub): use a RuntimeError when we finalize the error semantics
|
|
66
66
|
throw new Error('`toSignal()` called with `requireSync` but `Observable` did not emit synchronously.');
|
|
67
67
|
}
|
|
68
|
-
});
|
|
68
|
+
}, { equal: options?.equal });
|
|
69
69
|
registerFinalization(result, () => sub.unsubscribe());
|
|
70
70
|
return result;
|
|
71
71
|
}
|
|
72
|
+
function makeToSignalEqual(userEquality = Object.is) {
|
|
73
|
+
return (a, b) => a.kind === StateKind.Value && b.kind === StateKind.Value && userEquality(a.value, b.value);
|
|
74
|
+
}
|
|
72
75
|
var StateKind;
|
|
73
76
|
(function (StateKind) {
|
|
74
77
|
StateKind[StateKind["NoValue"] = 0] = "NoValue";
|
|
@@ -5,8 +5,7 @@
|
|
|
5
5
|
* Use of this source code is governed by an MIT-style license that can be
|
|
6
6
|
* found in the LICENSE file at https://angular.io/license
|
|
7
7
|
*/
|
|
8
|
-
import type
|
|
9
|
-
import { SIGNAL } from './graph.js';
|
|
8
|
+
import { type ReactiveNode, SIGNAL } from './graph.js';
|
|
10
9
|
/**
|
|
11
10
|
* A cleanup function that can be optionally registered from the watch logic. If registered, the
|
|
12
11
|
* cleanup logic runs before the next watch execution.
|
|
@@ -1,5 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright Google LLC All Rights Reserved.
|
|
4
|
+
*
|
|
5
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
6
|
+
* found in the LICENSE file at https://angular.io/license
|
|
7
|
+
*/
|
|
8
|
+
import { consumerAfterComputation, consumerBeforeComputation, consumerDestroy, consumerMarkDirty, consumerPollProducersForChange, isInNotificationPhase, REACTIVE_NODE, SIGNAL, } from './graph.js';
|
|
3
9
|
export function createWatch(fn, schedule, allowSignalWrites) {
|
|
4
10
|
const node = Object.create(WATCH_NODE);
|
|
5
11
|
if (allowSignalWrites) {
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { Signal } from './api.js';
|
|
2
|
+
import { ValueEqualityFn } from './equality.js';
|
|
3
|
+
import { SignalGetter } from './signal.js';
|
|
4
|
+
/**
|
|
5
|
+
* @license
|
|
6
|
+
* Copyright Google LLC All Rights Reserved.
|
|
7
|
+
*
|
|
8
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
9
|
+
* found in the LICENSE file at https://angular.io/license
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* A `Signal` with a value that can be mutated via a setter interface.
|
|
13
|
+
*/
|
|
14
|
+
export interface WritableSignal<T> extends Signal<T> {
|
|
15
|
+
/**
|
|
16
|
+
* Directly set the signal to a new value, and notify any dependents.
|
|
17
|
+
*/
|
|
18
|
+
set(value: T): void;
|
|
19
|
+
/**
|
|
20
|
+
* Update the value of the signal based on its current value, and
|
|
21
|
+
* notify any dependents.
|
|
22
|
+
*/
|
|
23
|
+
update(updateFn: (value: T) => T): void;
|
|
24
|
+
/**
|
|
25
|
+
* Returns a readonly version of this signal. Readonly signals can be accessed to read their value
|
|
26
|
+
* but can't be changed using set or update methods. The readonly signals do _not_ have
|
|
27
|
+
* any built-in mechanism that would prevent deep-mutation of their value.
|
|
28
|
+
*/
|
|
29
|
+
asReadonly(): Signal<T>;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Options passed to the `signal` creation function.
|
|
33
|
+
*/
|
|
34
|
+
export interface CreateSignalOptions<T> {
|
|
35
|
+
/**
|
|
36
|
+
* A comparison function which defines equality for signal values.
|
|
37
|
+
*/
|
|
38
|
+
equal?: ValueEqualityFn<T>;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Create a `Signal` that can be set or updated directly.
|
|
42
|
+
*/
|
|
43
|
+
export declare function signal<T>(initialValue: T, options?: CreateSignalOptions<T>): WritableSignal<T>;
|
|
44
|
+
export declare function signalAsReadonlyFn<T>(this: SignalGetter<T>): Signal<T>;
|
|
45
|
+
/**
|
|
46
|
+
* Checks if the given `value` is a writeable signal.
|
|
47
|
+
*/
|
|
48
|
+
export declare function isWritableSignal(value: unknown): value is WritableSignal<unknown>;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/* eslint-disable */
|
|
2
|
+
import { SIGNAL } from '../symbol.js';
|
|
3
|
+
import { isSignal } from './api.js';
|
|
4
|
+
import { createSignal, signalSetFn, signalUpdateFn } from './signal.js';
|
|
5
|
+
/**
|
|
6
|
+
* Create a `Signal` that can be set or updated directly.
|
|
7
|
+
*/
|
|
8
|
+
export function signal(initialValue, options) {
|
|
9
|
+
const signalFn = createSignal(initialValue);
|
|
10
|
+
const node = signalFn[SIGNAL];
|
|
11
|
+
if (options?.equal) {
|
|
12
|
+
node.equal = options.equal;
|
|
13
|
+
}
|
|
14
|
+
signalFn.set = (newValue) => signalSetFn(node, newValue);
|
|
15
|
+
signalFn.update = (updateFn) => signalUpdateFn(node, updateFn);
|
|
16
|
+
signalFn.asReadonly = signalAsReadonlyFn.bind(signalFn);
|
|
17
|
+
return signalFn;
|
|
18
|
+
}
|
|
19
|
+
export function signalAsReadonlyFn() {
|
|
20
|
+
const node = this[SIGNAL];
|
|
21
|
+
if (node.readonlyFn === undefined) {
|
|
22
|
+
const readonlyFn = () => this();
|
|
23
|
+
readonlyFn[SIGNAL] = node;
|
|
24
|
+
node.readonlyFn = readonlyFn;
|
|
25
|
+
}
|
|
26
|
+
return node.readonlyFn;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Checks if the given `value` is a writeable signal.
|
|
30
|
+
*/
|
|
31
|
+
export function isWritableSignal(value) {
|
|
32
|
+
return isSignal(value) && typeof value.set === 'function';
|
|
33
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { concatAll, exhaustAll, mergeAll, switchAll, type Observable } from 'rxjs';
|
|
2
2
|
import { type Signal, type ToSignalOptions } from '../api.js';
|
|
3
|
-
export type DeriveAsyncOptions = ToSignalOptions & {
|
|
3
|
+
export type DeriveAsyncOptions<T> = ToSignalOptions<T> & {
|
|
4
4
|
behavior?: DeriveAsyncBehavior;
|
|
5
5
|
};
|
|
6
6
|
declare const operatorMap: {
|
|
@@ -12,19 +12,19 @@ declare const operatorMap: {
|
|
|
12
12
|
export type DeriveAsyncBehavior = keyof typeof operatorMap;
|
|
13
13
|
type DeriveAsyncSourceParameter<T> = () => (T | Promise<T> | Observable<T>);
|
|
14
14
|
export declare function deriveAsync<T>(source: DeriveAsyncSourceParameter<T>): Signal<T | undefined>;
|
|
15
|
-
export declare function deriveAsync<T>(source: DeriveAsyncSourceParameter<T>, options: DeriveAsyncOptions & {
|
|
15
|
+
export declare function deriveAsync<T>(source: DeriveAsyncSourceParameter<T>, options: DeriveAsyncOptions<T> & {
|
|
16
16
|
initialValue?: undefined;
|
|
17
17
|
requireSync?: false;
|
|
18
18
|
}): Signal<T | undefined>;
|
|
19
|
-
export declare function deriveAsync<T>(source: DeriveAsyncSourceParameter<T>, options: DeriveAsyncOptions & {
|
|
19
|
+
export declare function deriveAsync<T>(source: DeriveAsyncSourceParameter<T>, options: DeriveAsyncOptions<T> & {
|
|
20
20
|
initialValue?: null;
|
|
21
21
|
requireSync?: false;
|
|
22
22
|
}): Signal<T | null>;
|
|
23
|
-
export declare function deriveAsync<T>(source: DeriveAsyncSourceParameter<T>, options: DeriveAsyncOptions & {
|
|
23
|
+
export declare function deriveAsync<T>(source: DeriveAsyncSourceParameter<T>, options: DeriveAsyncOptions<T> & {
|
|
24
24
|
initialValue?: undefined;
|
|
25
25
|
requireSync: true;
|
|
26
26
|
}): Signal<T>;
|
|
27
|
-
export declare function deriveAsync<T, const U extends T>(source: DeriveAsyncSourceParameter<T>, options: DeriveAsyncOptions & {
|
|
27
|
+
export declare function deriveAsync<T, const U extends T>(source: DeriveAsyncSourceParameter<T>, options: DeriveAsyncOptions<T> & {
|
|
28
28
|
initialValue: U;
|
|
29
29
|
requireSync?: false;
|
|
30
30
|
}): Signal<T | U>;
|
|
@@ -1,19 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { computed, toSignal } from './api.js';
|
|
3
|
-
const LAZY = Symbol('LAZY');
|
|
1
|
+
import { computed, toSignal, untracked } from './api.js';
|
|
4
2
|
export const toLazySignal = function toLazySignal(source, options) {
|
|
5
|
-
const subscribe$ = new Subject();
|
|
6
|
-
const lazySource = subscribe$.pipe(switchMap(() => source));
|
|
7
|
-
const signal = toSignal(lazySource, { initialValue: LAZY, ...options }); // eslint-disable-line @typescript-eslint/no-unsafe-argument
|
|
8
3
|
let computation = () => {
|
|
9
|
-
|
|
10
|
-
subscribe$.complete();
|
|
4
|
+
const signal = untracked(() => toSignal(source, { ...options })); // eslint-disable-line @typescript-eslint/no-unsafe-argument
|
|
11
5
|
const value = signal();
|
|
12
6
|
computation = signal;
|
|
13
|
-
if (value == LAZY) {
|
|
14
|
-
throw new Error('`toLazySignal()` called with `requireSync` but `Observable` did not emit synchronously.');
|
|
15
|
-
}
|
|
16
7
|
return value;
|
|
17
8
|
};
|
|
18
|
-
return computed(() => computation());
|
|
9
|
+
return computed(() => computation(), { equal: options?.equal });
|
|
19
10
|
};
|
|
@@ -4,12 +4,12 @@ export type MemoizeOptions = {
|
|
|
4
4
|
weak?: boolean;
|
|
5
5
|
};
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
7
|
+
* Memoizes a function with an arbitrary number of parameters. If you only need a single parameter, {@link memoizeSingle} is faster
|
|
8
8
|
* @param fn function memoize
|
|
9
9
|
* @returns memoized function
|
|
10
10
|
*/ export declare function memoize<Fn extends (...parameters: any[]) => any>(fn: Fn, options?: MemoizeOptions): Fn;
|
|
11
11
|
/**
|
|
12
|
-
*
|
|
12
|
+
* Memoizes a function with a single parameter. Faster than {@link memoize}
|
|
13
13
|
* @param fn function memoize
|
|
14
14
|
* @returns memoized function
|
|
15
15
|
*/
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { IterableWeakMap } from '../../data-structures/iterable-weak-map.js';
|
|
2
2
|
import { MultiKeyMap } from '../../data-structures/multi-key-map.js';
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
4
|
+
* Memoizes a function with an arbitrary number of parameters. If you only need a single parameter, {@link memoizeSingle} is faster
|
|
5
5
|
* @param fn function memoize
|
|
6
6
|
* @returns memoized function
|
|
7
7
|
*/ export function memoize(fn, options = {}) {
|
|
@@ -19,7 +19,7 @@ import { MultiKeyMap } from '../../data-structures/multi-key-map.js';
|
|
|
19
19
|
}[name];
|
|
20
20
|
}
|
|
21
21
|
/**
|
|
22
|
-
*
|
|
22
|
+
* Memoizes a function with a single parameter. Faster than {@link memoize}
|
|
23
23
|
* @param fn function memoize
|
|
24
24
|
* @returns memoized function
|
|
25
25
|
*/
|
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
import { type Signal, type ToSignalOptions } from '../signals/api.js';
|
|
2
2
|
import type { ReactiveValue } from '../types.js';
|
|
3
|
-
export type ReactiveValueToSignalOptions = ToSignalOptions
|
|
3
|
+
export type ReactiveValueToSignalOptions<T> = ToSignalOptions<T>;
|
|
4
4
|
export declare function reactiveValueToSignal<T>(source: ReactiveValue<T>): Signal<T | undefined>;
|
|
5
|
-
export declare function reactiveValueToSignal<T>(source: ReactiveValue<T>, options: ReactiveValueToSignalOptions & {
|
|
5
|
+
export declare function reactiveValueToSignal<T>(source: ReactiveValue<T>, options: ReactiveValueToSignalOptions<T | undefined> & {
|
|
6
6
|
initialValue?: undefined;
|
|
7
7
|
requireSync?: false;
|
|
8
8
|
}): Signal<T | undefined>;
|
|
9
|
-
export declare function reactiveValueToSignal<T>(source: ReactiveValue<T>, options: ReactiveValueToSignalOptions & {
|
|
9
|
+
export declare function reactiveValueToSignal<T>(source: ReactiveValue<T>, options: ReactiveValueToSignalOptions<T | null> & {
|
|
10
10
|
initialValue?: null;
|
|
11
11
|
requireSync?: false;
|
|
12
12
|
}): Signal<T | null>;
|
|
13
|
-
export declare function reactiveValueToSignal<T>(source: ReactiveValue<T>, options: ReactiveValueToSignalOptions & {
|
|
13
|
+
export declare function reactiveValueToSignal<T>(source: ReactiveValue<T>, options: ReactiveValueToSignalOptions<T> & {
|
|
14
14
|
initialValue?: undefined;
|
|
15
15
|
requireSync: true;
|
|
16
16
|
}): Signal<T>;
|
|
17
|
-
export declare function reactiveValueToSignal<T, const I>(source: ReactiveValue<T>, options: ReactiveValueToSignalOptions & {
|
|
17
|
+
export declare function reactiveValueToSignal<T, const I>(source: ReactiveValue<T>, options: ReactiveValueToSignalOptions<T | I> & {
|
|
18
18
|
initialValue: I;
|
|
19
19
|
requireSync?: false;
|
|
20
20
|
}): Signal<T | I>;
|