@restatedev/restate-sdk-cloudflare-workers 1.17.3 → 1.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/dist/common_api.d.cts +2 -2
  2. package/dist/common_api.d.cts.map +1 -1
  3. package/dist/common_api.d.ts +2 -2
  4. package/dist/common_api.d.ts.map +1 -1
  5. package/dist/common_api.js.map +1 -1
  6. package/dist/context.d.cts +25 -8
  7. package/dist/context.d.cts.map +1 -1
  8. package/dist/context.d.ts +25 -8
  9. package/dist/context.d.ts.map +1 -1
  10. package/dist/context.js.map +1 -1
  11. package/dist/context_impl.cjs +10 -10
  12. package/dist/context_impl.js +10 -10
  13. package/dist/context_impl.js.map +1 -1
  14. package/dist/endpoint/components.cjs +39 -7
  15. package/dist/endpoint/components.js +39 -8
  16. package/dist/endpoint/components.js.map +1 -1
  17. package/dist/endpoint/handlers/discovery.cjs +12 -2
  18. package/dist/endpoint/handlers/discovery.js +12 -2
  19. package/dist/endpoint/handlers/discovery.js.map +1 -1
  20. package/dist/endpoint/handlers/generic.cjs +1 -1
  21. package/dist/endpoint/handlers/generic.js +1 -1
  22. package/dist/endpoint/handlers/generic.js.map +1 -1
  23. package/dist/endpoint/handlers/vm/sdk_shared_core_wasm_bindings.d.ts +6 -6
  24. package/dist/endpoint/handlers/vm/sdk_shared_core_wasm_bindings_bg.js +30 -12
  25. package/dist/endpoint/handlers/vm/sdk_shared_core_wasm_bindings_bg.wasm +0 -0
  26. package/dist/endpoint/handlers/vm/sdk_shared_core_wasm_bindings_bg.wasm.d.ts +6 -6
  27. package/dist/fetch.d.cts +3 -3
  28. package/dist/fetch.d.ts +3 -3
  29. package/dist/index.d.cts +3 -3
  30. package/dist/index.d.ts +3 -3
  31. package/dist/internal.cjs +27 -0
  32. package/dist/internal.d.cts +30 -1
  33. package/dist/internal.d.cts.map +1 -1
  34. package/dist/internal.d.ts +30 -1
  35. package/dist/internal.d.ts.map +1 -1
  36. package/dist/internal.js +27 -0
  37. package/dist/internal.js.map +1 -1
  38. package/dist/lambda.d.cts +3 -3
  39. package/dist/lambda.d.ts +3 -3
  40. package/dist/node.d.cts +3 -3
  41. package/dist/node.d.ts +3 -3
  42. package/dist/package.cjs +1 -1
  43. package/dist/package.js +1 -1
  44. package/dist/package.js.map +1 -1
  45. package/dist/types/errors.cjs +4 -2
  46. package/dist/types/errors.d.cts.map +1 -1
  47. package/dist/types/errors.d.ts.map +1 -1
  48. package/dist/types/errors.js +4 -2
  49. package/dist/types/errors.js.map +1 -1
  50. package/dist/types/rpc.d.cts +45 -28
  51. package/dist/types/rpc.d.cts.map +1 -1
  52. package/dist/types/rpc.d.ts +45 -28
  53. package/dist/types/rpc.d.ts.map +1 -1
  54. package/dist/types/rpc.js.map +1 -1
  55. package/package.json +3 -3
@@ -1 +1 @@
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 onJournalMismatchErrors?: \"retry\" | \"pause\" | \"fail\";\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 onJournalMismatchErrors:\n handlerOptions?.onJournalMismatchErrors ??\n serviceOptions?.onJournalMismatchErrors,\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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"}
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 ObjectHandlerOpts,\n ObjectOptions,\n ServiceHandlerOpts,\n ServiceOptions,\n WorkflowHandlerOpts,\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 onJournalMismatchErrors?: \"retry\" | \"pause\" | \"fail\";\n explicitRecovery?: boolean;\n}\n\n/**\n * Key of the option set by `restate.internal.explicitRecovery()`: a symbol, to\n * keep it out of the service and handler option types.\n */\nexport const EXPLICIT_RECOVERY = Symbol(\"ExplicitRecovery\");\n\nfunction explicitRecoveryOf(options?: object): boolean | undefined {\n return (options as { [EXPLICIT_RECOVERY]?: boolean } | undefined)?.[\n EXPLICIT_RECOVERY\n ];\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 onJournalMismatchErrors:\n handlerOptions?.onJournalMismatchErrors ??\n serviceOptions?.onJournalMismatchErrors,\n explicitRecovery:\n explicitRecoveryOf(handlerOptions) ?? explicitRecoveryOf(serviceOptions),\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, false),\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, true),\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, true),\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 resolveStatePreload(\n options?:\n | ServiceOptions\n | ObjectOptions\n | WorkflowOptions\n | ServiceHandlerOpts<unknown, unknown>\n | ObjectHandlerOpts<unknown, unknown>\n | WorkflowHandlerOpts<unknown, unknown>\n): { enableLazyState?: boolean; eagerStateKeysWhitelist?: string[] } {\n const state =\n options !== undefined && \"state\" in options ? options.state : undefined;\n const legacyEnableLazyState =\n options !== undefined && \"enableLazyState\" in options\n ? options.enableLazyState\n : undefined;\n\n if (state !== undefined && legacyEnableLazyState !== undefined) {\n throw new Error(\n \"Cannot set both the 'state' option and the deprecated 'enableLazyState' option at the same time. Use only 'state'.\"\n );\n }\n\n if (state === undefined) {\n // Legacy passthrough (may itself be undefined).\n return {\n enableLazyState: legacyEnableLazyState,\n eagerStateKeysWhitelist: undefined,\n };\n }\n\n const preload = state.preload;\n if (typeof preload === \"boolean\") {\n // preload: true => eager (preload all) => not lazy\n // preload: false => lazy (preload none) => lazy\n return { enableLazyState: !preload, eagerStateKeysWhitelist: undefined };\n }\n\n // preload is a whitelist of keys to preload eagerly (selective preloading).\n // An empty whitelist is equivalent to fully lazy state.\n return {\n enableLazyState: true,\n // Copy, so later mutations of the user's array don't affect discovery.\n eagerStateKeysWhitelist: preload.length > 0 ? [...preload] : undefined,\n };\n}\n\nfunction commonServiceOptions(\n options: ServiceOptions | ObjectOptions | WorkflowOptions | undefined,\n stateful: boolean\n): Partial<d.Service> {\n // Stateless services must not advertise state options, which might have\n // been inherited from the endpoint default service options.\n const statePreload = stateful ? resolveStatePreload(options) : {};\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: statePreload.enableLazyState,\n eagerStateKeysWhitelist: statePreload.eagerStateKeysWhitelist,\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 const statePreload = resolveStatePreload(wrapper.options);\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: statePreload.enableLazyState,\n eagerStateKeysWhitelist: statePreload.eagerStateKeysWhitelist,\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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"}
@@ -5,6 +5,7 @@ const require_utils = require('./utils.cjs');
5
5
  const ENDPOINT_MANIFEST_V2 = "application/vnd.restate.endpointmanifest.v2+json";
6
6
  const ENDPOINT_MANIFEST_V3 = "application/vnd.restate.endpointmanifest.v3+json";
7
7
  const ENDPOINT_MANIFEST_V4 = "application/vnd.restate.endpointmanifest.v4+json";
8
+ const ENDPOINT_MANIFEST_V5 = "application/vnd.restate.endpointmanifest.v5+json";
8
9
  function handleDiscovery(endpoint, protocolMode, additionalDiscoveryFields, acceptVersionsString) {
9
10
  if (typeof acceptVersionsString !== "string") {
10
11
  const errorMessage = "Missing accept header";
@@ -12,7 +13,8 @@ function handleDiscovery(endpoint, protocolMode, additionalDiscoveryFields, acce
12
13
  return require_utils.errorResponse(415, errorMessage);
13
14
  }
14
15
  let manifestVersion;
15
- if (acceptVersionsString.includes(ENDPOINT_MANIFEST_V4)) manifestVersion = 4;
16
+ if (acceptVersionsString.includes(ENDPOINT_MANIFEST_V5)) manifestVersion = 5;
17
+ else if (acceptVersionsString.includes(ENDPOINT_MANIFEST_V4)) manifestVersion = 4;
16
18
  else if (acceptVersionsString.includes(ENDPOINT_MANIFEST_V3)) manifestVersion = 3;
17
19
  else if (acceptVersionsString.includes(ENDPOINT_MANIFEST_V2)) manifestVersion = 2;
18
20
  else {
@@ -47,9 +49,17 @@ function handleDiscovery(endpoint, protocolMode, additionalDiscoveryFields, acce
47
49
  }
48
50
  }
49
51
  }
52
+ if (manifestVersion < 5) for (const service of discovery.services) {
53
+ const error = checkUnsupportedFeature(service, "eagerStateKeysWhitelist");
54
+ if (error !== void 0) return error;
55
+ for (const handler of service.handlers) {
56
+ const error$1 = checkUnsupportedFeature(handler, "eagerStateKeysWhitelist");
57
+ if (error$1 !== void 0) return error$1;
58
+ }
59
+ }
50
60
  const body = JSON.stringify(discovery);
51
61
  return require_utils.simpleResponse(200, {
52
- "content-type": manifestVersion === 2 ? ENDPOINT_MANIFEST_V2 : manifestVersion === 3 ? ENDPOINT_MANIFEST_V3 : ENDPOINT_MANIFEST_V4,
62
+ "content-type": manifestVersion === 2 ? ENDPOINT_MANIFEST_V2 : manifestVersion === 3 ? ENDPOINT_MANIFEST_V3 : manifestVersion === 4 ? ENDPOINT_MANIFEST_V4 : ENDPOINT_MANIFEST_V5,
53
63
  "x-restate-server": require_user_agent.X_RESTATE_SERVER
54
64
  }, new TextEncoder().encode(body));
55
65
  }
@@ -5,6 +5,7 @@ import { errorResponse, simpleResponse } from "./utils.js";
5
5
  const ENDPOINT_MANIFEST_V2 = "application/vnd.restate.endpointmanifest.v2+json";
6
6
  const ENDPOINT_MANIFEST_V3 = "application/vnd.restate.endpointmanifest.v3+json";
7
7
  const ENDPOINT_MANIFEST_V4 = "application/vnd.restate.endpointmanifest.v4+json";
8
+ const ENDPOINT_MANIFEST_V5 = "application/vnd.restate.endpointmanifest.v5+json";
8
9
  function handleDiscovery(endpoint, protocolMode, additionalDiscoveryFields, acceptVersionsString) {
9
10
  if (typeof acceptVersionsString !== "string") {
10
11
  const errorMessage = "Missing accept header";
@@ -12,7 +13,8 @@ function handleDiscovery(endpoint, protocolMode, additionalDiscoveryFields, acce
12
13
  return errorResponse(415, errorMessage);
13
14
  }
14
15
  let manifestVersion;
15
- if (acceptVersionsString.includes(ENDPOINT_MANIFEST_V4)) manifestVersion = 4;
16
+ if (acceptVersionsString.includes(ENDPOINT_MANIFEST_V5)) manifestVersion = 5;
17
+ else if (acceptVersionsString.includes(ENDPOINT_MANIFEST_V4)) manifestVersion = 4;
16
18
  else if (acceptVersionsString.includes(ENDPOINT_MANIFEST_V3)) manifestVersion = 3;
17
19
  else if (acceptVersionsString.includes(ENDPOINT_MANIFEST_V2)) manifestVersion = 2;
18
20
  else {
@@ -47,9 +49,17 @@ function handleDiscovery(endpoint, protocolMode, additionalDiscoveryFields, acce
47
49
  }
48
50
  }
49
51
  }
52
+ if (manifestVersion < 5) for (const service of discovery.services) {
53
+ const error = checkUnsupportedFeature(service, "eagerStateKeysWhitelist");
54
+ if (error !== void 0) return error;
55
+ for (const handler of service.handlers) {
56
+ const error$1 = checkUnsupportedFeature(handler, "eagerStateKeysWhitelist");
57
+ if (error$1 !== void 0) return error$1;
58
+ }
59
+ }
50
60
  const body = JSON.stringify(discovery);
51
61
  return simpleResponse(200, {
52
- "content-type": manifestVersion === 2 ? ENDPOINT_MANIFEST_V2 : manifestVersion === 3 ? ENDPOINT_MANIFEST_V3 : ENDPOINT_MANIFEST_V4,
62
+ "content-type": manifestVersion === 2 ? ENDPOINT_MANIFEST_V2 : manifestVersion === 3 ? ENDPOINT_MANIFEST_V3 : manifestVersion === 4 ? ENDPOINT_MANIFEST_V4 : ENDPOINT_MANIFEST_V5,
53
63
  "x-restate-server": X_RESTATE_SERVER
54
64
  }, new TextEncoder().encode(body));
55
65
  }
