kreftjs 0.0.3-beta → 0.0.4-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 +12 -12
- package/bin/add.js +11 -11
- package/bin/artisan-more.js +41 -41
- package/bin/artisan.js +41 -41
- package/bin/backend/command.js +1 -1
- package/bin/backend/factory.js +1 -1
- package/bin/backend/index.js +3 -3
- package/bin/backend/model.js +2 -2
- package/bin/backend/notifications.js +1 -1
- package/bin/backend/queue.js +2 -2
- package/bin/backend/schedule.js +2 -2
- package/bin/backend/seo-pages.js +1 -1
- package/bin/backend/storage.js +1 -1
- package/bin/backend/support.js +4 -4
- package/bin/backend/typescript.js +1 -1
- package/bin/build.js +11 -11
- package/bin/db-api.js +3 -3
- package/bin/db.js +1 -1
- package/bin/deps.js +6 -6
- package/bin/electron.js +11 -11
- package/bin/env.js +2 -2
- package/bin/guard.js +2 -2
- package/bin/kreftjs-config.js +1 -1
- package/bin/kreftjs.js +105 -105
- package/bin/layout.js +1 -1
- package/bin/no-auth.js +4 -4
- package/bin/prerender.js +4 -4
- package/bin/server-routes.js +2 -2
- package/bin/ssr.js +2 -2
- package/bin/terminal.js +1 -1
- package/bin/to-ts.js +1 -1
- package/bin/update.js +14 -14
- package/bin/urls-file.js +1 -1
- package/bin/vite.js +11 -11
- package/docs/Docs.kreftjs +1 -1
- package/docs/README.md +140 -123
- package/kreftjs.d.ts +1 -1
- package/kreftjs.js +18 -18
- package/package.json +1 -1
- package/templates/app/README.md +20 -20
- package/templates/app/backend/database/migrations/0001_01_01_000000_create_users_table.js +1 -1
- package/templates/app/backend/database/migrations/0001_01_01_000002_create_jobs_table.js +1 -1
- package/templates/app/backend/database/seeders/DatabaseSeeder.js +1 -1
- package/templates/app/backend/routes/api.js +1 -1
- package/templates/app/backend/routes/console.js +2 -2
- package/templates/app/frontend/errors/ErrorMonitor.kreftjs +2 -2
- package/templates/app/frontend/index.html +1 -1
- package/templates/app/frontend/kreftjs.d.ts +1 -1
- package/templates/app/frontend/kreftjs.js +18 -18
- package/templates/app/frontend/pages/Dashboard.kreftjs +1 -1
- package/templates/app/frontend/pages/ErrorMonitor.kreftjs +1 -1
- package/templates/app/frontend/pages/Home.kreftjs +2 -2
- package/templates/errors/ErrorMonitor.kreftjs +1 -1
package/kreftjs.d.ts
CHANGED
package/kreftjs.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* Kreft v0.0.
|
|
2
|
+
* Kreft v0.0.4-beta — reactive by nature
|
|
3
3
|
* The .kreftjs component language (state · derive · action · when · watch · on),
|
|
4
4
|
* { } views with k-if / k-each / k-model, components, slots, router, stores,
|
|
5
5
|
* share / receive, event bus and a template engine.
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
} catch (e) { console.error('[Kreft error]', e); }
|
|
29
29
|
};
|
|
30
30
|
const text = () => document.createTextNode('');
|
|
31
|
-
// `
|
|
31
|
+
// `kreft dev` turns this on: live components are tracked for hot reload and the DevTools panel
|
|
32
32
|
const devMode = () => !!(global.__KREFT_DEV__ || global.__SOM_DEV__);
|
|
33
33
|
const liveInstances = new Set();
|
|
34
34
|
const BAD_PATH_KEYS = new Set(['__proto__', 'constructor', 'prototype']);
|
|
@@ -674,7 +674,7 @@
|
|
|
674
674
|
// build many different templates (Kreftjs.render, the Template engine page) don't grow forever
|
|
675
675
|
const fnCache = new Map();
|
|
676
676
|
const FN_CACHE_MAX = 3000;
|
|
677
|
-
// `
|
|
677
|
+
// `kreft build` fills this with ready-made functions, so built apps never need eval (strict CSP)
|
|
678
678
|
const precompiled = Object.create(null);
|
|
679
679
|
const FORBIDDEN_EXP_RE = /(?:^|[^$\w])(?:constructor|__proto__|prototype)(?:[^$\w]|$)/;
|
|
680
680
|
function compileFn(code, params = '__s') {
|
|
@@ -1709,7 +1709,7 @@
|
|
|
1709
1709
|
function addPresets() {
|
|
1710
1710
|
if (presetsAdded || typeof document === 'undefined') return;
|
|
1711
1711
|
presetsAdded = true;
|
|
1712
|
-
if (document.querySelector('[data-kreft-presets]')) return; // `
|
|
1712
|
+
if (document.querySelector('[data-kreft-presets]')) return; // `kreft build` put them in app.css
|
|
1713
1713
|
const st = document.createElement('style');
|
|
1714
1714
|
st.setAttribute('data-kreft-presets', '');
|
|
1715
1715
|
st.textContent = PRESET_CSS;
|
|
@@ -2235,7 +2235,7 @@
|
|
|
2235
2235
|
return out;
|
|
2236
2236
|
}
|
|
2237
2237
|
// Som.js names still work in a template: `s-if` is read as `k-if` and `<som-view>` as `<kreft-view>`.
|
|
2238
|
-
// It runs on the finished markup, so the browser, `
|
|
2238
|
+
// It runs on the finished markup, so the browser, `kreft build` and the Vite plugin all see the same names.
|
|
2239
2239
|
const LEGACY_TAGS = /^som-(?=(?:wait|view|component|yield|section|portal|link)$)/i;
|
|
2240
2240
|
const TAG_SCAN = /<(\/?)([A-Za-z][\w:.-]*)((?:\s+[^\s"'<>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s"'>]+))?)*)(\s*\/?>)/g;
|
|
2241
2241
|
const ATTR_SCAN = /(\s+)([^\s"'<>\/=]+)(\s*=\s*(?:"[^"]*"|'[^']*'|[^\s"'>]+))?/g;
|
|
@@ -2745,7 +2745,7 @@
|
|
|
2745
2745
|
// copy with descriptors so getters stay getters (computed)
|
|
2746
2746
|
let def = rootComponent; // a .kreftjs path like 'App.kreftjs', or an object
|
|
2747
2747
|
let source = container.innerHTML;
|
|
2748
|
-
if (container.hasAttribute('data-kreft-ssg')) { // a page made by `
|
|
2748
|
+
if (container.hasAttribute('data-kreft-ssg')) { // a page made by `kreft build --prerender`: its first view came ready
|
|
2749
2749
|
const t = document.querySelector('template[data-kreft-ssg-source]');
|
|
2750
2750
|
source = t ? t.innerHTML : '';
|
|
2751
2751
|
container.removeAttribute('data-kreft-ssg');
|
|
@@ -3874,7 +3874,7 @@
|
|
|
3874
3874
|
addStylesheet(abs === spec ? Kreftjs.__npmBase + spec : abs);
|
|
3875
3875
|
continue;
|
|
3876
3876
|
}
|
|
3877
|
-
const mod = await Kreftjs.__import(abs); // one place to load modules (
|
|
3877
|
+
const mod = await Kreftjs.__import(abs); // one place to load modules (kreft build uses it too)
|
|
3878
3878
|
if (!what) continue;
|
|
3879
3879
|
what.split(/,(?![^{]*\})/).map((s) => s.trim()).forEach((part) => {
|
|
3880
3880
|
if (part.startsWith('* as ')) values[part.slice(5).trim()] = mod;
|
|
@@ -4072,7 +4072,7 @@
|
|
|
4072
4072
|
return st;
|
|
4073
4073
|
}
|
|
4074
4074
|
|
|
4075
|
-
// Pure text work, shared by the browser and `
|
|
4075
|
+
// Pure text work, shared by the browser and `kreft build`: .kreftjs source → its parts
|
|
4076
4076
|
function splitKreft(source, url = 'inline.kreftjs') {
|
|
4077
4077
|
const name = (url.split('/').pop() || '').replace(/[?#].*$/, '').replace(EXT_RE, '');
|
|
4078
4078
|
source = source.replace(/\r\n?/g, '\n');
|
|
@@ -4105,7 +4105,7 @@
|
|
|
4105
4105
|
}
|
|
4106
4106
|
const propType = (sample) => (typeof sample === 'number' ? Number : typeof sample === 'boolean' ? Boolean : typeof sample === 'string' ? String : undefined);
|
|
4107
4107
|
|
|
4108
|
-
// parts (from the browser compiler or from `
|
|
4108
|
+
// parts (from the browser compiler or from `kreft build`) → component definition
|
|
4109
4109
|
function makeKreftDef(parts, values) {
|
|
4110
4110
|
const def = {
|
|
4111
4111
|
__name: parts.name,
|
|
@@ -4155,7 +4155,7 @@
|
|
|
4155
4155
|
return makeKreftDef({ name: sp.name, template: sp.template, props, events: sp.events, layout: sp.layout, scopeId, components, run }, values);
|
|
4156
4156
|
}
|
|
4157
4157
|
|
|
4158
|
-
// Used by the app.js that `
|
|
4158
|
+
// Used by the app.js that `kreft build` writes: registers a component that is already compiled
|
|
4159
4159
|
function defineCompiled(path, parts) {
|
|
4160
4160
|
const abs = new URL(path, document.baseURI).href;
|
|
4161
4161
|
kreftCache.set(abs, parts.loadValues
|
|
@@ -4271,7 +4271,7 @@
|
|
|
4271
4271
|
// mode 'history' (default): clean URLs like /users/5 — the server must send index.html for every path.
|
|
4272
4272
|
// mode 'hash': URLs like #/users/5 — works with any server, even file://.
|
|
4273
4273
|
// Error pages: errors/404.kreftjs, errors/403.kreftjs, errors/500.kreftjs …
|
|
4274
|
-
// (Kreftjs.router({ errors: 'errors' }) turns them on; `
|
|
4274
|
+
// (Kreftjs.router({ errors: 'errors' }) turns them on; `kreft make:errors` writes them into a project)
|
|
4275
4275
|
const ERROR_PAGES = [401, 402, 403, 404, 419, 429, 500, 503];
|
|
4276
4276
|
const ERROR_TITLES = { 400: 'Bad Request', 401: 'Unauthorized', 402: 'Payment Required', 403: 'Forbidden', 404: 'Not Found', 405: 'Method Not Allowed', 409: 'Conflict', 410: 'Gone', 419: 'Page Expired', 422: 'Unprocessable Content', 429: 'Too Many Requests', 500: 'Server Error', 502: 'Bad Gateway', 503: 'Service Unavailable', 504: 'Gateway Timeout' };
|
|
4277
4277
|
let activeRouter = null;
|
|
@@ -4285,7 +4285,7 @@
|
|
|
4285
4285
|
* Route.redirect('/home', '/')
|
|
4286
4286
|
* Route.view('/settings', 'pages/Settings.kreftjs').children(() => { Route.view('profile', 'pages/settings/Profile.kreftjs') })
|
|
4287
4287
|
*/
|
|
4288
|
-
const routeFiles = new Map(); // absolute URL → function (Route) { … } (
|
|
4288
|
+
const routeFiles = new Map(); // absolute URL → function (Route) { … } (kreft build puts them in app.js)
|
|
4289
4289
|
function defineRoutes(path, fn) { routeFiles.set(new URL(path, document.baseURI).href, fn); }
|
|
4290
4290
|
function makeRouteBuilder() {
|
|
4291
4291
|
const top = [];
|
|
@@ -4852,7 +4852,7 @@
|
|
|
4852
4852
|
}
|
|
4853
4853
|
|
|
4854
4854
|
/* ================================================================
|
|
4855
|
-
* Kreftjs.table('posts') — the rows of a database table that `
|
|
4855
|
+
* Kreftjs.table('posts') — the rows of a database table that `kreft dev --db` / `kreft serve --db` serve
|
|
4856
4856
|
* const posts = Kreftjs.table('posts')
|
|
4857
4857
|
* await posts.all({ userId: 3, _sort: '-id', _limit: 20 }) posts.find(1) posts.count()
|
|
4858
4858
|
* await posts.create({ title }) posts.update(1, row) posts.patch(1, { title }) posts.remove(1)
|
|
@@ -4876,7 +4876,7 @@
|
|
|
4876
4876
|
}
|
|
4877
4877
|
|
|
4878
4878
|
/* ================================================================
|
|
4879
|
-
* Developer tools (used by `
|
|
4879
|
+
* Developer tools (used by `kreft dev`: hot reload and the DevTools panel)
|
|
4880
4880
|
* ================================================================ */
|
|
4881
4881
|
const isInside = (i, o) => { for (let p = i.parent; p; p = p.parent) if (p === o) return true; return false; };
|
|
4882
4882
|
/* ================================================================
|
|
@@ -5032,10 +5032,10 @@
|
|
|
5032
5032
|
stores, storeLog, busLog,
|
|
5033
5033
|
};
|
|
5034
5034
|
|
|
5035
|
-
const VERSION = '0.0.
|
|
5035
|
+
const VERSION = '0.0.4-beta';
|
|
5036
5036
|
const Kreftjs = {
|
|
5037
5037
|
version: VERSION,
|
|
5038
|
-
// PUBLIC_ values from .env (
|
|
5038
|
+
// PUBLIC_ values from .env (kreft dev and kreft build put them here); never secrets
|
|
5039
5039
|
get env() { return Object.freeze({ ...((typeof window !== 'undefined' && (window.__KREFT_ENV__ || window.__SOM_ENV__)) || {}) }); },
|
|
5040
5040
|
get isVite() {
|
|
5041
5041
|
return Boolean(typeof window !== 'undefined' && (window.__KREFT_VITE__ || window.__SOM_VITE__));
|
|
@@ -5055,14 +5055,14 @@
|
|
|
5055
5055
|
abort: abortPage,
|
|
5056
5056
|
// apps & components
|
|
5057
5057
|
app: createApp, lazy, load, compile: compileKreft, compileSom: compileKreft, render, // compileSom: the Som.js name, kept as an alias
|
|
5058
|
-
// used by `
|
|
5058
|
+
// used by `kreft build`, Vite plugin and the app.js it writes
|
|
5059
5059
|
__makeDef: makeKreftDef,
|
|
5060
5060
|
__registerDef: registerDef,
|
|
5061
5061
|
__hotDef: hotDef,
|
|
5062
5062
|
__define: defineCompiled,
|
|
5063
5063
|
__routes: defineRoutes,
|
|
5064
5064
|
__fileHeaders: (url) => fileHeaders(new URL(url, document.baseURI).href),
|
|
5065
|
-
__npmBase: '/__kreft/npm/', // where
|
|
5065
|
+
__npmBase: '/__kreft/npm/', // where kreft dev serves files from node_modules (CSS imports)
|
|
5066
5066
|
__import: (url) => import(url), // how built apps load the .js modules a .kreftjs file imports
|
|
5067
5067
|
__precompiled: precompiled,
|
|
5068
5068
|
__hot: hotUpdate,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kreftjs",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.4-beta",
|
|
4
4
|
"description": "A tiny reactive framework with its own component language (.kreftjs files): router with nested routes, stores, saved data, animations, an API client, hot reload, DevTools and a template engine.",
|
|
5
5
|
"main": "kreftjs.js",
|
|
6
6
|
"browser": "kreftjs.js",
|
package/templates/app/README.md
CHANGED
|
@@ -51,28 +51,28 @@ Generate full-stack features from the terminal:
|
|
|
51
51
|
|
|
52
52
|
```bash
|
|
53
53
|
# Generate Model + Migration + Factory + Seeder + Controller + .kreftjs Page + Route:
|
|
54
|
-
|
|
54
|
+
kreft make:model Post --all
|
|
55
55
|
|
|
56
56
|
# Or pick specific layers (-m migration, -f factory, -s seeder, -c controller, -p page, -r route):
|
|
57
|
-
|
|
57
|
+
kreft make:model Post -mfscpr --route=api --auth
|
|
58
58
|
|
|
59
59
|
# Individual generators:
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
60
|
+
kreft make:controller OrderController --api
|
|
61
|
+
kreft make:request StorePostRequest --model Post
|
|
62
|
+
kreft make:resource PostResource
|
|
63
|
+
kreft make:rule StrongPassword
|
|
64
|
+
kreft make:observer PostObserver --model Post
|
|
65
|
+
kreft make:middleware EnsureSubscribed
|
|
66
|
+
kreft make:job ProcessWebhook
|
|
67
|
+
kreft make:mail InvoiceReady
|
|
68
|
+
kreft make:routes billing # Creates frontend/routes/billing.kreftjs & backend/routes/billing.js
|
|
69
69
|
|
|
70
70
|
# Database & inspection tools:
|
|
71
71
|
kreftjs db:migrate # Run pending migrations
|
|
72
|
-
|
|
73
|
-
|
|
72
|
+
kreft db:seed # Run database seeders
|
|
73
|
+
kreft route:list # List all registered backend API routes
|
|
74
74
|
kreftjs redis:ping # Verify Redis connectivity
|
|
75
|
-
|
|
75
|
+
kreft tinker # Interactive REPL with your Models, DB, Cache & Redis preloaded
|
|
76
76
|
```
|
|
77
77
|
|
|
78
78
|
---
|
|
@@ -111,17 +111,17 @@ action create() {
|
|
|
111
111
|
|
|
112
112
|
## Installing & Updating Packages
|
|
113
113
|
|
|
114
|
-
Use `
|
|
114
|
+
Use `kreft add` to install npm packages safely (blocks untrusted lifecycle scripts, checks for typosquatting, and skips redundant packages already built into Kreft):
|
|
115
115
|
|
|
116
116
|
```bash
|
|
117
|
-
|
|
118
|
-
|
|
117
|
+
kreft add dayjs nanoid
|
|
118
|
+
kreft add -D esbuild # Bundles browser packages into import-mapped modules
|
|
119
119
|
```
|
|
120
120
|
|
|
121
121
|
Keep dependencies and your embedded Kreft runtime up to date:
|
|
122
122
|
|
|
123
123
|
```bash
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
124
|
+
kreft update # Update npm dependencies & refresh kreftjs.js / kreftjs.d.ts
|
|
125
|
+
kreft update --check # Check for outdated packages without modifying files
|
|
126
|
+
kreft update --core # Refresh only Kreft runtime & TypeScript definitions
|
|
127
127
|
```
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// The queue's tables: jobs waiting (
|
|
1
|
+
// The queue's tables: jobs waiting (kreft queue:work, or kreft dev, runs them) and jobs that failed
|
|
2
2
|
module.exports = {
|
|
3
3
|
up(schema) {
|
|
4
4
|
schema.create('jobs', (table) => {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const { Seeder, Hash } = require('kreftjs/server')
|
|
2
2
|
const User = require('../../app/Models/User')
|
|
3
3
|
|
|
4
|
-
//
|
|
4
|
+
// kreft db:seed (kreft dev --seed fills a new database). Sign in as test@example.com / password;
|
|
5
5
|
// that user is an admin too, so /admin opens for it
|
|
6
6
|
class DatabaseSeeder extends Seeder {
|
|
7
7
|
async run() {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Your API: every address here starts with /api.
|
|
2
2
|
// All API routes live directly in this file. Add your new routes here!
|
|
3
|
-
// See them all anytime with:
|
|
3
|
+
// See them all anytime with: kreft route:list
|
|
4
4
|
const { Route, use, namespace } = require('kreftjs/server')
|
|
5
5
|
|
|
6
6
|
// PHP-style namespace imports (e.g. use('App\Http\Controllers\Admin\UserController')):
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
// What runs on a schedule.
|
|
2
|
-
// on a server:
|
|
1
|
+
// What runs on a schedule. kreft dev runs it while it is on;
|
|
2
|
+
// on a server: kreft schedule:work (or `kreft schedule:run` from cron every minute). See them: kreft schedule:list
|
|
3
3
|
const { Schedule } = require('kreftjs/server')
|
|
4
4
|
|
|
5
5
|
// Schedule.call(async () => { … }).daily().name('clean-up')
|
|
@@ -90,7 +90,7 @@ action copyReport() {
|
|
|
90
90
|
<div class="badges">
|
|
91
91
|
<span class="badge danger-badge">HTTP {status}</span>
|
|
92
92
|
<span class="badge solid">{currentTitle}</span>
|
|
93
|
-
<span class="badge">Kreft {Kreftjs.version || '0.0.
|
|
93
|
+
<span class="badge">Kreft {Kreftjs.version || '0.0.4-beta'}</span>
|
|
94
94
|
</div>
|
|
95
95
|
<div class="actions">
|
|
96
96
|
<button class="sm" @click={copyReport}>{copied ? 'Copied Markdown' : 'Copy Report'}</button>
|
|
@@ -187,7 +187,7 @@ action copyReport() {
|
|
|
187
187
|
<h3>Kreft Runtime</h3>
|
|
188
188
|
<table>
|
|
189
189
|
<tbody>
|
|
190
|
-
<tr><th>Engine</th><td><code>Kreft v{Kreftjs.version || '0.0.
|
|
190
|
+
<tr><th>Engine</th><td><code>Kreft v{Kreftjs.version || '0.0.4-beta'}</code></td></tr>
|
|
191
191
|
<tr><th>Sanitizer</th><td><code>Active (cleanHtml / SafeHtml)</code></td></tr>
|
|
192
192
|
<tr><th>Environment</th><td><code>development (APP_DEBUG=true)</code></td></tr>
|
|
193
193
|
</tbody>
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
}, { saved: ['user'] })
|
|
32
32
|
|
|
33
33
|
const router = Kreftjs.router({
|
|
34
|
-
routes: ['routes/web.kreftjs'], // the pages are in routes/web.kreftjs; add more files:
|
|
34
|
+
routes: ['routes/web.kreftjs'], // the pages are in routes/web.kreftjs; add more files: kreft make:routes admin
|
|
35
35
|
layout: 'app', // every page goes inside layouts/app.kreftjs…
|
|
36
36
|
errors: 'errors', // error pages: errors/404.kreftjs for unknown addresses, abort(403) → errors/403.kreftjs
|
|
37
37
|
// the names routes use in .middleware(…): return an address to send the visitor there instead
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* Kreft v0.0.
|
|
2
|
+
* Kreft v0.0.4-beta — reactive by nature
|
|
3
3
|
* The .kreftjs component language (state · derive · action · when · watch · on),
|
|
4
4
|
* { } views with k-if / k-each / k-model, components, slots, router, stores,
|
|
5
5
|
* share / receive, event bus and a template engine.
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
} catch (e) { console.error('[Kreft error]', e); }
|
|
29
29
|
};
|
|
30
30
|
const text = () => document.createTextNode('');
|
|
31
|
-
// `
|
|
31
|
+
// `kreft dev` turns this on: live components are tracked for hot reload and the DevTools panel
|
|
32
32
|
const devMode = () => !!(global.__KREFT_DEV__ || global.__SOM_DEV__);
|
|
33
33
|
const liveInstances = new Set();
|
|
34
34
|
const BAD_PATH_KEYS = new Set(['__proto__', 'constructor', 'prototype']);
|
|
@@ -674,7 +674,7 @@
|
|
|
674
674
|
// build many different templates (Kreftjs.render, the Template engine page) don't grow forever
|
|
675
675
|
const fnCache = new Map();
|
|
676
676
|
const FN_CACHE_MAX = 3000;
|
|
677
|
-
// `
|
|
677
|
+
// `kreft build` fills this with ready-made functions, so built apps never need eval (strict CSP)
|
|
678
678
|
const precompiled = Object.create(null);
|
|
679
679
|
const FORBIDDEN_EXP_RE = /(?:^|[^$\w])(?:constructor|__proto__|prototype)(?:[^$\w]|$)/;
|
|
680
680
|
function compileFn(code, params = '__s') {
|
|
@@ -1709,7 +1709,7 @@
|
|
|
1709
1709
|
function addPresets() {
|
|
1710
1710
|
if (presetsAdded || typeof document === 'undefined') return;
|
|
1711
1711
|
presetsAdded = true;
|
|
1712
|
-
if (document.querySelector('[data-kreft-presets]')) return; // `
|
|
1712
|
+
if (document.querySelector('[data-kreft-presets]')) return; // `kreft build` put them in app.css
|
|
1713
1713
|
const st = document.createElement('style');
|
|
1714
1714
|
st.setAttribute('data-kreft-presets', '');
|
|
1715
1715
|
st.textContent = PRESET_CSS;
|
|
@@ -2235,7 +2235,7 @@
|
|
|
2235
2235
|
return out;
|
|
2236
2236
|
}
|
|
2237
2237
|
// Som.js names still work in a template: `s-if` is read as `k-if` and `<som-view>` as `<kreft-view>`.
|
|
2238
|
-
// It runs on the finished markup, so the browser, `
|
|
2238
|
+
// It runs on the finished markup, so the browser, `kreft build` and the Vite plugin all see the same names.
|
|
2239
2239
|
const LEGACY_TAGS = /^som-(?=(?:wait|view|component|yield|section|portal|link)$)/i;
|
|
2240
2240
|
const TAG_SCAN = /<(\/?)([A-Za-z][\w:.-]*)((?:\s+[^\s"'<>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s"'>]+))?)*)(\s*\/?>)/g;
|
|
2241
2241
|
const ATTR_SCAN = /(\s+)([^\s"'<>\/=]+)(\s*=\s*(?:"[^"]*"|'[^']*'|[^\s"'>]+))?/g;
|
|
@@ -2745,7 +2745,7 @@
|
|
|
2745
2745
|
// copy with descriptors so getters stay getters (computed)
|
|
2746
2746
|
let def = rootComponent; // a .kreftjs path like 'App.kreftjs', or an object
|
|
2747
2747
|
let source = container.innerHTML;
|
|
2748
|
-
if (container.hasAttribute('data-kreft-ssg')) { // a page made by `
|
|
2748
|
+
if (container.hasAttribute('data-kreft-ssg')) { // a page made by `kreft build --prerender`: its first view came ready
|
|
2749
2749
|
const t = document.querySelector('template[data-kreft-ssg-source]');
|
|
2750
2750
|
source = t ? t.innerHTML : '';
|
|
2751
2751
|
container.removeAttribute('data-kreft-ssg');
|
|
@@ -3874,7 +3874,7 @@
|
|
|
3874
3874
|
addStylesheet(abs === spec ? Kreftjs.__npmBase + spec : abs);
|
|
3875
3875
|
continue;
|
|
3876
3876
|
}
|
|
3877
|
-
const mod = await Kreftjs.__import(abs); // one place to load modules (
|
|
3877
|
+
const mod = await Kreftjs.__import(abs); // one place to load modules (kreft build uses it too)
|
|
3878
3878
|
if (!what) continue;
|
|
3879
3879
|
what.split(/,(?![^{]*\})/).map((s) => s.trim()).forEach((part) => {
|
|
3880
3880
|
if (part.startsWith('* as ')) values[part.slice(5).trim()] = mod;
|
|
@@ -4072,7 +4072,7 @@
|
|
|
4072
4072
|
return st;
|
|
4073
4073
|
}
|
|
4074
4074
|
|
|
4075
|
-
// Pure text work, shared by the browser and `
|
|
4075
|
+
// Pure text work, shared by the browser and `kreft build`: .kreftjs source → its parts
|
|
4076
4076
|
function splitKreft(source, url = 'inline.kreftjs') {
|
|
4077
4077
|
const name = (url.split('/').pop() || '').replace(/[?#].*$/, '').replace(EXT_RE, '');
|
|
4078
4078
|
source = source.replace(/\r\n?/g, '\n');
|
|
@@ -4105,7 +4105,7 @@
|
|
|
4105
4105
|
}
|
|
4106
4106
|
const propType = (sample) => (typeof sample === 'number' ? Number : typeof sample === 'boolean' ? Boolean : typeof sample === 'string' ? String : undefined);
|
|
4107
4107
|
|
|
4108
|
-
// parts (from the browser compiler or from `
|
|
4108
|
+
// parts (from the browser compiler or from `kreft build`) → component definition
|
|
4109
4109
|
function makeKreftDef(parts, values) {
|
|
4110
4110
|
const def = {
|
|
4111
4111
|
__name: parts.name,
|
|
@@ -4155,7 +4155,7 @@
|
|
|
4155
4155
|
return makeKreftDef({ name: sp.name, template: sp.template, props, events: sp.events, layout: sp.layout, scopeId, components, run }, values);
|
|
4156
4156
|
}
|
|
4157
4157
|
|
|
4158
|
-
// Used by the app.js that `
|
|
4158
|
+
// Used by the app.js that `kreft build` writes: registers a component that is already compiled
|
|
4159
4159
|
function defineCompiled(path, parts) {
|
|
4160
4160
|
const abs = new URL(path, document.baseURI).href;
|
|
4161
4161
|
kreftCache.set(abs, parts.loadValues
|
|
@@ -4271,7 +4271,7 @@
|
|
|
4271
4271
|
// mode 'history' (default): clean URLs like /users/5 — the server must send index.html for every path.
|
|
4272
4272
|
// mode 'hash': URLs like #/users/5 — works with any server, even file://.
|
|
4273
4273
|
// Error pages: errors/404.kreftjs, errors/403.kreftjs, errors/500.kreftjs …
|
|
4274
|
-
// (Kreftjs.router({ errors: 'errors' }) turns them on; `
|
|
4274
|
+
// (Kreftjs.router({ errors: 'errors' }) turns them on; `kreft make:errors` writes them into a project)
|
|
4275
4275
|
const ERROR_PAGES = [401, 402, 403, 404, 419, 429, 500, 503];
|
|
4276
4276
|
const ERROR_TITLES = { 400: 'Bad Request', 401: 'Unauthorized', 402: 'Payment Required', 403: 'Forbidden', 404: 'Not Found', 405: 'Method Not Allowed', 409: 'Conflict', 410: 'Gone', 419: 'Page Expired', 422: 'Unprocessable Content', 429: 'Too Many Requests', 500: 'Server Error', 502: 'Bad Gateway', 503: 'Service Unavailable', 504: 'Gateway Timeout' };
|
|
4277
4277
|
let activeRouter = null;
|
|
@@ -4285,7 +4285,7 @@
|
|
|
4285
4285
|
* Route.redirect('/home', '/')
|
|
4286
4286
|
* Route.view('/settings', 'pages/Settings.kreftjs').children(() => { Route.view('profile', 'pages/settings/Profile.kreftjs') })
|
|
4287
4287
|
*/
|
|
4288
|
-
const routeFiles = new Map(); // absolute URL → function (Route) { … } (
|
|
4288
|
+
const routeFiles = new Map(); // absolute URL → function (Route) { … } (kreft build puts them in app.js)
|
|
4289
4289
|
function defineRoutes(path, fn) { routeFiles.set(new URL(path, document.baseURI).href, fn); }
|
|
4290
4290
|
function makeRouteBuilder() {
|
|
4291
4291
|
const top = [];
|
|
@@ -4852,7 +4852,7 @@
|
|
|
4852
4852
|
}
|
|
4853
4853
|
|
|
4854
4854
|
/* ================================================================
|
|
4855
|
-
* Kreftjs.table('posts') — the rows of a database table that `
|
|
4855
|
+
* Kreftjs.table('posts') — the rows of a database table that `kreft dev --db` / `kreft serve --db` serve
|
|
4856
4856
|
* const posts = Kreftjs.table('posts')
|
|
4857
4857
|
* await posts.all({ userId: 3, _sort: '-id', _limit: 20 }) posts.find(1) posts.count()
|
|
4858
4858
|
* await posts.create({ title }) posts.update(1, row) posts.patch(1, { title }) posts.remove(1)
|
|
@@ -4876,7 +4876,7 @@
|
|
|
4876
4876
|
}
|
|
4877
4877
|
|
|
4878
4878
|
/* ================================================================
|
|
4879
|
-
* Developer tools (used by `
|
|
4879
|
+
* Developer tools (used by `kreft dev`: hot reload and the DevTools panel)
|
|
4880
4880
|
* ================================================================ */
|
|
4881
4881
|
const isInside = (i, o) => { for (let p = i.parent; p; p = p.parent) if (p === o) return true; return false; };
|
|
4882
4882
|
/* ================================================================
|
|
@@ -5032,10 +5032,10 @@
|
|
|
5032
5032
|
stores, storeLog, busLog,
|
|
5033
5033
|
};
|
|
5034
5034
|
|
|
5035
|
-
const VERSION = '0.0.
|
|
5035
|
+
const VERSION = '0.0.4-beta';
|
|
5036
5036
|
const Kreftjs = {
|
|
5037
5037
|
version: VERSION,
|
|
5038
|
-
// PUBLIC_ values from .env (
|
|
5038
|
+
// PUBLIC_ values from .env (kreft dev and kreft build put them here); never secrets
|
|
5039
5039
|
get env() { return Object.freeze({ ...((typeof window !== 'undefined' && (window.__KREFT_ENV__ || window.__SOM_ENV__)) || {}) }); },
|
|
5040
5040
|
get isVite() {
|
|
5041
5041
|
return Boolean(typeof window !== 'undefined' && (window.__KREFT_VITE__ || window.__SOM_VITE__));
|
|
@@ -5055,14 +5055,14 @@
|
|
|
5055
5055
|
abort: abortPage,
|
|
5056
5056
|
// apps & components
|
|
5057
5057
|
app: createApp, lazy, load, compile: compileKreft, compileSom: compileKreft, render, // compileSom: the Som.js name, kept as an alias
|
|
5058
|
-
// used by `
|
|
5058
|
+
// used by `kreft build`, Vite plugin and the app.js it writes
|
|
5059
5059
|
__makeDef: makeKreftDef,
|
|
5060
5060
|
__registerDef: registerDef,
|
|
5061
5061
|
__hotDef: hotDef,
|
|
5062
5062
|
__define: defineCompiled,
|
|
5063
5063
|
__routes: defineRoutes,
|
|
5064
5064
|
__fileHeaders: (url) => fileHeaders(new URL(url, document.baseURI).href),
|
|
5065
|
-
__npmBase: '/__kreft/npm/', // where
|
|
5065
|
+
__npmBase: '/__kreft/npm/', // where kreft dev serves files from node_modules (CSS imports)
|
|
5066
5066
|
__import: (url) => import(url), // how built apps load the .js modules a .kreftjs file imports
|
|
5067
5067
|
__precompiled: precompiled,
|
|
5068
5068
|
__hot: hotUpdate,
|
|
@@ -110,7 +110,7 @@ load board = api.get('/api/dashboard')
|
|
|
110
110
|
<div class="info-list">
|
|
111
111
|
<div class="info-item">
|
|
112
112
|
<span class="info-label">Framework Engine</span>
|
|
113
|
-
<span class="info-value">Kreft {Kreftjs.version || '0.0.
|
|
113
|
+
<span class="info-value">Kreft {Kreftjs.version || '0.0.4-beta'}</span>
|
|
114
114
|
</div>
|
|
115
115
|
<div class="info-item">
|
|
116
116
|
<span class="info-label">Active Database</span>
|
|
@@ -59,7 +59,7 @@ derive sampleError = scenario === 'method' ? {
|
|
|
59
59
|
],
|
|
60
60
|
solution: {
|
|
61
61
|
title: 'Pending Database Migration',
|
|
62
|
-
message: "Run 'kreftjs db:migrate' or create the table with '
|
|
62
|
+
message: "Run 'kreftjs db:migrate' or create the table with 'kreft make:migration create_tasks_archive_table'."
|
|
63
63
|
}
|
|
64
64
|
}
|
|
65
65
|
|
|
@@ -34,7 +34,7 @@ state parts = [
|
|
|
34
34
|
|
|
35
35
|
action add() { count++ }
|
|
36
36
|
action copy() {
|
|
37
|
-
navigator.clipboard && navigator.clipboard.writeText('
|
|
37
|
+
navigator.clipboard && navigator.clipboard.writeText('kreft new my-app --db sqlite')
|
|
38
38
|
copied = true
|
|
39
39
|
setTimeout(() => (copied = false), 1500)
|
|
40
40
|
}
|
|
@@ -194,7 +194,7 @@ action copy() {
|
|
|
194
194
|
<section class="begin">
|
|
195
195
|
<h2>Start a project</h2>
|
|
196
196
|
<div class="term">
|
|
197
|
-
<code>
|
|
197
|
+
<code>kreft new my-app --db sqlite</code>
|
|
198
198
|
<button class="sm" @click={copy} aria-label="Copy the command">{copied ? 'Copied' : 'Copy'}</button>
|
|
199
199
|
</div>
|
|
200
200
|
<p>Then <code>cd my-app</code> and <code>npm run dev</code>. Coming from Vue? The <kreft-link to="/docs">docs</kreft-link> have a table with the Kreft name for every Vue feature.</p>
|
|
@@ -116,7 +116,7 @@ action copyReport() {
|
|
|
116
116
|
<div class="hero-badges">
|
|
117
117
|
<span class="badge-exception">{currentTitle}</span>
|
|
118
118
|
<span class="badge-env">Node.js {typeof process !== 'undefined' ? process.version : 'v22.0.0'}</span>
|
|
119
|
-
<span class="badge-env">Kreft v0.0.
|
|
119
|
+
<span class="badge-env">Kreft v0.0.4-beta</span>
|
|
120
120
|
</div>
|
|
121
121
|
<h1 class="hero-error-message">{currentMessage}</h1>
|
|
122
122
|
</div>
|