@nhtio/encoder 1.20251230.0 → 1.20260624.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.
package/index.d.ts CHANGED
@@ -36,6 +36,17 @@ declare type CountryOrUnknown = Country | 'XX';
36
36
  */
37
37
  declare type CountryTimezone = 'Europe/Andorra' | 'Asia/Dubai' | 'Asia/Kabul' | 'America/Antigua' | 'America/Anguilla' | 'Europe/Tirane' | 'Asia/Yerevan' | 'Africa/Luanda' | 'Antarctica/Casey' | 'America/Argentina/Buenos_Aires' | 'Pacific/Pago_Pago' | 'Europe/Vienna' | 'Australia/Sydney' | 'America/Aruba' | 'Europe/Mariehamn' | 'Asia/Baku' | 'Europe/Sarajevo' | 'America/Barbados' | 'Asia/Dhaka' | 'Europe/Brussels' | 'Africa/Ouagadougou' | 'Europe/Sofia' | 'Asia/Bahrain' | 'Africa/Bujumbura' | 'Africa/Porto-Novo' | 'America/St_Barthelemy' | 'Atlantic/Bermuda' | 'Asia/Brunei' | 'America/La_Paz' | 'America/Kralendijk' | 'America/Sao_Paulo' | 'America/Nassau' | 'Asia/Thimphu' | 'Africa/Gaborone' | 'Europe/Minsk' | 'America/Belize' | 'America/Toronto' | 'Indian/Cocos' | 'Africa/Kinshasa' | 'Africa/Bangui' | 'Africa/Brazzaville' | 'Europe/Zurich' | 'Africa/Abidjan' | 'Pacific/Rarotonga' | 'America/Santiago' | 'Africa/Douala' | 'Asia/Shanghai' | 'America/Bogota' | 'America/Costa_Rica' | 'America/Havana' | 'Atlantic/Cape_Verde' | 'America/Curacao' | 'Indian/Christmas' | 'Asia/Nicosia' | 'Europe/Prague' | 'Europe/Berlin' | 'Africa/Djibouti' | 'Europe/Copenhagen' | 'America/Dominica' | 'America/Santo_Domingo' | 'Africa/Algiers' | 'America/Guayaquil' | 'Europe/Tallinn' | 'Africa/Cairo' | 'Africa/El_Aaiun' | 'Africa/Asmara' | 'Europe/Madrid' | 'Africa/Addis_Ababa' | 'Europe/Helsinki' | 'Pacific/Fiji' | 'Atlantic/Stanley' | 'Pacific/Pohnpei' | 'Atlantic/Faroe' | 'Europe/Paris' | 'Africa/Libreville' | 'Europe/London' | 'America/Grenada' | 'Asia/Tbilisi' | 'America/Cayenne' | 'Europe/Guernsey' | 'Africa/Accra' | 'Europe/Gibraltar' | 'America/Godthab' | 'Africa/Banjul' | 'Africa/Conakry' | 'America/Guadeloupe' | 'Africa/Malabo' | 'Europe/Athens' | 'Atlantic/South_Georgia' | 'America/Guatemala' | 'Pacific/Guam' | 'Africa/Bissau' | 'America/Guyana' | 'Asia/Hong_Kong' | 'America/Tegucigalpa' | 'Europe/Zagreb' | 'America/Port-au-Prince' | 'Europe/Budapest' | 'Asia/Jakarta' | 'Europe/Dublin' | 'Asia/Jerusalem' | 'Europe/Isle_of_Man' | 'Asia/Kolkata' | 'Indian/Chagos' | 'Asia/Baghdad' | 'Asia/Tehran' | 'Atlantic/Reykjavik' | 'Europe/Rome' | 'Europe/Jersey' | 'America/Jamaica' | 'Asia/Amman' | 'Asia/Tokyo' | 'Africa/Nairobi' | 'Asia/Bishkek' | 'Asia/Phnom_Penh' | 'Pacific/Tarawa' | 'Indian/Comoro' | 'America/St_Kitts' | 'Asia/Pyongyang' | 'Asia/Seoul' | 'Asia/Kuwait' | 'America/Cayman' | 'Asia/Almaty' | 'Asia/Vientiane' | 'Asia/Beirut' | 'America/St_Lucia' | 'Europe/Vaduz' | 'Asia/Colombo' | 'Africa/Monrovia' | 'Africa/Maseru' | 'Europe/Vilnius' | 'Europe/Luxembourg' | 'Europe/Riga' | 'Africa/Tripoli' | 'Africa/Casablanca' | 'Europe/Monaco' | 'Europe/Chisinau' | 'Europe/Podgorica' | 'America/Marigot' | 'Indian/Antananarivo' | 'Pacific/Majuro' | 'Europe/Skopje' | 'Africa/Bamako' | 'Asia/Yangon' | 'Asia/Ulaanbaatar' | 'Asia/Macau' | 'Pacific/Saipan' | 'America/Martinique' | 'Africa/Nouakchott' | 'America/Montserrat' | 'Europe/Malta' | 'Indian/Mauritius' | 'Indian/Maldives' | 'Africa/Blantyre' | 'America/Mexico_City' | 'Asia/Kuala_Lumpur' | 'Africa/Maputo' | 'Africa/Windhoek' | 'Pacific/Noumea' | 'Africa/Niamey' | 'Pacific/Norfolk' | 'Africa/Lagos' | 'America/Managua' | 'Europe/Amsterdam' | 'Europe/Oslo' | 'Asia/Kathmandu' | 'Pacific/Nauru' | 'Pacific/Niue' | 'Pacific/Auckland' | 'Asia/Muscat' | 'America/Panama' | 'America/Lima' | 'Pacific/Tahiti' | 'Pacific/Port_Moresby' | 'Asia/Manila' | 'Asia/Karachi' | 'Europe/Warsaw' | 'America/Miquelon' | 'Pacific/Pitcairn' | 'America/Puerto_Rico' | 'Asia/Gaza' | 'Europe/Lisbon' | 'Pacific/Palau' | 'America/Asuncion' | 'Asia/Qatar' | 'Indian/Reunion' | 'Europe/Bucharest' | 'Europe/Belgrade' | 'Europe/Moscow' | 'Africa/Kigali' | 'Asia/Riyadh' | 'Pacific/Guadalcanal' | 'Indian/Mahe' | 'Africa/Khartoum' | 'Europe/Stockholm' | 'Asia/Singapore' | 'Atlantic/St_Helena' | 'Europe/Ljubljana' | 'Arctic/Longyearbyen' | 'Europe/Bratislava' | 'Africa/Freetown' | 'Europe/San_Marino' | 'Africa/Dakar' | 'Africa/Mogadishu' | 'America/Paramaribo' | 'Africa/Juba' | 'Africa/Sao_Tome' | 'America/El_Salvador' | 'America/Lower_Princes' | 'Asia/Damascus' | 'Africa/Mbabane' | 'America/Grand_Turk' | 'Africa/Ndjamena' | 'Indian/Kerguelen' | 'Africa/Lome' | 'Asia/Bangkok' | 'Asia/Dushanbe' | 'Pacific/Fakaofo' | 'Asia/Dili' | 'Asia/Ashgabat' | 'Africa/Tunis' | 'Pacific/Tongatapu' | 'Europe/Istanbul' | 'America/Port_of_Spain' | 'Pacific/Funafuti' | 'Asia/Taipei' | 'Africa/Dar_es_Salaam' | 'Europe/Kiev' | 'Africa/Kampala' | 'Pacific/Wake' | 'America/New_York' | 'America/Montevideo' | 'Asia/Tashkent' | 'Europe/Vatican' | 'America/St_Vincent' | 'America/Caracas' | 'America/Tortola' | 'America/St_Thomas' | 'Asia/Ho_Chi_Minh' | 'Pacific/Efate' | 'Pacific/Wallis' | 'Pacific/Apia' | 'Asia/Aden' | 'Indian/Mayotte' | 'Africa/Johannesburg' | 'Africa/Lusaka' | 'Africa/Harare';
