Skip to content

Commit d99d5b2

Browse files
committed
🔧 fix: merge main
2 parents 5188902 + 668c7a1 commit d99d5b2

File tree

21 files changed

+9339
-19
lines changed

21 files changed

+9339
-19
lines changed

CHANGELOG.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
1-
# 1.4.9
1+
# 1.4.10
22
Bug fix:
33
Change:
44
- `Elysia.file` readstream value is now IIFE to re-read
55

6+
# 1.4.9 - 29 Sep 2025
7+
Improvement:
8+
- add Cloudflare Worker test
9+
- add `Sucrose.Settings`
10+
- [#1443](https://github.com/elysiajs/elysia/pull/1443) add knip for detecting deadcode
11+
612
# 1.4.8 - 27 Sep 2025
713
Improvement:
814
- automatically clear up sucrose cache when not used

bun.lock

Lines changed: 72 additions & 1 deletion
Large diffs are not rendered by default.

example/a.ts

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,31 @@
11
import { Elysia, t } from '../src'
2-
import { sucrose } from '../src/sucrose'
2+
import { parseCookie } from '../src/cookies'
33
import { req } from '../test/utils'
44

5-
const app = new Elysia()
6-
.get('/:id', ({ params: { id } }) => 'hello')
7-
.listen(3000)
5+
console.log(getLastBalancedParenIndex(`a({ hello: a() }).thing`))
86

9-
// app.handle(req('/1'))
7+
function getLastBalancedParenIndex(input: string): number {
8+
let depth = 0
9+
let lastBalancedIndex = -1
10+
11+
for (let i = 0; i < input.length; i++) {
12+
const char = input[i]
13+
14+
if (char === '(') {
15+
depth++
16+
} else if (char === ')') {
17+
if (depth > 0) {
18+
depth--
19+
// when depth goes back to 0, it's a balanced pair
20+
if (depth === 0) {
21+
lastBalancedIndex = i
22+
}
23+
} else {
24+
// Unbalanced closing bracket
25+
return -1
26+
}
27+
}
28+
}
29+
30+
return lastBalancedIndex
31+
}

knip.json

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"entry": [
3+
"src/index.ts"
4+
],
5+
"project": [
6+
"src/**/*.{js,ts}"
7+
],
8+
"ignoreDependencies": [
9+
"@types/cookie",
10+
"arktype",
11+
"@elysiajs/openapi",
12+
"eslint-plugin-security",
13+
"expect-type",
14+
"prettier",
15+
"valibot",
16+
"zod",
17+
"file-type"
18+
],
19+
"ignoreBinaries": [
20+
"dist/bun/index.js"
21+
]
22+
}

package.json

