jsx-framework-test-pb 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.
@@ -1,4 +1,4 @@
1
- import { setActiveEffect } from "./state";
1
+ import { setActiveEffect } from './state';
2
2
  export function effect(fn) {
3
3
  const runner = () => {
4
4
  setActiveEffect(runner);
@@ -5,5 +5,5 @@ interface FiberNode {
5
5
  key: string | null;
6
6
  index: number;
7
7
  }
8
- export declare function reconcile(parent: HTMLElement, newElements: any[], oldFibers?: FiberNode[]): FiberNode[];
8
+ export declare function reconcile(parent: HTMLElement, newElements: any[] | any, oldFibers?: FiberNode[]): FiberNode[];
9
9
  export {};
@@ -1,43 +1,74 @@
1
- import { createElement } from './createElement';
2
- import { isElement } from '../utils';
3
- const fiberMap = new WeakMap();
1
+ import { createElement } from "./createElement";
2
+ import { isElement } from "../utils";
3
+ function canReuse(oldElement, newElement) {
4
+ if (typeof oldElement !== typeof newElement)
5
+ return false;
6
+ if (typeof oldElement !== "object" || !isElement(oldElement) || !isElement(newElement)) {
7
+ return false;
8
+ }
9
+ return oldElement.type === newElement.type;
10
+ }
11
+ function updateElement(dom, element) {
12
+ if (!isElement(element))
13
+ return;
14
+ const { props } = element;
15
+ Object.keys(props).forEach((key) => {
16
+ if (key === "children") {
17
+ return;
18
+ }
19
+ else if (key.startsWith("on") && typeof props[key] === "function") {
20
+ return;
21
+ }
22
+ else if (key === "className") {
23
+ dom.setAttribute("class", props[key]);
24
+ }
25
+ else if (key === "style" && typeof props[key] === "object") {
26
+ Object.assign(dom.style, props[key]);
27
+ }
28
+ else if (key !== "key" && props[key] != null) {
29
+ dom.setAttribute(key, String(props[key]));
30
+ }
31
+ });
32
+ }
33
+ function getInsertionPoint(parent, targetIndex) {
34
+ return parent.childNodes.item(targetIndex) ?? null;
35
+ }
4
36
  export function reconcile(parent, newElements, oldFibers = []) {
5
37
  const newFibers = [];
6
38
  const newElementsArray = Array.isArray(newElements) ? newElements : [newElements];
7
39
  const oldFibersByKey = new Map();
8
40
  const oldFibersByIndex = new Map();
9
- oldFibers.forEach((fiber, index) => {
10
- if (fiber.key !== null) {
41
+ oldFibers.forEach((fiber, i) => {
42
+ if (fiber.key != null)
11
43
  oldFibersByKey.set(fiber.key, fiber);
12
- }
13
- else {
14
- oldFibersByIndex.set(index, fiber);
15
- }
44
+ else
45
+ oldFibersByIndex.set(i, fiber);
16
46
  });
17
- const anchor = document.createComment('anchor');
18
- if (!parent.contains(anchor)) {
19
- parent.appendChild(anchor);
20
- }
47
+ const reusedOldDoms = new Set();
21
48
  newElementsArray.forEach((element, index) => {
22
49
  const key = isElement(element) ? element.key : null;
23
- let fiber;
24
50
  let oldFiber;
25
- if (key !== null) {
51
+ if (key != null) {
26
52
  oldFiber = oldFibersByKey.get(key);
27
- oldFibersByKey.delete(key);
53
+ if (oldFiber)
54
+ oldFibersByKey.delete(key);
28
55
  }
29
56
  else {
30
57
  oldFiber = oldFibersByIndex.get(index);
31
- oldFibersByIndex.delete(index);
58
+ if (oldFiber)
59
+ oldFibersByIndex.delete(index);
32
60
  }
61
+ let fiber;
33
62
  if (oldFiber && canReuse(oldFiber.element, element)) {
34
63
  fiber = {
35
64
  element,
36
65
  dom: oldFiber.dom,
37
66
  parent: null,
38
67
  key,
39
- index
68
+ index,
40
69
  };
70
+ if (fiber.dom)
71
+ reusedOldDoms.add(fiber.dom);
41
72
  if (oldFiber.dom && isElement(element)) {
42
73
  updateElement(oldFiber.dom, element);
43
74
  }
@@ -49,55 +80,28 @@ export function reconcile(parent, newElements, oldFibers = []) {
49
80
  dom,
50
81
  parent: null,
51
82
  key,
52
- index
83
+ index,
53
84
  };
85
+ if (oldFiber?.dom && oldFiber.dom.parentNode === parent) {
86
+ parent.removeChild(oldFiber.dom);
87
+ }
54
88
  if (dom) {
55
- parent.insertBefore(dom, anchor);
89
+ const before = getInsertionPoint(parent, index);
90
+ parent.insertBefore(dom, before);
56
91
  }
57
- if (oldFiber?.dom) {
58
- parent.removeChild(oldFiber.dom);
92
+ }
93
+ if (fiber.dom) {
94
+ const before = getInsertionPoint(parent, index);
95
+ if (fiber.dom !== before) {
96
+ parent.insertBefore(fiber.dom, before);
59
97
  }
60
98
  }
61
99
  newFibers.push(fiber);
62
- if (fiber.dom && fiber.dom.nextSibling !== anchor) {
63
- parent.insertBefore(fiber.dom, anchor);
64
- }
65
100
  });
66
- [...oldFibersByKey.values(), ...oldFibersByIndex.values()].forEach(fiber => {
67
- if (fiber.dom) {
101
+ [...oldFibersByKey.values(), ...oldFibersByIndex.values()].forEach((fiber) => {
102
+ if (fiber.dom && fiber.dom.parentNode === parent && !reusedOldDoms.has(fiber.dom)) {
68
103
  parent.removeChild(fiber.dom);
69
104
  }
70
105
  });
71
106
  return newFibers;
72
107
  }
73
- function canReuse(oldElement, newElement) {
74
- if (typeof oldElement !== typeof newElement) {
75
- return false;
76
- }
77
- if (typeof oldElement !== 'object' || !isElement(oldElement) || !isElement(newElement)) {
78
- return false;
79
- }
80
- return oldElement.type === newElement.type;
81
- }
82
- function updateElement(dom, element) {
83
- if (!isElement(element))
84
- return;
85
- const { props } = element;
86
- Object.keys(props).forEach(key => {
87
- if (key === 'children') {
88
- return;
89
- }
90
- else if (key.startsWith('on') && typeof props[key] === 'function') {
91
- return;
92
- }
93
- else if (key === 'className') {
94
- dom.setAttribute('class', props[key]);
95
- }
96
- else if (key === 'style' && typeof props[key] === 'object') {
97
- Object.assign(dom.style, props[key]);
98
- }
99
- else if (key !== 'key' && props[key] != null) {
100
- dom.setAttribute(key, String(props[key]));
101
- }
102
- });
103
- }
package/dist/types.d.ts CHANGED
@@ -16,7 +16,7 @@ export interface ElementProps {
16
16
  children?: ElementChild | ElementChild[];
17
17
  [key: string]: any;
18
18
  }
19
- export type ElementChild = Element | string | number | boolean | null | undefined;
19
+ export type ElementChild = Element | string | number | boolean | null | undefined | (() => any);
20
20
  export type FC<P = {}> = (props: P) => Element | null;
21
21
  export interface CSSProperties {
22
22
  [key: string]: string | number;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jsx-framework-test-pb",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",