@yaoxiu/marketing-dsl 1.5.2 → 2.1.0
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/README.md +120 -17
- package/dist/{chunk-FKZKLCVV.js → chunk-7TWWOK7Q.js} +147 -7
- package/dist/docs/index.cjs +227 -45
- package/dist/docs/index.d.cts +1 -1
- package/dist/docs/index.d.ts +1 -1
- package/dist/docs/index.js +200 -46
- package/dist/index.cjs +194 -20
- package/dist/index.d.cts +75 -4
- package/dist/index.d.ts +75 -4
- package/dist/index.js +46 -16
- package/dist/report/index.cjs +47 -30
- package/dist/report/index.d.cts +80 -31
- package/dist/report/index.d.ts +80 -31
- package/dist/report/index.js +46 -31
- package/dist/{types-BgUaJUAu.d.cts → types-Bj0xyWnx.d.cts} +54 -2
- package/dist/{types-BgUaJUAu.d.ts → types-Bj0xyWnx.d.ts} +54 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { normalizeViews, createTicker,
|
|
2
|
-
export { ACTION_TYPES, ALLOWED_STYLE_KEYS, CLOSE_POSITIONS, DSL_VERSION, NODE_TYPES, SINGLE_VIEW_NAME, TRACK_EVENT_PATTERN, check, computeParts, evaluate, formatIssues, formatParts, interpolate, interpolateDeep, isLength, isValidEndTime, normalizeViews, parseEndTime, toCssStyle, toLength, validate } from './chunk-
|
|
1
|
+
import { normalizeViews, createTicker, evaluate, resolveNodeStyle, interpolateDeep, interpolate, toLength, toCssStyle, parseEndTime, computeParts, formatParts } from './chunk-7TWWOK7Q.js';
|
|
2
|
+
export { ACTION_TYPES, ALLOWED_STYLE_KEYS, BANNER_MIN_ASPECT_RATIO, CLOSE_POSITIONS, DEFAULT_USER_FIELDS, DSL_VERSION, NODE_TYPES, SINGLE_VIEW_NAME, TRACK_EVENT_PATTERN, USER_FIELD_LABELS, check, computeParts, evaluate, formatIssues, formatParts, interpolate, interpolateDeep, isLength, isValidEndTime, normalizeViews, parseEndTime, toCssStyle, toLength, validate, validateUserFields } from './chunk-7TWWOK7Q.js';
|
|
3
3
|
|
|
4
4
|
// src/url.ts
|
|
5
5
|
var SAFE_PROTOCOLS = ["http:", "https:", "mailto:", "tel:"];
|
|
@@ -22,13 +22,13 @@ function safeImageUrl(input) {
|
|
|
22
22
|
// src/actions.ts
|
|
23
23
|
function createDispatcher(options) {
|
|
24
24
|
const { setState, emit, openView, closeTop, closeAll } = options;
|
|
25
|
-
function
|
|
25
|
+
function run(action, context, interaction) {
|
|
26
26
|
if (!action || !action.type) return;
|
|
27
27
|
const handlers = options.handlers || {};
|
|
28
28
|
const editMode = !!options.editMode;
|
|
29
29
|
switch (action.type) {
|
|
30
30
|
case "sequence":
|
|
31
|
-
(action.actions || []).forEach((item) =>
|
|
31
|
+
(action.actions || []).forEach((item) => run(item, context, interaction));
|
|
32
32
|
return;
|
|
33
33
|
case "navigate": {
|
|
34
34
|
const url = safeUrl(interpolate(action.url, context));
|
|
@@ -38,6 +38,7 @@ function createDispatcher(options) {
|
|
|
38
38
|
}
|
|
39
39
|
const target = action.target || "_blank";
|
|
40
40
|
emit("navigate", { url, target });
|
|
41
|
+
if (!interaction.navigate) interaction.navigate = { url, target };
|
|
41
42
|
if (editMode) return;
|
|
42
43
|
if (typeof window === "undefined") return;
|
|
43
44
|
if (target === "_self") window.location.href = url;
|
|
@@ -51,20 +52,25 @@ function createDispatcher(options) {
|
|
|
51
52
|
return;
|
|
52
53
|
// 关掉栈顶那层;只剩一层时就是整体关闭
|
|
53
54
|
case "close":
|
|
55
|
+
interaction.closes = true;
|
|
54
56
|
closeTop(action.reason);
|
|
55
57
|
return;
|
|
56
58
|
case "closeAll":
|
|
59
|
+
interaction.closes = true;
|
|
57
60
|
closeAll(action.reason);
|
|
58
61
|
return;
|
|
59
62
|
case "setState":
|
|
60
63
|
setState(action.key, interpolate(action.value, context));
|
|
61
64
|
return;
|
|
62
|
-
case "track":
|
|
63
|
-
|
|
65
|
+
case "track": {
|
|
66
|
+
const payload = {
|
|
64
67
|
event: String(interpolate(action.event, context)),
|
|
65
68
|
params: interpolateDeep(action.params || {}, context)
|
|
66
|
-
}
|
|
69
|
+
};
|
|
70
|
+
emit("track", payload);
|
|
71
|
+
if (!interaction.track) interaction.track = payload;
|
|
67
72
|
return;
|
|
73
|
+
}
|
|
68
74
|
case "call": {
|
|
69
75
|
const handler = handlers[action.name];
|
|
70
76
|
if (typeof handler !== "function") {
|
|
@@ -84,6 +90,13 @@ function createDispatcher(options) {
|
|
|
84
90
|
});
|
|
85
91
|
}
|
|
86
92
|
}
|
|
93
|
+
function dispatch(action, context, meta) {
|
|
94
|
+
if (!action || !action.type) return;
|
|
95
|
+
const interaction = { trigger: (meta == null ? void 0 : meta.trigger) || "action" };
|
|
96
|
+
if ((meta == null ? void 0 : meta.reason) !== void 0) interaction.reason = meta.reason;
|
|
97
|
+
run(action, context, interaction);
|
|
98
|
+
emit("interaction", interaction);
|
|
99
|
+
}
|
|
87
100
|
return dispatch;
|
|
88
101
|
}
|
|
89
102
|
|
|
@@ -91,9 +104,7 @@ function createDispatcher(options) {
|
|
|
91
104
|
function resolveTree(input) {
|
|
92
105
|
const { normalized, viewStack, ready } = input;
|
|
93
106
|
const layers = viewStack.map((name) => ({ name, view: normalized.views[name] })).filter((item) => !!item.view);
|
|
94
|
-
const hasPopup =
|
|
95
|
-
(name) => normalized.views[name].type === "popup"
|
|
96
|
-
);
|
|
107
|
+
const hasPopup = layers.some((item) => item.view.type === "popup");
|
|
97
108
|
const countdowns = { endTimes: [], precision: "s" };
|
|
98
109
|
const renderLayers = ready ? layers.map(
|
|
99
110
|
(item, index) => resolveLayer(
|
|
@@ -107,8 +118,10 @@ function resolveTree(input) {
|
|
|
107
118
|
return {
|
|
108
119
|
ready: ready && layers.length > 0,
|
|
109
120
|
hasPopup,
|
|
110
|
-
//
|
|
111
|
-
|
|
121
|
+
// 根容器恒为 relative:它要待在宿主给的位置上(banner / 公告坑位是流式的普通 div,
|
|
122
|
+
// 根容器一脱流坑位就塌成 0、内容按最近定位祖先飘走)。弹窗铺满视口由弹窗层自己
|
|
123
|
+
// `position: fixed` 完成,不再靠根容器撑开,见 layerStyle。
|
|
124
|
+
rootStyle: { position: "relative" },
|
|
112
125
|
layers: renderLayers,
|
|
113
126
|
countdownEndTimes: countdowns.endTimes,
|
|
114
127
|
countdownPrecision: countdowns.precision
|
|
@@ -154,7 +167,15 @@ function resolveLayer(name, view, isTop, input, countdowns) {
|
|
|
154
167
|
};
|
|
155
168
|
}
|
|
156
169
|
function layerStyle(isPopup, isTop) {
|
|
157
|
-
const style = isPopup ? {
|
|
170
|
+
const style = isPopup ? {
|
|
171
|
+
position: "fixed",
|
|
172
|
+
top: "0",
|
|
173
|
+
right: "0",
|
|
174
|
+
bottom: "0",
|
|
175
|
+
left: "0",
|
|
176
|
+
// 弹窗层可能挂在页面中段的坑位里,不提层会被后面的内容盖住
|
|
177
|
+
zIndex: "1000"
|
|
178
|
+
} : {};
|
|
158
179
|
if (!isTop) style.pointerEvents = "none";
|
|
159
180
|
return style;
|
|
160
181
|
}
|
|
@@ -182,7 +203,7 @@ function resolveStageStyle(stage, isPopup, context) {
|
|
|
182
203
|
base.margin = "auto";
|
|
183
204
|
base.flex = "none";
|
|
184
205
|
}
|
|
185
|
-
|
|
206
|
+
const style = Object.assign(
|
|
186
207
|
base,
|
|
187
208
|
{
|
|
188
209
|
// width / height 支持数字(px)、'100%' / 'auto' / calc(...) 等相对单位,也支持 {{ }}
|
|
@@ -196,6 +217,11 @@ function resolveStageStyle(stage, isPopup, context) {
|
|
|
196
217
|
// stage.style 也走一遍插值,这样切 tab 时弹窗本身的背景能跟着变
|
|
197
218
|
toCssStyle(interpolateDeep(stage.style, context))
|
|
198
219
|
);
|
|
220
|
+
if (!isPopup && style.maxWidth !== void 0 && style.margin === void 0) {
|
|
221
|
+
style.marginLeft = "auto";
|
|
222
|
+
style.marginRight = "auto";
|
|
223
|
+
}
|
|
224
|
+
return style;
|
|
199
225
|
}
|
|
200
226
|
function resolveCloseButton(config, layerName, closeTop) {
|
|
201
227
|
if (!config || config.show === false) return void 0;
|
|
@@ -659,7 +685,11 @@ function createRuntime(dsl, options = {}) {
|
|
|
659
685
|
const view = normalized.views[viewName];
|
|
660
686
|
const action = view && view.stage && view.stage[hook];
|
|
661
687
|
if (!action) return;
|
|
662
|
-
|
|
688
|
+
const reason = extra && extra.closeReason;
|
|
689
|
+
dispatch(action, Object.assign({}, buildContext(), extra), {
|
|
690
|
+
trigger: hook === "onShow" ? "show" : "close",
|
|
691
|
+
reason: typeof reason === "string" ? reason : void 0
|
|
692
|
+
});
|
|
663
693
|
}
|
|
664
694
|
function loadData() {
|
|
665
695
|
const data = dsl.data || {};
|
|
@@ -690,8 +720,8 @@ function createRuntime(dsl, options = {}) {
|
|
|
690
720
|
resolvedData = resolved;
|
|
691
721
|
loading = false;
|
|
692
722
|
notify();
|
|
693
|
-
emit("ready", { keys: Object.keys(resolved) });
|
|
694
723
|
fireLifecycle(normalized.entry, "onShow");
|
|
724
|
+
emit("ready", { keys: Object.keys(resolved) });
|
|
695
725
|
}).catch((error) => {
|
|
696
726
|
if (destroyed) return;
|
|
697
727
|
loading = false;
|
package/dist/report/index.cjs
CHANGED
|
@@ -1,41 +1,58 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
// src/report/map.ts
|
|
4
|
-
function
|
|
4
|
+
function pickInteractionTrack(payload) {
|
|
5
|
+
const track = payload == null ? void 0 : payload.track;
|
|
6
|
+
if (!track) return void 0;
|
|
7
|
+
return { name: track.event, params: track.params };
|
|
8
|
+
}
|
|
9
|
+
function buildExposureReport(id, extra) {
|
|
5
10
|
if (!id) return null;
|
|
6
|
-
|
|
11
|
+
const params = { id, event: "exposure" };
|
|
12
|
+
if (extra && (extra.name !== void 0 || extra.params !== void 0)) {
|
|
13
|
+
params.extra = extra;
|
|
14
|
+
}
|
|
15
|
+
return params;
|
|
7
16
|
}
|
|
8
|
-
function
|
|
17
|
+
function buildCloseReport(id, options) {
|
|
9
18
|
if (!id) return null;
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
event: "close",
|
|
32
|
-
reason: data.reason
|
|
33
|
-
};
|
|
34
|
-
}
|
|
35
|
-
default:
|
|
36
|
-
return null;
|
|
19
|
+
const params = {
|
|
20
|
+
id,
|
|
21
|
+
event: "close",
|
|
22
|
+
reason: options == null ? void 0 : options.reason
|
|
23
|
+
};
|
|
24
|
+
const extra = options == null ? void 0 : options.extra;
|
|
25
|
+
if (extra && (extra.name !== void 0 || extra.params !== void 0)) {
|
|
26
|
+
params.extra = extra;
|
|
27
|
+
}
|
|
28
|
+
return params;
|
|
29
|
+
}
|
|
30
|
+
function buildClickExtra(payload) {
|
|
31
|
+
const { track, navigate } = payload;
|
|
32
|
+
if (track) {
|
|
33
|
+
const extra = {
|
|
34
|
+
trigger: "track",
|
|
35
|
+
name: track.event,
|
|
36
|
+
params: track.params
|
|
37
|
+
};
|
|
38
|
+
if (navigate == null ? void 0 : navigate.url) extra.url = navigate.url;
|
|
39
|
+
return extra;
|
|
37
40
|
}
|
|
41
|
+
if (navigate) return { trigger: "navigate", url: navigate.url };
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
function mapRuntimeEventToReport(id, event, payload) {
|
|
45
|
+
if (!id) return null;
|
|
46
|
+
if (event !== "interaction") return null;
|
|
47
|
+
const data = payload != null ? payload : {};
|
|
48
|
+
if (data.trigger !== "action") return null;
|
|
49
|
+
if (data.closes) return null;
|
|
50
|
+
const extra = buildClickExtra(data);
|
|
51
|
+
if (!extra) return null;
|
|
52
|
+
return { id, event: "click", extra };
|
|
38
53
|
}
|
|
39
54
|
|
|
55
|
+
exports.buildCloseReport = buildCloseReport;
|
|
40
56
|
exports.buildExposureReport = buildExposureReport;
|
|
41
57
|
exports.mapRuntimeEventToReport = mapRuntimeEventToReport;
|
|
58
|
+
exports.pickInteractionTrack = pickInteractionTrack;
|
package/dist/report/index.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { G as RuntimeEventName, E as DslInteractionEvent } from '../types-Bj0xyWnx.cjs';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* 营销物料上报载荷类型(上报契约的唯一数据源)。
|
|
@@ -19,23 +19,39 @@ import { E as RuntimeEventName } from '../types-BgUaJUAu.cjs';
|
|
|
19
19
|
* - `close` 关闭:用户关掉了这条物料
|
|
20
20
|
*/
|
|
21
21
|
type MarketingReportEvent = 'exposure' | 'click' | 'close';
|
|
22
|
+
/**
|
|
23
|
+
* 运营配的埋点信息(`track` 动作的事件名与参数)
|
|
24
|
+
*
|
|
25
|
+
* 挂在 `stage.onShow` / `stage.onClose` 上的 `track` 属于「曝光埋点 / 关闭埋点」,
|
|
26
|
+
* **不算点击**,所以它们进的是 `exposure` / `close` 的 `extra`,而不是产出一条 `click`。
|
|
27
|
+
* 早期实现把这类埋点名一律映射成 `click`,直接把点击量放大了数倍。
|
|
28
|
+
*/
|
|
29
|
+
interface MarketingTrackExtra {
|
|
30
|
+
/** 运营在配置里写的埋点名 */
|
|
31
|
+
name?: string;
|
|
32
|
+
/** 运营在配置里写的自定义参数,原样透传 */
|
|
33
|
+
params?: Record<string, unknown>;
|
|
34
|
+
}
|
|
22
35
|
/**
|
|
23
36
|
* 点击上报的附加信息(**只在 `event='click'` 时有值**)
|
|
24
37
|
*
|
|
25
38
|
* 运营在 DSL 里自定义的埋点名 / 参数一律放这里,
|
|
26
39
|
* **不要塞进 `reason`** —— `reason` 的语义被「关闭原因」独占。
|
|
40
|
+
*
|
|
41
|
+
* 一次点击里同时配了埋点和跳转(`sequence: [track, navigate]`,最常见的写法)时,
|
|
42
|
+
* 只产出**一条** click:`trigger='track'`,跳转地址并进 `url`。
|
|
27
43
|
*/
|
|
28
44
|
interface MarketingClickExtra {
|
|
29
45
|
/** 点击来源:`track` = 运营配的埋点动作;`navigate` = 跳转动作 */
|
|
30
46
|
trigger: 'track' | 'navigate';
|
|
31
47
|
/** `trigger='track'` 时:运营在配置里写的埋点名 */
|
|
32
48
|
name?: string;
|
|
33
|
-
/**
|
|
49
|
+
/** 跳转目标地址:`trigger='navigate'` 时必有;`trigger='track'` 时若同一次点击里还配了跳转也会带上 */
|
|
34
50
|
url?: string;
|
|
35
51
|
/** 运营在配置里写的自定义参数,原样透传 */
|
|
36
52
|
params?: Record<string, unknown>;
|
|
37
53
|
}
|
|
38
|
-
/**
|
|
54
|
+
/** 曝光上报入参:运营在 `stage.onShow` 里配了埋点时带上 `extra` */
|
|
39
55
|
interface MarketingExposureReportParams {
|
|
40
56
|
/** 物料 id,取自 `MarketingMaterial.id` */
|
|
41
57
|
id: string;
|
|
@@ -43,8 +59,14 @@ interface MarketingExposureReportParams {
|
|
|
43
59
|
event: 'exposure';
|
|
44
60
|
/** 曝光事件无关闭原因 */
|
|
45
61
|
reason?: never;
|
|
46
|
-
/**
|
|
47
|
-
|
|
62
|
+
/**
|
|
63
|
+
* 运营配在 `stage.onShow` 里的埋点名 / 参数,没配则不带。
|
|
64
|
+
*
|
|
65
|
+
* 【为什么并进曝光而不是单独上报】那条 `track` 记的就是「这条物料露出了」,
|
|
66
|
+
* 与曝光是同一件事,单独上报会与前台统一发的 exposure 重复计数;
|
|
67
|
+
* 但也不能直接丢掉 —— 运营配了就该在后端看得到。
|
|
68
|
+
*/
|
|
69
|
+
extra?: MarketingTrackExtra;
|
|
48
70
|
}
|
|
49
71
|
/** 关闭上报入参:可带关闭原因 */
|
|
50
72
|
interface MarketingCloseReportParams {
|
|
@@ -58,8 +80,8 @@ interface MarketingCloseReportParams {
|
|
|
58
80
|
* `action`(配置里 close 动作未写 reason 的默认值)/ 运营自定义值。
|
|
59
81
|
*/
|
|
60
82
|
reason?: string;
|
|
61
|
-
/**
|
|
62
|
-
extra?:
|
|
83
|
+
/** 运营配在 `stage.onClose` 里的埋点名 / 参数,没配则不带 */
|
|
84
|
+
extra?: MarketingTrackExtra;
|
|
63
85
|
}
|
|
64
86
|
/** 点击上报入参:必须带 extra 说明点了什么 */
|
|
65
87
|
interface MarketingClickReportParams {
|
|
@@ -76,7 +98,10 @@ interface MarketingClickReportParams {
|
|
|
76
98
|
* 上报物料事件的入参(可辨识联合,按 `event` 区分)
|
|
77
99
|
*
|
|
78
100
|
* 用联合而非「三个可选字段」是为了把契约写进类型里:`reason` 只配 `close`、
|
|
79
|
-
* `
|
|
101
|
+
* 点击详情(`MarketingClickExtra`,带 `trigger`)只配 `click`,写错直接编译不过。
|
|
102
|
+
* `exposure` / `close` 的 `extra` 是另一种形态(`MarketingTrackExtra`,只有 `name` / `params`),
|
|
103
|
+
* 装的是运营配在 `stage.onShow` / `onClose` 里的埋点名 —— 它们不是点击,混不进 click 那一支。
|
|
104
|
+
* 不该出现的字段声明成 `?: never`
|
|
80
105
|
* 而不是省略,这样消费方(formatter / 上报层 / 调试台预览)仍能直接读
|
|
81
106
|
* `params.reason`、`params.extra`,无需先做类型窄化 —— 约束留在调用侧,消费侧照旧好写。
|
|
82
107
|
*/
|
|
@@ -88,39 +113,44 @@ type MarketingReportParams = MarketingExposureReportParams | MarketingCloseRepor
|
|
|
88
113
|
* 前台坑位组件与后台调试台的「上报预览」共用这一份:
|
|
89
114
|
* 调试台要展示的就是**真实会发给后端的 JSON**,映射有第二份实现,
|
|
90
115
|
* 前台改了口径而调试台忘了改,调试台就会骗人。
|
|
116
|
+
*
|
|
117
|
+
* 【只认 `interaction`,不认 `track` / `navigate`】
|
|
118
|
+
* 动作粒度的事件不能直接当上报口径:`sequence: [track, navigate]`(先埋点再跳转)
|
|
119
|
+
* 是最常见的写法,两个动作各报一条 → 点击量翻倍;而 `track` 还能挂在
|
|
120
|
+
* `stage.onShow` / `onClose` 上,动作粒度看不出时机 → 曝光和关闭也被算成点击。
|
|
121
|
+
* 解释器为此在**交互粒度**上多抛了一条 `interaction`(一次手势 / 一个时机一条),
|
|
122
|
+
* 上报只认它。
|
|
91
123
|
*/
|
|
92
124
|
|
|
93
125
|
/**
|
|
94
126
|
* 会产生上报的运行时事件及其载荷。
|
|
95
127
|
*
|
|
96
|
-
*
|
|
128
|
+
* 字段一律可选(`Partial`):宿主(Vue 组件的 `$event`、调试台的手工构造)拿到的载荷未必齐全,
|
|
97
129
|
* 缺字段是允许的,不该在映射这一步炸掉。
|
|
98
130
|
*/
|
|
99
131
|
interface MarketingReportableEventPayloads {
|
|
100
|
-
/**
|
|
101
|
-
|
|
102
|
-
event?: string;
|
|
103
|
-
params?: Record<string, unknown>;
|
|
104
|
-
};
|
|
105
|
-
/** 跳转动作:`url` 是目标地址(跳转本身由渲染壳完成,这里只记一笔) */
|
|
106
|
-
navigate: {
|
|
107
|
-
url?: string;
|
|
108
|
-
target?: string;
|
|
109
|
-
};
|
|
110
|
-
/** 关闭:`reason` 是关闭原因 */
|
|
111
|
-
close: {
|
|
112
|
-
reason?: string;
|
|
113
|
-
};
|
|
132
|
+
/** 一次交互的汇总事件,见 {@link DslInteractionEvent} */
|
|
133
|
+
interaction: Partial<DslInteractionEvent>;
|
|
114
134
|
}
|
|
115
135
|
/** 会产生上报的运行时事件名 */
|
|
116
136
|
type MarketingReportableEventName = keyof MarketingReportableEventPayloads;
|
|
117
137
|
/**
|
|
118
138
|
* 事件名 → 载荷类型。
|
|
119
139
|
*
|
|
120
|
-
* 不产生上报的事件(`
|
|
121
|
-
*
|
|
140
|
+
* 不产生上报的事件(`track` / `navigate` / `close` / `call` / `error` / `state-change` /
|
|
141
|
+
* `view-change` / `ready` / `open`)载荷为 `unknown`:调用方照常传,映射返回 `null`。
|
|
122
142
|
*/
|
|
123
143
|
type MarketingRuntimeEventPayload<K extends RuntimeEventName> = K extends MarketingReportableEventName ? MarketingReportableEventPayloads[K] : unknown;
|
|
144
|
+
/**
|
|
145
|
+
* 把交互事件里的埋点动作转成上报用的 `extra`(字段名 `event` → `name`)。
|
|
146
|
+
*
|
|
147
|
+
* 给宿主组装曝光 / 关闭上报用:`trigger='show'` / `'close'` 的 interaction 不产出点击,
|
|
148
|
+
* 但运营配的埋点名不能凭空消失,由宿主并进 exposure / close 的 `extra`。
|
|
149
|
+
*
|
|
150
|
+
* @param payload interaction 事件载荷
|
|
151
|
+
* @returns 埋点信息;没配埋点时返回 `undefined`
|
|
152
|
+
*/
|
|
153
|
+
declare function pickInteractionTrack(payload?: Partial<DslInteractionEvent> | null): MarketingTrackExtra | undefined;
|
|
124
154
|
/**
|
|
125
155
|
* 曝光上报载荷。
|
|
126
156
|
*
|
|
@@ -128,17 +158,36 @@ type MarketingRuntimeEventPayload<K extends RuntimeEventName> = K extends Market
|
|
|
128
158
|
* 解释器根本不知道自己被画出来了。
|
|
129
159
|
*
|
|
130
160
|
* @param id 物料 id,为空(未取到物料)时返回 `null`,不产生上报
|
|
161
|
+
* @param extra 运营配在 `stage.onShow` 里的埋点信息,可用 {@link pickInteractionTrack} 从
|
|
162
|
+
* `trigger='show'` 的 interaction 事件里取;没有则不带
|
|
163
|
+
* @returns 上报载荷,或 `null`
|
|
164
|
+
*/
|
|
165
|
+
declare function buildExposureReport(id: string | undefined | null, extra?: MarketingTrackExtra | null): MarketingExposureReportParams | null;
|
|
166
|
+
/**
|
|
167
|
+
* 关闭上报载荷。
|
|
168
|
+
*
|
|
169
|
+
* 与曝光同理由:关闭由宿主统一上报一条 —— `close` 运行时事件才是「这条物料真的关了」,
|
|
170
|
+
* 运营配不配 `stage.onClose` 都得有这条。
|
|
171
|
+
*
|
|
172
|
+
* @param id 物料 id,为空时返回 `null`
|
|
173
|
+
* @param options `reason` 取自 `close` 运行时事件;`extra` 取自 `trigger='close'` 的 interaction
|
|
131
174
|
* @returns 上报载荷,或 `null`
|
|
132
175
|
*/
|
|
133
|
-
declare function
|
|
176
|
+
declare function buildCloseReport(id: string | undefined | null, options?: {
|
|
177
|
+
reason?: string;
|
|
178
|
+
extra?: MarketingTrackExtra | null;
|
|
179
|
+
}): MarketingCloseReportParams | null;
|
|
134
180
|
/**
|
|
135
181
|
* 把一个 DSL 运行时事件映射成上报载荷。
|
|
136
182
|
*
|
|
137
183
|
* 口径(与 `docs/marketing/README.md` 的契约一一对应):
|
|
138
|
-
* - `
|
|
139
|
-
* - `
|
|
140
|
-
*
|
|
141
|
-
* -
|
|
184
|
+
* - `interaction` 且 `trigger='action'` → 一条 `click`,`extra` 见 {@link buildClickExtra}
|
|
185
|
+
* - `interaction` 且 `trigger='show'` / `'close'` → `null`:曝光 / 关闭由宿主统一上报,
|
|
186
|
+
* 运营配在这两个时机上的埋点名走 {@link buildExposureReport} / {@link buildCloseReport} 的 `extra`
|
|
187
|
+
* - `interaction` 且 `trigger='action'` 但 `closes` 为真(手势里执行了关闭动作)→ `null`:
|
|
188
|
+
* 点关闭按钮的本质是关闭,不再算一次点击
|
|
189
|
+
* - 其余事件(`track` / `navigate` / `close` / `call` / `error` / `state-change` /
|
|
190
|
+
* `view-change` / `ready` / `open`)不产生上报 —— 它们是动作粒度的事件,按它们上报会重复计数
|
|
142
191
|
*
|
|
143
192
|
* @param id 物料 id,为空时返回 `null`(拿不到 id 的上报对后端没有意义)
|
|
144
193
|
* @param event 运行时事件名
|
|
@@ -147,4 +196,4 @@ declare function buildExposureReport(id: string | undefined | null): MarketingEx
|
|
|
147
196
|
*/
|
|
148
197
|
declare function mapRuntimeEventToReport<K extends RuntimeEventName>(id: string | undefined | null, event: K, payload?: MarketingRuntimeEventPayload<K>): MarketingReportParams | null;
|
|
149
198
|
|
|
150
|
-
export { type MarketingClickExtra, type MarketingClickReportParams, type MarketingCloseReportParams, type MarketingExposureReportParams, type MarketingReportEvent, type MarketingReportParams, type MarketingReportableEventName, type MarketingReportableEventPayloads, type MarketingRuntimeEventPayload, buildExposureReport, mapRuntimeEventToReport };
|
|
199
|
+
export { type MarketingClickExtra, type MarketingClickReportParams, type MarketingCloseReportParams, type MarketingExposureReportParams, type MarketingReportEvent, type MarketingReportParams, type MarketingReportableEventName, type MarketingReportableEventPayloads, type MarketingRuntimeEventPayload, type MarketingTrackExtra, buildCloseReport, buildExposureReport, mapRuntimeEventToReport, pickInteractionTrack };
|
package/dist/report/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { G as RuntimeEventName, E as DslInteractionEvent } from '../types-Bj0xyWnx.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* 营销物料上报载荷类型(上报契约的唯一数据源)。
|
|
@@ -19,23 +19,39 @@ import { E as RuntimeEventName } from '../types-BgUaJUAu.js';
|
|
|
19
19
|
* - `close` 关闭:用户关掉了这条物料
|
|
20
20
|
*/
|
|
21
21
|
type MarketingReportEvent = 'exposure' | 'click' | 'close';
|
|
22
|
+
/**
|
|
23
|
+
* 运营配的埋点信息(`track` 动作的事件名与参数)
|
|
24
|
+
*
|
|
25
|
+
* 挂在 `stage.onShow` / `stage.onClose` 上的 `track` 属于「曝光埋点 / 关闭埋点」,
|
|
26
|
+
* **不算点击**,所以它们进的是 `exposure` / `close` 的 `extra`,而不是产出一条 `click`。
|
|
27
|
+
* 早期实现把这类埋点名一律映射成 `click`,直接把点击量放大了数倍。
|
|
28
|
+
*/
|
|
29
|
+
interface MarketingTrackExtra {
|
|
30
|
+
/** 运营在配置里写的埋点名 */
|
|
31
|
+
name?: string;
|
|
32
|
+
/** 运营在配置里写的自定义参数,原样透传 */
|
|
33
|
+
params?: Record<string, unknown>;
|
|
34
|
+
}
|
|
22
35
|
/**
|
|
23
36
|
* 点击上报的附加信息(**只在 `event='click'` 时有值**)
|
|
24
37
|
*
|
|
25
38
|
* 运营在 DSL 里自定义的埋点名 / 参数一律放这里,
|
|
26
39
|
* **不要塞进 `reason`** —— `reason` 的语义被「关闭原因」独占。
|
|
40
|
+
*
|
|
41
|
+
* 一次点击里同时配了埋点和跳转(`sequence: [track, navigate]`,最常见的写法)时,
|
|
42
|
+
* 只产出**一条** click:`trigger='track'`,跳转地址并进 `url`。
|
|
27
43
|
*/
|
|
28
44
|
interface MarketingClickExtra {
|
|
29
45
|
/** 点击来源:`track` = 运营配的埋点动作;`navigate` = 跳转动作 */
|
|
30
46
|
trigger: 'track' | 'navigate';
|
|
31
47
|
/** `trigger='track'` 时:运营在配置里写的埋点名 */
|
|
32
48
|
name?: string;
|
|
33
|
-
/**
|
|
49
|
+
/** 跳转目标地址:`trigger='navigate'` 时必有;`trigger='track'` 时若同一次点击里还配了跳转也会带上 */
|
|
34
50
|
url?: string;
|
|
35
51
|
/** 运营在配置里写的自定义参数,原样透传 */
|
|
36
52
|
params?: Record<string, unknown>;
|
|
37
53
|
}
|
|
38
|
-
/**
|
|
54
|
+
/** 曝光上报入参:运营在 `stage.onShow` 里配了埋点时带上 `extra` */
|
|
39
55
|
interface MarketingExposureReportParams {
|
|
40
56
|
/** 物料 id,取自 `MarketingMaterial.id` */
|
|
41
57
|
id: string;
|
|
@@ -43,8 +59,14 @@ interface MarketingExposureReportParams {
|
|
|
43
59
|
event: 'exposure';
|
|
44
60
|
/** 曝光事件无关闭原因 */
|
|
45
61
|
reason?: never;
|
|
46
|
-
/**
|
|
47
|
-
|
|
62
|
+
/**
|
|
63
|
+
* 运营配在 `stage.onShow` 里的埋点名 / 参数,没配则不带。
|
|
64
|
+
*
|
|
65
|
+
* 【为什么并进曝光而不是单独上报】那条 `track` 记的就是「这条物料露出了」,
|
|
66
|
+
* 与曝光是同一件事,单独上报会与前台统一发的 exposure 重复计数;
|
|
67
|
+
* 但也不能直接丢掉 —— 运营配了就该在后端看得到。
|
|
68
|
+
*/
|
|
69
|
+
extra?: MarketingTrackExtra;
|
|
48
70
|
}
|
|
49
71
|
/** 关闭上报入参:可带关闭原因 */
|
|
50
72
|
interface MarketingCloseReportParams {
|
|
@@ -58,8 +80,8 @@ interface MarketingCloseReportParams {
|
|
|
58
80
|
* `action`(配置里 close 动作未写 reason 的默认值)/ 运营自定义值。
|
|
59
81
|
*/
|
|
60
82
|
reason?: string;
|
|
61
|
-
/**
|
|
62
|
-
extra?:
|
|
83
|
+
/** 运营配在 `stage.onClose` 里的埋点名 / 参数,没配则不带 */
|
|
84
|
+
extra?: MarketingTrackExtra;
|
|
63
85
|
}
|
|
64
86
|
/** 点击上报入参:必须带 extra 说明点了什么 */
|
|
65
87
|
interface MarketingClickReportParams {
|
|
@@ -76,7 +98,10 @@ interface MarketingClickReportParams {
|
|
|
76
98
|
* 上报物料事件的入参(可辨识联合,按 `event` 区分)
|
|
77
99
|
*
|
|
78
100
|
* 用联合而非「三个可选字段」是为了把契约写进类型里:`reason` 只配 `close`、
|
|
79
|
-
* `
|
|
101
|
+
* 点击详情(`MarketingClickExtra`,带 `trigger`)只配 `click`,写错直接编译不过。
|
|
102
|
+
* `exposure` / `close` 的 `extra` 是另一种形态(`MarketingTrackExtra`,只有 `name` / `params`),
|
|
103
|
+
* 装的是运营配在 `stage.onShow` / `onClose` 里的埋点名 —— 它们不是点击,混不进 click 那一支。
|
|
104
|
+
* 不该出现的字段声明成 `?: never`
|
|
80
105
|
* 而不是省略,这样消费方(formatter / 上报层 / 调试台预览)仍能直接读
|
|
81
106
|
* `params.reason`、`params.extra`,无需先做类型窄化 —— 约束留在调用侧,消费侧照旧好写。
|
|
82
107
|
*/
|
|
@@ -88,39 +113,44 @@ type MarketingReportParams = MarketingExposureReportParams | MarketingCloseRepor
|
|
|
88
113
|
* 前台坑位组件与后台调试台的「上报预览」共用这一份:
|
|
89
114
|
* 调试台要展示的就是**真实会发给后端的 JSON**,映射有第二份实现,
|
|
90
115
|
* 前台改了口径而调试台忘了改,调试台就会骗人。
|
|
116
|
+
*
|
|
117
|
+
* 【只认 `interaction`,不认 `track` / `navigate`】
|
|
118
|
+
* 动作粒度的事件不能直接当上报口径:`sequence: [track, navigate]`(先埋点再跳转)
|
|
119
|
+
* 是最常见的写法,两个动作各报一条 → 点击量翻倍;而 `track` 还能挂在
|
|
120
|
+
* `stage.onShow` / `onClose` 上,动作粒度看不出时机 → 曝光和关闭也被算成点击。
|
|
121
|
+
* 解释器为此在**交互粒度**上多抛了一条 `interaction`(一次手势 / 一个时机一条),
|
|
122
|
+
* 上报只认它。
|
|
91
123
|
*/
|
|
92
124
|
|
|
93
125
|
/**
|
|
94
126
|
* 会产生上报的运行时事件及其载荷。
|
|
95
127
|
*
|
|
96
|
-
*
|
|
128
|
+
* 字段一律可选(`Partial`):宿主(Vue 组件的 `$event`、调试台的手工构造)拿到的载荷未必齐全,
|
|
97
129
|
* 缺字段是允许的,不该在映射这一步炸掉。
|
|
98
130
|
*/
|
|
99
131
|
interface MarketingReportableEventPayloads {
|
|
100
|
-
/**
|
|
101
|
-
|
|
102
|
-
event?: string;
|
|
103
|
-
params?: Record<string, unknown>;
|
|
104
|
-
};
|
|
105
|
-
/** 跳转动作:`url` 是目标地址(跳转本身由渲染壳完成,这里只记一笔) */
|
|
106
|
-
navigate: {
|
|
107
|
-
url?: string;
|
|
108
|
-
target?: string;
|
|
109
|
-
};
|
|
110
|
-
/** 关闭:`reason` 是关闭原因 */
|
|
111
|
-
close: {
|
|
112
|
-
reason?: string;
|
|
113
|
-
};
|
|
132
|
+
/** 一次交互的汇总事件,见 {@link DslInteractionEvent} */
|
|
133
|
+
interaction: Partial<DslInteractionEvent>;
|
|
114
134
|
}
|
|
115
135
|
/** 会产生上报的运行时事件名 */
|
|
116
136
|
type MarketingReportableEventName = keyof MarketingReportableEventPayloads;
|
|
117
137
|
/**
|
|
118
138
|
* 事件名 → 载荷类型。
|
|
119
139
|
*
|
|
120
|
-
* 不产生上报的事件(`
|
|
121
|
-
*
|
|
140
|
+
* 不产生上报的事件(`track` / `navigate` / `close` / `call` / `error` / `state-change` /
|
|
141
|
+
* `view-change` / `ready` / `open`)载荷为 `unknown`:调用方照常传,映射返回 `null`。
|
|
122
142
|
*/
|
|
123
143
|
type MarketingRuntimeEventPayload<K extends RuntimeEventName> = K extends MarketingReportableEventName ? MarketingReportableEventPayloads[K] : unknown;
|
|
144
|
+
/**
|
|
145
|
+
* 把交互事件里的埋点动作转成上报用的 `extra`(字段名 `event` → `name`)。
|
|
146
|
+
*
|
|
147
|
+
* 给宿主组装曝光 / 关闭上报用:`trigger='show'` / `'close'` 的 interaction 不产出点击,
|
|
148
|
+
* 但运营配的埋点名不能凭空消失,由宿主并进 exposure / close 的 `extra`。
|
|
149
|
+
*
|
|
150
|
+
* @param payload interaction 事件载荷
|
|
151
|
+
* @returns 埋点信息;没配埋点时返回 `undefined`
|
|
152
|
+
*/
|
|
153
|
+
declare function pickInteractionTrack(payload?: Partial<DslInteractionEvent> | null): MarketingTrackExtra | undefined;
|
|
124
154
|
/**
|
|
125
155
|
* 曝光上报载荷。
|
|
126
156
|
*
|
|
@@ -128,17 +158,36 @@ type MarketingRuntimeEventPayload<K extends RuntimeEventName> = K extends Market
|
|
|
128
158
|
* 解释器根本不知道自己被画出来了。
|
|
129
159
|
*
|
|
130
160
|
* @param id 物料 id,为空(未取到物料)时返回 `null`,不产生上报
|
|
161
|
+
* @param extra 运营配在 `stage.onShow` 里的埋点信息,可用 {@link pickInteractionTrack} 从
|
|
162
|
+
* `trigger='show'` 的 interaction 事件里取;没有则不带
|
|
163
|
+
* @returns 上报载荷,或 `null`
|
|
164
|
+
*/
|
|
165
|
+
declare function buildExposureReport(id: string | undefined | null, extra?: MarketingTrackExtra | null): MarketingExposureReportParams | null;
|
|
166
|
+
/**
|
|
167
|
+
* 关闭上报载荷。
|
|
168
|
+
*
|
|
169
|
+
* 与曝光同理由:关闭由宿主统一上报一条 —— `close` 运行时事件才是「这条物料真的关了」,
|
|
170
|
+
* 运营配不配 `stage.onClose` 都得有这条。
|
|
171
|
+
*
|
|
172
|
+
* @param id 物料 id,为空时返回 `null`
|
|
173
|
+
* @param options `reason` 取自 `close` 运行时事件;`extra` 取自 `trigger='close'` 的 interaction
|
|
131
174
|
* @returns 上报载荷,或 `null`
|
|
132
175
|
*/
|
|
133
|
-
declare function
|
|
176
|
+
declare function buildCloseReport(id: string | undefined | null, options?: {
|
|
177
|
+
reason?: string;
|
|
178
|
+
extra?: MarketingTrackExtra | null;
|
|
179
|
+
}): MarketingCloseReportParams | null;
|
|
134
180
|
/**
|
|
135
181
|
* 把一个 DSL 运行时事件映射成上报载荷。
|
|
136
182
|
*
|
|
137
183
|
* 口径(与 `docs/marketing/README.md` 的契约一一对应):
|
|
138
|
-
* - `
|
|
139
|
-
* - `
|
|
140
|
-
*
|
|
141
|
-
* -
|
|
184
|
+
* - `interaction` 且 `trigger='action'` → 一条 `click`,`extra` 见 {@link buildClickExtra}
|
|
185
|
+
* - `interaction` 且 `trigger='show'` / `'close'` → `null`:曝光 / 关闭由宿主统一上报,
|
|
186
|
+
* 运营配在这两个时机上的埋点名走 {@link buildExposureReport} / {@link buildCloseReport} 的 `extra`
|
|
187
|
+
* - `interaction` 且 `trigger='action'` 但 `closes` 为真(手势里执行了关闭动作)→ `null`:
|
|
188
|
+
* 点关闭按钮的本质是关闭,不再算一次点击
|
|
189
|
+
* - 其余事件(`track` / `navigate` / `close` / `call` / `error` / `state-change` /
|
|
190
|
+
* `view-change` / `ready` / `open`)不产生上报 —— 它们是动作粒度的事件,按它们上报会重复计数
|
|
142
191
|
*
|
|
143
192
|
* @param id 物料 id,为空时返回 `null`(拿不到 id 的上报对后端没有意义)
|
|
144
193
|
* @param event 运行时事件名
|
|
@@ -147,4 +196,4 @@ declare function buildExposureReport(id: string | undefined | null): MarketingEx
|
|
|
147
196
|
*/
|
|
148
197
|
declare function mapRuntimeEventToReport<K extends RuntimeEventName>(id: string | undefined | null, event: K, payload?: MarketingRuntimeEventPayload<K>): MarketingReportParams | null;
|
|
149
198
|
|
|
150
|
-
export { type MarketingClickExtra, type MarketingClickReportParams, type MarketingCloseReportParams, type MarketingExposureReportParams, type MarketingReportEvent, type MarketingReportParams, type MarketingReportableEventName, type MarketingReportableEventPayloads, type MarketingRuntimeEventPayload, buildExposureReport, mapRuntimeEventToReport };
|
|
199
|
+
export { type MarketingClickExtra, type MarketingClickReportParams, type MarketingCloseReportParams, type MarketingExposureReportParams, type MarketingReportEvent, type MarketingReportParams, type MarketingReportableEventName, type MarketingReportableEventPayloads, type MarketingRuntimeEventPayload, type MarketingTrackExtra, buildCloseReport, buildExposureReport, mapRuntimeEventToReport, pickInteractionTrack };
|