@lovrozagar/honey 0.4.2 → 0.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/README.md CHANGED
@@ -1539,7 +1539,7 @@ Import features from their path.
1539
1539
  | `honey/codegen-go-cli` | `generateGoCLI` |
1540
1540
  | `honey/codegen/extract` | ts-morph chain extractor |
1541
1541
  | `honey/build` | `createBuildPlugin` |
1542
- | `honey/tree` | Tree types + `mergeTree` |
1542
+ | `honey/tree` | Tree types + `mergeTree` + `assembleRouteTree` |
1543
1543
  | `honey/cli` | `honey` binary |
1544
1544
  | `honey/errors` | `defineErrors` (also on the root export) |
1545
1545
 
package/dist/codegen.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { type InvalidateCheckConfig } from "./invalidate-check.ts";
2
2
  import type { Honey } from "./index.ts";
3
- import type { TreeNode } from "./tree.ts";
3
+ import { type TreeNode } from "./tree.ts";
4
4
  export { prepareCodegen } from "./codegen-loaders.ts";
5
5
  export type { InvalidateCheckConfig, InvalidateCheckLevel } from "./invalidate-check.ts";
6
6
  export { toYaml, yamlSiblingPath } from "./yaml.ts";
@@ -1 +1 @@
1
- {"version":3,"file":"codegen.d.ts","sourceRoot":"","sources":["../src/codegen.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"codegen.d.ts","sourceRoot":"","sources":["../src/codegen.ts"],"names":[],"mappings":"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"}
package/dist/tree.d.ts CHANGED
@@ -76,6 +76,40 @@ export type RouteTree = {
76
76
  root: TreeNode;
77
77
  };
78
78
  export declare function createNode(): TreeNode;
79
+ /** Dense array, or unique-value table + per-row indices when that JSON is smaller. */
80
+ export type PackedColumn<T> = readonly T[] | {
81
+ readonly t: readonly T[];
82
+ readonly x: readonly number[];
83
+ };
84
+ /** Columnar packed route table consumed by `assembleRouteTree`. */
85
+ export type PackedRouteTable = {
86
+ /** Boundary error key. A string applies to every route. */
87
+ b?: Array<string | null> | string;
88
+ /** Per-route error-key lists. When `k` is set, each row is the extras beyond `k`. */
89
+ e?: PackedColumn<readonly string[] | null>;
90
+ /** Per-route input schemas. */
91
+ i?: PackedColumn<unknown>;
92
+ /** Error keys shared by every route; prepended onto each `e` row at inflate. */
93
+ k?: readonly string[];
94
+ /** Per-route meta objects. Keys are `u` indices when `u` is set. */
95
+ m?: PackedColumn<Record<string, unknown> | null>;
96
+ /** Per-route output schemas. */
97
+ o?: PackedColumn<unknown>;
98
+ /** Route selectors (`METHOD /path`), same order as the other columns. */
99
+ s: readonly string[];
100
+ /** Meta key dictionary; packed meta objects use decimal index keys. */
101
+ u?: readonly string[];
102
+ };
103
+ export declare function packInputSchemas(iv: unknown): unknown;
104
+ export declare function unpackInputSchemas(iv: unknown): unknown;
105
+ export declare function packOutputSchemas(os: unknown): unknown;
106
+ export declare function unpackOutputSchemas(os: unknown): unknown;
107
+ /**
108
+ * Inflate a packed route table into a live route tree.
109
+ * Each handler and each `ek` Set is a unique object so `.routeTree()` patches
110
+ * cannot cross-wire routes.
111
+ */
112
+ export declare function assembleRouteTree(table: PackedRouteTable): RouteTree;
79
113
  export declare function insertRoute(root: TreeNode, method: HttpMethod | "ALL", path: string, handler: RouteHandler): void;
80
114
  export declare function matchRoute(root: TreeNode, method: HttpMethod, path: string): MatchResult;
81
115
  export declare function insertWsRoute(root: TreeNode, path: string, handler: WSRouteHandler): void;
@@ -1 +1 @@
1
- {"version":3,"file":"tree.d.ts","sourceRoot":"","sources":["../src/tree.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tree.d.ts","sourceRoot":"","sources":["../src/tree.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lovrozagar/honey",
3
- "version": "0.4.2",
3
+ "version": "0.5.1",
4
4
  "description": "Type-safe API framework built on Web Standards. Builder-pattern DX, precompiled radix tree in production.",
5
5
  "keywords": [
6
6
  "api",
package/src/codegen.ts CHANGED
@@ -22,7 +22,14 @@ import {
22
22
  import { ERROR_META } from "./errors.ts"
23
23
  import type { ErrorMetaEntry } from "./errors.ts"
24
24
  import type { Honey } from "./index.ts"
25
- import type { RouteHandler, TreeNode } from "./tree.ts"
25
+ import {
26
+ type PackedColumn,
27
+ type PackedRouteTable,
28
+ packInputSchemas,
29
+ packOutputSchemas,
30
+ type RouteHandler,
31
+ type TreeNode,
32
+ } from "./tree.ts"
26
33
  import { irToTs } from "./ts-type-emitter.ts"
27
34
  import { createTypeEmitState, emitSchemaType } from "./type-emitter.ts"
28
35
  import type { TypeEmitState } from "./type-emitter.ts"
@@ -1991,217 +1998,192 @@ function collectRoutesForTree(node: TreeNode, currentPath: string, routes: Route
1991
1998
  }
1992
1999
  }
1993
2000
 
1994
- type TreeBuild = {
1995
- children: Record<string, TreeBuild>
1996
- dynamic: { child: TreeBuild; name: string } | null
1997
- handlers: Array<{ handler: string; method: string }>
1998
- wildcard: {
1999
- handlers: Array<{ handler: string; method: string }>
2000
- name: string
2001
- } | null
2001
+ function selectorOf(route: RouteConfig): string {
2002
+ return `${route.method} ${route.path}`
2002
2003
  }
2003
2004
 
2004
- function createTreeBuild(): TreeBuild {
2005
- return { children: {}, dynamic: null, handlers: [], wildcard: null }
2005
+ function encodePackedColumn<T>(values: T[]): PackedColumn<T> {
2006
+ const table: T[] = []
2007
+ const index: number[] = []
2008
+ const seen = new Map<string, number>()
2009
+ for (const value of values) {
2010
+ const key = JSON.stringify(value) ?? "null"
2011
+ let id = seen.get(key)
2012
+ if (id === undefined) {
2013
+ id = table.length
2014
+ seen.set(key, id)
2015
+ table.push(value)
2016
+ }
2017
+ index.push(id)
2018
+ }
2019
+ const dict: PackedColumn<T> = { t: table, x: index }
2020
+ return JSON.stringify(dict).length < JSON.stringify(values).length ? dict : values
2006
2021
  }
2007
2022
 
2008
- function serializeNode(node: TreeBuild): string {
2009
- const staticEntries = Object.entries(node.children)
2010
- const sExpr =
2011
- staticEntries.length > 0
2012
- ? `Object.assign(Object.create(null), { ${staticEntries.map(([k, v]) => `${JSON.stringify(k)}: ${serializeNode(v)}`).join(", ")} })`
2013
- : "E"
2014
-
2015
- const dExpr = node.dynamic
2016
- ? `{ n: ${JSON.stringify(node.dynamic.name)}, c: ${serializeNode(node.dynamic.child)} }`
2017
- : "null"
2018
-
2019
- const wExpr = node.wildcard
2020
- ? `{ n: ${JSON.stringify(node.wildcard.name)}, m: { ${node.wildcard.handlers.map((h) => `${h.method}: ${h.handler}`).join(", ")} } }`
2021
- : "null"
2022
-
2023
- const mExpr =
2024
- node.handlers.length > 0 ? `{ ${node.handlers.map((h) => `${h.method}: ${h.handler}`).join(", ")} }` : "null"
2025
-
2026
- return `{ s: ${sExpr}, d: ${dExpr}, w: ${wExpr}, m: ${mExpr}, ws: null }`
2023
+ function pickSmallerJson<T extends object>(candidate: T, fallback: T): T {
2024
+ return JSON.stringify(candidate).length < JSON.stringify(fallback).length ? candidate : fallback
2027
2025
  }
2028
2026
 
2029
- function toTsLiteral(v: unknown): string {
2030
- if (v === null) return "null"
2031
- if (v === true) return "true"
2032
- if (v === false) return "false"
2033
- if (Array.isArray(v)) return "unknown[]"
2034
- if (typeof v === "string") return JSON.stringify(v)
2035
- if (typeof v === "number") return String(v)
2036
- if (typeof v === "object") return "Record<string, unknown>"
2037
- return typeof v
2027
+ function sharedErrorKeys(rows: string[][]): string[] {
2028
+ if (rows.length === 0) return []
2029
+ const sets = rows.map((row) => new Set(row))
2030
+ return rows[0].filter((key) => sets.every((set) => set.has(key)))
2038
2031
  }
2039
2032
 
2040
- export function generateRouteTree(routes: RouteConfig[]): string {
2041
- const lines: string[] = []
2042
- lines.push('import type { TreeNode, RouteHandler, RouteTree } from "@lovrozagar/honey/tree"')
2043
- lines.push("")
2044
- lines.push("const E = Object.create(null) as Record<string, TreeNode>")
2045
- lines.push("")
2046
-
2047
- /* unique handler per route — no dedup, patching shared handlers would corrupt */
2048
- const handlerEntries: Array<{ index: number; route: RouteConfig }> = []
2049
- for (let i = 0; i < routes.length; i++) {
2050
- handlerEntries.push({ index: i, route: routes[i] })
2051
- }
2052
-
2053
- /* emit handler configs with pre-built ek and mt */
2054
- for (const { index, route } of handlerEntries) {
2055
- const mwList = "[]"
2056
- const bekExpr = route.boundaryErrorKey !== null ? JSON.stringify(route.boundaryErrorKey) : "null"
2057
- const ekSet = route.errorKeys.length > 0 ? `new Set(${JSON.stringify(route.errorKeys)})` : "new Set()"
2058
- const mtExpr = route.meta !== null ? JSON.stringify(route.meta) : "null"
2059
- const ivExpr =
2060
- route.inputSchemas !== null ? `${JSON.stringify(route.inputSchemas)} as unknown as RouteHandler["iv"]` : "null"
2061
- const osExpr =
2062
- route.outputSchemas !== null ? `${JSON.stringify(route.outputSchemas)} as unknown as RouteHandler["os"]` : "null"
2063
- lines.push(
2064
- `const H${index}: RouteHandler = { bek: ${bekExpr}, ef: null, fn: null as unknown as RouteHandler["fn"], mw: ${mwList}, ek: ${ekSet}, iv: ${ivExpr}, os: ${osExpr}, mt: ${mtExpr}, ov: null, rp: "" }`,
2065
- )
2066
- }
2067
-
2068
- lines.push("")
2069
-
2070
- /* build tree structure */
2071
- const rootBuild = createTreeBuild()
2072
-
2073
- for (const { index, route } of handlerEntries) {
2074
- const hName = `H${index}`
2075
- const segments = route.path.split("/").filter((s) => s.length > 0)
2076
- let node = rootBuild
2077
-
2078
- for (let i = 0; i < segments.length; i++) {
2079
- const seg = segments[i]
2080
- if (seg.startsWith("*")) {
2081
- const name = seg.length > 1 ? seg.slice(1) : "*"
2082
- if (node.wildcard === null) {
2083
- node.wildcard = { handlers: [], name }
2084
- }
2085
- node.wildcard.handlers.push({ handler: hName, method: route.method })
2086
- break
2087
- }
2088
- if (seg.startsWith(":")) {
2089
- const name = seg.endsWith("?") ? seg.slice(1, -1) : seg.slice(1)
2090
- if (node.dynamic === null) {
2091
- node.dynamic = { child: createTreeBuild(), name }
2092
- }
2093
- if (i === segments.length - 1) {
2094
- node.dynamic.child.handlers.push({
2095
- handler: hName,
2096
- method: route.method,
2097
- })
2098
- } else {
2099
- node = node.dynamic.child
2100
- }
2101
- continue
2102
- }
2103
- if (node.children[seg] === undefined) {
2104
- node.children[seg] = createTreeBuild()
2105
- }
2106
- if (i === segments.length - 1) {
2107
- node.children[seg].handlers.push({
2108
- handler: hName,
2109
- method: route.method,
2110
- })
2111
- } else {
2112
- node = node.children[seg]
2113
- }
2114
- }
2033
+ function encodeErrorKeys(rows: string[][]): Pick<PackedRouteTable, "e" | "k"> {
2034
+ if (!rows.some((row) => row.length > 0)) return {}
2035
+ const full: Pick<PackedRouteTable, "e" | "k"> = { e: encodePackedColumn(rows) }
2036
+ const shared = sharedErrorKeys(rows)
2037
+ if (shared.length === 0) return full
2038
+ const sharedSet = new Set(shared)
2039
+ const extras = rows.map((row) => row.filter((key) => !sharedSet.has(key)))
2040
+ const withBase: Pick<PackedRouteTable, "e" | "k"> = { k: shared }
2041
+ if (extras.some((row) => row.length > 0)) withBase.e = encodePackedColumn(extras)
2042
+ return pickSmallerJson(withBase, full)
2043
+ }
2115
2044
 
2116
- if (segments.length === 0) {
2117
- node.handlers.push({ handler: hName, method: route.method })
2045
+ function encodeMetaColumn(rows: Array<Record<string, unknown> | null>): Pick<PackedRouteTable, "m" | "u"> {
2046
+ if (!rows.some((row) => row !== null)) return {}
2047
+ const names: string[] = []
2048
+ const seen = new Set<string>()
2049
+ for (const row of rows) {
2050
+ if (row === null) continue
2051
+ for (const key of Object.keys(row)) {
2052
+ if (seen.has(key)) continue
2053
+ if (/^\d+$/.test(key)) return { m: encodePackedColumn(rows) }
2054
+ seen.add(key)
2055
+ names.push(key)
2118
2056
  }
2119
2057
  }
2120
-
2121
- lines.push(`export const tree: TreeNode = ${serializeNode(rootBuild)}`)
2122
- lines.push("")
2123
-
2124
- /* emit handler lookup map for .routeTree() patching */
2125
- const handlerMapEntries = handlerEntries.map(
2126
- ({ index, route }) => `\t${JSON.stringify(`${route.method} ${route.path}`)}: H${index}`,
2127
- )
2128
- lines.push(`export const handlers: Record<string, RouteHandler> = {\n${handlerMapEntries.join(",\n")}\n}`)
2129
- lines.push("")
2130
-
2131
- return lines.join("\n")
2058
+ if (names.length === 0) return { m: encodePackedColumn(rows) }
2059
+ const packed = rows.map((row) => {
2060
+ if (row === null) return null
2061
+ const out: Record<string, unknown> = Object.create(null)
2062
+ for (const [key, value] of Object.entries(row)) out[String(names.indexOf(key))] = value
2063
+ return out
2064
+ })
2065
+ return pickSmallerJson({ m: encodePackedColumn(packed), u: names }, { m: encodePackedColumn(rows) })
2132
2066
  }
2133
2067
 
2134
- function generateFromTreeRoot(root: TreeNode): string {
2135
- const routes: RouteConfig[] = []
2136
- collectRoutesForTree(root, "", routes)
2137
-
2138
- const collected: CollectedRoute[] = []
2139
- walkTree(root, "", collected)
2140
-
2141
- let code = generateRouteTree(routes)
2068
+ function packRouteTable(routes: RouteConfig[]): PackedRouteTable {
2069
+ const table: PackedRouteTable = { s: routes.map(selectorOf) }
2070
+ const b = routes.map((r) => r.boundaryErrorKey)
2071
+ const e = routes.map((r) => r.errorKeys)
2072
+ const i = routes.map((r) => packInputSchemas(r.inputSchemas))
2073
+ const o = routes.map((r) => packOutputSchemas(r.outputSchemas))
2074
+ const m = routes.map((r) => r.meta)
2075
+ if (b.some((x) => x !== null)) {
2076
+ const first = b[0]
2077
+ if (first !== null && b.every((x) => x === first)) table.b = first
2078
+ else table.b = b
2079
+ }
2080
+ Object.assign(table, encodeErrorKeys(e))
2081
+ if (i.some((x) => x !== null)) table.i = encodePackedColumn(i)
2082
+ if (o.some((x) => x !== null)) table.o = encodePackedColumn(o)
2083
+ Object.assign(table, encodeMetaColumn(m))
2084
+ return table
2085
+ }
2142
2086
 
2143
- /* emit meta export — full meta for gateway/external consumers */
2144
- const metaEntries: string[] = []
2145
- for (const { handler, method, path } of collected) {
2146
- if (handler.mt === null || Object.keys(handler.mt).length === 0) continue
2147
- metaEntries.push(`\t${JSON.stringify(`${method} ${path}`)}: ${JSON.stringify(handler.mt)}`)
2087
+ function emitPackedLiteral(value: unknown): string {
2088
+ const json = JSON.stringify(value)
2089
+ if (json.includes('"__proto__"')) {
2090
+ return `JSON.parse(${JSON.stringify(json)})`
2148
2091
  }
2092
+ return json
2093
+ }
2149
2094
 
2150
- /* emit MetaShape type from handler metas — preserve literal types */
2095
+ function collectMetaShape(collected: CollectedRoute[]): {
2096
+ allKeys: Map<string, Set<string>>
2097
+ keyCount: Map<string, number>
2098
+ metaHandlerCount: number
2099
+ } {
2151
2100
  const allKeys = new Map<string, Set<string>>()
2101
+ const keyCount = new Map<string, number>()
2152
2102
  let metaHandlerCount = 0
2153
2103
  for (const { handler } of collected) {
2154
2104
  if (handler.mt === null) continue
2155
2105
  metaHandlerCount++
2156
2106
  for (const [k, v] of Object.entries(handler.mt)) {
2157
2107
  if (!allKeys.has(k)) allKeys.set(k, new Set())
2158
- allKeys.get(k)?.add(toTsLiteral(v))
2159
- }
2160
- }
2161
-
2162
- /* count per-key occurrences to determine optionality */
2163
- const keyCount = new Map<string, number>()
2164
- for (const { handler } of collected) {
2165
- if (handler.mt === null) continue
2166
- for (const k of Object.keys(handler.mt)) {
2108
+ allKeys.get(k)?.add(emitLiteral(v))
2167
2109
  keyCount.set(k, (keyCount.get(k) ?? 0) + 1)
2168
2110
  }
2169
2111
  }
2112
+ return { allKeys, keyCount, metaHandlerCount }
2113
+ }
2170
2114
 
2171
- if (allKeys.size > 0) {
2172
- const props = [...allKeys.entries()]
2173
- .sort(([a], [b]) => a.localeCompare(b))
2174
- .map(([key, types]) => {
2175
- const optional = (keyCount.get(key) ?? 0) < metaHandlerCount ? "?" : ""
2176
- const safeKey = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(key) ? key : `"${key}"`
2177
- return `\t${safeKey}${optional}: ${[...types].join(" | ")}`
2178
- })
2179
- code += `\nexport type MetaShape = {\n${props.join("\n")}\n}\n\n`
2115
+ function emitMetaShapeType(shape: ReturnType<typeof collectMetaShape>): string {
2116
+ if (shape.allKeys.size === 0) return ""
2117
+ const props = [...shape.allKeys.entries()]
2118
+ .sort(([a], [b]) => a.localeCompare(b))
2119
+ .map(([key, types]) => {
2120
+ const optional = (shape.keyCount.get(key) ?? 0) < shape.metaHandlerCount ? "?" : ""
2121
+ const safeKey = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(key) ? key : `"${key}"`
2122
+ return `\t${safeKey}${optional}: ${[...types].join(" | ")}`
2123
+ })
2124
+ return `export type MetaShape = {\n${props.join("\n")}\n} & Record<string, unknown>\n`
2125
+ }
2126
+
2127
+ function emitRouteTree(routes: RouteConfig[], collected: CollectedRoute[] | null): string {
2128
+ const metaShape = collected !== null ? collectMetaShape(collected) : null
2129
+ const hasMetaShape = metaShape !== null && metaShape.allKeys.size > 0
2130
+ const selectors = routes.map(selectorOf)
2131
+ const table = packRouteTable(routes)
2132
+ const lines: string[] = []
2133
+ lines.push(
2134
+ 'import { assembleRouteTree, type PackedRouteTable, type RouteHandler, type RouteTree, type TreeNode } from "@lovrozagar/honey/tree"',
2135
+ )
2136
+ lines.push("")
2137
+ lines.push(`declare const P: readonly ${JSON.stringify(selectors)}`)
2138
+ lines.push(`const D: PackedRouteTable = ${emitPackedLiteral(table)}`)
2139
+ lines.push("export const routeTree: RouteTree = assembleRouteTree(D)")
2140
+ lines.push("export const tree: TreeNode = routeTree.root")
2141
+ lines.push("export const handlers: Record<string, RouteHandler> = routeTree.handlers ?? {}")
2142
+ let code = `${lines.join("\n")}\n`
2143
+ if (collected === null) return code
2144
+
2145
+ if (hasMetaShape && metaShape !== null) {
2146
+ code += `\n${emitMetaShapeType(metaShape)}\n`
2180
2147
  }
2181
2148
 
2182
- /* emit RouteSelector union from route graph */
2183
- const selectors = new Set<string>()
2149
+ const publicSelectors: string[] = []
2184
2150
  for (const { handler, method, path } of collected) {
2185
2151
  if (handler._skip || isMetaInternal(handler)) continue
2186
- selectors.add(`${method} ${path}`)
2152
+ publicSelectors.push(`${method} ${path}`)
2187
2153
  }
2188
- if (selectors.size > 0) {
2189
- const sorted = [...selectors].sort()
2190
- code += `\nexport type RouteSelector = ${sorted.map((s) => JSON.stringify(s)).join(" | ")}\n`
2154
+ if (publicSelectors.length > 0) {
2155
+ if (publicSelectors.length === selectors.length) {
2156
+ code += "export type RouteSelector = typeof P[number]\n"
2157
+ } else {
2158
+ const parts = publicSelectors.map((s) => {
2159
+ const idx = selectors.indexOf(s)
2160
+ return idx >= 0 ? `typeof P[${idx}]` : JSON.stringify(s)
2161
+ })
2162
+ code += `export type RouteSelector = ${parts.join(" | ")}\n`
2163
+ }
2191
2164
  }
2192
2165
 
2193
- if (metaEntries.length > 0) {
2194
- const metaType = allKeys.size > 0 ? "Record<string, MetaShape>" : "Record<string, Record<string, unknown>>"
2195
- code += `export const meta: ${metaType} = {\n${metaEntries.join(",\n")}\n}\n`
2166
+ const hasMeta = routes.some((r) => r.meta !== null && Object.keys(r.meta).length > 0)
2167
+ if (hasMeta) {
2168
+ const metaType = hasMetaShape ? "Record<string, MetaShape>" : "Record<string, Record<string, unknown>>"
2169
+ code += `export const meta: ${metaType} = routeTree.meta as ${metaType}\n`
2196
2170
  }
2197
2171
 
2198
- /* emit routeTree convenience export for .routeTree() */
2199
- const hasMetaExport = metaEntries.length > 0
2200
- code += `export const routeTree: RouteTree = { root: tree, ${hasMetaExport ? "meta, " : "meta: {}, "}handlers }\n`
2201
-
2202
2172
  return code
2203
2173
  }
2204
2174
 
2175
+ export function generateRouteTree(routes: RouteConfig[]): string {
2176
+ return emitRouteTree(routes, null)
2177
+ }
2178
+
2179
+ function generateFromTreeRoot(root: TreeNode): string {
2180
+ const routes: RouteConfig[] = []
2181
+ collectRoutesForTree(root, "", routes)
2182
+ const collected: CollectedRoute[] = []
2183
+ walkTree(root, "", collected)
2184
+ return emitRouteTree(routes, collected)
2185
+ }
2186
+
2205
2187
  export function generateRouteTreeFromApp<TEnv, TCtx>(
2206
2188
  app: Honey<TEnv, TCtx, unknown, unknown, unknown, string, string>,
2207
2189
  ): string {
package/src/tree.ts CHANGED
@@ -108,6 +108,399 @@ export function createNode(): TreeNode {
108
108
  }
109
109
  }
110
110
 
111
+ const UNSET_FN = null as unknown as RouteHandler["fn"]
112
+
113
+ /** Dense array, or unique-value table + per-row indices when that JSON is smaller. */
114
+ export type PackedColumn<T> = readonly T[] | { readonly t: readonly T[]; readonly x: readonly number[] }
115
+
116
+ /** Columnar packed route table consumed by `assembleRouteTree`. */
117
+ export type PackedRouteTable = {
118
+ /** Boundary error key. A string applies to every route. */
119
+ b?: Array<string | null> | string
120
+ /** Per-route error-key lists. When `k` is set, each row is the extras beyond `k`. */
121
+ e?: PackedColumn<readonly string[] | null>
122
+ /** Per-route input schemas. */
123
+ i?: PackedColumn<unknown>
124
+ /** Error keys shared by every route; prepended onto each `e` row at inflate. */
125
+ k?: readonly string[]
126
+ /** Per-route meta objects. Keys are `u` indices when `u` is set. */
127
+ m?: PackedColumn<Record<string, unknown> | null>
128
+ /** Per-route output schemas. */
129
+ o?: PackedColumn<unknown>
130
+ /** Route selectors (`METHOD /path`), same order as the other columns. */
131
+ s: readonly string[]
132
+ /** Meta key dictionary; packed meta objects use decimal index keys. */
133
+ u?: readonly string[]
134
+ }
135
+
136
+ const SCHEMA_KEY_PACK = new Map<string, string>([
137
+ ["$ref", "$"],
138
+ ["additionalItems", "ai"],
139
+ ["additionalProperties", "ap"],
140
+ ["allOf", "ao"],
141
+ ["anyOf", "yo"],
142
+ ["const", "c"],
143
+ ["contains", "cs"],
144
+ ["contentEncoding", "ce"],
145
+ ["contentMediaType", "cm"],
146
+ ["contentSchema", "cc"],
147
+ ["default", "d"],
148
+ ["definitions", "df"],
149
+ ["dependentRequired", "dr"],
150
+ ["dependentSchemas", "dh"],
151
+ ["description", "ds"],
152
+ ["else", "el"],
153
+ ["enum", "en"],
154
+ ["examples", "ex"],
155
+ ["exclusiveMaximum", "xm"],
156
+ ["exclusiveMinimum", "xn"],
157
+ ["format", "f"],
158
+ ["if", "if"],
159
+ ["items", "it"],
160
+ ["maxItems", "xi"],
161
+ ["maxLength", "xl"],
162
+ ["maxProperties", "xp"],
163
+ ["maximum", "xa"],
164
+ ["minItems", "ni"],
165
+ ["minLength", "nl"],
166
+ ["minProperties", "np"],
167
+ ["minimum", "na"],
168
+ ["multipleOf", "mo"],
169
+ ["not", "nt"],
170
+ ["nullable", "nu"],
171
+ ["oneOf", "oo"],
172
+ ["pattern", "pt"],
173
+ ["patternProperties", "pp"],
174
+ ["prefixItems", "pi"],
175
+ ["properties", "p"],
176
+ ["propertyNames", "pn"],
177
+ ["required", "r"],
178
+ ["then", "th"],
179
+ ["title", "ti"],
180
+ ["type", "t"],
181
+ ["unevaluatedItems", "ue"],
182
+ ["unevaluatedProperties", "up"],
183
+ ["uniqueItems", "ui"],
184
+ ])
185
+
186
+ function invertStringMap(src: Map<string, string>): Map<string, string> {
187
+ const out = new Map<string, string>()
188
+ for (const [long, short] of src) out.set(short, long)
189
+ return out
190
+ }
191
+
192
+ const SCHEMA_KEY_UNPACK = invertStringMap(SCHEMA_KEY_PACK)
193
+
194
+ const SCHEMA_TYPE_PACK = new Map<string, string>([
195
+ ["array", "a"],
196
+ ["boolean", "b"],
197
+ ["integer", "i"],
198
+ ["null", "l"],
199
+ ["number", "n"],
200
+ ["object", "o"],
201
+ ["string", "s"],
202
+ ])
203
+ const SCHEMA_TYPE_UNPACK = invertStringMap(SCHEMA_TYPE_PACK)
204
+
205
+ const SCHEMA_FORMAT_PACK = new Map<string, string>([
206
+ ["binary", "bin"],
207
+ ["date", "d"],
208
+ ["date-time", "dt"],
209
+ ["email", "e"],
210
+ ["hostname", "hn"],
211
+ ["int32", "i3"],
212
+ ["int64", "i6"],
213
+ ["ipv4", "v4"],
214
+ ["ipv6", "v6"],
215
+ ["time", "tm"],
216
+ ["uri", "u"],
217
+ ["uri-reference", "ur"],
218
+ ["uuid", "id"],
219
+ ])
220
+ const SCHEMA_FORMAT_UNPACK = invertStringMap(SCHEMA_FORMAT_PACK)
221
+
222
+ const INPUT_KEY_PACK = new Map<string, string>([
223
+ ["cookies", "c"],
224
+ ["form", "f"],
225
+ ["headers", "h"],
226
+ ["json", "j"],
227
+ ["params", "p"],
228
+ ["search", "q"],
229
+ ])
230
+ const INPUT_KEY_UNPACK = invertStringMap(INPUT_KEY_PACK)
231
+
232
+ const OUTPUT_CT_PACK = new Map<string, string>([
233
+ ["application/cbor", "cb"],
234
+ ["application/json", "j"],
235
+ ["application/msgpack", "mp"],
236
+ ["application/octet-stream", "os"],
237
+ ["application/pdf", "pf"],
238
+ ["application/xml", "xm"],
239
+ ["redirect", "rd"],
240
+ ["text/csv", "csv"],
241
+ ["text/event-stream", "sse"],
242
+ ["text/html", "ht"],
243
+ ["text/plain", "tp"],
244
+ ])
245
+ const OUTPUT_CT_UNPACK = invertStringMap(OUTPUT_CT_PACK)
246
+
247
+ const SCHEMA_NAME_CHILDREN = new Set(["$defs", "definitions", "dependentSchemas", "patternProperties", "properties"])
248
+ const SCHEMA_NODE_CHILDREN = new Set([
249
+ "$defs",
250
+ "additionalItems",
251
+ "additionalProperties",
252
+ "allOf",
253
+ "anyOf",
254
+ "contains",
255
+ "contentSchema",
256
+ "definitions",
257
+ "dependentSchemas",
258
+ "else",
259
+ "if",
260
+ "items",
261
+ "not",
262
+ "oneOf",
263
+ "patternProperties",
264
+ "prefixItems",
265
+ "properties",
266
+ "propertyNames",
267
+ "then",
268
+ "unevaluatedItems",
269
+ "unevaluatedProperties",
270
+ ])
271
+
272
+ function isPlainObject(value: unknown): value is Record<string, unknown> {
273
+ return value !== null && typeof value === "object" && !Array.isArray(value)
274
+ }
275
+
276
+ function remapLeaf(value: unknown, map: Map<string, string>): unknown {
277
+ if (typeof value === "string") return map.get(value) ?? value
278
+ if (Array.isArray(value)) {
279
+ return value.map((item) => (typeof item === "string" ? (map.get(item) ?? item) : item))
280
+ }
281
+ return value
282
+ }
283
+
284
+ function isNullTypeSchema(value: unknown): boolean {
285
+ return isPlainObject(value) && Object.keys(value).length === 1 && value.type === "null"
286
+ }
287
+
288
+ function packJsonSchema(node: unknown): unknown {
289
+ if (Array.isArray(node)) return node.map(packJsonSchema)
290
+ if (!isPlainObject(node)) return node
291
+
292
+ const oneOf = node.oneOf
293
+ if (Array.isArray(oneOf) && oneOf.length === 2 && Object.keys(node).length === 1) {
294
+ if (isPlainObject(oneOf[0]) && isNullTypeSchema(oneOf[1])) {
295
+ const packed = packJsonSchema(oneOf[0])
296
+ if (isPlainObject(packed)) {
297
+ packed.n1 = 1
298
+ return packed
299
+ }
300
+ }
301
+ if (isNullTypeSchema(oneOf[0]) && isPlainObject(oneOf[1])) {
302
+ const packed = packJsonSchema(oneOf[1])
303
+ if (isPlainObject(packed)) {
304
+ packed.n1 = 0
305
+ return packed
306
+ }
307
+ }
308
+ }
309
+
310
+ const out: Record<string, unknown> = Object.create(null)
311
+ for (const [key, value] of Object.entries(node)) {
312
+ const nextKey = SCHEMA_KEY_PACK.get(key) ?? key
313
+ if (key === "type") {
314
+ out[nextKey] = remapLeaf(value, SCHEMA_TYPE_PACK)
315
+ continue
316
+ }
317
+ if (key === "format") {
318
+ out[nextKey] = remapLeaf(value, SCHEMA_FORMAT_PACK)
319
+ continue
320
+ }
321
+ if (SCHEMA_NAME_CHILDREN.has(key) && isPlainObject(value)) {
322
+ const inner: Record<string, unknown> = Object.create(null)
323
+ for (const [name, child] of Object.entries(value)) inner[name] = packJsonSchema(child)
324
+ out[nextKey] = inner
325
+ continue
326
+ }
327
+ if (SCHEMA_NODE_CHILDREN.has(key)) {
328
+ out[nextKey] = packJsonSchema(value)
329
+ continue
330
+ }
331
+ out[nextKey] = value
332
+ }
333
+ return out
334
+ }
335
+
336
+ function unpackJsonSchema(node: unknown): unknown {
337
+ if (Array.isArray(node)) return node.map(unpackJsonSchema)
338
+ if (!isPlainObject(node)) return node
339
+
340
+ if (Object.hasOwn(node, "n1")) {
341
+ const copy: Record<string, unknown> = Object.create(null)
342
+ for (const [key, value] of Object.entries(node)) {
343
+ if (key !== "n1") copy[key] = value
344
+ }
345
+ const rest = unpackJsonSchema(copy)
346
+ const nullBranch = { type: "null" }
347
+ return node.n1 === 0 ? { oneOf: [nullBranch, rest] } : { oneOf: [rest, nullBranch] }
348
+ }
349
+
350
+ const out: Record<string, unknown> = Object.create(null)
351
+ for (const [key, value] of Object.entries(node)) {
352
+ const nextKey = SCHEMA_KEY_UNPACK.get(key) ?? key
353
+ if (nextKey === "type") {
354
+ out[nextKey] = remapLeaf(value, SCHEMA_TYPE_UNPACK)
355
+ continue
356
+ }
357
+ if (nextKey === "format") {
358
+ out[nextKey] = remapLeaf(value, SCHEMA_FORMAT_UNPACK)
359
+ continue
360
+ }
361
+ if (SCHEMA_NAME_CHILDREN.has(nextKey) && isPlainObject(value)) {
362
+ const inner: Record<string, unknown> = Object.create(null)
363
+ for (const [name, child] of Object.entries(value)) inner[name] = unpackJsonSchema(child)
364
+ out[nextKey] = inner
365
+ continue
366
+ }
367
+ if (SCHEMA_NODE_CHILDREN.has(nextKey)) {
368
+ out[nextKey] = unpackJsonSchema(value)
369
+ continue
370
+ }
371
+ out[nextKey] = value
372
+ }
373
+ return out
374
+ }
375
+
376
+ export function packInputSchemas(iv: unknown): unknown {
377
+ if (iv === null || typeof iv !== "object") return iv
378
+ const out: Record<string, unknown> = Object.create(null)
379
+ for (const [source, schema] of Object.entries(iv as Record<string, unknown>)) {
380
+ out[INPUT_KEY_PACK.get(source) ?? source] = packJsonSchema(schema)
381
+ }
382
+ return out
383
+ }
384
+
385
+ export function unpackInputSchemas(iv: unknown): unknown {
386
+ if (iv === null || typeof iv !== "object") return iv
387
+ const out: Record<string, unknown> = Object.create(null)
388
+ for (const [source, schema] of Object.entries(iv as Record<string, unknown>)) {
389
+ out[INPUT_KEY_UNPACK.get(source) ?? source] = unpackJsonSchema(schema)
390
+ }
391
+ return out
392
+ }
393
+
394
+ export function packOutputSchemas(os: unknown): unknown {
395
+ if (os === null || typeof os !== "object") return os
396
+ const out: Record<string, unknown> = Object.create(null)
397
+ for (const [contentType, statuses] of Object.entries(os as Record<string, unknown>)) {
398
+ const packedCt = OUTPUT_CT_PACK.get(contentType) ?? contentType
399
+ if (contentType === "redirect" || statuses === null || typeof statuses !== "object") {
400
+ out[packedCt] = statuses
401
+ continue
402
+ }
403
+ const inner: Record<string, unknown> = Object.create(null)
404
+ for (const [statusKey, schema] of Object.entries(statuses as Record<string, unknown>)) {
405
+ inner[statusKey] = schema === true ? true : packJsonSchema(schema)
406
+ }
407
+ out[packedCt] = inner
408
+ }
409
+ return out
410
+ }
411
+
412
+ export function unpackOutputSchemas(os: unknown): unknown {
413
+ if (os === null || typeof os !== "object") return os
414
+ const out: Record<string, unknown> = Object.create(null)
415
+ for (const [contentType, statuses] of Object.entries(os as Record<string, unknown>)) {
416
+ const longCt = OUTPUT_CT_UNPACK.get(contentType) ?? contentType
417
+ if (longCt === "redirect" || statuses === null || typeof statuses !== "object") {
418
+ out[longCt] = statuses
419
+ continue
420
+ }
421
+ const inner: Record<string, unknown> = Object.create(null)
422
+ for (const [statusKey, schema] of Object.entries(statuses as Record<string, unknown>)) {
423
+ inner[statusKey] = schema === true ? true : unpackJsonSchema(schema)
424
+ }
425
+ out[longCt] = inner
426
+ }
427
+ return out
428
+ }
429
+
430
+ function columnAt<T>(col: PackedColumn<T> | undefined, index: number, fallback: T): T {
431
+ if (col === undefined) return fallback
432
+ if (!Array.isArray(col) && "x" in col) {
433
+ const value = col.t[col.x[index]]
434
+ return (value === undefined ? fallback : value) as T
435
+ }
436
+ const value = col[index]
437
+ return (value === undefined ? fallback : value) as T
438
+ }
439
+
440
+ function mapColumn<T, U>(col: PackedColumn<T> | undefined, fn: (value: T) => U): PackedColumn<U> | undefined {
441
+ if (col === undefined) return undefined
442
+ if (!Array.isArray(col) && "x" in col) {
443
+ return { t: col.t.map(fn), x: col.x }
444
+ }
445
+ return (col as readonly T[]).map(fn)
446
+ }
447
+
448
+ function unpackMeta(
449
+ mt: Record<string, unknown> | null,
450
+ names: readonly string[] | undefined,
451
+ ): Record<string, unknown> | null {
452
+ if (mt === null || names === undefined) return mt
453
+ const out: Record<string, unknown> = Object.create(null)
454
+ for (const [key, value] of Object.entries(mt)) {
455
+ const idx = Number(key)
456
+ const name = Number.isInteger(idx) ? names[idx] : undefined
457
+ out[name ?? key] = value
458
+ }
459
+ return out
460
+ }
461
+
462
+ /**
463
+ * Inflate a packed route table into a live route tree.
464
+ * Each handler and each `ek` Set is a unique object so `.routeTree()` patches
465
+ * cannot cross-wire routes.
466
+ */
467
+ export function assembleRouteTree(table: PackedRouteTable): RouteTree {
468
+ const root = createNode()
469
+ const handlers: Record<string, RouteHandler> = Object.create(null)
470
+ const meta: Record<string, Record<string, unknown>> = Object.create(null)
471
+ const selectors = table.s
472
+ const sharedEk = table.k ?? []
473
+ const inputCol = mapColumn(table.i, unpackInputSchemas)
474
+ const outputCol = mapColumn(table.o, unpackOutputSchemas)
475
+ const metaCol = mapColumn(table.m, (mt) => unpackMeta(mt, table.u))
476
+ for (let i = 0; i < selectors.length; i++) {
477
+ const sel = selectors[i]
478
+ const bek = typeof table.b === "string" ? table.b : (table.b?.[i] ?? null)
479
+ const extra = columnAt(table.e, i, [] as readonly string[])
480
+ const mt = columnAt(metaCol, i, null)
481
+ const handler: RouteHandler = {
482
+ bek,
483
+ ef: null,
484
+ ek: new Set(sharedEk.length === 0 ? (extra ?? []) : [...sharedEk, ...(extra ?? [])]),
485
+ fn: UNSET_FN,
486
+ iv: columnAt(inputCol, i, null) as RouteHandler["iv"],
487
+ mt,
488
+ mw: [],
489
+ os: columnAt(outputCol, i, null) as RouteHandler["os"],
490
+ ov: null,
491
+ rp: "",
492
+ }
493
+ handlers[sel] = handler
494
+ if (mt !== null) meta[sel] = mt
495
+ const sp = sel.indexOf(" ")
496
+ if (sp === -1) {
497
+ throw new Error(`Invalid route selector: ${sel}`)
498
+ }
499
+ insertRoute(root, sel.slice(0, sp) as HttpMethod, sel.slice(sp + 1), handler)
500
+ }
501
+ return { handlers, meta, root }
502
+ }
503
+
111
504
  function splitSegments(path: string): string[] {
112
505
  return path.split("/").filter((s) => s.length > 0)
113
506
  }