shelving 1.92.1 → 1.93.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/Database.d.ts +3 -3
- package/db/ItemReference.js +3 -3
- package/db/ItemState.js +2 -2
- package/db/QueryReference.js +3 -3
- package/db/QueryState.js +2 -2
- package/package.json +1 -1
- package/state/DataState.js +2 -2
- package/util/data.d.ts +4 -3
- package/util/data.js +4 -7
- package/util/null.d.ts +2 -0
- package/util/null.js +7 -0
- package/util/object.d.ts +4 -0
- package/util/object.js +4 -0
- package/util/query.d.ts +2 -2
- package/util/query.js +17 -17
- package/util/update.d.ts +3 -3
- package/util/update.js +12 -9
package/db/Database.d.ts
CHANGED
|
@@ -13,7 +13,7 @@ declare abstract class AbstractDatabase<T extends Datas> {
|
|
|
13
13
|
/** Create a query on a collection in this database. */
|
|
14
14
|
abstract collection<K extends DataKey<T>>(collection: K): CollectionReference<T[K]> | AsyncCollectionReference<T[K]>;
|
|
15
15
|
/** Create a query on a collection in this database. */
|
|
16
|
-
abstract query<K extends DataKey<T>>(collection: K, query?: ItemQuery<T>): QueryReference<T[K]> | AsyncQueryReference<T[K]>;
|
|
16
|
+
abstract query<K extends DataKey<T>>(collection: K, query?: ItemQuery<T[K]>): QueryReference<T[K]> | AsyncQueryReference<T[K]>;
|
|
17
17
|
/** Reference an item in a collection in this database. */
|
|
18
18
|
abstract item<K extends DataKey<T>>(collection: K, id: string): ItemReference<T[K]> | AsyncItemReference<T[K]>;
|
|
19
19
|
/** Run a set of changes in this database. */
|
|
@@ -42,7 +42,7 @@ export declare class Database<T extends Datas = Datas> extends AbstractDatabase<
|
|
|
42
42
|
readonly provider: Provider;
|
|
43
43
|
constructor(provider: Provider);
|
|
44
44
|
collection<K extends DataKey<T>>(collection: K): CollectionReference<T[K]>;
|
|
45
|
-
query<K extends DataKey<T>>(collection: K, query?: ItemQuery<T>): QueryReference<T[K]>;
|
|
45
|
+
query<K extends DataKey<T>>(collection: K, query?: ItemQuery<T[K]>): QueryReference<T[K]>;
|
|
46
46
|
item<K extends DataKey<T>>(collection: K, id: string): ItemReference<T[K]>;
|
|
47
47
|
change(...changes: Nullish<WriteChange<Data>>[]): ItemChanges;
|
|
48
48
|
get<K extends DataKey<T>>(collection: K, id: string): ItemValue<T[K]>;
|
|
@@ -56,7 +56,7 @@ export declare class AsyncDatabase<T extends Datas = Datas> extends AbstractData
|
|
|
56
56
|
readonly provider: AsyncProvider;
|
|
57
57
|
constructor(provider: AsyncProvider);
|
|
58
58
|
collection<K extends DataKey<T>>(collection: K): AsyncCollectionReference<T[K]>;
|
|
59
|
-
query<K extends DataKey<T>>(collection: K, query?: ItemQuery<T>): AsyncQueryReference<T[K]>;
|
|
59
|
+
query<K extends DataKey<T>>(collection: K, query?: ItemQuery<T[K]>): AsyncQueryReference<T[K]>;
|
|
60
60
|
item<K extends DataKey<T>>(collection: K, id: string): AsyncItemReference<T[K]>;
|
|
61
61
|
change(...changes: Nullish<WriteChange<Data>>[]): Promise<ItemChanges>;
|
|
62
62
|
get<K extends DataKey<T>>(collection: K, id: string): Promise<ItemValue<T[K]>>;
|
package/db/ItemReference.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getRequired } from "../util/null.js";
|
|
2
2
|
import { runSequence } from "../util/sequence.js";
|
|
3
3
|
/** Get the ID from item data. */
|
|
4
4
|
export const getID = ({ id }) => id;
|
|
@@ -53,7 +53,7 @@ export class ItemReference extends AbstractItemReference {
|
|
|
53
53
|
return this.provider.getItem(this.collection, this.id);
|
|
54
54
|
}
|
|
55
55
|
get data() {
|
|
56
|
-
return
|
|
56
|
+
return getRequired(this.value);
|
|
57
57
|
}
|
|
58
58
|
set(data) {
|
|
59
59
|
return this.provider.setItem(this.collection, this.id, data);
|
|
@@ -78,7 +78,7 @@ export class AsyncItemReference extends AbstractItemReference {
|
|
|
78
78
|
return this.provider.getItem(this.collection, this.id);
|
|
79
79
|
}
|
|
80
80
|
get data() {
|
|
81
|
-
return this.value.then(
|
|
81
|
+
return this.value.then(getRequired);
|
|
82
82
|
}
|
|
83
83
|
set(data) {
|
|
84
84
|
return this.provider.setItem(this.collection, this.id, data);
|
package/db/ItemState.js
CHANGED
|
@@ -2,13 +2,13 @@ import { CacheProvider } from "../provider/CacheProvider.js";
|
|
|
2
2
|
import { LazyDeferredSequence } from "../sequence/LazyDeferredSequence.js";
|
|
3
3
|
import { BooleanState } from "../state/BooleanState.js";
|
|
4
4
|
import { State } from "../state/State.js";
|
|
5
|
-
import {
|
|
5
|
+
import { getRequired } from "../util/null.js";
|
|
6
6
|
import { getOptionalSource } from "../util/source.js";
|
|
7
7
|
/** Hold the current state of a item. */
|
|
8
8
|
export class ItemState extends State {
|
|
9
9
|
/** Get the data of the item (throws `RequiredError` if item doesn't exist). */
|
|
10
10
|
get data() {
|
|
11
|
-
return
|
|
11
|
+
return getRequired(this.value);
|
|
12
12
|
}
|
|
13
13
|
/** Does the item exist (i.e. its value isn't `null`)? */
|
|
14
14
|
get exists() {
|
package/db/QueryReference.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { countArray, getOptionalFirstItem, getOptionalLastItem, isArrayLength } from "../util/array.js";
|
|
2
|
-
import {
|
|
2
|
+
import { getRequired } from "../util/null.js";
|
|
3
3
|
import { cloneObjectWith } from "../util/object.js";
|
|
4
4
|
import { runSequence } from "../util/sequence.js";
|
|
5
5
|
/** Reference to a set of items in a sync or async provider. */
|
|
@@ -47,7 +47,7 @@ export class QueryReference extends AbstractQueryReference {
|
|
|
47
47
|
return getOptionalLastItem(this.items);
|
|
48
48
|
}
|
|
49
49
|
get data() {
|
|
50
|
-
return
|
|
50
|
+
return getRequired(this.first);
|
|
51
51
|
}
|
|
52
52
|
set(data) {
|
|
53
53
|
return this.provider.setQuery(this.collection, this.query, data);
|
|
@@ -81,7 +81,7 @@ export class AsyncQueryReference extends AbstractQueryReference {
|
|
|
81
81
|
return this.items.then(getOptionalLastItem);
|
|
82
82
|
}
|
|
83
83
|
get data() {
|
|
84
|
-
return this.first.then(
|
|
84
|
+
return this.first.then(getRequired);
|
|
85
85
|
}
|
|
86
86
|
set(data) {
|
|
87
87
|
return this.provider.setQuery(this.collection, this.query, data);
|
package/db/QueryState.js
CHANGED
|
@@ -3,7 +3,7 @@ import { LazyDeferredSequence } from "../sequence/LazyDeferredSequence.js";
|
|
|
3
3
|
import { BooleanState } from "../state/BooleanState.js";
|
|
4
4
|
import { State } from "../state/State.js";
|
|
5
5
|
import { getOptionalFirstItem, getOptionalLastItem } from "../util/array.js";
|
|
6
|
-
import {
|
|
6
|
+
import { getRequired } from "../util/null.js";
|
|
7
7
|
import { getAfterQuery, getLimit } from "../util/query.js";
|
|
8
8
|
import { getOptionalSource } from "../util/source.js";
|
|
9
9
|
/** Hold the current state of a query. */
|
|
@@ -26,7 +26,7 @@ export class QueryState extends State {
|
|
|
26
26
|
}
|
|
27
27
|
/** Get the first document matched by this query. */
|
|
28
28
|
get data() {
|
|
29
|
-
return
|
|
29
|
+
return getRequired(this.first);
|
|
30
30
|
}
|
|
31
31
|
/** Does the document have at least one result. */
|
|
32
32
|
get exists() {
|
package/package.json
CHANGED
package/state/DataState.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getRequired } from "../util/null.js";
|
|
2
2
|
import { withProp } from "../util/object.js";
|
|
3
3
|
import { updateData } from "../util/update.js";
|
|
4
4
|
import { State } from "./State.js";
|
|
@@ -25,7 +25,7 @@ export class DataState extends State {
|
|
|
25
25
|
export class OptionalDataState extends State {
|
|
26
26
|
/** Get current data value of this state (or throw `Promise` that resolves to the next required value). */
|
|
27
27
|
get data() {
|
|
28
|
-
return
|
|
28
|
+
return getRequired(this.value);
|
|
29
29
|
}
|
|
30
30
|
/** Does the data exist or not? */
|
|
31
31
|
get exists() {
|
package/util/data.d.ts
CHANGED
|
@@ -50,9 +50,10 @@ export declare const isData: <T extends Data>(value: unknown) => value is T;
|
|
|
50
50
|
/** Assert that an unknown value is a data object. */
|
|
51
51
|
export declare function assertData<T extends Data>(value: T | unknown): asserts value is T;
|
|
52
52
|
/** Is an unknown value the key for an own prop of a data object. */
|
|
53
|
-
export declare const isDataProp: <T extends Data>(
|
|
54
|
-
/**
|
|
55
|
-
export declare function getData<T extends Data>(
|
|
53
|
+
export declare const isDataProp: <T extends Data>(data: T, key: unknown) => key is DataKey<T>;
|
|
54
|
+
/** Convert a data object or set of `DataProp` props for that object back into the full object. */
|
|
55
|
+
export declare function getData<T extends Data>(input: T): T;
|
|
56
|
+
export declare function getData<T extends Data>(input: T | Iterable<DataProp<T>>): Partial<T>;
|
|
56
57
|
/** Get the props of a data object as a set of entries. */
|
|
57
58
|
export declare function getDataProps<T extends Data>(data: T): ImmutableArray<DataProp<T>>;
|
|
58
59
|
export declare function getDataProps<T extends Data>(data: T | Partial<T>): ImmutableArray<DataProp<T>>;
|
package/util/data.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { AssertionError } from "../error/AssertionError.js";
|
|
2
|
-
import {
|
|
2
|
+
import { isIterable } from "./iterate.js";
|
|
3
3
|
import { isObject, isPlainObject } from "./object.js";
|
|
4
4
|
/** Is an unknown value a data object? */
|
|
5
5
|
export const isData = (value) => isPlainObject(value);
|
|
@@ -9,12 +9,9 @@ export function assertData(value) {
|
|
|
9
9
|
throw new AssertionError("Must be data", value);
|
|
10
10
|
}
|
|
11
11
|
/** Is an unknown value the key for an own prop of a data object. */
|
|
12
|
-
export const isDataProp = (
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
if (!result)
|
|
16
|
-
throw new RequiredError("Data is required");
|
|
17
|
-
return result;
|
|
12
|
+
export const isDataProp = (data, key) => typeof key === "string" && Object.prototype.hasOwnProperty.call(data, key);
|
|
13
|
+
export function getData(input) {
|
|
14
|
+
return isIterable(input) ? Object.fromEntries(input) : input;
|
|
18
15
|
}
|
|
19
16
|
export function getDataProps(data) {
|
|
20
17
|
return Object.entries(data);
|
package/util/null.d.ts
CHANGED
|
@@ -18,3 +18,5 @@ export declare const notNullish: <T>(value: Nullish<T>) => value is T;
|
|
|
18
18
|
export declare function assertNotNullish<T>(value: Nullish<T>): asserts value is T;
|
|
19
19
|
/** Get the not-nullish version of value. */
|
|
20
20
|
export declare function getNotNullish<T>(value: Nullish<T>): T;
|
|
21
|
+
/** Get a required value. */
|
|
22
|
+
export declare function getRequired<T>(value: Nullish<T>): T;
|
package/util/null.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { AssertionError } from "../error/AssertionError.js";
|
|
2
|
+
import { RequiredError } from "../error/RequiredError.js";
|
|
2
3
|
/** Function that always returns null. */
|
|
3
4
|
export const getNull = () => null;
|
|
4
5
|
/** Is a value null? */
|
|
@@ -29,3 +30,9 @@ export function getNotNullish(value) {
|
|
|
29
30
|
assertNotNullish(value);
|
|
30
31
|
return value;
|
|
31
32
|
}
|
|
33
|
+
/** Get a required value. */
|
|
34
|
+
export function getRequired(value) {
|
|
35
|
+
if (isNullish(value))
|
|
36
|
+
throw new RequiredError("Value is required");
|
|
37
|
+
return value;
|
|
38
|
+
}
|
package/util/object.d.ts
CHANGED
|
@@ -77,6 +77,10 @@ export declare function getKeys<T>(obj: T | Partial<T>): ImmutableArray<Key<T>>;
|
|
|
77
77
|
export declare function getKeys<T>(obj: T | Partial<T> | Iterable<Key<T>>): Iterable<Key<T>>;
|
|
78
78
|
/** Extract the value of a named prop from an object. */
|
|
79
79
|
export declare function getProp<T, K extends Key<T>>(obj: T, key: K): T[K];
|
|
80
|
+
/** Create an object from a single prop. */
|
|
81
|
+
export declare function fromProp<K extends PropertyKey, V>(key: K, value: V): {
|
|
82
|
+
readonly [KK in K]: V;
|
|
83
|
+
};
|
|
80
84
|
/** Set a prop on an object (immutably) and return a new object including that prop. */
|
|
81
85
|
export declare function withProp<T extends ImmutableObject, K extends Key<T>>(input: T, key: K, value: T[K]): T;
|
|
82
86
|
/** Set several props on an object (immutably) and return a new object including those props. */
|
package/util/object.js
CHANGED
|
@@ -36,6 +36,10 @@ export function getKeys(obj) {
|
|
|
36
36
|
export function getProp(obj, key) {
|
|
37
37
|
return obj[key];
|
|
38
38
|
}
|
|
39
|
+
/** Create an object from a single prop. */
|
|
40
|
+
export function fromProp(key, value) {
|
|
41
|
+
return { [key]: value };
|
|
42
|
+
}
|
|
39
43
|
/** Set a prop on an object (immutably) and return a new object including that prop. */
|
|
40
44
|
export function withProp(input, key, value) {
|
|
41
45
|
return input[key] === value ? input : { __proto__: getPrototype(input), ...input, [key]: value };
|
package/util/query.d.ts
CHANGED
|
@@ -2,13 +2,13 @@ import type { ImmutableArray } from "./array.js";
|
|
|
2
2
|
import type { Data, LeafData, LeafKey } from "./data.js";
|
|
3
3
|
/** Query that can be applied to a list of data objects. */
|
|
4
4
|
export type Query<T extends Data> = {
|
|
5
|
-
readonly [K in LeafKey<T> as
|
|
5
|
+
readonly [K in LeafKey<T> as `${K}` | `!${K}`]?: LeafData<T>[K] | ImmutableArray<LeafData<T>[K]> | undefined;
|
|
6
6
|
} & {
|
|
7
7
|
readonly [K in LeafKey<T> as `${K}<` | `${K}<=` | `${K}>` | `${K}>=`]?: LeafData<T>[K] | undefined;
|
|
8
8
|
} & {
|
|
9
9
|
readonly [K in LeafKey<T> as `${K}[]`]?: LeafData<T>[K] extends ImmutableArray<infer X> ? X | undefined : never;
|
|
10
10
|
} & {
|
|
11
|
-
readonly $order?:
|
|
11
|
+
readonly $order?: `${LeafKey<T>}` | `!${LeafKey<T>}` | undefined | ImmutableArray<`${LeafKey<T>}` | `!${LeafKey<T>}` | undefined>;
|
|
12
12
|
readonly $limit?: number | undefined;
|
|
13
13
|
};
|
|
14
14
|
/** A single filter that can be applied to a list of data objects. */
|
package/util/query.js
CHANGED
|
@@ -22,26 +22,26 @@ export function getFilters(query) {
|
|
|
22
22
|
return getProps(query).map(_getFilters).filter(isDefined);
|
|
23
23
|
}
|
|
24
24
|
function _getFilters([key, value]) {
|
|
25
|
-
if (key
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
25
|
+
if (key !== "$order" && key !== "$limit" && value !== undefined) {
|
|
26
|
+
if (key.startsWith("!"))
|
|
27
|
+
return isArray(value) ? { key: key.slice(1), operator: "out", value } : { key: key.slice(1), operator: "not", value };
|
|
28
|
+
else if (key.endsWith("[]"))
|
|
29
|
+
return { key: key.slice(0, -2), operator: "contains", value };
|
|
30
|
+
else if (key.endsWith(">"))
|
|
31
|
+
return { key: key.slice(0, -1), operator: "gt", value };
|
|
32
|
+
else if (key.endsWith(">="))
|
|
33
|
+
return { key: key.slice(0, -2), operator: "gte", value };
|
|
34
|
+
else if (key.endsWith("<"))
|
|
35
|
+
return { key: key.slice(0, -1), operator: "lt", value };
|
|
36
|
+
else if (key.endsWith("<="))
|
|
37
|
+
return { key: key.slice(0, -2), operator: "lte", value };
|
|
38
|
+
else
|
|
39
|
+
return isArray(value) ? { key, operator: "in", value } : { key: key, operator: "is", value };
|
|
40
|
+
}
|
|
41
41
|
}
|
|
42
42
|
/** Get the `Order` objects for a query. */
|
|
43
43
|
export function getOrders({ $order }) {
|
|
44
|
-
return
|
|
44
|
+
return (isArray($order) ? $order : [$order]).filter(isDefined).map(_getOrder);
|
|
45
45
|
}
|
|
46
46
|
function _getOrder(key) {
|
|
47
47
|
if (key.startsWith("!"))
|
package/util/update.d.ts
CHANGED
|
@@ -2,11 +2,11 @@ import type { ImmutableArray } from "./array.js";
|
|
|
2
2
|
import type { BranchData, BranchKey, Data, LeafData, LeafKey } from "./data.js";
|
|
3
3
|
/** Set of named updates for a data object. */
|
|
4
4
|
export type Updates<T extends Data = Data> = {
|
|
5
|
-
readonly [K in BranchKey<T> as `${K}`]?: BranchData<T>[K];
|
|
5
|
+
readonly [K in BranchKey<T> as `${K}`]?: BranchData<T>[K] | undefined;
|
|
6
6
|
} & {
|
|
7
|
-
readonly [K in LeafKey<T> as `=${K}`]?: LeafData<T>[K];
|
|
7
|
+
readonly [K in LeafKey<T> as `=${K}`]?: LeafData<T>[K] | undefined;
|
|
8
8
|
} & {
|
|
9
|
-
readonly [K in LeafKey<T> as `+=${K}` | `-=${K}`]?: LeafData<T>[K] extends number ? LeafData<T>[K] : never;
|
|
9
|
+
readonly [K in LeafKey<T> as `+=${K}` | `-=${K}`]?: LeafData<T>[K] extends number ? LeafData<T>[K] | undefined : never;
|
|
10
10
|
};
|
|
11
11
|
/** A single update to a keyed property in an object. */
|
|
12
12
|
export type Update = {
|
package/util/update.js
CHANGED
|
@@ -2,19 +2,22 @@ import { AssertionError } from "../error/AssertionError.js";
|
|
|
2
2
|
import { reduceItems } from "./iterate.js";
|
|
3
3
|
import { getNumber } from "./number.js";
|
|
4
4
|
import { getProps, isObject } from "./object.js";
|
|
5
|
+
import { isDefined } from "./undefined.js";
|
|
5
6
|
/** Yield the prop updates in an `Updates` object as a set of `Update` objects. */
|
|
6
7
|
export function getUpdates(data) {
|
|
7
|
-
return getProps(data).map(_getUpdate);
|
|
8
|
+
return getProps(data).map(_getUpdate).filter(isDefined);
|
|
8
9
|
}
|
|
9
10
|
function _getUpdate([key, value]) {
|
|
10
|
-
if (
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
11
|
+
if (value !== undefined) {
|
|
12
|
+
if (key.startsWith("+="))
|
|
13
|
+
return { action: "sum", key: key.slice(2), value: getNumber(value) };
|
|
14
|
+
else if (key.startsWith("-="))
|
|
15
|
+
return { action: "sum", key: key.slice(2), value: 0 - getNumber(value) };
|
|
16
|
+
else if (key.startsWith("="))
|
|
17
|
+
return { action: "set", key: key.slice(1), value };
|
|
18
|
+
else
|
|
19
|
+
return { action: "set", key, value };
|
|
20
|
+
}
|
|
18
21
|
}
|
|
19
22
|
/** Update a data object with a set of updates. */
|
|
20
23
|
export function updateData(data, updates) {
|