lithent 1.18.5 → 1.20.0

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 (82) hide show
  1. package/README.md +79 -16
  2. package/devHelper/dist/componentMapControl.d.ts +4 -0
  3. package/devHelper/dist/createBoundary.d.ts +10 -0
  4. package/devHelper/dist/index.d.ts +2 -0
  5. package/devHelper/dist/lithentDevHelper.mjs +72 -0
  6. package/devHelper/dist/lithentDevHelper.mjs.map +1 -0
  7. package/devHelper/dist/lithentDevHelper.umd.js +2 -0
  8. package/devHelper/dist/lithentDevHelper.umd.js.map +1 -0
  9. package/devHelper/package.json +35 -0
  10. package/devHelper/src/componentMapControl.ts +20 -0
  11. package/devHelper/src/createBoundary.ts +160 -0
  12. package/devHelper/src/index.ts +2 -0
  13. package/devHelper/src/tests/hmrBoundary.tsx +290 -0
  14. package/dist/hook/{unmount.d.ts → internal/unmount.d.ts} +1 -1
  15. package/dist/hook/internal/useUpdate.d.ts +5 -0
  16. package/dist/hook/mountCallback.d.ts +11 -3
  17. package/dist/hook/mountReadyCallback.d.ts +10 -0
  18. package/dist/hook/updateCallback.d.ts +3 -1
  19. package/dist/index.d.ts +5 -3
  20. package/dist/lithent.mjs +397 -339
  21. package/dist/lithent.mjs.map +1 -1
  22. package/dist/lithent.umd.js +1 -1
  23. package/dist/lithent.umd.js.map +1 -1
  24. package/dist/types/index.d.ts +9 -9
  25. package/dist/utils/index.d.ts +2 -2
  26. package/dist/utils/predicator.d.ts +8 -0
  27. package/dist/utils/universalRef.d.ts +10 -10
  28. package/dist/wDom.d.ts +4 -4
  29. package/examples/dist/assets/index-BKrlmwUB.js +2 -0
  30. package/examples/dist/assets/index-BKrlmwUB.js.map +1 -0
  31. package/examples/dist/index.html +1 -1
  32. package/ftags/dist/index.d.ts +5 -5
  33. package/helper/dist/hook/computed.d.ts +4 -3
  34. package/helper/dist/hook/context.d.ts +19 -0
  35. package/helper/dist/hook/state.d.ts +2 -1
  36. package/helper/dist/hook/store.d.ts +7 -6
  37. package/helper/dist/index.d.ts +6 -0
  38. package/helper/dist/lithentHelper.mjs +138 -74
  39. package/helper/dist/lithentHelper.mjs.map +1 -1
  40. package/helper/dist/lithentHelper.umd.js +1 -1
  41. package/helper/dist/lithentHelper.umd.js.map +1 -1
  42. package/helper/dist/utils/children.d.ts +6 -0
  43. package/helper/dist/utils/types.d.ts +3 -0
  44. package/helper/src/hook/computed.ts +6 -6
  45. package/helper/src/hook/context.tsx +202 -0
  46. package/helper/src/hook/state.ts +4 -5
  47. package/helper/src/hook/store.ts +11 -6
  48. package/helper/src/index.ts +12 -0
  49. package/helper/src/tests/context.tsx +813 -0
  50. package/helper/src/tests/renderprops.tsx +81 -0
  51. package/helper/src/utils/children.ts +15 -0
  52. package/helper/src/utils/types.ts +10 -0
  53. package/jsx-runtime/dist/index.d.ts +2 -2
  54. package/package.json +19 -5
  55. package/src/diff.ts +70 -64
  56. package/src/hook/{unmount.ts → internal/unmount.ts} +16 -8
  57. package/src/hook/{useUpdate.ts → internal/useUpdate.ts} +17 -8
  58. package/src/hook/mountCallback.ts +30 -11
  59. package/src/hook/mountReadyCallback.ts +44 -0
  60. package/src/hook/updateCallback.ts +16 -6
  61. package/src/index.ts +13 -2
  62. package/src/render.ts +85 -104
  63. package/src/tests/core-childrentest.tsx +234 -0
  64. package/src/tests/core-mountreadycallback.tsx +283 -0
  65. package/src/tests/core-parentChildSync.tsx +103 -0
  66. package/src/tests/core-ref.tsx +105 -0
  67. package/src/types/index.ts +13 -8
  68. package/src/utils/predicator.ts +62 -40
  69. package/src/utils/redraw.ts +4 -5
  70. package/src/utils/universalRef.ts +36 -13
  71. package/src/wDom.ts +186 -105
  72. package/ssr/dist/lithentSsr.mjs +32 -32
  73. package/ssr/dist/lithentSsr.mjs.map +1 -1
  74. package/ssr/dist/lithentSsr.umd.js +2 -2
  75. package/ssr/dist/lithentSsr.umd.js.map +1 -1
  76. package/ssr/src/helper/index.ts +1 -1
  77. package/ssr/src/hydration.ts +8 -9
  78. package/ssr/src/renderToString.ts +2 -2
  79. package/tag/dist/index.d.ts +4 -4
  80. package/dist/hook/useUpdate.d.ts +0 -3
  81. package/examples/dist/assets/index-GZ-P6cMy.js +0 -2
  82. package/examples/dist/assets/index-GZ-P6cMy.js.map +0 -1
