@lobu/connector-sdk 6.1.1 → 7.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/dist/browser/acquire.d.ts +7 -0
- package/dist/browser/acquire.d.ts.map +1 -1
- package/dist/browser/acquire.js +68 -16
- package/dist/browser/acquire.js.map +1 -1
- package/dist/browser/cdp-page.d.ts.map +1 -1
- package/dist/browser/cdp-page.js +111 -29
- package/dist/browser/cdp-page.js.map +1 -1
- package/dist/browser/cdp.d.ts.map +1 -1
- package/dist/browser/cdp.js +10 -7
- package/dist/browser/cdp.js.map +1 -1
- package/dist/browser/devtools-active-port.d.ts +20 -0
- package/dist/browser/devtools-active-port.d.ts.map +1 -0
- package/dist/browser/devtools-active-port.js +46 -0
- package/dist/browser/devtools-active-port.js.map +1 -0
- package/dist/browser/launcher.d.ts +1 -2
- package/dist/browser/launcher.d.ts.map +1 -1
- package/dist/browser/launcher.js +12 -9
- package/dist/browser/launcher.js.map +1 -1
- package/dist/browser/mirror-cookies.d.ts +64 -0
- package/dist/browser/mirror-cookies.d.ts.map +1 -0
- package/dist/browser/mirror-cookies.js +293 -0
- package/dist/browser/mirror-cookies.js.map +1 -0
- package/dist/browser-network.d.ts +6 -0
- package/dist/browser-network.d.ts.map +1 -1
- package/dist/browser-network.js +106 -35
- package/dist/browser-network.js.map +1 -1
- package/dist/connector-types.d.ts +32 -0
- package/dist/connector-types.d.ts.map +1 -1
- package/dist/connector-types.js.map +1 -1
- package/dist/index.d.ts +2 -10
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -6
- package/dist/index.js.map +1 -1
- package/dist/retry.d.ts.map +1 -1
- package/dist/retry.js +59 -86
- package/dist/retry.js.map +1 -1
- package/dist/types.d.ts +0 -134
- package/dist/types.d.ts.map +1 -1
- package/package.json +19 -3
- package/dist/api-paginated.d.ts +0 -79
- package/dist/api-paginated.d.ts.map +0 -1
- package/dist/api-paginated.js +0 -120
- package/dist/api-paginated.js.map +0 -1
- package/dist/base.d.ts +0 -65
- package/dist/base.d.ts.map +0 -1
- package/dist/base.js +0 -122
- package/dist/base.js.map +0 -1
- package/dist/browser-paginated.d.ts +0 -141
- package/dist/browser-paginated.d.ts.map +0 -1
- package/dist/browser-paginated.js +0 -269
- package/dist/browser-paginated.js.map +0 -1
- package/dist/http.d.ts +0 -18
- package/dist/http.d.ts.map +0 -1
- package/dist/http.js +0 -74
- package/dist/http.js.map +0 -1
- package/dist/paginated.d.ts +0 -93
- package/dist/paginated.d.ts.map +0 -1
- package/dist/paginated.js +0 -167
- package/dist/paginated.js.map +0 -1
package/dist/paginated.js
DELETED
|
@@ -1,167 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Paginated Feed Base Class
|
|
3
|
-
*
|
|
4
|
-
* Provides a reusable pagination pattern for feeds that fetch data in pages.
|
|
5
|
-
* Uses the template method pattern - subclasses implement specific methods while
|
|
6
|
-
* the base class handles the pagination loop, rate limiting, and checkpoint management.
|
|
7
|
-
*/
|
|
8
|
-
import { BaseFeed, RateLimitError } from './base.js';
|
|
9
|
-
import { sdkLogger } from './logger.js';
|
|
10
|
-
/**
|
|
11
|
-
* Base class for feeds with cursor/page-based pagination
|
|
12
|
-
*/
|
|
13
|
-
export class PaginatedFeed extends BaseFeed {
|
|
14
|
-
/**
|
|
15
|
-
* Default pagination configuration
|
|
16
|
-
*/
|
|
17
|
-
getPaginationConfig() {
|
|
18
|
-
return {
|
|
19
|
-
maxPages: 50,
|
|
20
|
-
pageSize: 100,
|
|
21
|
-
rateLimitMs: 1000,
|
|
22
|
-
incrementalCheckpoint: false,
|
|
23
|
-
};
|
|
24
|
-
}
|
|
25
|
-
/**
|
|
26
|
-
* OPTIONAL: Filter items before transformation
|
|
27
|
-
*/
|
|
28
|
-
filterItem(_item, _options) {
|
|
29
|
-
return true;
|
|
30
|
-
}
|
|
31
|
-
/**
|
|
32
|
-
* OPTIONAL: Extract parent ID for hierarchical content
|
|
33
|
-
*/
|
|
34
|
-
getParentId(_item) {
|
|
35
|
-
return null;
|
|
36
|
-
}
|
|
37
|
-
/**
|
|
38
|
-
* OPTIONAL: Extract pagination token from checkpoint
|
|
39
|
-
*/
|
|
40
|
-
getPaginationToken(checkpoint) {
|
|
41
|
-
return checkpoint?.pagination_token ?? null;
|
|
42
|
-
}
|
|
43
|
-
/**
|
|
44
|
-
* OPTIONAL: Create checkpoint with feed-specific fields
|
|
45
|
-
*/
|
|
46
|
-
createCheckpoint(existing, latestContent, nextToken, itemsProcessed) {
|
|
47
|
-
return {
|
|
48
|
-
updated_at: new Date(),
|
|
49
|
-
last_timestamp: latestContent?.occurred_at ?? existing?.last_timestamp,
|
|
50
|
-
pagination_token: nextToken,
|
|
51
|
-
total_items_processed: (existing?.total_items_processed || 0) + itemsProcessed,
|
|
52
|
-
initial_complete: existing?.initial_complete ?? false,
|
|
53
|
-
};
|
|
54
|
-
}
|
|
55
|
-
/**
|
|
56
|
-
* Main pagination loop - handles both initial and incremental syncs
|
|
57
|
-
*/
|
|
58
|
-
async paginate(options, checkpoint, env, updateCheckpointFn) {
|
|
59
|
-
const config = this.getPaginationConfig();
|
|
60
|
-
const existingToken = this.getPaginationToken(checkpoint);
|
|
61
|
-
const parentMap = new Map();
|
|
62
|
-
const initialComplete = checkpoint?.initial_complete ?? (!!checkpoint?.last_timestamp && !existingToken);
|
|
63
|
-
const isIncremental = initialComplete && !existingToken;
|
|
64
|
-
const lookbackDate = this.getLookbackDate(options);
|
|
65
|
-
const checkpointTimestamp = checkpoint?.last_timestamp ?? null;
|
|
66
|
-
const checkpointDate = checkpointTimestamp
|
|
67
|
-
? checkpointTimestamp instanceof Date
|
|
68
|
-
? checkpointTimestamp
|
|
69
|
-
: new Date(checkpointTimestamp)
|
|
70
|
-
: null;
|
|
71
|
-
const boundaryDate = initialComplete && checkpointDate ? checkpointDate : lookbackDate;
|
|
72
|
-
const allContents = [];
|
|
73
|
-
let cursor = isIncremental ? null : existingToken;
|
|
74
|
-
let pageCount = 0;
|
|
75
|
-
let stopReason = null;
|
|
76
|
-
let rateLimitRetryMs;
|
|
77
|
-
const modeLabel = isIncremental ? 'incremental' : cursor ? 'resumed' : 'initial';
|
|
78
|
-
sdkLogger.info(`[${this.type}] Starting ${modeLabel} sync (max ${config.maxPages} pages)`);
|
|
79
|
-
while (pageCount < config.maxPages) {
|
|
80
|
-
if (pageCount > 0) {
|
|
81
|
-
await this.sleep(config.rateLimitMs);
|
|
82
|
-
}
|
|
83
|
-
let result;
|
|
84
|
-
try {
|
|
85
|
-
result = await this.fetchPage(cursor, options, env);
|
|
86
|
-
}
|
|
87
|
-
catch (error) {
|
|
88
|
-
if (error instanceof RateLimitError) {
|
|
89
|
-
sdkLogger.warn({ error: error.message }, `[${this.type}] Rate limit hit after ${pageCount} pages, pausing`);
|
|
90
|
-
stopReason = 'rate_limited';
|
|
91
|
-
rateLimitRetryMs = error.retryAfterMs;
|
|
92
|
-
break;
|
|
93
|
-
}
|
|
94
|
-
throw error;
|
|
95
|
-
}
|
|
96
|
-
const rawCount = result.rawCount ?? result.items.length;
|
|
97
|
-
if (result.items.length === 0) {
|
|
98
|
-
sdkLogger.info(`[${this.type}] Empty page at ${pageCount + 1}, stopping`);
|
|
99
|
-
stopReason = 'empty_page';
|
|
100
|
-
break;
|
|
101
|
-
}
|
|
102
|
-
const pageContents = [];
|
|
103
|
-
for (const item of result.items) {
|
|
104
|
-
if (!this.filterItem(item, options))
|
|
105
|
-
continue;
|
|
106
|
-
const content = this.transformItem(item, options);
|
|
107
|
-
pageContents.push(content);
|
|
108
|
-
const parentId = this.getParentId(item);
|
|
109
|
-
if (parentId) {
|
|
110
|
-
parentMap.set(content.origin_id, parentId);
|
|
111
|
-
if (!content.origin_parent_id) {
|
|
112
|
-
content.origin_parent_id = parentId;
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
const boundaryContents = pageContents.filter((c) => c.occurred_at >= boundaryDate);
|
|
117
|
-
allContents.push(...boundaryContents);
|
|
118
|
-
pageCount++;
|
|
119
|
-
sdkLogger.info(`[${this.type}] Page ${pageCount}: raw=${rawCount}, ` +
|
|
120
|
-
`filtered=${pageContents.length}, recent=${boundaryContents.length}, ` +
|
|
121
|
-
`nextToken=${result.nextToken ? 'yes' : 'no'}`);
|
|
122
|
-
if (config.incrementalCheckpoint && updateCheckpointFn && allContents.length > 0) {
|
|
123
|
-
const incrementalCP = this.createCheckpoint(checkpoint, allContents[0], result.nextToken, boundaryContents.length);
|
|
124
|
-
await updateCheckpointFn(incrementalCP);
|
|
125
|
-
sdkLogger.debug(`[${this.type}] Saved incremental checkpoint after page ${pageCount}`);
|
|
126
|
-
}
|
|
127
|
-
if (boundaryContents.length === 0 && pageContents.length > 0) {
|
|
128
|
-
sdkLogger.info(`[${this.type}] Reached boundary after ${pageCount} pages`);
|
|
129
|
-
stopReason = 'boundary';
|
|
130
|
-
break;
|
|
131
|
-
}
|
|
132
|
-
if (result.items.length < config.pageSize) {
|
|
133
|
-
sdkLogger.info(`[${this.type}] Partial page (${result.items.length}/${config.pageSize}), end reached`);
|
|
134
|
-
stopReason = 'partial_page';
|
|
135
|
-
break;
|
|
136
|
-
}
|
|
137
|
-
if (!result.nextToken) {
|
|
138
|
-
sdkLogger.info(`[${this.type}] No next token after page ${pageCount}, end reached`);
|
|
139
|
-
stopReason = 'no_next_token';
|
|
140
|
-
break;
|
|
141
|
-
}
|
|
142
|
-
cursor = result.nextToken;
|
|
143
|
-
}
|
|
144
|
-
if (!stopReason && pageCount >= config.maxPages) {
|
|
145
|
-
stopReason = 'max_pages';
|
|
146
|
-
}
|
|
147
|
-
if (stopReason === 'max_pages') {
|
|
148
|
-
sdkLogger.warn(`[${this.type}] Hit max page limit (${config.maxPages})`);
|
|
149
|
-
}
|
|
150
|
-
sdkLogger.info(`[${this.type}] Pagination complete: ${allContents.length} items from ${pageCount} pages`);
|
|
151
|
-
const resumeToken = stopReason === 'max_pages' || stopReason === 'rate_limited' ? cursor : null;
|
|
152
|
-
const shouldMarkComplete = initialComplete ||
|
|
153
|
-
(!initialComplete && stopReason !== 'max_pages' && stopReason !== 'rate_limited');
|
|
154
|
-
const nextSyncRecommendedAt = stopReason === 'rate_limited'
|
|
155
|
-
? new Date(Date.now() + (rateLimitRetryMs ?? config.rateLimitMs))
|
|
156
|
-
: undefined;
|
|
157
|
-
const finalCheckpoint = this.createCheckpoint(checkpoint, allContents[0] || null, resumeToken, allContents.length);
|
|
158
|
-
finalCheckpoint.initial_complete = shouldMarkComplete;
|
|
159
|
-
return {
|
|
160
|
-
contents: allContents,
|
|
161
|
-
checkpoint: finalCheckpoint,
|
|
162
|
-
parentMap: parentMap.size > 0 ? parentMap : undefined,
|
|
163
|
-
nextSyncRecommendedAt,
|
|
164
|
-
};
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
//# sourceMappingURL=paginated.js.map
|
package/dist/paginated.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"paginated.js","sourceRoot":"","sources":["../src/paginated.ts"],"names":[],"mappings":"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"}
|