@@ -1 +1 @@
1
- {"version":3,"file":"discovery.js","names":["error"],"sources":["../../../src/endpoint/handlers/discovery.ts"],"sourcesContent":["import type { RestateResponse } from \"./types.js\";\nimport type { Endpoint } from \"../endpoint.js\";\nimport type {\n Endpoint as EndpointManifest,\n ProtocolMode,\n} from \"../discovery.js\";\nimport { X_RESTATE_SERVER } from \"../../user_agent.js\";\nimport { errorResponse, simpleResponse } from \"./utils.js\";\n\nconst ENDPOINT_MANIFEST_V2 = \"application/vnd.restate.endpointmanifest.v2+json\";\nconst ENDPOINT_MANIFEST_V3 = \"application/vnd.restate.endpointmanifest.v3+json\";\nconst ENDPOINT_MANIFEST_V4 = \"application/vnd.restate.endpointmanifest.v4+json\";\n\nexport function handleDiscovery(\n endpoint: Endpoint,\n protocolMode: ProtocolMode,\n additionalDiscoveryFields: Partial<EndpointManifest>,\n acceptVersionsString: string | string[] | undefined\n): RestateResponse {\n if (typeof acceptVersionsString !== \"string\") {\n const errorMessage = \"Missing accept header\";\n endpoint.rlog.warn(errorMessage);\n return errorResponse(415, errorMessage);\n }\n\n // Negotiate version to use\n let manifestVersion;\n if (acceptVersionsString.includes(ENDPOINT_MANIFEST_V4)) {\n manifestVersion = 4;\n } else if (acceptVersionsString.includes(ENDPOINT_MANIFEST_V3)) {\n manifestVersion = 3;\n } else if (acceptVersionsString.includes(ENDPOINT_MANIFEST_V2)) {\n manifestVersion = 2;\n } else {\n const errorMessage = `Unsupported service discovery protocol version '${acceptVersionsString}'`;\n endpoint.rlog.warn(errorMessage);\n return errorResponse(415, errorMessage);\n }\n\n const discovery = {\n ...endpoint.discoveryMetadata,\n ...additionalDiscoveryFields,\n protocolMode: protocolMode,\n };\n\n const checkUnsupportedFeature = <T extends object>(\n obj: T,\n ...fields: Array<keyof T>\n ) => {\n for (const field of fields) {\n if (field in obj && obj[field] !== undefined) {\n return errorResponse(\n 500,\n `The code uses the new discovery feature '${String(\n field\n )}' but the runtime doesn't support it yet (discovery protocol negotiated version ${manifestVersion}). Either remove the usage of this feature, or upgrade the runtime.`\n );\n }\n }\n return;\n };\n\n // Verify none of the manifest v3 configuration options are used.\n if (manifestVersion < 3) {\n for (const service of discovery.services) {\n const error = checkUnsupportedFeature(\n service,\n \"journalRetention\",\n \"idempotencyRetention\",\n \"inactivityTimeout\",\n \"abortTimeout\",\n \"enableLazyState\",\n \"ingressPrivate\"\n );\n if (error !== undefined) {\n return error;\n }\n for (const handler of service.handlers) {\n const error = checkUnsupportedFeature(\n handler,\n \"journalRetention\",\n \"idempotencyRetention\",\n \"workflowCompletionRetention\",\n \"inactivityTimeout\",\n \"abortTimeout\",\n \"enableLazyState\",\n \"ingressPrivate\"\n );\n if (error !== undefined) {\n return error;\n }\n }\n }\n }\n\n if (manifestVersion < 4) {\n // Blank the lambda compression field. No need to fail in this case.\n discovery.lambdaCompression = undefined;\n for (const service of discovery.services) {\n const error = checkUnsupportedFeature(\n service,\n \"retryPolicyExponentiationFactor\",\n \"retryPolicyInitialInterval\",\n \"retryPolicyMaxAttempts\",\n \"retryPolicyMaxInterval\",\n \"retryPolicyOnMaxAttempts\"\n );\n if (error !== undefined) {\n return error;\n }\n for (const handler of service.handlers) {\n const error = checkUnsupportedFeature(\n handler,\n \"retryPolicyExponentiationFactor\",\n \"retryPolicyInitialInterval\",\n \"retryPolicyMaxAttempts\",\n \"retryPolicyMaxInterval\",\n \"retryPolicyOnMaxAttempts\"\n );\n if (error !== undefined) {\n return error;\n }\n }\n }\n }\n\n const body = JSON.stringify(discovery);\n return simpleResponse(\n 200,\n {\n \"content-type\":\n manifestVersion === 2\n ? ENDPOINT_MANIFEST_V2\n : manifestVersion === 3\n ? ENDPOINT_MANIFEST_V3\n : ENDPOINT_MANIFEST_V4,\n \"x-restate-server\": X_RESTATE_SERVER,\n },\n new TextEncoder().encode(body)\n );\n}\n"],"mappings":";;;;AASA,MAAM,uBAAuB;AAC7B,MAAM,uBAAuB;AAC7B,MAAM,uBAAuB;AAE7B,SAAgB,gBACd,UACA,cACA,2BACA,sBACiB;AACjB,KAAI,OAAO,yBAAyB,UAAU;EAC5C,MAAM,eAAe;AACrB,WAAS,KAAK,KAAK,aAAa;AAChC,SAAO,cAAc,KAAK,aAAa;;CAIzC,IAAI;AACJ,KAAI,qBAAqB,SAAS,qBAAqB,CACrD,mBAAkB;UACT,qBAAqB,SAAS,qBAAqB,CAC5D,mBAAkB;UACT,qBAAqB,SAAS,qBAAqB,CAC5D,mBAAkB;MACb;EACL,MAAM,eAAe,mDAAmD,qBAAqB;AAC7F,WAAS,KAAK,KAAK,aAAa;AAChC,SAAO,cAAc,KAAK,aAAa;;CAGzC,MAAM,YAAY;EAChB,GAAG,SAAS;EACZ,GAAG;EACW;EACf;CAED,MAAM,2BACJ,KACA,GAAG,WACA;AACH,OAAK,MAAM,SAAS,OAClB,KAAI,SAAS,OAAO,IAAI,WAAW,OACjC,QAAO,cACL,KACA,4CAA4C,OAC1C,MACD,CAAC,kFAAkF,gBAAgB,qEACrG;;AAOP,KAAI,kBAAkB,EACpB,MAAK,MAAM,WAAW,UAAU,UAAU;EACxC,MAAM,QAAQ,wBACZ,SACA,oBACA,wBACA,qBACA,gBACA,mBACA,iBACD;AACD,MAAI,UAAU,OACZ,QAAO;AAET,OAAK,MAAM,WAAW,QAAQ,UAAU;GACtC,MAAMA,UAAQ,wBACZ,SACA,oBACA,wBACA,+BACA,qBACA,gBACA,mBACA,iBACD;AACD,OAAIA,YAAU,OACZ,QAAOA;;;AAMf,KAAI,kBAAkB,GAAG;AAEvB,YAAU,oBAAoB;AAC9B,OAAK,MAAM,WAAW,UAAU,UAAU;GACxC,MAAM,QAAQ,wBACZ,SACA,mCACA,8BACA,0BACA,0BACA,2BACD;AACD,OAAI,UAAU,OACZ,QAAO;AAET,QAAK,MAAM,WAAW,QAAQ,UAAU;IACtC,MAAMA,UAAQ,wBACZ,SACA,mCACA,8BACA,0BACA,0BACA,2BACD;AACD,QAAIA,YAAU,OACZ,QAAOA;;;;CAMf,MAAM,OAAO,KAAK,UAAU,UAAU;AACtC,QAAO,eACL,KACA;EACE,gBACE,oBAAoB,IAChB,uBACA,oBAAoB,IAClB,uBACA;EACR,oBAAoB;EACrB,EACD,IAAI,aAAa,CAAC,OAAO,KAAK,CAC/B"}
1
+ {"version":3,"file":"discovery.js","names":["error"],"sources":["../../../src/endpoint/handlers/discovery.ts"],"sourcesContent":["import type { RestateResponse } from \"./types.js\";\nimport type { Endpoint } from \"../endpoint.js\";\nimport type {\n Endpoint as EndpointManifest,\n ProtocolMode,\n} from \"../discovery.js\";\nimport { X_RESTATE_SERVER } from \"../../user_agent.js\";\nimport { errorResponse, simpleResponse } from \"./utils.js\";\n\nconst ENDPOINT_MANIFEST_V2 = \"application/vnd.restate.endpointmanifest.v2+json\";\nconst ENDPOINT_MANIFEST_V3 = \"application/vnd.restate.endpointmanifest.v3+json\";\nconst ENDPOINT_MANIFEST_V4 = \"application/vnd.restate.endpointmanifest.v4+json\";\nconst ENDPOINT_MANIFEST_V5 = \"application/vnd.restate.endpointmanifest.v5+json\";\n\nexport function handleDiscovery(\n endpoint: Endpoint,\n protocolMode: ProtocolMode,\n additionalDiscoveryFields: Partial<EndpointManifest>,\n acceptVersionsString: string | string[] | undefined\n): RestateResponse {\n if (typeof acceptVersionsString !== \"string\") {\n const errorMessage = \"Missing accept header\";\n endpoint.rlog.warn(errorMessage);\n return errorResponse(415, errorMessage);\n }\n\n // Negotiate version to use\n let manifestVersion;\n if (acceptVersionsString.includes(ENDPOINT_MANIFEST_V5)) {\n manifestVersion = 5;\n } else if (acceptVersionsString.includes(ENDPOINT_MANIFEST_V4)) {\n manifestVersion = 4;\n } else if (acceptVersionsString.includes(ENDPOINT_MANIFEST_V3)) {\n manifestVersion = 3;\n } else if (acceptVersionsString.includes(ENDPOINT_MANIFEST_V2)) {\n manifestVersion = 2;\n } else {\n const errorMessage = `Unsupported service discovery protocol version '${acceptVersionsString}'`;\n endpoint.rlog.warn(errorMessage);\n return errorResponse(415, errorMessage);\n }\n\n const discovery = {\n ...endpoint.discoveryMetadata,\n ...additionalDiscoveryFields,\n protocolMode: protocolMode,\n };\n\n const checkUnsupportedFeature = <T extends object>(\n obj: T,\n ...fields: Array<keyof T>\n ) => {\n for (const field of fields) {\n if (field in obj && obj[field] !== undefined) {\n return errorResponse(\n 500,\n `The code uses the new discovery feature '${String(\n field\n )}' but the runtime doesn't support it yet (discovery protocol negotiated version ${manifestVersion}). Either remove the usage of this feature, or upgrade the runtime.`\n );\n }\n }\n return;\n };\n\n // Verify none of the manifest v3 configuration options are used.\n if (manifestVersion < 3) {\n for (const service of discovery.services) {\n const error = checkUnsupportedFeature(\n service,\n \"journalRetention\",\n \"idempotencyRetention\",\n \"inactivityTimeout\",\n \"abortTimeout\",\n \"enableLazyState\",\n \"ingressPrivate\"\n );\n if (error !== undefined) {\n return error;\n }\n for (const handler of service.handlers) {\n const error = checkUnsupportedFeature(\n handler,\n \"journalRetention\",\n \"idempotencyRetention\",\n \"workflowCompletionRetention\",\n \"inactivityTimeout\",\n \"abortTimeout\",\n \"enableLazyState\",\n \"ingressPrivate\"\n );\n if (error !== undefined) {\n return error;\n }\n }\n }\n }\n\n if (manifestVersion < 4) {\n // Blank the lambda compression field. No need to fail in this case.\n discovery.lambdaCompression = undefined;\n for (const service of discovery.services) {\n const error = checkUnsupportedFeature(\n service,\n \"retryPolicyExponentiationFactor\",\n \"retryPolicyInitialInterval\",\n \"retryPolicyMaxAttempts\",\n \"retryPolicyMaxInterval\",\n \"retryPolicyOnMaxAttempts\"\n );\n if (error !== undefined) {\n return error;\n }\n for (const handler of service.handlers) {\n const error = checkUnsupportedFeature(\n handler,\n \"retryPolicyExponentiationFactor\",\n \"retryPolicyInitialInterval\",\n \"retryPolicyMaxAttempts\",\n \"retryPolicyMaxInterval\",\n \"retryPolicyOnMaxAttempts\"\n );\n if (error !== undefined) {\n return error;\n }\n }\n }\n }\n\n // Verify none of the manifest v5 configuration options are used.\n // Note: `enableLazyState` itself is already available since v3; only the\n // eager-state whitelist (selective preloading) requires v5.\n if (manifestVersion < 5) {\n for (const service of discovery.services) {\n const error = checkUnsupportedFeature(service, \"eagerStateKeysWhitelist\");\n if (error !== undefined) {\n return error;\n }\n for (const handler of service.handlers) {\n const error = checkUnsupportedFeature(\n handler,\n \"eagerStateKeysWhitelist\"\n );\n if (error !== undefined) {\n return error;\n }\n }\n }\n }\n\n const body = JSON.stringify(discovery);\n return simpleResponse(\n 200,\n {\n \"content-type\":\n manifestVersion === 2\n ? ENDPOINT_MANIFEST_V2\n : manifestVersion === 3\n ? ENDPOINT_MANIFEST_V3\n : manifestVersion === 4\n ? ENDPOINT_MANIFEST_V4\n : ENDPOINT_MANIFEST_V5,\n \"x-restate-server\": X_RESTATE_SERVER,\n },\n new TextEncoder().encode(body)\n );\n}\n"],"mappings":";;;;AASA,MAAM,uBAAuB;AAC7B,MAAM,uBAAuB;AAC7B,MAAM,uBAAuB;AAC7B,MAAM,uBAAuB;AAE7B,SAAgB,gBACd,UACA,cACA,2BACA,sBACiB;AACjB,KAAI,OAAO,yBAAyB,UAAU;EAC5C,MAAM,eAAe;AACrB,WAAS,KAAK,KAAK,aAAa;AAChC,SAAO,cAAc,KAAK,aAAa;;CAIzC,IAAI;AACJ,KAAI,qBAAqB,SAAS,qBAAqB,CACrD,mBAAkB;UACT,qBAAqB,SAAS,qBAAqB,CAC5D,mBAAkB;UACT,qBAAqB,SAAS,qBAAqB,CAC5D,mBAAkB;UACT,qBAAqB,SAAS,qBAAqB,CAC5D,mBAAkB;MACb;EACL,MAAM,eAAe,mDAAmD,qBAAqB;AAC7F,WAAS,KAAK,KAAK,aAAa;AAChC,SAAO,cAAc,KAAK,aAAa;;CAGzC,MAAM,YAAY;EAChB,GAAG,SAAS;EACZ,GAAG;EACW;EACf;CAED,MAAM,2BACJ,KACA,GAAG,WACA;AACH,OAAK,MAAM,SAAS,OAClB,KAAI,SAAS,OAAO,IAAI,WAAW,OACjC,QAAO,cACL,KACA,4CAA4C,OAC1C,MACD,CAAC,kFAAkF,gBAAgB,qEACrG;;AAOP,KAAI,kBAAkB,EACpB,MAAK,MAAM,WAAW,UAAU,UAAU;EACxC,MAAM,QAAQ,wBACZ,SACA,oBACA,wBACA,qBACA,gBACA,mBACA,iBACD;AACD,MAAI,UAAU,OACZ,QAAO;AAET,OAAK,MAAM,WAAW,QAAQ,UAAU;GACtC,MAAMA,UAAQ,wBACZ,SACA,oBACA,wBACA,+BACA,qBACA,gBACA,mBACA,iBACD;AACD,OAAIA,YAAU,OACZ,QAAOA;;;AAMf,KAAI,kBAAkB,GAAG;AAEvB,YAAU,oBAAoB;AAC9B,OAAK,MAAM,WAAW,UAAU,UAAU;GACxC,MAAM,QAAQ,wBACZ,SACA,mCACA,8BACA,0BACA,0BACA,2BACD;AACD,OAAI,UAAU,OACZ,QAAO;AAET,QAAK,MAAM,WAAW,QAAQ,UAAU;IACtC,MAAMA,UAAQ,wBACZ,SACA,mCACA,8BACA,0BACA,0BACA,2BACD;AACD,QAAIA,YAAU,OACZ,QAAOA;;;;AASf,KAAI,kBAAkB,EACpB,MAAK,MAAM,WAAW,UAAU,UAAU;EACxC,MAAM,QAAQ,wBAAwB,SAAS,0BAA0B;AACzE,MAAI,UAAU,OACZ,QAAO;AAET,OAAK,MAAM,WAAW,QAAQ,UAAU;GACtC,MAAMA,UAAQ,wBACZ,SACA,0BACD;AACD,OAAIA,YAAU,OACZ,QAAOA;;;CAMf,MAAM,OAAO,KAAK,UAAU,UAAU;AACtC,QAAO,eACL,KACA;EACE,gBACE,oBAAoB,IAChB,uBACA,oBAAoB,IAClB,uBACA,oBAAoB,IAClB,uBACA;EACV,oBAAoB;EACrB,EACD,IAAI,aAAa,CAAC,OAAO,KAAK,CAC/B"}
@@ -113,7 +113,7 @@ var RestateInvokeResponse = class {
113
113
  this.loggerId = Math.floor(Math.random() * 4294967295);
114
114
  const isJournalCodecDefined = this.journalValueCodecInit !== void 0;
115
115
  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));
