Skip to content

Commit b018c16

Browse files
committed
Temp
1 parent b26a7ad commit b018c16

12 files changed

+1786
-1
lines changed

.gitignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,2 @@
1-
dist/
21
node_modules/
32
custom-elements.json

dist/bundle.js

Lines changed: 823 additions & 0 deletions
Large diffs are not rendered by default.

dist/duration-format-ponyfill.d.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import type { Duration } from './duration.js';
2+
interface DurationFormatResolvedOptions {
3+
locale: string;
4+
style: 'long' | 'short' | 'narrow' | 'digital';
5+
years: 'long' | 'short' | 'narrow';
6+
yearsDisplay: 'always' | 'auto';
7+
months: 'long' | 'short' | 'narrow';
8+
monthsDisplay: 'always' | 'auto';
9+
weeks: 'long' | 'short' | 'narrow';
10+
weeksDisplay: 'always' | 'auto';
11+
days: 'long' | 'short' | 'narrow';
12+
daysDisplay: 'always' | 'auto';
13+
hours: 'long' | 'short' | 'narrow' | 'numeric' | '2-digit';
14+
hoursDisplay: 'always' | 'auto';
15+
minutes: 'long' | 'short' | 'narrow' | 'numeric' | '2-digit';
16+
minutesDisplay: 'always' | 'auto';
17+
seconds: 'long' | 'short' | 'narrow' | 'numeric' | '2-digit';
18+
secondsDisplay: 'always' | 'auto';
19+
milliseconds: 'long' | 'short' | 'narrow' | 'numeric';
20+
millisecondsDisplay: 'always' | 'auto';
21+
}
22+
export type DurationFormatOptions = Partial<Omit<DurationFormatResolvedOptions, 'locale'>>;
23+
interface DurationPart {
24+
type: 'integer' | 'literal' | 'element';
25+
value: string;
26+
}
27+
export default class DurationFormat {
28+
#private;
29+
constructor(locale: string, options?: DurationFormatOptions);
30+
resolvedOptions(): DurationFormatResolvedOptions;
31+
formatToParts(duration: Duration): DurationPart[];
32+
format(duration: Duration): string;
33+
}
34+
export {};

