shelving 1.96.2 → 1.98.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 +3 -3
- package/db/ItemState.d.ts +2 -2
- package/db/ItemState.js +6 -6
- package/db/QueryReference.d.ts +2 -2
- package/db/QueryState.d.ts +2 -2
- package/db/QueryState.js +6 -5
- package/firestore/client/FirestoreClientProvider.js +7 -6
- package/firestore/lite/FirestoreLiteProvider.js +2 -1
- package/firestore/server/FirestoreServerProvider.js +7 -6
- package/iterate/AbstractGenerator.d.ts +1 -1
- package/iterate/AbstractGenerator.js +3 -10
- 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 +6 -11
- package/sequence/AbstractSequence.d.ts +1 -1
- package/sequence/AbstractSequence.js +3 -10
- package/sequence/DeferredSequence.d.ts +10 -8
- package/sequence/DeferredSequence.js +11 -10
- package/sequence/SwitchingDeferredSequence.d.ts +8 -0
- package/sequence/SwitchingDeferredSequence.js +13 -0
- package/sequence/SwitchingSequence.d.ts +10 -0
- package/sequence/SwitchingSequence.js +52 -0
- package/sequence/index.d.ts +2 -2
- package/sequence/index.js +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 -12
- package/state/State.js +33 -20
- package/util/array.d.ts +6 -6
- package/util/array.js +9 -10
- package/util/async.d.ts +16 -24
- package/util/async.js +16 -33
- package/util/callback.d.ts +22 -0
- package/util/callback.js +26 -0
- package/util/class.d.ts +0 -25
- package/util/class.js +0 -61
- package/util/constants.d.ts +4 -2
- package/util/constants.js +4 -2
- package/util/data.d.ts +0 -2
- package/util/error.d.ts +2 -2
- package/util/function.d.ts +0 -18
- package/util/function.js +0 -28
- package/util/index.d.ts +1 -1
- package/util/index.js +1 -1
- 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 +5 -5
- package/util/sequence.js +16 -16
- package/util/switch.d.ts +33 -0
- package/util/switch.js +49 -0
- package/util/timeout.d.ts +3 -4
- package/util/timeout.js +3 -8
- package/util/undefined.d.ts +5 -5
- package/sequence/LazyDeferredSequence.d.ts +0 -9
- package/sequence/LazyDeferredSequence.js +0 -14
- package/sequence/RegisteringSequence.d.ts +0 -9
- package/sequence/RegisteringSequence.js +0 -51
- package/util/activity.d.ts +0 -38
- package/util/activity.js +0 -64
|
@@ -13,14 +13,14 @@ export declare class MemoryProvider implements Provider {
|
|
|
13
13
|
private _tables;
|
|
14
14
|
/** Get a table for a collection. */
|
|
15
15
|
getTable(collection: string): MemoryTable;
|
|
16
|
-
|
|
16
|
+
getItemTime(collection: string, id: string): number | undefined;
|
|
17
17
|
getItem(collection: string, id: string): ItemValue;
|
|
18
18
|
getItemSequence(collection: string, id: string): AsyncIterable<ItemValue>;
|
|
19
19
|
addItem(collection: string, data: Data): string;
|
|
20
|
-
setItem(collection: string, id: string, data: Data):
|
|
21
|
-
updateItem(collection: string, id: string, updates: Updates):
|
|
22
|
-
deleteItem(collection: string, id: string):
|
|
23
|
-
getQueryTime(collection: string, query: ItemQuery): number |
|
|
20
|
+
setItem(collection: string, id: string, data: Data): boolean;
|
|
21
|
+
updateItem(collection: string, id: string, updates: Updates): boolean;
|
|
22
|
+
deleteItem(collection: string, id: string): boolean;
|
|
23
|
+
getQueryTime(collection: string, query: ItemQuery): number | undefined;
|
|
24
24
|
getQuery(collection: string, query: ItemQuery): ItemArray;
|
|
25
25
|
getQuerySequence(collection: string, query: ItemQuery): AsyncIterable<ItemArray>;
|
|
26
26
|
setQuery(collection: string, query: ItemQuery, data: Data): number;
|
|
@@ -35,28 +35,27 @@ export declare class MemoryTable<T extends Data = Data> {
|
|
|
35
35
|
protected readonly _times: Map<string, number>;
|
|
36
36
|
/** Deferred sequence of next values. */
|
|
37
37
|
readonly _changed: DeferredSequence<void, void>;
|
|
38
|
-
getItemTime(id: string): number |
|
|
38
|
+
getItemTime(id: string): number | undefined;
|
|
39
39
|
getItem(id: string): ItemValue<T>;
|
|
40
40
|
getItemSequence(id: string): AsyncIterable<ItemValue<T>>;
|
|
41
41
|
/** Subscribe to a query in this table, but only if the query has been explicitly set (i.e. has a time). */
|
|
42
42
|
getCachedItemSequence(id: string): AsyncIterable<ItemValue<T>>;
|
|
43
43
|
addItem(data: T): string;
|
|
44
|
-
|
|
45
|
-
setItem(id: string, item: ItemData<T> | T):
|
|
46
|
-
setItemValue(id: string, value: ItemData<T> | T |
|
|
44
|
+
setItemData(item: ItemData<T>): boolean;
|
|
45
|
+
setItem(id: string, item: ItemData<T> | T): boolean;
|
|
46
|
+
setItemValue(id: string, value: ItemData<T> | T | undefined): boolean;
|
|
47
47
|
setItemValueSequence(id: string, sequence: AsyncIterable<ItemValue<T>>): AsyncIterable<ItemValue>;
|
|
48
|
-
updateItem(id: string, updates: Updates<T>):
|
|
49
|
-
deleteItem(id: string):
|
|
50
|
-
getQueryTime(query: ItemQuery<T>): number |
|
|
48
|
+
updateItem(id: string, updates: Updates<T>): boolean;
|
|
49
|
+
deleteItem(id: string): boolean;
|
|
50
|
+
getQueryTime(query: ItemQuery<T>): number | undefined;
|
|
51
51
|
getQuery(query: ItemQuery<T>): ItemArray<T>;
|
|
52
52
|
getQuerySequence(query: ItemQuery<T>): AsyncIterable<ItemArray<T>>;
|
|
53
53
|
/** Subscribe to a query in this table, but only if the query has been explicitly set (i.e. has a time). */
|
|
54
54
|
getCachedQuerySequence(query: ItemQuery<T>): AsyncIterable<ItemArray<T>>;
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
setQueryItemsSequence(query: ItemQuery<T>, sequence: AsyncIterable<ItemArray<T>>): AsyncIterable<ItemArray<T>>;
|
|
55
|
+
setItemArray(items: ItemArray<T>): number;
|
|
56
|
+
setItemArraySequence(sequence: AsyncIterable<ItemArray<T>>): AsyncIterable<ItemArray<T>>;
|
|
57
|
+
setQueryArray(query: ItemQuery<T>, items: ItemArray<T>): void;
|
|
58
|
+
setQueryArraySequence(query: ItemQuery<T>, sequence: AsyncIterable<ItemArray<T>>): AsyncIterable<ItemArray<T>>;
|
|
60
59
|
setQuery(query: ItemQuery<T>, data: T): number;
|
|
61
60
|
updateQuery(query: ItemQuery<T>, updates: Updates<T>): number;
|
|
62
61
|
deleteQuery(query: ItemQuery<T>): number;
|
|
@@ -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
|
@@ -1,20 +1,15 @@
|
|
|
1
1
|
import { useEffect, useState as useReactState } from "react";
|
|
2
|
-
import {
|
|
2
|
+
import { call } from "../util/callback.js";
|
|
3
3
|
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,
|
|
11
|
-
return () => stops.filter(isDefined).forEach(
|
|
8
|
+
const rerender = () => setValue({});
|
|
9
|
+
const stops = mapArray(states, _startState, rerender);
|
|
10
|
+
return () => stops.filter(isDefined).forEach(call);
|
|
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,6 +1,6 @@
|
|
|
1
1
|
/** Sequence of values designed to be extended that implements the full async generator protocol. */
|
|
2
2
|
export declare abstract class AbstractSequence<T, R> implements AsyncGenerator<T, R, void> {
|
|
3
|
-
readonly [Symbol.toStringTag]
|
|
3
|
+
readonly [Symbol.toStringTag] = "Sequence";
|
|
4
4
|
abstract next(): Promise<IteratorResult<T, R>>;
|
|
5
5
|
return(returnValue: R | PromiseLike<R>): Promise<IteratorResult<T, R>>;
|
|
6
6
|
throw(reason: Error | unknown): Promise<IteratorResult<T, R>>;
|
|
@@ -1,13 +1,9 @@
|
|
|
1
|
-
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
-
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
-
};
|
|
7
1
|
var _a;
|
|
8
|
-
import { setPrototype } from "../util/class.js";
|
|
9
2
|
/** Sequence of values designed to be extended that implements the full async generator protocol. */
|
|
10
3
|
export class AbstractSequence {
|
|
4
|
+
constructor() {
|
|
5
|
+
this[_a] = "Sequence";
|
|
6
|
+
}
|
|
11
7
|
async return(returnValue) {
|
|
12
8
|
// Default behaviour for a generator is to return `done: true` and the input value.
|
|
13
9
|
return { done: true, value: await returnValue };
|
|
@@ -21,6 +17,3 @@ export class AbstractSequence {
|
|
|
21
17
|
return this;
|
|
22
18
|
}
|
|
23
19
|
}
|
|
24
|
-
__decorate([
|
|
25
|
-
setPrototype(Symbol.toStringTag, "Sequence")
|
|
26
|
-
], AbstractSequence.prototype, _a, void 0);
|
|
@@ -1,23 +1,25 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Deferred } from "../util/async.js";
|
|
2
|
+
import type { Callback, ErrorCallback, StopCallback } from "../util/callback.js";
|
|
2
3
|
import { AbstractSequence } from "./AbstractSequence.js";
|
|
3
4
|
/**
|
|
4
|
-
* Deferred sequence of values.
|
|
5
|
+
* Deferred sequence of values that can be async iterated and new values can be published.
|
|
5
6
|
* - Implements `AsyncIterable` so values can be iterated over using `for await...of`
|
|
6
7
|
* - Implements `Promise` so the next value can be awaited.
|
|
8
|
+
* - Implements `Deferred` so next values can be resolved or rejected.
|
|
7
9
|
*/
|
|
8
|
-
export declare class DeferredSequence<T = void, R = void> extends AbstractSequence<T, R> implements Promise<T> {
|
|
10
|
+
export declare class DeferredSequence<T = void, R = void> extends AbstractSequence<T, R> implements Deferred<T>, Promise<T> {
|
|
9
11
|
/**
|
|
10
12
|
* Next deferred to be rejected/resolved, or `undefined` if we haven't requested one yet..
|
|
11
13
|
* - Only create the deferred on demand, because we don't want to reject a deferred that isn't used to or it would throw an unhandled promise error.
|
|
12
14
|
*/
|
|
13
15
|
private _deferred;
|
|
14
16
|
/** Get the next promise to be deferred/rejected. */
|
|
15
|
-
get
|
|
17
|
+
get promise(): Promise<T>;
|
|
16
18
|
/** Resolve the current deferred in the sequence. */
|
|
17
|
-
readonly resolve:
|
|
19
|
+
readonly resolve: Callback<T>;
|
|
18
20
|
private _nextValue;
|
|
19
21
|
/** Reject the current deferred in the sequence. */
|
|
20
|
-
readonly reject:
|
|
22
|
+
readonly reject: ErrorCallback;
|
|
21
23
|
private _nextReason;
|
|
22
24
|
/** Fulfill the current deferred by resolving or rejecting it. */
|
|
23
25
|
private readonly _fulfill;
|
|
@@ -28,7 +30,7 @@ export declare class DeferredSequence<T = void, R = void> extends AbstractSequen
|
|
|
28
30
|
/** Resolve the current deferred from a sequence of values. */
|
|
29
31
|
through(sequence: AsyncIterable<T>): AsyncIterable<T>;
|
|
30
32
|
/** Pull values from a source sequence until the returned stop function is called. */
|
|
31
|
-
from(source: AsyncIterable<T>, onError?:
|
|
33
|
+
from(source: AsyncIterable<T>, onError?: ErrorCallback): StopCallback;
|
|
32
34
|
/** Subscrbe to the value of the sequence with a callback until the returned stop function is called. */
|
|
33
|
-
to(onNext:
|
|
35
|
+
to(onNext: Callback<T>, onError?: ErrorCallback): StopCallback;
|
|
34
36
|
}
|
|
@@ -1,25 +1,26 @@
|
|
|
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. */
|
|
5
5
|
const _NOVALUE = Symbol("shelving/DeferredSequence.NOVALUE");
|
|
6
6
|
/**
|
|
7
|
-
* Deferred sequence of values.
|
|
7
|
+
* Deferred sequence of values that can be async iterated and new values can be published.
|
|
8
8
|
* - Implements `AsyncIterable` so values can be iterated over using `for await...of`
|
|
9
9
|
* - Implements `Promise` so the next value can be awaited.
|
|
10
|
+
* - Implements `Deferred` so next values can be resolved or rejected.
|
|
10
11
|
*/
|
|
11
12
|
export class DeferredSequence extends AbstractSequence {
|
|
12
13
|
constructor() {
|
|
13
14
|
super(...arguments);
|
|
14
15
|
/** Resolve the current deferred in the sequence. */
|
|
15
|
-
this.resolve =
|
|
16
|
+
this.resolve = value => {
|
|
16
17
|
this._nextValue = value;
|
|
17
18
|
this._nextReason = _NOVALUE;
|
|
18
19
|
queueMicrotask(this._fulfill);
|
|
19
20
|
};
|
|
20
21
|
this._nextValue = _NOVALUE;
|
|
21
22
|
/** Reject the current deferred in the sequence. */
|
|
22
|
-
this.reject =
|
|
23
|
+
this.reject = reason => {
|
|
23
24
|
this._nextValue = _NOVALUE;
|
|
24
25
|
this._nextReason = reason;
|
|
25
26
|
queueMicrotask(this._fulfill);
|
|
@@ -40,22 +41,22 @@ export class DeferredSequence extends AbstractSequence {
|
|
|
40
41
|
};
|
|
41
42
|
}
|
|
42
43
|
/** Get the next promise to be deferred/rejected. */
|
|
43
|
-
get
|
|
44
|
-
return (this._deferred || (this._deferred =
|
|
44
|
+
get promise() {
|
|
45
|
+
return (this._deferred || (this._deferred = getDeferred())).promise;
|
|
45
46
|
}
|
|
46
47
|
// Implement `AsyncIterator`
|
|
47
48
|
async next() {
|
|
48
|
-
return { value: await this.
|
|
49
|
+
return { value: await this.promise };
|
|
49
50
|
}
|
|
50
51
|
// Implement `Promise`
|
|
51
52
|
then(onNext, onError) {
|
|
52
|
-
return this.
|
|
53
|
+
return this.promise.then(onNext, onError);
|
|
53
54
|
}
|
|
54
55
|
catch(onError) {
|
|
55
|
-
return this.
|
|
56
|
+
return this.promise.catch(onError);
|
|
56
57
|
}
|
|
57
58
|
finally(onFinally) {
|
|
58
|
-
return this.
|
|
59
|
+
return this.promise.finally(onFinally);
|
|
59
60
|
}
|
|
60
61
|
/** Resolve the current deferred from a sequence of values. */
|
|
61
62
|
async *through(sequence) {
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { StartCallback } from "../util/callback.js";
|
|
2
|
+
import { DeferredSequence } from "./DeferredSequence.js";
|
|
3
|
+
/** Deferred sequence of values that switches on when it has iterators that are iterating, and off when all iterators are done. */
|
|
4
|
+
export declare class SwitchingDeferredSequence<T = void, R = void> extends DeferredSequence<T, R> {
|
|
5
|
+
private readonly _switch;
|
|
6
|
+
constructor(start: StartCallback<DeferredSequence<T, R>>);
|
|
7
|
+
[Symbol.asyncIterator](): AsyncGenerator<T, R, void>;
|
|
8
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { SwitchingSet } from "../util/switch.js";
|
|
2
|
+
import { DeferredSequence } from "./DeferredSequence.js";
|
|
3
|
+
import { SwitchingSequence } from "./SwitchingSequence.js";
|
|
4
|
+
/** Deferred sequence of values that switches on when it has iterators that are iterating, and off when all iterators are done. */
|
|
5
|
+
export class SwitchingDeferredSequence extends DeferredSequence {
|
|
6
|
+
constructor(start) {
|
|
7
|
+
super();
|
|
8
|
+
this._switch = new SwitchingSet(() => start(this));
|
|
9
|
+
}
|
|
10
|
+
[Symbol.asyncIterator]() {
|
|
11
|
+
return new SwitchingSequence(this, this._switch);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { PossibleSwitch } from "../util/switch.js";
|
|
2
|
+
import { ThroughSequence } from "./ThroughSequence.js";
|
|
3
|
+
/** Async generator that switches on when it has iterators that are iterating, and off when all iterators are done. */
|
|
4
|
+
export declare class SwitchingSequence<T, R> extends ThroughSequence<T, R> implements ThroughSequence<T, R> {
|
|
5
|
+
private readonly _switch;
|
|
6
|
+
constructor(source: AsyncIterator<T, R>, switchable: PossibleSwitch<AsyncIterator<T, R>>);
|
|
7
|
+
next(): Promise<IteratorResult<T, R>>;
|
|
8
|
+
return(value: R | PromiseLike<R>): Promise<IteratorResult<T, R>>;
|
|
9
|
+
throw(reason: Error | unknown): Promise<IteratorResult<T, R>>;
|
|
10
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { getSwitch } from "../util/switch.js";
|
|
2
|
+
import { ThroughSequence } from "./ThroughSequence.js";
|
|
3
|
+
/** Async generator that switches on when it has iterators that are iterating, and off when all iterators are done. */
|
|
4
|
+
export class SwitchingSequence extends ThroughSequence {
|
|
5
|
+
constructor(source, switchable) {
|
|
6
|
+
super(source);
|
|
7
|
+
this._switch = getSwitch(switchable);
|
|
8
|
+
}
|
|
9
|
+
async next() {
|
|
10
|
+
this._switch.start(this); // Register this in anticipation that it'll continue iterating.
|
|
11
|
+
try {
|
|
12
|
+
const result = await super.next();
|
|
13
|
+
if (result.done)
|
|
14
|
+
this._switch.stop(this); // Deregister this.
|
|
15
|
+
else
|
|
16
|
+
this._switch.start(this); // Register this.
|
|
17
|
+
return result;
|
|
18
|
+
}
|
|
19
|
+
catch (caught) {
|
|
20
|
+
this._switch.stop(this);
|
|
21
|
+
throw caught;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
async return(value) {
|
|
25
|
+
try {
|
|
26
|
+
const result = await super.return(value);
|
|
27
|
+
if (result.done)
|
|
28
|
+
this._switch.stop(this); // Deregister this.
|
|
29
|
+
else
|
|
30
|
+
this._switch.start(this); // Stop this.
|
|
31
|
+
return result;
|
|
32
|
+
}
|
|
33
|
+
catch (caught) {
|
|
34
|
+
this._switch.stop(this);
|
|
35
|
+
throw caught;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
async throw(reason) {
|
|
39
|
+
try {
|
|
40
|
+
const result = await super.throw(reason);
|
|
41
|
+
if (result.done)
|
|
42
|
+
this._switch.stop(this); // Deregister this.
|
|
43
|
+
else
|
|
44
|
+
this._switch.start(this); // Start this.
|
|
45
|
+
return result;
|
|
46
|
+
}
|
|
47
|
+
catch (caught) {
|
|
48
|
+
this._switch.stop(this);
|
|
49
|
+
throw caught;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
package/sequence/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export * from "./AbstractSequence.js";
|
|
2
2
|
export * from "./DeferredSequence.js";
|
|
3
3
|
export * from "./InspectSequence.js";
|
|
4
|
-
export * from "./
|
|
5
|
-
export * from "./
|
|
4
|
+
export * from "./SwitchingSequence.js";
|
|
5
|
+
export * from "./SwitchingDeferredSequence.js";
|
|
6
6
|
export * from "./ThroughSequence.js";
|