yrby 0.6.1 → 0.7.1
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 +75 -28
- data/Cargo.lock +29 -29
- data/README.md +297 -98
- data/ext/yrby/Cargo.toml +3 -3
- data/ext/yrby/crates/html-core/Cargo.toml +5 -4
- data/ext/yrby/crates/html-core/src/lib.rs +3 -7
- data/ext/yrby/crates/lexical-html/Cargo.toml +5 -4
- data/ext/yrby/crates/lexical-html/src/lib.rs +6 -10
- data/ext/yrby/crates/prosemirror-html/Cargo.toml +5 -4
- data/ext/yrby/crates/prosemirror-html/src/lib.rs +114 -72
- data/ext/yrby/src/lib.rs +10 -10
- data/ext/yrby/src/protocol.rs +63 -0
- data/lib/generators/yrby/install/templates/document_channel.rb +1 -1
- data/lib/generators/yrby/tables/tables_generator.rb +3 -3
- data/lib/y/decoder.rb +64 -0
- data/lib/y/version.rb +1 -1
- data/lib/y.rb +2 -1
- metadata +2 -1
data/lib/y/decoder.rb
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "y"
|
|
4
|
+
|
|
5
|
+
module Y
|
|
6
|
+
# Plain-text reconstruction of a stored Yjs document, for search indexing
|
|
7
|
+
# and previews. It reads the text out of the shared type the editor uses
|
|
8
|
+
# (Lexical's `Y.XmlText`, plain `Y.Text`, or ProseMirror's `Y.XmlFragment`)
|
|
9
|
+
# in-process, on the same native extension as `Doc`: no Node, no
|
|
10
|
+
# subprocess.
|
|
11
|
+
#
|
|
12
|
+
# state = doc.encode_state_as_update # opaque CRDT bytes from the store
|
|
13
|
+
# Y::Decoder.text(state) # => "hello world"
|
|
14
|
+
# Y::Decoder.preview(state, 280) # => "hello world…"
|
|
15
|
+
#
|
|
16
|
+
# For full-fidelity HTML, `Y::Lexxy` and `Y::Tiptap` render the document
|
|
17
|
+
# with the editor's own semantics; this module is the cheap plain-text
|
|
18
|
+
# path.
|
|
19
|
+
module Decoder
|
|
20
|
+
class Error < Y::Error; end
|
|
21
|
+
|
|
22
|
+
module_function
|
|
23
|
+
|
|
24
|
+
# Plain text of the document. `field` pins the root key (Lexical: the editor
|
|
25
|
+
# id; ProseMirror: "default"); omit it to use the document's sole root.
|
|
26
|
+
def text(state, field: nil)
|
|
27
|
+
field ||= Y::Doc.new.tap { |d| d.apply_update(state) }.root_names.first
|
|
28
|
+
return "" unless field
|
|
29
|
+
|
|
30
|
+
# A plain `Y.Text` root (a simple shared-text editor) reads straight out.
|
|
31
|
+
# (A yrs root's type is fixed by its first typed access, so each reader
|
|
32
|
+
# gets a fresh doc to try a different shared type against the same state.)
|
|
33
|
+
direct = load(state).read_text(field)
|
|
34
|
+
return normalize(direct) if direct && !direct.strip.empty?
|
|
35
|
+
|
|
36
|
+
# Lexical (each block a sibling `Y.XmlText`) and ProseMirror (blocks are
|
|
37
|
+
# `Y.XmlElement`s) both come back from read_xml as block-per-line markup;
|
|
38
|
+
# strip any element tags to plain text.
|
|
39
|
+
markup = load(state).read_xml(field)
|
|
40
|
+
markup ? normalize(strip_tags(markup)) : ""
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# A compact, single-line preview for list UIs.
|
|
44
|
+
def preview(state, limit: 280, field: nil)
|
|
45
|
+
body = text(state, field: field).gsub(/\s+/, " ").strip
|
|
46
|
+
body.length > limit ? "#{body[0, limit].rstrip}…" : body
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def load(state)
|
|
50
|
+
Y::Doc.new.tap { |doc| doc.apply_update(state) }
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def strip_tags(markup)
|
|
54
|
+
markup.gsub(/<[^>]*>/, " ")
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def normalize(text)
|
|
58
|
+
text.gsub(/[ \t]+/, " ") # collapse runs of spaces/tabs
|
|
59
|
+
.gsub(/ *\n */, "\n") # trim spaces left around block separators
|
|
60
|
+
.gsub(/\n{3,}/, "\n\n") # cap blank-line runs
|
|
61
|
+
.strip
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
data/lib/y/version.rb
CHANGED
data/lib/y.rb
CHANGED
|
@@ -15,9 +15,10 @@ end
|
|
|
15
15
|
require_relative "y/rendering"
|
|
16
16
|
require_relative "y/lexxy"
|
|
17
17
|
require_relative "y/tiptap"
|
|
18
|
+
require_relative "y/decoder"
|
|
18
19
|
|
|
19
20
|
module Y
|
|
20
21
|
# Doc, Error, and the protocol module functions are defined in the Rust
|
|
21
22
|
# extension. The ActionCable integration (Y::ActionCable::Sync) lives in the
|
|
22
|
-
#
|
|
23
|
+
# `yrby-rails` gem; require "y/action_cable".
|
|
23
24
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: yrby
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.7.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- JP Camara
|
|
@@ -105,6 +105,7 @@ files:
|
|
|
105
105
|
- lib/generators/yrby/tables/tables_generator.rb
|
|
106
106
|
- lib/generators/yrby/tables/templates/create_y_tables.rb
|
|
107
107
|
- lib/y.rb
|
|
108
|
+
- lib/y/decoder.rb
|
|
108
109
|
- lib/y/lexxy.rb
|
|
109
110
|
- lib/y/rendering.rb
|
|
110
111
|
- lib/y/tiptap.rb
|