restate-sdk 0.4.4 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a8e9a5eab5505c6585cad44e4d579238dfd87f637c480c8992ee182e1a5d7dc8
4
- data.tar.gz: de1d60c560fcc48f55120820bdaf3de1d36c6a03664bdc0408c152ee11a160e7
3
+ metadata.gz: 1b23261e2b75927f25f70d83c93133191b894a2451c8a194e73a38e91b3f44d6
4
+ data.tar.gz: 269ac3b7c8a496da0db88b53d5dedbd54afe64a6507c712c9d71c828811bfb55
5
5
  SHA512:
6
- metadata.gz: 9ffae9eb0811b513127a2369960a9aa8511cabd21c5e8b5d460e9b5e9131db8f45b3597c8f93aa1faea3d1cc3839b928ed4e216a20826de050668e09abd7617c
7
- data.tar.gz: d9bfc8f6c4b86012aa00f236fe8b26abfff5966c833376259beb8b91cad1fc4a300d4ade6374e14865179f02485700428bb819c2ce455df2494f69126a1c03d3
6
+ metadata.gz: 3b66009141e9bfba8841a5f73c7a8bd4b808d36f1edd122f70e73b91f4718f5a0de1f8d653c55b1686839c66dbef802a1f71a13e7fba71fbb4d631b2c1721295
7
+ data.tar.gz: 9caa27f5058be3d18cf9a06295dc828c5053cbb3d4622c6944ec6f27466b8b80e41b67e11ac244c3fb1847297e24b03997aec7fe602347bdabfa9377213b77d9
data/Cargo.lock CHANGED
@@ -569,7 +569,7 @@ dependencies = [
569
569
 
570
570
  [[package]]
571
571
  name = "restate_internal"
572
- version = "0.4.4"
572
+ version = "0.5.1"
573
573
  dependencies = [
574
574
  "magnus",
575
575
  "rb-sys",
data/README.md CHANGED
@@ -5,14 +5,15 @@
5
5
 
6
6
  # Restate Ruby SDK
7
7
 
8
+ > **Note:** This SDK is currently under active development. APIs may change between releases.
9
+
8
10
  [Restate](https://restate.dev/) is a system for easily building resilient applications using *distributed durable async/await*. This repository contains the Restate SDK for writing services in **Ruby**.
9
11
 
10
12
  ```ruby
11
13
  require 'restate'
12
14
 
13
15
  class Greeter < Restate::Service
14
- handler def greet(name)
15
- ctx = Restate.current_context
16
+ handler def greet(ctx, name)
16
17
  ctx.run_sync('build-greeting') { "Hello, #{name}!" }
17
18
  end
18
19
  end
@@ -66,9 +67,7 @@ end
66
67
 
67
68
  class EventService < Restate::Service
68
69
  handler :register, input: RegistrationRequest, output: RegistrationResponse
69
- def register(request)
70
- ctx = Restate.current_context
71
-
70
+ def register(ctx, request)
72
71
  registration_id = ctx.run_sync('create-registration') do
73
72
  "reg_#{request.event_name}_#{rand(10_000)}"
74
73
  end
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "restate_internal"
3
- version = "0.4.4"
3
+ version = "0.5.1"
4
4
  edition = "2021"
5
5
  publish = false
6
6
 
@@ -31,20 +31,20 @@ module Restate
31
31
 
32
32
  module_function
33
33
 
34
- # Invoke a handler with raw input bytes. The context is available via
35
- # fiber-local Restate.current_context (set by ServerContext#enter).
34
+ # Invoke a handler with the context and raw input bytes.
35
+ # The context is passed as the first argument to every handler.
36
36
  # Returns raw output bytes.
37
- sig { params(handler: T.untyped, in_buffer: String).returns(String) }
38
- def invoke_handler(handler:, in_buffer:)
39
- if handler.arity == 1
37
+ sig { params(handler: T.untyped, ctx: T.untyped, in_buffer: String).returns(String) }
38
+ def invoke_handler(handler:, ctx:, in_buffer:)
39
+ if handler.arity == 2
40
40
  begin
41
41
  in_arg = handler.handler_io.input_serde.deserialize(in_buffer)
42
42
  rescue StandardError => e
43
43
  Kernel.raise TerminalError, "Unable to parse input argument: #{e.message}"
44
44
  end
45
- out_arg = handler.callable.call(in_arg)
45
+ out_arg = handler.callable.call(ctx, in_arg)
46
46
  else
47
- out_arg = handler.callable.call
47
+ out_arg = handler.callable.call(ctx)
48
48
  end
49
49
  handler.handler_io.output_serde.serialize(out_arg)
50
50
  end
data/lib/restate/serde.rb CHANGED
@@ -212,10 +212,13 @@ module Restate
212
212
  class TypeSerde
213
213
  extend T::Sig
214
214
 
215
+ sig { returns(T.untyped) }
216
+ attr_reader :type_class
217
+
215
218
  # Create a TypeSerde for the given type with a precomputed JSON Schema.
216
219
  sig { params(type: T.untyped, schema: T.nilable(T::Hash[String, T.untyped])).void }
217
220
  def initialize(type, schema)
218
- @type = type
221
+ @type_class = type
219
222
  @schema = schema
220
223
  end
221
224
 
@@ -243,6 +246,9 @@ module Restate
243
246
  class DryStructSerde
244
247
  extend T::Sig
245
248
 
249
+ sig { returns(T.untyped) }
250
+ attr_reader :struct_class
251
+
246
252
  # Create a DryStructSerde for the given Dry::Struct class.
247
253
  sig { params(struct_class: T.untyped).void }
248
254
  def initialize(struct_class)
@@ -280,6 +286,9 @@ module Restate
280
286
  class TStructSerde
281
287
  extend T::Sig
282
288
 
289
+ sig { returns(T.class_of(T::Struct)) }
290
+ attr_reader :struct_class
291
+
283
292
  # Create a TStructSerde for the given T::Struct subclass.
284
293
  sig { params(struct_class: T.class_of(T::Struct)).void }
285
294
  def initialize(struct_class)
@@ -48,7 +48,7 @@ module Restate
48
48
  Thread.current[:restate_service_kind] = @handler.service_tag.kind
49
49
  Thread.current[:restate_handler_kind] = @handler.kind
50
50
  in_buffer = @invocation.input_buffer
51
- out_buffer = Restate.invoke_handler(handler: @handler, in_buffer: in_buffer)
51
+ out_buffer = Restate.invoke_handler(handler: @handler, ctx: self, in_buffer: in_buffer)
52
52
  @vm.sys_write_output_success(out_buffer.b)
53
53
  @vm.sys_end
54
54
  rescue TerminalError => e
@@ -6,8 +6,8 @@ module Restate
6
6
  #
7
7
  # @example
8
8
  # class Greeter < Restate::Service
9
- # handler def greet(name)
10
- # "Hello, #{name}!"
9
+ # handler def greet(ctx, name)
10
+ # ctx.run_sync('build-greeting') { "Hello, #{name}!" }
11
11
  # end
12
12
  # end
13
13
  class Service
@@ -15,7 +15,7 @@ module Restate
15
15
  extend ServiceDSL
16
16
 
17
17
  # Register a handler method on this service.
18
- # Use as: +handler def my_method(arg)+ or +handler :my_method, input: String+
18
+ # Use as: +handler def my_method(ctx, arg)+ or +handler :my_method, input: String+
19
19
  #
20
20
  # @param method_name [Symbol] name of the method to register
21
21
  # @param opts [Hash] handler options (+input:+, +output:+, +accept:+, +content_type:+)
@@ -9,8 +9,7 @@ module Restate
9
9
  #
10
10
  # @example
11
11
  # class Counter < Restate::VirtualObject
12
- # handler def add(addend)
13
- # ctx = Restate.current_object_context
12
+ # handler def add(ctx, addend)
14
13
  # old = ctx.get('counter') || 0
15
14
  # ctx.set('counter', old + addend)
16
15
  # old + addend
@@ -211,8 +210,8 @@ module Restate
211
210
 
212
211
  um = T.unsafe(self).instance_method(name)
213
212
  arity = um.arity.abs
214
- unless [0, 1].include?(arity)
215
- Kernel.raise ArgumentError, "handler '#{name}' must accept 0 or 1 parameters ([input]), got #{arity}"
213
+ unless [1, 2].include?(arity)
214
+ Kernel.raise ArgumentError, "handler '#{name}' must accept 1 or 2 parameters (ctx[, input]), got #{arity}"
216
215
  end
217
216
 
218
217
  bound = um.bind(instance)
@@ -2,5 +2,5 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module Restate
5
- VERSION = '0.4.4'
5
+ VERSION = '0.5.1'
6
6
  end
@@ -6,15 +6,13 @@ module Restate
6
6
  #
7
7
  # @example
8
8
  # class Counter < Restate::VirtualObject
9
- # handler def add(addend)
10
- # ctx = Restate.current_object_context
9
+ # handler def add(ctx, addend)
11
10
  # old = ctx.get("count") || 0
12
11
  # ctx.set("count", old + addend)
13
12
  # old + addend
14
13
  # end
15
14
  #
16
- # shared def get
17
- # ctx = Restate.current_object_context
15
+ # shared def get(ctx)
18
16
  # ctx.get("count") || 0
19
17
  # end
20
18
  # end
@@ -22,7 +20,7 @@ module Restate
22
20
  extend T::Sig
23
21
  extend ServiceDSL
24
22
 
25
- # Register an exclusive handler. Use as: +handler def my_method(arg)+
23
+ # Register an exclusive handler. Use as: +handler def my_method(ctx, arg)+
26
24
  #
27
25
  # @param method_name [Symbol] name of the method to register
28
26
  # @param kind [Symbol] concurrency mode (+:exclusive+ or +:shared+)
@@ -6,12 +6,11 @@ module Restate
6
6
  #
7
7
  # @example
8
8
  # class Signup < Restate::Workflow
9
- # main def run(email)
9
+ # main def run(ctx, email)
10
10
  # # workflow logic
11
11
  # end
12
12
  #
13
- # handler def status
14
- # ctx = Restate.current_workflow_context
13
+ # handler def status(ctx)
15
14
  # ctx.get("status")
16
15
  # end
17
16
  # end
@@ -20,7 +19,7 @@ module Restate
20
19
  extend ServiceDSL
21
20
 
22
21
  # Register the main workflow entry point.
23
- # Use as: +main def run(arg)+ or +main :run, input: String+
22
+ # Use as: +main def run(ctx, arg)+ or +main :run, input: String+
24
23
  #
25
24
  # @param method_name [Symbol] name of the method to register
26
25
  # @param opts [Hash] handler options (+input:+, +output:+, +accept:+, +content_type:+)
data/lib/restate.rb CHANGED
@@ -46,12 +46,12 @@ module Restate
46
46
 
47
47
  # ── Fiber-local context accessors ──
48
48
  #
49
- # The SDK stores the current handler context in fiber-local storage
50
- # (Thread.current[], which is fiber-scoped in Ruby). These methods
51
- # retrieve it with the appropriate type for IDE completion.
49
+ # The SDK passes the context as the first argument to every handler.
50
+ # It is also stored in fiber-local storage (Thread.current[], which is
51
+ # fiber-scoped in Ruby). These methods retrieve it with the appropriate
52
+ # type for IDE completion.
52
53
  #
53
- # Use these instead of the +ctx+ parameter when you need the context
54
- # from a nested method that doesn't have +ctx+ in scope.
54
+ # Use these from nested helper methods that don't have +ctx+ in scope.
55
55
 
56
56
  # Returns the current context for a Service handler.
57
57
  # Raises if called outside a Restate handler.
@@ -3,14 +3,15 @@
3
3
 
4
4
  return unless defined?(Tapioca::Dsl::Compiler)
5
5
 
6
+ require 'restate'
7
+
6
8
  module Tapioca
7
9
  module Dsl
8
10
  module Compilers
9
11
  # Generates Sorbet sigs for Restate handler methods.
10
12
  #
11
- # Handlers no longer receive +ctx+ as a parameter context is accessed
12
- # via fiber-local +Restate.current_context+ (or typed variants). This
13
- # compiler generates sigs reflecting the actual handler arity (0 or 1).
13
+ # Every handler receives +ctx+ as its first parameter. Handlers that
14
+ # accept input receive it as the second parameter (arity 2).
14
15
  #
15
16
  # Usage:
16
17
  # bundle exec tapioca dsl
@@ -19,6 +20,10 @@ module Tapioca
19
20
 
20
21
  class << self
21
22
  def gather_constants
23
+ # Load service files so they're visible to all_classes.
24
+ # In non-Rails apps, Tapioca doesn't auto-load application code.
25
+ load_service_files
26
+
22
27
  all_classes.select do |klass|
23
28
  klass.is_a?(Class) && (
24
29
  klass < ::Restate::Service ||
@@ -29,16 +34,82 @@ module Tapioca
29
34
  false
30
35
  end
31
36
  end
37
+
38
+ private
39
+
40
+ def load_service_files # rubocop:disable Metrics/MethodLength
41
+ root = Bundler.root.to_s
42
+ patterns = [
43
+ "#{root}/*.rb",
44
+ "#{root}/app/**/*.rb",
45
+ "#{root}/services/**/*.rb",
46
+ "#{root}/examples/**/*.rb"
47
+ ]
48
+ Dir.glob(patterns).each do |file|
49
+ next if file.end_with?('config.ru', 'Rakefile')
50
+
51
+ require file
52
+ rescue LoadError, StandardError
53
+ nil # skip files that can't be loaded
54
+ end
55
+ end
32
56
  end
33
57
 
34
- def decorate
58
+ def decorate # rubocop:disable Metrics/MethodLength
35
59
  root.create_path(constant) do |klass|
36
60
  constant.handlers.each do |name, handler|
37
- params = handler.arity == 1 ? [create_param('input', type: 'T.untyped')] : []
38
- klass.create_method(name, parameters: params, return_type: 'T.untyped')
61
+ ctx_type = resolve_context_type(constant, handler)
62
+ params = [create_param('ctx', type: ctx_type)]
63
+ if handler.arity == 2
64
+ input_type = resolve_input_type(handler)
65
+ params << create_param('input', type: input_type)
66
+ end
67
+ output_type = resolve_output_type(handler)
68
+ klass.create_method(name, parameters: params, return_type: output_type)
39
69
  end
40
70
  end
41
71
  end
72
+
73
+ private
74
+
75
+ # Maps (service kind, handler kind) to the correct context module.
76
+ def resolve_context_type(klass, handler)
77
+ if klass < ::Restate::Workflow
78
+ handler.kind == 'workflow' ? 'Restate::WorkflowContext' : 'Restate::WorkflowSharedContext'
79
+ elsif klass < ::Restate::VirtualObject
80
+ handler.kind == 'shared' ? 'Restate::ObjectSharedContext' : 'Restate::ObjectContext'
81
+ else
82
+ 'Restate::Context'
83
+ end
84
+ end
85
+
86
+ # Resolves the Sorbet type string for the handler's input serde.
87
+ def resolve_input_type(handler)
88
+ type_class = handler.handler_io&.input_serde
89
+ sorbet_type_name(type_class) || 'T.untyped'
90
+ end
91
+
92
+ # Resolves the Sorbet type string for the handler's output serde.
93
+ def resolve_output_type(handler)
94
+ type_class = handler.handler_io&.output_serde
95
+ sorbet_type_name(type_class) || 'T.untyped'
96
+ end
97
+
98
+ # Returns a Sorbet type string if the serde wraps a known type, nil otherwise.
99
+ def sorbet_type_name(serde)
100
+ return nil if serde.nil?
101
+
102
+ # TStructSerde exposes .struct_class (T::Struct subclasses are visible to Sorbet)
103
+ return serde.struct_class.name if serde.is_a?(::Restate::TStructSerde)
104
+
105
+ # TypeSerde wraps a primitive type in .type_class
106
+ if serde.respond_to?(:type_class)
107
+ name = serde.type_class.name
108
+ return name if %w[String Integer Float].include?(name)
109
+ end
110
+
111
+ nil
112
+ end
42
113
  end
43
114
  end
44
115
  end
@@ -0,0 +1,307 @@
1
+ # typed: true
2
+
3
+ # RBI shipped with the restate-sdk gem.
4
+ # Tapioca merges this automatically when users run `tapioca gems`.
5
+
6
+ module Restate
7
+ # Create an endpoint, optionally binding services.
8
+ sig do
9
+ params(
10
+ services: T.untyped,
11
+ protocol: T.nilable(String),
12
+ identity_keys: T.nilable(T::Array[String])
13
+ ).returns(Restate::Endpoint)
14
+ end
15
+ def self.endpoint(*services, protocol: nil, identity_keys: nil); end
16
+
17
+ # Returns the current context (any handler).
18
+ sig { returns(Restate::Context) }
19
+ def self.current_context; end
20
+
21
+ # Returns the current context for a VirtualObject exclusive handler.
22
+ sig { returns(Restate::ObjectContext) }
23
+ def self.current_object_context; end
24
+
25
+ # Returns the current context for a VirtualObject shared handler.
26
+ sig { returns(Restate::ObjectSharedContext) }
27
+ def self.current_shared_context; end
28
+
29
+ # Returns the current context for a Workflow main handler.
30
+ sig { returns(Restate::WorkflowContext) }
31
+ def self.current_workflow_context; end
32
+
33
+ # Returns the current context for a Workflow shared handler.
34
+ sig { returns(Restate::WorkflowSharedContext) }
35
+ def self.current_shared_workflow_context; end
36
+
37
+ class TerminalError < StandardError
38
+ sig { returns(Integer) }
39
+ def status_code; end
40
+
41
+ sig { params(message: String, status_code: Integer).void }
42
+ def initialize(message = '', status_code: 500); end
43
+ end
44
+
45
+ class AttemptFinishedEvent
46
+ sig { returns(T::Boolean) }
47
+ def set?; end
48
+
49
+ sig { void }
50
+ def wait; end
51
+ end
52
+
53
+ Request = T.type_alias { T.untyped }
54
+
55
+ class RunRetryPolicy < T::Struct
56
+ const :initial_interval, T.nilable(Integer)
57
+ const :max_attempts, T.nilable(Integer)
58
+ const :max_duration, T.nilable(Integer)
59
+ const :max_interval, T.nilable(Integer)
60
+ const :interval_factor, T.nilable(Float)
61
+ end
62
+
63
+ class DurableFuture
64
+ sig { returns(T.untyped) }
65
+ def await; end
66
+
67
+ sig { returns(T::Boolean) }
68
+ def completed?; end
69
+
70
+ sig { returns(Integer) }
71
+ def handle; end
72
+ end
73
+
74
+ class DurableCallFuture < DurableFuture
75
+ sig { returns(String) }
76
+ def invocation_id; end
77
+
78
+ sig { void }
79
+ def cancel; end
80
+ end
81
+
82
+ class SendHandle
83
+ sig { returns(String) }
84
+ def invocation_id; end
85
+
86
+ sig { void }
87
+ def cancel; end
88
+ end
89
+
90
+ # Base context interface for all Restate handlers.
91
+ module Context
92
+ sig do
93
+ params(
94
+ name: String, serde: T.untyped, retry_policy: T.nilable(RunRetryPolicy),
95
+ background: T::Boolean, action: T.proc.returns(T.untyped)
96
+ ).returns(DurableFuture)
97
+ end
98
+ def run(name, serde: Restate::JsonSerde, retry_policy: nil, background: false, &action); end
99
+
100
+ sig do
101
+ params(
102
+ name: String, serde: T.untyped, retry_policy: T.nilable(RunRetryPolicy),
103
+ background: T::Boolean, action: T.proc.returns(T.untyped)
104
+ ).returns(T.untyped)
105
+ end
106
+ def run_sync(name, serde: Restate::JsonSerde, retry_policy: nil, background: false, &action); end
107
+
108
+ sig { params(seconds: Numeric).returns(DurableFuture) }
109
+ def sleep(seconds); end
110
+
111
+ sig do
112
+ params(
113
+ service: T.any(String, T::Class[T.anything]), handler: T.any(String, Symbol),
114
+ arg: T.untyped, key: T.nilable(String), idempotency_key: T.nilable(String),
115
+ headers: T.nilable(T::Hash[String, String]), input_serde: T.untyped, output_serde: T.untyped
116
+ ).returns(DurableCallFuture)
117
+ end
118
+ def service_call(service, handler, arg, key: nil, idempotency_key: nil, headers: nil,
119
+ input_serde: T.unsafe(nil), output_serde: T.unsafe(nil)); end
120
+
121
+ sig do
122
+ params(
123
+ service: T.any(String, T::Class[T.anything]), handler: T.any(String, Symbol),
124
+ arg: T.untyped, key: T.nilable(String), delay: T.nilable(Numeric),
125
+ idempotency_key: T.nilable(String), headers: T.nilable(T::Hash[String, String]),
126
+ input_serde: T.untyped
127
+ ).returns(SendHandle)
128
+ end
129
+ def service_send(service, handler, arg, key: nil, delay: nil, idempotency_key: nil,
130
+ headers: nil, input_serde: T.unsafe(nil)); end
131
+
132
+ sig do
133
+ params(
134
+ service: T.any(String, T::Class[T.anything]), handler: T.any(String, Symbol),
135
+ key: String, arg: T.untyped, idempotency_key: T.nilable(String),
136
+ headers: T.nilable(T::Hash[String, String]), input_serde: T.untyped, output_serde: T.untyped
137
+ ).returns(DurableCallFuture)
138
+ end
139
+ def object_call(service, handler, key, arg, idempotency_key: nil, headers: nil,
140
+ input_serde: T.unsafe(nil), output_serde: T.unsafe(nil)); end
141
+
142
+ sig do
143
+ params(
144
+ service: T.any(String, T::Class[T.anything]), handler: T.any(String, Symbol),
145
+ key: String, arg: T.untyped, delay: T.nilable(Numeric),
146
+ idempotency_key: T.nilable(String), headers: T.nilable(T::Hash[String, String]),
147
+ input_serde: T.untyped
148
+ ).returns(SendHandle)
149
+ end
150
+ def object_send(service, handler, key, arg, delay: nil, idempotency_key: nil,
151
+ headers: nil, input_serde: T.unsafe(nil)); end
152
+
153
+ sig do
154
+ params(
155
+ service: T.any(String, T::Class[T.anything]), handler: T.any(String, Symbol),
156
+ key: String, arg: T.untyped, idempotency_key: T.nilable(String),
157
+ headers: T.nilable(T::Hash[String, String]), input_serde: T.untyped, output_serde: T.untyped
158
+ ).returns(DurableCallFuture)
159
+ end
160
+ def workflow_call(service, handler, key, arg, idempotency_key: nil, headers: nil,
161
+ input_serde: T.unsafe(nil), output_serde: T.unsafe(nil)); end
162
+
163
+ sig do
164
+ params(
165
+ service: T.any(String, T::Class[T.anything]), handler: T.any(String, Symbol),
166
+ key: String, arg: T.untyped, delay: T.nilable(Numeric),
167
+ idempotency_key: T.nilable(String), headers: T.nilable(T::Hash[String, String]),
168
+ input_serde: T.untyped
169
+ ).returns(SendHandle)
170
+ end
171
+ def workflow_send(service, handler, key, arg, delay: nil, idempotency_key: nil,
172
+ headers: nil, input_serde: T.unsafe(nil)); end
173
+
174
+ sig do
175
+ params(
176
+ service: String, handler: String, arg: String,
177
+ key: T.nilable(String), idempotency_key: T.nilable(String),
178
+ headers: T.nilable(T::Hash[String, String])
179
+ ).returns(DurableCallFuture)
180
+ end
181
+ def generic_call(service, handler, arg, key: nil, idempotency_key: nil, headers: nil); end
182
+
183
+ sig do
184
+ params(
185
+ service: String, handler: String, arg: String,
186
+ key: T.nilable(String), delay: T.nilable(Numeric),
187
+ idempotency_key: T.nilable(String), headers: T.nilable(T::Hash[String, String])
188
+ ).returns(SendHandle)
189
+ end
190
+ def generic_send(service, handler, arg, key: nil, delay: nil, idempotency_key: nil, headers: nil); end
191
+
192
+ sig { params(serde: T.untyped).returns([String, DurableFuture]) }
193
+ def awakeable(serde: Restate::JsonSerde); end
194
+
195
+ sig { params(awakeable_id: String, payload: T.untyped, serde: T.untyped).void }
196
+ def resolve_awakeable(awakeable_id, payload, serde: Restate::JsonSerde); end
197
+
198
+ sig { params(awakeable_id: String, message: String, code: Integer).void }
199
+ def reject_awakeable(awakeable_id, message, code: 500); end
200
+
201
+ sig { params(invocation_id: String).void }
202
+ def cancel_invocation(invocation_id); end
203
+
204
+ sig { params(futures: DurableFuture).returns([T::Array[DurableFuture], T::Array[DurableFuture]]) }
205
+ def wait_any(*futures); end
206
+
207
+ sig { returns(T.untyped) }
208
+ def request; end
209
+
210
+ sig { returns(String) }
211
+ def key; end
212
+ end
213
+
214
+ # VirtualObject shared handler context (read-only state).
215
+ module ObjectSharedContext
216
+ include Context
217
+
218
+ sig { params(name: String, serde: T.untyped).returns(T.untyped) }
219
+ def get(name, serde: Restate::JsonSerde); end
220
+
221
+ sig { params(name: String, serde: T.untyped).returns(DurableFuture) }
222
+ def get_async(name, serde: Restate::JsonSerde); end
223
+
224
+ sig { returns(T.untyped) }
225
+ def state_keys; end
226
+
227
+ sig { returns(DurableFuture) }
228
+ def state_keys_async; end
229
+ end
230
+
231
+ # VirtualObject exclusive handler context (full state access).
232
+ module ObjectContext
233
+ include ObjectSharedContext
234
+
235
+ sig { params(name: String, value: T.untyped, serde: T.untyped).void }
236
+ def set(name, value, serde: Restate::JsonSerde); end
237
+
238
+ sig { params(name: String).void }
239
+ def clear(name); end
240
+
241
+ sig { void }
242
+ def clear_all; end
243
+ end
244
+
245
+ # Workflow shared handler context (read-only state + promises).
246
+ module WorkflowSharedContext
247
+ include ObjectSharedContext
248
+
249
+ sig { params(name: String, serde: T.untyped).returns(T.untyped) }
250
+ def promise(name, serde: Restate::JsonSerde); end
251
+
252
+ sig { params(name: String, serde: T.untyped).returns(T.untyped) }
253
+ def peek_promise(name, serde: Restate::JsonSerde); end
254
+
255
+ sig { params(name: String, payload: T.untyped, serde: T.untyped).void }
256
+ def resolve_promise(name, payload, serde: Restate::JsonSerde); end
257
+
258
+ sig { params(name: String, message: String, code: Integer).void }
259
+ def reject_promise(name, message, code: 500); end
260
+ end
261
+
262
+ # Workflow main handler context (full state + promises).
263
+ module WorkflowContext
264
+ include ObjectContext
265
+
266
+ sig { params(name: String, serde: T.untyped).returns(T.untyped) }
267
+ def promise(name, serde: Restate::JsonSerde); end
268
+
269
+ sig { params(name: String, serde: T.untyped).returns(T.untyped) }
270
+ def peek_promise(name, serde: Restate::JsonSerde); end
271
+
272
+ sig { params(name: String, payload: T.untyped, serde: T.untyped).void }
273
+ def resolve_promise(name, payload, serde: Restate::JsonSerde); end
274
+
275
+ sig { params(name: String, message: String, code: Integer).void }
276
+ def reject_promise(name, message, code: 500); end
277
+ end
278
+
279
+ # Stateless service base class.
280
+ class Service; end
281
+
282
+ # Keyed virtual object base class.
283
+ class VirtualObject; end
284
+
285
+ # Durable workflow base class.
286
+ class Workflow; end
287
+
288
+ class Endpoint
289
+ sig { params(services: T.untyped).void }
290
+ def bind(*services); end
291
+
292
+ sig { void }
293
+ def streaming_protocol; end
294
+
295
+ sig { void }
296
+ def request_response_protocol; end
297
+
298
+ sig { params(key: String).void }
299
+ def identity_key(key); end
300
+
301
+ sig { returns(T.untyped) }
302
+ def app; end
303
+ end
304
+
305
+ module JsonSerde; end
306
+ module BytesSerde; end
307
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: restate-sdk
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.4
4
+ version: 0.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Restate Developers
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-03-17 00:00:00.000000000 Z
11
+ date: 2026-03-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: async
@@ -86,6 +86,7 @@ files:
86
86
  - lib/restate/vm.rb
87
87
  - lib/restate/workflow.rb
88
88
  - lib/tapioca/dsl/compilers/restate.rb
89
+ - rbi/restate-sdk.rbi
89
90
  homepage: https://github.com/restatedev/sdk-ruby
90
91
  licenses:
91
92
  - MIT