@develia/commons 0.4.15 → 0.4.16

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/cjs/array.js CHANGED
@@ -4,6 +4,7 @@ exports.pull = pull;
4
4
  exports.chunk = chunk;
5
5
  exports.clear = clear;
6
6
  exports.remove = remove;
7
+ exports.pushIfAbsent = pushIfAbsent;
7
8
  /**
8
9
  * Removes all given values from the provided array and returns the number of removed elements.
9
10
  * The operation mutates the original array.
@@ -67,4 +68,19 @@ function remove(array, predicate) {
67
68
  }
68
69
  return removed;
69
70
  }
71
+ /**
72
+ * Adds an element to the array if it's not already present.
73
+ * The operation mutates the original array.
74
+ * @template T
75
+ * @param {Array<T>} array - The array to modify.
76
+ * @param {T} element - The element to add if absent.
77
+ * @return {boolean} True if the element was added, false otherwise.
78
+ */
79
+ function pushIfAbsent(array, element) {
80
+ if (!array.includes(element)) {
81
+ array.push(element);
82
+ return true;
83
+ }
84
+ return false;
85
+ }
70
86
  //# sourceMappingURL=array.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"array.js","sourceRoot":"","sources":["../../src/array.ts"],"names":[],"mappings":";;AAUA,oBAWC;AASD,sBAOC;AAOD,sBAEC;AAQD,wBAcC;AAlED;;;;;;;GAOG;AACH,SAAgB,IAAI,CAAI,KAAe,EAAE,GAAG,KAAe;IAEvD,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACvB,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAClC,IAAI,KAAK,KAAK,CAAC,CAAC,EAAE,CAAC;YACf,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;YACvB,MAAM,EAAE,CAAC;QACb,CAAC;IACL,CAAC;IACD,OAAO,MAAM,CAAC;AAClB,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,KAAK,CAAI,KAAe,EAAE,IAAY;IAClD,IAAI,IAAI,IAAI,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;IAC9D,MAAM,MAAM,GAAoB,EAAE,CAAC;IACnC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC;QAC1C,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;IAC1C,CAAC;IACD,OAAO,MAAM,CAAC;AAClB,CAAC;AAED;;;;GAIG;AACH,SAAgB,KAAK,CAAI,KAAe;IACpC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;AACrB,CAAC;AAED;;;;;GAKG;AACH,SAAgB,MAAM,CAAI,KAAe,EAAC,SAAuB;IAC7D,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,IAAI,CAAC,GAAG,CAAC,CAAC;IAEV,OAAO,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;QACtB,IAAI,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YACtB,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;YACvB,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,gBAAgB;QACxC,CAAC;aAAM,CAAC;YACJ,CAAC,EAAE,CAAC;QACR,CAAC;IACL,CAAC;IAED,OAAO,OAAO,CAAC;AACnB,CAAC","sourcesContent":["import type {Predicate} from \"./types.js\";\r\n\r\n/**\r\n * Removes all given values from the provided array and returns the number of removed elements.\r\n * The operation mutates the original array.\r\n * @template T\r\n * @param {Array<T>} array - The array to modify by removing specified items.\r\n * @param {...T} items - The values to remove from the array.\r\n * @return {number} The number of elements removed from the array.\r\n */\r\nexport function pull<T>(array: Array<T>, ...items: Array<T>): number {\r\n\r\n let output = 0;\r\n for (const item of items) {\r\n const index = array.indexOf(item);\r\n if (index !== -1) {\r\n array.splice(index, 1);\r\n output++;\r\n }\r\n }\r\n return output;\r\n}\r\n\r\n/**\r\n * Splits an array into chunks of a given size.\r\n * @template T\r\n * @param {Array<T>} array - The array to split.\r\n * @param {number} size - The size of each chunk.\r\n * @return {Array<Array<T>>} The array of chunks.\r\n */\r\nexport function chunk<T>(array: Array<T>, size: number): Array<Array<T>> {\r\n if (size <= 0) throw new Error(\"Size must be greater than 0\");\r\n const result: Array<Array<T>> = [];\r\n for (let i = 0; i < array.length; i += size) {\r\n result.push(array.slice(i, i + size));\r\n }\r\n return result;\r\n}\r\n\r\n/**\r\n * Removes all elements from the array, mutating it.\r\n * @template T\r\n * @param {Array<T>} array - The array to clear.\r\n */\r\nexport function clear<T>(array: Array<T>): void {\r\n array.length = 0;\r\n}\r\n\r\n/**\r\n * Removes all elements from the array that satisfy the predicate.\r\n * The operation mutates the original array.\r\n * @template T\r\n * @return {Array<T>} An array of removed elements.\r\n */\r\nexport function remove<T>(array: Array<T>,predicate: Predicate<T>): Array<T> {\r\n const removed: Array<T> = [];\r\n let i = 0;\r\n\r\n while (i < array.length) {\r\n if (predicate(array[i])) {\r\n removed.push(array[i]);\r\n array.splice(i, 1); // muta el array\r\n } else {\r\n i++;\r\n }\r\n }\r\n\r\n return removed;\r\n}"]}
1
+ {"version":3,"file":"array.js","sourceRoot":"","sources":["../../src/array.ts"],"names":[],"mappings":";;AAUA,oBAWC;AASD,sBAOC;AAOD,sBAEC;AAQD,wBAcC;AAUD,oCAMC;AAlFD;;;;;;;GAOG;AACH,SAAgB,IAAI,CAAI,KAAe,EAAE,GAAG,KAAe;IAEvD,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACvB,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAClC,IAAI,KAAK,KAAK,CAAC,CAAC,EAAE,CAAC;YACf,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;YACvB,MAAM,EAAE,CAAC;QACb,CAAC;IACL,CAAC;IACD,OAAO,MAAM,CAAC;AAClB,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,KAAK,CAAI,KAAe,EAAE,IAAY;IAClD,IAAI,IAAI,IAAI,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;IAC9D,MAAM,MAAM,GAAoB,EAAE,CAAC;IACnC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC;QAC1C,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;IAC1C,CAAC;IACD,OAAO,MAAM,CAAC;AAClB,CAAC;AAED;;;;GAIG;AACH,SAAgB,KAAK,CAAI,KAAe;IACpC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;AACrB,CAAC;AAED;;;;;GAKG;AACH,SAAgB,MAAM,CAAI,KAAe,EAAC,SAAuB;IAC7D,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,IAAI,CAAC,GAAG,CAAC,CAAC;IAEV,OAAO,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;QACtB,IAAI,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YACtB,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;YACvB,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,gBAAgB;QACxC,CAAC;aAAM,CAAC;YACJ,CAAC,EAAE,CAAC;QACR,CAAC;IACL,CAAC;IAED,OAAO,OAAO,CAAC;AACnB,CAAC;AAED;;;;;;;GAOG;AACH,SAAgB,YAAY,CAAI,KAAe,EAAE,OAAU;IACvD,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;QAC3B,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACpB,OAAO,IAAI,CAAC;IAChB,CAAC;IACD,OAAO,KAAK,CAAC;AACjB,CAAC","sourcesContent":["import type {Predicate} from \"./types.js\";\r\n\r\n/**\r\n * Removes all given values from the provided array and returns the number of removed elements.\r\n * The operation mutates the original array.\r\n * @template T\r\n * @param {Array<T>} array - The array to modify by removing specified items.\r\n * @param {...T} items - The values to remove from the array.\r\n * @return {number} The number of elements removed from the array.\r\n */\r\nexport function pull<T>(array: Array<T>, ...items: Array<T>): number {\r\n\r\n let output = 0;\r\n for (const item of items) {\r\n const index = array.indexOf(item);\r\n if (index !== -1) {\r\n array.splice(index, 1);\r\n output++;\r\n }\r\n }\r\n return output;\r\n}\r\n\r\n/**\r\n * Splits an array into chunks of a given size.\r\n * @template T\r\n * @param {Array<T>} array - The array to split.\r\n * @param {number} size - The size of each chunk.\r\n * @return {Array<Array<T>>} The array of chunks.\r\n */\r\nexport function chunk<T>(array: Array<T>, size: number): Array<Array<T>> {\r\n if (size <= 0) throw new Error(\"Size must be greater than 0\");\r\n const result: Array<Array<T>> = [];\r\n for (let i = 0; i < array.length; i += size) {\r\n result.push(array.slice(i, i + size));\r\n }\r\n return result;\r\n}\r\n\r\n/**\r\n * Removes all elements from the array, mutating it.\r\n * @template T\r\n * @param {Array<T>} array - The array to clear.\r\n */\r\nexport function clear<T>(array: Array<T>): void {\r\n array.length = 0;\r\n}\r\n\r\n/**\r\n * Removes all elements from the array that satisfy the predicate.\r\n * The operation mutates the original array.\r\n * @template T\r\n * @return {Array<T>} An array of removed elements.\r\n */\r\nexport function remove<T>(array: Array<T>,predicate: Predicate<T>): Array<T> {\r\n const removed: Array<T> = [];\r\n let i = 0;\r\n\r\n while (i < array.length) {\r\n if (predicate(array[i])) {\r\n removed.push(array[i]);\r\n array.splice(i, 1); // muta el array\r\n } else {\r\n i++;\r\n }\r\n }\r\n\r\n return removed;\r\n}\r\n\r\n/**\r\n * Adds an element to the array if it's not already present.\r\n * The operation mutates the original array.\r\n * @template T\r\n * @param {Array<T>} array - The array to modify.\r\n * @param {T} element - The element to add if absent.\r\n * @return {boolean} True if the element was added, false otherwise.\r\n */\r\nexport function pushIfAbsent<T>(array: Array<T>, element: T): boolean {\r\n if (!array.includes(element)) {\r\n array.push(element);\r\n return true;\r\n }\r\n return false;\r\n}"]}
package/dist/cjs/index.js CHANGED
@@ -18,7 +18,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
18
18
  return (mod && mod.__esModule) ? mod : { "default": mod };
19
19
  };
20
20
  Object.defineProperty(exports, "__esModule", { value: true });
21
- exports.formToObject = exports.submitForm = exports.ajaxSubmission = exports.ajaxSubmit = exports.CleanURLSearchParams = exports.draft = exports.Event = exports.EventBus = exports.from = exports.Lazy = exports.AsyncPoolExecutor = exports.Stopwatch = exports.TimeSpan = exports.Timer = exports.Order = exports.KeyValuePair = exports.CancellablePromise = exports.TypeCode = exports.Type = void 0;
21
+ exports.formToObject = exports.submitForm = exports.ajaxSubmission = exports.ajaxSubmit = exports.CleanURLSearchParams = exports.draft = exports.Range = exports.Event = exports.EventBus = exports.from = exports.Lazy = exports.AsyncPoolExecutor = exports.Stopwatch = exports.TimeSpan = exports.Timer = exports.Order = exports.KeyValuePair = exports.CancellablePromise = exports.TypeCode = exports.Type = void 0;
22
22
  // ─── Types ───────────────────────────────────────────
23
23
  __exportStar(require("./types.js"), exports);
24
24
  var type_js_1 = require("./type.js");
