@nextlytics/core 0.2.2 → 0.3.0-canary.80
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/api-handler.d.ts +11 -0
- package/dist/api-handler.js +182 -0
- package/dist/backends/ga.d.ts +5 -0
- package/dist/backends/ga.js +93 -17
- package/dist/backends/gtm.js +25 -8
- package/dist/backends/logging.js +33 -0
- package/dist/backends/segment.js +50 -17
- package/dist/client-utils.d.ts +35 -0
- package/dist/client-utils.js +121 -0
- package/dist/client.d.ts +1 -4
- package/dist/client.js +146 -67
- package/dist/config-helpers.d.ts +2 -2
- package/dist/config-helpers.js +3 -18
- package/dist/index.d.ts +3 -3
- package/dist/index.js +1 -3
- package/dist/middleware.d.ts +2 -3
- package/dist/middleware.js +66 -127
- package/dist/pages-router.d.ts +6 -31
- package/dist/pages-router.js +1 -2
- package/dist/server-component-context.d.ts +10 -11
- package/dist/server-component-context.js +18 -28
- package/dist/server.d.ts +1 -6
- package/dist/server.js +59 -33
- package/dist/stable-hash.d.ts +6 -0
- package/dist/stable-hash.js +76 -0
- package/dist/types.d.ts +78 -17
- package/dist/uitils.d.ts +7 -1
- package/dist/uitils.js +39 -5
- package/package.json +1 -1
- package/dist/handlers.d.ts +0 -9
- package/dist/handlers.js +0 -123
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
"use client";
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
11
|
+
var __copyProps = (to, from, except, desc) => {
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
+
for (let key of __getOwnPropNames(from))
|
|
14
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
20
|
+
var client_utils_exports = {};
|
|
21
|
+
__export(client_utils_exports, {
|
|
22
|
+
InjectScript: () => InjectScript,
|
|
23
|
+
debug: () => debug,
|
|
24
|
+
useNavigation: () => useNavigation,
|
|
25
|
+
usePathnameSafe: () => usePathnameSafe
|
|
26
|
+
});
|
|
27
|
+
module.exports = __toCommonJS(client_utils_exports);
|
|
28
|
+
var import_react = require("react");
|
|
29
|
+
const DEBUG_KEY = "nextlytics:debug";
|
|
30
|
+
function isDebugEnabled() {
|
|
31
|
+
if (typeof window === "undefined") return false;
|
|
32
|
+
try {
|
|
33
|
+
return localStorage.getItem(DEBUG_KEY) === "true";
|
|
34
|
+
} catch {
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
const debug = (...args) => {
|
|
39
|
+
if (!isDebugEnabled()) return;
|
|
40
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString().split("T")[1].slice(0, -1);
|
|
41
|
+
console.log(`[${timestamp}] [Nextlytics]`, ...args);
|
|
42
|
+
};
|
|
43
|
+
let usePathnameImpl = null;
|
|
44
|
+
try {
|
|
45
|
+
usePathnameImpl = require("next/navigation").usePathname;
|
|
46
|
+
} catch {
|
|
47
|
+
}
|
|
48
|
+
function usePathnameSafe() {
|
|
49
|
+
if (!usePathnameImpl) return null;
|
|
50
|
+
return usePathnameImpl();
|
|
51
|
+
}
|
|
52
|
+
function useNavigation(requestId, onNavigate) {
|
|
53
|
+
const pathname = usePathnameSafe();
|
|
54
|
+
const stateRef = (0, import_react.useRef)(null);
|
|
55
|
+
const onNavigateRef = (0, import_react.useRef)(onNavigate);
|
|
56
|
+
onNavigateRef.current = onNavigate;
|
|
57
|
+
(0, import_react.useEffect)(() => {
|
|
58
|
+
const prev = stateRef.current;
|
|
59
|
+
const isInitial = prev === null;
|
|
60
|
+
const requestIdChanged = !isInitial && prev.requestId !== requestId;
|
|
61
|
+
const pathnameChanged = !isInitial && pathname !== null && prev.pathname !== pathname;
|
|
62
|
+
stateRef.current = { requestId, pathname };
|
|
63
|
+
if (!isInitial && !requestIdChanged && !pathnameChanged) {
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
const softNavigation = !isInitial && !requestIdChanged && pathnameChanged;
|
|
67
|
+
debug("Navigation", {
|
|
68
|
+
isInitial,
|
|
69
|
+
softNavigation,
|
|
70
|
+
requestId,
|
|
71
|
+
pathname,
|
|
72
|
+
requestIdChanged,
|
|
73
|
+
pathnameChanged
|
|
74
|
+
});
|
|
75
|
+
if (softNavigation) {
|
|
76
|
+
const controller = new AbortController();
|
|
77
|
+
onNavigateRef.current({ softNavigation: true, signal: controller.signal });
|
|
78
|
+
return () => {
|
|
79
|
+
debug("Aborting previous soft navigation request");
|
|
80
|
+
controller.abort();
|
|
81
|
+
};
|
|
82
|
+
} else {
|
|
83
|
+
onNavigateRef.current({ softNavigation: false });
|
|
84
|
+
}
|
|
85
|
+
}, [requestId, pathname]);
|
|
86
|
+
}
|
|
87
|
+
function arraysEqual(a, b) {
|
|
88
|
+
if (a === b) return true;
|
|
89
|
+
if (!a || !b || a.length !== b.length) return false;
|
|
90
|
+
return a.every((v, i) => v === b[i]);
|
|
91
|
+
}
|
|
92
|
+
const InjectScript = (0, import_react.memo)(
|
|
93
|
+
function InjectScript2({ body, src, async: isAsync, deps = [] }) {
|
|
94
|
+
const depsKey = deps.map(String).join("\0");
|
|
95
|
+
(0, import_react.useEffect)(() => {
|
|
96
|
+
const el = document.createElement("script");
|
|
97
|
+
if (src) {
|
|
98
|
+
el.src = src;
|
|
99
|
+
if (isAsync) el.async = true;
|
|
100
|
+
debug("Inject external", { src, deps });
|
|
101
|
+
} else if (body) {
|
|
102
|
+
el.textContent = body;
|
|
103
|
+
debug("Inject inline", { body: body.slice(0, 100), deps });
|
|
104
|
+
}
|
|
105
|
+
document.head.appendChild(el);
|
|
106
|
+
return () => {
|
|
107
|
+
debug("Remove script", { deps });
|
|
108
|
+
el.remove();
|
|
109
|
+
};
|
|
110
|
+
}, [depsKey]);
|
|
111
|
+
return null;
|
|
112
|
+
},
|
|
113
|
+
(prev, next) => prev.body === next.body && prev.src === next.src && prev.async === next.async && arraysEqual(prev.deps, next.deps)
|
|
114
|
+
);
|
|
115
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
116
|
+
0 && (module.exports = {
|
|
117
|
+
InjectScript,
|
|
118
|
+
debug,
|
|
119
|
+
useNavigation,
|
|
120
|
+
usePathnameSafe
|
|
121
|
+
});
|
package/dist/client.d.ts
CHANGED
|
@@ -11,10 +11,7 @@ type NextlyticsContext = {
|
|
|
11
11
|
templates?: Record<string, JavascriptTemplate>;
|
|
12
12
|
};
|
|
13
13
|
declare function NextlyticsClient(props: {
|
|
14
|
-
ctx
|
|
15
|
-
requestId?: string;
|
|
16
|
-
scripts?: TemplatizedScriptInsertion<unknown>[];
|
|
17
|
-
templates?: Record<string, JavascriptTemplate>;
|
|
14
|
+
ctx: NextlyticsContext;
|
|
18
15
|
children?: ReactNode;
|
|
19
16
|
}): react_jsx_runtime.JSX.Element;
|
|
20
17
|
type NextlyticsClientApi = {
|
package/dist/client.js
CHANGED
|
@@ -25,13 +25,15 @@ __export(client_exports, {
|
|
|
25
25
|
module.exports = __toCommonJS(client_exports);
|
|
26
26
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
27
27
|
var import_react = require("react");
|
|
28
|
+
var import_client_utils = require("./client-utils");
|
|
28
29
|
var import_server_component_context = require("./server-component-context");
|
|
29
30
|
var import_template = require("./template");
|
|
31
|
+
var import_stable_hash = require("./stable-hash");
|
|
30
32
|
const templateFunctions = {
|
|
31
33
|
q: (v) => JSON.stringify(v ?? null),
|
|
32
|
-
json: (v) => JSON.stringify(v ?? null)
|
|
34
|
+
json: (v) => JSON.stringify(v ?? null),
|
|
35
|
+
stableHash: (v) => (0, import_stable_hash.stableHash)(v)
|
|
33
36
|
};
|
|
34
|
-
const compiledCache = {};
|
|
35
37
|
const NextlyticsContext = (0, import_react.createContext)(null);
|
|
36
38
|
function createClientContext() {
|
|
37
39
|
const isBrowser = typeof window !== "undefined";
|
|
@@ -39,6 +41,11 @@ function createClientContext() {
|
|
|
39
41
|
collectedAt: /* @__PURE__ */ new Date(),
|
|
40
42
|
referer: isBrowser ? document.referrer || void 0 : void 0,
|
|
41
43
|
path: isBrowser ? window.location.pathname : void 0,
|
|
44
|
+
url: isBrowser ? window.location.href : void 0,
|
|
45
|
+
host: isBrowser ? window.location.host : void 0,
|
|
46
|
+
search: isBrowser ? window.location.search : void 0,
|
|
47
|
+
hash: isBrowser ? window.location.hash : void 0,
|
|
48
|
+
title: isBrowser ? document.title : void 0,
|
|
42
49
|
screen: {
|
|
43
50
|
width: isBrowser ? window.screen.width : void 0,
|
|
44
51
|
height: isBrowser ? window.screen.height : void 0,
|
|
@@ -50,94 +57,165 @@ function createClientContext() {
|
|
|
50
57
|
locale: isBrowser ? navigator.language : void 0
|
|
51
58
|
};
|
|
52
59
|
}
|
|
53
|
-
function
|
|
54
|
-
const
|
|
55
|
-
|
|
56
|
-
compiledCache[cacheKey] = {
|
|
57
|
-
src: item.src ? (0, import_template.compile)(item.src) : void 0,
|
|
58
|
-
body: item.body ? (0, import_template.compile)(item.body) : void 0
|
|
59
|
-
};
|
|
60
|
-
}
|
|
61
|
-
return compiledCache[cacheKey];
|
|
62
|
-
}
|
|
63
|
-
function executeTemplatedScripts(scripts, templates) {
|
|
64
|
-
if (!scripts || typeof window === "undefined") return;
|
|
60
|
+
function deduplicateScripts(scripts, templates) {
|
|
61
|
+
const result = [];
|
|
62
|
+
const firstSeenByDeps = /* @__PURE__ */ new Set();
|
|
65
63
|
for (const script of scripts) {
|
|
66
|
-
if (script.type !== "script-template")
|
|
67
|
-
|
|
64
|
+
if (script.type !== "script-template") continue;
|
|
65
|
+
const template = templates[script.templateId];
|
|
66
|
+
if (!template) continue;
|
|
67
|
+
if (!template.deps) {
|
|
68
|
+
result.push(script);
|
|
68
69
|
continue;
|
|
69
70
|
}
|
|
71
|
+
const paramsRecord = script.params || {};
|
|
72
|
+
const deps = compileTemplateDeps(template, paramsRecord);
|
|
73
|
+
const depsKey = `${script.templateId}\0${deps.join("\0")}`;
|
|
74
|
+
if (firstSeenByDeps.has(depsKey)) continue;
|
|
75
|
+
firstSeenByDeps.add(depsKey);
|
|
76
|
+
result.push(script);
|
|
77
|
+
}
|
|
78
|
+
return result;
|
|
79
|
+
}
|
|
80
|
+
function compileScripts(scripts, templates) {
|
|
81
|
+
const result = [];
|
|
82
|
+
for (const [scriptIndex, script] of scripts.entries()) {
|
|
83
|
+
if (script.type !== "script-template") continue;
|
|
70
84
|
const template = templates[script.templateId];
|
|
71
85
|
if (!template) {
|
|
72
|
-
console.warn(`[Nextlytics]
|
|
86
|
+
console.warn(`[Nextlytics] Template "${script.templateId}" not found`);
|
|
73
87
|
continue;
|
|
74
88
|
}
|
|
75
|
-
const
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
const
|
|
80
|
-
if (item.
|
|
89
|
+
const paramsRecord = script.params || {};
|
|
90
|
+
const deps = compileTemplateDeps(template, paramsRecord);
|
|
91
|
+
let itemIndex = 0;
|
|
92
|
+
for (const item of template.items) {
|
|
93
|
+
const keyPrefix = `${script.templateId}:${scriptIndex}:${item.src ? "ext" : "body"}:${itemIndex}`;
|
|
94
|
+
if (item.src) {
|
|
95
|
+
const compiledSrc = (0, import_template.compile)(item.src);
|
|
96
|
+
const src = (0, import_template.apply)(compiledSrc, paramsRecord, templateFunctions);
|
|
97
|
+
result.push({
|
|
98
|
+
key: keyPrefix,
|
|
99
|
+
src,
|
|
100
|
+
async: item.async,
|
|
101
|
+
deps
|
|
102
|
+
});
|
|
103
|
+
itemIndex++;
|
|
81
104
|
continue;
|
|
82
105
|
}
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
}
|
|
87
|
-
if (compiled.body) {
|
|
88
|
-
el.textContent = (0, import_template.apply)(compiled.body, params, templateFunctions);
|
|
89
|
-
}
|
|
90
|
-
if (item.async) {
|
|
91
|
-
el.async = true;
|
|
106
|
+
if (!item.body) {
|
|
107
|
+
itemIndex++;
|
|
108
|
+
continue;
|
|
92
109
|
}
|
|
93
|
-
|
|
110
|
+
const bodyText = Array.isArray(item.body) ? item.body.join("\n") : item.body;
|
|
111
|
+
const compiled = (0, import_template.compile)(bodyText);
|
|
112
|
+
const body = (0, import_template.apply)(compiled, paramsRecord, templateFunctions);
|
|
113
|
+
result.push({ key: keyPrefix, body, deps });
|
|
114
|
+
itemIndex++;
|
|
94
115
|
}
|
|
95
116
|
}
|
|
117
|
+
return result;
|
|
118
|
+
}
|
|
119
|
+
function compileTemplateDeps(template, paramsRecord) {
|
|
120
|
+
if (!template.deps) return [];
|
|
121
|
+
const rawDeps = Array.isArray(template.deps) ? template.deps : [template.deps];
|
|
122
|
+
return rawDeps.map((dep) => (0, import_template.apply)((0, import_template.compile)(dep), paramsRecord, templateFunctions));
|
|
96
123
|
}
|
|
97
|
-
|
|
124
|
+
function NextlyticsScripts({
|
|
125
|
+
initialScripts
|
|
126
|
+
}) {
|
|
127
|
+
const context = (0, import_react.useContext)(NextlyticsContext);
|
|
128
|
+
if (!context) {
|
|
129
|
+
throw new Error("NextlyticsScripts should be called within NextlyticsContext");
|
|
130
|
+
}
|
|
131
|
+
const { scriptsRef, subscribersRef, templates } = context;
|
|
132
|
+
const [, forceUpdate] = (0, import_react.useReducer)((x) => x + 1, 0);
|
|
133
|
+
(0, import_react.useEffect)(() => {
|
|
134
|
+
subscribersRef.current.add(forceUpdate);
|
|
135
|
+
return () => {
|
|
136
|
+
subscribersRef.current.delete(forceUpdate);
|
|
137
|
+
};
|
|
138
|
+
}, [subscribersRef]);
|
|
139
|
+
const allScripts = [...initialScripts, ...scriptsRef.current];
|
|
140
|
+
const dedupedScripts = (0, import_react.useMemo)(
|
|
141
|
+
() => deduplicateScripts(allScripts, templates),
|
|
142
|
+
[allScripts, templates]
|
|
143
|
+
);
|
|
144
|
+
const compiled = (0, import_react.useMemo)(
|
|
145
|
+
() => compileScripts(dedupedScripts, templates),
|
|
146
|
+
[dedupedScripts, templates]
|
|
147
|
+
);
|
|
148
|
+
(0, import_client_utils.debug)("Rendering scripts", {
|
|
149
|
+
initialCount: initialScripts.length,
|
|
150
|
+
dynamicCount: scriptsRef.current.length,
|
|
151
|
+
totalCount: allScripts.length,
|
|
152
|
+
compiledCount: compiled.length
|
|
153
|
+
});
|
|
154
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children: compiled.map(({ key, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_client_utils.InjectScript, { ...props }, key)) });
|
|
155
|
+
}
|
|
156
|
+
async function sendEventToServer(requestId, request, { signal, isSoftNavigation } = {}) {
|
|
98
157
|
try {
|
|
158
|
+
const headers = {
|
|
159
|
+
"Content-Type": "application/json",
|
|
160
|
+
[import_server_component_context.headerNames.pageRenderId]: requestId
|
|
161
|
+
};
|
|
162
|
+
if (isSoftNavigation) {
|
|
163
|
+
headers[import_server_component_context.headerNames.isSoftNavigation] = "1";
|
|
164
|
+
}
|
|
99
165
|
const response = await fetch("/api/event", {
|
|
100
166
|
method: "POST",
|
|
101
|
-
headers
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
},
|
|
105
|
-
body: JSON.stringify({ type, payload })
|
|
167
|
+
headers,
|
|
168
|
+
body: JSON.stringify(request),
|
|
169
|
+
signal
|
|
106
170
|
});
|
|
107
171
|
if (response.status === 404) {
|
|
108
172
|
console.error(
|
|
109
|
-
"[Nextlytics] In order for NextlyticsClient to work, you must
|
|
173
|
+
"[Nextlytics] In order for NextlyticsClient to work, you must install nextlytics middleware"
|
|
110
174
|
);
|
|
111
175
|
return { ok: false };
|
|
112
176
|
}
|
|
113
177
|
const data = await response.json().catch(() => ({ ok: response.ok }));
|
|
114
|
-
return { ok: data.ok ?? response.ok,
|
|
178
|
+
return { ok: data.ok ?? response.ok, items: data.items };
|
|
115
179
|
} catch (error) {
|
|
180
|
+
if (error instanceof Error && error.name === "AbortError") {
|
|
181
|
+
return { ok: false };
|
|
182
|
+
}
|
|
116
183
|
console.error("[Nextlytics] Failed to send event:", error);
|
|
117
184
|
return { ok: false };
|
|
118
185
|
}
|
|
119
186
|
}
|
|
120
|
-
const initializedRequestIds = /* @__PURE__ */ new Set();
|
|
121
187
|
function NextlyticsClient(props) {
|
|
122
|
-
const requestId =
|
|
123
|
-
const
|
|
124
|
-
const
|
|
125
|
-
(0, import_react.
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
188
|
+
const { requestId, scripts: initialScripts = [], templates = {} } = props.ctx;
|
|
189
|
+
const scriptsRef = (0, import_react.useRef)([]);
|
|
190
|
+
const subscribersRef = (0, import_react.useRef)(/* @__PURE__ */ new Set());
|
|
191
|
+
const addScripts = (0, import_react.useCallback)((newScripts) => {
|
|
192
|
+
(0, import_client_utils.debug)("Adding scripts", {
|
|
193
|
+
newCount: newScripts.length,
|
|
194
|
+
templateIds: newScripts.map((s) => s.templateId)
|
|
195
|
+
});
|
|
196
|
+
scriptsRef.current = [...scriptsRef.current, ...newScripts];
|
|
197
|
+
subscribersRef.current.forEach((cb) => cb());
|
|
198
|
+
}, []);
|
|
199
|
+
const contextValue = (0, import_react.useMemo)(
|
|
200
|
+
() => ({ requestId, templates, addScripts, scriptsRef, subscribersRef }),
|
|
201
|
+
[requestId, templates, addScripts]
|
|
202
|
+
);
|
|
203
|
+
(0, import_client_utils.useNavigation)(requestId, ({ softNavigation, signal }) => {
|
|
204
|
+
(0, import_client_utils.debug)("Sending page-view", { requestId, softNavigation });
|
|
131
205
|
const clientContext = createClientContext();
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
206
|
+
sendEventToServer(
|
|
207
|
+
requestId,
|
|
208
|
+
{ type: "page-view", clientContext, softNavigation: softNavigation || void 0 },
|
|
209
|
+
{ signal, isSoftNavigation: softNavigation }
|
|
210
|
+
).then(({ items }) => {
|
|
211
|
+
(0, import_client_utils.debug)("page-view response", { scriptsCount: items?.length ?? 0 });
|
|
212
|
+
if (items?.length) addScripts(items);
|
|
213
|
+
});
|
|
214
|
+
});
|
|
215
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(NextlyticsContext.Provider, { value: contextValue, children: [
|
|
216
|
+
props.children,
|
|
217
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(NextlyticsScripts, { initialScripts })
|
|
218
|
+
] });
|
|
141
219
|
}
|
|
142
220
|
function useNextlytics() {
|
|
143
221
|
const context = (0, import_react.useContext)(NextlyticsContext);
|
|
@@ -146,23 +224,24 @@ function useNextlytics() {
|
|
|
146
224
|
"[Nextlytics] useNextlytics() must be used within a component wrapped by <NextlyticsServer>. Add <NextlyticsServer> at the top of your layout.tsx file."
|
|
147
225
|
);
|
|
148
226
|
}
|
|
149
|
-
const { requestId,
|
|
150
|
-
const
|
|
227
|
+
const { requestId, addScripts } = context;
|
|
228
|
+
const sendEvent = (0, import_react.useCallback)(
|
|
151
229
|
async (eventName, opts) => {
|
|
152
|
-
const result = await
|
|
230
|
+
const result = await sendEventToServer(requestId, {
|
|
231
|
+
type: "custom-event",
|
|
153
232
|
name: eventName,
|
|
154
233
|
props: opts?.props,
|
|
155
234
|
collectedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
156
235
|
clientContext: createClientContext()
|
|
157
236
|
});
|
|
158
|
-
if (result.
|
|
159
|
-
|
|
237
|
+
if (result.items && result.items.length > 0) {
|
|
238
|
+
addScripts(result.items);
|
|
160
239
|
}
|
|
161
240
|
return { ok: result.ok };
|
|
162
241
|
},
|
|
163
|
-
[requestId,
|
|
242
|
+
[requestId, addScripts]
|
|
164
243
|
);
|
|
165
|
-
return { sendEvent
|
|
244
|
+
return { sendEvent };
|
|
166
245
|
}
|
|
167
246
|
// Annotate the CommonJS export names for ESM import in node:
|
|
168
247
|
0 && (module.exports = {
|
package/dist/config-helpers.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { NextlyticsConfig } from './types.js';
|
|
|
2
2
|
import 'next/dist/server/web/spec-extension/cookies';
|
|
3
3
|
import 'next/server';
|
|
4
4
|
|
|
5
|
-
type NextlyticsConfigWithDefaults = Required<Pick<NextlyticsConfig, "
|
|
5
|
+
type NextlyticsConfigWithDefaults = Required<Pick<NextlyticsConfig, "excludeApiCalls" | "eventEndpoint" | "isApiPath" | "backends">> & NextlyticsConfig & {
|
|
6
6
|
anonymousUsers: Required<NonNullable<NextlyticsConfig["anonymousUsers"]>>;
|
|
7
7
|
};
|
|
8
8
|
declare function withDefaults(config: NextlyticsConfig): NextlyticsConfigWithDefaults;
|
|
@@ -10,7 +10,7 @@ interface ConfigValidationResult {
|
|
|
10
10
|
valid: boolean;
|
|
11
11
|
warnings: string[];
|
|
12
12
|
}
|
|
13
|
-
declare function validateConfig(
|
|
13
|
+
declare function validateConfig(_config: NextlyticsConfig): ConfigValidationResult;
|
|
14
14
|
declare function logConfigWarnings(result: ConfigValidationResult): void;
|
|
15
15
|
|
|
16
16
|
export { type ConfigValidationResult, type NextlyticsConfigWithDefaults, logConfigWarnings, validateConfig, withDefaults };
|
package/dist/config-helpers.js
CHANGED
|
@@ -26,10 +26,9 @@ module.exports = __toCommonJS(config_helpers_exports);
|
|
|
26
26
|
function withDefaults(config) {
|
|
27
27
|
return {
|
|
28
28
|
...config,
|
|
29
|
-
pageViewMode: config.pageViewMode ?? "server",
|
|
30
29
|
excludeApiCalls: config.excludeApiCalls ?? false,
|
|
31
30
|
eventEndpoint: config.eventEndpoint ?? "/api/event",
|
|
32
|
-
isApiPath: config.isApiPath ?? (() =>
|
|
31
|
+
isApiPath: config.isApiPath ?? ((str) => str.startsWith("/api")),
|
|
33
32
|
backends: config.backends ?? [],
|
|
34
33
|
anonymousUsers: {
|
|
35
34
|
gdprMode: config.anonymousUsers?.gdprMode ?? true,
|
|
@@ -41,22 +40,8 @@ function withDefaults(config) {
|
|
|
41
40
|
}
|
|
42
41
|
};
|
|
43
42
|
}
|
|
44
|
-
function validateConfig(
|
|
45
|
-
|
|
46
|
-
if (config.pageViewMode === "client-init" && config.backends?.length) {
|
|
47
|
-
const staticBackends = config.backends.filter((b) => typeof b !== "function");
|
|
48
|
-
const backendsWithoutUpdates = staticBackends.filter((b) => !b.supportsUpdates);
|
|
49
|
-
if (backendsWithoutUpdates.length > 0) {
|
|
50
|
-
const backendNames = backendsWithoutUpdates.map((b) => `"${b.name}"`).join(", ");
|
|
51
|
-
warnings.push(
|
|
52
|
-
`[Nextlytics] pageViewMode="client-init" requires backends that support updates. These don't: ${backendNames}`
|
|
53
|
-
);
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
return {
|
|
57
|
-
valid: warnings.length === 0,
|
|
58
|
-
warnings
|
|
59
|
-
};
|
|
43
|
+
function validateConfig(_config) {
|
|
44
|
+
return { valid: true, warnings: [] };
|
|
60
45
|
}
|
|
61
46
|
function logConfigWarnings(result) {
|
|
62
47
|
for (const warning of result.warnings) {
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
export { Nextlytics
|
|
2
|
-
export { NextlyticsClient, NextlyticsContext, useNextlytics } from './client.js';
|
|
1
|
+
export { Nextlytics } from './server.js';
|
|
3
2
|
export { getNextlyticsProps } from './pages-router.js';
|
|
3
|
+
export { NextlyticsClient, NextlyticsContext, useNextlytics } from './client.js';
|
|
4
4
|
export { loggingBackend } from './backends/logging.js';
|
|
5
|
-
export { AnonymousUserResult, ClientContext, NextlyticsBackend, NextlyticsBackendFactory, NextlyticsConfig, NextlyticsEvent, NextlyticsPlugin, NextlyticsPluginFactory, NextlyticsResult, NextlyticsServerSide, RequestContext, ServerEventContext, UserContext } from './types.js';
|
|
5
|
+
export { AnonymousUserResult, BackendConfigEntry, BackendWithConfig, ClientAction, ClientContext, ClientRequest, JavascriptTemplate, NextlyticsBackend, NextlyticsBackendFactory, NextlyticsClientContext, NextlyticsConfig, NextlyticsEvent, NextlyticsPlugin, NextlyticsPluginFactory, NextlyticsResult, NextlyticsServerSide, PageViewDelivery, PagesRouterContext, RequestContext, ServerEventContext, UserContext } from './types.js';
|
|
6
6
|
import 'react/jsx-runtime';
|
|
7
7
|
import 'react';
|
|
8
8
|
import 'next/dist/server/web/spec-extension/cookies';
|
package/dist/index.js
CHANGED
|
@@ -20,21 +20,19 @@ var index_exports = {};
|
|
|
20
20
|
__export(index_exports, {
|
|
21
21
|
Nextlytics: () => import_server.Nextlytics,
|
|
22
22
|
NextlyticsClient: () => import_client.NextlyticsClient,
|
|
23
|
-
NextlyticsServer: () => import_server.NextlyticsServer,
|
|
24
23
|
getNextlyticsProps: () => import_pages_router.getNextlyticsProps,
|
|
25
24
|
loggingBackend: () => import_logging.loggingBackend,
|
|
26
25
|
useNextlytics: () => import_client.useNextlytics
|
|
27
26
|
});
|
|
28
27
|
module.exports = __toCommonJS(index_exports);
|
|
29
28
|
var import_server = require("./server");
|
|
30
|
-
var import_client = require("./client");
|
|
31
29
|
var import_pages_router = require("./pages-router");
|
|
30
|
+
var import_client = require("./client");
|
|
32
31
|
var import_logging = require("./backends/logging");
|
|
33
32
|
// Annotate the CommonJS export names for ESM import in node:
|
|
34
33
|
0 && (module.exports = {
|
|
35
34
|
Nextlytics,
|
|
36
35
|
NextlyticsClient,
|
|
37
|
-
NextlyticsServer,
|
|
38
36
|
getNextlyticsProps,
|
|
39
37
|
loggingBackend,
|
|
40
38
|
useNextlytics
|
package/dist/middleware.d.ts
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import { NextMiddleware } from 'next/server';
|
|
2
|
-
import { NextlyticsEvent, RequestContext, DispatchResult } from './types.js';
|
|
3
2
|
import { NextlyticsConfigWithDefaults } from './config-helpers.js';
|
|
3
|
+
import { DispatchEvent, UpdateEvent } from './api-handler.js';
|
|
4
|
+
import './types.js';
|
|
4
5
|
import 'next/dist/server/web/spec-extension/cookies';
|
|
5
6
|
|
|
6
|
-
type DispatchEvent = (event: NextlyticsEvent, ctx: RequestContext) => DispatchResult;
|
|
7
|
-
type UpdateEvent = (eventId: string, patch: Partial<NextlyticsEvent>, ctx: RequestContext) => Promise<void>;
|
|
8
7
|
declare function createNextlyticsMiddleware(config: NextlyticsConfigWithDefaults, dispatchEvent: DispatchEvent, updateEvent: UpdateEvent): NextMiddleware;
|
|
9
8
|
|
|
10
9
|
export { createNextlyticsMiddleware };
|