@nextera.one/tps-standard 0.5.3 → 0.5.34

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.
Files changed (57) hide show
  1. package/dist/date.d.ts +54 -0
  2. package/dist/date.js +174 -0
  3. package/dist/date.js.map +1 -0
  4. package/dist/drivers/gregorian.d.ts +3 -5
  5. package/dist/drivers/gregorian.js +26 -19
  6. package/dist/drivers/gregorian.js.map +1 -1
  7. package/dist/drivers/hijri.d.ts +1 -16
  8. package/dist/drivers/hijri.js +9 -102
  9. package/dist/drivers/hijri.js.map +1 -1
  10. package/dist/drivers/holocene.d.ts +6 -3
  11. package/dist/drivers/holocene.js +7 -20
  12. package/dist/drivers/holocene.js.map +1 -1
  13. package/dist/drivers/julian.d.ts +3 -10
  14. package/dist/drivers/julian.js +11 -71
  15. package/dist/drivers/julian.js.map +1 -1
  16. package/dist/drivers/persian.d.ts +1 -6
  17. package/dist/drivers/persian.js +17 -92
  18. package/dist/drivers/persian.js.map +1 -1
  19. package/dist/drivers/tps.d.ts +11 -28
  20. package/dist/drivers/tps.js +8 -58
  21. package/dist/drivers/tps.js.map +1 -1
  22. package/dist/drivers/unix.d.ts +5 -6
  23. package/dist/drivers/unix.js +10 -32
  24. package/dist/drivers/unix.js.map +1 -1
  25. package/dist/index.d.ts +6 -477
  26. package/dist/index.js +33 -978
  27. package/dist/index.js.map +1 -1
  28. package/dist/types.d.ts +85 -0
  29. package/dist/types.js +30 -0
  30. package/dist/types.js.map +1 -0
  31. package/dist/uid.d.ts +48 -0
  32. package/dist/uid.js +225 -0
  33. package/dist/uid.js.map +1 -0
  34. package/dist/utils/calendar.d.ts +55 -0
  35. package/dist/utils/calendar.js +136 -0
  36. package/dist/utils/calendar.js.map +1 -0
  37. package/dist/utils/env.d.ts +12 -0
  38. package/dist/utils/env.js +79 -0
  39. package/dist/utils/env.js.map +1 -0
  40. package/dist/utils/tps-string.d.ts +12 -0
  41. package/dist/utils/tps-string.js +164 -0
  42. package/dist/utils/tps-string.js.map +1 -0
  43. package/package.json +1 -1
  44. package/src/date.ts +243 -0
  45. package/src/drivers/gregorian.ts +29 -27
  46. package/src/drivers/hijri.ts +13 -113
  47. package/src/drivers/holocene.ts +11 -12
  48. package/src/drivers/julian.ts +18 -72
  49. package/src/drivers/persian.ts +25 -92
  50. package/src/drivers/tps.ts +16 -55
  51. package/src/drivers/unix.ts +12 -33
  52. package/src/index.ts +18 -1446
  53. package/src/types.ts +107 -0
  54. package/src/uid.ts +308 -0
  55. package/src/utils/calendar.ts +161 -0
  56. package/src/utils/env.ts +88 -0
  57. package/src/utils/tps-string.ts +166 -0
