Class: Y::Doc

Inherits:
Object
  • Object
show all
Defined in:
lib/y/doc.rb

Overview

Examples:

Create a local and remote doc and syncs the diff

local = Y::Doc.new
local_map = local.get_map("my map")
local_map[:hello] = "world"

remote = Y::Doc.new

diff = local.diff(remote.state)
remote.sync(diff)

remote_map = remote.get_map("my_map")
pp remote_map.to_h #=> {hello: "world"}

Instance Method Summary collapse

Instance Method Details

#attach(&block) ⇒ Object

Example: Attach listener to document changes doc = described_class.new doc.attach { |update| pp update }

text = doc.get_text("my text") text << "1"



37
38
39
# File 'lib/y/doc.rb', line 37

def attach(&block)
  ydoc_observe_update(block)
end

#commitvoid

This method returns an undefined value.

Commit current transaction

This is a convenience method that invokes Transaction#commit on the current transaction used by this document.



47
48
49
# File 'lib/y/doc.rb', line 47

def commit
  current_transaction(&:commit)
end

#diff(state = ZERO_STATE) ⇒ ::Array<Integer>

Create a diff between this document and another document. The diff is created based on a state vector provided by the other document. It only returns the missing blocks, as binary encoded sequence.

Parameters:

  • state (::Array<Integer>) (defaults to: ZERO_STATE)

    The state to create the diff against

Returns:

  • (::Array<Integer>)

    Binary encoded diff



57
58
59
# File 'lib/y/doc.rb', line 57

def diff(state = ZERO_STATE)
  current_transaction { |tx| ydoc_encode_diff_v1(tx, state) }
end

#diff_v2(state = ZERO_STATE_V2) ⇒ ::Array<Integer>

Create a v2 diff between this document and another document. The diff is created based on a state vector provided by the other document. It only returns the missing blocks, as binary encoded sequence.

Parameters:

  • state (::Array<Integer>) (defaults to: ZERO_STATE_V2)

    The state to create the diff against

Returns:

  • (::Array<Integer>)

    Binary encoded diff



67
68
69
# File 'lib/y/doc.rb', line 67

def diff_v2(state = ZERO_STATE_V2)
  current_transaction { |tx| ydoc_encode_diff_v2(tx, state) }
end

#full_diff::Array<Integer>

Creates a full diff for the current document. It is similar to #diff, but does not take a state. Instead it creates an empty state and passes it to the encode_diff function.

Returns:

  • (::Array<Integer>)

    Binary encoded diff



76
77
78
# File 'lib/y/doc.rb', line 76

def full_diff
  diff
end

#get_array(name, values = nil) ⇒ Y::Array

Gets or creates a new array by name

If the optional values array is present, fills the array up with elements from the provided array. If the array already exists and isn't empty, elements are pushed to the end of the array.

Parameters:

  • name (String)

    The name of the structure

  • values (::Array) (defaults to: nil)

    Optional initial values

Returns:



89
90
91
92
93
94
# File 'lib/y/doc.rb', line 89

def get_array(name, values = nil)
  array = ydoc_get_or_insert_array(name)
  array.document = self
  array.concat(values) unless values.nil?
  array
end

#get_map(name, input = nil) ⇒ Y::Map

Gets or creates a new map by name

If the optional input hash is present, fills the map up with key-value pairs from the provided input hash. If the map already exists and isn't empty, any existing keys are overridden and new keys are added.

Parameters:

  • name (String)

    The name of the structure

  • input (Hash) (defaults to: nil)

    Optional initial map key-value pairs

Returns:



105
106
107
108
109
110
# File 'lib/y/doc.rb', line 105

def get_map(name, input = nil)
  map = ydoc_get_or_insert_map(name)
  map.document = self
  input&.each { |key, value| map[key] = value }
  map
end

#get_text(name, input = nil) ⇒ Y::Text

Gets or creates a new text by name

If the optional input string is provided, fills a new text with the string at creation time. If the text isn't new and not empty, appends the input to the end of the text.

