wallace 0.11.0 → 0.12.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 CHANGED
@@ -2,22 +2,33 @@ const throwAway = document.createElement("template");
2
2
  const NO_LOOKUP = "__";
3
3
 
4
4
  const ComponentPrototype = {
5
- /**
6
- * The render function that gets called by parent components.
7
- */
5
+ /*
6
+ COMPILER_MODS:
7
+ if useController is false:
8
+ - param `ctrl` is removed.
9
+ - `this.ctrl = ctrl` is removed.
10
+ */
8
11
  render: function (props, ctrl) {
9
12
  this.props = props;
10
13
  this.ctrl = ctrl;
11
14
  this.update();
12
15
  },
13
16
 
14
- /**
15
- * Updates the DOM and renders nested components.
16
- */
17
+ /*
18
+ COMPILER_MODS:
19
+ if useFlags is false this is deleted.
20
+ */
17
21
  update: function () {
18
22
  this._u(0, this._l);
19
23
  },
20
24
 
25
+ /*
26
+ COMPILER_MODS:
27
+ if useFlags is false:
28
+ - gets renamed to `update`
29
+ - parameters are removed
30
+ - add `i = 0, il = this._l` to variable declarator.
31
+ */
21
32
  _u: function (i, il) {
22
33
  let watch,
23
34
  element,
@@ -147,6 +158,21 @@ export function initConstructor(ComponentFunction, BaseComponentFunction) {
147
158
  return proto;
148
159
  }
149
160
  });
161
+ } else {
162
+ if (process.env.NODE_ENV !== "production") {
163
+ Object.defineProperty(ComponentFunction, "name", {
164
+ set: function (value) {
165
+ throw new Error(
166
+ 'Flag "useMethods" must be set to true in the config for this feature.'
167
+ );
168
+ },
169
+ get: function () {
170
+ throw new Error(
171
+ 'Flag "useMethods" must be set to true in the config for this feature.'
172
+ );
173
+ }
174
+ });
175
+ }
150
176
  }
151
177
 
152
178
  if (wallaceConfig.flags.useStubs) {
@@ -163,6 +189,24 @@ export function defineComponent(html, watches, queries, contructor, inheritFrom)
163
189
  proto._w = watches;
164
190
  proto._q = queries;
165
191
  proto._t = throwAway.content.firstChild;
166
- proto.base = ComponentPrototype;
192
+ if (wallaceConfig.flags.useBase) {
193
+ proto.base = ComponentPrototype;
194
+ } else {
195
+ if (process.env.NODE_ENV !== "production") {
196
+ Object.defineProperty(proto, "base", {
197
+ set: function (value) {
198
+ throw new Error(
199
+ 'Flag "useBase" must be set to true in the config for this feature.'
200
+ );
201
+ },
202
+ get: function () {
203
+ throw new Error(
204
+ 'Flag "useBase" must be set to true in the config for this feature.'
205
+ );
206
+ }
207
+ });
208
+ }
209
+ }
210
+
167
211
  return ComponentDefinition;
168
212
  }
package/lib/index.js CHANGED
@@ -6,6 +6,7 @@ export { nestComponent } from "./nestComponent";
6
6
  export { saveRef } from "./refs";
7
7
  export { savePart } from "./part";
8
8
  export { KeyedRepeater } from "./repeaters/keyed";
9
+ export { KeyedFnRepeater } from "./repeaters/keyedFn";
9
10
  export { SequentialRepeater } from "./repeaters/sequential";
10
11
  export { Router, route } from "./router";
11
12
  export { getStub } from "./stubs";
@@ -1,12 +1,14 @@
1
+ // WARNING: Code here is near duplicated in keyedFn.
2
+
1
3
  /**
2
4
  * Repeats nested components, reusing items based on key.
3
5
  *
4
6
  * @param {function} componentDefinition - The ComponentDefinition to create.
5
- * @param {function} keyFn - A function which obtains the key.
7
+ * @param {string} keyName - The name of the key property.
6
8
  */
