@jmp-technologies/analytics 0.1.25 → 0.1.27

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 (100) hide show
  1. package/README.md +43 -0
  2. package/bin/jmp-init.mjs +34 -0
  3. package/dist/astro/client.cjs +103 -0
  4. package/dist/astro/client.cjs.map +1 -1
  5. package/dist/astro/client.d.cts +2 -2
  6. package/dist/astro/client.d.ts +2 -2
  7. package/dist/astro/client.js +5 -3
  8. package/dist/astro/client.js.map +1 -1
  9. package/dist/astro/content.cjs +271 -1
  10. package/dist/astro/content.cjs.map +1 -1
  11. package/dist/astro/content.d.cts +9 -3
  12. package/dist/astro/content.d.ts +9 -3
  13. package/dist/astro/content.js +10 -3
  14. package/dist/astro/integration.cjs +56 -10
  15. package/dist/astro/integration.cjs.map +1 -1
  16. package/dist/astro/integration.js +4 -3
  17. package/dist/astro/integration.js.map +1 -1
  18. package/dist/astro/middleware.cjs.map +1 -1
  19. package/dist/astro/middleware.d.cts +2 -2
  20. package/dist/astro/middleware.d.ts +2 -2
  21. package/dist/astro/middleware.js +2 -2
  22. package/dist/astro/register.cjs +56 -10
  23. package/dist/astro/register.cjs.map +1 -1
  24. package/dist/astro/register.js +4 -3
  25. package/dist/{chunk-MOX7RJUU.js → chunk-A4RRTY5D.js} +1 -1
  26. package/dist/{chunk-MOX7RJUU.js.map → chunk-A4RRTY5D.js.map} +1 -1
  27. package/dist/{chunk-L67PVZYL.js → chunk-DNYJF7BG.js} +3 -24
  28. package/dist/chunk-DNYJF7BG.js.map +1 -0
  29. package/dist/{chunk-5GORAM7J.js → chunk-FNWE2DT5.js} +2 -2
  30. package/dist/{chunk-7MLPSL6T.js → chunk-HODG4NJQ.js} +2 -2
  31. package/dist/{chunk-OLWCYWVB.js → chunk-KZ4WVDGL.js} +3 -3
  32. package/dist/{chunk-AJ33NQVZ.js → chunk-PG3IOI5O.js} +42 -3
  33. package/dist/chunk-PG3IOI5O.js.map +1 -0
  34. package/dist/chunk-TCZ6TC2L.js +149 -0
  35. package/dist/chunk-TCZ6TC2L.js.map +1 -0
  36. package/dist/{chunk-VRDPVKAN.js → chunk-UVYF33XE.js} +213 -157
  37. package/dist/chunk-UVYF33XE.js.map +1 -0
  38. package/dist/chunk-YCVHRMM6.js +28 -0
  39. package/dist/chunk-YCVHRMM6.js.map +1 -0
  40. package/dist/{create-jmp-analytics-ClLOMb9p.d.cts → create-jmp-analytics-D4Qw_d6o.d.cts} +1 -1
  41. package/dist/{create-jmp-analytics-COxo3-yg.d.ts → create-jmp-analytics-DpG5Hdl5.d.ts} +1 -1
  42. package/dist/index.cjs +213 -12
  43. package/dist/index.cjs.map +1 -1
  44. package/dist/index.d.cts +22 -7
  45. package/dist/index.d.ts +22 -7
  46. package/dist/index.js +19 -3
  47. package/dist/next/content.cjs +274 -1
  48. package/dist/next/content.cjs.map +1 -1
  49. package/dist/next/content.d.cts +7 -4
  50. package/dist/next/content.d.ts +7 -4
  51. package/dist/next/content.js +13 -3
  52. package/dist/next/content.js.map +1 -1
  53. package/dist/next/instrumentation.cjs +56 -10
  54. package/dist/next/instrumentation.cjs.map +1 -1
  55. package/dist/next/instrumentation.js +3 -2
  56. package/dist/next/instrumentation.js.map +1 -1
  57. package/dist/next/landing-capture-script-server.cjs +61 -0
  58. package/dist/next/landing-capture-script-server.cjs.map +1 -0
  59. package/dist/next/landing-capture-script-server.d.cts +14 -0
  60. package/dist/next/landing-capture-script-server.d.ts +14 -0
  61. package/dist/next/landing-capture-script-server.js +8 -0
  62. package/dist/next/landing-capture-script-server.js.map +1 -0
  63. package/dist/next/landing-pages.cjs +659 -0
  64. package/dist/next/landing-pages.cjs.map +1 -0
  65. package/dist/next/landing-pages.d.cts +104 -0
  66. package/dist/next/landing-pages.d.ts +104 -0
  67. package/dist/next/landing-pages.js +299 -0
  68. package/dist/next/landing-pages.js.map +1 -0
  69. package/dist/next/middleware.cjs.map +1 -1
  70. package/dist/next/middleware.d.cts +2 -2
  71. package/dist/next/middleware.d.ts +2 -2
  72. package/dist/next/middleware.js +2 -2
  73. package/dist/next/site-root-server.cjs +159 -23
  74. package/dist/next/site-root-server.cjs.map +1 -1
  75. package/dist/next/site-root-server.js +9 -4
  76. package/dist/next/site-root-server.js.map +1 -1
  77. package/dist/next.cjs +152 -70
  78. package/dist/next.cjs.map +1 -1
  79. package/dist/next.d.cts +7 -15
  80. package/dist/next.d.ts +7 -15
  81. package/dist/next.js +7 -7
  82. package/dist/react.cjs +103 -0
  83. package/dist/react.cjs.map +1 -1
  84. package/dist/react.d.cts +2 -2
  85. package/dist/react.d.ts +2 -2
  86. package/dist/react.js +4 -3
  87. package/dist/{site-config-BSMVyUjk.d.ts → site-config-CJqYnZm7.d.cts} +6 -3
  88. package/dist/{site-config-8TTHIW6w.d.cts → site-config-UTzDG-UG.d.ts} +6 -3
  89. package/dist/{track-page-view-DtxbdM5q.d.ts → track-page-view-CMAqyhD_.d.ts} +1 -1
  90. package/dist/{track-page-view-BweavmXz.d.cts → track-page-view-tX0Magkd.d.cts} +1 -1
  91. package/dist/{types-Bk0ST1aH.d.ts → types-B-111Wht.d.cts} +52 -5
  92. package/dist/{types-Bk0ST1aH.d.cts → types-B-111Wht.d.ts} +52 -5
  93. package/docs/astro-integration.md +1 -1
  94. package/package.json +16 -2
  95. package/dist/chunk-AJ33NQVZ.js.map +0 -1
  96. package/dist/chunk-L67PVZYL.js.map +0 -1
  97. package/dist/chunk-VRDPVKAN.js.map +0 -1
  98. /package/dist/{chunk-5GORAM7J.js.map → chunk-FNWE2DT5.js.map} +0 -0
  99. /package/dist/{chunk-7MLPSL6T.js.map → chunk-HODG4NJQ.js.map} +0 -0
  100. /package/dist/{chunk-OLWCYWVB.js.map → chunk-KZ4WVDGL.js.map} +0 -0
