@mintjamsinc/ichigojs 0.1.88 → 0.1.89

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.
@@ -10795,8 +10795,7 @@ class VNode {
10795
10795
  const changed = this.bindings.isAffected(changes, this.#textEvaluator.identifiers, this.#textEvaluator.trackedPaths);
10796
10796
  // If the text node has changed, update its content
10797
10797
  if (changed) {
10798
- const text = this.#node;
10799
- text.data = this.#textEvaluator.evaluate(this.bindings);
10798
+ this.#renderText();
10800
10799
  }
10801
10800
  }
10802
10801
  else if (this.#nodeType === Node.ELEMENT_NODE) {
@@ -10817,7 +10816,7 @@ class VNode {
10817
10816
  for (const preparer of this.#directiveManager.bindingsPreparers) {
10818
10817
  const changed = this.bindings.isAffected(changes, preparer.dependentIdentifiers, preparer.trackedPaths);
10819
10818
  if (changed) {
10820
- preparer.prepareBindings();
10819
+ this.#renderSafely(() => preparer.prepareBindings());
10821
10820
  }
10822
10821
  }
10823
10822
  }
@@ -10826,7 +10825,7 @@ class VNode {
10826
10825
  for (const updater of this.#directiveManager.domUpdaters) {
10827
10826
  const changed = this.bindings.isAffected(changes, updater.dependentIdentifiers, updater.trackedPaths);
10828
10827
  if (changed) {
10829
- updater.applyToDOM();
10828
+ this.#renderSafely(() => updater.applyToDOM());
10830
10829
  }
10831
10830
  }
10832
10831
  }
@@ -10864,8 +10863,7 @@ class VNode {
10864
10863
  forceUpdate() {
10865
10864
  if (this.#nodeType === Node.TEXT_NODE && this.#textEvaluator) {
10866
10865
  // If this is a text node with a text evaluator, update its content if needed
10867
- const text = this.#node;
10868
- text.data = this.#textEvaluator.evaluate(this.bindings);
10866
+ this.#renderText();
10869
10867
  }
10870
10868
  else if (this.#nodeType === Node.ELEMENT_NODE) {
10871
10869
  // If this is an element node, update directives and child nodes
@@ -10883,13 +10881,13 @@ class VNode {
10883
10881
  }
10884
10882
  // Prepare bindings for each preparer if relevant identifiers have changed
10885
10883
  for (const preparer of this.#directiveManager.bindingsPreparers) {
10886
- preparer.prepareBindings();
10884
+ this.#renderSafely(() => preparer.prepareBindings());
10887
10885
  }
10888
10886
  }
10889
10887
  // Apply DOM updaters from directives, if any
10890
10888
  if (this.#directiveManager?.domUpdaters) {
10891
10889
  for (const updater of this.#directiveManager.domUpdaters) {
10892
- updater.applyToDOM();
10890
+ this.#renderSafely(() => updater.applyToDOM());
10893
10891
  }
10894
10892
  }
10895
10893
  // Recursively update child virtual nodes. A copy: an update can
@@ -10911,6 +10909,38 @@ class VNode {
10911
10909
  });
10912
10910
  }
10913
10911
  }
10912
+ /**
10913
+ * Evaluates this text node's expressions into its content.
10914
+ */
10915
+ #renderText() {
10916
+ const text = this.#node;
10917
+ this.#renderSafely(() => {
10918
+ text.data = this.#textEvaluator.evaluate(this.bindings);
10919
+ });
10920
+ }
10921
+ /**
10922
+ * Runs one binding's render step. A binding whose expression throws (for example one that
10923
+ * reads a member of a value that is still undefined) is logged and left as it was, so that
10924
+ * it does not stop the rest of the tree from rendering.
10925
+ * @param render The render step.
10926
+ */
10927
+ #renderSafely(render) {
10928
+ try {
10929
+ render();
10930
+ }
10931
+ catch (error) {
10932
+ this.#vApplication.logManager.getLogger(this.constructor.name).error(`Error rendering ${this.#describe()}: ${error}`);
10933
+ }
10934
+ }
10935
+ /**
10936
+ * Describes this node for a log message: a text node by its text, an element by its tag.
10937
+ */
10938
+ #describe() {
10939
+ if (this.#nodeType === Node.TEXT_NODE) {
10940
+ return `text "${(this.#node.textContent ?? '').trim()}"`;
10941
+ }
10942
+ return `<${this.#nodeName.toLowerCase()}>`;
10943
+ }
10914
10944
  /**
10915
10945
  * Adds a child virtual node to this virtual node.
10916
10946
  * @param child The child virtual node to add.
@@ -15637,8 +15667,11 @@ class VApplication {
15637
15667
  vApplication: this,
15638
15668
  bindings: this.#bindings
15639
15669
  });
15640
- // Initial rendering
15641
- this.#vNode.update();
15670
+ // Initial rendering. Every binding is applied, not only those whose identifiers were
15671
+ // recorded as changed while the data was set up: a value that starts undefined is never
15672
+ // recorded (undefined -> undefined is no change), and an expression over globals only
15673
+ // has no identifier to record at all.
15674
+ this.#vNode.forceUpdate();
15642
15675
  // Expand the components in the tree. Last, so every component element
15643
15676
  // has been compiled and has had its prop values delivered before its
15644
15677
  // template is cloned in. See VNode.expandComponents.