@volter/world-core 3.0.20 → 3.0.21
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/dist/inject.cjs +77 -1
- package/inject.cjs +77 -1
- package/package.json +1 -1
package/dist/inject.cjs
CHANGED
|
@@ -21,7 +21,13 @@
|
|
|
21
21
|
// (stripe-node → https; @octokit → fetch; @slack/web-api & jira.js → axios →
|
|
22
22
|
// http/https; @linear/sdk → fetch), so no per-SDK shim is needed.
|
|
23
23
|
//
|
|
24
|
-
//
|
|
24
|
+
// Attached to a World (VOLTER_WORLD), a request a bundled undici (wrangler's) sends to the
|
|
25
|
+
// World's own paths through undici's shared global dispatcher carries the World's key too:
|
|
26
|
+
// Object.defineProperty is watched for that global, and the dispatcher set there is stood
|
|
27
|
+
// in for by a view whose dispatch keys a hop whose origin and path are the World's
|
|
28
|
+
// (keyedView, below), sent with maxRedirections 0 so no follower below it takes the key on.
|
|
29
|
+
//
|
|
30
|
+
// A client can still open its own sockets (npm `undici`'s own Agent, which
|
|
25
31
|
// @turbopuffer/turbopuffer uses under Node, honours neither patch nor HTTPS_PROXY).
|
|
26
32
|
// `net.connect`/`tls.connect` are the seam every Node client ends at, so they carry
|
|
27
33
|
// the backstop: a connect to a twinned vendor host went around the rewrite and is
|
|
@@ -435,6 +441,74 @@ function withWorldKey(args) {
|
|
|
435
441
|
return out;
|
|
436
442
|
}
|
|
437
443
|
|
|
444
|
+
// A client that bundles its own undici (wrangler) calls neither the global `fetch` nor http(s), so its requests to the
|
|
445
|
+
// World's own paths would arrive without the key. Every undici copy, Node's own included, keeps its dispatcher on one
|
|
446
|
+
// shared global (`Symbol.for('undici.globalDispatcher.<n>')`), set with Object.defineProperty when that copy loads. A
|
|
447
|
+
// dispatcher defined there is stood in for by a view of it whose `dispatch` adds the key to one hop, only when that
|
|
448
|
+
// hop's origin is the World's and its path one of the World's own, compared as strings (a path is never resolved as a
|
|
449
|
+
// URL, so `//other-host/…` names no other origin); the dispatcher itself is never changed, and restore() puts it back.
|
|
450
|
+
const UNDICI_DISPATCHERS = [Symbol.for('undici.globalDispatcher.1'), Symbol.for('undici.globalDispatcher.2')];
|
|
451
|
+
const KEYED_VIEWS = new WeakMap(); // view -> the dispatcher it stands in for
|
|
452
|
+
function keyedUndiciHeaders(headers, key) {
|
|
453
|
+
if (headers == null) return { 'x-twins-key': key };
|
|
454
|
+
if (Array.isArray(headers)) {
|
|
455
|
+
const flat = headers.length === 0 || !Array.isArray(headers[0]);
|
|
456
|
+
const names = flat ? headers.filter((_, i) => i % 2 === 0) : headers.map((h) => h[0]);
|
|
457
|
+
if (names.some((n) => String(n).toLowerCase() === 'x-twins-key')) return headers;
|
|
458
|
+
return flat ? [...headers, 'x-twins-key', key] : [...headers, ['x-twins-key', key]];
|
|
459
|
+
}
|
|
460
|
+
const entries = typeof headers[Symbol.iterator] === 'function' ? [...headers] : Object.entries(headers);
|
|
461
|
+
if (entries.some(([n]) => String(n).toLowerCase() === 'x-twins-key')) return headers;
|
|
462
|
+
return Object.assign(Object.fromEntries(entries), { 'x-twins-key': key });
|
|
463
|
+
}
|
|
464
|
+
/** A dispatch hop is the World's: its origin is the World's own and its path, as written, under the World's paths. */
|
|
465
|
+
function hopToWorld(opts) {
|
|
466
|
+
const base = worldBase();
|
|
467
|
+
if (!base || !base.path || !opts || opts.origin == null) return false;
|
|
468
|
+
let origin;
|
|
469
|
+
try { origin = new URL(String(opts.origin)).origin; } catch { return false; }
|
|
470
|
+
const at = String(opts.path == null ? '/' : opts.path);
|
|
471
|
+
return origin === base.origin && (at.startsWith(`${base.path}/`) || at.startsWith(`/-${base.path}/`));
|
|
472
|
+
}
|
|
473
|
+
function keyedView(dispatcher) {
|
|
474
|
+
if (!dispatcher || typeof dispatcher.dispatch !== 'function' || KEYED_VIEWS.has(dispatcher)) return dispatcher;
|
|
475
|
+
const view = new Proxy(dispatcher, {
|
|
476
|
+
get(target, name) {
|
|
477
|
+
if (name === 'dispatch') {
|
|
478
|
+
return function keyedDispatch(opts, handler) {
|
|
479
|
+
const key = ORIGINAL_DEFINE_PROPERTY ? twinsKey() : null;
|
|
480
|
+
// a hop the caller asked undici to follow is not keyed; a keyed hop is sent with maxRedirections 0, so no
|
|
481
|
+
// redirect follower below this view (a composed interceptor, a RetryAgent or proxy agent around one, undici
|
|
482
|
+
// 6's option or interceptors) carries its headers to the next origin: the redirect comes back to the caller
|
|
483
|
+
const keyed = key && !(opts && Number(opts.maxRedirections) > 0) && hopToWorld(opts);
|
|
484
|
+
return target.dispatch(keyed ? Object.assign({}, opts, { headers: keyedUndiciHeaders(opts.headers, key), maxRedirections: 0 }) : opts, handler);
|
|
485
|
+
};
|
|
486
|
+
}
|
|
487
|
+
const value = Reflect.get(target, name, target);
|
|
488
|
+
return typeof value === 'function' ? value.bind(target) : value;
|
|
489
|
+
},
|
|
490
|
+
});
|
|
491
|
+
KEYED_VIEWS.set(view, dispatcher);
|
|
492
|
+
return view;
|
|
493
|
+
}
|
|
494
|
+
let ORIGINAL_DEFINE_PROPERTY = null;
|
|
495
|
+
function keyUndiciDispatches() {
|
|
496
|
+
if (ORIGINAL_DEFINE_PROPERTY || !worldBase() || Object.defineProperty.name === 'keyingDefineProperty') return;
|
|
497
|
+
const define = ORIGINAL_DEFINE_PROPERTY = Object.defineProperty;
|
|
498
|
+
Object.defineProperty = function keyingDefineProperty(target, name, descriptor) {
|
|
499
|
+
if (ORIGINAL_DEFINE_PROPERTY && target === globalThis && UNDICI_DISPATCHERS.includes(name) && descriptor && 'value' in descriptor) descriptor = Object.assign({}, descriptor, { value: keyedView(descriptor.value) });
|
|
500
|
+
return define(target, name, descriptor);
|
|
501
|
+
};
|
|
502
|
+
for (const name of UNDICI_DISPATCHERS) if (globalThis[name]) globalThis[name] = keyedView(globalThis[name]);
|
|
503
|
+
}
|
|
504
|
+
function unkeyUndiciDispatches() {
|
|
505
|
+
if (!ORIGINAL_DEFINE_PROPERTY) return;
|
|
506
|
+
// only what this put in place is put back: a wrapper installed over it since stays
|
|
507
|
+
if (Object.defineProperty.name === 'keyingDefineProperty') Object.defineProperty = ORIGINAL_DEFINE_PROPERTY;
|
|
508
|
+
ORIGINAL_DEFINE_PROPERTY = null;
|
|
509
|
+
for (const name of UNDICI_DISPATCHERS) if (KEYED_VIEWS.has(globalThis[name])) globalThis[name] = KEYED_VIEWS.get(globalThis[name]);
|
|
510
|
+
}
|
|
511
|
+
|
|
438
512
|
// S4 review F3: undici's default redirect-follow forwards CUSTOM headers across origins — a
|
|
439
513
|
// twin (or the World) answering 30x to an external URL would carry x-twins-key to a REAL host. A
|
|
440
514
|
// keyed fetch follows redirects itself: a hop that is a twin or the World re-enters the patched
|
|
@@ -979,6 +1053,7 @@ function install(mapOverride) {
|
|
|
979
1053
|
tls.connect = patchedConnect(ORIGINALS.tlsConnect, true);
|
|
980
1054
|
dns.lookup = patchedLookup(ORIGINALS.dnsLookup);
|
|
981
1055
|
dns.promises.lookup = patchedPromisesLookup(ORIGINALS.dnsPromisesLookup);
|
|
1056
|
+
keyUndiciDispatches();
|
|
982
1057
|
// gRPC (architecture, "Other wires": gRPC): an HTTP/2 session to a host a twin serves (grpc-js on google-gax: TLS to
|
|
983
1058
|
// webrisk.googleapis.com) connects to that twin's origin in plain text, where the kernel's HTTP/2 server answers it;
|
|
984
1059
|
// the client carries on unchanged. Any other authority is the real one's.
|
|
@@ -1139,6 +1214,7 @@ function restore() {
|
|
|
1139
1214
|
dns.lookup = ORIGINALS.dnsLookup;
|
|
1140
1215
|
dns.promises.lookup = ORIGINALS.dnsPromisesLookup;
|
|
1141
1216
|
http2.connect = ORIGINALS.http2Connect;
|
|
1217
|
+
unkeyUndiciDispatches();
|
|
1142
1218
|
installed = false;
|
|
1143
1219
|
MAP = {};
|
|
1144
1220
|
}
|
package/inject.cjs
CHANGED
|
@@ -21,7 +21,13 @@
|
|
|
21
21
|
// (stripe-node → https; @octokit → fetch; @slack/web-api & jira.js → axios →
|
|
22
22
|
// http/https; @linear/sdk → fetch), so no per-SDK shim is needed.
|
|
23
23
|
//
|
|
24
|
-
//
|
|
24
|
+
// Attached to a World (VOLTER_WORLD), a request a bundled undici (wrangler's) sends to the
|
|
25
|
+
// World's own paths through undici's shared global dispatcher carries the World's key too:
|
|
26
|
+
// Object.defineProperty is watched for that global, and the dispatcher set there is stood
|
|
27
|
+
// in for by a view whose dispatch keys a hop whose origin and path are the World's
|
|
28
|
+
// (keyedView, below), sent with maxRedirections 0 so no follower below it takes the key on.
|
|
29
|
+
//
|
|
30
|
+
// A client can still open its own sockets (npm `undici`'s own Agent, which
|
|
25
31
|
// @turbopuffer/turbopuffer uses under Node, honours neither patch nor HTTPS_PROXY).
|
|
26
32
|
// `net.connect`/`tls.connect` are the seam every Node client ends at, so they carry
|
|
27
33
|
// the backstop: a connect to a twinned vendor host went around the rewrite and is
|
|
@@ -435,6 +441,74 @@ function withWorldKey(args) {
|
|
|
435
441
|
return out;
|
|
436
442
|
}
|
|
437
443
|
|
|
444
|
+
// A client that bundles its own undici (wrangler) calls neither the global `fetch` nor http(s), so its requests to the
|
|
445
|
+
// World's own paths would arrive without the key. Every undici copy, Node's own included, keeps its dispatcher on one
|
|
446
|
+
// shared global (`Symbol.for('undici.globalDispatcher.<n>')`), set with Object.defineProperty when that copy loads. A
|
|
447
|
+
// dispatcher defined there is stood in for by a view of it whose `dispatch` adds the key to one hop, only when that
|
|
448
|
+
// hop's origin is the World's and its path one of the World's own, compared as strings (a path is never resolved as a
|
|
449
|
+
// URL, so `//other-host/…` names no other origin); the dispatcher itself is never changed, and restore() puts it back.
|
|
450
|
+
const UNDICI_DISPATCHERS = [Symbol.for('undici.globalDispatcher.1'), Symbol.for('undici.globalDispatcher.2')];
|
|
451
|
+
const KEYED_VIEWS = new WeakMap(); // view -> the dispatcher it stands in for
|
|
452
|
+
function keyedUndiciHeaders(headers, key) {
|
|
453
|
+
if (headers == null) return { 'x-twins-key': key };
|
|
454
|
+
if (Array.isArray(headers)) {
|
|
455
|
+
const flat = headers.length === 0 || !Array.isArray(headers[0]);
|
|
456
|
+
const names = flat ? headers.filter((_, i) => i % 2 === 0) : headers.map((h) => h[0]);
|
|
457
|
+
if (names.some((n) => String(n).toLowerCase() === 'x-twins-key')) return headers;
|
|
458
|
+
return flat ? [...headers, 'x-twins-key', key] : [...headers, ['x-twins-key', key]];
|
|
459
|
+
}
|
|
460
|
+
const entries = typeof headers[Symbol.iterator] === 'function' ? [...headers] : Object.entries(headers);
|
|
461
|
+
if (entries.some(([n]) => String(n).toLowerCase() === 'x-twins-key')) return headers;
|
|
462
|
+
return Object.assign(Object.fromEntries(entries), { 'x-twins-key': key });
|
|
463
|
+
}
|
|
464
|
+
/** A dispatch hop is the World's: its origin is the World's own and its path, as written, under the World's paths. */
|
|
465
|
+
function hopToWorld(opts) {
|
|
466
|
+
const base = worldBase();
|
|
467
|
+
if (!base || !base.path || !opts || opts.origin == null) return false;
|
|
468
|
+
let origin;
|
|
469
|
+
try { origin = new URL(String(opts.origin)).origin; } catch { return false; }
|
|
470
|
+
const at = String(opts.path == null ? '/' : opts.path);
|
|
471
|
+
return origin === base.origin && (at.startsWith(`${base.path}/`) || at.startsWith(`/-${base.path}/`));
|
|
472
|
+
}
|
|
473
|
+
function keyedView(dispatcher) {
|
|
474
|
+
if (!dispatcher || typeof dispatcher.dispatch !== 'function' || KEYED_VIEWS.has(dispatcher)) return dispatcher;
|
|
475
|
+
const view = new Proxy(dispatcher, {
|
|
476
|
+
get(target, name) {
|
|
477
|
+
if (name === 'dispatch') {
|
|
478
|
+
return function keyedDispatch(opts, handler) {
|
|
479
|
+
const key = ORIGINAL_DEFINE_PROPERTY ? twinsKey() : null;
|
|
480
|
+
// a hop the caller asked undici to follow is not keyed; a keyed hop is sent with maxRedirections 0, so no
|
|
481
|
+
// redirect follower below this view (a composed interceptor, a RetryAgent or proxy agent around one, undici
|
|
482
|
+
// 6's option or interceptors) carries its headers to the next origin: the redirect comes back to the caller
|
|
483
|
+
const keyed = key && !(opts && Number(opts.maxRedirections) > 0) && hopToWorld(opts);
|
|
484
|
+
return target.dispatch(keyed ? Object.assign({}, opts, { headers: keyedUndiciHeaders(opts.headers, key), maxRedirections: 0 }) : opts, handler);
|
|
485
|
+
};
|
|
486
|
+
}
|
|
487
|
+
const value = Reflect.get(target, name, target);
|
|
488
|
+
return typeof value === 'function' ? value.bind(target) : value;
|
|
489
|
+
},
|
|
490
|
+
});
|
|
491
|
+
KEYED_VIEWS.set(view, dispatcher);
|
|
492
|
+
return view;
|
|
493
|
+
}
|
|
494
|
+
let ORIGINAL_DEFINE_PROPERTY = null;
|
|
495
|
+
function keyUndiciDispatches() {
|
|
496
|
+
if (ORIGINAL_DEFINE_PROPERTY || !worldBase() || Object.defineProperty.name === 'keyingDefineProperty') return;
|
|
497
|
+
const define = ORIGINAL_DEFINE_PROPERTY = Object.defineProperty;
|
|
498
|
+
Object.defineProperty = function keyingDefineProperty(target, name, descriptor) {
|
|
499
|
+
if (ORIGINAL_DEFINE_PROPERTY && target === globalThis && UNDICI_DISPATCHERS.includes(name) && descriptor && 'value' in descriptor) descriptor = Object.assign({}, descriptor, { value: keyedView(descriptor.value) });
|
|
500
|
+
return define(target, name, descriptor);
|
|
501
|
+
};
|
|
502
|
+
for (const name of UNDICI_DISPATCHERS) if (globalThis[name]) globalThis[name] = keyedView(globalThis[name]);
|
|
503
|
+
}
|
|
504
|
+
function unkeyUndiciDispatches() {
|
|
505
|
+
if (!ORIGINAL_DEFINE_PROPERTY) return;
|
|
506
|
+
// only what this put in place is put back: a wrapper installed over it since stays
|
|
507
|
+
if (Object.defineProperty.name === 'keyingDefineProperty') Object.defineProperty = ORIGINAL_DEFINE_PROPERTY;
|
|
508
|
+
ORIGINAL_DEFINE_PROPERTY = null;
|
|
509
|
+
for (const name of UNDICI_DISPATCHERS) if (KEYED_VIEWS.has(globalThis[name])) globalThis[name] = KEYED_VIEWS.get(globalThis[name]);
|
|
510
|
+
}
|
|
511
|
+
|
|
438
512
|
// S4 review F3: undici's default redirect-follow forwards CUSTOM headers across origins — a
|
|
439
513
|
// twin (or the World) answering 30x to an external URL would carry x-twins-key to a REAL host. A
|
|
440
514
|
// keyed fetch follows redirects itself: a hop that is a twin or the World re-enters the patched
|
|
@@ -979,6 +1053,7 @@ function install(mapOverride) {
|
|
|
979
1053
|
tls.connect = patchedConnect(ORIGINALS.tlsConnect, true);
|
|
980
1054
|
dns.lookup = patchedLookup(ORIGINALS.dnsLookup);
|
|
981
1055
|
dns.promises.lookup = patchedPromisesLookup(ORIGINALS.dnsPromisesLookup);
|
|
1056
|
+
keyUndiciDispatches();
|
|
982
1057
|
// gRPC (architecture, "Other wires": gRPC): an HTTP/2 session to a host a twin serves (grpc-js on google-gax: TLS to
|
|
983
1058
|
// webrisk.googleapis.com) connects to that twin's origin in plain text, where the kernel's HTTP/2 server answers it;
|
|
984
1059
|
// the client carries on unchanged. Any other authority is the real one's.
|
|
@@ -1139,6 +1214,7 @@ function restore() {
|
|
|
1139
1214
|
dns.lookup = ORIGINALS.dnsLookup;
|
|
1140
1215
|
dns.promises.lookup = ORIGINALS.dnsPromisesLookup;
|
|
1141
1216
|
http2.connect = ORIGINALS.http2Connect;
|
|
1217
|
+
unkeyUndiciDispatches();
|
|
1142
1218
|
installed = false;
|
|
1143
1219
|
MAP = {};
|
|
1144
1220
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@volter/world-core",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.21",
|
|
4
4
|
"description": "The kernel of Volter World: one log per twin, branches as pointers, checkpoints, the fold that keeps a twin current, the head that performs a write against the vendor, references, and the git plane. A twin package builds on it; the runtime serves it.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"twin",
|