Skip to content

Commit 3afb521

Browse files
authored
refactor(contract, server): improve lazy, naming, hidden, ... (#214)
- Improve lazy, no need FlatLazy anymore - Improve naming, - Improve hidden, <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **Documentation** - Updated the connection status header in the event iterator docs for clearer descriptions. - **Refactor** - Streamlined internal routing, builder, and middleware systems to improve type safety, error mapping, and lazy-loading performance. - **Tests** - Expanded test coverage to validate enhanced router and procedure functionalities. - Introduced new tests for `createAssertedLazyProcedure` and `createContractedProcedure`. - **Chores** - Consolidated module exports and internal utilities for improved maintainability. These improvements maintain existing functionality while enhancing stability and developer efficiency. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
1 parent 371be67 commit 3afb521

File tree

81 files changed

+1181
-1344
lines changed

Some content is hidden

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

81 files changed

+1181
-1344
lines changed

apps/content/docs/client/event-iterator.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ catch (error) {
7171
Errors thrown by the server can be instances of `ORPCError`.
7272
:::
7373

74-
## Event Iterator Connection Status
74+
## Connection Status
7575

7676
Combine with `onEventIteratorStatusChange` to track the connection status of the event iterator.
7777

packages/contract/src/builder-variants.test-d.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import type { ContractBuilder } from './builder'
33
import type { ContractProcedureBuilder, ContractProcedureBuilderWithInput, ContractProcedureBuilderWithInputOutput, ContractProcedureBuilderWithOutput, ContractRouterBuilder } from './builder-variants'
44
import type { MergedErrorMap } from './error'
55
import type { ContractProcedure } from './procedure'
6-
import type { AdaptedContractRouter } from './router'
6+
import type { EnhancedContractRouter } from './router-utils'
77
import { type baseErrorMap, type BaseMeta, generalSchema, type inputSchema, type outputSchema, ping, pong } from '../tests/shared'
88

99
const generalBuilder = {} as ContractBuilder<typeof inputSchema, typeof outputSchema, typeof baseErrorMap, BaseMeta>
@@ -311,7 +311,7 @@ describe('ContractRouterBuilder', () => {
311311
}
312312

313313
expectTypeOf(builder.router(router)).toEqualTypeOf<
314-
AdaptedContractRouter<typeof router, typeof baseErrorMap>
314+
EnhancedContractRouter<typeof router, typeof baseErrorMap>
315315
>()
316316

317317
// @ts-expect-error - invalid router

packages/contract/src/builder-variants.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ import type { ErrorMap, MergedErrorMap } from './error'
22
import type { Meta } from './meta'
33
import type { ContractProcedure } from './procedure'
44
import type { HTTPPath, Route } from './route'
5-
import type { AdaptContractRouterOptions, AdaptedContractRouter, ContractRouter } from './router'
5+
import type { ContractRouter } from './router'
6+
import type { EnhanceContractRouterOptions, EnhancedContractRouter } from './router-utils'
67
import type { Schema } from './schema'
78

89
export interface ContractProcedureBuilder<
@@ -101,7 +102,7 @@ export interface ContractRouterBuilder<
101102
TErrorMap extends ErrorMap,
102103
TMeta extends Meta,
103104
> {
104-
'~orpc': AdaptContractRouterOptions<TErrorMap>
105+
'~orpc': EnhanceContractRouterOptions<TErrorMap>
105106

106107
'errors'<U extends ErrorMap>(
107108
errors: U,
@@ -111,5 +112,5 @@ export interface ContractRouterBuilder<
111112

112113
'tag'(...tags: string[]): ContractRouterBuilder <TErrorMap, TMeta>
113114

114-
'router'<T extends ContractRouter<TMeta>>(router: T): AdaptedContractRouter <T, TErrorMap>
115+
'router'<T extends ContractRouter<TMeta>>(router: T): EnhancedContractRouter<T, TErrorMap>
115116
}

packages/contract/src/builder.test-d.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import type { ContractBuilder } from './builder'
33
import type { ContractProcedureBuilder, ContractProcedureBuilderWithInput, ContractProcedureBuilderWithOutput, ContractRouterBuilder } from './builder-variants'
44
import type { MergedErrorMap } from './error'
55
import type { ContractProcedure } from './procedure'
6-
import type { AdaptedContractRouter } from './router'
6+
import type { EnhancedContractRouter } from './router-utils'
77
import { generalSchema, ping, pong } from '../tests/shared'
88

99
const builder = {} as ContractBuilder<typeof inputSchema, typeof outputSchema, typeof baseErrorMap, BaseMeta>
@@ -135,7 +135,7 @@ describe('ContractBuilder', () => {
135135
}
136136

137137
expectTypeOf(builder.router(router)).toEqualTypeOf<
138-
AdaptedContractRouter<typeof router, typeof baseErrorMap>
138+
EnhancedContractRouter<typeof router, typeof baseErrorMap>
139139
>()
140140

141141
// @ts-expect-error - invalid router

packages/contract/src/builder.test.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ import { baseErrorMap, baseMeta, baseRoute, generalSchema, inputSchema, outputSc
22
import { ContractBuilder } from './builder'
33
import { mergeErrorMap } from './error'
44
import { isContractProcedure } from './procedure'
5-
import * as Router from './router'
5+
import * as RouterUtilsModule from './router-utils'
66

7-
const adaptContractRouterSpy = vi.spyOn(Router, 'adaptContractRouter')
7+
const enhanceContractRouterSpy = vi.spyOn(RouterUtilsModule, 'enhanceContractRouter')
88

99
const def = {
1010
errorMap: baseErrorMap,
@@ -126,8 +126,8 @@ describe('contractBuilder', () => {
126126
it('.router', () => {
127127
const router = { ping, pong }
128128
const applied = builder.router(router)
129-
expect(applied).toBe(adaptContractRouterSpy.mock.results[0]?.value)
130-
expect(adaptContractRouterSpy).toHaveBeenCalledOnce()
131-
expect(adaptContractRouterSpy).toHaveBeenCalledWith(router, def)
129+
expect(applied).toBe(enhanceContractRouterSpy.mock.results[0]?.value)
130+
expect(enhanceContractRouterSpy).toHaveBeenCalledOnce()
131+
expect(enhanceContractRouterSpy).toHaveBeenCalledWith(router, def)
132132
})
133133
})

packages/contract/src/builder.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
import type { ContractProcedureBuilder, ContractProcedureBuilderWithInput, ContractProcedureBuilderWithOutput, ContractRouterBuilder } from './builder-variants'
22
import type { ContractProcedureDef } from './procedure'
3-
import type { AdaptContractRouterOptions, AdaptedContractRouter, ContractRouter } from './router'
3+
import type { ContractRouter } from './router'
44
import type { Schema } from './schema'
55
import { type ErrorMap, type MergedErrorMap, mergeErrorMap } from './error'
66
import { mergeMeta, type Meta } from './meta'
77
import { ContractProcedure } from './procedure'
88
import { type HTTPPath, mergePrefix, mergeRoute, mergeTags, type Route } from './route'
9-
import { adaptContractRouter } from './router'
9+
import { enhanceContractRouter, type EnhanceContractRouterOptions, type EnhancedContractRouter } from './router-utils'
1010

1111
export interface ContractBuilderDef<
1212
TInputSchema extends Schema,
1313
TOutputSchema extends Schema,
1414
TErrorMap extends ErrorMap,
1515
TMeta extends Meta,
16-
> extends ContractProcedureDef<TInputSchema, TOutputSchema, TErrorMap, TMeta>, AdaptContractRouterOptions<TErrorMap> {
16+
> extends ContractProcedureDef<TInputSchema, TOutputSchema, TErrorMap, TMeta>, EnhanceContractRouterOptions<TErrorMap> {
1717
}
1818

1919
export class ContractBuilder<
@@ -114,8 +114,8 @@ export class ContractBuilder<
114114
})
115115
}
116116

117-
router<T extends ContractRouter<TMeta>>(router: T): AdaptedContractRouter<T, TErrorMap> {
118-
return adaptContractRouter(router, this['~orpc'])
117+
router<T extends ContractRouter<TMeta>>(router: T): EnhancedContractRouter<T, TErrorMap> {
118+
return enhanceContractRouter(router, this['~orpc'])
119119
}
120120
}
121121

packages/contract/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ export * from './procedure-client'
1111
export * from './route'
1212
export * from './router'
1313
export * from './router-client'
14+
export * from './router-utils'
1415
export * from './schema'
1516

1617
export { ORPCError } from '@orpc/client'

packages/contract/src/route.test.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { adaptRoute, mergePrefix, mergeRoute, mergeTags, prefixRoute, unshiftTagRoute } from './route'
1+
import { enhanceRoute, mergePrefix, mergeRoute, mergeTags, prefixRoute, unshiftTagRoute } from './route'
22

33
it('mergeRoute', () => {
44
expect(mergeRoute({ path: '/api' }, { path: '/v1' })).toEqual({ path: '/v1' })
@@ -29,14 +29,14 @@ it('mergeTags', () => {
2929
expect(mergeTags(['tag'], ['tag', 'tag2'])).toEqual(['tag', 'tag', 'tag2'])
3030
})
3131

32-
it('adaptRoute', () => {
32+
it('enhanceRoute', () => {
3333
const route = {
3434
path: '/api/v1',
3535
tags: ['tag'],
3636
description: 'description',
3737
} as const
3838

39-
expect(adaptRoute(route, {
39+
expect(enhanceRoute(route, {
4040
prefix: '/adapt',
4141
tags: ['adapt'],
4242
})).toEqual({
@@ -45,21 +45,21 @@ it('adaptRoute', () => {
4545
description: 'description',
4646
})
4747

48-
expect(adaptRoute(route, {
48+
expect(enhanceRoute(route, {
4949
prefix: '/adapt',
5050
})).toEqual({
5151
path: '/adapt/api/v1',
5252
tags: ['tag'],
5353
description: 'description',
5454
})
5555

56-
expect(adaptRoute(route, {
56+
expect(enhanceRoute(route, {
5757
tags: ['adapt'],
5858
})).toEqual({
5959
path: '/api/v1',
6060
tags: ['adapt', 'tag'],
6161
description: 'description',
6262
})
6363

64-
expect(adaptRoute(route, {})).toBe(route)
64+
expect(enhanceRoute(route, {})).toBe(route)
6565
})

packages/contract/src/route.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -101,19 +101,19 @@ export function mergeTags(a: readonly string[] | undefined, b: readonly string[]
101101
return a ? [...a, ...b] : b
102102
}
103103

104-
export interface AdaptRouteOptions {
104+
export interface EnhanceRouteOptions {
105105
prefix?: HTTPPath
106106
tags?: readonly string[]
107107
}
108108

109-
export function adaptRoute(route: Route, options: AdaptRouteOptions): Route {
109+
export function enhanceRoute(route: Route, options: EnhanceRouteOptions): Route {
110110
let router = route
111111

112112
if (options.prefix) {
113113
router = prefixRoute(router, options.prefix)
114114
}
115115

116-
if (options.tags) {
116+
if (options.tags?.length) {
117117
router = unshiftTagRoute(router, options.tags)
118118
}
119119

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import type { baseErrorMap, BaseMeta, inputSchema, outputSchema, router } from '../tests/shared'
2+
import type { MergedErrorMap } from './error'
3+
import type { Meta } from './meta'
4+
import type { ContractProcedure } from './procedure'
5+
import type { EnhancedContractRouter } from './router-utils'
6+
7+
it('EnhancedContractRouter', () => {
8+
const enhanced = {} as EnhancedContractRouter<typeof router, { INVALID: { status: number }, BASE2: { message: string } }>
9+
10+
expectTypeOf(enhanced.ping).toEqualTypeOf<
11+
ContractProcedure<
12+
typeof inputSchema,
13+
typeof outputSchema,
14+
MergedErrorMap<{ INVALID: { status: number }, BASE2: { message: string } }, typeof baseErrorMap>,
15+
BaseMeta
16+
>
17+
>()
18+
19+
expectTypeOf(enhanced.nested.ping).toEqualTypeOf<
20+
ContractProcedure<
21+
typeof inputSchema,
22+
typeof outputSchema,
23+
MergedErrorMap<{ INVALID: { status: number }, BASE2: { message: string } }, typeof baseErrorMap>,
24+
BaseMeta
25+
>
26+
>()
27+
28+
expectTypeOf(enhanced.pong).toEqualTypeOf<
29+
ContractProcedure<
30+
undefined,
31+
undefined,
32+
MergedErrorMap<{ INVALID: { status: number }, BASE2: { message: string } }, Record<never, never>>,
33+
Meta
34+
>
35+
>()
36+
37+
expectTypeOf(enhanced.nested.pong).toEqualTypeOf<
38+
ContractProcedure<
39+
undefined,
40+
undefined,
41+
MergedErrorMap<{ INVALID: { status: number }, BASE2: { message: string } }, Record<never, never>>,
42+
Meta
43+
>
44+
>()
45+
})

0 commit comments

Comments
 (0)