princejs 1.9.6 โ†’ 2.0.0

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,7 +1,5 @@
1
1
  <div align="center">
2
2
 
3
- <img src="./src/images/og.png" alt="PrinceJS"/>
4
-
5
3
  # ๐Ÿ‘‘ PrinceJS
6
4
 
7
5
  **Ultra-clean, modern & minimal Bun web framework.**
@@ -36,9 +34,9 @@ Benchmarked with `oha -c 100 -z 30s` on Windows 10:
36
34
  ## ๐Ÿš€ Quick Start
37
35
 
38
36
  ```bash
39
- bun create princejs my-app
40
- cd my-app
41
- bun dev
37
+ npm install princejs
38
+ bun add princejs
39
+ yarn add princejs
42
40
  ```
43
41
 
44
42
  ```ts
@@ -77,7 +75,8 @@ app.listen(3000);
77
75
  | SQLite Database | `princejs/db` |
78
76
  | Plugin System | `princejs` |
79
77
  | End-to-End Type Safety | `princejs/client` |
80
- | Deploy Adapters | `princejs/vercel` ยท `princejs/cloudflare` ยท `princejs/deno` |
78
+ | Deploy Adapters | `princejs/vercel` ยท `princejs/cloudflare` ยท `princejs/deno` ยท `princejs/node` |
79
+ | Lifecycle Hooks | `princejs` |
81
80
 
82
81
  ---
83
82
 
@@ -160,6 +159,57 @@ app.plugin(usersPlugin, { prefix: "/api" });
160
159
 
161
160
  ---
162
161
 
162
+ ## ๐ŸŽฃ Lifecycle Hooks
163
+
164
+ React to key moments in request processing with lifecycle hooks:
165
+
166
+ ```ts
167
+ import { prince } from "princejs";
168
+
169
+ const app = prince();
170
+
171
+ // Called for every incoming request
172
+ app.onRequest((req) => {
173
+ console.log(`๐Ÿ“ฅ Request received: ${req.method} ${req.url}`);
174
+ });
175
+
176
+ // Called before handler execution
177
+ app.onBeforeHandle((req, path, method) => {
178
+ console.log(`๐Ÿ” About to handle: ${method} ${path}`);
179
+ (req as any).startTime = Date.now();
180
+ });
181
+
182
+ // Called after successful handler execution
183
+ app.onAfterHandle((req, res, path, method) => {
184
+ const duration = Date.now() - (req as any).startTime;
185
+ console.log(`โœ… Response: ${method} ${path} ${res.status} (${duration}ms)`);
186
+ });
187
+
188
+ // Called when handler throws an error
189
+ app.onError((err, req, path, method) => {
190
+ console.error(`โŒ Error in ${method} ${path}:`, err.message);
191
+ // Send alert, log to monitoring service, etc.
192
+ });
193
+
194
+ app.get("/users", () => ({ users: [] }));
195
+ ```
196
+
197
+ **Hook execution order:**
198
+ 1. `onRequest` โ€” early for request-wide setup
199
+ 2. `onBeforeHandle` โ€” just before route handler runs
200
+ 3. Handler executes
201
+ 4. `onAfterHandle` โ€” after success (on error, skipped)
202
+ 5. `onError` โ€” only if handler throws (skips onAfterHandle)
203
+
204
+ **Use cases:**
205
+ - ๐Ÿ“Š Metrics & observability
206
+ - ๐Ÿ” Request inspection & debugging
207
+ - โฑ๏ธ Timing & performance monitoring
208
+ - ๐Ÿšจ Error tracking & alerting
209
+ - ๐Ÿ” Security audits & compliance logging
210
+
211
+ ---
212
+
163
213
  ## ๐Ÿ”’ End-to-End Type Safety
164
214
 
165
215
  Define a contract once โ€” your client gets full TypeScript autocompletion automatically:
@@ -206,6 +256,25 @@ import { toDeno } from "princejs/deno";
206
256
  Deno.serve(toDeno(app));
207
257
  ```
208
258
 
