@develia/commons 0.3.12 → 0.3.13
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.cjs.js.map +1 -1
- package/dist/index.esm.js.map +1 -1
- package/package.json +3 -2
- package/src/cache-dictionary.ts +78 -0
- package/src/from.ts +526 -0
- package/src/functions.ts +247 -0
- package/src/index.ts +11 -0
- package/src/lazy.ts +32 -0
- package/src/pair.ts +19 -0
- package/src/timer.ts +65 -0
- package/src/timespan.ts +217 -0
- package/src/types.ts +14 -0
package/src/functions.ts
ADDED
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
// noinspection JSUnusedGlobalSymbols
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
import Pair from "./pair";
|
|
5
|
+
import {Nullable, Provider} from "./types";
|
|
6
|
+
|
|
7
|
+
export function isIterable(obj: any): boolean {
|
|
8
|
+
return obj[Symbol.iterator] === 'function';
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function clamp(n: number, min: number, max: number) {
|
|
12
|
+
if (n <= min)
|
|
13
|
+
return min;
|
|
14
|
+
if (n >= max)
|
|
15
|
+
return max;
|
|
16
|
+
return n
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Linearly remaps a value from its source range [`inMin`, `inMax`] to the destination range [`outMin`, `outMax`]
|
|
21
|
+
*
|
|
22
|
+
* @category Math
|
|
23
|
+
* @example
|
|
24
|
+
* ```
|
|
25
|
+
* const value = remap(0.5, 0, 1, 200, 400) // value will be 300
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
export function lerp(n: number, inMin: number, inMax: number, outMin: number, outMax: number) {
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
return outMin + (outMax - outMin) * ((n - inMin) / (inMax - inMin))
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Ensure prefix of a string
|
|
39
|
+
*
|
|
40
|
+
* @category String
|
|
41
|
+
*/
|
|
42
|
+
export function ensurePrefix(prefix: string, str: string) {
|
|
43
|
+
if (!str.startsWith(prefix))
|
|
44
|
+
return prefix + str
|
|
45
|
+
return str
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Ensure suffix of a string
|
|
50
|
+
*
|
|
51
|
+
* @category String
|
|
52
|
+
*/
|
|
53
|
+
export function ensureSuffix(suffix: string, str: string) {
|
|
54
|
+
if (!str.endsWith(suffix))
|
|
55
|
+
return str + suffix
|
|
56
|
+
return str
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export function isString(value: any): value is string {
|
|
60
|
+
return typeof value === 'string';
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export function isNumber(value: any): value is number {
|
|
64
|
+
return typeof value === 'number';
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export function isBoolean(value: any): value is boolean {
|
|
68
|
+
return typeof value === 'boolean';
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export function isObject(value: any): value is object {
|
|
72
|
+
return value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export function isArray(value: any): value is any[] {
|
|
76
|
+
return Array.isArray(value);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export function isFunction(value: any): value is Function {
|
|
80
|
+
return typeof value === 'function';
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export function isUndefined(value: any): value is undefined {
|
|
84
|
+
return typeof value === 'undefined';
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export function isNull(value: any): value is null {
|
|
88
|
+
return value === null;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export function isBigInt(value: any): value is bigint {
|
|
92
|
+
return typeof value === 'bigint';
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export function isSymbol(value: any): value is symbol {
|
|
96
|
+
return typeof value === 'symbol';
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export function isNullOrUndefined(value: any) {
|
|
100
|
+
return value === null || typeof value === 'undefined';
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export function isEmpty(value: any): boolean {
|
|
104
|
+
return (Array.isArray(value) && value.length === 0) ||
|
|
105
|
+
(typeof value === 'string' && value === '') ||
|
|
106
|
+
value === null || typeof value === 'undefined';
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
export function isEmptyOrWhitespace(value: any): boolean {
|
|
110
|
+
return (Array.isArray(value) && value.length === 0) ||
|
|
111
|
+
(typeof value === 'string' && value.trim() === '') ||
|
|
112
|
+
value === null || typeof value === 'undefined';
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
export async function ajaxSubmit(selectorOrElement: HTMLFormElement | string): Promise<Response> {
|
|
117
|
+
|
|
118
|
+
const form = typeof selectorOrElement === 'string'
|
|
119
|
+
? document.querySelector(selectorOrElement)
|
|
120
|
+
: selectorOrElement;
|
|
121
|
+
|
|
122
|
+
if (!(form instanceof HTMLFormElement)) {
|
|
123
|
+
throw new Error("Invalid element.");
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// Crear un objeto FormData a partir del formulario
|
|
127
|
+
return await fetch(form.action, {
|
|
128
|
+
method: form.method,
|
|
129
|
+
body: new FormData(form),
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
export function toPairs(obj: any): Pair<any, any>[] {
|
|
134
|
+
|
|
135
|
+
let output = [];
|
|
136
|
+
for (const key in obj) {
|
|
137
|
+
output.push(new Pair(key, obj[key]));
|
|
138
|
+
}
|
|
139
|
+
return output;
|
|
140
|
+
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
export function promisify<T>(thing: any): Promise<T> {
|
|
144
|
+
|
|
145
|
+
if (thing instanceof Promise)
|
|
146
|
+
return thing;
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
if (isFunction(thing)) {
|
|
150
|
+
return new Promise<T>((resolve, reject) => {
|
|
151
|
+
try {
|
|
152
|
+
const result = thing();
|
|
153
|
+
resolve(result);
|
|
154
|
+
} catch (error) {
|
|
155
|
+
reject(error);
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
return Promise.resolve(thing);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
export function ajaxSubmission(selectorOrElement: HTMLFormElement | string,
|
|
164
|
+
onSuccess: Nullable<Provider<Nullable<any>>> = null,
|
|
165
|
+
onFailure: Nullable<Provider<Nullable<any>>> = null) {
|
|
166
|
+
|
|
167
|
+
const form = typeof selectorOrElement === 'string'
|
|
168
|
+
? document.querySelector(selectorOrElement)
|
|
169
|
+
: selectorOrElement;
|
|
170
|
+
|
|
171
|
+
if (!(form instanceof HTMLFormElement)) {
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
form.addEventListener('submit', async (event) => {
|
|
176
|
+
event.preventDefault();
|
|
177
|
+
let promise = ajaxSubmit(form);
|
|
178
|
+
if (promise) {
|
|
179
|
+
if (onSuccess)
|
|
180
|
+
promise = promise.then(onSuccess);
|
|
181
|
+
if (onFailure)
|
|
182
|
+
promise.catch(onFailure);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
export function deepClone<T>(obj: T): T {
|
|
192
|
+
if (obj === null || typeof obj !== 'object') {
|
|
193
|
+
return obj;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
if (Array.isArray(obj)) {
|
|
197
|
+
const copy: any[] = [];
|
|
198
|
+
for (const element of obj) {
|
|
199
|
+
copy.push(deepClone(element));
|
|
200
|
+
}
|
|
201
|
+
return copy as T;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
const copy: { [key: string]: any } = {};
|
|
205
|
+
for (const key in obj) {
|
|
206
|
+
if (obj.hasOwnProperty(key)) {
|
|
207
|
+
copy[key] = deepClone((obj as { [key: string]: any })[key]);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
return copy as T;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
function _objectToFormData(data: Record<string, any>, formData: FormData, parentKey: string = ''): FormData {
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
for (const key in data) {
|
|
217
|
+
if (data.hasOwnProperty(key)) {
|
|
218
|
+
const value = data[key];
|
|
219
|
+
|
|
220
|
+
if (value instanceof Date) {
|
|
221
|
+
formData.append(parentKey ? `${parentKey}[${key}]` : key, value.toISOString());
|
|
222
|
+
} else if (value instanceof File) {
|
|
223
|
+
formData.append(parentKey ? `${parentKey}[${key}]` : key, value);
|
|
224
|
+
} else if (typeof value === 'object' && !Array.isArray(value)) {
|
|
225
|
+
_objectToFormData(value, formData, parentKey ? `${parentKey}[${key}]` : key);
|
|
226
|
+
} else if (Array.isArray(value)) {
|
|
227
|
+
value.forEach((item, index) => {
|
|
228
|
+
const arrayKey = `${parentKey ? `${parentKey}[${key}]` : key}[${index}]`;
|
|
229
|
+
if (typeof item === 'object' && !Array.isArray(item)) {
|
|
230
|
+
_objectToFormData(item, formData, arrayKey);
|
|
231
|
+
} else {
|
|
232
|
+
formData.append(arrayKey, item);
|
|
233
|
+
}
|
|
234
|
+
});
|
|
235
|
+
} else {
|
|
236
|
+
formData.append(parentKey ? `${parentKey}[${key}]` : key, value);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
return formData;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
export function objectToFormData(data: Record<string, any>): FormData {
|
|
245
|
+
let formData = new FormData();
|
|
246
|
+
return _objectToFormData(data, formData);
|
|
247
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export * from './functions';
|
|
2
|
+
export {default as CacheDictionary} from './cache-dictionary';
|
|
3
|
+
export {default as from, From} from './from';
|
|
4
|
+
export * from './types';
|
|
5
|
+
export {default as Timer} from './timer'
|
|
6
|
+
export {default as TimeSpan} from './timespan'
|
|
7
|
+
export {default as Lazy} from './lazy'
|
|
8
|
+
export {default as Pair} from './pair'
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
package/src/lazy.ts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import {promisify} from "./functions";
|
|
2
|
+
import {Nullable} from "./types";
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
type FactoryMethod<T> = Promise<Nullable<T>> | (() => (Promise<Nullable<T>> | Nullable<T>));
|
|
6
|
+
|
|
7
|
+
export default class Lazy<T> {
|
|
8
|
+
private _valueCreated = false;
|
|
9
|
+
private _value: Nullable<T> = null;
|
|
10
|
+
private readonly _factoryMethod: FactoryMethod<T>;
|
|
11
|
+
|
|
12
|
+
constructor(getter: FactoryMethod<T>) {
|
|
13
|
+
this._factoryMethod = getter;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
get valueCreated(): boolean {
|
|
17
|
+
return this._valueCreated;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
async getValue(): Promise<Nullable<T>> {
|
|
21
|
+
if (!this._valueCreated) {
|
|
22
|
+
this._value = await promisify(this._factoryMethod);
|
|
23
|
+
this._valueCreated = true;
|
|
24
|
+
}
|
|
25
|
+
return this._value;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
reset(): void {
|
|
29
|
+
this._valueCreated = false;
|
|
30
|
+
this._value = null;
|
|
31
|
+
}
|
|
32
|
+
}
|
package/src/pair.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export default class Pair<TKey, TValue> {
|
|
2
|
+
get value(): TValue {
|
|
3
|
+
return this._value;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
get key(): TKey {
|
|
7
|
+
return this._key;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
private readonly _key: TKey;
|
|
11
|
+
private readonly _value: TValue;
|
|
12
|
+
|
|
13
|
+
constructor(key: TKey, value: TValue) {
|
|
14
|
+
this._key = key;
|
|
15
|
+
this._value = value;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
}
|
package/src/timer.ts
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
export default class Timer {
|
|
2
|
+
|
|
3
|
+
private _callback: () => void;
|
|
4
|
+
private _interval: number;
|
|
5
|
+
private _intervalId: any | null;
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @param callback Callback
|
|
9
|
+
* @param interval Seconds between calls
|
|
10
|
+
*/
|
|
11
|
+
constructor(callback: () => void, interval: number) {
|
|
12
|
+
this._callback = callback;
|
|
13
|
+
this._interval = interval;
|
|
14
|
+
this._intervalId = null;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
get running(): boolean {
|
|
19
|
+
return this._intervalId !== null && this._intervalId !== undefined;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
get interval(): number {
|
|
23
|
+
return this._interval;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
set interval(value: number) {
|
|
27
|
+
if (value != this._interval) {
|
|
28
|
+
this._interval = value;
|
|
29
|
+
if (this.running)
|
|
30
|
+
this.restart();
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
get callback(): () => void {
|
|
35
|
+
return this._callback;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
set callback(value: () => void) {
|
|
39
|
+
if (value != this._callback) {
|
|
40
|
+
this._callback = value;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
start(): void {
|
|
46
|
+
if (this._intervalId === null) {
|
|
47
|
+
this._intervalId = setInterval(() => {
|
|
48
|
+
if (this._callback != null)
|
|
49
|
+
this._callback();
|
|
50
|
+
}, this._interval);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
stop(): void {
|
|
55
|
+
if (this._intervalId !== null) {
|
|
56
|
+
clearInterval(this._intervalId);
|
|
57
|
+
this._intervalId = null;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
restart(): void {
|
|
62
|
+
this.stop();
|
|
63
|
+
this.start();
|
|
64
|
+
}
|
|
65
|
+
}
|
package/src/timespan.ts
ADDED
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
export default class TimeSpan {
|
|
2
|
+
public milliseconds: number;
|
|
3
|
+
|
|
4
|
+
private constructor(milliseconds: number) {
|
|
5
|
+
this.milliseconds = milliseconds;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
// Obtener el intervalo de tiempo en segundos
|
|
10
|
+
seconds(): number {
|
|
11
|
+
return this.milliseconds / 1000;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// Obtener el intervalo de tiempo en minutos
|
|
15
|
+
minutes(): number {
|
|
16
|
+
return this.milliseconds / (1000 * 60);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// Obtener el intervalo de tiempo en horas
|
|
20
|
+
hours(): number {
|
|
21
|
+
return this.milliseconds / (1000 * 60 * 60);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// Obtener el intervalo de tiempo en días
|
|
25
|
+
days(): number {
|
|
26
|
+
return this.milliseconds / (1000 * 60 * 60 * 24);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// Obtener el intervalo de tiempo en semanas
|
|
30
|
+
weeks(): number {
|
|
31
|
+
return this.milliseconds / (1000 * 60 * 60 * 24 * 7);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Constructor estático para crear un TimeSpan desde milisegundos
|
|
35
|
+
static fromMilliseconds(milliseconds: number): TimeSpan {
|
|
36
|
+
return new TimeSpan(milliseconds);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Constructor estático para crear un TimeSpan desde segundos
|
|
40
|
+
static fromSeconds(seconds: number): TimeSpan {
|
|
41
|
+
return new TimeSpan(seconds * 1000);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Constructor estático para crear un TimeSpan desde minutos
|
|
45
|
+
static fromMinutes(minutes: number): TimeSpan {
|
|
46
|
+
return new TimeSpan(minutes * 1000 * 60);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Constructor estático para crear un TimeSpan desde horas
|
|
50
|
+
static fromHours(hours: number): TimeSpan {
|
|
51
|
+
return new TimeSpan(hours * 1000 * 60 * 60);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Constructor estático para crear un TimeSpan desde días
|
|
55
|
+
static fromDays(days: number): TimeSpan {
|
|
56
|
+
return new TimeSpan(days * 1000 * 60 * 60 * 24);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Constructor estático para crear un TimeSpan desde semanas
|
|
60
|
+
static fromWeeks(weeks: number): TimeSpan {
|
|
61
|
+
return new TimeSpan(weeks * 1000 * 60 * 60 * 24 * 7);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Añadir un intervalo de tiempo
|
|
65
|
+
addMilliseconds(milliseconds: number): TimeSpan {
|
|
66
|
+
return new TimeSpan(this.milliseconds + milliseconds);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
addSeconds(seconds: number): TimeSpan {
|
|
70
|
+
return this.addMilliseconds(seconds * 1000);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
addMinutes(minutes: number): TimeSpan {
|
|
74
|
+
return this.addMilliseconds(minutes * 1000 * 60);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
addHours(hours: number): TimeSpan {
|
|
78
|
+
return this.addMilliseconds(hours * 1000 * 60 * 60);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
addDays(days: number): TimeSpan {
|
|
82
|
+
return this.addMilliseconds(days * 1000 * 60 * 60 * 24);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
addWeeks(weeks: number): TimeSpan {
|
|
86
|
+
return this.addMilliseconds(weeks * 1000 * 60 * 60 * 24 * 7);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Restar un intervalo de tiempo
|
|
90
|
+
subtractMilliseconds(milliseconds: number): TimeSpan {
|
|
91
|
+
return new TimeSpan(this.milliseconds - milliseconds);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
subtractSeconds(seconds: number): TimeSpan {
|
|
95
|
+
return this.subtractMilliseconds(seconds * 1000);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
subtractMinutes(minutes: number): TimeSpan {
|
|
99
|
+
return this.subtractMilliseconds(minutes * 1000 * 60);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
subtractHours(hours: number): TimeSpan {
|
|
103
|
+
return this.subtractMilliseconds(hours * 1000 * 60 * 60);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
subtractDays(days: number): TimeSpan {
|
|
107
|
+
return this.subtractMilliseconds(days * 1000 * 60 * 60 * 24);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
subtractWeeks(weeks: number): TimeSpan {
|
|
111
|
+
return this.subtractMilliseconds(weeks * 1000 * 60 * 60 * 24 * 7);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// Añadir otro TimeSpan
|
|
115
|
+
add(other: TimeSpan): TimeSpan {
|
|
116
|
+
return new TimeSpan(this.milliseconds + other.milliseconds);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// Restar otro TimeSpan
|
|
120
|
+
subtract(other: TimeSpan): TimeSpan {
|
|
121
|
+
return new TimeSpan(this.milliseconds - other.milliseconds);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// Añadir un intervalo de tiempo a una fecha
|
|
125
|
+
addTo(date: Date): Date {
|
|
126
|
+
return new Date(date.getTime() + this.milliseconds);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// Restar un intervalo de tiempo de una fecha
|
|
130
|
+
subtractFrom(date: Date): Date {
|
|
131
|
+
return new Date(date.getTime() - this.milliseconds);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
static fromDifference(earlierDate: Date, laterDate: Date): TimeSpan {
|
|
136
|
+
return new TimeSpan(laterDate.getTime() - earlierDate.getTime());
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
format(format: string = 'hh:mm:ss'): string {
|
|
140
|
+
const formatLower = format.toLowerCase();
|
|
141
|
+
const hasHours = formatLower.includes("h");
|
|
142
|
+
const hasMinutes = formatLower.includes("m");
|
|
143
|
+
|
|
144
|
+
let hours = 0, minutes = 0, seconds = Math.floor(this.milliseconds / 1000);
|
|
145
|
+
|
|
146
|
+
if (hasHours) {
|
|
147
|
+
hours = Math.floor(seconds / 3600);
|
|
148
|
+
seconds -= hours * 3600;
|
|
149
|
+
}
|
|
150
|
+
if (hasMinutes) {
|
|
151
|
+
minutes = Math.floor(seconds / 60);
|
|
152
|
+
seconds -= minutes * 60;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
const hoursPadded = String(hours).padStart(2, '0');
|
|
156
|
+
const minutesPadded = String(minutes).padStart(2, '0');
|
|
157
|
+
const secondsPadded = String(seconds).padStart(2, '0');
|
|
158
|
+
|
|
159
|
+
return formatLower
|
|
160
|
+
.replace('hh', hoursPadded)
|
|
161
|
+
.replace('h', hours.toString())
|
|
162
|
+
.replace('mm', minutesPadded)
|
|
163
|
+
.replace('m', minutes.toString())
|
|
164
|
+
.replace('ss', secondsPadded)
|
|
165
|
+
.replace('s', seconds.toString());
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
eq(other: TimeSpan): boolean {
|
|
169
|
+
return this.milliseconds === other.milliseconds;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
le(other: TimeSpan): boolean {
|
|
173
|
+
return this.milliseconds <= other.milliseconds;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
lt(other: TimeSpan): boolean {
|
|
177
|
+
return this.milliseconds < other.milliseconds;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
ge(other: TimeSpan): boolean {
|
|
181
|
+
return this.milliseconds >= other.milliseconds;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
gt(other: TimeSpan): boolean {
|
|
185
|
+
return this.milliseconds > other.milliseconds;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
multiply(number: number): TimeSpan {
|
|
189
|
+
return new TimeSpan(this.milliseconds * number);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
divide(number: number): TimeSpan {
|
|
193
|
+
return new TimeSpan(this.milliseconds / number);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
abs(): TimeSpan {
|
|
197
|
+
return new TimeSpan(Math.abs(this.milliseconds));
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
static readonly INFINITE = new TimeSpan(Number.POSITIVE_INFINITY);
|
|
201
|
+
|
|
202
|
+
static readonly NEGATIVE_INFINITE = new TimeSpan(Number.NEGATIVE_INFINITY);
|
|
203
|
+
|
|
204
|
+
isInfinite() {
|
|
205
|
+
return this.milliseconds === Number.POSITIVE_INFINITY || this.milliseconds === Number.NEGATIVE_INFINITY
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// Determinar si es un TimeSpan infinitamente positivo
|
|
209
|
+
isPositiveInfinite(): boolean {
|
|
210
|
+
return this.milliseconds === Number.POSITIVE_INFINITY;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// Determinar si es un TimeSpan infinitamente negativo
|
|
214
|
+
isNegativeInfinite(): boolean {
|
|
215
|
+
return this.milliseconds === Number.NEGATIVE_INFINITY;
|
|
216
|
+
}
|
|
217
|
+
}
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export type EqualityComparer<T> = (arg1: T, arg2: T) => boolean;
|
|
2
|
+
|
|
3
|
+
export type UnaryFunction<T, R> = (arg: T) => R;
|
|
4
|
+
|
|
5
|
+
export type Consumer<T> = (arg: T) => void
|
|
6
|
+
|
|
7
|
+
export type Predicate<T> = (arg: T) => boolean;
|
|
8
|
+
|
|
9
|
+
export type Provider<T> = () => T;
|
|
10
|
+
|
|
11
|
+
export type Nullable<T> = T | null;
|
|
12
|
+
|
|
13
|
+
export type Deferred<T> = Promise<T> | Provider<T>
|
|
14
|
+
|