real-view 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.
@@ -0,0 +1,23 @@
1
+ type realViewOptions = {
2
+ threshold?: number;
3
+ pollInterval?: number;
4
+ trackTab?: boolean;
5
+ };
6
+ type VisibilityCallback = (isVisible: boolean) => void;
7
+ declare class realViewEngine {
8
+ private static instance;
9
+ private observer;
10
+ private watchers;
11
+ static get(): realViewEngine;
12
+ private constructor();
13
+ private initObserver;
14
+ private initTabListener;
15
+ private handleIntersect;
16
+ private checkOcclusion;
17
+ private startPolling;
18
+ private stopPolling;
19
+ private notify;
20
+ observe(el: Element, cb: VisibilityCallback, options?: realViewOptions): () => void;
21
+ }
22
+
23
+ export { realViewEngine, type realViewOptions };
@@ -0,0 +1,23 @@
1
+ type realViewOptions = {
2
+ threshold?: number;
3
+ pollInterval?: number;
4
+ trackTab?: boolean;
5
+ };
6
+ type VisibilityCallback = (isVisible: boolean) => void;
7
+ declare class realViewEngine {
8
+ private static instance;
9
+ private observer;
10
+ private watchers;
11
+ static get(): realViewEngine;
12
+ private constructor();
13
+ private initObserver;
14
+ private initTabListener;
15
+ private handleIntersect;
16
+ private checkOcclusion;
17
+ private startPolling;
18
+ private stopPolling;
19
+ private notify;
20
+ observe(el: Element, cb: VisibilityCallback, options?: realViewOptions): () => void;
21
+ }
22
+
23
+ export { realViewEngine, type realViewOptions };
package/dist/index.js ADDED
@@ -0,0 +1,6 @@
1
+ import {
2
+ realViewEngine
3
+ } from "./chunk-UW5FKFTH.js";
4
+ export {
5
+ realViewEngine
6
+ };
package/dist/react.cjs ADDED
@@ -0,0 +1,149 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __export = (target, all) => {
6
+ for (var name in all)
7
+ __defProp(target, name, { get: all[name], enumerable: true });
8
+ };
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
+
19
+ // src/react.ts
20
+ var react_exports = {};
21
+ __export(react_exports, {
22
+ userealView: () => userealView
23
+ });
24
+ module.exports = __toCommonJS(react_exports);
25
+ var import_react = require("react");
26
+
27
+ // src/core/utils.ts
28
+ var isBrowser = () => {
29
+ return typeof window !== "undefined" && typeof window.document !== "undefined";
30
+ };
31
+
32
+ // src/core/engine.ts
33
+ var realViewEngine = class _realViewEngine {
34
+ constructor() {
35
+ this.observer = null;
36
+ this.watchers = /* @__PURE__ */ new Map();
37
+ if (!isBrowser()) return;
38
+ this.initObserver();
39
+ this.initTabListener();
40
+ }
41
+ static get() {
42
+ if (!this.instance) this.instance = new _realViewEngine();
43
+ return this.instance;
44
+ }
45
+ initObserver() {
46
+ this.observer = new IntersectionObserver(this.handleIntersect.bind(this), {
47
+ threshold: 0
48
+ });
49
+ }
50
+ initTabListener() {
51
+ document.addEventListener("visibilitychange", () => {
52
+ const isHidden = document.hidden;
53
+ this.watchers.forEach((w) => {
54
+ if (w.opts.trackTab && isHidden) {
55
+ this.notify(w, false);
56
+ } else if (w.state.inViewport && !isHidden) {
57
+ this.checkOcclusion(w);
58
+ }
59
+ });
60
+ });
61
+ }
62
+ handleIntersect(entries) {
63
+ entries.forEach((entry) => {
64
+ const watcher = this.watchers.get(entry.target);
65
+ if (!watcher) return;
66
+ watcher.state.inViewport = entry.isIntersecting;
67
+ if (entry.isIntersecting) {
68
+ this.startPolling(watcher);
69
+ } else {
70
+ this.stopPolling(watcher);
71
+ this.notify(watcher, false);
72
+ }
73
+ });
74
+ }
75
+ checkOcclusion(w) {
76
+ if (w.opts.trackTab && document.hidden) return this.notify(w, false);
77
+ const rect = w.el.getBoundingClientRect();
78
+ if (rect.width === 0 || rect.height === 0) return this.notify(w, false);
79
+ const style = window.getComputedStyle(w.el);
80
+ if (style.opacity === "0" || style.visibility === "hidden") return this.notify(w, false);
81
+ const x = rect.left + rect.width / 2;
82
+ const y = rect.top + rect.height / 2;
83
+ const topEl = document.elementFromPoint(x, y);
84
+ const isVisible = topEl ? w.el.contains(topEl) || w.el === topEl : false;
85
+ this.notify(w, isVisible);
86
+ }
87
+ startPolling(w) {
88
+ if (w.state.timer) return;
89
+ const tick = () => {
90
+ if ("requestIdleCallback" in window) {
91
+ window.requestIdleCallback(() => this.checkOcclusion(w));
92
+ } else {
93
+ this.checkOcclusion(w);
94
+ }
95
+ };
96
+ tick();
97
+ w.state.timer = window.setInterval(tick, w.opts.pollInterval);
98
+ }
99
+ stopPolling(w) {
100
+ if (w.state.timer) {
101
+ clearInterval(w.state.timer);
102
+ w.state.timer = null;
103
+ }
104
+ }
105
+ notify(w, isVisible) {
106
+ if (w.state.isOccluded !== !isVisible) {
107
+ w.state.isOccluded = !isVisible;
108
+ w.cb(isVisible);
109
+ }
110
+ }
111
+ observe(el, cb, options = {}) {
112
+ if (!isBrowser()) return () => {
113
+ };
114
+ const opts = {
115
+ threshold: 0,
116
+ pollInterval: 1e3,
117
+ trackTab: true,
118
+ ...options
119
+ };
120
+ this.watchers.set(el, {
121
+ el,
122
+ cb,
123
+ opts,
124
+ state: { inViewport: false, isOccluded: false, timer: null }
125
+ });
126
+ this.observer?.observe(el);
127
+ return () => {
128
+ this.stopPolling(this.watchers.get(el));
129
+ this.observer?.unobserve(el);
130
+ this.watchers.delete(el);
131
+ };
132
+ }
133
+ };
134
+
135
+ // src/react.ts
136
+ function userealView(options) {
137
+ const ref = (0, import_react.useRef)(null);
138
+ const [isVisible, setIsVisible] = (0, import_react.useState)(false);
139
+ (0, import_react.useEffect)(() => {
140
+ if (!ref.current) return;
141
+ const cleanup = realViewEngine.get().observe(ref.current, setIsVisible, options);
142
+ return cleanup;
143
+ }, [options?.pollInterval, options?.trackTab]);
144
+ return [ref, isVisible];
145
+ }
146
+ // Annotate the CommonJS export names for ESM import in node:
147
+ 0 && (module.exports = {
148
+ userealView
149
+ });
@@ -0,0 +1,6 @@
1
+ import * as react from 'react';
2
+ import { realViewOptions } from './index.cjs';
3
+
4
+ declare function userealView(options?: realViewOptions): readonly [react.MutableRefObject<HTMLElement>, boolean];
5
+
6
+ export { userealView };
@@ -0,0 +1,6 @@
1
+ import * as react from 'react';
2
+ import { realViewOptions } from './index.js';
3
+
4
+ declare function userealView(options?: realViewOptions): readonly [react.MutableRefObject<HTMLElement>, boolean];
5
+
6
+ export { userealView };
package/dist/react.js ADDED
@@ -0,0 +1,19 @@
1
+ import {
2
+ realViewEngine
3
+ } from "./chunk-UW5FKFTH.js";
4
+
5
+ // src/react.ts
6
+ import { useEffect, useRef, useState } from "react";
7
+ function userealView(options) {
8
+ const ref = useRef(null);
9
+ const [isVisible, setIsVisible] = useState(false);
10
+ useEffect(() => {
11
+ if (!ref.current) return;
12
+ const cleanup = realViewEngine.get().observe(ref.current, setIsVisible, options);
13
+ return cleanup;
14
+ }, [options?.pollInterval, options?.trackTab]);
15
+ return [ref, isVisible];
16
+ }
17
+ export {
18
+ userealView
19
+ };
package/dist/solid.cjs ADDED
@@ -0,0 +1,150 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __export = (target, all) => {
6
+ for (var name in all)
7
+ __defProp(target, name, { get: all[name], enumerable: true });
8
+ };
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
+
19
+ // src/solid.ts
20
+ var solid_exports = {};
21
+ __export(solid_exports, {
22
+ createrealView: () => createrealView
23
+ });
24
+ module.exports = __toCommonJS(solid_exports);
25
+ var import_solid_js = require("solid-js");
26
+
27
+ // src/core/utils.ts
28
+ var isBrowser = () => {
29
+ return typeof window !== "undefined" && typeof window.document !== "undefined";
30
+ };
31
+
32
+ // src/core/engine.ts
33
+ var realViewEngine = class _realViewEngine {
34
+ constructor() {
35
+ this.observer = null;
36
+ this.watchers = /* @__PURE__ */ new Map();
37
+ if (!isBrowser()) return;
38
+ this.initObserver();
39
+ this.initTabListener();
40
+ }
41
+ static get() {
42
+ if (!this.instance) this.instance = new _realViewEngine();
43
+ return this.instance;
44
+ }
45
+ initObserver() {
46
+ this.observer = new IntersectionObserver(this.handleIntersect.bind(this), {
47
+ threshold: 0
48
+ });
49
+ }
50
+ initTabListener() {
51
+ document.addEventListener("visibilitychange", () => {
52
+ const isHidden = document.hidden;
53
+ this.watchers.forEach((w) => {
54
+ if (w.opts.trackTab && isHidden) {
55
+ this.notify(w, false);
56
+ } else if (w.state.inViewport && !isHidden) {
57
+ this.checkOcclusion(w);
58
+ }
59
+ });
60
+ });
61
+ }
62
+ handleIntersect(entries) {
63
+ entries.forEach((entry) => {
64
+ const watcher = this.watchers.get(entry.target);
65
+ if (!watcher) return;
66
+ watcher.state.inViewport = entry.isIntersecting;
67
+ if (entry.isIntersecting) {
68
+ this.startPolling(watcher);
69
+ } else {
70
+ this.stopPolling(watcher);
71
+ this.notify(watcher, false);
72
+ }
73
+ });
74
+ }
75
+ checkOcclusion(w) {
76
+ if (w.opts.trackTab && document.hidden) return this.notify(w, false);
77
+ const rect = w.el.getBoundingClientRect();
78
+ if (rect.width === 0 || rect.height === 0) return this.notify(w, false);
79
+ const style = window.getComputedStyle(w.el);
80
+ if (style.opacity === "0" || style.visibility === "hidden") return this.notify(w, false);
81
+ const x = rect.left + rect.width / 2;
82
+ const y = rect.top + rect.height / 2;
83
+ const topEl = document.elementFromPoint(x, y);
84
+ const isVisible = topEl ? w.el.contains(topEl) || w.el === topEl : false;
85
+ this.notify(w, isVisible);
86
+ }
87
+ startPolling(w) {
88
+ if (w.state.timer) return;
89
+ const tick = () => {
90
+ if ("requestIdleCallback" in window) {
91
+ window.requestIdleCallback(() => this.checkOcclusion(w));
92
+ } else {
93
+ this.checkOcclusion(w);
94
+ }
95
+ };
96
+ tick();
97
+ w.state.timer = window.setInterval(tick, w.opts.pollInterval);
98
+ }
99
+ stopPolling(w) {
100
+ if (w.state.timer) {
101
+ clearInterval(w.state.timer);
102
+ w.state.timer = null;
103
+ }
104
+ }
105
+ notify(w, isVisible) {
106
+ if (w.state.isOccluded !== !isVisible) {
107
+ w.state.isOccluded = !isVisible;
108
+ w.cb(isVisible);
109
+ }
110
+ }
111
+ observe(el, cb, options = {}) {
112
+ if (!isBrowser()) return () => {
113
+ };
114
+ const opts = {
115
+ threshold: 0,
116
+ pollInterval: 1e3,
117
+ trackTab: true,
118
+ ...options
119
+ };
120
+ this.watchers.set(el, {
121
+ el,
122
+ cb,
123
+ opts,
124
+ state: { inViewport: false, isOccluded: false, timer: null }
125
+ });
126
+ this.observer?.observe(el);
127
+ return () => {
128
+ this.stopPolling(this.watchers.get(el));
129
+ this.observer?.unobserve(el);
130
+ this.watchers.delete(el);
131
+ };
132
+ }
133
+ };
134
+
135
+ // src/solid.ts
136
+ function createrealView(el, options) {
137
+ const [isVisible, setIsVisible] = (0, import_solid_js.createSignal)(false);
138
+ (0, import_solid_js.onMount)(() => {
139
+ const node = el();
140
+ if (node) {
141
+ const stop = realViewEngine.get().observe(node, setIsVisible, options);
142
+ (0, import_solid_js.onCleanup)(stop);
143
+ }
144
+ });
145
+ return isVisible;
146
+ }
147
+ // Annotate the CommonJS export names for ESM import in node:
148
+ 0 && (module.exports = {
149
+ createrealView
150
+ });
@@ -0,0 +1,6 @@
1
+ import * as solid_js from 'solid-js';
2
+ import { realViewOptions } from './index.cjs';
3
+
4
+ declare function createrealView(el: () => HTMLElement | null, options?: realViewOptions): solid_js.Accessor<boolean>;
5
+
6
+ export { createrealView };
@@ -0,0 +1,6 @@
1
+ import * as solid_js from 'solid-js';
2
+ import { realViewOptions } from './index.js';
3
+
4
+ declare function createrealView(el: () => HTMLElement | null, options?: realViewOptions): solid_js.Accessor<boolean>;
5
+
6
+ export { createrealView };
package/dist/solid.js ADDED
@@ -0,0 +1,20 @@
1
+ import {
2
+ realViewEngine
3
+ } from "./chunk-UW5FKFTH.js";
4
+
5
+ // src/solid.ts
6
+ import { createSignal, onCleanup, onMount } from "solid-js";
7
+ function createrealView(el, options) {
8
+ const [isVisible, setIsVisible] = createSignal(false);
9
+ onMount(() => {
10
+ const node = el();
11
+ if (node) {
12
+ const stop = realViewEngine.get().observe(node, setIsVisible, options);
13
+ onCleanup(stop);
14
+ }
15
+ });
16
+ return isVisible;
17
+ }
18
+ export {
19
+ createrealView
20
+ };
@@ -0,0 +1,146 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __export = (target, all) => {
6
+ for (var name in all)
7
+ __defProp(target, name, { get: all[name], enumerable: true });
8
+ };
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
+
19
+ // src/svelte.ts
20
+ var svelte_exports = {};
21
+ __export(svelte_exports, {
22
+ realView: () => realView
23
+ });
24
+ module.exports = __toCommonJS(svelte_exports);
25
+
26
+ // src/core/utils.ts
27
+ var isBrowser = () => {
28
+ return typeof window !== "undefined" && typeof window.document !== "undefined";
29
+ };
30
+
31
+ // src/core/engine.ts
32
+ var realViewEngine = class _realViewEngine {
33
+ constructor() {
34
+ this.observer = null;
35
+ this.watchers = /* @__PURE__ */ new Map();
36
+ if (!isBrowser()) return;
37
+ this.initObserver();
38
+ this.initTabListener();
39
+ }
40
+ static get() {
41
+ if (!this.instance) this.instance = new _realViewEngine();
42
+ return this.instance;
43
+ }
44
+ initObserver() {
45
+ this.observer = new IntersectionObserver(this.handleIntersect.bind(this), {
46
+ threshold: 0
47
+ });
48
+ }
49
+ initTabListener() {
50
+ document.addEventListener("visibilitychange", () => {
51
+ const isHidden = document.hidden;
52
+ this.watchers.forEach((w) => {
53
+ if (w.opts.trackTab && isHidden) {
54
+ this.notify(w, false);
55
+ } else if (w.state.inViewport && !isHidden) {
56
+ this.checkOcclusion(w);
57
+ }
58
+ });
59
+ });
60
+ }
61
+ handleIntersect(entries) {
62
+ entries.forEach((entry) => {
63
+ const watcher = this.watchers.get(entry.target);
64
+ if (!watcher) return;
65
+ watcher.state.inViewport = entry.isIntersecting;
66
+ if (entry.isIntersecting) {
67
+ this.startPolling(watcher);
68
+ } else {
69
+ this.stopPolling(watcher);
70
+ this.notify(watcher, false);
71
+ }
72
+ });
73
+ }
74
+ checkOcclusion(w) {
75
+ if (w.opts.trackTab && document.hidden) return this.notify(w, false);
76
+ const rect = w.el.getBoundingClientRect();
77
+ if (rect.width === 0 || rect.height === 0) return this.notify(w, false);
78
+ const style = window.getComputedStyle(w.el);
79
+ if (style.opacity === "0" || style.visibility === "hidden") return this.notify(w, false);
80
+ const x = rect.left + rect.width / 2;
81
+ const y = rect.top + rect.height / 2;
82
+ const topEl = document.elementFromPoint(x, y);
83
+ const isVisible = topEl ? w.el.contains(topEl) || w.el === topEl : false;
84
+ this.notify(w, isVisible);
85
+ }
86
+ startPolling(w) {
87
+ if (w.state.timer) return;
88
+ const tick = () => {
89
+ if ("requestIdleCallback" in window) {
90
+ window.requestIdleCallback(() => this.checkOcclusion(w));
91
+ } else {
92
+ this.checkOcclusion(w);
93
+ }
94
+ };
95
+ tick();
96
+ w.state.timer = window.setInterval(tick, w.opts.pollInterval);
97
+ }
98
+ stopPolling(w) {
99
+ if (w.state.timer) {
100
+ clearInterval(w.state.timer);
101
+ w.state.timer = null;
102
+ }
103
+ }
104
+ notify(w, isVisible) {
105
+ if (w.state.isOccluded !== !isVisible) {
106
+ w.state.isOccluded = !isVisible;
107
+ w.cb(isVisible);
108
+ }
109
+ }
110
+ observe(el, cb, options = {}) {
111
+ if (!isBrowser()) return () => {
112
+ };
113
+ const opts = {
114
+ threshold: 0,
115
+ pollInterval: 1e3,
116
+ trackTab: true,
117
+ ...options
118
+ };
119
+ this.watchers.set(el, {
120
+ el,
121
+ cb,
122
+ opts,
123
+ state: { inViewport: false, isOccluded: false, timer: null }
124
+ });
125
+ this.observer?.observe(el);
126
+ return () => {
127
+ this.stopPolling(this.watchers.get(el));
128
+ this.observer?.unobserve(el);
129
+ this.watchers.delete(el);
130
+ };
131
+ }
132
+ };
133
+
134
+ // src/svelte.ts
135
+ function realView(node, params) {
136
+ const stop = realViewEngine.get().observe(node, params.onVisible, params.options);
137
+ return {
138
+ destroy() {
139
+ stop();
140
+ }
141
+ };
142
+ }
143
+ // Annotate the CommonJS export names for ESM import in node:
144
+ 0 && (module.exports = {
145
+ realView
146
+ });
@@ -0,0 +1,11 @@
1
+ import { realViewOptions } from './index.cjs';
2
+
3
+ type Params = {
4
+ onVisible: (v: boolean) => void;
5
+ options?: realViewOptions;
6
+ };
7
+ declare function realView(node: HTMLElement, params: Params): {
8
+ destroy(): void;
9
+ };
10
+
11
+ export { realView };
@@ -0,0 +1,11 @@
1
+ import { realViewOptions } from './index.js';
2
+
3
+ type Params = {
4
+ onVisible: (v: boolean) => void;
5
+ options?: realViewOptions;
6
+ };
7
+ declare function realView(node: HTMLElement, params: Params): {
8
+ destroy(): void;
9
+ };
10
+
11
+ export { realView };
package/dist/svelte.js ADDED
@@ -0,0 +1,16 @@
1
+ import {
2
+ realViewEngine
3
+ } from "./chunk-UW5FKFTH.js";
4
+
5
+ // src/svelte.ts
6
+ function realView(node, params) {
7
+ const stop = realViewEngine.get().observe(node, params.onVisible, params.options);
8
+ return {
9
+ destroy() {
10
+ stop();
11
+ }
12
+ };
13
+ }
14
+ export {
15
+ realView
16
+ };