kreftjs 0.0.7-beta → 0.0.9-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 +2 -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 +22 -18
- 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 +89 -102
- 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 +69 -79
- package/package.json +4 -4
- package/templates/app/README.md +10 -10
- package/templates/app/_env.example +2 -2
- 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 +1 -1
- package/templates/app/backend/app/Http/Controllers/Auth/PasswordResetLinkController.js +1 -1
- package/templates/app/backend/app/Http/Controllers/Auth/RegisteredUserController.js +1 -1
- 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 +1 -1
- package/templates/app/backend/app/Http/Middleware/RequirePassword.js +1 -1
- 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 +69 -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} +3 -3
- 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/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/{Register.kreftjs → Register.kreft} +0 -0
- /package/templates/app/frontend/pages/auth/{ResetPassword.kreftjs → ResetPassword.kreft} +0 -0
- /package/templates/app/frontend/pages/auth/{VerifyEmail.kreftjs → VerifyEmail.kreft} +0 -0
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.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kreftjs",
|
|
3
|
-
"displayName": "Kreft (.
|
|
4
|
-
"description": "Colors, brackets, formatting and snippets for Kreft .
|
|
3
|
+
"displayName": "Kreft (.kreft files)",
|
|
4
|
+
"description": "Colors, brackets, formatting and snippets for Kreft .kreft component files (and .kreftjs files from the 0.0.x betas).",
|
|
5
5
|
"version": "2.3.0",
|
|
6
6
|
"publisher": "kreft",
|
|
7
7
|
"license": "MIT",
|
|
@@ -26,9 +26,8 @@
|
|
|
26
26
|
"kreftjs"
|
|
27
27
|
],
|
|
28
28
|
"extensions": [
|
|
29
|
-
".kreftjs",
|
|
30
29
|
".kreft",
|
|
31
|
-
".
|
|
30
|
+
".kreftjs"
|
|
32
31
|
],
|
|
33
32
|
"configuration": "./language-configuration.json"
|
|
34
33
|
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"Component": {
|
|
3
3
|
"prefix": "kreftjs",
|
|
4
4
|
"body": ["state ${1:count} = ${2:0}", "", "action ${3:add}() {", " ${1:count}++", "}", "", "<view>", " <button @click={${3:add}}>{${1:count}}</button>", "</view>", "", "<style scoped>", " $0", "</style>"],
|
|
5
|
-
"description": "A new .
|
|
5
|
+
"description": "A new .kreft component"
|
|
6
6
|
},
|
|
7
7
|
"state": { "prefix": "state", "body": "state ${1:name} = ${2:0}", "description": "A value the view follows" },
|
|
8
8
|
"saved": { "prefix": "saved", "body": "saved ${1:name} = ${2:[]}", "description": "A value kept after a reload (localStorage)" },
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"when": { "prefix": "when", "body": ["when ${1:condition} {", " $0", "}"], "description": "Run when a condition becomes true" },
|
|
13
13
|
"watch": { "prefix": "watch", "body": ["watch ${1:value} {", " $0", "}"], "description": "Run when a value changes (value, old)" },
|
|
14
14
|
"on": { "prefix": "on", "body": ["on ${1|start,ready,update,show,hide,destroy|} {", " $0", "}"], "description": "Lifecycle" },
|
|
15
|
-
"layout": { "prefix": "layout", "body": "layout ${1:app}", "description": "This page goes inside layouts/<name>.
|
|
15
|
+
"layout": { "prefix": "layout", "body": "layout ${1:app}", "description": "This page goes inside layouts/<name>.kreft (layout none: no layout)" },
|
|
16
16
|
"section": { "prefix": "kreft-section", "body": ["<kreft-section name=\"${1:actions}\">", " $0", "</kreft-section>"], "description": "Content for the layout's <kreft-yield name>" },
|
|
17
17
|
"yield": { "prefix": "kreft-yield", "body": "<kreft-yield name=\"${1:actions}\">${0}</kreft-yield>", "description": "In a layout: where a page's <kreft-section> goes" },
|
|
18
18
|
"for": { "prefix": "for", "body": ["{for ${1:item} in ${2:items} key ${1:item}.id}", " $0", "{empty}", " <p>Nothing yet.</p>", "{/for}"], "description": "Loop over a list" },
|
package/kreftjs.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Type definitions for Kreft 0.0.
|
|
1
|
+
// Type definitions for Kreft 0.0.9-beta
|
|
2
2
|
// Use from TypeScript or for editor hints in plain JavaScript (// @ts-check).
|
|
3
3
|
|
|
4
4
|
export interface Signal<T> { value: T }
|
|
@@ -212,7 +212,7 @@ export interface ComponentDef {
|
|
|
212
212
|
destroyed?(): void
|
|
213
213
|
[key: string]: any
|
|
214
214
|
}
|
|
215
|
-
/** A component: an object, an init function, a lazy() loader or the address of a .
|
|
215
|
+
/** A component: an object, an init function, a lazy() loader or the address of a .kreft file */
|
|
216
216
|
export type Component = ComponentDef | ((props: any, ctx: Context) => object | void) | LazyComponent | string
|
|
217
217
|
export interface LazyComponent { __loader: () => Promise<any> }
|
|
218
218
|
|
|
@@ -248,7 +248,7 @@ export interface RouteRecord {
|
|
|
248
248
|
guard?: Guard
|
|
249
249
|
/** Child routes, shown in the page's own <kreft-view> */
|
|
250
250
|
children?: RouteRecord[]
|
|
251
|
-
/** The layout for this route and its children: 'admin' → layouts/admin.
|
|
251
|
+
/** The layout for this route and its children: 'admin' → layouts/admin.kreft, a .kreft path, a component, or false for none */
|
|
252
252
|
layout?: string | Component | false
|
|
253
253
|
}
|
|
254
254
|
export interface Route {
|
|
@@ -266,7 +266,7 @@ export type RouteTarget = string | { path?: string; name?: string; params?: Reco
|
|
|
266
266
|
export type Guard = (to: Route, from: Route) => boolean | void | RouteTarget | Promise<boolean | void | RouteTarget>
|
|
267
267
|
export interface Router {
|
|
268
268
|
readonly route: Route
|
|
269
|
-
/** shows errors/<status>.
|
|
269
|
+
/** shows errors/<status>.kreft for this address: abort(403, 'Only the owner can see this.') */
|
|
270
270
|
abort(status?: number, message?: string): void
|
|
271
271
|
readonly routes: RouteRecord[]
|
|
272
272
|
go(to: RouteTarget | number): Promise<void> | void
|
|
@@ -282,7 +282,7 @@ export interface Router {
|
|
|
282
282
|
ready(): Promise<void>
|
|
283
283
|
install(app: App): void
|
|
284
284
|
}
|
|
285
|
-
/** routes/web.
|
|
285
|
+
/** routes/web.kreft: `Route` is there without an import */
|
|
286
286
|
export interface RouteEntry {
|
|
287
287
|
name(name: string): RouteEntry
|
|
288
288
|
title(title: string): RouteEntry
|
|
@@ -307,7 +307,7 @@ export interface RouteGroup {
|
|
|
307
307
|
group(fn: (route: RouteFile) => void): RouteFile
|
|
308
308
|
}
|
|
309
309
|
export interface RouteFile {
|
|
310
|
-
/** a page: Route.view('/posts/:id', 'pages/Post.
|
|
310
|
+
/** a page: Route.view('/posts/:id', 'pages/Post.kreft') — :id reaches the page as a prop */
|
|
311
311
|
view(path: string, component: string | Component): RouteEntry
|
|
312
312
|
get(path: string, component: string | Component): RouteEntry
|
|
313
313
|
redirect(from: string, to: string): void
|
|
@@ -325,25 +325,25 @@ export interface RouteFile {
|
|
|
325
325
|
export type RouteMiddleware = (to: Route, from: Route, ...args: string[]) => boolean | string | object | void | Promise<boolean | string | object | void>
|
|
326
326
|
|
|
327
327
|
export interface RouterOptions {
|
|
328
|
-
/** route objects, or route files: 'routes/web.
|
|
328
|
+
/** route objects, or route files: 'routes/web.kreft' / ['routes/web.kreft', 'routes/admin.kreft'] (both can be mixed) */
|
|
329
329
|
routes: RouteRecord[] | string | (string | RouteRecord)[]
|
|
330
330
|
/** the names routes use in .middleware(…): { auth: (to) => auth.token ? true : '/login' } */
|
|
331
331
|
middleware?: Record<string, RouteMiddleware>
|
|
332
332
|
mode?: 'history' | 'hash'
|
|
333
333
|
base?: string
|
|
334
334
|
scrollToTop?: boolean
|
|
335
|
-
/** The layout every page goes in: 'app' → layouts/app.
|
|
335
|
+
/** The layout every page goes in: 'app' → layouts/app.kreft (a page's `layout x`, or a route's `layout`, wins) */
|
|
336
336
|
layout?: string | Component | false
|
|
337
|
-
/** Names for layouts that live elsewhere: { admin: 'views/AdminShell.
|
|
337
|
+
/** Names for layouts that live elsewhere: { admin: 'views/AdminShell.kreft' } */
|
|
338
338
|
layouts?: Record<string, string | Component>
|
|
339
|
-
/** The folder with the error pages (errors/404.
|
|
339
|
+
/** The folder with the error pages (errors/404.kreft, 403, 500…): unknown addresses show 404.kreft, abort(…) the others */
|
|
340
340
|
errors?: string | boolean
|
|
341
341
|
}
|
|
342
342
|
|
|
343
343
|
/* ---------------- Kreft ---------------- */
|
|
344
344
|
export interface KreftStatic {
|
|
345
345
|
readonly version: string
|
|
346
|
-
/** PUBLIC_ values from .env (also `env` in .
|
|
346
|
+
/** PUBLIC_ values from .env (also `env` in .kreft files). Never secrets: those stay in server code */
|
|
347
347
|
readonly env: Readonly<Record<string, string>>
|
|
348
348
|
/** true when running inside an Electron desktop window */
|
|
349
349
|
readonly isElectron: boolean
|
|
@@ -354,15 +354,13 @@ export interface KreftStatic {
|
|
|
354
354
|
__makeDef(parts: any, values?: any): ComponentDef
|
|
355
355
|
__registerDef(path: string, def: any): any
|
|
356
356
|
__hotDef(id: string, newDef: any): boolean
|
|
357
|
-
/** the error page for this address: abort(404), abort(403, 'Only the owner can see this.') (also `abort` in .
|
|
357
|
+
/** the error page for this address: abort(404), abort(403, 'Only the owner can see this.') (also `abort` in .kreft files) */
|
|
358
358
|
abort(status?: number, message?: string): void
|
|
359
359
|
app(root?: Component, props?: Record<string, any>): App
|
|
360
360
|
lazy(loader: () => Promise<any>): LazyComponent
|
|
361
361
|
load(url: string): Promise<ComponentDef>
|
|
362
|
-
/** Compiles the text of a .
|
|
362
|
+
/** Compiles the text of a .kreft file into a component */
|
|
363
363
|
compile(source: string, url?: string): Promise<ComponentDef>
|
|
364
|
-
/** @deprecated the Som.js name of `compile` */
|
|
365
|
-
compileSom(source: string, url?: string): Promise<ComponentDef>
|
|
366
364
|
/** Strips TypeScript type annotations, interfaces, type aliases and enums from source code while preserving line numbers */
|
|
367
365
|
stripTypeScript(source: string): string
|
|
368
366
|
/** The template engine: a view and data → an HTML string */
|
|
@@ -552,28 +550,18 @@ declare global {
|
|
|
552
550
|
var Kreftjs: KreftStatic
|
|
553
551
|
/** the shorter name of `Kreftjs` */
|
|
554
552
|
var Kreft: KreftStatic
|
|
555
|
-
/** @deprecated the Som.js name of `Kreftjs` */
|
|
556
|
-
var Som: KreftStatic
|
|
557
553
|
interface Window {
|
|
558
554
|
kreftDesktop?: DesktopBridge
|
|
559
|
-
/** @deprecated the Som.js name of `kreftDesktop` */
|
|
560
|
-
somDesktop?: DesktopBridge
|
|
561
555
|
}
|
|
562
556
|
}
|
|
563
557
|
|
|
564
|
-
declare module '*.kreftjs' {
|
|
565
|
-
const component: import('./kreftjs.js').ComponentDef
|
|
566
|
-
export default component
|
|
567
|
-
}
|
|
568
|
-
|
|
569
|
-
// files from older projects (.kreft, then Som.js's .som)
|
|
570
558
|
declare module '*.kreft' {
|
|
571
559
|
const component: import('./kreftjs.js').ComponentDef
|
|
572
560
|
export default component
|
|
573
561
|
}
|
|
574
562
|
|
|
575
|
-
|
|
563
|
+
// files from the 0.0.x betas (.kreftjs)
|
|
564
|
+
declare module '*.kreftjs' {
|
|
576
565
|
const component: import('./kreftjs.js').ComponentDef
|
|
577
566
|
export default component
|
|
578
567
|
}
|
|
579
|
-
|
package/kreftjs.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* Kreft v0.0.
|
|
3
|
-
* The .
|
|
2
|
+
* Kreft v0.0.9-beta — reactive by nature
|
|
3
|
+
* The .kreft 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.
|
|
6
6
|
* One file, no build step, no virtual DOM. MIT License.
|
|
@@ -29,7 +29,7 @@
|
|
|
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
|
-
const devMode = () => !!
|
|
32
|
+
const devMode = () => !!global.__KREFT_DEV__;
|
|
33
33
|
const liveInstances = new Set();
|
|
34
34
|
const BAD_PATH_KEYS = new Set(['__proto__', 'constructor', 'prototype']);
|
|
35
35
|
const getPath = (obj, path) => String(path).split('.').reduce((o, k) => (o == null || BAD_PATH_KEYS.has(k) ? undefined : o[k]), obj);
|
|
@@ -651,8 +651,8 @@
|
|
|
651
651
|
return replacePlaceholders(chosen, fullReplace);
|
|
652
652
|
}
|
|
653
653
|
|
|
654
|
-
if (typeof window !== 'undefined' && (window.__KREFT_LANG__
|
|
655
|
-
addTranslations(window.__KREFT_LANG__
|
|
654
|
+
if (typeof window !== 'undefined' && (window.__KREFT_LANG__)) {
|
|
655
|
+
addTranslations(window.__KREFT_LANG__);
|
|
656
656
|
}
|
|
657
657
|
|
|
658
658
|
function formatNumber(n, options, locale = currentLocaleRef.value) {
|
|
@@ -1898,9 +1898,9 @@
|
|
|
1898
1898
|
|
|
1899
1899
|
/* ---------- <kreft-view>: the page for the current route (nested views show child routes) ----------
|
|
1900
1900
|
* Layouts: the page is shown inside a layout component, in its <slot>.
|
|
1901
|
-
* Kreftjs.router({ layout: 'app', routes }) every page uses layouts/app.
|
|
1902
|
-
* { path: '/admin', component: …, layout: 'admin' } this route (and its children) use layouts/admin.
|
|
1903
|
-
* layout admin in a page's .
|
|
1901
|
+
* Kreftjs.router({ layout: 'app', routes }) every page uses layouts/app.kreft
|
|
1902
|
+
* { path: '/admin', component: …, layout: 'admin' } this route (and its children) use layouts/admin.kreft
|
|
1903
|
+
* layout admin in a page's .kreft file: this page uses it
|
|
1904
1904
|
* layout none / layout: false no layout
|
|
1905
1905
|
* Moving between pages with the same layout keeps the layout on the page (its state stays).
|
|
1906
1906
|
* ------------------------------------------------------------------------------------------- */
|
|
@@ -1953,7 +1953,7 @@
|
|
|
1953
1953
|
const p = loadDef(def).then(() => { loaded.value++; }, (e) => {
|
|
1954
1954
|
def.__failed = true;
|
|
1955
1955
|
def.__failedError = e;
|
|
1956
|
-
if (router.__errors) { console.error('[Kreft error] the page could not be loaded:', e); return router.abort(500, e && e.message); } // errors/500.
|
|
1956
|
+
if (router.__errors) { console.error('[Kreft error] the page could not be loaded:', e); return router.abort(500, e && e.message); } // errors/500.kreft
|
|
1957
1957
|
loaded.value++; // the page reports its own error
|
|
1958
1958
|
});
|
|
1959
1959
|
if (first) waitFor(p);
|
|
@@ -2028,7 +2028,7 @@
|
|
|
2028
2028
|
|
|
2029
2029
|
/* ---------- <kreft-wait>: show something else until everything inside has loaded ----------
|
|
2030
2030
|
* <kreft-wait>
|
|
2031
|
-
* <UserList /> (its .
|
|
2031
|
+
* <UserList /> (its .kreft file, `load` data, async `on start`)
|
|
2032
2032
|
* <p k-waiting>Loading…</p>
|
|
2033
2033
|
* <p k-failed="error">Could not load: {error.message}</p>
|
|
2034
2034
|
* </kreft-wait>
|
|
@@ -2234,20 +2234,7 @@
|
|
|
2234
2234
|
if (open.length) throw new SyntaxError('A {for} block is missing its {/for}');
|
|
2235
2235
|
return out;
|
|
2236
2236
|
}
|
|
2237
|
-
|
|
2238
|
-
// It runs on the finished markup, so the browser, `kreft build` and the Vite plugin all see the same names.
|
|
2239
|
-
const LEGACY_TAGS = /^som-(?=(?:wait|view|component|yield|section|portal|link)$)/i;
|
|
2240
|
-
const TAG_SCAN = /<(\/?)([A-Za-z][\w:.-]*)((?:\s+[^\s"'<>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s"'>]+))?)*)(\s*\/?>)/g;
|
|
2241
|
-
const ATTR_SCAN = /(\s+)([^\s"'<>\/=]+)(\s*=\s*(?:"[^"]*"|'[^']*'|[^\s"'>]+))?/g;
|
|
2242
|
-
function legacyMarkup(html) {
|
|
2243
|
-
if (!/s-[a-z]|<\/?som-/i.test(html)) return html;
|
|
2244
|
-
return html.replace(TAG_SCAN, (m, slash, name, attrs, end) => {
|
|
2245
|
-
const tag = LEGACY_TAGS.test(name) ? 'kreft-' + name.slice(4) : name;
|
|
2246
|
-
const out = attrs ? attrs.replace(ATTR_SCAN, (a, sp, an, val) => (/^s-[a-z]/i.test(an) ? sp + 'k-' + an.slice(2) + (val || '') : a)) : attrs;
|
|
2247
|
-
return tag === name && out === attrs ? m : '<' + slash + tag + out + end;
|
|
2248
|
-
});
|
|
2249
|
-
}
|
|
2250
|
-
const prepareTemplate = (src) => legacyMarkup(quoteBraceAttrs(expandBlocks(expandSelfClosing(src))));
|
|
2237
|
+
const prepareTemplate = (src) => quoteBraceAttrs(expandBlocks(expandSelfClosing(src)));
|
|
2251
2238
|
function getTemplate(def) {
|
|
2252
2239
|
if (def.__tpl) return def.__tpl;
|
|
2253
2240
|
let src = def.template;
|
|
@@ -2380,7 +2367,7 @@
|
|
|
2380
2367
|
}
|
|
2381
2368
|
|
|
2382
2369
|
function mountComponent(el, def, parentScope, parentInst, options = {}) {
|
|
2383
|
-
if (typeof def === 'string') def = kreftComponent(def); // 'components/Card.
|
|
2370
|
+
if (typeof def === 'string') def = kreftComponent(def); // 'components/Card.kreft'
|
|
2384
2371
|
if (def.__loader && def.__resolved) def = def.__resolved;
|
|
2385
2372
|
if (isFunction(def)) def = { init: def };
|
|
2386
2373
|
if (def.__loader || (def.templateUrl && !def.__tpl)) {
|
|
@@ -2574,11 +2561,16 @@
|
|
|
2574
2561
|
if (refName && parentInst) setRef(parentInst, refName, inst.exposed ? reactive(inst.exposed) : inst.ctx);
|
|
2575
2562
|
const mountedJob = () => {
|
|
2576
2563
|
inst.isMounted = true;
|
|
2577
|
-
// run inside the component's scope, so watchers and bus listeners made here are removed with it
|
|
2578
|
-
|
|
2579
|
-
|
|
2580
|
-
|
|
2581
|
-
|
|
2564
|
+
// run inside the component's scope, so watchers and bus listeners made here are removed with it.
|
|
2565
|
+
// The instance is current too, so `on ready { onDestroy(() => …) }` registers its cleanup on this component
|
|
2566
|
+
const prevInstance = currentInstance;
|
|
2567
|
+
currentInstance = inst;
|
|
2568
|
+
try {
|
|
2569
|
+
inst.scope.run(() => {
|
|
2570
|
+
inst.hooks.ready.forEach((h) => safeCall(h, inst.ctx));
|
|
2571
|
+
if (inst.keep) inst.hooks.show.forEach((h) => safeCall(h, inst.ctx)); // a kept one is shown the first time too
|
|
2572
|
+
});
|
|
2573
|
+
} finally { currentInstance = prevInstance; }
|
|
2582
2574
|
};
|
|
2583
2575
|
if (setupDone.length) {
|
|
2584
2576
|
const waitCtx = currentWait, keepCtx = currentKeep;
|
|
@@ -2743,7 +2735,7 @@
|
|
|
2743
2735
|
if (!container) return warn(`Failed to mount app: "${target}" not found.`);
|
|
2744
2736
|
if (rootInst) return warn('App has already been mounted.');
|
|
2745
2737
|
// copy with descriptors so getters stay getters (computed)
|
|
2746
|
-
let def = rootComponent; // a .
|
|
2738
|
+
let def = rootComponent; // a .kreft path like 'App.kreft', or an object
|
|
2747
2739
|
let source = container.innerHTML;
|
|
2748
2740
|
if (container.hasAttribute('data-kreft-ssg')) { // a page made by `kreft build --prerender`: its first view came ready
|
|
2749
2741
|
const t = document.querySelector('template[data-kreft-ssg-source]');
|
|
@@ -2846,14 +2838,13 @@
|
|
|
2846
2838
|
|
|
2847
2839
|
/* ================================================================
|
|
2848
2840
|
* Saved data — kept in localStorage, so it survives a page reload
|
|
2849
|
-
* .
|
|
2841
|
+
* .kreft: saved todos = [] (key: "<Component>.todos")
|
|
2850
2842
|
* saved theme = 'dark' as 'settings.theme'
|
|
2851
2843
|
* JS: const theme = Kreftjs.saved('theme', 'dark') → a signal
|
|
2852
2844
|
* Kreftjs.storage.get / set / remove / clear
|
|
2853
|
-
* Values are stored as JSON under "
|
|
2845
|
+
* Values are stored as JSON under "kreft:<key>". Changes in another tab show up here too.
|
|
2854
2846
|
* ================================================================ */
|
|
2855
|
-
|
|
2856
|
-
const STORAGE_PREFIX = 'som:';
|
|
2847
|
+
const STORAGE_PREFIX = 'kreft:';
|
|
2857
2848
|
const ls = () => { try { return typeof localStorage !== 'undefined' ? localStorage : null; } catch (_) { return null; } };
|
|
2858
2849
|
const storage = {
|
|
2859
2850
|
has(key) { const s = ls(); try { return !!s && s.getItem(STORAGE_PREFIX + key) !== null; } catch (_) { return false; } },
|
|
@@ -3048,7 +3039,7 @@
|
|
|
3048
3039
|
|
|
3049
3040
|
/* ================================================================
|
|
3050
3041
|
* load — data from an async function, with loading and error built in
|
|
3051
|
-
* .
|
|
3042
|
+
* .kreft: load users = api.get('/api/users')
|
|
3052
3043
|
* JS: const users = Kreftjs.resource(() => Kreftjs.api.get('/api/users'))
|
|
3053
3044
|
* → users.data · users.loading · users.error · users.loaded · users.reload()
|
|
3054
3045
|
* It loads again by itself when a value it reads changes: load user = api.get('/api/users/' + id)
|
|
@@ -3158,7 +3149,7 @@
|
|
|
3158
3149
|
}
|
|
3159
3150
|
|
|
3160
3151
|
/* ================================================================
|
|
3161
|
-
* The .
|
|
3152
|
+
* The .kreft language
|
|
3162
3153
|
*
|
|
3163
3154
|
* prop start = 0
|
|
3164
3155
|
* state count = start
|
|
@@ -3174,20 +3165,20 @@
|
|
|
3174
3165
|
*
|
|
3175
3166
|
* <style scoped> button { color: red } </style>
|
|
3176
3167
|
*
|
|
3177
|
-
* Load with app.component('Counter', 'components/Counter.
|
|
3178
|
-
* a route { path: '/', component: 'pages/Home.
|
|
3168
|
+
* Load with app.component('Counter', 'components/Counter.kreft'),
|
|
3169
|
+
* a route { path: '/', component: 'pages/Home.kreft' } or Kreftjs.load(url).
|
|
3179
3170
|
* ================================================================ */
|
|
3180
|
-
// Component files are `.
|
|
3181
|
-
//
|
|
3182
|
-
const EXT = '.
|
|
3183
|
-
const LEGACY_EXTS = ['.
|
|
3184
|
-
const EXT_RE = /\.(?:kreftjs|kreft
|
|
3185
|
-
const COMPONENT_RE = /\.(?:kreftjs|kreft
|
|
3171
|
+
// Component files are `.kreft`. Projects from the 0.0.x betas have `.kreftjs` files:
|
|
3172
|
+
// both are accepted, and a name that is not found with one extension is tried with the other.
|
|
3173
|
+
const EXT = '.kreft';
|
|
3174
|
+
const LEGACY_EXTS = ['.kreftjs'];
|
|
3175
|
+
const EXT_RE = /\.(?:kreftjs|kreft)$/i;
|
|
3176
|
+
const COMPONENT_RE = /\.(?:kreftjs|kreft)(?:[?#].*)?$/i;
|
|
3186
3177
|
const isComponent = (s) => COMPONENT_RE.test(s);
|
|
3187
3178
|
const isKreftUrl = isComponent;
|
|
3188
3179
|
// the same address under the other extensions
|
|
3189
3180
|
const altExts = (url) => {
|
|
3190
|
-
const m = /^(.*?)(\.(?:kreftjs|kreft
|
|
3181
|
+
const m = /^(.*?)(\.(?:kreftjs|kreft))([?#].*)?$/i.exec(url);
|
|
3191
3182
|
return m ? [EXT, ...LEGACY_EXTS].filter((e) => e !== m[2].toLowerCase()).map((e) => m[1] + e + (m[3] || '')) : [];
|
|
3192
3183
|
};
|
|
3193
3184
|
// fetch() the file, or the first of its other-extension names that exists; also tells which address answered
|
|
@@ -3228,7 +3219,7 @@
|
|
|
3228
3219
|
const hashString = (s) => { let h = 0; for (let i = 0; i < s.length; i++) h = (h * 31 + s.charCodeAt(i)) | 0; return (h >>> 0).toString(36); };
|
|
3229
3220
|
|
|
3230
3221
|
/* ---------- a small scanner that understands strings, comments and brackets ---------- */
|
|
3231
|
-
// the .
|
|
3222
|
+
// the .kreft script part may hold regular expressions like /["']/g; views never do ({/for} must stay a block)
|
|
3232
3223
|
let scanScript = false;
|
|
3233
3224
|
const REGEX_BEFORE = /(?:^|[(,=:[!&|?{};+\-*%<>~^]|\b(?:return|typeof|instanceof|in|of|new|delete|void|throw|case|do|else|yield|await))\s*$/;
|
|
3234
3225
|
function skipLiteral(src, i) {
|
|
@@ -3634,7 +3625,7 @@
|
|
|
3634
3625
|
}
|
|
3635
3626
|
}
|
|
3636
3627
|
|
|
3637
|
-
/* ---------- the compiler: .
|
|
3628
|
+
/* ---------- the compiler: .kreft source → component definition ---------- */
|
|
3638
3629
|
function parseKreftScript(src, url) {
|
|
3639
3630
|
scanScript = true;
|
|
3640
3631
|
try { return parseKreftScriptInner(src, url); } finally { scanScript = false; }
|
|
@@ -3677,7 +3668,7 @@
|
|
|
3677
3668
|
if (m && (m[1] === 'watch' || m[1] === 'when') && /^\w+\s*\(/.test(src.slice(i))) m = null;
|
|
3678
3669
|
if (m && m[1] === 'interface' && !/^interface\s+[A-Za-z_$][\w$]*/.test(src.slice(i, i + 120))) m = null;
|
|
3679
3670
|
if (m && m[1] === 'type' && !/^type\s+[A-Za-z_$][\w$]*(?:\s*<[^>]*>)?\s*=(?!=)/.test(src.slice(i, i + 160))) m = null;
|
|
3680
|
-
// `layout admin` / `layout 'layouts/admin.
|
|
3671
|
+
// `layout admin` / `layout 'layouts/admin.kreft'` / `layout none`: only like that, so `layout = …` stays code
|
|
3681
3672
|
const lm = m && m[1] === 'layout' && src.slice(i).match(/^layout[ \t]+(?:(['"])([^'"\n]+)\1|([\w./-]+))[ \t]*;?[ \t]*(?=\n|$|\/\/)/);
|
|
3682
3673
|
if (m && m[1] === 'layout' && !lm) m = null;
|
|
3683
3674
|
if (lm) { layout = lm[2] || lm[3]; if (layout === 'none' || layout === 'false') layout = false; i += lm[0].length; continue; }
|
|
@@ -3844,7 +3835,7 @@
|
|
|
3844
3835
|
return { code: out.join('\n'), imports, props, events, layout };
|
|
3845
3836
|
}
|
|
3846
3837
|
|
|
3847
|
-
// a CSS file imported by a .
|
|
3838
|
+
// a CSS file imported by a .kreft file: one <link> for the whole page, before the components' own styles
|
|
3848
3839
|
function addStylesheet(href) {
|
|
3849
3840
|
if (typeof document === 'undefined') return;
|
|
3850
3841
|
const full = new URL(href, document.baseURI).href;
|
|
@@ -3857,14 +3848,14 @@
|
|
|
3857
3848
|
document.head.insertBefore(link, first);
|
|
3858
3849
|
}
|
|
3859
3850
|
|
|
3860
|
-
// load `import` lines once per file; .
|
|
3851
|
+
// load `import` lines once per file; .kreft imports become local components
|
|
3861
3852
|
async function resolveImports(list, url) {
|
|
3862
3853
|
const values = {}, components = {};
|
|
3863
3854
|
for (const stmt of list) {
|
|
3864
3855
|
const m = stmt.match(/^import\s+(?:([\s\S]+?)\s+from\s+)?(['"])(.+?)\2/);
|
|
3865
3856
|
if (!m) { warn(`Can't read import: ${stmt}`); continue; }
|
|
3866
3857
|
const [, what, , spec] = m;
|
|
3867
|
-
if (/^(?:kreftjs|kreft
|
|
3858
|
+
if (/^(?:kreftjs|kreft)(\.js)?$/.test(spec)) continue; // Kreft's own functions are always available
|
|
3868
3859
|
const abs = /^\.{0,2}\//.test(spec) ? new URL(spec, url).href : spec;
|
|
3869
3860
|
if (isKreftUrl(spec)) {
|
|
3870
3861
|
if (what && IDENT.test(what.trim())) components[what.trim()] = kreftComponent(abs);
|
|
@@ -4072,15 +4063,15 @@
|
|
|
4072
4063
|
return st;
|
|
4073
4064
|
}
|
|
4074
4065
|
|
|
4075
|
-
// Pure text work, shared by the browser and `kreft build`: .
|
|
4076
|
-
function splitKreft(source, url = 'inline.
|
|
4066
|
+
// Pure text work, shared by the browser and `kreft build`: .kreft source → its parts
|
|
4067
|
+
function splitKreft(source, url = 'inline.kreft') {
|
|
4077
4068
|
const name = (url.split('/').pop() || '').replace(/[?#].*$/, '').replace(EXT_RE, '');
|
|
4078
4069
|
source = source.replace(/\r\n?/g, '\n');
|
|
4079
4070
|
// Safe linear extraction of <view> ... </view> to prevent ReDoS catastrophic backtracking
|
|
4080
4071
|
const viewOpenIdx = source.search(/<view(\s[^>]*)?>/i);
|
|
4081
4072
|
const viewCloseIdx = source.toLowerCase().lastIndexOf('</view>');
|
|
4082
4073
|
if (viewOpenIdx === -1 || viewCloseIdx === -1 || viewCloseIdx <= viewOpenIdx) {
|
|
4083
|
-
throw new SyntaxError(`${name}.
|
|
4074
|
+
throw new SyntaxError(`${name}.kreft has no <view> … </view>`);
|
|
4084
4075
|
}
|
|
4085
4076
|
const viewOpenTagMatch = source.slice(viewOpenIdx).match(/^<view(\s[^>]*)?>/i);
|
|
4086
4077
|
const viewContentStart = viewOpenIdx + viewOpenTagMatch[0].length;
|
|
@@ -4120,12 +4111,12 @@
|
|
|
4120
4111
|
return def;
|
|
4121
4112
|
}
|
|
4122
4113
|
|
|
4123
|
-
async function compileKreft(source, url = 'inline.
|
|
4114
|
+
async function compileKreft(source, url = 'inline.kreft') {
|
|
4124
4115
|
const sp = splitKreft(source, url);
|
|
4125
4116
|
const { values, components } = await resolveImports(sp.imports, url);
|
|
4126
4117
|
let run;
|
|
4127
4118
|
try { run = new Function('$scope', '$h', `with ($scope) {\n${sp.code}\n}`); }
|
|
4128
|
-
catch (e) { throw new SyntaxError(`${sp.name}.
|
|
4119
|
+
catch (e) { throw new SyntaxError(`${sp.name}.kreft: ${e.message}`); }
|
|
4129
4120
|
|
|
4130
4121
|
const props = {};
|
|
4131
4122
|
for (const p in sp.props) {
|
|
@@ -4270,20 +4261,20 @@
|
|
|
4270
4261
|
|
|
4271
4262
|
// mode 'history' (default): clean URLs like /users/5 — the server must send index.html for every path.
|
|
4272
4263
|
// mode 'hash': URLs like #/users/5 — works with any server, even file://.
|
|
4273
|
-
// Error pages: errors/404.
|
|
4264
|
+
// Error pages: errors/404.kreft, errors/403.kreft, errors/500.kreft …
|
|
4274
4265
|
// (Kreftjs.router({ errors: 'errors' }) turns them on; `kreft make:errors` writes them into a project)
|
|
4275
4266
|
const ERROR_PAGES = [401, 402, 403, 404, 419, 429, 500, 503];
|
|
4276
4267
|
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
4268
|
let activeRouter = null;
|
|
4278
4269
|
|
|
4279
|
-
/* ---------- route files: routes/web.
|
|
4280
|
-
* Route.view('/', 'pages/Home.
|
|
4281
|
-
* Route.view('/users/:id', 'pages/User.
|
|
4282
|
-
* Route.middleware('auth').group(() => { Route.view('/dashboard', 'pages/Dashboard.
|
|
4283
|
-
* Route.layout('guest').middleware('guest').group(() => { Route.view('/login', 'pages/auth/Login.
|
|
4270
|
+
/* ---------- route files: routes/web.kreft ----------
|
|
4271
|
+
* Route.view('/', 'pages/Home.kreft').name('home').title('Home')
|
|
4272
|
+
* Route.view('/users/:id', 'pages/User.kreft') // :id reaches the page as a prop
|
|
4273
|
+
* Route.middleware('auth').group(() => { Route.view('/dashboard', 'pages/Dashboard.kreft') })
|
|
4274
|
+
* Route.layout('guest').middleware('guest').group(() => { Route.view('/login', 'pages/auth/Login.kreft') })
|
|
4284
4275
|
* Route.prefix('/admin').name('admin.').group(() => { … })
|
|
4285
4276
|
* Route.redirect('/home', '/')
|
|
4286
|
-
* Route.view('/settings', 'pages/Settings.
|
|
4277
|
+
* Route.view('/settings', 'pages/Settings.kreft').children(() => { Route.view('profile', 'pages/settings/Profile.kreft') })
|
|
4287
4278
|
*/
|
|
4288
4279
|
const routeFiles = new Map(); // absolute URL → function (Route) { … } (kreft build puts them in app.js)
|
|
4289
4280
|
function defineRoutes(path, fn) { routeFiles.set(new URL(path, document.baseURI).href, fn); }
|
|
@@ -4397,7 +4388,7 @@
|
|
|
4397
4388
|
}
|
|
4398
4389
|
|
|
4399
4390
|
function createRouter({ routes = [], mode = 'history', base, scrollToTop = true, layout = null, layouts = null, errors = null, middleware = {} } = {}) {
|
|
4400
|
-
// routes: 'routes/web.
|
|
4391
|
+
// routes: 'routes/web.kreft', or ['routes/web.kreft', 'routes/admin.kreft'], or the route objects themselves
|
|
4401
4392
|
const files = [].concat(routes).filter((r) => typeof r === 'string');
|
|
4402
4393
|
const inline = [].concat(routes).filter((r) => r && typeof r === 'object');
|
|
4403
4394
|
const middlewares = { ...middleware };
|
|
@@ -4539,7 +4530,7 @@
|
|
|
4539
4530
|
if (!fromBrowser) setURL(target.fullPath, replace);
|
|
4540
4531
|
Object.assign(route, target, { error: null });
|
|
4541
4532
|
const rec = target.matched;
|
|
4542
|
-
if (!rec && errorsDir) { // no route for this address: errors/404.
|
|
4533
|
+
if (!rec && errorsDir) { // no route for this address: errors/404.kreft
|
|
4543
4534
|
showError(404, '');
|
|
4544
4535
|
afterHooks.forEach((h) => { try { h(route, from); } catch (e) { console.error(e); } });
|
|
4545
4536
|
return readyResolve();
|
|
@@ -4563,10 +4554,10 @@
|
|
|
4563
4554
|
readyResolve();
|
|
4564
4555
|
}
|
|
4565
4556
|
|
|
4566
|
-
// shows errors/<status>.
|
|
4557
|
+
// shows errors/<status>.kreft in place of the page; the address stays as it is
|
|
4567
4558
|
function showError(status, message) {
|
|
4568
4559
|
status = Number(status) || 500;
|
|
4569
|
-
const file = ERROR_PAGES.includes(status) ? status : 'error'; // errors/error.
|
|
4560
|
+
const file = ERROR_PAGES.includes(status) ? status : 'error'; // errors/error.kreft for any other status
|
|
4570
4561
|
const component = kreftComponent(`${errorsDir}/${file}${EXT}`);
|
|
4571
4562
|
route.error = { status, message: message || '' };
|
|
4572
4563
|
levels.value = [{ component, isError: true, props: { status, message: message || '', title: ERROR_TITLES[status] || 'Error' } }];
|
|
@@ -4635,7 +4626,7 @@
|
|
|
4635
4626
|
};
|
|
4636
4627
|
return router;
|
|
4637
4628
|
}
|
|
4638
|
-
// abort(404) in any .
|
|
4629
|
+
// abort(404) in any .kreft file or in JavaScript
|
|
4639
4630
|
const abortPage = (status, message) => { if (activeRouter) activeRouter.abort(status, message); else warn('abort() needs a router.'); };
|
|
4640
4631
|
const currentRouter = () => receive(ROUTER_KEY, null);
|
|
4641
4632
|
const currentRoute = () => { const r = receive(ROUTER_KEY, null); return r && r.route; };
|
|
@@ -4959,7 +4950,7 @@
|
|
|
4959
4950
|
Object.keys(kept).forEach((k) => { if (hasOwn(raw, k) && keepable(raw[k])) s[k] = kept[k]; });
|
|
4960
4951
|
});
|
|
4961
4952
|
}
|
|
4962
|
-
// a .
|
|
4953
|
+
// a .kreft file changed: compile it again and swap every live copy (false = reload the page instead)
|
|
4963
4954
|
async function hotUpdate(url, source) {
|
|
4964
4955
|
const abs = new URL(url, document.baseURI).href;
|
|
4965
4956
|
const entry = kreftCache.get(abs);
|
|
@@ -5032,29 +5023,29 @@
|
|
|
5032
5023
|
stores, storeLog, busLog,
|
|
5033
5024
|
};
|
|
5034
5025
|
|
|
5035
|
-
const VERSION = '0.0.
|
|
5026
|
+
const VERSION = '0.0.9-beta';
|
|
5036
5027
|
const Kreftjs = {
|
|
5037
5028
|
version: VERSION,
|
|
5038
5029
|
// PUBLIC_ values from .env (kreft dev and kreft build put them here); never secrets
|
|
5039
|
-
get env() { return Object.freeze({ ...((typeof window !== 'undefined' &&
|
|
5030
|
+
get env() { return Object.freeze({ ...((typeof window !== 'undefined' && window.__KREFT_ENV__) || {}) }); },
|
|
5040
5031
|
get isVite() {
|
|
5041
|
-
return Boolean(typeof window !== 'undefined' &&
|
|
5032
|
+
return Boolean(typeof window !== 'undefined' && window.__KREFT_VITE__);
|
|
5042
5033
|
},
|
|
5043
5034
|
get isElectron() {
|
|
5044
5035
|
return Boolean(
|
|
5045
5036
|
typeof window !== 'undefined' && (
|
|
5046
|
-
window.kreftDesktop ||
|
|
5037
|
+
window.kreftDesktop ||
|
|
5047
5038
|
(window.process && window.process.type === 'renderer') ||
|
|
5048
5039
|
(typeof navigator !== 'undefined' && /electron/i.test(navigator.userAgent))
|
|
5049
5040
|
)
|
|
5050
5041
|
);
|
|
5051
5042
|
},
|
|
5052
5043
|
get desktop() {
|
|
5053
|
-
return (typeof window !== 'undefined' &&
|
|
5044
|
+
return (typeof window !== 'undefined' && window.kreftDesktop) || null;
|
|
5054
5045
|
},
|
|
5055
5046
|
abort: abortPage,
|
|
5056
5047
|
// apps & components
|
|
5057
|
-
app: createApp, lazy, load, compile: compileKreft,
|
|
5048
|
+
app: createApp, lazy, load, compile: compileKreft, render,
|
|
5058
5049
|
// used by `kreft build`, Vite plugin and the app.js it writes
|
|
5059
5050
|
__makeDef: makeKreftDef,
|
|
5060
5051
|
__registerDef: registerDef,
|
|
@@ -5063,7 +5054,7 @@
|
|
|
5063
5054
|
__routes: defineRoutes,
|
|
5064
5055
|
__fileHeaders: (url) => fileHeaders(new URL(url, document.baseURI).href),
|
|
5065
5056
|
__npmBase: '/__kreft/npm/', // where kreft dev serves files from node_modules (CSS imports)
|
|
5066
|
-
__import: (url) => import(url), // how built apps load the .js modules a .
|
|
5057
|
+
__import: (url) => import(url), // how built apps load the .js modules a .kreft file imports
|
|
5067
5058
|
__precompiled: precompiled,
|
|
5068
5059
|
__hot: hotUpdate,
|
|
5069
5060
|
__devtools: devtools,
|
|
@@ -5098,11 +5089,10 @@
|
|
|
5098
5089
|
|
|
5099
5090
|
// the text-only helpers the build tool reuses, so built code matches the browser exactly
|
|
5100
5091
|
Object.defineProperty(Kreftjs, '__internal', {
|
|
5101
|
-
value: { expandBlocks, prepareTemplate,
|
|
5092
|
+
value: { expandBlocks, prepareTemplate, splitKreft, splitInterp, exactBrace, stripBrace, interpToExpr, quoteBraceAttrs, expandSelfClosing, scopeCss, hashString, propType, simplePathRE, fnExpRE, forAliasRE, makeKreftDef, compileFn, evaluate, stripTypeScript, stripTsParams },
|
|
5102
5093
|
});
|
|
5103
5094
|
|
|
5104
5095
|
if (typeof module !== 'undefined' && module.exports) module.exports = Kreftjs;
|
|
5105
5096
|
global.Kreftjs = Kreftjs;
|
|
5106
5097
|
global.Kreft = Kreftjs; // the shorter name, kept as an alias
|
|
5107
|
-
global.Som = Kreftjs; // Som.js name, kept so older code keeps working (deprecated: use Kreftjs)
|
|
5108
5098
|
})(typeof window !== 'undefined' ? window : globalThis);
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kreftjs",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"description": "A tiny reactive framework with its own component language (.
|
|
3
|
+
"version": "0.0.9-beta",
|
|
4
|
+
"description": "A tiny reactive framework with its own component language (.kreft files): router with nested routes, stores, saved data, animations, an API client, hot reload, DevTools and a template engine.",
|
|
5
5
|
"license": "Elastic-2.0",
|
|
6
6
|
"main": "kreftjs.js",
|
|
7
7
|
"browser": "kreftjs.js",
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"start": "node bin/kreftjs.js dev --api demo/db.json --db sqlite:demo/database/demo.db --migrations demo/database/migrations --server demo/server --backend demo --seed",
|
|
15
15
|
"build": "node bin/kreftjs.js build demo --out dist/demo --include docs",
|
|
16
16
|
"preview": "node bin/kreftjs.js dev dist --api demo/db.json --db sqlite:demo/database/demo.db --migrations demo/database/migrations --server demo/server --backend demo --seed",
|
|
17
|
-
"test": "node --test test/security.test.js test/prerender.test.js test/seo.test.js test/rebrand.test.js test/noauth.test.js test/winspawn.test.js",
|
|
17
|
+
"test": "node --test test/security.test.js test/prerender.test.js test/seo.test.js test/rebrand.test.js test/noauth.test.js test/winspawn.test.js test/htaccess.test.js",
|
|
18
18
|
"electron": "kreftjs electron",
|
|
19
19
|
"electron:dev": "kreftjs electron:dev",
|
|
20
20
|
"electron:build": "kreftjs electron:build"
|
|
@@ -66,7 +66,7 @@
|
|
|
66
66
|
"electron-builder": "^25.1.8"
|
|
67
67
|
},
|
|
68
68
|
"build": {
|
|
69
|
-
"appId": "com.kreftjs.
|
|
69
|
+
"appId": "com.kreftjs.kreft",
|
|
70
70
|
"productName": "Kreftjs",
|
|
71
71
|
"directories": {
|
|
72
72
|
"output": "dist-electron"
|