@restatedev/restate-sdk 1.11.1 → 1.12.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 (128) hide show
  1. package/dist/_virtual/rolldown_runtime.cjs +9 -0
  2. package/dist/common_api.cjs +2 -1
  3. package/dist/common_api.d.cts +6 -2
  4. package/dist/common_api.d.cts.map +1 -1
  5. package/dist/common_api.d.ts +6 -2
  6. package/dist/common_api.d.ts.map +1 -1
  7. package/dist/common_api.js +2 -1
  8. package/dist/common_api.js.map +1 -1
  9. package/dist/context.cjs +13 -9
  10. package/dist/context.d.cts +36 -29
  11. package/dist/context.d.cts.map +1 -1
  12. package/dist/context.d.ts +36 -29
  13. package/dist/context.d.ts.map +1 -1
  14. package/dist/context.js +13 -9
  15. package/dist/context.js.map +1 -1
  16. package/dist/context_impl.cjs +150 -91
  17. package/dist/context_impl.d.cts +8 -0
  18. package/dist/context_impl.d.ts +8 -72
  19. package/dist/context_impl.d.ts.map +1 -1
  20. package/dist/context_impl.js +151 -93
  21. package/dist/context_impl.js.map +1 -1
  22. package/dist/endpoint/components.cjs +35 -20
  23. package/dist/endpoint/components.d.cts +5 -0
  24. package/dist/endpoint/components.d.ts +5 -97
  25. package/dist/endpoint/components.d.ts.map +1 -1
  26. package/dist/endpoint/components.js +35 -20
  27. package/dist/endpoint/components.js.map +1 -1
  28. package/dist/endpoint/endpoint.cjs +2 -2
  29. package/dist/endpoint/endpoint.d.cts +5 -0
  30. package/dist/endpoint/endpoint.d.ts +5 -39
  31. package/dist/endpoint/endpoint.js +2 -2
  32. package/dist/endpoint/endpoint.js.map +1 -1
  33. package/dist/endpoint/handlers/generic.cjs +115 -39
  34. package/dist/endpoint/handlers/generic.d.ts.map +1 -1
  35. package/dist/endpoint/handlers/generic.js +115 -39
  36. package/dist/endpoint/handlers/generic.js.map +1 -1
  37. package/dist/endpoint/handlers/types.d.cts +1 -0
  38. package/dist/endpoint/handlers/types.d.ts +1 -41
  39. package/dist/endpoint/handlers/utils.cjs +1 -1
  40. package/dist/endpoint/handlers/utils.js +1 -1
  41. package/dist/endpoint/handlers/vm/sdk_shared_core_wasm_bindings.cjs +43 -3
  42. package/dist/endpoint/handlers/vm/sdk_shared_core_wasm_bindings.d.ts +19 -1
  43. package/dist/endpoint/handlers/vm/sdk_shared_core_wasm_bindings.d.ts.map +1 -1
  44. package/dist/endpoint/handlers/vm/sdk_shared_core_wasm_bindings.js +43 -3
  45. package/dist/endpoint/handlers/vm/sdk_shared_core_wasm_bindings.js.map +1 -1
  46. package/dist/endpoint/node_endpoint.cjs +28 -12
  47. package/dist/endpoint/node_endpoint.d.ts +14 -2
  48. package/dist/endpoint/node_endpoint.d.ts.map +1 -1
  49. package/dist/endpoint/node_endpoint.js +27 -11
  50. package/dist/endpoint/node_endpoint.js.map +1 -1
  51. package/dist/endpoint/types.d.cts +1 -1
  52. package/dist/endpoint/types.d.ts +1 -1
  53. package/dist/endpoint.d.cts +87 -5
  54. package/dist/endpoint.d.cts.map +1 -1
  55. package/dist/endpoint.d.ts +87 -5
  56. package/dist/endpoint.d.ts.map +1 -1
  57. package/dist/error_sanitization.cjs +26 -0
  58. package/dist/error_sanitization.d.ts +13 -0
  59. package/dist/error_sanitization.d.ts.map +1 -0
  60. package/dist/error_sanitization.js +26 -0
  61. package/dist/error_sanitization.js.map +1 -0
  62. package/dist/fetch.cjs +3 -1
  63. package/dist/fetch.d.cts +5 -3
  64. package/dist/fetch.d.cts.map +1 -1
  65. package/dist/fetch.d.ts +5 -3
  66. package/dist/fetch.d.ts.map +1 -1
  67. package/dist/fetch.js +3 -2
  68. package/dist/fetch.js.map +1 -1
  69. package/dist/hooks.d.cts +87 -0
  70. package/dist/hooks.d.cts.map +1 -0
  71. package/dist/hooks.d.ts +87 -0
  72. package/dist/hooks.d.ts.map +1 -0
  73. package/dist/hooks.js +2 -0
  74. package/dist/hooks.js.map +1 -0
  75. package/dist/index.cjs +3 -1
  76. package/dist/index.d.cts +6 -4
  77. package/dist/index.d.ts +6 -4
  78. package/dist/index.js +3 -2
  79. package/dist/internal.cjs +3 -1
  80. package/dist/internal.d.cts +186 -2
  81. package/dist/internal.d.cts.map +1 -1
  82. package/dist/internal.d.ts +186 -2
  83. package/dist/internal.d.ts.map +1 -1
  84. package/dist/internal.js +4 -1
  85. package/dist/internal.js.map +1 -1
  86. package/dist/io.d.cts +1 -0
  87. package/dist/io.d.ts +1 -24
  88. package/dist/lambda.cjs +3 -1
  89. package/dist/lambda.d.cts +5 -3
  90. package/dist/lambda.d.cts.map +1 -1
  91. package/dist/lambda.d.ts +5 -3
  92. package/dist/lambda.d.ts.map +1 -1
  93. package/dist/lambda.js +3 -2
  94. package/dist/lambda.js.map +1 -1
  95. package/dist/logging/logger.d.cts +1 -0
  96. package/dist/logging/logger.d.ts +1 -10
  97. package/dist/node.cjs +23 -6
  98. package/dist/node.d.cts +46 -8
  99. package/dist/node.d.cts.map +1 -1
  100. package/dist/node.d.ts +46 -8
  101. package/dist/node.d.ts.map +1 -1
  102. package/dist/node.js +23 -7
  103. package/dist/node.js.map +1 -1
  104. package/dist/package.cjs +1 -1
  105. package/dist/package.js +1 -1
  106. package/dist/package.js.map +1 -1
  107. package/dist/promises.cjs +90 -53
  108. package/dist/promises.d.cts +18 -0
  109. package/dist/promises.d.cts.map +1 -0
  110. package/dist/promises.d.ts +15 -108
  111. package/dist/promises.d.ts.map +1 -1
  112. package/dist/promises.js +85 -48
  113. package/dist/promises.js.map +1 -1
  114. package/dist/types/errors.cjs +13 -0
  115. package/dist/types/errors.d.cts +11 -5
  116. package/dist/types/errors.d.cts.map +1 -1
  117. package/dist/types/errors.d.ts +11 -5
  118. package/dist/types/errors.d.ts.map +1 -1
  119. package/dist/types/errors.js +13 -1
  120. package/dist/types/errors.js.map +1 -1
  121. package/dist/types/rpc.cjs +7 -19
  122. package/dist/types/rpc.d.cts +174 -0
  123. package/dist/types/rpc.d.cts.map +1 -1
  124. package/dist/types/rpc.d.ts +174 -0
  125. package/dist/types/rpc.d.ts.map +1 -1
  126. package/dist/types/rpc.js +7 -19
  127. package/dist/types/rpc.js.map +1 -1
  128. package/package.json +2 -2
@@ -3,8 +3,8 @@ const require_errors = require('../types/errors.cjs');
3
3
  const require_endpoint = require('./endpoint.cjs');
4
4
  const require_utils = require('./handlers/utils.cjs');
5
5
  const require_generic = require('./handlers/generic.cjs');
6
- let http2 = require("http2");
7
- http2 = require_rolldown_runtime.__toESM(http2);
6
+ let node_http2 = require("node:http2");
7
+ node_http2 = require_rolldown_runtime.__toESM(node_http2);
8
8
 