Parameters:

  • name (String)

    The name of the structure

  • input (String) (defaults to: nil)

    Optional initial text value

Returns:



121
122
123
124
125
126
# File 'lib/y/doc.rb', line 121

def get_text(name, input = nil)
  text = ydoc_get_or_insert_text(name)
  text.document = self
  text << input unless input.nil?
  text
end

#get_xml_element(name) ⇒ Y::XMLElement

Gets or creates a new XMLElement by name

Parameters:

  • name (String)

    The name of the structure

Returns:



132
133
134
135
136
# File 'lib/y/doc.rb', line 132

def get_xml_element(name)
  xml_element = ydoc_get_or_insert_xml_element(name)
  xml_element.document = self
  xml_element
end

#get_xml_fragment(name) ⇒ Y::XMLFragment

Gets or creates a new XMLFragment by name

Parameters:

  • name (String)

    The name of the fragment

Returns:

  • (Y::XMLFragment)


142
143
144
145
146
# File 'lib/y/doc.rb', line 142

def get_xml_fragment(name)
  xml_fragment = ydoc_get_or_insert_xml_fragment(name)
  xml_fragment.document = self
  xml_fragment
end

#get_xml_text(name, input = nil) ⇒ Y::XMLText

Gets or creates a new XMLText by name

Parameters:

  • name (String)

    The name of the structure

  • input (String) (defaults to: nil)

    Optional initial text value

Returns:



153
154
155
156
157
158
# File 'lib/y/doc.rb', line 153

def get_xml_text(name, input = nil)
  xml_text = ydoc_get_or_insert_xml_text(name)
  xml_text.document = self
  xml_text << input unless input.nil?
  xml_text
end

#restore(full_diff) ⇒ void

This method returns an undefined value.

Restores a specific document from an update that contains full state

This is doing the same as #sync, but it exists to be explicit about the intent. This is the companion to #full_diff.

Parameters:

  • full_diff (::Array<Integer>)

    Binary encoded update



199
200
201
# File 'lib/y/doc.rb', line 199

def restore(full_diff)
  current_transaction { |tx| tx.apply(full_diff) }
end

#state::Array<Integer>

Creates a state vector of this document. This can be used to compare the state of two documents with each other and to later on sync them.

Returns:

  • (::Array<Integer>)

    Binary encoded state vector



164
165
166
# File 'lib/y/doc.rb', line 164

def state
  current_transaction(&:state)
end

#state_v2::Array<Integer>

Creates a v2 state vector of this document. This can be used to compare the state of two documents with each other and to later on sync them.

Returns:

  • (::Array<Integer>)

    Binary encoded state vector



172
173
174
# File 'lib/y/doc.rb', line 172

def state_v2
  current_transaction(&:state_v2)
end

#sync(diff) ⇒ void

This method returns an undefined value.

Synchronizes this document with the diff from another document

Parameters:

  • diff (::Array<Integer>)

    Binary encoded update



180
181
182
# File 'lib/y/doc.rb', line 180

def sync(diff)
  current_transaction { |tx| tx.apply(diff) }
end

#sync_v2(diff) ⇒ void

This method returns an undefined value.

Synchronizes this document with the v2 diff from another document

Parameters:

  • diff (::Array<Integer>)

    Binary encoded update



188
189
190
# File 'lib/y/doc.rb', line 188

def sync_v2(diff)
  current_transaction { |tx| tx.apply_v2(diff) }
end

#transactObject

Creates a new transaction



204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
# File 'lib/y/doc.rb', line 204

def transact
  # 1. release potentially existing transaction
  if @current_transaction
    @current_transaction.free
    @current_transaction = nil
  end

  # 2. store new transaction in instance variable
  @current_transaction = ydoc_transact
  @current_transaction.document = self

  # 3. call block with reference to current_transaction
  yield @current_transaction
ensure
  @current_transaction&.free
  @current_transaction = nil
end