@bananacool467/authtics-host 0.2.5 → 0.2.7

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.
@@ -0,0 +1 @@
1
+ - [Node child-process test cleanup](node-child-process-tests.md) — a signaled child can have `exitCode === null`; check `signalCode` too.
@@ -0,0 +1,10 @@
1
+ ---
2
+ name: Node child-process test cleanup
3
+ description: Avoid hanging integration-test cleanup when a fixture server exits from a signal.
4
+ ---
5
+
6
+ When a Node child process is terminated by a signal, `exitCode` remains `null` and `signalCode` identifies how it exited. Treat either a non-null exit code or signal code as completion.
7
+
8
+ **Why:** Fixture-server tests can otherwise wait for an `exit` event that already fired and be cancelled when the event loop empties.
9
+
10
+ **How to apply:** In child-process test helpers, check both `exitCode` and `signalCode`, and register the exit listener before sending a termination signal.
package/README.md CHANGED
@@ -1,17 +1,11 @@
1
1
  # Authtics Host
2
2
 
3
- Version 0.2.5, License: MIT
3
+ Version 0.2.7, License: MIT
4
4
 
5
- Authtics Host is a web framework inspired by Next.js. Authtics Host supports SSR (Server-Side Rendering) and uses esbuild. This is not to be confused with auth platforms.
5
+ Authtics Host is a web framework inspired by Next.js. Authtics Host supports SSR (Server-Side Rendering), SSG (Static Site Generation), CSR (Client-Side Rendering) and SRTWS (Site Rendering Through WebSockets) and uses **Esbuild**. This is not to be confused with auth platforms.
6
6
 
7
7
  **(NOTE: The short name for Authtics Host is HostJS or Host.js)**
8
8
 
9
- **(From the Developer: I am having 1 small issue:**
10
-
11
- 1. **Web Socket Connections** are **not showing** in the DevPanel's Network tab
12
-
13
- **I need help fixing that)**
14
-
15
9
  ## Setting Up
16
10
 
17
11
  To get **Authtics Host** use:
@@ -51,7 +45,7 @@ import { defineConfig } from "@bananacool467/authtics-host";
51
45
 
