cdc-core 0.1.1 → 0.1.2
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 +5 -0
- data/README.md +69 -3
- data/lib/cdc/core/composite_processor.rb +5 -4
- data/lib/cdc/core/pipeline.rb +5 -4
- data/lib/cdc/core/processor_chain.rb +92 -0
- data/lib/cdc/core/processor_result.rb +21 -6
- data/lib/cdc/core/version.rb +1 -1
- data/lib/cdc/core.rb +1 -0
- data/sig/cdc/core/processor_chain.rbs +45 -0
- data/sig/cdc/core/processor_result.rbs +9 -2
- metadata +7 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b6b50778bfa61fb46ffb973eaa1975345cdbd6df15d4a719110dba339b63ed68
|
|
4
|
+
data.tar.gz: e461bc281b0147d2c8fdcfc1e3c95f209076070c3585858cc97c5c90585cc6ad
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 761888ea92dcd0c5f0a268bdb999016de811486fd69a3e2eaab457d1d4b21e1a79664214017961da69ec05adebcc2d99b98e2b433430a8d69e3f70e2967be8ca
|
|
7
|
+
data.tar.gz: 27c091d4e1f0b16a1c3503cc12af85ed9311e9650f028251fbf2334d81849359b15932d92b556e4ebd11f1ef51f7b37bfdbfe630f79087ff50c450b049f3c17e
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
## [Unreleased]
|
|
2
2
|
|
|
3
|
+
## [0.1.2] - 2026-06-10
|
|
4
|
+
|
|
5
|
+
- Added `CDC::Core::ProcessorChain` that feeds the successful value from one processor into the next processor
|
|
6
|
+
- Updated and enriched the API and Architecture documenation
|
|
7
|
+
|
|
3
8
|
## [0.1.1] - 2026-06-09
|
|
4
9
|
|
|
5
10
|
### Added
|
data/README.md
CHANGED
|
@@ -15,7 +15,7 @@ Shared Change Data Capture vocabulary for Ruby.
|
|
|
15
15
|
- Transaction grouping via `TransactionEnvelope`
|
|
16
16
|
- Column-level change objects
|
|
17
17
|
- Ordering vocabulary
|
|
18
|
-
- Processor
|
|
18
|
+
- Processor, composite processor, processor chain, and pipeline contracts
|
|
19
19
|
- Event filters
|
|
20
20
|
- Small pipeline orchestration object
|
|
21
21
|
- Router for supported work item shapes
|
|
@@ -186,7 +186,23 @@ AnalyticsProcessor.new.ractor_safe?
|
|
|
186
186
|
|
|
187
187
|
This declares intent only. `cdc-core` does not execute processors in Ractors. `cdc-parallel` can use this signal before moving processor work across Ractors.
|
|
188
188
|
|
|
189
|
-
##
|
|
189
|
+
## Downstream Workflow Primitives
|
|
190
|
+
|
|
191
|
+
`cdc-core` defines three small workflow primitives. Runtime gems and
|
|
192
|
+
application-specific integrations can execute these primitives without
|
|
193
|
+
inventing their own composition vocabulary.
|
|
194
|
+
|
|
195
|
+
### CompositeProcessor
|
|
196
|
+
|
|
197
|
+
Use `CompositeProcessor` when many independent processors should receive the
|
|
198
|
+
same input.
|
|
199
|
+
|
|
200
|
+
```text
|
|
201
|
+
event
|
|
202
|
+
├─ AuditProcessor
|
|
203
|
+
├─ AnalyticsProcessor
|
|
204
|
+
└─ WebhookProcessor
|
|
205
|
+
```
|
|
190
206
|
|
|
191
207
|
```ruby
|
|
192
208
|
processor = CDC::Core::CompositeProcessor.new([
|
|
@@ -197,7 +213,17 @@ processor = CDC::Core::CompositeProcessor.new([
|
|
|
197
213
|
results = processor.process(event)
|
|
198
214
|
```
|
|
199
215
|
|
|
200
|
-
|
|
216
|
+
### Pipeline
|
|
217
|
+
|
|
218
|
+
Use `Pipeline` when one processor should run only after filters match.
|
|
219
|
+
|
|
220
|
+
```text
|
|
221
|
+
event
|
|
222
|
+
↓
|
|
223
|
+
filters
|
|
224
|
+
↓
|
|
225
|
+
processor
|
|
226
|
+
```
|
|
201
227
|
|
|
202
228
|
```ruby
|
|
203
229
|
pipeline = CDC::Core::Pipeline.new(
|
|
@@ -211,6 +237,46 @@ pipeline = CDC::Core::Pipeline.new(
|
|
|
211
237
|
result = pipeline.process(event)
|
|
212
238
|
```
|
|
213
239
|
|
|
240
|
+
### ProcessorChain
|
|
241
|
+
|
|
242
|
+
Use `ProcessorChain` when each processor depends on the previous processor's
|
|
243
|
+
successful value.
|
|
244
|
+
|
|
245
|
+
```text
|
|
246
|
+
user_ids
|
|
247
|
+
↓
|
|
248
|
+
LoadUsersProcessor
|
|
249
|
+
↓
|
|
250
|
+
users
|
|
251
|
+
↓
|
|
252
|
+
SendNotificationsProcessor
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
```ruby
|
|
256
|
+
class LoadUsersProcessor < CDC::Core::Processor
|
|
257
|
+
def process(user_ids)
|
|
258
|
+
users = User.where(id: user_ids).to_a
|
|
259
|
+
CDC::Core::ProcessorResult.success(user_ids, value: users)
|
|
260
|
+
end
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
class SendNotificationsProcessor < CDC::Core::Processor
|
|
264
|
+
def process(users)
|
|
265
|
+
users.each { |user| NotificationMailer.notice(user).deliver_later }
|
|
266
|
+
CDC::Core::ProcessorResult.success(users, value: users.size)
|
|
267
|
+
end
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
chain = CDC::Core::ProcessorChain.new([
|
|
271
|
+
LoadUsersProcessor.new,
|
|
272
|
+
SendNotificationsProcessor.new
|
|
273
|
+
])
|
|
274
|
+
|
|
275
|
+
result = chain.process([1, 2, 3])
|
|
276
|
+
result.value
|
|
277
|
+
# => 3
|
|
278
|
+
```
|
|
279
|
+
|
|
214
280
|
## Non-goals
|
|
215
281
|
|
|
216
282
|
`cdc-core` does not:
|
|
@@ -2,11 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
module CDC
|
|
4
4
|
module Core
|
|
5
|
-
#
|
|
5
|
+
# Fan-out processor that delegates the same input to multiple processors.
|
|
6
6
|
#
|
|
7
|
-
# CompositeProcessor
|
|
8
|
-
#
|
|
9
|
-
#
|
|
7
|
+
# CompositeProcessor is for independent downstream side effects. Every
|
|
8
|
+
# configured processor receives the same input, and their results are
|
|
9
|
+
# collected independently. Use ProcessorChain when Processor B must receive
|
|
10
|
+
# Processor A's output.
|
|
10
11
|
class CompositeProcessor < Processor
|
|
11
12
|
# @return [Array<Processor>] processors executed for each event
|
|
12
13
|
# @return [Boolean] whether processing stops on the first failure
|
data/lib/cdc/core/pipeline.rb
CHANGED
|
@@ -2,11 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
module CDC
|
|
4
4
|
module Core
|
|
5
|
-
# Connects filters with
|
|
5
|
+
# Connects filters with one processor to form a guarded processing unit.
|
|
6
6
|
#
|
|
7
|
-
# A Pipeline
|
|
8
|
-
#
|
|
9
|
-
#
|
|
7
|
+
# A Pipeline evaluates all filters before invoking its processor. Matching
|
|
8
|
+
# inputs are processed, while filtered inputs produce skipped results. Use
|
|
9
|
+
# CompositeProcessor for fan-out to many processors and ProcessorChain for
|
|
10
|
+
# dependent step-by-step workflows.
|
|
10
11
|
class Pipeline
|
|
11
12
|
# @return [#process] processor invoked for matching events
|
|
12
13
|
# @return [Array<Filter>] filters that must all match before processing
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module CDC
|
|
4
|
+
module Core
|
|
5
|
+
# Sequential processor workflow where each successful result feeds the next processor.
|
|
6
|
+
#
|
|
7
|
+
# ProcessorChain models dependent workflows. Unlike CompositeProcessor,
|
|
8
|
+
# which sends the same input to every processor, ProcessorChain sends the
|
|
9
|
+
# value returned by one processor to the next processor. This is useful for
|
|
10
|
+
# downstream workflows such as loading records, enriching them, and then
|
|
11
|
+
# sending the enriched payload to a sink.
|
|
12
|
+
#
|
|
13
|
+
# Each processor result is normalized into a ProcessorResult. The chain stops
|
|
14
|
+
# at the first failure or skipped result because later processors depend on
|
|
15
|
+
# the previous processor's successful value.
|
|
16
|
+
class ProcessorChain < Processor
|
|
17
|
+
# @return [Array<#process>] processors executed in dependency order
|
|
18
|
+
# @return [Observer] observer notified of dispatch events
|
|
19
|
+
attr_reader :processors, :observer
|
|
20
|
+
|
|
21
|
+
# Build a processor chain.
|
|
22
|
+
#
|
|
23
|
+
# @param processors [Array<#process>] processors executed in dependency order
|
|
24
|
+
# @param observer [Observer, nil] instrumentation observer for each processor result
|
|
25
|
+
def initialize(processors, observer: NullObserver::INSTANCE) # rubocop:disable Lint/MissingSuper
|
|
26
|
+
@processors = processors.freeze
|
|
27
|
+
@observer = observer || NullObserver::INSTANCE
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Process one input through each processor in sequence.
|
|
31
|
+
#
|
|
32
|
+
# The first processor receives the original input. Each later processor
|
|
33
|
+
# receives the previous successful ProcessorResult#value. The returned
|
|
34
|
+
# value is the final ProcessorResult produced by the chain.
|
|
35
|
+
#
|
|
36
|
+
# @param input [Object] initial input for the first processor
|
|
37
|
+
# @return [ProcessorResult] final processor result or the first failed/skipped result
|
|
38
|
+
def process(input)
|
|
39
|
+
observer.dispatch_started(input)
|
|
40
|
+
current_input = input
|
|
41
|
+
|
|
42
|
+
processors.each do |processor|
|
|
43
|
+
result = process_with(processor, current_input)
|
|
44
|
+
observe_result(result)
|
|
45
|
+
return result unless result.success?
|
|
46
|
+
|
|
47
|
+
current_input = result.value
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
ProcessorResult.success(current_input, value: current_input)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# Process many inputs in order.
|
|
54
|
+
#
|
|
55
|
+
# @param inputs [Enumerable<Object>] inputs to process through the chain
|
|
56
|
+
# @return [Array<ProcessorResult>] final result for each input
|
|
57
|
+
def process_many(inputs)
|
|
58
|
+
inputs.map { |input| process(input) }.freeze
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
private
|
|
62
|
+
|
|
63
|
+
# Normalize processor return values into ProcessorResult objects.
|
|
64
|
+
#
|
|
65
|
+
# @param result [Object] raw processor result
|
|
66
|
+
# @param input [Object] input given to the processor
|
|
67
|
+
# @return [ProcessorResult] normalized result
|
|
68
|
+
def normalize_result(result, input)
|
|
69
|
+
return result if result.is_a?(ProcessorResult)
|
|
70
|
+
|
|
71
|
+
result ? ProcessorResult.success(input, value: result) : ProcessorResult.skipped(input)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def process_with(processor, input)
|
|
75
|
+
normalize_result(processor.process(input), input)
|
|
76
|
+
rescue StandardError => e
|
|
77
|
+
ProcessorResult.failure(e, event: input, processor: processor.class.name)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def observe_result(result)
|
|
81
|
+
case result.status
|
|
82
|
+
when :success
|
|
83
|
+
observer.dispatch_succeeded(result)
|
|
84
|
+
when :failure
|
|
85
|
+
observer.dispatch_failed(result)
|
|
86
|
+
when :skipped
|
|
87
|
+
observer.dispatch_skipped(result)
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
@@ -12,17 +12,19 @@ module CDC
|
|
|
12
12
|
VALID_STATUSES = Ractor.make_shareable(%i[success failure skipped].freeze)
|
|
13
13
|
|
|
14
14
|
# @return [Symbol] result status
|
|
15
|
-
# @return [ChangeEvent, nil] event associated with the result
|
|
15
|
+
# @return [ChangeEvent, Object, nil] event or input associated with the result
|
|
16
|
+
# @return [Object, nil] value produced by the processor
|
|
16
17
|
# @return [Exception, nil] failure error, when status is :failure
|
|
17
18
|
# @return [EventMetadata] result metadata
|
|
18
|
-
attr_reader :status, :event, :error, :metadata
|
|
19
|
+
attr_reader :status, :event, :value, :error, :metadata
|
|
19
20
|
|
|
20
21
|
# Build a successful result.
|
|
21
22
|
#
|
|
22
23
|
# @param event [ChangeEvent, nil] processed event
|
|
23
24
|
# @param metadata [Hash, EventMetadata] result metadata
|
|
25
|
+
# @param value [Object, nil] value produced by the processor; defaults to event for compatibility
|
|
24
26
|
# @return [ProcessorResult]
|
|
25
|
-
def self.success(event = nil, metadata: {}) = new(:success, event:, metadata:)
|
|
27
|
+
def self.success(event = nil, metadata: {}, value: event) = new(:success, event:, metadata:, value:)
|
|
26
28
|
|
|
27
29
|
# Build a failure result.
|
|
28
30
|
#
|
|
@@ -60,12 +62,14 @@ module CDC
|
|
|
60
62
|
# @param event [ChangeEvent, nil] associated event
|
|
61
63
|
# @param error [Exception, nil] associated failure
|
|
62
64
|
# @param metadata [Hash, EventMetadata] result metadata
|
|
63
|
-
|
|
65
|
+
# @param value [Object, nil] value produced by the processor
|
|
66
|
+
def initialize(status, event: nil, error: nil, metadata: {}, value: event)
|
|
64
67
|
@status = normalize_status(status)
|
|
65
68
|
@event = event
|
|
69
|
+
@value = value
|
|
66
70
|
@error = error
|
|
67
71
|
@metadata = metadata.is_a?(EventMetadata) ? metadata : EventMetadata.new(metadata)
|
|
68
|
-
|
|
72
|
+
make_shareable_when_possible
|
|
69
73
|
end
|
|
70
74
|
|
|
71
75
|
# @return [Boolean] true when status is :success
|
|
@@ -132,7 +136,8 @@ module CDC
|
|
|
132
136
|
def to_h
|
|
133
137
|
payload = {
|
|
134
138
|
'status' => status,
|
|
135
|
-
'event' => event
|
|
139
|
+
'event' => event.respond_to?(:to_h) ? event.to_h : event,
|
|
140
|
+
'value' => value.respond_to?(:to_h) ? value.to_h : value,
|
|
136
141
|
'error_class' => error_class,
|
|
137
142
|
'error_message' => error_message,
|
|
138
143
|
'error_backtrace' => error_backtrace,
|
|
@@ -144,6 +149,16 @@ module CDC
|
|
|
144
149
|
|
|
145
150
|
private
|
|
146
151
|
|
|
152
|
+
def make_shareable_when_possible
|
|
153
|
+
Ractor.make_shareable(self) unless error
|
|
154
|
+
rescue Ractor::Error, TypeError
|
|
155
|
+
# ProcessorResult may carry application-specific values such as ActiveRecord
|
|
156
|
+
# result sets. Those values are valid in sequential/fiber runtimes even when
|
|
157
|
+
# they cannot be shared with Ractors. Ractor runtimes remain responsible for
|
|
158
|
+
# validating shareability at their boundary.
|
|
159
|
+
self
|
|
160
|
+
end
|
|
161
|
+
|
|
147
162
|
def normalize_status(status)
|
|
148
163
|
value = status.to_sym
|
|
149
164
|
return value if VALID_STATUSES.include?(value)
|
data/lib/cdc/core/version.rb
CHANGED
data/lib/cdc/core.rb
CHANGED
|
@@ -15,6 +15,7 @@ require_relative 'core/source_adapter'
|
|
|
15
15
|
require_relative 'core/processor_result'
|
|
16
16
|
require_relative 'core/processor'
|
|
17
17
|
require_relative 'core/composite_processor'
|
|
18
|
+
require_relative 'core/processor_chain'
|
|
18
19
|
require_relative 'core/observer'
|
|
19
20
|
require_relative 'core/null_observer'
|
|
20
21
|
require_relative 'core/filter'
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
module CDC
|
|
2
|
+
module Core
|
|
3
|
+
# Sequential processor workflow where each successful result feeds the next processor.
|
|
4
|
+
class ProcessorChain < Processor
|
|
5
|
+
@processors: untyped
|
|
6
|
+
@observer: untyped
|
|
7
|
+
|
|
8
|
+
# @return [Array<#process>] processors executed in dependency order
|
|
9
|
+
attr_reader processors: untyped
|
|
10
|
+
|
|
11
|
+
# @return [Observer] observer notified of dispatch events
|
|
12
|
+
attr_reader observer: untyped
|
|
13
|
+
|
|
14
|
+
# Build a processor chain.
|
|
15
|
+
#
|
|
16
|
+
# @param processors [Array<#process>] processors executed in dependency order
|
|
17
|
+
# @param observer [Observer, nil] instrumentation observer for each processor result
|
|
18
|
+
def initialize: (untyped processors, ?observer: untyped?) -> void
|
|
19
|
+
|
|
20
|
+
# Process one input through each processor in sequence.
|
|
21
|
+
#
|
|
22
|
+
# @param input [Object] initial input for the first processor
|
|
23
|
+
# @return [ProcessorResult] final processor result or the first failed/skipped result
|
|
24
|
+
def process: (untyped input) -> untyped
|
|
25
|
+
|
|
26
|
+
# Process many inputs in order.
|
|
27
|
+
#
|
|
28
|
+
# @param inputs [Enumerable<Object>] inputs to process through the chain
|
|
29
|
+
# @return [Array<ProcessorResult>] final result for each input
|
|
30
|
+
def process_many: (untyped inputs) -> untyped
|
|
31
|
+
|
|
32
|
+
private
|
|
33
|
+
|
|
34
|
+
# Normalize processor return values into ProcessorResult objects.
|
|
35
|
+
#
|
|
36
|
+
# @param result [Object] raw processor result
|
|
37
|
+
# @param input [Object] input given to the processor
|
|
38
|
+
# @return [ProcessorResult] normalized result
|
|
39
|
+
def normalize_result: (untyped result, untyped input) -> untyped
|
|
40
|
+
|
|
41
|
+
def process_with: (untyped processor, untyped input) -> untyped
|
|
42
|
+
def observe_result: (untyped result) -> untyped
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -11,6 +11,8 @@ module CDC
|
|
|
11
11
|
|
|
12
12
|
@event: untyped
|
|
13
13
|
|
|
14
|
+
@value: untyped
|
|
15
|
+
|
|
14
16
|
@error: untyped
|
|
15
17
|
|
|
16
18
|
@metadata: untyped
|
|
@@ -27,6 +29,9 @@ module CDC
|
|
|
27
29
|
# @return [EventMetadata] result metadata
|
|
28
30
|
attr_reader event: untyped
|
|
29
31
|
|
|
32
|
+
# @return [Object, nil] value produced by the processor
|
|
33
|
+
attr_reader value: untyped
|
|
34
|
+
|
|
30
35
|
# @return [Symbol] result status
|
|
31
36
|
# @return [ChangeEvent, nil] event associated with the result
|
|
32
37
|
# @return [Exception, nil] failure error, when status is :failure
|
|
@@ -44,7 +49,7 @@ module CDC
|
|
|
44
49
|
# @param event [ChangeEvent, nil] processed event
|
|
45
50
|
# @param metadata [Hash, EventMetadata] result metadata
|
|
46
51
|
# @return [ProcessorResult]
|
|
47
|
-
def self.success: (?untyped? event, ?metadata: ::Hash[untyped, untyped]) -> untyped
|
|
52
|
+
def self.success: (?untyped? event, ?metadata: ::Hash[untyped, untyped], ?value: untyped?) -> untyped
|
|
48
53
|
|
|
49
54
|
# Build a failure result.
|
|
50
55
|
#
|
|
@@ -71,7 +76,7 @@ module CDC
|
|
|
71
76
|
# @param event [ChangeEvent, nil] associated event
|
|
72
77
|
# @param error [Exception, nil] associated failure
|
|
73
78
|
# @param metadata [Hash, EventMetadata] result metadata
|
|
74
|
-
def initialize: (untyped status, ?event: untyped?, ?error: untyped?, ?metadata: ::Hash[untyped, untyped]) -> void
|
|
79
|
+
def initialize: (untyped status, ?event: untyped?, ?error: untyped?, ?metadata: ::Hash[untyped, untyped], ?value: untyped?) -> void
|
|
75
80
|
|
|
76
81
|
# @return [Boolean] true when status is :success
|
|
77
82
|
def success?: () -> untyped
|
|
@@ -124,6 +129,8 @@ module CDC
|
|
|
124
129
|
|
|
125
130
|
private
|
|
126
131
|
|
|
132
|
+
def make_shareable_when_possible: () -> untyped
|
|
133
|
+
|
|
127
134
|
def normalize_status: (untyped status) -> untyped
|
|
128
135
|
end
|
|
129
136
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: cdc-core
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ken C. Demanawa
|
|
@@ -9,10 +9,9 @@ bindir: bin
|
|
|
9
9
|
cert_chain: []
|
|
10
10
|
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
11
|
dependencies: []
|
|
12
|
-
description:
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
'
|
|
12
|
+
description: |
|
|
13
|
+
CDC Core provides immutable, Ractor-safe Change Data Capture contracts and domain primitives,
|
|
14
|
+
including source adapters, change events, processors, routing, ordering policies, and pipelines.
|
|
16
15
|
email:
|
|
17
16
|
- kenneth.c.demanawa@gmail.com
|
|
18
17
|
executables: []
|
|
@@ -38,6 +37,7 @@ files:
|
|
|
38
37
|
- lib/cdc/core/ordering_scope.rb
|
|
39
38
|
- lib/cdc/core/pipeline.rb
|
|
40
39
|
- lib/cdc/core/processor.rb
|
|
40
|
+
- lib/cdc/core/processor_chain.rb
|
|
41
41
|
- lib/cdc/core/processor_result.rb
|
|
42
42
|
- lib/cdc/core/router.rb
|
|
43
43
|
- lib/cdc/core/source_adapter.rb
|
|
@@ -60,6 +60,7 @@ files:
|
|
|
60
60
|
- sig/cdc/core/ordering_scope.rbs
|
|
61
61
|
- sig/cdc/core/pipeline.rbs
|
|
62
62
|
- sig/cdc/core/processor.rbs
|
|
63
|
+
- sig/cdc/core/processor_chain.rbs
|
|
63
64
|
- sig/cdc/core/processor_result.rbs
|
|
64
65
|
- sig/cdc/core/router.rbs
|
|
65
66
|
- sig/cdc/core/source_adapter.rbs
|
|
@@ -91,5 +92,5 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
91
92
|
requirements: []
|
|
92
93
|
rubygems_version: 3.6.9
|
|
93
94
|
specification_version: 4
|
|
94
|
-
summary:
|
|
95
|
+
summary: Source-agnostic Change Data Capture contracts and domain primitives for Ruby..
|
|
95
96
|
test_files: []
|