viewport-truth 1.0.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 (52) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +251 -0
  3. package/banner.js +46 -0
  4. package/dist/angular.d.ts +28 -0
  5. package/dist/angular.d.ts.map +1 -0
  6. package/dist/angular.js +82 -0
  7. package/dist/angular.js.map +1 -0
  8. package/dist/core/engine.d.ts +3 -0
  9. package/dist/core/engine.d.ts.map +1 -0
  10. package/dist/core/engine.js +200 -0
  11. package/dist/core/engine.js.map +1 -0
  12. package/dist/core/env.d.ts +8 -0
  13. package/dist/core/env.d.ts.map +1 -0
  14. package/dist/core/env.js +38 -0
  15. package/dist/core/env.js.map +1 -0
  16. package/dist/core/index.d.ts +3 -0
  17. package/dist/core/index.d.ts.map +1 -0
  18. package/dist/core/index.js +2 -0
  19. package/dist/core/index.js.map +1 -0
  20. package/dist/core/scheduler.d.ts +7 -0
  21. package/dist/core/scheduler.d.ts.map +1 -0
  22. package/dist/core/scheduler.js +44 -0
  23. package/dist/core/scheduler.js.map +1 -0
  24. package/dist/core/types.d.ts +70 -0
  25. package/dist/core/types.d.ts.map +1 -0
  26. package/dist/core/types.js +2 -0
  27. package/dist/core/types.js.map +1 -0
  28. package/dist/index.d.ts +8 -0
  29. package/dist/index.d.ts.map +1 -0
  30. package/dist/index.js +8 -0
  31. package/dist/index.js.map +1 -0
  32. package/dist/react.d.ts +4 -0
  33. package/dist/react.d.ts.map +1 -0
  34. package/dist/react.js +7 -0
  35. package/dist/react.js.map +1 -0
  36. package/dist/solid.d.ts +12 -0
  37. package/dist/solid.d.ts.map +1 -0
  38. package/dist/solid.js +26 -0
  39. package/dist/solid.js.map +1 -0
  40. package/dist/svelte.d.ts +15 -0
  41. package/dist/svelte.d.ts.map +1 -0
  42. package/dist/svelte.js +31 -0
  43. package/dist/svelte.js.map +1 -0
  44. package/dist/vanilla.d.ts +8 -0
  45. package/dist/vanilla.d.ts.map +1 -0
  46. package/dist/vanilla.js +16 -0
  47. package/dist/vanilla.js.map +1 -0
  48. package/dist/vue.d.ts +8 -0
  49. package/dist/vue.d.ts.map +1 -0
  50. package/dist/vue.js +32 -0
  51. package/dist/vue.js.map +1 -0
  52. package/package.json +120 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../../src/core/env.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,SAAS,QAAO,OAGO,CAAC;AAErC,eAAO,MAAM,GAAG,QAAO,MAKtB,CAAC;AAEF,eAAO,MAAM,GAAG,GAAI,IAAI,oBAAoB,KAAG,MAG9C,CAAC;AAEF,eAAO,MAAM,GAAG,GAAI,IAAI,MAAM,KAAG,IAGhC,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAAI,IAAI,MAAM,IAAI,KAAG,IAGnD,CAAC;AAEF,eAAO,MAAM,WAAW,GAAI,IAAI,mBAAmB,EAAE,kBAAe,KAAG,MAItE,CAAC;AAEF,eAAO,MAAM,UAAU,GAAI,IAAI,MAAM,KAAG,IAIvC,CAAC"}
