@braidlabs/gateway 0.1.1 → 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/README.md +112 -17
- package/package.json +2 -2
- package/src/gateway.d.ts +46 -15
- package/src/gateway.js +260 -44
- package/src/gateway.js.map +1 -1
- package/src/protocol.d.ts +18 -2
- package/src/protocol.js +19 -3
- package/src/protocol.js.map +1 -1
- package/src/redirect.d.ts +70 -0
- package/src/redirect.js +172 -0
- package/src/redirect.js.map +1 -0
- package/src/registry.d.ts +73 -0
- package/src/registry.js +16 -0
- package/src/registry.js.map +1 -1
- package/src/rewriter/html-rewrite-stream.d.ts +8 -3
- package/src/rewriter/html-rewrite-stream.js +25 -7
- package/src/rewriter/html-rewrite-stream.js.map +1 -1
- package/src/rewriter/transforms.d.ts +60 -10
- package/src/rewriter/transforms.js +192 -49
- package/src/rewriter/transforms.js.map +1 -1
- package/src/single-flight.d.ts +7 -1
- package/src/single-flight.js +26 -6
- package/src/single-flight.js.map +1 -1
package/src/single-flight.js
CHANGED
|
@@ -19,13 +19,17 @@ export function createSingleFlight() {
|
|
|
19
19
|
return {
|
|
20
20
|
async run(key, fetcher) {
|
|
21
21
|
const existing = inflight.get(key);
|
|
22
|
-
if (existing)
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
22
|
+
if (existing) {
|
|
23
|
+
// counted synchronously, so the starter knows before it hands out a body whether anyone
|
|
24
|
+
// else will need one
|
|
25
|
+
existing.joiners++;
|
|
26
|
+
return (await existing.flight).clone();
|
|
27
|
+
}
|
|
28
|
+
const entry = { flight: fetcher(), joiners: 0 };
|
|
29
|
+
inflight.set(key, entry);
|
|
26
30
|
let response;
|
|
27
31
|
try {
|
|
28
|
-
response = await flight;
|
|
32
|
+
response = await entry.flight;
|
|
29
33
|
}
|
|
30
34
|
finally {
|
|
31
35
|
// Removed as soon as it settles: a request arriving after this point must start its own
|
|
@@ -33,6 +37,10 @@ export function createSingleFlight() {
|
|
|
33
37
|
// cache with an accidental TTL.
|
|
34
38
|
inflight.delete(key);
|
|
35
39
|
}
|
|
40
|
+
// Nobody joined, and nobody can now: the response is this caller's alone. Most fetches end
|
|
41
|
+
// here, and a clone would tee every byte of them for a second reader that does not exist.
|
|
42
|
+
if (entry.joiners === 0)
|
|
43
|
+
return response;
|
|
36
44
|
const mine = response.clone();
|
|
37
45
|
/**
|
|
38
46
|
* Release the branch nobody reads.
|
|
@@ -73,9 +81,15 @@ export function createSingleFlight() {
|
|
|
73
81
|
* What this cannot see is an endpoint varying on something unusual: a tenant header, a
|
|
74
82
|
* feature-flag header, anything bespoke. Those set `coalesce: false` on the manifest.
|
|
75
83
|
*
|
|
84
|
+
* `extraHeaders` closes that gap for headers the *gateway itself* adds per request — an identity
|
|
85
|
+
* assertion from a function-form `additionalHeaders`, most importantly. Those vary by caller and
|
|
86
|
+
* are invisible to everything above, so leaving them out of the key would hand one caller a
|
|
87
|
+
* fragment rendered for another. Names, not values: the values are read off the request that is
|
|
88
|
+
* actually being sent.
|
|
89
|
+
*
|
|
76
90
|
* Returns null when the request must not be shared at all.
|
|
77
91
|
*/
|
|
78
|
-
export function singleFlightKey(request, url) {
|
|
92
|
+
export function singleFlightKey(request, url, extraHeaders = []) {
|
|
79
93
|
// Only safe methods. A POST is an action, and two identical actions are still two actions.
|
|
80
94
|
if (request.method !== 'GET' && request.method !== 'HEAD')
|
|
81
95
|
return null;
|
|
@@ -92,6 +106,12 @@ export function singleFlightKey(request, url) {
|
|
|
92
106
|
request.headers.get('accept-language') ?? '',
|
|
93
107
|
request.headers.get('accept') ?? '',
|
|
94
108
|
request.headers.get('user-agent') ?? '',
|
|
109
|
+
// A conditional request may be answered with a bodyless 304, which is no answer at all to a
|
|
110
|
+
// caller who asked for the body.
|
|
111
|
+
request.headers.get('if-none-match') ?? '',
|
|
112
|
+
request.headers.get('if-modified-since') ?? '',
|
|
113
|
+
// Sorted, so the key does not depend on the order a host happened to build its object in.
|
|
114
|
+
...[...extraHeaders].sort().map((name) => `${name}=${request.headers.get(name) ?? ''}`),
|
|
95
115
|
].join('\n');
|
|
96
116
|
}
|
|
97
117
|
//# sourceMappingURL=single-flight.js.map
|
package/src/single-flight.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"single-flight.js","sourceRoot":"","sources":["../../../../libs/braid-gateway/src/single-flight.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAcH,MAAM,UAAU,kBAAkB;IAChC,MAAM,QAAQ,GAAG,IAAI,GAAG,
|
|
1
|
+
{"version":3,"file":"single-flight.js","sourceRoot":"","sources":["../../../../libs/braid-gateway/src/single-flight.ts"],"names":[],"mappings":"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"}
|