lively 0.3.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 +4 -4
- checksums.yaml.gz.sig +0 -0
- data/lib/lively/version.rb +1 -1
- data/public/_components/@socketry/live/Live.js +59 -27
- data/public/_components/@socketry/live/package.json +1 -1
- data/public/_components/@socketry/live/test/Live.js +80 -11
- data.tar.gz.sig +0 -0
- metadata +7 -7
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 2eb71ca34e43090f3b06b4577cc5c29ed82d3282df6fb26c69adb02cc5eff5fe
|
|
4
|
+
data.tar.gz: 7df1288ae0defc42656da59f5a12e92f3619adc9993e54a4b5e55ac7d10cd795
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: dafdbe14c26702f71de2bc519ac398d141ffc2d1b7f2d1b94f32c44602ea9efc6c083282268f48c7d08798269947322d13bc7005d664b02863fb7bf4f041f031
|
|
7
|
+
data.tar.gz: d65fd9f4c15cd6992c67bf2ffb1ee21d4d86d15643b71e092f38f55386f438bea86e1aa1b0a535a1c0fbd48836e6ec99e77575e751eec513f7c74f77d89064f5
|
checksums.yaml.gz.sig
CHANGED
|
Binary file
|
data/lib/lively/version.rb
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
|
|
2
1
|
import morphdom from 'morphdom';
|
|
3
2
|
|
|
4
3
|
export class Live {
|
|
@@ -25,6 +24,39 @@ export class Live {
|
|
|
25
24
|
// Track visibility state and connect if required:
|
|
26
25
|
this.document.addEventListener("visibilitychange", () => this.handleVisibilityChange());
|
|
27
26
|
this.handleVisibilityChange();
|
|
27
|
+
|
|
28
|
+
// Create a MutationObserver to watch for removed nodes
|
|
29
|
+
this.observer = new this.window.MutationObserver((mutationsList, observer) => {
|
|
30
|
+
for (let mutation of mutationsList) {
|
|
31
|
+
if (mutation.type === 'childList') {
|
|
32
|
+
for (let node of mutation.removedNodes) {
|
|
33
|
+
if (node.classList?.contains('live')) {
|
|
34
|
+
this.unbind(node);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Unbind any child nodes:
|
|
38
|
+
for (let child of node.getElementsByClassName('live')) {
|
|
39
|
+
this.unbind(child);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
for (let node of mutation.addedNodes) {
|
|
44
|
+
if (node.classList?.contains('live')) {
|
|
45
|
+
this.bind(node);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Bind any child nodes:
|
|
49
|
+
for (let child of node.getElementsByClassName('live')) {
|
|
50
|
+
this.bind(child);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
this.observer.observe(this.document.body, {childList: true, subtree: true});
|
|
58
|
+
|
|
59
|
+
this.attach();
|
|
28
60
|
}
|
|
29
61
|
|
|
30
62
|
// -- Connection Handling --
|
|
@@ -36,7 +68,7 @@ export class Live {
|
|
|
36
68
|
|
|
37
69
|
server.onopen = () => {
|
|
38
70
|
this.failures = 0;
|
|
39
|
-
this.
|
|
71
|
+
this.flush();
|
|
40
72
|
};
|
|
41
73
|
|
|
42
74
|
server.onmessage = (message) => {
|
|
@@ -73,11 +105,15 @@ export class Live {
|
|
|
73
105
|
}
|
|
74
106
|
|
|
75
107
|
send(message) {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
108
|
+
if (this.server) {
|
|
109
|
+
try {
|
|
110
|
+
return this.server.send(message);
|
|
111
|
+
} catch (error) {
|
|
112
|
+
// Ignore.
|
|
113
|
+
}
|
|
80
114
|
}
|
|
115
|
+
|
|
116
|
+
this.events.push(message);
|
|
81
117
|
}
|
|
82
118
|
|
|
83
119
|
flush() {
|
|
@@ -91,20 +127,6 @@ export class Live {
|
|
|
91
127
|
}
|
|
92
128
|
}
|
|
93
129
|
|
|
94
|
-
bind(elements) {
|
|
95
|
-
for (var element of elements) {
|
|
96
|
-
this.send(JSON.stringify({bind: element.id, data: element.dataset}));
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
bindElementsByClassName(selector = 'live') {
|
|
101
|
-
this.bind(
|
|
102
|
-
this.document.getElementsByClassName(selector)
|
|
103
|
-
);
|
|
104
|
-
|
|
105
|
-
this.flush();
|
|
106
|
-
}
|
|
107
|
-
|
|
108
130
|
handleVisibilityChange() {
|
|
109
131
|
if (this.document.hidden) {
|
|
110
132
|
this.disconnect();
|
|
@@ -113,11 +135,21 @@ export class Live {
|
|
|
113
135
|
}
|
|
114
136
|
}
|
|
115
137
|
|
|
138
|
+
bind(element) {
|
|
139
|
+
console.log("bind", element.id, element.dataset);
|
|
140
|
+
|
|
141
|
+
this.send(JSON.stringify(['bind', element.id, element.dataset]));
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
unbind(element) {
|
|
145
|
+
console.log("unbind", element.id, element.dataset);
|
|
146
|
+
|
|
147
|
+
this.send(JSON.stringify(['unbind', element.id]));
|
|
148
|
+
}
|
|
149
|
+
|
|
116
150
|
attach() {
|
|
117
|
-
|
|
118
|
-
this.
|
|
119
|
-
} else {
|
|
120
|
-
this.bindElementsByClassName();
|
|
151
|
+
for (let node of this.document.getElementsByClassName('live')) {
|
|
152
|
+
this.bind(node);
|
|
121
153
|
}
|
|
122
154
|
}
|
|
123
155
|
|
|
@@ -126,8 +158,8 @@ export class Live {
|
|
|
126
158
|
}
|
|
127
159
|
|
|
128
160
|
reply(options) {
|
|
129
|
-
if (options
|
|
130
|
-
this.send(JSON.stringify(
|
|
161
|
+
if (options?.reply) {
|
|
162
|
+
this.send(JSON.stringify(['reply', options.reply]));
|
|
131
163
|
}
|
|
132
164
|
}
|
|
133
165
|
|
|
@@ -193,7 +225,7 @@ export class Live {
|
|
|
193
225
|
this.connect();
|
|
194
226
|
|
|
195
227
|
this.send(
|
|
196
|
-
JSON.stringify(
|
|
228
|
+
JSON.stringify(['event', id, event])
|
|
197
229
|
);
|
|
198
230
|
}
|
|
199
231
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {describe, before, after, it} from 'node:test';
|
|
2
|
-
import {ok, strict, strictEqual} from 'node:assert';
|
|
2
|
+
import {ok, strict, strictEqual, deepStrictEqual} from 'node:assert';
|
|
3
3
|
|
|
4
4
|
import {WebSocket} from 'ws';
|
|
5
5
|
import {JSDOM} from 'jsdom';
|
|
@@ -13,8 +13,9 @@ describe('Live', function () {
|
|
|
13
13
|
const webSocketServerURL = `ws://localhost:${webSocketServerConfig.port}/live`;
|
|
14
14
|
|
|
15
15
|
before(async function () {
|
|
16
|
-
const listening = new Promise(resolve => {
|
|
16
|
+
const listening = new Promise((resolve, reject) => {
|
|
17
17
|
webSocketServer = new WebSocket.Server(webSocketServerConfig, resolve);
|
|
18
|
+
webSocketServer.on('error', reject);
|
|
18
19
|
});
|
|
19
20
|
|
|
20
21
|
dom = new JSDOM('<!DOCTYPE html><html><body><div id="my"><p>Hello World</p></div></body></html>');
|
|
@@ -81,7 +82,7 @@ describe('Live', function () {
|
|
|
81
82
|
const reply = new Promise((resolve, reject) => {
|
|
82
83
|
socket.on('message', message => {
|
|
83
84
|
let payload = JSON.parse(message);
|
|
84
|
-
if (payload
|
|
85
|
+
if (payload[0] == 'reply') resolve(payload);
|
|
85
86
|
});
|
|
86
87
|
});
|
|
87
88
|
|
|
@@ -96,7 +97,72 @@ describe('Live', function () {
|
|
|
96
97
|
live.disconnect();
|
|
97
98
|
});
|
|
98
99
|
|
|
100
|
+
it('should handle updates with child live elements', async function () {
|
|
101
|
+
const live = new Live(dom.window, webSocketServerURL);
|
|
102
|
+
|
|
103
|
+
live.connect();
|
|
104
|
+
|
|
105
|
+
const connected = new Promise(resolve => {
|
|
106
|
+
webSocketServer.on('connection', resolve);
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
let socket = await connected;
|
|
110
|
+
|
|
111
|
+
const reply = new Promise((resolve, reject) => {
|
|
112
|
+
socket.on('message', message => {
|
|
113
|
+
let payload = JSON.parse(message);
|
|
114
|
+
console.log("message", payload);
|
|
115
|
+
if (payload[0] == 'bind') resolve(payload);
|
|
116
|
+
else console.log("ignoring", payload);
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
socket.send(
|
|
121
|
+
JSON.stringify(['update', 'my', '<div id="my"><div id="mychild" class="live"></div></div>'])
|
|
122
|
+
);
|
|
123
|
+
|
|
124
|
+
let payload = await reply;
|
|
125
|
+
|
|
126
|
+
deepStrictEqual(payload, ['bind', 'mychild', {}]);
|
|
127
|
+
|
|
128
|
+
live.disconnect();
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
it('can unbind removed elements', async function () {
|
|
132
|
+
dom.window.document.body.innerHTML = '<div id="my" class="live"><p>Hello World</p></div>';
|
|
133
|
+
|
|
134
|
+
const live = new Live(dom.window, webSocketServerURL);
|
|
135
|
+
|
|
136
|
+
live.connect();
|
|
137
|
+
|
|
138
|
+
const connected = new Promise(resolve => {
|
|
139
|
+
webSocketServer.on('connection', resolve);
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
let socket = await connected;
|
|
143
|
+
|
|
144
|
+
const reply = new Promise((resolve, reject) => {
|
|
145
|
+
socket.on('message', message => {
|
|
146
|
+
let payload = JSON.parse(message);
|
|
147
|
+
if (payload[0] == 'unbind') resolve(payload);
|
|
148
|
+
else console.log("ignoring", payload);
|
|
149
|
+
});
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
live.attach();
|
|
153
|
+
|
|
154
|
+
dom.window.document.getElementById('my').remove();
|
|
155
|
+
|
|
156
|
+
let payload = await reply;
|
|
157
|
+
|
|
158
|
+
deepStrictEqual(payload, ['unbind', 'my']);
|
|
159
|
+
|
|
160
|
+
live.disconnect();
|
|
161
|
+
});
|
|
162
|
+
|
|
99
163
|
it('should handle replacements', async function () {
|
|
164
|
+
dom.window.document.body.innerHTML = '<div id="my"><p>Hello World</p></div>';
|
|
165
|
+
|
|
100
166
|
const live = new Live(dom.window, webSocketServerURL);
|
|
101
167
|
|
|
102
168
|
live.connect();
|
|
@@ -110,7 +176,8 @@ describe('Live', function () {
|
|
|
110
176
|
const reply = new Promise((resolve, reject) => {
|
|
111
177
|
socket.on('message', message => {
|
|
112
178
|
let payload = JSON.parse(message);
|
|
113
|
-
if (payload
|
|
179
|
+
if (payload[0] == 'reply') resolve(payload);
|
|
180
|
+
else console.log("ignoring", payload);
|
|
114
181
|
});
|
|
115
182
|
});
|
|
116
183
|
|
|
@@ -143,7 +210,8 @@ describe('Live', function () {
|
|
|
143
210
|
const reply = new Promise((resolve, reject) => {
|
|
144
211
|
socket.on('message', message => {
|
|
145
212
|
let payload = JSON.parse(message);
|
|
146
|
-
if (payload
|
|
213
|
+
if (payload[0] == 'reply') resolve(payload);
|
|
214
|
+
else console.log("ignoring", payload);
|
|
147
215
|
});
|
|
148
216
|
});
|
|
149
217
|
|
|
@@ -176,7 +244,8 @@ describe('Live', function () {
|
|
|
176
244
|
const reply = new Promise((resolve, reject) => {
|
|
177
245
|
socket.on('message', message => {
|
|
178
246
|
let payload = JSON.parse(message);
|
|
179
|
-
if (payload
|
|
247
|
+
if (payload[0] == 'reply') resolve(payload);
|
|
248
|
+
else console.log("ignoring", payload);
|
|
180
249
|
});
|
|
181
250
|
});
|
|
182
251
|
|
|
@@ -209,7 +278,7 @@ describe('Live', function () {
|
|
|
209
278
|
const reply = new Promise((resolve, reject) => {
|
|
210
279
|
socket.on('message', message => {
|
|
211
280
|
let payload = JSON.parse(message);
|
|
212
|
-
if (payload
|
|
281
|
+
if (payload[0] == 'reply') resolve(payload);
|
|
213
282
|
});
|
|
214
283
|
});
|
|
215
284
|
|
|
@@ -238,7 +307,7 @@ describe('Live', function () {
|
|
|
238
307
|
const reply = new Promise((resolve, reject) => {
|
|
239
308
|
socket.on('message', message => {
|
|
240
309
|
let payload = JSON.parse(message);
|
|
241
|
-
if (payload
|
|
310
|
+
if (payload[0] == 'reply') resolve(payload);
|
|
242
311
|
});
|
|
243
312
|
});
|
|
244
313
|
|
|
@@ -265,7 +334,7 @@ describe('Live', function () {
|
|
|
265
334
|
const reply = new Promise((resolve, reject) => {
|
|
266
335
|
socket.on('message', message => {
|
|
267
336
|
let payload = JSON.parse(message);
|
|
268
|
-
if (payload
|
|
337
|
+
if (payload[0] == 'event') resolve(payload);
|
|
269
338
|
});
|
|
270
339
|
});
|
|
271
340
|
|
|
@@ -277,8 +346,8 @@ describe('Live', function () {
|
|
|
277
346
|
|
|
278
347
|
let payload = await reply;
|
|
279
348
|
|
|
280
|
-
strictEqual(payload
|
|
281
|
-
strictEqual(payload.
|
|
349
|
+
strictEqual(payload[1], 'my');
|
|
350
|
+
strictEqual(payload[2].type, 'click');
|
|
282
351
|
|
|
283
352
|
live.disconnect();
|
|
284
353
|
});
|
data.tar.gz.sig
CHANGED
|
Binary file
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: lively
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.4.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Samuel Williams
|
|
@@ -43,30 +43,30 @@ dependencies:
|
|
|
43
43
|
name: falcon
|
|
44
44
|
requirement: !ruby/object:Gem::Requirement
|
|
45
45
|
requirements:
|
|
46
|
-
- - "
|
|
46
|
+
- - "~>"
|
|
47
47
|
- !ruby/object:Gem::Version
|
|
48
|
-
version: '0'
|
|
48
|
+
version: '0.47'
|
|
49
49
|
type: :runtime
|
|
50
50
|
prerelease: false
|
|
51
51
|
version_requirements: !ruby/object:Gem::Requirement
|
|
52
52
|
requirements:
|
|
53
|
-
- - "
|
|
53
|
+
- - "~>"
|
|
54
54
|
- !ruby/object:Gem::Version
|
|
55
|
-
version: '0'
|
|
55
|
+
version: '0.47'
|
|
56
56
|
- !ruby/object:Gem::Dependency
|
|
57
57
|
name: live
|
|
58
58
|
requirement: !ruby/object:Gem::Requirement
|
|
59
59
|
requirements:
|
|
60
60
|
- - "~>"
|
|
61
61
|
- !ruby/object:Gem::Version
|
|
62
|
-
version: 0.
|
|
62
|
+
version: '0.8'
|
|
63
63
|
type: :runtime
|
|
64
64
|
prerelease: false
|
|
65
65
|
version_requirements: !ruby/object:Gem::Requirement
|
|
66
66
|
requirements:
|
|
67
67
|
- - "~>"
|
|
68
68
|
- !ruby/object:Gem::Version
|
|
69
|
-
version: 0.
|
|
69
|
+
version: '0.8'
|
|
70
70
|
- !ruby/object:Gem::Dependency
|
|
71
71
|
name: xrb
|
|
72
72
|
requirement: !ruby/object:Gem::Requirement
|
metadata.gz.sig
CHANGED
|
Binary file
|