lively 0.2.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/readme.md ADDED
@@ -0,0 +1,36 @@
1
+ # Lively
2
+
3
+ A high level framework for building live HTML applications with Ruby.
4
+
5
+ [![Development Status](https://github.com/socketry/lively/workflows/Test/badge.svg)](https://github.com/socketry/lively/actions?workflow=Test)
6
+
7
+ ## Features
8
+
9
+ - Simple high level interface for server-side SPAs.
10
+
11
+ ## Usage
12
+
13
+ See the example app in `app/`.
14
+
15
+ ## Contributing
16
+
17
+ We welcome contributions to this project.
18
+
19
+ 1. Fork it.
20
+ 2. Create your feature branch (`git checkout -b my-new-feature`).
21
+ 3. Commit your changes (`git commit -am 'Add some feature'`).
22
+ 4. Push to the branch (`git push origin my-new-feature`).
23
+ 5. Create new Pull Request.
24
+
25
+ ### Developer Certificate of Origin
26
+
27
+ This project uses the [Developer Certificate of Origin](https://developercertificate.org/). All contributors to this project must agree to this document to have their contributions accepted.
28
+
29
+ ### Contributor Covenant
30
+
31
+ This project is governed by the [Contributor Covenant](https://www.contributor-covenant.org/). All contributors and participants agree to abide by its terms.
32
+
33
+ ## See Also
34
+
35
+ - [live](https://github.com/socketry/live) — Provides client-server communication using websockets.
36
+ - [mayu](https://github.com/mayu-live/framework) — A live streaming server-side component-based VirtualDOM rendering framework.
data.tar.gz.sig ADDED
Binary file
metadata CHANGED
@@ -1,29 +1,44 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lively
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Williams
8
8
  autorequire:
9
9
  bindir: bin
10
- cert_chain: []
11
- date: 2022-09-09 00:00:00.000000000 Z
10
+ cert_chain:
11
+ - |
12
+ -----BEGIN CERTIFICATE-----
13
+ MIIE2DCCA0CgAwIBAgIBATANBgkqhkiG9w0BAQsFADBhMRgwFgYDVQQDDA9zYW11
14
+ ZWwud2lsbGlhbXMxHTAbBgoJkiaJk/IsZAEZFg1vcmlvbnRyYW5zZmVyMRIwEAYK
15
+ CZImiZPyLGQBGRYCY28xEjAQBgoJkiaJk/IsZAEZFgJuejAeFw0yMjA4MDYwNDUz
16
+ MjRaFw0zMjA4MDMwNDUzMjRaMGExGDAWBgNVBAMMD3NhbXVlbC53aWxsaWFtczEd
17
+ MBsGCgmSJomT8ixkARkWDW9yaW9udHJhbnNmZXIxEjAQBgoJkiaJk/IsZAEZFgJj
18
+ bzESMBAGCgmSJomT8ixkARkWAm56MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIB
19
+ igKCAYEAomvSopQXQ24+9DBB6I6jxRI2auu3VVb4nOjmmHq7XWM4u3HL+pni63X2
20
+ 9qZdoq9xt7H+RPbwL28LDpDNflYQXoOhoVhQ37Pjn9YDjl8/4/9xa9+NUpl9XDIW
21
+ sGkaOY0eqsQm1pEWkHJr3zn/fxoKPZPfaJOglovdxf7dgsHz67Xgd/ka+Wo1YqoE
22
+ e5AUKRwUuvaUaumAKgPH+4E4oiLXI4T1Ff5Q7xxv6yXvHuYtlMHhYfgNn8iiW8WN
23
+ XibYXPNP7NtieSQqwR/xM6IRSoyXKuS+ZNGDPUUGk8RoiV/xvVN4LrVm9upSc0ss
24
+ RZ6qwOQmXCo/lLcDUxJAgG95cPw//sI00tZan75VgsGzSWAOdjQpFM0l4dxvKwHn
25
+ tUeT3ZsAgt0JnGqNm2Bkz81kG4A2hSyFZTFA8vZGhp+hz+8Q573tAR89y9YJBdYM
26
+ zp0FM4zwMNEUwgfRzv1tEVVUEXmoFCyhzonUUw4nE4CFu/sE3ffhjKcXcY//qiSW
27
+ xm4erY3XAgMBAAGjgZowgZcwCQYDVR0TBAIwADALBgNVHQ8EBAMCBLAwHQYDVR0O
28
+ BBYEFO9t7XWuFf2SKLmuijgqR4sGDlRsMC4GA1UdEQQnMCWBI3NhbXVlbC53aWxs
29
+ aWFtc0BvcmlvbnRyYW5zZmVyLmNvLm56MC4GA1UdEgQnMCWBI3NhbXVlbC53aWxs
30
+ aWFtc0BvcmlvbnRyYW5zZmVyLmNvLm56MA0GCSqGSIb3DQEBCwUAA4IBgQB5sxkE
31
+ cBsSYwK6fYpM+hA5B5yZY2+L0Z+27jF1pWGgbhPH8/FjjBLVn+VFok3CDpRqwXCl
32
+ xCO40JEkKdznNy2avOMra6PFiQyOE74kCtv7P+Fdc+FhgqI5lMon6tt9rNeXmnW/
33
+ c1NaMRdxy999hmRGzUSFjozcCwxpy/LwabxtdXwXgSay4mQ32EDjqR1TixS1+smp
34
+ 8C/NCWgpIfzpHGJsjvmH2wAfKtTTqB9CVKLCWEnCHyCaRVuKkrKjqhYCdmMBqCws
35
+ JkxfQWC+jBVeG9ZtPhQgZpfhvh+6hMhraUYRQ6XGyvBqEUe+yo6DKIT3MtGE2+CP
36
+ eX9i9ZWBydWb8/rvmwmX2kkcBbX0hZS1rcR593hGc61JR6lvkGYQ2MYskBveyaxt
37
+ Q2K9NVun/S785AP05vKkXZEFYxqG6EW012U4oLcFl5MySFajYXRYbuUpH6AY+HP8
38
+ voD0MPg1DssDLKwXyt1eKD/+Fq0bFWhwVM/1XiAXL7lyYUyOq24KHgQ2Csg=
39
+ -----END CERTIFICATE-----
40
+ date: 2024-05-05 00:00:00.000000000 Z
12
41
  dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: async-io
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - ">="
18
- - !ruby/object:Gem::Version
19
- version: '0'
20
- type: :runtime
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - ">="
25
- - !ruby/object:Gem::Version
26
- version: '0'
27
42
  - !ruby/object:Gem::Dependency
28
43
  name: falcon
29
44
  requirement: !ruby/object:Gem::Requirement
@@ -44,70 +59,28 @@ dependencies:
44
59
  requirements:
45
60
  - - "~>"
46
61
  - !ruby/object:Gem::Version
47
- version: 0.5.0
62
+ version: 0.7.0
48
63
  type: :runtime
49
64
  prerelease: false
50
65
  version_requirements: !ruby/object:Gem::Requirement
51
66
  requirements:
52
67
  - - "~>"
53
68
  - !ruby/object:Gem::Version
54
- version: 0.5.0
55
- - !ruby/object:Gem::Dependency
56
- name: async-rspec
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - "~>"
60
- - !ruby/object:Gem::Version
61
- version: '1.1'
62
- type: :development
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - "~>"
67
- - !ruby/object:Gem::Version
68
- version: '1.1'
69
+ version: 0.7.0
69
70
  - !ruby/object:Gem::Dependency
70
- name: bundler
71
+ name: xrb
71
72
  requirement: !ruby/object:Gem::Requirement
72
73
  requirements:
73
74
  - - ">="
74
75
  - !ruby/object:Gem::Version
75
76
  version: '0'
76
- type: :development
77
+ type: :runtime
77
78
  prerelease: false
78
79
  version_requirements: !ruby/object:Gem::Requirement
79
80
  requirements:
80
81
  - - ">="
81
82
  - !ruby/object:Gem::Version
82
83
  version: '0'
83
- - !ruby/object:Gem::Dependency
84
- name: covered
85
- requirement: !ruby/object:Gem::Requirement
86
- requirements:
87
- - - "~>"
88
- - !ruby/object:Gem::Version
89
- version: '0.10'
90
- type: :development
91
- prerelease: false
92
- version_requirements: !ruby/object:Gem::Requirement
93
- requirements:
94
- - - "~>"
95
- - !ruby/object:Gem::Version
96
- version: '0.10'
97
- - !ruby/object:Gem::Dependency
98
- name: rspec
99
- requirement: !ruby/object:Gem::Requirement
100
- requirements:
101
- - - "~>"
102
- - !ruby/object:Gem::Version
103
- version: '3.6'
104
- type: :development
105
- prerelease: false
106
- version_requirements: !ruby/object:Gem::Requirement
107
- requirements:
108
- - - "~>"
109
- - !ruby/object:Gem::Version
110
- version: '3.6'
111
84
  description:
112
85
  email:
113
86
  executables: []
@@ -117,12 +90,15 @@ files:
117
90
  - lib/lively.rb
118
91
  - lib/lively/application.rb
119
92
  - lib/lively/assets.rb
120
- - lib/lively/environments/application.rb
93
+ - lib/lively/environment/application.rb
121
94
  - lib/lively/pages/index.rb
122
- - lib/lively/pages/index.trenni
95
+ - lib/lively/pages/index.xrb
123
96
  - lib/lively/version.rb
124
- - public/_components/@socketry/live/live.js
125
- - public/_components/@socketry/live/live.min.js
97
+ - license.md
98
+ - public/_components/@socketry/live/Live.js
99
+ - public/_components/@socketry/live/package.json
100
+ - public/_components/@socketry/live/readme.md
101
+ - public/_components/@socketry/live/test/Live.js
126
102
  - public/_components/morphdom/morphdom-esm.js
127
103
  - public/_components/morphdom/morphdom-factory.js
128
104
  - public/_components/morphdom/morphdom-umd.js
@@ -131,10 +107,13 @@ files:
131
107
  - public/_static/icon.png
132
108
  - public/_static/index.css
133
109
  - public/_static/site.css
110
+ - readme.md
134
111
  homepage: https://github.com/socketry/lively
135
112
  licenses:
136
113
  - MIT
137
- metadata: {}
114
+ metadata:
115
+ documentation_uri: https://socketry.github.io/lively/
116
+ source_code_uri: https://github.com/socketry/lively.git
138
117
  post_install_message:
139
118
  rdoc_options: []
140
119
  require_paths:
@@ -143,14 +122,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
143
122
  requirements:
144
123
  - - ">="
145
124
  - !ruby/object:Gem::Version
146
- version: 2.5.0
125
+ version: '3.1'
147
126
  required_rubygems_version: !ruby/object:Gem::Requirement
148
127
  requirements:
149
128
  - - ">="
150
129
  - !ruby/object:Gem::Version
151
130
  version: '0'
152
131
  requirements: []
153
- rubygems_version: 3.3.7
132
+ rubygems_version: 3.5.3
154
133
  signing_key:
155
134
  specification_version: 4
156
135
  summary: A simple client-server SPA framework.
metadata.gz.sig ADDED
Binary file
@@ -1,43 +0,0 @@
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 Lively
24
- module Environments
25
- module Application
26
- def self.load(configuration)
27
- configuration.load(:application)
28
-
29
- configuration.environment(:lively, :application) do
30
- # The middleware stack for the application.
31
- # @attribute [Protocol::HTTP::Middleware]
32
- middleware do
33
- ::Protocol::HTTP::Middleware.build do |builder|
34
- builder.use Assets, root: File.expand_path('public', @root)
35
- builder.use Assets, root: File.expand_path('../../../public', __dir__)
36
- builder.use ::Application
37
- end
38
- end
39
- end
40
- end
41
- end
42
- end
43
- end
@@ -1,157 +0,0 @@
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
- }());
@@ -1 +0,0 @@
1
- var live=function(){"use strict";class Live{constructor(document,url){this.document=document;this.url=url;this.events=[];this.failures=0;this.document.addEventListener("visibilitychange",()=>this.handleVisibilityChange());this.handleVisibilityChange()}connect(){if(this.server)return;let server=this.server=new WebSocket(this.url.href);server.onopen=()=>{this.failures=0;this.attach()};server.onmessage=message=>{const[name,_arguments]=JSON.parse(message.data);this[name](..._arguments)};server.onerror=()=>{this.failures+=1};server.onclose=()=>{this.server=null;let delay=100*(this.failures+1)**2;setTimeout(()=>this.connect(),delay>6e4?6e4:delay)}}disconnect(){if(this.server){this.server.close();this.server=null}}createDocumentFragment(html){return this.document.createRange().createContextualFragment(html)}replace(id,html){let element=document.getElementById(id);morphdom(element,html)}prepend(id,html){let element=document.getElementById(id);let fragment=this.createDocumentFragment(html);element.prepend(fragment)}append(id,html){let element=document.getElementById(id);let fragment=this.createDocumentFragment(html);element.append(fragment)}dispatch(id,type,details){let element=document.getElementById(id);element.dispatchEvent(new CustomEvent(type,details))}trigger(id,event){this.connect();this.send(JSON.stringify({id:id,event:event}))}forward(id,event,details){this.trigger(id,{type:event.type,details:details})}send(message){try{this.server.send(message)}catch(error){this.events.push(message)}}flush(){if(this.events.length===0)return;let events=this.events;this.events=[];for(var event of events){this.send(event)}}bind(elements){for(var element of elements){this.send(JSON.stringify({bind:element.id,data:element.dataset}))}}bindElementsByClassName(selector="live"){this.bind(this.document.getElementsByClassName(selector));this.flush()}handleVisibilityChange(){if(document.hidden){this.disconnect()}else{this.connect()}}attach(){if(this.document.readyState==="loading"){this.document.addEventListener("DOMContentLoaded",()=>this.bindElementsByClassName())}else{this.bindElementsByClassName()}}}let url=new URL("live",location.href);url.protocol=url.protocol.replace("http","ws");let live=new Live(document,url);return live}();