@absolutejs/absolute 0.20.0-beta.66 → 0.20.0-beta.68

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.
@@ -1,7 +1,520 @@
1
1
  // @bun
2
+ var __defProp = Object.defineProperty;
3
+ var __returnValue = (v) => v;
4
+ function __exportSetter(name, newValue) {
5
+ this[name] = __returnValue.bind(null, newValue);
6
+ }
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, {
10
+ get: all[name],
11
+ enumerable: true,
12
+ configurable: true,
13
+ set: __exportSetter.bind(all, name)
14
+ });
15
+ };
16
+ var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
17
+
18
+ // src/constants.ts
19
+ var DEFAULT_PORT = 3000, HOURS_IN_DAY = 24, MILLISECONDS_IN_A_SECOND = 1000, MINUTES_IN_AN_HOUR = 60, SECONDS_IN_A_MINUTE = 60, MILLISECONDS_IN_A_MINUTE, MILLISECONDS_IN_A_DAY, TWO_THIRDS;
20
+ var init_constants = __esm(() => {
21
+ MILLISECONDS_IN_A_MINUTE = MILLISECONDS_IN_A_SECOND * SECONDS_IN_A_MINUTE;
22
+ MILLISECONDS_IN_A_DAY = MILLISECONDS_IN_A_SECOND * SECONDS_IN_A_MINUTE * MINUTES_IN_AN_HOUR * HOURS_IN_DAY;
23
+ TWO_THIRDS = 2 / 3;
24
+ });
25
+
26
+ // src/dev/bootLifecycle.ts
27
+ var getBootPhase = () => globalThis.__absoluteBootPhase;
28
+ var init_bootLifecycle = __esm(() => {
29
+ init_constants();
30
+ });
31
+
32
+ // src/dev/earlyListener.ts
33
+ var exports_earlyListener = {};
34
+ __export(exports_earlyListener, {
35
+ BOOT_STATUS_HEADER: () => BOOT_STATUS_HEADER,
36
+ bootStatusSnapshot: () => bootStatusSnapshot,
37
+ buildingResponse: () => buildingResponse,
38
+ installEarlyListenerServeGuard: () => installEarlyListenerServeGuard,
39
+ releaseEarlyListener: () => releaseEarlyListener,
40
+ startEarlyListener: () => startEarlyListener
41
+ });
42
+ var HTTP_SERVICE_UNAVAILABLE = 503, RETRY_AFTER_SECONDS = 2, BIND_RETRY_INTERVAL_MS = 250, BIND_RETRY_LIMIT = 40, POLL_INTERVAL_MS, NOSCRIPT_REFRESH_SECONDS = 10, BOOT_STATUS_HEADER = "X-Absolute-Boot", bindingPlaceholder = false, escapeHtml = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;"), bootStatusSnapshot = (startedAt) => {
43
+ const elapsedMs = Math.max(0, Date.now() - startedAt);
44
+ return {
45
+ elapsedMs,
46
+ elapsedSeconds: Math.floor(elapsedMs / MILLISECONDS_IN_A_SECOND),
47
+ phase: getBootPhase() ?? "starting",
48
+ status: "building"
49
+ };
50
+ }, buildingPage = (snapshot) => `<!doctype html>
51
+ <html lang="en">
52
+ <head>
53
+ <meta charset="utf-8">
54
+ <meta name="viewport" content="width=device-width, initial-scale=1">
55
+ <meta http-equiv="refresh" content="${NOSCRIPT_REFRESH_SECONDS}">
56
+ <title>Building\u2026</title>
57
+ <style>
58
+ :root{color-scheme:light dark}
59
+ body{margin:0;min-height:100vh;display:grid;place-items:center;font:15px/1.5 system-ui,-apple-system,"Segoe UI",sans-serif;background:#0f1115;color:#e6e8ee}
60
+ main{text-align:center;padding:2rem}
61
+ .spin{width:36px;height:36px;margin:0 auto 1rem;border:3px solid rgba(255,255,255,.15);border-top-color:#8ab4ff;border-radius:50%;animation:s 1s linear infinite}
62
+ @keyframes s{to{transform:rotate(360deg)}}
63
+ h1{font-size:1.15rem;font-weight:600;margin:0 0 .25rem}
64
+ p{margin:0;opacity:.6;font-size:.85rem}
65
+ code{font-family:ui-monospace,SFMono-Regular,Menlo,monospace}
66
+ </style>
67
+ </head>
68
+ <body>
69
+ <main>
70
+ <div class="spin" aria-hidden="true"></div>
71
+ <h1>Building\u2026 <span id="t">${snapshot.elapsedSeconds}</span>s</h1>
72
+ <p>AbsoluteJS dev server \xB7 <code id="p">${escapeHtml(snapshot.phase)}</code></p>
73
+ </main>
74
+ <script>
75
+ (function(){
76
+ var started=Date.now()-${snapshot.elapsedMs};
77
+ var t=document.getElementById('t');
78
+ setInterval(function(){t.textContent=String(Math.floor((Date.now()-started)/1000));},1000);
79
+ function poll(){
80
+ fetch(location.href,{cache:'no-store',headers:{accept:'application/json'}}).then(function(r){
81
+ if(r.headers.get('${BOOT_STATUS_HEADER.toLowerCase()}')!=='building'){location.reload();return;}
82
+ return r.json().then(function(j){if(j&&j.phase){document.getElementById('p').textContent=j.phase;}});
83
+ }).catch(function(){}).then(function(){setTimeout(poll,${POLL_INTERVAL_MS});});
84
+ }
85
+ setTimeout(poll,${POLL_INTERVAL_MS});
86
+ })();
87
+ </script>
88
+ </body>
89
+ </html>
90
+ `, buildingResponse = (request, startedAt) => {
91
+ const snapshot = bootStatusSnapshot(startedAt);
92
+ const headers = {
93
+ "Cache-Control": "no-store",
94
+ "Retry-After": String(RETRY_AFTER_SECONDS),
95
+ "X-Absolute-Boot": "building"
96
+ };
97
+ const isUpgrade = request.headers.get("upgrade")?.toLowerCase() === "websocket";
98
+ const accept = request.headers.get("accept") ?? "";
99
+ if (!isUpgrade && accept.includes("text/html")) {
100
+ headers["Content-Type"] = "text/html; charset=utf-8";
101
+ return new Response(buildingPage(snapshot), {
102
+ headers,
103
+ status: HTTP_SERVICE_UNAVAILABLE
104
+ });
105
+ }
106
+ if (!isUpgrade && accept.includes("application/json")) {
107
+ headers["Content-Type"] = "application/json; charset=utf-8";
108
+ return new Response(JSON.stringify(snapshot), {
109
+ headers,
110
+ status: HTTP_SERVICE_UNAVAILABLE
111
+ });
112
+ }
113
+ headers["Content-Type"] = "text/plain; charset=utf-8";
114
+ return new Response(`AbsoluteJS dev server is building (${snapshot.elapsedSeconds}s, ${snapshot.phase}). Retry shortly.
115
+ `, { headers, status: HTTP_SERVICE_UNAVAILABLE });
116
+ }, installEarlyListenerServeGuard = (port) => {
117
+ if (globalThis.__absoluteEarlyListenerServeGuard)
118
+ return;
119
+ const originalServe = Bun.serve;
120
+ const guardedServe = (serveOptions) => {
121
+ const requested = Number(serveOptions.port ?? port);
122
+ const listener = globalThis.__absoluteEarlyListener;
123
+ if (!bindingPlaceholder && listener && (requested === port || Number.isNaN(requested))) {
124
+ releaseEarlyListener();
125
+ }
126
+ return originalServe.call(Bun, serveOptions);
127
+ };
128
+ if (Reflect.set(Bun, "serve", guardedServe)) {
129
+ globalThis.__absoluteEarlyListenerServeGuard = true;
130
+ }
131
+ }, releaseEarlyListener = () => {
132
+ const listener = globalThis.__absoluteEarlyListener;
133
+ if (!listener)
134
+ return false;
135
+ const hadServer = listener.server !== null;
136
+ listener.release();
137
+ globalThis.__absoluteEarlyListener = undefined;
138
+ return hadServer;
139
+ }, startEarlyListener = (options) => {
140
+ const startedAt = Date.now();
141
+ let server = null;
142
+ let released = false;
143
+ let attempts = 0;
144
+ let retryTimer;
145
+ const tryBind = () => {
146
+ if (released)
147
+ return;
148
+ attempts += 1;
149
+ bindingPlaceholder = true;
150
+ try {
151
+ server = Bun.serve({
152
+ hostname: options.host,
153
+ port: options.port,
154
+ fetch: (request) => buildingResponse(request, startedAt),
155
+ ...options.tls ? { tls: options.tls } : {}
156
+ });
157
+ } catch {
158
+ if (attempts >= BIND_RETRY_LIMIT)
159
+ return;
160
+ retryTimer = setTimeout(tryBind, BIND_RETRY_INTERVAL_MS);
161
+ retryTimer.unref();
162
+ } finally {
163
+ bindingPlaceholder = false;
164
+ }
165
+ };
166
+ const release = () => {
167
+ if (released)
168
+ return;
169
+ released = true;
170
+ if (retryTimer)
171
+ clearTimeout(retryTimer);
172
+ const active = server;
173
+ server = null;
174
+ if (!active)
175
+ return;
176
+ try {
177
+ active.stop(true);
178
+ } catch {}
179
+ };
180
+ tryBind();
181
+ const listener = {
182
+ release,
183
+ startedAt,
184
+ get released() {
185
+ return released;
186
+ },
187
+ get server() {
188
+ return server;
189
+ }
190
+ };
191
+ globalThis.__absoluteEarlyListener = listener;
192
+ return listener;
193
+ };
194
+ var init_earlyListener = __esm(() => {
195
+ init_constants();
196
+ init_bootLifecycle();
197
+ POLL_INTERVAL_MS = RETRY_AFTER_SECONDS * MILLISECONDS_IN_A_SECOND;
198
+ });
199
+
200
+ // src/dev/devCert.ts
201
+ var exports_devCert = {};
202
+ __export(exports_devCert, {
203
+ ensureDevCert: () => ensureDevCert,
204
+ getDevCertificateAuthorityPath: () => getDevCertificateAuthorityPath,
205
+ hasCert: () => hasCert,
206
+ hasMkcert: () => hasMkcert,
207
+ loadDevCert: () => loadDevCert,
208
+ normalizeDevCertificateHosts: () => normalizeDevCertificateHosts,
209
+ setupMkcert: () => setupMkcert
210
+ });
211
+ import {
212
+ copyFileSync,
213
+ existsSync,
214
+ mkdirSync,
215
+ readFileSync,
216
+ rmSync
217
+ } from "fs";
218
+ import { X509Certificate } from "crypto";
219
+ import { isIP } from "net";
220
+ import { platform } from "os";
221
+ import { join } from "path";
222
+ var CERT_DIR, CERT_PATH, KEY_PATH, CERT_VALIDITY_DAYS = 365, DEFAULT_CERTIFICATE_HOSTS, CERTIFICATE_HOSTNAME_PATTERN, devLog = (msg) => console.log(`\x1B[2m${new Date().toLocaleTimeString()}\x1B[0m \x1B[36m[dev]\x1B[0m ${msg}`), devWarn = (msg) => console.log(`\x1B[2m${new Date().toLocaleTimeString()}\x1B[0m \x1B[33m[dev]\x1B[0m \x1B[33m${msg}\x1B[0m`), certFilesExist = () => existsSync(CERT_PATH) && existsSync(KEY_PATH), normalizeDevCertificateHosts = (hosts = []) => {
223
+ const normalized = new Set(DEFAULT_CERTIFICATE_HOSTS);
224
+ for (const host of hosts) {
225
+ const value = host.trim().toLowerCase();
226
+ if (!value || value === "0.0.0.0" || value === "::")
227
+ continue;
228
+ if (isIP(value) === 0 && !CERTIFICATE_HOSTNAME_PATTERN.test(value)) {
229
+ throw new TypeError(`Invalid development certificate host: ${host}`);
230
+ }
231
+ normalized.add(value);
232
+ }
233
+ return [...normalized];
234
+ }, certificateIsUsable = (hosts) => {
235
+ try {
236
+ const certPem = readFileSync(CERT_PATH, "utf-8");
237
+ const certificate = new X509Certificate(certPem);
238
+ if (new Date(certificate.validTo).getTime() <= Date.now())
239
+ return false;
240
+ return normalizeDevCertificateHosts(hosts).every((host) => isIP(host) ? certificate.checkIP(host) !== undefined : certificate.checkHost(host) !== undefined);
241
+ } catch {
242
+ return false;
243
+ }
244
+ }, hasMkcert = () => {
245
+ try {
246
+ const result = Bun.spawnSync(["mkcert", "-version"], {
247
+ stderr: "pipe",
248
+ stdout: "pipe"
249
+ });
250
+ return result.exitCode === 0;
251
+ } catch {
252
+ return false;
253
+ }
254
+ }, generateWithMkcert = (hosts = []) => {
255
+ const result = Bun.spawnSync([
256
+ "mkcert",
257
+ "-cert-file",
258
+ CERT_PATH,
259
+ "-key-file",
260
+ KEY_PATH,
261
+ ...normalizeDevCertificateHosts(hosts)
262
+ ], { stderr: "pipe", stdout: "pipe" });
263
+ if (result.exitCode !== 0) {
264
+ const err = new TextDecoder().decode(result.stderr);
265
+ throw new Error(`mkcert failed: ${err}`);
266
+ }
267
+ }, generateSelfSigned = (hosts = []) => {
268
+ const subjectAlternativeNames = normalizeDevCertificateHosts(hosts).map((host) => `${isIP(host) ? "IP" : "DNS"}:${host}`).join(",");
269
+ const proc = Bun.spawnSync([
270
+ "openssl",
271
+ "req",
272
+ "-x509",
273
+ "-newkey",
274
+ "ec",
275
+ "-pkeyopt",
276
+ "ec_paramgen_curve:prime256v1",
277
+ "-days",
278
+ String(CERT_VALIDITY_DAYS),
279
+ "-nodes",
280
+ "-keyout",
281
+ KEY_PATH,
282
+ "-out",
283
+ CERT_PATH,
284
+ "-subj",
285
+ "/CN=localhost",
286
+ "-addext",
287
+ `subjectAltName=${subjectAlternativeNames}`
288
+ ], { stderr: "pipe", stdout: "pipe" });
289
+ if (proc.exitCode !== 0) {
290
+ const err = new TextDecoder().decode(proc.stderr);
291
+ throw new Error(`openssl failed: ${err}`);
292
+ }
293
+ devLog("Using self-signed certificate \u2014 browser will show a one-time warning");
294
+ }, generateCert = (hosts = []) => {
295
+ if (hasMkcert()) {
296
+ generateWithMkcert(hosts);
297
+ } else {
298
+ generateSelfSigned(hosts);
299
+ }
300
+ }, ensureDevCert = (hosts = []) => {
301
+ mkdirSync(CERT_DIR, { recursive: true });
302
+ if (hasCert(hosts)) {
303
+ return { cert: CERT_PATH, key: KEY_PATH };
304
+ }
305
+ if (certFilesExist()) {
306
+ devLog("Certificate is expired or missing a required host, regenerating...");
307
+ }
308
+ try {
309
+ generateCert(hosts);
310
+ } catch (err) {
311
+ devWarn(`Failed to generate certificate: ${err instanceof Error ? err.message : err}`);
312
+ return null;
313
+ }
314
+ return { cert: CERT_PATH, key: KEY_PATH };
315
+ }, hasCert = (hosts = []) => certFilesExist() && certificateIsUsable(hosts), loadDevCert = (hosts = []) => {
316
+ const paths = ensureDevCert(hosts);
317
+ if (!paths)
318
+ return null;
319
+ try {
320
+ return {
321
+ cert: readFileSync(paths.cert, "utf-8"),
322
+ key: readFileSync(paths.key, "utf-8")
323
+ };
324
+ } catch {
325
+ return null;
326
+ }
327
+ }, commandExists = (cmd) => {
328
+ try {
329
+ const check = platform() === "win32" ? ["where", cmd] : ["which", cmd];
330
+ const result = Bun.spawnSync(check, {
331
+ stderr: "pipe",
332
+ stdout: "pipe"
333
+ });
334
+ return result.exitCode === 0;
335
+ } catch {
336
+ return false;
337
+ }
338
+ }, installMkcertDarwin = () => {
339
+ if (!commandExists("brew")) {
340
+ devWarn("Install Homebrew first: https://brew.sh");
341
+ return false;
342
+ }
343
+ devLog("Installing mkcert with Homebrew...");
344
+ const result = Bun.spawnSync(["brew", "install", "mkcert"], {
345
+ stderr: "pipe",
346
+ stdout: "pipe"
347
+ });
348
+ return result.exitCode === 0;
349
+ }, installMkcertLinux = () => {
350
+ const sudoOpts = {
351
+ stderr: "inherit",
352
+ stdin: "inherit",
353
+ stdout: "pipe"
354
+ };
355
+ if (commandExists("apt-get")) {
356
+ devLog("Installing mkcert (may prompt for password)...");
357
+ const result = Bun.spawnSync(["sudo", "apt-get", "install", "-y", "mkcert", "libnss3-tools"], sudoOpts);
358
+ if (result.exitCode === 0)
359
+ return true;
360
+ }
361
+ if (commandExists("dnf")) {
362
+ devLog("Installing mkcert (may prompt for password)...");
363
+ const result = Bun.spawnSync(["sudo", "dnf", "install", "-y", "mkcert"], sudoOpts);
364
+ if (result.exitCode === 0)
365
+ return true;
366
+ }
367
+ if (commandExists("pacman")) {
368
+ devLog("Installing mkcert (may prompt for password)...");
369
+ const result = Bun.spawnSync(["sudo", "pacman", "-S", "--noconfirm", "mkcert"], sudoOpts);
370
+ if (result.exitCode === 0)
371
+ return true;
372
+ }
373
+ devWarn("Could not install mkcert automatically.");
374
+ console.log(" See: https://github.com/FiloSottile/mkcert#installation");
375
+ return false;
376
+ }, installMkcertWin32 = () => {
377
+ if (commandExists("choco")) {
378
+ devLog("Installing mkcert with Chocolatey...");
379
+ const result = Bun.spawnSync(["choco", "install", "-y", "mkcert"], {
380
+ stderr: "pipe",
381
+ stdout: "pipe"
382
+ });
383
+ if (result.exitCode === 0)
384
+ return true;
385
+ }
386
+ if (commandExists("winget")) {
387
+ devLog("Installing mkcert with winget...");
388
+ const result = Bun.spawnSync(["winget", "install", "--id", "FiloSottile.mkcert", "-e"], { stderr: "pipe", stdout: "pipe" });
389
+ if (result.exitCode === 0)
390
+ return true;
391
+ }
392
+ devWarn("Could not install mkcert automatically.");
393
+ console.log(" See: https://github.com/FiloSottile/mkcert#installation");
394
+ return false;
395
+ }, installMkcert = () => {
396
+ const osPlatform = platform();
397
+ if (osPlatform === "darwin")
398
+ return installMkcertDarwin();
399
+ if (osPlatform === "linux")
400
+ return installMkcertLinux();
401
+ if (osPlatform === "win32")
402
+ return installMkcertWin32();
403
+ return false;
404
+ }, ensureMkcert = () => {
405
+ if (hasMkcert())
406
+ return true;
407
+ if (!installMkcert())
408
+ return false;
409
+ if (!hasMkcert()) {
410
+ devWarn("mkcert installed but not found in PATH. Restart your terminal and try again.");
411
+ return false;
412
+ }
413
+ return true;
414
+ }, isWSL = () => {
415
+ if (platform() !== "linux")
416
+ return false;
417
+ try {
418
+ return /microsoft|wsl/i.test(readFileSync("/proc/version", "utf-8"));
419
+ } catch {
420
+ return false;
421
+ }
422
+ }, runCapture = (cmd) => {
423
+ try {
424
+ const result = Bun.spawnSync(cmd, { stderr: "pipe", stdout: "pipe" });
425
+ if (result.exitCode !== 0)
426
+ return null;
427
+ const out = new TextDecoder().decode(result.stdout).trim();
428
+ return out || null;
429
+ } catch {
430
+ return null;
431
+ }
432
+ }, mkcertCaRoot = () => runCapture(["mkcert", "-CAROOT"]), getDevCertificateAuthorityPath = () => {
433
+ const caRoot = hasMkcert() ? mkcertCaRoot() : null;
434
+ const rootCertificate = caRoot ? join(caRoot, "rootCA.pem") : null;
435
+ if (rootCertificate && existsSync(rootCertificate))
436
+ return rootCertificate;
437
+ if (certFilesExist())
438
+ return CERT_PATH;
439
+ return null;
440
+ }, toWindowsPath = (linuxPath) => runCapture(["wslpath", "-w", linuxPath]), windowsTempDir = () => {
441
+ const winTemp = runCapture(["cmd.exe", "/c", "echo %TEMP%"]);
442
+ if (!winTemp)
443
+ return null;
444
+ return runCapture(["wslpath", "-u", winTemp]);
445
+ }, trustCaOnWindows = () => {
446
+ const caRoot = mkcertCaRoot();
447
+ if (!caRoot)
448
+ return false;
449
+ const rootCa = join(caRoot, "rootCA.pem");
450
+ if (!existsSync(rootCa))
451
+ return false;
452
+ const winTemp = windowsTempDir();
453
+ if (!winTemp)
454
+ return false;
455
+ const staged = join(winTemp, "absolutejs-mkcert-rootCA.crt");
456
+ try {
457
+ copyFileSync(rootCa, staged);
458
+ } catch {
459
+ return false;
460
+ }
461
+ const stagedWin = toWindowsPath(staged);
462
+ if (!stagedWin) {
463
+ rmSync(staged, { force: true });
464
+ return false;
465
+ }
466
+ const result = Bun.spawnSync([
467
+ "powershell.exe",
468
+ "-NoProfile",
469
+ "-Command",
470
+ `Import-Certificate -FilePath '${stagedWin}' -CertStoreLocation Cert:\\CurrentUser\\Root`
471
+ ], { stderr: "pipe", stdout: "pipe" });
472
+ rmSync(staged, { force: true });
473
+ return result.exitCode === 0;
474
+ }, setupMkcert = (hosts = []) => {
475
+ if (!ensureMkcert())
476
+ return false;
477
+ const installResult = Bun.spawnSync(["mkcert", "-install"], {
478
+ stderr: "pipe",
479
+ stdin: "inherit",
480
+ stdout: "pipe"
481
+ });
482
+ if (installResult.exitCode !== 0) {
483
+ devWarn("Failed to install local CA");
484
+ return false;
485
+ }
486
+ if (isWSL()) {
487
+ if (trustCaOnWindows()) {
488
+ devLog("Trusted the local CA in the Windows store \u2014 Chrome/Edge on Windows now accept dev HTTPS");
489
+ } else {
490
+ const caRoot = mkcertCaRoot();
491
+ const hint = caRoot ? toWindowsPath(join(caRoot, "rootCA.pem")) : null;
492
+ devWarn("Could not auto-trust the local CA on Windows; Windows browsers may warn.");
493
+ if (hint) {
494
+ console.log(` Run in PowerShell: Import-Certificate -FilePath "${hint}" -CertStoreLocation Cert:\\CurrentUser\\Root`);
495
+ }
496
+ }
497
+ }
498
+ rmSync(CERT_PATH, { force: true });
499
+ rmSync(KEY_PATH, { force: true });
500
+ mkdirSync(CERT_DIR, { recursive: true });
501
+ generateWithMkcert(hosts);
502
+ console.log("");
503
+ devLog("mkcert installed \u2014 HTTPS certificates are now locally trusted");
504
+ return true;
505
+ };
506
+ var init_devCert = __esm(() => {
507
+ CERT_DIR = join(process.cwd(), ".absolutejs");
508
+ CERT_PATH = join(CERT_DIR, "cert.pem");
509
+ KEY_PATH = join(CERT_DIR, "key.pem");
510
+ DEFAULT_CERTIFICATE_HOSTS = ["localhost", "127.0.0.1", "::1"];
511
+ CERTIFICATE_HOSTNAME_PATTERN = /^(?=.{1,253}$)(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)(?:\.(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?))*$/u;
512
+ });
513
+
2
514
  // src/dev/serverBootstrap.ts
