vaderjs 1.4.9 → 1.5.1
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/LICENSE +21 -0
- package/README.md +89 -0
- package/bun.lockb +0 -0
- package/bundler/index.js +43 -11
- package/document/index.ts +8 -4
- package/{main.js → index.js} +377 -336
- package/index.ts +140 -122
- package/jsconfig.json +7 -0
- package/logo.png +0 -0
- package/package.json +15 -11
package/index.ts
CHANGED
|
@@ -70,6 +70,10 @@ export const useEffect = (callback:any, dependencies: any[]) => {
|
|
|
70
70
|
}
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
+
// make a switch function component
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
|
|
73
77
|
export const Fragment = (props: any, children: any) => {
|
|
74
78
|
return {
|
|
75
79
|
type: "div",
|
|
@@ -87,23 +91,53 @@ globalThis.Fragment = Fragment;
|
|
|
87
91
|
* @param children
|
|
88
92
|
* @returns
|
|
89
93
|
*/
|
|
90
|
-
export const e = (element
|
|
94
|
+
export const e = (element, props, ...children) => {
|
|
91
95
|
let instance;
|
|
92
|
-
switch (true){
|
|
96
|
+
switch (true) {
|
|
93
97
|
case isClassComponent(element):
|
|
94
|
-
|
|
98
|
+
instance = new element;
|
|
95
99
|
instance.props = props;
|
|
96
100
|
instance.children = children;
|
|
97
|
-
return instance.render();
|
|
101
|
+
return instance.render(props);
|
|
98
102
|
case typeof element === "function":
|
|
99
|
-
instance = new Component
|
|
100
|
-
instance.render = element;
|
|
101
|
-
|
|
103
|
+
instance = new Component;
|
|
104
|
+
instance.render = element;
|
|
105
|
+
let firstEl = instance.render({key: instance.key, children: children, ...props});
|
|
106
|
+
instance.children = children;
|
|
107
|
+
if (!firstEl) firstEl = {type: "div", props: {key: instance.key, children: [], ...props}, children: []};
|
|
108
|
+
firstEl.props = {key: instance.key, children: children, ...props};
|
|
109
|
+
return firstEl;
|
|
102
110
|
default:
|
|
103
111
|
return { type: element, props: props || {}, children: children || [] };
|
|
104
|
-
}
|
|
112
|
+
}
|
|
105
113
|
};
|
|
106
114
|
|
|
115
|
+
/*
|
|
116
|
+
* @description - Switch component
|
|
117
|
+
* @param element
|
|
118
|
+
* @param props
|
|
119
|
+
* @param children
|
|
120
|
+
* @returns
|
|
121
|
+
*/
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
export function Switch({ children }) {
|
|
125
|
+
for (let child of children) {
|
|
126
|
+
if (child.props.when) {
|
|
127
|
+
return child;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
return null;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* @description - Match component
|
|
135
|
+
* @param param0
|
|
136
|
+
* @returns
|
|
137
|
+
*/
|
|
138
|
+
export function Match({ when, children }) {
|
|
139
|
+
return when ? children : null;
|
|
140
|
+
}
|
|
107
141
|
/**
|
|
108
142
|
* @description - Manage state and forceupdate specific affected elements
|
|
109
143
|
* @param key
|
|
@@ -135,119 +169,101 @@ export const useState = <T>(initialState: T) => {
|
|
|
135
169
|
* render(<App name="John" />, document.getElementById("root"));
|
|
136
170
|
*/
|
|
137
171
|
export class Component {
|
|
138
|
-
props
|
|
139
|
-
state
|
|
140
|
-
element
|
|
141
|
-
Mounted
|
|
142
|
-
effect
|
|
143
|
-
key
|
|
144
|
-
prevState
|
|
172
|
+
props;
|
|
173
|
+
state;
|
|
174
|
+
element;
|
|
175
|
+
Mounted;
|
|
176
|
+
effect;
|
|
177
|
+
key;
|
|
178
|
+
prevState;
|
|
145
179
|
constructor() {
|
|
146
|
-
this.key =
|
|
180
|
+
this.key = crypto.randomUUID();
|
|
147
181
|
this.props = {};
|
|
148
182
|
this.state = {};
|
|
149
183
|
this.effect = [];
|
|
150
184
|
this.Mounted = false;
|
|
151
|
-
this.element = null;
|
|
185
|
+
this.element = null;
|
|
152
186
|
}
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
useEffect(callback: any, dependencies: any[]) {
|
|
156
|
-
if (dependencies.length === 0 && this.Mounted && this.effect.length === 0) {
|
|
187
|
+
useEffect(callback, dependencies) {
|
|
188
|
+
if (dependencies.length === 0 && this.Mounted && this.effect.length === 0) {
|
|
157
189
|
callback();
|
|
158
190
|
this.effect.push(callback);
|
|
159
|
-
}else{
|
|
160
|
-
for (let i = 0;
|
|
191
|
+
} else {
|
|
192
|
+
for (let i = 0;i < dependencies.length; i++) {
|
|
161
193
|
if (this.effect[i] !== dependencies[i]) {
|
|
162
194
|
this.effect = dependencies;
|
|
163
195
|
callback();
|
|
164
|
-
}
|
|
196
|
+
}
|
|
165
197
|
}
|
|
166
198
|
}
|
|
167
|
-
}
|
|
168
|
-
|
|
199
|
+
}
|
|
200
|
+
useState(key, defaultValue) {
|
|
201
|
+
if (typeof window === "undefined")
|
|
202
|
+
return [defaultValue, () => {
|
|
203
|
+
}];
|
|
169
204
|
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') {
|
|
205
|
+
if (typeof value === "string") {
|
|
173
206
|
try {
|
|
174
207
|
value = JSON.parse(value);
|
|
175
208
|
} catch (error) {
|
|
176
|
-
// Not a valid JSON, keep it as is
|
|
177
209
|
}
|
|
178
210
|
}
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
window.addEventListener('beforeunload', () => {
|
|
184
|
-
sessionStorage.removeItem('state_' + key)
|
|
211
|
+
if (!window["listener" + key] && !isServer) {
|
|
212
|
+
window["listener" + key] = true;
|
|
213
|
+
window.addEventListener("beforeunload", () => {
|
|
214
|
+
sessionStorage.removeItem("state_" + key);
|
|
185
215
|
});
|
|
186
216
|
}
|
|
187
|
-
|
|
188
|
-
const setValue = (newValue: T) => {
|
|
217
|
+
const setValue = (newValue) => {
|
|
189
218
|
value = newValue;
|
|
190
219
|
sessionStorage.setItem("state_" + key, JSON.stringify({ type: typeof newValue, value: newValue }));
|
|
191
|
-
this.forceUpdate(this.key)
|
|
220
|
+
this.forceUpdate(this.key);
|
|
192
221
|
};
|
|
193
|
-
|
|
194
|
-
return [value as T, setValue];
|
|
222
|
+
return [value, setValue];
|
|
195
223
|
}
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
useFetch(url: string, options: any) {
|
|
224
|
+
useFetch(url, options) {
|
|
200
225
|
const loadingKey = "loading_" + url;
|
|
201
226
|
const errorKey = "error" + url;
|
|
202
|
-
const dataKey = "_data" + url;
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
227
|
+
const dataKey = "_data" + url;
|
|
228
|
+
let [loading, setLoading] = this.useState(loadingKey, true);
|
|
229
|
+
let [error, setError] = this.useState(errorKey, null);
|
|
230
|
+
let [data, setData] = this.useState(dataKey, null);
|
|
207
231
|
if (loading && !error && !data) {
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
this.forceUpdate(this.key);
|
|
217
|
-
})
|
|
218
|
-
.catch((err) => {
|
|
219
|
-
setError(err);
|
|
220
|
-
this.forceUpdate(this.key);
|
|
221
|
-
});
|
|
232
|
+
fetch(url, options).then((res) => res.json()).then((data2) => {
|
|
233
|
+
setLoading(false);
|
|
234
|
+
setData(data2);
|
|
235
|
+
this.forceUpdate(this.key);
|
|
236
|
+
}).catch((err) => {
|
|
237
|
+
setError(err);
|
|
238
|
+
this.forceUpdate(this.key);
|
|
239
|
+
});
|
|
222
240
|
}
|
|
223
|
-
|
|
224
241
|
return [data, loading, error];
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
|
|
242
|
+
}
|
|
228
243
|
forceUpdate(key) {
|
|
229
|
-
|
|
230
|
-
|
|
244
|
+
let el = Array.from(document.querySelectorAll("*")).filter((el2) => {
|
|
245
|
+
return el2.key === key;
|
|
246
|
+
})[0];
|
|
231
247
|
let newl = this.toElement();
|
|
232
|
-
if(newl.key !== key){
|
|
233
|
-
//@ts-ignore
|
|
248
|
+
if (newl.key !== key) {
|
|
234
249
|
newl = Array.from(newl.children).filter((el2) => el2.key === key)[0];
|
|
235
|
-
}
|
|
250
|
+
}
|
|
236
251
|
this.Reconciler.update(el, newl);
|
|
237
252
|
}
|
|
238
253
|
Reconciler = {
|
|
239
|
-
update: (oldElement, newElement) => {
|
|
240
|
-
if(!oldElement || !newElement)
|
|
241
|
-
|
|
242
|
-
|
|
254
|
+
update: (oldElement, newElement) => {
|
|
255
|
+
if (!oldElement || !newElement)
|
|
256
|
+
return;
|
|
257
|
+
if (this.Reconciler.shouldUpdate(oldElement, newElement) && oldElement.tagName == newElement.tagName) {
|
|
258
|
+
oldElement.replaceWith(newElement);
|
|
243
259
|
} else {
|
|
244
260
|
let children = oldElement.childNodes;
|
|
245
|
-
for (let i = 0;
|
|
261
|
+
for (let i = 0;i < children.length; i++) {
|
|
246
262
|
this.Reconciler.update(children[i], newElement.childNodes[i]);
|
|
247
263
|
}
|
|
248
264
|
}
|
|
249
265
|
},
|
|
250
|
-
|
|
266
|
+
shouldUpdate(oldElement, newElement) {
|
|
251
267
|
if (oldElement.nodeType !== newElement.nodeType) {
|
|
252
268
|
return true;
|
|
253
269
|
}
|
|
@@ -262,10 +278,10 @@ export class Component {
|
|
|
262
278
|
}
|
|
263
279
|
return false;
|
|
264
280
|
}
|
|
265
|
-
};
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
281
|
+
};
|
|
282
|
+
parseToElement = (element) => {
|
|
283
|
+
if (!element)
|
|
284
|
+
return document.createElement("div");
|
|
269
285
|
let el = document.createElement(element.type);
|
|
270
286
|
let isText = typeof element === "string" || typeof element === "number" || typeof element === "boolean";
|
|
271
287
|
if (isText) {
|
|
@@ -274,8 +290,8 @@ export class Component {
|
|
|
274
290
|
let attributes = element.props;
|
|
275
291
|
let children = element.children;
|
|
276
292
|
for (let key in attributes) {
|
|
277
|
-
if(key === "key"){
|
|
278
|
-
|
|
293
|
+
if (key === "key") {
|
|
294
|
+
el.key = attributes[key];
|
|
279
295
|
continue;
|
|
280
296
|
}
|
|
281
297
|
if (key === "className") {
|
|
@@ -288,55 +304,57 @@ export class Component {
|
|
|
288
304
|
}
|
|
289
305
|
continue;
|
|
290
306
|
}
|
|
291
|
-
|
|
292
|
-
if (key.startsWith("on")) {
|
|
307
|
+
if (key.startsWith("on")) {
|
|
293
308
|
el.addEventListener(key.substring(2).toLowerCase(), attributes[key]);
|
|
294
309
|
continue;
|
|
295
310
|
}
|
|
296
311
|
el.setAttribute(key, attributes[key]);
|
|
297
|
-
}
|
|
298
|
-
|
|
312
|
+
}
|
|
313
|
+
if(children === undefined) return el;
|
|
314
|
+
for (let i = 0;i < children.length; i++) {
|
|
299
315
|
let child = children[i];
|
|
300
316
|
if (Array.isArray(child)) {
|
|
301
317
|
child.forEach((c) => {
|
|
302
318
|
el.appendChild(this.parseToElement(c));
|
|
303
319
|
});
|
|
304
320
|
}
|
|
305
|
-
if(typeof child === "function"){
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
321
|
+
if (typeof child === "function") {
|
|
322
|
+
console.log("child is function");
|
|
323
|
+
let comp = memoizeClassComponent(Component);
|
|
324
|
+
comp.Mounted = true;
|
|
325
|
+
comp.render = child;
|
|
326
|
+
let el2 = comp.toElement();
|
|
327
|
+
el2.setAttribute("key", comp.key);
|
|
328
|
+
el.appendChild(el2);
|
|
329
|
+
} else if (typeof child === "object") {
|
|
330
|
+
el.appendChild(this.parseToElement(child));
|
|
331
|
+
} else {
|
|
332
|
+
let span = document.createElement("span");
|
|
333
|
+
span.innerHTML = child;
|
|
334
|
+
el.appendChild(span);
|
|
314
335
|
}
|
|
315
336
|
}
|
|
316
337
|
}
|
|
317
338
|
return el;
|
|
318
339
|
};
|
|
319
|
-
e(element
|
|
320
|
-
if(typeof element === "function"){
|
|
340
|
+
e(element, props, ...children) {
|
|
341
|
+
if (typeof element === "function") {
|
|
321
342
|
return element();
|
|
322
343
|
}
|
|
323
344
|
return { type: element, props: props || {}, children: children || [] };
|
|
324
345
|
}
|
|
325
|
-
toElement() {
|
|
346
|
+
toElement() {
|
|
326
347
|
let children = this.render();
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
this.key = children.props['key'];
|
|
348
|
+
if (children.props["key"]) {
|
|
349
|
+
this.key = children.props["key"];
|
|
330
350
|
}
|
|
331
351
|
let el = this.parseToElement(children);
|
|
332
|
-
el.key = this.key;
|
|
352
|
+
el.key = this.key;
|
|
333
353
|
return el;
|
|
334
354
|
}
|
|
335
355
|
render() {
|
|
336
356
|
return "";
|
|
337
357
|
}
|
|
338
|
-
|
|
339
|
-
|
|
340
358
|
}
|
|
341
359
|
|
|
342
360
|
function memoizeClassComponent(Component: any) {
|
|
@@ -354,21 +372,21 @@ function memoizeClassComponent(Component: any) {
|
|
|
354
372
|
* @param element
|
|
355
373
|
* @param container
|
|
356
374
|
*/
|
|
357
|
-
export function render(element
|
|
375
|
+
export function render(element, container) {
|
|
358
376
|
if (isClassComponent(element)) {
|
|
359
|
-
const instance = new element
|
|
360
|
-
instance.Mounted = true;
|
|
361
|
-
let el = instance.toElement();
|
|
362
|
-
instance.element = el;
|
|
363
|
-
container.innerHTML = "";
|
|
377
|
+
const instance = new element;
|
|
378
|
+
instance.Mounted = true;
|
|
379
|
+
let el = instance.toElement();
|
|
380
|
+
instance.element = el;
|
|
381
|
+
container.innerHTML = "";
|
|
382
|
+
container.replaceWith(el);
|
|
383
|
+
} else {
|
|
384
|
+
let memoizedInstance = memoizeClassComponent(Component);
|
|
385
|
+
memoizedInstance.Mounted = true;
|
|
386
|
+
memoizedInstance.render = element.bind(memoizedInstance);
|
|
387
|
+
let el = memoizedInstance.toElement();
|
|
388
|
+
el.key = memoizedInstance.key;
|
|
389
|
+
container.innerHTML = "";
|
|
364
390
|
container.replaceWith(el);
|
|
365
|
-
} else {
|
|
366
|
-
let memoizedInstance = memoizeClassComponent(Component);
|
|
367
|
-
memoizedInstance.Mounted = true;
|
|
368
|
-
memoizedInstance.render = element.bind(memoizedInstance);
|
|
369
|
-
let el = memoizedInstance.toElement();
|
|
370
|
-
container.innerHTML = "";
|
|
371
|
-
container.replaceWith(el);
|
|
372
|
-
|
|
373
391
|
}
|
|
374
|
-
}
|
|
392
|
+
}
|
package/jsconfig.json
ADDED
package/logo.png
ADDED
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,12 +1,16 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "vaderjs",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "A simple and powerful JavaScript library for building modern web applications.",
|
|
5
|
-
"main":"./index.js",
|
|
6
|
-
"
|
|
7
|
-
"
|
|
8
|
-
},
|
|
9
|
-
"
|
|
10
|
-
"
|
|
11
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "vaderjs",
|
|
3
|
+
"version": "1.5.1",
|
|
4
|
+
"description": "A simple and powerful JavaScript library for building modern web applications.",
|
|
5
|
+
"main": "./index.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"dev":"bun run index.js dev"
|
|
8
|
+
},
|
|
9
|
+
"bin": {
|
|
10
|
+
"vaderjs": "./main.js"
|
|
11
|
+
},
|
|
12
|
+
"dependencies": {
|
|
13
|
+
"ansi-colors": "latest",
|
|
14
|
+
"vaderjs": "^1.5.0"
|
|
15
|
+
}
|
|
12
16
|
}
|