@lowerdeck/rpc-server 1.0.0 → 1.0.2

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.
@@ -1,11 +1,18 @@
1
1
 
2
2
  $ microbundle
3
- Build "@lowerdeck/anonymize-ip" to dist:
4
- 857 B: index.cjs.gz
5
- 760 B: index.cjs.br
6
- 798 B: index.module.js.gz
7
- 713 B: index.module.js.br
8
- 863 B: index.module.js.gz
9
- 759 B: index.module.js.br
10
- 917 B: index.umd.js.gz
11
- 805 B: index.umd.js.br
3
+ No name was provided for external module '@lowerdeck/error' in output.globals – guessing 'error'
4
+ No name was provided for external module '@lowerdeck/execution-context' in output.globals – guessing 'executionContext'
5
+ No name was provided for external module '@lowerdeck/id' in output.globals – guessing 'id'
6
+ No name was provided for external module '@lowerdeck/memo' in output.globals – guessing 'memo'
7
+ No name was provided for external module '@lowerdeck/sentry' in output.globals – guessing 'sentry'
8
+ No name was provided for external module '@lowerdeck/serialize' in output.globals – guessing 'serialize'
9
+ No name was provided for external module '@lowerdeck/validation' in output.globals – guessing 'validation$1'
10
+ Build "@lowerdeck/rpc-server" to dist:
11
+ 4.14 kB: index.cjs.gz
12
+ 3.72 kB: index.cjs.br
13
+ 2.8 kB: index.module.js.gz
14
+ 2.51 kB: index.module.js.br
15
+ 4.06 kB: index.module.js.gz
16
+ 3.65 kB: index.module.js.br
17
+ 4.24 kB: index.umd.js.gz
18
+ 3.83 kB: index.umd.js.br
package/CHANGELOG.md ADDED
@@ -0,0 +1,16 @@
1
+ # @lowerdeck/rpc-server
2
+
3
+ ## 1.0.2
4
+
5
+ ### Patch Changes
6
+
7
+ - Add debug endpoints
8
+
9
+ ## 1.0.1
10
+
11
+ ### Patch Changes
12
+
13
+ - add readmes
14
+ - Updated dependencies
15
+ - @lowerdeck/execution-context@1.0.1
16
+ - @lowerdeck/sentry@1.0.1
package/README.md ADDED
@@ -0,0 +1,48 @@
1
+ # `@lowerdeck/rpc-server`
2
+
3
+ Type-safe RPC server for handling remote procedure calls. Provides automatic validation, error handling, execution context tracking, and Sentry integration.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @lowerdeck/rpc-server
9
+ yarn add @lowerdeck/rpc-server
10
+ bun add @lowerdeck/rpc-server
11
+ pnpm add @lowerdeck/rpc-server
12
+ ```
13
+
14
+ ## Usage
15
+
16
+ ```typescript
17
+ import { createRpcServer } from '@lowerdeck/rpc-server';
18
+
19
+ // Define your API implementation
20
+ const api = {
21
+ getUser: async (id: string) => {
22
+ return { name: 'John Doe', email: 'john@example.com' };
23
+ },
24
+
25
+ createPost: async (data: { title: string; content: string }) => {
26
+ return { id: 'post_123' };
27
+ }
28
+ };
29
+
30
+ // Create the RPC server
31
+ const server = createRpcServer({
32
+ controllers: { api },
33
+ context: async (req) => ({
34
+ userId: req.headers.get('user-id')
35
+ })
36
+ });
37
+
38
+ // Use with your HTTP framework
39
+ app.post('/rpc', server.handler);
40
+ ```
41
+
42
+ ## License
43
+
44
+ This project is licensed under the Apache License 2.0.
45
+
46
+ <div align="center">
47
+ <sub>Built with ❤️ by <a href="https://metorial.com">Metorial</a></sub>
48
+ </div>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lowerdeck/rpc-server",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -31,10 +31,10 @@
31
31
  },
32
32
  "dependencies": {
33
33
  "@lowerdeck/error": "^1.0.5",
34
- "@lowerdeck/execution-context": "^1.0.0",
34
+ "@lowerdeck/execution-context": "^1.0.1",
35
35
  "@lowerdeck/id": "^1.0.2",
36
36
  "@lowerdeck/memo": "^1.0.1",
37
- "@lowerdeck/sentry": "^1.0.0",
37
+ "@lowerdeck/sentry": "^1.0.1",
38
38
  "@lowerdeck/serialize": "^1.0.1",
39
39
  "@lowerdeck/validation": "^1.0.1",
40
40
  "cookie": "^1.1.1"
package/src/rpcMux.ts CHANGED
@@ -207,19 +207,6 @@ export let rpcMux = (
207
207
  contentType: 'application/json'
208
208
  });
209
209
 
210
- let valRes = validation.validate(body);
211
- if (!valRes.success) {
212
- return new Response(
213
- JSON.stringify(
214
- validationError({
215
- errors: valRes.errors,
216
- entity: 'request_data'
217
- }).toResponse()
218
- ),
219
- { status: 406, headers }
220
- );
221
- }
222
-
223
210
  return provideExecutionContext(
224
211
  createExecutionContext({
225
212
  type: 'request',
@@ -233,8 +220,20 @@ export let rpcMux = (
233
220
  { id: string; name: string; payload: any }[]
234
221
  >();
235
222
 
236
- for (let call of body.calls) {
237
- let rpcIndex = handlerNameToRpcMap.get(call.name);
223
+ let resRef = {
224
+ body: {
225
+ __typename: 'rpc.response',
226
+ calls: [] as any[]
227
+ },
228
+ status: 200
229
+ };
230
+
231
+ let pathParts = url.pathname.split('/').filter(Boolean);
232
+ let lastPart = pathParts[pathParts.length - 1];
233
+
234
+ if (lastPart[0] == '$') {
235
+ let id = lastPart.slice(1);
236
+ let rpcIndex = handlerNameToRpcMap.get(id);
238
237
  if (rpcIndex == undefined) {
239
238
  return new Response(
240
239
  JSON.stringify(
@@ -245,19 +244,42 @@ export let rpcMux = (
245
244
  }
246
245
 
247
246
  let calls = callsByRpc.get(rpcIndex) ?? [];
248
- calls.push(call);
247
+ calls.push({
248
+ id: generateCustomId('call_'),
249
+ name: id,
250
+ payload: body
251
+ });
249
252
  callsByRpc.set(rpcIndex, calls);
250
- }
251
-
252
- // let res = await runMany(request);
253
+ } else {
254
+ let valRes = validation.validate(body);
255
+ if (!valRes.success) {
256
+ return new Response(
257
+ JSON.stringify(
258
+ validationError({
259
+ errors: valRes.errors,
260
+ entity: 'request_data'
261
+ }).toResponse()
262
+ ),
263
+ { status: 406, headers }
264
+ );
265
+ }
253
266
 
254
- let resRef = {
255
- body: {
256
- __typename: 'rpc.response',
257
- calls: [] as any[]
258
- },
259
- status: 200
260
- };
267
+ for (let call of valRes.value.calls) {
268
+ let rpcIndex = handlerNameToRpcMap.get(call.name);
269
+ if (rpcIndex == undefined) {
270
+ return new Response(
271
+ JSON.stringify(
272
+ notFoundError({ entity: 'handler' }).toResponse()
273
+ ),
274
+ { status: 404, headers }
275
+ );
276
+ }
277
+
278
+ let calls = callsByRpc.get(rpcIndex) ?? [];
279
+ calls.push(call as any);
280
+ callsByRpc.set(rpcIndex, calls);
281
+ }
282
+ }
261
283
 
262
284
  await Promise.all(
263
285
  Array.from(callsByRpc.entries()).map(async ([rpcIndex, calls]) => {