create-gardener 2.1.3 → 2.1.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 (96) hide show
  1. package/README.md +108 -302
  2. package/package.json +1 -1
  3. package/template/.env +3 -0
  4. package/template/README.md +181 -0
  5. package/template/buildHelper.js +5 -0
  6. package/template/src/backend/controllers/gardener/hotReload.ts +34 -0
  7. package/template/src/backend/controllers/gardener/imageOptimiser.ts +114 -25
  8. package/template/src/backend/controllers/gardener/index.ts +1 -0
  9. package/template/src/backend/routes/gardener.route.ts +2 -1
  10. package/template/src/backend/server.ts +19 -1
  11. package/template/src/frontend/assets/remote/betterway.jpg +0 -0
  12. package/template/src/frontend/static/components/gardener/hotReloadbtn.js +25 -78
  13. package/template/src/frontend/static/gardenerDev.js +2 -18
  14. package/template/src/frontend/static/style.css +0 -77
  15. package/template/src/frontend/views/_.ejs +101 -89
  16. package/template/build/backend/controllers/gardener/addComponent.d.ts +0 -8
  17. package/template/build/backend/controllers/gardener/addComponent.d.ts.map +0 -1
  18. package/template/build/backend/controllers/gardener/addComponent.js +0 -19
  19. package/template/build/backend/controllers/gardener/addComponent.js.map +0 -1
  20. package/template/build/backend/controllers/gardener/addPage.d.ts +0 -3
  21. package/template/build/backend/controllers/gardener/addPage.d.ts.map +0 -1
  22. package/template/build/backend/controllers/gardener/addPage.js +0 -86
  23. package/template/build/backend/controllers/gardener/addPage.js.map +0 -1
  24. package/template/build/backend/controllers/gardener/createStatic.d.ts +0 -3
  25. package/template/build/backend/controllers/gardener/createStatic.d.ts.map +0 -1
  26. package/template/build/backend/controllers/gardener/createStatic.js +0 -63
  27. package/template/build/backend/controllers/gardener/createStatic.js.map +0 -1
  28. package/template/build/backend/controllers/gardener/imageOptimiser.d.ts +0 -3
  29. package/template/build/backend/controllers/gardener/imageOptimiser.d.ts.map +0 -1
  30. package/template/build/backend/controllers/gardener/imageOptimiser.js +0 -54
  31. package/template/build/backend/controllers/gardener/imageOptimiser.js.map +0 -1
  32. package/template/build/backend/controllers/gardener/index.d.ts +0 -6
  33. package/template/build/backend/controllers/gardener/index.d.ts.map +0 -1
  34. package/template/build/backend/controllers/gardener/index.js +0 -6
  35. package/template/build/backend/controllers/gardener/index.js.map +0 -1
  36. package/template/build/backend/controllers/gardener/saveTemplate.d.ts +0 -3
  37. package/template/build/backend/controllers/gardener/saveTemplate.d.ts.map +0 -1
  38. package/template/build/backend/controllers/gardener/saveTemplate.js +0 -36
  39. package/template/build/backend/controllers/gardener/saveTemplate.js.map +0 -1
  40. package/template/build/backend/libs/generateWebp.d.ts +0 -2
  41. package/template/build/backend/libs/generateWebp.d.ts.map +0 -1
  42. package/template/build/backend/libs/generateWebp.js +0 -16
  43. package/template/build/backend/libs/generateWebp.js.map +0 -1
  44. package/template/build/backend/routes/gardener.route.d.ts +0 -4
  45. package/template/build/backend/routes/gardener.route.d.ts.map +0 -1
  46. package/template/build/backend/routes/gardener.route.js +0 -18
  47. package/template/build/backend/routes/gardener.route.js.map +0 -1
  48. package/template/build/backend/server.d.ts +0 -2
  49. package/template/build/backend/server.d.ts.map +0 -1
  50. package/template/build/backend/server.js +0 -20
  51. package/template/build/backend/server.js.map +0 -1
  52. package/template/build/frontend/assets/favicon.png +0 -0
  53. package/template/build/frontend/assets/gardener.jpg +0 -0
  54. package/template/build/frontend/static/bundle/bundle._.js +0 -1
  55. package/template/build/frontend/static/bundle/bundle._about.js +0 -1
  56. package/template/build/frontend/static/bundle/bundle._kartik.js +0 -1
  57. package/template/build/frontend/static/bundle/bundle._new.js +0 -1
  58. package/template/build/frontend/static/bundle/bundle._ritish.js +0 -1
  59. package/template/build/frontend/static/cache/favicon_500x500.webp +0 -0
  60. package/template/build/frontend/static/cache/favicon_50x50.webp +0 -0
  61. package/template/build/frontend/static/cache/gardener_100x100.webp +0 -0
  62. package/template/build/frontend/static/cache/gardener_500x500.webp +0 -0
  63. package/template/build/frontend/static/cache/gardener_50x50.webp +0 -0
  64. package/template/build/frontend/static/components/copybtn.js +0 -99
  65. package/template/build/frontend/static/components/footer.js +0 -33
  66. package/template/build/frontend/static/components/gardener/errorBox.js +0 -47
  67. package/template/build/frontend/static/components/gardener/hotReloadbtn.js +0 -82
  68. package/template/build/frontend/static/components/gardener/pageOverlayBtn.js +0 -138
  69. package/template/build/frontend/static/components/gardener/parserWindow.js +0 -159
  70. package/template/build/frontend/static/components/nonui/api.js +0 -52
  71. package/template/build/frontend/static/components/nonui/navigation.js +0 -59
  72. package/template/build/frontend/static/components/notification.js +0 -67
  73. package/template/build/frontend/static/gardener.js +0 -160
  74. package/template/build/frontend/static/gardenerConfig.js +0 -1
  75. package/template/build/frontend/static/gardenerDev.js +0 -165
  76. package/template/build/frontend/static/global.js +0 -4
  77. package/template/build/frontend/static/pages/pages._.js +0 -25
  78. package/template/build/frontend/static/pages/pages._about.js +0 -2
  79. package/template/build/frontend/static/pages/pages._kartik.js +0 -2
  80. package/template/build/frontend/static/pages/pages._new.js +0 -2
  81. package/template/build/frontend/static/pages/pages._ritish.js +0 -2
  82. package/template/build/frontend/static/style.css +0 -2
  83. package/template/build/frontend/static/style2.css +0 -26
  84. package/template/build/frontend/style.css +0 -1045
  85. package/template/build/frontend/tailwind.css +0 -1
  86. package/template/build/frontend/views/_.ejs +0 -125
  87. package/template/build/frontend/views/_about.ejs +0 -126
  88. package/template/build/frontend/views/_kartik.ejs +0 -126
  89. package/template/build/frontend/views/_new.ejs +0 -126
  90. package/template/build/frontend/views/_ritish.ejs +0 -126
  91. package/template/build/frontend/views/partials/icons/clipboard.ejs +0 -1
  92. package/template/build/frontend/views/partials/icons/clipboardok.ejs +0 -1
  93. package/template/src/frontend/static/cache/favicon_500x500.webp +0 -0
  94. package/template/src/frontend/static/cache/favicon_50x50.webp +0 -0
  95. package/template/src/frontend/static/cache/gardener_100x100.webp +0 -0
  96. package/template/src/frontend/static/cache/gardener_500x500.webp +0 -0
