speexjs 0.2.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.
Files changed (67) hide show
  1. package/README.md +555 -0
  2. package/dist/cli/index.d.ts +1 -0
  3. package/dist/cli/index.js +1017 -0
  4. package/dist/cli/index.js.map +1 -0
  5. package/dist/client/index.d.ts +73 -0
  6. package/dist/client/index.js +927 -0
  7. package/dist/client/index.js.map +1 -0
  8. package/dist/client/signals/index.d.ts +62 -0
  9. package/dist/client/signals/index.js +248 -0
  10. package/dist/client/signals/index.js.map +1 -0
  11. package/dist/client/vdom/index.d.ts +50 -0
  12. package/dist/client/vdom/index.js +540 -0
  13. package/dist/client/vdom/index.js.map +1 -0
  14. package/dist/client/vdom/jsx-runtime.d.ts +9 -0
  15. package/dist/client/vdom/jsx-runtime.js +203 -0
  16. package/dist/client/vdom/jsx-runtime.js.map +1 -0
  17. package/dist/index-CMkhSDh7.d.ts +97 -0
  18. package/dist/index.d.ts +18 -0
  19. package/dist/index.js +6402 -0
  20. package/dist/index.js.map +1 -0
  21. package/dist/jsx-DGrnv8QB.d.ts +8 -0
  22. package/dist/response-Ca8KWK5_.d.ts +173 -0
  23. package/dist/rpc/index.d.ts +70 -0
  24. package/dist/rpc/index.js +136 -0
  25. package/dist/rpc/index.js.map +1 -0
  26. package/dist/schema/index.d.ts +231 -0
  27. package/dist/schema/index.js +1160 -0
  28. package/dist/schema/index.js.map +1 -0
  29. package/dist/server/auth/index.d.ts +61 -0
  30. package/dist/server/auth/index.js +462 -0
  31. package/dist/server/auth/index.js.map +1 -0
  32. package/dist/server/cache/index.d.ts +45 -0
  33. package/dist/server/cache/index.js +238 -0
  34. package/dist/server/cache/index.js.map +1 -0
  35. package/dist/server/container/index.d.ts +20 -0
  36. package/dist/server/container/index.js +62 -0
  37. package/dist/server/container/index.js.map +1 -0
  38. package/dist/server/controller/index.d.ts +37 -0
  39. package/dist/server/controller/index.js +139 -0
  40. package/dist/server/controller/index.js.map +1 -0
  41. package/dist/server/database/index.d.ts +461 -0
  42. package/dist/server/database/index.js +1977 -0
  43. package/dist/server/database/index.js.map +1 -0
  44. package/dist/server/events/index.d.ts +29 -0
  45. package/dist/server/events/index.js +159 -0
  46. package/dist/server/events/index.js.map +1 -0
  47. package/dist/server/gate/index.d.ts +36 -0
  48. package/dist/server/gate/index.js +169 -0
  49. package/dist/server/gate/index.js.map +1 -0
  50. package/dist/server/http/index.d.ts +45 -0
  51. package/dist/server/http/index.js +871 -0
  52. package/dist/server/http/index.js.map +1 -0
  53. package/dist/server/index.d.ts +79 -0
  54. package/dist/server/index.js +4185 -0
  55. package/dist/server/index.js.map +1 -0
  56. package/dist/server/middleware/index.d.ts +5 -0
  57. package/dist/server/middleware/index.js +416 -0
  58. package/dist/server/middleware/index.js.map +1 -0
  59. package/dist/server/router/index.d.ts +5 -0
  60. package/dist/server/router/index.js +231 -0
  61. package/dist/server/router/index.js.map +1 -0
  62. package/dist/server/storage/index.d.ts +66 -0
  63. package/dist/server/storage/index.js +244 -0
  64. package/dist/server/storage/index.js.map +1 -0
  65. package/dist/session-guard-CZeN87L9.d.ts +48 -0
  66. package/dist/types-CXH8hPei.d.ts +38 -0
  67. package/package.json +138 -0
