nanoshell 1.7.3 → 1.7.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.
package/app/app.js CHANGED
@@ -66,24 +66,32 @@ function getNanoShell() {
66
66
  return null;
67
67
  }
68
68
 
69
+ function addClick(id, handler) {
70
+ var el = document.getElementById(id);
71
+ if (el) {
72
+ el.addEventListener("click", handler);
73
+ }
74
+ }
75
+
69
76
  function bootApp() {
70
77
  console.log("⚡ [NanoShell] App Booting...");
71
- console.log("⚡ [NanoShell Transpiler Test]:", document.getElementById("val-cores")?.innerText ?? "Fallback");
78
+ const coresEl = document.getElementById("val-cores");
79
+ console.log("⚡ [NanoShell Boot Status]:", coresEl ? coresEl.innerText : "Ready");
72
80
 
73
81
  // 1. Tab Navigation via Standard addEventListener
74
82
  const navBtns = document.querySelectorAll(".nav-btn");
75
83
  const tabContents = document.querySelectorAll(".tab-content");
76
84
 
77
85
  navBtns.forEach(btn => {
78
- btn.addEventListener("click", (e) => {
86
+ btn.addEventListener("click", function(e) {
79
87
  e.preventDefault();
80
- const targetTab = btn.getAttribute("data-tab");
81
- console.log("⚡ [NanoShell] Tab Clicked via addEventListener:", targetTab);
88
+ const targetTab = this.getAttribute("data-tab") || btn.getAttribute("data-tab");
89
+ console.log("⚡ [NanoShell] Tab Clicked:", targetTab);
82
90
 
83
91
  navBtns.forEach(b => b.classList.remove("active"));
84
92
  tabContents.forEach(c => c.classList.remove("active"));
85
93
 
86
- btn.classList.add("active");
94
+ this.classList.add("active");
87
95
  const targetEl = document.getElementById(targetTab);
88
96
  if (targetEl) targetEl.classList.add("active");
89
97
  });
@@ -99,7 +107,7 @@ function bootApp() {
99
107
  }
100
108
 
101
109
  // Clear Output Button
102
- document.getElementById("btn-clear-output")?.addEventListener("click", () => {
110
+ addClick("btn-clear-output", () => {
103
111
  if (outputEl) outputEl.innerText = "// Console cleared. Click any API button to test real Win32 kernel calls.";
104
112
  });
105
113
 
@@ -201,7 +209,11 @@ function bootApp() {
201
209
  function callNative(methodName, fn) {
202
210
  const ns = getNanoShell();
203
211
  if (!ns) {
204
- logApi(methodName, { error: "NanoShell native C/Zig bridge not attached yet!" });
212
+ logApi(methodName, {
213
+ status: "Bridge Not Attached",
214
+ detail: "Native Win32 bridge is initializing. Please wait...",
215
+ workaround: "APIs will work as soon as the bridge connects."
216
+ });
205
217
  return;
206
218
  }
207
219
  try {
@@ -211,40 +223,40 @@ function bootApp() {
211
223
  }
212
224
  }
213
225
 
214
- // 5. Bind All 38 Native APIs using standard addEventListener
215
- document.getElementById("btn-quick-os")?.addEventListener("click", () => {
226
+ // 5. Bind All 38 Native APIs using addClick
227
+ addClick("btn-quick-os", () => {
216
228
  callNative("os.getInfo()", ns => logApi("os.getInfo()", JSON.parse(ns.os.getInfo())));
217
229
  });
218
230
 
219
- document.getElementById("btn-quick-battery")?.addEventListener("click", () => {
231
+ addClick("btn-quick-battery", () => {
220
232
  callNative("power.getBatteryStatus()", ns => logApi("power.getBatteryStatus()", JSON.parse(ns.power.getBatteryStatus())));
221
233
  });
222
234
 
223
- document.getElementById("btn-quick-gpu")?.addEventListener("click", () => {
235
+ addClick("btn-quick-gpu", () => {
224
236
  callNative("gpu.getInfo()", ns => logApi("gpu.getInfo()", JSON.parse(ns.gpu.getInfo())));
225
237
  });
226
238
 
227
- document.getElementById("btn-quick-procs")?.addEventListener("click", () => {
239
+ addClick("btn-quick-procs", () => {
228
240
  callNative("process.list()", ns => logApi("process.list()", JSON.parse(ns.process.list())));
229
241
  });
230
242
 
231
243
  // TAB 2: Window & Effects
232
- document.getElementById("btn-win-mica")?.addEventListener("click", () => {
244
+ addClick("btn-win-mica", () => {
233
245
  callNative("window.effects.setMica()", ns => logApi("window.effects.setMica(true)", { success: ns.window.effects.setMica(true), effect: "Windows 11 Native Mica" }));
234
246
  });
235
247
 
236
- document.getElementById("btn-win-acrylic")?.addEventListener("click", () => {
248
+ addClick("btn-win-acrylic", () => {
237
249
  callNative("window.effects.setAcrylic()", ns => logApi("window.effects.setAcrylic(true)", { success: ns.window.effects.setAcrylic(true), effect: "Windows 10/11 Acrylic Blur" }));
238
250
  });
239
251
 
240
- document.getElementById("btn-win-title")?.addEventListener("click", () => {
252
+ addClick("btn-win-title", () => {
241
253
  callNative("window.setTitle()", ns => {
242
254
  ns.window.setTitle("⚡ NanoShell Cyber Control Center [Active]");
243
255
  logApi("window.setTitle()", "Title bar updated via Win32 SetWindowTextA!");
244
256
  });
245
257
  });
246
258
 
247
- document.getElementById("btn-win-center")?.addEventListener("click", () => {
259
+ addClick("btn-win-center", () => {
248
260
  callNative("window.center()", ns => {
249
261
  ns.window.center();
250
262
  logApi("window.center()", "Window moved to screen center!");
@@ -252,7 +264,7 @@ function bootApp() {
252
264
  });
253
265
 
254
266
  let isFull = false;
255
- document.getElementById("btn-win-fullscreen")?.addEventListener("click", () => {
267
+ addClick("btn-win-fullscreen", () => {
256
268
  callNative("window.setFullscreen()", ns => {
257
269
  isFull = !isFull;
258
270
  ns.window.setFullscreen(isFull);
@@ -260,46 +272,66 @@ function bootApp() {
260
272
  });
261
273
  });
262
274
 
263
- document.getElementById("btn-win-min")?.addEventListener("click", () => {
264
- callNative("window.minimize()", ns => ns.window.minimize());
275
+ addClick("btn-win-min", () => {
276
+ callNative("window.minimize()", ns => {
277
+ ns.window.minimize();
278
+ logApi("window.minimize()", "Window minimized via native Zig bridge");
279
+ });
265
280
  });
266
281
 
267
- document.getElementById("btn-win-max")?.addEventListener("click", () => {
268
- callNative("window.maximize()", ns => ns.window.maximize());
282
+ addClick("btn-win-max", () => {
283
+ callNative("window.maximize()", ns => {
284
+ ns.window.maximize();
285
+ logApi("window.maximize()", "Window maximized via native Zig bridge");
286
+ });
287
+ });
288
+
289
+ addClick("btn-win-restore", () => {
290
+ callNative("window.restore()", ns => {
291
+ ns.window.restore();
292
+ logApi("window.restore()", "Window restored via native Zig bridge");
293
+ });
294
+ });
295
+
296
+ addClick("btn-win-close", () => {
297
+ callNative("window.close()", ns => {
298
+ logApi("window.close()", "Closing application gracefully...");
299
+ ns.window.close();
300
+ });
269
301
  });
270
302
 
271
303
  // TAB 3: FileSystem & Dialogs
272
- document.getElementById("btn-dlg-open")?.addEventListener("click", () => {
304
+ addClick("btn-dlg-open", () => {
273
305
  callNative("dialog.showOpen()", ns => logApi("dialog.showOpen()", { selectedPath: ns.dialog.showOpen() || "Cancelled" }));
274
306
  });
275
307
 
276
- document.getElementById("btn-dlg-save")?.addEventListener("click", () => {
308
+ addClick("btn-dlg-save", () => {
277
309
  callNative("dialog.showSave()", ns => logApi("dialog.showSave()", { savePath: ns.dialog.showSave() || "Cancelled" }));
278
310
  });
279
311
 
280
- document.getElementById("btn-fs-read")?.addEventListener("click", () => {
312
+ addClick("btn-fs-read", () => {
281
313
  callNative("fs.readFile()", ns => {
282
314
  const file = ns.dialog.showOpen();
283
315
  if (file) logApi("fs.readFile()", { file: file, content: ns.fs.readFile(file) });
284
316
  });
285
317
  });
286
318
 
287
- document.getElementById("btn-fs-write")?.addEventListener("click", () => {
319
+ addClick("btn-fs-write", () => {
288
320
  callNative("fs.writeFile()", ns => {
289
321
  const ok = ns.fs.writeFile("nanoshell_test.txt", "Saved cleanly via 100% Genuine Win32 C fopen/fwrite!");
290
322
  logApi("fs.writeFile()", { file: "nanoshell_test.txt", success: ok });
291
323
  });
292
324
  });
293
325
 
294
- document.getElementById("btn-fs-readdir")?.addEventListener("click", () => {
326
+ addClick("btn-fs-readdir", () => {
295
327
  callNative("fs.readDir()", ns => logApi("fs.readDir('.')", JSON.parse(ns.fs.readDir("."))));
296
328
  });
297
329
 
298
- document.getElementById("btn-fs-mkdir")?.addEventListener("click", () => {
330
+ addClick("btn-fs-mkdir", () => {
299
331
  callNative("fs.mkdir()", ns => logApi("fs.mkdir('nanoshell_test_dir')", { success: ns.fs.mkdir("nanoshell_test_dir") }));
300
332
  });
301
333
 
302
- document.getElementById("btn-dlg-msg")?.addEventListener("click", () => {
334
+ addClick("btn-dlg-msg", () => {
303
335
  callNative("dialog.showMessage()", ns => {
304
336
  ns.dialog.showMessage("NanoShell Native Alert", "Triggered 100% Win32 MessageBoxA Dialog!");
305
337
  logApi("dialog.showMessage()", "Alert displayed via Win32 MessageBoxA.");
@@ -307,19 +339,19 @@ function bootApp() {
307
339
  });
308
340
 
309
341
  // TAB 4: Process & Shell
310
- document.getElementById("btn-proc-list")?.addEventListener("click", () => {
342
+ addClick("btn-proc-list", () => {
311
343
  callNative("process.list()", ns => logApi("process.list()", JSON.parse(ns.process.list())));
312
344
  });
313
345
 
314
- document.getElementById("btn-proc-spawn")?.addEventListener("click", () => {
346
+ addClick("btn-proc-spawn", () => {
315
347
  callNative("process.spawn()", ns => logApi("process.spawn('notepad.exe')", JSON.parse(ns.process.spawn("notepad.exe"))));
316
348
  });
317
349
 
318
- document.getElementById("btn-shell-exec")?.addEventListener("click", () => {
350
+ addClick("btn-shell-exec", () => {
319
351
  callNative("shell.exec()", ns => logApi("shell.exec('dir')", JSON.parse(ns.shell.exec("dir"))));
320
352
  });
321
353
 
322
- document.getElementById("btn-shell-url")?.addEventListener("click", () => {
354
+ addClick("btn-shell-url", () => {
323
355
  callNative("shell.openExternal()", ns => {
324
356
  ns.shell.openExternal("https://github.com");
325
357
  logApi("shell.openExternal()", "Opened https://github.com in default browser via ShellExecuteA.");
@@ -327,26 +359,26 @@ function bootApp() {
327
359
  });
328
360
 
329
361
  // TAB 5: System & Hardware
330
- document.getElementById("btn-sys-info")?.addEventListener("click", () => {
362
+ addClick("btn-sys-info", () => {
331
363
  callNative("os.getInfo()", ns => logApi("os.getInfo()", JSON.parse(ns.os.getInfo())));
332
364
  });
333
365
 
334
- document.getElementById("btn-clip-write")?.addEventListener("click", () => {
366
+ addClick("btn-clip-write", () => {
335
367
  callNative("clipboard.writeText()", ns => {
336
368
  const ok = ns.clipboard.writeText("Copied from NanoShell v1.7.0 Master Control Center!");
337
369
  logApi("clipboard.writeText()", { success: ok, text: "Copied to Win32 Clipboard!" });
338
370
  });
339
371
  });
340
372
 
341
- document.getElementById("btn-clip-read")?.addEventListener("click", () => {
373
+ addClick("btn-clip-read", () => {
342
374
  callNative("clipboard.readText()", ns => logApi("clipboard.readText()", { textFromClipboard: ns.clipboard.readText() }));
343
375
  });
344
376
 
345
- document.getElementById("btn-screen-monitors")?.addEventListener("click", () => {
377
+ addClick("btn-screen-monitors", () => {
346
378
  callNative("screen.getMonitors()", ns => logApi("screen.getMonitors()", JSON.parse(ns.screen.getMonitors())));
347
379
  });
348
380
 
349
- document.getElementById("btn-notif-show")?.addEventListener("click", () => {
381
+ addClick("btn-notif-show", () => {
350
382
  callNative("notification.show()", ns => {
351
383
  ns.notification.show("NanoShell Toast", "Native Windows Action Center Notification!");
352
384
  logApi("notification.show()", "Notification triggered via Win32.");
@@ -354,7 +386,7 @@ function bootApp() {
354
386
  });
355
387
 
356
388
  // TAB 6: Exclusive Engines
357
- document.getElementById("btn-shm-test")?.addEventListener("click", () => {
389
+ addClick("btn-shm-test", () => {
358
390
  callNative("shm (Shared Memory)", ns => {
359
391
  const cOk = ns.shm.createRegion("nano_shm_channel", 65536);
360
392
  const wOk = ns.shm.write("nano_shm_channel", "Zero-Copy 120 FPS C-RAM Memory Buffer Payload");
@@ -363,31 +395,31 @@ function bootApp() {
363
395
  });
364
396
  });
365
397
 
366
- document.getElementById("btn-snap-freeze")?.addEventListener("click", () => {
398
+ addClick("btn-snap-freeze", () => {
367
399
  callNative("snapshot.freezeState()", ns => {
368
400
  window.__nanoshell_state = { user: "Admin", timestamp: Date.now(), activeModule: "EngineTester" };
369
401
  logApi("snapshot.freezeState()", { success: ns.snapshot.freezeState("nanoshell.snap"), savedFile: "nanoshell.snap" });
370
402
  });
371
403
  });
372
404
 
373
- document.getElementById("btn-snap-thaw")?.addEventListener("click", () => {
405
+ addClick("btn-snap-thaw", () => {
374
406
  callNative("snapshot.thawState()", ns => {
375
407
  logApi("snapshot.thawState()", { coldBootTime: "< 1ms", restoredState: JSON.parse(ns.snapshot.thawState("nanoshell.snap") || "{}") });
376
408
  });
377
409
  });
378
410
 
379
- document.getElementById("btn-gpu-info")?.addEventListener("click", () => {
411
+ addClick("btn-gpu-info", () => {
380
412
  callNative("gpu.getInfo()", ns => logApi("gpu.getInfo()", JSON.parse(ns.gpu.getInfo())));
381
413
  });
382
414
 
383
- document.getElementById("btn-gpu-fps120")?.addEventListener("click", () => {
415
+ addClick("btn-gpu-fps120", () => {
384
416
  callNative("gpu.setFPSCap(120)", ns => {
385
417
  ns.gpu.setFPSCap(120);
386
418
  logApi("gpu.setFPSCap(120)", "Capped to 120 FPS!");
387
419
  });
388
420
  });
389
421
 
390
- document.getElementById("btn-gpu-fps60")?.addEventListener("click", () => {
422
+ addClick("btn-gpu-fps60", () => {
391
423
  callNative("gpu.setFPSCap(60)", ns => {
392
424
  ns.gpu.setFPSCap(60);
393
425
  logApi("gpu.setFPSCap(60)", "Capped to 60 FPS!");
package/app/index.html CHANGED
@@ -94,6 +94,8 @@
94
94
  <button class="btn-primary" id="btn-win-fullscreen">Toggle Fullscreen</button>
95
95
  <button class="btn-secondary" id="btn-win-min">Minimize Window</button>
96
96
  <button class="btn-accent" id="btn-win-max">Maximize Window</button>
97
+ <button class="btn-secondary" id="btn-win-restore">Restore Window</button>
98
+ <button class="btn-secondary" id="btn-win-close" style="border-color: #f44; color: #f44;">Close Window</button>
97
99
  </div>
98
100
  </div>
99
101
  </section>
package/cli/index.js CHANGED
@@ -11,7 +11,22 @@ if (!fs.existsSync(exePath)) {
11
11
 
12
12
  const args = process.argv.slice(2);
13
13
 
14
- // Run the Zig CLI binary
14
+ // Handle "package" command directly in JS CLI runner
15
+ if (args.length > 0 && (args[0] === 'package' || args[0] === 'installer')) {
16
+ console.log("⚡ [NanoShell] Packaging application...");
17
+ console.log("1. Building production binary (ReleaseFast)...");
18
+ const buildRes = spawnSync('zig', ['build', '-Doptimize=ReleaseFast'], { stdio: 'inherit', shell: true });
19
+ if (buildRes.status !== 0) {
20
+ console.error("❌ Build failed.");
21
+ process.exit(buildRes.status || 1);
22
+ }
23
+
24
+ console.log("\n2. Generating Windows Installer setup script & compiling setup.exe...");
25
+ const packageResult = spawnSync(exePath, args, { stdio: 'inherit', shell: true });
26
+ process.exit(packageResult.status || 0);
27
+ }
28
+
29
+ // Run the Zig CLI binary for other commands
15
30
  const result = spawnSync(exePath, args, { stdio: 'inherit', shell: true });
16
31
 
17
32
  // If a new app directory was scaffolded (e.g. npx nanoshell my-app), copy runtime binaries from the npm package directory
@@ -75,6 +90,20 @@ if (args.length > 0 && !args[0].startsWith('-') && args[0] !== 'package' && args
75
90
  }
76
91
  }
77
92
  }
93
+
94
+ // Copy full NanoShell Master Control Center UI dashboard into target app/ folder
95
+ const pkgAppDir = path.join(pkgDir, 'app');
96
+ const targetAppDir = path.join(targetDir, 'app');
97
+ if (fs.existsSync(pkgAppDir)) {
98
+ if (!fs.existsSync(targetAppDir)) fs.mkdirSync(targetAppDir, { recursive: true });
99
+ const appFiles = fs.readdirSync(pkgAppDir);
100
+ for (const file of appFiles) {
101
+ const srcFile = path.join(pkgAppDir, file);
102
+ if (fs.statSync(srcFile).isFile()) {
103
+ fs.copyFileSync(srcFile, path.join(targetAppDir, file));
104
+ }
105
+ }
106
+ }
78
107
  }
79
108
  }
80
109
 
@@ -261,11 +261,31 @@ function bootApp() {
261
261
  });
262
262
 
263
263
  document.getElementById("btn-win-min")?.addEventListener("click", () => {
264
- callNative("window.minimize()", ns => ns.window.minimize());
264
+ callNative("window.minimize()", ns => {
265
+ ns.window.minimize();
266
+ logApi("window.minimize()", "Window minimized via native Zig bridge");
267
+ });
265
268
  });
266
269
 
267
270
  document.getElementById("btn-win-max")?.addEventListener("click", () => {
268
- callNative("window.maximize()", ns => ns.window.maximize());
271
+ callNative("window.maximize()", ns => {
272
+ ns.window.maximize();
273
+ logApi("window.maximize()", "Window maximized via native Zig bridge");
274
+ });
275
+ });
276
+
277
+ document.getElementById("btn-win-restore")?.addEventListener("click", () => {
278
+ callNative("window.restore()", ns => {
279
+ ns.window.restore();
280
+ logApi("window.restore()", "Window restored via native Zig bridge");
281
+ });
282
+ });
283
+
284
+ document.getElementById("btn-win-close")?.addEventListener("click", () => {
285
+ callNative("window.close()", ns => {
286
+ logApi("window.close()", "Closing application gracefully...");
287
+ ns.window.close();
288
+ });
269
289
  });
270
290
 
271
291
  // TAB 3: FileSystem & Dialogs
@@ -94,6 +94,8 @@
94
94
  <button class="btn-primary" id="btn-win-fullscreen">Toggle Fullscreen</button>
95
95
  <button class="btn-secondary" id="btn-win-min">Minimize Window</button>
96
96
  <button class="btn-accent" id="btn-win-max">Maximize Window</button>
97
+ <button class="btn-secondary" id="btn-win-restore">Restore Window</button>
98
+ <button class="btn-secondary" id="btn-win-close" style="border-color: #f44; color: #f44;">Close Window</button>
97
99
  </div>
98
100
  </div>
99
101
  </section>
package/package.json CHANGED
@@ -1,26 +1,28 @@
1
1
  {
2
2
  "name": "nanoshell",
3
- "version": "1.7.3",
4
- "description": "Hyper-lightweight 17MB RAM, 120 FPS native desktop application framework & runtime engine created by Suman Biswas",
5
- "main": "zig-out/bin/example_app.exe",
3
+ "version": "1.7.5",
4
+ "description": "Hyper-lightweight native desktop application framework. 17MB RAM, 120 FPS, pure Win32 DPI-aware windowing with WebKit rendering. No Electron. Created by Suman Biswas.",
5
+ "main": "cli/index.js",
6
6
  "bin": {
7
7
  "nanoshell": "cli/index.js",
8
8
  "create-nanoshell-app": "cli/index.js"
9
9
  },
10
10
  "readme": "README.md",
11
11
  "files": [
12
- "cli/",
12
+ "cli/index.js",
13
13
  "app/",
14
14
  "example_app/",
15
15
  "zig-out/bin/*.exe",
16
16
  "zig-out/bin/*.dll",
17
- "vendor/bin/",
17
+ "zig-out/bin/*.dat",
18
+ "zig-out/bin/*.pem",
19
+ "zig-out/bin/resources/",
18
20
  "vendor/resources/",
19
- "SKILL.md",
20
21
  "README.md"
21
22
  ],
22
23
  "scripts": {
23
24
  "build": "zig build -Doptimize=ReleaseFast",
25
+ "package": "node cli/index.js package",
24
26
  "start": "zig-out/bin/example_app.exe",
25
27
  "init": "zig-out/bin/nanoshell.exe init"
26
28
  },
@@ -35,8 +37,15 @@
35
37
  "webkit",
36
38
  "ultralight",
37
39
  "lightweight",
40
+ "win32",
41
+ "dpi-aware",
38
42
  "suman-biswas"
39
43
  ],
44
+ "engines": {
45
+ "node": ">=16.0.0"
46
+ },
47
+ "os": ["win32"],
48
+ "cpu": ["x64"],
40
49
  "author": "Suman Biswas <suman@zeroui.dev>",
41
50
  "license": "MIT"
42
51
  }