package/README.md CHANGED
@@ -1,360 +1,165 @@
1
- # 🌱 Gardener
1
+ # Gardener — DOM-First Mini Framework
2
2
 
3
- A full-stack web framework that combines Express.js backend with EJS templating and a unique DOM-to-JSON component system. Build web apps with a visual-first approach where you can convert any DOM element into reusable components with a single function call.
3
+ Gardener is a lightweight web framework built on top of Express and EJS. It enables building web applications without React or heavy frontend frameworks by using a DOM-first approach with reusable components.
4
4
 
5
- ## 🚀 Quick Start
6
-
7
- Create a new Gardener app:
8
-
9
- ```bash
10
- pnpm create gardener app
11
- ```
12
-
13
- Install dependencies and start development:
14
-
15
- ```bash
16
- pnpm install
17
- pnpm dev
18
- ```
19
-
20
- Your app will be running with hot reload enabled!
21
-
22
- ## 🌟 Core Features
23
-
24
- ### Backend
25
- - **Express.js**: Familiar Node.js backend with full Express capabilities
26
- - **TypeScript Ready**: Built-in TypeScript support for type-safe development
27
- - **Static Site Generation**: Export your dynamic app to static HTML with one API call
28
-
29
- ### Frontend
30
- - **EJS Templating**: Server-side rendering with EJS views
31
- - **Tailwind CSS**: Integrated with watch mode for rapid styling
32
- - **Gardener Component System**: Unique DOM-to-JSON conversion for reusable components
33
- - **Live Development Tools**: Browser-based route and component creation
34
-
35
- ### Developer Experience
36
- - **Hot Reload**: Toggle with `Alt + H` for instant CSS updates
37
- - **Visual Component Parser**: Convert DOM elements to JSON components in the browser
38
- - **Browser-Based Routing**: Create new routes without touching your code
39
- - **Image Optimization**: Automatic WebP conversion with smart sizing
40
-
41
- ## 📖 Complete Workflow
42
-
43
- ### 1. Backend Development
44
-
45
- Write familiar Express.js code in TypeScript:
46
-
47
- ```typescript
48
- // src/backend/server.ts
49
- app.get('/api/posts', (req, res) => {
50
- res.json({ posts: [] });
51
- });
52
- ```
53
-
54
- ### 2. Creating Pages & Routes
55
-
56
- **Two ways to create routes:**
5
+ ---
57
6
 
