@adobe-commerce/elsie 2.1.0-beta.3 → 2.1.0-beta.4

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/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # @adobe-commerce/elsie
2
2
 
3
+ ## 2.1.0-beta.4
4
+
5
+ ### Patch Changes
6
+
7
+ - 8fc53e5: Fix `Slot` silently dropping
8
+ `replaceWith`/`appendChild`/`prependChild`/
9
+ `appendSibling`/`prependSibling`/`remove` calls made from a `slot` callback
10
+ that doesn't `return`/`await` its own async work (e.g. a non-`async` callback
11
+ that calls an `async` helper as a bare statement). Previously, nothing was
12
+ left to trigger the render that would have picked up the queued method once
13
+ the slot's normal init-triggered render pass had already completed. `Slot` now
14
+ detects that case and flushes the pending update itself. Existing callers that
15
+ already `return`/`await` their `slot` callback are unaffected.
16
+
17
+ See `docs/slot-dom-graft-race.md` for the full trace.
18
+
3
19
  ## 2.1.0-beta.3
4
20
 
5
21
  ### Patch Changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adobe-commerce/elsie",
3
- "version": "2.1.0-beta.3",
3
+ "version": "2.1.0-beta.4",
4
4
  "license": "SEE LICENSE IN LICENSE.md",
5
5
  "description": "Domain Package SDK",
6
6
  "engines": {
package/src/lib/slot.tsx CHANGED
@@ -146,9 +146,21 @@ export function useSlot<K, V extends HTMLElement>(
146
146
  });
147
147
  };
148
148
 
149
+ const handleLifeCycleRenderRef = useRef<() => Promise<void>>();
150
+
149
151
  const _registerMethod = useCallback((cb: Function) => {
150
152
  if (typeof cb === 'function') {
151
153
  methodsRef.current.push(cb);
154
+
155
+ // If the slot already finished its normal init-triggered render pass
156
+ // (status is back to 'ready'), nothing else will flush this method.
157
+ // This happens when an async `slot` callback doesn't `return`/`await`
158
+ // its own async work before calling replaceWith/appendChild/etc. --
159
+ // `handleLifeCycleInit` moves on before this method gets registered.
160
+ // Flush it ourselves rather than silently dropping it.
161
+ if (status.current === 'ready') {
162
+ handleLifeCycleRenderRef.current?.();
163
+ }
152
164
  } else {
153
165
  console.warn('Skipped: Invalid _registerMethod', cb);
154
166
  }
@@ -337,6 +349,8 @@ export function useSlot<K, V extends HTMLElement>(
337
349
  status.current = 'ready';
338
350
  }, [children, context, name, props, render, state]);
339
351
 
352
+ handleLifeCycleRenderRef.current = handleLifeCycleRender;
353
+
340
354
  // Initialization
341
355
  const handleLifeCycleInit = useCallback(async () => {
342
356
  if (!callback) return;