@skirbi/sugar 0.1.8 → 0.1.9

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/Changes CHANGED
@@ -1,5 +1,35 @@
1
1
  Revision history for @skirbi/sugar
2
2
 
3
+ 0.1.9 2026-06-10 21:49:27Z
4
+
5
+ * Add wc:rendered custom event to sugar
6
+
7
+ When components load the order in which they load seems kind of totally
8
+ random. This causes multiple connects and disconnects. Now, the Custom
9
+ Element spec defines a `moveBefore()` method, but unfortunatly, that
10
+ isn't supported by all browsers, most notably Safari. Which is also a
11
+ massive consumer of webcomponents in the whole Apple ecosystem.
12
+
13
+ The workaround to this problem is by giving sugar a way to detect if it
14
+ is inside the DOM-tree of another webcomponent. If sugar is inside a
15
+ webcomponent it will wait until its parent is rendered to actually
16
+ render itself. Within a page where all components are sugared, we can
17
+ safely say that parents are always rendered first, minimizing the amount
18
+ of (dis)connect calls.
19
+
20
+ It does this by looking at `el._internals` and checks for the rendered
21
+ state.
22
+
23
+ When we are part of a webcomponent chain where the parent isn't a
24
+ sugared component, we still wait for the parent to finish and hope our
25
+ parent does similar logic.
26
+
27
+ This approach is simply a workaround until Safari (and others) supports
28
+ `moveBefore`.
29
+
30
+ * Made sideEffects actually target files. The true was breaking things in
31
+ ways I didn't expect.
32
+
3
33
  0.1.8 2026-06-08 22:43:46Z
4
34
 
5
35
  * Forward value for htmlelement-input.mjs in all cases not just with
package/lib/fakedom.mjs CHANGED
@@ -40,6 +40,7 @@ export async function setupDomForTesting(
40
40
  global.document = dom.window.document;
41
41
  global.window = dom.window;
42
42
  global.MutationObserver = dom.window.MutationObserver;
43
+ global.CustomEvent = dom.window.CustomEvent;
43
44
 
44
45
  const projectRoot = process.cwd();
45
46
 
@@ -324,6 +324,7 @@ export class HTMLElementSugar extends HTMLElement {
324
324
  this.config = {
325
325
  ...(this.constructor.defaultConfig ?? {})
326
326
  };
327
+ this._internals = this.attachInternals();
327
328
  }
328
329
 
329
330
  /**
package/lib/index.mjs CHANGED
@@ -2,7 +2,7 @@
2
2
  //
3
3
  // SPDX-License-Identifier: MIT
4
4
 
5
- const VERSION = "0.1.8";
5
+ const VERSION = "0.1.9";
6
6
 
7
7
  export { HTMLElementSugar } from './htmlelement.mjs';
8
8
  export { HTMLElementSugarInput } from './htmlelement-input.mjs';
package/lib/livewire.mjs CHANGED
@@ -30,12 +30,15 @@ if (typeof document !== 'undefined') {
30
30
  document.body.appendChild(staging);
31
31
  staging.innerHTML = effects.html;
32
32
 
33
+ console.log(effects.html);
34
+
33
35
  Promise.resolve().then(() => Promise.resolve().then(() => {
34
36
  effects.html = staging.innerHTML;
35
37
  effects._sugarHydrated = true;
36
38
  staging.remove();
37
39
  original(effects);
38
40
  }));
41
+ console.log(effects.html);
39
42
  };
40
43
  });
41
44
  });
@@ -2,20 +2,83 @@
2
2
  //
3
3
  // SPDX-License-Identifier: MIT
4
4
 
5
+ const sugarState = new WeakMap();
6
+
5
7
  export const withConnectedSugar = (Base) =>
6
8
  class extends Base {
7
9
  static morphTriggerSelector = '';
8
10
 
9
11
  connectedCallback() {
12
+ if (!sugarState.has(this)) {
13
+ sugarState.set(this, {
14
+ rendered: false,
15
+ firstUpdatedCalled: false,
16
+ });
17
+ }
18
+ const state = sugarState.get(this);
19
+
10
20
  this._syncObservedAttributesToConfig();
11
21
  this._armMorphObserver();
22
+
12
23
  if (this.connectedCallbackSugarOnce) {
13
24
  this.connectedCallbackSugarOnce();
14
25
  }
15
26
 
16
27
  if (this._shouldRenderOnConnect()) {
17
- this.connectedCallbackSugar();
28
+ const wcParent = this._findWcParent();
29
+
30
+ const render = () => {
31
+
32
+ this.connectedCallbackSugar();
33
+ state.rendered = true;
34
+
35
+ const event = new CustomEvent('wc:rendered', { bubbles: false });
36
+ this.dispatchEvent(event);
37
+
38
+ if (!state.firstUpdatedCalled) {
39
+ Promise.resolve().then(() => {
40
+ state.firstUpdatedCalled = true;
41
+ this.firstUpdatedSugar?.();
42
+ });
43
+ }
44
+ };
45
+
46
+ this.renderIfParent(wcParent, render);
47
+ }
48
+ }
49
+
50
+ renderIfParent(parent = null, cb) {
51
+
52
+ if (!parent || !sugarState.has(parent)) {
53
+ cb();
54
+ return;
55
+ }
56
+ const parentState = sugarState.get(parent);
57
+ if (parentState.rendered) {
58
+ cb();
59
+ return;
60
+ }
61
+
62
+ const timeout = setTimeout(cb, 1000);
63
+ parent.addEventListener('wc:rendered', () => {
64
+ clearTimeout(timeout);
65
+ cb();
66
+ }, { once: true });
67
+ }
68
+
69
+
70
+ _findWcParent() {
71
+ let el = this.parentElement;
72
+ while (el) {
73
+ if (el.tagName?.includes('-')) {
74
+ if (el._internals || el._sugarRendered !== undefined) {
75
+ return el;
76
+ }
77
+ return null;
78
+ }
79
+ el = el.parentElement;
18
80
  }
81
+ return null;
19
82
  }
20
83
 
21
84
  _syncObservedAttributesToConfig() {
package/package.json CHANGED
@@ -54,7 +54,10 @@
54
54
  "release": "rzil release",
55
55
  "test": "tap"
56
56
  },
57
- "sideEffects": true,
57
+ "sideEffects": [
58
+ "./livewire",
59
+ "./aliases-register"
60
+ ],
58
61
  "type": "module",
59
- "version": "0.1.8"
62
+ "version": "0.1.9"
60
63
  }