@pfern/elements 0.1.6 → 0.1.7
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/elements.js +20 -6
- package/package.json +1 -1
package/elements.js
CHANGED
|
@@ -26,6 +26,8 @@ const rootMap = new WeakMap()
|
|
|
26
26
|
|
|
27
27
|
const isNodeEnv = typeof document === 'undefined'
|
|
28
28
|
|
|
29
|
+
let componentUpdateDepth = 0
|
|
30
|
+
|
|
29
31
|
/**
|
|
30
32
|
* Determines whether two nodes have changed enough to require replacement.
|
|
31
33
|
* Compares type, string value, or element tag.
|
|
@@ -185,8 +187,12 @@ const renderTree = (node, isRoot = true) => {
|
|
|
185
187
|
}
|
|
186
188
|
|
|
187
189
|
if (Array.isArray(node) && node[0] === 'wrap') {
|
|
188
|
-
const [_tag,
|
|
189
|
-
|
|
190
|
+
const [_tag, props = {}, child] = node
|
|
191
|
+
const el = renderTree(child, true)
|
|
192
|
+
if (props && typeof props === 'object' && props.__instance) {
|
|
193
|
+
rootMap.set(props.__instance, el)
|
|
194
|
+
}
|
|
195
|
+
return el
|
|
190
196
|
}
|
|
191
197
|
|
|
192
198
|
const [tag, props = {}, ...children] = node
|
|
@@ -298,17 +304,25 @@ export const render = (vtree, container = null) => {
|
|
|
298
304
|
* @returns {(...args: any[]) => any} - A callable component that can manage its own subtree.
|
|
299
305
|
*/
|
|
300
306
|
export const component = fn => {
|
|
307
|
+
const instance = {}
|
|
301
308
|
return (...args) => {
|
|
302
309
|
try {
|
|
310
|
+
const prevEl = rootMap.get(instance)
|
|
311
|
+
const canUpdateInPlace = !!prevEl?.parentNode && componentUpdateDepth === 0
|
|
312
|
+
|
|
313
|
+
componentUpdateDepth++
|
|
303
314
|
const vnode = fn(...args)
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
315
|
+
componentUpdateDepth--
|
|
316
|
+
|
|
317
|
+
if (canUpdateInPlace) {
|
|
318
|
+
const replacement = renderTree(['wrap', { __instance: instance }, vnode], true)
|
|
307
319
|
prevEl.parentNode.replaceChild(replacement, prevEl)
|
|
308
320
|
return replacement.__vnode
|
|
309
321
|
}
|
|
310
|
-
|
|
322
|
+
|
|
323
|
+
return ['wrap', { __instance: instance }, vnode]
|
|
311
324
|
} catch (err) {
|
|
325
|
+
componentUpdateDepth = Math.max(0, componentUpdateDepth - 1)
|
|
312
326
|
console.error('Component error:', err)
|
|
313
327
|
return ['div', {}, `Error: ${err.message}`]
|
|
314
328
|
}
|