Skip to content

Commit 89e0c3f

Browse files
committed
Merge remote-tracking branch 'upstream/main' into c-env-type-each-handler
2 parents 5308071 + 502709f commit 89e0c3f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+918
-290
lines changed

.github/workflows/ci.yml

Lines changed: 35 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -181,45 +181,53 @@ jobs:
181181
name: coverage-lambda-edge
182182
path: coverage/
183183

184-
perf-measures-type-check-on-pr:
184+
perf-measures-type-and-bundle-check-on-pr:
185+
name: 'Type & Bundle size Check on PR'
185186
runs-on: ubuntu-latest
186187
if: github.event_name == 'pull_request'
187188
steps:
188189
- uses: actions/checkout@v4
189190
- uses: oven-sh/setup-bun@v2
190191
- run: bun install
191-
- uses: actions/cache/restore@v4
192-
with:
193-
path: perf-measures/type-check/previous-result.txt
194-
restore-keys: |
195-
type-check-perf-previous-result-
196-
key: type-check-perf-previous-result-
197-
- run: bun scripts/generate-app.ts
198-
working-directory: perf-measures/type-check
199-
- run: bun tsc -p tsconfig.build.json --diagnostics > result.txt
192+
- name: Performance measurement of type check
193+
run: |
194+
bun scripts/generate-app.ts
195+
bun tsc -p tsconfig.build.json --diagnostics | bun scripts/process-results.ts > diagnostics.json
200196
working-directory: perf-measures/type-check
201-
- run: |
202-
{
203-
echo 'COMPARISON<<EOF'
204-
bun scripts/process-results.ts | column -s '|' -t
205-
echo 'EOF'
206-
} >> "$GITHUB_ENV"
207-
working-directory: perf-measures/type-check
208-
- run: echo "$COMPARISON"
209-
name: display comparison
197+
- name: Performance measurement of bundle check
198+
run: |
199+
bun run build
200+
bun perf-measures/bundle-check/scripts/check-bundle-size.ts > perf-measures/bundle-check/size.json
201+
- name: Run octocov
202+
uses: k1LoW/octocov-action@v1
203+
with:
204+
config: perf-measures/.octocov.perf-measures.yml
205+
env:
206+
OCTOCOV_CUSTOM_METRICS_BENCHMARK_BUNDLE: perf-measures/bundle-check/size.json
207+
OCTOCOV_CUSTOM_METRICS_BENCHMARK_TYPE: perf-measures/type-check/diagnostics.json
210208

211-
perf-measures-type-check-on-main:
209+
perf-measures-type-and-bundle-check-on-main:
210+
name: 'Type & Bundle size Check on Main'
212211
runs-on: ubuntu-latest
213212
if: github.ref == 'refs/heads/main'
214213
steps:
215214
- uses: actions/checkout@v4
216215
- uses: oven-sh/setup-bun@v2
217216
- run: bun install
218-
- run: bun scripts/generate-app.ts
217+
- name: Performance measurement of type check
218+
run: |
219+
bun scripts/generate-app.ts
220+
bun tsc -p tsconfig.build.json --diagnostics | bun scripts/process-results.ts > diagnostics.json
219221
working-directory: perf-measures/type-check
220-
- run: bun tsc -p tsconfig.build.json --diagnostics > previous-result.txt
221-
working-directory: perf-measures/type-check
222-
- uses: actions/cache/save@v4
223-
with:
224-
path: perf-measures/type-check/previous-result.txt
225-
key: type-check-perf-previous-result-${{ github.sha }}
222+
- name: Performance measurement of bundle check
223+
run: |
224+
bun run build
225+
bun perf-measures/bundle-check/scripts/check-bundle-size.ts > perf-measures/bundle-check/size.json
226+
- name: Run octocov (main)
227+
uses: k1LoW/octocov-action@v1
228+
with:
229+
config: perf-measures/.octocov.perf-measures.main.yml
230+
env:
231+
OCTOCOV_GITHUB_REF: refs/heads/main
232+
OCTOCOV_CUSTOM_METRICS_BENCHMARK_BUNDLE: perf-measures/bundle-check/size.json
233+
OCTOCOV_CUSTOM_METRICS_BENCHMARK_TYPE: perf-measures/type-check/diagnostics.json