package/README.md ADDED
@@ -0,0 +1,555 @@
1
+ # speedx 🚀
2
+
3
+ **Fullstack JavaScript/TypeScript Framework — Server + Client + RPC + Schema + Database + Auth**
4
+ **🇮🇩 Indonesia First, Built for the World**
5
+
6
+ ```bash
7
+ npm install speedx
8
+ ```
9
+
10
+ > Zero external dependencies. Only Node.js built-in modules.
11
+
12
+ ---
13
+
14
+ ## 📦 Kenapa speedx?
15
+
16
+ | Masalah | Solusi speedx |
17
+ |---------|---------------|
18
+ | Next.js terlalu berat & vendor lock-in | speedx ringan, zero-dep, engine-swappable |
19
+ | Express terlalu minimalis | speedx Laravel-like: routing, middleware, controller, DI, ORM |
20
+ | Laravel pakai PHP | speedx TypeScript native, end-to-end type safe |
21
+ | Fetch API ribet | SuperRequest/SuperResponse wrapper sendiri — lebih mudah |
22
+ | Framework asing untuk Indonesia | 🇮🇩 NIK, NPWP, Phone, Rupiah, terbilang built-in |
23
+ | React/Vue dependency berat | Signal-based VDOM sendiri — ringan, cepat |
24
+
25
+ ---
26
+
27
+ ## ✨ Fitur Lengkap
28
+
29
+ ### 🔴 Server (Laravel-like, TypeScript Native)
30
+
31
+ | Modul | Fitur |
32
+ |-------|-------|
33
+ | **Routing** | `get()`, `post()`, `put()`, `patch()`, `delete()`, `resource()`, `group()`, named routes |
34
+ | **Middleware** | CORS, CSRF, Auth, Throttle, Session, Helmet, Logger, Body Parser, Compress, Static Files |
35
+ | **Controller** | Base class + `@controller`/`@get`/`@post` decorators |
36
+ | **Container (DI)** | `bind()`, `singleton()`, `instance()`, `resolve()` |
37
+ | **HTTP** | SuperRequest + SuperResponse **(BUKAN Fetch API)** — `.json()`, `.html()`, `.redirect()`, `.stream()`, `.file()` |
38
+ | **Engine** | Node.js default, bisa ganti ke Bun/Deno via `app.setEngine()` |
39
+ | **Validation** | 25+ schema types + 🇮🇩 NIK, NPWP, Phone, Kodepos, Rekening |
40
+ | **Error Handling** | `TypedError`, HTTP status codes, exception handler |
41
+ | **Logging** | Structured logger — WIB/WITA/WIT timezone |
42
+
43
+ ### 🟡 Auth & Security
44
+
45
+ | Modul | Fitur |
46
+ |-------|-------|
47
+ | **Session Guard** | Login/logout via encrypted cookies (AES-256-GCM) |
48
+ | **Token Guard** | Bearer token authentication, abilities/permissions |
49
+ | **Gate** | Authorization policies — `Gate.define()`, `Gate.allows()` |
50
+ | **Middleware** | `authMiddleware()`, `guestMiddleware()`, `authorize()` |
51
+ | **Encryption** | AES-256-GCM encrypt/decrypt — Node.js `crypto` native |
52
+ | **Hashing** | scrypt (OWASP recommended) + PBKDF2 |
53
+
54
+ ### 🟡 Database
55
+
56
+ | Modul | Fitur |
57
+ |-------|-------|
58
+ | **Query Builder** | Laravel-like chain: `.select()`, `.where()`, `.join()`, `.orderBy()` |
59
+ | **Pagination** | `.paginate(perPage)` — built-in di Query Builder |
60
+ | **Migrations** | `SchemaBuilder`, `TableBlueprint` (30+ column types) |
61
+ | **Seeding** | `Seeder` class — insert/truncate data awal |
62
+ | **Drivers** | MySQL (default), SQLite, PostgreSQL — runtime dynamic import |
63
+
64
+ ### 🎨 Client (Signal-Based VDOM)
65
+
66
+ | Modul | Fitur |
67
+ |-------|-------|
68
+ | **Signals** | `signal()`, `computed()`, `effect()`, `batch()`, `untracked()` |
69
+ | **VDOM** | `h()`, `render()`, `patch()`, `hydrate()` — Virtual DOM sendiri |
70
+ | **SSR** | `renderToString()`, `renderToStream()`, `ServerRenderer` |
71
+ | **JSX** | Full JSX support via `jsxImportSource: \"@SpeedX/vdom\"` |
72
+ | **Router** | File-based routing, guards, reactive current/params/query |
73
+ | **Adapters** | `FrameworkAdapter` interface — React/Vue integration |
74
+
75
+ ### 🔗 RPC (Type-Safe)
76
+
77
+ | Modul | Fitur |
78
+ |-------|-------|
79
+ | **Server** | `rpc.create()` — definisi procedure + schema validation |
80
+ | **Client** | `createClient()` — auto-typed queries & mutations |
81
+ | **Batch** | Multiple procedures in one request |
82
+
83
+ ### 🛠️ CLI (Zero Dependencies)
84
+
85
+ | Perintah | Fungsi |
86
+ |----------|--------|
87
+ | `speedx init [name]` | Scaffold project baru (blank/fullstack/api-only) |
88
+ | `speedx make:controller <name>` | Generate controller |
89
+ | `speedx make:middleware <name>` | Generate middleware |
90
+ | `speedx make:schema <name>` | Generate schema |
91
+ | `speedx list-routes` | Lihat semua route yang terdaftar |
92
+ | `speedx serve` | Jalankan development server |
93
+
94
+ ---
95
+
96
+ ## 🚀 Quickstart
97
+
98
+ ### 1. Install
99
+
100
+ ```bash
101
+ npm install speedx
102
+ ```
103
+
104
+ ### 2. Buat File Server
105
+
106
+ ```typescript
107
+ // src/index.ts
108
+ import { speedx } from 'speedx/server'
109
+
110
+ const app = speedx()
111
+
112
+ app.get('/', async ({ response }) => {
113
+ return response.html('<h1>speedx 🚀</h1>')
114
+ })
115
+
116
+ app.get('/api/hello', async ({ response }) => {
117
+ return response.json({ message: 'Halo Dunia!' })
118
+ })
119
+
120
+ app.listen(3000, () => console.log('speedx running on http://localhost:3000'))
121
+ ```
122
+
123
+ ### 3. Jalankan
124
+
125
+ ```bash
126
+ npx speedx serve
127
+ # atau
128
+ node --loader ts-node src/index.ts
129
+ ```
130
+
131
+ ---
132
+
133
+ ## 📖 Dokumentasi Lengkap
134
+
135
+ ### Server Routing
136
+
137
+ ```typescript
138
+ import { speedx } from 'speedx/server'
139
+
140
+ const app = speedx()
141
+
142
+ // Basic routes
143
+ app.get('/users', handler)
144
+ app.post('/users', handler)
145
+ app.put('/users/:id', handler)
146
+ app.delete('/users/:id', handler)
147
+ app.patch('/users/:id', handler)
148
+
149
+ // Route groups
150
+ app.group('/api', (router) => {
151
+ router.get('/users', [UserController, 'index'])
152
+ router.post('/users', [UserController, 'store'])
153
+ }).middleware(['auth', 'throttle'])
154
+
155
+ // Resource routes
156
+ app.router.resource('/posts', PostController)
157
+ // GET /posts → index
158
+ // GET /posts/create → create
159
+ // POST /posts → store
160
+ // GET /posts/:id → show
161
+ // GET /posts/:id/edit → edit
162
+ // PUT /posts/:id → update
163
+ // DELETE /posts/:id → destroy
164
+
165
+ // Named routes
166
+ app.get('/users/:id', handler).name('users.show')
167
+ // app.router.route('users.show', { id: 5 }) → '/users/5'
168
+ ```
169
+
170
+ ### Controller
171
+
172
+ ```typescript
173
+ import { Controller, get, post, put, del } from 'speedx/server'
174
+
175
+ @controller('/api/users')
176
+ export class UserController extends Controller {
177
+ @get('/')
178
+ async index({ response }) {
179
+ const users = await UserService.all()
180
+ return response.json(users)
181
+ }
182
+
183
+ @post('/')
184
+ async store({ request, response }) {
185
+ const data = await request.validate(CreateUserSchema)
186
+ const user = await UserService.create(data)
187
+ return response.json(user, 201)
188
+ }
189
+
190
+ @get('/:id')
191
+ async show({ params, response }) {
192
+ const user = await UserService.findOrFail(params.id)
193
+ return response.json(user)
194
+ }
195
+
196
+ @put('/:id')
197
+ async update({ params, request, response }) {
198
+ const data = await request.validate(UpdateUserSchema)
199
+ const user = await UserService.update(params.id, data)
200
+ return response.json(user)
201
+ }
202
+
203
+ @del('/:id')
204
+ async destroy({ params, response }) {
205
+ await UserService.delete(params.id)
206
+ return response.noContent()
207
+ }
208
+ }
209
+ ```
210
+
211
+ ### Schema Validation
212
+
213
+ ```typescript
214
+ import { s } from 'speedx/schema'
215
+
216
+ // Buat schema
217
+ const UserSchema = s.object({
218
+ id: s.number(),
219
+ name: s.string().min(3).max(100),
220
+ email: s.string().email(),
221
+ age: s.number().min(17).max(120).optional(),
222
+ phone: s.phone(), // 🇮🇩 Nomor Indonesia
223
+ nik: s.nik().optional(), // 🇮🇩 NIK 16 digit
224
+ npwp: s.npwp().optional(), // 🇮🇩 NPWP
225
+ })
226
+
227
+ // Type inference
228
+ type User = s.Infer<typeof UserSchema>
229
+
230
+ // Parse & validate
231
+ const result = UserSchema.safeParse(input)
232
+ if (!result.success) {
233
+ console.log(result.error) // Pesan error Bahasa Indonesia
234
+ }
235
+ ```
236
+
237
+ ### Database Query Builder
238
+
239
+ ```typescript
240
+ import { DatabaseConnection } from 'speedx/server/database'
241
+
242
+ const db = new DatabaseConnection({
243
+ driver: 'mysql', // mysql | sqlite | postgresql
244
+ host: 'localhost',
245
+ database: 'myapp',
246
+ username: 'root',
247
+ password: 'secret',
248
+ })
249
+
250
+ await db.connect()
251
+
252
+ // Query dengan chaining
253
+ const users = await db.table('users')
254
+ .select('id', 'name', 'email')
255
+ .where('age', '>', 18)
256
+ .whereLike('name', '%john%')
257
+ .orderByDesc('created_at')
258
+ .limit(10)
259
+ .get()
260
+
261
+ // Pagination
262
+ const result = await db.table('posts')
263
+ .where('published', true)
264
+ .paginate(15, 1)
265
+ // result.data, result.total, result.lastPage, ...
266
+
267
+ // Insert
268
+ const id = await db.table('users').insert({
269
+ name: 'John',
270
+ email: 'john@test.com',
271
+ })
272
+
273
+ // Update
274
+ await db.table('users')
275
+ .where('id', 1)
276
+ .update({ name: 'John Doe' })
277
+
278
+ // Raw SQL
279
+ const result = await db.raw('SELECT * FROM users WHERE age > ?', [18])
280
+ ```
281
+
282
+ ### Authentication
283
+
284
+ ```typescript
285
+ import { speedx } from 'speedx/server'
286
+ import { AuthManager, SessionGuard } from 'speedx/server/auth'
287
+
288
+ const app = speedx()
289
+
290
+ // Setup auth
291
+ const auth = new AuthManager()
292
+ auth.guard('session', new SessionGuard({
293
+ table: 'users',
294
+ cookieName: 'speedx_session',
295
+ }))
296
+
297
+ // Login route
298
+ app.post('/login', async ({ request, response }) => {
299
+ const { email, password } = await request.json()
300
+ const authenticated = await auth.guard('session').attempt({ email, password })
301
+
302
+ if (!authenticated) {
303
+ return response.json({ error: 'Login gagal' }, 401)
304
+ }
305
+ return response.json({ message: 'Login berhasil' })
306
+ })
307
+
308
+ // Protected route
309
+ app.get('/profile', async ({ response }, next) => {
310
+ const user = await auth.guard('session').user()
311
+ return response.json(user)
312
+ }).middleware(['auth'])
313
+
314
+ // Authorization Gate
315
+ import { Gate } from 'speedx/server/gate'
316
+
317
+ const gate = new Gate()
318
+ gate.define('update-post', (user, post) => user.id === post.user_id)
319
+
320
+ app.put('/posts/:id', async ({ params, response }) => {
321
+ const post = await Post.find(params.id)
322
+ await gate.authorize('update-post', currentUser, post)
323
+ // ...
324
+ })
325
+ ```
326
+
327
+ ### Client — Signals + VDOM
328
+
329
+ ```typescript
330
+ import { signal, computed, effect, h, render } from 'speedx/client'
331
+
332
+ function Counter() {
333
+ const count = signal(0)
334
+ const doubled = computed(() => count.value * 2)
335
+
336
+ effect(() => console.log('Count:', count.value))
337
+
338
+ return h('div', { class: 'counter' },
339
+ h('p', {}, `Count: ${count.value}`),
340
+ h('p', {}, `Doubled: ${doubled.value}`),
341
+ h('button', { onClick: () => count.value++ }, '+'),
342
+ h('button', { onClick: () => count.value-- }, '-'),
343
+ )
344
+ }
345
+
346
+ // Mount ke DOM
347
+ render(h(Counter), document.getElementById('root')!)
348
+ ```
349
+
350
+ Dengan JSX (`tsconfig.json`):
351
+ ```json
352
+ {
353
+ "compilerOptions": {
354
+ "jsx": "react-jsx",
355
+ "jsxImportSource": "@SpeedX/vdom"
356
+ }
357
+ }
358
+ ```
359
+
360
+ ```tsx
361
+ function Counter() {
362
+ const count = signal(0)
363
+ return (
364
+ <div class="counter">
365
+ <p>Count: {count}</p>
366
+ <button onClick={() => count.value++}>+</button>
367
+ </div>
368
+ )
369
+ }
370
+ ```
371
+
372
+ ### Cache
373
+
374
+ ```typescript
375
+ import { Cache } from 'speedx/server/cache'
376
+
377
+ const cache = new Cache({ store: 'memory', ttl: 3600 })
378
+
379
+ // Set & Get
380
+ await cache.set('user:1', { name: 'John' })
381
+ const user = await cache.get('user:1') // { name: 'John' }
382
+
383
+ // Remember (get or set)
384
+ const data = await cache.remember('expensive:data', 300, async () => {
385
+ return await fetchExpensiveData()
386
+ })
387
+
388
+ // Increment/Decrement
389
+ await cache.increment('visits')
390
+ ```
391
+
392
+ ### File Storage
393
+
394
+ ```typescript
395
+ import { createStorage } from 'speedx/server/storage'
396
+
397
+ const storage = createStorage({
398
+ defaultDisk: 'local',
399
+ disks: {
400
+ local: { driver: 'local', root: './storage' },
401
+ public: { driver: 'local', root: './public/uploads', url: '/uploads' },
402
+ },
403
+ })
404
+
405
+ // Upload file
406
+ await storage.disk('public').put('images/photo.jpg', buffer)
407
+
408
+ // Get file URL
409
+ const url = storage.disk('public').url('images/photo.jpg')
410
+
411
+ // Check exists
412
+ const exists = await storage.exists('images/photo.jpg')
413
+ ```
414
+
415
+ ### Events
416
+
417
+ ```typescript
418
+ import { event } from 'speedx/server/events'
419
+
420
+ // Listen
421
+ event.on('user.registered', async (user) => {
422
+ await sendWelcomeEmail(user)
423
+ })
424
+
425
+ // Wildcard pattern
426
+ event.onPattern('user.*', async (eventName, data) => {
427
+ console.log(`User event: ${eventName}`, data)
428
+ })
429
+
430
+ // Emit
431
+ await event.emit('user.registered', { id: 1, email: 'john@test.com' })
432
+ ```
433
+
434
+ ### RPC (Type-Safe)
435
+
436
+ ```typescript
437
+ // === SERVER ===
438
+ import { speedx } from 'speedx/server'
439
+ import { rpc } from 'speedx/rpc'
440
+ import { s } from 'speedx/schema'
441
+
442
+ const api = rpc.create({
443
+ procedures: {
444
+ 'users.list': {
445
+ input: s.object({ page: s.number().default(1) }),
446
+ output: s.array(s.object({ id: s.number(), name: s.string() })),
447
+ handler: async ({ page }, ctx) => {
448
+ return await db.table('users').paginate(10, page).data
449
+ },
450
+ },
451
+ 'echo': {
452
+ input: s.object({ message: s.string() }),
453
+ output: s.object({ reply: s.string() }),
454
+ handler: async ({ message }) => ({ reply: `You said: ${message}` }),
455
+ },
456
+ },
457
+ })
458
+
459
+ const app = speedx()
460
+ app.post('/api/rpc', api.toHandler())
461
+ app.listen(3000)
462
+
463
+ // === CLIENT ===
464
+ import { createClient } from 'speedx/rpc'
465
+
466
+ const client = createClient({ baseUrl: 'http://localhost:3000/api' })
467
+ const users = await client.call('users.list', { page: 1 })
468
+ // users typed as { id: number, name: string }[]
469
+ ```
470
+
471
+ ---
472
+
473
+ ## 🇮🇩 Fitur Indonesia
474
+
475
+ | Fitur | Keterangan |
476
+ |-------|-----------|
477
+ | `s.nik()` | Validasi NIK 16 digit + tanggal lahir |
478
+ | `s.npwp()` | Validasi NPWP + checksum |
479
+ | `s.phone()` | Validasi nomor telepon Indonesia (+62, 08xx) |
480
+ | `s.kodepos()` | Validasi kode pos 5 digit |
481
+ | `s.rekening()` | Validasi nomor rekening bank |
482
+ | `s.alamat()` | Validasi alamat Indonesia |
483
+ | `Number.formatRupiah()` | Format mata uang Rupiah |
484
+ | `Number.terbilang()` | Angka ke kata Bahasa Indonesia |
485
+ | **Logger** | Timezone WIB/WITA/WIT |
486
+ | **Error messages** | Bahasa Indonesia default |
487
+ | **CLI** | Output dengan Bahasa Indonesia |
488
+
489
+ ---
490
+
491
+ ## 🏗️ Arsitektur
492
+
493
+ ```
494
+ speedx/
495
+ ├── src/
496
+ │ ├── index.ts # Barrel export
497
+ │ ├── native/ # Zero-dep utilities
498
+ │ ├── schema/ # Validation (25+ types)
499
+ │ ├── server/
500
+ │ │ ├── http/ # SuperRequest/SuperResponse
501
+ │ │ ├── router/ # Routing engine
502
+ │ │ ├── middleware/ # 10 built-in middleware
503
+ │ │ ├── controller/ # Base controller
504
+ │ │ ├── container/ # Dependency injection
505
+ │ │ ├── engine/ # Swappable engine
506
+ │ │ ├── auth/ # Session + Token guards
507
+ │ │ ├── gate/ # Authorization
508
+ │ │ ├── cache/ # Caching system
509
+ │ │ ├── storage/ # File storage
510
+ │ │ ├── events/ # Event system
511
+ │ │ └── database/ # Query Builder + Migrations
512
+ │ ├── client/ # Signals + VDOM + SSR
513
+ │ ├── rpc/ # Type-safe RPC
514
+ │ └── cli/ # Native CLI (zero dep)
515
+ └── tests/
516
+ ```
517
+
518
+ ---
519
+
520
+ ## 📋 Perbandingan dengan Framework Lain
521
+
522
+ | Fitur | speedx | Next.js | Express | AdonisJS | Laravel |
523
+ |-------|---------|---------|---------|----------|---------|
524
+ | Bahasa | TS/JS | TS/JS | JS | TS/JS | PHP |
525
+ | Dependencies | **0** | Ratusan | Puluhan | Puluhan | Ratusan |
526
+ | File size | ~175KB | >50MB | ~500KB | >10MB | >20MB |
527
+ | Routing | ✅ Laravel-like | ✅ File-based | ❌ Manual | ✅ Programmatic | ✅ Laravel |
528
+ | Database | ✅ Query Builder | ❌ Prisma | ❌ None | ✅ Lucid ORM | ✅ Eloquent |
529
+ | Auth | ✅ Session+Token | ✅ NextAuth | ❌ Manual | ✅ Built-in | ✅ Built-in |
530
+ | Validation | ✅ Schema (25+) | ✅ Zod | ❌ Manual | ✅ Vine | ✅ Form Request |
531
+ | VDOM/Signals | ✅ Built-in | ✅ React | ❌ | ❌ Edge | ❌ Blade |
532
+ | RPC | ✅ Type-safe | ❌ Server Actions | ❌ | ✅ Tuyau | ❌ |
533
+ | 🇮🇩 Indonesia | ✅ Built-in | ❌ | ❌ | ❌ | ❌ |
534
+
535
+ ---
536
+
537
+ ## 🗺️ Roadmap
538
+
539
+ | Version | Fitur |
540
+ |---------|-------|
541
+ | **v0.1.0** | ✅ Schema, Server (HTTP+Router+Middleware+Controller), Client (Signals+VDOM), RPC, CLI (commander) |
542
+ | **v0.2.0** | ✅ Zero dependencies, Native CLI, Auth (Session+Token), Gate, Database (Query Builder+Migrations+Pagination), Cache, Storage, Events, Encryption, Hashing, Helpers |
543
+ | **v0.3.0** | 🔜 File-based routing, Server Components, ORM, Queues |
544
+ | **v1.0.0** | 🔜 Adapter React/Vue, Dokumentasi lengkap, Publikasi global |
545
+
546
+ ---
547
+
548
+ ## ⚖️ License
549
+
550
+ MIT — bebas digunakan, dimodifikasi, dan didistribusikan.
551
+
552
+ ---
553
+
554
+ **speedx — Fullstack JavaScript/TypeScript Framework**
555
+ **🇮🇩 Dibuat oleh developer Indonesia, untuk developer dunia.**
@@ -0,0 +1 @@
1
+ #!/usr/bin/env node