@orpc/server 0.0.0-next.c59d67c → 0.0.0-next.db1f26d

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.
@@ -45,13 +45,92 @@ function decorateMiddleware(middleware) {
45
45
  }
46
46
 
47
47
  // src/procedure-caller.ts
48
- import { value } from "@orpc/shared";
48
+ import { trim, value } from "@orpc/shared";
49
49
  import { ORPCError } from "@orpc/shared/error";
50
50
  import { OpenAPIDeserializer } from "@orpc/transformer";
51
+
52
+ // src/procedure.ts
53
+ import {
54
+ DecoratedContractProcedure,
55
+ isContractProcedure
56
+ } from "@orpc/contract";
57
+ var Procedure = class {
58
+ constructor(zz$p) {
59
+ this.zz$p = zz$p;
60
+ }
61
+ };
62
+ var DECORATED_PROCEDURE_SYMBOL = Symbol("DECORATED_PROCEDURE");
63
+ function decorateProcedure(procedure) {
64
+ if (DECORATED_PROCEDURE_SYMBOL in procedure) {
65
+ return procedure;
66
+ }
67
+ return Object.assign(createProcedureCaller({
68
+ procedure,
69
+ context: void 0
70
+ }), {
71
+ [DECORATED_PROCEDURE_SYMBOL]: true,
72
+ zz$p: procedure.zz$p,
73
+ prefix(prefix) {
74
+ return decorateProcedure({
75
+ zz$p: {
76
+ ...procedure.zz$p,
77
+ contract: DecoratedContractProcedure.decorate(
78
+ procedure.zz$p.contract
79
+ ).prefix(prefix)
80
+ }
81
+ });
82
+ },
83
+ route(opts) {
84
+ return decorateProcedure({
85
+ zz$p: {
86
+ ...procedure.zz$p,
87
+ contract: DecoratedContractProcedure.decorate(
88
+ procedure.zz$p.contract
89
+ ).route(opts)
90
+ }
91
+ });
92
+ },
93
+ use(middleware, mapInput) {
94
+ const middleware_ = mapInput ? decorateMiddleware(middleware).mapInput(mapInput) : middleware;
95
+ return decorateProcedure({
96
+ zz$p: {
97
+ ...procedure.zz$p,
98
+ middlewares: [middleware_, ...procedure.zz$p.middlewares ?? []]
99
+ }
100
+ });
101
+ }
102
+ });
103
+ }
104
+ function isProcedure(item) {
105
+ if (item instanceof Procedure)
106
+ return true;
107
+ return (typeof item === "object" || typeof item === "function") && item !== null && "zz$p" in item && typeof item.zz$p === "object" && item.zz$p !== null && "contract" in item.zz$p && isContractProcedure(item.zz$p.contract) && "func" in item.zz$p && typeof item.zz$p.func === "function";
108
+ }
109
+
110
+ // src/procedure-caller.ts
51
111
  function createProcedureCaller(options) {
52
- const path = options.path ?? [];
53
- const procedure = options.procedure;
112
+ const loadProcedure = async () => {
113
+ let procedure;
114
+ if (isLazy(options.procedure)) {
115
+ procedure = (await loadLazy(options.procedure)).default;
116
+ } else {
117
+ procedure = options.procedure;
118
+ }
119
+ if (!isProcedure(procedure)) {
120
+ throw new ORPCError({
121
+ code: "NOT_FOUND",
122
+ message: "Not found",
123
+ cause: new Error(trim(`
124
+ This error should be caught by the typescript compiler.
125
+ But if you still see this error, it means that you trying to call a lazy router (expected to be a lazy procedure).
126
+ `))
127
+ });
128
+ }
129
+ return procedure;
130
+ };
54
131
  const caller = async (input) => {
132
+ const path = options.path ?? [];
133
+ const procedure = await loadProcedure();
55
134
  const input_ = (() => {
56
135
  if (!(input instanceof FormData)) {
57
136
  return input;
@@ -121,70 +200,68 @@ function createProcedureCaller(options) {
121
200
  return caller;
122
201
  }
123
202
 
124
- // src/procedure.ts
125
- import {
126
- DecoratedContractProcedure,
127
- isContractProcedure
128
- } from "@orpc/contract";
129
- var Procedure = class {
130
- constructor(zz$p) {
131
- this.zz$p = zz$p;
132
- }
133
- };
134
- var DECORATED_PROCEDURE_SYMBOL = Symbol("DECORATED_PROCEDURE");
135
- function decorateProcedure(procedure) {
136
- if (DECORATED_PROCEDURE_SYMBOL in procedure) {
137
- return procedure;
138
- }
139
- return Object.assign(createProcedureCaller({
140
- procedure,
203
+ // src/lazy.ts
204
+ var LAZY_LOADER_SYMBOL = Symbol("ORPC_LAZY_LOADER");
205
+ function createLazy(loader) {
206
+ return {
207
+ [LAZY_LOADER_SYMBOL]: loader
208
+ };
209
+ }
210
+ function loadLazy(lazy) {
211
+ return lazy[LAZY_LOADER_SYMBOL]();
212
+ }
213
+ function isLazy(item) {
214
+ return (typeof item === "object" || typeof item === "function") && item !== null && LAZY_LOADER_SYMBOL in item && typeof item[LAZY_LOADER_SYMBOL] === "function";
215
+ }
216
+ function createFlattenLazy(lazy) {
217
+ const flattenLoader = async () => {
218
+ let current = await loadLazy(lazy);
219
+ while (true) {
220
+ if (!isLazy(current.default)) {
221
+ break;
222
+ }
223
+ current = await loadLazy(current.default);
224
+ }
225
+ return current;
226
+ };
227
+ const flattenLazy = {
228
+ [LAZY_LOADER_SYMBOL]: flattenLoader
229
+ };
230
+ return flattenLazy;
231
+ }
232
+ function decorateLazy(lazy) {
233
+ const flattenLazy = createFlattenLazy(lazy);
234
+ const procedureCaller = createProcedureCaller({
235
+ procedure: flattenLazy,
141
236
  context: void 0
142
- }), {
143
- [DECORATED_PROCEDURE_SYMBOL]: true,
144
- zz$p: procedure.zz$p,
145
- prefix(prefix) {
146
- return decorateProcedure({
147
- zz$p: {
148
- ...procedure.zz$p,
149
- contract: DecoratedContractProcedure.decorate(
150
- procedure.zz$p.contract
151
- ).prefix(prefix)
152
- }
153
- });
154
- },
155
- route(opts) {
156
- return decorateProcedure({
157
- zz$p: {
158
- ...procedure.zz$p,
159
- contract: DecoratedContractProcedure.decorate(
160
- procedure.zz$p.contract
161
- ).route(opts)
162
- }
163
- });
164
- },
165
- use(middleware, mapInput) {
166
- const middleware_ = mapInput ? decorateMiddleware(middleware).mapInput(mapInput) : middleware;
167
- return decorateProcedure({
168
- zz$p: {
169
- ...procedure.zz$p,
170
- middlewares: [middleware_, ...procedure.zz$p.middlewares ?? []]
171
- }
172
- });
237
+ });
238
+ Object.assign(procedureCaller, flattenLazy);
239
+ const recursive = new Proxy(procedureCaller, {
240
+ get(target, key) {
241
+ if (typeof key !== "string") {
242
+ return Reflect.get(target, key);
243
+ }
244
+ return decorateLazy(createLazy(async () => {
245
+ const current = await loadLazy(flattenLazy);
246
+ return { default: current.default[key] };
247
+ }));
173
248
  }
174
249
  });
175
- }
176
- function isProcedure(item) {
177
- if (item instanceof Procedure)
178
- return true;
179
- return (typeof item === "object" || typeof item === "function") && item !== null && "zz$p" in item && typeof item.zz$p === "object" && item.zz$p !== null && "contract" in item.zz$p && isContractProcedure(item.zz$p.contract) && "func" in item.zz$p && typeof item.zz$p.func === "function";
250
+ return recursive;
180
251
  }
181
252
 
182
253
  export {
183
254
  mergeContext,
184
255
  decorateMiddleware,
256
+ LAZY_LOADER_SYMBOL,
257
+ createLazy,
258
+ loadLazy,
259
+ isLazy,
260
+ createFlattenLazy,
261
+ decorateLazy,
185
262
  createProcedureCaller,
186
263
  Procedure,
187
264
  decorateProcedure,
188
265
  isProcedure
189
266
  };
190
- //# sourceMappingURL=chunk-TDFYNRZV.js.map
267
+ //# sourceMappingURL=chunk-FL4ZAGNE.js.map
package/dist/fetch.js CHANGED
@@ -1,7 +1,8 @@
1
1
  import {
2
2
  createProcedureCaller,
3
+ isLazy,
3
4
  isProcedure
4
- } from "./chunk-TDFYNRZV.js";
5
+ } from "./chunk-FL4ZAGNE.js";
5
6
 
6
7
  // src/fetch/handle.ts
7
8
  import { ORPCError } from "@orpc/shared/error";
@@ -77,13 +78,13 @@ function resolveORPCRouter(router, pathname) {
77
78
  const path = trim(pathname, "/").split("/").map(decodeURIComponent);
78
79
  let current = router;
79
80
  for (const segment of path) {
80
- if ((typeof current !== "object" || current === null) && typeof current !== "function") {
81
+ if (typeof current !== "object" && typeof current !== "function" || !current) {
81
82
  current = void 0;
82
83
  break;
83
84
  }
84
85
  current = current[segment];
85
86
  }
86
- return isProcedure(current) ? {
87
+ return isProcedure(current) || isLazy(current) ? {
87
88
  procedure: current,
88
89
  path
89
90
  } : void 0;
package/dist/index.js CHANGED
@@ -1,11 +1,17 @@
1
1
  import {
2
+ LAZY_LOADER_SYMBOL,
2
3
  Procedure,
4
+ createFlattenLazy,
5
+ createLazy,
3
6
  createProcedureCaller,
7
+ decorateLazy,
4
8
  decorateMiddleware,
5
9
  decorateProcedure,
10
+ isLazy,
6
11
  isProcedure,
12
+ loadLazy,
7
13
  mergeContext
8
- } from "./chunk-TDFYNRZV.js";
14
+ } from "./chunk-FL4ZAGNE.js";
9
15
 
10
16
  // src/builder.ts
11
17
  import {
@@ -15,9 +21,138 @@ import {
15
21
 
16
22
  // src/procedure-builder.ts
17
23
  import {
18
- DecoratedContractProcedure
24
+ DecoratedContractProcedure as DecoratedContractProcedure2
19
25
  } from "@orpc/contract";
20
26
 
27
+ // src/router-builder.ts
28
+ import { DecoratedContractProcedure, prefixHTTPPath } from "@orpc/contract";
29
+ var LAZY_ROUTER_PREFIX_SYMBOL = Symbol("ORPC_LAZY_ROUTER_PREFIX");
30
+ var RouterBuilder = class _RouterBuilder {
31
+ constructor(zz$rb) {
32
+ this.zz$rb = zz$rb;
33
+ if (zz$rb.prefix && zz$rb.prefix.includes("{")) {
34
+ throw new Error('Prefix cannot contain "{" for dynamic routing');
35
+ }
36
+ }
37
+ prefix(prefix) {
38
+ return new _RouterBuilder({
39
+ ...this.zz$rb,
40
+ prefix: `${this.zz$rb.prefix ?? ""}${prefix}`
41
+ });
42
+ }
43
+ tags(...tags) {
44
+ if (!tags.length)
45
+ return this;
46
+ return new _RouterBuilder({
47
+ ...this.zz$rb,
48
+ tags: [...this.zz$rb.tags ?? [], ...tags]
49
+ });
50
+ }
51
+ use(middleware, mapInput) {
52
+ const middleware_ = mapInput ? decorateMiddleware(middleware).mapInput(mapInput) : middleware;
53
+ return new _RouterBuilder({
54
+ ...this.zz$rb,
55
+ middlewares: [...this.zz$rb.middlewares || [], middleware_]
56
+ });
57
+ }
58
+ router(router) {
59
+ const handled = adaptRouter({
60
+ routerOrChild: router,
61
+ middlewares: this.zz$rb.middlewares,
62
+ tags: this.zz$rb.tags,
63
+ prefix: this.zz$rb.prefix
64
+ });
65
+ return handled;
66
+ }
67
+ lazy(loader) {
68
+ const lazy = adaptLazyRouter({
69
+ current: createLazy(loader),
70
+ middlewares: this.zz$rb.middlewares,
71
+ tags: this.zz$rb.tags,
72
+ prefix: this.zz$rb.prefix
73
+ });
74
+ return lazy;
75
+ }
76
+ };
77
+ function adaptRouter(options) {
78
+ if (isProcedure(options.routerOrChild)) {
79
+ return adaptProcedure({
80
+ ...options,
81
+ procedure: options.routerOrChild
82
+ });
83
+ }
84
+ if (isLazy(options.routerOrChild)) {
85
+ return adaptLazyRouter({
86
+ ...options,
87
+ current: options.routerOrChild
88
+ });
89
+ }
90
+ const handled = {};
91
+ for (const key in options.routerOrChild) {
92
+ handled[key] = adaptRouter({
93
+ ...options,
94
+ routerOrChild: options.routerOrChild[key]
95
+ });
96
+ }
97
+ return handled;
98
+ }
99
+ function adaptLazyRouter(options) {
100
+ const loader = async () => {
101
+ const current = (await loadLazy(options.current)).default;
102
+ return {
103
+ default: adaptRouter({
104
+ ...options,
105
+ routerOrChild: current
106
+ })
107
+ };
108
+ };
109
+ let lazyRouterPrefix = options.prefix;
110
+ if (LAZY_ROUTER_PREFIX_SYMBOL in options.current && typeof options.current[LAZY_ROUTER_PREFIX_SYMBOL] === "string") {
111
+ lazyRouterPrefix = lazyRouterPrefix ? prefixHTTPPath(options.current[LAZY_ROUTER_PREFIX_SYMBOL], lazyRouterPrefix) : options.current[LAZY_ROUTER_PREFIX_SYMBOL];
112
+ }
113
+ const decoratedLazy = Object.assign(decorateLazy(createLazy(loader)), {
114
+ [LAZY_ROUTER_PREFIX_SYMBOL]: lazyRouterPrefix
115
+ });
116
+ const recursive = new Proxy(decoratedLazy, {
117
+ get(target, key) {
118
+ if (typeof key !== "string") {
119
+ return Reflect.get(target, key);
120
+ }
121
+ return adaptLazyRouter({
122
+ ...options,
123
+ current: createLazy(async () => {
124
+ const current = (await loadLazy(options.current)).default;
125
+ return { default: current[key] };
126
+ })
127
+ });
128
+ }
129
+ });
130
+ return recursive;
131
+ }
132
+ function adaptProcedure(options) {
133
+ const builderMiddlewares = options.middlewares ?? [];
134
+ const procedureMiddlewares = options.procedure.zz$p.middlewares ?? [];
135
+ const middlewares = [
136
+ ...builderMiddlewares,
137
+ ...procedureMiddlewares.filter(
138
+ (item) => !builderMiddlewares.includes(item)
139
+ )
140
+ ];
141
+ let contract = DecoratedContractProcedure.decorate(
142
+ options.procedure.zz$p.contract
143
+ ).addTags(...options.tags ?? []);
144
+ if (options.prefix) {
145
+ contract = contract.prefix(options.prefix);
146
+ }
147
+ return decorateProcedure({
148
+ zz$p: {
149
+ ...options.procedure.zz$p,
150
+ contract,
151
+ middlewares
152
+ }
153
+ });
154
+ }
155
+
21
156
  // src/procedure-implementer.ts
22
157
  var ProcedureImplementer = class _ProcedureImplementer {
23
158
  constructor(zz$pi) {
@@ -39,6 +174,9 @@ var ProcedureImplementer = class _ProcedureImplementer {
39
174
  }
40
175
  });
41
176
  }
177
+ lazy(loader) {
178
+ return new RouterBuilder(this.zz$pi).lazy(loader);
179
+ }
42
180
  };
43
181
 
44
182
  // src/procedure-builder.ts
@@ -52,7 +190,7 @@ var ProcedureBuilder = class _ProcedureBuilder {
52
190
  route(opts) {
53
191
  return new _ProcedureBuilder({
54
192
  ...this.zz$pb,
55
- contract: DecoratedContractProcedure.decorate(this.zz$pb.contract).route(
193
+ contract: DecoratedContractProcedure2.decorate(this.zz$pb.contract).route(
56
194
  opts
57
195
  )
58
196
  });
@@ -60,7 +198,7 @@ var ProcedureBuilder = class _ProcedureBuilder {
60
198
  input(schema, example) {
61
199
  return new _ProcedureBuilder({
62
200
  ...this.zz$pb,
63
- contract: DecoratedContractProcedure.decorate(this.zz$pb.contract).input(
201
+ contract: DecoratedContractProcedure2.decorate(this.zz$pb.contract).input(
64
202
  schema,
65
203
  example
66
204
  )
@@ -69,7 +207,7 @@ var ProcedureBuilder = class _ProcedureBuilder {
69
207
  output(schema, example) {
70
208
  return new _ProcedureBuilder({
71
209
  ...this.zz$pb,
72
- contract: DecoratedContractProcedure.decorate(this.zz$pb.contract).output(
210
+ contract: DecoratedContractProcedure2.decorate(this.zz$pb.contract).output(
73
211
  schema,
74
212
  example
75
213
  )
@@ -101,75 +239,24 @@ var ProcedureBuilder = class _ProcedureBuilder {
101
239
  }
102
240
  };
103
241
 
104
- // src/router-builder.ts
105
- import { DecoratedContractProcedure as DecoratedContractProcedure2 } from "@orpc/contract";
106
- var RouterBuilder = class _RouterBuilder {
107
- constructor(zz$rb) {
108
- this.zz$rb = zz$rb;
109
- }
110
- prefix(prefix) {
111
- return new _RouterBuilder({
112
- ...this.zz$rb,
113
- prefix: `${this.zz$rb.prefix ?? ""}${prefix}`
114
- });
115
- }
116
- tags(...tags) {
117
- if (!tags.length)
118
- return this;
119
- return new _RouterBuilder({
120
- ...this.zz$rb,
121
- tags: [...this.zz$rb.tags ?? [], ...tags]
122
- });
123
- }
124
- use(middleware, mapInput) {
125
- const middleware_ = mapInput ? decorateMiddleware(middleware).mapInput(mapInput) : middleware;
126
- return new _RouterBuilder({
127
- ...this.zz$rb,
128
- middlewares: [...this.zz$rb.middlewares || [], middleware_]
129
- });
130
- }
131
- router(router) {
132
- const handled = {};
133
- for (const key in router) {
134
- const item = router[key];
135
- if (isProcedure(item)) {
136
- const builderMiddlewares = this.zz$rb.middlewares ?? [];
137
- const itemMiddlewares = item.zz$p.middlewares ?? [];
138
- const middlewares = [
139
- ...builderMiddlewares,
140
- ...itemMiddlewares.filter(
141
- (item2) => !builderMiddlewares.includes(item2)
142
- )
143
- ];
144
- const contract = DecoratedContractProcedure2.decorate(
145
- item.zz$p.contract
146
- ).addTags(...this.zz$rb.tags ?? []);
147
- handled[key] = decorateProcedure({
148
- zz$p: {
149
- ...item.zz$p,
150
- contract: this.zz$rb.prefix ? contract.prefix(this.zz$rb.prefix) : contract,
151
- middlewares
152
- }
153
- });
154
- } else {
155
- handled[key] = this.router(item);
156
- }
157
- }
158
- return handled;
159
- }
160
- };
161
-
162
242
  // src/router-implementer.ts
163
- import {
164
- isContractProcedure
165
- } from "@orpc/contract";
243
+ import { isContractProcedure } from "@orpc/contract";
244
+ var ROUTER_CONTRACT_SYMBOL = Symbol("ORPC_ROUTER_CONTRACT");
166
245
  var RouterImplementer = class {
167
246
  constructor(zz$ri) {
168
247
  this.zz$ri = zz$ri;
169
248
  }
170
249
  router(router) {
171
- assertRouterImplementation(this.zz$ri.contract, router);
172
- return router;
250
+ return Object.assign(new RouterBuilder({}).router(router), {
251
+ [ROUTER_CONTRACT_SYMBOL]: this.zz$ri.contract
252
+ });
253
+ }
254
+ lazy(loader) {
255
+ const lazy = createLazy(loader);
256
+ const decorated = decorateLazy(lazy);
257
+ return Object.assign(decorated, {
258
+ [ROUTER_CONTRACT_SYMBOL]: this.zz$ri.contract
259
+ });
173
260
  }
174
261
  };
175
262
  function chainRouterImplementer(contract, middlewares) {
@@ -188,37 +275,6 @@ function chainRouterImplementer(contract, middlewares) {
188
275
  const implementer = new RouterImplementer({ contract });
189
276
  return Object.assign(implementer, result);
190
277
  }
191
- function assertRouterImplementation(contract, router, path = []) {
192
- for (const key in contract) {
193
- const currentPath = [...path, key];
194
- const contractItem = contract[key];
195
- const routerItem = router[key];
196
- if (!routerItem) {
197
- throw new Error(
198
- `Missing implementation for procedure at [${currentPath.join(".")}]`
199
- );
200
- }
201
- if (isContractProcedure(contractItem)) {
202
- if (isProcedure(routerItem)) {
203
- if (routerItem.zz$p.contract !== contractItem) {
204
- throw new Error(
205
- `Mismatch implementation for procedure at [${currentPath.join(".")}]`
206
- );
207
- }
208
- } else {
209
- throw new Error(
210
- `Mismatch implementation for procedure at [${currentPath.join(".")}]`
211
- );
212
- }
213
- } else {
214
- assertRouterImplementation(
215
- contractItem,
216
- routerItem,
217
- currentPath
218
- );
219
- }
220
- }
221
- }
222
278
 
223
279
  // src/builder.ts
224
280
  var Builder = class _Builder {
@@ -327,6 +383,9 @@ var Builder = class _Builder {
327
383
  router(router) {
328
384
  return new RouterBuilder(this.zz$b).router(router);
329
385
  }
386
+ lazy(loader) {
387
+ return new RouterBuilder(this.zz$b).lazy(loader);
388
+ }
330
389
  };
331
390
 
332
391
  // src/router.ts
@@ -350,25 +409,32 @@ function toContractRouter(router) {
350
409
 
351
410
  // src/router-caller.ts
352
411
  function createRouterCaller(options) {
353
- const caller = {};
354
- for (const key in options.router) {
355
- const path = [...options.basePath ?? [], key];
356
- const item = options.router[key];
357
- if (isProcedure(item)) {
358
- caller[key] = createProcedureCaller({
359
- procedure: item,
360
- context: options.context,
361
- path
362
- });
363
- } else {
364
- caller[key] = createRouterCaller({
365
- router: item,
412
+ return createRouterCallerInternal({
413
+ current: options.router,
414
+ context: options.context,
415
+ path: options.basePath ?? []
416
+ });
417
+ }
418
+ function createRouterCallerInternal(options) {
419
+ const procedureCaller = isLazy(options.current) || isProcedure(options.current) ? createProcedureCaller({
420
+ procedure: options.current,
421
+ context: options.context,
422
+ path: options.path
423
+ }) : {};
424
+ const recursive = new Proxy(procedureCaller, {
425
+ get(target, key) {
426
+ if (typeof key !== "string") {
427
+ return Reflect.get(target, key);
428
+ }
429
+ const next = options.current[key];
430
+ return createRouterCallerInternal({
431
+ current: next,
366
432
  context: options.context,
367
- basePath: path
433
+ path: [...options.path, key]
368
434
  });
369
435
  }
370
- }
371
- return caller;
436
+ });
437
+ return recursive;
372
438
  }
373
439
 
374
440
  // src/index.ts
@@ -376,17 +442,25 @@ export * from "@orpc/shared/error";
376
442
  var os = new Builder();
377
443
  export {
378
444
  Builder,
445
+ LAZY_LOADER_SYMBOL,
446
+ LAZY_ROUTER_PREFIX_SYMBOL,
379
447
  Procedure,
380
448
  ProcedureBuilder,
381
449
  ProcedureImplementer,
450
+ ROUTER_CONTRACT_SYMBOL,
451
+ RouterBuilder,
382
452
  RouterImplementer,
383
- assertRouterImplementation,
384
453
  chainRouterImplementer,
454
+ createFlattenLazy,
455
+ createLazy,
385
456
  createProcedureCaller,
386
457
  createRouterCaller,
458
+ decorateLazy,
387
459
  decorateMiddleware,
388
460
  decorateProcedure,
461
+ isLazy,
389
462
  isProcedure,
463
+ loadLazy,
390
464
  mergeContext,
391
465
  os,
392
466
  toContractRouter
@@ -1,9 +1,10 @@
1
1
  import type { IsEqual } from '@orpc/shared';
2
+ import type { DecoratedLazy } from './lazy';
3
+ import type { DecoratedProcedure, Procedure, ProcedureFunc } from './procedure';
2
4
  import type { HandledRouter, Router } from './router';
3
5
  import type { Context, MergeContext } from './types';
4
6
  import { ContractProcedure, type ContractRouter, type HTTPPath, type RouteOptions, type Schema, type SchemaInput, type SchemaOutput } from '@orpc/contract';
5
7
  import { type DecoratedMiddleware, type MapInputMiddleware, type Middleware } from './middleware';
6
- import { type DecoratedProcedure, type ProcedureFunc } from './procedure';
7
8
  import { ProcedureBuilder } from './procedure-builder';
8
9
  import { ProcedureImplementer } from './procedure-implementer';
9
10
  import { RouterBuilder } from './router-builder';
@@ -45,5 +46,8 @@ export declare class Builder<TContext extends Context, TExtraContext extends Con
45
46
  * Create DecoratedRouter
46
47
  */
47
48
  router<URouter extends Router<TContext>>(router: URouter): HandledRouter<URouter>;
49
+ lazy<U extends Router<TContext> | Procedure<TContext, any, any, any, any>>(loader: () => Promise<{
50
+ default: U;
51
+ }>): DecoratedLazy<U>;
48
52
  }
49
53
  //# sourceMappingURL=builder.d.ts.map
@@ -1,11 +1,13 @@
1
1
  import { Builder } from './builder';
2
2
  export * from './builder';
3
+ export * from './lazy';
3
4
  export * from './middleware';
4
5
  export * from './procedure';
5
6
  export * from './procedure-builder';
6
7
  export * from './procedure-caller';
7
8
  export * from './procedure-implementer';
8
9
  export * from './router';
10
+ export * from './router-builder';
9
11
  export * from './router-caller';
10
12
  export * from './router-implementer';
11
13
  export * from './types';
@@ -0,0 +1,23 @@
1
+ import type { Procedure } from './procedure';
2
+ import type { ProcedureCaller } from './procedure-caller';
3
+ export declare const LAZY_LOADER_SYMBOL: unique symbol;
4
+ export interface Lazy<T> {
5
+ [LAZY_LOADER_SYMBOL]: () => Promise<{
6
+ default: T;
7
+ }>;
8
+ }
9
+ export type ANY_LAZY = Lazy<any>;
10
+ export declare function createLazy<T>(loader: () => Promise<{
11
+ default: T;
12
+ }>): Lazy<T>;
13
+ export declare function loadLazy<T>(lazy: Lazy<T>): Promise<{
14
+ default: T;
15
+ }>;
16
+ export declare function isLazy(item: unknown): item is ANY_LAZY;
17
+ export type FlattenLazy<T> = T extends Lazy<infer U> ? FlattenLazy<U> : Lazy<T>;
18
+ export declare function createFlattenLazy<T>(lazy: Lazy<T>): FlattenLazy<T>;
19
+ export type DecoratedLazy<T> = T extends Lazy<infer U> ? DecoratedLazy<U> : (T extends Procedure<infer UContext, any, any, any, any> ? Lazy<T> & (undefined extends UContext ? ProcedureCaller<T> : unknown) : T extends Record<any, any> ? {
20
+ [K in keyof T]: DecoratedLazy<T[K]>;
21
+ } /** Notice: this still a lazy, but type not work when I & Lazy<T>, maybe it's a bug, should improve */ : Lazy<T>);
22
+ export declare function decorateLazy<T>(lazy: Lazy<T>): DecoratedLazy<T>;
23
+ //# sourceMappingURL=lazy.d.ts.map
@@ -1,12 +1,13 @@
1
1
  import type { SchemaInput, SchemaOutput } from '@orpc/contract';
2
- import type { Procedure } from './procedure';
2
+ import type { Lazy } from './lazy';
3
3
  import { type Value } from '@orpc/shared';
4
- export interface CreateProcedureCallerOptions<TProcedure extends Procedure<any, any, any, any, any>> {
4
+ import { type ANY_LAZY_PROCEDURE, type ANY_PROCEDURE, type Procedure } from './procedure';
5
+ export interface CreateProcedureCallerOptions<TProcedure extends ANY_PROCEDURE | ANY_LAZY_PROCEDURE> {
5
6
  procedure: TProcedure;
6
7
  /**
7
8
  * The context used when calling the procedure.
8
9
  */
9
- context: Value<TProcedure extends Procedure<infer UContext, any, any, any, any> ? UContext : never>;
10
+ context: Value<TProcedure extends Procedure<infer UContext, any, any, any, any> | Lazy<Procedure<infer UContext, any, any, any, any>> ? UContext : never>;
10
11
  /**
11
12
  * This is helpful for logging and analytics.
12
13
  *
@@ -14,6 +15,6 @@ export interface CreateProcedureCallerOptions<TProcedure extends Procedure<any,
14
15
  */
15
16
  path?: string[];
16
17
  }
17
- export type ProcedureCaller<TProcedure extends Procedure<any, any, any, any, any>> = TProcedure extends Procedure<any, any, infer UInputSchema, infer UOutputSchema, infer UFuncOutput> ? (...input: [input: SchemaInput<UInputSchema> | FormData] | (undefined extends SchemaInput<UInputSchema> ? [] : never)) => Promise<SchemaOutput<UOutputSchema, UFuncOutput>> : never;
18
- export declare function createProcedureCaller<TProcedure extends Procedure<any, any, any, any, any>>(options: CreateProcedureCallerOptions<TProcedure>): ProcedureCaller<TProcedure>;
18
+ export type ProcedureCaller<TProcedure extends ANY_PROCEDURE | ANY_LAZY_PROCEDURE> = TProcedure extends Procedure<any, any, infer UInputSchema, infer UOutputSchema, infer UFuncOutput> | Lazy<Procedure<any, any, infer UInputSchema, infer UOutputSchema, infer UFuncOutput>> ? (...input: [input: SchemaInput<UInputSchema> | FormData] | (undefined extends SchemaInput<UInputSchema> ? [] : never)) => Promise<SchemaOutput<UOutputSchema, UFuncOutput>> : never;
19
+ export declare function createProcedureCaller<TProcedure extends ANY_PROCEDURE | ANY_LAZY_PROCEDURE>(options: CreateProcedureCallerOptions<TProcedure>): ProcedureCaller<TProcedure>;
19
20
  //# sourceMappingURL=procedure-caller.d.ts.map
@@ -1,7 +1,8 @@
1
1
  import type { ContractProcedure, Schema, SchemaInput, SchemaOutput } from '@orpc/contract';
2
+ import type { DecoratedLazy } from './lazy';
3
+ import type { DecoratedProcedure, Procedure, ProcedureFunc } from './procedure';
2
4
  import type { Context, MergeContext } from './types';
3
5
  import { type MapInputMiddleware, type Middleware } from './middleware';
4
- import { type DecoratedProcedure, type ProcedureFunc } from './procedure';
5
6
  export declare class ProcedureImplementer<TContext extends Context, TExtraContext extends Context, TInputSchema extends Schema, TOutputSchema extends Schema> {
6
7
  zz$pi: {
7
8
  contract: ContractProcedure<TInputSchema, TOutputSchema>;
@@ -14,5 +15,8 @@ export declare class ProcedureImplementer<TContext extends Context, TExtraContex
14
15
  use<UExtraContext extends Partial<MergeContext<Context, MergeContext<TContext, TExtraContext>>> | undefined = undefined>(middleware: Middleware<MergeContext<TContext, TExtraContext>, UExtraContext, SchemaOutput<TInputSchema>, SchemaInput<TOutputSchema>>): ProcedureImplementer<TContext, MergeContext<TExtraContext, UExtraContext>, TInputSchema, TOutputSchema>;
15
16
  use<UExtraContext extends Partial<MergeContext<Context, MergeContext<TContext, TExtraContext>>> | undefined = undefined, UMappedInput = unknown>(middleware: Middleware<MergeContext<TContext, TExtraContext>, UExtraContext, UMappedInput, SchemaInput<TOutputSchema>>, mapInput: MapInputMiddleware<SchemaOutput<TInputSchema>, UMappedInput>): ProcedureImplementer<TContext, MergeContext<TExtraContext, UExtraContext>, TInputSchema, TOutputSchema>;
16
17
  func<UFuncOutput extends SchemaOutput<TOutputSchema>>(func: ProcedureFunc<TContext, TExtraContext, TInputSchema, TOutputSchema, UFuncOutput>): DecoratedProcedure<TContext, TExtraContext, TInputSchema, TOutputSchema, UFuncOutput>;
18
+ lazy<U extends Procedure<TContext, TExtraContext, TInputSchema, TOutputSchema, SchemaOutput<TOutputSchema>>>(loader: () => Promise<{
19
+ default: U;
20
+ }>): DecoratedLazy<U>;
17
21
  }
18
22
  //# sourceMappingURL=procedure-implementer.d.ts.map
@@ -1,4 +1,5 @@
1
1
  import type { Promisable } from '@orpc/shared';
2
+ import type { Lazy } from './lazy';
2
3
  import type { ProcedureCaller } from './procedure-caller';
3
4
  import type { Context, MergeContext, Meta } from './types';
4
5
  import { type ContractProcedure, type HTTPPath, type RouteOptions, type Schema, type SchemaInput, type SchemaOutput } from '@orpc/contract';
@@ -15,6 +16,9 @@ export declare class Procedure<TContext extends Context, TExtraContext extends C
15
16
  func: ProcedureFunc<TContext, TExtraContext, TInputSchema, TOutputSchema, TFuncOutput>;
16
17
  });
17
18
  }
19
+ export type ANY_PROCEDURE = Procedure<any, any, any, any, any>;
20
+ export type WELL_DEFINED_PROCEDURE = Procedure<Context, Context, Schema, Schema, unknown>;
21
+ export type ANY_LAZY_PROCEDURE = Lazy<ANY_PROCEDURE>;
18
22
  export type DecoratedProcedure<TContext extends Context, TExtraContext extends Context, TInputSchema extends Schema, TOutputSchema extends Schema, TFuncOutput extends SchemaOutput<TOutputSchema>> = Procedure<TContext, TExtraContext, TInputSchema, TOutputSchema, TFuncOutput> & {
19
23
  prefix: (prefix: HTTPPath) => DecoratedProcedure<TContext, TExtraContext, TInputSchema, TOutputSchema, TFuncOutput>;
20
24
  route: (opts: RouteOptions) => DecoratedProcedure<TContext, TExtraContext, TInputSchema, TOutputSchema, TFuncOutput>;
@@ -24,6 +28,5 @@ export interface ProcedureFunc<TContext extends Context, TExtraContext extends C
24
28
  (input: SchemaOutput<TInputSchema>, context: MergeContext<TContext, TExtraContext>, meta: Meta): Promisable<SchemaInput<TOutputSchema, TOutput>>;
25
29
  }
26
30
  export declare function decorateProcedure<TContext extends Context, TExtraContext extends Context, TInputSchema extends Schema, TOutputSchema extends Schema, TFuncOutput extends SchemaOutput<TOutputSchema>>(procedure: Procedure<TContext, TExtraContext, TInputSchema, TOutputSchema, TFuncOutput>): DecoratedProcedure<TContext, TExtraContext, TInputSchema, TOutputSchema, TFuncOutput>;
27
- export type WELL_DEFINED_PROCEDURE = Procedure<Context, Context, Schema, Schema, unknown>;
28
- export declare function isProcedure(item: unknown): item is WELL_DEFINED_PROCEDURE;
31
+ export declare function isProcedure(item: unknown): item is ANY_PROCEDURE;
29
32
  //# sourceMappingURL=procedure.d.ts.map
@@ -1,7 +1,9 @@
1
+ import type { DecoratedLazy } from './lazy';
1
2
  import type { HandledRouter, Router } from './router';
2
3
  import type { Context, MergeContext } from './types';
3
4
  import { type HTTPPath } from '@orpc/contract';
4
5
  import { type MapInputMiddleware, type Middleware } from './middleware';
6
+ export declare const LAZY_ROUTER_PREFIX_SYMBOL: unique symbol;
5
7
  export declare class RouterBuilder<TContext extends Context, TExtraContext extends Context> {
6
8
  zz$rb: {
7
9
  prefix?: HTTPPath;
@@ -18,5 +20,8 @@ export declare class RouterBuilder<TContext extends Context, TExtraContext exten
18
20
  use<UExtraContext extends Partial<MergeContext<Context, MergeContext<TContext, TExtraContext>>> | undefined = undefined>(middleware: Middleware<MergeContext<TContext, TExtraContext>, UExtraContext, unknown, unknown>): RouterBuilder<TContext, MergeContext<TExtraContext, UExtraContext>>;
19
21
  use<UExtraContext extends Partial<MergeContext<Context, MergeContext<TContext, TExtraContext>>> | undefined = undefined, UMappedInput = unknown>(middleware: Middleware<MergeContext<TContext, TExtraContext>, UExtraContext, UMappedInput, unknown>, mapInput: MapInputMiddleware<unknown, UMappedInput>): RouterBuilder<TContext, MergeContext<TExtraContext, UExtraContext>>;
20
22
  router<URouter extends Router<TContext>>(router: URouter): HandledRouter<URouter>;
23
+ lazy<U extends Router<TContext>>(loader: () => Promise<{
24
+ default: U;
25
+ }>): DecoratedLazy<U>;
21
26
  }
22
27
  //# sourceMappingURL=router-builder.d.ts.map
@@ -1,6 +1,6 @@
1
1
  import type { Value } from '@orpc/shared';
2
+ import type { ANY_LAZY_PROCEDURE, ANY_PROCEDURE } from './procedure';
2
3
  import type { Router } from './router';
3
- import { type Procedure } from './procedure';
4
4
  import { type ProcedureCaller } from './procedure-caller';
5
5
  export interface CreateRouterCallerOptions<TRouter extends Router<any>> {
6
6
  router: TRouter;
@@ -16,7 +16,7 @@ export interface CreateRouterCallerOptions<TRouter extends Router<any>> {
16
16
  basePath?: string[];
17
17
  }
18
18
  export type RouterCaller<TRouter extends Router<any>> = {
19
- [K in keyof TRouter]: TRouter[K] extends Procedure<any, any, any, any, any> ? ProcedureCaller<TRouter[K]> : TRouter[K] extends Router<any> ? RouterCaller<TRouter[K]> : never;
19
+ [K in keyof TRouter]: TRouter[K] extends ANY_PROCEDURE | ANY_LAZY_PROCEDURE ? ProcedureCaller<TRouter[K]> : TRouter[K] extends Router<any> ? RouterCaller<TRouter[K]> : never;
20
20
  };
21
21
  export declare function createRouterCaller<TRouter extends Router<any>>(options: CreateRouterCallerOptions<TRouter>): RouterCaller<TRouter>;
22
22
  //# sourceMappingURL=router-caller.d.ts.map
@@ -1,8 +1,10 @@
1
+ import type { DecoratedLazy } from './lazy';
1
2
  import type { Middleware } from './middleware';
2
- import type { RouterWithContract } from './router';
3
+ import type { HandledRouter, RouterWithContract } from './router';
3
4
  import type { Context } from './types';
4
5
  import { type ContractProcedure, type ContractRouter } from '@orpc/contract';
5
6
  import { ProcedureImplementer } from './procedure-implementer';
7
+ export declare const ROUTER_CONTRACT_SYMBOL: unique symbol;
6
8
  export declare class RouterImplementer<TContext extends Context, TContract extends ContractRouter> {
7
9
  zz$ri: {
8
10
  contract: TContract;
@@ -10,11 +12,13 @@ export declare class RouterImplementer<TContext extends Context, TContract exten
10
12
  constructor(zz$ri: {
11
13
  contract: TContract;
12
14
  });
13
- router(router: RouterWithContract<TContext, TContract>): RouterWithContract<TContext, TContract>;
15
+ router(router: RouterWithContract<TContext, TContract>): HandledRouter<RouterWithContract<TContext, TContract>>;
16
+ lazy(loader: () => Promise<{
17
+ default: RouterWithContract<TContext, TContract>;
18
+ }>): DecoratedLazy<RouterWithContract<TContext, TContract>>;
14
19
  }
15
20
  export type ChainedRouterImplementer<TContext extends Context, TContract extends ContractRouter, TExtraContext extends Context> = {
16
21
  [K in keyof TContract]: TContract[K] extends ContractProcedure<infer UInputSchema, infer UOutputSchema> ? ProcedureImplementer<TContext, TExtraContext, UInputSchema, UOutputSchema> : TContract[K] extends ContractRouter ? ChainedRouterImplementer<TContext, TContract[K], TExtraContext> : never;
17
22
  } & RouterImplementer<TContext, TContract>;
18
23
  export declare function chainRouterImplementer<TContext extends Context, TContract extends ContractRouter, TExtraContext extends Context>(contract: TContract, middlewares?: Middleware<any, any, any, any>[]): ChainedRouterImplementer<TContext, TContract, TExtraContext>;
19
- export declare function assertRouterImplementation(contract: ContractRouter, router: RouterWithContract<any, any>, path?: string[]): void;
20
24
  //# sourceMappingURL=router-implementer.d.ts.map
@@ -1,14 +1,15 @@
1
1
  import type { ContractProcedure, ContractRouter, SchemaInput, SchemaOutput } from '@orpc/contract';
2
+ import type { ANY_LAZY, DecoratedLazy, Lazy } from './lazy';
2
3
  import type { Context } from './types';
3
4
  import { type DecoratedProcedure, type Procedure } from './procedure';
4
5
  export interface Router<TContext extends Context> {
5
- [k: string]: Procedure<TContext, any, any, any, any> | Router<TContext>;
6
+ [k: string]: Procedure<TContext, any, any, any, any> | Lazy<Procedure<TContext, any, any, any, any>> | Router<TContext> | Lazy<Router<TContext>>;
6
7
  }
7
8
  export type HandledRouter<TRouter extends Router<any>> = {
8
- [K in keyof TRouter]: TRouter[K] extends Procedure<infer UContext, infer UExtraContext, infer UInputSchema, infer UOutputSchema, infer UFuncOutput> ? DecoratedProcedure<UContext, UExtraContext, UInputSchema, UOutputSchema, UFuncOutput> : TRouter[K] extends Router<any> ? HandledRouter<TRouter[K]> : never;
9
+ [K in keyof TRouter]: TRouter[K] extends Procedure<infer UContext, infer UExtraContext, infer UInputSchema, infer UOutputSchema, infer UFuncOutput> ? DecoratedProcedure<UContext, UExtraContext, UInputSchema, UOutputSchema, UFuncOutput> : TRouter[K] extends ANY_LAZY ? DecoratedLazy<TRouter[K]> : TRouter[K] extends Router<any> ? HandledRouter<TRouter[K]> : never;
9
10
  };
10
11
  export type RouterWithContract<TContext extends Context, TContract extends ContractRouter> = {
11
- [K in keyof TContract]: TContract[K] extends ContractProcedure<infer UInputSchema, infer UOutputSchema> ? Procedure<TContext, any, UInputSchema, UOutputSchema, any> : TContract[K] extends ContractRouter ? RouterWithContract<TContext, TContract[K]> : never;
12
+ [K in keyof TContract]: TContract[K] extends ContractProcedure<infer UInputSchema, infer UOutputSchema> ? Procedure<TContext, any, UInputSchema, UOutputSchema, any> | Lazy<Procedure<TContext, any, UInputSchema, UOutputSchema, any>> : TContract[K] extends ContractRouter ? RouterWithContract<TContext, TContract[K]> | Lazy<RouterWithContract<TContext, TContract[K]>> : never;
12
13
  };
13
14
  export declare function toContractRouter(router: ContractRouter | Router<any>): ContractRouter;
14
15
  export type InferRouterInputs<T extends Router<any>> = {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@orpc/server",
3
3
  "type": "module",
4
- "version": "0.0.0-next.c59d67c",
4
+ "version": "0.0.0-next.db1f26d",
5
5
  "license": "MIT",
6
6
  "homepage": "https://orpc.unnoq.com",
7
7
  "repository": {
@@ -35,15 +35,15 @@
35
35
  ],
36
36
  "peerDependencies": {
37
37
  "zod": ">=3.23.0",
38
- "@orpc/zod": "0.0.0-next.c59d67c"
38
+ "@orpc/zod": "0.0.0-next.db1f26d"
39
39
  },
40
40
  "dependencies": {
41
- "@orpc/contract": "0.0.0-next.c59d67c",
42
- "@orpc/shared": "0.0.0-next.c59d67c",
43
- "@orpc/transformer": "0.0.0-next.c59d67c"
41
+ "@orpc/contract": "0.0.0-next.db1f26d",
42
+ "@orpc/shared": "0.0.0-next.db1f26d",
43
+ "@orpc/transformer": "0.0.0-next.db1f26d"
44
44
  },
45
45
  "devDependencies": {
46
- "@orpc/openapi": "0.0.0-next.c59d67c"
46
+ "@orpc/openapi": "0.0.0-next.db1f26d"
47
47
  },
48
48
  "scripts": {
49
49
  "build": "tsup --clean --sourcemap --entry.index=src/index.ts --entry.fetch=src/fetch/index.ts --format=esm --onSuccess='tsc -b --noCheck'",