@supernal/interface 1.0.13 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/dist/cjs/src/index.js +18 -1
  2. package/dist/cjs/src/index.js.map +1 -1
  3. package/dist/cjs/src/tracking/SITrackingProvider.js +126 -0
  4. package/dist/cjs/src/tracking/SITrackingProvider.js.map +1 -0
  5. package/dist/cjs/src/tracking/hooks.js +233 -0
  6. package/dist/cjs/src/tracking/hooks.js.map +1 -0
  7. package/dist/cjs/src/tracking/index.js +67 -0
  8. package/dist/cjs/src/tracking/index.js.map +1 -0
  9. package/dist/cjs/src/tracking/tracker.js +289 -0
  10. package/dist/cjs/src/tracking/tracker.js.map +1 -0
  11. package/dist/esm/src/index.d.ts +3 -0
  12. package/dist/esm/src/index.d.ts.map +1 -1
  13. package/dist/esm/src/index.js +4 -0
  14. package/dist/esm/src/index.js.map +1 -1
  15. package/dist/esm/src/tracking/SITrackingProvider.d.ts +64 -0
  16. package/dist/esm/src/tracking/SITrackingProvider.d.ts.map +1 -0
  17. package/dist/esm/src/tracking/SITrackingProvider.js +82 -0
  18. package/dist/esm/src/tracking/SITrackingProvider.js.map +1 -0
  19. package/dist/esm/src/tracking/hooks.d.ts +112 -0
  20. package/dist/esm/src/tracking/hooks.d.ts.map +1 -0
  21. package/dist/esm/src/tracking/hooks.js +215 -0
  22. package/dist/esm/src/tracking/hooks.js.map +1 -0
  23. package/dist/esm/src/tracking/index.d.ts +48 -0
  24. package/dist/esm/src/tracking/index.d.ts.map +1 -0
  25. package/dist/esm/src/tracking/index.js +51 -0
  26. package/dist/esm/src/tracking/index.js.map +1 -0
  27. package/dist/esm/src/tracking/tracker.d.ts +121 -0
  28. package/dist/esm/src/tracking/tracker.d.ts.map +1 -0
  29. package/dist/esm/src/tracking/tracker.js +284 -0
  30. package/dist/esm/src/tracking/tracker.js.map +1 -0
  31. package/package.json +9 -4
