@bananacool467/authtics-host 0.1.0 → 0.1.4

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 CHANGED
@@ -1,10 +1,8 @@
1
1
  # Authtics Host
2
2
 
3
- Version 0.1.0
3
+ Version 0.1.4
4
4
  License: MIT
5
5
 
6
- **(NOTE: THIS IS AUTHTICS HOST'S FIRST RELEASE 🎉🎉🎉)**
7
-
8
6
  Authtics Host is a framework inspired by Next.js. Authtics Host supports SSR (Server-Side Rendering) and uses esbuild.
9
7
 
10
8
  **(NOTE: The short name for Authtics Host is HostJS or Host.js)**
@@ -107,11 +105,12 @@ export default function App() {
107
105
  return (
108
106
  <RouteMap>
109
107
  <Route at="/" statusCode={200} page={Index} />
110
- <RouteMap/>
108
+ </RouteMap>
111
109
  )
112
110
  }
113
111
  ```
114
112
  **(NOTE: You can change the `statusCode` to anything you want, the property is optional, it either gives 404 or 200 if the `statusCode` is missing.)**
113
+
115
114
  **(NOTE: To make an 404 page you can use:**
116
115
  ```tsx
117
116
  <Route statusCode={404} page={NotFound} />
@@ -152,13 +151,15 @@ Then when you run your project, you will get a page just saying **"Hello, World!
152
151
 
153
152
  The Developer Panel is what you could use to help you debug your code. The Developer Panel has **7 tabs**:
154
153
 
155
- **Console** — Shows current logs
156
- **Route** — Shows information about the current route
157
- **Webpage Info** — Shows information about the website/webpage
158
- **Network** — Shows the current ping and shows sent fetches from the client and shows received from the server after fetching
159
- **Client Info** — Shows information about your client's User Agent, OS and FPS
160
- **About Host** — Shows the current version of Authtics Host
161
- **Server Info** — Shows how much heap was used and how much CPU was used on the server and how much requests there were and how much users are currently on the site and how long the site has been up
154
+ **Console** — Shows current logs.
155
+ **Route** — Shows information about the current route.
156
+ **Webpage Info** — Shows information about the website/webpage.
157
+ **Network** — Shows the current ping and shows sent fetches from the client and shows received from the server after fetching.
158
+ **Client Info** — Shows information about your client's User Agent, OS and FPS.
159
+ **About Host** — Shows the current version of Authtics Host.
160
+ **Server Info** — Shows how much heap was used and how much CPU was used on the server and how much requests there were and how much users are currently on the site and how long the site has been up.
161
+
162
+ The information the Developer Panel shows outside of the tabs is just your **DAT** (Developer Access Token).
162
163
 
163
164
  **(NOTE: If you do not set DAT restriction (Which will be explained on how to set it up in the next section), you will only get access to the Console and Network tabs)**
164
165
 
package/dist/cli.js CHANGED
@@ -266,8 +266,26 @@ export default class App {
266
266
  const pathname = reqBody.pathname;
267
267
  const pagesDir = config_.autoPage === true ? path.join(process.cwd(), config_.autoPageDir || "") : undefined;
268
268
  const safePath = path.normalize(pathname).replace(/^(\.\.[\/\\])+/, '');
269
- const filePath = pagesDir ? path.join(pagesDir, safePath + ".tsx") : undefined;
270
- const fileExists = filePath ? fs.existsSync(filePath) : true;
269
+ let filePath = pagesDir ? path.join(pagesDir, (safePath !== "/" ? safePath : "index") + ".tsx") : undefined;
270
+ let fileExists = filePath ? fs.existsSync(filePath) : true;
271
+ const publicDir = config_.autoFile === true ? path.join(process.cwd(), config_.autoFileDir || "") : undefined;
272
+ if (publicDir && !fileExists) {
273
+ const staticPath = path.join(publicDir, pathname);
274
+ const safePath = path.resolve(staticPath);
275
+ if (safePath.startsWith(path.resolve(publicDir))) {
276
+ filePath = safePath;
277
+ fileExists = fs.existsSync(safePath) && fs.statSync(safePath).isFile();
278
+ }
279
+ }
280
+ if (pathname.startsWith("/api/") && pagesDir != null && !fileExists) {
281
+ const apiFile = path.join(pagesDir, `${pathname}.ts`);
282
+ const apiFileTsx = path.join(pagesDir, `${pathname}.tsx`);
283
+ filePath = fs.existsSync(apiFile) ? apiFile : fs.existsSync(apiFileTsx) ? apiFileTsx : apiFile;
284
+ fileExists = filePath == apiFileTsx ? fs.existsSync(apiFileTsx) : fs.existsSync(apiFile);
285
+ }
286
+ if (!fileExists) {
287
+ filePath = "File is unresolvable. Could be because it's not found.";
288
+ }
271
289
  res.writeHead(200, { "Content-Type": "application/json" });
272
290
  res.end(JSON.stringify({
273
291
  fileExists,
@@ -402,8 +420,24 @@ async function start() {
402
420
  return res.end(JSON.stringify({ error: e.message }));
403
421
  }
404
422
  }
405
- res.writeHead(404);
406
- return res.end(JSON.stringify({ error: `API route not found: ${pathname}` }));
423
+ const notFoundPath = path.join(__dirname, '404.js');
424
+ if (fs.existsSync(notFoundPath)) {
425
+ try {
426
+ let html = await renderPage(notFoundPath, url, actuallyShowPanel, compiler, hotReload, autoPaging, config.autoPageDir, (routes.get("APP_TSX") || ""));
427
+ res.setHeader("Content-Type", "text/html");
428
+ res.writeHead(404);
429
+ html = html.replace("<script>", "<script>\nwindow.__status_code__ = 404;");
430
+ res.end(html);
431
+ }
432
+ catch (e) {
433
+ res.writeHead(404);
434
+ res.end(`<html><head></head><body><center><b>404</b> | Not found: ${url}</center></body></html>`);
435
+ }
436
+ }
437
+ else {
438
+ res.writeHead(404);
439
+ res.end(`<html><head></head><body><center><b>404</b> | Not found: ${url}</center></body></html>`);
440
+ }
407
441
  }
408
442
  const urlPath = pathname === "/" ? "/index" : pathname;
409
443
  const tsxPath = pagesDir ? path.join(pagesDir, `${urlPath}.tsx`) : undefined;
package/dist/devPanel.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import React, { useState, useEffect, useRef } from 'react';
3
- import { ShieldCheck, CircleX, ChevronDown, ChevronUp, Bug, AlertTriangle, Info, ArrowLeft, Wifi, Terminal, Route, Globe, ChevronRight, ChevronLeft, Server, TriangleAlert, Eye } from 'lucide-react';
3
+ import { ShieldCheck, CircleX, ChevronDown, ChevronUp, Bug, AlertTriangle, Info, ArrowLeft, Wifi, Terminal, Route, Globe, ChevronRight, ChevronLeft, Server, TriangleAlert, Eye, Zap } from 'lucide-react';
4
4
  import Prism from 'prismjs';
5
5
  import 'prismjs/components/prism-javascript';
6
6
  Prism.languages.javascript['builtin'] = /\b(window|document|console|navigator|localStorage|sessionStorage|fetch|Promise|setTimeout|setInterval|clearTimeout|clearInterval|requestAnimationFrame|Math|JSON|Object|Array|String|Number|Boolean|Date|RegExp|Error|Map|Set|Symbol|Proxy|Reflect|performance|history|location|screen|crypto|indexedDB|alert|confirm|prompt)\b/;
@@ -63,7 +63,7 @@ function Sparkline({ data, color, label, unit }) {
63
63
  return _jsx("circle", { cx: last[0], cy: last[1], r: "2.5", fill: color });
64
64
  })()] }))] })] }));
