@replit/river 0.8.0 → 0.9.0

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.
Files changed (57) hide show
  1. package/README.md +2 -0
  2. package/dist/__tests__/bandwidth.bench.js +1 -1
  3. package/dist/__tests__/e2e.test.js +119 -5
  4. package/dist/__tests__/fixtures/cleanup.d.ts +12 -0
  5. package/dist/__tests__/fixtures/cleanup.d.ts.map +1 -0
  6. package/dist/__tests__/fixtures/cleanup.js +39 -0
  7. package/dist/__tests__/fixtures/services.d.ts +72 -0
  8. package/dist/__tests__/fixtures/services.d.ts.map +1 -1
  9. package/dist/__tests__/fixtures/services.js +55 -0
  10. package/dist/__tests__/handler.test.js +35 -2
  11. package/dist/__tests__/invariants.test.d.ts +2 -0
  12. package/dist/__tests__/invariants.test.d.ts.map +1 -0
  13. package/dist/__tests__/invariants.test.js +136 -0
  14. package/dist/__tests__/serialize.test.js +40 -0
  15. package/dist/__tests__/typescript-stress.test.d.ts +392 -196
  16. package/dist/__tests__/typescript-stress.test.d.ts.map +1 -1
  17. package/dist/__tests__/typescript-stress.test.js +13 -3
  18. package/dist/router/builder.d.ts +49 -11
  19. package/dist/router/builder.d.ts.map +1 -1
  20. package/dist/router/builder.js +8 -2
  21. package/dist/router/client.d.ts +18 -2
  22. package/dist/router/client.d.ts.map +1 -1
  23. package/dist/router/client.js +52 -11
  24. package/dist/router/index.d.ts +1 -1
  25. package/dist/router/index.d.ts.map +1 -1
  26. package/dist/router/server.d.ts +15 -1
  27. package/dist/router/server.d.ts.map +1 -1
  28. package/dist/router/server.js +106 -44
  29. package/dist/transport/events.d.ts +19 -0
  30. package/dist/transport/events.d.ts.map +1 -0
  31. package/dist/transport/events.js +26 -0
  32. package/dist/transport/impls/stdio/stdio.d.ts +0 -4
  33. package/dist/transport/impls/stdio/stdio.d.ts.map +1 -1
  34. package/dist/transport/impls/stdio/stdio.js +0 -5
  35. package/dist/transport/impls/stdio/stdio.test.js +5 -0
  36. package/dist/transport/impls/ws/client.d.ts.map +1 -1
  37. package/dist/transport/impls/ws/client.js +2 -2
  38. package/dist/transport/impls/ws/connection.d.ts.map +1 -1
  39. package/dist/transport/impls/ws/connection.js +2 -1
  40. package/dist/transport/impls/ws/server.d.ts +0 -2
  41. package/dist/transport/impls/ws/server.d.ts.map +1 -1
  42. package/dist/transport/impls/ws/server.js +4 -9
  43. package/dist/transport/impls/ws/ws.test.js +30 -10
  44. package/dist/transport/index.d.ts +3 -3
  45. package/dist/transport/index.d.ts.map +1 -1
  46. package/dist/transport/index.js +3 -3
  47. package/dist/transport/message.d.ts +10 -0
  48. package/dist/transport/message.d.ts.map +1 -1
  49. package/dist/transport/message.js +15 -0
  50. package/dist/transport/transport.d.ts +48 -19
  51. package/dist/transport/transport.d.ts.map +1 -1
  52. package/dist/transport/transport.js +60 -27
  53. package/dist/util/testHelpers.d.ts +58 -7
  54. package/dist/util/testHelpers.d.ts.map +1 -1
  55. package/dist/util/testHelpers.js +133 -3
  56. package/package.json +12 -13
  57. /package/dist/__tests__/{largePayload.json → fixtures/largePayload.json} +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"typescript-stress.test.d.ts","sourceRoot":"","sources":["../../__tests__/typescript-stress.test.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,SAAS,EAAE,sBAAsB,EAAS,MAAM,sBAAsB,CAAC;AAEhF,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AA8B/D,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmDlB,CAAC;AAGhB,qBAAa,aAAc,SAAQ,SAAS,CAAC,UAAU,CAAC;gBAC1C,QAAQ,EAAE,MAAM;IAI5B,IAAI,CAAC,GAAG,EAAE,sBAAsB,GAAG,SAAS;IAK5C,8BAA8B;IACxB,mBAAmB;IACnB,KAAK;CACZ"}