@@ -0,0 +1,215 @@
1
+ /**
2
+ * SI Tracking React Hooks
3
+ *
4
+ * React hooks for integrating Supernal Interface tracking into components.
5
+ *
6
+ * @packageDocumentation
7
+ */
8
+ 'use client';
9
+ import { useCallback, useEffect, useRef, useContext, createContext } from 'react';
10
+ // Context for providing tracker instance
11
+ const SITrackerContext = createContext(null);
12
+ export const SITrackerProvider = SITrackerContext.Provider;
13
+ /**
14
+ * Get the tracker instance from context
15
+ */
16
+ export function useTracker() {
17
+ return useContext(SITrackerContext);
18
+ }
19
+ /**
20
+ * Hook to sync auth state with tracker
21
+ * Place this once in your app layout
22
+ *
23
+ * @example
24
+ * ```tsx
25
+ * function App() {
26
+ * const { user } = useAuth();
27
+ * useSITrackingInit(tracker, user?.id);
28
+ * return <div>...</div>;
29
+ * }
30
+ * ```
31
+ */
32
+ export function useSITrackingInit(tracker, userId) {
33
+ useEffect(() => {
34
+ if (tracker) {
35
+ tracker.setUserId(userId ?? null);
36
+ }
37
+ }, [tracker, userId]);
38
+ }
39
+ /**
40
+ * Hook for tracking click events
41
+ *
42
+ * @example
43
+ * ```tsx
44
+ * const trackClick = useTrackClick(tracker, 'PostCard');
45
+ * <button onClick={() => trackClick('like', postId)}>Like</button>
46
+ * ```
47
+ */
48
+ export function useTrackClick(tracker, componentId) {
49
+ return useCallback((action, targetId, metadata) => {
50
+ if (tracker) {
51
+ tracker.trackClick(componentId, action, targetId, metadata);
52
+ }
53
+ }, [tracker, componentId]);
54
+ }
55
+ /**
56
+ * Hook for tracking component views (impressions)
57
+ * Automatically tracks when component mounts
58
+ *
59
+ * @example
60
+ * ```tsx
61
+ * useTrackView(tracker, 'PostCard', post.id);
62
+ * ```
63
+ */
64
+ export function useTrackView(tracker, componentId, targetId, options) {
65
+ const { trackOnMount = true } = options ?? {};
66
+ useEffect(() => {
67
+ if (tracker && trackOnMount) {
68
+ tracker.trackView(componentId, targetId);
69
+ }
70
+ }, [tracker, componentId, targetId, trackOnMount]);
71
+ }
72
+ /**
73
+ * Hook for tracking engagement time on a specific target
74
+ * Automatically handles start/end of engagement session
75
+ *
76
+ * @example
77
+ * ```tsx
78
+ * const { recordInteraction } = useTrackEngagement(tracker, post.id);
79
+ * <button onClick={recordInteraction}>Interact</button>
80
+ * ```
81
+ */
82
+ export function useTrackEngagement(tracker, targetId, componentId = 'Content') {
83
+ const engagementStarted = useRef(false);
84
+ useEffect(() => {
85
+ if (!tracker || !targetId)
86
+ return;
87
+ // Start engagement tracking
88
+ tracker.startEngagement(targetId);
89
+ engagementStarted.current = true;
90
+ return () => {
91
+ // End engagement tracking on unmount
92
+ if (engagementStarted.current && tracker) {
93
+ tracker.endEngagement(targetId, componentId);
94
+ engagementStarted.current = false;
95
+ }
96
+ };
97
+ }, [tracker, targetId, componentId]);
98
+ const recordInteraction = useCallback(() => {
99
+ if (tracker) {
100
+ tracker.recordEngagementInteraction(targetId);
101
+ }
102
+ }, [tracker, targetId]);
103
+ return { recordInteraction };
104
+ }
105
+ /**
106
+ * Hook for tracking scroll depth in feed
107
+ * Attach to a scrollable container
108
+ *
109
+ * @example
110
+ * ```tsx
111
+ * const { handleScroll, resetScroll } = useTrackScrollDepth(tracker);
112
+ * <div onScroll={handleScroll}>...</div>
113
+ * ```
114
+ */
115
+ export function useTrackScrollDepth(tracker, componentId = 'Feed') {
116
+ const handleScroll = useCallback((event) => {
117
+ if (!tracker)
118
+ return;
119
+ const target = event.currentTarget;
120
+ const scrollHeight = target.scrollHeight - target.clientHeight;
121
+ if (scrollHeight <= 0)
122
+ return;
123
+ const scrollPercent = Math.round((target.scrollTop / scrollHeight) * 100);
124
+ tracker.trackScrollDepth(scrollPercent, componentId);
125
+ }, [tracker, componentId]);
126
+ const resetScroll = useCallback(() => {
127
+ if (tracker) {
128
+ tracker.resetScrollTracking();
129
+ }
130
+ }, [tracker]);
131
+ // Reset on mount
132
+ useEffect(() => {
133
+ if (tracker) {
134
+ tracker.resetScrollTracking();
135
+ }
136
+ }, [tracker]);
137
+ return { handleScroll, resetScroll };
138
+ }
139
+ /**
140
+ * Hook for tracking intersection observer visibility
141
+ * Useful for tracking when components come into view in feed
142
+ *
143
+ * @example
144
+ * ```tsx
145
+ * const ref = useTrackVisibility(tracker, 'PostCard', post.id);
146
+ * <div ref={ref}>...</div>
147
+ * ```
148
+ */
149
+ export function useTrackVisibility(tracker, componentId, targetId, options) {
150
+ const { threshold = 0.5 } = options ?? {};
151
+ const hasTracked = useRef(false);
152
+ const observerRef = useRef(null);
153
+ const refCallback = useCallback((element) => {
154
+ // Cleanup previous observer
155
+ if (observerRef.current) {
156
+ observerRef.current.disconnect();
157
+ observerRef.current = null;
158
+ }
159
+ if (!element || !tracker)
160
+ return;
161
+ // Create new observer
162
+ observerRef.current = new IntersectionObserver((entries) => {
163
+ entries.forEach((entry) => {
164
+ if (entry.isIntersecting && !hasTracked.current) {
165
+ tracker.trackView(componentId, targetId);
166
+ hasTracked.current = true;
167
+ }
168
+ });
169
+ }, { threshold });
170
+ observerRef.current.observe(element);
171
+ }, [tracker, componentId, targetId, threshold]);
172
+ // Reset tracking flag when targetId changes
173
+ useEffect(() => {
174
+ hasTracked.current = false;
175
+ }, [targetId]);
176
+ // Cleanup on unmount
177
+ useEffect(() => {
178
+ return () => {
179
+ if (observerRef.current) {
180
+ observerRef.current.disconnect();
181
+ }
182
+ };
183
+ }, []);
184
+ return refCallback;
185
+ }
186
+ /**
187
+ * Create a component-specific tracking hook factory
188
+ *
189
+ * @example
190
+ * ```typescript
191
+ * // Define your actions
192
+ * type PostActions = 'like' | 'unlike' | 'share' | 'bookmark';
193
+ *
194
+ * // Create hooks for PostCard
195
+ * export function usePostCardTracking(tracker: SITracker<PostActions>, postId: string) {
196
+ * const trackClick = useTrackClick(tracker, 'PostCard');
197
+ * const visibilityRef = useTrackVisibility(tracker, 'PostCard', postId);
198
+ *
199
+ * return {
200
+ * trackLike: () => trackClick('like', postId),
201
+ * trackShare: () => trackClick('share', postId),
202
+ * visibilityRef,
203
+ * };
204
+ * }
205
+ * ```
206
+ */
207
+ export function createComponentTrackingHook(componentId, factory) {
208
+ return function useComponentTracking(tracker, targetId) {
209
+ const trackClick = useTrackClick(tracker, componentId);
210
+ if (!tracker)
211
+ return null;
212
+ return factory(trackClick, tracker, targetId);
213
+ };
214
+ }
215
+ //# sourceMappingURL=hooks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks.js","sourceRoot":"","sources":["../../../../src/tracking/hooks.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Supernal Interface Tracking Module
3
+ *
4
+ * Analytics and interaction tracking for SI-enabled applications.
5
+ * Automatically batches events, handles offline scenarios, and provides
6
+ * React hooks for easy integration.
7
+ *
8
+ * @packageDocumentation
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * // Create a tracker
13
+ * import { createTracker, TrackingProvider, useTrackClick } from '@supernal/interface/tracking';
14
+ *
15
+ * const tracker = createTracker({
16
+ * endpoint: '/api/v1/analytics',
17
+ * batchSize: 10,
18
+ * debug: process.env.NODE_ENV === 'development',
19
+ * });
20
+ *
21
+ * // Provide to React tree
22
+ * function App() {
23
+ * const { user } = useAuth();
24
+ * return (
25
+ * <TrackingProvider tracker={tracker} userId={user?.id}>
26
+ * <YourApp />
27
+ * </TrackingProvider>
28
+ * );
29
+ * }
30
+ *
31
+ * // Use in components
32
+ * function PostCard({ post }) {
33
+ * const tracker = useTracker();
34
+ * const trackClick = useTrackClick(tracker, 'PostCard');
35
+ * const visibilityRef = useTrackVisibility(tracker, 'PostCard', post.id);
36
+ *
37
+ * return (
38
+ * <div ref={visibilityRef}>
39
+ * <button onClick={() => trackClick('like', post.id)}>Like</button>
40
+ * </div>
41
+ * );
42
+ * }
43
+ * ```
44
+ */
45
+ export { SITracker, createTracker, type SITrackerConfig, type SIInteraction, type SIBaseAction, } from './tracker';
46
+ export { SITrackerProvider, useTracker, useSITrackingInit, useTrackClick, useTrackView, useTrackEngagement, useTrackScrollDepth, useTrackVisibility, createComponentTrackingHook, } from './hooks';
47
+ export { TrackingProvider, withTracking, type SITrackingProviderProps } from './SITrackingProvider';
48
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/tracking/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AAGH,OAAO,EACL,SAAS,EACT,aAAa,EACb,KAAK,eAAe,EACpB,KAAK,aAAa,EAClB,KAAK,YAAY,GAClB,MAAM,WAAW,CAAC;AAGnB,OAAO,EACL,iBAAiB,EACjB,UAAU,EACV,iBAAiB,EACjB,aAAa,EACb,YAAY,EACZ,kBAAkB,EAClB,mBAAmB,EACnB,kBAAkB,EAClB,2BAA2B,GAC5B,MAAM,SAAS,CAAC;AAGjB,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,KAAK,uBAAuB,EAAE,MAAM,sBAAsB,CAAC"}
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Supernal Interface Tracking Module
3
+ *
4
+ * Analytics and interaction tracking for SI-enabled applications.
5
+ * Automatically batches events, handles offline scenarios, and provides
6
+ * React hooks for easy integration.
7
+ *
8
+ * @packageDocumentation
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * // Create a tracker
13
+ * import { createTracker, TrackingProvider, useTrackClick } from '@supernal/interface/tracking';
14
+ *
15
+ * const tracker = createTracker({
16
+ * endpoint: '/api/v1/analytics',
17
+ * batchSize: 10,
18
+ * debug: process.env.NODE_ENV === 'development',
19
+ * });
20
+ *
21
+ * // Provide to React tree
22
+ * function App() {
23
+ * const { user } = useAuth();
24
+ * return (
25
+ * <TrackingProvider tracker={tracker} userId={user?.id}>
26
+ * <YourApp />
27
+ * </TrackingProvider>
28
+ * );
29
+ * }
30
+ *
31
+ * // Use in components
32
+ * function PostCard({ post }) {
33
+ * const tracker = useTracker();
34
+ * const trackClick = useTrackClick(tracker, 'PostCard');
35
+ * const visibilityRef = useTrackVisibility(tracker, 'PostCard', post.id);
36
+ *
37
+ * return (
38
+ * <div ref={visibilityRef}>
39
+ * <button onClick={() => trackClick('like', post.id)}>Like</button>
40
+ * </div>
41
+ * );
42
+ * }
43
+ * ```
44
+ */
45
+ // Core tracker
46
+ export { SITracker, createTracker, } from './tracker.js';
47
+ // React hooks
48
+ export { SITrackerProvider, useTracker, useSITrackingInit, useTrackClick, useTrackView, useTrackEngagement, useTrackScrollDepth, useTrackVisibility, createComponentTrackingHook, } from './hooks.js';
49
+ // React provider component
50
+ export { TrackingProvider, withTracking } from './SITrackingProvider.js';
51
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/tracking/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AAEH,eAAe;AACf,OAAO,EACL,SAAS,EACT,aAAa,GAId,MAAM,WAAW,CAAC;AAEnB,cAAc;AACd,OAAO,EACL,iBAAiB,EACjB,UAAU,EACV,iBAAiB,EACjB,aAAa,EACb,YAAY,EACZ,kBAAkB,EAClB,mBAAmB,EACnB,kBAAkB,EAClB,2BAA2B,GAC5B,MAAM,SAAS,CAAC;AAEjB,2BAA2B;AAC3B,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAgC,MAAM,sBAAsB,CAAC"}
@@ -0,0 +1,121 @@
1
+ /**
2
+ * Supernal Interface Interaction Tracking
3
+ *
4
+ * Tracks user interactions with SI components for analytics and AI analysis.
5
+ * Batches events to minimize network requests and handles offline gracefully.
6
+ *
7
+ * @packageDocumentation
8
+ */
9
+ /**
10
+ * Base action types for tracking
11
+ * Apps can extend these with custom actions via generics
12
+ */
13
+ export type SIBaseAction = 'view' | 'click' | 'expand' | 'collapse' | 'copy' | 'share' | 'like' | 'unlike' | 'bookmark' | 'unbookmark' | 'submit' | 'helpful' | 'challenge' | 'navigate' | 'scroll' | 'refresh' | 'search';
14
+ /**
15
+ * Interaction event structure
16
+ */
17
+ export interface SIInteraction<TAction extends string = SIBaseAction> {
18
+ /** Component that triggered the event */
19
+ componentId: string;
20
+ /** Action performed */
21
+ action: TAction;
22
+ /** Target entity ID (post, user, etc.) */
23
+ targetId?: string;
24
+ /** Additional event metadata */
25
+ metadata?: Record<string, unknown>;
26
+ /** Client-side timestamp */
27
+ timestamp: number;
28
+ /** Session identifier */
29
+ sessionId: string;
30
+ }
31
+ /**
32
+ * Tracker configuration options
33
+ */
34
+ export interface SITrackerConfig {
35
+ /** API endpoint for logging events (default: '/api/v1/analytics') */
36
+ endpoint?: string;
37
+ /** Maximum events before auto-flush (default: 10) */
38
+ batchSize?: number;
39
+ /** Milliseconds between auto-flushes (default: 5000) */
40
+ flushIntervalMs?: number;
41
+ /** Minimum engagement time to track (default: 3000) */
42
+ minEngagementMs?: number;
43
+ /** Scroll depth debounce (default: 500) */
44
+ scrollDebounceMs?: number;
45
+ /** Enable debug logging (default: false) */
46
+ debug?: boolean;
47
+ /** Custom fetch implementation for testing */
48
+ customFetch?: typeof fetch;
49
+ }
50
+ /**
51
+ * SI Tracker - Core tracking class
52
+ *
53
+ * @example
54
+ * ```typescript
55
+ * const tracker = new SITracker({ endpoint: '/api/analytics' });
56
+ * tracker.track('PostCard', 'view', 'post-123');
57
+ * ```
58
+ */
59
+ export declare class SITracker<TAction extends string = SIBaseAction> {
60
+ private queue;
61
+ private sessionId;
62
+ private flushInterval;
63
+ private engagementSessions;
64
+ private scrollState;
65
+ private isClient;
66
+ private userId;
67
+ private config;
68
+ constructor(config?: SITrackerConfig);
69
+ /** Generate a unique session ID */
70
+ private generateSessionId;
71
+ /** Log debug message */
72
+ private log;
73
+ /** Set the current user ID for tracking */
74
+ setUserId(userId: string | null): void;
75
+ /** Get current session ID */
76
+ getSessionId(): string;
77
+ /** Get queue length (for testing) */
78
+ getQueueLength(): number;
79
+ /**
80
+ * Track an interaction
81
+ */
82
+ track(componentId: string, action: TAction, targetId?: string, metadata?: Record<string, unknown>): void;
83
+ /** Alias for track - for click events */
84
+ trackClick(componentId: string, action: TAction, targetId?: string, metadata?: Record<string, unknown>): void;
85
+ /** Track view (impression) of a component */
86
+ trackView(componentId: string, targetId?: string): void;
87
+ /** Start engagement tracking for a target */
88
+ startEngagement(targetId: string): void;
89
+ /** Record an interaction during engagement */
90
+ recordEngagementInteraction(targetId: string): void;
91
+ /** Update scroll depth for engagement session */
92
+ updateEngagementScrollDepth(targetId: string, depth: number): void;
93
+ /** End engagement tracking and log the session */
94
+ endEngagement(targetId: string, componentId?: string): void;
95
+ /** Track scroll depth in feed */
96
+ trackScrollDepth(depth: number, componentId?: string): void;
97
+ /** Reset scroll tracking (e.g., on page navigation) */
98
+ resetScrollTracking(): void;
99
+ /** Start periodic flush interval */
100
+ private startFlushInterval;
101
+ /** Stop flush interval */
102
+ private stopFlushInterval;
103
+ /** Setup beforeunload handler to flush remaining events */
104
+ private setupBeforeUnload;
105
+ /** Flush queued events to the API */
106
+ flush(): Promise<void>;
107
+ /** Flush using sendBeacon (for unload events) */
108
+ private flushWithBeacon;
109
+ /** Cleanup (for testing or unmounting) */
110
+ destroy(): void;
111
+ }
112
+ /**
113
+ * Create a singleton tracker instance
114
+ *
115
+ * @example
116
+ * ```typescript
117
+ * export const tracker = createTracker({ endpoint: '/api/analytics' });
118
+ * ```
119
+ */
120
+ export declare function createTracker<TAction extends string = SIBaseAction>(config?: SITrackerConfig): SITracker<TAction>;
121
+ //# sourceMappingURL=tracker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tracker.d.ts","sourceRoot":"","sources":["../../../../src/tracking/tracker.ts"],"names":[],"mappings":"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"}