@volter/world-core 3.0.50 → 3.0.52

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 CHANGED
@@ -1037,7 +1037,9 @@ function isTwinOriginHost(host) {
1037
1037
  // public name gets. The address is one of the documentation ranges (RFC 5737's 203.0.113.0/24, RFC 3849's
1038
1038
  // 2001:db8::/32): public-shaped, never private, and routed nowhere, so nothing reaches a host by it; the request by name
1039
1039
  // is routed as every other one is, and a socket dialled to the address itself is refused with the reason. Every other
1040
- // name is the real resolver's, unchanged.
1040
+ // name is the real resolver's, unchanged. A browser Node guest has only its
1041
+ // engine's address resolver: routed names resolve the actual HTTP hop below,
1042
+ // never a documentation address on which that engine cannot connect.
1041
1043
  const WORLD_ADDRESS = { 4: '203.0.113.7', 6: '2001:db8::7' };
1042
1044
  function worldResolves(hostname) {
1043
1045
  const host = String(hostname || '').toLowerCase().replace(/\.$/, '');
@@ -1052,6 +1054,23 @@ function worldLookupAnswer(options) {
1052
1054
  const all = !!(options && typeof options === 'object' && options.all);
1053
1055
  return all ? families.map((f) => ({ address: WORLD_ADDRESS[f], family: f })) : { address: WORLD_ADDRESS[families[0]], family: families[0] };
1054
1056
  }
1057
+ function guestLookupTarget(hostname) {
1058
+ if (!process.versions.webcontainer) return null;
1059
+ const routed = resolveTwin(String(hostname).toLowerCase().replace(/\.$/, ''), MAP);
1060
+ if (!routed) return null;
1061
+ const endpoint = localGuestProxy() || new URL(routed.origin);
1062
+ return endpoint.hostname.replace(/^\[|\]$/g, '');
1063
+ }
1064
+ function guestLookupOptions(options) {
1065
+ return typeof options === 'number' ? { family: options } : options || {};
1066
+ }
1067
+ function guestLookupAnswer(hostname, options, addresses) {
1068
+ const opts = guestLookupOptions(options);
1069
+ const family = opts.family === 'IPv4' ? 4 : opts.family === 'IPv6' ? 6 : opts.family || 0;
1070
+ const available = addresses.filter(answer => !family || answer.family === family);
1071
+ if (!available.length) throw Object.assign(new Error(`getaddrinfo ENOTFOUND ${hostname}`), { code: 'ENOTFOUND', errno: -3008, syscall: 'getaddrinfo', hostname });
1072
+ return opts.all ? available : available[0];
1073
+ }
1055
1074
  /** Whether a lookup of `hostname` waits for the claiming twins' first read: never for a twin's own origin, whose
1056
1075
  * lookup that read itself makes (a claimer at a hostname origin, as `attach` gives one, would wait on itself). */
1057
1076
  function lookupWaitsForClaims(hostname) {
@@ -1096,6 +1115,14 @@ function patchedLookup(original) {
1096
1115
  if (typeof cb !== 'function') return original.apply(this, arguments);
1097
1116
  const answer = () => {
1098
1117
  if (!worldResolves(hostname)) return original.call(dns, hostname, opts ?? {}, cb);
1118
+ const target = guestLookupTarget(hostname);
1119
+ if (target) return original.call(dns, target, { ...guestLookupOptions(opts), all: true }, (error, addresses) => {
1120
+ if (error) return cb(Object.assign(error, { hostname }));
1121
+ let a;
1122
+ try { a = guestLookupAnswer(hostname, opts, addresses); }
1123
+ catch (failure) { return cb(failure); }
1124
+ if (Array.isArray(a)) cb(null, a); else cb(null, a.address, a.family);
1125
+ });
1099
1126
  const a = worldLookupAnswer(opts);
1100
1127
  process.nextTick(() => (Array.isArray(a) ? cb(null, a) : cb(null, a.address, a.family)));
1101
1128
  };
@@ -1110,7 +1137,11 @@ function patchedPromisesLookup(original) {
1110
1137
  return async function patchedDnsPromisesLookup(hostname, options) {
1111
1138
  const pending = lookupWaitsForClaims(hostname);
1112
1139
  if (pending) await pending;
1113
- return worldResolves(hostname) ? worldLookupAnswer(options) : original.call(dns.promises, hostname, options);
1140
+ if (!worldResolves(hostname)) return original.call(dns.promises, hostname, options);
1141
+ const target = guestLookupTarget(hostname);
1142
+ if (!target) return worldLookupAnswer(options);
1143
+ const addresses = await original.call(dns.promises, target, { ...guestLookupOptions(options), all: true });
1144
+ return guestLookupAnswer(hostname, options, addresses);
1114
1145
  };
1115
1146
  }
1116
1147
 
package/inject.cjs CHANGED
@@ -1037,7 +1037,9 @@ function isTwinOriginHost(host) {
1037
1037
  // public name gets. The address is one of the documentation ranges (RFC 5737's 203.0.113.0/24, RFC 3849's
1038
1038
  // 2001:db8::/32): public-shaped, never private, and routed nowhere, so nothing reaches a host by it; the request by name
1039
1039
  // is routed as every other one is, and a socket dialled to the address itself is refused with the reason. Every other
1040
- // name is the real resolver's, unchanged.
1040
+ // name is the real resolver's, unchanged. A browser Node guest has only its
1041
+ // engine's address resolver: routed names resolve the actual HTTP hop below,
1042
+ // never a documentation address on which that engine cannot connect.
1041
1043
  const WORLD_ADDRESS = { 4: '203.0.113.7', 6: '2001:db8::7' };
1042
1044
  function worldResolves(hostname) {
1043
1045
  const host = String(hostname || '').toLowerCase().replace(/\.$/, '');
@@ -1052,6 +1054,23 @@ function worldLookupAnswer(options) {
1052
1054
  const all = !!(options && typeof options === 'object' && options.all);
1053
1055
  return all ? families.map((f) => ({ address: WORLD_ADDRESS[f], family: f })) : { address: WORLD_ADDRESS[families[0]], family: families[0] };
1054
1056
  }
1057
+ function guestLookupTarget(hostname) {
1058
+ if (!process.versions.webcontainer) return null;
1059
+ const routed = resolveTwin(String(hostname).toLowerCase().replace(/\.$/, ''), MAP);
1060
+ if (!routed) return null;
1061
+ const endpoint = localGuestProxy() || new URL(routed.origin);
1062
+ return endpoint.hostname.replace(/^\[|\]$/g, '');
1063
+ }
1064
+ function guestLookupOptions(options) {
1065
+ return typeof options === 'number' ? { family: options } : options || {};
1066
+ }
1067
+ function guestLookupAnswer(hostname, options, addresses) {
1068
+ const opts = guestLookupOptions(options);
1069
+ const family = opts.family === 'IPv4' ? 4 : opts.family === 'IPv6' ? 6 : opts.family || 0;
1070
+ const available = addresses.filter(answer => !family || answer.family === family);
1071
+ if (!available.length) throw Object.assign(new Error(`getaddrinfo ENOTFOUND ${hostname}`), { code: 'ENOTFOUND', errno: -3008, syscall: 'getaddrinfo', hostname });
1072
+ return opts.all ? available : available[0];
1073
+ }
1055
1074
  /** Whether a lookup of `hostname` waits for the claiming twins' first read: never for a twin's own origin, whose
1056
1075
  * lookup that read itself makes (a claimer at a hostname origin, as `attach` gives one, would wait on itself). */
1057
1076
  function lookupWaitsForClaims(hostname) {
@@ -1096,6 +1115,14 @@ function patchedLookup(original) {
1096
1115
  if (typeof cb !== 'function') return original.apply(this, arguments);
1097
1116
  const answer = () => {
1098
1117
  if (!worldResolves(hostname)) return original.call(dns, hostname, opts ?? {}, cb);
1118
+ const target = guestLookupTarget(hostname);
1119
+ if (target) return original.call(dns, target, { ...guestLookupOptions(opts), all: true }, (error, addresses) => {
1120
+ if (error) return cb(Object.assign(error, { hostname }));
1121
+ let a;
1122
+ try { a = guestLookupAnswer(hostname, opts, addresses); }
1123
+ catch (failure) { return cb(failure); }
1124
+ if (Array.isArray(a)) cb(null, a); else cb(null, a.address, a.family);
1125
+ });
1099
1126
  const a = worldLookupAnswer(opts);
1100
1127
  process.nextTick(() => (Array.isArray(a) ? cb(null, a) : cb(null, a.address, a.family)));
1101
1128
  };
@@ -1110,7 +1137,11 @@ function patchedPromisesLookup(original) {
1110
1137
  return async function patchedDnsPromisesLookup(hostname, options) {
1111
1138
  const pending = lookupWaitsForClaims(hostname);
1112
1139
  if (pending) await pending;
1113
- return worldResolves(hostname) ? worldLookupAnswer(options) : original.call(dns.promises, hostname, options);
1140
+ if (!worldResolves(hostname)) return original.call(dns.promises, hostname, options);
1141
+ const target = guestLookupTarget(hostname);
1142
+ if (!target) return worldLookupAnswer(options);
1143
+ const addresses = await original.call(dns.promises, target, { ...guestLookupOptions(options), all: true });
1144
+ return guestLookupAnswer(hostname, options, addresses);
1114
1145
  };
1115
1146
  }
1116
1147
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@volter/world-core",
3
- "version": "3.0.50",
3
+ "version": "3.0.52",
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",