sourced-message 0.3.0 → 0.4.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c32c4b5ea1020c0623e0f572d67a529a70630e21dd9d865a43386c4ca318915b
4
- data.tar.gz: b1bf6ccf2eadf06ea8c5bf301f692a520bb9cb84de37c07a5a340a0395177ff5
3
+ metadata.gz: 12ddf9298bf827a4f20e9f2db6b9edababd24efa73323326e5cd5ff6bbedebc1
4
+ data.tar.gz: a88ab37ddb627868b20cd9a03615334a01d1f957fc3dedae25db4486623b983f
5
5
  SHA512:
6
- metadata.gz: c9d6eb69097f9e6f70df79786f8a285c638d7a985f762ba15d70463109058b5884117d838242834db8771a1ee6996434695d5ab4a4dac4d9809a2d25c0456ffa
7
- data.tar.gz: a1b78a345ee0f8463372e729d9cce17ad28ce9c9da6a2d137da72c174ed10d668148018b7fdb7f13529d2c6d9db78a14f8401e0d976781457f95ec52944998ba
6
+ metadata.gz: 154e306175767857b9471c5700fe12ec3f73c17292af5c30826e2f61afa0dc217853e56950cddbf3decf8b38c38f5837e3cad76a822c6078cfd8904ef912093b
7
+ data.tar.gz: 0640b5e2560fa1dfd331ee8b015dde0b5195bf1ec55efaa1cb0e98cf4b3713ca8544b4bc784495cb09f08d32d12bc2dc4c60977b60df99b021bf6f71a6e63c76
data/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.4.0]
4
+
5
+ - Requires plumb 0.4, whose codecs rewrite Hash keys like values: `#encode` now emits
6
+ String keys (`{'type' => ..., 'payload' => {'name' => ...}}`), and decoders accept
7
+ String or Symbol keys. `JSON.dump` output is unchanged.
8
+ - `Codec#decode` reads the envelope's `type` and `id` under either key form, so
9
+ `decode(encode(message))` works without a JSON round trip.
10
+ - `metadata` is typed as `Types::Metadata`: Symbol keys and `Types::JSONValue` values
11
+ (String, Numeric, boolean, nil, and Arrays/Symbol-keyed Hashes of those, at any depth).
12
+ Codecs now restore nested metadata keys as Symbols. A non-JSON value (a Time, a
13
+ Symbol) makes the message invalid and fails `#encode`, where `JSON.dump` used to
14
+ stringify it silently.
15
+ - `Sourced::Message::VERSION` is now `0.4.0`.
16
+
3
17
  ## [0.3.0]
4
18
 
5
19
  - Add `Sourced::Message#correlation_type`, the type counterpart of `correlation_id`:
@@ -182,23 +182,27 @@ module Sourced
182
182
  # Rebuild a message from decoded attributes. An unknown type raises: a process
183
183
  # reading types it doesn't know about is missing the class.
184
184
  #
185
- # @param attrs [Hash] symbol-keyed message attributes
185
+ # @param attrs [Hash] message attributes, String- (as #encode emits them) or Symbol-keyed
186
186
  # @return [Sourced::Message]
187
187
  # @raise [UnknownMessageError] if the type isn't in the registry
188
188
  # @raise [UnregisteredTypeError] if the type was not compiled
189
189
  # @raise [DecodeError] if the attributes don't satisfy the schema
190
190
  def decode(attrs)
191
- type = attrs[:type]
191
+ type = envelope(attrs, :type)
192
+ id = envelope(attrs, :id)
192
193
  klass = @registry[type]
193
- raise UnknownMessageError, "Unknown message type: #{label(type, attrs[:id])}" unless klass
194
+ raise UnknownMessageError, "Unknown message type: #{label(type, id)}" unless klass
194
195
 
195
- build(klass, attrs, pair(type, attrs[:id]).decoder)
196
+ build(klass, attrs, pair(type, id).decoder)
196
197
  rescue Plumb::ParseError => e
197
- raise DecodeError, "cannot decode #{label(type, attrs[:id])}: #{e.message}"
198
+ raise DecodeError, "cannot decode #{label(type, id)}: #{e.message}"
198
199
  end
199
200
 
200
201
  private
201
202
 
203
+ # Read before the decoder runs, so it must accept both key forms the decoder does.
204
+ def envelope(attrs, key) = attrs.fetch(key) { attrs[key.to_s] }
205
+
202
206
  # --- subclass seams -------------------------------------------------------
203
207
 
204
208
  # @param klass [Class<Sourced::Message>]
@@ -22,7 +22,7 @@ module Sourced
22
22
  # +Sourced::Message.registry[type]+ resolves a type registered under any
23
23
  # subclass. Resolve from this root to see the whole tree.
24
24
  class Message < Plumb::Types::Data
25
- VERSION = '0.3.0'
25
+ VERSION = '0.4.0'
26
26
 
27
27
  EMPTY_ARRAY = [].freeze
28
28
 
@@ -34,6 +34,15 @@ module Sourced
34
34
 
35
35
  # Accepts a UUID string or generates a new one when none is provided.
36
36
  AutoUUID = UUID::V4.default { SecureRandom.uuid }
37
+
38
+ # A JSON value, with Symbol-keyed objects at every depth. Typed all the way
39
+ # down so a codec decodes nested keys too. The self-references are deferred
40
+ # inside the union, not the constant itself: naming a type here freezes it,
41
+ # and a frozen Deferred can't materialize.
42
+ JSONValue = String | Numeric | Boolean | Nil |
43
+ Array[Any.defer { JSONValue }] | Hash[Symbol, Any.defer { JSONValue }]
44
+
45
+ Metadata = Hash[Symbol, JSONValue]
37
46
  end
38
47
 
39
48
  # Raised by {.from} when a type string isn't registered.
@@ -47,7 +56,7 @@ module Sourced
47
56
  attribute? :causation_id, Types::UUID::V4
48
57
  attribute? :correlation_id, Types::UUID::V4
49
58
  attribute :created_at, LaxTime.default { Time.now }
50
- attribute :metadata, Types::Hash.default(Plumb::BLANK_HASH)
59
+ attribute :metadata, Types::Metadata.default(Plumb::BLANK_HASH)
51
60
  attribute :payload, Types::Static[nil]
52
61
 
53
62
  # Lookup table mapping type strings to message subclasses.
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sourced-message
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ismael Celis
@@ -15,14 +15,14 @@ dependencies:
15
15
  requirements:
16
16
  - - ">="
17
17
  - !ruby/object:Gem::Version
18
- version: '0.3'
18
+ version: '0.4'
19
19
  type: :runtime
20
20
  prerelease: false
21
21
  version_requirements: !ruby/object:Gem::Requirement
22
22
  requirements:
23
23
  - - ">="
24
24
  - !ruby/object:Gem::Version
25
- version: '0.3'
25
+ version: '0.4'
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: fugit
28
28
  requirement: !ruby/object:Gem::Requirement
@@ -74,7 +74,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
74
74
  - !ruby/object:Gem::Version
75
75
  version: '0'
76
76
  requirements: []
77
- rubygems_version: 4.0.8
77
+ rubygems_version: 4.0.21
78
78
  specification_version: 4
79
79
  summary: Canonical typed Message class and registry shared by Sourced and Sidereal.
80
80
  test_files: []