neo.mjs 8.0.0-alpha.1 → 8.0.0-alpha.2

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.
@@ -20,9 +20,9 @@ class ServiceWorker extends ServiceBase {
20
20
  */
21
21
  singleton: true,
22
22
  /**
23
- * @member {String} version='8.0.0-alpha.1'
23
+ * @member {String} version='8.0.0-alpha.2'
24
24
  */
25
- version: '8.0.0-alpha.1'
25
+ version: '8.0.0-alpha.2'
26
26
  }
27
27
 
28
28
  /**
@@ -111,7 +111,7 @@ class FooterContainer extends Container {
111
111
  }, {
112
112
  module: Component,
113
113
  cls : ['neo-version'],
114
- html : 'v8.0.0-alpha.1'
114
+ html : 'v8.0.0-alpha.2'
115
115
  }]
116
116
  }],
117
117
  /**
@@ -20,9 +20,9 @@ class ServiceWorker extends ServiceBase {
20
20
  */
21
21
  singleton: true,
22
22
  /**
23
- * @member {String} version='8.0.0-alpha.1'
23
+ * @member {String} version='8.0.0-alpha.2'
24
24
  */
25
- version: '8.0.0-alpha.1'
25
+ version: '8.0.0-alpha.2'
26
26
  }
27
27
 
28
28
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "neo.mjs",
3
- "version": "8.0.0-alpha.1",
3
+ "version": "8.0.0-alpha.2",
4
4
  "description": "The webworkers driven UI framework",
5
5
  "type": "module",
