shelving 1.84.2 → 1.85.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/package.json +9 -9
- package/react/useItem.js +2 -2
- package/react/useQuery.js +2 -2
- package/schema/AllowSchema.d.ts +12 -10
- package/schema/AllowSchema.js +4 -3
- package/schema/ArraySchema.d.ts +9 -7
- package/schema/BooleanSchema.d.ts +5 -3
- package/schema/DataSchema.d.ts +6 -4
- package/schema/DateSchema.d.ts +7 -5
- package/schema/DictionarySchema.d.ts +8 -6
- package/schema/LinkSchema.d.ts +6 -4
- package/schema/NumberSchema.d.ts +8 -6
- package/schema/Schema.d.ts +14 -12
- package/schema/Schema.js +2 -1
- package/schema/ThroughSchema.d.ts +6 -4
- package/schema/TimeSchema.d.ts +8 -6
- package/sequence/DeferredSequence.d.ts +4 -2
- package/sequence/DeferredSequence.js +7 -0
- package/state/State.d.ts +9 -4
- package/state/State.js +26 -3
- package/update/DataUpdate.d.ts +4 -2
- package/util/merge.d.ts +3 -3
- package/util/merge.js +2 -17
- package/util/sequence.d.ts +5 -9
- package/util/transform.d.ts +14 -2
- package/util/transform.js +7 -1
package/package.json
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"state-management",
|
|
12
12
|
"query-builder"
|
|
13
13
|
],
|
|
14
|
-
"version": "1.
|
|
14
|
+
"version": "1.85.0",
|
|
15
15
|
"repository": "https://github.com/dhoulb/shelving",
|
|
16
16
|
"author": "Dave Houlbrooke <dave@shax.com>",
|
|
17
17
|
"license": "0BSD",
|
|
@@ -65,25 +65,25 @@
|
|
|
65
65
|
},
|
|
66
66
|
"devDependencies": {
|
|
67
67
|
"@google-cloud/firestore": "^5.0.2",
|
|
68
|
-
"@types/jest": "^28.1.
|
|
69
|
-
"@types/react": "^18.0.
|
|
68
|
+
"@types/jest": "^28.1.8",
|
|
69
|
+
"@types/react": "^18.0.21",
|
|
70
70
|
"@types/react-dom": "^18.0.4",
|
|
71
|
-
"@typescript-eslint/eslint-plugin": "^5.
|
|
72
|
-
"@typescript-eslint/parser": "^5.
|
|
71
|
+
"@typescript-eslint/eslint-plugin": "^5.39.0",
|
|
72
|
+
"@typescript-eslint/parser": "^5.39.0",
|
|
73
73
|
"dpdm": "^3.9.0",
|
|
74
|
-
"esbuild": "^0.15.
|
|
74
|
+
"esbuild": "^0.15.10",
|
|
75
75
|
"esbuild-jest": "^0.5.0",
|
|
76
|
-
"eslint": "^8.
|
|
76
|
+
"eslint": "^8.25.0",
|
|
77
77
|
"eslint-config-prettier": "^8.5.0",
|
|
78
78
|
"eslint-plugin-import": "^2.26.0",
|
|
79
79
|
"eslint-plugin-prettier": "^4.0.0",
|
|
80
|
-
"firebase": "^9.
|
|
80
|
+
"firebase": "^9.11.0",
|
|
81
81
|
"jest": "^28.1.0",
|
|
82
82
|
"jest-ts-webcompat-resolver": "^1.0.0",
|
|
83
83
|
"prettier": "^2.6.2",
|
|
84
84
|
"react": "^18.1.0",
|
|
85
85
|
"react-dom": "^18.1.0",
|
|
86
|
-
"typescript": "^4.
|
|
86
|
+
"typescript": "^4.8.4"
|
|
87
87
|
},
|
|
88
88
|
"peerDependencies": {
|
|
89
89
|
"@google-cloud/firestore": ">=4.0.0",
|
package/react/useItem.js
CHANGED
|
@@ -15,7 +15,7 @@ export class ItemState extends State {
|
|
|
15
15
|
const table = (_a = getOptionalSource(CacheProvider, db.provider)) === null || _a === void 0 ? void 0 : _a.memory.getTable(collection);
|
|
16
16
|
const time = table ? table.getItemTime(id) : null;
|
|
17
17
|
const isCached = typeof time === "number";
|
|
18
|
-
super(table && isCached ? table.getItem(id) : State.NOVALUE, table ? new LazyDeferredSequence(() => this.
|
|
18
|
+
super(table && isCached ? table.getItem(id) : State.NOVALUE, table ? new LazyDeferredSequence(() => this.from(table.getCachedItemSequence(id))) : undefined);
|
|
19
19
|
this.busy = new BooleanState();
|
|
20
20
|
/** Refresh this state from the source provider. */
|
|
21
21
|
this.refresh = () => {
|
|
@@ -55,7 +55,7 @@ export class ItemState extends State {
|
|
|
55
55
|
}
|
|
56
56
|
/** Subscribe this state to the source provider. */
|
|
57
57
|
connectSource() {
|
|
58
|
-
return this.
|
|
58
|
+
return this.from(this.ref);
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
61
|
export function useItem(ref) {
|
package/react/useQuery.js
CHANGED
|
@@ -15,7 +15,7 @@ export class QueryState extends State {
|
|
|
15
15
|
const table = (_a = getOptionalSource(CacheProvider, db.provider)) === null || _a === void 0 ? void 0 : _a.memory.getTable(collection);
|
|
16
16
|
const time = table ? table.getQueryTime(ref) : null;
|
|
17
17
|
const isCached = typeof time === "number";
|
|
18
|
-
super(table && isCached ? table.getQuery(ref) : State.NOVALUE, table ? new LazyDeferredSequence(() => this.
|
|
18
|
+
super(table && isCached ? table.getQuery(ref) : State.NOVALUE, table ? new LazyDeferredSequence(() => this.from(table.getCachedQuerySequence(ref))) : undefined);
|
|
19
19
|
this.busy = new BooleanState();
|
|
20
20
|
this._hasMore = false;
|
|
21
21
|
/** Refresh this state from the source provider. */
|
|
@@ -87,7 +87,7 @@ export class QueryState extends State {
|
|
|
87
87
|
}
|
|
88
88
|
/** Subscribe this state to the source provider. */
|
|
89
89
|
connectSource() {
|
|
90
|
-
return this.
|
|
90
|
+
return this.from(this.ref);
|
|
91
91
|
}
|
|
92
92
|
async _loadMore() {
|
|
93
93
|
this.busy.set(true);
|
package/schema/AllowSchema.d.ts
CHANGED
|
@@ -1,24 +1,26 @@
|
|
|
1
1
|
import type { Entry } from "../util/entry.js";
|
|
2
2
|
import { ImmutableRequiredMap, PossibleMap, PossibleStringMap } from "../util/map.js";
|
|
3
3
|
import { Schema, SchemaOptions } from "./Schema.js";
|
|
4
|
+
/** Allowed options for `AllowSchama` */
|
|
5
|
+
export declare type AllowSchemaOptions<K, T> = Omit<SchemaOptions, "value"> & {
|
|
6
|
+
allow: PossibleMap<K, T>;
|
|
7
|
+
};
|
|
4
8
|
/** Define a valid value from an allowed set of values. */
|
|
5
9
|
export declare class AllowSchema<K, T> extends Schema<K> implements Iterable<Entry<K, T>> {
|
|
6
|
-
readonly value: K
|
|
10
|
+
readonly value: K;
|
|
7
11
|
readonly allow: ImmutableRequiredMap<K, T>;
|
|
8
|
-
constructor({ allow,
|
|
9
|
-
allow: PossibleMap<K, T>;
|
|
10
|
-
value?: K | null;
|
|
11
|
-
});
|
|
12
|
+
constructor({ allow, ...options }: AllowSchemaOptions<K, T>);
|
|
12
13
|
validate(value?: unknown): K;
|
|
13
14
|
/** Iterate over the the allowed options in `[key, value]` format. */
|
|
14
15
|
[Symbol.iterator](): Iterator<Entry<K, T>>;
|
|
15
16
|
}
|
|
16
|
-
/**
|
|
17
|
+
/** Allowed options for `AllowStringSchama` */
|
|
18
|
+
export declare type AllowStringSchemaOptions<K extends string, T> = Omit<SchemaOptions, "value"> & {
|
|
19
|
+
allow: PossibleStringMap<K, T>;
|
|
20
|
+
};
|
|
21
|
+
/** Define a valid string value from an allowed set of string values. */
|
|
17
22
|
export declare class AllowStringSchema<K extends string, T> extends AllowSchema<K, T> {
|
|
18
|
-
constructor({ allow, ...options }:
|
|
19
|
-
allow: PossibleStringMap<K, T>;
|
|
20
|
-
value?: K | null;
|
|
21
|
-
});
|
|
23
|
+
constructor({ allow, ...options }: AllowStringSchemaOptions<K, T>);
|
|
22
24
|
validator(value?: unknown): K;
|
|
23
25
|
}
|
|
24
26
|
/** Valid value from an allowed set of values. */
|
package/schema/AllowSchema.js
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { getString } from "../util/string.js";
|
|
2
2
|
import { getRequiredMap, isMapKey } from "../util/map.js";
|
|
3
3
|
import { InvalidFeedback } from "../feedback/InvalidFeedback.js";
|
|
4
|
+
import { getFirstItem } from "../util/array.js";
|
|
4
5
|
import { Schema } from "./Schema.js";
|
|
5
6
|
/** Define a valid value from an allowed set of values. */
|
|
6
7
|
export class AllowSchema extends Schema {
|
|
7
|
-
constructor({ allow,
|
|
8
|
+
constructor({ allow, ...options }) {
|
|
8
9
|
super(options);
|
|
9
10
|
this.allow = getRequiredMap(allow);
|
|
10
|
-
this.value =
|
|
11
|
+
this.value = getFirstItem(this.allow.keys());
|
|
11
12
|
}
|
|
12
13
|
validate(value = this.value) {
|
|
13
14
|
if (isMapKey(this.allow, value))
|
|
@@ -19,7 +20,7 @@ export class AllowSchema extends Schema {
|
|
|
19
20
|
return this.allow[Symbol.iterator]();
|
|
20
21
|
}
|
|
21
22
|
}
|
|
22
|
-
/** Define a valid string value from an allowed set of values. */
|
|
23
|
+
/** Define a valid string value from an allowed set of string values. */
|
|
23
24
|
export class AllowStringSchema extends AllowSchema {
|
|
24
25
|
constructor({ allow, ...options }) {
|
|
25
26
|
super({ allow: getRequiredMap(allow), ...options });
|
package/schema/ArraySchema.d.ts
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
import { ImmutableArray } from "../util/array.js";
|
|
2
2
|
import { Validator } from "../util/validate.js";
|
|
3
3
|
import { Schema, SchemaOptions } from "./Schema.js";
|
|
4
|
+
/** Allowed options for `ArraySchema` */
|
|
5
|
+
export declare type ArraySchemaOptions<T> = SchemaOptions & {
|
|
6
|
+
readonly value?: ImmutableArray;
|
|
7
|
+
readonly items: Validator<T>;
|
|
8
|
+
readonly min?: number;
|
|
9
|
+
readonly max?: number | null;
|
|
10
|
+
readonly unique?: boolean;
|
|
11
|
+
};
|
|
4
12
|
/**
|
|
5
13
|
* Define a valid array.
|
|
6
14
|
*
|
|
@@ -34,13 +42,7 @@ export declare class ArraySchema<T> extends Schema<ImmutableArray<T>> {
|
|
|
34
42
|
readonly unique: boolean;
|
|
35
43
|
readonly min: number;
|
|
36
44
|
readonly max: number | null;
|
|
37
|
-
constructor({ value, items, unique, min, max, ...options }:
|
|
38
|
-
readonly value?: ImmutableArray;
|
|
39
|
-
readonly items: Validator<T>;
|
|
40
|
-
readonly min?: number;
|
|
41
|
-
readonly max?: number | null;
|
|
42
|
-
readonly unique?: boolean;
|
|
43
|
-
});
|
|
45
|
+
constructor({ value, items, unique, min, max, ...options }: ArraySchemaOptions<T>);
|
|
44
46
|
validate(unsafeValue?: unknown): ImmutableArray<T>;
|
|
45
47
|
}
|
|
46
48
|
/** Valid array with specifed items. */
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { Schema, SchemaOptions } from "./Schema.js";
|
|
2
|
+
/** Allowed options for `BooleanSchema` */
|
|
3
|
+
export declare type BooleanSchemaOptions = SchemaOptions & {
|
|
4
|
+
readonly value?: boolean;
|
|
5
|
+
};
|
|
2
6
|
/** Define a valid boolean. */
|
|
3
7
|
export declare class BooleanSchema extends Schema<boolean> {
|
|
4
8
|
readonly value: boolean;
|
|
5
|
-
constructor({ value, ...options }:
|
|
6
|
-
readonly value?: boolean;
|
|
7
|
-
});
|
|
9
|
+
constructor({ value, ...options }: BooleanSchemaOptions);
|
|
8
10
|
validate(unsafeValue?: unknown): boolean;
|
|
9
11
|
}
|
|
10
12
|
/** Valid boolean. */
|
package/schema/DataSchema.d.ts
CHANGED
|
@@ -2,14 +2,16 @@ import type { Data, Datas } from "../util/data.js";
|
|
|
2
2
|
import { Validators } from "../util/validate.js";
|
|
3
3
|
import { OptionalSchema } from "./OptionalSchema.js";
|
|
4
4
|
import { Schema, SchemaOptions } from "./Schema.js";
|
|
5
|
+
/** Allowed options for `DataSchema` */
|
|
6
|
+
export declare type DataSchemaOptions<T extends Data> = SchemaOptions & {
|
|
7
|
+
readonly props: Validators<T>;
|
|
8
|
+
readonly value?: Partial<T>;
|
|
9
|
+
};
|
|
5
10
|
/** Validate a data object. */
|
|
6
11
|
export declare class DataSchema<T extends Data> extends Schema<T> {
|
|
7
12
|
readonly value: Partial<T>;
|
|
8
13
|
readonly props: Validators<T>;
|
|
9
|
-
constructor({ value, props, ...options }:
|
|
10
|
-
readonly props: Validators<T>;
|
|
11
|
-
readonly value?: Partial<T>;
|
|
12
|
-
});
|
|
14
|
+
constructor({ value, props, ...options }: DataSchemaOptions<T>);
|
|
13
15
|
validate(unsafeValue?: unknown): T;
|
|
14
16
|
}
|
|
15
17
|
/** Set of named data schemas. */
|
package/schema/DateSchema.d.ts
CHANGED
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
import { PossibleDate } from "../util/date.js";
|
|
2
2
|
import { Schema, SchemaOptions } from "./Schema.js";
|
|
3
|
+
/** Allowed options for `DateSchema` */
|
|
4
|
+
export declare type DateSchemaOptions = SchemaOptions & {
|
|
5
|
+
readonly value?: PossibleDate;
|
|
6
|
+
readonly min?: PossibleDate | null;
|
|
7
|
+
readonly max?: PossibleDate | null;
|
|
8
|
+
};
|
|
3
9
|
/** Define a valid date in YMD format, e.g. `2005-09-12` */
|
|
4
10
|
export declare class DateSchema extends Schema<string> {
|
|
5
11
|
readonly value: PossibleDate;
|
|
6
12
|
readonly min: Date | null;
|
|
7
13
|
readonly max: Date | null;
|
|
8
|
-
constructor({ value, min, max, ...options }:
|
|
9
|
-
readonly value?: PossibleDate;
|
|
10
|
-
readonly min?: PossibleDate | null;
|
|
11
|
-
readonly max?: PossibleDate | null;
|
|
12
|
-
});
|
|
14
|
+
constructor({ value, min, max, ...options }: DateSchemaOptions);
|
|
13
15
|
validate(unsafeValue?: unknown): string;
|
|
14
16
|
}
|
|
15
17
|
/** Valid date, e.g. `2005-09-12` (required because falsy values are invalid). */
|
|
@@ -1,18 +1,20 @@
|
|
|
1
1
|
import { ImmutableDictionary } from "../util/dictionary.js";
|
|
2
2
|
import { Validator } from "../util/validate.js";
|
|
3
3
|
import { Schema, SchemaOptions } from "./Schema.js";
|
|
4
|
+
/** Allowed options for `DictionarySchema` */
|
|
5
|
+
export declare type DictionarySchemaOptions<T> = SchemaOptions & {
|
|
6
|
+
readonly items: Validator<T>;
|
|
7
|
+
readonly value?: ImmutableDictionary;
|
|
8
|
+
readonly min?: number | null;
|
|
9
|
+
readonly max?: number | null;
|
|
10
|
+
};
|
|
4
11
|
/** Validate a dictionary object (whose props are all the same with string keys). */
|
|
5
12
|
export declare class DictionarySchema<T> extends Schema<ImmutableDictionary<T>> {
|
|
6
13
|
readonly value: ImmutableDictionary;
|
|
7
14
|
readonly items: Validator<T>;
|
|
8
15
|
readonly min: number | null;
|
|
9
16
|
readonly max: number | null;
|
|
10
|
-
constructor({ value, items, min, max, ...rest }:
|
|
11
|
-
readonly items: Validator<T>;
|
|
12
|
-
readonly value?: ImmutableDictionary;
|
|
13
|
-
readonly min?: number | null;
|
|
14
|
-
readonly max?: number | null;
|
|
15
|
-
});
|
|
17
|
+
constructor({ value, items, min, max, ...rest }: DictionarySchemaOptions<T>);
|
|
16
18
|
validate(unsafeValue?: unknown): ImmutableDictionary<T>;
|
|
17
19
|
}
|
|
18
20
|
/** Valid dictionary object with specifed items. */
|
package/schema/LinkSchema.d.ts
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
import { StringSchema, StringSchemaOptions } from "./StringSchema.js";
|
|
2
|
+
/** Allowed options for `LinkSchema` */
|
|
3
|
+
export declare type LinkSchemaOptions = StringSchemaOptions & {
|
|
4
|
+
readonly schemes?: string[];
|
|
5
|
+
readonly hosts?: string[] | null;
|
|
6
|
+
};
|
|
2
7
|
/**
|
|
3
8
|
* Type of `StringSchema` that defines a valid URL.
|
|
4
9
|
* - Checks URL scheme against a whitelist (always), and checks URL domain against a whitelist (optional).
|
|
@@ -11,10 +16,7 @@ export declare class LinkSchema extends StringSchema {
|
|
|
11
16
|
readonly max = 512;
|
|
12
17
|
readonly schemes: string[];
|
|
13
18
|
readonly hosts: string[] | null;
|
|
14
|
-
constructor({ schemes, hosts, ...rest }:
|
|
15
|
-
readonly schemes?: string[];
|
|
16
|
-
readonly hosts?: string[] | null;
|
|
17
|
-
});
|
|
19
|
+
constructor({ schemes, hosts, ...rest }: LinkSchemaOptions);
|
|
18
20
|
validate(unsafeValue: unknown): string;
|
|
19
21
|
}
|
|
20
22
|
/** Valid link, e.g. `https://www.google.com` */
|
package/schema/NumberSchema.d.ts
CHANGED
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
import { Schema, SchemaOptions } from "./Schema.js";
|
|
2
|
+
/** Allowed options for `NumberSchema` */
|
|
3
|
+
export declare type NumberSchemaOptions = SchemaOptions & {
|
|
4
|
+
readonly value?: number | null;
|
|
5
|
+
readonly min?: number | null;
|
|
6
|
+
readonly max?: number | null;
|
|
7
|
+
readonly step?: number | null;
|
|
8
|
+
};
|
|
2
9
|
/** Schema that defines a valid number. */
|
|
3
10
|
export declare class NumberSchema extends Schema<number> {
|
|
4
11
|
readonly value: number | null;
|
|
5
12
|
readonly min: number | null;
|
|
6
13
|
readonly max: number | null;
|
|
7
14
|
readonly step: number | null;
|
|
8
|
-
constructor({ value, min, max, step, ...rest }:
|
|
9
|
-
readonly value?: number | null;
|
|
10
|
-
readonly min?: number | null;
|
|
11
|
-
readonly max?: number | null;
|
|
12
|
-
readonly step?: number | null;
|
|
13
|
-
});
|
|
15
|
+
constructor({ value, min, max, step, ...rest }: NumberSchemaOptions);
|
|
14
16
|
validate(unsafeValue?: unknown): number;
|
|
15
17
|
}
|
|
16
18
|
/** Valid number, e.g. `2048.12345` or `0` zero. */
|
package/schema/Schema.d.ts
CHANGED
|
@@ -2,11 +2,13 @@ import type { Validatable } from "../util/validate.js";
|
|
|
2
2
|
/** Options allowed by a `Schema` instance. */
|
|
3
3
|
export declare type SchemaOptions = {
|
|
4
4
|
/** Title of the schema, e.g. for using as the title of a corresponding field. */
|
|
5
|
-
readonly title?: string;
|
|
5
|
+
readonly title?: string | null;
|
|
6
6
|
/** Description of the schema, e.g. for using as a description in a corresponding field. */
|
|
7
|
-
readonly description?: string;
|
|
7
|
+
readonly description?: string | null;
|
|
8
8
|
/** Placeholder of the schema, e.g. for using as a placeholder in a corresponding field. */
|
|
9
|
-
readonly placeholder?: string;
|
|
9
|
+
readonly placeholder?: string | null;
|
|
10
|
+
/** Default value for the schema if `validate()` is called with an `undefined` value. */
|
|
11
|
+
readonly value?: unknown;
|
|
10
12
|
};
|
|
11
13
|
/**
|
|
12
14
|
* Schema is an object instance with a `validate()` method.
|
|
@@ -14,15 +16,15 @@ export declare type SchemaOptions = {
|
|
|
14
16
|
* - `validate()` returns `Invalid` if value was not valid.
|
|
15
17
|
*/
|
|
16
18
|
export declare abstract class Schema<T extends unknown = unknown> implements Validatable<T> {
|
|
17
|
-
/** Title, e.g. for
|
|
18
|
-
readonly title
|
|
19
|
-
/** Description, e.g. for
|
|
20
|
-
readonly description
|
|
21
|
-
/** Placeholder, e.g. for
|
|
22
|
-
readonly placeholder
|
|
23
|
-
/** Default value. */
|
|
24
|
-
readonly value
|
|
25
|
-
constructor({ title, description, placeholder }: SchemaOptions);
|
|
19
|
+
/** Title of the schema, e.g. for using as the title of a corresponding field. */
|
|
20
|
+
readonly title: string | null;
|
|
21
|
+
/** Description of the schema, e.g. for using as a description in a corresponding field. */
|
|
22
|
+
readonly description: string | null;
|
|
23
|
+
/** Placeholder of the schema, e.g. for using as a placeholder in a corresponding field. */
|
|
24
|
+
readonly placeholder: string | null;
|
|
25
|
+
/** Default value for the schema if `validate()` is called with an `undefined` value. */
|
|
26
|
+
readonly value: unknown;
|
|
27
|
+
constructor({ title, description, placeholder, value }: SchemaOptions);
|
|
26
28
|
/** Every schema must implement a `validate()` method. */
|
|
27
29
|
abstract validate(unsafeValue: unknown): T;
|
|
28
30
|
}
|
package/schema/Schema.js
CHANGED
|
@@ -4,9 +4,10 @@
|
|
|
4
4
|
* - `validate()` returns `Invalid` if value was not valid.
|
|
5
5
|
*/
|
|
6
6
|
export class Schema {
|
|
7
|
-
constructor({ title =
|
|
7
|
+
constructor({ title = null, description = null, placeholder = null, value }) {
|
|
8
8
|
this.title = title;
|
|
9
9
|
this.description = description;
|
|
10
10
|
this.placeholder = placeholder;
|
|
11
|
+
this.value = value;
|
|
11
12
|
}
|
|
12
13
|
}
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import type { Sourceable } from "../util/source.js";
|
|
2
|
-
import { Schema } from "./Schema.js";
|
|
2
|
+
import { Schema, SchemaOptions } from "./Schema.js";
|
|
3
|
+
/** Allowed options for `ThroughSchama` */
|
|
4
|
+
export declare type ThroughSchemaOptions<T> = SchemaOptions & {
|
|
5
|
+
source: Schema<T>;
|
|
6
|
+
};
|
|
3
7
|
/** Schema that passes through to a source schema. */
|
|
4
8
|
export declare abstract class ThroughSchema<T> extends Schema<T> implements Sourceable<Schema<T>> {
|
|
5
9
|
readonly source: Schema<T>;
|
|
6
|
-
constructor({ source, ...props }:
|
|
7
|
-
source: Schema<T>;
|
|
8
|
-
});
|
|
10
|
+
constructor({ source, ...props }: ThroughSchemaOptions<T>);
|
|
9
11
|
validate(unsafeValue: unknown): T;
|
|
10
12
|
}
|
package/schema/TimeSchema.d.ts
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
import { PossibleTime, Time } from "../util/time.js";
|
|
2
2
|
import { Schema, SchemaOptions } from "./Schema.js";
|
|
3
|
+
/** Allowed options for `TimeSchama` */
|
|
4
|
+
export declare type TimeSchemaOptions = SchemaOptions & {
|
|
5
|
+
readonly value?: PossibleTime;
|
|
6
|
+
readonly min?: PossibleTime | null;
|
|
7
|
+
readonly max?: PossibleTime | null;
|
|
8
|
+
readonly step?: number | null;
|
|
9
|
+
};
|
|
3
10
|
/** Define a valid time in 24h hh:mm:ss.fff format, e.g. `23:59` or `24:00 */
|
|
4
11
|
export declare class TimeSchema extends Schema<string> {
|
|
5
12
|
readonly value: PossibleTime;
|
|
@@ -10,12 +17,7 @@ export declare class TimeSchema extends Schema<string> {
|
|
|
10
17
|
* - Note: `<input type="time">` elements expect `step=""` to be in _seconds_ so you need to multiply this by `1000`
|
|
11
18
|
*/
|
|
12
19
|
readonly step: number | null;
|
|
13
|
-
constructor({ value, min, max, step, ...options }:
|
|
14
|
-
readonly value?: PossibleTime;
|
|
15
|
-
readonly min?: PossibleTime | null;
|
|
16
|
-
readonly max?: PossibleTime | null;
|
|
17
|
-
readonly step?: number | null;
|
|
18
|
-
});
|
|
20
|
+
constructor({ value, min, max, step, ...options }: TimeSchemaOptions);
|
|
19
21
|
validate(unsafeValue?: unknown): string;
|
|
20
22
|
}
|
|
21
23
|
/** Valid time, e.g. `2005-09-12` (required because falsy values are invalid). */
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Dispatch, Handler } from "../util/function.js";
|
|
1
|
+
import type { Dispatch, Handler, Stop } from "../util/function.js";
|
|
2
2
|
import { AbstractSequence } from "./AbstractSequence.js";
|
|
3
3
|
/**
|
|
4
4
|
* Deferred sequence of values.
|
|
@@ -21,10 +21,12 @@ export declare class DeferredSequence<T = void, R = void> extends AbstractSequen
|
|
|
21
21
|
private _nextReason;
|
|
22
22
|
/** Fulfill the current deferred by resolving or rejecting it. */
|
|
23
23
|
private readonly _fulfill;
|
|
24
|
+
/** Resolve the current deferred from a sequence of values. */
|
|
25
|
+
resolveSequence(sequence: AsyncIterable<T>): AsyncIterable<T>;
|
|
24
26
|
next(): Promise<IteratorResult<T, R>>;
|
|
25
27
|
then<X = T, Y = never>(onNext?: (v: T) => X | PromiseLike<X>, onError?: (r: unknown) => Y | PromiseLike<Y>): Promise<X | Y>;
|
|
26
28
|
catch<Y>(onError: (r: unknown) => Y | PromiseLike<Y>): Promise<T | Y>;
|
|
27
29
|
finally(onFinally: () => void): Promise<T>;
|
|
28
30
|
/** Subscrbe to the value of the sequence with a callback until the returned stop function is called. */
|
|
29
|
-
subscribe(onNext: Dispatch<[T]>, onError?: Handler):
|
|
31
|
+
subscribe(onNext: Dispatch<[T]>, onError?: Handler): Stop;
|
|
30
32
|
}
|
|
@@ -43,6 +43,13 @@ export class DeferredSequence extends AbstractSequence {
|
|
|
43
43
|
get value() {
|
|
44
44
|
return (this._deferred || (this._deferred = new Deferred()));
|
|
45
45
|
}
|
|
46
|
+
/** Resolve the current deferred from a sequence of values. */
|
|
47
|
+
async *resolveSequence(sequence) {
|
|
48
|
+
for await (const item of sequence) {
|
|
49
|
+
this.resolve(item);
|
|
50
|
+
yield item;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
46
53
|
// Implement `AsyncIterator`
|
|
47
54
|
async next() {
|
|
48
55
|
return { value: await this.value };
|
package/state/State.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { Dispatch, Handler, Stop } from "../util/function.js";
|
|
2
2
|
import { DeferredSequence } from "../sequence/DeferredSequence.js";
|
|
3
3
|
/** Any `State` instance. */
|
|
4
4
|
export declare type AnyState = State<any>;
|
|
@@ -12,7 +12,7 @@ export declare type AnyState = State<any>;
|
|
|
12
12
|
* - To set the state to be loading, use the `State.NOVALUE` constant or a `Promise` value.
|
|
13
13
|
* - To set the state to an explicit value, use that value or another `State` instance with a value.
|
|
14
14
|
* */
|
|
15
|
-
export declare class State<T> {
|
|
15
|
+
export declare class State<T> implements AsyncIterable<T> {
|
|
16
16
|
/** The `NOVALUE` symbol indicates no value has been received by a `State` instance. */
|
|
17
17
|
static readonly NOVALUE: unique symbol;
|
|
18
18
|
/** Deferred sequence this state uses to issue values as they change. */
|
|
@@ -33,6 +33,11 @@ export declare class State<T> {
|
|
|
33
33
|
set(value: T): void;
|
|
34
34
|
/** Set the value of the state as values are pulled from a sequence. */
|
|
35
35
|
setSequence(sequence: AsyncIterable<T>): AsyncIterable<T>;
|
|
36
|
-
/**
|
|
37
|
-
|
|
36
|
+
/** Pull values from a source sequence until the returned stop function is called. */
|
|
37
|
+
from(source: AsyncIterable<T>, onError?: Handler): Stop;
|
|
38
|
+
/** Push values to another state or callback to this state until the returned stop function is called. */
|
|
39
|
+
to(target: State<T> | Dispatch<[T]>, onError?: Handler): Stop;
|
|
40
|
+
[Symbol.asyncIterator](): AsyncIterator<T, any, undefined>;
|
|
38
41
|
}
|
|
42
|
+
/** Is an unknown value a `State` instance. */
|
|
43
|
+
export declare const isState: <T extends AnyState>(v: unknown) => v is T;
|
package/state/State.js
CHANGED
|
@@ -51,10 +51,33 @@ export class State {
|
|
|
51
51
|
yield value;
|
|
52
52
|
}
|
|
53
53
|
}
|
|
54
|
-
/**
|
|
55
|
-
|
|
56
|
-
return runSequence(this.setSequence(
|
|
54
|
+
/** Pull values from a source sequence until the returned stop function is called. */
|
|
55
|
+
from(source, onError) {
|
|
56
|
+
return runSequence(this.setSequence(source), onError);
|
|
57
|
+
}
|
|
58
|
+
/** Push values to another state or callback to this state until the returned stop function is called. */
|
|
59
|
+
to(target, onError) {
|
|
60
|
+
if (isState(target)) {
|
|
61
|
+
return runSequence(target.setSequence(this), onError);
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
return runSequence(this, target, onError);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
// Implement `AsyncIterable`
|
|
68
|
+
// Issues the current value of the state first, then any subsequent values that are issued.
|
|
69
|
+
[Symbol.asyncIterator]() {
|
|
70
|
+
// If this is still loading yield the next value as soon as we get one.
|
|
71
|
+
if (this.loading)
|
|
72
|
+
return this.next[Symbol.asyncIterator]();
|
|
73
|
+
// If this has a current value then yield the current value immediately, then the rest of the sequence.
|
|
74
|
+
// But! If additional values are set synchronously, only the yield the final one. Use a new `DeferredSequence` to make sure this happens cleanly.
|
|
75
|
+
const deferred = new DeferredSequence();
|
|
76
|
+
deferred.resolve(this.value);
|
|
77
|
+
return deferred.resolveSequence(this.next)[Symbol.asyncIterator]();
|
|
57
78
|
}
|
|
58
79
|
}
|
|
59
80
|
/** The `NOVALUE` symbol indicates no value has been received by a `State` instance. */
|
|
60
81
|
State.NOVALUE = Symbol("shelving/State.NOVALUE");
|
|
82
|
+
/** Is an unknown value a `State` instance. */
|
|
83
|
+
export const isState = (v) => v instanceof State;
|
package/update/DataUpdate.d.ts
CHANGED
|
@@ -10,7 +10,7 @@ import { Update } from "./Update.js";
|
|
|
10
10
|
* - If a prop contains an `Update` instance, the existing value is updated.
|
|
11
11
|
*/
|
|
12
12
|
export declare type Updates<T extends Data = Data> = {
|
|
13
|
-
readonly [K in keyof T]?: T[K] | Update<T[K]
|
|
13
|
+
readonly [K in keyof T]?: T[K] | Update<T[K]> | undefined;
|
|
14
14
|
};
|
|
15
15
|
/**
|
|
16
16
|
* Validate a set of updates against a set of validators.
|
|
@@ -30,5 +30,7 @@ export declare class DataUpdate<T extends Data = Data> extends Update<T> impleme
|
|
|
30
30
|
update<K extends DataKey<T>>(key: Nullish<K>, value: T[K] | Update<T[K]>): this;
|
|
31
31
|
transform(data: T): T;
|
|
32
32
|
validate(validator: Validator<T>): this;
|
|
33
|
-
[Symbol.iterator](): Iterator<DataProp<
|
|
33
|
+
[Symbol.iterator](): Iterator<DataProp<{
|
|
34
|
+
readonly [K in keyof T]: T[K] | Update<T[K]>;
|
|
35
|
+
}>, void>;
|
|
34
36
|
}
|
package/util/merge.d.ts
CHANGED
|
@@ -18,7 +18,7 @@ export declare const exactMerge: MergeRecursor;
|
|
|
18
18
|
* - Will be merged instance otherwise.
|
|
19
19
|
*/
|
|
20
20
|
export declare function shallowMerge<L extends ImmutableObject, R extends ImmutableObject>(left: L, right: R): L & R;
|
|
21
|
-
export declare function shallowMerge<L
|
|
21
|
+
export declare function shallowMerge<L, R>(left: ImmutableArray<L>, right: ImmutableArray<R>): ImmutableArray<L | R>;
|
|
22
22
|
export declare function shallowMerge<R>(left: unknown, right: R): R;
|
|
23
23
|
/**
|
|
24
24
|
* Deeply merge two unknown values.
|
|
@@ -32,7 +32,7 @@ export declare function shallowMerge<R>(left: unknown, right: R): R;
|
|
|
32
32
|
* - Will be a new merged instance otherwise.
|
|
33
33
|
*/
|
|
34
34
|
export declare function deepMerge<L extends ImmutableObject, R extends ImmutableObject>(left: L, right: R): L & R;
|
|
35
|
-
export declare function deepMerge<L
|
|
35
|
+
export declare function deepMerge<L, R>(left: ImmutableArray<L>, right: ImmutableArray<R>): ImmutableArray<L | R>;
|
|
36
36
|
export declare function deepMerge<R>(left: unknown, right: R): R;
|
|
37
37
|
/**
|
|
38
38
|
* Merge two arrays.
|
|
@@ -45,7 +45,7 @@ export declare function deepMerge<R>(left: unknown, right: R): R;
|
|
|
45
45
|
* - Will be `left` instance if no items were added.
|
|
46
46
|
* - Will be a new merged array otherwise.
|
|
47
47
|
*/
|
|
48
|
-
export declare function mergeArray<L
|
|
48
|
+
export declare function mergeArray<L, R>(left: ImmutableArray<L>, right: ImmutableArray<R> | ImmutableArray<L>): ImmutableArray<L | R>;
|
|
49
49
|
/**
|
|
50
50
|
* Merge two data objects.
|
|
51
51
|
*
|
package/util/merge.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { isArray } from "./array.js";
|
|
1
|
+
import { isArray, withArrayItems } from "./array.js";
|
|
2
2
|
import { isObject } from "./object.js";
|
|
3
3
|
// Internal shared by shallow/deep merge.
|
|
4
4
|
function _merge(left, right, recursor) {
|
|
@@ -21,17 +21,6 @@ export function shallowMerge(left, right) {
|
|
|
21
21
|
export function deepMerge(left, right) {
|
|
22
22
|
return _merge(left, right, deepMerge);
|
|
23
23
|
}
|
|
24
|
-
/**
|
|
25
|
-
* Merge two arrays.
|
|
26
|
-
* - Values are considered unique so values will not appear twice.
|
|
27
|
-
* - Arrays have no concept of `deep merge` because array keys are not stable.
|
|
28
|
-
* - Use an map/object data structure instead for values that need to be deeply mergeable (only use arrays for primitive values).
|
|
29
|
-
*
|
|
30
|
-
* @returns Merged array.
|
|
31
|
-
* - Values that appear in both arrays will not be added twice.
|
|
32
|
-
* - Will be `left` instance if no items were added.
|
|
33
|
-
* - Will be a new merged array otherwise.
|
|
34
|
-
*/
|
|
35
24
|
export function mergeArray(left, right) {
|
|
36
25
|
if (left === right)
|
|
37
26
|
return right;
|
|
@@ -39,11 +28,7 @@ export function mergeArray(left, right) {
|
|
|
39
28
|
return left;
|
|
40
29
|
if (!left.length)
|
|
41
30
|
return right;
|
|
42
|
-
|
|
43
|
-
for (const v of right)
|
|
44
|
-
if (!merged.includes(v))
|
|
45
|
-
merged.push(v);
|
|
46
|
-
return merged.length === left.length ? left : merged;
|
|
31
|
+
return withArrayItems(left, ...right);
|
|
47
32
|
}
|
|
48
33
|
export function mergeObject(left, right, recursor = exactMerge) {
|
|
49
34
|
if (left === right)
|
package/util/sequence.d.ts
CHANGED
|
@@ -1,22 +1,18 @@
|
|
|
1
1
|
import { SIGNAL } from "./constants.js";
|
|
2
2
|
import { Handler, Stop, AsyncDispatch, Dispatch } from "./function.js";
|
|
3
|
-
/** Slightly modify the definition of `AsyncIterable` to default `R` and `N` to `void` */
|
|
4
|
-
export declare interface AsyncIterable<T, R = void, N = void> {
|
|
5
|
-
[Symbol.asyncIterator](): AsyncIterator<T, R, N>;
|
|
6
|
-
}
|
|
7
3
|
/**
|
|
8
4
|
* Is a value an async iterable object?
|
|
9
5
|
* - Any object with a `Symbol.iterator` property is iterable.
|
|
10
6
|
* - Note: Array and Map instances etc will return true because they implement `Symbol.iterator`
|
|
11
7
|
*/
|
|
12
|
-
export declare const isAsyncIterable: <T extends AsyncIterable<unknown
|
|
8
|
+
export declare const isAsyncIterable: <T extends AsyncIterable<unknown>>(value: unknown) => value is T;
|
|
13
9
|
/** Infinite sequence that yields until a `SIGNAL` is received. */
|
|
14
|
-
export declare function repeatUntil<T
|
|
10
|
+
export declare function repeatUntil<T>(source: AsyncIterable<T>, ...signals: [Promise<typeof SIGNAL>, ...Promise<typeof SIGNAL>[]]): AsyncIterable<T>;
|
|
15
11
|
/** Infinite sequence that yields every X milliseconds (yields a count of the number of iterations). */
|
|
16
12
|
export declare function repeatDelay(ms: number): AsyncIterable<number>;
|
|
17
13
|
/** Dispatch items in a sequence to a (possibly async) callback. */
|
|
18
|
-
export declare function dispatchSequence<T
|
|
14
|
+
export declare function dispatchSequence<T>(sequence: AsyncIterable<T>, onNext: AsyncDispatch<[T]>): AsyncIterable<T>;
|
|
19
15
|
/** Get the first value from an async iterator. **/
|
|
20
|
-
export declare function getNextValue<T
|
|
16
|
+
export declare function getNextValue<T>(sequence: AsyncIterable<T>): Promise<T>;
|
|
21
17
|
/** Pull values from a sequence until the returned function is called. */
|
|
22
|
-
export declare function runSequence<T
|
|
18
|
+
export declare function runSequence<T>(sequence: AsyncIterable<T>, onNext?: Dispatch<[T]>, onError?: Handler): Stop;
|
package/util/transform.d.ts
CHANGED
|
@@ -6,15 +6,25 @@ import { ImmutableDictionary } from "./dictionary.js";
|
|
|
6
6
|
export interface Transformable<I, O> {
|
|
7
7
|
transform(input: I): O;
|
|
8
8
|
}
|
|
9
|
+
/** Object that transforms an input value into an output value with its `transform()` method. */
|
|
10
|
+
export interface AsyncTransformable<I, O> {
|
|
11
|
+
transform(input: I): O | PromiseLike<O>;
|
|
12
|
+
}
|
|
9
13
|
/** Is an unknown value a transformable. */
|
|
10
14
|
export declare const isTransformable: <T extends Transformable<unknown, unknown>>(v: unknown) => v is T;
|
|
11
15
|
/** Function that can transform an input value into an output value. */
|
|
12
16
|
export declare type Transform<I, O> = (input: I) => O;
|
|
17
|
+
/** Function that can transform an input value into an output value. */
|
|
18
|
+
export declare type AsyncTransform<I, O> = (input: I) => O | PromiseLike<O>;
|
|
13
19
|
/** Something that can transform an input value into an output value (or a plain value). */
|
|
14
20
|
export declare type Transformer<I, O> = Transformable<I, O> | Transform<I, O> | O;
|
|
21
|
+
/** Something that can transform an input value into an output value (or a plain value). */
|
|
22
|
+
export declare type AsyncTransformer<I, O> = AsyncTransformable<I, O> | AsyncTransform<I, O> | O;
|
|
15
23
|
/** Transform a value using a transformer. */
|
|
16
24
|
export declare function transform<I, O>(input: I, transformer: (v: I) => O): O;
|
|
25
|
+
export declare function transform<I, O>(input: I, transformer: (v: I) => O | PromiseLike<O>): O | PromiseLike<O>;
|
|
17
26
|
export declare function transform<I, O>(input: I, transformer: Transformer<I, O>): O;
|
|
27
|
+
export declare function transform<I, O>(input: I, transformer: AsyncTransformer<I, O>): O;
|
|
18
28
|
/** Modify a set of items using a transformer. */
|
|
19
29
|
export declare function mapItems<I, O>(items: Iterable<I>, transformer: Transformer<I, O>): Iterable<O>;
|
|
20
30
|
/** Modify the items of an array using a transformer. */
|
|
@@ -27,11 +37,13 @@ export declare function mapObject<I extends ImmutableObject, O extends Immutable
|
|
|
27
37
|
export declare const mapDictionary: <I, O>(dictionary: ImmutableDictionary<I>, transformer: Transformer<I, O>) => ImmutableDictionary<O>;
|
|
28
38
|
/** Modify the values of a set of entries using a transformer. */
|
|
29
39
|
export declare function mapEntries<K, I, O>(entries: Iterable<Entry<K, I>>, transformer: Transformer<I, O>): Iterable<Entry<K, O>>;
|
|
30
|
-
/** Set of named transformers for a data object. */
|
|
40
|
+
/** Set of named transformers for a data object (or `undefined` to skip the transform). */
|
|
31
41
|
export declare type Transformers<T extends ImmutableObject> = {
|
|
32
|
-
readonly [K in keyof T]?: Transformer<T[K], T[K]
|
|
42
|
+
readonly [K in keyof T]?: Transformer<T[K], T[K]> | undefined;
|
|
33
43
|
};
|
|
34
44
|
/** Transform an object using a set of named transformers. */
|
|
35
45
|
export declare function transformObject<T extends ImmutableObject>(obj: T, transforms: Transformers<T>): T;
|
|
36
46
|
/** Transform a dictionary object using a set of named transformers. */
|
|
37
47
|
export declare const transformDictionary: <T>(dict: ImmutableDictionary<T>, transforms: Transformers<ImmutableDictionary<T>>) => ImmutableDictionary<T>;
|
|
48
|
+
/** Transform items in a sequence as they are yielded using a (potentially async) transformer. */
|
|
49
|
+
export declare function mapSequence<L, R>(sequence: AsyncIterable<L>, transformer: AsyncTransformer<L, R>): AsyncIterable<R>;
|
package/util/transform.js
CHANGED
|
@@ -29,7 +29,13 @@ export function transformObject(obj, transforms) {
|
|
|
29
29
|
}
|
|
30
30
|
function* _transformObjectProps(obj, transforms) {
|
|
31
31
|
for (const [k, v] of getProps(transforms))
|
|
32
|
-
|
|
32
|
+
if (v !== undefined)
|
|
33
|
+
yield [k, transform(obj[k], v)];
|
|
33
34
|
}
|
|
34
35
|
/** Transform a dictionary object using a set of named transformers. */
|
|
35
36
|
export const transformDictionary = transformObject;
|
|
37
|
+
/** Transform items in a sequence as they are yielded using a (potentially async) transformer. */
|
|
38
|
+
export async function* mapSequence(sequence, transformer) {
|
|
39
|
+
for await (const item of sequence)
|
|
40
|
+
yield transform(item, transformer);
|
|
41
|
+
}
|