7
- export function KeyedRepeater(componentDefinition, keyFn) {
9
+ export function KeyedRepeater(componentDefinition, keyName) {
8
10
  this.def = componentDefinition;
9
- this.keyFn = keyFn;
11
+ this.keyName = keyName;
10
12
  this.keys = []; // array of keys as last set.
11
13
  this.pool = {}; // pool of component instances.
12
14
  }
@@ -22,7 +24,7 @@ export function KeyedRepeater(componentDefinition, keyFn) {
22
24
  KeyedRepeater.prototype.patch = function (e, items, ctrl) {
23
25
  const pool = this.pool,
24
26
  componentDefinition = this.def,
25
- keyFn = this.keyFn,
27
+ keyName = this.keyName,
26
28
  childNodes = e.childNodes,
27
29
  itemsLength = items.length,
28
30
  previousKeys = this.keys,
@@ -44,7 +46,7 @@ KeyedRepeater.prototype.patch = function (e, items, ctrl) {
44
46
  const frag = document.createDocumentFragment();
45
47
  while (i >= 0) {
46
48
  item = items[i];
47
- key = keyFn(item);
49
+ key = item[keyName];
48
50
  component = pool[key] || (pool[key] = new componentDefinition());
49
51
  component.render(item, ctrl);
50
52
  el = component.el;
@@ -0,0 +1,81 @@
1
+ // WARNING: Code here is near duplicated in keyedFn.
2
+
3
+ /**
4
+ * Repeats nested components, reusing items based on key.
5
+ *
6
+ * @param {function} componentDefinition - The ComponentDefinition to create.
7
+ * @param {function} keyFn - A function which obtains the key.
8
+ */
9
+ export function KeyedFnRepeater(componentDefinition, keyFn) {
10
+ this.def = componentDefinition;
11
+ this.keyFn = keyFn;
12
+ this.keys = []; // array of keys as last set.
13
+ this.pool = {}; // pool of component instances.
14
+ }
15
+
16
+ /**
17
+ * Updates the element's childNodes to match the items.
18
+ * Performance is important.
19
+ *
20
+ * @param {DOMElement} e - The DOM element to patch.
21
+ * @param {Array} items - Array of items which will be passed as props.
22
+ * @param {any} ctrl - The parent item's controller.
23
+ */
24
+ KeyedFnRepeater.prototype.patch = function (e, items, ctrl) {
25
+ const pool = this.pool,
26
+ componentDefinition = this.def,
27
+ keyFn = this.keyFn,
28
+ childNodes = e.childNodes,
29
+ itemsLength = items.length,
30
+ previousKeys = this.keys,
31
+ previousKeysLength = previousKeys.length,
32
+ newKeys = [],
33
+ previousKeysSet = new Set(previousKeys);
34
+ let item,
35
+ el,
36
+ key,
37
+ component,
38
+ anchor = null,
39
+ fragAnchor = null,
40
+ untouched = true,
41
+ append = false,
42
+ offset = previousKeysLength - itemsLength,
43
+ i = itemsLength - 1;
44
+
45
+ // Working backwards saves us having to track moves.
46
+ const frag = document.createDocumentFragment();
47
+ while (i >= 0) {
48
+ item = items[i];
49
+ key = keyFn(item);
50
+ component = pool[key] || (pool[key] = new componentDefinition());
51
+ component.render(item, ctrl);
52
+ el = component.el;
53
+ if (untouched && !previousKeysSet.has(key)) {
54
+ frag.insertBefore(el, fragAnchor);
55
+ fragAnchor = el;
56
+ append = true;
57
+ offset++;
58
+ } else {
59
+ if (key !== previousKeys[i + offset]) {
60
+ e.insertBefore(el, anchor);
61
+ untouched = false;
62
+ }
63
+ anchor = el;
64
+ }
65
+ newKeys.push(key);
66
+ previousKeysSet.delete(key);
67
+ i--;
68
+ }
69
+
70
+ if (append) {
71
+ e.appendChild(frag);
72
+ }
73
+
74
+ let toStrip = previousKeysSet.size;
75
+ while (toStrip > 0) {
76
+ e.removeChild(childNodes[0]);
77
+ toStrip--;
78
+ }
79
+
80
+ this.keys = newKeys.reverse();
81
+ };
@@ -43,7 +43,7 @@ SequentialRepeater.prototype.patch = function (e, items, ctrl) {
43
43
  }
44
44
  this.count = itemsLength;
45
45
  let lastIndex = childNodes.length - 1;
46
- let keepIndex = itemsLength - 1;
46
+ const keepIndex = itemsLength - 1;
47
47
  for (let i = lastIndex; i > keepIndex; i--) {
48
48
  e.removeChild(childNodes[i]);
49
49
  }
package/lib/types.d.ts CHANGED
@@ -8,7 +8,6 @@
8
8
 
9
9
  ### Contents
10
10
 
11
- 0. Configuration
12
11
  1. Components
13
12
  2. JSX
14
13
  3. Nesting
@@ -19,43 +18,11 @@
19
18
  8. Stubs
20
19
  9. TypeScript
21
20
  10. Helpers
21
+ 11. Flags
22
22
 
23
23
  For more detailed documentation go to https://wallace.js.org/docs/
24
24
 
25
25
 
26
- ## 0. Configuration
27
-
28
- You need to set flags in your babel config to use certain features:
29
-
30
- 1. useControllers - enables use of `ctrl` in components.
31
- 2. useMethods - adds the `methods` helper to components.
32
- 3. useStubs - enables the use of stubs.
33
-
34
- The types (and therefore tool tips) are unaffected by these flags, and will treat them
35
- all as being true.
36
-
37
- ```tsx
38
- module.exports = {
39
- plugins: [
40
- [
41
- "babel-plugin-wallace",
42
- {
43
- flags: {
44
- useControllers: true,
45
- useMethods: true,
46
- useStubs: true
47
- },
48
- directives: [...]
49
- }
50
- ],
51
- "@babel/plugin-syntax-jsx"
52
- ],
53
- presets: ["@babel/preset-typescript", ...]
54
- };
55
- ```
56
-
57
- The `directives` option lets you override or define new directives. See main docs.
58
-
59
26
  ## 1. Components
60
27
 
61
28
  ### 1.1 Defining
@@ -554,6 +521,42 @@ const protectedObj = protect([]);
554
521
  watchedObj[0] = 'foo'; // throws error.
555
522
  ```
556
523
 
524
+ ## 11. Flags
525
+
526
+ You can toggle flags in your babel config to disable certain features for cutting edge
527
+ performance and bundle size:
528
+
529
+ 1. useBase - enables use of `base` in components.
530
+ 2. useControllers - enables use of `ctrl` in components.
531
+ 3. useMethods - adds the `methods` helper to components.
532
+ 4. useParts - enables use of parts.
533
+ 5. useStubs - enables the use of stubs.
534
+
535
+ These flags default to true, unless you specify `flags` in the plugin config, in which
536
+ case they default to false and you need to explicitly enable those you want:
537
+
538
+
539
+ ```tsx
540
+ module.exports = {
541
+ plugins: [
542
+ [
543
+ "babel-plugin-wallace",
544
+ {
545
+ flags: {
546
+ useControllers: true,
547
+ useStubs: false
548
+ },
549
+ }
550
+ ],
551
+ "@babel/plugin-syntax-jsx"
552
+ ],
553
+ presets: ["@babel/preset-typescript", ...]
554
+ };
555
+ ```
556
+
557
+ The types (and therefore tool tips) are unaffected by these flags, and will treat them
558
+ all as being true.
559
+
557
560
  ---
558
561
  Report any issues to https://github.com/wallace-js/wallace (and please give it a ★)
559
562
 
@@ -585,19 +588,18 @@ declare module "wallace" {
585
588
  hide
586
589
  }: {
587
590
  props?: Props;
591
+ ctrl?: Controller;
588
592
  show?: boolean;
589
593
  hide?: boolean;
590
594
  }): JSX.Element;
591
595
  repeat?({
592
596
  items,
593
- key,
594
- show,
595
- hide
597
+ ctrl,
598
+ key
596
599
  }: {
597
600
  items: Array<Props>;
601
+ ctrl?: Controller;
598
602
  key?: string | ((item: Props) => any);
599
- show?: boolean;
600
- hide?: boolean;
601
603
  }): JSX.Element;
602
604
  methods?: ComponenMethods<Props, Controller> &
603
605
  ThisType<ComponentInstance<Props, Controller, Methods>>;
@@ -751,7 +753,7 @@ declare module "wallace" {
751
753
  type WatchCallback = (target: any, key: string, value: any) => void;
752
754
 
753
755
  /**
754
- * Returns a Proxy of an object which calls `callback` when it, or its nested objects
756
+ * Returns a Proxy of the target which calls `callback` when it, or its nested objects
755
757
  * are modified:
756
758
  *
757
759
  * ```js
@@ -764,6 +766,9 @@ declare module "wallace" {
764
766
  * obj.y = {}
765
767
  * obj.y.z = 1000
766
768
  * ```
769
+ *
770
+ * The original object is also modified.
771
+ *
767
772
  * The callback accepts parameters:
768
773
  *
769
774
  * - `target` - the object which is being modified.
@@ -772,10 +777,6 @@ declare module "wallace" {
772
777
  *
773
778
  * The callback is called after the modification has occured.
774
779
  *
775
- * Some methods like `Array.push` set the index and then the length immediately after,
776
- * so we use a timeout period to avoid calling the callback twice for what is really a
777
- * single operation.
778
- *
779
780
  * @param {*} target - Any object, including arrays.
780
781
  * @param {*} callback - A callback function.
781
782
  * @returns a Proxy of the object.
@@ -911,6 +912,17 @@ interface DirectiveAttributes extends AllDomEvents {
911
912
  */
912
913
  css?: string;
913
914
 
915
+ /**
916
+ * ## Wallace directive: ctrl
917
+ *
918
+ * Specifies ctrl for nested/repeated components.
919
+ *
920
+ * ```
921
+ * <MyComponent.nest ctrl={aController} />
922
+ * ```
923
+ */
924
+ ctrl?: any;
925
+
914
926
  /**
915
927
  * ## Wallace directive: fixed
916
928
  *
@@ -1074,21 +1086,22 @@ declare namespace JSX {
1074
1086
  * - `bind` updates a value when an input is changed.
1075
1087
  * - `class:xyz` defines a set of classes to be toggled.
1076
1088
  * - `css` shorthand for `fixed:class`.
1089
+ * - `ctrl` specifies ctrl for nested/repeated components.
1077
1090
  * - `fixed:xyz` sets a attribute from an expression at definition.
1078
1091
  * - `hide` sets an element or component's hidden property.
1079
1092
  * - `html` Set the element's `innnerHTML` property.
1080
1093
  * - `if` excludes an element from the DOM.
1081
1094
  * - `key` specifies a key for repeated items.
1082
1095
  * - `items` set items for repeated component, must be an array of props.
1083
- * - `on[EventName]` creates an event handler (note the code is copied)
1084
- * - `part:xyz` saves a reference to part of a component so it can be updated
1085
- * - `props` specifes props for a nested components.
1086
- * - `ref:xyz` saves a reference to an element or nested omponent.
1096
+ * - `on[EventName]` creates an event handler (note the code is copied).
1097
+ * - `part:xyz` saves a reference to part of a component so it can be updated.
1098
+ * - `props` specifies props for a nested components.
1099
+ * - `ref:xyz` saves a reference to an element or nested component.
1087
1100
  * - `show` sets and element or component's hidden property.
1088
1101
  * - `style:xyz` sets a specific style property.
1089
1102
  * - `toggle:xyz` toggles `xyz` as defined by `class:xyz` on same element, or class
1090
1103
  * `xyz`.
1091
- * - `unique` can be set on components which only used once for better performance.
1104
+ * - `unique` can be set on components which are only used once for better performance.
1092
1105
  *
1093
1106
  * You will get more details by hovering on the directive itself, but unfortunetely
1094
1107
  * the tool tip won't display when you use a qualifier, like `class:danger`. To see
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wallace",
3
- "version": "0.11.0",
3
+ "version": "0.12.0",
4
4
  "author": "Andrew Buchan",
5
5
  "description": "An insanely small, fast, intuitive and extendable front-end framework",
6
6
  "homepage": "https://wallace.js.org",
@@ -15,8 +15,8 @@
15
15
  "test": "jest --clearCache && jest"
16
16
  },
17
17
  "dependencies": {
18
- "babel-plugin-wallace": "^0.11.0",
18
+ "babel-plugin-wallace": "^0.12.0",
19
19
  "browserify": "^17.0.1"
20
20
  },
21
- "gitHead": "f145fe3b852025e2c851c27d75e7a104c5ec2bda"
21
+ "gitHead": "bbaf61dd2313ba947efc3f35580626ca6f71fc84"
22
22
  }