create-electro 1.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +24 -0
  3. package/bin/create-electro.mjs +9 -0
  4. package/dist/index.d.mts +4 -0
  5. package/dist/index.mjs +10 -0
  6. package/package.json +54 -0
  7. package/template/monorepo/README.md +19 -0
  8. package/template/monorepo/electro.config.ts +6 -0
  9. package/template/monorepo/package.json +26 -0
  10. package/template/monorepo/pnpm-workspace.yaml +3 -0
  11. package/template/monorepo/runtime/electro-env.d.ts +90 -0
  12. package/template/monorepo/runtime/package.json +15 -0
  13. package/template/monorepo/runtime/runtime.config.ts +5 -0
  14. package/template/monorepo/runtime/src/main.ts +25 -0
  15. package/template/monorepo/runtime/src/modules/app.module.ts +35 -0
  16. package/template/monorepo/runtime/src/modules/app.shell.service.ts +54 -0
  17. package/template/monorepo/runtime/src/modules/app.view.ts +22 -0
  18. package/template/monorepo/runtime/src/modules/app.window.ts +54 -0
  19. package/template/monorepo/runtime/src/modules/notes/notes.module.ts +8 -0
  20. package/template/monorepo/runtime/src/modules/notes/notes.service.ts +55 -0
  21. package/template/monorepo/runtime/tsconfig.json +11 -0
  22. package/template/monorepo/views/main/electro-env.d.ts +51 -0
  23. package/template/monorepo/views/main/index.html +12 -0
  24. package/template/monorepo/views/main/package.json +17 -0
  25. package/template/monorepo/views/main/src/app.css +1254 -0
  26. package/template/monorepo/views/main/src/app.tsx +464 -0
  27. package/template/monorepo/views/main/src/icon.svg +11 -0
  28. package/template/monorepo/views/main/src/main.tsx +12 -0
  29. package/template/monorepo/views/main/tsconfig.json +9 -0
  30. package/template/monorepo/views/main/view.config.ts +8 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Anton Ryuben
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,24 @@
1
+ # create-electro
2
+
3
+ Scaffold a new ElectroJS application with the supported monorepo-first layout.
4
+
5
+ ## Usage
6
+
7
+ ```bash
8
+ npm create electro@latest my-app
9
+ ```
10
+
11
+ or
12
+
13
+ ```bash
14
+ pnpm create electro my-app
15
+ ```
16
+
17
+ The generated project contains:
18
+
19
+ - a root `electro.config.ts`
20
+ - a `runtime/` package
21
+ - a `views/main/` package
22
+ - package-local `electro-env.d.ts` starter files
23
+
24
+ ElectroJS documents and supports this monorepo-style layout. Other layouts are outside the documented path.
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { runCli } from "../dist/index.mjs";
4
+
5
+ await runCli(process.argv.slice(2)).catch((error) => {
6
+ const message = error instanceof Error ? error.message : String(error);
7
+ console.error(message);
8
+ process.exitCode = 1;
9
+ });
@@ -0,0 +1,4 @@
1
+ //#region src/index.d.ts
2
+ declare function runCli(argv?: readonly string[]): Promise<void>;
3
+ //#endregion
4
+ export { runCli };
package/dist/index.mjs ADDED
@@ -0,0 +1,10 @@
1
+ import{basename as e,dirname as t,join as n,resolve as r}from"node:path";import{fileURLToPath as i}from"node:url";import{mkdir as a,readFile as o,readdir as s,stat as c,writeFile as l}from"node:fs/promises";const u=i(new URL(`../template/monorepo`,import.meta.url));function d(e){let t=e.trim().toLowerCase().replace(/[^a-z0-9]+/g,`-`).replace(/^-+|-+$/g,``);return t.length>0?t:`electro-app`}function f(e){return e.split(/[^a-zA-Z0-9]+/).filter(e=>e.length>0).map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(` `)}function p(e){let t=d(e);return{packageName:t,displayName:f(t)}}function m(e){return{__DISPLAY_NAME__:e.displayName,__ELECTRON_VERSION__:`41.0.4`,__FRAMEWORK_VERSION__:`2.0.0`,__NODE_TYPES_VERSION__:`^25.5.0`,__PACKAGE_MANAGER__:`pnpm@10.32.1`,__PACKAGE_NAME__:e.packageName,__REACT_DOM_TYPES_VERSION__:`^19.2.3`,__REACT_TYPES_VERSION__:`^19.2.14`,__REACT_VERSION__:`^19.2.4`,__TYPESCRIPT_VERSION__:`^6.0.2`,__VITE_REACT_PLUGIN_VERSION__:`^6.0.1`,__VITE_VERSION__:`^8.0.2`}}function h(e,t){let n=e;for(let[e,r]of Object.entries(t))n=n.replaceAll(e,r);return n}async function g(e){try{return await c(e),!0}catch{return!1}}async function _(e,t){if(!await g(e)){await a(e,{recursive:!0});return}if((await s(e)).length>0&&!t)throw Error(`Target directory "${e}" is not empty. Use --force to overwrite scaffold files.`)}async function v(e,t=e){let r=await s(t,{withFileTypes:!0}),i=[];for(let a of r){let r=n(t,a.name);if(a.isDirectory()){i.push(...await v(e,r));continue}a.isFile()&&i.push(r)}return i.sort()}async function y(e,r){let i=m(r),s=await v(u),c=[];for(let r of s){let s=n(e,r.slice(u.length+1)),d=h(await o(r,`utf8`),i);await a(t(s),{recursive:!0}),await l(s,d,`utf8`),c.push(s)}return c.sort()}async function b(e){return await _(e.projectDir,e.force),y(e.projectDir,p(e.projectName))}function x(){console.log(`create-electro
2
+
3
+ Usage:
4
+ npm create electro@latest [project-name]
5
+ pnpm create electro [project-name]
6
+
7
+ Options:
8
+ -f, --force Overwrite scaffold files in a non-empty directory
9
+ -h, --help Show this help message
10
+ `)}function S(e){let t=!1,n=!1,r=`electro-app`;for(let i of e){if(i===`--force`||i===`-f`){t=!0;continue}if(i===`--help`||i===`-h`){n=!0;continue}if(i.startsWith(`-`))throw Error(`Unknown option "${i}".`);r=i}return{force:t,help:n,targetDir:r}}function C(e){return e===`.`||e===`./`?null:e}async function w(t=process.argv.slice(2)){let n=S(t);if(n.help){x();return}let i=r(process.cwd(),n.targetDir),a=e(i),o=await b({force:n.force,projectDir:i,projectName:a});console.log(`\nScaffolded ElectroJS app in ${i}`),console.log(`Created ${o.length} file(s).\n`),console.log(`Next steps:`);let s=C(n.targetDir);s&&console.log(` cd ${s}`),console.log(` pnpm install`),console.log(` pnpm run dev`)}const T=process.argv[1];T&&r(T)===i(import.meta.url)&&await w(process.argv.slice(2)).catch(e=>{let t=e instanceof Error?e.message:String(e);console.error(t),process.exitCode=1});export{w as runCli};
package/package.json ADDED
@@ -0,0 +1,54 @@
1
+ {
2
+ "name": "create-electro",
3
+ "version": "1.0.5",
4
+ "description": "Scaffold a new ElectroJS Electron app with the recommended monorepo layout",
5
+ "keywords": [
6
+ "create",
7
+ "electro",
8
+ "electrojs",
9
+ "electron",
10
+ "scaffold",
11
+ "starter",
12
+ "template",
13
+ "vite"
14
+ ],
15
+ "homepage": "https://electrojs.myraxbyte.dev/",
16
+ "bugs": {
17
+ "url": "https://github.com/MyraxByte/electrojs/issues"
18
+ },
19
+ "license": "MIT",
20
+ "repository": {
21
+ "type": "git",
22
+ "url": "git+https://github.com/MyraxByte/electrojs.git",
23
+ "directory": "packages/create-electro"
24
+ },
25
+ "bin": {
26
+ "create-electro": "./bin/create-electro.mjs"
27
+ },
28
+ "files": [
29
+ "bin",
30
+ "dist",
31
+ "template",
32
+ "README.md"
33
+ ],
34
+ "type": "module",
35
+ "main": "./dist/index.mjs",
36
+ "types": "./dist/index.d.mts",
37
+ "exports": {
38
+ ".": {
39
+ "types": "./dist/index.d.mts",
40
+ "import": "./dist/index.mjs"
41
+ }
42
+ },
43
+ "publishConfig": {
44
+ "access": "public"
45
+ },
46
+ "devDependencies": {
47
+ "tsdown": "^0.21.4",
48
+ "vitest": "^4.1.1"
49
+ },
50
+ "scripts": {
51
+ "build": "tsdown",
52
+ "test": "vitest"
53
+ }
54
+ }
@@ -0,0 +1,19 @@
1
+ # **DISPLAY_NAME**
2
+
3
+ ElectroJS monorepo application scaffolded with `create-electro`.
4
+
5
+ ## Commands
6
+
7
+ ```bash
8
+ pnpm install
9
+ pnpm run dev
10
+ pnpm run generate
11
+ pnpm run build
12
+ pnpm run preview
13
+ ```
14
+
15
+ ## Layout
16
+
17
+ - `runtime/` contains the Electron main-process runtime package
18
+ - `views/main/` contains the first renderer package
19
+ - `electro.config.ts` wires runtime and views together through explicit package specifiers
@@ -0,0 +1,6 @@
1
+ import { defineElectroConfig } from "@electrojs/config";
2
+
3
+ export default defineElectroConfig({
4
+ runtime: "runtime",
5
+ views: ["@views/main"],
6
+ });
@@ -0,0 +1,26 @@
1
+ {
2
+ "name": "__PACKAGE_NAME__",
3
+ "version": "0.0.0",
4
+ "private": true,
5
+ "type": "module",
6
+ "scripts": {
7
+ "dev": "electro dev",
8
+ "build": "electro build",
9
+ "preview": "electro preview",
10
+ "generate": "electro generate"
11
+ },
12
+ "devDependencies": {
13
+ "@electrojs/cli": "__FRAMEWORK_VERSION__",
14
+ "@electrojs/config": "__FRAMEWORK_VERSION__",
15
+ "@types/node": "__NODE_TYPES_VERSION__",
16
+ "electron": "__ELECTRON_VERSION__",
17
+ "typescript": "__TYPESCRIPT_VERSION__",
18
+ "vite": "__VITE_VERSION__"
19
+ },
20
+ "packageManager": "__PACKAGE_MANAGER__",
21
+ "pnpm": {
22
+ "onlyBuiltDependencies": [
23
+ "electron"
24
+ ]
25
+ }
26
+ }
@@ -0,0 +1,3 @@
1
+ packages:
2
+ - "runtime"
3
+ - "views/*"
@@ -0,0 +1,90 @@
1
+ // Auto-generated by ElectroJS codegen. Do not edit.
2
+ // @ts-nocheck
3
+ // ElectroJS runtime authoring contract types — provides IDE completions for modules, signals, jobs, windows, and runtime-declared views.
4
+
5
+ export {};
6
+
7
+ type _Instance<T> = T extends abstract new (...args: never[]) => infer R ? R : never;
8
+ type _ModuleAuthoringApi<TModuleId extends import("@electrojs/runtime").ModuleRegistryId> = import("@electrojs/runtime").ModuleAuthoringApi<TModuleId>;
9
+ type _WindowAuthoringApi = import("@electrojs/runtime").WindowAuthoringApi;
10
+ type _ViewAuthoringApi = import("@electrojs/runtime").ViewAuthoringApi;
11
+ type _InvokeMethod<T, K extends PropertyKey> = K extends keyof _Instance<T>
12
+ ? _Instance<T>[K] extends (...args: infer A) => infer V
13
+ ? (...args: A) => Promise<Awaited<V>>
14
+ : never
15
+ : never;
16
+
17
+ declare module "@electrojs/runtime" {
18
+ interface ModuleMethodMap {
19
+ "notes:createNote": _InvokeMethod<typeof import("./src/modules/notes/notes.service").NotesService, "createNote">;
20
+ "notes:getNotes": _InvokeMethod<typeof import("./src/modules/notes/notes.service").NotesService, "getNotes">;
21
+ "notes:deleteNote": _InvokeMethod<typeof import("./src/modules/notes/notes.service").NotesService, "deleteNote">;
22
+ }
23
+
24
+ interface ModuleApiRegistry {
25
+ app: {};
26
+ notes: {
27
+ createNote: _InvokeMethod<typeof import("./src/modules/notes/notes.service").NotesService, "createNote">;
28
+ getNotes: _InvokeMethod<typeof import("./src/modules/notes/notes.service").NotesService, "getNotes">;
29
+ deleteNote: _InvokeMethod<typeof import("./src/modules/notes/notes.service").NotesService, "deleteNote">;
30
+ };
31
+ }
32
+
33
+ interface ModuleSignalPayloadMap {}
34
+
35
+ interface ModuleJobRegistry {
36
+ app: never;
37
+ notes: never;
38
+ }
39
+
40
+ interface InjectableClassRegistry {
41
+ NotesService: typeof import("./src/modules/notes/notes.service").NotesService;
42
+ }
43
+
44
+ interface WindowClassRegistry {
45
+ main: typeof import("./src/modules/app.window").MainWindow;
46
+ }
47
+
48
+ interface ViewClassRegistry {
49
+ main: typeof import("./src/modules/app.view").MainView;
50
+ }
51
+ }
52
+
53
+ declare module "@electrojs/common" {
54
+ interface ViewAccessRegistry {
55
+ "notes:createNote": true;
56
+ "notes:getNotes": true;
57
+ "notes:deleteNote": true;
58
+ }
59
+
60
+ interface ViewSignalRegistry {}
61
+
62
+ interface BundledViewIdRegistry {
63
+ main: true;
64
+ }
65
+ }
66
+
67
+ import "./src/modules/app.module";
68
+ declare module "./src/modules/app.module" {
69
+ interface AppModule extends _ModuleAuthoringApi<"app"> {}
70
+ }
71
+
72
+ import "./src/modules/notes/notes.module";
73
+ declare module "./src/modules/notes/notes.module" {
74
+ interface NotesModule extends _ModuleAuthoringApi<"notes"> {}
75
+ }
76
+
77
+ import "./src/modules/notes/notes.service";
78
+ declare module "./src/modules/notes/notes.service" {
79
+ interface NotesService extends _ModuleAuthoringApi<"notes"> {}
80
+ }
81
+
82
+ import "./src/modules/app.window";
83
+ declare module "./src/modules/app.window" {
84
+ interface MainWindow extends _WindowAuthoringApi {}
85
+ }
86
+
87
+ import "./src/modules/app.view";
88
+ declare module "./src/modules/app.view" {
89
+ interface MainView extends _ViewAuthoringApi {}
90
+ }
@@ -0,0 +1,15 @@
1
+ {
2
+ "name": "runtime",
3
+ "version": "0.0.0",
4
+ "private": true,
5
+ "type": "module",
6
+ "devDependencies": {
7
+ "@electrojs/common": "__FRAMEWORK_VERSION__",
8
+ "@electrojs/config": "__FRAMEWORK_VERSION__",
9
+ "@electrojs/runtime": "__FRAMEWORK_VERSION__",
10
+ "@types/node": "__NODE_TYPES_VERSION__",
11
+ "electron": "__ELECTRON_VERSION__",
12
+ "typescript": "__TYPESCRIPT_VERSION__",
13
+ "vite": "__VITE_VERSION__"
14
+ }
15
+ }
@@ -0,0 +1,5 @@
1
+ import { defineRuntimeConfig } from "@electrojs/config";
2
+
3
+ export default defineRuntimeConfig({
4
+ entry: "./src/main.ts",
5
+ });
@@ -0,0 +1,25 @@
1
+ import { AppKernel, createConsoleLogger } from "@electrojs/runtime";
2
+ import { app } from "electron";
3
+ import { AppModule } from "./modules/app.module";
4
+
5
+ const kernel = AppKernel.create(AppModule, {
6
+ logger: createConsoleLogger(),
7
+ });
8
+
9
+ if (!app.requestSingleInstanceLock()) {
10
+ app.quit();
11
+ }
12
+
13
+ app.on("window-all-closed", () => {
14
+ if (process.platform !== "darwin") {
15
+ app.quit();
16
+ }
17
+ });
18
+
19
+ app.on("before-quit", () => {
20
+ void kernel.shutdown();
21
+ });
22
+
23
+ void app.whenReady().then(async () => {
24
+ await kernel.start();
25
+ });
@@ -0,0 +1,35 @@
1
+ import { Module } from "@electrojs/common";
2
+ import { app } from "electron";
3
+ import { inject } from "@electrojs/runtime";
4
+ import { ShellService } from "./app.shell.service";
5
+ import { NotesModule } from "./notes/notes.module";
6
+ import { MainView } from "./app.view";
7
+ import { MainWindow } from "./app.window";
8
+
9
+ @Module({
10
+ imports: [NotesModule],
11
+ providers: [ShellService],
12
+ views: [MainView],
13
+ windows: [MainWindow],
14
+ })
15
+ export class AppModule {
16
+ private readonly window = inject(MainWindow);
17
+
18
+ async onInit() {
19
+ this.window.register();
20
+
21
+ app.on("activate", async () => {
22
+ if (!this.window.window) {
23
+ this.window.register();
24
+ await this.window.open();
25
+ return;
26
+ }
27
+
28
+ this.window.show();
29
+ });
30
+ }
31
+
32
+ async onReady() {
33
+ await this.window.open();
34
+ }
35
+ }
@@ -0,0 +1,54 @@
1
+ import { Injectable, command, query } from "@electrojs/common";
2
+ import { inject } from "@electrojs/runtime";
3
+ import { shell } from "electron";
4
+ import { MainWindow } from "./app.window";
5
+
6
+ const DOCS_URL = "https://electrojs.myraxbyte.dev/";
7
+
8
+ export interface ShellState {
9
+ readonly platform: string;
10
+ readonly isMaximized: boolean;
11
+ }
12
+
13
+ @Injectable()
14
+ export class ShellService {
15
+ private readonly mainWindow = inject(MainWindow);
16
+
17
+ @query()
18
+ public getShellState(): ShellState {
19
+ return {
20
+ platform: process.platform,
21
+ isMaximized: this.mainWindow.window?.isMaximized() ?? false,
22
+ };
23
+ }
24
+
25
+ @command()
26
+ public minimizeWindow(): void {
27
+ this.mainWindow.window?.minimize();
28
+ }
29
+
30
+ @command()
31
+ public toggleMaximizeWindow(): ShellState {
32
+ const window = this.mainWindow.window;
33
+
34
+ if (window) {
35
+ if (window.isMaximized()) {
36
+ window.unmaximize();
37
+ } else {
38
+ window.maximize();
39
+ }
40
+ }
41
+
42
+ return this.getShellState();
43
+ }
44
+
45
+ @command()
46
+ public closeWindow(): void {
47
+ this.mainWindow.window?.close();
48
+ }
49
+
50
+ @command()
51
+ public async openDocumentation(): Promise<void> {
52
+ await shell.openExternal(DOCS_URL);
53
+ }
54
+ }
@@ -0,0 +1,22 @@
1
+ import { View } from "@electrojs/common";
2
+ import { ViewProvider } from "@electrojs/runtime";
3
+
4
+ @View({
5
+ access: [
6
+ "app:getShellState",
7
+ "app:minimizeWindow",
8
+ "app:toggleMaximizeWindow",
9
+ "app:closeWindow",
10
+ "app:openDocumentation",
11
+ "notes:createNote",
12
+ "notes:getNotes",
13
+ "notes:deleteNote",
14
+ ],
15
+ source: "view:main",
16
+ configuration: {},
17
+ })
18
+ export class MainView extends ViewProvider {
19
+ public resize(width: number, height: number) {
20
+ this.contentView?.setBounds({ x: 0, y: 0, width, height });
21
+ }
22
+ }
@@ -0,0 +1,54 @@
1
+ import { Window } from "@electrojs/common";
2
+ import { inject, WindowProvider } from "@electrojs/runtime";
3
+ import { shell } from "electron";
4
+ import { MainView } from "./app.view";
5
+ import { app, Menu } from "electron/main";
6
+
7
+ const isMacOS = process.platform === "darwin";
8
+ const isWindows = process.platform === "win32";
9
+
10
+ @Window({
11
+ id: "main",
12
+ configuration: {
13
+ width: 1360,
14
+ height: 860,
15
+ minWidth: 1120,
16
+ minHeight: 720,
17
+ show: false,
18
+ frame: false,
19
+ transparent: true,
20
+ visualEffectState: "active",
21
+ backgroundColor: "#00000000",
22
+ ...(isMacOS && { vibrancy: "fullscreen-ui" }),
23
+ ...(isWindows && { backgroundMaterial: "mica" }),
24
+ },
25
+ })
26
+ export class MainWindow extends WindowProvider {
27
+ private readonly view = inject(MainView);
28
+
29
+ public register() {
30
+ this.create();
31
+ this.window?.on("resize", () => this.onResize());
32
+ }
33
+
34
+ public onResize() {
35
+ const bounds = this.window?.getBounds();
36
+ this.view.resize(bounds?.width ?? 0, bounds?.height ?? 0);
37
+ }
38
+
39
+ async open() {
40
+ await this.view.load();
41
+ this.onResize();
42
+ this.view.setBackgroundColor("#00000000");
43
+ if (isMacOS) {
44
+ this.view.setWindowButtonVisibility(false);
45
+ }
46
+
47
+ this.mount(this.view);
48
+ this.view.webContents?.setWindowOpenHandler((details) => {
49
+ void shell.openExternal(details.url);
50
+ return { action: "deny" };
51
+ });
52
+ this.show();
53
+ }
54
+ }
@@ -0,0 +1,8 @@
1
+ import { Module } from "@electrojs/common";
2
+ import { NotesService } from "./notes.service";
3
+
4
+ @Module({
5
+ providers: [NotesService],
6
+ exports: [NotesService],
7
+ })
8
+ export class NotesModule {}
@@ -0,0 +1,55 @@
1
+ import { Injectable, command, query } from "@electrojs/common";
2
+
3
+ export interface Note {
4
+ readonly id: string;
5
+ readonly title: string;
6
+ readonly content: string;
7
+ readonly createdAt: string;
8
+ }
9
+
10
+ @Injectable()
11
+ export class NotesService {
12
+ private readonly notes: Note[] = [
13
+ {
14
+ id: "bridge-demo",
15
+ title: "Bridge is connected",
16
+ content: "This note was loaded via bridge.notes.getNotes() — a @query method in the runtime. Try creating and deleting notes to test @command methods.",
17
+ createdAt: new Date().toISOString(),
18
+ },
19
+ {
20
+ id: "architecture",
21
+ title: "How this app works",
22
+ content: "AppModule composes the runtime graph. ShellService exposes window controls. NotesService handles CRUD. Everything is typed end-to-end.",
23
+ createdAt: new Date().toISOString(),
24
+ },
25
+ ];
26
+
27
+ @query()
28
+ getNotes(): Note[] {
29
+ return [...this.notes];
30
+ }
31
+
32
+ @command()
33
+ createNote(title: string, content: string): Note {
34
+ const note: Note = {
35
+ id: crypto.randomUUID(),
36
+ title,
37
+ content,
38
+ createdAt: new Date().toISOString(),
39
+ };
40
+
41
+ this.notes.unshift(note);
42
+ return note;
43
+ }
44
+
45
+ @command()
46
+ deleteNote(id: string): boolean {
47
+ const index = this.notes.findIndex((note) => note.id === id);
48
+ if (index === -1) {
49
+ return false;
50
+ }
51
+
52
+ this.notes.splice(index, 1);
53
+ return true;
54
+ }
55
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "extends": "@electrojs/config/tsconfig/base.json",
3
+ "compilerOptions": {
4
+ "outDir": "./out",
5
+ "types": ["@types/node"],
6
+ "paths": {
7
+ "@/*": ["./src/*"]
8
+ }
9
+ },
10
+ "include": ["src/**/*", "runtime.config.ts", "electro-env.d.ts"]
11
+ }
@@ -0,0 +1,51 @@
1
+ // Auto-generated by ElectroJS codegen. Do not edit.
2
+ // @ts-nocheck
3
+ // ElectroJS renderer bridge contract types — provides IDE completions for bridge access and forwarded signals.
4
+
5
+ export {};
6
+
7
+ type _Instance<T> = T extends abstract new (...args: never[]) => infer R ? R : never;
8
+ type _BridgeInputFromMethod<T, K extends PropertyKey> = K extends keyof _Instance<T>
9
+ ? _Instance<T>[K] extends (...args: infer A) => infer _Ignored
10
+ ? A extends []
11
+ ? undefined
12
+ : A extends [infer TOnly]
13
+ ? TOnly
14
+ : A
15
+ : never
16
+ : never;
17
+ type _BridgeOutputFromMethod<T, K extends PropertyKey> = K extends keyof _Instance<T>
18
+ ? _Instance<T>[K] extends (...args: infer _Args) => infer V
19
+ ? Awaited<V>
20
+ : never
21
+ : never;
22
+
23
+ declare module "@electrojs/renderer" {
24
+ interface BridgeQueries {
25
+ "notes:getNotes": import("@electrojs/renderer").BridgeContractEntry<
26
+ _BridgeInputFromMethod<typeof import("../../runtime/src/modules/notes/notes.service").NotesService, "getNotes">,
27
+ _BridgeOutputFromMethod<typeof import("../../runtime/src/modules/notes/notes.service").NotesService, "getNotes">
28
+ >;
29
+ "notes:createNote": import("@electrojs/renderer").BridgeContractEntry<
30
+ _BridgeInputFromMethod<typeof import("../../runtime/src/modules/notes/notes.service").NotesService, "createNote">,
31
+ _BridgeOutputFromMethod<typeof import("../../runtime/src/modules/notes/notes.service").NotesService, "createNote">
32
+ >;
33
+ "notes:deleteNote": import("@electrojs/renderer").BridgeContractEntry<
34
+ _BridgeInputFromMethod<typeof import("../../runtime/src/modules/notes/notes.service").NotesService, "deleteNote">,
35
+ _BridgeOutputFromMethod<typeof import("../../runtime/src/modules/notes/notes.service").NotesService, "deleteNote">
36
+ >;
37
+ }
38
+
39
+ interface BridgeCommands {
40
+ "notes:createNote": import("@electrojs/renderer").BridgeContractEntry<
41
+ _BridgeInputFromMethod<typeof import("../../runtime/src/modules/notes/notes.service").NotesService, "createNote">,
42
+ _BridgeOutputFromMethod<typeof import("../../runtime/src/modules/notes/notes.service").NotesService, "createNote">
43
+ >;
44
+ "notes:deleteNote": import("@electrojs/renderer").BridgeContractEntry<
45
+ _BridgeInputFromMethod<typeof import("../../runtime/src/modules/notes/notes.service").NotesService, "deleteNote">,
46
+ _BridgeOutputFromMethod<typeof import("../../runtime/src/modules/notes/notes.service").NotesService, "deleteNote">
47
+ >;
48
+ }
49
+
50
+ interface BridgeSignals {}
51
+ }
@@ -0,0 +1,12 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>__DISPLAY_NAME__</title>
7
+ </head>
8
+ <body>
9
+ <div id="root"></div>
10
+ <script type="module" src="./src/main.tsx"></script>
11
+ </body>
12
+ </html>
@@ -0,0 +1,17 @@
1
+ {
2
+ "name": "@views/main",
3
+ "version": "0.0.0",
4
+ "private": true,
5
+ "type": "module",
6
+ "devDependencies": {
7
+ "@electrojs/config": "__FRAMEWORK_VERSION__",
8
+ "@electrojs/renderer": "__FRAMEWORK_VERSION__",
9
+ "@types/react": "__REACT_TYPES_VERSION__",
10
+ "@types/react-dom": "__REACT_DOM_TYPES_VERSION__",
11
+ "@vitejs/plugin-react": "__VITE_REACT_PLUGIN_VERSION__",
12
+ "react": "__REACT_VERSION__",
13
+ "react-dom": "__REACT_VERSION__",
14
+ "typescript": "__TYPESCRIPT_VERSION__",
15
+ "vite": "__VITE_VERSION__"
16
+ }
17
+ }