@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.
- package/dist/_virtual/rolldown_runtime.cjs +9 -0
- package/dist/common_api.cjs +2 -1
- package/dist/common_api.d.cts +6 -2
- package/dist/common_api.d.cts.map +1 -1
- package/dist/common_api.d.ts +6 -2
- package/dist/common_api.d.ts.map +1 -1
- package/dist/common_api.js +2 -1
- package/dist/common_api.js.map +1 -1
- package/dist/context.cjs +13 -9
- package/dist/context.d.cts +36 -29
- package/dist/context.d.cts.map +1 -1
- package/dist/context.d.ts +36 -29
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +13 -9
- package/dist/context.js.map +1 -1
- package/dist/context_impl.cjs +150 -91
- package/dist/context_impl.d.cts +8 -0
- package/dist/context_impl.d.ts +8 -72
- package/dist/context_impl.d.ts.map +1 -1
- package/dist/context_impl.js +151 -93
- package/dist/context_impl.js.map +1 -1
- package/dist/endpoint/components.cjs +35 -20
- package/dist/endpoint/components.d.cts +5 -0
- package/dist/endpoint/components.d.ts +5 -97
- package/dist/endpoint/components.d.ts.map +1 -1
- package/dist/endpoint/components.js +35 -20
- package/dist/endpoint/components.js.map +1 -1
- package/dist/endpoint/endpoint.cjs +2 -2
- package/dist/endpoint/endpoint.d.cts +5 -0
- package/dist/endpoint/endpoint.d.ts +5 -39
- package/dist/endpoint/endpoint.js +2 -2
- package/dist/endpoint/endpoint.js.map +1 -1
- package/dist/endpoint/handlers/generic.cjs +115 -39
- package/dist/endpoint/handlers/generic.d.ts.map +1 -1
- package/dist/endpoint/handlers/generic.js +115 -39
- package/dist/endpoint/handlers/generic.js.map +1 -1
- package/dist/endpoint/handlers/types.d.cts +1 -0
- package/dist/endpoint/handlers/types.d.ts +1 -41
- package/dist/endpoint/handlers/utils.cjs +1 -1
- package/dist/endpoint/handlers/utils.js +1 -1
- package/dist/endpoint/handlers/vm/sdk_shared_core_wasm_bindings.cjs +43 -3
- package/dist/endpoint/handlers/vm/sdk_shared_core_wasm_bindings.d.ts +19 -1
- package/dist/endpoint/handlers/vm/sdk_shared_core_wasm_bindings.d.ts.map +1 -1
- package/dist/endpoint/handlers/vm/sdk_shared_core_wasm_bindings.js +43 -3
- package/dist/endpoint/handlers/vm/sdk_shared_core_wasm_bindings.js.map +1 -1
- package/dist/endpoint/node_endpoint.cjs +28 -12
- package/dist/endpoint/node_endpoint.d.ts +14 -2
- package/dist/endpoint/node_endpoint.d.ts.map +1 -1
- package/dist/endpoint/node_endpoint.js +27 -11
- package/dist/endpoint/node_endpoint.js.map +1 -1
- package/dist/endpoint/types.d.cts +1 -1
- package/dist/endpoint/types.d.ts +1 -1
- package/dist/endpoint.d.cts +87 -5
- package/dist/endpoint.d.cts.map +1 -1
- package/dist/endpoint.d.ts +87 -5
- package/dist/endpoint.d.ts.map +1 -1
- package/dist/error_sanitization.cjs +26 -0
- package/dist/error_sanitization.d.ts +13 -0
- package/dist/error_sanitization.d.ts.map +1 -0
- package/dist/error_sanitization.js +26 -0
- package/dist/error_sanitization.js.map +1 -0
- package/dist/fetch.cjs +3 -1
- package/dist/fetch.d.cts +5 -3
- package/dist/fetch.d.cts.map +1 -1
- package/dist/fetch.d.ts +5 -3
- package/dist/fetch.d.ts.map +1 -1
- package/dist/fetch.js +3 -2
- package/dist/fetch.js.map +1 -1
- package/dist/hooks.d.cts +87 -0
- package/dist/hooks.d.cts.map +1 -0
- package/dist/hooks.d.ts +87 -0
- package/dist/hooks.d.ts.map +1 -0
- package/dist/hooks.js +2 -0
- package/dist/hooks.js.map +1 -0
- package/dist/index.cjs +3 -1
- package/dist/index.d.cts +6 -4
- package/dist/index.d.ts +6 -4
- package/dist/index.js +3 -2
- package/dist/internal.cjs +3 -1
- package/dist/internal.d.cts +186 -2
- package/dist/internal.d.cts.map +1 -1
- package/dist/internal.d.ts +186 -2
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +4 -1
- package/dist/internal.js.map +1 -1
- package/dist/io.d.cts +1 -0
- package/dist/io.d.ts +1 -24
- package/dist/lambda.cjs +3 -1
- package/dist/lambda.d.cts +5 -3
- package/dist/lambda.d.cts.map +1 -1
- package/dist/lambda.d.ts +5 -3
- package/dist/lambda.d.ts.map +1 -1
- package/dist/lambda.js +3 -2
- package/dist/lambda.js.map +1 -1
- package/dist/logging/logger.d.cts +1 -0
- package/dist/logging/logger.d.ts +1 -10
- package/dist/node.cjs +23 -6
- package/dist/node.d.cts +46 -8
- package/dist/node.d.cts.map +1 -1
- package/dist/node.d.ts +46 -8
- package/dist/node.d.ts.map +1 -1
- package/dist/node.js +23 -7
- package/dist/node.js.map +1 -1
- package/dist/package.cjs +1 -1
- package/dist/package.js +1 -1
- package/dist/package.js.map +1 -1
- package/dist/promises.cjs +90 -53
- package/dist/promises.d.cts +18 -0
- package/dist/promises.d.cts.map +1 -0
- package/dist/promises.d.ts +15 -108
- package/dist/promises.d.ts.map +1 -1
- package/dist/promises.js +85 -48
- package/dist/promises.js.map +1 -1
- package/dist/types/errors.cjs +13 -0
- package/dist/types/errors.d.cts +11 -5
- package/dist/types/errors.d.cts.map +1 -1
- package/dist/types/errors.d.ts +11 -5
- package/dist/types/errors.d.ts.map +1 -1
- package/dist/types/errors.js +13 -1
- package/dist/types/errors.js.map +1 -1
- package/dist/types/rpc.cjs +7 -19
- package/dist/types/rpc.d.cts +174 -0
- package/dist/types/rpc.d.cts.map +1 -1
- package/dist/types/rpc.d.ts +174 -0
- package/dist/types/rpc.d.ts.map +1 -1
- package/dist/types/rpc.js +7 -19
- package/dist/types/rpc.js.map +1 -1
- 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
|
|
7
|
-
|
|
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 =
|
|
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
|
|
56
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 {
|
|
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(
|
|
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,
|
|
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
|
|
54
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
7
|
+
* Options for creating an endpoint handler.
|
|
8
8
|
*/
|
|
9
9
|
interface EndpointOptions {
|
|
10
10
|
/**
|
package/dist/endpoint/types.d.ts
CHANGED
|
@@ -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
|
|
7
|
+
* Options for creating an endpoint handler.
|
|
8
8
|
*/
|
|
9
9
|
interface EndpointOptions {
|
|
10
10
|
/**
|
package/dist/endpoint.d.cts
CHANGED
|
@@ -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 {
|
|
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
|
|
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
|
|
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.
|
|
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
|
-
|
|
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 };
|
package/dist/endpoint.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"endpoint.d.cts","names":[],"sources":["../src/endpoint.ts"],"sourcesContent":[],"mappings":"
|
|
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"}
|
package/dist/endpoint.d.ts
CHANGED
|
@@ -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
|
|
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
|
|
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.
|
|
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
|
-
|
|
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 };
|
package/dist/endpoint.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"endpoint.d.ts","names":[],"sources":["../src/endpoint.ts"],"sourcesContent":[],"mappings":"
|
|
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
|
|
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,
|