UNPKG

@everwhen/temporal

Version:
137 lines (136 loc) 4.5 kB
import * as devalue from 'devalue'; import { Instant } from "../instant.js"; import { isInstant, isPlainDate, isPlainDateTime, isPlainTime, isPlainYearMonth, isZonedDateTime, } from "../is.js"; import { PlainDateTime } from "../plain-date-time.js"; import { PlainDate } from "../plain-date.js"; import { PlainTime } from "../plain-time.js"; import { PlainYearMonth } from "../plain-year-month.js"; import { ZonedDateTime } from "../zoned-date-time.js"; /** * Serializes a value containing temporal types to a JSON string. * * Uses `devalue` for serialization, automatically handling all temporal types: * `PlainDate`, `PlainDateTime`, `PlainTime`, `PlainYearMonth`, `ZonedDateTime`, and `Instant`. * * @param value - The value to serialize (can contain temporal types at any depth) * @param reducers - Optional additional reducers for custom types * @returns A JSON string that can be parsed back with `parse()` * * @example * ```ts * import { PlainDate } from '@everwhen/temporal' * import { json } from '@everwhen/temporal/fn' * * const data = { * event: 'Birthday', * date: PlainDate.from('2024-06-15'), * } * * const serialized = json.stringify(data) * // Preserves the PlainDate type information * ``` * * @example * ```ts * import { PlainDateTime, ZonedDateTime } from '@everwhen/temporal' * import { json } from '@everwhen/temporal/fn' * * // Works with nested structures and arrays * const schedule = { * meetings: [ * { time: PlainDateTime.from('2024-06-15T09:00'), title: 'Standup' }, * { time: PlainDateTime.from('2024-06-15T14:00'), title: 'Review' }, * ], * } * * const serialized = json.stringify(schedule) * ``` */ export function stringify(value, reducers) { return devalue.stringify(value, { PlainDate: (val) => isPlainDate(val) && val.toJSON(), PlainDateTime: (val) => isPlainDateTime(val) && val.toJSON(), PlainTime: (val) => isPlainTime(val) && val.toJSON(), PlainYearMonth: (val) => isPlainYearMonth(val) && val.toJSON(), ZonedDateTime: (val) => isZonedDateTime(val) && val.toJSON(), Instant: (val) => isInstant(val) && val.toJSON(), ...reducers, }); } /** * Parses a JSON string serialized with `stringify()`, restoring temporal types. * * Uses `devalue` for parsing, automatically restoring all temporal types: * `PlainDate`, `PlainDateTime`, `PlainTime`, `PlainYearMonth`, `ZonedDateTime`, and `Instant`. * * @param serialized - The JSON string to parse (created by `stringify()`) * @param revivers - Optional additional revivers for custom types * @returns The parsed value with temporal types restored * * @example * ```ts * import { PlainDate } from '@everwhen/temporal' * import { json } from '@everwhen/temporal/fn' * * const data = { * event: 'Birthday', * date: PlainDate.from('2024-06-15'), * } * * const serialized = json.stringify(data) * const restored = json.parse(serialized) as typeof data * * restored.date instanceof PlainDate // true * restored.date.month // 6 * ``` * * @example * ```ts * import { json } from '@everwhen/temporal/fn' * * // Round-trip serialization preserves types * const original = { times: [PlainTime.from('09:00'), PlainTime.from('17:00')] } * const restored = json.parse(json.stringify(original)) * * restored.times[0].hour // 9 * ``` */ export function parse(serialized, revivers) { return devalue.parse(serialized, { PlainDate: (v) => PlainDate.from(v), PlainDateTime: (v) => PlainDateTime.from(v), PlainTime: (v) => PlainTime.from(v), PlainYearMonth: (v) => PlainYearMonth.from(v), ZonedDateTime: (v) => ZonedDateTime.from(v), Instant: (v) => Instant.from(v), ...revivers, }); } /** * JSON serialization utilities for temporal types. * * Provides `stringify` and `parse` methods that automatically handle * serialization and deserialization of temporal types using `devalue`. * * @example * ```ts * import { PlainDate, PlainDateTime } from '@everwhen/temporal' * import { json } from '@everwhen/temporal/fn' * * const event = { * name: 'Conference', * date: PlainDate.from('2024-06-15'), * startTime: PlainDateTime.from('2024-06-15T09:00'), * } * * // Serialize to JSON string * const serialized = json.stringify(event) * * // Parse back to objects with temporal types restored * const restored = json.parse(serialized) * ``` */ export const json = { stringify, parse, };