@nextera.one/tps-standard 0.5.0 → 0.5.2

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/dist/index.d.ts CHANGED
@@ -2,32 +2,79 @@
2
2
  * TPS: Temporal Positioning System
3
3
  * The Universal Protocol for Space-Time Coordinates.
4
4
  * @packageDocumentation
5
- * @version 0.4.2
6
- * @license MIT
5
+ * @version 0.5.0
6
+ * @license Apache-2.0
7
7
  * @copyright 2026 TPS Standards Working Group
8
+ *
9
+ * v0.5.0 Changes:
10
+ * - Added Actor anchor (A:) for provenance tracking
11
+ * - Added Signature (!) for cryptographic verification
12
+ * - Added structural anchors (bldg, floor, room, zone)
13
+ * - Added geospatial cell systems (S2, H3, Plus Code, what3words)
14
+ */
15
+ export declare const DefaultCalendars: {
16
+ readonly TPS: "tps";
17
+ readonly GREG: "greg";
18
+ readonly HIJ: "hij";
19
+ readonly JUL: "jul";
20
+ readonly HOLO: "holo";
21
+ readonly UNIX: "unix";
22
+ };
23
+ /**
24
+ * Specifies the direction of the time-component hierarchy when serializing or
25
+ * deserializing a TPS string. The default is `'descending'` (millennium → … →
26
+ * second), but `'ascending'` produces the reverse order.
8
27
  */
9
- export type CalendarCode = 'greg' | 'hij' | 'jul' | 'holo' | 'unix';
28
+ export declare enum TimeOrder {
29
+ DESC = "desc",
30
+ ASC = "asc"
31
+ }
10
32
  export interface TPSComponents {
11
- calendar: CalendarCode;
12
- millennium?: number;
13
- century?: number;
14
- year?: number;
15
- month?: number;
16
- day?: number;
17
- hour?: number;
18
- minute?: number;
19
- second?: number;
33
+ calendar: string;
34
+ millennium: number;
35
+ century: number;
36
+ year: number;
37
+ month: number;
38
+ day: number;
39
+ hour: number;
40
+ minute: number;
41
+ second: number;
42
+ /** Sub-second precision (0–999). Encoded as the last `m` token. */
43
+ millisecond: number;
20
44
  unixSeconds?: number;
21
45
  latitude?: number;
22
46
  longitude?: number;
23
47
  altitude?: number;
48
+ /** Google S2 cell ID (hierarchical, prefix-searchable) */
49
+ s2Cell?: string;
50
+ /** Uber H3 cell ID (hexagonal grid) */
51
+ h3Cell?: string;
52
+ /** Open Location Code / Plus Code */
53
+ plusCode?: string;
54
+ /** what3words address (e.g. "filled.count.soap") */
55
+ what3words?: string;
56
+ /** Physical building identifier */
57
+ building?: string;
58
+ /** Vertical division (level) */
59
+ floor?: string;
60
+ /** Enclosed space identifier */
61
+ room?: string;
62
+ /** Logical area within building */
63
+ zone?: string;
64
+ /** Raw pre-@ space anchor (e.g. adm:city:SA:riyadh, node:api-1, net:ip4:203.0.113.10) */
65
+ spaceAnchor?: string;
24
66
  /** Technical missing data (e.g. server log without GPS) */
25
67
  isUnknownLocation?: boolean;
26
68
  /** Removed for legal/security reasons (e.g. GDPR) */
27
69
  isRedactedLocation?: boolean;
28
70
  /** Masked by user preference (e.g. "Don't show my location") */
29
71
  isHiddenLocation?: boolean;
72
+ /** Actor anchor - identifies observer/witness (e.g. "did:web:sensor.example.com", "node:gateway-01") */
73
+ actor?: string;
74
+ /** Verification hash appended to time (e.g. "sha256:8f3e2a...") */
75
+ signature?: string;
30
76
  extensions?: Record<string, string>;
77
+ order?: TimeOrder;
31
78
  }
32
79
  /**
33
80
  * Interface for Calendar Driver plugins.
@@ -80,30 +127,30 @@ export interface TPSComponents {
80
127
  */
