Skip to content

Commit 57ff9cd

Browse files
committed
🧹 chore: refactor composeErrorHandler
1 parent 727767e commit 57ff9cd

File tree

9 files changed

+89
-160
lines changed

9 files changed

+89
-160
lines changed

example/a.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ const app = new Elysia()
2727
})
2828
.listen(3000)
2929

30-
// console.log(app.routes[0].compile().toString())
30+
app.compile()
3131

3232
// app.handle(
3333
// upload('/', {

example/stress/instance.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ for (let i = 0; i < total; i++) {
1818

1919
const t2 = performance.now()
2020

21+
Bun.gc(true)
22+
2123
const memoryAfter = process.memoryUsage().heapTotal / 1024 / 1024
2224
console.log(+(memoryAfter - memory).toFixed(2), 'MB memory used')
2325
console.log(+(t2 - t1).toFixed(2), 'ms')

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "elysia",
33
"description": "Ergonomic Framework for Human",
4-
"version": "1.3.0-exp.71",
4+
"version": "1.3.0-exp.74",
55
"author": {
66
"name": "saltyAom",
77
"url": "https://github.com/SaltyAom",

src/compose.ts

Lines changed: 28 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -379,8 +379,7 @@ export const composeHandler = ({
379379
validator,
380380
handler,
381381
allowMeta = false,
382-
inference,
383-
asManifest = false
382+
inference
384383
}: {
385384
app: AnyElysia
386385
path: string
@@ -390,7 +389,6 @@ export const composeHandler = ({
390389
handler: unknown | Handler<any, any>
391390
allowMeta?: boolean
392391
inference: Sucrose.Inference
393-
asManifest?: boolean
394392
}): ComposedHandler => {
395393
const adapter = app['~adapter'].composeHandler
396394
const adapterHandler = app['~adapter'].handler
@@ -411,10 +409,13 @@ export const composeHandler = ({
411409
if (handler instanceof Response)
412410
return Function(
413411
'a',
414-
`return function(){return a.clone()}`
412+
'"use strict";\n' + `return function(){return a.clone()}`
415413
)(handler)
416414

417-
return Function('a', 'return function(){return a}')(handler)
415+
return Function(
416+
'a',
417+
'"use strict";\n' + 'return function(){return a}'
418+
)(handler)
418419
}
419420
}
420421

@@ -1057,9 +1058,9 @@ export const composeHandler = ({
10571058

10581059
default:
10591060
fnLiteral +=
1060-
`${name}=parser['${hooks.parse[i].fn}'](c,contentType)\n` +
1061+
`let ${name}=parser['${hooks.parse[i].fn}'](c,contentType)\n` +
10611062
`if(${name} instanceof Promise)${name}=await ${name}\n` +
1062-
`if(${name}!==undefined){c.body=${name};used=true}\n`
1063+
`if(${name}!==undefined){c.body=${name};used=true;}\n`
10631064
}
10641065

10651066
endUnit()
@@ -2026,11 +2027,9 @@ export const composeHandler = ({
20262027
init = ''
20272028

20282029
try {
2029-
if (asManifest) return Function('hooks', init) as any
2030-
20312030
return Function(
20322031
'hooks',
2033-
fnLiteral
2032+
'"use strict";\n' + fnLiteral
20342033
)({
20352034
handler,
20362035
hooks: lifeCycleToFn(hooks),
@@ -2196,11 +2195,7 @@ export const createHoc = (app: AnyElysia, fnName = 'map') => {
21962195
return `return function hocMap(${adapter.parameters}){return ${handler}(${adapter.parameters})}`
21972196
}
21982197

2199-
export const composeGeneralHandler = (
2200-
app: AnyElysia,
2201-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
2202-
{ asManifest = false }: { asManifest?: false } = {}
2203-
) => {
2198+
export const composeGeneralHandler = (app: AnyElysia) => {
22042199
const adapter = app['~adapter'].composeGeneralHandler
22052200
app.router.http.build()
22062201

@@ -2329,7 +2324,7 @@ export const composeGeneralHandler = (
23292324

23302325
const fn = Function(
23312326
'data',
2332-
fnLiteral
2327+
'"use strict";\n' + fnLiteral
23332328
)({
23342329
app,
23352330
mapEarlyResponse: app['~adapter']['handler'].mapEarlyResponse,
@@ -2362,36 +2357,23 @@ export const composeErrorHandler = (app: AnyElysia) => {
23622357

23632358
fnLiteral +=
23642359
`const {` +
2365-
`app:{` +
2366-
`event:{` +
2367-
`error:onErrorContainer,` +
2368-
`afterResponse:resContainer,` +
2369-
`mapResponse:_onMapResponse,` +
2370-
`trace:_trace` +
2371-
`}` +
2372-
`},` +
23732360
`mapResponse,` +
23742361
`ERROR_CODE,` +
23752362
`ElysiaCustomStatusResponse,` +
2363+
allocateIf(`onError,`, app.event.error) +
2364+
allocateIf(`afterResponse,`, app.event.afterResponse) +
2365+
allocateIf(`trace,`, app.event.trace) +
2366+
allocateIf(`onMapResponse,`, app.event.mapResponse) +
23762367
allocateIf(`ELYSIA_TRACE,`, hasTrace) +
23772368
allocateIf(`ELYSIA_REQUEST_ID,`, hasTrace) +
23782369
adapterVariables +
23792370
`}=inject\n`
23802371

2381-
fnLiteral +=
2382-
`const trace=_trace?.map(x=>typeof x==='function'?x:x.fn)??[]\n` +
2383-
`const onMapResponse=[]\n` +
2384-
`if(_onMapResponse)for(let i=0;i<_onMapResponse.length;i++)` +
2385-
`onMapResponse.push(_onMapResponse[i].fn??_onMapResponse[i])\n` +
2386-
`delete _onMapResponse\n` +
2387-
`const onError=onErrorContainer?.map(x=>x.fn)??[]\n` +
2388-
`const res=resContainer?.map(x=>x.fn)??[]\n` +
2389-
`return ${
2390-
app.event.error?.find(isAsync) ||
2391-
app.event.mapResponse?.find(isAsync)
2392-
? 'async '
2393-
: ''
2394-
}function(context,error,skipGlobal){`
2372+
fnLiteral += `return ${
2373+
app.event.error?.find(isAsync) || app.event.mapResponse?.find(isAsync)
2374+
? 'async '
2375+
: ''
2376+
}function(context,error,skipGlobal){`
23952377

23962378
fnLiteral += ''
23972379

@@ -2518,14 +2500,20 @@ export const composeErrorHandler = (app: AnyElysia) => {
25182500

25192501
fnLiteral += `\nreturn mapResponse(${saveResponse}error,set${adapter.mapResponseContext})}`
25202502

2503+
const mapFn = (x: Function | HookContainer) =>
2504+
typeof x === 'function' ? x : x.fn
2505+
25212506
return Function(
25222507
'inject',
2523-
fnLiteral
2508+
'"use strict";\n' + fnLiteral
25242509
)({
2525-
app,
25262510
mapResponse: app['~adapter'].handler.mapResponse,
25272511
ERROR_CODE,
25282512
ElysiaCustomStatusResponse,
2513+
onError: app.event.error?.map(mapFn),
2514+
afterResponse: app.event.afterResponse?.map(mapFn),
2515+
trace: app.event.trace?.map(mapFn),
2516+
onMapResponse: app.event.mapResponse?.map(mapFn),
25292517
ELYSIA_TRACE: hasTrace ? ELYSIA_TRACE : undefined,
25302518
ELYSIA_REQUEST_ID: hasTrace ? ELYSIA_REQUEST_ID : undefined,
25312519
...adapter.inject

src/sucrose.ts

Lines changed: 42 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -241,20 +241,19 @@ export const retrieveRootParamters = (parameter: string) => {
241241
parameter = removeColonAlias(parameter)
242242
if (parameter) parameters = parameters.concat(parameter.split(','))
243243

244-
const newParameters = []
244+
const parameterMap: Record<string, true> = Object.create(null)
245245
for (const p of parameters) {
246246
if (p.indexOf(',') === -1) {
247-
newParameters.push(p)
247+
parameterMap[p] = true
248248
continue
249249
}
250250

251-
for (const q of p.split(',')) newParameters.push(q.trim())
251+
for (const q of p.split(',')) parameterMap[q.trim()] = true
252252
}
253-
parameters = newParameters
254253

255254
return {
256255
hasParenthesis,
257-
parameters
256+
parameters: parameterMap
258257
}
259258
}
260259

@@ -270,41 +269,35 @@ export const findParameterReference = (
270269
const { parameters, hasParenthesis } = retrieveRootParamters(parameter)
271270

272271
// Check if root is an object destructuring
273-
if (!inference.query && parameters.includes('query')) inference.query = true
274-
if (!inference.headers && parameters.includes('headers'))
275-
inference.headers = true
276-
if (!inference.body && parameters.includes('body')) inference.body = true
277-
if (!inference.cookie && parameters.includes('cookie'))
278-
inference.cookie = true
279-
if (!inference.set && parameters.includes('set')) inference.set = true
280-
if (!inference.server && parameters.includes('server'))
281-
inference.server = true
282-
if (!inference.route && parameters.includes('route')) inference.route = true
283-
if (!inference.url && parameters.includes('url')) inference.url = true
284-
if (!inference.path && parameters.includes('path')) inference.path = true
285-
286-
if (hasParenthesis) return `{ ${parameters.join(', ')} }`
287-
288-
return parameters.join(', ')
272+
if (parameters.query) inference.query = true
273+
if (parameters.headers) inference.headers = true
274+
if (parameters.body) inference.body = true
275+
if (parameters.cookie) inference.cookie = true
276+
if (parameters.set) inference.set = true
277+
if (parameters.server) inference.server = true
278+
if (parameters.route) inference.route = true
279+
if (parameters.url) inference.url = true
280+
if (parameters.path) inference.path = true
281+
282+
if (hasParenthesis) return `{ ${Object.keys(parameters).join(', ')} }`
283+
284+
return Object.keys(parameters).join(', ')
289285
}
290286

291287
const findEndIndex = (
292288
type: string,
293289
content: string,
294290
index?: number | undefined
295291
) => {
296-
const newLineIndex = content.indexOf(type + '\n', index)
297-
const newTabIndex = content.indexOf(type + '\t', index)
298-
const commaIndex = content.indexOf(type + ',', index)
299-
const semicolonIndex = content.indexOf(type + ';', index)
300-
const emptyIndex = content.indexOf(type + ' ', index)
301-
302-
// Pick the smallest index that is not -1 or 0
303-
return (
304-
[newLineIndex, newTabIndex, commaIndex, semicolonIndex, emptyIndex]
305-
.filter((i) => i > 0)
306-
.sort((a, b) => a - b)[0] || -1
292+
const regex = new RegExp(
293+
`${type.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}[\\n\\t,; ]`
307294
)
295+
296+
if (index !== undefined) regex.lastIndex = index
297+
298+
const match = regex.exec(content)
299+
300+
return match ? match.index : -1
308301
}
309302

310303
const findEndQueryBracketIndex = (
@@ -422,9 +415,9 @@ export const extractMainParameter = (parameter: string) => {
422415

423416
const hasComma = parameter.includes(',')
424417
if (!hasComma) {
418+
const index = parameter.indexOf('...')
425419
// This happens when spread operator is used as the only parameter
426-
if (parameter.includes('...'))
427-
return parameter.slice(parameter.indexOf('...') + 3)
420+
if (index !== -1) return parameter.slice(parameter.indexOf('...') + 3)
428421

429422
return
430423
}
@@ -445,9 +438,9 @@ export const inferBodyReference = (
445438
inference: Sucrose.Inference
446439
) => {
447440
const access = (type: string, alias: string) =>
448-
code.includes(alias + '.' + type) ||
449-
code.includes(alias + '["' + type + '"]') ||
450-
code.includes(alias + "['" + type + "']")
441+
new RegExp(
442+
`${alias}\\.(${type})|${alias}\\["${type}"\\]|${alias}\\['${type}'\\]`
443+
).test(code)
451444

452445
for (const alias of aliases) {
453446
if (!alias) continue
@@ -456,41 +449,25 @@ export const inferBodyReference = (
456449
if (alias.charCodeAt(0) === 123) {
457450
const parameters = retrieveRootParamters(alias).parameters
458451

459-
if (!inference.query && parameters.includes('query'))
460-
inference.query = true
461-
462-
if (!inference.headers && parameters.includes('headers'))
463-
inference.headers = true
464-
465-
if (!inference.body && parameters.includes('body'))
466-
inference.body = true
467-
468-
if (!inference.cookie && parameters.includes('cookie'))
469-
inference.cookie = true
470-
471-
if (!inference.set && parameters.includes('set'))
472-
inference.set = true
473-
474-
if (!inference.query && parameters.includes('server'))
475-
inference.server = true
476-
477-
if (!inference.url && parameters.includes('url'))
478-
inference.url = true
479-
480-
if (!inference.route && parameters.includes('route'))
481-
inference.route = true
482-
483-
if (!inference.path && parameters.includes('path'))
484-
inference.path = true
452+
if (parameters.query) inference.query = true
453+
if (parameters.headers) inference.headers = true
454+
if (parameters.body) inference.body = true
455+
if (parameters.cookie) inference.cookie = true
456+
if (parameters.set) inference.set = true
457+
if (parameters.server) inference.server = true
458+
if (parameters.url) inference.url = true
459+
if (parameters.route) inference.route = true
460+
if (parameters.path) inference.path = true
485461

486462
continue
487463
}
488464

489465
if (!inference.query && access('query', alias)) inference.query = true
490466

491467
if (
492-
code.includes('return ' + alias) ||
493-
code.includes('return ' + alias + '.query')
468+
!inference.query &&
469+
(code.includes('return ' + alias) ||
470+
code.includes('return ' + alias + '.query'))
494471
)
495472
inference.query = true
496473

src/types.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,9 +113,9 @@ export interface ElysiaConfig<Prefix extends string | undefined> {
113113
schema?: boolean
114114
}
115115
/**
116-
* Disable Ahead of Time compliation
116+
* Enable Ahead of Time compilation
117117
*
118-
* Reduced performance but faster startup time
118+
* Trade significant performance with slightly faster startup time and reduced memory usage
119119
*/
120120
aot?: boolean
121121
/**

src/utils.ts

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -332,16 +332,13 @@ const isBun = typeof Bun !== 'undefined'
332332
const hasBunHash = isBun && typeof Bun.hash === 'function'
333333

334334
// https://stackoverflow.com/a/52171480
335-
export const checksum = hasBunHash
336-
? (s: string) => Bun.hash(s) as number
337-
: (s: string) => {
338-
let h = 9
335+
export const checksum = (s: string) => {
336+
let h = 9
339337

340-
for (let i = 0; i < s.length; )
341-
h = Math.imul(h ^ s.charCodeAt(i++), 9 ** 9)
338+
for (let i = 0; i < s.length; ) h = Math.imul(h ^ s.charCodeAt(i++), 9 ** 9)
342339

343-
return (h = h ^ (h >>> 9))
344-
}
340+
return (h = h ^ (h >>> 9))
341+
}
345342

346343
export const injectChecksum = (
347344
checksum: number | undefined,

0 commit comments

Comments
 (0)