wallace 0.0.8 → 0.2.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.
- package/lib/component.js +50 -15
- package/lib/index.js +6 -9
- package/lib/initCalls.js +39 -50
- package/lib/repeaters.js +23 -25
- package/lib/types.d.ts +1724 -26
- package/lib/utils.js +27 -27
- package/package.json +4 -4
- package/lib/lookup.js +0 -62
package/lib/component.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
const ALWAYS_UPDATE = "__";
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* The base component.
|
|
3
5
|
*/
|
|
@@ -8,18 +10,59 @@ export function Component() {
|
|
|
8
10
|
this.ref = {}; // user set references to elements or components.
|
|
9
11
|
// Internal state objects
|
|
10
12
|
this._e = {}; // The dynamic elements in the DOM.
|
|
11
|
-
this._p = {}; // The previous values for watches to compare against.
|
|
12
13
|
this._s = []; // A stash for misc objects.
|
|
14
|
+
this._p = {}; // The previous values for watches to compare against.
|
|
15
|
+
this._r = {}; // The current values read during an update.
|
|
13
16
|
}
|
|
14
17
|
|
|
18
|
+
Component.stubs = {};
|
|
19
|
+
|
|
15
20
|
var proto = Component.prototype;
|
|
16
21
|
|
|
17
22
|
Object.defineProperty(proto, "hidden", {
|
|
18
23
|
set: function (value) {
|
|
19
24
|
this.el.hidden = value;
|
|
20
|
-
}
|
|
25
|
+
}
|
|
21
26
|
});
|
|
22
27
|
|
|
28
|
+
proto._gs = function (name) {
|
|
29
|
+
return this.constructor.stubs[name];
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Reads a query during update, returns an array with (oldValue, newValue, changed)
|
|
34
|
+
* and saves the old value. Must reset this._r before each run.
|
|
35
|
+
*/
|
|
36
|
+
proto._rq = function (props, key) {
|
|
37
|
+
const run = this._r;
|
|
38
|
+
if (run[key] === undefined) {
|
|
39
|
+
let oldValue = this._p[key];
|
|
40
|
+
const newValue = this._q[key](props, this);
|
|
41
|
+
this._p[key] = newValue;
|
|
42
|
+
const rtn = [newValue, oldValue, newValue !== oldValue];
|
|
43
|
+
run[key] = rtn;
|
|
44
|
+
return rtn;
|
|
45
|
+
}
|
|
46
|
+
return run[key];
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Applies the callbacks.
|
|
51
|
+
*/
|
|
52
|
+
proto._ac = function (props, element, callbacks) {
|
|
53
|
+
for (let key in callbacks) {
|
|
54
|
+
let callback = callbacks[key];
|
|
55
|
+
if (key === ALWAYS_UPDATE) {
|
|
56
|
+
callback(element, props, this);
|
|
57
|
+
} else {
|
|
58
|
+
const result = this._rq(props, key);
|
|
59
|
+
if (result[2]) {
|
|
60
|
+
callback(element, props, this, result[0]);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
|
|
23
66
|
/**
|
|
24
67
|
* The render function that gets called by parent components.
|
|
25
68
|
*/
|
|
@@ -40,10 +83,8 @@ proto.update = function () {
|
|
|
40
83
|
parent,
|
|
41
84
|
displayToggle,
|
|
42
85
|
detacher,
|
|
43
|
-
lookupReturn,
|
|
44
86
|
lookupTrue,
|
|
45
87
|
shouldBeVisible,
|
|
46
|
-
visibilityChanged,
|
|
47
88
|
detachedElements,
|
|
48
89
|
detachedElement,
|
|
49
90
|
index,
|
|
@@ -51,11 +92,10 @@ proto.update = function () {
|
|
|
51
92
|
thisElement;
|
|
52
93
|
|
|
53
94
|
const watches = this._w;
|
|
54
|
-
const lookup = this._l;
|
|
55
95
|
const props = this.props;
|
|
56
|
-
lookup.reset();
|
|
57
96
|
const il = watches.length;
|
|
58
|
-
|
|
97
|
+
this._r = {};
|
|
98
|
+
/*
|
|
59
99
|
Watches is an array of objects with keys:
|
|
60
100
|
e: the element reference (string)
|
|
61
101
|
c: the callbacks (object)
|
|
@@ -79,10 +119,8 @@ proto.update = function () {
|
|
|
79
119
|
i++;
|
|
80
120
|
shouldBeVisible = true;
|
|
81
121
|
if (displayToggle) {
|
|
82
|
-
|
|
83
|
-
lookupTrue = !!lookupReturn.n;
|
|
122
|
+
lookupTrue = !!this._rq(props, displayToggle.q)[0];
|
|
84
123
|
shouldBeVisible = displayToggle.r ? lookupTrue : !lookupTrue;
|
|
85
|
-
visibilityChanged = lookupTrue != !!lookupReturn.o;
|
|
86
124
|
detacher = displayToggle.d;
|
|
87
125
|
if (detacher) {
|
|
88
126
|
index = detacher.i;
|
|
@@ -95,10 +133,7 @@ proto.update = function () {
|
|
|
95
133
|
Object.keys(detachedElements).filter(function (k) {
|
|
96
134
|
return k < index && detachedElements[k];
|
|
97
135
|
}).length;
|
|
98
|
-
parent.insertBefore(
|
|
99
|
-
detachedElement,
|
|
100
|
-
parent.childNodes[adjustedIndex],
|
|
101
|
-
);
|
|
136
|
+
parent.insertBefore(detachedElement, parent.childNodes[adjustedIndex]);
|
|
102
137
|
detachedElements[index] = null;
|
|
103
138
|
} else if (!shouldBeVisible && !detachedElement) {
|
|
104
139
|
thisElement = this._e[watch.e];
|
|
@@ -113,7 +148,7 @@ proto.update = function () {
|
|
|
113
148
|
}
|
|
114
149
|
}
|
|
115
150
|
if (shouldBeVisible) {
|
|
116
|
-
|
|
151
|
+
this._ac(props, element, watch.c);
|
|
117
152
|
}
|
|
118
153
|
}
|
|
119
154
|
};
|
package/lib/index.js
CHANGED
|
@@ -1,26 +1,22 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { mount, watch } from "./utils";
|
|
2
2
|
import { Component } from "./component";
|
|
3
3
|
import { KeyedRepeater, SequentialRepeater } from "./repeaters";
|
|
4
4
|
import {
|
|
5
5
|
extendComponent,
|
|
6
|
+
defineComponent,
|
|
6
7
|
findElement,
|
|
7
8
|
getKeyedRepeater,
|
|
8
9
|
getSequentialRepeater,
|
|
9
10
|
onEvent,
|
|
10
11
|
nestComponent,
|
|
11
|
-
defineComponent,
|
|
12
|
-
extendPrototype,
|
|
13
|
-
stashMisc,
|
|
14
12
|
saveRef,
|
|
13
|
+
stashMisc
|
|
15
14
|
} from "./initCalls";
|
|
16
15
|
|
|
17
16
|
export {
|
|
18
|
-
extendComponent,
|
|
19
17
|
Component,
|
|
20
|
-
createComponent,
|
|
21
|
-
watch,
|
|
22
18
|
defineComponent,
|
|
23
|
-
|
|
19
|
+
extendComponent,
|
|
24
20
|
findElement,
|
|
25
21
|
getKeyedRepeater,
|
|
26
22
|
getSequentialRepeater,
|
|
@@ -28,7 +24,8 @@ export {
|
|
|
28
24
|
mount,
|
|
29
25
|
nestComponent,
|
|
30
26
|
onEvent,
|
|
31
|
-
stashMisc,
|
|
32
27
|
saveRef,
|
|
33
28
|
SequentialRepeater,
|
|
29
|
+
stashMisc,
|
|
30
|
+
watch
|
|
34
31
|
};
|
package/lib/initCalls.js
CHANGED
|
@@ -1,103 +1,92 @@
|
|
|
1
1
|
import { Component } from "./component";
|
|
2
|
-
import { Lookup } from "./lookup";
|
|
3
2
|
import { buildComponent, replaceNode } from "./utils";
|
|
4
3
|
import { KeyedRepeater, SequentialRepeater } from "./repeaters";
|
|
5
4
|
const throwAway = document.createElement("template");
|
|
6
5
|
|
|
7
6
|
/**
|
|
8
|
-
* Create an element from html string
|
|
7
|
+
* Create an element from html string.
|
|
9
8
|
*/
|
|
10
9
|
function makeEl(html) {
|
|
11
10
|
throwAway.innerHTML = html;
|
|
12
11
|
return throwAway.content.firstChild;
|
|
13
12
|
}
|
|
14
13
|
|
|
15
|
-
export
|
|
16
|
-
return component.props;
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
export const findElement = (rootElement, path) => {
|
|
14
|
+
export function findElement(rootElement, path) {
|
|
20
15
|
return path.reduce((acc, index) => acc.childNodes[index], rootElement);
|
|
21
|
-
}
|
|
16
|
+
}
|
|
22
17
|
|
|
23
|
-
export
|
|
18
|
+
export function nestComponent(rootElement, path, cls) {
|
|
24
19
|
const el = findElement(rootElement, path),
|
|
25
20
|
child = buildComponent(cls);
|
|
26
21
|
replaceNode(el, child.el);
|
|
27
22
|
return child;
|
|
28
|
-
}
|
|
23
|
+
}
|
|
29
24
|
|
|
30
25
|
/**
|
|
31
26
|
* Saves a reference to element or nested component. Returns the element.
|
|
32
27
|
*/
|
|
33
|
-
export
|
|
28
|
+
export function saveRef(element, component, name) {
|
|
34
29
|
component.ref[name] = element;
|
|
35
30
|
return element;
|
|
36
|
-
}
|
|
31
|
+
}
|
|
37
32
|
|
|
38
33
|
/**
|
|
39
34
|
* Stash something on the component. Returns the element.
|
|
40
35
|
* The generated code is expected to keep track of the position.
|
|
41
36
|
*/
|
|
42
|
-
export
|
|
37
|
+
export function stashMisc(element, component, object) {
|
|
43
38
|
component._s.push(object);
|
|
44
39
|
return element;
|
|
45
|
-
}
|
|
40
|
+
}
|
|
46
41
|
|
|
47
|
-
export
|
|
42
|
+
export function onEvent(element, eventName, callback) {
|
|
48
43
|
element.addEventListener(eventName, callback);
|
|
49
44
|
return element;
|
|
50
|
-
}
|
|
45
|
+
}
|
|
51
46
|
|
|
52
|
-
export
|
|
47
|
+
export function getKeyedRepeater(cls, keyFn) {
|
|
53
48
|
return new KeyedRepeater(cls, keyFn);
|
|
54
|
-
}
|
|
49
|
+
}
|
|
55
50
|
|
|
56
|
-
export
|
|
51
|
+
export function getSequentialRepeater(cls) {
|
|
57
52
|
return new SequentialRepeater(cls);
|
|
58
|
-
}
|
|
53
|
+
}
|
|
59
54
|
|
|
60
|
-
export function
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
prototypeExtras,
|
|
67
|
-
) {
|
|
68
|
-
const Constructor = extendPrototype(
|
|
69
|
-
inheritFrom || Component,
|
|
70
|
-
prototypeExtras,
|
|
71
|
-
);
|
|
72
|
-
extendComponent(Constructor.prototype, html, watches, lookups, buildFunction);
|
|
73
|
-
return Constructor;
|
|
55
|
+
export function extendComponent(base, componentDef) {
|
|
56
|
+
// This function call will have been replaced if 2nd arg is a valid component func.
|
|
57
|
+
// and therefor we would not receive it.
|
|
58
|
+
if (componentDef)
|
|
59
|
+
throw new Error("2nd arg to extendComponent must be a JSX arrow function");
|
|
60
|
+
return _createConstructor(base);
|
|
74
61
|
}
|
|
75
62
|
|
|
76
|
-
export function
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
watches,
|
|
80
|
-
lookups,
|
|
81
|
-
buildFunction,
|
|
82
|
-
) {
|
|
63
|
+
export function defineComponent(html, watches, queries, buildFunction, inheritFrom) {
|
|
64
|
+
const ComponentDefinition = _createConstructor(inheritFrom || Component);
|
|
65
|
+
const prototype = ComponentDefinition.prototype;
|
|
83
66
|
//Ensure these do not clash with fields on the component itself.
|
|
84
67
|
prototype._w = watches;
|
|
85
|
-
prototype.
|
|
68
|
+
prototype._q = queries;
|
|
86
69
|
prototype._b = buildFunction;
|
|
87
70
|
prototype._n = makeEl(html);
|
|
71
|
+
return ComponentDefinition;
|
|
88
72
|
}
|
|
89
73
|
|
|
90
|
-
|
|
91
|
-
const
|
|
74
|
+
function _createConstructor(base) {
|
|
75
|
+
const ComponentDefinition = function () {
|
|
92
76
|
base.call(this);
|
|
93
77
|
};
|
|
94
|
-
|
|
78
|
+
ComponentDefinition.stubs = {};
|
|
79
|
+
Object.assign(ComponentDefinition.stubs, base.stubs);
|
|
80
|
+
// This is a helper function for the user.
|
|
81
|
+
ComponentDefinition.methods = function (obj) {
|
|
82
|
+
Object.assign(ComponentDefinition.prototype, obj);
|
|
83
|
+
};
|
|
84
|
+
ComponentDefinition.prototype = Object.create(base && base.prototype, {
|
|
95
85
|
constructor: {
|
|
96
|
-
value:
|
|
86
|
+
value: ComponentDefinition,
|
|
97
87
|
writable: true,
|
|
98
|
-
configurable: true
|
|
99
|
-
}
|
|
88
|
+
configurable: true
|
|
89
|
+
}
|
|
100
90
|
});
|
|
101
|
-
|
|
102
|
-
return Constructor;
|
|
91
|
+
return ComponentDefinition;
|
|
103
92
|
}
|
package/lib/repeaters.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { buildComponent } from "./utils";
|
|
2
2
|
|
|
3
3
|
/*
|
|
4
4
|
* Gets a component from the pool.
|
|
@@ -7,11 +7,11 @@ function getComponent(pool, componentDefinition, ctrl, key, props) {
|
|
|
7
7
|
let component;
|
|
8
8
|
if (pool.hasOwnProperty(key)) {
|
|
9
9
|
component = pool[key];
|
|
10
|
-
component.render(props, ctrl);
|
|
11
10
|
} else {
|
|
12
|
-
component =
|
|
11
|
+
component = buildComponent(componentDefinition);
|
|
13
12
|
pool[key] = component;
|
|
14
13
|
}
|
|
14
|
+
component.render(props, ctrl);
|
|
15
15
|
return component;
|
|
16
16
|
}
|
|
17
17
|
|
|
@@ -50,10 +50,10 @@ function pull(arr, item, to) {
|
|
|
50
50
|
* @param {function} keyFn - A function which obtains the key.
|
|
51
51
|
*/
|
|
52
52
|
export function KeyedRepeater(componentDefinition, keyFn) {
|
|
53
|
-
this.
|
|
54
|
-
this.
|
|
55
|
-
this.
|
|
56
|
-
this.
|
|
53
|
+
this.def = componentDefinition;
|
|
54
|
+
this.keyFn = keyFn;
|
|
55
|
+
this.keys = []; // keys
|
|
56
|
+
this.pool = {}; // pool of component instances
|
|
57
57
|
}
|
|
58
58
|
const proto = KeyedRepeater.prototype;
|
|
59
59
|
|
|
@@ -64,7 +64,7 @@ const proto = KeyedRepeater.prototype;
|
|
|
64
64
|
* @param {Object} item - The item which will be passed as props.
|
|
65
65
|
*/
|
|
66
66
|
proto.getOne = function (item, ctrl) {
|
|
67
|
-
return getComponent(this.
|
|
67
|
+
return getComponent(this.pool, this.def, ctrl, this.keyFn(item), item);
|
|
68
68
|
};
|
|
69
69
|
|
|
70
70
|
/**
|
|
@@ -77,12 +77,12 @@ proto.getOne = function (item, ctrl) {
|
|
|
77
77
|
proto.patch = function (e, items, ctrl) {
|
|
78
78
|
// Attempt to speed up by reducing lookups. Does this even do anything?
|
|
79
79
|
// Does webpack undo this/do it for for me? Does the engine?
|
|
80
|
-
const pool = this.
|
|
81
|
-
const componentDefinition = this.
|
|
82
|
-
const keyFn = this.
|
|
80
|
+
const pool = this.pool;
|
|
81
|
+
const componentDefinition = this.def;
|
|
82
|
+
const keyFn = this.keyFn;
|
|
83
83
|
const childNodes = e.childNodes;
|
|
84
84
|
const itemsLength = items.length;
|
|
85
|
-
const oldKeySequence = this.
|
|
85
|
+
const oldKeySequence = this.keys;
|
|
86
86
|
const newKeys = [];
|
|
87
87
|
let item,
|
|
88
88
|
key,
|
|
@@ -100,7 +100,7 @@ proto.patch = function (e, items, ctrl) {
|
|
|
100
100
|
pull(oldKeySequence, key, i);
|
|
101
101
|
}
|
|
102
102
|
}
|
|
103
|
-
this.
|
|
103
|
+
this.keys = newKeys;
|
|
104
104
|
trimChildren(e, childNodes, itemsLength);
|
|
105
105
|
};
|
|
106
106
|
|
|
@@ -110,9 +110,9 @@ proto.patch = function (e, items, ctrl) {
|
|
|
110
110
|
* @param {componentDefinition} componentDefinition - The class ComponentDefinition to create.
|
|
111
111
|
*/
|
|
112
112
|
export function SequentialRepeater(componentDefinition) {
|
|
113
|
-
this.
|
|
114
|
-
this.
|
|
115
|
-
this.
|
|
113
|
+
this.def = componentDefinition;
|
|
114
|
+
this.pool = []; // pool of component instances
|
|
115
|
+
this.count = 0; // Child element count
|
|
116
116
|
}
|
|
117
117
|
|
|
118
118
|
/**
|
|
@@ -124,29 +124,27 @@ export function SequentialRepeater(componentDefinition) {
|
|
|
124
124
|
* @param {any} ctrl - The parent item's controller.
|
|
125
125
|
*/
|
|
126
126
|
SequentialRepeater.prototype.patch = function (e, items, ctrl) {
|
|
127
|
-
const pool = this.
|
|
128
|
-
const componentDefinition = this.
|
|
127
|
+
const pool = this.pool;
|
|
128
|
+
const componentDefinition = this.def;
|
|
129
129
|
const childNodes = e.childNodes;
|
|
130
130
|
const itemsLength = items.length;
|
|
131
|
-
let
|
|
132
|
-
component,
|
|
131
|
+
let component,
|
|
133
132
|
poolCount = pool.length,
|
|
134
|
-
childElementCount = this.
|
|
133
|
+
childElementCount = this.count;
|
|
135
134
|
|
|
136
135
|
for (let i = 0; i < itemsLength; i++) {
|
|
137
|
-
item = items[i];
|
|
138
136
|
if (i < poolCount) {
|
|
139
137
|
component = pool[i];
|
|
140
|
-
component.render(item, ctrl);
|
|
141
138
|
} else {
|
|
142
|
-
component =
|
|
139
|
+
component = buildComponent(componentDefinition);
|
|
143
140
|
pool.push(component);
|
|
144
141
|
poolCount++;
|
|
145
142
|
}
|
|
143
|
+
component.render(items[i], ctrl);
|
|
146
144
|
if (i >= childElementCount) {
|
|
147
145
|
e.appendChild(component.el);
|
|
148
146
|
}
|
|
149
147
|
}
|
|
150
|
-
this.
|
|
148
|
+
this.count = itemsLength;
|
|
151
149
|
trimChildren(e, childNodes, itemsLength);
|
|
152
150
|
};
|