lithent 1.19.1 → 1.20.1
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/README.md +15 -15
- package/devHelper/dist/componentMapControl.d.ts +4 -0
- package/devHelper/dist/createBoundary.d.ts +10 -0
- package/devHelper/dist/index.d.ts +2 -0
- package/devHelper/dist/lithentDevHelper.mjs +72 -0
- package/devHelper/dist/lithentDevHelper.mjs.map +1 -0
- package/devHelper/dist/lithentDevHelper.umd.js +2 -0
- package/devHelper/dist/lithentDevHelper.umd.js.map +1 -0
- package/devHelper/package.json +35 -0
- package/devHelper/src/componentMapControl.ts +20 -0
- package/devHelper/src/createBoundary.ts +160 -0
- package/devHelper/src/index.ts +2 -0
- package/devHelper/src/tests/hmrBoundary.tsx +290 -0
- package/dist/hook/internal/useUpdate.d.ts +3 -1
- package/dist/hook/updateCallback.d.ts +3 -1
- package/dist/index.d.ts +3 -2
- package/dist/lithent.mjs +265 -251
- package/dist/lithent.mjs.map +1 -1
- package/dist/lithent.umd.js +1 -1
- package/dist/lithent.umd.js.map +1 -1
- package/dist/types/index.d.ts +1 -3
- package/dist/utils/index.d.ts +2 -2
- package/dist/utils/universalRef.d.ts +4 -0
- package/dist/wDom.d.ts +4 -4
- package/examples/dist/assets/index-Ch3C2eh3.js +2 -0
- package/examples/dist/assets/index-Ch3C2eh3.js.map +1 -0
- package/examples/dist/index.html +1 -1
- package/ftags/dist/index.d.ts +5 -5
- package/jsx-runtime/dist/index.d.ts +2 -2
- package/package.json +45 -30
- package/src/diff.ts +11 -7
- package/src/hook/internal/unmount.ts +9 -5
- package/src/hook/internal/useUpdate.ts +7 -3
- package/src/hook/updateCallback.ts +3 -1
- package/src/index.ts +5 -1
- package/src/render.ts +17 -10
- package/src/tests/core-childrentest.tsx +0 -1
- package/src/tests/core-parentChildSync.tsx +103 -0
- package/src/tests/core-styleUpdate.tsx +49 -0
- package/src/types/index.ts +2 -2
- package/src/utils/universalRef.ts +20 -0
- package/src/wDom.ts +17 -1
- package/tag/dist/index.d.ts +4 -4
- package/examples/dist/assets/index-CqMCFcHq.js +0 -2
- package/examples/dist/assets/index-CqMCFcHq.js.map +0 -1
package/README.md
CHANGED
|
@@ -92,14 +92,14 @@ pnpm add lithent
|
|
|
92
92
|
|
|
93
93
|
#### Or Use CDN
|
|
94
94
|
|
|
95
|
-
* UMD : https://cdn.jsdelivr.net/npm/lithent@1.
|
|
96
|
-
* UMD-HELPER: https://cdn.jsdelivr.net/npm/lithent@1.
|
|
97
|
-
* UMD-FTAGS: https://cdn.jsdelivr.net/npm/lithent@1.
|
|
98
|
-
* UMD-TAG: https://cdn.jsdelivr.net/npm/lithent@1.
|
|
99
|
-
* ESM : https://cdn.jsdelivr.net/npm/lithent@1.
|
|
100
|
-
* ESM-HELPER: https://cdn.jsdelivr.net/npm/lithent@1.
|
|
101
|
-
* ESM-FTAGS: https://cdn.jsdelivr.net/npm/lithent@1.
|
|
102
|
-
* ESM-TAG: https://cdn.jsdelivr.net/npm/lithent@1.
|
|
95
|
+
* UMD : https://cdn.jsdelivr.net/npm/lithent@1.20.1/dist/lithent.umd.js
|
|
96
|
+
* UMD-HELPER: https://cdn.jsdelivr.net/npm/lithent@1.20.1/helper/dist/lithentHelper.umd.js
|
|
97
|
+
* UMD-FTAGS: https://cdn.jsdelivr.net/npm/lithent@1.20.1/ftags/dist/lithentFTags.umd.js
|
|
98
|
+
* UMD-TAG: https://cdn.jsdelivr.net/npm/lithent@1.20.1/tag/dist/lithentTag.umd.js
|
|
99
|
+
* ESM : https://cdn.jsdelivr.net/npm/lithent@1.20.1/dist/lithent.mjs
|
|
100
|
+
* ESM-HELPER: https://cdn.jsdelivr.net/npm/lithent@1.20.1/helper/dist/lithentHelper.mjs
|
|
101
|
+
* ESM-FTAGS: https://cdn.jsdelivr.net/npm/lithent@1.20.1/ftags/dist/lithentFTags.mjs
|
|
102
|
+
* ESM-TAG: https://cdn.jsdelivr.net/npm/lithent@1.20.1/tag/dist/lithentTag.mjs
|
|
103
103
|
|
|
104
104
|
|
|
105
105
|
It's easier to use lithent with JSX or HTM.
|
|
@@ -124,9 +124,9 @@ import { fTags, fFragment, fMount } from 'lithent/ftags';
|
|
|
124
124
|
const { section, div, p, br, strong } = fTags;
|
|
125
125
|
|
|
126
126
|
/* UMD
|
|
127
|
-
<script src="https://cdn.jsdelivr.net/npm/lithent@1.
|
|
128
|
-
<script src="https://cdn.jsdelivr.net/npm/lithent@1.
|
|
129
|
-
<script src="https://cdn.jsdelivr.net/npm/lithent@1.
|
|
127
|
+
<script src="https://cdn.jsdelivr.net/npm/lithent@1.20.1/dist/lithent.umd.js"></script>
|
|
128
|
+
<script src="https://cdn.jsdelivr.net/npm/lithent@1.20.1/helper/dist/lithentHelper.umd.js"></script>
|
|
129
|
+
<script src="https://cdn.jsdelivr.net/npm/lithent@1.20.1/ftags/dist/lithentFTags.umd.js"></script>
|
|
130
130
|
|
|
131
131
|
const { render } = lithent;
|
|
132
132
|
const { fTags, fMount, fFragment } = lithentFTags;
|
|
@@ -199,10 +199,10 @@ const destroy = render(lTag`<${Component} />`, document.getElementById('root'),
|
|
|
199
199
|
#### With UMD
|
|
200
200
|
|
|
201
201
|
```html
|
|
202
|
-
<script src="https://cdn.jsdelivr.net/npm/lithent@1.
|
|
203
|
-
<!--script src="https://cdn.jsdelivr.net/npm/lithent@1.
|
|
204
|
-
<script src="https://cdn.jsdelivr.net/npm/lithent@1.
|
|
205
|
-
<!--script src="https://cdn.jsdelivr.net/npm/lithent@1.
|
|
202
|
+
<script src="https://cdn.jsdelivr.net/npm/lithent@1.20.1/dist/lithent.umd.js"></script>
|
|
203
|
+
<!--script src="https://cdn.jsdelivr.net/npm/lithent@1.20.1/helper/dist/lithentHelper.umd.js"></script-->
|
|
204
|
+
<script src="https://cdn.jsdelivr.net/npm/lithent@1.20.1/tag/dist/lithentTag.umd.js"></script>
|
|
205
|
+
<!--script src="https://cdn.jsdelivr.net/npm/lithent@1.20.1/ftags/dist/lithentFTags.umd.js"></script-->
|
|
206
206
|
|
|
207
207
|
<div id="root"></div>
|
|
208
208
|
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { CompKey, TagFunction } from 'lithent';
|
|
2
|
+
export type BoundaryController = {
|
|
3
|
+
register: (compKey: CompKey) => () => void;
|
|
4
|
+
update: (nextCtor: TagFunction) => boolean;
|
|
5
|
+
dispose: () => void;
|
|
6
|
+
};
|
|
7
|
+
export declare const registerBoundaryInstance: (moduleId: string, compKey: CompKey) => () => void;
|
|
8
|
+
export declare const disposeBoundary: (moduleId: string) => void;
|
|
9
|
+
export declare const applyBoundaryUpdate: (moduleId: string, nextCtor: TagFunction) => boolean;
|
|
10
|
+
export declare const createBoundary: (moduleId: string) => BoundaryController;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { setComponentMapManualMode as C, disposeComponentEntry as m, componentMap as p, replaceWDom as B } from "lithent";
|
|
2
|
+
let c = 0;
|
|
3
|
+
const R = () => {
|
|
4
|
+
c += 1, C(!0);
|
|
5
|
+
}, b = () => {
|
|
6
|
+
c = Math.max(0, c - 1), c === 0 && C(!1);
|
|
7
|
+
}, w = (t) => {
|
|
8
|
+
m(t);
|
|
9
|
+
}, s = /* @__PURE__ */ new Map(), E = (t) => {
|
|
10
|
+
let e = s.get(t);
|
|
11
|
+
return e || (e = {
|
|
12
|
+
instances: /* @__PURE__ */ new Set(),
|
|
13
|
+
domMap: /* @__PURE__ */ new Map(),
|
|
14
|
+
scheduled: !1,
|
|
15
|
+
pendingCtor: void 0
|
|
16
|
+
}, s.set(t, e)), e;
|
|
17
|
+
}, D = (t, e) => {
|
|
18
|
+
const n = E(t);
|
|
19
|
+
return n.instances.add(e), queueMicrotask(() => {
|
|
20
|
+
var o;
|
|
21
|
+
const r = p.get(e), a = ((o = r == null ? void 0 : r.vd) == null ? void 0 : o.value) ?? null;
|
|
22
|
+
a && n.domMap.set(e, a);
|
|
23
|
+
}), () => {
|
|
24
|
+
const r = s.get(t);
|
|
25
|
+
r && (r.instances.delete(e), r.domMap.delete(e), r.instances.size || s.delete(t));
|
|
26
|
+
};
|
|
27
|
+
}, W = (t) => {
|
|
28
|
+
const e = s.get(t);
|
|
29
|
+
e && Array.from(e.instances).forEach(
|
|
30
|
+
(n) => w(n)
|
|
31
|
+
), s.delete(t), b();
|
|
32
|
+
}, k = (t, e) => {
|
|
33
|
+
const n = s.get(t);
|
|
34
|
+
return n ? (n.pendingCtor = e, n.scheduled || (n.scheduled = !0, queueMicrotask(() => y(t))), !0) : !1;
|
|
35
|
+
}, y = (t) => {
|
|
36
|
+
const e = s.get(t);
|
|
37
|
+
if (!e) return;
|
|
38
|
+
e.scheduled = !1;
|
|
39
|
+
const n = e.pendingCtor;
|
|
40
|
+
if (!n)
|
|
41
|
+
return;
|
|
42
|
+
e.pendingCtor = void 0;
|
|
43
|
+
let r = !1, a = !1;
|
|
44
|
+
e.instances.forEach((o) => {
|
|
45
|
+
var g, M, h;
|
|
46
|
+
const u = p.get(o), v = e.domMap.get(o), i = ((g = u == null ? void 0 : u.vd) == null ? void 0 : g.value) || v;
|
|
47
|
+
if (!i || !i.el) {
|
|
48
|
+
a = !0;
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
const { compProps: l, compChild: f } = i;
|
|
52
|
+
if (!l || !f) {
|
|
53
|
+
a = !0;
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
try {
|
|
57
|
+
B(n, l, f, i);
|
|
58
|
+
const d = ((h = (M = p.get(o)) == null ? void 0 : M.vd) == null ? void 0 : h.value) || i;
|
|
59
|
+
e.domMap.set(o, d), r = !0;
|
|
60
|
+
} catch (d) {
|
|
61
|
+
console.warn(`[Lithent HMR] boundary update 실패: ${t}`, d);
|
|
62
|
+
}
|
|
63
|
+
}), (a && !r || e.pendingCtor) && (e.scheduled || (e.scheduled = !0, setTimeout(() => y(t), 0)));
|
|
64
|
+
}, x = (t) => (R(), {
|
|
65
|
+
register: (e) => D(t, e),
|
|
66
|
+
update: (e) => k(t, e),
|
|
67
|
+
dispose: () => W(t)
|
|
68
|
+
});
|
|
69
|
+
export {
|
|
70
|
+
x as createBoundary
|
|
71
|
+
};
|
|
72
|
+
//# sourceMappingURL=lithentDevHelper.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lithentDevHelper.mjs","sources":["../src/componentMapControl.ts","../src/createBoundary.ts"],"sourcesContent":["import type { CompKey } from 'lithent';\nimport { setComponentMapManualMode, disposeComponentEntry } from 'lithent';\n\nlet manualModeRefCount = 0;\n\nexport const enableComponentMapManualMode = (): void => {\n manualModeRefCount += 1;\n setComponentMapManualMode(true);\n};\n\nexport const disableComponentMapManualMode = (): void => {\n manualModeRefCount = Math.max(0, manualModeRefCount - 1);\n if (manualModeRefCount === 0) {\n setComponentMapManualMode(false);\n }\n};\n\nexport const removeComponentEntry = (compKey: CompKey): void => {\n disposeComponentEntry(compKey);\n};\n","import type { CompKey, TagFunction, WDom } from 'lithent';\nimport { componentMap, replaceWDom } from 'lithent';\nimport {\n disableComponentMapManualMode,\n enableComponentMapManualMode,\n removeComponentEntry,\n} from './componentMapControl';\n\ntype InstanceRegistry = {\n instances: Set<CompKey>;\n domMap: Map<CompKey, WDom>;\n scheduled: boolean;\n pendingCtor?: TagFunction;\n};\n\nconst boundaryRegistry = new Map<string, InstanceRegistry>();\n\nconst getRegistry = (moduleId: string): InstanceRegistry => {\n let registry = boundaryRegistry.get(moduleId);\n\n if (!registry) {\n registry = {\n instances: new Set(),\n domMap: new Map(),\n scheduled: false,\n pendingCtor: undefined,\n };\n boundaryRegistry.set(moduleId, registry);\n }\n\n return registry;\n};\n\nexport type BoundaryController = {\n register: (compKey: CompKey) => () => void;\n update: (nextCtor: TagFunction) => boolean;\n dispose: () => void;\n};\n\nexport const registerBoundaryInstance = (\n moduleId: string,\n compKey: CompKey\n) => {\n const registry = getRegistry(moduleId);\n\n registry.instances.add(compKey);\n\n queueMicrotask(() => {\n const entry = componentMap.get(compKey);\n const currentWDom = entry?.vd?.value ?? null;\n\n if (currentWDom) {\n registry.domMap.set(compKey, currentWDom);\n }\n });\n\n return () => {\n const currentRegistry = boundaryRegistry.get(moduleId);\n if (!currentRegistry) return;\n\n currentRegistry.instances.delete(compKey);\n currentRegistry.domMap.delete(compKey);\n\n if (!currentRegistry.instances.size) {\n boundaryRegistry.delete(moduleId);\n }\n };\n};\n\nexport const disposeBoundary = (moduleId: string) => {\n const registry = boundaryRegistry.get(moduleId);\n\n if (registry) {\n Array.from(registry.instances).forEach(compKey =>\n removeComponentEntry(compKey)\n );\n }\n\n boundaryRegistry.delete(moduleId);\n disableComponentMapManualMode();\n};\n\nexport const applyBoundaryUpdate = (\n moduleId: string,\n nextCtor: TagFunction\n) => {\n const registry = boundaryRegistry.get(moduleId);\n\n if (!registry) return false;\n\n registry.pendingCtor = nextCtor;\n\n if (!registry.scheduled) {\n registry.scheduled = true;\n queueMicrotask(() => flushBoundary(moduleId));\n }\n\n return true;\n};\n\nconst flushBoundary = (moduleId: string) => {\n const registry = boundaryRegistry.get(moduleId);\n if (!registry) return;\n\n registry.scheduled = false;\n\n const ctor = registry.pendingCtor;\n if (!ctor) {\n return;\n }\n\n registry.pendingCtor = undefined;\n\n let updated = false;\n let hasMissing = false;\n\n registry.instances.forEach(compKey => {\n const entry = componentMap.get(compKey);\n const cached = registry.domMap.get(compKey);\n const currentWDom = entry?.vd?.value || cached;\n\n if (!currentWDom || !currentWDom.el) {\n hasMissing = true;\n return;\n }\n\n const { compProps, compChild } = currentWDom;\n\n if (!compProps || !compChild) {\n hasMissing = true;\n return;\n }\n\n try {\n replaceWDom(ctor, compProps, compChild, currentWDom as any);\n const refreshed = componentMap.get(compKey)?.vd?.value || currentWDom;\n registry.domMap.set(compKey, refreshed as WDom);\n updated = true;\n } catch (error) {\n console.warn(`[Lithent HMR] boundary update 실패: ${moduleId}`, error);\n }\n });\n\n if ((hasMissing && !updated) || registry.pendingCtor) {\n if (!registry.scheduled) {\n registry.scheduled = true;\n setTimeout(() => flushBoundary(moduleId), 0);\n }\n }\n};\n\nexport const createBoundary = (moduleId: string): BoundaryController => {\n enableComponentMapManualMode();\n\n return {\n register: (compKey: CompKey) => registerBoundaryInstance(moduleId, compKey),\n update: (nextCtor: TagFunction) => applyBoundaryUpdate(moduleId, nextCtor),\n dispose: () => disposeBoundary(moduleId),\n };\n};\n"],"names":["manualModeRefCount","enableComponentMapManualMode","setComponentMapManualMode","disableComponentMapManualMode","removeComponentEntry","compKey","disposeComponentEntry","boundaryRegistry","getRegistry","moduleId","registry","registerBoundaryInstance","entry","componentMap","currentWDom","_a","currentRegistry","disposeBoundary","applyBoundaryUpdate","nextCtor","flushBoundary","ctor","updated","hasMissing","cached","compProps","compChild","replaceWDom","refreshed","_c","_b","error","createBoundary"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
(function(a,r){typeof exports=="object"&&typeof module<"u"?r(exports,require("lithent")):typeof define=="function"&&define.amd?define(["exports","lithent"],r):(a=typeof globalThis<"u"?globalThis:a||self,r(a.lithentDevHelper={},a.lithent))})(this,function(a,r){"use strict";let d=0;const m=()=>{d+=1,r.setComponentMapManualMode(!0)},v=()=>{d=Math.max(0,d-1),d===0&&r.setComponentMapManualMode(!1)},b=t=>{r.disposeComponentEntry(t)},o=new Map,B=t=>{let e=o.get(t);return e||(e={instances:new Set,domMap:new Map,scheduled:!1,pendingCtor:void 0},o.set(t,e)),e},R=(t,e)=>{const n=B(t);return n.instances.add(e),queueMicrotask(()=>{var i;const s=r.componentMap.get(e),c=((i=s==null?void 0:s.vd)==null?void 0:i.value)??null;c&&n.domMap.set(e,c)}),()=>{const s=o.get(t);s&&(s.instances.delete(e),s.domMap.delete(e),s.instances.size||o.delete(t))}},w=t=>{const e=o.get(t);e&&Array.from(e.instances).forEach(n=>b(n)),o.delete(t),v()},D=(t,e)=>{const n=o.get(t);return n?(n.pendingCtor=e,n.scheduled||(n.scheduled=!0,queueMicrotask(()=>l(t))),!0):!1},l=t=>{const e=o.get(t);if(!e)return;e.scheduled=!1;const n=e.pendingCtor;if(!n)return;e.pendingCtor=void 0;let s=!1,c=!1;e.instances.forEach(i=>{var h,y,C;const p=r.componentMap.get(i),T=e.domMap.get(i),u=((h=p==null?void 0:p.vd)==null?void 0:h.value)||T;if(!u||!u.el){c=!0;return}const{compProps:M,compChild:g}=u;if(!M||!g){c=!0;return}try{r.replaceWDom(n,M,g,u);const f=((C=(y=r.componentMap.get(i))==null?void 0:y.vd)==null?void 0:C.value)||u;e.domMap.set(i,f),s=!0}catch(f){console.warn(`[Lithent HMR] boundary update 실패: ${t}`,f)}}),(c&&!s||e.pendingCtor)&&(e.scheduled||(e.scheduled=!0,setTimeout(()=>l(t),0)))},E=t=>(m(),{register:e=>R(t,e),update:e=>D(t,e),dispose:()=>w(t)});a.createBoundary=E,Object.defineProperty(a,Symbol.toStringTag,{value:"Module"})});
|
|
2
|
+
//# sourceMappingURL=lithentDevHelper.umd.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lithentDevHelper.umd.js","sources":["../src/componentMapControl.ts","../src/createBoundary.ts"],"sourcesContent":["import type { CompKey } from 'lithent';\nimport { setComponentMapManualMode, disposeComponentEntry } from 'lithent';\n\nlet manualModeRefCount = 0;\n\nexport const enableComponentMapManualMode = (): void => {\n manualModeRefCount += 1;\n setComponentMapManualMode(true);\n};\n\nexport const disableComponentMapManualMode = (): void => {\n manualModeRefCount = Math.max(0, manualModeRefCount - 1);\n if (manualModeRefCount === 0) {\n setComponentMapManualMode(false);\n }\n};\n\nexport const removeComponentEntry = (compKey: CompKey): void => {\n disposeComponentEntry(compKey);\n};\n","import type { CompKey, TagFunction, WDom } from 'lithent';\nimport { componentMap, replaceWDom } from 'lithent';\nimport {\n disableComponentMapManualMode,\n enableComponentMapManualMode,\n removeComponentEntry,\n} from './componentMapControl';\n\ntype InstanceRegistry = {\n instances: Set<CompKey>;\n domMap: Map<CompKey, WDom>;\n scheduled: boolean;\n pendingCtor?: TagFunction;\n};\n\nconst boundaryRegistry = new Map<string, InstanceRegistry>();\n\nconst getRegistry = (moduleId: string): InstanceRegistry => {\n let registry = boundaryRegistry.get(moduleId);\n\n if (!registry) {\n registry = {\n instances: new Set(),\n domMap: new Map(),\n scheduled: false,\n pendingCtor: undefined,\n };\n boundaryRegistry.set(moduleId, registry);\n }\n\n return registry;\n};\n\nexport type BoundaryController = {\n register: (compKey: CompKey) => () => void;\n update: (nextCtor: TagFunction) => boolean;\n dispose: () => void;\n};\n\nexport const registerBoundaryInstance = (\n moduleId: string,\n compKey: CompKey\n) => {\n const registry = getRegistry(moduleId);\n\n registry.instances.add(compKey);\n\n queueMicrotask(() => {\n const entry = componentMap.get(compKey);\n const currentWDom = entry?.vd?.value ?? null;\n\n if (currentWDom) {\n registry.domMap.set(compKey, currentWDom);\n }\n });\n\n return () => {\n const currentRegistry = boundaryRegistry.get(moduleId);\n if (!currentRegistry) return;\n\n currentRegistry.instances.delete(compKey);\n currentRegistry.domMap.delete(compKey);\n\n if (!currentRegistry.instances.size) {\n boundaryRegistry.delete(moduleId);\n }\n };\n};\n\nexport const disposeBoundary = (moduleId: string) => {\n const registry = boundaryRegistry.get(moduleId);\n\n if (registry) {\n Array.from(registry.instances).forEach(compKey =>\n removeComponentEntry(compKey)\n );\n }\n\n boundaryRegistry.delete(moduleId);\n disableComponentMapManualMode();\n};\n\nexport const applyBoundaryUpdate = (\n moduleId: string,\n nextCtor: TagFunction\n) => {\n const registry = boundaryRegistry.get(moduleId);\n\n if (!registry) return false;\n\n registry.pendingCtor = nextCtor;\n\n if (!registry.scheduled) {\n registry.scheduled = true;\n queueMicrotask(() => flushBoundary(moduleId));\n }\n\n return true;\n};\n\nconst flushBoundary = (moduleId: string) => {\n const registry = boundaryRegistry.get(moduleId);\n if (!registry) return;\n\n registry.scheduled = false;\n\n const ctor = registry.pendingCtor;\n if (!ctor) {\n return;\n }\n\n registry.pendingCtor = undefined;\n\n let updated = false;\n let hasMissing = false;\n\n registry.instances.forEach(compKey => {\n const entry = componentMap.get(compKey);\n const cached = registry.domMap.get(compKey);\n const currentWDom = entry?.vd?.value || cached;\n\n if (!currentWDom || !currentWDom.el) {\n hasMissing = true;\n return;\n }\n\n const { compProps, compChild } = currentWDom;\n\n if (!compProps || !compChild) {\n hasMissing = true;\n return;\n }\n\n try {\n replaceWDom(ctor, compProps, compChild, currentWDom as any);\n const refreshed = componentMap.get(compKey)?.vd?.value || currentWDom;\n registry.domMap.set(compKey, refreshed as WDom);\n updated = true;\n } catch (error) {\n console.warn(`[Lithent HMR] boundary update 실패: ${moduleId}`, error);\n }\n });\n\n if ((hasMissing && !updated) || registry.pendingCtor) {\n if (!registry.scheduled) {\n registry.scheduled = true;\n setTimeout(() => flushBoundary(moduleId), 0);\n }\n }\n};\n\nexport const createBoundary = (moduleId: string): BoundaryController => {\n enableComponentMapManualMode();\n\n return {\n register: (compKey: CompKey) => registerBoundaryInstance(moduleId, compKey),\n update: (nextCtor: TagFunction) => applyBoundaryUpdate(moduleId, nextCtor),\n dispose: () => disposeBoundary(moduleId),\n };\n};\n"],"names":["manualModeRefCount","enableComponentMapManualMode","setComponentMapManualMode","disableComponentMapManualMode","removeComponentEntry","compKey","disposeComponentEntry","boundaryRegistry","getRegistry","moduleId","registry","registerBoundaryInstance","entry","componentMap","currentWDom","_a","currentRegistry","disposeBoundary","applyBoundaryUpdate","nextCtor","flushBoundary","ctor","updated","hasMissing","cached","compProps","compChild","replaceWDom","refreshed","error","createBoundary"],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"type": "module",
|
|
3
|
+
"name": "lithent-dev-helper",
|
|
4
|
+
"version": "0.21.0",
|
|
5
|
+
"description": "Lithent development helper utilities",
|
|
6
|
+
"private": true,
|
|
7
|
+
"packageManager": "pnpm@7.6.0",
|
|
8
|
+
"main": "./dist/lithentDevHelper.umd.js",
|
|
9
|
+
"module": "./dist/lithentDevHelper.mjs",
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"scripts": {
|
|
12
|
+
"dev": "vite",
|
|
13
|
+
"test:dev": "vitest",
|
|
14
|
+
"test": "vitest run --reporter verbose",
|
|
15
|
+
"watch": "vite build --watch",
|
|
16
|
+
"build": "vite build"
|
|
17
|
+
},
|
|
18
|
+
"author": "",
|
|
19
|
+
"repository": {
|
|
20
|
+
"type": "git",
|
|
21
|
+
"url": "https@github.com:superlucky84/lithent.git"
|
|
22
|
+
},
|
|
23
|
+
"homepage": "https://github.com/superlucky84/lithent",
|
|
24
|
+
"license": "MIT",
|
|
25
|
+
"keywords": ["lithent"],
|
|
26
|
+
"devDependencies": {
|
|
27
|
+
"lithent": "workspace:*"
|
|
28
|
+
},
|
|
29
|
+
"peerDependencies": {
|
|
30
|
+
"lithent": "workspace:*"
|
|
31
|
+
},
|
|
32
|
+
"volta": {
|
|
33
|
+
"node": "20.3.0"
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { CompKey } from 'lithent';
|
|
2
|
+
import { setComponentMapManualMode, disposeComponentEntry } from 'lithent';
|
|
3
|
+
|
|
4
|
+
let manualModeRefCount = 0;
|
|
5
|
+
|
|
6
|
+
export const enableComponentMapManualMode = (): void => {
|
|
7
|
+
manualModeRefCount += 1;
|
|
8
|
+
setComponentMapManualMode(true);
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export const disableComponentMapManualMode = (): void => {
|
|
12
|
+
manualModeRefCount = Math.max(0, manualModeRefCount - 1);
|
|
13
|
+
if (manualModeRefCount === 0) {
|
|
14
|
+
setComponentMapManualMode(false);
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export const removeComponentEntry = (compKey: CompKey): void => {
|
|
19
|
+
disposeComponentEntry(compKey);
|
|
20
|
+
};
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import type { CompKey, TagFunction, WDom } from 'lithent';
|
|
2
|
+
import { componentMap, replaceWDom } from 'lithent';
|
|
3
|
+
import {
|
|
4
|
+
disableComponentMapManualMode,
|
|
5
|
+
enableComponentMapManualMode,
|
|
6
|
+
removeComponentEntry,
|
|
7
|
+
} from './componentMapControl';
|
|
8
|
+
|
|
9
|
+
type InstanceRegistry = {
|
|
10
|
+
instances: Set<CompKey>;
|
|
11
|
+
domMap: Map<CompKey, WDom>;
|
|
12
|
+
scheduled: boolean;
|
|
13
|
+
pendingCtor?: TagFunction;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
const boundaryRegistry = new Map<string, InstanceRegistry>();
|
|
17
|
+
|
|
18
|
+
const getRegistry = (moduleId: string): InstanceRegistry => {
|
|
19
|
+
let registry = boundaryRegistry.get(moduleId);
|
|
20
|
+
|
|
21
|
+
if (!registry) {
|
|
22
|
+
registry = {
|
|
23
|
+
instances: new Set(),
|
|
24
|
+
domMap: new Map(),
|
|
25
|
+
scheduled: false,
|
|
26
|
+
pendingCtor: undefined,
|
|
27
|
+
};
|
|
28
|
+
boundaryRegistry.set(moduleId, registry);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return registry;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export type BoundaryController = {
|
|
35
|
+
register: (compKey: CompKey) => () => void;
|
|
36
|
+
update: (nextCtor: TagFunction) => boolean;
|
|
37
|
+
dispose: () => void;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
export const registerBoundaryInstance = (
|
|
41
|
+
moduleId: string,
|
|
42
|
+
compKey: CompKey
|
|
43
|
+
) => {
|
|
44
|
+
const registry = getRegistry(moduleId);
|
|
45
|
+
|
|
46
|
+
registry.instances.add(compKey);
|
|
47
|
+
|
|
48
|
+
queueMicrotask(() => {
|
|
49
|
+
const entry = componentMap.get(compKey);
|
|
50
|
+
const currentWDom = entry?.vd?.value ?? null;
|
|
51
|
+
|
|
52
|
+
if (currentWDom) {
|
|
53
|
+
registry.domMap.set(compKey, currentWDom);
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
return () => {
|
|
58
|
+
const currentRegistry = boundaryRegistry.get(moduleId);
|
|
59
|
+
if (!currentRegistry) return;
|
|
60
|
+
|
|
61
|
+
currentRegistry.instances.delete(compKey);
|
|
62
|
+
currentRegistry.domMap.delete(compKey);
|
|
63
|
+
|
|
64
|
+
if (!currentRegistry.instances.size) {
|
|
65
|
+
boundaryRegistry.delete(moduleId);
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
export const disposeBoundary = (moduleId: string) => {
|
|
71
|
+
const registry = boundaryRegistry.get(moduleId);
|
|
72
|
+
|
|
73
|
+
if (registry) {
|
|
74
|
+
Array.from(registry.instances).forEach(compKey =>
|
|
75
|
+
removeComponentEntry(compKey)
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
boundaryRegistry.delete(moduleId);
|
|
80
|
+
disableComponentMapManualMode();
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
export const applyBoundaryUpdate = (
|
|
84
|
+
moduleId: string,
|
|
85
|
+
nextCtor: TagFunction
|
|
86
|
+
) => {
|
|
87
|
+
const registry = boundaryRegistry.get(moduleId);
|
|
88
|
+
|
|
89
|
+
if (!registry) return false;
|
|
90
|
+
|
|
91
|
+
registry.pendingCtor = nextCtor;
|
|
92
|
+
|
|
93
|
+
if (!registry.scheduled) {
|
|
94
|
+
registry.scheduled = true;
|
|
95
|
+
queueMicrotask(() => flushBoundary(moduleId));
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return true;
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
const flushBoundary = (moduleId: string) => {
|
|
102
|
+
const registry = boundaryRegistry.get(moduleId);
|
|
103
|
+
if (!registry) return;
|
|
104
|
+
|
|
105
|
+
registry.scheduled = false;
|
|
106
|
+
|
|
107
|
+
const ctor = registry.pendingCtor;
|
|
108
|
+
if (!ctor) {
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
registry.pendingCtor = undefined;
|
|
113
|
+
|
|
114
|
+
let updated = false;
|
|
115
|
+
let hasMissing = false;
|
|
116
|
+
|
|
117
|
+
registry.instances.forEach(compKey => {
|
|
118
|
+
const entry = componentMap.get(compKey);
|
|
119
|
+
const cached = registry.domMap.get(compKey);
|
|
120
|
+
const currentWDom = entry?.vd?.value || cached;
|
|
121
|
+
|
|
122
|
+
if (!currentWDom || !currentWDom.el) {
|
|
123
|
+
hasMissing = true;
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const { compProps, compChild } = currentWDom;
|
|
128
|
+
|
|
129
|
+
if (!compProps || !compChild) {
|
|
130
|
+
hasMissing = true;
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
try {
|
|
135
|
+
replaceWDom(ctor, compProps, compChild, currentWDom as any);
|
|
136
|
+
const refreshed = componentMap.get(compKey)?.vd?.value || currentWDom;
|
|
137
|
+
registry.domMap.set(compKey, refreshed as WDom);
|
|
138
|
+
updated = true;
|
|
139
|
+
} catch (error) {
|
|
140
|
+
console.warn(`[Lithent HMR] boundary update 실패: ${moduleId}`, error);
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
if ((hasMissing && !updated) || registry.pendingCtor) {
|
|
145
|
+
if (!registry.scheduled) {
|
|
146
|
+
registry.scheduled = true;
|
|
147
|
+
setTimeout(() => flushBoundary(moduleId), 0);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
export const createBoundary = (moduleId: string): BoundaryController => {
|
|
153
|
+
enableComponentMapManualMode();
|
|
154
|
+
|
|
155
|
+
return {
|
|
156
|
+
register: (compKey: CompKey) => registerBoundaryInstance(moduleId, compKey),
|
|
157
|
+
update: (nextCtor: TagFunction) => applyBoundaryUpdate(moduleId, nextCtor),
|
|
158
|
+
dispose: () => disposeBoundary(moduleId),
|
|
159
|
+
};
|
|
160
|
+
};
|