decider 0.10.0 → 2.0.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.

Potentially problematic release.


This version of decider might be problematic. Click here for more details.

@@ -1,142 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Decider
4
- module Reactor
5
- class Module < ::Module
6
- REACT_FALLBACK = proc { [nil, proc {}] }
7
-
8
- React = Data.define(:action_result, :_actions) do
9
- def issue(*actions)
10
- _actions.push(*actions)
11
- end
12
- end
13
-
14
- def initialize(reactions:)
15
- define_method(:react) do |action_result|
16
- context = React.new(action_result: action_result, _actions: [])
17
-
18
- reactions.find(REACT_FALLBACK) do |arg, _|
19
- case arg
20
- in Proc => fn
21
- context.instance_exec(&fn)
22
- in artype
23
- action_result in ^artype
24
- else
25
- false
26
- end
27
- end => [_, handler]
28
-
29
- context.instance_exec(&handler)
30
- context._actions
31
- end
32
-
33
- define_method(:lmap_on_action_result) do |fn|
34
- Decider::Reactor.lmap_on_action_result(fn, self)
35
- end
36
-
37
- define_method(:rmap_on_action) do |fn|
38
- Decider::Reactor.rmap_on_action(fn, self)
39
- end
40
-
41
- define_method(:map_on_action) do |fn|
42
- Decider::Reactor.rmap_on_action(fn, self)
43
- end
44
-
45
- define_method(:combine_with_decider) do |decider|
46
- Decider::Reactor.combine_with_decider(self, decider)
47
- end
48
- end
49
- end
50
-
51
- class Builder
52
- DEFAULT = Object.new
53
-
54
- def initialize
55
- @reactions = {}
56
- end
57
-
58
- def build(&block)
59
- instance_exec(&block) if block_given?
60
-
61
- reactor = Class.new
62
-
63
- mod = Module.new(
64
- reactions: reactions
65
- )
66
-
67
- reactor.extend(mod)
68
-
69
- reactor
70
- end
71
-
72
- private
73
-
74
- attr_reader :reactions
75
-
76
- def react(arg, &block)
77
- reactions[arg] = block
78
- end
79
- end
80
- private_constant :Builder
81
-
82
- def self.define(&block)
83
- builder = Builder.new
84
- builder.build(&block)
85
- end
86
-
87
- def self.lmap_on_action_result(fn, reactor)
88
- define do
89
- react proc { true } do
90
- reactor.react(fn.call(action_result)).each do |action|
91
- issue action
92
- end
93
- end
94
- end
95
- end
96
-
97
- def self.rmap_on_action(fn, reactor)
98
- define do
99
- react proc { true } do
100
- reactor.react(action_result).each do |action|
101
- issue fn.call(action)
102
- end
103
- end
104
- end
105
- end
106
-
107
- def self.map_on_action(fn, reactor)
108
- rmap_on_action(fn, reactor)
109
- end
110
-
111
- def self.combine_with_decider(reactor, decider)
112
- Decider.define do
113
- initial_state decider.initial_state
114
-
115
- decide proc { true } do
116
- fn = ->(commands, events, ds) {
117
- case commands
118
- in []
119
- events
120
- in [head, *tail]
121
- new_events = decider.decide(head, ds)
122
- new_commands = new_events.flat_map { |action_result| reactor.react(action_result) }
123
- new_state = new_events.reduce(ds, &decider.evolve)
124
-
125
- fn.call(tail + new_commands, events + new_events, new_state)
126
- end
127
- }
128
-
129
- fn.call([command], [], state).each { |event| emit event }
130
- end
131
-
132
- evolve proc { true } do
133
- decider.evolve(state, event)
134
- end
135
-
136
- terminal? do
137
- decider.terminal?(state)
138
- end
139
- end
140
- end
141
- end
142
- end
data/lib/decider/state.rb DELETED
@@ -1,25 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Decider
4
- class State
5
- def initialize(decider:, repository:)
6
- @decider = decider
7
- @repository = repository
8
- end
9
-
10
- def call(command, key:, etag: nil)
11
- state, etag = repository.try_load(key: key, etag: etag)
12
-
13
- events = decider.decide(command, state)
14
- new_state = events.reduce(state, &decider.method(:evolve))
15
-
16
- new_etag = repository.save(new_state, key: key, etag: etag)
17
-
18
- [events, new_etag]
19
- end
20
-
21
- private
22
-
23
- attr_reader :decider, :repository
24
- end
25
- end
@@ -1,5 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Decider
4
- VERSION = "0.10.0"
5
- end
data/lib/decider/view.rb DELETED
@@ -1,169 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Decider::View
4
- StateAlreadyDefined = Class.new(StandardError)
5
- StateNotDefined = Class.new(StandardError)
6
-
7
- class Module < ::Module
8
- EVOLVE_FALLBACK = proc { [nil, proc { state }] }
9
-
10
- Evolve = Data.define(:state, :event) do
11
- def self.build(state, event)
12
- new(state: state, event: event)
13
- end
14
- end
15
-
16
- def initialize(initial_state:, evolutions:)
17
- case initial_state
18
- in Proc
19
- define_method(:initial_state) do
20
- initial_state.call
21
- end
22
- else
23
- define_method(:initial_state) do
24
- initial_state
25
- end
26
- end
27
-
28
- define_method(:evolve) do |*args|
29
- if args.empty?
30
- ->(state, event) { evolve(state, event) }
31
- else
32
- context = Evolve.build(*args)
33
-
34
- evolutions.find(EVOLVE_FALLBACK) do |args, _|
35
- case args
36
- in [Proc => fn]
37
- context.instance_exec(&fn)
38
- in [etype]
39
- context_event = context.event
40
- context_event in ^etype
41
- in [stype, etype]
42
- context_state = context.state
43
- context_event = context.event
44
- [context_state, context_event] in [^stype, ^etype]
45
- else
46
- false
47
- end
48
- end => [_, handler]
49
-
50
- context.instance_exec(&handler)
51
- end
52
- end
53
-
54
- define_method(:lmap_on_event) do |fn|
55
- Decider::View.lmap_on_event(fn, self)
56
- end
57
-
58
- define_method(:lmap_on_state) do |fn|
59
- Decider::View.lmap_on_state(fn, self)
60
- end
61
-
62
- define_method(:rmap_on_state) do |fn|
63
- Decider::View.rmap_on_state(fn, self)
64
- end
65
-
66
- define_method(:dimap_on_state) do |fl:, fr:|
67
- Decider::View.dimap_on_state(fl, fr, self)
68
- end
69
-
70
- define_method(:many) do
71
- Decider::View.many(self)
72
- end
73
- end
74
- end
75
-
76
- class Builder
77
- DEFAULT = Object.new
78
-
79
- def initialize
80
- @initial_state = DEFAULT
81
- @evolutions = {}
82
- end
83
-
84
- def build(&block)
85
- instance_exec(&block) if block_given?
86
-
87
- raise StateNotDefined if @initial_state == DEFAULT
88
-
89
- view = Class.new
90
-
91
- mod = Module.new(
92
- initial_state: @initial_state,
93
- evolutions: evolutions
94
- )
95
-
96
- view.extend(mod)
97
-
98
- view
99
- end
100
-
101
- private
102
-
103
- attr_reader :evolutions
104
-
105
- def initial_state(state = DEFAULT, &block)
106
- raise StateAlreadyDefined if @initial_state != DEFAULT
107
-
108
- @initial_state =
109
- if block_given?
110
- block
111
- else
112
- state
113
- end
114
- end
115
-
116
- def evolve(*args, &block)
117
- evolutions[args] = block
118
- end
119
- end
120
- private_constant :Builder
121
-
122
- def self.define(&block)
123
- builder = Builder.new
124
- builder.build(&block)
125
- end
126
-
127
- def self.lmap_on_event(fn, view)
128
- define do
129
- initial_state view.initial_state
130
-
131
- evolve proc { true } do
132
- view.evolve(state, fn.call(event))
133
- end
134
- end
135
- end
136
-
137
- def self.lmap_on_state(fn, view)
138
- dimap_on_state(fn, ->(state) { state }, view)
139
- end
140
-
141
- def self.rmap_on_state(fn, view)
142
- dimap_on_state(->(state) { state }, fn, view)
143
- end
144
-
145
- def self.dimap_on_state(fl, fr, view)
146
- define do
147
- initial_state fr.call(view.initial_state)
148
-
149
- evolve proc { true } do
150
- fr.call(view.evolve(fl.call(state), event))
151
- end
152
- end
153
- end
154
-
155
- def self.many(view)
156
- define do
157
- initial_state({})
158
-
159
- evolve proc { [state, event] in [Hash, [_id, _]] } do
160
- event => [id, event]
161
-
162
- vs = state.fetch(id) { view.initial_state }
163
- vs = view.evolve(vs, event)
164
-
165
- state.merge(id => vs)
166
- end
167
- end
168
- end
169
- end
data/mise.toml DELETED
@@ -1,17 +0,0 @@
1
- [env]
2
- _.path = ["bin"]
3
-
4
- [tools]
5
- ruby = "4.0.2"
6
-
7
- [tasks.test]
8
- run = "bundle exec rake"
9
- alias = "t"
10
-
11
- [tasks.console]
12
- run = "console"
13
- alias = "c"
14
-
15
- [tasks.release]
16
- run = "bundle exec rake release"
17
- alias = "r"
data/sig/decider.rbs DELETED
@@ -1,16 +0,0 @@
1
- module Decider
2
- VERSION: String
3
-
4
- interface _Decider[C, S, E]
5
- def decide: (C, S) -> Array[E]
6
-
7
- def evolve: (S, E) -> S
8
-
9
- def initial_state: () -> S
10
-
11
- def terminal?: (S) -> bool
12
- end
13
-
14
- def self.compose: [C1, S1, E1, C2, S2, E2] (_Decider[C1, S1, E1], _Decider[C2, S2, E2]) -> _Decider[C1 | C2, S1 & S2, E1 | E2]
15
- def self.define: [C, S, E] () -> _Decider[C, S, E]
16
- end