@pvorona/duration 0.1.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +64 -5
- package/dist/index.js +161 -108
- package/dist/lib/duration.d.ts +24 -0
- package/dist/lib/duration.d.ts.map +1 -1
- package/package.json +6 -1
package/README.md
CHANGED
|
@@ -19,10 +19,26 @@ import { duration, TimeUnit } from '@pvorona/duration';
|
|
|
19
19
|
|
|
20
20
|
const d = duration(2, TimeUnit.Minute);
|
|
21
21
|
d.toSeconds(); // 120
|
|
22
|
-
d.toMilliseconds(); //
|
|
22
|
+
d.toMilliseconds(); // 120_000
|
|
23
23
|
duration(250, TimeUnit.Millisecond).toSeconds(); // 0.25
|
|
24
24
|
```
|
|
25
25
|
|
|
26
|
+
### Compose from multiple units
|
|
27
|
+
|
|
28
|
+
```ts
|
|
29
|
+
import { duration } from '@pvorona/duration';
|
|
30
|
+
|
|
31
|
+
const total = duration({ minutes: 1, seconds: 30 });
|
|
32
|
+
total.toSeconds(); // 90
|
|
33
|
+
|
|
34
|
+
const negative = duration({ hours: -1, minutes: -30 });
|
|
35
|
+
negative.toMilliseconds(); // -5_400_000
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
`duration(parts)` accepts only the exact plural keys `milliseconds`, `seconds`, `minutes`, `hours`, `days`, `weeks`, `months`, and `years`.
|
|
39
|
+
|
|
40
|
+
All non-zero parts must share the same sign. For example, `duration({ hours: 1, minutes: -30 })` throws `TypeError`.
|
|
41
|
+
|
|
26
42
|
### Compare
|
|
27
43
|
|
|
28
44
|
```ts
|
|
@@ -54,20 +70,45 @@ const elapsed = since(startedAt);
|
|
|
54
70
|
elapsed.toSeconds(); // ~2
|
|
55
71
|
```
|
|
56
72
|
|
|
57
|
-
|
|
73
|
+
### Apply a duration to a date
|
|
74
|
+
|
|
75
|
+
```ts
|
|
76
|
+
import { addTo, seconds, subtractFrom } from '@pvorona/duration';
|
|
77
|
+
|
|
78
|
+
const start = new Date(1_000);
|
|
79
|
+
|
|
80
|
+
addTo(start, seconds(2)).getTime(); // 3_000
|
|
81
|
+
subtractFrom(start, seconds(2)).getTime(); // -1_000
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Important semantics
|
|
58
85
|
|
|
59
86
|
- ESM-only package: use `import`, not `require(...)`.
|
|
87
|
+
- Duration values are frozen branded objects created by this package. Use `isDuration(...)` for unknown inputs instead of duck typing.
|
|
88
|
+
- Compare durations by value with `d.equals(other)` or `isEqual(a, b)`, not `===`.
|
|
89
|
+
- Do not spread, JSON-serialize, or structured-clone `Duration` values as a transport format. Serialize your own explicit shape and reconstruct with `milliseconds(...)` for finite values or `infinite` for the sentinel.
|
|
90
|
+
- `DurationParts` is constructor input only. It is not a serialized `Duration` format and should not be treated as one.
|
|
91
|
+
- `instant` is the exported zero-duration constant, but any zero-valued duration has `isInstant === true`.
|
|
92
|
+
- The public millisecond APIs are `TimeUnit.Millisecond`, `milliseconds(...)`, and `toMilliseconds()`.
|
|
60
93
|
- `Month` is treated as 30 days and `Year` as 365.25 days. These are approximations, not calendar-aware durations.
|
|
61
94
|
- Negative finite durations are valid. `between(...)`, `since(...)`, arithmetic, and comparisons can produce or operate on negative values.
|
|
62
95
|
- Constructors accept only finite numeric inputs. `infinite` is the only supported non-finite duration.
|
|
96
|
+
- `duration(parts)` requires at least one supported plural key, rejects unknown keys, rejects non-finite part values, and rejects mixed-sign non-zero parts.
|
|
63
97
|
- `add(infinite, x)`, `subtract(infinite, finite)`, `multiply(infinite, positive finite)`, and `divide(infinite, positive finite)` return `infinite`.
|
|
98
|
+
- `addTo(date, duration)` and `subtractFrom(date, duration)` do exact timestamp arithmetic equivalent to `new Date(date.getTime() +/- duration.toMilliseconds())`.
|
|
99
|
+
- `addTo(...)` and `subtractFrom(...)` reject invalid dates, reject `infinite`, and reject result timestamps outside the JavaScript `Date` range.
|
|
100
|
+
- `addTo(...)` and `subtractFrom(...)` are timestamp-based, not calendar-aware. Local clock time may shift across DST or timezone offset transitions.
|
|
101
|
+
- `Date` values only have millisecond precision, so the date helpers follow native JavaScript `Date` semantics for fractional-millisecond timestamps.
|
|
64
102
|
- Invalid units, invalid dates, non-finite scalar inputs, divide-by-zero, `subtract(infinite, infinite)`, `subtract(finite, infinite)`, `multiply(infinite, 0)`, `multiply(infinite, negative)`, and `divide(infinite, negative)` throw `TypeError`.
|
|
65
103
|
|
|
66
104
|
## API
|
|
67
105
|
|
|
68
106
|
### `TimeUnit`
|
|
69
107
|
|
|
70
|
-
|
|
108
|
+
The package exports both:
|
|
109
|
+
|
|
110
|
+
- `type TimeUnit`: the union of the supported runtime unit values
|
|
111
|
+
- `const TimeUnit`: the runtime constants accepted by `duration(value, unit)` and `d.to(unit)`
|
|
71
112
|
|
|
72
113
|
- `TimeUnit.Millisecond`
|
|
73
114
|
- `TimeUnit.Second`
|
|
@@ -80,13 +121,13 @@ Runtime unit constants supported by `duration(value, unit)` and `d.to(unit)`.
|
|
|
80
121
|
|
|
81
122
|
### `type Duration`
|
|
82
123
|
|
|
83
|
-
An opaque, immutable duration value.
|
|
124
|
+
An opaque, immutable duration value. Duration instances are branded by the package, so use `isDuration(...)` for unknown inputs and compare values with `equals(...)` / `isEqual(...)` rather than `===`.
|
|
84
125
|
|
|
85
126
|
#### Properties
|
|
86
127
|
|
|
87
128
|
- **`isFinite: boolean`**: `true` for finite durations
|
|
88
129
|
- **`isInfinite: boolean`**: `true` only for `infinite`
|
|
89
|
-
- **`isInstant: boolean`**: `true` for zero duration (`instant`)
|
|
130
|
+
- **`isInstant: boolean`**: `true` for any zero duration (including `instant`)
|
|
90
131
|
|
|
91
132
|
#### Conversions
|
|
92
133
|
|
|
@@ -125,11 +166,27 @@ isShort(a); // true
|
|
|
125
166
|
a.greaterThan(b); // true
|
|
126
167
|
```
|
|
127
168
|
|
|
169
|
+
### `type DurationParts`
|
|
170
|
+
|
|
171
|
+
Strict constructor input for `duration(parts)`. Supported keys:
|
|
172
|
+
|
|
173
|
+
- `milliseconds?: number`
|
|
174
|
+
- `seconds?: number`
|
|
175
|
+
- `minutes?: number`
|
|
176
|
+
- `hours?: number`
|
|
177
|
+
- `days?: number`
|
|
178
|
+
- `weeks?: number`
|
|
179
|
+
- `months?: number`
|
|
180
|
+
- `years?: number`
|
|
181
|
+
|
|
182
|
+
At least one key is required. All non-zero keys must share the same sign.
|
|
183
|
+
|
|
128
184
|
### Function API
|
|
129
185
|
|
|
130
186
|
#### Constructors
|
|
131
187
|
|
|
132
188
|
- `duration(value: number, unit: TimeUnit): Duration`
|
|
189
|
+
- `duration(parts: DurationParts): Duration`
|
|
133
190
|
- `milliseconds(value: number): Duration`
|
|
134
191
|
- `seconds(value: number): Duration`
|
|
135
192
|
- `minutes(value: number): Duration`
|
|
@@ -143,6 +200,8 @@ a.greaterThan(b); // true
|
|
|
143
200
|
|
|
144
201
|
- `between(start: Date, end: Date): Duration`
|
|
145
202
|
- `since(start: Date): Duration`
|
|
203
|
+
- `addTo(date: Date, duration: Duration): Date`
|
|
204
|
+
- `subtractFrom(date: Date, duration: Duration): Date`
|
|
146
205
|
|
|
147
206
|
#### Arithmetic helpers
|
|
148
207
|
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { isObject as
|
|
2
|
-
const
|
|
1
|
+
import { isObject as T, hasOwnKey as b } from "@pvorona/assert";
|
|
2
|
+
const N = {
|
|
3
3
|
Millisecond: 0,
|
|
4
4
|
Second: 1,
|
|
5
5
|
Minute: 2,
|
|
@@ -8,196 +8,249 @@ const I = {
|
|
|
8
8
|
Week: 5,
|
|
9
9
|
Month: 6,
|
|
10
10
|
Year: 7
|
|
11
|
-
},
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
11
|
+
}, e = N, w = {
|
|
12
|
+
milliseconds: e.Millisecond,
|
|
13
|
+
seconds: e.Second,
|
|
14
|
+
minutes: e.Minute,
|
|
15
|
+
hours: e.Hour,
|
|
16
|
+
days: e.Day,
|
|
17
|
+
weeks: e.Week,
|
|
18
|
+
months: e.Month,
|
|
19
|
+
years: e.Year
|
|
20
|
+
}, r = /* @__PURE__ */ Symbol("milliseconds"), D = new Set(Object.values(e)), S = new Set(
|
|
21
|
+
Object.keys(w)
|
|
22
|
+
), d = {
|
|
23
|
+
[e.Millisecond]: 1,
|
|
24
|
+
[e.Second]: 1e3,
|
|
25
|
+
[e.Minute]: 60 * 1e3,
|
|
26
|
+
[e.Hour]: 3600 * 1e3,
|
|
16
27
|
/** Note: Does not account for leap second */
|
|
17
|
-
[
|
|
18
|
-
[
|
|
28
|
+
[e.Day]: 1440 * 60 * 1e3,
|
|
29
|
+
[e.Week]: 10080 * 60 * 1e3,
|
|
19
30
|
/** Note: Does not account for leap year */
|
|
20
|
-
[
|
|
31
|
+
[e.Month]: (
|
|
21
32
|
/* 30 days */
|
|
22
33
|
720 * 60 * 60 * 1e3
|
|
23
34
|
),
|
|
24
35
|
/** Note: Does not account for leap year */
|
|
25
|
-
[
|
|
36
|
+
[e.Year]: (
|
|
26
37
|
/* 365.25 days */
|
|
27
38
|
365.25 * 24 * 60 * 60 * 1e3
|
|
28
39
|
)
|
|
29
40
|
};
|
|
30
|
-
function
|
|
31
|
-
if (
|
|
41
|
+
function p(n) {
|
|
42
|
+
if (D.has(n))
|
|
32
43
|
return n;
|
|
33
44
|
throw new TypeError("Expected a valid time unit.");
|
|
34
45
|
}
|
|
35
|
-
function c(n,
|
|
46
|
+
function c(n, t) {
|
|
36
47
|
if (Number.isFinite(n))
|
|
37
48
|
return n;
|
|
38
|
-
throw new TypeError(`Expected \`${
|
|
49
|
+
throw new TypeError(`Expected \`${t}\` to be finite.`);
|
|
39
50
|
}
|
|
40
|
-
function
|
|
41
|
-
const
|
|
42
|
-
if (!Number.isNaN(
|
|
43
|
-
return
|
|
44
|
-
throw new TypeError(`Expected \`${
|
|
51
|
+
function a(n, t) {
|
|
52
|
+
const i = n.getTime();
|
|
53
|
+
if (!Number.isNaN(i))
|
|
54
|
+
return i;
|
|
55
|
+
throw new TypeError(`Expected \`${t}\` to be a valid date.`);
|
|
45
56
|
}
|
|
46
|
-
function y(n,
|
|
57
|
+
function y(n, t) {
|
|
58
|
+
const i = new Date(n);
|
|
59
|
+
return a(i, t), i;
|
|
60
|
+
}
|
|
61
|
+
function g(n) {
|
|
62
|
+
if (S.has(n))
|
|
63
|
+
return n;
|
|
64
|
+
throw new TypeError(`Expected \`${n}\` to be a supported duration part.`);
|
|
65
|
+
}
|
|
66
|
+
function _(n) {
|
|
67
|
+
const t = Object.entries(n);
|
|
68
|
+
if (t.length === 0)
|
|
69
|
+
throw new TypeError("Expected `parts` to include at least one duration part.");
|
|
70
|
+
let i = 0, o;
|
|
71
|
+
for (const [E, M] of t) {
|
|
72
|
+
const h = g(E), l = c(M, `parts.${h}`);
|
|
73
|
+
if (l === 0)
|
|
74
|
+
continue;
|
|
75
|
+
const m = Math.sign(l);
|
|
76
|
+
if (o == null && (o = m), o !== m)
|
|
77
|
+
throw new TypeError("Expected non-zero duration parts to share the same sign.");
|
|
78
|
+
i += l * d[w[h]];
|
|
79
|
+
}
|
|
80
|
+
return i;
|
|
81
|
+
}
|
|
82
|
+
function O(n, t) {
|
|
47
83
|
if (Number.isNaN(n) || n === Number.NEGATIVE_INFINITY)
|
|
48
84
|
throw new TypeError("Expected duration milliseconds to be finite or `Infinity`.");
|
|
49
|
-
if (n !== 1 / 0 ||
|
|
85
|
+
if (n !== 1 / 0 || t?.allowInfinite)
|
|
50
86
|
return n;
|
|
51
87
|
throw new TypeError("Expected duration milliseconds to be finite.");
|
|
52
88
|
}
|
|
53
|
-
const
|
|
54
|
-
[
|
|
89
|
+
const U = {
|
|
90
|
+
[r]: 0,
|
|
55
91
|
isFinite: !1,
|
|
56
92
|
isInfinite: !1,
|
|
57
93
|
isInstant: !1,
|
|
58
94
|
to(n) {
|
|
59
|
-
return this[
|
|
95
|
+
return this[r] / d[p(n)];
|
|
60
96
|
},
|
|
61
97
|
toMilliseconds() {
|
|
62
|
-
return this.to(
|
|
98
|
+
return this.to(e.Millisecond);
|
|
63
99
|
},
|
|
64
100
|
toSeconds() {
|
|
65
|
-
return this.to(
|
|
101
|
+
return this.to(e.Second);
|
|
66
102
|
},
|
|
67
103
|
toMinutes() {
|
|
68
|
-
return this.to(
|
|
104
|
+
return this.to(e.Minute);
|
|
69
105
|
},
|
|
70
106
|
toHours() {
|
|
71
|
-
return this.to(
|
|
107
|
+
return this.to(e.Hour);
|
|
72
108
|
},
|
|
73
109
|
toDays() {
|
|
74
|
-
return this.to(
|
|
110
|
+
return this.to(e.Day);
|
|
75
111
|
},
|
|
76
112
|
toWeeks() {
|
|
77
|
-
return this.to(
|
|
113
|
+
return this.to(e.Week);
|
|
78
114
|
},
|
|
79
115
|
toMonths() {
|
|
80
|
-
return this.to(
|
|
116
|
+
return this.to(e.Month);
|
|
81
117
|
},
|
|
82
118
|
toYears() {
|
|
83
|
-
return this.to(
|
|
119
|
+
return this.to(e.Year);
|
|
84
120
|
},
|
|
85
121
|
equals(n) {
|
|
86
|
-
return this[
|
|
122
|
+
return this[r] === n[r];
|
|
87
123
|
},
|
|
88
124
|
lessThan(n) {
|
|
89
|
-
return this[
|
|
125
|
+
return this[r] < n[r];
|
|
90
126
|
},
|
|
91
127
|
lessThanOrEqual(n) {
|
|
92
|
-
return this[
|
|
128
|
+
return this[r] <= n[r];
|
|
93
129
|
},
|
|
94
130
|
greaterThan(n) {
|
|
95
|
-
return this[
|
|
131
|
+
return this[r] > n[r];
|
|
96
132
|
},
|
|
97
133
|
greaterThanOrEqual(n) {
|
|
98
|
-
return this[
|
|
134
|
+
return this[r] >= n[r];
|
|
99
135
|
},
|
|
100
136
|
compare(n) {
|
|
101
137
|
return this.lessThan(n) ? -1 : this.greaterThan(n) ? 1 : 0;
|
|
102
138
|
}
|
|
103
139
|
};
|
|
104
|
-
function
|
|
105
|
-
const
|
|
106
|
-
return o[
|
|
140
|
+
function s(n, t) {
|
|
141
|
+
const i = O(n, t), o = Object.create(U);
|
|
142
|
+
return o[r] = i, o.isFinite = Number.isFinite(i), o.isInfinite = i === 1 / 0, o.isInstant = i === 0, Object.freeze(o);
|
|
107
143
|
}
|
|
108
|
-
function
|
|
109
|
-
|
|
110
|
-
|
|
144
|
+
function u(n, t) {
|
|
145
|
+
if (T(n))
|
|
146
|
+
return s(_(n));
|
|
147
|
+
const i = c(n, "value"), o = p(t);
|
|
148
|
+
return s(i * d[o]);
|
|
111
149
|
}
|
|
112
|
-
function
|
|
113
|
-
return
|
|
150
|
+
function x(n) {
|
|
151
|
+
return u(n, e.Millisecond);
|
|
114
152
|
}
|
|
115
|
-
function
|
|
116
|
-
return
|
|
153
|
+
function z(n) {
|
|
154
|
+
return u(n, e.Second);
|
|
117
155
|
}
|
|
118
|
-
function
|
|
119
|
-
return
|
|
156
|
+
function A(n) {
|
|
157
|
+
return u(n, e.Minute);
|
|
120
158
|
}
|
|
121
|
-
function
|
|
122
|
-
return
|
|
159
|
+
function Y(n) {
|
|
160
|
+
return u(n, e.Hour);
|
|
123
161
|
}
|
|
124
|
-
function
|
|
125
|
-
return
|
|
162
|
+
function v(n) {
|
|
163
|
+
return u(n, e.Day);
|
|
126
164
|
}
|
|
127
|
-
function
|
|
128
|
-
return
|
|
165
|
+
function j(n) {
|
|
166
|
+
return u(n, e.Week);
|
|
129
167
|
}
|
|
130
|
-
function
|
|
131
|
-
return
|
|
168
|
+
function C(n) {
|
|
169
|
+
return u(n, e.Month);
|
|
132
170
|
}
|
|
133
|
-
function
|
|
134
|
-
return
|
|
171
|
+
function H(n) {
|
|
172
|
+
return u(n, e.Year);
|
|
135
173
|
}
|
|
136
|
-
function
|
|
137
|
-
const
|
|
138
|
-
return
|
|
174
|
+
function F(n, t) {
|
|
175
|
+
const i = a(n, "start"), o = a(t, "end");
|
|
176
|
+
return s(o - i);
|
|
139
177
|
}
|
|
140
|
-
function
|
|
141
|
-
return
|
|
178
|
+
function V(n) {
|
|
179
|
+
return F(n, /* @__PURE__ */ new Date());
|
|
180
|
+
}
|
|
181
|
+
function I(n) {
|
|
182
|
+
if (!n.isInfinite)
|
|
183
|
+
return n.toMilliseconds();
|
|
184
|
+
throw new TypeError("Expected `duration` to be finite.");
|
|
142
185
|
}
|
|
143
|
-
function
|
|
144
|
-
return n.isInfinite ||
|
|
186
|
+
function W(n, t) {
|
|
187
|
+
return n.isInfinite || t.isInfinite ? f : s(n[r] + t[r]);
|
|
145
188
|
}
|
|
146
|
-
function
|
|
147
|
-
if (n.isInfinite &&
|
|
189
|
+
function R(n, t) {
|
|
190
|
+
if (n.isInfinite && t.isInfinite)
|
|
148
191
|
throw new TypeError("Cannot subtract `infinite` from `infinite`.");
|
|
149
192
|
if (n.isInfinite)
|
|
150
|
-
return
|
|
151
|
-
if (
|
|
193
|
+
return f;
|
|
194
|
+
if (t.isInfinite)
|
|
152
195
|
throw new TypeError("Cannot subtract `infinite` from a finite duration.");
|
|
153
|
-
return
|
|
196
|
+
return s(n[r] - t[r]);
|
|
154
197
|
}
|
|
155
|
-
function
|
|
156
|
-
const
|
|
198
|
+
function q(n, t) {
|
|
199
|
+
const i = c(t, "multiplier");
|
|
157
200
|
if (!n.isInfinite)
|
|
158
|
-
return
|
|
159
|
-
if (
|
|
160
|
-
return
|
|
201
|
+
return s(n[r] * i);
|
|
202
|
+
if (i > 0)
|
|
203
|
+
return f;
|
|
161
204
|
throw new TypeError(
|
|
162
205
|
"Cannot multiply `infinite` by zero or a negative number."
|
|
163
206
|
);
|
|
164
207
|
}
|
|
165
|
-
function
|
|
166
|
-
const
|
|
167
|
-
if (
|
|
208
|
+
function K(n, t) {
|
|
209
|
+
const i = c(t, "divisor");
|
|
210
|
+
if (i === 0)
|
|
168
211
|
throw new TypeError("Cannot divide by zero.");
|
|
169
212
|
if (!n.isInfinite)
|
|
170
|
-
return
|
|
171
|
-
if (
|
|
172
|
-
return
|
|
213
|
+
return s(n[r] / i);
|
|
214
|
+
if (i > 0)
|
|
215
|
+
return f;
|
|
173
216
|
throw new TypeError("Cannot divide `infinite` by a negative number.");
|
|
174
217
|
}
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
return
|
|
218
|
+
function $(n, t) {
|
|
219
|
+
const i = a(n, "date"), o = I(t);
|
|
220
|
+
return y(i + o, "result");
|
|
221
|
+
}
|
|
222
|
+
function L(n, t) {
|
|
223
|
+
const i = a(n, "date"), o = I(t);
|
|
224
|
+
return y(i - o, "result");
|
|
225
|
+
}
|
|
226
|
+
const f = s(1 / 0, { allowInfinite: !0 }), P = x(0);
|
|
227
|
+
function B(n) {
|
|
228
|
+
return T(n) && b(n, r);
|
|
178
229
|
}
|
|
179
|
-
function
|
|
180
|
-
return n[
|
|
230
|
+
function G(n, t) {
|
|
231
|
+
return n[r] === t[r];
|
|
181
232
|
}
|
|
182
233
|
export {
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
234
|
+
e as TimeUnit,
|
|
235
|
+
W as add,
|
|
236
|
+
$ as addTo,
|
|
237
|
+
F as between,
|
|
238
|
+
v as days,
|
|
239
|
+
K as divide,
|
|
240
|
+
u as duration,
|
|
241
|
+
Y as hours,
|
|
242
|
+
f as infinite,
|
|
243
|
+
P as instant,
|
|
244
|
+
B as isDuration,
|
|
245
|
+
G as isEqual,
|
|
246
|
+
x as milliseconds,
|
|
247
|
+
A as minutes,
|
|
248
|
+
C as months,
|
|
249
|
+
q as multiply,
|
|
250
|
+
z as seconds,
|
|
251
|
+
V as since,
|
|
252
|
+
R as subtract,
|
|
253
|
+
L as subtractFrom,
|
|
254
|
+
j as weeks,
|
|
255
|
+
H as years
|
|
203
256
|
};
|
package/dist/lib/duration.d.ts
CHANGED
|
@@ -18,6 +18,24 @@ export type TimeUnit = (typeof TIME_UNIT_VALUES)[keyof typeof TIME_UNIT_VALUES];
|
|
|
18
18
|
export declare const TimeUnit: {
|
|
19
19
|
readonly [Key in keyof typeof TIME_UNIT_VALUES]: TimeUnit;
|
|
20
20
|
};
|
|
21
|
+
declare const DURATION_PART_TIME_UNITS: {
|
|
22
|
+
readonly milliseconds: TimeUnit;
|
|
23
|
+
readonly seconds: TimeUnit;
|
|
24
|
+
readonly minutes: TimeUnit;
|
|
25
|
+
readonly hours: TimeUnit;
|
|
26
|
+
readonly days: TimeUnit;
|
|
27
|
+
readonly weeks: TimeUnit;
|
|
28
|
+
readonly months: TimeUnit;
|
|
29
|
+
readonly years: TimeUnit;
|
|
30
|
+
};
|
|
31
|
+
type DurationPartKey = keyof typeof DURATION_PART_TIME_UNITS;
|
|
32
|
+
type RequireAtLeastOne<T> = {
|
|
33
|
+
[Key in keyof T]-?: Required<Pick<T, Key>> & Partial<Omit<T, Key>>;
|
|
34
|
+
}[keyof T];
|
|
35
|
+
/** Input bag accepted by `duration(parts)` for strict multi-unit construction. */
|
|
36
|
+
export type DurationParts = RequireAtLeastOne<{
|
|
37
|
+
readonly [Key in DurationPartKey]?: number;
|
|
38
|
+
}>;
|
|
21
39
|
declare const millisecondsTag: unique symbol;
|
|
22
40
|
/** Immutable duration value with conversions, comparisons, and state flags. */
|
|
23
41
|
export type Duration = {
|
|
@@ -43,6 +61,8 @@ export type Duration = {
|
|
|
43
61
|
};
|
|
44
62
|
/** Creates a duration from a finite numeric value in the provided unit. */
|
|
45
63
|
export declare function duration(value: number, unit: TimeUnit): Duration;
|
|
64
|
+
/** Creates a duration from strict multi-unit parts. */
|
|
65
|
+
export declare function duration(parts: DurationParts): Duration;
|
|
46
66
|
/** Creates a duration from a finite millisecond value. */
|
|
47
67
|
export declare function milliseconds(value: number): Duration;
|
|
48
68
|
/** Creates a duration from a finite second value. */
|
|
@@ -71,6 +91,10 @@ export declare function subtract(a: Duration, b: Duration): Duration;
|
|
|
71
91
|
export declare function multiply(a: Duration, b: number): Duration;
|
|
72
92
|
/** Divides a duration by a finite, non-zero scalar. */
|
|
73
93
|
export declare function divide(a: Duration, b: number): Duration;
|
|
94
|
+
/** Returns a new date shifted forward by an exact duration timestamp delta. */
|
|
95
|
+
export declare function addTo(date: Date, duration: Duration): Date;
|
|
96
|
+
/** Returns a new date shifted backward by an exact duration timestamp delta. */
|
|
97
|
+
export declare function subtractFrom(date: Date, duration: Duration): Date;
|
|
74
98
|
/** The explicit non-finite duration sentinel supported by this package. */
|
|
75
99
|
export declare const infinite: Duration;
|
|
76
100
|
/** The zero-length duration constant. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"duration.d.ts","sourceRoot":"","sources":["../../src/lib/duration.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"duration.d.ts","sourceRoot":"","sources":["../../src/lib/duration.ts"],"names":[],"mappings":"AAEA,QAAA,MAAM,gBAAgB;;;;;;;;;CASZ,CAAC;AAEX,wDAAwD;AACxD,MAAM,MAAM,QAAQ,GAAG,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,OAAO,gBAAgB,CAAC,CAAC;AAEhF;;;;GAIG;AACH,eAAO,MAAM,QAAQ,EAAE;IACrB,QAAQ,EAAE,GAAG,IAAI,MAAM,OAAO,gBAAgB,GAAG,QAAQ;CACvC,CAAC;AAErB,QAAA,MAAM,wBAAwB;;;;;;;;;CASpB,CAAC;AAEX,KAAK,eAAe,GAAG,MAAM,OAAO,wBAAwB,CAAC;AAE7D,KAAK,iBAAiB,CAAC,CAAC,IAAI;KACzB,GAAG,IAAI,MAAM,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;CACnE,CAAC,MAAM,CAAC,CAAC,CAAC;AAMX,kFAAkF;AAClF,MAAM,MAAM,aAAa,GAAG,iBAAiB,CAAC;IAC5C,QAAQ,EAAE,GAAG,IAAI,eAAe,CAAC,CAAC,EAAE,MAAM;CAC3C,CAAC,CAAC;AAEH,QAAA,MAAM,eAAe,eAAyB,CAAC;AAM/C,+EAA+E;AAC/E,MAAM,MAAM,QAAQ,GAAG;IACrB,QAAQ,CAAC,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAE5B,EAAE,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,CAAC;IAC3B,cAAc,IAAI,MAAM,CAAC;IACzB,SAAS,IAAI,MAAM,CAAC;IACpB,SAAS,IAAI,MAAM,CAAC;IACpB,OAAO,IAAI,MAAM,CAAC;IAClB,MAAM,IAAI,MAAM,CAAC;IACjB,OAAO,IAAI,MAAM,CAAC;IAClB,QAAQ,IAAI,MAAM,CAAC;IACnB,OAAO,IAAI,MAAM,CAAC;IAElB,MAAM,CAAC,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC;IACjC,QAAQ,CAAC,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC;IACnC,eAAe,CAAC,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC;IAC1C,WAAW,CAAC,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC;IACtC,kBAAkB,CAAC,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC;IAC7C,OAAO,CAAC,KAAK,EAAE,QAAQ,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;CACtC,CAAC;AA4KF,2EAA2E;AAC3E,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,GAAG,QAAQ,CAAC;AAElE,uDAAuD;AACvD,wBAAgB,QAAQ,CAAC,KAAK,EAAE,aAAa,GAAG,QAAQ,CAAC;AAazD,0DAA0D;AAC1D,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,QAAQ,CAEpD;AAED,qDAAqD;AACrD,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,QAAQ,CAE/C;AAED,qDAAqD;AACrD,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,QAAQ,CAE/C;AAED,mDAAmD;AACnD,wBAAgB,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,QAAQ,CAE7C;AAED,kDAAkD;AAClD,wBAAgB,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,QAAQ,CAE5C;AAED,mDAAmD;AACnD,wBAAgB,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,QAAQ,CAE7C;AAED,+EAA+E;AAC/E,wBAAgB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,QAAQ,CAE9C;AAED,kFAAkF;AAClF,wBAAgB,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,QAAQ,CAE7C;AAED,gFAAgF;AAChF,wBAAgB,OAAO,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,GAAG,QAAQ,CAKxD;AAED,iFAAiF;AACjF,wBAAgB,KAAK,CAAC,KAAK,EAAE,IAAI,GAAG,QAAQ,CAE3C;AAUD,yEAAyE;AACzE,wBAAgB,GAAG,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,QAAQ,GAAG,QAAQ,CAMtD;AAED,kFAAkF;AAClF,wBAAgB,QAAQ,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,QAAQ,GAAG,QAAQ,CAc3D;AAED,gDAAgD;AAChD,wBAAgB,QAAQ,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,MAAM,GAAG,QAAQ,CAczD;AAED,uDAAuD;AACvD,wBAAgB,MAAM,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,MAAM,GAAG,QAAQ,CAevD;AAED,+EAA+E;AAC/E,wBAAgB,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAK1D;AAED,gFAAgF;AAChF,wBAAgB,YAAY,CAAC,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAKjE;AAED,2EAA2E;AAC3E,eAAO,MAAM,QAAQ,EAAE,QAA4D,CAAC;AAEpF,yCAAyC;AACzC,eAAO,MAAM,OAAO,EAAE,QAA0B,CAAC;AAEjD,2EAA2E;AAC3E,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,QAAQ,CAE5D;AAED,sEAAsE;AACtE,wBAAgB,OAAO,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,QAAQ,GAAG,OAAO,CAEzD"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pvorona/duration",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -18,6 +18,11 @@
|
|
|
18
18
|
"dist",
|
|
19
19
|
"!**/*.tsbuildinfo"
|
|
20
20
|
],
|
|
21
|
+
"scripts": {
|
|
22
|
+
"check-consumer-types": "node ./scripts/check-consumer-types.mjs",
|
|
23
|
+
"check-package-surface": "node ./scripts/check-package-surface.mjs",
|
|
24
|
+
"prepublishOnly": "npm run check-consumer-types && npm run check-package-surface"
|
|
25
|
+
},
|
|
21
26
|
"publishConfig": {
|
|
22
27
|
"access": "public"
|
|
23
28
|
},
|