Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ sorbet/rbi/gems/
sorbet/rbi/dsl/
sorbet/rbi/annotations/

# Sub-project lock files (middleware_example has its own Gemfile)
middleware_example/Gemfile.lock

# OS
.DS_Store
Thumbs.db
12 changes: 1 addition & 11 deletions .rubocop.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
plugins:
- rubocop-sorbet

AllCops:
TargetRubyVersion: 3.1
NewCops: enable
Expand All @@ -9,7 +6,6 @@ AllCops:
- "ext/**/*"
- ".bundle/**/*"
- "pkg/**/*"
- "sorbet/rbi/**/*"
- "spec/**/*"
- "tmp/**/*"
- "vendor/**/*"
Expand Down Expand Up @@ -85,6 +81,7 @@ Metrics/BlockLength:
Metrics/ParameterLists:
Exclude:
- "lib/restate.rb"
- "lib/restate/context.rb"
- "lib/restate/server_context.rb"
- "lib/restate/virtual_object.rb"
- "lib/restate/vm.rb"
Expand All @@ -94,13 +91,6 @@ Lint/DuplicateBranch:
Exclude:
- "lib/restate/server.rb"

# Sorbet sigs require named block parameters, conflicts with anonymous forwarding
Naming/BlockForwarding:
Enabled: false

Style/ArgumentsForwarding:
Enabled: false

# These marker classes are intentionally empty (used as type tags)
Lint/EmptyClass:
Exclude:
Expand Down
3 changes: 1 addition & 2 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,8 @@ group :development, :test do
gem 'falcon', '~> 0.47', require: false
gem 'rspec', '~> 3.12'
gem 'rubocop', require: false
gem 'rubocop-sorbet', require: false
gem 'sorbet', require: false
gem 'tapioca', require: false
gem 'steep', require: false
gem 'testcontainers-core', require: false

# For middleware_example/
Expand Down
111 changes: 62 additions & 49 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,23 @@ PATH
restate-sdk (0.7.0)
async (~> 2.0)
rack (>= 2.0)
sorbet-runtime

