y-rb 0.3.0-x86_64-linux → 0.3.1-x86_64-linux

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3e764ed148987200b5fbc12af9eaab5d190a92d84cc030598ea26bf27e00de6a
4
- data.tar.gz: ae736fae3d90db89290fde484491ed72e214655cc62420cf4a72a056f715a508
3
+ metadata.gz: 94ee494d71cb95886592130f1aa7b764af02f88273b7c823e5bb3b6cf79ee8b3
4
+ data.tar.gz: f642a14aa03767aba59754ca064ff958e79f16265141a103c91f6f186e58428e
5
5
  SHA512:
6
- metadata.gz: c47ffa342eb4a60b90f3c1e3da79f69429f0373a3361aa2b6316118c9d4c7c9b75234a8941bbbe7d8b3a6bcebb92123836eabed7ef6978349768fd99b90a59d4
7
- data.tar.gz: 570cb9f86a7d37c990a80ff89bfa97a03b2a96261088f6c729d451a2791f6ac1ef8f36f4a81e1040b35562f66bcf1dd352d0cb52bc82bc43a889bff18c7cf172
6
+ metadata.gz: 86b47de7253c9350799726b85e636c1716489533d4e39d145d0a505477f024813f9f42b8f223e8ac3a89183cf912aba41c1bc4b5d746c02f61f159f235437367
7
+ data.tar.gz: '08c8e3b9440cfe0bee4c5ba754cc15ed790da9e1cf7ef69d984d45cbde0fadde0fba621e6928faa9798937215e4a282808601460907d3c8bb9adf4bb5493df43'
data/ext/yrb/Cargo.toml CHANGED
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "yrb"
3
- version = "0.3.0"
3
+ version = "0.3.1"
4
4
  authors = ["Hannes Moser <box@hannesmoser.at>", "Hannes Moser <hmoser@gitlab.com>"]
5
5
  edition = "2021"
6
6
  homepage = "https://github.com/y-crdt/yrb"
data/ext/yrb/src/lib.rs CHANGED
@@ -1,7 +1,7 @@
1
1
  extern crate core;
2
2
 
3
3
  use crate::yarray::YArray;
4
- use crate::yawareness::{YAwareness, YAwarenessEvent, YAwarenessUpdate};
4
+ use crate::yawareness::{YAwareness, YAwarenessEvent};
5
5
  use crate::ydoc::YDoc;
6
6
  use crate::ymap::YMap;
7
7
  use crate::ytext::YText;
@@ -488,16 +488,6 @@ fn init() -> Result<(), Error> {
488
488
  )
489
489
  .expect("cannot define private method: yawareness_update_with_clients");
490
490
 
491
- let yawareness_update = module
492
- .define_class("AwarenessUpdate", Default::default())
493
- .expect("cannot define class Y:AwarenessUpdate");
494
- yawareness_update
495
- .define_private_method(
496
- "yawareness_update_encode",
497
- method!(YAwarenessUpdate::yawareness_update_encode, 0),
498
- )
499
- .expect("cannot define private method: yawareness_update_encode");
500
-
501
491
  let yawareness_event = module
502
492
  .define_class("AwarenessEvent", Default::default())
503
493
  .expect("cannot define class Y:AwarenessEvent");
@@ -23,13 +23,15 @@ impl YAwareness {
23
23
  Self(RefCell::new(awareness))
24
24
  }
25
25
 