@@ -0,0 +1,38 @@
1
+ export const canUseDOM = () => typeof window !== "undefined" &&
2
+ typeof document !== "undefined" &&
3
+ typeof navigator !== "undefined";
4
+ export const now = () => {
5
+ const p = (typeof performance !== "undefined" ? performance : undefined);
6
+ return typeof p?.now === "function" ? p.now() : Date.now();
7
+ };
8
+ export const raf = (cb) => {
9
+ if (typeof requestAnimationFrame === "function")
10
+ return requestAnimationFrame(cb);
11
+ return setTimeout(() => cb(now()), 16);
12
+ };
13
+ export const caf = (id) => {
14
+ if (typeof cancelAnimationFrame === "function")
15
+ cancelAnimationFrame(id);
16
+ else
17
+ clearTimeout(id);
18
+ };
19
+ export const queueMicrotaskSafe = (cb) => {
20
+ if (typeof queueMicrotask === "function")
21
+ queueMicrotask(cb);
22
+ else
23
+ Promise.resolve().then(cb).catch(() => void 0);
24
+ };
25
+ export const requestIdle = (cb, timeoutMs = 200) => {
26
+ const ric = globalThis.requestIdleCallback;
27
+ if (typeof ric === "function")
28
+ return ric(cb, { timeout: timeoutMs });
29
+ return setTimeout(() => cb({ didTimeout: true, timeRemaining: () => 0 }), 0);
30
+ };
31
+ export const cancelIdle = (id) => {
32
+ const cic = globalThis.cancelIdleCallback;
33
+ if (typeof cic === "function")
34
+ cic(id);
35
+ else
36
+ clearTimeout(id);
37
+ };
38
+ //# sourceMappingURL=env.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env.js","sourceRoot":"","sources":["../../src/core/env.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,SAAS,GAAG,GAAY,EAAE,CACnC,OAAO,MAAM,KAAK,WAAW;IAC7B,OAAO,QAAQ,KAAK,WAAW;IAC/B,OAAO,SAAS,KAAK,WAAW,CAAC;AAErC,MAAM,CAAC,MAAM,GAAG,GAAG,GAAW,EAAE;IAC5B,MAAM,CAAC,GAAG,CAAC,OAAO,WAAW,KAAK,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,CAExD,CAAC;IAChB,OAAO,OAAO,CAAC,EAAE,GAAG,KAAK,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;AAC/D,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,GAAG,GAAG,CAAC,EAAwB,EAAU,EAAE;IACpD,IAAI,OAAO,qBAAqB,KAAK,UAAU;QAAE,OAAO,qBAAqB,CAAC,EAAE,CAAC,CAAC;IAClF,OAAO,UAAU,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,GAAG,EAAuB,CAAC,EAAE,EAAE,CAAsB,CAAC;AACrF,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,GAAG,GAAG,CAAC,EAAU,EAAQ,EAAE;IACpC,IAAI,OAAO,oBAAoB,KAAK,UAAU;QAAE,oBAAoB,CAAC,EAAE,CAAC,CAAC;;QACpE,YAAY,CAAC,EAAuB,CAAC,CAAC;AAC/C,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,EAAc,EAAQ,EAAE;IACvD,IAAI,OAAO,cAAc,KAAK,UAAU;QAAE,cAAc,CAAC,EAAE,CAAC,CAAC;;QACxD,OAAO,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;AACxD,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,EAAuB,EAAE,SAAS,GAAG,GAAG,EAAU,EAAE;IAC5E,MAAM,GAAG,GAAI,UAAkB,CAAC,mBAA+F,CAAC;IAChI,IAAI,OAAO,GAAG,KAAK,UAAU;QAAE,OAAO,GAAG,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC,CAAC;IACtE,OAAO,UAAU,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,aAAa,EAAE,GAAG,EAAE,CAAC,CAAC,EAAkB,CAAC,EAAE,CAAC,CAAsB,CAAC;AACtH,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,EAAU,EAAQ,EAAE;IAC3C,MAAM,GAAG,GAAI,UAAkB,CAAC,kBAAuD,CAAC;IACxF,IAAI,OAAO,GAAG,KAAK,UAAU;QAAE,GAAG,CAAC,EAAE,CAAC,CAAC;;QAClC,YAAY,CAAC,EAAuB,CAAC,CAAC;AAC/C,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ export type { ViewportTruthOptions, ViewportTruthSnapshot, ViewportTruthStore, ViewportTruthSubscribe, } from "./types";
2
+ export { createViewportTruthStore } from "./engine";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACR,oBAAoB,EACpB,qBAAqB,EACrB,kBAAkB,EAClB,sBAAsB,GACzB,MAAM,SAAS,CAAC;AAEjB,OAAO,EAAE,wBAAwB,EAAE,MAAM,UAAU,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { createViewportTruthStore } from "./engine";
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,wBAAwB,EAAE,MAAM,UAAU,CAAC"}
@@ -0,0 +1,7 @@
1
+ export type Scheduler = Readonly<{
2
+ scheduleFrame: (fn: () => void) => void;
3
+ scheduleIdle: (fn: () => void) => void;
4
+ cancelAll: () => void;
5
+ }>;
6
+ export declare const createScheduler: () => Scheduler;
7
+ //# sourceMappingURL=scheduler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scheduler.d.ts","sourceRoot":"","sources":["../../src/core/scheduler.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,SAAS,GAAG,QAAQ,CAAC;IAC7B,aAAa,EAAE,CAAC,EAAE,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;IACxC,YAAY,EAAE,CAAC,EAAE,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;IACvC,SAAS,EAAE,MAAM,IAAI,CAAC;CACzB,CAAC,CAAC;AAEH,eAAO,MAAM,eAAe,QAAO,SA0ClC,CAAC"}
@@ -0,0 +1,44 @@
1
+ import { caf, raf, queueMicrotaskSafe, requestIdle, cancelIdle } from "./env";
2
+ export const createScheduler = () => {
3
+ let rafId = null;
4
+ let idleId = null;
5
+ let frameQueued = false;
6
+ let idleQueued = false;
7
+ return {
8
+ scheduleFrame(fn) {
9
+ if (frameQueued)
10
+ return;
11
+ frameQueued = true;
12
+ queueMicrotaskSafe(() => {
13
+ if (!frameQueued)
14
+ return;
15
+ rafId = raf(() => {
16
+ rafId = null;
17
+ frameQueued = false;
18
+ fn();
19
+ });
20
+ });
21
+ },
22
+ scheduleIdle(fn) {
23
+ if (idleQueued)
24
+ return;
25
+ idleQueued = true;
26
+ idleId = requestIdle(() => {
27
+ idleId = null;
28
+ idleQueued = false;
29
+ fn();
30
+ });
31
+ },
32
+ cancelAll() {
33
+ if (rafId != null)
34
+ caf(rafId);
35
+ if (idleId != null)
36
+ cancelIdle(idleId);
37
+ rafId = null;
38
+ idleId = null;
39
+ frameQueued = false;
40
+ idleQueued = false;
41
+ },
42
+ };
43
+ };
44
+ //# sourceMappingURL=scheduler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scheduler.js","sourceRoot":"","sources":["../../src/core/scheduler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,kBAAkB,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAQ9E,MAAM,CAAC,MAAM,eAAe,GAAG,GAAc,EAAE;IAC3C,IAAI,KAAK,GAAkB,IAAI,CAAC;IAChC,IAAI,MAAM,GAAkB,IAAI,CAAC;IACjC,IAAI,WAAW,GAAG,KAAK,CAAC;IACxB,IAAI,UAAU,GAAG,KAAK,CAAC;IAEvB,OAAO;QACH,aAAa,CAAC,EAAE;YACZ,IAAI,WAAW;gBAAE,OAAO;YACxB,WAAW,GAAG,IAAI,CAAC;YAEnB,kBAAkB,CAAC,GAAG,EAAE;gBACpB,IAAI,CAAC,WAAW;oBAAE,OAAO;gBAEzB,KAAK,GAAG,GAAG,CAAC,GAAG,EAAE;oBACb,KAAK,GAAG,IAAI,CAAC;oBACb,WAAW,GAAG,KAAK,CAAC;oBACpB,EAAE,EAAE,CAAC;gBACT,CAAC,CAAC,CAAC;YACP,CAAC,CAAC,CAAC;QACP,CAAC;QAED,YAAY,CAAC,EAAE;YACX,IAAI,UAAU;gBAAE,OAAO;YACvB,UAAU,GAAG,IAAI,CAAC;YAElB,MAAM,GAAG,WAAW,CAAC,GAAG,EAAE;gBACtB,MAAM,GAAG,IAAI,CAAC;gBACd,UAAU,GAAG,KAAK,CAAC;gBACnB,EAAE,EAAE,CAAC;YACT,CAAC,CAAC,CAAC;QACP,CAAC;QAED,SAAS;YACL,IAAI,KAAK,IAAI,IAAI;gBAAE,GAAG,CAAC,KAAK,CAAC,CAAC;YAC9B,IAAI,MAAM,IAAI,IAAI;gBAAE,UAAU,CAAC,MAAM,CAAC,CAAC;YACvC,KAAK,GAAG,IAAI,CAAC;YACb,MAAM,GAAG,IAAI,CAAC;YACd,WAAW,GAAG,KAAK,CAAC;YACpB,UAAU,GAAG,KAAK,CAAC;QACvB,CAAC;KACJ,CAAC;AACN,CAAC,CAAC"}
@@ -0,0 +1,70 @@
1
+ export type ViewportTruthSnapshot = Readonly<{
2
+ /** CSS px of the *visible* viewport (best-effort, VisualViewport-first) */
3
+ width: number;
4
+ height: number;
5
+ /** Layout viewport (window.inner*) in CSS px */
6
+ layoutWidth: number;
7
+ layoutHeight: number;
8
+ /** Visual viewport offsets (CSS px) */
9
+ offsetLeft: number;
10
+ offsetTop: number;
11
+ /** Zoom scale (1 = no zoom). If unknown => 1 */
12
+ scale: number;
13
+ /** Heuristic flags */
14
+ isKeyboardOpen: boolean;
15
+ isStable: boolean;
16
+ /** Capability flags */
17
+ hasVisualViewport: boolean;
18
+ /** Timestamp (performance.now) when snapshot was computed */
19
+ ts: number;
20
+ }>;
21
+ export type ViewportTruthSubscribe = (onStoreChange: () => void) => () => void;
22
+ export type ViewportTruthStore = Readonly<{
23
+ /** Get current snapshot (client) */
24
+ getSnapshot: () => ViewportTruthSnapshot;
25
+ /** Get server snapshot (SSR) */
26
+ getServerSnapshot: () => ViewportTruthSnapshot | null;
27
+ /** Subscribe to updates */
28
+ subscribe: ViewportTruthSubscribe;
29
+ /** Stop internal listeners (optional manual control) */
30
+ destroy: () => void;
31
+ }>;
32
+ export type ViewportTruthOptions = Readonly<{
33
+ /**
34
+ * Stability debounce in ms. isStable becomes true after this period without changes.
35
+ * Default: 150
36
+ */
37
+ stableDelayMs?: number;
38
+ /**
39
+ * Keyboard detection threshold: if visualHeight < layoutHeight * ratio => keyboard likely open.
40
+ * Default: 0.75
41
+ */
42
+ keyboardRatio?: number;
43
+ /**
44
+ * Also require absolute delta in px to avoid false positives on tiny fluctuations.
45
+ * Default: 120
46
+ */
47
+ keyboardMinDeltaPx?: number;
48
+ /**
49
+ * Treat this as "measurement floor" in CSS px to clamp weird transient zeros.
50
+ * Default: 1
51
+ */
52
+ minViewportPx?: number;
53
+ /**
54
+ * For PWAs / edge environments: if true, prefer VisualViewport even when scale != 1.
55
+ * Default: true
56
+ */
57
+ trustVisualViewportUnderZoom?: boolean;
58
+ /**
59
+ * Optional hook to supply safe-area insets (CSS px).
60
+ * Core engine does not touch DOM; if you want to compensate iOS quirks with env(safe-area-*),
61
+ * provide these from your app layer.
62
+ */
63
+ safeAreaInsets?: Partial<Readonly<{
64
+ top: number;
65
+ right: number;
66
+ bottom: number;
67
+ left: number;
68
+ }>>;
69
+ }>;
70
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,qBAAqB,GAAG,QAAQ,CAAC;IACzC,2EAA2E;IAC3E,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IAEf,gDAAgD;IAChD,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IAErB,uCAAuC;IACvC,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAElB,gDAAgD;IAChD,KAAK,EAAE,MAAM,CAAC;IAEd,sBAAsB;IACtB,cAAc,EAAE,OAAO,CAAC;IACxB,QAAQ,EAAE,OAAO,CAAC;IAElB,uBAAuB;IACvB,iBAAiB,EAAE,OAAO,CAAC;IAE3B,6DAA6D;IAC7D,EAAE,EAAE,MAAM,CAAC;CACd,CAAC,CAAC;AAEH,MAAM,MAAM,sBAAsB,GAAG,CAAC,aAAa,EAAE,MAAM,IAAI,KAAK,MAAM,IAAI,CAAC;AAE/E,MAAM,MAAM,kBAAkB,GAAG,QAAQ,CAAC;IACtC,oCAAoC;IACpC,WAAW,EAAE,MAAM,qBAAqB,CAAC;IACzC,gCAAgC;IAChC,iBAAiB,EAAE,MAAM,qBAAqB,GAAG,IAAI,CAAC;IACtD,2BAA2B;IAC3B,SAAS,EAAE,sBAAsB,CAAC;IAClC,wDAAwD;IACxD,OAAO,EAAE,MAAM,IAAI,CAAC;CACvB,CAAC,CAAC;AAEH,MAAM,MAAM,oBAAoB,GAAG,QAAQ,CAAC;IACxC;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB;;;OAGG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAE5B;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB;;;OAGG;IACH,4BAA4B,CAAC,EAAE,OAAO,CAAC;IAEvC;;;;OAIG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,CAAC;CACpG,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,8 @@
1
+ export * from "./core/index";
2
+ export * as react from "./react";
3
+ export * as vue from "./vue";
4
+ export * as svelte from "./svelte";
5
+ export * as solid from "./solid";
6
+ export * as angular from "./angular";
7
+ export * as vanilla from "./vanilla";
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAE7B,OAAO,KAAK,KAAK,MAAM,SAAS,CAAC;AACjC,OAAO,KAAK,GAAG,MAAM,OAAO,CAAC;AAC7B,OAAO,KAAK,MAAM,MAAM,UAAU,CAAC;AACnC,OAAO,KAAK,KAAK,MAAM,SAAS,CAAC;AACjC,OAAO,KAAK,OAAO,MAAM,WAAW,CAAC;AACrC,OAAO,KAAK,OAAO,MAAM,WAAW,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,8 @@
1
+ export * from "./core/index";
2
+ export * as react from "./react";
3
+ export * as vue from "./vue";
4
+ export * as svelte from "./svelte";
5
+ export * as solid from "./solid";
6
+ export * as angular from "./angular";
7
+ export * as vanilla from "./vanilla";
8
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAE7B,OAAO,KAAK,KAAK,MAAM,SAAS,CAAC;AACjC,OAAO,KAAK,GAAG,MAAM,OAAO,CAAC;AAC7B,OAAO,KAAK,MAAM,MAAM,UAAU,CAAC;AACnC,OAAO,KAAK,KAAK,MAAM,SAAS,CAAC;AACjC,OAAO,KAAK,OAAO,MAAM,WAAW,CAAC;AACrC,OAAO,KAAK,OAAO,MAAM,WAAW,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { ViewportTruthOptions, ViewportTruthSnapshot } from "./core/types";
2
+ export type UseViewportTruthResult = ViewportTruthSnapshot | null;
3
+ export declare const useViewportTruth: (options?: ViewportTruthOptions) => UseViewportTruthResult;
4
+ //# sourceMappingURL=react.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"react.d.ts","sourceRoot":"","sources":["../src/react.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAGhF,MAAM,MAAM,sBAAsB,GAAG,qBAAqB,GAAG,IAAI,CAAC;AAElE,eAAO,MAAM,gBAAgB,GAAI,UAAU,oBAAoB,KAAG,sBAIjE,CAAC"}
package/dist/react.js ADDED
@@ -0,0 +1,7 @@
1
+ import { useMemo, useSyncExternalStore } from "react";
2
+ import { createViewportTruthStore } from "./core/engine";
3
+ export const useViewportTruth = (options) => {
4
+ const store = useMemo(() => createViewportTruthStore(options), [options]);
5
+ return useSyncExternalStore(store.subscribe, store.getSnapshot, store.getServerSnapshot);
6
+ };
7
+ //# sourceMappingURL=react.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"react.js","sourceRoot":"","sources":["../src/react.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,oBAAoB,EAAE,MAAM,OAAO,CAAC;AAEtD,OAAO,EAAE,wBAAwB,EAAE,MAAM,eAAe,CAAC;AAIzD,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,OAA8B,EAA0B,EAAE;IACvF,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,wBAAwB,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;IAE1E,OAAO,oBAAoB,CAAC,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,WAAW,EAAE,KAAK,CAAC,iBAAiB,CAAC,CAAC;AAC7F,CAAC,CAAC"}
@@ -0,0 +1,12 @@
1
+ import { type Accessor } from "solid-js";
2
+ import type { ViewportTruthOptions, ViewportTruthSnapshot } from "./core/types";
3
+ export declare const createViewportTruth: (options?: ViewportTruthOptions) => Accessor<ViewportTruthSnapshot | null>;
4
+ /**
5
+ * Directive-like helper (Solid "use:" works with functions)
6
+ * Usage: <div use:viewportTruthDirective={{ onChange, options }} />
7
+ */
8
+ export declare const viewportTruthDirective: (_el: HTMLElement, accessor: () => {
9
+ onChange: (s: ViewportTruthSnapshot) => void;
10
+ options?: ViewportTruthOptions;
11
+ }) => void;
12
+ //# sourceMappingURL=solid.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"solid.d.ts","sourceRoot":"","sources":["../src/solid.ts"],"names":[],"mappings":"AAAA,OAAO,EAA2B,KAAK,QAAQ,EAAE,MAAM,UAAU,CAAC;AAClE,OAAO,KAAK,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAGhF,eAAO,MAAM,mBAAmB,GAC5B,UAAU,oBAAoB,KAC/B,QAAQ,CAAC,qBAAqB,GAAG,IAAI,CAYvC,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,sBAAsB,GAC/B,KAAK,WAAW,EAChB,UAAU,MAAM;IAAE,QAAQ,EAAE,CAAC,CAAC,EAAE,qBAAqB,KAAK,IAAI,CAAC;IAAC,OAAO,CAAC,EAAE,oBAAoB,CAAA;CAAE,SAUnG,CAAC"}
package/dist/solid.js ADDED
@@ -0,0 +1,26 @@
1
+ import { createSignal, onCleanup } from "solid-js";
2
+ import { createViewportTruthStore } from "./core/engine";
3
+ export const createViewportTruth = (options) => {
4
+ const store = createViewportTruthStore(options);
5
+ const [snap, setSnap] = createSignal(store.getServerSnapshot());
6
+ const unsub = store.subscribe(() => setSnap(store.getSnapshot()));
7
+ onCleanup(() => {
8
+ unsub();
9
+ store.destroy();
10
+ });
11
+ return snap;
12
+ };
13
+ /**
14
+ * Directive-like helper (Solid "use:" works with functions)
15
+ * Usage: <div use:viewportTruthDirective={{ onChange, options }} />
16
+ */
17
+ export const viewportTruthDirective = (_el, accessor) => {
18
+ const cfg = accessor();
19
+ const store = createViewportTruthStore(cfg.options);
20
+ const unsub = store.subscribe(() => cfg.onChange(store.getSnapshot()));
21
+ onCleanup(() => {
22
+ unsub();
23
+ store.destroy();
24
+ });
25
+ };
26
+ //# sourceMappingURL=solid.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"solid.js","sourceRoot":"","sources":["../src/solid.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,SAAS,EAAiB,MAAM,UAAU,CAAC;AAElE,OAAO,EAAE,wBAAwB,EAAE,MAAM,eAAe,CAAC;AAEzD,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAC/B,OAA8B,EACQ,EAAE;IACxC,MAAM,KAAK,GAAG,wBAAwB,CAAC,OAAO,CAAC,CAAC;IAChD,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,YAAY,CAA+B,KAAK,CAAC,iBAAiB,EAAE,CAAC,CAAC;IAE9F,MAAM,KAAK,GAAG,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;IAElE,SAAS,CAAC,GAAG,EAAE;QACX,KAAK,EAAE,CAAC;QACR,KAAK,CAAC,OAAO,EAAE,CAAC;IACpB,CAAC,CAAC,CAAC;IAEH,OAAO,IAAI,CAAC;AAChB,CAAC,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAClC,GAAgB,EAChB,QAAgG,EAClG,EAAE;IACA,MAAM,GAAG,GAAG,QAAQ,EAAE,CAAC;IACvB,MAAM,KAAK,GAAG,wBAAwB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IACpD,MAAM,KAAK,GAAG,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;IAEvE,SAAS,CAAC,GAAG,EAAE;QACX,KAAK,EAAE,CAAC;QACR,KAAK,CAAC,OAAO,EAAE,CAAC;IACpB,CAAC,CAAC,CAAC;AACP,CAAC,CAAC"}
@@ -0,0 +1,15 @@
1
+ import type { ViewportTruthOptions, ViewportTruthSnapshot } from "./core/types";
2
+ export declare const viewportTruth: (options?: ViewportTruthOptions) => {
3
+ subscribe(run: (v: ViewportTruthSnapshot | null) => void): () => void;
4
+ };
5
+ /**
6
+ * Action: use:viewportTruthAction={{ onChange, options }}
7
+ */
8
+ export declare const viewportTruthAction: (_node: HTMLElement, params: {
9
+ onChange: (s: ViewportTruthSnapshot) => void;
10
+ options?: ViewportTruthOptions;
11
+ }) => {
12
+ update(next: typeof params): void;
13
+ destroy(): void;
14
+ };
15
+ //# sourceMappingURL=svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"svelte.d.ts","sourceRoot":"","sources":["../src/svelte.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAGhF,eAAO,MAAM,aAAa,GAAI,UAAU,oBAAoB;mBAIrC,CAAC,CAAC,EAAE,qBAAqB,GAAG,IAAI,KAAK,IAAI;CAS/D,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,mBAAmB,GAC5B,OAAO,WAAW,EAClB,QAAQ;IAAE,QAAQ,EAAE,CAAC,CAAC,EAAE,qBAAqB,KAAK,IAAI,CAAC;IAAC,OAAO,CAAC,EAAE,oBAAoB,CAAA;CAAE;iBAMvE,OAAO,MAAM;;CAQjC,CAAC"}
package/dist/svelte.js ADDED
@@ -0,0 +1,31 @@
1
+ import { createViewportTruthStore } from "./core/engine";
2
+ export const viewportTruth = (options) => {
3
+ const store = createViewportTruthStore(options);
4
+ return {
5
+ subscribe(run) {
6
+ run(store.getServerSnapshot());
7
+ const unsub = store.subscribe(() => run(store.getSnapshot()));
8
+ return () => {
9
+ unsub();
10
+ store.destroy();
11
+ };
12
+ },
13
+ };
14
+ };
15
+ /**
16
+ * Action: use:viewportTruthAction={{ onChange, options }}
17
+ */
18
+ export const viewportTruthAction = (_node, params) => {
19
+ const store = createViewportTruthStore(params?.options);
20
+ const unsub = store.subscribe(() => params.onChange(store.getSnapshot()));
21
+ return {
22
+ update(next) {
23
+ params = next;
24
+ },
25
+ destroy() {
26
+ unsub();
27
+ store.destroy();
28
+ },
29
+ };
30
+ };
31
+ //# sourceMappingURL=svelte.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"svelte.js","sourceRoot":"","sources":["../src/svelte.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,wBAAwB,EAAE,MAAM,eAAe,CAAC;AAEzD,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,OAA8B,EAAE,EAAE;IAC5D,MAAM,KAAK,GAAG,wBAAwB,CAAC,OAAO,CAAC,CAAC;IAEhD,OAAO;QACH,SAAS,CAAC,GAA8C;YACpD,GAAG,CAAC,KAAK,CAAC,iBAAiB,EAAE,CAAC,CAAC;YAC/B,MAAM,KAAK,GAAG,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;YAC9D,OAAO,GAAG,EAAE;gBACR,KAAK,EAAE,CAAC;gBACR,KAAK,CAAC,OAAO,EAAE,CAAC;YACpB,CAAC,CAAC;QACN,CAAC;KACJ,CAAC;AACN,CAAC,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAC/B,KAAkB,EAClB,MAAwF,EAC1F,EAAE;IACA,MAAM,KAAK,GAAG,wBAAwB,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACxD,MAAM,KAAK,GAAG,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;IAE1E,OAAO;QACH,MAAM,CAAC,IAAmB;YACtB,MAAM,GAAG,IAAI,CAAC;QAClB,CAAC;QACD,OAAO;YACH,KAAK,EAAE,CAAC;YACR,KAAK,CAAC,OAAO,EAAE,CAAC;QACpB,CAAC;KACJ,CAAC;AACN,CAAC,CAAC"}
@@ -0,0 +1,8 @@
1
+ import type { ViewportTruthOptions, ViewportTruthSnapshot } from "./core/types";
2
+ export type ViewportTruthController = Readonly<{
3
+ get: () => ViewportTruthSnapshot;
4
+ subscribe: (fn: (s: ViewportTruthSnapshot) => void) => () => void;
5
+ destroy: () => void;
6
+ }>;
7
+ export declare const createViewportTruth: (options?: ViewportTruthOptions) => ViewportTruthController;
8
+ //# sourceMappingURL=vanilla.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vanilla.d.ts","sourceRoot":"","sources":["../src/vanilla.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAGhF,MAAM,MAAM,uBAAuB,GAAG,QAAQ,CAAC;IAC3C,GAAG,EAAE,MAAM,qBAAqB,CAAC;IACjC,SAAS,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,qBAAqB,KAAK,IAAI,KAAK,MAAM,IAAI,CAAC;IAClE,OAAO,EAAE,MAAM,IAAI,CAAC;CACvB,CAAC,CAAC;AAEH,eAAO,MAAM,mBAAmB,GAAI,UAAU,oBAAoB,KAAG,uBAcpE,CAAC"}
@@ -0,0 +1,16 @@
1
+ import { createViewportTruthStore } from "./core/engine";
2
+ export const createViewportTruth = (options) => {
3
+ const store = createViewportTruthStore(options);
4
+ return {
5
+ get() {
6
+ return store.getSnapshot();
7
+ },
8
+ subscribe(fn) {
9
+ return store.subscribe(() => fn(store.getSnapshot()));
10
+ },
11
+ destroy() {
12
+ store.destroy();
13
+ },
14
+ };
15
+ };
16
+ //# sourceMappingURL=vanilla.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vanilla.js","sourceRoot":"","sources":["../src/vanilla.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,wBAAwB,EAAE,MAAM,eAAe,CAAC;AAQzD,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,OAA8B,EAA2B,EAAE;IAC3F,MAAM,KAAK,GAAG,wBAAwB,CAAC,OAAO,CAAC,CAAC;IAEhD,OAAO;QACH,GAAG;YACC,OAAO,KAAK,CAAC,WAAW,EAAE,CAAC;QAC/B,CAAC;QACD,SAAS,CAAC,EAAE;YACR,OAAO,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;QAC1D,CAAC;QACD,OAAO;YACH,KAAK,CAAC,OAAO,EAAE,CAAC;QACpB,CAAC;KACJ,CAAC;AACN,CAAC,CAAC"}
package/dist/vue.d.ts ADDED
@@ -0,0 +1,8 @@
1
+ import { type ShallowRef, type Directive } from "vue";
2
+ import type { ViewportTruthOptions, ViewportTruthSnapshot } from "./core/types";
3
+ export declare const useViewportTruth: (options?: ViewportTruthOptions) => ShallowRef<ViewportTruthSnapshot | null>;
4
+ export declare const vViewportTruth: Directive<HTMLElement, {
5
+ onChange: (s: ViewportTruthSnapshot) => void;
6
+ options?: ViewportTruthOptions;
7
+ }>;
8
+ //# sourceMappingURL=vue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vue.d.ts","sourceRoot":"","sources":["../src/vue.ts"],"names":[],"mappings":"AAAA,OAAO,EAA0C,KAAK,UAAU,EAAE,KAAK,SAAS,EAAE,MAAM,KAAK,CAAC;AAC9F,OAAO,KAAK,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAGhF,eAAO,MAAM,gBAAgB,GACzB,UAAU,oBAAoB,KAC/B,UAAU,CAAC,qBAAqB,GAAG,IAAI,CAkBzC,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,SAAS,CAAC,WAAW,EAAE;IAAE,QAAQ,EAAE,CAAC,CAAC,EAAE,qBAAqB,KAAK,IAAI,CAAC;IAAC,OAAO,CAAC,EAAE,oBAAoB,CAAA;CAAE,CAgB/H,CAAC"}
package/dist/vue.js ADDED
@@ -0,0 +1,32 @@
1
+ import { onBeforeUnmount, onMounted, shallowRef } from "vue";
2
+ import { createViewportTruthStore } from "./core/engine";
3
+ export const useViewportTruth = (options) => {
4
+ const store = createViewportTruthStore(options);
5
+ const state = shallowRef(store.getServerSnapshot());
6
+ let unsub = null;
7
+ onMounted(() => {
8
+ unsub = store.subscribe(() => {
9
+ state.value = store.getSnapshot();
10
+ });
11
+ });
12
+ onBeforeUnmount(() => {
13
+ unsub?.();
14
+ store.destroy();
15
+ });
16
+ return state;
17
+ };
18
+ export const vViewportTruth = {
19
+ mounted(_el, binding) {
20
+ const store = createViewportTruthStore(binding.value?.options);
21
+ const onChange = binding.value?.onChange;
22
+ const unsub = store.subscribe(() => onChange(store.getSnapshot()));
23
+ _el.__vt = { store, unsub };
24
+ },
25
+ unmounted(el) {
26
+ const bag = el.__vt;
27
+ bag?.unsub?.();
28
+ bag?.store?.destroy?.();
29
+ delete el.__vt;
30
+ },
31
+ };
32
+ //# sourceMappingURL=vue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vue.js","sourceRoot":"","sources":["../src/vue.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,UAAU,EAAmC,MAAM,KAAK,CAAC;AAE9F,OAAO,EAAE,wBAAwB,EAAE,MAAM,eAAe,CAAC;AAEzD,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAC5B,OAA8B,EACU,EAAE;IAC1C,MAAM,KAAK,GAAG,wBAAwB,CAAC,OAAO,CAAC,CAAC;IAChD,MAAM,KAAK,GAAG,UAAU,CAA+B,KAAK,CAAC,iBAAiB,EAAE,CAAC,CAAC;IAElF,IAAI,KAAK,GAAwB,IAAI,CAAC;IAEtC,SAAS,CAAC,GAAG,EAAE;QACX,KAAK,GAAG,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;YACzB,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC;QACtC,CAAC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;IAEH,eAAe,CAAC,GAAG,EAAE;QACjB,KAAK,EAAE,EAAE,CAAC;QACV,KAAK,CAAC,OAAO,EAAE,CAAC;IACpB,CAAC,CAAC,CAAC;IAEH,OAAO,KAAK,CAAC;AACjB,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,cAAc,GACvB;IACI,OAAO,CAAC,GAAG,EAAE,OAAO;QAChB,MAAM,KAAK,GAAG,wBAAwB,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QAC/D,MAAM,QAAQ,GAAG,OAAO,CAAC,KAAK,EAAE,QAAQ,CAAC;QAEzC,MAAM,KAAK,GAAG,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;QAEjE,GAAW,CAAC,IAAI,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;IAC1C,CAAC;IACD,SAAS,CAAC,EAAE;QACR,MAAM,GAAG,GAAI,EAAU,CAAC,IAA6F,CAAC;QACtH,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC;QACf,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,CAAC;QACxB,OAAQ,EAAU,CAAC,IAAI,CAAC;IAC5B,CAAC;CACJ,CAAC"}
package/package.json ADDED
@@ -0,0 +1,120 @@
1
+ {
2
+ "name": "viewport-truth",
3
+ "version": "1.0.0",
4
+ "description": "",
5
+ "author": {
6
+ "name": "AntonVoronezh",
7
+ "email": "anton.voronezh.1990@gmail.com",
8
+ "url": "https://github.com/AntonVoronezh"
9
+ },
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "git+https://github.com/AntonVoronezh/viewport-truth.git"
13
+ },
14
+ "bugs": {
15
+ "url": "https://github.com/AntonVoronezh/viewport-truth/issues"
16
+ },
17
+ "homepage": "https://github.com/AntonVoronezh/viewport-truth#readme",
18
+ "funding": [
19
+ {
20
+ "type": "boosty",
21
+ "url": "https://boosty.to/antonvoronezh/donate"
22
+ },
23
+ {
24
+ "type": "crypto",
25
+ "url": "https://t.me/AntonVoronezhh/4"
26
+ }
27
+ ],
28
+ "files": [
29
+ "dist",
30
+ "README.md",
31
+ "LICENSE",
32
+ "banner.js"
33
+ ],
34
+ "scripts": {
35
+ "build": "tsc -p tsconfig.build.json",
36
+ "clean": "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\"",
37
+ "typecheck": "tsc -p tsconfig.json --noEmit",
38
+ "postinstall": "node ./banner.js || exit 0"
39
+ },
40
+ "keywords": [
41
+
42
+ ],
43
+ "license": "MIT",
44
+ "type": "module",
45
+ "sideEffects": false,
46
+ "exports": {
47
+ ".": {
48
+ "types": "./dist/index.d.ts",
49
+ "default": "./dist/index.js"
50
+ },
51
+ "./core": {
52
+ "types": "./dist/core/index.d.ts",
53
+ "default": "./dist/core/index.js"
54
+ },
55
+ "./react": {
56
+ "types": "./dist/react.d.ts",
57
+ "default": "./dist/react.js"
58
+ },
59
+ "./vue": {
60
+ "types": "./dist/vue.d.ts",
61
+ "default": "./dist/vue.js"
62
+ },
63
+ "./svelte": {
64
+ "types": "./dist/svelte.d.ts",
65
+ "default": "./dist/svelte.js"
66
+ },
67
+ "./solid": {
68
+ "types": "./dist/solid.d.ts",
69
+ "default": "./dist/solid.js"
70
+ },
71
+ "./angular": {
72
+ "types": "./dist/angular.d.ts",
73
+ "default": "./dist/angular.js"
74
+ },
75
+ "./vanilla": {
76
+ "types": "./dist/vanilla.d.ts",
77
+ "default": "./dist/vanilla.js"
78
+ }
79
+ },
80
+ "main": "./dist/index.js",
81
+ "types": "./dist/index.d.ts",
82
+ "peerDependencies": {
83
+ "react": ">=18.0.0",
84
+ "vue": ">=3.3.0",
85
+ "svelte": ">=4.0.0",
86
+ "solid-js": ">=1.7.0",
87
+ "@angular/core": ">=17.0.0"
88
+ },
89
+ "peerDependenciesMeta": {
90
+ "react": {
91
+ "optional": true
92
+ },
93
+ "vue": {
94
+ "optional": true
95
+ },
96
+ "svelte": {
97
+ "optional": true
98
+ },
99
+ "solid-js": {
100
+ "optional": true
101
+ },
102
+ "@angular/core": {
103
+ "optional": true
104
+ }
105
+ },
106
+ "devDependencies": {
107
+ "typescript": "^5.5.4",
108
+ "@types/node": "^22.0.0",
109
+ "react": "^18.3.0",
110
+ "react-dom": "^18.3.0",
111
+ "@types/react": "^18.3.0",
112
+ "@types/react-dom": "^18.3.0",
113
+ "vue": "^3.5.0",
114
+ "svelte": "^4.2.0",
115
+ "solid-js": "^1.9.0",
116
+ "@angular/core": "^17.3.0",
117
+ "@angular/common": "^17.3.0",
118
+ "rxjs": "^7.8.0"
119
+ }
120
+ }