use-page-view 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +208 -0
- package/dist/__tests__/use-page-view.test.d.ts +1 -0
- package/dist/__tests__/use-page-view.test.js +182 -0
- package/dist/chunk-DyJZ69wI.js +1 -0
- package/dist/hooks/use-interval.d.ts +47 -0
- package/dist/hooks/use-interval.js +1 -0
- package/dist/hooks/use-page-view.d.ts +2 -0
- package/dist/hooks/use-page-view.js +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -0
- package/dist/magic-string.es-CwF9G552.js +10 -0
- package/dist/use-interval-OzNazv7J.js +1 -0
- package/dist/use-page-view-BY9Dsxki.js +1 -0
- package/dist/use-page-view-vAkJzz-K.d.ts +102 -0
- package/package.json +57 -0
@@ -0,0 +1 @@
|
|
1
|
+
var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports),s=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},c=(n,r,a)=>(a=n==null?{}:e(i(n)),s(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n)),l=(e=>typeof require<`u`?require:typeof Proxy<`u`?new Proxy(e,{get:(e,t)=>(typeof require<`u`?require:e)[t]}):e)(function(e){if(typeof require<`u`)return require.apply(this,arguments);throw Error('Calling `require` for "'+e+"\" in an environment that doesn't expose the `require` function.")});export{o as __commonJSMin,l as __require,c as __toESM};
|
@@ -0,0 +1,47 @@
|
|
1
|
+
import React from "react";
|
2
|
+
|
3
|
+
//#region src/hooks/use-interval.d.ts
|
4
|
+
|
5
|
+
/**
|
6
|
+
* A hook that creates an interval that can be paused and resumed
|
7
|
+
*
|
8
|
+
* @param callback - The function to call on each interval tick
|
9
|
+
* @param delay - The interval delay in milliseconds. Set to null to pause the interval
|
10
|
+
*
|
11
|
+
* @example
|
12
|
+
* ```tsx
|
13
|
+
* function Timer() {
|
14
|
+
* const [count, setCount] = React.useState(0);
|
15
|
+
*
|
16
|
+
* useInterval(() => {
|
17
|
+
* setCount(c => c + 1);
|
18
|
+
* }, 1000);
|
19
|
+
*
|
20
|
+
* return <div>Count: {count}</div>;
|
21
|
+
* }
|
22
|
+
* ```
|
23
|
+
*
|
24
|
+
* @example
|
25
|
+
* ```tsx
|
26
|
+
* function PausableTimer() {
|
27
|
+
* const [count, setCount] = React.useState(0);
|
28
|
+
* const [isPaused, setIsPaused] = React.useState(false);
|
29
|
+
*
|
30
|
+
* useInterval(() => {
|
31
|
+
* setCount(c => c + 1);
|
32
|
+
* }, isPaused ? null : 1000);
|
33
|
+
*
|
34
|
+
* return (
|
35
|
+
* <div>
|
36
|
+
* <div>Count: {count}</div>
|
37
|
+
* <button onClick={() => setIsPaused(p => !p)}>
|
38
|
+
* {isPaused ? 'Resume' : 'Pause'}
|
39
|
+
* </button>
|
40
|
+
* </div>
|
41
|
+
* );
|
42
|
+
* }
|
43
|
+
* ```
|
44
|
+
*/
|
45
|
+
declare function useInterval(callback: () => void, delay: number | null): React.RefObject<number | null>;
|
46
|
+
//#endregion
|
47
|
+
export { useInterval };
|
@@ -0,0 +1 @@
|
|
1
|
+
import{useInterval as e}from"../use-interval-OzNazv7J.js";export{e as useInterval};
|
@@ -0,0 +1 @@
|
|
1
|
+
import"../use-interval-OzNazv7J.js";import{usePageView as e}from"../use-page-view-BY9Dsxki.js";export{e as usePageView};
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
import"./use-interval-OzNazv7J.js";import{usePageView as e}from"./use-page-view-BY9Dsxki.js";export{e as usePageView};
|
@@ -0,0 +1,10 @@
|
|
1
|
+
import{__commonJSMin as e,__toESM as t}from"./chunk-DyJZ69wI.js";var n=e((exports,t)=>{(function(n,r){typeof exports==`object`&&t!==void 0?r(exports):typeof define==`function`&&define.amd?define([`exports`],r):(n=typeof globalThis<`u`?globalThis:n||self,r(n.sourcemapCodec={}))})(void 0,function(e){"use strict";let t=44,n=59,r=`ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/`,i=new Uint8Array(64),a=new Uint8Array(128);for(let e=0;e<r.length;e++){let t=r.charCodeAt(e);i[e]=t,a[t]=e}function o(e,t){let n=0,r=0,i=0;do{let t=e.next();i=a[t],n|=(i&31)<<r,r+=5}while(i&32);let o=n&1;return n>>>=1,o&&(n=-2147483648|-n),t+n}function s(e,t,n){let r=t-n;r=r<0?-r<<1|1:r<<1;do{let t=r&31;r>>>=5,r>0&&(t|=32),e.write(i[t])}while(r>0);return t}function c(e,n){return e.pos>=n?!1:e.peek()!==t}let l=1024*16,u=typeof TextDecoder<`u`?new TextDecoder:typeof Buffer<`u`?{decode(e){let t=Buffer.from(e.buffer,e.byteOffset,e.byteLength);return t.toString()}}:{decode(e){let t=``;for(let n=0;n<e.length;n++)t+=String.fromCharCode(e[n]);return t}};class d{constructor(){this.pos=0,this.out=``,this.buffer=new Uint8Array(l)}write(e){let{buffer:t}=this;t[this.pos++]=e,this.pos===l&&(this.out+=u.decode(t),this.pos=0)}flush(){let{buffer:e,out:t,pos:n}=this;return n>0?t+u.decode(e.subarray(0,n)):t}}class f{constructor(e){this.pos=0,this.buffer=e}next(){return this.buffer.charCodeAt(this.pos++)}peek(){return this.buffer.charCodeAt(this.pos)}indexOf(e){let{buffer:t,pos:n}=this,r=t.indexOf(e,n);return r===-1?t.length:r}}let p=[];function m(e){let{length:t}=e,n=new f(e),r=[],i=[],a=0;for(;n.pos<t;n.pos++){a=o(n,a);let e=o(n,0);if(!c(n,t)){let t=i.pop();t[2]=a,t[3]=e;continue}let s=o(n,0),l=o(n,0),u=l&1,d=u?[a,e,0,0,s,o(n,0)]:[a,e,0,0,s],f=p;if(c(n,t)){f=[];do{let e=o(n,0);f.push(e)}while(c(n,t))}d.vars=f,r.push(d),i.push(d)}return r}function h(e){let t=new d;for(let n=0;n<e.length;)n=g(e,n,t,[0]);return t.flush()}function g(e,n,r,i){let a=e[n],{0:o,1:c,2:l,3:u,4:d,vars:f}=a;n>0&&r.write(t),i[0]=s(r,o,i[0]),s(r,c,0),s(r,d,0);let p=a.length===6?1:0;s(r,p,0),a.length===6&&s(r,a[5],0);for(let e of f)s(r,e,0);for(n++;n<e.length;){let t=e[n],{0:a,1:o}=t;if(a>l||a===l&&o>=u)break;n=g(e,n,r,i)}return r.write(t),i[0]=s(r,l,i[0]),s(r,u,0),n}function _(e){let{length:t}=e,n=new f(e),r=[],i=[],a=0,s=0,l=0,u=0,d=0,m=0,h=0,g=0;do{let e=n.indexOf(`;`),t=0;for(;n.pos<e;n.pos++){if(t=o(n,t),!c(n,e)){let e=i.pop();e[2]=a,e[3]=t;continue}let f=o(n,0),_=f&1,v=f&2,y=f&4,b=null,x=p,S;if(_){let e=o(n,s);l=o(n,s===e?l:0),s=e,S=[a,t,0,0,e,l]}else S=[a,t,0,0];if(S.isScope=!!y,v){let e=u,t=d;u=o(n,u);let r=e===u;d=o(n,r?d:0),m=o(n,r&&t===d?m:0),b=[u,d,m]}if(S.callsite=b,c(n,e)){x=[];do{h=a,g=t;let e=o(n,0),r;if(e<-1){r=[[o(n,0)]];for(let t=-1;t>e;t--){let e=h;h=o(n,h),g=o(n,h===e?g:0);let t=o(n,0);r.push([t,h,g])}}else r=[[e]];x.push(r)}while(c(n,e))}S.bindings=x,r.push(S),i.push(S)}a++,n.pos=e+1}while(n.pos<t);return r}function v(e){if(e.length===0)return``;let t=new d;for(let n=0;n<e.length;)n=y(e,n,t,[0,0,0,0,0,0,0]);return t.flush()}function y(e,n,r,i){let a=e[n],{0:o,1:c,2:l,3:u,isScope:d,callsite:f,bindings:p}=a;i[0]<o?(b(r,i[0],o),i[0]=o,i[1]=0):n>0&&r.write(t),i[1]=s(r,a[1],i[1]);let m=(a.length===6?1:0)|(f?2:0)|(d?4:0);if(s(r,m,0),a.length===6){let{4:e,5:t}=a;e!==i[2]&&(i[3]=0),i[2]=s(r,e,i[2]),i[3]=s(r,t,i[3])}if(f){let{0:e,1:t,2:n}=a.callsite;e===i[4]?t!==i[5]&&(i[6]=0):(i[5]=0,i[6]=0),i[4]=s(r,e,i[4]),i[5]=s(r,t,i[5]),i[6]=s(r,n,i[6])}if(p)for(let e of p){e.length>1&&s(r,-e.length,0);let t=e[0][0];s(r,t,0);let n=o,i=c;for(let t=1;t<e.length;t++){let a=e[t];n=s(r,a[1],n),i=s(r,a[2],i),s(r,a[0],0)}}for(n++;n<e.length;){let t=e[n],{0:a,1:o}=t;if(a>l||a===l&&o>=u)break;n=y(e,n,r,i)}return i[0]<l?(b(r,i[0],l),i[0]=l,i[1]=0):r.write(t),i[1]=s(r,u,i[1]),n}function b(e,t,r){do e.write(n);while(++t<r)}function x(e){let{length:t}=e,n=new f(e),r=[],i=0,a=0,s=0,l=0,u=0;do{let e=n.indexOf(`;`),t=[],d=!0,f=0;for(i=0;n.pos<e;){let r;i=o(n,i),i<f&&(d=!1),f=i,c(n,e)?(a=o(n,a),s=o(n,s),l=o(n,l),c(n,e)?(u=o(n,u),r=[i,a,s,l,u]):r=[i,a,s,l]):r=[i],t.push(r),n.pos++}d||S(t),r.push(t),n.pos=e+1}while(n.pos<=t);return r}function S(e){e.sort(C)}function C(e,t){return e[0]-t[0]}function w(e){let r=new d,i=0,a=0,o=0,c=0;for(let l=0;l<e.length;l++){let u=e[l];if(l>0&&r.write(n),u.length===0)continue;let d=0;for(let e=0;e<u.length;e++){let n=u[e];e>0&&r.write(t),d=s(r,n[0],d),n.length!==1&&(i=s(r,n[1],i),a=s(r,n[2],a),o=s(r,n[3],o),n.length!==4&&(c=s(r,n[4],c)))}}return r.flush()}e.decode=x,e.decodeGeneratedRanges=_,e.decodeOriginalScopes=m,e.encode=w,e.encodeGeneratedRanges=v,e.encodeOriginalScopes=h,Object.defineProperty(e,`__esModule`,{value:!0})})}),r=t(n(),1),i=class e{constructor(t){this.bits=t instanceof e?t.bits.slice():[]}add(e){this.bits[e>>5]|=1<<(e&31)}has(e){return!!(this.bits[e>>5]&1<<(e&31))}},a=class e{constructor(e,t,n){this.start=e,this.end=t,this.original=n,this.intro=``,this.outro=``,this.content=n,this.storeName=!1,this.edited=!1,this.previous=null,this.next=null}appendLeft(e){this.outro+=e}appendRight(e){this.intro+=e}clone(){let t=new e(this.start,this.end,this.original);return t.intro=this.intro,t.outro=this.outro,t.content=this.content,t.storeName=this.storeName,t.edited=this.edited,t}contains(e){return this.start<e&&e<this.end}eachNext(e){let t=this;for(;t;)e(t),t=t.next}eachPrevious(e){let t=this;for(;t;)e(t),t=t.previous}edit(e,t,n){return this.content=e,n||(this.intro=``,this.outro=``),this.storeName=t,this.edited=!0,this}prependLeft(e){this.outro=e+this.outro}prependRight(e){this.intro=e+this.intro}reset(){this.intro=``,this.outro=``,this.edited&&(this.content=this.original,this.storeName=!1,this.edited=!1)}split(t){let n=t-this.start,r=this.original.slice(0,n),i=this.original.slice(n);this.original=r;let a=new e(t,this.end,i);return a.outro=this.outro,this.outro=``,this.end=t,this.edited?(a.edit(``,!1),this.content=``):this.content=r,a.next=this.next,a.next&&(a.next.previous=a),a.previous=this,this.next=a,a}toString(){return this.intro+this.content+this.outro}trimEnd(e){if(this.outro=this.outro.replace(e,``),this.outro.length)return!0;let t=this.content.replace(e,``);if(t.length)return t!==this.content&&(this.split(this.start+t.length).edit(``,void 0,!0),this.edited&&this.edit(t,this.storeName,!0)),!0;if(this.edit(``,void 0,!0),this.intro=this.intro.replace(e,``),this.intro.length)return!0}trimStart(e){if(this.intro=this.intro.replace(e,``),this.intro.length)return!0;let t=this.content.replace(e,``);if(t.length){if(t!==this.content){let e=this.split(this.end-t.length);this.edited&&e.edit(t,this.storeName,!0),this.edit(``,void 0,!0)}return!0}else if(this.edit(``,void 0,!0),this.outro=this.outro.replace(e,``),this.outro.length)return!0}};function o(){return typeof globalThis<`u`&&typeof globalThis.btoa==`function`?e=>globalThis.btoa(unescape(encodeURIComponent(e))):typeof Buffer==`function`?e=>Buffer.from(e,`utf-8`).toString(`base64`):()=>{throw Error("Unsupported environment: `window.btoa` or `Buffer` should be supported.")}}const s=o();var c=class{constructor(e){this.version=3,this.file=e.file,this.sources=e.sources,this.sourcesContent=e.sourcesContent,this.names=e.names,this.mappings=(0,r.encode)(e.mappings),e.x_google_ignoreList!==void 0&&(this.x_google_ignoreList=e.x_google_ignoreList),e.debugId!==void 0&&(this.debugId=e.debugId)}toString(){return JSON.stringify(this)}toUrl(){return`data:application/json;charset=utf-8;base64,`+s(this.toString())}};function l(e){let t=e.split(`
|
2
|
+
`),n=t.filter(e=>/^\t+/.test(e)),r=t.filter(e=>/^ {2,}/.test(e));if(n.length===0&&r.length===0)return null;if(n.length>=r.length)return` `;let i=r.reduce((e,t)=>{let n=/^ +/.exec(t)[0].length;return Math.min(n,e)},1/0);return Array(i+1).join(` `)}function u(e,t){let n=e.split(/[/\\]/),r=t.split(/[/\\]/);for(n.pop();n[0]===r[0];)n.shift(),r.shift();if(n.length){let e=n.length;for(;e--;)n[e]=`..`}return n.concat(r).join(`/`)}const d=Object.prototype.toString;function f(e){return d.call(e)===`[object Object]`}function p(e){let t=e.split(`
|
3
|
+
`),n=[];for(let e=0,r=0;e<t.length;e++)n.push(r),r+=t[e].length+1;return function(e){let t=0,r=n.length;for(;t<r;){let i=t+r>>1;e<n[i]?r=i:t=i+1}let i=t-1,a=e-n[i];return{line:i,column:a}}}const m=/\w/;var h=class{constructor(e){this.hires=e,this.generatedCodeLine=0,this.generatedCodeColumn=0,this.raw=[],this.rawSegments=this.raw[this.generatedCodeLine]=[],this.pending=null}addEdit(e,t,n,r){if(t.length){let i=t.length-1,a=t.indexOf(`
|
4
|
+
`,0),o=-1;for(;a>=0&&i>a;){let i=[this.generatedCodeColumn,e,n.line,n.column];r>=0&&i.push(r),this.rawSegments.push(i),this.generatedCodeLine+=1,this.raw[this.generatedCodeLine]=this.rawSegments=[],this.generatedCodeColumn=0,o=a,a=t.indexOf(`
|
5
|
+
`,a+1)}let s=[this.generatedCodeColumn,e,n.line,n.column];r>=0&&s.push(r),this.rawSegments.push(s),this.advance(t.slice(o+1))}else this.pending&&(this.rawSegments.push(this.pending),this.advance(t));this.pending=null}addUneditedChunk(e,t,n,r,i){let a=t.start,o=!0,s=!1;for(;a<t.end;){if(n[a]===`
|
6
|
+
`)r.line+=1,r.column=0,this.generatedCodeLine+=1,this.raw[this.generatedCodeLine]=this.rawSegments=[],this.generatedCodeColumn=0,o=!0,s=!1;else{if(this.hires||o||i.has(a)){let t=[this.generatedCodeColumn,e,r.line,r.column];this.hires===`boundary`?m.test(n[a])?s||(this.rawSegments.push(t),s=!0):(this.rawSegments.push(t),s=!1):this.rawSegments.push(t)}r.column+=1,this.generatedCodeColumn+=1,o=!1}a+=1}this.pending=null}advance(e){if(!e)return;let t=e.split(`
|
7
|
+
`);if(t.length>1){for(let e=0;e<t.length-1;e++)this.generatedCodeLine++,this.raw[this.generatedCodeLine]=this.rawSegments=[];this.generatedCodeColumn=0}this.generatedCodeColumn+=t[t.length-1].length}};const g=`
|
8
|
+
`,_={insertLeft:!1,insertRight:!1,storeName:!1};var v=class e{constructor(e,t={}){let n=new a(0,e.length,e);Object.defineProperties(this,{original:{writable:!0,value:e},outro:{writable:!0,value:``},intro:{writable:!0,value:``},firstChunk:{writable:!0,value:n},lastChunk:{writable:!0,value:n},lastSearchedChunk:{writable:!0,value:n},byStart:{writable:!0,value:{}},byEnd:{writable:!0,value:{}},filename:{writable:!0,value:t.filename},indentExclusionRanges:{writable:!0,value:t.indentExclusionRanges},sourcemapLocations:{writable:!0,value:new i},storedNames:{writable:!0,value:{}},indentStr:{writable:!0,value:void 0},ignoreList:{writable:!0,value:t.ignoreList},offset:{writable:!0,value:t.offset||0}}),this.byStart[0]=n,this.byEnd[e.length]=n}addSourcemapLocation(e){this.sourcemapLocations.add(e)}append(e){if(typeof e!=`string`)throw TypeError(`outro content must be a string`);return this.outro+=e,this}appendLeft(e,t){if(e+=this.offset,typeof t!=`string`)throw TypeError(`inserted content must be a string`);this._split(e);let n=this.byEnd[e];return n?n.appendLeft(t):this.intro+=t,this}appendRight(e,t){if(e+=this.offset,typeof t!=`string`)throw TypeError(`inserted content must be a string`);this._split(e);let n=this.byStart[e];return n?n.appendRight(t):this.outro+=t,this}clone(){let t=new e(this.original,{filename:this.filename,offset:this.offset}),n=this.firstChunk,r=t.firstChunk=t.lastSearchedChunk=n.clone();for(;n;){t.byStart[r.start]=r,t.byEnd[r.end]=r;let e=n.next,i=e&&e.clone();i&&(r.next=i,i.previous=r,r=i),n=e}return t.lastChunk=r,this.indentExclusionRanges&&(t.indentExclusionRanges=this.indentExclusionRanges.slice()),t.sourcemapLocations=new i(this.sourcemapLocations),t.intro=this.intro,t.outro=this.outro,t}generateDecodedMap(e){e||={};let t=0,n=Object.keys(this.storedNames),r=new h(e.hires),i=p(this.original);return this.intro&&r.advance(this.intro),this.firstChunk.eachNext(e=>{let a=i(e.start);e.intro.length&&r.advance(e.intro),e.edited?r.addEdit(t,e.content,a,e.storeName?n.indexOf(e.original):-1):r.addUneditedChunk(t,e,this.original,a,this.sourcemapLocations),e.outro.length&&r.advance(e.outro)}),{file:e.file?e.file.split(/[/\\]/).pop():void 0,sources:[e.source?u(e.file||``,e.source):e.file||``],sourcesContent:e.includeContent?[this.original]:void 0,names:n,mappings:r.raw,x_google_ignoreList:this.ignoreList?[t]:void 0}}generateMap(e){return new c(this.generateDecodedMap(e))}_ensureindentStr(){this.indentStr===void 0&&(this.indentStr=l(this.original))}_getRawIndentString(){return this._ensureindentStr(),this.indentStr}getIndentString(){return this._ensureindentStr(),this.indentStr===null?` `:this.indentStr}indent(e,t){let n=/^[^\r\n]/gm;if(f(e)&&(t=e,e=void 0),e===void 0&&(this._ensureindentStr(),e=this.indentStr||` `),e===``)return this;t||={};let r={};if(t.exclude){let e=typeof t.exclude[0]==`number`?[t.exclude]:t.exclude;e.forEach(e=>{for(let t=e[0];t<e[1];t+=1)r[t]=!0})}let i=t.indentStart!==!1,a=t=>i?`${e}${t}`:(i=!0,t);this.intro=this.intro.replace(n,a);let o=0,s=this.firstChunk;for(;s;){let t=s.end;if(s.edited)r[o]||(s.content=s.content.replace(n,a),s.content.length&&(i=s.content[s.content.length-1]===`
|
9
|
+
`));else for(o=s.start;o<t;){if(!r[o]){let t=this.original[o];t===`
|
10
|
+
`?i=!0:t!==`\r`&&i&&(i=!1,o===s.start?s.prependRight(e):(this._splitChunk(s,o),s=s.next,s.prependRight(e)))}o+=1}o=s.end,s=s.next}return this.outro=this.outro.replace(n,a),this}insert(){throw Error(`magicString.insert(...) is deprecated. Use prependRight(...) or appendLeft(...)`)}insertLeft(e,t){return _.insertLeft||(console.warn(`magicString.insertLeft(...) is deprecated. Use magicString.appendLeft(...) instead`),_.insertLeft=!0),this.appendLeft(e,t)}insertRight(e,t){return _.insertRight||(console.warn(`magicString.insertRight(...) is deprecated. Use magicString.prependRight(...) instead`),_.insertRight=!0),this.prependRight(e,t)}move(e,t,n){if(e+=this.offset,t+=this.offset,n+=this.offset,n>=e&&n<=t)throw Error(`Cannot move a selection inside itself`);this._split(e),this._split(t),this._split(n);let r=this.byStart[e],i=this.byEnd[t],a=r.previous,o=i.next,s=this.byStart[n];if(!s&&i===this.lastChunk)return this;let c=s?s.previous:this.lastChunk;return a&&(a.next=o),o&&(o.previous=a),c&&(c.next=r),s&&(s.previous=i),r.previous||(this.firstChunk=i.next),i.next||(this.lastChunk=r.previous,this.lastChunk.next=null),r.previous=c,i.next=s||null,c||(this.firstChunk=r),s||(this.lastChunk=i),this}overwrite(e,t,n,r){return r||={},this.update(e,t,n,{...r,overwrite:!r.contentOnly})}update(e,t,n,r){if(e+=this.offset,t+=this.offset,typeof n!=`string`)throw TypeError(`replacement content must be a string`);if(this.original.length!==0){for(;e<0;)e+=this.original.length;for(;t<0;)t+=this.original.length}if(t>this.original.length)throw Error(`end is out of bounds`);if(e===t)throw Error(`Cannot overwrite a zero-length range – use appendLeft or prependRight instead`);this._split(e),this._split(t),r===!0&&(_.storeName||(console.warn(`The final argument to magicString.overwrite(...) should be an options object. See https://github.com/rich-harris/magic-string`),_.storeName=!0),r={storeName:!0});let i=r===void 0?!1:r.storeName,o=r===void 0?!1:r.overwrite;if(i){let n=this.original.slice(e,t);Object.defineProperty(this.storedNames,n,{writable:!0,value:!0,enumerable:!0})}let s=this.byStart[e],c=this.byEnd[t];if(s){let e=s;for(;e!==c;){if(e.next!==this.byStart[e.end])throw Error(`Cannot overwrite across a split point`);e=e.next,e.edit(``,!1)}s.edit(n,i,!o)}else{let r=new a(e,t,``).edit(n,i);c.next=r,r.previous=c}return this}prepend(e){if(typeof e!=`string`)throw TypeError(`outro content must be a string`);return this.intro=e+this.intro,this}prependLeft(e,t){if(e+=this.offset,typeof t!=`string`)throw TypeError(`inserted content must be a string`);this._split(e);let n=this.byEnd[e];return n?n.prependLeft(t):this.intro=t+this.intro,this}prependRight(e,t){if(e+=this.offset,typeof t!=`string`)throw TypeError(`inserted content must be a string`);this._split(e);let n=this.byStart[e];return n?n.prependRight(t):this.outro=t+this.outro,this}remove(e,t){if(e+=this.offset,t+=this.offset,this.original.length!==0){for(;e<0;)e+=this.original.length;for(;t<0;)t+=this.original.length}if(e===t)return this;if(e<0||t>this.original.length)throw Error(`Character is out of bounds`);if(e>t)throw Error(`end must be greater than start`);this._split(e),this._split(t);let n=this.byStart[e];for(;n;)n.intro=``,n.outro=``,n.edit(``),n=t>n.end?this.byStart[n.end]:null;return this}reset(e,t){if(e+=this.offset,t+=this.offset,this.original.length!==0){for(;e<0;)e+=this.original.length;for(;t<0;)t+=this.original.length}if(e===t)return this;if(e<0||t>this.original.length)throw Error(`Character is out of bounds`);if(e>t)throw Error(`end must be greater than start`);this._split(e),this._split(t);let n=this.byStart[e];for(;n;)n.reset(),n=t>n.end?this.byStart[n.end]:null;return this}lastChar(){if(this.outro.length)return this.outro[this.outro.length-1];let e=this.lastChunk;do{if(e.outro.length)return e.outro[e.outro.length-1];if(e.content.length)return e.content[e.content.length-1];if(e.intro.length)return e.intro[e.intro.length-1]}while(e=e.previous);return this.intro.length?this.intro[this.intro.length-1]:``}lastLine(){let e=this.outro.lastIndexOf(g);if(e!==-1)return this.outro.substr(e+1);let t=this.outro,n=this.lastChunk;do{if(n.outro.length>0){if(e=n.outro.lastIndexOf(g),e!==-1)return n.outro.substr(e+1)+t;t=n.outro+t}if(n.content.length>0){if(e=n.content.lastIndexOf(g),e!==-1)return n.content.substr(e+1)+t;t=n.content+t}if(n.intro.length>0){if(e=n.intro.lastIndexOf(g),e!==-1)return n.intro.substr(e+1)+t;t=n.intro+t}}while(n=n.previous);return e=this.intro.lastIndexOf(g),e===-1?this.intro+t:this.intro.substr(e+1)+t}slice(e=0,t=this.original.length-this.offset){if(e+=this.offset,t+=this.offset,this.original.length!==0){for(;e<0;)e+=this.original.length;for(;t<0;)t+=this.original.length}let n=``,r=this.firstChunk;for(;r&&(r.start>e||r.end<=e);){if(r.start<t&&r.end>=t)return n;r=r.next}if(r&&r.edited&&r.start!==e)throw Error(`Cannot use replaced character ${e} as slice start anchor.`);let i=r;for(;r;){r.intro&&(i!==r||r.start===e)&&(n+=r.intro);let a=r.start<t&&r.end>=t;if(a&&r.edited&&r.end!==t)throw Error(`Cannot use replaced character ${t} as slice end anchor.`);let o=i===r?e-r.start:0,s=a?r.content.length+t-r.end:r.content.length;if(n+=r.content.slice(o,s),r.outro&&(!a||r.end===t)&&(n+=r.outro),a)break;r=r.next}return n}snip(e,t){let n=this.clone();return n.remove(0,e),n.remove(t,n.original.length),n}_split(e){if(this.byStart[e]||this.byEnd[e])return;let t=this.lastSearchedChunk,n=e>t.end;for(;t;){if(t.contains(e))return this._splitChunk(t,e);t=n?this.byStart[t.end]:this.byEnd[t.start]}}_splitChunk(e,t){if(e.edited&&e.content.length){let n=p(this.original)(t);throw Error(`Cannot split a chunk that has already been edited (${n.line}:${n.column} – "${e.original}")`)}let n=e.split(t);return this.byEnd[t]=e,this.byStart[t]=n,this.byEnd[n.end]=n,e===this.lastChunk&&(this.lastChunk=n),this.lastSearchedChunk=e,!0}toString(){let e=this.intro,t=this.firstChunk;for(;t;)e+=t.toString(),t=t.next;return e+this.outro}isEmpty(){let e=this.firstChunk;do if(e.intro.length&&e.intro.trim()||e.content.length&&e.content.trim()||e.outro.length&&e.outro.trim())return!1;while(e=e.next);return!0}length(){let e=this.firstChunk,t=0;do t+=e.intro.length+e.content.length+e.outro.length;while(e=e.next);return t}trimLines(){return this.trim(`[\\r\\n]`)}trim(e){return this.trimStart(e).trimEnd(e)}trimEndAborted(e){let t=RegExp((e||`\\s`)+`+$`);if(this.outro=this.outro.replace(t,``),this.outro.length)return!0;let n=this.lastChunk;do{let e=n.end,r=n.trimEnd(t);if(n.end!==e&&(this.lastChunk===n&&(this.lastChunk=n.next),this.byEnd[n.end]=n,this.byStart[n.next.start]=n.next,this.byEnd[n.next.end]=n.next),r)return!0;n=n.previous}while(n);return!1}trimEnd(e){return this.trimEndAborted(e),this}trimStartAborted(e){let t=RegExp(`^`+(e||`\\s`)+`+`);if(this.intro=this.intro.replace(t,``),this.intro.length)return!0;let n=this.firstChunk;do{let e=n.end,r=n.trimStart(t);if(n.end!==e&&(n===this.lastChunk&&(this.lastChunk=n.next),this.byEnd[n.end]=n,this.byStart[n.next.start]=n.next,this.byEnd[n.next.end]=n.next),r)return!0;n=n.next}while(n);return!1}trimStart(e){return this.trimStartAborted(e),this}hasChanged(){return this.original!==this.toString()}_replaceRegexp(e,t){function n(e,n){return typeof t==`string`?t.replace(/\$(\$|&|\d+)/g,(t,n)=>{if(n===`$`)return`$`;if(n===`&`)return e[0];let r=+n;return r<e.length?e[+n]:`$${n}`}):t(...e,e.index,n,e.groups)}function r(e,t){let n,r=[];for(;n=e.exec(t);)r.push(n);return r}if(e.global){let t=r(e,this.original);t.forEach(e=>{if(e.index!=null){let t=n(e,this.original);t!==e[0]&&this.overwrite(e.index,e.index+e[0].length,t)}})}else{let t=this.original.match(e);if(t&&t.index!=null){let e=n(t,this.original);e!==t[0]&&this.overwrite(t.index,t.index+t[0].length,e)}}return this}_replaceString(e,t){let{original:n}=this,r=n.indexOf(e);return r!==-1&&this.overwrite(r,r+e.length,t),this}replace(e,t){return typeof e==`string`?this._replaceString(e,t):this._replaceRegexp(e,t)}_replaceAllString(e,t){let{original:n}=this,r=e.length;for(let i=n.indexOf(e);i!==-1;i=n.indexOf(e,i+r)){let e=n.slice(i,i+r);e!==t&&this.overwrite(i,i+r,t)}return this}replaceAll(e,t){if(typeof e==`string`)return this._replaceAllString(e,t);if(!e.global)throw TypeError(`MagicString.prototype.replaceAll called with a non-global RegExp argument`);return this._replaceRegexp(e,t)}};export{v as default};
|
@@ -0,0 +1 @@
|
|
1
|
+
import e from"react";function t(t,n){let r=e.useRef(null),i=e.useRef(t);return e.useEffect(()=>{i.current=t},[t]),e.useEffect(()=>{let e=()=>i.current();if(typeof n==`number`)return r.current=window.setInterval(e,n),()=>window.clearInterval(r.current)},[n]),r}export{t as useInterval};
|
@@ -0,0 +1 @@
|
|
1
|
+
import{useInterval as e}from"./use-interval-OzNazv7J.js";import*as t from"react";function n({pageId:n,userId:r,minTimeThreshold:i=5,heartbeatInterval:a=30,inactivityThreshold:o=30,onPageView:s,trackOnce:c=!1,trackOnceDelay:l=0}){let[u,d]=t.useState(0),[f,p]=t.useState(!0),m=t.useRef(0),h=t.useRef(0),g=t.useRef(s),_=t.useRef(!1);return t.useEffect(()=>{m.current=Date.now(),h.current=Date.now()},[]),t.useEffect(()=>{g.current=s},[s]),t.useEffect(()=>{if(c&&!_.current&&g.current&&m.current>0)if(l>0){let e=setTimeout(()=>{_.current||(_.current=!0,g.current?.({pageId:n,userId:r,timeSpent:l,isActive:!0}))},l*1e3);return()=>clearTimeout(e)}else _.current=!0,g.current({pageId:n,userId:r,timeSpent:0,isActive:!0})},[c,n,r,l]),t.useEffect(()=>{let e=()=>{document.hidden?p(!1):(p(!0),h.current=Date.now())},t=()=>{h.current=Date.now(),p(!0)};document.addEventListener(`visibilitychange`,e);let n=[`mousedown`,`mousemove`,`keypress`,`scroll`,`touchstart`,`click`];return n.forEach(e=>{document.addEventListener(e,t,{passive:!0})}),()=>{document.removeEventListener(`visibilitychange`,e),n.forEach(e=>{document.removeEventListener(e,t)})}},[]),e(()=>{if(m.current===0)return;let e=Date.now(),t=Math.floor((e-m.current)/1e3),n=e-h.current,r=n<o*1e3;d(t),p(r)},1e3),e(()=>{!c&&u>=i&&g.current&&m.current>0&&g.current({pageId:n,userId:r,timeSpent:u,isActive:f})},a*1e3),t.useEffect(()=>{let e=m.current;return()=>{if(!c&&e>0){let t=Math.floor((Date.now()-e)/1e3);t>=i&&g.current&&g.current({pageId:n,userId:r,timeSpent:t,isActive:!1})}}},[n,r,i,c]),{timeSpent:u,isActive:f}}export{n as usePageView};
|
@@ -0,0 +1,102 @@
|
|
1
|
+
//#region src/hooks/use-page-view.d.ts
|
2
|
+
/**
|
3
|
+
* Data structure for page view tracking
|
4
|
+
*/
|
5
|
+
interface PageViewData {
|
6
|
+
pageId: string;
|
7
|
+
userId?: string;
|
8
|
+
timeSpent: number;
|
9
|
+
isActive: boolean;
|
10
|
+
}
|
11
|
+
/**
|
12
|
+
* Configuration options for the page view tracker
|
13
|
+
*/
|
14
|
+
interface UsePageViewOptions {
|
15
|
+
/** Unique identifier for the page being tracked */
|
16
|
+
pageId: string;
|
17
|
+
/** Optional user identifier if user is logged in */
|
18
|
+
userId?: string;
|
19
|
+
/** Minimum time in seconds before recording a view (default: 5) */
|
20
|
+
minTimeThreshold?: number;
|
21
|
+
/** How often to send updates in seconds (default: 30) */
|
22
|
+
heartbeatInterval?: number;
|
23
|
+
/** Time in seconds before user is considered inactive (default: 30) */
|
24
|
+
inactivityThreshold?: number;
|
25
|
+
/** Callback function to handle page view data */
|
26
|
+
onPageView?: (data: PageViewData) => void;
|
27
|
+
/** Track only the initial view (default: false) */
|
28
|
+
trackOnce?: boolean;
|
29
|
+
/** Minimum time in seconds before recording a view when trackOnce is true (default: 0) */
|
30
|
+
trackOnceDelay?: number;
|
31
|
+
}
|
32
|
+
/**
|
33
|
+
* A React hook to track page views and user engagement time. It monitors user activity,
|
34
|
+
* page visibility, and time spent on the page, providing real-time updates through
|
35
|
+
* a callback function.
|
36
|
+
*
|
37
|
+
* @param options - Configuration options for the page view tracker
|
38
|
+
* @param options.pageId - Unique identifier for the page being tracked
|
39
|
+
* @param options.userId - Optional user identifier if user is logged in
|
40
|
+
* @param options.minTimeThreshold - Minimum time in seconds before recording a view (default: 5)
|
41
|
+
* @param options.heartbeatInterval - How often to send updates in seconds (default: 30)
|
42
|
+
* @param options.inactivityThreshold - Time in seconds before user is considered inactive (default: 30)
|
43
|
+
* @param options.onPageView - Callback function to handle page view data
|
44
|
+
* @param options.trackOnce - Track only the initial view (default: false)
|
45
|
+
* @param options.trackOnceDelay - Minimum time in seconds before recording a view when trackOnce is true (default: 0)
|
46
|
+
*
|
47
|
+
* @returns An object containing:
|
48
|
+
* - timeSpent: number - Total time spent on the page in seconds
|
49
|
+
* - isActive: boolean - Whether the user is currently active on the page
|
50
|
+
*
|
51
|
+
* @example
|
52
|
+
* ```tsx
|
53
|
+
* // Example of a time formatting function
|
54
|
+
* function formatTime(seconds: number): string {
|
55
|
+
* const mins = Math.floor(seconds / 60);
|
56
|
+
* const secs = seconds % 60;
|
57
|
+
* return `${mins}:${secs.toString().padStart(2, '0')}`;
|
58
|
+
* }
|
59
|
+
*
|
60
|
+
* const handlePageView = React.useCallback(async (data: PageViewData) => {
|
61
|
+
* await fetch('/api/track-page-view', {
|
62
|
+
* method: 'POST',
|
63
|
+
* body: JSON.stringify(data)
|
64
|
+
* });
|
65
|
+
* }, []);
|
66
|
+
*
|
67
|
+
* function BlogPost() {
|
68
|
+
* const { timeSpent, isActive } = usePageView({
|
69
|
+
* pageId: 'blog-post-123',
|
70
|
+
* userId: 'user-456',
|
71
|
+
* minTimeThreshold: 10,
|
72
|
+
* heartbeatInterval: 30,
|
73
|
+
* inactivityThreshold: 60, // User considered inactive after 60 seconds
|
74
|
+
* onPageView: handlePageView
|
75
|
+
* });
|
76
|
+
*
|
77
|
+
* return (
|
78
|
+
* <div>
|
79
|
+
* <div>
|
80
|
+
* Time: {formatTime(timeSpent)} {isActive ? '🟢' : '🔴'}
|
81
|
+
* </div>
|
82
|
+
* <article>Your content here...</article>
|
83
|
+
* </div>
|
84
|
+
* );
|
85
|
+
* }
|
86
|
+
* ```
|
87
|
+
*/
|
88
|
+
declare function usePageView({
|
89
|
+
pageId,
|
90
|
+
userId,
|
91
|
+
minTimeThreshold,
|
92
|
+
heartbeatInterval,
|
93
|
+
inactivityThreshold,
|
94
|
+
onPageView,
|
95
|
+
trackOnce,
|
96
|
+
trackOnceDelay
|
97
|
+
}: UsePageViewOptions): {
|
98
|
+
timeSpent: number;
|
99
|
+
isActive: boolean;
|
100
|
+
};
|
101
|
+
//#endregion
|
102
|
+
export { PageViewData, usePageView };
|
package/package.json
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
{
|
2
|
+
"name": "use-page-view",
|
3
|
+
"version": "0.0.1",
|
4
|
+
"description": "React hook for tracking page views",
|
5
|
+
"type": "module",
|
6
|
+
"main": "dist/index.js",
|
7
|
+
"files": [
|
8
|
+
"dist"
|
9
|
+
],
|
10
|
+
"keywords": [
|
11
|
+
"react",
|
12
|
+
"page-view",
|
13
|
+
"typescript"
|
14
|
+
],
|
15
|
+
"author": "Christopher S. Aondona <me@codingsimba.com> (https://codingsimba.com)",
|
16
|
+
"repository": {
|
17
|
+
"type": "git",
|
18
|
+
"url": "git+https://github.com/christophersesugh/use-page-view.git"
|
19
|
+
},
|
20
|
+
"homepage": "https://github.com/christophersesugh/use-page-view",
|
21
|
+
"bugs": {
|
22
|
+
"url": "https://github.com/christophersesugh/use-page-view/issues"
|
23
|
+
},
|
24
|
+
"scripts": {
|
25
|
+
"build": "tsdown",
|
26
|
+
"test": "vitest",
|
27
|
+
"lint": "tsc",
|
28
|
+
"format": "prettier --write .",
|
29
|
+
"format:check": "prettier . --check",
|
30
|
+
"exports:check": "attw --pack . --ignore-rules=cjs-resolves-to-esm",
|
31
|
+
"release:local": "changeset version && changeset publish",
|
32
|
+
"prepublishOnly": "npm run ci",
|
33
|
+
"test:browser": "vitest run",
|
34
|
+
"ci": "npm run build && npm run format:check && npm run lint"
|
35
|
+
},
|
36
|
+
"license": "MIT",
|
37
|
+
"dependencies": {
|
38
|
+
"react": "^19.1.0",
|
39
|
+
"react-dom": "^19.1.0"
|
40
|
+
},
|
41
|
+
"devDependencies": {
|
42
|
+
"@arethetypeswrong/cli": "^0.18.1",
|
43
|
+
"@changesets/cli": "^2.29.4",
|
44
|
+
"@testing-library/react": "^14.0.0",
|
45
|
+
"@testing-library/react-hooks": "^8.0.1",
|
46
|
+
"@types/react": "^19.1.6",
|
47
|
+
"@types/react-dom": "^19.1.0",
|
48
|
+
"@vitejs/plugin-react": "^4.5.1",
|
49
|
+
"@vitest/browser": "^3.2.0",
|
50
|
+
"playwright": "^1.52.0",
|
51
|
+
"prettier": "^3.5.3",
|
52
|
+
"tsdown": "^0.12.6",
|
53
|
+
"typescript": "^5.8.3",
|
54
|
+
"vitest": "^3.2.0",
|
55
|
+
"vitest-browser-react": "^0.2.0"
|
56
|
+
}
|
57
|
+
}
|