@provex/utils 1.0.16 → 1.2.3

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 (122) hide show
  1. package/dist/src/chain.d.ts +436 -4
  2. package/dist/src/chain.js +80 -0
  3. package/dist/src/chain.test.d.ts +1 -0
  4. package/dist/src/chain.test.js +112 -0
  5. package/dist/src/contracts.d.ts +196 -20
  6. package/dist/src/contracts.js +245 -17
  7. package/dist/src/contracts.test.d.ts +1 -0
  8. package/dist/src/contracts.test.js +243 -0
  9. package/dist/src/conversionRates.d.ts +99 -8
  10. package/dist/src/conversionRates.js +74 -4
  11. package/dist/src/conversionRates.test.d.ts +1 -0
  12. package/dist/src/conversionRates.test.js +473 -0
  13. package/dist/src/currencies.d.ts +113 -9
  14. package/dist/src/currencies.js +119 -38
  15. package/dist/src/currencies.test.d.ts +1 -0
  16. package/dist/src/currencies.test.js +343 -0
  17. package/dist/src/data/countries.json +166 -166
  18. package/dist/src/deposit.d.ts +69 -1
  19. package/dist/src/deposit.js +52 -1
  20. package/dist/src/depositKeys.d.ts +154 -0
  21. package/dist/src/depositKeys.js +104 -0
  22. package/dist/src/depositKeys.test.d.ts +1 -0
  23. package/dist/src/depositKeys.test.js +231 -0
  24. package/dist/src/endpoints.d.ts +51 -0
  25. package/dist/src/endpoints.js +70 -0
  26. package/dist/src/endpoints.test.d.ts +1 -0
  27. package/dist/src/endpoints.test.js +54 -0
  28. package/dist/src/events.d.ts +40 -2
  29. package/dist/src/events.js +86 -10
  30. package/dist/src/events.test.d.ts +1 -0
  31. package/dist/src/events.test.js +111 -0
  32. package/dist/src/fees.d.ts +136 -0
  33. package/dist/src/fees.js +178 -0
  34. package/dist/src/fees.test.d.ts +1 -0
  35. package/dist/src/fees.test.js +165 -0
  36. package/dist/src/ids.d.ts +125 -22
  37. package/dist/src/ids.js +211 -61
  38. package/dist/src/ids.test.d.ts +1 -0
  39. package/dist/src/ids.test.js +607 -0
  40. package/dist/src/index.d.ts +30 -1
  41. package/dist/src/index.js +30 -1
  42. package/dist/src/input.d.ts +23 -4
  43. package/dist/src/input.js +23 -4
  44. package/dist/src/intent.d.ts +38 -2
  45. package/dist/src/intent.js +28 -1
  46. package/dist/src/intent.test.d.ts +1 -0
  47. package/dist/src/intent.test.js +119 -0
  48. package/dist/src/json.d.ts +38 -1
  49. package/dist/src/json.js +38 -2
  50. package/dist/src/normalization.d.ts +224 -0
  51. package/dist/src/normalization.js +119 -0
  52. package/dist/src/normalization.test.d.ts +1 -0
  53. package/dist/src/normalization.test.js +284 -0
  54. package/dist/src/participants.d.ts +19 -4
  55. package/dist/src/participants.js +19 -4
  56. package/dist/src/payment.d.ts +333 -16
  57. package/dist/src/payment.js +768 -58
  58. package/dist/src/payment.test.d.ts +1 -0
  59. package/dist/src/payment.test.js +272 -0
  60. package/dist/src/peer-types.d.ts +327 -0
  61. package/dist/src/peer-types.js +169 -0
  62. package/dist/src/profit.d.ts +26 -5
  63. package/dist/src/profit.js +31 -8
  64. package/dist/src/profit.test.d.ts +1 -0
  65. package/dist/src/profit.test.js +315 -0
  66. package/dist/src/reputation.d.ts +125 -0
  67. package/dist/src/reputation.js +188 -0
  68. package/dist/src/reputation.test.d.ts +1 -0
  69. package/dist/src/reputation.test.js +156 -0
  70. package/dist/src/sort.d.ts +49 -10
  71. package/dist/src/sort.js +40 -9
  72. package/dist/src/sort.test.d.ts +1 -0
  73. package/dist/src/sort.test.js +216 -0
  74. package/dist/src/stateKey.d.ts +35 -0
  75. package/dist/src/stateKey.js +36 -0
  76. package/dist/src/stats.d.ts +55 -1
  77. package/dist/src/stats.js +46 -1
  78. package/dist/src/stats.test.d.ts +1 -0
  79. package/dist/src/stats.test.js +104 -0
  80. package/dist/src/time.d.ts +59 -9
  81. package/dist/src/time.js +71 -15
  82. package/dist/src/time.test.d.ts +1 -0
  83. package/dist/src/time.test.js +231 -0
  84. package/dist/src/tokens.d.ts +11972 -145
  85. package/dist/src/tokens.js +98 -17
  86. package/dist/src/tokens.test.d.ts +1 -0
  87. package/dist/src/tokens.test.js +193 -0
  88. package/dist/src/units.d.ts +183 -0
  89. package/dist/src/units.js +206 -6
  90. package/dist/src/units.test.d.ts +1 -0
  91. package/dist/src/units.test.js +327 -0
  92. package/dist/src/zkp2p-types.d.ts +273 -4
  93. package/dist/src/zkp2p-types.js +169 -1
  94. package/dist/tsconfig.tsbuildinfo +1 -1
  95. package/package.json +116 -26
  96. package/scripts/convert-svg.ts +0 -22
  97. package/src/chain.ts +0 -27
  98. package/src/contracts.ts +0 -89
  99. package/src/conversionRates.ts +0 -356
  100. package/src/currencies.ts +0 -286
  101. package/src/data/countries.json +0 -1099
  102. package/src/deposit.ts +0 -2
  103. package/src/events.ts +0 -21
  104. package/src/flags/eur.svg +0 -4
  105. package/src/flags/usd.svg +0 -25
  106. package/src/flags.ts +0 -4
  107. package/src/global.d.ts +0 -9
  108. package/src/ids.ts +0 -137
  109. package/src/index.ts +0 -16
  110. package/src/input.ts +0 -35
  111. package/src/intent.ts +0 -15
  112. package/src/json.ts +0 -42
  113. package/src/participants.ts +0 -14
  114. package/src/payment.ts +0 -573
  115. package/src/profit.ts +0 -55
  116. package/src/sort.ts +0 -49
  117. package/src/stats.ts +0 -10
  118. package/src/time.ts +0 -123
  119. package/src/tokens.ts +0 -159
  120. package/src/units.ts +0 -120
  121. package/src/zkp2p-types.ts +0 -55
  122. package/tsconfig.json +0 -18