9
9
  //#region src/endpoint/node_endpoint.ts
10
10
  var NodeEndpoint = class {
@@ -29,14 +29,26 @@ var NodeEndpoint = class {
29
29
  this.builder.setJournalValueCodecProvider(codecProvider);
30
30
  return this;
31
31
  }
32
- http2Handler() {
33
- return nodeHttp2Handler(this.builder.build());
32
+ http2Handler(options) {
33
+ return nodeHttp2Handler(this.builder.build(), options?.bidirectional === false ? "REQUEST_RESPONSE" : "BIDI_STREAM");
34
+ }
35
+ http1Handler(options) {
36
+ return nodeHttp1Handler(this.builder.build(), options?.bidirectional ? "BIDI_STREAM" : "REQUEST_RESPONSE");
37
+ }
38
+ handler(options) {
39
+ const endpoint = this.builder.build();
40
+ const h2Handler = nodeHttp2Handler(endpoint, options?.bidirectional === false ? "REQUEST_RESPONSE" : "BIDI_STREAM");
41
+ const h1Handler = nodeHttp1Handler(endpoint, options?.bidirectional ? "BIDI_STREAM" : "REQUEST_RESPONSE");
42
+ return ((request, response) => {
43
+ if (request.httpVersionMajor >= 2) h2Handler(request, response);
44
+ else h1Handler(request, response);
45
+ });
34
46
  }
35
47
  listen(port) {
36
48
  const endpoint = this.builder.build();
37
49
  const actualPort = port ?? parseInt(process.env.PORT ?? "9080");
38
50
  endpoint.rlog.info(`Restate SDK started listening on ${actualPort}...`);
39
- const server = http2.createServer(nodeHttp2Handler(endpoint));
51
+ const server = node_http2.createServer(nodeHttp2Handler(endpoint, "BIDI_STREAM"));
40
52
  return new Promise((resolve, reject) => {
41
53
  let failed = false;
42
54
  server.once("error", (e) => {
@@ -52,8 +64,14 @@ var NodeEndpoint = class {
52
64
  });
53
65
  }
54
66
  };
55
- function nodeHttp2Handler(endpoint) {
56
- const handler = require_generic.createRestateHandler(endpoint, "BIDI_STREAM", {});
67
+ function nodeHttp1Handler(endpoint, protocolMode) {
68
+ return nodeHandlerImpl(endpoint, protocolMode);
69
+ }
70
+ function nodeHttp2Handler(endpoint, protocolMode) {
71
+ return nodeHandlerImpl(endpoint, protocolMode);
72
+ }
73
+ function nodeHandlerImpl(endpoint, protocolMode) {
74
+ const handler = require_generic.createRestateHandler(endpoint, protocolMode, {});
57
75
  return (httpRequest, httpResponse) => {
58
76
  const url = httpRequest.url;
59
77
  const abortController = new AbortController();
@@ -80,18 +98,16 @@ function inputReaderAdapter(request) {
80
98
  return request[Symbol.asyncIterator]();
81
99
  }
82
100
  function outputWriterAdapter(response) {
101
+ const res = response;
83
102
  return {
84
103
  write: function(value) {
85
104
  return new Promise((resolve, reject) => {
86
- response.write(value, (err) => {
87
- if (err) reject(err);
88
- else resolve();
89
- });
105
+ res.write(value, (err) => err ? reject(err) : resolve());
90
106
  });
91
107
  },
92
108
  close: function() {
93
109
  return new Promise((resolve) => {
94
- response.end(() => resolve());
110
+ res.end(() => resolve());
95
111
  });
96
112
  }
97
113
  };
@@ -1,6 +1,7 @@
1
1
  import type { RestateEndpoint } from "../index.js";
2
2
  import type { JournalValueCodec, ServiceDefinition, VirtualObjectDefinition, WorkflowDefinition } from "@restatedev/restate-sdk-core";
3
- import { Http2ServerRequest, Http2ServerResponse } from "http2";
3
+ import { IncomingMessage, ServerResponse } from "node:http";
4
+ import { Http2ServerRequest, Http2ServerResponse } from "node:http2";
4
5
  import type { LoggerTransport } from "../logging/logger_transport.js";
5
6
  import type { DefaultServiceOptions } from "../endpoint.js";
6
7
  export declare class NodeEndpoint implements RestateEndpoint {
@@ -10,7 +11,18 @@ export declare class NodeEndpoint implements RestateEndpoint {
10
11
  defaultServiceOptions(options: DefaultServiceOptions): RestateEndpoint;
11
12
  setLogger(logger: LoggerTransport): RestateEndpoint;
12
13
  journalValueCodecProvider(codecProvider: () => Promise<JournalValueCodec>): RestateEndpoint;
13
- http2Handler(): (request: Http2ServerRequest, response: Http2ServerResponse) => void;
14
+ http2Handler(options?: {
15
+ bidirectional?: boolean;
16
+ }): (request: Http2ServerRequest, response: Http2ServerResponse) => void;
17
+ http1Handler(options?: {
18
+ bidirectional?: boolean;
19
+ }): (request: IncomingMessage, response: ServerResponse) => void;
20
+ handler(options?: {
21
+ bidirectional?: boolean;
22
+ }): {
23
+ (request: IncomingMessage, response: ServerResponse): void;
24
+ (request: Http2ServerRequest, response: Http2ServerResponse): void;
25
+ };
14
26
  listen(port?: number): Promise<number>;
15
27
  }
16
28
  //# sourceMappingURL=node_endpoint.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"node_endpoint.d.ts","sourceRoot":"","sources":["../../src/endpoint/node_endpoint.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,KAAK,EACV,iBAAiB,EACjB,iBAAiB,EACjB,uBAAuB,EACvB,kBAAkB,EACnB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,OAAO,CAAC;AAMhE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACtE,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AAI5D,qBAAa,YAAa,YAAW,eAAe;IAClD,OAAO,CAAC,OAAO,CAA0C;IAElD,IAAI,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,EAC7B,UAAU,EACN,iBAAiB,CAAC,CAAC,EAAE,CAAC,CAAC,GACvB,uBAAuB,CAAC,CAAC,EAAE,CAAC,CAAC,GAC7B,kBAAkB,CAAC,CAAC,EAAE,CAAC,CAAC,GAC3B,eAAe;IAKX,cAAc,CAAC,GAAG,IAAI,EAAE,MAAM,EAAE,GAAG,eAAe;IAKlD,qBAAqB,CAC1B,OAAO,EAAE,qBAAqB,GAC7B,eAAe;IAKX,SAAS,CAAC,MAAM,EAAE,eAAe,GAAG,eAAe;IAKnD,yBAAyB,CAC9B,aAAa,EAAE,MAAM,OAAO,CAAC,iBAAiB,CAAC,GAC9C,eAAe;IAKlB,YAAY,IAAI,CACd,OAAO,EAAE,kBAAkB,EAC3B,QAAQ,EAAE,mBAAmB,KAC1B,IAAI;IAIT,MAAM,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CA+BvC"}
1
+ {"version":3,"file":"node_endpoint.d.ts","sourceRoot":"","sources":["../../src/endpoint/node_endpoint.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,KAAK,EACV,iBAAiB,EACjB,iBAAiB,EACjB,uBAAuB,EACvB,kBAAkB,EACnB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC5D,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAMrE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACtE,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AAK5D,qBAAa,YAAa,YAAW,eAAe;IAClD,OAAO,CAAC,OAAO,CAA0C;IAElD,IAAI,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,EAC7B,UAAU,EACN,iBAAiB,CAAC,CAAC,EAAE,CAAC,CAAC,GACvB,uBAAuB,CAAC,CAAC,EAAE,CAAC,CAAC,GAC7B,kBAAkB,CAAC,CAAC,EAAE,CAAC,CAAC,GAC3B,eAAe;IAKX,cAAc,CAAC,GAAG,IAAI,EAAE,MAAM,EAAE,GAAG,eAAe;IAKlD,qBAAqB,CAC1B,OAAO,EAAE,qBAAqB,GAC7B,eAAe;IAKX,SAAS,CAAC,MAAM,EAAE,eAAe,GAAG,eAAe;IAKnD,yBAAyB,CAC9B,aAAa,EAAE,MAAM,OAAO,CAAC,iBAAiB,CAAC,GAC9C,eAAe;IAKlB,YAAY,CAAC,OAAO,CAAC,EAAE;QACrB,aAAa,CAAC,EAAE,OAAO,CAAC;KACzB,GAAG,CAAC,OAAO,EAAE,kBAAkB,EAAE,QAAQ,EAAE,mBAAmB,KAAK,IAAI;IAOxE,YAAY,CAAC,OAAO,CAAC,EAAE;QACrB,aAAa,CAAC,EAAE,OAAO,CAAC;KACzB,GAAG,CAAC,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,cAAc,KAAK,IAAI;IAOhE,OAAO,CAAC,OAAO,CAAC,EAAE;QAAE,aAAa,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG;QAC9C,CAAC,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,cAAc,GAAG,IAAI,CAAC;QAC3D,CAAC,OAAO,EAAE,kBAAkB,EAAE,QAAQ,EAAE,mBAAmB,GAAG,IAAI,CAAC;KACpE;IA6BD,MAAM,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAiCvC"}
@@ -2,7 +2,7 @@ import { ensureError } from "../types/errors.js";
2
2
  import { EndpointBuilder } from "./endpoint.js";
3
3
  import { tryCreateContextualLogger } from "./handlers/utils.js";
4
4
  import { createRestateHandler } from "./handlers/generic.js";
5
- import * as http2 from "http2";
5
+ import * as http2 from "node:http2";
6
6
 
7
7
  //#region src/endpoint/node_endpoint.ts
8
8
  var NodeEndpoint = class {
@@ -27,14 +27,26 @@ var NodeEndpoint = class {
27
27
  this.builder.setJournalValueCodecProvider(codecProvider);
28
28
  return this;
29
29
  }
30
- http2Handler() {
31
- return nodeHttp2Handler(this.builder.build());
30
+ http2Handler(options) {
31
+ return nodeHttp2Handler(this.builder.build(), options?.bidirectional === false ? "REQUEST_RESPONSE" : "BIDI_STREAM");
32
+ }
33
+ http1Handler(options) {
34
+ return nodeHttp1Handler(this.builder.build(), options?.bidirectional ? "BIDI_STREAM" : "REQUEST_RESPONSE");
35
+ }
36
+ handler(options) {
37
+ const endpoint = this.builder.build();
38
+ const h2Handler = nodeHttp2Handler(endpoint, options?.bidirectional === false ? "REQUEST_RESPONSE" : "BIDI_STREAM");
39
+ const h1Handler = nodeHttp1Handler(endpoint, options?.bidirectional ? "BIDI_STREAM" : "REQUEST_RESPONSE");
40
+ return ((request, response) => {
41
+ if (request.httpVersionMajor >= 2) h2Handler(request, response);
42
+ else h1Handler(request, response);
43
+ });
32
44
  }
33
45
  listen(port) {
34
46
  const endpoint = this.builder.build();
35
47
  const actualPort = port ?? parseInt(process.env.PORT ?? "9080");
36
48
  endpoint.rlog.info(`Restate SDK started listening on ${actualPort}...`);
37
- const server = http2.createServer(nodeHttp2Handler(endpoint));
49
+ const server = http2.createServer(nodeHttp2Handler(endpoint, "BIDI_STREAM"));
38
50
  return new Promise((resolve, reject) => {
39
51
  let failed = false;
40
52
  server.once("error", (e) => {
@@ -50,8 +62,14 @@ var NodeEndpoint = class {
50
62
  });
51
63
  }
52
64
  };
53
- function nodeHttp2Handler(endpoint) {
54
- const handler = createRestateHandler(endpoint, "BIDI_STREAM", {});
65
+ function nodeHttp1Handler(endpoint, protocolMode) {
66
+ return nodeHandlerImpl(endpoint, protocolMode);
67
+ }
68
+ function nodeHttp2Handler(endpoint, protocolMode) {
69
+ return nodeHandlerImpl(endpoint, protocolMode);
70
+ }
71
+ function nodeHandlerImpl(endpoint, protocolMode) {
72
+ const handler = createRestateHandler(endpoint, protocolMode, {});
55
73
  return (httpRequest, httpResponse) => {
56
74
  const url = httpRequest.url;
57
75
  const abortController = new AbortController();
@@ -78,18 +96,16 @@ function inputReaderAdapter(request) {
78
96
  return request[Symbol.asyncIterator]();
79
97
  }
80
98
  function outputWriterAdapter(response) {
99
+ const res = response;
81
100
  return {
82
101
  write: function(value) {
83
102
  return new Promise((resolve, reject) => {
84
- response.write(value, (err) => {
85
- if (err) reject(err);
86
- else resolve();
87
- });
103
+ res.write(value, (err) => err ? reject(err) : resolve());
88
104
  });
89
105
  },
90
106
  close: function() {
91
107
  return new Promise((resolve) => {
92
- response.end(() => resolve());
108
+ res.end(() => resolve());
93
109
  });
94
110
  }
95
111
  };
@@ -1 +1 @@
1
- {"version":3,"file":"node_endpoint.js","names":[],"sources":["../../src/endpoint/node_endpoint.ts"],"sourcesContent":["/*\n * Copyright (c) 2023-2024 - Restate Software, Inc., Restate GmbH\n *\n * This file is part of the Restate SDK for Node.js/TypeScript,\n * which is released under the MIT license.\n *\n * You can find a copy of the license in file LICENSE in the root\n * directory of this repository or package, or at\n * https://github.com/restatedev/sdk-typescript/blob/main/LICENSE\n */\n\nimport type { RestateEndpoint } from \"../index.js\";\nimport type {\n JournalValueCodec,\n ServiceDefinition,\n VirtualObjectDefinition,\n WorkflowDefinition,\n} from \"@restatedev/restate-sdk-core\";\nimport { Http2ServerRequest, Http2ServerResponse } from \"http2\";\nimport * as http2 from \"http2\";\nimport type { Endpoint } from \"./endpoint.js\";\nimport { EndpointBuilder } from \"./endpoint.js\";\nimport { createRestateHandler } from \"./handlers/generic.js\";\nimport { ensureError } from \"../types/errors.js\";\nimport type { LoggerTransport } from \"../logging/logger_transport.js\";\nimport type { DefaultServiceOptions } from \"../endpoint.js\";\nimport { tryCreateContextualLogger } from \"./handlers/utils.js\";\nimport { InputReader, OutputWriter } from \"./handlers/types.js\";\n\nexport class NodeEndpoint implements RestateEndpoint {\n private builder: EndpointBuilder = new EndpointBuilder();\n\n public bind<P extends string, M>(\n definition:\n | ServiceDefinition<P, M>\n | VirtualObjectDefinition<P, M>\n | WorkflowDefinition<P, M>\n ): RestateEndpoint {\n this.builder.bind(definition);\n return this;\n }\n\n public withIdentityV1(...keys: string[]): RestateEndpoint {\n this.builder.addIdentityKeys(...keys);\n return this;\n }\n\n public defaultServiceOptions(\n options: DefaultServiceOptions\n ): RestateEndpoint {\n this.builder.setDefaultServiceOptions(options);\n return this;\n }\n\n public setLogger(logger: LoggerTransport): RestateEndpoint {\n this.builder.setLogger(logger);\n return this;\n }\n\n public journalValueCodecProvider(\n codecProvider: () => Promise<JournalValueCodec>\n ): RestateEndpoint {\n this.builder.setJournalValueCodecProvider(codecProvider);\n return this;\n }\n\n http2Handler(): (\n request: Http2ServerRequest,\n response: Http2ServerResponse\n ) => void {\n return nodeHttp2Handler(this.builder.build());\n }\n\n listen(port?: number): Promise<number> {\n const endpoint = this.builder.build();\n\n const actualPort = port ?? parseInt(process.env.PORT ?? \"9080\");\n endpoint.rlog.info(`Restate SDK started listening on ${actualPort}...`);\n\n const server = http2.createServer(nodeHttp2Handler(endpoint));\n\n return new Promise((resolve, reject) => {\n let failed = false;\n server.once(\"error\", (e: Error) => {\n failed = true;\n reject(e);\n });\n server.listen(actualPort, () => {\n if (failed) {\n return;\n }\n const address = server.address();\n if (address === null || typeof address === \"string\") {\n reject(\n new TypeError(\n \"endpoint.listen() currently supports only binding to a PORT\"\n )\n );\n } else {\n resolve(address.port);\n }\n });\n });\n }\n}\n\nfunction nodeHttp2Handler(\n endpoint: Endpoint\n): (request: Http2ServerRequest, response: Http2ServerResponse) => void {\n const handler = createRestateHandler(endpoint, \"BIDI_STREAM\", {});\n\n return (httpRequest, httpResponse) => {\n const url = httpRequest.url;\n\n // Abort controller used to cleanup resources at the end of this stream lifecycle\n const abortController = new AbortController();\n httpRequest.on(\"close\", () => {\n // The 'close' event is emitted when the Http2Stream is destroyed.\n abortController.abort();\n });\n\n const restateResponse = handler.handle({\n url,\n headers: httpRequest.headers,\n extraArgs: [],\n });\n\n httpResponse.writeHead(restateResponse.statusCode, restateResponse.headers);\n\n restateResponse\n .process({\n inputReader: inputReaderAdapter(httpRequest),\n outputWriter: outputWriterAdapter(httpResponse),\n abortSignal: abortController.signal,\n })\n .catch((e) => {\n // handle should never throw\n const error = ensureError(e);\n const logger =\n tryCreateContextualLogger(\n endpoint.loggerTransport,\n url,\n httpRequest.headers\n ) ?? endpoint.rlog;\n logger.error(\"Unexpected error: \" + (error.stack ?? error.message));\n });\n };\n}\n\nfunction inputReaderAdapter(request: Http2ServerRequest): InputReader {\n return request[Symbol.asyncIterator]();\n}\n\nfunction outputWriterAdapter(response: Http2ServerResponse): OutputWriter {\n return {\n write: function (value: Uint8Array): Promise<void> {\n return new Promise((resolve, reject) => {\n response.write(value, (err) => {\n if (err) {\n reject(err);\n } else {\n resolve();\n }\n });\n });\n },\n close: function (): Promise<void> {\n return new Promise((resolve) => {\n response.end(() => resolve());\n });\n },\n };\n}\n"],"mappings":";;;;;;;AA6BA,IAAa,eAAb,MAAqD;CACnD,AAAQ,UAA2B,IAAI,iBAAiB;CAExD,AAAO,KACL,YAIiB;AACjB,OAAK,QAAQ,KAAK,WAAW;AAC7B,SAAO;;CAGT,AAAO,eAAe,GAAG,MAAiC;AACxD,OAAK,QAAQ,gBAAgB,GAAG,KAAK;AACrC,SAAO;;CAGT,AAAO,sBACL,SACiB;AACjB,OAAK,QAAQ,yBAAyB,QAAQ;AAC9C,SAAO;;CAGT,AAAO,UAAU,QAA0C;AACzD,OAAK,QAAQ,UAAU,OAAO;AAC9B,SAAO;;CAGT,AAAO,0BACL,eACiB;AACjB,OAAK,QAAQ,6BAA6B,cAAc;AACxD,SAAO;;CAGT,eAGU;AACR,SAAO,iBAAiB,KAAK,QAAQ,OAAO,CAAC;;CAG/C,OAAO,MAAgC;EACrC,MAAM,WAAW,KAAK,QAAQ,OAAO;EAErC,MAAM,aAAa,QAAQ,SAAS,QAAQ,IAAI,QAAQ,OAAO;AAC/D,WAAS,KAAK,KAAK,oCAAoC,WAAW,KAAK;EAEvE,MAAM,SAAS,MAAM,aAAa,iBAAiB,SAAS,CAAC;AAE7D,SAAO,IAAI,SAAS,SAAS,WAAW;GACtC,IAAI,SAAS;AACb,UAAO,KAAK,UAAU,MAAa;AACjC,aAAS;AACT,WAAO,EAAE;KACT;AACF,UAAO,OAAO,kBAAkB;AAC9B,QAAI,OACF;IAEF,MAAM,UAAU,OAAO,SAAS;AAChC,QAAI,YAAY,QAAQ,OAAO,YAAY,SACzC,wBACE,IAAI,UACF,8DACD,CACF;QAED,SAAQ,QAAQ,KAAK;KAEvB;IACF;;;AAIN,SAAS,iBACP,UACsE;CACtE,MAAM,UAAU,qBAAqB,UAAU,eAAe,EAAE,CAAC;AAEjE,SAAQ,aAAa,iBAAiB;EACpC,MAAM,MAAM,YAAY;EAGxB,MAAM,kBAAkB,IAAI,iBAAiB;AAC7C,cAAY,GAAG,eAAe;AAE5B,mBAAgB,OAAO;IACvB;EAEF,MAAM,kBAAkB,QAAQ,OAAO;GACrC;GACA,SAAS,YAAY;GACrB,WAAW,EAAE;GACd,CAAC;AAEF,eAAa,UAAU,gBAAgB,YAAY,gBAAgB,QAAQ;AAE3E,kBACG,QAAQ;GACP,aAAa,mBAAmB,YAAY;GAC5C,cAAc,oBAAoB,aAAa;GAC/C,aAAa,gBAAgB;GAC9B,CAAC,CACD,OAAO,MAAM;GAEZ,MAAM,QAAQ,YAAY,EAAE;AAO5B,IALE,0BACE,SAAS,iBACT,KACA,YAAY,QACb,IAAI,SAAS,MACT,MAAM,wBAAwB,MAAM,SAAS,MAAM,SAAS;IACnE;;;AAIR,SAAS,mBAAmB,SAA0C;AACpE,QAAO,QAAQ,OAAO,gBAAgB;;AAGxC,SAAS,oBAAoB,UAA6C;AACxE,QAAO;EACL,OAAO,SAAU,OAAkC;AACjD,UAAO,IAAI,SAAS,SAAS,WAAW;AACtC,aAAS,MAAM,QAAQ,QAAQ;AAC7B,SAAI,IACF,QAAO,IAAI;SAEX,UAAS;MAEX;KACF;;EAEJ,OAAO,WAA2B;AAChC,UAAO,IAAI,SAAS,YAAY;AAC9B,aAAS,UAAU,SAAS,CAAC;KAC7B;;EAEL"}
1
+ {"version":3,"file":"node_endpoint.js","names":[],"sources":["../../src/endpoint/node_endpoint.ts"],"sourcesContent":["/*\n * Copyright (c) 2023-2024 - Restate Software, Inc., Restate GmbH\n *\n * This file is part of the Restate SDK for Node.js/TypeScript,\n * which is released under the MIT license.\n *\n * You can find a copy of the license in file LICENSE in the root\n * directory of this repository or package, or at\n * https://github.com/restatedev/sdk-typescript/blob/main/LICENSE\n */\n\nimport type { RestateEndpoint } from \"../index.js\";\nimport type {\n JournalValueCodec,\n ServiceDefinition,\n VirtualObjectDefinition,\n WorkflowDefinition,\n} from \"@restatedev/restate-sdk-core\";\nimport { IncomingMessage, ServerResponse } from \"node:http\";\nimport { Http2ServerRequest, Http2ServerResponse } from \"node:http2\";\nimport * as http2 from \"node:http2\";\nimport type { Endpoint } from \"./endpoint.js\";\nimport { EndpointBuilder } from \"./endpoint.js\";\nimport { createRestateHandler } from \"./handlers/generic.js\";\nimport { ensureError } from \"../types/errors.js\";\nimport type { LoggerTransport } from \"../logging/logger_transport.js\";\nimport type { DefaultServiceOptions } from \"../endpoint.js\";\nimport { tryCreateContextualLogger } from \"./handlers/utils.js\";\nimport type { InputReader, OutputWriter } from \"./handlers/types.js\";\nimport type { ProtocolMode } from \"./discovery.js\";\n\nexport class NodeEndpoint implements RestateEndpoint {\n private builder: EndpointBuilder = new EndpointBuilder();\n\n public bind<P extends string, M>(\n definition:\n | ServiceDefinition<P, M>\n | VirtualObjectDefinition<P, M>\n | WorkflowDefinition<P, M>\n ): RestateEndpoint {\n this.builder.bind(definition);\n return this;\n }\n\n public withIdentityV1(...keys: string[]): RestateEndpoint {\n this.builder.addIdentityKeys(...keys);\n return this;\n }\n\n public defaultServiceOptions(\n options: DefaultServiceOptions\n ): RestateEndpoint {\n this.builder.setDefaultServiceOptions(options);\n return this;\n }\n\n public setLogger(logger: LoggerTransport): RestateEndpoint {\n this.builder.setLogger(logger);\n return this;\n }\n\n public journalValueCodecProvider(\n codecProvider: () => Promise<JournalValueCodec>\n ): RestateEndpoint {\n this.builder.setJournalValueCodecProvider(codecProvider);\n return this;\n }\n\n http2Handler(options?: {\n bidirectional?: boolean;\n }): (request: Http2ServerRequest, response: Http2ServerResponse) => void {\n return nodeHttp2Handler(\n this.builder.build(),\n options?.bidirectional === false ? \"REQUEST_RESPONSE\" : \"BIDI_STREAM\"\n );\n }\n\n http1Handler(options?: {\n bidirectional?: boolean;\n }): (request: IncomingMessage, response: ServerResponse) => void {\n return nodeHttp1Handler(\n this.builder.build(),\n options?.bidirectional ? \"BIDI_STREAM\" : \"REQUEST_RESPONSE\"\n );\n }\n\n handler(options?: { bidirectional?: boolean }): {\n (request: IncomingMessage, response: ServerResponse): void;\n (request: Http2ServerRequest, response: Http2ServerResponse): void;\n } {\n const endpoint = this.builder.build();\n const h2Handler = nodeHttp2Handler(\n endpoint,\n options?.bidirectional === false ? \"REQUEST_RESPONSE\" : \"BIDI_STREAM\"\n );\n const h1Handler = nodeHttp1Handler(\n endpoint,\n options?.bidirectional ? \"BIDI_STREAM\" : \"REQUEST_RESPONSE\"\n );\n\n return ((\n request: IncomingMessage | Http2ServerRequest,\n response: ServerResponse | Http2ServerResponse\n ) => {\n if (request.httpVersionMajor >= 2) {\n h2Handler(\n request as Http2ServerRequest,\n response as Http2ServerResponse\n );\n } else {\n h1Handler(request as IncomingMessage, response as ServerResponse);\n }\n }) as {\n (request: IncomingMessage, response: ServerResponse): void;\n (request: Http2ServerRequest, response: Http2ServerResponse): void;\n };\n }\n\n listen(port?: number): Promise<number> {\n const endpoint = this.builder.build();\n\n const actualPort = port ?? parseInt(process.env.PORT ?? \"9080\");\n endpoint.rlog.info(`Restate SDK started listening on ${actualPort}...`);\n\n const server = http2.createServer(\n nodeHttp2Handler(endpoint, \"BIDI_STREAM\")\n );\n\n return new Promise((resolve, reject) => {\n let failed = false;\n server.once(\"error\", (e: Error) => {\n failed = true;\n reject(e);\n });\n server.listen(actualPort, () => {\n if (failed) {\n return;\n }\n const address = server.address();\n if (address === null || typeof address === \"string\") {\n reject(\n new TypeError(\n \"endpoint.listen() currently supports only binding to a PORT\"\n )\n );\n } else {\n resolve(address.port);\n }\n });\n });\n }\n}\n\nfunction nodeHttp1Handler(\n endpoint: Endpoint,\n protocolMode: ProtocolMode\n): (request: IncomingMessage, response: ServerResponse) => void {\n return nodeHandlerImpl(endpoint, protocolMode);\n}\n\nfunction nodeHttp2Handler(\n endpoint: Endpoint,\n protocolMode: ProtocolMode\n): (request: Http2ServerRequest, response: Http2ServerResponse) => void {\n return nodeHandlerImpl(endpoint, protocolMode);\n}\n\nfunction nodeHandlerImpl(\n endpoint: Endpoint,\n protocolMode: ProtocolMode\n): (\n request: Http2ServerRequest | IncomingMessage,\n response: Http2ServerResponse | ServerResponse\n) => void {\n const handler = createRestateHandler(endpoint, protocolMode, {});\n\n return (httpRequest, httpResponse) => {\n const url = httpRequest.url!;\n\n // Abort controller used to cleanup resources at the end of this stream lifecycle\n const abortController = new AbortController();\n httpRequest.on(\"close\", () => {\n abortController.abort();\n });\n\n const restateResponse = handler.handle({\n url,\n headers: httpRequest.headers,\n extraArgs: [],\n });\n const res = httpResponse as NodeWritableResponse;\n res.writeHead(restateResponse.statusCode, restateResponse.headers);\n\n restateResponse\n .process({\n inputReader: inputReaderAdapter(httpRequest),\n outputWriter: outputWriterAdapter(httpResponse),\n abortSignal: abortController.signal,\n })\n .catch((e) => {\n // handle should never throw\n const error = ensureError(e);\n const logger =\n tryCreateContextualLogger(\n endpoint.loggerTransport,\n url,\n httpRequest.headers\n ) ?? endpoint.rlog;\n logger.error(\"Unexpected error: \" + (error.stack ?? error.message));\n });\n };\n}\n\n// Both ServerResponse and Http2ServerResponse satisfy this interface.\n// We use it to avoid TS union overload incompatibilities.\ninterface NodeWritableResponse {\n writeHead(statusCode: number, headers: Record<string, string>): void;\n write(chunk: Uint8Array, callback: (err?: Error | null) => void): boolean;\n end(callback: () => void): void;\n}\n\nfunction inputReaderAdapter(\n request: Http2ServerRequest | IncomingMessage\n): InputReader {\n return (request as AsyncIterable<Uint8Array>)[Symbol.asyncIterator]();\n}\n\nfunction outputWriterAdapter(\n response: Http2ServerResponse | ServerResponse\n): OutputWriter {\n const res = response as NodeWritableResponse;\n return {\n write: function (value: Uint8Array): Promise<void> {\n return new Promise((resolve, reject) => {\n res.write(value, (err) => (err ? reject(err) : resolve()));\n });\n },\n close: function (): Promise<void> {\n return new Promise((resolve) => {\n res.end(() => resolve());\n });\n },\n };\n}\n"],"mappings":"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"}
@@ -4,7 +4,7 @@ import { JournalValueCodec, ServiceDefinition, VirtualObjectDefinition, Workflow
4
4
 
5
5
  //#region src/endpoint/types.d.ts
6
6
  /**
7
- * Options for creating an endpoint handler for Node.js HTTP/2 servers.
7
+ * Options for creating an endpoint handler.
8
8
  */
9
9
  interface EndpointOptions {
10
10
  /**
@@ -4,7 +4,7 @@ import { JournalValueCodec, ServiceDefinition, VirtualObjectDefinition, Workflow
4
4
 
5
5
  //#region src/endpoint/types.d.ts
6
6
  /**
7
- * Options for creating an endpoint handler for Node.js HTTP/2 servers.
7
+ * Options for creating an endpoint handler.
8
8
  */
9
9
  interface EndpointOptions {
10
10
  /**
@@ -1,7 +1,8 @@
1
1
  import { ObjectOptions, ServiceOptions, WorkflowOptions } from "./types/rpc.cjs";
2
2
  import { LoggerTransport } from "./logging/logger_transport.cjs";
3
3
  import { JournalValueCodec, ServiceDefinition, VirtualObjectDefinition, WorkflowDefinition } from "@restatedev/restate-sdk-core";
4
- import { Http2ServerRequest, Http2ServerResponse } from "http2";
4
+ import { IncomingMessage, ServerResponse } from "node:http";
5
+ import { Http2ServerRequest, Http2ServerResponse } from "node:http2";
5
6
 
6
7
  //#region src/endpoint.d.ts
7
8
  type DefaultServiceOptions = ServiceOptions & ObjectOptions & WorkflowOptions;
@@ -63,12 +64,15 @@ interface RestateEndpointBase<E> {
63
64
  /**
64
65
  * RestateEndpoint encapsulates all the Restate services served by this endpoint.
65
66
  *
66
- * A RestateEndpoint can either be served as HTTP2 server, using the methods {@link RestateEndpoint.listen} or {@link RestateEndpoint.http2Handler}.
67
+ * A RestateEndpoint can be served as:
68
+ * - An HTTP/2 server using {@link RestateEndpoint.listen}, {@link RestateEndpoint.http2Handler}
69
+ * - An HTTP/1.1 server using {@link RestateEndpoint.http1Handler}
70
+ * - A combined HTTP/1.1 + HTTP/2 server using {@link RestateEndpoint.handler}
67
71
  *
68
72
  * For Lambda, check {@link LambdaEndpoint}
69
73
  *
70
74
  * @example
71
- * A typical endpoint served as HTTP server would look like this:
75
+ * A typical endpoint served as HTTP/2 server:
72
76
  * ```
73
77
  * import * as restate from "@restatedev/restate-sdk";
74
78
  *
@@ -77,6 +81,28 @@ interface RestateEndpointBase<E> {
77
81
  * .bind(myService)
78
82
  * .listen(8000);
79
83
  * ```
84
+ *
85
+ * @example
86
+ * Using the HTTP/1.1 handler with your own server:
87
+ * ```
88
+ * import * as http from "node:http";
89
+ * import * as restate from "@restatedev/restate-sdk";
90
+ *
91
+ * const endpoint = restate.endpoint().bind(myService);
92
+ * const server = http.createServer(endpoint.http1Handler());
93
+ * server.listen(8000);
94
+ * ```
95
+ *
96
+ * @example
97
+ * Using the combined handler with an HTTP/2 server that also accepts HTTP/1.1:
98
+ * ```
99
+ * import * as http2 from "node:http2";
100
+ * import * as restate from "@restatedev/restate-sdk";
101
+ *
102
+ * const endpoint = restate.endpoint().bind(myService);
103
+ * const server = http2.createSecureServer({ key, cert, allowHTTP1: true }, endpoint.handler());
104
+ * server.listen(8000);
105
+ * ```
80
106
  */
81
107
  interface RestateEndpoint extends RestateEndpointBase<RestateEndpoint> {
82
108
  /**
@@ -103,9 +129,65 @@ interface RestateEndpoint extends RestateEndpointBase<RestateEndpoint> {
103
129
  */
104
130
  listen(port?: number): Promise<number>;
105
131
  /**
106
- * Returns an http2 server handler. See {@link RestateEndpoint.listen} for more details.
132
+ * Returns an http2 server handler.
133
+ *
134
+ * By default, this handler uses bidirectional streaming (`BIDI_STREAM`).
135
+ * Set `bidirectional: false` to use request-response mode (`REQUEST_RESPONSE`).
136
+ *
137
+ * See {@link RestateEndpoint.listen} for more details.
138
+ */
139
+ http2Handler(options?: {
140
+ bidirectional?: boolean;
141
+ }): (request: Http2ServerRequest, response: Http2ServerResponse) => void;
142
+ /**
143
+ * Returns an http1 server handler.
144
+ *
145
+ * By default, this handler operates in request-response protocol mode (`REQUEST_RESPONSE`),
146
+ * which buffers the full request before sending the response. This is the safest mode
147
+ * for HTTP/1.1 and works across all environments and proxies.
148
+ *
149
+ * Set `bidirectional: true` to enable bidirectional streaming (`BIDI_STREAM`) for
150
+ * HTTP/1.1 servers that support it. Note that some proxies and clients may not
151
+ * handle HTTP/1.1 bidirectional streaming correctly.
152
+ *
153
+ * @example
154
+ * ```
155
+ * const httpServer = http.createServer(endpoint.http1Handler());
156
+ * httpServer.listen(port);
157
+ * ```
158
+ */
159
+ http1Handler(options?: {
160
+ bidirectional?: boolean;
161
+ }): (request: IncomingMessage, response: ServerResponse) => void;
162
+ /**
163
+ * Returns a combined request handler that auto-detects HTTP/1 vs HTTP/2
164
+ * requests and dispatches to the appropriate internal handler.
165
+ *
166
+ * By default (when `bidirectional` is omitted), HTTP/2+ requests use
167
+ * bidirectional streaming (`BIDI_STREAM`) and HTTP/1 requests use
168
+ * request-response mode (`REQUEST_RESPONSE`).
169
+ *
170
+ * Set `bidirectional: true` to force `BIDI_STREAM` for all requests,
171
+ * or `bidirectional: false` to force `REQUEST_RESPONSE` for all requests.
172
+ *
173
+ * This is useful with `http2.createSecureServer({ allowHTTP1: true })`, where
174
+ * the same server handles both HTTP/1.1 and HTTP/2 connections.
175
+ *
176
+ * @example
177
+ * ```
178
+ * const server = http2.createSecureServer(
179
+ * { key, cert, allowHTTP1: true },
180
+ * endpoint.handler()
181
+ * );
182
+ * server.listen(port);
183
+ * ```
107
184
  */
108
- http2Handler(): (request: Http2ServerRequest, response: Http2ServerResponse) => void;
185
+ handler(options?: {
186
+ bidirectional?: boolean;
187
+ }): {
188
+ (request: IncomingMessage, response: ServerResponse): void;
189
+ (request: Http2ServerRequest, response: Http2ServerResponse): void;
190
+ };
109
191
  }
110
192
  //#endregion
111
193
  export { DefaultServiceOptions, RestateEndpoint, RestateEndpointBase };
@@ -1 +1 @@
1
- {"version":3,"file":"endpoint.d.cts","names":[],"sources":["../src/endpoint.ts"],"sourcesContent":[],"mappings":";;;;;;KAyBY,qBAAA,GAAwB,iBAClC,gBACA;UAEe;EAJL;;;;;EAIK,IAAA,CAAA,UAAA,MAAA,EAAmB,CAAA,CAAA,CAAA,OAAA,EAQ5B,iBAR4B,CAQV,CARU,EAQP,CARO,CAAA,GAS5B,uBAT4B,CASJ,CATI,EASD,CATC,CAAA,GAU5B,kBAV4B,CAUT,CAVS,EAUN,CAVM,CAAA,CAAA,EAW/B,CAX+B;EAQV;;;;;;;;;EAGrB,cAAA,CAAA,GAAA,IAAA,EAAA,MAAA,EAAA,CAAA,EAWgC,CAXhC;EAWgC;;;;;;;EAwCyC,qBAAA,CAAA,OAAA,EA/B7C,qBA+B6C,CAAA,EA/BrB,CA+BqB;EAAC;AAqB/E;;;;;;;;;;;;;;;;;;;;oBA7BoB,kBAAkB;;;;;;;iDAQW,QAAQ,qBAAqB;;;;;;;;;;;;;;;;;;;;UAqB7D,eAAA,SAAwB,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;yBAuBpC;;;;4BAMZ,8BACC"}
1
+ {"version":3,"file":"endpoint.d.cts","names":[],"sources":["../src/endpoint.ts"],"sourcesContent":[],"mappings":";;;;;;;KA0BY,qBAAA,GAAwB,iBAClC,gBACA;UAEe;EAJL;;;;;EAIK,IAAA,CAAA,UAAA,MAAA,EAAmB,CAAA,CAAA,CAAA,OAAA,EAQ5B,iBAR4B,CAQV,CARU,EAQP,CARO,CAAA,GAS5B,uBAT4B,CASJ,CATI,EASD,CATC,CAAA,GAU5B,kBAV4B,CAUT,CAVS,EAUN,CAVM,CAAA,CAAA,EAW/B,CAX+B;EAQV;;;;;;;;;EAGrB,cAAA,CAAA,GAAA,IAAA,EAAA,MAAA,EAAA,CAAA,EAWgC,CAXhC;EAWgC;;;;;;;EAwCyC,qBAAA,CAAA,OAAA,EA/B7C,qBA+B6C,CAAA,EA/BrB,CA+BqB;EAAC;AA8C/E;;;;;;;;;;;;;;;;;;;;oBAtDoB,kBAAkB;;;;;;;iDAQW,QAAQ,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UA8C7D,eAAA,SAAwB,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;yBAuBpC;;;;;;;;;;;gBAYT,8BAA8B;;;;;;;;;;;;;;;;;;;;gBAqB9B,2BAA2B;;;;;;;;;;;;;;;;;;;;;;;;;;;cA0B7B,2BAA2B;cAC3B,8BAA8B"}
@@ -1,7 +1,8 @@
1
1
  import { ObjectOptions, ServiceOptions, WorkflowOptions } from "./types/rpc.js";
2
2
  import { LoggerTransport } from "./logging/logger_transport.js";
3
3
  import { JournalValueCodec, ServiceDefinition, VirtualObjectDefinition, WorkflowDefinition } from "@restatedev/restate-sdk-core";
4
- import { Http2ServerRequest, Http2ServerResponse } from "http2";
4
+ import { Http2ServerRequest, Http2ServerResponse } from "node:http2";
5
+ import { IncomingMessage, ServerResponse } from "node:http";
5
6
 
6
7
  //#region src/endpoint.d.ts
7
8
  type DefaultServiceOptions = ServiceOptions & ObjectOptions & WorkflowOptions;
@@ -63,12 +64,15 @@ interface RestateEndpointBase<E> {
63
64
  /**
64
65
  * RestateEndpoint encapsulates all the Restate services served by this endpoint.
65
66
  *
66
- * A RestateEndpoint can either be served as HTTP2 server, using the methods {@link RestateEndpoint.listen} or {@link RestateEndpoint.http2Handler}.
67
+ * A RestateEndpoint can be served as:
68
+ * - An HTTP/2 server using {@link RestateEndpoint.listen}, {@link RestateEndpoint.http2Handler}
69
+ * - An HTTP/1.1 server using {@link RestateEndpoint.http1Handler}
70
+ * - A combined HTTP/1.1 + HTTP/2 server using {@link RestateEndpoint.handler}
67
71
  *
68
72
  * For Lambda, check {@link LambdaEndpoint}
69
73
  *
70
74
  * @example
71
- * A typical endpoint served as HTTP server would look like this:
75
+ * A typical endpoint served as HTTP/2 server:
72
76
  * ```
73
77
  * import * as restate from "@restatedev/restate-sdk";
74
78
  *
@@ -77,6 +81,28 @@ interface RestateEndpointBase<E> {
77
81
  * .bind(myService)
78
82
  * .listen(8000);
79
83
  * ```
84
+ *
85
+ * @example
86
+ * Using the HTTP/1.1 handler with your own server:
87
+ * ```
88
+ * import * as http from "node:http";
89
+ * import * as restate from "@restatedev/restate-sdk";
90
+ *
91
+ * const endpoint = restate.endpoint().bind(myService);
92
+ * const server = http.createServer(endpoint.http1Handler());
93
+ * server.listen(8000);
94
+ * ```
95
+ *
96
+ * @example
97
+ * Using the combined handler with an HTTP/2 server that also accepts HTTP/1.1:
98
+ * ```
99
+ * import * as http2 from "node:http2";
100
+ * import * as restate from "@restatedev/restate-sdk";
101
+ *
102
+ * const endpoint = restate.endpoint().bind(myService);
103
+ * const server = http2.createSecureServer({ key, cert, allowHTTP1: true }, endpoint.handler());
104
+ * server.listen(8000);
105
+ * ```
80
106
  */
81
107
  interface RestateEndpoint extends RestateEndpointBase<RestateEndpoint> {
82
108
  /**
@@ -103,9 +129,65 @@ interface RestateEndpoint extends RestateEndpointBase<RestateEndpoint> {
103
129
  */
104
130
  listen(port?: number): Promise<number>;
105
131
  /**
106
- * Returns an http2 server handler. See {@link RestateEndpoint.listen} for more details.
132
+ * Returns an http2 server handler.
133
+ *
134
+ * By default, this handler uses bidirectional streaming (`BIDI_STREAM`).
135
+ * Set `bidirectional: false` to use request-response mode (`REQUEST_RESPONSE`).
136
+ *
137
+ * See {@link RestateEndpoint.listen} for more details.
138
+ */
139
+ http2Handler(options?: {
140
+ bidirectional?: boolean;
141
+ }): (request: Http2ServerRequest, response: Http2ServerResponse) => void;
142
+ /**
143
+ * Returns an http1 server handler.
144
+ *
145
+ * By default, this handler operates in request-response protocol mode (`REQUEST_RESPONSE`),
146
+ * which buffers the full request before sending the response. This is the safest mode
147
+ * for HTTP/1.1 and works across all environments and proxies.
148
+ *
149
+ * Set `bidirectional: true` to enable bidirectional streaming (`BIDI_STREAM`) for
150
+ * HTTP/1.1 servers that support it. Note that some proxies and clients may not
151
+ * handle HTTP/1.1 bidirectional streaming correctly.
152
+ *
153
+ * @example
154
+ * ```
155
+ * const httpServer = http.createServer(endpoint.http1Handler());
156
+ * httpServer.listen(port);
157
+ * ```
158
+ */
159
+ http1Handler(options?: {
160
+ bidirectional?: boolean;
161
+ }): (request: IncomingMessage, response: ServerResponse) => void;
162
+ /**
163
+ * Returns a combined request handler that auto-detects HTTP/1 vs HTTP/2
164
+ * requests and dispatches to the appropriate internal handler.
165
+ *
166
+ * By default (when `bidirectional` is omitted), HTTP/2+ requests use
167
+ * bidirectional streaming (`BIDI_STREAM`) and HTTP/1 requests use
168
+ * request-response mode (`REQUEST_RESPONSE`).
169
+ *
170
+ * Set `bidirectional: true` to force `BIDI_STREAM` for all requests,
171
+ * or `bidirectional: false` to force `REQUEST_RESPONSE` for all requests.
172
+ *
173
+ * This is useful with `http2.createSecureServer({ allowHTTP1: true })`, where
174
+ * the same server handles both HTTP/1.1 and HTTP/2 connections.
175
+ *
176
+ * @example
177
+ * ```
178
+ * const server = http2.createSecureServer(
179
+ * { key, cert, allowHTTP1: true },
180
+ * endpoint.handler()
181
+ * );
182
+ * server.listen(port);
183
+ * ```
107
184
  */
108
- http2Handler(): (request: Http2ServerRequest, response: Http2ServerResponse) => void;
185
+ handler(options?: {
186
+ bidirectional?: boolean;
187
+ }): {
188
+ (request: IncomingMessage, response: ServerResponse): void;
189
+ (request: Http2ServerRequest, response: Http2ServerResponse): void;
190
+ };
109
191
  }
110
192
  //#endregion
111
193
  export { DefaultServiceOptions, RestateEndpoint, RestateEndpointBase };
@@ -1 +1 @@
1
- {"version":3,"file":"endpoint.d.ts","names":[],"sources":["../src/endpoint.ts"],"sourcesContent":[],"mappings":";;;;;;KAyBY,qBAAA,GAAwB,iBAClC,gBACA;UAEe;EAJL;;;;;EAIK,IAAA,CAAA,UAAA,MAAA,EAAmB,CAAA,CAAA,CAAA,OAAA,EAQ5B,iBAR4B,CAQV,CARU,EAQP,CARO,CAAA,GAS5B,uBAT4B,CASJ,CATI,EASD,CATC,CAAA,GAU5B,kBAV4B,CAUT,CAVS,EAUN,CAVM,CAAA,CAAA,EAW/B,CAX+B;EAQV;;;;;;;;;EAGrB,cAAA,CAAA,GAAA,IAAA,EAAA,MAAA,EAAA,CAAA,EAWgC,CAXhC;EAWgC;;;;;;;EAwCyC,qBAAA,CAAA,OAAA,EA/B7C,qBA+B6C,CAAA,EA/BrB,CA+BqB;EAAC;AAqB/E;;;;;;;;;;;;;;;;;;;;oBA7BoB,kBAAkB;;;;;;;iDAQW,QAAQ,qBAAqB;;;;;;;;;;;;;;;;;;;;UAqB7D,eAAA,SAAwB,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;yBAuBpC;;;;4BAMZ,8BACC"}
1
+ {"version":3,"file":"endpoint.d.ts","names":[],"sources":["../src/endpoint.ts"],"sourcesContent":[],"mappings":";;;;;;;KA0BY,qBAAA,GAAwB,iBAClC,gBACA;UAEe;EAJL;;;;;EAIK,IAAA,CAAA,UAAA,MAAA,EAAmB,CAAA,CAAA,CAAA,OAAA,EAQ5B,iBAR4B,CAQV,CARU,EAQP,CARO,CAAA,GAS5B,uBAT4B,CASJ,CATI,EASD,CATC,CAAA,GAU5B,kBAV4B,CAUT,CAVS,EAUN,CAVM,CAAA,CAAA,EAW/B,CAX+B;EAQV;;;;;;;;;EAGrB,cAAA,CAAA,GAAA,IAAA,EAAA,MAAA,EAAA,CAAA,EAWgC,CAXhC;EAWgC;;;;;;;EAwCyC,qBAAA,CAAA,OAAA,EA/B7C,qBA+B6C,CAAA,EA/BrB,CA+BqB;EAAC;AA8C/E;;;;;;;;;;;;;;;;;;;;oBAtDoB,kBAAkB;;;;;;;iDAQW,QAAQ,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UA8C7D,eAAA,SAAwB,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;yBAuBpC;;;;;;;;;;;gBAYT,8BAA8B;;;;;;;;;;;;;;;;;;;;gBAqB9B,2BAA2B;;;;;;;;;;;;;;;;;;;;;;;;;;;cA0B7B,2BAA2B;cAC3B,8BAA8B"}
@@ -0,0 +1,26 @@
1
+ const require_errors = require('./types/errors.cjs');
2
+ const require_context_impl = require('./context_impl.cjs');
3
+
4
+ //#region src/error_sanitization.ts
5
+ /**
6
+ * Strips SDK-internal metadata from an error before it enters the interceptor
7
+ * chain. Interceptors see a plain Error — no CommandError.
8
+ */
9
+ function sanitizeError(e) {
10
+ if (e instanceof require_context_impl.CommandError) return require_errors.ensureError(e.cause);
11
+ return require_errors.ensureError(e);
12
+ }
13
+ /**
14
+ * Restores SDK-internal metadata after the interceptor chain exits, using the
15
+ * original error's metadata and the interceptor's error as the new cause.
16
+ * If the original had no SDK metadata, the interceptor's error passes through
17
+ * unchanged.
18
+ */
19
+ function restoreError(interceptorError, original) {
20
+ if (original instanceof require_context_impl.CommandError) return original.commandIndex !== void 0 ? new require_context_impl.CommandError(interceptorError, original.commandType, original.commandIndex) : new require_context_impl.CommandError(interceptorError, original.commandType);
21
+ return interceptorError;
22
+ }
23
+
24
+ //#endregion
25
+ exports.restoreError = restoreError;
26
+ exports.sanitizeError = sanitizeError;
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Strips SDK-internal metadata from an error before it enters the interceptor
3
+ * chain. Interceptors see a plain Error — no CommandError.
4
+ */
5
+ export declare function sanitizeError(e: unknown): Error;
6
+ /**
7
+ * Restores SDK-internal metadata after the interceptor chain exits, using the
8
+ * original error's metadata and the interceptor's error as the new cause.
9
+ * If the original had no SDK metadata, the interceptor's error passes through
10
+ * unchanged.
11
+ */
12
+ export declare function restoreError(interceptorError: unknown, original: unknown): unknown;
13
+ //# sourceMappingURL=error_sanitization.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error_sanitization.d.ts","sourceRoot":"","sources":["../src/error_sanitization.ts"],"names":[],"mappings":"AAcA;;;GAGG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAAE,OAAO,GAAG,KAAK,CAG/C;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAC1B,gBAAgB,EAAE,OAAO,EACzB,QAAQ,EAAE,OAAO,GAChB,OAAO,CAWT"}
@@ -0,0 +1,26 @@
1
+ import { ensureError } from "./types/errors.js";
2
+ import { CommandError } from "./context_impl.js";
3
+
4
+ //#region src/error_sanitization.ts
5
+ /**
6
+ * Strips SDK-internal metadata from an error before it enters the interceptor
7
+ * chain. Interceptors see a plain Error — no CommandError.
8
+ */
9
+ function sanitizeError(e) {
10
+ if (e instanceof CommandError) return ensureError(e.cause);
11
+ return ensureError(e);
12
+ }
13
+ /**
14
+ * Restores SDK-internal metadata after the interceptor chain exits, using the
15
+ * original error's metadata and the interceptor's error as the new cause.
16
+ * If the original had no SDK metadata, the interceptor's error passes through
17
+ * unchanged.
18
+ */
19
+ function restoreError(interceptorError, original) {
20
+ if (original instanceof CommandError) return original.commandIndex !== void 0 ? new CommandError(interceptorError, original.commandType, original.commandIndex) : new CommandError(interceptorError, original.commandType);
21
+ return interceptorError;
22
+ }
23
+
24
+ //#endregion
25
+ export { restoreError, sanitizeError };
26
+ //# sourceMappingURL=error_sanitization.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error_sanitization.js","names":[],"sources":["../src/error_sanitization.ts"],"sourcesContent":["/*\n * Copyright (c) 2023-2024 - Restate Software, Inc., Restate GmbH\n *\n * This file is part of the Restate SDK for Node.js/TypeScript,\n * which is released under the MIT license.\n *\n * You can find a copy of the license in file LICENSE in the root\n * directory of this repository or package, or at\n * https://github.com/restatedev/sdk-typescript/blob/main/LICENSE\n */\n\nimport { CommandError } from \"./context_impl.js\";\nimport { ensureError } from \"./types/errors.js\";\n\n/**\n * Strips SDK-internal metadata from an error before it enters the interceptor\n * chain. Interceptors see a plain Error — no CommandError.\n */\nexport function sanitizeError(e: unknown): Error {\n if (e instanceof CommandError) return ensureError(e.cause);\n return ensureError(e);\n}\n\n/**\n * Restores SDK-internal metadata after the interceptor chain exits, using the\n * original error's metadata and the interceptor's error as the new cause.\n * If the original had no SDK metadata, the interceptor's error passes through\n * unchanged.\n */\nexport function restoreError(\n interceptorError: unknown,\n original: unknown\n): unknown {\n if (original instanceof CommandError) {\n return original.commandIndex !== undefined\n ? new CommandError(\n interceptorError,\n original.commandType,\n original.commandIndex\n )\n : new CommandError(interceptorError, original.commandType);\n }\n return interceptorError;\n}\n"],"mappings":";;;;;;;;AAkBA,SAAgB,cAAc,GAAmB;AAC/C,KAAI,aAAa,aAAc,QAAO,YAAY,EAAE,MAAM;AAC1D,QAAO,YAAY,EAAE;;;;;;;;AASvB,SAAgB,aACd,kBACA,UACS;AACT,KAAI,oBAAoB,aACtB,QAAO,SAAS,iBAAiB,SAC7B,IAAI,aACF,kBACA,SAAS,aACT,SAAS,aACV,GACD,IAAI,aAAa,kBAAkB,SAAS,YAAY;AAE9D,QAAO"}
package/dist/fetch.cjs CHANGED
@@ -1,7 +1,8 @@
1
1
  const require_rolldown_runtime = require('./_virtual/rolldown_runtime.cjs');
2
2
  const require_errors = require('./types/errors.cjs');
3
- const require_rpc = require('./types/rpc.cjs');
3
+ const require_promises = require('./promises.cjs');
4
4
  const require_context = require('./context.cjs');
5
+ const require_rpc = require('./types/rpc.cjs');
5
6
  const require_internal = require('./internal.cjs');
6
7
  const require_common_api = require('./common_api.cjs');
7
8
  const require_fetch_endpoint = require('./endpoint/fetch_endpoint.cjs');
@@ -73,6 +74,7 @@ Object.defineProperty(exports, 'internal', {
73
74
  return require_internal.internal_exports;
74
75
  }
75
76
  });
77
+ exports.isRestatePromise = require_promises.isRestatePromise;
76
78
  exports.object = require_rpc.object;
77
79
  Object.defineProperty(exports, 'rpc', {
78
80
  enumerable: true,