@jagreehal/workflow 1.12.0 → 1.14.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.
Files changed (49) hide show
  1. package/README.md +1197 -20
  2. package/dist/duration.cjs +2 -0
  3. package/dist/duration.cjs.map +1 -0
  4. package/dist/duration.d.cts +246 -0
  5. package/dist/duration.d.ts +246 -0
  6. package/dist/duration.js +2 -0
  7. package/dist/duration.js.map +1 -0
  8. package/dist/index.cjs +5 -5
  9. package/dist/index.cjs.map +1 -1
  10. package/dist/index.d.cts +3 -0
  11. package/dist/index.d.ts +3 -0
  12. package/dist/index.js +5 -5
  13. package/dist/index.js.map +1 -1
  14. package/dist/match.cjs +2 -0
  15. package/dist/match.cjs.map +1 -0
  16. package/dist/match.d.cts +216 -0
  17. package/dist/match.d.ts +216 -0
  18. package/dist/match.js +2 -0
  19. package/dist/match.js.map +1 -0
  20. package/dist/schedule.cjs +2 -0
  21. package/dist/schedule.cjs.map +1 -0
  22. package/dist/schedule.d.cts +387 -0
  23. package/dist/schedule.d.ts +387 -0
  24. package/dist/schedule.js +2 -0
  25. package/dist/schedule.js.map +1 -0
  26. package/dist/visualize.cjs +73 -67
  27. package/dist/visualize.cjs.map +1 -1
  28. package/dist/visualize.d.cts +13 -1
  29. package/dist/visualize.d.ts +13 -1
  30. package/dist/visualize.js +73 -67
  31. package/dist/visualize.js.map +1 -1
  32. package/docs/api.md +30 -0
  33. package/docs/coming-from-neverthrow.md +103 -10
  34. package/docs/effect-features-to-port.md +210 -0
  35. package/docs/match-examples.test.ts +558 -0
  36. package/docs/match.md +417 -0
  37. package/docs/pino-logging-example.md +293 -0
  38. package/docs/policies-examples.test.ts +750 -0
  39. package/docs/policies.md +508 -0
  40. package/docs/resource-management-examples.test.ts +729 -0
  41. package/docs/resource-management.md +509 -0
  42. package/docs/schedule-examples.test.ts +736 -0
  43. package/docs/schedule.md +467 -0
  44. package/docs/tagged-error-examples.test.ts +494 -0
  45. package/docs/tagged-error.md +730 -0
  46. package/docs/visualization-examples.test.ts +663 -0
  47. package/docs/visualization.md +430 -0
  48. package/docs/visualize-examples.md +1 -1
  49. package/package.json +22 -3
