@imrankhanjoya/visit-analytics 1.0.0 → 1.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/README.md ADDED
@@ -0,0 +1,119 @@
1
+ # @imrankhanjoya/visit-analytics
2
+
3
+ Simple MongoDB and Mongoose-based visit analytics package for Next.js and Node.js applications.
4
+
5
+ Track page visits, profile visits, post visits, unique visitors, and retrieve visitor details with minimal setup.
6
+
7
+ ## Installation
8
+
9
+ bash npm install @imrankhanjoya/visit-analytics
10
+
11
+ or
12
+
13
+ bash pnpm add @imrankhanjoya/visit-analytics
14
+
15
+ ## Prerequisites
16
+
17
+ Install Mongoose and connect to MongoDB before using this package.
18
+
19
+ bash npm install mongoose
20
+
21
+ javascript import mongoose from "mongoose"; await mongoose.connect(process.env.MONGODB_URI);
22
+
23
+ ---
24
+
25
+ # Exports
26
+
27
+ The package exports:
28
+
29
+ javascript import { Visit, saveVisit, getVisits, getVisitMembers, } from "@imrankhanjoya/visit-analytics";
30
+
31
+ ## Visit Model
32
+
33
+ A ready-to-use Mongoose model.
34
+
35
+ javascript import { Visit } from "@imrankhanjoya/visit-analytics"; const visits = await Visit.find();
36
+
37
+ ---
38
+
39
+ ## saveVisit()
40
+
41
+ Create or record a visit.
42
+
43
+ ### Example
44
+
45
+ javascript import { saveVisit } from "@imrankhanjoya/visit-analytics"; await saveVisit({ path: "john-doe", type: "profile", token: "visitor-token", ip: "127.0.0.1", userinfo: [ { username: "imran", image: "https://example.com/profile.jpg", }, ], });
46
+
47
+ ### Parameters
48
+
49
+ | Property | Type | Required |
50
+ |----------|------|----------|
51
+ | path | string | Yes |
52
+ | type | string | Yes |
53
+ | token | string | Yes |
54
+ | ip | string | No |
55
+ | userinfo | array | No |
56
+
57
+ ---
58
+
59
+ ## getVisits()
60
+
61
+ Returns total visits for a path.
62
+
63
+ ### Example
64
+
65
+ javascript import { getVisits } from "@imrankhanjoya/visit-analytics"; const totalVisits = await getVisits( "john-doe", "profile" ); console.log(totalVisits);
66
+
67
+ ### Response
68
+
69
+ javascript 25
70
+
71
+ ---
72
+
73
+ ## getVisitMembers()
74
+
75
+ Returns visitor records for a path.
76
+
77
+ ### Example
78
+
79
+ javascript import { getVisitMembers } from "@imrankhanjoya/visit-analytics"; const visitors = await getVisitMembers( "john-doe", "profile" ); console.log(visitors);
80
+
81
+ ### Example Response
82
+
83
+ javascript [ { token: "abc123", path: "john-doe", type: "profile", ip: "127.0.0.1", userinfo: [ { username: "imran" } ] } ]
84
+
85
+ ---
86
+
87
+ # Next.js Example
88
+
89
+ ## Record Visit
90
+
91
+ javascript import { saveVisit } from "@imrankhanjoya/visit-analytics"; export async function POST(request) { const body = await request.json(); await saveVisit({ path: body.path, type: body.type, token: body.token, ip: body.ip, }); return Response.json({ success: true, }); }
92
+
93
+ ## Get Visit Count
94
+
95
+ javascript import { getVisits } from "@imrankhanjoya/visit-analytics"; const count = await getVisits( "john-doe", "profile" );
96
+
97
+ ---
98
+
99
+ # Supported Types
100
+
101
+ javascript "profile" "post" "page" "custom"
102
+
103
+ ---
104
+
105
+ # Visit Document Structure
106
+
107
+ javascript { token: "visitor-token", path: "john-doe", type: "profile", ip: "127.0.0.1", date: "2026-06-05", userinfo: [], createdAt: Date, updatedAt: Date }
108
+
109
+ ---
110
+
111
+ # License
112
+
113
+ MIT
114
+
115
+ # Author
116
+
117
+ Imran Khan
118
+
119
+ Package: @imrankhanjoya/visit-analytics
package/package.json CHANGED
@@ -1,13 +1,16 @@
1
1
  {
2
2
  "name": "@imrankhanjoya/visit-analytics",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "",
5
- "main": "index.js",
5
+ "main": "./src/index.js",
6
+ "exports": {
7
+ ".": "./src/index.js"
8
+ },
6
9
  "scripts": {
7
10
  "test": "echo \"Error: no test specified\" && exit 1"
8
11
  },
9
12
  "keywords": [],
10
13
  "author": "",
11
14
  "license": "ISC",
12
- "type": "commonjs"
15
+ "type": "module"
13
16
  }
