shelving 1.86.0 → 1.86.2

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 (97) hide show
  1. package/api/Resource.d.ts +2 -2
  2. package/constraint/Constraints.js +7 -6
  3. package/constraint/FilterConstraint.d.ts +4 -4
  4. package/constraint/FilterConstraint.js +17 -17
  5. package/constraint/QueryConstraints.d.ts +1 -1
  6. package/constraint/QueryConstraints.js +8 -8
  7. package/constraint/SortConstraint.d.ts +4 -4
  8. package/constraint/SortConstraint.js +3 -3
  9. package/db/Change.d.ts +4 -4
  10. package/db/Item.d.ts +4 -4
  11. package/error/ThroughError.js +1 -1
  12. package/markup/index.d.ts +1 -0
  13. package/markup/index.js +1 -0
  14. package/markup/options.d.ts +2 -2
  15. package/markup/regexp.d.ts +2 -2
  16. package/markup/render.js +19 -20
  17. package/markup/rule.d.ts +80 -0
  18. package/markup/rule.js +63 -0
  19. package/markup/rules.d.ts +17 -67
  20. package/markup/rules.js +88 -160
  21. package/package.json +17 -17
  22. package/react/useItem.js +10 -10
  23. package/react/useQuery.js +29 -29
  24. package/schema/AllowSchema.d.ts +4 -4
  25. package/schema/AllowSchema.js +3 -3
  26. package/schema/ArraySchema.d.ts +1 -1
  27. package/schema/BooleanSchema.d.ts +1 -1
  28. package/schema/DataSchema.d.ts +2 -2
  29. package/schema/DateSchema.d.ts +1 -1
  30. package/schema/DictionarySchema.d.ts +1 -1
  31. package/schema/LinkSchema.d.ts +1 -1
  32. package/schema/NumberSchema.d.ts +1 -1
  33. package/schema/NumberSchema.js +4 -4
  34. package/schema/Schema.d.ts +1 -1
  35. package/schema/StringSchema.d.ts +3 -3
  36. package/schema/ThroughSchema.d.ts +1 -1
  37. package/schema/TimeSchema.d.ts +1 -1
  38. package/state/State.d.ts +1 -1
  39. package/state/State.js +6 -6
  40. package/test/basics.d.ts +2 -2
  41. package/test/index.d.ts +1 -1
  42. package/test/people.d.ts +2 -2
  43. package/update/ArrayUpdate.d.ts +2 -1
  44. package/update/ArrayUpdate.js +9 -8
  45. package/update/DataUpdate.d.ts +1 -1
  46. package/update/DataUpdate.js +7 -6
  47. package/update/DictionaryUpdate.d.ts +1 -1
  48. package/update/DictionaryUpdate.js +8 -7
  49. package/util/array.d.ts +4 -4
  50. package/util/async.js +8 -8
  51. package/util/class.d.ts +3 -3
  52. package/util/clone.js +4 -3
  53. package/util/color.d.ts +2 -2
  54. package/util/color.js +6 -6
  55. package/util/data.d.ts +7 -14
  56. package/util/data.js +1 -19
  57. package/util/date.d.ts +3 -3
  58. package/util/debug.d.ts +1 -0
  59. package/util/debug.js +5 -5
  60. package/util/dictionary.d.ts +5 -5
  61. package/util/duration.d.ts +17 -0
  62. package/util/duration.js +52 -0
  63. package/util/entry.d.ts +3 -3
  64. package/util/equal.js +6 -3
  65. package/util/function.d.ts +8 -8
  66. package/util/hydrate.d.ts +3 -3
  67. package/util/hydrate.js +2 -2
  68. package/util/index.d.ts +1 -0
  69. package/util/index.js +1 -0
  70. package/util/iterate.d.ts +1 -1
  71. package/util/jsx.d.ts +3 -3
  72. package/util/lazy.d.ts +1 -1
  73. package/util/map.d.ts +15 -19
  74. package/util/map.js +11 -13
  75. package/util/match.d.ts +2 -2
  76. package/util/merge.d.ts +1 -1
  77. package/util/null.d.ts +1 -1
  78. package/util/number.d.ts +4 -2
  79. package/util/number.js +8 -6
  80. package/util/object.d.ts +24 -11
  81. package/util/object.js +30 -4
  82. package/util/regexp.d.ts +2 -3
  83. package/util/serialise.js +2 -2
  84. package/util/set.d.ts +4 -4
  85. package/util/sort.d.ts +2 -2
  86. package/util/source.js +2 -2
  87. package/util/string.d.ts +1 -1
  88. package/util/string.js +3 -3
  89. package/util/template.d.ts +2 -2
  90. package/util/template.js +9 -9
  91. package/util/time.d.ts +2 -2
  92. package/util/time.js +3 -3
  93. package/util/transform.d.ts +5 -5
  94. package/util/units.d.ts +39 -50
  95. package/util/units.js +36 -74
  96. package/util/url.d.ts +2 -2
  97. package/util/validate.d.ts +5 -5
