vaderjs 1.4.6 → 1.4.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/README.MD +1 -1
- package/bundler/index.js +97 -0
- package/document/index.ts +1 -1
- package/index.ts +128 -98
- package/main.js +184 -234
- package/package.json +4 -1
package/README.MD
CHANGED
package/bundler/index.js
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Component,
|
|
3
|
+
e,
|
|
4
|
+
useState,
|
|
5
|
+
useEffect,
|
|
6
|
+
useFetch,
|
|
7
|
+
useAsyncState,
|
|
8
|
+
Fragment,
|
|
9
|
+
} from "vaderjs";
|
|
10
|
+
import { document } from "vaderjs/document";
|
|
11
|
+
import fs from "fs";
|
|
12
|
+
import ansiColors from "ansi-colors";
|
|
13
|
+
let path2 = require("path");
|
|
14
|
+
globalThis.Fragment = Fragment;
|
|
15
|
+
globalThis.window = {
|
|
16
|
+
location: {
|
|
17
|
+
hash: "",
|
|
18
|
+
host: "",
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
globalThis.Component = Component;
|
|
22
|
+
globalThis.e = e;
|
|
23
|
+
globalThis.useFetch = useFetch;
|
|
24
|
+
globalThis.useEffect = useEffect;
|
|
25
|
+
globalThis.useAsyncState = useAsyncState;
|
|
26
|
+
globalThis.useState = useState;
|
|
27
|
+
globalThis.genKey = () => {
|
|
28
|
+
return crypto.randomUUID();
|
|
29
|
+
};
|
|
30
|
+
globalThis.document = {
|
|
31
|
+
createElement: (tag) => { },
|
|
32
|
+
getElementById: (id) => { },
|
|
33
|
+
querySelector: (query) => { },
|
|
34
|
+
};
|
|
35
|
+
await Bun.build({
|
|
36
|
+
entrypoints: [process.env.ENTRYPOINT],
|
|
37
|
+
minify: true,
|
|
38
|
+
root: process.cwd() + "/dist/",
|
|
39
|
+
outdir: process.cwd() + "/dist/",
|
|
40
|
+
format: "esm",
|
|
41
|
+
...(process.env.DEV ? { sourcemap: "inline" } : {}),
|
|
42
|
+
});
|
|
43
|
+
let isClass = function (element) {
|
|
44
|
+
return element.toString().startsWith("class");
|
|
45
|
+
};
|
|
46
|
+
const generatePage = async (
|
|
47
|
+
data = { path: process.env.INPUT, route: process.env.OUT }
|
|
48
|
+
) => {
|
|
49
|
+
const { path, route } = data;
|
|
50
|
+
if (path.includes("root.js")) return;
|
|
51
|
+
let html = await import(path).then((m) => m.default);
|
|
52
|
+
let { head } = await import(path).then((m) => m);
|
|
53
|
+
let isFunction = false;
|
|
54
|
+
globalThis.isServer = true;
|
|
55
|
+
if (isClass(html)) {
|
|
56
|
+
html = new html();
|
|
57
|
+
html.Mounted = true;
|
|
58
|
+
html = html.render();
|
|
59
|
+
} else {
|
|
60
|
+
isFunction = true;
|
|
61
|
+
let instance = new Component();
|
|
62
|
+
html = html.bind(instance);
|
|
63
|
+
instance.render = html;
|
|
64
|
+
html = instance.render();
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
let h = document(html);
|
|
68
|
+
if (!fs.existsSync(process.cwd() + "/dist" + path2.dirname(route))) {
|
|
69
|
+
fs.mkdirSync(process.cwd() + "/dist" + path2.dirname(route), {
|
|
70
|
+
recursive: true,
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
let headHtml = "";
|
|
74
|
+
if (head) {
|
|
75
|
+
headHtml = document(head());
|
|
76
|
+
}
|
|
77
|
+
Bun.write(
|
|
78
|
+
process.cwd() + "/dist/" + route + "/index.html",
|
|
79
|
+
`<!DOCTYPE html><head>${headHtml}</head>${h}
|
|
80
|
+
<script type="module">
|
|
81
|
+
import c from '${process.env.filePath}'
|
|
82
|
+
import {render} from '/src/vader/index.js'
|
|
83
|
+
render(c, document.body.firstChild)
|
|
84
|
+
</script>
|
|
85
|
+
`
|
|
86
|
+
);
|
|
87
|
+
|
|
88
|
+
console.log(
|
|
89
|
+
ansiColors.blue(
|
|
90
|
+
`${process.env.filePath.replace(".js", ".jsx")} - ${parseInt(
|
|
91
|
+
process.env.size
|
|
92
|
+
).toFixed(2)}kb`
|
|
93
|
+
)
|
|
94
|
+
);
|
|
95
|
+
process.exit(0);
|
|
96
|
+
};
|
|
97
|
+
generatePage({ path: process.env.INPUT, route: process.env.OUT });
|
package/document/index.ts
CHANGED
package/index.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
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
|
|
@@ -14,9 +14,12 @@ declare global {
|
|
|
14
14
|
state: any;
|
|
15
15
|
}
|
|
16
16
|
const genKey: any;
|
|
17
|
+
/**
|
|
18
|
+
* @description Allows you to check if current session is server or client
|
|
19
|
+
*/
|
|
17
20
|
let isServer: boolean;
|
|
18
21
|
/**
|
|
19
|
-
* @description - The params object is used to store the
|
|
22
|
+
* @description - The params object is used to store the parameters of the current URL
|
|
20
23
|
* @example
|
|
21
24
|
* // URL: https://example.com?name=John
|
|
22
25
|
* console.log(params.name) // John
|
|
@@ -27,6 +30,7 @@ declare global {
|
|
|
27
30
|
* console.log(params.age) // 20
|
|
28
31
|
*/
|
|
29
32
|
let params: { [key: string]: string };
|
|
33
|
+
let localStorage : []
|
|
30
34
|
}
|
|
31
35
|
//@ts-ignore
|
|
32
36
|
globalThis.isServer = typeof window === "undefined";
|
|
@@ -39,6 +43,7 @@ globalThis.params = {
|
|
|
39
43
|
},
|
|
40
44
|
};
|
|
41
45
|
|
|
46
|
+
|
|
42
47
|
|
|
43
48
|
/**
|
|
44
49
|
* @description useFetch allows you to make POST - GET - PUT - DELETE requests then returns the data, loading state and error
|
|
@@ -51,12 +56,11 @@ export const useFetch = (url: string, options: any) => {
|
|
|
51
56
|
};
|
|
52
57
|
|
|
53
58
|
/**
|
|
54
|
-
* @description
|
|
55
|
-
* @param key
|
|
59
|
+
* @description - Handle asyncronous promises and return the data or error;
|
|
56
60
|
* @param promise
|
|
57
61
|
* @returns
|
|
58
62
|
*/
|
|
59
|
-
export const useAsyncState = (
|
|
63
|
+
export const useAsyncState = (promise: Promise<any>) => {
|
|
60
64
|
return [null, () => {}];
|
|
61
65
|
}
|
|
62
66
|
export const useEffect = (callback:any, dependencies: any[]) => {
|
|
@@ -64,19 +68,18 @@ export const useEffect = (callback:any, dependencies: any[]) => {
|
|
|
64
68
|
if (dependencies.length === 0) {
|
|
65
69
|
callback();
|
|
66
70
|
}
|
|
67
|
-
}
|
|
71
|
+
}
|
|
68
72
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
+
export const Fragment = (props: any, children: any) => {
|
|
74
|
+
return {
|
|
75
|
+
type: "div",
|
|
76
|
+
props: props || {},
|
|
77
|
+
children: children || [],
|
|
73
78
|
}
|
|
74
|
-
let instance = new Component();
|
|
75
|
-
memoizes.set(key, instance);
|
|
76
|
-
return instance;
|
|
77
|
-
|
|
78
79
|
}
|
|
79
80
|
|
|
81
|
+
globalThis.Fragment = Fragment;
|
|
82
|
+
|
|
80
83
|
/**
|
|
81
84
|
* @description - Create a new element
|
|
82
85
|
* @param element
|
|
@@ -85,30 +88,52 @@ function memoizeComponent(Component: any) {
|
|
|
85
88
|
* @returns
|
|
86
89
|
*/
|
|
87
90
|
export const e = (element: any, props: any, ...children: any[]) => {
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
91
|
+
let instance;
|
|
92
|
+
switch (true){
|
|
93
|
+
case isClassComponent(element):
|
|
94
|
+
instance = new element();
|
|
95
|
+
instance.props = props;
|
|
96
|
+
instance.children = children;
|
|
97
|
+
return instance.render();
|
|
98
|
+
case typeof element === "function":
|
|
99
|
+
instance = new Component();
|
|
100
|
+
instance.render = element;
|
|
101
|
+
return instance.render();
|
|
102
|
+
default:
|
|
103
|
+
return { type: element, props: props || {}, children: children || [] };
|
|
104
|
+
}
|
|
94
105
|
};
|
|
95
106
|
|
|
96
107
|
/**
|
|
97
|
-
* @description -
|
|
108
|
+
* @description - Manage state and forceupdate specific affected elements
|
|
98
109
|
* @param key
|
|
99
110
|
* @param initialState
|
|
100
111
|
* @returns {state, (newState: any, Element: string) => void, key}
|
|
101
112
|
*/
|
|
102
113
|
export const useState = <T>(initialState: T) => {
|
|
103
|
-
const setState = (newState: T
|
|
114
|
+
const setState = (newState: T) => {
|
|
104
115
|
initialState = newState;
|
|
105
116
|
}
|
|
106
117
|
return [initialState, setState];
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* @description - Create a new component
|
|
122
|
+
* @param element
|
|
123
|
+
* @param props
|
|
124
|
+
* @param children
|
|
125
|
+
* @returns
|
|
126
|
+
* @example
|
|
127
|
+
* const App = (props) => {
|
|
128
|
+
* return (
|
|
129
|
+
* <div>
|
|
130
|
+
* <h1>Hello, {props.name}</h1>
|
|
131
|
+
* </div>
|
|
132
|
+
* )
|
|
133
|
+
* }
|
|
134
|
+
*
|
|
135
|
+
* render(<App name="John" />, document.getElementById("root"));
|
|
136
|
+
*/
|
|
112
137
|
export class Component {
|
|
113
138
|
props: any;
|
|
114
139
|
state: any;
|
|
@@ -120,21 +145,12 @@ export class Component {
|
|
|
120
145
|
constructor() {
|
|
121
146
|
this.key = Math.random().toString(36).substring(7);
|
|
122
147
|
this.props = {};
|
|
123
|
-
|
|
124
|
-
if(!isServer){
|
|
125
|
-
window.state[this.key] = {};
|
|
126
|
-
this.state = window.state[this.key];
|
|
127
|
-
}else{
|
|
128
|
-
this.state = {};
|
|
129
|
-
}
|
|
148
|
+
this.state = {};
|
|
130
149
|
this.effect = [];
|
|
131
150
|
this.Mounted = false;
|
|
132
|
-
this.element = null;
|
|
133
|
-
}
|
|
134
|
-
setState(newState: any, Element: string) {
|
|
135
|
-
globalThis.window.state[this.key] = { ...this.state, ...newState };
|
|
136
|
-
this.forceUpdate(Element);
|
|
151
|
+
this.element = null;
|
|
137
152
|
}
|
|
153
|
+
|
|
138
154
|
|
|
139
155
|
useEffect(callback: any, dependencies: any[]) {
|
|
140
156
|
if (dependencies.length === 0 && this.Mounted && this.effect.length === 0) {
|
|
@@ -149,35 +165,41 @@ export class Component {
|
|
|
149
165
|
}
|
|
150
166
|
}
|
|
151
167
|
}
|
|
152
|
-
useState
|
|
153
|
-
let value = sessionStorage.getItem("state_" + key)
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
168
|
+
useState<T>(key: string, defaultValue: T) {
|
|
169
|
+
let value = sessionStorage.getItem("state_" + key) ? JSON.parse(sessionStorage.getItem("state_" + key)).value : defaultValue;
|
|
170
|
+
|
|
171
|
+
// Parse value if it's a stringified object or number
|
|
172
|
+
if (typeof value === 'string') {
|
|
173
|
+
try {
|
|
174
|
+
value = JSON.parse(value);
|
|
175
|
+
} catch (error) {
|
|
176
|
+
// Not a valid JSON, keep it as is
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// Add listener for unload event to save state
|
|
181
|
+
if (!window['listener' + key]) {
|
|
182
|
+
window['listener' + key] = true;
|
|
183
|
+
window.addEventListener('beforeunload', () => {
|
|
184
|
+
sessionStorage.removeItem('state_' + key)
|
|
185
|
+
});
|
|
164
186
|
}
|
|
165
|
-
|
|
187
|
+
|
|
188
|
+
const setValue = (newValue: T) => {
|
|
189
|
+
value = newValue;
|
|
190
|
+
sessionStorage.setItem("state_" + key, JSON.stringify({ type: typeof newValue, value: newValue }));
|
|
191
|
+
this.forceUpdate(this.key)
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
return [value as T, setValue];
|
|
166
195
|
}
|
|
167
196
|
|
|
168
197
|
|
|
169
198
|
|
|
170
|
-
useFetch(url, options) {
|
|
171
|
-
const { key } = options;
|
|
172
|
-
if (!key) {
|
|
173
|
-
throw new Error(`You must supply a key for the affected element in the options object`);
|
|
174
|
-
}
|
|
175
|
-
|
|
199
|
+
useFetch(url: string, options: any) {
|
|
176
200
|
const loadingKey = "loading_" + url;
|
|
177
201
|
const errorKey = "error" + url;
|
|
178
|
-
const dataKey = "_data" + url;
|
|
179
|
-
|
|
180
|
-
// Initialize loading to false if loadingKey doesn't exist in state
|
|
202
|
+
const dataKey = "_data" + url;
|
|
181
203
|
let [loading, setLoading] = this.useState(loadingKey, false);
|
|
182
204
|
let [error, setError] = this.useState(errorKey, null);
|
|
183
205
|
let [data, setData] = this.useState(dataKey, null);
|
|
@@ -189,13 +211,13 @@ export class Component {
|
|
|
189
211
|
.then((res) => res.json())
|
|
190
212
|
.then((data) => {
|
|
191
213
|
//@ts-ignore
|
|
192
|
-
setLoading(false
|
|
193
|
-
setData(data
|
|
194
|
-
this.forceUpdate(key);
|
|
214
|
+
setLoading(false);
|
|
215
|
+
setData(data);
|
|
216
|
+
this.forceUpdate(this.key);
|
|
195
217
|
})
|
|
196
218
|
.catch((err) => {
|
|
197
|
-
setError(err
|
|
198
|
-
this.forceUpdate(key);
|
|
219
|
+
setError(err);
|
|
220
|
+
this.forceUpdate(this.key);
|
|
199
221
|
});
|
|
200
222
|
}
|
|
201
223
|
|
|
@@ -206,38 +228,39 @@ export class Component {
|
|
|
206
228
|
forceUpdate(key) {
|
|
207
229
|
//@ts-ignore
|
|
208
230
|
let el = Array.from(document.querySelectorAll("*")).filter((el2: any) =>{ return el2.key === key})[0];
|
|
209
|
-
let newl = this.
|
|
231
|
+
let newl = this.toElement();
|
|
210
232
|
if(newl.key !== key){
|
|
211
233
|
//@ts-ignore
|
|
212
234
|
newl = Array.from(newl.children).filter((el2) => el2.key === key)[0];
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
el.replaceWith(newl);
|
|
216
|
-
}
|
|
235
|
+
}
|
|
236
|
+
this.Reconciler.update(el, newl);
|
|
217
237
|
}
|
|
218
238
|
Reconciler = {
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
let
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
if (attribute.name === "key") {
|
|
228
|
-
continue;
|
|
229
|
-
}
|
|
230
|
-
if (attribute.name === "class") {
|
|
231
|
-
if (attribute.value !== newElement.className) {
|
|
232
|
-
return true;
|
|
233
|
-
}
|
|
234
|
-
continue;
|
|
235
|
-
}
|
|
236
|
-
if (attribute.value !== newAttributes[attribute.name]) {
|
|
237
|
-
return true;
|
|
239
|
+
update: (oldElement, newElement) => {
|
|
240
|
+
if(!oldElement || !newElement) return;
|
|
241
|
+
if (this.Reconciler.shouldUpdate(oldElement, newElement) && oldElement.tagName == newElement.tagName){
|
|
242
|
+
oldElement.replaceWith(newElement)
|
|
243
|
+
} else {
|
|
244
|
+
let children = oldElement.childNodes;
|
|
245
|
+
for (let i = 0; i < children.length; i++) {
|
|
246
|
+
this.Reconciler.update(children[i], newElement.childNodes[i]);
|
|
238
247
|
}
|
|
239
248
|
}
|
|
240
|
-
|
|
249
|
+
},
|
|
250
|
+
shouldUpdate(oldElement, newElement) {
|
|
251
|
+
if (oldElement.nodeType !== newElement.nodeType) {
|
|
252
|
+
return true;
|
|
253
|
+
}
|
|
254
|
+
if (oldElement.nodeType === 3 && newElement.nodeType === 3) {
|
|
255
|
+
return oldElement.textContent !== newElement.textContent;
|
|
256
|
+
}
|
|
257
|
+
if (oldElement.nodeName !== newElement.nodeName) {
|
|
258
|
+
return true;
|
|
259
|
+
}
|
|
260
|
+
if (oldElement.childNodes.length !== newElement.childNodes.length) {
|
|
261
|
+
return true;
|
|
262
|
+
}
|
|
263
|
+
return false;
|
|
241
264
|
}
|
|
242
265
|
};
|
|
243
266
|
|
|
@@ -301,7 +324,12 @@ export class Component {
|
|
|
301
324
|
}
|
|
302
325
|
toElement() {
|
|
303
326
|
let children = this.render();
|
|
327
|
+
//@ts-ignore
|
|
328
|
+
if(children.props['key']){
|
|
329
|
+
this.key = children.props['key'];
|
|
330
|
+
}
|
|
304
331
|
let el = this.parseToElement(children);
|
|
332
|
+
el.key = this.key;
|
|
305
333
|
return el;
|
|
306
334
|
}
|
|
307
335
|
render() {
|
|
@@ -321,8 +349,12 @@ function memoizeClassComponent(Component: any) {
|
|
|
321
349
|
return instance;
|
|
322
350
|
|
|
323
351
|
}
|
|
324
|
-
|
|
325
|
-
|
|
352
|
+
/**
|
|
353
|
+
* @description - Render jsx Componenet to the DOM
|
|
354
|
+
* @param element
|
|
355
|
+
* @param container
|
|
356
|
+
*/
|
|
357
|
+
export function render(element: any, container: HTMLElement) {
|
|
326
358
|
if (isClassComponent(element)) {
|
|
327
359
|
const instance = new element();
|
|
328
360
|
instance.Mounted = true;
|
|
@@ -330,15 +362,13 @@ export function render(element: any, container) {
|
|
|
330
362
|
instance.element = el;
|
|
331
363
|
container.innerHTML = "";
|
|
332
364
|
container.replaceWith(el);
|
|
333
|
-
} else {
|
|
334
|
-
// memoizeComponent(element);
|
|
365
|
+
} else {
|
|
335
366
|
let memoizedInstance = memoizeClassComponent(Component);
|
|
336
367
|
memoizedInstance.Mounted = true;
|
|
337
368
|
memoizedInstance.render = element.bind(memoizedInstance);
|
|
338
|
-
let el = memoizedInstance.toElement();
|
|
369
|
+
let el = memoizedInstance.toElement();
|
|
339
370
|
container.innerHTML = "";
|
|
340
371
|
container.replaceWith(el);
|
|
341
372
|
|
|
342
373
|
}
|
|
343
|
-
}
|
|
344
|
-
|
|
374
|
+
}
|
package/main.js
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
2
|
|
|
3
|
+
import ansiColors from 'ansi-colors'
|
|
3
4
|
import { Glob } from 'bun'
|
|
4
5
|
const args = Bun.argv.slice(2)
|
|
5
6
|
import fs from 'fs'
|
|
6
|
-
import path from 'path'
|
|
7
|
-
|
|
7
|
+
import path from 'path'
|
|
8
8
|
if (!fs.existsSync(process.cwd() + '/app')) {
|
|
9
9
|
console.error(`App directory not found in ${process.cwd()}/app`)
|
|
10
10
|
process.exit(1)
|
|
11
11
|
}
|
|
12
12
|
if (!fs.existsSync(process.cwd() + '/public')) {
|
|
13
13
|
fs.mkdirSync(process.cwd() + '/public')
|
|
14
|
-
}
|
|
15
|
-
const mode = args.includes('dev') ? 'development' :
|
|
16
|
-
if(!mode){
|
|
14
|
+
}
|
|
15
|
+
const mode = args.includes('dev') ? 'development' : args.includes('prod') || args.includes('build') ? 'production' : null
|
|
16
|
+
if (!mode) {
|
|
17
17
|
console.log(`
|
|
18
18
|
Usage:
|
|
19
19
|
bun vaderjs dev - Start development server output in dist/
|
|
@@ -22,15 +22,26 @@ if(!mode){
|
|
|
22
22
|
process.exit(1)
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
+
console.log(
|
|
26
|
+
`VaderJS - v${require(process.cwd() + '/node_modules/vaderjs/package.json').version} 🚀
|
|
27
|
+
Mode: ${mode}
|
|
28
|
+
SSR: ${require(process.cwd() + '/config').default.ssr ? 'Enabled' : 'Disabled'}
|
|
29
|
+
PORT: ${require(process.cwd() + '/config').default.port || 8080}
|
|
30
|
+
`
|
|
31
|
+
)
|
|
32
|
+
|
|
25
33
|
let start = Date.now()
|
|
26
|
-
console.log(`Starting build at ${new Date().toLocaleTimeString()}`)
|
|
34
|
+
console.log(`Starting build at ${new Date().toLocaleTimeString()}`)
|
|
27
35
|
let { port, host, host_provider } = require(process.cwd() + '/config').default
|
|
28
|
-
|
|
36
|
+
if (host_provider === 'apache' && mode === 'development') {
|
|
37
|
+
console.warn('Note: SSR will not work with Apache')
|
|
38
|
+
}
|
|
29
39
|
if (!fs.existsSync(process.cwd() + '/jsconfig.json')) {
|
|
30
40
|
let json = {
|
|
31
41
|
"compilerOptions": {
|
|
32
42
|
"jsx": "react",
|
|
33
43
|
"jsxFactory": "e",
|
|
44
|
+
"jsxFragmentFactory": "Fragment",
|
|
34
45
|
}
|
|
35
46
|
}
|
|
36
47
|
await Bun.write(process.cwd() + '/jsconfig.json', JSON.stringify(json, null, 4))
|
|
@@ -43,27 +54,27 @@ const handleReplacements = (code, file) => {
|
|
|
43
54
|
let newLines = []
|
|
44
55
|
for (let line of lines) {
|
|
45
56
|
let hasImport = line.includes('import')
|
|
46
|
-
if(hasImport && line.includes('.jsx')){
|
|
57
|
+
if (hasImport && line.includes('.jsx')) {
|
|
47
58
|
line = line.replace('.jsx', '.js')
|
|
48
59
|
}
|
|
49
|
-
if(hasImport && line.includes('.css')){
|
|
50
|
-
|
|
60
|
+
if (hasImport && line.includes('.css')) {
|
|
61
|
+
try {
|
|
51
62
|
let url = path.join('/' + line.split("'")[1])
|
|
52
63
|
let css = fs.readFileSync(process.cwd() + url, 'utf-8')
|
|
53
64
|
line = '';
|
|
54
|
-
if(!bindes.includes(`<link rel="stylesheet" href="${url}">`)) {
|
|
65
|
+
if (!bindes.includes(`<link rel="stylesheet" href="${url}">`)) {
|
|
55
66
|
bindes.push(`<link rel="stylesheet" href="${url}">`)
|
|
56
|
-
}
|
|
67
|
+
}
|
|
57
68
|
fs.mkdirSync(process.cwd() + '/dist' + path.dirname(url), { recursive: true })
|
|
58
69
|
fs.writeFileSync(process.cwd() + '/dist' + url, css)
|
|
59
|
-
|
|
70
|
+
} catch (error) {
|
|
60
71
|
console.error(error)
|
|
61
|
-
|
|
62
|
-
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
63
74
|
if (line.toLowerCase().includes('genkey()')) {
|
|
64
75
|
line = line.toLowerCase().replace('genkey()', `this.key = "${crypto.randomUUID()}"`)
|
|
65
76
|
}
|
|
66
|
-
if(!hasImport && line.includes('useFetch')){
|
|
77
|
+
if (!hasImport && line.includes('useFetch')) {
|
|
67
78
|
line = line.replace('useFetch', 'this.useFetch')
|
|
68
79
|
}
|
|
69
80
|
if (!hasImport && line.includes('useState')) {
|
|
@@ -72,7 +83,7 @@ const handleReplacements = (code, file) => {
|
|
|
72
83
|
b4 = line.replace('useState(', `this.useState('${key}',`)
|
|
73
84
|
line = b4
|
|
74
85
|
}
|
|
75
|
-
if(!hasImport && line.includes('useAsyncState')){
|
|
86
|
+
if (!hasImport && line.includes('useAsyncState')) {
|
|
76
87
|
let key = line.split(',')[0].split('[')[1].replace(' ', '')
|
|
77
88
|
let b4 = line
|
|
78
89
|
b4 = line.replace('useAsyncState(', `this.useAsyncState('${key}',`)
|
|
@@ -88,239 +99,180 @@ const handleReplacements = (code, file) => {
|
|
|
88
99
|
let key = line.split(' ')[1].split('=')[0]
|
|
89
100
|
b4 = line.replace('useRef(', `this.useRef('${key}',`)
|
|
90
101
|
line = b4
|
|
91
|
-
}
|
|
102
|
+
}
|
|
92
103
|
newLines.push(line)
|
|
93
104
|
}
|
|
94
105
|
let c = newLines.join('\n')
|
|
95
106
|
return c
|
|
96
|
-
}
|
|
97
|
-
|
|
107
|
+
}
|
|
98
108
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
109
|
+
|
|
110
|
+
async function generateApp() {
|
|
111
|
+
// remove files from dist
|
|
112
|
+
if (mode === 'development') {
|
|
113
|
+
fs.rmdirSync(process.cwd() + '/dist', { recursive: true })
|
|
114
|
+
} else {
|
|
115
|
+
fs.mkdirSync(process.cwd() + '/dist', { recursive: true })
|
|
116
|
+
}
|
|
117
|
+
return new Promise(async (resolve, reject) => {
|
|
118
|
+
let routes = new Bun.FileSystemRouter({
|
|
119
|
+
dir: process.cwd() + '/app',
|
|
120
|
+
style: 'nextjs'
|
|
121
|
+
})
|
|
122
|
+
routes.reload()
|
|
123
|
+
globalThis.routes = routes.routes
|
|
124
|
+
console.log(ansiColors.green(`Processing ${Object.keys(routes.routes).length} routes`))
|
|
125
|
+
|
|
126
|
+
Object.keys(routes.routes).forEach(async (route) => {
|
|
127
|
+
|
|
128
|
+
let r = routes.routes[route]
|
|
129
|
+
let code = await Bun.file(r).text()
|
|
130
|
+
code = handleReplacements(code)
|
|
131
|
+
let size = code.length / 1024
|
|
132
|
+
r = r.replace(process.cwd().replace(/\\/g, '/') + '/app', '')
|
|
133
|
+
r = r.replace('.jsx', '.js')
|
|
134
|
+
fs.mkdirSync(path.dirname(process.cwd() + '/dist/' + r), { recursive: true })
|
|
135
|
+
fs.writeFileSync(process.cwd() + '/dist/' + path.dirname(r) + '/' + path.basename(r), `
|
|
121
136
|
let route = window.location.pathname.split('/').filter(v => v !== '')
|
|
122
137
|
let params = {
|
|
123
|
-
${Object.keys(routes.match(route).params || {}).length >
|
|
138
|
+
${Object.keys(routes.match(route).params || {}).length > 0 ? Object.keys(routes.match(route).params || {}).map(p => {
|
|
124
139
|
return `${p}: route[${Object.keys(routes.match(route).params).indexOf(p) + 1}]`
|
|
125
140
|
}).join(',') : ""}
|
|
126
141
|
}
|
|
127
142
|
\n${code}
|
|
128
143
|
`)
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
import { document } from 'vaderjs/document'
|
|
133
|
-
import fs from 'fs'
|
|
134
|
-
let path2 = require('path')
|
|
135
|
-
globalThis.window = {
|
|
136
|
-
location: {
|
|
137
|
-
hash: '',
|
|
138
|
-
host: '',
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
globalThis.Component = Component
|
|
142
|
-
globalThis.e = e
|
|
143
|
-
globalThis.useState = useState
|
|
144
|
-
globalThis.genKey = () => {
|
|
145
|
-
return crypto.randomUUID()
|
|
146
|
-
};
|
|
147
|
-
globalThis.document = {
|
|
148
|
-
createElement: (tag) => {},
|
|
149
|
-
getElementById: (id) => {},
|
|
150
|
-
}
|
|
151
|
-
await Bun.build({
|
|
152
|
-
entrypoints: [process.env.ENTRYPOINT],
|
|
153
|
-
minify:true,
|
|
154
|
-
root: process.cwd() + '/dist/',
|
|
155
|
-
outdir: process.cwd() + '/dist/',
|
|
156
|
-
format: 'esm',
|
|
157
|
-
...(process.env.DEV ? { sourcemap: 'inline' } : {})
|
|
158
|
-
})
|
|
159
|
-
let isClass = function(element) {
|
|
160
|
-
return element.toString().startsWith('class');
|
|
161
|
-
};
|
|
162
|
-
const generatePage = async (data = {path: process.env.INPUT, route: process.env.OUT}) => {
|
|
163
|
-
const { path, route } = data
|
|
164
|
-
if(path.includes('root.js')) return
|
|
165
|
-
let html = await import(path).then(m => m.default)
|
|
166
|
-
let { head } = await import(path).then(m => m)
|
|
167
|
-
let isFunction = false
|
|
168
|
-
globalThis.isServer = true
|
|
169
|
-
if(isClass(html)){
|
|
170
|
-
html = new html()
|
|
171
|
-
html.Mounted = true
|
|
172
|
-
html = html.render()
|
|
173
|
-
}else{
|
|
174
|
-
isFunction = true
|
|
175
|
-
let instance = new Component()
|
|
176
|
-
html = html.bind(instance)
|
|
177
|
-
instance.render = html
|
|
178
|
-
html = instance.render()
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
let h = document(html)
|
|
182
|
-
if(!fs.existsSync(process.cwd() + '/dist' + path2.dirname(route))){
|
|
183
|
-
fs.mkdirSync(process.cwd() + '/dist' + path2.dirname(route), { recursive: true })
|
|
184
|
-
}
|
|
185
|
-
let headHtml = ''
|
|
186
|
-
if(head){
|
|
187
|
-
headHtml = document(head())
|
|
188
|
-
}
|
|
189
|
-
Bun.write(process.cwd() + '/dist/' + route + '/index.html', \`<!DOCTYPE html><head>\${headHtml}</head>\${h}
|
|
190
|
-
<script type="module">
|
|
191
|
-
import c from '\${process.env.filePath}'
|
|
192
|
-
import {render} from '/src/vader/index.js'
|
|
193
|
-
render(c, document.body.firstChild)
|
|
194
|
-
</script>
|
|
195
|
-
\`)
|
|
196
|
-
}
|
|
197
|
-
generatePage({path: process.env.INPUT, route: process.env.OUT})
|
|
198
|
-
`)
|
|
199
|
-
|
|
200
|
-
fs.mkdirSync(process.cwd() + '/dist/src/vader', { recursive: true })
|
|
201
|
-
fs.writeFileSync(process.cwd() + '/dist/src/vader/index.js', await new Bun.Transpiler({
|
|
202
|
-
loader: 'ts',
|
|
203
|
-
}).transformSync(await Bun.file(require.resolve('vaderjs')).text()))
|
|
204
|
-
|
|
205
|
-
const spawn = Bun.spawn({
|
|
206
|
-
cmd: ['bun', 'run', './dev/bundler.js'],
|
|
207
|
-
cwd: process.cwd(),
|
|
208
|
-
stdout: 'inherit',
|
|
209
|
-
env: {
|
|
210
|
-
ENTRYPOINT: path.join(process.cwd() + '/dist/' + path.dirname(r) + '/' + path.basename(r)),
|
|
211
|
-
ROOT: process.cwd() + '/app/',
|
|
212
|
-
OUT: path.dirname(r),
|
|
213
|
-
file: process.cwd() + '/dist/' + path.dirname(r) + '/index.js',
|
|
214
|
-
DEV: mode === 'development',
|
|
215
|
-
filePath: r,
|
|
216
|
-
INPUT: `../app/${r.replace('.js', '.jsx')}`,
|
|
217
|
-
},
|
|
218
|
-
onExit({exitCode: code}) {
|
|
219
|
-
if (code === 0) {
|
|
220
|
-
console.log('Build complete')
|
|
221
|
-
resolve()
|
|
222
|
-
} else {
|
|
223
|
-
reject()
|
|
224
|
-
}
|
|
144
|
+
fs.mkdirSync(process.cwd() + '/dev', { recursive: true })
|
|
145
|
+
if (!fs.existsSync(process.cwd() + '/dev/bundler.js')) {
|
|
146
|
+
fs.copyFileSync(require.resolve('vaderjs/bundler/index.js'), process.cwd() + '/dev/bundler.js')
|
|
225
147
|
}
|
|
226
|
-
})
|
|
227
|
-
|
|
228
|
-
})
|
|
229
148
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
let vercelData = {
|
|
234
|
-
rewrites: []
|
|
149
|
+
if (!fs.existsSync(process.cwd() + '/dev/readme.md')) {
|
|
150
|
+
fs.writeFileSync(process.cwd() + '/dev/readme.md', `# Please do not edit the bundler.js file in the dev directory. This file is automatically generated by the bundler. \n\n`)
|
|
235
151
|
}
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
152
|
+
fs.mkdirSync(process.cwd() + '/dist/src/vader', { recursive: true })
|
|
153
|
+
fs.writeFileSync(process.cwd() + '/dist/src/vader/index.js', await new Bun.Transpiler({
|
|
154
|
+
loader: 'ts',
|
|
155
|
+
}).transformSync(await Bun.file(require.resolve('vaderjs')).text()))
|
|
156
|
+
Bun.spawn({
|
|
157
|
+
cmd: ['bun', 'run', './dev/bundler.js'],
|
|
158
|
+
cwd: process.cwd(),
|
|
159
|
+
stdout: 'inherit',
|
|
160
|
+
env: {
|
|
161
|
+
ENTRYPOINT: path.join(process.cwd() + '/dist/' + path.dirname(r) + '/' + path.basename(r)),
|
|
162
|
+
ROOT: process.cwd() + '/app/',
|
|
163
|
+
OUT: path.dirname(r),
|
|
164
|
+
file: process.cwd() + '/dist/' + path.dirname(r) + '/index.js',
|
|
165
|
+
DEV: mode === 'development',
|
|
166
|
+
size,
|
|
167
|
+
filePath: r,
|
|
168
|
+
INPUT: `../app/${r.replace('.js', '.jsx')}`,
|
|
169
|
+
},
|
|
170
|
+
onExit({ exitCode: code }) {
|
|
171
|
+
if (code === 0) {
|
|
172
|
+
resolve()
|
|
173
|
+
} else {
|
|
174
|
+
reject()
|
|
175
|
+
}
|
|
243
176
|
}
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
base = base.split('/').filter(v => v !== '').join('/')
|
|
177
|
+
})
|
|
178
|
+
|
|
179
|
+
})
|
|
180
|
+
|
|
181
|
+
switch (host_provider) {
|
|
182
|
+
case 'vercel':
|
|
183
|
+
|
|
184
|
+
let vercelData = {
|
|
185
|
+
rewrites: []
|
|
254
186
|
}
|
|
255
|
-
|
|
256
|
-
|
|
187
|
+
|
|
188
|
+
for (let route in routes.routes) {
|
|
189
|
+
let { filePath, kind, name, params, pathname, query } = routes.match(route)
|
|
190
|
+
let paramString = ''
|
|
191
|
+
if (params) {
|
|
192
|
+
paramString = Object.keys(params).map(p => `:${p}`).join('/')
|
|
193
|
+
}
|
|
194
|
+
// replace double slashes
|
|
195
|
+
paramString = paramString.replace(/\/\//g, '/')
|
|
196
|
+
let base = route.split('/').filter(v => v !== '').join('/')
|
|
197
|
+
|
|
198
|
+
if (base.includes('[')) {
|
|
199
|
+
base = base.split('[')[0].split('/').filter(v => v !== '').join('/')
|
|
200
|
+
}
|
|
201
|
+
// remove double slashes
|
|
202
|
+
base = base.replace(/\/\//g, '/')
|
|
203
|
+
if (base === '/' || base === '') {
|
|
204
|
+
continue;
|
|
205
|
+
}
|
|
206
|
+
|
|
257
207
|
vercelData.rewrites.push({
|
|
258
208
|
source: `/${base}/${paramString}`,
|
|
259
209
|
destination: `${path.dirname(routes.routes[route]).replace(process.cwd().replace(/\\/g, '/') + '/app', '')}/index.html`
|
|
260
210
|
})
|
|
261
211
|
}
|
|
262
|
-
|
|
263
|
-
|
|
212
|
+
|
|
213
|
+
fs.writeFileSync(process.cwd() + '/vercel.json', JSON.stringify(vercelData, null, 4))
|
|
214
|
+
break;
|
|
215
|
+
}
|
|
264
216
|
|
|
265
|
-
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
})
|
|
217
|
+
})
|
|
269
218
|
|
|
270
219
|
}
|
|
271
220
|
|
|
272
221
|
await generateApp()
|
|
273
|
-
function handleFiles(){
|
|
274
|
-
|
|
275
|
-
try {
|
|
276
|
-
let glob = new Glob('public/**/*')
|
|
277
|
-
for await (var i of glob.scan()){
|
|
278
|
-
let file = i
|
|
279
|
-
fs.mkdirSync(path.join(process.cwd() + '/dist', path.dirname(file)), { recursive: true })
|
|
280
|
-
fs.copyFileSync(file, path.join(process.cwd() + '/dist', file))
|
|
281
|
-
}
|
|
282
|
-
resolve()
|
|
283
|
-
} catch (error) {
|
|
284
|
-
reject(error)
|
|
285
|
-
}
|
|
286
|
-
})
|
|
287
|
-
}
|
|
288
|
-
await handleFiles()
|
|
289
|
-
let isBuilding = false;
|
|
290
|
-
let timeout = null
|
|
291
|
-
if(mode === 'development'){
|
|
292
|
-
const watcher = fs.watch(path.join(process.cwd() + '/app'), { recursive: true })
|
|
293
|
-
const publicWatcher = fs.watch(path.join(process.cwd() + '/public'), { recursive: true })
|
|
294
|
-
publicWatcher.on('change', async (event, filename) => {
|
|
295
|
-
try {
|
|
296
|
-
await handleFiles()
|
|
297
|
-
clients.forEach(c => {
|
|
298
|
-
c.send('reload')
|
|
299
|
-
})
|
|
300
|
-
} catch (error) {
|
|
301
|
-
console.error(error)
|
|
302
|
-
}
|
|
303
|
-
})
|
|
304
|
-
watcher.on('change', async (event, filename) => {
|
|
222
|
+
function handleFiles() {
|
|
223
|
+
return new Promise(async (resolve, reject) => {
|
|
305
224
|
try {
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
225
|
+
let glob = new Glob('public/**/*')
|
|
226
|
+
for await (var i of glob.scan()) {
|
|
227
|
+
let file = i
|
|
228
|
+
fs.mkdirSync(path.join(process.cwd() + '/dist', path.dirname(file)), { recursive: true })
|
|
229
|
+
if (fs.existsSync(path.join(process.cwd() + '/dist', file))) {
|
|
230
|
+
fs.rmSync(path.join(process.cwd() + '/dist', file))
|
|
231
|
+
}
|
|
232
|
+
fs.copyFileSync(file, path.join(process.cwd() + '/dist', file))
|
|
233
|
+
}
|
|
234
|
+
resolve()
|
|
312
235
|
} catch (error) {
|
|
313
|
-
|
|
236
|
+
reject(error)
|
|
314
237
|
}
|
|
315
|
-
|
|
316
|
-
})
|
|
317
|
-
watcher.on('error', (err) => {
|
|
318
|
-
console.error(err)
|
|
319
238
|
})
|
|
320
239
|
}
|
|
240
|
+
await handleFiles()
|
|
321
241
|
globalThis.clients = []
|
|
322
242
|
|
|
323
|
-
if(mode === 'development'){
|
|
243
|
+
if (mode === 'development') {
|
|
244
|
+
const watcher = fs.watch(path.join(process.cwd() + '/app'), { recursive: true })
|
|
245
|
+
const publicWatcher = fs.watch(path.join(process.cwd() + '/public'), { recursive: true })
|
|
246
|
+
let isBuilding = false; // Flag to track build status
|
|
247
|
+
|
|
248
|
+
// Initialize a variable to hold the timeout ID
|
|
249
|
+
let debounceTimeout;
|
|
250
|
+
|
|
251
|
+
// Function to handle file changes with debounce
|
|
252
|
+
const handleFileChangeDebounced = async () => {
|
|
253
|
+
clearTimeout(debounceTimeout);
|
|
254
|
+
debounceTimeout = setTimeout(async () => {
|
|
255
|
+
if (!isBuilding) { // Check if not already building
|
|
256
|
+
isBuilding = true; // Set build flag to true
|
|
257
|
+
try {
|
|
258
|
+
await generateApp();
|
|
259
|
+
await handleFiles();
|
|
260
|
+
clients.forEach(c => {
|
|
261
|
+
c.send('reload');
|
|
262
|
+
});
|
|
263
|
+
} catch (error) {
|
|
264
|
+
console.error(error);
|
|
265
|
+
} finally {
|
|
266
|
+
isBuilding = false; // Reset build flag
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
}, 500);
|
|
270
|
+
};
|
|
271
|
+
|
|
272
|
+
// Event listeners with debounced handling
|
|
273
|
+
publicWatcher.on('change', handleFileChangeDebounced);
|
|
274
|
+
watcher.on('change', handleFileChangeDebounced);
|
|
275
|
+
|
|
324
276
|
let server = Bun.serve({
|
|
325
277
|
port: port || 8080,
|
|
326
278
|
websocket: {
|
|
@@ -333,34 +285,34 @@ if(mode === 'development'){
|
|
|
333
285
|
c.send(message)
|
|
334
286
|
})
|
|
335
287
|
},
|
|
336
|
-
|
|
288
|
+
|
|
337
289
|
},
|
|
338
290
|
async fetch(req, res) {
|
|
339
|
-
if(res.upgrade(req)){
|
|
291
|
+
if (res.upgrade(req)) {
|
|
340
292
|
return new Response('Upgraded', { status: 101 })
|
|
341
293
|
}
|
|
342
|
-
|
|
343
|
-
let url = new URL(req.url)
|
|
344
|
-
if(url.pathname.includes('.')){
|
|
345
|
-
let file = await Bun.file(path.join(process.cwd() + '/dist' + url.pathname))
|
|
346
|
-
if(!await file.exists()) return new Response('Not found', { status: 404 })
|
|
294
|
+
|
|
295
|
+
let url = new URL(req.url)
|
|
296
|
+
if (url.pathname.includes('.')) {
|
|
297
|
+
let file = await Bun.file(path.join(process.cwd() + '/dist' + url.pathname))
|
|
298
|
+
if (!await file.exists()) return new Response('Not found', { status: 404 })
|
|
347
299
|
return new Response(await file.text(), {
|
|
348
300
|
headers: {
|
|
349
|
-
'Content-Type':
|
|
301
|
+
'Content-Type': file.type
|
|
350
302
|
}
|
|
351
303
|
})
|
|
352
|
-
}
|
|
304
|
+
}
|
|
353
305
|
let router = new Bun.FileSystemRouter({
|
|
354
306
|
dir: process.cwd() + '/app',
|
|
355
307
|
style: 'nextjs'
|
|
356
308
|
})
|
|
357
|
-
router.reload()
|
|
309
|
+
router.reload()
|
|
358
310
|
let route = router.match(url.pathname)
|
|
359
|
-
if(!route){
|
|
311
|
+
if (!route) {
|
|
360
312
|
return new Response('Not found', { status: 404 })
|
|
361
|
-
}
|
|
362
|
-
let p = route.pathname;
|
|
363
|
-
let base = path.dirname(route.filePath)
|
|
313
|
+
}
|
|
314
|
+
let p = route.pathname;
|
|
315
|
+
let base = path.dirname(route.filePath)
|
|
364
316
|
base = base.replace(path.join(process.cwd() + '/app'), '')
|
|
365
317
|
base = base.replace(/\\/g, '/').replace('/app', '/dist')
|
|
366
318
|
return new Response(await Bun.file(path.join(base, 'index.html')).text() + `
|
|
@@ -376,12 +328,10 @@ if(mode === 'development'){
|
|
|
376
328
|
headers: {
|
|
377
329
|
'Content-Type': 'text/html'
|
|
378
330
|
}
|
|
379
|
-
})
|
|
331
|
+
})
|
|
380
332
|
}
|
|
381
333
|
})
|
|
382
|
-
|
|
383
|
-
console.log(`Server running on http://localhost:${server.port}`)
|
|
384
|
-
}else{
|
|
334
|
+
} else {
|
|
385
335
|
console.log(`Build complete in ${Date.now() - start}ms at ${new Date().toLocaleTimeString()}`)
|
|
386
336
|
process.exit(0)
|
|
387
337
|
}
|
package/package.json
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vaderjs",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.8",
|
|
4
4
|
"description": "A simple and powerful JavaScript library for building modern web applications.",
|
|
5
5
|
"main":"./index.js",
|
|
6
6
|
"bin": {
|
|
7
7
|
"vaderjs": "./main.js"
|
|
8
|
+
},
|
|
9
|
+
"dependencies": {
|
|
10
|
+
"ansi-colors":"latest"
|
|
8
11
|
}
|
|
9
12
|
}
|