collab 0.3.1 → 0.5.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/lib/collab.rb +3 -0
- data/lib/collab/channel.rb +25 -11
- data/lib/collab/config.rb +3 -4
- data/lib/collab/engine.rb +2 -2
- data/lib/collab/has_tracked_document_positions.rb +34 -0
- data/lib/collab/js.rb +15 -10
- data/lib/collab/models/commit.rb +13 -39
- data/lib/collab/models/document.rb +66 -8
- data/lib/collab/models/tracked_position.rb +45 -0
- data/lib/collab/selection.rb +21 -0
- data/lib/collab/version.rb +1 -1
- data/lib/generators/collab/install/templates/channel.rb +15 -8
- data/lib/generators/collab/install/templates/create_collab_tables.rb.erb +13 -0
- data/lib/generators/collab/install/templates/initializer.rb +0 -5
- metadata +33 -3
- data/app/jobs/collab/commit_job.rb +0 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 57b6b2acc480ad0a0d40fb20c82a1091b30dbea74b674a5d02339dd1bf8b7f83
|
4
|
+
data.tar.gz: 2a36b774b1ad0693feef4194888a07b58e8899173de10bad52a174d012a6c2f4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ab13771371259f4294fd94d207889643631f541dfdc26f43dbc6b2e7a454e79de4816dc4be560d1203b70dfe82a2e8b26fb3d1bcc56172743d2ce872060ee40f
|
7
|
+
data.tar.gz: 0a18c044a507454196599921a00ba0ace34fb7b3230dcb2c0a06124774f5893fa77d12a373f34d91cfe556af31a8c0d41a89571da8f3c0a37d8841dd141795e1
|
data/lib/collab.rb
CHANGED
@@ -6,10 +6,13 @@ require "collab/engine"
|
|
6
6
|
module Collab
|
7
7
|
autoload "Channel", "collab/channel"
|
8
8
|
autoload "HasCollaborativeDocument", "collab/has_collaborative_document"
|
9
|
+
# autoload "DocumentSelection", "collab/selection"
|
10
|
+
autoload "HasTrackedDocumentPositions", "collab/has_tracked_document_positions"
|
9
11
|
|
10
12
|
module Models
|
11
13
|
autoload "Base", "collab/models/base"
|
12
14
|
autoload "Document", "collab/models/document"
|
13
15
|
autoload "Commit", "collab/models/commit"
|
16
|
+
autoload "TrackedPosition", "collab/models/tracked_position"
|
14
17
|
end
|
15
18
|
end
|
data/lib/collab/channel.rb
CHANGED
@@ -1,19 +1,18 @@
|
|
1
1
|
module Collab
|
2
2
|
module Channel
|
3
|
-
def document; @document end
|
4
|
-
|
5
3
|
def subscribed
|
6
|
-
@document = find_document
|
7
|
-
|
4
|
+
reject_unauthorized_connection unless @document = find_document
|
5
|
+
|
8
6
|
starting_version = params[:startingVersion]&.to_i
|
9
7
|
raise "missing startingVersion" if starting_version.nil?
|
8
|
+
raise "invalid version" unless @document.possibly_saved_version? starting_version
|
10
9
|
|
11
|
-
stream_for document
|
10
|
+
stream_for @document
|
12
11
|
|
13
|
-
commits = document.commits
|
14
|
-
|
15
|
-
|
16
|
-
|
12
|
+
commits = @document.commits
|
13
|
+
.where("document_version > ?", starting_version)
|
14
|
+
.order(document_version: :asc)
|
15
|
+
.load
|
17
16
|
|
18
17
|
unless commits.empty?
|
19
18
|
raise "invalid version" unless commits.first.document_version == (starting_version + 1)
|
@@ -22,10 +21,25 @@ module Collab
|
|
22
21
|
end
|
23
22
|
|
24
23
|
def commit(data)
|
25
|
-
|
26
|
-
document.commit_later(data)
|
24
|
+
@document.apply_commit(data)
|
27
25
|
end
|
28
26
|
|
27
|
+
# def select(data)
|
28
|
+
# return unless defined?(_select)
|
29
|
+
|
30
|
+
# version = data["v"]&.to_i
|
31
|
+
# anchor_pos = data["anchor"]&.to_i
|
32
|
+
# head_pos = data["head"]&.to_i
|
33
|
+
|
34
|
+
# return unless version && @document.possibly_saved_version?(version) && anchor_pos && head_pos
|
35
|
+
|
36
|
+
# @document.resolve_selection(anchor_pos, head_pos, version: version) do |selection|
|
37
|
+
# _select selection
|
38
|
+
# end
|
39
|
+
|
40
|
+
# transmit({ack: "select"})
|
41
|
+
# end
|
42
|
+
|
29
43
|
def unsubscribed
|
30
44
|
stop_all_streams # this may not be needed
|
31
45
|
end
|
data/lib/collab/config.rb
CHANGED
@@ -16,19 +16,18 @@ module Collab
|
|
16
16
|
|
17
17
|
class Config
|
18
18
|
attr_accessor :base_record,
|
19
|
-
:base_job,
|
20
19
|
:channel,
|
21
|
-
:commit_job,
|
22
20
|
:commit_model,
|
23
21
|
:document_model,
|
24
22
|
:max_commit_history_length,
|
25
23
|
:num_js_processes,
|
26
|
-
:schema_package
|
24
|
+
:schema_package,
|
25
|
+
:tracked_position_model
|
27
26
|
|
28
27
|
def initialize
|
29
|
-
self.commit_job = "Collab::CommitJob"
|
30
28
|
self.document_model = "Collab::Models::Document"
|
31
29
|
self.commit_model = "Collab::Models::Commit"
|
30
|
+
self.tracked_position_model = "Collab::Models::TrackedPosition"
|
32
31
|
end
|
33
32
|
end
|
34
33
|
end
|
data/lib/collab/engine.rb
CHANGED
@@ -0,0 +1,34 @@
|
|
1
|
+
module Collab
|
2
|
+
module HasTrackedDocumentPositions
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
class_methods do
|
6
|
+
def has_tracked_document_position(pos_name, optional: true)
|
7
|
+
has_one pos_name.to_sym, -> { where(name: pos_name) }, class_name: ::Collab.config.tracked_position_model, as: :owner, dependent: :destroy, autosave: true
|
8
|
+
validates pos_name.to_sym, presence: !optional
|
9
|
+
|
10
|
+
define_method :"#{pos_name}=" do |pos|
|
11
|
+
pos.name = pos_name
|
12
|
+
super(pos)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def has_tracked_document_selection(selection_name)
|
17
|
+
has_tracked_document_position :"#{selection_name}_anchor"
|
18
|
+
has_tracked_document_position :"#{selection_name}_head"
|
19
|
+
|
20
|
+
define_method selection_name do
|
21
|
+
anchor = self.send(:"#{selection_name}_anchor")
|
22
|
+
head = self.send(:"#{selection_name}_head")
|
23
|
+
|
24
|
+
::Collab::DocumentSelection.new anchor, head
|
25
|
+
end
|
26
|
+
|
27
|
+
define_method :"#{selection_name}=" do |sel|
|
28
|
+
self.send(:"#{selection_name}_anchor=", sel&.anchor)
|
29
|
+
self.send(:"#{selection_name}_head=", sel&.head)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
data/lib/collab/js.rb
CHANGED
@@ -21,20 +21,26 @@ module Collab
|
|
21
21
|
queue << js
|
22
22
|
end
|
23
23
|
|
24
|
-
def call(name, data = nil, schema_name
|
25
|
-
|
24
|
+
def call(name, data = nil, schema_name = nil)
|
25
|
+
req = {name: name, data: data, schemaPackage: ::Collab.config.schema_package}
|
26
|
+
req[:schemaName] = schema_name if schema_name
|
27
|
+
with_js { |js| js.call(JSON.generate(req)) }
|
26
28
|
end
|
27
29
|
|
28
|
-
def apply_commit(document, commit, schema_name:)
|
29
|
-
call("applyCommit", {doc: document, commit: commit
|
30
|
+
def apply_commit(document, commit, pos: nil, map_steps_through:, schema_name:)
|
31
|
+
call("applyCommit", {doc: document, commit: commit, mapStepsThrough: map_steps_through, pos: pos},schema_name)
|
30
32
|
end
|
31
33
|
|
32
34
|
def html_to_document(html, schema_name:)
|
33
|
-
call("htmlToDoc", html, schema_name
|
35
|
+
call("htmlToDoc", html, schema_name)
|
34
36
|
end
|
35
37
|
|
36
38
|
def document_to_html(document, schema_name:)
|
37
|
-
call("docToHtml", document, schema_name
|
39
|
+
call("docToHtml", document, schema_name)
|
40
|
+
end
|
41
|
+
|
42
|
+
def map_through(steps:, pos:)
|
43
|
+
call("mapThru", {steps: steps, pos: pos})
|
38
44
|
end
|
39
45
|
|
40
46
|
private
|
@@ -58,9 +64,8 @@ module Collab
|
|
58
64
|
end
|
59
65
|
end
|
60
66
|
|
61
|
-
def call(
|
62
|
-
req
|
63
|
-
@node.puts(JSON.generate(req))
|
67
|
+
def call(req)
|
68
|
+
@node.puts(req)
|
64
69
|
res = JSON.parse(@node.gets)
|
65
70
|
raise ::Collab::JS::JSRuntimeError.new(res["error"]) if res["error"]
|
66
71
|
res["result"]
|
@@ -68,7 +73,7 @@ module Collab
|
|
68
73
|
|
69
74
|
private
|
70
75
|
def open_node
|
71
|
-
IO.popen(["node", "-e", "require('
|
76
|
+
IO.popen(["node", "-e", "require('@pmcp/authority/dist/rpc')"], "r+")
|
72
77
|
end
|
73
78
|
end
|
74
79
|
|
data/lib/collab/models/commit.rb
CHANGED
@@ -2,52 +2,26 @@ module Collab
|
|
2
2
|
class Models::Commit < ::Collab::Models::Base
|
3
3
|
belongs_to :document, class_name: ::Collab.config.document_model
|
4
4
|
|
5
|
-
validates :steps,
|
6
|
-
validates :document_version, presence: true
|
7
|
-
validates :ref, length: { maximum: 36 }
|
5
|
+
validates :steps, length: { in: 0..10, allow_nil: false }
|
6
|
+
validates :document_version, presence: true, numericality: {only_integer: true, greater_than_or_equal_to: 0}
|
7
|
+
validates :ref, length: { maximum: 36 }, if: :ref
|
8
8
|
|
9
9
|
after_create_commit :broadcast
|
10
10
|
|
11
|
-
def
|
12
|
-
|
11
|
+
def steps
|
12
|
+
super || []
|
13
13
|
end
|
14
14
|
|
15
|
-
def
|
16
|
-
{
|
17
|
-
v
|
18
|
-
steps
|
19
|
-
ref
|
20
|
-
}
|
21
|
-
end
|
22
|
-
|
23
|
-
def apply_later
|
24
|
-
raise "cannot apply persisted commit" if self.persisted?
|
25
|
-
raise "commit not valid" unless self.valid?
|
26
|
-
return false if self.document.document_version != self.document_version
|
27
|
-
|
28
|
-
::Collab.config.commit_job.constantize.perform_later(self.document, as_json)
|
29
|
-
end
|
30
|
-
|
31
|
-
def apply!
|
32
|
-
raise "cannot apply persisted commit" if self.persisted?
|
33
|
-
raise "commit not valid" unless self.valid?
|
34
|
-
return false if self.document.document_version != self.document_version # optimization, prevents need to apply lock if outdated
|
35
|
-
|
36
|
-
self.document.with_lock do
|
37
|
-
return false if self.document.document_version != self.document_version
|
38
|
-
|
39
|
-
return false unless result = ::Collab::JS.apply_commit(self.document, self.to_json, schema_name: self.document.schema_name)
|
40
|
-
|
41
|
-
self.document.document = result["doc"]
|
42
|
-
self.document.document_version = self.document_version
|
43
|
-
|
44
|
-
self.document.save!
|
45
|
-
self.save!
|
46
|
-
end
|
15
|
+
def broadcast
|
16
|
+
::Collab.config.channel.constantize.broadcast_to(document, {
|
17
|
+
"v" => document_version,
|
18
|
+
"steps" => steps,
|
19
|
+
"ref" => ref
|
20
|
+
})
|
47
21
|
end
|
48
22
|
|
49
|
-
def
|
50
|
-
|
23
|
+
def self.steps
|
24
|
+
pluck(:steps).flatten(1)
|
51
25
|
end
|
52
26
|
end
|
53
27
|
end
|
@@ -1,7 +1,11 @@
|
|
1
1
|
module Collab
|
2
2
|
class Models::Document < ::Collab::Models::Base
|
3
3
|
belongs_to :attached, polymorphic: true
|
4
|
-
|
4
|
+
|
5
|
+
with_options foreign_key: :document_id do
|
6
|
+
has_many :commits, class_name: ::Collab.config.commit_model
|
7
|
+
has_many :tracked_positions, class_name: ::Collab.config.tracked_position_model
|
8
|
+
end
|
5
9
|
|
6
10
|
validates :content, presence: true
|
7
11
|
validates :document_version, presence: true, numericality: {only_integer: true, greater_than_or_equal_to: 0}
|
@@ -24,12 +28,49 @@ module Collab
|
|
24
28
|
end
|
25
29
|
end
|
26
30
|
|
27
|
-
def
|
28
|
-
|
31
|
+
def apply_commit(data)
|
32
|
+
base_version = data["v"]&.to_i
|
33
|
+
steps = data["steps"]
|
34
|
+
|
35
|
+
return false unless base_version
|
36
|
+
return false unless steps.is_a?(Array) && !steps.empty?
|
37
|
+
|
38
|
+
self.with_lock do
|
39
|
+
return false unless self.possibly_saved_version? base_version
|
40
|
+
|
41
|
+
self.document_version += 1
|
42
|
+
|
43
|
+
original_positions = self.tracked_positions.current.distinct.pluck(:pos, :assoc).map { |(pos, assoc)| {pos: pos, assoc: assoc} }
|
44
|
+
|
45
|
+
result = ::Collab::JS.apply_commit content,
|
46
|
+
{steps: steps},
|
47
|
+
map_steps_through: self.commits.where("document_version > ?", base_version).steps,
|
48
|
+
pos: original_positions,
|
49
|
+
schema_name: schema_name
|
50
|
+
|
51
|
+
self.content = result["doc"]
|
52
|
+
|
53
|
+
commits.create!({
|
54
|
+
steps: result["steps"],
|
55
|
+
ref: data["ref"],
|
56
|
+
document_version: self.document_version
|
57
|
+
})
|
58
|
+
|
59
|
+
self.save!
|
60
|
+
|
61
|
+
original_positions.lazy.zip(result["pos"]) do |original, res|
|
62
|
+
if res["deleted"]
|
63
|
+
tracked_positions.current.where(original).update_all deleted_at_version: self.document_version
|
64
|
+
elsif original[:pos] != res["pos"]
|
65
|
+
tracked_positions.current.where(original).update_all pos: res["pos"]
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
29
70
|
end
|
30
71
|
|
31
|
-
def
|
32
|
-
|
72
|
+
def from_html(html)
|
73
|
+
self.content = ::Collab::JS.html_to_document(html, schema_name: schema_name)
|
33
74
|
end
|
34
75
|
|
35
76
|
def as_json
|
@@ -41,12 +82,29 @@ module Collab
|
|
41
82
|
self.serialized_html = nil
|
42
83
|
end
|
43
84
|
|
85
|
+
def possibly_saved_version?(version)
|
86
|
+
self.document_version >= version && self.oldest_saved_commit_version <= version
|
87
|
+
end
|
88
|
+
|
89
|
+
def oldest_saved_commit_version
|
90
|
+
v = document_version - ::Collab.config.max_commit_history_length
|
91
|
+
v > 0 ? v : 0
|
92
|
+
end
|
93
|
+
|
94
|
+
def resolve_positions(*positions, **kwargs, &block)
|
95
|
+
::Collab.config.tracked_position_model.constantize.resolve(self, *positions, **kwargs, &block)
|
96
|
+
end
|
97
|
+
alias :resolve_position :resolve_positions
|
98
|
+
|
99
|
+
def resolve_selection(anchor_pos, head_pos, version:, &block)
|
100
|
+
::Collab::DocumentSelection.resolve(self, anchor_pos, head_pos, version: version, &block)
|
101
|
+
end
|
102
|
+
|
44
103
|
private
|
45
104
|
|
46
105
|
def delete_old_commits
|
47
|
-
|
48
|
-
|
49
|
-
commits.where("document_version < ?", cutoff).delete_all
|
106
|
+
return if oldest_saved_commit_version == 0
|
107
|
+
commits.where("document_version < ?", oldest_saved_commit_version).delete_all
|
50
108
|
end
|
51
109
|
end
|
52
110
|
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module Collab
|
2
|
+
# Represents a position in the document which is tracked between commits
|
3
|
+
#
|
4
|
+
# If the position is deleted through mapping, deleted_at_version will be set, the position will
|
5
|
+
# no longer be tracked,
|
6
|
+
#
|
7
|
+
class Models::TrackedPosition < ::Collab::Models::Base
|
8
|
+
belongs_to :document, class_name: ::Collab.config.document_model
|
9
|
+
belongs_to :owner, polymorphic: true
|
10
|
+
|
11
|
+
validates :pos, presence: true, numericality: {only_integer: true, greater_than_or_equal_to: 0}
|
12
|
+
validates :assoc, presence: true, inclusion: {in: [-1, 1]}, numericality: {only_integer: true}
|
13
|
+
|
14
|
+
validates :deleted_at_version, numericality: {only_integer: true, greater_than_or_equal_to: 0}, if: :deleted_at_version
|
15
|
+
|
16
|
+
scope :current, -> { where(deleted_at_version: nil) }
|
17
|
+
|
18
|
+
# Resolves a set of positions and yields them to the block given, returning the result of the block
|
19
|
+
# The document will be locked IN SHARE MODE during resolution and the block execution
|
20
|
+
# Positions should consist of {"pos" => number, "assoc": number}
|
21
|
+
# Returns false if invalid version or any position has been deleted
|
22
|
+
def self.resolve(document, *positions, version:)
|
23
|
+
raise false unless document.possibly_saved_version? version
|
24
|
+
|
25
|
+
document.with_lock("FOR SHARE") do
|
26
|
+
unless document.document_version == version
|
27
|
+
steps = document.commits.where("document_version > ?", @mapped_to).order(document_version: :asc).pluck(:steps).flatten(1)
|
28
|
+
|
29
|
+
map_results = ::Collab::JS.map_through(steps: steps, pos: positions)["pos"]
|
30
|
+
|
31
|
+
map_results.each_with_index do |r, i|
|
32
|
+
return false if r["deleted"]
|
33
|
+
positions[i]["pos"] = r["pos"]
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
positions.map! do |p|
|
38
|
+
document.tracked_positions.current.find_or_initialize_by(pos: p["pos"], assoc: p["assoc"])
|
39
|
+
end
|
40
|
+
|
41
|
+
yield(*positions)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# module Collab
|
2
|
+
# class DocumentSelection
|
3
|
+
# attr_reader :anchor, :head
|
4
|
+
# def initialize(anchor, head)
|
5
|
+
# @anchor = anchor
|
6
|
+
# @head = head
|
7
|
+
# end
|
8
|
+
|
9
|
+
# def self.resolve(document, anchor_pos, head_pos, version:)
|
10
|
+
# anchor_assoc = anchor_pos > head_pos ? -1 : 1
|
11
|
+
|
12
|
+
# document.resolve_positions(
|
13
|
+
# {"pos" => anchor_pos, "assoc" => anchor_assoc},
|
14
|
+
# {"pos" => head_pos, "assoc" => anchor_assoc * -1},
|
15
|
+
# version: version
|
16
|
+
# ) do |anchor, head|
|
17
|
+
# yield new anchor, head
|
18
|
+
# end
|
19
|
+
# end
|
20
|
+
# end
|
21
|
+
# end
|
data/lib/collab/version.rb
CHANGED
@@ -1,6 +1,14 @@
|
|
1
1
|
class CollabDocumentChannel < ApplicationCable::Channel
|
2
2
|
include Collab::Channel
|
3
3
|
|
4
|
+
def commit(data)
|
5
|
+
if false # replace with your own authorization logic
|
6
|
+
raise "authorization not implemented"
|
7
|
+
end
|
8
|
+
|
9
|
+
super # make sure to call super in order to process the commit
|
10
|
+
end
|
11
|
+
|
4
12
|
private
|
5
13
|
|
6
14
|
# Find the document to subscribe to based on the params passed to the channel
|
@@ -8,15 +16,14 @@ class CollabDocumentChannel < ApplicationCable::Channel
|
|
8
16
|
def find_document
|
9
17
|
Collab::Models::Document.find(params[:document_id]).tap do |document|
|
10
18
|
# TODO: Replace with your own authorization logic
|
11
|
-
|
19
|
+
reject_unauthorized_connection
|
12
20
|
end
|
13
21
|
end
|
14
22
|
|
15
|
-
#
|
16
|
-
#
|
17
|
-
#
|
18
|
-
def
|
19
|
-
|
20
|
-
|
21
|
-
end
|
23
|
+
# Uncomment this line to receive the user's selection
|
24
|
+
# You must allow enable syncSelection on the client
|
25
|
+
#
|
26
|
+
# def _select(selection)
|
27
|
+
# ...
|
28
|
+
# end
|
22
29
|
end
|
@@ -24,5 +24,18 @@ class CreateCollabTables < ActiveRecord::Migration[6.0]
|
|
24
24
|
|
25
25
|
t.datetime :created_at, null: false
|
26
26
|
end
|
27
|
+
|
28
|
+
create_table :collab_tracked_positions<%= ", id: #{@primary_key_type.inspect}" if @primary_key_type %> do |t|
|
29
|
+
t.references :document, null: false, foreign_key: {to_table: :collab_documents}, index: false<%= ", type: #{@primary_key_type.inspect}" if @primary_key_type %>
|
30
|
+
t.references :owner, null: false, polymorphic: true, index: false<%= ", type: #{@primary_key_type.inspect}" if @primary_key_type %>
|
31
|
+
t.string :name, null: false
|
32
|
+
|
33
|
+
t.integer :pos, null: false
|
34
|
+
t.integer :assoc, null: false, default: 1
|
35
|
+
t.integer :deleted_at_version
|
36
|
+
|
37
|
+
t.index [:document_id, :deleted_at_version, :pos], name: "index_collab_tracked_positions_on_document_pos"
|
38
|
+
t.index [:owner_type, :name, :owner_id], name: "index_collab_tracked_positions_on_owner"
|
39
|
+
end
|
27
40
|
end
|
28
41
|
end
|
@@ -12,11 +12,6 @@ Collab.config do |c|
|
|
12
12
|
# If you change this, you must pass the value as {channel: "[ChannelName]"} in the params from the ActionCable client
|
13
13
|
c.channel = "CollabDocumentChannel"
|
14
14
|
|
15
|
-
# The class which jobs in the gem should inherit from
|
16
|
-
c.base_job = "ApplicationJob"
|
17
|
-
# The jobs to use, if you want to implement your own jobs
|
18
|
-
# c.commit_job = "..."
|
19
|
-
|
20
15
|
# The class which models in the gem should inherit from
|
21
16
|
c.base_record = "ApplicationRecord"
|
22
17
|
# The models to use, if you want to implement your own models
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: collab
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ben Aubin
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-08-
|
11
|
+
date: 2020-08-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -44,6 +44,34 @@ dependencies:
|
|
44
44
|
- - ">="
|
45
45
|
- !ruby/object:Gem::Version
|
46
46
|
version: '0'
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: webpacker
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - ">="
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '0'
|
61
|
+
- !ruby/object:Gem::Dependency
|
62
|
+
name: puma
|
63
|
+
requirement: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - ">="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '0'
|
68
|
+
type: :development
|
69
|
+
prerelease: false
|
70
|
+
version_requirements: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - ">="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '0'
|
47
75
|
description:
|
48
76
|
email:
|
49
77
|
- ben@benaubin.com
|
@@ -52,16 +80,18 @@ extensions: []
|
|
52
80
|
extra_rdoc_files: []
|
53
81
|
files:
|
54
82
|
- Rakefile
|
55
|
-
- app/jobs/collab/commit_job.rb
|
56
83
|
- lib/collab.rb
|
57
84
|
- lib/collab/channel.rb
|
58
85
|
- lib/collab/config.rb
|
59
86
|
- lib/collab/engine.rb
|
60
87
|
- lib/collab/has_collaborative_document.rb
|
88
|
+
- lib/collab/has_tracked_document_positions.rb
|
61
89
|
- lib/collab/js.rb
|
62
90
|
- lib/collab/models/base.rb
|
63
91
|
- lib/collab/models/commit.rb
|
64
92
|
- lib/collab/models/document.rb
|
93
|
+
- lib/collab/models/tracked_position.rb
|
94
|
+
- lib/collab/selection.rb
|
65
95
|
- lib/collab/version.rb
|
66
96
|
- lib/generators/collab/install/install_generator.rb
|
67
97
|
- lib/generators/collab/install/templates/channel.rb
|