package/util/data.js CHANGED
@@ -13,25 +13,7 @@ export function getData(result) {
13
13
  export function getDataProps(data) {
14
14
  return Object.entries(data);
15
15
  }
16
- /**
17
- * Format a data object as a string.
18
- * - Use the custom `.toString()` function if it exists (don't use built in `Object.prototype.toString` because it's useless.
19
- * - Use `.title` or `.name` or `.id` if they exist and are strings.
20
- * - Use `Object` otherwise.
21
- */
22
- export function formatData(data) {
23
- const { toString, name, title, id } = data;
24
- if (typeof toString === "function" && toString !== Object.prototype.toString)
25
- return data.toString();
26
- if (typeof name === "string")
27
- return name;
28
- if (typeof title === "string")
29
- return title;
30
- if (typeof id === "string")
31
- return id;
32
- return "Object";
33
- }
34
16
  /** An empty object. */
35
- export const EMPTY_DATA = {};
17
+ export const EMPTY_DATA = { __proto__: null };
36
18
  /** Function that returns an an empty object. */
37
19
  export const getEmptyData = () => EMPTY_DATA;
package/util/date.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  /** Things that converted to dates. */
2
- export declare type PossibleDate = Date | number | string;
2
+ export type PossibleDate = Date | number | string;
3
3
  /** Things that converted to dates or `null` */
4
- export declare type PossibleOptionalDate = Date | number | string | null;
4
+ export type PossibleOptionalDate = Date | number | string | null;
5
5
  /** Is a value a date? */
6
6
  export declare const isDate: (v: Date | unknown) => v is Date;
7
7
  /** Assert that a value is a `Date` instance. */
@@ -35,7 +35,7 @@ export declare const getYMD: (possible?: PossibleDate) => string;
35
35
  /** List of day-of-week strings. */
36
36
  export declare const days: readonly ["sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday"];
37
37
  /** Type listing day-of-week strings. */
38
- export declare type Day = typeof days[number];
38
+ export type Day = (typeof days)[number];
39
39
  /** Convert a `Date` instance to a day-of-week string like "monday" */
40
40
  export declare const getDay: (target?: PossibleDate) => Day;
41
41
  /** Get a Date representing exactly midnight of the specified date. */
package/util/debug.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ /** Note: try to avoid non-type imports in this file, it can easily cause circular imports. */
1
2
  import type { ImmutableArray } from "./array.js";
2
3
  import type { ImmutableMap } from "./map.js";
3
4
  import type { ImmutableSet } from "./set.js";
package/util/debug.js CHANGED
@@ -38,25 +38,25 @@ const _escapeChar = (char) => ESCAPE_LIST[char] || `\\x${char.charCodeAt(0).toSt
38
38
  /** Debug an array. */
39
39
  export function debugArray(value) {
40
40
  const prototype = Object.getPrototypeOf(value);
41
- const name = prototype === Array ? "" : prototype.name || "";
41
+ const name = prototype === Array.prototype ? "" : prototype.constructor.name || "";
42
42
  return `${name ? `${name} ` : ""}${value.length ? `[\n\t${value.map(debug).join(",\n\t")}\n]` : "[]"}`;
43
43
  }
44
44
  /** Debug a set. */
45
45
  export function debugSet(value) {
46
46
  const prototype = Object.getPrototypeOf(value);
47
- const name = prototype === Array ? "" : prototype.name || "Set";
47
+ const name = prototype === Set.prototype ? "" : prototype.constructor.name || "Set";
48
48
  return `${name}(value.size) ${value.size ? `{\n\t${Array.from(value).map(debug).join(",\n\t")}\n}` : "{}"}`;
49
49
  }
50
50
  /** Debug a map. */
51
51
  export function debugMap(value) {
52
52
  const prototype = Object.getPrototypeOf(value);
53
- const name = prototype === Array ? "" : prototype.name || "Map";
53
+ const name = prototype === Map.prototype ? "" : prototype.constructor.name || "Map";
54
54
  return `${name}(value.size) ${value.size ? `{\n\t${Array.from(value).map(_debugProp).join(",\n\t")}\n}` : "{}"}`;
55
55
  }
56
56
  /** Debug an object. */
57
57
  export function debugObject(value) {
58
- const prototype = Object.getPrototypeOf(value) || Object;
59
- const name = prototype === Object ? "" : prototype.name || "";
58
+ const prototype = Object.getPrototypeOf(value);
59
+ const name = prototype === Object.prototype ? "" : prototype.constructor.name || "";
60
60
  const props = Object.entries(value).map(_debugProp);
61
61
  return `${name ? `${name} ` : ""}${props.length ? `{\n\t${props.join(",\n\t")}\n}` : "{}"}`;
62
62
  }
@@ -1,17 +1,17 @@
1
1
  /** Readonly dictionary object. */
2
- export declare type ImmutableDictionary<T = unknown> = {
2
+ export type ImmutableDictionary<T = unknown> = {
3
3
  readonly [K in string]: T;
4
4
  };
5
5
  /** Writable dictionary object. */
6
- export declare type MutableDictionary<T = unknown> = {
6
+ export type MutableDictionary<T = unknown> = {
7
7
  [K in string]: T;
8
8
  };
9
9
  /** Get the type for an item of a dictionary object in entry format. */
10
- export declare type DictionaryItem<T> = readonly [string, T];
10
+ export type DictionaryItem<T> = readonly [string, T];
11
11
  /** Get the type of the _values_ of the items of a dictionary object. */
12
- export declare type DictionaryValue<T extends ImmutableDictionary> = T[string];
12
+ export type DictionaryValue<T extends ImmutableDictionary> = T[string];
13
13
  /** Something that can be converted to a dictionary object. */
14
- export declare type PossibleDictionary<T> = ImmutableDictionary<T> | Iterable<DictionaryItem<T>>;
14
+ export type PossibleDictionary<T> = ImmutableDictionary<T> | Iterable<DictionaryItem<T>>;
15
15
  /** Is an unknown value a dictionary object? */
16
16
  export declare const isDictionary: <T extends ImmutableDictionary<T>>(value: unknown) => value is T;
17
17
  /** Assert that an unknown value is a dictionary object */
@@ -0,0 +1,17 @@
1
+ import { PossibleDate } from "./date.js";
2
+ /** Format a full format of a duration of time using the most reasonable units e.g. `5 years` or `1 week` or `4 minutes` or `12 milliseconds`. */
3
+ export declare function formatFullDuration(ms: number, precision?: number): string;
4
+ /** Format a description of a duration of time using the most reasonable units e.g. `5y` or `4m` or `12ms`. */
5
+ export declare function formatDuration(ms: number, precision?: number): string;
6
+ /** Full when a date happens/happened, e.g. `in 10 days` or `2 hours ago` */
7
+ export declare const formatFullWhen: (target: PossibleDate, current?: PossibleDate) => string;
8
+ /** Compact when a date happens/happened, e.g. `in 10d` or `2h ago` or `in 1w` */
9
+ export declare const formatWhen: (target: PossibleDate, current?: PossibleDate) => string;
10
+ /** Full when a date happens, e.g. `10 days` or `2 hours` or `-1 week` */
11
+ export declare const formatFullUntil: (target: PossibleDate, current?: PossibleDate) => string;
12
+ /** Compact when a date happens, e.g. `10d` or `2h` or `-1w` */
13
+ export declare const formatUntil: (target: PossibleDate, current?: PossibleDate) => string;
14
+ /** Full when a date happened, e.g. `10 days` or `2 hours` or `-1 week` */
15
+ export declare const formatFullAgo: (target: PossibleDate, current?: PossibleDate) => string;
16
+ /** Compact when a date will happen, e.g. `10d` or `2h` or `-1w` */
17
+ export declare const formatAgo: (target: PossibleDate, current?: PossibleDate) => string;
@@ -0,0 +1,52 @@
1
+ import { MONTH, WEEK, DAY, HOUR, SECOND } from "./constants.js";
2
+ import { getDuration } from "./date.js";
3
+ import { getMapItem } from "./map.js";
4
+ import { TIME_UNITS } from "./units.js";
5
+ /** Get the ID for a time unit based on the amount in milliseconds. */
6
+ function _getTimeUnitKey(ms) {
7
+ const abs = Math.abs(ms);
8
+ if (abs > 18 * MONTH)
9
+ return "year";
10
+ if (abs > 10 * WEEK)
11
+ return "month";
12
+ if (abs > 2 * WEEK)
13
+ return "week";
14
+ if (abs > DAY)
15
+ return "day";
16
+ if (abs > HOUR)
17
+ return "hour";
18
+ if (abs > 9949)
19
+ return "minute";
20
+ if (abs > SECOND)
21
+ return "second";
22
+ return "millisecond";
23
+ }
24
+ /** Format a full format of a duration of time using the most reasonable units e.g. `5 years` or `1 week` or `4 minutes` or `12 milliseconds`. */
25
+ export function formatFullDuration(ms, precision) {
26
+ const unit = getMapItem(TIME_UNITS, _getTimeUnitKey(ms));
27
+ return unit.formatFull(unit.from(ms), precision);
28
+ }
29
+ /** Format a description of a duration of time using the most reasonable units e.g. `5y` or `4m` or `12ms`. */
30
+ export function formatDuration(ms, precision) {
31
+ const unit = getMapItem(TIME_UNITS, _getTimeUnitKey(ms));
32
+ return unit.format(unit.from(ms), precision);
33
+ }
34
+ /** format when a data happens/happened. */
35
+ function _formatWhen(formatter, target, current) {
36
+ const ms = getDuration(target, current);
37
+ const abs = Math.abs(ms);
38
+ const duration = formatter(ms);
39
+ return abs < 10 * SECOND ? "just now" : ms > 0 ? `in ${duration}` : `${duration} ago`;
40
+ }
41
+ /** Full when a date happens/happened, e.g. `in 10 days` or `2 hours ago` */
42
+ export const formatFullWhen = (target, current) => _formatWhen(formatFullDuration, target, current);
43
+ /** Compact when a date happens/happened, e.g. `in 10d` or `2h ago` or `in 1w` */
44
+ export const formatWhen = (target, current) => _formatWhen(formatDuration, target, current);
45
+ /** Full when a date happens, e.g. `10 days` or `2 hours` or `-1 week` */
46
+ export const formatFullUntil = (target, current) => formatFullDuration(getDuration(target, current));
47
+ /** Compact when a date happens, e.g. `10d` or `2h` or `-1w` */
48
+ export const formatUntil = (target, current) => formatDuration(getDuration(target, current));
49
+ /** Full when a date happened, e.g. `10 days` or `2 hours` or `-1 week` */
50
+ export const formatFullAgo = (target, current) => formatFullDuration(getDuration(current, target));
51
+ /** Compact when a date will happen, e.g. `10d` or `2h` or `-1w` */
52
+ export const formatAgo = (target, current) => formatDuration(getDuration(current, target));
package/util/entry.d.ts CHANGED
@@ -6,11 +6,11 @@ import { ImmutableSet } from "./set.js";
6
6
  * - Consistency with `UnknownObject`
7
7
  * - Always readonly.
8
8
  */
9
- export declare type Entry<K = unknown, T = unknown> = readonly [K, T];
9
+ export type Entry<K = unknown, T = unknown> = readonly [K, T];
10
10
  /** Extract the type for the value of an entry. */
11
- export declare type EntryKey<X> = X extends Entry<infer Y, unknown> ? Y : never;
11
+ export type EntryKey<X> = X extends Entry<infer Y, unknown> ? Y : never;
12
12
  /** Extract the type for the value of an entry. */
13
- export declare type EntryValue<X> = X extends Entry<unknown, infer Y> ? Y : never;
13
+ export type EntryValue<X> = X extends Entry<unknown, infer Y> ? Y : never;
14
14
  /** Extract the key from an object entry. */
15
15
  export declare const getEntryKey: <K, T>([k]: Entry<K, T>) => K;
16
16
  /** Extract the value from an object entry. */
package/util/equal.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { isArray } from "./array.js";
2
- import { isObject } from "./object.js";
2
+ import { getPrototype, isObject } from "./object.js";
3
3
  import { isMap } from "./map.js";
4
4
  // Internal shared by shallow/deep equal.
5
5
  function _equal(left, right, recursor) {
@@ -35,7 +35,10 @@ export function isMapEqual(left, right, recursor = isExactlyEqual) {
35
35
  return false; // Different lengths aren't equal.
36
36
  const rightIterator = right.entries();
37
37
  for (const [leftKey, leftValue] of left) {
38
- const [rightKey, rightValue] = rightIterator.next().value;
38
+ const { done, value } = rightIterator.next();
39
+ if (done)
40
+ return false;
41
+ const [rightKey, rightValue] = value;
39
42
  if (leftKey !== rightKey || !recursor(leftValue, rightValue))
40
43
  return false;
41
44
  }
@@ -70,7 +73,7 @@ export function isObjectEqual(left, right, recursor = isExactlyEqual) {
70
73
  var _a, _b;
71
74
  if (left === right)
72
75
  return true; // Referentially equal.
73
- if (((_a = Object.getPrototypeOf(left)) === null || _a === void 0 ? void 0 : _a.constructor) !== ((_b = Object.getPrototypeOf(right)) === null || _b === void 0 ? void 0 : _b.constructor))
76
+ if (((_a = getPrototype(left)) === null || _a === void 0 ? void 0 : _a.constructor) !== ((_b = getPrototype(right)) === null || _b === void 0 ? void 0 : _b.constructor))
74
77
  return false; // Constructors are not equal.
75
78
  const leftEntries = Object.entries(left);
76
79
  const rightKeys = Object.keys(right);
@@ -1,21 +1,21 @@
1
1
  /** Unknown function. */
2
- export declare type UnknownFunction = (...args: unknown[]) => unknown;
2
+ export type UnknownFunction = (...args: unknown[]) => unknown;
3
3
  /** Any function (designed for use with `extends AnyFunction` guards). */
4
- export declare type AnyFunction = (...args: any) => any;
4
+ export type AnyFunction = (...args: any) => any;
5
5
  /** Is a value a function? */
6
6
  export declare const isFunction: <T extends AnyFunction>(v: unknown) => v is T;
7
7
  /** Assert that a value is a function. */
8
8
  export declare function assertFunction<T extends AnyFunction>(v: T | unknown): asserts v is T;
9
9
  /** Readonly unknown array that is being used as a set of arguments to a function. */
10
- export declare type Arguments = readonly unknown[];
10
+ export type Arguments = readonly unknown[];
11
11
  /** Function that just passes through the first argument. */
12
12
  export declare const PASSTHROUGH: <T>(value: T) => T;
13
13
  /** Function that does nothing with its arguments and always returns void. */
14
14
  export declare const BLACKHOLE: (...args: Arguments) => void | undefined;
15
15
  /** Function that receives a dispatched value. */
16
- export declare type Dispatch<T extends Arguments = []> = (...value: T) => void;
16
+ export type Dispatch<T extends Arguments = []> = (...value: T) => void;
17
17
  /** Function that receives a dispatched value. */
18
- export declare type AsyncDispatch<T extends Arguments = []> = (...value: T) => void | PromiseLike<void>;
18
+ export type AsyncDispatch<T extends Arguments = []> = (...value: T) => void | PromiseLike<void>;
19
19
  /** Safely dispatch a value to a dispatcher function. */
20
20
  export declare function dispatch<A extends Arguments>(func: AsyncDispatch<A>, ...value: A): void;
21
21
  /** Return a function that dispatches a value to a dispatcher function. */
@@ -25,8 +25,8 @@ export declare function dispatchMethod<T extends Arguments, M extends string | s
25
25
  [K in M]: AsyncDispatch<T>;
26
26
  }, key: M, ...value: T): void;
27
27
  /** Function that starts something. */
28
- export declare type Start<A extends Arguments = []> = (...args: A) => Stop | void;
28
+ export type Start<A extends Arguments = []> = (...args: A) => Stop | void;
29
29
  /** Function that stops something. */
30
- export declare type Stop = Dispatch;
30
+ export type Stop = Dispatch;
31
31
  /** Function that handles an error. */
32
- export declare type Handler = (reason: Error | unknown) => void;
32
+ export type Handler = (reason: Error | unknown) => void;
package/util/hydrate.d.ts CHANGED
@@ -5,7 +5,7 @@ import { Transformable } from "./transform.js";
5
5
  * A set of hydrations describes a set of string keys and the class constructor to be dehydrated and rehydrated.
6
6
  * - We can't use `class.name` because we don't know that the name of the class will survive minification.
7
7
  */
8
- export declare type Hydrations = ImmutableDictionary<Class>;
8
+ export type Hydrations = ImmutableDictionary<Class>;
9
9
  /**
10
10
  * Deeply dehydrate a class instance based on a set of `Hydrations`
11
11
  * - Dehydration allows you to pass class instances from a server back to a client.
@@ -26,9 +26,9 @@ export declare function dehydrate(value: unknown, hydrations: Hydrations): unkno
26
26
  */
27
27
  export declare function hydrate(value: unknown, hydrations: Hydrations): unknown;
28
28
  /** A dehydrated object with a `$type` key. */
29
- export declare type DehydratedObject = {
29
+ export type DehydratedObject = {
30
30
  readonly $type: string;
31
- readonly $value: any;
31
+ readonly $value: unknown;
32
32
  };
33
33
  /** Hydrates a value with a set of hydrations. */
34
34
  export declare class Hydrator implements Transformable<unknown, unknown> {
package/util/hydrate.js CHANGED
@@ -2,7 +2,7 @@ import { AssertionError } from "../error/AssertionError.js";
2
2
  import { isArray } from "./array.js";
3
3
  import { isDate } from "./date.js";
4
4
  import { isMap } from "./map.js";
5
- import { isObject, isPlainObject } from "./object.js";
5
+ import { getPrototype, isObject, isPlainObject } from "./object.js";
6
6
  import { isSet } from "./set.js";
7
7
  import { isString } from "./string.js";
8
8
  import { mapArray, mapObject, mapEntries, mapItems } from "./transform.js";
@@ -72,7 +72,7 @@ export class Dehydrator {
72
72
  if (isDate(value))
73
73
  return { $type: "Date", $value: value.getTime() };
74
74
  if (isObject(value)) {
75
- const proto = Object.getPrototypeOf(value);
75
+ const proto = getPrototype(value);
76
76
  if (proto === Object.prototype || proto === null)
77
77
  return mapObject(value, this);
78
78
  for (const [$type, hydration] of Object.entries(this._hydrations))
package/util/index.d.ts CHANGED
@@ -12,6 +12,7 @@ export * from "./date.js";
12
12
  export * from "./debug.js";
13
13
  export * from "./dictionary.js";
14
14
  export * from "./diff.js";
15
+ export * from "./duration.js";
15
16
  export * from "./entry.js";
16
17
  export * from "./equal.js";
17
18
  export * from "./error.js";
package/util/index.js CHANGED
@@ -12,6 +12,7 @@ export * from "./date.js";
12
12
  export * from "./debug.js";
13
13
  export * from "./dictionary.js";
14
14
  export * from "./diff.js";
15
+ export * from "./duration.js";
15
16
  export * from "./entry.js";
16
17
  export * from "./equal.js";
17
18
  export * from "./error.js";
package/util/iterate.d.ts CHANGED
@@ -7,7 +7,7 @@ import { Arguments } from "./function.js";
7
7
  import { Matcher } from "./match.js";
8
8
  export declare const isIterable: <T extends Iterable<unknown>>(value: unknown) => value is T;
9
9
  /** An iterable containing items or nested iterables of items. */
10
- export declare type DeepIterable<T> = T | Iterable<DeepIterable<T>>;
10
+ export type DeepIterable<T> = T | Iterable<DeepIterable<T>>;
11
11
  /** Flatten one or more iterables. */
12
12
  export declare function flattenItems<T>(items: DeepIterable<T>): Iterable<T>;
13
13
  /**
package/util/jsx.d.ts CHANGED
@@ -1,10 +1,10 @@
1
1
  /** Set of valid props for a JSX element. */
2
- export declare type JSXProps = {
2
+ export type JSXProps = {
3
3
  [key: string]: unknown;
4
4
  children?: JSXNode;
5
5
  };
6
6
  /** JSX element (similar to `React.ReactElement`) */
7
- export declare type JSXElement<P extends JSXProps = JSXProps> = {
7
+ export type JSXElement<P extends JSXProps = JSXProps> = {
8
8
  type: string | ((props: P) => JSXElement | null);
9
9
  props: P;
10
10
  key: string | number | null;
@@ -12,7 +12,7 @@ export declare type JSXElement<P extends JSXProps = JSXProps> = {
12
12
  $$typeof?: symbol;
13
13
  };
14
14
  /** JSX node (similar to `React.ReactNode`) */
15
- export declare type JSXNode = undefined | null | string | JSXElement | JSXNode[];
15
+ export type JSXNode = undefined | null | string | JSXElement | JSXNode[];
16
16
  /** Is an unknown value a JSX element? */
17
17
  export declare const isJSXElement: <T extends JSXElement<JSXProps>>(v: unknown) => v is T;
18
18
  /** Is an unknown value a JSX node? */
package/util/lazy.d.ts CHANGED
@@ -3,7 +3,7 @@ import { Arguments } from "./function.js";
3
3
  * Lazy value: a plain value, or an initialiser function that returns that value.
4
4
  * @param ...args Any arguments the lazy value needs if it's a function.
5
5
  */
6
- export declare type Lazy<T, A extends Arguments = []> = ((...args: A) => T) | T;
6
+ export type Lazy<T, A extends Arguments = []> = ((...args: A) => T) | T;
7
7
  /**
8
8
  * Initialise a lazy value.
9
9
  *
package/util/map.d.ts CHANGED
@@ -1,18 +1,22 @@
1
1
  import { Entry } from "./entry.js";
2
2
  /** `Map` that cannot be changed. */
3
- export declare type ImmutableMap<K = unknown, T = unknown> = ReadonlyMap<K, T>;
3
+ export type ImmutableMap<K = unknown, T = unknown> = ReadonlyMap<K, T>;
4
+ /** Class for a `Map` that cannot be changed (so you can extend `Map` while implementing `ImmutableMap`). */
5
+ export declare const ImmutableMap: {
6
+ new <K, T>(...params: ConstructorParameters<typeof Map<K, T>>): ImmutableMap<K, T>;
7
+ };
4
8
  /** `Map` that can be changed. */
5
- export declare type MutableMap<K = unknown, T = unknown> = Map<K, T>;
9
+ export type MutableMap<K = unknown, T = unknown> = Map<K, T>;
6
10
  /** Extract the type for the value of a map. */
7
- export declare type MapKey<X> = X extends ReadonlyMap<infer Y, unknown> ? Y : never;
11
+ export type MapKey<X> = X extends ReadonlyMap<infer Y, unknown> ? Y : never;
8
12
  /** Extract the type for the value of a map. */
9
- export declare type MapValue<X> = X extends ReadonlyMap<unknown, infer Y> ? Y : never;
13
+ export type MapValue<X> = X extends ReadonlyMap<unknown, infer Y> ? Y : never;
10
14
  /** Get the type for an item of a map in entry format. */
11
- export declare type MapItem<T extends ImmutableMap> = readonly [MapKey<T>, MapValue<T>];
15
+ export type MapItem<T extends ImmutableMap> = readonly [MapKey<T>, MapValue<T>];
12
16
  /** Things that can be converted to maps. */
13
- export declare type PossibleMap<K, T> = ImmutableMap<K, T> | Iterable<Entry<K, T>>;
17
+ export type PossibleMap<K, T> = ImmutableMap<K, T> | Iterable<Entry<K, T>>;
14
18
  /** Things that can be converted to maps with string keys. */
15
- export declare type PossibleStringMap<K extends string, T> = PossibleMap<K, T> | {
19
+ export type PossibleStringMap<K extends string, T> = PossibleMap<K, T> | {
16
20
  readonly [KK in K]: T;
17
21
  };
18
22
  /** Is an unknown value a map? */
@@ -24,9 +28,6 @@ export declare function assertMap<T extends ImmutableMap>(v: T | unknown): asser
24
28
  /** Convert an iterable to a `Map` (if it's already a `Map` it passes through unchanged). */
25
29
  export declare function getMap<K extends string, T>(input: PossibleStringMap<K, T>): ImmutableMap<K, T>;
26
30
  export declare function getMap<K, T>(input: PossibleMap<K, T>): ImmutableMap<K, T>;
27
- /** Convert an iterable to a `Map` (if it's already a `Map` it passes through unchanged). */
28
- export declare function getRequiredMap<K extends string, T>(input: PossibleStringMap<K, T>): ImmutableRequiredMap<K, T>;
29
- export declare function getRequiredMap<K, T>(input: PossibleMap<K, T>): ImmutableRequiredMap<K, T>;
30
31
  /** Apply a limit to a map. */
31
32
  export declare function limitMap<T>(map: ImmutableMap<T>, limit: number): ImmutableMap<T>;
32
33
  /** Function that lets new items in a map be created and updated by calling a `reduce()` callback that receives the existing value. */
@@ -35,12 +36,7 @@ export declare function setMapItem<K, T>(map: MutableMap<K, T>, key: K, value: T
35
36
  export declare function setMapItems<K, T>(map: MutableMap<K, T>, items: Iterable<MapItem<ImmutableMap<K, T>>>): void;
36
37
  /** Remove multiple items from a set (by reference). */
37
38
  export declare function removeMapItems<K, T>(map: MutableMap<K, T>, ...keys: K[]): void;
38
- /** Mutable map that changes `get()` to throw an error if the requested value doesn't exist. */
39
- export declare class MutableRequiredMap<K, T> extends Map<K, T> {
40
- get(key: K): T;
41
- }
42
- /** Immutable map that changes `get()` to throw an error if the requested value doesn't exist. */
43
- export declare const ImmutableRequiredMap: {
44
- new <K, T>(...params: ConstructorParameters<typeof MutableRequiredMap<K, T>>): ImmutableRequiredMap<K, T>;
45
- };
46
- export declare type ImmutableRequiredMap<K, T> = Omit<MutableRequiredMap<K, T>, "set" | "delete">;
39
+ /** Get an item in a map or throw an error if it doesn't exist. */
40
+ export declare function getMapItem<K, T>(map: ImmutableMap<K, T>, key: K): T;
41
+ /** Get an item in a map or `null` if it doesn't exist. */
42
+ export declare function getOptionalMapItem<K, T>(map: ImmutableMap<K, T>, key: K): T | null;
package/util/map.js CHANGED
@@ -1,7 +1,8 @@
1
1
  import { AssertionError } from "../error/AssertionError.js";
2
2
  import { RequiredError } from "../error/RequiredError.js";
3
3
  import { isIterable, limitItems } from "./iterate.js";
4
- import { getString } from "./string.js";
4
+ /** Class for a `Map` that cannot be changed (so you can extend `Map` while implementing `ImmutableMap`). */
5
+ export const ImmutableMap = Map;
5
6
  /** Is an unknown value a map? */
6
7
  export const isMap = (v) => v instanceof Map;
7
8
  /** Is an unknown value a key for an item in a map? */
@@ -14,9 +15,6 @@ export function assertMap(v) {
14
15
  export function getMap(input) {
15
16
  return isMap(input) ? input : new Map(isIterable(input) ? input : Object.entries(input));
16
17
  }
17
- export function getRequiredMap(input) {
18
- return input instanceof ImmutableRequiredMap ? input : new ImmutableRequiredMap(isIterable(input) ? input : Object.entries(input));
19
- }
20
18
  /** Apply a limit to a map. */
21
19
  export function limitMap(map, limit) {
22
20
  return limit > map.size ? map : new Map(limitItems(map, limit));
@@ -36,13 +34,13 @@ export function removeMapItems(map, ...keys) {
36
34
  for (const key of keys)
37
35
  map.delete(key);
38
36
  }
39
- /** Mutable map that changes `get()` to throw an error if the requested value doesn't exist. */
40
- export class MutableRequiredMap extends Map {
41
- get(key) {
42
- if (!this.has(key))
43
- throw new RequiredError(`Item "${getString(key)}" is required`);
44
- return super.get(key);
45
- }
37
+ /** Get an item in a map or throw an error if it doesn't exist. */
38
+ export function getMapItem(map, key) {
39
+ if (!map.has(key))
40
+ throw new RequiredError(`Map item is required`);
41
+ return map.get(key);
42
+ }
43
+ /** Get an item in a map or `null` if it doesn't exist. */
44
+ export function getOptionalMapItem(map, key) {
45
+ return map.has(key) ? map.get(key) : null;
46
46
  }
47
- /** Immutable map that changes `get()` to throw an error if the requested value doesn't exist. */
48
- export const ImmutableRequiredMap = MutableRequiredMap;
package/util/match.d.ts CHANGED
@@ -4,9 +4,9 @@ export interface Matchable<A extends Arguments = unknown[]> {
4
4
  match(...args: A): boolean;
5
5
  }
6
6
  /** Function that can match an item against a target. */
7
- export declare type Match<A extends Arguments = unknown[]> = (...args: A) => boolean;
7
+ export type Match<A extends Arguments = unknown[]> = (...args: A) => boolean;
8
8
  /** Match is either a `Matcherable` object, or matcher function. */
9
- export declare type Matcher<A extends Arguments = unknown[]> = Matchable<A> | Match<A>;
9
+ export type Matcher<A extends Arguments = unknown[]> = Matchable<A> | Match<A>;
10
10
  /** Match two values using a `Matcher`. */
11
11
  export declare function match<A extends Arguments>(matcher: Matcher<A>, ...args: A): boolean;
12
12
  export declare const isEqual: Match<[item: unknown, target: unknown]>;
package/util/merge.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { ImmutableArray } from "./array.js";
2
2
  import { ImmutableObject } from "./object.js";
3
- declare type MergeRecursor = (left: unknown, right: unknown) => unknown;
3
+ type MergeRecursor = (left: unknown, right: unknown) => unknown;
4
4
  /**
5
5
  * Exact merge two unknown values.
6
6
  * - Always returns `right`.
package/util/null.d.ts CHANGED
@@ -9,7 +9,7 @@ export declare function assertNotNull<T>(v: T | null): asserts v is T;
9
9
  /** Get the not-nullish version of value. */
10
10
  export declare function getNotNull<T>(v: T | null): T;
11
11
  /** Nullish is `null` or `undefined` */
12
- export declare type Nullish<T> = T | null | undefined;
12
+ export type Nullish<T> = T | null | undefined;
13
13
  /** Is a value nullish? */
14
14
  export declare const isNullish: <T>(v: Nullish<T>) => v is null | undefined;
15
15
  /** Is a value not nullish? */
package/util/number.d.ts CHANGED
@@ -70,7 +70,7 @@ export declare function boundNumber(num: number, min: number, max: number): numb
70
70
  export declare function wrapNumber(num: number, min: number, max: number): number;
71
71
  /** Format a number (based on the user's browser language settings). */
72
72
  export declare function formatNumber(num: number, precision?: number | null): string;
73
- /** Format a number with a short abbreviated suffix. */
73
+ /** Format a number with a short suffix, e.g. `1,000 kg` */
74
74
  export declare const formatQuantity: (num: number, abbr: string, precision?: number | null) => string;
75
75
  /** Format a number with a longer full-word suffix. */
76
76
  export declare function formatFullQuantity(num: number, singular: string, plural: string, precision?: number | null): string;
@@ -98,7 +98,7 @@ export declare function formatFullQuantity(num: number, singular: string, plural
98
98
  * @returns The number formatted as a crammed string.
99
99
  */
100
100
  export declare function cramNumber(num: number): string;
101
- /** Cram a number with a short suffix. */
101
+ /** Cram a number with a short suffix, e.g. `1.02M kg` */
102
102
  export declare const cramQuantity: (num: number, suffix: string) => string;
103
103
  /** Cram a number with a longer full-word suffix. */
104
104
  export declare function cramFullQuantity(num: number, singular: string, plural: string): string;
@@ -109,6 +109,8 @@ export declare function cramFullQuantity(num: number, singular: string, plural:
109
109
  * @param denumerator The number representing the whole amount.
110
110
  */
111
111
  export declare const getPercent: (numerator: number, denumerator: number) => number;
112
+ /** Format a percentage (combines `getPercent()` and `formatQuantity()` for convenience). */
113
+ export declare const formatPercent: (numerator: number, denumerator: number, precision?: number) => string;
112
114
  /** Sum an iterable set of numbers and return the total. */
113
115
  export declare function sumNumbers(nums: Iterable<number>): number;
114
116
  /** Find the number that's closest to a target in an iterable set of numbers. */
package/util/number.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { AssertionError } from "../error/AssertionError.js";
2
- import { BILLION, MILLION, NNBSP, TRILLION } from "./constants.js";
2
+ import { BILLION, MILLION, NNBSP, TEN_THOUSAND, THOUSAND, TRILLION } from "./constants.js";
3
3
  /** Is a value a number? */
4
4
  export const isNumber = (v) => typeof v === "number";
5
5
  /** Assert that a value is a number. */
@@ -114,7 +114,7 @@ export function formatNumber(num, precision = null) {
114
114
  return Number.isNaN(num) ? "None" : "Infinity";
115
115
  return new Intl.NumberFormat(undefined, { minimumFractionDigits: precision !== null && precision !== void 0 ? precision : undefined, maximumFractionDigits: precision !== null && precision !== void 0 ? precision : 20 }).format(num);
116
116
  }
117
- /** Format a number with a short abbreviated suffix. */
117
+ /** Format a number with a short suffix, e.g. `1,000 kg` */
118
118
  export const formatQuantity = (num, abbr, precision) => `${formatNumber(num, precision)}${NNBSP}${abbr}`;
119
119
  /** Format a number with a longer full-word suffix. */
120
120
  export function formatFullQuantity(num, singular, plural, precision) {
@@ -152,16 +152,16 @@ export function cramNumber(num) {
152
152
  return `${_significance(num / BILLION)}B`;
153
153
  if (abs >= MILLION)
154
154
  return `${_significance(num / MILLION)}M`;
155
- if (abs >= 10000)
156
- return `${_significance(num / 1000)}K`;
155
+ if (abs >= TEN_THOUSAND)
156
+ return `${_significance(num / THOUSAND)}K`;
157
157
  return truncateNumber(num, 2).toString();
158
158
  }
159
159
  function _significance(num) {
160
160
  const digits = num >= 100 ? 0 : num >= 10 ? 1 : 2;
161
161
  return truncateNumber(num, digits).toFixed(digits);
162
162
  }
163
- /** Cram a number with a short suffix. */
164
- export const cramQuantity = (num, suffix) => `${cramNumber(num)}${suffix}`;
163
+ /** Cram a number with a short suffix, e.g. `1.02M kg` */
164
+ export const cramQuantity = (num, suffix) => `${cramNumber(num)}${NNBSP}${suffix}`;
165
165
  /** Cram a number with a longer full-word suffix. */
166
166
  export function cramFullQuantity(num, singular, plural) {
167
167
  const qty = cramNumber(num);
@@ -174,6 +174,8 @@ export function cramFullQuantity(num, singular, plural) {
174
174
  * @param denumerator The number representing the whole amount.
175
175
  */
176
176
  export const getPercent = (numerator, denumerator) => Math.max(0, Math.min(100, (100 / denumerator) * numerator));
177
+ /** Format a percentage (combines `getPercent()` and `formatQuantity()` for convenience). */
178
+ export const formatPercent = (numerator, denumerator, precision) => formatQuantity(getPercent(numerator, denumerator), "%", precision);
177
179
  /** Sum an iterable set of numbers and return the total. */
178
180
  export function sumNumbers(nums) {
179
181
  let sum = 0;