abret 0.1.1
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/LICENSE +21 -0
- package/README.md +217 -0
- package/assets/logo.png +0 -0
- package/dist/html.d.ts +62 -0
- package/dist/html.js +586 -0
- package/dist/index.d.ts +103 -0
- package/dist/index.js +161 -0
- package/dist/jsx/index.d.ts +38 -0
- package/dist/jsx/jsx-dev-runtime.d.ts +1 -0
- package/dist/jsx/jsx-dev-runtime.js +65 -0
- package/dist/jsx/jsx-runtime.d.ts +1 -0
- package/dist/jsx/jsx-runtime.js +65 -0
- package/dist/middleware/static/index.d.ts +31 -0
- package/dist/middleware/static/index.js +40 -0
- package/dist/store.d.ts +148 -0
- package/dist/store.js +88 -0
- package/package.json +69 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Arisris
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="assets/logo.png" alt="Abret Logo" width="200" />
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
# Abret
|
|
6
|
+
|
|
7
|
+
[](https://www.npmjs.com/package/abret)
|
|
8
|
+
[](https://bun.sh)
|
|
9
|
+
[](LICENSE)
|
|
10
|
+
|
|
11
|
+
**Abret** is a modern, lightweight, and type-safe web framework built specifically for [Bun](https://bun.sh). It extends `Bun.serve` with a powerful routing system, composable middleware, and a built-in JSX rendering engine, all while maintaining minimal overhead.
|
|
12
|
+
|
|
13
|
+
## ✨ Features
|
|
14
|
+
|
|
15
|
+
- **🚀 Native Bun Integration**: Built directly on top of `Bun.serve` for maximum performance.
|
|
16
|
+
- **🛡️ Type-Safe Routing**: Strict TypeScript inference for route parameters and handlers.
|
|
17
|
+
- **🔗 Composable Middleware**: Robust middleware system with `createMiddleware` and `composeMiddlewares`.
|
|
18
|
+
- **⚛️ JSX/TSX Support**: Server-side rendering with familiar JSX syntax (no Virtual DOM).
|
|
19
|
+
- **🧩 Unified Context**: Component and Request context unified into a single API using `AsyncLocalStorage`.
|
|
20
|
+
- **🧠 Smart HTML Generation**: Automatic `<head>` management (titles, meta tags) and DOCTYPE handling.
|
|
21
|
+
|
|
22
|
+
## ⚡ Benchmarks
|
|
23
|
+
|
|
24
|
+
Abret's JSX engine is optimized for high-performance server-side rendering, avoiding the overhead of Virtual DOM.
|
|
25
|
+
|
|
26
|
+
- **Simple Render**: ~800,000 ops/sec
|
|
27
|
+
- **Complex Component Tree**: ~82,000 ops/sec
|
|
28
|
+
- **VNode Creation**: ~2,200,000 ops/sec
|
|
29
|
+
|
|
30
|
+
_Preliminary results on typical hardware. Significantly faster than standard React/Preact `renderToString`._
|
|
31
|
+
|
|
32
|
+
## 📦 Installation
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
bun add abret
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## 🚀 Quick Start
|
|
39
|
+
|
|
40
|
+
Create a simple server with routes and HTML rendering:
|
|
41
|
+
|
|
42
|
+
```tsx
|
|
43
|
+
import { createRoute, mergeRoutes } from "abret";
|
|
44
|
+
import { html } from "abret/html";
|
|
45
|
+
|
|
46
|
+
const home = createRoute("/", () => {
|
|
47
|
+
return html`
|
|
48
|
+
<!DOCTYPE html>
|
|
49
|
+
<html>
|
|
50
|
+
<head>
|
|
51
|
+
<title>My App</title>
|
|
52
|
+
</head>
|
|
53
|
+
<body>
|
|
54
|
+
<h1>Welcome to Abret!</h1>
|
|
55
|
+
</body>
|
|
56
|
+
</html>
|
|
57
|
+
`;
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
const api = createRoute("/api/hello", () =>
|
|
61
|
+
Response.json({ message: "Hello World" }),
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
const routes = mergeRoutes(home, api);
|
|
65
|
+
|
|
66
|
+
Bun.serve({
|
|
67
|
+
routes,
|
|
68
|
+
});
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## 📖 Key Concepts
|
|
72
|
+
|
|
73
|
+
### Routing & Groups
|
|
74
|
+
|
|
75
|
+
Organize your routes using `createRoute` and `createRouteGroup`. Types for parameters are automatically inferred.
|
|
76
|
+
|
|
77
|
+
```ts
|
|
78
|
+
import { createRouteGroup, mergeRoutes } from "abret";
|
|
79
|
+
|
|
80
|
+
// Create a group with a prefix
|
|
81
|
+
const api = createRouteGroup("/api/v1");
|
|
82
|
+
|
|
83
|
+
const routes = mergeRoutes(
|
|
84
|
+
api("/users", { GET: () => Response.json([]) }),
|
|
85
|
+
api("/users/:id", (req) => {
|
|
86
|
+
// strict type safety: req.params.id is string
|
|
87
|
+
return Response.json({ id: req.params.id });
|
|
88
|
+
}),
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
Bun.serve({ routes });
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Middleware & Context
|
|
95
|
+
|
|
96
|
+
Create reusable middleware and share state across the request lifecycle using the unified Context API. Context is implicit and doesn't require passing `req` objects.
|
|
97
|
+
|
|
98
|
+
```ts
|
|
99
|
+
```ts
|
|
100
|
+
import { createRoute, createMiddleware, createContext, setContext, useContext } from "abret";
|
|
101
|
+
|
|
102
|
+
// Define a type-safe context key
|
|
103
|
+
const UserContext = createContext<{ name: string }>("user");
|
|
104
|
+
|
|
105
|
+
const authMiddleware = createMiddleware((req, server, next) => {
|
|
106
|
+
const token = req.headers.get("Authorization");
|
|
107
|
+
if (!token) return new Response("Unauthorized", { status: 401 });
|
|
108
|
+
|
|
109
|
+
// Store user in context (implicit scope)
|
|
110
|
+
setContext(UserContext, { name: "Alice" });
|
|
111
|
+
return next();
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
// Apply middleware to a route
|
|
115
|
+
const dashboard = createRoute(
|
|
116
|
+
"/dashboard",
|
|
117
|
+
() => {
|
|
118
|
+
// Safely retrieve context (no req needed)
|
|
119
|
+
const user = useContext(UserContext, { required: true });
|
|
120
|
+
return new Response(`Welcome ${user.name}`);
|
|
121
|
+
},
|
|
122
|
+
authMiddleware,
|
|
123
|
+
);
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### Components & JSX
|
|
127
|
+
|
|
128
|
+
Build UI with components and share state using Context, just like in React (but on the server).
|
|
129
|
+
|
|
130
|
+
To use JSX, configure your `tsconfig.json`:
|
|
131
|
+
|
|
132
|
+
```json
|
|
133
|
+
{
|
|
134
|
+
"compilerOptions": {
|
|
135
|
+
"jsx": "react-jsx",
|
|
136
|
+
"jsxImportSource": "abret"
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
Example component:
|
|
142
|
+
|
|
143
|
+
```tsx
|
|
144
|
+
import { createRoute, createContext, useContext } from "abret";
|
|
145
|
+
import { html } from "abret/html";
|
|
146
|
+
|
|
147
|
+
const ThemeContext = createContext("light"); // Default value
|
|
148
|
+
|
|
149
|
+
function ThemeButton() {
|
|
150
|
+
const theme = useContext(ThemeContext);
|
|
151
|
+
return <button class={`btn-${theme}`}>Click me</button>;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
const page = createRoute("/component", () => {
|
|
155
|
+
return html(
|
|
156
|
+
<ThemeContext.Provider value="dark">
|
|
157
|
+
<ThemeButton />
|
|
158
|
+
</ThemeContext.Provider>,
|
|
159
|
+
);
|
|
160
|
+
});
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
## 🛠️ API Reference
|
|
164
|
+
|
|
165
|
+
### Core (`abret`)
|
|
166
|
+
|
|
167
|
+
```ts
|
|
168
|
+
import {
|
|
169
|
+
createRoute,
|
|
170
|
+
createRouteGroup,
|
|
171
|
+
mergeRoutes,
|
|
172
|
+
createMiddleware,
|
|
173
|
+
composeMiddlewares,
|
|
174
|
+
createContext,
|
|
175
|
+
useContext,
|
|
176
|
+
setContext,
|
|
177
|
+
} from "abret";
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
- `createRoute(path, handler, ...middlewares)` - Creates a route. Uses exact path matching.
|
|
181
|
+
- `mergeRoutes(...routes)` - Combines multiple route objects.
|
|
182
|
+
- `createRouteGroup(prefix, middlewares)` - Creates a route group.
|
|
183
|
+
- `createMiddleware(fn)` - Helper for typed middleware.
|
|
184
|
+
- `composeMiddlewares(...middlewares)` - Composes multiple middlewares.
|
|
185
|
+
- Context utilities: `createContext`, `useContext`, `setContext`, `runWithContext`, `runWithContextValue`.
|
|
186
|
+
|
|
187
|
+
### Context Store (`abret/store`)
|
|
188
|
+
|
|
189
|
+
```ts
|
|
190
|
+
import {
|
|
191
|
+
createContext,
|
|
192
|
+
useContext,
|
|
193
|
+
setContext,
|
|
194
|
+
hasContext,
|
|
195
|
+
clearContext,
|
|
196
|
+
} from "abret/store";
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
- `createContext<T>(name, defaultValue?)` - Creates a context key (and Provider if default given).
|
|
200
|
+
- `setContext(key, value)` - Sets value in current scope.
|
|
201
|
+
- `useContext(key, options?)` - Gets value (or default).
|
|
202
|
+
- `hasContext(key)` - Checks if set.
|
|
203
|
+
- `clearContext(key)` - Clears value.
|
|
204
|
+
|
|
205
|
+
### HTML & JSX (`abret/html`)
|
|
206
|
+
|
|
207
|
+
```ts
|
|
208
|
+
import { html, HTMLResponse } from "abret/html";
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
- `html(string | jsx)` - Creates an `HTMLResponse`.
|
|
212
|
+
- `HTMLResponse` - Extended Response with `.doctype()` and metadata handling.
|
|
213
|
+
- `raw(string)` - Creates safe unescaped HTML content.
|
|
214
|
+
|
|
215
|
+
## 📄 License
|
|
216
|
+
|
|
217
|
+
MIT
|
package/assets/logo.png
ADDED
|
Binary file
|
package/dist/html.d.ts
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { AsyncBuffer, Fragment, type JSXNode, SafeString, VNode } from "./jsx";
|
|
2
|
+
export { AsyncBuffer, SafeString, VNode, Fragment, type JSXNode };
|
|
3
|
+
/**
|
|
4
|
+
* Helper to create HTML Response automatically
|
|
5
|
+
*/
|
|
6
|
+
export declare class HTMLResponse extends Response {
|
|
7
|
+
private _bodySource;
|
|
8
|
+
constructor(body: any, init?: ResponseInit);
|
|
9
|
+
/**
|
|
10
|
+
* Initializes the response with new options.
|
|
11
|
+
*
|
|
12
|
+
* @param newInit - The new options to apply to the response.
|
|
13
|
+
* @returns A new HTMLResponse instance with the updated options.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```ts
|
|
17
|
+
* const response = new HTMLResponse(<div>Hello World</div>).init({ status: 200 });
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
init(newInit: ResponseInit): HTMLResponse;
|
|
21
|
+
/**
|
|
22
|
+
* Adds a DOCTYPE declaration to the response body.
|
|
23
|
+
*
|
|
24
|
+
* @param dt - The DOCTYPE declaration to add. Can be a string or a boolean.
|
|
25
|
+
* @returns A new HTMLResponse instance with the DOCTYPE declaration added.
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* ```ts
|
|
29
|
+
* const response = new HTMLResponse(<div>Hello World</div>).doctype(true);
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
doctype(dt?: string | boolean): HTMLResponse;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Creates an implementation of `HTMLResponse`.
|
|
36
|
+
*/
|
|
37
|
+
export declare function html(bodyOrStrings: JSXNode | TemplateStringsArray, ...args: any[]): HTMLResponse;
|
|
38
|
+
/**
|
|
39
|
+
* Renders a JSXNode to a SafeString or Promise<SafeString>.
|
|
40
|
+
*
|
|
41
|
+
* @param node - The JSXNode to render.
|
|
42
|
+
* @returns A SafeString or Promise<SafeString> containing the rendered HTML.
|
|
43
|
+
*
|
|
44
|
+
* @example
|
|
45
|
+
* ```tsx
|
|
46
|
+
* const rendered = render(<div>Hello World</div>);
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
49
|
+
export declare function render(node: any): SafeString | Promise<SafeString>;
|
|
50
|
+
/**
|
|
51
|
+
* Creates a raw HTML string that will not be escaped when rendered.
|
|
52
|
+
* Equivalent to using `new SafeString(str)`.
|
|
53
|
+
*
|
|
54
|
+
* @param str - The raw HTML string.
|
|
55
|
+
* @returns A SafeString instance.
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* ```tsx
|
|
59
|
+
* <div>{raw("<span>Raw HTML</span>")}</div>
|
|
60
|
+
* ```
|
|
61
|
+
*/
|
|
62
|
+
export declare function raw(str: string): SafeString;
|