65
65
  }
66
- function installNetworkInterceptor(onFetch, setFetch, onBytesClient, onBytesServer) {
66
+ function installNetworkInterceptor(onFetch, setFetch, onEventSource, setEventSource, onWebSocket, setWebSocket, onResource, setResource, onBytesClient, onBytesServer) {
67
67
  if (window.__authtics_network_intercepted__)
68
68
  return;
69
69
  window.__authtics_network_intercepted__ = true;
@@ -100,6 +100,142 @@ function installNetworkInterceptor(onFetch, setFetch, onBytesClient, onBytesServ
100
100
  throw e;
101
101
  }
102
102
  };
103
+ const OriginalWebSocket = window.WebSocket;
104
+ window.WebSocket = function (url, protocols) {
105
+ fetchId++;
106
+ const savedId = fetchId;
107
+ const ws = new OriginalWebSocket(url, protocols);
108
+ if (url.includes('__authtics'))
109
+ return ws;
110
+ onWebSocket({
111
+ url,
112
+ status: 'Connecting...',
113
+ id: savedId,
114
+ type: "WebSocket"
115
+ });
116
+ ws.addEventListener('open', () => {
117
+ setWebSocket({
118
+ url,
119
+ status: 'Connected',
120
+ id: savedId,
121
+ type: "WebSocket"
122
+ });
123
+ });
124
+ ws.addEventListener('close', () => {
125
+ setWebSocket({
126
+ url,
127
+ status: 'Disconnected',
128
+ id: savedId,
129
+ type: "WebSocket"
130
+ });
131
+ });
132
+ ws.addEventListener('message', (event) => {
133
+ const bytes = new Blob([event.data]).size;
134
+ onBytesServer(bytes);
135
+ setWebSocket({
136
+ url,
137
+ status: 'Connected',
138
+ id: savedId,
139
+ type: "WebSocket"
140
+ });
141
+ });
142
+ ws.addEventListener('error', () => {
143
+ const status = ws.readyState === OriginalWebSocket.CLOSED
144
+ ? 'Disconnected'
145
+ : 'Connection Failed';
146
+ setWebSocket({
147
+ url,
148
+ status,
149
+ id: savedId,
150
+ type: "WebSocket"
151
+ });
152
+ });
153
+ const OriginalSend = ws.send;
154
+ ws.send = function (data) {
155
+ let bytes = 0;
156
+ if (typeof data === 'string') {
157
+ bytes = new Blob([data]).size;
158
+ }
159
+ else if (data instanceof Blob) {
160
+ bytes = data.size;
161
+ }
162
+ else if (data instanceof ArrayBuffer || data instanceof SharedArrayBuffer) {
163
+ bytes = data.byteLength;
164
+ }
165
+ else if (ArrayBuffer.isView(data)) {
166
+ bytes = data.byteLength;
167
+ }
168
+ onBytesClient(bytes);
169
+ OriginalSend.call(this, data);
170
+ };
171
+ return ws;
172
+ };
173
+ Object.defineProperty(window.WebSocket, 'prototype', {
174
+ value: OriginalWebSocket.prototype,
175
+ writable: false
176
+ });
177
+ Object.assign(window.WebSocket, OriginalWebSocket);
178
+ const OriginalEventSource = window.EventSource;
179
+ window.EventSource = function (url, eventSourceInitDict) {
180
+ fetchId++;
181
+ const savedId = fetchId;
182
+ const es = new OriginalEventSource(url, eventSourceInitDict);
183
+ if (url.includes('__authtics'))
184
+ return es;
185
+ onEventSource({
186
+ url,
187
+ status: 'Connecting...',
188
+ id: savedId,
189
+ type: "EventSource"
190
+ });
191
+ es.addEventListener('open', () => {
192
+ setEventSource({
193
+ url,
194
+ status: 'Connected',
195
+ id: savedId,
196
+ type: "EventSource"
197
+ });
198
+ });
199
+ es.addEventListener('message', (event) => {
200
+ const bytes = new Blob([event.data]).size;
201
+ onBytesServer(bytes);
202
+ setEventSource({
203
+ url,
204
+ status: 'Connected',
205
+ id: savedId,
206
+ type: "EventSource"
207
+ });
208
+ });
209
+ es.addEventListener('error', () => {
210
+ const status = es.readyState === OriginalEventSource.CLOSED
211
+ ? 'Disconnected'
212
+ : 'Connection Failed';
213
+ setEventSource({
214
+ url,
215
+ status: status,
216
+ id: savedId,
217
+ type: "EventSource"
218
+ });
219
+ });
220
+ return es;
221
+ };
222
+ window.EventSource.prototype = OriginalEventSource.prototype;
223
+ Object.assign(window.EventSource, OriginalEventSource);
224
+ const queryImg = document.querySelectorAll('img');
225
+ const queryScript = document.querySelectorAll('script');
226
+ const queryLink = document.querySelectorAll('link');
227
+ queryImg.forEach((img) => {
228
+ if (img.src)
229
+ onResource({ url: img.src, type: 'img', id: fetchId++ });
230
+ });
231
+ queryScript.forEach((script) => {
232
+ if (script.src)
233
+ onResource({ url: script.src, type: 'script', id: fetchId++ });
234
+ });
235
+ queryLink.forEach((link) => {
236
+ if (link.href)
237
+ onResource({ url: link.href, type: 'link', id: fetchId++ });
238
+ });
103
239
  }
