assign-gingerly 0.0.57 → 0.0.59

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.
@@ -0,0 +1,65 @@
1
+ /**
2
+ * waitForSettled.ts — Waits for a DOM subtree to "settle" (mutations stop cascading).
3
+ *
4
+ * Observes a node for DOM mutations and debounces: each mutation resets an idle timer.
5
+ * When no mutations have occurred for `idleMs` milliseconds, the promise resolves.
6
+ *
7
+ * Useful for waiting for async rendering (itemscope managers, enhancements, features)
8
+ * to complete inside a DocumentFragment before committing to the live DOM.
9
+ *
10
+ * @example
11
+ * import { waitForSettled } from 'assign-gingerly/waitForSettled.js';
12
+ *
13
+ * const fragment = document.createDocumentFragment();
14
+ * // ... clone and assign into fragment ...
15
+ * await waitForSettled(fragment, 100, 2000);
16
+ * target.appendChild(fragment);
17
+ *
18
+ * @param root - The node to observe (typically a DocumentFragment or Element)
19
+ * @param idleMs - Debounce window in milliseconds. Default: 100
20
+ * @param timeout - Maximum wait time in milliseconds. If exceeded, rejects. Default: none (infinite)
21
+ */
22
+ export function waitForSettled(
23
+ root: Node,
24
+ idleMs: number = 100,
25
+ timeout?: number
26
+ ): Promise<void> {
27
+ return new Promise((resolve, reject) => {
28
+ let timer: ReturnType<typeof setTimeout>;
29
+ let maxTimer: ReturnType<typeof setTimeout> | undefined;
30
+
31
+ const mo = new MutationObserver(() => {
32
+ clearTimeout(timer);
33
+ timer = setTimeout(() => {
34
+ mo.disconnect();
35
+ if (maxTimer) clearTimeout(maxTimer);
36
+ resolve();
37
+ }, idleMs);
38
+ });
39
+
40
+ mo.observe(root, {
41
+ childList: true,
42
+ subtree: true,
43
+ attributes: true,
44
+ characterData: true
45
+ });
46
+
47
+ // Initial timer — resolves if no mutations happen at all
48
+ timer = setTimeout(() => {
49
+ mo.disconnect();
50
+ if (maxTimer) clearTimeout(maxTimer);
51
+ resolve();
52
+ }, idleMs);
53
+
54
+ // Maximum timeout — rejects if mutations never quiesce
55
+ if (timeout !== undefined) {
56
+ maxTimer = setTimeout(() => {
57
+ mo.disconnect();
58
+ clearTimeout(timer);
59
+ reject(new Error(
60
+ `waitForSettled: mutations did not quiesce within ${timeout}ms`
61
+ ));
62
+ }, timeout);
63
+ }
64
+ });
65
+ }