@oscarpalmer/atoms 0.220.0 → 0.221.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/index.d.mts CHANGED
@@ -4417,6 +4417,14 @@ export declare namespace pipe {
4417
4417
  export var async: typeof asyncPipe;
4418
4418
  }
4419
4419
  //#endregion
4420
+ //#region src/models/string/string.case.model.d.ts
4421
+ type StringCase = "camel" | "capitalize" | "kebab" | "lower" | "pascal" | "snake" | "title" | "upper";
4422
+ type StringCaseOptions = {
4423
+ capitalizeAny: boolean;
4424
+ capitalizeFirst: boolean;
4425
+ type: StringCase;
4426
+ };
4427
+ //#endregion
4420
4428
  //#region src/internal/string/case.d.ts
4421
4429
  /**
4422
4430
  * Convert a string to camel case _(thisIsCamelCase)_
@@ -4522,6 +4530,7 @@ export declare function snakeCase(value: string): string;
4522
4530
  * ```
4523
4531
  */
4524
4532
  export declare function titleCase(value: string): string;
4533
+ export declare function toCaseCallback(this: StringCaseOptions, value: string): string;
4525
4534
  /**
4526
4535
  * Convert a string to upper case
4527
4536
  *
package/dist/index.mjs CHANGED
@@ -1132,7 +1132,7 @@ const VALUE_MISC_NESTED_MESSAGE_UNSAFE = "Access to this property is not allowed
1132
1132
  //#endregion
1133
1133
  //#region src/models/string/string.misc.model.ts
1134
1134
  const STRING_EXPRESSION_IGNORED = /(^|\.)(__proto__|constructor|prototype)(\.|$)/i;
1135
- const STRING_EXPRESSION_WORDS = /([^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+)/g;
1135
+ const STRING_EXPRESSION_WORDS = /[\dA-Za-z\P{ASCII}]+/gu;
1136
1136
  const STRING_EXPRESSION_WHITESPACE_PREFIX = /^(\s+)/;
1137
1137
  const STRING_MATCH_ENDS_WITH = "endsWith";
1138
1138
  const STRING_MATCH_INCLUDES = "includes";
@@ -1981,9 +1981,7 @@ function assertInstanceOf(constructor, message, error) {
1981
1981
  * @returns _Asserter_
1982
1982
  */
1983
1983
  function assertIs(condition, message, error) {
1984
- return (value) => {
1985
- assert(() => condition(value), message, error);
1986
- };
1984
+ return assertCondition(condition, message, error);
1987
1985
  }
1988
1986
  /**
1989
1987
  * Creates an _Asserter_ that asserts a property of a value exists and satisfies a condition, throwing an error if it does not
@@ -2568,12 +2566,17 @@ pipe.async = asyncPipe;
2568
2566
  //#endregion
2569
2567
  //#region src/models/string/string.case.model.ts
2570
2568
  const STRING_CASE_CAMEL = "camel";
2569
+ const STRING_CASE_CAPITALIZE = "capitalize";
2571
2570
  const STRING_CASE_KEBAB = "kebab";
2571
+ const STRING_CASE_LOWER = "lower";
2572
2572
  const STRING_CASE_PASCAL = "pascal";
2573
2573
  const STRING_CASE_SNAKE = "snake";
2574
+ const STRING_CASE_TITLE = "title";
2575
+ const STRING_CASE_UPPER = "upper";
2574
2576
  const STRING_EXPRESSION_CAMEL_CASE = /(\p{Ll})(\p{Lu})/gu;
2575
- const STRING_EXPRESSION_ACRONYM = /(\p{Lu}*)(\p{Lu})(\p{Ll}+)/gu;
2577
+ const STRING_EXPRESSION_ACRONYM = /(?<=\p{Lu})(?=\p{Lu}\p{Ll})(?!\p{Lu}s(?!\p{Ll}))/gu;
2576
2578
  const STRING_REPLACEMENT_CAMEL_CASE = "$1-$2";
2579
+ const ignoreCachingCases = /* @__PURE__ */ new Set(["lower", "upper"]);
2577
2580
  //#endregion
2578
2581
  //#region src/internal/string/case.ts
2579
2582
  /**
@@ -2608,9 +2611,11 @@ function camelCase(value) {
2608
2611
  * ```
2609
2612
  */
2610
2613
  function capitalize(value) {
2611
- if (typeof value !== "string" || value.length === 0) return "";
2612
- memoizedCapitalize ??= memoize((v) => v.length === 1 ? v.toLocaleUpperCase() : `${v.charAt(0).toLocaleUpperCase()}${v.slice(1).toLocaleLowerCase()}`);
2613
- return memoizedCapitalize.run(value);
2614
+ return toCase(STRING_CASE_CAPITALIZE, value, true, true, capitalizeHandler);
2615
+ }
2616
+ function capitalizeHandler(value) {
2617
+ if (value.length === 1) return value.toLocaleUpperCase();
2618
+ return `${value.charAt(0).toLocaleUpperCase()}${value.slice(1).toLocaleLowerCase()}`;
2614
2619
  }
