@oscarpalmer/atoms 0.193.1 → 0.195.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/dist/array/difference.mjs +2 -2
- package/dist/array/index.d.mts +2 -2
- package/dist/array/index.mjs +2 -2
- package/dist/array/intersection.mjs +2 -2
- package/dist/array/move.mjs +1 -1
- package/dist/array/slice.mjs +5 -5
- package/dist/array/sort.d.mts +5 -1
- package/dist/array/sort.mjs +4 -2
- package/dist/array/swap.mjs +1 -1
- package/dist/array/union.mjs +2 -2
- package/dist/beacon.d.mts +8 -1
- package/dist/beacon.mjs +52 -60
- package/dist/color/constants.d.mts +1 -1
- package/dist/color/constants.mjs +3 -5
- package/dist/color/instance.mjs +34 -41
- package/dist/color/misc/format.d.mts +3 -2
- package/dist/color/misc/format.mjs +4 -1
- package/dist/color/misc/is.d.mts +9 -1
- package/dist/color/misc/is.mjs +11 -1
- package/dist/color/misc/state.d.mts +6 -6
- package/dist/color/misc/state.mjs +11 -14
- package/dist/color/models.d.mts +23 -68
- package/dist/color/space/hex.mjs +1 -1
- package/dist/color/space/rgb.mjs +1 -1
- package/dist/function/index.d.mts +1 -2
- package/dist/function/index.mjs +1 -2
- package/dist/function/limit.d.mts +0 -6
- package/dist/function/limit.mjs +2 -2
- package/dist/function/once.d.mts +0 -3
- package/dist/function/once.mjs +17 -14
- package/dist/function/retry.d.mts +1 -24
- package/dist/function/retry.mjs +1 -1
- package/dist/herald.d.mts +2 -72
- package/dist/herald.mjs +2 -92
- package/dist/index.d.mts +3332 -3418
- package/dist/index.mjs +1850 -1870
- package/dist/internal/abort.d.mts +10 -0
- package/dist/internal/abort.mjs +14 -0
- package/dist/internal/array/chunk.mjs +2 -2
- package/dist/internal/array/find.mjs +2 -2
- package/dist/{array → internal/array}/get.d.mts +2 -2
- package/dist/{array → internal/array}/get.mjs +2 -2
- package/dist/{array → internal/array}/match.d.mts +2 -2
- package/dist/{array → internal/array}/match.mjs +15 -15
- package/dist/internal/array/sets.d.mts +4 -4
- package/dist/internal/array/sets.mjs +7 -7
- package/dist/internal/defaults.d.mts +5 -0
- package/dist/internal/defaults.mjs +9 -0
- package/dist/{function → internal/function}/assert.d.mts +2 -2
- package/dist/{function → internal/function}/assert.mjs +4 -4
- package/dist/{function → internal/function}/memoize.d.mts +2 -2
- package/dist/{function → internal/function}/memoize.mjs +22 -35
- package/dist/internal/function/timer.mjs +19 -15
- package/dist/{function → internal/function}/work.d.mts +2 -2
- package/dist/{function → internal/function}/work.mjs +15 -13
- package/dist/internal/herald.d.mts +71 -0
- package/dist/internal/herald.mjs +110 -0
- package/dist/internal/number.d.mts +1 -2
- package/dist/internal/number.mjs +8 -11
- package/dist/internal/{result.d.mts → result/misc.d.mts} +42 -3
- package/dist/internal/result/misc.mjs +51 -0
- package/dist/{result → internal/result}/models.d.mts +2 -2
- package/dist/{sized → internal/sized}/map.d.mts +1 -1
- package/dist/{sized → internal/sized}/map.mjs +2 -2
- package/dist/internal/{sized.d.mts → sized/misc.d.mts} +1 -1
- package/dist/internal/sized/misc.mjs +12 -0
- package/dist/{string → internal/string}/case.d.mts +1 -1
- package/dist/{string → internal/string}/case.mjs +22 -22
- package/dist/internal/{string.d.mts → string/misc.d.mts} +1 -1
- package/dist/internal/{string.mjs → string/misc.mjs} +5 -5
- package/dist/internal/subscription.d.mts +24 -8
- package/dist/internal/subscription.mjs +49 -36
- package/dist/internal/value/compare.mjs +1 -1
- package/dist/internal/value/equal.mjs +6 -6
- package/dist/internal/value/has.d.mts +1 -1
- package/dist/internal/value/misc.d.mts +1 -1
- package/dist/internal/value/misc.mjs +16 -16
- package/dist/internal/value/set.mjs +2 -2
- package/dist/is.mjs +2 -2
- package/dist/logger.mjs +15 -39
- package/dist/promise/constants.d.mts +17 -0
- package/dist/promise/constants.mjs +14 -0
- package/dist/promise/delay.mjs +7 -10
- package/dist/promise/helpers.d.mts +1 -1
- package/dist/promise/helpers.mjs +3 -3
- package/dist/promise/index.d.mts +1 -1
- package/dist/promise/index.mjs +14 -17
- package/dist/promise/misc.d.mts +3 -2
- package/dist/promise/misc.mjs +10 -8
- package/dist/promise/models.d.mts +5 -17
- package/dist/promise/models.mjs +4 -13
- package/dist/promise/timed.mjs +9 -10
- package/dist/query.mjs +16 -16
- package/dist/queue.mjs +104 -120
- package/dist/random.mjs +8 -8
- package/dist/result/index.d.mts +1 -4
- package/dist/result/index.mjs +2 -2
- package/dist/result/match.d.mts +1 -4
- package/dist/result/match.mjs +5 -5
- package/dist/result/misc.d.mts +3 -42
- package/dist/result/misc.mjs +4 -30
- package/dist/result/work/flow.d.mts +1 -4
- package/dist/result/work/flow.mjs +6 -6
- package/dist/result/work/pipe.d.mts +1 -4
- package/dist/result/work/pipe.mjs +5 -5
- package/dist/sized/set.mjs +1 -1
- package/dist/string/fuzzy.mjs +25 -20
- package/dist/string/index.d.mts +1 -1
- package/dist/string/index.mjs +8 -8
- package/dist/string/match.mjs +1 -1
- package/dist/string/normalize.mjs +16 -16
- package/dist/string/template.mjs +3 -3
- package/dist/subscription.d.mts +2 -0
- package/dist/subscription.mjs +2 -0
- package/dist/value/clone.mjs +10 -10
- package/dist/value/diff.mjs +1 -1
- package/dist/value/smush.mjs +3 -3
- package/package.json +35 -14
- package/dist/internal/result.mjs +0 -25
- package/dist/internal/sized.mjs +0 -12
- /package/dist/{result → internal/result}/models.mjs +0 -0
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { isPlainObject } from "./is.mjs";
|
|
2
|
+
import { createSubscriptions, isSubscription } from "./subscription.mjs";
|
|
3
|
+
//#region src/internal/herald.ts
|
|
4
|
+
function createEvents(herald, state) {
|
|
5
|
+
const events = {};
|
|
6
|
+
Object.defineProperty(events, HERALD_PROPERTY, { value: HERALD_NAME_EVENTS });
|
|
7
|
+
for (const key of state.keys) events[key] = (callback, signal) => herald.subscribe(key, callback, signal);
|
|
8
|
+
return Object.freeze(events);
|
|
9
|
+
}
|
|
10
|
+
function emitForHerald(state, event, ...parameters) {
|
|
11
|
+
const items = state.subscriptions.state.values.from.keyed?.get(event);
|
|
12
|
+
if (items == null || items.size === 0) return;
|
|
13
|
+
for (const [callback] of items) callback(...parameters);
|
|
14
|
+
}
|
|
15
|
+
function getHeraldSubscriptionProperty(input) {
|
|
16
|
+
if (input == null) return heraldSubscription;
|
|
17
|
+
const property = isPlainObject(input) ? input : {};
|
|
18
|
+
if (typeof property.key !== "string" || property.value != null && typeof property.value !== "string") throw new Error(HERALD_MESSAGE_PROPERTY);
|
|
19
|
+
return {
|
|
20
|
+
key: property.key,
|
|
21
|
+
value: property.value
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
function getHeraldState(input) {
|
|
25
|
+
const options = isPlainObject(input) ? input : {};
|
|
26
|
+
if (!Array.isArray(options.names) || options.names.length === 0 || !options.names.every((name) => typeof name === "string")) throw new Error(HERALD_MESSAGE_ARRAY);
|
|
27
|
+
if (options.onCreate != null && typeof options.onCreate !== "function") throw new Error(HERALD_MESSAGE_ONCREATE);
|
|
28
|
+
const keys = new Set(options.names);
|
|
29
|
+
const property = getHeraldSubscriptionProperty(options.property);
|
|
30
|
+
return {
|
|
31
|
+
keys,
|
|
32
|
+
subscriptions: createSubscriptions({
|
|
33
|
+
keys,
|
|
34
|
+
property
|
|
35
|
+
}),
|
|
36
|
+
onCreate: options.onCreate
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Create a _Herald_ for announcing named events
|
|
41
|
+
*
|
|
42
|
+
* @param names Event names
|
|
43
|
+
* @param property Optional property for subscription identification _(defaults to `$herald`)_
|
|
44
|
+
* @returns _Herald_ instance
|
|
45
|
+
*/
|
|
46
|
+
function herald(options) {
|
|
47
|
+
const state = getHeraldState(options);
|
|
48
|
+
const instance = {
|
|
49
|
+
clear: () => state.subscriptions.clear(),
|
|
50
|
+
emit: (event, ...parameters) => emitForHerald(state, event, ...parameters),
|
|
51
|
+
observed: (event) => (state.subscriptions.state.items.keyed?.get(event)?.size ?? 0) > 0,
|
|
52
|
+
subscribe: (key, callback, signal) => subscribeToHerald(state, key, callback, signal)
|
|
53
|
+
};
|
|
54
|
+
Object.defineProperties(instance, {
|
|
55
|
+
[HERALD_PROPERTY]: { value: HERALD_NAME_HERALD },
|
|
56
|
+
events: {
|
|
57
|
+
enumerable: true,
|
|
58
|
+
value: createEvents(instance, state)
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
return Object.freeze(instance);
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Is the value a herald?
|
|
65
|
+
*
|
|
66
|
+
* @param value Value to check
|
|
67
|
+
* @returns `true` if the value is a herald, otherwise `false`
|
|
68
|
+
*/
|
|
69
|
+
function isHerald(value) {
|
|
70
|
+
return isHeraldInstance(HERALD_NAME_HERALD, value);
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Is the value events for a herald?
|
|
74
|
+
*
|
|
75
|
+
* @param value Value to check
|
|
76
|
+
* @returns `true` if the value is events for a herald, otherwise `false`
|
|
77
|
+
*/
|
|
78
|
+
function isHeraldEvents(value) {
|
|
79
|
+
return isHeraldInstance(HERALD_NAME_EVENTS, value);
|
|
80
|
+
}
|
|
81
|
+
function isHeraldInstance(name, value) {
|
|
82
|
+
return isPlainObject(value) && HERALD_PROPERTY in value && value[HERALD_PROPERTY] === name;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Is the value a herald subscription?
|
|
86
|
+
*
|
|
87
|
+
* @param value Value to check
|
|
88
|
+
* @returns `true` if the value is a herald subscription, otherwise `false`
|
|
89
|
+
*/
|
|
90
|
+
function isHeraldSubscription(value) {
|
|
91
|
+
return isSubscription(value) && value[HERALD_PROPERTY] === "subscription";
|
|
92
|
+
}
|
|
93
|
+
function subscribeToHerald(state, key, callback, signal) {
|
|
94
|
+
const [subscription, existing] = state.subscriptions.create({
|
|
95
|
+
key,
|
|
96
|
+
signal,
|
|
97
|
+
value: callback
|
|
98
|
+
});
|
|
99
|
+
if (!existing) state.onCreate?.(key, callback, subscription);
|
|
100
|
+
return subscription;
|
|
101
|
+
}
|
|
102
|
+
const HERALD_PROPERTY = "$herald";
|
|
103
|
+
const HERALD_MESSAGE_ARRAY = "Herald requires an array of event names.";
|
|
104
|
+
const HERALD_MESSAGE_ONCREATE = `Herald requires a valid onCreate callback for subscription creation`;
|
|
105
|
+
const HERALD_MESSAGE_PROPERTY = `Herald requires valid property information for subscription identification`;
|
|
106
|
+
const HERALD_NAME_EVENTS = "events";
|
|
107
|
+
const HERALD_NAME_HERALD = "herald";
|
|
108
|
+
const heraldSubscription = { key: HERALD_PROPERTY };
|
|
109
|
+
//#endregion
|
|
110
|
+
export { herald, isHerald, isHeraldEvents, isHeraldSubscription };
|
|
@@ -33,6 +33,5 @@ declare function clamp(value: number, minimum: number, maximum: number, loop?: b
|
|
|
33
33
|
* @returns Original value as a number, or `Number.NaN` if the value is unable to be parsed
|
|
34
34
|
*/
|
|
35
35
|
declare function getNumber(value: unknown): number;
|
|
36
|
-
declare function getNumberOrDefault(value: unknown, defaultValue: number, minimum?: number): number;
|
|
37
36
|
//#endregion
|
|
38
|
-
export { between, clamp, getNumber
|
|
37
|
+
export { between, clamp, getNumber };
|
package/dist/internal/number.mjs
CHANGED
|
@@ -59,17 +59,14 @@ function getNumber(value) {
|
|
|
59
59
|
if (typeof parsed !== "string") return getNumber(parsed);
|
|
60
60
|
const trimmed = parsed.trim();
|
|
61
61
|
if (trimmed.length === 0) return NaN;
|
|
62
|
-
if (
|
|
63
|
-
const isBinary =
|
|
64
|
-
if (isBinary ||
|
|
62
|
+
if (NUMBER_EXPRESSION_ZEROISH.test(parsed)) return 0;
|
|
63
|
+
const isBinary = NUMBER_EXPRESSION_BINARY.test(trimmed);
|
|
64
|
+
if (isBinary || NUMBER_EXPRESSION_OCTAL.test(trimmed)) return Number.parseInt(trimmed.slice(2), isBinary ? 2 : NUMBER_OCTAL_VALUE);
|
|
65
65
|
return Number(trimmed);
|
|
66
66
|
}
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
const
|
|
71
|
-
const EXPRESSION_OCTAL = /^0o[0-7]+$/i;
|
|
72
|
-
const EXPRESSION_ZEROISH = /^\s*0+\s*$/;
|
|
73
|
-
const OCTAL_VALUE = 8;
|
|
67
|
+
const NUMBER_EXPRESSION_BINARY = /^0b[01]+$/i;
|
|
68
|
+
const NUMBER_EXPRESSION_OCTAL = /^0o[0-7]+$/i;
|
|
69
|
+
const NUMBER_EXPRESSION_ZEROISH = /^\s*0+\s*$/;
|
|
70
|
+
const NUMBER_OCTAL_VALUE = 8;
|
|
74
71
|
//#endregion
|
|
75
|
-
export { between, clamp, getNumber
|
|
72
|
+
export { between, clamp, getNumber };
|
|
@@ -1,5 +1,21 @@
|
|
|
1
|
-
import { Err, ExtendedErr, Ok, Result } from "
|
|
2
|
-
//#region src/internal/result.d.ts
|
|
1
|
+
import { Err, ExtendedErr, Ok, Result } from "./models.mjs";
|
|
2
|
+
//#region src/internal/result/misc.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* Creates an extended error result
|
|
5
|
+
*
|
|
6
|
+
* @param value Error value
|
|
7
|
+
* @param original Original error
|
|
8
|
+
* @returns Error result
|
|
9
|
+
*/
|
|
10
|
+
declare function error<E>(value: E, original: Error): ExtendedErr<E>;
|
|
11
|
+
/**
|
|
12
|
+
* Creates an error result
|
|
13
|
+
*
|
|
14
|
+
* @param value Error value
|
|
15
|
+
* @returns Error result
|
|
16
|
+
*/
|
|
17
|
+
declare function error<E>(value: E): Err<E>;
|
|
18
|
+
declare function getError<E>(value: E, original?: Error): Err<E> | ExtendedErr<E>;
|
|
3
19
|
/**
|
|
4
20
|
* Is the _Result_ an extended error?
|
|
5
21
|
*
|
|
@@ -42,5 +58,28 @@ declare function isOk(value: unknown): value is Ok<unknown>;
|
|
|
42
58
|
* @returns `true` if the value is a _Result_, otherwise `false`
|
|
43
59
|
*/
|
|
44
60
|
declare function isResult(value: unknown): value is ExtendedErr<unknown> | Result<unknown, unknown>;
|
|
61
|
+
/**
|
|
62
|
+
* Creates an ok result
|
|
63
|
+
*
|
|
64
|
+
* @param value Value
|
|
65
|
+
* @returns Ok result
|
|
66
|
+
*/
|
|
67
|
+
declare function ok<Value>(value: Value): Ok<Value>;
|
|
68
|
+
/**
|
|
69
|
+
* Gets the value of an ok result _(or a default value)_
|
|
70
|
+
*
|
|
71
|
+
* @param value _Result_ to unwrap
|
|
72
|
+
* @param defaultValue Default value
|
|
73
|
+
* @returns Value of the _Result_ _(or the default value)_
|
|
74
|
+
*/
|
|
75
|
+
declare function unwrap<Value, E = Error>(value: Result<Value, E>, defaultValue: Value): Value;
|
|
76
|
+
/**
|
|
77
|
+
* Gets the value of an ok result _(or a default value)_
|
|
78
|
+
*
|
|
79
|
+
* @param value _Result_ to unwrap
|
|
80
|
+
* @param defaultValue Default value
|
|
81
|
+
* @returns Value of the _Result_ _(or the default value)_
|
|
82
|
+
*/
|
|
83
|
+
declare function unwrap(value: unknown, defaultValue: unknown): unknown;
|
|
45
84
|
//#endregion
|
|
46
|
-
export { isError, isOk, isResult };
|
|
85
|
+
export { error, getError, isError, isOk, isResult, ok, unwrap };
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { isNonPlainObject } from "../is.mjs";
|
|
2
|
+
//#region src/internal/result/misc.ts
|
|
3
|
+
function error(value, original) {
|
|
4
|
+
return getError(value, original);
|
|
5
|
+
}
|
|
6
|
+
function getError(value, original) {
|
|
7
|
+
const errorResult = {
|
|
8
|
+
error: value,
|
|
9
|
+
ok: false
|
|
10
|
+
};
|
|
11
|
+
if (original instanceof Error) errorResult.original = original;
|
|
12
|
+
return errorResult;
|
|
13
|
+
}
|
|
14
|
+
function isError(value, extended) {
|
|
15
|
+
return isResultValue(value, false) && (extended === true ? value.original instanceof Error : true);
|
|
16
|
+
}
|
|
17
|
+
function isOk(value) {
|
|
18
|
+
return isResultValue(value, true);
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Is the value a _Result_?
|
|
22
|
+
*
|
|
23
|
+
* @param value Value to check
|
|
24
|
+
* @returns `true` if the value is a _Result_, otherwise `false`
|
|
25
|
+
*/
|
|
26
|
+
function isResult(value) {
|
|
27
|
+
return isResultValue(value, true) || isResultValue(value, false);
|
|
28
|
+
}
|
|
29
|
+
function isResultValue(value, okValue) {
|
|
30
|
+
if (isNonPlainObject(value)) return false;
|
|
31
|
+
return value.ok === okValue && (okValue ? RESULT_PROPERTY_VALUE : RESULT_PROPERTY_ERROR) in value;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Creates an ok result
|
|
35
|
+
*
|
|
36
|
+
* @param value Value
|
|
37
|
+
* @returns Ok result
|
|
38
|
+
*/
|
|
39
|
+
function ok(value) {
|
|
40
|
+
return {
|
|
41
|
+
ok: true,
|
|
42
|
+
value
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
function unwrap(value, defaultValue) {
|
|
46
|
+
return isOk(value) ? value.value : defaultValue;
|
|
47
|
+
}
|
|
48
|
+
const RESULT_PROPERTY_ERROR = "error";
|
|
49
|
+
const RESULT_PROPERTY_VALUE = "value";
|
|
50
|
+
//#endregion
|
|
51
|
+
export { error, getError, isError, isOk, isResult, ok, unwrap };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { clamp } from "../number.mjs";
|
|
2
|
+
//#region src/internal/sized/misc.ts
|
|
3
|
+
function getSizedMaximum(first, second) {
|
|
4
|
+
let actual;
|
|
5
|
+
if (typeof first === "number") actual = first;
|
|
6
|
+
else actual = typeof second === "number" ? second : SIZED_MAXIMUM_DEFAULT;
|
|
7
|
+
return clamp(actual, 1, SIZED_MAXIMUM_ABSOLUTE);
|
|
8
|
+
}
|
|
9
|
+
const SIZED_MAXIMUM_ABSOLUTE = 16777216;
|
|
10
|
+
const SIZED_MAXIMUM_DEFAULT = 1048576;
|
|
11
|
+
//#endregion
|
|
12
|
+
export { getSizedMaximum };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { join, words } from "
|
|
1
|
+
import { join, words } from "./misc.mjs";
|
|
2
2
|
import { memoize } from "../function/memoize.mjs";
|
|
3
|
-
//#region src/string/case.ts
|
|
3
|
+
//#region src/internal/string/case.ts
|
|
4
4
|
/**
|
|
5
5
|
* Convert a string to camel case _(thisIsCamelCase)_
|
|
6
6
|
*
|
|
@@ -8,7 +8,7 @@ import { memoize } from "../function/memoize.mjs";
|
|
|
8
8
|
* @returns Camel-cased string
|
|
9
9
|
*/
|
|
10
10
|
function camelCase(value) {
|
|
11
|
-
return toCase(
|
|
11
|
+
return toCase(STRING_CASE_CAMEL, value, true, false);
|
|
12
12
|
}
|
|
13
13
|
/**
|
|
14
14
|
* Capitalize the first letter of a string _(and lowercase the rest)_
|
|
@@ -28,7 +28,7 @@ function capitalize(value) {
|
|
|
28
28
|
* @returns Kebab-cased string
|
|
29
29
|
*/
|
|
30
30
|
function kebabCase(value) {
|
|
31
|
-
return toCase(
|
|
31
|
+
return toCase(STRING_CASE_KEBAB, value, false, false);
|
|
32
32
|
}
|
|
33
33
|
/**
|
|
34
34
|
* Convert a string to lower case
|
|
@@ -48,7 +48,7 @@ function lowerCase(value) {
|
|
|
48
48
|
* @returns Pascal-cased string
|
|
49
49
|
*/
|
|
50
50
|
function pascalCase(value) {
|
|
51
|
-
return toCase(
|
|
51
|
+
return toCase(STRING_CASE_PASCAL, value, true, true);
|
|
52
52
|
}
|
|
53
53
|
/**
|
|
54
54
|
* Convert a string to snake case _(this_is_snake_case)_
|
|
@@ -57,7 +57,7 @@ function pascalCase(value) {
|
|
|
57
57
|
* @returns Snake-cased string
|
|
58
58
|
*/
|
|
59
59
|
function snakeCase(value) {
|
|
60
|
-
return toCase(
|
|
60
|
+
return toCase(STRING_CASE_SNAKE, value, false, false);
|
|
61
61
|
}
|
|
62
62
|
/**
|
|
63
63
|
* Convert a string to title case _(Capitalizing Every Word)_
|
|
@@ -86,7 +86,7 @@ function toCaseCallback(value) {
|
|
|
86
86
|
const partsLength = parts.length;
|
|
87
87
|
const cased = [];
|
|
88
88
|
for (let partIndex = 0; partIndex < partsLength; partIndex += 1) {
|
|
89
|
-
const items = parts[partIndex].replace(
|
|
89
|
+
const items = parts[partIndex].replace(STRING_EXPRESSION_ACRONYM, (full, one, two, three) => three === STRING_S ? full : `${one}-${two}${three}`).replace(STRING_EXPRESSION_CAMEL_CASE, STRING_REPLACEMENT_CAMEL_CASE).split("-");
|
|
90
90
|
const itemsLength = items.length;
|
|
91
91
|
const partResult = [];
|
|
92
92
|
let itemCount = 0;
|
|
@@ -112,23 +112,23 @@ function upperCase(value) {
|
|
|
112
112
|
memoizedUpperCase ??= memoize((v) => v.toLocaleUpperCase());
|
|
113
113
|
return memoizedUpperCase.run(value);
|
|
114
114
|
}
|
|
115
|
-
const
|
|
116
|
-
const
|
|
117
|
-
const
|
|
118
|
-
const
|
|
119
|
-
const
|
|
120
|
-
const
|
|
121
|
-
const
|
|
122
|
-
const
|
|
123
|
-
const
|
|
124
|
-
const
|
|
125
|
-
const
|
|
115
|
+
const STRING_CASE_CAMEL = "camel";
|
|
116
|
+
const STRING_CASE_KEBAB = "kebab";
|
|
117
|
+
const STRING_CASE_PASCAL = "pascal";
|
|
118
|
+
const STRING_CASE_SNAKE = "snake";
|
|
119
|
+
const STRING_DELIMTER_EMPTY = "";
|
|
120
|
+
const STRING_DELIMITER_HYPHEN = "-";
|
|
121
|
+
const STRING_DELIMITER_UNDERSCORE = "_";
|
|
122
|
+
const STRING_EXPRESSION_CAMEL_CASE = /(\p{Ll})(\p{Lu})/gu;
|
|
123
|
+
const STRING_EXPRESSION_ACRONYM = /(\p{Lu}*)(\p{Lu})(\p{Ll}+)/gu;
|
|
124
|
+
const STRING_REPLACEMENT_CAMEL_CASE = "$1-$2";
|
|
125
|
+
const STRING_S = "s";
|
|
126
126
|
const caseMemoizers = {};
|
|
127
127
|
const delimiters = {
|
|
128
|
-
[
|
|
129
|
-
[
|
|
130
|
-
[
|
|
131
|
-
[
|
|
128
|
+
[STRING_CASE_CAMEL]: STRING_DELIMTER_EMPTY,
|
|
129
|
+
[STRING_CASE_KEBAB]: STRING_DELIMITER_HYPHEN,
|
|
130
|
+
[STRING_CASE_PASCAL]: STRING_DELIMTER_EMPTY,
|
|
131
|
+
[STRING_CASE_SNAKE]: STRING_DELIMITER_UNDERSCORE
|
|
132
132
|
};
|
|
133
133
|
let memoizedCapitalize;
|
|
134
134
|
let memoizedLowerCase;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
//#region src/internal/string.ts
|
|
1
|
+
//#region src/internal/string/misc.ts
|
|
2
2
|
/**
|
|
3
3
|
* Get the string value from any value
|
|
4
4
|
*
|
|
@@ -25,7 +25,7 @@ function getString(value) {
|
|
|
25
25
|
return asString.startsWith("[object ") ? JSON.stringify(value) : asString;
|
|
26
26
|
}
|
|
27
27
|
function ignoreKey(key) {
|
|
28
|
-
return
|
|
28
|
+
return STRING_EXPRESSION_IGNORED.test(key);
|
|
29
29
|
}
|
|
30
30
|
function interpolate(strings, values) {
|
|
31
31
|
const { length } = strings;
|
|
@@ -76,9 +76,9 @@ function tryEncode(value) {
|
|
|
76
76
|
* @returns Array of words found in the string
|
|
77
77
|
*/
|
|
78
78
|
function words(value) {
|
|
79
|
-
return typeof value === "string" ? value.match(
|
|
79
|
+
return typeof value === "string" ? value.match(STRING_EXPRESSION_WORDS) ?? [] : [];
|
|
80
80
|
}
|
|
81
|
-
const
|
|
82
|
-
const
|
|
81
|
+
const STRING_EXPRESSION_IGNORED = /(^|\.)(__proto__|constructor|prototype)(\.|$)/i;
|
|
82
|
+
const STRING_EXPRESSION_WORDS = /[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g;
|
|
83
83
|
//#endregion
|
|
84
84
|
export { getString, ignoreKey, interpolate, join, tryDecode, tryEncode, words };
|
|
@@ -12,16 +12,33 @@ type Subscription = {
|
|
|
12
12
|
};
|
|
13
13
|
type SubscriptionParameters = {
|
|
14
14
|
isActive?: () => boolean;
|
|
15
|
-
key?:
|
|
16
|
-
|
|
17
|
-
subscriptions: Subscriptions;
|
|
15
|
+
key?: unknown;
|
|
16
|
+
signal?: AbortSignal;
|
|
18
17
|
value: unknown;
|
|
19
18
|
};
|
|
19
|
+
/**
|
|
20
|
+
* Property information for subscription identification
|
|
21
|
+
*/
|
|
20
22
|
type SubscriptionProperty = {
|
|
23
|
+
/**
|
|
24
|
+
* Name of the property used to identify a subscription
|
|
25
|
+
*/
|
|
21
26
|
key: string;
|
|
22
|
-
|
|
27
|
+
/**
|
|
28
|
+
* Value of the property used to identify a subscription _(defaults to `subscription`)_
|
|
29
|
+
*/
|
|
30
|
+
value?: unknown;
|
|
23
31
|
};
|
|
24
32
|
type Subscriptions<Value = unknown> = {
|
|
33
|
+
state: SubscriptionsState<Value>;
|
|
34
|
+
clear: () => void;
|
|
35
|
+
create: (parameters: SubscriptionParameters) => [Subscription, boolean];
|
|
36
|
+
};
|
|
37
|
+
type SubscriptionsParameters = {
|
|
38
|
+
keys?: Set<Key>;
|
|
39
|
+
property: SubscriptionProperty;
|
|
40
|
+
};
|
|
41
|
+
type SubscriptionsState<Value = unknown> = {
|
|
25
42
|
items: SubscriptionsItems;
|
|
26
43
|
keys?: Set<Key>;
|
|
27
44
|
values: SubscriptionsValues<Value>;
|
|
@@ -38,9 +55,7 @@ type SubscriptionsValuesItem<MapKey, MapValue> = {
|
|
|
38
55
|
any: Map<MapKey, MapValue>;
|
|
39
56
|
keyed?: Map<Key, Map<MapKey, MapValue>>;
|
|
40
57
|
};
|
|
41
|
-
declare function
|
|
42
|
-
declare function getSubscription(parameters: SubscriptionParameters): Subscription;
|
|
43
|
-
declare function getSubscriptions<Value = unknown>(keys?: Set<Key>): Subscriptions<Value>;
|
|
58
|
+
declare function createSubscriptions<Value = unknown>(parameters: SubscriptionsParameters): Subscriptions<Value>;
|
|
44
59
|
/**
|
|
45
60
|
* Is the value a subscription?
|
|
46
61
|
*
|
|
@@ -48,5 +63,6 @@ declare function getSubscriptions<Value = unknown>(keys?: Set<Key>): Subscriptio
|
|
|
48
63
|
* @returns `true` if the value is a subscription, otherwise `false`
|
|
49
64
|
*/
|
|
50
65
|
declare function isSubscription(value: unknown): value is Subscription;
|
|
66
|
+
declare const SUBSCRIPTION_NAME = "subscription";
|
|
51
67
|
//#endregion
|
|
52
|
-
export { Subscription, SubscriptionParameters, SubscriptionProperty, Subscriptions,
|
|
68
|
+
export { SUBSCRIPTION_NAME, Subscription, SubscriptionParameters, SubscriptionProperty, Subscriptions, createSubscriptions, isSubscription };
|
|
@@ -1,14 +1,16 @@
|
|
|
1
|
-
import { isPlainObject } from "./is.mjs";
|
|
1
|
+
import { isKey, isPlainObject } from "./is.mjs";
|
|
2
|
+
import { createAborter } from "./abort.mjs";
|
|
2
3
|
//#region src/internal/subscription.ts
|
|
3
|
-
function addSubscription(subscription, state) {
|
|
4
|
-
const { key,
|
|
5
|
-
const { items, values } = subscriptions;
|
|
6
|
-
if (key
|
|
4
|
+
function addSubscription(subscriptions, subscription, state) {
|
|
5
|
+
const { key, value } = state.parameters;
|
|
6
|
+
const { items, values } = subscriptions.state;
|
|
7
|
+
if (!isKey(key)) {
|
|
7
8
|
items.any.add(subscription);
|
|
8
9
|
values.from.any.set(value, subscription);
|
|
9
10
|
values.to.any.set(subscription, value);
|
|
10
11
|
return;
|
|
11
12
|
}
|
|
13
|
+
/* istanbul ignore if */
|
|
12
14
|
if (items.keyed == null || values.from.keyed == null || values.to.keyed == null)
|
|
13
15
|
// istanbul ignore next
|
|
14
16
|
return;
|
|
@@ -35,41 +37,31 @@ function clearSubscriptions(store) {
|
|
|
35
37
|
for (const susbcription of store.values.to.any.keys()) susbcription.unsubscribe();
|
|
36
38
|
if (store.values.to.keyed != null) for (const values of store.values.to.keyed.values()) for (const susbcription of values.keys()) susbcription.unsubscribe();
|
|
37
39
|
}
|
|
38
|
-
function
|
|
39
|
-
|
|
40
|
-
const { values } = parameters.subscriptions;
|
|
41
|
-
return parameters.key == null ? values.from.any.get(parameters.value) : values.from.keyed?.get(parameters.key)?.get(parameters.value);
|
|
42
|
-
}
|
|
43
|
-
function getSubscription(parameters) {
|
|
40
|
+
function createSubscription(subscriptions, property, parameters) {
|
|
41
|
+
if (parameters.signal?.aborted ?? false) throw new Error(parameters.signal?.reason);
|
|
44
42
|
const state = {
|
|
45
43
|
parameters,
|
|
46
44
|
active: true
|
|
47
45
|
};
|
|
48
|
-
const existing = getExistingSubscription(state);
|
|
49
|
-
if (existing != null) return existing;
|
|
50
|
-
if (
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
} };
|
|
46
|
+
const existing = getExistingSubscription(subscriptions, state);
|
|
47
|
+
if (existing != null) return [existing, true];
|
|
48
|
+
if (subscriptions.state.keys != null && isKey(parameters.key) && !subscriptions.state.keys.has(parameters.key)) throw new Error(SUBSCRIPTION_INVALID_KEY);
|
|
49
|
+
state.aborter = createAborter(parameters.signal, () => unsubscribe(subscriptions, instance, state));
|
|
50
|
+
const instance = { unsubscribe: () => unsubscribe(subscriptions, instance, state) };
|
|
54
51
|
Object.defineProperties(instance, {
|
|
55
|
-
[
|
|
56
|
-
|
|
57
|
-
value: true
|
|
58
|
-
},
|
|
59
|
-
[parameters.property.key]: {
|
|
60
|
-
enumerable: false,
|
|
61
|
-
value: parameters.property.value
|
|
62
|
-
},
|
|
52
|
+
[SUBSCRIPTION_PROPERTY]: { value: true },
|
|
53
|
+
[property.key]: { value: property.value ?? "subscription" },
|
|
63
54
|
active: {
|
|
64
55
|
enumerable: true,
|
|
65
56
|
get: () => (parameters.isActive?.() ?? true) && state.active
|
|
66
57
|
}
|
|
67
58
|
});
|
|
68
|
-
addSubscription(instance, state);
|
|
69
|
-
return Object.freeze(instance);
|
|
59
|
+
addSubscription(subscriptions, instance, state);
|
|
60
|
+
return [Object.freeze(instance), false];
|
|
70
61
|
}
|
|
71
|
-
function
|
|
72
|
-
|
|
62
|
+
function createSubscriptions(parameters) {
|
|
63
|
+
const { keys, property } = parameters;
|
|
64
|
+
const state = {
|
|
73
65
|
keys,
|
|
74
66
|
items: {
|
|
75
67
|
any: /* @__PURE__ */ new Set(),
|
|
@@ -86,6 +78,17 @@ function getSubscriptions(keys) {
|
|
|
86
78
|
}
|
|
87
79
|
}
|
|
88
80
|
};
|
|
81
|
+
const instance = {
|
|
82
|
+
state,
|
|
83
|
+
clear: () => clearSubscriptions(state),
|
|
84
|
+
create: (parameters) => createSubscription(instance, property, parameters)
|
|
85
|
+
};
|
|
86
|
+
return instance;
|
|
87
|
+
}
|
|
88
|
+
function getExistingSubscription(subscriptions, state) {
|
|
89
|
+
const { parameters } = state;
|
|
90
|
+
const { values } = subscriptions.state;
|
|
91
|
+
return isKey(parameters.key) ? values.from.keyed?.get(parameters.key)?.get(parameters.value) : values.from.any.get(parameters.value);
|
|
89
92
|
}
|
|
90
93
|
/**
|
|
91
94
|
* Is the value a subscription?
|
|
@@ -94,7 +97,7 @@ function getSubscriptions(keys) {
|
|
|
94
97
|
* @returns `true` if the value is a subscription, otherwise `false`
|
|
95
98
|
*/
|
|
96
99
|
function isSubscription(value) {
|
|
97
|
-
return isPlainObject(value) &&
|
|
100
|
+
return isPlainObject(value) && SUBSCRIPTION_PROPERTY in value && value[SUBSCRIPTION_PROPERTY] === true;
|
|
98
101
|
}
|
|
99
102
|
function removeFromStore(items, values, subscription, value, key) {
|
|
100
103
|
items.delete(subscription);
|
|
@@ -106,22 +109,32 @@ function removeFromStore(items, values, subscription, value, key) {
|
|
|
106
109
|
values.to.keyed?.get(key)?.delete(subscription);
|
|
107
110
|
}
|
|
108
111
|
}
|
|
109
|
-
function removeSubscription(subscription, state) {
|
|
112
|
+
function removeSubscription(subscriptions, subscription, state) {
|
|
110
113
|
if (!state.active) return;
|
|
114
|
+
state.aborter = void 0;
|
|
111
115
|
state.active = false;
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
116
|
+
state.parameters.isActive = void 0;
|
|
117
|
+
state.parameters.signal = void 0;
|
|
118
|
+
const { key, value } = state.parameters;
|
|
119
|
+
const { items, values } = subscriptions.state;
|
|
120
|
+
if (!isKey(key)) {
|
|
115
121
|
removeFromStore(items.any, values, subscription, value);
|
|
116
122
|
return;
|
|
117
123
|
}
|
|
118
124
|
const keyed = items.keyed?.get(key);
|
|
125
|
+
/* istanbul ignore if */
|
|
119
126
|
if (items.keyed == null || keyed == null)
|
|
120
127
|
// istanbul ignore next
|
|
121
128
|
return;
|
|
122
129
|
removeFromStore(keyed, values, subscription, value, key);
|
|
123
130
|
if (keyed.size === 0) items.keyed.delete(key);
|
|
124
131
|
}
|
|
125
|
-
|
|
132
|
+
function unsubscribe(subscriptions, subscription, state) {
|
|
133
|
+
state.aborter?.cancel();
|
|
134
|
+
removeSubscription(subscriptions, subscription, state);
|
|
135
|
+
}
|
|
136
|
+
const SUBSCRIPTION_INVALID_KEY = "Invalid key for subscription";
|
|
137
|
+
const SUBSCRIPTION_NAME = "subscription";
|
|
138
|
+
const SUBSCRIPTION_PROPERTY = "$subscription";
|
|
126
139
|
//#endregion
|
|
127
|
-
export {
|
|
140
|
+
export { SUBSCRIPTION_NAME, createSubscriptions, isSubscription };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { max } from "../math/aggregate.mjs";
|
|
2
|
-
import { getString, words } from "../string.mjs";
|
|
2
|
+
import { getString, words } from "../string/misc.mjs";
|
|
3
3
|
import { getCompareHandlers } from "./handlers.mjs";
|
|
4
4
|
//#region src/internal/value/compare.ts
|
|
5
5
|
const COMPARE_NAME = "compare";
|