38
38
 
39
+ /**
40
+ * A class that opts in to custom encoding/decoding.
41
+ *
42
+ * Implement `[ENCODE_METHOD]()` on instances to produce an Encodable snapshot,
43
+ * and `static [DECODE_METHOD](data)` to reconstruct the instance.
44
+ * Pass the class to `registerClass()` so the decoder can find it.
45
+ */
46
+ export declare interface CustomEncodable {
47
+ [ENCODE_METHOD](): Encodable;
48
+ }
49
+
39
50
  declare type DateInput = DateTime | DateObjectUnits | Date;
40
51
 
41
52
  /**
@@ -1485,6 +1496,11 @@ declare type DayNumbers =
1485
1496
  | 30
1486
1497
  | 31;
1487
1498
 
1499
+ declare interface DecodableConstructor {
1500
+ readonly name: string;
1501
+ [DECODE_METHOD](data: Encodable): any;
1502
+ }
1503
+
1488
1504
  /**
1489
1505
  * Decodes a compressed base64 string back into a value
1490
1506
  * @param base64 The compressed base64 string representing an encoded value
@@ -1496,6 +1512,9 @@ declare type DayNumbers =
1496
1512
  */
1497
1513
  export declare const decode: <T extends Encodable = Encodable>(base64: string) => T;
