shelving 1.96.2 → 1.97.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/db/ItemReference.d.ts +4 -3
- package/db/ItemState.js +5 -5
- package/db/QueryReference.d.ts +3 -2
- package/db/QueryState.d.ts +1 -1
- package/db/QueryState.js +5 -4
- package/firestore/client/FirestoreClientProvider.js +2 -1
- package/firestore/lite/FirestoreLiteProvider.js +2 -1
- package/firestore/server/FirestoreServerProvider.js +2 -1
- package/package.json +1 -1
- package/provider/CacheProvider.js +2 -2
- package/provider/DebugProvider.js +53 -75
- package/provider/MemoryProvider.d.ts +16 -17
- package/provider/MemoryProvider.js +54 -93
- package/provider/ValidationProvider.js +11 -11
- package/react/useReduce.js +2 -2
- package/react/useState.js +4 -9
- package/sequence/DeferredSequence.d.ts +3 -2
- package/sequence/DeferredSequence.js +2 -2
- package/sequence/LazyDeferredSequence.d.ts +2 -2
- package/state/ArrayState.d.ts +2 -1
- package/state/ArrayState.js +2 -2
- package/state/BooleanState.d.ts +2 -1
- package/state/BooleanState.js +2 -2
- package/state/DataState.d.ts +2 -2
- package/state/DataState.js +2 -2
- package/state/DictionaryState.d.ts +2 -1
- package/state/DictionaryState.js +2 -2
- package/state/State.d.ts +21 -11
- package/state/State.js +33 -20
- package/util/activity.d.ts +13 -17
- package/util/activity.js +3 -17
- package/util/array.d.ts +6 -6
- package/util/array.js +9 -10
- package/util/async.d.ts +14 -22
- package/util/async.js +16 -33
- package/util/constants.d.ts +4 -2
- package/util/constants.js +4 -2
- package/util/data.d.ts +0 -2
- package/util/function.d.ts +8 -10
- package/util/function.js +5 -6
- package/util/map.d.ts +2 -2
- package/util/map.js +2 -2
- package/util/match.d.ts +2 -0
- package/util/match.js +6 -0
- package/util/null.d.ts +2 -2
- package/util/random.d.ts +3 -1
- package/util/random.js +9 -1
- package/util/sequence.d.ts +6 -5
- package/util/sequence.js +14 -14
- package/util/undefined.d.ts +5 -5
|
@@ -2,6 +2,7 @@ import { RequiredError } from "../error/RequiredError.js";
|
|
|
2
2
|
import { DeferredSequence } from "../sequence/DeferredSequence.js";
|
|
3
3
|
import { getArray } from "../util/array.js";
|
|
4
4
|
import { isArrayEqual } from "../util/equal.js";
|
|
5
|
+
import { filterSequence } from "../util/match.js";
|
|
5
6
|
import { queryItems, queryWritableItems } from "../util/query.js";
|
|
6
7
|
import { getRandomKey } from "../util/random.js";
|
|
7
8
|
import { updateData } from "../util/update.js";
|
|
@@ -19,7 +20,7 @@ export class MemoryProvider {
|
|
|
19
20
|
getTable(collection) {
|
|
20
21
|
return this._tables[collection] || (this._tables[collection] = new MemoryTable());
|
|
21
22
|
}
|
|
22
|
-
|
|
23
|
+
getItemTime(collection, id) {
|
|
23
24
|
return this.getTable(collection).getItemTime(id);
|
|
24
25
|
}
|
|
25
26
|
getItem(collection, id) {
|
|
@@ -70,57 +71,49 @@ export class MemoryTable {
|
|
|
70
71
|
this._changed = new DeferredSequence();
|
|
71
72
|
}
|
|
72
73
|
getItemTime(id) {
|
|
73
|
-
return this._times.get(id)
|
|
74
|
+
return this._times.get(id);
|
|
74
75
|
}
|
|
75
76
|
getItem(id) {
|
|
76
|
-
return this._data.get(id)
|
|
77
|
+
return this._data.get(id);
|
|
77
78
|
}
|
|
78
79
|
async *getItemSequence(id) {
|
|
79
|
-
let last = this.
|
|
80
|
-
yield
|
|
80
|
+
let last = this._times.get(id);
|
|
81
|
+
yield this.getItem(id);
|
|
81
82
|
while (true) {
|
|
82
83
|
await this._changed;
|
|
83
|
-
const next = this.
|
|
84
|
-
if (next !== last)
|
|
85
|
-
|
|
84
|
+
const next = this._times.get(id);
|
|
85
|
+
if (next !== last) {
|
|
86
|
+
last = next;
|
|
87
|
+
yield this.getItem(id);
|
|
88
|
+
}
|
|
86
89
|
}
|
|
87
90
|
}
|
|
88
91
|
/** Subscribe to a query in this table, but only if the query has been explicitly set (i.e. has a time). */
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
if (this._times.has(id)) {
|
|
92
|
-
last = this.getItem(id);
|
|
93
|
-
yield last;
|
|
94
|
-
}
|
|
95
|
-
while (true) {
|
|
96
|
-
await this._changed;
|
|
97
|
-
if (this._times.has(id)) {
|
|
98
|
-
const next = this.getItem(id);
|
|
99
|
-
if (next !== last)
|
|
100
|
-
yield (last = next);
|
|
101
|
-
}
|
|
102
|
-
}
|
|
92
|
+
getCachedItemSequence(id) {
|
|
93
|
+
return filterSequence(this.getItemSequence(id), () => this._times.has(id));
|
|
103
94
|
}
|
|
104
95
|
addItem(data) {
|
|
105
96
|
let id = getRandomKey();
|
|
106
97
|
while (this._data.has(id))
|
|
107
98
|
id = getRandomKey(); // Regenerate ID until unique.
|
|
108
|
-
this.
|
|
109
|
-
this._times.set(id, Date.now());
|
|
110
|
-
this._changed.resolve();
|
|
99
|
+
this.setItemData({ ...data, id });
|
|
111
100
|
return id;
|
|
112
101
|
}
|
|
113
|
-
|
|
102
|
+
setItemData(item) {
|
|
114
103
|
const id = item.id;
|
|
115
|
-
this._data.
|
|
116
|
-
|
|
104
|
+
if (this._data.get(id) !== item) {
|
|
105
|
+
this._data.set(id, item);
|
|
106
|
+
this._times.set(id, Date.now());
|
|
107
|
+
this._changed.resolve();
|
|
108
|
+
return true;
|
|
109
|
+
}
|
|
110
|
+
return false;
|
|
117
111
|
}
|
|
118
112
|
setItem(id, item) {
|
|
119
|
-
this.
|
|
120
|
-
this._changed.resolve();
|
|
113
|
+
return this.setItemData(item.id === id ? item : { ...item, id });
|
|
121
114
|
}
|
|
122
115
|
setItemValue(id, value) {
|
|
123
|
-
return value
|
|
116
|
+
return value ? this.setItem(id, value) : this.deleteItem(id);
|
|
124
117
|
}
|
|
125
118
|
async *setItemValueSequence(id, sequence) {
|
|
126
119
|
for await (const value of sequence) {
|
|
@@ -132,22 +125,19 @@ export class MemoryTable {
|
|
|
132
125
|
const oldItem = this._data.get(id);
|
|
133
126
|
if (!oldItem)
|
|
134
127
|
throw new RequiredError(`Document "${id}" does not exist`);
|
|
135
|
-
|
|
136
|
-
if (oldItem !== newItem) {
|
|
137
|
-
this._data.set(id, newItem);
|
|
138
|
-
this._times.set(id, Date.now());
|
|
139
|
-
this._changed.resolve();
|
|
140
|
-
}
|
|
128
|
+
return this.setItemData(updateData(oldItem, updates));
|
|
141
129
|
}
|
|
142
130
|
deleteItem(id) {
|
|
143
131
|
if (this._data.has(id)) {
|
|
144
132
|
this._data.delete(id);
|
|
145
133
|
this._times.set(id, Date.now());
|
|
146
134
|
this._changed.resolve();
|
|
135
|
+
return true;
|
|
147
136
|
}
|
|
137
|
+
return false;
|
|
148
138
|
}
|
|
149
139
|
getQueryTime(query) {
|
|
150
|
-
return this._times.get(_getQueryKey(query)) ||
|
|
140
|
+
return this._times.get(_getQueryKey(query)) || undefined;
|
|
151
141
|
}
|
|
152
142
|
getQuery(query) {
|
|
153
143
|
return getArray(queryItems(this._data.values(), query));
|
|
@@ -163,99 +153,70 @@ export class MemoryTable {
|
|
|
163
153
|
}
|
|
164
154
|
}
|
|
165
155
|
/** Subscribe to a query in this table, but only if the query has been explicitly set (i.e. has a time). */
|
|
166
|
-
|
|
156
|
+
getCachedQuerySequence(query) {
|
|
167
157
|
const key = _getQueryKey(query);
|
|
168
|
-
|
|
169
|
-
if (this._times.has(key)) {
|
|
170
|
-
last = this.getQuery(query);
|
|
171
|
-
yield last;
|
|
172
|
-
}
|
|
173
|
-
while (true) {
|
|
174
|
-
await this._changed;
|
|
175
|
-
if (this._times.has(key)) {
|
|
176
|
-
const next = this.getQuery(query);
|
|
177
|
-
if (!last || !isArrayEqual(last, next))
|
|
178
|
-
yield (last = next);
|
|
179
|
-
}
|
|
180
|
-
}
|
|
158
|
+
return filterSequence(this.getQuerySequence(query), () => this._times.has(key));
|
|
181
159
|
}
|
|
182
|
-
|
|
160
|
+
setItemArray(items) {
|
|
161
|
+
let count = 0;
|
|
183
162
|
for (const item of items)
|
|
184
|
-
this.
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
this._setItems(items);
|
|
188
|
-
if (items.length)
|
|
189
|
-
this._changed.resolve();
|
|
163
|
+
if (this.setItemData(item))
|
|
164
|
+
count++;
|
|
165
|
+
return count;
|
|
190
166
|
}
|
|
191
|
-
async *
|
|
167
|
+
async *setItemArraySequence(sequence) {
|
|
192
168
|
for await (const items of sequence) {
|
|
193
|
-
this.
|
|
169
|
+
this.setItemArray(items);
|
|
194
170
|
yield items;
|
|
195
171
|
}
|
|
196
172
|
}
|
|
197
|
-
|
|
173
|
+
setQueryArray(query, items) {
|
|
198
174
|
const key = _getQueryKey(query);
|
|
199
|
-
|
|
200
|
-
this.
|
|
201
|
-
this._setItems(items, now);
|
|
175
|
+
this._times.set(key, Date.now());
|
|
176
|
+
this.setItemArray(items);
|
|
202
177
|
this._changed.resolve();
|
|
203
178
|
}
|
|
204
|
-
async *
|
|
179
|
+
async *setQueryArraySequence(query, sequence) {
|
|
205
180
|
const key = _getQueryKey(query);
|
|
206
181
|
for await (const items of sequence) {
|
|
207
|
-
|
|
208
|
-
this.
|
|
209
|
-
this._setItems(items, now);
|
|
182
|
+
this._times.set(key, Date.now());
|
|
183
|
+
this.setItemArray(items);
|
|
210
184
|
this._changed.resolve();
|
|
211
185
|
yield items;
|
|
212
186
|
}
|
|
213
187
|
}
|
|
214
188
|
setQuery(query, data) {
|
|
215
|
-
const now = Date.now();
|
|
216
189
|
let count = 0;
|
|
217
|
-
for (const { id } of queryWritableItems(this._data.values(), query))
|
|
218
|
-
this.
|
|
219
|
-
|
|
220
|
-
count++;
|
|
221
|
-
}
|
|
190
|
+
for (const { id } of queryWritableItems(this._data.values(), query))
|
|
191
|
+
if (this.setItem(id, data))
|
|
192
|
+
count++;
|
|
222
193
|
if (count) {
|
|
223
194
|
const key = _getQueryKey(query);
|
|
224
|
-
this._times.set(key, now);
|
|
195
|
+
this._times.set(key, Date.now());
|
|
225
196
|
this._changed.resolve();
|
|
226
197
|
}
|
|
227
198
|
return count;
|
|
228
199
|
}
|
|
229
200
|
updateQuery(query, updates) {
|
|
230
|
-
const now = Date.now();
|
|
231
201
|
let count = 0;
|
|
232
|
-
for (const
|
|
233
|
-
|
|
234
|
-
if (oldItem !== newItem) {
|
|
235
|
-
const id = oldItem.id;
|
|
236
|
-
this._data.set(id, newItem);
|
|
237
|
-
this._times.set(id, now);
|
|
202
|
+
for (const { id } of queryWritableItems(this._data.values(), query))
|
|
203
|
+
if (this.updateItem(id, updates))
|
|
238
204
|
count++;
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
205
|
if (count) {
|
|
242
206
|
const key = _getQueryKey(query);
|
|
243
|
-
this._times.set(key, now);
|
|
207
|
+
this._times.set(key, Date.now());
|
|
244
208
|
this._changed.resolve();
|
|
245
209
|
}
|
|
246
210
|
return count;
|
|
247
211
|
}
|
|
248
212
|
deleteQuery(query) {
|
|
249
|
-
const now = Date.now();
|
|
250
213
|
let count = 0;
|
|
251
|
-
for (const { id } of queryWritableItems(this._data.values(), query))
|
|
252
|
-
this.
|
|
253
|
-
|
|
254
|
-
count++;
|
|
255
|
-
}
|
|
214
|
+
for (const { id } of queryWritableItems(this._data.values(), query))
|
|
215
|
+
if (this.deleteItem(id))
|
|
216
|
+
count++;
|
|
256
217
|
if (count) {
|
|
257
218
|
const key = _getQueryKey(query);
|
|
258
|
-
this._times.set(key, now);
|
|
219
|
+
this._times.set(key, Date.now());
|
|
259
220
|
this._changed.resolve();
|
|
260
221
|
}
|
|
261
222
|
return count;
|
|
@@ -18,12 +18,12 @@ class BaseValidationProvider {
|
|
|
18
18
|
async *getItemSequence(collection, id) {
|
|
19
19
|
const schema = this.getSchema(collection);
|
|
20
20
|
for await (const unsafeItem of this.source.getItemSequence(collection, id))
|
|
21
|
-
yield
|
|
21
|
+
yield _validateItemValue(collection, unsafeItem, schema);
|
|
22
22
|
}
|
|
23
23
|
async *getQuerySequence(collection, constraints) {
|
|
24
24
|
const schema = this.getSchema(collection);
|
|
25
25
|
for await (const unsafeItems of this.source.getQuerySequence(collection, constraints))
|
|
26
|
-
yield
|
|
26
|
+
yield _validateItemArray(collection, unsafeItems, schema);
|
|
27
27
|
}
|
|
28
28
|
}
|
|
29
29
|
/** Validate a synchronous source provider (source can have any type because validation guarantees the type). */
|
|
@@ -33,7 +33,7 @@ export class ValidationProvider extends BaseValidationProvider {
|
|
|
33
33
|
this.source = source;
|
|
34
34
|
}
|
|
35
35
|
getItem(collection, id) {
|
|
36
|
-
return
|
|
36
|
+
return _validateItemValue(collection, this.source.getItem(collection, id), this.getSchema(collection));
|
|
37
37
|
}
|
|
38
38
|
addItem(collection, data) {
|
|
39
39
|
return this.source.addItem(collection, validateWithContext(data, this.getSchema(collection), VALIDATION_CONTEXT_ADD));
|
|
@@ -49,7 +49,7 @@ export class ValidationProvider extends BaseValidationProvider {
|
|
|
49
49
|
return this.source.deleteItem(collection, id);
|
|
50
50
|
}
|
|
51
51
|
getQuery(collection, constraints) {
|
|
52
|
-
return
|
|
52
|
+
return _validateItemArray(collection, this.source.getQuery(collection, constraints), this.getSchema(collection));
|
|
53
53
|
}
|
|
54
54
|
setQuery(collection, constraints, value) {
|
|
55
55
|
return this.source.setQuery(collection, constraints, validate(value, this.getSchema(collection)));
|
|
@@ -69,7 +69,7 @@ export class AsyncValidationProvider extends BaseValidationProvider {
|
|
|
69
69
|
this.source = source;
|
|
70
70
|
}
|
|
71
71
|
async getItem(collection, id) {
|
|
72
|
-
return
|
|
72
|
+
return _validateItemValue(collection, await this.source.getItem(collection, id), this.getSchema(collection));
|
|
73
73
|
}
|
|
74
74
|
addItem(collection, data) {
|
|
75
75
|
return this.source.addItem(collection, validateWithContext(data, this.getSchema(collection), VALIDATION_CONTEXT_ADD));
|
|
@@ -85,7 +85,7 @@ export class AsyncValidationProvider extends BaseValidationProvider {
|
|
|
85
85
|
return this.source.deleteItem(collection, id);
|
|
86
86
|
}
|
|
87
87
|
async getQuery(collection, constraints) {
|
|
88
|
-
return
|
|
88
|
+
return _validateItemArray(collection, await this.source.getQuery(collection, constraints), this.getSchema(collection));
|
|
89
89
|
}
|
|
90
90
|
setQuery(collection, constraints, value) {
|
|
91
91
|
return this.source.setQuery(collection, constraints, validateWithContext(value, this.getSchema(collection), VALIDATION_CONTEXT_SET));
|
|
@@ -99,9 +99,9 @@ export class AsyncValidationProvider extends BaseValidationProvider {
|
|
|
99
99
|
}
|
|
100
100
|
}
|
|
101
101
|
/** Validate an entity for a document reference. */
|
|
102
|
-
function
|
|
102
|
+
function _validateItemValue(collection, unsafeEntity, schema) {
|
|
103
103
|
if (!unsafeEntity)
|
|
104
|
-
return
|
|
104
|
+
return undefined;
|
|
105
105
|
try {
|
|
106
106
|
return validateWithContext(unsafeEntity, schema, VALIDATION_CONTEXT_GET);
|
|
107
107
|
}
|
|
@@ -112,10 +112,10 @@ function _validateItem(collection, unsafeEntity, schema) {
|
|
|
112
112
|
}
|
|
113
113
|
}
|
|
114
114
|
/** Validate a set of entities for this query reference. */
|
|
115
|
-
function
|
|
116
|
-
return Array.from(
|
|
115
|
+
function _validateItemArray(collection, unsafeEntities, schema) {
|
|
116
|
+
return Array.from(_validateItems(collection, unsafeEntities, schema));
|
|
117
117
|
}
|
|
118
|
-
function*
|
|
118
|
+
function* _validateItems(collection, unsafeEntities, schema) {
|
|
119
119
|
let invalid = false;
|
|
120
120
|
const messages = {};
|
|
121
121
|
for (const unsafeEntity of unsafeEntities) {
|
package/react/useReduce.js
CHANGED
package/react/useState.js
CHANGED
|
@@ -4,17 +4,12 @@ import { mapArray } from "../util/transform.js";
|
|
|
4
4
|
import { isDefined } from "../util/undefined.js";
|
|
5
5
|
export function useState(...states) {
|
|
6
6
|
const setValue = useReactState(undefined)[1];
|
|
7
|
-
const [error, setError] = useReactState(undefined);
|
|
8
7
|
useEffect(() => {
|
|
9
|
-
const
|
|
10
|
-
const stops = mapArray(states, _startState,
|
|
8
|
+
const rerender = () => setValue({});
|
|
9
|
+
const stops = mapArray(states, _startState, rerender);
|
|
11
10
|
return () => stops.filter(isDefined).forEach(dispatch);
|
|
12
11
|
}, states);
|
|
13
|
-
if (error)
|
|
14
|
-
throw error;
|
|
15
12
|
return states.length <= 1 ? states[0] : states;
|
|
16
13
|
}
|
|
17
|
-
/** Start a subscription to a `ReferenceState` instance. */
|
|
18
|
-
|
|
19
|
-
return state === null || state === void 0 ? void 0 : state.next.to(setValue, setError);
|
|
20
|
-
}
|
|
14
|
+
/** Start a subscription to a `ReferenceState` instance and rerender a new value or error is issued. */
|
|
15
|
+
const _startState = (state, rerender) => state === null || state === void 0 ? void 0 : state.next.to(rerender, rerender);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Stop } from "../util/activity.js";
|
|
2
|
+
import type { Dispatch, Handler } from "../util/function.js";
|
|
2
3
|
import { AbstractSequence } from "./AbstractSequence.js";
|
|
3
4
|
/**
|
|
4
5
|
* Deferred sequence of values.
|
|
@@ -30,5 +31,5 @@ export declare class DeferredSequence<T = void, R = void> extends AbstractSequen
|
|
|
30
31
|
/** Pull values from a source sequence until the returned stop function is called. */
|
|
31
32
|
from(source: AsyncIterable<T>, onError?: Handler): Stop;
|
|
32
33
|
/** Subscrbe to the value of the sequence with a callback until the returned stop function is called. */
|
|
33
|
-
to(onNext: Dispatch<
|
|
34
|
+
to(onNext: Dispatch<T>, onError?: Handler): Stop;
|
|
34
35
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getDeferred } from "../util/async.js";
|
|
2
2
|
import { runSequence } from "../util/sequence.js";
|
|
3
3
|
import { AbstractSequence } from "./AbstractSequence.js";
|
|
4
4
|
/** Used when the deferred sequence has no value or reason queued. */
|
|
@@ -41,7 +41,7 @@ export class DeferredSequence extends AbstractSequence {
|
|
|
41
41
|
}
|
|
42
42
|
/** Get the next promise to be deferred/rejected. */
|
|
43
43
|
get value() {
|
|
44
|
-
return (this._deferred || (this._deferred =
|
|
44
|
+
return (this._deferred || (this._deferred = getDeferred())).promise;
|
|
45
45
|
}
|
|
46
46
|
// Implement `AsyncIterator`
|
|
47
47
|
async next() {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import type { Start } from "../util/
|
|
1
|
+
import type { Start } from "../util/activity.js";
|
|
2
2
|
import { DeferredSequence } from "./DeferredSequence.js";
|
|
3
3
|
/** Deferred sequence of values that lazily calls a start function when it has iterators that are iterating, and stops the activity when all iterators are done. */
|
|
4
4
|
export declare class LazyDeferredSequence<T = void, R = void> extends DeferredSequence<T, R> {
|
|
5
5
|
/** Store a list of iterators currently iterating over this iterable. */
|
|
6
6
|
private readonly _iterators;
|
|
7
|
-
constructor(start: Start<
|
|
7
|
+
constructor(start: Start<DeferredSequence<T, R>>);
|
|
8
8
|
[Symbol.asyncIterator](): AsyncGenerator<T, R, void>;
|
|
9
9
|
}
|
package/state/ArrayState.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
import type { StateOptions } from "./State.js";
|
|
1
2
|
import type { ImmutableArray } from "../util/array.js";
|
|
2
3
|
import { State } from "./State.js";
|
|
3
4
|
/** State that stores an array and has additional methods to help with that. */
|
|
4
5
|
export declare class ArrayState<T> extends State<ImmutableArray<T>> implements Iterable<T> {
|
|
5
|
-
constructor(
|
|
6
|
+
constructor(options?: StateOptions<ImmutableArray<T>>);
|
|
6
7
|
/** Get the length of the current value of this state. */
|
|
7
8
|
get count(): number;
|
|
8
9
|
/** Add items to this array. */
|
package/state/ArrayState.js
CHANGED
|
@@ -2,8 +2,8 @@ import { omitArrayItems, toggleArrayItems, withArrayItems } from "../util/array.
|
|
|
2
2
|
import { State } from "./State.js";
|
|
3
3
|
/** State that stores an array and has additional methods to help with that. */
|
|
4
4
|
export class ArrayState extends State {
|
|
5
|
-
constructor(
|
|
6
|
-
super(
|
|
5
|
+
constructor(options = {}) {
|
|
6
|
+
super("value" in options ? options : { value: [], ...options });
|
|
7
7
|
}
|
|
8
8
|
/** Get the length of the current value of this state. */
|
|
9
9
|
get count() {
|
package/state/BooleanState.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
import type { StateOptions } from "./State.js";
|
|
1
2
|
import { State } from "./State.js";
|
|
2
3
|
/** State that stores a boolean and has additional methods to help with that. */
|
|
3
4
|
export declare class BooleanState extends State<boolean> {
|
|
4
|
-
constructor(
|
|
5
|
+
constructor(options?: StateOptions<boolean>);
|
|
5
6
|
/** Toggle the current boolean value. */
|
|
6
7
|
toggle(): void;
|
|
7
8
|
}
|
package/state/BooleanState.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { State } from "./State.js";
|
|
2
2
|
/** State that stores a boolean and has additional methods to help with that. */
|
|
3
3
|
export class BooleanState extends State {
|
|
4
|
-
constructor(
|
|
5
|
-
super(
|
|
4
|
+
constructor(options = {}) {
|
|
5
|
+
super("value" in options ? options : { ...options, value: false });
|
|
6
6
|
}
|
|
7
7
|
/** Toggle the current boolean value. */
|
|
8
8
|
toggle() {
|
package/state/DataState.d.ts
CHANGED
|
@@ -13,7 +13,7 @@ export declare class DataState<T extends Data> extends State<T> {
|
|
|
13
13
|
setProp<K extends DataKey<T>>(name: K, value: T[K]): void;
|
|
14
14
|
}
|
|
15
15
|
/** State that stores an optional data object and has additional methods to help with that. */
|
|
16
|
-
export declare class OptionalDataState<T extends Data> extends State<T |
|
|
16
|
+
export declare class OptionalDataState<T extends Data> extends State<T | undefined> {
|
|
17
17
|
/** Get current data value of this state (or throw `Promise` that resolves to the next required value). */
|
|
18
18
|
get data(): T;
|
|
19
19
|
/** Does the data exist or not? */
|
|
@@ -24,6 +24,6 @@ export declare class OptionalDataState<T extends Data> extends State<T | null> {
|
|
|
24
24
|
getProp<K extends DataKey<T>>(name: K): T[K];
|
|
25
25
|
/** Update a single named prop in this data. */
|
|
26
26
|
setProp<K extends DataKey<T>>(name: K, value: T[K]): void;
|
|
27
|
-
/** Set the data to `
|
|
27
|
+
/** Set the data to `undefined`. */
|
|
28
28
|
unset(): void;
|
|
29
29
|
}
|
package/state/DataState.js
CHANGED
|
@@ -43,8 +43,8 @@ export class OptionalDataState extends State {
|
|
|
43
43
|
setProp(name, value) {
|
|
44
44
|
this.set(withProp(this.data, name, value));
|
|
45
45
|
}
|
|
46
|
-
/** Set the data to `
|
|
46
|
+
/** Set the data to `undefined`. */
|
|
47
47
|
unset() {
|
|
48
|
-
this.set(
|
|
48
|
+
this.set(undefined);
|
|
49
49
|
}
|
|
50
50
|
}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
+
import type { StateOptions } from "./State.js";
|
|
1
2
|
import type { DictionaryItem, ImmutableDictionary } from "../util/dictionary.js";
|
|
2
3
|
import type { Updates } from "../util/update.js";
|
|
3
4
|
import { State } from "./State.js";
|
|
4
5
|
/** State that stores a dictionary object and has additional methods to help with that. */
|
|
5
6
|
export declare class DictionaryState<T> extends State<ImmutableDictionary<T>> implements Iterable<DictionaryItem<T>> {
|
|
6
|
-
constructor(
|
|
7
|
+
constructor(options?: StateOptions<ImmutableDictionary<T>>);
|
|
7
8
|
/** Get the length of the current value of this state. */
|
|
8
9
|
get count(): number;
|
|
9
10
|
/** Set a named entry in this object with a different value. */
|
package/state/DictionaryState.js
CHANGED
|
@@ -4,8 +4,8 @@ import { updateData } from "../util/update.js";
|
|
|
4
4
|
import { State } from "./State.js";
|
|
5
5
|
/** State that stores a dictionary object and has additional methods to help with that. */
|
|
6
6
|
export class DictionaryState extends State {
|
|
7
|
-
constructor(
|
|
8
|
-
super(
|
|
7
|
+
constructor(options = {}) {
|
|
8
|
+
super("value" in options ? options : { ...options, value: {} });
|
|
9
9
|
}
|
|
10
10
|
/** Get the length of the current value of this state. */
|
|
11
11
|
get count() {
|
package/state/State.d.ts
CHANGED
|
@@ -1,8 +1,15 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Stop } from "../util/activity.js";
|
|
2
|
+
import type { Dispatch, Handler } from "../util/function.js";
|
|
2
3
|
import type { Validatable } from "../util/validate.js";
|
|
3
4
|
import { DeferredSequence } from "../sequence/DeferredSequence.js";
|
|
4
5
|
/** Any `State` instance. */
|
|
5
6
|
export type AnyState = State<any>;
|
|
7
|
+
/** Options for a `State` instance. */
|
|
8
|
+
export type StateOptions<T> = {
|
|
9
|
+
value?: T;
|
|
10
|
+
time?: number | undefined;
|
|
11
|
+
next?: DeferredSequence<T> | undefined;
|
|
12
|
+
};
|
|
6
13
|
/**
|
|
7
14
|
* Stream that retains its most recent value
|
|
8
15
|
* - Current value can be read at `state.value` and `state.data`
|
|
@@ -10,34 +17,37 @@ export type AnyState = State<any>;
|
|
|
10
17
|
* - States can also be in a loading state where they do not have a current value.
|
|
11
18
|
*
|
|
12
19
|
* @param initial The initial value for the state, a `Promise` that resolves to the initial value, a source `Subscribable` to subscribe to, or another `State` instance to take the initial value from and subscribe to.
|
|
13
|
-
* - To set the state to be loading, use the `
|
|
20
|
+
* - To set the state to be loading, use the `NONE` constant or a `Promise` value.
|
|
14
21
|
* - To set the state to an explicit value, use that value or another `State` instance with a value.
|
|
15
22
|
* */
|
|
16
23
|
export declare class State<T> implements AsyncIterable<T>, Validatable<T> {
|
|
17
|
-
/** The `NOVALUE` symbol indicates no value has been received by a `State` instance. */
|
|
18
|
-
static readonly NOVALUE: unique symbol;
|
|
19
24
|
/** Deferred sequence this state uses to issue values as they change. */
|
|
20
25
|
readonly next: DeferredSequence<T>;
|
|
21
|
-
/**
|
|
26
|
+
/** Current value of the state (or throw a promise that resolves when this state receives its next value or error). */
|
|
22
27
|
get value(): T;
|
|
23
28
|
private _value;
|
|
24
29
|
/** Time this state was last updated with a new value. */
|
|
25
|
-
get time(): number |
|
|
26
|
-
|
|
30
|
+
get time(): number | undefined;
|
|
31
|
+
private _time;
|
|
32
|
+
/** Is there a current value, or is it still loading. */
|
|
33
|
+
get loading(): boolean;
|
|
27
34
|
/** How old this state's value is (in milliseconds). */
|
|
28
35
|
get age(): number;
|
|
36
|
+
/** Current error of this state (or `undefined` if there is no reason). */
|
|
37
|
+
get reason(): unknown;
|
|
38
|
+
private _reason;
|
|
29
39
|
/** State is initiated with an initial state. */
|
|
30
|
-
constructor(
|
|
31
|
-
/** Is there a current value, or is it still loading. */
|
|
32
|
-
get loading(): boolean;
|
|
40
|
+
constructor(options?: StateOptions<T>);
|
|
33
41
|
/** Set the value of the state. */
|
|
34
42
|
set(next: T): void;
|
|
43
|
+
/** Set the error reason of the state (will be */
|
|
44
|
+
error(reason: unknown): void;
|
|
35
45
|
/** Set the value of the state as values are pulled from a sequence. */
|
|
36
46
|
through(sequence: AsyncIterable<T>): AsyncIterable<T>;
|
|
37
47
|
/** Pull values from a source sequence until the returned stop function is called. */
|
|
38
48
|
from(source: AsyncIterable<T>, onError?: Handler): Stop;
|
|
39
49
|
/** Push values to another state or callback to this state until the returned stop function is called. */
|
|
40
|
-
to(target: Dispatch<
|
|
50
|
+
to(target: Dispatch<T>, onError?: Handler): Stop;
|
|
41
51
|
[Symbol.asyncIterator](): AsyncIterator<T>;
|
|
42
52
|
/** Validate data set on this state. */
|
|
43
53
|
validate(value: T): T;
|