2615
2620
  /**
2616
2621
  * Convert a string to kebab case _(this-is-kebab-case)_
@@ -2643,9 +2648,10 @@ function kebabCase(value) {
2643
2648
  * ```
2644
2649
  */
2645
2650
  function lowerCase(value) {
2646
- if (typeof value !== "string") return "";
2647
- memoizedLowerCase ??= memoize((v) => v.toLocaleLowerCase());
2648
- return memoizedLowerCase.run(value);
2651
+ return toCase(STRING_CASE_LOWER, value, false, false, lowerCaseHandler);
2652
+ }
2653
+ function lowerCaseHandler(value) {
2654
+ return value.toLocaleLowerCase();
2649
2655
  }
2650
2656
  /**
2651
2657
  * Convert a string to pascal case _(ThisIsPascalCase)_
@@ -2696,33 +2702,39 @@ function snakeCase(value) {
2696
2702
  * ```
2697
2703
  */
2698
2704
  function titleCase(value) {
2699
- if (typeof value !== "string" || value.length === 0) return "";
2700
- memoizedTitleCase ??= memoize((v) => v.length < 2 ? capitalize(v) : join(words(v).map(capitalize), " "));
2701
- return memoizedTitleCase.run(value);
2705
+ return toCase(STRING_CASE_TITLE, value, true, true, titleCaseHandler);
2702
2706
  }