104
240
  function installConsoleInterceptor() {
105
241
  if (window.__authtics_intercepted__)
@@ -171,12 +307,18 @@ export default function DevPanel() {
171
307
  const [hasIssue, setHasIssue] = useState(false);
172
308
  const [ping__, setPing__] = useState(0);
173
309
  const [networkFetches, setNetworkFetches] = useState([]);
310
+ const [eventSources, setEventSources] = useState([]);
311
+ const [webSockets, setWebSockets] = useState([]);
312
+ const [resourcesFound, setResourcesFound] = useState([]);
174
313
  const [status, setStatus] = useState(200);
175
314
  const [code, setCode] = useState('');
176
315
  const [pathName, setPathName] = useState(undefined);
177
316
  const [hostName, setHostName] = useState(undefined);
178
317
  const [protocol, setProtocol] = useState(undefined);
179
318
  const [path, setPath] = useState(undefined);
319
+ const contextMenuTimeoutMobile = useRef(undefined);
320
+ const [cursorPosition, setCursorPosition] = useState({ x: 0, y: 0 });
321
+ const [contextMenuShown, setContextMenuShown] = useState(false);
180
322
  const [isSsr, setIsSsr] = useState(false);
181
323
  const datRestrictionMissingRef = useRef(true);
182
324
  const cpuUsage = useRef(0);
@@ -366,16 +508,26 @@ export default function DevPanel() {
366
508
  isSSR();
367
509
  userSettings();
368
510
  getHostVersion();
369
- setInterval(() => {
370
- getUsage();
371
- }, 250);
372
511
  setInterval(() => {
373
512
  update();
513
+ getUsage();
374
514
  }, 500);
375
515
  }
376
516
  }, 250);