81
128
  export interface CalendarDriver {
82
129
  /** The calendar code this driver handles (e.g., 'hij', 'jul'). */
83
- readonly code: CalendarCode;
130
+ readonly code: string;
84
131
  /**
85
132
  * Human-readable name for this calendar (optional).
86
133
  * @example "Hijri (Islamic)"
87
134
  */
88
135
  readonly name?: string;
89
136
  /**
90
- * Converts a Gregorian Date to this calendar's components.
137
+ * Converts a Date to this calendar's components.
91
138
  * @param date - The Gregorian Date object.
92
139
  * @returns Partial TPS components for year, month, day, etc.
93
140
  */
94
- fromGregorian(date: Date): Partial<TPSComponents>;
141
+ getComponentsFromDate(date: Date): Partial<TPSComponents>;
95
142
  /**
96
- * Converts this calendar's components to a Gregorian Date.
143
+ * Converts this calendar's components to a Date.
97
144
  * @param components - Partial TPS components (year, month, day, etc.).
98
145
  * @returns A JavaScript Date object.
99
146
  */
100
- toGregorian(components: Partial<TPSComponents>): Date;
147
+ getDateFromComponents(components: Partial<TPSComponents>): Date;
101
148
  /**
102
149
  * Generates a TPS time string for this calendar from a Date.
103
150
  * @param date - The Gregorian Date object.
104
- * @returns A TPS time string (e.g., "T:hij.y1447.M07.d21...").
151
+ * @returns A TPS time string (e.g., "T:hij.y1447.m07.d21...").
105
152
  */
106
- fromDate(date: Date): string;
153
+ getFromDate(date: Date): string;
107
154
  /**
108
155
  * Parse a calendar-specific date string into TPS components.
109
156
  * This allows drivers to handle native date formats from external libraries.
@@ -121,7 +168,7 @@ export interface CalendarDriver {
121
168
  * driver.parseDate('1447-07-21 14:30:00'); // → { year: 1447, month: 7, day: 21, hour: 14, ... }
122
169
  * ```
123
170
  */
124
- parseDate?(input: string, format?: string): Partial<TPSComponents>;
171
+ parseDate(input: string, format?: string): Partial<TPSComponents>;
125
172
  /**
126
173
  * Format TPS components to a calendar-specific date string.
127
174
  * Inverse of parseDate().
@@ -136,7 +183,7 @@ export interface CalendarDriver {
136
183
  * driver.format({ year: 1447, month: 7, day: 21 }, 'short'); // → '21/7/1447'
137
184
  * ```
138
185
  */
139
- format?(components: Partial<TPSComponents>, format?: string): string;
186
+ format(components: Partial<TPSComponents>, format?: string): string;
140
187
  /**
141
188
  * Validate a calendar-specific date string or components.
142
189
  *
@@ -149,7 +196,7 @@ export interface CalendarDriver {
149
196
  * driver.validate({ year: 1447, month: 7, day: 31 }); // → false (Rajab has 30 days)
150
197
  * ```
151
198
  */
152
- validate?(input: string | Partial<TPSComponents>): boolean;
199
+ validate(input: string | Partial<TPSComponents>): boolean;
153
200
  /**
154
201
  * Get calendar metadata (month names, day names, etc.).
155
202
  * Useful for UI rendering.
@@ -160,7 +207,7 @@ export interface CalendarDriver {
160
207
  * // → ['Muharram', 'Safar', 'Rabi I', ...]
161
208
  * ```
162
209
  */
163
- getMetadata?(): CalendarMetadata;
210
+ getMetadata(): CalendarMetadata;
164
211
  }
165
212
  /**
166
213
  * Metadata about a calendar system.
@@ -195,9 +242,18 @@ export declare class TPS {
195
242
  * @param code - The calendar code.
196
243
  * @returns The driver or undefined.
197
244
  */
198
- static getDriver(code: CalendarCode): CalendarDriver | undefined;
245
+ static getDriver(code: string): CalendarDriver | undefined;
199
246
  private static readonly REGEX_URI;
200
247
  private static readonly REGEX_TIME;
