@blackbirdjs/component 0.1.0 → 0.1.2
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 +2 -2
- package/src/component.js +23 -6
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@blackbirdjs/component",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "Template-first fine-grained Web Component layer for BlackbirdJS",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./src/index.js",
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
".": "./src/index.js"
|
|
9
9
|
},
|
|
10
10
|
"dependencies": {
|
|
11
|
-
"@blackbirdjs/store": "^0.
|
|
11
|
+
"@blackbirdjs/store": "^0.2.0"
|
|
12
12
|
},
|
|
13
13
|
"license": "Apache-2.0",
|
|
14
14
|
"publishConfig": {
|
package/src/component.js
CHANGED
|
@@ -7,6 +7,9 @@ export function setGlobalStore(store) {
|
|
|
7
7
|
}
|
|
8
8
|
|
|
9
9
|
export class BlackbirdComponent extends HTMLElement {
|
|
10
|
+
// Add an internal register array to capture cleanup tokens safely
|
|
11
|
+
#unsubscribers = [];
|
|
12
|
+
|
|
10
13
|
constructor() {
|
|
11
14
|
super();
|
|
12
15
|
this.attachShadow({ mode: 'open' });
|
|
@@ -32,17 +35,25 @@ export class BlackbirdComponent extends HTMLElement {
|
|
|
32
35
|
return;
|
|
33
36
|
}
|
|
34
37
|
|
|
35
|
-
|
|
38
|
+
// Changed contentEditable to template.content
|
|
39
|
+
const clone = template.content.cloneNode(true);
|
|
36
40
|
this.shadowRoot.appendChild(clone);
|
|
37
41
|
|
|
38
42
|
this._hydrateInitialAttributes();
|
|
39
43
|
this._compileDOM();
|
|
40
44
|
}
|
|
41
45
|
|
|
46
|
+
// Automatically clean up memory when the component leaves the screen
|
|
47
|
+
disconnectedCallback() {
|
|
48
|
+
this.#unsubscribers.forEach(unsubscribe => unsubscribe());
|
|
49
|
+
this.#unsubscribers = [];
|
|
50
|
+
}
|
|
51
|
+
|
|
42
52
|
_hydrateInitialAttributes() {
|
|
43
53
|
Array.from(this.attributes).forEach(attr => {
|
|
44
54
|
if (attr.name.startsWith('data-')) {
|
|
45
|
-
|
|
55
|
+
// FIX 3: Fixed broken regex format from /-(a-z)/g to /-([a-z])/g
|
|
56
|
+
const cleanKey = attr.name.replace(/^data-/, '').replace(/-([a-z])/g, (_, letter) => letter.toUpperCase());
|
|
46
57
|
this.localStore.set(cleanKey, attr.value);
|
|
47
58
|
}
|
|
48
59
|
});
|
|
@@ -50,23 +61,29 @@ export class BlackbirdComponent extends HTMLElement {
|
|
|
50
61
|
|
|
51
62
|
_compileDOM() {
|
|
52
63
|
// Map Text Bindings
|
|
53
|
-
|
|
64
|
+
// Changed querySelector to querySelectorAll so .forEach runs successfully
|
|
65
|
+
const boundElements = this.shadowRoot.querySelectorAll('[data-bind]');
|
|
66
|
+
|
|
54
67
|
boundElements.forEach(element => {
|
|
55
68
|
const bindingExpression = element.getAttribute('data-bind').trim();
|
|
56
69
|
|
|
57
70
|
if (bindingExpression.startsWith('global.')) {
|
|
58
71
|
const key = bindingExpression.replace('global.', '');
|
|
59
72
|
if (globalStoreInstance) {
|
|
60
|
-
|
|
73
|
+
// Push the returned unsubscribe token to the cleanup tracking list
|
|
74
|
+
const sub = globalStoreInstance.subscribe(key, (val) => {
|
|
61
75
|
element.textContent = val;
|
|
62
76
|
});
|
|
77
|
+
this.#unsubscribers.push(sub.unsubscribe);
|
|
63
78
|
} else {
|
|
64
|
-
console.warn(`[Blackbird] Global Variable "${key}" requested but no global store
|
|
79
|
+
console.warn(`[Blackbird] Global Variable "${key}" requested but no global store configured.`);
|
|
65
80
|
}
|
|
66
81
|
} else {
|
|
67
|
-
|
|
82
|
+
// Capture local store unsubscriptions as well
|
|
83
|
+
const sub = this.localStore.subscribe(bindingExpression, (val) => {
|
|
68
84
|
element.textContent = val;
|
|
69
85
|
});
|
|
86
|
+
this.#unsubscribers.push(sub.unsubscribe);
|
|
70
87
|
}
|
|
71
88
|
});
|
|
72
89
|
|