shelving 1.98.3 → 1.98.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -15,6 +15,8 @@ export type ItemValue<T extends Data = Data> = ItemData<T> | undefined;
15
15
  export declare const getID: <T extends Data>({ id }: ItemData<T>) => string;
16
16
  /** Get the IDs of an iterable set item data. */
17
17
  export declare function getIDs<T extends Data>(entities: Iterable<ItemData<T>>): Iterable<string>;
18
+ /** Merge an ID into a set of data to make an `ItemData` */
19
+ export declare const getItemData: <T extends Data>(id: string, data: T | ItemData<T>) => ItemData<T>;
18
20
  /** An array of item data. */
19
21
  export type ItemArray<T extends Data = Data> = ImmutableArray<ItemData<T>>;
20
22
  /** A set of query constraints for item data. */
@@ -7,6 +7,8 @@ export function* getIDs(entities) {
7
7
  for (const { id } of entities)
8
8
  yield id;
9
9
  }
10
+ /** Merge an ID into a set of data to make an `ItemData` */
11
+ export const getItemData = (id, data) => (data.id === id ? data : { ...data, id });
10
12
  /** Get query that targets a single database item by its ID. */
11
13
  export const getItemQuery = (id) => ({ id, $limit: 1 });
12
14
  /** Reference to an item in a synchronous or asynchronous database. */
