vaderjs 1.4.2-jpiml56 → 1.4.2-kml56
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 +4 -14
- package/binaries/Kalix/index.js +12 -20
- package/binaries/compiler/main.js +20 -99
- package/binaries/vader.js +0 -0
- package/binaries/watcher/hmr.js +0 -5
- package/client/runtime/index.js +417 -1
- package/client/runtime/router.js +235 -1
- package/config/index.ts +1 -20
- package/package.json +3 -2
- package/plugins/cloudflare/functions/index.js +0 -4
- package/plugins/cloudflare/toCopy/@server/Kalix/index.js +14 -62
- package/plugins/cloudflare/toCopy/src/client.js +432 -1
- package/plugins/cloudflare/toCopy/src/router.js +235 -1
- package/plugins/ssg/index.js +21 -94
- package/router/index.ts +10 -37
- package/server/index.js +2 -16
- package/plugins/tailwindcss/index.ts +0 -93
- /package/{vader_dev.js → vader.js} +0 -0
|
@@ -1 +1,235 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview - A simple router for vaderjs - Kuai
|
|
3
|
+
* @version - 1.0.0
|
|
4
|
+
*/
|
|
5
|
+
export class Kuai{
|
|
6
|
+
constructor(config = { container: '#app'}){
|
|
7
|
+
this.routes = [];
|
|
8
|
+
this.middleware = [];
|
|
9
|
+
this.container = config.container ? config.container : document.getElementById('app');
|
|
10
|
+
this.renderPlugins = [];
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
res = {
|
|
14
|
+
/**
|
|
15
|
+
* @description render text to the container
|
|
16
|
+
* @param {string} data
|
|
17
|
+
*/
|
|
18
|
+
text: (data) => {
|
|
19
|
+
this.container.innerHTML = data;
|
|
20
|
+
},
|
|
21
|
+
/**
|
|
22
|
+
* @method html
|
|
23
|
+
* @description render html to the container
|
|
24
|
+
* @param {any} data
|
|
25
|
+
* @returns
|
|
26
|
+
*/
|
|
27
|
+
html: (data) => {
|
|
28
|
+
switch(typeof data){
|
|
29
|
+
case 'function':
|
|
30
|
+
if(this.renderPlugins.length > 0){
|
|
31
|
+
this.renderPlugins.forEach((plugin) => {
|
|
32
|
+
if(plugin.for === 'html'){
|
|
33
|
+
console.log('Plugin', plugin)
|
|
34
|
+
plugin.plugin(data, this.container)
|
|
35
|
+
}
|
|
36
|
+
})
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
this.container.innerHTML = data();
|
|
40
|
+
break;
|
|
41
|
+
case 'string':
|
|
42
|
+
this.container.innerHTML = data;
|
|
43
|
+
break;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
},
|
|
47
|
+
/**
|
|
48
|
+
* @method json
|
|
49
|
+
* @description render json to the container
|
|
50
|
+
* @param {Object} data
|
|
51
|
+
*/
|
|
52
|
+
json: (data) => {
|
|
53
|
+
this.container.innerHTML = `<Oject data=${JSON.stringify(data)}></Object>`
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
req = {
|
|
57
|
+
/**
|
|
58
|
+
* @method navigate
|
|
59
|
+
* @description - navigate to a new route
|
|
60
|
+
* @param {string} path
|
|
61
|
+
*/
|
|
62
|
+
navigate: (path) => {
|
|
63
|
+
window.history.pushState({}, '', path);
|
|
64
|
+
let currentPath = this.match(window.location.pathname.replace('/index.html', ''))
|
|
65
|
+
if(currentPath){
|
|
66
|
+
this.currentRoute = currentPath.path
|
|
67
|
+
currentPath.callback(this.res, currentPath.params, this.extractQueryParams(window.location.search));
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
/**
|
|
71
|
+
* @method back
|
|
72
|
+
* @description - go back to the previous route
|
|
73
|
+
*/
|
|
74
|
+
back: () => {
|
|
75
|
+
window.history.back();
|
|
76
|
+
},
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* @method forward
|
|
80
|
+
* @description - go forward to the next route
|
|
81
|
+
* @returns {void}
|
|
82
|
+
* **/
|
|
83
|
+
forward: () => {
|
|
84
|
+
window.history.forward();
|
|
85
|
+
},
|
|
86
|
+
url: window.location
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* @private
|
|
90
|
+
*/
|
|
91
|
+
extractQueryParams(path){
|
|
92
|
+
let params = new URLSearchParams(path);
|
|
93
|
+
let query = {};
|
|
94
|
+
for(let param of params){
|
|
95
|
+
query[param[0]] = param[1];
|
|
96
|
+
}
|
|
97
|
+
return query;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* @private
|
|
101
|
+
*/
|
|
102
|
+
extractParams(routePath, currentPath){
|
|
103
|
+
const routeParts = routePath.split('/').filter((part) => part !== '');
|
|
104
|
+
const hashParts = currentPath.split('/').filter((part) => part !== '');
|
|
105
|
+
const params = {};
|
|
106
|
+
routeParts.forEach((part, index) => {
|
|
107
|
+
if (part.startsWith(':')) {
|
|
108
|
+
const paramName = part.slice(1);
|
|
109
|
+
params[paramName] = hashParts[index];
|
|
110
|
+
}else if(part.startsWith('*')){
|
|
111
|
+
let array = hashParts.slice(index)
|
|
112
|
+
array.forEach((i, index)=>{
|
|
113
|
+
params[index] = i
|
|
114
|
+
})
|
|
115
|
+
};
|
|
116
|
+
});
|
|
117
|
+
return params;
|
|
118
|
+
}
|
|
119
|
+
use(path, middleware){
|
|
120
|
+
this.middleware.push({path, middleware});
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* @method usePlugin
|
|
124
|
+
* @description - add a plugin to handle how the route should be rendered
|
|
125
|
+
* @param {Function} plugin
|
|
126
|
+
* @param {('html')} method
|
|
127
|
+
*/
|
|
128
|
+
usePlugin(plugin, method){
|
|
129
|
+
this.renderPlugins.push({plugin, for: method})
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* @method match
|
|
133
|
+
* @description - match a route to the current path and return the route object
|
|
134
|
+
* @param {string} route
|
|
135
|
+
* @returns {Object} - {path: string, callback: Function, params: Object}
|
|
136
|
+
*/
|
|
137
|
+
match(hash){
|
|
138
|
+
hash = hash.endsWith('/') ? hash.slice(0, -1) : hash;
|
|
139
|
+
hash.includes('index.html') ? hash = hash.replace('index.html', '') : null;
|
|
140
|
+
if(hash.includes('?')){
|
|
141
|
+
hash = hash.split('?')[0]
|
|
142
|
+
}
|
|
143
|
+
let route = this.routes.find((route) => {
|
|
144
|
+
if (route.path === hash) {
|
|
145
|
+
return true;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
if(hash === '' && route.path === '/'){
|
|
149
|
+
return true
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
if (route.path.includes('*') || route.path.includes(':')) {
|
|
154
|
+
const routeParts = route.path.split('/').filter((part) => part !== '');
|
|
155
|
+
const hashParts = hash.split('/').filter((part) => part !== '');
|
|
156
|
+
if(this.basePath){
|
|
157
|
+
hashParts.shift();
|
|
158
|
+
}
|
|
159
|
+
if (routeParts.length !== hashParts.length && !route.path.endsWith('*')) {
|
|
160
|
+
return false;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
for (let index = 0; index < routeParts.length; index++) {
|
|
164
|
+
const routePart = routeParts[index];
|
|
165
|
+
const hashPart = hashParts[index];
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
if (routePart.startsWith(':') || routePart.startsWith('*')) {
|
|
169
|
+
|
|
170
|
+
continue;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
if (routePart !== hashPart) {
|
|
174
|
+
return false;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
return true;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
});
|
|
183
|
+
if(route){
|
|
184
|
+
let params = this.extractParams(route.path, hash)
|
|
185
|
+
return { ...route, params}
|
|
186
|
+
}
|
|
187
|
+
return null;
|
|
188
|
+
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* @description - create a new route
|
|
193
|
+
* @param {string} path
|
|
194
|
+
* @param {Function} callback
|
|
195
|
+
*/
|
|
196
|
+
get(path, callback){
|
|
197
|
+
this.routes.push({path, callback});
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* @method listen
|
|
202
|
+
* @description - listen for route changes
|
|
203
|
+
*/
|
|
204
|
+
listen(){
|
|
205
|
+
let currentPath = this.match(window.location.pathname.replace('/index.html', ''))
|
|
206
|
+
if(currentPath){
|
|
207
|
+
this.middleware.forEach((middleware) => {
|
|
208
|
+
if(middleware.path === currentPath.path){
|
|
209
|
+
middleware.middleware();
|
|
210
|
+
}
|
|
211
|
+
});
|
|
212
|
+
this.currentRoute = currentPath.path
|
|
213
|
+
let obj = {
|
|
214
|
+
...this.res,
|
|
215
|
+
res: this.res,
|
|
216
|
+
req:{
|
|
217
|
+
...this.req,
|
|
218
|
+
params: (param) => currentPath.params[param]
|
|
219
|
+
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
currentPath.callback(obj);
|
|
223
|
+
}
|
|
224
|
+
window.onpopstate = () => {
|
|
225
|
+
let currentPath = this.match(window.location.pathname.replace('/index.html', ''))
|
|
226
|
+
if(currentPath){
|
|
227
|
+
this.currentRoute = currentPath.path
|
|
228
|
+
currentPath.callback(this.res, currentPath.params, this.extractQueryParams(window.location.search));
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
export default Kuai;
|
package/plugins/ssg/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as Bun from 'bun'
|
|
2
|
-
import {
|
|
2
|
+
import { Element, Document, DOMParser} from 'vaderjs/binaries/Kalix/index.js'
|
|
3
3
|
import { renderToString } from '../../server'
|
|
4
4
|
import fs from 'fs'
|
|
5
5
|
let routes = new Bun.FileSystemRouter({
|
|
@@ -11,77 +11,35 @@ async function generate(){
|
|
|
11
11
|
let config = await import(process.cwd() + '/vader.config.js').then((config) => { return config.default })
|
|
12
12
|
let provider = config?.host?.provider
|
|
13
13
|
|
|
14
|
-
let providerRoutes = []
|
|
15
|
-
Object.keys(routes).map((route) => {
|
|
16
|
-
if(route.includes('[')){
|
|
17
|
-
|
|
18
|
-
let root = Object.keys(routes).find((r) => {
|
|
19
|
-
return r === '/'
|
|
20
|
-
} )
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
let param = route.split('/[')[1].split(']')[0]
|
|
24
|
-
let p = {}
|
|
25
|
-
let existingParams = routes[root]?.params || []
|
|
26
|
-
existingParams.push({
|
|
27
|
-
isCatchAll: route.includes('[[catchall]]') ? true : false,
|
|
28
|
-
name: param,
|
|
29
|
-
file: routes[route],
|
|
30
|
-
baseFolder: route.split('[')[0]
|
|
31
|
-
})
|
|
32
|
-
p.file = routes[root]
|
|
33
|
-
p.params = existingParams
|
|
34
|
-
routes[root] = p
|
|
35
|
-
delete routes[route]
|
|
36
|
-
|
|
37
|
-
}
|
|
38
|
-
})
|
|
14
|
+
let providerRoutes = []
|
|
39
15
|
for(var i in routes){
|
|
40
|
-
let path = i
|
|
16
|
+
let path = i
|
|
41
17
|
let file = routes[i]
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
let dom = await renderToString(comp)
|
|
51
|
-
let isHtml = dom.includes('<html')
|
|
18
|
+
let comp = require(file).default
|
|
19
|
+
let document = new Document()
|
|
20
|
+
let div = document.createElement('div')
|
|
21
|
+
div.setAttribute('id', 'root')
|
|
22
|
+
let dom = await renderToString(comp)
|
|
23
|
+
div.setContent(dom)
|
|
24
|
+
dom = div.toString("outerHTML")
|
|
52
25
|
let folder = path.split('/pages')[0]
|
|
53
26
|
let newPath = process.cwd() + '/build' + folder + '/index.html'
|
|
54
|
-
let name = comp.name
|
|
27
|
+
let name = comp.name
|
|
55
28
|
file = file.replace(/\\/g, '/').replace('\/\/', '/').replace(process.cwd().replace(/\\/g, '/'), '').split('/pages')[1].replace('.tsx', '.js').replace('.jsx', '.js')
|
|
56
|
-
let isParamRoute =
|
|
29
|
+
let isParamRoute = path.includes('[')
|
|
57
30
|
let baseFolder = ''
|
|
58
31
|
if(isParamRoute){
|
|
59
|
-
|
|
60
|
-
baseFolder = i.split('[')[0]
|
|
32
|
+
baseFolder = path.split('[')[0]
|
|
61
33
|
let providerPath;
|
|
62
34
|
switch(true){
|
|
63
35
|
case provider === 'vercel':
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
providerRoutes.push({source: providerPath, destination: `${path}/index.html`})
|
|
67
|
-
break;
|
|
68
|
-
}
|
|
69
|
-
providerPath = `${baseFolder}:${route.name}`
|
|
70
|
-
providerRoutes.push({source: providerPath, dest: `/`})
|
|
36
|
+
providerPath = `${baseFolder}:${path.split('[')[1].split(']')[0]}`
|
|
37
|
+
providerRoutes.push({source: providerPath, dest: `${path}/index.html`})
|
|
71
38
|
break;
|
|
72
39
|
case provider === 'nginx':
|
|
73
40
|
providerPath = `RewriteRule ^${baseFolder.replace('/', '')}.*$ ${path}/index.html [L]`
|
|
74
41
|
providerRoutes.push(providerPath)
|
|
75
42
|
break;
|
|
76
|
-
case provider === 'cloudflare':
|
|
77
|
-
if(route.isCatchAll){
|
|
78
|
-
providerPath = `${baseFolder}/*`
|
|
79
|
-
providerRoutes.push({source: providerPath, destination: `${path}/index.html`})
|
|
80
|
-
break;
|
|
81
|
-
}
|
|
82
|
-
providerPath = `${baseFolder}/*`
|
|
83
|
-
providerRoutes.push({source: providerPath, destination: `${path}/index.html`})
|
|
84
|
-
break;
|
|
85
43
|
}
|
|
86
44
|
}else{
|
|
87
45
|
let providerPath;
|
|
@@ -97,48 +55,17 @@ async function generate(){
|
|
|
97
55
|
providerPath = `RewriteRule ^${path.replace('/', '')}/$ ${path}/index.html [L]`
|
|
98
56
|
providerRoutes.push(providerPath)
|
|
99
57
|
break;
|
|
100
|
-
|
|
101
58
|
|
|
102
59
|
}
|
|
103
|
-
}
|
|
104
|
-
dom =
|
|
105
|
-
<script type="module">
|
|
106
|
-
|
|
60
|
+
}
|
|
61
|
+
dom = dom + `
|
|
62
|
+
<script type="module">
|
|
107
63
|
import { render } from '/src/client.js'
|
|
108
|
-
|
|
109
|
-
if(${name}.default){
|
|
110
|
-
${name} = ${name}.default
|
|
111
|
-
}else{
|
|
112
|
-
let keys = Object.keys(${name})
|
|
113
|
-
${name} = ${name}[keys[0]]
|
|
114
|
-
}
|
|
64
|
+
import ${name} from '/pages/${file.replace(process.cwd(), '')}'
|
|
115
65
|
import Kuai from '/src/router.js'
|
|
116
66
|
let kuai = new Kuai()
|
|
117
|
-
${
|
|
118
|
-
routes[i].params ?
|
|
119
|
-
routes[i].params.map((param) => {
|
|
120
|
-
let name = param.name
|
|
121
|
-
let file = param.file.replace(/\\/g, '/').replace('\/\/', '/').replace(process.cwd().replace(/\\/g, '/'), '').split('/pages')[1].replace('.tsx', '.js').replace('.jsx', '.js')
|
|
122
|
-
return `
|
|
123
|
-
// handle if default or named
|
|
124
|
-
let ${name} = await import('/pages/${file}')
|
|
125
|
-
if(${name}.default){
|
|
126
|
-
${name} = ${name}.default
|
|
127
|
-
}else{
|
|
128
|
-
let keys = Object.keys(${name})
|
|
129
|
-
${name} = ${name}[keys[0]]
|
|
130
|
-
}
|
|
131
|
-
kuai.get('${param.baseFolder}:${name}', (c) => {
|
|
132
|
-
render(${name}, ${
|
|
133
|
-
isHtml ? `document.documentElement`: `document.body.firstChild`
|
|
134
|
-
}, c.req, c.res)
|
|
135
|
-
})`
|
|
136
|
-
}).join('\n') : ''
|
|
137
|
-
}
|
|
138
67
|
kuai.get('${path}', (c) => {
|
|
139
|
-
render(${name},
|
|
140
|
-
isHtml ? `document.documentElement`: `document.body.firstChild`
|
|
141
|
-
}, c.req, c.res)
|
|
68
|
+
render(${name}, document.getElementById('root'), c.req, c.res)
|
|
142
69
|
})
|
|
143
70
|
|
|
144
71
|
kuai.listen()
|
|
@@ -173,7 +100,7 @@ Header add x-powered-by "vaderjs"
|
|
|
173
100
|
</IfModule>
|
|
174
101
|
`
|
|
175
102
|
fs.writeFileSync(process.cwd() + '/.htaccess', full)
|
|
176
|
-
break;
|
|
103
|
+
break;
|
|
177
104
|
}
|
|
178
105
|
console.log(`\x1b[32mSuccess\x1b[0m - Static files generated`)
|
|
179
106
|
|
package/router/index.ts
CHANGED
|
@@ -56,11 +56,7 @@ function spawn_ssr_server(config: any ){
|
|
|
56
56
|
let fileType = handleContentTypes(file)
|
|
57
57
|
if(fs.existsSync(file)){
|
|
58
58
|
let content = await Bun.file(file).text()
|
|
59
|
-
|
|
60
|
-
const compressed = Bun.gzipSync(data);
|
|
61
|
-
return new Response(compressed, {status: 200, headers: {'Content-Type': fileType, 'x-powered-by': 'Vader',
|
|
62
|
-
'Content-Encoding':'gzip',
|
|
63
|
-
...config?.routes.find(route => route.pathname === "*" || route.pathname === url.pathname)?.headers}})
|
|
59
|
+
return new Response(content, {status: 200, headers: {'Content-Type': fileType, 'x-powered-by': 'Vader'}})
|
|
64
60
|
}
|
|
65
61
|
}
|
|
66
62
|
let routeMatch = routesRouter.match(url.pathname)
|
|
@@ -80,7 +76,6 @@ function spawn_ssr_server(config: any ){
|
|
|
80
76
|
if(response instanceof Response){
|
|
81
77
|
// set x-powered-by header
|
|
82
78
|
response.headers.set('x-powered-by', 'Vader')
|
|
83
|
-
response.headers.set('Content-Type', 'text/html')
|
|
84
79
|
return response
|
|
85
80
|
}
|
|
86
81
|
throw new Error(`Route ${routeMatch.filePath.split('/routes')[1]} did not return a response in file ${routeMatch.filePath}`)
|
|
@@ -94,12 +89,11 @@ function spawn_ssr_server(config: any ){
|
|
|
94
89
|
}
|
|
95
90
|
}
|
|
96
91
|
let server = Bun.serve({
|
|
97
|
-
port: config
|
|
98
|
-
hostname: config
|
|
92
|
+
port: config.env.PORT || 3000,
|
|
93
|
+
hostname: config.host.hostname || 'localhost',
|
|
99
94
|
reusePort: true,
|
|
100
95
|
lowMemoryMode: true,
|
|
101
96
|
development: false,
|
|
102
|
-
...(config?.Router?.tls && {tls: {cert: config.Router.tls.cert, key: config.Router.tls.key}}),
|
|
103
97
|
websocket: {
|
|
104
98
|
message(event){
|
|
105
99
|
|
|
@@ -143,42 +137,21 @@ function spawnServer(config: any){
|
|
|
143
137
|
if(url.pathname.includes('.')){
|
|
144
138
|
url.pathname = url.pathname.replace('/\/', '/')
|
|
145
139
|
url.pathname = url.pathname.replace('/build/', '')
|
|
146
|
-
|
|
147
|
-
|
|
140
|
+
if(url.pathname.includes('/build')){
|
|
141
|
+
url.pathname = url.pathname.replace('/build', '')
|
|
142
|
+
}
|
|
143
|
+
let file = process.cwd() + '/build' + url.pathname
|
|
148
144
|
let fileType = handleContentTypes(file)
|
|
149
145
|
if(fs.existsSync(file)){
|
|
150
146
|
let content = await Bun.file(file).text()
|
|
151
|
-
|
|
152
|
-
const compressed = Bun.gzipSync(data);
|
|
153
|
-
|
|
154
|
-
return new Response(compressed, {status: 200, headers: {'Content-Type': fileType, 'x-powered-by': 'Vader', 'x-powered-by': 'Vader',
|
|
155
|
-
'Content-Encoding':'gzip',
|
|
156
|
-
'Accept-Encoding': 'gzip, deflate, br','Connection': 'keep-alive', 'Cache-Control': 'no-cache', 'Pragma': 'no-cache', 'Expires': '0', ...config?.Router?.headers}})
|
|
147
|
+
return new Response(content, {status: 200, headers: {'Content-Type': fileType, 'x-powered-by': 'Vader'}})
|
|
157
148
|
}
|
|
158
149
|
}
|
|
159
150
|
let route = router.match(url.pathname)
|
|
160
151
|
if(route){
|
|
161
|
-
let isParamRoute = route.filePath.includes('[') && route.filePath.includes(']')
|
|
162
152
|
let path = route.filePath.split('/pages')[1].replace('.jsx', '.js').replace('.tsx', '.js').replace('.ts', '.js')
|
|
163
|
-
path = isParamRoute ? 'index.html' : path
|
|
164
153
|
let html = fs.readFileSync(process.cwd() + `/build/${path.replace('.js', '.html')}`).toString()
|
|
165
|
-
html
|
|
166
|
-
<script>
|
|
167
|
-
let ws = new WebSocket('ws://${config.host.hostname || 'localhost'}:${config.env.PORT || 3000}')
|
|
168
|
-
ws.onmessage = function(event){
|
|
169
|
-
console.log(event.data)
|
|
170
|
-
}
|
|
171
|
-
ws.onclose = function(event){
|
|
172
|
-
window.location.reload()
|
|
173
|
-
}
|
|
174
|
-
</script>
|
|
175
|
-
`
|
|
176
|
-
const data = Buffer.from(html, 'utf-8');
|
|
177
|
-
const compressed = Bun.gzipSync(data);
|
|
178
|
-
return new Response(compressed, {status: 200, headers: {'Content-Type': 'text/html', 'x-powered-by': 'Vader',
|
|
179
|
-
'Content-Encoding':'gzip',
|
|
180
|
-
'Accept-Encoding': 'gzip, deflate, br','Connection': 'keep-alive', 'Cache-Control': 'no-cache', 'Pragma': 'no-cache', 'Expires': '0',
|
|
181
|
-
...config?.Router?.headers}})
|
|
154
|
+
return new Response(html, {status: 200, headers: {'Content-Type': 'text/html', 'x-powered-by': 'Vader'}})
|
|
182
155
|
}
|
|
183
156
|
return new Response('Not Found', {status: 404})
|
|
184
157
|
}
|
|
@@ -198,7 +171,7 @@ export default {
|
|
|
198
171
|
if(!globalThis.isListening){
|
|
199
172
|
let config = require(process.cwd() + '/vader.config.js').default
|
|
200
173
|
if(process.env.mode === 'production'){
|
|
201
|
-
console.log(
|
|
174
|
+
console.log(`Listening at - http://${config.host.hostname}:${config.env.PORT}`)
|
|
202
175
|
spawnServer(config)
|
|
203
176
|
}
|
|
204
177
|
config?.env?.SSR ? spawn_ssr_server(config ) : spawnServer(config)
|
package/server/index.js
CHANGED
|
@@ -47,22 +47,8 @@ class Component {
|
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
}
|
|
50
|
-
export async function renderToString(element, args = []) {
|
|
51
|
-
|
|
52
|
-
globalThis.preRender = true
|
|
53
|
-
let data = typeof element === 'function' ? await element(args) : element
|
|
54
|
-
if(data?.tagName === 'html'){
|
|
55
|
-
let body = data.querySelector('body') || new Document().createElement('body')
|
|
56
|
-
let innerHTML = body.innerHTML
|
|
57
|
-
innerHTML = `${innerHTML}`
|
|
58
|
-
body.tagName = 'div'
|
|
59
|
-
body.setAttribute('id', 'root')
|
|
60
|
-
body.innerHTML = innerHTML
|
|
61
|
-
data.removeChild(data.querySelector('body'))
|
|
62
|
-
data.appendChild(body)
|
|
63
|
-
}else if(data){
|
|
64
|
-
data.firstChild.setAttribute('id', 'root')
|
|
65
|
-
}
|
|
50
|
+
export async function renderToString(element, args = []) {
|
|
51
|
+
let data = typeof element === 'function' ? await element(args) : element
|
|
66
52
|
let doc = new Document()
|
|
67
53
|
let el = doc.createElement(data)
|
|
68
54
|
|
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
//@ts-nocheck
|
|
2
|
-
function checkIFtailwindInstalled() {
|
|
3
|
-
try {
|
|
4
|
-
require.resolve('tailwindcss');
|
|
5
|
-
return true;
|
|
6
|
-
} catch (e) {
|
|
7
|
-
return false;
|
|
8
|
-
}
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
export default {
|
|
13
|
-
name: "tailwind",
|
|
14
|
-
description: "A plugin to install tailwindcss",
|
|
15
|
-
once: true,
|
|
16
|
-
init: async () => {
|
|
17
|
-
let config = require(process.cwd() + "/vader.config.js").default;
|
|
18
|
-
const fs = require("fs");
|
|
19
|
-
const path = require("path");
|
|
20
|
-
const { exec} = require("child_process");
|
|
21
|
-
const tailwindConfig = `
|
|
22
|
-
/** @type {import('tailwindcss').Config} */
|
|
23
|
-
module.exports = {
|
|
24
|
-
content: ['./src/**/*.{jsx,tsx,js,ts}', './pages/**/*.{jsx,tsx,js,ts}', './components/**/*.{jsx,tsx,js,ts}'],
|
|
25
|
-
theme: {
|
|
26
|
-
${
|
|
27
|
-
config?.tailwind?.theme ? JSON.stringify(config.tailwind.theme, null, 2) : ``
|
|
28
|
-
}
|
|
29
|
-
},
|
|
30
|
-
plugins: [
|
|
31
|
-
${
|
|
32
|
-
config?.tailwind?.plugins ? config?.tailwind?.plugins.map((plugin) => {
|
|
33
|
-
return `require('${plugin}')`
|
|
34
|
-
}).join(",") : ``
|
|
35
|
-
}
|
|
36
|
-
]
|
|
37
|
-
}
|
|
38
|
-
`;
|
|
39
|
-
fs.writeFileSync(
|
|
40
|
-
path.join(process.cwd(), "tailwind.config.js"),
|
|
41
|
-
tailwindConfig
|
|
42
|
-
);
|
|
43
|
-
if (!checkIFtailwindInstalled()) {
|
|
44
|
-
console.log(`\x1b[36mwait \x1b[0m - installing tailwindcss & ${config?.tailwind?.plugins ? config?.tailwind?.plugins.length + " plugins" : ""} (First time only)`);
|
|
45
|
-
let npmPath = process.platform === "win32" ? "npm.cmd" : "npm";
|
|
46
|
-
Bun.spawnSync({
|
|
47
|
-
cmd: [npmPath, "install", "tailwindcss", "postcss", "autoprefixer" , ...config?.tailwind?.plugins || []],
|
|
48
|
-
cwd: process.cwd(),
|
|
49
|
-
stderr: "inherit",
|
|
50
|
-
})
|
|
51
|
-
console.log(`\x1b[32msuccess \x1b[0m - tailwindcss installed`)
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
const postcssConfig = `
|
|
55
|
-
module.exports = {
|
|
56
|
-
plugins: {
|
|
57
|
-
tailwindcss: {},
|
|
58
|
-
autoprefixer: {},
|
|
59
|
-
},
|
|
60
|
-
}
|
|
61
|
-
`;
|
|
62
|
-
fs.mkdirSync(path.join(process.cwd(), "src/public/styles"), {
|
|
63
|
-
recursive: true,
|
|
64
|
-
});
|
|
65
|
-
fs.writeFileSync(
|
|
66
|
-
path.join(process.cwd(), "src/public/styles/tailwind.css"),
|
|
67
|
-
`@import 'tailwindcss/base'; @import 'tailwindcss/components'; @import 'tailwindcss/utilities';`
|
|
68
|
-
);
|
|
69
|
-
fs.writeFileSync(
|
|
70
|
-
path.join(process.cwd(), "postcss.config.js"),
|
|
71
|
-
postcssConfig
|
|
72
|
-
);
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
if(!fs.existsSync(path.join(process.cwd(), "src/public/styles/tailwind.css"))){
|
|
76
|
-
fs.mkdirSync(path.join(process.cwd(), "src/public/styles"), {
|
|
77
|
-
recursive: true,
|
|
78
|
-
});
|
|
79
|
-
fs.writeFileSync(
|
|
80
|
-
path.join(process.cwd(), "src/public/styles/tailwind.css"),
|
|
81
|
-
`@import 'tailwindcss/base'; @import 'tailwindcss/components'; @import 'tailwindcss/utilities';`
|
|
82
|
-
);
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
let cmd = process.platform === "win32" ? "npx.cmd" : "npx";
|
|
86
|
-
Bun.spawn({
|
|
87
|
-
cmd: [ cmd, "tailwindcss", process.cwd() + '/tailwind.config.js' , "-i", "src/public/styles/tailwind.css", "-o", config?.tailwind?.output || "public/styles/tailwind.css", "--minify"],
|
|
88
|
-
cwd: process.cwd(),
|
|
89
|
-
stdin: "inherit",
|
|
90
|
-
stderr: "inherit",
|
|
91
|
-
});
|
|
92
|
-
},
|
|
93
|
-
}
|
|
File without changes
|