58
- #### Browser Method (Recommended for Development)
59
- 1. Click the "**New Page**" button that appears in development mode
60
- 2. Enter your route path (e.g., `/about`, `/blog/post`)
61
- 3. Press Enter - the route and EJS file are created automatically!
7
+ ## What it does
62
8
 
63
- #### Manual Method
64
- Create an EJS file in `src/frontend/views/` and add the Express route manually.
9
+ Gardener lets you:
65
10
 
66
- ### 3. Working with Components
11
+ - Build UI using plain HTML, CSS, and JavaScript
12
+ - Convert DOM elements into reusable components
13
+ - Serve lightweight pages with minimal runtime overhead
67
14
 
68
- Gardener has **two component types**:
15
+ ---
69
16
 
70
- #### A. EJS Partials (Traditional)
71
- Static components that render once:
72
- ```ejs
73
- <%- include('partials/header') %>
74
- ```
17
+ ## Why it exists
75
18
 
76
- #### B. Gardener Components (Dynamic)
77
- JSON-based components with the Gardener system:
78
-
79
- **Creating a Component:**
80
- 1. Write your HTML structure in an EJS file or browser
81
- 2. In your JavaScript file, call:
82
- ```javascript
83
- import { parser } from '/static/gardenerDev.js';
84
-
85
- parser('.my-component-selector');
86
- ```
87
- 3. A window appears in the browser with the JSON representation
88
- 4. Name and save the component
89
- 5. The component is now reusable!
90
-
91
- **Using a Component:**
92
- ```javascript
93
- import { myComponent } from '/static/components/myComponent.js';
94
- import { gardener, appendElement } from '/static/gardener.js';
95
-
96
- // Render the component
97
- const element = gardener(myComponent);
98
- appendElement('#container', element);
99
- ```
19
+ Modern frameworks introduce significant abstraction and bundle size overhead.
100
20
 
101
- **Component Structure:**
102
- ```javascript
103
- // Gardener components are JSON objects
104
- export const button = {
105
- t: 'button', // tag
106
- cn: ['btn', 'primary'], // classNames
107
- txt: 'Click me', // text content
108
- attr: { id: 'submit' }, // attributes
109
- events: { click: handleClick }, // event handlers
110
- children: [...] // nested components
111
- };
112
- ```
21
+ Gardener focuses on:
113
22
 