248
+ /**
249
+ * SANITIZER: Normalises a raw TPS input string before validation.
250
+ *
251
+ * Pure string-based — no parsing into components, no regex beyond simple
252
+ * character checks, no re-serialisation via buildTimePart / toURI.
253
+ *
254
+ * Token ranks (descending): m(8) c(7) y(6) m(5) d(4) h(3) m(2) s(1) m(0)
255
+ */
256
+ static sanitizeTimeInput(input: string): string;
201
257
  static validate(input: string): boolean;
202
258
  static parse(input: string): TPSComponents | null;
203
259
  /**
@@ -210,10 +266,14 @@ export declare class TPS {
210
266
  * CONVERTER: Creates a TPS Time Object string from a JavaScript Date.
211
267
  * Supports plugin drivers for non-Gregorian calendars.
212
268
  * @param date - The JS Date object (defaults to Now).
213
- * @param calendar - The target calendar driver (default 'greg').
214
- * @returns Canonical string (e.g., "T:greg.m3.c1.y26...").
269
+ * @param calendar - The target calendar driver (default `"tps"`).
270
+ * @param opts - Optional parameters; for built-in calendars the only
271
+ * supported key is `order` which may be `'ascending'` or `'descending'`.
272
+ * @returns Canonical string (e.g., "T:tps.m3.c1.y26...").
215
273
  */
216
- static fromDate(date?: Date, calendar?: CalendarCode): string;
274
+ static fromDate(date?: Date, calendar?: string, opts?: {
275
+ order?: TimeOrder;
276
+ }): string;
217
277
  /**
218
278
  * CONVERTER: Converts a TPS string to a Date in a target calendar format.
219
279
  * Uses plugin drivers for cross-calendar conversion.
@@ -221,7 +281,7 @@ export declare class TPS {
221
281
  * @param targetCalendar - The target calendar code (e.g., 'hij').
222
282
  * @returns A TPS string in the target calendar, or null if invalid.
223
283
  */
224
- static to(targetCalendar: CalendarCode, tpsString: string): string | null;
284
+ static to(targetCalendar: string, tpsString: string): string | null;
225
285
  /**
226
286
  * CONVERTER: Reconstructs a JavaScript Date object from a TPS string.
227
287
  * Supports plugin drivers for non-Gregorian calendars.
@@ -231,7 +291,7 @@ export declare class TPS {
231
291
  static toDate(tpsString: string): Date | null;
232
292
  /**
233
293
  * Parse a calendar-specific date string into TPS components.
234
- * Requires the driver to implement the optional `parseDate` method.
294
+ * Requires the driver to implement `parseDate`.
235
295
  *
236
296
  * @param calendar - The calendar code (e.g., 'hij')
237
297
  * @param dateString - Date string in calendar-native format (e.g., '1447-07-21')
@@ -244,10 +304,10 @@ export declare class TPS {
244
304
  * // { calendar: 'hij', year: 1447, month: 7, day: 21 }
245
305
  *
246
306
  * const uri = TPS.toURI({ ...components, latitude: 31.95, longitude: 35.91 });
247
- * // "tps://31.95,35.91@T:hij.y1447.M07.d21"
307
+ * // "tps://31.95,35.91@T:hij.y1447.m07.d21"
248
308
  * ```
249
309
  */
250
- static parseCalendarDate(calendar: CalendarCode, dateString: string, format?: string): Partial<TPSComponents> | null;
310
+ static parseCalendarDate(calendar: string, dateString: string, format?: string): Partial<TPSComponents> | null;
251
311
  /**
252
312
  * Convert a calendar-specific date string directly to a TPS URI.
253
313
  * This is a convenience method that combines parseDate + toURI.
@@ -261,18 +321,18 @@ export declare class TPS {
261
321
  * ```ts
262
322
  * // With coordinates
263
323
  * TPS.fromCalendarDate('hij', '1447-07-21', { latitude: 31.95, longitude: 35.91 });
264
- * // "tps://31.95,35.91@T:hij.y1447.M07.d21"
324
+ * // "tps://31.95,35.91@T:hij.y1447.m07.d21"
265
325
  *
266
326
  * // With privacy flag
267
327
  * TPS.fromCalendarDate('hij', '1447-07-21', { isHiddenLocation: true });
268
- * // "tps://hidden@T:hij.y1447.M07.d21"
328
+ * // "tps://hidden@T:hij.y1447.m07.d21"
269
329
  *
270
330
  * // Without location
271
331
  * TPS.fromCalendarDate('hij', '1447-07-21');
272
- * // "tps://unknown@T:hij.y1447.M07.d21"
332
+ * // "tps://unknown@T:hij.y1447.m07.d21"
273
333
  * ```
274
334
  */
