@toyz/loom 0.1.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 (127) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +108 -0
  3. package/dist/app.d.ts +70 -0
  4. package/dist/app.d.ts.map +1 -0
  5. package/dist/app.js +152 -0
  6. package/dist/app.js.map +1 -0
  7. package/dist/bus.d.ts +27 -0
  8. package/dist/bus.d.ts.map +1 -0
  9. package/dist/bus.js +41 -0
  10. package/dist/bus.js.map +1 -0
  11. package/dist/css.d.ts +25 -0
  12. package/dist/css.d.ts.map +1 -0
  13. package/dist/css.js +48 -0
  14. package/dist/css.js.map +1 -0
  15. package/dist/decorators/component.d.ts +11 -0
  16. package/dist/decorators/component.d.ts.map +1 -0
  17. package/dist/decorators/component.js +38 -0
  18. package/dist/decorators/component.js.map +1 -0
  19. package/dist/decorators/di.d.ts +37 -0
  20. package/dist/decorators/di.d.ts.map +1 -0
  21. package/dist/decorators/di.js +65 -0
  22. package/dist/decorators/di.js.map +1 -0
  23. package/dist/decorators/dom.d.ts +15 -0
  24. package/dist/decorators/dom.d.ts.map +1 -0
  25. package/dist/decorators/dom.js +33 -0
  26. package/dist/decorators/dom.js.map +1 -0
  27. package/dist/decorators/events.d.ts +46 -0
  28. package/dist/decorators/events.d.ts.map +1 -0
  29. package/dist/decorators/events.js +69 -0
  30. package/dist/decorators/events.js.map +1 -0
  31. package/dist/decorators/index.d.ts +18 -0
  32. package/dist/decorators/index.d.ts.map +1 -0
  33. package/dist/decorators/index.js +27 -0
  34. package/dist/decorators/index.js.map +1 -0
  35. package/dist/decorators/lifecycle.d.ts +49 -0
  36. package/dist/decorators/lifecycle.d.ts.map +1 -0
  37. package/dist/decorators/lifecycle.js +105 -0
  38. package/dist/decorators/lifecycle.js.map +1 -0
  39. package/dist/decorators/state.d.ts +41 -0
  40. package/dist/decorators/state.d.ts.map +1 -0
  41. package/dist/decorators/state.js +125 -0
  42. package/dist/decorators/state.js.map +1 -0
  43. package/dist/decorators/symbols.d.ts +13 -0
  44. package/dist/decorators/symbols.d.ts.map +1 -0
  45. package/dist/decorators/symbols.js +15 -0
  46. package/dist/decorators/symbols.js.map +1 -0
  47. package/dist/decorators/timing.d.ts +35 -0
  48. package/dist/decorators/timing.d.ts.map +1 -0
  49. package/dist/decorators/timing.js +57 -0
  50. package/dist/decorators/timing.js.map +1 -0
  51. package/dist/decorators/transform.d.ts +45 -0
  52. package/dist/decorators/transform.d.ts.map +1 -0
  53. package/dist/decorators/transform.js +48 -0
  54. package/dist/decorators/transform.js.map +1 -0
  55. package/dist/element.d.ts +62 -0
  56. package/dist/element.d.ts.map +1 -0
  57. package/dist/element.js +150 -0
  58. package/dist/element.js.map +1 -0
  59. package/dist/event.d.ts +24 -0
  60. package/dist/event.d.ts.map +1 -0
  61. package/dist/event.js +35 -0
  62. package/dist/event.js.map +1 -0
  63. package/dist/icon.d.ts +35 -0
  64. package/dist/icon.d.ts.map +1 -0
  65. package/dist/icon.js +119 -0
  66. package/dist/icon.js.map +1 -0
  67. package/dist/index.d.ts +29 -0
  68. package/dist/index.d.ts.map +1 -0
  69. package/dist/index.js +34 -0
  70. package/dist/index.js.map +1 -0
  71. package/dist/jsx-dev-runtime.d.ts +8 -0
  72. package/dist/jsx-dev-runtime.d.ts.map +1 -0
  73. package/dist/jsx-dev-runtime.js +8 -0
  74. package/dist/jsx-dev-runtime.js.map +1 -0
  75. package/dist/jsx-runtime.d.ts +13 -0
  76. package/dist/jsx-runtime.d.ts.map +1 -0
  77. package/dist/jsx-runtime.js +101 -0
  78. package/dist/jsx-runtime.js.map +1 -0
  79. package/dist/morph.d.ts +23 -0
  80. package/dist/morph.d.ts.map +1 -0
  81. package/dist/morph.js +212 -0
  82. package/dist/morph.js.map +1 -0
  83. package/dist/reactive.d.ts +75 -0
  84. package/dist/reactive.d.ts.map +1 -0
  85. package/dist/reactive.js +133 -0
  86. package/dist/reactive.js.map +1 -0
  87. package/dist/render-loop.d.ts +34 -0
  88. package/dist/render-loop.d.ts.map +1 -0
  89. package/dist/render-loop.js +70 -0
  90. package/dist/render-loop.js.map +1 -0
  91. package/dist/router/events.d.ts +12 -0
  92. package/dist/router/events.d.ts.map +1 -0
  93. package/dist/router/events.js +17 -0
  94. package/dist/router/events.js.map +1 -0
  95. package/dist/router/index.d.ts +14 -0
  96. package/dist/router/index.d.ts.map +1 -0
  97. package/dist/router/index.js +18 -0
  98. package/dist/router/index.js.map +1 -0
  99. package/dist/router/link.d.ts +18 -0
  100. package/dist/router/link.d.ts.map +1 -0
  101. package/dist/router/link.js +75 -0
  102. package/dist/router/link.js.map +1 -0
  103. package/dist/router/mode.d.ts +33 -0
  104. package/dist/router/mode.d.ts.map +1 -0
  105. package/dist/router/mode.js +48 -0
  106. package/dist/router/mode.js.map +1 -0
  107. package/dist/router/outlet.d.ts +40 -0
  108. package/dist/router/outlet.d.ts.map +1 -0
  109. package/dist/router/outlet.js +171 -0
  110. package/dist/router/outlet.js.map +1 -0
  111. package/dist/router/route.d.ts +76 -0
  112. package/dist/router/route.d.ts.map +1 -0
  113. package/dist/router/route.js +147 -0
  114. package/dist/router/route.js.map +1 -0
  115. package/dist/router/router.d.ts +50 -0
  116. package/dist/router/router.d.ts.map +1 -0
  117. package/dist/router/router.js +140 -0
  118. package/dist/router/router.js.map +1 -0
  119. package/dist/storage.d.ts +55 -0
  120. package/dist/storage.d.ts.map +1 -0
  121. package/dist/storage.js +90 -0
  122. package/dist/storage.js.map +1 -0
  123. package/dist/virtual.d.ts +69 -0
  124. package/dist/virtual.d.ts.map +1 -0
  125. package/dist/virtual.js +247 -0
  126. package/dist/virtual.js.map +1 -0
  127. package/package.json +58 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../src/storage.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,oDAAoD;AACpD,MAAM,WAAW,aAAa;IAC5B,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IAChC,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,0DAA0D;AAC1D,MAAM,WAAW,cAAc;IAC7B,mDAAmD;IACnD,GAAG,EAAE,MAAM,CAAC;IACZ,kEAAkE;IAClE,OAAO,EAAE,aAAa,CAAC;CACxB;AAED;;;GAGG;AACH,qBAAa,aAAc,YAAW,aAAa;IACjD,OAAO,CAAC,IAAI,CAA6B;IAEzC,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAI/B,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAIrC,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;CAG1B;AAED;;;;;;GAMG;AACH,qBAAa,WAAY,YAAW,aAAa;IAC/C,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAQ/B,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAQrC,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;CAO1B;AAED;;;;;;GAMG;AACH,qBAAa,aAAc,YAAW,aAAa;IACjD,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAQ/B,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAQrC,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;CAO1B"}
