async-debug 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (92) hide show
  1. checksums.yaml +7 -0
  2. data/lib/async/debug.rb +90 -0
  3. data/lib/async/debug/reactor_view.rb +101 -0
  4. data/lib/async/debug/version.rb +27 -0
  5. data/pages/_heading.xnode +2 -0
  6. data/pages/_page.xnode +42 -0
  7. data/pages/controller.rb +21 -0
  8. data/pages/errors/exception.xnode +5 -0
  9. data/pages/errors/file-not-found.xnode +5 -0
  10. data/pages/index.xnode +3 -0
  11. data/pages/links.yaml +4 -0
  12. data/public/_components/@socketry/live/live.js +157 -0
  13. data/public/_components/@socketry/live/live.min.js +1 -0
  14. data/public/_components/jquery-syntax/base/jquery.syntax.brush.apache.css +12 -0
  15. data/public/_components/jquery-syntax/base/jquery.syntax.brush.applescript.css +5 -0
  16. data/public/_components/jquery-syntax/base/jquery.syntax.brush.assembly.css +8 -0
  17. data/public/_components/jquery-syntax/base/jquery.syntax.brush.bash-script.css +4 -0
  18. data/public/_components/jquery-syntax/base/jquery.syntax.brush.bash.css +2 -0
  19. data/public/_components/jquery-syntax/base/jquery.syntax.brush.clang.css +6 -0
  20. data/public/_components/jquery-syntax/base/jquery.syntax.brush.css.css +14 -0
  21. data/public/_components/jquery-syntax/base/jquery.syntax.brush.diff.css +16 -0
  22. data/public/_components/jquery-syntax/base/jquery.syntax.brush.html.css +5 -0
  23. data/public/_components/jquery-syntax/base/jquery.syntax.brush.ocaml.css +3 -0
  24. data/public/_components/jquery-syntax/base/jquery.syntax.brush.protobuf.css +2 -0
  25. data/public/_components/jquery-syntax/base/jquery.syntax.brush.python.css +6 -0
  26. data/public/_components/jquery-syntax/base/jquery.syntax.brush.ruby.css +2 -0
  27. data/public/_components/jquery-syntax/base/jquery.syntax.brush.xml.css +35 -0
  28. data/public/_components/jquery-syntax/base/jquery.syntax.core.css +58 -0
  29. data/public/_components/jquery-syntax/base/jquery.syntax.editor.css +6 -0
  30. data/public/_components/jquery-syntax/base/theme.js +1 -0
  31. data/public/_components/jquery-syntax/bright/jquery.syntax.core.css +27 -0
  32. data/public/_components/jquery-syntax/bright/theme.js +1 -0
  33. data/public/_components/jquery-syntax/jquery.syntax.brush.apache.js +3 -0
  34. data/public/_components/jquery-syntax/jquery.syntax.brush.applescript.js +5 -0
  35. data/public/_components/jquery-syntax/jquery.syntax.brush.assembly.js +3 -0
  36. data/public/_components/jquery-syntax/jquery.syntax.brush.bash-script.js +4 -0
  37. data/public/_components/jquery-syntax/jquery.syntax.brush.bash.js +2 -0
  38. data/public/_components/jquery-syntax/jquery.syntax.brush.basic.js +5 -0
  39. data/public/_components/jquery-syntax/jquery.syntax.brush.clang.js +5 -0
  40. data/public/_components/jquery-syntax/jquery.syntax.brush.csharp.js +4 -0
  41. data/public/_components/jquery-syntax/jquery.syntax.brush.css.js +5 -0
  42. data/public/_components/jquery-syntax/jquery.syntax.brush.diff.js +2 -0
  43. data/public/_components/jquery-syntax/jquery.syntax.brush.go.js +3 -0
  44. data/public/_components/jquery-syntax/jquery.syntax.brush.haskell.js +3 -0
  45. data/public/_components/jquery-syntax/jquery.syntax.brush.html.js +4 -0
  46. data/public/_components/jquery-syntax/jquery.syntax.brush.io.js +3 -0
  47. data/public/_components/jquery-syntax/jquery.syntax.brush.java.js +4 -0
  48. data/public/_components/jquery-syntax/jquery.syntax.brush.javascript.js +3 -0
  49. data/public/_components/jquery-syntax/jquery.syntax.brush.kai.js +2 -0
  50. data/public/_components/jquery-syntax/jquery.syntax.brush.lisp.js +2 -0
  51. data/public/_components/jquery-syntax/jquery.syntax.brush.lua.js +3 -0
  52. data/public/_components/jquery-syntax/jquery.syntax.brush.nginx.js +2 -0
  53. data/public/_components/jquery-syntax/jquery.syntax.brush.ocaml.js +4 -0
  54. data/public/_components/jquery-syntax/jquery.syntax.brush.ooc.js +4 -0
  55. data/public/_components/jquery-syntax/jquery.syntax.brush.pascal.js +4 -0
  56. data/public/_components/jquery-syntax/jquery.syntax.brush.perl5.js +3 -0
  57. data/public/_components/jquery-syntax/jquery.syntax.brush.php-script.js +4 -0
  58. data/public/_components/jquery-syntax/jquery.syntax.brush.php.js +2 -0
  59. data/public/_components/jquery-syntax/jquery.syntax.brush.plain.js +2 -0
  60. data/public/_components/jquery-syntax/jquery.syntax.brush.protobuf.js +3 -0
  61. data/public/_components/jquery-syntax/jquery.syntax.brush.python.js +5 -0
  62. data/public/_components/jquery-syntax/jquery.syntax.brush.ruby.js +5 -0
  63. data/public/_components/jquery-syntax/jquery.syntax.brush.scala.js +4 -0
  64. data/public/_components/jquery-syntax/jquery.syntax.brush.smalltalk.js +2 -0
  65. data/public/_components/jquery-syntax/jquery.syntax.brush.sql.js +4 -0
  66. data/public/_components/jquery-syntax/jquery.syntax.brush.super-collider.js +3 -0
  67. data/public/_components/jquery-syntax/jquery.syntax.brush.swift.js +3 -0
  68. data/public/_components/jquery-syntax/jquery.syntax.brush.trenni.js +2 -0
  69. data/public/_components/jquery-syntax/jquery.syntax.brush.xml.js +4 -0
  70. data/public/_components/jquery-syntax/jquery.syntax.brush.yaml.js +2 -0
  71. data/public/_components/jquery-syntax/jquery.syntax.cache.js +7 -0
  72. data/public/_components/jquery-syntax/jquery.syntax.core.js +34 -0
  73. data/public/_components/jquery-syntax/jquery.syntax.editor.js +11 -0
  74. data/public/_components/jquery-syntax/jquery.syntax.js +8 -0
  75. data/public/_components/jquery-syntax/jquery.syntax.min.js +13 -0
  76. data/public/_components/jquery-syntax/paper/jquery.syntax.core.css +31 -0
  77. data/public/_components/jquery-syntax/paper/theme.js +1 -0
  78. data/public/_components/jquery/jquery.js +10872 -0
  79. data/public/_components/jquery/jquery.min.js +2 -0
  80. data/public/_components/jquery/jquery.min.map +1 -0
  81. data/public/_components/jquery/jquery.slim.js +8777 -0
  82. data/public/_components/jquery/jquery.slim.min.js +2 -0
  83. data/public/_components/jquery/jquery.slim.min.map +1 -0
  84. data/public/_components/morphdom/morphdom-esm.js +755 -0
  85. data/public/_components/morphdom/morphdom-factory.js +691 -0
  86. data/public/_components/morphdom/morphdom-umd.js +763 -0
  87. data/public/_components/morphdom/morphdom-umd.min.js +1 -0
  88. data/public/_components/morphdom/morphdom.js +757 -0
  89. data/public/_static/icon.png +0 -0
  90. data/public/_static/links.js +21 -0
  91. data/public/_static/site.css +332 -0
  92. metadata +244 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 7e6c031c862d32fc655259441e30c747221067b52216a547c050b177c12325c0
