kreftjs 0.0.7-beta → 0.0.10-beta
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 +5 -31
- package/bin/artisan-more.js +2 -0
- package/bin/artisan.js +51 -49
- package/bin/backend/config.js +2 -2
- package/bin/backend/http.js +5 -5
- package/bin/backend/index.js +6 -2
- package/bin/backend/mcp.js +3 -5
- package/bin/backend/migrator.js +1 -3
- package/bin/backend/query.js +1 -1
- package/bin/backend/queue.js +8 -9
- package/bin/backend/redis.js +1 -1
- package/bin/backend/typescript.js +1 -1
- package/bin/build.js +24 -19
- package/bin/db-api.js +2 -2
- package/bin/db.js +4 -4
- package/bin/deps.js +1 -1
- package/bin/electron.js +3 -5
- package/bin/kreftjs-config.js +1 -6
- package/bin/kreftjs.js +34 -35
- package/bin/layout.js +1 -1
- package/bin/no-auth.js +18 -18
- package/bin/prerender.js +1 -1
- package/bin/ssr.js +3 -3
- package/bin/update.js +10 -10
- package/docs/{Docs.kreftjs → Docs.kreft} +1 -1
- package/docs/README.md +102 -104
- package/editors/vscode/README.md +3 -3
- package/editors/vscode/package.json +3 -4
- package/editors/vscode/snippets/kreftjs.json +2 -2
- package/kreftjs.d.ts +15 -27
- package/kreftjs.js +82 -79
- package/package.json +4 -4
- package/templates/app/README.md +10 -10
- package/templates/app/_env.example +7 -6
- package/templates/app/_vscode/settings.json +3 -2
- package/templates/app/backend/app/Http/Controllers/Admin/DashboardController.js +2 -2
- package/templates/app/backend/app/Http/Controllers/Admin/UserController.js +1 -1
- package/templates/app/backend/app/Http/Controllers/Auth/ApiTokenController.js +1 -1
- package/templates/app/backend/app/Http/Controllers/Auth/AuthenticatedSessionController.js +1 -1
- package/templates/app/backend/app/Http/Controllers/Auth/ConfirmablePasswordController.js +1 -1
- package/templates/app/backend/app/Http/Controllers/Auth/EmailVerificationController.js +1 -1
- package/templates/app/backend/app/Http/Controllers/Auth/NewPasswordController.js +2 -2
- package/templates/app/backend/app/Http/Controllers/Auth/PasswordResetLinkController.js +1 -1
- package/templates/app/backend/app/Http/Controllers/Auth/RegisteredUserController.js +2 -2
- package/templates/app/backend/app/Http/Controllers/Auth/SessionController.js +1 -1
- package/templates/app/backend/app/Http/Controllers/Auth/TwoFactorController.js +1 -1
- package/templates/app/backend/app/Http/Controllers/ProfileController.js +2 -2
- package/templates/app/backend/app/Http/Middleware/RequirePassword.js +1 -1
- package/templates/app/backend/lang/ar/validation.json +2 -2
- package/templates/app/backend/lang/en/validation.json +2 -2
- package/templates/app/frontend/{App.kreftjs → App.kreft} +1 -1
- package/templates/app/frontend/components/profile/{ApiTokens.kreftjs → ApiTokens.kreft} +1 -1
- package/templates/app/frontend/components/profile/{Sessions.kreftjs → Sessions.kreft} +1 -1
- package/templates/app/frontend/components/profile/{TwoFactor.kreftjs → TwoFactor.kreft} +1 -1
- package/templates/app/frontend/errors/{ErrorMonitor.kreftjs → ErrorMonitor.kreft} +3 -3
- package/templates/app/frontend/index.html +8 -8
- package/templates/app/frontend/kreftjs.d.ts +15 -27
- package/templates/app/frontend/kreftjs.js +82 -79
- package/templates/app/frontend/layouts/{docs.kreftjs → docs.kreft} +1 -1
- package/templates/app/frontend/pages/{Dashboard.kreftjs → Dashboard.kreft} +1 -1
- package/templates/app/frontend/pages/{ErrorMonitor.kreftjs → ErrorMonitor.kreft} +2 -2
- package/templates/app/frontend/pages/{Home.kreftjs → Home.kreft} +2 -2
- package/templates/app/frontend/pages/{Profile.kreftjs → Profile.kreft} +4 -4
- package/templates/app/frontend/pages/auth/{Register.kreftjs → Register.kreft} +1 -1
- package/templates/app/frontend/pages/auth/{ResetPassword.kreftjs → ResetPassword.kreft} +1 -1
- package/templates/app/frontend/routes/web.kreft +34 -0
- package/templates/app/frontend/tests/components/{Counter.kreftjs → Counter.kreft} +1 -1
- package/templates/app/frontend/tests/pages/About.kreft +12 -0
- package/templates/app/frontend/tests/pages/{Test.kreftjs → Test.kreft} +1 -1
- package/templates/app/lang/ar/validation.json +1 -1
- package/templates/app/lang/en/validation.json +1 -1
- package/templates/errors/{401.kreftjs → 401.kreft} +2 -2
- package/templates/errors/{402.kreftjs → 402.kreft} +2 -2
- package/templates/errors/{403.kreftjs → 403.kreft} +2 -2
- package/templates/errors/{404.kreftjs → 404.kreft} +2 -2
- package/templates/errors/{419.kreftjs → 419.kreft} +2 -2
- package/templates/errors/{429.kreftjs → 429.kreft} +2 -2
- package/templates/errors/{500.kreftjs → 500.kreft} +2 -2
- package/templates/errors/{503.kreftjs → 503.kreft} +2 -2
- package/templates/errors/{ErrorMonitor.kreftjs → ErrorMonitor.kreft} +13 -12
- package/templates/errors/{error.kreftjs → error.kreft} +2 -2
- package/templates/errors/{minimal.kreftjs → minimal.kreft} +1 -1
- package/tools/dev-client.js +2 -2
- package/tools/vite-plugin-kreftjs.d.ts +3 -5
- package/tools/vite-plugin-kreftjs.js +12 -14
- package/templates/app/frontend/routes/web.kreftjs +0 -34
- package/templates/app/frontend/tests/pages/About.kreftjs +0 -12
- /package/templates/app/frontend/components/{Field.kreftjs → Field.kreft} +0 -0
- /package/templates/app/frontend/components/{StatCard.kreftjs → StatCard.kreft} +0 -0
- /package/templates/app/frontend/layouts/{app.kreftjs → app.kreft} +0 -0
- /package/templates/app/frontend/layouts/{guest.kreftjs → guest.kreft} +0 -0
- /package/templates/app/frontend/pages/{Users.kreftjs → Users.kreft} +0 -0
- /package/templates/app/frontend/pages/auth/{ConfirmPassword.kreftjs → ConfirmPassword.kreft} +0 -0
- /package/templates/app/frontend/pages/auth/{ForgotPassword.kreftjs → ForgotPassword.kreft} +0 -0
- /package/templates/app/frontend/pages/auth/{Login.kreftjs → Login.kreft} +0 -0
- /package/templates/app/frontend/pages/auth/{VerifyEmail.kreftjs → VerifyEmail.kreft} +0 -0
package/docs/README.md
CHANGED
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
## Introduction
|
|
4
4
|
|
|
5
|
-
Kreft is a small reactive framework with its own component language. You write a component in a `.
|
|
5
|
+
Kreft is a small reactive framework with its own component language. You write a component in a `.kreft` file: declare your state, derived values and actions in plain words, then describe the page in a `<view>`. The framework also ships a full Node.js backend (routes, controllers, models, migrations, queues, mail) so one project can cover the whole stack.
|
|
6
6
|
|
|
7
7
|
```html
|
|
8
|
-
<!-- Counter.
|
|
8
|
+
<!-- Counter.kreft -->
|
|
9
9
|
state count = 0
|
|
10
10
|
derive double = count * 2
|
|
11
11
|
action add() { count++ }
|
|
@@ -19,7 +19,7 @@ action add() { count++ }
|
|
|
19
19
|
|
|
20
20
|
| Part | What it gives you |
|
|
21
21
|
|---|---|
|
|
22
|
-
| **The `.
|
|
22
|
+
| **The `.kreft` language** | `state`, `derive`, `action`, `watch`, props, events, slots, stores, a router with layouts and nested routes, forms with validation, animations. |
|
|
23
23
|
| **The backend** | `Route`, controllers, an Active Record `Model`, migrations, seeders, factories, jobs, mail, cache, file storage, policies, scheduling. |
|
|
24
24
|
| **Authentication** | Sign-in pages, password reset, email verification, two-factor codes, device sessions and API tokens, ready in every new project (leave them out with `--no-auth`). |
|
|
25
25
|
| **Tooling** | `kreft dev` with hot reload that keeps state, DevTools, an error monitor, `kreft build`, TypeScript, Vite and Electron support. |
|
|
@@ -82,7 +82,7 @@ npx kreftjs dev
|
|
|
82
82
|
### Check that it works
|
|
83
83
|
|
|
84
84
|
```bash
|
|
85
|
-
kreft --version # for example 0.0.
|
|
85
|
+
kreft --version # for example 0.0.10-beta
|
|
86
86
|
kreft about # Kreft and Node.js versions, this project's settings and drivers
|
|
87
87
|
kreft list # every command your version has
|
|
88
88
|
```
|
|
@@ -95,7 +95,7 @@ kreft list # every command your version has
|
|
|
95
95
|
kreft vscode
|
|
96
96
|
```
|
|
97
97
|
|
|
98
|
-
installs colors and snippets for `.
|
|
98
|
+
installs colors and snippets for `.kreft` files in VS Code (also Cursor and VSCodium). Restart the editor afterwards.
|
|
99
99
|
|
|
100
100
|
### Update
|
|
101
101
|
|
|
@@ -131,21 +131,6 @@ Run `npm link` inside the Kreft folder. The `kreft` command then runs that folde
|
|
|
131
131
|
|
|
132
132
|
Next: [Your first app](#your-first-app).
|
|
133
133
|
|
|
134
|
-
### Migrating from Som.js
|
|
135
|
-
|
|
136
|
-
Kreft is Som.js under a new name (the package and command are `kreftjs`), and an existing project keeps working without edits. `kreft`, an earlier spelling of the new name, is accepted in the same places:
|
|
137
|
-
|
|
138
|
-
- **Files:** `.som` (and `.kreft`) files still compile, next to `.kreftjs` ones. A name that is missing with one extension is tried with the others. Everything the tools write is `.kreftjs`.
|
|
139
|
-
- **Templates:** `s-if`, `s-each` and every other `s-` directive are read as `k-if`, `k-each` …, and `<som-view>`, `<som-link>` … as `<kreft-view>`, `<kreft-link>` …
|
|
140
|
-
- **JavaScript:** `Som` and `Kreft` are other names for `Kreftjs` (same object; `Som` is deprecated), and `Som.compileSom` is `Kreftjs.compile`.
|
|
141
|
-
- **Command:** use `kreft` (or `kreftjs`). Kreft does not install a `som` command, so it can be installed next to an old Som.js without an `EEXIST` error; remove the old one with `npm rm -g somjs`.
|
|
142
|
-
- **Server code:** `require('somjs/server')` (also `som/server`, `@somjs/server`, `kreft/server`) still works; new code uses `require('kreftjs/server')`.
|
|
143
|
-
- **Settings:** `kreft.config.json`, `som.config.json` and `SOM_` environment variables (`SOM_SSR`, `SOM_ALLOWED_HOSTS` …) are read when the `kreftjs.config.json` file or the `KREFT_` variable is missing.
|
|
144
|
-
- **Cookies:** new projects use `kreft_session`, `kreft_2fa` and `kreft_bypass`. An existing project keeps its `som_` names until you change `app/Auth/Session.js`, and the framework's CSRF check accepts both.
|
|
145
|
-
- **Kept on purpose:** the `som_migrations` table, the `som:` prefix of saved data in `localStorage`, and the `som:` Redis keys of the queue. Renaming them needs a migration, planned for 3.1.
|
|
146
|
-
|
|
147
|
-
To move a project over, rename `*.som` (or `*.kreft`) to `*.kreftjs` (and the paths that mention them), run `kreft update` and replace `s-` with `k-`.
|
|
148
|
-
|
|
149
134
|
## Your first app
|
|
150
135
|
|
|
151
136
|
Create a project, move into it and start the development server:
|
|
@@ -186,19 +171,19 @@ The new project already has a working login page. `npm run dev` creates the tabl
|
|
|
186
171
|
|
|
187
172
|
### The smallest possible app
|
|
188
173
|
|
|
189
|
-
You can use Kreft without any project at all. An app is an HTML page plus `.
|
|
174
|
+
You can use Kreft without any project at all. An app is an HTML page plus `.kreft` files:
|
|
190
175
|
|
|
191
176
|
```html
|
|
192
177
|
<!-- index.html -->
|
|
193
178
|
<div id="app"></div>
|
|
194
179
|
<script src="kreftjs.js"></script>
|
|
195
180
|
<script>
|
|
196
|
-
Kreftjs.app('App.
|
|
181
|
+
Kreftjs.app('App.kreft').mount('#app')
|
|
197
182
|
</script>
|
|
198
183
|
```
|
|
199
184
|
|
|
200
185
|
```html
|
|
201
|
-
<!-- App.
|
|
186
|
+
<!-- App.kreft -->
|
|
202
187
|
state name = 'World'
|
|
203
188
|
|
|
204
189
|
<view>
|
|
@@ -208,7 +193,7 @@ state name = 'World'
|
|
|
208
193
|
```
|
|
209
194
|
|
|
210
195
|
> [!WARNING]
|
|
211
|
-
> `.
|
|
196
|
+
> `.kreft` files need a web server. Browsers refuse to load files from `file://`, so always open your app through `npm run dev` or any other server.
|
|
212
197
|
|
|
213
198
|
## Project structure
|
|
214
199
|
|
|
@@ -218,10 +203,10 @@ state name = 'World'
|
|
|
218
203
|
my-app/
|
|
219
204
|
├── frontend/
|
|
220
205
|
│ ├── index.html entry point
|
|
221
|
-
│ ├── App.
|
|
222
|
-
│ ├── routes/web.
|
|
223
|
-
│ ├── layouts/ app.
|
|
224
|
-
│ ├── pages/ one .
|
|
206
|
+
│ ├── App.kreft root component and router container
|
|
207
|
+
│ ├── routes/web.kreft page routes
|
|
208
|
+
│ ├── layouts/ app.kreft (signed in), guest.kreft (sign-in pages)
|
|
209
|
+
│ ├── pages/ one .kreft file per screen, auth/ for sign-in pages
|
|
225
210
|
│ ├── components/ reusable pieces
|
|
226
211
|
│ ├── ui.css the design system
|
|
227
212
|
│ └── tests/ component tests
|
|
@@ -246,16 +231,16 @@ my-app/
|
|
|
246
231
|
|
|
247
232
|
### Adding a CSS library
|
|
248
233
|
|
|
249
|
-
Any CSS library works. Add its `<link>` to `index.html`, or install it and import the file from a `.
|
|
234
|
+
Any CSS library works. Add its `<link>` to `index.html`, or install it and import the file from a `.kreft` file; it becomes a `<link>` added once, and `kreft build` copies it (with its fonts and images) into `dist/vendor/`.
|
|
250
235
|
|
|
251
236
|
```html
|
|
252
237
|
import 'bootstrap/dist/css/bootstrap.min.css' // npm i bootstrap
|
|
253
|
-
import './theme.css' // your own file, next to this .
|
|
238
|
+
import './theme.css' // your own file, next to this .kreft file
|
|
254
239
|
```
|
|
255
240
|
|
|
256
241
|
### npm packages in the browser
|
|
257
242
|
|
|
258
|
-
Install a package with `kreft add`, then import it in any `.
|
|
243
|
+
Install a package with `kreft add`, then import it in any `.kreft` file:
|
|
259
244
|
|
|
260
245
|
```bash
|
|
261
246
|
kreft add dayjs nanoid lodash
|
|
@@ -277,9 +262,9 @@ state id = nanoid()
|
|
|
277
262
|
|
|
278
263
|
# The Kreft language
|
|
279
264
|
|
|
280
|
-
## Components and the .
|
|
265
|
+
## Components and the .kreft file
|
|
281
266
|
|
|
282
|
-
A `.
|
|
267
|
+
A `.kreft` file has three parts:
|
|
283
268
|
|
|
284
269
|
1. **The script**: everything outside `<view>` and `<style>`. Each line starts with a keyword.
|
|
285
270
|
2. **`<view>`**: the HTML of the component.
|
|
@@ -299,7 +284,7 @@ A `.kreftjs` file has three parts:
|
|
|
299
284
|
| `event` | `event save, remove` | Events this component sends to its parent with `send('save', data)`. |
|
|
300
285
|
| `use` | `use cart` | Use a shared store. `use mouse = trackMouse()` uses shared logic from a `.js` file. |
|
|
301
286
|
| `share` / `receive` | `share theme = 'dark'` | Give a value to everything inside this component / take a value a parent shared. |
|
|
302
|
-
| `import` | `import Card from './Card.
|
|
287
|
+
| `import` | `import Card from './Card.kreft'` | Use another component or a JavaScript module. |
|
|
303
288
|
| `saved` | `saved todos = []` | Like `state`, but kept in the browser (localStorage). |
|
|
304
289
|
| `load` | `load users = api.get('/api/users')` | Loads data and gives `users.data`, `users.loading`, `users.error`, `users.reload()`. |
|
|
305
290
|
|
|
@@ -308,7 +293,7 @@ Inside the script you use names **directly**: write `count++`, not `this.count++
|
|
|
308
293
|
### A complete example
|
|
309
294
|
|
|
310
295
|
```html
|
|
311
|
-
<!-- TodoPage.
|
|
296
|
+
<!-- TodoPage.kreft -->
|
|
312
297
|
state todos = []
|
|
313
298
|
state text = ''
|
|
314
299
|
|
|
@@ -344,7 +329,7 @@ when todos.length && remaining === 0 {
|
|
|
344
329
|
- An `action` that uses `await` becomes async automatically.
|
|
345
330
|
- A line that does not start with a keyword is normal JavaScript (`let timer`, `const max = 10`). Your actions can use it, but the view cannot. Use `state`, `derive` or `action` for anything the view needs.
|
|
346
331
|
- Every Kreft function is available in the script: `bus`, `store`, `signal`, `watch`, `tick`, `send`, `props`, `$route`, `$router`.
|
|
347
|
-
- Errors name the file and line, for example `"state" needs a name, like: state count = 0 (Bad.
|
|
332
|
+
- Errors name the file and line, for example `"state" needs a name, like: state count = 0 (Bad.kreft, line 3)`.
|
|
348
333
|
|
|
349
334
|
### Lifecycle
|
|
350
335
|
|
|
@@ -497,13 +482,13 @@ app.directive('focus', {
|
|
|
497
482
|
Register it once by its path, or import it where you need it:
|
|
498
483
|
|
|
499
484
|
```js
|
|
500
|
-
Kreftjs.app('App.
|
|
501
|
-
.component('UserCard', 'components/UserCard.
|
|
485
|
+
Kreftjs.app('App.kreft')
|
|
486
|
+
.component('UserCard', 'components/UserCard.kreft')
|
|
502
487
|
.mount('#app')
|
|
503
488
|
```
|
|
504
489
|
|
|
505
490
|
```html
|
|
506
|
-
import UserCard from './UserCard.
|
|
491
|
+
import UserCard from './UserCard.kreft'
|
|
507
492
|
|
|
508
493
|
<view>
|
|
509
494
|
<user-card name="Alice Smith" age={30}></user-card>
|
|
@@ -515,7 +500,7 @@ In the view, write component names in **kebab-case** (`<user-card>`).
|
|
|
515
500
|
### Props: parent to child
|
|
516
501
|
|
|
517
502
|
```html
|
|
518
|
-
<!-- UserCard.
|
|
503
|
+
<!-- UserCard.kreft -->
|
|
519
504
|
prop name
|
|
520
505
|
prop age = 0
|
|
521
506
|
prop admin = false
|
|
@@ -534,7 +519,7 @@ The default's type decides how plain text attributes are read: `age="30"` become
|
|
|
534
519
|
### Events: child to parent
|
|
535
520
|
|
|
536
521
|
```html
|
|
537
|
-
<!-- TodoItem.
|
|
522
|
+
<!-- TodoItem.kreft -->
|
|
538
523
|
prop todo
|
|
539
524
|
event remove
|
|
540
525
|
|
|
@@ -555,7 +540,7 @@ action removeTodo(id) { todos = todos.filter((t) => t.id !== id) }
|
|
|
555
540
|
### `k-model` on a component
|
|
556
541
|
|
|
557
542
|
```html
|
|
558
|
-
<!-- Toggle.
|
|
543
|
+
<!-- Toggle.kreft -->
|
|
559
544
|
prop modelValue = false
|
|
560
545
|
event update:modelValue
|
|
561
546
|
|
|
@@ -573,7 +558,7 @@ Named models: `k-model:title="pageTitle"` uses `prop title` and the event `updat
|
|
|
573
558
|
### Slots
|
|
574
559
|
|
|
575
560
|
```html
|
|
576
|
-
<!-- Card.
|
|
561
|
+
<!-- Card.kreft -->
|
|
577
562
|
prop items = []
|
|
578
563
|
|
|
579
564
|
<view>
|
|
@@ -648,7 +633,7 @@ Kreftjs.store('cart', {
|
|
|
648
633
|
})
|
|
649
634
|
```
|
|
650
635
|
|
|
651
|
-
Use it in any `.
|
|
636
|
+
Use it in any `.kreft` file. Every component sees the same data:
|
|
652
637
|
|
|
653
638
|
```html
|
|
654
639
|
use cart
|
|
@@ -686,7 +671,7 @@ use mouse = trackMouse()
|
|
|
686
671
|
### Share and receive
|
|
687
672
|
|
|
688
673
|
```html
|
|
689
|
-
<!-- Layout.
|
|
674
|
+
<!-- Layout.kreft -->
|
|
690
675
|
state settings = { theme: 'dark', lang: 'so' }
|
|
691
676
|
share settings = settings
|
|
692
677
|
|
|
@@ -722,7 +707,7 @@ saved token = '' as 'auth.token' <!-- choose the storage key yourself -->
|
|
|
722
707
|
```
|
|
723
708
|
|
|
724
709
|
- Every change is saved by itself, including deep ones: `todos.push(…)`, `todo.done = true`.
|
|
725
|
-
- The default key is `<Component>.<name
|
|
710
|
+
- The default key is `<Component>.<name>`, for example `Home.todos`. Use `as '…'` to share one value between components.
|
|
726
711
|
- A change made in another tab of the same site shows up in this tab too.
|
|
727
712
|
|
|
728
713
|
A store keeps its plain values when you add `saved`:
|
|
@@ -751,20 +736,20 @@ Kreftjs.storage.clear() // removes only what Kreft save
|
|
|
751
736
|
```js
|
|
752
737
|
const router = Kreftjs.router({
|
|
753
738
|
routes: [
|
|
754
|
-
{ path: '/', component: 'pages/Home.
|
|
755
|
-
{ path: '/users/:id', name: 'user', component: 'pages/User.
|
|
756
|
-
{ path: '/posts/:slug?', component: 'pages/Posts.
|
|
739
|
+
{ path: '/', component: 'pages/Home.kreft', meta: { title: 'Home' } },
|
|
740
|
+
{ path: '/users/:id', name: 'user', component: 'pages/User.kreft', props: true },
|
|
741
|
+
{ path: '/posts/:slug?', component: 'pages/Posts.kreft' },
|
|
757
742
|
{ path: '/old', redirect: '/' },
|
|
758
|
-
{ path: '/admin', component: 'pages/Admin.
|
|
759
|
-
{ path: '*', component: 'pages/NotFound.
|
|
743
|
+
{ path: '/admin', component: 'pages/Admin.kreft', guard: () => isAdmin() || '/login' },
|
|
744
|
+
{ path: '*', component: 'pages/NotFound.kreft' },
|
|
760
745
|
],
|
|
761
746
|
})
|
|
762
747
|
|
|
763
|
-
Kreftjs.app('App.
|
|
748
|
+
Kreftjs.app('App.kreft').use(router).mount('#app')
|
|
764
749
|
```
|
|
765
750
|
|
|
766
751
|
```html
|
|
767
|
-
<!-- App.
|
|
752
|
+
<!-- App.kreft -->
|
|
768
753
|
<view>
|
|
769
754
|
<nav>
|
|
770
755
|
<kreft-link to="/">Home</kreft-link>
|
|
@@ -777,7 +762,7 @@ Kreftjs.app('App.kreftjs').use(router).mount('#app')
|
|
|
777
762
|
With `props: true`, the `:id` parameter arrives as a prop:
|
|
778
763
|
|
|
779
764
|
```html
|
|
780
|
-
<!-- pages/User.
|
|
765
|
+
<!-- pages/User.kreft -->
|
|
781
766
|
prop id
|
|
782
767
|
derive user = users.find(id)
|
|
783
768
|
action back() { $router.back() }
|
|
@@ -797,11 +782,11 @@ Each page file is loaded the first time someone opens it.
|
|
|
797
782
|
|
|
798
783
|
### Route files
|
|
799
784
|
|
|
800
|
-
New projects keep their pages in `frontend/routes/web.
|
|
785
|
+
New projects keep their pages in `frontend/routes/web.kreft`, and `index.html` only points to it:
|
|
801
786
|
|
|
802
787
|
```js
|
|
803
788
|
Kreftjs.router({
|
|
804
|
-
routes: ['routes/web.
|
|
789
|
+
routes: ['routes/web.kreft', 'routes/shop.kreft'],
|
|
805
790
|
layout: 'app',
|
|
806
791
|
errors: 'errors',
|
|
807
792
|
middleware: {
|
|
@@ -812,27 +797,27 @@ Kreftjs.router({
|
|
|
812
797
|
```
|
|
813
798
|
|
|
814
799
|
```js
|
|
815
|
-
// routes/web.
|
|
816
|
-
Route.view('/', 'pages/Home.
|
|
817
|
-
Route.view('/posts/:id', 'pages/Post.
|
|
800
|
+
// routes/web.kreft
|
|
801
|
+
Route.view('/', 'pages/Home.kreft').name('home').title('Home')
|
|
802
|
+
Route.view('/posts/:id', 'pages/Post.kreft')
|
|
818
803
|
|
|
819
804
|
Route.middleware('auth').group(() => {
|
|
820
|
-
Route.view('/dashboard', 'pages/Dashboard.
|
|
805
|
+
Route.view('/dashboard', 'pages/Dashboard.kreft').middleware('verified')
|
|
821
806
|
})
|
|
822
807
|
|
|
823
808
|
Route.layout('guest').middleware('guest').group(() => {
|
|
824
|
-
Route.view('/login', 'pages/auth/Login.
|
|
809
|
+
Route.view('/login', 'pages/auth/Login.kreft').title('Log in')
|
|
825
810
|
})
|
|
826
811
|
|
|
827
812
|
Route.prefix('/account').name('account.').middleware('auth').group(() => {
|
|
828
|
-
Route.view('/settings', 'pages/account/Settings.
|
|
829
|
-
Route.view('', 'pages/account/General.
|
|
830
|
-
Route.view('mail', 'pages/account/Mail.
|
|
813
|
+
Route.view('/settings', 'pages/account/Settings.kreft').children(() => {
|
|
814
|
+
Route.view('', 'pages/account/General.kreft') // /account/settings
|
|
815
|
+
Route.view('mail', 'pages/account/Mail.kreft') // /account/settings/mail
|
|
831
816
|
})
|
|
832
817
|
})
|
|
833
818
|
|
|
834
819
|
Route.redirect('/home', '/')
|
|
835
|
-
Route.fallback('pages/NotFound.
|
|
820
|
+
Route.fallback('pages/NotFound.kreft')
|
|
836
821
|
```
|
|
837
822
|
|
|
838
823
|
| On a route | What it does |
|
|
@@ -852,7 +837,7 @@ Route.fallback('pages/NotFound.kreftjs')
|
|
|
852
837
|
A layout is the frame around your pages: bar, menu, footer. Put it in `layouts/` and use `<slot>` where the page goes.
|
|
853
838
|
|
|
854
839
|
```html
|
|
855
|
-
<!-- layouts/app.
|
|
840
|
+
<!-- layouts/app.kreft -->
|
|
856
841
|
state menuOpen = false
|
|
857
842
|
|
|
858
843
|
<view>
|
|
@@ -887,12 +872,12 @@ A page can also fill other places in its layout:
|
|
|
887
872
|
Each HTTP error can have its own page in `errors/`. Turn them on with `errors: 'errors'` in the router. New projects already have the folder (`kreft make:errors` adds it to an older one):
|
|
888
873
|
|
|
889
874
|
```text
|
|
890
|
-
errors/401.
|
|
891
|
-
errors/error.
|
|
892
|
-
errors/minimal.
|
|
875
|
+
errors/401.kreft 402.kreft 403.kreft 404.kreft 419.kreft 429.kreft 500.kreft 503.kreft
|
|
876
|
+
errors/error.kreft any other status
|
|
877
|
+
errors/minimal.kreft the shared frame
|
|
893
878
|
```
|
|
894
879
|
|
|
895
|
-
An unknown address shows `errors/404.
|
|
880
|
+
An unknown address shows `errors/404.kreft`; a page that cannot load shows `errors/500.kreft`. From any `.kreft` file, `abort(404)` (also `$router.abort()` and `Kreftjs.abort()`) shows the matching page:
|
|
896
881
|
|
|
897
882
|
```html
|
|
898
883
|
prop id
|
|
@@ -911,7 +896,7 @@ If you cannot change the server, use `mode: 'hash'`; URLs then look like `/#/use
|
|
|
911
896
|
|
|
912
897
|
## Fetching data
|
|
913
898
|
|
|
914
|
-
The global `api` client is available in every `.
|
|
899
|
+
The global `api` client is available in every `.kreft` file, and `Kreftjs.api` in plain JavaScript:
|
|
915
900
|
|
|
916
901
|
```js
|
|
917
902
|
const users = await api.get('/api/users', { query: { page: 2 } })
|
|
@@ -926,7 +911,7 @@ await api.delete('/api/users/1')
|
|
|
926
911
|
`load` declares a reactive resource. It handles the loading state, the error, and fetches again when the values it reads change:
|
|
927
912
|
|
|
928
913
|
```html
|
|
929
|
-
<!-- pages/Posts.
|
|
914
|
+
<!-- pages/Posts.kreft -->
|
|
930
915
|
state query = ''
|
|
931
916
|
state page = 1
|
|
932
917
|
|
|
@@ -1060,6 +1045,16 @@ Without a form, `validate(values, rules)` gives `{}` or `{ field: ['…'] }`. Cu
|
|
|
1060
1045
|
|
|
1061
1046
|
The same rule names work on the server in `req.validate()` (see [Controllers and requests](#controllers-and-requests)), so one set of rules can describe both sides.
|
|
1062
1047
|
|
|
1048
|
+
### Passwords
|
|
1049
|
+
|
|
1050
|
+
`not_common_password` refuses a password that is among the most used ones (`password`, `12345678`, `qwertyuiop` …), one character repeated (`aaaaaaaa`), a plain run (`12345678`, `abcdefgh`), or the same as the email address. A new app uses it next to `min:8` when people register, reset or change a password, in the pages and in the controllers:
|
|
1051
|
+
|
|
1052
|
+
```js
|
|
1053
|
+
password: 'required|min:8|confirmed|not_common_password'
|
|
1054
|
+
```
|
|
1055
|
+
|
|
1056
|
+
It is a short list that runs offline, with no service called, so it catches the worst choices and nothing more. For longer ones, raise `min` (a passphrase of four words beats a short mix of symbols). Change the message in `lang/en/validation.json` (`not_common_password`).
|
|
1057
|
+
|
|
1063
1058
|
## Internationalization and RTL
|
|
1064
1059
|
|
|
1065
1060
|
Kreft translates text and flips direction for right-to-left languages such as Arabic, Hebrew, Persian and Urdu.
|
|
@@ -1112,7 +1107,7 @@ On the server, request language comes from `?lang=`, the `lang` cookie or `Accep
|
|
|
1112
1107
|
|
|
1113
1108
|
## Using Kreft from JavaScript
|
|
1114
1109
|
|
|
1115
|
-
You can write components as plain objects. The rules match the `.
|
|
1110
|
+
You can write components as plain objects. The rules match the `.kreft` language: values are state, getters are derived values, functions are actions.
|
|
1116
1111
|
|
|
1117
1112
|
```js
|
|
1118
1113
|
Kreftjs.app({
|
|
@@ -1123,7 +1118,7 @@ Kreftjs.app({
|
|
|
1123
1118
|
}).mount('#app')
|
|
1124
1119
|
```
|
|
1125
1120
|
|
|
1126
|
-
| JavaScript | Same as in `.
|
|
1121
|
+
| JavaScript | Same as in `.kreft` |
|
|
1127
1122
|
|---|---|
|
|
1128
1123
|
| `Kreftjs.state({ … })` | `state` + `derive` + `action` together, for code outside components. |
|
|
1129
1124
|
| `Kreftjs.signal(0)` | One value, read and written with `.value`. |
|
|
@@ -1141,7 +1136,7 @@ Kreftjs.render(`<ul><li k-each="u in users">{u}</li></ul>`, { users: ['Alex', 'A
|
|
|
1141
1136
|
|
|
1142
1137
|
### Server templates
|
|
1143
1138
|
|
|
1144
|
-
Blade and similar engines use `{{ }}`; Kreft uses `{ }`, so they do not clash. Put `kreftjs.js` and your `.
|
|
1139
|
+
Blade and similar engines use `{{ }}`; Kreft uses `{ }`, so they do not clash. Put `kreftjs.js` and your `.kreft` files in your public folder and mount as usual.
|
|
1145
1140
|
|
|
1146
1141
|
# Backend
|
|
1147
1142
|
|
|
@@ -1397,13 +1392,13 @@ New projects come with every sign-in screen and the backend behind it:
|
|
|
1397
1392
|
|
|
1398
1393
|
| Page | Address | What it does |
|
|
1399
1394
|
|---|---|---|
|
|
1400
|
-
| `pages/auth/Login.
|
|
1401
|
-
| `pages/auth/Register.
|
|
1402
|
-
| `pages/auth/ForgotPassword.
|
|
1403
|
-
| `pages/auth/ResetPassword.
|
|
1404
|
-
| `pages/auth/VerifyEmail.
|
|
1405
|
-
| `pages/auth/ConfirmPassword.
|
|
1406
|
-
| `pages/Dashboard.
|
|
1395
|
+
| `pages/auth/Login.kreft` | `/login` | Log in with email and password. |
|
|
1396
|
+
| `pages/auth/Register.kreft` | `/register` | Make an account and get an email to verify the address. |
|
|
1397
|
+
| `pages/auth/ForgotPassword.kreft` | `/forgot-password` | Email a link to choose a new password. |
|
|
1398
|
+
| `pages/auth/ResetPassword.kreft` | `/reset-password/:token` | The link from that email. |
|
|
1399
|
+
| `pages/auth/VerifyEmail.kreft` | `/verify-email` | "Check your email", and the link from it opens `/verify-email/:id/:hash`. |
|
|
1400
|
+
| `pages/auth/ConfirmPassword.kreft` | `/confirm-password` | Type the password again before something serious. |
|
|
1401
|
+
| `pages/Dashboard.kreft`, `pages/Profile.kreft` | `/dashboard`, `/profile` | The first page after logging in; account settings. |
|
|
1407
1402
|
|
|
1408
1403
|
### How a login works
|
|
1409
1404
|
|
|
@@ -1649,7 +1644,7 @@ Run `kreft list` to see every command your installed version has, and `kreft hel
|
|
|
1649
1644
|
| `kreft add <package>` | A safer `npm install`. See [Packages](#packages). |
|
|
1650
1645
|
| `kreft about`, `kreft env`, `kreft log`, `kreft tinker` | Versions and folders, environment, logs, a console with your models (`await User.count()`). |
|
|
1651
1646
|
| `kreft down --secret=x` / `kreft up` | Maintenance mode: visitors get `503`, and `/x` lets you in. |
|
|
1652
|
-
| `kreft vscode` | Installs colors, snippets and folding for `.
|
|
1647
|
+
| `kreft vscode` | Installs colors, snippets and folding for `.kreft` files in VS Code, Cursor and VSCodium. |
|
|
1653
1648
|
|
|
1654
1649
|
### Generators and database
|
|
1655
1650
|
|
|
@@ -1675,7 +1670,7 @@ Run `kreft list` to see every command your installed version has, and `kreft hel
|
|
|
1675
1670
|
|
|
1676
1671
|
Everything here comes with Kreft. Nothing else to install.
|
|
1677
1672
|
|
|
1678
|
-
**Hot reload.** While `kreft dev` runs, save a `.
|
|
1673
|
+
**Hot reload.** While `kreft dev` runs, save a `.kreft` file and only that component is swapped; its state stays. A `.css` file is reloaded without a page refresh, and an error shows an overlay with the file and line.
|
|
1679
1674
|
|
|
1680
1675
|
**Kreft DevTools.** The **S** button in the corner (or <kbd>Alt</kbd>+<kbd>Shift</kbd>+<kbd>D</kbd>) opens a panel:
|
|
1681
1676
|
|
|
@@ -1702,10 +1697,10 @@ In development, an uncaught error on the server shows an interactive page instea
|
|
|
1702
1697
|
|
|
1703
1698
|
The page is only shown when `APP_ENV` is not `production` and `APP_DEBUG` is true. **In production the same error answers a plain `Server error.`** with no stack or file names.
|
|
1704
1699
|
|
|
1705
|
-
Frontend errors use the same design through `errors/ErrorMonitor.
|
|
1700
|
+
Frontend errors use the same design through `errors/ErrorMonitor.kreft`; pass it a caught exception:
|
|
1706
1701
|
|
|
1707
1702
|
```html
|
|
1708
|
-
import ErrorMonitor from 'errors/ErrorMonitor.
|
|
1703
|
+
import ErrorMonitor from 'errors/ErrorMonitor.kreft'
|
|
1709
1704
|
state caught = null
|
|
1710
1705
|
|
|
1711
1706
|
<view>
|
|
@@ -1726,16 +1721,16 @@ npm run preview # check the result: kreft dev dist
|
|
|
1726
1721
|
|---|---|
|
|
1727
1722
|
| `index.html` | Your page, now loading the files below. |
|
|
1728
1723
|
| `kreftjs.js` | The framework. |
|
|
1729
|
-
| `app.js` | Every `.
|
|
1724
|
+
| `app.js` | Every `.kreft` file, already compiled. |
|
|
1730
1725
|
| `app.css` | All `<style>` blocks; scoped ones already scoped. |
|
|
1731
1726
|
| `main.js` | The inline `<script>` code from `index.html`. |
|
|
1732
|
-
| `deps/`, `vendor/` | The npm packages and CSS your `.
|
|
1727
|
+
| `deps/`, `vendor/` | The npm packages and CSS your `.kreft` files import, minified. |
|
|
1733
1728
|
|
|
1734
1729
|
What you get:
|
|
1735
1730
|
|
|
1736
1731
|
- **A faster first load.** The browser downloads one `app.js` and compiles nothing.
|
|
1737
1732
|
- **A strict Content-Security-Policy works.** Every expression becomes a real function, so the built app never uses `eval` or `new Function`.
|
|
1738
|
-
- **Errors before you deploy.** A mistake in any `.
|
|
1733
|
+
- **Errors before you deploy.** A mistake in any `.kreft` file stops the build and names the file and line.
|
|
1739
1734
|
|
|
1740
1735
|
Options: `kreft build ./site --out public` builds another folder, and `--base /` changes `<base href>`. `--no-htaccess` skips the `.htaccess` file described below.
|
|
1741
1736
|
|
|
@@ -1750,11 +1745,13 @@ RewriteEngine On
|
|
|
1750
1745
|
RewriteBase /
|
|
1751
1746
|
RewriteRule ^index\.html$ - [L]
|
|
1752
1747
|
RewriteCond %{REQUEST_FILENAME} !-f
|
|
1753
|
-
RewriteCond %{REQUEST_FILENAME} !-
|
|
1748
|
+
RewriteCond %{REQUEST_FILENAME}/index.html !-f
|
|
1749
|
+
RewriteCond %{REQUEST_URI} !^/api/
|
|
1750
|
+
RewriteCond %{REQUEST_URI} !\.[A-Za-z0-9]+$
|
|
1754
1751
|
RewriteRule . /index.html [L]
|
|
1755
1752
|
```
|
|
1756
1753
|
|
|
1757
|
-
Apache only knows the files on disk, so without these rules `/docs` or any other clean address gives a 404 when someone opens or reloads it. With them, every address that is not a real file or folder opens `index.html` and the router takes over. Upload the file too (it starts with a dot, so some file managers hide it; turn on "show hidden files"). If the site lives in a folder, build with `--base /folder/` and the rules follow it. An `.htaccess` you keep in `public/` is used as it is. A relative base (`--base ./`, used by the desktop build) gets no file.
|
|
1754
|
+
Apache only knows the files on disk, so without these rules `/docs` or any other clean address gives a 404 when someone opens or reloads it. With them, every page address (no file extension, not under `/api/`) that is not a real file, or a folder with its own `index.html`, opens `index.html` and the router takes over. A missing file such as `app.js`, or an `/api/` address, stays a plain 404, so code that asks for data never receives the page's HTML. Upload the file too (it starts with a dot, so some file managers hide it; turn on "show hidden files"). If the site lives in a folder, build with `--base /folder/` and the rules follow it. An `.htaccess` you keep in `public/` is used as it is. A relative base (`--base ./`, used by the desktop build) gets no file.
|
|
1758
1755
|
|
|
1759
1756
|
> [!NOTE]
|
|
1760
1757
|
> This hosts the front end only. Login, the database and everything under `/api` need the Node.js server, which Apache does not run.
|
|
@@ -1828,7 +1825,7 @@ module.exports = {
|
|
|
1828
1825
|
|
|
1829
1826
|
### Whole pages for crawlers
|
|
1830
1827
|
|
|
1831
|
-
A crawler or link preview (Googlebot, Bingbot, WhatsApp, Facebook, X, Slack, Telegram …) that doesn't run JavaScript would see an empty `<div id="app">`. For these visitors `kreft dev` and `kreft serve` open the page in the same simulated browser as `--prerender`, wait until its data has loaded, and answer with the page already drawn. If the app shows its `errors/404.
|
|
1828
|
+
A crawler or link preview (Googlebot, Bingbot, WhatsApp, Facebook, X, Slack, Telegram …) that doesn't run JavaScript would see an empty `<div id="app">`. For these visitors `kreft dev` and `kreft serve` open the page in the same simulated browser as `--prerender`, wait until its data has loaded, and answer with the page already drawn. If the app shows its `errors/404.kreft` page, the answer has status 404. A page that `kreft build --prerender` already drew is sent as it is. Everyone else gets the normal page.
|
|
1832
1829
|
|
|
1833
1830
|
```bash
|
|
1834
1831
|
npm i -D jsdom # once per project
|
|
@@ -1847,7 +1844,7 @@ kreft sitemap --url https://example.com # public/sitemap.xml an
|
|
|
1847
1844
|
kreft sitemap --url https://example.com --urls urls.js # and the addresses in that file
|
|
1848
1845
|
```
|
|
1849
1846
|
|
|
1850
|
-
It lists the routes of `Kreftjs.router({ routes })` in `index.html` and `routes/web.
|
|
1847
|
+
It lists the routes of `Kreftjs.router({ routes })` in `index.html` and `routes/web.kreft`, skipping redirects and patterns like `/posts/:id`, plus the `urls` of `backend/routes/seo.js` and `--urls`. A `lastmod` is written only when you give one (a database date such as `2026-01-02 10:00:00` becomes `2026-01-02`). A route can list `alternates: { en: '/about', ar: '/ar/about' }` for `xhtml:link` entries.
|
|
1851
1848
|
|
|
1852
1849
|
### Deploying the backend
|
|
1853
1850
|
|
|
@@ -1859,13 +1856,13 @@ Before you do, work through the [Production checklist](#production-checklist).
|
|
|
1859
1856
|
|
|
1860
1857
|
## TypeScript
|
|
1861
1858
|
|
|
1862
|
-
TypeScript works in the browser (`.
|
|
1859
|
+
TypeScript works in the browser (`.kreft` files and `.ts` modules) and on the server (`routes/api.ts`, `app/**/*.ts`, migrations, seeders).
|
|
1863
1860
|
|
|
1864
1861
|
```bash
|
|
1865
1862
|
kreft new my-app --ts
|
|
1866
1863
|
```
|
|
1867
1864
|
|
|
1868
|
-
Inside a `.
|
|
1865
|
+
Inside a `.kreft` file you can write `interface`, `type`, `enum`, `import type`, and typed `prop`, `state`, `derive` and `saved`. `kreftjs make:*` writes `.ts` files when the project has a `tsconfig.json` (or with `--ts`; `--js` forces JavaScript).
|
|
1869
1866
|
|
|
1870
1867
|
Execution needs no setup: Kreft uses `esbuild` if installed, otherwise Node's built-in type stripping (Node 22.6+), otherwise its own zero-dependency stripper.
|
|
1871
1868
|
|
|
@@ -1874,7 +1871,7 @@ Execution needs no setup: Kreft uses `esbuild` if installed, otherwise Node's bu
|
|
|
1874
1871
|
|
|
1875
1872
|
## Vite and Electron
|
|
1876
1873
|
|
|
1877
|
-
**Vite.** If your team prefers the Vite ecosystem, Kreft has a plugin that compiles `.
|
|
1874
|
+
**Vite.** If your team prefers the Vite ecosystem, Kreft has a plugin that compiles `.kreft` files on the fly:
|
|
1878
1875
|
|
|
1879
1876
|
```bash
|
|
1880
1877
|
kreft vite:init # writes vite.config.js with the Kreft plugin
|
|
@@ -1887,7 +1884,7 @@ kreft vite:preview
|
|
|
1887
1884
|
|
|
1888
1885
|
## Desktop apps with Electron
|
|
1889
1886
|
|
|
1890
|
-
Kreft can package your app as a desktop application for Windows, macOS and Linux. The pages are the same `.
|
|
1887
|
+
Kreft can package your app as a desktop application for Windows, macOS and Linux. The pages are the same `.kreft` files you already have; Electron only supplies the window.
|
|
1891
1888
|
|
|
1892
1889
|
### Quick start
|
|
1893
1890
|
|
|
@@ -2208,7 +2205,8 @@ Go through this before your first real user:
|
|
|
2208
2205
|
| `MCP_TOKEN` set, or MCP left off | The MCP endpoint is disabled in production without it. |
|
|
2209
2206
|
| Tables listed in `kreftjs.config.json`, or no `--db` at all | `kreft serve` serves only the tables you list. |
|
|
2210
2207
|
| No test user | Do not run `--seed` against production; delete `test@example.com` if it exists. |
|
|
2211
|
-
| HTTPS in front of the app | Cookies are `Secure` in production and on `https` URLs. |
|
|
2208
|
+
| HTTPS in front of the app, and `FORCE_HTTPS=true` | Cookies are `Secure` in production and on `https` URLs. Plain HTTP is only redirected to HTTPS with `FORCE_HTTPS=true` or an `https://` `APP_URL`. |
|
|
2209
|
+
| No `SESSION_SECURE_COOKIE=false` in `.env` | It switches the `Secure` flag off, so the login cookie is also sent over plain `http://`. Older templates wrote it; the server warns about it at start-up in production. |
|
|
2212
2210
|
| `npm audit` and `kreft update` | Fix known vulnerabilities before release. |
|
|
2213
2211
|
|
|
2214
2212
|
> [!NOTE]
|
|
@@ -2221,7 +2219,7 @@ Go through this before your first real user:
|
|
|
2221
2219
|
- The memory of which two-factor codes were already used, and login tickets, is kept per process. Behind several servers, a code can be replayed once on each. The per-account lockout (kept in the cache) still limits guessing.
|
|
2222
2220
|
- The sanitizer removes unsafe markup; it is not a substitute for choosing carefully what HTML you show.
|
|
2223
2221
|
- `--prerender` makes static HTML at build time. On a running server whole pages are drawn only for crawlers and link previews; every other visitor gets the page drawn by the browser, and an address the app does not have answers 200 (the app shows its own 404 page) unless `seo.js` says otherwise.
|
|
2224
|
-
- `.
|
|
2222
|
+
- `.kreft` files must be served over `http://` or `https://`, not opened from `file://`.
|
|
2225
2223
|
|
|
2226
2224
|
# Reference
|
|
2227
2225
|
|
|
@@ -2284,7 +2282,7 @@ Set these in `.env` (never commit it). Variables that start with `PUBLIC_` are c
|
|
|
2284
2282
|
|
|
2285
2283
|
| Group | Names |
|
|
2286
2284
|
|---|---|
|
|
2287
|
-
| `.
|
|
2285
|
+
| `.kreft` keywords | `state` `derive` `action` `when` `watch` `on` `prop` `event` `use` `share` `receive` `import` `saved` `load` `layout` |
|
|
2288
2286
|
| In the script | `send` `props` `bus` `store` `$route` `$router` `tick` and every `Kreft` function |
|
|
2289
2287
|
| In the view | `{expr}` `attr={expr}` `@event` `k-if` `k-elif` `k-else` `k-each` `k-key` `k-model` `k-show` `k-text` `k-html` `k-ref` `k-skip` `k-once` `k-memo` `k-animate` `{for}` |
|
|
2290
2288
|
| App | `Kreftjs.app(rootOrPath)` then `.component()` `.directive()` `.share()` `.use()` `.mount()` `.unmount()` |
|
|
@@ -2305,7 +2303,7 @@ Kreft is one framework for the browser and the server. The others below each cov
|
|
|
2305
2303
|
| | **Kreft** | **Next.js** | **Nuxt** | **Astro** | **AdonisJS** | **NestJS** |
|
|
2306
2304
|
|---|---|---|---|---|---|---|
|
|
2307
2305
|
| **What it is** | Frontend and backend in one | React framework | Vue framework | Content sites with islands of interactivity | Backend (MVC) | Backend (modules, dependency injection) |
|
|
2308
|
-
| **Components** | `.
|
|
2306
|
+
| **Components** | `.kreft` files, no Virtual DOM | React | Vue | Astro files; React, Vue, Svelte … inside | none (Edge templates, or Inertia) | none |
|
|
2309
2307
|
| **Pages drawn on the server** | At build time (`--prerender`), and for crawlers and link previews on request | Yes, for every visitor | Yes, for every visitor | Yes, mostly at build time | Only with Inertia | no |
|
|
2310
2308
|
| **Database layer** | Active Record `Model`, migrations, seeders, factories | none (use Prisma, Drizzle …) | none | none | Lucid (Active Record) | none (TypeORM, Prisma, MikroORM …) |
|
|
2311
2309
|
| **Sign-in, 2FA, API tokens** | Built in, in every new project | none (Auth.js …) | none (a module) | none | Built in | none (Passport, your own) |
|
|
@@ -2324,13 +2322,13 @@ Kreft is one framework for the browser and the server. The others below each cov
|
|
|
2324
2322
|
- **AdonisJS:** you want the same Laravel-like backend with a larger community and years of production use, and you will bring your own frontend.
|
|
2325
2323
|
- **NestJS:** you build a large API or microservices with many teams, and you want strict structure and dependency injection.
|
|
2326
2324
|
|
|
2327
|
-
**Things to weigh before choosing Kreft:** it is young and has one small community, few third-party packages are made for `.
|
|
2325
|
+
**Things to weigh before choosing Kreft:** it is young and has one small community, few third-party packages are made for `.kreft` files, and nobody has run it at large scale yet. See [Known limits](#known-limits).
|
|
2328
2326
|
|
|
2329
2327
|
## Coming from Vue
|
|
2330
2328
|
|
|
2331
2329
|
| Vue | Kreft |
|
|
2332
2330
|
|---|---|
|
|
2333
|
-
| `.vue` single-file component | `.
|
|
2331
|
+
| `.vue` single-file component | `.kreft` file: script, `<view>`, `<style scoped>` |
|
|
2334
2332
|
| `ref()`, `reactive()`, `computed()` | `state`, `derive` (JS: `Kreftjs.signal`, `Kreftjs.state`, `Kreftjs.derived`) |
|
|
2335
2333
|
| `watch`, `watchEffect` | `watch x { }`, `when cond { }` (JS: `Kreftjs.watch`, `Kreftjs.effect`) |
|
|
2336
2334
|
| `{{ x }}`, `:attr`, `@click` | `{x}`, `attr={x}`, `@click={fn}` |
|
|
@@ -2353,7 +2351,7 @@ Kreft is one framework for the browser and the server. The others below each cov
|
|
|
2353
2351
|
|
|
2354
2352
|
| Term | Meaning |
|
|
2355
2353
|
|---|---|
|
|
2356
|
-
| **Component** | A `.
|
|
2354
|
+
| **Component** | A `.kreft` file: script, view and style together. |
|
|
2357
2355
|
| **State** | A value that can change; the view follows it. |
|
|
2358
2356
|
| **Derived value** | A value calculated from other values; stays up to date by itself. |
|
|
2359
2357
|
| **Store** | State shared by many components. |
|
package/editors/vscode/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Kreft for VS Code
|
|
2
2
|
|
|
3
|
-
Colors, bracket matching, comments (Ctrl+/), folding and snippets for `.
|
|
3
|
+
Colors, bracket matching, comments (Ctrl+/), folding and snippets for `.kreft` files.
|
|
4
4
|
|
|
5
5
|
Install from a Kreft project or the Kreft folder:
|
|
6
6
|
|
|
@@ -8,6 +8,6 @@ Install from a Kreft project or the Kreft folder:
|
|
|
8
8
|
kreftjs vscode
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
-
Then restart VS Code. Type `kreftjs` in an empty `.
|
|
11
|
+
Then restart VS Code. Type `kreftjs` in an empty `.kreft` file for a starter component, or `state`, `action`, `for`, `kreft-wait` …
|
|
12
12
|
|
|
13
|
-
Files
|
|
13
|
+
Files with the older `.kreftjs` extension get the same colors.
|