52
46
  export default defineConfig({
53
47
  port: 8000,
54
- ssr: true,
48
+ renderType: 'ssr',
55
49
  devMode: true,
56
50
  autoFile: true,
57
51
  autoPage: true,
@@ -94,7 +88,7 @@ import { defineConfig } from "@bananacool467/authtics-host";
94
88
 
95
89
  export default defineConfig({
96
90
  port: 8000,
97
- ssr: true,
91
+ renderType: 'ssr',
98
92
  devMode: true,
99
93
  autoFile: false,
100
94
  autoPage: false
@@ -131,6 +125,36 @@ export default function Index () {
131
125
  }
132
126
  ```
133
127
 
128
+ ## Build Output Styles
129
+
130
+ HostJS supports two output layouts through `buildStyle` in `authtics_host.config.ts`.
131
+
132
+ - `default` (the default) keeps the existing `.authtics_host/` cache layout.
133
+ - `super` enables the Next.js-inspired `.hostjs/` layout with separated client/server bundler caches, route-cache files, route and middleware manifests, generated route type files, diagnostics metadata, and trace directories.
134
+
135
+ To opt in, add this to your existing `defineConfig({ ... })` object:
136
+
137
+ ```ts
138
+ buildStyle: "super"
139
+ ```
140
+
141
+ The setting is opt-in, so projects that do not specify it continue using `default`.
142
+
143
+ ## Build Triggers
144
+
145
+ HostJS supports two ways to trigger page bundle compilation using `buildTrigger` in `authtics_host.config.ts`.
146
+
147
+ - `default` (the default) compiles a TSX page on demand when a request needs it.
148
+ - `prebuilt` compiles discoverable TSX pages during Authtics Host startup, before the HTTP server begins listening. SSR pages are compiled without eagerly invoking their page components; SSG pages are rendered during startup so their static HTML is ready. Startup reports a prebuild error instead of opening the server if compilation (or SSG generation) fails.
149
+
150
+ Prebuilt mode scans the configured auto-page directory for TSX pages and also prebuilds a registered `app.registerApp(...)` entry when it points to an existing TSX file. API handlers and static files are not TSX renderer bundles, so they are not prebuilt by this option. The renderer reuses generated caches in both `default` and `super` build styles.
151
+
152
+ To opt in, add this to your existing `defineConfig({ ... })` object:
153
+
154
+ ```ts
155
+ buildTrigger: "prebuilt"
156
+ ```
157
+
134
158
  ## To Run The Project
135
159
 
136
160
  Make sure **Node 22** is installed:
@@ -152,9 +176,13 @@ node --experimental-strip-types index.ts
152
176
 
153
177
  Then when you run your project, you will get a page just saying **"Hello, World!"** and you should see a clickable Developer Panel at the bottom-right.
154
178
 
179
+ ![Result](assets/result.jpg)
180
+
155
181
  ## About The Developer Panel
156
182
 
157
- The Developer Panel is what you could use to help you debug your code. The Developer Panel has **7 tabs**:
183
+ ![Developer Panel](assets/dev_panel.jpg)
184
+
185
+ The Developer Panel is what you could use to help you debug your code. The Developer Panel has **8 tabs**:
158
186
 
159
187
  * **Console** — Shows current logs.
160
188
  * **Route** — Shows information about the current route.
@@ -163,6 +191,7 @@ The Developer Panel is what you could use to help you debug your code. The Devel
163
191
  * **Client Info** — Shows information about your client's User Agent, OS **(Operating System)** and FPS **(Frames Per Second)**.
164
192
  * **About Host** — Shows the current version of *Authtics Host*.
165
193
  * **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.
194
+ * **Panel Customization** — Customize the dev panel.
166
195
 
167
196
  The information the Developer Panel shows outside of the tabs is just your **DAT** (Developer Access Token).
168
197
 
@@ -186,6 +215,48 @@ and then create a file like `paused.tsx` and then inside `App.tsx`, import `Paus
186
215
  ```
187
216
  and if your using `autoPaging` then you just create a file named `_paused.tsx`.
188
217
 
218
+ ## Page Patching
219
+
220
+ Pages may fail to render in SSR if it uses `window` instead of assigning it to a **useState** while in a **useEffect** in *React*
221
+
222
+ You can fix this by adding this to your config file:
223
+ ```json
224
+ "patchForServer": true
225
+ ```
226
+
227
+ It makes a fake `window`, `document`, etc for SSR when building for Node. Which fixes the issue.
228
+
229
+ ## Browser API
230
+
231
+ You can set, delete and get cookies using Authtics Host's BrowserAPI (BAPI) feature. Example:
232
+
233
+ ```typescript
234
+ import {
235
+ Cookies
236
+ } from "@bananacool467/authtics-host";
237
+
238
+ const cookies = new Cookies();
239
+ // set
240
+ cookies.set("name", "value");
241
+ // get
242
+ const data = cookies.get("name");
243
+ // delete
244
+ cookies.del("name");
245
+ ```
246
+
247
+ You can also enable stuff on cookies, like:
248
+ * **Secure**
249
+ * **Max Age / Expires**
250
+ * **Same Site**
251
+
252
+ Example:
253
+ ```typescript
254
+ cookies.set("name", "value", true, "Lax", 2 * 24 * 60 * 60);
255
+ ```
256
+ * **Secure** is `true`
257
+ * **Same Site** is `Lax`
258
+ * **Max Age** is `2 * 24 * 60 * 60` (2 days)
259
+
189
260
  ## App APIs
190
261
 
191
262
  You can add APIs like `get`, `post`, `del` and `put`.
@@ -201,34 +272,72 @@ Then when you go to `/hi` you see:
201
272
  Hello!
202
273
  ```
203
274
 
204
- ## Notes about Authtics Host
205
-
206
- Since Authtics Host is SSR, stuff like NPM packages that uses **Browser APIs** (e.g., `window`, `document`) will cause errors.
207
- The developer (The one that is writing this README) may add a feature where Authtics Host converts:
208
- ```tsx
209
- export function Component() {
210
- return (
211
- <p>{window.__status_code__}</p>
212
- )
213
- }
275
+ You can add an `on` event onto the Node.js server by using `on(event, handler)`, example:
276
+ ```typescript
277
+ app.on("upgrade", (req, socket, head) => {
278
+ if (req.headers['upgrade'] && req.headers['upgrade'].toLowerCase() === 'websocket') {
279
+ // any code here
280
+ }
281
+ });
214
282
  ```
215
- To:
216
- ```tsx
217
- import { useState, useEffect } from 'react';
218
- export function Component() {
219
- const [__window, __set_window] = useState<any>(null);
220
- useEffect(() => {
221
- if (window) __set_window(window);
222
- }, []);
223
- return (
224
- <p>{__window.__status_code__}</p>
225
- )
226
- }
283
+
284
+ You can also add an `use` event onto the HostJS App, when a user visits the page, the first `use` event runs on it before reaching any other route, any other `use` event doesn't run until you call `next()`. Example:
285
+ ```typescript
286
+ app.use((req, res, id, next) => {
287
+ console.log("Request cookies: " + req.cookies);
288
+ return next();
289
+ });
290
+
291
+ app.use((req, res, id, next) => {
292
+ console.log("2nd USE event ran.");
293
+ });
294
+
295
+ app.use((req, res, id, next) => {
296
+ console.log("3rd...");
297
+ })
227
298
  ```
228
299
 
229
- The developer might also redesign the UI for the DevPanel using [UI Tools](https://npmjs.com/package/@bananakitssu/ui-tools).
300
+ The 3rd USE event will never run because the 2nd USE event didnt use `next()`.
301
+
302
+ ## SRTWS
303
+
304
+ SRTWS is **Site Rendering Through WebSockets**, its currently in BETA.
305
+
306
+ When a client visits your site if renderer is set to SRTWS, a **SRTWS server** starts and the client connects to it. Then, the **SRTWS server** sends the entire compiled TSX to the client.
307
+
308
+ ## REQuest APIs
309
+
310
+ The `req` variable (like used in `app.get`) is an extension of the ***Node.js HTTP IncomingMessage*** class, the added items in `req` are:
311
+
312
+ * **dat** (`req.dat`) — The user's DAT cookie for the current App.
313
+ * **cookies** (`req.cookies`) — All the extracted user's cookies for the current App.
314
+ * **body** (`req.body` for POST) — The parsed `body` that was sent from client.
315
+ * **ip** (`req.ip`) — The request's IP.
316
+ * **ipType** (`req.ipType`) — The IP's type as a number, 6 is IPv6, 4 is IPv4, 0 is unknown.
317
+ * **ua** (`req.ua`) — The request's UserAgent.
318
+ * **os** (`req.os`) — The request's OS from the UserAgent.
319
+ * **browser** (`req.browser`) — The request's browser from the UserAgent.
320
+ * **sentTime** (`req.sentTim.e`) — When the request was sent
321
+ * **bodySize** (`req.bodySize` for POST) — The size of the body. (`req.body`)
322
+ * **bodyType** (`req.bodyType`) — The Content-Type of the body. (`req.body`)
323
+
324
+ ## RESponse APIs
325
+
326
+ The `res` variable (like used in `app.get`) is an extension of the ***Node.js HTTP ServerResponse*** class, the added items in `res` are:
327
+
328
+ * **redirect** (`res.redirect(url)`) — Send the client to another URL.
329
+ * **html** (`res.html(content)`) — Return HTML to the client.
330
+ * **json** (`res.json(content)`) — Return JSON to the client.
331
+ * **text** (`res.text(content)`) — Return plain text to the client.
332
+ * **file** (`res.file(path)`) — Let HostJS read the provided file path and return the file content to the client.
333
+ * **status** (`res.status(code)`) — Change the server's status code, returns new **ServerResponse** object.
334
+ * **reload** (`res.reload()`) — Send a reload request to the client.
335
+ * **setCookie** (`res.setCookie(name, value)`) — Set a cookie on the client.
336
+ * **rmvCookie** (`res.rmvCookie(name)`) — Remove a cookie from the client.
337
+
338
+ ## Notes about Authtics Host
230
339
 
231
- And also maybe, add Developer Panel customization.
340
+ The developer might redesign the UI for the DevPanel using [UI Tools](https://npmjs.com/package/@bananakitssu/ui-tools).
232
341
 
233
342
  > **Warning**:
234
343
  > Asking AI about HostJS is not recommended, it will give an Auth platform and call HostJS/Authtics Host a typo, say it doesn't exist, say it was renamed, it is private, or the account doesn't exist. Or if it knows, it may swap your server script with regular **Node.js**/**ExpressJS**/**Next.js** or use **Next.js-like** code because this framework is **Next.js-inspired**
@@ -263,4 +372,4 @@ I named this web framework Authtics Host because it uses DAT (For the **Auth**ti
263
372
 
264
373
  ## Contacting The Developer Of Authtics Host
265
374
 
266
- If you have any questions, or encountered a bug while using HostJS, contact: authtics@proton.me
375
+ If you have any questions, or encountered a bug while using HostJS, contact: authtics@proton.me
Binary file
Binary file
@@ -0,0 +1,10 @@
1
+ type bAPI = 'navigator' | 'window' | 'document' | 'location' | 'localStorage' | 'sessionStorage' | 'fetch' | 'XMLHttpRequest';
2
+ export declare function load(browserAPI: bAPI): Promise<any>;
3
+ export declare class Cookies {
4
+ private Document;
5
+ constructor();
6
+ set(name: string, value: string, sameSite?: string, Secure?: boolean, MaxAge?: number | null): Promise<void>;
7
+ get(name: string): Promise<string | undefined>;
8
+ del(name: string): Promise<void>;
9
+ }
10
+ export {};
@@ -0,0 +1,53 @@
1
+ 'use strict';
2
+ export async function load(browserAPI) {
3
+ while (typeof window === "undefined") {
4
+ return null;
5
+ }
6
+ const apiMap = {
7
+ navigator: window.navigator,
8
+ window: window,
9
+ document: window.document,
10
+ location: window.location,
11
+ localStorage: window.localStorage,
12
+ sessionStorage: window.sessionStorage,
13
+ fetch: window.fetch.bind(window),
14
+ XMLHttpRequest: window.XMLHttpRequest
15
+ };
16
+ return apiMap[browserAPI];
17
+ }
18
+ export class Cookies {
19
+ Document;
20
+ constructor() {
21
+ this.Document = load('document');
22
+ }
23
+ async set(name, value, sameSite = "Lax", Secure = true, MaxAge = null) {
24
+ const Document = this.Document;
25
+ const cookieParts = [`${encodeURIComponent(name)}=${encodeURIComponent(value)}`, "Path=/"];
26
+ if (MaxAge !== null) {
27
+ cookieParts.push(`max-age=${MaxAge}`);
28
+ const d = new Date();
29
+ d.setTime(d.getTime() + (MaxAge * 1000));
30
+ cookieParts.push(`expires=${d.toUTCString()}`);
31
+ }
32
+ if (Secure)
33
+ cookieParts.push("secure");
34
+ if (sameSite)
35
+ cookieParts.push(`samesite=${sameSite}`);
36
+ Document.cookie = cookieParts.join("; ");
37
+ }
38
+ async get(name) {
39
+ const Document = this.Document;
40
+ const cookies = Document.cookie.split(";").filter(Boolean);
41
+ for (const c of cookies) {
42
+ const [key, ...valParts] = c.trim().split("=");
43
+ if (decodeURIComponent(key) === name) {
44
+ return decodeURIComponent(valParts.join("="));
45
+ }
46
+ }
47
+ return undefined;
48
+ }
49
+ async del(name) {
50
+ const Document = await load('document');
51
+ Document.cookie = `${encodeURIComponent(name)}=; path=/; max-age=0; samesite=Lax; secure`;
52
+ }
53
+ }
package/dist/cli.d.ts CHANGED
@@ -1,13 +1,15 @@
1
1
  #!/usr/bin/env node
2
- import { IncomingMessage, ServerResponse } from "node:http";
2
+ import { IncomingMessage, ServerResponse, Server } from "node:http";
3
3
  export default class App {
4
- server: any;
4
+ server: Server | null | undefined;
5
5
  constructor();
6
6
  startServer(): Promise<void>;
7
- get(routePath: string, handler: (req: IncomingMessage, res: ServerResponse) => void): void;
8
7
  registerApp(route: string): void;
8
+ get(routePath: string, handler: (req: IncomingMessage, res: ServerResponse) => void): void;
9
9
  post(routePath: string, handler: (req: IncomingMessage, res: ServerResponse) => void): void;
10
10
  put(routePath: string, handler: (req: IncomingMessage, res: ServerResponse) => void): void;
11
11
  delete(routePath: string, handler: (req: IncomingMessage, res: ServerResponse) => void): void;
12
+ use(handler: (req: IncomingMessage, res: ServerResponse, id: bigint | null, next: Function) => void): void;
13
+ on(method: string, handler: (...args: any[]) => void): void;
12
14
  remove(method: string, routePath: string): void;
13
15
  }