dist/duration-format-ponyfill.js

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
2+
if (kind === "m") throw new TypeError("Private method is not writable");
3+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
4+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
5+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
6+
};
7+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
8+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
9+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
10+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
11+
};
12+
var _DurationFormat_options;
13+
class ListFormatPonyFill {
14+
formatToParts(members) {
15+
const parts = [];
16+
for (const value of members) {
17+
parts.push({ type: 'element', value });
18+
parts.push({ type: 'literal', value: ', ' });
19+
}
20+
return parts.slice(0, -1);
21+
}
22+
}
23+
const ListFormat = (typeof Intl !== 'undefined' && Intl.ListFormat) || ListFormatPonyFill;
24+
const partsTable = [
25+
['years', 'year'],
26+
['months', 'month'],
27+
['weeks', 'week'],
28+
['days', 'day'],
29+
['hours', 'hour'],
30+
['minutes', 'minute'],
31+
['seconds', 'second'],
32+
['milliseconds', 'millisecond'],
33+
];
34+
const twoDigitFormatOptions = { minimumIntegerDigits: 2 };
35+
export default class DurationFormat {
36+
constructor(locale, options = {}) {
37+
_DurationFormat_options.set(this, void 0);
38+
let style = String(options.style || 'short');
39+
if (style !== 'long' && style !== 'short' && style !== 'narrow' && style !== 'digital')
40+
style = 'short';
41+
let prevStyle = style === 'digital' ? 'numeric' : style;
42+
const hours = options.hours || prevStyle;
43+
prevStyle = hours === '2-digit' ? 'numeric' : hours;
44+
const minutes = options.minutes || prevStyle;
45+
prevStyle = minutes === '2-digit' ? 'numeric' : minutes;
46+
const seconds = options.seconds || prevStyle;
47+
prevStyle = seconds === '2-digit' ? 'numeric' : seconds;
48+
const milliseconds = options.milliseconds || prevStyle;
49+
__classPrivateFieldSet(this, _DurationFormat_options, {
50+
locale,
51+
style,
52+
years: options.years || style === 'digital' ? 'short' : style,
53+
yearsDisplay: options.yearsDisplay === 'always' ? 'always' : 'auto',
54+
months: options.months || style === 'digital' ? 'short' : style,
55+
monthsDisplay: options.monthsDisplay === 'always' ? 'always' : 'auto',
56+
weeks: options.weeks || style === 'digital' ? 'short' : style,
57+
weeksDisplay: options.weeksDisplay === 'always' ? 'always' : 'auto',
58+
days: options.days || style === 'digital' ? 'short' : style,
59+
daysDisplay: options.daysDisplay === 'always' ? 'always' : 'auto',
60+
hours,
61+
hoursDisplay: options.hoursDisplay === 'always' ? 'always' : style === 'digital' ? 'always' : 'auto',
62+
minutes,
63+
minutesDisplay: options.minutesDisplay === 'always' ? 'always' : style === 'digital' ? 'always' : 'auto',
64+
seconds,
65+
secondsDisplay: options.secondsDisplay === 'always' ? 'always' : style === 'digital' ? 'always' : 'auto',
66+
milliseconds,
67+
millisecondsDisplay: options.millisecondsDisplay === 'always' ? 'always' : 'auto',
68+
}, "f");
69+
}
70+
resolvedOptions() {
71+
return __classPrivateFieldGet(this, _DurationFormat_options, "f");
72+
}
73+
formatToParts(duration) {
74+
const list = [];
75+
const options = __classPrivateFieldGet(this, _DurationFormat_options, "f");
76+
const style = options.style;
77+
const locale = options.locale;
78+
for (const [unit, nfUnit] of partsTable) {
79+
const value = duration[unit];
80+
if (options[`${unit}Display`] === 'auto' && !value)
81+
continue;
82+
const unitStyle = options[unit];
83+
const nfOpts = unitStyle === '2-digit'
84+
? twoDigitFormatOptions
85+
: unitStyle === 'numeric'
86+
? {}
87+
: { style: 'unit', unit: nfUnit, unitDisplay: unitStyle };
88+
let formattedValue = new Intl.NumberFormat(locale, nfOpts).format(value);
89+
if (unit === 'months' && (unitStyle === 'narrow' || (style === 'narrow' && formattedValue.endsWith('m')))) {
90+
formattedValue = formattedValue.replace(/(\d+)m$/, '$1mo');
91+
}
92+
list.push(formattedValue);
93+
}
94+
return new ListFormat(locale, {
95+
type: 'unit',
96+
style: style === 'digital' ? 'short' : style,
97+
}).formatToParts(list);
98+
}
99+
format(duration) {
100+
return this.formatToParts(duration)
101+
.map(p => p.value)
102+
.join('');
103+
}
104+
}
105+
_DurationFormat_options = new WeakMap();

dist/duration.d.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import type { DurationFormatOptions } from './duration-format-ponyfill.js';
2+
export declare const unitNames: readonly ["year", "month", "week", "day", "hour", "minute", "second", "millisecond"];
3+
export type Unit = typeof unitNames[number];
4+
export declare const isDuration: (str: string) => boolean;
5+
type Sign = -1 | 0 | 1;
6+
export declare class Duration {
7+
readonly years: number;
8+
readonly months: number;
9+
readonly weeks: number;
10+
readonly days: number;
11+
readonly hours: number;
12+
readonly minutes: number;
13+
readonly seconds: number;
14+
readonly milliseconds: number;
15+
readonly sign: Sign;
16+
readonly blank: boolean;
17+
constructor(years?: number, months?: number, weeks?: number, days?: number, hours?: number, minutes?: number, seconds?: number, milliseconds?: number);
18+
abs(): Duration;
19+
static from(durationLike: unknown): Duration;
20+
static compare(one: unknown, two: unknown): -1 | 0 | 1;
21+
toLocaleString(locale: string, opts: DurationFormatOptions): string;
22+
}
23+
export declare function applyDuration(date: Date | number, duration: Duration): Date;
24+
export declare function elapsedTime(date: Date, precision?: Unit, now?: number): Duration;
25+
interface RoundingOpts {
26+
relativeTo: Date | number;
27+
}
28+
export declare function roundToSingleUnit(duration: Duration, { relativeTo }?: Partial<RoundingOpts>): Duration;
29+
export declare function getRelativeTimeUnit(duration: Duration, opts?: Partial<RoundingOpts>): [number, Intl.RelativeTimeFormatUnit];
30+
export {};