@@ -0,0 +1,166 @@
1
+ import { TPSComponents, TimeOrder, DefaultCalendars } from "../types";
2
+
3
+ /**
4
+ * Generate the canonical `T:` time string for a set of components.
5
+ */
6
+ export function buildTimePart(comp: TPSComponents): string {
7
+ const calendar = (comp.calendar || "").toLowerCase();
8
+ if (!/^[a-z]{3,4}$/.test(calendar)) {
9
+ throw new Error(
10
+ `Invalid calendar code '${comp.calendar}'. Calendar code width must be 3–4 lowercase letters.`,
11
+ );
12
+ }
13
+
14
+ let time = `T:${calendar}`;
15
+ if (calendar === DefaultCalendars.UNIX) {
16
+ if (comp.unixSeconds !== undefined) {
17
+ time += `.s${comp.unixSeconds}`;
18
+ }
19
+ return time;
20
+ }
21
+
22
+ const tokens: Array<[string, number | undefined, number]> = [
23
+ ["m", comp.millennium, 8],
24
+ ["c", comp.century, 7],
25
+ ["y", comp.year, 6],
26
+ ["m", comp.month, 5],
27
+ ["d", comp.day, 4],
28
+ ["h", comp.hour, 3],
29
+ ["m", comp.minute, 2],
30
+ ["s", comp.second, 1],
31
+ ["m", comp.millisecond, 0],
32
+ ];
33
+
34
+ const order: TimeOrder = comp.order || TimeOrder.DESC;
35
+ const activeTokens = order === TimeOrder.ASC ? [...tokens].reverse() : tokens;
36
+
37
+ for (const [pref, val] of activeTokens) {
38
+ if (val !== undefined) {
39
+ time += `.${pref}${val}`;
40
+ }
41
+ }
42
+
43
+ if (comp.signature) {
44
+ time += `!${comp.signature}`;
45
+ }
46
+
47
+ return time;
48
+ }
49
+
50
+ /**
51
+ * Parse the time portion of a TPS string into components.
52
+ */
53
+ export function parseTimeString(
54
+ input: string,
55
+ ): { components: Partial<TPSComponents>; order: TimeOrder } | null {
56
+ let s = input.trim();
57
+ s = s.split(/[!;?#]/)[0];
58
+ if (s.startsWith("T:")) s = s.slice(2);
59
+ const parts = s.split(".");
60
+ if (parts.length === 0) return null;
61
+ const calendar = parts[0];
62
+ const comp: Partial<TPSComponents> = { calendar };
63
+
64
+ const fixedRankMap: Record<string, number> = {
65
+ c: 7,
66
+ y: 6,
67
+ d: 4,
68
+ h: 3,
69
+ s: 1,
70
+ };
71
+
72
+ let initialOrder: TimeOrder = TimeOrder.DESC;
73
+ if (calendar !== DefaultCalendars.UNIX) {
74
+ const nonMRanks: number[] = [];
75
+ for (let i = 1; i < parts.length; i++) {
76
+ const pr = parts[i]?.charAt(0);
77
+ if (pr && pr in fixedRankMap) nonMRanks.push(fixedRankMap[pr]);
78
+ }
79
+ if (nonMRanks.length >= 2) {
80
+ const isAsc = nonMRanks.every((v, i, a) => i === 0 || a[i - 1] <= v);
81
+ if (isAsc) initialOrder = TimeOrder.ASC;
82
+ }
83
+ }
84
+
85
+ const assignMRank = (lastRank: number | null, ord: TimeOrder): number => {
86
+ if (ord === TimeOrder.DESC) {
87
+ if (lastRank === null) return 8;
88
+ if (lastRank > 5) return 5;
89
+ if (lastRank > 2) return 2;
90
+ return 0;
91
+ } else {
92
+ if (lastRank === null) return 0;
93
+ if (lastRank < 2) return 2;
94
+ if (lastRank < 5) return 5;
95
+ return 8;
96
+ }
97
+ };
98
+
99
+ const ranks: number[] = [];
100
+ let lastAssignedRank: number | null = null;
101
+
102
+ for (let i = 1; i < parts.length; i++) {
103
+ const token = parts[i];
104
+ if (!token) continue;
105
+ const prefix = token.charAt(0);
106
+ const value = token.slice(1);
107
+
108
+ if (calendar === DefaultCalendars.UNIX && prefix === "s") {
109
+ comp.unixSeconds = parseFloat(value);
110
+ ranks.push(9);
111
+ continue;
112
+ }
113
+
114
+ if (prefix === "m") {
115
+ const rank = assignMRank(lastAssignedRank, initialOrder);
116
+ switch (rank) {
117
+ case 8:
118
+ comp.millennium = parseInt(value, 10);
119
+ break;
120
+ case 5:
121
+ comp.month = parseInt(value, 10);
122
+ break;
123
+ case 2:
124
+ comp.minute = parseInt(value, 10);
125
+ break;
126
+ case 0:
127
+ comp.millisecond = parseInt(value, 10);
128
+ break;
129
+ }
130
+ ranks.push(rank);
131
+ lastAssignedRank = rank;
132
+ } else {
133
+ const rank = fixedRankMap[prefix];
134
+ if (rank !== undefined) {
135
+ switch (prefix) {
136
+ case "c":
137
+ comp.century = parseInt(value, 10);
138
+ break;
139
+ case "y":
140
+ comp.year = parseInt(value, 10);
141
+ break;
142
+ case "d":
143
+ comp.day = parseInt(value, 10);
144
+ break;
145
+ case "h":
146
+ comp.hour = parseInt(value, 10);
147
+ break;
148
+ case "s":
149
+ comp.second = parseFloat(value);
150
+ break;
151
+ }
152
+ ranks.push(rank);
153
+ lastAssignedRank = rank;
154
+ }
155
+ }
156
+ }
157
+
158
+ let order: TimeOrder = TimeOrder.DESC;
159
+ if (ranks.length > 1) {
160
+ const isAsc = ranks.every((v, i, a) => i === 0 || a[i - 1] <= v);
161
+ const isDesc = ranks.every((v, i, a) => i === 0 || a[i - 1] >= v);
162
+ if (isAsc && !isDesc) order = TimeOrder.ASC;
163
+ }
164
+
165
+ return { components: comp, order };
166
+ }