259
+ **Node Adapter** - `server.ts`
260
+ ```ts
261
+ import { createServer } from "http";
262
+ import { toNode, toExpress } from "princejs/node";
263
+
264
+ const app = prince();
265
+ app.get("/", () => ({ message: "Hello from Node!" }));
266
+
267
+ // Native Node.js http
268
+ const server = createServer(toNode(app));
269
+ server.listen(3000);
270
+
271
+ // Or with Express
272
+ import express from "express";
273
+ const expressApp = express();
274
+ expressApp.all("*", toExpress(app));
275
+ expressApp.listen(3000);
276
+ ```
277
+
209
278
  ---
210
279
 
211
280
  ## ๐ŸŽฏ Full Example
@@ -222,7 +291,29 @@ import { z } from "zod";
222
291
 
223
292
  const app = prince(true);
224
293
 
225
- // Global middleware
294
+ // ==========================================
295
+ // LIFECYCLE HOOKS - Timing & Observability
296
+ // ==========================================
297
+ app.onRequest((req) => {
298
+ (req as any).startTime = Date.now();
299
+ });
300
+
301
+ app.onBeforeHandle((req, path, method) => {
302
+ console.log(`๐Ÿ” Handling: ${method} ${path}`);
303
+ });
304
+
305
+ app.onAfterHandle((req, res, path, method) => {
306
+ const duration = Date.now() - (req as any).startTime;
307
+ console.log(`โœ… ${method} ${path} โ†’ ${res.status} (${duration}ms)`);
308
+ });
309
+
310
+ app.onError((err, req, path, method) => {
311
+ console.error(`โŒ ${method} ${path} failed:`, err.message);
312
+ });
313
+
314
+ // ==========================================
315
+ // GLOBAL MIDDLEWARE
316
+ // ==========================================
226
317
  app.use(cors());
227
318
  app.use(logger());
228
319
  app.use(rateLimit({ max: 100, window: 60 }));
@@ -231,6 +322,10 @@ app.use(jwt(key));
231
322
  app.use(session({ secret: "key" }));
232
323
  app.use(compress());
233
324
 
325
+ // ==========================================
326
+ // ROUTES
327
+ // ==========================================
328
+
234
329
  // JSX
235
330
  const Page = () => Html(Head("Test Page"), Body(H1("Hello World"), P("This is a test")));
236
331
  app.get("/jsx", () => render(Page()));
