@absolutejs/absolute 0.19.0-beta.1023 → 0.19.0-beta.1025
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/angular/browser.js +13 -17
- package/dist/angular/browser.js.map +3 -3
- package/dist/angular/components/core/streamingSlotRegistrar.js +1 -1
- package/dist/angular/components/core/streamingSlotRegistry.js +2 -2
- package/dist/angular/index.js +595 -267
- package/dist/angular/index.js.map +11 -8
- package/dist/angular/server.js +577 -249
- package/dist/angular/server.js.map +11 -8
- package/dist/build.js +827 -735
- package/dist/build.js.map +11 -10
- package/dist/cli/config/server.js +49 -42
- package/dist/cli/index.js +366 -9
- package/dist/client/index.js +34 -20
- package/dist/client/index.js.map +6 -6
- package/dist/index.js +899 -800
- package/dist/index.js.map +12 -11
- package/dist/islands/index.js +416 -95
- package/dist/islands/index.js.map +10 -7
- package/dist/react/browser.js +13 -17
- package/dist/react/browser.js.map +3 -3
- package/dist/react/index.js +484 -156
- package/dist/react/index.js.map +12 -9
- package/dist/react/server.js +69 -62
- package/dist/react/server.js.map +5 -5
- package/dist/src/cli/scripts/tunnelRelay.d.ts +9 -0
- package/dist/src/client/preserveIslandMarkup.d.ts +4 -1
- package/dist/src/core/angularServerModule.d.ts +1 -0
- package/dist/src/dev/tunnel/client.d.ts +20 -0
- package/dist/src/dev/tunnel/protocol.d.ts +85 -0
- package/dist/src/dev/tunnel/relay.d.ts +28 -0
- package/dist/src/utils/loadConfig.d.ts +4 -0
- package/dist/svelte/index.js +389 -61
- package/dist/svelte/index.js.map +11 -8
- package/dist/svelte/server.js +50 -43
- package/dist/svelte/server.js.map +3 -3
- package/dist/types/angular.d.ts +3 -0
- package/dist/types/build.d.ts +11 -0
- package/dist/types/globals.d.ts +0 -1
- package/dist/vue/browser.js +13 -17
- package/dist/vue/browser.js.map +3 -3
- package/dist/vue/index.js +477 -153
- package/dist/vue/index.js.map +12 -9
- package/dist/vue/server.js +50 -43
- package/dist/vue/server.js.map +3 -3
- package/package.json +2 -6
|
@@ -35275,7 +35275,6 @@ var ensureConfigCert = (host) => {
|
|
|
35275
35275
|
};
|
|
35276
35276
|
// src/constants.ts
|
|
35277
35277
|
var BASE_36_RADIX = 36;
|
|
35278
|
-
var BYTES_PER_KILOBYTE = 1024;
|
|
35279
35278
|
var CONFIG_DEFAULT_HOST = "config.absolute.localhost";
|
|
35280
35279
|
var CONFIG_DEFAULT_PORT = 4099;
|
|
35281
35280
|
var HTTP_STATUS_BAD_REQUEST = 400;
|
|
@@ -35410,61 +35409,69 @@ var pipeStreamWithHeadInjection = (stream, markup) => {
|
|
|
35410
35409
|
var pipeStreamWithIslandMarkerDetection = (stream, markup) => {
|
|
35411
35410
|
const encoder = new TextEncoder;
|
|
35412
35411
|
const decoder = new TextDecoder;
|
|
35413
|
-
const
|
|
35414
|
-
const
|
|
35415
|
-
if (
|
|
35416
|
-
controller.enqueue(encoder.encode(
|
|
35417
|
-
return { injected, pending: "" };
|
|
35412
|
+
const headLookbehind = CLOSING_HEAD_TAG.length - 1;
|
|
35413
|
+
const enqueue = (controller, text) => {
|
|
35414
|
+
if (text.length > 0) {
|
|
35415
|
+
controller.enqueue(encoder.encode(text));
|
|
35418
35416
|
}
|
|
35419
|
-
|
|
35420
|
-
|
|
35421
|
-
|
|
35422
|
-
|
|
35423
|
-
const next = `${pending.slice(0, injectAt)}${markup}${pending.slice(injectAt)}`;
|
|
35424
|
-
controller.enqueue(encoder.encode(next));
|
|
35425
|
-
return { injected: true, pending: "" };
|
|
35417
|
+
};
|
|
35418
|
+
const processHolding = (controller, held) => {
|
|
35419
|
+
if (!held.includes(ISLAND_MARKER)) {
|
|
35420
|
+
return { held, injected: false, pending: "", sawHead: true };
|
|
35426
35421
|
}
|
|
35427
|
-
|
|
35428
|
-
|
|
35429
|
-
pending: flushSafePendingText(controller, encoder, pending, lookbehind)
|
|
35430
|
-
};
|
|
35422
|
+
enqueue(controller, `${markup}${held}`);
|
|
35423
|
+
return { held: "", injected: true, pending: "", sawHead: true };
|
|
35431
35424
|
};
|
|
35432
|
-
const
|
|
35433
|
-
const
|
|
35434
|
-
if (
|
|
35435
|
-
|
|
35425
|
+
const processHead = (controller, pending) => {
|
|
35426
|
+
const headIndex = pending.indexOf(CLOSING_HEAD_TAG);
|
|
35427
|
+
if (headIndex < 0) {
|
|
35428
|
+
return {
|
|
35429
|
+
held: "",
|
|
35430
|
+
injected: false,
|
|
35431
|
+
pending: flushSafePendingText(controller, encoder, pending, headLookbehind),
|
|
35432
|
+
sawHead: false
|
|
35433
|
+
};
|
|
35436
35434
|
}
|
|
35437
|
-
controller.
|
|
35435
|
+
enqueue(controller, pending.slice(0, headIndex));
|
|
35436
|
+
return processHolding(controller, pending.slice(headIndex));
|
|
35438
35437
|
};
|
|
35439
|
-
const
|
|
35440
|
-
|
|
35441
|
-
|
|
35442
|
-
return
|
|
35438
|
+
const processChunk = (controller, state, chunk) => {
|
|
35439
|
+
if (state.injected) {
|
|
35440
|
+
enqueue(controller, chunk);
|
|
35441
|
+
return state;
|
|
35443
35442
|
}
|
|
35444
|
-
|
|
35445
|
-
|
|
35446
|
-
|
|
35447
|
-
|
|
35448
|
-
pending: processed.pending
|
|
35449
|
-
};
|
|
35443
|
+
if (!state.sawHead) {
|
|
35444
|
+
return processHead(controller, state.pending + chunk);
|
|
35445
|
+
}
|
|
35446
|
+
return processHolding(controller, state.held + chunk);
|
|
35450
35447
|
};
|
|
35451
|
-
const
|
|
35452
|
-
const
|
|
35453
|
-
|
|
35454
|
-
|
|
35455
|
-
|
|
35456
|
-
|
|
35448
|
+
const finishMarkerStream = (controller, state) => {
|
|
35449
|
+
const tail = decoder.decode();
|
|
35450
|
+
const remainder = state.injected ? tail : (state.sawHead ? state.held : state.pending) + tail;
|
|
35451
|
+
enqueue(controller, remainder);
|
|
35452
|
+
controller.close();
|
|
35453
|
+
};
|
|
35454
|
+
const runMarkerLoop = (controller, reader) => {
|
|
35455
|
+
const consumeNext = async (state) => {
|
|
35456
|
+
const { done, value } = await readStreamChunk(reader);
|
|
35457
|
+
if (done || !value) {
|
|
35458
|
+
return state;
|
|
35457
35459
|
}
|
|
35458
|
-
return
|
|
35460
|
+
return consumeNext(processChunk(controller, state, streamChunkToString(value, decoder)));
|
|
35459
35461
|
};
|
|
35460
|
-
return
|
|
35462
|
+
return consumeNext({
|
|
35463
|
+
held: "",
|
|
35464
|
+
injected: false,
|
|
35465
|
+
pending: "",
|
|
35466
|
+
sawHead: false
|
|
35467
|
+
});
|
|
35461
35468
|
};
|
|
35462
35469
|
return new ReadableStream({
|
|
35463
35470
|
async start(controller) {
|
|
35464
35471
|
const reader = stream.getReader();
|
|
35465
35472
|
try {
|
|
35466
|
-
const
|
|
35467
|
-
|
|
35473
|
+
const finalState = await runMarkerLoop(controller, reader);
|
|
35474
|
+
finishMarkerStream(controller, finalState);
|
|
35468
35475
|
} catch (error) {
|
|
35469
35476
|
controller.error(error);
|
|
35470
35477
|
}
|
package/dist/cli/index.js
CHANGED
|
@@ -55,6 +55,16 @@ var init_constants = __esm(() => {
|
|
|
55
55
|
TWO_THIRDS = 2 / 3;
|
|
56
56
|
});
|
|
57
57
|
|
|
58
|
+
// src/dev/tunnel/protocol.ts
|
|
59
|
+
var TUNNEL_CONTROL_PATH = "/__abs_tunnel/control", TUNNEL_FORWARDED_HOST_HEADER = "x-absolute-tunnel-host", decodeTunnelMessage = (raw) => {
|
|
60
|
+
try {
|
|
61
|
+
const parsed = JSON.parse(raw);
|
|
62
|
+
return parsed;
|
|
63
|
+
} catch {
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
}, encodeTunnelMessage = (message) => JSON.stringify(message);
|
|
67
|
+
|
|
58
68
|
// src/utils/getDurationString.ts
|
|
59
69
|
var getDurationString = (duration) => {
|
|
60
70
|
let durationString;
|
|
@@ -172658,14 +172668,337 @@ var init_typecheck = __esm(() => {
|
|
|
172658
172668
|
];
|
|
172659
172669
|
});
|
|
172660
172670
|
|
|
172671
|
+
// src/dev/tunnel/relay.ts
|
|
172672
|
+
var DEFAULT_RELAY_PORT = 8787, DEFAULT_REQUEST_TIMEOUT_MS = 30000, headersToObject = (headers) => {
|
|
172673
|
+
const out = {};
|
|
172674
|
+
headers.forEach((value, key) => {
|
|
172675
|
+
out[key] = value;
|
|
172676
|
+
});
|
|
172677
|
+
return out;
|
|
172678
|
+
}, startTunnelRelay = (options) => {
|
|
172679
|
+
const port = options.port ?? (Number(process.env.PORT) || DEFAULT_RELAY_PORT);
|
|
172680
|
+
const requestTimeoutMs = options.requestTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;
|
|
172681
|
+
let client = null;
|
|
172682
|
+
const pending = new Map;
|
|
172683
|
+
const publicSockets = new Map;
|
|
172684
|
+
const resolvePublicUrl = (request) => {
|
|
172685
|
+
if (options.publicUrl)
|
|
172686
|
+
return options.publicUrl.replace(/\/$/, "");
|
|
172687
|
+
const url = new URL(request.url);
|
|
172688
|
+
const host = request.headers.get("x-forwarded-host") ?? url.host;
|
|
172689
|
+
const proto = request.headers.get("x-forwarded-proto") ?? url.protocol.replace(":", "");
|
|
172690
|
+
return `${proto}://${host}`;
|
|
172691
|
+
};
|
|
172692
|
+
const isWebSocketUpgrade = (request) => request.headers.get("upgrade")?.toLowerCase() === "websocket";
|
|
172693
|
+
const server2 = Bun.serve({
|
|
172694
|
+
port,
|
|
172695
|
+
websocket: {
|
|
172696
|
+
close(ws) {
|
|
172697
|
+
if (ws.data.control) {
|
|
172698
|
+
if (client === ws)
|
|
172699
|
+
client = null;
|
|
172700
|
+
return;
|
|
172701
|
+
}
|
|
172702
|
+
publicSockets.delete(ws.data.id);
|
|
172703
|
+
client?.send(encodeTunnelMessage({ id: ws.data.id, type: "ws_close" }));
|
|
172704
|
+
},
|
|
172705
|
+
message(ws, raw) {
|
|
172706
|
+
if (!ws.data.control) {
|
|
172707
|
+
const binary = typeof raw !== "string";
|
|
172708
|
+
const bytes = typeof raw === "string" ? Buffer.from(raw, "utf8") : Buffer.from(raw);
|
|
172709
|
+
client?.send(encodeTunnelMessage({
|
|
172710
|
+
binary,
|
|
172711
|
+
dataBase64: bytes.toString("base64"),
|
|
172712
|
+
id: ws.data.id,
|
|
172713
|
+
type: "ws_data"
|
|
172714
|
+
}));
|
|
172715
|
+
return;
|
|
172716
|
+
}
|
|
172717
|
+
const message = decodeTunnelMessage(typeof raw === "string" ? raw : raw.toString());
|
|
172718
|
+
if (!message)
|
|
172719
|
+
return;
|
|
172720
|
+
switch (message.type) {
|
|
172721
|
+
case "ping":
|
|
172722
|
+
ws.send(encodeTunnelMessage({ type: "pong" }));
|
|
172723
|
+
break;
|
|
172724
|
+
case "response":
|
|
172725
|
+
case "error":
|
|
172726
|
+
pending.get(message.id)?.(message);
|
|
172727
|
+
break;
|
|
172728
|
+
case "ws_open_ack":
|
|
172729
|
+
if (!message.ok)
|
|
172730
|
+
publicSockets.get(message.id)?.close();
|
|
172731
|
+
break;
|
|
172732
|
+
case "ws_data": {
|
|
172733
|
+
const target = publicSockets.get(message.id);
|
|
172734
|
+
const bytes = Buffer.from(message.dataBase64, "base64");
|
|
172735
|
+
target?.send(message.binary ? bytes : bytes.toString("utf8"));
|
|
172736
|
+
break;
|
|
172737
|
+
}
|
|
172738
|
+
case "ws_close":
|
|
172739
|
+
publicSockets.get(message.id)?.close(message.code, message.reason);
|
|
172740
|
+
publicSockets.delete(message.id);
|
|
172741
|
+
break;
|
|
172742
|
+
default:
|
|
172743
|
+
break;
|
|
172744
|
+
}
|
|
172745
|
+
},
|
|
172746
|
+
open(ws) {
|
|
172747
|
+
if (ws.data.control) {
|
|
172748
|
+
client = ws;
|
|
172749
|
+
ws.send(encodeTunnelMessage({ publicUrl: options.publicUrl ?? "", type: "ready" }));
|
|
172750
|
+
return;
|
|
172751
|
+
}
|
|
172752
|
+
publicSockets.set(ws.data.id, ws);
|
|
172753
|
+
client?.send(encodeTunnelMessage({
|
|
172754
|
+
headers: ws.data.headers,
|
|
172755
|
+
id: ws.data.id,
|
|
172756
|
+
type: "ws_open",
|
|
172757
|
+
url: ws.data.url
|
|
172758
|
+
}));
|
|
172759
|
+
}
|
|
172760
|
+
},
|
|
172761
|
+
async fetch(request, srv) {
|
|
172762
|
+
const url = new URL(request.url);
|
|
172763
|
+
if (url.pathname === TUNNEL_CONTROL_PATH) {
|
|
172764
|
+
if (url.searchParams.get("token") !== options.token) {
|
|
172765
|
+
return new Response("Forbidden", { status: 403 });
|
|
172766
|
+
}
|
|
172767
|
+
const upgraded = srv.upgrade(request, { data: { control: true } });
|
|
172768
|
+
return upgraded ? undefined : new Response("Upgrade failed", { status: 426 });
|
|
172769
|
+
}
|
|
172770
|
+
if (!client) {
|
|
172771
|
+
return new Response("Tunnel offline: no dev client connected.", { status: 503 });
|
|
172772
|
+
}
|
|
172773
|
+
if (isWebSocketUpgrade(request)) {
|
|
172774
|
+
const id2 = crypto.randomUUID();
|
|
172775
|
+
const upgraded = srv.upgrade(request, {
|
|
172776
|
+
data: {
|
|
172777
|
+
control: false,
|
|
172778
|
+
headers: headersToObject(request.headers),
|
|
172779
|
+
id: id2,
|
|
172780
|
+
url: url.pathname + url.search
|
|
172781
|
+
}
|
|
172782
|
+
});
|
|
172783
|
+
return upgraded ? undefined : new Response("Upgrade failed", { status: 426 });
|
|
172784
|
+
}
|
|
172785
|
+
const id = crypto.randomUUID();
|
|
172786
|
+
const bodyBytes = ["GET", "HEAD"].includes(request.method) ? null : new Uint8Array(await request.arrayBuffer());
|
|
172787
|
+
const headers = headersToObject(request.headers);
|
|
172788
|
+
headers[TUNNEL_FORWARDED_HOST_HEADER] = resolvePublicUrl(request);
|
|
172789
|
+
const message = {
|
|
172790
|
+
headers,
|
|
172791
|
+
id,
|
|
172792
|
+
method: request.method,
|
|
172793
|
+
type: "request",
|
|
172794
|
+
url: url.pathname + url.search,
|
|
172795
|
+
...bodyBytes && bodyBytes.length > 0 ? { bodyBase64: Buffer.from(bodyBytes).toString("base64") } : {}
|
|
172796
|
+
};
|
|
172797
|
+
const responsePromise = new Promise((resolve14) => {
|
|
172798
|
+
pending.set(id, resolve14);
|
|
172799
|
+
});
|
|
172800
|
+
client.send(encodeTunnelMessage(message));
|
|
172801
|
+
const timeout = new Promise((resolve14) => setTimeout(() => resolve14({ id, message: "timeout", type: "error" }), requestTimeoutMs));
|
|
172802
|
+
const result = await Promise.race([responsePromise, timeout]);
|
|
172803
|
+
pending.delete(id);
|
|
172804
|
+
if (result.type === "error") {
|
|
172805
|
+
return new Response(`Tunnel error: ${result.message}`, { status: 504 });
|
|
172806
|
+
}
|
|
172807
|
+
if (result.type !== "response") {
|
|
172808
|
+
return new Response("Tunnel protocol error", { status: 502 });
|
|
172809
|
+
}
|
|
172810
|
+
return new Response(result.bodyBase64 ? Buffer.from(result.bodyBase64, "base64") : null, { headers: result.headers, status: result.status });
|
|
172811
|
+
}
|
|
172812
|
+
});
|
|
172813
|
+
console.info(`[tunnel-relay] listening on :${server2.port} (control ${TUNNEL_CONTROL_PATH})`);
|
|
172814
|
+
return server2;
|
|
172815
|
+
};
|
|
172816
|
+
var init_relay = () => {};
|
|
172817
|
+
|
|
172818
|
+
// src/cli/scripts/tunnelRelay.ts
|
|
172819
|
+
var exports_tunnelRelay = {};
|
|
172820
|
+
__export(exports_tunnelRelay, {
|
|
172821
|
+
tunnelRelay: () => tunnelRelay
|
|
172822
|
+
});
|
|
172823
|
+
var tunnelRelay = () => {
|
|
172824
|
+
const token = process.env.ABSOLUTE_TUNNEL_TOKEN;
|
|
172825
|
+
if (!token) {
|
|
172826
|
+
console.error("[tunnel-relay] ABSOLUTE_TUNNEL_TOKEN is required.");
|
|
172827
|
+
process.exit(1);
|
|
172828
|
+
}
|
|
172829
|
+
startTunnelRelay({
|
|
172830
|
+
port: Number(process.env.PORT) || undefined,
|
|
172831
|
+
publicUrl: process.env.ABSOLUTE_TUNNEL_PUBLIC_URL,
|
|
172832
|
+
token
|
|
172833
|
+
});
|
|
172834
|
+
};
|
|
172835
|
+
var init_tunnelRelay = __esm(() => {
|
|
172836
|
+
init_relay();
|
|
172837
|
+
});
|
|
172838
|
+
|
|
172661
172839
|
// src/cli/scripts/dev.ts
|
|
172662
172840
|
init_constants();
|
|
172663
|
-
init_startupBanner();
|
|
172664
172841
|
var {$: $2, env } = globalThis.Bun;
|
|
172665
172842
|
import { spawn as nodeSpawn } from "child_process";
|
|
172666
172843
|
import { createWriteStream, existsSync as existsSync5, readFileSync as readFileSync7 } from "fs";
|
|
172667
172844
|
import { resolve as resolve3 } from "path";
|
|
172668
172845
|
|
|
172846
|
+
// src/dev/tunnel/client.ts
|
|
172847
|
+
var RECONNECT_DELAY_MS = 2000;
|
|
172848
|
+
var controlSocketUrl = (relayUrl, token) => {
|
|
172849
|
+
const url = new URL(relayUrl);
|
|
172850
|
+
url.protocol = url.protocol === "https:" ? "wss:" : "ws:";
|
|
172851
|
+
url.pathname = TUNNEL_CONTROL_PATH;
|
|
172852
|
+
url.search = `?token=${encodeURIComponent(token)}`;
|
|
172853
|
+
return url.toString();
|
|
172854
|
+
};
|
|
172855
|
+
var STRIPPED_REQUEST_HEADERS = new Set(["host", "connection", "content-length", TUNNEL_FORWARDED_HOST_HEADER]);
|
|
172856
|
+
var startTunnelClient = (options) => {
|
|
172857
|
+
const publicUrl = options.relayUrl.replace(/\/$/, "");
|
|
172858
|
+
const localWsOrigin = options.localOrigin.replace(/^http/, "ws");
|
|
172859
|
+
let socket = null;
|
|
172860
|
+
let closed = false;
|
|
172861
|
+
let reconnectTimer = null;
|
|
172862
|
+
const localSockets = new Map;
|
|
172863
|
+
const sendFrameToRelay = (id, data, binary) => {
|
|
172864
|
+
const bytes = typeof data === "string" ? Buffer.from(data, "utf8") : data;
|
|
172865
|
+
const message = {
|
|
172866
|
+
binary,
|
|
172867
|
+
dataBase64: bytes.toString("base64"),
|
|
172868
|
+
id,
|
|
172869
|
+
type: "ws_data"
|
|
172870
|
+
};
|
|
172871
|
+
socket?.send(encodeTunnelMessage(message));
|
|
172872
|
+
};
|
|
172873
|
+
const openLocalWs = (id, url) => {
|
|
172874
|
+
const local = new WebSocket(`${localWsOrigin}${url}`);
|
|
172875
|
+
local.binaryType = "arraybuffer";
|
|
172876
|
+
const entry = { pending: [], ready: false, ws: local };
|
|
172877
|
+
localSockets.set(id, entry);
|
|
172878
|
+
local.addEventListener("open", () => {
|
|
172879
|
+
entry.ready = true;
|
|
172880
|
+
socket?.send(encodeTunnelMessage({ id, ok: true, type: "ws_open_ack" }));
|
|
172881
|
+
for (const frame of entry.pending) {
|
|
172882
|
+
local.send(frame.binary ? frame.bytes : frame.bytes.toString("utf8"));
|
|
172883
|
+
}
|
|
172884
|
+
entry.pending = [];
|
|
172885
|
+
});
|
|
172886
|
+
local.addEventListener("message", (event) => {
|
|
172887
|
+
if (typeof event.data === "string") {
|
|
172888
|
+
sendFrameToRelay(id, event.data, false);
|
|
172889
|
+
} else if (event.data instanceof ArrayBuffer) {
|
|
172890
|
+
sendFrameToRelay(id, Buffer.from(event.data), true);
|
|
172891
|
+
}
|
|
172892
|
+
});
|
|
172893
|
+
local.addEventListener("close", (event) => {
|
|
172894
|
+
localSockets.delete(id);
|
|
172895
|
+
socket?.send(encodeTunnelMessage({ code: event.code, id, type: "ws_close" }));
|
|
172896
|
+
});
|
|
172897
|
+
local.addEventListener("error", () => {
|
|
172898
|
+
if (!entry.ready) {
|
|
172899
|
+
socket?.send(encodeTunnelMessage({ error: "local ws failed", id, ok: false, type: "ws_open_ack" }));
|
|
172900
|
+
}
|
|
172901
|
+
});
|
|
172902
|
+
};
|
|
172903
|
+
const forwardFrameToLocal = (message) => {
|
|
172904
|
+
const entry = localSockets.get(message.id);
|
|
172905
|
+
if (!entry)
|
|
172906
|
+
return;
|
|
172907
|
+
const bytes = Buffer.from(message.dataBase64, "base64");
|
|
172908
|
+
if (!entry.ready) {
|
|
172909
|
+
entry.pending.push({ binary: message.binary, bytes });
|
|
172910
|
+
return;
|
|
172911
|
+
}
|
|
172912
|
+
entry.ws.send(message.binary ? bytes : bytes.toString("utf8"));
|
|
172913
|
+
};
|
|
172914
|
+
const handleRequest = async (message) => {
|
|
172915
|
+
const headers = {};
|
|
172916
|
+
for (const [key, value] of Object.entries(message.headers)) {
|
|
172917
|
+
if (!STRIPPED_REQUEST_HEADERS.has(key.toLowerCase()))
|
|
172918
|
+
headers[key] = value;
|
|
172919
|
+
}
|
|
172920
|
+
try {
|
|
172921
|
+
const response = await fetch(`${options.localOrigin}${message.url}`, {
|
|
172922
|
+
body: message.bodyBase64 ? Buffer.from(message.bodyBase64, "base64") : undefined,
|
|
172923
|
+
headers,
|
|
172924
|
+
method: message.method,
|
|
172925
|
+
redirect: "manual"
|
|
172926
|
+
});
|
|
172927
|
+
const bodyBytes = new Uint8Array(await response.arrayBuffer());
|
|
172928
|
+
const responseHeaders = {};
|
|
172929
|
+
response.headers.forEach((value, key) => {
|
|
172930
|
+
responseHeaders[key] = value;
|
|
172931
|
+
});
|
|
172932
|
+
const reply = {
|
|
172933
|
+
headers: responseHeaders,
|
|
172934
|
+
id: message.id,
|
|
172935
|
+
status: response.status,
|
|
172936
|
+
type: "response",
|
|
172937
|
+
...bodyBytes.length > 0 ? { bodyBase64: Buffer.from(bodyBytes).toString("base64") } : {}
|
|
172938
|
+
};
|
|
172939
|
+
socket?.send(encodeTunnelMessage(reply));
|
|
172940
|
+
} catch (error) {
|
|
172941
|
+
socket?.send(encodeTunnelMessage({
|
|
172942
|
+
id: message.id,
|
|
172943
|
+
message: error instanceof Error ? error.message : String(error),
|
|
172944
|
+
type: "error"
|
|
172945
|
+
}));
|
|
172946
|
+
}
|
|
172947
|
+
};
|
|
172948
|
+
const connect = () => {
|
|
172949
|
+
if (closed)
|
|
172950
|
+
return;
|
|
172951
|
+
socket = new WebSocket(controlSocketUrl(options.relayUrl, options.token));
|
|
172952
|
+
socket.addEventListener("message", (event) => {
|
|
172953
|
+
const message = decodeTunnelMessage(String(event.data));
|
|
172954
|
+
if (!message)
|
|
172955
|
+
return;
|
|
172956
|
+
switch (message.type) {
|
|
172957
|
+
case "request":
|
|
172958
|
+
handleRequest(message);
|
|
172959
|
+
break;
|
|
172960
|
+
case "ready":
|
|
172961
|
+
options.onReady?.(publicUrl);
|
|
172962
|
+
break;
|
|
172963
|
+
case "ping":
|
|
172964
|
+
socket?.send(encodeTunnelMessage({ type: "pong" }));
|
|
172965
|
+
break;
|
|
172966
|
+
case "ws_open":
|
|
172967
|
+
openLocalWs(message.id, message.url);
|
|
172968
|
+
break;
|
|
172969
|
+
case "ws_data":
|
|
172970
|
+
forwardFrameToLocal(message);
|
|
172971
|
+
break;
|
|
172972
|
+
case "ws_close":
|
|
172973
|
+
localSockets.get(message.id)?.ws.close();
|
|
172974
|
+
localSockets.delete(message.id);
|
|
172975
|
+
break;
|
|
172976
|
+
default:
|
|
172977
|
+
break;
|
|
172978
|
+
}
|
|
172979
|
+
});
|
|
172980
|
+
socket.addEventListener("close", () => {
|
|
172981
|
+
if (closed)
|
|
172982
|
+
return;
|
|
172983
|
+
reconnectTimer = setTimeout(connect, RECONNECT_DELAY_MS);
|
|
172984
|
+
});
|
|
172985
|
+
socket.addEventListener("error", () => {});
|
|
172986
|
+
};
|
|
172987
|
+
connect();
|
|
172988
|
+
return {
|
|
172989
|
+
publicUrl,
|
|
172990
|
+
close() {
|
|
172991
|
+
closed = true;
|
|
172992
|
+
if (reconnectTimer)
|
|
172993
|
+
clearTimeout(reconnectTimer);
|
|
172994
|
+
socket?.close();
|
|
172995
|
+
}
|
|
172996
|
+
};
|
|
172997
|
+
};
|
|
172998
|
+
|
|
172999
|
+
// src/cli/scripts/dev.ts
|
|
173000
|
+
init_startupBanner();
|
|
173001
|
+
|
|
172669
173002
|
// src/cli/interactive.ts
|
|
172670
173003
|
init_constants();
|
|
172671
173004
|
import { openSync } from "fs";
|
|
@@ -173037,13 +173370,18 @@ var setupHttpsCert = async () => {
|
|
|
173037
173370
|
}
|
|
173038
173371
|
await setupCertWithPrompt(ensureDevCert2, setupMkcert2);
|
|
173039
173372
|
};
|
|
173040
|
-
var resolveDevConfig = (configDev) =>
|
|
173041
|
-
|
|
173042
|
-
|
|
173043
|
-
|
|
173044
|
-
|
|
173045
|
-
|
|
173046
|
-
|
|
173373
|
+
var resolveDevConfig = (configDev) => {
|
|
173374
|
+
const relay = env.ABSOLUTE_TUNNEL_RELAY ?? configDev?.tunnel?.relay;
|
|
173375
|
+
const token = env.ABSOLUTE_TUNNEL_TOKEN ?? configDev?.tunnel?.token;
|
|
173376
|
+
return {
|
|
173377
|
+
host: env.ABSOLUTE_HOST ?? configDev?.host ?? "localhost",
|
|
173378
|
+
https: env.ABSOLUTE_HTTPS === "true" || configDev?.https === true,
|
|
173379
|
+
port: Number(env.ABSOLUTE_PORT) || Number(env.PORT) || configDev?.port || DEFAULT_PORT,
|
|
173380
|
+
portRange: Number(env.ABSOLUTE_PORT_RANGE) || configDev?.portRange || DEFAULT_PORT_RANGE,
|
|
173381
|
+
strictPort: env.ABSOLUTE_STRICT_PORT === "true" || configDev?.strictPort === true,
|
|
173382
|
+
...relay && token ? { tunnel: { relay, token } } : {}
|
|
173383
|
+
};
|
|
173384
|
+
};
|
|
173047
173385
|
var dev = async (serverEntry, configPath2) => {
|
|
173048
173386
|
let httpsEnabled = false;
|
|
173049
173387
|
let resolvedDev;
|
|
@@ -173078,7 +173416,7 @@ var dev = async (serverEntry, configPath2) => {
|
|
|
173078
173416
|
console.error(cliTag("\x1B[31m", String(err.message ?? err)));
|
|
173079
173417
|
process.exit(1);
|
|
173080
173418
|
});
|
|
173081
|
-
let port = initialPortProbe
|
|
173419
|
+
let { port } = initialPortProbe;
|
|
173082
173420
|
if (initialPortProbe.fellBack) {
|
|
173083
173421
|
const displayHost = resolvedDev.host === "0.0.0.0" ? "localhost" : resolvedDev.host;
|
|
173084
173422
|
console.log(cliTag("\x1B[33m", `Port ${resolvedDev.port} is in use, trying another one... \u2192 http://${displayHost}:${port}/`));
|
|
@@ -173123,11 +173461,24 @@ var dev = async (serverEntry, configPath2) => {
|
|
|
173123
173461
|
let cleaning = false;
|
|
173124
173462
|
let interactive = null;
|
|
173125
173463
|
let serverReady = false;
|
|
173464
|
+
let tunnelClient = null;
|
|
173465
|
+
const startTunnelIfConfigured = () => {
|
|
173466
|
+
if (tunnelClient || !resolvedDev.tunnel)
|
|
173467
|
+
return;
|
|
173468
|
+
tunnelClient = startTunnelClient({
|
|
173469
|
+
localOrigin: `http://localhost:${port}`,
|
|
173470
|
+
relayUrl: resolvedDev.tunnel.relay,
|
|
173471
|
+
token: resolvedDev.tunnel.token,
|
|
173472
|
+
onReady: (publicUrl) => process.stdout.write(` \x1B[32m\u279C\x1B[0m \x1B[1mPublic:\x1B[0m ${publicUrl}/
|
|
173473
|
+
`)
|
|
173474
|
+
});
|
|
173475
|
+
};
|
|
173126
173476
|
const checkServerReady = (value) => {
|
|
173127
173477
|
const chunk = value.toString();
|
|
173128
173478
|
if (!chunk.includes("Local:"))
|
|
173129
173479
|
return;
|
|
173130
173480
|
serverReady = true;
|
|
173481
|
+
startTunnelIfConfigured();
|
|
173131
173482
|
interactive?.showPrompt();
|
|
173132
173483
|
};
|
|
173133
173484
|
const RESTART_MARKER = "[abs:restart]";
|
|
@@ -173391,6 +173742,7 @@ var dev = async (serverEntry, configPath2) => {
|
|
|
173391
173742
|
});
|
|
173392
173743
|
if (interactive)
|
|
173393
173744
|
interactive.dispose();
|
|
173745
|
+
tunnelClient?.close();
|
|
173394
173746
|
if (paused)
|
|
173395
173747
|
sendSignal("SIGCONT");
|
|
173396
173748
|
killChildTree("SIGTERM");
|
|
@@ -175905,6 +176257,10 @@ if (command === "dev") {
|
|
|
175905
176257
|
sendTelemetryEvent("cli:command", { command });
|
|
175906
176258
|
const { setupMkcert: setupMkcert2 } = await Promise.resolve().then(() => (init_devCert(), exports_devCert));
|
|
175907
176259
|
setupMkcert2();
|
|
176260
|
+
} else if (command === "tunnel-relay") {
|
|
176261
|
+
sendTelemetryEvent("cli:command", { command });
|
|
176262
|
+
const { tunnelRelay: tunnelRelay2 } = await Promise.resolve().then(() => (init_tunnelRelay(), exports_tunnelRelay));
|
|
176263
|
+
tunnelRelay2();
|
|
175908
176264
|
} else {
|
|
175909
176265
|
const message = command ? `Unknown command: ${command}` : "No command specified";
|
|
175910
176266
|
console.error(message);
|
|
@@ -175922,5 +176278,6 @@ if (command === "dev") {
|
|
|
175922
176278
|
console.error(" prettier Run Prettier check (cached)");
|
|
175923
176279
|
console.error(" typecheck Run type checkers for all frameworks");
|
|
175924
176280
|
console.error(" telemetry Manage anonymous telemetry");
|
|
176281
|
+
console.error(" tunnel-relay Run the public reverse-tunnel relay (for webhook dev)");
|
|
175925
176282
|
process.exit(1);
|
|
175926
176283
|
}
|
package/dist/client/index.js
CHANGED
|
@@ -259,12 +259,20 @@ __export(exports_react, {
|
|
|
259
259
|
});
|
|
260
260
|
import { createElement } from "react";
|
|
261
261
|
import { hydrateRoot } from "react-dom/client";
|
|
262
|
-
var reactIslandRoots, isPropsRecord = (value) => typeof value === "object" && value !== null,
|
|
262
|
+
var reactIslandRoots, isPropsRecord = (value) => typeof value === "object" && value !== null, HOST_REACT_EXPANDO_PREFIXES, detachFromHostReactRoot = (element) => {
|
|
263
|
+
for (const key of Object.keys(element)) {
|
|
264
|
+
const isHostExpando = HOST_REACT_EXPANDO_PREFIXES.some((prefix) => key.startsWith(prefix));
|
|
265
|
+
if (!isHostExpando)
|
|
266
|
+
continue;
|
|
267
|
+
Reflect.deleteProperty(element, key);
|
|
268
|
+
}
|
|
269
|
+
}, isReactComponent = (value) => typeof value === "function", hydrateReactIsland = (component, element, props) => {
|
|
263
270
|
const existingRoot = reactIslandRoots.get(element);
|
|
264
271
|
if (existingRoot) {
|
|
265
272
|
existingRoot.render(isPropsRecord(props) ? createElement(component, props) : createElement(component));
|
|
266
273
|
return;
|
|
267
274
|
}
|
|
275
|
+
detachFromHostReactRoot(element);
|
|
268
276
|
if (!isPropsRecord(props)) {
|
|
269
277
|
reactIslandRoots.set(element, hydrateRoot(element, createElement(component)));
|
|
270
278
|
return;
|
|
@@ -273,6 +281,14 @@ var reactIslandRoots, isPropsRecord = (value) => typeof value === "object" && va
|
|
|
273
281
|
};
|
|
274
282
|
var init_react = __esm(() => {
|
|
275
283
|
reactIslandRoots = new WeakMap;
|
|
284
|
+
HOST_REACT_EXPANDO_PREFIXES = [
|
|
285
|
+
"__reactFiber$",
|
|
286
|
+
"__reactProps$",
|
|
287
|
+
"__reactContainer$",
|
|
288
|
+
"__reactEvents$",
|
|
289
|
+
"__reactListeners$",
|
|
290
|
+
"__reactHandles$"
|
|
291
|
+
];
|
|
276
292
|
});
|
|
277
293
|
|
|
278
294
|
// src/client/hydrators/svelte.ts
|
|
@@ -524,9 +540,12 @@ var initDominoAdapter = (platformServer) => {
|
|
|
524
540
|
return {
|
|
525
541
|
APP_BASE_HREF: common.APP_BASE_HREF,
|
|
526
542
|
bootstrapApplication: platformBrowser.bootstrapApplication,
|
|
543
|
+
Component: core.Component,
|
|
527
544
|
DomSanitizer: platformBrowser.DomSanitizer,
|
|
528
545
|
ENVIRONMENT_INITIALIZER: core.ENVIRONMENT_INITIALIZER,
|
|
529
546
|
inject: core.inject,
|
|
547
|
+
InjectionToken: core.InjectionToken,
|
|
548
|
+
NgComponentOutlet: common.NgComponentOutlet,
|
|
530
549
|
provideClientHydration: platformBrowser.provideClientHydration,
|
|
531
550
|
provideServerRendering: platformServer.provideServerRendering,
|
|
532
551
|
provideZonelessChangeDetection: core.provideZonelessChangeDetection,
|
|
@@ -782,9 +801,8 @@ var angularIslandSelector = "abs-angular-island", isAngularComponent = (value) =
|
|
|
782
801
|
const componentName = typeof component.name === "string" && component.name.length > 0 ? component.name : "AngularIsland";
|
|
783
802
|
return `${componentName}:${JSON.stringify(props)}`;
|
|
784
803
|
}, buildAngularIslandWrapperMetadata = async (component, islandId, wrapperKey) => {
|
|
785
|
-
const { Component, InjectionToken, inject } = await import("@angular/core");
|
|
786
|
-
const { NgComponentOutlet } = await import("@angular/common");
|
|
787
804
|
const deps = await getAngularDeps();
|
|
805
|
+
const { Component, InjectionToken, NgComponentOutlet, inject } = deps;
|
|
788
806
|
const selector = getAngularIslandSelector(islandId);
|
|
789
807
|
const propsToken = new InjectionToken(`${wrapperKey}:props`);
|
|
790
808
|
|
|
@@ -1014,13 +1032,6 @@ init_islands();
|
|
|
1014
1032
|
|
|
1015
1033
|
// src/client/preserveIslandMarkup.ts
|
|
1016
1034
|
init_islandMarkupAttributes();
|
|
1017
|
-
var getClaimMap = () => {
|
|
1018
|
-
if (typeof window === "undefined") {
|
|
1019
|
-
return null;
|
|
1020
|
-
}
|
|
1021
|
-
window.__ABS_CLAIMED_ISLAND_MARKUP__ ??= new Map;
|
|
1022
|
-
return window.__ABS_CLAIMED_ISLAND_MARKUP__;
|
|
1023
|
-
};
|
|
1024
1035
|
var getSnapshotMap = () => {
|
|
1025
1036
|
if (typeof window === "undefined") {
|
|
1026
1037
|
return null;
|
|
@@ -1079,19 +1090,22 @@ var preserveIslandMarkup = (props) => {
|
|
|
1079
1090
|
innerHTML: ""
|
|
1080
1091
|
};
|
|
1081
1092
|
}
|
|
1082
|
-
const claimMap = getClaimMap();
|
|
1083
1093
|
const snapshotMap = getSnapshotMap();
|
|
1084
1094
|
const signature = getIslandSignature(props);
|
|
1085
|
-
const
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1095
|
+
const snapshotCandidate = snapshotMap?.get(signature)?.[0];
|
|
1096
|
+
if (snapshotCandidate) {
|
|
1097
|
+
return snapshotCandidate;
|
|
1098
|
+
}
|
|
1099
|
+
const liveCandidate = Array.from(document.querySelectorAll('[data-island="true"]')).find((element) => isMatchingIslandElement(element, props));
|
|
1100
|
+
if (!liveCandidate) {
|
|
1101
|
+
return {
|
|
1102
|
+
attributes: getIslandMarkerAttributes(props),
|
|
1103
|
+
innerHTML: ""
|
|
1104
|
+
};
|
|
1091
1105
|
}
|
|
1092
1106
|
return {
|
|
1093
|
-
attributes:
|
|
1094
|
-
innerHTML:
|
|
1107
|
+
attributes: Object.fromEntries(liveCandidate.getAttributeNames().map((name) => [name, liveCandidate.getAttribute(name) ?? ""])),
|
|
1108
|
+
innerHTML: liveCandidate.innerHTML
|
|
1095
1109
|
};
|
|
1096
1110
|
};
|
|
1097
1111
|
|
|
@@ -1242,5 +1256,5 @@ export {
|
|
|
1242
1256
|
createIslandManifestResolver
|
|
1243
1257
|
};
|
|
1244
1258
|
|
|
1245
|
-
//# debugId=
|
|
1259
|
+
//# debugId=07B15BB8DBC2C0A764756E2164756E21
|
|
1246
1260
|
//# sourceMappingURL=index.js.map
|