6
6
  "repository": {
@@ -55,11 +55,11 @@
55
55
  "fs-extra": "^11.2.0",
56
56
  "highlightjs-line-numbers.js": "^2.9.0",
57
57
  "inquirer": "^12.0.1",
58
- "marked": "^14.1.4",
58
+ "marked": "^15.0.0",
59
59
  "monaco-editor": "0.50.0",
60
60
  "neo-jsdoc": "1.0.1",
61
61
  "neo-jsdoc-x": "1.0.5",
62
- "postcss": "^8.4.47",
62
+ "postcss": "^8.4.48",
63
63
  "sass": "^1.80.6",
64
64
  "siesta-lite": "5.5.2",
65
65
  "url": "^0.11.4",
@@ -21,9 +21,10 @@ If you move quickly, you might reach 20,000 or 30,000 delta updates per second.
21
21
  second — but we've never actually hit the limit.
22
22
 
23
23
  <pre data-neo>
24
- import Base from '../container/Base.mjs';
24
+ import Base from '../container/Base.mjs';
25
25
  import Helix from '../component/Helix.mjs';
26
- class Foo extends Base {
26
+
27
+ class MainView extends Base {
27
28
  static config = {
28
29
  className: 'Benefits.speed.MainView',
29
30
  layout : 'fit',
@@ -34,14 +35,14 @@ class Foo extends Base {
34
35
  store: {
35
36
  autoLoad: true,
36
37
  model: {
37
- fields: [ { name: 'image' , type: 'String' } ],
38
+ fields: [{name: 'image', type: 'String'}],
38
39
  },
39
40
  url: '../../../../resources/examples/data/ai_contacts.json'
40
41
  }
41
42
  }]
42
43
  }
43
44
  }
44
- Foo = Neo.setupClass(Foo);
45
+ MainView = Neo.setupClass(MainView);
45
46
  </pre>
46
47
 
47
48
 
@@ -84,6 +84,12 @@
84
84
  top .4s ease-out,
85
85
  width .4s ease-out;
86
86
 
87
+ &.neo-dragproxy {
88
+ > * {
89
+ height: unset;
90
+ }
91
+ }
92
+
87
93
  &.neo-focus {
88
94
  color : #fff;
89
95
  outline: 0;
@@ -163,6 +163,7 @@
163
163
  flex : 1;
164
164
  font-weight : bold;
165
165
  justify-content: end;
166
+ padding-bottom : 1px;
166
167
  }
167
168
 
168
169
  .neo-year-text {
@@ -262,12 +262,12 @@ const DefaultConfig = {
262
262
  useVdomWorker: true,
263
263
  /**
264
264
  * buildScripts/injectPackageVersion.mjs will update this value
265
- * @default '8.0.0-alpha.1'
265
+ * @default '8.0.0-alpha.2'
266
266
  * @memberOf! module:Neo
267
267
  * @name config.version
268
268
  * @type String
269
269
  */
270
- version: '8.0.0-alpha.1'
270
+ version: '8.0.0-alpha.2'
271
271
  };
272
272
 
273
273
  Object.assign(DefaultConfig, {
@@ -259,6 +259,9 @@ class MainContainer extends Container {
259
259
  style = sideBar.style || {};
260
260
 
261
261
  if (value) {
262
+ me.updateDepth = -1;
263
+
264
+ // todo: updates colliding with parent updates need to pass the update depth for the next parent update cycle
262
265
  delete sideBar.vdom.removeDom;
263
266
 
264
267
  me.promiseUpdate().then(() => {
@@ -274,7 +277,7 @@ class MainContainer extends Container {
274
277
  sideBar._style = style; // silent update
275
278
  sideBar._vdom.style = style; // silent update
276
279
 
277
- me.promiseUpdate().then(() => {
280
+ sideBar.promiseUpdate().then(() => {
278
281
  me.timeout(400).then(() => {
279
282
  sideBar.vdom.removeDom = true;
280
283
  sideBar.update();
@@ -224,9 +224,6 @@ class YearComponent extends Component {
224
224
 
225
225
  if (year !== oldYear) {
226
226
  this.changeYear(year - oldYear)
227
- } else {
228
- // todo
229
- console.log('## select a new day', value.getMonth(), value.getDate())
230
227
  }
231
228
  }
232
229
  }
@@ -150,6 +150,14 @@ class List extends ComponentList {
150
150
  onSelect(items) {
151
151
  this.getModel().setData('activeCalendarId', this.getItemRecordId(items[0]))
152
152
  }
153
+
154
+ /**
155
+ * Disabling the super class logic for now, since the collection.Base mutation event already covers the sorting
156
+ * @param {Object} data
157
+ */
158
+ sortItems(data) {
159
+
160
+ }
153
161
  }
154
162
 
155
163
  export default Neo.setupClass(List);
@@ -208,10 +208,10 @@ class Base extends CoreBase {
208
208
  isLoading_: false,
209
209
  /**
210
210
  * Internal flag which will get set to true while an update request (worker messages) is in progress
211
- * @member {Boolean} isVdomUpdating=false
211
+ * @member {Boolean} isVdomUpdating_=false
212
212
  * @protected
213
213
  */
214
- isVdomUpdating: false,
214
+ isVdomUpdating_: false,
215
215
  /**
216
216
  * Using the keys config will create an instance of Neo.util.KeyNavigation.
217
217
  * @see {@link Neo.util.KeyNavigation KeyNavigation}
@@ -404,6 +404,11 @@ class Base extends CoreBase {
404
404
  * @member {String[]} childUpdateCache=[]
405
405
  */
406
406
  childUpdateCache = []
407
+ /**
408
+ * Stores the updateDepth while an update is running to enable checks for parent update collisions
409
+ * @member {Number|null} currentUpdateDepth=null
410
+ */
411
+ currentUpdateDepth = null
407
412
  /**
408
413
  * @member {Function[]} resolveUpdateCache=[]
409
414
  */
@@ -767,6 +772,16 @@ class Base extends CoreBase {
767
772
  }
768
773
  }
769
774
 
775
+ /**
776
+ * Triggered after the isVdomUpdating config got changed
777
+ * @param {Number|null} value
778
+ * @param {Number|null} oldValue
779
+ * @protected
780
+ */
781
+ afterSetIsVdomUpdating(value, oldValue) {
782
+ this.currentUpdateDepth = value ? this.updateDepth : null
783
+ }
784
+
770
785
  /**
771
786
  * Triggered after the maxHeight config got changed
772
787
  * @param {Number|String|null} value
@@ -1830,6 +1845,16 @@ class Base extends CoreBase {
1830
1845
  return this.vnode
1831
1846
  }
1832
1847
 
1848
+ /**
1849
+ * Checks if a given updateDepth & distance would result in an update collision
1850
+ * @param {Number} updateDepth
1851
+ * @param {Number} distance
1852
+ * @returns {Boolean}
1853
+ */
1854
+ hasUpdateCollision(updateDepth, distance) {
1855
+ return updateDepth === -1 ? true : distance < updateDepth
1856
+ }
1857
+
1833
1858
  /**
1834
1859
  * Hide the component.
1835
1860
  * hideMode: 'removeDom' uses vdom removeDom.
@@ -1889,28 +1914,34 @@ class Base extends CoreBase {
1889
1914
  * Checks for vdom updates inside the parent chain and if found.
1890
1915
  * Registers the component for a vdom update once done.
1891
1916
  * @param {String} parentId=this.parentId
1892
- * @param {Function} [resolve] gets passed by updateVdom()
1917
+ * @param {Function} [resolve] Gets passed by updateVdom()
1918
+ * @param {Number} distance=1 Distance inside the component tree
1893
1919
  * @returns {Boolean}
1894
1920
  */
1895
- isParentVdomUpdating(parentId=this.parentId, resolve) {
1921
+ isParentVdomUpdating(parentId=this.parentId, resolve, distance=1) {
1896
1922
  if (parentId !== 'document.body') {
1897
1923
  let me = this,
1898
1924
  parent = Neo.getComponent(parentId);
1899
1925
 
1900
1926
  if (parent) {
1901
1927
  if (parent.isVdomUpdating) {
1902
- if (Neo.config.logVdomUpdateCollisions) {
1903
- console.warn('vdom parent update conflict with:', parent, 'for:', me)
1904
- }
1928
+ if (me.hasUpdateCollision(parent.currentUpdateDepth, distance)) {
1929
+ if (Neo.config.logVdomUpdateCollisions) {
1930
+ console.warn('vdom parent update conflict with:', parent, 'for:', me)
1931
+ }
1905
1932
 
1906
- NeoArray.add(parent.childUpdateCache, me.id);
1933
+ NeoArray.add(parent.childUpdateCache, me.id);
1907
1934
 
1908
- // Adding the resolve fn to its own cache, since the parent will trigger
1909
- // a new update() directly on this cmp
1910
- resolve && me.resolveUpdateCache.push(resolve)
1911
- return true
1935
+ // Adding the resolve fn to its own cache, since the parent will trigger
1936
+ // a new update() directly on this cmp
1937
+ resolve && me.resolveUpdateCache.push(resolve);
1938
+ return true
1939
+ }
1940
+
1941
+ // If an update is running and does not have a collision, we do not need to check further parents
1942
+ return false
1912
1943
  } else {
1913
- return me.isParentVdomUpdating(parent.parentId, resolve)
1944
+ return me.isParentVdomUpdating(parent.parentId, resolve, distance+1)
1914
1945
  }
1915
1946
  }
1916
1947
  }
@@ -168,7 +168,7 @@ class Base extends Component {
168
168
  if (oldValue !== undefined) {
169
169
  super.afterSetMounted(value, oldValue);
170
170
 
171
- for (let i = 0, { items } = this, { length } = items; i < length; i++) {
171
+ for (let i = 0, {items} = this, {length} = items; i < length; i++) {
172
172
  if (!items[i].vdom.removeDom) {
173
173
  items[i].mounted = value
174
174
  }
@@ -201,14 +201,14 @@ class Card extends Base {
201
201
  item.className = proto.className;
202
202
  item.module = module;
203
203
 
204
- me.applyChildAttributes(item, index);
205
-
206
204
  delete item.isLoading;
207
205
  delete item.vdom;
208
206
 
209
207
  items[index] = item = Neo.create(item);
210
208
 
211
- container.getVdomItemsRoot().cn[index] = item.vdom;
209
+ me.applyChildAttributes(item, index);
210
+
211
+ container.getVdomItemsRoot().cn[index] = item.createVdomReference();
212
212
 
213
213
  container.fire('cardLoaded', {item});
214
214
 
@@ -253,13 +253,15 @@ class Card extends Base {
253
253
 
254
254
  vdom.cn = [
255
255
  {cls: ['neo-relative'], cn: [
256
- {cls: ['neo-animation-wrapper'], style, cn: [card.vdom]}
256
+ {cls: ['neo-animation-wrapper'], style, cn: [card.createVdomReference()]}
257
257
  ]}
258
258
  ];
259
259
 
260
260
  animationWrapper = vdom.cn[0].cn[0];
261
261
 
262
- animationWrapper.cn[slideIn ? 'unshift' : 'push'](oldCard.vdom);
262
+ animationWrapper.cn[slideIn ? 'unshift' : 'push'](oldCard.createVdomReference());
263
+
264
+ container.updateDepth = -1;
263
265
 
264
266
  await container.promiseUpdate();
265
267
 
@@ -274,11 +276,13 @@ class Card extends Base {
274
276
  vdom.cn = [];
275
277
 
276
278
  container.items.forEach(item => {
277
- vdom.cn.push(item.vdom)
279
+ vdom.cn.push(item.createVdomReference())
278
280
  });
279
281
 
280
282
  oldCard.vdom.removeDom = true;
281
283
 
284
+ container.updateDepth = -1;
285
+
282
286
  await container.promiseUpdate()
283
287
  }
284
288
  }
@@ -144,6 +144,7 @@ class Cube extends Card {
144
144
 
145
145
  if (Neo.typeOf(item.module) === 'Function') {
146
146
  await me.loadModule(item, value);
147
+ container.updateDepth = -1;
147
148
  container.update();
148
149
 
149
150
  await me.timeout(100) // wait for the view to get painted first
@@ -276,6 +277,14 @@ class Cube extends Card {
276
277
  }
277
278
  }
278
279
 
280
+ /**
281
+ * @protected
282
+ */
283
+ applyRenderAttributes() {
284
+ this.container.updateDepth = -1;
285
+ super.applyRenderAttributes()
286
+ }
287
+
279
288
  /**
280
289
  *
281
290
  */
@@ -299,9 +308,9 @@ class Cube extends Card {
299
308
  vdom.cn = container.getVdomItemsRoot().cn;
300
309
 
301
310
  if (me.hideInactiveCardsOnDestroy) {
302
- vdom.cn.forEach((item, index) => {
311
+ container.items.forEach((item, index) => {
303
312
  if (index < 6 && index !== me.activeIndex) {
304
- item.removeDom = true
313
+ item.vdom.removeDom = true
305
314
  }
306
315
  })
307
316
  }
@@ -309,6 +318,7 @@ class Cube extends Card {
309
318
  // override
310
319
  container.getVdomItemsRoot = me.#cachedVdomItemsRoot;
311
320
 
321
+ container.updateDepth = -1;
312
322
  container.update();
313
323
 
314
324
  super.destroy(...args)
@@ -336,12 +346,13 @@ class Cube extends Card {
336
346
 
337
347
  me.timeout(50).then(() => {
338
348
  // Important when switching from a card layout to this one
339
- container.vdom.cn[0].cn[0].cn.forEach((node, index) => {
349
+ container.items.forEach((item, index) => {
340
350
  if (index < 6) {
341
- delete node.removeDom
351
+ delete item.vdom.removeDom
342
352
  }
343
353
  });
344
354
 
355
+ container.updateDepth = -1;
345
356
  container.update()
346
357
  })
347
358
  }
@@ -309,14 +309,14 @@ class Helper extends Base {
309
309
  }
310
310
 
311
311
  if (childNode) {
312
- if (oldVnodeMap.get(childNode.id)) {
313
- me.moveNode({deltas, insertDelta, oldVnodeMap, vnode: childNode, vnodeMap});
312
+ if (me.isMovedNode(childNode, oldVnodeMap)) {
313
+ me.moveNode({deltas, insertDelta, oldVnodeMap, vnode: childNode, vnodeMap})
314
314
  } else {
315
315
  me.insertNode({deltas, index: i + insertDelta, oldVnodeMap, vnode: childNode, vnodeMap});
316
316
  }
317
317
 
318
318
  if (oldChildNode && vnodeId === vnodeMap.get(oldChildNodeId)?.parentNode.id) {
319
- len++;
319
+ len++
320
320
  }
321
321
  }
322
322
  }
@@ -600,9 +600,7 @@ class Helper extends Base {
600
600
  id = vnode?.id;
601
601
 
602
602
  if (id) {
603
- let currentNode = oldVnodeMap.get(id)
604
-
605
- if (currentNode) {
603
+ if (this.isMovedNode(vnode, oldVnodeMap)) {
606
604
  movedNodes.set(id, vnodeMap.get(id))
607
605
  } else {
608
606
  vnode.childNodes?.forEach(childNode => {
@@ -647,6 +645,21 @@ class Helper extends Base {
647
645
  })
648
646
  }
649
647
 
648
+ /**
649
+ *
650
+ * @param {Neo.vdom.VNode} vnode
651
+ * @param {Map} oldVnodeMap
652
+ * @returns {Boolean}
653
+ */
654
+ isMovedNode(vnode, oldVnodeMap) {
655
+ let oldVnode = oldVnodeMap.get(vnode.id);
656
+
657
+ return oldVnode && (
658
+ !oldVnode.vnode.componentId || // the old vnode is not a reference
659
+ vnode.componentId === oldVnode.vnode.componentId // old & new nodes are the same references
660
+ )
661
+ }
662
+
650
663
  /**
651
664
  * @param {Object} config
652
665
  * @param {Object} config.deltas