Lines changed: 9 additions & 6 deletions
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.4.9-beta.0",
4+
"version": "1.4.10-beta.0",
55
"author": {
66
"name": "saltyAom",
77
"url": "https://github.com/SaltyAom",
@@ -178,14 +178,16 @@
178178
],
179179
"license": "MIT",
180180
"scripts": {
181-
"test": "npm run test:functionality && npm run test:types",
182-
"test:functionality": "bun test && bun run test:imports && npm run test:node",
183-
"test:imports": "bun run ./test/type-system/import.ts",
181+
"test": "bun run test:functionality && bun run test:types && bun run test:node && bun run test:cf",
182+
"test:functionality": "bun test && bun run test:imports",
183+
"test:imports": "bun run test/type-system/import.ts",
184184
"test:types": "tsc --project tsconfig.test.json",
185-
"test:node": "npm install --prefix ./test/node/cjs/ && npm install --prefix ./test/node/esm/ && node ./test/node/cjs/index.js && node ./test/node/esm/index.js && bun dist/bun/index.js",
185+
"test:node": "npm install --prefix test/node/cjs/ && npm install --prefix test/node/esm/ && node test/node/cjs/index.js && node test/node/esm/index.js",
186+
"test:cf": "npm install --prefix test/cloudflare && cd test/cloudflare && bun run cf-typegen && bun run test",
186187
"dev": "bun run --watch example/a.ts",
187188
"build": "rm -rf dist && bun build.ts",
188-
"release": "npm run build && npm run test && npm publish"
189+
"deadcode": "knip",
190+
"release": "bun run build && bun run test && bun publish"
189191
},
190192
"dependencies": {
191193
"cookie": "^1.0.2",
@@ -205,6 +207,7 @@
205207
"eslint-plugin-sonarjs": "^3.0.2",
206208
"expect-type": "^1.2.1",
207209
"file-type": "^20.4.1",
210+
"knip": "^5.64.1",
208211
"memoirist": "^0.4.0",
209212
"prettier": "^3.5.3",
210213
"tsup": "^8.4.0",

src/compose.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -486,7 +486,8 @@ export const composeHandler = ({
486486

487487
inference = sucrose(
488488
Object.assign({ handler: handler as any }, hooks),
489-
inference
489+
inference,
490+
app.config.sucrose
490491
)
491492

492493
if (adapter.declare) {

src/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3621,7 +3621,8 @@ export default class Elysia<
36213621
{
36223622
[type]: handles.map((x) => x.fn)
36233623
},
3624-
this.inference
3624+
this.inference,
3625+
this.config.sucrose
36253626
)
36263627

36273628
for (const handle of handles) {

src/sucrose.ts

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { checksum } from './utils'
44
import { isBun } from './universal/utils'
55

66
import type { Handler, HookContainer, LifeCycleStore } from './types'
7+
import { isCloudflareWorker } from './adapter/cloudflare-worker'
78

89
export namespace Sucrose {
910
export interface Inference {
@@ -21,6 +22,18 @@ export namespace Sucrose {
2122
export interface LifeCycle extends Partial<LifeCycleStore> {
2223
handler?: Handler
2324
}
25+
26+
export interface Settings {
27+
/**
28+
* If no sucrose usage is found in time
29+
* it's likely that server is either idle or
30+
* no new compilation is happening
31+
* clear the cache to free up memory
32+
*
33+
* @default 4 * 60 * 1000 + 55 * 1000 (4 minutes 55 seconds)
34+
*/
35+
gcTime?: number | null
36+
}
2437
}
2538

2639
/**
@@ -579,7 +592,11 @@ export const isContextPassToFunction = (
579592
let pendingGC: number | undefined
580593
let caches = <Record<number, Sucrose.Inference>>{}
581594

582-
export const clearSucroseCache = (delay = 0) => {
595+
export const clearSucroseCache = (delay: Sucrose.Settings['gcTime']) => {
596+
// Can't setTimeout outside fetch in Cloudflare Worker
597+
if (delay === null || isCloudflareWorker()) return
598+
if (delay === undefined) delay = 4 * 60 * 1000 + 55 * 1000
599+
583600
if (pendingGC) clearTimeout(pendingGC)
584601

585602
pendingGC = setTimeout(() => {
@@ -616,7 +633,8 @@ export const sucrose = (
616633
url: false,
617634
route: false,
618635
path: false
619-
}
636+
},
637+
settings: Sucrose.Settings = {}
620638
): Sucrose.Inference => {
621639
const events = <(Handler | HookContainer)[]>[]
622640

@@ -653,7 +671,7 @@ export const sucrose = (
653671
// it's likely that server is either idle or
654672
// no new compilation is happening
655673
// Clear the cache to free up memory
656-
clearSucroseCache(4 * 60 * 1000 + 55 * 1000)
674+
clearSucroseCache(settings.gcTime)
657675

658676
const fnInference: Sucrose.Inference = {
659677
query: false,

src/types.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ import type { WebSocketHandler } from './ws/bun'
3636

3737
import type { Instruction as ExactMirrorInstruction } from 'exact-mirror'
3838
import { BunHTMLBundlelike } from './universal/types'
39+
import { Sucrose } from './sucrose'
3940

4041
export type IsNever<T> = [T] extends [never] ? true : false
4142

@@ -233,6 +234,10 @@ export interface ElysiaConfig<Prefix extends string | undefined> {
233234
* @since 1.3.0
234235
*/
235236
sanitize?: ExactMirrorInstruction['sanitize']
237+
/**
238+
* Sucrose (Static Code Analysis) configuration
239+
*/
240+
sucrose?: Sucrose.Settings
236241
}
237242

238243
export interface ValidatorLayer {

test/cloudflare/.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
node_modules/
2+
package-lock.json
3+
.wrangler

0 commit comments

Comments
 (0)