package/db/ItemState.d.ts CHANGED
@@ -7,9 +7,11 @@ import { State } from "../state/State.js";
7
7
  export declare class ItemState<T extends Data = Data> extends State<ItemValue<T>> {
8
8
  readonly ref: ItemReference<T> | AsyncItemReference<T>;
9
9
  readonly busy: BooleanState;
10
- /** Get the data of the item (throws `RequiredError` if item doesn't exist). */
10
+ /** Get the data of this state (throws `RequiredError` if item doesn't exist). */
11
11
  get data(): ItemData<T>;
12
- /** Does the item exist (i.e. its value isn't `null`)? */
12
+ /** Set the data of this state. */
13
+ set data(data: T | ItemData<T>);
14
+ /** Does the item exist? */
13
15
  get exists(): boolean;
14
16
  constructor(ref: ItemReference<T> | AsyncItemReference<T>);
15
17
  /** Refresh this state from the source provider. */
package/db/ItemState.js CHANGED
@@ -4,13 +4,18 @@ import { BooleanState } from "../state/BooleanState.js";
4
4
  import { State } from "../state/State.js";
5
5
  import { getRequired } from "../util/null.js";
6
6
  import { getOptionalSource } from "../util/source.js";
7
+ import { getItemData } from "./ItemReference.js";
7
8
  /** Hold the current state of a item. */
8
9
  export class ItemState extends State {
9
- /** Get the data of the item (throws `RequiredError` if item doesn't exist). */
10
+ /** Get the data of this state (throws `RequiredError` if item doesn't exist). */
10
11
  get data() {
11
12
  return getRequired(this.value);
12
13
  }
13
- /** Does the item exist (i.e. its value isn't `null`)? */
14
+ /** Set the data of this state. */
15
+ set data(data) {
16
+ this.value = getItemData(this.ref.id, data);
17
+ }
18
+ /** Does the item exist? */
14
19
  get exists() {
15
20
  return !!this.value;
16
21
  }
@@ -33,16 +38,16 @@ export class ItemState extends State {
33
38
  this.refresh();
34
39
  }
35
40
  async _refresh() {
36
- this.busy.set(true);
41
+ this.busy.value = true;
37
42
  this.reason = undefined; // Optimistically clear the error.
38
43
  try {
39
- this.set(await this.ref.value);
44
+ this.value = await this.ref.value;
40
45
  }
41
46
  catch (thrown) {
42
47
  this.reason = thrown;
43
48
  }
44
49
  finally {
45
- this.busy.set(false);
50
+ this.busy.value = false;
46
51
  }
47
52
  }
48
53
  /** Refresh this state if data in the cache is older than `maxAge` (in milliseconds). */
package/db/QueryState.js CHANGED
@@ -65,18 +65,18 @@ export class QueryState extends State {
65
65
  this.refresh();
66
66
  }
67
67
  async _refresh() {
68
- this.busy.set(true);
68
+ this.busy.value = true;
69
69
  this.reason = undefined; // Optimistically clear the error.
70
70
  try {
71
71
  const items = await this.ref.items;
72
72
  this._hasMore = items.length >= this.limit; // If the query returned {limit} or more items, we can assume there are more items waiting to be queried.
73
- this.set(items);
73
+ this.value = items;
74
74
  }
75
75
  catch (thrown) {
76
- this.next.reject(thrown);
76
+ this.reason = thrown;
77
77
  }
78
78
  finally {
79
- this.busy.set(false);
79
+ this.busy.value = false;
80
80
  }
81
81
  }
82
82
  /** Refresh this state if data in the cache is older than `maxAge` (in milliseconds). */
@@ -89,20 +89,20 @@ export class QueryState extends State {
89
89
  return this.from(this.ref);
90
90
  }
91
91
  async _loadMore() {
92
- this.busy.set(true);
92
+ this.busy.value = true;
93
93
  this.reason = undefined; // Optimistically clear the error.
94
94
  try {
95
95
  const last = this.last;
96
96
  const ref = last ? this.ref.with(getAfterQuery(this.ref.query, last)) : this.ref;
97
97
  const items = await ref.items;
98
- this.set([...this.items, ...items]);
98
+ this.value = [...this.items, ...items];
99
99
  this._hasMore = items.length >= this.limit; // If the query returned {limit} or more items, we can assume there are more items waiting to be queried.
100
100
  }
101
101
  catch (thrown) {
102
102
  this.reason = thrown;
103
103
  }
104
104
  finally {
105
- this.busy.set(false);
105
+ this.busy.value = false;
106
106
  }
107
107
  }
108
108
  /** Iterate over the items. */
@@ -1,4 +1,5 @@
1
1
  import { addDoc, collection, deleteDoc, doc, documentId, getDoc, getDocs, increment, limit, onSnapshot, orderBy, query, setDoc, updateDoc, where } from "firebase/firestore";
2
+ import { getItemData } from "../../db/ItemReference.js";
2
3
  import { SwitchingDeferredSequence } from "../../sequence/SwitchingDeferredSequence.js";
3
4
  import { getObject } from "../../util/object.js";
4
5
  import { getFilters, getLimit, getOrders } from "../../util/query.js";
@@ -36,12 +37,12 @@ function _getItems(snapshot) {
36
37
  }
37
38
  function _getItemData(snapshot) {
38
39
  const data = snapshot.data();
39
- return { ...data, id: snapshot.id };
40
+ return getItemData(snapshot.id, data);
40
41
  }
41
42
  function _getItemValue(snapshot) {
42
43
  const data = snapshot.data();
43
44
  if (data)
44
- return { ...data, id: snapshot.id };
45
+ return getItemData(snapshot.id, data);
45
46
  }
46
47
  /** Convert `Updates` object into corresponding Firestore `FieldValue` instances. */
47
48
  const _getFieldValues = (updates) => getObject(mapItems(getUpdates(updates), _getFieldValue));
@@ -1,4 +1,5 @@
1
1
  import { addDoc, collection, deleteDoc, doc, documentId, getDoc, getDocs, increment, limit, orderBy, query, setDoc, updateDoc, where } from "firebase/firestore/lite";
2
+ import { getItemData } from "../../db/ItemReference.js";
2
3
  import { UnsupportedError } from "../../error/UnsupportedError.js";
3
4
  import { getObject } from "../../util/object.js";
4
5
  import { getFilters, getLimit, getOrders } from "../../util/query.js";
@@ -33,12 +34,12 @@ function* _getConstraints(q) {
33
34
  }
34
35
  function _getItemData(snapshot) {
35
36
  const data = snapshot.data();
36
- return { ...data, id: snapshot.id };
37
+ return getItemData(snapshot.id, data);
37
38
  }
38
39
  function _getItemValue(snapshot) {
39
40
  const data = snapshot.data();
40
41
  if (data)
41
- return { ...data, id: snapshot.id };
42
+ return getItemData(snapshot.id, data);
42
43
  }
43
44
  /** Convert `Updates` object into corresponding Firestore `FieldValue` instances. */
44
45
  const _getFieldValues = (updates) => getObject(mapItems(getUpdates(updates), _getFieldValue));
@@ -1,4 +1,5 @@
1
1
  import { FieldPath, FieldValue, Firestore } from "@google-cloud/firestore";
2
+ import { getItemData } from "../../db/ItemReference.js";
2
3
  import { SwitchingDeferredSequence } from "../../sequence/SwitchingDeferredSequence.js";
3
4
  import { getObject } from "../../util/object.js";
4
5
  import { getFilters, getLimit, getOrders } from "../../util/query.js";
@@ -35,12 +36,12 @@ function _getItemArray(snapshot) {
35
36
  }
36
37
  function _getItemData(snapshot) {
37
38
  const data = snapshot.data();
38
- return { ...data, id: snapshot.id };
39
+ return getItemData(snapshot.id, data);
39
40
  }
40
41
  function _getItemValue(snapshot) {
41
42
  const data = snapshot.data();
42
43
  if (data)
43
- return { ...data, id: snapshot.id };
44
+ return getItemData(snapshot.id, data);
44
45
  }
45
46
  /** Convert `Update` instances into corresponding Firestore `FieldValue` instances. */
46
47
  const _getFieldValues = (updates) => getObject(mapItems(getUpdates(updates), _getFieldValue));
package/package.json CHANGED
@@ -11,7 +11,7 @@
11
11
  "state-management",
12
12
  "query-builder"
13
13
  ],
14
- "version": "1.98.3",
14
+ "version": "1.98.4",
15
15
  "repository": "https://github.com/dhoulb/shelving",
16
16
  "author": "Dave Houlbrooke <dave@shax.com>",
17
17
  "license": "0BSD",
@@ -42,7 +42,7 @@ export declare class MemoryTable<T extends Data = Data> {
42
42
  getCachedItemSequence(id: string): AsyncIterable<ItemValue<T>>;
43
43
  addItem(data: T): string;
44
44
  setItemData(item: ItemData<T>): boolean;
45
- setItem(id: string, item: ItemData<T> | T): boolean;
45
+ setItem(id: string, data: ItemData<T> | T): boolean;
46
46
  setItemValue(id: string, value: ItemData<T> | T | undefined): boolean;
47
47
  setItemValueSequence(id: string, sequence: AsyncIterable<ItemValue<T>>): AsyncIterable<ItemValue>;
48
48
  updateItem(id: string, updates: Updates<T>): boolean;
@@ -1,3 +1,4 @@
1
+ import { getItemData } from "../db/ItemReference.js";
1
2
  import { RequiredError } from "../error/RequiredError.js";
2
3
  import { DeferredSequence } from "../sequence/DeferredSequence.js";
3
4
  import { getArray } from "../util/array.js";
@@ -96,7 +97,7 @@ export class MemoryTable {
96
97
  let id = getRandomKey();
97
98
  while (this._data.has(id))
98
99
  id = getRandomKey(); // Regenerate ID until unique.
99
- this.setItemData({ ...data, id });
100
+ this.setItemData(getItemData(id, data));
100
101
  return id;
101
102
  }
102
103
  setItemData(item) {
@@ -109,8 +110,8 @@ export class MemoryTable {
109
110
  }
110
111
  return false;
111
112
  }
112
- setItem(id, item) {
113
- return this.setItemData(item.id === id ? item : { ...item, id });
113
+ setItem(id, data) {
114
+ return this.setItemData(getItemData(id, data));
114
115
  }
115
116
  setItemValue(id, value) {
116
117
  return value ? this.setItem(id, value) : this.deleteItem(id);
@@ -11,8 +11,8 @@ export declare function useData<T extends Nullish<AsyncItemReference | AsyncQuer
11
11
  export declare function useData<T extends ImmutableArray<Nullish<AsyncItemReference | AsyncQueryReference>>>(...refs: T): {
12
12
  [K in keyof T]: NullishReferenceState<T[K]>;
13
13
  };
14
- /** Wrap components with `<DataCache>` to allow the use of `useData()`. */
15
- export declare const DataCache: ({ children }: {
14
+ /** Wrap components with `<DataProvider>` to allow the use of `useData()`. */
15
+ export declare const DataProvider: ({ children }: {
16
16
  children: import("react").ReactNode;
17
17
  }) => import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>;
18
18
  export {};
package/react/useData.js CHANGED
@@ -17,5 +17,5 @@ function _getRefState(ref, cache) {
17
17
  const key = ref === null || ref === void 0 ? void 0 : ref.toString();
18
18
  return ref && key ? cache.get(key) || setMapItem(cache, key, ref instanceof AsyncItemReference ? new ItemState(ref) : new QueryState(ref)) : undefined;
19
19
  }
20
- /** Wrap components with `<DataCache>` to allow the use of `useData()`. */
21
- export const DataCache = Cache;
20
+ /** Wrap components with `<DataProvider>` to allow the use of `useData()`. */
21
+ export const DataProvider = Cache;
@@ -3,8 +3,10 @@ import type { Updates } from "../util/update.js";
3
3
  import { State } from "./State.js";
4
4
  /** State that stores a data object and has additional methods to help with that. */
5
5
  export declare class DataState<T extends Data> extends State<T> {
6
- /** Get the data value of this state. */
6
+ /** Get the data of this state. */
7
7
  get data(): T;
8
+ /** Set the data of this state. */
9
+ set data(data: T);
8
10
  /** Update several props in this data. */
9
11
  update(updates: Updates<T>): void;
10
12
  /** Update a single named prop in this data. */
@@ -16,6 +18,8 @@ export declare class DataState<T extends Data> extends State<T> {
16
18
  export declare class OptionalDataState<T extends Data> extends State<T | undefined> {
17
19
  /** Get current data value of this state (or throw `Promise` that resolves to the next required value). */
18
20
  get data(): T;
21
+ /** Set the data of this state. */
22
+ set data(data: T);
19
23
  /** Does the data exist or not? */
20
24
  get exists(): boolean;
21
25
  /** Update several props in this data. */
@@ -4,10 +4,14 @@ import { updateData } from "../util/update.js";
4
4
  import { State } from "./State.js";
5
5
  /** State that stores a data object and has additional methods to help with that. */
6
6
  export class DataState extends State {
7
- /** Get the data value of this state. */
7
+ /** Get the data of this state. */
8
8
  get data() {
9
9
  return this.value;
10
10
  }
11
+ /** Set the data of this state. */
12
+ set data(data) {
13
+ this.value = data;
14
+ }
11
15
  /** Update several props in this data. */
12
16
  update(updates) {
13
17
  this.value = updateData(this.data, updates);
@@ -27,6 +31,10 @@ export class OptionalDataState extends State {
27
31
  get data() {
28
32
  return getRequired(this.value);
29
33
  }
34
+ /** Set the data of this state. */
35
+ set data(data) {
36
+ this.value = data;
37
+ }
30
38
  /** Does the data exist or not? */
31
39
  get exists() {
32
40
  return !!this.value;