GEM
remote: https://rubygems.org/
specs:
activesupport (8.1.2)
base64
bigdecimal
concurrent-ruby (~> 1.0, >= 1.3.1)
connection_pool (>= 2.2.5)
drb
i18n (>= 1.6, < 2)
json
logger (>= 1.4.2)
minitest (>= 5.1)
securerandom (>= 0.3)
tzinfo (~> 2.0, >= 2.0.5)
uri (>= 0.13.1)
addressable (2.8.9)
public_suffix (>= 2.0.2, < 8.0)
ast (2.4.3)
Expand Down Expand Up @@ -42,17 +54,19 @@ GEM
async-utilization (0.3.1)
console (~> 1.0)
base64 (0.3.0)
benchmark (0.5.0)
bigdecimal (4.0.1)
concurrent-ruby (1.3.6)
connection_pool (3.0.2)
console (1.34.3)
fiber-annotation
fiber-local (~> 1.1)
json
csv (3.3.5)
diff-lcs (1.6.2)
docker-api (2.4.0)
excon (>= 0.64.0)
multi_json
drb (2.2.3)
dry-core (1.2.0)
concurrent-ruby (~> 1.0)
logger
Expand All @@ -75,7 +89,6 @@ GEM
dry-inflector (~> 1.0)
dry-logic (~> 1.4)
zeitwerk (~> 2.6)
erubi (1.13.1)
excon (1.4.0)
logger
falcon (0.55.2)
Expand All @@ -91,10 +104,15 @@ GEM
protocol-http (~> 0.31)
protocol-rack (~> 0.7)
samovar (~> 2.3)
ffi (1.17.3-arm64-darwin)
ffi (1.17.3-x86_64-linux-gnu)
fiber-annotation (0.2.0)
fiber-local (1.1.0)
fiber-storage
fiber-storage (1.0.1)
fileutils (1.8.0)
i18n (1.14.8)
concurrent-ruby (~> 1.0)
ice_nine (0.11.2)
io-endpoint (0.17.2)
io-event (1.14.4)
Expand All @@ -105,14 +123,21 @@ GEM
bigdecimal (>= 3.1, < 5)
language_server-protocol (3.17.0.5)
lint_roller (1.1.0)
listen (3.10.0)
logger
rb-fsevent (~> 0.10, >= 0.10.3)
rb-inotify (~> 0.9, >= 0.9.10)
localhost (1.7.0)
logger (1.7.0)
mapping (1.1.3)
mcp (0.8.0)
json-schema (>= 4.1)
metrics (0.15.0)
minitest (6.0.2)
drb (~> 2.0)
prism (~> 1.5)
multi_json (1.19.1)
netrc (0.11.0)
mutex_m (0.3.0)
openssl (4.0.1)
opentelemetry-api (1.8.0)
logger
Expand Down Expand Up @@ -152,18 +177,15 @@ GEM
rake-compiler (1.3.1)
rake
rake-compiler-dock (1.11.0)
rb-fsevent (0.11.2)
rb-inotify (0.11.1)
ffi (~> 1.0)
rb_sys (0.9.124)
rake-compiler-dock (= 1.11.0)
rbi (0.3.9)
prism (~> 1.0)
rbs (>= 3.4.4)
rbs (4.0.0)
rbs (3.10.3)
logger
prism (>= 1.6.0)
tsort
regexp_parser (2.11.3)
require-hooks (0.2.3)
rexml (3.4.4)
rspec (3.13.2)
rspec-core (~> 3.13.0)
rspec-expectations (~> 3.13.0)
Expand Down Expand Up @@ -192,54 +214,46 @@ GEM
rubocop-ast (1.49.1)
parser (>= 3.3.7.2)
prism (~> 1.7)
rubocop-sorbet (0.12.0)
lint_roller
rubocop (>= 1.75.2)
ruby-progressbar (1.13.0)
samovar (2.4.1)
console (~> 1.0)
mapping (~> 1.0)
sorbet (0.6.13043)
sorbet-static (= 0.6.13043)
sorbet-runtime (0.6.13043)
sorbet-static (0.6.13043-universal-darwin)
sorbet-static (0.6.13043-x86_64-linux)
sorbet-static-and-runtime (0.6.13043)
sorbet (= 0.6.13043)
sorbet-runtime (= 0.6.13043)
spoom (1.7.11)
erubi (>= 1.10.0)
prism (>= 0.28.0)
rbi (>= 0.3.3)
rbs (>= 4.0.0.dev.4)
rexml (>= 3.2.6)
sorbet-static-and-runtime (>= 0.5.10187)
thor (>= 0.19.2)
securerandom (0.4.1)
sorbet (0.6.13051)
sorbet-static (= 0.6.13051)
sorbet-static (0.6.13051-universal-darwin)
sorbet-static (0.6.13051-x86_64-linux)
steep (1.10.0)
activesupport (>= 5.1)
concurrent-ruby (>= 1.1.10)
csv (>= 3.0.9)
fileutils (>= 1.1.0)
json (>= 2.1.0)
language_server-protocol (>= 3.17.0.4, < 4.0)
listen (~> 3.0)
logger (>= 1.3.0)
mutex_m (>= 0.3.0)
parser (>= 3.1)
rainbow (>= 2.2.2, < 4.0)
rbs (~> 3.9)
securerandom (>= 0.1)
strscan (>= 1.0.0)
terminal-table (>= 2, < 5)
uri (>= 0.12.0)
string-format (0.2.0)
tapioca (0.18.0)
benchmark
bundler (>= 2.2.25)
netrc (>= 0.11.0)
parallel (>= 1.21.0)
rbi (>= 0.3.7)
require-hooks (>= 0.2.2)
sorbet-static-and-runtime (>= 0.5.11087)
spoom (>= 1.7.9)
thor (>= 1.2.0)
tsort
yard-sorbet
strscan (3.1.7)
terminal-table (4.0.0)
unicode-display_width (>= 1.1.1, < 4)
testcontainers-core (0.2.0)
docker-api (~> 2.2)
thor (1.5.0)
traces (0.18.2)
tsort (0.2.0)
tzinfo (2.0.6)
concurrent-ruby (~> 1.0)
unicode-display_width (3.2.0)
unicode-emoji (~> 4.1)
unicode-emoji (4.2.0)
yard (0.9.38)
yard-sorbet (0.9.0)
sorbet-runtime
yard
uri (1.1.1)
zeitwerk (2.7.5)

