@mt-gloss/utils 0.1.149 → 0.1.150

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/index.d.ts CHANGED
@@ -4,6 +4,8 @@ export { formatValue, getValueFontSize, pickMetricTier } from './lib/formatValue
4
4
  export type { FormatValueOptions, FormattedValue, MetricTier, PickMetricTierResult } from './lib/formatValue';
5
5
  export { formatCurrency } from './lib/formatCurrency';
6
6
  export type { FormatCurrencyOptions } from './lib/formatCurrency';
7
+ export { daysBetween } from './lib/daysBetween';
8
+ export type { DaysBetweenOptions, DaysBetweenRounding } from './lib/daysBetween';
7
9
  export { formatTrend } from './lib/formatTrend';
8
10
  export type { TrendDirection, FormattedTrend } from './lib/formatTrend';
9
11
  export { formatDateRange, formatMarketDates, isMarketActive, isSameDay, isInRange, generateMarketId } from './lib/dateHelpers';
package/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { D as N, y as v, P as A, n as O, o as V, R as x, T as G, d as Y, t as w, f as z, b as k, k as C, l as H, c as B, h as Z, x as K, g as X, q as j, j as q, m as W, u as J, i as Q, v as tt, p as et, a as nt, r as rt, s as at, e as st, w as ot } from "./formatting-dHqp6ksD.js";
1
+ import { D as A, y as O, P as V, n as x, o as Y, R as w, T as G, d as z, t as k, f as B, b as C, k as H, l as Z, c as K, h as X, x as j, g as q, q as W, j as J, m as Q, u as tt, i as et, v as nt, p as rt, a as at, r as ot, s as st, e as it, w as ut } from "./formatting-dHqp6ksD.js";
2
2
  const g = "NEXT_PUBLIC_V1_1_STATUS_MODE";