@@ -35,6 +35,7 @@ __export(site_root_server_exports, {
35
35
  module.exports = __toCommonJS(site_root_server_exports);
36
36
 
37
37
  // src/constants.ts
38
+ var JMP_ANALYTICS_SDK_VERSION = "0.1.26";
38
39
  var JMP_TRACKING_CONSENT_STORAGE_KEY = "jmp_analytics_consent_v1";
39
40
  var DEFAULT_JMP_BROWSER_PAGE_VIEW_DEDUPE_MS = 2500;
40
41
 
@@ -120,14 +121,147 @@ async function getContentText(config, path) {
120
121
  return text;
121
122
  }
122
123
 
124
+ // src/content/wrapper-discovery.ts
125
+ var WRAPPER_SLOT_ORDER = [
126
+ "blog",
127
+ "faq",
128
+ "contact",
129
+ "trust",
130
+ "trust.summary",
131
+ "trust.testimonials",
132
+ "trust.reviews",
133
+ "trust.stats",
134
+ "trust.logos",
135
+ "trust.credentials"
136
+ ];
137
+ var discovered = /* @__PURE__ */ new Set();
138
+ var syncTimer = null;
139
+ var pendingSyncConfig = null;
140
+ var reportedDedupeKeys = /* @__PURE__ */ new Set();
141
+ var syncHandler = null;
142
+ function markContentWrapper(slot) {
143
+ const normalized = slot.trim().toLowerCase();
144
+ if (!normalized) {
145
+ return;
146
+ }
147
+ discovered.add(normalized);
148
+ }
149
+ function getDiscoveredContentWrappers() {
150
+ return sortWrapperSlots([...discovered]);
151
+ }
152
+ function resolveContentWrappersForReport(config) {
153
+ const explicit = config.contentWrappers ?? [];
154
+ const auto = getDiscoveredContentWrappers();
155
+ if (config.contentWrapperMode === "manual") {
156
+ return sortWrapperSlots([...explicit]);
157
+ }
158
+ if (config.contentWrapperMode === "explicit-only") {
159
+ return sortWrapperSlots([...explicit]);
160
+ }
161
+ const merged = /* @__PURE__ */ new Set([...explicit, ...auto]);
162
+ return sortWrapperSlots([...merged]);
163
+ }
164
+ function hasReportedContentWrappers(dedupeKey) {
165
+ return reportedDedupeKeys.has(dedupeKey);
166
+ }
167
+ function rememberReportedContentWrappers(dedupeKey) {
168
+ reportedDedupeKeys.add(dedupeKey);
169
+ }
170
+ function setContentWrapperSyncHandler(handler) {
171
+ syncHandler = handler;
172
+ }
173
+ function scheduleContentWrapperSync(config) {
174
+ if (!syncHandler) {
175
+ return;
176
+ }
177
+ pendingSyncConfig = config;
178
+ if (syncTimer) {
179
+ clearTimeout(syncTimer);
180
+ }
181
+ syncTimer = setTimeout(() => {
182
+ syncTimer = null;
183
+ const cfg = pendingSyncConfig;
184
+ pendingSyncConfig = null;
185
+ if (!cfg || !syncHandler) {
186
+ return;
187
+ }
188
+ void syncHandler(cfg).catch(() => {
189
+ });
190
+ }, 750);
191
+ }
192
+ function sortWrapperSlots(slots) {
193
+ const order = new Map(WRAPPER_SLOT_ORDER.map((slot, index) => [slot, index]));
194
+ return [...new Set(slots)].sort((a, b) => {
195
+ const ai = order.get(a) ?? 999;
196
+ const bi = order.get(b) ?? 999;
197
+ if (ai !== bi) {
198
+ return ai - bi;
199
+ }
200
+ return a.localeCompare(b);
201
+ });
202
+ }
203
+
123
204
  // src/content/api.ts
205
+ function afterContentWrapperUse(config) {
206
+ scheduleContentWrapperSync(config);
207
+ }
124
208
  async function getJmpSiteProfile(config) {
125
209
  const data = await getContent(
126
210
  config,
127
211
  "/api/content/site"
128
212
  );
213
+ markContentWrapper("contact");
214
+ afterContentWrapperUse(config);
129
215
  return data.site;
130
216
  }
217
+ async function registerJmpContentWrappers(config) {
218
+ const wrappers = resolveContentWrappersForReport(config);
219
+ if (!wrappers.length) {
220
+ return { ok: false, skipped: true };
221
+ }
222
+ const dedupeKey = `${config.trackingKey}:${[...wrappers].sort().join(",")}`;
223
+ if (hasReportedContentWrappers(dedupeKey)) {
224
+ return { ok: true, wrappers };
225
+ }
226
+ const baseUrl = normalizeBaseUrl(config.baseUrl);
227
+ const resolvedFetch = config.fetchImpl ?? (typeof globalThis !== "undefined" && globalThis.fetch ? globalThis.fetch.bind(globalThis) : void 0);
228
+ if (!resolvedFetch) {
229
+ throw new Error(
230
+ "JMP content wrappers: fetch is not available; pass fetchImpl in config"
231
+ );
232
+ }
233
+ const url = `${baseUrl}/api/content/capabilities`;
234
+ if (config.debug) {
235
+ console.debug("[@jmp-technologies/analytics]", "POST", url, { wrappers });
236
+ }
237
+ const res = await resolvedFetch(url, {
238
+ method: "POST",
239
+ headers: {
240
+ "Content-Type": "application/json",
241
+ "X-JMP-Tracking-Key": config.trackingKey
242
+ },
243
+ body: JSON.stringify({
244
+ wrappers,
245
+ sdkVersion: JMP_ANALYTICS_SDK_VERSION
246
+ })
247
+ });
248
+ const text = await res.text();
249
+ if (!res.ok) {
250
+ let parsed = {};
251
+ try {
252
+ parsed = JSON.parse(text);
253
+ } catch {
254
+ parsed = { error: text };
255
+ }
256
+ throw new Error(
257
+ [`JMP content wrappers HTTP ${res.status}`, parsed.error, parsed.hint].filter(Boolean).join(" \u2014 ")
258
+ );
259
+ }
260
+ rememberReportedContentWrappers(dedupeKey);
261
+ const data = JSON.parse(text);
262
+ return { ok: true, wrappers: data.wrappers ?? wrappers };
263
+ }
264
+ setContentWrapperSyncHandler(registerJmpContentWrappers);
131
265
 
132
266
  // src/env-public.ts
133
267
  function firstDefined(...values) {
@@ -193,7 +327,6 @@ function getJmpContentConfig() {
193
327
  }
194
328
 
195
329
  // src/next.tsx
196
- var import_script2 = __toESM(require("next/script"), 1);
197
330
  var import_react3 = require("react");
198
331
  var import_navigation2 = require("next/navigation");
199
332
 
@@ -986,23 +1119,6 @@ function JmpGoogleTagPagePath({ gaId }) {
986
1119
 
987
1120
  // src/next.tsx
988
1121
  var import_jsx_runtime3 = require("react/jsx-runtime");
989
- function JmpLandingCaptureScript({
990
- trackingKey = readJmpPublicEnvFromProcess().trackingKey
991
- } = {}) {
992
- if (!trackingKey?.trim()) {
993
- return null;
994
- }
995
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
996
- import_script2.default,
997
- {
998
- id: "jmp-landing-capture",
999
- strategy: "beforeInteractive",
1000
- dangerouslySetInnerHTML: {
1001
- __html: buildLandingCaptureInlineScript()
1002
- }
1003
- }
1004
- );
1005
- }
1006
1122
  function JmpNextPageViewTrackerInner({
1007
1123
  configOverrides
1008
1124
  }) {
@@ -1062,7 +1178,6 @@ function JmpNextAnalytics({
1062
1178
  }
1063
1179
  return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
1064
1180
  /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(JmpNextAnalyticsBootstrap, { configOverrides }),
1065
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(JmpLandingCaptureScript, { trackingKey }),
1066
1181
  /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(JmpNextPageViewTracker, { configOverrides })
1067
1182
  ] });
1068
1183
  }
@@ -1085,8 +1200,28 @@ function JmpSiteRoot({
1085
1200
  ] });
