@webjsdev/core 0.7.57 → 0.7.58

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": "@webjsdev/core",
3
- "version": "0.7.57",
3
+ "version": "0.7.58",
4
4
  "type": "module",
5
5
  "description": "The runtime for WebJs, a full-stack JavaScript framework built on web components with server-side rendering and no build step. Ships the html and css template tags, the WebComponent base class, signals, directives, and the isomorphic renderers.",
6
6
  "types": "./index.d.ts",
@@ -1,6 +1,6 @@
1
1
  import { render as clientRender } from '../render-client.js';
2
2
  import { readAttributeValue, resolveAttributeProperty } from '../attribute-reader.js';
3
- import { setActiveActionSignal } from '../action-abort-client.js';
3
+ import { setActiveActionSignal, activeActionSignal } from '../action-abort-client.js';
4
4
  import { carriesFunction } from '../form-action.js';
5
5
  import { isCSS, adoptStyles } from '../css.js';
6
6
  import { register, tagOf } from '../registry.js';
@@ -872,23 +872,18 @@ class WebComponentBase extends Base {
872
872
  // by-sync case (#469); a shouldUpdate=false cycle never reaches here,
873
873
  // so it does not invalidate an in-flight async render.
874
874
  this.__renderToken = (this.__renderToken || 0) + 1;
875
- // Abort the superseded render's in-flight action fetches (#492), start a
876
- // fresh controller for this render, and bind it as the active signal so
877
- // the RPC stub ties its fetches to this render. A superseded fetch's
878
- // AbortError is dropped by the render-token guard in _commitAsync.
875
+ // Abort the superseded render's in-flight action fetches (#492) and
876
+ // start a fresh controller for this render. update() binds its signal
877
+ // around render() alone (see there), never the DOM commit. A
878
+ // superseded fetch's AbortError is dropped by the render-token guard
879
+ // in _commitAsync.
879
880
  if (this.__renderAbort) this.__renderAbort.abort();
880
881
  this.__renderAbort = typeof AbortController !== 'undefined' ? new AbortController() : null;
881
- setActiveActionSignal(this.__renderAbort ? this.__renderAbort.signal : null);
882
882
  try {
883
883
  const r = this.update(changedProperties);
884
884
  if (r && typeof r.then === 'function') pendingCommit = r;
885
885
  } catch (error) {
886
886
  this._handleRenderError(/** @type {Error} */ (error));
887
- } finally {
888
- // The synchronous portion of render() has run; actions invoked there
889
- // already captured the signal. Clear it so a later event handler is
890
- // not bound to a stale render's controller.
891
- setActiveActionSignal(null);
892
887
  }
893
888
 
894
889
  if (!pendingCommit) {
@@ -1126,7 +1121,21 @@ class WebComponentBase extends Base {
1126
1121
  });
1127
1122
  }
1128
1123
  let tpl;
1129
- this.__signalWatcher.observe(() => { tpl = this.render(); });
1124
+ // Bind this render's abort signal (#492) around the synchronous part of
1125
+ // render() ONLY, so the RPC stub ties an action called there to this
1126
+ // render and the next render cancels it. The commit below runs unbound:
1127
+ // it connects the child elements this template creates, and an action a
1128
+ // child starts in its connectedCallback belongs to the child, not to this
1129
+ // render, so the parent's next render must not cancel it (#1514). The
1130
+ // previous binding is restored rather than cleared, so a render nested
1131
+ // inside another's synchronous work leaves the outer one intact.
1132
+ const outer = activeActionSignal();
1133
+ setActiveActionSignal(this.__renderAbort ? this.__renderAbort.signal : null);
1134
+ try {
1135
+ this.__signalWatcher.observe(() => { tpl = this.render(); });
1136
+ } finally {
1137
+ setActiveActionSignal(outer || null);
1138
+ }
1130
1139
  // Bare-await async render (#469): render() returned a promise. Use
1131
1140
  // stale-while-revalidate: keep the current DOM (the SSR first paint on
1132
1141
  // hydration, or the prior content on a re-fetch) visible until the new