3
3
  function d() {
4
4
  return typeof globalThis < "u" && globalThis.__GLOSS_FLAGS__?.v1_1_status_mode === !0 ? !0 : typeof process < "u" && process.env ? process.env[g] === "true" : !1;
@@ -10,29 +10,29 @@ const $ = {
10
10
  function D() {
11
11
  return typeof globalThis < "u" && globalThis.__GLOSS_FLAGS__?.v1_1_edge_hover_resize === !0 ? !0 : typeof process < "u" && process.env ? process.env[m] === "true" : !1;
12
12
  }
13
- const S = {
13
+ const p = {
14
14
  env: m,
15
15
  check: D
16
16
  };
17
- function _(t, { prefix: e = "", suffix: n = "", abbreviated: s = !0, kThreshold: r = 1e3 } = {}) {
17
+ function _(t, { prefix: e = "", suffix: n = "", abbreviated: o = !0, kThreshold: a = 1e3 } = {}) {
18
18
  if (t == null) {
19
- const l = e ? `${e} —${n}` : `—${n}`;
20
- return { display: l.trim(), full: l.trim(), length: l.trim().length };
19
+ const c = e ? `${e} —${n}` : `—${n}`;
20
+ return { display: c.trim(), full: c.trim(), length: c.trim().length };
21
21
  }
22
- const a = typeof t == "number" ? t : parseFloat(String(t).replace(/,/g, ""));
23
- if (isNaN(a)) {
22
+ const r = typeof t == "number" ? t : parseFloat(String(t).replace(/,/g, ""));
23
+ if (isNaN(r)) {
24
24
  const u = `${e}${t}${n}`;
25
25
  return { display: u, full: u, length: u.length };
26
26
  }
27
- let o;
28
- s !== !1 && Math.abs(a) >= 1e6 ? o = (a / 1e6).toFixed(1).replace(/\.0$/, "") + "M" : s !== !1 && Math.abs(a) >= r ? o = (a / 1e3).toFixed(1).replace(/\.0$/, "") + "K" : o = a.toLocaleString("en-US");
29
- const i = `${e}${o}${n}`, c = `${e}${a.toLocaleString("en-US")}${n}`;
30
- return { display: i, full: c, length: i.length };
27
+ let s;
28
+ o !== !1 && Math.abs(r) >= 1e6 ? s = (r / 1e6).toFixed(1).replace(/\.0$/, "") + "M" : o !== !1 && Math.abs(r) >= a ? s = (r / 1e3).toFixed(1).replace(/\.0$/, "") + "K" : s = r.toLocaleString("en-US");
29
+ const i = `${e}${s}${n}`, f = `${e}${r.toLocaleString("en-US")}${n}`;
30
+ return { display: i, full: f, length: i.length };
31
31
  }
32
- function p(t, e) {
32
+ function E(t, e) {
33
33
  return (e ?? 1) >= 2 ? t <= 4 || t <= 6 ? 30 : t <= 8 ? 24 : 20 : t <= 5 ? 28 : t <= 8 ? 20 : 17;
34
34
  }
35
- const f = {
35
+ const l = {
36
36
  1: 5,
37
37
  // "$2.7K", "12K", "$5", "100%"
38
38
  2: 8,
@@ -41,30 +41,36 @@ const f = {
41
41
  // "$1,234,567"
42
42
  };
43
43
  function h(t) {
44
- return t <= 1 ? f[1] : t >= 3 ? f[3] : f[t] ?? f[1];
44
+ return t <= 1 ? l[1] : t >= 3 ? l[3] : l[t] ?? l[1];
45
45
  }
46
- function E(t, e = {}, n = 1) {
47
- const s = h(n), r = e.prefix ?? "", a = e.suffix ?? "", o = typeof t == "number" ? t : parseFloat(String(t ?? "").replace(/,/g, ""));
48
- if (t != null && !Number.isNaN(o)) {
49
- const c = `${r}${o.toLocaleString("en-US", { minimumFractionDigits: Number.isInteger(o) ? 0 : 2, maximumFractionDigits: 2 })}${a}`;
50
- if (c.length <= s) return { formatted: c, tier: "wide", length: c.length };
51
- const u = `${r}${Math.round(o).toLocaleString("en-US")}${a}`;
52
- if (u.length <= s) return { formatted: u, tier: "medium", length: u.length };
46
+ function M(t, e = {}, n = 1) {
47
+ const o = h(n), a = e.prefix ?? "", r = e.suffix ?? "", s = typeof t == "number" ? t : parseFloat(String(t ?? "").replace(/,/g, ""));
48
+ if (t != null && !Number.isNaN(s)) {
49
+ const f = `${a}${s.toLocaleString("en-US", { minimumFractionDigits: Number.isInteger(s) ? 0 : 2, maximumFractionDigits: 2 })}${r}`;
50
+ if (f.length <= o) return { formatted: f, tier: "wide", length: f.length };
51
+ const u = `${a}${Math.round(s).toLocaleString("en-US")}${r}`;
52
+ if (u.length <= o) return { formatted: u, tier: "medium", length: u.length };
53
53
  }
54
54
  const i = _(t, { ...e, abbreviated: !0 });
55
- return i.display.length <= s ? { formatted: i.display, tier: "narrow", length: i.display.length } : { formatted: i.display, tier: "very-narrow", length: i.display.length };
55
+ return i.display.length <= o ? { formatted: i.display, tier: "narrow", length: i.display.length } : { formatted: i.display, tier: "very-narrow", length: i.display.length };
56
56
  }
57
- function y(t, { notation: e = "standard", fractionDigits: n, currency: s = "USD" } = {}) {
58
- const r = { style: "currency", currency: s };
57
+ function y(t, { notation: e = "standard", fractionDigits: n, currency: o = "USD" } = {}) {
58
+ const a = { style: "currency", currency: o };
59
59
  if (e === "compact")
60
- r.notation = "compact", r.compactDisplay = "short", n !== void 0 && (r.minimumFractionDigits = n, r.maximumFractionDigits = n);
60
+ a.notation = "compact", a.compactDisplay = "short", n !== void 0 && (a.minimumFractionDigits = n, a.maximumFractionDigits = n);
61
61
  else {
62
- const a = n ?? 2;
63
- r.minimumFractionDigits = a, r.maximumFractionDigits = a;
62
+ const r = n ?? 2;
63
+ a.minimumFractionDigits = r, a.maximumFractionDigits = r;
64
64
  }
65
- return new Intl.NumberFormat("en-US", r).format(t);
65
+ return new Intl.NumberFormat("en-US", a).format(t);
66
66
  }
67
- function T(t) {
67
+ const S = 1e3 * 60 * 60 * 24;
68
+ function T(t, e, n = {}) {
69
+ const { rounding: o = "round", inclusive: a = !1, min: r, absolute: s = !0 } = n, i = e.getTime() - t.getTime(), u = (s ? Math.abs(i) : i) / S;
70
+ let c = o === "ceil" ? Math.ceil(u) : o === "floor" ? Math.floor(u) : o === "round" ? Math.round(u) : u;
71
+ return a && (c += 1), r !== void 0 && (c = Math.max(c, r)), c;
72
+ }
73
+ function R(t) {
68
74
  if (t == null || t === 0)
69
75
  return { text: "0%", direction: "flat" };
70
76
  const e = t > 0 ? "up" : t < 0 ? "down" : "flat", n = Math.abs(t);
@@ -72,72 +78,73 @@ function T(t) {
72
78
  }
73
79
  function F(t, e) {
74
80
  if (!t || !e) return "";
75
- const n = t.toLocaleDateString("en-US", { month: "short" }), s = e.toLocaleDateString("en-US", { month: "short" }), r = t.getDate(), a = e.getDate(), o = t.getFullYear(), i = e.getFullYear();
76
- return t.getTime() === e.getTime() || n === s && r === a && o === i ? `${n} ${r}, ${o}` : n === s && o === i ? `${n} ${r}–${a}` : o === i ? `${n} ${r} – ${s} ${a}` : `${n} ${r}, ${o} – ${s} ${a}, ${i}`;
81
+ const n = t.toLocaleDateString("en-US", { month: "short" }), o = e.toLocaleDateString("en-US", { month: "short" }), a = t.getDate(), r = e.getDate(), s = t.getFullYear(), i = e.getFullYear();
82
+ return t.getTime() === e.getTime() || n === o && a === r && s === i ? `${n} ${a}, ${s}` : n === o && s === i ? `${n} ${a}–${r}` : s === i ? `${n} ${a} – ${o} ${r}` : `${n} ${a}, ${s} – ${o} ${r}, ${i}`;
77
83
  }
78
- function M(t, e) {
79
- const n = t.toLocaleDateString("en-US", { month: "short" }), s = e.toLocaleDateString("en-US", { month: "short" }), r = t.getDate(), a = e.getDate();
80
- return n === s ? `${n} ${r}–${a}` : `${n} ${r} – ${s} ${a}`;
84
+ function P(t, e) {
85
+ const n = t.toLocaleDateString("en-US", { month: "short" }), o = e.toLocaleDateString("en-US", { month: "short" }), a = t.getDate(), r = e.getDate();
86
+ return n === o ? `${n} ${a}–${r}` : `${n} ${a} – ${o} ${r}`;
81
87
  }
82
- function R(t, e = /* @__PURE__ */ new Date()) {
88
+ function b(t, e = /* @__PURE__ */ new Date()) {
83
89
  return !t?.startDate || !t?.endDate ? !1 : e >= t.startDate && e <= t.endDate;
84
90
  }
85
- function P(t, e) {
91
+ function L(t, e) {
86
92
  return !t || !e ? !1 : t.getFullYear() === e.getFullYear() && t.getMonth() === e.getMonth() && t.getDate() === e.getDate();
87
93
  }
88
- function b(t, e, n) {
94
+ function I(t, e, n) {
89
95
  if (!t || !e || !n) return !1;
90
- const s = t.getTime(), r = e.getTime(), a = n.getTime();
91
- return s >= Math.min(r, a) && s <= Math.max(r, a);
96
+ const o = t.getTime(), a = e.getTime(), r = n.getTime();
97
+ return o >= Math.min(a, r) && o <= Math.max(a, r);
92
98
  }
93
- function L() {
99
+ function U() {
94
100
  return `custom-${Date.now()}-${Math.random().toString(36).substring(2, 11)}`;
95
101
  }
96
102
  export {
97
- N as DEFAULT_MARKET_PRESETS,
98
- v as DEFAULT_PINNED,
99
- A as PERIOD_OPTIONS,
100
- O as PRESET_ID_MAP,
101
- V as PRESET_ID_REVERSE_MAP,
102
- x as ROLLING_OPTIONS,
103
+ A as DEFAULT_MARKET_PRESETS,
104
+ O as DEFAULT_PINNED,
105
+ V as PERIOD_OPTIONS,
106
+ x as PRESET_ID_MAP,
107
+ Y as PRESET_ID_REVERSE_MAP,
108
+ w as ROLLING_OPTIONS,
103
109
  G as TODAY_PRESET,
104
110
  m as V1_1_EDGE_HOVER_RESIZE_ENV,
105
111
  g as V1_1_STATUS_MODE_ENV,
106
- Y as detectPreset,
107
- w as findPreset,
112
+ T as daysBetween,
113
+ z as detectPreset,
114
+ k as findPreset,
108
115
  y as formatCurrency,
109
116
  F as formatDateRange,
110
- z as formatDateRangeSmart,
111
- k as formatDateRangeWithPreset,
112
- C as formatDuration,
113
- M as formatMarketDates,
114
- H as formatPreset,
115
- B as formatShortYear,
116
- Z as formatSingleDate,
117
- T as formatTrend,
117
+ B as formatDateRangeSmart,
118
+ C as formatDateRangeWithPreset,
119
+ H as formatDuration,
120
+ P as formatMarketDates,
121
+ Z as formatPreset,
122
+ K as formatShortYear,
123
+ X as formatSingleDate,
124
+ R as formatTrend,
118
125
  _ as formatValue,
119
- L as generateMarketId,
120
- K as getAllPresets,
121
- X as getDateRangeDisplayInfo,
122
- j as getDateRangeForPreset,
123
- q as getDurationDays,
124
- W as getPresetDateRange,
125
- J as getPresetLabel,
126
- p as getValueFontSize,
126
+ U as generateMarketId,
127
+ j as getAllPresets,
128
+ q as getDateRangeDisplayInfo,
129
+ W as getDateRangeForPreset,
130
+ J as getDurationDays,
131
+ Q as getPresetDateRange,
132
+ tt as getPresetLabel,
133
+ E as getValueFontSize,
127
134
  D as isEdgeHoverResizeEnabled,
128
- b as isInRange,
129
- R as isMarketActive,
130
- P as isSameDay,
135
+ I as isInRange,
136
+ b as isMarketActive,
137
+ L as isSameDay,
131
138
  d as isStatusModeEnabled,
132
- Q as isValidDateRangeFormat,
133
- tt as normalizePresetId,
134
- et as parseDateRange,
135
- E as pickMetricTier,
136
- nt as resolveEvent,
137
- rt as resolvePreset,
138
- at as smartDateFormat,
139
- st as stripLeadingZeros,
140
- ot as toUppercasePresetId,
141
- S as v1_1_edge_hover_resize,
139
+ et as isValidDateRangeFormat,
140
+ nt as normalizePresetId,
141
+ rt as parseDateRange,
142
+ M as pickMetricTier,
143
+ at as resolveEvent,
144
+ ot as resolvePreset,
145
+ st as smartDateFormat,
146
+ it as stripLeadingZeros,
147
+ ut as toUppercasePresetId,
148
+ p as v1_1_edge_hover_resize,
142
149
  $ as v1_1_status_mode
143
150
  };
@@ -0,0 +1,36 @@
1
+ export type DaysBetweenRounding = 'ceil' | 'floor' | 'round' | 'none';
2
+ export interface DaysBetweenOptions {
3
+ /** Rounding applied to the raw day fraction. `'none'` returns the fraction. Default `'round'`. */
4
+ rounding?: DaysBetweenRounding;
5
+ /** Add `+1` AFTER rounding to count both endpoints (e.g. `floor(x) + 1`). Default `false`. */
6
+ inclusive?: boolean;
7
+ /** Clamp the final result up to this floor (e.g. `1` to reproduce `… || 1`). Default none. */
8
+ min?: number;
9
+ /** `Math.abs` the millisecond diff so argument order is irrelevant. Default `true`. */
10
+ absolute?: boolean;
11
+ }
12
+ /**
13
+ * Day span between two dates, with explicit rounding/inclusivity/clamping.
14
+ *
15
+ * One configurable helper for the dashboard's several day-span computations,
16
+ * each of which carries a distinct mode. Order of operations is load-bearing:
17
+ * round → `+1` (inclusive) → `Math.max(min)`.
18
+ *
19
+ * Rules:
20
+ * - `rounding: 'none'` returns the raw fractional day count (callers that threshold on a non-integer).
21
+ * - `inclusive: true` adds `1` after rounding (counts both endpoints).
22
+ * - `min` clamps the final value up (e.g. `min: 1` turns a `0`-day span into `1`).
23
+ * - `absolute: true` (default) uses `|end − start|`; pass `false` for a signed difference.
24
+ *
25
+ * @example
26
+ * ```ts
27
+ * import { daysBetween } from '@mt-gloss/utils';
28
+ *
29
+ * const a = new Date('2026-01-01'), b = new Date('2026-01-04');
30
+ * daysBetween(a, b); // 3
31
+ * daysBetween(a, b, { rounding: 'floor', inclusive: true }); // 4 (both endpoints)
32
+ * daysBetween(a, a, { rounding: 'ceil', min: 1 }); // 1
33
+ * ```
34
+ */
35
+ export declare function daysBetween(start: Date, end: Date, opts?: DaysBetweenOptions): number;
36
+ //# sourceMappingURL=daysBetween.d.ts.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mt-gloss/utils",
3
- "version": "0.1.149",
3
+ "version": "0.1.150",
4
4
  "type": "module",
5
5
  "publishConfig": {
6
6
  "access": "public"