@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.
Files changed (237) hide show
  1. package/CHANGELOG.md +68 -0
  2. package/LICENSE.md +21 -0
  3. package/README.md +361 -0
  4. package/bin/cli.ts +169 -0
  5. package/dist/Analytics.d.ts +558 -0
  6. package/dist/api.d.ts +109 -0
  7. package/dist/batching.d.ts +93 -0
  8. package/dist/chunk-2mx7fq49.js +4 -0
  9. package/dist/chunk-3z29508k.js +204 -0
  10. package/dist/chunk-deephkz6.js +56 -0
  11. package/dist/chunk-j261vgyp.js +305 -0
  12. package/dist/chunk-xga17tz7.js +207 -0
  13. package/dist/config.d.ts +132 -0
  14. package/dist/dashboard/components/index.d.ts +80 -0
  15. package/dist/dashboard/composables/useAnalytics.d.ts +99 -0
  16. package/dist/dashboard/index.d.ts +110 -0
  17. package/dist/dashboard/types/index.d.ts +144 -0
  18. package/dist/dashboard/utils/index.d.ts +81 -0
  19. package/dist/dynamodb.d.ts +86 -0
  20. package/dist/funnels.d.ts +104 -0
  21. package/dist/geolocation.d.ts +96 -0
  22. package/dist/index.d.ts +371 -0
  23. package/dist/index.js +10211 -0
  24. package/dist/infrastructure/cdk.d.ts +60 -0
  25. package/dist/infrastructure/cloudformation.d.ts +44 -0
  26. package/dist/infrastructure/index.d.ts +45 -0
  27. package/dist/infrastructure/setup.d.ts +133 -0
  28. package/dist/integrations/cloudflare.d.ts +76 -0
  29. package/dist/integrations/hono.d.ts +60 -0
  30. package/dist/integrations/index.d.ts +24 -0
  31. package/dist/integrations/nuxt.d.ts +7 -0
  32. package/dist/integrations/nuxt.js +42 -0
  33. package/dist/integrations/runtime/use-ts-analytics.d.ts +18 -0
  34. package/dist/integrations/runtime/use-ts-analytics.js +17 -0
  35. package/dist/integrations/stx.d.ts +88 -0
  36. package/dist/integrations/stx.js +18 -0
  37. package/dist/lib/crypto-random.d.ts +4 -0
  38. package/dist/lib/salt.d.ts +16 -0
  39. package/dist/local.d.ts +56 -0
  40. package/dist/model-connector.d.ts +145 -0
  41. package/dist/models/AggregatedStats.d.ts +9 -0
  42. package/dist/models/CampaignStats.d.ts +9 -0
  43. package/dist/models/Conversion.d.ts +11 -0
  44. package/dist/models/CustomEvent.d.ts +11 -0
  45. package/dist/models/DeviceStats.d.ts +9 -0
  46. package/dist/models/EventStats.d.ts +9 -0
  47. package/dist/models/GeoStats.d.ts +9 -0
  48. package/dist/models/Goal.d.ts +9 -0
  49. package/dist/models/GoalStats.d.ts +9 -0
  50. package/dist/models/PageStats.d.ts +11 -0
  51. package/dist/models/PageView.d.ts +13 -0
  52. package/dist/models/RealtimeStats.d.ts +9 -0
  53. package/dist/models/ReferrerStats.d.ts +9 -0
  54. package/dist/models/Session.d.ts +11 -0
  55. package/dist/models/Site.d.ts +11 -0
  56. package/dist/models/index.d.ts +28 -0
  57. package/dist/models/types.d.ts +60 -0
  58. package/dist/sqs-buffering.d.ts +243 -0
  59. package/dist/stacks-integration.d.ts +159 -0
  60. package/dist/tracking-script.d.ts +71 -0
  61. package/dist/tracking.d.ts +17 -0
  62. package/dist/tracking.js +26 -0
  63. package/dist/types.d.ts +595 -0
  64. package/dist/utils/geolocation.d.ts +111 -0
  65. package/dist/utils/user-agent.d.ts +17 -0
  66. package/dist/version.d.ts +7 -0
  67. package/package.json +119 -0
  68. package/src/Analytics.ts +3349 -0
  69. package/src/api.ts +1286 -0
  70. package/src/assets/crosswind.css +2220 -0
  71. package/src/batching.ts +452 -0
  72. package/src/components/dashboard/index.ts +18 -0
  73. package/src/config.ts +456 -0
  74. package/src/dashboard/Dashboard.stx +1517 -0
  75. package/src/dashboard/components/AlertCard.stx +177 -0
  76. package/src/dashboard/components/AnalyticsDashboard.stx +354 -0
  77. package/src/dashboard/components/AnimatedNumber.stx +86 -0
  78. package/src/dashboard/components/BarChart.stx +220 -0
  79. package/src/dashboard/components/BrowserBreakdown.stx +98 -0
  80. package/src/dashboard/components/BrowsersTable.stx +125 -0
  81. package/src/dashboard/components/CampaignBreakdown.stx +163 -0
  82. package/src/dashboard/components/CampaignTable.stx +238 -0
  83. package/src/dashboard/components/CountryList.stx +101 -0
  84. package/src/dashboard/components/DataTable.stx +226 -0
  85. package/src/dashboard/components/DateRangePicker.stx +77 -0
  86. package/src/dashboard/components/DeviceBreakdown.stx +94 -0
  87. package/src/dashboard/components/DevicesTable.stx +163 -0
  88. package/src/dashboard/components/DonutChart.stories.ts +55 -0
  89. package/src/dashboard/components/DonutChart.stx +157 -0
  90. package/src/dashboard/components/EmptyState.stx +90 -0
  91. package/src/dashboard/components/EngagementMetrics.stx +183 -0
  92. package/src/dashboard/components/EventsSection.stx +192 -0
  93. package/src/dashboard/components/FilterBar.stx +104 -0
  94. package/src/dashboard/components/FullAnalyticsDashboard.stx +455 -0
  95. package/src/dashboard/components/FunnelChart.stx +142 -0
  96. package/src/dashboard/components/GeoTable.stx +337 -0
  97. package/src/dashboard/components/GoalsPanel.stx +109 -0
  98. package/src/dashboard/components/Header.stx +39 -0
  99. package/src/dashboard/components/HeatmapChart.stx +140 -0
  100. package/src/dashboard/components/LiveActivityFeed.stx +172 -0
  101. package/src/dashboard/components/MetricComparison.stx +106 -0
  102. package/src/dashboard/components/MiniStats.stx +96 -0
  103. package/src/dashboard/components/OSBreakdown.stx +124 -0
  104. package/src/dashboard/components/PageDetailCard.stx +102 -0
  105. package/src/dashboard/components/PagesTable.stx +127 -0
  106. package/src/dashboard/components/ProgressRing.stx +89 -0
  107. package/src/dashboard/components/RealtimeCounter.stories.ts +45 -0
  108. package/src/dashboard/components/RealtimeCounter.stx +46 -0
  109. package/src/dashboard/components/ReferrersTable.stx +180 -0
  110. package/src/dashboard/components/SparklineChart.stx +160 -0
  111. package/src/dashboard/components/StatCard.stories.ts +58 -0
  112. package/src/dashboard/components/StatCard.stx +90 -0
  113. package/src/dashboard/components/SummaryStats.stx +81 -0
  114. package/src/dashboard/components/TabNav.stx +66 -0
  115. package/src/dashboard/components/ThemeSwitcher.stx +124 -0
  116. package/src/dashboard/components/TimeSeriesChart.stx +106 -0
  117. package/src/dashboard/components/TopList.stories.ts +58 -0
  118. package/src/dashboard/components/TopList.stx +74 -0
  119. package/src/dashboard/components/TrendIndicator.stx +84 -0
  120. package/src/dashboard/components/heatmap/ClickHeatmap.stx +264 -0
  121. package/src/dashboard/components/heatmap/ElementClickList.stx +125 -0
  122. package/src/dashboard/components/heatmap/HeatmapControls.stx +125 -0
  123. package/src/dashboard/components/heatmap/HeatmapLegend.stx +69 -0
  124. package/src/dashboard/components/heatmap/PageHeatmap.stx +264 -0
  125. package/src/dashboard/components/heatmap/ScrollHeatmap.stx +127 -0
  126. package/src/dashboard/components/heatmap/index.ts +12 -0
  127. package/src/dashboard/components/index.ts +86 -0
  128. package/src/dashboard/composables/useAnalytics.ts +465 -0
  129. package/src/dashboard/demo/DemoApp.stx +370 -0
  130. package/src/dashboard/demo/index.ts +8 -0
  131. package/src/dashboard/demo/mockData.ts +234 -0
  132. package/src/dashboard/index.ts +117 -0
  133. package/src/dashboard/stx-shim.d.ts +4 -0
  134. package/src/dashboard/types/index.ts +203 -0
  135. package/src/dashboard/utils/index.ts +426 -0
  136. package/src/dynamodb.ts +344 -0
  137. package/src/funnels.ts +534 -0
  138. package/src/geolocation.ts +515 -0
  139. package/src/handlers/alerts.ts +328 -0
  140. package/src/handlers/annotations.ts +128 -0
  141. package/src/handlers/api-keys.ts +240 -0
  142. package/src/handlers/auth.ts +1020 -0
  143. package/src/handlers/authz.ts +137 -0
  144. package/src/handlers/collect.ts +724 -0
  145. package/src/handlers/data.ts +625 -0
  146. package/src/handlers/experiments.ts +138 -0
  147. package/src/handlers/funnels.ts +216 -0
  148. package/src/handlers/goals.ts +218 -0
  149. package/src/handlers/heatmaps.ts +272 -0
  150. package/src/handlers/index.ts +56 -0
  151. package/src/handlers/lib/read-cache.ts +63 -0
  152. package/src/handlers/misc.ts +486 -0
  153. package/src/handlers/oauth.ts +233 -0
  154. package/src/handlers/performance.ts +388 -0
  155. package/src/handlers/sessions.ts +413 -0
  156. package/src/handlers/sharing.ts +198 -0
  157. package/src/handlers/stats.ts +1368 -0
  158. package/src/handlers/team.ts +161 -0
  159. package/src/handlers/uptime.ts +283 -0
  160. package/src/handlers/views.ts +390 -0
  161. package/src/handlers/webhooks.ts +226 -0
  162. package/src/heatmap/index.ts +32 -0
  163. package/src/heatmap/tracking-script.ts +452 -0
  164. package/src/heatmap/types.ts +79 -0
  165. package/src/index.ts +387 -0
  166. package/src/infrastructure/cdk.ts +496 -0
  167. package/src/infrastructure/cloudformation.ts +595 -0
  168. package/src/infrastructure/index.ts +48 -0
  169. package/src/infrastructure/setup.ts +611 -0
  170. package/src/integrations/cloudflare.ts +732 -0
  171. package/src/integrations/hono.ts +589 -0
  172. package/src/integrations/index.ts +27 -0
  173. package/src/integrations/nuxt.ts +78 -0
  174. package/src/integrations/runtime/use-ts-analytics.ts +32 -0
  175. package/src/integrations/stx.ts +138 -0
  176. package/src/jobs/index.ts +127 -0
  177. package/src/lib/crypto-random.ts +41 -0
  178. package/src/lib/ddb-errors.ts +20 -0
  179. package/src/lib/dynamodb.ts +216 -0
  180. package/src/lib/email.ts +38 -0
  181. package/src/lib/ga-import.ts +471 -0
  182. package/src/lib/ga4-api.ts +244 -0
  183. package/src/lib/goals.ts +205 -0
  184. package/src/lib/index.ts +6 -0
  185. package/src/lib/ingest-counters.ts +123 -0
  186. package/src/lib/log.ts +36 -0
  187. package/src/lib/membership.ts +98 -0
  188. package/src/lib/plans.ts +90 -0
  189. package/src/lib/quota.ts +46 -0
  190. package/src/lib/rate-limit.ts +27 -0
  191. package/src/lib/rollups.ts +472 -0
  192. package/src/lib/salt.ts +97 -0
  193. package/src/lib/scheduler.ts +97 -0
  194. package/src/lib/significance.ts +66 -0
  195. package/src/lib/site-retention.ts +56 -0
  196. package/src/local.ts +360 -0
  197. package/src/model-connector.ts +616 -0
  198. package/src/models/AggregatedStats.ts +162 -0
  199. package/src/models/CampaignStats.ts +141 -0
  200. package/src/models/Conversion.ts +135 -0
  201. package/src/models/CustomEvent.ts +123 -0
  202. package/src/models/DeviceStats.ts +105 -0
  203. package/src/models/EventStats.ts +108 -0
  204. package/src/models/GeoStats.ts +112 -0
  205. package/src/models/Goal.ts +105 -0
  206. package/src/models/GoalStats.ts +106 -0
  207. package/src/models/PageStats.ts +152 -0
  208. package/src/models/PageView.ts +277 -0
  209. package/src/models/RealtimeStats.ts +96 -0
  210. package/src/models/ReferrerStats.ts +115 -0
  211. package/src/models/Session.ts +235 -0
  212. package/src/models/Site.ts +115 -0
  213. package/src/models/index.ts +50 -0
  214. package/src/models/orm/index.ts +2043 -0
  215. package/src/models/types.ts +71 -0
  216. package/src/router.ts +521 -0
  217. package/src/sqs-buffering.ts +806 -0
  218. package/src/stacks-integration.ts +527 -0
  219. package/src/tracking-script.ts +944 -0
  220. package/src/tracking.ts +27 -0
  221. package/src/types/analytics.ts +219 -0
  222. package/src/types/api.ts +75 -0
  223. package/src/types/bun-router.d.ts +15 -0
  224. package/src/types/dashboard.ts +62 -0
  225. package/src/types/index.ts +66 -0
  226. package/src/types/stx.d.ts +27 -0
  227. package/src/types/window.d.ts +101 -0
  228. package/src/types.ts +911 -0
  229. package/src/utils/cache.ts +148 -0
  230. package/src/utils/date.ts +118 -0
  231. package/src/utils/filters.ts +71 -0
  232. package/src/utils/geolocation.ts +323 -0
  233. package/src/utils/index.ts +9 -0
  234. package/src/utils/response.ts +180 -0
  235. package/src/utils/timezone-country.ts +242 -0
  236. package/src/utils/user-agent.ts +110 -0
  237. package/src/version.ts +7 -0
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Generate CDK TypeScript code for analytics infrastructure
3
+ */
4
+ export declare function generateCdkCode(props?: AnalyticsApiProps): string;
5
+ /**
6
+ * Generate minimal CDK code for just the table (no API)
7
+ */
8
+ export declare function generateCdkTableCode(props?: AnalyticsTableProps): string;
9
+ /**
10
+ * Generate CreateTableInput for AWS SDK
11
+ */
12
+ export declare function generateCreateTableInput(props?: AnalyticsTableProps): Record<string, unknown>;
13
+ /**
14
+ * AWS CDK Construct for Analytics DynamoDB Table
15
+ *
16
+ * This module provides CDK constructs for deploying the analytics
17
+ * infrastructure to AWS.
18
+ *
19
+ * @example
20
+ * ```typescript
21
+ * import { AnalyticsTable } from 'dynamodb-tooling/analytics/infrastructure/cdk'
22
+ *
23
+ * const analytics = new AnalyticsTable(this, 'Analytics', {
24
+ * tableName: 'my-analytics',
25
+ * billingMode: BillingMode.PAY_PER_REQUEST,
26
+ * })
27
+ *
28
+ * // Access the table
29
+ * analytics.table.grantReadWriteData(myLambda)
30
+ * ```
31
+ *
32
+ * Note: This module exports construct props and a helper function
33
+ * to generate the CDK code since we can't import CDK directly
34
+ * (it's a peer dependency).
35
+ */
36
+ // ============================================================================
37
+ // CDK Props Types
38
+ // ============================================================================
39
+ export declare interface AnalyticsTableProps {
40
+ tableName?: string
41
+ billingMode?: 'PAY_PER_REQUEST' | 'PROVISIONED'
42
+ readCapacity?: number
43
+ writeCapacity?: number
44
+ pointInTimeRecovery?: boolean
45
+ stream?: 'KEYS_ONLY' | 'NEW_IMAGE' | 'OLD_IMAGE' | 'NEW_AND_OLD_IMAGES'
46
+ timeToLiveAttribute?: string
47
+ removalPolicy?: 'DESTROY' | 'RETAIN' | 'SNAPSHOT'
48
+ encryption?: 'AWS_MANAGED' | 'CUSTOMER_MANAGED' | 'DEFAULT'
49
+ encryptionKey?: string
50
+ deletionProtection?: boolean
51
+ tags?: Record<string, string>
52
+ }
53
+ export declare interface AnalyticsApiProps extends AnalyticsTableProps {
54
+ stageName?: string
55
+ corsOrigins?: string[]
56
+ memorySize?: number
57
+ timeout?: number
58
+ codePath?: string
59
+ enableAggregation?: boolean
60
+ }
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Generate CloudFormation template for analytics table
3
+ */
4
+ export declare function generateCloudFormationTemplate(userConfig?: CloudFormationConfig): Record<string, unknown>;
5
+ /**
6
+ * Generate CloudFormation template as JSON string
7
+ */
8
+ export declare function generateCloudFormationJson(config?: CloudFormationConfig, pretty?: boolean): string;
9
+ /**
10
+ * Generate CloudFormation template as YAML string
11
+ */
12
+ export declare function generateCloudFormationYaml(config?: CloudFormationConfig): string;
13
+ /**
14
+ * Generate SAM (Serverless Application Model) template
15
+ * Includes Lambda functions for API endpoints
16
+ */
17
+ export declare function generateSamTemplate(config?: CloudFormationConfig): Record<string, unknown>;
18
+ /**
19
+ * Generate SAM template as YAML string
20
+ */
21
+ export declare function generateSamYaml(config?: CloudFormationConfig): string;
22
+ /**
23
+ * CloudFormation Template Generator for Analytics DynamoDB Table
24
+ *
25
+ * Generates CloudFormation JSON/YAML for deploying the analytics
26
+ * single-table design to AWS.
27
+ */
28
+ export declare interface CloudFormationConfig {
29
+ stackName?: string
30
+ tableName?: string
31
+ billingMode?: 'PAY_PER_REQUEST' | 'PROVISIONED'
32
+ provisionedCapacity?: {
33
+ readCapacityUnits: number
34
+ writeCapacityUnits: number
35
+ }
36
+ enablePitr?: boolean
37
+ enableStreams?: boolean
38
+ streamViewType?: 'KEYS_ONLY' | 'NEW_IMAGE' | 'OLD_IMAGE' | 'NEW_AND_OLD_IMAGES'
39
+ ttlAttributeName?: string
40
+ enableEncryption?: boolean
41
+ kmsKeyArn?: string
42
+ tags?: Record<string, string>
43
+ deletionProtection?: boolean
44
+ }
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Analytics Infrastructure Module
3
+ *
4
+ * Provides tools for deploying the analytics DynamoDB table:
5
+ * - CloudFormation templates (JSON/YAML)
6
+ * - SAM templates for serverless deployment
7
+ * - CDK code generation
8
+ * - AWS SDK CreateTable input
9
+ * - Migration utilities
10
+ * - Setup scripts
11
+ */
12
+ // CDK
13
+ export {
14
+ type AnalyticsApiProps,
15
+ type AnalyticsTableProps,
16
+ generateCdkCode,
17
+ generateCdkTableCode,
18
+ generateCreateTableInput,
19
+ } from './cdk';
20
+ // CloudFormation
21
+ export {
22
+ type CloudFormationConfig,
23
+ generateCloudFormationJson,
24
+ generateCloudFormationTemplate,
25
+ generateCloudFormationYaml,
26
+ generateSamTemplate,
27
+ generateSamYaml,
28
+ } from './cloudformation';
29
+ // Setup & Migrations
30
+ export {
31
+ checkTableStatus,
32
+ createAnalyticsTable,
33
+ createPitrMigration,
34
+ createStreamsMigration,
35
+ createTimeBasedGsiMigration,
36
+ type DynamoDBClientLike,
37
+ enableTtl,
38
+ generateAwsCliCommands,
39
+ type MigrationResult,
40
+ type MigrationStep,
41
+ printSetupInstructions,
42
+ runMigrations,
43
+ type SetupConfig,
44
+ type SetupResult,
45
+ } from './setup';
@@ -0,0 +1,133 @@
1
+ import type { AnalyticsTableProps } from './cdk';
2
+ /**
3
+ * Create the analytics table
4
+ *
5
+ * @example
6
+ * ```typescript
7
+ * import { DynamoDBClient, CreateTableCommand } from '@aws-sdk/client-dynamodb'
8
+ * import { createAnalyticsTable } from 'dynamodb-tooling/analytics/infrastructure'
9
+ *
10
+ * const client = new DynamoDBClient({ region: 'us-east-1' })
11
+ *
12
+ * const result = await createAnalyticsTable(client, {
13
+ * tableName: 'my-analytics',
14
+ * billingMode: 'PAY_PER_REQUEST',
15
+ * })
16
+ *
17
+ * console.log(`Created table: ${result.tableName}`)
18
+ * ```
19
+ */
20
+ export declare function createAnalyticsTable(client: DynamoDBClientLike, config?: SetupConfig | undefined, commandFactories: {
21
+ CreateTableCommand: new (input: Record<string, unknown>) => unknown
22
+ DescribeTableCommand: new (input: { TableName: string }) => unknown
23
+ }): Promise<SetupResult>;
24
+ /**
25
+ * Enable TTL on the analytics table
26
+ */
27
+ export declare function enableTtl(client: DynamoDBClientLike, tableName: string, attributeName: string, commandFactory: {
28
+ UpdateTimeToLiveCommand: new (input: {
29
+ TableName: string
30
+ TimeToLiveSpecification: { AttributeName: string, Enabled: boolean }
31
+ }) => unknown
32
+ }): Promise<SetupResult>;
33
+ /**
34
+ * Check if table exists and is active
35
+ */
36
+ // eslint-disable-next-line pickier/no-unused-vars
37
+ export declare function checkTableStatus(client: DynamoDBClientLike, tableName: string, commandFactory: {
38
+ DescribeTableCommand: new (input: { TableName: string }) => unknown
39
+ }): Promise<{
40
+ exists: boolean
41
+ status?: string
42
+ itemCount?: number
43
+ sizeBytes?: number
44
+ gsiCount?: number
45
+ }>;
46
+ /**
47
+ * Run analytics migrations
48
+ */
49
+ export declare function runMigrations(client: DynamoDBClientLike, _tableName: string, migrations: MigrationStep[]): Promise<MigrationResult>;
50
+ /**
51
+ * Migration: Add GSI for time-based queries
52
+ */
53
+ export declare function createTimeBasedGsiMigration(tableName: string, commandFactory: {
54
+ UpdateTableCommand: new (input: Record<string, unknown>) => unknown
55
+ }): MigrationStep;
56
+ /**
57
+ * Migration: Enable Point-in-Time Recovery
58
+ */
59
+ export declare function createPitrMigration(tableName: string, commandFactory: {
60
+ UpdateContinuousBackupsCommand: new (input: Record<string, unknown>) => unknown
61
+ }): MigrationStep;
62
+ /**
63
+ * Migration: Enable DynamoDB Streams
64
+ */
65
+ export declare function createStreamsMigration(tableName: string, viewType: 'KEYS_ONLY' | 'NEW_IMAGE' | 'OLD_IMAGE' | 'NEW_AND_OLD_IMAGES', commandFactory: {
66
+ UpdateTableCommand: new (input: Record<string, unknown>) => unknown
67
+ }): MigrationStep;
68
+ /**
69
+ * Print setup instructions for manual deployment
70
+ */
71
+ export declare function printSetupInstructions(config?: SetupConfig): void;
72
+ /**
73
+ * Generate AWS CLI commands for table creation
74
+ */
75
+ export declare function generateAwsCliCommands(config?: SetupConfig): string;
76
+ // ============================================================================
77
+ // Types
78
+ // ============================================================================
79
+ export declare interface SetupConfig extends AnalyticsTableProps {
80
+ region?: string
81
+ endpoint?: string
82
+ waitForActive?: boolean
83
+ waitTimeout?: number
84
+ }
85
+ export declare interface SetupResult {
86
+ success: boolean
87
+ tableName: string
88
+ tableArn?: string
89
+ error?: string
90
+ }
91
+ export declare interface MigrationStep {
92
+ name: string
93
+ description: string
94
+ execute: (client: DynamoDBClientLike) => Promise<void>
95
+ rollback?: (client: DynamoDBClientLike) => Promise<void>
96
+ }
97
+ export declare interface MigrationResult {
98
+ success: boolean
99
+ stepsCompleted: string[]
100
+ error?: string
101
+ failedStep?: string
102
+ }
103
+ /**
104
+ * Minimal DynamoDB client interface
105
+ * Allows using either AWS SDK v2 or v3
106
+ */
107
+ export declare interface DynamoDBClientLike {
108
+ send: (command: unknown) => Promise<unknown>
109
+ }
110
+ /**
111
+ * CreateTable command interface
112
+ */
113
+ export declare interface CreateTableCommandLike {
114
+ input: Record<string, unknown>
115
+ }
116
+ /**
117
+ * DescribeTable command interface
118
+ */
119
+ export declare interface DescribeTableCommandLike {
120
+ input: { TableName: string }
121
+ }
122
+ /**
123
+ * UpdateTimeToLive command interface
124
+ */
125
+ export declare interface UpdateTimeToLiveCommandLike {
126
+ input: {
127
+ TableName: string
128
+ TimeToLiveSpecification: {
129
+ AttributeName: string
130
+ Enabled: boolean
131
+ }
132
+ }
133
+ }
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Create a Cloudflare Workers fetch handler for analytics
3
+ */
4
+ export declare function createAnalyticsHandler(options?: CloudflareHandlerOptions): (
5
+ request: Request,
6
+ env: CloudflareEnv,
7
+ ctx: ExecutionContext,
8
+ ) => Promise<Response>;
9
+ /**
10
+ * Create a D1 storage adapter for SQLite-based storage
11
+ */
12
+ export declare function createD1Adapter(db: D1Database): StorageAdapter;
13
+ // ============================================================================
14
+ // Types
15
+ // ============================================================================
16
+ export declare interface CloudflareEnv {
17
+ DYNAMODB_ENDPOINT?: string
18
+ AWS_REGION?: string
19
+ AWS_ACCESS_KEY_ID?: string
20
+ AWS_SECRET_ACCESS_KEY?: string
21
+ SESSIONS_KV?: KVNamespace
22
+ D1_DATABASE?: D1Database
23
+ TABLE_NAME?: string
24
+ }
25
+ declare interface KVNamespace {
26
+ get: (key: string, options?: { type?: string }) => Promise<string | null>
27
+ put: (key: string, value: string, options?: { expirationTtl?: number }) => Promise<void>
28
+ delete: (key: string) => Promise<void>
29
+ }
30
+ declare interface D1Database {
31
+ prepare: (sql: string) => D1PreparedStatement
32
+ exec: (sql: string) => Promise<D1ExecResult>
33
+ batch: <T>(statements: D1PreparedStatement[]) => Promise<D1Result<T>[]>
34
+ }
35
+ declare interface D1PreparedStatement {
36
+ bind: (...values: unknown[]) => D1PreparedStatement
37
+ first: <T>() => Promise<T | null>
38
+ all: <T>() => Promise<D1Result<T>>
39
+ run: () => Promise<D1Result<unknown>>
40
+ }
41
+ declare interface D1Result<T> {
42
+ results?: T[]
43
+ success: boolean
44
+ meta?: Record<string, unknown>
45
+ }
46
+ declare interface D1ExecResult {
47
+ count: number
48
+ duration: number
49
+ }
50
+ export declare interface CloudflareHandlerOptions {
51
+ corsOrigins?: string[]
52
+ basePath?: string
53
+ sessionTtl?: number
54
+ storage?: StorageAdapter
55
+ }
56
+ export declare interface StorageAdapter {
57
+ putItem: (tableName: string, item: Record<string, unknown>) => Promise<void>
58
+ query: (tableName: string, params: QueryParams) => Promise<QueryResult>
59
+ }
60
+ declare interface QueryParams {
61
+ pk: string
62
+ skPrefix?: string
63
+ skStart?: string
64
+ skEnd?: string
65
+ indexName?: string
66
+ limit?: number
67
+ }
68
+ declare interface QueryResult {
69
+ items: Record<string, unknown>[]
70
+ lastKey?: string
71
+ }
72
+ // Cloudflare Workers types
73
+ declare interface ExecutionContext {
74
+ waitUntil: (promise: Promise<unknown>) => void
75
+ passThroughOnException: () => void
76
+ }
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Create analytics middleware for Hono
3
+ *
4
+ * Adds analytics context to requests and handles CORS.
5
+ */
6
+ export declare function analyticsMiddleware(options?: Partial<AnalyticsMiddlewareOptions>): HonoMiddleware;
7
+ /**
8
+ * Create analytics routes for Hono
9
+ */
10
+ export declare function createAnalyticsRoutes(options: AnalyticsMiddlewareOptions): {
11
+ collect: (c: HonoContext) => Promise<Response>
12
+ stats: (c: HonoContext) => Promise<Response>
13
+ realtime: (c: HonoContext) => Promise<Response>
14
+ script: (c: HonoContext) => Response
15
+ sites: (c: HonoContext) => Promise<Response>
16
+ createSite: (c: HonoContext) => Promise<Response>
17
+ };
18
+ /**
19
+ * Mount analytics routes on a Hono app
20
+ */
21
+ export declare function mountAnalyticsRoutes(app: HonoApp, basePath: string, options: AnalyticsMiddlewareOptions): void;
22
+ // ============================================================================
23
+ // Types
24
+ // ============================================================================
25
+ declare interface HonoContext {
26
+ req: {
27
+ url: string
28
+ method: string
29
+ header: (name: string) => string | undefined
30
+ param: (name: string) => string | undefined
31
+ query: (name: string) => string | undefined
32
+ json: <T>() => Promise<T>
33
+ }
34
+ json: (data: unknown, status?: number) => Response
35
+ text: (data: string, status?: number) => Response
36
+ body: (data: unknown, status?: number) => Response
37
+ set: (name: string, value: unknown) => void
38
+ get: (name: string) => unknown
39
+ }
40
+ declare interface HonoApp {
41
+ use: (path: string, ...handlers: HonoMiddleware[]) => void
42
+ get: (path: string, handler: (c: HonoContext) => Promise<Response> | Response) => void
43
+ post: (path: string, handler: (c: HonoContext) => Promise<Response> | Response) => void
44
+ options: (path: string, handler: (c: HonoContext) => Promise<Response> | Response) => void
45
+ }
46
+ export declare interface AnalyticsMiddlewareOptions {
47
+ skipPaths?: string[]
48
+ getVisitorId?: (c: HonoContext) => Promise<string>
49
+ sessionStore?: SessionStore
50
+ executeCommand: (cmd: DynamoCommand) => Promise<unknown>
51
+ }
52
+ declare interface SessionStore {
53
+ get: (key: string) => Promise<Session | null>
54
+ set: (key: string, session: Session, ttlSeconds?: number) => Promise<void>
55
+ }
56
+ declare interface DynamoCommand {
57
+ command: string
58
+ input: Record<string, unknown>
59
+ }
60
+ declare type HonoMiddleware = (c: HonoContext, next: () => Promise<void>) => Promise<Response | void>;
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Framework Integrations
3
+ *
4
+ * Pre-built integrations for popular frameworks.
5
+ */
6
+ export {
7
+ analyticsMiddleware,
8
+ createAnalyticsRoutes,
9
+ mountAnalyticsRoutes,
10
+ type AnalyticsMiddlewareOptions,
11
+ } from './hono';
12
+ export {
13
+ createAnalyticsHandler,
14
+ createD1Adapter,
15
+ type CloudflareEnv,
16
+ type CloudflareHandlerOptions,
17
+ type StorageAdapter,
18
+ } from './cloudflare';
19
+ export {
20
+ type StxHeadScript,
21
+ tsAnalytics,
22
+ type TsAnalyticsOptions,
23
+ tsAnalyticsTag,
24
+ } from './stx';
@@ -0,0 +1,7 @@
1
+ import type { NuxtModule } from '@nuxt/schema'
2
+ import { type TsAnalyticsOptions } from './stx';
3
+ declare const tsAnalyticsNuxtModule: NuxtModule<TsAnalyticsNuxtOptions>;
4
+ export declare interface TsAnalyticsNuxtOptions extends TsAnalyticsOptions {
5
+ enabled?: boolean
6
+ }
7
+ export default tsAnalyticsNuxtModule;
@@ -0,0 +1,42 @@
1
+ // @bun
2
+ import {
3
+ resolveApiEndpoint,
4
+ tsAnalytics
5
+ } from "../chunk-deephkz6.js";
6
+ import"../chunk-2mx7fq49.js";
7
+
8
+ // src/integrations/nuxt.ts
9
+ import { addImports, createResolver, defineNuxtModule } from "@nuxt/kit";
10
+ var tsAnalyticsNuxtModule = defineNuxtModule({
11
+ meta: {
12
+ name: "@stacksjs/ts-analytics",
13
+ configKey: "tsAnalytics",
14
+ compatibility: { nuxt: ">=3.0.0" }
15
+ },
16
+ defaults: { enabled: true },
17
+ setup(options, nuxt) {
18
+ if (options.enabled === false)
19
+ return;
20
+ const scripts = tsAnalytics(options);
21
+ if (scripts.length === 0) {
22
+ console.warn("[ts-analytics] module skipped \u2014 `appId` is required in nuxt.config `tsAnalytics`.");
23
+ return;
24
+ }
25
+ nuxt.options.app.head.script = nuxt.options.app.head.script || [];
26
+ nuxt.options.app.head.script.push(...scripts);
27
+ nuxt.options.runtimeConfig.public.tsAnalytics = {
28
+ appId: options.appId,
29
+ apiEndpoint: resolveApiEndpoint(options.apiEndpoint)
30
+ };
31
+ const resolver = createResolver(import.meta.url);
32
+ addImports({
33
+ name: "useTsAnalytics",
34
+ as: "useTsAnalytics",
35
+ from: resolver.resolve("./runtime/use-ts-analytics")
36
+ });
37
+ }
38
+ });
39
+ var nuxt_default = tsAnalyticsNuxtModule;
40
+ export {
41
+ nuxt_default as default
42
+ };
@@ -0,0 +1,18 @@
1
+ export declare function useTsAnalytics(): TsAnalyticsApi;
2
+ /**
3
+ * `useTsAnalytics()` — custom event tracking for the ts-analytics Nuxt module.
4
+ *
5
+ * The injected tracker exposes a Fathom-API-compatible global
6
+ * (`window.fathom.track(name, value)`); this composable wraps it with an
7
+ * SSR-safe no-op on the server. Auto-imported by `@stacksjs/ts-analytics/nuxt`.
8
+ *
9
+ * ```ts
10
+ * const { track } = useTsAnalytics()
11
+ * track('signup')
12
+ * track('purchase', 4200) // optional numeric value (e.g. cents)
13
+ * track('signup', 0, { plan: 'pro' }) // custom properties
14
+ * ```
15
+ */
16
+ export declare interface TsAnalyticsApi {
17
+ track: (name: string, value?: number, props?: Record<string, string | number | boolean>) => void
18
+ }
@@ -0,0 +1,17 @@
1
+ // @bun
2
+ import"../../chunk-2mx7fq49.js";
3
+
4
+ // src/integrations/runtime/use-ts-analytics.ts
5
+ function useTsAnalytics() {
6
+ return {
7
+ track(name, value, props) {
8
+ if (typeof window === "undefined")
9
+ return;
10
+ const tracker = window.fathom;
11
+ tracker?.track?.(name, value, props);
12
+ }
13
+ };
14
+ }
15
+ export {
16
+ useTsAnalytics
17
+ };
@@ -0,0 +1,88 @@
1
+ /** Resolve the API origin from an explicit override, env, then the default. */
2
+ export declare function resolveApiEndpoint(explicit?: string): string;
3
+ /**
4
+ * Build the ts-analytics head `<script>` entry for a stx/Stacks app config.
5
+ *
6
+ * Returns an **array** (so it spreads cleanly into `app.head.script` and can
7
+ * grow later — e.g. an error-tracking tag — without changing call sites).
8
+ * Returns `[]` when `appId`/`apiEndpoint` are missing, so a half-configured
9
+ * environment never injects a broken tag.
10
+ */
11
+ export declare function tsAnalytics(options: TsAnalyticsOptions): StxHeadScript[];
12
+ /**
13
+ * Raw `<script>` tag string for non-stx contexts — paste into a plain HTML
14
+ * `<head>`, or inject server-side. Same inputs as {@link tsAnalytics}. Returns
15
+ * `''` when required options are missing.
16
+ */
17
+ export declare function tsAnalyticsTag(options: TsAnalyticsOptions): string;
18
+ /**
19
+ * Default ts-analytics API origin — where `/script.js` is served and events are
20
+ * collected. Baked in (Fathom-style) so host apps supply *only* an App ID.
21
+ *
22
+ * Endpoint resolution order: an explicit `apiEndpoint` option → the
23
+ * `TS_ANALYTICS_ENDPOINT` env var → this constant. Set this to your production
24
+ * ts-analytics host so deployed apps need zero endpoint config.
25
+ */
26
+ export declare const DEFAULT_API_ENDPOINT: 'http://localhost:2027';
27
+ /** A stx head `<script>` entry — an item of the config `app.head.script` array. */
28
+ export declare interface StxHeadScript {
29
+ src?: string
30
+ content?: string
31
+ defer?: boolean
32
+ async?: boolean
33
+ type?: string
34
+ [attr: string]: unknown
35
+ }
36
+ export declare interface TsAnalyticsOptions {
37
+ appId: string
38
+ apiEndpoint?: string
39
+ scriptPath?: string
40
+ stealth?: boolean
41
+ }
42
+ /**
43
+ * stx / Stacks Config Integration
44
+ *
45
+ * Add ts-analytics to a stx (or Stacks) app the way you'd add a Nuxt analytics
46
+ * module — from the config file, keyed by an **App ID**.
47
+ *
48
+ * ts-analytics serves one shared, cacheable tracker at `<apiEndpoint>/script.js`
49
+ * (Fathom/Plausible-style). The tracker reads its App ID from the `data-site`
50
+ * attribute and derives the collector endpoint from its own `src` origin, so
51
+ * the only thing a host app supplies is the App ID + the API origin.
52
+ *
53
+ * Spread the result into your stx config's `app.head.script`:
54
+ *
55
+ * ```ts
56
+ * // config/stx.ts (Stacks) — or stx.config.ts
57
+ * import { tsAnalytics } from '@stacksjs/ts-analytics/stx'
58
+ *
59
+ * export default {
60
+ * app: {
61
+ * head: {
62
+ * script: [
63
+ * ...tsAnalytics({ appId: 'my-app' }), // endpoint is baked in
64
+ * ],
65
+ * },
66
+ * },
67
+ * }
68
+ * ```
69
+ *
70
+ * **Why a head helper and not a `plugins: [...]` entry?** stx's plugin render
71
+ * lifecycle hooks (`afterRender`) are not invoked by the dev/serve render
72
+ * pipeline, and a plugin's `setup()` config mutation does not propagate to
73
+ * rendering. The head config *is* read on every render, so this is the reliable
74
+ * mechanism — and it mirrors what framework analytics modules do internally
75
+ * (push a tag onto the document head).
76
+ */
77
+ /**
78
+ * Generate a short, unguessable App ID (Fathom-style `data-site`, 8 chars). Run
79
+ * once per site and paste the result into your config — the backend
80
+ * auto-provisions the site on its first event, so nothing else is needed.
81
+ *
82
+ * ```ts
83
+ * import { generateAppId } from '@stacksjs/ts-analytics/stx'
84
+ * console.log(generateAppId()) // e.g. 'K7MN4PQR'
85
+ * ```
86
+ */
87
+ export { generateAppId } from '../lib/crypto-random';
88
+ export default tsAnalytics;
@@ -0,0 +1,18 @@
1
+ // @bun
2
+ import {
3
+ DEFAULT_API_ENDPOINT,
4
+ generateAppId,
5
+ resolveApiEndpoint,
6
+ stx_default,
7
+ tsAnalytics,
8
+ tsAnalyticsTag
9
+ } from "../chunk-deephkz6.js";
10
+ import"../chunk-2mx7fq49.js";
11
+ export {
12
+ tsAnalyticsTag,
13
+ tsAnalytics,
14
+ resolveApiEndpoint,
15
+ generateAppId,
16
+ stx_default as default,
17
+ DEFAULT_API_ENDPOINT
18
+ };
@@ -0,0 +1,4 @@
1
+ /** A random string of `length` chars drawn uniformly from `chars`. */
2
+ export declare function randomToken(length: number, chars?: string): string;
3
+ /** A short, random, unguessable App ID (default 8 chars). */
4
+ export declare function generateAppId(length?: number): string;
@@ -0,0 +1,16 @@
1
+ /** Daily-rotating, secret-seeded salt for visitor ID hashing.
2
+ *
3
+ * NOTE: process-local — on multi-instance deployments prefer
4
+ * {@link getSharedDailySalt}, which persists the day's salt in DynamoDB so
5
+ * every instance hashes with the same value.
6
+ */
7
+ export declare function getDailySalt(): string;
8
+ /**
9
+ * Cluster-consistent daily salt (#165). The process-local salt differs per
10
+ * instance when ANALYTICS_SALT_SECRET is unset (Lambda concurrency, restarts),
11
+ * which inflates unique-visitor counts — the same visitor hashes differently on
12
+ * every instance. Persist the day's salt as a SALT item via conditional put
13
+ * (first writer wins) so all instances converge, with the process-local value
14
+ * as both the candidate and the fallback when DynamoDB is unreachable.
15
+ */
16
+ export declare function getSharedDailySalt(): Promise<string>;