116
- 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, onJournalMismatchErrorsToWasm(handler.executionOptions.onJournalMismatchErrors));
116
+ 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, onJournalMismatchErrorsToWasm(handler.executionOptions.onJournalMismatchErrors), handler.executionOptions.explicitRecovery ?? false);
117
117
  const responseHead = this.coreVm.get_response_head();
118
118
  this.statusCode = responseHead.status_code;
119
119
  this.headers = responseHead.headers.reduce((headers, { key, value }) => ({
@@ -111,7 +111,7 @@ var RestateInvokeResponse = class {
111
111
  this.loggerId = Math.floor(Math.random() * 4294967295);
112
112
  const isJournalCodecDefined = this.journalValueCodecInit !== void 0;
113
113
  const vmHeaders = Object.entries(this.attemptHeaders).filter(([, v]) => v !== void 0).map(([k, v]) => new WasmHeader(k, v instanceof Array ? v[0] : v));
114
- this.coreVm = new WasmVM(vmHeaders, restateLogLevelToWasmLogLevel(DEFAULT_CONSOLE_LOGGER_LOG_LEVEL), this.loggerId, isJournalCodecDefined, handler.executionOptions.explicitCancellation ?? false, onJournalMismatchErrorsToWasm(handler.executionOptions.onJournalMismatchErrors));
114
+ this.coreVm = new WasmVM(vmHeaders, restateLogLevelToWasmLogLevel(DEFAULT_CONSOLE_LOGGER_LOG_LEVEL), this.loggerId, isJournalCodecDefined, handler.executionOptions.explicitCancellation ?? false, onJournalMismatchErrorsToWasm(handler.executionOptions.onJournalMismatchErrors), handler.executionOptions.explicitRecovery ?? false);
115
115
  const responseHead = this.coreVm.get_response_head();
116
116
  this.statusCode = responseHead.status_code;
117
117
  this.headers = responseHead.headers.reduce((headers, { key, value }) => ({
@@ -1 +1 @@
1
- {"version":3,"file":"generic.js","names":["endpoint: Endpoint","protocolMode: ProtocolMode","additionalDiscoveryFields: Partial<EndpointManifest>","vm.WasmIdentityVerifier","vm.WasmHeader","service: Component","handler: ComponentHandler","attemptHeaders: Headers","extraArgs: unknown[]","additionalContext: AdditionalContext","journalValueCodecInit:\n | Promise<JournalValueCodec>\n | undefined","loggerTransport: LoggerTransport","vm.WasmVM","journalValueCodec: JournalValueCodec","ctx: ContextImpl","invocationRequest: Request","hooks: Hooks[]","hookContext: { request: Request }","encodedOutput: Uint8Array | undefined","originalError: unknown"],"sources":["../../../src/endpoint/handlers/generic.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 {\n ensureError,\n logError,\n PauseError,\n RestateError,\n RetryableError,\n TerminalError,\n} from \"../../types/errors.js\";\nimport type {\n Endpoint as EndpointManifest,\n ProtocolMode,\n} from \"../discovery.js\";\nimport {\n Component,\n ComponentHandler,\n InvokePathComponents,\n} from \"../components.js\";\nimport { parseUrlComponents } from \"../components.js\";\nimport { X_RESTATE_SERVER } from \"../../user_agent.js\";\nimport { CommandError, ContextImpl } from \"../../context_impl.js\";\nimport { restoreError, sanitizeError } from \"../../error_sanitization.js\";\nimport type { InvocationId, Request } from \"../../context.js\";\nimport * as vm from \"./vm/sdk_shared_core_wasm_bindings.js\";\nimport { HandlerKind } from \"../../types/rpc.js\";\nimport { createLogger, type Logger } from \"../../logging/logger.js\";\nimport { DEFAULT_CONSOLE_LOGGER_LOG_LEVEL } from \"../../logging/console_logger_transport.js\";\nimport {\n LoggerContext,\n LoggerTransport,\n LogSource,\n RestateLogLevel,\n} from \"../../logging/logger_transport.js\";\nimport {\n type JournalValueCodec,\n millisOrDurationToMillis,\n} from \"@restatedev/restate-sdk-core\";\nimport type { Endpoint } from \"../endpoint.js\";\nimport {\n type RestateHandler,\n type Headers,\n type RestateRequest,\n type AdditionalContext,\n type RestateResponse,\n ResponseHeaders,\n InputReader,\n OutputWriter,\n} from \"./types.js\";\nimport { handleDiscovery } from \"./discovery.js\";\nimport { handlePreview } from \"./preview.js\";\nimport {\n errorResponse,\n invocationIdFromHeaders,\n simpleResponse,\n tryCreateContextualLogger,\n} from \"./utils.js\";\nimport { destroyLogger, registerLogger } from \"./core_logging.js\";\nimport type { Hooks } from \"../../hooks.js\";\n\n// Hidden symbol key used by first-party hooks to read the live\n// replay/processing phase without widening the public HooksProvider API.\nconst HOOK_CONTEXT_IS_PROCESSING_SYMBOL = Symbol.for(\n \"@restatedev/restate-sdk/hooks.isProcessing\"\n);\n\nexport function createRestateHandler(\n endpoint: Endpoint,\n protocolMode: ProtocolMode,\n additionalDiscoveryFields: Partial<EndpointManifest>\n): RestateHandler {\n return new RestateHandlerImpl(\n endpoint,\n protocolMode,\n additionalDiscoveryFields\n );\n}\n\n/**\n * This is the RestateHandler implementation\n */\nclass RestateHandlerImpl implements RestateHandler {\n private readonly identityVerifier?: vm.WasmIdentityVerifier;\n\n constructor(\n readonly endpoint: Endpoint,\n private readonly protocolMode: ProtocolMode,\n private readonly additionalDiscoveryFields: Partial<EndpointManifest>\n ) {\n // Setup identity verifier\n if (\n this.endpoint.keySet === undefined ||\n this.endpoint.keySet.length === 0\n ) {\n this.endpoint.rlog.warn(\n `Accepting requests without validating request signatures; handler access must be restricted`\n );\n } else {\n this.endpoint.rlog.info(\n `Validating requests using signing keys [${this.endpoint.keySet}]`\n );\n this.identityVerifier = new vm.WasmIdentityVerifier(this.endpoint.keySet);\n }\n\n // Set the logging level in the shared core too!\n vm.set_log_level(\n restateLogLevelToWasmLogLevel(DEFAULT_CONSOLE_LOGGER_LOG_LEVEL)\n );\n }\n\n // handle does not throw.\n public handle(\n request: RestateRequest,\n context?: AdditionalContext\n ): RestateResponse {\n try {\n return this._handle(request, context);\n } catch (e) {\n const error = ensureError(e);\n (\n tryCreateContextualLogger(\n this.endpoint.loggerTransport,\n request.url,\n request.headers\n ) ?? this.endpoint.rlog\n ).error(\n \"Error while handling request: \" + (error.stack ?? error.message)\n );\n return errorResponse(\n error instanceof RestateError ? error.code : 500,\n error.message\n );\n }\n }\n\n private _handle(\n request: RestateRequest,\n context?: AdditionalContext\n ): RestateResponse {\n // this is the recommended way to get the relative path from a url that may be relative or absolute\n const path = new URL(request.url, \"https://example.com\").pathname;\n const parsed = parseUrlComponents(path);\n\n if (parsed.type === \"unknown\") {\n const msg =\n \"Invalid path. Allowed are /health, /discover, /invoke/SvcName/handlerName, \" +\n \"/serdes/SvcName/decode/<serdeName>, or \" +\n \"/serdes/SvcName/encode/<serdeName>, but was: \" +\n path;\n this.endpoint.rlog.trace(msg);\n return errorResponse(404, msg);\n }\n if (parsed.type === \"health\") {\n return simpleResponse(\n 200,\n {\n \"content-type\": \"application/text\",\n \"x-restate-server\": X_RESTATE_SERVER,\n },\n new TextEncoder().encode(\"OK\")\n );\n }\n\n // Discovery, preview, and handling invocations require identity verification\n const error = this.validateConnectionSignature(path, request.headers);\n if (error !== null) {\n return error;\n }\n if (parsed.type === \"discover\") {\n return handleDiscovery(\n this.endpoint,\n this.protocolMode,\n this.additionalDiscoveryFields,\n request.headers[\"accept\"]\n );\n }\n if (parsed.type === \"preview\") {\n return handlePreview(this.endpoint, parsed);\n }\n\n return this.handleInvoke(\n parsed,\n request.headers,\n request.extraArgs,\n context ?? {}\n );\n }\n\n private validateConnectionSignature(\n path: string,\n headers: Headers\n ): RestateResponse | null {\n if (!this.identityVerifier) {\n // not validating\n return null;\n }\n\n const vmHeaders = Object.entries(headers)\n .filter(([, v]) => v !== undefined)\n .map(\n ([k, v]) =>\n new vm.WasmHeader(k, v instanceof Array ? v[0]! : (v as string))\n );\n\n try {\n this.identityVerifier.verify_identity(path, vmHeaders);\n return null;\n } catch (e) {\n this.endpoint.rlog.error(\n // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n `Rejecting request as its JWT did not validate: ${e}`\n );\n return errorResponse(401, \"Unauthorized\");\n }\n }\n\n private handleInvoke(\n invokePathComponent: InvokePathComponents,\n headers: Headers,\n extraArgs: unknown[],\n additionalContext: AdditionalContext\n ): RestateResponse {\n // Check if we support this protocol version\n const serviceProtocolVersionString = headers[\"content-type\"];\n if (typeof serviceProtocolVersionString !== \"string\") {\n const errorMessage = \"Missing content-type header\";\n this.endpoint.rlog.warn(errorMessage);\n return errorResponse(415, errorMessage);\n }\n\n const service = this.endpoint.components.get(\n invokePathComponent.componentName\n );\n if (!service) {\n const msg = `No service found for URL: ${JSON.stringify(invokePathComponent)}`;\n this.endpoint.rlog.error(msg);\n return errorResponse(404, msg);\n }\n\n const handler = service.handlerMatching(invokePathComponent);\n if (!handler) {\n const msg = `No handler found for URL: ${JSON.stringify(invokePathComponent)}`;\n this.endpoint.rlog.error(msg);\n return errorResponse(404, msg);\n }\n\n return new RestateInvokeResponse(\n service,\n handler,\n headers,\n extraArgs,\n additionalContext,\n this.endpoint.journalValueCodec,\n this.endpoint.loggerTransport\n );\n }\n}\n\nclass RestateInvokeResponse implements RestateResponse {\n private readonly headers: ResponseHeaders;\n private readonly statusCode: number;\n\n private readonly loggerId: number;\n private vmLogger: Logger;\n private readonly coreVm: vm.WasmVM;\n\n constructor(\n private readonly service: Component,\n private readonly handler: ComponentHandler,\n private readonly attemptHeaders: Headers,\n private readonly extraArgs: unknown[],\n private readonly additionalContext: AdditionalContext,\n private readonly journalValueCodecInit:\n | Promise<JournalValueCodec>\n | undefined,\n private readonly loggerTransport: LoggerTransport\n ) {\n this.loggerId = Math.floor(Math.random() * 4_294_967_295 /* u32::MAX */);\n const isJournalCodecDefined = this.journalValueCodecInit !== undefined;\n\n // Instantiate core vm and prepare response headers\n const vmHeaders = Object.entries(this.attemptHeaders)\n .filter(([, v]) => v !== undefined)\n .map(\n ([k, v]) =>\n new vm.WasmHeader(k, v instanceof Array ? v[0]! : (v as string))\n );\n this.coreVm = new vm.WasmVM(\n vmHeaders,\n restateLogLevelToWasmLogLevel(DEFAULT_CONSOLE_LOGGER_LOG_LEVEL),\n this.loggerId,\n isJournalCodecDefined,\n handler.executionOptions.explicitCancellation ?? false,\n onJournalMismatchErrorsToWasm(\n handler.executionOptions.onJournalMismatchErrors\n )\n );\n const responseHead = this.coreVm.get_response_head();\n this.statusCode = responseHead.status_code;\n this.headers = responseHead.headers.reduce(\n (headers, { key, value }) => ({\n [key]: value,\n ...headers,\n }),\n {\n \"x-restate-server\": X_RESTATE_SERVER,\n }\n );\n this.vmLogger = createLogger(\n this.loggerTransport,\n LogSource.JOURNAL,\n new LoggerContext(\n invocationIdFromHeaders(this.attemptHeaders),\n this.service.name(),\n this.handler.name(),\n undefined,\n undefined,\n this.additionalContext\n )\n );\n }\n\n async process({\n inputReader,\n outputWriter,\n writeHead,\n abortSignal,\n }: {\n inputReader: InputReader;\n outputWriter: OutputWriter;\n writeHead: (statusCode: number, headers: ResponseHeaders) => void;\n abortSignal: AbortSignal;\n }): Promise<void> {\n // Commit the response head immediately — the VM-determined head is known\n // at construction time and never changes during processing.\n writeHead(this.statusCode, this.headers);\n\n abortSignal.addEventListener(\n \"abort\",\n () => {\n // In any case, on abort remove the invocation logger to avoid memory leaks\n destroyLogger(this.loggerId);\n\n // When the HTTP connection closes (e.g. abort timeout), poison the VM.\n // We only read new input from the server when a Restate command is\n // waiting for a response. If no command has been issued, the server's\n // abort signal is never read. Poisoning the VM ensures the handler\n // fails on the next VM call (e.g. ctx.run, ctx.sleep).\n setImmediate(() => {\n const msg = \"Connection closed\";\n this.coreVm.notify_error(msg, msg);\n });\n },\n { once: true }\n );\n // Use a default logger that still respects the endpoint custom logger\n // We will override this later with a logger that has a LoggerContext\n // See vm_log below for more details\n registerLogger(this.loggerId, this.vmLogger);\n\n const journalValueCodec: JournalValueCodec = this.journalValueCodecInit\n ? await this.journalValueCodecInit\n : {\n encode: (entry) => entry,\n decode: (entry) => Promise.resolve(entry),\n };\n\n // This promise is used to signal the end of the computation,\n // which can be either the user returns a value,\n // or an exception gets caught, or the state machine fails/suspends.\n //\n // The last case is handled internally within the ContextImpl.\n const invocationEndPromise = Promise.withResolvers<void>();\n let ctx: ContextImpl;\n\n // Initial phase before running user code\n // -> Buffer in shared core the journal entries\n // -> Initiate loggers\n // -> Initialize the ContextImpl\n try {\n // Buffer journal inside shared core\n await bufferJournalReplayInCoreVm(this.coreVm, inputReader);\n\n // Get input from coreVm to build the request object\n const input = this.coreVm.sys_input();\n const invocationRequest: Request = {\n target: {\n service: this.service.name(),\n handler: this.handler.name(),\n key: input.key || undefined,\n toString() {\n return this.key !== undefined\n ? `${this.service}/${this.key}/${this.handler}`\n : `${this.service}/${this.handler}`;\n },\n },\n id: input.invocation_id as InvocationId,\n headers: input.headers.reduce((headers, { key, value }) => {\n headers.set(key, value);\n return headers;\n }, new Map()),\n attemptHeaders: Object.entries(this.attemptHeaders).reduce(\n (headers, [key, value]) => {\n if (value !== undefined) {\n headers.set(key, value instanceof Array ? value[0] : value);\n }\n return headers;\n },\n new Map()\n ),\n body: input.input,\n extraArgs: this.extraArgs,\n idempotencyKey: input.idempotency_key || undefined,\n scope: input.scope || undefined,\n limitKey: input.limit_key || undefined,\n attemptCompletedSignal: abortSignal,\n };\n\n // Prepare logger\n const loggerContext = new LoggerContext(\n input.invocation_id,\n this.handler.component().name(),\n this.handler.name(),\n this.handler.kind() === HandlerKind.SERVICE ? undefined : input.key,\n invocationRequest,\n this.additionalContext\n );\n const ctxLogger = createLogger(\n this.loggerTransport,\n LogSource.USER,\n loggerContext,\n () => !this.coreVm.is_processing()\n );\n // Override the vmLogger created before with more info!\n this.vmLogger = createLogger(\n this.loggerTransport,\n LogSource.JOURNAL,\n loggerContext\n // Filtering is done within the shared core\n );\n\n // See vm_log below for more details\n registerLogger(this.loggerId, this.vmLogger);\n if (!this.coreVm.is_processing()) {\n this.vmLogger.info(\"Replaying invocation.\");\n } else {\n this.vmLogger.info(\"Starting invocation.\");\n }\n\n // Prepare context\n ctx = new ContextImpl(\n this.coreVm,\n input,\n ctxLogger,\n this.handler.kind(),\n this.vmLogger,\n invocationRequest,\n invocationEndPromise,\n inputReader,\n outputWriter,\n journalValueCodec,\n this.handler.executionOptions\n );\n } catch (e) {\n // That's \"preflight\" failure cases, where stuff fails before running user code\n // In this scenario, we close the coreVm, then flush and close\n const error = ensureError(e);\n this.coreVm.notify_error(error.message, error.message);\n try {\n await flushAndClose(\n this.coreVm,\n this.vmLogger,\n Promise.resolve(inputReader),\n outputWriter\n );\n } finally {\n // Safety net: the abort listener should clean this up when the attempt\n // ends, but process() owns the logger registration, so avoid leaking if\n // an adapter ever fails to abort the attempt-completed signal.\n destroyLogger(this.loggerId);\n }\n return;\n }\n\n // Run user code. Errors that reach the handler or interceptor code\n // (handler throws, interceptor throws, entry completes with terminal\n // failure) propagate naturally. Errors where the handler is stuck on\n // an await that will never settle (e.g. suspension, retryable run\n // error) are broken out by raceWithAttemptEnd, which races against\n // invocationEndPromise — rejected by ContextImpl when the attempt ends.\n try {\n await startUserHandler(\n ctx,\n this.service,\n this.handler,\n journalValueCodec\n );\n } catch (e) {\n notifyError(e, ctx, this.handler.executionOptions.asTerminalError);\n } finally {\n try {\n await flushAndClose(\n this.coreVm,\n this.vmLogger,\n ctx.inputPump.stop(),\n outputWriter\n );\n } finally {\n // Safety net: the abort listener should clean this up when the attempt\n // ends, but process() owns the logger registration, so avoid leaking if\n // an adapter ever fails to abort the attempt-completed signal.\n destroyLogger(this.loggerId);\n }\n }\n }\n}\n\nasync function bufferJournalReplayInCoreVm(\n coreVm: vm.WasmVM,\n inputReader: InputReader\n) {\n while (!coreVm.is_ready_to_execute()) {\n const nextValue = await inputReader.next();\n if (nextValue.done) {\n coreVm.notify_input_closed();\n break;\n }\n if (nextValue.value !== undefined) {\n coreVm.notify_input(nextValue.value);\n }\n }\n}\n\nasync function startUserHandler(\n ctx: ContextImpl,\n service: Component,\n handler: ComponentHandler,\n journalValueCodec: JournalValueCodec\n) {\n // Instantiate hooks from providers.\n // If a provider throws, the same rules as handler failures apply:\n // TerminalError → terminate invocation, other errors → retry.\n const hooks: Hooks[] = [];\n for (const provider of handler.executionOptions.hooks ?? []) {\n const hookContext: { request: Request } = {\n request: ctx.request(),\n };\n Object.defineProperty(hookContext, HOOK_CONTEXT_IS_PROCESSING_SYMBOL, {\n value: () => ctx.isProcessing(),\n enumerable: false,\n });\n hooks.push(provider(hookContext));\n }\n\n // Compose interceptor.handler into a single interceptor (first = outermost)\n const handlerInterceptor = composeInterceptors(\n hooks.map((h) => h.interceptor?.handler).filter(isDefined)\n );\n\n ctx.setRunInterceptor(\n composeInterceptors(hooks.map((h) => h.interceptor?.run).filter(isDefined))\n );\n\n let encodedOutput: Uint8Array | undefined;\n await raceWithAttemptEnd(\n ctx,\n handlerInterceptor\n )(async () => {\n const decodedInput = await journalValueCodec\n .decode(ctx.request().body)\n .catch((e) =>\n // Re-throw as terminal error, to fail on input errors\n Promise.reject(\n new TerminalError(\n `Failed to decode input using journal value codec: ${\n ensureError(e).message\n }`,\n {\n errorCode: 400,\n }\n )\n )\n );\n\n // Then run user code\n const output = await handler.invoke(ctx, decodedInput);\n\n // Encode user code output\n encodedOutput = journalValueCodec.encode(output);\n });\n\n // Interceptor chain completed without error — commit the result.\n // sys_end() is called here (after interceptors) so that interceptor\n // errors after next() correctly prevent the invocation from succeeding.\n ctx.coreVm.sys_write_output_success(encodedOutput!);\n ctx.coreVm.sys_end();\n ctx.vmLogger.info(\"Invocation completed successfully.\");\n}\n\n/**\n * Classifies the error and notifies the VM. Called from the process() catch\n * block — the single place that decides how to report errors to the VM.\n */\nfunction notifyError(\n e: unknown,\n ctx: ContextImpl,\n asTerminalError?: (error: unknown) => TerminalError | undefined\n) {\n // Command-specific errors from ContextImpl carry metadata the VM needs\n // for command correlation. Check before ensureError to preserve the type.\n if (e instanceof CommandError) {\n const cause = ensureError(e.cause);\n logError(ctx.vmLogger, cause);\n if (e.hasCommandIndex) {\n // Completion failure — command exists in the journal\n ctx.coreVm.notify_error_for_specific_command(\n cause.message,\n cause.stack,\n e.commandType,\n e.commandIndex!,\n null\n );\n } else {\n // Preparation failure — command not yet issued\n ctx.coreVm.notify_error_for_next_command(\n cause.message,\n cause.stack,\n e.commandType\n );\n }\n return;\n }\n\n // Handler/interceptor errors\n const error = ensureError(e, asTerminalError);\n logError(ctx.vmLogger, error);\n\n try {\n if (error instanceof TerminalError) {\n // Terminal: write the failure as the invocation output\n ctx.coreVm.sys_write_output_failure({\n code: error.code,\n message: error.message,\n metadata: Object.entries(error.metadata ?? {}).map(([key, value]) => ({\n key,\n value,\n })),\n });\n ctx.coreVm.sys_end();\n } else if (error instanceof RetryableError) {\n // Retryable with explicit delay\n ctx.coreVm.notify_error_with_delay_override(\n error.message,\n error.stack,\n error.retryAfter !== undefined\n ? BigInt(millisOrDurationToMillis(error.retryAfter))\n : undefined\n );\n } else {\n if (error instanceof PauseError) {\n ctx.vmLogger.warn(\n \"Throwing PauseError from the handler context will be ignored, \" +\n \"as it leads to pause loops. You should use PauseError only inside `ctx.run`\"\n );\n }\n\n // Transient error — VM decides retry policy\n ctx.coreVm.notify_error(error.message, error.stack);\n }\n } catch (vmError) {\n // Safety net: if sys_write_output_failure or other VM calls fail,\n // fall back to notify_error.\n const inner = ensureError(vmError);\n ctx.coreVm.notify_error(inner.message, inner.stack);\n }\n}\n\nasync function flushAndClose(\n coreVm: vm.WasmVM,\n vmLogger: Logger,\n inputReaderGetter: Promise<InputReader>,\n outputWriter: OutputWriter\n): Promise<void> {\n let inputClosed = false;\n try {\n // Consume vm output buffer, write it out, then close the stream\n const nextOutput = coreVm.take_output();\n if (nextOutput?.length > 0) {\n await outputWriter.write(nextOutput);\n }\n\n // --- After this point, we should have flushed the shared core internal buffer\n\n // Wait for the input reader.\n // In case we executed the user code, this is wired up to the InputPump.stop()\n // to make sure there is only one reader for inputReader.\n const inputReader = await inputReaderGetter;\n\n // Let's make sure we properly close the request stream before closing the response stream\n while (!inputClosed) {\n try {\n const res = await inputReader.next();\n inputClosed = res.done ?? false;\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n } catch (e) {\n inputClosed = true;\n }\n }\n\n // Close the response stream\n await outputWriter.close();\n } catch (e) {\n // In case of failure, we can do little here except just logging stuff out,\n // because outputWriter is not usable here.\n const error = ensureError(e);\n const abortErrorOnWrite = isAbortErrorOnWrite(error);\n\n if (inputClosed && abortErrorOnWrite) {\n // Because we closed the input already,\n // these errors are benign and are caused by\n // synchronization issues wrt closing the response stream in the runtime\n // This will be fixed in the runtime with https://github.com/restatedev/restate/issues/4456\n return;\n }\n\n if (abortErrorOnWrite) {\n vmLogger.error(\n \"Got abort error from connection: \" +\n error.message +\n \"\\n\" +\n \"This might indicate that:\\n\" +\n \"* The restate-server aborted the connection after hitting the 'abort-timeout'\\n\" +\n \"* The connection with the restate-server was lost\\n\" +\n \"\\n\" +\n \"Please check the invocation in the Restate UI for more details.\"\n );\n } else {\n vmLogger.error(\n \"Error while handling request: \" + (error.stack ?? error.message)\n );\n }\n }\n}\n\nfunction isAbortErrorOnWrite(error: Error) {\n return (\n error.name === \"AbortError\" ||\n error.message === \"Invalid state: WritableStream is closed\" ||\n /**\n * Node stream closed error thrown on writes\n */\n (error as { code?: string }).code === \"ERR_HTTP2_INVALID_STREAM\"\n );\n}\n\n// -- Hook composition utils --------------------------------------------------\n\ntype InterceptorFn<Args extends unknown[]> = (\n ...args: [...Args, () => Promise<void>]\n) => Promise<void>;\n\nfunction composeInterceptors<Args extends unknown[]>(\n interceptors: InterceptorFn<Args>[]\n): InterceptorFn<Args> {\n return interceptors.reduceRight<InterceptorFn<Args>>(\n (innerInterceptor, interceptor) =>\n (...args) => {\n const context = args.slice(0, -1) as unknown as Args;\n const callback = args.at(-1) as () => Promise<void>;\n return interceptor(...context, () =>\n innerInterceptor(...context, callback)\n );\n },\n (...args) => (args.at(-1) as () => Promise<void>)()\n );\n}\n\n/**\n * Wraps an interceptor so that both `next()` and the interceptor body race\n * against `invocationEndPromise`. When the attempt ends (suspension, retryable\n * error, etc.), the promise rejects and the interceptor chain unwinds through\n * catch/finally blocks — preventing interceptors from hanging on a `next()`\n * that will never settle.\n *\n * SDK-internal metadata (CommandError, retryAfter) is stripped before the\n * interceptor sees the error and restored after the chain exits.\n */\nfunction raceWithAttemptEnd<Args extends unknown[]>(\n ctx: ContextImpl,\n interceptor: InterceptorFn<Args>\n): InterceptorFn<Args> {\n return (...args) => {\n let originalError: unknown;\n\n // Strip SDK metadata before interceptors see the error.\n // Store the original in the closure for restoration after the chain.\n const signal = ctx.invocationEndPromise.promise.catch((e) => {\n originalError = e;\n throw sanitizeError(e);\n }) as Promise<never>;\n\n const originalNext = args.at(-1) as () => Promise<void>;\n const racingNext = () => Promise.race([originalNext(), signal]);\n const newArgs = [...args.slice(0, -1), racingNext] as unknown as [\n ...Args,\n () => Promise<void>,\n ];\n\n return Promise.race([interceptor(...newArgs), signal]).catch((e) => {\n // Restore SDK metadata after the interceptor chain exits.\n if (originalError !== undefined) {\n throw restoreError(e, originalError);\n }\n throw e;\n });\n };\n}\n\nfunction isDefined<T>(value: T | undefined | null): value is T {\n return value != null;\n}\n\n// -- Logging utils -----------------------------------------------------------\n\nfunction restateLogLevelToWasmLogLevel(level: RestateLogLevel): vm.LogLevel {\n switch (level) {\n case RestateLogLevel.TRACE:\n return vm.LogLevel.TRACE;\n case RestateLogLevel.DEBUG:\n return vm.LogLevel.DEBUG;\n case RestateLogLevel.INFO:\n return vm.LogLevel.INFO;\n case RestateLogLevel.WARN:\n return vm.LogLevel.WARN;\n case RestateLogLevel.ERROR:\n return vm.LogLevel.ERROR;\n }\n}\n\nfunction onJournalMismatchErrorsToWasm(\n behavior: \"retry\" | \"pause\" | \"fail\" | undefined\n): vm.WasmJournalMismatchBehavior {\n switch (behavior) {\n case \"pause\":\n return vm.WasmJournalMismatchBehavior.Pause;\n case \"fail\":\n return vm.WasmJournalMismatchBehavior.Fail;\n case \"retry\":\n case undefined:\n return vm.WasmJournalMismatchBehavior.Retry;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"generic.js","names":["endpoint: Endpoint","protocolMode: ProtocolMode","additionalDiscoveryFields: Partial<EndpointManifest>","vm.WasmIdentityVerifier","vm.WasmHeader","service: Component","handler: ComponentHandler","attemptHeaders: Headers","extraArgs: unknown[]","additionalContext: AdditionalContext","journalValueCodecInit:\n | Promise<JournalValueCodec>\n | undefined","loggerTransport: LoggerTransport","vm.WasmVM","journalValueCodec: JournalValueCodec","ctx: ContextImpl","invocationRequest: Request","hooks: Hooks[]","hookContext: { request: Request }","encodedOutput: Uint8Array | undefined","originalError: unknown"],"sources":["../../../src/endpoint/handlers/generic.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 {\n ensureError,\n logError,\n PauseError,\n RestateError,\n RetryableError,\n TerminalError,\n} from \"../../types/errors.js\";\nimport type {\n Endpoint as EndpointManifest,\n ProtocolMode,\n} from \"../discovery.js\";\nimport {\n Component,\n ComponentHandler,\n InvokePathComponents,\n} from \"../components.js\";\nimport { parseUrlComponents } from \"../components.js\";\nimport { X_RESTATE_SERVER } from \"../../user_agent.js\";\nimport { CommandError, ContextImpl } from \"../../context_impl.js\";\nimport { restoreError, sanitizeError } from \"../../error_sanitization.js\";\nimport type { InvocationId, Request } from \"../../context.js\";\nimport * as vm from \"./vm/sdk_shared_core_wasm_bindings.js\";\nimport { HandlerKind } from \"../../types/rpc.js\";\nimport { createLogger, type Logger } from \"../../logging/logger.js\";\nimport { DEFAULT_CONSOLE_LOGGER_LOG_LEVEL } from \"../../logging/console_logger_transport.js\";\nimport {\n LoggerContext,\n LoggerTransport,\n LogSource,\n RestateLogLevel,\n} from \"../../logging/logger_transport.js\";\nimport {\n type JournalValueCodec,\n millisOrDurationToMillis,\n} from \"@restatedev/restate-sdk-core\";\nimport type { Endpoint } from \"../endpoint.js\";\nimport {\n type RestateHandler,\n type Headers,\n type RestateRequest,\n type AdditionalContext,\n type RestateResponse,\n ResponseHeaders,\n InputReader,\n OutputWriter,\n} from \"./types.js\";\nimport { handleDiscovery } from \"./discovery.js\";\nimport { handlePreview } from \"./preview.js\";\nimport {\n errorResponse,\n invocationIdFromHeaders,\n simpleResponse,\n tryCreateContextualLogger,\n} from \"./utils.js\";\nimport { destroyLogger, registerLogger } from \"./core_logging.js\";\nimport type { Hooks } from \"../../hooks.js\";\n\n// Hidden symbol key used by first-party hooks to read the live\n// replay/processing phase without widening the public HooksProvider API.\nconst HOOK_CONTEXT_IS_PROCESSING_SYMBOL = Symbol.for(\n \"@restatedev/restate-sdk/hooks.isProcessing\"\n);\n\nexport function createRestateHandler(\n endpoint: Endpoint,\n protocolMode: ProtocolMode,\n additionalDiscoveryFields: Partial<EndpointManifest>\n): RestateHandler {\n return new RestateHandlerImpl(\n endpoint,\n protocolMode,\n additionalDiscoveryFields\n );\n}\n\n/**\n * This is the RestateHandler implementation\n */\nclass RestateHandlerImpl implements RestateHandler {\n private readonly identityVerifier?: vm.WasmIdentityVerifier;\n\n constructor(\n readonly endpoint: Endpoint,\n private readonly protocolMode: ProtocolMode,\n private readonly additionalDiscoveryFields: Partial<EndpointManifest>\n ) {\n // Setup identity verifier\n if (\n this.endpoint.keySet === undefined ||\n this.endpoint.keySet.length === 0\n ) {\n this.endpoint.rlog.warn(\n `Accepting requests without validating request signatures; handler access must be restricted`\n );\n } else {\n this.endpoint.rlog.info(\n `Validating requests using signing keys [${this.endpoint.keySet}]`\n );\n this.identityVerifier = new vm.WasmIdentityVerifier(this.endpoint.keySet);\n }\n\n // Set the logging level in the shared core too!\n vm.set_log_level(\n restateLogLevelToWasmLogLevel(DEFAULT_CONSOLE_LOGGER_LOG_LEVEL)\n );\n }\n\n // handle does not throw.\n public handle(\n request: RestateRequest,\n context?: AdditionalContext\n ): RestateResponse {\n try {\n return this._handle(request, context);\n } catch (e) {\n const error = ensureError(e);\n (\n tryCreateContextualLogger(\n this.endpoint.loggerTransport,\n request.url,\n request.headers\n ) ?? this.endpoint.rlog\n ).error(\n \"Error while handling request: \" + (error.stack ?? error.message)\n );\n return errorResponse(\n error instanceof RestateError ? error.code : 500,\n error.message\n );\n }\n }\n\n private _handle(\n request: RestateRequest,\n context?: AdditionalContext\n ): RestateResponse {\n // this is the recommended way to get the relative path from a url that may be relative or absolute\n const path = new URL(request.url, \"https://example.com\").pathname;\n const parsed = parseUrlComponents(path);\n\n if (parsed.type === \"unknown\") {\n const msg =\n \"Invalid path. Allowed are /health, /discover, /invoke/SvcName/handlerName, \" +\n \"/serdes/SvcName/decode/<serdeName>, or \" +\n \"/serdes/SvcName/encode/<serdeName>, but was: \" +\n path;\n this.endpoint.rlog.trace(msg);\n return errorResponse(404, msg);\n }\n if (parsed.type === \"health\") {\n return simpleResponse(\n 200,\n {\n \"content-type\": \"application/text\",\n \"x-restate-server\": X_RESTATE_SERVER,\n },\n new TextEncoder().encode(\"OK\")\n );\n }\n\n // Discovery, preview, and handling invocations require identity verification\n const error = this.validateConnectionSignature(path, request.headers);\n if (error !== null) {\n return error;\n }\n if (parsed.type === \"discover\") {\n return handleDiscovery(\n this.endpoint,\n this.protocolMode,\n this.additionalDiscoveryFields,\n request.headers[\"accept\"]\n );\n }\n if (parsed.type === \"preview\") {\n return handlePreview(this.endpoint, parsed);\n }\n\n return this.handleInvoke(\n parsed,\n request.headers,\n request.extraArgs,\n context ?? {}\n );\n }\n\n private validateConnectionSignature(\n path: string,\n headers: Headers\n ): RestateResponse | null {\n if (!this.identityVerifier) {\n // not validating\n return null;\n }\n\n const vmHeaders = Object.entries(headers)\n .filter(([, v]) => v !== undefined)\n .map(\n ([k, v]) =>\n new vm.WasmHeader(k, v instanceof Array ? v[0]! : (v as string))\n );\n\n try {\n this.identityVerifier.verify_identity(path, vmHeaders);\n return null;\n } catch (e) {\n this.endpoint.rlog.error(\n // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n `Rejecting request as its JWT did not validate: ${e}`\n );\n return errorResponse(401, \"Unauthorized\");\n }\n }\n\n private handleInvoke(\n invokePathComponent: InvokePathComponents,\n headers: Headers,\n extraArgs: unknown[],\n additionalContext: AdditionalContext\n ): RestateResponse {\n // Check if we support this protocol version\n const serviceProtocolVersionString = headers[\"content-type\"];\n if (typeof serviceProtocolVersionString !== \"string\") {\n const errorMessage = \"Missing content-type header\";\n this.endpoint.rlog.warn(errorMessage);\n return errorResponse(415, errorMessage);\n }\n\n const service = this.endpoint.components.get(\n invokePathComponent.componentName\n );\n if (!service) {\n const msg = `No service found for URL: ${JSON.stringify(invokePathComponent)}`;\n this.endpoint.rlog.error(msg);\n return errorResponse(404, msg);\n }\n\n const handler = service.handlerMatching(invokePathComponent);\n if (!handler) {\n const msg = `No handler found for URL: ${JSON.stringify(invokePathComponent)}`;\n this.endpoint.rlog.error(msg);\n return errorResponse(404, msg);\n }\n\n return new RestateInvokeResponse(\n service,\n handler,\n headers,\n extraArgs,\n additionalContext,\n this.endpoint.journalValueCodec,\n this.endpoint.loggerTransport\n );\n }\n}\n\nclass RestateInvokeResponse implements RestateResponse {\n private readonly headers: ResponseHeaders;\n private readonly statusCode: number;\n\n private readonly loggerId: number;\n private vmLogger: Logger;\n private readonly coreVm: vm.WasmVM;\n\n constructor(\n private readonly service: Component,\n private readonly handler: ComponentHandler,\n private readonly attemptHeaders: Headers,\n private readonly extraArgs: unknown[],\n private readonly additionalContext: AdditionalContext,\n private readonly journalValueCodecInit:\n | Promise<JournalValueCodec>\n | undefined,\n private readonly loggerTransport: LoggerTransport\n ) {\n this.loggerId = Math.floor(Math.random() * 4_294_967_295 /* u32::MAX */);\n const isJournalCodecDefined = this.journalValueCodecInit !== undefined;\n\n // Instantiate core vm and prepare response headers\n const vmHeaders = Object.entries(this.attemptHeaders)\n .filter(([, v]) => v !== undefined)\n .map(\n ([k, v]) =>\n new vm.WasmHeader(k, v instanceof Array ? v[0]! : (v as string))\n );\n this.coreVm = new vm.WasmVM(\n vmHeaders,\n restateLogLevelToWasmLogLevel(DEFAULT_CONSOLE_LOGGER_LOG_LEVEL),\n this.loggerId,\n isJournalCodecDefined,\n handler.executionOptions.explicitCancellation ?? false,\n onJournalMismatchErrorsToWasm(\n handler.executionOptions.onJournalMismatchErrors\n ),\n handler.executionOptions.explicitRecovery ?? false\n );\n const responseHead = this.coreVm.get_response_head();\n this.statusCode = responseHead.status_code;\n this.headers = responseHead.headers.reduce(\n (headers, { key, value }) => ({\n [key]: value,\n ...headers,\n }),\n {\n \"x-restate-server\": X_RESTATE_SERVER,\n }\n );\n this.vmLogger = createLogger(\n this.loggerTransport,\n LogSource.JOURNAL,\n new LoggerContext(\n invocationIdFromHeaders(this.attemptHeaders),\n this.service.name(),\n this.handler.name(),\n undefined,\n undefined,\n this.additionalContext\n )\n );\n }\n\n async process({\n inputReader,\n outputWriter,\n writeHead,\n abortSignal,\n }: {\n inputReader: InputReader;\n outputWriter: OutputWriter;\n writeHead: (statusCode: number, headers: ResponseHeaders) => void;\n abortSignal: AbortSignal;\n }): Promise<void> {\n // Commit the response head immediately — the VM-determined head is known\n // at construction time and never changes during processing.\n writeHead(this.statusCode, this.headers);\n\n abortSignal.addEventListener(\n \"abort\",\n () => {\n // In any case, on abort remove the invocation logger to avoid memory leaks\n destroyLogger(this.loggerId);\n\n // When the HTTP connection closes (e.g. abort timeout), poison the VM.\n // We only read new input from the server when a Restate command is\n // waiting for a response. If no command has been issued, the server's\n // abort signal is never read. Poisoning the VM ensures the handler\n // fails on the next VM call (e.g. ctx.run, ctx.sleep).\n setImmediate(() => {\n const msg = \"Connection closed\";\n this.coreVm.notify_error(msg, msg);\n });\n },\n { once: true }\n );\n // Use a default logger that still respects the endpoint custom logger\n // We will override this later with a logger that has a LoggerContext\n // See vm_log below for more details\n registerLogger(this.loggerId, this.vmLogger);\n\n const journalValueCodec: JournalValueCodec = this.journalValueCodecInit\n ? await this.journalValueCodecInit\n : {\n encode: (entry) => entry,\n decode: (entry) => Promise.resolve(entry),\n };\n\n // This promise is used to signal the end of the computation,\n // which can be either the user returns a value,\n // or an exception gets caught, or the state machine fails/suspends.\n //\n // The last case is handled internally within the ContextImpl.\n const invocationEndPromise = Promise.withResolvers<void>();\n let ctx: ContextImpl;\n\n // Initial phase before running user code\n // -> Buffer in shared core the journal entries\n // -> Initiate loggers\n // -> Initialize the ContextImpl\n try {\n // Buffer journal inside shared core\n await bufferJournalReplayInCoreVm(this.coreVm, inputReader);\n\n // Get input from coreVm to build the request object\n const input = this.coreVm.sys_input();\n const invocationRequest: Request = {\n target: {\n service: this.service.name(),\n handler: this.handler.name(),\n key: input.key || undefined,\n toString() {\n return this.key !== undefined\n ? `${this.service}/${this.key}/${this.handler}`\n : `${this.service}/${this.handler}`;\n },\n },\n id: input.invocation_id as InvocationId,\n headers: input.headers.reduce((headers, { key, value }) => {\n headers.set(key, value);\n return headers;\n }, new Map()),\n attemptHeaders: Object.entries(this.attemptHeaders).reduce(\n (headers, [key, value]) => {\n if (value !== undefined) {\n headers.set(key, value instanceof Array ? value[0] : value);\n }\n return headers;\n },\n new Map()\n ),\n body: input.input,\n extraArgs: this.extraArgs,\n idempotencyKey: input.idempotency_key || undefined,\n scope: input.scope || undefined,\n limitKey: input.limit_key || undefined,\n attemptCompletedSignal: abortSignal,\n };\n\n // Prepare logger\n const loggerContext = new LoggerContext(\n input.invocation_id,\n this.handler.component().name(),\n this.handler.name(),\n this.handler.kind() === HandlerKind.SERVICE ? undefined : input.key,\n invocationRequest,\n this.additionalContext\n );\n const ctxLogger = createLogger(\n this.loggerTransport,\n LogSource.USER,\n loggerContext,\n () => !this.coreVm.is_processing()\n );\n // Override the vmLogger created before with more info!\n this.vmLogger = createLogger(\n this.loggerTransport,\n LogSource.JOURNAL,\n loggerContext\n // Filtering is done within the shared core\n );\n\n // See vm_log below for more details\n registerLogger(this.loggerId, this.vmLogger);\n if (!this.coreVm.is_processing()) {\n this.vmLogger.info(\"Replaying invocation.\");\n } else {\n this.vmLogger.info(\"Starting invocation.\");\n }\n\n // Prepare context\n ctx = new ContextImpl(\n this.coreVm,\n input,\n ctxLogger,\n this.handler.kind(),\n this.vmLogger,\n invocationRequest,\n invocationEndPromise,\n inputReader,\n outputWriter,\n journalValueCodec,\n this.handler.executionOptions\n );\n } catch (e) {\n // That's \"preflight\" failure cases, where stuff fails before running user code\n // In this scenario, we close the coreVm, then flush and close\n const error = ensureError(e);\n this.coreVm.notify_error(error.message, error.message);\n try {\n await flushAndClose(\n this.coreVm,\n this.vmLogger,\n Promise.resolve(inputReader),\n outputWriter\n );\n } finally {\n // Safety net: the abort listener should clean this up when the attempt\n // ends, but process() owns the logger registration, so avoid leaking if\n // an adapter ever fails to abort the attempt-completed signal.\n destroyLogger(this.loggerId);\n }\n return;\n }\n\n // Run user code. Errors that reach the handler or interceptor code\n // (handler throws, interceptor throws, entry completes with terminal\n // failure) propagate naturally. Errors where the handler is stuck on\n // an await that will never settle (e.g. suspension, retryable run\n // error) are broken out by raceWithAttemptEnd, which races against\n // invocationEndPromise — rejected by ContextImpl when the attempt ends.\n try {\n await startUserHandler(\n ctx,\n this.service,\n this.handler,\n journalValueCodec\n );\n } catch (e) {\n notifyError(e, ctx, this.handler.executionOptions.asTerminalError);\n } finally {\n try {\n await flushAndClose(\n this.coreVm,\n this.vmLogger,\n ctx.inputPump.stop(),\n outputWriter\n );\n } finally {\n // Safety net: the abort listener should clean this up when the attempt\n // ends, but process() owns the logger registration, so avoid leaking if\n // an adapter ever fails to abort the attempt-completed signal.\n destroyLogger(this.loggerId);\n }\n }\n }\n}\n\nasync function bufferJournalReplayInCoreVm(\n coreVm: vm.WasmVM,\n inputReader: InputReader\n) {\n while (!coreVm.is_ready_to_execute()) {\n const nextValue = await inputReader.next();\n if (nextValue.done) {\n coreVm.notify_input_closed();\n break;\n }\n if (nextValue.value !== undefined) {\n coreVm.notify_input(nextValue.value);\n }\n }\n}\n\nasync function startUserHandler(\n ctx: ContextImpl,\n service: Component,\n handler: ComponentHandler,\n journalValueCodec: JournalValueCodec\n) {\n // Instantiate hooks from providers.\n // If a provider throws, the same rules as handler failures apply:\n // TerminalError → terminate invocation, other errors → retry.\n const hooks: Hooks[] = [];\n for (const provider of handler.executionOptions.hooks ?? []) {\n const hookContext: { request: Request } = {\n request: ctx.request(),\n };\n Object.defineProperty(hookContext, HOOK_CONTEXT_IS_PROCESSING_SYMBOL, {\n value: () => ctx.isProcessing(),\n enumerable: false,\n });\n hooks.push(provider(hookContext));\n }\n\n // Compose interceptor.handler into a single interceptor (first = outermost)\n const handlerInterceptor = composeInterceptors(\n hooks.map((h) => h.interceptor?.handler).filter(isDefined)\n );\n\n ctx.setRunInterceptor(\n composeInterceptors(hooks.map((h) => h.interceptor?.run).filter(isDefined))\n );\n\n let encodedOutput: Uint8Array | undefined;\n await raceWithAttemptEnd(\n ctx,\n handlerInterceptor\n )(async () => {\n const decodedInput = await journalValueCodec\n .decode(ctx.request().body)\n .catch((e) =>\n // Re-throw as terminal error, to fail on input errors\n Promise.reject(\n new TerminalError(\n `Failed to decode input using journal value codec: ${\n ensureError(e).message\n }`,\n {\n errorCode: 400,\n }\n )\n )\n );\n\n // Then run user code\n const output = await handler.invoke(ctx, decodedInput);\n\n // Encode user code output\n encodedOutput = journalValueCodec.encode(output);\n });\n\n // Interceptor chain completed without error — commit the result.\n // sys_end() is called here (after interceptors) so that interceptor\n // errors after next() correctly prevent the invocation from succeeding.\n ctx.coreVm.sys_write_output_success(encodedOutput!);\n ctx.coreVm.sys_end();\n ctx.vmLogger.info(\"Invocation completed successfully.\");\n}\n\n/**\n * Classifies the error and notifies the VM. Called from the process() catch\n * block — the single place that decides how to report errors to the VM.\n */\nfunction notifyError(\n e: unknown,\n ctx: ContextImpl,\n asTerminalError?: (error: unknown) => TerminalError | undefined\n) {\n // Command-specific errors from ContextImpl carry metadata the VM needs\n // for command correlation. Check before ensureError to preserve the type.\n if (e instanceof CommandError) {\n const cause = ensureError(e.cause);\n logError(ctx.vmLogger, cause);\n if (e.hasCommandIndex) {\n // Completion failure — command exists in the journal\n ctx.coreVm.notify_error_for_specific_command(\n cause.message,\n cause.stack,\n e.commandType,\n e.commandIndex!,\n null\n );\n } else {\n // Preparation failure — command not yet issued\n ctx.coreVm.notify_error_for_next_command(\n cause.message,\n cause.stack,\n e.commandType\n );\n }\n return;\n }\n\n // Handler/interceptor errors\n const error = ensureError(e, asTerminalError);\n logError(ctx.vmLogger, error);\n\n try {\n if (error instanceof TerminalError) {\n // Terminal: write the failure as the invocation output\n ctx.coreVm.sys_write_output_failure({\n code: error.code,\n message: error.message,\n metadata: Object.entries(error.metadata ?? {}).map(([key, value]) => ({\n key,\n value,\n })),\n });\n ctx.coreVm.sys_end();\n } else if (error instanceof RetryableError) {\n // Retryable with explicit delay\n ctx.coreVm.notify_error_with_delay_override(\n error.message,\n error.stack,\n error.retryAfter !== undefined\n ? BigInt(millisOrDurationToMillis(error.retryAfter))\n : undefined\n );\n } else {\n if (error instanceof PauseError) {\n ctx.vmLogger.warn(\n \"Throwing PauseError from the handler context will be ignored, \" +\n \"as it leads to pause loops. You should use PauseError only inside `ctx.run`\"\n );\n }\n\n // Transient error — VM decides retry policy\n ctx.coreVm.notify_error(error.message, error.stack);\n }\n } catch (vmError) {\n // Safety net: if sys_write_output_failure or other VM calls fail,\n // fall back to notify_error.\n const inner = ensureError(vmError);\n ctx.coreVm.notify_error(inner.message, inner.stack);\n }\n}\n\nasync function flushAndClose(\n coreVm: vm.WasmVM,\n vmLogger: Logger,\n inputReaderGetter: Promise<InputReader>,\n outputWriter: OutputWriter\n): Promise<void> {\n let inputClosed = false;\n try {\n // Consume vm output buffer, write it out, then close the stream\n const nextOutput = coreVm.take_output();\n if (nextOutput?.length > 0) {\n await outputWriter.write(nextOutput);\n }\n\n // --- After this point, we should have flushed the shared core internal buffer\n\n // Wait for the input reader.\n // In case we executed the user code, this is wired up to the InputPump.stop()\n // to make sure there is only one reader for inputReader.\n const inputReader = await inputReaderGetter;\n\n // Let's make sure we properly close the request stream before closing the response stream\n while (!inputClosed) {\n try {\n const res = await inputReader.next();\n inputClosed = res.done ?? false;\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n } catch (e) {\n inputClosed = true;\n }\n }\n\n // Close the response stream\n await outputWriter.close();\n } catch (e) {\n // In case of failure, we can do little here except just logging stuff out,\n // because outputWriter is not usable here.\n const error = ensureError(e);\n const abortErrorOnWrite = isAbortErrorOnWrite(error);\n\n if (inputClosed && abortErrorOnWrite) {\n // Because we closed the input already,\n // these errors are benign and are caused by\n // synchronization issues wrt closing the response stream in the runtime\n // This will be fixed in the runtime with https://github.com/restatedev/restate/issues/4456\n return;\n }\n\n if (abortErrorOnWrite) {\n vmLogger.error(\n \"Got abort error from connection: \" +\n error.message +\n \"\\n\" +\n \"This might indicate that:\\n\" +\n \"* The restate-server aborted the connection after hitting the 'abort-timeout'\\n\" +\n \"* The connection with the restate-server was lost\\n\" +\n \"\\n\" +\n \"Please check the invocation in the Restate UI for more details.\"\n );\n } else {\n vmLogger.error(\n \"Error while handling request: \" + (error.stack ?? error.message)\n );\n }\n }\n}\n\nfunction isAbortErrorOnWrite(error: Error) {\n return (\n error.name === \"AbortError\" ||\n error.message === \"Invalid state: WritableStream is closed\" ||\n /**\n * Node stream closed error thrown on writes\n */\n (error as { code?: string }).code === \"ERR_HTTP2_INVALID_STREAM\"\n );\n}\n\n// -- Hook composition utils --------------------------------------------------\n\ntype InterceptorFn<Args extends unknown[]> = (\n ...args: [...Args, () => Promise<void>]\n) => Promise<void>;\n\nfunction composeInterceptors<Args extends unknown[]>(\n interceptors: InterceptorFn<Args>[]\n): InterceptorFn<Args> {\n return interceptors.reduceRight<InterceptorFn<Args>>(\n (innerInterceptor, interceptor) =>\n (...args) => {\n const context = args.slice(0, -1) as unknown as Args;\n const callback = args.at(-1) as () => Promise<void>;\n return interceptor(...context, () =>\n innerInterceptor(...context, callback)\n );\n },\n (...args) => (args.at(-1) as () => Promise<void>)()\n );\n}\n\n/**\n * Wraps an interceptor so that both `next()` and the interceptor body race\n * against `invocationEndPromise`. When the attempt ends (suspension, retryable\n * error, etc.), the promise rejects and the interceptor chain unwinds through\n * catch/finally blocks — preventing interceptors from hanging on a `next()`\n * that will never settle.\n *\n * SDK-internal metadata (CommandError, retryAfter) is stripped before the\n * interceptor sees the error and restored after the chain exits.\n */\nfunction raceWithAttemptEnd<Args extends unknown[]>(\n ctx: ContextImpl,\n interceptor: InterceptorFn<Args>\n): InterceptorFn<Args> {\n return (...args) => {\n let originalError: unknown;\n\n // Strip SDK metadata before interceptors see the error.\n // Store the original in the closure for restoration after the chain.\n const signal = ctx.invocationEndPromise.promise.catch((e) => {\n originalError = e;\n throw sanitizeError(e);\n }) as Promise<never>;\n\n const originalNext = args.at(-1) as () => Promise<void>;\n const racingNext = () => Promise.race([originalNext(), signal]);\n const newArgs = [...args.slice(0, -1), racingNext] as unknown as [\n ...Args,\n () => Promise<void>,\n ];\n\n return Promise.race([interceptor(...newArgs), signal]).catch((e) => {\n // Restore SDK metadata after the interceptor chain exits.\n if (originalError !== undefined) {\n throw restoreError(e, originalError);\n }\n throw e;\n });\n };\n}\n\nfunction isDefined<T>(value: T | undefined | null): value is T {\n return value != null;\n}\n\n// -- Logging utils -----------------------------------------------------------\n\nfunction restateLogLevelToWasmLogLevel(level: RestateLogLevel): vm.LogLevel {\n switch (level) {\n case RestateLogLevel.TRACE:\n return vm.LogLevel.TRACE;\n case RestateLogLevel.DEBUG:\n return vm.LogLevel.DEBUG;\n case RestateLogLevel.INFO:\n return vm.LogLevel.INFO;\n case RestateLogLevel.WARN:\n return vm.LogLevel.WARN;\n case RestateLogLevel.ERROR:\n return vm.LogLevel.ERROR;\n }\n}\n\nfunction onJournalMismatchErrorsToWasm(\n behavior: \"retry\" | \"pause\" | \"fail\" | undefined\n): vm.WasmJournalMismatchBehavior {\n switch (behavior) {\n case \"pause\":\n return vm.WasmJournalMismatchBehavior.Pause;\n case \"fail\":\n return vm.WasmJournalMismatchBehavior.Fail;\n case \"retry\":\n case undefined:\n return vm.WasmJournalMismatchBehavior.Retry;\n }\n}\n"],"mappings":"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"}
@@ -140,7 +140,7 @@ export class WasmVM {
140
140
  is_processing(): boolean;
141
141
  is_ready_to_execute(): boolean;
142
142
  last_command_index(): number;
143
- constructor(headers: WasmHeader[], log_level: LogLevel, logger_id: number, disable_payload_checks: boolean, explicit_cancellation: boolean, on_journal_mismatch: WasmJournalMismatchBehavior);
143
+ constructor(headers: WasmHeader[], log_level: LogLevel, logger_id: number, disable_payload_checks: boolean, explicit_cancellation: boolean, on_journal_mismatch: WasmJournalMismatchBehavior, explicit_recovery: boolean);
144
144
  notify_error(error_message: string, stacktrace?: string | null): void;
145
145
  notify_error_for_next_command(error_message: string, stacktrace: string | null | undefined, wasm_command_type: WasmCommandType): void;
146
146
  notify_error_for_specific_command(error_message: string, stacktrace: string | null | undefined, wasm_command_type: WasmCommandType, command_index: number, command_name?: string | null): void;
@@ -156,8 +156,8 @@ export class WasmVM {
156
156
  sys_awakeable(): WasmAwakeable;
157
157
  sys_call(service: string, handler: string, buffer: Uint8Array, key: string | null | undefined, headers: WasmHeader[], idempotency_key?: string | null, scope?: string | null, limit_key?: string | null, name?: string | null): WasmCallHandle;
158
158
  sys_cancel_invocation(target_invocation_id: string): void;
159
- sys_clear_all_state(): void;
160
- sys_clear_state(key: string): void;
159
+ sys_clear_all_state(name?: string | null): void;
160
+ sys_clear_state(key: string, name?: string | null): void;
161
161
  sys_complete_awakeable_failure(id: string, value: WasmFailure): void;
162
162
  sys_complete_awakeable_success(id: string, buffer: Uint8Array): void;
163
163
  sys_complete_promise_failure(key: string, value: WasmFailure): number;
@@ -167,13 +167,13 @@ export class WasmVM {
167
167
  sys_end(): void;
168
168
  sys_get_invocation_output(invocation_id: string): number;
169
169
  sys_get_promise(key: string): number;
170
- sys_get_state(key: string): number;
171
- sys_get_state_keys(): number;
170
+ sys_get_state(key: string, name?: string | null): number;
171
+ sys_get_state_keys(name?: string | null): number;
172
172
  sys_input(): WasmInput;
173
173
  sys_peek_promise(key: string): number;
174
174
  sys_run(name: string): WasmRun;
175
175
  sys_send(service: string, handler: string, buffer: Uint8Array, key: string | null | undefined, headers: WasmHeader[], delay?: bigint | null, idempotency_key?: string | null, scope?: string | null, limit_key?: string | null, name?: string | null): WasmSendHandle;
176
- sys_set_state(key: string, buffer: Uint8Array): void;
176
+ sys_set_state(key: string, buffer: Uint8Array, name?: string | null): void;
177
177
  sys_signal(signal_name: string): number;
178
178
  sys_sleep(millis: bigint, name?: string | null): number;
179
179
  sys_write_output_failure(value: WasmFailure): void;
@@ -394,11 +394,12 @@ export class WasmVM {
394
394
  * @param {boolean} disable_payload_checks
395
395
  * @param {boolean} explicit_cancellation
396
396
  * @param {WasmJournalMismatchBehavior} on_journal_mismatch
397
+ * @param {boolean} explicit_recovery
397
398
  */
398
- constructor(headers, log_level, logger_id, disable_payload_checks, explicit_cancellation, on_journal_mismatch) {
399
+ constructor(headers, log_level, logger_id, disable_payload_checks, explicit_cancellation, on_journal_mismatch, explicit_recovery) {
399
400
  const ptr0 = passArrayJsValueToWasm0(headers, wasm.__wbindgen_malloc);
400
401
  const len0 = WASM_VECTOR_LEN;
401
- const ret = wasm.wasmvm_new(ptr0, len0, log_level, logger_id, disable_payload_checks, explicit_cancellation, on_journal_mismatch);
402
+ const ret = wasm.wasmvm_new(ptr0, len0, log_level, logger_id, disable_payload_checks, explicit_cancellation, on_journal_mismatch, explicit_recovery);
402
403
  if (ret[2]) {
403
404
  throw takeFromExternrefTable0(ret[1]);
404
405
  }
@@ -613,19 +614,27 @@ export class WasmVM {
613
614
  throw takeFromExternrefTable0(ret[0]);
614
615
  }
615
616
  }
616
- sys_clear_all_state() {
617
- const ret = wasm.wasmvm_sys_clear_all_state(this.__wbg_ptr);
617
+ /**
618
+ * @param {string | null} [name]
619
+ */
620
+ sys_clear_all_state(name) {
621
+ var ptr0 = isLikeNone(name) ? 0 : passStringToWasm0(name, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
622
+ var len0 = WASM_VECTOR_LEN;
623
+ const ret = wasm.wasmvm_sys_clear_all_state(this.__wbg_ptr, ptr0, len0);
618
624
  if (ret[1]) {
619
625
  throw takeFromExternrefTable0(ret[0]);
620
626
  }
621
627
  }
622
628
  /**
623
629
  * @param {string} key
630
+ * @param {string | null} [name]
624
631
  */
625
- sys_clear_state(key) {
632
+ sys_clear_state(key, name) {
626
633
  const ptr0 = passStringToWasm0(key, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
627
634
  const len0 = WASM_VECTOR_LEN;
628
- const ret = wasm.wasmvm_sys_clear_state(this.__wbg_ptr, ptr0, len0);
635
+ var ptr1 = isLikeNone(name) ? 0 : passStringToWasm0(name, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
636
+ var len1 = WASM_VECTOR_LEN;
637
+ const ret = wasm.wasmvm_sys_clear_state(this.__wbg_ptr, ptr0, len0, ptr1, len1);
629
638
  if (ret[1]) {
630
639
  throw takeFromExternrefTable0(ret[0]);
631
640
  }
@@ -752,22 +761,28 @@ export class WasmVM {
752
761
  }
753
762
  /**
754
763
  * @param {string} key
764
+ * @param {string | null} [name]
755
765
  * @returns {number}
756
766
  */
757
- sys_get_state(key) {
767
+ sys_get_state(key, name) {
758
768
  const ptr0 = passStringToWasm0(key, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
759
769
  const len0 = WASM_VECTOR_LEN;
760
- const ret = wasm.wasmvm_sys_get_state(this.__wbg_ptr, ptr0, len0);
770
+ var ptr1 = isLikeNone(name) ? 0 : passStringToWasm0(name, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
771
+ var len1 = WASM_VECTOR_LEN;
772
+ const ret = wasm.wasmvm_sys_get_state(this.__wbg_ptr, ptr0, len0, ptr1, len1);
761
773
  if (ret[2]) {
762
774
  throw takeFromExternrefTable0(ret[1]);
763
775
  }
764
776
  return ret[0] >>> 0;
765
777
  }
766
778
  /**
779
+ * @param {string | null} [name]
767
780
  * @returns {number}
768
781
  */
769
- sys_get_state_keys() {
770
- const ret = wasm.wasmvm_sys_get_state_keys(this.__wbg_ptr);
782
+ sys_get_state_keys(name) {
783
+ var ptr0 = isLikeNone(name) ? 0 : passStringToWasm0(name, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
784
+ var len0 = WASM_VECTOR_LEN;
785
+ const ret = wasm.wasmvm_sys_get_state_keys(this.__wbg_ptr, ptr0, len0);
771
786
  if (ret[2]) {
772
787
  throw takeFromExternrefTable0(ret[1]);
773
788
  }
@@ -850,13 +865,16 @@ export class WasmVM {
850
865
  /**
851
866
  * @param {string} key
852
867
  * @param {Uint8Array} buffer
868
+ * @param {string | null} [name]
853
869
  */
854
- sys_set_state(key, buffer) {
870
+ sys_set_state(key, buffer, name) {
855
871
  const ptr0 = passStringToWasm0(key, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
856
872
  const len0 = WASM_VECTOR_LEN;
857
873
  const ptr1 = passArray8ToWasm0(buffer, wasm.__wbindgen_malloc);
858
874
  const len1 = WASM_VECTOR_LEN;
859
- const ret = wasm.wasmvm_sys_set_state(this.__wbg_ptr, ptr0, len0, ptr1, len1);
875
+ var ptr2 = isLikeNone(name) ? 0 : passStringToWasm0(name, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
876
+ var len2 = WASM_VECTOR_LEN;
877
+ const ret = wasm.wasmvm_sys_set_state(this.__wbg_ptr, ptr0, len0, ptr1, len1, ptr2, len2);
860
878
  if (ret[1]) {
861
879
  throw takeFromExternrefTable0(ret[0]);
862
880
  }