114
- ### 4. Parameterized Components
23
+ - Minimal runtime (~300 lines core)
24
+ - Direct DOM control
25
+ - Simplicity over abstraction
115
26
 
116
- Create dynamic components with parameters using `??`:
27
+ ---
117
28
 
118
- ```javascript
119
- // In your component definition, wrap dynamic parts with ??
120
- const card = {
121
- t: 'div',
122
- cn: ['card'],
123
- children: [
124
- { t: 'h2', txt: '??title??' },
125
- { t: 'p', txt: '??description??' }
29
+ ## Example
30
+
31
+ Define a component using JSON:
32
+
33
+ ```
34
+ {
35
+ "t": "div",
36
+ "cn": ["flex", "justify-center", "items-center", "target"],
37
+ "children": [
38
+ {
39
+ "t": "span",
40
+ "cn": ["text-xl", "font-bold"],
41
+ "txt": "Hello World"
42
+ },
43
+ {
44
+ "t": "button",
45
+ "txt": "click",
46
+ "events": {
47
+ "click": "() => console.log('button clicked')"
48
+ }
49
+ }
126
50
  ]
127
- };
128
-
129
- // Use with parameters
130
- const myCard = gardener(card, {
131
- title: 'Hello',
132
- description: 'World'
133
- });
134
- ```
135
-
136
- ### 5. Template System
137
-
138
- **Save Current Page as Template:**
139
- - Click "**Save Template**" button in the browser
140
- - This saves the current page structure as a template
141
- - Used automatically for deeper routes (e.g., `/blog/` template for `/blog/post-1`)
142
-
143
- ### 6. Dynamic Routes & Parameters
144
-
145
- For parameterized routes like `/post/:id`:
146
-
147
- **Backend:**
148
- ```javascript
149
- app.get('/post/:id', (req, res) => {
150
- res.render('post', {
151
- id: req.params.id,
152
- title: 'My Post'
153
- });
154
- });
51
+ }
155
52
  ```
156
53
 
157
- **Frontend (EJS):**
158
- ```ejs
159
- <h1>Post <%= id %></h1>
160
- <p><%= title %></p>
161
- ```
162
-
163
- **Query Parameters:**
164
- ```javascript
165
- // Backend
166
- app.get('/search', (req, res) => {
167
- const query = req.query.q;
168
- res.render('search', { query });
169
- });
170
-
171
- // Frontend EJS
172
- <p>Searching for: <%= query %></p>
173
- ```
54
+ You don’t need to write JSON manually.
174
55
 
175
- ### 7. Hot Reload for Styling
56
+ Instead:
176
57
 
177
- Press **`Alt + H`** to toggle hot reload mode:
178
- - Automatically refreshes CSS changes
179
- - No page reload needed
180
- - Perfect for rapid styling iterations
181
-
182
- ### 8. Image Optimization
183
-
184
- Use the built-in image optimizer:
185
-
186
- ```html
187
- <img src="/static/image_800x600.webp" alt="Optimized">
188
- ```
58
+ 1. Write standard HTML
59
+ 2. Select an element (id/class)
60
+ 3. Run the parser → generates reusable component
189
61
 
190
- Format: `/static/image_{width}x{height}.webp`
62
+ ---
191
63
 
192
- The server automatically:
193
- - Converts to WebP format
194
- - Resizes to specified dimensions
195
- - Caches for performance
64
+ ## Key Features
196
65
 
197
- ### 9. Static Site Generation
66
+ - Lightweight (~300 lines core, bundled with esbuild)
67
+ - No frontend framework dependency
68
+ - Reusable components (DOM → JSON)
69
+ - Server-side rendering via EJS
70
+ - Hot reloading
71
+ - Image optimization (Sharp + caching)
72
+ - Static build support
73
+ - One-command page creation
198
74
 
199
- Generate a static version of your entire app:
75
+ ---
200
76
 
201
- ```javascript
202
- // Make a GET request
203
- fetch('/createStatic')
204
- ```
77
+ ## Architecture
205
78
 
206
- Or visit `http://localhost:3000/createStatic` in your browser.
79
+ Gardener follows a simple request → render → enhance flow:
207
80
 
