@hanzo/event 0.3.20 → 0.3.22
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/dist/index.cjs +61 -110
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +12 -58
- package/dist/index.d.ts +12 -58
- package/dist/index.mjs +21 -78
- package/dist/index.mjs.map +1 -1
- package/dist/react.cjs +20 -30
- package/dist/react.cjs.map +1 -1
- package/dist/react.mjs +18 -28
- package/dist/react.mjs.map +1 -1
- package/hz.js +7 -8
- package/package.json +4 -1
- package/src/core.test.ts +3 -37
- package/src/core.ts +18 -24
- package/src/dsn.test.ts +28 -18
- package/src/dsn.ts +14 -34
- package/src/events.ts +21 -76
- package/src/hz.test.ts +4 -10
- package/src/version.ts +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
var events = require('@hanzo/events');
|
|
4
|
+
|
|
3
5
|
// src/attribution.ts
|
|
4
6
|
var SOCIAL_HOSTS = [
|
|
5
7
|
"facebook.",
|
|
@@ -82,70 +84,13 @@ var PRODUCT_PROJECT = Object.freeze({
|
|
|
82
84
|
site: "019f9b1e-5785-7359-ad0b-f75db8e58c99"
|
|
83
85
|
// hanzo.ai (marketing; product `site`)
|
|
84
86
|
});
|
|
85
|
-
function dsnForProduct(product) {
|
|
86
|
-
if (!product) return void 0;
|
|
87
|
+
function dsnForProduct(product, key) {
|
|
88
|
+
if (!product || !key) return void 0;
|
|
87
89
|
const projectId = PRODUCT_PROJECT[product];
|
|
88
90
|
if (!projectId) return void 0;
|
|
89
|
-
return `https://${
|
|
90
|
-
}
|
|
91
|
-
var HANZO_PUBLISHABLE_KEY = "pk-live-c88649f1085fb6ad441d8a0072933a9b";
|
|
92
|
-
function defaultPublishableKey(host) {
|
|
93
|
-
return host === void 0 || host === "https://api.hanzo.ai" ? HANZO_PUBLISHABLE_KEY : void 0;
|
|
91
|
+
return `https://${key}@api.hanzo.ai/v1/sentry/${projectId}`;
|
|
94
92
|
}
|
|
95
93
|
|
|
96
|
-
// src/events.ts
|
|
97
|
-
var EVENTS = {
|
|
98
|
-
// Signup funnel: view -> submit -> verify -> completed -> first action.
|
|
99
|
-
SIGNUP_VIEWED: "signup_viewed",
|
|
100
|
-
SIGNUP_SUBMITTED: "signup_submitted",
|
|
101
|
-
SIGNUP_VERIFIED: "signup_verified",
|
|
102
|
-
SIGNUP_COMPLETED: "signup_completed",
|
|
103
|
-
/** A RETURNING user authenticated — the non-signup half of the IAM callback.
|
|
104
|
-
* Keeping it distinct is what stops returning logins from inflating signups. */
|
|
105
|
-
LOGIN_COMPLETED: "login_completed",
|
|
106
|
-
/** Activation: the first moment of real value. ONE event for every product —
|
|
107
|
-
* the product-specific moment is the `action` property (api_call, app_live,
|
|
108
|
-
* chat_reply), never a new event name. */
|
|
109
|
-
FIRST_ACTION: "first_action",
|
|
110
|
-
// Waitlist + referral.
|
|
111
|
-
WAITLIST_JOINED: "waitlist_joined",
|
|
112
|
-
WAITLIST_SHARED: "waitlist_shared",
|
|
113
|
-
REFERRAL_USED: "referral_used",
|
|
114
|
-
REFERRAL_CLAIMED: "referral_claimed",
|
|
115
|
-
// Upgrade-intent + purchase.
|
|
116
|
-
PRICING_VIEWED: "pricing_viewed",
|
|
117
|
-
PLAN_CLICKED: "plan_clicked",
|
|
118
|
-
CHECKOUT_STARTED: "checkout_started",
|
|
119
|
-
ORDER_COMPLETED: "order_completed",
|
|
120
|
-
// Feature usage — generic + the common key surfaces across products.
|
|
121
|
-
FEATURE_USED: "feature_used",
|
|
122
|
-
API_KEY_CREATED: "api_key_created",
|
|
123
|
-
APP_CREATED: "app_created",
|
|
124
|
-
PROJECT_CREATED: "project_created",
|
|
125
|
-
AGENT_CREATED: "agent_created",
|
|
126
|
-
CHAT_STARTED: "chat_started",
|
|
127
|
-
CHAT_MESSAGE_SENT: "chat_message_sent",
|
|
128
|
-
/** The user switched model/endpoint — the single strongest quality signal a
|
|
129
|
-
* chat surface emits (a switch usually follows a bad answer). */
|
|
130
|
-
MODEL_SWITCHED: "model_switched",
|
|
131
|
-
TASK_STARTED: "task_started",
|
|
132
|
-
TASK_COMPLETED: "task_completed",
|
|
133
|
-
// Build → ship. `build_*` is a MODEL producing an artifact; `deploy_*` is that
|
|
134
|
-
// artifact going live. Intent (build_started) is never the same event as the
|
|
135
|
-
// artifact existing (app_created) — conflating them makes the funnel lie.
|
|
136
|
-
BUILD_STARTED: "build_started",
|
|
137
|
-
/** A model finished producing an artifact (an app build, a chat reply, an agent
|
|
138
|
-
* run). Carries `durationMs` — the outcome event owns its own duration, so no
|
|
139
|
-
* paired start event is needed. */
|
|
140
|
-
GENERATION_COMPLETED: "generation_completed",
|
|
141
|
-
GENERATION_FAILED: "generation_failed",
|
|
142
|
-
DEPLOY_STARTED: "deploy_started",
|
|
143
|
-
DEPLOY_SUCCEEDED: "deploy_succeeded",
|
|
144
|
-
DEPLOY_FAILED: "deploy_failed"
|
|
145
|
-
};
|
|
146
|
-
var PAGEVIEW = "$pageview";
|
|
147
|
-
var EXCEPTION = "$exception";
|
|
148
|
-
|
|
149
94
|
// src/scrub.ts
|
|
150
95
|
var REDACTED = "[redacted]";
|
|
151
96
|
var EMAIL_MARK = "[email]";
|
|
@@ -374,7 +319,7 @@ function uuidv7Time(id) {
|
|
|
374
319
|
}
|
|
375
320
|
|
|
376
321
|
// src/version.ts
|
|
377
|
-
var VERSION = "0.3.
|
|
322
|
+
var VERSION = "0.3.21";
|
|
378
323
|
|
|
379
324
|
// src/sentry.ts
|
|
380
325
|
var MAX_FRAMES = 50;
|
|
@@ -825,27 +770,24 @@ var Analytics = class {
|
|
|
825
770
|
enabled: true,
|
|
826
771
|
captureErrors: true,
|
|
827
772
|
...config,
|
|
828
|
-
// The publishable key resolves
|
|
829
|
-
//
|
|
830
|
-
// enough. Most specific first:
|
|
773
|
+
// The publishable key resolves from ONE live source, never a literal baked
|
|
774
|
+
// beside the code. Most specific first:
|
|
831
775
|
// 1. an explicit `ingestKey` in config;
|
|
832
776
|
// 2. NEXT_PUBLIC_PUBLISHABLE_KEY, the inlined build-time env the fleet
|
|
833
|
-
// carries end to end
|
|
834
|
-
// build-arg -> the NEXT_PUBLIC_ prefix Next inlines
|
|
835
|
-
// 3. the hanzo org key baked in `dsn.ts`, on the hanzo cloud only.
|
|
777
|
+
// carries end to end — KMS `deploy/PUBLISHABLE_KEY` -> the PUBLISHABLE_KEY
|
|
778
|
+
// build-arg -> the NEXT_PUBLIC_ prefix Next inlines.
|
|
836
779
|
//
|
|
837
|
-
//
|
|
838
|
-
//
|
|
839
|
-
//
|
|
840
|
-
//
|
|
841
|
-
//
|
|
842
|
-
|
|
843
|
-
// its own cloud (a non-default host) gets no default, so the org this
|
|
844
|
-
// attributes to is never the wrong one.
|
|
845
|
-
ingestKey: config.ingestKey ?? readEnv("NEXT_PUBLIC_PUBLISHABLE_KEY") ?? defaultPublishableKey(config.host ?? DEFAULT_HOST)
|
|
780
|
+
// A surface that provides neither has no key, and its anonymous traffic
|
|
781
|
+
// files under `$public` (which drops track/identify/group and answers 200);
|
|
782
|
+
// the fix is to give it the KMS-sourced env, not to hardcode the org key
|
|
783
|
+
// here. The key is a credential-class value: its home is KMS, and the ONE
|
|
784
|
+
// build reads it from there.
|
|
785
|
+
ingestKey: config.ingestKey ?? readEnv("NEXT_PUBLIC_PUBLISHABLE_KEY")
|
|
846
786
|
};
|
|
847
787
|
this.transport = config.transport ?? new DefaultTransport();
|
|
848
|
-
this.dsn = parseDsn(
|
|
788
|
+
this.dsn = parseDsn(
|
|
789
|
+
config.dsn ?? readEnvDsn() ?? dsnForProduct(this.cfg.product, this.cfg.ingestKey)
|
|
790
|
+
);
|
|
849
791
|
}
|
|
850
792
|
/** errorPlaneEnabled reports whether captured exceptions can actually reach the
|
|
851
793
|
* error host. False means a DSN was never configured — the documented
|
|
@@ -900,7 +842,7 @@ var Analytics = class {
|
|
|
900
842
|
/** pageview records a $pageview for the current (or given) location. */
|
|
901
843
|
pageview(path, properties) {
|
|
902
844
|
const p = path ?? (isBrowser() ? window.location.pathname : void 0);
|
|
903
|
-
this.enqueue("pageview", PAGEVIEW, { path: p, properties });
|
|
845
|
+
this.enqueue("pageview", events.PAGEVIEW, { path: p, properties });
|
|
904
846
|
}
|
|
905
847
|
/** capture records a named product event with optional properties. Commerce
|
|
906
848
|
* fields (productId/quantity/revenue/currency) may be passed for order events. */
|
|
@@ -933,7 +875,7 @@ var Analytics = class {
|
|
|
933
875
|
const handled = context?.handled ?? true;
|
|
934
876
|
const ex = normalizeError2(err);
|
|
935
877
|
ex.handled = handled;
|
|
936
|
-
this.enqueue("event", EXCEPTION, {
|
|
878
|
+
this.enqueue("event", events.EXCEPTION, {
|
|
937
879
|
error: ex,
|
|
938
880
|
properties: {
|
|
939
881
|
...context?.properties,
|
|
@@ -1103,11 +1045,11 @@ var FUNNELS = {
|
|
|
1103
1045
|
products: ["site"],
|
|
1104
1046
|
join: "person",
|
|
1105
1047
|
steps: [
|
|
1106
|
-
s(PAGEVIEW, "Landed"),
|
|
1107
|
-
s(EVENTS.SIGNUP_VIEWED, "Opened signup"),
|
|
1108
|
-
s(EVENTS.SIGNUP_SUBMITTED, "Redirected to Hanzo ID"),
|
|
1109
|
-
s(EVENTS.SIGNUP_COMPLETED, "Account created"),
|
|
1110
|
-
s(EVENTS.FIRST_ACTION, "First action")
|
|
1048
|
+
s(events.PAGEVIEW, "Landed"),
|
|
1049
|
+
s(events.EVENTS.SIGNUP_VIEWED, "Opened signup"),
|
|
1050
|
+
s(events.EVENTS.SIGNUP_SUBMITTED, "Redirected to Hanzo ID"),
|
|
1051
|
+
s(events.EVENTS.SIGNUP_COMPLETED, "Account created"),
|
|
1052
|
+
s(events.EVENTS.FIRST_ACTION, "First action")
|
|
1111
1053
|
]
|
|
1112
1054
|
},
|
|
1113
1055
|
/** The developer activation path: an account is worth nothing until a key has
|
|
@@ -1118,9 +1060,9 @@ var FUNNELS = {
|
|
|
1118
1060
|
products: ["site", "cloud"],
|
|
1119
1061
|
join: "person",
|
|
1120
1062
|
steps: [
|
|
1121
|
-
s(EVENTS.SIGNUP_COMPLETED, "Account created"),
|
|
1122
|
-
s(EVENTS.API_KEY_CREATED, "Key minted"),
|
|
1123
|
-
s(EVENTS.FIRST_ACTION, "First successful API call", {
|
|
1063
|
+
s(events.EVENTS.SIGNUP_COMPLETED, "Account created"),
|
|
1064
|
+
s(events.EVENTS.API_KEY_CREATED, "Key minted"),
|
|
1065
|
+
s(events.EVENTS.FIRST_ACTION, "First successful API call", {
|
|
1124
1066
|
property: "action",
|
|
1125
1067
|
equals: "api_call"
|
|
1126
1068
|
})
|
|
@@ -1132,10 +1074,10 @@ var FUNNELS = {
|
|
|
1132
1074
|
products: ["site", "app", "console"],
|
|
1133
1075
|
join: "person",
|
|
1134
1076
|
steps: [
|
|
1135
|
-
s(EVENTS.PRICING_VIEWED, "Viewed pricing"),
|
|
1136
|
-
s(EVENTS.PLAN_CLICKED, "Chose a plan"),
|
|
1137
|
-
s(EVENTS.CHECKOUT_STARTED, "Started checkout"),
|
|
1138
|
-
s(EVENTS.ORDER_COMPLETED, "Paid")
|
|
1077
|
+
s(events.EVENTS.PRICING_VIEWED, "Viewed pricing"),
|
|
1078
|
+
s(events.EVENTS.PLAN_CLICKED, "Chose a plan"),
|
|
1079
|
+
s(events.EVENTS.CHECKOUT_STARTED, "Started checkout"),
|
|
1080
|
+
s(events.EVENTS.ORDER_COMPLETED, "Paid")
|
|
1139
1081
|
]
|
|
1140
1082
|
},
|
|
1141
1083
|
/** hanzo.app: describe → build → deploy → live URL. The whole product thesis
|
|
@@ -1145,11 +1087,11 @@ var FUNNELS = {
|
|
|
1145
1087
|
products: ["app"],
|
|
1146
1088
|
join: "person",
|
|
1147
1089
|
steps: [
|
|
1148
|
-
s(PAGEVIEW, "Landed"),
|
|
1149
|
-
s(EVENTS.BUILD_STARTED, "Described an app"),
|
|
1150
|
-
s(EVENTS.GENERATION_COMPLETED, "Got a working build"),
|
|
1151
|
-
s(EVENTS.DEPLOY_STARTED, "Hit publish"),
|
|
1152
|
-
s(EVENTS.DEPLOY_SUCCEEDED, "Live URL")
|
|
1090
|
+
s(events.PAGEVIEW, "Landed"),
|
|
1091
|
+
s(events.EVENTS.BUILD_STARTED, "Described an app"),
|
|
1092
|
+
s(events.EVENTS.GENERATION_COMPLETED, "Got a working build"),
|
|
1093
|
+
s(events.EVENTS.DEPLOY_STARTED, "Hit publish"),
|
|
1094
|
+
s(events.EVENTS.DEPLOY_SUCCEEDED, "Live URL")
|
|
1153
1095
|
]
|
|
1154
1096
|
},
|
|
1155
1097
|
/** hanzo.chat: visit → first message → answer. `generation_completed` is what
|
|
@@ -1159,10 +1101,10 @@ var FUNNELS = {
|
|
|
1159
1101
|
products: ["chat"],
|
|
1160
1102
|
join: "person",
|
|
1161
1103
|
steps: [
|
|
1162
|
-
s(PAGEVIEW, "Landed"),
|
|
1163
|
-
s(EVENTS.CHAT_STARTED, "Started a conversation"),
|
|
1164
|
-
s(EVENTS.CHAT_MESSAGE_SENT, "Sent a message"),
|
|
1165
|
-
s(EVENTS.GENERATION_COMPLETED, "Got an answer")
|
|
1104
|
+
s(events.PAGEVIEW, "Landed"),
|
|
1105
|
+
s(events.EVENTS.CHAT_STARTED, "Started a conversation"),
|
|
1106
|
+
s(events.EVENTS.CHAT_MESSAGE_SENT, "Sent a message"),
|
|
1107
|
+
s(events.EVENTS.GENERATION_COMPLETED, "Got an answer")
|
|
1166
1108
|
]
|
|
1167
1109
|
},
|
|
1168
1110
|
/** The cross-surface handoff: the hanzo.ai composer forwards its prompt to
|
|
@@ -1174,15 +1116,15 @@ var FUNNELS = {
|
|
|
1174
1116
|
products: ["site", "chat"],
|
|
1175
1117
|
join: "aggregate",
|
|
1176
1118
|
steps: [
|
|
1177
|
-
s(EVENTS.CHAT_STARTED, "Submitted the hanzo.ai composer", {
|
|
1119
|
+
s(events.EVENTS.CHAT_STARTED, "Submitted the hanzo.ai composer", {
|
|
1178
1120
|
property: "source",
|
|
1179
1121
|
equals: "composer"
|
|
1180
1122
|
}),
|
|
1181
|
-
s(EVENTS.CHAT_STARTED, "Landed in hanzo.chat", {
|
|
1123
|
+
s(events.EVENTS.CHAT_STARTED, "Landed in hanzo.chat", {
|
|
1182
1124
|
property: "referrerProduct",
|
|
1183
1125
|
equals: "site"
|
|
1184
1126
|
}),
|
|
1185
|
-
s(EVENTS.GENERATION_COMPLETED, "Got an answer")
|
|
1127
|
+
s(events.EVENTS.GENERATION_COMPLETED, "Got an answer")
|
|
1186
1128
|
]
|
|
1187
1129
|
}
|
|
1188
1130
|
};
|
|
@@ -1195,14 +1137,14 @@ var GOALS = {
|
|
|
1195
1137
|
// Signup: the conversion is signup_completed, along the site signup funnel.
|
|
1196
1138
|
signup: {
|
|
1197
1139
|
label: "Signup",
|
|
1198
|
-
event: EVENTS.SIGNUP_COMPLETED,
|
|
1140
|
+
event: events.EVENTS.SIGNUP_COMPLETED,
|
|
1199
1141
|
funnelId: "signup",
|
|
1200
1142
|
funnel: eventsOf("signup")
|
|
1201
1143
|
},
|
|
1202
1144
|
// Sale: a completed order qualified as a plan purchase (kind=plan).
|
|
1203
1145
|
sale: {
|
|
1204
1146
|
label: "Sale",
|
|
1205
|
-
event: EVENTS.ORDER_COMPLETED,
|
|
1147
|
+
event: events.EVENTS.ORDER_COMPLETED,
|
|
1206
1148
|
funnelId: "upgrade",
|
|
1207
1149
|
funnel: eventsOf("upgrade"),
|
|
1208
1150
|
filter: { property: "kind", equals: "plan" }
|
|
@@ -1210,7 +1152,7 @@ var GOALS = {
|
|
|
1210
1152
|
// Upgrade intent: a plan click; pricing_viewed is the top of its funnel.
|
|
1211
1153
|
upgradeIntent: {
|
|
1212
1154
|
label: "Upgrade Intent",
|
|
1213
|
-
event: EVENTS.PLAN_CLICKED,
|
|
1155
|
+
event: events.EVENTS.PLAN_CLICKED,
|
|
1214
1156
|
funnelId: "upgrade",
|
|
1215
1157
|
funnel: eventsOf("upgrade")
|
|
1216
1158
|
},
|
|
@@ -1218,7 +1160,7 @@ var GOALS = {
|
|
|
1218
1160
|
// valuable thing (a successful API call, a live app, a chat answer).
|
|
1219
1161
|
activation: {
|
|
1220
1162
|
label: "Activation",
|
|
1221
|
-
event: EVENTS.FIRST_ACTION,
|
|
1163
|
+
event: events.EVENTS.FIRST_ACTION,
|
|
1222
1164
|
funnelId: "apiActivation",
|
|
1223
1165
|
funnel: eventsOf("apiActivation")
|
|
1224
1166
|
}
|
|
@@ -1250,13 +1192,22 @@ var COHORTS = {
|
|
|
1250
1192
|
* reformat of one copy is a diff against the other.
|
|
1251
1193
|
*/
|
|
1252
1194
|
|
|
1195
|
+
Object.defineProperty(exports, "EVENTS", {
|
|
1196
|
+
enumerable: true,
|
|
1197
|
+
get: function () { return events.EVENTS; }
|
|
1198
|
+
});
|
|
1199
|
+
Object.defineProperty(exports, "EXCEPTION", {
|
|
1200
|
+
enumerable: true,
|
|
1201
|
+
get: function () { return events.EXCEPTION; }
|
|
1202
|
+
});
|
|
1203
|
+
Object.defineProperty(exports, "PAGEVIEW", {
|
|
1204
|
+
enumerable: true,
|
|
1205
|
+
get: function () { return events.PAGEVIEW; }
|
|
1206
|
+
});
|
|
1253
1207
|
exports.Analytics = Analytics;
|
|
1254
1208
|
exports.COHORTS = COHORTS;
|
|
1255
|
-
exports.EVENTS = EVENTS;
|
|
1256
|
-
exports.EXCEPTION = EXCEPTION;
|
|
1257
1209
|
exports.FUNNELS = FUNNELS;
|
|
1258
1210
|
exports.GOALS = GOALS;
|
|
1259
|
-
exports.PAGEVIEW = PAGEVIEW;
|
|
1260
1211
|
exports.PRODUCTS = PRODUCTS;
|
|
1261
1212
|
exports.PRODUCT_PROJECT = PRODUCT_PROJECT;
|
|
1262
1213
|
exports.VERSION = VERSION;
|