@reykjavik/webtools 0.1.24 → 0.1.26
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 +14 -0
- package/README.md +7 -14
- package/esm/fixIcelandicLocale.privates.js +1 -1
- package/esm/http.d.ts +10 -3
- package/esm/http.js +33 -7
- package/esm/remix/Wait.d.ts +1 -1
- package/esm/remix/Wait.js +1 -1
- package/fixIcelandicLocale.privates.js +1 -1
- package/http.d.ts +10 -3
- package/http.js +33 -7
- package/package.json +1 -1
- package/remix/Wait.d.ts +1 -1
- package/remix/Wait.js +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,20 @@
|
|
|
4
4
|
|
|
5
5
|
- ... <!-- Add new lines here. -->
|
|
6
6
|
|
|
7
|
+
## 0.1.26
|
|
8
|
+
|
|
9
|
+
_2024-05-25_
|
|
10
|
+
|
|
11
|
+
- `@reykjavik/webtools/fixIcelandicLocale`:
|
|
12
|
+
- fix: Emit `"*dagur, "`, not `"*dagurinn "` from `Intl.DateTimeFormat`
|
|
13
|
+
|
|
14
|
+
## 0.1.25
|
|
15
|
+
|
|
16
|
+
_2024-05-17_
|
|
17
|
+
|
|
18
|
+
- `@reykjavik/webtools/http`:
|
|
19
|
+
- feat: `cacheControl` now also accepts standard `Response` objects
|
|
20
|
+
|
|
7
21
|
## 0.1.24
|
|
8
22
|
|
|
9
23
|
_2024-03-22_
|
package/README.md
CHANGED
|
@@ -268,7 +268,8 @@ values.
|
|
|
268
268
|
|
|
269
269
|
- `Intl.Collator` and `String.prototype.localeCompare`
|
|
270
270
|
- `Intl.NumberFormat` and `Number.prototype.toLocaleString`
|
|
271
|
-
- `Intl.DateTimeFormat` and `Date.prototype.
|
|
271
|
+
- `Intl.DateTimeFormat` and `Date.prototype.toLocaleString`,
|
|
272
|
+
`.toLocaleDateString`, and `.toLocaleTimeString`
|
|
272
273
|
- `Intl.PluralRules`
|
|
273
274
|
- `Intl.ListFormat`
|
|
274
275
|
|
|
@@ -341,28 +342,20 @@ editor), but there's a brief summary:
|
|
|
341
342
|
- `scriptUrl?: string` — The full SiteImprove analytics script URL.
|
|
342
343
|
(alternative to `accountId` prop).
|
|
343
344
|
- `hasConsented?: boolean` — Manual GDPR 'analytics' consent flag. Allows hard
|
|
344
|
-
opt-out, but defers to
|
|
345
|
-
|
|
346
|
-
available.
|
|
345
|
+
opt-out, but defers to [`CookieHubProvider` values](#usecookiehubconsent) if
|
|
346
|
+
they are available.
|
|
347
347
|
- `onLoad?: (e: unknown) => void` — Fires when the script has loaded.
|
|
348
348
|
- `onError?: (e: unknown) => void` — Fires if loading the script failed.
|
|
349
349
|
|
|
350
350
|
Example usage somewhere in your application:
|
|
351
351
|
|
|
352
|
-
```
|
|
352
|
+
```jsz
|
|
353
353
|
import { SiteImprove } from '@reykjavik/webtools/SiteImprove';
|
|
354
354
|
|
|
355
|
-
// ideally emit this from your loader function
|
|
356
355
|
const siteImproveAccountId = '[ACCOUNT_ID]'; // e.g. "7654321"
|
|
357
356
|
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
<SiteImprove
|
|
361
|
-
accountId={siteImproveAccountId}
|
|
362
|
-
onError={(error) =>
|
|
363
|
-
Logger('error', 'An error occured initializing siteimprove', error)
|
|
364
|
-
}
|
|
365
|
-
/>;
|
|
357
|
+
// ...then inside your main App component
|
|
358
|
+
<SiteImprove accountId={siteImproveAccountId} />;
|
|
366
359
|
```
|
|
367
360
|
|
|
368
361
|
In dev mode it does NOT load the SiteImprove script and merely logs page-view
|
package/esm/http.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
/// <reference types="node" resolution-mode="require"/>
|
|
2
|
+
import { ServerResponse } from 'node:http';
|
|
2
3
|
/** The client should continue the request or ignore the response if the request is already finished. */
|
|
3
4
|
export declare const HTTP_100_Continue = 100;
|
|
4
5
|
/** Response to an Upgrade request header from the client and indicates the protocol the server is switching to. */
|
|
@@ -163,13 +164,19 @@ export type TTLConfig = TTL | TTLKeywords | TTLObj;
|
|
|
163
164
|
* @see https://github.com/reykjavikcity/webtools/blob/v0.1/README.md#tosec-ttl-helper
|
|
164
165
|
*/
|
|
165
166
|
export declare const toSec: (ttl: TTL) => number;
|
|
167
|
+
type ServerResponseStub = Pick<ServerResponse, 'setHeader' | 'getHeader' | 'removeHeader'> & {
|
|
168
|
+
headers?: Record<string, string | Array<string>>;
|
|
169
|
+
};
|
|
170
|
+
type ResponseStub = {
|
|
171
|
+
headers: Pick<Headers, 'set' | 'get' | 'delete' | 'append'>;
|
|
172
|
+
};
|
|
166
173
|
/**
|
|
167
174
|
* Use this function to quickly set the `Cache-Control` header with a `max-age=`
|
|
168
175
|
* on a HTTP response
|
|
169
176
|
*
|
|
170
177
|
* @see https://github.com/reykjavikcity/webtools/blob/v0.1/README.md#getcssbundleurl
|
|
171
178
|
*/
|
|
172
|
-
export declare const cacheControl: (response:
|
|
173
|
-
res:
|
|
179
|
+
export declare const cacheControl: (response: ServerResponseStub | ResponseStub | {
|
|
180
|
+
res: ServerResponseStub | ResponseStub;
|
|
174
181
|
}, ttlCfg: TTLConfig, eTag?: string | number) => void;
|
|
175
182
|
export {};
|
package/esm/http.js
CHANGED
|
@@ -146,6 +146,31 @@ export const toSec = (ttl) => {
|
|
|
146
146
|
}
|
|
147
147
|
return Math.max(0, Math.round(ttl)) || 0;
|
|
148
148
|
};
|
|
149
|
+
const toRespnseStubHeaders = (response) => {
|
|
150
|
+
if ('headers' in response && !('setHeader' in response)) {
|
|
151
|
+
return response.headers;
|
|
152
|
+
}
|
|
153
|
+
return {
|
|
154
|
+
get: (name) => {
|
|
155
|
+
const val = response.getHeader(name);
|
|
156
|
+
if (Array.isArray(val)) {
|
|
157
|
+
return val.join(', ');
|
|
158
|
+
}
|
|
159
|
+
return val != null ? `${val}` : null;
|
|
160
|
+
},
|
|
161
|
+
set: (name, value) => response.setHeader(name, value),
|
|
162
|
+
append: (name, value) => {
|
|
163
|
+
const existing = response.getHeader(name);
|
|
164
|
+
if (existing) {
|
|
165
|
+
response.setHeader(name, `${existing}, ${value}`);
|
|
166
|
+
}
|
|
167
|
+
else {
|
|
168
|
+
response.setHeader(name, value);
|
|
169
|
+
}
|
|
170
|
+
},
|
|
171
|
+
delete: (name) => response.removeHeader(name),
|
|
172
|
+
};
|
|
173
|
+
};
|
|
149
174
|
const stabilities = {
|
|
150
175
|
revalidate: ', must-revalidate',
|
|
151
176
|
immutable: ', immutable',
|
|
@@ -153,16 +178,17 @@ const stabilities = {
|
|
|
153
178
|
};
|
|
154
179
|
const setCC = (response, cc) => {
|
|
155
180
|
const devModeHeader = 'X-Cache-Control';
|
|
181
|
+
const headers = toRespnseStubHeaders(response);
|
|
156
182
|
// Also set `X-Cache-Control` in dev mode, because some frameworks
|
|
157
|
-
// **cough** **
|
|
183
|
+
// **cough** **Nextjs** **cough** forcefully override the `Cache-Control`
|
|
158
184
|
// header when the server is in dev mode.
|
|
159
185
|
if (!cc) {
|
|
160
|
-
|
|
161
|
-
process.env.NODE_ENV !== 'production' &&
|
|
186
|
+
headers.delete('Cache-Control');
|
|
187
|
+
process.env.NODE_ENV !== 'production' && headers.delete(devModeHeader);
|
|
162
188
|
return;
|
|
163
189
|
}
|
|
164
|
-
|
|
165
|
-
process.env.NODE_ENV !== 'production' &&
|
|
190
|
+
headers.set('Cache-Control', cc);
|
|
191
|
+
process.env.NODE_ENV !== 'production' && headers.set(devModeHeader, cc);
|
|
166
192
|
};
|
|
167
193
|
/**
|
|
168
194
|
* Use this function to quickly set the `Cache-Control` header with a `max-age=`
|
|
@@ -189,7 +215,7 @@ export const cacheControl = (response, ttlCfg, eTag) => {
|
|
|
189
215
|
}
|
|
190
216
|
}
|
|
191
217
|
if (maxAge == null) {
|
|
192
|
-
response.
|
|
218
|
+
toRespnseStubHeaders(response).delete('Cache-Control');
|
|
193
219
|
return;
|
|
194
220
|
}
|
|
195
221
|
maxAge = toSec(maxAge);
|
|
@@ -204,5 +230,5 @@ export const cacheControl = (response, ttlCfg, eTag) => {
|
|
|
204
230
|
const scope = opts.publ ? 'public' : 'private';
|
|
205
231
|
const stability = (opts.stability && stabilities[opts.stability]) || stabilities.immutable;
|
|
206
232
|
setCC(response, `${scope}, max-age=${maxAge + sWR + sIE + stability}`);
|
|
207
|
-
eTag != null && response.
|
|
233
|
+
eTag != null && toRespnseStubHeaders(response).set('ETag', String(eTag));
|
|
208
234
|
};
|
package/esm/remix/Wait.d.ts
CHANGED
|
@@ -37,7 +37,7 @@ export type WaitComponent<CustomProps extends Record<string, unknown> = Record<n
|
|
|
37
37
|
displayName?: string;
|
|
38
38
|
};
|
|
39
39
|
/**
|
|
40
|
-
*
|
|
40
|
+
* A thin wrapper around [Remix's `Await`](https://remix.run/docs/en/2/components/await)
|
|
41
41
|
* component, to provide a more ergonomic API.
|
|
42
42
|
*
|
|
43
43
|
* If the awaited promise (`props.for`) resolves to an object with a truthy
|
package/esm/remix/Wait.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React, { Suspense } from 'react';
|
|
2
2
|
import { Await } from '@remix-run/react';
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
4
|
+
* A thin wrapper around [Remix's `Await`](https://remix.run/docs/en/2/components/await)
|
|
5
5
|
* component, to provide a more ergonomic API.
|
|
6
6
|
*
|
|
7
7
|
* If the awaited promise (`props.for`) resolves to an object with a truthy
|
package/http.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { ServerResponse } from 'node:http';
|
|
2
3
|
/** The client should continue the request or ignore the response if the request is already finished. */
|
|
3
4
|
export declare const HTTP_100_Continue = 100;
|
|
4
5
|
/** Response to an Upgrade request header from the client and indicates the protocol the server is switching to. */
|
|
@@ -163,13 +164,19 @@ export type TTLConfig = TTL | TTLKeywords | TTLObj;
|
|
|
163
164
|
* @see https://github.com/reykjavikcity/webtools/blob/v0.1/README.md#tosec-ttl-helper
|
|
164
165
|
*/
|
|
165
166
|
export declare const toSec: (ttl: TTL) => number;
|
|
167
|
+
type ServerResponseStub = Pick<ServerResponse, 'setHeader' | 'getHeader' | 'removeHeader'> & {
|
|
168
|
+
headers?: Record<string, string | Array<string>>;
|
|
169
|
+
};
|
|
170
|
+
type ResponseStub = {
|
|
171
|
+
headers: Pick<Headers, 'set' | 'get' | 'delete' | 'append'>;
|
|
172
|
+
};
|
|
166
173
|
/**
|
|
167
174
|
* Use this function to quickly set the `Cache-Control` header with a `max-age=`
|
|
168
175
|
* on a HTTP response
|
|
169
176
|
*
|
|
170
177
|
* @see https://github.com/reykjavikcity/webtools/blob/v0.1/README.md#getcssbundleurl
|
|
171
178
|
*/
|
|
172
|
-
export declare const cacheControl: (response:
|
|
173
|
-
res:
|
|
179
|
+
export declare const cacheControl: (response: ServerResponseStub | ResponseStub | {
|
|
180
|
+
res: ServerResponseStub | ResponseStub;
|
|
174
181
|
}, ttlCfg: TTLConfig, eTag?: string | number) => void;
|
|
175
182
|
export {};
|
package/http.js
CHANGED
|
@@ -151,6 +151,31 @@ const toSec = (ttl) => {
|
|
|
151
151
|
return Math.max(0, Math.round(ttl)) || 0;
|
|
152
152
|
};
|
|
153
153
|
exports.toSec = toSec;
|
|
154
|
+
const toRespnseStubHeaders = (response) => {
|
|
155
|
+
if ('headers' in response && !('setHeader' in response)) {
|
|
156
|
+
return response.headers;
|
|
157
|
+
}
|
|
158
|
+
return {
|
|
159
|
+
get: (name) => {
|
|
160
|
+
const val = response.getHeader(name);
|
|
161
|
+
if (Array.isArray(val)) {
|
|
162
|
+
return val.join(', ');
|
|
163
|
+
}
|
|
164
|
+
return val != null ? `${val}` : null;
|
|
165
|
+
},
|
|
166
|
+
set: (name, value) => response.setHeader(name, value),
|
|
167
|
+
append: (name, value) => {
|
|
168
|
+
const existing = response.getHeader(name);
|
|
169
|
+
if (existing) {
|
|
170
|
+
response.setHeader(name, `${existing}, ${value}`);
|
|
171
|
+
}
|
|
172
|
+
else {
|
|
173
|
+
response.setHeader(name, value);
|
|
174
|
+
}
|
|
175
|
+
},
|
|
176
|
+
delete: (name) => response.removeHeader(name),
|
|
177
|
+
};
|
|
178
|
+
};
|
|
154
179
|
const stabilities = {
|
|
155
180
|
revalidate: ', must-revalidate',
|
|
156
181
|
immutable: ', immutable',
|
|
@@ -158,16 +183,17 @@ const stabilities = {
|
|
|
158
183
|
};
|
|
159
184
|
const setCC = (response, cc) => {
|
|
160
185
|
const devModeHeader = 'X-Cache-Control';
|
|
186
|
+
const headers = toRespnseStubHeaders(response);
|
|
161
187
|
// Also set `X-Cache-Control` in dev mode, because some frameworks
|
|
162
|
-
// **cough** **
|
|
188
|
+
// **cough** **Nextjs** **cough** forcefully override the `Cache-Control`
|
|
163
189
|
// header when the server is in dev mode.
|
|
164
190
|
if (!cc) {
|
|
165
|
-
|
|
166
|
-
process.env.NODE_ENV !== 'production' &&
|
|
191
|
+
headers.delete('Cache-Control');
|
|
192
|
+
process.env.NODE_ENV !== 'production' && headers.delete(devModeHeader);
|
|
167
193
|
return;
|
|
168
194
|
}
|
|
169
|
-
|
|
170
|
-
process.env.NODE_ENV !== 'production' &&
|
|
195
|
+
headers.set('Cache-Control', cc);
|
|
196
|
+
process.env.NODE_ENV !== 'production' && headers.set(devModeHeader, cc);
|
|
171
197
|
};
|
|
172
198
|
/**
|
|
173
199
|
* Use this function to quickly set the `Cache-Control` header with a `max-age=`
|
|
@@ -194,7 +220,7 @@ const cacheControl = (response, ttlCfg, eTag) => {
|
|
|
194
220
|
}
|
|
195
221
|
}
|
|
196
222
|
if (maxAge == null) {
|
|
197
|
-
response.
|
|
223
|
+
toRespnseStubHeaders(response).delete('Cache-Control');
|
|
198
224
|
return;
|
|
199
225
|
}
|
|
200
226
|
maxAge = (0, exports.toSec)(maxAge);
|
|
@@ -209,6 +235,6 @@ const cacheControl = (response, ttlCfg, eTag) => {
|
|
|
209
235
|
const scope = opts.publ ? 'public' : 'private';
|
|
210
236
|
const stability = (opts.stability && stabilities[opts.stability]) || stabilities.immutable;
|
|
211
237
|
setCC(response, `${scope}, max-age=${maxAge + sWR + sIE + stability}`);
|
|
212
|
-
eTag != null && response.
|
|
238
|
+
eTag != null && toRespnseStubHeaders(response).set('ETag', String(eTag));
|
|
213
239
|
};
|
|
214
240
|
exports.cacheControl = cacheControl;
|
package/package.json
CHANGED
package/remix/Wait.d.ts
CHANGED
|
@@ -37,7 +37,7 @@ export type WaitComponent<CustomProps extends Record<string, unknown> = Record<n
|
|
|
37
37
|
displayName?: string;
|
|
38
38
|
};
|
|
39
39
|
/**
|
|
40
|
-
*
|
|
40
|
+
* A thin wrapper around [Remix's `Await`](https://remix.run/docs/en/2/components/await)
|
|
41
41
|
* component, to provide a more ergonomic API.
|
|
42
42
|
*
|
|
43
43
|
* If the awaited promise (`props.for`) resolves to an object with a truthy
|
package/remix/Wait.js
CHANGED
|
@@ -27,7 +27,7 @@ exports.Wait = void 0;
|
|
|
27
27
|
const react_1 = __importStar(require("react"));
|
|
28
28
|
const react_2 = require("@remix-run/react");
|
|
29
29
|
/**
|
|
30
|
-
*
|
|
30
|
+
* A thin wrapper around [Remix's `Await`](https://remix.run/docs/en/2/components/await)
|
|
31
31
|
* component, to provide a more ergonomic API.
|
|
32
32
|
*
|
|
33
33
|
* If the awaited promise (`props.for`) resolves to an object with a truthy
|