@xhub-short/adapters 0.1.0-beta.9 → 1.0.0-beta.22
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/index.d.ts +540 -19
- package/dist/index.js +673 -48
- package/package.json +4 -4
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { IDataSource,
|
|
1
|
+
import { IDataSource, ContentItem, FeedResponse, VideoItem, IPlaylistDataSource, PlaylistData, PlaylistCollectionResponse, ILogger, LogLevel, LogEntry, IStorage, ISessionStorage, SessionSnapshot, IInteraction, Comment, ICommentAdapter, MockCommentAdapterConfig, CommentListResponse, ReplyListResponse, PostCommentPayload, CommentItem, PostReplyPayload, ReplyItem, EditCommentPayload, DeleteCommentPayload, ReportCommentPayload, IAnalytics, AnalyticsEvent, INetworkAdapter, NetworkType, NetworkQuality, IPosterLoader, IVideoLoader, VideoSource, PreloadConfig, PreloadResult, PreloadStatus, ReportReason, CommentTransformers } from '@xhub-short/contracts';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* MockDataAdapter - Development/Testing Data Source
|
|
@@ -13,16 +13,20 @@ import { IDataSource, VideoItem, FeedResponse, ILogger, LogLevel, LogEntry, ISto
|
|
|
13
13
|
* ```
|
|
14
14
|
*/
|
|
15
15
|
declare class MockDataAdapter implements IDataSource {
|
|
16
|
-
private readonly
|
|
16
|
+
private readonly items;
|
|
17
17
|
private readonly pageSize;
|
|
18
18
|
private readonly delay;
|
|
19
19
|
constructor(options?: MockDataAdapterOptions);
|
|
20
20
|
/**
|
|
21
|
-
* Fetch a page of mock
|
|
21
|
+
* Fetch a page of mock items
|
|
22
22
|
*/
|
|
23
|
-
fetchFeed(cursor?: string): Promise<FeedResponse
|
|
23
|
+
fetchFeed(cursor?: string): Promise<FeedResponse<ContentItem>>;
|
|
24
|
+
/**
|
|
25
|
+
* Get a single content item by ID
|
|
26
|
+
*/
|
|
27
|
+
getContentDetail(id: string): Promise<ContentItem>;
|
|
24
28
|
/**
|
|
25
|
-
*
|
|
29
|
+
* @deprecated Use getContentDetail instead
|
|
26
30
|
*/
|
|
27
31
|
getVideoDetail(id: string): Promise<VideoItem>;
|
|
28
32
|
/**
|
|
@@ -38,14 +42,29 @@ declare class MockDataAdapter implements IDataSource {
|
|
|
38
42
|
* Configuration options for MockDataAdapter
|
|
39
43
|
*/
|
|
40
44
|
interface MockDataAdapterOptions {
|
|
41
|
-
/** Custom mock
|
|
42
|
-
|
|
45
|
+
/** Custom mock content data */
|
|
46
|
+
items?: ContentItem[];
|
|
47
|
+
/** @deprecated Use items instead */
|
|
48
|
+
videos?: ContentItem[];
|
|
43
49
|
/** Number of items per page (default: 3) */
|
|
44
50
|
pageSize?: number;
|
|
45
51
|
/** Simulated network delay in ms (default: 300) */
|
|
46
52
|
delay?: number;
|
|
47
53
|
}
|
|
48
54
|
|
|
55
|
+
/**
|
|
56
|
+
* MockPlaylistAdapter - Development/Testing Playlist Data Source
|
|
57
|
+
*/
|
|
58
|
+
declare class MockPlaylistAdapter implements IPlaylistDataSource {
|
|
59
|
+
private readonly delay;
|
|
60
|
+
constructor(options?: {
|
|
61
|
+
delay?: number;
|
|
62
|
+
});
|
|
63
|
+
fetchPlaylist(id: string): Promise<PlaylistData>;
|
|
64
|
+
fetchPlaylistCollection(cursor?: string): Promise<PlaylistCollectionResponse>;
|
|
65
|
+
private simulateDelay;
|
|
66
|
+
}
|
|
67
|
+
|
|
49
68
|
/**
|
|
50
69
|
* Configuration options for MockLoggerAdapter
|
|
51
70
|
*/
|
|
@@ -446,9 +465,9 @@ declare class MockInteractionAdapter implements IInteraction {
|
|
|
446
465
|
/**
|
|
447
466
|
* Report a video
|
|
448
467
|
*
|
|
449
|
-
* @param
|
|
450
|
-
* @param
|
|
451
|
-
* @param
|
|
468
|
+
* @param videoId - ID of the video to report
|
|
469
|
+
* @param reason - Report reason code
|
|
470
|
+
* @param description - Optional additional description
|
|
452
471
|
*/
|
|
453
472
|
report(_videoId: string, _reason: string, _description?: string): Promise<void>;
|
|
454
473
|
/**
|
|
@@ -972,6 +991,22 @@ interface RESTEndpointMap {
|
|
|
972
991
|
*/
|
|
973
992
|
detail: string;
|
|
974
993
|
};
|
|
994
|
+
/**
|
|
995
|
+
* Playlist-related endpoints
|
|
996
|
+
*/
|
|
997
|
+
playlist?: {
|
|
998
|
+
/**
|
|
999
|
+
* GET endpoint for playlist collection (listing)
|
|
1000
|
+
* Example: '/playlists'
|
|
1001
|
+
*/
|
|
1002
|
+
list: string;
|
|
1003
|
+
/**
|
|
1004
|
+
* GET endpoint for playlist detail
|
|
1005
|
+
* :id will be replaced with playlist ID
|
|
1006
|
+
* Example: '/playlists/:id'
|
|
1007
|
+
*/
|
|
1008
|
+
detail: string;
|
|
1009
|
+
};
|
|
975
1010
|
/**
|
|
976
1011
|
* Interaction endpoints
|
|
977
1012
|
*/
|
|
@@ -990,6 +1025,12 @@ interface RESTEndpointMap {
|
|
|
990
1025
|
deleteComment: string;
|
|
991
1026
|
/** POST /videos/:id/share (optional) */
|
|
992
1027
|
share?: string;
|
|
1028
|
+
/** POST /content/:id/report (optional) */
|
|
1029
|
+
report?: string;
|
|
1030
|
+
/** GET /report-reasons (optional) */
|
|
1031
|
+
reportReasons?: string;
|
|
1032
|
+
/** POST /content/:id/not-interested (optional) */
|
|
1033
|
+
notInterested?: string;
|
|
993
1034
|
};
|
|
994
1035
|
/**
|
|
995
1036
|
* Analytics endpoints (optional) - BATCH mode
|
|
@@ -1100,14 +1141,26 @@ interface RetryConfig {
|
|
|
1100
1141
|
*/
|
|
1101
1142
|
exponentialBackoff?: boolean;
|
|
1102
1143
|
}
|
|
1144
|
+
/**
|
|
1145
|
+
* Report reason from API
|
|
1146
|
+
*/
|
|
1147
|
+
interface ReportReasonItem {
|
|
1148
|
+
id: string;
|
|
1149
|
+
label: string;
|
|
1150
|
+
description?: string;
|
|
1151
|
+
}
|
|
1103
1152
|
/**
|
|
1104
1153
|
* Response transform configuration
|
|
1105
1154
|
*/
|
|
1106
1155
|
interface TransformConfig {
|
|
1107
1156
|
/**
|
|
1108
|
-
* Transform single
|
|
1157
|
+
* Transform single content item from API response
|
|
1109
1158
|
* If not provided, uses default transform
|
|
1110
1159
|
*/
|
|
1160
|
+
contentItem?: (apiResponse: unknown) => ContentItem;
|
|
1161
|
+
/**
|
|
1162
|
+
* @deprecated Use contentItem instead. Will be removed in v3.0
|
|
1163
|
+
*/
|
|
1111
1164
|
videoItem?: (apiResponse: unknown) => VideoItem;
|
|
1112
1165
|
/**
|
|
1113
1166
|
* Transform feed response from API
|
|
@@ -1118,6 +1171,51 @@ interface TransformConfig {
|
|
|
1118
1171
|
nextCursor: string | null;
|
|
1119
1172
|
hasMore: boolean;
|
|
1120
1173
|
};
|
|
1174
|
+
/**
|
|
1175
|
+
* Transform playlist response from API
|
|
1176
|
+
* If not provided, uses default transform
|
|
1177
|
+
*/
|
|
1178
|
+
playlist?: (apiResponse: unknown) => PlaylistData;
|
|
1179
|
+
/**
|
|
1180
|
+
* Transform playlist collection response from API
|
|
1181
|
+
* If not provided, uses default transform
|
|
1182
|
+
*/
|
|
1183
|
+
playlistCollection?: (apiResponse: unknown) => PlaylistCollectionResponse;
|
|
1184
|
+
/**
|
|
1185
|
+
* Transform report reasons response from API
|
|
1186
|
+
* If not provided, uses default transform
|
|
1187
|
+
*
|
|
1188
|
+
* @example
|
|
1189
|
+
* ```ts
|
|
1190
|
+
* reportReasons: (response) => {
|
|
1191
|
+
* const data = response.data?.reasons || [];
|
|
1192
|
+
* return data.map(item => ({
|
|
1193
|
+
* id: item.id,
|
|
1194
|
+
* label: item.title,
|
|
1195
|
+
* description: item.description,
|
|
1196
|
+
* }));
|
|
1197
|
+
* }
|
|
1198
|
+
* ```
|
|
1199
|
+
*/
|
|
1200
|
+
reportReasons?: (apiResponse: unknown) => ReportReasonItem[];
|
|
1201
|
+
/**
|
|
1202
|
+
* Transform report request body before sending to API
|
|
1203
|
+
* If not provided, uses default format: { reason, description }
|
|
1204
|
+
*
|
|
1205
|
+
* @example
|
|
1206
|
+
* ```ts
|
|
1207
|
+
* reportBody: ({ contentId, reasonId, description }) => ({
|
|
1208
|
+
* video_id: contentId,
|
|
1209
|
+
* reason_id: reasonId,
|
|
1210
|
+
* description: description || '',
|
|
1211
|
+
* })
|
|
1212
|
+
* ```
|
|
1213
|
+
*/
|
|
1214
|
+
reportBody?: (input: {
|
|
1215
|
+
contentId: string;
|
|
1216
|
+
reasonId: string;
|
|
1217
|
+
description?: string;
|
|
1218
|
+
}) => Record<string, unknown>;
|
|
1121
1219
|
/**
|
|
1122
1220
|
* Field mapping for default transforms
|
|
1123
1221
|
* Used when API field names differ from defaults
|
|
@@ -1134,6 +1232,11 @@ interface FieldMapConfig {
|
|
|
1134
1232
|
* Example: { 'author.name': 'creator.display_name' }
|
|
1135
1233
|
*/
|
|
1136
1234
|
video?: Record<string, string>;
|
|
1235
|
+
/**
|
|
1236
|
+
* Article field mapping
|
|
1237
|
+
* Example: { 'author.name': 'creator.display_name' }
|
|
1238
|
+
*/
|
|
1239
|
+
article?: Record<string, string>;
|
|
1137
1240
|
/**
|
|
1138
1241
|
* FeedResponse field mapping
|
|
1139
1242
|
*/
|
|
@@ -1143,6 +1246,161 @@ interface FieldMapConfig {
|
|
|
1143
1246
|
hasMore?: string;
|
|
1144
1247
|
};
|
|
1145
1248
|
}
|
|
1249
|
+
/**
|
|
1250
|
+
* Event types for batch analytics
|
|
1251
|
+
* Maps SDK internal types to API event types
|
|
1252
|
+
*/
|
|
1253
|
+
type BatchAnalyticsEventType = 'view_start' | 'view_end' | 'scroll_pass' | 'like' | 'comment' | 'share' | 'follow_creator' | 'save' | 'report';
|
|
1254
|
+
/**
|
|
1255
|
+
* Device type for analytics context
|
|
1256
|
+
*/
|
|
1257
|
+
type BatchAnalyticsDeviceType = 'ios' | 'android' | 'web';
|
|
1258
|
+
/**
|
|
1259
|
+
* Network type for analytics context
|
|
1260
|
+
*/
|
|
1261
|
+
type BatchAnalyticsNetworkType = 'wifi' | '4g' | '5g' | 'other';
|
|
1262
|
+
/**
|
|
1263
|
+
* SDK internal analytics event data
|
|
1264
|
+
* Passed to transform function
|
|
1265
|
+
*/
|
|
1266
|
+
interface BatchAnalyticsEventData {
|
|
1267
|
+
/** SDK event type (will be mapped to API event type) */
|
|
1268
|
+
sdkEventType: string;
|
|
1269
|
+
/** Video ID */
|
|
1270
|
+
videoId?: string;
|
|
1271
|
+
/** Event timestamp */
|
|
1272
|
+
timestamp: number;
|
|
1273
|
+
/** User ID (from setUser) */
|
|
1274
|
+
userId: string | null;
|
|
1275
|
+
/** User properties (from setUser) */
|
|
1276
|
+
userProperties: Record<string, unknown>;
|
|
1277
|
+
/** Additional event data from SDK */
|
|
1278
|
+
data?: Record<string, unknown>;
|
|
1279
|
+
}
|
|
1280
|
+
/**
|
|
1281
|
+
* Context data for analytics events
|
|
1282
|
+
* Provided by Host App via config
|
|
1283
|
+
*/
|
|
1284
|
+
interface BatchAnalyticsContext {
|
|
1285
|
+
/** Get current session ID */
|
|
1286
|
+
getSessionId: () => string | null | Promise<string | null>;
|
|
1287
|
+
/** Get device type */
|
|
1288
|
+
getDeviceType: () => BatchAnalyticsDeviceType;
|
|
1289
|
+
/** Get network type */
|
|
1290
|
+
getNetworkType: () => BatchAnalyticsNetworkType | Promise<BatchAnalyticsNetworkType>;
|
|
1291
|
+
/** Get geo location (optional) */
|
|
1292
|
+
getGeoLocation?: () => string | null | Promise<string | null>;
|
|
1293
|
+
/** Get current video position index in feed */
|
|
1294
|
+
getPositionIndex?: () => number;
|
|
1295
|
+
/** Get scroll speed in ms (optional) */
|
|
1296
|
+
getScrollSpeed?: () => number | null;
|
|
1297
|
+
}
|
|
1298
|
+
/**
|
|
1299
|
+
* Single event in batch request body (after transform)
|
|
1300
|
+
*/
|
|
1301
|
+
type BatchAnalyticsRequestEvent = Record<string, unknown>;
|
|
1302
|
+
/**
|
|
1303
|
+
* Full request body for batch analytics
|
|
1304
|
+
*/
|
|
1305
|
+
interface BatchAnalyticsRequestBody {
|
|
1306
|
+
events: BatchAnalyticsRequestEvent[];
|
|
1307
|
+
}
|
|
1308
|
+
/**
|
|
1309
|
+
* Transform function to convert SDK event to API event format
|
|
1310
|
+
*
|
|
1311
|
+
* @example
|
|
1312
|
+
* ```typescript
|
|
1313
|
+
* const transform: BatchAnalyticsEventTransformer = async (event, context) => ({
|
|
1314
|
+
* event_id: crypto.randomUUID(),
|
|
1315
|
+
* user_id: event.userId,
|
|
1316
|
+
* video_id: event.videoId,
|
|
1317
|
+
* session_id: await context.getSessionId(),
|
|
1318
|
+
* event_type: mapEventType(event.sdkEventType),
|
|
1319
|
+
* position_index: context.getPositionIndex?.() ?? 0,
|
|
1320
|
+
* impression_timestamp: new Date(event.timestamp).toISOString(),
|
|
1321
|
+
* scroll_speed_ms: context.getScrollSpeed?.() ?? null,
|
|
1322
|
+
* device_type: context.getDeviceType(),
|
|
1323
|
+
* network_type: await context.getNetworkType(),
|
|
1324
|
+
* geo_location: await context.getGeoLocation?.() ?? null,
|
|
1325
|
+
* time_of_day: new Date(event.timestamp).getHours(),
|
|
1326
|
+
* day_of_week: new Date(event.timestamp).getDay(),
|
|
1327
|
+
* });
|
|
1328
|
+
* ```
|
|
1329
|
+
*/
|
|
1330
|
+
type BatchAnalyticsEventTransformer = (event: BatchAnalyticsEventData, context: BatchAnalyticsContext) => BatchAnalyticsRequestEvent | Promise<BatchAnalyticsRequestEvent>;
|
|
1331
|
+
/**
|
|
1332
|
+
* Batch analytics configuration for preset
|
|
1333
|
+
*
|
|
1334
|
+
* @example
|
|
1335
|
+
* ```typescript
|
|
1336
|
+
* const batchAnalytics: BatchAnalyticsConfig = {
|
|
1337
|
+
* batchSize: 10,
|
|
1338
|
+
* flushInterval: 30000,
|
|
1339
|
+
* context: {
|
|
1340
|
+
* getSessionId: () => sessionStorage.getItem('session_id'),
|
|
1341
|
+
* getDeviceType: () => 'web',
|
|
1342
|
+
* getNetworkType: () => navigator.connection?.effectiveType === '4g' ? '4g' : 'wifi',
|
|
1343
|
+
* getGeoLocation: () => 'Ho Chi Minh City, Vietnam',
|
|
1344
|
+
* getPositionIndex: () => currentIndex,
|
|
1345
|
+
* },
|
|
1346
|
+
* transform: async (event, ctx) => ({
|
|
1347
|
+
* event_id: crypto.randomUUID(),
|
|
1348
|
+
* user_id: event.userId,
|
|
1349
|
+
* video_id: event.videoId,
|
|
1350
|
+
* session_id: await ctx.getSessionId(),
|
|
1351
|
+
* event_type: event.sdkEventType,
|
|
1352
|
+
* // ... more fields
|
|
1353
|
+
* }),
|
|
1354
|
+
* };
|
|
1355
|
+
* ```
|
|
1356
|
+
*/
|
|
1357
|
+
interface BatchAnalyticsConfig {
|
|
1358
|
+
/**
|
|
1359
|
+
* Batch size threshold for auto-flush
|
|
1360
|
+
* @default 10
|
|
1361
|
+
*/
|
|
1362
|
+
batchSize?: number;
|
|
1363
|
+
/**
|
|
1364
|
+
* Flush interval in milliseconds
|
|
1365
|
+
* @default 30000 (30 seconds)
|
|
1366
|
+
*/
|
|
1367
|
+
flushInterval?: number;
|
|
1368
|
+
/**
|
|
1369
|
+
* Context providers for enriching events
|
|
1370
|
+
* Required if using custom transform
|
|
1371
|
+
*/
|
|
1372
|
+
context?: BatchAnalyticsContext;
|
|
1373
|
+
/**
|
|
1374
|
+
* Custom transform function
|
|
1375
|
+
* If not provided, uses default SDK format
|
|
1376
|
+
*/
|
|
1377
|
+
transform?: BatchAnalyticsEventTransformer;
|
|
1378
|
+
/**
|
|
1379
|
+
* Map SDK event types to API event types
|
|
1380
|
+
* Used by default transform if no custom transform provided
|
|
1381
|
+
*
|
|
1382
|
+
* @example
|
|
1383
|
+
* ```typescript
|
|
1384
|
+
* eventTypeMap: {
|
|
1385
|
+
* 'video_view': 'view_start',
|
|
1386
|
+
* 'video_complete': 'view_end',
|
|
1387
|
+
* 'scroll': 'scroll_pass',
|
|
1388
|
+
* 'like': 'like',
|
|
1389
|
+
* 'follow': 'follow_creator',
|
|
1390
|
+
* }
|
|
1391
|
+
* ```
|
|
1392
|
+
*/
|
|
1393
|
+
eventTypeMap?: Record<string, BatchAnalyticsEventType>;
|
|
1394
|
+
/**
|
|
1395
|
+
* Use sendBeacon API for flushing events
|
|
1396
|
+
*
|
|
1397
|
+
* sendBeacon is more reliable for page unload events but shows as "ping" in Network tab.
|
|
1398
|
+
* Set to false to always use HTTP POST (easier for debugging).
|
|
1399
|
+
*
|
|
1400
|
+
* @default true
|
|
1401
|
+
*/
|
|
1402
|
+
useSendBeacon?: boolean;
|
|
1403
|
+
}
|
|
1146
1404
|
/**
|
|
1147
1405
|
* View event data passed to transformer
|
|
1148
1406
|
*/
|
|
@@ -1238,6 +1496,30 @@ interface RESTPresetConfig {
|
|
|
1238
1496
|
* Only used if endpoints.viewTracking is configured
|
|
1239
1497
|
*/
|
|
1240
1498
|
viewTracking?: ViewTrackingConfig;
|
|
1499
|
+
/**
|
|
1500
|
+
* Batch analytics configuration (optional)
|
|
1501
|
+
* Only used if endpoints.analytics is configured
|
|
1502
|
+
*
|
|
1503
|
+
* @example
|
|
1504
|
+
* ```typescript
|
|
1505
|
+
* batchAnalytics: {
|
|
1506
|
+
* batchSize: 10,
|
|
1507
|
+
* flushInterval: 30000,
|
|
1508
|
+
* context: {
|
|
1509
|
+
* getSessionId: () => sessionStorage.getItem('session_id'),
|
|
1510
|
+
* getDeviceType: () => 'web',
|
|
1511
|
+
* getNetworkType: () => 'wifi',
|
|
1512
|
+
* },
|
|
1513
|
+
* transform: (event, ctx) => ({
|
|
1514
|
+
* event_id: crypto.randomUUID(),
|
|
1515
|
+
* user_id: event.userId,
|
|
1516
|
+
* video_id: event.videoId,
|
|
1517
|
+
* // ... custom format
|
|
1518
|
+
* }),
|
|
1519
|
+
* }
|
|
1520
|
+
* ```
|
|
1521
|
+
*/
|
|
1522
|
+
batchAnalytics?: BatchAnalyticsConfig;
|
|
1241
1523
|
/**
|
|
1242
1524
|
* Logger adapter for error/warning logging
|
|
1243
1525
|
* If not provided, uses console in dev, silent in prod
|
|
@@ -1251,6 +1533,8 @@ interface PresetAdapters {
|
|
|
1251
1533
|
dataSource: IDataSource;
|
|
1252
1534
|
interaction: IInteraction;
|
|
1253
1535
|
analytics: IAnalytics;
|
|
1536
|
+
/** Playlist adapter (optional) */
|
|
1537
|
+
playlist?: IPlaylistDataSource;
|
|
1254
1538
|
/** Comment adapter (only if comment endpoints are configured) */
|
|
1255
1539
|
comment?: ICommentAdapter;
|
|
1256
1540
|
}
|
|
@@ -1520,6 +1804,13 @@ declare class LocalStorageAdapter implements IStorage {
|
|
|
1520
1804
|
* Clear all SDK-namespaced keys
|
|
1521
1805
|
*/
|
|
1522
1806
|
clear(): Promise<void>;
|
|
1807
|
+
/**
|
|
1808
|
+
* Get a value from localStorage synchronously
|
|
1809
|
+
*
|
|
1810
|
+
* Used for zero-flash cache hydration during React render phase.
|
|
1811
|
+
* localStorage is inherently synchronous, so this bypasses the async wrapper.
|
|
1812
|
+
*/
|
|
1813
|
+
getSync<T>(key: string): T | null;
|
|
1523
1814
|
/**
|
|
1524
1815
|
* Get all SDK-namespaced keys
|
|
1525
1816
|
*/
|
|
@@ -1718,6 +2009,8 @@ interface FullPresetAdapters {
|
|
|
1718
2009
|
videoLoader: IVideoLoader;
|
|
1719
2010
|
/** Poster preloader (Image) */
|
|
1720
2011
|
posterLoader: IPosterLoader;
|
|
2012
|
+
/** Playlist adapter (REST API, optional) */
|
|
2013
|
+
playlist?: IPlaylistDataSource;
|
|
1721
2014
|
/** Comment adapter (REST API, only if comment endpoints configured) */
|
|
1722
2015
|
comment?: ICommentAdapter;
|
|
1723
2016
|
/** Logger (passed through) */
|
|
@@ -1812,6 +2105,10 @@ declare class HttpClient {
|
|
|
1812
2105
|
private readonly config;
|
|
1813
2106
|
private readonly retryConfig;
|
|
1814
2107
|
private readonly requestConfig;
|
|
2108
|
+
/**
|
|
2109
|
+
* Get base URL (for sendBeacon which needs full URL)
|
|
2110
|
+
*/
|
|
2111
|
+
getBaseUrl(): string;
|
|
1815
2112
|
private isRefreshing;
|
|
1816
2113
|
private refreshPromise;
|
|
1817
2114
|
constructor(config: HttpClientConfig);
|
|
@@ -1905,12 +2202,17 @@ declare function defaultFeedResponseTransform(apiResponse: unknown, fieldMap?: F
|
|
|
1905
2202
|
* Create transforms with custom overrides
|
|
1906
2203
|
*/
|
|
1907
2204
|
interface ResolvedTransforms {
|
|
2205
|
+
/** Map raw API item to ContentItem (Video or Article) */
|
|
2206
|
+
contentItem: (data: unknown) => ContentItem;
|
|
2207
|
+
/** @deprecated Use contentItem instead */
|
|
1908
2208
|
videoItem: (data: unknown) => VideoItem;
|
|
1909
2209
|
feedResponse: (data: unknown) => {
|
|
1910
2210
|
items: unknown[];
|
|
1911
2211
|
nextCursor: string | null;
|
|
1912
2212
|
hasMore: boolean;
|
|
1913
2213
|
};
|
|
2214
|
+
playlist: (data: unknown) => PlaylistData;
|
|
2215
|
+
playlistCollection: (data: unknown) => PlaylistCollectionResponse;
|
|
1914
2216
|
}
|
|
1915
2217
|
declare function createTransforms(config?: TransformConfig, logger?: ILogger): ResolvedTransforms;
|
|
1916
2218
|
|
|
@@ -1918,8 +2220,8 @@ declare function createTransforms(config?: TransformConfig, logger?: ILogger): R
|
|
|
1918
2220
|
* REST Data Adapter - IDataSource implementation for REST APIs
|
|
1919
2221
|
*
|
|
1920
2222
|
* Implements:
|
|
1921
|
-
* - fetchFeed: GET /
|
|
1922
|
-
* -
|
|
2223
|
+
* - fetchFeed: GET /items with pagination
|
|
2224
|
+
* - getContentDetail: GET /items/:id
|
|
1923
2225
|
* - prefetch: Optional prefetch support
|
|
1924
2226
|
*/
|
|
1925
2227
|
|
|
@@ -1948,11 +2250,15 @@ declare class RESTDataAdapter implements IDataSource {
|
|
|
1948
2250
|
*/
|
|
1949
2251
|
fetchFeed(cursor?: string): Promise<FeedResponse>;
|
|
1950
2252
|
/**
|
|
1951
|
-
* Get
|
|
2253
|
+
* Get content detail by ID
|
|
2254
|
+
*/
|
|
2255
|
+
getContentDetail(id: string): Promise<ContentItem>;
|
|
2256
|
+
/**
|
|
2257
|
+
* @deprecated Use getContentDetail instead
|
|
1952
2258
|
*/
|
|
1953
2259
|
getVideoDetail(id: string): Promise<VideoItem>;
|
|
1954
2260
|
/**
|
|
1955
|
-
* Optional: Prefetch
|
|
2261
|
+
* Optional: Prefetch content
|
|
1956
2262
|
* This is a no-op by default, can be overridden if API supports batch fetch
|
|
1957
2263
|
*/
|
|
1958
2264
|
prefetch(ids: string[]): Promise<void>;
|
|
@@ -1961,9 +2267,9 @@ declare class RESTDataAdapter implements IDataSource {
|
|
|
1961
2267
|
*/
|
|
1962
2268
|
private unwrapResponse;
|
|
1963
2269
|
/**
|
|
1964
|
-
* Create fallback
|
|
2270
|
+
* Create fallback content item when transform fails
|
|
1965
2271
|
*/
|
|
1966
|
-
private
|
|
2272
|
+
private createFallbackItem;
|
|
1967
2273
|
}
|
|
1968
2274
|
|
|
1969
2275
|
/**
|
|
@@ -1976,6 +2282,14 @@ declare class RESTDataAdapter implements IDataSource {
|
|
|
1976
2282
|
* - share (optional)
|
|
1977
2283
|
*/
|
|
1978
2284
|
|
|
2285
|
+
/**
|
|
2286
|
+
* Report body input from SDK
|
|
2287
|
+
*/
|
|
2288
|
+
interface ReportBodyInput {
|
|
2289
|
+
contentId: string;
|
|
2290
|
+
reasonId: string;
|
|
2291
|
+
description?: string;
|
|
2292
|
+
}
|
|
1979
2293
|
/**
|
|
1980
2294
|
* REST Interaction Adapter configuration
|
|
1981
2295
|
*/
|
|
@@ -1983,6 +2297,10 @@ interface RESTInteractionAdapterConfig {
|
|
|
1983
2297
|
httpClient: HttpClient;
|
|
1984
2298
|
endpoints: RESTEndpointMap['interaction'];
|
|
1985
2299
|
logger?: ILogger;
|
|
2300
|
+
/** Custom transform for report reasons response */
|
|
2301
|
+
transformReportReasons?: (apiResponse: unknown) => ReportReasonItem[];
|
|
2302
|
+
/** Custom transform for report request body */
|
|
2303
|
+
transformReportBody?: (input: ReportBodyInput) => Record<string, unknown>;
|
|
1986
2304
|
}
|
|
1987
2305
|
/**
|
|
1988
2306
|
* REST Interaction Adapter
|
|
@@ -1991,6 +2309,8 @@ declare class RESTInteractionAdapter implements IInteraction {
|
|
|
1991
2309
|
private readonly httpClient;
|
|
1992
2310
|
private readonly endpoints;
|
|
1993
2311
|
private readonly logger?;
|
|
2312
|
+
private readonly customTransformReportReasons?;
|
|
2313
|
+
private readonly customTransformReportBody?;
|
|
1994
2314
|
constructor(config: RESTInteractionAdapterConfig);
|
|
1995
2315
|
/**
|
|
1996
2316
|
* Like a video
|
|
@@ -2028,6 +2348,38 @@ declare class RESTInteractionAdapter implements IInteraction {
|
|
|
2028
2348
|
* Share a video (optional tracking)
|
|
2029
2349
|
*/
|
|
2030
2350
|
share(videoId: string, platform?: string): Promise<void>;
|
|
2351
|
+
/**
|
|
2352
|
+
* Report content (video or image post)
|
|
2353
|
+
*
|
|
2354
|
+
* @param contentId - ID of the content to report
|
|
2355
|
+
* @param reason - Report reason code/ID
|
|
2356
|
+
* @param description - Optional additional description
|
|
2357
|
+
*/
|
|
2358
|
+
report(contentId: string, reason: string, description?: string): Promise<void>;
|
|
2359
|
+
/**
|
|
2360
|
+
* Get available report reasons
|
|
2361
|
+
*
|
|
2362
|
+
* @returns Array of report reasons, or empty array if not configured
|
|
2363
|
+
*/
|
|
2364
|
+
getReportReasons(): Promise<ReportReason[]>;
|
|
2365
|
+
/**
|
|
2366
|
+
* Mark content as "not interested"
|
|
2367
|
+
*
|
|
2368
|
+
* Used for recommendation algorithm feedback.
|
|
2369
|
+
* Content should be hidden from feed after this action.
|
|
2370
|
+
*
|
|
2371
|
+
* @param contentId - ID of the content (video or image post)
|
|
2372
|
+
*/
|
|
2373
|
+
notInterested(contentId: string): Promise<void>;
|
|
2374
|
+
/**
|
|
2375
|
+
* Default transform for API report reasons response to ReportReason[]
|
|
2376
|
+
*
|
|
2377
|
+
* Expected format: [{ id, label, description }]
|
|
2378
|
+
* Or wrapped: { data: [{ id, label, description }] }
|
|
2379
|
+
*
|
|
2380
|
+
* For custom API formats, use `transforms.reportReasons` in preset config.
|
|
2381
|
+
*/
|
|
2382
|
+
private transformReportReasons;
|
|
2031
2383
|
/**
|
|
2032
2384
|
* Transform API comment response to Comment type
|
|
2033
2385
|
*/
|
|
@@ -2045,6 +2397,34 @@ declare class RESTInteractionAdapter implements IInteraction {
|
|
|
2045
2397
|
* - Events queued internally
|
|
2046
2398
|
* - Flush conditions: queue > 10, video change, visibility change
|
|
2047
2399
|
* - Uses sendBeacon for reliability when available
|
|
2400
|
+
*
|
|
2401
|
+
* Supports custom transform for flexible API formats:
|
|
2402
|
+
* - Default: SDK format { events: [...] }
|
|
2403
|
+
* - Custom: Any format via transform function
|
|
2404
|
+
*
|
|
2405
|
+
* @example
|
|
2406
|
+
* ```typescript
|
|
2407
|
+
* // With custom transform for specific API format
|
|
2408
|
+
* const adapter = new RESTAnalyticsAdapter({
|
|
2409
|
+
* httpClient,
|
|
2410
|
+
* endpoints: { batch: '/api/v1/events/track-batch' },
|
|
2411
|
+
* config: {
|
|
2412
|
+
* context: {
|
|
2413
|
+
* getSessionId: () => sessionStorage.getItem('session_id'),
|
|
2414
|
+
* getDeviceType: () => 'web',
|
|
2415
|
+
* getNetworkType: () => 'wifi',
|
|
2416
|
+
* },
|
|
2417
|
+
* transform: async (event, ctx) => ({
|
|
2418
|
+
* event_id: crypto.randomUUID(),
|
|
2419
|
+
* user_id: event.userId,
|
|
2420
|
+
* video_id: event.videoId,
|
|
2421
|
+
* session_id: await ctx.getSessionId(),
|
|
2422
|
+
* event_type: event.sdkEventType,
|
|
2423
|
+
* // ... more fields
|
|
2424
|
+
* }),
|
|
2425
|
+
* },
|
|
2426
|
+
* });
|
|
2427
|
+
* ```
|
|
2048
2428
|
*/
|
|
2049
2429
|
|
|
2050
2430
|
/**
|
|
@@ -2053,22 +2433,35 @@ declare class RESTInteractionAdapter implements IInteraction {
|
|
|
2053
2433
|
interface RESTAnalyticsAdapterConfig {
|
|
2054
2434
|
httpClient: HttpClient;
|
|
2055
2435
|
endpoints: NonNullable<RESTEndpointMap['analytics']>;
|
|
2436
|
+
/** Batch analytics config with transform and context */
|
|
2437
|
+
config?: BatchAnalyticsConfig;
|
|
2438
|
+
/** @deprecated Use config.batchSize instead */
|
|
2056
2439
|
batchSize?: number;
|
|
2440
|
+
/** @deprecated Use config.flushInterval instead */
|
|
2057
2441
|
flushInterval?: number;
|
|
2058
2442
|
logger?: ILogger;
|
|
2059
2443
|
}
|
|
2060
2444
|
/**
|
|
2061
2445
|
* REST Analytics Adapter
|
|
2446
|
+
*
|
|
2447
|
+
* Supports two modes:
|
|
2448
|
+
* 1. Default mode: Uses SDK format { events: [...] }
|
|
2449
|
+
* 2. Custom mode: Uses transform function for custom API format
|
|
2062
2450
|
*/
|
|
2063
2451
|
declare class RESTAnalyticsAdapter implements IAnalytics {
|
|
2064
2452
|
private readonly httpClient;
|
|
2065
2453
|
private readonly endpoint;
|
|
2066
2454
|
private readonly batchSize;
|
|
2067
2455
|
private readonly logger?;
|
|
2456
|
+
private readonly transform?;
|
|
2457
|
+
private readonly context;
|
|
2458
|
+
private readonly eventTypeMap;
|
|
2459
|
+
private readonly useSendBeacon;
|
|
2068
2460
|
private queue;
|
|
2069
2461
|
private flushTimer;
|
|
2070
2462
|
private userId;
|
|
2071
2463
|
private userProperties;
|
|
2464
|
+
private viewedVideos;
|
|
2072
2465
|
constructor(config: RESTAnalyticsAdapterConfig);
|
|
2073
2466
|
/**
|
|
2074
2467
|
* Track an analytics event
|
|
@@ -2080,9 +2473,23 @@ declare class RESTAnalyticsAdapter implements IAnalytics {
|
|
|
2080
2473
|
*/
|
|
2081
2474
|
flush(): Promise<void>;
|
|
2082
2475
|
/**
|
|
2083
|
-
*
|
|
2476
|
+
* Build request body from events
|
|
2477
|
+
* Uses custom transform if provided, otherwise SDK default format
|
|
2478
|
+
*/
|
|
2479
|
+
private buildRequestBody;
|
|
2480
|
+
/**
|
|
2481
|
+
* Track video view duration
|
|
2482
|
+
*
|
|
2483
|
+
* Note: PlayerEngine calls this every second (heartbeat), but for batch analytics
|
|
2484
|
+
* we only need ONE view_start per video. This method deduplicates by videoId.
|
|
2485
|
+
*
|
|
2486
|
+
* If you need heartbeat tracking, use RESTViewTrackingAdapter instead.
|
|
2084
2487
|
*/
|
|
2085
2488
|
trackViewDuration(videoId: string, duration: number, totalDuration: number): void;
|
|
2489
|
+
/**
|
|
2490
|
+
* Clear viewed videos cache (useful for testing or session reset)
|
|
2491
|
+
*/
|
|
2492
|
+
clearViewedVideos(): void;
|
|
2086
2493
|
/**
|
|
2087
2494
|
* Track video completion
|
|
2088
2495
|
*/
|
|
@@ -2101,12 +2508,23 @@ declare class RESTAnalyticsAdapter implements IAnalytics {
|
|
|
2101
2508
|
destroy(): void;
|
|
2102
2509
|
/**
|
|
2103
2510
|
* Try to send via sendBeacon (for reliability on page unload)
|
|
2511
|
+
* Note: sendBeacon shows as "ping" type in Network tab, not "POST"
|
|
2512
|
+
*
|
|
2513
|
+
* Set useSendBeacon: false in config to always use HTTP POST
|
|
2104
2514
|
*/
|
|
2105
2515
|
private trySendBeacon;
|
|
2106
2516
|
/**
|
|
2107
2517
|
* Build full URL for sendBeacon
|
|
2108
2518
|
*/
|
|
2109
2519
|
private buildFullUrl;
|
|
2520
|
+
/**
|
|
2521
|
+
* Get mapped API event type from SDK event type
|
|
2522
|
+
*/
|
|
2523
|
+
getApiEventType(sdkEventType: string): BatchAnalyticsEventType;
|
|
2524
|
+
/**
|
|
2525
|
+
* Get current context (for debugging/testing)
|
|
2526
|
+
*/
|
|
2527
|
+
getContext(): BatchAnalyticsContext;
|
|
2110
2528
|
}
|
|
2111
2529
|
/**
|
|
2112
2530
|
* Create a no-op analytics adapter
|
|
@@ -2114,6 +2532,109 @@ declare class RESTAnalyticsAdapter implements IAnalytics {
|
|
|
2114
2532
|
*/
|
|
2115
2533
|
declare function createNoOpAnalyticsAdapter(): IAnalytics;
|
|
2116
2534
|
|
|
2535
|
+
/**
|
|
2536
|
+
* REST View Tracking Adapter - Per-video view tracking via REST API
|
|
2537
|
+
*
|
|
2538
|
+
* Implements IAnalytics interface with throttled, fire-and-forget tracking.
|
|
2539
|
+
* Uses shared HttpClient from preset (auth, retry, timeout).
|
|
2540
|
+
*
|
|
2541
|
+
* @example
|
|
2542
|
+
* ```typescript
|
|
2543
|
+
* // Created automatically by createRESTAdapters when viewTracking is configured
|
|
2544
|
+
* const adapters = createRESTAdapters({
|
|
2545
|
+
* baseUrl: 'https://api.myapp.com/v1',
|
|
2546
|
+
* auth: { ... },
|
|
2547
|
+
* endpoints: {
|
|
2548
|
+
* feed: { ... },
|
|
2549
|
+
* interaction: { ... },
|
|
2550
|
+
* viewTracking: {
|
|
2551
|
+
* notify: '/reels/:id/notify-views',
|
|
2552
|
+
* },
|
|
2553
|
+
* },
|
|
2554
|
+
* });
|
|
2555
|
+
* ```
|
|
2556
|
+
*/
|
|
2557
|
+
|
|
2558
|
+
/**
|
|
2559
|
+
* REST View Tracking Adapter configuration
|
|
2560
|
+
*/
|
|
2561
|
+
interface RESTViewTrackingAdapterConfig {
|
|
2562
|
+
httpClient: HttpClient;
|
|
2563
|
+
endpoint: NonNullable<RESTEndpointMap['viewTracking']>;
|
|
2564
|
+
config?: ViewTrackingConfig;
|
|
2565
|
+
logger?: ILogger;
|
|
2566
|
+
}
|
|
2567
|
+
/**
|
|
2568
|
+
* RESTViewTrackingAdapter - Per-video view tracking via REST API
|
|
2569
|
+
*
|
|
2570
|
+
* Uses shared HttpClient (inherits auth, retry, timeout from preset).
|
|
2571
|
+
* Implements throttled, fire-and-forget tracking.
|
|
2572
|
+
*/
|
|
2573
|
+
declare class RESTViewTrackingAdapter implements IAnalytics {
|
|
2574
|
+
private readonly httpClient;
|
|
2575
|
+
private readonly endpoint;
|
|
2576
|
+
private readonly transform;
|
|
2577
|
+
private readonly viewEventValue;
|
|
2578
|
+
private readonly heartbeatInterval;
|
|
2579
|
+
private readonly minWatchTime;
|
|
2580
|
+
private readonly trackLeaveEnabled;
|
|
2581
|
+
private readonly logger?;
|
|
2582
|
+
private lastTrackTime;
|
|
2583
|
+
private lastEventType;
|
|
2584
|
+
private _userId;
|
|
2585
|
+
private _userProperties;
|
|
2586
|
+
/** Get current user ID */
|
|
2587
|
+
get userId(): string | null;
|
|
2588
|
+
/** Get current user properties */
|
|
2589
|
+
get userProperties(): Record<string, unknown>;
|
|
2590
|
+
constructor(config: RESTViewTrackingAdapterConfig);
|
|
2591
|
+
/**
|
|
2592
|
+
* Track generic event
|
|
2593
|
+
* Delegates video events to specific handlers
|
|
2594
|
+
*/
|
|
2595
|
+
track(event: AnalyticsEvent): void;
|
|
2596
|
+
/**
|
|
2597
|
+
* Flush - No-op since we send events immediately (fire-and-forget)
|
|
2598
|
+
*/
|
|
2599
|
+
flush(): Promise<void>;
|
|
2600
|
+
/**
|
|
2601
|
+
* Track view duration (heartbeat)
|
|
2602
|
+
* Called periodically during video playback
|
|
2603
|
+
*/
|
|
2604
|
+
trackViewDuration(videoId: string, duration: number, totalDuration: number): void;
|
|
2605
|
+
/**
|
|
2606
|
+
* Track video completion
|
|
2607
|
+
* Called when video ends or loops
|
|
2608
|
+
*/
|
|
2609
|
+
trackCompletion(videoId: string, watchTime: number, loopCount: number): void;
|
|
2610
|
+
/**
|
|
2611
|
+
* Set user context
|
|
2612
|
+
*/
|
|
2613
|
+
setUser(userId: string | null, properties?: Record<string, unknown>): void;
|
|
2614
|
+
/**
|
|
2615
|
+
* Get queue size (always 0 - no batching)
|
|
2616
|
+
*/
|
|
2617
|
+
getQueueSize(): number;
|
|
2618
|
+
/**
|
|
2619
|
+
* Track when user leaves video
|
|
2620
|
+
* Called when user scrolls to another video
|
|
2621
|
+
*/
|
|
2622
|
+
trackLeaveVideo(videoId: string, currentTime: number, duration: number): void;
|
|
2623
|
+
/**
|
|
2624
|
+
* Clear tracking state for a video
|
|
2625
|
+
* Call when video is removed from viewport
|
|
2626
|
+
*/
|
|
2627
|
+
clearVideoState(videoId: string): void;
|
|
2628
|
+
/**
|
|
2629
|
+
* Clear all tracking state
|
|
2630
|
+
*/
|
|
2631
|
+
reset(): void;
|
|
2632
|
+
/**
|
|
2633
|
+
* Send view event to API (fire-and-forget)
|
|
2634
|
+
*/
|
|
2635
|
+
private sendViewEvent;
|
|
2636
|
+
}
|
|
2637
|
+
|
|
2117
2638
|
/**
|
|
2118
2639
|
* REST Comment Adapter - ICommentAdapter implementation for REST APIs
|
|
2119
2640
|
*
|
|
@@ -2228,4 +2749,4 @@ declare class RESTCommentAdapter implements ICommentAdapter {
|
|
|
2228
2749
|
private unwrapResponse;
|
|
2229
2750
|
}
|
|
2230
2751
|
|
|
2231
|
-
export { type AuthConfig, type AuthError, type BrowserAdaptersConfig, BrowserPosterLoader, BrowserVideoLoader, type BrowserVideoLoaderConfig, DEFAULT_REQUEST_CONFIG, DEFAULT_RETRY_CONFIG, type FieldMapConfig, type FullPresetAdapters, HttpClient, HttpError, LocalSessionStorageAdapter, LocalStorageAdapter, type LocalStorageConfig, MockAnalyticsAdapter, type MockAnalyticsAdapterOptions, MockCommentAdapter, MockDataAdapter, type MockDataAdapterOptions, MockInteractionAdapter, type MockInteractionAdapterOptions, MockLoggerAdapter, type MockLoggerAdapterOptions, MockNetworkAdapter, type MockNetworkAdapterOptions, MockPosterLoader, MockSessionStorageAdapter, type MockSessionStorageAdapterOptions, MockStorageAdapter, type MockStorageAdapterOptions, MockVideoLoader, type MockVideoLoaderOptions, type PresetAdapters, RESTAnalyticsAdapter, RESTCommentAdapter, type RESTCommentAdapterConfig, RESTDataAdapter, type RESTEndpointMap, RESTInteractionAdapter, type RESTPresetConfig, type RESTRequestConfig, type ResolvedTransforms, type RetryConfig, type TransformConfig, WebNetworkAdapter, type WebNetworkConfig, createBrowserAdapters, createBrowserPosterLoader, createBrowserVideoLoader, createLocalStorageAdapter, createNoOpAnalyticsAdapter, createRESTAdapters, createSessionStorageAdapter, createTransforms, createWebNetworkAdapter, defaultFeedResponseTransform, defaultVideoItemTransform };
|
|
2752
|
+
export { type AuthConfig, type AuthError, type BatchAnalyticsConfig, type BatchAnalyticsContext, type BatchAnalyticsDeviceType, type BatchAnalyticsEventData, type BatchAnalyticsEventTransformer, type BatchAnalyticsEventType, type BatchAnalyticsNetworkType, type BatchAnalyticsRequestBody, type BatchAnalyticsRequestEvent, type BrowserAdaptersConfig, BrowserPosterLoader, BrowserVideoLoader, type BrowserVideoLoaderConfig, DEFAULT_REQUEST_CONFIG, DEFAULT_RETRY_CONFIG, type FieldMapConfig, type FullPresetAdapters, HttpClient, HttpError, LocalSessionStorageAdapter, LocalStorageAdapter, type LocalStorageConfig, MockAnalyticsAdapter, type MockAnalyticsAdapterOptions, MockCommentAdapter, MockDataAdapter, type MockDataAdapterOptions, MockInteractionAdapter, type MockInteractionAdapterOptions, MockLoggerAdapter, type MockLoggerAdapterOptions, MockNetworkAdapter, type MockNetworkAdapterOptions, MockPlaylistAdapter, MockPosterLoader, MockSessionStorageAdapter, type MockSessionStorageAdapterOptions, MockStorageAdapter, type MockStorageAdapterOptions, MockVideoLoader, type MockVideoLoaderOptions, type PresetAdapters, RESTAnalyticsAdapter, type RESTAnalyticsAdapterConfig, RESTCommentAdapter, type RESTCommentAdapterConfig, RESTDataAdapter, type RESTEndpointMap, RESTInteractionAdapter, type RESTPresetConfig, type RESTRequestConfig, RESTViewTrackingAdapter, type RESTViewTrackingAdapterConfig, type ResolvedTransforms, type RetryConfig, type TransformConfig, type ViewEventData, type ViewEventRequestBody, type ViewEventTransformer, type ViewTrackingConfig, WebNetworkAdapter, type WebNetworkConfig, createBrowserAdapters, createBrowserPosterLoader, createBrowserVideoLoader, createLocalStorageAdapter, createNoOpAnalyticsAdapter, createRESTAdapters, createSessionStorageAdapter, createTransforms, createWebNetworkAdapter, defaultFeedResponseTransform, defaultVideoItemTransform };
|