3
- import { copyFileSync, existsSync, readdirSync, unlinkSync } from "fs";
4
- import { dirname, extname, join, resolve } from "path";
515
+ init_constants();
516
+ import { copyFileSync as copyFileSync2, existsSync as existsSync2, readdirSync, unlinkSync } from "fs";
517
+ import { dirname, extname, join as join2, resolve } from "path";
5
518
 
6
519
  // src/dev/serverEntryCopies.ts
7
520
  var ENTRY_COPY_OWNER_PATTERN = /^\.absolutejs-hmr-(\d+)-(?:bootstrap-)?\d+\.[^.]+$/;
@@ -33,7 +546,7 @@ if (!originalEntry) {
33
546
  throw new Error("ABSOLUTE_SERVER_ENTRY is required by the AbsoluteJS dev bootstrap");
34
547
  }
35
548
  var entryPath = resolve(originalEntry);
36
- if (!existsSync(entryPath)) {
549
+ if (!existsSync2(entryPath)) {
37
550
  throw new Error(`AbsoluteJS server entry does not exist: ${entryPath}`);
38
551
  }
39
552
  var entryDir = dirname(entryPath);
@@ -52,13 +565,13 @@ if (!isHotReevaluation) {
52
565
  }
53
566
  if (!isStaleAbsoluteServerEntryCopy(name))
54
567
  continue;
55
- removeEntryCopy(join(entryDir, name));
568
+ removeEntryCopy(join2(entryDir, name));
56
569
  }
