@mcp-fe/event-tracker 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/README.md ADDED
@@ -0,0 +1,11 @@
1
+ # event-tracker
2
+
3
+ This library was generated with [Nx](https://nx.dev).
4
+
5
+ ## Building
6
+
7
+ Run `nx build event-tracker` to build the library.
8
+
9
+ ## Running unit tests
10
+
11
+ Run `nx test event-tracker` to execute the unit tests via [Vitest](https://vitest.dev/).
@@ -0,0 +1,22 @@
1
+ import baseConfig from '../../eslint.config.mjs';
2
+
3
+ export default [
4
+ ...baseConfig,
5
+ {
6
+ files: ['**/*.json'],
7
+ rules: {
8
+ '@nx/dependency-checks': [
9
+ 'error',
10
+ {
11
+ ignoredFiles: [
12
+ '{projectRoot}/eslint.config.{js,cjs,mjs,ts,cts,mts}',
13
+ '{projectRoot}/vite.config.{js,ts,mjs,mts}',
14
+ ],
15
+ },
16
+ ],
17
+ },
18
+ languageOptions: {
19
+ parser: await import('jsonc-eslint-parser'),
20
+ },
21
+ },
22
+ ];
package/package.json ADDED
@@ -0,0 +1,12 @@
1
+ {
2
+ "name": "@mcp-fe/event-tracker",
3
+ "version": "0.0.1",
4
+ "private": false,
5
+ "type": "module",
6
+ "main": "./index.js",
7
+ "types": "./index.d.ts",
8
+ "dependencies": {},
9
+ "publishConfig": {
10
+ "access": "public"
11
+ }
12
+ }
package/project.json ADDED
@@ -0,0 +1,9 @@
1
+ {
2
+ "name": "event-tracker",
3
+ "$schema": "../../node_modules/nx/schemas/project-schema.json",
4
+ "sourceRoot": "libs/event-tracker/src",
5
+ "projectType": "library",
6
+ "tags": [],
7
+ "// targets": "to see all targets run: nx show project event-tracker --web",
8
+ "targets": {}
9
+ }
package/src/index.ts ADDED
@@ -0,0 +1 @@
1
+ export * from './lib/event-tracker';
@@ -0,0 +1,102 @@
1
+ import { queryEvents, type UserEvent, WorkerClient } from '@mcp-fe/mcp-worker';
2
+ export type { UserEvent } from '@mcp-fe/mcp-worker';
3
+
4
+
5
+ export interface UserEventData {
6
+ type: 'navigation' | 'click' | 'input' | 'custom';
7
+ path?: string;
8
+ from?: string;
9
+ to?: string;
10
+ element?: string;
11
+ elementId?: string;
12
+ elementClass?: string;
13
+ elementText?: string;
14
+ metadata?: Record<string, unknown>;
15
+ }
16
+
17
+ // Singleton client used by exported functions
18
+ const workerClient = new WorkerClient();
19
+
20
+ // Public API - thin wrappers around workerClient
21
+ export async function initEventTracker(registration?: ServiceWorkerRegistration): Promise<void> {
22
+ return workerClient.init(registration);
23
+ }
24
+
25
+ export async function trackEvent(event: UserEventData): Promise<void> {
26
+ const userEvent = { ...event, timestamp: Date.now() };
27
+ // use request to ensure the worker stored the event; mimic previous behavior
28
+ await workerClient.request('STORE_EVENT', { event: userEvent });
29
+ }
30
+
31
+ export async function getStoredEvents(): Promise<UserEvent[]> {
32
+ const res = await queryEvents();
33
+ return Array.isArray(res) ? res : [];
34
+ }
35
+
36
+ export async function getConnectionStatus(): Promise<boolean> {
37
+ return workerClient.getConnectionStatus();
38
+ }
39
+
40
+ export function setAuthToken(token: string): void {
41
+ workerClient.setAuthToken(token);
42
+ }
43
+
44
+ // Connection status subscription helpers
45
+ export function onConnectionStatus(cb: (connected: boolean) => void): void {
46
+ workerClient.onConnectionStatus(cb);
47
+ }
48
+
49
+ export function offConnectionStatus(cb: (connected: boolean) => void): void {
50
+ workerClient.offConnectionStatus(cb);
51
+ }
52
+
53
+ // Convenience helpers (kept outside for ergonomic API)
54
+ export async function trackNavigation(from: string, to: string, path?: string): Promise<void> {
55
+ return trackEvent({ type: 'navigation', from, to, path: path || to });
56
+ }
57
+
58
+ export async function trackClick(element: HTMLElement, path?: string, metadata?: Record<string, unknown>): Promise<void> {
59
+ const elementId = element.id || undefined;
60
+ const elementClass = element.className || undefined;
61
+ const elementText = element.textContent?.trim().substring(0, 100) || undefined;
62
+ const tagName = element.tagName.toLowerCase();
63
+
64
+ return trackEvent({
65
+ type: 'click',
66
+ element: tagName,
67
+ elementId,
68
+ elementClass,
69
+ elementText,
70
+ path: path || window.location.pathname,
71
+ metadata,
72
+ });
73
+ }
74
+
75
+ export async function trackInput(element: HTMLElement, value?: string, path?: string): Promise<void> {
76
+ const elementId = element.id || undefined;
77
+ const elementClass = element.className || undefined;
78
+ const tagName = element.tagName.toLowerCase();
79
+
80
+ return trackEvent({
81
+ type: 'input',
82
+ element: tagName,
83
+ elementId,
84
+ elementClass,
85
+ path: path || window.location.pathname,
86
+ metadata: {
87
+ valueLength: value?.length || 0,
88
+ value: value,
89
+ },
90
+ });
91
+ }
92
+
93
+ export async function trackCustom(eventName: string, metadata?: Record<string, unknown>, path?: string): Promise<void> {
94
+ return trackEvent({
95
+ type: 'custom',
96
+ path: path || window.location.pathname,
97
+ metadata: {
98
+ eventName,
99
+ ...metadata,
100
+ },
101
+ });
102
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,24 @@
1
+ {
2
+ "extends": "../../tsconfig.base.json",
3
+ "compilerOptions": {
4
+ "module": "commonjs",
5
+ "forceConsistentCasingInFileNames": true,
6
+ "strict": true,
7
+ "importHelpers": true,
8
+ "noImplicitOverride": true,
9
+ "noImplicitReturns": true,
10
+ "noFallthroughCasesInSwitch": true,
11
+ "noPropertyAccessFromIndexSignature": true,
12
+ "lib": ["esnext", "dom", "webworker"]
13
+ },
14
+ "files": [],
15
+ "include": [],
16
+ "references": [
17
+ {
18
+ "path": "./tsconfig.lib.json"
19
+ },
20
+ {
21
+ "path": "./tsconfig.spec.json"
22
+ }
23
+ ]
24
+ }
@@ -0,0 +1,25 @@
1
+ {
2
+ "extends": "./tsconfig.json",
3
+ "compilerOptions": {
4
+ "module": "esnext",
5
+ "outDir": "../../dist/out-tsc",
6
+ "declaration": true,
7
+ "types": ["node", "vite/client"]
8
+ },
9
+ "include": ["src/**/*.ts"],
10
+ "exclude": [
11
+ "vite.config.ts",
12
+ "vite.config.mts",
13
+ "vitest.config.ts",
14
+ "vitest.config.mts",
15
+ "src/**/*.test.ts",
16
+ "src/**/*.spec.ts",
17
+ "src/**/*.test.tsx",
18
+ "src/**/*.spec.tsx",
19
+ "src/**/*.test.js",
20
+ "src/**/*.spec.js",
21
+ "src/**/*.test.jsx",
22
+ "src/**/*.spec.jsx"
23
+ ],
24
+ "references": []
25
+ }
@@ -0,0 +1,28 @@
1
+ {
2
+ "extends": "./tsconfig.json",
3
+ "compilerOptions": {
4
+ "outDir": "../../dist/out-tsc",
5
+ "types": [
6
+ "vitest/globals",
7
+ "vitest/importMeta",
8
+ "vite/client",
9
+ "node",
10
+ "vitest"
11
+ ]
12
+ },
13
+ "include": [
14
+ "vite.config.ts",
15
+ "vite.config.mts",
16
+ "vitest.config.ts",
17
+ "vitest.config.mts",
18
+ "src/**/*.test.ts",
19
+ "src/**/*.spec.ts",
20
+ "src/**/*.test.tsx",
21
+ "src/**/*.spec.tsx",
22
+ "src/**/*.test.js",
23
+ "src/**/*.spec.js",
24
+ "src/**/*.test.jsx",
25
+ "src/**/*.spec.jsx",
26
+ "src/**/*.d.ts"
27
+ ]
28
+ }
@@ -0,0 +1,59 @@
1
+ /// <reference types='vitest' />
2
+ import { defineConfig } from 'vite';
3
+ import dts from 'vite-plugin-dts';
4
+ import * as path from 'path';
5
+ import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin';
6
+ import { nxCopyAssetsPlugin } from '@nx/vite/plugins/nx-copy-assets.plugin';
7
+
8
+ export default defineConfig(() => ({
9
+ root: import.meta.dirname,
10
+ cacheDir: '../../node_modules/.vite/libs/event-tracker',
11
+ plugins: [
12
+ nxViteTsPaths(),
13
+ nxCopyAssetsPlugin(['*.md']),
14
+ dts({
15
+ entryRoot: 'src',
16
+ tsconfigPath: path.join(import.meta.dirname, 'tsconfig.lib.json'),
17
+ pathsToAliases: false,
18
+ }),
19
+ ],
20
+ // Uncomment this if you are using workers.
21
+ // worker: {
22
+ // plugins: () => [ nxViteTsPaths() ],
23
+ // },
24
+ // Configuration for building your library.
25
+ // See: https://vite.dev/guide/build.html#library-mode
26
+ build: {
27
+ outDir: '../../dist/libs/event-tracker',
28
+ emptyOutDir: true,
29
+ reportCompressedSize: true,
30
+ commonjsOptions: {
31
+ transformMixedEsModules: true,
32
+ },
33
+ lib: {
34
+ // Could also be a dictionary or array of multiple entry points.
35
+ entry: 'src/index.ts',
36
+ name: 'event-tracker',
37
+ fileName: 'index',
38
+ // Change this to the formats you want to support.
39
+ // Don't forget to update your package.json as well.
40
+ formats: ['es' as const],
41
+ },
42
+ rollupOptions: {
43
+ // External packages that should not be bundled into your library.
44
+ external: [],
45
+ },
46
+ },
47
+ test: {
48
+ name: 'event-tracker',
49
+ watch: false,
50
+ globals: true,
51
+ environment: 'node',
52
+ include: ['{src,tests}/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
53
+ reporters: ['default'],
54
+ coverage: {
55
+ reportsDirectory: '../../coverage/libs/event-tracker',
56
+ provider: 'v8' as const,
57
+ },
58
+ },
59
+ }));