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/object.d.ts CHANGED
@@ -1,18 +1,18 @@
1
1
  import type { ImmutableArray } from "./array.js";
2
2
  /** Any readonly objet. */
3
- export declare type ImmutableObject<K extends PropertyKey = PropertyKey, T = unknown> = {
3
+ export type ImmutableObject<K extends PropertyKey = PropertyKey, T = unknown> = {
4
4
  readonly [KK in K]: T;
5
5
  };
6
6
  /** Any writable object. */
7
- export declare type MutableObject<K extends PropertyKey = PropertyKey, T = unknown> = {
7
+ export type MutableObject<K extends PropertyKey = PropertyKey, T = unknown> = {
8
8
  [KK in K]: T;
9
9
  };
10
10
  /** Prop for an object. */
11
- export declare type ObjectProp<T extends ImmutableObject = ImmutableObject> = readonly [keyof T, T[keyof T]];
11
+ export type ObjectProp<T extends ImmutableObject = ImmutableObject> = readonly [keyof T, T[keyof T]];
12
12
  /** Key for an object prop. */
13
- export declare type ObjectKey<T extends ImmutableObject = ImmutableObject> = keyof T;
13
+ export type ObjectKey<T extends ImmutableObject = ImmutableObject> = keyof T;
14
14
  /** Value for an object prop. */
15
- export declare type ObjectValue<T extends ImmutableObject = ImmutableObject> = T[keyof T];
15
+ export type ObjectValue<T extends ImmutableObject = ImmutableObject> = T[keyof T];
16
16
  /** Is an unknown value an unknown object? */
17
17
  export declare const isObject: <T extends ImmutableObject<PropertyKey, unknown>>(value: unknown) => value is T;
18
18
  /** Assert that a value is an object */
@@ -28,7 +28,7 @@ export declare const isProp: <T extends ImmutableObject<PropertyKey, unknown>>(o
28
28
  * - See https://github.com/microsoft/TypeScript/issues/24509
29
29
  * - Consistency with `Readonly<T>`
30
30
  */
31
- export declare type Mutable<T> = {
31
+ export type Mutable<T> = {
32
32
  -readonly [K in keyof T]: T[K];
33
33
  };
34
34
  /**
@@ -36,7 +36,7 @@ export declare type Mutable<T> = {
36
36
  * - Any value that extends `UnknownObject` has its props made partial.
37
37
  * - Works deeply on nested objects too.
38
38
  */
39
- export declare type DeepPartial<T> = {
39
+ export type DeepPartial<T> = {
40
40
  [K in keyof T]?: DeepPartial<T[K]>;
41
41
  };
42
42
  /**
@@ -44,7 +44,7 @@ export declare type DeepPartial<T> = {
44
44
  * - Any value that extends `UnknownObject` has its props made mutable.
45
45
  * - Works deeply on nested objects too.
46
46
  */
47
- export declare type DeepMutable<T> = {
47
+ export type DeepMutable<T> = {
48
48
  -readonly [K in keyof T]: DeepMutable<T[K]>;
49
49
  };
50
50
  /**
@@ -52,15 +52,15 @@ export declare type DeepMutable<T> = {
52
52
  * - Any value that extends `UnknownObject` has its props made readonly.
53
53
  * - Works deeply on nested objects too.
54
54
  */
55
- export declare type DeepReadonly<T> = {
55
+ export type DeepReadonly<T> = {
56
56
  +readonly [K in keyof T]: DeepReadonly<T[K]>;
57
57
  };
58
58
  /** Pick only the properties of an object that match a type. */
59
- export declare type PickProps<T, TT> = Pick<T, {
59
+ export type PickProps<T, TT> = Pick<T, {
60
60
  [K in keyof T]: T[K] extends TT ? K : never;
61
61
  }[keyof T]>;
62
62
  /** Omit the properties of an object that match a type. */
63
- export declare type OmitProps<T, TT> = Omit<T, {
63
+ export type OmitProps<T, TT> = Omit<T, {
64
64
  [K in keyof T]: T[K] extends TT ? K : never;
65
65
  }[keyof T]>;
66
66
  /** Get the props of an object as a set of entries. */
@@ -84,6 +84,7 @@ export declare function getProp<T extends ImmutableObject, K1 extends keyof T>(o
84
84
  /** Set a prop on an object (immutably) and return a new object including that prop. */
85
85
  export declare function withProp<T extends ImmutableObject, K extends keyof T>(input: T, key: K, value: T[K]): T;
86
86
  /** Set several props on an object (immutably) and return a new object including those props. */
87
+ export declare function withProps<T>(input: T, props: Partial<T>): T;
87
88
  export declare function withProps<T extends ImmutableObject>(input: T, props: T | Partial<T> | Iterable<ObjectProp<T>>): T;
88
89
  /** Remove several props from an object (immutably) and return a new object without those props. */
89
90
  export declare function omitProps<T extends ImmutableObject, K extends keyof T>(input: T, ...keys: K[]): Omit<T, K>;
@@ -95,3 +96,15 @@ export declare function setProp<T extends MutableObject, K extends keyof T>(obj:
95
96
  export declare function setProps<T extends MutableObject>(obj: T, entries: T | Partial<T> | Iterable<ObjectProp<T>>): void;
96
97
  /** Remove several key/value entries from an object (by reference). */
97
98
  export declare function deleteProps<T extends MutableObject>(obj: T, ...keys: (keyof T)[]): void;
99
+ /**
100
+ * Format an unknown object as a string.
101
+ * - Use the custom `.toString()` function if it exists (don't use built in `Object.prototype.toString` because it's useless.
102
+ * - Use `.title` or `.name` or `.id` if they exist and are strings.
103
+ * - Use `Object` otherwise.
104
+ */
105
+ export declare function formatObject(obj: ImmutableObject): string;
106
+ /**
107
+ * Get the prototype of an object instance.
108
+ * - Recommend to use this because Typescript's default lib specifies `Object.getPrototypeOf()` returning `any`.
109
+ */
110
+ export declare function getPrototype<T>(obj: T): Partial<T> | null;
package/util/object.js CHANGED
@@ -10,7 +10,7 @@ export function assertObject(value) {
10
10
  /** is an unknown value an unknown plain object? */
11
11
  export function isPlainObject(value) {
12
12
  if (isObject(value)) {
13
- const proto = Object.getPrototypeOf(value);
13
+ const proto = getPrototype(value);
14
14
  return proto === null || proto === Object.prototype;
15
15
  }
16
16
  return false;
@@ -30,13 +30,12 @@ export function getProp(data, k1, k2, k3, k4) {
30
30
  }
31
31
  /** Set a prop on an object (immutably) and return a new object including that prop. */
32
32
  export function withProp(input, key, value) {
33
- return input[key] === value ? input : { ...input, [key]: value };
33
+ return input[key] === value ? input : { __proto__: getPrototype(input), ...input, [key]: value };
34
34
  }
35
- /** Set several props on an object (immutably) and return a new object including those props. */
36
35
  export function withProps(input, props) {
37
36
  for (const [k, v] of getProps(props))
38
37
  if (input[k] !== v)
39
- return { ...input, ...props };
38
+ return { __proto__: getPrototype(input), ...input, ...props };
40
39
  return input;
41
40
  }
42
41
  export function omitProps(input, ...keys) {
@@ -69,3 +68,30 @@ export function deleteProps(obj, ...keys) {
69
68
  for (const key of keys)
70
69
  delete obj[key];
71
70
  }
71
+ /**
72
+ * Format an unknown object as a string.
73
+ * - Use the custom `.toString()` function if it exists (don't use built in `Object.prototype.toString` because it's useless.
74
+ * - Use `.title` or `.name` or `.id` if they exist and are strings.
75
+ * - Use `Object` otherwise.
76
+ */
77
+ export function formatObject(obj) {
78
+ if (typeof obj.toString === "function" && obj.toString !== Object.prototype.toString)
79
+ return obj.toString();
80
+ const name = obj.name;
81
+ if (typeof name === "string")
82
+ return name;
83
+ const title = obj.title;
84
+ if (typeof title === "string")
85
+ return title;
86
+ const id = obj.id;
87
+ if (typeof id === "string")
88
+ return id;
89
+ return "Object";
90
+ }
91
+ /**
92
+ * Get the prototype of an object instance.
93
+ * - Recommend to use this because Typescript's default lib specifies `Object.getPrototypeOf()` returning `any`.
94
+ */
95
+ export function getPrototype(obj) {
96
+ return Object.getPrototypeOf(obj);
97
+ }
package/util/regexp.d.ts CHANGED
@@ -5,7 +5,7 @@ export declare const ALWAYS_REGEXP: RegExp;
5
5
  /** Regular expression that never matches anything. */
6
6
  export declare const NEVER_REGEXP: RegExp;
7
7
  /** Things that can be convert to a regular expression. */
8
- export declare type PossibleRegExp = string | RegExp;
8
+ export type PossibleRegExp = string | RegExp;
9
9
  /** Is an unknown value a `RegExp` instance? */
10
10
  export declare const isRegExp: <T extends RegExp>(v: unknown) => v is T;
11
11
  /** Assert that an unknown value is a `RegExp` instance. */
@@ -17,12 +17,11 @@ export declare const getRegExpSource: (regexp: PossibleRegExp) => string;
17
17
  /** Escape special characters in a string regular expression. */
18
18
  export declare const escapeRegExp: (pattern: string) => string;
19
19
  /** Set of named match groups from a regular expression. */
20
- export declare type NamedRegExpData = {
20
+ export type NamedRegExpData = {
21
21
  [named: string]: string;
22
22
  };
23
23
  /** Regular expression match array that you've asserted contains the specified named groups. */
24
24
  export interface NamedRegExpArray<T extends NamedRegExpData = NamedRegExpData> extends RegExpExecArray {
25
- 0: string;
26
25
  groups: T;
27
26
  }
28
27
  /** Regular expression that you've asserted contains the specified named capture groups. */
package/util/serialise.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { AssertionError } from "../error/AssertionError.js";
2
2
  import { isArray } from "./array.js";
3
- import { isObject } from "./object.js";
3
+ import { getPrototype, isObject } from "./object.js";
4
4
  const R_QUOTE = /"/g;
5
5
  /**
6
6
  * Custom JSON.stringify()
@@ -31,7 +31,7 @@ export function serialise(value) {
31
31
  if (isArray(value))
32
32
  return `[${value.map(serialise).join(",")}]`;
33
33
  if (isObject(value)) {
34
- const prototype = Object.getPrototypeOf(value);
34
+ const prototype = getPrototype(value);
35
35
  const type = prototype !== Object.prototype && prototype !== null ? (_a = prototype === null || prototype === void 0 ? void 0 : prototype.constructor) === null || _a === void 0 ? void 0 : _a.name : undefined;
36
36
  // Use custom `toString()` function if it's defined.
37
37
  if (type && value.toString !== Object.prototype.toString)
package/util/set.d.ts CHANGED
@@ -1,11 +1,11 @@
1
1
  /** `Set` that cannot be changed. */
2
- export declare type ImmutableSet<T = unknown> = ReadonlySet<T>;
2
+ export type ImmutableSet<T = unknown> = ReadonlySet<T>;
3
3
  /** `Set` that can be changed. */
4
- export declare type MutableSet<T = unknown> = Set<T>;
4
+ export type MutableSet<T = unknown> = Set<T>;
5
5
  /** Things that can be converted to sets. */
6
- export declare type PossibleSet<T> = ImmutableSet<T> | Iterable<T>;
6
+ export type PossibleSet<T> = ImmutableSet<T> | Iterable<T>;
7
7
  /** Get the type of the _items_ in a set. */
8
- export declare type SetItem<X> = X extends ReadonlySet<infer Y> ? Y : never;
8
+ export type SetItem<X> = X extends ReadonlySet<infer Y> ? Y : never;
9
9
  /** Is an unknown value a set? */
10
10
  export declare const isSet: <T extends ImmutableSet<unknown>>(v: unknown) => v is T;
11
11
  /** Is an unknown value an item in a set? */
package/util/sort.d.ts CHANGED
@@ -4,9 +4,9 @@ export interface Rankable<T> {
4
4
  rank(left: T, right: T): number;
5
5
  }
6
6
  /** Function that can rank two values. */
7
- export declare type Rank<T> = (left: T, right: T) => number;
7
+ export type Rank<T> = (left: T, right: T) => number;
8
8
  /** Something that can rank two values. */
9
- export declare type Ranker<T> = Rankable<T> | Rank<T>;
9
+ export type Ranker<T> = Rankable<T> | Rank<T>;
10
10
  /** Rank two values with a `Ranker`. */
11
11
  export declare function rank<T>(left: T, ranker: Ranker<T>, right: T): number;
12
12
  /**
package/util/source.js CHANGED
@@ -1,10 +1,10 @@
1
1
  import { AssertionError } from "../error/AssertionError.js";
2
- import { isData } from "./data.js";
2
+ import { isObject } from "./object.js";
3
3
  /**
4
4
  * Recurse through `Sourceable` objects and return the first one that is an instance of `type`, or `null` if no source object matches.
5
5
  */
6
6
  export function getOptionalSource(type, value) {
7
- if (isData(value)) {
7
+ if (isObject(value)) {
8
8
  if (value instanceof type)
9
9
  return value;
10
10
  if ("source" in value)
package/util/string.d.ts CHANGED
@@ -5,7 +5,7 @@ import { ImmutableArray } from "./array.js";
5
5
  * - Using `Iterable<string> & NotString` allows an iterable containing strings but not `string` itself.
6
6
  * - This helps catch this category of subtle errors.
7
7
  */
8
- export declare type NotString = {
8
+ export type NotString = {
9
9
  toUpperCase?: never;
10
10
  toLowerCase?: never;
11
11
  };
package/util/string.js CHANGED
@@ -1,7 +1,7 @@
1
1
  /* eslint-disable no-control-regex */
2
2
  import { AssertionError } from "../error/AssertionError.js";
3
3
  import { formatDate, isDate } from "./date.js";
4
- import { formatData, isData } from "./data.js";
4
+ import { formatObject, isObject } from "./object.js";
5
5
  import { getArray, isArray } from "./array.js";
6
6
  import { formatNumber, isBetween } from "./number.js";
7
7
  /** Is a value a string? */
@@ -41,8 +41,8 @@ export function getString(value) {
41
41
  return formatDate(value);
42
42
  if (isArray(value))
43
43
  return value.map(getString).join(", ");
44
- if (isData(value))
45
- return formatData(value);
44
+ if (isObject(value))
45
+ return formatObject(value);
46
46
  return "Unknown";
47
47
  }
48
48
  /** Concatenate an iterable set of strings together. */
@@ -1,9 +1,9 @@
1
1
  import type { NotString } from "./string.js";
2
2
  import type { ImmutableDictionary } from "./dictionary.js";
3
3
  /** Template values in `{ placeholder: value }` format. */
4
- declare type TemplateValues = ImmutableDictionary<string>;
4
+ type TemplateValues = ImmutableDictionary<string>;
5
5
  /** Things that can be converted to the value for a named placeholder. */
6
- declare type PlaceholderValues = string | ((name: string) => string) | string[] | TemplateValues;
6
+ type PlaceholderValues = string | ((name: string) => string) | string[] | TemplateValues;
7
7
  /**
8
8
  * Get list of placeholders named in a template string.
9
9
  *
package/util/template.js CHANGED
@@ -1,12 +1,12 @@
1
1
  import { isObject } from "./object.js";
2
+ import { setMapItem } from "./map.js";
3
+ import { EMPTY_DATA } from "./data.js";
2
4
  // RegExp to find named variables in several formats e.g. `:a`, `${b}`, `{{c}}` or `{d}`
3
5
  const R_PLACEHOLDERS = /(\*|:[a-z][a-z0-9]*|\$\{[a-z][a-z0-9]*\}|\{\{[a-z][a-z0-9]*\}\}|\{[a-z][a-z0-9]*\})/i;
4
6
  // Find actual name within template placeholder e.g. `${name}` → `name`
5
7
  const R_NAME = /[a-z0-9]+/i;
6
- // Empty template.
7
- const EMPTY_TEMPLATE = Object.create(null);
8
8
  // Cache of templates.
9
- const TEMPLATE_CACHE = Object.create(null);
9
+ const TEMPLATE_CACHE = new Map();
10
10
  /**
11
11
  * Split up a template into an array of separator → placeholder → separator → placeholder → separator
12
12
  * - Odd numbered chunks are separators.
@@ -15,7 +15,7 @@ const TEMPLATE_CACHE = Object.create(null);
15
15
  * @param template The template including template placeholders, e.g. `:name-${country}/{city}`
16
16
  * @returns Array of strings alternating separator and placeholder.
17
17
  */
18
- const splitTemplate = (template) => (TEMPLATE_CACHE[template] || (TEMPLATE_CACHE[template] = _split(template)));
18
+ const _splitTemplate = (template) => TEMPLATE_CACHE.get(template) || setMapItem(TEMPLATE_CACHE, template, _split(template));
19
19
  const _split = (template) => {
20
20
  var _a;
21
21
  const matches = template.split(R_PLACEHOLDERS);
@@ -38,7 +38,7 @@ const _split = (template) => {
38
38
  * @param template The template including template placeholders, e.g. `:name-${country}/{city}`
39
39
  * @returns Array of clean string names of found placeholders, e.g. `["name", "country", "city"]`
40
40
  */
41
- export const getPlaceholders = (template) => splitTemplate(template).map(_getPlaceholder);
41
+ export const getPlaceholders = (template) => _splitTemplate(template).map(_getPlaceholder);
42
42
  const _getPlaceholder = ({ name }) => name;
43
43
  /**
44
44
  * Match a template against a target string.
@@ -51,17 +51,17 @@ const _getPlaceholder = ({ name }) => name;
51
51
  */
52
52
  export function matchTemplate(template, target) {
53
53
  // Get separators and placeholders from template.
54
- const chunks = splitTemplate(template);
54
+ const chunks = _splitTemplate(template);
55
55
  const firstChunk = chunks[0];
56
56
  // Return early if empty.
57
57
  if (!firstChunk)
58
- return template === target ? EMPTY_TEMPLATE : undefined;
58
+ return template === target ? EMPTY_DATA : undefined;
59
59
  // Check first separator.
60
60
  if (!target.startsWith(firstChunk.pre))
61
61
  return undefined; // target doesn't match template
62
62
  // Loop through the placeholders (placeholders are at all the even-numbered positions in `chunks`).
63
63
  let startIndex = firstChunk.pre.length;
64
- const values = Object.create(null);
64
+ const values = {};
65
65
  for (const { name, post } of chunks) {
66
66
  const stopIndex = !post ? Infinity : target.indexOf(post, startIndex);
67
67
  if (stopIndex < 0)
@@ -96,7 +96,7 @@ export function matchTemplates(templates, target) {
96
96
  * @throws {ReferenceError} If a placeholder in the template string is not specified in values.
97
97
  */
98
98
  export const renderTemplate = (template, value) => {
99
- const chunks = splitTemplate(template);
99
+ const chunks = _splitTemplate(template);
100
100
  if (!chunks.length)
101
101
  return template;
102
102
  let output = template;
package/util/time.d.ts CHANGED
@@ -33,9 +33,9 @@ export declare class Time {
33
33
  /** Regular expression that matches a time in ISO 8601 format. */
34
34
  export declare const TIME_REGEXP: RegExp;
35
35
  /** Things that converted to times. */
36
- export declare type PossibleTime = Time | Date | number | string;
36
+ export type PossibleTime = Time | Date | number | string;
37
37
  /** Things that converted to times or `null` */
38
- export declare type PossibleOptionalTime = Time | Date | number | string | null;
38
+ export type PossibleOptionalTime = Time | Date | number | string | null;
39
39
  /** Is an unknown value a `Time` instance. */
40
40
  export declare const isTime: (v: Time | unknown) => v is Time;
41
41
  /**
package/util/time.js CHANGED
@@ -4,9 +4,6 @@ import { getOptionalDate } from "./date.js";
4
4
  import { wrapNumber } from "./number.js";
5
5
  /** Class representing a time in the day in 24 hour format in the user's current locale. */
6
6
  export class Time {
7
- constructor(time) {
8
- this.time = wrapNumber(Math.round(time), 0, DAY);
9
- }
10
7
  /** Make a new `Time` instance from a date (or any value that can be converted to a date). */
11
8
  static fromDate(possible) {
12
9
  const date = getOptionalDate(possible);
@@ -20,6 +17,9 @@ export class Time {
20
17
  const [, h, m, s, ms] = matches;
21
18
  return new Time(parseInt(h, 10) * HOUR + parseInt(m, 10) * MINUTE + (typeof s === "string" ? parseInt(s, 10) * SECOND : 0) + (typeof ms === "string" ? parseInt(ms, 10) : 0));
22
19
  }
20
+ constructor(time) {
21
+ this.time = wrapNumber(Math.round(time), 0, DAY);
22
+ }
23
23
  /** Get the number of hours in this time. */
24
24
  get h() {
25
25
  return Math.trunc(this.time / HOUR);
@@ -13,13 +13,13 @@ export interface AsyncTransformable<I, O> {
13
13
  /** Is an unknown value a transformable. */
14
14
  export declare const isTransformable: <T extends Transformable<unknown, unknown>>(v: unknown) => v is T;
15
15
  /** Function that can transform an input value into an output value. */
16
- export declare type Transform<I, O> = (input: I) => O;
16
+ export type Transform<I, O> = (input: I) => O;
17
17
  /** Function that can transform an input value into an output value. */
18
- export declare type AsyncTransform<I, O> = (input: I) => O | PromiseLike<O>;
18
+ export type AsyncTransform<I, O> = (input: I) => O | PromiseLike<O>;
19
19
  /** Something that can transform an input value into an output value (or a plain value). */
20
- export declare type Transformer<I, O> = Transformable<I, O> | Transform<I, O> | O;
20
+ export type Transformer<I, O> = Transformable<I, O> | Transform<I, O> | O;
21
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;
22
+ export type AsyncTransformer<I, O> = AsyncTransformable<I, O> | AsyncTransform<I, O> | O;
23
23
  /** Transform a value using a transformer. */
24
24
  export declare function transform<I, O>(input: I, transformer: (v: I) => O): O;
25
25
  export declare function transform<I, O>(input: I, transformer: (v: I) => O | PromiseLike<O>): O | PromiseLike<O>;
@@ -38,7 +38,7 @@ export declare const mapDictionary: <I, O>(dictionary: ImmutableDictionary<I>, t
38
38
  /** Modify the values of a set of entries using a transformer. */
39
39
  export declare function mapEntries<K, I, O>(entries: Iterable<Entry<K, I>>, transformer: Transformer<I, O>): Iterable<Entry<K, O>>;
40
40
  /** Set of named transformers for a data object (or `undefined` to skip the transform). */
41
- export declare type Transformers<T extends ImmutableObject> = {
41
+ export type Transformers<T extends ImmutableObject> = {
42
42
  readonly [K in keyof T]?: Transformer<T[K], T[K]> | undefined;
43
43
  };
44
44
  /** Transform an object using a set of named transformers. */
package/util/units.d.ts CHANGED
@@ -1,13 +1,12 @@
1
1
  import { ImmutableObject } from "./object.js";
2
- import { PossibleDate } from "./date.js";
3
- import { MapKey, ImmutableRequiredMap } from "./map.js";
4
- /** Conversion from one unit to another (either a number to multiple by, or a function to convert). */
5
- declare type Conversion = number | ((num: number) => number);
2
+ import { MapKey, ImmutableMap } from "./map.js";
3
+ /** Conversion from one unit to another (either an amount to multiple by, or a function to convert). */
4
+ type Conversion = number | ((num: number) => number);
6
5
  /** Set of possible conversions for a set of items. */
7
- declare type Conversions<T extends string> = {
6
+ type Conversions<T extends string> = {
8
7
  readonly [K in T]?: Conversion;
9
8
  };
10
- declare type UnitProps<T extends string> = {
9
+ type UnitProps<T extends string> = {
11
10
  /** Short abbreviation for this unit, e.g. `km` (defaults to first letter of `id`). */
12
11
  readonly abbr?: string;
13
12
  /** Singular name for this unit, e.g. `kilometer` (defaults to `id` + "s"). */
@@ -20,12 +19,12 @@ declare type UnitProps<T extends string> = {
20
19
  readonly to?: Conversions<T>;
21
20
  };
22
21
  /** Represent a unit. */
23
- export declare class Unit<T extends string> {
22
+ export declare class Unit<K extends string> {
24
23
  /** `UnitList` this unit belongs to. */
25
- readonly list: UnitList<T>;
24
+ readonly list: UnitList<K>;
26
25
  private readonly _to;
27
- /** Identifier for this unit, e.g. `kilometer` */
28
- readonly id: T;
26
+ /** String key for this unit, e.g. `kilometer` */
27
+ readonly key: K;
29
28
  /** Short abbreviation for this unit, e.g. `km` (defaults to first letter of `id`). */
30
29
  readonly abbr: string;
31
30
  /** Singular name for this unit, e.g. `kilometer` (defaults to `id`). */
@@ -38,73 +37,63 @@ export declare class Unit<T extends string> {
38
37
  get title(): string;
39
38
  constructor(
40
39
  /** `UnitList` this unit belongs to. */
41
- list: UnitList<T>,
42
- /** Key for this unit, e.g. `kilometer` */
43
- id: T,
40
+ list: UnitList<K>,
41
+ /** String key for this unit, e.g. `kilometer` */
42
+ key: K,
44
43
  /** Props to configure this unit. */
45
- { abbr, singular, plural, precision, to }: UnitProps<T>);
44
+ { abbr, singular, plural, precision, to }: UnitProps<K>);
46
45
  /** Convert an amount from this unit to another unit. */
47
- to(amount: number, id?: T | Unit<T>): number;
46
+ to(amount: number, unit?: K | Unit<K>): number;
48
47
  /** Convert an amount from another unit to this unit. */
49
- from(amount: number, id?: T | Unit<T>): number;
48
+ from(amount: number, unit?: K | Unit<K>): number;
50
49
  /** Convert an amount from this unit to another unit (must specify another `Unit` instance). */
51
50
  private _toUnit;
52
- /** Format a number with a given unit of measure, e.g. `12 kg` or `29.5 l` */
51
+ /** Format an amount with a given unit of measure, e.g. `12 kg` or `29.5 l` */
53
52
  format(amount: number, precision?: number | null): string;
54
- /** Format a number with a given unit of measure, e.g. `12 kilograms` or `29.5 liters` or `1 degree` */
53
+ /** Format an amount with a given unit of measure, e.g. `12 kilograms` or `29.5 liters` or `1 degree` */
55
54
  formatFull(amount: number, precision?: number | null): string;
55
+ /** Cram an amount with a given unit of measure, e.g. `1.25M mi` */
56
+ cram(amount: number): string;
56
57
  }
57
- /** Represent a list of units. */
58
- export declare class UnitList<T extends string> extends ImmutableRequiredMap<T, Unit<T>> {
59
- readonly base: Unit<T>;
60
- constructor(units: ImmutableObject<T, UnitProps<T>>);
58
+ /**
59
+ * Represent a list of units.
60
+ * - Has a known base unit at `.base`
61
+ * - Cannot have additional units added after it is created.
62
+ */
63
+ export declare class UnitList<K extends string> extends ImmutableMap<K, Unit<K>> {
64
+ readonly base: Unit<K>;
65
+ constructor(units: ImmutableObject<K, UnitProps<K>>);
66
+ /** Convert an amount from a unit to another unit. */
67
+ convert(amount: number, sourceUnit: K | Unit<K>, targetUnit: K | Unit<K>): number;
61
68
  }
62
69
  /** Percentage units. */
63
70
  export declare const PERCENTAGE_UNITS: UnitList<"percent">;
64
- export declare type PercentageUnitIdentifier = MapKey<typeof PERCENTAGE_UNITS>;
71
+ export type PercentageUnitKey = MapKey<typeof PERCENTAGE_UNITS>;
65
72
  /** Point units. */
66
73
  export declare const POINT_UNITS: UnitList<"basis-point" | "percentage-point">;
67
- export declare type PointUnitIdentifier = MapKey<typeof POINT_UNITS>;
74
+ export type PointUnitKey = MapKey<typeof POINT_UNITS>;
68
75
  /** Angle units. */
69
76
  export declare const ANGLE_UNITS: UnitList<"degree" | "radian" | "gradian">;
70
- export declare type AngleUnitIdentifier = MapKey<typeof ANGLE_UNITS>;
77
+ export type AngleUnitKey = MapKey<typeof ANGLE_UNITS>;
71
78
  /** Mass units. */
72
79
  export declare const MASS_UNITS: UnitList<"milligram" | "gram" | "kilogram" | "ounce" | "pound" | "stone">;
73
- export declare type MassUnitIdentifier = MapKey<typeof MASS_UNITS>;
80
+ export type MassUnitKey = MapKey<typeof MASS_UNITS>;
74
81
  /** Time units. */
75
82
  export declare const TIME_UNITS: UnitList<"millisecond" | "second" | "minute" | "hour" | "day" | "week" | "month" | "year">;
76
- export declare type TimeUnitIdentifier = MapKey<typeof TIME_UNITS>;
83
+ export type TimeUnitKey = MapKey<typeof TIME_UNITS>;
77
84
  /** Length units. */
78
85
  export declare const LENGTH_UNITS: UnitList<"millimeter" | "centimeter" | "meter" | "kilometer" | "inch" | "foot" | "yard" | "furlong" | "mile">;
79
- export declare type LengthUnitIdentifier = MapKey<typeof LENGTH_UNITS>;
86
+ export type LengthUnitKey = MapKey<typeof LENGTH_UNITS>;
80
87
  /** Speed units. */
81
88
  export declare const SPEED_UNITS: UnitList<"meter-per-second" | "kilometer-per-hour" | "mile-per-hour">;
82
- export declare type SpeedUnitIdentifier = MapKey<typeof SPEED_UNITS>;
89
+ export type SpeedUnitKey = MapKey<typeof SPEED_UNITS>;
83
90
  /** Area units. */
84
91
  export declare const AREA_UNITS: UnitList<"square-millimeter" | "square-centimeter" | "square-meter" | "square-kilometer" | "hectare" | "square-inch" | "square-foot" | "square-yard" | "acre">;
85
- export declare type AreaUnitIdentifier = MapKey<typeof AREA_UNITS>;
92
+ export type AreaUnitKey = MapKey<typeof AREA_UNITS>;
86
93
  /** Volume units. */
87
94
  export declare const VOLUME_UNITS: UnitList<"milliliter" | "liter" | "cubic-centimeter" | "cubic-meter" | "us-fluid-ounce" | "us-pint" | "us-quart" | "us-gallon" | "imperial-fluid-ounce" | "imperial-pint" | "imperial-quart" | "imperial-gallon" | "cubic-inch" | "cubic-foot" | "cubic-yard">;
88
- export declare type VolumeUnitIdentifier = MapKey<typeof VOLUME_UNITS>;
95
+ export type VolumeUnitKey = MapKey<typeof VOLUME_UNITS>;
89
96
  /** Temperature units. */
90
97
  export declare const TEMPERATURE_UNITS: UnitList<"celsius" | "fahrenheit" | "kelvin">;
91
- export declare type TemperatureUnitIdentifier = MapKey<typeof TEMPERATURE_UNITS>;
92
- /** Format a percentage (combines `getPercent()` and `formatUnits()` for convenience). */
93
- export declare const formatPercent: (numerator: number, denumerator: number, precision?: number) => string;
94
- /** 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`. */
95
- export declare function formatFullDuration(ms: number, precision?: number): string;
96
- /** Format a description of a duration of time using the most reasonable units e.g. `5y` or `4m` or `12ms`. */
97
- export declare function formatDuration(ms: number, precision?: number): string;
98
- /** Full when a date happens/happened, e.g. `in 10 days` or `2 hours ago` */
99
- export declare const formatFullWhen: (target: PossibleDate, current?: PossibleDate) => string;
100
- /** Compact when a date happens/happened, e.g. `in 10d` or `2h ago` or `in 1w` */
101
- export declare const formatWhen: (target: PossibleDate, current?: PossibleDate) => string;
102
- /** Full when a date happens, e.g. `10 days` or `2 hours` or `-1 week` */
103
- export declare const formatFullUntil: (target: PossibleDate, current?: PossibleDate) => string;
104
- /** Compact when a date happens, e.g. `10d` or `2h` or `-1w` */
105
- export declare const formatUntil: (target: PossibleDate, current?: PossibleDate) => string;
106
- /** Full when a date happened, e.g. `10 days` or `2 hours` or `-1 week` */
107
- export declare const formatFullAgo: (target: PossibleDate, current?: PossibleDate) => string;
108
- /** Compact when a date will happen, e.g. `10d` or `2h` or `-1w` */
109
- export declare const formatAgo: (target: PossibleDate, current?: PossibleDate) => string;
98
+ export type TemperatureUnitKey = MapKey<typeof TEMPERATURE_UNITS>;
110
99
  export {};