live 0.1.0 → 0.4.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 +7 -0
- data/lib/live.rb +26 -89
- data/lib/live/element.rb +74 -0
- data/lib/live/page.rb +112 -0
- data/lib/live/resolver.rb +67 -0
- data/lib/live/version.rb +3 -1
- data/lib/live/view.rb +60 -0
- metadata +115 -71
- data/.gitignore +0 -5
- data/Gemfile +0 -4
- data/README.rdoc +0 -36
- data/Rakefile +0 -2
- data/bin/live +0 -6
- data/lib/ext/object.rb +0 -21
- data/live.gemspec +0 -24
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 53a3a21f8a7de949ee8da7c7a0fe6dce23d96312a067319ffcabba644265353b
|
4
|
+
data.tar.gz: 178c8cc94c77b80f030367995fdc409e583bdff9687c0bbb1355c70548f86e7e
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 70a8976aac2a661c412f98a08aa7b310faf56438053ae2661739d90c241a989b4fbfd7ed01d03c4d8e1df390cb8e4243e7c3beeff5ba8edf0d7a59c4b1007da3
|
7
|
+
data.tar.gz: e502e8cd52a9dc0509746e877ba3810d9544e514e9b83819870d12417311b7b114be15be845ea2fb169cc4b11cf144a68274e017009bf4af628cf575f5349b17
|
data/lib/live.rb
CHANGED
@@ -1,90 +1,27 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright, 2021, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
4
|
+
#
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
# of this software and associated documentation files (the "Software"), to deal
|
7
|
+
# in the Software without restriction, including without limitation the rights
|
8
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
# copies of the Software, and to permit persons to whom the Software is
|
10
|
+
# furnished to do so, subject to the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be included in
|
13
|
+
# all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
# THE SOFTWARE.
|
22
|
+
|
23
|
+
require_relative "live/version"
|
24
|
+
|
25
|
+
require_relative 'live/page'
|
26
|
+
require_relative 'live/view'
|
3
27
|
|
4
|
-
$LOAD_PATH.unshift File.dirname(__FILE__)
|
5
|
-
require 'ext/object'
|
6
|
-
|
7
|
-
module Live
|
8
|
-
class Notice < String; end
|
9
|
-
|
10
|
-
class Context
|
11
|
-
def initialize session
|
12
|
-
@session = session
|
13
|
-
@binding = binding
|
14
|
-
end
|
15
|
-
|
16
|
-
def eval string
|
17
|
-
begin
|
18
|
-
super string, @binding
|
19
|
-
rescue Exception => exception
|
20
|
-
SystemExit === exception ? quit! : exception
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
# Binds a proc to a keystroke
|
25
|
-
def bind_key key, &block
|
26
|
-
@session.key_bindings[key.to_s.unpack('c').first] = block
|
27
|
-
Notice.new "Key '#{key}' is bound to an action" if block
|
28
|
-
end
|
29
|
-
|
30
|
-
def quit!
|
31
|
-
@session.quit!
|
32
|
-
end
|
33
|
-
|
34
|
-
def reset!
|
35
|
-
@session.key_bindings.clear
|
36
|
-
@session.new_context
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
class Session
|
41
|
-
include HighLine::SystemExtensions
|
42
|
-
attr_reader :path, :key_bindings
|
43
|
-
|
44
|
-
# Starts a live session using a named pipe to receive code from a remote source and evaluates it within a context, a bit like an IRB session but evaluates code sent from a text editor
|
45
|
-
def initialize path = "#{Dir.tmpdir}/live-rb"
|
46
|
-
raise Exception.new("Another session sems to be running: #{path}") if File.exist? path
|
47
|
-
puts Notice.new("Live Session: #{path}")
|
48
|
-
|
49
|
-
%x{mkfifo #{path}}
|
50
|
-
@pipe, @path, @key_bindings = File.open(path, 'r+'), path, {}
|
51
|
-
|
52
|
-
begin
|
53
|
-
new_context and key_listen and run!
|
54
|
-
ensure
|
55
|
-
File.delete(path) if File.exists? path
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
def quit!
|
60
|
-
File.delete(@path) && exit
|
61
|
-
end
|
62
|
-
|
63
|
-
def puts obj
|
64
|
-
super obj.colored_inspect
|
65
|
-
# Hackish solution for cursor position
|
66
|
-
super "\e[200D"
|
67
|
-
super "\e[2A"
|
68
|
-
end
|
69
|
-
|
70
|
-
def new_context
|
71
|
-
@context = Context.new(self)
|
72
|
-
end
|
73
|
-
|
74
|
-
private
|
75
|
-
# Starts a loop that checks the named pipe and evaluate its contents, will be called on initialize
|
76
|
-
def run!
|
77
|
-
loop { puts @context.eval(@pipe.gets) }
|
78
|
-
end
|
79
|
-
|
80
|
-
# Listen for keystrokes and calls bound procs
|
81
|
-
def key_listen
|
82
|
-
Thread.new do
|
83
|
-
loop do
|
84
|
-
block = @key_bindings[get_character]
|
85
|
-
puts block.call if block
|
86
|
-
end
|
87
|
-
end
|
88
|
-
end
|
89
|
-
end
|
90
|
-
end
|
data/lib/live/element.rb
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright, 2021, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
4
|
+
#
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
# of this software and associated documentation files (the "Software"), to deal
|
7
|
+
# in the Software without restriction, including without limitation the rights
|
8
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
# copies of the Software, and to permit persons to whom the Software is
|
10
|
+
# furnished to do so, subject to the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be included in
|
13
|
+
# all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
# THE SOFTWARE.
|
22
|
+
|
23
|
+
require 'json'
|
24
|
+
|
25
|
+
module Live
|
26
|
+
# Represents a single dynamic content area on the page.
|
27
|
+
class Element
|
28
|
+
# @parameter id [String] The unique identifier within the page.
|
29
|
+
# @parameter data [Hash] The data associated with the element, typically stored as `data-` attributes.
|
30
|
+
def initialize(id, **data)
|
31
|
+
@id = id
|
32
|
+
@data = data
|
33
|
+
@data[:class] ||= self.class.name
|
34
|
+
|
35
|
+
@page = nil
|
36
|
+
end
|
37
|
+
|
38
|
+
# The unique id within the bound page.
|
39
|
+
attr :id
|
40
|
+
|
41
|
+
# Generate a JavaScript string which forwards the specified event to the server.
|
42
|
+
# @parameter details [Hash] The details associated with the forwarded event.
|
43
|
+
def forward(details = nil)
|
44
|
+
if details
|
45
|
+
"live.forward(#{JSON.dump(@id)}, event, #{JSON.dump(details)})"
|
46
|
+
else
|
47
|
+
"live.forward(#{JSON.dump(@id)}, event)"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# Bind this tag to a dynamically updating page.
|
52
|
+
# @parameter page [Live::Page]
|
53
|
+
def bind(page)
|
54
|
+
@page = page
|
55
|
+
end
|
56
|
+
|
57
|
+
def close
|
58
|
+
@page = nil
|
59
|
+
end
|
60
|
+
|
61
|
+
# Handle a client event, typically as triggered by {#forward}.
|
62
|
+
# @parameter event [String] The type of the event.
|
63
|
+
def handle(event)
|
64
|
+
end
|
65
|
+
|
66
|
+
# Enqueue a remote procedure call to the currently bound page.
|
67
|
+
# @parameter method [Symbol] The name of the remote functio to invoke.
|
68
|
+
# @parameter arguments [Array]
|
69
|
+
def rpc(method, arguments)
|
70
|
+
# This update might not be sent right away. Therefore, mutable arguments may be serialized to JSON at a later time (or never). This could be a race condition:
|
71
|
+
@page.updates.enqueue([method, arguments])
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
data/lib/live/page.rb
ADDED
@@ -0,0 +1,112 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright, 2021, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
4
|
+
#
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
# of this software and associated documentation files (the "Software"), to deal
|
7
|
+
# in the Software without restriction, including without limitation the rights
|
8
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
# copies of the Software, and to permit persons to whom the Software is
|
10
|
+
# furnished to do so, subject to the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be included in
|
13
|
+
# all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
# THE SOFTWARE.
|
22
|
+
|
23
|
+
require_relative 'element'
|
24
|
+
require_relative 'resolver'
|
25
|
+
|
26
|
+
require 'async'
|
27
|
+
require 'async/queue'
|
28
|
+
|
29
|
+
module Live
|
30
|
+
# Represents a connected client page with bound dynamic content areas.
|
31
|
+
class Page
|
32
|
+
# @parameter resolver [Live::Resolver] Used to resolve client-side elements to server-side element instances.
|
33
|
+
def initialize(resolver)
|
34
|
+
@resolver = resolver
|
35
|
+
|
36
|
+
@elements = {}
|
37
|
+
@updates = Async::Queue.new
|
38
|
+
end
|
39
|
+
|
40
|
+
# The queue of outstanding events to be sent to the client.
|
41
|
+
attr :updates
|
42
|
+
|
43
|
+
# Bind a client-side element to a server side element.
|
44
|
+
# @parameter element [Live::Element] The element to bind.
|
45
|
+
def bind(element)
|
46
|
+
@elements[element.id] = element
|
47
|
+
|
48
|
+
element.bind(self)
|
49
|
+
end
|
50
|
+
|
51
|
+
# Resolve a client-side element to a server side instance.
|
52
|
+
# @parameter id [String] The unique identifier within the page.
|
53
|
+
# @parameter data [Hash] The data associated with the element, typically stored as `data-` attributes.
|
54
|
+
def resolve(id, data)
|
55
|
+
@resolver.call(id, data)
|
56
|
+
end
|
57
|
+
|
58
|
+
# Handle an event from the client. If the element could not be found, it is silently ignored.
|
59
|
+
# @parameter id [String] The unique identifier of the element which forwarded the event.
|
60
|
+
# @parameter event [String] The type of the event.
|
61
|
+
# @parameter details [Hash] The associated details if any.
|
62
|
+
# @returns [Object] The result of the element handler, if the element was found.
|
63
|
+
# @returns [Nil] If the element could not be found.
|
64
|
+
def handle(id, event)
|
65
|
+
if element = @elements[id]
|
66
|
+
return element.handle(event)
|
67
|
+
else
|
68
|
+
Console.logger.warn(self, "Could not handle event:", event, details)
|
69
|
+
end
|
70
|
+
|
71
|
+
return nil
|
72
|
+
end
|
73
|
+
|
74
|
+
def close
|
75
|
+
@elements.each do |id, element|
|
76
|
+
element.close
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
# Run the event handling loop with the given websocket connection.
|
81
|
+
# @parameter connection [Async::WebSocket::Connection]
|
82
|
+
def run(connection)
|
83
|
+
queue_task = Async do
|
84
|
+
while update = @updates.dequeue
|
85
|
+
Console.logger.debug(self, "Sending update:", update)
|
86
|
+
|
87
|
+
connection.write(update)
|
88
|
+
connection.flush if @updates.empty?
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
while message = connection.read
|
93
|
+
Console.logger.debug(self, "Reading message:", message)
|
94
|
+
|
95
|
+
if id = message[:bind] and data = message[:data]
|
96
|
+
if element = self.resolve(id, data)
|
97
|
+
self.bind(element)
|
98
|
+
else
|
99
|
+
Console.logger.warn(self, "Could not resolve element:", message)
|
100
|
+
end
|
101
|
+
elsif id = message[:id]
|
102
|
+
self.handle(id, message[:event])
|
103
|
+
else
|
104
|
+
Console.logger.warn(self, "Unhandled message:", message)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
ensure
|
108
|
+
self.close
|
109
|
+
queue_task&.stop
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright, 2021, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
4
|
+
#
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
# of this software and associated documentation files (the "Software"), to deal
|
7
|
+
# in the Software without restriction, including without limitation the rights
|
8
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
# copies of the Software, and to permit persons to whom the Software is
|
10
|
+
# furnished to do so, subject to the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be included in
|
13
|
+
# all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
# THE SOFTWARE.
|
22
|
+
|
23
|
+
require_relative 'element'
|
24
|
+
|
25
|
+
module Live
|
26
|
+
# Resolves a client-side tag into a server-side instance.
|
27
|
+
class Resolver
|
28
|
+
# Creates an instance of the resolver, allowing the specified classes to be resolved.
|
29
|
+
def self.allow(*arguments)
|
30
|
+
self.new.allow(*arguments).freeze
|
31
|
+
end
|
32
|
+
|
33
|
+
def initialize
|
34
|
+
@allowed = {}
|
35
|
+
end
|
36
|
+
|
37
|
+
# @attribute [Hash(String, Class)] A map of allowed class names.
|
38
|
+
attr :allowed
|
39
|
+
|
40
|
+
def freeze
|
41
|
+
return self unless frozen?
|
42
|
+
|
43
|
+
@allowed.freeze
|
44
|
+
|
45
|
+
super
|
46
|
+
end
|
47
|
+
|
48
|
+
# Allow the specified classes to be resolved.
|
49
|
+
def allow(*arguments)
|
50
|
+
arguments.each do |klass|
|
51
|
+
@allowed[klass.name] = klass
|
52
|
+
end
|
53
|
+
|
54
|
+
return self
|
55
|
+
end
|
56
|
+
|
57
|
+
# Resolve a tag.
|
58
|
+
# @parameter id [String] The unique identifier for the tag.
|
59
|
+
# @parameter data [Hash] The data associated with the tag. Should include the `:class` key.
|
60
|
+
# @returns [Element] The element instance if it was allowed.
|
61
|
+
def call(id, data)
|
62
|
+
if klass = @allowed[data[:class]]
|
63
|
+
return klass.new(id, **data)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
data/lib/live/version.rb
CHANGED
data/lib/live/view.rb
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright, 2021, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
4
|
+
#
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
# of this software and associated documentation files (the "Software"), to deal
|
7
|
+
# in the Software without restriction, including without limitation the rights
|
8
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
# copies of the Software, and to permit persons to whom the Software is
|
10
|
+
# furnished to do so, subject to the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be included in
|
13
|
+
# all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
# THE SOFTWARE.
|
22
|
+
|
23
|
+
require_relative 'element'
|
24
|
+
require 'trenni/builder'
|
25
|
+
|
26
|
+
module Live
|
27
|
+
# Represents a single division of content on the page an provides helpers for rendering the content.
|
28
|
+
class View < Element
|
29
|
+
# Replace the content of the client-side element by rendering this view.
|
30
|
+
def replace!
|
31
|
+
rpc(:replace, [@id, self.to_html])
|
32
|
+
end
|
33
|
+
|
34
|
+
# Append to the content of the client-side element by appending the specified element.
|
35
|
+
# @parameter node [Live::Element] The element to append.
|
36
|
+
def append!(element)
|
37
|
+
rpc(:append, [@id, element.to_html])
|
38
|
+
end
|
39
|
+
|
40
|
+
# Prepend to the content of the client-side element by appending the specified element.
|
41
|
+
# @parameter node [Live::Element] The element to prepend.
|
42
|
+
def prepend!(element)
|
43
|
+
rpc(:prepend, [@id, element.to_html])
|
44
|
+
end
|
45
|
+
|
46
|
+
# Render the element.
|
47
|
+
# @parameter builder [Trenni::Builder] The HTML builder.
|
48
|
+
def render(builder)
|
49
|
+
end
|
50
|
+
|
51
|
+
# @returns [Object] The generated HTML.
|
52
|
+
def to_html
|
53
|
+
Trenni::Builder.fragment do |builder|
|
54
|
+
builder.tag :div, id: @id, class: 'live', data: @data do
|
55
|
+
render(builder)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
metadata
CHANGED
@@ -1,88 +1,132 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: live
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
segments:
|
6
|
-
- 0
|
7
|
-
- 1
|
8
|
-
- 0
|
9
|
-
version: 0.1.0
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.4.0
|
10
5
|
platform: ruby
|
11
|
-
authors:
|
12
|
-
-
|
13
|
-
autorequire:
|
6
|
+
authors:
|
7
|
+
- Samuel Williams
|
8
|
+
autorequire:
|
14
9
|
bindir: bin
|
15
10
|
cert_chain: []
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
11
|
+
date: 2021-06-07 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: trenni
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
22
21
|
prerelease: false
|
23
|
-
|
24
|
-
|
25
|
-
requirements:
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
26
24
|
- - ">="
|
27
|
-
- !ruby/object:Gem::Version
|
28
|
-
|
29
|
-
|
30
|
-
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: async-websocket
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
31
34
|
type: :runtime
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
-
|
39
|
-
|
40
|
-
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: async-rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.1'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.1'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: bundler
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: covered
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0.10'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0.10'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rspec
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '3.6'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '3.6'
|
97
|
+
description:
|
98
|
+
email:
|
99
|
+
executables: []
|
41
100
|
extensions: []
|
42
|
-
|
43
101
|
extra_rdoc_files: []
|
44
|
-
|
45
|
-
files:
|
46
|
-
- .gitignore
|
47
|
-
- Gemfile
|
48
|
-
- README.rdoc
|
49
|
-
- Rakefile
|
50
|
-
- bin/live
|
51
|
-
- lib/ext/object.rb
|
102
|
+
files:
|
52
103
|
- lib/live.rb
|
104
|
+
- lib/live/element.rb
|
105
|
+
- lib/live/page.rb
|
106
|
+
- lib/live/resolver.rb
|
53
107
|
- lib/live/version.rb
|
54
|
-
- live.
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
post_install_message:
|
108
|
+
- lib/live/view.rb
|
109
|
+
homepage: https://github.com/socketry/live
|
110
|
+
licenses:
|
111
|
+
- MIT
|
112
|
+
metadata: {}
|
113
|
+
post_install_message:
|
60
114
|
rdoc_options: []
|
61
|
-
|
62
|
-
require_paths:
|
115
|
+
require_paths:
|
63
116
|
- lib
|
64
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
65
|
-
|
66
|
-
requirements:
|
117
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
118
|
+
requirements:
|
67
119
|
- - ">="
|
68
|
-
- !ruby/object:Gem::Version
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
73
|
-
none: false
|
74
|
-
requirements:
|
120
|
+
- !ruby/object:Gem::Version
|
121
|
+
version: 2.5.0
|
122
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
123
|
+
requirements:
|
75
124
|
- - ">="
|
76
|
-
- !ruby/object:Gem::Version
|
77
|
-
|
78
|
-
- 0
|
79
|
-
version: "0"
|
125
|
+
- !ruby/object:Gem::Version
|
126
|
+
version: '0'
|
80
127
|
requirements: []
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
specification_version: 3
|
86
|
-
summary: Live is like IRC only it is meant to be used from a text editor
|
128
|
+
rubygems_version: 3.2.15
|
129
|
+
signing_key:
|
130
|
+
specification_version: 4
|
131
|
+
summary: Live HTML tags updated via a WebSocket.
|
87
132
|
test_files: []
|
88
|
-
|
data/Gemfile
DELETED
data/README.rdoc
DELETED
@@ -1,36 +0,0 @@
|
|
1
|
-
Live
|
2
|
-
====
|
3
|
-
|
4
|
-
Live is like IRC only it is meant to be used from a text editor, it essentially polls a *nix pipe and evaluates its contents.
|
5
|
-
It was devised for audiovisual livecoding (ruby-processing and scruby), a block can be bound to a key and can be called later by a keystroke.
|
6
|
-
|
7
|
-
Usage
|
8
|
-
-----
|
9
|
-
|
10
|
-
$ live
|
11
|
-
|
12
|
-
open a new terminal
|
13
|
-
|
14
|
-
$ echo 'hello' > /tmp/live-rb
|
15
|
-
|
16
|
-
You will see the code evaluated in the first terminal
|
17
|
-
|
18
|
-
$ echo 'bind_key(:a){ 'key a was pressed' }' > /tmp/live-rb
|
19
|
-
|
20
|
-
When you press the key 'a' with focus on the first terminal it will call the block
|
21
|
-
|
22
|
-
Vim
|
23
|
-
---
|
24
|
-
|
25
|
-
To use from vim paste this in your .vimrc file
|
26
|
-
|
27
|
-
function EvalLiveRuby() range
|
28
|
-
let text = [join(getline(a:firstline, a:lastline), ';')]
|
29
|
-
return writefile(text, '/tmp/live-rb')
|
30
|
-
endfunction
|
31
|
-
|
32
|
-
map <Leader>x :call EvalLiveRuby()<enter>
|
33
|
-
|
34
|
-
Then by pressing leader and x you will execute the file or range in the live session
|
35
|
-
|
36
|
-
|
data/Rakefile
DELETED
data/bin/live
DELETED
data/lib/ext/object.rb
DELETED
@@ -1,21 +0,0 @@
|
|
1
|
-
class Object
|
2
|
-
# Outputs an ANSI colored string with the object representation
|
3
|
-
def colored_inspect
|
4
|
-
case self
|
5
|
-
when Exception
|
6
|
-
"\e[41;33m#{self.inspect}\e[0m"
|
7
|
-
when Numeric, Symbol, TrueClass, FalseClass, NilClass
|
8
|
-
"\e[35m#{self.inspect}\e[0m"
|
9
|
-
when Live::Notice
|
10
|
-
"\e[42;30m#{self}\e[0m"
|
11
|
-
when String
|
12
|
-
"\e[32m#{self.inspect}\e[0m"
|
13
|
-
when Array
|
14
|
-
"[#{ self.collect{ |i| i.colored_inspect}.join(', ') }]"
|
15
|
-
when Hash
|
16
|
-
"{#{ self.collect{ |i| i.collect{|e| e.colored_inspect}.join(' => ') }.join(', ') }}"
|
17
|
-
else
|
18
|
-
"\e[36m#{self}\e[0m"
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
data/live.gemspec
DELETED
@@ -1,24 +0,0 @@
|
|
1
|
-
# -*- encoding: utf-8 -*-
|
2
|
-
$:.push File.expand_path("../lib", __FILE__)
|
3
|
-
require "live/version"
|
4
|
-
|
5
|
-
Gem::Specification.new do |s|
|
6
|
-
s.name = "live"
|
7
|
-
s.version = Live::VERSION
|
8
|
-
s.platform = Gem::Platform::RUBY
|
9
|
-
s.authors = ["Macario Ortega"]
|
10
|
-
s.email = ["macarui@gmail.com"]
|
11
|
-
s.homepage = ""
|
12
|
-
s.summary = %q{Live is like IRC only it is meant to be used from a text editor}
|
13
|
-
s.description = %q{Live is like IRC only it is meant to be used from a text editor, it essentially polls a *nix pipe and evaluates its contents.
|
14
|
-
It was devised for audiovisual livecoding (ruby-processing and scruby), a block can be bound to a key and can be called later by a keystroke.
|
15
|
-
}
|
16
|
-
|
17
|
-
s.add_dependency 'highline'
|
18
|
-
|
19
|
-
s.rubyforge_project = "live"
|
20
|
-
s.files = `git ls-files`.split("\n")
|
21
|
-
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
22
|
-
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
23
|
-
s.require_paths = ["lib"]
|
24
|
-
end
|