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.
Files changed (50) hide show
  1. package/db/ItemReference.d.ts +4 -3
  2. package/db/ItemState.js +5 -5
  3. package/db/QueryReference.d.ts +3 -2
  4. package/db/QueryState.d.ts +1 -1
  5. package/db/QueryState.js +5 -4
  6. package/firestore/client/FirestoreClientProvider.js +2 -1
  7. package/firestore/lite/FirestoreLiteProvider.js +2 -1
  8. package/firestore/server/FirestoreServerProvider.js +2 -1
  9. package/package.json +1 -1
  10. package/provider/CacheProvider.js +2 -2
  11. package/provider/DebugProvider.js +53 -75
  12. package/provider/MemoryProvider.d.ts +16 -17
  13. package/provider/MemoryProvider.js +54 -93
  14. package/provider/ValidationProvider.js +11 -11
  15. package/react/useReduce.js +2 -2
  16. package/react/useState.js +4 -9
  17. package/sequence/DeferredSequence.d.ts +3 -2
  18. package/sequence/DeferredSequence.js +2 -2
  19. package/sequence/LazyDeferredSequence.d.ts +2 -2
  20. package/state/ArrayState.d.ts +2 -1
  21. package/state/ArrayState.js +2 -2
  22. package/state/BooleanState.d.ts +2 -1
  23. package/state/BooleanState.js +2 -2
  24. package/state/DataState.d.ts +2 -2
  25. package/state/DataState.js +2 -2
  26. package/state/DictionaryState.d.ts +2 -1
  27. package/state/DictionaryState.js +2 -2
  28. package/state/State.d.ts +21 -11
  29. package/state/State.js +33 -20
  30. package/util/activity.d.ts +13 -17
  31. package/util/activity.js +3 -17
  32. package/util/array.d.ts +6 -6
  33. package/util/array.js +9 -10
  34. package/util/async.d.ts +14 -22
  35. package/util/async.js +16 -33
  36. package/util/constants.d.ts +4 -2
  37. package/util/constants.js +4 -2
  38. package/util/data.d.ts +0 -2
  39. package/util/function.d.ts +8 -10
  40. package/util/function.js +5 -6
  41. package/util/map.d.ts +2 -2
  42. package/util/map.js +2 -2
  43. package/util/match.d.ts +2 -0
  44. package/util/match.js +6 -0
  45. package/util/null.d.ts +2 -2
  46. package/util/random.d.ts +3 -1
  47. package/util/random.js +9 -1
  48. package/util/sequence.d.ts +6 -5
  49. package/util/sequence.js +14 -14
  50. 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
- 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
@@ -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 forceRerender = () => setValue({});
10
- const stops = mapArray(states, _startState, forceRerender, setError);
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
- 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,4 +1,5 @@
1
- import type { Dispatch, Handler, Stop } from "../util/function.js";
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<[T]>, onError?: Handler): Stop;
34
+ to(onNext: Dispatch<T>, onError?: Handler): Stop;
34
35
  }
@@ -1,4 +1,4 @@
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. */
@@ -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 = new 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/function.js";
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<[DeferredSequence<T, R>]>);
7
+ constructor(start: Start<DeferredSequence<T, R>>);
8
8
  [Symbol.asyncIterator](): AsyncGenerator<T, R, void>;
9
9
  }
@@ -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(initial?: ImmutableArray<T>);
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. */
@@ -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(initial = []) {
6
- super(initial);
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() {
@@ -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(initial?: boolean);
5
+ constructor(options?: StateOptions<boolean>);
5
6
  /** Toggle the current boolean value. */
6
7
  toggle(): void;
7
8
  }
@@ -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(initial = false) {
5
- super(initial);
4
+ constructor(options = {}) {
5
+ super("value" in options ? options : { ...options, value: false });
6
6
  }
7
7
  /** Toggle the current boolean value. */
8
8
  toggle() {
@@ -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 | null> {
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 `null`. */
27
+ /** Set the data to `undefined`. */
28
28
  unset(): void;
29
29
  }
@@ -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 `null`. */
46
+ /** Set the data to `undefined`. */
47
47
  unset() {
48
- this.set(null);
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(initial?: ImmutableDictionary<T>);
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. */
@@ -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(initial = {}) {
8
- super(initial);
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 { Dispatch, Handler, Stop } from "../util/function.js";
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 `State.NOVALUE` constant or a `Promise` value.
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
- /** Most recently dispatched value (or throw `Promise` that resolves to the next value). */
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 | null;
26
- protected _time: number | null;
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(initial?: T | typeof State.NOVALUE, next?: DeferredSequence<T>);
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<[T]>, onError?: Handler): Stop;
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;