1498
1514
 
1515
+ /** Static method: reconstruct an instance from an Encodable snapshot */
1516
+ export declare const DECODE_METHOD: unique symbol;
1517
+
1499
1518
  declare type DefaultValidity = CanBeInvalid extends true ? boolean : true;
1500
1519
 
1501
1520
  declare interface DiffOptions {
@@ -1996,7 +2015,7 @@ declare type DurationUnits = DurationUnit | DurationUnit[];
1996
2015
  */
1997
2016
  export declare type Encodable = EncodablePrimitive | Date | RegExp | ArrayBuffer | DataView | DateTime | Duration | Interval | EncodableTypedArray | Encodable[] | {
1998
2017
  [key: string]: Encodable;
1999
- } | Map<Encodable, Encodable> | Set<Encodable> | Error | EvalError | RangeError | ReferenceError | SyntaxError | TypeError | URIError | PhoneModel | Function | ((...args: any[]) => any);
2018
+ } | Map<Encodable, Encodable> | Set<Encodable> | Error | EvalError | RangeError | ReferenceError | SyntaxError | TypeError | URIError | PhoneModel | Function | ((...args: any[]) => any) | CustomEncodable;
2000
2019
 
2001
2020
  /**
2002
2021
  * Defines the union of all encodable primitive types.
@@ -2018,6 +2037,9 @@ export declare type EncodableTypedArray = Int8Array | Uint8Array | Uint8ClampedA
2018
2037
  */
2019
2038
  export declare const encode: <T extends Encodable = Encodable>(what: T) => string;
2020
2039
 
2040
+ /** Instance method: serialize the object into an Encodable snapshot */
2041
+ export declare const ENCODE_METHOD: unique symbol;
2042
+
2021
2043
  declare type EndOfOptions = _UseLocaleWeekOption;
2022
2044
 
2023
2045
  declare interface ExplainedFormat {
@@ -2638,6 +2660,15 @@ declare type PossibleWeeksInYear = 52 | 53;
2638
2660
 
2639
2661
  declare type QuarterNumbers = 1 | 2 | 3 | 4;
2640
2662
 
2663
+ /**
2664
+ * Register a class so the decoder can reconstruct it from a snapshot.
2665
+ * The class must have a static `[DECODE_METHOD]` that accepts an Encodable
2666
+ * snapshot and returns an instance of the class.
2667
+ *
2668
+ * @param ctor - The class constructor to register
2669
+ */
2670
+ export declare const registerClass: (ctor: DecodableConstructor) => void;
2671
+
2641
2672
  declare type ResolvedLocaleOptions = Required<LocaleOptions>;
2642
2673
 
2643
2674
  declare type SecondNumbers =
package/index.mjs CHANGED
@@ -1,6 +1,6 @@
1
- import { i as isObject, a as isArray, b as isSet, c as isMap, d as isLuxonSystemZone, e as isLuxonInterval, f as isLuxonDuration, g as isLuxonDateTime, D as DateTime, h as isPhoneObject, j as isTypedArray, k as isBigIntTypedArray, l as isPrimitive, m as isUniterableObject, n as isError, o as isBigInt, p as isUnsafeInteger, q as isNegativeInfinity, r as isPositiveInfinity, s as isNegativeZero, I as Info, t as Interval, u as Duration, P as Phone } from "./type_guards-UkDoe__i.mjs";
1
+ import { i as isObject, a as isCustomEncodable, E as ENCODE_METHOD, b as isArray, c as isSet, d as isMap, e as isLuxonSystemZone, f as isLuxonInterval, g as isLuxonDuration, h as isLuxonDateTime, j as isPhoneObject, k as isTypedArray, l as isBigIntTypedArray, m as isPrimitive, n as isUniterableObject, o as isError, p as isBigInt, q as isUnsafeInteger, r as isNegativeInfinity, s as isPositiveInfinity, t as isNegativeZero, D as DECODE_METHOD, I as Info, u as Interval, v as DateTime, w as Duration, P as Phone } from "./type_guards-BAhiOypL.mjs";
2
2
  import { FunctionSerializer } from "./function_serializer.mjs";
3
- import { E as E_UNENCODABLE_VALUE, a as E_CIRCULAR_REFERENCE, b as E_ENCODING_FAILED, B as BaseException, c as E_UNDECODABLE_VALUE, d as E_NOT_AN_ENCODED_VALUE, e as E_INVALID_VERSION, f as E_INCOMPATIBLE_VERSION } from "./exceptions-ieVRrxe4.mjs";
3
+ import { E as E_UNENCODABLE_VALUE, a as E_CIRCULAR_REFERENCE, b as E_ENCODING_FAILED, B as BaseException, c as E_UNDECODABLE_VALUE, d as E_NOT_AN_ENCODED_VALUE, e as E_INVALID_VERSION, f as E_INCOMPATIBLE_VERSION } from "./exceptions-CypFn5FZ.mjs";
4
4
  var re = { exports: {} };
5
5
  var constants;
6
6
  var hasRequiredConstants;
@@ -2728,6 +2728,16 @@ const atou = (base64) => {
2728
2728
  }
2729
2729
  return decodeURIComponent(escape(binary));
2730
2730
  };
