mithril-lynx 0.0.4 → 0.0.5

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mithril-lynx",
3
- "version": "0.0.4",
3
+ "version": "0.0.5",
4
4
  "description": "Mithril.js rendered through Lynx's Element PAPI \u2014 a contract-complete port of mithril/render/render.js@2.3.8 to the Lynx main thread, packaged as a reusable framework.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -696,23 +696,41 @@ function factory() {
696
696
 
697
697
  function initComponent(vnode, hooks) {
698
698
  var sentinel
699
- if (typeof vnode.tag.view === "function") {
699
+ var classStyle = typeof vnode.tag.view !== "function"
700
+ if (!classStyle) {
700
701
  vnode.state = Object.create(vnode.tag)
701
702
  sentinel = vnode.state.view
702
- if (sentinel.$$reentrantLock$$ != null) return
703
- sentinel.$$reentrantLock$$ = true
704
703
  } else {
705
- vnode.state = void 0
706
704
  sentinel = vnode.tag
707
- if (sentinel.$$reentrantLock$$ != null) return
708
- sentinel.$$reentrantLock$$ = true
709
- vnode.state = (vnode.tag.prototype != null && typeof vnode.tag.prototype.view === "function") ? new vnode.tag(vnode) : vnode.tag(vnode)
710
705
  }
711
- initLifecycle(vnode.state, vnode, hooks)
712
- if (vnode.attrs != null) initLifecycle(vnode.attrs, vnode, hooks)
713
- vnode.instance = Vnode.normalize(callHook.call(vnode.state.view, vnode))
714
- if (vnode.instance === vnode) throw Error("A view cannot return the vnode it received as argument")
715
- sentinel.$$reentrantLock$$ = null
706
+ if (sentinel.$$reentrantLock$$ != null) return
707
+ sentinel.$$reentrantLock$$ = true
708
+ // The lock above is stored on `sentinel` — the component's OWN shared
709
+ // view function (or, for class-style components, the tag itself), NOT
710
+ // on this vnode instance — so it's shared by EVERY use of this
711
+ // component anywhere in the app. Without the try/finally below, a
712
+ // view() (or, for a class-style component, its CONSTRUCTOR) that
713
+ // throws on a component's first render (e.g. a fail-loudly validation
714
+ // error) skips the `sentinel.$$reentrantLock$$ = null` reset entirely,
715
+ // leaving that lock stuck at `true` forever. Every later attempt to
716
+ // create that SAME component type — anywhere, not just the one
717
+ // instance that threw — then silently no-ops right here
718
+ // (`if (sentinel.$$reentrantLock$$ != null) return`): no render, no
719
+ // error, nothing. Found via mithril-lynx-ui's own test suite: a
720
+ // component whose view() deliberately throws to validate a prop,
721
+ // exercised in one test, made every SUBSEQUENT test mounting that
722
+ // same component silently render nothing, no matter how unrelated.
723
+ try {
724
+ if (classStyle) {
725
+ vnode.state = (vnode.tag.prototype != null && typeof vnode.tag.prototype.view === "function") ? new vnode.tag(vnode) : vnode.tag(vnode)
726
+ }
727
+ initLifecycle(vnode.state, vnode, hooks)
728
+ if (vnode.attrs != null) initLifecycle(vnode.attrs, vnode, hooks)
729
+ vnode.instance = Vnode.normalize(callHook.call(vnode.state.view, vnode))
730
+ if (vnode.instance === vnode) throw Error("A view cannot return the vnode it received as argument")
731
+ } finally {
732
+ sentinel.$$reentrantLock$$ = null
733
+ }
716
734
  }
717
735
 
718
736
  function createComponent(parent, vnode, hooks, ns, nextSibling) {