377
517
  }, 250);
378
518
  }, []);
519
+ const datTouchStart = (e) => {
520
+ e.preventDefault();
521
+ setCursorPosition({ x: e.clientX || e.touches[0].clientX, y: e.clientY || e.touches[0].clientY });
522
+ contextMenuTimeoutMobile.current = setTimeout(() => {
523
+ setContextMenuShown(true);
524
+ clearTimeout(contextMenuTimeoutMobile.current);
525
+ }, 1000);
526
+ };
527
+ const datTouchEnd = (e) => {
528
+ e.preventDefault();
529
+ clearTimeout(contextMenuTimeoutMobile.current);
530
+ };
379
531
  const restart = async () => {
380
532
  const resp = await fetch('/__authtics_host_apis__/restart', {
381
533
  method: 'POST',
@@ -454,7 +606,7 @@ export default function DevPanel() {
454
606
  }, []);
455
607
  useEffect(() => {
456
608
  installConsoleInterceptor();
457
- installNetworkInterceptor((f) => setNetworkFetches(prev => [...prev.slice(-49), f]), (f) => setNetworkFetches(prev => prev.map(p => p.id === f.id ? f : p)), (sent) => {
609
+ installNetworkInterceptor((f) => setNetworkFetches(prev => [...prev.slice(-49), f]), (f) => setNetworkFetches(prev => prev.map(p => p.id === f.id ? f : p)), (f) => setEventSources(prev => [...prev.slice(-49), f]), (f) => setEventSources(prev => prev.map(p => p.id === f.id ? f : p)), (f) => setWebSockets(prev => [...prev.slice(-49), f]), (f) => setWebSockets(prev => prev.map(p => p.id === f.id ? f : p)), (f) => setResourcesFound(prev => [...prev.slice(-49), f]), (f) => setResourcesFound(prev => prev.map(p => p.id === f.id ? f : p)), (sent) => {
458
610
  pendingSent.current += sent;
459
611
  }, (received) => {
460
612
  pendingReceived.current += received;
@@ -718,7 +870,7 @@ export default function DevPanel() {
718
870
  border: '1px solid #eee',
719
871
  fontSize: '12px',
720
872
  color: '#333',
721
- }, children: [_jsx("span", { children: "Ping" }), _jsx("span", { style: { color: ping__ < 100 ? '#16a34a' : ping__ < 300 ? '#d97706' : '#e53e3e', fontFamily: 'monospace' }, children: ping__ > 0 ? `${ping__}ms` : '??ms' })] }), datRestrictionMissing ? (_jsxs("span", { style: { display: 'flex', opacity: 0.5, fontSize: 10, justifyContent: 'center', alignItems: 'center', gap: '4px' }, children: [_jsx(Info, { size: 10 }), "this analytic is unavaliable. Set \"dat\" in the Authtics Host config to set restriction and then restart."] })) : (_jsx(_Fragment, {})), _jsx(Sparkline, { data: receivedHistory, color: "#3b82f6", label: "Received", unit: " bytes" }), _jsx(Sparkline, { data: sentHistory, color: "#16a34a", label: "Sent", unit: " bytes" }), networkFetches.length === 0
873
+ }, children: [_jsx("span", { children: "Ping" }), _jsx("span", { style: { color: ping__ < 100 ? '#16a34a' : ping__ < 300 ? '#d97706' : '#e53e3e', fontFamily: 'monospace' }, children: ping__ > 0 ? `${ping__}ms` : '??ms' })] }), datRestrictionMissing ? (_jsxs("span", { style: { display: 'flex', opacity: 0.5, fontSize: 10, justifyContent: 'center', alignItems: 'center', gap: '4px' }, children: [_jsx(Info, { size: 10 }), "this analytic is unavaliable. Set \"dat\" in the Authtics Host config to set restriction and then restart."] })) : (_jsx(_Fragment, {})), _jsx(Sparkline, { data: receivedHistory, color: "#3b82f6", label: "Received", unit: " bytes" }), _jsx(Sparkline, { data: sentHistory, color: "#16a34a", label: "Sent", unit: " bytes" }), _jsxs("span", { style: { fontSize: '15px', color: '#333', fontWeight: 'bold' }, children: ["Fetches \u2014 ", networkFetches.length, " total fetches"] }), networkFetches.length === 0
722
874
  ? _jsx("div", { style: { color: '#aaa', fontSize: '12px', padding: '4px 2px' }, children: "No network requests yet." })
723
875
  : [...networkFetches].reverse().map((f, i) => (_jsxs("div", { style: {
724
876
  background: '#fff',
@@ -738,7 +890,25 @@ export default function DevPanel() {
738
890
  obj___.innerText = f.response?.slice(0, 100) + "...";
739
891
  obj___.removeAttribute('expanded');
740
892
  e.currentTarget.innerText = `View more (${f.response ? (f.response.split('').length - 100) : 0} bytes hidden)`;
741
- } }, style: { padding: '8px 10px', borderRadius: '10px', background: '#34a8eb', color: '#fff', border: 'none', cursor: 'pointer', margin: '10px', textAlign: 'center', fontFamily: 'system-ui, sans-serif' }, children: ["View more (", f.response ? (f.response.split('').length - 100) : 0, " bytes hidden)"] })) : (_jsx(_Fragment, {}))) : (_jsx(_Fragment, {}))] }, i)))] })] })) : routeOpen ? (_jsxs(_Fragment, { children: [_jsxs("div", { style: {
893
+ } }, style: { padding: '8px 10px', borderRadius: '10px', background: '#34a8eb', color: '#fff', border: 'none', cursor: 'pointer', margin: '10px', textAlign: 'center', fontFamily: 'system-ui, sans-serif' }, children: ["View more (", f.response ? (f.response.split('').length - 100) : 0, " bytes hidden)"] })) : (_jsx(_Fragment, {}))) : (_jsx(_Fragment, {}))] }, i))), _jsx("span", { style: { fontSize: '15px', color: '#333', fontWeight: 'bold' }, children: "Active connections" }), eventSources.length === 0 ? (_jsx("div", { style: { color: '#aaa', fontSize: '12px', padding: '4px 2px' }, children: "No active connections." })) :
894
+ [...eventSources, ...webSockets].reverse().map((es, i) => (_jsx("div", { style: {
895
+ background: '#fff',
896
+ display: 'flex',
897
+ flexDirection: 'column',
898
+ borderRadius: '10px',
899
+ border: '1px solid #eee',
900
+ fontSize: '11px',
901
+ fontFamily: 'monospace'
902
+ }, children: _jsxs("div", { style: { display: 'flex', justifyContent: 'space-between', gap: '8px', padding: '6px 10px' }, children: [_jsxs("span", { style: { color: '#3b82f6', display: 'flex', gap: '4px', justifyContent: 'center', alignItems: 'center' }, children: [es.type === "EventSource" ? _jsx(Zap, { color: "green", size: 12 }) : es.type === "WebSocket" ? _jsx(Globe, { color: "green", size: 12 }) : _jsx(_Fragment, {}), es.type === "EventSource" ? "Event Source" : es.type === "WebSocket" ? "Web Socket" : "???"] }), _jsx("span", { style: { flex: 1, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap', color: '#333' }, children: es.url }), _jsx("span", { style: { color: es.status === 'Connected' ? '#16a34a' : es.status === 'Disconnected' ? '#e53e3e' : 'orange' }, children: es.status === 'Connected' ? 'Active' : es.status === 'Disconnected' ? 'Disconnected' : es.status === 'Connecting...' ? '...' : es.status === 'Connection Failed' ? 'Failed' : 'Unknown' })] }) }, i))), _jsxs("span", { style: { fontSize: '15px', color: '#333', fontWeight: 'bold' }, children: ["Resources Found \u2014 ", resourcesFound.length, " total resources"] }), resourcesFound.length === 0 ? (_jsx("div", { style: { color: '#aaa', fontSize: '12px', padding: '4px 2px' }, children: "No resources found." })) :
903
+ [...resourcesFound].reverse().map((r, i) => (_jsx("div", { style: {
904
+ background: '#fff',
905
+ display: 'flex',
906
+ flexDirection: 'column',
907
+ borderRadius: '10px',
908
+ border: '1px solid #eee',
909
+ fontSize: '11px',
910
+ fontFamily: 'monospace'
911
+ }, children: _jsxs("div", { style: { display: 'flex', justifyContent: 'space-between', gap: '8px', padding: '6px 10px' }, children: [_jsx("span", { style: { color: '#3b82f6', display: 'flex', gap: '4px', justifyContent: 'center', alignItems: 'center' }, children: r.type }), _jsx("span", { style: { flex: 1, overflow: 'hidden', color: '#333' }, children: r.url })] }) }, i)))] })] })) : routeOpen ? (_jsxs(_Fragment, { children: [_jsxs("div", { style: {
742
912
  padding: '6px 8px',
743
913
  borderBottom: '1px solid #ddd',
744
914
  background: '#fff',
@@ -162,23 +162,23 @@ export async function renderPage(tsxPath, reqUrl, showPanel = true, compiler = '
162
162
  }
163
163
  if (!clientCode || !serverCode) {
164
164
  const virtualServer = `
165
- import Page from ${JSON.stringify(tsxPath)};
166
165
  ${usesDevPanel ? `import DevPanel from ${JSON.stringify(devPanelPath)};` : ""}
166
+ import Page from ${JSON.stringify(tsxPath)};
167
167
  export default Page;
168
168
  ${usesDevPanel ? `export { DevPanel };` : ""}
169
169
  `;
170
170
  const virtualClient = `
171
171
  import React from "react";
172
172
  import { hydrateRoot } from "react-dom/client";
173
- import Page from ${JSON.stringify(tsxPath)};
174
173
  ${usesDevPanel ? `import DevPanel from ${JSON.stringify(devPanelPath)};` : ""}
174
+ import Page from ${JSON.stringify(tsxPath)};
175
175
 
176
- const rootEl = document.getElementById("root");
177
- if (rootEl) hydrateRoot(rootEl, React.createElement(Page));
178
176
  ${usesDevPanel ? `
179
177
  const panelEl = document.getElementById("authtics-dev-panel-root");
180
178
  if (panelEl) hydrateRoot(panelEl, React.createElement(DevPanel));
181
179
  ` : ""}
180
+ const rootEl = document.getElementById("root");
181
+ if (rootEl) hydrateRoot(rootEl, React.createElement(Page));
182
182
  `;
183
183
  if (compiler === 'babel') {
184
184
  serverCode = await buildWithBabel(tsxPath, virtualServer, 'node');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bananacool467/authtics-host",
3
- "version": "0.1.0",
3
+ "version": "0.1.4",
4
4
  "description": "A Next.js-inspired SSR framework for Node.js with TypeScript and JSX support.",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -36,7 +36,8 @@
36
36
  "hot-reload",
37
37
  "dev",
38
38
  "developer",
39
- "HostJS"
39
+ "HostJS",
40
+ "Host.js"
40
41
  ],
41
42
  "author": "bananacool467",
42
43
  "license": "MIT",
@@ -45,8 +46,6 @@
45
46
  "@babel/preset-env": "^7.29.0",
46
47
  "@babel/preset-react": "^7.28.5",
47
48
  "@babel/preset-typescript": "^7.28.5",
48
- "@types/babel__core": "^7.20.5",
49
- "@types/babel__preset-env": "^7.10.0",
50
49
  "esbuild": "^0.27.3",
51
50
  "jiti": "^2.6.1",
52
51
  "lucide-react": "^0.577.0",
@@ -62,6 +61,8 @@
62
61
  "@types/prismjs": "^1.26.6",
63
62
  "@types/react": "^19.2.14",
64
63
  "@types/react-dom": "^19.2.3",
65
- "@types/react-syntax-highlighter": "^15.5.13"
64
+ "@types/react-syntax-highlighter": "^15.5.13",
65
+ "@types/babel__core": "^7.20.5",
66
+ "@types/babel__preset-env": "^7.10.0"
66
67
  }
67
68
  }