2703
- function toCase(type, value, capitalizeAny, capitalizeFirst) {
2704
- caseMemoizers[type] ??= memoize(toCaseCallback.bind({
2705
- type,
2706
- capitalizeAny,
2707
- capitalizeFirst
2708
- }));
2709
- return caseMemoizers[type].run(value);
2707
+ function titleCaseHandler(value) {
2708
+ if (value.length < 2) return capitalize(value);
2709
+ return join(words(value).map(capitalize), " ");
2710
2710
  }
2711
- function toCaseCallback(value) {
2711
+ function toCase(type, value, capitalizeAny, capitalizeFirst, handler) {
2712
2712
  if (typeof value !== "string") return "";
2713
- if (value.length < 1) return value;
2713
+ if (value.trim().length === 0) return value;
2714
+ if (handler == null) {
2715
+ caseMemoizers[type] ??= memoize(toCaseCallback.bind({
2716
+ type,
2717
+ capitalizeAny,
2718
+ capitalizeFirst
2719
+ }));
2720
+ return caseMemoizers[type].run(value);
2721
+ }
2722
+ if (ignoreCachingCases.has(type)) return handler(value);
2723
+ simpleMemoizers[type] ??= memoize(handler);
2724
+ return simpleMemoizers[type].run(value);
2725
+ }
2726
+ function toCaseCallback(value) {
2714
2727
  const { capitalizeAny, capitalizeFirst, type } = this;
2715
2728
  const parts = words(value);
2716
2729
  const partsLength = parts.length;
2717
2730
  const cased = [];
2718
2731
  for (let partIndex = 0; partIndex < partsLength; partIndex += 1) {
2719
- const items = parts[partIndex].replace(STRING_EXPRESSION_ACRONYM, (full, one, two, three) => three === "s" ? full : `${one}-${two}${three}`).replace(STRING_EXPRESSION_CAMEL_CASE, STRING_REPLACEMENT_CAMEL_CASE).split("-");
2732
+ const items = parts[partIndex].replace(STRING_EXPRESSION_ACRONYM, "-").replace(STRING_EXPRESSION_CAMEL_CASE, STRING_REPLACEMENT_CAMEL_CASE).split("-");
2720
2733
  const itemsLength = items.length;
2721
2734
  const partResult = [];
2722
2735
  let itemCount = 0;
2723
2736
  for (let itemIndex = 0; itemIndex < itemsLength; itemIndex += 1) {
2724
2737
  const item = items[itemIndex];
2725
- if (item.length === 0) continue;
2726
2738
  if (!capitalizeAny || itemCount === 0 && partIndex === 0 && !capitalizeFirst) partResult.push(item.toLocaleLowerCase());
2727
2739
  else partResult.push(capitalize(item));
2728
2740
  itemCount += 1;
@@ -2746,9 +2758,10 @@ function toCaseCallback(value) {
2746
2758
  * ```
2747
2759
  */
2748
2760
  function upperCase(value) {
2749
- if (typeof value !== "string" || value.length === 0) return "";
2750
- memoizedUpperCase ??= memoize((v) => v.toLocaleUpperCase());
2751
- return memoizedUpperCase.run(value);
2761
+ return toCase(STRING_CASE_UPPER, value, false, false, upperCaseHandler);
2762
+ }
2763
+ function upperCaseHandler(value) {
2764
+ return value.toLocaleUpperCase();
2752
2765
  }
2753
2766
  const caseMemoizers = {};
2754
2767
  const delimiters = {
@@ -2757,10 +2770,7 @@ const delimiters = {
2757
2770
  [STRING_CASE_PASCAL]: "",
2758
2771
  [STRING_CASE_SNAKE]: "_"
2759
2772
  };
2760
- let memoizedCapitalize;
2761
- let memoizedLowerCase;
2762
- let memoizedTitleCase;
2763
- let memoizedUpperCase;
2773
+ const simpleMemoizers = {};
2764
2774
  //#endregion
2765
2775
  //#region src/models/value/value.equal.model.ts
2766
2776
  const EQUAL_ERROR_PROPERTIES = ["name", "message"];
@@ -4271,7 +4281,7 @@ let deburrMemoizer;
4271
4281
  normalize.initialize = initializeNormalizer;
4272
4282
  //#endregion
4273
4283
  //#region src/models/string/string.template.model.ts
4274
- const TEMPLATE_EXPRESSION_VARIABLE = /{{([\s\S]+?)}}/g;
4284
+ const TEMPLATE_EXPRESSION_VARIABLE = /{{([^{}]+)}}/g;
4275
4285
  const TEMPLATE_SYMBOL = Symbol("template");
4276
4286
  //#endregion
4277
4287
  //#region src/string/template.ts
@@ -5078,9 +5088,7 @@ function addSubscription(instance) {
5078
5088
  return;
5079
5089
  }
5080
5090
  /* istanbul ignore if */
5081
- if (items.keyed == null || values.from.keyed == null || values.to.keyed == null)
5082
- // istanbul ignore next
5083
- return;
5091
+ if (items.keyed == null || values.from.keyed == null || values.to.keyed == null) return;
5084
5092
  let keyedItems = items.keyed.get(key);
5085
5093
  if (keyedItems == null) {
5086
5094
  keyedItems = /* @__PURE__ */ new Set();
@@ -5230,9 +5238,7 @@ function removeSubscription() {
5230
5238
  }
5231
5239
  const keyed = items.keyed?.get(key);
5232
5240
  /* istanbul ignore if */
5233
- if (items.keyed == null || keyed == null)
5234
- // istanbul ignore next
5235
- return;
5241
+ if (items.keyed == null || keyed == null) return;
5236
5242
  removeFromStore(keyed, values, this, value, key);
5237
5243
  if (keyed.size === 0) items.keyed.delete(key);
5238
5244
  }
@@ -7654,4 +7660,4 @@ var SizedSet = class extends Set {
7654
7660
  }
7655
7661
  };
7656
7662
  //#endregion
7657
- export { CancelablePromise, Logger, PromiseTimeoutError, RetryError, SORT_DIRECTION_ASCENDING, SORT_DIRECTION_DESCENDING, SizedMap, SizedSet, push as append, push, assert, assertCondition, assertDefined, assertInstanceOf, assertIs, assertProperty, assign, asyncAttempt, asyncAttemptRun, asyncDebounce, asyncFail, asyncFlow, asyncMatchResult, asyncOnce, asyncPipe, asyncRun, asyncSucceed, asyncThrottle, asyncUse, attempt, attemptAsyncFlow, attemptAsyncPipe, attemptFlow, attemptPipe, attemptPromise, attemptRun, average, beacon, between, camelCase, cancelable, capitalize, ceil, chunk, clamp, clone, compact, compare, copy, count, debounce, deburr, dedent, delay, deregisterCloner, deregisterComparator, deregisterEqualizer, diff, difference, drop, endsWith, endsWithArray, equal, error, exclude, exists, fail, filter, filterAndFlatMap, filterAndMap, filterAndMap as select, find, findLast, first, firstOrDefault, flatFreeze, flatMapAndFilter, flatten, floor, flow, freeze, fromQuery, toPromise as fromResult, toPromise, fuzzy, fuzzyMatch, getArray, getArrayComparison, getColor, getForegroundColor, getHexColor, getHexaColor, getHslColor, getHslaColor, getHwbColor, getHwbaColor, getNormalizedHex, getNumber, getRandom, getRandomBoolean, getRandomCharacters, getRandomColor, getRandomFloatingNumber as getRandomFloat, getRandomHex, getRandomInteger, getRandomItem, getRandomItems, getRgbColor, getRgbaColor, getSortedIndex, getString, getTimedPromise, getUuid, getValue, groupArraysBy, groupBy, handleResult, hasValue, hasValueResult, herald, hexToHsl, hexToHsla, hexToHwb, hexToHwba, hexToRgb, hexToRgba, hslToHex, hslToHwb, hslToHwba, hslToRgb, hslToRgba, hwbToHex, hwbToHsl, hwbToHsla, hwbToRgb, hwbToRgba, ignoreKey, inMap, inSet, includes, includesArray, indexOf, indexOfArray, initializeAssigner, initializeCloner, initializeEqualizer, initializeMerger, initializeNormalizer, initializeSorter, initializeTemplater, initializeTransformer, insert, interpolate, intersection, isArrayOrPlainObject, isAsyncFailure, isAsyncGenerator, isAsyncGeneratorFunction, isAsyncOnce, isAsyncPlan, isAsyncStep, isAsyncSuccess, isBeacon, isBeaconSubscription, isColor, isConstructor, isEmpty, isError, isFailure, isFrozen, isFulfilled, isFuzzy, isGenerator, isGeneratorFunction, isHerald, isHeraldEvents, isHeraldSubscription, isHexColor, isHslColor, isHslaColor, isHwbColor, isHwbaColor, isInstanceOf, isKey, isKeyedQueue, isLogger, isNonArrayOrPlainObject, isNonConstructor, isNonEmpty, isNonInstanceOf, isNonKey, isNonNullable, isNonNullableOrEmpty, isNonNullableOrWhitespace, isNonNumber, isNonNumerical, isNonObject, isNonPlainObject, isNonPrimitive, isNonTemplateStringsArray, isNonTypedArray, isNullable, isNullableOrEmpty, isNullableOrWhitespace, isNumber, isNumerical, isObject, isObservable, isOk, isOnce, isPlainObject, isPlan, isPrimitive, isQueue, isRejected, isResult, isRgbColor, isRgbaColor, isSorted, isStep, isSubscription, isSubscriptions, isSuccess, isTemplateStringsArray, isTimeLogger, isTypedArray, join, kebabCase, keyedQueue, last, lastIndexOf, lastOrDefault, lowerCase, mapAndFilter, mapAndFilter as reverseSelect, matchResult, max, median, memoize, merge, min, move, moveIndices, moveToIndex, noop, normalize, ok, omit, once, parse, partition, pascalCase, pick, pipe, plan, promises, queue, range, registerCloner, registerComparator, registerEqualizer, resultPromises, retry, reverse, rgbToHex, rgbToHsl, rgbToHsla, rgbToHwb, rgbToHwba, round, run, setValue, settlePromise, shake, shuffle, single, slice, smush, snakeCase, sort, splice, startsWith, startsWithArray, subscriptions, succeed, sum, swap, take, template, throttle, timed, times, titleCase, toMap, toMapArrays, toQuery, toRecord, toRecordArrays, toResult, toSet, toggle, transform, trim, truncate, tryDecode, tryEncode, union, unique, unsmush, unwrap, update, upperCase, use, words };
7663
+ export { CancelablePromise, Logger, PromiseTimeoutError, RetryError, SORT_DIRECTION_ASCENDING, SORT_DIRECTION_DESCENDING, SizedMap, SizedSet, push as append, push, assert, assertCondition, assertDefined, assertInstanceOf, assertIs, assertProperty, assign, asyncAttempt, asyncAttemptRun, asyncDebounce, asyncFail, asyncFlow, asyncMatchResult, asyncOnce, asyncPipe, asyncRun, asyncSucceed, asyncThrottle, asyncUse, attempt, attemptAsyncFlow, attemptAsyncPipe, attemptFlow, attemptPipe, attemptPromise, attemptRun, average, beacon, between, camelCase, cancelable, capitalize, ceil, chunk, clamp, clone, compact, compare, copy, count, debounce, deburr, dedent, delay, deregisterCloner, deregisterComparator, deregisterEqualizer, diff, difference, drop, endsWith, endsWithArray, equal, error, exclude, exists, fail, filter, filterAndFlatMap, filterAndMap, filterAndMap as select, find, findLast, first, firstOrDefault, flatFreeze, flatMapAndFilter, flatten, floor, flow, freeze, fromQuery, toPromise as fromResult, toPromise, fuzzy, fuzzyMatch, getArray, getArrayComparison, getColor, getForegroundColor, getHexColor, getHexaColor, getHslColor, getHslaColor, getHwbColor, getHwbaColor, getNormalizedHex, getNumber, getRandom, getRandomBoolean, getRandomCharacters, getRandomColor, getRandomFloatingNumber as getRandomFloat, getRandomHex, getRandomInteger, getRandomItem, getRandomItems, getRgbColor, getRgbaColor, getSortedIndex, getString, getTimedPromise, getUuid, getValue, groupArraysBy, groupBy, handleResult, hasValue, hasValueResult, herald, hexToHsl, hexToHsla, hexToHwb, hexToHwba, hexToRgb, hexToRgba, hslToHex, hslToHwb, hslToHwba, hslToRgb, hslToRgba, hwbToHex, hwbToHsl, hwbToHsla, hwbToRgb, hwbToRgba, ignoreKey, inMap, inSet, includes, includesArray, indexOf, indexOfArray, initializeAssigner, initializeCloner, initializeEqualizer, initializeMerger, initializeNormalizer, initializeSorter, initializeTemplater, initializeTransformer, insert, interpolate, intersection, isArrayOrPlainObject, isAsyncFailure, isAsyncGenerator, isAsyncGeneratorFunction, isAsyncOnce, isAsyncPlan, isAsyncStep, isAsyncSuccess, isBeacon, isBeaconSubscription, isColor, isConstructor, isEmpty, isError, isFailure, isFrozen, isFulfilled, isFuzzy, isGenerator, isGeneratorFunction, isHerald, isHeraldEvents, isHeraldSubscription, isHexColor, isHslColor, isHslaColor, isHwbColor, isHwbaColor, isInstanceOf, isKey, isKeyedQueue, isLogger, isNonArrayOrPlainObject, isNonConstructor, isNonEmpty, isNonInstanceOf, isNonKey, isNonNullable, isNonNullableOrEmpty, isNonNullableOrWhitespace, isNonNumber, isNonNumerical, isNonObject, isNonPlainObject, isNonPrimitive, isNonTemplateStringsArray, isNonTypedArray, isNullable, isNullableOrEmpty, isNullableOrWhitespace, isNumber, isNumerical, isObject, isObservable, isOk, isOnce, isPlainObject, isPlan, isPrimitive, isQueue, isRejected, isResult, isRgbColor, isRgbaColor, isSorted, isStep, isSubscription, isSubscriptions, isSuccess, isTemplateStringsArray, isTimeLogger, isTypedArray, join, kebabCase, keyedQueue, last, lastIndexOf, lastOrDefault, lowerCase, mapAndFilter, mapAndFilter as reverseSelect, matchResult, max, median, memoize, merge, min, move, moveIndices, moveToIndex, noop, normalize, ok, omit, once, parse, partition, pascalCase, pick, pipe, plan, promises, queue, range, registerCloner, registerComparator, registerEqualizer, resultPromises, retry, reverse, rgbToHex, rgbToHsl, rgbToHsla, rgbToHwb, rgbToHwba, round, run, setValue, settlePromise, shake, shuffle, single, slice, smush, snakeCase, sort, splice, startsWith, startsWithArray, subscriptions, succeed, sum, swap, take, template, throttle, timed, times, titleCase, toCaseCallback, toMap, toMapArrays, toQuery, toRecord, toRecordArrays, toResult, toSet, toggle, transform, trim, truncate, tryDecode, tryEncode, union, unique, unsmush, unwrap, update, upperCase, use, words };
@@ -64,9 +64,7 @@ function assertInstanceOf(constructor, message, error) {
64
64
  * @returns _Asserter_
65
65
  */
66
66
  function assertIs(condition, message, error) {
67
- return (value) => {
68
- assert(() => condition(value), message, error);
69
- };
67
+ return assertCondition(condition, message, error);
70
68
  }
71
69
  /**
72
70
  * Creates an _Asserter_ that asserts a property of a value exists and satisfies a condition, throwing an error if it does not
@@ -1,3 +1,4 @@
1
+ import { StringCaseOptions } from "../../models/string/string.case.model.mjs";
1
2
  //#region src/internal/string/case.d.ts
2
3
  /**
3
4
  * Convert a string to camel case _(thisIsCamelCase)_
@@ -103,6 +104,7 @@ export declare function snakeCase(value: string): string;
103
104
  * ```
104
105
  */
105
106
  export declare function titleCase(value: string): string;
107
+ export declare function toCaseCallback(this: StringCaseOptions, value: string): string;
106
108
  /**
107
109
  * Convert a string to upper case
108
110
  *
@@ -1,6 +1,6 @@
1
1
  import { join, words } from "./misc.mjs";
2
2
  import { memoize } from "../function/memoize.mjs";
3
- import { STRING_CASE_CAMEL, STRING_CASE_KEBAB, STRING_CASE_PASCAL, STRING_CASE_SNAKE, STRING_EXPRESSION_ACRONYM, STRING_EXPRESSION_CAMEL_CASE, STRING_REPLACEMENT_CAMEL_CASE } from "../../models/string/string.case.model.mjs";
3
+ import { STRING_CASE_CAMEL, STRING_CASE_CAPITALIZE, STRING_CASE_KEBAB, STRING_CASE_LOWER, STRING_CASE_PASCAL, STRING_CASE_SNAKE, STRING_CASE_TITLE, STRING_CASE_UPPER, STRING_EXPRESSION_ACRONYM, STRING_EXPRESSION_CAMEL_CASE, STRING_REPLACEMENT_CAMEL_CASE, ignoreCachingCases } from "../../models/string/string.case.model.mjs";
4
4
  //#region src/internal/string/case.ts
5
5
  /**
6
6
  * Convert a string to camel case _(thisIsCamelCase)_
@@ -34,9 +34,11 @@ function camelCase(value) {
34
34
  * ```
35
35
  */
36
36
  function capitalize(value) {
37
- if (typeof value !== "string" || value.length === 0) return "";
38
- memoizedCapitalize ??= memoize((v) => v.length === 1 ? v.toLocaleUpperCase() : `${v.charAt(0).toLocaleUpperCase()}${v.slice(1).toLocaleLowerCase()}`);
39
- return memoizedCapitalize.run(value);
37
+ return toCase(STRING_CASE_CAPITALIZE, value, true, true, capitalizeHandler);
38
+ }
39
+ function capitalizeHandler(value) {
40
+ if (value.length === 1) return value.toLocaleUpperCase();
41
+ return `${value.charAt(0).toLocaleUpperCase()}${value.slice(1).toLocaleLowerCase()}`;
40
42
  }
41
43
  /**
42
44
  * Convert a string to kebab case _(this-is-kebab-case)_
@@ -69,9 +71,10 @@ function kebabCase(value) {
69
71
  * ```
70
72
  */
71
73
  function lowerCase(value) {
72
- if (typeof value !== "string") return "";
73
- memoizedLowerCase ??= memoize((v) => v.toLocaleLowerCase());
74
- return memoizedLowerCase.run(value);
74
+ return toCase(STRING_CASE_LOWER, value, false, false, lowerCaseHandler);
75
+ }
76
+ function lowerCaseHandler(value) {
77
+ return value.toLocaleLowerCase();
75
78
  }
76
79
  /**
77
80
  * Convert a string to pascal case _(ThisIsPascalCase)_
@@ -122,33 +125,39 @@ function snakeCase(value) {
122
125
  * ```
123
126
  */
124
127
  function titleCase(value) {
125
- if (typeof value !== "string" || value.length === 0) return "";
126
- memoizedTitleCase ??= memoize((v) => v.length < 2 ? capitalize(v) : join(words(v).map(capitalize), " "));
127
- return memoizedTitleCase.run(value);
128
+ return toCase(STRING_CASE_TITLE, value, true, true, titleCaseHandler);
128
129
  }
129
- function toCase(type, value, capitalizeAny, capitalizeFirst) {
130
- caseMemoizers[type] ??= memoize(toCaseCallback.bind({
131
- type,
132
- capitalizeAny,
133
- capitalizeFirst
134
- }));
135
- return caseMemoizers[type].run(value);
130
+ function titleCaseHandler(value) {
131
+ if (value.length < 2) return capitalize(value);
132
+ return join(words(value).map(capitalize), " ");
136
133
  }
137
- function toCaseCallback(value) {
134
+ function toCase(type, value, capitalizeAny, capitalizeFirst, handler) {
138
135
  if (typeof value !== "string") return "";
139
- if (value.length < 1) return value;
136
+ if (value.trim().length === 0) return value;
137
+ if (handler == null) {
138
+ caseMemoizers[type] ??= memoize(toCaseCallback.bind({
139
+ type,
140
+ capitalizeAny,
141
+ capitalizeFirst
142
+ }));
143
+ return caseMemoizers[type].run(value);
144
+ }
145
+ if (ignoreCachingCases.has(type)) return handler(value);
146
+ simpleMemoizers[type] ??= memoize(handler);
147
+ return simpleMemoizers[type].run(value);
148
+ }
149
+ function toCaseCallback(value) {
140
150
  const { capitalizeAny, capitalizeFirst, type } = this;
141
151
  const parts = words(value);
142
152
  const partsLength = parts.length;
143
153
  const cased = [];
144
154
  for (let partIndex = 0; partIndex < partsLength; partIndex += 1) {
145
- const items = parts[partIndex].replace(STRING_EXPRESSION_ACRONYM, (full, one, two, three) => three === "s" ? full : `${one}-${two}${three}`).replace(STRING_EXPRESSION_CAMEL_CASE, STRING_REPLACEMENT_CAMEL_CASE).split("-");
155
+ const items = parts[partIndex].replace(STRING_EXPRESSION_ACRONYM, "-").replace(STRING_EXPRESSION_CAMEL_CASE, STRING_REPLACEMENT_CAMEL_CASE).split("-");
146
156
  const itemsLength = items.length;
147
157
  const partResult = [];
148
158
  let itemCount = 0;
149
159
  for (let itemIndex = 0; itemIndex < itemsLength; itemIndex += 1) {
150
160
  const item = items[itemIndex];
151
- if (item.length === 0) continue;
152
161
  if (!capitalizeAny || itemCount === 0 && partIndex === 0 && !capitalizeFirst) partResult.push(item.toLocaleLowerCase());
153
162
  else partResult.push(capitalize(item));
154
163
  itemCount += 1;
@@ -172,9 +181,10 @@ function toCaseCallback(value) {
172
181
  * ```
173
182
  */
174
183
  function upperCase(value) {
175
- if (typeof value !== "string" || value.length === 0) return "";
176
- memoizedUpperCase ??= memoize((v) => v.toLocaleUpperCase());
177
- return memoizedUpperCase.run(value);
184
+ return toCase(STRING_CASE_UPPER, value, false, false, upperCaseHandler);
185
+ }
186
+ function upperCaseHandler(value) {
187
+ return value.toLocaleUpperCase();
178
188
  }
179
189
  const caseMemoizers = {};
180
190
  const delimiters = {
@@ -183,9 +193,6 @@ const delimiters = {
183
193
  [STRING_CASE_PASCAL]: "",
184
194
  [STRING_CASE_SNAKE]: "_"
185
195
  };
186
- let memoizedCapitalize;
187
- let memoizedLowerCase;
188
- let memoizedTitleCase;
189
- let memoizedUpperCase;
196
+ const simpleMemoizers = {};
190
197
  //#endregion
191
- export { camelCase, capitalize, kebabCase, lowerCase, pascalCase, snakeCase, titleCase, upperCase };
198
+ export { camelCase, capitalize, kebabCase, lowerCase, pascalCase, snakeCase, titleCase, toCaseCallback, upperCase };
@@ -42,9 +42,7 @@ function addSubscription(instance) {
42
42
  return;
43
43
  }
44
44
  /* istanbul ignore if */
45
- if (items.keyed == null || values.from.keyed == null || values.to.keyed == null)
46
- // istanbul ignore next
47
- return;
45
+ if (items.keyed == null || values.from.keyed == null || values.to.keyed == null) return;
48
46
  let keyedItems = items.keyed.get(key);
49
47
  if (keyedItems == null) {
50
48
  keyedItems = /* @__PURE__ */ new Set();
@@ -194,9 +192,7 @@ function removeSubscription() {
194
192
  }
195
193
  const keyed = items.keyed?.get(key);
196
194
  /* istanbul ignore if */
197
- if (items.keyed == null || keyed == null)
198
- // istanbul ignore next
199
- return;
195
+ if (items.keyed == null || keyed == null) return;
200
196
  removeFromStore(keyed, values, this, value, key);
201
197
  if (keyed.size === 0) items.keyed.delete(key);
202
198
  }
@@ -1,19 +1,24 @@
1
1
  //#region src/models/string/string.case.model.d.ts
2
- export type StringCase = "camel" | "kebab" | "pascal" | "snake";
2
+ export type StringCase = "camel" | "capitalize" | "kebab" | "lower" | "pascal" | "snake" | "title" | "upper";
3
3
  export type StringCaseOptions = {
4
4
  capitalizeAny: boolean;
5
5
  capitalizeFirst: boolean;
6
6
  type: StringCase;
7
7
  };
8
8
  export declare const STRING_CASE_CAMEL: StringCase;
9
+ export declare const STRING_CASE_CAPITALIZE: StringCase;
9
10
  export declare const STRING_CASE_KEBAB: StringCase;
11
+ export declare const STRING_CASE_LOWER: StringCase;
10
12
  export declare const STRING_CASE_PASCAL: StringCase;
11
13
  export declare const STRING_CASE_SNAKE: StringCase;
12
- export declare const STRING_DELIMTER_EMPTY = "";
14
+ export declare const STRING_CASE_TITLE: StringCase;
15
+ export declare const STRING_CASE_UPPER: StringCase;
16
+ export declare const STRING_DELIMITER_EMPTY = "";
13
17
  export declare const STRING_DELIMITER_HYPHEN = "-";
18
+ export declare const STRING_DELIMITER_SPACE = " ";
14
19
  export declare const STRING_DELIMITER_UNDERSCORE = "_";
15
20
  export declare const STRING_EXPRESSION_CAMEL_CASE: RegExp;
16
21
  export declare const STRING_EXPRESSION_ACRONYM: RegExp;
17
22
  export declare const STRING_REPLACEMENT_CAMEL_CASE = "$1-$2";
18
- export declare const STRING_S = "s";
23
+ export declare const ignoreCachingCases: Set<StringCase>;
19
24
  //#endregion
@@ -1,14 +1,19 @@
1
1
  //#region src/models/string/string.case.model.ts
2
2
  const STRING_CASE_CAMEL = "camel";
3
+ const STRING_CASE_CAPITALIZE = "capitalize";
3
4
  const STRING_CASE_KEBAB = "kebab";
5
+ const STRING_CASE_LOWER = "lower";
4
6
  const STRING_CASE_PASCAL = "pascal";
5
7
  const STRING_CASE_SNAKE = "snake";
6
- const STRING_DELIMTER_EMPTY = "";
8
+ const STRING_CASE_TITLE = "title";
9
+ const STRING_CASE_UPPER = "upper";
10
+ const STRING_DELIMITER_EMPTY = "";
7
11
  const STRING_DELIMITER_HYPHEN = "-";
12
+ const STRING_DELIMITER_SPACE = " ";
8
13
  const STRING_DELIMITER_UNDERSCORE = "_";
9
14
  const STRING_EXPRESSION_CAMEL_CASE = /(\p{Ll})(\p{Lu})/gu;
10
- const STRING_EXPRESSION_ACRONYM = /(\p{Lu}*)(\p{Lu})(\p{Ll}+)/gu;
15
+ const STRING_EXPRESSION_ACRONYM = /(?<=\p{Lu})(?=\p{Lu}\p{Ll})(?!\p{Lu}s(?!\p{Ll}))/gu;
11
16
  const STRING_REPLACEMENT_CAMEL_CASE = "$1-$2";
12
- const STRING_S = "s";
17
+ const ignoreCachingCases = /* @__PURE__ */ new Set(["lower", "upper"]);
13
18
  //#endregion
14
- export { STRING_CASE_CAMEL, STRING_CASE_KEBAB, STRING_CASE_PASCAL, STRING_CASE_SNAKE, STRING_DELIMITER_HYPHEN, STRING_DELIMITER_UNDERSCORE, STRING_DELIMTER_EMPTY, STRING_EXPRESSION_ACRONYM, STRING_EXPRESSION_CAMEL_CASE, STRING_REPLACEMENT_CAMEL_CASE, STRING_S };
19
+ export { STRING_CASE_CAMEL, STRING_CASE_CAPITALIZE, STRING_CASE_KEBAB, STRING_CASE_LOWER, STRING_CASE_PASCAL, STRING_CASE_SNAKE, STRING_CASE_TITLE, STRING_CASE_UPPER, STRING_DELIMITER_EMPTY, STRING_DELIMITER_HYPHEN, STRING_DELIMITER_SPACE, STRING_DELIMITER_UNDERSCORE, STRING_EXPRESSION_ACRONYM, STRING_EXPRESSION_CAMEL_CASE, STRING_REPLACEMENT_CAMEL_CASE, ignoreCachingCases };
@@ -2,7 +2,7 @@
2
2
  const STRING_DELIMITER_UUID_DEFAULT = "-";
3
3
  const STRING_DELIMITER_UUID_HTML = "_";
4
4
  const STRING_EXPRESSION_IGNORED = /(^|\.)(__proto__|constructor|prototype)(\.|$)/i;
5
- const STRING_EXPRESSION_WORDS = /([^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+)/g;
5
+ const STRING_EXPRESSION_WORDS = /[\dA-Za-z\P{ASCII}]+/gu;
6
6
  const STRING_EXPRESSION_WHITESPACE_PREFIX = /^(\s+)/;
7
7
  const STRING_MATCH_ENDS_WITH = "endsWith";
8
8
  const STRING_MATCH_INCLUDES = "includes";
@@ -1,5 +1,5 @@
1
1
  //#region src/models/string/string.template.model.ts
2
- const TEMPLATE_EXPRESSION_VARIABLE = /{{([\s\S]+?)}}/g;
2
+ const TEMPLATE_EXPRESSION_VARIABLE = /{{([^{}]+)}}/g;
3
3
  const TEMPLATE_SYMBOL = Symbol("template");
4
4
  //#endregion
5
5
  export { TEMPLATE_EXPRESSION_VARIABLE, TEMPLATE_SYMBOL };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oscarpalmer/atoms",
3
- "version": "0.220.0",
3
+ "version": "0.221.0",
4
4
  "description": "Atomic utilities for making your JavaScript better.",
5
5
  "keywords": [
6
6
  "array",