create-gardener 2.1.3 → 2.1.4

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 (85) hide show
  1. package/package.json +1 -1
  2. package/template/buildHelper.js +5 -0
  3. package/template/src/backend/controllers/gardener/hotReload.ts +34 -0
  4. package/template/src/backend/routes/gardener.route.ts +2 -0
  5. package/template/src/frontend/static/components/gardener/hotReloadbtn.js +25 -78
  6. package/template/src/frontend/static/gardenerDev.js +2 -18
  7. package/template/src/frontend/static/style.css +0 -61
  8. package/template/src/frontend/views/_.ejs +104 -90
  9. package/template/build/backend/controllers/gardener/addComponent.d.ts +0 -8
  10. package/template/build/backend/controllers/gardener/addComponent.d.ts.map +0 -1
  11. package/template/build/backend/controllers/gardener/addComponent.js +0 -19
  12. package/template/build/backend/controllers/gardener/addComponent.js.map +0 -1
  13. package/template/build/backend/controllers/gardener/addPage.d.ts +0 -3
  14. package/template/build/backend/controllers/gardener/addPage.d.ts.map +0 -1
  15. package/template/build/backend/controllers/gardener/addPage.js +0 -86
  16. package/template/build/backend/controllers/gardener/addPage.js.map +0 -1
  17. package/template/build/backend/controllers/gardener/createStatic.d.ts +0 -3
  18. package/template/build/backend/controllers/gardener/createStatic.d.ts.map +0 -1
  19. package/template/build/backend/controllers/gardener/createStatic.js +0 -63
  20. package/template/build/backend/controllers/gardener/createStatic.js.map +0 -1
  21. package/template/build/backend/controllers/gardener/imageOptimiser.d.ts +0 -3
  22. package/template/build/backend/controllers/gardener/imageOptimiser.d.ts.map +0 -1
  23. package/template/build/backend/controllers/gardener/imageOptimiser.js +0 -54
  24. package/template/build/backend/controllers/gardener/imageOptimiser.js.map +0 -1
  25. package/template/build/backend/controllers/gardener/index.d.ts +0 -6
  26. package/template/build/backend/controllers/gardener/index.d.ts.map +0 -1
  27. package/template/build/backend/controllers/gardener/index.js +0 -6
  28. package/template/build/backend/controllers/gardener/index.js.map +0 -1
  29. package/template/build/backend/controllers/gardener/saveTemplate.d.ts +0 -3
  30. package/template/build/backend/controllers/gardener/saveTemplate.d.ts.map +0 -1
  31. package/template/build/backend/controllers/gardener/saveTemplate.js +0 -36
  32. package/template/build/backend/controllers/gardener/saveTemplate.js.map +0 -1
  33. package/template/build/backend/libs/generateWebp.d.ts +0 -2
  34. package/template/build/backend/libs/generateWebp.d.ts.map +0 -1
  35. package/template/build/backend/libs/generateWebp.js +0 -16
  36. package/template/build/backend/libs/generateWebp.js.map +0 -1
  37. package/template/build/backend/routes/gardener.route.d.ts +0 -4
  38. package/template/build/backend/routes/gardener.route.d.ts.map +0 -1
  39. package/template/build/backend/routes/gardener.route.js +0 -18
  40. package/template/build/backend/routes/gardener.route.js.map +0 -1
  41. package/template/build/backend/server.d.ts +0 -2
  42. package/template/build/backend/server.d.ts.map +0 -1
  43. package/template/build/backend/server.js +0 -20
  44. package/template/build/backend/server.js.map +0 -1
  45. package/template/build/frontend/assets/favicon.png +0 -0
  46. package/template/build/frontend/assets/gardener.jpg +0 -0
  47. package/template/build/frontend/static/bundle/bundle._.js +0 -1
  48. package/template/build/frontend/static/bundle/bundle._about.js +0 -1
  49. package/template/build/frontend/static/bundle/bundle._kartik.js +0 -1
  50. package/template/build/frontend/static/bundle/bundle._new.js +0 -1
  51. package/template/build/frontend/static/bundle/bundle._ritish.js +0 -1
  52. package/template/build/frontend/static/cache/favicon_500x500.webp +0 -0
  53. package/template/build/frontend/static/cache/favicon_50x50.webp +0 -0
  54. package/template/build/frontend/static/cache/gardener_100x100.webp +0 -0
  55. package/template/build/frontend/static/cache/gardener_500x500.webp +0 -0
  56. package/template/build/frontend/static/cache/gardener_50x50.webp +0 -0
  57. package/template/build/frontend/static/components/copybtn.js +0 -99
  58. package/template/build/frontend/static/components/footer.js +0 -33
  59. package/template/build/frontend/static/components/gardener/errorBox.js +0 -47
  60. package/template/build/frontend/static/components/gardener/hotReloadbtn.js +0 -82
  61. package/template/build/frontend/static/components/gardener/pageOverlayBtn.js +0 -138
  62. package/template/build/frontend/static/components/gardener/parserWindow.js +0 -159
  63. package/template/build/frontend/static/components/nonui/api.js +0 -52
  64. package/template/build/frontend/static/components/nonui/navigation.js +0 -59
  65. package/template/build/frontend/static/components/notification.js +0 -67
  66. package/template/build/frontend/static/gardener.js +0 -160
  67. package/template/build/frontend/static/gardenerConfig.js +0 -1
  68. package/template/build/frontend/static/gardenerDev.js +0 -165
  69. package/template/build/frontend/static/global.js +0 -4
  70. package/template/build/frontend/static/pages/pages._.js +0 -25
  71. package/template/build/frontend/static/pages/pages._about.js +0 -2
  72. package/template/build/frontend/static/pages/pages._kartik.js +0 -2
  73. package/template/build/frontend/static/pages/pages._new.js +0 -2
  74. package/template/build/frontend/static/pages/pages._ritish.js +0 -2
  75. package/template/build/frontend/static/style.css +0 -2
  76. package/template/build/frontend/static/style2.css +0 -26
  77. package/template/build/frontend/style.css +0 -1045
  78. package/template/build/frontend/tailwind.css +0 -1
  79. package/template/build/frontend/views/_.ejs +0 -125
  80. package/template/build/frontend/views/_about.ejs +0 -126
  81. package/template/build/frontend/views/_kartik.ejs +0 -126
  82. package/template/build/frontend/views/_new.ejs +0 -126
  83. package/template/build/frontend/views/_ritish.ejs +0 -126
  84. package/template/build/frontend/views/partials/icons/clipboard.ejs +0 -1
  85. package/template/build/frontend/views/partials/icons/clipboardok.ejs +0 -1
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "type": "git",
6
6
  "url": "https://github.com/ritishDas/gardener"