package/src/index.js CHANGED
@@ -1,2 +1,5 @@
1
+ export { default as Visit } from "./models/Visit.js";
1
2
 
2
- export { saveVisit, getVisits } from "./trackVisit.js";
3
+ export {
4
+ getVisits, saveVisit, getVisitMembers
5
+ } from "./trackVisit.js";
package/src/trackVisit.js CHANGED
@@ -1,14 +1,12 @@
1
- const Visit = require("./models/Visit");
2
-
1
+ import Visit from "./models/Visit.js"
3
2
 
4
3
  export const saveVisit = async (visitData) => {
5
4
  try {
6
- const data = {token:token,ip:headersList,path:path,type:type,date:date,userinfo:[{username:username,image:image}]};
7
5
 
8
- console.log("Visit saved successfully");
9
6
  try{
10
- const val = await Visits.create(data)
11
- return val
7
+
8
+ const val = await Visit.create(visitData)
9
+ return val
12
10
  }catch(e){
13
11
  return e
14
12
  }
@@ -20,9 +18,56 @@ export const saveVisit = async (visitData) => {
20
18
  export const getVisits = async (path) => {
21
19
  try {
22
20
  const visits = await Visit.find({ path }).sort({ date: -1 });
23
- return visits;
21
+ return {visits, count: visits.length};
24
22
  } catch (error) {
25
23
  console.error("Error retrieving visits:", error);
24
+ return {visits: [], count: 0};
25
+ }
26
+ }
27
+
28
+
29
+ export const getVisitMembers = async (path,type) => {
30
+
31
+ const data = {path:path,type:type}
32
+
33
+
34
+
35
+
36
+ try{
37
+ const val = await Visit.aggregate([
38
+ { $match: data },
39
+ { $unwind: "$userinfo" },
40
+ { $match: { "userinfo.username": { $exists: true, $ne: "" } } },
41
+ { $sort: { createdAt: -1 } },
42
+ { $group: {
43
+ _id: "$userinfo.username",
44
+ userinfo: { $first: "$userinfo" },
45
+ createdAt: { $first: "$createdAt" }
46
+ }
47
+ },
48
+ { $project: {
49
+ _id: 0,
50
+ userinfo: 1,
51
+ createdAt: 1
52
+ }
53
+ },
54
+ { $sort: { createdAt: -1 } },
55
+ { $limit: 10 }
56
+ ]).exec();
57
+
58
+ // Add anonymous user entry with pixel art image from text
59
+ const anonymousImageUrl = `https://api.dicebear.com/7.x/pixel-art/svg?seed=anonymous`;
60
+ val.push({
61
+ userinfo: {
62
+ username: "anonymous",
63
+ image: anonymousImageUrl
64
+ },
65
+ createdAt: new Date()
66
+ });
67
+
68
+ return val;
69
+ }catch(e){
26
70
  return [];
71
+
27
72
  }
28
73
  }