@carlos-tzin/tzin 0.1.0 → 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/README.md +19 -38
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
measured (see [Benchmarks](#benchmarks)), but this is not yet production software.
|
|
12
12
|
|
|
13
13
|
```sh
|
|
14
|
-
npm install tzin
|
|
14
|
+
npm install @carlos-tzin/tzin
|
|
15
15
|
```
|
|
16
16
|
|
|
17
17
|
## Why another framework?
|
|
@@ -29,8 +29,8 @@ The TypeScript backend landscape is crowded — and still leaves real gaps:
|
|
|
29
29
|
tzin's answer: **declare a contract once**, get everything else for free.
|
|
30
30
|
|
|
31
31
|
```ts
|
|
32
|
-
import { t } from 'tzin'
|
|
33
|
-
import { contract, impl, createApp } from 'tzin'
|
|
32
|
+
import { t } from '@carlos-tzin/tzin'
|
|
33
|
+
import { contract, impl, createApp } from '@carlos-tzin/tzin'
|
|
34
34
|
|
|
35
35
|
const getUser = contract({
|
|
36
36
|
method: 'GET',
|
|
@@ -146,7 +146,7 @@ contracts that generate your OpenAPI document also expose your endpoints as tool
|
|
|
146
146
|
for AI agents:
|
|
147
147
|
|
|
148
148
|
```ts
|
|
149
|
-
import { startStdioMcp } from 'tzin'
|
|
149
|
+
import { startStdioMcp } from '@carlos-tzin/tzin'
|
|
150
150
|
|
|
151
151
|
const app = createApp(routes)
|
|
152
152
|
startStdioMcp(app) // newline-delimited JSON-RPC on stdio
|
|
@@ -184,7 +184,7 @@ Phoenix-style channels, mounted as ordinary routes — SSE down, POST up, so it
|
|
|
184
184
|
runs on every runtime including Workers:
|
|
185
185
|
|
|
186
186
|
```ts
|
|
187
|
-
import { Hub, Presence, channelRoutes } from 'tzin'
|
|
187
|
+
import { Hub, Presence, channelRoutes } from '@carlos-tzin/tzin'
|
|
188
188
|
|
|
189
189
|
const hub = new Hub()
|
|
190
190
|
const presence = new Presence(hub, 30_000)
|
|
@@ -201,7 +201,7 @@ ghost clients disappear even after crashes. The in-memory `Hub` is one process;
|
|
|
201
201
|
multi-node deployments wire hubs together over a message bus:
|
|
202
202
|
|
|
203
203
|
```ts
|
|
204
|
-
import { Hub } from 'tzin'
|
|
204
|
+
import { Hub } from '@carlos-tzin/tzin'
|
|
205
205
|
import { LocalBus, type MessageBus } from 'tzin/bus'
|
|
206
206
|
|
|
207
207
|
// Any PUBLISH/SUBSCRIBE transport maps onto this 2-method interface:
|
|
@@ -252,8 +252,8 @@ exactly like Node/Bun (workerd drops sends that come from another request's
|
|
|
252
252
|
context, which is why plain fetch handlers can't relay between sockets):
|
|
253
253
|
|
|
254
254
|
```ts
|
|
255
|
-
import { toDurableWorker, toWorker, TzinChannels } from 'tzin'
|
|
256
|
-
import { Hub, Presence, channelRoutes, wsChannels, createApp } from 'tzin'
|
|
255
|
+
import { toDurableWorker, toWorker, TzinChannels } from '@carlos-tzin/tzin'
|
|
256
|
+
import { Hub, Presence, channelRoutes, wsChannels, createApp } from '@carlos-tzin/tzin'
|
|
257
257
|
|
|
258
258
|
export { TzinChannels } // workerd discovers DO classes among exports
|
|
259
259
|
|
|
@@ -289,22 +289,6 @@ HTTP ✓, WS upgrade ✓, roster ✓, broadcast across connections ✓, leave di
|
|
|
289
289
|
Request-scoped middleware can override. No decorators, no reflection, no
|
|
290
290
|
container configuration files.
|
|
291
291
|
|
|
292
|
-
## Roadmap
|
|
293
|
-
|
|
294
|
-
- [x] Spike: contracts, router, server, typed client, OpenAPI generation
|
|
295
|
-
- [x] Middleware composition (onion-style) with typed per-request context
|
|
296
|
-
- [x] Adapters: Node, Bun (verified e2e), Workers (HTTP + DO-backed WebSockets, verified via miniflare/workerd)
|
|
297
|
-
- [x] Streaming/SSE (`sse()` helper + `raw()` escape hatch)
|
|
298
|
-
- [x] Realtime: Hub (pub/sub), Presence (TTL + diffs), mountable channel routes
|
|
299
|
-
- [x] Native WebSockets for channels: Node + Bun verified, Workers via Durable Objects
|
|
300
|
-
- [x] Multi-node realtime over a `MessageBus` (Redis/Postgres/Durable Objects map onto it)
|
|
301
|
-
- [x] Typed client with status-discriminated unions + zero-dep browser channel client
|
|
302
|
-
- [x] Optional light DI layer (`provide()` → typed singleton seeds in request context)
|
|
303
|
-
- [x] AI-native toolchain: MCP (stdio + Streamable HTTP), OpenAPI 3.1, `/llms.txt`
|
|
304
|
-
- [x] Batteries started: CORS middleware, bearer-auth pattern (see `examples/todo-api.ts`)
|
|
305
|
-
- [ ] Phoenix-style presence replication across nodes
|
|
306
|
-
- [ ] `create-tzin` scaffolding
|
|
307
|
-
|
|
308
292
|
## Development
|
|
309
293
|
|
|
310
294
|
```sh
|
|
@@ -313,20 +297,6 @@ npm test # vitest — runtime + end-to-end client + type assertions
|
|
|
313
297
|
npm run typecheck # strict tsc across src/test/bench fixtures
|
|
314
298
|
```
|
|
315
299
|
|
|
316
|
-
### Production-shaped example
|
|
317
|
-
|
|
318
|
-
`examples/todo-api.ts` is the full story in one runnable file: bearer-token auth
|
|
319
|
-
as onion middleware, typed context DI between middleware and handlers,
|
|
320
|
-
app-scoped injected store, ownership checks, query coercion, and the generated
|
|
321
|
-
`/openapi.json` + `/llms.txt` + `POST /mcp` surface from the same contracts.
|
|
322
|
-
|
|
323
|
-
```sh
|
|
324
|
-
npx tsx examples/todo-api.ts
|
|
325
|
-
TOKEN=$(curl -s localhost:4644/auth/login -H 'content-type: application/json' \
|
|
326
|
-
-d '{"username":"ada","password":"lovelace"}' | node -pe 'JSON.parse(require("fs").readFileSync(0)).token')
|
|
327
|
-
curl -s localhost:4644/todos -H "authorization: Bearer $TOKEN"
|
|
328
|
-
```
|
|
329
|
-
|
|
330
300
|
### Dev server
|
|
331
301
|
|
|
332
302
|
```sh
|
|
@@ -343,6 +313,17 @@ tzin dev · 2 routes
|
|
|
343
313
|
POST /users create_user
|
|
344
314
|
```
|
|
345
315
|
|
|
316
|
+
### Examples
|
|
317
|
+
|
|
318
|
+
| Example | Runtime | What it shows |
|
|
319
|
+
|---|---|---|
|
|
320
|
+
| `examples/node-demo.ts` | Node | Minimal HTTP server with contracts |
|
|
321
|
+
| `examples/bun-demo.ts` | Bun | Bun.serve with validation |
|
|
322
|
+
| `examples/todo-api.ts` | Node | Full CRUD: auth middleware, DI, OpenAPI, MCP |
|
|
323
|
+
| `examples/mcp-demo.ts` | Node | MCP server over stdio |
|
|
324
|
+
| `examples/ws-demo.ts` | Bun | WebSocket channels with presence |
|
|
325
|
+
| `examples/worker-channels.ts` | Workers | Cloudflare DO-backed channels |
|
|
326
|
+
|
|
346
327
|
## License
|
|
347
328
|
|
|
348
329
|
MIT — see [LICENSE](./LICENSE).
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@carlos-tzin/tzin",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "Contract-first TypeScript framework. Types that scale, realtime channels with presence, and an MCP server for every API.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "The tzin authors",
|