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.
Files changed (75) hide show
  1. package/db/ItemReference.d.ts +3 -3
  2. package/db/ItemState.d.ts +2 -2
  3. package/db/ItemState.js +6 -6
  4. package/db/QueryReference.d.ts +2 -2
  5. package/db/QueryState.d.ts +2 -2
  6. package/db/QueryState.js +6 -5
  7. package/firestore/client/FirestoreClientProvider.js +7 -6
  8. package/firestore/lite/FirestoreLiteProvider.js +2 -1
  9. package/firestore/server/FirestoreServerProvider.js +7 -6
  10. package/iterate/AbstractGenerator.d.ts +1 -1
  11. package/iterate/AbstractGenerator.js +3 -10
  12. package/package.json +1 -1
  13. package/provider/CacheProvider.js +2 -2
  14. package/provider/DebugProvider.js +53 -75
  15. package/provider/MemoryProvider.d.ts +16 -17
  16. package/provider/MemoryProvider.js +54 -93
  17. package/provider/ValidationProvider.js +11 -11
  18. package/react/useReduce.js +2 -2
  19. package/react/useState.js +6 -11
  20. package/sequence/AbstractSequence.d.ts +1 -1
  21. package/sequence/AbstractSequence.js +3 -10
  22. package/sequence/DeferredSequence.d.ts +10 -8
  23. package/sequence/DeferredSequence.js +11 -10
  24. package/sequence/SwitchingDeferredSequence.d.ts +8 -0
  25. package/sequence/SwitchingDeferredSequence.js +13 -0
  26. package/sequence/SwitchingSequence.d.ts +10 -0
  27. package/sequence/SwitchingSequence.js +52 -0
  28. package/sequence/index.d.ts +2 -2
  29. package/sequence/index.js +2 -2
  30. package/state/ArrayState.d.ts +2 -1
  31. package/state/ArrayState.js +2 -2
  32. package/state/BooleanState.d.ts +2 -1
  33. package/state/BooleanState.js +2 -2
  34. package/state/DataState.d.ts +2 -2
  35. package/state/DataState.js +2 -2
  36. package/state/DictionaryState.d.ts +2 -1
  37. package/state/DictionaryState.js +2 -2
  38. package/state/State.d.ts +21 -12
  39. package/state/State.js +33 -20
  40. package/util/array.d.ts +6 -6
  41. package/util/array.js +9 -10
  42. package/util/async.d.ts +16 -24
  43. package/util/async.js +16 -33
  44. package/util/callback.d.ts +22 -0
  45. package/util/callback.js +26 -0
  46. package/util/class.d.ts +0 -25
  47. package/util/class.js +0 -61
  48. package/util/constants.d.ts +4 -2
  49. package/util/constants.js +4 -2
  50. package/util/data.d.ts +0 -2
  51. package/util/error.d.ts +2 -2
  52. package/util/function.d.ts +0 -18
  53. package/util/function.js +0 -28
  54. package/util/index.d.ts +1 -1
  55. package/util/index.js +1 -1
  56. package/util/map.d.ts +2 -2
  57. package/util/map.js +2 -2
  58. package/util/match.d.ts +2 -0
  59. package/util/match.js +6 -0
  60. package/util/null.d.ts +2 -2
  61. package/util/random.d.ts +3 -1
  62. package/util/random.js +9 -1
  63. package/util/sequence.d.ts +5 -5
  64. package/util/sequence.js +16 -16
  65. package/util/switch.d.ts +33 -0
  66. package/util/switch.js +49 -0
  67. package/util/timeout.d.ts +3 -4
  68. package/util/timeout.js +3 -8
  69. package/util/undefined.d.ts +5 -5
  70. package/sequence/LazyDeferredSequence.d.ts +0 -9
  71. package/sequence/LazyDeferredSequence.js +0 -14
  72. package/sequence/RegisteringSequence.d.ts +0 -9
  73. package/sequence/RegisteringSequence.js +0 -51
  74. package/util/activity.d.ts +0 -38
  75. 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
- getDocumentTime(collection: string, id: string): number | null;
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): void;
21
- updateItem(collection: string, id: string, updates: Updates): void;
22
- deleteItem(collection: string, id: string): void;
23
- getQueryTime(collection: string, query: ItemQuery): number | null;
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 | null;
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
- private _setItemData;
45
- setItem(id: string, item: ItemData<T> | T): void;
46
- setItemValue(id: string, value: ItemData<T> | T | null): void;
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>): void;
49
- deleteItem(id: string): void;
50
- getQueryTime(query: ItemQuery<T>): number | null;
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
- private _setItems;
56
- setItems(items: ItemArray<T>): void;
57
- setItemsSequence(sequence: AsyncIterable<ItemArray<T>>): AsyncIterable<ItemArray<T>>;
58
- setQueryItems(query: ItemQuery<T>, items: ItemArray<T>): void;
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
- getDocumentTime(collection, id) {
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) || null;
74
+ return this._times.get(id);
74
75
  }
75
76
  getItem(id) {
76
- return this._data.get(id) || null;
77
+ return this._data.get(id);
77
78
  }
