lightview 1.4.10-b → 1.6.3-b
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.
- package/README.md +35 -1
- package/components/chart.html +76 -0
- package/components/gauge.html +57 -0
- package/examples/chart.html +64 -0
- package/examples/counter.html +3 -10
- package/examples/counter.test.mjs +47 -0
- package/examples/directives.html +2 -2
- package/examples/foreign.html +1 -1
- package/examples/forgeinform.html +3 -3
- package/examples/form.html +9 -15
- package/examples/gauge.html +16 -0
- package/examples/invalid-template-literals.html +45 -0
- package/examples/message.html +1 -1
- package/examples/remote.html +3 -1
- package/examples/remote.json +1 -1
- package/examples/sensors/index.html +30 -0
- package/examples/sensors/sensor-server.js +30 -0
- package/examples/template.html +1 -1
- package/examples/types.html +25 -5
- package/examples/xor.html +3 -3
- package/lightview.js +179 -327
- package/package.json +36 -36
- package/test/basic.html +26 -19
- package/test/basic.test.mjs +98 -21
- package/types.js +445 -0
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# lightview v1.
|
|
1
|
+
# lightview v1.6.3b (BETA)
|
|
2
2
|
|
|
3
3
|
Small, simple, powerful web UI and micro front end creation ...
|
|
4
4
|
|
|
@@ -6,3 +6,37 @@ Great ideas from Svelte, React, Vue and Riot combined into one small tool: < 7K
|
|
|
6
6
|
|
|
7
7
|
See the docs and examples at [https://lightview.dev](https://lightview.dev).
|
|
8
8
|
|
|
9
|
+
Meanwhile, here is what you get:
|
|
10
|
+
|
|
11
|
+
1) Single file and <a href="#local-templates" target=_self>template</a> components.
|
|
12
|
+
|
|
13
|
+
1) [Sandboxed remote components](https://lightview.dev/#sandboxed-components) and micro front ends</a>.
|
|
14
|
+
|
|
15
|
+
1) [Unit testable](https://lightview.dev/#unit-testing) components and a [debug mode](https://lightview.dev/#debugging) for using standard JavaScript debuggers</a>.
|
|
16
|
+
|
|
17
|
+
1) No pre-deployment transpilation/compilation required.
|
|
18
|
+
|
|
19
|
+
1) Svelte like variable usage, i.e. write your state modifying code like normal code.
|
|
20
|
+
|
|
21
|
+
1) Extended variable type declarations including `min`, `max` and `step` on `number` or limits on `string` and `array` lengths.
|
|
22
|
+
|
|
23
|
+
1) [TypeScript like](https://lightview.dev/#variables) runtime type checking of variables in components.
|
|
24
|
+
|
|
25
|
+
1) Automatic server retrieval and update of variables declared as `remote`.
|
|
26
|
+
|
|
27
|
+
1) Automatic import, export, cross-component sync, or reactive response to attributes/props/variables. See [superVariable](https://lightview.dev/#super-variable).
|
|
28
|
+
|
|
29
|
+
1) [Automatic form variable creation and binding](https://lightview.dev/#auto-binding-forms).
|
|
30
|
+
|
|
31
|
+
1) [Attribute directives](https://lightview.dev/#attribute-directives) like `l-if`, and a single powerful `l-for` that handles array and object keys, values, and entries.
|
|
32
|
+
|
|
33
|
+
1) Reactive string template literals for content and attribute value replacement.
|
|
34
|
+
|
|
35
|
+
1) No virtual DOM. The Lightview dependency tracker laser targets just those nodes that need updates.
|
|
36
|
+
|
|
37
|
+
1) SPA, and MPA friendly ... somewhat SEO friendly and short steps away from fully SEO friendly.
|
|
38
|
+
|
|
39
|
+
1) A [component library](https://lightview.dev/components) including charts and gauges.
|
|
40
|
+
|
|
41
|
+
1) Lots of live [editable examples](https://lightview.dev/#examples).
|
|
42
|
+
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
<html>
|
|
2
|
+
<head>
|
|
3
|
+
<meta charset="UTF-8">
|
|
4
|
+
<title>Lightview:Chart</title>
|
|
5
|
+
</head>
|
|
6
|
+
<body hidden>
|
|
7
|
+
<div id="target"></div>
|
|
8
|
+
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
|
|
9
|
+
<script src="https://unpkg.com/json5@^2.0.0/dist/index.min.js"></script>
|
|
10
|
+
<script type="lightview/module">
|
|
11
|
+
const target = self.getElementById("target"),
|
|
12
|
+
resizeObserver = new ResizeObserver(entries => {
|
|
13
|
+
for (let entry of entries) {
|
|
14
|
+
if(entry.contentBoxSize) {
|
|
15
|
+
// Firefox implements `contentBoxSize` as a single content rect, rather than an array
|
|
16
|
+
const contentBoxSize = Array.isArray(entry.contentBoxSize) ? entry.contentBoxSize[0] : entry.contentBoxSize;
|
|
17
|
+
options.width = contentBoxSize.inlineSize;
|
|
18
|
+
} else {
|
|
19
|
+
options.width = entry.contentRect.width;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
chart.draw(datatable, options);
|
|
23
|
+
});
|
|
24
|
+
let chart,
|
|
25
|
+
datatable,
|
|
26
|
+
options;
|
|
27
|
+
self.variables({type: "string", title: "string", style: "string"}, {observed});
|
|
28
|
+
if(style) target.setAttribute("style",style);
|
|
29
|
+
self.addRow = (row) => {
|
|
30
|
+
datatable.addRows([row]);
|
|
31
|
+
chart.draw(datatable, options);
|
|
32
|
+
};
|
|
33
|
+
self.setValue = (row,col,value) => {
|
|
34
|
+
if(datatable) {
|
|
35
|
+
datatable.setValue(row,col,value);
|
|
36
|
+
chart.draw(datatable, options);
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
self.init = () => {
|
|
40
|
+
const node = self.firstChild,
|
|
41
|
+
callback = (textNode, oldValue, newValue) => {
|
|
42
|
+
datatable = new google.visualization.DataTable();
|
|
43
|
+
try {
|
|
44
|
+
const table = JSON5.parse(newValue.trim());
|
|
45
|
+
datatable = google.visualization.arrayToDataTable(table);
|
|
46
|
+
chart.draw(datatable, options);
|
|
47
|
+
} catch (e) {
|
|
48
|
+
target.innerText = e + newValue;
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
options = {
|
|
52
|
+
title: title
|
|
53
|
+
};
|
|
54
|
+
chart = new google.visualization[type](target);
|
|
55
|
+
node.characterDataMutationCallback = callback;
|
|
56
|
+
callback(node, node.textContent, node.textContent);
|
|
57
|
+
addEventListener("change",({target,value}) => {
|
|
58
|
+
if (target === "type") {
|
|
59
|
+
chart = new google.visualization[type](target);
|
|
60
|
+
} else if (target === "title") {
|
|
61
|
+
options.title = value;
|
|
62
|
+
} else if(target === "style") {
|
|
63
|
+
target.setAttribute("style",value);
|
|
64
|
+
}
|
|
65
|
+
chart.draw(datatable, options);
|
|
66
|
+
});
|
|
67
|
+
resizeObserver.observe(target);
|
|
68
|
+
self.removeAttribute("hidden");
|
|
69
|
+
};
|
|
70
|
+
addEventListener("connected", ({target}) => {
|
|
71
|
+
google.charts.load("current", {"packages": ["corechart","gauge"]});
|
|
72
|
+
google.charts.setOnLoadCallback(self.init);
|
|
73
|
+
});
|
|
74
|
+
</script>
|
|
75
|
+
</body>
|
|
76
|
+
</html>
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
<html>
|
|
2
|
+
<head>
|
|
3
|
+
<meta charset="UTF-8">
|
|
4
|
+
<title>Lightview:Gauge</title>
|
|
5
|
+
</head>
|
|
6
|
+
<body hidden>
|
|
7
|
+
<div id="target"></div>
|
|
8
|
+
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
|
|
9
|
+
<script type="lightview/module">
|
|
10
|
+
const target = self.getElementById("target"),
|
|
11
|
+
resizeObserver = new ResizeObserver(entries => {
|
|
12
|
+
for (let entry of entries) {
|
|
13
|
+
if(entry.contentBoxSize) {
|
|
14
|
+
// Firefox implements `contentBoxSize` as a single content rect, rather than an array
|
|
15
|
+
const contentBoxSize = Array.isArray(entry.contentBoxSize) ? entry.contentBoxSize[0] : entry.contentBoxSize;
|
|
16
|
+
options.width = contentBoxSize.inlineSize;
|
|
17
|
+
} else {
|
|
18
|
+
options.width = entry.contentRect.width;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
chart.draw(datatable, options);
|
|
22
|
+
});
|
|
23
|
+
let chart,
|
|
24
|
+
datatable,
|
|
25
|
+
options;
|
|
26
|
+
self.variables({label: "string", value:"number", style: "string"}, {observed});
|
|
27
|
+
if(style) target.setAttribute("style",style);
|
|
28
|
+
self.setValue = (newValue) => {
|
|
29
|
+
if(datatable) {
|
|
30
|
+
datatable.setValue(0,1,newValue);
|
|
31
|
+
chart.draw(datatable, options);
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
self.init = () => {
|
|
35
|
+
options = { };
|
|
36
|
+
chart = new google.visualization.Gauge(target);
|
|
37
|
+
datatable = google.visualization.arrayToDataTable([["Label","Value"],[label,value]]);
|
|
38
|
+
addEventListener("change",({target,value}) => {
|
|
39
|
+
if (target === "label") {
|
|
40
|
+
datatable.setValue(0,0,value);
|
|
41
|
+
} else if(target ==="value") {
|
|
42
|
+
self.setValue(value);
|
|
43
|
+
} else if(target === "style") {
|
|
44
|
+
target.setAttribute("style",value);
|
|
45
|
+
}
|
|
46
|
+
chart.draw(datatable, options);
|
|
47
|
+
});
|
|
48
|
+
resizeObserver.observe(target);
|
|
49
|
+
self.removeAttribute("hidden");
|
|
50
|
+
};
|
|
51
|
+
addEventListener("connected", ({target}) => {
|
|
52
|
+
google.charts.load("current", {"packages": ["corechart","gauge"]});
|
|
53
|
+
google.charts.setOnLoadCallback(self.init);
|
|
54
|
+
});
|
|
55
|
+
</script>
|
|
56
|
+
</body>
|
|
57
|
+
</html>
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<head>
|
|
3
|
+
<title>Chart</title>
|
|
4
|
+
<link href="../components/chart.html" rel="module">
|
|
5
|
+
<script src="../lightview.js"></script>
|
|
6
|
+
</head>
|
|
7
|
+
<body>
|
|
8
|
+
<l-chart id="myPieChart" style="max-width:750px" type="PieChart" title="How Much Pizza I Ate Last Night">
|
|
9
|
+
// Chart will resize automatically to a max-width of 750px and repaint on type and title changes.
|
|
10
|
+
// The component DOM element also exposes a method `el.addRow(row:array)` to dynamically add data
|
|
11
|
+
// And, `el.init()` will re-render from the initial data and current attributes.
|
|
12
|
+
[
|
|
13
|
+
["Topping","Slices"], // column headings
|
|
14
|
+
["Mushrooms", 3], // remaining rows are data
|
|
15
|
+
["Onions", 1],
|
|
16
|
+
["Olives", 1],
|
|
17
|
+
["Zucchini", 1],
|
|
18
|
+
["Pepperoni", 2]
|
|
19
|
+
]
|
|
20
|
+
</l-chart>
|
|
21
|
+
<l-chart id="myBarChart" style="max-width:750px" type="BarChart" title="How Much Pizza I Ate Last Night">
|
|
22
|
+
[
|
|
23
|
+
["Topping","Slices",{ role: "style" },{ role: "annotation" }], // column headings, annotation does not apply to Pie
|
|
24
|
+
["Mushrooms", 3, "brown","M"], // remaining rows are data
|
|
25
|
+
["Onions", 1, "yellow","On"],
|
|
26
|
+
["Olives", 1, "black", "Ol"],
|
|
27
|
+
["Zucchini", 1, "green","Z"],
|
|
28
|
+
["Pepperoni", 2, "red","P"]
|
|
29
|
+
]
|
|
30
|
+
</l-chart>
|
|
31
|
+
<l-chart id="myColumnChart" style="max-width:750px" type="ColumnChart" title="How Much Pizza I Ate Last Night">
|
|
32
|
+
[
|
|
33
|
+
["Topping","Slices",{ role: "style" },{ role: "annotation" }], // column headings, style does not apply to Pie or Bar
|
|
34
|
+
["Mushrooms", 3, "brown","Yum"], // remaining rows are data
|
|
35
|
+
["Onions", 1, "yellow","Sweet"],
|
|
36
|
+
["Olives", 1, "black","So, so"],
|
|
37
|
+
["Zucchini", 1, "green","Ick!"],
|
|
38
|
+
["Pepperoni", 2, "red","Spicy!"]
|
|
39
|
+
]
|
|
40
|
+
</l-chart>
|
|
41
|
+
<l-chart id="myGauges" style="max-width:750px" type="Gauge" title="Laptop">
|
|
42
|
+
[
|
|
43
|
+
['Label', 'Value'], // gauge will always take two columns, Label and Value
|
|
44
|
+
['Memory', 80],
|
|
45
|
+
['CPU', 55],
|
|
46
|
+
['Network', 68]
|
|
47
|
+
]
|
|
48
|
+
// there is also a separate l-gauge component that shows just one gauge
|
|
49
|
+
// and is driven entirely by attributes
|
|
50
|
+
</l-chart>
|
|
51
|
+
<script>
|
|
52
|
+
const gauges = document.getElementById("myGauges");
|
|
53
|
+
setInterval(function() {
|
|
54
|
+
gauges.setValue(0, 1, 40 + Math.round(60 * Math.random()));
|
|
55
|
+
}, 6000);
|
|
56
|
+
setInterval(function() {
|
|
57
|
+
gauges.setValue(1, 1, 40 + Math.round(60 * Math.random()));
|
|
58
|
+
}, 5000);
|
|
59
|
+
setInterval(function() {
|
|
60
|
+
gauges.setValue(2, 1, 60 + Math.round(40 * Math.random()));
|
|
61
|
+
}, 7500);
|
|
62
|
+
</script>
|
|
63
|
+
</body>
|
|
64
|
+
</html>
|
package/examples/counter.html
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<head>
|
|
2
|
-
<title>Counter</title>
|
|
2
|
+
<title>Lightview:Examples:Counter</title>
|
|
3
3
|
<script src="../lightview.js?as=x-body"></script>
|
|
4
4
|
</head>
|
|
5
5
|
|
|
@@ -9,16 +9,9 @@
|
|
|
9
9
|
</p>
|
|
10
10
|
|
|
11
11
|
<script type="lightview/module">
|
|
12
|
-
|
|
13
|
-
self.variables({
|
|
14
|
-
count: number
|
|
15
|
-
}, {
|
|
16
|
-
reactive
|
|
17
|
-
});
|
|
18
|
-
debugger;
|
|
19
|
-
count = 0;
|
|
12
|
+
self.variables({count: "number",}, {reactive,set:0});
|
|
20
13
|
self.bump = () => count++;
|
|
21
|
-
|
|
14
|
+
</script>
|
|
22
15
|
|
|
23
16
|
<style>
|
|
24
17
|
button {
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import 'expect-puppeteer';
|
|
2
|
+
|
|
3
|
+
describe('Lightview:Example:Counter', () => {
|
|
4
|
+
beforeAll(async () => {
|
|
5
|
+
await page.goto('http://localhost:8080/examples/counter.html');
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
test('should be titled "Lightview:Examples:Counter"', async () => {
|
|
9
|
+
await expect(page.title()).resolves.toMatch("Lightview:Examples:Counter");
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
test('count should be a variable', async () => {
|
|
13
|
+
const result = await page.evaluate(async () => {
|
|
14
|
+
return document.body.getVariable("count");
|
|
15
|
+
});
|
|
16
|
+
expect(result).toBeDefined();
|
|
17
|
+
const {name,type,value,reactive} = result;
|
|
18
|
+
expect(name).toBe("count");
|
|
19
|
+
expect(type).toBe("number");
|
|
20
|
+
expect(value).toBe(0);
|
|
21
|
+
expect(reactive).toBe(true);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
test('bump should be called', async () => {
|
|
25
|
+
const result = await page.evaluate(async () => {
|
|
26
|
+
document.body.bump();
|
|
27
|
+
return document.body.getVariableValue("count");
|
|
28
|
+
});
|
|
29
|
+
expect(result).toBe(1);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
test('click should bump', async () => {
|
|
33
|
+
const buttonHandle = await page.evaluateHandle('document.body.querySelector("button")');
|
|
34
|
+
await buttonHandle.click();
|
|
35
|
+
const result = await page.evaluate(async () => {
|
|
36
|
+
return document.body.getVariableValue("count");
|
|
37
|
+
});
|
|
38
|
+
expect(result).toBe(2);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
test("should be custom element", async() => {
|
|
42
|
+
const result = await page.evaluate(async () => {
|
|
43
|
+
return document.body.constructor.name;
|
|
44
|
+
});
|
|
45
|
+
expect(result).toBe("CustomElement");
|
|
46
|
+
})
|
|
47
|
+
})
|
package/examples/directives.html
CHANGED
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
<p id="variables"></p>
|
|
52
52
|
</div>
|
|
53
53
|
<script type="lightview/module">
|
|
54
|
-
self.variables({on:boolean,options:Array},{reactive});
|
|
54
|
+
self.variables({on:"boolean",options:Array},{reactive});
|
|
55
55
|
|
|
56
56
|
on = true;
|
|
57
57
|
options = ["lettuce"];
|
|
@@ -62,7 +62,7 @@ const variableValues = () => {
|
|
|
62
62
|
while(el.lastElementChild) el.lastElementChild.remove();
|
|
63
63
|
self.getVariableNames().forEach((name) => {
|
|
64
64
|
const line = document.createElement("div");
|
|
65
|
-
line.innerText = `${name} = ${JSON.stringify(self.
|
|
65
|
+
line.innerText = `${name} = ${JSON.stringify(self.getVariableValue(name))}`;
|
|
66
66
|
el.appendChild(line);
|
|
67
67
|
});
|
|
68
68
|
};
|
package/examples/foreign.html
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
The component below is loaded from an alternate domain and running in a child iframe.
|
|
13
13
|
The logging console is below the component in this frame.
|
|
14
14
|
</p>
|
|
15
|
-
<iframe id="myframe" src="https://lightview.dev/
|
|
15
|
+
<iframe id="myframe" src="https://lightview.dev/foreignform.html?id=myframe"></iframe>
|
|
16
16
|
<div id="console" style="max-height:250px;scroll:auto"></div>
|
|
17
17
|
<script>
|
|
18
18
|
const mutationCallback = (mutationsList) => {
|
|
@@ -46,8 +46,8 @@
|
|
|
46
46
|
</div>
|
|
47
47
|
<script type="lightview/module">
|
|
48
48
|
self.variables({
|
|
49
|
-
color: string,
|
|
50
|
-
checked: boolean,
|
|
49
|
+
color: "string",
|
|
50
|
+
checked: "boolean",
|
|
51
51
|
hamburger: Array
|
|
52
52
|
}, {
|
|
53
53
|
reactive
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
while (el.lastElementChild) el.lastElementChild.remove();
|
|
62
62
|
self.getVariableNames().forEach((name) => {
|
|
63
63
|
const line = document.createElement("div");
|
|
64
|
-
line.innerText = `${name} = ${JSON.stringify(self.
|
|
64
|
+
line.innerText = `${name} = ${JSON.stringify(self.getVariableValue(name))}`;
|
|
65
65
|
el.appendChild(line);
|
|
66
66
|
});
|
|
67
67
|
};
|
package/examples/form.html
CHANGED
|
@@ -34,31 +34,25 @@
|
|
|
34
34
|
</p>
|
|
35
35
|
</div>
|
|
36
36
|
<script type="lightview/module">
|
|
37
|
-
self.variables({
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
37
|
+
self.variables({color:"string"},{reactive});
|
|
38
|
+
addEventListener("change", () => {
|
|
39
|
+
variableValues()
|
|
40
|
+
});
|
|
41
|
+
addEventListener("connected",() => {
|
|
42
|
+
color = "yellow";
|
|
43
|
+
checked = true;
|
|
44
|
+
hamburger = ["cheese"];
|
|
43
45
|
});
|
|
44
|
-
color = "red";
|
|
45
|
-
checked = true;
|
|
46
|
-
hamburger = ["cheese"];
|
|
47
|
-
|
|
48
46
|
// demo instrumentation
|
|
49
47
|
const variableValues = () => {
|
|
50
48
|
const el = self.getElementById("variables");
|
|
51
49
|
while (el.lastElementChild) el.lastElementChild.remove();
|
|
52
50
|
self.getVariableNames().forEach((name) => {
|
|
53
51
|
const line = document.createElement("div");
|
|
54
|
-
line.innerText = `${name} = ${JSON.stringify(self.
|
|
52
|
+
line.innerText = `${name} = ${JSON.stringify(self.getVariableValue(name))}`;
|
|
55
53
|
el.appendChild(line);
|
|
56
54
|
});
|
|
57
55
|
};
|
|
58
|
-
variableValues();
|
|
59
|
-
addEventListener("change", () => {
|
|
60
|
-
variableValues()
|
|
61
|
-
});
|
|
62
56
|
</script>
|
|
63
57
|
</body>
|
|
64
58
|
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<head>
|
|
3
|
+
<title>Chart</title>
|
|
4
|
+
<link href="../components/gauge.html" rel="module">
|
|
5
|
+
<script src="../lightview.js"></script>
|
|
6
|
+
</head>
|
|
7
|
+
<body>
|
|
8
|
+
<l-gauge id="myGauge" style="max-width:750px" type="Gauge" label="Laptop" value="50"></l-gauge>
|
|
9
|
+
<script>
|
|
10
|
+
const gauge = document.getElementById("myGauge");
|
|
11
|
+
setInterval(function() {
|
|
12
|
+
gauge.setValue(40 + Math.round(60 * Math.random()));
|
|
13
|
+
}, 2500);
|
|
14
|
+
</script>
|
|
15
|
+
</body>
|
|
16
|
+
</html>
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<title>Invalid Template Literals</title>
|
|
5
|
+
<script src="../lightview.js?as=x-body"></script>
|
|
6
|
+
</head>
|
|
7
|
+
<body>
|
|
8
|
+
<p>
|
|
9
|
+
<button l-on:click="bump">Click count:${count}</button>
|
|
10
|
+
</p>
|
|
11
|
+
<div style="margin:20px">
|
|
12
|
+
<p>
|
|
13
|
+
${"<h1>"+(test++)+"</h1>"}
|
|
14
|
+
</p>
|
|
15
|
+
<p>
|
|
16
|
+
${(while (test)<10 { test++}; test)}
|
|
17
|
+
</p>
|
|
18
|
+
<p>
|
|
19
|
+
${(() =>test)()}
|
|
20
|
+
</p>
|
|
21
|
+
<p>
|
|
22
|
+
${(() = >test)()}
|
|
23
|
+
</p>
|
|
24
|
+
<p>
|
|
25
|
+
${function(){return \${test}})()}
|
|
26
|
+
</p>
|
|
27
|
+
<p>
|
|
28
|
+
${window.alert("ok")}
|
|
29
|
+
</p>
|
|
30
|
+
</div>
|
|
31
|
+
|
|
32
|
+
<script type="lightview/module">
|
|
33
|
+
self.variables({count: "number",test:"number"}, {reactive,set:0});
|
|
34
|
+
self.bump = () => count++;
|
|
35
|
+
</script>
|
|
36
|
+
|
|
37
|
+
<style>
|
|
38
|
+
button {
|
|
39
|
+
margin: 20px;
|
|
40
|
+
background: gray
|
|
41
|
+
}
|
|
42
|
+
</style>
|
|
43
|
+
</body>
|
|
44
|
+
|
|
45
|
+
</html>
|
package/examples/message.html
CHANGED
package/examples/remote.html
CHANGED
|
@@ -13,7 +13,9 @@
|
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
<script type="lightview/module">
|
|
16
|
-
|
|
16
|
+
const {remote} = await import("../types.js");
|
|
17
|
+
|
|
18
|
+
self.variables({myRemote:"object"},{reactive,remote:remote("http://localhost:8000/remote.json")});
|
|
17
19
|
|
|
18
20
|
await myRemote; // must await remotes before the first time they are used, e.g. before HTML is rendered
|
|
19
21
|
|
package/examples/remote.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"name":"joe","age":
|
|
1
|
+
{"name":"joe","age":30}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<head>
|
|
3
|
+
<title>Lightview:Sensor Demo</title>
|
|
4
|
+
<link href="../../components/gauge.html" rel="module">
|
|
5
|
+
<script src="../../lightview.js?as=x-body"></script>
|
|
6
|
+
</head>
|
|
7
|
+
<body>
|
|
8
|
+
<div style="width:100%;text-align:center">
|
|
9
|
+
<div style="display:inline-block">
|
|
10
|
+
<l-gauge id="sensor1" type="Gauge" label="Sensor One" value="50"></l-gauge>
|
|
11
|
+
</div>
|
|
12
|
+
|
|
13
|
+
<div style="display:inline-block">
|
|
14
|
+
<l-gauge id="sensor2" type="Gauge" label="Sensor Two" value="50"></l-gauge>
|
|
15
|
+
</div>
|
|
16
|
+
</div>
|
|
17
|
+
|
|
18
|
+
<script type="lightview/module">
|
|
19
|
+
const {remote} = await import("../../types.js");
|
|
20
|
+
self.variables({sensor1:"number"},{remote:remote({ttl:5000,path:"https://lightview.dev/sensors/sensor1"})});
|
|
21
|
+
self.variables({sensor2:"number"},{remote:remote({ttl:7500,path:"https://lightview.dev/sensors/sensor2"})});
|
|
22
|
+
await sensor1;
|
|
23
|
+
await sensor2;
|
|
24
|
+
addEventListener("change",({variableName,value}) => {
|
|
25
|
+
const sensor = document.body.getElementById(variableName);
|
|
26
|
+
sensor.setValue(value);
|
|
27
|
+
});
|
|
28
|
+
</script>
|
|
29
|
+
</body>
|
|
30
|
+
</html>
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
const http = require("http"),
|
|
2
|
+
fs = require("fs"),
|
|
3
|
+
host = 'localhost',
|
|
4
|
+
port = 8000,
|
|
5
|
+
requestListener = async function (req, res) {
|
|
6
|
+
const path = `.${req.url}`;
|
|
7
|
+
res.setHeader("Access-Control-Allow-Origin","*");
|
|
8
|
+
res.setHeader("Access-Control-Allow-Methods", "GET,OPTIONS");
|
|
9
|
+
res.setHeader("Access-Control-Allow-Headers", "*");
|
|
10
|
+
res.setHeader("Content-Type", "application/json");
|
|
11
|
+
if(req.method==="OPTIONS") {
|
|
12
|
+
res.end();
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
if(req.method==="GET") {
|
|
16
|
+
const value = `${40 + Math.round(60 * Math.random())}`;
|
|
17
|
+
console.log("GET",req.url,"<-",value);
|
|
18
|
+
res.setHeader("Content-Length", value.length);
|
|
19
|
+
res.write(value);
|
|
20
|
+
res.end();
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
console.log(req.method);
|
|
24
|
+
},
|
|
25
|
+
server = http.createServer(requestListener);
|
|
26
|
+
server.listen(port, host, () => {
|
|
27
|
+
console.log(`Server is running on http://${host}:${port}`);
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
|
package/examples/template.html
CHANGED
package/examples/types.html
CHANGED
|
@@ -15,17 +15,36 @@
|
|
|
15
15
|
<p id="console"></p>
|
|
16
16
|
</div>
|
|
17
17
|
<script type="lightview/module">
|
|
18
|
-
|
|
19
|
-
astring: string,
|
|
20
|
-
aDate: Date,
|
|
21
|
-
err: Error
|
|
22
|
-
});
|
|
18
|
+
const {string} = await import("../types.js");
|
|
23
19
|
self.run = () => {
|
|
20
|
+
self.variables({
|
|
21
|
+
err: Error,
|
|
22
|
+
astring: "string",
|
|
23
|
+
asdvancedstring: string({maxlength:10}),
|
|
24
|
+
aDate: Date,
|
|
25
|
+
});
|
|
26
|
+
try {
|
|
27
|
+
self.variables({
|
|
28
|
+
badvariable: string({maxlength:"10"}),
|
|
29
|
+
});
|
|
30
|
+
} catch(e) {
|
|
31
|
+
err = e;
|
|
32
|
+
}
|
|
24
33
|
try {
|
|
25
34
|
astring = "my string";
|
|
26
35
|
} catch (e) {
|
|
27
36
|
err = e;
|
|
28
37
|
}
|
|
38
|
+
try {
|
|
39
|
+
asdvancedstring = "my string";
|
|
40
|
+
} catch (e) {
|
|
41
|
+
err = e;
|
|
42
|
+
}
|
|
43
|
+
try {
|
|
44
|
+
asdvancedstring = "my long string";
|
|
45
|
+
} catch (e) {
|
|
46
|
+
err = e;
|
|
47
|
+
}
|
|
29
48
|
try {
|
|
30
49
|
astring = 1;
|
|
31
50
|
} catch (e) {
|
|
@@ -47,6 +66,7 @@
|
|
|
47
66
|
err = e;
|
|
48
67
|
}
|
|
49
68
|
};
|
|
69
|
+
|
|
50
70
|
// demo instrumentation
|
|
51
71
|
self.clear = () => {
|
|
52
72
|
const cnsl = self.getElementById("console");
|
package/examples/xor.html
CHANGED
|
@@ -9,10 +9,10 @@
|
|
|
9
9
|
</p>
|
|
10
10
|
<script type="lightview/module">
|
|
11
11
|
self.variables({
|
|
12
|
-
run: boolean
|
|
12
|
+
run: "boolean"
|
|
13
13
|
},{reactive});
|
|
14
14
|
self.variables({
|
|
15
|
-
name: string
|
|
15
|
+
name: "string"
|
|
16
16
|
}, {
|
|
17
17
|
imported
|
|
18
18
|
});
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
}) => {
|
|
23
23
|
if (variableName === "run" && value === true) {
|
|
24
24
|
self.siblings.forEach((sibling) => {
|
|
25
|
-
sibling.
|
|
25
|
+
sibling.setVariableValue(variableName, false);
|
|
26
26
|
})
|
|
27
27
|
}
|
|
28
28
|
})
|