@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,207 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import"./chunk-3z29508k.js";
|
|
3
|
+
import"./chunk-2mx7fq49.js";
|
|
4
|
+
|
|
5
|
+
// src/models/orm/index.ts
|
|
6
|
+
import { Model, configureModels, DynamoDBClient, createClient } from "bun-query-builder/dynamodb";
|
|
7
|
+
|
|
8
|
+
// src/lib/ddb-errors.ts
|
|
9
|
+
function isConditionalCheckFailed(e) {
|
|
10
|
+
const err = e;
|
|
11
|
+
return !!err && (String(err.name || "").includes("ConditionalCheckFailed") || /conditional request failed/i.test(String(err.message || err)));
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// src/lib/site-retention.ts
|
|
15
|
+
var CACHE_MS = 5 * 60 * 1000;
|
|
16
|
+
var cache = new Map;
|
|
17
|
+
|
|
18
|
+
// src/models/orm/index.ts
|
|
19
|
+
var analyticsConfig = {
|
|
20
|
+
tableName: process.env.ANALYTICS_TABLE_NAME || "ts-analytics"
|
|
21
|
+
};
|
|
22
|
+
function configureAnalytics(config) {
|
|
23
|
+
if (config.tableName) {
|
|
24
|
+
analyticsConfig.tableName = config.tableName;
|
|
25
|
+
console.log("[ORM] Configured tableName:", analyticsConfig.tableName);
|
|
26
|
+
}
|
|
27
|
+
configureModels({
|
|
28
|
+
region: config.region,
|
|
29
|
+
endpoint: config.endpoint,
|
|
30
|
+
credentials: config.credentials
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
function marshall(obj) {
|
|
34
|
+
const result = {};
|
|
35
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
36
|
+
result[key] = marshallValue(value);
|
|
37
|
+
}
|
|
38
|
+
return result;
|
|
39
|
+
}
|
|
40
|
+
function marshallValue(value) {
|
|
41
|
+
if (value === null || value === undefined) {
|
|
42
|
+
return { NULL: true };
|
|
43
|
+
}
|
|
44
|
+
if (typeof value === "string") {
|
|
45
|
+
return { S: value };
|
|
46
|
+
}
|
|
47
|
+
if (typeof value === "number") {
|
|
48
|
+
return { N: String(value) };
|
|
49
|
+
}
|
|
50
|
+
if (typeof value === "boolean") {
|
|
51
|
+
return { BOOL: value };
|
|
52
|
+
}
|
|
53
|
+
if (Array.isArray(value)) {
|
|
54
|
+
return { L: value.map(marshallValue) };
|
|
55
|
+
}
|
|
56
|
+
if (typeof value === "object") {
|
|
57
|
+
const m = {};
|
|
58
|
+
for (const [k, v] of Object.entries(value)) {
|
|
59
|
+
m[k] = marshallValue(v);
|
|
60
|
+
}
|
|
61
|
+
return { M: m };
|
|
62
|
+
}
|
|
63
|
+
return { S: String(value) };
|
|
64
|
+
}
|
|
65
|
+
function unmarshall(item) {
|
|
66
|
+
const result = {};
|
|
67
|
+
for (const [key, value] of Object.entries(item)) {
|
|
68
|
+
result[key] = unmarshallValue(value);
|
|
69
|
+
}
|
|
70
|
+
return result;
|
|
71
|
+
}
|
|
72
|
+
function unmarshallValue(value) {
|
|
73
|
+
if ("S" in value)
|
|
74
|
+
return value.S;
|
|
75
|
+
if ("N" in value)
|
|
76
|
+
return Number(value.N);
|
|
77
|
+
if ("BOOL" in value)
|
|
78
|
+
return value.BOOL;
|
|
79
|
+
if ("NULL" in value)
|
|
80
|
+
return null;
|
|
81
|
+
if ("SS" in value)
|
|
82
|
+
return [...value.SS];
|
|
83
|
+
if ("NS" in value)
|
|
84
|
+
return value.NS.map(Number);
|
|
85
|
+
if ("L" in value)
|
|
86
|
+
return value.L.map(unmarshallValue);
|
|
87
|
+
if ("M" in value)
|
|
88
|
+
return unmarshall(value.M);
|
|
89
|
+
return value;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// src/lib/dynamodb.ts
|
|
93
|
+
var TABLE_NAME = process.env.ANALYTICS_TABLE_NAME || "ts-analytics";
|
|
94
|
+
var REGION = process.env.AWS_REGION || "us-east-1";
|
|
95
|
+
var DYNAMODB_ENDPOINT = process.env.ANALYTICS_DYNAMODB_ENDPOINT || undefined;
|
|
96
|
+
configureAnalytics({
|
|
97
|
+
tableName: TABLE_NAME,
|
|
98
|
+
region: REGION,
|
|
99
|
+
...DYNAMODB_ENDPOINT ? { endpoint: DYNAMODB_ENDPOINT } : {}
|
|
100
|
+
});
|
|
101
|
+
var dynamodb = createClient({ region: REGION, ...DYNAMODB_ENDPOINT ? { endpoint: DYNAMODB_ENDPOINT } : {} });
|
|
102
|
+
function buildDateRangeExpression(startDate, endDate, timestampField = "timestamp") {
|
|
103
|
+
return {
|
|
104
|
+
expression: `#${timestampField} BETWEEN :startDate AND :endDate`,
|
|
105
|
+
names: { [`#${timestampField}`]: timestampField },
|
|
106
|
+
values: {
|
|
107
|
+
":startDate": { S: startDate.toISOString() },
|
|
108
|
+
":endDate": { S: endDate.toISOString() }
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
function buildSiteKeyCondition(siteId) {
|
|
113
|
+
return {
|
|
114
|
+
expression: "pk = :pk",
|
|
115
|
+
values: { ":pk": { S: `SITE#${siteId}` } }
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
async function paginatedQuery(params, maxItems = 1000) {
|
|
119
|
+
const items = [];
|
|
120
|
+
let lastKey;
|
|
121
|
+
do {
|
|
122
|
+
const response = await dynamodb.query({
|
|
123
|
+
...params,
|
|
124
|
+
ExclusiveStartKey: lastKey
|
|
125
|
+
});
|
|
126
|
+
if (response.Items) {
|
|
127
|
+
for (const item of response.Items) {
|
|
128
|
+
items.push(unmarshall(item));
|
|
129
|
+
if (items.length >= maxItems) {
|
|
130
|
+
return items;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
lastKey = response.LastEvaluatedKey;
|
|
135
|
+
} while (lastKey);
|
|
136
|
+
return items;
|
|
137
|
+
}
|
|
138
|
+
async function querySessionItemsInRange(siteId, startDate, endDate) {
|
|
139
|
+
return queryAllItems({
|
|
140
|
+
TableName: TABLE_NAME,
|
|
141
|
+
IndexName: "GSI1",
|
|
142
|
+
KeyConditionExpression: "gsi1pk = :pk AND gsi1sk BETWEEN :start AND :end",
|
|
143
|
+
ExpressionAttributeValues: {
|
|
144
|
+
":pk": { S: `SITE#${siteId}#SESSIONS` },
|
|
145
|
+
":start": { S: startDate.toISOString() },
|
|
146
|
+
":end": { S: `${endDate.toISOString()}~` }
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
async function queryAllItems(params, cap = 1e5) {
|
|
151
|
+
const items = [];
|
|
152
|
+
let lastKey;
|
|
153
|
+
do {
|
|
154
|
+
const page = await dynamodb.query({ ...params, ExclusiveStartKey: lastKey });
|
|
155
|
+
if (page.Items)
|
|
156
|
+
items.push(...page.Items);
|
|
157
|
+
lastKey = page.LastEvaluatedKey;
|
|
158
|
+
if (items.length >= cap) {
|
|
159
|
+
console.warn(`[queryAllItems] hit ${cap}-item cap (table ${String(params.TableName)}) \u2014 results truncated; counts may undercount`);
|
|
160
|
+
break;
|
|
161
|
+
}
|
|
162
|
+
} while (lastKey);
|
|
163
|
+
return { Items: items, Count: items.length };
|
|
164
|
+
}
|
|
165
|
+
async function batchGet(keys) {
|
|
166
|
+
if (keys.length === 0)
|
|
167
|
+
return [];
|
|
168
|
+
const items = [];
|
|
169
|
+
const batches = [];
|
|
170
|
+
for (let i = 0;i < keys.length; i += 100) {
|
|
171
|
+
batches.push(keys.slice(i, i + 100));
|
|
172
|
+
}
|
|
173
|
+
for (const batch of batches) {
|
|
174
|
+
const response = await dynamodb.batchGetItem({
|
|
175
|
+
RequestItems: {
|
|
176
|
+
[TABLE_NAME]: {
|
|
177
|
+
Keys: batch.map((key) => ({
|
|
178
|
+
pk: { S: key.pk },
|
|
179
|
+
sk: { S: key.sk }
|
|
180
|
+
}))
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
const tableItems = response.Responses?.[TABLE_NAME];
|
|
185
|
+
if (tableItems) {
|
|
186
|
+
for (const item of tableItems) {
|
|
187
|
+
items.push(unmarshall(item));
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
return items;
|
|
192
|
+
}
|
|
193
|
+
export {
|
|
194
|
+
unmarshall,
|
|
195
|
+
querySessionItemsInRange,
|
|
196
|
+
queryAllItems,
|
|
197
|
+
paginatedQuery,
|
|
198
|
+
marshall,
|
|
199
|
+
isConditionalCheckFailed,
|
|
200
|
+
dynamodb,
|
|
201
|
+
buildSiteKeyCondition,
|
|
202
|
+
buildDateRangeExpression,
|
|
203
|
+
batchGet,
|
|
204
|
+
TABLE_NAME,
|
|
205
|
+
REGION,
|
|
206
|
+
DYNAMODB_ENDPOINT
|
|
207
|
+
};
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import type { AnalyticsTableConfig, BillingMode, GSIDefinition, SingleTableDesignConfig } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Merge user config with defaults
|
|
4
|
+
*/
|
|
5
|
+
export declare function defineConfig(userConfig?: UserAnalyticsConfig): AnalyticsConfig;
|
|
6
|
+
/**
|
|
7
|
+
* Create table configuration from analytics config
|
|
8
|
+
*/
|
|
9
|
+
export declare function getTableConfig(config: AnalyticsConfig): {
|
|
10
|
+
tableName: string
|
|
11
|
+
billingMode: BillingMode
|
|
12
|
+
partitionKey: string
|
|
13
|
+
sortKey: string
|
|
14
|
+
gsis: GSIDefinition[]
|
|
15
|
+
ttlAttribute?: string
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Get TTL value for a given entity type
|
|
19
|
+
*/
|
|
20
|
+
export declare function getTtlForEntity(config: AnalyticsConfig, entityType: 'raw' | 'hourly' | 'daily' | 'monthly'): number | undefined;
|
|
21
|
+
/**
|
|
22
|
+
* Set global analytics configuration
|
|
23
|
+
*/
|
|
24
|
+
export declare function setConfig(config: UserAnalyticsConfig): AnalyticsConfig;
|
|
25
|
+
/**
|
|
26
|
+
* Get current analytics configuration
|
|
27
|
+
*/
|
|
28
|
+
export declare function getConfig(): AnalyticsConfig;
|
|
29
|
+
/**
|
|
30
|
+
* Reset configuration to defaults
|
|
31
|
+
*/
|
|
32
|
+
export declare function resetConfig(): void;
|
|
33
|
+
/**
|
|
34
|
+
* Default single-table design configuration
|
|
35
|
+
*/
|
|
36
|
+
export declare const defaultSingleTableConfig: SingleTableDesignConfig;
|
|
37
|
+
/**
|
|
38
|
+
* Default GSI definitions for analytics
|
|
39
|
+
*/
|
|
40
|
+
export declare const defaultGSIs: GSIDefinition[];
|
|
41
|
+
/**
|
|
42
|
+
* Default analytics table configuration
|
|
43
|
+
*/
|
|
44
|
+
export declare const defaultAnalyticsConfig: AnalyticsTableConfig;
|
|
45
|
+
/**
|
|
46
|
+
* Complete default configuration
|
|
47
|
+
*/
|
|
48
|
+
export declare const defaultConfig: AnalyticsConfig;
|
|
49
|
+
/**
|
|
50
|
+
* Analytics configuration options
|
|
51
|
+
*/
|
|
52
|
+
export declare interface AnalyticsConfig {
|
|
53
|
+
table: AnalyticsTableConfig
|
|
54
|
+
region: string
|
|
55
|
+
endpoint?: string
|
|
56
|
+
retention: {
|
|
57
|
+
rawEventTtl: number
|
|
58
|
+
hourlyAggregateTtl: number
|
|
59
|
+
dailyAggregateTtl: number
|
|
60
|
+
monthlyAggregateTtl?: number
|
|
61
|
+
}
|
|
62
|
+
privacy: {
|
|
63
|
+
hashVisitorIds: boolean
|
|
64
|
+
collectGeolocation: boolean
|
|
65
|
+
honorDnt: boolean
|
|
66
|
+
ipAnonymization: 'none' | 'partial' | 'full'
|
|
67
|
+
}
|
|
68
|
+
tracking: {
|
|
69
|
+
trackReferrers: boolean
|
|
70
|
+
trackUtmParams: boolean
|
|
71
|
+
trackDeviceType: boolean
|
|
72
|
+
trackHashChanges: boolean
|
|
73
|
+
trackOutboundLinks: boolean
|
|
74
|
+
excludedIps?: string[]
|
|
75
|
+
excludedPaths?: string[]
|
|
76
|
+
}
|
|
77
|
+
api: {
|
|
78
|
+
basePath: string
|
|
79
|
+
corsOrigins: string[]
|
|
80
|
+
}
|
|
81
|
+
aggregation: {
|
|
82
|
+
batchSize: number
|
|
83
|
+
hourlyEnabled: boolean
|
|
84
|
+
dailyEnabled: boolean
|
|
85
|
+
monthlyEnabled: boolean
|
|
86
|
+
}
|
|
87
|
+
scale: {
|
|
88
|
+
sqsBuffering: {
|
|
89
|
+
enabled: boolean
|
|
90
|
+
queueUrl?: string
|
|
91
|
+
deadLetterQueueUrl?: string
|
|
92
|
+
maxRetries: number
|
|
93
|
+
}
|
|
94
|
+
daxCaching: {
|
|
95
|
+
enabled: boolean
|
|
96
|
+
endpoint?: string
|
|
97
|
+
ttlSeconds: number
|
|
98
|
+
}
|
|
99
|
+
partitionSharding: {
|
|
100
|
+
enabled: boolean
|
|
101
|
+
shardCount: number
|
|
102
|
+
enabledSiteIds: string[]
|
|
103
|
+
}
|
|
104
|
+
writeCoalescing: {
|
|
105
|
+
enabled: boolean
|
|
106
|
+
windowMs: number
|
|
107
|
+
}
|
|
108
|
+
batchWrites: {
|
|
109
|
+
enabled: boolean
|
|
110
|
+
maxBatchSize: number
|
|
111
|
+
flushIntervalMs: number
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Partial configuration for user overrides
|
|
117
|
+
*/
|
|
118
|
+
export type UserAnalyticsConfig = {
|
|
119
|
+
[K in keyof AnalyticsConfig]?: K extends 'table'
|
|
120
|
+
? Partial<AnalyticsTableConfig>
|
|
121
|
+
: K extends 'retention' | 'privacy' | 'tracking' | 'api' | 'aggregation'
|
|
122
|
+
? Partial<AnalyticsConfig[K]>
|
|
123
|
+
: K extends 'scale'
|
|
124
|
+
? {
|
|
125
|
+
sqsBuffering?: Partial<AnalyticsConfig['scale']['sqsBuffering']>
|
|
126
|
+
daxCaching?: Partial<AnalyticsConfig['scale']['daxCaching']>
|
|
127
|
+
partitionSharding?: Partial<AnalyticsConfig['scale']['partitionSharding']>
|
|
128
|
+
writeCoalescing?: Partial<AnalyticsConfig['scale']['writeCoalescing']>
|
|
129
|
+
batchWrites?: Partial<AnalyticsConfig['scale']['batchWrites']>
|
|
130
|
+
}
|
|
131
|
+
: AnalyticsConfig[K]
|
|
132
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
// Function to get component file path
|
|
2
|
+
export declare function getComponentPath(name: string): string | undefined;
|
|
3
|
+
/**
|
|
4
|
+
* Analytics Dashboard Components
|
|
5
|
+
*
|
|
6
|
+
* stx components for displaying analytics data.
|
|
7
|
+
* These are .stx files that need to be processed by the stx framework.
|
|
8
|
+
* Total: 31 components
|
|
9
|
+
*
|
|
10
|
+
* Components are exported as string identifiers pointing to the component files.
|
|
11
|
+
* The stx framework uses these to resolve and render the components at runtime.
|
|
12
|
+
*/
|
|
13
|
+
// Component name constants - use these when referencing components in stx templates
|
|
14
|
+
export declare const AlertCard: 'AlertCard';
|
|
15
|
+
export declare const AnalyticsDashboard: 'AnalyticsDashboard';
|
|
16
|
+
export declare const AnimatedNumber: 'AnimatedNumber';
|
|
17
|
+
export declare const BarChart: 'BarChart';
|
|
18
|
+
export declare const BrowserBreakdown: 'BrowserBreakdown';
|
|
19
|
+
export declare const CampaignBreakdown: 'CampaignBreakdown';
|
|
20
|
+
export declare const CountryList: 'CountryList';
|
|
21
|
+
export declare const DataTable: 'DataTable';
|
|
22
|
+
export declare const DateRangePicker: 'DateRangePicker';
|
|
23
|
+
export declare const DeviceBreakdown: 'DeviceBreakdown';
|
|
24
|
+
export declare const DonutChart: 'DonutChart';
|
|
25
|
+
export declare const EmptyState: 'EmptyState';
|
|
26
|
+
export declare const EngagementMetrics: 'EngagementMetrics';
|
|
27
|
+
export declare const FilterBar: 'FilterBar';
|
|
28
|
+
export declare const FullAnalyticsDashboard: 'FullAnalyticsDashboard';
|
|
29
|
+
export declare const FunnelChart: 'FunnelChart';
|
|
30
|
+
export declare const GoalsPanel: 'GoalsPanel';
|
|
31
|
+
export declare const HeatmapChart: 'HeatmapChart';
|
|
32
|
+
export declare const LiveActivityFeed: 'LiveActivityFeed';
|
|
33
|
+
export declare const MetricComparison: 'MetricComparison';
|
|
34
|
+
export declare const MiniStats: 'MiniStats';
|
|
35
|
+
export declare const OSBreakdown: 'OSBreakdown';
|
|
36
|
+
export declare const PageDetailCard: 'PageDetailCard';
|
|
37
|
+
export declare const ProgressRing: 'ProgressRing';
|
|
38
|
+
export declare const RealtimeCounter: 'RealtimeCounter';
|
|
39
|
+
export declare const SparklineChart: 'SparklineChart';
|
|
40
|
+
export declare const StatCard: 'StatCard';
|
|
41
|
+
export declare const ThemeSwitcher: 'ThemeSwitcher';
|
|
42
|
+
export declare const TimeSeriesChart: 'TimeSeriesChart';
|
|
43
|
+
export declare const TopList: 'TopList';
|
|
44
|
+
export declare const TrendIndicator: 'TrendIndicator';
|
|
45
|
+
// Component registry for dynamic component resolution
|
|
46
|
+
export declare const componentRegistry: {
|
|
47
|
+
AlertCard: './AlertCard.stx';
|
|
48
|
+
AnalyticsDashboard: './AnalyticsDashboard.stx';
|
|
49
|
+
AnimatedNumber: './AnimatedNumber.stx';
|
|
50
|
+
BarChart: './BarChart.stx';
|
|
51
|
+
BrowserBreakdown: './BrowserBreakdown.stx';
|
|
52
|
+
CampaignBreakdown: './CampaignBreakdown.stx';
|
|
53
|
+
CountryList: './CountryList.stx';
|
|
54
|
+
DataTable: './DataTable.stx';
|
|
55
|
+
DateRangePicker: './DateRangePicker.stx';
|
|
56
|
+
DeviceBreakdown: './DeviceBreakdown.stx';
|
|
57
|
+
DonutChart: './DonutChart.stx';
|
|
58
|
+
EmptyState: './EmptyState.stx';
|
|
59
|
+
EngagementMetrics: './EngagementMetrics.stx';
|
|
60
|
+
FilterBar: './FilterBar.stx';
|
|
61
|
+
FullAnalyticsDashboard: './FullAnalyticsDashboard.stx';
|
|
62
|
+
FunnelChart: './FunnelChart.stx';
|
|
63
|
+
GoalsPanel: './GoalsPanel.stx';
|
|
64
|
+
HeatmapChart: './HeatmapChart.stx';
|
|
65
|
+
LiveActivityFeed: './LiveActivityFeed.stx';
|
|
66
|
+
MetricComparison: './MetricComparison.stx';
|
|
67
|
+
MiniStats: './MiniStats.stx';
|
|
68
|
+
OSBreakdown: './OSBreakdown.stx';
|
|
69
|
+
PageDetailCard: './PageDetailCard.stx';
|
|
70
|
+
ProgressRing: './ProgressRing.stx';
|
|
71
|
+
RealtimeCounter: './RealtimeCounter.stx';
|
|
72
|
+
SparklineChart: './SparklineChart.stx';
|
|
73
|
+
StatCard: './StatCard.stx';
|
|
74
|
+
ThemeSwitcher: './ThemeSwitcher.stx';
|
|
75
|
+
TimeSeriesChart: './TimeSeriesChart.stx';
|
|
76
|
+
TopList: './TopList.stx';
|
|
77
|
+
TrendIndicator: './TrendIndicator.stx'
|
|
78
|
+
};
|
|
79
|
+
// List of all component names
|
|
80
|
+
export declare const allComponents: string[];
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import type { AnalyticsApiConfig, DashboardSummary, FetchOptions, GoalConversion, RealtimeData, TimeSeriesDataPoint, TopItem } from '../types/index';
|
|
2
|
+
/**
|
|
3
|
+
* Create analytics composable
|
|
4
|
+
* Note: This returns a factory function that works with Vue's reactivity system
|
|
5
|
+
*/
|
|
6
|
+
export declare function createAnalyticsComposable(options: UseAnalyticsOptions): {
|
|
7
|
+
client: AnalyticsClient
|
|
8
|
+
getInitialDateRange: () => { start: Date, end: Date }
|
|
9
|
+
fetchStats: (dateRange: { start: Date, end: Date }) => Promise<DashboardSummary>
|
|
10
|
+
fetchRealtime: () => Promise<RealtimeData>
|
|
11
|
+
fetchTopPages: (dateRange: { start: Date, end: Date }, limit?: number) => Promise<unknown[]>
|
|
12
|
+
fetchTopReferrers: (dateRange: { start: Date, end: Date }, limit?: number) => Promise<unknown[]>
|
|
13
|
+
fetchDevices: (dateRange: { start: Date, end: Date }) => Promise<unknown>
|
|
14
|
+
fetchBrowsers: (dateRange: { start: Date, end: Date }, limit?: number) => Promise<unknown[]>
|
|
15
|
+
fetchCountries: (dateRange: { start: Date, end: Date }, limit?: number) => Promise<unknown[]>
|
|
16
|
+
fetchRegions: (dateRange: { start: Date, end: Date }, country?: string, limit?: number) => Promise<unknown[]>
|
|
17
|
+
fetchCities: (dateRange: { start: Date, end: Date }, country?: string, region?: string, limit?: number) => Promise<unknown[]>
|
|
18
|
+
fetchTimeSeries: (dateRange: { start: Date, end: Date }) => Promise<unknown[]>
|
|
19
|
+
fetchGoals: (dateRange: { start: Date, end: Date }) => Promise<unknown[]>
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Fetch all dashboard data at once
|
|
23
|
+
*/
|
|
24
|
+
// eslint-disable-next-line pickier/no-unused-vars
|
|
25
|
+
export declare function fetchDashboardData(config: AnalyticsApiConfig, options?: FetchOptions): Promise<{
|
|
26
|
+
stats: DashboardSummary
|
|
27
|
+
realtime: RealtimeData
|
|
28
|
+
topPages: TopItem[]
|
|
29
|
+
topReferrers: TopItem[]
|
|
30
|
+
devices: TopItem[]
|
|
31
|
+
timeSeries: TimeSeriesDataPoint[]
|
|
32
|
+
}>;
|
|
33
|
+
/**
|
|
34
|
+
* Create a polling function for realtime data
|
|
35
|
+
*/
|
|
36
|
+
export declare function createRealtimePoller(config: AnalyticsApiConfig, callback: (data: RealtimeData) => void, interval?: number): { start: () => void, stop: () => void };
|
|
37
|
+
/**
|
|
38
|
+
* Create analytics composable for Vue 3
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* ```vue
|
|
42
|
+
* <script setup>
|
|
43
|
+
* import { useAnalytics } from 'dynamodb-tooling/analytics/dashboard'
|
|
44
|
+
*
|
|
45
|
+
* const {
|
|
46
|
+
* stats,
|
|
47
|
+
* realtime,
|
|
48
|
+
* topPages,
|
|
49
|
+
* loading,
|
|
50
|
+
* error,
|
|
51
|
+
* refresh,
|
|
52
|
+
* setDateRange
|
|
53
|
+
* } = useAnalytics({
|
|
54
|
+
* baseUrl: '/api',
|
|
55
|
+
* siteId: 'my-site'
|
|
56
|
+
* })
|
|
57
|
+
* </script>
|
|
58
|
+
* ```
|
|
59
|
+
*/
|
|
60
|
+
export declare interface UseAnalyticsOptions extends AnalyticsApiConfig {
|
|
61
|
+
refreshInterval?: number
|
|
62
|
+
initialDateRange?: '7d' | '30d' | '90d' | 'today' | 'yesterday'
|
|
63
|
+
fetchRealtime?: boolean
|
|
64
|
+
realtimeInterval?: number
|
|
65
|
+
}
|
|
66
|
+
export declare interface UseAnalyticsReturn {
|
|
67
|
+
stats: { value: DashboardSummary | null }
|
|
68
|
+
realtime: { value: RealtimeData | null }
|
|
69
|
+
topPages: { value: TopItem[] }
|
|
70
|
+
topReferrers: { value: TopItem[] }
|
|
71
|
+
devices: { value: TopItem[] }
|
|
72
|
+
browsers: { value: TopItem[] }
|
|
73
|
+
countries: { value: TopItem[] }
|
|
74
|
+
timeSeries: { value: TimeSeriesDataPoint[] }
|
|
75
|
+
goals: { value: GoalConversion[] }
|
|
76
|
+
loading: { value: boolean }
|
|
77
|
+
error: { value: Error | null }
|
|
78
|
+
dateRange: { value: { start: Date, end: Date } }
|
|
79
|
+
refresh: () => Promise<void>
|
|
80
|
+
setDateRange: (start: Date, end: Date) => void
|
|
81
|
+
setDatePreset: (preset: string) => void
|
|
82
|
+
}
|
|
83
|
+
// ============================================================================
|
|
84
|
+
// API Client
|
|
85
|
+
// ============================================================================
|
|
86
|
+
export declare class AnalyticsClient {
|
|
87
|
+
constructor(config: AnalyticsApiConfig);
|
|
88
|
+
getStats(options?: FetchOptions): Promise<DashboardSummary>;
|
|
89
|
+
getRealtime(minutes?: number): Promise<RealtimeData>;
|
|
90
|
+
getTopPages(options?: FetchOptions): Promise<TopItem[]>;
|
|
91
|
+
getTopReferrers(options?: FetchOptions): Promise<TopItem[]>;
|
|
92
|
+
getDevices(options?: FetchOptions): Promise<TopItem[]>;
|
|
93
|
+
getBrowsers(options?: FetchOptions): Promise<TopItem[]>;
|
|
94
|
+
getCountries(options?: FetchOptions): Promise<TopItem[]>;
|
|
95
|
+
getRegions(options?: FetchOptions & { country?: string }): Promise<TopItem[]>;
|
|
96
|
+
getCities(options?: FetchOptions & { country?: string, region?: string }): Promise<TopItem[]>;
|
|
97
|
+
getTimeSeries(options?: FetchOptions): Promise<TimeSeriesDataPoint[]>;
|
|
98
|
+
getGoals(options?: FetchOptions): Promise<GoalConversion[]>;
|
|
99
|
+
}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
// Types
|
|
2
|
+
export type {
|
|
3
|
+
AnalyticsApiConfig,
|
|
4
|
+
ChartProps,
|
|
5
|
+
DashboardSummary,
|
|
6
|
+
DashboardTheme,
|
|
7
|
+
DateRange,
|
|
8
|
+
RealtimeCounterProps,
|
|
9
|
+
RealtimeData,
|
|
10
|
+
StatCardProps,
|
|
11
|
+
TimeSeriesDataPoint,
|
|
12
|
+
TopItem,
|
|
13
|
+
TopListProps,
|
|
14
|
+
} from './types/index';
|
|
15
|
+
/**
|
|
16
|
+
* Analytics Dashboard Module
|
|
17
|
+
*
|
|
18
|
+
* Vue 3 dashboard components and utilities for displaying
|
|
19
|
+
* privacy-focused analytics data.
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```vue
|
|
23
|
+
* <script setup lang="ts">
|
|
24
|
+
* import { AnalyticsDashboard } from '@stacksjs/dynamodb-tooling/analytics/dashboard'
|
|
25
|
+
*
|
|
26
|
+
* const config = {
|
|
27
|
+
* baseUrl: '/api/analytics',
|
|
28
|
+
* siteId: 'my-site',
|
|
29
|
+
* }
|
|
30
|
+
* </script>
|
|
31
|
+
*
|
|
32
|
+
* <template>
|
|
33
|
+
* <AnalyticsDashboard :config="config" />
|
|
34
|
+
* </template>
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
// Components - All 31 dashboard components
|
|
38
|
+
// These are string identifiers that reference .stx component files
|
|
39
|
+
export {
|
|
40
|
+
// Alert & activity
|
|
41
|
+
AlertCard,
|
|
42
|
+
// Main dashboards
|
|
43
|
+
AnalyticsDashboard,
|
|
44
|
+
AnimatedNumber,
|
|
45
|
+
BarChart,
|
|
46
|
+
BrowserBreakdown,
|
|
47
|
+
CampaignBreakdown,
|
|
48
|
+
CountryList,
|
|
49
|
+
DataTable,
|
|
50
|
+
DateRangePicker,
|
|
51
|
+
// Breakdown components
|
|
52
|
+
DeviceBreakdown,
|
|
53
|
+
DonutChart,
|
|
54
|
+
EmptyState,
|
|
55
|
+
EngagementMetrics,
|
|
56
|
+
FilterBar,
|
|
57
|
+
FullAnalyticsDashboard,
|
|
58
|
+
FunnelChart,
|
|
59
|
+
// Conversion & engagement
|
|
60
|
+
GoalsPanel,
|
|
61
|
+
HeatmapChart,
|
|
62
|
+
LiveActivityFeed,
|
|
63
|
+
MetricComparison,
|
|
64
|
+
MiniStats,
|
|
65
|
+
OSBreakdown,
|
|
66
|
+
PageDetailCard,
|
|
67
|
+
ProgressRing,
|
|
68
|
+
RealtimeCounter,
|
|
69
|
+
SparklineChart,
|
|
70
|
+
// Core components
|
|
71
|
+
StatCard,
|
|
72
|
+
ThemeSwitcher,
|
|
73
|
+
// Chart components
|
|
74
|
+
TimeSeriesChart,
|
|
75
|
+
// List & table components
|
|
76
|
+
TopList,
|
|
77
|
+
TrendIndicator,
|
|
78
|
+
// Utilities for component resolution
|
|
79
|
+
allComponents,
|
|
80
|
+
componentRegistry,
|
|
81
|
+
getComponentPath,
|
|
82
|
+
} from './components/index';
|
|
83
|
+
// Composables
|
|
84
|
+
export {
|
|
85
|
+
AnalyticsClient,
|
|
86
|
+
createAnalyticsComposable,
|
|
87
|
+
createRealtimePoller,
|
|
88
|
+
fetchDashboardData,
|
|
89
|
+
} from './composables/useAnalytics';
|
|
90
|
+
// Re-export as useAnalytics alias for convenience
|
|
91
|
+
export { createAnalyticsComposable as useAnalytics } from './composables/useAnalytics';
|
|
92
|
+
// Theme
|
|
93
|
+
export { darkTheme, defaultTheme } from './types/index';
|
|
94
|
+
// Utilities
|
|
95
|
+
export {
|
|
96
|
+
calculateAxisTicks,
|
|
97
|
+
calculateChange,
|
|
98
|
+
type DateRangePreset,
|
|
99
|
+
dateRangePresets,
|
|
100
|
+
formatCompact,
|
|
101
|
+
formatDate,
|
|
102
|
+
formatDateRange,
|
|
103
|
+
formatDuration,
|
|
104
|
+
formatNumber,
|
|
105
|
+
formatPercentage,
|
|
106
|
+
getDateRangeFromPreset,
|
|
107
|
+
} from './utils/index';
|
|
108
|
+
// Re-export with common alias names
|
|
109
|
+
export { calculateChange as calculatePercentageChange } from './utils/index';
|
|
110
|
+
export { getDateRangeFromPreset as getDateRangePreset } from './utils/index';
|