@stacksjs/ts-analytics 0.1.6
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/CHANGELOG.md +68 -0
- package/LICENSE.md +21 -0
- package/README.md +361 -0
- package/bin/cli.ts +169 -0
- package/dist/Analytics.d.ts +558 -0
- package/dist/api.d.ts +109 -0
- package/dist/batching.d.ts +93 -0
- package/dist/chunk-2mx7fq49.js +4 -0
- package/dist/chunk-3z29508k.js +204 -0
- package/dist/chunk-deephkz6.js +56 -0
- package/dist/chunk-j261vgyp.js +305 -0
- package/dist/chunk-xga17tz7.js +207 -0
- package/dist/config.d.ts +132 -0
- package/dist/dashboard/components/index.d.ts +80 -0
- package/dist/dashboard/composables/useAnalytics.d.ts +99 -0
- package/dist/dashboard/index.d.ts +110 -0
- package/dist/dashboard/types/index.d.ts +144 -0
- package/dist/dashboard/utils/index.d.ts +81 -0
- package/dist/dynamodb.d.ts +86 -0
- package/dist/funnels.d.ts +104 -0
- package/dist/geolocation.d.ts +96 -0
- package/dist/index.d.ts +371 -0
- package/dist/index.js +10211 -0
- package/dist/infrastructure/cdk.d.ts +60 -0
- package/dist/infrastructure/cloudformation.d.ts +44 -0
- package/dist/infrastructure/index.d.ts +45 -0
- package/dist/infrastructure/setup.d.ts +133 -0
- package/dist/integrations/cloudflare.d.ts +76 -0
- package/dist/integrations/hono.d.ts +60 -0
- package/dist/integrations/index.d.ts +24 -0
- package/dist/integrations/nuxt.d.ts +7 -0
- package/dist/integrations/nuxt.js +42 -0
- package/dist/integrations/runtime/use-ts-analytics.d.ts +18 -0
- package/dist/integrations/runtime/use-ts-analytics.js +17 -0
- package/dist/integrations/stx.d.ts +88 -0
- package/dist/integrations/stx.js +18 -0
- package/dist/lib/crypto-random.d.ts +4 -0
- package/dist/lib/salt.d.ts +16 -0
- package/dist/local.d.ts +56 -0
- package/dist/model-connector.d.ts +145 -0
- package/dist/models/AggregatedStats.d.ts +9 -0
- package/dist/models/CampaignStats.d.ts +9 -0
- package/dist/models/Conversion.d.ts +11 -0
- package/dist/models/CustomEvent.d.ts +11 -0
- package/dist/models/DeviceStats.d.ts +9 -0
- package/dist/models/EventStats.d.ts +9 -0
- package/dist/models/GeoStats.d.ts +9 -0
- package/dist/models/Goal.d.ts +9 -0
- package/dist/models/GoalStats.d.ts +9 -0
- package/dist/models/PageStats.d.ts +11 -0
- package/dist/models/PageView.d.ts +13 -0
- package/dist/models/RealtimeStats.d.ts +9 -0
- package/dist/models/ReferrerStats.d.ts +9 -0
- package/dist/models/Session.d.ts +11 -0
- package/dist/models/Site.d.ts +11 -0
- package/dist/models/index.d.ts +28 -0
- package/dist/models/types.d.ts +60 -0
- package/dist/sqs-buffering.d.ts +243 -0
- package/dist/stacks-integration.d.ts +159 -0
- package/dist/tracking-script.d.ts +71 -0
- package/dist/tracking.d.ts +17 -0
- package/dist/tracking.js +26 -0
- package/dist/types.d.ts +595 -0
- package/dist/utils/geolocation.d.ts +111 -0
- package/dist/utils/user-agent.d.ts +17 -0
- package/dist/version.d.ts +7 -0
- package/package.json +119 -0
- package/src/Analytics.ts +3349 -0
- package/src/api.ts +1286 -0
- package/src/assets/crosswind.css +2220 -0
- package/src/batching.ts +452 -0
- package/src/components/dashboard/index.ts +18 -0
- package/src/config.ts +456 -0
- package/src/dashboard/Dashboard.stx +1517 -0
- package/src/dashboard/components/AlertCard.stx +177 -0
- package/src/dashboard/components/AnalyticsDashboard.stx +354 -0
- package/src/dashboard/components/AnimatedNumber.stx +86 -0
- package/src/dashboard/components/BarChart.stx +220 -0
- package/src/dashboard/components/BrowserBreakdown.stx +98 -0
- package/src/dashboard/components/BrowsersTable.stx +125 -0
- package/src/dashboard/components/CampaignBreakdown.stx +163 -0
- package/src/dashboard/components/CampaignTable.stx +238 -0
- package/src/dashboard/components/CountryList.stx +101 -0
- package/src/dashboard/components/DataTable.stx +226 -0
- package/src/dashboard/components/DateRangePicker.stx +77 -0
- package/src/dashboard/components/DeviceBreakdown.stx +94 -0
- package/src/dashboard/components/DevicesTable.stx +163 -0
- package/src/dashboard/components/DonutChart.stories.ts +55 -0
- package/src/dashboard/components/DonutChart.stx +157 -0
- package/src/dashboard/components/EmptyState.stx +90 -0
- package/src/dashboard/components/EngagementMetrics.stx +183 -0
- package/src/dashboard/components/EventsSection.stx +192 -0
- package/src/dashboard/components/FilterBar.stx +104 -0
- package/src/dashboard/components/FullAnalyticsDashboard.stx +455 -0
- package/src/dashboard/components/FunnelChart.stx +142 -0
- package/src/dashboard/components/GeoTable.stx +337 -0
- package/src/dashboard/components/GoalsPanel.stx +109 -0
- package/src/dashboard/components/Header.stx +39 -0
- package/src/dashboard/components/HeatmapChart.stx +140 -0
- package/src/dashboard/components/LiveActivityFeed.stx +172 -0
- package/src/dashboard/components/MetricComparison.stx +106 -0
- package/src/dashboard/components/MiniStats.stx +96 -0
- package/src/dashboard/components/OSBreakdown.stx +124 -0
- package/src/dashboard/components/PageDetailCard.stx +102 -0
- package/src/dashboard/components/PagesTable.stx +127 -0
- package/src/dashboard/components/ProgressRing.stx +89 -0
- package/src/dashboard/components/RealtimeCounter.stories.ts +45 -0
- package/src/dashboard/components/RealtimeCounter.stx +46 -0
- package/src/dashboard/components/ReferrersTable.stx +180 -0
- package/src/dashboard/components/SparklineChart.stx +160 -0
- package/src/dashboard/components/StatCard.stories.ts +58 -0
- package/src/dashboard/components/StatCard.stx +90 -0
- package/src/dashboard/components/SummaryStats.stx +81 -0
- package/src/dashboard/components/TabNav.stx +66 -0
- package/src/dashboard/components/ThemeSwitcher.stx +124 -0
- package/src/dashboard/components/TimeSeriesChart.stx +106 -0
- package/src/dashboard/components/TopList.stories.ts +58 -0
- package/src/dashboard/components/TopList.stx +74 -0
- package/src/dashboard/components/TrendIndicator.stx +84 -0
- package/src/dashboard/components/heatmap/ClickHeatmap.stx +264 -0
- package/src/dashboard/components/heatmap/ElementClickList.stx +125 -0
- package/src/dashboard/components/heatmap/HeatmapControls.stx +125 -0
- package/src/dashboard/components/heatmap/HeatmapLegend.stx +69 -0
- package/src/dashboard/components/heatmap/PageHeatmap.stx +264 -0
- package/src/dashboard/components/heatmap/ScrollHeatmap.stx +127 -0
- package/src/dashboard/components/heatmap/index.ts +12 -0
- package/src/dashboard/components/index.ts +86 -0
- package/src/dashboard/composables/useAnalytics.ts +465 -0
- package/src/dashboard/demo/DemoApp.stx +370 -0
- package/src/dashboard/demo/index.ts +8 -0
- package/src/dashboard/demo/mockData.ts +234 -0
- package/src/dashboard/index.ts +117 -0
- package/src/dashboard/stx-shim.d.ts +4 -0
- package/src/dashboard/types/index.ts +203 -0
- package/src/dashboard/utils/index.ts +426 -0
- package/src/dynamodb.ts +344 -0
- package/src/funnels.ts +534 -0
- package/src/geolocation.ts +515 -0
- package/src/handlers/alerts.ts +328 -0
- package/src/handlers/annotations.ts +128 -0
- package/src/handlers/api-keys.ts +240 -0
- package/src/handlers/auth.ts +1020 -0
- package/src/handlers/authz.ts +137 -0
- package/src/handlers/collect.ts +724 -0
- package/src/handlers/data.ts +625 -0
- package/src/handlers/experiments.ts +138 -0
- package/src/handlers/funnels.ts +216 -0
- package/src/handlers/goals.ts +218 -0
- package/src/handlers/heatmaps.ts +272 -0
- package/src/handlers/index.ts +56 -0
- package/src/handlers/lib/read-cache.ts +63 -0
- package/src/handlers/misc.ts +486 -0
- package/src/handlers/oauth.ts +233 -0
- package/src/handlers/performance.ts +388 -0
- package/src/handlers/sessions.ts +413 -0
- package/src/handlers/sharing.ts +198 -0
- package/src/handlers/stats.ts +1368 -0
- package/src/handlers/team.ts +161 -0
- package/src/handlers/uptime.ts +283 -0
- package/src/handlers/views.ts +390 -0
- package/src/handlers/webhooks.ts +226 -0
- package/src/heatmap/index.ts +32 -0
- package/src/heatmap/tracking-script.ts +452 -0
- package/src/heatmap/types.ts +79 -0
- package/src/index.ts +387 -0
- package/src/infrastructure/cdk.ts +496 -0
- package/src/infrastructure/cloudformation.ts +595 -0
- package/src/infrastructure/index.ts +48 -0
- package/src/infrastructure/setup.ts +611 -0
- package/src/integrations/cloudflare.ts +732 -0
- package/src/integrations/hono.ts +589 -0
- package/src/integrations/index.ts +27 -0
- package/src/integrations/nuxt.ts +78 -0
- package/src/integrations/runtime/use-ts-analytics.ts +32 -0
- package/src/integrations/stx.ts +138 -0
- package/src/jobs/index.ts +127 -0
- package/src/lib/crypto-random.ts +41 -0
- package/src/lib/ddb-errors.ts +20 -0
- package/src/lib/dynamodb.ts +216 -0
- package/src/lib/email.ts +38 -0
- package/src/lib/ga-import.ts +471 -0
- package/src/lib/ga4-api.ts +244 -0
- package/src/lib/goals.ts +205 -0
- package/src/lib/index.ts +6 -0
- package/src/lib/ingest-counters.ts +123 -0
- package/src/lib/log.ts +36 -0
- package/src/lib/membership.ts +98 -0
- package/src/lib/plans.ts +90 -0
- package/src/lib/quota.ts +46 -0
- package/src/lib/rate-limit.ts +27 -0
- package/src/lib/rollups.ts +472 -0
- package/src/lib/salt.ts +97 -0
- package/src/lib/scheduler.ts +97 -0
- package/src/lib/significance.ts +66 -0
- package/src/lib/site-retention.ts +56 -0
- package/src/local.ts +360 -0
- package/src/model-connector.ts +616 -0
- package/src/models/AggregatedStats.ts +162 -0
- package/src/models/CampaignStats.ts +141 -0
- package/src/models/Conversion.ts +135 -0
- package/src/models/CustomEvent.ts +123 -0
- package/src/models/DeviceStats.ts +105 -0
- package/src/models/EventStats.ts +108 -0
- package/src/models/GeoStats.ts +112 -0
- package/src/models/Goal.ts +105 -0
- package/src/models/GoalStats.ts +106 -0
- package/src/models/PageStats.ts +152 -0
- package/src/models/PageView.ts +277 -0
- package/src/models/RealtimeStats.ts +96 -0
- package/src/models/ReferrerStats.ts +115 -0
- package/src/models/Session.ts +235 -0
- package/src/models/Site.ts +115 -0
- package/src/models/index.ts +50 -0
- package/src/models/orm/index.ts +2043 -0
- package/src/models/types.ts +71 -0
- package/src/router.ts +521 -0
- package/src/sqs-buffering.ts +806 -0
- package/src/stacks-integration.ts +527 -0
- package/src/tracking-script.ts +944 -0
- package/src/tracking.ts +27 -0
- package/src/types/analytics.ts +219 -0
- package/src/types/api.ts +75 -0
- package/src/types/bun-router.d.ts +15 -0
- package/src/types/dashboard.ts +62 -0
- package/src/types/index.ts +66 -0
- package/src/types/stx.d.ts +27 -0
- package/src/types/window.d.ts +101 -0
- package/src/types.ts +911 -0
- package/src/utils/cache.ts +148 -0
- package/src/utils/date.ts +118 -0
- package/src/utils/filters.ts +71 -0
- package/src/utils/geolocation.ts +323 -0
- package/src/utils/index.ts +9 -0
- package/src/utils/response.ts +180 -0
- package/src/utils/timezone-country.ts +242 -0
- package/src/utils/user-agent.ts +110 -0
- package/src/version.ts +7 -0
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
import type { CustomEvent, PageView, Session } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Generate a partition key with time-based sharding to avoid hot partitions
|
|
4
|
+
*
|
|
5
|
+
* For high-volume sites, we add a shard suffix based on the current minute
|
|
6
|
+
* to distribute writes across multiple partitions.
|
|
7
|
+
*
|
|
8
|
+
* Pattern: SITE#{siteId}#SHARD#{shardId}
|
|
9
|
+
*
|
|
10
|
+
* This helps with:
|
|
11
|
+
* - Distributing write throughput across partitions
|
|
12
|
+
* - Avoiding hot partition throttling
|
|
13
|
+
* - Supporting burst traffic patterns
|
|
14
|
+
*/
|
|
15
|
+
export declare function getShardedPartitionKey(siteId: string, shardCount?: number): string;
|
|
16
|
+
/**
|
|
17
|
+
* Generate partition key with random sharding for even distribution
|
|
18
|
+
*/
|
|
19
|
+
export declare function getRandomShardedPartitionKey(siteId: string, shardCount?: number): string;
|
|
20
|
+
/**
|
|
21
|
+
* Get all shard keys for a site (used for queries)
|
|
22
|
+
*/
|
|
23
|
+
export declare function getAllShardKeys(siteId: string, shardCount?: number): string[];
|
|
24
|
+
/**
|
|
25
|
+
* Generate CloudFormation resources for SQS-based buffering
|
|
26
|
+
*/
|
|
27
|
+
export declare function generateSQSResources(config: {
|
|
28
|
+
queueName: string
|
|
29
|
+
deadLetterQueueName?: string
|
|
30
|
+
visibilityTimeout?: number
|
|
31
|
+
messageRetention?: number
|
|
32
|
+
maxReceiveCount?: number
|
|
33
|
+
fifo?: boolean
|
|
34
|
+
}): Record<string, unknown>;
|
|
35
|
+
/**
|
|
36
|
+
* Create an SQS event producer using ts-cloud configuration
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* ```ts
|
|
40
|
+
* import { createAnalyticsProducer } from 'ts-analytics'
|
|
41
|
+
*
|
|
42
|
+
* // Uses queue URL from environment or cloud.config.ts
|
|
43
|
+
* const producer = await createAnalyticsProducer()
|
|
44
|
+
*
|
|
45
|
+
* // Or specify queue URL directly
|
|
46
|
+
* const producer = await createAnalyticsProducer({
|
|
47
|
+
* queueUrl: 'https://sqs.us-east-1.amazonaws.com/123456789/analytics-events',
|
|
48
|
+
* region: 'us-east-1',
|
|
49
|
+
* })
|
|
50
|
+
*
|
|
51
|
+
* // Send events
|
|
52
|
+
* await producer.sendEvent({
|
|
53
|
+
* type: 'pageview',
|
|
54
|
+
* siteId: 'my-site',
|
|
55
|
+
* timestamp: new Date().toISOString(),
|
|
56
|
+
* data: pageViewData,
|
|
57
|
+
* })
|
|
58
|
+
* ```
|
|
59
|
+
*/
|
|
60
|
+
export declare function createAnalyticsProducer(options?: {
|
|
61
|
+
queueUrl?: string
|
|
62
|
+
region?: string
|
|
63
|
+
}): Promise<SQSEventProducer>;
|
|
64
|
+
/**
|
|
65
|
+
* Check if SQS buffering is enabled based on configuration
|
|
66
|
+
*/
|
|
67
|
+
export declare function isSQSBufferingEnabled(): boolean;
|
|
68
|
+
// ============================================================================
|
|
69
|
+
// Default Configuration
|
|
70
|
+
// ============================================================================
|
|
71
|
+
export declare const defaultSQSConfig: SQSConfig;
|
|
72
|
+
// Re-export ts-cloud compatible types for convenience
|
|
73
|
+
export declare interface SQSRawMessage {
|
|
74
|
+
MessageId: string
|
|
75
|
+
ReceiptHandle: string
|
|
76
|
+
Body: string
|
|
77
|
+
Attributes?: Record<string, string>
|
|
78
|
+
MessageAttributes?: Record<string, unknown>
|
|
79
|
+
}
|
|
80
|
+
export declare interface QueueAttributes {
|
|
81
|
+
QueueUrl: string
|
|
82
|
+
QueueArn?: string
|
|
83
|
+
ApproximateNumberOfMessages?: string
|
|
84
|
+
ApproximateNumberOfMessagesNotVisible?: string
|
|
85
|
+
VisibilityTimeout?: string
|
|
86
|
+
MessageRetentionPeriod?: string
|
|
87
|
+
}
|
|
88
|
+
// ============================================================================
|
|
89
|
+
// Types
|
|
90
|
+
// ============================================================================
|
|
91
|
+
export declare interface SQSConfig {
|
|
92
|
+
queueUrl?: string
|
|
93
|
+
enabled: boolean
|
|
94
|
+
batchSize: number
|
|
95
|
+
maxMessagesPerInvocation: number
|
|
96
|
+
visibilityTimeout: number
|
|
97
|
+
messageRetention: number
|
|
98
|
+
deadLetterQueueUrl?: string
|
|
99
|
+
maxReceiveCount: number
|
|
100
|
+
}
|
|
101
|
+
export declare interface AnalyticsEvent {
|
|
102
|
+
type: 'pageview' | 'session' | 'event' | 'realtime'
|
|
103
|
+
siteId: string
|
|
104
|
+
timestamp: string
|
|
105
|
+
data: PageView | Session | CustomEvent | RealtimeUpdate
|
|
106
|
+
}
|
|
107
|
+
export declare interface RealtimeUpdate {
|
|
108
|
+
siteId: string
|
|
109
|
+
minute: string
|
|
110
|
+
path: string
|
|
111
|
+
visitorId: string
|
|
112
|
+
}
|
|
113
|
+
export declare interface SQSMessage {
|
|
114
|
+
events: AnalyticsEvent[]
|
|
115
|
+
batchId: string
|
|
116
|
+
timestamp: string
|
|
117
|
+
retryCount?: number
|
|
118
|
+
}
|
|
119
|
+
export declare interface SQSSendResult {
|
|
120
|
+
successful: number
|
|
121
|
+
failed: number
|
|
122
|
+
messageId?: string
|
|
123
|
+
}
|
|
124
|
+
export declare interface SQSClient {
|
|
125
|
+
sendMessage: (input: SQSSendMessageInput) => Promise<SQSSendMessageOutput>
|
|
126
|
+
sendMessageBatch: (input: SQSSendMessageBatchInput) => Promise<SQSSendMessageBatchOutput>
|
|
127
|
+
receiveMessage: (input: SQSReceiveMessageInput) => Promise<SQSReceiveMessageOutput>
|
|
128
|
+
deleteMessage: (input: SQSDeleteMessageInput) => Promise<void>
|
|
129
|
+
deleteMessageBatch: (input: SQSDeleteMessageBatchInput) => Promise<SQSDeleteMessageBatchOutput>
|
|
130
|
+
}
|
|
131
|
+
declare interface SQSSendMessageInput {
|
|
132
|
+
QueueUrl: string
|
|
133
|
+
MessageBody: string
|
|
134
|
+
MessageGroupId?: string
|
|
135
|
+
MessageDeduplicationId?: string
|
|
136
|
+
}
|
|
137
|
+
declare interface SQSSendMessageOutput {
|
|
138
|
+
MessageId?: string
|
|
139
|
+
}
|
|
140
|
+
declare interface SQSSendMessageBatchInput {
|
|
141
|
+
QueueUrl: string
|
|
142
|
+
Entries: Array<{
|
|
143
|
+
Id: string
|
|
144
|
+
MessageBody: string
|
|
145
|
+
MessageGroupId?: string
|
|
146
|
+
MessageDeduplicationId?: string
|
|
147
|
+
}>
|
|
148
|
+
}
|
|
149
|
+
declare interface SQSSendMessageBatchOutput {
|
|
150
|
+
Successful?: Array<{ Id: string, MessageId: string }>
|
|
151
|
+
Failed?: Array<{ Id: string, Code: string, Message: string }>
|
|
152
|
+
}
|
|
153
|
+
declare interface SQSReceiveMessageInput {
|
|
154
|
+
QueueUrl: string
|
|
155
|
+
MaxNumberOfMessages?: number
|
|
156
|
+
VisibilityTimeout?: number
|
|
157
|
+
WaitTimeSeconds?: number
|
|
158
|
+
}
|
|
159
|
+
declare interface SQSReceiveMessageOutput {
|
|
160
|
+
Messages?: Array<{
|
|
161
|
+
MessageId: string
|
|
162
|
+
ReceiptHandle: string
|
|
163
|
+
Body: string
|
|
164
|
+
}>
|
|
165
|
+
}
|
|
166
|
+
declare interface SQSDeleteMessageInput {
|
|
167
|
+
QueueUrl: string
|
|
168
|
+
ReceiptHandle: string
|
|
169
|
+
}
|
|
170
|
+
declare interface SQSDeleteMessageBatchInput {
|
|
171
|
+
QueueUrl: string
|
|
172
|
+
Entries: Array<{
|
|
173
|
+
Id: string
|
|
174
|
+
ReceiptHandle: string
|
|
175
|
+
}>
|
|
176
|
+
}
|
|
177
|
+
declare interface SQSDeleteMessageBatchOutput {
|
|
178
|
+
Successful?: Array<{ Id: string }>
|
|
179
|
+
Failed?: Array<{ Id: string, Code: string }>
|
|
180
|
+
}
|
|
181
|
+
// ============================================================================
|
|
182
|
+
// Event Processor Interface
|
|
183
|
+
// ============================================================================
|
|
184
|
+
export declare interface EventProcessor {
|
|
185
|
+
processEvents(events: AnalyticsEvent[]): Promise<void>
|
|
186
|
+
}
|
|
187
|
+
export declare interface SQSLambdaMessage {
|
|
188
|
+
messageId: string
|
|
189
|
+
receiptHandle: string
|
|
190
|
+
body: string
|
|
191
|
+
}
|
|
192
|
+
export declare interface ProcessResult {
|
|
193
|
+
successful: number
|
|
194
|
+
failed: number
|
|
195
|
+
errors: Array<{ messageId: string, error: string }>
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* In-memory event buffer for batching before SQS send
|
|
199
|
+
*/
|
|
200
|
+
export declare class EventBuffer {
|
|
201
|
+
constructor(options: {
|
|
202
|
+
maxSize?: number
|
|
203
|
+
flushIntervalMs?: number
|
|
204
|
+
onFlush: (events: AnalyticsEvent[]) => Promise<void>
|
|
205
|
+
});
|
|
206
|
+
add(event: AnalyticsEvent): void;
|
|
207
|
+
flush(): Promise<void>;
|
|
208
|
+
get size(): number;
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Sends analytics events to SQS queue
|
|
212
|
+
*/
|
|
213
|
+
export declare class SQSEventProducer {
|
|
214
|
+
constructor(client: SQSClient, queueUrl: string, batchSize?: number);
|
|
215
|
+
sendEvent(event: AnalyticsEvent): Promise<SQSSendResult>;
|
|
216
|
+
sendEvents(events: AnalyticsEvent[]): Promise<SQSSendResult>;
|
|
217
|
+
sendEventsBatch(events: AnalyticsEvent[]): Promise<SQSSendResult>;
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Processes analytics events from SQS queue
|
|
221
|
+
*/
|
|
222
|
+
export declare class SQSEventConsumer {
|
|
223
|
+
constructor(client: SQSClient, queueUrl: string, processor: EventProcessor);
|
|
224
|
+
processBatch(messages: SQSLambdaMessage[]): Promise<ProcessResult>;
|
|
225
|
+
poll(maxMessages?: number): Promise<ProcessResult>;
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Coalesce multiple writes to the same key within a time window
|
|
229
|
+
* This reduces write costs and avoids unnecessary overwrites
|
|
230
|
+
*/
|
|
231
|
+
export declare class WriteCoalescer<T> {
|
|
232
|
+
constructor(options: {
|
|
233
|
+
windowMs?: number
|
|
234
|
+
onWrite: (key: string, data: T) => Promise<void>
|
|
235
|
+
});
|
|
236
|
+
write(key: string, data: T): void;
|
|
237
|
+
flush(): Promise<void>;
|
|
238
|
+
get size(): number;
|
|
239
|
+
}
|
|
240
|
+
// ============================================================================
|
|
241
|
+
// Export Default Config
|
|
242
|
+
// ============================================================================
|
|
243
|
+
export { defaultSQSConfig as sqsConfig };
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import { AggregationPipeline, AnalyticsAPI, AnalyticsQueryAPI, AnalyticsStore } from './index';
|
|
2
|
+
import type { AnalyticsAPIConfig, HandlerContext } from './index';
|
|
3
|
+
// ============================================================================
|
|
4
|
+
// Type Exports for Stacks Integration
|
|
5
|
+
// ============================================================================
|
|
6
|
+
export type {
|
|
7
|
+
AnalyticsAPIConfig,
|
|
8
|
+
HandlerContext,
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Create Stacks analytics middleware
|
|
12
|
+
* Injects tracking script into HTML responses
|
|
13
|
+
*/
|
|
14
|
+
export declare function createAnalyticsMiddleware(driver: DynamoDBAnalyticsDriver): (ctx: {
|
|
15
|
+
request: Request
|
|
16
|
+
response?: Response
|
|
17
|
+
html?: string
|
|
18
|
+
}, next: () => Promise<void>) => Promise<void>;
|
|
19
|
+
/**
|
|
20
|
+
* Create server-side tracking middleware
|
|
21
|
+
* Tracks page views automatically for server-rendered pages
|
|
22
|
+
*/
|
|
23
|
+
export declare function createServerTrackingMiddleware(driver: DynamoDBAnalyticsDriver, options?: {
|
|
24
|
+
excludedPaths?: RegExp[]
|
|
25
|
+
getVisitorId?: (request: Request) => string
|
|
26
|
+
getSessionId?: (request: Request) => string
|
|
27
|
+
}): (ctx: { request: Request, url: URL }, next: () => Promise<void>) => Promise<void>;
|
|
28
|
+
/**
|
|
29
|
+
* Create Stacks dashboard actions for analytics
|
|
30
|
+
*/
|
|
31
|
+
export declare function createDashboardActions(driver: DynamoDBAnalyticsDriver): {
|
|
32
|
+
getDashboardStats: (params: { startDate?: string, endDate?: string, compare?: boolean }) => Promise<unknown>
|
|
33
|
+
getRealtimeStats: (params?: { minutes?: number }) => Promise<unknown>
|
|
34
|
+
getTopPages: (params?: { startDate?: string, endDate?: string, limit?: number }) => Promise<unknown>
|
|
35
|
+
runAggregation: (params: { period: 'hour' | 'day' | 'month' }) => Promise<unknown>
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* Create a DynamoDB analytics driver from Stacks config
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* ```typescript
|
|
42
|
+
* import { createAnalyticsDriver } from '@stacksjs/dynamodb-tooling'
|
|
43
|
+
* import config from './config/analytics'
|
|
44
|
+
* import { DynamoDBClient } from '@aws-sdk/client-dynamodb'
|
|
45
|
+
*
|
|
46
|
+
* const client = new DynamoDBClient({ region: 'us-east-1' })
|
|
47
|
+
* const driver = createAnalyticsDriver(config.drivers.dynamodb!, async (cmd) => {
|
|
48
|
+
* // Execute DynamoDB command
|
|
49
|
+
* return client.send(new cmd.command(cmd.input))
|
|
50
|
+
* })
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
53
|
+
export declare function createAnalyticsDriver(config: DynamoDBAnalyticsConfig, executeCommand: HandlerContext['executeCommand']): DynamoDBAnalyticsDriver;
|
|
54
|
+
/**
|
|
55
|
+
* DynamoDB analytics driver configuration for Stacks
|
|
56
|
+
*/
|
|
57
|
+
export declare interface DynamoDBAnalyticsConfig {
|
|
58
|
+
tableName: string
|
|
59
|
+
region?: string
|
|
60
|
+
siteId: string
|
|
61
|
+
apiEndpoint?: string
|
|
62
|
+
useTtl?: boolean
|
|
63
|
+
rawEventRetentionDays?: number
|
|
64
|
+
hourlyRetentionDays?: number
|
|
65
|
+
dailyRetentionYears?: number
|
|
66
|
+
privacy?: {
|
|
67
|
+
honorDnt?: boolean
|
|
68
|
+
hashIps?: boolean
|
|
69
|
+
collectGeolocation?: boolean
|
|
70
|
+
}
|
|
71
|
+
tracking?: {
|
|
72
|
+
trackHashChanges?: boolean
|
|
73
|
+
trackOutboundLinks?: boolean
|
|
74
|
+
excludedPaths?: string[]
|
|
75
|
+
excludedIps?: string[]
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Stacks analytics options interface (matches Stacks pattern)
|
|
80
|
+
*/
|
|
81
|
+
export declare interface StacksAnalyticsOptions {
|
|
82
|
+
driver: 'google-analytics' | 'fathom' | 'dynamodb'
|
|
83
|
+
drivers: {
|
|
84
|
+
googleAnalytics?: {
|
|
85
|
+
trackingId: string
|
|
86
|
+
}
|
|
87
|
+
fathom?: {
|
|
88
|
+
siteId: string
|
|
89
|
+
}
|
|
90
|
+
dynamodb?: DynamoDBAnalyticsConfig
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* DynamoDB Analytics Driver for Stacks
|
|
95
|
+
*
|
|
96
|
+
* @example
|
|
97
|
+
* ```typescript
|
|
98
|
+
* // config/analytics.ts
|
|
99
|
+
* export default {
|
|
100
|
+
* driver: 'dynamodb',
|
|
101
|
+
* drivers: {
|
|
102
|
+
* dynamodb: {
|
|
103
|
+
* tableName: 'analytics',
|
|
104
|
+
* siteId: 'my-site-id',
|
|
105
|
+
* region: 'us-east-1',
|
|
106
|
+
* privacy: {
|
|
107
|
+
* honorDnt: true,
|
|
108
|
+
* hashIps: true,
|
|
109
|
+
* },
|
|
110
|
+
* },
|
|
111
|
+
* },
|
|
112
|
+
* } satisfies StacksAnalyticsOptions
|
|
113
|
+
* ```
|
|
114
|
+
*/
|
|
115
|
+
export declare class DynamoDBAnalyticsDriver {
|
|
116
|
+
constructor(config: DynamoDBAnalyticsConfig, executeCommand: HandlerContext['executeCommand']);
|
|
117
|
+
getTrackingScript(): string;
|
|
118
|
+
trackPageView(options: {
|
|
119
|
+
path: string
|
|
120
|
+
title?: string
|
|
121
|
+
referrer?: string
|
|
122
|
+
visitorId: string
|
|
123
|
+
sessionId: string
|
|
124
|
+
userAgent?: string
|
|
125
|
+
ip?: string
|
|
126
|
+
}): Promise<void>;
|
|
127
|
+
trackEvent(options: {
|
|
128
|
+
name: string
|
|
129
|
+
value?: number
|
|
130
|
+
properties?: Record<string, string | number | boolean>
|
|
131
|
+
path: string
|
|
132
|
+
visitorId: string
|
|
133
|
+
sessionId: string
|
|
134
|
+
}): Promise<void>;
|
|
135
|
+
getDashboardStats(options?: {
|
|
136
|
+
startDate?: Date
|
|
137
|
+
endDate?: Date
|
|
138
|
+
includeComparison?: boolean
|
|
139
|
+
}): Promise<{
|
|
140
|
+
summary: ReturnType<typeof AnalyticsQueryAPI.processSummary>
|
|
141
|
+
timeSeries: ReturnType<typeof AnalyticsQueryAPI.processTimeSeries>
|
|
142
|
+
}>;
|
|
143
|
+
getRealtimeVisitors(minutes?: number): Promise<{
|
|
144
|
+
currentVisitors: number
|
|
145
|
+
pageViewsLastHour: number
|
|
146
|
+
topActivePages: Array<{ name: string, value: number, percentage: number }>
|
|
147
|
+
}>;
|
|
148
|
+
getTopPages(options?: {
|
|
149
|
+
startDate?: Date
|
|
150
|
+
endDate?: Date
|
|
151
|
+
limit?: number
|
|
152
|
+
}): Promise<unknown[]>;
|
|
153
|
+
runAggregation(period: 'hour' | 'day' | 'month'): Promise<{
|
|
154
|
+
success: boolean
|
|
155
|
+
config: ReturnType<typeof AggregationPipeline.createJobConfig>
|
|
156
|
+
}>;
|
|
157
|
+
getAPI(): AnalyticsAPI;
|
|
158
|
+
getStore(): AnalyticsStore;
|
|
159
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generate a comprehensive tracking script
|
|
3
|
+
*
|
|
4
|
+
* @example
|
|
5
|
+
* ```ts
|
|
6
|
+
* const script = generateFullTrackingScript({
|
|
7
|
+
* siteId: 'my-site',
|
|
8
|
+
* apiEndpoint: 'https://analytics.example.com/api/analytics',
|
|
9
|
+
* trackScrollDepth: [25, 50, 75, 100],
|
|
10
|
+
* trackOutboundLinks: true,
|
|
11
|
+
* })
|
|
12
|
+
*
|
|
13
|
+
* // Add to HTML
|
|
14
|
+
* res.send(`<script>${script}</script>`)
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
export declare function generateFullTrackingScript(config: TrackingScriptConfig): string;
|
|
18
|
+
/**
|
|
19
|
+
* Generate just the tracking snippet (loader)
|
|
20
|
+
*/
|
|
21
|
+
export declare function generateTrackingSnippet(config: Pick<TrackingScriptConfig, 'siteId' | 'apiEndpoint'>): string;
|
|
22
|
+
/**
|
|
23
|
+
* Generate inline tracking script (no external file needed)
|
|
24
|
+
*/
|
|
25
|
+
export declare function generateInlineTrackingScript(config: TrackingScriptConfig): string;
|
|
26
|
+
/**
|
|
27
|
+
* Generate a minimal tracking script (page views only)
|
|
28
|
+
*/
|
|
29
|
+
export declare function generateMinimalTrackingScript(config: Pick<TrackingScriptConfig, 'siteId' | 'apiEndpoint' | 'honorDnt' | 'stealthMode'>): string;
|
|
30
|
+
/**
|
|
31
|
+
* Generate a Google Analytics 4-style tracking script
|
|
32
|
+
*/
|
|
33
|
+
export declare function generateGA4StyleScript(config: TrackingScriptConfig): string;
|
|
34
|
+
/* eslint-disable prefer-const */
|
|
35
|
+
/**
|
|
36
|
+
* Tracking Script Generator
|
|
37
|
+
*
|
|
38
|
+
* Generates a comprehensive client-side tracking script for web analytics.
|
|
39
|
+
* Supports page views, custom events, scroll tracking, outbound links, and more.
|
|
40
|
+
*/
|
|
41
|
+
// ============================================================================
|
|
42
|
+
// Types
|
|
43
|
+
// ============================================================================
|
|
44
|
+
export declare interface TrackingScriptConfig {
|
|
45
|
+
siteId: string
|
|
46
|
+
apiEndpoint: string
|
|
47
|
+
autoPageView?: boolean
|
|
48
|
+
trackHashChanges?: boolean
|
|
49
|
+
trackOutboundLinks?: boolean
|
|
50
|
+
trackScrollDepth?: number[]
|
|
51
|
+
trackTimeOnPage?: number[]
|
|
52
|
+
honorDnt?: boolean
|
|
53
|
+
cookieDomain?: string
|
|
54
|
+
sessionTimeout?: number
|
|
55
|
+
dataAttributePrefix?: string
|
|
56
|
+
debug?: boolean
|
|
57
|
+
onError?: string
|
|
58
|
+
excludePaths?: string[]
|
|
59
|
+
excludeQueryParams?: boolean
|
|
60
|
+
minify?: boolean
|
|
61
|
+
heatmap?: HeatmapTrackingConfig
|
|
62
|
+
stealthMode?: boolean
|
|
63
|
+
}
|
|
64
|
+
export declare interface HeatmapTrackingConfig {
|
|
65
|
+
trackClicks?: boolean
|
|
66
|
+
trackMovements?: boolean
|
|
67
|
+
movementSampleInterval?: number
|
|
68
|
+
maxMovementPoints?: number
|
|
69
|
+
trackScrollPositions?: boolean
|
|
70
|
+
flushInterval?: number
|
|
71
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/*`, which have no imports.
|
|
2
|
+
*/
|
|
3
|
+
export {
|
|
4
|
+
getBrowserFamily,
|
|
5
|
+
isBot,
|
|
6
|
+
type ParsedUserAgent,
|
|
7
|
+
parseUserAgent,
|
|
8
|
+
} from './utils/user-agent';
|
|
9
|
+
export {
|
|
10
|
+
anonymizeIp,
|
|
11
|
+
countryCodeOf,
|
|
12
|
+
countryFlagEmoji,
|
|
13
|
+
getCountryFromHeaders,
|
|
14
|
+
getRegionFromHeaders,
|
|
15
|
+
isSpamReferrer,
|
|
16
|
+
parseReferrerSource,
|
|
17
|
+
} from './utils/geolocation';
|
package/dist/tracking.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import {
|
|
3
|
+
anonymizeIp,
|
|
4
|
+
countryCodeOf,
|
|
5
|
+
countryFlagEmoji,
|
|
6
|
+
getBrowserFamily,
|
|
7
|
+
getCountryFromHeaders,
|
|
8
|
+
getRegionFromHeaders,
|
|
9
|
+
isBot,
|
|
10
|
+
isSpamReferrer,
|
|
11
|
+
parseReferrerSource,
|
|
12
|
+
parseUserAgent
|
|
13
|
+
} from "./chunk-j261vgyp.js";
|
|
14
|
+
import"./chunk-2mx7fq49.js";
|
|
15
|
+
export {
|
|
16
|
+
parseUserAgent,
|
|
17
|
+
parseReferrerSource,
|
|
18
|
+
isSpamReferrer,
|
|
19
|
+
isBot,
|
|
20
|
+
getRegionFromHeaders,
|
|
21
|
+
getCountryFromHeaders,
|
|
22
|
+
getBrowserFamily,
|
|
23
|
+
countryFlagEmoji,
|
|
24
|
+
countryCodeOf,
|
|
25
|
+
anonymizeIp
|
|
26
|
+
};
|