vaderjs 1.6.6 → 1.6.8

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/index.ts CHANGED
@@ -1,19 +1,19 @@
1
1
  //@ts-nocheck
2
2
  let isClassComponent = function(element) {
3
3
  return element.toString().startsWith("class");
4
- };
4
+ };
5
5
 
6
6
  const memoizes = new Map();
7
7
  //@ts-ignore
8
-
8
+
9
9
  declare global {
10
10
  interface Window {
11
11
  onbeforeunload: any;
12
12
  localStorage: any;
13
13
  sessionStorage: any;
14
14
  state: any;
15
- }
16
- const genKey: any;
15
+ }
16
+ const genKey: any;
17
17
  /**
18
18
  * @description Allows you to check if current session is server or client
19
19
  */
@@ -42,13 +42,13 @@ globalThis.params = {
42
42
  }
43
43
  },
44
44
  };
45
-
46
-
45
+
46
+
47
47
 
48
48
  /**
49
49
  * @description useFetch allows you to make POST - GET - PUT - DELETE requests then returns the data, loading state and error
50
- * @param url
51
- * @param options
50
+ * @param url
51
+ * @param options
52
52
  * @returns [data, loading, error]
53
53
  */
54
54
  export const useFetch = (url: string, options: any) => {
@@ -56,9 +56,9 @@ export const useFetch = (url: string, options: any) => {
56
56
  };
57
57
 
58
58
  /**
59
- * @description - Handle asyncronous promises and return the data or error;
60
- * @param promise
61
- * @returns
59
+ * @description - Handle asyncronous promises and return the data or error;
60
+ * @param promise
61
+ * @returns
62
62
  */
63
63
  export const useAsyncState = (promise: Promise<any>) => {
64
64
  return [null, () => {}];
@@ -68,17 +68,35 @@ export const useEffect = (callback:any, dependencies: any[]) => {
68
68
  if (dependencies.length === 0) {
69
69
  callback();
70
70
  }
71
- }
71
+ }
72
72
 
73
73
  // make a switch function component
74
74
 
75
75
 
76
- export const A = (props: any, children: any) => {
76
+ export const A = (props: {
77
+ /**
78
+ * @description Set the elements classlist
79
+ */
80
+ class: string;
81
+ /**
82
+ * @description Once clicked send user to a different link
83
+ */
84
+ href: string;
85
+ style: string;
86
+ openInNewTab: boolean
87
+ onClick: () => void;
88
+ onChange: () => void;
89
+ }, children: any) => {
77
90
  function handleClick(e) {
78
91
  e.preventDefault();
92
+ if(props.openInNewTab){
93
+ window.open(props.href, "_blank");
94
+ return void 0;
95
+ }
79
96
  window.history.pushState({}, "", props.href);
80
97
  window.dispatchEvent(new PopStateEvent("popstate"));
81
98
  window.location.reload();
99
+ return void 0;
82
100
  }
83
101
  return {
84
102
  type: "a",
@@ -88,33 +106,39 @@ export const A = (props: any, children: any) => {
88
106
  }
89
107
 
90
108
 
91
- export const Fragment = (props: any, children: any) => {
92
- return children[0];
109
+ export const Fragment = (props: any, children: any) => {
110
+ return {
111
+ type:null,
112
+ props: props,
113
+ children
114
+ }
93
115
  }
94
116
 
95
117
  globalThis.Fragment = Fragment;
96
118
 
97
119
  /**
98
120
  * @description - Create a new element
99
- * @param element
100
- * @param props
101
- * @param children
102
- * @returns
121
+ * @param element
122
+ * @param props
123
+ * @param children
124
+ * @returns
103
125
  */
104
- export const e = (element, props, ...children) => {
126
+ export const e = (element, props, ...children) => {
105
127
  let instance;
106
128
  switch (true) {
107
129
  case isClassComponent(element):
108
130
  instance = new element;
109
131
  instance.props = props;
110
132
  instance.children = children;
133
+ instance.Mounted = true;
111
134
  return instance.render(props);
112
135
  case typeof element === "function":
113
136
  instance = new Component;
114
- instance.render = element;
137
+ instance.render = element;
138
+ instance.Mounted = true;
115
139
  let firstEl = instance.render({key: instance.key, children: children, ...props}, children);
116
- instance.children = children;
117
- if (!firstEl) firstEl = {type: "div", props: {key: instance.key, ...props}, children: children};
140
+ instance.children = children;
141
+ if (!firstEl) firstEl = {type: "div", props: {key: instance.key, ...props}, children: children};
118
142
  firstEl.props = { key: instance.key, ...firstEl.props, ...props };
119
143
  return firstEl;
120
144
  default:
@@ -142,16 +166,16 @@ export function Switch({ children }) {
142
166
 
143
167
  /**
144
168
  * @description - Match component
145
- * @param param0
146
- * @returns
169
+ * @param param0
170
+ * @returns
147
171
  */
148
172
  export function Match({ when, children }) {
149
173
  return when ? children : { type: "div", props: {}, children: [] };
150
174
  }
151
175
  /**
152
176
  * @description - Manage state and forceupdate specific affected elements
153
- * @param key
154
- * @param initialState
177
+ * @param key
178
+ * @param initialState
155
179
  * @param persist - persist state on reload
156
180
  * @returns {()=> T, (newState: any, Element: string) => void, key}
157
181
  */
@@ -159,15 +183,20 @@ export const useState = <T>(initialState: T, persist: false) => {
159
183
  const setState = (newState: T) => {
160
184
  initialState = newState;
161
185
  }
162
- /**
186
+ /**
163
187
  * @returns {T}
164
188
  */
165
189
  const getVal = () => {
166
- return initialState as T
167
- }
190
+ return initialState as T;
191
+ }
168
192
 
169
193
  return [getVal, setState];
170
- }
194
+ }
195
+
196
+ if (!isServer) {
197
+ window.effects = []
198
+ }
199
+
171
200
 
172
201
  /**
173
202
  * @description - Create a new component
@@ -183,7 +212,7 @@ export const useState = <T>(initialState: T, persist: false) => {
183
212
  * </div>
184
213
  * )
185
214
  * }
186
- *
215
+ *
187
216
  * render(<App name="John" />, document.getElementById("root"));
188
217
  */
189
218
  export class Component {
@@ -194,6 +223,7 @@ export class Component {
194
223
  effect;
195
224
  key;
196
225
  effectCalls: any[]
226
+ eventRegistry: any
197
227
  prevState;
198
228
  constructor() {
199
229
  this.key = crypto.randomUUID();
@@ -205,31 +235,32 @@ export class Component {
205
235
  this.effectCalls = []
206
236
  this.errorThreshold = 1000
207
237
  this.maxIntervalCalls = 10
238
+ this.eventRegistry = new Map();
208
239
  }
209
- useEffect(callback, dependencies) {
240
+ useEffect(callback, dependencies = []) {
210
241
  const callbackId = callback.toString();
211
-
242
+
212
243
  if (!this.effectCalls.some(s => s.id === callbackId)) {
213
- this.effectCalls.push({ id: callbackId, count: 0, lastCall: Date.now() });
244
+ this.effectCalls.push({ id: callbackId, count: 0, lastCall: Date.now(), runOnce: dependencies.length === 0 });
214
245
  }
215
246
 
216
247
  const effectCall = this.effectCalls.find(s => s.id === callbackId);
217
-
248
+
218
249
  const executeCallback = () => {
219
250
  const now = Date.now();
220
251
  const timeSinceLastCall = now - effectCall.lastCall;
221
-
252
+
222
253
  if (timeSinceLastCall < this.errorThreshold) {
223
254
  effectCall.count += 1;
224
255
  if (effectCall.count > this.maxIntervalCalls) {
225
- throw new Error(`Woah wayy too many calls, ensure you are not overlooping you can change the maxThresholdCalls and errorThreshold depending on needs`)
256
+ throw new Error(`Woah wayy too many calls, ensure you are not overlooping you can change the maxThresholdCalls and errorThreshold depending on needs`)
226
257
  }
227
258
  } else {
228
- effectCall.count = 1;
259
+ effectCall.count = 1;
229
260
  }
230
-
261
+
231
262
  effectCall.lastCall = now;
232
-
263
+
233
264
  setTimeout(() => {
234
265
  try {
235
266
  callback();
@@ -238,10 +269,11 @@ export class Component {
238
269
  }
239
270
  }, 0);
240
271
  };
241
-
242
- if (dependencies.length === 0 && this.Mounted && this.effect.length === 0) {
272
+
273
+ if (dependencies.length === 0 && this.Mounted && this.effect.length === 0 && !effects.includes(callbackId)){
243
274
  executeCallback();
244
275
  this.effect.push(callbackId);
276
+ effects.push(callbackId);
245
277
  } else {
246
278
  // Check if dependencies have changed
247
279
  let dependenciesChanged = false;
@@ -255,7 +287,7 @@ export class Component {
255
287
  }
256
288
  }
257
289
  }
258
-
290
+
259
291
  if (dependenciesChanged) {
260
292
  this.effect = [...dependencies];
261
293
  executeCallback();
@@ -267,7 +299,7 @@ export class Component {
267
299
  return [defaultValue, () => {
268
300
  }];
269
301
  let value = sessionStorage.getItem("state_" + key) ? JSON.parse(sessionStorage.getItem("state_" + key)).value : defaultValue;
270
-
302
+
271
303
  if (typeof value === "string") {
272
304
  try {
273
305
  value = JSON.parse(value);
@@ -280,7 +312,10 @@ export class Component {
280
312
  !persist && sessionStorage.removeItem("state_" + key);
281
313
  });
282
314
  }
283
- const setValue = (newValue) => {
315
+ const setValue = (newValue) => {
316
+ if (typeof newValue === "function") {
317
+ newValue = newValue(value);
318
+ }
284
319
  sessionStorage.setItem("state_" + key, JSON.stringify({ value: newValue }));
285
320
  this.forceUpdate(this.key);
286
321
  };
@@ -295,9 +330,9 @@ export class Component {
295
330
  const dataKey = "_data" + url;
296
331
  let [loading, setLoading] = this.useState(loadingKey, true);
297
332
  let [error, setError] = this.useState(errorKey, null);
298
- let [data, setData] = this.useState(dataKey, null);
333
+ let [data, setData] = this.useState(dataKey, null);
299
334
  if (loading && !error && !data) {
300
- fetch(url, options).then((res) => res.json()).then((data2) => {
335
+ fetch(url, options).then((res) => res.json()).then((data2) => {
301
336
  setLoading(false);
302
337
  setData(data2);
303
338
  this.forceUpdate(this.key);
@@ -308,19 +343,23 @@ export class Component {
308
343
  }
309
344
  return [data, loading, error];
310
345
  }
311
- forceUpdate(key) {
346
+ forceUpdate(key) {
312
347
  let el = Array.from(document.querySelectorAll("*")).filter((el2) => {
313
348
  return el2.key === key;
314
349
  })[0];
315
- let newl = this.toElement();
350
+ let newl = this.toElement();
316
351
  if (newl.key !== key) {
317
352
  newl = Array.from(newl.children).filter((el2) => el2.key === key)[0];
318
- }
353
+ }
319
354
  this.Reconciler.update(el, newl);
320
355
  }
321
356
  Reconciler = {
322
357
  update: (oldElement, newElement) => {
323
- if(!oldElement || !newElement) return;
358
+ if (!oldElement || !newElement) return;
359
+
360
+ // Store and re-attach events before updating
361
+ const events = this.eventRegistry.get(oldElement) || [];
362
+
324
363
  if (this.Reconciler.shouldUpdate(oldElement, newElement)) {
325
364
  let part = this.Reconciler.shouldUpdate(oldElement, newElement, true);
326
365
  if (part === true) {
@@ -328,25 +367,36 @@ export class Component {
328
367
  oldElement.nodeValue = newElement.nodeValue;
329
368
  } else {
330
369
  oldElement.innerHTML = newElement.innerHTML;
331
- // swap attributes
370
+
371
+ // Swap attributes
332
372
  for (let i = 0; i < newElement.attributes.length; i++) {
333
373
  let attr = newElement.attributes[i];
334
374
  oldElement.setAttribute(attr.name, attr.value);
335
375
  }
376
+
377
+ // Re-attach events
378
+ for (const { event, handler } of events) {
379
+ oldElement.addEventListener(event, handler);
380
+ }
381
+
382
+ // Update children recursively
383
+ for (let i = 0; i < newElement.childNodes.length; i++) {
384
+ this.Reconciler.update(oldElement.childNodes[i], newElement.childNodes[i], true);
385
+ }
336
386
  }
337
387
  } else if (part.type === "attribute") {
338
388
  oldElement.setAttribute(part.name, part.value);
339
- }
389
+ }
340
390
  } else {
391
+ // Update children recursively
341
392
  for (let i = 0; i < newElement.childNodes.length; i++) {
342
393
  this.Reconciler.update(oldElement.childNodes[i], newElement.childNodes[i], true);
343
394
  }
344
395
  }
345
396
  },
346
- shouldUpdate(oldElement, newElement, isChild = false) {
347
- if (oldElement.nodeType !== newElement.nodeType) {
348
- // and both do not contain same text
349
397
 
398
+ shouldUpdate: (oldElement, newElement, isChild = false) => {
399
+ if (oldElement.nodeType !== newElement.nodeType) {
350
400
  return oldElement.innerHTML !== newElement.innerHTML ? { type: 'innerHTML' } : true;
351
401
  }
352
402
  if (oldElement.nodeType === 3 && newElement.nodeType === 3) {
@@ -356,25 +406,24 @@ export class Component {
356
406
  }
357
407
  if (oldElement.nodeName !== newElement.nodeName) {
358
408
  return true;
359
- }
409
+ }
360
410
  if (oldElement.childNodes.length !== newElement.childNodes.length) {
361
411
  return true;
362
412
  }
363
- if(newElement.attributes){
364
- for (let i = 0; i < newElement.attributes.length; i++) {
365
- let attr = newElement.attributes[i];
366
- if (oldElement.getAttribute(attr.name) !== attr.value) {
367
- return { type: "attribute", name: attr.name, value: attr.value };
413
+ if (newElement.attributes) {
414
+ for (let i = 0; i < newElement.attributes.length; i++) {
415
+ let attr = newElement.attributes[i];
416
+ if (oldElement.getAttribute(attr.name) !== attr.value) {
417
+ return { type: "attribute", name: attr.name, value: attr.value };
418
+ }
368
419
  }
369
420
  }
370
- }
371
-
372
-
373
421
  return false;
374
422
  }
375
423
  };
424
+
376
425
  parseToElement = (element) => {
377
- if (!element) return document.createElement("div");
426
+ if (!element) return document.createElement("div");
378
427
  // create either a element or svg element
379
428
  let svg = ["svg", "path", "circle", "rect", "line", "polyline", "polygon", "ellipse", "g"];
380
429
  let el = svg.includes(element.type) ? document.createElementNS("http://www.w3.org/2000/svg", element.type) : document.createElement(element.type);
@@ -399,12 +448,13 @@ export class Component {
399
448
  el.style[styleKey] = attributes[key][styleKey];
400
449
  }
401
450
  } catch (error) {
402
-
451
+
403
452
  }
404
453
  continue;
405
454
  }
406
455
  if (key.startsWith("on")) {
407
456
  el.addEventListener(key.substring(2).toLowerCase(), attributes[key]);
457
+ this.eventRegistry.set(el, [...(this.eventRegistry.get(el) || []), { event: key.substring(2).toLowerCase(), handler: attributes[key] }]);
408
458
  continue;
409
459
  }
410
460
  el.setAttribute(key, attributes[key]);
@@ -429,7 +479,7 @@ export class Component {
429
479
  } else if (typeof child === "object") {
430
480
  el.appendChild(this.parseToElement(child));
431
481
  } else {
432
- let span = document.createTextNode(child)
482
+ let span = document.createTextNode(child)
433
483
  el.appendChild(span);
434
484
  }
435
485
  }
@@ -444,7 +494,7 @@ export class Component {
444
494
  }
445
495
  toElement() {
446
496
  let children = this.render();
447
-
497
+
448
498
  let el = this.parseToElement(children);
449
499
  el.key = this.key;
450
500
  return el;
@@ -453,7 +503,7 @@ export class Component {
453
503
  return "";
454
504
  }
455
505
  }
456
-
506
+
457
507
  function memoizeClassComponent(Component: any) {
458
508
  let key = Component.toString();
459
509
  if (memoizes.has(key)) {
@@ -466,10 +516,10 @@ function memoizeClassComponent(Component: any) {
466
516
  }
467
517
  /**
468
518
  * @description - Render jsx Componenet to the DOM
469
- * @param element
470
- * @param container
519
+ * @param element
520
+ * @param container
471
521
  */
472
- export function render(element, container) {
522
+ export function render(element, container) {
473
523
  if (isClassComponent(element)) {
474
524
  const instance = new element;
475
525
  instance.Mounted = true;
@@ -481,7 +531,7 @@ export function render(element, container) {
481
531
  let memoizedInstance = memoizeClassComponent(Component);
482
532
  memoizedInstance.Mounted = true;
483
533
  memoizedInstance.render = element.bind(memoizedInstance);
484
- let el = memoizedInstance.toElement();
534
+ let el = memoizedInstance.toElement();
485
535
  el.key = memoizedInstance.key;
486
536
  container.innerHTML = "";
487
537
  container.replaceWith(el);
package/main.js CHANGED
@@ -20,13 +20,13 @@ if (!fs.existsSync(process.cwd() + '/src')) {
20
20
  }
21
21
  if (!fs.existsSync(process.cwd() + '/vader.config.ts')) {
22
22
  fs.writeFileSync(process.cwd() + '/vader.config.ts',
23
- `import defineConfig from 'vaderjs/config'
24
- export default defineConfig({
23
+ `import defineConfig from 'vaderjs/config'
24
+ export default defineConfig({
25
25
  port: 8080,
26
26
  host_provider: 'apache'
27
27
  })`)
28
28
  }
29
- const config = require(process.cwd() + '/vader.config.ts').default
29
+ var config = require(process.cwd() + '/vader.config.ts').default
30
30
  const mode = args.includes('dev') ? 'development' : args.includes('prod') || args.includes('build') ? 'production' : args.includes('init') ? 'init' : args.includes('serve') ? 'serve' : null;
31
31
  if (!mode) {
32
32
  console.log(`
@@ -44,11 +44,10 @@ if (mode === 'init') {
44
44
  console.error('App directory already exists: just run `bun vaderjs dev` to start the development server')
45
45
  process.exit(1)
46
46
  }
47
- fs.mkdirSync(process.cwd() + '/app')
48
- fs.copyFileSync(path.join(process.cwd(), "/node_modules/vaderjs/example/counter/index.jsx"), path.join(process.cwd(), "/app/index.jsx"))
49
-
47
+ let counterText = await Bun.file(path.join(process.cwd(), "/node_modules/vaderjs/examples/counter/index.jsx")).text()
48
+ await Bun.write(path.join(process.cwd(), "/app/index.jsx"), counterText)
50
49
  console.log('Initialized new vaderjs project: run `bun vaderjs dev` to start the development server')
51
- procss.exit(1)
50
+ process.exit(0)
52
51
  }
53
52
 
54
53
  console.log(
@@ -118,7 +117,7 @@ const handleReplacements = (code) => {
118
117
  try {
119
118
  let isSmallColon = line.includes("'")
120
119
  let url = isSmallColon ? line.split("'")[1] : line.split('"')[1]
121
- // start from "/" not "/app"
120
+ // start from "/" not "/app"
122
121
  // remvoe all ./ and ../
123
122
  url = url.replaceAll('./', '/').replaceAll('../', '/')
124
123
 
@@ -130,7 +129,7 @@ const handleReplacements = (code) => {
130
129
  bindes.push(`
131
130
  <style>
132
131
  ${fs.readFileSync(p, 'utf-8')}
133
- </style>
132
+ </style>
134
133
  `)
135
134
  }
136
135
  } catch (error) {
@@ -179,11 +178,13 @@ async function generateApp() {
179
178
  globalThis.isBuilding = true;
180
179
  console.log(ansiColors.green('Building...'))
181
180
  console.log(`Starting build at ${new Date().toLocaleTimeString()}`)
182
- for (let fn of fnmap) {
183
- await fn.fn(vader)
184
- fnmap = fnmap.filter(v => v.code !== fn.code)
181
+ let plugins = config.plugins || []
182
+ for (let plugin of plugins) {
183
+ if (plugin.onBuildStart) {
184
+ await plugin.onBuildStart(vader)
185
+ }
185
186
  }
186
- // remove files from dist
187
+
187
188
  if (mode === 'development') {
188
189
  fs.rmdirSync(process.cwd() + '/dist', { recursive: true })
189
190
  } else {
@@ -206,7 +207,7 @@ async function generateApp() {
206
207
  r = r.replace('.jsx', '.js').replace('.tsx', '.js')
207
208
  fs.mkdirSync(path.dirname(process.cwd() + '/dist/' + r), { recursive: true })
208
209
  fs.writeFileSync(process.cwd() + '/dist/' + path.dirname(r) + '/' + path.basename(r), `
209
- let route = window.location.pathname.split('/').filter(v => v !== '')
210
+ let route = window.location.pathname.split('/').filter(v => v !== '')
210
211
  let params = {
211
212
  ${Object.keys(routes.match(route).params || {}).length > 0 ? Object.keys(routes.match(route).params || {}).map(p => {
212
213
  return `${p}: route[${Object.keys(routes.match(route).params).indexOf(p) + Object.keys(routes.match(route).params).length}]`
@@ -299,6 +300,7 @@ async function generateApp() {
299
300
  function handleFiles() {
300
301
  return new Promise(async (resolve, reject) => {
301
302
  try {
303
+ console.log(Glob)
302
304
  let glob = new Glob('public/**/*')
303
305
  for await (var i of glob.scan()) {
304
306
  let file = i
@@ -315,6 +317,7 @@ function handleFiles() {
315
317
  // turn jsx to js
316
318
  if (file.includes('.jsx') || file.includes('.tsx')) {
317
319
  let code = await Bun.file(file).text()
320
+
318
321
  code = handleReplacements(code)
319
322
 
320
323
  file = file.replace('.jsx', '.js').replace('.tsx', '.js')
@@ -327,6 +330,7 @@ function handleFiles() {
327
330
  ENTRYPOINT: path.join(process.cwd() + '/dist/' + file.replace('.jsx', '.js').replace('.tsx', '.js')),
328
331
  ROOT: process.cwd() + '/app/',
329
332
  OUT: path.dirname(file),
333
+ shouldReplace: true,
330
334
  file: process.cwd() + '/dist/' + file.replace('.jsx', '.js').replace('.tsx', '.js'),
331
335
  DEV: mode === 'development',
332
336
  size: code.length / 1024,
@@ -393,7 +397,20 @@ if (mode === 'development') {
393
397
 
394
398
  // Function to handle file changes with debounce
395
399
  const handleFileChangeDebounced = async (change, file) => {
396
- if (file.endsWith('.tsx') || file.endsWith('.jsx') || file.endsWith('.css') || file.endsWith('.ts')) {
400
+ if (file.endsWith('.tsx') || file.endsWith('.jsx') || file.endsWith('.css') || file.endsWith('.ts')
401
+ && !file.includes('node_module')
402
+ ) {
403
+ // delete files cache
404
+ if (file.endsWith('vader.config.ts')){
405
+ delete require.cache[require.resolve(process.cwd() + '/vader.config.ts')]
406
+
407
+ config = require(process.cwd() + '/vader.config.ts').default
408
+ port = config.port;
409
+ host_provider = config.host_provider
410
+ host = config.host
411
+
412
+ globalThis.config = config
413
+ }
397
414
  if (file.includes('dist')) return
398
415
  clearTimeout(debounceTimeout);
399
416
  debounceTimeout = setTimeout(async () => {
@@ -418,7 +435,7 @@ if (mode === 'development') {
418
435
  }
419
436
  };
420
437
 
421
- // Event listeners with debounced handling
438
+ // Event listeners with debounced handling
422
439
  watcher.on('change', handleFileChangeDebounced);
423
440
 
424
441
  }
@@ -491,8 +508,8 @@ if (mode == 'development' || mode == 'serve') {
491
508
  if(e.data === 'reload'){
492
509
  console.log('Reloading to display changes from server')
493
510
  window.location.reload()
494
- }
495
- }
511
+ }
512
+ }
496
513
  </script>
497
514
  `, {
498
515
  headers: {
@@ -511,4 +528,4 @@ if (mode == 'development' || mode == 'serve') {
511
528
  })
512
529
 
513
530
  console.log(ansiColors.green('Server started at http://localhost:' + port || 8080))
514
- }
531
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vaderjs",
3
- "version": "1.6.6",
3
+ "version": "1.6.8",
4
4
  "description": "A simple and powerful JavaScript library for building modern web applications.",
5
5
  "bin": {
6
6
  "vaderjs": "./main.js"
@@ -13,7 +13,15 @@ function checkIfTailwindInstalled() {
13
13
 
14
14
  function initTailwind() {
15
15
  const tailwindConfig = path.resolve(process.cwd(), 'tailwind.config.js')
16
+ const postcssConfig = path.resolve(process.cwd(), 'postcss.config.js')
16
17
  if (!fs.existsSync(tailwindConfig)) {
18
+ fs.writeFileSync(postcssConfig, `module.exports = {
19
+ plugins: {
20
+ tailwindcss: {},
21
+ autoprefixer: {},
22
+ }
23
+ }`)
24
+
17
25
  fs.writeFileSync(tailwindConfig, `/** @type {import('tailwindcss').Config} */
18
26
  module.exports = {
19
27
  content: ['./src/**/*.{html,js,jsx,ts,tsx}', './app/**/*.{html,js,jsx,ts,tsx}'],
@@ -32,19 +40,25 @@ export default {
32
40
  name: 'tailwindcss',
33
41
  description: 'TailwindCSS plugin for Vader.js',
34
42
  version: '0.0.1',
35
- onBuildFinish: async (vader) => {
43
+ onBuildStart: async (vader) => {
36
44
  if (!checkIfTailwindInstalled()) {
37
- console.error('TailwindCSS is not installed. Please install it using `bun install tailwindcss`')
45
+ console.error('TailwindCSS is not installed. Please install it using `bun install tailwindcss postcss-cli autoprefixer`')
38
46
  process.exit(1)
39
47
  }else{
40
48
  initTailwind()
49
+
41
50
  vader.onFileChange('tailwind.config.js', async () => {
42
51
  console.log('Rebuilding TailwindCSS...')
43
- await vader.runCommand(['bun', 'run', 'tailwindcss', 'build', '-o', 'public/styles.css'])
52
+ await vader.runCommand(['bun', 'run', 'postcss', './public/styles.css', '-o', 'dist/public/tailwind.css'])
44
53
  console.log('TailwindCSS rebuilt successfully!')
45
54
  })
46
- vader.runCommand(['bun', 'run', 'tailwindcss', 'build', '-o', 'public/styles.css'])
47
- }
55
+ await vader.runCommand(['bun', 'run', 'postcss', './public/styles.css', '-o', 'dist/public/tailwind.css'])
56
+ vader.injectHTML(`<style>${fs.readFileSync(path.resolve(process.cwd(), 'dist/public/tailwind.css'))}</style>`)
57
+ }
58
+
59
+ },
60
+ onBuildFinish: async (vader) => {
61
+ console.log('TailwindCSS plugin finished building')
48
62
  },
49
63
 
50
64
  }
@@ -40,18 +40,19 @@ export default {
40
40
  name: 'tailwindcss',
41
41
  description: 'TailwindCSS plugin for Vader.js',
42
42
  version: '0.0.1',
43
+ onBuildStart: async (vader) => {
44
+ vader.injectHTML(`<link rel="stylesheet" href="/public/tailwind.css">`)
45
+ },
43
46
  onBuildFinish: async (vader) => {
44
47
  if (!checkIfTailwindInstalled()) {
45
48
  console.error('TailwindCSS is not installed. Please install it using `bun install tailwindcss postcss-cli autoprefixer`')
46
49
  process.exit(1)
47
50
  }else{
48
51
  initTailwind()
49
- vader.onBuildStart(() => {
50
- vader.injectHTML(`<link rel="stylesheet" href="/public/tailwind.css">`)
51
- })
52
+
52
53
  vader.onFileChange('tailwind.config.js', async () => {
53
54
  console.log('Rebuilding TailwindCSS...')
54
- await vader.runCommand(['bun', 'run', 'postcss', 'public/styles.css', '-o', 'dist/public/tailwind.css'])
55
+ await vader.runCommand(['bun', 'run', 'tailwindcss', 'build', '-o', 'public/styles.css'])
55
56
  console.log('TailwindCSS rebuilt successfully!')
56
57
  })
57
58
  vader.runCommand(['bun', 'run', 'postcss', 'public/styles.css', '-o', 'dist/public/tailwind.css'])