1
+ {"version":3,"file":"typescript-stress.test.d.ts","sourceRoot":"","sources":["../../__tests__/typescript-stress.test.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,SAAS,EAAE,sBAAsB,EAAS,MAAM,sBAAsB,CAAC;AAEhF,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAsC/D,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmDlB,CAAC;AAGhB,qBAAa,aAAc,SAAQ,SAAS,CAAC,UAAU,CAAC;gBAC1C,QAAQ,EAAE,MAAM;IAI5B,IAAI,CAAC,GAAG,EAAE,sBAAsB,GAAG,SAAS;IAK5C,8BAA8B;IACxB,mBAAmB;IACnB,KAAK;CACZ"}
@@ -7,8 +7,11 @@ import { Transport } from '../transport/transport';
7
7
  import { NaiveJsonCodec } from '../codec/json';
8
8
  import { createClient } from '../router/client';
9
9
  import { Ok } from '../router/result';
10
- const input = Type.Object({ a: Type.Number() });
11
- const output = Type.Object({ b: Type.Number() });
10
+ const input = Type.Union([
11
+ Type.Object({ a: Type.Number() }),
12
+ Type.Object({ c: Type.String() }),
13
+ ]);
14
+ const output = Type.Object({ b: Type.Union([Type.Number(), Type.String()]) });
12
15
  const errors = Type.Union([
13
16
  Type.Object({
14
17
  code: Type.Literal('ERROR1'),
@@ -25,7 +28,12 @@ const fnBody = {
25
28
  output,
26
29
  errors,
27
30
  async handler(_state, msg) {
28
- return reply(msg, Ok({ b: msg.payload.a }));
31
+ if ('c' in msg.payload) {
32
+ return reply(msg, Ok({ b: msg.payload.c }));
33
+ }
34
+ else {
35
+ return reply(msg, Ok({ b: msg.payload.a }));
36
+ }
29
37
  },
30
38
  };
31
39
  // typescript is limited to max 50 constraints
@@ -107,6 +115,8 @@ describe("ensure typescript doesn't give up trying to infer the types for large
107
115
  };
108
116
  const server = await createServer(new MockTransport('SERVER'), listing);
109
117
  const client = createClient(new MockTransport('client'));
118
+ expect(client.d.f48.rpc({ a: 0 })).toBeTruthy();
119
+ expect(client.a.f2.rpc({ c: 'abc' })).toBeTruthy();
110
120
  expect(server).toBeTruthy();
111
121
  expect(client).toBeTruthy();
112
122
  });
@@ -4,9 +4,11 @@ import { TransportMessage } from '../transport/message';
4
4
  import { ServiceContextWithState } from './context';
5
5
  import { Result, RiverError, RiverUncaughtSchema } from './result';
6
6
  /**
7
- * The valid {@link Procedure} types.
7
+ * The valid {@link Procedure} types. The `stream` and `upload` types can optionally have a
8
+ * different type for the very first initialization message. The suffixless types correspond to
9
+ * gRPC's four combinations of stream / non-stream in each direction.
8
10
  */
9
- export type ValidProcType = 'rpc' | 'stream' | 'subscription';
11
+ export type ValidProcType = 'rpc' | 'upload' | 'subscription' | 'stream';
10
12
  /**
11
13
  * A generic procedure listing where the keys are the names of the procedures
12
14
  * and the values are the {@link Procedure} definitions. This is not meant to
@@ -38,6 +40,20 @@ export declare function serializeService(s: AnyService): object;
38
40
  * @template ProcName - The name of the procedure.
39
41
  */
40
42
  export type ProcHandler<S extends AnyService, ProcName extends keyof S['procedures']> = S['procedures'][ProcName]['handler'];
43
+ /**
44
+ * Helper to get whether the type definition for the procedure contains an init type.
45
+ * @template S - The service.
46
+ * @template ProcName - The name of the procedure.
47
+ */
48
+ export type ProcHasInit<S extends AnyService, ProcName extends keyof S['procedures']> = S['procedures'][ProcName] extends {
49
+ init: any;
50
+ } ? true : false;
51
+ /**
52
+ * Helper to get the type definition for the procedure init type of a service.
53
+ * @template S - The service.
54
+ * @template ProcName - The name of the procedure.
55
+ */
56
+ export type ProcInit<S extends AnyService, ProcName extends keyof S['procedures']> = S['procedures'][ProcName]['init'];
41
57
  /**
42
58
  * Helper to get the type definition for the procedure input of a service.
43
59
  * @template S - The service.
@@ -62,33 +78,55 @@ export type ProcErrors<S extends AnyService, ProcName extends keyof S['procedure
62
78
  * @template ProcName - The name of the procedure.
63
79
  */
64
80
  export type ProcType<S extends AnyService, ProcName extends keyof S['procedures']> = S['procedures'][ProcName]['type'];
81
+ export type PayloadType = TObject | TUnion<TObject[]>;
65
82
  /**
66
83
  * Defines a Procedure type that can be either an RPC or a stream procedure.
67
84
  * @template State - The TypeBox schema of the state object.
68
85
  * @template Ty - The type of the procedure.
69
86
  * @template I - The TypeBox schema of the input object.
70
87
  * @template O - The TypeBox schema of the output object.
88
+ * @template Init - The TypeBox schema of the input initialization object.
71
89
  */
72
- export type Procedure<State extends object | unknown, Ty extends ValidProcType, I extends TObject, O extends TObject, E extends RiverError> = Ty extends 'rpc' ? {
90
+ export type Procedure<State extends object | unknown, Ty extends ValidProcType, I extends PayloadType, O extends PayloadType, E extends RiverError, Init extends PayloadType | null = null> = Ty extends 'rpc' ? Init extends null ? {
73
91
  input: I;
74
92
  output: O;
75
93
  errors: E;
76
94
  handler: (context: ServiceContextWithState<State>, input: TransportMessage<Static<I>>) => Promise<TransportMessage<Result<Static<O>, Static<E>>>>;
77
95
  type: Ty;
78
- } : Ty extends 'stream' ? {
96
+ } : never : Ty extends 'upload' ? Init extends PayloadType ? {
97
+ init: Init;
79
98
  input: I;
80
99
  output: O;
81
100
  errors: E;
82
- handler: (context: ServiceContextWithState<State>, input: AsyncIterable<TransportMessage<Static<I>>>, output: Pushable<TransportMessage<Result<Static<O>, Static<E>>>>) => Promise<void>;
101
+ handler: (context: ServiceContextWithState<State>, init: TransportMessage<Static<Init>>, input: AsyncIterable<TransportMessage<Static<I>>>) => Promise<TransportMessage<Result<Static<O>, Static<E>>>>;
102
+ type: Ty;
103
+ } : {
104
+ input: I;
105
+ output: O;
106
+ errors: E;
107
+ handler: (context: ServiceContextWithState<State>, input: AsyncIterable<TransportMessage<Static<I>>>) => Promise<TransportMessage<Result<Static<O>, Static<E>>>>;
83
108
  type: Ty;
84
- } : Ty extends 'subscription' ? {
109
+ } : Ty extends 'subscription' ? Init extends null ? {
85
110
  input: I;
86
111
  output: O;
87
112
  errors: E;
88
113
  handler: (context: ServiceContextWithState<State>, input: TransportMessage<Static<I>>, output: Pushable<TransportMessage<Result<Static<O>, Static<E>>>>) => Promise<void>;
89
114
  type: Ty;
115
+ } : never : Ty extends 'stream' ? Init extends PayloadType ? {
116
+ init: Init;
117
+ input: I;
118
+ output: O;
119
+ errors: E;
120
+ handler: (context: ServiceContextWithState<State>, init: TransportMessage<Static<Init>>, input: AsyncIterable<TransportMessage<Static<I>>>, output: Pushable<TransportMessage<Result<Static<O>, Static<E>>>>) => Promise<void>;
121
+ type: Ty;
122
+ } : {
123
+ input: I;
124
+ output: O;
125
+ errors: E;
126
+ handler: (context: ServiceContextWithState<State>, input: AsyncIterable<TransportMessage<Static<I>>>, output: Pushable<TransportMessage<Result<Static<O>, Static<E>>>>) => Promise<void>;
127
+ type: Ty;
90
128
  } : never;
91
- export type AnyProcedure = Procedure<object, ValidProcType, TObject, TObject, RiverError>;
129
+ export type AnyProcedure = Procedure<object, ValidProcType, PayloadType, PayloadType, RiverError, PayloadType | null>;
92
130
  /**
93
131
  * A builder class for creating River Services.
94
132
  * You must call the finalize method to get the finalized schema for use in a service router.
@@ -116,14 +154,14 @@ export declare class ServiceBuilder<T extends Service<string, object, ProcListin
116
154
  /**
117
155
  * Defines a new procedure for the service.
118
156
  * @param {ProcName} procName The name of the procedure.
119
- * @param {Procedure<T['state'], Ty, I, O>} procDef The definition of the procedure.
120
- * @returns {ServiceBuilder<{ name: T['name']; state: T['state']; procedures: T['procedures'] & { [k in ProcName]: Procedure<T['state'], Ty, I, O>; }; }>} A new ServiceBuilder instance with the updated schema.
157
+ * @param {Procedure<T['state'], Ty, I, O, E, Init>} procDef The definition of the procedure.
158
+ * @returns {ServiceBuilder<{ name: T['name']; state: T['state']; procedures: T['procedures'] & { [k in ProcName]: Procedure<T['state'], Ty, I, O, E, Init>; }; }>} A new ServiceBuilder instance with the updated schema.
121
159
  */
122
- defineProcedure<ProcName extends string, Ty extends ValidProcType, I extends TObject, O extends TObject, E extends RiverError>(procName: ProcName, procDef: Procedure<T['state'], Ty, I, O, E>): ServiceBuilder<{
160
+ defineProcedure<ProcName extends string, Ty extends ValidProcType, I extends PayloadType, O extends PayloadType, E extends RiverError, Init extends PayloadType | null = null>(procName: ProcName, procDef: Procedure<T['state'], Ty, I, O, E, Init>): ServiceBuilder<{
123
161
  name: T['name'];
124
162
  state: T['state'];
125
163
  procedures: T['procedures'] & {
126
- [k in ProcName]: Procedure<T['state'], Ty, I, O, E>;
164
+ [k in ProcName]: Procedure<T['state'], Ty, I, O, E, Init>;
127
165
  };
128
166
  }>;
129
167
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"builder.d.ts","sourceRoot":"","sources":["../../router/builder.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"builder.d.ts","sourceRoot":"","sources":["../../router/builder.ts"],"names":[],"mappings":"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"}
@@ -15,6 +15,12 @@ export function serializeService(s) {
15
15
  output: Type.Strict(procDef.output),
16
16
  errors: Type.Strict(procDef.errors),
17
17
  type: procDef.type,
18
+ // Only add the `init` field if the type declares it.
19
+ ...('init' in procDef
20
+ ? {
21
+ init: Type.Strict(procDef.init),
22
+ }
23
+ : {}),
18
24
  },
19
25
  ])),
20
26
  };
@@ -51,8 +57,8 @@ export class ServiceBuilder {
51
57
  /**
52
58
  * Defines a new procedure for the service.
53
59
  * @param {ProcName} procName The name of the procedure.
54
- * @param {Procedure<T['state'], Ty, I, O>} procDef The definition of the procedure.
55
- * @returns {ServiceBuilder<{ name: T['name']; state: T['state']; procedures: T['procedures'] & { [k in ProcName]: Procedure<T['state'], Ty, I, O>; }; }>} A new ServiceBuilder instance with the updated schema.
60
+ * @param {Procedure<T['state'], Ty, I, O, E, Init>} procDef The definition of the procedure.
61
+ * @returns {ServiceBuilder<{ name: T['name']; state: T['state']; procedures: T['procedures'] & { [k in ProcName]: Procedure<T['state'], Ty, I, O, E, Init>; }; }>} A new ServiceBuilder instance with the updated schema.
56
62
  */
57
63
  defineProcedure(procName, procDef) {
58
64
  const newProcedure = { [procName]: procDef };
@@ -1,5 +1,5 @@
1
1
  import { Connection, Transport } from '../transport/transport';
2
- import { AnyService, ProcErrors, ProcInput, ProcOutput, ProcType } from './builder';
2
+ import { AnyService, ProcErrors, ProcHasInit, ProcInit, ProcInput, ProcOutput, ProcType } from './builder';
3
3
  import type { Pushable } from 'it-pushable';
4
4
  import { Server } from './server';
5
5
  import { TransportClientId } from '../transport/message';
@@ -14,7 +14,23 @@ type AsyncIter<T> = AsyncGenerator<T, T, unknown>;
14
14
  type ServiceClient<Router extends AnyService> = {
15
15
  [ProcName in keyof Router['procedures']]: ProcType<Router, ProcName> extends 'rpc' ? {
16
16
  rpc: (input: Static<ProcInput<Router, ProcName>>) => Promise<Result<Static<ProcOutput<Router, ProcName>>, Static<ProcErrors<Router, ProcName>>>>;
17
- } : ProcType<Router, ProcName> extends 'stream' ? {
17
+ } : ProcType<Router, ProcName> extends 'upload' ? ProcHasInit<Router, ProcName> extends true ? {
18
+ upload: (init: Static<ProcInit<Router, ProcName>>) => Promise<[
19
+ Pushable<Static<ProcInput<Router, ProcName>>>,
20
+ Promise<Result<Static<ProcOutput<Router, ProcName>>, Static<ProcErrors<Router, ProcName>>>>
21
+ ]>;
22
+ } : {
23
+ upload: () => Promise<[
24
+ Pushable<Static<ProcInput<Router, ProcName>>>,
25
+ Promise<Result<Static<ProcOutput<Router, ProcName>>, Static<ProcErrors<Router, ProcName>>>>
26
+ ]>;
27
+ } : ProcType<Router, ProcName> extends 'stream' ? ProcHasInit<Router, ProcName> extends true ? {
28
+ stream: (init: Static<ProcInit<Router, ProcName>>) => Promise<[
29
+ Pushable<Static<ProcInput<Router, ProcName>>>,
30
+ AsyncIter<Result<Static<ProcOutput<Router, ProcName>>, Static<ProcErrors<Router, ProcName>>>>,
31
+ () => void
32
+ ]>;
33
+ } : {
18
34
  stream: () => Promise<[
19
35
  Pushable<Static<ProcInput<Router, ProcName>>>,
20
36
  AsyncIter<Result<Static<ProcOutput<Router, ProcName>>, Static<ProcErrors<Router, ProcName>>>>,
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../router/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,EACL,UAAU,EACV,UAAU,EACV,SAAS,EACT,UAAU,EACV,QAAQ,EACT,MAAM,WAAW,CAAC;AAEnB,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAIL,iBAAiB,EAElB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAG3C,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAGlC,KAAK,SAAS,CAAC,CAAC,IAAI,cAAc,CAAC,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC;AAElD;;;;GAIG;AACH,KAAK,aAAa,CAAC,MAAM,SAAS,UAAU,IAAI;KAC7C,QAAQ,IAAI,MAAM,MAAM,CAAC,YAAY,CAAC,GAAG,QAAQ,CAChD,MAAM,EACN,QAAQ,CACT,SAAS,KAAK,GACX;QACE,GAAG,EAAE,CACH,KAAK,EAAE,MAAM,CAAC,SAAS,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,KACvC,OAAO,CACV,MAAM,CACJ,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,EACpC,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CACrC,CACF,CAAC;KACH,GACD,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,SAAS,QAAQ,GAC3C;QACE,MAAM,EAAE,MAAM,OAAO,CACnB;YACE,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;YAC7C,SAAS,CACP,MAAM,CACJ,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,EACpC,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CACrC,CACF;YACD,MAAM,IAAI;SACX,CACF,CAAC;KACH,GACD,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,SAAS,cAAc,GACjD;QACE,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,SAAS,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,KAAK,OAAO,CAChE;YACE,SAAS,CACP,MAAM,CACJ,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,EACpC,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CACrC,CACF;YACD,MAAM,IAAI;SACX,CACF,CAAC;KACH,GACD,KAAK;CACV,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,YAAY,CAAC,GAAG,SAAS,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,IAAI;KACxE,OAAO,IAAI,MAAM,GAAG,CAAC,UAAU,CAAC,GAAG,aAAa,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,OAAO,CAAC,CAAC;CAC5E,CAAC;AAgCF;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,YAAY,8DACZ,UAAU,UAAU,CAAC,aACtB,iBAAiB,sBAmHA,CAAC"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../router/client.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { pushable } from 'it-pushable';
2
- import { msg, } from '../transport/message';
2
+ import { msg, isStreamClose, closeStream, } from '../transport/message';
3
3
  import { waitForMessage } from '../transport';
4
4
  import { nanoid } from 'nanoid';
5
5
  const noop = () => { };
@@ -49,29 +49,41 @@ export const createClient = (transport, serverId = 'SERVER') => _createRecursive
49
49
  if (procType === 'stream') {
50
50
  const inputStream = pushable({ objectMode: true });
51
51
  const outputStream = pushable({ objectMode: true });
52
+ let firstMessage = true;
53
+ if (input) {
54
+ const m = msg(transport.clientId, serverId, serviceName, procName, streamId, input);
55
+ // first message needs the open bit.
56
+ m.controlFlags = 2 /* ControlFlags.StreamOpenBit */;
57
+ transport.send(m);
58
+ firstMessage = false;
59
+ }
52
60
  // input -> transport
53
- // this gets cleaned up on i.end() which is called by closeHandler
61
+ // this gets cleaned up on inputStream.end() which is called by closeHandler
54
62
  (async () => {
55
63
  for await (const rawIn of inputStream) {
56
64
  const m = msg(transport.clientId, serverId, serviceName, procName, streamId, rawIn);
57
- m.controlFlags |= 2 /* ControlFlags.StreamOpenBit */;
65
+ if (firstMessage) {
66
+ m.controlFlags |= 2 /* ControlFlags.StreamOpenBit */;
67
+ firstMessage = false;
68
+ }
58
69
  transport.send(m);
59
70
  }
60
71
  })();
61
72
  // transport -> output
62
73
  const listener = (msg) => {
63
- if (belongsToSameStream(msg)) {
74
+ if (isStreamClose(msg.controlFlags)) {
75
+ outputStream.end();
76
+ }
77
+ else if (belongsToSameStream(msg)) {
64
78
  outputStream.push(msg.payload);
65
79
  }
66
80
  };
67
- transport.addMessageListener(listener);
81
+ transport.addEventListener('message', listener);
68
82
  const closeHandler = () => {
69
83
  inputStream.end();
70
84
  outputStream.end();
71
- const closeMessage = msg(transport.clientId, serverId, serviceName, procName, streamId, { type: 'CLOSE' });
72
- closeMessage.controlFlags |= 4 /* ControlFlags.StreamClosedBit */;
73
- transport.send(closeMessage);
74
- transport.removeMessageListener(listener);
85
+ transport.send(closeStream(transport.clientId, serverId, serviceName, procName, streamId));
86
+ transport.removeEventListener('message', listener);
75
87
  };
76
88
  return [inputStream, outputStream, closeHandler];
77
89
  }
@@ -93,14 +105,43 @@ export const createClient = (transport, serverId = 'SERVER') => _createRecursive
93
105
  if (belongsToSameStream(msg)) {
94
106
  outputStream.push(msg.payload);
95
107
  }
108
+ if (isStreamClose(msg.controlFlags)) {
109
+ outputStream.end();
110
+ }
96
111
  };
97
- transport.addMessageListener(listener);
112
+ transport.addEventListener('message', listener);
98
113
  const closeHandler = () => {
99
114
  outputStream.end();
100
- transport.removeMessageListener(listener);
115
+ transport.send(closeStream(transport.clientId, serverId, serviceName, procName, streamId));
116
+ transport.removeEventListener('message', listener);
101
117
  };
102
118
  return [outputStream, closeHandler];
103
119
  }
120
+ else if (procType === 'upload') {
121
+ const inputStream = pushable({ objectMode: true });
122
+ let firstMessage = true;
123
+ if (input) {
124
+ const m = msg(transport.clientId, serverId, serviceName, procName, streamId, input);
125
+ // first message needs the open bit.
126
+ m.controlFlags = 2 /* ControlFlags.StreamOpenBit */;
127
+ transport.send(m);
128
+ firstMessage = false;
129
+ }
130
+ // input -> transport
131
+ // this gets cleaned up on inputStream.end(), which the caller should call.
132
+ (async () => {
133
+ for await (const rawIn of inputStream) {
134
+ const m = msg(transport.clientId, serverId, serviceName, procName, streamId, rawIn);
135
+ if (firstMessage) {
136
+ m.controlFlags |= 2 /* ControlFlags.StreamOpenBit */;
137
+ firstMessage = false;
138
+ }
139
+ transport.send(m);
140
+ }
141
+ transport.send(closeStream(transport.clientId, serverId, serviceName, procName, streamId));
142
+ })();
143
+ return [inputStream, waitForMessage(transport, belongsToSameStream)];
144
+ }
104
145
  else {
105
146
  throw new Error(`invalid river call, unknown procedure type ${procType}`);
106
147
  }
@@ -1,5 +1,5 @@
1
1
  export { serializeService, ServiceBuilder } from './builder';
2
- export type { ValidProcType, ProcListing, Service, ProcHandler, ProcInput, ProcOutput, ProcType, Procedure, } from './builder';
2
+ export type { ValidProcType, ProcListing, Service, ProcHandler, ProcInput, ProcOutput, ProcType, Procedure, PayloadType, } from './builder';
3
3
  export { createClient } from './client';
4
4
  export type { ServerClient } from './client';
5
5
  export { createServer } from './server';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../router/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC7D,YAAY,EACV,aAAa,EACb,WAAW,EACX,OAAO,EACP,WAAW,EACX,SAAS,EACT,UAAU,EACV,QAAQ,EACR,SAAS,GACV,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACxC,YAAY,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACxC,YAAY,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AACvC,YAAY,EAAE,cAAc,EAAE,uBAAuB,EAAE,MAAM,WAAW,CAAC;AACzE,OAAO,EAAE,EAAE,EAAE,GAAG,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AACxE,YAAY,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../router/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC7D,YAAY,EACV,aAAa,EACb,WAAW,EACX,OAAO,EACP,WAAW,EACX,SAAS,EACT,UAAU,EACV,QAAQ,EACR,SAAS,EACT,WAAW,GACZ,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACxC,YAAY,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACxC,YAAY,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AACvC,YAAY,EAAE,cAAc,EAAE,uBAAuB,EAAE,MAAM,WAAW,CAAC;AACzE,OAAO,EAAE,EAAE,EAAE,GAAG,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AACxE,YAAY,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC"}
@@ -1,14 +1,27 @@
1
+ import { Static } from '@sinclair/typebox';
1
2
  import { Connection, Transport } from '../transport/transport';
2
- import { AnyService } from './builder';
3
+ import { AnyService, PayloadType } from './builder';
4
+ import type { Pushable } from 'it-pushable';
5
+ import { TransportMessage } from '../transport/message';
3
6
  import { ServiceContext } from './context';
7
+ import { Result, RiverError } from './result';
4
8
  /**
5
9
  * Represents a server with a set of services. Use {@link createServer} to create it.
6
10
  * @template Services - The type of services provided by the server.
7
11
  */
8
12
  export interface Server<Services> {
9
13
  services: Services;
14
+ streams: Map<string, ProcStream>;
10
15
  close(): Promise<void>;
11
16
  }
17
+ interface ProcStream {
18
+ incoming: Pushable<TransportMessage>;
19
+ outgoing: Pushable<TransportMessage<Result<Static<PayloadType>, Static<RiverError>>>>;
20
+ promises: {
21
+ outputHandler: Promise<unknown>;
22
+ inputHandler: Promise<unknown>;
23
+ };
24
+ }
12
25
  /**
13
26
  * Creates a server instance that listens for incoming messages from a transport and routes them to the appropriate service and procedure.
14
27
  * The server tracks the state of each service along with open streams and the extended context object.
@@ -18,4 +31,5 @@ export interface Server<Services> {
18
31
  * @returns A promise that resolves to a server instance with the registered services.
19
32
  */
20
33
  export declare function createServer<Services extends Record<string, AnyService>>(transport: Transport<Connection>, services: Services, extendedContext?: Omit<ServiceContext, 'state'>): Promise<Server<Services>>;
34
+ export {};
21
35
  //# sourceMappingURL=server.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../router/server.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,EAAgB,UAAU,EAAE,MAAM,WAAW,CAAC;AAWrD,OAAO,EAAE,cAAc,EAA2B,MAAM,WAAW,CAAC;AAWpE;;;GAGG;AACH,MAAM,WAAW,MAAM,CAAC,QAAQ;IAC9B,QAAQ,EAAE,QAAQ,CAAC;IACnB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAWD;;;;;;;GAOG;AACH,wBAAsB,YAAY,CAAC,QAAQ,SAAS,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,EAC5E,SAAS,EAAE,SAAS,CAAC,UAAU,CAAC,EAChC,QAAQ,EAAE,QAAQ,EAClB,eAAe,CAAC,EAAE,IAAI,CAAC,cAAc,EAAE,OAAO,CAAC,GAC9C,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CA0K3B"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../router/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,EAAgB,UAAU,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAElE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAGL,gBAAgB,EAKjB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,cAAc,EAA2B,MAAM,WAAW,CAAC;AAGpE,OAAO,EAEL,MAAM,EACN,UAAU,EAGX,MAAM,UAAU,CAAC;AAElB;;;GAGG;AACH,MAAM,WAAW,MAAM,CAAC,QAAQ;IAC9B,QAAQ,EAAE,QAAQ,CAAC;IACnB,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACjC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED,UAAU,UAAU;IAClB,QAAQ,EAAE,QAAQ,CAAC,gBAAgB,CAAC,CAAC;IACrC,QAAQ,EAAE,QAAQ,CAChB,gBAAgB,CAAC,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAClE,CAAC;IACF,QAAQ,EAAE;QACR,aAAa,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;QAChC,YAAY,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;KAChC,CAAC;CACH;AAED;;;;;;;GAOG;AACH,wBAAsB,YAAY,CAAC,QAAQ,SAAS,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,EAC5E,SAAS,EAAE,SAAS,CAAC,UAAU,CAAC,EAChC,QAAQ,EAAE,QAAQ,EAClB,eAAe,CAAC,EAAE,IAAI,CAAC,cAAc,EAAE,OAAO,CAAC,GAC9C,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAuP3B"}