@restatedev/restate-sdk-cloudflare-workers 1.13.0 → 1.14.1

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.
@@ -37,16 +37,48 @@ function handlerOutputDiscovery(handler, defaultSerde) {
37
37
  };
38
38
  }
39
39
  function createExecutionOptions(serviceOptions, handlerOptions) {
40
+ const defaultSerde = handlerOptions?.serde ?? serviceOptions?.serde ?? __restatedev_restate_sdk_core.serde.json;
40
41
  const hooks = [...serviceOptions?.hooks ?? [], ...handlerOptions?.hooks ?? []];
41
42
  return {
42
- defaultSerde: handlerOptions?.serde ?? serviceOptions?.serde,
43
+ defaultSerde,
43
44
  asTerminalError: handlerOptions?.asTerminalError ?? serviceOptions?.asTerminalError,
44
45
  hooks: hooks.length > 0 ? hooks : void 0,
45
46
  explicitCancellation: handlerOptions?.explicitCancellation ?? serviceOptions?.explicitCancellation
46
47
  };
47
48
  }
49
+ const PREVIEW_METADATA_KEY_PREFIX = "dev.restate.serde.preview";
50
+ /**
51
+ * Service-scoped serde namespace.
52
+ *
53
+ * Today it is populated from handler inputs/outputs under `<handler>/input`
54
+ * and `<handler>/output`. Custom service-level serdes can be registered
55
+ * alongside them under any name.
56
+ */
57
+ var ServiceSerdeRegistry = class {
58
+ serdes = /* @__PURE__ */ new Map();
59
+ registerHandlerIO(handlerName, wrapper, executionOptions) {
60
+ this.serdes.set(`${handlerName}/input`, wrapper.options?.input ?? executionOptions.defaultSerde);
61
+ this.serdes.set(`${handlerName}/output`, wrapper.options?.output ?? executionOptions.defaultSerde);
62
+ }
63
+ resolve(name) {
64
+ return this.serdes.get(name);
65
+ }
66
+ previewMetadata() {
67
+ const metadata = {};
68
+ for (const [name, s] of this.serdes) if (s.preview) metadata[`${PREVIEW_METADATA_KEY_PREFIX}.${name}`] = "true";
69
+ return Object.keys(metadata).length > 0 ? metadata : void 0;
70
+ }
71
+ };
72
+ function mergeMetadata(baseMetadata, additionalMetadata) {
73
+ if (!baseMetadata && !additionalMetadata) return;
74
+ return {
75
+ ...baseMetadata ?? {},
76
+ ...additionalMetadata ?? {}
77
+ };
78
+ }
48
79
  var ServiceComponent = class {
49
80
  handlers = /* @__PURE__ */ new Map();
81
+ serdeRegistry = new ServiceSerdeRegistry();
50
82
  constructor(componentName, description, metadata, options) {
51
83
  this.componentName = componentName;
52
84
  this.description = description;
@@ -57,13 +89,15 @@ var ServiceComponent = class {
57
89
  return this.componentName;
58
90
  }
59
91
  add(name, handlerWrapper) {
60
- this.handlers.set(name, new ServiceHandler(name, handlerWrapper, this));
92
+ const handler = new ServiceHandler(name, handlerWrapper, this);
93
+ this.handlers.set(name, handler);
94
+ this.serdeRegistry.registerHandlerIO(name, handlerWrapper, handler.executionOptions);
61
95
  }
62
96
  discovery() {
63
97
  const handlers = [...this.handlers.entries()].map(([name, handler]) => {
64
98
  return {
65
99
  name,
66
- ...commonHandlerOptions(handler.handlerWrapper, handler.executionOptions.defaultSerde ?? __restatedev_restate_sdk_core.serde.json)
100
+ ...commonHandlerOptions(handler.handlerWrapper, handler.executionOptions.defaultSerde)
67
101
  };
68
102
  });
69
103
  return {
@@ -71,13 +105,16 @@ var ServiceComponent = class {
71
105
  ty: "SERVICE",
72
106
  handlers,
73
107
  documentation: this.description,
74
- metadata: this.metadata,
108
+ metadata: mergeMetadata(this.metadata, this.serdeRegistry.previewMetadata()),
75
109
  ...commonServiceOptions(this.options)
76
110
  };
77
111
  }
78
112
  handlerMatching(url) {
79
113
  return this.handlers.get(url.handlerName);
80
114
  }
115
+ serdeMatching(name) {
116
+ return this.serdeRegistry.resolve(name);
117
+ }
81
118
  };
82
119
  var ServiceHandler = class {
83
120
  executionOptions;
@@ -102,6 +139,7 @@ var ServiceHandler = class {
102
139
  };
103
140
  var VirtualObjectComponent = class {
104
141
  handlers = /* @__PURE__ */ new Map();
142
+ serdeRegistry = new ServiceSerdeRegistry();
105
143
  constructor(componentName, description, metadata, options) {
106
144
  this.componentName = componentName;
107
145
  this.description = description;
@@ -112,14 +150,16 @@ var VirtualObjectComponent = class {
112
150
  return this.componentName;
113
151
  }
114
152
  add(name, wrapper) {
115
- this.handlers.set(name, new VirtualObjectHandler(name, wrapper, this));
153
+ const handler = new VirtualObjectHandler(name, wrapper, this);
154
+ this.handlers.set(name, handler);
155
+ this.serdeRegistry.registerHandlerIO(name, wrapper, handler.executionOptions);
116
156
  }
117
157
  discovery() {
118
158
  const handlers = [...this.handlers.entries()].map(([name, handler]) => {
119
159
  return {
120
160
  name,
121
161
  ty: handler.kind() === require_rpc.HandlerKind.EXCLUSIVE ? "EXCLUSIVE" : "SHARED",
122
- ...commonHandlerOptions(handler.handlerWrapper, handler.executionOptions.defaultSerde ?? __restatedev_restate_sdk_core.serde.json)
162
+ ...commonHandlerOptions(handler.handlerWrapper, handler.executionOptions.defaultSerde)
123
163
  };
124
164
  });
125
165
  return {
@@ -127,13 +167,16 @@ var VirtualObjectComponent = class {
127
167
  ty: "VIRTUAL_OBJECT",
128
168
  handlers,
129
169
  documentation: this.description,
130
- metadata: this.metadata,
170
+ metadata: mergeMetadata(this.metadata, this.serdeRegistry.previewMetadata()),
131
171
  ...commonServiceOptions(this.options)
132
172
  };
133
173
  }
134
174
  handlerMatching(url) {
135
175
  return this.handlers.get(url.handlerName);
136
176
  }
177
+ serdeMatching(name) {
178
+ return this.serdeRegistry.resolve(name);
179
+ }
137
180
  };
138
181
  var VirtualObjectHandler = class {
139
182
  executionOptions;
@@ -158,6 +201,7 @@ var VirtualObjectHandler = class {
158
201
  };
159
202
  var WorkflowComponent = class {
160
203
  handlers = /* @__PURE__ */ new Map();
204
+ serdeRegistry = new ServiceSerdeRegistry();
161
205
  constructor(componentName, description, metadata, options) {
162
206
  this.componentName = componentName;
163
207
  this.description = description;
@@ -168,7 +212,9 @@ var WorkflowComponent = class {
168
212
  return this.componentName;
169
213
  }
170
214
  add(name, wrapper) {
171
- this.handlers.set(name, new WorkflowHandler(name, wrapper, this));
215
+ const handler = new WorkflowHandler(name, wrapper, this);
216
+ this.handlers.set(name, handler);
217
+ this.serdeRegistry.registerHandlerIO(name, wrapper, handler.executionOptions);
172
218
  }
173
219
  discovery() {
174
220
  const handlers = [...this.handlers.entries()].map(([name, handler]) => {
@@ -176,7 +222,7 @@ var WorkflowComponent = class {
176
222
  name,
177
223
  ty: handler.kind() === require_rpc.HandlerKind.WORKFLOW ? "WORKFLOW" : "SHARED",
178
224
  workflowCompletionRetention: handler.kind() === require_rpc.HandlerKind.WORKFLOW && this.options?.workflowRetention !== void 0 ? (0, __restatedev_restate_sdk_core.millisOrDurationToMillis)(this.options?.workflowRetention) : void 0,
179
- ...commonHandlerOptions(handler.handlerWrapper, handler.executionOptions.defaultSerde ?? __restatedev_restate_sdk_core.serde.json)
225
+ ...commonHandlerOptions(handler.handlerWrapper, handler.executionOptions.defaultSerde)
180
226
  };
181
227
  });
182
228
  return {
@@ -184,13 +230,16 @@ var WorkflowComponent = class {
184
230
  ty: "WORKFLOW",
185
231
  handlers,
186
232
  documentation: this.description,
187
- metadata: this.metadata,
233
+ metadata: mergeMetadata(this.metadata, this.serdeRegistry.previewMetadata()),
188
234
  ...commonServiceOptions(this.options)
189
235
  };
190
236
  }
191
237
  handlerMatching(url) {
192
238
  return this.handlers.get(url.handlerName);
193
239
  }
240
+ serdeMatching(name) {
241
+ return this.serdeRegistry.resolve(name);
242
+ }
194
243
  };
195
244
  var WorkflowHandler = class {
196
245
  executionOptions;
@@ -213,11 +262,19 @@ var WorkflowHandler = class {
213
262
  return this.handlerWrapper.invoke(context, input);
214
263
  }
215
264
  };
265
+ const PREVIEW_PATH_REGEX = /(?:^|\/)serdes\/(?<componentName>[^/]+)\/(?<operation>encode|decode)\/(?<serdeName>.+?)\/?$/;
216
266
  function parseUrlComponents(urlPath) {
217
267
  if (!urlPath) return {
218
268
  type: "unknown",
219
269
  path: ""
220
270
  };
271
+ const preview = PREVIEW_PATH_REGEX.exec(urlPath);
272
+ if (preview?.groups) return {
273
+ type: "preview",
274
+ componentName: preview.groups.componentName,
275
+ operation: preview.groups.operation,
276
+ serdeName: decodeURIComponent(preview.groups.serdeName)
277
+ };
221
278
  const fragments = urlPath.split("/");
222
279
  if (fragments.length >= 3 && fragments[fragments.length - 3] === "invoke") return {
223
280
  type: "invoke",
@@ -35,16 +35,48 @@ function handlerOutputDiscovery(handler, defaultSerde) {
35
35
  };
36
36
  }
37
37
  function createExecutionOptions(serviceOptions, handlerOptions) {
38
+ const defaultSerde = handlerOptions?.serde ?? serviceOptions?.serde ?? serde.json;
38
39
  const hooks = [...serviceOptions?.hooks ?? [], ...handlerOptions?.hooks ?? []];
39
40
  return {
40
- defaultSerde: handlerOptions?.serde ?? serviceOptions?.serde,
41
+ defaultSerde,
41
42
  asTerminalError: handlerOptions?.asTerminalError ?? serviceOptions?.asTerminalError,
42
43
  hooks: hooks.length > 0 ? hooks : void 0,
43
44
  explicitCancellation: handlerOptions?.explicitCancellation ?? serviceOptions?.explicitCancellation
44
45
  };
45
46
  }
47
+ const PREVIEW_METADATA_KEY_PREFIX = "dev.restate.serde.preview";
48
+ /**
49
+ * Service-scoped serde namespace.
50
+ *
51
+ * Today it is populated from handler inputs/outputs under `<handler>/input`
52
+ * and `<handler>/output`. Custom service-level serdes can be registered
53
+ * alongside them under any name.
54
+ */
55
+ var ServiceSerdeRegistry = class {
56
+ serdes = /* @__PURE__ */ new Map();
57
+ registerHandlerIO(handlerName, wrapper, executionOptions) {
58
+ this.serdes.set(`${handlerName}/input`, wrapper.options?.input ?? executionOptions.defaultSerde);
59
+ this.serdes.set(`${handlerName}/output`, wrapper.options?.output ?? executionOptions.defaultSerde);
60
+ }
61
+ resolve(name) {
62
+ return this.serdes.get(name);
63
+ }
64
+ previewMetadata() {
65
+ const metadata = {};
66
+ for (const [name, s] of this.serdes) if (s.preview) metadata[`${PREVIEW_METADATA_KEY_PREFIX}.${name}`] = "true";
67
+ return Object.keys(metadata).length > 0 ? metadata : void 0;
68
+ }
69
+ };
70
+ function mergeMetadata(baseMetadata, additionalMetadata) {
71
+ if (!baseMetadata && !additionalMetadata) return;
72
+ return {
73
+ ...baseMetadata ?? {},
74
+ ...additionalMetadata ?? {}
75
+ };
76
+ }
46
77
  var ServiceComponent = class {
47
78
  handlers = /* @__PURE__ */ new Map();
79
+ serdeRegistry = new ServiceSerdeRegistry();
48
80
  constructor(componentName, description, metadata, options) {
49
81
  this.componentName = componentName;
50
82
  this.description = description;
@@ -55,13 +87,15 @@ var ServiceComponent = class {
55
87
  return this.componentName;
56
88
  }
57
89
  add(name, handlerWrapper) {
58
- this.handlers.set(name, new ServiceHandler$1(name, handlerWrapper, this));
90
+ const handler = new ServiceHandler$1(name, handlerWrapper, this);
91
+ this.handlers.set(name, handler);
92
+ this.serdeRegistry.registerHandlerIO(name, handlerWrapper, handler.executionOptions);
59
93
  }
60
94
  discovery() {
61
95
  const handlers = [...this.handlers.entries()].map(([name, handler]) => {
62
96
  return {
63
97
  name,
64
- ...commonHandlerOptions(handler.handlerWrapper, handler.executionOptions.defaultSerde ?? serde.json)
98
+ ...commonHandlerOptions(handler.handlerWrapper, handler.executionOptions.defaultSerde)
65
99
  };
66
100
  });
67
101
  return {
@@ -69,13 +103,16 @@ var ServiceComponent = class {
69
103
  ty: "SERVICE",
70
104
  handlers,
71
105
  documentation: this.description,
72
- metadata: this.metadata,
106
+ metadata: mergeMetadata(this.metadata, this.serdeRegistry.previewMetadata()),
73
107
  ...commonServiceOptions(this.options)
74
108
  };
75
109
  }
76
110
  handlerMatching(url) {
77
111
  return this.handlers.get(url.handlerName);
78
112
  }
113
+ serdeMatching(name) {
114
+ return this.serdeRegistry.resolve(name);
115
+ }
79
116
  };
80
117
  var ServiceHandler$1 = class {
81
118
  executionOptions;
@@ -100,6 +137,7 @@ var ServiceHandler$1 = class {
100
137
  };
101
138
  var VirtualObjectComponent = class {
102
139
  handlers = /* @__PURE__ */ new Map();
140
+ serdeRegistry = new ServiceSerdeRegistry();
103
141
  constructor(componentName, description, metadata, options) {
104
142
  this.componentName = componentName;
105
143
  this.description = description;
@@ -110,14 +148,16 @@ var VirtualObjectComponent = class {
110
148
  return this.componentName;
111
149
  }
112
150
  add(name, wrapper) {
113
- this.handlers.set(name, new VirtualObjectHandler(name, wrapper, this));
151
+ const handler = new VirtualObjectHandler(name, wrapper, this);
152
+ this.handlers.set(name, handler);
153
+ this.serdeRegistry.registerHandlerIO(name, wrapper, handler.executionOptions);
114
154
  }
115
155
  discovery() {
116
156
  const handlers = [...this.handlers.entries()].map(([name, handler]) => {
117
157
  return {
118
158
  name,
119
159
  ty: handler.kind() === HandlerKind.EXCLUSIVE ? "EXCLUSIVE" : "SHARED",
120
- ...commonHandlerOptions(handler.handlerWrapper, handler.executionOptions.defaultSerde ?? serde.json)
160
+ ...commonHandlerOptions(handler.handlerWrapper, handler.executionOptions.defaultSerde)
121
161
  };
122
162
  });
123
163
  return {
@@ -125,13 +165,16 @@ var VirtualObjectComponent = class {
125
165
  ty: "VIRTUAL_OBJECT",
126
166
  handlers,
127
167
  documentation: this.description,
128
- metadata: this.metadata,
168
+ metadata: mergeMetadata(this.metadata, this.serdeRegistry.previewMetadata()),
129
169
  ...commonServiceOptions(this.options)
130
170
  };
131
171
  }
132
172
  handlerMatching(url) {
133
173
  return this.handlers.get(url.handlerName);
134
174
  }
175
+ serdeMatching(name) {
176
+ return this.serdeRegistry.resolve(name);
177
+ }
135
178
  };
136
179
  var VirtualObjectHandler = class {
137
180
  executionOptions;
@@ -156,6 +199,7 @@ var VirtualObjectHandler = class {
156
199
  };
157
200
  var WorkflowComponent = class {
158
201
  handlers = /* @__PURE__ */ new Map();
202
+ serdeRegistry = new ServiceSerdeRegistry();
159
203
  constructor(componentName, description, metadata, options) {
160
204
  this.componentName = componentName;
161
205
  this.description = description;
@@ -166,7 +210,9 @@ var WorkflowComponent = class {
166
210
  return this.componentName;
167
211
  }
168
212
  add(name, wrapper) {
169
- this.handlers.set(name, new WorkflowHandler$1(name, wrapper, this));
213
+ const handler = new WorkflowHandler$1(name, wrapper, this);
214
+ this.handlers.set(name, handler);
215
+ this.serdeRegistry.registerHandlerIO(name, wrapper, handler.executionOptions);
170
216
  }
171
217
  discovery() {
172
218
  const handlers = [...this.handlers.entries()].map(([name, handler]) => {
@@ -174,7 +220,7 @@ var WorkflowComponent = class {
174
220
  name,
175
221
  ty: handler.kind() === HandlerKind.WORKFLOW ? "WORKFLOW" : "SHARED",
176
222
  workflowCompletionRetention: handler.kind() === HandlerKind.WORKFLOW && this.options?.workflowRetention !== void 0 ? millisOrDurationToMillis(this.options?.workflowRetention) : void 0,
177
- ...commonHandlerOptions(handler.handlerWrapper, handler.executionOptions.defaultSerde ?? serde.json)
223
+ ...commonHandlerOptions(handler.handlerWrapper, handler.executionOptions.defaultSerde)
178
224
  };
179
225
  });
180
226
  return {
@@ -182,13 +228,16 @@ var WorkflowComponent = class {
182
228
  ty: "WORKFLOW",
183
229
  handlers,
184
230
  documentation: this.description,
185
- metadata: this.metadata,
231
+ metadata: mergeMetadata(this.metadata, this.serdeRegistry.previewMetadata()),
186
232
  ...commonServiceOptions(this.options)
187
233
  };
188
234
  }
189
235
  handlerMatching(url) {
190
236
  return this.handlers.get(url.handlerName);
191
237
  }
238
+ serdeMatching(name) {
239
+ return this.serdeRegistry.resolve(name);
240
+ }
192
241
  };
193
242
  var WorkflowHandler$1 = class {
194
243
  executionOptions;
@@ -211,11 +260,19 @@ var WorkflowHandler$1 = class {
211
260
  return this.handlerWrapper.invoke(context, input);
212
261
  }
213
262
  };
263
+ const PREVIEW_PATH_REGEX = /(?:^|\/)serdes\/(?<componentName>[^/]+)\/(?<operation>encode|decode)\/(?<serdeName>.+?)\/?$/;
214
264
  function parseUrlComponents(urlPath) {
215
265
  if (!urlPath) return {
216
266
  type: "unknown",
217
267
  path: ""
218
268
  };
269
+ const preview = PREVIEW_PATH_REGEX.exec(urlPath);
270
+ if (preview?.groups) return {
271
+ type: "preview",
272
+ componentName: preview.groups.componentName,
273
+ operation: preview.groups.operation,
274
+ serdeName: decodeURIComponent(preview.groups.serdeName)
275
+ };
219
276
  const fragments = urlPath.split("/");
220
277
  if (fragments.length >= 3 && fragments[fragments.length - 3] === "invoke") return {
221
278
  type: "invoke",
@@ -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 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
+ {"version":3,"file":"components.js","names":["serde","metadata: Record<string, string>","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 serdeMatching(name: string): Serde<any> | 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 const defaultSerde =\n handlerOptions?.serde ?? serviceOptions?.serde ?? serde.json;\n\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,\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\nconst PREVIEW_METADATA_KEY_PREFIX = \"dev.restate.serde.preview\";\n\n/**\n * Service-scoped serde namespace.\n *\n * Today it is populated from handler inputs/outputs under `<handler>/input`\n * and `<handler>/output`. Custom service-level serdes can be registered\n * alongside them under any name.\n */\nclass ServiceSerdeRegistry {\n private readonly serdes = new Map<string, Serde<unknown>>();\n\n registerHandlerIO(\n handlerName: string,\n wrapper: HandlerWrapper,\n executionOptions: ExecutionOptions\n ): void {\n this.serdes.set(\n `${handlerName}/input`,\n wrapper.options?.input ?? executionOptions.defaultSerde\n );\n this.serdes.set(\n `${handlerName}/output`,\n wrapper.options?.output ?? executionOptions.defaultSerde\n );\n }\n\n resolve(name: string): Serde<unknown> | undefined {\n return this.serdes.get(name);\n }\n\n previewMetadata(): Record<string, string> | undefined {\n const metadata: Record<string, string> = {};\n for (const [name, s] of this.serdes) {\n if (s.preview) {\n metadata[`${PREVIEW_METADATA_KEY_PREFIX}.${name}`] = \"true\";\n }\n }\n return Object.keys(metadata).length > 0 ? metadata : undefined;\n }\n}\n\nfunction mergeMetadata(\n baseMetadata?: Record<string, string>,\n additionalMetadata?: Record<string, string>\n): Record<string, string> | undefined {\n if (!baseMetadata && !additionalMetadata) {\n return undefined;\n }\n\n return {\n ...(baseMetadata ?? {}),\n ...(additionalMetadata ?? {}),\n };\n}\n\nexport class ServiceComponent implements Component {\n private readonly handlers: Map<string, ServiceHandler> = new Map();\n private readonly serdeRegistry = new ServiceSerdeRegistry();\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 const handler = new ServiceHandler(name, handlerWrapper, this);\n this.handlers.set(name, handler);\n this.serdeRegistry.registerHandlerIO(\n name,\n handlerWrapper,\n handler.executionOptions\n );\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\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: mergeMetadata(\n this.metadata,\n this.serdeRegistry.previewMetadata()\n ),\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 serdeMatching(name: string): Serde<any> | undefined {\n return this.serdeRegistry.resolve(name);\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 private readonly serdeRegistry = new ServiceSerdeRegistry();\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 const handler = new VirtualObjectHandler(name, wrapper, this);\n this.handlers.set(name, handler);\n this.serdeRegistry.registerHandlerIO(\n name,\n wrapper,\n handler.executionOptions\n );\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\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: mergeMetadata(\n this.metadata,\n this.serdeRegistry.previewMetadata()\n ),\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 serdeMatching(name: string): Serde<any> | undefined {\n return this.serdeRegistry.resolve(name);\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 private readonly serdeRegistry = new ServiceSerdeRegistry();\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 const handler = new WorkflowHandler(name, wrapper, this);\n this.handlers.set(name, handler);\n this.serdeRegistry.registerHandlerIO(\n name,\n wrapper,\n handler.executionOptions\n );\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\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: mergeMetadata(\n this.metadata,\n this.serdeRegistry.previewMetadata()\n ),\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 serdeMatching(name: string): Serde<any> | undefined {\n return this.serdeRegistry.resolve(name);\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 | PreviewPathComponents\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 type PreviewPathComponents = {\n type: \"preview\";\n componentName: string;\n operation: \"decode\" | \"encode\";\n serdeName: string;\n};\n\n// Preview uses a regex so that `serdeName` can span multiple path segments\n// (built-ins are shaped as `<handler>/(input|output)`). The regex is anchored\n// with `(?:^|\\/)` so deployments mounted under a sub-path also work.\nconst PREVIEW_PATH_REGEX =\n /(?:^|\\/)serdes\\/(?<componentName>[^/]+)\\/(?<operation>encode|decode)\\/(?<serdeName>.+?)\\/?$/;\n\nexport function parseUrlComponents(urlPath?: string): PathComponents {\n if (!urlPath) {\n return { type: \"unknown\", path: \"\" };\n }\n\n const preview = PREVIEW_PATH_REGEX.exec(urlPath);\n if (preview?.groups) {\n return {\n type: \"preview\",\n componentName: preview.groups.componentName!,\n operation: preview.groups.operation as \"decode\" | \"encode\",\n serdeName: decodeURIComponent(preview.groups.serdeName!),\n };\n }\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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"}
@@ -14,17 +14,19 @@ function fetcher(handler) {
14
14
  const inputReader = event.body ? event.body[Symbol.asyncIterator]() : require_utils.emptyInputReader();
15
15
  const transformStream = new TransformStream();
16
16
  const outputWriter = transformStream.writable.getWriter();
17
+ const { writeHead, head } = require_utils.captureHead();
17
18
  response.process({
18
19
  inputReader,
19
20
  outputWriter,
21
+ writeHead,
20
22
  abortSignal: event.signal
21
23
  }).catch((e) => {
22
24
  const error = require_errors.ensureError(e);
23
25
  (require_utils.tryCreateContextualLogger(handler.endpoint.loggerTransport, url, headers) ?? handler.endpoint.rlog).error("Unexpected error: " + (error.stack ?? error.message));
24
26
  });
25
- return Promise.resolve(new Response(transformStream.readable, {
26
- status: response.statusCode,
27
- headers: response.headers
27
+ return head.then((h) => new Response(transformStream.readable, {
28
+ status: h.statusCode,
29
+ headers: h.headers
28
30
  }));
29
31
  } };
30
32
  }
@@ -1,5 +1,5 @@
1
1
  import { ensureError } from "../../types/errors.js";
2
- import { emptyInputReader, tryCreateContextualLogger } from "./utils.js";
2
+ import { captureHead, emptyInputReader, tryCreateContextualLogger } from "./utils.js";
3
3
 
4
4
  //#region src/endpoint/handlers/fetch.ts
5
5
  function fetcher(handler) {
@@ -14,17 +14,19 @@ function fetcher(handler) {
14
14
  const inputReader = event.body ? event.body[Symbol.asyncIterator]() : emptyInputReader();
15
15
  const transformStream = new TransformStream();
16
16
  const outputWriter = transformStream.writable.getWriter();
17
+ const { writeHead, head } = captureHead();
17
18
  response.process({
18
19
  inputReader,
19
20
  outputWriter,
21
+ writeHead,
20
22
  abortSignal: event.signal
21
23
  }).catch((e) => {
22
24
  const error = ensureError(e);
23
25
  (tryCreateContextualLogger(handler.endpoint.loggerTransport, url, headers) ?? handler.endpoint.rlog).error("Unexpected error: " + (error.stack ?? error.message));
24
26
  });
25
- return Promise.resolve(new Response(transformStream.readable, {
26
- status: response.statusCode,
27
- headers: response.headers
27
+ return head.then((h) => new Response(transformStream.readable, {
28
+ status: h.statusCode,
29
+ headers: h.headers
28
30
  }));
29
31
  } };
30
32
  }
@@ -1 +1 @@
1
- {"version":3,"file":"fetch.js","names":[],"sources":["../../../src/endpoint/handlers/fetch.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 { ensureError } from \"../../types/errors.js\";\nimport type { RestateHandler } from \"./types.js\";\nimport { emptyInputReader, tryCreateContextualLogger } from \"./utils.js\";\n\nexport function fetcher(handler: RestateHandler) {\n return {\n fetch: (event: Request, ...extraArgs: unknown[]): Promise<Response> => {\n const url = event.url;\n const headers = Object.fromEntries(event.headers.entries());\n\n const response = handler.handle({\n url,\n headers,\n extraArgs,\n });\n\n const inputReader = event.body\n ? event.body[Symbol.asyncIterator]()\n : emptyInputReader();\n\n // We use the TransformStream here to adapt writer -> reader\n const transformStream = new TransformStream<Uint8Array>();\n const outputWriter = transformStream.writable.getWriter();\n\n // Start processing, then return back the response\n response\n .process({\n inputReader,\n outputWriter,\n abortSignal: event.signal,\n })\n .catch((e) => {\n // handle should never throw\n const error = ensureError(e);\n const logger =\n tryCreateContextualLogger(\n handler.endpoint.loggerTransport,\n url,\n headers\n ) ?? handler.endpoint.rlog;\n logger.error(\"Unexpected error: \" + (error.stack ?? error.message));\n });\n\n return Promise.resolve(\n new Response(transformStream.readable, {\n status: response.statusCode,\n headers: response.headers,\n })\n );\n },\n };\n}\n"],"mappings":";;;;AAeA,SAAgB,QAAQ,SAAyB;AAC/C,QAAO,EACL,QAAQ,OAAgB,GAAG,cAA4C;EACrE,MAAM,MAAM,MAAM;EAClB,MAAM,UAAU,OAAO,YAAY,MAAM,QAAQ,SAAS,CAAC;EAE3D,MAAM,WAAW,QAAQ,OAAO;GAC9B;GACA;GACA;GACD,CAAC;EAEF,MAAM,cAAc,MAAM,OACtB,MAAM,KAAK,OAAO,gBAAgB,GAClC,kBAAkB;EAGtB,MAAM,kBAAkB,IAAI,iBAA6B;EACzD,MAAM,eAAe,gBAAgB,SAAS,WAAW;AAGzD,WACG,QAAQ;GACP;GACA;GACA,aAAa,MAAM;GACpB,CAAC,CACD,OAAO,MAAM;GAEZ,MAAM,QAAQ,YAAY,EAAE;AAO5B,IALE,0BACE,QAAQ,SAAS,iBACjB,KACA,QACD,IAAI,QAAQ,SAAS,MACjB,MAAM,wBAAwB,MAAM,SAAS,MAAM,SAAS;IACnE;AAEJ,SAAO,QAAQ,QACb,IAAI,SAAS,gBAAgB,UAAU;GACrC,QAAQ,SAAS;GACjB,SAAS,SAAS;GACnB,CAAC,CACH;IAEJ"}
1
+ {"version":3,"file":"fetch.js","names":[],"sources":["../../../src/endpoint/handlers/fetch.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 { ensureError } from \"../../types/errors.js\";\nimport type { RestateHandler } from \"./types.js\";\nimport {\n captureHead,\n emptyInputReader,\n tryCreateContextualLogger,\n} from \"./utils.js\";\n\nexport function fetcher(handler: RestateHandler) {\n return {\n fetch: (event: Request, ...extraArgs: unknown[]): Promise<Response> => {\n const url = event.url;\n const headers = Object.fromEntries(event.headers.entries());\n\n // handle should never throw\n const response = handler.handle({\n url,\n headers,\n extraArgs,\n });\n\n const inputReader = event.body\n ? event.body[Symbol.asyncIterator]()\n : emptyInputReader();\n\n // We use the TransformStream here to adapt writer -> reader\n const transformStream = new TransformStream<Uint8Array>();\n const outputWriter = transformStream.writable.getWriter();\n\n const { writeHead, head } = captureHead();\n\n response\n .process({\n inputReader,\n outputWriter,\n writeHead,\n abortSignal: event.signal,\n })\n .catch((e) => {\n // Responses handle their own errors before rejecting; anything\n // reaching here is an unexpected failure — just log.\n const error = ensureError(e);\n const logger =\n tryCreateContextualLogger(\n handler.endpoint.loggerTransport,\n url,\n headers\n ) ?? handler.endpoint.rlog;\n logger.error(\"Unexpected error: \" + (error.stack ?? error.message));\n });\n\n return head.then(\n (h) =>\n new Response(transformStream.readable, {\n status: h.statusCode,\n headers: h.headers,\n })\n );\n },\n };\n}\n"],"mappings":";;;;AAmBA,SAAgB,QAAQ,SAAyB;AAC/C,QAAO,EACL,QAAQ,OAAgB,GAAG,cAA4C;EACrE,MAAM,MAAM,MAAM;EAClB,MAAM,UAAU,OAAO,YAAY,MAAM,QAAQ,SAAS,CAAC;EAG3D,MAAM,WAAW,QAAQ,OAAO;GAC9B;GACA;GACA;GACD,CAAC;EAEF,MAAM,cAAc,MAAM,OACtB,MAAM,KAAK,OAAO,gBAAgB,GAClC,kBAAkB;EAGtB,MAAM,kBAAkB,IAAI,iBAA6B;EACzD,MAAM,eAAe,gBAAgB,SAAS,WAAW;EAEzD,MAAM,EAAE,WAAW,SAAS,aAAa;AAEzC,WACG,QAAQ;GACP;GACA;GACA;GACA,aAAa,MAAM;GACpB,CAAC,CACD,OAAO,MAAM;GAGZ,MAAM,QAAQ,YAAY,EAAE;AAO5B,IALE,0BACE,QAAQ,SAAS,iBACjB,KACA,QACD,IAAI,QAAQ,SAAS,MACjB,MAAM,wBAAwB,MAAM,SAAS,MAAM,SAAS;IACnE;AAEJ,SAAO,KAAK,MACT,MACC,IAAI,SAAS,gBAAgB,UAAU;GACrC,QAAQ,EAAE;GACV,SAAS,EAAE;GACZ,CAAC,CACL;IAEJ"}
@@ -13,6 +13,7 @@ const require_context_impl = require('../../context_impl.cjs');
13
13
  const require_error_sanitization = require('../../error_sanitization.cjs');
14
14
  const require_utils = require('./utils.cjs');
15
15
  const require_discovery = require('./discovery.cjs');
16
+ const require_preview = require('./preview.cjs');
16
17
  let __restatedev_restate_sdk_core = require("@restatedev/restate-sdk-core");
17
18
  __restatedev_restate_sdk_core = require_rolldown_runtime.__toESM(__restatedev_restate_sdk_core);
18
19
 
@@ -50,7 +51,7 @@ var RestateHandlerImpl = class {
50
51
  const path = new URL(request.url, "https://example.com").pathname;
51
52
  const parsed = require_components.parseUrlComponents(path);
52
53
  if (parsed.type === "unknown") {
53
- const msg = `Invalid path. Allowed are /health, or /discover, or /invoke/SvcName/handlerName, but was: ${path}`;
54
+ const msg = "Invalid path. Allowed are /health, /discover, /invoke/SvcName/handlerName, /serdes/SvcName/decode/<serdeName>, or /serdes/SvcName/encode/<serdeName>, but was: " + path;
54
55
  this.endpoint.rlog.trace(msg);
55
56
  return require_utils.errorResponse(404, msg);
56
57
  }
@@ -61,6 +62,7 @@ var RestateHandlerImpl = class {
61
62
  const error = this.validateConnectionSignature(path, request.headers);
62
63
  if (error !== null) return error;
63
64
  if (parsed.type === "discover") return require_discovery.handleDiscovery(this.endpoint, this.protocolMode, this.additionalDiscoveryFields, request.headers["accept"]);
65
+ if (parsed.type === "preview") return require_preview.handlePreview(this.endpoint, parsed);
64
66
  return this.handleInvoke(parsed, request.headers, request.extraArgs, context ?? {});
65
67
  }
66
68
  validateConnectionSignature(path, headers) {
@@ -86,9 +88,9 @@ var RestateHandlerImpl = class {
86
88
  this.endpoint.rlog.error(msg);
87
89
  return require_utils.errorResponse(404, msg);
88
90
  }
89
- const handler = service?.handlerMatching(invokePathComponent);
91
+ const handler = service.handlerMatching(invokePathComponent);
90
92
  if (!handler) {
91
- const msg = `No service found for URL: ${JSON.stringify(invokePathComponent)}`;
93
+ const msg = `No handler found for URL: ${JSON.stringify(invokePathComponent)}`;
92
94
  this.endpoint.rlog.error(msg);
93
95
  return require_utils.errorResponse(404, msg);
94
96
  }
@@ -121,7 +123,8 @@ var RestateInvokeResponse = class {
121
123
  }), { "x-restate-server": require_user_agent.X_RESTATE_SERVER });
122
124
  this.vmLogger = require_logger.createLogger(this.loggerTransport, require_logger_transport.LogSource.JOURNAL, new require_logger_transport.LoggerContext(require_utils.invocationIdFromHeaders(this.attemptHeaders), this.service.name(), this.handler.name(), void 0, void 0, this.additionalContext));
123
125
  }
124
- async process({ inputReader, outputWriter, abortSignal }) {
126
+ async process({ inputReader, outputWriter, writeHead, abortSignal }) {
127
+ writeHead(this.statusCode, this.headers);
125
128
  abortSignal.addEventListener("abort", () => {
126
129
  require_core_logging.destroyLogger(this.loggerId);
127
130
  setImmediate(() => {