@trevrpc/trevrpc-js 0.2.2 → 1.0.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 (42) hide show
  1. package/README.md +89 -47
  2. package/bin/protoc-gen-trevrpc-js.js +1 -1
  3. package/package.json +11 -41
  4. package/src/bytes.js +10 -0
  5. package/src/call.js +287 -0
  6. package/src/channel.js +131 -296
  7. package/src/client.js +203 -1292
  8. package/src/framing.js +125 -519
  9. package/src/generator.js +26 -103
  10. package/src/index.d.ts +79 -452
  11. package/src/index.js +4 -3
  12. package/src/status.js +24 -70
  13. package/src/wire.js +4 -59
  14. package/examples/greeter/README.md +0 -35
  15. package/examples/greeter/client.js +0 -172
  16. package/examples/greeter/greeter.node.trevrpc.d.ts +0 -53
  17. package/examples/greeter/greeter.node.trevrpc.js +0 -9
  18. package/examples/greeter/greeter.proto +0 -18
  19. package/examples/greeter/greeter.trevrpc.d.ts +0 -55
  20. package/examples/greeter/greeter.trevrpc.js +0 -103
  21. package/examples/greeter/index.html +0 -140
  22. package/examples/greeter/static-server.js +0 -168
  23. package/src/advanced.d.ts +0 -29
  24. package/src/advanced.js +0 -1
  25. package/src/browser-channel.js +0 -49
  26. package/src/connect.js +0 -6
  27. package/src/connect.node.js +0 -6
  28. package/src/index.node.d.ts +0 -10
  29. package/src/index.node.js +0 -3
  30. package/src/native-loader.js +0 -118
  31. package/src/node-advanced.d.ts +0 -27
  32. package/src/node-advanced.js +0 -1
  33. package/src/node-generated.d.ts +0 -24
  34. package/src/node-generated.js +0 -126
  35. package/src/node-index.d.ts +0 -1
  36. package/src/node-index.js +0 -7
  37. package/src/node.d.ts +0 -298
  38. package/src/node.js +0 -1456
  39. package/src/runtime.js +0 -66
  40. package/src/server-response.js +0 -49
  41. package/src/timer.js +0 -29
  42. package/src/webtransport.js +0 -639
package/src/generator.js CHANGED
@@ -166,6 +166,14 @@ const FieldLabel = Object.freeze({
166
166
  Repeated: 3,
167
167
  });
168
168
 
