async-matrix-bridge 2.0.0 → 3.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +161 -0
- data/README.md +79 -142
- data/lib/async/matrix/bridge/puppet.rb +89 -0
- data/lib/async/matrix/bridge/registration.rb +116 -197
- data/lib/async/matrix/bridge/service.rb +250 -0
- data/lib/async/matrix/bridge/transaction.rb +90 -0
- data/lib/async/matrix/bridge/transaction_store.rb +0 -39
- data/lib/async/matrix/bridge/version.rb +1 -1
- metadata +16 -23
- data/lib/async/matrix/bridge/endpoint.rb +0 -482
- data/lib/async/matrix/bridge/registration/schema/namespace_list.json +0 -22
- data/lib/async/matrix/bridge/registration/schema/registration.json +0 -91
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Released under the Apache License, Version 2.0.
|
|
4
|
+
# Copyright, 2026, by General Intelligence Systems.
|
|
5
|
+
|
|
6
|
+
require "async/matrix"
|
|
7
|
+
require "async/rest/wrapper/json"
|
|
8
|
+
|
|
9
|
+
module Async
|
|
10
|
+
module Matrix
|
|
11
|
+
module Bridge
|
|
12
|
+
# What the homeserver pushed, which is to a service what a sync batch is to a client.
|
|
13
|
+
#
|
|
14
|
+
# A representation is an instance of a resource at a point in time, and that is what this is:
|
|
15
|
+
# the difference is that it was handed over rather than fetched, so the value is given at
|
|
16
|
+
# construction and never read from a response.
|
|
17
|
+
#
|
|
18
|
+
# Being a representation is what makes it match: {Async::Matrix::Representation} already
|
|
19
|
+
# deconstructs to its own document, so a whole transaction can be a pattern.
|
|
20
|
+
class Transaction < Async::Matrix::Representation
|
|
21
|
+
# Read one from a request, parsing it with the wrapper a response would have used.
|
|
22
|
+
#
|
|
23
|
+
# @parameter request [Protocol::HTTP::Request] the request the homeserver made.
|
|
24
|
+
# @parameter txn_id [String] the transaction, which the homeserver numbers.
|
|
25
|
+
# @parameter version [String] the specification version to type the events as.
|
|
26
|
+
# @returns [Transaction] the transaction it carried.
|
|
27
|
+
def self.for(request, txn_id, version: Async::Matrix::LATEST)
|
|
28
|
+
value = ::Async::REST::Wrapper::JSON::Parser.new(request.body).join
|
|
29
|
+
|
|
30
|
+
self.new(nil, value: value, metadata: request.headers, txn_id: txn_id, version: version)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# @parameter resource [Nil] nothing: there is no resource to fetch this again from.
|
|
34
|
+
# @parameter value [Hash] the document the homeserver sent.
|
|
35
|
+
# @parameter metadata [Protocol::HTTP::Headers] the headers it arrived with.
|
|
36
|
+
# @parameter txn_id [String] the transaction, which the homeserver numbers.
|
|
37
|
+
# @parameter version [String] the specification version to type the events as.
|
|
38
|
+
def initialize(resource, value:, metadata: {}, txn_id: nil, version: Async::Matrix::LATEST)
|
|
39
|
+
super(resource, value: value, metadata: metadata)
|
|
40
|
+
|
|
41
|
+
@txn_id = txn_id
|
|
42
|
+
@events = Async::Matrix::Events.registry(version)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# @attribute [String] the transaction, which makes handling it twice unnecessary.
|
|
46
|
+
attr :txn_id
|
|
47
|
+
|
|
48
|
+
# The timeline, typed as the registry describes it.
|
|
49
|
+
#
|
|
50
|
+
# @returns [Array(Async::Matrix::Events::Envelope)] the events.
|
|
51
|
+
def events
|
|
52
|
+
(self.value[:events] || []).map{|value| @events.wrap(value)}
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# Read receipts, typing and presence, which arrive only when the registration asked for them.
|
|
56
|
+
#
|
|
57
|
+
# @returns [Array(Async::Matrix::Events::Envelope)] the events.
|
|
58
|
+
def ephemeral
|
|
59
|
+
(self.value[:ephemeral] || []).map{|value| @events.wrap(value)}
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# @returns [Boolean] whether this transaction carried nothing at all.
|
|
63
|
+
def empty?
|
|
64
|
+
self.events.empty? and self.ephemeral.empty?
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# The events of each room, in the order they were sent.
|
|
68
|
+
#
|
|
69
|
+
# Events in one room are ordered and must stay so, because a message can depend on the
|
|
70
|
+
# membership before it and a key on the session before that. Different rooms are independent,
|
|
71
|
+
# so a caller may handle them at the same time.
|
|
72
|
+
#
|
|
73
|
+
# @yields {|room_id, events| ...}
|
|
74
|
+
# @parameter room_id [String] the room.
|
|
75
|
+
# @parameter events [Array(Async::Matrix::Events::Envelope)] its events, in order.
|
|
76
|
+
def each_room
|
|
77
|
+
if block_given?
|
|
78
|
+
self.events.group_by(&:room_id).each do |room_id, events|
|
|
79
|
+
yield room_id, events
|
|
80
|
+
end
|
|
81
|
+
else
|
|
82
|
+
to_enum(:each_room)
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def inspect = "\#<#{self.class} #{@txn_id} #{self.events.size} event(s)>"
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
@@ -41,42 +41,3 @@ module Async
|
|
|
41
41
|
end
|
|
42
42
|
end
|
|
43
43
|
end
|
|
44
|
-
|
|
45
|
-
__END__
|
|
46
|
-
describe "Async::Matrix::Bridge::TransactionStore" do
|
|
47
|
-
it "tracks seen transaction IDs" do
|
|
48
|
-
store = Async::Matrix::Bridge::TransactionStore.new
|
|
49
|
-
store.seen?("txn1").should == false
|
|
50
|
-
store.mark_seen("txn1")
|
|
51
|
-
store.seen?("txn1").should == true
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
it "reports size" do
|
|
55
|
-
store = Async::Matrix::Bridge::TransactionStore.new
|
|
56
|
-
store.size.should == 0
|
|
57
|
-
store.mark_seen("a")
|
|
58
|
-
store.mark_seen("b")
|
|
59
|
-
store.size.should == 2
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
it "prunes oldest entries when capacity is reached" do
|
|
63
|
-
store = Async::Matrix::Bridge::TransactionStore.new(capacity: 4)
|
|
64
|
-
store.mark_seen("a")
|
|
65
|
-
store.mark_seen("b")
|
|
66
|
-
store.mark_seen("c")
|
|
67
|
-
store.mark_seen("d")
|
|
68
|
-
# This triggers prune — drops oldest half (a, b)
|
|
69
|
-
store.mark_seen("e")
|
|
70
|
-
store.seen?("a").should == false
|
|
71
|
-
store.seen?("b").should == false
|
|
72
|
-
store.seen?("d").should == true
|
|
73
|
-
store.seen?("e").should == true
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
it "does not prune below capacity" do
|
|
77
|
-
store = Async::Matrix::Bridge::TransactionStore.new(capacity: 10)
|
|
78
|
-
5.times { |i| store.mark_seen("txn#{i}") }
|
|
79
|
-
store.size.should == 5
|
|
80
|
-
store.seen?("txn0").should == true
|
|
81
|
-
end
|
|
82
|
-
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: async-matrix-bridge
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 3.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Nathan Kidd
|
|
@@ -29,42 +29,34 @@ dependencies:
|
|
|
29
29
|
requirements:
|
|
30
30
|
- - "~>"
|
|
31
31
|
- !ruby/object:Gem::Version
|
|
32
|
-
version: '
|
|
33
|
-
|
|
34
|
-
prerelease: false
|
|
35
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
36
|
-
requirements:
|
|
37
|
-
- - "~>"
|
|
38
|
-
- !ruby/object:Gem::Version
|
|
39
|
-
version: '3.0'
|
|
40
|
-
- !ruby/object:Gem::Dependency
|
|
41
|
-
name: json_schemer
|
|
42
|
-
requirement: !ruby/object:Gem::Requirement
|
|
43
|
-
requirements:
|
|
44
|
-
- - "~>"
|
|
32
|
+
version: '4.0'
|
|
33
|
+
- - ">="
|
|
45
34
|
- !ruby/object:Gem::Version
|
|
46
|
-
version:
|
|
35
|
+
version: 4.0.1
|
|
47
36
|
type: :runtime
|
|
48
37
|
prerelease: false
|
|
49
38
|
version_requirements: !ruby/object:Gem::Requirement
|
|
50
39
|
requirements:
|
|
51
40
|
- - "~>"
|
|
52
41
|
- !ruby/object:Gem::Version
|
|
53
|
-
version: '
|
|
42
|
+
version: '4.0'
|
|
43
|
+
- - ">="
|
|
44
|
+
- !ruby/object:Gem::Version
|
|
45
|
+
version: 4.0.1
|
|
54
46
|
- !ruby/object:Gem::Dependency
|
|
55
|
-
name:
|
|
47
|
+
name: protocol-http
|
|
56
48
|
requirement: !ruby/object:Gem::Requirement
|
|
57
49
|
requirements:
|
|
58
50
|
- - "~>"
|
|
59
51
|
- !ruby/object:Gem::Version
|
|
60
|
-
version: '
|
|
61
|
-
type: :
|
|
52
|
+
version: '0.72'
|
|
53
|
+
type: :runtime
|
|
62
54
|
prerelease: false
|
|
63
55
|
version_requirements: !ruby/object:Gem::Requirement
|
|
64
56
|
requirements:
|
|
65
57
|
- - "~>"
|
|
66
58
|
- !ruby/object:Gem::Version
|
|
67
|
-
version: '
|
|
59
|
+
version: '0.72'
|
|
68
60
|
- !ruby/object:Gem::Dependency
|
|
69
61
|
name: logger
|
|
70
62
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -102,13 +94,14 @@ executables: []
|
|
|
102
94
|
extensions: []
|
|
103
95
|
extra_rdoc_files: []
|
|
104
96
|
files:
|
|
97
|
+
- CHANGELOG.md
|
|
105
98
|
- LICENSE
|
|
106
99
|
- README.md
|
|
107
100
|
- lib/async/matrix/bridge.rb
|
|
108
|
-
- lib/async/matrix/bridge/
|
|
101
|
+
- lib/async/matrix/bridge/puppet.rb
|
|
109
102
|
- lib/async/matrix/bridge/registration.rb
|
|
110
|
-
- lib/async/matrix/bridge/
|
|
111
|
-
- lib/async/matrix/bridge/
|
|
103
|
+
- lib/async/matrix/bridge/service.rb
|
|
104
|
+
- lib/async/matrix/bridge/transaction.rb
|
|
112
105
|
- lib/async/matrix/bridge/transaction_store.rb
|
|
113
106
|
- lib/async/matrix/bridge/version.rb
|
|
114
107
|
homepage: https://github.com/general-intelligence-systems/async-matrix-bridge
|