lithent 1.0.0 → 1.0.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.
Files changed (47) hide show
  1. package/README.md +28 -17
  2. package/dist/lithent.mjs +135 -140
  3. package/dist/lithent.mjs.map +1 -1
  4. package/dist/lithent.umd.js +1 -1
  5. package/dist/lithent.umd.js.map +1 -1
  6. package/dist/types/index.d.ts +6 -6
  7. package/dist/utils/index.d.ts +16 -0
  8. package/dist/utils/predicator.d.ts +1 -0
  9. package/dist/utils/universalRef.d.ts +6 -6
  10. package/dist/wDom.d.ts +2 -2
  11. package/examples/dist/assets/index.1e9792b7.js +2 -0
  12. package/examples/dist/assets/index.1e9792b7.js.map +1 -0
  13. package/examples/dist/index.html +1 -1
  14. package/examples/src/index.tsx +1 -1
  15. package/examples/src/sharedStore.tsx +1 -1
  16. package/package.json +3 -2
  17. package/src/diff.ts +22 -24
  18. package/src/hook/mountCallback.ts +6 -6
  19. package/src/hook/unmount.ts +7 -7
  20. package/src/hook/useUpdate.ts +6 -6
  21. package/src/render.ts +51 -57
  22. package/src/tests/fragment.tsx +38 -0
  23. package/src/tests/loopWithoutKey.tsx +55 -0
  24. package/src/tests/{example17.tsx → test17.tsx} +1 -1
  25. package/src/types/index.ts +6 -6
  26. package/src/utils/index.ts +7 -5
  27. package/src/utils/predicator.ts +10 -2
  28. package/src/utils/universalRef.ts +23 -28
  29. package/src/wDom.ts +25 -30
  30. package/examples/dist/assets/index.2b484d3b.js +0 -2
  31. package/examples/dist/assets/index.2b484d3b.js.map +0 -1
  32. /package/src/tests/{example1.tsx → test1.tsx} +0 -0
  33. /package/src/tests/{example10.tsx → test10.tsx} +0 -0
  34. /package/src/tests/{example11.tsx → test11.tsx} +0 -0
  35. /package/src/tests/{example12.tsx → test12.tsx} +0 -0
  36. /package/src/tests/{example13.tsx → test13.tsx} +0 -0
  37. /package/src/tests/{example14.tsx → test14.tsx} +0 -0
  38. /package/src/tests/{example15.tsx → test15.tsx} +0 -0
  39. /package/src/tests/{example16.tsx → test16.tsx} +0 -0
  40. /package/src/tests/{example2.tsx → test2.tsx} +0 -0
  41. /package/src/tests/{example3.tsx → test3.tsx} +0 -0
  42. /package/src/tests/{example4.tsx → test4.tsx} +0 -0
  43. /package/src/tests/{example5.tsx → test5.tsx} +0 -0
  44. /package/src/tests/{example6.tsx → test6.tsx} +0 -0
  45. /package/src/tests/{example7.tsx → test7.tsx} +0 -0
  46. /package/src/tests/{example8.tsx → test8.tsx} +0 -0
  47. /package/src/tests/{example9.tsx → test9.tsx} +0 -0
@@ -1,6 +1,6 @@
1
1
  // example.jsx
2
2
  import { h, render, mount } from 'lithent';
3
- import { store } from 'lithent-helper';
3
+ import { store } from 'lithent/helper';
4
4
 
