rajt 0.0.73 โ 0.0.75
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 +3 -3
- package/src/cli/commands/dev.ts +117 -112
- package/src/cli/commands/migrate.ts +1 -1
- package/src/cli/commands/utils.ts +9 -10
- package/src/utils/log.ts +5 -0
package/package.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rajt",
|
|
3
3
|
"description": "A serverless bundler layer, fully typed for AWS Lambda (Node.js and LLRT) and Cloudflare Workers.",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.75",
|
|
5
5
|
"type": "module",
|
|
6
|
-
"main": "
|
|
6
|
+
"main": "./src/index.ts",
|
|
7
7
|
"bin": {
|
|
8
8
|
"rajt": "./bin/rajt.js"
|
|
9
9
|
},
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"sam:package": "sam package --template-file ../../template-prod.yaml --output-template-file ../../packaged.yaml",
|
|
36
36
|
"sam:deploy": "sam deploy --template-file ../../packaged.yaml --stack-name rajt-llrt --capabilities CAPABILITY_IAM",
|
|
37
37
|
"sam:update": "source ../../.env.prod && aws lambda update-function-code --function-name $AWS_NAME --zip-file fileb://../../lambda.zip --region $AWS_REGION --no-cli-pager 2>&1 >/dev/null",
|
|
38
|
-
"zip": "zip -j ../../lambda.zip
|
|
38
|
+
"zip": "zip -j ../../lambda.zip ../../.rajt/dist/index.js"
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
41
|
"cripta": "^0.1",
|
package/src/cli/commands/dev.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { spawn, type ChildProcess } from 'node:child_process'
|
|
|
4
4
|
import { defineCommand } from 'citty'
|
|
5
5
|
import type { Miniflare } from 'miniflare'
|
|
6
6
|
import { _root, build, wait, watch, normalizePlatform, platformError, getRuntime, createMiniflare, getDockerHost } from './utils'
|
|
7
|
-
import {
|
|
7
|
+
import { error, event, log, rn, warn } from '../../utils/log'
|
|
8
8
|
import { withPort } from '../../utils/port'
|
|
9
9
|
import shutdown from '../../utils/shutdown'
|
|
10
10
|
|
|
@@ -39,49 +39,83 @@ export default defineCommand({
|
|
|
39
39
|
|
|
40
40
|
const desiredPort = args.port ? Number(args.port) : 3000
|
|
41
41
|
const host = args.host ? String(args.host) : 'localhost'
|
|
42
|
+
|
|
43
|
+
let isBuilding = false
|
|
44
|
+
const startApp = async (start: Function, stop: Function|undefined = undefined, building: boolean = true) => {
|
|
45
|
+
if (building) {
|
|
46
|
+
if (isBuilding) return
|
|
47
|
+
isBuilding = true
|
|
48
|
+
event('Building..')
|
|
49
|
+
}
|
|
50
|
+
const fn = async () => {
|
|
51
|
+
building && await build(platform)
|
|
52
|
+
await start()
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
try {
|
|
56
|
+
await fn()
|
|
57
|
+
watch(async () => {
|
|
58
|
+
event('Restarting..')
|
|
59
|
+
await fn()
|
|
60
|
+
// event('Restarted...')
|
|
61
|
+
})
|
|
62
|
+
// @ts-ignore
|
|
63
|
+
stop && shutdown(stop)
|
|
64
|
+
} catch (e: any) {
|
|
65
|
+
error(e)
|
|
66
|
+
process.exit(0)
|
|
67
|
+
} finally {
|
|
68
|
+
isBuilding = false
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const applyExit = async (app: ChildProcess | null) => {
|
|
73
|
+
if (!app) return null
|
|
74
|
+
|
|
75
|
+
app //?.on('exit', code => process.exit(code ?? 0))
|
|
76
|
+
.on('message', msg => {
|
|
77
|
+
process.send && process.send(msg)
|
|
78
|
+
}).on('disconnect', () => {
|
|
79
|
+
process.disconnect && process.disconnect()
|
|
80
|
+
})
|
|
81
|
+
}
|
|
82
|
+
const killProcess = async (app: ChildProcess | null) => {
|
|
83
|
+
if (!app) return null
|
|
84
|
+
// event('Stopping..')
|
|
85
|
+
try {
|
|
86
|
+
if (!app?.killed) {
|
|
87
|
+
app.kill('SIGTERM')
|
|
88
|
+
await wait(1000)
|
|
89
|
+
|
|
90
|
+
if (!app?.killed) { // force kill
|
|
91
|
+
app.kill('SIGKILL')
|
|
92
|
+
await wait(1000)
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return null
|
|
97
|
+
} catch (e) {
|
|
98
|
+
error('Error stopping:', e)
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return null
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const started = (port: number) => {
|
|
105
|
+
log(`Starting API on http://${host}:${port}`)
|
|
106
|
+
rn()
|
|
107
|
+
}
|
|
108
|
+
|
|
42
109
|
switch (platform) {
|
|
43
110
|
case 'aws':
|
|
44
111
|
return withPort(desiredPort, async (port) => {
|
|
45
|
-
|
|
112
|
+
started(port)
|
|
46
113
|
let lambda: ChildProcess | null = null
|
|
47
|
-
|
|
48
|
-
const buildLambda = async () => {
|
|
49
|
-
if (isBuilding) return
|
|
50
|
-
isBuilding = true
|
|
51
|
-
step('Building lambda')
|
|
52
|
-
try {
|
|
53
|
-
await build(platform)
|
|
54
|
-
if (!lambda) await startLambda()
|
|
55
|
-
} catch (e: any) {
|
|
56
|
-
error('Build failed:', e?.message || e)
|
|
57
|
-
process.exit(0)
|
|
58
|
-
} finally {
|
|
59
|
-
isBuilding = false
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
114
|
const stopLambda = async () => {
|
|
64
|
-
|
|
65
|
-
step('Stopping lambda process...')
|
|
66
|
-
try {
|
|
67
|
-
if (!lambda?.killed) {
|
|
68
|
-
lambda.kill('SIGTERM')
|
|
69
|
-
await wait(1000)
|
|
70
|
-
|
|
71
|
-
if (!lambda?.killed) { // force kill
|
|
72
|
-
lambda.kill('SIGKILL')
|
|
73
|
-
await wait(1000)
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
lambda = null
|
|
78
|
-
} catch (e) {
|
|
79
|
-
warn('Error stopping lambda:', e)
|
|
80
|
-
}
|
|
115
|
+
lambda = await killProcess(lambda)
|
|
81
116
|
}
|
|
82
|
-
|
|
83
117
|
const startLambda = async () => {
|
|
84
|
-
await stopLambda()
|
|
118
|
+
if (lambda) await stopLambda()
|
|
85
119
|
|
|
86
120
|
lambda = spawn(
|
|
87
121
|
'sam',
|
|
@@ -97,106 +131,77 @@ export default defineCommand({
|
|
|
97
131
|
shell: process.platform == 'win32',
|
|
98
132
|
env: {...process.env, DOCKER_HOST: getDockerHost()},
|
|
99
133
|
}
|
|
100
|
-
)
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
.on('message', msg => {
|
|
108
|
-
|
|
109
|
-
}).on('disconnect', () => {
|
|
110
|
-
|
|
111
|
-
}).on('error', e => {
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
})
|
|
115
|
-
|
|
134
|
+
)
|
|
135
|
+
//.on('exit', code => {
|
|
136
|
+
// warn(`Lambda process exited with code ${code ?? 0}`)
|
|
137
|
+
// if (code != 0 && code != null)
|
|
138
|
+
// error('Lambda process crashed, waiting for restart...')
|
|
139
|
+
|
|
140
|
+
// lambda = null
|
|
141
|
+
// }).on('message', msg => {
|
|
142
|
+
// process.send && process.send(msg)
|
|
143
|
+
// }).on('disconnect', () => {
|
|
144
|
+
// process.disconnect && process.disconnect()
|
|
145
|
+
// }).on('error', e => {
|
|
146
|
+
// error('Lambda process error:', e)
|
|
147
|
+
// lambda = null
|
|
148
|
+
// })
|
|
149
|
+
applyExit(lambda)
|
|
116
150
|
await wait(2000)
|
|
117
|
-
|
|
118
|
-
step('Lambda process started successfully')
|
|
119
151
|
}
|
|
120
152
|
|
|
121
|
-
await
|
|
122
|
-
event(`API running on http://${host}:${port}`)
|
|
123
|
-
|
|
124
|
-
watch(async () => {
|
|
125
|
-
await buildLambda()
|
|
126
|
-
})
|
|
127
|
-
|
|
128
|
-
shutdown(async () => {
|
|
129
|
-
await stopLambda()
|
|
130
|
-
})
|
|
153
|
+
await startApp(startLambda, stopLambda)
|
|
131
154
|
})
|
|
132
155
|
case 'cf':
|
|
133
156
|
return withPort(desiredPort, async (port) => {
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
const buildWorker = async () => {
|
|
137
|
-
if (isBuilding) return
|
|
138
|
-
isBuilding = true
|
|
139
|
-
step('Building worker')
|
|
140
|
-
try {
|
|
141
|
-
await build(platform)
|
|
142
|
-
await startWorker()
|
|
143
|
-
} catch (e: any) {
|
|
144
|
-
error('Build failed:', e?.message || e)
|
|
145
|
-
process.exit(0)
|
|
146
|
-
} finally {
|
|
147
|
-
isBuilding = false
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
|
|
157
|
+
started(port)
|
|
151
158
|
let worker: Miniflare | null = null
|
|
152
159
|
const startWorker = async () => {
|
|
153
160
|
if (worker) await worker.dispose()
|
|
154
|
-
|
|
155
161
|
worker = await createMiniflare({ port, host, liveReload: false })
|
|
156
162
|
}
|
|
157
163
|
|
|
158
|
-
await
|
|
159
|
-
event(`API running on http://${host}:${port}`)
|
|
160
|
-
|
|
161
|
-
watch(async () => {
|
|
162
|
-
step('Restarting server')
|
|
163
|
-
await buildWorker()
|
|
164
|
-
step('Server restarted')
|
|
165
|
-
})
|
|
164
|
+
await startApp(startWorker)
|
|
166
165
|
})
|
|
167
166
|
default:
|
|
168
167
|
case 'node':
|
|
169
168
|
return withPort(desiredPort, async (port) => {
|
|
169
|
+
started(port)
|
|
170
170
|
const isBun = getRuntime() == 'bun'
|
|
171
171
|
const params = isBun
|
|
172
172
|
? ['run', '--port='+ port, '--hot', '--silent', '--no-clear-screen', '--no-summary', join(_root, 'node_modules/rajt/src/dev.ts')]
|
|
173
173
|
: [join(_root, 'node_modules/.bin/tsx'), 'watch', join(_root, 'node_modules/rajt/src/dev-node.ts')]
|
|
174
174
|
|
|
175
|
-
const child = spawn(
|
|
176
|
-
process.execPath,
|
|
177
|
-
params,
|
|
178
|
-
{
|
|
179
|
-
stdio: ['inherit', isBun ? 'pipe' : 'inherit', 'inherit', 'ipc'],
|
|
180
|
-
env: {...process.env, PORT: port},
|
|
181
|
-
}
|
|
182
|
-
)
|
|
183
175
|
|
|
184
|
-
|
|
176
|
+
let nodeApp: ChildProcess | null = null
|
|
177
|
+
const stopNode = async () => {
|
|
178
|
+
nodeApp = await killProcess(nodeApp)
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
const startNode = async () => {
|
|
182
|
+
if (nodeApp) await stopNode()
|
|
183
|
+
|
|
184
|
+
nodeApp = spawn(
|
|
185
|
+
process.execPath,
|
|
186
|
+
params,
|
|
187
|
+
{
|
|
188
|
+
stdio: ['inherit', isBun ? 'pipe' : 'inherit', 'inherit', 'ipc'],
|
|
189
|
+
env: {...process.env, PORT: port},
|
|
190
|
+
}
|
|
191
|
+
)
|
|
192
|
+
|
|
193
|
+
if (isBun && nodeApp?.stdout) {
|
|
194
|
+
nodeApp.stdout?.on('data', data => {
|
|
195
|
+
const output = data.toString()
|
|
196
|
+
if (!output.includes('Started development server'))
|
|
197
|
+
process.stdout.write(output)
|
|
198
|
+
})
|
|
199
|
+
}
|
|
185
200
|
|
|
186
|
-
|
|
187
|
-
child.stdout?.on('data', data => {
|
|
188
|
-
const output = data.toString()
|
|
189
|
-
if (!output.includes('Started development server'))
|
|
190
|
-
process.stdout.write(output)
|
|
191
|
-
})
|
|
201
|
+
applyExit(nodeApp)
|
|
192
202
|
}
|
|
193
203
|
|
|
194
|
-
|
|
195
|
-
.on('message', msg => {
|
|
196
|
-
process.send && process.send(msg)
|
|
197
|
-
}).on('disconnect', () => {
|
|
198
|
-
process.disconnect && process.disconnect()
|
|
199
|
-
})
|
|
204
|
+
await startApp(startNode, stopNode, false)
|
|
200
205
|
})
|
|
201
206
|
}
|
|
202
207
|
},
|
|
@@ -10,7 +10,7 @@ import { gray } from '../../utils/colors'
|
|
|
10
10
|
import type { ChokidarEventName, Platform } from './types'
|
|
11
11
|
|
|
12
12
|
import { cacheRoutes } from '../../routes'
|
|
13
|
-
import { step, substep, event, error, warn } from '../../utils/log'
|
|
13
|
+
import { step, substep, event, error, wait as wwait, warn, log } from '../../utils/log'
|
|
14
14
|
import { platforms } from './constants'
|
|
15
15
|
|
|
16
16
|
export const _root = join(dirname(new URL(import.meta.url).pathname), '../../../../../')
|
|
@@ -58,11 +58,12 @@ export const formatTime = (ms: number) => {
|
|
|
58
58
|
return `${(ms / 1000).toFixed(2)}s`
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
+
const dist = '.rajt/dist'
|
|
61
62
|
export const build = async (platform: Platform) => {
|
|
62
63
|
const startTime = Date.now()
|
|
63
64
|
|
|
64
65
|
const isCF = platform == 'cf'
|
|
65
|
-
const distDir = join(_root,
|
|
66
|
+
const distDir = join(_root, dist)
|
|
66
67
|
|
|
67
68
|
existsSync(distDir)
|
|
68
69
|
? readdirSync(distDir).forEach(file => rmSync(join(distDir, file), { recursive: true, force: true }))
|
|
@@ -74,7 +75,7 @@ export const build = async (platform: Platform) => {
|
|
|
74
75
|
]) {
|
|
75
76
|
file = join(_root, file)
|
|
76
77
|
if (existsSync(file))
|
|
77
|
-
copyFileSync(file, join(_root,
|
|
78
|
+
copyFileSync(file, join(_root, dist, basename(file)))
|
|
78
79
|
}
|
|
79
80
|
}
|
|
80
81
|
|
|
@@ -86,7 +87,7 @@ export const build = async (platform: Platform) => {
|
|
|
86
87
|
entryPoints: [join(__rajt, `prod${platform}.ts`)],
|
|
87
88
|
bundle: true,
|
|
88
89
|
minify: true,
|
|
89
|
-
outfile: join(_root, '
|
|
90
|
+
outfile: join(_root, dist +'/index.js'),
|
|
90
91
|
format: 'esm',
|
|
91
92
|
target: isCF ? 'es2022' : 'node20',
|
|
92
93
|
// platform: 'neutral',
|
|
@@ -194,7 +195,7 @@ export async function createMiniflare(options = {}, configPath = 'wrangler.toml'
|
|
|
194
195
|
liveReload: options.liveReload !== false,
|
|
195
196
|
updateCheck: false,
|
|
196
197
|
|
|
197
|
-
scriptPath: join(_root, '
|
|
198
|
+
scriptPath: join(_root, dist +'/index.js'),
|
|
198
199
|
compatibilityDate: config.compatibility_date || '2024-11-01',
|
|
199
200
|
compatibilityFlags: config.compatibility_flags || [
|
|
200
201
|
'nodejs_compat',
|
|
@@ -209,7 +210,7 @@ export async function createMiniflare(options = {}, configPath = 'wrangler.toml'
|
|
|
209
210
|
d1Databases: Array.isArray(config.d1_databases) ? Object.fromEntries(config.d1_databases.map(db => [db.binding, db.database_id])) : {},
|
|
210
211
|
|
|
211
212
|
modules: [
|
|
212
|
-
{ type:
|
|
213
|
+
{ type: 'ESModule', path: dist +'/index.js' },
|
|
213
214
|
],
|
|
214
215
|
// modules: true,
|
|
215
216
|
// modulesRules: [
|
|
@@ -252,8 +253,6 @@ export async function createMiniflare(options = {}, configPath = 'wrangler.toml'
|
|
|
252
253
|
})
|
|
253
254
|
}
|
|
254
255
|
|
|
255
|
-
|
|
256
|
-
|
|
257
256
|
function getAssetChangeMessage(
|
|
258
257
|
e: ChokidarEventName,
|
|
259
258
|
path: string
|
|
@@ -293,7 +292,7 @@ export async function watch(cb: (e: ChokidarEventName | string, file: string) =>
|
|
|
293
292
|
let restartTimeout: NodeJS.Timeout | null = null
|
|
294
293
|
|
|
295
294
|
const watcher = (e: ChokidarEventName) => async (file: string) => {
|
|
296
|
-
|
|
295
|
+
log(getAssetChangeMessage(e, file))
|
|
297
296
|
|
|
298
297
|
if (restartTimeout)
|
|
299
298
|
clearTimeout(restartTimeout)
|
|
@@ -309,7 +308,7 @@ export async function watch(cb: (e: ChokidarEventName | string, file: string) =>
|
|
|
309
308
|
codeWatcher.on('addDir', watcher('addDir'))
|
|
310
309
|
codeWatcher.on('unlinkDir', watcher('unlinkDir'))
|
|
311
310
|
|
|
312
|
-
|
|
311
|
+
wwait('Watching for file changes')
|
|
313
312
|
}
|
|
314
313
|
|
|
315
314
|
export async function wait(ms: number) {
|
package/src/utils/log.ts
CHANGED
|
@@ -43,6 +43,7 @@ export const prefixes = {
|
|
|
43
43
|
info: white(bold(' ')),
|
|
44
44
|
event: green(bold('โ')),
|
|
45
45
|
trace: magenta(bold('ยป')),
|
|
46
|
+
log: gray(bold('โ')),
|
|
46
47
|
} as const
|
|
47
48
|
|
|
48
49
|
const LOGGING_METHOD = {
|
|
@@ -76,6 +77,10 @@ function prefixedLog(prefixType: keyof typeof prefixes, ...msg: any[]) {
|
|
|
76
77
|
}
|
|
77
78
|
}
|
|
78
79
|
|
|
80
|
+
export function log(...msg: any[]) {
|
|
81
|
+
prefixedLog('log', ...msg)
|
|
82
|
+
}
|
|
83
|
+
|
|
79
84
|
export function wait(...msg: any[]) {
|
|
80
85
|
prefixedLog('wait', ...msg)
|
|
81
86
|
}
|