{"version":3,"file":"index.mjs","names":[],"sources":["../src/index.ts"],"sourcesContent":["import { type DateAdapter, type TimeUnit } from 'chart.js';\n\nexport interface AdapterOptions {\n  locale?: string;\n  timeZone?: string;\n}\n\nexport interface FormatContext {\n  locale?: string;\n  timeZone: string;\n}\n\nexport type FormatValue =\n  | string\n  | Intl.DateTimeFormatOptions\n  | ((timestamp: number, context: FormatContext) => string);\n\nconst FORMAT_OPTIONS: Record<\n  string,\n  Intl.DateTimeFormatOptions & { fractionalSecondDigits?: number }\n> = {\n  datetime: { dateStyle: 'medium', timeStyle: 'medium' },\n  millisecond: {\n    fractionalSecondDigits: 3,\n    second: 'numeric',\n    minute: 'numeric',\n    hour: 'numeric',\n  },\n  second: {\n    second: 'numeric',\n    minute: 'numeric',\n    hour: 'numeric',\n  },\n  minute: { hour: 'numeric', minute: 'numeric' },\n  hour: { hour: 'numeric', minute: 'numeric' },\n  day: { day: 'numeric', month: 'short' },\n  week: { day: 'numeric', month: 'short' },\n  month: { month: 'short', year: 'numeric' },\n  year: { year: 'numeric' },\n};\n\nconst FORMATS = {\n  datetime: 'datetime',\n  millisecond: 'millisecond',\n  second: 'second',\n  minute: 'minute',\n  hour: 'hour',\n  day: 'day',\n  week: 'week',\n  month: 'month',\n  quarter: 'quarter',\n  year: 'year',\n};\n\nconst units: Temporal.DateTimeUnit[] = [\n  'millisecond',\n  'second',\n  'minute',\n  'hour',\n  'day',\n  'week',\n  'month',\n  'year',\n];\n\nconst cache = new Map<string, Intl.DateTimeFormat>();\n\nfunction getTimeZone(options: AdapterOptions) {\n  return options.timeZone ?? Temporal.Now.timeZoneId();\n}\n\nconst adapter: DateAdapter<AdapterOptions> = {\n  options: {},\n\n  init(chartOptions) {\n    if (chartOptions.locale) {\n      this.options.locale = chartOptions.locale;\n    }\n  },\n\n  formats() {\n    return FORMATS;\n  },\n\n  format(timestamp, _format) {\n    const format = _format as FormatValue;\n    const timeZone = getTimeZone(this.options);\n\n    if (typeof format === 'function') {\n      return format(timestamp, { locale: this.options.locale, timeZone });\n    }\n\n    if (format === FORMATS.quarter) {\n      const q =\n        Math.floor(\n          Temporal.Instant.fromEpochMilliseconds(timestamp).toZonedDateTimeISO(timeZone).month / 3,\n        ) + 1;\n      return `Q${q} - ${this.format(timestamp, FORMATS.year as any)}`;\n    }\n\n    const options = typeof format === 'string' ? FORMAT_OPTIONS[format] : format;\n    const key = `${this.options.locale}:${timeZone}:${typeof format === 'string' ? format : JSON.stringify(format)}`;\n    let formatter = cache.get(key);\n\n    if (!formatter) {\n      formatter = new Intl.DateTimeFormat(this.options.locale, { ...options, timeZone });\n      cache.set(key, formatter);\n    }\n\n    return formatter.format(timestamp);\n  },\n\n  parse(value) {\n    if (value instanceof Date) {\n      return value.getTime();\n    }\n\n    if (typeof value === 'number') {\n      return value;\n    }\n\n    if (typeof value === 'string') {\n      try {\n        return Temporal.Instant.from(value).epochMilliseconds;\n      } catch {\n        try {\n          return Temporal.PlainDateTime.from(value).toZonedDateTime(getTimeZone(this.options))\n            .epochMilliseconds;\n        } catch {\n          // ignore\n        }\n      }\n    }\n\n    throw new Error(`Not a date: ${JSON.stringify(value)}`);\n  },\n\n  add(timestamp, amount, unit) {\n    if (unit === 'quarter') {\n      amount *= 3;\n      unit = 'month';\n    }\n\n    const temporalUnit: keyof Temporal.DurationLike = `${unit}s` as const;\n\n    return Temporal.Instant.fromEpochMilliseconds(timestamp)\n      .toZonedDateTimeISO(getTimeZone(this.options))\n      .add({ [temporalUnit]: amount }).epochMilliseconds;\n  },\n\n  diff(a, b, unit) {\n    if (unit === 'quarter') {\n      return Math.floor(this.diff(a, b, 'month') / 3);\n    }\n\n    const temporalUnit = `${unit}s` as const;\n    const _a = Temporal.Instant.fromEpochMilliseconds(a).toZonedDateTimeISO(\n      getTimeZone(this.options),\n    );\n    const _b = Temporal.Instant.fromEpochMilliseconds(b).toZonedDateTimeISO(\n      getTimeZone(this.options),\n    );\n\n    return _a.since(_b, { largestUnit: temporalUnit })[temporalUnit];\n  },\n\n  startOf(timestamp, unit) {\n    return startOf(timestamp, unit, this.options).epochMilliseconds;\n  },\n\n  endOf(timestamp, unit) {\n    const start = startOf(timestamp, unit, this.options);\n\n    // @ts-expect-error 'isoWeek' was removed\n    if (unit === 'isoWeek' || unit === 'week') {\n      return start.add({ days: 7 }).epochMilliseconds;\n    }\n\n    if (unit === 'quarter') {\n      return start.add({ months: 3 }).epochMilliseconds;\n    }\n\n    const temporalUnit: keyof Temporal.DurationLike = `${unit}s` as const;\n    return start.add({ [temporalUnit]: 1 }).epochMilliseconds;\n  },\n};\n\nexport default adapter;\n\nfunction startOf(\n  _ts: number,\n  unit: TimeUnit | 'isoWeek',\n  options: AdapterOptions,\n): Temporal.ZonedDateTime {\n  const ts = Temporal.Instant.fromEpochMilliseconds(_ts).toZonedDateTimeISO(getTimeZone(options));\n\n  if (unit === 'millisecond') {\n    return ts;\n  }\n\n  if (unit === 'isoWeek' || unit === 'week') {\n    const startOfDay = ts.startOfDay();\n    return startOfDay.subtract({\n      days: startOfDay.dayOfWeek - 1,\n    });\n  }\n\n  if (unit === 'quarter') {\n    const startOfMonth = startOf(_ts, 'month', options);\n    const quarter = Math.floor(startOfMonth.month / 3);\n    return startOfMonth.with({ month: quarter * 3 + 1 });\n  }\n\n  const index = units.indexOf(unit);\n  const resetUnits = Object.fromEntries(\n    units.slice(0, index).map((u) => [u, u === 'day' || u === 'month' ? 1 : 0]),\n  );\n\n  return ts.with(resetUnits);\n}\n"],"mappings":"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"}