@restatedev/restate-sdk 1.11.1 → 1.13.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/README.md +12 -9
- 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 +38 -22
- 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 +38 -22
- 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 +113 -39
- package/dist/endpoint/handlers/generic.d.ts.map +1 -1
- package/dist/endpoint/handlers/generic.js +113 -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 +100 -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 +95 -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 +185 -0
- package/dist/types/rpc.d.cts.map +1 -1
- package/dist/types/rpc.d.ts +185 -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,13 +3,13 @@ import { millisOrDurationToMillis, serde } from "@restatedev/restate-sdk-core";
|
|
|
3
3
|
|
|
4
4
|
//#region src/endpoint/components.ts
|
|
5
5
|
function handlerInputDiscovery(handler, defaultSerde) {
|
|
6
|
-
const serde$1 = handler.
|
|
6
|
+
const serde$1 = handler.options?.input ?? defaultSerde;
|
|
7
7
|
let contentType = void 0;
|
|
8
8
|
let jsonSchema = void 0;
|
|
9
9
|
if (serde$1.jsonSchema) {
|
|
10
10
|
jsonSchema = serde$1.jsonSchema;
|
|
11
|
-
contentType = handler.accept ?? serde$1.contentType;
|
|
12
|
-
} else if (handler.accept) contentType = handler.accept;
|
|
11
|
+
contentType = handler.options?.accept ?? serde$1.contentType;
|
|
12
|
+
} else if (handler.options?.accept) contentType = handler.options?.accept;
|
|
13
13
|
else if (serde$1.contentType) contentType = serde$1.contentType;
|
|
14
14
|
else return {};
|
|
15
15
|
return {
|
|
@@ -19,20 +19,30 @@ function handlerInputDiscovery(handler, defaultSerde) {
|
|
|
19
19
|
};
|
|
20
20
|
}
|
|
21
21
|
function handlerOutputDiscovery(handler, defaultSerde) {
|
|
22
|
-
const serde$1 = handler.
|
|
22
|
+
const serde$1 = handler.options?.output ?? defaultSerde;
|
|
23
|
+
const setContentTypeIfEmpty = handler.options?.setOutputContentTypeIfEmpty ?? false;
|
|
23
24
|
let contentType = void 0;
|
|
24
25
|
let jsonSchema = void 0;
|
|
25
26
|
if (serde$1.jsonSchema) {
|
|
26
27
|
jsonSchema = serde$1.jsonSchema;
|
|
27
28
|
contentType = serde$1.contentType ?? "application/json";
|
|
28
29
|
} else if (serde$1.contentType) contentType = serde$1.contentType;
|
|
29
|
-
else return { setContentTypeIfEmpty
|
|
30
|
+
else return { setContentTypeIfEmpty };
|
|
30
31
|
return {
|
|
31
|
-
setContentTypeIfEmpty
|
|
32
|
+
setContentTypeIfEmpty,
|
|
32
33
|
jsonSchema,
|
|
33
34
|
contentType
|
|
34
35
|
};
|
|
35
36
|
}
|
|
37
|
+
function createExecutionOptions(serviceOptions, handlerOptions) {
|
|
38
|
+
const hooks = [...serviceOptions?.hooks ?? [], ...handlerOptions?.hooks ?? []];
|
|
39
|
+
return {
|
|
40
|
+
defaultSerde: handlerOptions?.serde ?? serviceOptions?.serde,
|
|
41
|
+
asTerminalError: handlerOptions?.asTerminalError ?? serviceOptions?.asTerminalError,
|
|
42
|
+
hooks: hooks.length > 0 ? hooks : void 0,
|
|
43
|
+
explicitCancellation: handlerOptions?.explicitCancellation ?? serviceOptions?.explicitCancellation
|
|
44
|
+
};
|
|
45
|
+
}
|
|
36
46
|
var ServiceComponent = class {
|
|
37
47
|
handlers = /* @__PURE__ */ new Map();
|
|
38
48
|
constructor(componentName, description, metadata, options) {
|
|
@@ -51,7 +61,7 @@ var ServiceComponent = class {
|
|
|
51
61
|
const handlers = [...this.handlers.entries()].map(([name, handler]) => {
|
|
52
62
|
return {
|
|
53
63
|
name,
|
|
54
|
-
...commonHandlerOptions(handler.handlerWrapper,
|
|
64
|
+
...commonHandlerOptions(handler.handlerWrapper, handler.executionOptions.defaultSerde ?? serde.json)
|
|
55
65
|
};
|
|
56
66
|
});
|
|
57
67
|
return {
|
|
@@ -68,10 +78,12 @@ var ServiceComponent = class {
|
|
|
68
78
|
}
|
|
69
79
|
};
|
|
70
80
|
var ServiceHandler$1 = class {
|
|
81
|
+
executionOptions;
|
|
71
82
|
constructor(handlerName, handlerWrapper, parent) {
|
|
72
83
|
this.handlerName = handlerName;
|
|
73
84
|
this.handlerWrapper = handlerWrapper;
|
|
74
85
|
this.parent = parent;
|
|
86
|
+
this.executionOptions = createExecutionOptions(this.parent.options, handlerWrapper.options);
|
|
75
87
|
}
|
|
76
88
|
name() {
|
|
77
89
|
return this.handlerName;
|
|
@@ -105,7 +117,7 @@ var VirtualObjectComponent = class {
|
|
|
105
117
|
return {
|
|
106
118
|
name,
|
|
107
119
|
ty: handler.kind() === HandlerKind.EXCLUSIVE ? "EXCLUSIVE" : "SHARED",
|
|
108
|
-
...commonHandlerOptions(handler.handlerWrapper,
|
|
120
|
+
...commonHandlerOptions(handler.handlerWrapper, handler.executionOptions.defaultSerde ?? serde.json)
|
|
109
121
|
};
|
|
110
122
|
});
|
|
111
123
|
return {
|
|
@@ -122,10 +134,12 @@ var VirtualObjectComponent = class {
|
|
|
122
134
|
}
|
|
123
135
|
};
|
|
124
136
|
var VirtualObjectHandler = class {
|
|
137
|
+
executionOptions;
|
|
125
138
|
constructor(handlerName, handlerWrapper, parent) {
|
|
126
139
|
this.handlerName = handlerName;
|
|
127
140
|
this.handlerWrapper = handlerWrapper;
|
|
128
141
|
this.parent = parent;
|
|
142
|
+
this.executionOptions = createExecutionOptions(this.parent.options, handlerWrapper.options);
|
|
129
143
|
}
|
|
130
144
|
name() {
|
|
131
145
|
return this.handlerName;
|
|
@@ -160,7 +174,7 @@ var WorkflowComponent = class {
|
|
|
160
174
|
name,
|
|
161
175
|
ty: handler.kind() === HandlerKind.WORKFLOW ? "WORKFLOW" : "SHARED",
|
|
162
176
|
workflowCompletionRetention: handler.kind() === HandlerKind.WORKFLOW && this.options?.workflowRetention !== void 0 ? millisOrDurationToMillis(this.options?.workflowRetention) : void 0,
|
|
163
|
-
...commonHandlerOptions(handler.handlerWrapper,
|
|
177
|
+
...commonHandlerOptions(handler.handlerWrapper, handler.executionOptions.defaultSerde ?? serde.json)
|
|
164
178
|
};
|
|
165
179
|
});
|
|
166
180
|
return {
|
|
@@ -177,10 +191,12 @@ var WorkflowComponent = class {
|
|
|
177
191
|
}
|
|
178
192
|
};
|
|
179
193
|
var WorkflowHandler$1 = class {
|
|
194
|
+
executionOptions;
|
|
180
195
|
constructor(handlerName, handlerWrapper, parent) {
|
|
181
196
|
this.handlerName = handlerName;
|
|
182
197
|
this.handlerWrapper = handlerWrapper;
|
|
183
198
|
this.parent = parent;
|
|
199
|
+
this.executionOptions = createExecutionOptions(this.parent.options, handlerWrapper.options);
|
|
184
200
|
}
|
|
185
201
|
name() {
|
|
186
202
|
return this.handlerName;
|
|
@@ -232,19 +248,19 @@ function commonHandlerOptions(wrapper, defaultSerde) {
|
|
|
232
248
|
return {
|
|
233
249
|
input: handlerInputDiscovery(wrapper, defaultSerde),
|
|
234
250
|
output: handlerOutputDiscovery(wrapper, defaultSerde),
|
|
235
|
-
journalRetention: wrapper.journalRetention !== void 0 ? millisOrDurationToMillis(wrapper.journalRetention) : void 0,
|
|
236
|
-
idempotencyRetention: wrapper.idempotencyRetention !== void 0 ? millisOrDurationToMillis(wrapper.idempotencyRetention) : void 0,
|
|
237
|
-
inactivityTimeout: wrapper.inactivityTimeout !== void 0 ? millisOrDurationToMillis(wrapper.inactivityTimeout) : void 0,
|
|
238
|
-
abortTimeout: wrapper.abortTimeout !== void 0 ? millisOrDurationToMillis(wrapper.abortTimeout) : void 0,
|
|
239
|
-
ingressPrivate: wrapper.ingressPrivate,
|
|
240
|
-
enableLazyState: wrapper.enableLazyState,
|
|
241
|
-
retryPolicyExponentiationFactor: wrapper.retryPolicy?.exponentiationFactor,
|
|
242
|
-
retryPolicyInitialInterval: wrapper.retryPolicy?.initialInterval !== void 0 ? millisOrDurationToMillis(wrapper.retryPolicy?.initialInterval) : void 0,
|
|
243
|
-
retryPolicyMaxInterval: wrapper.retryPolicy?.maxInterval !== void 0 ? millisOrDurationToMillis(wrapper.retryPolicy?.maxInterval) : void 0,
|
|
244
|
-
retryPolicyMaxAttempts: wrapper.retryPolicy?.maxAttempts,
|
|
245
|
-
retryPolicyOnMaxAttempts: wrapper.retryPolicy?.onMaxAttempts === "kill" ? "KILL" : wrapper.retryPolicy?.onMaxAttempts === "pause" ? "PAUSE" : void 0,
|
|
246
|
-
documentation: wrapper.description,
|
|
247
|
-
metadata: wrapper.metadata
|
|
251
|
+
journalRetention: wrapper.options?.journalRetention !== void 0 ? millisOrDurationToMillis(wrapper.options?.journalRetention) : void 0,
|
|
252
|
+
idempotencyRetention: wrapper.options?.idempotencyRetention !== void 0 ? millisOrDurationToMillis(wrapper.options?.idempotencyRetention) : void 0,
|
|
253
|
+
inactivityTimeout: wrapper.options?.inactivityTimeout !== void 0 ? millisOrDurationToMillis(wrapper.options?.inactivityTimeout) : void 0,
|
|
254
|
+
abortTimeout: wrapper.options?.abortTimeout !== void 0 ? millisOrDurationToMillis(wrapper.options?.abortTimeout) : void 0,
|
|
255
|
+
ingressPrivate: wrapper.options?.ingressPrivate,
|
|
256
|
+
enableLazyState: wrapper.options !== void 0 && "enableLazyState" in wrapper.options ? wrapper.options?.enableLazyState : void 0,
|
|
257
|
+
retryPolicyExponentiationFactor: wrapper.options?.retryPolicy?.exponentiationFactor,
|
|
258
|
+
retryPolicyInitialInterval: wrapper.options?.retryPolicy?.initialInterval !== void 0 ? millisOrDurationToMillis(wrapper.options?.retryPolicy?.initialInterval) : void 0,
|
|
259
|
+
retryPolicyMaxInterval: wrapper.options?.retryPolicy?.maxInterval !== void 0 ? millisOrDurationToMillis(wrapper.options?.retryPolicy?.maxInterval) : void 0,
|
|
260
|
+
retryPolicyMaxAttempts: wrapper.options?.retryPolicy?.maxAttempts,
|
|
261
|
+
retryPolicyOnMaxAttempts: wrapper.options?.retryPolicy?.onMaxAttempts === "kill" ? "KILL" : wrapper.options?.retryPolicy?.onMaxAttempts === "pause" ? "PAUSE" : void 0,
|
|
262
|
+
documentation: wrapper.options?.description,
|
|
263
|
+
metadata: wrapper.options?.metadata
|
|
248
264
|
};
|
|
249
265
|
}
|
|
250
266
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"components.js","names":["serde","componentName: string","description?: string","metadata?: Record<string, string>","options?: ServiceOptions","ServiceHandler","handlers: d.Handler[]","handlerName: string","handlerWrapper: HandlerWrapper","parent: ServiceComponent","options?: ObjectOptions","parent: VirtualObjectComponent","options?: WorkflowOptions","WorkflowHandler","parent: WorkflowComponent"],"sources":["../../src/endpoint/components.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\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport type * as d from \"./discovery.js\";\nimport type { ContextImpl } from \"../context_impl.js\";\nimport type {\n HandlerWrapper,\n ObjectOptions,\n ServiceOptions,\n WorkflowOptions,\n} from \"../types/rpc.js\";\nimport { HandlerKind } from \"../types/rpc.js\";\nimport type { Serde } from \"@restatedev/restate-sdk-core\";\nimport { millisOrDurationToMillis, serde } from \"@restatedev/restate-sdk-core\";\n\n//\n// Interfaces\n//\nexport interface Component {\n name(): string;\n handlerMatching(url: InvokePathComponents): ComponentHandler | undefined;\n discovery(): d.Service;\n options?: ServiceOptions | ObjectOptions | WorkflowOptions;\n}\n\nexport interface ComponentHandler {\n name(): string;\n component(): Component;\n invoke(context: ContextImpl, input: Uint8Array): Promise<Uint8Array>;\n kind(): HandlerKind;\n}\n\n//\n// Service\n//\n\nfunction handlerInputDiscovery(\n handler: HandlerWrapper,\n defaultSerde: Serde<any>\n): d.InputPayload {\n const serde = handler.inputSerde ?? defaultSerde;\n\n let contentType = undefined;\n let jsonSchema = undefined;\n\n if (serde.jsonSchema) {\n jsonSchema = serde.jsonSchema;\n contentType = handler.accept ?? serde.contentType;\n } else if (handler.accept) {\n contentType = handler.accept;\n } else if (serde.contentType) {\n contentType = serde.contentType;\n } else {\n // no input information\n return {};\n }\n\n return {\n required: false,\n contentType,\n jsonSchema,\n };\n}\n\nfunction handlerOutputDiscovery(\n handler: HandlerWrapper,\n defaultSerde: Serde<any>\n): d.OutputPayload {\n const serde = handler.outputSerde ?? defaultSerde;\n\n let contentType = undefined;\n let jsonSchema = undefined;\n\n if (serde.jsonSchema) {\n jsonSchema = serde.jsonSchema;\n contentType = serde.contentType ?? \"application/json\";\n } else if (serde.contentType) {\n contentType = serde.contentType;\n } else {\n // no input information\n return { setContentTypeIfEmpty: false };\n }\n\n return {\n setContentTypeIfEmpty: false,\n jsonSchema,\n contentType,\n };\n}\n\nexport class ServiceComponent implements Component {\n private readonly handlers: Map<string, ServiceHandler> = new Map();\n\n constructor(\n private readonly componentName: string,\n public readonly description?: string,\n public readonly metadata?: Record<string, string>,\n public readonly options?: ServiceOptions\n ) {}\n\n name(): string {\n return this.componentName;\n }\n\n add(name: string, handlerWrapper: HandlerWrapper) {\n this.handlers.set(name, new ServiceHandler(name, handlerWrapper, this));\n }\n\n discovery(): d.Service {\n const handlers: d.Handler[] = [...this.handlers.entries()].map(\n ([name, handler]) => {\n return {\n name,\n ...commonHandlerOptions(\n handler.handlerWrapper,\n this.options?.serde ?? serde.json\n ),\n } satisfies d.Handler;\n }\n );\n\n return {\n name: this.componentName,\n ty: \"SERVICE\",\n handlers,\n documentation: this.description,\n metadata: this.metadata,\n ...commonServiceOptions(this.options),\n } satisfies d.Service;\n }\n\n handlerMatching(url: InvokePathComponents): ComponentHandler | undefined {\n return this.handlers.get(url.handlerName);\n }\n}\n\nexport class ServiceHandler implements ComponentHandler {\n constructor(\n private readonly handlerName: string,\n public readonly handlerWrapper: HandlerWrapper,\n private readonly parent: ServiceComponent\n ) {}\n\n name(): string {\n return this.handlerName;\n }\n\n component(): Component {\n return this.parent;\n }\n\n kind(): HandlerKind {\n return this.handlerWrapper.kind;\n }\n\n invoke(context: ContextImpl, input: Uint8Array): Promise<Uint8Array> {\n return this.handlerWrapper.invoke(context, input);\n }\n}\n\n//\n// Virtual Object\n//\n\nexport class VirtualObjectComponent implements Component {\n private readonly handlers: Map<string, VirtualObjectHandler> = new Map();\n\n constructor(\n public readonly componentName: string,\n public readonly description?: string,\n public readonly metadata?: Record<string, string>,\n public readonly options?: ObjectOptions\n ) {}\n\n name(): string {\n return this.componentName;\n }\n\n add(name: string, wrapper: HandlerWrapper) {\n this.handlers.set(name, new VirtualObjectHandler(name, wrapper, this));\n }\n\n discovery(): d.Service {\n const handlers: d.Handler[] = [...this.handlers.entries()].map(\n ([name, handler]) => {\n return {\n name,\n ty: handler.kind() === HandlerKind.EXCLUSIVE ? \"EXCLUSIVE\" : \"SHARED\",\n ...commonHandlerOptions(\n handler.handlerWrapper,\n this.options?.serde ?? serde.json\n ),\n } satisfies d.Handler;\n }\n );\n\n return {\n name: this.componentName,\n ty: \"VIRTUAL_OBJECT\",\n handlers,\n documentation: this.description,\n metadata: this.metadata,\n ...commonServiceOptions(this.options),\n } satisfies d.Service;\n }\n\n handlerMatching(url: InvokePathComponents): ComponentHandler | undefined {\n return this.handlers.get(url.handlerName);\n }\n}\n\nexport class VirtualObjectHandler implements ComponentHandler {\n constructor(\n private readonly handlerName: string,\n public readonly handlerWrapper: HandlerWrapper,\n private readonly parent: VirtualObjectComponent\n ) {}\n\n name(): string {\n return this.handlerName;\n }\n\n component(): Component {\n return this.parent;\n }\n\n kind(): HandlerKind {\n return this.handlerWrapper.kind;\n }\n\n invoke(context: ContextImpl, input: Uint8Array): Promise<Uint8Array> {\n return this.handlerWrapper.invoke(context, input);\n }\n}\n\n// Workflow\n\nexport class WorkflowComponent implements Component {\n private readonly handlers: Map<string, WorkflowHandler> = new Map();\n\n constructor(\n public readonly componentName: string,\n public readonly description?: string,\n public readonly metadata?: Record<string, string>,\n public readonly options?: WorkflowOptions\n ) {}\n\n name(): string {\n return this.componentName;\n }\n\n add(name: string, wrapper: HandlerWrapper) {\n this.handlers.set(name, new WorkflowHandler(name, wrapper, this));\n }\n\n discovery(): d.Service {\n const handlers: d.Handler[] = [...this.handlers.entries()].map(\n ([name, handler]) => {\n return {\n name,\n ty: handler.kind() === HandlerKind.WORKFLOW ? \"WORKFLOW\" : \"SHARED\",\n workflowCompletionRetention:\n handler.kind() === HandlerKind.WORKFLOW &&\n this.options?.workflowRetention !== undefined\n ? millisOrDurationToMillis(this.options?.workflowRetention)\n : undefined,\n ...commonHandlerOptions(\n handler.handlerWrapper,\n this.options?.serde ?? serde.json\n ),\n } satisfies d.Handler;\n }\n );\n\n return {\n name: this.componentName,\n ty: \"WORKFLOW\",\n handlers,\n documentation: this.description,\n metadata: this.metadata,\n ...commonServiceOptions(this.options),\n } satisfies d.Service;\n }\n\n handlerMatching(url: InvokePathComponents): ComponentHandler | undefined {\n return this.handlers.get(url.handlerName);\n }\n}\n\nexport class WorkflowHandler implements ComponentHandler {\n constructor(\n private readonly handlerName: string,\n public readonly handlerWrapper: HandlerWrapper,\n private readonly parent: WorkflowComponent\n ) {}\n\n name(): string {\n return this.handlerName;\n }\n component(): Component {\n return this.parent;\n }\n\n kind(): HandlerKind {\n return this.handlerWrapper.kind;\n }\n\n invoke(context: ContextImpl, input: Uint8Array): Promise<Uint8Array> {\n return this.handlerWrapper.invoke(context, input);\n }\n}\n\nexport type PathComponents =\n | InvokePathComponents\n | { type: \"discover\" }\n | { type: \"health\" }\n | { type: \"unknown\"; path: string };\n\nexport type InvokePathComponents = {\n type: \"invoke\";\n componentName: string;\n handlerName: string;\n};\n\nexport function parseUrlComponents(urlPath?: string): PathComponents {\n if (!urlPath) {\n return { type: \"unknown\", path: \"\" };\n }\n const fragments = urlPath.split(\"/\");\n if (fragments.length >= 3 && fragments[fragments.length - 3] === \"invoke\") {\n return {\n type: \"invoke\",\n componentName: fragments[fragments.length - 2]!,\n handlerName: fragments[fragments.length - 1]!,\n };\n }\n if (fragments.length > 0 && fragments[fragments.length - 1] === \"discover\") {\n return { type: \"discover\" };\n }\n if (fragments.length > 0 && fragments[fragments.length - 1] === \"health\") {\n return { type: \"health\" };\n }\n return { type: \"unknown\", path: urlPath };\n}\n\nfunction commonServiceOptions(\n options?: ServiceOptions | ObjectOptions | WorkflowOptions\n): Partial<d.Service> {\n return {\n journalRetention:\n options?.journalRetention !== undefined\n ? millisOrDurationToMillis(options.journalRetention)\n : undefined,\n idempotencyRetention:\n options?.idempotencyRetention !== undefined\n ? millisOrDurationToMillis(options.idempotencyRetention)\n : undefined,\n inactivityTimeout:\n options?.inactivityTimeout !== undefined\n ? millisOrDurationToMillis(options.inactivityTimeout)\n : undefined,\n abortTimeout:\n options?.abortTimeout !== undefined\n ? millisOrDurationToMillis(options.abortTimeout)\n : undefined,\n ingressPrivate: options?.ingressPrivate,\n enableLazyState:\n options !== undefined && \"enableLazyState\" in options\n ? options.enableLazyState\n : undefined,\n retryPolicyExponentiationFactor: options?.retryPolicy?.exponentiationFactor,\n retryPolicyInitialInterval:\n options?.retryPolicy?.initialInterval !== undefined\n ? millisOrDurationToMillis(options?.retryPolicy?.initialInterval)\n : undefined,\n retryPolicyMaxInterval:\n options?.retryPolicy?.maxInterval !== undefined\n ? millisOrDurationToMillis(options?.retryPolicy?.maxInterval)\n : undefined,\n retryPolicyMaxAttempts: options?.retryPolicy?.maxAttempts,\n retryPolicyOnMaxAttempts: (options?.retryPolicy?.onMaxAttempts === \"kill\"\n ? \"KILL\"\n : options?.retryPolicy?.onMaxAttempts === \"pause\"\n ? \"PAUSE\"\n : undefined) as d.RetryPolicyOnMaxAttempts,\n };\n}\n\nfunction commonHandlerOptions(\n wrapper: HandlerWrapper,\n defaultSerde: Serde<any>\n) {\n return {\n input: handlerInputDiscovery(wrapper, defaultSerde),\n output: handlerOutputDiscovery(wrapper, defaultSerde),\n journalRetention:\n wrapper.journalRetention !== undefined\n ? millisOrDurationToMillis(wrapper.journalRetention)\n : undefined,\n idempotencyRetention:\n wrapper.idempotencyRetention !== undefined\n ? millisOrDurationToMillis(wrapper.idempotencyRetention)\n : undefined,\n inactivityTimeout:\n wrapper.inactivityTimeout !== undefined\n ? millisOrDurationToMillis(wrapper.inactivityTimeout)\n : undefined,\n abortTimeout:\n wrapper.abortTimeout !== undefined\n ? millisOrDurationToMillis(wrapper.abortTimeout)\n : undefined,\n ingressPrivate: wrapper.ingressPrivate,\n enableLazyState: wrapper.enableLazyState,\n retryPolicyExponentiationFactor: wrapper.retryPolicy?.exponentiationFactor,\n retryPolicyInitialInterval:\n wrapper.retryPolicy?.initialInterval !== undefined\n ? millisOrDurationToMillis(wrapper.retryPolicy?.initialInterval)\n : undefined,\n retryPolicyMaxInterval:\n wrapper.retryPolicy?.maxInterval !== undefined\n ? millisOrDurationToMillis(wrapper.retryPolicy?.maxInterval)\n : undefined,\n retryPolicyMaxAttempts: wrapper.retryPolicy?.maxAttempts,\n retryPolicyOnMaxAttempts: (wrapper.retryPolicy?.onMaxAttempts === \"kill\"\n ? \"KILL\"\n : wrapper.retryPolicy?.onMaxAttempts === \"pause\"\n ? \"PAUSE\"\n : undefined) as d.RetryPolicyOnMaxAttempts1,\n\n documentation: wrapper.description,\n metadata: wrapper.metadata,\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"components.js","names":["serde","componentName: string","description?: string","metadata?: Record<string, string>","options?: ServiceOptions","ServiceHandler","handlers: d.Handler[]","handlerName: string","handlerWrapper: HandlerWrapper","parent: ServiceComponent","options?: ObjectOptions","parent: VirtualObjectComponent","options?: WorkflowOptions","WorkflowHandler","parent: WorkflowComponent"],"sources":["../../src/endpoint/components.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\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport type * as d from \"./discovery.js\";\nimport type { ContextImpl } from \"../context_impl.js\";\nimport type {\n HandlerWrapper,\n ObjectOptions,\n ServiceHandlerOpts,\n ServiceOptions,\n WorkflowOptions,\n} from \"../types/rpc.js\";\nimport { HandlerKind } from \"../types/rpc.js\";\nimport type { Serde } from \"@restatedev/restate-sdk-core\";\nimport { millisOrDurationToMillis, serde } from \"@restatedev/restate-sdk-core\";\nimport type { HooksProvider } from \"../hooks.js\";\nimport type { TerminalError } from \"../types/errors.js\";\n\n//\n// Interfaces\n//\nexport interface Component {\n name(): string;\n handlerMatching(url: InvokePathComponents): ComponentHandler | undefined;\n discovery(): d.Service;\n}\n\n/**\n * Execution-related options\n */\nexport interface ExecutionOptions {\n asTerminalError?: (error: any) => TerminalError | undefined;\n /**\n * Default serde to use for requests, responses, state, side effects, awakeables, promises. Used when no other serde is specified.\n */\n defaultSerde?: Serde<any>;\n hooks?: HooksProvider[];\n explicitCancellation?: boolean;\n}\n\nexport interface ComponentHandler {\n name(): string;\n component(): Component;\n invoke(context: ContextImpl, input: Uint8Array): Promise<Uint8Array>;\n kind(): HandlerKind;\n\n /**\n * Returns the execution options, already merged with different layers (endpoint -> service -> handler)\n */\n executionOptions: ExecutionOptions;\n}\n\n//\n// Service\n//\n\nfunction handlerInputDiscovery(\n handler: HandlerWrapper,\n defaultSerde: Serde<any>\n): d.InputPayload {\n const serde = handler.options?.input ?? defaultSerde;\n\n let contentType = undefined;\n let jsonSchema = undefined;\n\n if (serde.jsonSchema) {\n jsonSchema = serde.jsonSchema;\n contentType = handler.options?.accept ?? serde.contentType;\n } else if (handler.options?.accept) {\n contentType = handler.options?.accept;\n } else if (serde.contentType) {\n contentType = serde.contentType;\n } else {\n // no input information\n return {};\n }\n\n return {\n required: false,\n contentType,\n jsonSchema,\n };\n}\n\nfunction handlerOutputDiscovery(\n handler: HandlerWrapper,\n defaultSerde: Serde<any>\n): d.OutputPayload {\n const serde = handler.options?.output ?? defaultSerde;\n const setContentTypeIfEmpty =\n handler.options?.setOutputContentTypeIfEmpty ?? false;\n\n let contentType = undefined;\n let jsonSchema = undefined;\n\n if (serde.jsonSchema) {\n jsonSchema = serde.jsonSchema;\n contentType = serde.contentType ?? \"application/json\";\n } else if (serde.contentType) {\n contentType = serde.contentType;\n } else {\n // no input information\n return { setContentTypeIfEmpty };\n }\n\n return {\n setContentTypeIfEmpty,\n jsonSchema,\n contentType,\n };\n}\n\nfunction createExecutionOptions(\n serviceOptions?: ServiceOptions,\n handlerOptions?: ServiceHandlerOpts<unknown, unknown>\n): ExecutionOptions {\n // Service-level hooks run outermost, handler-level hooks run innermost.\n // Both are merged into a single list: service hooks first, then handler hooks.\n const hooks = [\n ...(serviceOptions?.hooks ?? []),\n ...(handlerOptions?.hooks ?? []),\n ];\n return {\n defaultSerde: handlerOptions?.serde ?? serviceOptions?.serde,\n asTerminalError:\n handlerOptions?.asTerminalError ?? serviceOptions?.asTerminalError,\n hooks: hooks.length > 0 ? hooks : undefined,\n explicitCancellation:\n handlerOptions?.explicitCancellation ??\n serviceOptions?.explicitCancellation,\n };\n}\n\nexport class ServiceComponent implements Component {\n private readonly handlers: Map<string, ServiceHandler> = new Map();\n\n constructor(\n private readonly componentName: string,\n public readonly description?: string,\n public readonly metadata?: Record<string, string>,\n public readonly options?: ServiceOptions\n ) {}\n\n name(): string {\n return this.componentName;\n }\n\n add(name: string, handlerWrapper: HandlerWrapper) {\n this.handlers.set(name, new ServiceHandler(name, handlerWrapper, this));\n }\n\n discovery(): d.Service {\n const handlers: d.Handler[] = [...this.handlers.entries()].map(\n ([name, handler]) => {\n return {\n name,\n ...commonHandlerOptions(\n handler.handlerWrapper,\n handler.executionOptions.defaultSerde ?? serde.json\n ),\n } satisfies d.Handler;\n }\n );\n\n return {\n name: this.componentName,\n ty: \"SERVICE\",\n handlers,\n documentation: this.description,\n metadata: this.metadata,\n ...commonServiceOptions(this.options),\n } satisfies d.Service;\n }\n\n handlerMatching(url: InvokePathComponents): ComponentHandler | undefined {\n return this.handlers.get(url.handlerName);\n }\n}\n\nexport class ServiceHandler implements ComponentHandler {\n readonly executionOptions: ExecutionOptions;\n\n constructor(\n private readonly handlerName: string,\n public readonly handlerWrapper: HandlerWrapper,\n private readonly parent: ServiceComponent\n ) {\n this.executionOptions = createExecutionOptions(\n this.parent.options,\n handlerWrapper.options\n );\n }\n\n name(): string {\n return this.handlerName;\n }\n\n component(): Component {\n return this.parent;\n }\n\n kind(): HandlerKind {\n return this.handlerWrapper.kind;\n }\n\n invoke(context: ContextImpl, input: Uint8Array): Promise<Uint8Array> {\n return this.handlerWrapper.invoke(context, input);\n }\n}\n\n//\n// Virtual Object\n//\n\nexport class VirtualObjectComponent implements Component {\n private readonly handlers: Map<string, VirtualObjectHandler> = new Map();\n\n constructor(\n public readonly componentName: string,\n public readonly description?: string,\n public readonly metadata?: Record<string, string>,\n public readonly options?: ObjectOptions\n ) {}\n\n name(): string {\n return this.componentName;\n }\n\n add(name: string, wrapper: HandlerWrapper) {\n this.handlers.set(name, new VirtualObjectHandler(name, wrapper, this));\n }\n\n discovery(): d.Service {\n const handlers: d.Handler[] = [...this.handlers.entries()].map(\n ([name, handler]) => {\n return {\n name,\n ty: handler.kind() === HandlerKind.EXCLUSIVE ? \"EXCLUSIVE\" : \"SHARED\",\n ...commonHandlerOptions(\n handler.handlerWrapper,\n handler.executionOptions.defaultSerde ?? serde.json\n ),\n } satisfies d.Handler;\n }\n );\n\n return {\n name: this.componentName,\n ty: \"VIRTUAL_OBJECT\",\n handlers,\n documentation: this.description,\n metadata: this.metadata,\n ...commonServiceOptions(this.options),\n } satisfies d.Service;\n }\n\n handlerMatching(url: InvokePathComponents): ComponentHandler | undefined {\n return this.handlers.get(url.handlerName);\n }\n}\n\nexport class VirtualObjectHandler implements ComponentHandler {\n readonly executionOptions: ExecutionOptions;\n\n constructor(\n private readonly handlerName: string,\n public readonly handlerWrapper: HandlerWrapper,\n private readonly parent: VirtualObjectComponent\n ) {\n this.executionOptions = createExecutionOptions(\n this.parent.options,\n handlerWrapper.options\n );\n }\n\n name(): string {\n return this.handlerName;\n }\n\n component(): Component {\n return this.parent;\n }\n\n kind(): HandlerKind {\n return this.handlerWrapper.kind;\n }\n\n invoke(context: ContextImpl, input: Uint8Array): Promise<Uint8Array> {\n return this.handlerWrapper.invoke(context, input);\n }\n}\n\n// Workflow\n\nexport class WorkflowComponent implements Component {\n private readonly handlers: Map<string, WorkflowHandler> = new Map();\n\n constructor(\n public readonly componentName: string,\n public readonly description?: string,\n public readonly metadata?: Record<string, string>,\n public readonly options?: WorkflowOptions\n ) {}\n\n name(): string {\n return this.componentName;\n }\n\n add(name: string, wrapper: HandlerWrapper) {\n this.handlers.set(name, new WorkflowHandler(name, wrapper, this));\n }\n\n discovery(): d.Service {\n const handlers: d.Handler[] = [...this.handlers.entries()].map(\n ([name, handler]) => {\n return {\n name,\n ty: handler.kind() === HandlerKind.WORKFLOW ? \"WORKFLOW\" : \"SHARED\",\n workflowCompletionRetention:\n handler.kind() === HandlerKind.WORKFLOW &&\n this.options?.workflowRetention !== undefined\n ? millisOrDurationToMillis(this.options?.workflowRetention)\n : undefined,\n ...commonHandlerOptions(\n handler.handlerWrapper,\n handler.executionOptions.defaultSerde ?? serde.json\n ),\n } satisfies d.Handler;\n }\n );\n\n return {\n name: this.componentName,\n ty: \"WORKFLOW\",\n handlers,\n documentation: this.description,\n metadata: this.metadata,\n ...commonServiceOptions(this.options),\n } satisfies d.Service;\n }\n\n handlerMatching(url: InvokePathComponents): ComponentHandler | undefined {\n return this.handlers.get(url.handlerName);\n }\n}\n\nexport class WorkflowHandler implements ComponentHandler {\n readonly executionOptions: ExecutionOptions;\n\n constructor(\n private readonly handlerName: string,\n public readonly handlerWrapper: HandlerWrapper,\n private readonly parent: WorkflowComponent\n ) {\n this.executionOptions = createExecutionOptions(\n this.parent.options,\n handlerWrapper.options\n );\n }\n\n name(): string {\n return this.handlerName;\n }\n component(): Component {\n return this.parent;\n }\n\n kind(): HandlerKind {\n return this.handlerWrapper.kind;\n }\n\n invoke(context: ContextImpl, input: Uint8Array): Promise<Uint8Array> {\n return this.handlerWrapper.invoke(context, input);\n }\n}\n\nexport type PathComponents =\n | InvokePathComponents\n | { type: \"discover\" }\n | { type: \"health\" }\n | { type: \"unknown\"; path: string };\n\nexport type InvokePathComponents = {\n type: \"invoke\";\n componentName: string;\n handlerName: string;\n};\n\nexport function parseUrlComponents(urlPath?: string): PathComponents {\n if (!urlPath) {\n return { type: \"unknown\", path: \"\" };\n }\n const fragments = urlPath.split(\"/\");\n if (fragments.length >= 3 && fragments[fragments.length - 3] === \"invoke\") {\n return {\n type: \"invoke\",\n componentName: fragments[fragments.length - 2]!,\n handlerName: fragments[fragments.length - 1]!,\n };\n }\n if (fragments.length > 0 && fragments[fragments.length - 1] === \"discover\") {\n return { type: \"discover\" };\n }\n if (fragments.length > 0 && fragments[fragments.length - 1] === \"health\") {\n return { type: \"health\" };\n }\n return { type: \"unknown\", path: urlPath };\n}\n\nfunction commonServiceOptions(\n options?: ServiceOptions | ObjectOptions | WorkflowOptions\n): Partial<d.Service> {\n return {\n journalRetention:\n options?.journalRetention !== undefined\n ? millisOrDurationToMillis(options.journalRetention)\n : undefined,\n idempotencyRetention:\n options?.idempotencyRetention !== undefined\n ? millisOrDurationToMillis(options.idempotencyRetention)\n : undefined,\n inactivityTimeout:\n options?.inactivityTimeout !== undefined\n ? millisOrDurationToMillis(options.inactivityTimeout)\n : undefined,\n abortTimeout:\n options?.abortTimeout !== undefined\n ? millisOrDurationToMillis(options.abortTimeout)\n : undefined,\n ingressPrivate: options?.ingressPrivate,\n enableLazyState:\n options !== undefined && \"enableLazyState\" in options\n ? options.enableLazyState\n : undefined,\n retryPolicyExponentiationFactor: options?.retryPolicy?.exponentiationFactor,\n retryPolicyInitialInterval:\n options?.retryPolicy?.initialInterval !== undefined\n ? millisOrDurationToMillis(options?.retryPolicy?.initialInterval)\n : undefined,\n retryPolicyMaxInterval:\n options?.retryPolicy?.maxInterval !== undefined\n ? millisOrDurationToMillis(options?.retryPolicy?.maxInterval)\n : undefined,\n retryPolicyMaxAttempts: options?.retryPolicy?.maxAttempts,\n retryPolicyOnMaxAttempts: (options?.retryPolicy?.onMaxAttempts === \"kill\"\n ? \"KILL\"\n : options?.retryPolicy?.onMaxAttempts === \"pause\"\n ? \"PAUSE\"\n : undefined) as d.RetryPolicyOnMaxAttempts,\n };\n}\n\nfunction commonHandlerOptions(\n wrapper: HandlerWrapper,\n defaultSerde: Serde<any>\n) {\n return {\n input: handlerInputDiscovery(wrapper, defaultSerde),\n output: handlerOutputDiscovery(wrapper, defaultSerde),\n journalRetention:\n wrapper.options?.journalRetention !== undefined\n ? millisOrDurationToMillis(wrapper.options?.journalRetention)\n : undefined,\n idempotencyRetention:\n wrapper.options?.idempotencyRetention !== undefined\n ? millisOrDurationToMillis(wrapper.options?.idempotencyRetention)\n : undefined,\n inactivityTimeout:\n wrapper.options?.inactivityTimeout !== undefined\n ? millisOrDurationToMillis(wrapper.options?.inactivityTimeout)\n : undefined,\n abortTimeout:\n wrapper.options?.abortTimeout !== undefined\n ? millisOrDurationToMillis(wrapper.options?.abortTimeout)\n : undefined,\n ingressPrivate: wrapper.options?.ingressPrivate,\n enableLazyState:\n wrapper.options !== undefined && \"enableLazyState\" in wrapper.options\n ? wrapper.options?.enableLazyState\n : undefined,\n retryPolicyExponentiationFactor:\n wrapper.options?.retryPolicy?.exponentiationFactor,\n retryPolicyInitialInterval:\n wrapper.options?.retryPolicy?.initialInterval !== undefined\n ? millisOrDurationToMillis(\n wrapper.options?.retryPolicy?.initialInterval\n )\n : undefined,\n retryPolicyMaxInterval:\n wrapper.options?.retryPolicy?.maxInterval !== undefined\n ? millisOrDurationToMillis(wrapper.options?.retryPolicy?.maxInterval)\n : undefined,\n retryPolicyMaxAttempts: wrapper.options?.retryPolicy?.maxAttempts,\n retryPolicyOnMaxAttempts: (wrapper.options?.retryPolicy?.onMaxAttempts ===\n \"kill\"\n ? \"KILL\"\n : wrapper.options?.retryPolicy?.onMaxAttempts === \"pause\"\n ? \"PAUSE\"\n : undefined) as d.RetryPolicyOnMaxAttempts1,\n\n documentation: wrapper.options?.description,\n metadata: wrapper.options?.metadata,\n };\n}\n"],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
const require_logger_transport = require('../logging/logger_transport.cjs');
|
|
2
|
-
const require_console_logger_transport = require('../logging/console_logger_transport.cjs');
|
|
3
1
|
const require_rpc = require('../types/rpc.cjs');
|
|
4
2
|
const require_components = require('./components.cjs');
|
|
3
|
+
const require_logger_transport = require('../logging/logger_transport.cjs');
|
|
4
|
+
const require_console_logger_transport = require('../logging/console_logger_transport.cjs');
|
|
5
5
|
const require_logger = require('../logging/logger.cjs');
|
|
6
6
|
|
|
7
7
|
//#region src/endpoint/endpoint.ts
|
|
@@ -1,39 +1,5 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
import type { DefaultServiceOptions } from "../endpoint.js";
|
|
7
|
-
export type Endpoint = {
|
|
8
|
-
loggerTransport: LoggerTransport;
|
|
9
|
-
components: Map<string, Component>;
|
|
10
|
-
keySet: string[];
|
|
11
|
-
/**
|
|
12
|
-
* This is a simple console without contextual info.
|
|
13
|
-
*
|
|
14
|
-
* This should be used only in cases where no contextual info is available.
|
|
15
|
-
*/
|
|
16
|
-
rlog: Logger;
|
|
17
|
-
/**
|
|
18
|
-
* All discovery metadata, except protocol mode provided by the node/fetch/lambda endpoint implementations
|
|
19
|
-
*/
|
|
20
|
-
discoveryMetadata: Omit<discovery.Endpoint, "protocolMode">;
|
|
21
|
-
/**
|
|
22
|
-
* Codec provider to use for journal values.
|
|
23
|
-
*/
|
|
24
|
-
journalValueCodec?: Promise<JournalValueCodec>;
|
|
25
|
-
};
|
|
26
|
-
export declare class EndpointBuilder {
|
|
27
|
-
private readonly serviceDefinitions;
|
|
28
|
-
private loggerTransport;
|
|
29
|
-
private keySet;
|
|
30
|
-
private defaultServiceOptions;
|
|
31
|
-
private journalValueCodecProvider?;
|
|
32
|
-
bind<P extends string, M>(definition: ServiceDefinition<P, M> | VirtualObjectDefinition<P, M> | WorkflowDefinition<P, M>): void;
|
|
33
|
-
addIdentityKeys(...keys: string[]): void;
|
|
34
|
-
setDefaultServiceOptions(options: DefaultServiceOptions): void;
|
|
35
|
-
setLogger(newLogger: LoggerTransport): void;
|
|
36
|
-
setJournalValueCodecProvider(codecProvider: () => Promise<JournalValueCodec>): void;
|
|
37
|
-
build(): Endpoint;
|
|
38
|
-
}
|
|
39
|
-
//# sourceMappingURL=endpoint.d.ts.map
|
|
1
|
+
import "./components.js";
|
|
2
|
+
import "../logging/logger_transport.js";
|
|
3
|
+
import "../logging/logger.js";
|
|
4
|
+
import "../endpoint.js";
|
|
5
|
+
import { JournalValueCodec, ServiceDefinition, VirtualObjectDefinition, WorkflowDefinition } from "@restatedev/restate-sdk-core";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { LogSource } from "../logging/logger_transport.js";
|
|
2
|
-
import { defaultLoggerTransport } from "../logging/console_logger_transport.js";
|
|
3
1
|
import { HandlerWrapper } from "../types/rpc.js";
|
|
4
2
|
import { ServiceComponent, VirtualObjectComponent, WorkflowComponent } from "./components.js";
|
|
3
|
+
import { LogSource } from "../logging/logger_transport.js";
|
|
4
|
+
import { defaultLoggerTransport } from "../logging/console_logger_transport.js";
|
|
5
5
|
import { createLogger } from "../logging/logger.js";
|
|
6
6
|
|
|
7
7
|
//#region src/endpoint/endpoint.ts
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"endpoint.js","names":["name"],"sources":["../../src/endpoint/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\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport type {\n JournalValueCodec,\n ServiceDefinition,\n VirtualObjectDefinition,\n WorkflowDefinition,\n} from \"@restatedev/restate-sdk-core\";\n\nimport type {\n ObjectOptions,\n ServiceOptions,\n WorkflowOptions,\n} from \"../types/rpc.js\";\nimport { HandlerWrapper } from \"../types/rpc.js\";\nimport type { Component } from \"./components.js\";\nimport {\n ServiceComponent,\n VirtualObjectComponent,\n WorkflowComponent,\n} from \"./components.js\";\nimport type * as discovery from \"./discovery.js\";\nimport { defaultLoggerTransport } from \"../logging/console_logger_transport.js\";\nimport {\n type LoggerTransport,\n LogSource,\n} from \"../logging/logger_transport.js\";\nimport type { Logger } from \"../logging/logger.js\";\nimport { createLogger } from \"../logging/logger.js\";\nimport type { DefaultServiceOptions } from \"../endpoint.js\";\n\nfunction isServiceDefinition<P extends string, M>(\n m: Record<string, any>\n): m is ServiceDefinition<P, M> & { service: M } {\n return m && m.service !== undefined;\n}\n\nfunction isObjectDefinition<P extends string, M>(\n m: Record<string, any>\n): m is VirtualObjectDefinition<P, M> & { object: M } {\n return m && m.object !== undefined;\n}\n\nfunction isWorkflowDefinition<P extends string, M>(\n m: Record<string, any>\n): m is WorkflowDefinition<P, M> & { workflow: M } {\n return m && m.workflow !== undefined;\n}\n\n/**\n * Services can have additional information that is not part of the definition.\n * For example a description or metadata.\n */\ntype ServiceAuxInfo = {\n description?: string;\n metadata?: Record<string, any>;\n options?: ServiceOptions | ObjectOptions | WorkflowOptions;\n};\n\nexport type Endpoint = {\n loggerTransport: LoggerTransport;\n components: Map<string, Component>;\n keySet: string[];\n /**\n * This is a simple console without contextual info.\n *\n * This should be used only in cases where no contextual info is available.\n */\n rlog: Logger;\n /**\n * All discovery metadata, except protocol mode provided by the node/fetch/lambda endpoint implementations\n */\n discoveryMetadata: Omit<discovery.Endpoint, \"protocolMode\">;\n\n /**\n * Codec provider to use for journal values.\n */\n journalValueCodec?: Promise<JournalValueCodec>;\n};\n\nexport class EndpointBuilder {\n private readonly serviceDefinitions: Map<\n string,\n | ServiceDefinition<string, any>\n | VirtualObjectDefinition<string, any>\n | WorkflowDefinition<string, any>\n > = new Map();\n private loggerTransport: LoggerTransport = defaultLoggerTransport;\n private keySet: string[] = [];\n private defaultServiceOptions: DefaultServiceOptions = {};\n private journalValueCodecProvider?: () => Promise<JournalValueCodec>;\n\n public bind<P extends string, M>(\n definition:\n | ServiceDefinition<P, M>\n | VirtualObjectDefinition<P, M>\n | WorkflowDefinition<P, M>\n ) {\n // Validate service name\n if (definition.name.indexOf(\"/\") !== -1) {\n throw new Error(\"service name must not contain any slash '/'\");\n }\n\n this.serviceDefinitions.set(definition.name, definition);\n }\n\n public addIdentityKeys(...keys: string[]) {\n this.keySet.push(...keys);\n }\n\n public setDefaultServiceOptions(options: DefaultServiceOptions) {\n this.defaultServiceOptions = options;\n }\n\n public setLogger(newLogger: LoggerTransport) {\n this.loggerTransport = newLogger;\n }\n\n public setJournalValueCodecProvider(\n codecProvider: () => Promise<JournalValueCodec>\n ) {\n this.journalValueCodecProvider = codecProvider;\n }\n\n public build(): Endpoint {\n const rlog = createLogger(this.loggerTransport, LogSource.SYSTEM);\n\n // Build the components\n const components = new Map<string, Component>();\n for (const [name, definition] of this.serviceDefinitions) {\n if (isServiceDefinition(definition)) {\n const { name, service } = definition;\n if (!service) {\n throw new TypeError(`no service implementation found.`);\n }\n components.set(\n name,\n buildServiceComponent(\n name,\n service,\n definition as ServiceAuxInfo,\n this.defaultServiceOptions\n )\n );\n } else if (isObjectDefinition(definition)) {\n const { name, object } = definition;\n if (!object) {\n throw new TypeError(`no object implementation found.`);\n }\n components.set(\n name,\n buildVirtualObjectComponent(\n name,\n object,\n definition as ServiceAuxInfo,\n this.defaultServiceOptions\n )\n );\n } else if (isWorkflowDefinition(definition)) {\n const { name, workflow } = definition;\n if (!workflow) {\n throw new TypeError(`no workflow implementation found.`);\n }\n components.set(\n name,\n buildWorkflowComponent(\n name,\n workflow,\n definition as ServiceAuxInfo,\n this.defaultServiceOptions\n )\n );\n } else {\n throw new TypeError(\n `cannot bind ${name}, can only bind a service or a virtual object or a workflow definition`\n );\n }\n }\n\n // Compute discovery metadata\n const discoveryMetadata = computeDiscovery(components);\n\n return {\n keySet: this.keySet,\n loggerTransport: this.loggerTransport,\n rlog,\n components,\n discoveryMetadata,\n journalValueCodec: this.journalValueCodecProvider\n ? this.journalValueCodecProvider()\n : undefined,\n };\n }\n}\n\nfunction computeDiscovery(\n components: Map<string, Component>\n): discovery.Endpoint {\n return {\n minProtocolVersion: 5,\n maxProtocolVersion: 6,\n services: [...components.values()].map((c) => c.discovery()),\n };\n}\n\nfunction buildServiceComponent(\n name: string,\n router: any,\n definition: ServiceAuxInfo,\n defaultServiceOptions: DefaultServiceOptions\n): ServiceComponent {\n if (name.indexOf(\"/\") !== -1) {\n throw new Error(\"service name must not contain any slash '/'\");\n }\n const component = new ServiceComponent(\n name,\n definition.description,\n definition.metadata,\n {\n ...defaultServiceOptions,\n ...(definition?.options as ServiceOptions),\n }\n );\n\n for (const [route, handler] of Object.entries(\n router as { [s: string]: any }\n )) {\n const wrapper = HandlerWrapper.fromHandler(handler);\n if (!wrapper) {\n throw new TypeError(`${route} is not a restate handler.`);\n }\n wrapper.bindInstance(router);\n component.add(route, wrapper);\n }\n\n return component;\n}\n\nfunction buildVirtualObjectComponent(\n name: string,\n router: any,\n definition: ServiceAuxInfo,\n defaultServiceOptions: DefaultServiceOptions\n): VirtualObjectComponent {\n if (name.indexOf(\"/\") !== -1) {\n throw new Error(\"service name must not contain any slash '/'\");\n }\n const component = new VirtualObjectComponent(\n name,\n definition.description,\n definition.metadata,\n {\n ...defaultServiceOptions,\n ...(definition?.options as ObjectOptions),\n }\n );\n\n for (const [route, handler] of Object.entries(\n router as { [s: string]: any }\n )) {\n const wrapper = HandlerWrapper.fromHandler(handler);\n if (!wrapper) {\n throw new TypeError(`${route} is not a restate handler.`);\n }\n wrapper.bindInstance(router);\n component.add(route, wrapper);\n }\n return component;\n}\n\nfunction buildWorkflowComponent(\n name: string,\n workflow: any,\n definition: ServiceAuxInfo,\n defaultServiceOptions: DefaultServiceOptions\n): WorkflowComponent {\n if (name.indexOf(\"/\") !== -1) {\n throw new Error(\"service name must not contain any slash '/'\");\n }\n const component = new WorkflowComponent(\n name,\n definition.description,\n definition.metadata,\n {\n ...defaultServiceOptions,\n ...(definition?.options as WorkflowOptions),\n }\n );\n\n for (const [route, handler] of Object.entries(\n workflow as { [s: string]: any }\n )) {\n const wrapper = HandlerWrapper.fromHandler(handler);\n if (!wrapper) {\n throw new TypeError(`${route} is not a restate handler.`);\n }\n wrapper.bindInstance(workflow);\n component.add(route, wrapper);\n }\n return component;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"endpoint.js","names":["name"],"sources":["../../src/endpoint/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\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport type {\n JournalValueCodec,\n ServiceDefinition,\n VirtualObjectDefinition,\n WorkflowDefinition,\n} from \"@restatedev/restate-sdk-core\";\n\nimport type {\n ObjectOptions,\n ServiceOptions,\n WorkflowOptions,\n} from \"../types/rpc.js\";\nimport { HandlerWrapper } from \"../types/rpc.js\";\nimport type { Component } from \"./components.js\";\nimport {\n ServiceComponent,\n VirtualObjectComponent,\n WorkflowComponent,\n} from \"./components.js\";\nimport type * as discovery from \"./discovery.js\";\nimport { defaultLoggerTransport } from \"../logging/console_logger_transport.js\";\nimport {\n type LoggerTransport,\n LogSource,\n} from \"../logging/logger_transport.js\";\nimport type { Logger } from \"../logging/logger.js\";\nimport { createLogger } from \"../logging/logger.js\";\nimport type { DefaultServiceOptions } from \"../endpoint.js\";\n\nfunction isServiceDefinition<P extends string, M>(\n m: Record<string, any>\n): m is ServiceDefinition<P, M> & { service: M } {\n return m && m.service !== undefined;\n}\n\nfunction isObjectDefinition<P extends string, M>(\n m: Record<string, any>\n): m is VirtualObjectDefinition<P, M> & { object: M } {\n return m && m.object !== undefined;\n}\n\nfunction isWorkflowDefinition<P extends string, M>(\n m: Record<string, any>\n): m is WorkflowDefinition<P, M> & { workflow: M } {\n return m && m.workflow !== undefined;\n}\n\n/**\n * Services can have additional information that is not part of the definition.\n * For example a description or metadata.\n */\ntype ServiceAuxInfo = {\n description?: string;\n metadata?: Record<string, any>;\n options?: ServiceOptions | ObjectOptions | WorkflowOptions;\n};\n\nexport type Endpoint = {\n loggerTransport: LoggerTransport;\n components: Map<string, Component>;\n keySet: string[];\n /**\n * This is a simple console without contextual info.\n *\n * This should be used only in cases where no contextual info is available.\n */\n rlog: Logger;\n /**\n * All discovery metadata, except protocol mode provided by the node/fetch/lambda endpoint implementations\n */\n discoveryMetadata: Omit<discovery.Endpoint, \"protocolMode\">;\n\n /**\n * Codec provider to use for journal values.\n */\n journalValueCodec?: Promise<JournalValueCodec>;\n};\n\nexport class EndpointBuilder {\n private readonly serviceDefinitions: Map<\n string,\n | ServiceDefinition<string, any>\n | VirtualObjectDefinition<string, any>\n | WorkflowDefinition<string, any>\n > = new Map();\n private loggerTransport: LoggerTransport = defaultLoggerTransport;\n private keySet: string[] = [];\n private defaultServiceOptions: DefaultServiceOptions = {};\n private journalValueCodecProvider?: () => Promise<JournalValueCodec>;\n\n public bind<P extends string, M>(\n definition:\n | ServiceDefinition<P, M>\n | VirtualObjectDefinition<P, M>\n | WorkflowDefinition<P, M>\n ) {\n // Validate service name\n if (definition.name.indexOf(\"/\") !== -1) {\n throw new Error(\"service name must not contain any slash '/'\");\n }\n\n this.serviceDefinitions.set(definition.name, definition);\n }\n\n public addIdentityKeys(...keys: string[]) {\n this.keySet.push(...keys);\n }\n\n public setDefaultServiceOptions(options: DefaultServiceOptions) {\n this.defaultServiceOptions = options;\n }\n\n public setLogger(newLogger: LoggerTransport) {\n this.loggerTransport = newLogger;\n }\n\n public setJournalValueCodecProvider(\n codecProvider: () => Promise<JournalValueCodec>\n ) {\n this.journalValueCodecProvider = codecProvider;\n }\n\n public build(): Endpoint {\n const rlog = createLogger(this.loggerTransport, LogSource.SYSTEM);\n\n // Build the components\n const components = new Map<string, Component>();\n for (const [name, definition] of this.serviceDefinitions) {\n if (isServiceDefinition(definition)) {\n const { name, service } = definition;\n if (!service) {\n throw new TypeError(`no service implementation found.`);\n }\n components.set(\n name,\n buildServiceComponent(\n name,\n service,\n definition as ServiceAuxInfo,\n this.defaultServiceOptions\n )\n );\n } else if (isObjectDefinition(definition)) {\n const { name, object } = definition;\n if (!object) {\n throw new TypeError(`no object implementation found.`);\n }\n components.set(\n name,\n buildVirtualObjectComponent(\n name,\n object,\n definition as ServiceAuxInfo,\n this.defaultServiceOptions\n )\n );\n } else if (isWorkflowDefinition(definition)) {\n const { name, workflow } = definition;\n if (!workflow) {\n throw new TypeError(`no workflow implementation found.`);\n }\n components.set(\n name,\n buildWorkflowComponent(\n name,\n workflow,\n definition as ServiceAuxInfo,\n this.defaultServiceOptions\n )\n );\n } else {\n throw new TypeError(\n `cannot bind ${name}, can only bind a service or a virtual object or a workflow definition`\n );\n }\n }\n\n // Compute discovery metadata\n const discoveryMetadata = computeDiscovery(components);\n\n return {\n keySet: this.keySet,\n loggerTransport: this.loggerTransport,\n rlog,\n components,\n discoveryMetadata,\n journalValueCodec: this.journalValueCodecProvider\n ? this.journalValueCodecProvider()\n : undefined,\n };\n }\n}\n\nfunction computeDiscovery(\n components: Map<string, Component>\n): discovery.Endpoint {\n return {\n minProtocolVersion: 5,\n maxProtocolVersion: 6,\n services: [...components.values()].map((c) => c.discovery()),\n };\n}\n\nfunction buildServiceComponent(\n name: string,\n router: any,\n definition: ServiceAuxInfo,\n defaultServiceOptions: DefaultServiceOptions\n): ServiceComponent {\n if (name.indexOf(\"/\") !== -1) {\n throw new Error(\"service name must not contain any slash '/'\");\n }\n const component = new ServiceComponent(\n name,\n definition.description,\n definition.metadata,\n {\n ...defaultServiceOptions,\n ...(definition?.options as ServiceOptions | undefined),\n }\n );\n\n for (const [route, handler] of Object.entries(\n router as { [s: string]: any }\n )) {\n const wrapper = HandlerWrapper.fromHandler(handler);\n if (!wrapper) {\n throw new TypeError(`${route} is not a restate handler.`);\n }\n wrapper.bindInstance(router);\n component.add(route, wrapper);\n }\n\n return component;\n}\n\nfunction buildVirtualObjectComponent(\n name: string,\n router: any,\n definition: ServiceAuxInfo,\n defaultServiceOptions: DefaultServiceOptions\n): VirtualObjectComponent {\n if (name.indexOf(\"/\") !== -1) {\n throw new Error(\"service name must not contain any slash '/'\");\n }\n const component = new VirtualObjectComponent(\n name,\n definition.description,\n definition.metadata,\n {\n ...defaultServiceOptions,\n ...(definition?.options as ObjectOptions | undefined),\n }\n );\n\n for (const [route, handler] of Object.entries(\n router as { [s: string]: any }\n )) {\n const wrapper = HandlerWrapper.fromHandler(handler);\n if (!wrapper) {\n throw new TypeError(`${route} is not a restate handler.`);\n }\n wrapper.bindInstance(router);\n component.add(route, wrapper);\n }\n return component;\n}\n\nfunction buildWorkflowComponent(\n name: string,\n workflow: any,\n definition: ServiceAuxInfo,\n defaultServiceOptions: DefaultServiceOptions\n): WorkflowComponent {\n if (name.indexOf(\"/\") !== -1) {\n throw new Error(\"service name must not contain any slash '/'\");\n }\n const component = new WorkflowComponent(\n name,\n definition.description,\n definition.metadata,\n {\n ...defaultServiceOptions,\n ...(definition?.options as WorkflowOptions | undefined),\n }\n );\n\n for (const [route, handler] of Object.entries(\n workflow as { [s: string]: any }\n )) {\n const wrapper = HandlerWrapper.fromHandler(handler);\n if (!wrapper) {\n throw new TypeError(`${route} is not a restate handler.`);\n }\n wrapper.bindInstance(workflow);\n component.add(route, wrapper);\n }\n return component;\n}\n"],"mappings":"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"}
|
|
@@ -1,21 +1,23 @@
|
|
|
1
1
|
const require_rolldown_runtime = require('../../_virtual/rolldown_runtime.cjs');
|
|
2
|
-
const require_logger_transport = require('../../logging/logger_transport.cjs');
|
|
3
|
-
const require_console_logger_transport = require('../../logging/console_logger_transport.cjs');
|
|
4
|
-
const require_core_logging = require('./core_logging.cjs');
|
|
5
|
-
const require_sdk_shared_core_wasm_bindings = require('./vm/sdk_shared_core_wasm_bindings.cjs');
|
|
6
2
|
const require_errors = require('../../types/errors.cjs');
|
|
7
|
-
const require_rpc = require('../../types/rpc.cjs');
|
|
8
3
|
const require_completable_promise = require('../../utils/completable_promise.cjs');
|
|
9
|
-
const
|
|
4
|
+
const require_rpc = require('../../types/rpc.cjs');
|
|
10
5
|
const require_components = require('../components.cjs');
|
|
6
|
+
const require_logger_transport = require('../../logging/logger_transport.cjs');
|
|
7
|
+
const require_console_logger_transport = require('../../logging/console_logger_transport.cjs');
|
|
11
8
|
const require_logger = require('../../logging/logger.cjs');
|
|
12
9
|
const require_user_agent = require('../../user_agent.cjs');
|
|
10
|
+
const require_core_logging = require('./core_logging.cjs');
|
|
11
|
+
const require_sdk_shared_core_wasm_bindings = require('./vm/sdk_shared_core_wasm_bindings.cjs');
|
|
12
|
+
const require_context_impl = require('../../context_impl.cjs');
|
|
13
|
+
const require_error_sanitization = require('../../error_sanitization.cjs');
|
|
13
14
|
const require_utils = require('./utils.cjs');
|
|
14
15
|
const require_discovery = require('./discovery.cjs');
|
|
15
16
|
let __restatedev_restate_sdk_core = require("@restatedev/restate-sdk-core");
|
|
16
17
|
__restatedev_restate_sdk_core = require_rolldown_runtime.__toESM(__restatedev_restate_sdk_core);
|
|
17
18
|
|
|
18
19
|
//#region src/endpoint/handlers/generic.ts
|
|
20
|
+
const HOOK_CONTEXT_IS_PROCESSING_SYMBOL = Symbol.for("@restatedev/restate-sdk/hooks.isProcessing");
|
|
19
21
|
function createRestateHandler(endpoint, protocolMode, additionalDiscoveryFields) {
|
|
20
22
|
return new RestateHandlerImpl(endpoint, protocolMode, additionalDiscoveryFields);
|
|
21
23
|
}
|
|
@@ -110,7 +112,7 @@ var RestateInvokeResponse = class {
|
|
|
110
112
|
this.loggerId = Math.floor(Math.random() * 4294967295);
|
|
111
113
|
const isJournalCodecDefined = this.journalValueCodecInit !== void 0;
|
|
112
114
|
const vmHeaders = Object.entries(this.attemptHeaders).filter(([, v]) => v !== void 0).map(([k, v]) => new require_sdk_shared_core_wasm_bindings.WasmHeader(k, v instanceof Array ? v[0] : v));
|
|
113
|
-
this.coreVm = new require_sdk_shared_core_wasm_bindings.WasmVM(vmHeaders, restateLogLevelToWasmLogLevel(require_console_logger_transport.DEFAULT_CONSOLE_LOGGER_LOG_LEVEL), this.loggerId, isJournalCodecDefined);
|
|
115
|
+
this.coreVm = new require_sdk_shared_core_wasm_bindings.WasmVM(vmHeaders, restateLogLevelToWasmLogLevel(require_console_logger_transport.DEFAULT_CONSOLE_LOGGER_LOG_LEVEL), this.loggerId, isJournalCodecDefined, handler.executionOptions.explicitCancellation ?? false);
|
|
114
116
|
const responseHead = this.coreVm.get_response_head();
|
|
115
117
|
this.statusCode = responseHead.status_code;
|
|
116
118
|
this.headers = responseHead.headers.reduce((headers, { key, value }) => ({
|
|
@@ -122,6 +124,10 @@ var RestateInvokeResponse = class {
|
|
|
122
124
|
async process({ inputReader, outputWriter, abortSignal }) {
|
|
123
125
|
abortSignal.addEventListener("abort", () => {
|
|
124
126
|
require_core_logging.destroyLogger(this.loggerId);
|
|
127
|
+
setImmediate(() => {
|
|
128
|
+
const msg = "Connection closed";
|
|
129
|
+
this.coreVm.notify_error(msg, msg);
|
|
130
|
+
});
|
|
125
131
|
}, { once: true });
|
|
126
132
|
require_core_logging.registerLogger(this.loggerId, this.vmLogger);
|
|
127
133
|
const journalValueCodec = this.journalValueCodecInit ? await this.journalValueCodecInit : {
|
|
@@ -134,6 +140,14 @@ var RestateInvokeResponse = class {
|
|
|
134
140
|
await bufferJournalReplayInCoreVm(this.coreVm, inputReader);
|
|
135
141
|
const input = this.coreVm.sys_input();
|
|
136
142
|
const invocationRequest = {
|
|
143
|
+
target: {
|
|
144
|
+
service: this.service.name(),
|
|
145
|
+
handler: this.handler.name(),
|
|
146
|
+
key: input.key || void 0,
|
|
147
|
+
toString() {
|
|
148
|
+
return this.key !== void 0 ? `${this.service}/${this.key}/${this.handler}` : `${this.service}/${this.handler}`;
|
|
149
|
+
}
|
|
150
|
+
},
|
|
137
151
|
id: input.invocation_id,
|
|
138
152
|
headers: input.headers.reduce((headers, { key, value }) => {
|
|
139
153
|
headers.set(key, value);
|
|
@@ -153,18 +167,20 @@ var RestateInvokeResponse = class {
|
|
|
153
167
|
require_core_logging.registerLogger(this.loggerId, this.vmLogger);
|
|
154
168
|
if (!this.coreVm.is_processing()) this.vmLogger.info("Replaying invocation.");
|
|
155
169
|
else this.vmLogger.info("Starting invocation.");
|
|
156
|
-
ctx = new require_context_impl.ContextImpl(this.coreVm, input, ctxLogger, this.handler.kind(), this.vmLogger, invocationRequest, invocationEndPromise, inputReader, outputWriter, journalValueCodec, this.
|
|
170
|
+
ctx = new require_context_impl.ContextImpl(this.coreVm, input, ctxLogger, this.handler.kind(), this.vmLogger, invocationRequest, invocationEndPromise, inputReader, outputWriter, journalValueCodec, this.handler.executionOptions);
|
|
157
171
|
} catch (e) {
|
|
158
172
|
const error = require_errors.ensureError(e);
|
|
159
173
|
this.coreVm.notify_error(error.message, error.message);
|
|
160
174
|
await flushAndClose(this.coreVm, this.vmLogger, inputReader, outputWriter);
|
|
161
175
|
return;
|
|
162
176
|
}
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
})
|
|
166
|
-
|
|
167
|
-
|
|
177
|
+
try {
|
|
178
|
+
await startUserHandler(ctx, this.service, this.handler, journalValueCodec);
|
|
179
|
+
} catch (e) {
|
|
180
|
+
notifyError(e, ctx, this.handler.executionOptions.asTerminalError);
|
|
181
|
+
} finally {
|
|
182
|
+
await flushAndClose(this.coreVm, this.vmLogger, inputReader, outputWriter);
|
|
183
|
+
}
|
|
168
184
|
}
|
|
169
185
|
};
|
|
170
186
|
async function bufferJournalReplayInCoreVm(coreVm, inputReader) {
|
|
@@ -178,35 +194,57 @@ async function bufferJournalReplayInCoreVm(coreVm, inputReader) {
|
|
|
178
194
|
}
|
|
179
195
|
}
|
|
180
196
|
async function startUserHandler(ctx, service, handler, journalValueCodec) {
|
|
197
|
+
const hooks = [];
|
|
198
|
+
for (const provider of handler.executionOptions.hooks ?? []) {
|
|
199
|
+
const hookContext = { request: ctx.request() };
|
|
200
|
+
Object.defineProperty(hookContext, HOOK_CONTEXT_IS_PROCESSING_SYMBOL, {
|
|
201
|
+
value: () => ctx.isProcessing(),
|
|
202
|
+
enumerable: false
|
|
203
|
+
});
|
|
204
|
+
hooks.push(provider(hookContext));
|
|
205
|
+
}
|
|
206
|
+
const handlerInterceptor = composeInterceptors(hooks.map((h) => h.interceptor?.handler).filter(isDefined));
|
|
207
|
+
ctx.setRunInterceptor(composeInterceptors(hooks.map((h) => h.interceptor?.run).filter(isDefined)));
|
|
208
|
+
let encodedOutput;
|
|
209
|
+
await raceWithAttemptEnd(ctx, handlerInterceptor)(async () => {
|
|
210
|
+
const decodedInput = await journalValueCodec.decode(ctx.request().body).catch((e) => Promise.reject(new require_errors.TerminalError(`Failed to decode input using journal value codec: ${require_errors.ensureError(e).message}`, { errorCode: 400 })));
|
|
211
|
+
const output = await handler.invoke(ctx, decodedInput);
|
|
212
|
+
encodedOutput = journalValueCodec.encode(output);
|
|
213
|
+
});
|
|
214
|
+
ctx.coreVm.sys_write_output_success(encodedOutput);
|
|
215
|
+
ctx.coreVm.sys_end();
|
|
216
|
+
ctx.vmLogger.info("Invocation completed successfully.");
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Classifies the error and notifies the VM. Called from the process() catch
|
|
220
|
+
* block — the single place that decides how to report errors to the VM.
|
|
221
|
+
*/
|
|
222
|
+
function notifyError(e, ctx, asTerminalError) {
|
|
223
|
+
if (e instanceof require_context_impl.CommandError) {
|
|
224
|
+
const cause = require_errors.ensureError(e.cause);
|
|
225
|
+
require_errors.logError(ctx.vmLogger, cause);
|
|
226
|
+
if (e.hasCommandIndex) ctx.coreVm.notify_error_for_specific_command(cause.message, cause.stack, e.commandType, e.commandIndex, null);
|
|
227
|
+
else ctx.coreVm.notify_error_for_next_command(cause.message, cause.stack, e.commandType);
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
const error = require_errors.ensureError(e, asTerminalError);
|
|
231
|
+
require_errors.logError(ctx.vmLogger, error);
|
|
181
232
|
try {
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
233
|
+
if (error instanceof require_errors.TerminalError) {
|
|
234
|
+
ctx.coreVm.sys_write_output_failure({
|
|
235
|
+
code: error.code,
|
|
236
|
+
message: error.message,
|
|
237
|
+
metadata: Object.entries(error.metadata ?? {}).map(([key, value]) => ({
|
|
238
|
+
key,
|
|
239
|
+
value
|
|
240
|
+
}))
|
|
241
|
+
});
|
|
187
242
|
ctx.coreVm.sys_end();
|
|
188
|
-
|
|
189
|
-
} catch (e) {
|
|
190
|
-
const error = require_errors.ensureError(e, service.options?.asTerminalError);
|
|
191
|
-
require_errors.logError(ctx.vmLogger, error);
|
|
192
|
-
if (error instanceof require_errors.TerminalError) {
|
|
193
|
-
ctx.coreVm.sys_write_output_failure({
|
|
194
|
-
code: error.code,
|
|
195
|
-
message: error.message,
|
|
196
|
-
metadata: Object.entries(error.metadata ?? {}).map(([key, value]) => ({
|
|
197
|
-
key,
|
|
198
|
-
value
|
|
199
|
-
}))
|
|
200
|
-
});
|
|
201
|
-
ctx.coreVm.sys_end();
|
|
202
|
-
return;
|
|
203
|
-
}
|
|
204
|
-
throw error;
|
|
205
|
-
}
|
|
206
|
-
} catch (e) {
|
|
207
|
-
const error = require_errors.ensureError(e);
|
|
208
|
-
if (error instanceof require_errors.RetryableError) ctx.coreVm.notify_error_with_delay_override(error.message, error.stack, error.retryAfter !== void 0 ? BigInt((0, __restatedev_restate_sdk_core.millisOrDurationToMillis)(error.retryAfter)) : void 0);
|
|
243
|
+
} else if (error instanceof require_errors.RetryableError) ctx.coreVm.notify_error_with_delay_override(error.message, error.stack, error.retryAfter !== void 0 ? BigInt((0, __restatedev_restate_sdk_core.millisOrDurationToMillis)(error.retryAfter)) : void 0);
|
|
209
244
|
else ctx.coreVm.notify_error(error.message, error.stack);
|
|
245
|
+
} catch (vmError) {
|
|
246
|
+
const inner = require_errors.ensureError(vmError);
|
|
247
|
+
ctx.coreVm.notify_error(inner.message, inner.stack);
|
|
210
248
|
}
|
|
211
249
|
}
|
|
212
250
|
async function flushAndClose(coreVm, vmLogger, inputReader, outputWriter) {
|
|
@@ -234,6 +272,42 @@ async function flushAndClose(coreVm, vmLogger, inputReader, outputWriter) {
|
|
|
234
272
|
function isAbortErrorOnWrite(error) {
|
|
235
273
|
return error.name === "AbortError" || error.message === "Invalid state: WritableStream is closed" || error.code === "ERR_HTTP2_INVALID_STREAM";
|
|
236
274
|
}
|
|
275
|
+
function composeInterceptors(interceptors) {
|
|
276
|
+
return interceptors.reduceRight((innerInterceptor, interceptor) => (...args) => {
|
|
277
|
+
const context = args.slice(0, -1);
|
|
278
|
+
const callback = args.at(-1);
|
|
279
|
+
return interceptor(...context, () => innerInterceptor(...context, callback));
|
|
280
|
+
}, (...args) => args.at(-1)());
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* Wraps an interceptor so that both `next()` and the interceptor body race
|
|
284
|
+
* against `invocationEndPromise`. When the attempt ends (suspension, retryable
|
|
285
|
+
* error, etc.), the promise rejects and the interceptor chain unwinds through
|
|
286
|
+
* catch/finally blocks — preventing interceptors from hanging on a `next()`
|
|
287
|
+
* that will never settle.
|
|
288
|
+
*
|
|
289
|
+
* SDK-internal metadata (CommandError, retryAfter) is stripped before the
|
|
290
|
+
* interceptor sees the error and restored after the chain exits.
|
|
291
|
+
*/
|
|
292
|
+
function raceWithAttemptEnd(ctx, interceptor) {
|
|
293
|
+
return (...args) => {
|
|
294
|
+
let originalError;
|
|
295
|
+
const signal = ctx.invocationEndPromise.promise.catch((e) => {
|
|
296
|
+
originalError = e;
|
|
297
|
+
throw require_error_sanitization.sanitizeError(e);
|
|
298
|
+
});
|
|
299
|
+
const originalNext = args.at(-1);
|
|
300
|
+
const racingNext = () => Promise.race([originalNext(), signal]);
|
|
301
|
+
const newArgs = [...args.slice(0, -1), racingNext];
|
|
302
|
+
return Promise.race([interceptor(...newArgs), signal]).catch((e) => {
|
|
303
|
+
if (originalError !== void 0) throw require_error_sanitization.restoreError(e, originalError);
|
|
304
|
+
throw e;
|
|
305
|
+
});
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
function isDefined(value) {
|
|
309
|
+
return value != null;
|
|
310
|
+
}
|
|
237
311
|
function restateLogLevelToWasmLogLevel(level) {
|
|
238
312
|
switch (level) {
|
|
239
313
|
case require_logger_transport.RestateLogLevel.TRACE: return require_sdk_shared_core_wasm_bindings.LogLevel.TRACE;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generic.d.ts","sourceRoot":"","sources":["../../../src/endpoint/handlers/generic.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EACV,QAAQ,IAAI,gBAAgB,EAC5B,YAAY,EACb,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"generic.d.ts","sourceRoot":"","sources":["../../../src/endpoint/handlers/generic.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EACV,QAAQ,IAAI,gBAAgB,EAC5B,YAAY,EACb,MAAM,iBAAiB,CAAC;AA0BzB,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EACL,KAAK,cAAc,EAQpB,MAAM,YAAY,CAAC;AAiBpB,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,QAAQ,EAClB,YAAY,EAAE,YAAY,EAC1B,yBAAyB,EAAE,OAAO,CAAC,gBAAgB,CAAC,GACnD,cAAc,CAMhB"}
|