dexiecable 2.0.0.alpha1 → 2.0.0.alpha2
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/README.md +19 -1
- data/lib/dexiecable/dexie_channel.rb +31 -8
- data/lib/dexiecable/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 714562cd7c933eb48e81e9159acd326d77b6133a807cdd541000f350281c1c94
|
|
4
|
+
data.tar.gz: d3bcacdc18d5f9c7a8be970f9ede859be19e282e8ca35aa4d27c81e581310eb3
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ed0dbe4fdfade70f3300d9c2a61882f6a00320c384fe74ad76b6ba11ef0733a26b86f6949606117b4847efdd5221709bf1a091088a510a0155d6ff9f48a87774
|
|
7
|
+
data.tar.gz: d5cef46c7417c0e34ff4e08c08e0df846ff653f19ae0eeacbffe9de433a362c9ae9af60b32f669a6daa301b64a05d3844f227587cf20af4da23ecf149b39cfb9
|
data/README.md
CHANGED
|
@@ -85,7 +85,7 @@ For an ActiveRecord model it signs the record's GlobalID:
|
|
|
85
85
|
|
|
86
86
|
```ruby
|
|
87
87
|
DexieChannel.stream_token_for(current_user)
|
|
88
|
-
# => "
|
|
88
|
+
# => "signed token for gid://app/User/1"
|
|
89
89
|
```
|
|
90
90
|
|
|
91
91
|
Send that token to the client (render it in a view, return it from an endpoint, etc.) and add it to the subscription:
|
|
@@ -107,6 +107,24 @@ subscription.removeStream(userStream);
|
|
|
107
107
|
subscription.removeAllStreams();
|
|
108
108
|
```
|
|
109
109
|
|
|
110
|
+
#### Initial data on subscribe
|
|
111
|
+
|
|
112
|
+
To push a snapshot when a stream is added, set `DexieChannel.on_subscribe`. It receives the channel and the subscribed record (resolved from the signed GlobalID), so you can dispatch on the record type:
|
|
113
|
+
|
|
114
|
+
```ruby
|
|
115
|
+
# config/initializers/dexiecable.rb
|
|
116
|
+
DexieChannel.on_subscribe = ->(channel, record) do
|
|
117
|
+
case record
|
|
118
|
+
when User
|
|
119
|
+
channel.table("notifications").bulkAdd(record.notifications.map(&:as_json_for_dexie))
|
|
120
|
+
when Conversation
|
|
121
|
+
channel.table("messages").bulkAdd(record.messages.map(&:as_json_for_dexie))
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
The callback runs after the stream is opened, and `channel.table(...)` transmits to just this subscriber — so the snapshot arrives before any live mutation.
|
|
127
|
+
|
|
110
128
|
#### Public streams
|
|
111
129
|
|
|
112
130
|
For data that's public (a global feed, announcements, etc.), skip the signature. Use a string target — it's namespaced under `public:` automatically:
|
|
@@ -13,9 +13,23 @@ module DexieCable
|
|
|
13
13
|
# # public (no signature, namespaced under "public:")
|
|
14
14
|
# subscription.addPublicStream("feed")
|
|
15
15
|
#
|
|
16
|
+
# When a private stream is added, +on_subscribe+ is invoked with the
|
|
17
|
+
# channel and the subscribed record, so initial data can be pushed:
|
|
18
|
+
#
|
|
19
|
+
# DexieChannel.on_subscribe = ->(channel, record) do
|
|
20
|
+
# case record
|
|
21
|
+
# when User
|
|
22
|
+
# channel.table("notifications").bulkAdd(record.notifications.map(&:as_json_for_dexie))
|
|
23
|
+
# when Conversation
|
|
24
|
+
# channel.table("messages").bulkAdd(record.messages.map(&:as_json_for_dexie))
|
|
25
|
+
# end
|
|
26
|
+
# end
|
|
27
|
+
#
|
|
16
28
|
class DexieChannel < ActionCable::Channel::Base
|
|
17
29
|
PUBLIC_STREAM_PREFIX = "public:"
|
|
18
30
|
|
|
31
|
+
class_attribute :on_subscribe, instance_accessor: false, default: nil
|
|
32
|
+
|
|
19
33
|
public :transmit
|
|
20
34
|
|
|
21
35
|
# Open a scoped channel for broadcasting to a specific recipient.
|
|
@@ -40,11 +54,11 @@ module DexieCable
|
|
|
40
54
|
Query.new(self, name)
|
|
41
55
|
end
|
|
42
56
|
|
|
43
|
-
# Returns a signed token for
|
|
44
|
-
#
|
|
57
|
+
# Returns a signed token for +target+ (a record or other private
|
|
58
|
+
# target). Send it to the client, which passes it to
|
|
45
59
|
# +subscription.addStream+.
|
|
46
60
|
def self.stream_token_for(target)
|
|
47
|
-
verifier.generate(
|
|
61
|
+
verifier.generate(target.respond_to?(:to_gid_param) ? target.to_gid_param : target.to_s)
|
|
48
62
|
end
|
|
49
63
|
|
|
50
64
|
def self.verifier
|
|
@@ -56,13 +70,18 @@ module DexieCable
|
|
|
56
70
|
end
|
|
57
71
|
|
|
58
72
|
def add_stream(data)
|
|
59
|
-
|
|
60
|
-
|
|
73
|
+
target = verified_target(data["stream"])
|
|
74
|
+
return unless target
|
|
75
|
+
|
|
76
|
+
stream_for target
|
|
77
|
+
self.class.on_subscribe&.call(self, resolve_subscribe_target(target))
|
|
61
78
|
end
|
|
62
79
|
|
|
63
80
|
def remove_stream(data)
|
|
64
|
-
|
|
65
|
-
|
|
81
|
+
target = verified_target(data["stream"])
|
|
82
|
+
return unless target
|
|
83
|
+
|
|
84
|
+
stop_stream_from self.class.broadcasting_for(target)
|
|
66
85
|
end
|
|
67
86
|
|
|
68
87
|
def remove_all_streams(_data)
|
|
@@ -85,12 +104,16 @@ module DexieCable
|
|
|
85
104
|
self.class.broadcasting_for("#{PUBLIC_STREAM_PREFIX}#{name}")
|
|
86
105
|
end
|
|
87
106
|
|
|
88
|
-
def
|
|
107
|
+
def verified_target(token)
|
|
89
108
|
return unless token.present?
|
|
90
109
|
|
|
91
110
|
self.class.verifier.verify(token)
|
|
92
111
|
rescue ActiveSupport::MessageVerifier::InvalidSignature
|
|
93
112
|
nil
|
|
94
113
|
end
|
|
114
|
+
|
|
115
|
+
def resolve_subscribe_target(target)
|
|
116
|
+
target.start_with?("gid://") ? GlobalID::Locator.locate(target) : target
|
|
117
|
+
end
|
|
95
118
|
end
|
|
96
119
|
end
|
data/lib/dexiecable/version.rb
CHANGED