package/README.md CHANGED
@@ -38,6 +38,8 @@ used lightly in a variety of situations.
38
38
  - [Examples](#examples)
39
39
  - [With ESM](#with-esm)
40
40
  - [With UMD](#with-umd)
41
+ - [Context API](#context-api)
42
+ - [Multi-value Provider Example](#multi-value-provider-example)
41
43
  - [Related Projects](#related-projects)
42
44
  - [Develop Guide](#develop-guide)
43
45
  - [Test](#test)
@@ -90,14 +92,14 @@ pnpm add lithent
90
92
 
91
93
  #### Or Use CDN
92
94
 
93
- * UMD : https://cdn.jsdelivr.net/npm/lithent@1.18.5/dist/lithent.umd.js
94
- * UMD-HELPER: https://cdn.jsdelivr.net/npm/lithent@1.18.5/helper/dist/lithentHelper.umd.js
95
- * UMD-FTAGS: https://cdn.jsdelivr.net/npm/lithent@1.18.5/ftags/dist/lithentFTags.umd.js
96
- * UMD-TAG: https://cdn.jsdelivr.net/npm/lithent@1.18.5/tag/dist/lithentTag.umd.js
97
- * ESM : https://cdn.jsdelivr.net/npm/lithent@1.18.5/dist/lithent.mjs
98
- * ESM-HELPER: https://cdn.jsdelivr.net/npm/lithent@1.18.5/helper/dist/lithentHelper.mjs
99
- * ESM-FTAGS: https://cdn.jsdelivr.net/npm/lithent@1.18.5/ftags/dist/lithentFTags.mjs
100
- * ESM-TAG: https://cdn.jsdelivr.net/npm/lithent@1.18.5/tag/dist/lithentTag.mjs
95
+ * UMD : https://cdn.jsdelivr.net/npm/lithent@1.20.0/dist/lithent.umd.js
96
+ * UMD-HELPER: https://cdn.jsdelivr.net/npm/lithent@1.20.0/helper/dist/lithentHelper.umd.js
97
+ * UMD-FTAGS: https://cdn.jsdelivr.net/npm/lithent@1.20.0/ftags/dist/lithentFTags.umd.js
98
+ * UMD-TAG: https://cdn.jsdelivr.net/npm/lithent@1.20.0/tag/dist/lithentTag.umd.js
99
+ * ESM : https://cdn.jsdelivr.net/npm/lithent@1.20.0/dist/lithent.mjs
100
+ * ESM-HELPER: https://cdn.jsdelivr.net/npm/lithent@1.20.0/helper/dist/lithentHelper.mjs
101
+ * ESM-FTAGS: https://cdn.jsdelivr.net/npm/lithent@1.20.0/ftags/dist/lithentFTags.mjs
102
+ * ESM-TAG: https://cdn.jsdelivr.net/npm/lithent@1.20.0/tag/dist/lithentTag.mjs
101
103
 
102
104
 
103
105
  It's easier to use lithent with JSX or HTM.
@@ -122,9 +124,9 @@ import { fTags, fFragment, fMount } from 'lithent/ftags';
122
124
  const { section, div, p, br, strong } = fTags;
123
125
 
124
126
  /* UMD
125
- <script src="https://cdn.jsdelivr.net/npm/lithent@1.18.5/dist/lithent.umd.js"></script>
126
- <script src="https://cdn.jsdelivr.net/npm/lithent@1.18.5/helper/dist/lithentHelper.umd.js"></script>
127
- <script src="https://cdn.jsdelivr.net/npm/lithent@1.18.5/ftags/dist/lithentFTags.umd.js"></script>
127
+ <script src="https://cdn.jsdelivr.net/npm/lithent@1.20.0/dist/lithent.umd.js"></script>
128
+ <script src="https://cdn.jsdelivr.net/npm/lithent@1.20.0/helper/dist/lithentHelper.umd.js"></script>
129
+ <script src="https://cdn.jsdelivr.net/npm/lithent@1.20.0/ftags/dist/lithentFTags.umd.js"></script>
128
130
 
129
131
  const { render } = lithent;
130
132
  const { fTags, fMount, fFragment } = lithentFTags;
@@ -197,10 +199,10 @@ const destroy = render(lTag`<${Component} />`, document.getElementById('root'),
197
199
  #### With UMD
198
200
 
199
201
  ```html
200
- <script src="https://cdn.jsdelivr.net/npm/lithent@1.18.5/dist/lithent.umd.js"></script>
201
- <!--script src="https://cdn.jsdelivr.net/npm/lithent@1.18.5/helper/dist/lithentHelper.umd.js"></script-->
202
- <script src="https://cdn.jsdelivr.net/npm/lithent@1.18.5/tag/dist/lithentTag.umd.js"></script>
203
- <!--script src="https://cdn.jsdelivr.net/npm/lithent@1.18.5/ftags/dist/lithentFTags.umd.js"></script-->
202
+ <script src="https://cdn.jsdelivr.net/npm/lithent@1.20.0/dist/lithent.umd.js"></script>
203
+ <!--script src="https://cdn.jsdelivr.net/npm/lithent@1.20.0/helper/dist/lithentHelper.umd.js"></script-->
204
+ <script src="https://cdn.jsdelivr.net/npm/lithent@1.20.0/tag/dist/lithentTag.umd.js"></script>
205
+ <!--script src="https://cdn.jsdelivr.net/npm/lithent@1.20.0/ftags/dist/lithentFTags.umd.js"></script-->
204
206
 
205
207
  <div id="root"></div>
206
208
 
@@ -232,6 +234,68 @@ const destroy = render(lTag`<${Component} />`, document.getElementById('root'),
232
234
  </script>
233
235
  ```
234
236
 
237
+ ## Context API
238
+
239
+ Lithent-helper ships a lightweight context system so you can share state without manual prop drilling. Providers stay isolated from consumer renews and you can subscribe to every key or only the slices you need.
240
+
241
+ ### Multi-value Provider Example
242
+
243
+ ```tsx
244
+ import { h, mount } from 'lithent';
245
+ import { createContext } from 'lithent-helper';
246
+
247
+ type AppState = { user: string; theme: string; count: number };
248
+
249
+ const AppContext = createContext<AppState>();
250
+ const { Provider, contextState, useContext } = AppContext;
251
+
252
+ const AppProvider = mount((_renew, _props, children) => {
253
+ // Provider owns the shared state; consumers cannot trigger its renew directly.
254
+ const user = contextState('Alice');
255
+ const theme = contextState('dark');
256
+ const count = contextState(0);
257
+
258
+ return () => (
259
+ <Provider user={user} theme={theme} count={count}>
260
+ {children}
261
+ </Provider>
262
+ );
263
+ });
264
+
265
+ const StatsPanel = mount(renew => {
266
+ // Omitting the subscribe list subscribes to every value exposed by the Provider.
267
+ const ctx = useContext(AppContext, renew);
268
+ return () => (
269
+ <section>
270
+ <p>User: {ctx.user?.value}</p>
271
+ <p>Theme: {ctx.theme?.value}</p>
272
+ <p>Count: {ctx.count?.value}</p>
273
+ <button onClick={() => ctx.count && (ctx.count.value += 1)}>
274
+ Increment
275
+ </button>
276
+ <button onClick={() => ctx.count && (ctx.count.value = 3)}>
277
+ Set count to 3
278
+ </button>
279
+ </section>
280
+ );
281
+ });
282
+
283
+ const ThemeBadge = mount(renew => {
284
+ // Subscribe only to the theme key; user/count updates will not rerender this component.
285
+ const ctx = useContext(AppContext, renew, ['theme']);
286
+ return () => <span>Theme: {ctx.theme?.value}</span>;
287
+ });
288
+
289
+ const App = mount(() => {
290
+ return () => (
291
+ <AppProvider>
292
+ <StatsPanel />
293
+ <ThemeBadge />
294
+ </AppProvider>
295
+ );
296
+ });
297
+ ```
298
+
235
299
  ## Related Projects
236
300
  - [htm](https://www.npmjs.com/package/htm) - making **H**yperscript **T**agged **M**arkup possible
237
301
 
@@ -276,4 +340,3 @@ pnpm install
276
340
  pnpm build
277
341
  pnpm test
278
342
  ```
279
-
@@ -0,0 +1,4 @@
1
+ import type { CompKey } from 'lithent';
2
+ export declare const enableComponentMapManualMode: () => void;
3
+ export declare const disableComponentMapManualMode: () => void;
4
+ export declare const removeComponentEntry: (compKey: CompKey) => void;
@@ -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,2 @@
1
+ export { createBoundary } from './createBoundary';
2
+ export type { BoundaryController } from './createBoundary';
@@ -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
+ };
@@ -0,0 +1,2 @@
1
+ export { createBoundary } from './createBoundary';
2
+ export type { BoundaryController } from './createBoundary';