PLATFORMS
Expand All @@ -258,9 +272,8 @@ DEPENDENCIES
restate-sdk!
rspec (~> 3.12)
rubocop
rubocop-sorbet
sorbet
tapioca
steep
testcontainers-core

BUNDLED WITH
Expand Down
23 changes: 10 additions & 13 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.PHONY: build compile test test-harness test-integration clean fmt check install typecheck lint lint-fix verify tapioca
.PHONY: build compile test test-harness test-integration clean fmt check install lint lint-fix typecheck verify

# Build the native extension and compile
build: compile
Expand All @@ -18,21 +18,18 @@ test-harness: compile
test-integration: compile
./etc/run-integration-tests.sh

# Generate Tapioca DSL RBI files (typed handler signatures)
tapioca: compile
bundle exec tapioca dsl

# Type checking
typecheck:
bundle exec srb tc

# Linting
lint:
bundle exec rubocop

lint-fix:
bundle exec rubocop -A

# Type check — Steep (public API, shipped RBS) + Sorbet (internal, dev-only)
typecheck:
bundle exec steep check
bundle exec srb tc

# Check Rust code compiles
check:
cargo check
Expand All @@ -54,8 +51,8 @@ install:
gem: compile
gem build restate-sdk.gemspec

# Build, lint, typecheck, and run unit tests (no integration tests)
verify: compile tapioca lint typecheck test-harness
# Build, lint, and run unit tests (no integration tests)
verify: compile lint typecheck test-harness

# Run everything (install, compile, test, typecheck, lint)
all: install compile test typecheck lint
# Run everything (install, compile, test, lint)
all: install compile test lint
25 changes: 15 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,23 +58,28 @@ Or add the gem to an existing project:
gem install restate-sdk
```

### Typed handlers with T::Struct
### Typed handlers with Dry::Struct

Use Sorbet's `T::Struct` for typed input/output with automatic JSON Schema generation:
Use [dry-struct](https://dry-rb.org/gems/dry-struct/) for typed input/output with automatic JSON Schema generation:

```ruby
require 'restate'
require 'dry-struct'

class RegistrationRequest < T::Struct
const :event_name, String
const :attendee, String
const :num_guests, Integer
const :note, T.nilable(String)
module Types
include Dry.Types()
end

class RegistrationResponse < T::Struct
const :registration_id, String
const :status, String
class RegistrationRequest < Dry::Struct
attribute :event_name, Types::String
attribute :attendee, Types::String
attribute :num_guests, Types::Integer
attribute? :note, Types::String # optional attribute
end

class RegistrationResponse < Dry::Struct
attribute :registration_id, Types::String
attribute :status, Types::String
end

class EventService < Restate::Service
Expand Down
39 changes: 39 additions & 0 deletions Steepfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# frozen_string_literal: true

# Steepfile — configuration for the Steep type checker.
# Run: bundle exec steep check

target :lib do
signature 'sig'

check 'lib/restate/config.rb'
check 'lib/restate/errors.rb'
check 'lib/restate/durable_future.rb'
check 'lib/restate/endpoint.rb'
check 'lib/restate/service_proxy.rb'
check 'lib/restate/client.rb'

# Files with heavy metaprogramming — skip for now
# check "lib/restate.rb" # module_function pattern
# check "lib/restate/service.rb" # extend ServiceDSL
# check "lib/restate/virtual_object.rb"
# check "lib/restate/workflow.rb"
# check "lib/restate/service_dsl.rb" # define_method
# check "lib/restate/server_context.rb"
# check "lib/restate/server.rb"
# check "lib/restate/vm.rb"
# check "lib/restate/context.rb"
# check "lib/restate/discovery.rb"
# check "lib/restate/serde.rb"
# check "lib/restate/handler.rb"
# check "lib/restate/testing.rb"

library 'json'
library 'net-http'
library 'uri'

# method_missing proxies can't be fully typed
configure_code_diagnostics do |hash|
hash[Steep::Diagnostic::Ruby::MethodArityMismatch] = :information
end
end
Loading
Loading