@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,76 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var stable_hash_exports = {};
|
|
20
|
+
__export(stable_hash_exports, {
|
|
21
|
+
stableHash: () => stableHash
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(stable_hash_exports);
|
|
24
|
+
const FNV_OFFSET_BASIS = 2166136261;
|
|
25
|
+
const FNV_PRIME = 16777619;
|
|
26
|
+
function stableStringify(value, seen) {
|
|
27
|
+
if (value === null) return "null";
|
|
28
|
+
const valueType = typeof value;
|
|
29
|
+
if (valueType === "string") return JSON.stringify(value);
|
|
30
|
+
if (valueType === "number") return Number.isFinite(value) ? String(value) : "null";
|
|
31
|
+
if (valueType === "boolean") return value ? "true" : "false";
|
|
32
|
+
if (valueType === "bigint") {
|
|
33
|
+
throw new TypeError("Do not know how to serialize a BigInt");
|
|
34
|
+
}
|
|
35
|
+
if (valueType === "undefined" || valueType === "function" || valueType === "symbol") {
|
|
36
|
+
return void 0;
|
|
37
|
+
}
|
|
38
|
+
if (typeof value.toJSON === "function") {
|
|
39
|
+
return stableStringify(value.toJSON(), seen);
|
|
40
|
+
}
|
|
41
|
+
if (Array.isArray(value)) {
|
|
42
|
+
const items = value.map((item) => stableStringify(item, seen) ?? "null");
|
|
43
|
+
return `[${items.join(",")}]`;
|
|
44
|
+
}
|
|
45
|
+
const obj = value;
|
|
46
|
+
if (seen.has(obj)) {
|
|
47
|
+
throw new TypeError("Converting circular structure to JSON");
|
|
48
|
+
}
|
|
49
|
+
seen.add(obj);
|
|
50
|
+
const keys = Object.keys(obj).sort();
|
|
51
|
+
const parts = [];
|
|
52
|
+
for (const key of keys) {
|
|
53
|
+
const next = stableStringify(obj[key], seen);
|
|
54
|
+
if (next !== void 0) {
|
|
55
|
+
parts.push(`${JSON.stringify(key)}:${next}`);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
seen.delete(obj);
|
|
59
|
+
return `{${parts.join(",")}}`;
|
|
60
|
+
}
|
|
61
|
+
function fnv1aHash(input) {
|
|
62
|
+
let hash = FNV_OFFSET_BASIS;
|
|
63
|
+
for (let i = 0; i < input.length; i += 1) {
|
|
64
|
+
hash ^= input.charCodeAt(i);
|
|
65
|
+
hash = Math.imul(hash, FNV_PRIME) >>> 0;
|
|
66
|
+
}
|
|
67
|
+
return hash.toString(16).padStart(8, "0");
|
|
68
|
+
}
|
|
69
|
+
function stableHash(value) {
|
|
70
|
+
const stable = stableStringify(value, /* @__PURE__ */ new WeakSet()) ?? "null";
|
|
71
|
+
return fnv1aHash(stable);
|
|
72
|
+
}
|
|
73
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
74
|
+
0 && (module.exports = {
|
|
75
|
+
stableHash
|
|
76
|
+
});
|
package/dist/types.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { RequestCookies } from 'next/dist/server/web/spec-extension/cookies';
|
|
2
|
-
import {
|
|
2
|
+
import { NextMiddleware } from 'next/server';
|
|
3
3
|
|
|
4
4
|
/** Server-side request context collected in middleware */
|
|
5
5
|
interface ServerEventContext {
|
|
@@ -28,6 +28,16 @@ interface ClientContext {
|
|
|
28
28
|
referer?: string;
|
|
29
29
|
/** window.location.pathname - may differ from server path in SPAs */
|
|
30
30
|
path?: string;
|
|
31
|
+
/** window.location.href */
|
|
32
|
+
url?: string;
|
|
33
|
+
/** window.location.host */
|
|
34
|
+
host?: string;
|
|
35
|
+
/** window.location.search (as string, e.g. "?foo=bar") */
|
|
36
|
+
search?: string;
|
|
37
|
+
/** window.location.hash */
|
|
38
|
+
hash?: string;
|
|
39
|
+
/** document.title */
|
|
40
|
+
title?: string;
|
|
31
41
|
/** Screen and viewport dimensions */
|
|
32
42
|
screen: {
|
|
33
43
|
/** screen.width */
|
|
@@ -59,6 +69,12 @@ interface UserContext {
|
|
|
59
69
|
}
|
|
60
70
|
/** Analytics event sent to backends */
|
|
61
71
|
interface NextlyticsEvent {
|
|
72
|
+
/**
|
|
73
|
+
* Where the event was triggered?
|
|
74
|
+
* - server — on server, e.g in route or server side component
|
|
75
|
+
* - client — on client
|
|
76
|
+
*/
|
|
77
|
+
origin: "server" | "client";
|
|
62
78
|
/** ISO timestamp when event was collected */
|
|
63
79
|
collectedAt: string;
|
|
64
80
|
/** Unique event ID */
|
|
@@ -99,6 +115,20 @@ type NextlyticsPlugin = {
|
|
|
99
115
|
};
|
|
100
116
|
/** Factory to create plugin per-request (for request-scoped plugins) */
|
|
101
117
|
type NextlyticsPluginFactory = (ctx: RequestContext) => NextlyticsPlugin;
|
|
118
|
+
/** When to deliver page view events for a backend */
|
|
119
|
+
type PageViewDelivery =
|
|
120
|
+
/** Dispatch on server request in middleware (default) - faster but no client context */
|
|
121
|
+
"on-request"
|
|
122
|
+
/** Dispatch on page load (client-side) - has full client context (title, screen, etc) */
|
|
123
|
+
| "on-page-load";
|
|
124
|
+
/** Backend with configuration options */
|
|
125
|
+
type BackendWithConfig = {
|
|
126
|
+
backend: NextlyticsBackend | NextlyticsBackendFactory;
|
|
127
|
+
/** When to send events. Default: "on-request" */
|
|
128
|
+
pageViewDelivery?: PageViewDelivery;
|
|
129
|
+
};
|
|
130
|
+
/** Backend config entry - either a backend directly or with config */
|
|
131
|
+
type BackendConfigEntry = NextlyticsBackend | NextlyticsBackendFactory | BackendWithConfig;
|
|
102
132
|
type NextlyticsConfig = {
|
|
103
133
|
/** Enable debug logging (shows backend stats for each event) */
|
|
104
134
|
debug?: boolean;
|
|
@@ -114,12 +144,6 @@ type NextlyticsConfig = {
|
|
|
114
144
|
/** Cookie max age in seconds (default: 2 years) */
|
|
115
145
|
cookieMaxAge?: number;
|
|
116
146
|
};
|
|
117
|
-
/**
|
|
118
|
-
* When to record pageView:
|
|
119
|
-
* - "server": in middleware (default, more reliable)
|
|
120
|
-
* - "client-init": when JS loads (has client context) - NOT SUPPORTED CURRENTLU
|
|
121
|
-
*/
|
|
122
|
-
pageViewMode?: "server" | "client-init";
|
|
123
147
|
/** Skip tracking for API routes */
|
|
124
148
|
excludeApiCalls?: boolean;
|
|
125
149
|
/** Skip tracking for specific paths */
|
|
@@ -138,7 +162,7 @@ type NextlyticsConfig = {
|
|
|
138
162
|
}) => Promise<AnonymousUserResult>;
|
|
139
163
|
};
|
|
140
164
|
/** Analytics backends to send events to */
|
|
141
|
-
backends?:
|
|
165
|
+
backends?: BackendConfigEntry[];
|
|
142
166
|
plugins?: (NextlyticsPlugin | NextlyticsPluginFactory)[];
|
|
143
167
|
};
|
|
144
168
|
type ClientAction = {
|
|
@@ -163,13 +187,16 @@ type DispatchResult = {
|
|
|
163
187
|
};
|
|
164
188
|
type JavascriptTemplate = {
|
|
165
189
|
items: ScriptElement[];
|
|
190
|
+
/**
|
|
191
|
+
* Optional dependency key template. When this value changes, the script re-injects.
|
|
192
|
+
* If omitted, the template is treated as "once".
|
|
193
|
+
*/
|
|
194
|
+
deps?: string | string[];
|
|
166
195
|
};
|
|
167
196
|
type ScriptElement = {
|
|
168
|
-
async?:
|
|
169
|
-
body?: string;
|
|
197
|
+
async?: boolean;
|
|
198
|
+
body?: string | string[];
|
|
170
199
|
src?: string;
|
|
171
|
-
/** If true, skip insertion if script with same src already exists */
|
|
172
|
-
singleton?: boolean;
|
|
173
200
|
};
|
|
174
201
|
/** Backend that receives analytics events */
|
|
175
202
|
type NextlyticsBackend = {
|
|
@@ -183,7 +210,7 @@ type NextlyticsBackend = {
|
|
|
183
210
|
returnsClientActions?: boolean;
|
|
184
211
|
getClientSideTemplates?: () => Record<string, JavascriptTemplate>;
|
|
185
212
|
/** Handle new event */
|
|
186
|
-
onEvent(event: NextlyticsEvent): Promise<void |
|
|
213
|
+
onEvent(event: NextlyticsEvent): Promise<ClientAction | void | undefined>;
|
|
187
214
|
/** Update existing event (e.g. add client context to server pageView) */
|
|
188
215
|
updateEvent(eventId: string, patch: Partial<NextlyticsEvent>): Promise<void> | void;
|
|
189
216
|
};
|
|
@@ -198,11 +225,41 @@ type NextlyticsServerSide = {
|
|
|
198
225
|
ok: boolean;
|
|
199
226
|
}>;
|
|
200
227
|
};
|
|
201
|
-
|
|
228
|
+
/** Context for Pages Router _app.tsx */
|
|
229
|
+
type PagesRouterContext = {
|
|
230
|
+
req: {
|
|
231
|
+
headers: Record<string, string | string[] | undefined>;
|
|
232
|
+
cookies?: Record<string, string>;
|
|
233
|
+
};
|
|
234
|
+
};
|
|
235
|
+
/** Context passed to NextlyticsClient */
|
|
236
|
+
type NextlyticsClientContext = {
|
|
237
|
+
requestId: string;
|
|
238
|
+
scripts?: TemplatizedScriptInsertion<unknown>[];
|
|
239
|
+
templates?: Record<string, JavascriptTemplate>;
|
|
240
|
+
};
|
|
241
|
+
/** Client-to-server request types (discriminated union) */
|
|
242
|
+
type ClientRequest = {
|
|
243
|
+
type: "page-view";
|
|
244
|
+
clientContext: ClientContext;
|
|
245
|
+
/** If true, only update existing event (soft navigation - no dispatch, no scripts) */
|
|
246
|
+
softNavigation?: boolean;
|
|
247
|
+
} | {
|
|
248
|
+
type: "custom-event";
|
|
249
|
+
name: string;
|
|
250
|
+
props?: Record<string, unknown>;
|
|
251
|
+
collectedAt: string;
|
|
252
|
+
clientContext: ClientContext;
|
|
253
|
+
};
|
|
254
|
+
/**
|
|
255
|
+
* Result of any /api/event call
|
|
256
|
+
*/
|
|
257
|
+
type ClientRequestResult = {
|
|
258
|
+
ok: boolean;
|
|
259
|
+
items?: ClientActionItem[];
|
|
260
|
+
};
|
|
202
261
|
/** Return value from Nextlytics() */
|
|
203
262
|
type NextlyticsResult = {
|
|
204
|
-
/** Route handlers for /api/event */
|
|
205
|
-
handlers: AppRouteHandlers;
|
|
206
263
|
/** Get server-side analytics API */
|
|
207
264
|
analytics: () => Promise<NextlyticsServerSide>;
|
|
208
265
|
/** Middleware to intercept requests */
|
|
@@ -211,6 +268,10 @@ type NextlyticsResult = {
|
|
|
211
268
|
dispatchEvent: (event: NextlyticsEvent) => Promise<DispatchResult>;
|
|
212
269
|
/** Manually update existing event */
|
|
213
270
|
updateEvent: (eventId: string, patch: Partial<NextlyticsEvent>) => Promise<void>;
|
|
271
|
+
/** Server component that wraps your app to provide analytics context (App Router) */
|
|
272
|
+
NextlyticsServer: (props: {
|
|
273
|
+
children: React.ReactNode;
|
|
274
|
+
}) => Promise<React.ReactElement>;
|
|
214
275
|
};
|
|
215
276
|
|
|
216
|
-
export type { AnonymousUserResult, ClientAction, ClientActionItem, ClientContext, DispatchResult, JavascriptTemplate, NextlyticsBackend, NextlyticsBackendFactory, NextlyticsConfig, NextlyticsEvent, NextlyticsPlugin, NextlyticsPluginFactory, NextlyticsResult, NextlyticsServerSide, RequestContext, ScriptElement, ServerEventContext, TemplatizedScriptInsertion, UserContext };
|
|
277
|
+
export type { AnonymousUserResult, BackendConfigEntry, BackendWithConfig, ClientAction, ClientActionItem, ClientContext, ClientRequest, ClientRequestResult, DispatchResult, JavascriptTemplate, NextlyticsBackend, NextlyticsBackendFactory, NextlyticsClientContext, NextlyticsConfig, NextlyticsEvent, NextlyticsPlugin, NextlyticsPluginFactory, NextlyticsResult, NextlyticsServerSide, PageViewDelivery, PagesRouterContext, RequestContext, ScriptElement, ServerEventContext, TemplatizedScriptInsertion, UserContext };
|
package/dist/uitils.d.ts
CHANGED
|
@@ -2,6 +2,12 @@ import { NextRequest } from 'next/server';
|
|
|
2
2
|
import { ServerEventContext } from './types.js';
|
|
3
3
|
import 'next/dist/server/web/spec-extension/cookies';
|
|
4
4
|
|
|
5
|
+
/** Returns the full installed Next.js version string (e.g. "16.1.6"), or undefined. */
|
|
6
|
+
declare function getNextVersion(): string | undefined;
|
|
7
|
+
/** True if the installed Next.js major version is 15. */
|
|
8
|
+
declare function isNext15(): boolean;
|
|
9
|
+
/** True if the installed Next.js major version is 16. */
|
|
10
|
+
declare function isNext16(): boolean;
|
|
5
11
|
/** Generate a random base62 ID (16 chars = 62^16 ≈ 4.7 × 10^28 combinations) */
|
|
6
12
|
declare function generateId(): string;
|
|
7
13
|
type RequestInfo = {
|
|
@@ -19,4 +25,4 @@ type RequestInfo = {
|
|
|
19
25
|
declare function getRequestInfo(request: NextRequest): RequestInfo;
|
|
20
26
|
declare function createServerContext(request: NextRequest): ServerEventContext;
|
|
21
27
|
|
|
22
|
-
export { type RequestInfo, createServerContext, generateId, getRequestInfo };
|
|
28
|
+
export { type RequestInfo, createServerContext, generateId, getNextVersion, getRequestInfo, isNext15, isNext16 };
|
package/dist/uitils.js
CHANGED
|
@@ -20,10 +20,41 @@ var uitils_exports = {};
|
|
|
20
20
|
__export(uitils_exports, {
|
|
21
21
|
createServerContext: () => createServerContext,
|
|
22
22
|
generateId: () => generateId,
|
|
23
|
-
|
|
23
|
+
getNextVersion: () => getNextVersion,
|
|
24
|
+
getRequestInfo: () => getRequestInfo,
|
|
25
|
+
isNext15: () => isNext15,
|
|
26
|
+
isNext16: () => isNext16
|
|
24
27
|
});
|
|
25
28
|
module.exports = __toCommonJS(uitils_exports);
|
|
26
29
|
var import_headers = require("./headers");
|
|
30
|
+
let _nextVersion;
|
|
31
|
+
function detectNextVersion() {
|
|
32
|
+
if (_nextVersion !== void 0) return _nextVersion;
|
|
33
|
+
try {
|
|
34
|
+
const pkg = require("next/package.json");
|
|
35
|
+
_nextVersion = pkg.version;
|
|
36
|
+
} catch {
|
|
37
|
+
console.warn(
|
|
38
|
+
"[Nextlytics] Could not read Next.js version from next/package.json.\nThis can happen if your bundler does not support JSON imports from\nnode_modules. Ensure `resolveJsonModule: true` is set in tsconfig\nand your bundler can resolve peer-dependency subpath imports.\nTurbopack and webpack (default Next.js bundlers) both support this."
|
|
39
|
+
);
|
|
40
|
+
_nextVersion = "";
|
|
41
|
+
}
|
|
42
|
+
return _nextVersion || void 0;
|
|
43
|
+
}
|
|
44
|
+
function parseMajor(version) {
|
|
45
|
+
if (!version) return void 0;
|
|
46
|
+
const major = parseInt(version.split(".")[0], 10);
|
|
47
|
+
return Number.isFinite(major) ? major : void 0;
|
|
48
|
+
}
|
|
49
|
+
function getNextVersion() {
|
|
50
|
+
return detectNextVersion();
|
|
51
|
+
}
|
|
52
|
+
function isNext15() {
|
|
53
|
+
return parseMajor(detectNextVersion()) === 15;
|
|
54
|
+
}
|
|
55
|
+
function isNext16() {
|
|
56
|
+
return parseMajor(detectNextVersion()) === 16;
|
|
57
|
+
}
|
|
27
58
|
const BASE62_CHARS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
|
28
59
|
function generateId() {
|
|
29
60
|
const length = 16;
|
|
@@ -45,15 +76,15 @@ function getRequestInfo(request) {
|
|
|
45
76
|
);
|
|
46
77
|
const hasStandardPrefetchHeader = headers.get("next-router-prefetch") === "1" || headers.get("purpose") === "prefetch" || headers.get("sec-purpose") === "prefetch";
|
|
47
78
|
const nextUrl = headers.get("next-url");
|
|
48
|
-
const isRscPrefetch = nextUrl !== null && nextUrl !== pathname;
|
|
49
|
-
const isPrefetch = hasStandardPrefetchHeader || isRscPrefetch;
|
|
50
79
|
const isRsc = !!(nextUrl || headers.get("rsc"));
|
|
51
80
|
const secFetchDest = headers.get("sec-fetch-dest");
|
|
52
81
|
const secFetchMode = headers.get("sec-fetch-mode");
|
|
53
82
|
const accept = headers.get("accept") || "";
|
|
54
83
|
const isDocumentRequest = secFetchDest === "document" || secFetchMode === "navigate";
|
|
55
84
|
const acceptsHtml = accept.includes("text/html");
|
|
56
|
-
const isPageNavigation =
|
|
85
|
+
const isPageNavigation = isDocumentRequest || acceptsHtml;
|
|
86
|
+
const isRscPrefetch = nextUrl !== null && nextUrl !== pathname;
|
|
87
|
+
const isPrefetch = hasStandardPrefetchHeader || isRscPrefetch && !isPageNavigation;
|
|
57
88
|
return {
|
|
58
89
|
isPrefetch,
|
|
59
90
|
isRsc,
|
|
@@ -90,5 +121,8 @@ function createServerContext(request) {
|
|
|
90
121
|
0 && (module.exports = {
|
|
91
122
|
createServerContext,
|
|
92
123
|
generateId,
|
|
93
|
-
|
|
124
|
+
getNextVersion,
|
|
125
|
+
getRequestInfo,
|
|
126
|
+
isNext15,
|
|
127
|
+
isNext16
|
|
94
128
|
});
|
package/package.json
CHANGED
package/dist/handlers.d.ts
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { NextRequest } from 'next/server';
|
|
2
|
-
import { NextlyticsEvent, RequestContext, DispatchResult } from './types.js';
|
|
3
|
-
import { NextlyticsConfigWithDefaults } from './config-helpers.js';
|
|
4
|
-
import 'next/dist/server/web/spec-extension/cookies';
|
|
5
|
-
|
|
6
|
-
type AppRouteHandlers = Record<"GET" | "POST", (req: NextRequest) => Promise<Response>>;
|
|
7
|
-
declare function createHandlers(config: NextlyticsConfigWithDefaults, dispatchEvent: (event: NextlyticsEvent, ctx: RequestContext) => DispatchResult, updateEvent: (eventId: string, patch: Partial<NextlyticsEvent>, ctx: RequestContext) => Promise<void>): AppRouteHandlers;
|
|
8
|
-
|
|
9
|
-
export { createHandlers };
|
package/dist/handlers.js
DELETED
|
@@ -1,123 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __defProp = Object.defineProperty;
|
|
3
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
-
var __export = (target, all) => {
|
|
7
|
-
for (var name in all)
|
|
8
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
-
};
|
|
10
|
-
var __copyProps = (to, from, except, desc) => {
|
|
11
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
-
for (let key of __getOwnPropNames(from))
|
|
13
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
-
}
|
|
16
|
-
return to;
|
|
17
|
-
};
|
|
18
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
-
var handlers_exports = {};
|
|
20
|
-
__export(handlers_exports, {
|
|
21
|
-
createHandlers: () => createHandlers
|
|
22
|
-
});
|
|
23
|
-
module.exports = __toCommonJS(handlers_exports);
|
|
24
|
-
var import_server_component_context = require("./server-component-context");
|
|
25
|
-
var import_uitils = require("./uitils");
|
|
26
|
-
var import_anonymous_user = require("./anonymous-user");
|
|
27
|
-
function createRequestContext(request) {
|
|
28
|
-
return {
|
|
29
|
-
headers: request.headers,
|
|
30
|
-
cookies: request.cookies
|
|
31
|
-
};
|
|
32
|
-
}
|
|
33
|
-
async function getUserContext(config, ctx) {
|
|
34
|
-
if (!config.callbacks.getUser) return void 0;
|
|
35
|
-
return await config.callbacks.getUser(ctx) || void 0;
|
|
36
|
-
}
|
|
37
|
-
function createHandlers(config, dispatchEvent, updateEvent) {
|
|
38
|
-
return {
|
|
39
|
-
GET: async () => {
|
|
40
|
-
return Response.json({ status: "ok" });
|
|
41
|
-
},
|
|
42
|
-
POST: async (req) => {
|
|
43
|
-
const pageRenderId = req.headers.get(import_server_component_context.headers.pageRenderId);
|
|
44
|
-
if (!pageRenderId) {
|
|
45
|
-
return Response.json({ error: "Missing page render ID" }, { status: 400 });
|
|
46
|
-
}
|
|
47
|
-
let body;
|
|
48
|
-
try {
|
|
49
|
-
body = await req.json();
|
|
50
|
-
} catch {
|
|
51
|
-
return Response.json({ error: "Invalid JSON" }, { status: 400 });
|
|
52
|
-
}
|
|
53
|
-
const { type, payload } = body;
|
|
54
|
-
const ctx = createRequestContext(req);
|
|
55
|
-
if (type === "client-init") {
|
|
56
|
-
const clientContext = payload;
|
|
57
|
-
const serverContext = (0, import_uitils.createServerContext)(req);
|
|
58
|
-
if (clientContext?.path) {
|
|
59
|
-
serverContext.path = clientContext.path;
|
|
60
|
-
}
|
|
61
|
-
const userContext = await getUserContext(config, ctx);
|
|
62
|
-
const { anonId: anonymousUserId } = await (0, import_anonymous_user.resolveAnonymousUser)({
|
|
63
|
-
ctx,
|
|
64
|
-
serverContext,
|
|
65
|
-
config
|
|
66
|
-
});
|
|
67
|
-
if (config.pageViewMode === "client-init") {
|
|
68
|
-
const event = {
|
|
69
|
-
eventId: pageRenderId,
|
|
70
|
-
type: "pageView",
|
|
71
|
-
collectedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
72
|
-
anonymousUserId,
|
|
73
|
-
serverContext,
|
|
74
|
-
clientContext,
|
|
75
|
-
userContext,
|
|
76
|
-
properties: {}
|
|
77
|
-
};
|
|
78
|
-
const { clientActions, completion } = dispatchEvent(event, ctx);
|
|
79
|
-
const actions = await clientActions;
|
|
80
|
-
completion.catch((err) => console.warn("[Nextlytics] Dispatch completion error:", err));
|
|
81
|
-
const scripts = actions.items.filter((i) => i.type === "script-template");
|
|
82
|
-
return Response.json({ ok: true, scripts: scripts.length > 0 ? scripts : void 0 });
|
|
83
|
-
} else {
|
|
84
|
-
await updateEvent(pageRenderId, { clientContext, userContext, anonymousUserId }, ctx);
|
|
85
|
-
return Response.json({ ok: true });
|
|
86
|
-
}
|
|
87
|
-
} else if (type === "client-event") {
|
|
88
|
-
const clientContext = payload.clientContext || void 0;
|
|
89
|
-
const serverContext = (0, import_uitils.createServerContext)(req);
|
|
90
|
-
if (clientContext?.path) {
|
|
91
|
-
serverContext.path = clientContext.path;
|
|
92
|
-
}
|
|
93
|
-
const userContext = await getUserContext(config, ctx);
|
|
94
|
-
const { anonId: anonymousUserId } = await (0, import_anonymous_user.resolveAnonymousUser)({
|
|
95
|
-
ctx,
|
|
96
|
-
serverContext,
|
|
97
|
-
config
|
|
98
|
-
});
|
|
99
|
-
const event = {
|
|
100
|
-
eventId: (0, import_uitils.generateId)(),
|
|
101
|
-
parentEventId: pageRenderId,
|
|
102
|
-
type: payload.name || type,
|
|
103
|
-
collectedAt: payload.collectedAt || (/* @__PURE__ */ new Date()).toISOString(),
|
|
104
|
-
anonymousUserId,
|
|
105
|
-
serverContext,
|
|
106
|
-
clientContext,
|
|
107
|
-
userContext,
|
|
108
|
-
properties: payload.props || {}
|
|
109
|
-
};
|
|
110
|
-
const { clientActions, completion } = dispatchEvent(event, ctx);
|
|
111
|
-
const actions = await clientActions;
|
|
112
|
-
completion.catch((err) => console.warn("[Nextlytics] Dispatch completion error:", err));
|
|
113
|
-
const scripts = actions.items.filter((i) => i.type === "script-template");
|
|
114
|
-
return Response.json({ ok: true, scripts: scripts.length > 0 ? scripts : void 0 });
|
|
115
|
-
}
|
|
116
|
-
return Response.json({ ok: true });
|
|
117
|
-
}
|
|
118
|
-
};
|
|
119
|
-
}
|
|
120
|
-
// Annotate the CommonJS export names for ESM import in node:
|
|
121
|
-
0 && (module.exports = {
|
|
122
|
-
createHandlers
|
|
123
|
-
});
|