275
- static fromCalendarDate(calendar: CalendarCode, dateString: string, location?: {
335
+ static fromCalendarDate(calendar: string, dateString: string, location?: {
276
336
  latitude?: number;
277
337
  longitude?: number;
278
338
  altitude?: number;
@@ -282,7 +342,7 @@ export declare class TPS {
282
342
  }): string;
283
343
  /**
284
344
  * Format TPS components to a calendar-specific date string.
285
- * Requires the driver to implement the optional `format` method.
345
+ * Requires the driver to implement `format`.
286
346
  *
287
347
  * @param calendar - The calendar code
288
348
  * @param components - TPS components to format
@@ -291,21 +351,61 @@ export declare class TPS {
291
351
  *
292
352
  * @example
293
353
  * ```ts
294
- * const tps = TPS.parse('tps://unknown@T:hij.y1447.M07.d21');
354
+ * const tps = TPS.parse('tps://unknown@T:hij.y1447.m07.d21');
295
355
  * const formatted = TPS.formatCalendarDate('hij', tps);
296
356
  * // "1447-07-21"
297
357
  * ```
298
358
  */
299
- static formatCalendarDate(calendar: CalendarCode, components: Partial<TPSComponents>, format?: string): string;
359
+ static formatCalendarDate(calendar: string, components: Partial<TPSComponents>, format?: string): string;
360
+ /**
361
+ * Generate the canonical `T:` time string for a set of components. The
362
+ * `order` field (or `comp.order`) controls whether tokens are emitted in
363
+ * ascending or descending hierarchy; if undefined the default
364
+ * `'descending'` orientation is used.
365
+ *
366
+ * Drivers may ignore this helper and produce their own time strings if they
367
+ * implement custom ordering logic.
368
+ */
369
+ static buildTimePart(comp: TPSComponents): string;
370
+ /**
371
+ * Parse the *time* portion of a TPS string (optionally beginning with
372
+ * `T:`) into components and determine the component ordering. This helper
373
+ * accepts tokens in **any** sequence and will return an `order` value of
374
+ * `'ascending'` or `'descending'`.
375
+ *
376
+ * The caller is responsible for stripping off a leading signature or other
377
+ * trailer characters; this method will drop anything after `!`, `;`, `?` or
378
+ * `#`.
379
+ *
380
+ * ### `m`-token disambiguation
381
+ * All four of millennium (rank 8), month (rank 5), minute (rank 2) and
382
+ * millisecond (rank 0) share the single-character prefix `m`. They are told
383
+ * apart by their **position relative to the neighbouring tokens**. The
384
+ * algorithm is:
385
+ *
386
+ * 1. Pre-scan the non-`m` tokens (c, y, d, h, s) whose ranks are fixed to
387
+ * determine whether the string is ascending or descending.
388
+ * 2. While iterating, track `lastAssignedRank` – the rank of the most
389
+ * recently processed token (m or non-m).
390
+ * 3. When an `m` token is encountered, derive its rank from `lastAssignedRank`
391
+ * and the detected order:
392
+ * - **DESC** null → 8 (mill) | rank > 5 → 5 (month) | rank > 2 → 2 (min) | else → 0 (ms)
393
+ * - **ASC** null → 0 (ms) | rank < 2 → 2 (min) | rank < 5 → 5 (month) | else → 8 (mill)
394
+ *
395
+ * @param input - Time fragment (e.g. `"T:greg.m3.c1.y26"` or `"greg.m0.s25.m30"`)
396
+ */
397
+ static parseTimeString(input: string): {
398
+ components: Partial<TPSComponents>;
399
+ order: TimeOrder;
400
+ } | null;
300
401
  private static _mapGroupsToComponents;
301
- private static pad;
302
402
  }
303
403
  /**
304
404
  * Decoded result from TPSUID7RB binary format.
305
405
  */
306
406
  export type TPSUID7RBDecodeResult = {
307
407
  /** Version identifier */
308
- version: 'tpsuid7rb';
408
+ version: "tpsuid7rb";
309
409
  /** Epoch milliseconds (UTC) */
310
410
  epochMs: number;
311
411
  /** Whether the TPS payload was compressed */
@@ -344,7 +444,7 @@ export type TPSUID7RBEncodeOptions = {
344
444
  *
345
445
  * @example
346
446
  * ```ts
347
- * const tps = 'tps://31.95,35.91@T:greg.m3.c1.y26.M01.d09';
447
+ * const tps = 'tps://31.95,35.91@T:greg.m3.c1.y26.m01.d09';
348
448
  *
349
449
  * // Encode to binary
350
450
  * const bytes = TPSUID7RB.encodeBinary(tps);
@@ -418,6 +518,7 @@ export declare class TPSUID7RB {
418
518
  longitude?: number;
419
519
  altitude?: number;
420
520
  compress?: boolean;
521
+ order?: TimeOrder;
421
522
  }): string;
422
523
  /**
423
524
  * Generate a TPS string from a Date and optional location.
@@ -468,3 +569,61 @@ export declare class TPSUID7RB {
468
569
  /** Generate cryptographically secure random bytes */
469
570
  private static randomBytes;
470
571
  }
572
+ /**
573
+ * `TpsDate` is a Date-like wrapper with native TPS conversion helpers.
574
+ *
575
+ * It mirrors common JavaScript `Date` construction patterns:
576
+ * - `new TpsDate()`
577
+ * - `new TpsDate(ms)`
578
+ * - `new TpsDate(isoString)`
579
+ * - `new TpsDate(tpsString)`
580
+ * - `new TpsDate(year, monthIndex, day?, hour?, minute?, second?, ms?)`
581
+ */
582
+ export declare class TpsDate {
583
+ private readonly internal;
584
+ private getTpsComponents;
585
+ private getTpsFullYear;
586
+ constructor();
587
+ constructor(value: string | number | Date | TpsDate);
588
+ constructor(year: number, monthIndex: number, day?: number, hours?: number, minutes?: number, seconds?: number, ms?: number);
589
+ private static looksLikeTPS;
590
+ static now(): number;
591
+ static parse(input: string): number;
592
+ static UTC(year: number, monthIndex: number, day?: number, hours?: number, minutes?: number, seconds?: number, ms?: number): number;
593
+ static fromTPS(tps: string): TpsDate;
594
+ toGregorianDate(): Date;
595
+ toDate(): Date;
596
+ toTPS(calendar?: string, opts?: {
597
+ order?: TimeOrder;
598
+ }): string;
599
+ toTPSURI(calendar?: string, opts?: {
600
+ order?: TimeOrder;
601
+ latitude?: number;
602
+ longitude?: number;
603
+ altitude?: number;
604
+ isUnknownLocation?: boolean;
605
+ isHiddenLocation?: boolean;
606
+ isRedactedLocation?: boolean;
607
+ }): string;
608
+ getTime(): number;
609
+ valueOf(): number;
610
+ toString(): string;
611
+ toISOString(): string;
612
+ toUTCString(): string;
613
+ toJSON(): string | null;
614
+ getFullYear(): number;
615
+ getUTCFullYear(): number;
616
+ getMonth(): number;
617
+ getUTCMonth(): number;
618
+ getDate(): number;
619
+ getUTCDate(): number;
620
+ getHours(): number;
621
+ getUTCHours(): number;
622
+ getMinutes(): number;
623
+ getUTCMinutes(): number;
624
+ getSeconds(): number;
625
+ getUTCSeconds(): number;
626
+ getMilliseconds(): number;
627
+ getUTCMilliseconds(): number;
628
+ [Symbol.toPrimitive](hint: string): string | number;
629
+ }