@@ -53,6 +53,8 @@ Object.defineProperty(exports, "from", { enumerable: true, get: function () { re
53
53
  var event_bus_js_1 = require("./event-bus.js");
54
54
  Object.defineProperty(exports, "EventBus", { enumerable: true, get: function () { return event_bus_js_1.EventBus; } });
55
55
  Object.defineProperty(exports, "Event", { enumerable: true, get: function () { return event_bus_js_1.Event; } });
56
+ var range_js_1 = require("./range.js");
57
+ Object.defineProperty(exports, "Range", { enumerable: true, get: function () { return __importDefault(range_js_1).default; } });
56
58
  // ─── Draft ────────────────────────────────────────
57
59
  var draft_js_1 = require("./draft.js");
58
60
  Object.defineProperty(exports, "draft", { enumerable: true, get: function () { return __importDefault(draft_js_1).default; } });
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";AAAA,eAAe;;;;;;;;;;;;;;;;;;;;AAEf,wDAAwD;AACxD,6CAA2B;AAC3B,qCAA0C;AAAlC,gHAAA,OAAO,OAAQ;AACvB,+CAAmD;AAA3C,yHAAA,OAAO,OAAY;AAE3B,wDAAwD;AACxD,iDAA+B;AAC/B,8CAA4B;AAC5B,4CAA0B;AAC1B,mEAAuE;AAA/D,6IAAA,OAAO,OAAsB;AAErC,uDAAuD;AACvD,yDAA4D;AAApD,kIAAA,OAAO,OAAgB;AAC/B,uCAA4C;AAApC,kHAAA,OAAO,OAAS;AAExB,uDAAuD;AACvD,uCAA4C;AAApC,kHAAA,OAAO,OAAS;AACxB,6CAAkD;AAA1C,wHAAA,OAAO,OAAY;AAC3B,+CAAoD;AAA5C,0HAAA,OAAO,OAAa;AAC5B,mEAAsE;AAA9D,4IAAA,OAAO,OAAqB;AAEpC,wDAAwD;AACxD,qCAA0C;AAAlC,gHAAA,OAAO,OAAQ;AACvB,iDAAsD;AAA9C,gHAAA,OAAO,OAAQ;AACvB,+CAA+C;AAAvC,wGAAA,QAAQ,OAAA;AAAE,qGAAA,KAAK,OAAA;AAEvB,qDAAqD;AACrD,uCAA4C;AAApC,kHAAA,OAAO,OAAS;AAExB,wDAAwD;AACxD,2EAA6E;AAArE,mJAAA,OAAO,OAAwB;AACvC,mBAAmB;AACnB,+CAAwF;AAAhF,sGAAA,UAAU,OAAA;AAAE,0GAAA,cAAc,OAAA;AAAE,sGAAA,UAAU,OAAA;AAAE,wGAAA,YAAY,OAAA;AAI5D,wDAAwD;AACxD,mBAAmB;AACnB,6CAA2B;AAC3B,mBAAmB;AACnB,yDAAuC","sourcesContent":["// src/index.ts\r\n\r\n// ─── Types ───────────────────────────────────────────\r\nexport * from './types.js';\r\nexport {default as Type} from './type.js';\r\nexport {default as TypeCode} from './type-code.js';\r\n\r\n// ─── Utilities ───────────────────────────────────────\r\nexport * from './utilities.js';\r\nexport * from './string.js';\r\nexport * from './math.js';\r\nexport {default as CancellablePromise} from \"./cancellable-promise.js\";\r\n\r\n// ─── Data Structures ────────────────────────────────\r\nexport {default as KeyValuePair} from './key-value-pair.js';\r\nexport {default as Order} from './order.js';\r\n\r\n// ─── Async & Timing ─────────────────────────────────\r\nexport {default as Timer} from './timer.js';\r\nexport {default as TimeSpan} from './timespan.js';\r\nexport {default as Stopwatch} from './stopwatch.js';\r\nexport {default as AsyncPoolExecutor} from './async-pool-executor.js';\r\n\r\n// ─── Patterns ────────────────────────────────────────\r\nexport {default as Lazy} from './lazy.js';\r\nexport {default as from} from './collections/from.js';\r\nexport {EventBus, Event} from './event-bus.js';\r\n\r\n// ─── Draft ────────────────────────────────────────\r\nexport {default as draft} from './draft.js';\r\n\r\n// ─── Web ─────────────────────────────────────────────\r\nexport {default as CleanURLSearchParams} from './clean-url-search-params.js';\r\n/** @deprecated */\r\nexport {ajaxSubmit, ajaxSubmission, submitForm, formToObject} from './browser/index.js';\r\n\r\n\r\n\r\n// ─── Deprecated ──────────────────────────────────────\r\n/** @deprecated */\r\nexport * from './array.js';\r\n/** @deprecated */\r\nexport * from './collections/index.js';"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";AAAA,eAAe;;;;;;;;;;;;;;;;;;;;AAEf,wDAAwD;AACxD,6CAA2B;AAC3B,qCAA0C;AAAlC,gHAAA,OAAO,OAAQ;AACvB,+CAAmD;AAA3C,yHAAA,OAAO,OAAY;AAE3B,wDAAwD;AACxD,iDAA+B;AAC/B,8CAA4B;AAC5B,4CAA0B;AAC1B,mEAAuE;AAA/D,6IAAA,OAAO,OAAsB;AAErC,uDAAuD;AACvD,yDAA4D;AAApD,kIAAA,OAAO,OAAgB;AAC/B,uCAA4C;AAApC,kHAAA,OAAO,OAAS;AAExB,uDAAuD;AACvD,uCAA4C;AAApC,kHAAA,OAAO,OAAS;AACxB,6CAAkD;AAA1C,wHAAA,OAAO,OAAY;AAC3B,+CAAoD;AAA5C,0HAAA,OAAO,OAAa;AAC5B,mEAAsE;AAA9D,4IAAA,OAAO,OAAqB;AAEpC,wDAAwD;AACxD,qCAA0C;AAAlC,gHAAA,OAAO,OAAQ;AACvB,iDAAsD;AAA9C,gHAAA,OAAO,OAAQ;AACvB,+CAA+C;AAAvC,wGAAA,QAAQ,OAAA;AAAE,qGAAA,KAAK,OAAA;AACvB,uCAA4C;AAApC,kHAAA,OAAO,OAAS;AAExB,qDAAqD;AACrD,uCAA4C;AAApC,kHAAA,OAAO,OAAS;AAExB,wDAAwD;AACxD,2EAA6E;AAArE,mJAAA,OAAO,OAAwB;AACvC,mBAAmB;AACnB,+CAAwF;AAAhF,sGAAA,UAAU,OAAA;AAAE,0GAAA,cAAc,OAAA;AAAE,sGAAA,UAAU,OAAA;AAAE,wGAAA,YAAY,OAAA;AAI5D,wDAAwD;AACxD,mBAAmB;AACnB,6CAA2B;AAC3B,mBAAmB;AACnB,yDAAuC","sourcesContent":["// src/index.ts\n\n// ─── Types ───────────────────────────────────────────\nexport * from './types.js';\nexport {default as Type} from './type.js';\nexport {default as TypeCode} from './type-code.js';\n\n// ─── Utilities ───────────────────────────────────────\nexport * from './utilities.js';\nexport * from './string.js';\nexport * from './math.js';\nexport {default as CancellablePromise} from \"./cancellable-promise.js\";\n\n// ─── Data Structures ────────────────────────────────\nexport {default as KeyValuePair} from './key-value-pair.js';\nexport {default as Order} from './order.js';\n\n// ─── Async & Timing ─────────────────────────────────\nexport {default as Timer} from './timer.js';\nexport {default as TimeSpan} from './timespan.js';\nexport {default as Stopwatch} from './stopwatch.js';\nexport {default as AsyncPoolExecutor} from './async-pool-executor.js';\n\n// ─── Patterns ────────────────────────────────────────\nexport {default as Lazy} from './lazy.js';\nexport {default as from} from './collections/from.js';\nexport {EventBus, Event} from './event-bus.js';\nexport {default as Range} from './range.js';\n\n// ─── Draft ────────────────────────────────────────\nexport {default as draft} from './draft.js';\n\n// ─── Web ─────────────────────────────────────────────\nexport {default as CleanURLSearchParams} from './clean-url-search-params.js';\n/** @deprecated */\nexport {ajaxSubmit, ajaxSubmission, submitForm, formToObject} from './browser/index.js';\n\n\n\n// ─── Deprecated ──────────────────────────────────────\n/** @deprecated */\nexport * from './array.js';\n/** @deprecated */\nexport * from './collections/index.js';"]}
@@ -0,0 +1,154 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ class Range {
4
+ /**
5
+ * Range constructor.
6
+ * @param start
7
+ * @param end
8
+ */
9
+ constructor(start, end) {
10
+ this.start = start;
11
+ this.end = end;
12
+ }
13
+ /**
14
+ * Finds the intersection between two ranges.
15
+ *
16
+ * @param other The Range object to intersect with.
17
+ * @returns The intersected Range object, or null if there is no intersection.
18
+ */
19
+ intersect(other) {
20
+ const start = (this.start > other.start) ? this.start : other.start;
21
+ const end = (this.end < other.end) ? this.end : other.end;
22
+ if (start < end) {
23
+ return new Range(start, end);
24
+ }
25
+ else {
26
+ return null;
27
+ }
28
+ }
29
+ /**
30
+ * Subtract the given range from this range.
31
+ *
32
+ * @param other The range to subtract from this range.
33
+ * @returns An array of Range objects representing the result of the subtraction.
34
+ */
35
+ subtract(other) {
36
+ const result = [];
37
+ if (this.start >= other.end || this.end <= other.start) {
38
+ result.push(new Range(this.start, this.end));
39
+ }
40
+ else if (other.start <= this.start && other.end >= this.end) {
41
+ return result;
42
+ }
43
+ else {
44
+ if (this.start < other.start) {
45
+ result.push(new Range(this.start, other.start));
46
+ }
47
+ if (this.end > other.end) {
48
+ result.push(new Range(other.end, this.end));
49
+ }
50
+ }
51
+ return result;
52
+ }
53
+ /**
54
+ * Determines if the given range overlaps with the current range.
55
+ *
56
+ * @param other The range to be checked for overlap.
57
+ * @returns Returns true if there is an overlap between the ranges, false otherwise.
58
+ */
59
+ overlaps(other) {
60
+ const s1 = this.start;
61
+ const e1 = this.end;
62
+ const s2 = other.start;
63
+ const e2 = other.end;
64
+ return (s2 > s1 && s2 < e1 || e2 > s1 && e2 < e1) ||
65
+ (s1 > s2 && s1 < e2 || e1 > s2 && e1 < e2) ||
66
+ (s1 === s2 && e1 === e2);
67
+ }
68
+ /**
69
+ * Determines whether the specified value is within the range defined by the start and end values.
70
+ *
71
+ * @param obj The value to check if it is within the range.
72
+ * @param inclusive Optional. If set to true, the range boundaries are considered inclusive.
73
+ * @returns Returns true if the specified value is within the range, false otherwise.
74
+ */
75
+ contains(obj, inclusive = true) {
76
+ return inclusive ?
77
+ (this.start <= obj && this.end >= obj) :
78
+ (this.start < obj && this.end > obj);
79
+ }
80
+ /**
81
+ * @returns T
82
+ */
83
+ getStart() {
84
+ return this.start;
85
+ }
86
+ /**
87
+ * @returns T
88
+ */
89
+ getEnd() {
90
+ return this.end;
91
+ }
92
+ /**
93
+ * Finds the intersection between two sets of ranges.
94
+ *
95
+ * @param ranges1
96
+ * @param ranges2
97
+ * @returns
98
+ */
99
+ static intersectRanges(ranges1, ranges2) {
100
+ const result = [];
101
+ for (const r1 of ranges1) {
102
+ for (const r2 of ranges2) {
103
+ const intersection = r1.intersect(r2);
104
+ if (intersection !== null) {
105
+ result.push(intersection);
106
+ }
107
+ }
108
+ }
109
+ return result;
110
+ }
111
+ /**
112
+ * Determines if any range in the first set overlaps with any range in the second set.
113
+ *
114
+ * @param ranges1
115
+ * @param ranges2
116
+ * @returns
117
+ */
118
+ static overlapsAny(ranges1, ranges2) {
119
+ for (const r1 of ranges1) {
120
+ for (const r2 of ranges2) {
121
+ if (r1.overlaps(r2)) {
122
+ return true;
123
+ }
124
+ }
125
+ }
126
+ return false;
127
+ }
128
+ /**
129
+ * Subtracts the second set of ranges from the first set of ranges.
130
+ *
131
+ * @param ranges1
132
+ * @param ranges2
133
+ * @returns
134
+ */
135
+ static subtractRanges(ranges1, ranges2) {
136
+ let currentRanges = ranges1;
137
+ for (const r2 of ranges2) {
138
+ const nextRanges = [];
139
+ for (const r1 of currentRanges) {
140
+ const subtracted = r1.subtract(r2);
141
+ for (const s of subtracted) {
142
+ nextRanges.push(s);
143
+ }
144
+ }
145
+ currentRanges = nextRanges;
146
+ if (currentRanges.length === 0) {
147
+ break;
148
+ }
149
+ }
150
+ return currentRanges;
151
+ }
152
+ }
153
+ exports.default = Range;
154
+ //# sourceMappingURL=range.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"range.js","sourceRoot":"","sources":["../../src/range.ts"],"names":[],"mappings":"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","sourcesContent":["export default class Range<T> {\n\n private readonly start: T;\n private readonly end: T;\n\n /**\n * Range constructor.\n * @param start\n * @param end\n */\n constructor(start: T, end: T) {\n this.start = start;\n this.end = end;\n }\n\n /**\n * Finds the intersection between two ranges.\n *\n * @param other The Range object to intersect with.\n * @returns The intersected Range object, or null if there is no intersection.\n */\n public intersect(other: Range<T>): Range<T> | null {\n const start = (this.start > other.start) ? this.start : other.start;\n const end = (this.end < other.end) ? this.end : other.end;\n\n if (start < end) {\n return new Range(start, end);\n } else {\n return null;\n }\n }\n\n /**\n * Subtract the given range from this range.\n *\n * @param other The range to subtract from this range.\n * @returns An array of Range objects representing the result of the subtraction.\n */\n public subtract(other: Range<T>): Range<T>[] {\n const result: Range<T>[] = [];\n\n if (this.start >= other.end || this.end <= other.start) {\n result.push(new Range(this.start, this.end));\n } else if (other.start <= this.start && other.end >= this.end) {\n return result;\n } else {\n if (this.start < other.start) {\n result.push(new Range(this.start, other.start));\n }\n\n if (this.end > other.end) {\n result.push(new Range(other.end, this.end));\n }\n }\n\n return result;\n }\n\n /**\n * Determines if the given range overlaps with the current range.\n *\n * @param other The range to be checked for overlap.\n * @returns Returns true if there is an overlap between the ranges, false otherwise.\n */\n public overlaps(other: Range<T>): boolean {\n const s1 = this.start;\n const e1 = this.end;\n const s2 = other.start;\n const e2 = other.end;\n\n return (s2 > s1 && s2 < e1 || e2 > s1 && e2 < e1) ||\n (s1 > s2 && s1 < e2 || e1 > s2 && e1 < e2) ||\n (s1 === s2 && e1 === e2);\n }\n\n /**\n * Determines whether the specified value is within the range defined by the start and end values.\n *\n * @param obj The value to check if it is within the range.\n * @param inclusive Optional. If set to true, the range boundaries are considered inclusive.\n * @returns Returns true if the specified value is within the range, false otherwise.\n */\n public contains(obj: T, inclusive: boolean = true): boolean {\n return inclusive ?\n (this.start <= obj && this.end >= obj) :\n (this.start < obj && this.end > obj);\n }\n\n /**\n * @returns T\n */\n public getStart(): T {\n return this.start;\n }\n\n /**\n * @returns T\n */\n public getEnd(): T {\n return this.end;\n }\n\n /**\n * Finds the intersection between two sets of ranges.\n *\n * @param ranges1\n * @param ranges2\n * @returns\n */\n public static intersectRanges<T>(ranges1: Range<T>[], ranges2: Range<T>[]): Range<T>[] {\n const result: Range<T>[] = [];\n for (const r1 of ranges1) {\n for (const r2 of ranges2) {\n const intersection = r1.intersect(r2);\n if (intersection !== null) {\n result.push(intersection);\n }\n }\n }\n return result;\n }\n\n /**\n * Determines if any range in the first set overlaps with any range in the second set.\n *\n * @param ranges1\n * @param ranges2\n * @returns\n */\n public static overlapsAny<T>(ranges1: Range<T>[], ranges2: Range<T>[]): boolean {\n for (const r1 of ranges1) {\n for (const r2 of ranges2) {\n if (r1.overlaps(r2)) {\n return true;\n }\n }\n }\n return false;\n }\n\n /**\n * Subtracts the second set of ranges from the first set of ranges.\n *\n * @param ranges1\n * @param ranges2\n * @returns\n */\n public static subtractRanges<T>(ranges1: Range<T>[], ranges2: Range<T>[]): Range<T>[] {\n let currentRanges = ranges1;\n for (const r2 of ranges2) {\n const nextRanges: Range<T>[] = [];\n for (const r1 of currentRanges) {\n const subtracted = r1.subtract(r2);\n for (const s of subtracted) {\n nextRanges.push(s);\n }\n }\n currentRanges = nextRanges;\n if (currentRanges.length === 0) {\n break;\n }\n }\n return currentRanges;\n }\n}\n"]}
package/dist/esm/array.js CHANGED
@@ -61,4 +61,19 @@ export function remove(array, predicate) {
61
61
  }
62
62
  return removed;
63
63
  }
64
+ /**
65
+ * Adds an element to the array if it's not already present.
66
+ * The operation mutates the original array.
67
+ * @template T
68
+ * @param {Array<T>} array - The array to modify.
69
+ * @param {T} element - The element to add if absent.
70
+ * @return {boolean} True if the element was added, false otherwise.
71
+ */
72
+ export function pushIfAbsent(array, element) {
73
+ if (!array.includes(element)) {
74
+ array.push(element);
75
+ return true;
76
+ }
77
+ return false;
78
+ }
64
79
  //# sourceMappingURL=array.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"array.js","sourceRoot":"","sources":["../../src/array.ts"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AACH,MAAM,UAAU,IAAI,CAAI,KAAe,EAAE,GAAG,KAAe;IAEvD,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACvB,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAClC,IAAI,KAAK,KAAK,CAAC,CAAC,EAAE,CAAC;YACf,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;YACvB,MAAM,EAAE,CAAC;QACb,CAAC;IACL,CAAC;IACD,OAAO,MAAM,CAAC;AAClB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,KAAK,CAAI,KAAe,EAAE,IAAY;IAClD,IAAI,IAAI,IAAI,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;IAC9D,MAAM,MAAM,GAAoB,EAAE,CAAC;IACnC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC;QAC1C,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;IAC1C,CAAC;IACD,OAAO,MAAM,CAAC;AAClB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,KAAK,CAAI,KAAe;IACpC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;AACrB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,MAAM,CAAI,KAAe,EAAC,SAAuB;IAC7D,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,IAAI,CAAC,GAAG,CAAC,CAAC;IAEV,OAAO,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;QACtB,IAAI,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YACtB,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;YACvB,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,gBAAgB;QACxC,CAAC;aAAM,CAAC;YACJ,CAAC,EAAE,CAAC;QACR,CAAC;IACL,CAAC;IAED,OAAO,OAAO,CAAC;AACnB,CAAC","sourcesContent":["import type {Predicate} from \"./types.js\";\r\n\r\n/**\r\n * Removes all given values from the provided array and returns the number of removed elements.\r\n * The operation mutates the original array.\r\n * @template T\r\n * @param {Array<T>} array - The array to modify by removing specified items.\r\n * @param {...T} items - The values to remove from the array.\r\n * @return {number} The number of elements removed from the array.\r\n */\r\nexport function pull<T>(array: Array<T>, ...items: Array<T>): number {\r\n\r\n let output = 0;\r\n for (const item of items) {\r\n const index = array.indexOf(item);\r\n if (index !== -1) {\r\n array.splice(index, 1);\r\n output++;\r\n }\r\n }\r\n return output;\r\n}\r\n\r\n/**\r\n * Splits an array into chunks of a given size.\r\n * @template T\r\n * @param {Array<T>} array - The array to split.\r\n * @param {number} size - The size of each chunk.\r\n * @return {Array<Array<T>>} The array of chunks.\r\n */\r\nexport function chunk<T>(array: Array<T>, size: number): Array<Array<T>> {\r\n if (size <= 0) throw new Error(\"Size must be greater than 0\");\r\n const result: Array<Array<T>> = [];\r\n for (let i = 0; i < array.length; i += size) {\r\n result.push(array.slice(i, i + size));\r\n }\r\n return result;\r\n}\r\n\r\n/**\r\n * Removes all elements from the array, mutating it.\r\n * @template T\r\n * @param {Array<T>} array - The array to clear.\r\n */\r\nexport function clear<T>(array: Array<T>): void {\r\n array.length = 0;\r\n}\r\n\r\n/**\r\n * Removes all elements from the array that satisfy the predicate.\r\n * The operation mutates the original array.\r\n * @template T\r\n * @return {Array<T>} An array of removed elements.\r\n */\r\nexport function remove<T>(array: Array<T>,predicate: Predicate<T>): Array<T> {\r\n const removed: Array<T> = [];\r\n let i = 0;\r\n\r\n while (i < array.length) {\r\n if (predicate(array[i])) {\r\n removed.push(array[i]);\r\n array.splice(i, 1); // muta el array\r\n } else {\r\n i++;\r\n }\r\n }\r\n\r\n return removed;\r\n}"]}
1
+ {"version":3,"file":"array.js","sourceRoot":"","sources":["../../src/array.ts"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AACH,MAAM,UAAU,IAAI,CAAI,KAAe,EAAE,GAAG,KAAe;IAEvD,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACvB,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAClC,IAAI,KAAK,KAAK,CAAC,CAAC,EAAE,CAAC;YACf,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;YACvB,MAAM,EAAE,CAAC;QACb,CAAC;IACL,CAAC;IACD,OAAO,MAAM,CAAC;AAClB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,KAAK,CAAI,KAAe,EAAE,IAAY;IAClD,IAAI,IAAI,IAAI,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;IAC9D,MAAM,MAAM,GAAoB,EAAE,CAAC;IACnC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC;QAC1C,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;IAC1C,CAAC;IACD,OAAO,MAAM,CAAC;AAClB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,KAAK,CAAI,KAAe;IACpC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;AACrB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,MAAM,CAAI,KAAe,EAAC,SAAuB;IAC7D,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,IAAI,CAAC,GAAG,CAAC,CAAC;IAEV,OAAO,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;QACtB,IAAI,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YACtB,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;YACvB,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,gBAAgB;QACxC,CAAC;aAAM,CAAC;YACJ,CAAC,EAAE,CAAC;QACR,CAAC;IACL,CAAC;IAED,OAAO,OAAO,CAAC;AACnB,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,YAAY,CAAI,KAAe,EAAE,OAAU;IACvD,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;QAC3B,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACpB,OAAO,IAAI,CAAC;IAChB,CAAC;IACD,OAAO,KAAK,CAAC;AACjB,CAAC","sourcesContent":["import type {Predicate} from \"./types.js\";\r\n\r\n/**\r\n * Removes all given values from the provided array and returns the number of removed elements.\r\n * The operation mutates the original array.\r\n * @template T\r\n * @param {Array<T>} array - The array to modify by removing specified items.\r\n * @param {...T} items - The values to remove from the array.\r\n * @return {number} The number of elements removed from the array.\r\n */\r\nexport function pull<T>(array: Array<T>, ...items: Array<T>): number {\r\n\r\n let output = 0;\r\n for (const item of items) {\r\n const index = array.indexOf(item);\r\n if (index !== -1) {\r\n array.splice(index, 1);\r\n output++;\r\n }\r\n }\r\n return output;\r\n}\r\n\r\n/**\r\n * Splits an array into chunks of a given size.\r\n * @template T\r\n * @param {Array<T>} array - The array to split.\r\n * @param {number} size - The size of each chunk.\r\n * @return {Array<Array<T>>} The array of chunks.\r\n */\r\nexport function chunk<T>(array: Array<T>, size: number): Array<Array<T>> {\r\n if (size <= 0) throw new Error(\"Size must be greater than 0\");\r\n const result: Array<Array<T>> = [];\r\n for (let i = 0; i < array.length; i += size) {\r\n result.push(array.slice(i, i + size));\r\n }\r\n return result;\r\n}\r\n\r\n/**\r\n * Removes all elements from the array, mutating it.\r\n * @template T\r\n * @param {Array<T>} array - The array to clear.\r\n */\r\nexport function clear<T>(array: Array<T>): void {\r\n array.length = 0;\r\n}\r\n\r\n/**\r\n * Removes all elements from the array that satisfy the predicate.\r\n * The operation mutates the original array.\r\n * @template T\r\n * @return {Array<T>} An array of removed elements.\r\n */\r\nexport function remove<T>(array: Array<T>,predicate: Predicate<T>): Array<T> {\r\n const removed: Array<T> = [];\r\n let i = 0;\r\n\r\n while (i < array.length) {\r\n if (predicate(array[i])) {\r\n removed.push(array[i]);\r\n array.splice(i, 1); // muta el array\r\n } else {\r\n i++;\r\n }\r\n }\r\n\r\n return removed;\r\n}\r\n\r\n/**\r\n * Adds an element to the array if it's not already present.\r\n * The operation mutates the original array.\r\n * @template T\r\n * @param {Array<T>} array - The array to modify.\r\n * @param {T} element - The element to add if absent.\r\n * @return {boolean} True if the element was added, false otherwise.\r\n */\r\nexport function pushIfAbsent<T>(array: Array<T>, element: T): boolean {\r\n if (!array.includes(element)) {\r\n array.push(element);\r\n return true;\r\n }\r\n return false;\r\n}"]}
package/dist/esm/index.js CHANGED
@@ -20,6 +20,7 @@ export { default as AsyncPoolExecutor } from './async-pool-executor.js';
20
20
  export { default as Lazy } from './lazy.js';
21
21
  export { default as from } from './collections/from.js';
22
22
  export { EventBus, Event } from './event-bus.js';
23
+ export { default as Range } from './range.js';
23
24
  // ─── Draft ────────────────────────────────────────
24
25
  export { default as draft } from './draft.js';
25
26
  // ─── Web ─────────────────────────────────────────────
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,eAAe;AAEf,wDAAwD;AACxD,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAC,OAAO,IAAI,IAAI,EAAC,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAC,OAAO,IAAI,QAAQ,EAAC,MAAM,gBAAgB,CAAC;AAEnD,wDAAwD;AACxD,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,OAAO,EAAC,OAAO,IAAI,kBAAkB,EAAC,MAAM,0BAA0B,CAAC;AAEvE,uDAAuD;AACvD,OAAO,EAAC,OAAO,IAAI,YAAY,EAAC,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAC,OAAO,IAAI,KAAK,EAAC,MAAM,YAAY,CAAC;AAE5C,uDAAuD;AACvD,OAAO,EAAC,OAAO,IAAI,KAAK,EAAC,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAC,OAAO,IAAI,QAAQ,EAAC,MAAM,eAAe,CAAC;AAClD,OAAO,EAAC,OAAO,IAAI,SAAS,EAAC,MAAM,gBAAgB,CAAC;AACpD,OAAO,EAAC,OAAO,IAAI,iBAAiB,EAAC,MAAM,0BAA0B,CAAC;AAEtE,wDAAwD;AACxD,OAAO,EAAC,OAAO,IAAI,IAAI,EAAC,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAC,OAAO,IAAI,IAAI,EAAC,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAC,QAAQ,EAAE,KAAK,EAAC,MAAM,gBAAgB,CAAC;AAE/C,qDAAqD;AACrD,OAAO,EAAC,OAAO,IAAI,KAAK,EAAC,MAAM,YAAY,CAAC;AAE5C,wDAAwD;AACxD,OAAO,EAAC,OAAO,IAAI,oBAAoB,EAAC,MAAM,8BAA8B,CAAC;AAC7E,mBAAmB;AACnB,OAAO,EAAC,UAAU,EAAE,cAAc,EAAE,UAAU,EAAE,YAAY,EAAC,MAAM,oBAAoB,CAAC;AAIxF,wDAAwD;AACxD,mBAAmB;AACnB,cAAc,YAAY,CAAC;AAC3B,mBAAmB;AACnB,cAAc,wBAAwB,CAAC","sourcesContent":["// src/index.ts\r\n\r\n// ─── Types ───────────────────────────────────────────\r\nexport * from './types.js';\r\nexport {default as Type} from './type.js';\r\nexport {default as TypeCode} from './type-code.js';\r\n\r\n// ─── Utilities ───────────────────────────────────────\r\nexport * from './utilities.js';\r\nexport * from './string.js';\r\nexport * from './math.js';\r\nexport {default as CancellablePromise} from \"./cancellable-promise.js\";\r\n\r\n// ─── Data Structures ────────────────────────────────\r\nexport {default as KeyValuePair} from './key-value-pair.js';\r\nexport {default as Order} from './order.js';\r\n\r\n// ─── Async & Timing ─────────────────────────────────\r\nexport {default as Timer} from './timer.js';\r\nexport {default as TimeSpan} from './timespan.js';\r\nexport {default as Stopwatch} from './stopwatch.js';\r\nexport {default as AsyncPoolExecutor} from './async-pool-executor.js';\r\n\r\n// ─── Patterns ────────────────────────────────────────\r\nexport {default as Lazy} from './lazy.js';\r\nexport {default as from} from './collections/from.js';\r\nexport {EventBus, Event} from './event-bus.js';\r\n\r\n// ─── Draft ────────────────────────────────────────\r\nexport {default as draft} from './draft.js';\r\n\r\n// ─── Web ─────────────────────────────────────────────\r\nexport {default as CleanURLSearchParams} from './clean-url-search-params.js';\r\n/** @deprecated */\r\nexport {ajaxSubmit, ajaxSubmission, submitForm, formToObject} from './browser/index.js';\r\n\r\n\r\n\r\n// ─── Deprecated ──────────────────────────────────────\r\n/** @deprecated */\r\nexport * from './array.js';\r\n/** @deprecated */\r\nexport * from './collections/index.js';"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,eAAe;AAEf,wDAAwD;AACxD,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAC,OAAO,IAAI,IAAI,EAAC,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAC,OAAO,IAAI,QAAQ,EAAC,MAAM,gBAAgB,CAAC;AAEnD,wDAAwD;AACxD,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,OAAO,EAAC,OAAO,IAAI,kBAAkB,EAAC,MAAM,0BAA0B,CAAC;AAEvE,uDAAuD;AACvD,OAAO,EAAC,OAAO,IAAI,YAAY,EAAC,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAC,OAAO,IAAI,KAAK,EAAC,MAAM,YAAY,CAAC;AAE5C,uDAAuD;AACvD,OAAO,EAAC,OAAO,IAAI,KAAK,EAAC,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAC,OAAO,IAAI,QAAQ,EAAC,MAAM,eAAe,CAAC;AAClD,OAAO,EAAC,OAAO,IAAI,SAAS,EAAC,MAAM,gBAAgB,CAAC;AACpD,OAAO,EAAC,OAAO,IAAI,iBAAiB,EAAC,MAAM,0BAA0B,CAAC;AAEtE,wDAAwD;AACxD,OAAO,EAAC,OAAO,IAAI,IAAI,EAAC,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAC,OAAO,IAAI,IAAI,EAAC,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAC,QAAQ,EAAE,KAAK,EAAC,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAC,OAAO,IAAI,KAAK,EAAC,MAAM,YAAY,CAAC;AAE5C,qDAAqD;AACrD,OAAO,EAAC,OAAO,IAAI,KAAK,EAAC,MAAM,YAAY,CAAC;AAE5C,wDAAwD;AACxD,OAAO,EAAC,OAAO,IAAI,oBAAoB,EAAC,MAAM,8BAA8B,CAAC;AAC7E,mBAAmB;AACnB,OAAO,EAAC,UAAU,EAAE,cAAc,EAAE,UAAU,EAAE,YAAY,EAAC,MAAM,oBAAoB,CAAC;AAIxF,wDAAwD;AACxD,mBAAmB;AACnB,cAAc,YAAY,CAAC;AAC3B,mBAAmB;AACnB,cAAc,wBAAwB,CAAC","sourcesContent":["// src/index.ts\n\n// ─── Types ───────────────────────────────────────────\nexport * from './types.js';\nexport {default as Type} from './type.js';\nexport {default as TypeCode} from './type-code.js';\n\n// ─── Utilities ───────────────────────────────────────\nexport * from './utilities.js';\nexport * from './string.js';\nexport * from './math.js';\nexport {default as CancellablePromise} from \"./cancellable-promise.js\";\n\n// ─── Data Structures ────────────────────────────────\nexport {default as KeyValuePair} from './key-value-pair.js';\nexport {default as Order} from './order.js';\n\n// ─── Async & Timing ─────────────────────────────────\nexport {default as Timer} from './timer.js';\nexport {default as TimeSpan} from './timespan.js';\nexport {default as Stopwatch} from './stopwatch.js';\nexport {default as AsyncPoolExecutor} from './async-pool-executor.js';\n\n// ─── Patterns ────────────────────────────────────────\nexport {default as Lazy} from './lazy.js';\nexport {default as from} from './collections/from.js';\nexport {EventBus, Event} from './event-bus.js';\nexport {default as Range} from './range.js';\n\n// ─── Draft ────────────────────────────────────────\nexport {default as draft} from './draft.js';\n\n// ─── Web ─────────────────────────────────────────────\nexport {default as CleanURLSearchParams} from './clean-url-search-params.js';\n/** @deprecated */\nexport {ajaxSubmit, ajaxSubmission, submitForm, formToObject} from './browser/index.js';\n\n\n\n// ─── Deprecated ──────────────────────────────────────\n/** @deprecated */\nexport * from './array.js';\n/** @deprecated */\nexport * from './collections/index.js';"]}
@@ -0,0 +1,151 @@
1
+ export default class Range {
2
+ /**
3
+ * Range constructor.
4
+ * @param start
5
+ * @param end
6
+ */
7
+ constructor(start, end) {
8
+ this.start = start;
9
+ this.end = end;
10
+ }
11
+ /**
12
+ * Finds the intersection between two ranges.
13
+ *
14
+ * @param other The Range object to intersect with.
15
+ * @returns The intersected Range object, or null if there is no intersection.
16
+ */
17
+ intersect(other) {
18
+ const start = (this.start > other.start) ? this.start : other.start;
19
+ const end = (this.end < other.end) ? this.end : other.end;
20
+ if (start < end) {
21
+ return new Range(start, end);
22
+ }
23
+ else {
24
+ return null;
25
+ }
26
+ }
27
+ /**
28
+ * Subtract the given range from this range.
29
+ *
30
+ * @param other The range to subtract from this range.
31
+ * @returns An array of Range objects representing the result of the subtraction.
32
+ */
33
+ subtract(other) {
34
+ const result = [];
35
+ if (this.start >= other.end || this.end <= other.start) {
36
+ result.push(new Range(this.start, this.end));
37
+ }
38
+ else if (other.start <= this.start && other.end >= this.end) {
39
+ return result;
40
+ }
41
+ else {
42
+ if (this.start < other.start) {
43
+ result.push(new Range(this.start, other.start));
44
+ }
45
+ if (this.end > other.end) {
46
+ result.push(new Range(other.end, this.end));
47
+ }
48
+ }
49
+ return result;
50
+ }
51
+ /**
52
+ * Determines if the given range overlaps with the current range.
53
+ *
54
+ * @param other The range to be checked for overlap.
55
+ * @returns Returns true if there is an overlap between the ranges, false otherwise.
56
+ */
57
+ overlaps(other) {
58
+ const s1 = this.start;
59
+ const e1 = this.end;
60
+ const s2 = other.start;
61
+ const e2 = other.end;
62
+ return (s2 > s1 && s2 < e1 || e2 > s1 && e2 < e1) ||
63
+ (s1 > s2 && s1 < e2 || e1 > s2 && e1 < e2) ||
64
+ (s1 === s2 && e1 === e2);
65
+ }
66
+ /**
67
+ * Determines whether the specified value is within the range defined by the start and end values.
68
+ *
69
+ * @param obj The value to check if it is within the range.
70
+ * @param inclusive Optional. If set to true, the range boundaries are considered inclusive.
71
+ * @returns Returns true if the specified value is within the range, false otherwise.
72
+ */
73
+ contains(obj, inclusive = true) {
74
+ return inclusive ?
75
+ (this.start <= obj && this.end >= obj) :
76
+ (this.start < obj && this.end > obj);
77
+ }
78
+ /**
79
+ * @returns T
80
+ */
81
+ getStart() {
82
+ return this.start;
83
+ }
84
+ /**
85
+ * @returns T
86
+ */
87
+ getEnd() {
88
+ return this.end;
89
+ }
90
+ /**
91
+ * Finds the intersection between two sets of ranges.
92
+ *
93
+ * @param ranges1
94
+ * @param ranges2
95
+ * @returns
96
+ */
97
+ static intersectRanges(ranges1, ranges2) {
98
+ const result = [];
99
+ for (const r1 of ranges1) {
100
+ for (const r2 of ranges2) {
101
+ const intersection = r1.intersect(r2);
102
+ if (intersection !== null) {
103
+ result.push(intersection);
104
+ }
105
+ }
106
+ }
107
+ return result;
108
+ }
109
+ /**
110
+ * Determines if any range in the first set overlaps with any range in the second set.
111
+ *
112
+ * @param ranges1
113
+ * @param ranges2
114
+ * @returns
115
+ */
116
+ static overlapsAny(ranges1, ranges2) {
117
+ for (const r1 of ranges1) {
118
+ for (const r2 of ranges2) {
119
+ if (r1.overlaps(r2)) {
120
+ return true;
121
+ }
122
+ }
123
+ }
124
+ return false;
125
+ }
126
+ /**
127
+ * Subtracts the second set of ranges from the first set of ranges.
128
+ *
129
+ * @param ranges1
130
+ * @param ranges2
131
+ * @returns
132
+ */
133
+ static subtractRanges(ranges1, ranges2) {
134
+ let currentRanges = ranges1;
135
+ for (const r2 of ranges2) {
136
+ const nextRanges = [];
137
+ for (const r1 of currentRanges) {
138
+ const subtracted = r1.subtract(r2);
139
+ for (const s of subtracted) {
140
+ nextRanges.push(s);
141
+ }
142
+ }
143
+ currentRanges = nextRanges;
144
+ if (currentRanges.length === 0) {
145
+ break;
146
+ }
147
+ }
148
+ return currentRanges;
149
+ }
150
+ }
151
+ //# sourceMappingURL=range.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"range.js","sourceRoot":"","sources":["../../src/range.ts"],"names":[],"mappings":"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","sourcesContent":["export default class Range<T> {\n\n private readonly start: T;\n private readonly end: T;\n\n /**\n * Range constructor.\n * @param start\n * @param end\n */\n constructor(start: T, end: T) {\n this.start = start;\n this.end = end;\n }\n\n /**\n * Finds the intersection between two ranges.\n *\n * @param other The Range object to intersect with.\n * @returns The intersected Range object, or null if there is no intersection.\n */\n public intersect(other: Range<T>): Range<T> | null {\n const start = (this.start > other.start) ? this.start : other.start;\n const end = (this.end < other.end) ? this.end : other.end;\n\n if (start < end) {\n return new Range(start, end);\n } else {\n return null;\n }\n }\n\n /**\n * Subtract the given range from this range.\n *\n * @param other The range to subtract from this range.\n * @returns An array of Range objects representing the result of the subtraction.\n */\n public subtract(other: Range<T>): Range<T>[] {\n const result: Range<T>[] = [];\n\n if (this.start >= other.end || this.end <= other.start) {\n result.push(new Range(this.start, this.end));\n } else if (other.start <= this.start && other.end >= this.end) {\n return result;\n } else {\n if (this.start < other.start) {\n result.push(new Range(this.start, other.start));\n }\n\n if (this.end > other.end) {\n result.push(new Range(other.end, this.end));\n }\n }\n\n return result;\n }\n\n /**\n * Determines if the given range overlaps with the current range.\n *\n * @param other The range to be checked for overlap.\n * @returns Returns true if there is an overlap between the ranges, false otherwise.\n */\n public overlaps(other: Range<T>): boolean {\n const s1 = this.start;\n const e1 = this.end;\n const s2 = other.start;\n const e2 = other.end;\n\n return (s2 > s1 && s2 < e1 || e2 > s1 && e2 < e1) ||\n (s1 > s2 && s1 < e2 || e1 > s2 && e1 < e2) ||\n (s1 === s2 && e1 === e2);\n }\n\n /**\n * Determines whether the specified value is within the range defined by the start and end values.\n *\n * @param obj The value to check if it is within the range.\n * @param inclusive Optional. If set to true, the range boundaries are considered inclusive.\n * @returns Returns true if the specified value is within the range, false otherwise.\n */\n public contains(obj: T, inclusive: boolean = true): boolean {\n return inclusive ?\n (this.start <= obj && this.end >= obj) :\n (this.start < obj && this.end > obj);\n }\n\n /**\n * @returns T\n */\n public getStart(): T {\n return this.start;\n }\n\n /**\n * @returns T\n */\n public getEnd(): T {\n return this.end;\n }\n\n /**\n * Finds the intersection between two sets of ranges.\n *\n * @param ranges1\n * @param ranges2\n * @returns\n */\n public static intersectRanges<T>(ranges1: Range<T>[], ranges2: Range<T>[]): Range<T>[] {\n const result: Range<T>[] = [];\n for (const r1 of ranges1) {\n for (const r2 of ranges2) {\n const intersection = r1.intersect(r2);\n if (intersection !== null) {\n result.push(intersection);\n }\n }\n }\n return result;\n }\n\n /**\n * Determines if any range in the first set overlaps with any range in the second set.\n *\n * @param ranges1\n * @param ranges2\n * @returns\n */\n public static overlapsAny<T>(ranges1: Range<T>[], ranges2: Range<T>[]): boolean {\n for (const r1 of ranges1) {\n for (const r2 of ranges2) {\n if (r1.overlaps(r2)) {\n return true;\n }\n }\n }\n return false;\n }\n\n /**\n * Subtracts the second set of ranges from the first set of ranges.\n *\n * @param ranges1\n * @param ranges2\n * @returns\n */\n public static subtractRanges<T>(ranges1: Range<T>[], ranges2: Range<T>[]): Range<T>[] {\n let currentRanges = ranges1;\n for (const r2 of ranges2) {\n const nextRanges: Range<T>[] = [];\n for (const r1 of currentRanges) {\n const subtracted = r1.subtract(r2);\n for (const s of subtracted) {\n nextRanges.push(s);\n }\n }\n currentRanges = nextRanges;\n if (currentRanges.length === 0) {\n break;\n }\n }\n return currentRanges;\n }\n}\n"]}
@@ -29,4 +29,13 @@ export declare function clear<T>(array: Array<T>): void;
29
29
  * @return {Array<T>} An array of removed elements.
30
30
  */
31
31
  export declare function remove<T>(array: Array<T>, predicate: Predicate<T>): Array<T>;
32
+ /**
33
+ * Adds an element to the array if it's not already present.
34
+ * The operation mutates the original array.
35
+ * @template T
36
+ * @param {Array<T>} array - The array to modify.
37
+ * @param {T} element - The element to add if absent.
38
+ * @return {boolean} True if the element was added, false otherwise.
39
+ */
40
+ export declare function pushIfAbsent<T>(array: Array<T>, element: T): boolean;
32
41
  //# sourceMappingURL=array.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"array.d.ts","sourceRoot":"","sources":["../../src/array.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,YAAY,CAAC;AAE1C;;;;;;;GAOG;AACH,wBAAgB,IAAI,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,MAAM,CAWnE;AAED;;;;;;GAMG;AACH,wBAAgB,KAAK,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAOvE;AAED;;;;GAIG;AACH,wBAAgB,KAAK,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,IAAI,CAE9C;AAED;;;;;GAKG;AACH,wBAAgB,MAAM,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,EAAC,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAc3E"}
1
+ {"version":3,"file":"array.d.ts","sourceRoot":"","sources":["../../src/array.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,YAAY,CAAC;AAE1C;;;;;;;GAOG;AACH,wBAAgB,IAAI,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,MAAM,CAWnE;AAED;;;;;;GAMG;AACH,wBAAgB,KAAK,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAOvE;AAED;;;;GAIG;AACH,wBAAgB,KAAK,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,IAAI,CAE9C;AAED;;;;;GAKG;AACH,wBAAgB,MAAM,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,EAAC,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAc3E;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,GAAG,OAAO,CAMpE"}
@@ -14,6 +14,7 @@ export { default as AsyncPoolExecutor } from './async-pool-executor.js';
14
14
  export { default as Lazy } from './lazy.js';
15
15
  export { default as from } from './collections/from.js';
16
16
  export { EventBus, Event } from './event-bus.js';
17
+ export { default as Range } from './range.js';
17
18
  export { default as draft } from './draft.js';
18
19
  export { default as CleanURLSearchParams } from './clean-url-search-params.js';
19
20
  /** @deprecated */
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAGA,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAC,OAAO,IAAI,IAAI,EAAC,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAC,OAAO,IAAI,QAAQ,EAAC,MAAM,gBAAgB,CAAC;AAGnD,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,OAAO,EAAC,OAAO,IAAI,kBAAkB,EAAC,MAAM,0BAA0B,CAAC;AAGvE,OAAO,EAAC,OAAO,IAAI,YAAY,EAAC,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAC,OAAO,IAAI,KAAK,EAAC,MAAM,YAAY,CAAC;AAG5C,OAAO,EAAC,OAAO,IAAI,KAAK,EAAC,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAC,OAAO,IAAI,QAAQ,EAAC,MAAM,eAAe,CAAC;AAClD,OAAO,EAAC,OAAO,IAAI,SAAS,EAAC,MAAM,gBAAgB,CAAC;AACpD,OAAO,EAAC,OAAO,IAAI,iBAAiB,EAAC,MAAM,0BAA0B,CAAC;AAGtE,OAAO,EAAC,OAAO,IAAI,IAAI,EAAC,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAC,OAAO,IAAI,IAAI,EAAC,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAC,QAAQ,EAAE,KAAK,EAAC,MAAM,gBAAgB,CAAC;AAG/C,OAAO,EAAC,OAAO,IAAI,KAAK,EAAC,MAAM,YAAY,CAAC;AAG5C,OAAO,EAAC,OAAO,IAAI,oBAAoB,EAAC,MAAM,8BAA8B,CAAC;AAC7E,mBAAmB;AACnB,OAAO,EAAC,UAAU,EAAE,cAAc,EAAE,UAAU,EAAE,YAAY,EAAC,MAAM,oBAAoB,CAAC;AAKxF,mBAAmB;AACnB,cAAc,YAAY,CAAC;AAC3B,mBAAmB;AACnB,cAAc,wBAAwB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAGA,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAC,OAAO,IAAI,IAAI,EAAC,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAC,OAAO,IAAI,QAAQ,EAAC,MAAM,gBAAgB,CAAC;AAGnD,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,OAAO,EAAC,OAAO,IAAI,kBAAkB,EAAC,MAAM,0BAA0B,CAAC;AAGvE,OAAO,EAAC,OAAO,IAAI,YAAY,EAAC,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAC,OAAO,IAAI,KAAK,EAAC,MAAM,YAAY,CAAC;AAG5C,OAAO,EAAC,OAAO,IAAI,KAAK,EAAC,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAC,OAAO,IAAI,QAAQ,EAAC,MAAM,eAAe,CAAC;AAClD,OAAO,EAAC,OAAO,IAAI,SAAS,EAAC,MAAM,gBAAgB,CAAC;AACpD,OAAO,EAAC,OAAO,IAAI,iBAAiB,EAAC,MAAM,0BAA0B,CAAC;AAGtE,OAAO,EAAC,OAAO,IAAI,IAAI,EAAC,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAC,OAAO,IAAI,IAAI,EAAC,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAC,QAAQ,EAAE,KAAK,EAAC,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAC,OAAO,IAAI,KAAK,EAAC,MAAM,YAAY,CAAC;AAG5C,OAAO,EAAC,OAAO,IAAI,KAAK,EAAC,MAAM,YAAY,CAAC;AAG5C,OAAO,EAAC,OAAO,IAAI,oBAAoB,EAAC,MAAM,8BAA8B,CAAC;AAC7E,mBAAmB;AACnB,OAAO,EAAC,UAAU,EAAE,cAAc,EAAE,UAAU,EAAE,YAAY,EAAC,MAAM,oBAAoB,CAAC;AAKxF,mBAAmB;AACnB,cAAc,YAAY,CAAC;AAC3B,mBAAmB;AACnB,cAAc,wBAAwB,CAAC"}
@@ -0,0 +1,72 @@
1
+ export default class Range<T> {
2
+ private readonly start;
3
+ private readonly end;
4
+ /**
5
+ * Range constructor.
6
+ * @param start
7
+ * @param end
8
+ */
9
+ constructor(start: T, end: T);
10
+ /**
11
+ * Finds the intersection between two ranges.
12
+ *
13
+ * @param other The Range object to intersect with.
14
+ * @returns The intersected Range object, or null if there is no intersection.
15
+ */
16
+ intersect(other: Range<T>): Range<T> | null;
17
+ /**
18
+ * Subtract the given range from this range.
19
+ *
20
+ * @param other The range to subtract from this range.
21
+ * @returns An array of Range objects representing the result of the subtraction.
22
+ */
23
+ subtract(other: Range<T>): Range<T>[];
24
+ /**
25
+ * Determines if the given range overlaps with the current range.
26
+ *
27
+ * @param other The range to be checked for overlap.
28
+ * @returns Returns true if there is an overlap between the ranges, false otherwise.
29
+ */
30
+ overlaps(other: Range<T>): boolean;
31
+ /**
32
+ * Determines whether the specified value is within the range defined by the start and end values.
33
+ *
34
+ * @param obj The value to check if it is within the range.
35
+ * @param inclusive Optional. If set to true, the range boundaries are considered inclusive.
36
+ * @returns Returns true if the specified value is within the range, false otherwise.
37
+ */
38
+ contains(obj: T, inclusive?: boolean): boolean;
39
+ /**
40
+ * @returns T
41
+ */
42
+ getStart(): T;
43
+ /**
44
+ * @returns T
45
+ */
46
+ getEnd(): T;
47
+ /**
48
+ * Finds the intersection between two sets of ranges.
49
+ *
50
+ * @param ranges1
51
+ * @param ranges2
52
+ * @returns
53
+ */
54
+ static intersectRanges<T>(ranges1: Range<T>[], ranges2: Range<T>[]): Range<T>[];
55
+ /**
56
+ * Determines if any range in the first set overlaps with any range in the second set.
57
+ *
58
+ * @param ranges1
59
+ * @param ranges2
60
+ * @returns
61
+ */
62
+ static overlapsAny<T>(ranges1: Range<T>[], ranges2: Range<T>[]): boolean;
63
+ /**
64
+ * Subtracts the second set of ranges from the first set of ranges.
65
+ *
66
+ * @param ranges1
67
+ * @param ranges2
68
+ * @returns
69
+ */
70
+ static subtractRanges<T>(ranges1: Range<T>[], ranges2: Range<T>[]): Range<T>[];
71
+ }
72
+ //# sourceMappingURL=range.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"range.d.ts","sourceRoot":"","sources":["../../src/range.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,OAAO,OAAO,KAAK,CAAC,CAAC;IAExB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAI;IAC1B,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAI;IAExB;;;;OAIG;gBACS,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC;IAK5B;;;;;OAKG;IACI,SAAS,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,IAAI;IAWlD;;;;;OAKG;IACI,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,EAAE;IAoB5C;;;;;OAKG;IACI,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,OAAO;IAWzC;;;;;;OAMG;IACI,QAAQ,CAAC,GAAG,EAAE,CAAC,EAAE,SAAS,GAAE,OAAc,GAAG,OAAO;IAM3D;;OAEG;IACI,QAAQ,IAAI,CAAC;IAIpB;;OAEG;IACI,MAAM,IAAI,CAAC;IAIlB;;;;;;OAMG;WACW,eAAe,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,EAAE;IAatF;;;;;;OAMG;WACW,WAAW,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,OAAO;IAW/E;;;;;;OAMG;WACW,cAAc,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,EAAE;CAiBxF"}
package/dist/web/array.js CHANGED
@@ -61,4 +61,19 @@ export function remove(array, predicate) {
61
61
  }
62
62
  return removed;
63
63
  }
64
+ /**
65
+ * Adds an element to the array if it's not already present.
66
+ * The operation mutates the original array.
67
+ * @template T
68
+ * @param {Array<T>} array - The array to modify.
69
+ * @param {T} element - The element to add if absent.
70
+ * @return {boolean} True if the element was added, false otherwise.
71
+ */
72
+ export function pushIfAbsent(array, element) {
73
+ if (!array.includes(element)) {
74
+ array.push(element);
75
+ return true;
76
+ }
77
+ return false;
78
+ }
64
79
  //# sourceMappingURL=array.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"array.js","sourceRoot":"","sources":["../../src/array.ts"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AACH,MAAM,UAAU,IAAI,CAAI,KAAe,EAAE,GAAG,KAAe;IAEvD,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACvB,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAClC,IAAI,KAAK,KAAK,CAAC,CAAC,EAAE,CAAC;YACf,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;YACvB,MAAM,EAAE,CAAC;QACb,CAAC;IACL,CAAC;IACD,OAAO,MAAM,CAAC;AAClB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,KAAK,CAAI,KAAe,EAAE,IAAY;IAClD,IAAI,IAAI,IAAI,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;IAC9D,MAAM,MAAM,GAAoB,EAAE,CAAC;IACnC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC;QAC1C,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;IAC1C,CAAC;IACD,OAAO,MAAM,CAAC;AAClB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,KAAK,CAAI,KAAe;IACpC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;AACrB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,MAAM,CAAI,KAAe,EAAC,SAAuB;IAC7D,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,IAAI,CAAC,GAAG,CAAC,CAAC;IAEV,OAAO,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;QACtB,IAAI,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YACtB,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;YACvB,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,gBAAgB;QACxC,CAAC;aAAM,CAAC;YACJ,CAAC,EAAE,CAAC;QACR,CAAC;IACL,CAAC;IAED,OAAO,OAAO,CAAC;AACnB,CAAC","sourcesContent":["import type {Predicate} from \"./types.js\";\r\n\r\n/**\r\n * Removes all given values from the provided array and returns the number of removed elements.\r\n * The operation mutates the original array.\r\n * @template T\r\n * @param {Array<T>} array - The array to modify by removing specified items.\r\n * @param {...T} items - The values to remove from the array.\r\n * @return {number} The number of elements removed from the array.\r\n */\r\nexport function pull<T>(array: Array<T>, ...items: Array<T>): number {\r\n\r\n let output = 0;\r\n for (const item of items) {\r\n const index = array.indexOf(item);\r\n if (index !== -1) {\r\n array.splice(index, 1);\r\n output++;\r\n }\r\n }\r\n return output;\r\n}\r\n\r\n/**\r\n * Splits an array into chunks of a given size.\r\n * @template T\r\n * @param {Array<T>} array - The array to split.\r\n * @param {number} size - The size of each chunk.\r\n * @return {Array<Array<T>>} The array of chunks.\r\n */\r\nexport function chunk<T>(array: Array<T>, size: number): Array<Array<T>> {\r\n if (size <= 0) throw new Error(\"Size must be greater than 0\");\r\n const result: Array<Array<T>> = [];\r\n for (let i = 0; i < array.length; i += size) {\r\n result.push(array.slice(i, i + size));\r\n }\r\n return result;\r\n}\r\n\r\n/**\r\n * Removes all elements from the array, mutating it.\r\n * @template T\r\n * @param {Array<T>} array - The array to clear.\r\n */\r\nexport function clear<T>(array: Array<T>): void {\r\n array.length = 0;\r\n}\r\n\r\n/**\r\n * Removes all elements from the array that satisfy the predicate.\r\n * The operation mutates the original array.\r\n * @template T\r\n * @return {Array<T>} An array of removed elements.\r\n */\r\nexport function remove<T>(array: Array<T>,predicate: Predicate<T>): Array<T> {\r\n const removed: Array<T> = [];\r\n let i = 0;\r\n\r\n while (i < array.length) {\r\n if (predicate(array[i])) {\r\n removed.push(array[i]);\r\n array.splice(i, 1); // muta el array\r\n } else {\r\n i++;\r\n }\r\n }\r\n\r\n return removed;\r\n}"]}
1
+ {"version":3,"file":"array.js","sourceRoot":"","sources":["../../src/array.ts"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AACH,MAAM,UAAU,IAAI,CAAI,KAAe,EAAE,GAAG,KAAe;IAEvD,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACvB,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAClC,IAAI,KAAK,KAAK,CAAC,CAAC,EAAE,CAAC;YACf,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;YACvB,MAAM,EAAE,CAAC;QACb,CAAC;IACL,CAAC;IACD,OAAO,MAAM,CAAC;AAClB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,KAAK,CAAI,KAAe,EAAE,IAAY;IAClD,IAAI,IAAI,IAAI,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;IAC9D,MAAM,MAAM,GAAoB,EAAE,CAAC;IACnC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC;QAC1C,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;IAC1C,CAAC;IACD,OAAO,MAAM,CAAC;AAClB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,KAAK,CAAI,KAAe;IACpC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;AACrB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,MAAM,CAAI,KAAe,EAAC,SAAuB;IAC7D,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,IAAI,CAAC,GAAG,CAAC,CAAC;IAEV,OAAO,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;QACtB,IAAI,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YACtB,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;YACvB,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,gBAAgB;QACxC,CAAC;aAAM,CAAC;YACJ,CAAC,EAAE,CAAC;QACR,CAAC;IACL,CAAC;IAED,OAAO,OAAO,CAAC;AACnB,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,YAAY,CAAI,KAAe,EAAE,OAAU;IACvD,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;QAC3B,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACpB,OAAO,IAAI,CAAC;IAChB,CAAC;IACD,OAAO,KAAK,CAAC;AACjB,CAAC","sourcesContent":["import type {Predicate} from \"./types.js\";\r\n\r\n/**\r\n * Removes all given values from the provided array and returns the number of removed elements.\r\n * The operation mutates the original array.\r\n * @template T\r\n * @param {Array<T>} array - The array to modify by removing specified items.\r\n * @param {...T} items - The values to remove from the array.\r\n * @return {number} The number of elements removed from the array.\r\n */\r\nexport function pull<T>(array: Array<T>, ...items: Array<T>): number {\r\n\r\n let output = 0;\r\n for (const item of items) {\r\n const index = array.indexOf(item);\r\n if (index !== -1) {\r\n array.splice(index, 1);\r\n output++;\r\n }\r\n }\r\n return output;\r\n}\r\n\r\n/**\r\n * Splits an array into chunks of a given size.\r\n * @template T\r\n * @param {Array<T>} array - The array to split.\r\n * @param {number} size - The size of each chunk.\r\n * @return {Array<Array<T>>} The array of chunks.\r\n */\r\nexport function chunk<T>(array: Array<T>, size: number): Array<Array<T>> {\r\n if (size <= 0) throw new Error(\"Size must be greater than 0\");\r\n const result: Array<Array<T>> = [];\r\n for (let i = 0; i < array.length; i += size) {\r\n result.push(array.slice(i, i + size));\r\n }\r\n return result;\r\n}\r\n\r\n/**\r\n * Removes all elements from the array, mutating it.\r\n * @template T\r\n * @param {Array<T>} array - The array to clear.\r\n */\r\nexport function clear<T>(array: Array<T>): void {\r\n array.length = 0;\r\n}\r\n\r\n/**\r\n * Removes all elements from the array that satisfy the predicate.\r\n * The operation mutates the original array.\r\n * @template T\r\n * @return {Array<T>} An array of removed elements.\r\n */\r\nexport function remove<T>(array: Array<T>,predicate: Predicate<T>): Array<T> {\r\n const removed: Array<T> = [];\r\n let i = 0;\r\n\r\n while (i < array.length) {\r\n if (predicate(array[i])) {\r\n removed.push(array[i]);\r\n array.splice(i, 1); // muta el array\r\n } else {\r\n i++;\r\n }\r\n }\r\n\r\n return removed;\r\n}\r\n\r\n/**\r\n * Adds an element to the array if it's not already present.\r\n * The operation mutates the original array.\r\n * @template T\r\n * @param {Array<T>} array - The array to modify.\r\n * @param {T} element - The element to add if absent.\r\n * @return {boolean} True if the element was added, false otherwise.\r\n */\r\nexport function pushIfAbsent<T>(array: Array<T>, element: T): boolean {\r\n if (!array.includes(element)) {\r\n array.push(element);\r\n return true;\r\n }\r\n return false;\r\n}"]}
package/dist/web/index.js CHANGED
@@ -20,6 +20,7 @@ export { default as AsyncPoolExecutor } from './async-pool-executor.js';
20
20
  export { default as Lazy } from './lazy.js';
21
21
  export { default as from } from './collections/from.js';
22
22
  export { EventBus, Event } from './event-bus.js';
23
+ export { default as Range } from './range.js';
23
24
  // ─── Draft ────────────────────────────────────────
24
25
  export { default as draft } from './draft.js';
25
26
  // ─── Web ─────────────────────────────────────────────
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,eAAe;AAEf,wDAAwD;AACxD,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAC,OAAO,IAAI,IAAI,EAAC,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAC,OAAO,IAAI,QAAQ,EAAC,MAAM,gBAAgB,CAAC;AAEnD,wDAAwD;AACxD,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,OAAO,EAAC,OAAO,IAAI,kBAAkB,EAAC,MAAM,0BAA0B,CAAC;AAEvE,uDAAuD;AACvD,OAAO,EAAC,OAAO,IAAI,YAAY,EAAC,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAC,OAAO,IAAI,KAAK,EAAC,MAAM,YAAY,CAAC;AAE5C,uDAAuD;AACvD,OAAO,EAAC,OAAO,IAAI,KAAK,EAAC,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAC,OAAO,IAAI,QAAQ,EAAC,MAAM,eAAe,CAAC;AAClD,OAAO,EAAC,OAAO,IAAI,SAAS,EAAC,MAAM,gBAAgB,CAAC;AACpD,OAAO,EAAC,OAAO,IAAI,iBAAiB,EAAC,MAAM,0BAA0B,CAAC;AAEtE,wDAAwD;AACxD,OAAO,EAAC,OAAO,IAAI,IAAI,EAAC,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAC,OAAO,IAAI,IAAI,EAAC,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAC,QAAQ,EAAE,KAAK,EAAC,MAAM,gBAAgB,CAAC;AAE/C,qDAAqD;AACrD,OAAO,EAAC,OAAO,IAAI,KAAK,EAAC,MAAM,YAAY,CAAC;AAE5C,wDAAwD;AACxD,OAAO,EAAC,OAAO,IAAI,oBAAoB,EAAC,MAAM,8BAA8B,CAAC;AAC7E,mBAAmB;AACnB,OAAO,EAAC,UAAU,EAAE,cAAc,EAAE,UAAU,EAAE,YAAY,EAAC,MAAM,oBAAoB,CAAC;AAIxF,wDAAwD;AACxD,mBAAmB;AACnB,cAAc,YAAY,CAAC;AAC3B,mBAAmB;AACnB,cAAc,wBAAwB,CAAC","sourcesContent":["// src/index.ts\r\n\r\n// ─── Types ───────────────────────────────────────────\r\nexport * from './types.js';\r\nexport {default as Type} from './type.js';\r\nexport {default as TypeCode} from './type-code.js';\r\n\r\n// ─── Utilities ───────────────────────────────────────\r\nexport * from './utilities.js';\r\nexport * from './string.js';\r\nexport * from './math.js';\r\nexport {default as CancellablePromise} from \"./cancellable-promise.js\";\r\n\r\n// ─── Data Structures ────────────────────────────────\r\nexport {default as KeyValuePair} from './key-value-pair.js';\r\nexport {default as Order} from './order.js';\r\n\r\n// ─── Async & Timing ─────────────────────────────────\r\nexport {default as Timer} from './timer.js';\r\nexport {default as TimeSpan} from './timespan.js';\r\nexport {default as Stopwatch} from './stopwatch.js';\r\nexport {default as AsyncPoolExecutor} from './async-pool-executor.js';\r\n\r\n// ─── Patterns ────────────────────────────────────────\r\nexport {default as Lazy} from './lazy.js';\r\nexport {default as from} from './collections/from.js';\r\nexport {EventBus, Event} from './event-bus.js';\r\n\r\n// ─── Draft ────────────────────────────────────────\r\nexport {default as draft} from './draft.js';\r\n\r\n// ─── Web ─────────────────────────────────────────────\r\nexport {default as CleanURLSearchParams} from './clean-url-search-params.js';\r\n/** @deprecated */\r\nexport {ajaxSubmit, ajaxSubmission, submitForm, formToObject} from './browser/index.js';\r\n\r\n\r\n\r\n// ─── Deprecated ──────────────────────────────────────\r\n/** @deprecated */\r\nexport * from './array.js';\r\n/** @deprecated */\r\nexport * from './collections/index.js';"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,eAAe;AAEf,wDAAwD;AACxD,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAC,OAAO,IAAI,IAAI,EAAC,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAC,OAAO,IAAI,QAAQ,EAAC,MAAM,gBAAgB,CAAC;AAEnD,wDAAwD;AACxD,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,OAAO,EAAC,OAAO,IAAI,kBAAkB,EAAC,MAAM,0BAA0B,CAAC;AAEvE,uDAAuD;AACvD,OAAO,EAAC,OAAO,IAAI,YAAY,EAAC,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAC,OAAO,IAAI,KAAK,EAAC,MAAM,YAAY,CAAC;AAE5C,uDAAuD;AACvD,OAAO,EAAC,OAAO,IAAI,KAAK,EAAC,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAC,OAAO,IAAI,QAAQ,EAAC,MAAM,eAAe,CAAC;AAClD,OAAO,EAAC,OAAO,IAAI,SAAS,EAAC,MAAM,gBAAgB,CAAC;AACpD,OAAO,EAAC,OAAO,IAAI,iBAAiB,EAAC,MAAM,0BAA0B,CAAC;AAEtE,wDAAwD;AACxD,OAAO,EAAC,OAAO,IAAI,IAAI,EAAC,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAC,OAAO,IAAI,IAAI,EAAC,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAC,QAAQ,EAAE,KAAK,EAAC,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAC,OAAO,IAAI,KAAK,EAAC,MAAM,YAAY,CAAC;AAE5C,qDAAqD;AACrD,OAAO,EAAC,OAAO,IAAI,KAAK,EAAC,MAAM,YAAY,CAAC;AAE5C,wDAAwD;AACxD,OAAO,EAAC,OAAO,IAAI,oBAAoB,EAAC,MAAM,8BAA8B,CAAC;AAC7E,mBAAmB;AACnB,OAAO,EAAC,UAAU,EAAE,cAAc,EAAE,UAAU,EAAE,YAAY,EAAC,MAAM,oBAAoB,CAAC;AAIxF,wDAAwD;AACxD,mBAAmB;AACnB,cAAc,YAAY,CAAC;AAC3B,mBAAmB;AACnB,cAAc,wBAAwB,CAAC","sourcesContent":["// src/index.ts\n\n// ─── Types ───────────────────────────────────────────\nexport * from './types.js';\nexport {default as Type} from './type.js';\nexport {default as TypeCode} from './type-code.js';\n\n// ─── Utilities ───────────────────────────────────────\nexport * from './utilities.js';\nexport * from './string.js';\nexport * from './math.js';\nexport {default as CancellablePromise} from \"./cancellable-promise.js\";\n\n// ─── Data Structures ────────────────────────────────\nexport {default as KeyValuePair} from './key-value-pair.js';\nexport {default as Order} from './order.js';\n\n// ─── Async & Timing ─────────────────────────────────\nexport {default as Timer} from './timer.js';\nexport {default as TimeSpan} from './timespan.js';\nexport {default as Stopwatch} from './stopwatch.js';\nexport {default as AsyncPoolExecutor} from './async-pool-executor.js';\n\n// ─── Patterns ────────────────────────────────────────\nexport {default as Lazy} from './lazy.js';\nexport {default as from} from './collections/from.js';\nexport {EventBus, Event} from './event-bus.js';\nexport {default as Range} from './range.js';\n\n// ─── Draft ────────────────────────────────────────\nexport {default as draft} from './draft.js';\n\n// ─── Web ─────────────────────────────────────────────\nexport {default as CleanURLSearchParams} from './clean-url-search-params.js';\n/** @deprecated */\nexport {ajaxSubmit, ajaxSubmission, submitForm, formToObject} from './browser/index.js';\n\n\n\n// ─── Deprecated ──────────────────────────────────────\n/** @deprecated */\nexport * from './array.js';\n/** @deprecated */\nexport * from './collections/index.js';"]}
@@ -0,0 +1,151 @@
1
+ export default class Range {
2
+ /**
3
+ * Range constructor.
4
+ * @param start
5
+ * @param end
6
+ */
7
+ constructor(start, end) {
8
+ this.start = start;
9
+ this.end = end;
10
+ }
11
+ /**
12
+ * Finds the intersection between two ranges.
13
+ *
14
+ * @param other The Range object to intersect with.
15
+ * @returns The intersected Range object, or null if there is no intersection.
16
+ */
17
+ intersect(other) {
18
+ const start = (this.start > other.start) ? this.start : other.start;
19
+ const end = (this.end < other.end) ? this.end : other.end;
20
+ if (start < end) {
21
+ return new Range(start, end);
22
+ }
23
+ else {
24
+ return null;
25
+ }
26
+ }
27
+ /**
28
+ * Subtract the given range from this range.
29
+ *
30
+ * @param other The range to subtract from this range.
31
+ * @returns An array of Range objects representing the result of the subtraction.
32
+ */
33
+ subtract(other) {
34
+ const result = [];
35
+ if (this.start >= other.end || this.end <= other.start) {
36
+ result.push(new Range(this.start, this.end));
37
+ }
38
+ else if (other.start <= this.start && other.end >= this.end) {
39
+ return result;
40
+ }
41
+ else {
42
+ if (this.start < other.start) {
43
+ result.push(new Range(this.start, other.start));
44
+ }
45
+ if (this.end > other.end) {
46
+ result.push(new Range(other.end, this.end));
47
+ }
48
+ }
49
+ return result;
50
+ }
51
+ /**
52
+ * Determines if the given range overlaps with the current range.
53
+ *
54
+ * @param other The range to be checked for overlap.
55
+ * @returns Returns true if there is an overlap between the ranges, false otherwise.
56
+ */
57
+ overlaps(other) {
58
+ const s1 = this.start;
59
+ const e1 = this.end;
60
+ const s2 = other.start;
61
+ const e2 = other.end;
62
+ return (s2 > s1 && s2 < e1 || e2 > s1 && e2 < e1) ||
63
+ (s1 > s2 && s1 < e2 || e1 > s2 && e1 < e2) ||
64
+ (s1 === s2 && e1 === e2);
65
+ }
66
+ /**
67
+ * Determines whether the specified value is within the range defined by the start and end values.
68
+ *
69
+ * @param obj The value to check if it is within the range.
70
+ * @param inclusive Optional. If set to true, the range boundaries are considered inclusive.
71
+ * @returns Returns true if the specified value is within the range, false otherwise.
72
+ */
73
+ contains(obj, inclusive = true) {
74
+ return inclusive ?
75
+ (this.start <= obj && this.end >= obj) :
76
+ (this.start < obj && this.end > obj);
77
+ }
78
+ /**
79
+ * @returns T
80
+ */
81
+ getStart() {
82
+ return this.start;
83
+ }
84
+ /**
85
+ * @returns T
86
+ */
87
+ getEnd() {
88
+ return this.end;
89
+ }
90
+ /**
91
+ * Finds the intersection between two sets of ranges.
92
+ *
93
+ * @param ranges1
94
+ * @param ranges2
95
+ * @returns
96
+ */
97
+ static intersectRanges(ranges1, ranges2) {
98
+ const result = [];
99
+ for (const r1 of ranges1) {
100
+ for (const r2 of ranges2) {
101
+ const intersection = r1.intersect(r2);
102
+ if (intersection !== null) {
103
+ result.push(intersection);
104
+ }
105
+ }
106
+ }
107
+ return result;
108
+ }
109
+ /**
110
+ * Determines if any range in the first set overlaps with any range in the second set.
111
+ *
112
+ * @param ranges1
113
+ * @param ranges2
114
+ * @returns
115
+ */
116
+ static overlapsAny(ranges1, ranges2) {
117
+ for (const r1 of ranges1) {
118
+ for (const r2 of ranges2) {
119
+ if (r1.overlaps(r2)) {
120
+ return true;
121
+ }
122
+ }
123
+ }
124
+ return false;
125
+ }
126
+ /**
127
+ * Subtracts the second set of ranges from the first set of ranges.
128
+ *
129
+ * @param ranges1
130
+ * @param ranges2
131
+ * @returns
132
+ */
133
+ static subtractRanges(ranges1, ranges2) {
134
+ let currentRanges = ranges1;
135
+ for (const r2 of ranges2) {
136
+ const nextRanges = [];
137
+ for (const r1 of currentRanges) {
138
+ const subtracted = r1.subtract(r2);
139
+ for (const s of subtracted) {
140
+ nextRanges.push(s);
141
+ }
142
+ }
143
+ currentRanges = nextRanges;
144
+ if (currentRanges.length === 0) {
145
+ break;
146
+ }
147
+ }
148
+ return currentRanges;
149
+ }
150
+ }
151
+ //# sourceMappingURL=range.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"range.js","sourceRoot":"","sources":["../../src/range.ts"],"names":[],"mappings":"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","sourcesContent":["export default class Range<T> {\n\n private readonly start: T;\n private readonly end: T;\n\n /**\n * Range constructor.\n * @param start\n * @param end\n */\n constructor(start: T, end: T) {\n this.start = start;\n this.end = end;\n }\n\n /**\n * Finds the intersection between two ranges.\n *\n * @param other The Range object to intersect with.\n * @returns The intersected Range object, or null if there is no intersection.\n */\n public intersect(other: Range<T>): Range<T> | null {\n const start = (this.start > other.start) ? this.start : other.start;\n const end = (this.end < other.end) ? this.end : other.end;\n\n if (start < end) {\n return new Range(start, end);\n } else {\n return null;\n }\n }\n\n /**\n * Subtract the given range from this range.\n *\n * @param other The range to subtract from this range.\n * @returns An array of Range objects representing the result of the subtraction.\n */\n public subtract(other: Range<T>): Range<T>[] {\n const result: Range<T>[] = [];\n\n if (this.start >= other.end || this.end <= other.start) {\n result.push(new Range(this.start, this.end));\n } else if (other.start <= this.start && other.end >= this.end) {\n return result;\n } else {\n if (this.start < other.start) {\n result.push(new Range(this.start, other.start));\n }\n\n if (this.end > other.end) {\n result.push(new Range(other.end, this.end));\n }\n }\n\n return result;\n }\n\n /**\n * Determines if the given range overlaps with the current range.\n *\n * @param other The range to be checked for overlap.\n * @returns Returns true if there is an overlap between the ranges, false otherwise.\n */\n public overlaps(other: Range<T>): boolean {\n const s1 = this.start;\n const e1 = this.end;\n const s2 = other.start;\n const e2 = other.end;\n\n return (s2 > s1 && s2 < e1 || e2 > s1 && e2 < e1) ||\n (s1 > s2 && s1 < e2 || e1 > s2 && e1 < e2) ||\n (s1 === s2 && e1 === e2);\n }\n\n /**\n * Determines whether the specified value is within the range defined by the start and end values.\n *\n * @param obj The value to check if it is within the range.\n * @param inclusive Optional. If set to true, the range boundaries are considered inclusive.\n * @returns Returns true if the specified value is within the range, false otherwise.\n */\n public contains(obj: T, inclusive: boolean = true): boolean {\n return inclusive ?\n (this.start <= obj && this.end >= obj) :\n (this.start < obj && this.end > obj);\n }\n\n /**\n * @returns T\n */\n public getStart(): T {\n return this.start;\n }\n\n /**\n * @returns T\n */\n public getEnd(): T {\n return this.end;\n }\n\n /**\n * Finds the intersection between two sets of ranges.\n *\n * @param ranges1\n * @param ranges2\n * @returns\n */\n public static intersectRanges<T>(ranges1: Range<T>[], ranges2: Range<T>[]): Range<T>[] {\n const result: Range<T>[] = [];\n for (const r1 of ranges1) {\n for (const r2 of ranges2) {\n const intersection = r1.intersect(r2);\n if (intersection !== null) {\n result.push(intersection);\n }\n }\n }\n return result;\n }\n\n /**\n * Determines if any range in the first set overlaps with any range in the second set.\n *\n * @param ranges1\n * @param ranges2\n * @returns\n */\n public static overlapsAny<T>(ranges1: Range<T>[], ranges2: Range<T>[]): boolean {\n for (const r1 of ranges1) {\n for (const r2 of ranges2) {\n if (r1.overlaps(r2)) {\n return true;\n }\n }\n }\n return false;\n }\n\n /**\n * Subtracts the second set of ranges from the first set of ranges.\n *\n * @param ranges1\n * @param ranges2\n * @returns\n */\n public static subtractRanges<T>(ranges1: Range<T>[], ranges2: Range<T>[]): Range<T>[] {\n let currentRanges = ranges1;\n for (const r2 of ranges2) {\n const nextRanges: Range<T>[] = [];\n for (const r1 of currentRanges) {\n const subtracted = r1.subtract(r2);\n for (const s of subtracted) {\n nextRanges.push(s);\n }\n }\n currentRanges = nextRanges;\n if (currentRanges.length === 0) {\n break;\n }\n }\n return currentRanges;\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@develia/commons",
3
- "version": "0.4.15",
3
+ "version": "0.4.16",
4
4
  "author": {
5
5
  "name": "Antonio Gil Espinosa",
6
6
  "email": "antonio.gil.espinosa@gmail.com",
package/src/array.ts CHANGED
@@ -66,4 +66,20 @@ export function remove<T>(array: Array<T>,predicate: Predicate<T>): Array<T> {
66
66
  }
67
67
 
68
68
  return removed;
69
+ }
70
+
71
+ /**
72
+ * Adds an element to the array if it's not already present.
73
+ * The operation mutates the original array.
74
+ * @template T
75
+ * @param {Array<T>} array - The array to modify.
76
+ * @param {T} element - The element to add if absent.
77
+ * @return {boolean} True if the element was added, false otherwise.
78
+ */
79
+ export function pushIfAbsent<T>(array: Array<T>, element: T): boolean {
80
+ if (!array.includes(element)) {
81
+ array.push(element);
82
+ return true;
83
+ }
84
+ return false;
69
85
  }
package/src/index.ts CHANGED
@@ -1,43 +1,44 @@
1
- // src/index.ts
2
-
3
- // ─── Types ───────────────────────────────────────────
4
- export * from './types.js';
5
- export {default as Type} from './type.js';
6
- export {default as TypeCode} from './type-code.js';
7
-
8
- // ─── Utilities ───────────────────────────────────────
9
- export * from './utilities.js';
10
- export * from './string.js';
11
- export * from './math.js';
12
- export {default as CancellablePromise} from "./cancellable-promise.js";
13
-
14
- // ─── Data Structures ────────────────────────────────
15
- export {default as KeyValuePair} from './key-value-pair.js';
16
- export {default as Order} from './order.js';
17
-
18
- // ─── Async & Timing ─────────────────────────────────
19
- export {default as Timer} from './timer.js';
20
- export {default as TimeSpan} from './timespan.js';
21
- export {default as Stopwatch} from './stopwatch.js';
22
- export {default as AsyncPoolExecutor} from './async-pool-executor.js';
23
-
24
- // ─── Patterns ────────────────────────────────────────
25
- export {default as Lazy} from './lazy.js';
26
- export {default as from} from './collections/from.js';
27
- export {EventBus, Event} from './event-bus.js';
28
-
29
- // ─── Draft ────────────────────────────────────────
30
- export {default as draft} from './draft.js';
31
-
32
- // ─── Web ─────────────────────────────────────────────
33
- export {default as CleanURLSearchParams} from './clean-url-search-params.js';
34
- /** @deprecated */
35
- export {ajaxSubmit, ajaxSubmission, submitForm, formToObject} from './browser/index.js';
36
-
37
-
38
-
39
- // ─── Deprecated ──────────────────────────────────────
40
- /** @deprecated */
41
- export * from './array.js';
42
- /** @deprecated */
1
+ // src/index.ts
2
+
3
+ // ─── Types ───────────────────────────────────────────
4
+ export * from './types.js';
5
+ export {default as Type} from './type.js';
6
+ export {default as TypeCode} from './type-code.js';
7
+
8
+ // ─── Utilities ───────────────────────────────────────
9
+ export * from './utilities.js';
10
+ export * from './string.js';
11
+ export * from './math.js';
12
+ export {default as CancellablePromise} from "./cancellable-promise.js";
13
+
14
+ // ─── Data Structures ────────────────────────────────
15
+ export {default as KeyValuePair} from './key-value-pair.js';
16
+ export {default as Order} from './order.js';
17
+
18
+ // ─── Async & Timing ─────────────────────────────────
19
+ export {default as Timer} from './timer.js';
20
+ export {default as TimeSpan} from './timespan.js';
21
+ export {default as Stopwatch} from './stopwatch.js';
22
+ export {default as AsyncPoolExecutor} from './async-pool-executor.js';
23
+
24
+ // ─── Patterns ────────────────────────────────────────
25
+ export {default as Lazy} from './lazy.js';
26
+ export {default as from} from './collections/from.js';
27
+ export {EventBus, Event} from './event-bus.js';
28
+ export {default as Range} from './range.js';
29
+
30
+ // ─── Draft ────────────────────────────────────────
31
+ export {default as draft} from './draft.js';
32
+
33
+ // ─── Web ─────────────────────────────────────────────
34
+ export {default as CleanURLSearchParams} from './clean-url-search-params.js';
35
+ /** @deprecated */
36
+ export {ajaxSubmit, ajaxSubmission, submitForm, formToObject} from './browser/index.js';
37
+
38
+
39
+
40
+ // ─── Deprecated ──────────────────────────────────────
41
+ /** @deprecated */
42
+ export * from './array.js';
43
+ /** @deprecated */
43
44
  export * from './collections/index.js';
package/src/range.ts ADDED
@@ -0,0 +1,165 @@
1
+ export default class Range<T> {
2
+
3
+ private readonly start: T;
4
+ private readonly end: T;
5
+
6
+ /**
7
+ * Range constructor.
8
+ * @param start
9
+ * @param end
10
+ */
11
+ constructor(start: T, end: T) {
12
+ this.start = start;
13
+ this.end = end;
14
+ }
15
+
16
+ /**
17
+ * Finds the intersection between two ranges.
18
+ *
19
+ * @param other The Range object to intersect with.
20
+ * @returns The intersected Range object, or null if there is no intersection.
21
+ */
22
+ public intersect(other: Range<T>): Range<T> | null {
23
+ const start = (this.start > other.start) ? this.start : other.start;
24
+ const end = (this.end < other.end) ? this.end : other.end;
25
+
26
+ if (start < end) {
27
+ return new Range(start, end);
28
+ } else {
29
+ return null;
30
+ }
31
+ }
32
+
33
+ /**
34
+ * Subtract the given range from this range.
35
+ *
36
+ * @param other The range to subtract from this range.
37
+ * @returns An array of Range objects representing the result of the subtraction.
38
+ */
39
+ public subtract(other: Range<T>): Range<T>[] {
40
+ const result: Range<T>[] = [];
41
+
42
+ if (this.start >= other.end || this.end <= other.start) {
43
+ result.push(new Range(this.start, this.end));
44
+ } else if (other.start <= this.start && other.end >= this.end) {
45
+ return result;
46
+ } else {
47
+ if (this.start < other.start) {
48
+ result.push(new Range(this.start, other.start));
49
+ }
50
+
51
+ if (this.end > other.end) {
52
+ result.push(new Range(other.end, this.end));
53
+ }
54
+ }
55
+
56
+ return result;
57
+ }
58
+
59
+ /**
60
+ * Determines if the given range overlaps with the current range.
61
+ *
62
+ * @param other The range to be checked for overlap.
63
+ * @returns Returns true if there is an overlap between the ranges, false otherwise.
64
+ */
65
+ public overlaps(other: Range<T>): boolean {
66
+ const s1 = this.start;
67
+ const e1 = this.end;
68
+ const s2 = other.start;
69
+ const e2 = other.end;
70
+
71
+ return (s2 > s1 && s2 < e1 || e2 > s1 && e2 < e1) ||
72
+ (s1 > s2 && s1 < e2 || e1 > s2 && e1 < e2) ||
73
+ (s1 === s2 && e1 === e2);
74
+ }
75
+
76
+ /**
77
+ * Determines whether the specified value is within the range defined by the start and end values.
78
+ *
79
+ * @param obj The value to check if it is within the range.
80
+ * @param inclusive Optional. If set to true, the range boundaries are considered inclusive.
81
+ * @returns Returns true if the specified value is within the range, false otherwise.
82
+ */
83
+ public contains(obj: T, inclusive: boolean = true): boolean {
84
+ return inclusive ?
85
+ (this.start <= obj && this.end >= obj) :
86
+ (this.start < obj && this.end > obj);
87
+ }
88
+
89
+ /**
90
+ * @returns T
91
+ */
92
+ public getStart(): T {
93
+ return this.start;
94
+ }
95
+
96
+ /**
97
+ * @returns T
98
+ */
99
+ public getEnd(): T {
100
+ return this.end;
101
+ }
102
+
103
+ /**
104
+ * Finds the intersection between two sets of ranges.
105
+ *
106
+ * @param ranges1
107
+ * @param ranges2
108
+ * @returns
109
+ */
110
+ public static intersectRanges<T>(ranges1: Range<T>[], ranges2: Range<T>[]): Range<T>[] {
111
+ const result: Range<T>[] = [];
112
+ for (const r1 of ranges1) {
113
+ for (const r2 of ranges2) {
114
+ const intersection = r1.intersect(r2);
115
+ if (intersection !== null) {
116
+ result.push(intersection);
117
+ }
118
+ }
119
+ }
120
+ return result;
121
+ }
122
+
123
+ /**
124
+ * Determines if any range in the first set overlaps with any range in the second set.
125
+ *
126
+ * @param ranges1
127
+ * @param ranges2
128
+ * @returns
129
+ */
130
+ public static overlapsAny<T>(ranges1: Range<T>[], ranges2: Range<T>[]): boolean {
131
+ for (const r1 of ranges1) {
132
+ for (const r2 of ranges2) {
133
+ if (r1.overlaps(r2)) {
134
+ return true;
135
+ }
136
+ }
137
+ }
138
+ return false;
139
+ }
140
+
141
+ /**
142
+ * Subtracts the second set of ranges from the first set of ranges.
143
+ *
144
+ * @param ranges1
145
+ * @param ranges2
146
+ * @returns
147
+ */
148
+ public static subtractRanges<T>(ranges1: Range<T>[], ranges2: Range<T>[]): Range<T>[] {
149
+ let currentRanges = ranges1;
150
+ for (const r2 of ranges2) {
151
+ const nextRanges: Range<T>[] = [];
152
+ for (const r1 of currentRanges) {
153
+ const subtracted = r1.subtract(r2);
154
+ for (const s of subtracted) {
155
+ nextRanges.push(s);
156
+ }
157
+ }
158
+ currentRanges = nextRanges;
159
+ if (currentRanges.length === 0) {
160
+ break;
161
+ }
162
+ }
163
+ return currentRanges;
164
+ }
165
+ }