7
7
  },
8
- "version": "2.1.3",
8
+ "version": "2.1.4",
9
9
  "description": "A dom gardener converting dom elements into json and vice versa",
10
10
  "main": "index.js",
11
11
  "bin": {
@@ -6,6 +6,11 @@ export default async function buildHelper() {
6
6
  const src = path.resolve('src', 'frontend');
7
7
  const dest = path.resolve('build', 'frontend');
8
8
 
9
+ try {
10
+ await fs.rm(dest, { recursive: true, force: true });
11
+ } catch (err) {
12
+ console.log(err);
13
+ }
9
14
  await fs.cp(src, dest, { recursive: true });
10
15
 
11
16
  await fs.writeFile(
@@ -0,0 +1,34 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ import type { Request, Response } from 'express';
4
+
5
+ // ── Version token ─────────────────────────────────────────────
6
+ // Monotonically-increasing timestamp updated whenever a file
7
+ // in src/frontend/ changes. The frontend stores the first value
8
+ // it sees and reloads as soon as it receives a different one.
9
+ let version: number = Date.now();
10
+
11
+ // ── File watcher ──────────────────────────────────────────────
12
+ const watchTarget = path.resolve('src', 'frontend');
13
+
14
+ let debounce: ReturnType<typeof setTimeout> | null = null;
15
+
16
+ fs.watch(watchTarget, { recursive: true }, (_event, filename) => {
17
+ // Ignore hidden files and node_modules
18
+ if (!filename || filename.startsWith('.')) return;
19
+
20
+ if (debounce) clearTimeout(debounce);
21
+ debounce = setTimeout(() => {
22
+ version = Date.now();
23
+ console.log(`[gardener] file changed: ${filename} → version ${version}`);
24
+ }, 100);
25
+ });
26
+
27
+ console.log(`[gardener] watching ${watchTarget} for changes…`);
28
+
29
+ // ── Route handler ─────────────────────────────────────────────
30
+ // GET /__gardener/hot-reload
31
+ // Returns { version: <number> }
32
+ export function hotReloadHandler(req: Request, res: Response) {
33
+ res.json({ version });
34
+ }
@@ -1,6 +1,7 @@
1
1
  import type { Request, Response } from 'express';
2
2
  import { Router } from "express";
3
3
  import { addComponent, addPage, imageOptimiser, saveTemplate } from "../controllers/gardener/index.js";
4
+ import { hotReloadHandler } from "../controllers/gardener/hotReload.js";
4
5
 
5
6
  const router: Router = Router();
6
7
  export default router;
@@ -14,6 +15,7 @@ if (process.env.NODE_ENV !== 'production') {
14
15
  router.route('/addcomponent').post(addComponent);
15
16
  router.route('/addpage').post(addPage);
16
17
  router.route('/savetemplate').post(saveTemplate);
18
+ router.route('/__gardener/hot-reload').get(hotReloadHandler);
17
19
  }
18
20
 
19
21
 
@@ -1,82 +1,29 @@
1
- import { gardener, fetchElement, appendElement } from '../../gardener.js'
2
- import { gardenerError } from './errorBox.js';
3
-
4
- const config = {
5
- hotreload: false
6
- }
7
-
8
- let hotReload;
9
- let hotReloadtimeout;
10
- const localStore = localStorage.getItem('hotreload');
11
-
12
- if (localStore === null) hotReload = config.hotreload;
13
- else if (localStore === 'true') hotReload = true
14
- else if (localStore === 'false') hotReload = false
15
-
16
-
17
- export function togglehotreload() {
18
- const hr = hotReload;
19
- const hrcheck = fetchElement('#hrcheckbox');
20
-
21
- localStorage.setItem('hotreload', hr);
22
-
23
- hotReload = !hotReload;
24
-
25
- if (hr) {
26
- hrcheck.style.background = '#66e666';
27
- fetchElement('.hrcheckbox').checked = true;
28
- localStorage.setItem('hotreload', 'true');
29
- hotReloadtimeout = setTimeout(() => window.location.reload(), 1000);
1
+ const POLL_INTERVAL = 500; // ms
2
+ const ENDPOINT = '/__gardener/hot-reload';
3
+
4
+ let knownVersion = null;
5
+
6
+ async function poll() {
7
+ try {
8
+ const res = await fetch(ENDPOINT);
9
+ if (!res.ok) return;
10
+ const { version } = await res.json();
11
+
12
+ if (knownVersion === null) {
13
+ knownVersion = version; // capture baseline on first poll
14
+ return;
15
+ }
16
+
17
+ if (version !== knownVersion) {
18
+ window.location.reload();
19
+ }
20
+ } catch {
21
+ // network hiccup — retry next tick
30
22
  }
31
- else {
32
- hrcheck.style.background = 'red';
33
- fetchElement('.hrcheckbox').checked = false;
34
- localStorage.setItem('hotreload', 'false');
35
- clearTimeout(hotReloadtimeout);
36
- }
37
-
38
- //localStorage.setItem('hotreload', hotReload);
39
23
  }
40
24
 
41
- export function hotReloadBtn() {
42
- return gardener({
43
- t: 'p',
44
- cn: ['bg-gray-200', 'fixed', 'bottom-0', 'z-100', 'right-0', 'border-b-1', 'p-2', 'rounded-md'],
45
- children: [
46
- {
47
- t: 'span',
48
- txt: 'Press '
49
- },
50
- {
51
- t: 'span',
52
- cn: ['text-green-500', 'font-bold'],
53
- txt: 'Alt+h'
54
- },
55
- {
56
- t: 'span',
57
- txt: ' to toggle Hot Reload'
58
- },
59
- {
60
- t: 'form',
61
- attr: {
62
- id: 'hrcheckbox',
63
- },
64
- events: {
65
- click: () => togglehotreload()
66
- },
67
- cn: ['p-2', 'bg-red-300'],
68
- children: [{
69
- t: 'label',
70
- txt: 'Hot Reload ',
71
- }
72
- , {
73
- t: 'input',
74
- cn: ['hrcheckbox'],
75
- attr: {
76
- type: 'checkbox'
77
- }
78
- }]
79
- }
80
- ]
81
- })
25
+ export function startHotReload() {
26
+ poll(); // immediate check
27
+ setInterval(poll, POLL_INTERVAL);
82
28
  }
29
+
@@ -2,7 +2,7 @@ import { mode } from './gardenerConfig.js'
2
2
  import { gardener, appendElement, fetchElement } from './gardener.js'
3
3
  import { addPagebtn } from './components/gardener/pageOverlayBtn.js';
4
4
  import { parserWindow as parserWindowComponent } from './components/gardener/parserWindow.js';
5
- import { hotReloadBtn, togglehotreload } from './components/gardener/hotReloadbtn.js';
5
+ import { startHotReload } from './components/gardener/hotReloadbtn.js';
6
6
  import { gardenerError } from './components/gardener/errorBox.js';
7
7
 
8
8
  const body = fetchElement('body');
@@ -20,28 +20,12 @@ const body = fetchElement('body');
20
20
 
21
21
  if (mode === 'dev') {
22
22
  appendElement(body, addPagebtn);
23
-
24
-
25
- appendElement(body, hotReloadBtn())
26
-
27
- togglehotreload();
23
+ startHotReload();
28
24
  }
29
25
 
30
26
 
31
27
 
32
28
 
33
- document.addEventListener('keydown', function(e) {
34
- // Detect Ctrl + H
35
- if (e.altKey && e.key.toLowerCase() === 'h') {
36
- e.preventDefault(); // Stop browser from opening history
37
- // Your logic here...
38
- togglehotreload();
39
- }
40
- });
41
-
42
-
43
-
44
-
45
29
 
46
30
 
47
31
  export function parserWindow(text) {
@@ -250,18 +250,12 @@
250
250
  .top-0 {
251
251
  top: calc(var(--spacing) * 0);
252
252
  }
253
- .top-1 {
254
- top: calc(var(--spacing) * 1);
255
- }
256
253
  .top-1\/2 {
257
254
  top: calc(1 / 2 * 100%);
258
255
  }
259
256
  .top-1\/4 {
260
257
  top: calc(1 / 4 * 100%);
261
258
  }
262
- .top-2 {
263
- top: calc(var(--spacing) * 2);
264
- }
265
259
  .top-2\/5 {
266
260
  top: calc(2 / 5 * 100%);
267
261
  }
@@ -292,18 +286,12 @@
292
286
  .left-0 {
293
287
  left: calc(var(--spacing) * 0);
294
288
  }
295
- .left-1 {
296
- left: calc(var(--spacing) * 1);
297
- }
298
289
  .left-1\/2 {
299
290
  left: calc(1 / 2 * 100%);
300
291
  }
301
292
  .left-1\/4 {
302
293
  left: calc(1 / 4 * 100%);
303
294
  }
304
- .left-2 {
305
- left: calc(var(--spacing) * 2);
306
- }
307
295
  .left-2\/5 {
308
296
  left: calc(2 / 5 * 100%);
309
297
  }
@@ -379,12 +367,6 @@
379
367
  .inline-block {
380
368
  display: inline-block;
381
369
  }
382
- .table {
383
- display: table;
384
- }
385
- .h-2 {
386
- height: calc(var(--spacing) * 2);
387
- }
388
370
  .h-2\/4 {
389
371
  height: calc(2 / 4 * 100%);
390
372
  }
@@ -403,24 +385,15 @@
403
385
  .h-screen {
404
386
  height: 100vh;
405
387
  }
406
- .w-1 {
407
- width: calc(var(--spacing) * 1);
408
- }
409
388
  .w-1\/4 {
410
389
  width: calc(1 / 4 * 100%);
411
390
  }
412
- .w-2 {
413
- width: calc(var(--spacing) * 2);
414
- }
415
391
  .w-2\/4 {
416
392
  width: calc(2 / 4 * 100%);
417
393
  }
418
394
  .w-5 {
419
395
  width: calc(var(--spacing) * 5);
420
396
  }
421
- .w-11 {
422
- width: calc(var(--spacing) * 11);
423
- }
424
397
  .w-11\/12 {
425
398
  width: calc(11 / 12 * 100%);
426
399
  }
@@ -457,21 +430,10 @@
457
430
  .flex-1 {
458
431
  flex: 1;
459
432
  }
460
- .border-collapse {
461
- border-collapse: collapse;
462
- }
463
- .-translate-x-1 {
464
- --tw-translate-x: calc(var(--spacing) * -1);
465
- translate: var(--tw-translate-x) var(--tw-translate-y);
466
- }
467
433
  .-translate-x-1\/2 {
468
434
  --tw-translate-x: calc(calc(1 / 2 * 100%) * -1);
469
435
  translate: var(--tw-translate-x) var(--tw-translate-y);
470
436
  }
471
- .-translate-y-1 {
472
- --tw-translate-y: calc(var(--spacing) * -1);
473
- translate: var(--tw-translate-x) var(--tw-translate-y);
474
- }
475
437
  .-translate-y-1\/2 {
476
438
  --tw-translate-y: calc(calc(1 / 2 * 100%) * -1);
477
439
  translate: var(--tw-translate-x) var(--tw-translate-y);
@@ -482,9 +444,6 @@
482
444
  .cursor-pointer {
483
445
  cursor: pointer;
484
446
  }
485
- .resize {
486
- resize: both;
487
- }
488
447
  .grid-cols-2 {
489
448
  grid-template-columns: repeat(2, minmax(0, 1fr));
490
449
  }
@@ -709,9 +668,6 @@
709
668
  .py-20 {
710
669
  padding-block: calc(var(--spacing) * 20);
711
670
  }
712
- .pb-1 {
713
- padding-bottom: calc(var(--spacing) * 1);
714
- }
715
671
  .pb-1\.5 {
716
672
  padding-bottom: calc(var(--spacing) * 1.5);
717
673
  }
@@ -830,9 +786,6 @@
830
786
  .italic {
831
787
  font-style: italic;
832
788
  }
833
- .underline {
834
- text-decoration-line: underline;
835
- }
836
789
  .opacity-70 {
837
790
  opacity: 70%;
838
791
  }
@@ -852,19 +805,11 @@
852
805
  --tw-shadow: 0 20px 25px -5px var(--tw-shadow-color, rgb(0 0 0 / 0.1)), 0 8px 10px -6px var(--tw-shadow-color, rgb(0 0 0 / 0.1));
853
806
  box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
854
807
  }
855
- .outline {
856
- outline-style: var(--tw-outline-style);
857
- outline-width: 1px;
858
- }
859
808
  .backdrop-blur-md {
860
809
  --tw-backdrop-blur: blur(var(--blur-md));
861
810
  -webkit-backdrop-filter: var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);
862
811
  backdrop-filter: var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);
863
812
  }
864
- .backdrop-filter {
865
- -webkit-backdrop-filter: var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);
866
- backdrop-filter: var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);
867
- }
868
813
  .transition {
869
814
  transition-property: color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, --tw-gradient-from, --tw-gradient-via, --tw-gradient-to, opacity, box-shadow, transform, translate, scale, rotate, filter, -webkit-backdrop-filter, backdrop-filter, display, content-visibility, overlay, pointer-events;
870
815
  transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
@@ -1081,11 +1026,6 @@
1081
1026
  inherits: false;
1082
1027
  initial-value: 0 0 #0000;
1083
1028
  }
1084
- @property --tw-outline-style {
1085
- syntax: "*";
1086
- inherits: false;
1087
- initial-value: solid;
1088
- }
1089
1029
  @property --tw-backdrop-blur {
1090
1030
  syntax: "*";
1091
1031
  inherits: false;
@@ -1170,7 +1110,6 @@
1170
1110
  --tw-ring-offset-width: 0px;
1171
1111
  --tw-ring-offset-color: #fff;
1172
1112
  --tw-ring-offset-shadow: 0 0 #0000;
1173
- --tw-outline-style: solid;
1174
1113
  --tw-backdrop-blur: initial;
1175
1114
  --tw-backdrop-brightness: initial;
1176
1115
  --tw-backdrop-contrast: initial;
@@ -1,83 +1,96 @@
1
1
  <!DOCTYPE html>
2
2
  <html lang="en">
3
- <head>
4
- <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <link rel="icon" type="image/svg+xml" href="/static/cache/favicon_50x50.webp" />
7
- <link href="/static/style.css" rel="stylesheet"/>
8
- <link href="/static/style2.css" rel="stylesheet"/>
9
- <title>Gardener: The Mini Web Framework</title>
10
- </head>
11
- <body class="bg-slate-50 text-slate-900 font-sans">
12
3
 
13
- <div class='hidden' id='fileName'><%=fileName%></div>
14
- <div class='loader w-screen h-screen bg-white fixed z-2'> </div>
15
- <div class='notification'></div>
4
+ <head>
5
+ <meta charset="UTF-8">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
+ <link rel="icon" type="image/svg+xml" href="/static/cache/favicon_50x50.webp" />
8
+ <link href="/static/style.css" rel="stylesheet" />
9
+ <link href="/static/style2.css" rel="stylesheet" />
10
+ <title>Gardener: The Mini Web Framework</title>
11
+ </head>
16
12
 
17
- <div id='main'>
13
+ <body class="bg-slate-50 text-slate-900 font-sans">
18
14
 
15
+ <div class='hidden' id='fileName'>
16
+ <%=fileName%>
17
+ </div>
18
+ <div class='loader w-screen h-screen bg-white fixed z-2'> </div>
19
+ <div class='notification'></div>
19
20
 
20
- <!-- hero -->
21
- <div class='hero flex-wrap w-full h-screen bg-green-200 flex justify-center items-center px-10'>
22
- <div class='w-200'>
23
- <a href="https://ritish.site">Home</a> > <a href="https://ritish.site/projects">Projects</a> > <a href="/">Gardener</a>
24
- <h1 class='text-6xl my-10 font-bold text-green-900'>Gardener</h1>
25
- <h2 class='text-2xl font-bold text-green-800 mb-4'>Develop With No Bloat</h2>
26
- <p class="text-lg mb-6 max-w-md">Gardener is a lightweight, DOM-first front-end library. No virtual DOM, no JSX, and no compilation step. Just the real DOM.</p>
27
- <div class='flex gap-2 m-2'>
28
- <a class="block bg-green-700 text-white px-8 py-3 rounded-lg font-bold hover:bg-green-800 transition" href='/get-started'>Get Started</a>
29
- <a class="block border border-green-700 text-black px-8 py-3 rounded-lg font-bold hover:text-white hover:bg-green-800 transition" href='/documentation/#introduction'>Documentation</a>
30
- </div>
31
- <div class='flex gap-2 m-2'>
32
- <a class="block border border-green-700 text-black px-8 py-3 rounded-lg font-bold hover:text-white hover:bg-green-800 transition" href='https://github.com/ritishDas/Gardener'>View On Github</a>
33
- <a class="block border border-green-700 text-black px-8 py-3 rounded-lg font-bold hover:text-white hover:bg-green-800 transition" href='https://www.npmjs.com/package/create-gardener'>View On npm</a>
34
- </div>
21
+ <div id='main'>
22
+
23
+
24
+ <!-- hero -->
25
+ <div class='hero flex-wrap w-full h-screen bg-green-200 flex justify-center items-center px-10'>
26
+ <div class='w-200'>
27
+ <a href="https://ritish.site">Home</a> > <a href="https://ritish.site/projects">Projects</a> > <a
28
+ href="/">Gardener</a>
29
+ <h1 class='text-6xl my-10 font-bold text-green-900'>Gardener</h1>
30
+ <h2 class='text-2xl font-bold text-green-800 mb-4'>Develop With No Bloat</h2>
31
+ <p class="text-lg mb-6 max-w-md">Gardener is a lightweight, DOM-first front-end library. No virtual DOM, no JSX,
32
+ and no compilation step. Just the real DOM.</p>
33
+ <div class='flex gap-2 m-2'>
34
+ <a class="block bg-green-700 text-white px-8 py-3 rounded-lg font-bold hover:bg-green-800 transition"
35
+ href='/get-started'>Get Started</a>
36
+ <a class="block border border-green-700 text-black px-8 py-3 rounded-lg font-bold hover:text-white hover:bg-green-800 transition"
37
+ href='/documentation/#introduction'>Documentation</a>
38
+ </div>
39
+ <div class='flex gap-2 m-2'>
40
+ <a class="block border border-green-700 text-black px-8 py-3 rounded-lg font-bold hover:text-white hover:bg-green-800 transition"
41
+ href='https://github.com/ritishDas/Gardener'>View On Github</a>
42
+ <a class="block border border-green-700 text-black px-8 py-3 rounded-lg font-bold hover:text-white hover:bg-green-800 transition"
43
+ href='https://www.npmjs.com/package/create-gardener'>View On npm</a>
35
44
  </div>
36
- <img src="/static/cache/gardener_500x500.webp" alt="Gardener Logo" class="w-96 h-96 object-contain ml-10">
37
45
  </div>
46
+ <img src="/static/cache/gardener_500x500.webp" alt="Gardener Logo" class="w-96 h-96 object-contain ml-10">
47
+ </div>
38
48
 
39
- <!-- Copy command -->
40
- <div class="flex w-1/4 items-center mx-auto my-15 justify-between gap-4 bg-[#1e1e1e] border border-gray-700 rounded-lg px-4 py-3 font-mono shadow-sm group">
41
- <span class="text-sm md:text-base text-gray-300 select-all">
42
- <span class="text-emerald-400 mr-2">$</span><span class='initCommand'>pnpm create gardener app</span>
43
- </span>
44
-
45
- <button class="copybtn flex items-center justify-center p-2 text-gray-400 hover:text-white hover:bg-white/10 rounded transition-all duration-200 active:scale-95" title="Copy to clipboard">
46
- <span class="w-5 h-5" >
47
- <%- include('partials/icons/clipboard') %>
48
- </span>
49
- </button>
50
- </div>
51
- <!-- Philosophy -->
52
- <div class="max-w-5xl mx-auto py-20 px-6 grid md:grid-cols-2 gap-12">
53
- <div>
54
- <h3 class="text-3xl font-bold mb-4 text-green-900">✨ Philosophy</h3>
55
- <ul class="space-y-3 text-slate-700">
56
- <li><strong>DOM-First:</strong> Renders directly to the real DOM.</li>
57
- <li><strong>Deterministic:</strong> If you can inspect it, you can understand it.</li>
58
- <li><strong>Native:</strong> Works in the browser via ES modules.</li>
59
- <li><strong>Zero Build:</strong> No bundlers or magic required.</li>
60
- </ul>
61
- </div>
49
+ <!-- Copy command -->
50
+ <div
51
+ class="flex w-1/4 items-center mx-auto my-15 justify-between gap-4 bg-[#1e1e1e] border border-gray-700 rounded-lg px-4 py-3 font-mono shadow-sm group">
52
+ <span class="text-sm md:text-base text-gray-300 select-all">
53
+ <span class="text-emerald-400 mr-2">$</span><span class='initCommand'>pnpm create gardener app</span>
54
+ </span>
55
+
56
+ <button
57
+ class="copybtn flex items-center justify-center p-2 text-gray-400 hover:text-white hover:bg-white/10 rounded transition-all duration-200 active:scale-95"
58
+ title="Copy to clipboard">
59
+ <span class="w-5 h-5">
60
+ <%- include('partials/icons/clipboard') %>
61
+ </span>
62
+ </button>
63
+ </div>
64
+ <!-- Philosophy -->
65
+ <div class="max-w-5xl mx-auto py-20 px-6 grid md:grid-cols-2 gap-12">
66
+ <div>
67
+ <h3 class="text-3xl font-bold mb-4 text-green-900">✨ Philosophy</h3>
68
+ <ul class="space-y-3 text-slate-700">
69
+ <li><strong>DOM-First:</strong> Renders directly to the real DOM.</li>
70
+ <li><strong>Deterministic:</strong> If you can inspect it, you can understand it.</li>
71
+ <li><strong>Native:</strong> Works in the browser via ES modules.</li>
72
+ <li><strong>Zero Build:</strong> No bundlers or magic required.</li>
73
+ </ul>
74
+ </div>
62
75
 
63
- <!-- Features -->
64
- <div>
65
- <h3 class="text-3xl font-bold mb-4 text-green-900">🚀 Features</h3>
66
- <div class="grid grid-cols-2 gap-4">
67
- <div class="p-4 bg-white shadow-sm border border-green-100 rounded">Declarative UI</div>
68
- <div class="p-4 bg-white shadow-sm border border-green-100 rounded">SVG Namespace Support</div>
69
- <div class="p-4 bg-white shadow-sm border border-green-100 rounded">Hot Reload</div>
70
- <div class="p-4 bg-white shadow-sm border border-green-100 rounded">Image Optimization</div>
71
- </div>
76
+ <!-- Features -->
77
+ <div>
78
+ <h3 class="text-3xl font-bold mb-4 text-green-900">🚀 Features</h3>
79
+ <div class="grid grid-cols-2 gap-4">
80
+ <div class="p-4 bg-white shadow-sm border border-green-100 rounded">Declarative UI</div>
81
+ <div class="p-4 bg-white shadow-sm border border-green-100 rounded">SVG Namespace Support</div>
82
+ <div class="p-4 bg-white shadow-sm border border-green-100 rounded">Hot Reload</div>
83
+ <div class="p-4 bg-white shadow-sm border border-green-100 rounded">Image Optimization</div>
72
84
  </div>
73
85
  </div>
86
+ </div>
74
87
 
75
- <!-- Api Example -->
76
- <div class="bg-slate-900 py-20 text-white">
77
- <div class="max-w-5xl mx-auto px-6">
78
- <h3 class="text-3xl font-bold mb-8 text-center text-green-400">The Core API</h3>
79
- <div class="bg-slate-800 p-6 rounded-xl border border-slate-700 font-mono text-sm overflow-x-auto">
80
- <pre class="text-blue-300">
88
+ <!-- Api Example -->
89
+ <div class="bg-slate-900 py-20 text-white">
90
+ <div class="max-w-5xl mx-auto px-6">
91
+ <h3 class="text-3xl font-bold mb-8 text-center text-green-400">The Core API</h3>
92
+ <div class="bg-slate-800 p-6 rounded-xl border border-slate-700 font-mono text-sm overflow-x-auto">
93
+ <pre class="text-blue-300">
81
94
  gardener({
82
95
  t: <span class="text-green-300">'div'</span>,
83
96
  cn: [<span class="text-green-300">'p-6'</span>, <span class="text-green-300">'flex'</span>],
@@ -91,35 +104,36 @@ gardener({
91
104
  ]
92
105
  })
93
106
  </pre>
94
- </div>
95
107
  </div>
96
108
  </div>
109
+ </div>
97
110
 
98
- <div class="max-w-5xl mx-auto py-20 px-6 text-center">
99
- <h3 class="text-3xl font-bold mb-4 text-green-900">🧠 Simple State</h3>
100
- <p class="mb-8 text-slate-600">No proxies. No diffing. Just clean, reactive callbacks.</p>
101
- <div class="inline-block text-left bg-white p-6 rounded shadow-lg border-t-4 border-green-500 font-mono text-sm">
102
- <p class="text-slate-500">// Initialize</p>
103
- <p>const count = new State(0);</p>
104
- <p class="text-slate-500 mt-2">// React</p>
105
- <p>count.registerCb(val => updateUI(val));</p>
106
- </div>
111
+ <div class="max-w-5xl mx-auto py-20 px-6 text-center">
112
+ <h3 class="text-3xl font-bold mb-4 text-green-900">🧠 Simple State</h3>
113
+ <p class="mb-8 text-slate-600">No proxies. No diffing. Just clean, reactive callbacks.</p>
114
+ <div class="inline-block text-left bg-white p-6 rounded shadow-lg border-t-4 border-green-500 font-mono text-sm">
115
+ <p class="text-slate-500">// Initialize</p>
116
+ <p>const count = new State(0);</p>
117
+ <p class="text-slate-500 mt-2">// React</p>
118
+ <p>count.registerCb(val => updateUI(val));</p>
107
119
  </div>
108
-
109
- <!-- Footer -->
110
- <footer class="bg-green-900 text-green-100 py-12 text-center">
111
- <p class="text-xl italic">"Because sometimes you don't need a forest. Just a garden."</p>
112
- <div class="mt-6 text-sm opacity-70">
113
- MIT Licensed | Built on Express & EJS
114
- </div>
115
- </footer>
116
120
  </div>
117
121
 
118
- </body>
119
- <% if (process.env.NODE_ENV === 'production') { %>
120
- <script type='module' src='/static/bundle/bundle.<%=fileName%>.js'></script>
122
+ <!-- Footer -->
123
+ <footer class="bg-green-900 text-green-100 py-12 text-center">
124
+ <p class="text-xl italic">"Because sometimes you don't need a forest. Just a garden."</p>
125
+ <div class="mt-6 text-sm opacity-70">
126
+ MIT Licensed | Built on Express & EJS
127
+ </div>
128
+ </footer>
129
+ </div>
130
+
131
+ </body>
132
+ <% if (process.env.NODE_ENV==='production' ) { %>
133
+ <script type='module' src='/static/bundle/bundle.<%=fileName%>.js'></script>
121
134
  <% } else { %>
122
135
  <script type='module' src='/static/global.js'></script>
123
136
  <script type='module' src='/static/pages/pages._.js'></script>
124
- <% } %>
125
- </html>
137
+ <% } %>
138
+
139
+ </html>
@@ -1,8 +0,0 @@
1
- import type { Request, Response } from "express";
2
- interface AddComponentBody {
3
- path: string;
4
- component: string;
5
- }
6
- export declare function addComponent(req: Request<{}, {}, AddComponentBody>, res: Response): Promise<void>;
7
- export {};
8
- //# sourceMappingURL=addComponent.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"addComponent.d.ts","sourceRoot":"","sources":["../../../../src/backend/controllers/gardener/addComponent.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAIjD,UAAU,gBAAgB;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;CACnB;AAQD,wBAAsB,YAAY,CAAC,GAAG,EAAE,OAAO,CAAC,EAAE,EAAE,EAAE,EAAE,gBAAgB,CAAC,EAAE,GAAG,EAAE,QAAQ,iBAWvF"}
@@ -1,19 +0,0 @@
1
- import fsp from "fs/promises";
2
- import path from 'path';
3
- import { fileURLToPath } from "url";
4
- const __filename = fileURLToPath(import.meta.url);
5
- const __dirname = path.dirname(__filename);
6
- const frontendDir = path.resolve(__dirname, '..', '..', '..', 'frontend');
7
- export async function addComponent(req, res) {
8
- try {
9
- const { path: filePath, component } = req.body;
10
- await fsp.mkdir(path.join(frontendDir, 'static', 'components'), { recursive: true });
11
- await fsp.writeFile(path.join(frontendDir, `${filePath}`), component, "utf8");
12
- res.json({ success: true });
13
- }
14
- catch (err) {
15
- const error = err;
16
- res.json({ success: false, msg: error.message });
17
- }
18
- }
19
- //# sourceMappingURL=addComponent.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"addComponent.js","sourceRoot":"","sources":["../../../../src/backend/controllers/gardener/addComponent.ts"],"names":[],"mappings":"AACA,OAAO,GAAG,MAAM,aAAa,CAAC;AAC9B,OAAO,IAAI,MAAM,MAAM,CAAC;AAOxB,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACpC,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;AAE3C,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC;AAE1E,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,GAAsC,EAAE,GAAa;IACtF,IAAI,CAAC;QACH,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,GAAG,CAAC,IAAI,CAAC;QAC/C,MAAM,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,QAAQ,EAAE,YAAY,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACrF,MAAM,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,QAAQ,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;QAC9E,GAAG,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;IAE9B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,KAAK,GAAG,GAAY,CAAC;QAC3B,GAAG,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;IACnD,CAAC;AACH,CAAC"}