57
570
  }
58
571
  var bootstrapSequence = (globalThis.__absoluteEntryBootstrapSequence ?? 0) + 1;
59
572
  globalThis.__absoluteEntryBootstrapSequence = bootstrapSequence;
60
- var bootstrapCopy = join(entryDir, `${copyPrefix}${process.pid}-bootstrap-${bootstrapSequence}${entryExtension}`);
61
- copyFileSync(entryPath, bootstrapCopy);
573
+ var bootstrapCopy = join2(entryDir, `${copyPrefix}${process.pid}-bootstrap-${bootstrapSequence}${entryExtension}`);
574
+ copyFileSync2(entryPath, bootstrapCopy);
62
575
  var entryCopies = globalThis.__absoluteEntryCopies ?? new Set;
63
576
  entryCopies.add(bootstrapCopy);
64
577
  globalThis.__absoluteEntryCopies = entryCopies;
@@ -70,4 +583,29 @@ if (!globalThis.__absoluteEntryCleanupRegistered) {
70
583
  }
71
584
  });
72
585
  }
586
+ if (!isHotReevaluation && !globalThis.__absoluteBunServer && process.env.ABSOLUTE_EARLY_LISTEN !== "0") {
587
+ const { startEarlyListener: startEarlyListener2, installEarlyListenerServeGuard: installEarlyListenerServeGuard2 } = await Promise.resolve().then(() => (init_earlyListener(), exports_earlyListener));
588
+ const earlyHost = process.env.ABSOLUTE_HOST ?? process.env.HOST ?? "localhost";
589
+ const earlyPort = Number(process.env.ABSOLUTE_PORT ?? process.env.PORT ?? DEFAULT_PORT);
590
+ const loadEarlyTls = async () => {
591
+ if (false)
592
+ ;
593
+ if (process.env.ABSOLUTE_HTTPS !== "true")
594
+ return null;
595
+ try {
596
+ const { loadDevCert: loadDevCert2 } = await Promise.resolve().then(() => (init_devCert(), exports_devCert));
597
+ return loadDevCert2();
598
+ } catch {
599
+ return null;
600
+ }
601
+ };
602
+ if (Number.isInteger(earlyPort) && earlyPort > 0) {
603
+ startEarlyListener2({
604
+ host: earlyHost,
605
+ port: earlyPort,
606
+ tls: await loadEarlyTls()
607
+ });
608
+ installEarlyListenerServeGuard2(earlyPort);
609
+ }
610
+ }
73
611
  await import(bootstrapCopy);