dist/duration.js

Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
import DurationFormat from './duration-format-ponyfill.js';
2+
const durationRe = /^[-+]?P(?:(\d+)Y)?(?:(\d+)M)?(?:(\d+)W)?(?:(\d+)D)?(?:T(?:(\d+)H)?(?:(\d+)M)?(?:(\d+)S)?)?$/;
3+
export const unitNames = ['year', 'month', 'week', 'day', 'hour', 'minute', 'second', 'millisecond'];
4+
export const isDuration = (str) => durationRe.test(str);
5+
export class Duration {
6+
constructor(years = 0, months = 0, weeks = 0, days = 0, hours = 0, minutes = 0, seconds = 0, milliseconds = 0) {
7+
this.years = years;
8+
this.months = months;
9+
this.weeks = weeks;
10+
this.days = days;
11+
this.hours = hours;
12+
this.minutes = minutes;
13+
this.seconds = seconds;
14+
this.milliseconds = milliseconds;
15+
this.years || (this.years = 0);
16+
this.sign || (this.sign = Math.sign(this.years));
17+
this.months || (this.months = 0);
18+
this.sign || (this.sign = Math.sign(this.months));
19+
this.weeks || (this.weeks = 0);
20+
this.sign || (this.sign = Math.sign(this.weeks));
21+
this.days || (this.days = 0);
22+
this.sign || (this.sign = Math.sign(this.days));
23+
this.hours || (this.hours = 0);
24+
this.sign || (this.sign = Math.sign(this.hours));
25+
this.minutes || (this.minutes = 0);
26+
this.sign || (this.sign = Math.sign(this.minutes));
27+
this.seconds || (this.seconds = 0);
28+
this.sign || (this.sign = Math.sign(this.seconds));
29+
this.milliseconds || (this.milliseconds = 0);
30+
this.sign || (this.sign = Math.sign(this.milliseconds));
31+
this.blank = this.sign === 0;
32+
}
33+
abs() {
34+
return new Duration(Math.abs(this.years), Math.abs(this.months), Math.abs(this.weeks), Math.abs(this.days), Math.abs(this.hours), Math.abs(this.minutes), Math.abs(this.seconds), Math.abs(this.milliseconds));
35+
}
36+
static from(durationLike) {
37+
var _a;
38+
if (typeof durationLike === 'string') {
39+
const str = String(durationLike).trim();
40+
const factor = str.startsWith('-') ? -1 : 1;
41+
const parsed = (_a = str
42+
.match(durationRe)) === null || _a === void 0 ? void 0 : _a.slice(1).map(x => (Number(x) || 0) * factor);
43+
if (!parsed)
44+
return new Duration();
45+
return new Duration(...parsed);
46+
}
47+
else if (typeof durationLike === 'object') {
48+
const { years, months, weeks, days, hours, minutes, seconds, milliseconds } = durationLike;
49+
return new Duration(years, months, weeks, days, hours, minutes, seconds, milliseconds);
50+
}
51+
throw new RangeError('invalid duration');
52+
}
53+
static compare(one, two) {
54+
const now = Date.now();
55+
const oneApplied = Math.abs(applyDuration(now, Duration.from(one)).getTime() - now);
56+
const twoApplied = Math.abs(applyDuration(now, Duration.from(two)).getTime() - now);
57+
return oneApplied > twoApplied ? -1 : oneApplied < twoApplied ? 1 : 0;
58+
}
59+
toLocaleString(locale, opts) {
60+
return new DurationFormat(locale, opts).format(this);
61+
}
62+
}
63+
export function applyDuration(date, duration) {
64+
const r = new Date(date);
65+
if (duration.sign < 0) {
66+
r.setUTCSeconds(r.getUTCSeconds() + duration.seconds);
67+
r.setUTCMinutes(r.getUTCMinutes() + duration.minutes);
68+
r.setUTCHours(r.getUTCHours() + duration.hours);
69+
r.setUTCDate(r.getUTCDate() + duration.weeks * 7 + duration.days);
70+
r.setUTCMonth(r.getUTCMonth() + duration.months);
71+
r.setUTCFullYear(r.getUTCFullYear() + duration.years);
72+
}
73+
else {
74+
r.setUTCFullYear(r.getUTCFullYear() + duration.years);
75+
r.setUTCMonth(r.getUTCMonth() + duration.months);
76+
r.setUTCDate(r.getUTCDate() + duration.weeks * 7 + duration.days);
77+
r.setUTCHours(r.getUTCHours() + duration.hours);
78+
r.setUTCMinutes(r.getUTCMinutes() + duration.minutes);
79+
r.setUTCSeconds(r.getUTCSeconds() + duration.seconds);
80+
}
81+
return r;
82+
}
83+
export function elapsedTime(date, precision = 'second', now = Date.now()) {
84+
const delta = date.getTime() - now;
85+
if (delta === 0)
86+
return new Duration();
87+
const sign = Math.sign(delta);
88+
const ms = Math.abs(delta);
89+
const sec = Math.floor(ms / 1000);
90+
const min = Math.floor(sec / 60);
91+
const hr = Math.floor(min / 60);
92+
const day = Math.floor(hr / 24);
93+
const month = Math.floor(day / 30);
94+
const year = Math.floor(month / 12);
95+
const i = unitNames.indexOf(precision) || unitNames.length;
96+
return new Duration(i >= 0 ? year * sign : 0, i >= 1 ? (month - year * 12) * sign : 0, 0, i >= 3 ? (day - month * 30) * sign : 0, i >= 4 ? (hr - day * 24) * sign : 0, i >= 5 ? (min - hr * 60) * sign : 0, i >= 6 ? (sec - min * 60) * sign : 0, i >= 7 ? (ms - sec * 1000) * sign : 0);
97+
}
98+
export function roundToSingleUnit(duration, { relativeTo = Date.now() } = {}) {
99+
relativeTo = new Date(relativeTo);
100+
if (duration.blank)
101+
return duration;
102+
const sign = duration.sign;
103+
let years = Math.abs(duration.years);
104+
let months = Math.abs(duration.months);
105+
let weeks = Math.abs(duration.weeks);
106+
let days = Math.abs(duration.days);
107+
let hours = Math.abs(duration.hours);
108+
let minutes = Math.abs(duration.minutes);
109+
let seconds = Math.abs(duration.seconds);
110+
let milliseconds = Math.abs(duration.milliseconds);
111+
if (milliseconds >= 900)
112+
seconds += Math.round(milliseconds / 1000);
113+
if (seconds || minutes || hours || days || weeks || months || years) {
114+
milliseconds = 0;
115+
}
116+
if (seconds >= 55)
117+
minutes += Math.round(seconds / 60);
118+
if (minutes || hours || days || weeks || months || years)
119+
seconds = 0;
120+
if (minutes >= 55)
121+
hours += Math.round(minutes / 60);
122+
if (hours || days || weeks || months || years)
123+
minutes = 0;
124+
if (days && hours >= 12)
125+
days += Math.round(hours / 24);
126+
if (!days && hours >= 21)
127+
days += Math.round(hours / 24);
128+
if (days || weeks || months || years)
129+
hours = 0;
130+
const currentYear = relativeTo.getFullYear();
131+
const currentMonth = relativeTo.getMonth();
132+
const currentDate = relativeTo.getDate();
133+
if (days >= 27 || years + months + days) {
134+
const newMonthDate = new Date(relativeTo);
135+
newMonthDate.setDate(1);
136+
newMonthDate.setMonth(currentMonth + months * sign + 1);
137+
newMonthDate.setDate(0);
138+
const monthDateCorrection = Math.max(0, currentDate - newMonthDate.getDate());
139+
const newDate = new Date(relativeTo);
140+
newDate.setFullYear(currentYear + years * sign);
141+
newDate.setDate(currentDate - monthDateCorrection);
142+
newDate.setMonth(currentMonth + months * sign);
143+
newDate.setDate(currentDate - monthDateCorrection + days * sign);
144+
const yearDiff = newDate.getFullYear() - relativeTo.getFullYear();
145+
const monthDiff = newDate.getMonth() - relativeTo.getMonth();
146+
const daysDiff = Math.abs(Math.round((Number(newDate) - Number(relativeTo)) / 86400000)) + monthDateCorrection;
147+
const monthsDiff = Math.abs(yearDiff * 12 + monthDiff);
148+
if (daysDiff < 27) {
149+
if (days >= 6) {
150+
weeks += Math.round(days / 7);
151+
days = 0;
152+
}
153+
else {
154+
days = daysDiff;
155+
}
156+
months = years = 0;
157+
}
158+
else if (monthsDiff <= 11) {
159+
months = monthsDiff;
160+
years = 0;
161+
}
162+
else {
163+
months = 0;
164+
years = yearDiff * sign;
165+
}
166+
if (months || years)
167+
days = 0;
168+
}
169+
if (years)
170+
months = 0;
171+
if (weeks >= 4)
172+
months += Math.round(weeks / 4);
173+
if (months || years)
174+
weeks = 0;
175+
if (days && weeks && !months && !years) {
176+
weeks += Math.round(days / 7);
177+
days = 0;
178+
}
179+
return new Duration(years * sign, months * sign, weeks * sign, days * sign, hours * sign, minutes * sign, seconds * sign, milliseconds * sign);
180+
}
181+
export function getRelativeTimeUnit(duration, opts) {
182+
const rounded = roundToSingleUnit(duration, opts);
183+
if (rounded.blank)
184+
return [0, 'second'];
185+
for (const unit of unitNames) {
186+
if (unit === 'millisecond')
187+
continue;
188+
const val = rounded[`${unit}s`];
189+
if (val)
190+
return [val, unit];
191+
}
192+
return [0, 'second'];
193+
}

dist/index.d.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import RelativeTimeElement from './relative-time-element-define.js';
2+
export { RelativeTimeElement };
3+
export default RelativeTimeElement;
4+
export * from './relative-time-element-define.js';

dist/index.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import RelativeTimeElement from './relative-time-element-define.js';
2+
export { RelativeTimeElement };
3+
export default RelativeTimeElement;
4+
export * from './relative-time-element-define.js';
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { RelativeTimeElement } from './relative-time-element.js';
2+
type JSXBase = JSX.IntrinsicElements extends {
3+
span: unknown;
4+
} ? JSX.IntrinsicElements : Record<string, Record<string, unknown>>;
5+
declare global {
6+
interface Window {
7+
RelativeTimeElement: typeof RelativeTimeElement;
8+
}
9+
interface HTMLElementTagNameMap {
10+
'relative-time': RelativeTimeElement;
11+
}
12+
namespace JSX {
13+
interface IntrinsicElements {
14+
['relative-time']: JSXBase['span'] & Partial<Omit<RelativeTimeElement, keyof HTMLElement>>;
15+
}
16+
}
17+
}
18+
export default RelativeTimeElement;
19+
export * from './relative-time-element.js';

0 commit comments

Comments
 (0)