1086
1201
  }
1087
1202
 
1088
- // src/next/site-root-server.tsx
1203
+ // src/next/landing-capture-script-server.tsx
1089
1204
  var import_jsx_runtime4 = require("react/jsx-runtime");
1205
+ function JmpLandingCaptureScriptServer({
1206
+ trackingKey
1207
+ } = {}) {
1208
+ if (!trackingKey?.trim()) {
1209
+ return null;
1210
+ }
1211
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1212
+ "script",
1213
+ {
1214
+ dangerouslySetInnerHTML: {
1215
+ __html: buildLandingCaptureInlineScript()
1216
+ },
1217
+ id: "jmp-landing-capture",
1218
+ suppressHydrationWarning: true
1219
+ }
1220
+ );
1221
+ }
1222
+
1223
+ // src/next/site-root-server.tsx
1224
+ var import_jsx_runtime5 = require("react/jsx-runtime");
1090
1225
  async function resolveGaMeasurementId(gaFromPortal) {
1091
1226
  const fromEnv = process.env.NEXT_PUBLIC_GA_MEASUREMENT_ID?.trim();
1092
1227
  if (fromEnv) {
@@ -1114,9 +1249,10 @@ async function JmpSiteRootServer({
1114
1249
  const pub = readJmpPublicEnvFromProcess();
1115
1250
  const site = getJmpSiteDefinition();
1116
1251
  const gaId = await resolveGaMeasurementId(gaFromPortal);
1117
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
1118
- gaId ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(JmpGoogleTag, { gaId }) : null,
1119
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1252
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
1253
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(JmpLandingCaptureScriptServer, { trackingKey: pub.trackingKey }),
1254
+ gaId ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(JmpGoogleTag, { gaId }) : null,
1255
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1120
1256
  JmpSiteRoot,
1121
1257
  {
1122
1258
  analyticsUrl: pub.analyticsUrl ?? site?.analyticsPortalUrl,