4
+ data.tar.gz: 12b3dde7ba214e9c8422a81f5c4d029d5c6132648e02f34d3d6a8326c9d921de
5
+ SHA512:
6
+ metadata.gz: 22e3d9c1719e58ccc1eb9e07c663e2bf376b933f7214abea83d32cf4a08be9de60888073b6dd14575ac84ca174c8ea002cafeec4cd58ccef42d9390155faa94d
7
+ data.tar.gz: 858ef197a2e6ddf3395cf5f37de67a01ef17d290440d2b88ebd50bb55a31b31782a74689e41653ebfe360d0f41005b5c1ba7e9d5288ebe18381390bf512152d5
@@ -0,0 +1,90 @@
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 "debug/version"
24
+
25
+ require 'utopia/localization'
26
+ require 'falcon/endpoint'
27
+ require 'falcon/server'
28
+ require 'utopia/setup'
29
+
30
+ module Async
31
+ module Debug
32
+ # Start the debugger.
33
+ #
34
+ # @parameter endpoint [Async::IO::Endpoint] The endpoint to bind to. Defaults to <https://localhost:9090>.
35
+ def self.serve(endpoint: nil)
36
+ endpoint ||= Falcon::Endpoint.parse("https://localhost:9090")
37
+ builder = Rack::Builder.new
38
+ self.call(builder)
39
+ app = builder.to_app
40
+ middleware = Falcon::Server.middleware(app)
41
+
42
+ Async(transient: true, annotation: self) do
43
+ Console.logger.info(self, "Live debugger binding to #{endpoint}...")
44
+ Async::HTTP::Server.new(middleware, endpoint).run
45
+ end
46
+ end
47
+
48
+ # The root directory of the web application files.
49
+ SITE_ROOT = File.expand_path("../..", __dir__)
50
+
51
+ # The root directory for the utopia middleware.
52
+ PAGES_ROOT = File.expand_path("pages", SITE_ROOT)
53
+
54
+ # The root directory for static assets.
55
+ PUBLIC_ROOT = File.expand_path("public", SITE_ROOT)
56
+
57
+ # Appends a project application to the rack builder.
58
+ #
59
+ # @parameter builder [Rack::Builder]
60
+ # @parameter root [String] The file-system root path of the project/gem.
61
+ # @parameter locales [Array(String)] an array of locales to support, e.g. `['en', 'ja']`.
62
+ def self.call(builder, root = Dir.pwd, locales: nil, utopia: Utopia.setup)
63
+ # We want to propate exceptions up when running tests:
64
+ builder.use Rack::ShowExceptions
65
+
66
+ builder.use Utopia::Static, root: PUBLIC_ROOT
67
+
68
+ builder.use Utopia::Redirection::Rewrite, {
69
+ '/' => '/index'
70
+ }
71
+
72
+ builder.use Utopia::Redirection::DirectoryIndex
73
+
74
+ builder.use Utopia::Redirection::Errors, {
75
+ 404 => '/errors/file-not-found'
76
+ }
77
+
78
+ if locales
79
+ builder.use Utopia::Localization,
80
+ default_locale: locales.first,
81
+ locales: locales
82
+ end
83
+
84
+ builder.use Utopia::Controller, root: PAGES_ROOT
85
+ builder.use Utopia::Content, root: PAGES_ROOT
86
+
87
+ builder.run lambda { |env| [404, {}, []] }
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,101 @@
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 'live'
24
+
25
+ module Async
26
+ module Debug
27
+ class ReactorView < Live::View
28
+ def initialize(id, **data)
29
+ super
30
+
31
+ @update = nil
32
+ @top = Async::Task.current.reactor
33
+ end
34
+
35
+ def bind(page)
36
+ super(page)
37
+
38
+ @update = Async do |task|
39
+ while true
40
+ task.sleep(1.0/10.0)
41
+ self.replace!
42
+ end
43
+ end
44
+ end
45
+
46
+ def close
47
+ @update.stop
48
+
49
+ super
50
+ end
51
+
52
+ def handle(event, details)
53
+ replace!
54
+ end
55
+
56
+ def render_node(builder, node = @top)
57
+ klass = []
58
+ title = []
59
+
60
+ if node.respond_to?(:status)
61
+ klass << node.status
62
+ end
63
+
64
+ if node.transient?
65
+ klass << "transient"
66
+ end
67
+
68
+ if node.respond_to?(:backtrace)
69
+ if backtrace = node.backtrace
70
+ title = backtrace.first(8)
71
+ end
72
+ end
73
+
74
+ builder.inline :span, class: klass.join(' '), title: title.join("\n") do
75
+ text = node.annotation || "#{node.class} 0x#{node.object_id.to_s(16)}"
76
+ builder.text(text)
77
+ end
78
+
79
+ if node.children
80
+ builder.tag :ul do
81
+ node.children.each do |child|
82
+ builder.inline :li do
83
+ render_node(builder, child)
84
+ end
85
+ end
86
+ end
87
+ end
88
+ end
89
+
90
+ def render(builder)
91
+ builder.tag :div, class: 'tree' do
92
+ builder.tag :ul do
93
+ builder.inline :li do
94
+ render_node(builder)
95
+ end
96
+ end
97
+ end
98
+ end
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,27 @@
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
+ module Async
24
+ module Debug
25
+ VERSION = "0.1.0"
26
+ end
27
+ end
@@ -0,0 +1,2 @@
1
+ <?r document.attributes[:title] ||= content ?>
2
+ <h1><utopia:content/></h1>
data/pages/_page.xnode ADDED
@@ -0,0 +1,42 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <?r response.cache! ?>
5
+
6
+ <?r if title = self[:title] ?>
7
+ <title>#{title.gsub(/<.*?>/, "")}</title>
8
+ <?r else ?>
9
+ <title>Async Debug</title>
10
+ <?r end ?>
11
+
12
+ <meta charset="UTF-8" />
13
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
14
+
15
+ <link rel="icon" type="image/png" href="/_static/icon.png" />
16
+ <link rel="stylesheet" href="/_static/site.css" type="text/css" media="screen" />
17
+
18
+ <script src="/_components/jquery/jquery.min.js"></script>
19
+ <script src="/_components/jquery-syntax/jquery.syntax.min.js"></script>
20
+
21
+ <script src="/_static/links.js"></script>
22
+
23
+ <script src="/_components/morphdom/morphdom-umd.js"></script>
24
+ <script src="/_components/@socketry/live/live.js"></script>
25
+
26
+ <script type="text/javascript">
27
+ //<![CDATA[
28
+ jQuery(function($) {
29
+ $.syntax();
30
+ });
31
+ //]]>
32
+ </script>
33
+ </head>
34
+
35
+ <body>
36
+ <content:header />
37
+
38
+ <main>
39
+ <utopia:content/>
40
+ </main>
41
+ </body>
42
+ </html>
@@ -0,0 +1,21 @@
1
+
2
+ require 'async/websocket/adapters/rack'
3
+ require_relative '../lib/async/debug/reactor_view'
4
+
5
+ prepend Actions
6
+
7
+ RESOLVER = Live::Resolver.allow(Async::Debug::ReactorView)
8
+
9
+ on 'live' do |request|
10
+ Console.logger.info("Incoming live connection...")
11
+
12
+ adapter = Async::WebSocket::Adapters::Rack.open(request.env) do |connection|
13
+ Live::Page.new(RESOLVER).run(connection)
14
+ end
15
+
16
+ respond?(adapter) or fail!
17
+ end
18
+
19
+ on 'index' do
20
+ @tag = Async::Debug::ReactorView.new('reactor-view')
21
+ end
@@ -0,0 +1,5 @@
1
+ <content:page>
2
+ <content:heading>Exception</content:heading>
3
+
4
+ <p>It seems like something didn't quite work out as expected!</p>
5
+ </content:page>
@@ -0,0 +1,5 @@
1
+ <content:page>
2
+ <content:heading>File Not Found</content:heading>
3
+
4
+ <p>The file you requested is unfortunately not available at this time!</p>
5
+ </content:page>
data/pages/index.xnode ADDED
@@ -0,0 +1,3 @@
1
+ <content:page title="Reactor Overview">
2
+ #{attributes[:tag].to_html}
3
+ </content:page>
data/pages/links.yaml ADDED
@@ -0,0 +1,4 @@
1
+ index:
2
+ title: Async Debug
3
+ errors:
4
+ display: false
@@ -0,0 +1,157 @@
1
+ var live = (function () {
2
+ 'use strict';
3
+
4
+ class Live {
5
+ constructor(document, url) {
6
+ this.document = document;
7
+
8
+ this.url = url;
9
+ this.events = [];
10
+
11
+ this.failures = 0;
12
+
13
+ // Track visibility state and connect if required:
14
+ this.document.addEventListener("visibilitychange", () => this.handleVisibilityChange());
15
+ this.handleVisibilityChange();
16
+ }
17
+
18
+ connect() {
19
+ if (this.server) return;
20
+
21
+ let server = this.server = new WebSocket(this.url.href);
22
+
23
+ server.onopen = () => {
24
+ this.failures = 0;
25
+ this.attach();
26
+ };
27
+
28
+ server.onmessage = (message) => {
29
+ const [name, _arguments] = JSON.parse(message.data);
30
+
31
+ this[name](..._arguments);
32
+ };
33
+
34
+ server.onerror = () => {
35
+ this.failures += 1;
36
+ };
37
+
38
+ // The remote end has disconnected:
39
+ server.onclose = () => {
40
+ this.server = null;
41
+
42
+ // We need a minimum delay otherwise this can end up immediately invoking the callback:
43
+ let delay = 100 * (this.failures + 1) ** 2;
44
+ setTimeout(() => this.connect(), delay > 60000 ? 60000 : delay);
45
+ };
46
+ }
47
+
48
+ disconnect() {
49
+ if (this.server) {
50
+ this.server.close();
51
+ this.server = null;
52
+ }
53
+ }
54
+
55
+ createDocumentFragment(html) {
56
+ return this.document.createRange().createContextualFragment(html);
57
+ }
58
+
59
+ // These methods are designed for RPC.
60
+ replace(id, html) {
61
+ let element = document.getElementById(id);
62
+
63
+ morphdom(element, html);
64
+ }
65
+
66
+ prepend(id, html) {
67
+ let element = document.getElementById(id);
68
+ let fragment = this.createDocumentFragment(html);
69
+
70
+ element.prepend(fragment);
71
+ }
72
+
73
+ append(id, html) {
74
+ let element = document.getElementById(id);
75
+ let fragment = this.createDocumentFragment(html);
76
+
77
+ element.append(fragment);
78
+ }
79
+
80
+ dispatch(id, type, details) {
81
+ let element = document.getElementById(id);
82
+
83
+ element.dispatchEvent(
84
+ new CustomEvent(type, details)
85
+ );
86
+ }
87
+
88
+ trigger(id, event) {
89
+ this.connect();
90
+
91
+ this.send(
92
+ JSON.stringify({id: id, event: event})
93
+ );
94
+ }
95
+
96
+ forward(id, event, details) {
97
+ this.trigger(id, {type: event.type, details: details});
98
+ }
99
+
100
+ send(message) {
101
+ try {
102
+ this.server.send(message);
103
+ } catch (error) {
104
+ this.events.push(message);
105
+ }
106
+ }
107
+
108
+ flush() {
109
+ if (this.events.length === 0) return;
110
+
111
+ let events = this.events;
112
+ this.events = [];
113
+
114
+ for (var event of events) {
115
+ this.send(event);
116
+ }
117
+ }
118
+
119
+ bind(elements) {
120
+ for (var element of elements) {
121
+ this.send(JSON.stringify({bind: element.id, data: element.dataset}));
122
+ }
123
+ }
124
+
125
+ bindElementsByClassName(selector = 'live') {
126
+ this.bind(
127
+ this.document.getElementsByClassName(selector)
128
+ );
129
+
130
+ this.flush();
131
+ }
132
+
133
+ handleVisibilityChange() {
134
+ if (document.hidden) {
135
+ this.disconnect();
136
+ } else {
137
+ this.connect();
138
+ }
139
+ }
140
+
141
+ attach() {
142
+ if (this.document.readyState === 'loading') {
143
+ this.document.addEventListener('DOMContentLoaded', () => this.bindElementsByClassName());
144
+ } else {
145
+ this.bindElementsByClassName();
146
+ }
147
+ }
148
+ }
149
+
150
+ let url = new URL('live', location.href);
151
+ url.protocol = url.protocol.replace('http', 'ws');
152
+
153
+ let live = new Live(document, url);
154
+
155
+ return live;
156
+
157
+ }());