2731
+ const registry = /* @__PURE__ */ new Map();
2732
+ const registerClass = (ctor) => {
2733
+ if (typeof ctor.name !== "string" || ctor.name === "") {
2734
+ throw new TypeError("Cannot register an anonymous class — give it an explicit name.");
2735
+ }
2736
+ registry.set(ctor.name, ctor);
2737
+ };
2738
+ const getRegisteredClass = (name) => {
2739
+ return registry.get(name);
2740
+ };
2731
2741
  const VOID = -1;
2732
2742
  const PRIMITIVE = 0;
2733
2743
  const ARRAY = 1;
@@ -3025,14 +3035,12 @@ const toStructuredData = (value, seen = /* @__PURE__ */ new WeakSet()) => {
3025
3035
  throw new E_CIRCULAR_REFERENCE();
3026
3036
  }
3027
3037
  seen.add(value);
3028
- const dto = value instanceof DateTime ? value : DateTime.fromObject(value.c, { zone: value.zone }).setLocale(
3029
- value.loc.locale
3030
- );
3038
+ const dto = value;
3031
3039
  return {
3032
3040
  _t: "luxon:DateTime",
3033
3041
  _s: toStructuredData(
3034
3042
  {
3035
- v: dto.toRFC2822(),
3043
+ v: dto.toMillis(),
3036
3044
  z: dto.zoneName,
3037
3045
  l: dto.locale,
3038
3046
  c: dto.outputCalendar,
@@ -3136,6 +3144,25 @@ const toStructuredData = (value, seen = /* @__PURE__ */ new WeakSet()) => {
3136
3144
  _s: utoa(JSON.stringify(value.map((item) => toStructuredData(item, seen))))
3137
3145
  };
3138
3146
  }
3147
+ case isCustomEncodable(value): {
3148
+ if (seen.has(value)) {
3149
+ throw new E_CIRCULAR_REFERENCE();
3150
+ }
3151
+ seen.add(value);
3152
+ const className = value.constructor.name;
3153
+ try {
3154
+ const snapshot = value[ENCODE_METHOD]();
3155
+ return {
3156
+ _t: `custom:${className}`,
3157
+ _s: toStructuredData(snapshot, seen)
3158
+ };
3159
+ } catch (e) {
3160
+ if (e instanceof BaseException) {
3161
+ throw e;
3162
+ }
3163
+ throw new E_ENCODING_FAILED(value, e);
3164
+ }
3165
+ }
3139
3166
  case isObject(value): {
3140
3167
  if (seen.has(value)) {
3141
3168
  throw new E_CIRCULAR_REFERENCE();
@@ -3224,13 +3251,16 @@ const fromStructuredData = (data) => {
3224
3251
  }
3225
3252
  case "luxon:DateTime": {
3226
3253
  const obj = fromStructuredData(data._s);
3227
- return DateTime.fromRFC2822(obj.v, {
3228
- // setZone: true,
3254
+ const options2 = {
3229
3255
  zone: obj.z,
3230
3256
  locale: obj.l,
3231
3257
  outputCalendar: obj.c,
3232
3258
  numberingSystem: obj.n
3233
- });
3259
+ };
3260
+ if (typeof obj.v !== "number") {
3261
+ return DateTime.fromRFC2822(obj.v, options2);
3262
+ }
3263
+ return DateTime.fromMillis(obj.v, options2);
3234
3264
  }
3235
3265
  case "luxon:Duration": {
3236
3266
  const obj = fromStructuredData(data._s);
@@ -3259,19 +3289,44 @@ const fromStructuredData = (data) => {
3259
3289
  throw err2;
3260
3290
  }
3261
3291
  }
3262
- default:
3292
+ default: {
3293
+ if (data._t.startsWith("custom:")) {
3294
+ const className = data._t.slice("custom:".length);
3295
+ const ctor = getRegisteredClass(className);
3296
+ if (!ctor) {
3297
+ const err2 = new E_UNDECODABLE_VALUE(data._t);
3298
+ err2.cause = new Error(
3299
+ `No class registered for "${className}". Call registerClass(${className}) before decoding.`
3300
+ );
3301
+ throw err2;
3302
+ }
3303
+ try {
3304
+ const snapshot = fromStructuredData(data._s);
3305
+ return ctor[DECODE_METHOD](snapshot);
3306
+ } catch (e) {
3307
+ if (e instanceof BaseException) {
3308
+ throw e;
3309
+ }
3310
+ const err2 = new E_UNDECODABLE_VALUE(data._t);
3311
+ if (e instanceof Error) {
3312
+ err2.cause = e;
3313
+ }
3314
+ throw err2;
3315
+ }
3316
+ }
3263
3317
  throw new E_UNDECODABLE_VALUE(data._t);
3318
+ }
3264
3319
  }
3265
3320
  };
3266
3321
  const { parse: $parse, stringify: $stringify } = JSON;
3267
3322
  const options = { json: true, lossy: true };
3268
3323
  const parse = (str) => deserialize($parse(str));
3269
3324
  const stringify = (any) => $stringify(serialize(any, options));
3270
- const version = "1.20251230.0";
3325
+ const version = "1.20260624.0";
3271
3326
  const encode = (what) => {
3272
3327
  const structured = toStructuredData(what);
3273
3328
  const serialized = serialize(structured, { lossy: true, json: true });
3274
- const json = stringify({ version: "1.20251230.0", serialized });
3329
+ const json = stringify({ version: "1.20260624.0", serialized });
3275
3330
  return utoa(json);
3276
3331
  };
3277
3332
  const decode = (base64) => {
@@ -3282,11 +3337,11 @@ const decode = (base64) => {
3282
3337
  throw new E_NOT_AN_ENCODED_VALUE(base64);
3283
3338
  }
3284
3339
  const { version: payloadVersion, serialized } = parsed;
3285
- if (semverExports.valid("1.20251230.0")) {
3340
+ if (semverExports.valid("1.20260624.0")) {
3286
3341
  if (!semverExports.valid(semverExports.coerce(payloadVersion))) {
3287
3342
  throw new E_INVALID_VERSION(payloadVersion);
3288
3343
  }
3289
- if (semverExports.gt(semverExports.coerce(payloadVersion), "1.20251230.0")) {
3344
+ if (semverExports.gt(semverExports.coerce(payloadVersion), "1.20260624.0")) {
3290
3345
  throw new E_INCOMPATIBLE_VERSION(payloadVersion);
3291
3346
  }
3292
3347
  }
@@ -3302,8 +3357,11 @@ const decode = (base64) => {
3302
3357
  }
3303
3358
  };
3304
3359
  export {
3360
+ DECODE_METHOD,
3361
+ ENCODE_METHOD,
3305
3362
  decode,
3306
3363
  encode,
3364
+ registerClass,
3307
3365
  version
3308
3366
  };
3309
3367
  //# sourceMappingURL=index.mjs.map