@@ -0,0 +1,2 @@
1
+ "use strict";var e=Object.defineProperty;var Z=Object.getOwnPropertyDescriptor;var A=Object.getOwnPropertyNames;var B=Object.prototype.hasOwnProperty;var G=(i,n)=>{for(var t in n)e(i,t,{get:n[t],enumerable:!0})},J=(i,n,t,u)=>{if(n&&typeof n=="object"||typeof n=="function")for(let r of A(n))!B.call(i,r)&&r!==t&&e(i,r,{get:()=>n[r],enumerable:!(u=Z(n,r))||u.enumerable});return i};var K=i=>J(e({},"__esModule",{value:!0}),i);var Q={};G(Q,{Duration:()=>P,add:()=>$,clamp:()=>k,days:()=>D,divide:()=>q,equals:()=>O,format:()=>N,greaterThan:()=>j,greaterThanOrEqual:()=>E,hours:()=>m,infinity:()=>h,isDuration:()=>L,isFinite:()=>H,isInfinite:()=>C,isZero:()=>z,lessThan:()=>w,lessThanOrEqual:()=>F,max:()=>f,millis:()=>a,min:()=>c,minutes:()=>s,multiply:()=>I,parse:()=>S,seconds:()=>l,subtract:()=>T,toDays:()=>M,toHours:()=>_,toMillis:()=>d,toMinutes:()=>y,toSeconds:()=>g,zero:()=>b});module.exports=K(Q);function a(i){return{_tag:"Duration",millis:i}}function l(i){return{_tag:"Duration",millis:i*1e3}}function s(i){return{_tag:"Duration",millis:i*60*1e3}}function m(i){return{_tag:"Duration",millis:i*60*60*1e3}}function D(i){return{_tag:"Duration",millis:i*24*60*60*1e3}}var b={_tag:"Duration",millis:0},h={_tag:"Duration",millis:1/0};function d(i){return i.millis}function g(i){return i.millis/1e3}function y(i){return i.millis/(60*1e3)}function _(i){return i.millis/(3600*1e3)}function M(i){return i.millis/(1440*60*1e3)}function $(i,n){return{_tag:"Duration",millis:i.millis+n.millis}}function T(i,n){return{_tag:"Duration",millis:Math.max(0,i.millis-n.millis)}}function I(i,n){return{_tag:"Duration",millis:i.millis*n}}function q(i,n){return{_tag:"Duration",millis:i.millis/n}}function w(i,n){return i.millis<n.millis}function F(i,n){return i.millis<=n.millis}function j(i,n){return i.millis>n.millis}function E(i,n){return i.millis>=n.millis}function O(i,n){return i.millis===n.millis}function c(i,n){return i.millis<=n.millis?i:n}function f(i,n){return i.millis>=n.millis?i:n}function k(i,n,t){return c(f(i,n),t)}function z(i){return i.millis===0}function C(i){return i.millis===1/0}function H(i){return Number.isFinite(i.millis)&&i.millis>0}function L(i){return typeof i=="object"&&i!==null&&"_tag"in i&&i._tag==="Duration"&&"millis"in i&&typeof i.millis=="number"}function N(i){let n=i.millis;if(n===1/0)return"\u221E";if(n===0)return"0ms";let t=Math.floor(n/(1440*60*1e3)),u=Math.floor(n%(1440*60*1e3)/(3600*1e3)),r=Math.floor(n%(3600*1e3)/(60*1e3)),p=Math.floor(n%(60*1e3)/1e3),x=n%1e3,o=[];return t>0&&o.push(`${t}d`),u>0&&o.push(`${u}h`),r>0&&o.push(`${r}m`),p>0&&o.push(`${p}s`),x>0&&o.length===0&&o.push(`${x}ms`),o.join(" ")||"0ms"}function S(i){let n=i.trim().match(/^(\d+(?:\.\d+)?)\s*(ms|s|m|h|d)$/i);if(!n)return;let t=parseFloat(n[1]);switch(n[2].toLowerCase()){case"ms":return a(t);case"s":return l(t);case"m":return s(t);case"h":return m(t);case"d":return D(t);default:return}}var P={millis:a,seconds:l,minutes:s,hours:m,days:D,zero:b,infinity:h,toMillis:d,toSeconds:g,toMinutes:y,toHours:_,toDays:M,add:$,subtract:T,multiply:I,divide:q,lessThan:w,lessThanOrEqual:F,greaterThan:j,greaterThanOrEqual:E,equals:O,min:c,max:f,clamp:k,isZero:z,isInfinite:C,isFinite:H,isDuration:L,format:N,parse:S};0&&(module.exports={Duration,add,clamp,days,divide,equals,format,greaterThan,greaterThanOrEqual,hours,infinity,isDuration,isFinite,isInfinite,isZero,lessThan,lessThanOrEqual,max,millis,min,minutes,multiply,parse,seconds,subtract,toDays,toHours,toMillis,toMinutes,toSeconds,zero});
2
+ //# sourceMappingURL=duration.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/duration.ts"],"sourcesContent":["/**\n * @jagreehal/workflow/duration\n *\n * Type-safe duration handling inspired by Effect's Duration module.\n * Prevents unit confusion (milliseconds vs seconds) with explicit constructors.\n */\n\n// =============================================================================\n// Duration Type\n// =============================================================================\n\n/**\n * A type-safe representation of a time duration.\n * Use the constructor functions (millis, seconds, etc.) to create durations.\n */\nexport interface Duration {\n readonly _tag: \"Duration\";\n readonly millis: number;\n}\n\n// =============================================================================\n// Constructors\n// =============================================================================\n\n/**\n * Create a Duration from milliseconds.\n *\n * @example\n * ```typescript\n * const d = Duration.millis(500)\n * ```\n */\nexport function millis(ms: number): Duration {\n return { _tag: \"Duration\", millis: ms };\n}\n\n/**\n * Create a Duration from seconds.\n *\n * @example\n * ```typescript\n * const d = Duration.seconds(5) // 5000ms\n * ```\n */\nexport function seconds(s: number): Duration {\n return { _tag: \"Duration\", millis: s * 1000 };\n}\n\n/**\n * Create a Duration from minutes.\n *\n * @example\n * ```typescript\n * const d = Duration.minutes(2) // 120000ms\n * ```\n */\nexport function minutes(m: number): Duration {\n return { _tag: \"Duration\", millis: m * 60 * 1000 };\n}\n\n/**\n * Create a Duration from hours.\n *\n * @example\n * ```typescript\n * const d = Duration.hours(1) // 3600000ms\n * ```\n */\nexport function hours(h: number): Duration {\n return { _tag: \"Duration\", millis: h * 60 * 60 * 1000 };\n}\n\n/**\n * Create a Duration from days.\n *\n * @example\n * ```typescript\n * const d = Duration.days(1) // 86400000ms\n * ```\n */\nexport function days(d: number): Duration {\n return { _tag: \"Duration\", millis: d * 24 * 60 * 60 * 1000 };\n}\n\n/**\n * Zero duration.\n */\nexport const zero: Duration = { _tag: \"Duration\", millis: 0 };\n\n/**\n * Infinite duration (represented as Infinity milliseconds).\n */\nexport const infinity: Duration = { _tag: \"Duration\", millis: Infinity };\n\n// =============================================================================\n// Conversions\n// =============================================================================\n\n/**\n * Convert a Duration to milliseconds.\n */\nexport function toMillis(duration: Duration): number {\n return duration.millis;\n}\n\n/**\n * Convert a Duration to seconds.\n */\nexport function toSeconds(duration: Duration): number {\n return duration.millis / 1000;\n}\n\n/**\n * Convert a Duration to minutes.\n */\nexport function toMinutes(duration: Duration): number {\n return duration.millis / (60 * 1000);\n}\n\n/**\n * Convert a Duration to hours.\n */\nexport function toHours(duration: Duration): number {\n return duration.millis / (60 * 60 * 1000);\n}\n\n/**\n * Convert a Duration to days.\n */\nexport function toDays(duration: Duration): number {\n return duration.millis / (24 * 60 * 60 * 1000);\n}\n\n// =============================================================================\n// Operations\n// =============================================================================\n\n/**\n * Add two durations.\n *\n * @example\n * ```typescript\n * const total = Duration.add(Duration.seconds(5), Duration.millis(500))\n * // 5500ms\n * ```\n */\nexport function add(a: Duration, b: Duration): Duration {\n return { _tag: \"Duration\", millis: a.millis + b.millis };\n}\n\n/**\n * Subtract duration b from duration a.\n * Result is clamped to zero (no negative durations).\n *\n * @example\n * ```typescript\n * const remaining = Duration.subtract(Duration.seconds(5), Duration.seconds(2))\n * // 3000ms\n * ```\n */\nexport function subtract(a: Duration, b: Duration): Duration {\n return { _tag: \"Duration\", millis: Math.max(0, a.millis - b.millis) };\n}\n\n/**\n * Multiply a duration by a factor.\n *\n * @example\n * ```typescript\n * const doubled = Duration.multiply(Duration.seconds(5), 2)\n * // 10000ms\n * ```\n */\nexport function multiply(duration: Duration, factor: number): Duration {\n return { _tag: \"Duration\", millis: duration.millis * factor };\n}\n\n/**\n * Divide a duration by a divisor.\n *\n * @example\n * ```typescript\n * const half = Duration.divide(Duration.seconds(10), 2)\n * // 5000ms\n * ```\n */\nexport function divide(duration: Duration, divisor: number): Duration {\n return { _tag: \"Duration\", millis: duration.millis / divisor };\n}\n\n// =============================================================================\n// Comparisons\n// =============================================================================\n\n/**\n * Check if duration a is less than duration b.\n */\nexport function lessThan(a: Duration, b: Duration): boolean {\n return a.millis < b.millis;\n}\n\n/**\n * Check if duration a is less than or equal to duration b.\n */\nexport function lessThanOrEqual(a: Duration, b: Duration): boolean {\n return a.millis <= b.millis;\n}\n\n/**\n * Check if duration a is greater than duration b.\n */\nexport function greaterThan(a: Duration, b: Duration): boolean {\n return a.millis > b.millis;\n}\n\n/**\n * Check if duration a is greater than or equal to duration b.\n */\nexport function greaterThanOrEqual(a: Duration, b: Duration): boolean {\n return a.millis >= b.millis;\n}\n\n/**\n * Check if two durations are equal.\n */\nexport function equals(a: Duration, b: Duration): boolean {\n return a.millis === b.millis;\n}\n\n/**\n * Get the minimum of two durations.\n */\nexport function min(a: Duration, b: Duration): Duration {\n return a.millis <= b.millis ? a : b;\n}\n\n/**\n * Get the maximum of two durations.\n */\nexport function max(a: Duration, b: Duration): Duration {\n return a.millis >= b.millis ? a : b;\n}\n\n/**\n * Clamp a duration between a minimum and maximum.\n */\nexport function clamp(duration: Duration, minimum: Duration, maximum: Duration): Duration {\n return min(max(duration, minimum), maximum);\n}\n\n// =============================================================================\n// Predicates\n// =============================================================================\n\n/**\n * Check if a duration is zero.\n */\nexport function isZero(duration: Duration): boolean {\n return duration.millis === 0;\n}\n\n/**\n * Check if a duration is infinite.\n */\nexport function isInfinite(duration: Duration): boolean {\n return duration.millis === Infinity;\n}\n\n/**\n * Check if a duration is finite and positive.\n */\nexport function isFinite(duration: Duration): boolean {\n return Number.isFinite(duration.millis) && duration.millis > 0;\n}\n\n/**\n * Type guard to check if a value is a Duration.\n */\nexport function isDuration(value: unknown): value is Duration {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"_tag\" in value &&\n value._tag === \"Duration\" &&\n \"millis\" in value &&\n typeof value.millis === \"number\"\n );\n}\n\n// =============================================================================\n// Formatting\n// =============================================================================\n\n/**\n * Format a duration as a human-readable string.\n *\n * @example\n * ```typescript\n * Duration.format(Duration.seconds(90)) // \"1m 30s\"\n * Duration.format(Duration.millis(500)) // \"500ms\"\n * ```\n */\nexport function format(duration: Duration): string {\n const ms = duration.millis;\n\n if (ms === Infinity) return \"∞\";\n if (ms === 0) return \"0ms\";\n\n const days = Math.floor(ms / (24 * 60 * 60 * 1000));\n const hours = Math.floor((ms % (24 * 60 * 60 * 1000)) / (60 * 60 * 1000));\n const minutes = Math.floor((ms % (60 * 60 * 1000)) / (60 * 1000));\n const seconds = Math.floor((ms % (60 * 1000)) / 1000);\n const millis = ms % 1000;\n\n const parts: string[] = [];\n if (days > 0) parts.push(`${days}d`);\n if (hours > 0) parts.push(`${hours}h`);\n if (minutes > 0) parts.push(`${minutes}m`);\n if (seconds > 0) parts.push(`${seconds}s`);\n if (millis > 0 && parts.length === 0) parts.push(`${millis}ms`);\n\n return parts.join(\" \") || \"0ms\";\n}\n\n// =============================================================================\n// Parsing\n// =============================================================================\n\n/**\n * Parse a duration from a string like \"100ms\", \"5s\", \"2m\", \"1h\", \"1d\".\n * Returns undefined if parsing fails.\n *\n * @example\n * ```typescript\n * Duration.parse(\"5s\") // Duration.seconds(5)\n * Duration.parse(\"100ms\") // Duration.millis(100)\n * Duration.parse(\"2m\") // Duration.minutes(2)\n * ```\n */\nexport function parse(input: string): Duration | undefined {\n const match = input.trim().match(/^(\\d+(?:\\.\\d+)?)\\s*(ms|s|m|h|d)$/i);\n if (!match) return undefined;\n\n const value = parseFloat(match[1]);\n const unit = match[2].toLowerCase();\n\n switch (unit) {\n case \"ms\":\n return millis(value);\n case \"s\":\n return seconds(value);\n case \"m\":\n return minutes(value);\n case \"h\":\n return hours(value);\n case \"d\":\n return days(value);\n default:\n return undefined;\n }\n}\n\n// =============================================================================\n// Namespace Export\n// =============================================================================\n\n/**\n * Duration namespace with all functions for convenient access.\n *\n * @example\n * ```typescript\n * import { Duration } from \"@jagreehal/workflow\";\n *\n * const timeout = Duration.seconds(30);\n * const delay = Duration.millis(100);\n * const total = Duration.add(timeout, delay);\n *\n * console.log(Duration.format(total)); // \"30s 100ms\"\n * ```\n */\nexport const Duration = {\n // Constructors\n millis,\n seconds,\n minutes,\n hours,\n days,\n zero,\n infinity,\n\n // Conversions\n toMillis,\n toSeconds,\n toMinutes,\n toHours,\n toDays,\n\n // Operations\n add,\n subtract,\n multiply,\n divide,\n\n // Comparisons\n lessThan,\n lessThanOrEqual,\n greaterThan,\n greaterThanOrEqual,\n equals,\n min,\n max,\n clamp,\n\n // Predicates\n isZero,\n isInfinite,\n isFinite,\n isDuration,\n\n // Formatting\n format,\n parse,\n} as const;\n\nexport type { Duration as DurationType };\n"],"mappings":"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","names":["duration_exports","__export","Duration","add","clamp","days","divide","equals","format","greaterThan","greaterThanOrEqual","hours","infinity","isDuration","isFinite","isInfinite","isZero","lessThan","lessThanOrEqual","max","millis","min","minutes","multiply","parse","seconds","subtract","toDays","toHours","toMillis","toMinutes","toSeconds","zero","__toCommonJS","ms","s","m","h","d","duration","a","b","factor","divisor","minimum","maximum","value","parts","input","match"]}
@@ -0,0 +1,246 @@
1
+ /**
2
+ * Create a Duration from milliseconds.
3
+ *
4
+ * @example
5
+ * ```typescript
6
+ * const d = Duration.millis(500)
7
+ * ```
8
+ */
9
+ declare function millis(ms: number): Duration;
10
+ /**
11
+ * Create a Duration from seconds.
12
+ *
13
+ * @example
14
+ * ```typescript
15
+ * const d = Duration.seconds(5) // 5000ms
16
+ * ```
17
+ */
18
+ declare function seconds(s: number): Duration;
19
+ /**
20
+ * Create a Duration from minutes.
21
+ *
22
+ * @example
23
+ * ```typescript
24
+ * const d = Duration.minutes(2) // 120000ms
25
+ * ```
26
+ */
27
+ declare function minutes(m: number): Duration;
28
+ /**
29
+ * Create a Duration from hours.
30
+ *
31
+ * @example
32
+ * ```typescript
33
+ * const d = Duration.hours(1) // 3600000ms
34
+ * ```
35
+ */
36
+ declare function hours(h: number): Duration;
37
+ /**
38
+ * Create a Duration from days.
39
+ *
40
+ * @example
41
+ * ```typescript
42
+ * const d = Duration.days(1) // 86400000ms
43
+ * ```
44
+ */
45
+ declare function days(d: number): Duration;
46
+ /**
47
+ * Zero duration.
48
+ */
49
+ declare const zero: Duration;
50
+ /**
51
+ * Infinite duration (represented as Infinity milliseconds).
52
+ */
53
+ declare const infinity: Duration;
54
+ /**
55
+ * Convert a Duration to milliseconds.
56
+ */
57
+ declare function toMillis(duration: Duration): number;
58
+ /**
59
+ * Convert a Duration to seconds.
60
+ */
61
+ declare function toSeconds(duration: Duration): number;
62
+ /**
63
+ * Convert a Duration to minutes.
64
+ */
65
+ declare function toMinutes(duration: Duration): number;
66
+ /**
67
+ * Convert a Duration to hours.
68
+ */
69
+ declare function toHours(duration: Duration): number;
70
+ /**
71
+ * Convert a Duration to days.
72
+ */
73
+ declare function toDays(duration: Duration): number;
74
+ /**
75
+ * Add two durations.
76
+ *
77
+ * @example
78
+ * ```typescript
79
+ * const total = Duration.add(Duration.seconds(5), Duration.millis(500))
80
+ * // 5500ms
81
+ * ```
82
+ */
83
+ declare function add(a: Duration, b: Duration): Duration;
84
+ /**
85
+ * Subtract duration b from duration a.
86
+ * Result is clamped to zero (no negative durations).
87
+ *
88
+ * @example
89
+ * ```typescript
90
+ * const remaining = Duration.subtract(Duration.seconds(5), Duration.seconds(2))
91
+ * // 3000ms
92
+ * ```
93
+ */
94
+ declare function subtract(a: Duration, b: Duration): Duration;
95
+ /**
96
+ * Multiply a duration by a factor.
97
+ *
98
+ * @example
99
+ * ```typescript
100
+ * const doubled = Duration.multiply(Duration.seconds(5), 2)
101
+ * // 10000ms
102
+ * ```
103
+ */
104
+ declare function multiply(duration: Duration, factor: number): Duration;
105
+ /**
106
+ * Divide a duration by a divisor.
107
+ *
108
+ * @example
109
+ * ```typescript
110
+ * const half = Duration.divide(Duration.seconds(10), 2)
111
+ * // 5000ms
112
+ * ```
113
+ */
114
+ declare function divide(duration: Duration, divisor: number): Duration;
115
+ /**
116
+ * Check if duration a is less than duration b.
117
+ */
118
+ declare function lessThan(a: Duration, b: Duration): boolean;
119
+ /**
120
+ * Check if duration a is less than or equal to duration b.
121
+ */
122
+ declare function lessThanOrEqual(a: Duration, b: Duration): boolean;
123
+ /**
124
+ * Check if duration a is greater than duration b.
125
+ */
126
+ declare function greaterThan(a: Duration, b: Duration): boolean;
127
+ /**
128
+ * Check if duration a is greater than or equal to duration b.
129
+ */
130
+ declare function greaterThanOrEqual(a: Duration, b: Duration): boolean;
131
+ /**
132
+ * Check if two durations are equal.
133
+ */
134
+ declare function equals(a: Duration, b: Duration): boolean;
135
+ /**
136
+ * Get the minimum of two durations.
137
+ */
138
+ declare function min(a: Duration, b: Duration): Duration;
139
+ /**
140
+ * Get the maximum of two durations.
141
+ */
142
+ declare function max(a: Duration, b: Duration): Duration;
143
+ /**
144
+ * Clamp a duration between a minimum and maximum.
145
+ */
146
+ declare function clamp(duration: Duration, minimum: Duration, maximum: Duration): Duration;
147
+ /**
148
+ * Check if a duration is zero.
149
+ */
150
+ declare function isZero(duration: Duration): boolean;
151
+ /**
152
+ * Check if a duration is infinite.
153
+ */
154
+ declare function isInfinite(duration: Duration): boolean;
155
+ /**
156
+ * Check if a duration is finite and positive.
157
+ */
158
+ declare function isFinite(duration: Duration): boolean;
159
+ /**
160
+ * Type guard to check if a value is a Duration.
161
+ */
162
+ declare function isDuration(value: unknown): value is Duration;
163
+ /**
164
+ * Format a duration as a human-readable string.
165
+ *
166
+ * @example
167
+ * ```typescript
168
+ * Duration.format(Duration.seconds(90)) // "1m 30s"
169
+ * Duration.format(Duration.millis(500)) // "500ms"
170
+ * ```
171
+ */
172
+ declare function format(duration: Duration): string;
173
+ /**
174
+ * Parse a duration from a string like "100ms", "5s", "2m", "1h", "1d".
175
+ * Returns undefined if parsing fails.
176
+ *
177
+ * @example
178
+ * ```typescript
179
+ * Duration.parse("5s") // Duration.seconds(5)
180
+ * Duration.parse("100ms") // Duration.millis(100)
181
+ * Duration.parse("2m") // Duration.minutes(2)
182
+ * ```
183
+ */
184
+ declare function parse(input: string): Duration | undefined;
185
+ /**
186
+ * @jagreehal/workflow/duration
187
+ *
188
+ * Type-safe duration handling inspired by Effect's Duration module.
189
+ * Prevents unit confusion (milliseconds vs seconds) with explicit constructors.
190
+ */
191
+ /**
192
+ * A type-safe representation of a time duration.
193
+ * Use the constructor functions (millis, seconds, etc.) to create durations.
194
+ */
195
+ interface Duration {
196
+ readonly _tag: "Duration";
197
+ readonly millis: number;
198
+ }
199
+ /**
200
+ * Duration namespace with all functions for convenient access.
201
+ *
202
+ * @example
203
+ * ```typescript
204
+ * import { Duration } from "@jagreehal/workflow";
205
+ *
206
+ * const timeout = Duration.seconds(30);
207
+ * const delay = Duration.millis(100);
208
+ * const total = Duration.add(timeout, delay);
209
+ *
210
+ * console.log(Duration.format(total)); // "30s 100ms"
211
+ * ```
212
+ */
213
+ declare const Duration: {
214
+ readonly millis: typeof millis;
215
+ readonly seconds: typeof seconds;
216
+ readonly minutes: typeof minutes;
217
+ readonly hours: typeof hours;
218
+ readonly days: typeof days;
219
+ readonly zero: Duration;
220
+ readonly infinity: Duration;
221
+ readonly toMillis: typeof toMillis;
222
+ readonly toSeconds: typeof toSeconds;
223
+ readonly toMinutes: typeof toMinutes;
224
+ readonly toHours: typeof toHours;
225
+ readonly toDays: typeof toDays;
226
+ readonly add: typeof add;
227
+ readonly subtract: typeof subtract;
228
+ readonly multiply: typeof multiply;
229
+ readonly divide: typeof divide;
230
+ readonly lessThan: typeof lessThan;
231
+ readonly lessThanOrEqual: typeof lessThanOrEqual;
232
+ readonly greaterThan: typeof greaterThan;
233
+ readonly greaterThanOrEqual: typeof greaterThanOrEqual;
234
+ readonly equals: typeof equals;
235
+ readonly min: typeof min;
236
+ readonly max: typeof max;
237
+ readonly clamp: typeof clamp;
238
+ readonly isZero: typeof isZero;
239
+ readonly isInfinite: typeof isInfinite;
240
+ readonly isFinite: typeof isFinite;
241
+ readonly isDuration: typeof isDuration;
242
+ readonly format: typeof format;
243
+ readonly parse: typeof parse;
244
+ };
245
+
246
+ export { Duration, Duration as DurationType, add, clamp, days, divide, equals, format, greaterThan, greaterThanOrEqual, hours, infinity, isDuration, isFinite, isInfinite, isZero, lessThan, lessThanOrEqual, max, millis, min, minutes, multiply, parse, seconds, subtract, toDays, toHours, toMillis, toMinutes, toSeconds, zero };
@@ -0,0 +1,246 @@
1
+ /**
2
+ * Create a Duration from milliseconds.
3
+ *
4
+ * @example
5
+ * ```typescript
6
+ * const d = Duration.millis(500)
7
+ * ```
8
+ */
9
+ declare function millis(ms: number): Duration;
10
+ /**
11
+ * Create a Duration from seconds.
12
+ *
13
+ * @example
14
+ * ```typescript
15
+ * const d = Duration.seconds(5) // 5000ms
16
+ * ```
17
+ */
18
+ declare function seconds(s: number): Duration;
19
+ /**
20
+ * Create a Duration from minutes.
21
+ *
22
+ * @example
23
+ * ```typescript
24
+ * const d = Duration.minutes(2) // 120000ms
25
+ * ```
26
+ */
27
+ declare function minutes(m: number): Duration;
28
+ /**
29
+ * Create a Duration from hours.
30
+ *
31
+ * @example
32
+ * ```typescript
33
+ * const d = Duration.hours(1) // 3600000ms
34
+ * ```
35
+ */
36
+ declare function hours(h: number): Duration;
37
+ /**
38
+ * Create a Duration from days.
39
+ *
40
+ * @example
41
+ * ```typescript
42
+ * const d = Duration.days(1) // 86400000ms
43
+ * ```
44
+ */
45
+ declare function days(d: number): Duration;
46
+ /**
47
+ * Zero duration.
48
+ */
49
+ declare const zero: Duration;
50
+ /**
51
+ * Infinite duration (represented as Infinity milliseconds).
52
+ */
53
+ declare const infinity: Duration;
54
+ /**
55
+ * Convert a Duration to milliseconds.
56
+ */
57
+ declare function toMillis(duration: Duration): number;
58
+ /**
59
+ * Convert a Duration to seconds.
60
+ */
61
+ declare function toSeconds(duration: Duration): number;
62
+ /**
63
+ * Convert a Duration to minutes.
64
+ */
65
+ declare function toMinutes(duration: Duration): number;
66
+ /**
67
+ * Convert a Duration to hours.
68
+ */
69
+ declare function toHours(duration: Duration): number;
70
+ /**
71
+ * Convert a Duration to days.
72
+ */
73
+ declare function toDays(duration: Duration): number;
74
+ /**
75
+ * Add two durations.
76
+ *
77
+ * @example
78
+ * ```typescript
79
+ * const total = Duration.add(Duration.seconds(5), Duration.millis(500))
80
+ * // 5500ms
81
+ * ```
82
+ */
83
+ declare function add(a: Duration, b: Duration): Duration;
84
+ /**
85
+ * Subtract duration b from duration a.
86
+ * Result is clamped to zero (no negative durations).
87
+ *
88
+ * @example
89
+ * ```typescript
90
+ * const remaining = Duration.subtract(Duration.seconds(5), Duration.seconds(2))
91
+ * // 3000ms
92
+ * ```
93
+ */
94
+ declare function subtract(a: Duration, b: Duration): Duration;
95
+ /**
96
+ * Multiply a duration by a factor.
97
+ *
98
+ * @example
99
+ * ```typescript
100
+ * const doubled = Duration.multiply(Duration.seconds(5), 2)
101
+ * // 10000ms
102
+ * ```
103
+ */
104
+ declare function multiply(duration: Duration, factor: number): Duration;
105
+ /**
106
+ * Divide a duration by a divisor.
107
+ *
108
+ * @example
109
+ * ```typescript
110
+ * const half = Duration.divide(Duration.seconds(10), 2)
111
+ * // 5000ms
112
+ * ```
113
+ */
114
+ declare function divide(duration: Duration, divisor: number): Duration;
115
+ /**
116
+ * Check if duration a is less than duration b.
117
+ */
118
+ declare function lessThan(a: Duration, b: Duration): boolean;
119
+ /**
120
+ * Check if duration a is less than or equal to duration b.
121
+ */
122
+ declare function lessThanOrEqual(a: Duration, b: Duration): boolean;
123
+ /**
124
+ * Check if duration a is greater than duration b.
125
+ */
126
+ declare function greaterThan(a: Duration, b: Duration): boolean;
127
+ /**
128
+ * Check if duration a is greater than or equal to duration b.
129
+ */
130
+ declare function greaterThanOrEqual(a: Duration, b: Duration): boolean;
131
+ /**
132
+ * Check if two durations are equal.
133
+ */
134
+ declare function equals(a: Duration, b: Duration): boolean;
135
+ /**
136
+ * Get the minimum of two durations.
137
+ */
138
+ declare function min(a: Duration, b: Duration): Duration;
139
+ /**
140
+ * Get the maximum of two durations.
141
+ */
142
+ declare function max(a: Duration, b: Duration): Duration;
143
+ /**
144
+ * Clamp a duration between a minimum and maximum.
145
+ */
146
+ declare function clamp(duration: Duration, minimum: Duration, maximum: Duration): Duration;
147
+ /**
148
+ * Check if a duration is zero.
149
+ */
150
+ declare function isZero(duration: Duration): boolean;
151
+ /**
152
+ * Check if a duration is infinite.
153
+ */
154
+ declare function isInfinite(duration: Duration): boolean;
155
+ /**
156
+ * Check if a duration is finite and positive.
157
+ */
158
+ declare function isFinite(duration: Duration): boolean;
159
+ /**
160
+ * Type guard to check if a value is a Duration.
161
+ */
162
+ declare function isDuration(value: unknown): value is Duration;
163
+ /**
164
+ * Format a duration as a human-readable string.
165
+ *
166
+ * @example
167
+ * ```typescript
168
+ * Duration.format(Duration.seconds(90)) // "1m 30s"
169
+ * Duration.format(Duration.millis(500)) // "500ms"
170
+ * ```
171
+ */
172
+ declare function format(duration: Duration): string;
173
+ /**
174
+ * Parse a duration from a string like "100ms", "5s", "2m", "1h", "1d".
175
+ * Returns undefined if parsing fails.
176
+ *
177
+ * @example
178
+ * ```typescript
179
+ * Duration.parse("5s") // Duration.seconds(5)
180
+ * Duration.parse("100ms") // Duration.millis(100)
181
+ * Duration.parse("2m") // Duration.minutes(2)
182
+ * ```
183
+ */
184
+ declare function parse(input: string): Duration | undefined;
185
+ /**
186
+ * @jagreehal/workflow/duration
187
+ *
188
+ * Type-safe duration handling inspired by Effect's Duration module.
189
+ * Prevents unit confusion (milliseconds vs seconds) with explicit constructors.
190
+ */
191
+ /**
192
+ * A type-safe representation of a time duration.
193
+ * Use the constructor functions (millis, seconds, etc.) to create durations.
194
+ */
195
+ interface Duration {
196
+ readonly _tag: "Duration";
197
+ readonly millis: number;
198
+ }
199
+ /**
200
+ * Duration namespace with all functions for convenient access.
201
+ *
202
+ * @example
203
+ * ```typescript
204
+ * import { Duration } from "@jagreehal/workflow";
205
+ *
206
+ * const timeout = Duration.seconds(30);
207
+ * const delay = Duration.millis(100);
208
+ * const total = Duration.add(timeout, delay);
209
+ *
210
+ * console.log(Duration.format(total)); // "30s 100ms"
211
+ * ```
212
+ */
213
+ declare const Duration: {
214
+ readonly millis: typeof millis;
215
+ readonly seconds: typeof seconds;
216
+ readonly minutes: typeof minutes;
217
+ readonly hours: typeof hours;
218
+ readonly days: typeof days;
219
+ readonly zero: Duration;
220
+ readonly infinity: Duration;
221
+ readonly toMillis: typeof toMillis;
222
+ readonly toSeconds: typeof toSeconds;
223
+ readonly toMinutes: typeof toMinutes;
224
+ readonly toHours: typeof toHours;
225
+ readonly toDays: typeof toDays;
226
+ readonly add: typeof add;
227
+ readonly subtract: typeof subtract;
228
+ readonly multiply: typeof multiply;
229
+ readonly divide: typeof divide;
230
+ readonly lessThan: typeof lessThan;
231
+ readonly lessThanOrEqual: typeof lessThanOrEqual;
232
+ readonly greaterThan: typeof greaterThan;
233
+ readonly greaterThanOrEqual: typeof greaterThanOrEqual;
234
+ readonly equals: typeof equals;
235
+ readonly min: typeof min;
236
+ readonly max: typeof max;
237
+ readonly clamp: typeof clamp;
238
+ readonly isZero: typeof isZero;
239
+ readonly isInfinite: typeof isInfinite;
240
+ readonly isFinite: typeof isFinite;
241
+ readonly isDuration: typeof isDuration;
242
+ readonly format: typeof format;
243
+ readonly parse: typeof parse;
244
+ };
245
+
246
+ export { Duration, Duration as DurationType, add, clamp, days, divide, equals, format, greaterThan, greaterThanOrEqual, hours, infinity, isDuration, isFinite, isInfinite, isZero, lessThan, lessThanOrEqual, max, millis, min, minutes, multiply, parse, seconds, subtract, toDays, toHours, toMillis, toMinutes, toSeconds, zero };
@@ -0,0 +1,2 @@
1
+ function l(i){return{_tag:"Duration",millis:i}}function s(i){return{_tag:"Duration",millis:i*1e3}}function m(i){return{_tag:"Duration",millis:i*60*1e3}}function D(i){return{_tag:"Duration",millis:i*60*60*1e3}}function c(i){return{_tag:"Duration",millis:i*24*60*60*1e3}}var x={_tag:"Duration",millis:0},b={_tag:"Duration",millis:1/0};function h(i){return i.millis}function d(i){return i.millis/1e3}function g(i){return i.millis/(60*1e3)}function y(i){return i.millis/(3600*1e3)}function _(i){return i.millis/(1440*60*1e3)}function M(i,n){return{_tag:"Duration",millis:i.millis+n.millis}}function $(i,n){return{_tag:"Duration",millis:Math.max(0,i.millis-n.millis)}}function T(i,n){return{_tag:"Duration",millis:i.millis*n}}function I(i,n){return{_tag:"Duration",millis:i.millis/n}}function q(i,n){return i.millis<n.millis}function w(i,n){return i.millis<=n.millis}function F(i,n){return i.millis>n.millis}function j(i,n){return i.millis>=n.millis}function E(i,n){return i.millis===n.millis}function f(i,n){return i.millis<=n.millis?i:n}function p(i,n){return i.millis>=n.millis?i:n}function O(i,n,t){return f(p(i,n),t)}function k(i){return i.millis===0}function z(i){return i.millis===1/0}function C(i){return Number.isFinite(i.millis)&&i.millis>0}function H(i){return typeof i=="object"&&i!==null&&"_tag"in i&&i._tag==="Duration"&&"millis"in i&&typeof i.millis=="number"}function L(i){let n=i.millis;if(n===1/0)return"\u221E";if(n===0)return"0ms";let t=Math.floor(n/(1440*60*1e3)),o=Math.floor(n%(1440*60*1e3)/(3600*1e3)),u=Math.floor(n%(3600*1e3)/(60*1e3)),e=Math.floor(n%(60*1e3)/1e3),a=n%1e3,r=[];return t>0&&r.push(`${t}d`),o>0&&r.push(`${o}h`),u>0&&r.push(`${u}m`),e>0&&r.push(`${e}s`),a>0&&r.length===0&&r.push(`${a}ms`),r.join(" ")||"0ms"}function N(i){let n=i.trim().match(/^(\d+(?:\.\d+)?)\s*(ms|s|m|h|d)$/i);if(!n)return;let t=parseFloat(n[1]);switch(n[2].toLowerCase()){case"ms":return l(t);case"s":return s(t);case"m":return m(t);case"h":return D(t);case"d":return c(t);default:return}}var S={millis:l,seconds:s,minutes:m,hours:D,days:c,zero:x,infinity:b,toMillis:h,toSeconds:d,toMinutes:g,toHours:y,toDays:_,add:M,subtract:$,multiply:T,divide:I,lessThan:q,lessThanOrEqual:w,greaterThan:F,greaterThanOrEqual:j,equals:E,min:f,max:p,clamp:O,isZero:k,isInfinite:z,isFinite:C,isDuration:H,format:L,parse:N};export{S as Duration,M as add,O as clamp,c as days,I as divide,E as equals,L as format,F as greaterThan,j as greaterThanOrEqual,D as hours,b as infinity,H as isDuration,C as isFinite,z as isInfinite,k as isZero,q as lessThan,w as lessThanOrEqual,p as max,l as millis,f as min,m as minutes,T as multiply,N as parse,s as seconds,$ as subtract,_ as toDays,y as toHours,h as toMillis,g as toMinutes,d as toSeconds,x as zero};
2
+ //# sourceMappingURL=duration.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/duration.ts"],"sourcesContent":["/**\n * @jagreehal/workflow/duration\n *\n * Type-safe duration handling inspired by Effect's Duration module.\n * Prevents unit confusion (milliseconds vs seconds) with explicit constructors.\n */\n\n// =============================================================================\n// Duration Type\n// =============================================================================\n\n/**\n * A type-safe representation of a time duration.\n * Use the constructor functions (millis, seconds, etc.) to create durations.\n */\nexport interface Duration {\n readonly _tag: \"Duration\";\n readonly millis: number;\n}\n\n// =============================================================================\n// Constructors\n// =============================================================================\n\n/**\n * Create a Duration from milliseconds.\n *\n * @example\n * ```typescript\n * const d = Duration.millis(500)\n * ```\n */\nexport function millis(ms: number): Duration {\n return { _tag: \"Duration\", millis: ms };\n}\n\n/**\n * Create a Duration from seconds.\n *\n * @example\n * ```typescript\n * const d = Duration.seconds(5) // 5000ms\n * ```\n */\nexport function seconds(s: number): Duration {\n return { _tag: \"Duration\", millis: s * 1000 };\n}\n\n/**\n * Create a Duration from minutes.\n *\n * @example\n * ```typescript\n * const d = Duration.minutes(2) // 120000ms\n * ```\n */\nexport function minutes(m: number): Duration {\n return { _tag: \"Duration\", millis: m * 60 * 1000 };\n}\n\n/**\n * Create a Duration from hours.\n *\n * @example\n * ```typescript\n * const d = Duration.hours(1) // 3600000ms\n * ```\n */\nexport function hours(h: number): Duration {\n return { _tag: \"Duration\", millis: h * 60 * 60 * 1000 };\n}\n\n/**\n * Create a Duration from days.\n *\n * @example\n * ```typescript\n * const d = Duration.days(1) // 86400000ms\n * ```\n */\nexport function days(d: number): Duration {\n return { _tag: \"Duration\", millis: d * 24 * 60 * 60 * 1000 };\n}\n\n/**\n * Zero duration.\n */\nexport const zero: Duration = { _tag: \"Duration\", millis: 0 };\n\n/**\n * Infinite duration (represented as Infinity milliseconds).\n */\nexport const infinity: Duration = { _tag: \"Duration\", millis: Infinity };\n\n// =============================================================================\n// Conversions\n// =============================================================================\n\n/**\n * Convert a Duration to milliseconds.\n */\nexport function toMillis(duration: Duration): number {\n return duration.millis;\n}\n\n/**\n * Convert a Duration to seconds.\n */\nexport function toSeconds(duration: Duration): number {\n return duration.millis / 1000;\n}\n\n/**\n * Convert a Duration to minutes.\n */\nexport function toMinutes(duration: Duration): number {\n return duration.millis / (60 * 1000);\n}\n\n/**\n * Convert a Duration to hours.\n */\nexport function toHours(duration: Duration): number {\n return duration.millis / (60 * 60 * 1000);\n}\n\n/**\n * Convert a Duration to days.\n */\nexport function toDays(duration: Duration): number {\n return duration.millis / (24 * 60 * 60 * 1000);\n}\n\n// =============================================================================\n// Operations\n// =============================================================================\n\n/**\n * Add two durations.\n *\n * @example\n * ```typescript\n * const total = Duration.add(Duration.seconds(5), Duration.millis(500))\n * // 5500ms\n * ```\n */\nexport function add(a: Duration, b: Duration): Duration {\n return { _tag: \"Duration\", millis: a.millis + b.millis };\n}\n\n/**\n * Subtract duration b from duration a.\n * Result is clamped to zero (no negative durations).\n *\n * @example\n * ```typescript\n * const remaining = Duration.subtract(Duration.seconds(5), Duration.seconds(2))\n * // 3000ms\n * ```\n */\nexport function subtract(a: Duration, b: Duration): Duration {\n return { _tag: \"Duration\", millis: Math.max(0, a.millis - b.millis) };\n}\n\n/**\n * Multiply a duration by a factor.\n *\n * @example\n * ```typescript\n * const doubled = Duration.multiply(Duration.seconds(5), 2)\n * // 10000ms\n * ```\n */\nexport function multiply(duration: Duration, factor: number): Duration {\n return { _tag: \"Duration\", millis: duration.millis * factor };\n}\n\n/**\n * Divide a duration by a divisor.\n *\n * @example\n * ```typescript\n * const half = Duration.divide(Duration.seconds(10), 2)\n * // 5000ms\n * ```\n */\nexport function divide(duration: Duration, divisor: number): Duration {\n return { _tag: \"Duration\", millis: duration.millis / divisor };\n}\n\n// =============================================================================\n// Comparisons\n// =============================================================================\n\n/**\n * Check if duration a is less than duration b.\n */\nexport function lessThan(a: Duration, b: Duration): boolean {\n return a.millis < b.millis;\n}\n\n/**\n * Check if duration a is less than or equal to duration b.\n */\nexport function lessThanOrEqual(a: Duration, b: Duration): boolean {\n return a.millis <= b.millis;\n}\n\n/**\n * Check if duration a is greater than duration b.\n */\nexport function greaterThan(a: Duration, b: Duration): boolean {\n return a.millis > b.millis;\n}\n\n/**\n * Check if duration a is greater than or equal to duration b.\n */\nexport function greaterThanOrEqual(a: Duration, b: Duration): boolean {\n return a.millis >= b.millis;\n}\n\n/**\n * Check if two durations are equal.\n */\nexport function equals(a: Duration, b: Duration): boolean {\n return a.millis === b.millis;\n}\n\n/**\n * Get the minimum of two durations.\n */\nexport function min(a: Duration, b: Duration): Duration {\n return a.millis <= b.millis ? a : b;\n}\n\n/**\n * Get the maximum of two durations.\n */\nexport function max(a: Duration, b: Duration): Duration {\n return a.millis >= b.millis ? a : b;\n}\n\n/**\n * Clamp a duration between a minimum and maximum.\n */\nexport function clamp(duration: Duration, minimum: Duration, maximum: Duration): Duration {\n return min(max(duration, minimum), maximum);\n}\n\n// =============================================================================\n// Predicates\n// =============================================================================\n\n/**\n * Check if a duration is zero.\n */\nexport function isZero(duration: Duration): boolean {\n return duration.millis === 0;\n}\n\n/**\n * Check if a duration is infinite.\n */\nexport function isInfinite(duration: Duration): boolean {\n return duration.millis === Infinity;\n}\n\n/**\n * Check if a duration is finite and positive.\n */\nexport function isFinite(duration: Duration): boolean {\n return Number.isFinite(duration.millis) && duration.millis > 0;\n}\n\n/**\n * Type guard to check if a value is a Duration.\n */\nexport function isDuration(value: unknown): value is Duration {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"_tag\" in value &&\n value._tag === \"Duration\" &&\n \"millis\" in value &&\n typeof value.millis === \"number\"\n );\n}\n\n// =============================================================================\n// Formatting\n// =============================================================================\n\n/**\n * Format a duration as a human-readable string.\n *\n * @example\n * ```typescript\n * Duration.format(Duration.seconds(90)) // \"1m 30s\"\n * Duration.format(Duration.millis(500)) // \"500ms\"\n * ```\n */\nexport function format(duration: Duration): string {\n const ms = duration.millis;\n\n if (ms === Infinity) return \"∞\";\n if (ms === 0) return \"0ms\";\n\n const days = Math.floor(ms / (24 * 60 * 60 * 1000));\n const hours = Math.floor((ms % (24 * 60 * 60 * 1000)) / (60 * 60 * 1000));\n const minutes = Math.floor((ms % (60 * 60 * 1000)) / (60 * 1000));\n const seconds = Math.floor((ms % (60 * 1000)) / 1000);\n const millis = ms % 1000;\n\n const parts: string[] = [];\n if (days > 0) parts.push(`${days}d`);\n if (hours > 0) parts.push(`${hours}h`);\n if (minutes > 0) parts.push(`${minutes}m`);\n if (seconds > 0) parts.push(`${seconds}s`);\n if (millis > 0 && parts.length === 0) parts.push(`${millis}ms`);\n\n return parts.join(\" \") || \"0ms\";\n}\n\n// =============================================================================\n// Parsing\n// =============================================================================\n\n/**\n * Parse a duration from a string like \"100ms\", \"5s\", \"2m\", \"1h\", \"1d\".\n * Returns undefined if parsing fails.\n *\n * @example\n * ```typescript\n * Duration.parse(\"5s\") // Duration.seconds(5)\n * Duration.parse(\"100ms\") // Duration.millis(100)\n * Duration.parse(\"2m\") // Duration.minutes(2)\n * ```\n */\nexport function parse(input: string): Duration | undefined {\n const match = input.trim().match(/^(\\d+(?:\\.\\d+)?)\\s*(ms|s|m|h|d)$/i);\n if (!match) return undefined;\n\n const value = parseFloat(match[1]);\n const unit = match[2].toLowerCase();\n\n switch (unit) {\n case \"ms\":\n return millis(value);\n case \"s\":\n return seconds(value);\n case \"m\":\n return minutes(value);\n case \"h\":\n return hours(value);\n case \"d\":\n return days(value);\n default:\n return undefined;\n }\n}\n\n// =============================================================================\n// Namespace Export\n// =============================================================================\n\n/**\n * Duration namespace with all functions for convenient access.\n *\n * @example\n * ```typescript\n * import { Duration } from \"@jagreehal/workflow\";\n *\n * const timeout = Duration.seconds(30);\n * const delay = Duration.millis(100);\n * const total = Duration.add(timeout, delay);\n *\n * console.log(Duration.format(total)); // \"30s 100ms\"\n * ```\n */\nexport const Duration = {\n // Constructors\n millis,\n seconds,\n minutes,\n hours,\n days,\n zero,\n infinity,\n\n // Conversions\n toMillis,\n toSeconds,\n toMinutes,\n toHours,\n toDays,\n\n // Operations\n add,\n subtract,\n multiply,\n divide,\n\n // Comparisons\n lessThan,\n lessThanOrEqual,\n greaterThan,\n greaterThanOrEqual,\n equals,\n min,\n max,\n clamp,\n\n // Predicates\n isZero,\n isInfinite,\n isFinite,\n isDuration,\n\n // Formatting\n format,\n parse,\n} as const;\n\nexport type { Duration as DurationType };\n"],"mappings":"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","names":["millis","ms","seconds","s","minutes","m","hours","h","days","d","zero","infinity","toMillis","duration","toSeconds","toMinutes","toHours","toDays","add","a","b","subtract","multiply","factor","divide","divisor","lessThan","lessThanOrEqual","greaterThan","greaterThanOrEqual","equals","min","max","clamp","minimum","maximum","isZero","isInfinite","isFinite","isDuration","value","format","parts","parse","input","match","Duration"]}