169
+ /** Generic runtime types that generated declarations import only when they use them. */
170
+ const GeneratedTypeImports = [
171
+ "BidirectionalStreamingCall",
172
+ "ClientStreamingCall",
173
+ "ResponseStream",
174
+ "UnaryResponse",
175
+ ];
176
+
169
177
  const RESERVED_WORDS = new Set([
170
178
  "break",
171
179
  "case",
@@ -225,7 +233,6 @@ export function generate(request) {
225
233
  }
226
234
 
227
235
  const fileName = outputFileName(file.name, options.fileSuffix);
228
- const nodeFileName = outputFileName(file.name, `.node${options.fileSuffix}`);
229
236
  files.push({
230
237
  name: fileName,
231
238
  content: generateFile(file, rootJson, options),
@@ -234,14 +241,6 @@ export function generate(request) {
234
241
  name: declarationFileName(fileName),
235
242
  content: generateDeclarationFile(protoFiles, file, typeNames, options),
236
243
  });
237
- files.push({
238
- name: nodeFileName,
239
- content: generateNodeFile(file, fileName, options),
240
- });
241
- files.push({
242
- name: declarationFileName(nodeFileName),
243
- content: generateNodeDeclarationFile(file, fileName, typeNames, options),
244
- });
245
244
  }
246
245
 
247
246
  return { file: files };
@@ -255,8 +254,6 @@ export function parseOptions(parameter) {
255
254
  const options = {
256
255
  runtimeImport: "@trevrpc/trevrpc-js",
257
256
  runtimeTypeImport: null,
258
- nodeRuntimeImport: "@trevrpc/trevrpc-js/node/generated",
259
- nodeRuntimeTypeImport: null,
260
257
  fileSuffix: ".trevrpc.js",
261
258
  };
262
259
 
@@ -279,12 +276,6 @@ export function parseOptions(parameter) {
279
276
  case "runtime_type_import":
280
277
  options.runtimeTypeImport = value;
281
278
  break;
282
- case "node_runtime_import":
283
- options.nodeRuntimeImport = value;
284
- break;
285
- case "node_runtime_type_import":
286
- options.nodeRuntimeTypeImport = value;
287
- break;
288
279
  case "file_suffix":
289
280
  options.fileSuffix = value;
290
281
  break;
@@ -293,29 +284,15 @@ export function parseOptions(parameter) {
293
284
  }
294
285
  }
295
286
 
296
- options.runtimeTypeImport = resolveTypeImport(
297
- "runtime_import",
298
- options.runtimeImport,
299
- options.runtimeTypeImport,
300
- );
301
- options.nodeRuntimeTypeImport = resolveTypeImport(
302
- "node_runtime_import",
303
- options.nodeRuntimeImport,
304
- options.nodeRuntimeTypeImport,
305
- );
306
- return options;
307
- }
308
-
309
- function resolveTypeImport(optionName, runtimeImport, typeImport) {
310
- if (typeImport != null) {
311
- return typeImport;
312
- }
313
- if (/^[A-Za-z][A-Za-z0-9+.-]*:/u.test(runtimeImport)) {
314
- throw new Error(
315
- `${optionName} ${JSON.stringify(runtimeImport)} requires an explicit ${optionName.replace("_import", "_type_import")}`,
316
- );
287
+ if (options.runtimeTypeImport == null) {
288
+ if (/^[A-Za-z][A-Za-z0-9+.-]*:/u.test(options.runtimeImport)) {
289
+ throw new Error(
290
+ `runtime_import ${JSON.stringify(options.runtimeImport)} requires an explicit runtime_type_import`,
291
+ );
292
+ }
293
+ options.runtimeTypeImport = options.runtimeImport;
317
294
  }
318
- return runtimeImport;
295
+ return options;
319
296
  }
320
297
 
321
298
  /** Builds a protobuf.js JSON root from protobuf file descriptors. */
@@ -354,36 +331,19 @@ function generateDeclarationFile(protoFiles, file, typeNames, options) {
354
331
  .map((service) => generateServiceDeclaration(service, typeNames))
355
332
  .join("\n\n");
356
333
  const sections = [messages, services].filter(Boolean).join("\n\n");
357
-
358
- return `// Code generated by protoc-gen-trevrpc-js. DO NOT EDIT.\n\nimport type { Long, Root } from "protobufjs";\n\nimport type { BidirectionalStreamingCall, CallOptions, ClientStreamingCall, ResponseAsyncIterable, RpcServiceDescriptor, Transport, UnaryResponse } from ${JSON.stringify(
334
+ const protobufImports = sections.includes("string | Long") ? "Long, Root" : "Root";
335
+ const runtimeImports = [
336
+ "CallOptions",
337
+ "RpcServiceDescriptor",
338
+ "Transport",
339
+ ...GeneratedTypeImports.filter((name) => sections.includes(`${name}<`)),
340
+ ].sort();
341
+
342
+ return `// Code generated by protoc-gen-trevrpc-js. DO NOT EDIT.\n\nimport type { ${protobufImports} } from "protobufjs";\n\nimport type { ${runtimeImports.join(", ")} } from ${JSON.stringify(
359
343
  options.runtimeTypeImport,
360
344
  )};\n\nexport declare const root: Root;\n\n${sections}\n`;
361
345
  }
362
346
 
363
- function generateNodeFile(file, ordinaryFileName, options) {
364
- const services = (file.service ?? []).map((service) => serviceDescriptor(file, service));
365
- const serviceNames = services.map((service) => service.exportName).join(", ");
366
- const registrations = services.map(generateNodeServerRegistration).join("\n");
367
- return `// Code generated by protoc-gen-trevrpc-js. DO NOT EDIT.\n\nimport { registerTypedService } from ${JSON.stringify(
368
- options.nodeRuntimeImport,
369
- )};\nimport { ${serviceNames}, root } from ${JSON.stringify(localModuleSpecifier(ordinaryFileName))};\n\n${registrations}`;
370
- }
371
-
372
- function generateNodeDeclarationFile(file, ordinaryFileName, typeNames, options) {
373
- const services = (file.service ?? []).map((service) => serviceDescriptor(file, service));
374
- const messageNames = [...new Set(typeNames.values())].join(", ");
375
- const messageImport =
376
- messageNames === ""
377
- ? ""
378
- : `import type { ${messageNames} } from ${JSON.stringify(localModuleSpecifier(ordinaryFileName))};\n`;
379
- const declarations = services
380
- .map((service) => generateNodeServiceDeclaration(service, typeNames))
381
- .join("\n\n");
382
- return `// Code generated by protoc-gen-trevrpc-js. DO NOT EDIT.\n\nimport type { NodeServer, NodeServerCall, StreamingServerResponse, UnaryServerResponse } from ${JSON.stringify(
383
- options.nodeRuntimeTypeImport,
384
- )};\n${messageImport}\n${declarations}\n`;
385
- }
386
-
387
347
  function generateService(service) {
388
348
  const className = `${pascalIdentifier(service.name)}Client`;
389
349
  const factoryName = `create${className}`;
@@ -405,11 +365,6 @@ function generateServiceMethod(jsName, method) {
405
365
  return ` /** Calls the ${method.name} RPC. */\n ${jsName}(request, options = {}) {\n return this._client.${jsName}(request, options);\n }`;
406
366
  }
407
367
 
408
- function generateNodeServerRegistration(service) {
409
- const registerName = `register${pascalIdentifier(service.name)}Server`;
410
- return `/** Registers typed Node handlers for the ${service.name} service. */\nexport function ${registerName}(server, handlers) {\n return registerTypedService(server, root, ${service.exportName}, handlers);\n}\n`;
411
- }
412
-
413
368
  function generateServiceDeclaration(service, typeNames) {
414
369
  const className = `${pascalIdentifier(service.name)}Client`;
415
370
  const factoryName = `create${className}`;
@@ -420,15 +375,6 @@ function generateServiceDeclaration(service, typeNames) {
420
375
  return `/** Service descriptor for the ${service.name} service. */\nexport declare const ${service.exportName}: RpcServiceDescriptor;\n\n/** Client for the ${service.name} service. */\nexport declare class ${className} {\n /** Creates a client for the ${service.name} service. */\n constructor(transport: Transport, options?: CallOptions);\n\n${methods}\n}\n\n/** Creates a client for the ${service.name} service. */\nexport declare function ${factoryName}(transport: Transport, options?: CallOptions): ${className};`;
421
376
  }
422
377
 
423
- function generateNodeServiceDeclaration(service, typeNames) {
424
- const handlerName = `${pascalIdentifier(service.name)}Handlers`;
425
- const registerName = `register${pascalIdentifier(service.name)}Server`;
426
- const handlers = Object.entries(service.methods)
427
- .map(([jsName, method]) => generateHandlerDeclaration(jsName, method, typeNames))
428
- .join("\n");
429
- return `/** Typed Node handlers for the ${service.name} service. */\nexport interface ${handlerName} {\n${handlers}\n}\n\n/** Registers typed Node handlers for the ${service.name} service. */\nexport declare function ${registerName}(server: NodeServer, handlers: ${handlerName}): NodeServer;`;
430
- }
431
-
432
378
  function generateMethodDeclaration(jsName, method, typeNames) {
433
379
  const inputType = declarationTypeReference(method.inputType, typeNames);
434
380
  const outputType = declarationTypeReference(method.outputType, typeNames);
@@ -437,7 +383,7 @@ function generateMethodDeclaration(jsName, method, typeNames) {
437
383
  case "unary":
438
384
  return ` /** Calls the ${method.name} RPC. */\n ${jsName}(request: ${inputType}, options?: CallOptions): Promise<${outputType}>;\n /** Calls the ${method.name} RPC and returns response metadata. */\n ${jsName}WithResponse(request: ${inputType}, options?: CallOptions): Promise<UnaryResponse<${outputType}>>;`;
439
385
  case "serverStreaming":
440
- return ` /** Calls the ${method.name} RPC. */\n ${jsName}(request: ${inputType}, options?: CallOptions): Promise<ResponseAsyncIterable<${outputType}>>;`;
386
+ return ` /** Calls the ${method.name} RPC. */\n ${jsName}(request: ${inputType}, options?: CallOptions): Promise<ResponseStream<${outputType}>>;`;
441
387
  case "clientStreaming":
442
388
  return ` /** Calls the ${method.name} RPC. */\n ${jsName}(options?: CallOptions): Promise<ClientStreamingCall<${inputType}, ${outputType}>>;`;
443
389
  case "bidirectionalStreaming":
@@ -447,25 +393,6 @@ function generateMethodDeclaration(jsName, method, typeNames) {
447
393
  }
448
394
  }
449
395
 
450
- function generateHandlerDeclaration(jsName, method, typeNames) {
451
- const inputType = declarationTypeReference(method.inputType, typeNames);
452
- const outputType = declarationTypeReference(method.outputType, typeNames);
453
- const unaryResult = `${outputType} | UnaryServerResponse<${outputType}>`;
454
- const streamingResult = `Iterable<${outputType}> | AsyncIterable<${outputType}> | StreamingServerResponse<${outputType}>`;
455
- switch (method.kind) {
456
- case "unary":
457
- return ` ${jsName}?(request: ${inputType}, call: NodeServerCall): ${unaryResult} | Promise<${unaryResult}>;`;
458
- case "serverStreaming":
459
- return ` ${jsName}?(request: ${inputType}, call: NodeServerCall): ${streamingResult} | Promise<${streamingResult}>;`;
460
- case "clientStreaming":
461
- return ` ${jsName}?(requests: AsyncIterable<${inputType}>, call: NodeServerCall): ${unaryResult} | Promise<${unaryResult}>;`;
462
- case "bidirectionalStreaming":
463
- return ` ${jsName}?(requests: AsyncIterable<${inputType}>, call: NodeServerCall): ${streamingResult} | Promise<${streamingResult}>;`;
464
- default:
465
- throw new Error(`unsupported generated RPC kind ${JSON.stringify(method.kind)}`);
466
- }
467
- }
468
-
469
396
  function serviceDescriptor(file, service) {
470
397
  const fullName =
471
398
  file.package === "" || file.package == null ? service.name : `${file.package}.${service.name}`;
@@ -808,10 +735,6 @@ function outputFileName(inputName, suffix) {
808
735
  return `${extensionStart === -1 ? inputName : inputName.slice(0, extensionStart)}${suffix}`;
809
736
  }
810
737
 
811
- function localModuleSpecifier(fileName) {
812
- return `./${fileName.slice(fileName.lastIndexOf("/") + 1)}`;
813
- }
814
-
815
738
  function declarationFileName(outputName) {
816
739
  if (outputName.endsWith(".js")) {
817
740
  return `${outputName.slice(0, -3)}.d.ts`;