solarite 0.2.4 → 0.3.1
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/dist/Solarite-debug.js +1457 -1402
- package/dist/Solarite.js +1425 -1272
- package/dist/Solarite.min.js +2 -2
- package/package.json +5 -6
- package/readme.md +2 -4
- package/src/{solarite/ExprPath.js → ExprPath.js} +421 -231
- package/src/Globals.js +79 -0
- package/src/HtmlParser.js +91 -0
- package/src/{util/MultiValueMap.js → MultiValueMap.js} +22 -26
- package/src/{solarite/NodeGroup.js → NodeGroup.js} +286 -226
- package/src/{solarite/Shell.js → Shell.js} +119 -92
- package/src/Solarite.d.ts +62 -0
- package/src/{solarite/Solarite.js → Solarite.js} +15 -13
- package/src/{solarite/Template.js → Template.js} +22 -19
- package/src/Util.js +330 -0
- package/src/{util/Errors.js → assert.js} +1 -0
- package/src/createSolarite.js +154 -0
- package/src/{util/delve.js → delve.js} +5 -4
- package/src/{solarite/getArg.js → getArg.js} +41 -15
- package/src/{solarite/r.js → h.js} +59 -29
- package/src/{solarite/hash.js → hash.js} +12 -9
- package/src/unused/FastLookupArray.js +54 -0
- package/src/unused/Hashes.js +339 -0
- package/src/unused/InUse.test.js +92 -0
- package/src/unused/InUseMap.js +98 -0
- package/src/unused/LinkedList.js +117 -0
- package/src/unused/LinkedList.test.js +115 -0
- package/src/unused/Misc.js +13 -0
- package/src/unused/Perf.js +47 -0
- package/src/unused/TrackedArray.js +54 -0
- package/src/watch.js +546 -0
- package/src/solarite/Globals.js +0 -54
- package/src/solarite/Util.js +0 -388
- package/src/solarite/createSolarite.js +0 -274
- package/src/solarite/watch3.js +0 -189
- package/src/util/Util.js +0 -113
- /package/src/{solarite/udomdiff.js → udomdiff.js} +0 -0
- /package/src/{util → unused}/WeakArray.js +0 -0
package/src/solarite/watch3.js
DELETED
|
@@ -1,189 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Trying to be able to automatically watch primitive values.
|
|
3
|
-
* TODO:
|
|
4
|
-
* 1. Have get() return Proxies for nested updates.
|
|
5
|
-
* 2. Override .map() for loops to capture changes.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
// Example:
|
|
10
|
-
/*
|
|
11
|
-
class WatchExample extends Solarite {
|
|
12
|
-
|
|
13
|
-
constructor(items = []) {
|
|
14
|
-
super();
|
|
15
|
-
|
|
16
|
-
this.items = items;
|
|
17
|
-
watch(this, 'items');
|
|
18
|
-
|
|
19
|
-
this.name = 'George';
|
|
20
|
-
watch(this, 'name');
|
|
21
|
-
|
|
22
|
-
this.render();
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
render() {
|
|
26
|
-
r(this)`
|
|
27
|
-
<watch-example>
|
|
28
|
-
${() => this.name + '!'}
|
|
29
|
-
|
|
30
|
-
${this.items.map(item => r`
|
|
31
|
-
<div>${item.name}</div>
|
|
32
|
-
`)}
|
|
33
|
-
${() => this.items.length}
|
|
34
|
-
</watch-example>`;
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
customElements.define('watch-example', WatchExample);
|
|
38
|
-
|
|
39
|
-
let a = new WatchExample();
|
|
40
|
-
|
|
41
|
-
// Items is a Proxy.
|
|
42
|
-
// Calling push() will trigger the map'd ExprPaths to add another at the end.
|
|
43
|
-
// And the .length expression to update.
|
|
44
|
-
// Because accessing .items returns a proxy.
|
|
45
|
-
a.items.push({name: 'Fred'});
|
|
46
|
-
*/
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
import Globals from "./Globals.js";
|
|
50
|
-
import Util from "../util/Util.js";
|
|
51
|
-
|
|
52
|
-
let unusedArg = Symbol('unusedArg');
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* Custom map function triggers the get() Proxy.
|
|
56
|
-
* @param array {Array}
|
|
57
|
-
* @param callback {function}
|
|
58
|
-
* @returns {*[]} */
|
|
59
|
-
function map(array, callback) {
|
|
60
|
-
let result = [];
|
|
61
|
-
for (let i=0; i<array.length; i++)
|
|
62
|
-
result.push(callback(array[i], i, array));
|
|
63
|
-
return result;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
*
|
|
69
|
-
* @param root {HTMLElement}
|
|
70
|
-
* @param field {string}
|
|
71
|
-
* @param value {string|Symbol} */
|
|
72
|
-
export default function watch3(root, field, value=unusedArg) {
|
|
73
|
-
// Store internal value used by get/set.
|
|
74
|
-
if (value !== unusedArg)
|
|
75
|
-
root[field] = value;
|
|
76
|
-
else
|
|
77
|
-
value = root[field];
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
// use a single object for both defineProperty and new Proxy's handler.
|
|
81
|
-
const handler = {
|
|
82
|
-
get(obj, prop, receiver) {
|
|
83
|
-
|
|
84
|
-
let result = (obj === receiver && field === prop)
|
|
85
|
-
? value // top-level value.
|
|
86
|
-
: Reflect.get(obj, prop, receiver); // avoid infinite recursion.
|
|
87
|
-
|
|
88
|
-
if (prop === 'map')
|
|
89
|
-
|
|
90
|
-
// Double function so the ExprPath calls it as a function,
|
|
91
|
-
// instead of it being evaluated immediately when the Templat eis created.
|
|
92
|
-
return (callback) => () => {
|
|
93
|
-
let rootNg = Globals.nodeGroups.get(root);
|
|
94
|
-
rootNg.mapCallbacks.set(obj, callback);
|
|
95
|
-
return map(new Proxy(obj, handler), callback);
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
// Track which ExprPath is using this variable.
|
|
99
|
-
if (Globals.currentExprPath) {
|
|
100
|
-
let [exprPath, exprFunction] = Globals.currentExprPath; // Set in ExprPath.applyExact()
|
|
101
|
-
|
|
102
|
-
let rootNg = Globals.nodeGroups.get(root);
|
|
103
|
-
|
|
104
|
-
// Init for field.
|
|
105
|
-
rootNg.watchedExprPaths[field] = rootNg.watchedExprPaths[field] || new Set();
|
|
106
|
-
rootNg.watchedExprPaths[field].add(exprPath);
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
if (result && typeof result === 'object')
|
|
110
|
-
return new Proxy(result, handler);
|
|
111
|
-
|
|
112
|
-
return result;
|
|
113
|
-
},
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
// TODO: Will fail for attribute w/ a value having multiple ExprPaths.
|
|
117
|
-
// TODO: This won't update a component's expressions.
|
|
118
|
-
set(obj, prop, val, receiver) {
|
|
119
|
-
|
|
120
|
-
// 1. Set the value.
|
|
121
|
-
if (obj === receiver && field === prop)
|
|
122
|
-
value = val; // top-level value.
|
|
123
|
-
else // avoid infinite recursion.
|
|
124
|
-
Reflect.set(obj, prop, val, receiver);
|
|
125
|
-
|
|
126
|
-
// 2. Add to the list of ExprPaths to re-render.
|
|
127
|
-
let rootNg = Globals.nodeGroups.get(root);
|
|
128
|
-
for (let exprPath of rootNg.watchedExprPaths[field]) {
|
|
129
|
-
|
|
130
|
-
// Update a single NodeGroup created by array.map()
|
|
131
|
-
if (Array.isArray(obj) && parseInt(prop) == prop) {
|
|
132
|
-
let exprsToRender = rootNg.exprsToRender.get(exprPath);
|
|
133
|
-
|
|
134
|
-
// If we're not re-rendering the whole thing.
|
|
135
|
-
if (exprsToRender !== true)
|
|
136
|
-
Util.mapAdd(rootNg.exprsToRender, exprPath, [obj, prop, val]);
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
// Reapply the whole expression.
|
|
140
|
-
else
|
|
141
|
-
rootNg.exprsToRender.set(exprPath, true);
|
|
142
|
-
}
|
|
143
|
-
return true;
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
Object.defineProperty(root, field, {
|
|
148
|
-
get: () => handler.get(root, field, root),
|
|
149
|
-
set: (val) => handler.set(root, field, val, root)
|
|
150
|
-
});
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
/**
|
|
154
|
-
* TODO: Rename so we have watch.add() and watch.render() ?
|
|
155
|
-
* @param root
|
|
156
|
-
* @returns {*[]} */
|
|
157
|
-
export function renderWatched(root) {
|
|
158
|
-
let rootNg = Globals.nodeGroups.get(root);
|
|
159
|
-
let modified = [];
|
|
160
|
-
|
|
161
|
-
for (let [exprPath, params] of rootNg.exprsToRender) {
|
|
162
|
-
|
|
163
|
-
// Reapply the whole expression.
|
|
164
|
-
if (params === true) {
|
|
165
|
-
exprPath.apply(exprPath.watchFunction);
|
|
166
|
-
|
|
167
|
-
// TODO: freeNodeGroups() could be skipped if applyExprs() never marked them as in-use.
|
|
168
|
-
exprPath.freeNodeGroups();
|
|
169
|
-
|
|
170
|
-
modified.push(...exprPath.getNodes());
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
// Update a single NodeGroup created by array.map()
|
|
174
|
-
else {
|
|
175
|
-
for (let row of params) {
|
|
176
|
-
let [obj, prop, value] = row;
|
|
177
|
-
let callback = rootNg.mapCallbacks.get(obj);
|
|
178
|
-
let template = callback(value);
|
|
179
|
-
exprPath.applyLoopItemUpdate(prop, template);
|
|
180
|
-
|
|
181
|
-
modified.push(...exprPath.nodeGroups[prop].getNodes());
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
rootNg.exprsToRender = new Map(); // clear
|
|
187
|
-
|
|
188
|
-
return modified;
|
|
189
|
-
}
|
package/src/util/Util.js
DELETED
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* @typedef {Array|function(...*)} Callbacks
|
|
6
|
-
* @property {function(function)} push
|
|
7
|
-
* @property {function()} remove
|
|
8
|
-
* @property {function()} pause
|
|
9
|
-
* @property {function()} resume
|
|
10
|
-
* */
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* A place for functions that have no other home. */
|
|
15
|
-
var Util = {
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Create an array-like object that stores a group of callbacks.
|
|
19
|
-
* Supports all array functions and properties like push() and .length.
|
|
20
|
-
* Can be called directly.
|
|
21
|
-
*
|
|
22
|
-
* @param functions {function[]}
|
|
23
|
-
* @return {Callbacks|function}
|
|
24
|
-
*
|
|
25
|
-
* @example
|
|
26
|
-
* var c = Util.callback();
|
|
27
|
-
* var f = () => console.log(3);
|
|
28
|
-
* c.push(f);
|
|
29
|
-
* c();
|
|
30
|
-
* c.remove(f);
|
|
31
|
-
* c();
|
|
32
|
-
*/
|
|
33
|
-
callback(...functions) {
|
|
34
|
-
var paused = false;
|
|
35
|
-
|
|
36
|
-
// Make it callable. When we call it, call all callbacks() with the given args.
|
|
37
|
-
let result = async function(...args) {
|
|
38
|
-
let result2 = [];
|
|
39
|
-
if (!paused)
|
|
40
|
-
for (let i=0; i<result.length; i++)
|
|
41
|
-
result2.push(result[i](...args));
|
|
42
|
-
return await Promise.all(result2);
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
// Make it iterable.
|
|
46
|
-
result[Symbol.iterator] = function() {
|
|
47
|
-
let index = 0;
|
|
48
|
-
return {
|
|
49
|
-
next: () => index < result.length
|
|
50
|
-
? {value: result[index++], done: false}
|
|
51
|
-
: {done: true}
|
|
52
|
-
};
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
// Use properties from Array
|
|
56
|
-
for (let prop of Object.getOwnPropertyNames(Array.prototype))
|
|
57
|
-
if (prop !== 'length' && prop !== 'constructor')
|
|
58
|
-
result[prop] = Array.prototype[prop];
|
|
59
|
-
|
|
60
|
-
result.l = 0; // Internal length
|
|
61
|
-
Object.defineProperty(result, 'length', {
|
|
62
|
-
get() { return result.l },
|
|
63
|
-
set(val) { result.l = val}
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
// Add the remove() function.
|
|
67
|
-
result.remove = func => {
|
|
68
|
-
let idx = result.findIndex(item => item === func);
|
|
69
|
-
if (idx !== -1)
|
|
70
|
-
result.splice(idx, 1);
|
|
71
|
-
};
|
|
72
|
-
result.pause = () => paused = true;
|
|
73
|
-
|
|
74
|
-
result.resume = () => paused = false;
|
|
75
|
-
|
|
76
|
-
// Add initial functions
|
|
77
|
-
for (let f of functions)
|
|
78
|
-
result.push(f);
|
|
79
|
-
|
|
80
|
-
return result;
|
|
81
|
-
},
|
|
82
|
-
|
|
83
|
-
/**
|
|
84
|
-
* @param map {Map|WeakMap|Object}
|
|
85
|
-
* @param key
|
|
86
|
-
* @param value */
|
|
87
|
-
mapAdd(map, key, value) {
|
|
88
|
-
let isMap = map instanceof Map || map instanceof WeakMap;
|
|
89
|
-
let result = isMap ? map.get(key) : map[key];
|
|
90
|
-
if (!result) {
|
|
91
|
-
result = [value];
|
|
92
|
-
if (isMap)
|
|
93
|
-
map.set(key, result);
|
|
94
|
-
else
|
|
95
|
-
map[key] = result;
|
|
96
|
-
}
|
|
97
|
-
else
|
|
98
|
-
result.push(value);
|
|
99
|
-
},
|
|
100
|
-
|
|
101
|
-
weakMemoize(obj, callback) {
|
|
102
|
-
let result = weakMemoizeInputs.get(obj);
|
|
103
|
-
if (!result) {
|
|
104
|
-
result = callback(obj);
|
|
105
|
-
weakMemoizeInputs.set(obj, result);
|
|
106
|
-
}
|
|
107
|
-
return result;
|
|
108
|
-
}
|
|
109
|
-
};
|
|
110
|
-
|
|
111
|
-
let weakMemoizeInputs = new WeakMap();
|
|
112
|
-
|
|
113
|
-
export default Util;
|
|
File without changes
|
|
File without changes
|