kreftjs 0.0.17-beta → 0.0.19-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 CHANGED
@@ -42,6 +42,25 @@ Open the address in the terminal (normally `http://localhost:8000`). A new proje
42
42
  | **Authentication** | Cookie sessions with CSRF protection, API tokens with permissions, device list, two-factor codes, email verification, account lockout. |
43
43
  | **Tooling** | `kreft dev` with hot reload, DevTools, an error monitor, `kreft build` (CSP-safe), prerendering, TypeScript, Vite and Electron support, a safer `kreft add`, an MCP server for AI agents. |
44
44
 
45
+ ## Desktop apps (Electron)
46
+
47
+ ```bash
48
+ kreft new my-app --electron # or: kreft electron:init in an existing app
49
+ npm install
50
+ kreft electron # opens the app in its own window (no browser, no URL)
51
+ ```
52
+
53
+ Make installers (build each system on that system; `.deb` and `.rpm` need Linux):
54
+
55
+ ```bash
56
+ npm run electron:build:mac # .dmg and .zip
57
+ npm run electron:build:win # NSIS installer and portable .exe
58
+ npm run electron:build:linux # AppImage, .deb and .rpm
59
+ npm run electron:build:all # all three (same as: kreft electron:build --all)
60
+ ```
61
+
62
+ The app icon is `build/icon.png`, and `ELECTRON_MENU=show|auto|hide` controls the window menu. Details: [Desktop apps with Electron](docs/README.md#desktop-apps-with-electron).
63
+
45
64
  ## Learn more
46
65
 
47
66
  | I want to… | Read |
package/bin/electron.js CHANGED
@@ -54,11 +54,21 @@ function getDevToolsConfig() {
54
54
  // ELECTRON_MENU=hide no menu at all
55
55
  // Change it while running from the page: window.kreftDesktop.setMenu('show' | 'auto' | 'hide')
56
56
  let menuMode = String(process.env.ELECTRON_MENU || 'show').toLowerCase();
57
- const defaultMenu = Menu.getApplicationMenu();
57
+ let defaultMenu = null; // Electron's own menu, read once the app is ready
58
58
  function applyMenu(mode) {
59
59
  menuMode = ['show', 'auto', 'hide'].includes(mode) ? mode : 'show';
60
- Menu.setApplicationMenu(menuMode === 'hide' ? null : (Menu.getApplicationMenu() || defaultMenu));
60
+ if (!defaultMenu) defaultMenu = Menu.getApplicationMenu();
61
+ if (menuMode === 'hide') {
62
+ // macOS keeps one app menu (with Quit) because the system needs it; Windows and Linux lose the bar
63
+ Menu.setApplicationMenu(process.platform === 'darwin'
64
+ ? Menu.buildFromTemplate([{ role: 'appMenu' }])
65
+ : null);
66
+ } else {
67
+ Menu.setApplicationMenu(defaultMenu);
68
+ }
61
69
  if (mainWindow && process.platform !== 'darwin') {
70
+ if (menuMode === 'hide') mainWindow.removeMenu();
71
+ else mainWindow.setMenu(defaultMenu);
62
72
  mainWindow.setAutoHideMenuBar(menuMode === 'auto');
63
73
  mainWindow.setMenuBarVisibility(menuMode === 'show');
64
74
  }
@@ -235,6 +245,7 @@ ipcMain.handle('kreft:dialog:save', async (_, options) => {
235
245
  });
236
246
 
237
247
  app.whenReady().then(() => {
248
+ applyMenu(menuMode);
238
249
  createWindow();
239
250
 
240
251
  app.on('activate', () => {
@@ -431,7 +442,52 @@ function freePort(start) {
431
442
  });
432
443
  }
433
444
 
445
+ function help() {
446
+ console.log(`
447
+ Kreft + Electron: your app as a desktop program (Windows, macOS, Linux)
448
+
449
+ Commands
450
+ kreft new <name> --electron A new app with desktop support
451
+ kreft electron:init Add desktop support to an existing app (alias: kreft make:electron)
452
+ Writes electron/main.js, electron/preload.js, build/icon.png and the build block
453
+ in package.json. Files that exist are never overwritten.
454
+ kreft electron Open the app in its own window: no browser, no URL (alias: kreft electron:dev)
455
+ --devtools[=right|bottom|left|detach] Open DevTools --no-devtools Do not
456
+ --port <number> Private port for the hidden dev server (default: the next free one)
457
+ kreft electron:build Build the app (kreft build --base ./) and make installers in dist-electron/
458
+ --mac --win --linux Choose the systems (more electron-builder flags work: --arm64, --x64, --dir)
459
+ npm run electron:build:mac .dmg and .zip
460
+ npm run electron:build:win NSIS installer and portable .exe
461
+ npm run electron:build:linux AppImage, .deb and .rpm
462
+ npm run electron:build:all All three
463
+ kreft electron:help This text
464
+
465
+ Window menu ELECTRON_MENU=show (default) | auto (Alt shows it) | hide
466
+ From a page: kreftDesktop.setMenu('hide'), kreftDesktop.getMenu()
467
+ (macOS always keeps one app menu with Quit)
468
+ DevTools ELECTRON_DEVTOOLS=right|bottom|left|detach|false, or F12 / Ctrl+Shift+I
469
+ App icon build/icon.png, a square PNG of 512x512 or more (.icns and .ico are made from it)
470
+ App name build.productName and build.appId in package.json
471
+ Installer info description, homepage, author (with e-mail) and build.linux.maintainer in package.json
472
+ (missing ones are filled in from git when you build; check them)
473
+ From a page if (Kreftjs.isElectron) kreftDesktop.getInfo(), minimize(), maximize(), close(),
474
+ showMessageBox(), showOpenDialog(), showSaveDialog(), openDevTools()
475
+
476
+ Good to know
477
+ - Build each system on that system. On a Mac, .deb and .rpm fail: build them on Linux.
478
+ - npm run build makes the website (paths start at /). electron:build makes the desktop build (--base ./).
479
+ - The packaged app has no backend: frontend-only apps work, full-stack ones (login, database) need a server.
480
+ - Unsigned apps show a warning on macOS and Windows: https://www.electron.build/code-signing
481
+ - Errors: "Electron is not installed locally" -> kreft add -D electron
482
+ "electron-builder is not installed" -> kreft add -D electron-builder
483
+ White window in the app -> run electron:build again (it needs --base ./)
484
+
485
+ Full guide: docs/README.md, "Desktop apps with Electron"
486
+ `);
487
+ }
488
+
434
489
  function dev(args = []) {
490
+ if (['help', '--help', '-h'].includes(args[0])) return help();
435
491
  const asked = args.findIndex((a) => a === '--port' || a === '-p');
436
492
  if (asked >= 0 && Number(args[asked + 1])) return startDev(args, Number(args[asked + 1]));
437
493
  return freePort(Number(process.env.PORT) || 8000).then((port) => startDev(args, port));
@@ -521,6 +577,8 @@ function startDev(args, port) {
521
577
  }
522
578
 
523
579
  function build(args = []) {
580
+ // --all is a Kreft shortcut for --mac --win --linux (electron-builder has no such flag)
581
+ if (args.includes('--all')) args = [...args.filter((a) => a !== '--all'), ...['--mac', '--win', '--linux'].filter((p) => !args.includes(p))];
524
582
  const root = getProjectRoot();
525
583
  const electronMain = path.join(root, 'electron', 'main.js');
526
584
  if (!fs.existsSync(electronMain)) {
@@ -574,6 +632,7 @@ function build(args = []) {
574
632
 
575
633
  module.exports = {
576
634
  init,
635
+ help,
577
636
  dev,
578
637
  run: dev,
579
638
  build,
package/bin/kreftjs.js CHANGED
@@ -46,6 +46,7 @@ const commands = {
46
46
  'electron:dev': (a) => require('./electron.js').dev(a),
47
47
  'electron:build': (a) => require('./electron.js').build(a),
48
48
  'electron:init': (a) => require('./electron.js').init(a),
49
+ 'electron:help': () => require('./electron.js').help(),
49
50
  'make:electron': (a) => require('./electron.js').init(a),
50
51
  vite: (a) => require('./vite.js').dev(a),
51
52
  'vite:dev': (a) => require('./vite.js').dev(a),
@@ -117,10 +118,10 @@ function help() {
117
118
  kreft vite:init Add Vite configuration to an existing project (alias: kreft make:vite)
118
119
 
119
120
  Desktop (Electron.js):
120
- kreft electron Start dev server and launch desktop window (alias: kreft electron:dev)
121
- kreft electron:dev Start dev server and launch desktop window
122
- kreft electron:build Build static bundle and package desktop app with electron-builder
121
+ kreft electron Open the app in a desktop window only: no browser, no URL (alias: kreft electron:dev)
122
+ kreft electron:build Build and make installers (--mac, --win, --linux; or npm run electron:build:all)
123
123
  kreft electron:init Add Electron support to an existing project (alias: kreft make:electron)
124
+ kreft electron:help Everything about desktop apps: menu, icon, installers, errors
124
125
 
125
126
  The backend (kreft list shows every command, yours too):
126
127
  kreft key:generate Set the application encryption key in .env (--show: print only)
package/docs/README.md CHANGED
@@ -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.17-beta
85
+ kreft --version # for example 0.0.19-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
  ```
@@ -1908,10 +1908,31 @@ npm install # installs electron and electron-builder
1908
1908
  |---|---|
1909
1909
  | `kreft electron:init` | Writes `electron/main.js`, `electron/preload.js` and the app icon `build/icon.png`, and adds the scripts (including `electron:build:mac`, `:win`, `:linux` and `:all`), the `electron` and `electron-builder` dev dependencies and a `build` block to `package.json`. Files that already exist are never overwritten. It also removes the Google Fonts links from `index.html`, so the app starts without a network. |
1910
1910
  | `kreft electron:dev` | Opens the app in a desktop window only: no browser opens and no URL is printed. The dev server runs hidden on a private port of your computer that only the window uses (hot reload works). Closing the window stops the server. Flags after the command go to the dev server. |
1911
- | `kreft electron:build` | Runs `kreft build --base ./`, then `electron-builder`. |
1911
+ | `kreft electron:build` | Runs `kreft build --base ./`, then `electron-builder`. With no flag it builds for the system you are on. |
1912
+ | `kreft electron:build --mac` | `.dmg` and `.zip` for macOS. |
1913
+ | `kreft electron:build --win` | NSIS installer and portable `.exe` for Windows. |
1914
+ | `kreft electron:build --linux` | AppImage, `.deb` and `.rpm` for Linux. |
1915
+ | `kreft electron:build --mac --win --linux` | All three systems in one run. |
1916
+ | `kreft electron:build --all` | The same as `--mac --win --linux`. |
1917
+ | `npm run electron:build:mac`, `:win`, `:linux`, `:all` | Shortcuts for the four commands above. |
1918
+
1919
+ Other flags go straight to electron-builder: `--x64`, `--arm64`, `--ia32`, `--armv7l`, `--universal` (macOS) and `--dir` (an unpacked app folder only, no installer: fast for testing).
1912
1920
 
1913
1921
  `kreft electron` is the same as `kreft electron:dev`. If the `electron/` folder is missing, both commands create it first.
1914
1922
 
1923
+ ### Quick reference
1924
+
1925
+ | I want to… | Do this |
1926
+ |---|---|
1927
+ | Add desktop support | `kreft new my-app --electron`, or `kreft electron:init` in an existing app, then `npm install` |
1928
+ | Open the app in its window | `kreft electron` (no browser, no URL) |
1929
+ | Open DevTools | `kreft electron --devtools=bottom`, `ELECTRON_DEVTOOLS=right`, or F12 |
1930
+ | Show, auto-hide or hide the menu | `ELECTRON_MENU=show`, `auto` or `hide`; `kreftDesktop.setMenu('hide')` |
1931
+ | Change the icon | Replace `build/icon.png` (square PNG, 512×512 or bigger) |
1932
+ | Change the app name | `build.productName` and `build.appId` in `package.json` |
1933
+ | Make an installer | `npm run electron:build:mac`, `:win`, `:linux` or `:all` |
1934
+ | Get help in the terminal | `kreft electron:help` |
1935
+
1915
1936
  ### Project layout
1916
1937
 
1917
1938
  ```text
@@ -2011,7 +2032,7 @@ window.kreftDesktop.setMenu('hide') // 'show' | 'auto' | 'hide'
2011
2032
  window.kreftDesktop.getMenu() // the current mode
2012
2033
  ```
2013
2034
 
2014
- On macOS the menu lives in the top bar of the screen, so `show` and `auto` look the same. For your own menu (File, Edit…), call `Menu.buildFromTemplate([...])` and `Menu.setApplicationMenu(...)` in `electron/main.js`.
2035
+ On macOS the menu lives in the top bar of the screen, so `show` and `auto` look the same, and `hide` keeps only the app-name menu (with Quit) because macOS needs one. Apps created before 0.0.18 have the old `electron/main.js` without this: delete it and run `kreft electron:init` (copy your own changes back first). For your own menu (File, Edit…), call `Menu.buildFromTemplate([...])` and `Menu.setApplicationMenu(...)` in `electron/main.js`.
2015
2036
 
2016
2037
  ### The app icon
2017
2038
 
@@ -2020,12 +2041,15 @@ On macOS the menu lives in the top bar of the screen, so `show` and `auto` look
2020
2041
  ### Packaging and installers
2021
2042
 
2022
2043
  ```bash
2023
- npm run electron:build:mac # .dmg and .zip
2024
- npm run electron:build:win # NSIS installer and portable .exe
2025
- npm run electron:build:linux # AppImage, .deb and .rpm
2026
- npm run electron:build:all # all three
2044
+ kreft electron:build --mac # .dmg and .zip
2045
+ kreft electron:build --win # NSIS installer and portable .exe
2046
+ kreft electron:build --linux # AppImage, .deb and .rpm
2047
+ kreft electron:build --mac --win --linux # all three
2048
+ kreft electron:build --all # the same as the line above
2027
2049
  ```
2028
2050
 
2051
+ The `package.json` scripts do the same: `npm run electron:build:mac`, `:win`, `:linux` and `:all`.
2052
+
2029
2053
  `electron:build` writes to `dist-electron/`. Flags go to electron-builder, for example `kreft electron:build --mac --arm64`. The defaults in the `build` block of `package.json` are:
2030
2054
 
2031
2055
  | System | Targets |
@@ -2038,6 +2062,17 @@ Edit `appId`, `productName` and the targets there. Build for each system on that
2038
2062
 
2039
2063
  The packaged app loads the built `dist/index.html` and does not start a backend. A frontend-only app works as is; a full-stack app (login, database) does not work once installed.
2040
2064
 
2065
+ ### `npm run build` or `electron:build`?
2066
+
2067
+ Adding Electron does not change `npm run build`. The two commands make different things:
2068
+
2069
+ | Command | What it makes | Use it for |
2070
+ |---|---|---|
2071
+ | `npm run build` | The website in `dist/`, with paths that start at `/` (the `docs/` folder is included). | Putting the app on a web server. |
2072
+ | `npm run electron:build` | The same site built with `--base ./` so it opens from a file, then an installer in `dist-electron/`. | Giving the app to people as a desktop program. |
2073
+
2074
+ A `dist/` made by `npm run build` shows a white window if you open it in Electron, because its paths start at `/`. Run `electron:build` (or `kreft build --base ./`) first. Doing both is fine: `electron:build` rewrites `dist/`, so run `npm run build` again before you deploy the website.
2075
+
2041
2076
  ### Security
2042
2077
 
2043
2078
  The window follows Electron's security guidance:
package/kreftjs.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- // Type definitions for Kreft 0.0.17-beta
1
+ // Type definitions for Kreft 0.0.19-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 }
package/kreftjs.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * Kreft v0.0.17-beta — reactive by nature
2
+ * Kreft v0.0.19-beta — reactive by nature
3
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.
@@ -5036,7 +5036,7 @@
5036
5036
  stores, storeLog, busLog,
5037
5037
  };
5038
5038
 
5039
- const VERSION = '0.0.17-beta';
5039
+ const VERSION = '0.0.19-beta';
5040
5040
  const Kreftjs = {
5041
5041
  version: VERSION,
5042
5042
  // PUBLIC_ values from .env (kreft dev and kreft build put them here); never secrets
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kreftjs",
3
- "version": "0.0.17-beta",
3
+ "version": "0.0.19-beta",
4
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",
@@ -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 test/htaccess.test.js test/cookie-secure.test.js test/password-rule.test.js test/headline.test.js test/menu.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 test/cookie-secure.test.js test/password-rule.test.js test/headline.test.js test/menu.test.js test/electron-all.test.js",
18
18
  "electron": "kreftjs electron",
19
19
  "electron:dev": "kreftjs electron:dev",
20
20
  "electron:build": "kreftjs electron:build"
@@ -92,7 +92,7 @@ state docs = (Kreftjs.env.PUBLIC_DOCS_URL || 'http://kreftjs.com').replace(/\/+$
92
92
  <div class="badges">
93
93
  <span class="badge danger-badge">HTTP {status}</span>
94
94
  <span class="badge solid">{currentTitle}</span>
95
- <span class="badge">Kreft {Kreftjs.version || '0.0.17-beta'}</span>
95
+ <span class="badge">Kreft {Kreftjs.version || '0.0.19-beta'}</span>
96
96
  </div>
97
97
  <div class="actions">
98
98
  <button class="sm" @click={copyReport}>{copied ? 'Copied Markdown' : 'Copy Report'}</button>
@@ -189,7 +189,7 @@ state docs = (Kreftjs.env.PUBLIC_DOCS_URL || 'http://kreftjs.com').replace(/\/+$
189
189
  <h3>Kreft Runtime</h3>
190
190
  <table>
191
191
  <tbody>
192
- <tr><th>Engine</th><td><code>Kreft v{Kreftjs.version || '0.0.17-beta'}</code></td></tr>
192
+ <tr><th>Engine</th><td><code>Kreft v{Kreftjs.version || '0.0.19-beta'}</code></td></tr>
193
193
  <tr><th>Sanitizer</th><td><code>Active (cleanHtml / SafeHtml)</code></td></tr>
194
194
  <tr><th>Environment</th><td><code>development (APP_DEBUG=true)</code></td></tr>
195
195
  </tbody>
@@ -1,4 +1,4 @@
1
- // Type definitions for Kreft 0.0.17-beta
1
+ // Type definitions for Kreft 0.0.19-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 }
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * Kreft v0.0.17-beta — reactive by nature
2
+ * Kreft v0.0.19-beta — reactive by nature
3
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.
@@ -5036,7 +5036,7 @@
5036
5036
  stores, storeLog, busLog,
5037
5037
  };
5038
5038
 
5039
- const VERSION = '0.0.17-beta';
5039
+ const VERSION = '0.0.19-beta';
5040
5040
  const Kreftjs = {
5041
5041
  version: VERSION,
5042
5042
  // PUBLIC_ values from .env (kreft dev and kreft build put them here); never secrets
@@ -112,7 +112,7 @@ state docs = (Kreftjs.env.PUBLIC_DOCS_URL || 'http://kreftjs.com').replace(/\/+$
112
112
  <div class="info-list">
113
113
  <div class="info-item">
114
114
  <span class="info-label">Framework Engine</span>
115
- <span class="info-value">Kreft {Kreftjs.version || '0.0.17-beta'}</span>
115
+ <span class="info-value">Kreft {Kreftjs.version || '0.0.19-beta'}</span>
116
116
  </div>
117
117
  <div class="info-item">
118
118
  <span class="info-label">Active Database</span>
@@ -118,7 +118,7 @@ state docs = (Kreftjs.env.PUBLIC_DOCS_URL || 'http://kreftjs.com').replace(/\/+$
118
118
  <div class="hero-badges">
119
119
  <span class="badge-exception">{currentTitle}</span>
120
120
  <span class="badge-env">Node.js {typeof process !== 'undefined' ? process.version : 'v22.0.0'}</span>
121
- <span class="badge-env">Kreft v0.0.17-beta</span>
121
+ <span class="badge-env">Kreft v0.0.19-beta</span>
122
122
  </div>
123
123
  <h1 class="hero-error-message">{currentMessage}</h1>
124
124
  </div>