26
- pub(crate) fn yawareness_apply_update(&self, update: &YAwarenessUpdate) -> Result<(), Error> {
27
- update.decode().and_then(|value| {
28
- self.0
29
- .borrow_mut()
30
- .apply_update(value)
31
- .map_err(|_error| Error::runtime_error("cannot decode awareness update"))
32
- })
26
+ pub(crate) fn yawareness_apply_update(&self, update: Vec<u8>) -> Result<(), Error> {
27
+ AwarenessUpdate::decode_v1(update.as_slice())
28
+ .map_err(|_error| Error::runtime_error("cannot decode update"))
29
+ .and_then(|value| {
30
+ self.0
31
+ .borrow_mut()
32
+ .apply_update(value)
33
+ .map_err(|_error| Error::runtime_error("cannot apply awareness update"))
34
+ })
33
35
  }
34
36
 
35
37
  pub(crate) fn yawareness_clean_local_state(&self) {
@@ -76,23 +78,25 @@ impl YAwareness {
76
78
  self.0.borrow_mut().set_local_state(json)
77
79
  }
78
80
 
79
- pub(crate) fn yawareness_update(&self) -> Result<YAwarenessUpdate, Error> {
81
+ pub(crate) fn yawareness_update(&self) -> Result<Vec<u8>, Error> {
80
82
  self.0
81
83
  .borrow_mut()
82
84
  .update()
83
- .map(YAwarenessUpdate::from)
84
- .map_err(|_error| Error::runtime_error("cannot update awareness"))
85
+ .map(|update| update.encode_v1())
86
+ .map_err(|_error| Error::runtime_error("cannot create update for current state"))
85
87
  }
86
88
 
87
89
  pub(crate) fn yawareness_update_with_clients(
88
90
  &self,
89
91
  clients: Vec<ClientID>,
90
- ) -> Result<YAwarenessUpdate, Error> {
92
+ ) -> Result<Vec<u8>, Error> {
91
93
  self.0
92
94
  .borrow_mut()
93
95
  .update_with_clients(clients)
94
- .map(YAwarenessUpdate::from)
95
- .map_err(|_error| Error::runtime_error("cannot update awareness with clients"))
96
+ .map(|update| update.encode_v1())
97
+ .map_err(|_error| {
98
+ Error::runtime_error("cannot create update for current state and given clients")
99
+ })
96
100
  }
97
101
  }
98
102
 
@@ -102,34 +106,6 @@ impl From<Awareness> for YAwareness {
102
106
  }
103
107
  }
104
108
 
105
- #[magnus::wrap(class = "Y::AwarenessUpdate")]
106
- pub(crate) struct YAwarenessUpdate(pub(crate) Vec<u8>);
107
-
108
- /// SAFETY: This is safe because we only access this data when the GVL is held.
109
- unsafe impl Send for YAwarenessUpdate {}
110
-
111
- impl YAwarenessUpdate {
112
- pub(crate) fn decode(&self) -> Result<AwarenessUpdate, Error> {
113
- AwarenessUpdate::decode_v1(self.0.borrow())
114
- .map_err(|_error| Error::runtime_error("cannot decode awareness update"))
115
- }
116
- pub(crate) fn yawareness_update_encode(&self) -> Vec<u8> {
117
- self.0.to_vec()
118
- }
119
- }
120
-
121
- impl From<AwarenessUpdate> for YAwarenessUpdate {
122
- fn from(value: AwarenessUpdate) -> Self {
123
- YAwarenessUpdate(value.encode_v1())
124
- }
125
- }
126
-
127
- impl From<Vec<u8>> for YAwarenessUpdate {
128
- fn from(value: Vec<u8>) -> Self {
129
- YAwarenessUpdate(value)
130
- }
131
- }
132
-
133
109
  #[magnus::wrap(class = "Y::AwarenessEvent")]
134
110
  pub(crate) struct YAwarenessEvent(Event);
135
111
 
data/lib/2.7/yrb.so CHANGED
Binary file
data/lib/3.0/yrb.so CHANGED
Binary file
data/lib/3.1/yrb.so CHANGED
Binary file
data/lib/y/awareness.rb CHANGED
@@ -1,50 +1,168 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Y
4
+ # The Awareness class implements a simple shared state protocol that can be
5
+ # used for non-persistent data like awareness information (cursor, username,
6
+ # status, ..). Each client can update its own local state and listen to state
7
+ # changes of remote clients.
8
+ #
9
+ # Each client is identified by a unique client id (something we borrow from
10
+ # doc.client_id). A client can override its own state by propagating a message
11
+ # with an increasing timestamp (clock). If such a message is received, it is
12
+ # applied if the known state of that client is older than the new state
13
+ # (`clock < new_clock`). If a client thinks that a remote client is offline,
14
+ # it may propagate a message with `{ clock, state: null, client }`. If such a
15
+ # message is received, and the known clock of that client equals the received
16
+ # clock, it will clean the state.
17
+ #
18
+ # Before a client disconnects, it should propagate a null state with an
19
+ # updated clock.
20
+ #
21
+ # Awareness is an integral part of collaborative applications, you can read
22
+ # more about the concept here: https://docs.yjs.dev/getting-started/adding-awareness
23
+ #
24
+ # @example Instantiate awareness instance and encode update for broadcast
25
+ # local_state = {
26
+ # editing: { field: "description", pos: 0 },
27
+ # name: "Hannes Moser"
28
+ # }.to_json
29
+ #
30
+ # awareness = Y::Awareness.new
31
+ # awareness.local_state = local_state
32
+ # awareness.diff # [1,227,245,175,195,11,1,65,123, …]
33
+ #
34
+ #
4
35
  class Awareness
5
- def apply_update(update)
6
- yawareness_apply_update(update)
36
+ # Applies an incoming update. This gets the local awareness instance in
37
+ # sync with changes from another client. i.e., updates the state of another
38
+ # user in the local awareness instance.
39
+ #
40
+ # @example Apply an incoming update
41
+ # update = [1,227,245,175,195,11,1,65,123, …]
42
+ #
43
+ # awareness = Y::Awareness.new
44
+ # awareness.sync(update)
45
+ #
46
+ # @param [Array<Integer>] diff A binary encoded update
47
+ # @return [void]
48
+ def sync(diff)
49
+ yawareness_apply_update(diff)
7
50
  end
8
51
 
52
+ # Clears out a state of a current client, effectively marking it as
53
+ # disconnected.
54
+ #
55
+ # @return [void]
9
56
  def clean_local_state
10
57
  yawareness_clean_local_state
11
58
  end
12
59
 
60
+ # Returns a globally unique client ID of an underlying Doc.
61
+ #
62
+ # @return [Integer] Returns the client_id of the local user
13
63
  def client_id
14
64
  yawareness_client_id
15
65
  end
16
66
 
67
+ # Returns a state map of all of the clients tracked by current Awareness
68
+ # instance. Those states are identified by their corresponding ClientIDs.
69
+ # The associated state is represented and replicated to other clients as a
70
+ # JSON string.
71
+ #
72
+ # @example Instantiate awareness instance and encode update for broadcast
73
+ # local_state = {
74
+ # editing: { field: "description", pos: 0 },
75
+ # name: "Hannes Moser"
76
+ # }.to_json
77
+ #
78
+ # awareness = Y::Awareness.new
79
+ # awareness.local_state = local_state
80
+ # awareness.clients # {312134501=>"{\"editing\":{\"field\":\"descriptio …
81
+ #
82
+ # @return [Hash] All clients and their current state
17
83
  def clients
18
84
  yawareness_clients
19
85
  end
20
86
 
87
+ # Returns a JSON string state representation of a current Awareness
88
+ # instance.
89
+ #
90
+ # @example Create local state and inspect it
91
+ # local_state = {
92
+ # editing: { field: "description", pos: 0 },
93
+ # name: "Hannes Moser"
94
+ # }.to_json
95
+ #
96
+ # awareness = Y::Awareness.new
97
+ # awareness.local_state = local_state
98
+ # local_state # "{\"editing\":{\"field\":\"description\",\"pos\":0}, …
99
+ #
100
+ # @return [String] The current state of the local client
21
101
  def local_state
22
102
  yawareness_local_state
23
103
  end
24
104
 
105
+ # Sets a current Awareness instance state to a corresponding JSON string.
106
+ # This state will be replicated to other clients as part of the
107
+ # AwarenessUpdate.
108
+ #
109
+ # @example Set local state
110
+ # local_state = {
111
+ # editing: { field: "description", pos: 0 },
112
+ # name: "Hannes Moser"
113
+ # }.to_json
114
+ #
115
+ # awareness = Y::Awareness.new
116
+ # awareness.local_state = local_state
117
+ #
118
+ # @return [void]
25
119
  def local_state=(json)
26
120
  yawareness_set_local_state(json)
27
121
  end
28
122
 
123
+ # Subscribes to changes
124
+ #
125
+ # @return [Integer] The subscription ID
29
126
  def attach(callback, &block)
30
127
  return yawareness_on_update(callback) unless callback.nil?
31
128
 
32
129
  yawareness_on_update(block.to_proc) unless block.nil?
33
130
  end
34
131
 
132
+ # Unsubscribe from changes
133
+ #
134
+ # @param [Integer] subscription_id
135
+ # @return [void]
35
136
  def detach(subscription_id)
36
137
  yawareness_remove_on_update(subscription_id)
37
138
  end
38
139
 
140
+ # Clears out a state of a given client, effectively marking it as
141
+ # disconnected.
142
+ #
143
+ # @param [Integer] client_id Clears the state for given client_id
144
+ # @return [void]
39
145
  def remove_state(client_id)
40
146
  yawareness_remove_state(client_id)
41
147
  end
42
148
 
43
- def update
149
+ # Returns a serializable update object which is representation of a current
150
+ # Awareness state.
151
+ #
152
+ # @return [::Array<Integer>] Binary encoded update of the local instance
153
+ def diff
44
154
  yawareness_update
45
155
  end
46
156
 
47
- def update_with_clients(clients)
157
+ # Returns a serializable update object which is representation of a current
158
+ # Awareness state. Unlike Awareness::update, this method variant allows to
159
+ # prepare update only for a subset of known clients. These clients must all
160
+ # be known to a current Awareness instance, otherwise a
161
+ # Error::ClientNotFound error will be returned.
162
+ #
163
+ # @param [::Array<Integer>] clients A list of client IDs
164
+ # @return [String] Binary encoded update including all given client IDs
165
+ def diff_with_clients(*clients)
48
166
  yawareness_update_with_clients(clients)
49
167
  end
50
168
 
@@ -57,6 +175,12 @@ module Y
57
175
  # @param [Y::AwarenessUpdate] A structure that represents an encodable state
58
176
  # of an Awareness struct.
59
177
 
178
+ # @!method yawareness_apply_update(update)
179
+ # Applies an update
180
+ #
181
+ # @param [Y::AwarenessUpdate] A structure that represents an encodable state
182
+ # of an Awareness struct.
183
+
60
184
  # @!method yawareness_clean_local_state
61
185
  # Clears out a state of a current client , effectively marking it as
62
186
  # disconnected.
@@ -91,7 +215,7 @@ module Y
91
215
  # Clears out a state of a given client, effectively marking it as
92
216
  # disconnected.
93
217
  #
94
- # @param [Integer] A Client ID
218
+ # @param [Integer] client_id A Client ID
95
219
  # @return [String|nil] Returns a JSON string state representation of a
96
220
  # current Awareness instance.
97
221
 
@@ -119,8 +243,8 @@ module Y
119
243
  # These clients must all be known to a current Awareness instance,
120
244
  # otherwise an error will be returned.
121
245
  #
122
- # @param [Array<Integer>]
123
- # @return [Y::AwarenessUpdate] The update object
246
+ # @param [::Array<Integer>] clients
247
+ # @return [::Array<Integer>] A serialized (binary encoded) update object
124
248
 
125
249
  # rubocop:enable Lint/UselessAccessModifier
126
250
  end
@@ -130,28 +254,13 @@ module Y
130
254
  private
131
255
 
132
256
  # @!method added
133
- # @return [Array<Integer>] Added clients
257
+ # @return [::Array<Integer>] Added clients
134
258
 
135
259
  # @!method updated
136
- # @return [Array<Integer>] Updated clients
260
+ # @return [::Array<Integer>] Updated clients
137
261
 
138
262
  # @!method removed
139
- # @return [Array<Integer>] Removed clients
140
- end
141
- # rubocop:enable Lint/UselessAccessModifier
142
-
143
- # rubocop:disable Lint/UselessAccessModifier
144
- class AwarenessUpdate
145
- def encode
146
- yawareness_update_encode
147
- end
148
-
149
- private
150
-
151
- # @!method yawareness_update_encode
152
- # Encode the awareness state for simple transport
153
- #
154
- # @return [Array<Integer>] Encoded update
263
+ # @return [::Array<Integer>] Removed clients
155
264
  end
156
265
  # rubocop:enable Lint/UselessAccessModifier
157
266
  end
data/lib/y/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Y
4
- VERSION = "0.3.0"
4
+ VERSION = "0.3.1"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: y-rb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.1
5
5
  platform: x86_64-linux
6
6
  authors:
7
7
  - Hannes Moser
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-10-20 00:00:00.000000000 Z
11
+ date: 2022-10-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake