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/{main.js → index.js}
RENAMED
|
@@ -1,337 +1,378 @@
|
|
|
1
|
-
#!/usr/bin/env bun
|
|
2
|
-
|
|
3
|
-
import ansiColors from 'ansi-colors'
|
|
4
|
-
import { Glob } from 'bun'
|
|
5
|
-
const args = Bun.argv.slice(2)
|
|
6
|
-
import fs from 'fs'
|
|
7
|
-
import path from 'path'
|
|
8
|
-
if (!fs.existsSync(process.cwd() + '/app')) {
|
|
9
|
-
console.error(`App directory not found in ${process.cwd()}/app`)
|
|
10
|
-
process.exit(1)
|
|
11
|
-
}
|
|
12
|
-
if (!fs.existsSync(process.cwd() + '/public')) {
|
|
13
|
-
fs.mkdirSync(process.cwd() + '/public')
|
|
14
|
-
}
|
|
15
|
-
const mode = args.includes('dev') ? 'development' : args.includes('prod') || args.includes('build') ? 'production' : null
|
|
16
|
-
if (!mode) {
|
|
17
|
-
console.log(`
|
|
18
|
-
Usage:
|
|
19
|
-
bun vaderjs dev - Start development server output in dist/
|
|
20
|
-
bun vaderjs prod - Build for production output in dist/
|
|
21
|
-
`)
|
|
22
|
-
process.exit(1)
|
|
23
|
-
}
|
|
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
|
-
|
|
33
|
-
let start = Date.now()
|
|
34
|
-
console.log(`Starting build at ${new Date().toLocaleTimeString()}`)
|
|
35
|
-
let { port, host, host_provider } = require(process.cwd() + '/config').default
|
|
36
|
-
if (host_provider === 'apache' && mode === 'development') {
|
|
37
|
-
console.warn('Note: SSR will not work with Apache')
|
|
38
|
-
}
|
|
39
|
-
if (!fs.existsSync(process.cwd() + '/jsconfig.json')) {
|
|
40
|
-
let json = {
|
|
41
|
-
"compilerOptions": {
|
|
42
|
-
"jsx": "react",
|
|
43
|
-
"jsxFactory": "e",
|
|
44
|
-
"jsxFragmentFactory": "Fragment",
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
await Bun.write(process.cwd() + '/jsconfig.json', JSON.stringify(json, null, 4))
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
const bindes = []
|
|
51
|
-
|
|
52
|
-
const handleReplacements = (code, file) => {
|
|
53
|
-
let lines = code.split('\n')
|
|
54
|
-
let newLines = []
|
|
55
|
-
for (let line of lines) {
|
|
56
|
-
let hasImport = line.includes('import')
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
fs.
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
routes.
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
if (!fs.existsSync(process.cwd() + '/dev/
|
|
146
|
-
fs.
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
let
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
|
|
3
|
+
import ansiColors from 'ansi-colors'
|
|
4
|
+
import { Glob } from 'bun'
|
|
5
|
+
const args = Bun.argv.slice(2)
|
|
6
|
+
import fs from 'fs'
|
|
7
|
+
import path from 'path'
|
|
8
|
+
if (!fs.existsSync(process.cwd() + '/app')) {
|
|
9
|
+
console.error(`App directory not found in ${process.cwd()}/app`)
|
|
10
|
+
process.exit(1)
|
|
11
|
+
}
|
|
12
|
+
if (!fs.existsSync(process.cwd() + '/public')) {
|
|
13
|
+
fs.mkdirSync(process.cwd() + '/public')
|
|
14
|
+
}
|
|
15
|
+
const mode = args.includes('dev') ? 'development' : args.includes('prod') || args.includes('build') ? 'production' : null
|
|
16
|
+
if (!mode) {
|
|
17
|
+
console.log(`
|
|
18
|
+
Usage:
|
|
19
|
+
bun vaderjs dev - Start development server output in dist/
|
|
20
|
+
bun vaderjs prod - Build for production output in dist/
|
|
21
|
+
`)
|
|
22
|
+
process.exit(1)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
console.log(
|
|
26
|
+
`VaderJS - v${require(process.cwd() + '/node_modules/vaderjs/package.json').version} 🚀
|
|
27
|
+
Mode: ${mode}
|
|
28
|
+
SSR: ${require(process.cwd() + '/vader.config.ts').default.ssr ? 'Enabled' : 'Disabled'}
|
|
29
|
+
PORT: ${require(process.cwd() + '/vader.config.ts').default.port || 8080}
|
|
30
|
+
`
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
let start = Date.now()
|
|
34
|
+
console.log(`Starting build at ${new Date().toLocaleTimeString()}`)
|
|
35
|
+
let { port, host, host_provider } = require(process.cwd() + '/vader.config.ts').default
|
|
36
|
+
if (host_provider === 'apache' && mode === 'development') {
|
|
37
|
+
console.warn('Note: SSR will not work with Apache')
|
|
38
|
+
}
|
|
39
|
+
if (!fs.existsSync(process.cwd() + '/jsconfig.json')) {
|
|
40
|
+
let json = {
|
|
41
|
+
"compilerOptions": {
|
|
42
|
+
"jsx": "react",
|
|
43
|
+
"jsxFactory": "e",
|
|
44
|
+
"jsxFragmentFactory": "Fragment",
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
await Bun.write(process.cwd() + '/jsconfig.json', JSON.stringify(json, null, 4))
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const bindes = []
|
|
51
|
+
|
|
52
|
+
const handleReplacements = (code, file) => {
|
|
53
|
+
let lines = code.split('\n')
|
|
54
|
+
let newLines = []
|
|
55
|
+
for (let line of lines) {
|
|
56
|
+
let hasImport = line.includes('import')
|
|
57
|
+
|
|
58
|
+
if (hasImport && line.includes('.css')) {
|
|
59
|
+
try {
|
|
60
|
+
let url = path.join('/' + line.split("'")[1])
|
|
61
|
+
let css = fs.readFileSync(process.cwd() + url, 'utf-8')
|
|
62
|
+
line = '';
|
|
63
|
+
if (!bindes.includes(`<link rel="stylesheet" href="${url}">`)) {
|
|
64
|
+
bindes.push(`<link rel="stylesheet" href="${url}">`)
|
|
65
|
+
}
|
|
66
|
+
fs.mkdirSync(process.cwd() + '/dist' + path.dirname(url), { recursive: true })
|
|
67
|
+
fs.writeFileSync(process.cwd() + '/dist' + url, css)
|
|
68
|
+
} catch (error) {
|
|
69
|
+
console.error(error)
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
if (line.toLowerCase().includes('genkey()')) {
|
|
73
|
+
line = line.toLowerCase().replace('genkey()', `this.key = "${crypto.randomUUID()}"`)
|
|
74
|
+
}
|
|
75
|
+
if (!hasImport && line.includes('useFetch')) {
|
|
76
|
+
line = line.replace('useFetch', 'this.useFetch')
|
|
77
|
+
}
|
|
78
|
+
if (!hasImport && line.includes('useState') && line.includes('[')) {
|
|
79
|
+
let key = line.split(',')[0].split('[')[1].replace(' ', '')
|
|
80
|
+
let b4 = line
|
|
81
|
+
b4 = line.replace('useState(', `this.useState('${key}',`)
|
|
82
|
+
line = b4
|
|
83
|
+
}
|
|
84
|
+
if (!hasImport && line.includes('useAsyncState')) {
|
|
85
|
+
let key = line.split(',')[0].split('[')[1].replace(' ', '')
|
|
86
|
+
let b4 = line
|
|
87
|
+
b4 = line.replace('useAsyncState(', `this.useAsyncState('${key}',`)
|
|
88
|
+
line = b4
|
|
89
|
+
}
|
|
90
|
+
if (!hasImport && line.includes('useEffect')) {
|
|
91
|
+
let b4 = line
|
|
92
|
+
b4 = line.replace('useEffect(', `this.useEffect(`)
|
|
93
|
+
line = b4
|
|
94
|
+
}
|
|
95
|
+
if (!hasImport && line.includes('useRef')) {
|
|
96
|
+
let b4 = line
|
|
97
|
+
let key = line.split(' ')[1].split('=')[0]
|
|
98
|
+
b4 = line.replace('useRef(', `this.useRef('${key}',`)
|
|
99
|
+
line = b4
|
|
100
|
+
}
|
|
101
|
+
newLines.push(line)
|
|
102
|
+
}
|
|
103
|
+
let c = newLines.join('\n')
|
|
104
|
+
return c
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
async function generateApp() {
|
|
109
|
+
// remove files from dist
|
|
110
|
+
if (mode === 'development') {
|
|
111
|
+
fs.rmdirSync(process.cwd() + '/dist', { recursive: true })
|
|
112
|
+
} else {
|
|
113
|
+
fs.mkdirSync(process.cwd() + '/dist', { recursive: true })
|
|
114
|
+
}
|
|
115
|
+
return new Promise(async (resolve, reject) => {
|
|
116
|
+
let routes = new Bun.FileSystemRouter({
|
|
117
|
+
dir: process.cwd() + '/app',
|
|
118
|
+
style: 'nextjs'
|
|
119
|
+
})
|
|
120
|
+
routes.reload()
|
|
121
|
+
globalThis.routes = routes.routes
|
|
122
|
+
Object.keys(routes.routes).forEach(async (route) => {
|
|
123
|
+
|
|
124
|
+
let r = routes.routes[route]
|
|
125
|
+
let code = await Bun.file(r).text()
|
|
126
|
+
code = handleReplacements(code)
|
|
127
|
+
let size = code.length / 1024
|
|
128
|
+
r = r.replace(process.cwd().replace(/\\/g, '/') + '/app', '')
|
|
129
|
+
r = r.replace('.jsx', '.js')
|
|
130
|
+
fs.mkdirSync(path.dirname(process.cwd() + '/dist/' + r), { recursive: true })
|
|
131
|
+
fs.writeFileSync(process.cwd() + '/dist/' + path.dirname(r) + '/' + path.basename(r), `
|
|
132
|
+
let route = window.location.pathname.split('/').filter(v => v !== '')
|
|
133
|
+
let params = {
|
|
134
|
+
${Object.keys(routes.match(route).params || {}).length > 0 ? Object.keys(routes.match(route).params || {}).map(p => {
|
|
135
|
+
return `${p}: route[${Object.keys(routes.match(route).params).indexOf(p)}]`
|
|
136
|
+
}).join(',') : ""}
|
|
137
|
+
}
|
|
138
|
+
\n${code}
|
|
139
|
+
`)
|
|
140
|
+
fs.mkdirSync(process.cwd() + '/dev', { recursive: true })
|
|
141
|
+
if (!fs.existsSync(process.cwd() + '/dev/bundler.js')) {
|
|
142
|
+
fs.copyFileSync(require.resolve('vaderjs/bundler/index.js'), process.cwd() + '/dev/bundler.js')
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
if (!fs.existsSync(process.cwd() + '/dev/readme.md')) {
|
|
146
|
+
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`)
|
|
147
|
+
}
|
|
148
|
+
fs.mkdirSync(process.cwd() + '/dist/src/vader', { recursive: true })
|
|
149
|
+
fs.writeFileSync(process.cwd() + '/dist/src/vader/index.js', await new Bun.Transpiler({
|
|
150
|
+
loader: 'ts',
|
|
151
|
+
}).transformSync(await Bun.file(require.resolve('vaderjs')).text()))
|
|
152
|
+
Bun.spawn({
|
|
153
|
+
cmd: ['bun', 'run', './dev/bundler.js'],
|
|
154
|
+
cwd: process.cwd(),
|
|
155
|
+
stdout: 'inherit',
|
|
156
|
+
env: {
|
|
157
|
+
ENTRYPOINT: path.join(process.cwd() + '/dist/' + path.dirname(r) + '/' + path.basename(r)),
|
|
158
|
+
ROOT: process.cwd() + '/app/',
|
|
159
|
+
OUT: path.dirname(r),
|
|
160
|
+
file: process.cwd() + '/dist/' + path.dirname(r) + '/' + path.basename(r),
|
|
161
|
+
DEV: mode === 'development',
|
|
162
|
+
size,
|
|
163
|
+
filePath: r,
|
|
164
|
+
INPUT: `../app/${r.replace('.js', '.jsx')}`,
|
|
165
|
+
},
|
|
166
|
+
onExit({ exitCode: code }) {
|
|
167
|
+
if (code === 0) {
|
|
168
|
+
console.log(`Built ${r} in ${Date.now() - start}ms`)
|
|
169
|
+
resolve()
|
|
170
|
+
} else {
|
|
171
|
+
reject()
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
})
|
|
175
|
+
|
|
176
|
+
})
|
|
177
|
+
|
|
178
|
+
switch (host_provider) {
|
|
179
|
+
case 'vercel':
|
|
180
|
+
|
|
181
|
+
let vercelData = {
|
|
182
|
+
rewrites: []
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
for (let route in routes.routes) {
|
|
186
|
+
let { filePath, kind, name, params, pathname, query } = routes.match(route)
|
|
187
|
+
let r = route
|
|
188
|
+
|
|
189
|
+
if (r.includes('[')) {
|
|
190
|
+
r = r.replaceAll('[', ':').replaceAll(']', '')
|
|
191
|
+
}
|
|
192
|
+
if (r === '/') {
|
|
193
|
+
continue
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
vercelData.rewrites.push({
|
|
197
|
+
source: r,
|
|
198
|
+
destination: `${path.dirname(routes.routes[route]).replace(process.cwd().replace(/\\/g, '/') + '/app', '')}/index.html`
|
|
199
|
+
})
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
fs.writeFileSync(process.cwd() + '/vercel.json', JSON.stringify(vercelData, null, 4))
|
|
203
|
+
break;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
})
|
|
207
|
+
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
await generateApp()
|
|
211
|
+
function handleFiles() {
|
|
212
|
+
return new Promise(async (resolve, reject) => {
|
|
213
|
+
try {
|
|
214
|
+
let glob = new Glob('public/**/*')
|
|
215
|
+
for await (var i of glob.scan()) {
|
|
216
|
+
let file = i
|
|
217
|
+
fs.mkdirSync(path.join(process.cwd() + '/dist', path.dirname(file)), { recursive: true })
|
|
218
|
+
if (fs.existsSync(path.join(process.cwd() + '/dist', file))) {
|
|
219
|
+
fs.rmSync(path.join(process.cwd() + '/dist', file))
|
|
220
|
+
}
|
|
221
|
+
fs.copyFileSync(file, path.join(process.cwd() + '/dist', file))
|
|
222
|
+
}
|
|
223
|
+
let glob2 = new Glob('src/**/*')
|
|
224
|
+
for await (var i of glob2.scan()) {
|
|
225
|
+
var file = i
|
|
226
|
+
fs.mkdirSync(path.join(process.cwd() + '/dist', path.dirname(file)), { recursive: true })
|
|
227
|
+
// turn jsx to js
|
|
228
|
+
if (file.includes('.jsx')) {
|
|
229
|
+
let code = await Bun.file(file).text()
|
|
230
|
+
code = handleReplacements(code)
|
|
231
|
+
|
|
232
|
+
file = file.replace('.jsx', '.js')
|
|
233
|
+
fs.writeFileSync(path.join(process.cwd() + '/dist', file.replace('.jsx', '.js')), code)
|
|
234
|
+
await Bun.spawn({
|
|
235
|
+
cmd: ['bun', 'run', './dev/bundler.js'],
|
|
236
|
+
cwd: process.cwd(),
|
|
237
|
+
stdout: 'inherit',
|
|
238
|
+
env: {
|
|
239
|
+
ENTRYPOINT: path.join(process.cwd() + '/dist/' + file.replace('.jsx', '.js')),
|
|
240
|
+
ROOT: process.cwd() + '/app/',
|
|
241
|
+
OUT: path.dirname(file),
|
|
242
|
+
file: process.cwd() + '/dist/' + file.replace('.jsx', '.js'),
|
|
243
|
+
DEV: mode === 'development',
|
|
244
|
+
size: code.length / 1024,
|
|
245
|
+
filePath: file.replace('.jsx', '.js'),
|
|
246
|
+
INPUT: path.join(process.cwd() , file.replace('.js', '.jsx')),
|
|
247
|
+
},
|
|
248
|
+
onExit({ exitCode: code }) {
|
|
249
|
+
if (code === 0) {
|
|
250
|
+
resolve()
|
|
251
|
+
} else {
|
|
252
|
+
reject()
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
})
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
resolve()
|
|
261
|
+
} catch (error) {
|
|
262
|
+
reject(error)
|
|
263
|
+
}
|
|
264
|
+
})
|
|
265
|
+
}
|
|
266
|
+
await handleFiles()
|
|
267
|
+
globalThis.clients = []
|
|
268
|
+
|
|
269
|
+
if (mode === 'development') {
|
|
270
|
+
const watcher = fs.watch(path.join(process.cwd() + '/app'), { recursive: true })
|
|
271
|
+
const publicWatcher = fs.watch(path.join(process.cwd() + '/public'), { recursive: true })
|
|
272
|
+
const srcWatcher = fs.watch(path.join(process.cwd() + '/src'), { recursive: true })
|
|
273
|
+
let isBuilding = false; // Flag to track build status
|
|
274
|
+
|
|
275
|
+
// Initialize a variable to hold the timeout ID
|
|
276
|
+
let debounceTimeout;
|
|
277
|
+
|
|
278
|
+
// Function to handle file changes with debounce
|
|
279
|
+
const handleFileChangeDebounced = async () => {
|
|
280
|
+
clearTimeout(debounceTimeout);
|
|
281
|
+
debounceTimeout = setTimeout(async () => {
|
|
282
|
+
if (!isBuilding) { // Check if not already building
|
|
283
|
+
isBuilding = true; // Set build flag to true
|
|
284
|
+
try {
|
|
285
|
+
await generateApp();
|
|
286
|
+
await handleFiles();
|
|
287
|
+
clients.forEach(c => {
|
|
288
|
+
c.send('reload');
|
|
289
|
+
});
|
|
290
|
+
} catch (error) {
|
|
291
|
+
console.error(error);
|
|
292
|
+
} finally {
|
|
293
|
+
isBuilding = false; // Reset build flag
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
}, 500);
|
|
297
|
+
};
|
|
298
|
+
|
|
299
|
+
// Event listeners with debounced handling
|
|
300
|
+
publicWatcher.on('change', handleFileChangeDebounced);
|
|
301
|
+
watcher.on('change', handleFileChangeDebounced);
|
|
302
|
+
srcWatcher.on('change', handleFileChangeDebounced);
|
|
303
|
+
let server = Bun.serve({
|
|
304
|
+
port: port || 8080,
|
|
305
|
+
websocket: {
|
|
306
|
+
open(ws) {
|
|
307
|
+
globalThis.clients.push(ws)
|
|
308
|
+
ws.send('Connected')
|
|
309
|
+
},
|
|
310
|
+
message(ws, message) {
|
|
311
|
+
globalThis.clients.forEach(c => {
|
|
312
|
+
c.send(message)
|
|
313
|
+
})
|
|
314
|
+
},
|
|
315
|
+
|
|
316
|
+
},
|
|
317
|
+
async fetch(req, res) {
|
|
318
|
+
if (res.upgrade(req)) {
|
|
319
|
+
return new Response('Upgraded', { status: 101 })
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
let url = new URL(req.url)
|
|
323
|
+
if (url.pathname.includes('.')) {
|
|
324
|
+
let p = url.pathname.replaceAll("%5B", "[").replaceAll("%5D", "]")
|
|
325
|
+
let file = await Bun.file(path.join(process.cwd() + '/dist' + p))
|
|
326
|
+
if (!await file.exists()) return new Response('Not found', { status: 404 })
|
|
327
|
+
return new Response(await file.text(), {
|
|
328
|
+
headers: {
|
|
329
|
+
'Content-Type': file.type,
|
|
330
|
+
'Cache-Control': 'no-cache',
|
|
331
|
+
'Access-Control-Allow-Origin': '*'
|
|
332
|
+
}
|
|
333
|
+
})
|
|
334
|
+
}
|
|
335
|
+
let router = new Bun.FileSystemRouter({
|
|
336
|
+
dir: process.cwd() + '/app',
|
|
337
|
+
style: 'nextjs'
|
|
338
|
+
})
|
|
339
|
+
router.reload()
|
|
340
|
+
let route = router.match(url.pathname)
|
|
341
|
+
if (!route) {
|
|
342
|
+
return new Response('Not found', { status: 404 })
|
|
343
|
+
}
|
|
344
|
+
let p = route.pathname;
|
|
345
|
+
let base = path.dirname(route.filePath)
|
|
346
|
+
base = base.replace(path.join(process.cwd() + '/app'), '')
|
|
347
|
+
base = base.replace(/\\/g, '/').replace('/app', '/dist')
|
|
348
|
+
base = process.cwd() + "/dist/" + base
|
|
349
|
+
let data = await Bun.file(path.join(base, 'index.html')).text()
|
|
350
|
+
if (mode == "development") {
|
|
351
|
+
return new Response(data + `
|
|
352
|
+
<script>
|
|
353
|
+
let ws = new WebSocket('ws://localhost:${server.port}')
|
|
354
|
+
ws.onmessage = (e) => {
|
|
355
|
+
if(e.data === 'reload'){
|
|
356
|
+
window.location.reload()
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
</script>
|
|
360
|
+
`, {
|
|
361
|
+
headers:{
|
|
362
|
+
'Content-Type': 'text/html'
|
|
363
|
+
}
|
|
364
|
+
})
|
|
365
|
+
} else {
|
|
366
|
+
return new Response(data, {
|
|
367
|
+
headers: {
|
|
368
|
+
'Content-Type': 'text/html'
|
|
369
|
+
}
|
|
370
|
+
})
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
}
|
|
374
|
+
})
|
|
375
|
+
} else {
|
|
376
|
+
console.log(`Build complete in ${Date.now() - start}ms at ${new Date().toLocaleTimeString()}`)
|
|
377
|
+
process.exit(0)
|
|
337
378
|
}
|