@yaoxiu/marketing-dsl 1.5.2 → 2.0.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-BSJDNS6C.js} +121 -2
- package/dist/docs/index.cjs +191 -43
- package/dist/docs/index.d.cts +1 -1
- package/dist/docs/index.d.ts +1 -1
- package/dist/docs/index.js +164 -44
- package/dist/index.cjs +167 -15
- package/dist/index.d.cts +63 -4
- package/dist/index.d.ts +63 -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/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 };
|
package/dist/report/index.js
CHANGED
|
@@ -1,38 +1,53 @@
|
|
|
1
1
|
// src/report/map.ts
|
|
2
|
-
function
|
|
2
|
+
function pickInteractionTrack(payload) {
|
|
3
|
+
const track = payload == null ? void 0 : payload.track;
|
|
4
|
+
if (!track) return void 0;
|
|
5
|
+
return { name: track.event, params: track.params };
|
|
6
|
+
}
|
|
7
|
+
function buildExposureReport(id, extra) {
|
|
3
8
|
if (!id) return null;
|
|
4
|
-
|
|
9
|
+
const params = { id, event: "exposure" };
|
|
10
|
+
if (extra && (extra.name !== void 0 || extra.params !== void 0)) {
|
|
11
|
+
params.extra = extra;
|
|
12
|
+
}
|
|
13
|
+
return params;
|
|
5
14
|
}
|
|
6
|
-
function
|
|
15
|
+
function buildCloseReport(id, options) {
|
|
7
16
|
if (!id) return null;
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
event: "close",
|
|
30
|
-
reason: data.reason
|
|
31
|
-
};
|
|
32
|
-
}
|
|
33
|
-
default:
|
|
34
|
-
return null;
|
|
17
|
+
const params = {
|
|
18
|
+
id,
|
|
19
|
+
event: "close",
|
|
20
|
+
reason: options == null ? void 0 : options.reason
|
|
21
|
+
};
|
|
22
|
+
const extra = options == null ? void 0 : options.extra;
|
|
23
|
+
if (extra && (extra.name !== void 0 || extra.params !== void 0)) {
|
|
24
|
+
params.extra = extra;
|
|
25
|
+
}
|
|
26
|
+
return params;
|
|
27
|
+
}
|
|
28
|
+
function buildClickExtra(payload) {
|
|
29
|
+
const { track, navigate } = payload;
|
|
30
|
+
if (track) {
|
|
31
|
+
const extra = {
|
|
32
|
+
trigger: "track",
|
|
33
|
+
name: track.event,
|
|
34
|
+
params: track.params
|
|
35
|
+
};
|
|
36
|
+
if (navigate == null ? void 0 : navigate.url) extra.url = navigate.url;
|
|
37
|
+
return extra;
|
|
35
38
|
}
|
|
39
|
+
if (navigate) return { trigger: "navigate", url: navigate.url };
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
function mapRuntimeEventToReport(id, event, payload) {
|
|
43
|
+
if (!id) return null;
|
|
44
|
+
if (event !== "interaction") return null;
|
|
45
|
+
const data = payload != null ? payload : {};
|
|
46
|
+
if (data.trigger !== "action") return null;
|
|
47
|
+
if (data.closes) return null;
|
|
48
|
+
const extra = buildClickExtra(data);
|
|
49
|
+
if (!extra) return null;
|
|
50
|
+
return { id, event: "click", extra };
|
|
36
51
|
}
|
|
37
52
|
|
|
38
|
-
export { buildExposureReport, mapRuntimeEventToReport };
|
|
53
|
+
export { buildCloseReport, buildExposureReport, mapRuntimeEventToReport, pickInteractionTrack };
|
|
@@ -213,7 +213,12 @@ interface RenderLayer {
|
|
|
213
213
|
interface RenderTree {
|
|
214
214
|
/** 数据没回来或加载失败时为 false,框架层什么都不画 */
|
|
215
215
|
ready: boolean;
|
|
216
|
-
/**
|
|
216
|
+
/**
|
|
217
|
+
* 当前视图栈里是否有弹窗视图。
|
|
218
|
+
*
|
|
219
|
+
* 注意不是「配置里有没有 popup 视图」——多视图配置(如公告条点击弹出弹窗)在弹出之前
|
|
220
|
+
* 这里是 `false`,根容器保持 `relative`,宿主的流式坑位才不会被脱流的根节点撑塌。
|
|
221
|
+
*/
|
|
217
222
|
hasPopup: boolean;
|
|
218
223
|
/** 根容器样式,已按 hasPopup 算好 */
|
|
219
224
|
rootStyle: CssStyle;
|
|
@@ -225,6 +230,51 @@ interface RenderTree {
|
|
|
225
230
|
}
|
|
226
231
|
type DslSource = (params: Record<string, unknown>, user: Record<string, unknown>) => unknown | Promise<unknown>;
|
|
227
232
|
type DslHandler = (params: Record<string, unknown>) => void;
|
|
233
|
+
/**
|
|
234
|
+
* 一次交互(手势 / 时机)的触发来源。
|
|
235
|
+
*
|
|
236
|
+
* - `show`:视图的 `stage.onShow` 被触发(曝光时机)
|
|
237
|
+
* - `close`:视图的 `stage.onClose` 被触发(关闭时机)
|
|
238
|
+
* - `action`:用户点了带 `action` 的节点(含关闭按钮、tab、倒计时 `onEnd`)
|
|
239
|
+
*/
|
|
240
|
+
type DslInteractionTrigger = 'show' | 'close' | 'action';
|
|
241
|
+
/**
|
|
242
|
+
* 一次交互的汇总事件(`interaction`),**专供上报**。
|
|
243
|
+
*
|
|
244
|
+
* 【为什么要有它】`track` / `navigate` 是**动作**粒度的事件,一次手势里配
|
|
245
|
+
* `sequence: [track, navigate]`(先埋点再跳转)是标准写法,按动作上报必然把点击量翻倍;
|
|
246
|
+
* 而 `track` 还能挂在 `stage.onShow` / `stage.onClose` 上,动作粒度看不出时机,
|
|
247
|
+
* 一律算成点击会把曝光和关闭也计成点击。
|
|
248
|
+
*
|
|
249
|
+
* 所以在**时机**粒度上再派发一条汇总事件:一次手势 = 一条 `interaction`,
|
|
250
|
+
* `sequence` 里有 N 个动作也只汇总成一条。原有的 `track` / `navigate` / `close` /
|
|
251
|
+
* `call` / `error` 事件语义不变、照常派发(宿主要靠它们做跳转、接自有埋点系统),
|
|
252
|
+
* `interaction` 是**新增**的,不替代任何既有事件。
|
|
253
|
+
*/
|
|
254
|
+
interface DslInteractionEvent {
|
|
255
|
+
/** 触发时机 */
|
|
256
|
+
trigger: DslInteractionTrigger;
|
|
257
|
+
/** 关闭原因,仅 `trigger='close'` 时有值 */
|
|
258
|
+
reason?: string;
|
|
259
|
+
/** 这次交互里的埋点动作;`sequence` 里有多个 `track` 时只取第一个 */
|
|
260
|
+
track?: {
|
|
261
|
+
event: string;
|
|
262
|
+
params?: Record<string, unknown>;
|
|
263
|
+
};
|
|
264
|
+
/** 这次交互里的跳转动作;有多个 `navigate` 时只取第一个 */
|
|
265
|
+
navigate?: {
|
|
266
|
+
url: string;
|
|
267
|
+
target?: string;
|
|
268
|
+
};
|
|
269
|
+
/**
|
|
270
|
+
* 这次交互里执行了关闭动作(`close` / `closeAll`)。
|
|
271
|
+
*
|
|
272
|
+
* 用来把「点关闭按钮」和「点营销内容」区分开:前者的本质是关闭,不该再算一次点击。
|
|
273
|
+
* 运营常把埋点配进关闭按钮的 `sequence: [track, close]`,不标记的话这一下会同时
|
|
274
|
+
* 产出 close 和 click 两条,点击量照样虚增。埋点名不会丢 —— 宿主把它并进 close 上报。
|
|
275
|
+
*/
|
|
276
|
+
closes?: boolean;
|
|
277
|
+
}
|
|
228
278
|
interface RuntimeEvents {
|
|
229
279
|
ready: {
|
|
230
280
|
keys: string[];
|
|
@@ -244,6 +294,8 @@ interface RuntimeEvents {
|
|
|
244
294
|
name: string;
|
|
245
295
|
params: Record<string, unknown>;
|
|
246
296
|
};
|
|
297
|
+
/** 一次交互的汇总事件,专供上报,见 {@link DslInteractionEvent} */
|
|
298
|
+
interaction: DslInteractionEvent;
|
|
247
299
|
'state-change': Record<string, unknown>;
|
|
248
300
|
'view-change': {
|
|
249
301
|
view: string;
|
|
@@ -290,4 +342,4 @@ interface RuntimeOptions {
|
|
|
290
342
|
emit?: RuntimeEmit;
|
|
291
343
|
}
|
|
292
344
|
|
|
293
|
-
export type { DslHandler as A,
|
|
345
|
+
export type { DslHandler as A, DslInteractionTrigger as B, CssStyle as C, Dsl as D, DslInteractionEvent as E, RuntimeEvents as F, RuntimeEventName as G, RuntimeEmit as H, RuntimeOptions as R, RenderTree as a, DslView as b, DslStyle as c, DslViewType as d, DslNodeType as e, DslLength as f, DslRect as g, DslActionBase as h, DslNavigateAction as i, DslCloseAction as j, DslCloseAllAction as k, DslOpenAction as l, DslSetStateAction as m, DslTrackAction as n, DslCallAction as o, DslSequenceAction as p, DslAction as q, DslNode as r, DslClosePosition as s, DslCloseButton as t, DslStage as u, DslSourceRef as v, DslDerived as w, RenderElement as x, RenderLayer as y, DslSource as z };
|