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 +125 -75
- package/main.js +36 -19
- package/package.json +1 -1
- package/plugins/tailwind.ts +19 -5
- package/plugins/tailwindcss/index.ts +5 -4
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:
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
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
|
-
|
|
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
|
-
|
|
48
|
-
|
|
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
|
-
|
|
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
|
-
|
|
183
|
-
|
|
184
|
-
|
|
181
|
+
let plugins = config.plugins || []
|
|
182
|
+
for (let plugin of plugins) {
|
|
183
|
+
if (plugin.onBuildStart) {
|
|
184
|
+
await plugin.onBuildStart(vader)
|
|
185
|
+
}
|
|
185
186
|
}
|
|
186
|
-
|
|
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
package/plugins/tailwind.ts
CHANGED
|
@@ -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
|
-
|
|
43
|
+
onBuildStart: async (vader) => {
|
|
36
44
|
if (!checkIfTailwindInstalled()) {
|
|
37
|
-
console.error('TailwindCSS is not installed. Please install it using `bun install
|
|
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', '
|
|
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', '
|
|
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
|
-
|
|
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', '
|
|
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'])
|