@@ -0,0 +1,90 @@
1
+ /**
2
+ * Loom — Storage Medium
3
+ *
4
+ * Pluggable persistence for Reactive<T> and CollectionStore<T>.
5
+ * Three built-in implementations: Memory (default), Local, Session.
6
+ * Implement StorageMedium for custom backends (IndexedDB, NATS KV, REST, etc).
7
+ */
8
+ /**
9
+ * In-memory storage. No persistence — values lost on page reload.
10
+ * This is the implicit default when no storage is configured.
11
+ */
12
+ export class MemoryStorage {
13
+ data = new Map();
14
+ get(key) {
15
+ return this.data.get(key) ?? null;
16
+ }
17
+ set(key, value) {
18
+ this.data.set(key, value);
19
+ }
20
+ remove(key) {
21
+ this.data.delete(key);
22
+ }
23
+ }
24
+ /**
25
+ * localStorage wrapper — survives page reloads and browser restarts.
26
+ *
27
+ * ```ts
28
+ * const count = new Reactive(0, { key: "app:count", storage: new LocalMedium() });
29
+ * ```
30
+ */
31
+ export class LocalMedium {
32
+ get(key) {
33
+ try {
34
+ return localStorage.getItem(key);
35
+ }
36
+ catch {
37
+ return null;
38
+ }
39
+ }
40
+ set(key, value) {
41
+ try {
42
+ localStorage.setItem(key, value);
43
+ }
44
+ catch {
45
+ // Storage full or blocked — silent fail
46
+ }
47
+ }
48
+ remove(key) {
49
+ try {
50
+ localStorage.removeItem(key);
51
+ }
52
+ catch {
53
+ // Silent fail
54
+ }
55
+ }
56
+ }
57
+ /**
58
+ * sessionStorage wrapper — survives page reloads but not browser restarts.
59
+ *
60
+ * ```ts
61
+ * const temp = new Reactive("", { key: "app:temp", storage: new SessionMedium() });
62
+ * ```
63
+ */
64
+ export class SessionMedium {
65
+ get(key) {
66
+ try {
67
+ return sessionStorage.getItem(key);
68
+ }
69
+ catch {
70
+ return null;
71
+ }
72
+ }
73
+ set(key, value) {
74
+ try {
75
+ sessionStorage.setItem(key, value);
76
+ }
77
+ catch {
78
+ // Storage full or blocked — silent fail
79
+ }
80
+ }
81
+ remove(key) {
82
+ try {
83
+ sessionStorage.removeItem(key);
84
+ }
85
+ catch {
86
+ // Silent fail
87
+ }
88
+ }
89
+ }
90
+ //# sourceMappingURL=storage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage.js","sourceRoot":"","sources":["../src/storage.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAiBH;;;GAGG;AACH,MAAM,OAAO,aAAa;IAChB,IAAI,GAAG,IAAI,GAAG,EAAkB,CAAC;IAEzC,GAAG,CAAC,GAAW;QACb,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC;IACpC,CAAC;IAED,GAAG,CAAC,GAAW,EAAE,KAAa;QAC5B,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAC5B,CAAC;IAED,MAAM,CAAC,GAAW;QAChB,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACxB,CAAC;CACF;AAED;;;;;;GAMG;AACH,MAAM,OAAO,WAAW;IACtB,GAAG,CAAC,GAAW;QACb,IAAI,CAAC;YACH,OAAO,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACnC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAED,GAAG,CAAC,GAAW,EAAE,KAAa;QAC5B,IAAI,CAAC;YACH,YAAY,CAAC,OAAO,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QACnC,CAAC;QAAC,MAAM,CAAC;YACP,wCAAwC;QAC1C,CAAC;IACH,CAAC;IAED,MAAM,CAAC,GAAW;QAChB,IAAI,CAAC;YACH,YAAY,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;QAC/B,CAAC;QAAC,MAAM,CAAC;YACP,cAAc;QAChB,CAAC;IACH,CAAC;CACF;AAED;;;;;;GAMG;AACH,MAAM,OAAO,aAAa;IACxB,GAAG,CAAC,GAAW;QACb,IAAI,CAAC;YACH,OAAO,cAAc,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACrC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAED,GAAG,CAAC,GAAW,EAAE,KAAa;QAC5B,IAAI,CAAC;YACH,cAAc,CAAC,OAAO,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QACrC,CAAC;QAAC,MAAM,CAAC;YACP,wCAAwC;QAC1C,CAAC;IACH,CAAC;IAED,MAAM,CAAC,GAAW;QAChB,IAAI,CAAC;YACH,cAAc,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;QACjC,CAAC;QAAC,MAAM,CAAC;YACP,cAAc;QAChB,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Loom — Virtual List Element
3
+ *
4
+ * Dynamic-height virtual list as a LoomElement web component.
5
+ * Renders only visible items from a large dataset, measuring
6
+ * actual heights after paint and caching them.
7
+ *
8
+ * Height strategy: the host sets its own inline height to match
9
+ * total content. The consumer's min-height / max-height clamp it.
10
+ * The viewport uses height:100% + overflow-y:auto, which resolves
11
+ * correctly because the host has a definite (inline) height.
12
+ *
13
+ * Usage:
14
+ * const vl = document.createElement("loom-virtual") as LoomVirtual<Msg>;
15
+ * vl.estimatedHeight = 44;
16
+ * vl.renderItem = (msg, i) => <div class="msg">{msg.text}</div>;
17
+ * vl.setItems(messages);
18
+ * parent.appendChild(vl);
19
+ */
20
+ import { LoomElement } from "./element";
21
+ export interface VirtualListOptions<T> {
22
+ estimatedHeight?: number;
23
+ overscan?: number;
24
+ renderItem: (item: T, index: number) => Node;
25
+ }
26
+ export declare class LoomVirtual<T = any> extends LoomElement {
27
+ /** Estimated height per item in px (before measurement) */
28
+ estimatedHeight: number;
29
+ /** Extra items above/below visible window */
30
+ overscan: number;
31
+ /** Render callback — must be set before use */
32
+ renderItem: ((item: T, index: number) => Node) | null;
33
+ /** Called when user scrolls near the bottom — use for pagination / infinite scroll */
34
+ onNearEnd: (() => void) | null;
35
+ private items;
36
+ private heightCache;
37
+ private offsets;
38
+ private rangeStart;
39
+ private rangeEnd;
40
+ private rafId;
41
+ private scrolling;
42
+ /** When true, automatically scrolls to bottom when new items are added (useful for chat) */
43
+ pinToBottom: boolean;
44
+ /** When true, host element auto-sizes height to content (clamped by external min/max-height). Set false for fixed-size containers. */
45
+ autoHeight: boolean;
46
+ private viewport;
47
+ private spacer;
48
+ private window;
49
+ constructor();
50
+ connectedCallback(): void;
51
+ /** Replace the full item list and re-render */
52
+ setItems(items: T[]): void;
53
+ /** Append items (auto-scrolls if pinned to bottom) */
54
+ push(...newItems: T[]): void;
55
+ /** Scroll to the very bottom */
56
+ scrollToEnd(): void;
57
+ /** Re-measure all visible items */
58
+ refresh(): void;
59
+ get length(): number;
60
+ private isAtBottom;
61
+ private onScroll;
62
+ private scheduleRender;
63
+ private rebuildOffsets;
64
+ /** Binary search for first item whose bottom edge >= scrollTop */
65
+ private findStart;
66
+ private renderWindow;
67
+ private measureVisible;
68
+ }
69
+ //# sourceMappingURL=virtual.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"virtual.d.ts","sourceRoot":"","sources":["../src/virtual.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAyBxC,MAAM,WAAW,kBAAkB,CAAC,CAAC;IACnC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CAC9C;AAED,qBACa,WAAW,CAAC,CAAC,GAAG,GAAG,CAAE,SAAQ,WAAW;IACnD,2DAA2D;IAC3D,eAAe,SAAM;IACrB,6CAA6C;IAC7C,QAAQ,SAAK;IACb,+CAA+C;IAC/C,UAAU,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,IAAI,CAAQ;IAC7D,sFAAsF;IACtF,SAAS,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,IAAI,CAAQ;IAEtC,OAAO,CAAC,KAAK,CAAW;IACxB,OAAO,CAAC,WAAW,CAA6B;IAChD,OAAO,CAAC,OAAO,CAAiB;IAChC,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,QAAQ,CAAK;IACrB,OAAO,CAAC,KAAK,CAAK;IAClB,OAAO,CAAC,SAAS,CAAS;IAC1B,4FAA4F;IAC5F,WAAW,UAAQ;IACnB,sIAAsI;IACtI,UAAU,UAAQ;IAElB,OAAO,CAAC,QAAQ,CAAkB;IAClC,OAAO,CAAC,MAAM,CAAkB;IAChC,OAAO,CAAC,MAAM,CAAkB;;IAMhC,iBAAiB,IAAI,IAAI;IA2BzB,+CAA+C;IAC/C,QAAQ,CAAC,KAAK,EAAE,CAAC,EAAE,GAAG,IAAI;IAa1B,sDAAsD;IACtD,IAAI,CAAC,GAAG,QAAQ,EAAE,CAAC,EAAE,GAAG,IAAI;IAS5B,gCAAgC;IAChC,WAAW,IAAI,IAAI;IAKnB,mCAAmC;IACnC,OAAO,IAAI,IAAI;IAMf,IAAI,MAAM,IAAI,MAAM,CAEnB;IAID,OAAO,CAAC,UAAU;IAMlB,OAAO,CAAC,QAAQ,CAgBd;IAEF,OAAO,CAAC,cAAc;IAKtB,OAAO,CAAC,cAAc;IAetB,kEAAkE;IAClE,OAAO,CAAC,SAAS;IAUjB,OAAO,CAAC,YAAY;IAgDpB,OAAO,CAAC,cAAc;CAcvB"}
@@ -0,0 +1,247 @@
1
+ /**
2
+ * Loom — Virtual List Element
3
+ *
4
+ * Dynamic-height virtual list as a LoomElement web component.
5
+ * Renders only visible items from a large dataset, measuring
6
+ * actual heights after paint and caching them.
7
+ *
8
+ * Height strategy: the host sets its own inline height to match
9
+ * total content. The consumer's min-height / max-height clamp it.
10
+ * The viewport uses height:100% + overflow-y:auto, which resolves
11
+ * correctly because the host has a definite (inline) height.
12
+ *
13
+ * Usage:
14
+ * const vl = document.createElement("loom-virtual") as LoomVirtual<Msg>;
15
+ * vl.estimatedHeight = 44;
16
+ * vl.renderItem = (msg, i) => <div class="msg">{msg.text}</div>;
17
+ * vl.setItems(messages);
18
+ * parent.appendChild(vl);
19
+ */
20
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
21
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
22
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
23
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
24
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
25
+ };
26
+ import { LoomElement } from "./element";
27
+ import { component } from "./decorators";
28
+ import { css } from "./css";
29
+ const styles = css `
30
+ :host {
31
+ display: block;
32
+ }
33
+ .vl-viewport {
34
+ height: 100%;
35
+ overflow-y: auto;
36
+ scrollbar-width: thin;
37
+ }
38
+ .vl-spacer {
39
+ position: relative;
40
+ width: 100%;
41
+ }
42
+ .vl-window {
43
+ position: absolute;
44
+ top: 0;
45
+ left: 0;
46
+ width: 100%;
47
+ }
48
+ `;
49
+ let LoomVirtual = class LoomVirtual extends LoomElement {
50
+ /** Estimated height per item in px (before measurement) */
51
+ estimatedHeight = 40;
52
+ /** Extra items above/below visible window */
53
+ overscan = 3;
54
+ /** Render callback — must be set before use */
55
+ renderItem = null;
56
+ /** Called when user scrolls near the bottom — use for pagination / infinite scroll */
57
+ onNearEnd = null;
58
+ items = [];
59
+ heightCache = new Map();
60
+ offsets = [0];
61
+ rangeStart = 0;
62
+ rangeEnd = 0;
63
+ rafId = 0;
64
+ scrolling = false;
65
+ /** When true, automatically scrolls to bottom when new items are added (useful for chat) */
66
+ pinToBottom = true;
67
+ /** When true, host element auto-sizes height to content (clamped by external min/max-height). Set false for fixed-size containers. */
68
+ autoHeight = true;
69
+ viewport;
70
+ spacer;
71
+ window;
72
+ constructor() {
73
+ super();
74
+ }
75
+ connectedCallback() {
76
+ super.connectedCallback();
77
+ this.shadow.adoptedStyleSheets = [styles];
78
+ // Build skeleton in shadow DOM
79
+ this.viewport = document.createElement("div");
80
+ this.viewport.className = "vl-viewport";
81
+ this.spacer = document.createElement("div");
82
+ this.spacer.className = "vl-spacer";
83
+ this.window = document.createElement("div");
84
+ this.window.className = "vl-window";
85
+ this.spacer.appendChild(this.window);
86
+ this.viewport.appendChild(this.spacer);
87
+ this.shadow.appendChild(this.viewport);
88
+ this.viewport.addEventListener("scroll", this.onScroll, { passive: true });
89
+ this.track(() => this.viewport.removeEventListener("scroll", this.onScroll));
90
+ this.track(() => cancelAnimationFrame(this.rafId));
91
+ }
92
+ // ── Public API ──
93
+ /** Replace the full item list and re-render */
94
+ setItems(items) {
95
+ // Only auto-detect pin if already pinned — don't override consumer's explicit false
96
+ if (this.pinToBottom) {
97
+ this.pinToBottom = this.isAtBottom();
98
+ }
99
+ this.items = items;
100
+ // Invalidate range so renderWindow always re-renders with new data
101
+ this.rangeStart = -1;
102
+ this.rangeEnd = -1;
103
+ this.rebuildOffsets();
104
+ this.scheduleRender();
105
+ }
106
+ /** Append items (auto-scrolls if pinned to bottom) */
107
+ push(...newItems) {
108
+ this.pinToBottom = this.isAtBottom();
109
+ for (const item of newItems)
110
+ this.items.push(item);
111
+ this.rangeStart = -1;
112
+ this.rangeEnd = -1;
113
+ this.rebuildOffsets();
114
+ this.scheduleRender();
115
+ }
116
+ /** Scroll to the very bottom */
117
+ scrollToEnd() {
118
+ this.pinToBottom = true;
119
+ if (this.viewport)
120
+ this.viewport.scrollTop = this.viewport.scrollHeight;
121
+ }
122
+ /** Re-measure all visible items */
123
+ refresh() {
124
+ this.measureVisible();
125
+ this.rebuildOffsets();
126
+ this.scheduleRender();
127
+ }
128
+ get length() {
129
+ return this.items.length;
130
+ }
131
+ // ── Internals ──
132
+ isAtBottom() {
133
+ if (!this.viewport)
134
+ return true;
135
+ const { scrollTop, scrollHeight, clientHeight } = this.viewport;
136
+ return scrollHeight - scrollTop - clientHeight < 30;
137
+ }
138
+ onScroll = () => {
139
+ if (!this.scrolling) {
140
+ this.scrolling = true;
141
+ this.rafId = requestAnimationFrame(() => {
142
+ this.scrolling = false;
143
+ this.renderWindow();
144
+ // Fire near-end callback for infinite scroll
145
+ if (this.onNearEnd && this.viewport) {
146
+ const { scrollTop, scrollHeight, clientHeight } = this.viewport;
147
+ if (scrollHeight - scrollTop - clientHeight < 100) {
148
+ this.onNearEnd();
149
+ }
150
+ }
151
+ });
152
+ }
153
+ };
154
+ scheduleRender() {
155
+ cancelAnimationFrame(this.rafId);
156
+ this.rafId = requestAnimationFrame(() => this.renderWindow());
157
+ }
158
+ rebuildOffsets() {
159
+ const n = this.items.length;
160
+ this.offsets = new Array(n + 1);
161
+ this.offsets[0] = 0;
162
+ for (let i = 0; i < n; i++) {
163
+ this.offsets[i + 1] = this.offsets[i] + (this.heightCache.get(i) ?? this.estimatedHeight);
164
+ }
165
+ if (this.spacer)
166
+ this.spacer.style.height = `${this.offsets[n]}px`;
167
+ // Set host height to total content — external min/max-height will clamp
168
+ if (this.autoHeight) {
169
+ this.style.height = `${this.offsets[n]}px`;
170
+ }
171
+ }
172
+ /** Binary search for first item whose bottom edge >= scrollTop */
173
+ findStart(scrollTop) {
174
+ let lo = 0, hi = this.items.length;
175
+ while (lo < hi) {
176
+ const mid = (lo + hi) >>> 1;
177
+ if (this.offsets[mid + 1] <= scrollTop)
178
+ lo = mid + 1;
179
+ else
180
+ hi = mid;
181
+ }
182
+ return lo;
183
+ }
184
+ renderWindow() {
185
+ if (!this.renderItem || !this.viewport || !this.window)
186
+ return;
187
+ const n = this.items.length;
188
+ if (n === 0) {
189
+ this.window.textContent = "";
190
+ this.rangeStart = this.rangeEnd = 0;
191
+ return;
192
+ }
193
+ const scrollTop = this.viewport.scrollTop;
194
+ let viewH = this.viewport.clientHeight;
195
+ // If viewport hasn't laid out yet, render a reasonable chunk and retry next frame
196
+ if (viewH === 0) {
197
+ viewH = this.estimatedHeight * 20;
198
+ requestAnimationFrame(() => this.scheduleRender());
199
+ }
200
+ let start = this.findStart(scrollTop);
201
+ let end = start;
202
+ while (end < n && this.offsets[end] < scrollTop + viewH)
203
+ end++;
204
+ start = Math.max(0, start - this.overscan);
205
+ end = Math.min(n, end + this.overscan);
206
+ if (start === this.rangeStart && end === this.rangeEnd)
207
+ return;
208
+ this.rangeStart = start;
209
+ this.rangeEnd = end;
210
+ this.window.style.transform = `translateY(${this.offsets[start]}px)`;
211
+ const frag = document.createDocumentFragment();
212
+ for (let i = start; i < end; i++) {
213
+ frag.appendChild(this.renderItem(this.items[i], i));
214
+ }
215
+ this.window.textContent = "";
216
+ this.window.appendChild(frag);
217
+ // Measure after paint
218
+ requestAnimationFrame(() => {
219
+ this.measureVisible();
220
+ if (this.pinToBottom && this.viewport) {
221
+ this.viewport.scrollTop = this.viewport.scrollHeight;
222
+ this.pinToBottom = false;
223
+ }
224
+ });
225
+ }
226
+ measureVisible() {
227
+ if (!this.window)
228
+ return;
229
+ const children = this.window.children;
230
+ let dirty = false;
231
+ for (let i = 0; i < children.length; i++) {
232
+ const idx = this.rangeStart + i;
233
+ const h = Math.ceil(children[i].getBoundingClientRect().height);
234
+ if (h > 0 && this.heightCache.get(idx) !== h) {
235
+ this.heightCache.set(idx, h);
236
+ dirty = true;
237
+ }
238
+ }
239
+ if (dirty)
240
+ this.rebuildOffsets();
241
+ }
242
+ };
243
+ LoomVirtual = __decorate([
244
+ component("loom-virtual")
245
+ ], LoomVirtual);
246
+ export { LoomVirtual };
247
+ //# sourceMappingURL=virtual.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"virtual.js","sourceRoot":"","sources":["../src/virtual.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,58 @@
1
+ {
2
+ "name": "@toyz/loom",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "description": "Decorator-driven web component framework with reactive state, DOM morphing, DI, and JSX",
6
+ "license": "MIT",
7
+ "author": "toyz",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "https://github.com/toyz/loom.git"
11
+ },
12
+ "homepage": "https://toyz.github.io/loom/",
13
+ "sideEffects": false,
14
+ "files": [
15
+ "dist",
16
+ "LICENSE",
17
+ "README.md"
18
+ ],
19
+ "main": "./dist/index.js",
20
+ "module": "./dist/index.js",
21
+ "types": "./dist/index.d.ts",
22
+ "exports": {
23
+ ".": {
24
+ "types": "./dist/index.d.ts",
25
+ "import": "./dist/index.js"
26
+ },
27
+ "./jsx-runtime": {
28
+ "types": "./dist/jsx-runtime.d.ts",
29
+ "import": "./dist/jsx-runtime.js"
30
+ },
31
+ "./jsx-dev-runtime": {
32
+ "types": "./dist/jsx-dev-runtime.d.ts",
33
+ "import": "./dist/jsx-dev-runtime.js"
34
+ },
35
+ "./router": {
36
+ "types": "./dist/router/index.d.ts",
37
+ "import": "./dist/router/index.js"
38
+ }
39
+ },
40
+ "scripts": {
41
+ "build": "tsc",
42
+ "dev": "tsc --watch",
43
+ "clean": "rm -rf dist",
44
+ "prepublishOnly": "npm run clean && npm run build"
45
+ },
46
+ "devDependencies": {
47
+ "typescript": "^5.7.0"
48
+ },
49
+ "keywords": [
50
+ "web-components",
51
+ "decorators",
52
+ "reactive",
53
+ "jsx",
54
+ "dom-morphing",
55
+ "shadow-dom",
56
+ "dependency-injection"
57
+ ]
58
+ }