vaderjs 1.3.3-alpha-119 → 1.3.3-alpha-121
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/package.json +1 -1
- package/runtime/router.js +1 -446
- package/vader.js +9 -11
- package/runtime/vercel.json +0 -3
package/package.json
CHANGED
package/runtime/router.js
CHANGED
|
@@ -1,446 +1 @@
|
|
|
1
|
-
import { Component }
|
|
2
|
-
|
|
3
|
-
let middlewares = [];
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* @class VaderRouter
|
|
9
|
-
* @description - creates an instance of Vader Express Router
|
|
10
|
-
*
|
|
11
|
-
* @param {String} path
|
|
12
|
-
* @param {Function} handler
|
|
13
|
-
* @param {object} req request object
|
|
14
|
-
* @param {object} res response object
|
|
15
|
-
* @returns {Object} Express
|
|
16
|
-
*
|
|
17
|
-
*/
|
|
18
|
-
class VaderRouter{
|
|
19
|
-
/**
|
|
20
|
-
* @constructor
|
|
21
|
-
* @param {*} basePath
|
|
22
|
-
*
|
|
23
|
-
*/
|
|
24
|
-
constructor(/**@type {string}**/basePath, /**@type {number}**/port) {
|
|
25
|
-
this.routes = [];
|
|
26
|
-
this.middlewares = [];
|
|
27
|
-
this.errorMiddlewares = [];
|
|
28
|
-
this.listeners = [];
|
|
29
|
-
|
|
30
|
-
this.basePath = basePath;
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* @method get
|
|
37
|
-
* @param {String} path
|
|
38
|
-
* @param {Function} handler
|
|
39
|
-
* @param {{a:b}} req request object
|
|
40
|
-
* @description This method is used to register a get route
|
|
41
|
-
* @returns {void}
|
|
42
|
-
* @memberof Express
|
|
43
|
-
*/
|
|
44
|
-
get(path, handler) {
|
|
45
|
-
this.routes.push({
|
|
46
|
-
path,
|
|
47
|
-
handler,
|
|
48
|
-
method: 'get',
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
}
|
|
52
|
-
/**
|
|
53
|
-
* @method use
|
|
54
|
-
* @description This method allows you to use middlewares
|
|
55
|
-
* @param {Function} middleware
|
|
56
|
-
*/
|
|
57
|
-
|
|
58
|
-
use(/* path, */ middleware) {
|
|
59
|
-
this.middlewares.push(middleware);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* @method listen
|
|
64
|
-
* @param {String} port - unique id for the listener
|
|
65
|
-
* @param {Function} callback - callback function
|
|
66
|
-
* @description This method is used to start listening to the routes
|
|
67
|
-
* @returns {void}
|
|
68
|
-
*
|
|
69
|
-
*/
|
|
70
|
-
|
|
71
|
-
listen(port, callback) {
|
|
72
|
-
if(!port){
|
|
73
|
-
port = Math.random().toString(36).substring(7);
|
|
74
|
-
}
|
|
75
|
-
window.onpopstate = async (e) => {
|
|
76
|
-
let route = window.location.pathname
|
|
77
|
-
let baseRoute = `/${route.split('/')[1]}`
|
|
78
|
-
if(!this.checkroute(route)){
|
|
79
|
-
route = '/404'
|
|
80
|
-
}
|
|
81
|
-
let html = new DOMParser().parseFromString(await fetch(baseRoute, {
|
|
82
|
-
cache: 'reload'
|
|
83
|
-
}).then((res)=>res.text()), 'text/html').documentElement
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
document.querySelector('#root').innerHTML = html.querySelector('#root').innerHTML;
|
|
87
|
-
document.title = html.querySelector('title').innerHTML;
|
|
88
|
-
document.querySelector('script[id="router"]').remove();
|
|
89
|
-
let newscript = document.createElement('script');
|
|
90
|
-
newscript.id = 'router';
|
|
91
|
-
newscript.innerHTML = html.querySelector('script[id="router"]').innerHTML;
|
|
92
|
-
newscript.setAttribute('type', 'module');
|
|
93
|
-
document.body.appendChild(newscript);
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
this.listeners.push(port);
|
|
97
|
-
if (this.listeners.length === 1) {
|
|
98
|
-
console.log(window.location.pathname)
|
|
99
|
-
this.handleRoute(window.location.pathname);
|
|
100
|
-
}else{
|
|
101
|
-
this.listeners.pop();
|
|
102
|
-
}
|
|
103
|
-
if (callback) {
|
|
104
|
-
callback();
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
}
|
|
108
|
-
/**
|
|
109
|
-
* @method extractParams
|
|
110
|
-
* @description This method is used to extract parameters from the route path
|
|
111
|
-
* @param {*} routePath
|
|
112
|
-
* @param {*} hash
|
|
113
|
-
* @returns {Object} params
|
|
114
|
-
* @memberof Express
|
|
115
|
-
*/
|
|
116
|
-
|
|
117
|
-
extractParams(routePath, hash) {
|
|
118
|
-
const routeParts = routePath.split('/').filter((part) => part !== '');
|
|
119
|
-
const hashParts = hash.split('/').filter((part) => part !== '');
|
|
120
|
-
const params = {};
|
|
121
|
-
routeParts.forEach((part, index) => {
|
|
122
|
-
if (part.startsWith(':')) {
|
|
123
|
-
const paramName = part.slice(1);
|
|
124
|
-
params[paramName] = hashParts[index];
|
|
125
|
-
}else if(part.startsWith('*')){
|
|
126
|
-
let array = hashParts.slice(index)
|
|
127
|
-
array.forEach((i, index)=>{
|
|
128
|
-
params[index] = i
|
|
129
|
-
})
|
|
130
|
-
};
|
|
131
|
-
});
|
|
132
|
-
return params;
|
|
133
|
-
}
|
|
134
|
-
extractQueryParams(hash){
|
|
135
|
-
|
|
136
|
-
const queryParams = hash.split('?')[1];
|
|
137
|
-
if(!queryParams){
|
|
138
|
-
return {};
|
|
139
|
-
}
|
|
140
|
-
const params = {};
|
|
141
|
-
queryParams.split('&').forEach((param)=>{
|
|
142
|
-
const [key, value] = param.split('=');
|
|
143
|
-
params[key] = value;
|
|
144
|
-
})
|
|
145
|
-
return params;
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
checkroute(hash){
|
|
149
|
-
let route = this.routes.find((route) => {
|
|
150
|
-
if (route.path === hash) {
|
|
151
|
-
return true;
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
if(hash === '' && route.path === '/'){
|
|
155
|
-
return true
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
if(hash.includes('?')){
|
|
159
|
-
hash = hash.split('?')[0]
|
|
160
|
-
}
|
|
161
|
-
if (route.path.includes('*') || route.path.includes(':')) {
|
|
162
|
-
const routeParts = route.path.split('/').filter((part) => part !== '');
|
|
163
|
-
const hashParts = hash.split('/').filter((part) => part !== '');
|
|
164
|
-
if (routeParts.length !== hashParts.length && !route.path.endsWith('*')) {
|
|
165
|
-
return false;
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
for (let index = 0; index < routeParts.length; index++) {
|
|
169
|
-
const routePart = routeParts[index];
|
|
170
|
-
const hashPart = hashParts[index];
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
if (routePart.startsWith(':') || routePart.startsWith('*')) {
|
|
174
|
-
|
|
175
|
-
continue;
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
if (routePart !== hashPart) {
|
|
179
|
-
return false;
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
return true;
|
|
184
|
-
}
|
|
185
|
-
const params = this.extractParams(route.path, hash);
|
|
186
|
-
return Object.keys(params).length > 0;
|
|
187
|
-
});
|
|
188
|
-
|
|
189
|
-
return route;
|
|
190
|
-
|
|
191
|
-
}
|
|
192
|
-
/**
|
|
193
|
-
* @method handleRoute
|
|
194
|
-
* @param {String} hash
|
|
195
|
-
* @description This method is used to handle the route
|
|
196
|
-
*/
|
|
197
|
-
|
|
198
|
-
handleRoute(hash) {
|
|
199
|
-
let status = 200;
|
|
200
|
-
let paramsCatchall = {}
|
|
201
|
-
let hashBefore = hash;
|
|
202
|
-
|
|
203
|
-
let route = this.checkroute(hash);
|
|
204
|
-
if (!route) {
|
|
205
|
-
route = window.routes.find((errorRoute) => {
|
|
206
|
-
if (errorRoute.url.includes('/404') && !this.error) {
|
|
207
|
-
console.error(`Route ${hash} not found`);
|
|
208
|
-
this.error = true;
|
|
209
|
-
return false
|
|
210
|
-
|
|
211
|
-
} else if (!this.error && errorRoute.url.includes('/404')){
|
|
212
|
-
return true
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
});
|
|
216
|
-
|
|
217
|
-
status = route ? 200 : 404;
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
const queryParams = this.extractQueryParams(hashBefore);
|
|
221
|
-
const params = route && route.path ? this.extractParams(route.path, hashBefore) : paramsCatchall;
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
// remove queryparams fromparam
|
|
225
|
-
Object.keys(params).forEach((key)=>{
|
|
226
|
-
params[key] = params[key].split('?') ? params[key].split('?')[0] : params[key];
|
|
227
|
-
})
|
|
228
|
-
const req = {
|
|
229
|
-
headers: {},
|
|
230
|
-
params: params,
|
|
231
|
-
query: queryParams,
|
|
232
|
-
path: hash,
|
|
233
|
-
fileUrl: window.location.href.split(window.location.origin)[1],
|
|
234
|
-
url: window.location.href,
|
|
235
|
-
method: route ? route.method : 'get',
|
|
236
|
-
pause: false,
|
|
237
|
-
timestamp: Date.now(),
|
|
238
|
-
};
|
|
239
|
-
|
|
240
|
-
// @ts-ignore
|
|
241
|
-
window.$CURRENT_URL = req.path
|
|
242
|
-
|
|
243
|
-
// @ts-ignore
|
|
244
|
-
window.$FULL_URL = window.location.href.replace('#', '')
|
|
245
|
-
|
|
246
|
-
const res = {
|
|
247
|
-
status: status,
|
|
248
|
-
/**
|
|
249
|
-
* @method log
|
|
250
|
-
* @param {String} type
|
|
251
|
-
* @description This method is used to log the request and response
|
|
252
|
-
*/
|
|
253
|
-
log: (type) => {
|
|
254
|
-
if(type === undefined){
|
|
255
|
-
console.log(`${req.path} ${req.method} ${res.status} ${req.timestamp}`);
|
|
256
|
-
}else{
|
|
257
|
-
console.table({
|
|
258
|
-
'Request Path': req.path,
|
|
259
|
-
'Request Method': route.method,
|
|
260
|
-
'Response Status': res.status,
|
|
261
|
-
'Request Timestamp': req.timestamp,
|
|
262
|
-
});
|
|
263
|
-
}
|
|
264
|
-
},
|
|
265
|
-
refresh: () => {
|
|
266
|
-
this.handleRoute(window.location.pathname)
|
|
267
|
-
},
|
|
268
|
-
redirect: (path) => {
|
|
269
|
-
!path.startsWith('/') ? path = `/${path}` : null;
|
|
270
|
-
window.history.pushState({}, '', path);
|
|
271
|
-
window.dispatchEvent(new Event('popstate'));
|
|
272
|
-
},
|
|
273
|
-
render: async (/**@type {Component} */ component, req, res, metadata) => {
|
|
274
|
-
function isClass(funcOrClass) {
|
|
275
|
-
return typeof funcOrClass === 'function' &&
|
|
276
|
-
/^class\s/.test(Function.prototype.toString.call(funcOrClass));
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
try {
|
|
280
|
-
let c = new Component();
|
|
281
|
-
if(!isClass(component.default)){
|
|
282
|
-
let render = component.default.toString();
|
|
283
|
-
if(render.includes('this.key')){
|
|
284
|
-
throw new Error('Using this.key is not supported in functional components use the attribute key="a value" instead')
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
c.key = component.default.toString().split('key="')[1] ? component.default.toString().split('key="')[1].split('"')[0] : null;
|
|
290
|
-
|
|
291
|
-
let comp = {
|
|
292
|
-
key: c.key,
|
|
293
|
-
render: () => {
|
|
294
|
-
return component.default.apply(c, [req, res])
|
|
295
|
-
},
|
|
296
|
-
request: req,
|
|
297
|
-
response: res,
|
|
298
|
-
params: params,
|
|
299
|
-
queryParams: queryParams,
|
|
300
|
-
reset: c.reset.bind(c),
|
|
301
|
-
onMount: c.onMount.bind(c),
|
|
302
|
-
useState: null,
|
|
303
|
-
router: {
|
|
304
|
-
use: c.router.use.bind(c),
|
|
305
|
-
},
|
|
306
|
-
bindMount: c.bindMount.bind(c),
|
|
307
|
-
memoize: c.memoize.bind(c),
|
|
308
|
-
createComponent: c.createComponent.bind(c),
|
|
309
|
-
isChild: false,
|
|
310
|
-
useState: c.useState.bind(c),
|
|
311
|
-
parseStyle: c.parseStyle.bind(c),
|
|
312
|
-
bind: c.bind.bind(c),
|
|
313
|
-
useRef: c.useRef.bind(c),
|
|
314
|
-
useReducer: c.useReducer.bind(c),
|
|
315
|
-
onMount: c.onMount.bind(c),
|
|
316
|
-
onUnmount: c.onUnmount.bind(c),
|
|
317
|
-
hydrate: c.hydrate.bind(c),
|
|
318
|
-
}
|
|
319
|
-
c.render = comp.render;
|
|
320
|
-
c = comp;
|
|
321
|
-
|
|
322
|
-
}else{
|
|
323
|
-
let comp = new component.default();
|
|
324
|
-
c.state = comp.state;
|
|
325
|
-
c = comp;
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
// Check if the root element exists
|
|
337
|
-
if (!document.querySelector('#root')) {
|
|
338
|
-
throw new Error('Root element not found, please add an element with id root');
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
c.reset();
|
|
342
|
-
c.components = {};
|
|
343
|
-
c.request = req;
|
|
344
|
-
c.response = res;
|
|
345
|
-
if (c.router.use && !c.isChild) {
|
|
346
|
-
await new Promise(async (resolve) => {
|
|
347
|
-
if(!isClass(component.default) ){
|
|
348
|
-
await component.default.apply(c, [req, res])
|
|
349
|
-
await c.router.use(req, res)
|
|
350
|
-
switch(req.pause){
|
|
351
|
-
case true:
|
|
352
|
-
let timer = setInterval(() => {
|
|
353
|
-
if (!req.pause) {
|
|
354
|
-
clearInterval(timer);
|
|
355
|
-
resolve();
|
|
356
|
-
}else{
|
|
357
|
-
console.log('still pausing request', req.url)
|
|
358
|
-
}
|
|
359
|
-
}, 1000);
|
|
360
|
-
break;
|
|
361
|
-
case false:
|
|
362
|
-
resolve();
|
|
363
|
-
break;
|
|
364
|
-
}
|
|
365
|
-
}else if(isClass(component.default)){
|
|
366
|
-
|
|
367
|
-
await c.router.use(req, res)
|
|
368
|
-
switch(req.pause){
|
|
369
|
-
case true:
|
|
370
|
-
console.log('pausing', req.pause)
|
|
371
|
-
let timer = setInterval(() => {
|
|
372
|
-
if (!req.pause) {
|
|
373
|
-
clearInterval(timer);
|
|
374
|
-
resolve();
|
|
375
|
-
}else{
|
|
376
|
-
console.log('still pausing', req.pause)
|
|
377
|
-
}
|
|
378
|
-
}, 1000);
|
|
379
|
-
break;
|
|
380
|
-
case false:
|
|
381
|
-
resolve();
|
|
382
|
-
break;
|
|
383
|
-
}
|
|
384
|
-
}else{
|
|
385
|
-
resolve();
|
|
386
|
-
}
|
|
387
|
-
});
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
} else if (c.router.use && c.isChild) {
|
|
391
|
-
console.warn('Router.use() is not supported in child components');
|
|
392
|
-
}
|
|
393
|
-
const renderedContent = await c.render();
|
|
394
|
-
if( document.querySelector('#root').innerHTML !== renderedContent){
|
|
395
|
-
document.querySelector('#root').innerHTML = renderedContent;
|
|
396
|
-
}
|
|
397
|
-
c.bindMount();
|
|
398
|
-
c.onMount();
|
|
399
|
-
|
|
400
|
-
} catch (error) {
|
|
401
|
-
console.error(error);
|
|
402
|
-
}
|
|
403
|
-
},
|
|
404
|
-
setQuery: (query) => {
|
|
405
|
-
let queryString = '';
|
|
406
|
-
Object.keys(query).forEach((key, index) => {
|
|
407
|
-
queryString += `${index === 0 ? '?' : '&'}${key}=${query[key]}`;
|
|
408
|
-
});
|
|
409
|
-
let route = window.location.hash.split('?')[0];
|
|
410
|
-
queryString = queryString.replace('/', '-').replaceAll('/', '-')
|
|
411
|
-
window.location.hash = `${route}${queryString}`;
|
|
412
|
-
},
|
|
413
|
-
send: (data) => {
|
|
414
|
-
document.querySelector('#root').innerHTML = data;
|
|
415
|
-
},
|
|
416
|
-
json: (data) => {
|
|
417
|
-
const rootElement = document.querySelector('#root');
|
|
418
|
-
|
|
419
|
-
// Clear existing content in #root
|
|
420
|
-
rootElement.innerHTML = '';
|
|
421
|
-
|
|
422
|
-
// Create a <pre> element
|
|
423
|
-
const preElement = document.createElement('pre');
|
|
424
|
-
|
|
425
|
-
// Set the text content of the <pre> element with formatted JSON
|
|
426
|
-
preElement.textContent = JSON.stringify(data, null, 2);
|
|
427
|
-
|
|
428
|
-
// Append the <pre> element to the #root element
|
|
429
|
-
rootElement.appendChild(preElement);
|
|
430
|
-
}
|
|
431
|
-
|
|
432
|
-
};
|
|
433
|
-
middlewares.forEach((middleware) => {
|
|
434
|
-
middleware(req, res);
|
|
435
|
-
});
|
|
436
|
-
|
|
437
|
-
route ? route.handler(req, res) : null;
|
|
438
|
-
}
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
}
|
|
442
|
-
|
|
443
|
-
window.VaderRouter = VaderRouter;
|
|
444
|
-
|
|
445
|
-
export default VaderRouter;
|
|
446
|
-
|
|
1
|
+
import{Component}from"./vader.js";let middlewares=[];class VaderRouter{constructor(e,t){this.routes=[],this.middlewares=[],this.errorMiddlewares=[],this.listeners=[],this.basePath=e}get(e,t){this.routes.push({path:e,handler:t,method:"get"})}use(e){this.middlewares.push(e)}listen(e,t){e||(e=Math.random().toString(36).substring(7)),window.onpopstate=async e=>{let t=window.location.pathname,r=`/${t.split("/")[1]}`;this.checkroute(t)||window.devMode||(t="/404");let n=(new DOMParser).parseFromString(await fetch(r,{cache:"reload"}).then((e=>e.text())),"text/html").documentElement;document.querySelector("#root").innerHTML=n.querySelector("#root").innerHTML,document.title=n.querySelector("title").innerHTML,document.querySelector('script[id="router"]').remove();let o=document.createElement("script");o.id="router",o.innerHTML=n.querySelector('script[id="router"]').innerHTML,o.setAttribute("type","module"),document.body.appendChild(o)},this.listeners.push(e),1===this.listeners.length?this.handleRoute(window.location.pathname):this.listeners.pop(),t&&t()}extractParams(e,t){const r=e.split("/").filter((e=>""!==e)),n=t.split("/").filter((e=>""!==e)),o={};return r.forEach(((e,t)=>{if(e.startsWith(":")){const r=e.slice(1);o[r]=n[t]}else if(e.startsWith("*")){n.slice(t).forEach(((e,t)=>{o[t]=e}))}})),o}extractQueryParams(e){const t=e.split("?")[1];if(!t)return{};const r={};return t.split("&").forEach((e=>{const[t,n]=e.split("=");r[t]=n})),r}checkroute(e){return this.routes.find((t=>{if(t.path===e)return!0;if(""===e&&"/"===t.path)return!0;if(e.includes("?")&&(e=e.split("?")[0]),t.path.includes("*")||t.path.includes(":")){const r=t.path.split("/").filter((e=>""!==e)),n=e.split("/").filter((e=>""!==e));if(r.length!==n.length&&!t.path.endsWith("*"))return!1;for(let e=0;e<r.length;e++){const t=r[e],o=n[e];if(!t.startsWith(":")&&!t.startsWith("*")&&t!==o)return!1}return!0}const r=this.extractParams(t.path,e);return Object.keys(r).length>0}))}handleRoute(e){let t=200,r=e,n=this.checkroute(e);n||(n=window.routes.find((e=>!e.url.includes("/404")||this.error||window.devMode?!(this.error||!e.url.includes("/404"))||void 0:(window.history.pushState({},"","/404"),window.dispatchEvent(new Event("popstate")),this.error=!0,!1))),t=n?200:404);const o=this.extractQueryParams(r),s=n&&n.path?this.extractParams(n.path,r):{};Object.keys(s).forEach((e=>{s[e]=s[e].split("?")?s[e].split("?")[0]:s[e]}));const i={headers:{},params:s,query:o,path:e,fileUrl:window.location.href.split(window.location.origin)[1],url:window.location.href,method:n?n.method:"get",pause:!1,timestamp:Date.now()};window.$CURRENT_URL=i.path,window.$FULL_URL=window.location.href.replace("#","");const a={status:t,log:e=>{void 0===e?console.log(`${i.path} ${i.method} ${a.status} ${i.timestamp}`):console.table({"Request Path":i.path,"Request Method":n.method,"Response Status":a.status,"Request Timestamp":i.timestamp})},refresh:()=>{this.handleRoute(window.location.pathname)},redirect:e=>{!e.startsWith("/")&&(e=`/${e}`),window.history.pushState({},"",e),window.dispatchEvent(new Event("popstate"))},render:async(e,t,r,n)=>{function i(e){return"function"==typeof e&&/^class\s/.test(Function.prototype.toString.call(e))}try{let n=new Component;if(i(e.default)){let t=new e.default;n.state=t.state,n=t}else{if(e.default.toString().includes("this.key"))throw new Error('Using this.key is not supported in functional components use the attribute key="a value" instead');n.key=e.default.toString().split('key="')[1]?e.default.toString().split('key="')[1].split('"')[0]:null;let i={key:n.key,render:()=>e.default.apply(n,[t,r]),request:t,response:r,params:s,queryParams:o,reset:n.reset.bind(n),onMount:n.onMount.bind(n),useState:null,router:{use:n.router.use.bind(n)},bindMount:n.bindMount.bind(n),memoize:n.memoize.bind(n),createComponent:n.createComponent.bind(n),isChild:!1,useState:n.useState.bind(n),parseStyle:n.parseStyle.bind(n),bind:n.bind.bind(n),useRef:n.useRef.bind(n),useReducer:n.useReducer.bind(n),onMount:n.onMount.bind(n),onUnmount:n.onUnmount.bind(n),hydrate:n.hydrate.bind(n)};n.render=i.render,n=i}if(!document.querySelector("#root"))throw new Error("Root element not found, please add an element with id root");n.reset(),n.components={},n.request=t,n.response=r,n.router.use&&!n.isChild?await new Promise((async o=>{if(i(e.default))if(i(e.default))switch(await n.router.use(t,r),t.pause){case!0:console.log("pausing",t.pause);let e=setInterval((()=>{t.pause?console.log("still pausing",t.pause):(clearInterval(e),o())}),1e3);break;case!1:o()}else o();else switch(await e.default.apply(n,[t,r]),await n.router.use(t,r),t.pause){case!0:let e=setInterval((()=>{t.pause?console.log("still pausing request",t.url):(clearInterval(e),o())}),1e3);break;case!1:o()}})):n.router.use&&n.isChild&&console.warn("Router.use() is not supported in child components");const a=await n.render();document.querySelector("#root").innerHTML!==a&&(document.querySelector("#root").innerHTML=a),n.bindMount(),n.onMount()}catch(e){console.error(e)}},setQuery:e=>{let t="";Object.keys(e).forEach(((r,n)=>{t+=`${0===n?"?":"&"}${r}=${e[r]}`}));let r=window.location.hash.split("?")[0];t=t.replace("/","-").replaceAll("/","-"),window.location.hash=`${r}${t}`},send:e=>{document.querySelector("#root").innerHTML=e},json:e=>{const t=document.querySelector("#root");t.innerHTML="";const r=document.createElement("pre");r.textContent=JSON.stringify(e,null,2),t.appendChild(r)}};middlewares.forEach((e=>{e(i,a)})),n&&n.handler(i,a)}}window.VaderRouter=VaderRouter;export default VaderRouter;
|
package/vader.js
CHANGED
|
@@ -726,13 +726,10 @@ async function Build() {
|
|
|
726
726
|
if (route.url.includes(':')) {
|
|
727
727
|
console.log('Route ' + route.url + ' is a dynamic route and will not be generated')
|
|
728
728
|
return
|
|
729
|
-
}
|
|
730
|
-
|
|
731
|
-
let equalparamroute = routes.map((e) => {
|
|
732
|
-
console.log(e.url, route.url)
|
|
729
|
+
}
|
|
730
|
+
let equalparamroute = routes.map((e) => {
|
|
733
731
|
if (e.url.includes(':')) {
|
|
734
|
-
let url = e.url.split('/:')[0]
|
|
735
|
-
console.log(url, route.url)
|
|
732
|
+
let url = e.url.split('/:')[0]
|
|
736
733
|
if (url && route.url === url) {
|
|
737
734
|
return e
|
|
738
735
|
} else {
|
|
@@ -752,6 +749,7 @@ async function Build() {
|
|
|
752
749
|
<meta charset="UTF-8">
|
|
753
750
|
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
|
754
751
|
<script type="module" id="meta">
|
|
752
|
+
window.history.pushState({}, '', '${route.url}')
|
|
755
753
|
window.module = await import('/${route.fileName.replace('.jsx', '.js')}')
|
|
756
754
|
let metadata = await module.$metadata
|
|
757
755
|
if(metadata && metadata.title){
|
|
@@ -832,8 +830,8 @@ async function Build() {
|
|
|
832
830
|
let port = Math.floor(Math.random() * (65535 - 49152 + 1) + 49152)
|
|
833
831
|
|
|
834
832
|
const server = http.createServer((req, res) => {
|
|
835
|
-
|
|
836
|
-
|
|
833
|
+
|
|
834
|
+
if (req.url === '/') {
|
|
837
835
|
res.writeHead(200, { 'Content-Type': 'text/html' });
|
|
838
836
|
res.end(document);
|
|
839
837
|
} else {
|
|
@@ -857,14 +855,14 @@ async function Build() {
|
|
|
857
855
|
globalThis.listen = true;
|
|
858
856
|
|
|
859
857
|
puppeteer.launch({
|
|
860
|
-
headless:
|
|
858
|
+
headless: "new", args: ['--no-sandbox', '--disable-setuid-sandbox'],
|
|
861
859
|
warning: false,
|
|
862
860
|
}).then(async (browser) => {
|
|
863
861
|
|
|
864
862
|
// remove /: from route
|
|
865
863
|
route.url = route.url.replaceAll(/\/:[a-zA-Z0-9_-]+/gs, '')
|
|
866
|
-
const page = await browser.newPage();
|
|
867
|
-
await page.goto(`http://localhost:${port}
|
|
864
|
+
const page = await browser.newPage();
|
|
865
|
+
await page.goto(`http://localhost:${port}/` , { waitUntil: 'networkidle2' });
|
|
868
866
|
await page.waitForSelector('#root');
|
|
869
867
|
await page.evaluate(() => {
|
|
870
868
|
document.getElementById('meta').remove()
|
package/runtime/vercel.json
DELETED