build/build.ts

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import type { Plugin, PluginBuild, BuildOptions } from 'esbuild'
1414
import * as glob from 'glob'
1515
import fs from 'fs'
1616
import path from 'path'
17-
import { removePrivateFields } from './remove-private-fields'
17+
import { cleanupWorkers, removePrivateFields } from './remove-private-fields'
1818
import { validateExports } from './validate-exports'
1919

2020
const args = arg({
@@ -102,14 +102,18 @@ const dtsEntries = glob.globSync('./dist/types/**/*.d.ts')
102102
const writer = stdout.writer()
103103
writer.write('\n')
104104
let lastOutputLength = 0
105-
for (let i = 0; i < dtsEntries.length; i++) {
106-
const entry = dtsEntries[i]
105+
let removedCount = 0
107106

108-
const message = `Removing private fields(${i + 1}/${dtsEntries.length}): ${entry}`
109-
writer.write(`\r${' '.repeat(lastOutputLength)}`)
110-
lastOutputLength = message.length
111-
writer.write(`\r${message}`)
107+
await Promise.all(
108+
dtsEntries.map(async (e) => {
109+
await fs.promises.writeFile(e, await removePrivateFields(e))
110+
111+
const message = `Private fields removed(${++removedCount}/${dtsEntries.length}): ${e}`
112+
writer.write(`\r${' '.repeat(lastOutputLength)}`)
113+
lastOutputLength = message.length
114+
writer.write(`\r${message}`)
115+
})
116+
)
112117

113-
fs.writeFileSync(entry, removePrivateFields(entry))
114-
}
115118
writer.write('\n')
119+
cleanupWorkers()

build/remove-private-fields.test.ts renamed to build/remove-private-fields-worker.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
/// <reference types="vitest/globals" />
22

3-
import { removePrivateFields } from './remove-private-fields'
43
import fs from 'node:fs/promises'
5-
import path from 'node:path'
64
import os from 'node:os'
5+
import path from 'node:path'
6+
import { removePrivateFields } from './remove-private-fields-worker'
77

88
describe('removePrivateFields', () => {
99
it('Works', async () => {

build/remove-private-fields-worker.ts

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
import * as ts from 'typescript'
2+
3+
export type WorkerInput = {
4+
file: string
5+
taskId: number
6+
}
7+
8+
export type WorkerOutput =
9+
| {
10+
type: 'success'
11+
value: string
12+
taskId: number
13+
}
14+
| {
15+
type: 'error'
16+
value: unknown
17+
taskId: number
18+
}
19+
20+
const removePrivateTransformer = <T extends ts.Node>(ctx: ts.TransformationContext) => {
21+
const visit: ts.Visitor = (node) => {
22+
if (ts.isClassDeclaration(node)) {
23+
const newMembers = node.members.filter((elem) => {
24+
if (ts.isPropertyDeclaration(elem) || ts.isMethodDeclaration(elem)) {
25+
for (const modifier of elem.modifiers ?? []) {
26+
if (modifier.kind === ts.SyntaxKind.PrivateKeyword) {
27+
return false
28+
}
29+
}
30+
}
31+
if (elem.name && ts.isPrivateIdentifier(elem.name)) {
32+
return false
33+
}
34+
return true
35+
})
36+
return ts.factory.createClassDeclaration(
37+
node.modifiers,
38+
node.name,
39+
node.typeParameters,
40+
node.heritageClauses,
41+
newMembers
42+
)
43+
}
44+
return ts.visitEachChild(node, visit, ctx)
45+
}
46+
47+
return (node: T) => {
48+
const visited = ts.visitNode(node, visit)
49+
if (!visited) {
50+
throw new Error('The result visited is undefined.')
51+
}
52+
return visited
53+
}
54+
}
55+
56+
export const removePrivateFields = (tsPath: string) => {
57+
const program = ts.createProgram([tsPath], {
58+
target: ts.ScriptTarget.ESNext,
59+
module: ts.ModuleKind.ESNext,
60+
})
61+
const file = program.getSourceFile(tsPath)
62+
63+
const transformed = ts.transform(file!, [removePrivateTransformer])
64+
const printer = ts.createPrinter()
65+
const transformedSourceFile = transformed.transformed[0] as ts.SourceFile
66+
const code = printer.printFile(transformedSourceFile)
67+
transformed.dispose()
68+
return code
69+
}
70+
71+
declare const self: Worker
72+
73+
if (globalThis.self) {
74+
self.addEventListener('message', function (e) {
75+
const { file, taskId } = e.data as WorkerInput
76+
77+
try {
78+
const result = removePrivateFields(file)
79+
self.postMessage({ type: 'success', value: result, taskId } satisfies WorkerOutput)
80+
} catch (e) {
81+
console.error(e)
82+
self.postMessage({ type: 'error', value: e, taskId } satisfies WorkerOutput)
83+
}
84+
})
85+
}

build/remove-private-fields.ts

Lines changed: 34 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,40 @@
1-
import * as ts from 'typescript'
1+
import { cpus } from 'node:os'
2+
import type { WorkerInput, WorkerOutput } from './remove-private-fields-worker'
23

3-
const removePrivateTransformer = <T extends ts.Node>(ctx: ts.TransformationContext) => {
4-
const visit: ts.Visitor = (node) => {
5-
if (ts.isClassDeclaration(node)) {
6-
const newMembers = node.members.filter((elem) => {
7-
if (ts.isPropertyDeclaration(elem) || ts.isMethodDeclaration(elem)) {
8-
for (const modifier of elem.modifiers ?? []) {
9-
if (modifier.kind === ts.SyntaxKind.PrivateKeyword) {
10-
return false
11-
}
12-
}
13-
}
14-
if (elem.name && ts.isPrivateIdentifier(elem.name)) {
15-
return false
16-
}
17-
return true
18-
})
19-
return ts.factory.createClassDeclaration(
20-
node.modifiers,
21-
node.name,
22-
node.typeParameters,
23-
node.heritageClauses,
24-
newMembers
25-
)
26-
}
27-
return ts.visitEachChild(node, visit, ctx)
28-
}
4+
const workers = Array.from({ length: Math.ceil(cpus().length / 2) }).map(
5+
() => new Worker(`${import.meta.dirname}/remove-private-fields-worker.ts`, { type: 'module' })
6+
)
7+
let workerIndex = 0
8+
let taskId = 0
299

30-
return (node: T) => {
31-
const visited = ts.visitNode(node, visit)
32-
if (!visited) {
33-
throw new Error('The result visited is undefined.')
34-
}
35-
return visited
36-
}
37-
}
10+
export async function removePrivateFields(file: string): Promise<string> {
11+
const currentTaskId = taskId++
12+
const worker = workers[workerIndex]
13+
workerIndex = (workerIndex + 1) % workers.length
3814

39-
export const removePrivateFields = (tsPath: string) => {
40-
const program = ts.createProgram([tsPath], {
41-
target: ts.ScriptTarget.ESNext,
42-
module: ts.ModuleKind.ESNext,
15+
return new Promise<string>((resolve, reject) => {
16+
const abortController = new AbortController()
17+
worker.addEventListener(
18+
'message',
19+
({ data: { type, value, taskId } }: { data: WorkerOutput }) => {
20+
if (taskId === currentTaskId) {
21+
if (type === 'success') {
22+
resolve(value)
23+
} else {
24+
reject(value)
25+
}
26+
27+
abortController.abort()
28+
}
29+
},
30+
{ signal: abortController.signal }
31+
)
32+
worker.postMessage({ file, taskId: currentTaskId } satisfies WorkerInput)
4333
})
44-
const file = program.getSourceFile(tsPath)
34+
}
4535

46-
const transformed = ts.transform(file!, [removePrivateTransformer])
47-
const printer = ts.createPrinter()
48-
const transformedSourceFile = transformed.transformed[0] as ts.SourceFile
49-
const code = printer.printFile(transformedSourceFile)
50-
transformed.dispose()
51-
return code
36+
export function cleanupWorkers() {
37+
for (const worker of workers) {
38+
worker.terminate()
39+
}
5240
}

jsr.json

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -110,9 +110,6 @@
110110
"jsr.json",
111111
"LICENSE",
112112
"README.md",
113-
"docs/CODE_OF_CONDUCT.md",
114-
"docs/CONTRIBUTING.md",
115-
"docs/MIGRATION.md",
116113
"src/**/*.ts"
117114
],
118115
"exclude": [

package.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "hono",
3-
"version": "4.6.10",
3+
"version": "4.6.17",
44
"description": "Web framework built on Web Standards",
55
"main": "dist/cjs/index.js",
66
"type": "module",
@@ -20,10 +20,10 @@
2020
"test:lambda": "vitest --run --config ./runtime-tests/lambda/vitest.config.ts",
2121
"test:lambda-edge": "vitest --run --config ./runtime-tests/lambda-edge/vitest.config.ts",
2222
"test:all": "bun run test && bun test:deno && bun test:bun && bun test:fastly && bun test:node && bun test:workerd && bun test:lambda && bun test:lambda-edge",
23-
"lint": "eslint src runtime-tests",
24-
"lint:fix": "eslint src runtime-tests --fix",
25-
"format": "prettier --check --cache \"src/**/*.{js,ts,tsx}\" \"runtime-tests/**/*.{js,ts,tsx}\" \"build/**/*.{js,ts,tsx}\"",
26-
"format:fix": "prettier --write --cache --cache-strategy metadata \"src/**/*.{js,ts,tsx}\" \"runtime-tests/**/*.{js,ts,tsx}\" \"build/**/*.{js,ts,tsx}\"",
23+
"lint": "eslint src runtime-tests build perf-measures",
24+
"lint:fix": "eslint src runtime-tests build perf-measures --fix",
25+
"format": "prettier --check --cache \"src/**/*.{js,ts,tsx}\" \"runtime-tests/**/*.{js,ts,tsx}\" \"build/**/*.{js,ts,tsx}\" \"perf-measures/**/*.{js,ts,tsx}\"",
26+
"format:fix": "prettier --write --cache --cache-strategy metadata \"src/**/*.{js,ts,tsx}\" \"runtime-tests/**/*.{js,ts,tsx}\" \"build/**/*.{js,ts,tsx}\" \"perf-measures/**/*.{js,ts,tsx}\"",
2727
"copy:package.cjs.json": "cp ./package.cjs.json ./dist/cjs/package.json && cp ./package.cjs.json ./dist/types/package.json",
2828
"build": "bun run --shell bun remove-dist && bun ./build/build.ts && bun run copy:package.cjs.json",
2929
"postbuild": "publint",
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
locale: "en"
2+
repository: ${GITHUB_REPOSITORY}/perf-measures
3+
coverage:
4+
if: false
5+
codeToTestRatio:
6+
if: false
7+
testExecutionTime:
8+
if: false
9+
report:
10+
datastores:
11+
- artifact://${GITHUB_REPOSITORY}
12+
summary:
13+
if: true
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
locale: "en"
2+
repository: ${GITHUB_REPOSITORY}/perf-measures
3+
coverage:
4+
if: false
5+
codeToTestRatio:
6+
if: false
7+
testExecutionTime:
8+
if: false
9+
diff:
10+
datastores:
11+
- artifact://${GITHUB_REPOSITORY}
12+
comment:
13+
if: is_pull_request
14+
summary:
15+
if: true

perf-measures/bundle-check/.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
generated
2+
!generated/.gitkeep
3+
size.json

perf-measures/bundle-check/generated/.gitkeep

Whitespace-only changes.

0 commit comments

Comments
 (0)