5
5
  const assignShardStore = store<{ text: string; count: number }>({
6
6
  text: 'sharedText',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lithent",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "An extensible virtual DOM library for lightweight use in a variety of environments.",
5
5
  "packageManager": "pnpm@7.6.0",
6
6
  "main": "./dist/lithent.umd.js",
@@ -17,7 +17,8 @@
17
17
  "build": "pnpm build:core && pnpm build:helper && pnpm build:examples && pnpm build:docs",
18
18
  "build:p": "pnpm build:core && pnpm -r build",
19
19
  "dev": "pnpm watch:core & pnpm watch:helper & pnpm dev:examples",
20
- "test": "vitest",
20
+ "test": "vitest run --reporter verbose",
21
+ "test:dev": "vitest",
21
22
  "coverage": "vitest run --coverage",
22
23
  "clean": "pnpm clean:dist && pnpm clean:module",
23
24
  "clean:dist": "pnpm -r exec rm -rf dist && rm -rf dist",
package/src/diff.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { WDom, TagFunctionResolver, RenderType } from '@/types';
2
- import { checkCustemComponentFunction } from '@/utils/predicator';
2
+ import { checkCustemComponentFunction, getKey } from '@/utils/predicator';
3
3
  import { getParent, reRender } from '@/utils';
4
4
  import { recursiveRemoveEvent } from '@/render';
5
5
  import {
@@ -27,38 +27,39 @@ const remakeNewWDom = (
27
27
  originalWDom?: WDom
28
28
  ) => {
29
29
  const remakeWDom = generalize(newWDom, isSameType, originalWDom);
30
-
31
- remakeWDom.children = remakeChildrenForDiff(
32
- remakeWDom,
33
- isSameType,
34
- originalWDom
35
- );
36
-
37
- const needRerender = addReRenderTypeProperty(
30
+ const param: [newWDom: WDom, isSameType: boolean, originalWDom?: WDom] = [
38
31
  remakeWDom,
39
32
  isSameType,
40
- originalWDom
41
- );
33
+ originalWDom,
34
+ ];
35
+ const needRerender = addReRenderTypeProperty(...param);
42
36
 
37
+ remakeWDom.children = remakeChildrenForDiff(...param);
43
38
  remakeWDom.needRerender = needRerender;
44
39
 
40
+ inheritPropForRender(remakeWDom, originalWDom, needRerender);
41
+
42
+ return remakeWDom;
43
+ };
44
+
45
+ const inheritPropForRender = (
46
+ remakeWDom: WDom,
47
+ originalWDom?: WDom,
48
+ needRerender?: RenderType
49
+ ) => {
45
50
  if (needRerender !== 'A' && originalWDom) {
46
51
  remakeWDom.el = originalWDom.el;
47
52
  }
48
53
 
49
- if (
50
- needRerender &&
51
- ['D', 'R', 'SR'].includes(needRerender) &&
52
- originalWDom?.componentKey
53
- ) {
54
- runUnmountQueueFromWDom(originalWDom);
55
- recursiveRemoveEvent(originalWDom);
56
- remakeWDom.oldChildren = originalWDom.children;
54
+ if (needRerender && ['D', 'R', 'SR'].includes(needRerender)) {
55
+ if (originalWDom?.compKey) {
56
+ runUnmountQueueFromWDom(originalWDom);
57
+ recursiveRemoveEvent(originalWDom);
58
+ }
59
+ remakeWDom.oldChildren = originalWDom?.children;
57
60
  }
58
61
 
59
62
  remakeWDom.oldProps = originalWDom?.props;
60
-
61
- return remakeWDom;
62
63
  };
63
64
 
64
65
  const addReRenderTypeProperty = (
@@ -185,6 +186,3 @@ const findSameKeyOriginalItem = (item: WDom, originalChildren: WDom[]) =>
185
186
  originalChildren.find(
186
187
  orignalChildItem => getKey(orignalChildItem) === getKey(item)
187
188
  );
188
-
189
- const getKey = (target: WDom) =>
190
- target?.componentProps?.key ?? target?.props?.key;
@@ -1,6 +1,6 @@
1
1
  import { WDom } from '@/types';
2
2
  import {
3
- componentKeyRef,
3
+ compKeyRef,
4
4
  componentRef,
5
5
  getComponentKey,
6
6
  } from '@/utils/universalRef';
@@ -13,7 +13,7 @@ export const execMountedQueue = () => {
13
13
  mountedQueue = [];
14
14
  };
15
15
  export const addMountedQueue = (wDom: WDom) => {
16
- if (wDom.componentKey) {
16
+ if (wDom.compKey) {
17
17
  mountedQueue.push(wDom);
18
18
  }
19
19
  };
@@ -21,14 +21,14 @@ export const mountCallback = (effectAction: () => void) =>
21
21
  componentRef.get(getComponentKey())!.mts.push(effectAction);
22
22
 
23
23
  export const runMountedQueueFromWDom = (newWDom: WDom) => {
24
- const { componentKey } = newWDom;
24
+ const { compKey } = newWDom;
25
25
 
26
- if (componentKey) {
27
- const component = componentRef.get(componentKey);
26
+ if (compKey) {
27
+ const component = componentRef.get(compKey);
28
28
  const queue = component?.mts;
29
29
  const sequence = component?.upS;
30
30
 
31
- componentKeyRef.value = componentKey;
31
+ compKeyRef.value = compKey;
32
32
 
33
33
  if (sequence) {
34
34
  sequence.value = 0;
@@ -6,17 +6,17 @@ export const unmount = (effectAction: () => void) => {
6
6
  };
7
7
 
8
8
  export const runUnmountQueueFromWDom = (newWDom: WDom) => {
9
- const { componentKey } = newWDom;
9
+ const { compKey } = newWDom;
10
10
 
11
- if (componentKey) {
12
- removeItem(componentKey);
11
+ if (compKey) {
12
+ removeItem(compKey);
13
13
  }
14
14
  recursiveRunUnmount(newWDom);
15
15
  };
16
16
 
17
17
  const recursiveRunUnmount = (wDom: WDom) => {
18
18
  (wDom.children || []).forEach(item => {
19
- const childComKey = item.componentKey;
19
+ const childComKey = item.compKey;
20
20
  if (childComKey) {
21
21
  runUnmountQueueFromWDom(item);
22
22
  } else {
@@ -25,11 +25,11 @@ const recursiveRunUnmount = (wDom: WDom) => {
25
25
  });
26
26
  };
27
27
 
28
- const removeItem = (componentKey: Props) => {
29
- const subInfo = componentRef.get(componentKey);
28
+ const removeItem = (compKey: Props) => {
29
+ const subInfo = componentRef.get(compKey);
30
30
  if (subInfo) {
31
31
  subInfo!.umts.forEach(effect => effect());
32
32
  subInfo!.umts = [];
33
- componentRef.delete(componentKey);
33
+ componentRef.delete(compKey);
34
34
  }
35
35
  };
@@ -1,6 +1,6 @@
1
1
  import { WDom } from '@/types';
2
2
  import {
3
- componentKeyRef,
3
+ compKeyRef,
4
4
  componentRef,
5
5
  getComponentKey,
6
6
  } from '@/utils/universalRef';
@@ -25,20 +25,20 @@ export const useUpdated = (
25
25
  };
26
26
 
27
27
  export const runUpdatedQueueFromWDom = (newWDom: WDom) => {
28
- const { componentKey } = newWDom;
28
+ const { compKey } = newWDom;
29
29
 
30
- if (componentKey) {
31
- const component = componentRef.get(componentKey);
30
+ if (compKey) {
31
+ const component = componentRef.get(compKey);
32
32
  const queue = component?.upCB;
33
33
  const sequence = component?.upS;
34
34
 
35
- componentKeyRef.value = componentKey;
35
+ compKeyRef.value = compKey;
36
36
 
37
37
  if (sequence) {
38
38
  sequence.value = 0;
39
39
  }
40
40
 
41
- if (newWDom.constructor && queue) {
41
+ if (newWDom.ctor && queue) {
42
42
  component.upCB = [];
43
43
  queue.forEach((effect: Function) => effect());
44
44
  }
package/src/render.ts CHANGED
@@ -14,7 +14,7 @@ import { componentRef, xmlnsRef } from '@/utils/universalRef';
14
14
  import { runUnmountQueueFromWDom } from '@/hook/unmount';
15
15
  import { execMountedQueue, addMountedQueue } from '@/hook/mountCallback';
16
16
  import { runUpdatedQueueFromWDom } from '@/hook/useUpdate';
17
- import { getParent, getEventName, getAttrKey } from '@/utils';
17
+ import { getParent, getEventName, getAttrKey, entries, keys } from '@/utils';
18
18
 
19
19
  export const render = (
20
20
  wDom: WDom,
@@ -37,7 +37,7 @@ export const render = (
37
37
  execMountedQueue();
38
38
 
39
39
  return () => {
40
- const component = componentRef.get(wDom.componentProps || {})?.vd.value;
40
+ const component = componentRef.get(wDom.compProps || {})?.vd.value;
41
41
  if (component) {
42
42
  runUnmountQueueFromWDom(component);
43
43
  recursiveRemoveEvent(component);
@@ -218,16 +218,14 @@ const removeEvent = (
218
218
  oldProps: Props,
219
219
  element: HTMLElement | DocumentFragment | Text
220
220
  ) => {
221
- Object.entries(oldProps || {}).forEach(
222
- ([dataKey, dataValue]: [string, unknown]) => {
223
- if (dataKey.match(/^on/)) {
224
- element.removeEventListener(
225
- getEventName(dataKey),
226
- dataValue as (e: Event) => void
227
- );
228
- }
221
+ entries(oldProps || {}).forEach(([dataKey, dataValue]: [string, unknown]) => {
222
+ if (dataKey.match(/^on/)) {
223
+ element.removeEventListener(
224
+ getEventName(dataKey),
225
+ dataValue as (e: Event) => void
226
+ );
229
227
  }
230
- );
228
+ });
231
229
  };
232
230
 
233
231
  const typeUpdate = (newWDom: WDom) => {
@@ -271,55 +269,51 @@ const updateProps = (
271
269
  ) => {
272
270
  const originalProps = { ...oldProps };
273
271
 
274
- Object.entries(props || {}).forEach(
275
- ([dataKey, dataValue]: [string, unknown]) => {
276
- if (dataKey === 'key') {
277
- // Do nothing
278
- } else if (dataKey === 'innerHTML' && typeof dataValue === 'string') {
279
- (element as HTMLElement).innerHTML = dataValue;
280
- } else if (checkStyleData(dataKey, dataValue)) {
281
- updateStyle(
282
- dataValue,
283
- checkStyleData(dataKey, originalProps.style)
284
- ? originalProps.style
285
- : {},
286
- element
272
+ entries(props || {}).forEach(([dataKey, dataValue]: [string, unknown]) => {
273
+ if (dataKey === 'key') {
274
+ // Do nothing
275
+ } else if (dataKey === 'innerHTML' && typeof dataValue === 'string') {
276
+ (element as HTMLElement).innerHTML = dataValue;
277
+ } else if (checkStyleData(dataKey, dataValue)) {
278
+ updateStyle(
279
+ dataValue,
280
+ checkStyleData(dataKey, originalProps.style) ? originalProps.style : {},
281
+ element
282
+ );
283
+ } else if (checkRefData(dataKey, dataValue)) {
284
+ dataValue.value = element;
285
+ } else if (dataKey.match(/^on/)) {
286
+ updateEvent(
287
+ element as HTMLElement,
288
+ dataKey,
289
+ dataValue as (e: Event) => void,
290
+ originalProps[dataKey] as (e: Event) => void
291
+ );
292
+ } else if (checkCheckableElement(element) && dataKey === 'checked') {
293
+ (element as HTMLInputElement).checked = !!dataValue;
294
+ } else if (checkTextareaElement(element) && dataKey === 'value') {
295
+ (element as HTMLInputElement).value = dataValue as string;
296
+ } else if (checkOptionElement(element) && dataKey === 'selected') {
297
+ (element as HTMLOptionElement).selected = !!dataValue;
298
+ } else if (checkNormalAttribute(dataValue)) {
299
+ if (xmlnsRef.value && dataKey !== 'xmlns') {
300
+ (element as HTMLElement).setAttributeNS(
301
+ null,
302
+ getAttrKey(dataKey),
303
+ String(dataValue)
287
304
  );
288
- } else if (checkRefData(dataKey, dataValue)) {
289
- dataValue.value = element;
290
- } else if (dataKey.match(/^on/)) {
291
- updateEvent(
292
- element as HTMLElement,
293
- dataKey,
294
- dataValue as (e: Event) => void,
295
- originalProps[dataKey] as (e: Event) => void
305
+ } else {
306
+ (element as HTMLElement).setAttribute(
307
+ getAttrKey(dataKey),
308
+ String(dataValue)
296
309
  );
297
- } else if (checkCheckableElement(element) && dataKey === 'checked') {
298
- (element as HTMLInputElement).checked = !!dataValue;
299
- } else if (checkTextareaElement(element) && dataKey === 'value') {
300
- (element as HTMLInputElement).value = dataValue as string;
301
- } else if (checkOptionElement(element) && dataKey === 'selected') {
302
- (element as HTMLOptionElement).selected = !!dataValue;
303
- } else if (checkNormalAttribute(dataValue)) {
304
- if (xmlnsRef.value && dataKey !== 'xmlns') {
305
- (element as HTMLElement).setAttributeNS(
306
- null,
307
- getAttrKey(dataKey),
308
- String(dataValue)
309
- );
310
- } else {
311
- (element as HTMLElement).setAttribute(
312
- getAttrKey(dataKey),
313
- String(dataValue)
314
- );
315
- }
316
310
  }
317
-
318
- delete originalProps[dataKey];
319
311
  }
320
- );
321
312
 
322
- Object.keys(originalProps).forEach(dataKey =>
313
+ delete originalProps[dataKey];
314
+ });
315
+
316
+ keys(originalProps).forEach(dataKey =>
323
317
  (element as HTMLElement).removeAttribute(dataKey)
324
318
  );
325
319
  };
@@ -407,12 +401,12 @@ const updateStyle = (
407
401
  const elementStyle = (element as HTMLElement)?.style;
408
402
 
409
403
  if (elementStyle) {
410
- Object.entries(style).forEach(([styleKey, dataValue]) => {
404
+ entries(style).forEach(([styleKey, dataValue]) => {
411
405
  (elementStyle as any)[styleKey] = dataValue;
412
406
  delete originalStyle[styleKey];
413
407
  });
414
408
 
415
- Object.entries(originalStyle).forEach(
409
+ entries(originalStyle).forEach(
416
410
  ([styleKey]) => ((elementStyle as any)[styleKey] = '')
417
411
  );
418
412
  }
@@ -0,0 +1,38 @@
1
+ import { mount, render, Fragment, h } from '@/index';
2
+
3
+ const Loop = mount(function (renew) {
4
+ let pType: boolean = true;
5
+ const handle = () => {
6
+ pType = false;
7
+ renew();
8
+ };
9
+
10
+ return () => (
11
+ <div>
12
+ <button onClick={handle}>handle</button>
13
+ <div>start</div>
14
+ {pType ? (
15
+ <Fragment>
16
+ <div>1</div>
17
+ <div>2</div>
18
+ <div>3</div>
19
+ <div>4</div>
20
+ </Fragment>
21
+ ) : (
22
+ <Fragment>
23
+ <div>two</div>
24
+ <div>three</div>
25
+ <div>four</div>
26
+ </Fragment>
27
+ )}
28
+ <div>end</div>
29
+ </div>
30
+ );
31
+ });
32
+
33
+ const Root = <Loop />;
34
+
35
+ //@ts-ignore
36
+ window.root = Root;
37
+
38
+ render(Root, document.getElementById('root'));
@@ -0,0 +1,55 @@
1
+ import { mount, render, Fragment, ref, h, nextTick } from '@/index';
2
+ const testChangeRef = ref<null | (() => void)>(null);
3
+
4
+ const Loop = mount(function (renew) {
5
+ let list: { value: string }[] = [
6
+ { value: '일' },
7
+ { value: '이' },
8
+ { value: '삼' },
9
+ { value: '사' },
10
+ ];
11
+ const handle = () => {
12
+ list = [{ value: '사사' }, { value: '삼삼' }, { value: '이이' }];
13
+ renew();
14
+ };
15
+
16
+ testChangeRef.value = () => {
17
+ handle();
18
+ };
19
+
20
+ return () => (
21
+ <Fragment>
22
+ <button onClick={handle}>handle</button>
23
+ <div>first</div>
24
+ {list.map(item => (
25
+ <div>{item.value}</div>
26
+ ))}
27
+ <div>end</div>
28
+ </Fragment>
29
+ );
30
+ });
31
+
32
+ const testWrap =
33
+ document.getElementById('root') || document.createElement('div');
34
+
35
+ render(<Loop />, testWrap);
36
+
37
+ if (import.meta.vitest) {
38
+ const { it, expect } = import.meta.vitest;
39
+ it('It should be reflected in the DOM exactly in the order of the loop initialization.', () => {
40
+ expect(testWrap.outerHTML).toBe(
41
+ '<div><button>handle</button><div>first</div><div>일</div><div>이</div><div>삼</div><div>사</div><div>end</div></div>'
42
+ );
43
+ });
44
+
45
+ it('Even if there are no keys in the loop, "replace" should be reflected correctly.', () => {
46
+ if (testChangeRef.value) {
47
+ testChangeRef.value();
48
+ }
49
+ nextTick().then(() => {
50
+ expect(testWrap.outerHTML).toBe(
51
+ '<div><button>handle</button><div>first</div><div>사사</div><div>삼삼</div><div>이이</div><div>end</div></div>'
52
+ );
53
+ });
54
+ });
55
+ }
@@ -42,7 +42,7 @@ render(<Root />, testWrap);
42
42
 
43
43
  if (import.meta.vitest) {
44
44
  const { it, expect } = import.meta.vitest;
45
- it('Is renew working properly?', () => {
45
+ it('Lithent draws the svg correctly.', () => {
46
46
  expect(testWrap.outerHTML).toBe(
47
47
  '<div><svg id="toggleSidebarMobileClose" class="w-6 h-6 " fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" clip-rule="evenodd"></path></svg><svg class="w-6 h-6" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M3 5a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zM3 10a1 1 0 011-1h6a1 1 0 110 2H4a1 1 0 01-1-1zM3 15a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1z" clip-rule="evenodd"></path><path fill-rule="evenodd" d="M3 5a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zM3 10a1 1 0 011-1h6a1 1 0 110 2H4a1 1 0 01-1-1zM3 15a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1z" clip-rule="evenodd"></path></svg></div>'
48
48
  );
@@ -16,10 +16,10 @@ export type Component<T> = (
16
16
 
17
17
  export type TagFunctionResolver = {
18
18
  tagName: string;
19
- constructor: Function;
19
+ ctor: Function;
20
20
  props: Props;
21
21
  children: WDom[];
22
- resolve: (componentKey?: Props) => WDom;
22
+ resolve: (compKey?: Props) => WDom;
23
23
  };
24
24
 
25
25
  export type FragmentFunction = (props: Props, children: WDom[]) => WDom;
@@ -46,15 +46,15 @@ export interface WDom {
46
46
  props?: Props;
47
47
  oldProps?: Props;
48
48
  tagName?: string;
49
- constructor?: Function;
49
+ ctor?: Function;
50
50
  children?: WDom[];
51
51
  oldChildren?: WDom[];
52
52
  getParent?: () => WDom | undefined;
53
53
  text?: string | number;
54
- componentKey?: Props;
54
+ compKey?: Props;
55
55
  reRender?: () => WDom;
56
- componentProps?: Props;
57
- componentChildren?: WDom[];
56
+ compProps?: Props;
57
+ compChild?: WDom[];
58
58
  wrapElement?: HTMLElement;
59
59
  afterElement?: HTMLElement;
60
60
  el?: HTMLElement | DocumentFragment | Text;
@@ -7,7 +7,7 @@ export const getParent = (vDom: WDom) => {
7
7
  };
8
8
 
9
9
  export const reRender = (vDom: WDom, infoVdom: TagFunctionResolver) => {
10
- const { componentProps: props, componentChildren: children } = vDom;
10
+ const { compProps: props, compChild: children } = vDom;
11
11
  const { props: infoProps, children: infoChidren } = infoVdom;
12
12
 
13
13
  if (props) {
@@ -29,13 +29,15 @@ export const getEventName = (eventKey: string) =>
29
29
  export const getAttrKey = (keyName: string) =>
30
30
  keyName === 'className' ? 'class' : keyName;
31
31
 
32
+ export const entries = Object.entries;
33
+ export const keys = Object.keys;
34
+ export const assign = Object.assign;
35
+
32
36
  const updateProps = (props: Props, infoProps: Props) => {
33
37
  if (props && infoProps !== props) {
34
- Object.keys(props).forEach(key => delete props[key]);
38
+ keys(props).forEach(key => delete props[key]);
35
39
 
36
- Object.entries(infoProps || {}).forEach(
37
- ([key, value]) => (props[key] = value)
38
- );
40
+ entries(infoProps || {}).forEach(([key, value]) => (props[key] = value));
39
41
  }
40
42
  };
41
43
 
@@ -27,7 +27,10 @@ const checkPlainType = (wDom: WDomParam, typeName: string) =>
27
27
  const checkSameCustomComponent = (
28
28
  newWDom: WDom | TagFunction | TagFunctionResolver,
29
29
  originalWDom?: WDom
30
- ) => newWDom.constructor === originalWDom?.constructor;
30
+ ) =>
31
+ 'ctor' in newWDom
32
+ ? newWDom.ctor === originalWDom?.ctor
33
+ : newWDom === originalWDom?.ctor;
31
34
 
32
35
  const checkSameFragment = (
33
36
  newWDom: WDom | TagFunction | TagFunctionResolver,
@@ -53,7 +56,12 @@ const checkNormalTypeElement = (
53
56
  checkPlainWDomType(newWDom) &&
54
57
  originalWDom?.type === newWDom.type &&
55
58
  (originalWDom?.children?.length === newWDom?.children?.length ||
56
- newWDom.type === 'loop');
59
+ (newWDom.type === 'loop' &&
60
+ checkExisty(getKey((newWDom.children || [])[0])) &&
61
+ checkExisty(getKey((originalWDom.children || [])[0]))));
62
+
63
+ export const getKey = (target: WDom) =>
64
+ target?.compProps?.key ?? target?.props?.key;
57
65
 
58
66
  export const checkVirtualType = (type: string | null) =>
59
67
  type && ['fragment', 'loop'].includes(type);
@@ -1,23 +1,23 @@
1
1
  import { ComponentRef, ComponentSubKey, Props, WDom } from '@/types';
2
2
 
3
3
  type RedrawQueueList = {
4
- componentKey: Props;
4
+ compKey: Props;
5
5
  exec: () => void;
6
6
  }[];
7
7
 
8
- let redrawQueue: { componentKey: Props; exec: () => void }[] = [];
8
+ let redrawQueue: { compKey: Props; exec: () => void }[] = [];
9
9
  let redrawQueueTimeout: boolean = false;
10
10
 
11
11
  /**
12
12
  * Common
13
13
  */
14
14
  export const xmlnsRef: { value: string } = { value: '' };
15
- export const componentKeyRef: { value: Props } = { value: {} };
15
+ export const compKeyRef: { value: Props } = { value: {} };
16
16
  export const needDiffRef: { value: boolean } = { value: false };
17
17
  export const componentRef: ComponentRef = new WeakMap();
18
18
 
19
- export const componentRender = (componentKey: Props) => () => {
20
- const up = componentRef.get(componentKey)?.up;
19
+ export const componentRender = (compKey: Props) => () => {
20
+ const up = componentRef.get(compKey)?.up;
21
21
  let result = false;
22
22
  if (up) {
23
23
  up();
@@ -27,8 +27,8 @@ export const componentRender = (componentKey: Props) => () => {
27
27
  return result;
28
28
  };
29
29
 
30
- const setComponetRef = (componentKey: Props) => {
31
- componentRef.set(componentKey, {
30
+ const setComponetRef = (compKey: Props) => {
31
+ componentRef.set(compKey, {
32
32
  vd: { value: null },
33
33
  up: () => {},
34
34
  upR: [],
@@ -40,17 +40,15 @@ const setComponetRef = (componentKey: Props) => {
40
40
  });
41
41
  };
42
42
 
43
- export const getComponentKey = () => componentKeyRef.value;
43
+ export const getComponentKey = () => compKeyRef.value;
44
44
 
45
- export const getComponentSubInfo = (
46
- componentKey: Props,
47
- subKey: ComponentSubKey
48
- ) => componentRef.get(componentKey)![subKey];
45
+ export const getComponentSubInfo = (compKey: Props, subKey: ComponentSubKey) =>
46
+ componentRef.get(compKey)![subKey];
49
47
 
50
- export const setRedrawAction = (componentKey: Props, exec: () => void) => {
51
- componentRef.get(componentKey)!.up = () => {
48
+ export const setRedrawAction = (compKey: Props, exec: () => void) => {
49
+ componentRef.get(compKey)!.up = () => {
52
50
  redrawQueue.push({
53
- componentKey,
51
+ compKey,
54
52
  exec,
55
53
  });
56
54
 
@@ -61,17 +59,17 @@ export const setRedrawAction = (componentKey: Props, exec: () => void) => {
61
59
  };
62
60
  };
63
61
 
64
- export const initUpdateHookState = (componentKey: Props) =>
65
- (componentKeyRef.value = componentKey);
62
+ export const initUpdateHookState = (compKey: Props) =>
63
+ (compKeyRef.value = compKey);
66
64
 
67
- export const initMountHookState = (componentKey: Props) => {
68
- componentKeyRef.value = componentKey;
69
- setComponetRef(componentKey);
65
+ export const initMountHookState = (compKey: Props) => {
66
+ compKeyRef.value = compKey;
67
+ setComponetRef(compKey);
70
68
  };
71
69
 
72
70
  const recursiveGetChildKeys = (wDom: WDom, result: Props[]) => {
73
71
  (wDom.children || []).forEach(item => {
74
- const childComKey = item.componentKey;
72
+ const childComKey = item.compKey;
75
73
  if (childComKey) {
76
74
  result.push(childComKey);
77
75
  }
@@ -84,7 +82,7 @@ const execRedrawQueue = () => {
84
82
  let childItemList: Props[] = [];
85
83
 
86
84
  redrawQueue.forEach(item => {
87
- const childVd = componentRef.get(item.componentKey)?.vd?.value;
85
+ const childVd = componentRef.get(item.compKey)?.vd?.value;
88
86
  if (childVd) {
89
87
  recursiveGetChildKeys(childVd, childItemList);
90
88
  }
@@ -92,16 +90,13 @@ const execRedrawQueue = () => {
92
90
 
93
91
  const addedKey: Props[] = [];
94
92
  const result = redrawQueue.reduce((acc, item) => {
95
- const { componentKey } = item;
93
+ const { compKey } = item;
96
94
 
97
- if (
98
- childItemList.includes(componentKey) ||
99
- addedKey.includes(componentKey)
100
- ) {
95
+ if (childItemList.includes(compKey) || addedKey.includes(compKey)) {
101
96
  return acc;
102
97
  }
103
98
 
104
- addedKey.push(componentKey);
99
+ addedKey.push(compKey);
105
100
  acc.push(item);
106
101
 
107
102
  return acc;