78
79
  async *getItemSequence(id) {
79
- let last = this.getItem(id);
80
- yield last;
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.getItem(id);
84
- if (next !== last)
85
- yield (last = next);
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
- async *getCachedItemSequence(id) {
90
- let last = undefined;
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._data.set(id, { ...data, id });
109
- this._times.set(id, Date.now());
110
- this._changed.resolve();
99
+ this.setItemData({ ...data, id });
111
100
  return id;
112
101
  }
113
- _setItemData(item, now = Date.now()) {
102
+ setItemData(item) {
114
103
  const id = item.id;
115
- this._data.set(id, item);
116
- this._times.set(id, now);
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._setItemData(item.id === id ? item : { ...item, id });
120
- this._changed.resolve();
113
+ return this.setItemData(item.id === id ? item : { ...item, id });
121
114
  }
122
115
  setItemValue(id, value) {
123
- return value === null ? this.deleteItem(id) : this.setItem(id, 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
- const newItem = updateData(oldItem, updates);
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)) || null;
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
- async *getCachedQuerySequence(query) {
156
+ getCachedQuerySequence(query) {
167
157
  const key = _getQueryKey(query);
168
- let last = undefined;
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
- _setItems(items, now = Date.now()) {
160
+ setItemArray(items) {
161
+ let count = 0;
183
162
  for (const item of items)
184
- this._setItemData(item, now);
185
- }
186
- setItems(items) {
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 *setItemsSequence(sequence) {
167
+ async *setItemArraySequence(sequence) {
192
168
  for await (const items of sequence) {
193
- this.setItems(items);
169
+ this.setItemArray(items);
194
170
  yield items;
195
171
  }
196
172
  }
197
- setQueryItems(query, items) {
173
+ setQueryArray(query, items) {
198
174
  const key = _getQueryKey(query);
199
- const now = Date.now();
200
- this._times.set(key, now);
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 *setQueryItemsSequence(query, sequence) {
179
+ async *setQueryArraySequence(query, sequence) {
205
180
  const key = _getQueryKey(query);
206
181
  for await (const items of sequence) {
207
- const now = Date.now();
208
- this._times.set(key, now);
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._data.set(id, { ...data, id });
219
- this._times.set(id, now);
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 oldItem of queryWritableItems(this._data.values(), query)) {
233
- const newItem = updateData(oldItem, updates);
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._data.delete(id);
253
- this._times.set(id, now);
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 _validateItem(collection, unsafeItem, schema);
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 _validateItems(collection, unsafeItems, schema);
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 _validateItem(collection, this.source.getItem(collection, id), this.getSchema(collection));
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 _validateItems(collection, this.source.getQuery(collection, constraints), this.getSchema(collection));
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 _validateItem(collection, await this.source.getItem(collection, id), this.getSchema(collection));
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 _validateItems(collection, await this.source.getQuery(collection, constraints), this.getSchema(collection));
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 _validateItem(collection, unsafeEntity, schema) {
102
+ function _validateItemValue(collection, unsafeEntity, schema) {
103
103
  if (!unsafeEntity)
104
- return null;
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 _validateItems(collection, unsafeEntities, schema) {
116
- return Array.from(_yieldValidItems(collection, unsafeEntities, schema));
115
+ function _validateItemArray(collection, unsafeEntities, schema) {
116
+ return Array.from(_validateItems(collection, unsafeEntities, schema));
117
117
  }
118
- function* _yieldValidItems(collection, unsafeEntities, schema) {
118
+ function* _validateItems(collection, unsafeEntities, schema) {
119
119
  let invalid = false;
120
120
  const messages = {};
121
121
  for (const unsafeEntity of unsafeEntities) {
@@ -1,5 +1,5 @@
1
1
  import { useRef } from "react";
2
2
  export function useReduce(reduce, ...args) {
3
- const r = useRef();
4
- return (r.current = reduce(r.current, ...args));
3
+ const ref = useRef();
4
+ return (ref.current = reduce(ref.current, ...args));
5
5
  }
package/react/useState.js CHANGED
@@ -1,20 +1,15 @@
1
1
  import { useEffect, useState as useReactState } from "react";
2
- import { dispatch } from "../util/function.js";
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 forceRerender = () => setValue({});
10
- const stops = mapArray(states, _startState, forceRerender, setError);
11
- return () => stops.filter(isDefined).forEach(dispatch);
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
- function _startState(state, setValue, setError) {
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]: string;
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 { Dispatch, Handler, Stop } from "../util/function.js";
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 value(): Promise<T>;
17
+ get promise(): Promise<T>;
16
18
  /** Resolve the current deferred in the sequence. */
17
- readonly resolve: (value: T) => void;
19
+ readonly resolve: Callback<T>;
18
20
  private _nextValue;
19
21
  /** Reject the current deferred in the sequence. */
20
- readonly reject: (reason: Error | unknown) => void;
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?: Handler): Stop;
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: Dispatch<[T]>, onError?: Handler): Stop;
35
+ to(onNext: Callback<T>, onError?: ErrorCallback): StopCallback;
34
36
  }
@@ -1,25 +1,26 @@
1
- import { Deferred } from "../util/async.js";
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 = (value) => {
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 = (reason) => {
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 value() {
44
- return (this._deferred || (this._deferred = new 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.value };
49
+ return { value: await this.promise };
49
50
  }
50
51
  // Implement `Promise`
51
52
  then(onNext, onError) {
52
- return this.value.then(onNext, onError);
53
+ return this.promise.then(onNext, onError);
53
54
  }
54
55
  catch(onError) {
55
- return this.value.catch(onError);
56
+ return this.promise.catch(onError);
56
57
  }
57
58
  finally(onFinally) {
58
- return this.value.finally(onFinally);
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
+ }
@@ -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 "./RegisteringSequence.js";
5
- export * from "./LazyDeferredSequence.js";
4
+ export * from "./SwitchingSequence.js";
5
+ export * from "./SwitchingDeferredSequence.js";
6
6
  export * from "./ThroughSequence.js";