locallytics 0.1.4 → 0.1.8
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 +4 -4
- package/dist/client/{AnalyticsGrabber.d.ts → LocallyticsGrabber.d.ts} +7 -5
- package/dist/client/LocallyticsGrabber.d.ts.map +1 -0
- package/dist/client/{AnalyticsGrabber.js → LocallyticsGrabber.js} +6 -6
- package/dist/client/LocallyticsGrabber.js.map +1 -0
- package/dist/client/tracker.d.ts +1 -1
- package/dist/client/tracker.d.ts.map +1 -1
- package/dist/client/tracker.js +2 -15
- package/dist/client/tracker.js.map +1 -1
- package/dist/db/factory.d.ts +11 -0
- package/dist/db/factory.d.ts.map +1 -0
- package/dist/db/factory.js +47 -0
- package/dist/db/factory.js.map +1 -0
- package/dist/db/mysql.d.ts +17 -0
- package/dist/db/mysql.d.ts.map +1 -0
- package/dist/db/mysql.js +144 -0
- package/dist/db/mysql.js.map +1 -0
- package/dist/db/sqlite.d.ts +17 -0
- package/dist/db/sqlite.d.ts.map +1 -0
- package/dist/db/sqlite.js +130 -0
- package/dist/db/sqlite.js.map +1 -0
- package/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/dist/server/index.d.ts +3 -3
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +5 -5
- package/dist/server/index.js.map +1 -1
- package/dist/server/validator.d.ts.map +1 -1
- package/dist/server/validator.js +0 -5
- package/dist/server/validator.js.map +1 -1
- package/dist/types/index.d.ts +7 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js.map +1 -1
- package/package.json +23 -3
- package/src/db/schema-mysql.sql +17 -0
- package/src/db/schema-sqlite.sql +29 -0
- package/dist/client/AnalyticsGrabber.d.ts.map +0 -1
- package/dist/client/AnalyticsGrabber.js.map +0 -1
package/README.md
CHANGED
|
@@ -35,14 +35,14 @@ export const { GET, POST } = analytics;
|
|
|
35
35
|
|
|
36
36
|
```tsx
|
|
37
37
|
// app/layout.tsx
|
|
38
|
-
import {
|
|
38
|
+
import { LocallyticsGrabber } from "locallytics";
|
|
39
39
|
|
|
40
40
|
export default function RootLayout({ children }) {
|
|
41
41
|
return (
|
|
42
42
|
<html>
|
|
43
43
|
<body>
|
|
44
44
|
{children}
|
|
45
|
-
<
|
|
45
|
+
<LocallyticsGrabber />
|
|
46
46
|
</body>
|
|
47
47
|
</html>
|
|
48
48
|
);
|
|
@@ -53,10 +53,10 @@ export default function RootLayout({ children }) {
|
|
|
53
53
|
|
|
54
54
|
```tsx
|
|
55
55
|
// app/page.tsx
|
|
56
|
-
import {
|
|
56
|
+
import { LocallyticsData } from "locallytics";
|
|
57
57
|
|
|
58
58
|
export default async function Home() {
|
|
59
|
-
const data = await
|
|
59
|
+
const data = await LocallyticsData(); // Simple! No arguments.
|
|
60
60
|
|
|
61
61
|
return <pre>{JSON.stringify(data, null, 2)}</pre>;
|
|
62
62
|
}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
interface
|
|
1
|
+
interface LocallyticsGrabberProps {
|
|
2
2
|
/** API endpoint URL (defaults to /api/analytics) */
|
|
3
3
|
endpoint?: string;
|
|
4
|
+
/** Interval in ms to batch events before sending (defaults to 30000) */
|
|
5
|
+
trackInterval?: number;
|
|
4
6
|
}
|
|
5
7
|
/**
|
|
6
8
|
* React component for tracking pageviews
|
|
@@ -9,20 +11,20 @@ interface AnalyticsGrabberProps {
|
|
|
9
11
|
* @example
|
|
10
12
|
* ```tsx
|
|
11
13
|
* // app/layout.tsx
|
|
12
|
-
* import {
|
|
14
|
+
* import { LocallyticsGrabber } from 'locallytics';
|
|
13
15
|
*
|
|
14
16
|
* export default function RootLayout({ children }) {
|
|
15
17
|
* return (
|
|
16
18
|
* <html>
|
|
17
19
|
* <body>
|
|
18
20
|
* {children}
|
|
19
|
-
* <
|
|
21
|
+
* <LocallyticsGrabber maxLength={5} trackInterval={5000} />
|
|
20
22
|
* </body>
|
|
21
23
|
* </html>
|
|
22
24
|
* );
|
|
23
25
|
* }
|
|
24
26
|
* ```
|
|
25
27
|
*/
|
|
26
|
-
export declare function
|
|
28
|
+
export declare function LocallyticsGrabber({ endpoint, trackInterval, }: LocallyticsGrabberProps): null;
|
|
27
29
|
export {};
|
|
28
|
-
//# sourceMappingURL=
|
|
30
|
+
//# sourceMappingURL=LocallyticsGrabber.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LocallyticsGrabber.d.ts","sourceRoot":"","sources":["../../src/client/LocallyticsGrabber.tsx"],"names":[],"mappings":"AAKA,UAAU,uBAAuB;IAC/B,oDAAoD;IACpD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,wEAAwE;IACxE,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,kBAAkB,CAAC,EACjC,QAA2B,EAC3B,aAAa,GACd,EAAE,uBAAuB,GAAG,IAAI,CAuDhC"}
|
|
@@ -8,26 +8,26 @@ import { Tracker } from "./tracker.js";
|
|
|
8
8
|
* @example
|
|
9
9
|
* ```tsx
|
|
10
10
|
* // app/layout.tsx
|
|
11
|
-
* import {
|
|
11
|
+
* import { LocallyticsGrabber } from 'locallytics';
|
|
12
12
|
*
|
|
13
13
|
* export default function RootLayout({ children }) {
|
|
14
14
|
* return (
|
|
15
15
|
* <html>
|
|
16
16
|
* <body>
|
|
17
17
|
* {children}
|
|
18
|
-
* <
|
|
18
|
+
* <LocallyticsGrabber maxLength={5} trackInterval={5000} />
|
|
19
19
|
* </body>
|
|
20
20
|
* </html>
|
|
21
21
|
* );
|
|
22
22
|
* }
|
|
23
23
|
* ```
|
|
24
24
|
*/
|
|
25
|
-
export function
|
|
25
|
+
export function LocallyticsGrabber({ endpoint = "/api/analytics", trackInterval, }) {
|
|
26
26
|
const trackerRef = useRef(null);
|
|
27
27
|
const lastPathRef = useRef("");
|
|
28
28
|
useEffect(() => {
|
|
29
29
|
// Initialize tracker
|
|
30
|
-
const tracker = new Tracker(endpoint);
|
|
30
|
+
const tracker = new Tracker(endpoint, trackInterval);
|
|
31
31
|
trackerRef.current = tracker;
|
|
32
32
|
// Track initial pageview
|
|
33
33
|
tracker.trackPageview();
|
|
@@ -64,8 +64,8 @@ export function AnalyticsGrabber({ endpoint = "/api/analytics", }) {
|
|
|
64
64
|
observer?.disconnect();
|
|
65
65
|
tracker.destroy();
|
|
66
66
|
};
|
|
67
|
-
}, [endpoint]);
|
|
67
|
+
}, [endpoint, trackInterval]);
|
|
68
68
|
// This component renders nothing
|
|
69
69
|
return null;
|
|
70
70
|
}
|
|
71
|
-
//# sourceMappingURL=
|
|
71
|
+
//# sourceMappingURL=LocallyticsGrabber.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LocallyticsGrabber.js","sourceRoot":"","sources":["../../src/client/LocallyticsGrabber.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AASvC;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,UAAU,kBAAkB,CAAC,EACjC,QAAQ,GAAG,gBAAgB,EAC3B,aAAa,GACW;IACxB,MAAM,UAAU,GAAG,MAAM,CAAiB,IAAI,CAAC,CAAC;IAChD,MAAM,WAAW,GAAG,MAAM,CAAS,EAAE,CAAC,CAAC;IAEvC,SAAS,CAAC,GAAG,EAAE;QACb,qBAAqB;QACrB,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;QACrD,UAAU,CAAC,OAAO,GAAG,OAAO,CAAC;QAE7B,yBAAyB;QACzB,OAAO,CAAC,aAAa,EAAE,CAAC;QACxB,WAAW,CAAC,OAAO,GAAG,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAE/C,yCAAyC;QACzC,MAAM,cAAc,GAAG,GAAS,EAAE;YAChC,IAAI,MAAM,CAAC,QAAQ,CAAC,QAAQ,KAAK,WAAW,CAAC,OAAO,EAAE,CAAC;gBACrD,WAAW,CAAC,OAAO,GAAG,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC;gBAC/C,OAAO,CAAC,aAAa,EAAE,CAAC;YAC1B,CAAC;QACH,CAAC,CAAC;QAEF,MAAM,CAAC,gBAAgB,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC;QAEpD,qDAAqD;QACrD,6CAA6C;QAC7C,IAAI,QAAQ,GAA4B,IAAI,CAAC;QAE7C,MAAM,kBAAkB,GAAG,GAAS,EAAE;YACpC,IAAI,MAAM,CAAC,QAAQ,CAAC,QAAQ,KAAK,WAAW,CAAC,OAAO,EAAE,CAAC;gBACrD,WAAW,CAAC,OAAO,GAAG,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC;gBAC/C,OAAO,CAAC,aAAa,EAAE,CAAC;YAC1B,CAAC;QACH,CAAC,CAAC;QAEF,iEAAiE;QACjE,QAAQ,GAAG,IAAI,gBAAgB,CAAC,GAAG,EAAE;YACnC,4CAA4C;YAC5C,qBAAqB,CAAC,kBAAkB,CAAC,CAAC;QAC5C,CAAC,CAAC,CAAC;QAEH,QAAQ,CAAC,OAAO,CAAC,QAAQ,EAAE;YACzB,OAAO,EAAE,IAAI;YACb,SAAS,EAAE,IAAI;SAChB,CAAC,CAAC;QAEH,UAAU;QACV,OAAO,GAAG,EAAE;YACV,MAAM,CAAC,mBAAmB,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC;YACvD,QAAQ,EAAE,UAAU,EAAE,CAAC;YACvB,OAAO,CAAC,OAAO,EAAE,CAAC;QACpB,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC,CAAC;IAE9B,iCAAiC;IACjC,OAAO,IAAI,CAAC;AACd,CAAC"}
|
package/dist/client/tracker.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tracker.d.ts","sourceRoot":"","sources":["../../src/client/tracker.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"tracker.d.ts","sourceRoot":"","sources":["../../src/client/tracker.ts"],"names":[],"mappings":"AA8EA;;GAEG;AACH,qBAAa,OAAO;IAClB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAe;IACvC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,UAAU,CAAU;gBAEhB,QAAQ,GAAE,MAAyB,EAAE,SAAS,CAAC,EAAE,MAAM;IAOnE;;OAEG;IACH,aAAa,IAAI,IAAI;IAwBrB;;OAEG;IACH,OAAO,IAAI,IAAI;CAGhB"}
|
package/dist/client/tracker.js
CHANGED
|
@@ -51,19 +51,6 @@ function isDNTEnabled() {
|
|
|
51
51
|
if (dnt === "1" || dnt === "yes") {
|
|
52
52
|
return true;
|
|
53
53
|
}
|
|
54
|
-
// Check window.doNotTrack (non-standard but used by some browsers)
|
|
55
|
-
if (typeof window !== "undefined" &&
|
|
56
|
-
"doNotTrack" in window &&
|
|
57
|
-
window.doNotTrack === "1") {
|
|
58
|
-
return true;
|
|
59
|
-
}
|
|
60
|
-
// Check Global Privacy Control
|
|
61
|
-
if (typeof navigator !== "undefined" &&
|
|
62
|
-
"globalPrivacyControl" in navigator &&
|
|
63
|
-
navigator
|
|
64
|
-
.globalPrivacyControl === true) {
|
|
65
|
-
return true;
|
|
66
|
-
}
|
|
67
54
|
return false;
|
|
68
55
|
}
|
|
69
56
|
/**
|
|
@@ -82,8 +69,8 @@ function sanitizeUrl(url) {
|
|
|
82
69
|
* Client-side tracker for pageviews
|
|
83
70
|
*/
|
|
84
71
|
export class Tracker {
|
|
85
|
-
constructor(endpoint = DEFAULT_ENDPOINT) {
|
|
86
|
-
this.batcher = new EventBatcher(endpoint);
|
|
72
|
+
constructor(endpoint = DEFAULT_ENDPOINT, maxWaitMs) {
|
|
73
|
+
this.batcher = new EventBatcher(endpoint, undefined, maxWaitMs);
|
|
87
74
|
this.dntEnabled = isDNTEnabled();
|
|
88
75
|
// Get persistent ID (returns ephemeral if DNT is on)
|
|
89
76
|
this.sessionId = getPersistentSessionId(this.dntEnabled);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tracker.js","sourceRoot":"","sources":["../../src/client/tracker.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C,MAAM,gBAAgB,GAAG,gBAAgB,CAAC;AAC1C,MAAM,WAAW,GAAG,iBAAiB,CAAC;AAEtC;;GAEG;AACH,SAAS,iBAAiB;IACxB,uDAAuD;IACvD,IAAI,OAAO,MAAM,KAAK,WAAW,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;QACvD,OAAO,MAAM,CAAC,UAAU,EAAE,CAAC;IAC7B,CAAC;IAED,+BAA+B;IAC/B,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;AACpE,CAAC;AAED;;GAEG;AACH,SAAS,sBAAsB,CAAC,UAAmB;IACjD,kEAAkE;IAClE,IAAI,UAAU,EAAE,CAAC;QACf,OAAO,iBAAiB,EAAE,CAAC;IAC7B,CAAC;IAED,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE,CAAC;QAClC,OAAO,iBAAiB,EAAE,CAAC;IAC7B,CAAC;IAED,IAAI,CAAC;QACH,qBAAqB;QACrB,MAAM,MAAM,GAAG,YAAY,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;QACjD,IAAI,MAAM,EAAE,CAAC;YACX,OAAO,MAAM,CAAC;QAChB,CAAC;QAED,uBAAuB;QACvB,MAAM,KAAK,GAAG,iBAAiB,EAAE,CAAC;QAClC,YAAY,CAAC,OAAO,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;QACzC,OAAO,KAAK,CAAC;IACf,CAAC;IAAC,MAAM,CAAC;QACP,+CAA+C;QAC/C,OAAO,iBAAiB,EAAE,CAAC;IAC7B,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAS,YAAY;IACnB,IAAI,OAAO,SAAS,KAAK,WAAW,EAAE,CAAC;QACrC,OAAO,KAAK,CAAC;IACf,CAAC;IAED,6BAA6B;IAC7B,MAAM,GAAG,GAAG,SAAS,CAAC,UAAU,CAAC;IACjC,IAAI,GAAG,KAAK,GAAG,IAAI,GAAG,KAAK,KAAK,EAAE,CAAC;QACjC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,
|
|
1
|
+
{"version":3,"file":"tracker.js","sourceRoot":"","sources":["../../src/client/tracker.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { AnalyticsDB, LocallyticsConfig } from "../types/index.js";
|
|
2
|
+
export type DatabaseType = "postgres" | "mysql" | "sqlite";
|
|
3
|
+
/**
|
|
4
|
+
* Detect database type from connection string
|
|
5
|
+
*/
|
|
6
|
+
export declare function detectDatabaseType(connectionString: string): DatabaseType;
|
|
7
|
+
/**
|
|
8
|
+
* Create the appropriate database instance based on config
|
|
9
|
+
*/
|
|
10
|
+
export declare function createDatabase(config: LocallyticsConfig): Promise<AnalyticsDB>;
|
|
11
|
+
//# sourceMappingURL=factory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../src/db/factory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAKxE,MAAM,MAAM,YAAY,GAAG,UAAU,GAAG,OAAO,GAAG,QAAQ,CAAC;AAE3D;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,gBAAgB,EAAE,MAAM,GAAG,YAAY,CAyBzE;AAED;;GAEG;AACH,wBAAsB,cAAc,CAClC,MAAM,EAAE,iBAAiB,GACxB,OAAO,CAAC,WAAW,CAAC,CAiBtB"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { PostgresDB } from "./postgres.js";
|
|
2
|
+
import { SQLiteDB } from "./sqlite.js";
|
|
3
|
+
import { MySQLDB } from "./mysql.js";
|
|
4
|
+
/**
|
|
5
|
+
* Detect database type from connection string
|
|
6
|
+
*/
|
|
7
|
+
export function detectDatabaseType(connectionString) {
|
|
8
|
+
const lower = connectionString.toLowerCase();
|
|
9
|
+
if (lower.startsWith("postgres://") || lower.startsWith("postgresql://")) {
|
|
10
|
+
return "postgres";
|
|
11
|
+
}
|
|
12
|
+
if (lower.startsWith("mysql://")) {
|
|
13
|
+
return "mysql";
|
|
14
|
+
}
|
|
15
|
+
// If it's a file path or sqlite:// prefix, use SQLite
|
|
16
|
+
if (lower.startsWith("sqlite://") ||
|
|
17
|
+
lower.endsWith(".db") ||
|
|
18
|
+
lower.endsWith(".sqlite") ||
|
|
19
|
+
lower.endsWith(".sqlite3") ||
|
|
20
|
+
lower.includes("/") ||
|
|
21
|
+
lower === ":memory:") {
|
|
22
|
+
return "sqlite";
|
|
23
|
+
}
|
|
24
|
+
// Default to postgres for backwards compatibility
|
|
25
|
+
return "postgres";
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Create the appropriate database instance based on config
|
|
29
|
+
*/
|
|
30
|
+
export async function createDatabase(config) {
|
|
31
|
+
const dbType = config.type ?? detectDatabaseType(config.database);
|
|
32
|
+
switch (dbType) {
|
|
33
|
+
case "sqlite": {
|
|
34
|
+
// Strip sqlite:// or file: prefix if present
|
|
35
|
+
const filePath = config.database
|
|
36
|
+
.replace(/^sqlite:\/\//, "")
|
|
37
|
+
.replace(/^file:/, "");
|
|
38
|
+
return SQLiteDB.create(filePath);
|
|
39
|
+
}
|
|
40
|
+
case "mysql":
|
|
41
|
+
return MySQLDB.create(config.database);
|
|
42
|
+
case "postgres":
|
|
43
|
+
default:
|
|
44
|
+
return new PostgresDB(config.database);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=factory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"factory.js","sourceRoot":"","sources":["../../src/db/factory.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAIrC;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAAC,gBAAwB;IACzD,MAAM,KAAK,GAAG,gBAAgB,CAAC,WAAW,EAAE,CAAC;IAE7C,IAAI,KAAK,CAAC,UAAU,CAAC,aAAa,CAAC,IAAI,KAAK,CAAC,UAAU,CAAC,eAAe,CAAC,EAAE,CAAC;QACzE,OAAO,UAAU,CAAC;IACpB,CAAC;IAED,IAAI,KAAK,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QACjC,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,sDAAsD;IACtD,IACE,KAAK,CAAC,UAAU,CAAC,WAAW,CAAC;QAC7B,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC;QACrB,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC;QACzB,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC;QAC1B,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC;QACnB,KAAK,KAAK,UAAU,EACpB,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,kDAAkD;IAClD,OAAO,UAAU,CAAC;AACpB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,MAAyB;IAEzB,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,IAAI,kBAAkB,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAElE,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,QAAQ,CAAC,CAAC,CAAC;YACd,6CAA6C;YAC7C,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ;iBAC7B,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC;iBAC3B,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;YACzB,OAAO,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QACnC,CAAC;QACD,KAAK,OAAO;YACV,OAAO,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QACzC,KAAK,UAAU,CAAC;QAChB;YACE,OAAO,IAAI,UAAU,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC3C,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { AnalyticsDB, PageviewEvent, DateRange, PageStats, DailyStats } from "../types/index.js";
|
|
2
|
+
/**
|
|
3
|
+
* MySQL implementation of the analytics database
|
|
4
|
+
*/
|
|
5
|
+
export declare class MySQLDB implements AnalyticsDB {
|
|
6
|
+
private pool;
|
|
7
|
+
private constructor();
|
|
8
|
+
static create(connectionString: string): Promise<MySQLDB>;
|
|
9
|
+
insertPageview(event: PageviewEvent, ipHash: string | null): Promise<void>;
|
|
10
|
+
getPageviews(dateRange: DateRange): Promise<number>;
|
|
11
|
+
getUniqueVisitors(dateRange: DateRange): Promise<number>;
|
|
12
|
+
getTopPages(dateRange: DateRange, limit: number): Promise<PageStats[]>;
|
|
13
|
+
getTopReferrers(dateRange: DateRange, limit: number): Promise<PageStats[]>;
|
|
14
|
+
getDailyStats(dateRange: DateRange): Promise<DailyStats[]>;
|
|
15
|
+
close(): Promise<void>;
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=mysql.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mysql.d.ts","sourceRoot":"","sources":["../../src/db/mysql.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,WAAW,EACX,aAAa,EACb,SAAS,EACT,SAAS,EACT,UAAU,EACX,MAAM,mBAAmB,CAAC;AAgD3B;;GAEG;AACH,qBAAa,OAAQ,YAAW,WAAW;IACzC,OAAO,CAAC,IAAI,CAAO;IAEnB,OAAO;WAIM,MAAM,CAAC,gBAAgB,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAUzD,cAAc,CAClB,KAAK,EAAE,aAAa,EACpB,MAAM,EAAE,MAAM,GAAG,IAAI,GACpB,OAAO,CAAC,IAAI,CAAC;IAoBV,YAAY,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC;IAgBnD,iBAAiB,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC;IAgBxD,WAAW,CAAC,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAsBtE,eAAe,CACnB,SAAS,EAAE,SAAS,EACpB,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,SAAS,EAAE,CAAC;IAsBjB,aAAa,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAgC1D,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAG7B"}
|
package/dist/db/mysql.js
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Get SQL WHERE clause parts for a date range (MySQL version)
|
|
3
|
+
*/
|
|
4
|
+
function getDateRangeFilter(dateRange) {
|
|
5
|
+
const now = new Date();
|
|
6
|
+
if (dateRange === "last24h") {
|
|
7
|
+
const start = new Date(now.getTime() - 24 * 60 * 60 * 1000);
|
|
8
|
+
return {
|
|
9
|
+
whereClause: "timestamp >= ?",
|
|
10
|
+
params: [start.toISOString()],
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
if (dateRange === "last7d") {
|
|
14
|
+
const start = new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000);
|
|
15
|
+
return {
|
|
16
|
+
whereClause: "timestamp >= ?",
|
|
17
|
+
params: [start.toISOString()],
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
if (dateRange === "last30d") {
|
|
21
|
+
const start = new Date(now.getTime() - 30 * 24 * 60 * 60 * 1000);
|
|
22
|
+
return {
|
|
23
|
+
whereClause: "timestamp >= ?",
|
|
24
|
+
params: [start.toISOString()],
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
// Custom date range
|
|
28
|
+
return {
|
|
29
|
+
whereClause: "timestamp >= ? AND timestamp <= ?",
|
|
30
|
+
params: [dateRange.start.toISOString(), dateRange.end.toISOString()],
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* MySQL implementation of the analytics database
|
|
35
|
+
*/
|
|
36
|
+
export class MySQLDB {
|
|
37
|
+
constructor(pool) {
|
|
38
|
+
this.pool = pool;
|
|
39
|
+
}
|
|
40
|
+
static async create(connectionString) {
|
|
41
|
+
const mysql = await import("mysql2/promise");
|
|
42
|
+
const pool = mysql.createPool({
|
|
43
|
+
uri: connectionString,
|
|
44
|
+
waitForConnections: true,
|
|
45
|
+
connectionLimit: 10,
|
|
46
|
+
});
|
|
47
|
+
return new MySQLDB(pool);
|
|
48
|
+
}
|
|
49
|
+
async insertPageview(event, ipHash) {
|
|
50
|
+
const query = `
|
|
51
|
+
INSERT INTO locallytics_pageviews (
|
|
52
|
+
session_id, page_url, referrer, user_agent,
|
|
53
|
+
screen_width, screen_height, ip_hash, timestamp
|
|
54
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
55
|
+
`;
|
|
56
|
+
await this.pool.execute(query, [
|
|
57
|
+
event.sessionId,
|
|
58
|
+
event.pageUrl,
|
|
59
|
+
event.referrer,
|
|
60
|
+
event.userAgent,
|
|
61
|
+
event.screenWidth,
|
|
62
|
+
event.screenHeight,
|
|
63
|
+
ipHash,
|
|
64
|
+
event.timestamp,
|
|
65
|
+
]);
|
|
66
|
+
}
|
|
67
|
+
async getPageviews(dateRange) {
|
|
68
|
+
const { whereClause, params } = getDateRangeFilter(dateRange);
|
|
69
|
+
const query = `
|
|
70
|
+
SELECT COUNT(*) as count
|
|
71
|
+
FROM locallytics_pageviews
|
|
72
|
+
WHERE ${whereClause}
|
|
73
|
+
`;
|
|
74
|
+
const [rows] = await this.pool.execute(query, params);
|
|
75
|
+
return rows[0]?.count ?? 0;
|
|
76
|
+
}
|
|
77
|
+
async getUniqueVisitors(dateRange) {
|
|
78
|
+
const { whereClause, params } = getDateRangeFilter(dateRange);
|
|
79
|
+
const query = `
|
|
80
|
+
SELECT COUNT(DISTINCT session_id) as count
|
|
81
|
+
FROM locallytics_pageviews
|
|
82
|
+
WHERE ${whereClause}
|
|
83
|
+
`;
|
|
84
|
+
const [rows] = await this.pool.execute(query, params);
|
|
85
|
+
return rows[0]?.count ?? 0;
|
|
86
|
+
}
|
|
87
|
+
async getTopPages(dateRange, limit) {
|
|
88
|
+
const { whereClause, params } = getDateRangeFilter(dateRange);
|
|
89
|
+
const query = `
|
|
90
|
+
SELECT page_url as pageUrl, COUNT(*) as count
|
|
91
|
+
FROM locallytics_pageviews
|
|
92
|
+
WHERE ${whereClause}
|
|
93
|
+
GROUP BY page_url
|
|
94
|
+
ORDER BY count DESC
|
|
95
|
+
LIMIT ?
|
|
96
|
+
`;
|
|
97
|
+
const [rows] = await this.pool.execute(query, [...params, limit]);
|
|
98
|
+
return rows.map((row) => ({
|
|
99
|
+
pageUrl: row.pageUrl,
|
|
100
|
+
count: Number(row.count),
|
|
101
|
+
}));
|
|
102
|
+
}
|
|
103
|
+
async getTopReferrers(dateRange, limit) {
|
|
104
|
+
const { whereClause, params } = getDateRangeFilter(dateRange);
|
|
105
|
+
const query = `
|
|
106
|
+
SELECT referrer as pageUrl, COUNT(*) as count
|
|
107
|
+
FROM locallytics_pageviews
|
|
108
|
+
WHERE ${whereClause} AND referrer IS NOT NULL
|
|
109
|
+
GROUP BY referrer
|
|
110
|
+
ORDER BY count DESC
|
|
111
|
+
LIMIT ?
|
|
112
|
+
`;
|
|
113
|
+
const [rows] = await this.pool.execute(query, [...params, limit]);
|
|
114
|
+
return rows.map((row) => ({
|
|
115
|
+
pageUrl: row.pageUrl,
|
|
116
|
+
count: Number(row.count),
|
|
117
|
+
}));
|
|
118
|
+
}
|
|
119
|
+
async getDailyStats(dateRange) {
|
|
120
|
+
const { whereClause, params } = getDateRangeFilter(dateRange);
|
|
121
|
+
const query = `
|
|
122
|
+
SELECT
|
|
123
|
+
DATE(timestamp) as date,
|
|
124
|
+
COUNT(*) as pageviews,
|
|
125
|
+
COUNT(DISTINCT session_id) as uniqueVisitors
|
|
126
|
+
FROM locallytics_pageviews
|
|
127
|
+
WHERE ${whereClause}
|
|
128
|
+
GROUP BY DATE(timestamp)
|
|
129
|
+
ORDER BY date DESC
|
|
130
|
+
`;
|
|
131
|
+
const [rows] = await this.pool.execute(query, params);
|
|
132
|
+
return rows.map((row) => ({
|
|
133
|
+
date: row.date instanceof Date
|
|
134
|
+
? row.date.toISOString().split("T")[0] ?? ""
|
|
135
|
+
: String(row.date),
|
|
136
|
+
pageviews: Number(row.pageviews),
|
|
137
|
+
uniqueVisitors: Number(row.uniqueVisitors),
|
|
138
|
+
}));
|
|
139
|
+
}
|
|
140
|
+
async close() {
|
|
141
|
+
await this.pool.end();
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
//# sourceMappingURL=mysql.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mysql.js","sourceRoot":"","sources":["../../src/db/mysql.ts"],"names":[],"mappings":"AAcA;;GAEG;AACH,SAAS,kBAAkB,CAAC,SAAoB;IAI9C,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;IAEvB,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;QAC5B,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;QAC5D,OAAO;YACL,WAAW,EAAE,gBAAgB;YAC7B,MAAM,EAAE,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;SAC9B,CAAC;IACJ,CAAC;IAED,IAAI,SAAS,KAAK,QAAQ,EAAE,CAAC;QAC3B,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;QAChE,OAAO;YACL,WAAW,EAAE,gBAAgB;YAC7B,MAAM,EAAE,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;SAC9B,CAAC;IACJ,CAAC;IAED,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;QAC5B,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;QACjE,OAAO;YACL,WAAW,EAAE,gBAAgB;YAC7B,MAAM,EAAE,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;SAC9B,CAAC;IACJ,CAAC;IAED,oBAAoB;IACpB,OAAO;QACL,WAAW,EAAE,mCAAmC;QAChD,MAAM,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,WAAW,EAAE,EAAE,SAAS,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC;KACrE,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,OAAO,OAAO;IAGlB,YAAoB,IAAU;QAC5B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,gBAAwB;QAC1C,MAAM,KAAK,GAAG,MAAM,MAAM,CAAC,gBAAgB,CAAC,CAAC;QAC7C,MAAM,IAAI,GAAG,KAAK,CAAC,UAAU,CAAC;YAC5B,GAAG,EAAE,gBAAgB;YACrB,kBAAkB,EAAE,IAAI;YACxB,eAAe,EAAE,EAAE;SACpB,CAAoB,CAAC;QACtB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3B,CAAC;IAED,KAAK,CAAC,cAAc,CAClB,KAAoB,EACpB,MAAqB;QAErB,MAAM,KAAK,GAAG;;;;;KAKb,CAAC;QAEF,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE;YAC7B,KAAK,CAAC,SAAS;YACf,KAAK,CAAC,OAAO;YACb,KAAK,CAAC,QAAQ;YACd,KAAK,CAAC,SAAS;YACf,KAAK,CAAC,WAAW;YACjB,KAAK,CAAC,YAAY;YAClB,MAAM;YACN,KAAK,CAAC,SAAS;SAChB,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,SAAoB;QACrC,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,GAAG,kBAAkB,CAAC,SAAS,CAAC,CAAC;QAE9D,MAAM,KAAK,GAAG;;;cAGJ,WAAW;KACpB,CAAC;QAEF,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,CACpC,KAAK,EACL,MAAM,CACP,CAAC;QACF,OAAO,IAAI,CAAC,CAAC,CAAC,EAAE,KAAK,IAAI,CAAC,CAAC;IAC7B,CAAC;IAED,KAAK,CAAC,iBAAiB,CAAC,SAAoB;QAC1C,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,GAAG,kBAAkB,CAAC,SAAS,CAAC,CAAC;QAE9D,MAAM,KAAK,GAAG;;;cAGJ,WAAW;KACpB,CAAC;QAEF,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,CACpC,KAAK,EACL,MAAM,CACP,CAAC;QACF,OAAO,IAAI,CAAC,CAAC,CAAC,EAAE,KAAK,IAAI,CAAC,CAAC;IAC7B,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,SAAoB,EAAE,KAAa;QACnD,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,GAAG,kBAAkB,CAAC,SAAS,CAAC,CAAC;QAE9D,MAAM,KAAK,GAAG;;;cAGJ,WAAW;;;;KAIpB,CAAC;QAEF,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,CAEpC,KAAK,EAAE,CAAC,GAAG,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC;QAE7B,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;YACxB,OAAO,EAAE,GAAG,CAAC,OAAO;YACpB,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC;SACzB,CAAC,CAAC,CAAC;IACN,CAAC;IAED,KAAK,CAAC,eAAe,CACnB,SAAoB,EACpB,KAAa;QAEb,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,GAAG,kBAAkB,CAAC,SAAS,CAAC,CAAC;QAE9D,MAAM,KAAK,GAAG;;;cAGJ,WAAW;;;;KAIpB,CAAC;QAEF,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,CAEpC,KAAK,EAAE,CAAC,GAAG,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC;QAE7B,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;YACxB,OAAO,EAAE,GAAG,CAAC,OAAO;YACpB,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC;SACzB,CAAC,CAAC,CAAC;IACN,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,SAAoB;QACtC,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,GAAG,kBAAkB,CAAC,SAAS,CAAC,CAAC;QAE9D,MAAM,KAAK,GAAG;;;;;;cAMJ,WAAW;;;KAGpB,CAAC;QAEF,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,CAMpC,KAAK,EAAE,MAAM,CAAC,CAAC;QAEjB,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;YACxB,IAAI,EACF,GAAG,CAAC,IAAI,YAAY,IAAI;gBACtB,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE;gBAC5C,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC;YACtB,SAAS,EAAE,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC;YAChC,cAAc,EAAE,MAAM,CAAC,GAAG,CAAC,cAAc,CAAC;SAC3C,CAAC,CAAC,CAAC;IACN,CAAC;IAED,KAAK,CAAC,KAAK;QACT,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;IACxB,CAAC;CACF"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { AnalyticsDB, PageviewEvent, DateRange, PageStats, DailyStats } from "../types/index.js";
|
|
2
|
+
/**
|
|
3
|
+
* SQLite implementation of the analytics database
|
|
4
|
+
*/
|
|
5
|
+
export declare class SQLiteDB implements AnalyticsDB {
|
|
6
|
+
private db;
|
|
7
|
+
private constructor();
|
|
8
|
+
static create(filePath: string): Promise<SQLiteDB>;
|
|
9
|
+
insertPageview(event: PageviewEvent, ipHash: string | null): Promise<void>;
|
|
10
|
+
getPageviews(dateRange: DateRange): Promise<number>;
|
|
11
|
+
getUniqueVisitors(dateRange: DateRange): Promise<number>;
|
|
12
|
+
getTopPages(dateRange: DateRange, limit: number): Promise<PageStats[]>;
|
|
13
|
+
getTopReferrers(dateRange: DateRange, limit: number): Promise<PageStats[]>;
|
|
14
|
+
getDailyStats(dateRange: DateRange): Promise<DailyStats[]>;
|
|
15
|
+
close(): Promise<void>;
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=sqlite.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sqlite.d.ts","sourceRoot":"","sources":["../../src/db/sqlite.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,WAAW,EACX,aAAa,EACb,SAAS,EACT,SAAS,EACT,UAAU,EACX,MAAM,mBAAmB,CAAC;AAuD3B;;GAEG;AACH,qBAAa,QAAS,YAAW,WAAW;IAC1C,OAAO,CAAC,EAAE,CAAW;IAErB,OAAO;WAIM,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;IAOlD,cAAc,CAClB,KAAK,EAAE,aAAa,EACpB,MAAM,EAAE,MAAM,GAAG,IAAI,GACpB,OAAO,CAAC,IAAI,CAAC;IAoBV,YAAY,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC;IAanD,iBAAiB,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC;IAaxD,WAAW,CAAC,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAuBtE,eAAe,CACnB,SAAS,EAAE,SAAS,EACpB,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,SAAS,EAAE,CAAC;IAuBjB,aAAa,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IA2B1D,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAG7B"}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Get SQL WHERE clause parts for a date range (SQLite version)
|
|
3
|
+
*/
|
|
4
|
+
function getDateRangeFilter(dateRange) {
|
|
5
|
+
const now = new Date();
|
|
6
|
+
if (dateRange === "last24h") {
|
|
7
|
+
const start = new Date(now.getTime() - 24 * 60 * 60 * 1000);
|
|
8
|
+
return {
|
|
9
|
+
whereClause: "timestamp >= ?",
|
|
10
|
+
params: [start.toISOString()],
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
if (dateRange === "last7d") {
|
|
14
|
+
const start = new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000);
|
|
15
|
+
return {
|
|
16
|
+
whereClause: "timestamp >= ?",
|
|
17
|
+
params: [start.toISOString()],
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
if (dateRange === "last30d") {
|
|
21
|
+
const start = new Date(now.getTime() - 30 * 24 * 60 * 60 * 1000);
|
|
22
|
+
return {
|
|
23
|
+
whereClause: "timestamp >= ?",
|
|
24
|
+
params: [start.toISOString()],
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
// Custom date range
|
|
28
|
+
return {
|
|
29
|
+
whereClause: "timestamp >= ? AND timestamp <= ?",
|
|
30
|
+
params: [dateRange.start.toISOString(), dateRange.end.toISOString()],
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* SQLite implementation of the analytics database
|
|
35
|
+
*/
|
|
36
|
+
export class SQLiteDB {
|
|
37
|
+
constructor(db) {
|
|
38
|
+
this.db = db;
|
|
39
|
+
}
|
|
40
|
+
static async create(filePath) {
|
|
41
|
+
const BetterSqlite3Module = await import("better-sqlite3");
|
|
42
|
+
const BetterSqlite3 = BetterSqlite3Module.default;
|
|
43
|
+
const db = new BetterSqlite3(filePath);
|
|
44
|
+
return new SQLiteDB(db);
|
|
45
|
+
}
|
|
46
|
+
async insertPageview(event, ipHash) {
|
|
47
|
+
const stmt = this.db.prepare(`
|
|
48
|
+
INSERT INTO locallytics_pageviews (
|
|
49
|
+
session_id, page_url, referrer, user_agent,
|
|
50
|
+
screen_width, screen_height, ip_hash, timestamp
|
|
51
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
52
|
+
`);
|
|
53
|
+
stmt.run(event.sessionId, event.pageUrl, event.referrer, event.userAgent, event.screenWidth, event.screenHeight, ipHash, event.timestamp);
|
|
54
|
+
}
|
|
55
|
+
async getPageviews(dateRange) {
|
|
56
|
+
const { whereClause, params } = getDateRangeFilter(dateRange);
|
|
57
|
+
const stmt = this.db.prepare(`
|
|
58
|
+
SELECT COUNT(*) as count
|
|
59
|
+
FROM locallytics_pageviews
|
|
60
|
+
WHERE ${whereClause}
|
|
61
|
+
`);
|
|
62
|
+
const result = stmt.get(...params);
|
|
63
|
+
return result?.count ?? 0;
|
|
64
|
+
}
|
|
65
|
+
async getUniqueVisitors(dateRange) {
|
|
66
|
+
const { whereClause, params } = getDateRangeFilter(dateRange);
|
|
67
|
+
const stmt = this.db.prepare(`
|
|
68
|
+
SELECT COUNT(DISTINCT session_id) as count
|
|
69
|
+
FROM locallytics_pageviews
|
|
70
|
+
WHERE ${whereClause}
|
|
71
|
+
`);
|
|
72
|
+
const result = stmt.get(...params);
|
|
73
|
+
return result?.count ?? 0;
|
|
74
|
+
}
|
|
75
|
+
async getTopPages(dateRange, limit) {
|
|
76
|
+
const { whereClause, params } = getDateRangeFilter(dateRange);
|
|
77
|
+
const stmt = this.db.prepare(`
|
|
78
|
+
SELECT page_url as pageUrl, COUNT(*) as count
|
|
79
|
+
FROM locallytics_pageviews
|
|
80
|
+
WHERE ${whereClause}
|
|
81
|
+
GROUP BY page_url
|
|
82
|
+
ORDER BY count DESC
|
|
83
|
+
LIMIT ?
|
|
84
|
+
`);
|
|
85
|
+
const results = stmt.all(...params, limit);
|
|
86
|
+
return results.map((row) => ({
|
|
87
|
+
pageUrl: row.pageUrl,
|
|
88
|
+
count: row.count,
|
|
89
|
+
}));
|
|
90
|
+
}
|
|
91
|
+
async getTopReferrers(dateRange, limit) {
|
|
92
|
+
const { whereClause, params } = getDateRangeFilter(dateRange);
|
|
93
|
+
const stmt = this.db.prepare(`
|
|
94
|
+
SELECT referrer as pageUrl, COUNT(*) as count
|
|
95
|
+
FROM locallytics_pageviews
|
|
96
|
+
WHERE ${whereClause} AND referrer IS NOT NULL
|
|
97
|
+
GROUP BY referrer
|
|
98
|
+
ORDER BY count DESC
|
|
99
|
+
LIMIT ?
|
|
100
|
+
`);
|
|
101
|
+
const results = stmt.all(...params, limit);
|
|
102
|
+
return results.map((row) => ({
|
|
103
|
+
pageUrl: row.pageUrl,
|
|
104
|
+
count: row.count,
|
|
105
|
+
}));
|
|
106
|
+
}
|
|
107
|
+
async getDailyStats(dateRange) {
|
|
108
|
+
const { whereClause, params } = getDateRangeFilter(dateRange);
|
|
109
|
+
const stmt = this.db.prepare(`
|
|
110
|
+
SELECT
|
|
111
|
+
date(timestamp) as date,
|
|
112
|
+
COUNT(*) as pageviews,
|
|
113
|
+
COUNT(DISTINCT session_id) as uniqueVisitors
|
|
114
|
+
FROM locallytics_pageviews
|
|
115
|
+
WHERE ${whereClause}
|
|
116
|
+
GROUP BY date(timestamp)
|
|
117
|
+
ORDER BY date DESC
|
|
118
|
+
`);
|
|
119
|
+
const results = stmt.all(...params);
|
|
120
|
+
return results.map((row) => ({
|
|
121
|
+
date: row.date,
|
|
122
|
+
pageviews: row.pageviews,
|
|
123
|
+
uniqueVisitors: row.uniqueVisitors,
|
|
124
|
+
}));
|
|
125
|
+
}
|
|
126
|
+
async close() {
|
|
127
|
+
this.db.close();
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
//# sourceMappingURL=sqlite.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sqlite.js","sourceRoot":"","sources":["../../src/db/sqlite.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
export { locallytics,
|
|
2
|
-
export {
|
|
1
|
+
export { locallytics, LocallyticsData } from "./server/index.js";
|
|
2
|
+
export { createDatabase } from "./db/factory.js";
|
|
3
|
+
export type { AnalyticsDB } from "./types/index.js";
|
|
4
|
+
export { LocallyticsGrabber } from "./client/LocallyticsGrabber.js";
|
|
3
5
|
export type { LocallyticsConfig, AnalyticsResult, DateRange, PageStats, DailyStats, PageviewEvent, AnalyticsDataOptions, } from "./types/index.js";
|
|
4
6
|
export { LocallyticsError } from "./types/index.js";
|
|
5
7
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACjE,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,YAAY,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAGpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AAGpE,YAAY,EACV,iBAAiB,EACjB,eAAe,EACf,SAAS,EACT,SAAS,EACT,UAAU,EACV,aAAa,EACb,oBAAoB,GACrB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// Server exports
|
|
2
|
-
export { locallytics,
|
|
2
|
+
export { locallytics, LocallyticsData } from "./server/index.js";
|
|
3
|
+
export { createDatabase } from "./db/factory.js";
|
|
3
4
|
// Client exports
|
|
4
|
-
export {
|
|
5
|
+
export { LocallyticsGrabber } from "./client/LocallyticsGrabber.js";
|
|
5
6
|
export { LocallyticsError } from "./types/index.js";
|
|
6
7
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,iBAAiB;AACjB,OAAO,EAAE,WAAW,EAAE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,iBAAiB;AACjB,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACjE,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAGjD,iBAAiB;AACjB,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AAapE,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC"}
|
package/dist/server/index.d.ts
CHANGED
|
@@ -29,14 +29,14 @@ export declare function locallytics(config: LocallyticsConfig): Promise<RouteHan
|
|
|
29
29
|
* @example
|
|
30
30
|
* ```tsx
|
|
31
31
|
* // app/dashboard/page.tsx
|
|
32
|
-
* import {
|
|
32
|
+
* import { LocallyticsData } from 'locallytics';
|
|
33
33
|
*
|
|
34
34
|
* export default async function Dashboard() {
|
|
35
|
-
* const data = await
|
|
35
|
+
* const data = await LocallyticsData(); // No arguments needed!
|
|
36
36
|
*
|
|
37
37
|
* return <div>{data.pageviews} pageviews</div>;
|
|
38
38
|
* }
|
|
39
39
|
* ```
|
|
40
40
|
*/
|
|
41
|
-
export declare function
|
|
41
|
+
export declare function LocallyticsData(options?: AnalyticsDataOptions): Promise<AnalyticsResult>;
|
|
42
42
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,iBAAiB,EACjB,YAAY,EACZ,eAAe,EACf,oBAAoB,EACrB,MAAM,mBAAmB,CAAC;AAI3B;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,WAAW,CAC/B,MAAM,EAAE,iBAAiB,GACxB,OAAO,CAAC,YAAY,CAAC,CAGvB;AAID;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,iBAAiB,EACjB,YAAY,EACZ,eAAe,EACf,oBAAoB,EACrB,MAAM,mBAAmB,CAAC;AAI3B;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,WAAW,CAC/B,MAAM,EAAE,iBAAiB,GACxB,OAAO,CAAC,YAAY,CAAC,CAGvB;AAID;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,eAAe,CACnC,OAAO,GAAE,oBAAyB,GACjC,OAAO,CAAC,eAAe,CAAC,CAiE1B"}
|
package/dist/server/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { createDatabase } from "../db/factory.js";
|
|
2
2
|
import { createHandlers } from "./handlers.js";
|
|
3
3
|
/**
|
|
4
4
|
* Initialize Locallytics and create route handlers
|
|
@@ -20,7 +20,7 @@ import { createHandlers } from "./handlers.js";
|
|
|
20
20
|
* ```
|
|
21
21
|
*/
|
|
22
22
|
export async function locallytics(config) {
|
|
23
|
-
const db =
|
|
23
|
+
const db = await createDatabase(config);
|
|
24
24
|
return createHandlers(db, config);
|
|
25
25
|
}
|
|
26
26
|
import { headers } from "next/headers";
|
|
@@ -34,16 +34,16 @@ import { headers } from "next/headers";
|
|
|
34
34
|
* @example
|
|
35
35
|
* ```tsx
|
|
36
36
|
* // app/dashboard/page.tsx
|
|
37
|
-
* import {
|
|
37
|
+
* import { LocallyticsData } from 'locallytics';
|
|
38
38
|
*
|
|
39
39
|
* export default async function Dashboard() {
|
|
40
|
-
* const data = await
|
|
40
|
+
* const data = await LocallyticsData(); // No arguments needed!
|
|
41
41
|
*
|
|
42
42
|
* return <div>{data.pageviews} pageviews</div>;
|
|
43
43
|
* }
|
|
44
44
|
* ```
|
|
45
45
|
*/
|
|
46
|
-
export async function
|
|
46
|
+
export async function LocallyticsData(options = {}) {
|
|
47
47
|
const { dateRange = "last7d", endpoint = "/api/analytics" } = options;
|
|
48
48
|
// Get headers to extract host for URL construction
|
|
49
49
|
const headersList = await Promise.resolve(headers());
|
package/dist/server/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../../src/server/validator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAQvD;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAkB/C;AAED;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,
|
|
1
|
+
{"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../../src/server/validator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAQvD;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAkB/C;AAED;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAUlD;AASD;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,OAAO,GAAG,aAAa,CA6ElE;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,OAAO,GAAG,aAAa,EAAE,CA2BpE"}
|
package/dist/server/validator.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validator.js","sourceRoot":"","sources":["../../src/server/validator.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAErD,MAAM,qBAAqB,GAAG,GAAG,CAAC;AAClC,MAAM,qBAAqB,GAAG,GAAG,CAAC;AAClC,MAAM,cAAc,GAAG,IAAI,CAAC;AAC5B,MAAM,cAAc,GAAG,GAAG,CAAC;AAE3B;;;;;GAKG;AACH,MAAM,UAAU,WAAW,CAAC,GAAW;IACrC,IAAI,CAAC;QACH,wCAAwC;QACxC,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,GAAG,EAAE,kBAAkB,CAAC,CAAC;QAEhD,kEAAkE;QAClE,IAAI,SAAS,GAAG,MAAM,CAAC,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC;QAEhD,eAAe;QACf,IAAI,SAAS,CAAC,MAAM,GAAG,cAAc,EAAE,CAAC;YACtC,SAAS,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,cAAc,CAAC,CAAC;QACjD,CAAC;QAED,OAAO,SAAS,CAAC;IACnB,CAAC;IAAC,MAAM,CAAC;QACP,8BAA8B;QAC9B,OAAO,GAAG,CAAC;IACb,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,QAAQ,CAAC,OAAgB;IACvC,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAEhC,mBAAmB;IACnB,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAC/B,IAAI,GAAG,KAAK,GAAG,EAAE,CAAC;QAChB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,
|
|
1
|
+
{"version":3,"file":"validator.js","sourceRoot":"","sources":["../../src/server/validator.ts"],"names":[],"mappings":"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"}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,9 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Database type supported by locallytics
|
|
3
|
+
*/
|
|
4
|
+
export type DatabaseType = "postgres" | "mysql" | "sqlite";
|
|
1
5
|
/**
|
|
2
6
|
* Configuration for the locallytics() function
|
|
3
7
|
*/
|
|
4
8
|
export interface LocallyticsConfig {
|
|
5
|
-
/**
|
|
9
|
+
/** Database connection string or file path (for SQLite) */
|
|
6
10
|
database: string;
|
|
11
|
+
/** Database type - auto-detected from connection string if omitted */
|
|
12
|
+
type?: DatabaseType;
|
|
7
13
|
/** Optional API key for GET endpoint authentication */
|
|
8
14
|
apiKey?: string;
|
|
9
15
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"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"}
|
package/dist/types/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAsIA;;GAEG;AACH,MAAM,OAAO,gBAAiB,SAAQ,KAAK;IACzC,YACE,OAAe,EACC,IAAY,EACZ,aAAqB,GAAG;QAExC,KAAK,CAAC,OAAO,CAAC,CAAC;QAHC,SAAI,GAAJ,IAAI,CAAQ;QACZ,eAAU,GAAV,UAAU,CAAc;QAGxC,IAAI,CAAC,IAAI,GAAG,kBAAkB,CAAC;IACjC,CAAC;IAED,MAAM,CAAC,UAAU,CAAC,OAAe;QAC/B,OAAO,IAAI,gBAAgB,CAAC,OAAO,EAAE,kBAAkB,EAAE,GAAG,CAAC,CAAC;IAChE,CAAC;IAED,MAAM,CAAC,SAAS;QACd,OAAO,IAAI,gBAAgB,CACzB,qBAAqB,EACrB,qBAAqB,EACrB,GAAG,CACJ,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,YAAY;QACjB,OAAO,IAAI,gBAAgB,CAAC,cAAc,EAAE,cAAc,EAAE,GAAG,CAAC,CAAC;IACnE,CAAC;IAED,MAAM,CAAC,QAAQ,CAAC,OAAe;QAC7B,OAAO,IAAI,gBAAgB,CAAC,OAAO,EAAE,gBAAgB,EAAE,GAAG,CAAC,CAAC;IAC9D,CAAC;CACF"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "locallytics",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.8",
|
|
4
4
|
"description": "Self-hosted, privacy-first analytics SDK for Next.js",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -11,11 +11,15 @@
|
|
|
11
11
|
"import": "./dist/index.js",
|
|
12
12
|
"default": "./dist/index.js"
|
|
13
13
|
},
|
|
14
|
-
"./schema.sql": "./src/db/schema.sql"
|
|
14
|
+
"./schema.sql": "./src/db/schema.sql",
|
|
15
|
+
"./schema-sqlite.sql": "./src/db/schema-sqlite.sql",
|
|
16
|
+
"./schema-mysql.sql": "./src/db/schema-mysql.sql"
|
|
15
17
|
},
|
|
16
18
|
"files": [
|
|
17
19
|
"dist",
|
|
18
|
-
"src/db/schema.sql"
|
|
20
|
+
"src/db/schema.sql",
|
|
21
|
+
"src/db/schema-sqlite.sql",
|
|
22
|
+
"src/db/schema-mysql.sql"
|
|
19
23
|
],
|
|
20
24
|
"scripts": {
|
|
21
25
|
"build": "tsc",
|
|
@@ -29,6 +33,8 @@
|
|
|
29
33
|
"privacy",
|
|
30
34
|
"nextjs",
|
|
31
35
|
"postgresql",
|
|
36
|
+
"mysql",
|
|
37
|
+
"sqlite",
|
|
32
38
|
"self-hosted"
|
|
33
39
|
],
|
|
34
40
|
"author": "",
|
|
@@ -40,10 +46,24 @@
|
|
|
40
46
|
"next": ">=13.0.0",
|
|
41
47
|
"react": ">=18.0.0"
|
|
42
48
|
},
|
|
49
|
+
"peerDependenciesMeta": {
|
|
50
|
+
"better-sqlite3": {
|
|
51
|
+
"optional": true
|
|
52
|
+
},
|
|
53
|
+
"mysql2": {
|
|
54
|
+
"optional": true
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
"optionalDependencies": {
|
|
58
|
+
"better-sqlite3": "^11.0.0",
|
|
59
|
+
"mysql2": "^3.9.0"
|
|
60
|
+
},
|
|
43
61
|
"devDependencies": {
|
|
62
|
+
"@types/better-sqlite3": "^7.6.8",
|
|
44
63
|
"@types/node": "^20.10.0",
|
|
45
64
|
"@types/pg": "^8.10.9",
|
|
46
65
|
"@types/react": "^18.2.0",
|
|
66
|
+
"mysql2": "^3.16.1",
|
|
47
67
|
"typescript": "^5.3.0",
|
|
48
68
|
"vitest": "^1.1.0"
|
|
49
69
|
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
-- Locallytics MySQL Schema
|
|
2
|
+
|
|
3
|
+
CREATE TABLE IF NOT EXISTS locallytics_pageviews (
|
|
4
|
+
id INT AUTO_INCREMENT PRIMARY KEY,
|
|
5
|
+
session_id VARCHAR(255) NOT NULL,
|
|
6
|
+
page_url TEXT NOT NULL,
|
|
7
|
+
referrer TEXT,
|
|
8
|
+
user_agent VARCHAR(512) NOT NULL,
|
|
9
|
+
screen_width INT NOT NULL,
|
|
10
|
+
screen_height INT NOT NULL,
|
|
11
|
+
ip_hash VARCHAR(64),
|
|
12
|
+
timestamp DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
13
|
+
INDEX idx_pageviews_timestamp (timestamp DESC),
|
|
14
|
+
INDEX idx_pageviews_session (session_id),
|
|
15
|
+
INDEX idx_pageviews_page_url (page_url(255)),
|
|
16
|
+
INDEX idx_pageviews_referrer (referrer(255))
|
|
17
|
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
-- Locallytics SQLite Schema
|
|
2
|
+
|
|
3
|
+
CREATE TABLE IF NOT EXISTS locallytics_pageviews (
|
|
4
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
5
|
+
session_id TEXT NOT NULL,
|
|
6
|
+
page_url TEXT NOT NULL,
|
|
7
|
+
referrer TEXT,
|
|
8
|
+
user_agent TEXT NOT NULL,
|
|
9
|
+
screen_width INTEGER NOT NULL,
|
|
10
|
+
screen_height INTEGER NOT NULL,
|
|
11
|
+
ip_hash TEXT,
|
|
12
|
+
timestamp TEXT NOT NULL DEFAULT (datetime('now'))
|
|
13
|
+
);
|
|
14
|
+
|
|
15
|
+
-- Index for time-based queries (most common)
|
|
16
|
+
CREATE INDEX IF NOT EXISTS idx_pageviews_timestamp
|
|
17
|
+
ON locallytics_pageviews(timestamp DESC);
|
|
18
|
+
|
|
19
|
+
-- Index for session lookups
|
|
20
|
+
CREATE INDEX IF NOT EXISTS idx_pageviews_session
|
|
21
|
+
ON locallytics_pageviews(session_id);
|
|
22
|
+
|
|
23
|
+
-- Index for page URL grouping
|
|
24
|
+
CREATE INDEX IF NOT EXISTS idx_pageviews_page_url
|
|
25
|
+
ON locallytics_pageviews(page_url);
|
|
26
|
+
|
|
27
|
+
-- Index for referrer grouping
|
|
28
|
+
CREATE INDEX IF NOT EXISTS idx_pageviews_referrer
|
|
29
|
+
ON locallytics_pageviews(referrer);
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"AnalyticsGrabber.d.ts","sourceRoot":"","sources":["../../src/client/AnalyticsGrabber.tsx"],"names":[],"mappings":"AAKA,UAAU,qBAAqB;IAC7B,oDAAoD;IACpD,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,gBAAgB,CAAC,EAC/B,QAA2B,GAC5B,EAAE,qBAAqB,GAAG,IAAI,CAuD9B"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"AnalyticsGrabber.js","sourceRoot":"","sources":["../../src/client/AnalyticsGrabber.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAOvC;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,UAAU,gBAAgB,CAAC,EAC/B,QAAQ,GAAG,gBAAgB,GACL;IACtB,MAAM,UAAU,GAAG,MAAM,CAAiB,IAAI,CAAC,CAAC;IAChD,MAAM,WAAW,GAAG,MAAM,CAAS,EAAE,CAAC,CAAC;IAEvC,SAAS,CAAC,GAAG,EAAE;QACb,qBAAqB;QACrB,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,QAAQ,CAAC,CAAC;QACtC,UAAU,CAAC,OAAO,GAAG,OAAO,CAAC;QAE7B,yBAAyB;QACzB,OAAO,CAAC,aAAa,EAAE,CAAC;QACxB,WAAW,CAAC,OAAO,GAAG,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAE/C,yCAAyC;QACzC,MAAM,cAAc,GAAG,GAAS,EAAE;YAChC,IAAI,MAAM,CAAC,QAAQ,CAAC,QAAQ,KAAK,WAAW,CAAC,OAAO,EAAE,CAAC;gBACrD,WAAW,CAAC,OAAO,GAAG,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC;gBAC/C,OAAO,CAAC,aAAa,EAAE,CAAC;YAC1B,CAAC;QACH,CAAC,CAAC;QAEF,MAAM,CAAC,gBAAgB,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC;QAEpD,qDAAqD;QACrD,6CAA6C;QAC7C,IAAI,QAAQ,GAA4B,IAAI,CAAC;QAE7C,MAAM,kBAAkB,GAAG,GAAS,EAAE;YACpC,IAAI,MAAM,CAAC,QAAQ,CAAC,QAAQ,KAAK,WAAW,CAAC,OAAO,EAAE,CAAC;gBACrD,WAAW,CAAC,OAAO,GAAG,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC;gBAC/C,OAAO,CAAC,aAAa,EAAE,CAAC;YAC1B,CAAC;QACH,CAAC,CAAC;QAEF,iEAAiE;QACjE,QAAQ,GAAG,IAAI,gBAAgB,CAAC,GAAG,EAAE;YACnC,4CAA4C;YAC5C,qBAAqB,CAAC,kBAAkB,CAAC,CAAC;QAC5C,CAAC,CAAC,CAAC;QAEH,QAAQ,CAAC,OAAO,CAAC,QAAQ,EAAE;YACzB,OAAO,EAAE,IAAI;YACb,SAAS,EAAE,IAAI;SAChB,CAAC,CAAC;QAEH,UAAU;QACV,OAAO,GAAG,EAAE;YACV,MAAM,CAAC,mBAAmB,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC;YACvD,QAAQ,EAAE,UAAU,EAAE,CAAC;YACvB,OAAO,CAAC,OAAO,EAAE,CAAC;QACpB,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;IAEf,iCAAiC;IACjC,OAAO,IAAI,CAAC;AACd,CAAC"}
|