@reykjavik/webtools 0.2.10 → 0.3.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/CHANGELOG.md CHANGED
@@ -4,14 +4,17 @@
4
4
 
5
5
  - ... <!-- Add new lines here. -->
6
6
 
7
- ## 0.2.10
7
+ ## 0.3.0
8
8
 
9
- _2025-09-30_
9
+ _2025-11-10_
10
10
 
11
- - `@reykjavik/webtools/next/vanillaExtract`:
12
- - fix: Remove stray side-effect invocation of `vanillaClass` on import
11
+ - `@reykjavik/webtools/http`:
12
+ - **BREAKING** feat: `toMs()` now treats raw numbers as milliseconds (not as
13
+ seconds)
14
+ - `@reykjavik/webtools/errorhandling`:
15
+ - feat: Alias `Result.catch()` as `Result.ify()` for readability
13
16
 
14
- ## 0.2.9
17
+ ## 0.2.9 – 0.2.10
15
18
 
16
19
  _2025-09-30_
17
20
 
package/README.md CHANGED
@@ -41,6 +41,7 @@ bun add @reykjavik/webtools
41
41
  - [Type `ResultTupleObj`](#type-resulttupleobj)
42
42
  - [Type `ResultTupleObj.mapTo`](#type-resulttupleobjmapto)
43
43
  - [`Result.catch`](#resultcatch)
44
+ - [`Result.ify`](#resultify)
44
45
  - [`Result.map`](#resultmap)
45
46
  - [`Result.Success`](#resultsuccess)
46
47
  - [`Result.Fail`](#resultfail)
@@ -230,7 +231,11 @@ import type { toSec, TTL } from '@reykjavik/webtools/http';
230
231
 
231
232
  const ttl: TTL = '2h';
232
233
 
233
- const ttlSec = toSec(ttl);
234
+ const ttlSec1 = toSec(ttl); // 7200
235
+ // Raw numbers are returned as-is (rounded)
236
+ const ttlSec2 = toSec(10.6); // 11
237
+ // Negative numbers become zero
238
+ const ttlSec3 = toSec('-1h'); // 0
234
239
  ```
235
240
 
236
241
  ### `toMs` duration helper
@@ -246,7 +251,11 @@ import type { toMs, TTL } from '@reykjavik/webtools/http';
246
251
 
247
252
  const ttl: TTL = '2h';
248
253
 
249
- const ttlSec = toMs(ttl);
254
+ const ttlMs1 = toMs(ttl); // 7_200_000
255
+ // Raw numbers are returned as-is (rounded)
256
+ const ttlMs2 = toMs(499.9); // 500
257
+ // Negative numbers become zero
258
+ const ttlMs3 = toMs('-1h'); // 0
250
259
  ```
251
260
 
252
261
  ---
@@ -711,6 +720,8 @@ failed `ResultTupleObj`.
711
720
 
712
721
  ### `Result.catch`
713
722
 
723
+ Aliased as `Result.ify` for readability.
724
+
714
725
  **Syntax:**
715
726
  `Result.catch<T, Err>(callback: () => T): ResultTupleObj<T, Err>`
716
727
  **Syntax:**
@@ -744,14 +755,19 @@ fooQuery.result; // Guaranteed to be defined
744
755
 
745
756
  This function acts as the inverse of [`Result.throw()`](#resultthrow).
746
757
 
758
+ ### `Result.ify`
759
+
760
+ Syntatic sugar alias of [`Result.catch`](#resultcatch).
761
+
747
762
  ### `Result.map`
748
763
 
749
764
  **Syntax:**
750
765
  `Result.map<T, T2, E>(result: ResultTuple<T, E>, mapResult: (resultValue: T) => T2): ResultTuple<T2, E>`
751
766
 
752
- Helper to map a `ResultTuple`-like object to a new `ResultTupleObj` object,
753
- applying a transformation function to the result, but retaining the error
754
- as-is.
767
+ Convenience helper to map a `ResultTuple`-like object to a new
768
+ `ResultTupleObj` object, applying a transformation function to the result, but
769
+ retaining the error as-is. Errors thrown from the mapping function are caught
770
+ and turned into a failed `ResultTupleObj`.
755
771
 
756
772
  ```ts
757
773
  import { Result } from '@reykjavik/webtools/errorhandling';
@@ -84,6 +84,7 @@ export declare const Result: {
84
84
  */
85
85
  Fail: <E extends Error = Error>(e: unknown) => FailResult<E>;
86
86
  catch: typeof catch_;
87
+ ify: typeof catch_;
87
88
  /**
88
89
  * Helper to map a `ResultTuple`-like object to a new `ResultTupleObj`
89
90
  * object, applying a transformation function to the result, but retaining
package/errorhandling.js CHANGED
@@ -96,6 +96,7 @@ exports.Result = {
96
96
  Fail,
97
97
  // NOTE: The JSDoc must be placed above the `catch_` function above.
98
98
  catch: catch_,
99
+ ify: catch_,
99
100
  /**
100
101
  * Helper to map a `ResultTuple`-like object to a new `ResultTupleObj`
101
102
  * object, applying a transformation function to the result, but retaining
@@ -84,6 +84,7 @@ export declare const Result: {
84
84
  */
85
85
  Fail: <E extends Error = Error>(e: unknown) => FailResult<E>;
86
86
  catch: typeof catch_;
87
+ ify: typeof catch_;
87
88
  /**
88
89
  * Helper to map a `ResultTuple`-like object to a new `ResultTupleObj`
89
90
  * object, applying a transformation function to the result, but retaining
@@ -91,6 +91,7 @@ export const Result = {
91
91
  Fail,
92
92
  // NOTE: The JSDoc must be placed above the `catch_` function above.
93
93
  catch: catch_,
94
+ ify: catch_,
94
95
  /**
95
96
  * Helper to map a `ResultTuple`-like object to a new `ResultTupleObj`
96
97
  * object, applying a transformation function to the result, but retaining
package/esm/http.d.ts CHANGED
@@ -157,13 +157,6 @@ type TTLObj = {
157
157
  * @see https://github.com/reykjavikcity/webtools/blob/v0.2/README.md#type-ttlconfig
158
158
  */
159
159
  export type TTLConfig = TTL | TTLKeywords | TTLObj;
160
- /**
161
- * Converts a `TTL` (max-age) value into seconds. Returns `0` for bad and/or
162
- * negative input values.
163
- *
164
- * @see https://github.com/reykjavikcity/webtools/blob/v0.2/README.md#tosec-ttl-helper
165
- */
166
- export declare const toSec: (ttl: TTL) => number;
167
160
  /**
168
161
  * Converts a `TTL` (duration) value into milliseconds. Returns `0` for bad
169
162
  * and/or negative input values.
@@ -171,6 +164,13 @@ export declare const toSec: (ttl: TTL) => number;
171
164
  * @see https://github.com/reykjavikcity/webtools/blob/v0.2/README.md#toms-duration-helper
172
165
  */
173
166
  export declare const toMs: (ttl: TTL) => number;
167
+ /**
168
+ * Converts a `TTL` (max-age) value into seconds. Returns `0` for bad and/or
169
+ * negative input values.
170
+ *
171
+ * @see https://github.com/reykjavikcity/webtools/blob/v0.2/README.md#tosec-ttl-helper
172
+ */
173
+ export declare const toSec: (ttl: TTL) => number;
174
174
  type ServerResponseStub = Pick<ServerResponse, 'setHeader' | 'getHeader' | 'removeHeader'> & {
175
175
  headers?: Record<string, string | Array<string>>;
176
176
  };
package/esm/http.js CHANGED
@@ -125,36 +125,44 @@ export const HTTP_508_LoopDetected = 508;
125
125
  export const HTTP_510_NotExtended = 510;
126
126
  /** The client needs to authenticate to gain network access. */
127
127
  export const HTTP_511_NetworkAuthenticationRequired = 511;
128
- const unitToSeconds = {
129
- s: 1,
130
- m: 60,
131
- h: 3600,
132
- d: 24 * 3600,
133
- w: 7 * 24 * 3600,
128
+ const unitToMilliseconds = {
129
+ s: 1000,
130
+ m: 60000,
131
+ h: 60 * 60000,
132
+ d: 24 * 60 * 60000,
133
+ w: 7 * 24 * 60 * 60000,
134
134
  };
135
135
  /**
136
- * Converts a `TTL` (max-age) value into seconds. Returns `0` for bad and/or
137
- * negative input values.
136
+ * Converts a `TTL` (duration) value into milliseconds. Returns `0` for bad
137
+ * and/or negative input values.
138
138
  *
139
- * @see https://github.com/reykjavikcity/webtools/blob/v0.2/README.md#tosec-ttl-helper
139
+ * @see https://github.com/reykjavikcity/webtools/blob/v0.2/README.md#toms-duration-helper
140
140
  */
141
141
  /*#__NO_SIDE_EFFECTS__*/
142
- export const toSec = (ttl) => {
142
+ export const toMs = (ttl) => {
143
+ if (!ttl) {
144
+ return 0;
145
+ }
143
146
  if (typeof ttl === 'string') {
144
147
  const value = parseFloat(ttl);
145
- const factor = unitToSeconds[ttl.slice(-1)] || 1;
148
+ const factor = unitToMilliseconds[ttl.slice(-1)] || 1;
146
149
  ttl = value * factor;
147
150
  }
148
151
  return Math.max(0, Math.round(ttl)) || 0;
149
152
  };
150
153
  /**
151
- * Converts a `TTL` (duration) value into milliseconds. Returns `0` for bad
152
- * and/or negative input values.
154
+ * Converts a `TTL` (max-age) value into seconds. Returns `0` for bad and/or
155
+ * negative input values.
153
156
  *
154
- * @see https://github.com/reykjavikcity/webtools/blob/v0.2/README.md#toms-duration-helper
157
+ * @see https://github.com/reykjavikcity/webtools/blob/v0.2/README.md#tosec-ttl-helper
155
158
  */
156
159
  /*#__NO_SIDE_EFFECTS__*/
157
- export const toMs = (ttl) => toSec(ttl) * 1000;
160
+ export const toSec = (ttl) => {
161
+ if (typeof ttl === 'number') {
162
+ ttl = ttl * 1000;
163
+ }
164
+ return Math.round(toMs(ttl) / 1000);
165
+ };
158
166
  /*#__NO_SIDE_EFFECTS__*/
159
167
  const toRespnseStubHeaders = (response) => {
160
168
  if (response instanceof Map) {
@@ -210,7 +218,7 @@ export const cacheControl = (response, ttlCfg, eTag) => {
210
218
  let maxAge = opts.maxAge;
211
219
  if (typeof maxAge === 'string') {
212
220
  if (maxAge === 'permanent') {
213
- maxAge = 365 * unitToSeconds.d;
221
+ maxAge = 365 * unitToMilliseconds.d;
214
222
  }
215
223
  else if (maxAge === 'no-cache') {
216
224
  maxAge = 0;
package/http.d.ts CHANGED
@@ -157,13 +157,6 @@ type TTLObj = {
157
157
  * @see https://github.com/reykjavikcity/webtools/blob/v0.2/README.md#type-ttlconfig
158
158
  */
159
159
  export type TTLConfig = TTL | TTLKeywords | TTLObj;
160
- /**
161
- * Converts a `TTL` (max-age) value into seconds. Returns `0` for bad and/or
162
- * negative input values.
163
- *
164
- * @see https://github.com/reykjavikcity/webtools/blob/v0.2/README.md#tosec-ttl-helper
165
- */
166
- export declare const toSec: (ttl: TTL) => number;
167
160
  /**
168
161
  * Converts a `TTL` (duration) value into milliseconds. Returns `0` for bad
169
162
  * and/or negative input values.
@@ -171,6 +164,13 @@ export declare const toSec: (ttl: TTL) => number;
171
164
  * @see https://github.com/reykjavikcity/webtools/blob/v0.2/README.md#toms-duration-helper
172
165
  */
173
166
  export declare const toMs: (ttl: TTL) => number;
167
+ /**
168
+ * Converts a `TTL` (max-age) value into seconds. Returns `0` for bad and/or
169
+ * negative input values.
170
+ *
171
+ * @see https://github.com/reykjavikcity/webtools/blob/v0.2/README.md#tosec-ttl-helper
172
+ */
173
+ export declare const toSec: (ttl: TTL) => number;
174
174
  type ServerResponseStub = Pick<ServerResponse, 'setHeader' | 'getHeader' | 'removeHeader'> & {
175
175
  headers?: Record<string, string | Array<string>>;
176
176
  };
package/http.js CHANGED
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.HTTP_502_BadGateway = exports.HTTP_501_NotImplemented = exports.HTTP_500_InternalServerError = exports.HTTP_451_UnavailableForLegalReasons = exports.HTTP_431_RequestHeaderFieldsTooLarge = exports.HTTP_429_TooManyRequests = exports.HTTP_428_PreconditionRequired = exports.HTTP_426_UpgradeRequired = exports.HTTP_424_FailedDependency = exports.HTTP_423_Locked = exports.HTTP_422_UnprocessableContent = exports.HTTP_421_MisdirectedRequest = exports.HTTP_418_ImATeapot = exports.HTTP_417_ExpectationFailed = exports.HTTP_416_RangeNotSatisfiable = exports.HTTP_415_UnsupportedMediaType = exports.HTTP_414_URITooLong = exports.HTTP_413_PayloadTooLarge = exports.HTTP_412_PreconditionFailed = exports.HTTP_411_LengthRequired = exports.HTTP_410_Gone = exports.HTTP_409_Conflict = exports.HTTP_408_RequestTimeout = exports.HTTP_407_ProxyAuthenticationRequired = exports.HTTP_406_NotAcceptable = exports.HTTP_405_MethodNotAllowed = exports.HTTP_404_NotFound = exports.HTTP_403_Forbidden = exports.HTTP_401_Unauthorized = exports.HTTP_400_BadRequest = exports.HTTP_308_PermanentRedirect = exports.HTTP_307_TemporaryRedirect = exports.HTTP_304_NotModified = exports.HTTP_303_SeeOther = exports.HTTP_302_Found = exports.HTTP_301_MovedPermanently = exports.HTTP_226_IMUsed = exports.HTTP_208_AlreadyReported = exports.HTTP_207_MultiStatus = exports.HTTP_206_PartialContent = exports.HTTP_205_ResetContent = exports.HTTP_204_NoContent = exports.HTTP_203_NonAuthoritativeInformation = exports.HTTP_202_Accepted = exports.HTTP_201_Created = exports.HTTP_200_OK = exports.HTTP_103_EarlyHints = exports.HTTP_102_Processing = exports.HTTP_101_SwitchingProtocols = exports.HTTP_100_Continue = void 0;
4
- exports.cacheControlHeaders = exports.cacheControl = exports.toMs = exports.toSec = exports.HTTP_511_NetworkAuthenticationRequired = exports.HTTP_510_NotExtended = exports.HTTP_508_LoopDetected = exports.HTTP_507_InsufficientStorage = exports.HTTP_506_VariantAlsoNegotiates = exports.HTTP_505_HTTPVersionNotSupported = exports.HTTP_504_GatewayTimeout = exports.HTTP_503_ServiceUnavailable = void 0;
4
+ exports.cacheControlHeaders = exports.cacheControl = exports.toSec = exports.toMs = exports.HTTP_511_NetworkAuthenticationRequired = exports.HTTP_510_NotExtended = exports.HTTP_508_LoopDetected = exports.HTTP_507_InsufficientStorage = exports.HTTP_506_VariantAlsoNegotiates = exports.HTTP_505_HTTPVersionNotSupported = exports.HTTP_504_GatewayTimeout = exports.HTTP_503_ServiceUnavailable = void 0;
5
5
  // INFORMATION
6
6
  /** The client should continue the request or ignore the response if the request is already finished. */
7
7
  exports.HTTP_100_Continue = 100;
@@ -129,38 +129,46 @@ exports.HTTP_508_LoopDetected = 508;
129
129
  exports.HTTP_510_NotExtended = 510;
130
130
  /** The client needs to authenticate to gain network access. */
131
131
  exports.HTTP_511_NetworkAuthenticationRequired = 511;
132
- const unitToSeconds = {
133
- s: 1,
134
- m: 60,
135
- h: 3600,
136
- d: 24 * 3600,
137
- w: 7 * 24 * 3600,
132
+ const unitToMilliseconds = {
133
+ s: 1000,
134
+ m: 60000,
135
+ h: 60 * 60000,
136
+ d: 24 * 60 * 60000,
137
+ w: 7 * 24 * 60 * 60000,
138
138
  };
139
139
  /**
140
- * Converts a `TTL` (max-age) value into seconds. Returns `0` for bad and/or
141
- * negative input values.
140
+ * Converts a `TTL` (duration) value into milliseconds. Returns `0` for bad
141
+ * and/or negative input values.
142
142
  *
143
- * @see https://github.com/reykjavikcity/webtools/blob/v0.2/README.md#tosec-ttl-helper
143
+ * @see https://github.com/reykjavikcity/webtools/blob/v0.2/README.md#toms-duration-helper
144
144
  */
145
145
  /*#__NO_SIDE_EFFECTS__*/
146
- const toSec = (ttl) => {
146
+ const toMs = (ttl) => {
147
+ if (!ttl) {
148
+ return 0;
149
+ }
147
150
  if (typeof ttl === 'string') {
148
151
  const value = parseFloat(ttl);
149
- const factor = unitToSeconds[ttl.slice(-1)] || 1;
152
+ const factor = unitToMilliseconds[ttl.slice(-1)] || 1;
150
153
  ttl = value * factor;
151
154
  }
152
155
  return Math.max(0, Math.round(ttl)) || 0;
153
156
  };
154
- exports.toSec = toSec;
157
+ exports.toMs = toMs;
155
158
  /**
156
- * Converts a `TTL` (duration) value into milliseconds. Returns `0` for bad
157
- * and/or negative input values.
159
+ * Converts a `TTL` (max-age) value into seconds. Returns `0` for bad and/or
160
+ * negative input values.
158
161
  *
159
- * @see https://github.com/reykjavikcity/webtools/blob/v0.2/README.md#toms-duration-helper
162
+ * @see https://github.com/reykjavikcity/webtools/blob/v0.2/README.md#tosec-ttl-helper
160
163
  */
161
164
  /*#__NO_SIDE_EFFECTS__*/
162
- const toMs = (ttl) => (0, exports.toSec)(ttl) * 1000;
163
- exports.toMs = toMs;
165
+ const toSec = (ttl) => {
166
+ if (typeof ttl === 'number') {
167
+ ttl = ttl * 1000;
168
+ }
169
+ return Math.round((0, exports.toMs)(ttl) / 1000);
170
+ };
171
+ exports.toSec = toSec;
164
172
  /*#__NO_SIDE_EFFECTS__*/
165
173
  const toRespnseStubHeaders = (response) => {
166
174
  if (response instanceof Map) {
@@ -216,7 +224,7 @@ const cacheControl = (response, ttlCfg, eTag) => {
216
224
  let maxAge = opts.maxAge;
217
225
  if (typeof maxAge === 'string') {
218
226
  if (maxAge === 'permanent') {
219
- maxAge = 365 * unitToSeconds.d;
227
+ maxAge = 365 * unitToMilliseconds.d;
220
228
  }
221
229
  else if (maxAge === 'no-cache') {
222
230
  maxAge = 0;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reykjavik/webtools",
3
- "version": "0.2.10",
3
+ "version": "0.3.0",
4
4
  "description": "Misc. JS/TS helpers used by Reykjavík City's web dev teams.",
5
5
  "main": "index.js",
6
6
  "repository": "ssh://git@github.com:reykjavikcity/webtools.git",