@@ -247,7 +342,7 @@ app.ws("/chat", {
247
342
 
248
343
  // Auth
249
344
  app.get("/protected", auth(), (req) => ({ user: req.user }));
250
- app.get("/api", apiKey({ keys: ["key_123"] }), handler);
345
+ app.get("/api", apiKey({ keys: ["key_123"] }), (req) => ({ ok: true }));
251
346
 
252
347
  // Helpers
253
348
  app.get("/data", cache(60)(() => ({ time: Date.now() })));
@@ -256,10 +351,14 @@ app.get("/events", sse(), (req) => {
256
351
  setInterval(() => req.sseSend({ time: Date.now() }), 1000);
257
352
  });
258
353
 
259
- // Cron
354
+ // ==========================================
355
+ // CRON JOBS
356
+ // ==========================================
260
357
  cron("*/1 * * * *", () => console.log("PrinceJS heartbeat"));
261
358
 
262
- // OpenAPI + Scalar docs
359
+ // ==========================================
360
+ // OPENAPI + SCALAR DOCS
361
+ // ==========================================
263
362
  const api = app.openapi({ title: "PrinceJS App", version: "1.0.0" }, "/docs");
264
363
  api.route("GET", "/items", {
265
364
  summary: "List items",
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Official Node.js deploy adapter for PrinceJS
3
+ *
4
+ * @example
5
+ * // server.ts
6
+ * import { createServer } from "http";
7
+ * import { prince } from "princejs";
8
+ * import { toNode } from "princejs/node";
9
+ *
10
+ * const app = prince();
11
+ * app.get("/", () => ({ message: "Hello from Node.js!" }));
12
+ *
13
+ * const server = createServer(toNode(app));
14
+ * server.listen(3000, () => {
15
+ * console.log("Listening on http://localhost:3000");
16
+ * });
17
+ *
18
+ * @example
19
+ * // With Express.js
20
+ * import express from "express";
21
+ * import { prince } from "princejs";
22
+ * import { toExpress } from "princejs/node";
23
+ *
24
+ * const app = express();
25
+ * const princeApp = prince();
26
+ * princeApp.get("/", () => ({ message: "Hello!" }));
27
+ *
28
+ * app.all("*", toExpress(princeApp));
29
+ * app.listen(3000);
30
+ */
31
+ export type PrinceApp = {
32
+ fetch(request: Request): Promise<Response>;
33
+ };
34
+ /**
35
+ * Converts a Prince app to a Node.js http.createServer() handler
36
+ * @example
37
+ * const server = createServer(toNode(app));
38
+ * server.listen(3000);
39
+ */
40
+ export declare function toNode(app: PrinceApp): (req: any, res: any) => Promise<void>;
41
+ /**
42
+ * Converts a Prince app to an Express.js middleware handler
43
+ * @example
44
+ * app.all("*", toExpress(princeApp));
45
+ */
46
+ export declare function toExpress(app: PrinceApp): (req: any, res: any, next?: any) => Promise<void>;
47
+ //# sourceMappingURL=node.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../../src/adapters/node.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,MAAM,MAAM,SAAS,GAAG;IAAE,KAAK,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAA;CAAE,CAAC;AAEvE;;;;;GAKG;AACH,wBAAgB,MAAM,CACpB,GAAG,EAAE,SAAS,GACb,CACD,GAAG,EAAE,GAAG,EACR,GAAG,EAAE,GAAG,KACL,OAAO,CAAC,IAAI,CAAC,CAuCjB;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CACvB,GAAG,EAAE,SAAS,GACb,CACD,GAAG,EAAE,GAAG,EACR,GAAG,EAAE,GAAG,EACR,IAAI,CAAC,EAAE,GAAG,KACP,OAAO,CAAC,IAAI,CAAC,CAoCjB"}
package/dist/prince.d.ts CHANGED
@@ -14,6 +14,10 @@ export interface PrinceRequest extends Request {
14
14
  sseSend?: (data: any, event?: string, id?: string) => void;
15
15
  [key: string]: any;
16
16
  }
17
+ export type OnRequest = (req: PrinceRequest) => void | Promise<void>;
18
+ export type OnBeforeHandle = (req: PrinceRequest, path: string, method: string) => void | Promise<void>;
19
+ export type OnAfterHandle = (req: PrinceRequest, res: Response, path: string, method: string) => void | Promise<void>;
20
+ export type OnError = (err: any, req: PrinceRequest, path: string, method: string) => void | Promise<void>;
17
21
  interface WebSocketHandler {
18
22
  open?: (ws: any) => void;
19
23
  message?: (ws: any, msg: string | Buffer) => void;
@@ -62,6 +66,10 @@ export declare class Prince {
62
66
  private staticRoutes;
63
67
  private staticMiddlewares;
64
68
  private routeCache;
69
+ private onRequestHooks;
70
+ private onBeforeHandleHooks;
71
+ private onAfterHandleHooks;
72
+ private onErrorHooks;
65
73
  constructor(devMode?: boolean);
66
74
  use(mw: Middleware): this;
67
75
  /**
@@ -77,6 +85,10 @@ export declare class Prince {
77
85
  */
78
86
  plugin<TOptions = any>(plugin: PrincePlugin<TOptions>, options?: TOptions): this;
79
87
  error(fn: (err: any, req: PrinceRequest) => Response): this;
88
+ onRequest(hook: OnRequest): this;
89
+ onBeforeHandle(hook: OnBeforeHandle): this;
90
+ onAfterHandle(hook: OnAfterHandle): this;
91
+ onError(hook: OnError): this;
80
92
  json(data: any, status?: number): Response;
81
93
  response(): ResponseBuilder;
82
94
  get(path: string, ...args: (RouteHandler | Middleware)[]): this;
@@ -1 +1 @@
1
- {"version":3,"file":"prince.d.ts","sourceRoot":"","sources":["../src/prince.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"prince.d.ts","sourceRoot":"","sources":["../src/prince.ts"],"names":[],"mappings":"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"}
package/dist/prince.js CHANGED
@@ -310,6 +310,10 @@ class Prince {
310
310
  staticRoutes = new Map;
311
311
  staticMiddlewares = new Map;
312
312
  routeCache = new Map;
313
+ onRequestHooks = [];
314
+ onBeforeHandleHooks = [];
315
+ onAfterHandleHooks = [];
316
+ onErrorHooks = [];
313
317
  constructor(devMode = false) {
314
318
  this.devMode = devMode;
315
319
  }
@@ -325,6 +329,22 @@ class Prince {
325
329
  this.errorHandler = fn;
326
330
  return this;
327
331
  }
332
+ onRequest(hook) {
333
+ this.onRequestHooks.push(hook);
334
+ return this;
335
+ }
336
+ onBeforeHandle(hook) {
337
+ this.onBeforeHandleHooks.push(hook);
338
+ return this;
339
+ }
340
+ onAfterHandle(hook) {
341
+ this.onAfterHandleHooks.push(hook);
342
+ return this;
343
+ }
344
+ onError(hook) {
345
+ this.onErrorHooks.push(hook);
346
+ return this;
347
+ }
328
348
  json(data, status = 200) {
329
349
  return new Response(JSON.stringify(data), {
330
350
  status,
@@ -572,7 +592,7 @@ class Prince {
572
592
  }
573
593
  return null;
574
594
  }
575
- async executeHandler(req, handler, params, query, routeMiddlewares) {
595
+ async executeHandler(req, handler, params, query, routeMiddlewares, method, pathname) {
576
596
  Object.defineProperty(req, "params", { value: params, writable: true, configurable: true });
577
597
  Object.defineProperty(req, "query", { value: query, writable: true, configurable: true });
578
598
  if (["POST", "PUT", "PATCH"].includes(req.method) && !req.parsedBody) {
@@ -593,6 +613,9 @@ class Prince {
593
613
  },
594
614
  configurable: true
595
615
  });
616
+ for (const hook of this.onBeforeHandleHooks) {
617
+ await hook(req, pathname, method);
618
+ }
596
619
  const allMiddlewares = routeMiddlewares.length > 0 ? [...this.middlewares, ...routeMiddlewares] : this.middlewares;
597
620
  let i = 0;
598
621
  const next = async () => {
@@ -610,13 +633,20 @@ class Prince {
610
633
  return new Response(res);
611
634
  return this.json(res);
612
635
  };
613
- return next();
636
+ const response = await next();
637
+ for (const hook of this.onAfterHandleHooks) {
638
+ await hook(req, response.clone(), pathname, method);
639
+ }
640
+ return response;
614
641
  }
615
642
  async handleFetch(req) {
616
643
  const url = new URL(req.url);
617
644
  const r = req;
618
645
  const method = req.method;
619
646
  const pathname = url.pathname;
647
+ for (const hook of this.onRequestHooks) {
648
+ await hook(r);
649
+ }
620
650
  const routeMatch = this.findRoute(method, pathname);
621
651
  if (!routeMatch) {
622
652
  return this.json({ error: "Not Found" }, 404);
@@ -630,12 +660,18 @@ class Prince {
630
660
  }
631
661
  });
632
662
  }
633
- return this.executeHandler(r, routeMatch.handler, routeMatch.params, url.searchParams, routeMatch.middlewares);
663
+ return this.executeHandler(r, routeMatch.handler, routeMatch.params, url.searchParams, routeMatch.middlewares, method, pathname);
634
664
  }
635
665
  async fetch(req) {
666
+ const url = new URL(req.url);
667
+ const pathname = url.pathname;
668
+ const method = req.method;
636
669
  try {
637
670
  return await this.handleFetch(req);
638
671
  } catch (err) {
672
+ for (const hook of this.onErrorHooks) {
673
+ await hook(err, req, pathname, method);
674
+ }
639
675
  if (this.errorHandler)
640
676
  return this.errorHandler(err, req);
641
677
  if (this.devMode) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "princejs",
3
- "version": "1.9.6",
3
+ "version": "2.0.0",
4
4
  "description": "An easy and fast backend framework that is among the top three โ€” by a 13yo developer, for developers.",
5
5
  "main": "dist/prince.js",
6
6
  "types": "dist/prince.d.ts",
@@ -45,6 +45,10 @@
45
45
  "import": "./dist/adapters/deno.js",
46
46
  "types": "./dist/adapters/deno.d.ts"
47
47
  },
48
+ "./node": {
49
+ "import": "./dist/adapters/node.js",
50
+ "types": "./dist/adapters/node.d.ts"
51
+ },
48
52
  "./client": {
49
53
  "import": "./dist/client.js",
50
54
  "types": "./dist/client.d.ts"