package/dist/src/time.js CHANGED
@@ -1,4 +1,18 @@
1
- /** Interval in milliseconds */
1
+ /**
2
+ * @fileoverview Time and date utilities for formatting and calculations.
3
+ *
4
+ * Provides:
5
+ * - Interval constants in milliseconds for time calculations
6
+ * - Human-readable relative time formatting ("5m ago", "2d 3h ago")
7
+ * - Duration formatting for time ranges
8
+ * - Absolute timestamp formatting
9
+ *
10
+ * @see {@link units} for blockchain timestamp conversion
11
+ */
12
+ /**
13
+ * Time unit relationships for manual calculations.
14
+ * Use these when building complex time expressions.
15
+ */
2
16
  export const intervalIn = {
3
17
  yearInDays: 365,
4
18
  quarterInMonths: 3,
@@ -15,7 +29,19 @@ const hour = intervalIn.minuteInHours * minute;
15
29
  const day = intervalIn.hourInDays * hour;
16
30
  const month = intervalIn.monthInDays * day;
17
31
  const year = intervalIn.yearInDays * month;
18
- /** Intervals in milliseconds */
32
+ /**
33
+ * Common time intervals in milliseconds.
34
+ * Use for timeout calculations, polling intervals, and date math.
35
+ *
36
+ * @example
37
+ * ```ts
38
+ * // Set a 5 minute timeout
39
+ * setTimeout(callback, 5 * interval.minute)
40
+ *
41
+ * // Calculate time 1 day ago
42
+ * const yesterday = Date.now() - interval.day
43
+ * ```
44
+ */
19
45
  export const interval = {
20
46
  second,
21
47
  minute,
@@ -24,26 +50,36 @@ export const interval = {
24
50
  month,
25
51
  year,
26
52
  };
27
- /** Default display intervals */
53
+ /**
54
+ * Default number of time units to display in statistics/charts.
55
+ * Used for "show last N hours/days/months" UI controls.
56
+ */
28
57
  export const defaultDisplayInterval = {
29
58
  hour: 7 * 24,
30
59
  day: 6 * 30,
31
60
  month: 60,
32
61
  };
33
62
  /**
34
- * Format a timestamp
35
- * @param timestamp - The timestamp to format
36
- * @param param1.anchor - The anchor date
37
- * @param param1.showSeconds - Whether to show seconds
38
- * @returns The formatted timestamp
63
+ * Format a timestamp as a human-readable relative time string.
64
+ * Produces compact strings like "5m ago", "2h 30m ago", "3d ago".
65
+ *
66
+ * @param timestamp - The timestamp to format (Date, number in ms, or date string)
67
+ * @param options - Optional configuration
68
+ * @param options.anchor - Reference date for "ago" calculation (default: now)
69
+ * @param options.showSeconds - Whether to show seconds for very recent times
70
+ * @returns Human-readable relative time string
71
+ *
72
+ * @example
73
+ * ```ts
74
+ * formatTimestamp(Date.now() - 5 * 60 * 1000) // "5m ago"
75
+ * formatTimestamp(Date.now() - 2.5 * 60 * 60 * 1000) // "2h 30m ago"
76
+ * formatTimestamp(Date.now() - 3 * 24 * 60 * 60 * 1000) // "3d 0h ago"
77
+ * ```
39
78
  */
40
- export const formatTimestamp = (timestamp, { anchor = new Date(), showSeconds = false, } = {}) => {
41
- const date = new Date(timestamp);
42
- const diffMs = anchor.getTime() - date.getTime();
43
- const diffMins = Math.floor(diffMs / interval.minute);
44
- const diffHours = Math.floor(diffMs / interval.hour);
45
- const diffDays = Math.floor(diffMs / interval.day);
46
- const diffMonths = Math.floor(diffDays / interval.month);
79
+ export const formatTimestamp = (timestamp, options) => {
80
+ const anchor = options?.anchor ?? new Date(), showSeconds = options?.showSeconds ?? false, date = new Date(timestamp);
81
+ const diffMs = anchor.getTime() - date.getTime(), diffMins = Math.floor(diffMs / interval.minute), diffHours = Math.floor(diffMs / interval.hour);
82
+ const diffDays = Math.floor(diffMs / interval.day), diffMonths = Math.floor(diffDays / intervalIn.monthInDays);
47
83
  if (diffMonths > 0) {
48
84
  if (diffMonths < intervalIn.quarterInMonths) {
49
85
  return `${diffMonths}mo ${diffDays % intervalIn.monthInDays}d ago`;
@@ -98,6 +134,26 @@ export const formatDuration = ({ start = new Date(), until = new Date(), } = {})
98
134
  }
99
135
  return `${diffMins % intervalIn.minuteInHours}m`;
100
136
  };
137
+ /**
138
+ * Format an absolute timestamp to a human-readable string
139
+ * @param timestamp - Unix timestamp in seconds or milliseconds (auto-detected)
140
+ * @param options - Intl.DateTimeFormatOptions for formatting
141
+ * @returns Formatted absolute timestamp string
142
+ */
143
+ export const formatAbsoluteTimestamp = (timestamp, options) => {
144
+ // Auto-detect if timestamp is in seconds or milliseconds
145
+ // Timestamps > 10 billion are assumed to be in milliseconds (year 2286+ if seconds)
146
+ const timestampMs = Number(timestamp) > 10000000000 ? Number(timestamp) : Number(timestamp) * 1000;
147
+ const date = new Date(timestampMs);
148
+ return date.toLocaleString(undefined, options ?? {
149
+ year: 'numeric',
150
+ month: 'short',
151
+ day: 'numeric',
152
+ hour: '2-digit',
153
+ minute: '2-digit',
154
+ second: '2-digit'
155
+ });
156
+ };
101
157
  /**
102
158
  * Sleep for a given number of milliseconds
103
159
  * @param ms - The number of milliseconds to sleep
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,231 @@
1
+ import { describe, it } from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import { interval, intervalIn, formatTimestamp, formatDuration, formatAbsoluteTimestamp, sleep, defaultDisplayInterval, } from './time.js';
4
+ describe('time', () => {
5
+ describe('formatTimestamp', () => {
6
+ const anchor = new Date('2025-01-05T12:00:00Z');
7
+ it('should return "Just now" for very recent timestamps', () => {
8
+ const recent = new Date(anchor.getTime() - 5 * 1000); // 5 seconds ago
9
+ assert.equal(formatTimestamp(recent, { anchor }), 'Just now');
10
+ });
11
+ it('should show seconds when enabled', () => {
12
+ const recent = new Date(anchor.getTime() - 30 * 1000); // 30 seconds ago
13
+ assert.equal(formatTimestamp(recent, { anchor, showSeconds: true }), '30s ago');
14
+ });
15
+ it('should format minutes correctly', () => {
16
+ const mins = new Date(anchor.getTime() - 15 * 60 * 1000); // 15 minutes ago
17
+ assert.equal(formatTimestamp(mins, { anchor }), '15m ago');
18
+ });
19
+ it('should format hours with minutes for recent hours', () => {
20
+ const hours = new Date(anchor.getTime() - 3 * 60 * 60 * 1000 - 30 * 60 * 1000); // 3h 30m ago
21
+ assert.equal(formatTimestamp(hours, { anchor }), '3h 30m ago');
22
+ });
23
+ it('should format hours only for older hours', () => {
24
+ const hours = new Date(anchor.getTime() - 8 * 60 * 60 * 1000); // 8 hours ago
25
+ assert.equal(formatTimestamp(hours, { anchor }), '8h ago');
26
+ });
27
+ it('should format days with hours for recent days', () => {
28
+ const days = new Date(anchor.getTime() - 2 * 24 * 60 * 60 * 1000 - 5 * 60 * 60 * 1000); // 2d 5h ago
29
+ assert.equal(formatTimestamp(days, { anchor }), '2d 5h ago');
30
+ });
31
+ it('should format days only for older days', () => {
32
+ const days = new Date(anchor.getTime() - 10 * 24 * 60 * 60 * 1000); // 10 days ago
33
+ assert.equal(formatTimestamp(days, { anchor }), '10d ago');
34
+ });
35
+ it('should format months with days for recent months', () => {
36
+ const twoMonthsAgo = new Date(anchor.getTime() - 60 * 24 * 60 * 60 * 1000); // 60 days = 2 months
37
+ const result = formatTimestamp(twoMonthsAgo, { anchor });
38
+ // 2 months is less than a quarter, so shows "2mo 0d ago"
39
+ assert.equal(result, '2mo 0d ago');
40
+ });
41
+ it('should format months only for older months', () => {
42
+ const fourMonthsAgo = new Date(anchor.getTime() - 120 * 24 * 60 * 60 * 1000); // 120 days = 4 months
43
+ const result = formatTimestamp(fourMonthsAgo, { anchor });
44
+ // 4 months is >= a quarter (3 months), so shows just "4mo ago"
45
+ assert.equal(result, '4mo ago');
46
+ });
47
+ it('should handle Date objects', () => {
48
+ const date = new Date(anchor.getTime() - 5 * 60 * 1000);
49
+ assert.equal(formatTimestamp(date, { anchor }), '5m ago');
50
+ });
51
+ it('should handle timestamp numbers', () => {
52
+ const timestamp = anchor.getTime() - 5 * 60 * 1000;
53
+ assert.equal(formatTimestamp(timestamp, { anchor }), '5m ago');
54
+ });
55
+ it('should handle ISO strings', () => {
56
+ const isoString = new Date(anchor.getTime() - 5 * 60 * 1000).toISOString();
57
+ assert.equal(formatTimestamp(isoString, { anchor }), '5m ago');
58
+ });
59
+ });
60
+ describe('formatDuration', () => {
61
+ it('should format minute durations', () => {
62
+ const start = new Date('2025-01-05T12:00:00Z');
63
+ const until = new Date('2025-01-05T12:15:00Z');
64
+ assert.equal(formatDuration({ start, until }), '15m');
65
+ });
66
+ it('should format hour durations with minutes', () => {
67
+ const start = new Date('2025-01-05T12:00:00Z');
68
+ const until = new Date('2025-01-05T15:30:00Z');
69
+ assert.equal(formatDuration({ start, until }), '3h 30m');
70
+ });
71
+ it('should format day durations with hours', () => {
72
+ const start = new Date('2025-01-05T12:00:00Z');
73
+ const until = new Date('2025-01-07T18:00:00Z');
74
+ assert.equal(formatDuration({ start, until }), '2d 6h');
75
+ });
76
+ it('should format month durations with days', () => {
77
+ const start = new Date('2025-01-05T12:00:00Z');
78
+ const until = new Date('2025-02-20T12:00:00Z');
79
+ const result = formatDuration({ start, until });
80
+ assert.ok(result.includes('mo'));
81
+ assert.ok(result.includes('d'));
82
+ });
83
+ it('should handle zero duration', () => {
84
+ const date = new Date('2025-01-05T12:00:00Z');
85
+ assert.equal(formatDuration({ start: date, until: date }), '0m');
86
+ });
87
+ it('should default to current time if no dates provided', () => {
88
+ const result = formatDuration();
89
+ assert.equal(result, '0m');
90
+ });
91
+ it('should handle only start date', () => {
92
+ const start = new Date(Date.now() - 5 * 60 * 1000);
93
+ const result = formatDuration({ start });
94
+ assert.ok(result.includes('m'));
95
+ });
96
+ it('should handle only until date', () => {
97
+ const until = new Date(Date.now() + 5 * 60 * 1000);
98
+ const result = formatDuration({ until });
99
+ assert.ok(result.includes('m'));
100
+ });
101
+ });
102
+ describe('sleep', () => {
103
+ it('should resolve after specified milliseconds', async () => {
104
+ const start = Date.now();
105
+ await sleep(100);
106
+ const elapsed = Date.now() - start;
107
+ assert.ok(elapsed >= 100, `Expected at least 100ms, got ${elapsed}ms`);
108
+ // Allow generous upper bound for CI environments with high load
109
+ assert.ok(elapsed < 1000, `Expected less than 1000ms, got ${elapsed}ms`);
110
+ });
111
+ it('should return a promise', () => {
112
+ const result = sleep(1);
113
+ assert.ok(result instanceof Promise);
114
+ });
115
+ it('should resolve immediately for 0ms', async () => {
116
+ const start = Date.now();
117
+ await sleep(0);
118
+ const elapsed = Date.now() - start;
119
+ assert.ok(elapsed < 10, `Expected less than 10ms, got ${elapsed}ms`);
120
+ });
121
+ });
122
+ describe('formatAbsoluteTimestamp', () => {
123
+ it('should format timestamp in seconds', () => {
124
+ // Unix timestamp for 2024-01-01 00:00:00 UTC
125
+ const timestamp = 1704067200;
126
+ const result = formatAbsoluteTimestamp(timestamp);
127
+ // Result format varies by timezone, just check it's a valid date string
128
+ assert.ok(result.length > 0);
129
+ assert.ok(typeof result === 'string');
130
+ });
131
+ it('should format timestamp in milliseconds', () => {
132
+ // Unix timestamp in ms for 2024-01-01 00:00:00 UTC
133
+ const timestamp = 1704067200000;
134
+ const result = formatAbsoluteTimestamp(timestamp);
135
+ assert.ok(result.length > 0);
136
+ assert.ok(typeof result === 'string');
137
+ });
138
+ it('should handle bigint timestamps', () => {
139
+ const timestamp = 1704067200n;
140
+ const result = formatAbsoluteTimestamp(timestamp);
141
+ assert.ok(result.length > 0);
142
+ });
143
+ it('should accept custom format options', () => {
144
+ const timestamp = 1704067200;
145
+ const result = formatAbsoluteTimestamp(timestamp, {
146
+ year: 'numeric',
147
+ month: 'numeric',
148
+ day: 'numeric',
149
+ timeZone: 'UTC', // Use UTC to get consistent results
150
+ });
151
+ assert.ok(result.includes('2024') || result.includes('1/1')); // Different locales format differently
152
+ });
153
+ it('should auto-detect milliseconds for large numbers', () => {
154
+ // Timestamp > 10 billion should be treated as milliseconds
155
+ const timestampMs = 1704067200000;
156
+ const timestampSec = 1704067200;
157
+ const resultMs = formatAbsoluteTimestamp(timestampMs);
158
+ const resultSec = formatAbsoluteTimestamp(timestampSec);
159
+ // Both should produce the same date
160
+ assert.equal(resultMs, resultSec);
161
+ });
162
+ });
163
+ describe('interval constants', () => {
164
+ it('should have correct second value', () => {
165
+ assert.equal(interval.second, 1000);
166
+ });
167
+ it('should have correct minute value', () => {
168
+ assert.equal(interval.minute, 60 * 1000);
169
+ });
170
+ it('should have correct hour value', () => {
171
+ assert.equal(interval.hour, 60 * 60 * 1000);
172
+ });
173
+ it('should have correct day value', () => {
174
+ assert.equal(interval.day, 24 * 60 * 60 * 1000);
175
+ });
176
+ });
177
+ describe('intervalIn constants', () => {
178
+ it('should have correct values', () => {
179
+ assert.equal(intervalIn.yearInDays, 365);
180
+ assert.equal(intervalIn.quarterInMonths, 3);
181
+ assert.equal(intervalIn.monthInDays, 30);
182
+ assert.equal(intervalIn.hourInDays, 24);
183
+ assert.equal(intervalIn.daysInWeek, 7);
184
+ assert.equal(intervalIn.minuteInHours, 60);
185
+ assert.equal(intervalIn.secondInMinutes, 60);
186
+ assert.equal(intervalIn.millisecondInSecond, 1000);
187
+ });
188
+ });
189
+ describe('defaultDisplayInterval', () => {
190
+ it('should have correct default values', () => {
191
+ assert.equal(defaultDisplayInterval.hour, 7 * 24);
192
+ assert.equal(defaultDisplayInterval.day, 6 * 30);
193
+ assert.equal(defaultDisplayInterval.month, 60);
194
+ });
195
+ });
196
+ describe('formatTimestamp edge cases', () => {
197
+ const anchor = new Date('2025-01-05T12:00:00Z');
198
+ it('should show "Just now" for showSeconds with very recent timestamp', () => {
199
+ const recent = new Date(anchor.getTime() - 5 * 1000); // 5 seconds ago
200
+ assert.equal(formatTimestamp(recent, { anchor, showSeconds: true }), 'Just now');
201
+ });
202
+ it('should show seconds for 10-59 seconds ago', () => {
203
+ const recent = new Date(anchor.getTime() - 15 * 1000); // 15 seconds ago
204
+ const result = formatTimestamp(recent, { anchor, showSeconds: true });
205
+ assert.equal(result, '15s ago');
206
+ });
207
+ it('should use default anchor and showSeconds when no options provided', () => {
208
+ // Test calling with no options object to cover default parameter initialization
209
+ const recent = new Date(Date.now() - 5 * 60 * 1000); // 5 minutes ago
210
+ const result = formatTimestamp(recent);
211
+ assert.ok(result.includes('m ago'));
212
+ });
213
+ it('should use defaults when empty options object provided', () => {
214
+ // Test calling with empty options to cover default parameter values
215
+ const recent = new Date(Date.now() - 10 * 60 * 1000); // 10 minutes ago
216
+ const result = formatTimestamp(recent, {});
217
+ assert.ok(result.includes('m ago'));
218
+ });
219
+ it('should use default anchor when only showSeconds provided', () => {
220
+ const recent = new Date(Date.now() - 30 * 1000); // 30 seconds ago
221
+ const result = formatTimestamp(recent, { showSeconds: true });
222
+ assert.ok(result.includes('s ago'));
223
+ });
224
+ it('should use default showSeconds when only anchor provided', () => {
225
+ const anchor = new Date('2025-01-05T12:00:00Z');
226
+ const recent = new Date(anchor.getTime() - 5 * 1000); // 5 seconds ago
227
+ const result = formatTimestamp(recent, { anchor });
228
+ assert.equal(result, 'Just now'); // showSeconds defaults to false
229
+ });
230
+ });
231
+ });