decide.rb 0.7.1 → 0.8.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 +4 -4
- data/CHANGELOG.md +26 -2
- data/lib/decider/reactor.rb +2 -4
- data/lib/decider/version.rb +1 -1
- data/lib/decider/view.rb +135 -0
- data/lib/decider.rb +9 -7
- metadata +4 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 4030eca80006638366697ffbe43f1881fa15229903086103d64416f704c8c431
|
|
4
|
+
data.tar.gz: c8896b205ef5d24b098a7fb61bae4a287980a01508a1c4ce94ec602d7ee6fc08
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4a64615c3f4ad63a0501ca740dfd8368a28004e1f76239c60b583e835c5a61dce095ee424f80d802df7058306b49d4ff7a59030cff1417a76991e9ee08275abd
|
|
7
|
+
data.tar.gz: 763ffe70ba2be9a55f8d51c6176632e63fe1bc3138c2f95dbe747d28b73eb8039894364a5cef3449b0adc79365569dee6eb01bbac761cee9813f5551cc469cb1
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,27 @@
|
|
|
1
|
+
# 0.8.1
|
|
2
|
+
|
|
3
|
+
* Fix support for Ruby > 3.4.5
|
|
4
|
+
|
|
5
|
+
# 0.8.0
|
|
6
|
+
|
|
7
|
+
* Add view that can evolve from initial state
|
|
8
|
+
|
|
9
|
+
```ruby
|
|
10
|
+
view = Decider::View.define do
|
|
11
|
+
initial_state 0
|
|
12
|
+
|
|
13
|
+
evolve :increased do
|
|
14
|
+
state + 1
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
evolve :decreased do
|
|
18
|
+
state - 1
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
* Add `lmap_on_event`, `dimap_on_state`, `lmap_on_state` and `rmap_on_state` extensions for view
|
|
24
|
+
|
|
1
25
|
# 0.7.0
|
|
2
26
|
|
|
3
27
|
* Add reactor that can react to action results and issue actions
|
|
@@ -6,7 +30,7 @@
|
|
|
6
30
|
ActionResult = Data.define(:value)
|
|
7
31
|
Action = Data.define(:value)
|
|
8
32
|
|
|
9
|
-
reactor = Reactor.define do
|
|
33
|
+
reactor = Decider::Reactor.define do
|
|
10
34
|
react :action_result do
|
|
11
35
|
issue :action
|
|
12
36
|
issue :another_action
|
|
@@ -82,7 +106,7 @@ deciders.evolve(state, [id, event])
|
|
|
82
106
|
|
|
83
107
|
```ruby
|
|
84
108
|
decider = Decider.map(fn.curry, deciderx)
|
|
85
|
-
decider = Decider.apply(decider, decidery)
|
|
109
|
+
decider = Decider.apply(decider, decidery)
|
|
86
110
|
decider = Decider.apply(decider, deciderz)
|
|
87
111
|
# or
|
|
88
112
|
deciderx.map(fn.curry).apply(decidery).apply(deciderz)
|
data/lib/decider/reactor.rb
CHANGED
|
@@ -51,8 +51,6 @@ module Decider
|
|
|
51
51
|
class Builder
|
|
52
52
|
DEFAULT = Object.new
|
|
53
53
|
|
|
54
|
-
attr_reader :module
|
|
55
|
-
|
|
56
54
|
def initialize
|
|
57
55
|
@reactions = {}
|
|
58
56
|
end
|
|
@@ -62,11 +60,11 @@ module Decider
|
|
|
62
60
|
|
|
63
61
|
reactor = Class.new
|
|
64
62
|
|
|
65
|
-
|
|
63
|
+
mod = Module.new(
|
|
66
64
|
reactions: reactions
|
|
67
65
|
)
|
|
68
66
|
|
|
69
|
-
reactor.extend(
|
|
67
|
+
reactor.extend(mod)
|
|
70
68
|
|
|
71
69
|
reactor
|
|
72
70
|
end
|
data/lib/decider/version.rb
CHANGED
data/lib/decider/view.rb
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Decider::View
|
|
4
|
+
class Module < ::Module
|
|
5
|
+
EVOLVE_FALLBACK = proc { [nil, proc { state }] }
|
|
6
|
+
|
|
7
|
+
Evolve = Data.define(:state, :event) do
|
|
8
|
+
def self.build(state, event)
|
|
9
|
+
new(state: state, event: event)
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def initialize(initial_state:, evolutions:)
|
|
14
|
+
define_method(:initial_state) do
|
|
15
|
+
initial_state
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
define_method(:evolve) do |*args|
|
|
19
|
+
if args.empty?
|
|
20
|
+
->(state, event) { evolve(state, event) }
|
|
21
|
+
else
|
|
22
|
+
context = Evolve.build(*args)
|
|
23
|
+
|
|
24
|
+
evolutions.find(EVOLVE_FALLBACK) do |args, _|
|
|
25
|
+
case args
|
|
26
|
+
in [Proc => fn]
|
|
27
|
+
context.instance_exec(&fn)
|
|
28
|
+
in [etype]
|
|
29
|
+
context_event = context.event
|
|
30
|
+
context_event in ^etype
|
|
31
|
+
in [stype, etype]
|
|
32
|
+
context_state = context.state
|
|
33
|
+
context_event = context.event
|
|
34
|
+
[context_state, context_event] in [^stype, ^etype]
|
|
35
|
+
else
|
|
36
|
+
false
|
|
37
|
+
end
|
|
38
|
+
end => [_, handler]
|
|
39
|
+
|
|
40
|
+
context.instance_exec(&handler)
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
define_method(:lmap_on_event) do |fn|
|
|
45
|
+
Decider::View.lmap_on_event(fn, self)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
define_method(:lmap_on_state) do |fn|
|
|
49
|
+
Decider::View.lmap_on_state(fn, self)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
define_method(:rmap_on_state) do |fn|
|
|
53
|
+
Decider::View.rmap_on_state(fn, self)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
define_method(:dimap_on_state) do |fl:, fr:|
|
|
57
|
+
Decider::View.dimap_on_state(fl, fr, self)
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
class Builder
|
|
63
|
+
DEFAULT = Object.new
|
|
64
|
+
|
|
65
|
+
def initialize
|
|
66
|
+
@initial_state = DEFAULT
|
|
67
|
+
@evolutions = {}
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def build(&block)
|
|
71
|
+
instance_exec(&block) if block_given?
|
|
72
|
+
|
|
73
|
+
raise StateNotDefined if @initial_state == DEFAULT
|
|
74
|
+
|
|
75
|
+
view = Class.new
|
|
76
|
+
|
|
77
|
+
mod = Module.new(
|
|
78
|
+
initial_state: @initial_state,
|
|
79
|
+
evolutions: evolutions
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
view.extend(mod)
|
|
83
|
+
|
|
84
|
+
view
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
private
|
|
88
|
+
|
|
89
|
+
attr_reader :evolutions
|
|
90
|
+
|
|
91
|
+
def initial_state(state)
|
|
92
|
+
raise StateAlreadyDefined if @initial_state != DEFAULT
|
|
93
|
+
|
|
94
|
+
@initial_state = state
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def evolve(*args, &block)
|
|
98
|
+
evolutions[args] = block
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
private_constant :Builder
|
|
102
|
+
|
|
103
|
+
def self.define(&block)
|
|
104
|
+
builder = Builder.new
|
|
105
|
+
builder.build(&block)
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def self.lmap_on_event(fn, view)
|
|
109
|
+
define do
|
|
110
|
+
initial_state view.initial_state
|
|
111
|
+
|
|
112
|
+
evolve proc { true } do
|
|
113
|
+
view.evolve(state, fn.call(event))
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def self.lmap_on_state(fn, view)
|
|
119
|
+
dimap_on_state(fn, ->(state) { state }, view)
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def self.rmap_on_state(fn, view)
|
|
123
|
+
dimap_on_state(->(state) { state }, fn, view)
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def self.dimap_on_state(fl, fr, view)
|
|
127
|
+
define do
|
|
128
|
+
initial_state fr.call(view.initial_state)
|
|
129
|
+
|
|
130
|
+
evolve proc { true } do
|
|
131
|
+
fr.call(view.evolve(fl.call(state), event))
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
end
|
data/lib/decider.rb
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
require_relative "decider/reactor"
|
|
4
|
+
require_relative "decider/view"
|
|
4
5
|
|
|
5
6
|
module Decider
|
|
6
7
|
StateAlreadyDefined = Class.new(StandardError)
|
|
@@ -92,9 +93,12 @@ module Decider
|
|
|
92
93
|
in [Proc => fn]
|
|
93
94
|
context.instance_exec(&fn)
|
|
94
95
|
in [etype]
|
|
95
|
-
context.event
|
|
96
|
+
context_event = context.event
|
|
97
|
+
context_event in ^etype
|
|
96
98
|
in [stype, etype]
|
|
97
|
-
|
|
99
|
+
context_state = context.state
|
|
100
|
+
context_event = context.event
|
|
101
|
+
[context_state, context_event] in [^stype, ^etype]
|
|
98
102
|
else
|
|
99
103
|
false
|
|
100
104
|
end
|
|
@@ -155,8 +159,6 @@ module Decider
|
|
|
155
159
|
class Builder
|
|
156
160
|
DEFAULT = Object.new
|
|
157
161
|
|
|
158
|
-
attr_reader :module
|
|
159
|
-
|
|
160
162
|
def initialize
|
|
161
163
|
@initial_state = DEFAULT
|
|
162
164
|
@deciders = {}
|
|
@@ -171,14 +173,14 @@ module Decider
|
|
|
171
173
|
|
|
172
174
|
decider = Class.new
|
|
173
175
|
|
|
174
|
-
|
|
176
|
+
mod = Module.new(
|
|
175
177
|
initial_state: @initial_state,
|
|
176
178
|
deciders: deciders,
|
|
177
179
|
evolutions: evolutions,
|
|
178
180
|
terminal: terminal
|
|
179
181
|
)
|
|
180
182
|
|
|
181
|
-
decider.extend(
|
|
183
|
+
decider.extend(mod)
|
|
182
184
|
|
|
183
185
|
decider
|
|
184
186
|
end
|
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: decide.rb
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.8.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Jan Dudulski
|
|
8
8
|
bindir: exe
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: concurrent-ruby
|
|
@@ -74,6 +74,7 @@ files:
|
|
|
74
74
|
- lib/decider/reactor.rb
|
|
75
75
|
- lib/decider/state.rb
|
|
76
76
|
- lib/decider/version.rb
|
|
77
|
+
- lib/decider/view.rb
|
|
77
78
|
- sig/decider.rbs
|
|
78
79
|
homepage: https://github.com/jandudulski/decide.rb
|
|
79
80
|
licenses:
|
|
@@ -99,7 +100,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
99
100
|
- !ruby/object:Gem::Version
|
|
100
101
|
version: '0'
|
|
101
102
|
requirements: []
|
|
102
|
-
rubygems_version: 3.6.
|
|
103
|
+
rubygems_version: 3.6.9
|
|
103
104
|
specification_version: 4
|
|
104
105
|
summary: Functional Event Sourcing Decider in Ruby
|
|
105
106
|
test_files: []
|