208
- Your static site is generated in the `/build` directory!
81
+ - Express handles routing and backend logic
82
+ - EJS renders templates into HTML
83
+ - Frontend library enhances DOM with:
84
+ - component system
85
+ - state handling
86
+ - dev tooling
209
87
 
210
- ## 🧩 API Reference
88
+ ---
211
89
 
212
- ### Gardener Core (`/static/gardener.js`)
90
+ ## Components
213
91
 
214
- ```javascript
215
- import {
216
- gardener, // Convert JSON to DOM elements
217
- fetchElement, // Query selector wrapper
218
- appendElement, // Append child with error handling
219
- createElement, // Create element with classes
220
- insertText, // Set text content
221
- replaceElement // Replace element in DOM
222
- } from '/static/gardener.js';
92
+ ### Two types:
223
93
 
224
- // Create element from JSON
225
- const el = gardener({
226
- t: 'div',
227
- cn: ['container'],
228
- attr: { id: 'main' },
229
- children: [...]
230
- });
231
- ```
94
+ 1. Static Components
232
95
 
233
- ### Gardener Dev Tools (`/static/gardenerDev.js`)
234
-
235
- ```javascript
236
- import {
237
- parser, // Convert DOM to JSON
238
- parserWindow, // Show parser UI
239
- State, // Reactive state management
240
- addEl // Add event listener helper
241
- } from '/static/gardenerDev.js';
242
-
243
- // Reactive State
244
- const count = new State(0);
245
- count.registerCb((value) => {
246
- console.log('Count:', value);
247
- });
248
- count.setTo(1); // Triggers callback
249
- ```
96
+ - EJS partials
97
+ - Require full page reload
250
98
 
251
- ### Navigation (`/static/components/nonui/navigation.js`)
99
+ 2. Dynamic Components
252
100
 
253
- ```javascript
254
- import {
255
- nextPage, // Navigate with animation
256
- nextPagehandler, // Set up link handlers
257
- pageloader // Handle page loader
258
- } from '/static/components/nonui/navigation.js';
259
- ```
101
+ - Generated from DOM → JSON
102
+ - Reusable and parameterized
260
103
 
261
- ### API Utilities (`/static/components/nonui/api.js`)
104
+ Example parameter:
262
105
 
263
- ```javascript
264
- import { Fetch } from '/static/components/nonui/api.js';
106
+ <span>?title?</span>
265
107
 
266
- // Make API requests
267
- const response = await Fetch('/api/data', { key: 'value' }, 'POST');
268
- const data = await response.json();
269
- ```
108
+ This creates a dynamic variable "title".
270
109
 
271
- ## 📁 Project Structure
110
+ ---
272
111
 
273
- ```
274
- your-app/
275
- ├── src/
276
- │ ├── backend/
277
- │ │ ├── server.ts # Main server file
278
- │ │ ├── routes/ # Express routes
279
- │ │ └── controllers/ # Route controllers
280
- │ └── frontend/
281
- │ ├── views/ # EJS templates
282
- │ │ └── partials/ # EJS partials
283
- │ ├── static/ # Client-side JS
284
- │ │ ├── gardener.js # Core framework
285
- │ │ ├── gardenerDev.js # Dev tools
286
- │ │ ├── components/ # Gardener components
287
- │ │ └── pages/ # Page-specific JS
288
- │ ├── template/ # Page templates
289
- │ ├── style.css # Compiled Tailwind
290
- │ └── tailwind.css # Tailwind source
291
- ├── build/ # Static site output
292
- └── package.json
293
- ```
112
+ ## Image Optimization
294
113
 
295
- ## 🎯 Key Concepts
114
+ - Uses Sharp for processing
115
+ - Cached images served via:
296
116
 
297
- ### 1. DOM-to-JSON Parser
298
- The `parser()` function converts any DOM element into a JSON representation that can be saved as a reusable component. This allows you to:
299
- - Build UI visually in the browser
300
- - Extract components without manual coding
301
- - Create a library of reusable elements
117
+ /static/[image_name]_[width]x[height].webp
302
118
 
303
- ### 2. Component Composition
304
- Components are composable JSON objects. Build complex UIs by nesting components:
119
+ ---
305
120
 
306
- ```javascript
307
- const page = {
308
- t: 'div',
309
- children: [
310
- header,
311
- mainContent,
312
- footer
313
- ]
314
- };
315
- ```
121
+ ## Hot Reloading
316
122
 
317
- ### 3. Development vs Production
318
- - **Development**: Full dev tools, component parser, hot reload
319
- - **Production**: Minimal runtime, optimized assets, static export option
123
+ - Backend watches file changes
124
+ - Generates hash updates
125
+ - Frontend polls reload endpoint
126
+ - Full page reload triggered on change
320
127
 
321
- ## 🔧 Configuration
128
+ ---
322
129
 
323
- Edit `src/frontend/static/gardenerConfig.js`:
130
+ ## Tech Stack
324
131
 
325
- ```javascript
326
- export const mode = 'dev'; // or 'production'
327
- ```
132
+ - TypeScript
133
+ - Express
134
+ - EJS
135
+ - esbuild
136
+ - Sharp
328
137
 
329
- ## 📚 Documentation
138
+ ---
330
139
 
331
- Visit [gardener.ritish.site](https://gardener.ritish.site) for full documentation and examples.
140
+ ## Setup
332
141
 
333
- ## 💡 Examples
142
+ npm create gardener <project-name>
334
143
 
335
- ### Creating a Blog Post Component
144
+ ---
336
145
 
337
- ```javascript
338
- // 1. Create HTML in your EJS file
339
- <div class="post">
340
- <h2 class="title">?title?</h2>
341
- <p class="content">?content?</p>
342
- </div>
146
+ ## Positioning
343
147
 
344
- <div class="post2">
345
- </div>
148
+ Gardener is designed for:
346
149
 
347
- // 2. Parse it by calling
348
- parser('.post');
150
+ - Developers who prefer control over abstraction
151
+ - Lightweight applications
152
+ - Learning how frameworks work internally
349
153
 
350
- // 3. accept the component by giving a name in browser
154
+ ---
351
155
 
352
- // 4. Use it
156
+ ## Future Work
353
157
 
354
- replaceElement('.post2', component({title:'new component', content:'this is the new content'}))
355
-
356
- ```
158
+ - Partial DOM updates (instead of full reload)
159
+ - Better state management primitives
160
+ - Devtools / debugging layer
357
161
 
162
+ ---
358
163
  ## 🤝 Contributing
359
164
 
360
165
  Contributions are welcome! Visit the [GitHub repository](https://github.com/ritishDas/gardener).
@@ -373,3 +178,4 @@ MIT License - See LICENSE file for details.
373
178
  ---
374
179
 
375
180
  Built with ❤️ for developers who want to move fast without breaking things.
181
+
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.5",
9
9
  "description": "A dom gardener converting dom elements into json and vice versa",
10
10
  "main": "index.js",
11
11
  "bin": {
package/template/.env CHANGED
@@ -0,0 +1,3 @@
1
+ # Comma-separated list of allowed domains (subdomains are included automatically)
2
+ GARDENER_IMAGE_DOMAINS=images.unsplash.com,cdn.mysite.com,example.com
3
+ PORT=3000
@@ -0,0 +1,181 @@
1
+ # Gardener — DOM-First Mini Framework
2
+
3
+ Gardener is a lightweight web framework built on top of Express and EJS. It enables building web applications without React or heavy frontend frameworks by using a DOM-first approach with reusable components.
4
+
5
+ ---
6
+
7
+ ## What it does
8
+
9
+ Gardener lets you:
10
+
11
+ - Build UI using plain HTML, CSS, and JavaScript
12
+ - Convert DOM elements into reusable components
13
+ - Serve lightweight pages with minimal runtime overhead
14
+
15
+ ---
16
+
17
+ ## Why it exists
18
+
19
+ Modern frameworks introduce significant abstraction and bundle size overhead.
20
+
21
+ Gardener focuses on:
22
+
23
+ - Minimal runtime (~300 lines core)
24
+ - Direct DOM control
25
+ - Simplicity over abstraction
26
+
27
+ ---
28
+
29
+ ## Example
30
+
31
+ Define a component using JSON:
32
+
33
+ ```
34
+ {
35
+ "t": "div",
36
+ "cn": ["flex", "justify-center", "items-center", "target"],
37
+ "children": [
38
+ {
39
+ "t": "span",
40
+ "cn": ["text-xl", "font-bold"],
41
+ "txt": "Hello World"
42
+ },
43
+ {
44
+ "t": "button",
45
+ "txt": "click",
46
+ "events": {
47
+ "click": "() => console.log('button clicked')"
48
+ }
49
+ }
50
+ ]
51
+ }
52
+ ```
53
+
54
+ You don’t need to write JSON manually.
55
+
56
+ Instead:
57
+
58
+ 1. Write standard HTML
59
+ 2. Select an element (id/class)
60
+ 3. Run the parser → generates reusable component
61
+
62
+ ---
63
+
64
+ ## Key Features
65
+
66
+ - Lightweight (~300 lines core, bundled with esbuild)
67
+ - No frontend framework dependency
68
+ - Reusable components (DOM → JSON)
69
+ - Server-side rendering via EJS
70
+ - Hot reloading
71
+ - Image optimization (Sharp + caching)
72
+ - Static build support
73
+ - One-command page creation
74
+
75
+ ---
76
+
77
+ ## Architecture
78
+
79
+ Gardener follows a simple request → render → enhance flow:
80
+
81
+ - Express handles routing and backend logic
82
+ - EJS renders templates into HTML
83
+ - Frontend library enhances DOM with:
84
+ - component system
85
+ - state handling
86
+ - dev tooling
87
+
88
+ ---
89
+
90
+ ## Components
91
+
92
+ ### Two types:
93
+
94
+ 1. Static Components
95
+
96
+ - EJS partials
97
+ - Require full page reload
98
+
99
+ 2. Dynamic Components
100
+
101
+ - Generated from DOM → JSON
102
+ - Reusable and parameterized
103
+
104
+ Example parameter:
105
+
106
+ <span>?title?</span>
107
+
108
+ This creates a dynamic variable "title".
109
+
110
+ ---
111
+
112
+ ## Image Optimization
113
+
114
+ - Uses Sharp for processing
115
+ - Cached images served via:
116
+
117
+ /static/[image_name]_[width]x[height].webp
118
+
119
+ ---
120
+
121
+ ## Hot Reloading
122
+
123
+ - Backend watches file changes
124
+ - Generates hash updates
125
+ - Frontend polls reload endpoint
126
+ - Full page reload triggered on change
127
+
128
+ ---
129
+
130
+ ## Tech Stack
131
+
132
+ - TypeScript
133
+ - Express
134
+ - EJS
135
+ - esbuild
136
+ - Sharp
137
+
138
+ ---
139
+
140
+ ## Setup
141
+
142
+ npm create gardener <project-name>
143
+
144
+ ---
145
+
146
+ ## Positioning
147
+
148
+ Gardener is designed for:
149
+
150
+ - Developers who prefer control over abstraction
151
+ - Lightweight applications
152
+ - Learning how frameworks work internally
153
+
154
+ ---
155
+
156
+ ## Future Work
157
+
158
+ - Partial DOM updates (instead of full reload)
159
+ - Better state management primitives
160
+ - Devtools / debugging layer
161
+
162
+ ---
163
+ ## 🤝 Contributing
164
+
165
+ Contributions are welcome! Visit the [GitHub repository](https://github.com/ritishDas/gardener).
166
+
167
+ ## 📄 License
168
+
169
+ MIT License - See LICENSE file for details.
170
+
171
+ ## 👤 Author
172
+
173
+ **ritishDas**
174
+
175
+ - GitHub: [@ritishDas](https://github.com/ritishDas)
176
+ - Website: [gardener.ritish.site](https://gardener.ritish.site)
177
+
178
+ ---
179
+
180
+ Built with ❤️ for developers who want to move fast without breaking things.
181
+
@@ -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(