@gscdump/engine 1.4.11 → 1.5.1
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/analysis-range.d.mts +7 -0
- package/dist/analysis-range.mjs +33 -0
- package/dist/entities/empty-types.d.mts +22 -0
- package/dist/entities/empty-types.mjs +58 -0
- package/dist/entities/indexing-metadata.d.mts +26 -0
- package/dist/entities/indexing-metadata.mjs +31 -0
- package/dist/entities/inspection.d.mts +240 -0
- package/dist/entities/inspection.mjs +443 -0
- package/dist/entities/io.mjs +16 -0
- package/dist/{query-dim.d.mts → entities/query-dim.d.mts} +3 -3
- package/dist/{query-dim.mjs → entities/query-dim.mjs} +4 -4
- package/dist/{sitemap-projection.mjs → entities/sitemap-projection.mjs} +1 -1
- package/dist/entities/sitemap-shared.d.mts +199 -0
- package/dist/entities/sitemap-shared.mjs +243 -0
- package/dist/entities/sitemap-write.d.mts +3 -0
- package/dist/entities/sitemap-write.mjs +528 -0
- package/dist/entities/sitemap.d.mts +3 -0
- package/dist/entities/sitemap.mjs +91 -0
- package/dist/entities.d.mts +9 -481
- package/dist/entities.mjs +7 -1380
- package/dist/rollups/canonical.d.mts +71 -0
- package/dist/rollups/canonical.mjs +335 -0
- package/dist/rollups/core.d.mts +201 -0
- package/dist/rollups/core.mjs +116 -0
- package/dist/rollups/dates.mjs +11 -0
- package/dist/rollups/defaults.d.mts +11 -0
- package/dist/rollups/defaults.mjs +17 -0
- package/dist/rollups/hourly.d.mts +38 -0
- package/dist/rollups/hourly.mjs +38 -0
- package/dist/rollups/indexing.d.mts +46 -0
- package/dist/rollups/indexing.mjs +357 -0
- package/dist/rollups/traffic.d.mts +38 -0
- package/dist/rollups/traffic.mjs +289 -0
- package/dist/rollups/windows.d.mts +90 -0
- package/dist/rollups/windows.mjs +176 -0
- package/dist/rollups.d.mts +8 -471
- package/dist/rollups.mjs +7 -1316
- package/package.json +9 -4
- /package/dist/{sitemap-projection.d.mts → entities/sitemap-projection.d.mts} +0 -0
package/dist/entities.d.mts
CHANGED
|
@@ -1,482 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { CreateEmptyTypesStoreOptions, EmptyTypesDoc, EmptyTypesStore, createEmptyTypesStore } from "./entities/empty-types.mjs";
|
|
2
|
+
import { CreateIndexingMetadataStoreOptions, IndexingMetadataIndex, IndexingMetadataRecord, IndexingMetadataStore, createIndexingMetadataStore } from "./entities/indexing-metadata.mjs";
|
|
3
|
+
import { CreateInspectionStoreOptions, INSPECTION_HISTORY_MAX_BYTES, InspectionEventRow, InspectionHistoryShard, InspectionIndex, InspectionParquetRow, InspectionRecord, InspectionStore, createInspectionStore } from "./entities/inspection.mjs";
|
|
3
4
|
import { SitemapGenerationKey, emptyTypesKey, hashSortedUrlList, hashUrl, hashUrlList, indexingMetadataIndexKey, inspectionBaseKey, inspectionEventKey, inspectionEventsPrefix, inspectionHistoryPrefix, inspectionHistoryShardKey, inspectionIndexKey, inspectionParquetKey, inspectionTransitionsMonthKey, inspectionTransitionsPrefix, parseSitemapUrlsDeltaKey, queryDimMetaKey, queryDimParquetKey, sitemapHistoryKey, sitemapIndexKey, sitemapUrlsDeltaKey, sitemapUrlsEventKey, sitemapUrlsEventSeedKey, sitemapUrlsEventsPrefix, sitemapUrlsGenerationKey, sitemapUrlsIndexKey, sitemapUrlsIndexPrefix, sitemapUrlsPendingGenerationKey, sitemapUrlsPendingGenerationsPrefix, sitemapUrlsPrefix, sitemapUrlsProjectionManifestKey, sitemapUrlsReconcileGenerationKey } from "./entity-keys.mjs";
|
|
4
|
-
import { QueryDimDeps, QueryDimMeta, QueryDimRecord, QueryDimStore, buildQueryDimRecords, createQueryDimStore } from "./query-dim.mjs";
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
* `searchconsole_v1.Schema$UrlInspectionResult` shape but as plain JSON
|
|
11
|
-
* so storage doesn't depend on the googleapis type tree.
|
|
12
|
-
*/
|
|
13
|
-
interface InspectionRecord {
|
|
14
|
-
url: string;
|
|
15
|
-
/** ISO-8601 timestamp of when we ran the inspection. */
|
|
16
|
-
inspectedAt: string;
|
|
17
|
-
/** PASS / NEUTRAL / FAIL — the headline verdict from indexStatusResult. */
|
|
18
|
-
indexStatus?: string;
|
|
19
|
-
/** Last-crawl timestamp the API reports (ISO-8601). */
|
|
20
|
-
lastCrawlTime?: string;
|
|
21
|
-
/** Canonical URL Google selected. */
|
|
22
|
-
googleCanonical?: string;
|
|
23
|
-
/** Canonical URL the page declares. */
|
|
24
|
-
userCanonical?: string;
|
|
25
|
-
/** Crawl/index/serving disposition strings as the API returns them. */
|
|
26
|
-
coverageState?: string;
|
|
27
|
-
robotsTxtState?: string;
|
|
28
|
-
indexingState?: string;
|
|
29
|
-
pageFetchState?: string;
|
|
30
|
-
mobileUsabilityVerdict?: string;
|
|
31
|
-
richResultsVerdict?: string;
|
|
32
|
-
/**
|
|
33
|
-
* Free-form payload for fields we don't promote to first-class columns
|
|
34
|
-
* (e.g. `referringUrls`, `crawledAs`). Keeps the wire format forward-compat
|
|
35
|
-
* without bumping the schema for every API addition.
|
|
36
|
-
*
|
|
37
|
-
* Recognised keys:
|
|
38
|
-
* - `schedule`: optional `ScheduleState` from {@link inspectionPolicy}
|
|
39
|
-
* governing when this URL is next due for re-inspection. Undefined on
|
|
40
|
-
* pre-§0 records — readers must tolerate the missing field and fall
|
|
41
|
-
* back to default policy on first observe.
|
|
42
|
-
*/
|
|
43
|
-
raw?: {
|
|
44
|
-
schedule?: ScheduleState;
|
|
45
|
-
[key: string]: unknown;
|
|
46
|
-
};
|
|
47
|
-
}
|
|
48
|
-
/** Wire shape persisted to disk/R2. */
|
|
49
|
-
interface InspectionIndex {
|
|
50
|
-
version: 1;
|
|
51
|
-
/** Map of urlHash → InspectionRecord (latest only). */
|
|
52
|
-
records: Record<string, InspectionRecord>;
|
|
53
|
-
}
|
|
54
|
-
/**
|
|
55
|
-
* Append-only history shard, one blob per `appendHistory` call.
|
|
56
|
-
* Keyed by UUID under the month directory — retries write a new blob,
|
|
57
|
-
* never RMW an existing one. Idempotent under job retries.
|
|
58
|
-
*/
|
|
59
|
-
interface InspectionHistoryShard {
|
|
60
|
-
version: 1;
|
|
61
|
-
/** Records persisted in this batch. */
|
|
62
|
-
records: InspectionRecord[];
|
|
63
|
-
}
|
|
64
|
-
/**
|
|
65
|
-
* Directory prefix for a month's history shards. Each shard is a UUID-keyed
|
|
66
|
-
* blob under this prefix; `appendHistory` writes one per call, `loadHistory`
|
|
67
|
-
* lists + concatenates.
|
|
68
|
-
*/
|
|
69
|
-
/**
|
|
70
|
-
* Row shape for the inspections parquet sidecar. Caller-side schema for
|
|
71
|
-
* `materialize` — D1 is the source of truth in the 2026-05-19 redesign, so
|
|
72
|
-
* consumers stream rows from `url_indexing_status` and pass them in. The
|
|
73
|
-
* parquet sidecar exists for DuckDB JOIN seams; readers go through
|
|
74
|
-
* `parquetUri`.
|
|
75
|
-
*/
|
|
76
|
-
interface InspectionParquetRow {
|
|
77
|
-
[column: string]: string | number | null;
|
|
78
|
-
urlHash: string;
|
|
79
|
-
url: string;
|
|
80
|
-
inspectedAt: string;
|
|
81
|
-
indexStatus: string | null;
|
|
82
|
-
lastCrawlTime: string | null;
|
|
83
|
-
googleCanonical: string | null;
|
|
84
|
-
userCanonical: string | null;
|
|
85
|
-
coverageState: string | null;
|
|
86
|
-
robotsTxtState: string | null;
|
|
87
|
-
indexingState: string | null;
|
|
88
|
-
pageFetchState: string | null;
|
|
89
|
-
mobileUsabilityVerdict: string | null;
|
|
90
|
-
richResultsVerdict: string | null;
|
|
91
|
-
scheduleNextAt: number | null;
|
|
92
|
-
scheduleConsecutiveUnchanged: number | null;
|
|
93
|
-
schedulePolicyVersion: number | null;
|
|
94
|
-
}
|
|
95
|
-
/**
|
|
96
|
-
* Row shape for the append-only inspection-event store. Superset of
|
|
97
|
-
* {@link InspectionParquetRow}: carries the full-fidelity columns the lossy
|
|
98
|
-
* `materialize` parquet dropped (`crawlingUserAgent`, `richResultsItems`,
|
|
99
|
-
* `sitemaps`, `referringUrls`, `mobileIssues`, `inspectionResultLink`,
|
|
100
|
-
* `firstCheckedAt`, `checkCount`). Object/array fields are persisted as JSON
|
|
101
|
-
* strings — read paths unpack them with DuckDB's JSON functions.
|
|
102
|
-
*
|
|
103
|
-
* `firstCheckedAt` / `checkCount` are caller-managed: the writer carries the
|
|
104
|
-
* earliest-seen timestamp + running observation count forward. Compaction
|
|
105
|
-
* preserves the EARLIEST `firstCheckedAt` per url (mirrors the sitemap store's
|
|
106
|
-
* `firstSeenAt` preservation); every other column is taken from the
|
|
107
|
-
* newest-by-`inspectedAt` event.
|
|
108
|
-
*/
|
|
109
|
-
interface InspectionEventRow extends InspectionParquetRow {
|
|
110
|
-
/** Declared-vs-selected canonical classification, computed at inspection ingest. */
|
|
111
|
-
canonicalMismatchKind: CanonicalDifferenceKind;
|
|
112
|
-
crawlingUserAgent: string | null;
|
|
113
|
-
/** JSON-encoded `RichResultsItem[]`. */
|
|
114
|
-
richResultsItems: string | null;
|
|
115
|
-
/** JSON-encoded list of sitemap URLs referencing this page. */
|
|
116
|
-
sitemaps: string | null;
|
|
117
|
-
/** JSON-encoded list of referring URLs. */
|
|
118
|
-
referringUrls: string | null;
|
|
119
|
-
/** JSON-encoded mobile-usability issues. */
|
|
120
|
-
mobileIssues: string | null;
|
|
121
|
-
inspectionResultLink: string | null;
|
|
122
|
-
/** ISO-8601 timestamp of the first inspection we ever recorded for this url. */
|
|
123
|
-
firstCheckedAt: string | null;
|
|
124
|
-
/** Total number of inspections recorded for this url. */
|
|
125
|
-
checkCount: number | null;
|
|
126
|
-
/**
|
|
127
|
-
* Stored next-recheck unix-seconds + priority as computed AT INSPECT TIME.
|
|
128
|
-
* Carried verbatim (NOT recomputed at read) because the scheduling policy can
|
|
129
|
-
* change over time — `__gsc/inspections` must replay the historical value to
|
|
130
|
-
* keep its frozen wire shape byte-stable.
|
|
131
|
-
*/
|
|
132
|
-
nextCheckAfter: number | null;
|
|
133
|
-
nextCheckPriority: string | null;
|
|
134
|
-
}
|
|
135
|
-
/**
|
|
136
|
-
* Hard cap on a single `appendHistory` shard payload. Encoded bytes >
|
|
137
|
-
* this threshold throws — the caller logs and moves on (D1 is
|
|
138
|
-
* authoritative, R2 history is a sidecar). At `URLS_PER_JOB=3` a real
|
|
139
|
-
* batch encodes to ~10 KB so the cap is purely defensive against future
|
|
140
|
-
* batch-size bumps.
|
|
141
|
-
*/
|
|
142
|
-
declare const INSPECTION_HISTORY_MAX_BYTES: number;
|
|
143
|
-
interface InspectionStore {
|
|
144
|
-
/**
|
|
145
|
-
* Append a batch of fresh inspection results as an immutable per-batch
|
|
146
|
-
* shard under `history/<YYYY-MM>/<batchId>.json`. Idempotent under job
|
|
147
|
-
* retry (caller-supplied UUID per logical batch), no read-before-write,
|
|
148
|
-
* one PUT per month-group within the batch.
|
|
149
|
-
*
|
|
150
|
-
* Throws if the encoded payload exceeds {@link INSPECTION_HISTORY_MAX_BYTES}.
|
|
151
|
-
*/
|
|
152
|
-
appendHistory: (ctx: TenantCtx, records: readonly InspectionRecord[], opts?: {
|
|
153
|
-
batchId?: string;
|
|
154
|
-
}) => Promise<void>;
|
|
155
|
-
/**
|
|
156
|
-
* Read every shard in a month directory and concatenate. Best-effort:
|
|
157
|
-
* shards that fail to decode are skipped (logged via console). Returns
|
|
158
|
-
* `undefined` if the month has no shards.
|
|
159
|
-
*/
|
|
160
|
-
loadHistory: (ctx: TenantCtx, yearMonth: string) => Promise<InspectionHistoryShard | undefined>;
|
|
161
|
-
/**
|
|
162
|
-
* Encode caller-provided rows into the inspections parquet sidecar at
|
|
163
|
-
* `entities/inspections/index.parquet`. Sorted by `urlHash` so DuckDB
|
|
164
|
-
* row-group stats can prune URL-keyed JOINs efficiently. One PUT.
|
|
165
|
-
*
|
|
166
|
-
* D1 is the source of truth in the 2026-05-19 redesign; this rebuilds
|
|
167
|
-
* the parquet from D1 rows the caller streams in (engine has no D1
|
|
168
|
-
* access). Triggered by `indexing/complete` post-hook.
|
|
169
|
-
*
|
|
170
|
-
* Returns the parquet object key (matches {@link parquetUri} after write).
|
|
171
|
-
*/
|
|
172
|
-
materialize: (ctx: TenantCtx, rows: Iterable<InspectionParquetRow>) => Promise<{
|
|
173
|
-
key: string;
|
|
174
|
-
rowCount: number;
|
|
175
|
-
bytes: number;
|
|
176
|
-
}>;
|
|
177
|
-
/**
|
|
178
|
-
* Append a batch of inspection results as an immutable per-batch parquet
|
|
179
|
-
* under `events/<YYYY-MM>/<batchId>.parquet`, partitioned by the `YYYY-MM`
|
|
180
|
-
* of each row's `inspectedAt` (a batch spanning a month boundary writes one
|
|
181
|
-
* file per month). No read-before-write; idempotent under job retry (same
|
|
182
|
-
* `batchId` → same key → whole-file overwrite). Rows carry the FULL column
|
|
183
|
-
* set ({@link INSPECTION_EVENT_COLUMNS}); this is the append-only
|
|
184
|
-
* source-of-truth that supersedes {@link InspectionStore.materialize}.
|
|
185
|
-
*
|
|
186
|
-
* Returns the keys written + total row count. Empty input is a no-op.
|
|
187
|
-
*/
|
|
188
|
-
appendInspectionEvents: (ctx: TenantCtx, rows: readonly InspectionEventRow[], opts?: {
|
|
189
|
-
batchId?: string;
|
|
190
|
-
}) => Promise<{
|
|
191
|
-
keys: string[];
|
|
192
|
-
rowCount: number;
|
|
193
|
-
}>;
|
|
194
|
-
/**
|
|
195
|
-
* Fold every outstanding event file into the `base.parquet`: latest-per-url
|
|
196
|
-
* by max `inspectedAt` (newest-wins), preserving the earliest non-null
|
|
197
|
-
* `firstCheckedAt` per url. Writes the new base then deletes the consumed
|
|
198
|
-
* event files — file-level only, never row-level (ADR-0002). Idempotent +
|
|
199
|
-
* re-runnable: a crash after the base write but before the delete just
|
|
200
|
-
* re-folds the same events (newest-wins makes that a no-op). A real read
|
|
201
|
-
* failure on the existing base propagates rather than rebuilding from events
|
|
202
|
-
* alone (which would drop URLs only the base held).
|
|
203
|
-
*
|
|
204
|
-
* No-op (no base rewrite) when there are zero outstanding events.
|
|
205
|
-
*/
|
|
206
|
-
compactInspections: (ctx: TenantCtx, opts?: {
|
|
207
|
-
/**
|
|
208
|
-
* Also record state changes into the durable transitions sidecar.
|
|
209
|
-
* Default OFF so publishing this is inert until a canary opts in.
|
|
210
|
-
*/
|
|
211
|
-
transitions?: boolean;
|
|
212
|
-
}) => Promise<{
|
|
213
|
-
baseRowCount: number;
|
|
214
|
-
eventsFolded: number;
|
|
215
|
-
eventFilesDeleted: number;
|
|
216
|
-
transitionsWritten: number;
|
|
217
|
-
}>;
|
|
218
|
-
/**
|
|
219
|
-
* Rewrite a legacy latest-only base with the canonical kind derived from the
|
|
220
|
-
* canonical pair it already retains. Outstanding events must be compacted first.
|
|
221
|
-
*/
|
|
222
|
-
backfillCanonicalMismatchKinds: (ctx: TenantCtx) => Promise<{
|
|
223
|
-
baseRowCount: number;
|
|
224
|
-
rowsBackfilled: number;
|
|
225
|
-
rewritten: boolean;
|
|
226
|
-
}>;
|
|
227
|
-
/**
|
|
228
|
-
* DuckDB-resolvable URI for the materialised parquet sidecar, or
|
|
229
|
-
* `undefined` if the underlying `DataSource` has no native URI shape
|
|
230
|
-
* (in-memory tests). When defined, read paths can `read_parquet(<uri>)`
|
|
231
|
-
* directly without staging bytes through JS.
|
|
232
|
-
*
|
|
233
|
-
* Does not check existence — caller is responsible for ensuring
|
|
234
|
-
* `materialize` has run at least once. Returning a URI for a missing key
|
|
235
|
-
* is safe; DuckDB will surface a 404 / not-found at query time.
|
|
236
|
-
*/
|
|
237
|
-
parquetUri: (ctx: TenantCtx) => string | undefined;
|
|
238
|
-
}
|
|
239
|
-
interface CreateInspectionStoreOptions {
|
|
240
|
-
dataSource: DataSource;
|
|
241
|
-
}
|
|
242
|
-
declare function createInspectionStore(opts: CreateInspectionStoreOptions): InspectionStore;
|
|
243
|
-
/** GSC sitemap record we persist. Matches `Schema$WmxSitemap` but as plain JSON. */
|
|
244
|
-
interface SitemapRecord {
|
|
245
|
-
/** The sitemap URL (feedpath) as returned by GSC. */
|
|
246
|
-
path: string;
|
|
247
|
-
/** ISO-8601 timestamp of the snapshot run that captured this record. */
|
|
248
|
-
capturedAt: string;
|
|
249
|
-
/** Last time Google downloaded this sitemap (RFC 3339, from the API). */
|
|
250
|
-
lastDownloaded?: string;
|
|
251
|
-
/** Last time the sitemap was submitted. */
|
|
252
|
-
lastSubmitted?: string;
|
|
253
|
-
type?: string;
|
|
254
|
-
isPending?: boolean;
|
|
255
|
-
isSitemapsIndex?: boolean;
|
|
256
|
-
errors?: string;
|
|
257
|
-
warnings?: string;
|
|
258
|
-
/** Per-content-type counts (web, image, video, news). */
|
|
259
|
-
contents?: Array<{
|
|
260
|
-
type?: string;
|
|
261
|
-
submitted?: string;
|
|
262
|
-
indexed?: string;
|
|
263
|
-
}>;
|
|
264
|
-
/** Raw payload for fields we don't promote to first-class columns. */
|
|
265
|
-
raw?: unknown;
|
|
266
|
-
/** Number of URLs observed in this feedpath at last snapshot. */
|
|
267
|
-
urlCount?: number;
|
|
268
|
-
/** Stable hash of the sorted normalized loc list at last snapshot. */
|
|
269
|
-
contentHash?: string;
|
|
270
|
-
/** Adaptive cadence state owned by `sitemapPolicy`. */
|
|
271
|
-
schedule?: ScheduleState;
|
|
272
|
-
}
|
|
273
|
-
interface SitemapIndex {
|
|
274
|
-
version: 1;
|
|
275
|
-
/** Map of feedpathHash → latest SitemapRecord. */
|
|
276
|
-
records: Record<string, SitemapRecord>;
|
|
277
|
-
}
|
|
278
|
-
interface SitemapHistoryDoc {
|
|
279
|
-
version: 1;
|
|
280
|
-
path: string;
|
|
281
|
-
capturedAt: string;
|
|
282
|
-
record: SitemapRecord;
|
|
283
|
-
}
|
|
284
|
-
/** Parsed URL entry from a sitemap XML. */
|
|
285
|
-
interface ParsedUrl {
|
|
286
|
-
loc: string;
|
|
287
|
-
/** ISO-8601 lastmod from the sitemap, if present. */
|
|
288
|
-
lastmod?: string;
|
|
289
|
-
}
|
|
290
|
-
/** A single URL row in the urls/index.parquet partition. */
|
|
291
|
-
interface SitemapUrlRecord {
|
|
292
|
-
feedpath: string;
|
|
293
|
-
feedpathHash: string;
|
|
294
|
-
urlHash: string;
|
|
295
|
-
loc: string;
|
|
296
|
-
lastmod?: string;
|
|
297
|
-
firstSeenAt: number;
|
|
298
|
-
lastSeenAt: number;
|
|
299
|
-
/** Set when the URL has been removed. Null/undefined = currently live. */
|
|
300
|
-
removedAt?: number;
|
|
301
|
-
}
|
|
302
|
-
interface SnapshotUrlsResult {
|
|
303
|
-
added: number;
|
|
304
|
-
removed: number;
|
|
305
|
-
kept: number;
|
|
306
|
-
contentHash: string;
|
|
307
|
-
/** True when current membership did not change. Initial history seeding may write. */
|
|
308
|
-
unchanged: boolean;
|
|
309
|
-
}
|
|
310
|
-
interface CompleteSitemapGeneration {
|
|
311
|
-
_tag: 'complete';
|
|
312
|
-
id: string;
|
|
313
|
-
/** Unix epoch milliseconds. */
|
|
314
|
-
observedAt: number;
|
|
315
|
-
}
|
|
316
|
-
interface ReconcileResult {
|
|
317
|
-
/** Feedpaths that were absent from the live set and had their live URLs pruned. */
|
|
318
|
-
feedpathsPruned: number;
|
|
319
|
-
/** Total URL rows transitioned live → removed across pruned feedpaths. */
|
|
320
|
-
urlsRemoved: number;
|
|
321
|
-
}
|
|
322
|
-
/**
|
|
323
|
-
* Bounds on a single `compactUrls` call. `compactUrls` is memory-bounded (one
|
|
324
|
-
* feedpath at a time) but was previously unbounded in TIME: a tenant with a
|
|
325
|
-
* large accumulated delta backlog could run past a caller's execution budget.
|
|
326
|
-
* Both bounds are checked BETWEEN feedpaths and only after at least one has
|
|
327
|
-
* been compacted, so a call always makes forward progress.
|
|
328
|
-
*/
|
|
329
|
-
interface CompactUrlsOptions {
|
|
330
|
-
/** Stop before starting another feedpath once this many ms have elapsed. */
|
|
331
|
-
deadlineMs?: number;
|
|
332
|
-
/** Stop after compacting this many feedpaths. */
|
|
333
|
-
maxFeedpaths?: number;
|
|
334
|
-
}
|
|
335
|
-
interface CompactUrlsResult {
|
|
336
|
-
/** Feedpaths whose active deltas were folded and retired by this call. */
|
|
337
|
-
compactedFeedpaths: number;
|
|
338
|
-
/**
|
|
339
|
-
* Feedpaths that still hold outstanding deltas. Call `compactUrls` again to
|
|
340
|
-
* continue. No cursor is needed because the projection watermark excludes a
|
|
341
|
-
* compacted feedpath's grace-retained deltas from the next call.
|
|
342
|
-
*/
|
|
343
|
-
remainingFeedpaths: number;
|
|
344
|
-
}
|
|
345
|
-
interface DeltaEntry {
|
|
346
|
-
feedpath: string;
|
|
347
|
-
feedpathHash: string;
|
|
348
|
-
urlHash: string;
|
|
349
|
-
op: 'added' | 'removed';
|
|
350
|
-
loc: string;
|
|
351
|
-
lastmod?: string;
|
|
352
|
-
at: number;
|
|
353
|
-
}
|
|
354
|
-
interface SitemapMembershipEvent {
|
|
355
|
-
feedpath: string;
|
|
356
|
-
feedpathHash: string;
|
|
357
|
-
urlHash: string;
|
|
358
|
-
op: 'added' | 'removed';
|
|
359
|
-
loc: string;
|
|
360
|
-
lastmod?: string;
|
|
361
|
-
generationId: string;
|
|
362
|
-
/** Unix epoch milliseconds. */
|
|
363
|
-
observedAt: number;
|
|
364
|
-
/** Stable ordering within one generation. */
|
|
365
|
-
sequence: number;
|
|
366
|
-
/** Whether this row also mutates the disposable current-state projection. */
|
|
367
|
-
projectsState: boolean;
|
|
368
|
-
}
|
|
369
|
-
interface DateRange {
|
|
370
|
-
/** YYYY-MM-DD inclusive. */
|
|
371
|
-
from?: string;
|
|
372
|
-
/** YYYY-MM-DD inclusive. */
|
|
373
|
-
to?: string;
|
|
374
|
-
}
|
|
375
|
-
interface LoadUrlsOptions {
|
|
376
|
-
includeRemoved?: boolean;
|
|
377
|
-
}
|
|
378
|
-
interface SitemapReadStore {
|
|
379
|
-
/** Load the full site index (latest record per feedpath). */
|
|
380
|
-
loadIndex: (ctx: TenantCtx) => Promise<SitemapIndex>;
|
|
381
|
-
/** Fetch the latest snapshot for a feedpath, or undefined. */
|
|
382
|
-
getLatest: (ctx: TenantCtx, path: string) => Promise<SitemapRecord | undefined>;
|
|
383
|
-
/** Stream live (and optionally removed) URL rows for a feedpath. */
|
|
384
|
-
loadUrls: (ctx: TenantCtx, feedpath: string, opts?: LoadUrlsOptions) => AsyncIterable<SitemapUrlRecord>;
|
|
385
|
-
/** Stream all delta entries within `[from, to]` (YYYY-MM-DD inclusive). */
|
|
386
|
-
loadDeltas: (ctx: TenantCtx, dateRange?: DateRange) => AsyncIterable<DeltaEntry>;
|
|
387
|
-
/** Stream immutable membership events within `[from, to]`. */
|
|
388
|
-
loadEvents: (ctx: TenantCtx, dateRange?: DateRange) => AsyncIterable<SitemapMembershipEvent>;
|
|
389
|
-
}
|
|
390
|
-
interface SitemapStore extends SitemapReadStore {
|
|
391
|
-
/**
|
|
392
|
-
* Persist a snapshot run. Updates the index + writes one immutable
|
|
393
|
-
* history doc per record under `history/<feedpathHash>__<capturedAtMs>.json`.
|
|
394
|
-
*/
|
|
395
|
-
writeSnapshot: (ctx: TenantCtx, records: readonly SitemapRecord[]) => Promise<void>;
|
|
396
|
-
/**
|
|
397
|
-
* Diff a complete sitemap generation against current state. The immutable
|
|
398
|
-
* membership event lands before its disposable state delta.
|
|
399
|
-
*/
|
|
400
|
-
snapshotUrls: (ctx: TenantCtx, generation: CompleteSitemapGeneration, feedpath: string, urls: readonly ParsedUrl[]) => Promise<SnapshotUrlsResult>;
|
|
401
|
-
/**
|
|
402
|
-
* Fold accumulated deltas into the prior index, one feedpath at a time:
|
|
403
|
-
* rewrites each touched feedpath's `by-feed/<hash>/index.parquet` and deletes
|
|
404
|
-
* the consumed delta files. Bounded per feedpath, so it stays within memory
|
|
405
|
-
* regardless of total site URL count.
|
|
406
|
-
*
|
|
407
|
-
* Optionally bounded in TIME too (`opts.deadlineMs` / `opts.maxFeedpaths`).
|
|
408
|
-
* A bounded call is safe to stop mid-way: each rewritten feedpath advances
|
|
409
|
-
* the projection watermark, so the remainder is simply what the next call
|
|
410
|
-
* finds. Callers drive this from `remainingFeedpaths`, not a cursor.
|
|
411
|
-
*/
|
|
412
|
-
compactUrls: (ctx: TenantCtx, opts?: CompactUrlsOptions) => Promise<CompactUrlsResult>;
|
|
413
|
-
/**
|
|
414
|
-
* Site-wide convergence: mark every still-live URL whose owning feedpath is
|
|
415
|
-
* absent from `liveFeedpaths` as removed. `compactUrls`/`snapshotUrls` only
|
|
416
|
-
* prune URLs *inside* a feedpath that was re-observed; a whole feed dropped
|
|
417
|
-
* from the sitemap list (no `snapshotUrls` call) leaves its URLs frozen-live
|
|
418
|
-
* forever. This is the sidecar mirror of the D1 generation sweep: it rewrites
|
|
419
|
-
* each dropped feedpath's `by-feed/<hash>/index.parquet` with `removedAt` set,
|
|
420
|
-
* advances its projection watermark, and grace-retires outstanding deltas.
|
|
421
|
-
* Bounded per feedpath, so memory stays flat regardless of site size. Live
|
|
422
|
-
* feedpaths are never touched.
|
|
423
|
-
*/
|
|
424
|
-
reconcile: (ctx: TenantCtx, generation: CompleteSitemapGeneration, opts: {
|
|
425
|
-
liveFeedpaths: readonly string[];
|
|
426
|
-
}) => Promise<ReconcileResult>;
|
|
427
|
-
}
|
|
428
|
-
interface CreateSitemapReadStoreOptions {
|
|
429
|
-
dataSource: DataSource;
|
|
430
|
-
/** Override the feedpath hash (test seam). */
|
|
431
|
-
hash?: (path: string) => string;
|
|
432
|
-
}
|
|
433
|
-
type SitemapMutation = <T>(ctx: TenantCtx, fn: () => Promise<T>) => Promise<T>;
|
|
434
|
-
interface CreateSitemapStoreOptions extends CreateSitemapReadStoreOptions {
|
|
435
|
-
withMutation: SitemapMutation;
|
|
436
|
-
now?: () => number;
|
|
437
|
-
}
|
|
438
|
-
declare function createSitemapReadStore(opts: CreateSitemapReadStoreOptions): SitemapReadStore;
|
|
439
|
-
declare function createSitemapStore(opts: CreateSitemapStoreOptions): SitemapStore;
|
|
440
|
-
interface IndexingMetadataRecord {
|
|
441
|
-
url: string;
|
|
442
|
-
capturedAt: string;
|
|
443
|
-
/** ISO-8601 notifyTime of the latest `URL_UPDATED` notification we've seen. */
|
|
444
|
-
latestUpdateAt?: string;
|
|
445
|
-
/** ISO-8601 notifyTime of the latest `URL_REMOVED` notification we've seen. */
|
|
446
|
-
latestRemoveAt?: string;
|
|
447
|
-
raw?: unknown;
|
|
448
|
-
}
|
|
449
|
-
interface IndexingMetadataIndex {
|
|
450
|
-
version: 1;
|
|
451
|
-
records: Record<string, IndexingMetadataRecord>;
|
|
452
|
-
}
|
|
453
|
-
interface IndexingMetadataStore {
|
|
454
|
-
writeBatch: (ctx: TenantCtx, records: readonly IndexingMetadataRecord[]) => Promise<void>;
|
|
455
|
-
loadIndex: (ctx: TenantCtx) => Promise<IndexingMetadataIndex>;
|
|
456
|
-
getLatest: (ctx: TenantCtx, url: string) => Promise<IndexingMetadataRecord | undefined>;
|
|
457
|
-
}
|
|
458
|
-
interface CreateIndexingMetadataStoreOptions {
|
|
459
|
-
dataSource: DataSource;
|
|
460
|
-
hash?: (url: string) => string;
|
|
461
|
-
}
|
|
462
|
-
declare function createIndexingMetadataStore(opts: CreateIndexingMetadataStoreOptions): IndexingMetadataStore;
|
|
463
|
-
interface EmptyTypesDoc {
|
|
464
|
-
version: 1;
|
|
465
|
-
/** SearchType strings detected as empty for this (user, site). */
|
|
466
|
-
emptyTypes: string[];
|
|
467
|
-
/** When each type was last marked empty (unix ms). Helps debug stale skips. */
|
|
468
|
-
markedAt: Record<string, number>;
|
|
469
|
-
}
|
|
470
|
-
interface EmptyTypesStore {
|
|
471
|
-
load: (ctx: TenantCtx) => Promise<EmptyTypesDoc>;
|
|
472
|
-
/** Add types to the empty set, preserving existing markers. No-op if all already present. */
|
|
473
|
-
mark: (ctx: TenantCtx, types: readonly string[], now?: number) => Promise<EmptyTypesDoc>;
|
|
474
|
-
/** Remove types from the empty set. Returns the updated doc. */
|
|
475
|
-
clear: (ctx: TenantCtx, types: readonly string[]) => Promise<EmptyTypesDoc>;
|
|
476
|
-
}
|
|
477
|
-
interface CreateEmptyTypesStoreOptions {
|
|
478
|
-
dataSource: DataSource;
|
|
479
|
-
now?: () => number;
|
|
480
|
-
}
|
|
481
|
-
declare function createEmptyTypesStore(opts: CreateEmptyTypesStoreOptions): EmptyTypesStore;
|
|
482
|
-
export { CompactUrlsOptions, CompactUrlsResult, CompleteSitemapGeneration, CreateEmptyTypesStoreOptions, CreateIndexingMetadataStoreOptions, CreateInspectionStoreOptions, CreateSitemapReadStoreOptions, CreateSitemapStoreOptions, DateRange, DeltaEntry, EmptyTypesDoc, EmptyTypesStore, INSPECTION_HISTORY_MAX_BYTES, IndexingMetadataIndex, IndexingMetadataRecord, IndexingMetadataStore, InspectionEventRow, InspectionHistoryShard, InspectionIndex, InspectionParquetRow, InspectionRecord, InspectionStore, LoadUrlsOptions, ParsedUrl, QueryDimDeps, QueryDimMeta, QueryDimRecord, QueryDimStore, ReconcileResult, SITEMAP_PROJECTION_GRACE_MS, SitemapGenerationKey, SitemapHistoryDoc, SitemapIndex, SitemapMembershipEvent, SitemapMutation, SitemapProjectionFeed, SitemapProjectionFiles, SitemapProjectionManifest, SitemapReadStore, SitemapRecord, SitemapStore, SitemapUrlRecord, SnapshotUrlsResult, buildQueryDimRecords, createEmptyTypesStore, createIndexingMetadataStore, createInspectionStore, createQueryDimStore, createSitemapReadStore, createSitemapStore, decodeSitemapProjectionManifest, emptySitemapProjectionManifest, emptyTypesKey, hashSortedUrlList, hashUrl, hashUrlList, indexingMetadataIndexKey, inspectionBaseKey, inspectionEventKey, inspectionEventsPrefix, inspectionHistoryPrefix, inspectionHistoryShardKey, inspectionIndexKey, inspectionParquetKey, inspectionTransitionsMonthKey, inspectionTransitionsPrefix, parseSitemapProjectionManifest, parseSitemapUrlsDeltaKey, queryDimMetaKey, queryDimParquetKey, selectSitemapProjectionFiles, sitemapHistoryKey, sitemapIndexKey, sitemapUrlsDeltaKey, sitemapUrlsEventKey, sitemapUrlsEventSeedKey, sitemapUrlsEventsPrefix, sitemapUrlsGenerationKey, sitemapUrlsIndexKey, sitemapUrlsIndexPrefix, sitemapUrlsPendingGenerationKey, sitemapUrlsPendingGenerationsPrefix, sitemapUrlsPrefix, sitemapUrlsProjectionManifestKey, sitemapUrlsReconcileGenerationKey, withSitemapProjectionFeed };
|
|
5
|
+
import { QueryDimDeps, QueryDimMeta, QueryDimRecord, QueryDimStore, buildQueryDimRecords, createQueryDimStore } from "./entities/query-dim.mjs";
|
|
6
|
+
import { CompactUrlsOptions, CompactUrlsResult, CompleteSitemapGeneration, CreateSitemapReadStoreOptions, CreateSitemapStoreOptions, DateRange, DeltaEntry, LoadUrlsOptions, ParsedUrl, ReconcileResult, SitemapHistoryDoc, SitemapIndex, SitemapMembershipEvent, SitemapMutation, SitemapReadStore, SitemapRecord, SitemapStore, SitemapUrlRecord, SnapshotUrlsResult } from "./entities/sitemap-shared.mjs";
|
|
7
|
+
import { createSitemapReadStore } from "./entities/sitemap.mjs";
|
|
8
|
+
import { SITEMAP_PROJECTION_GRACE_MS, SitemapProjectionFeed, SitemapProjectionFiles, SitemapProjectionManifest, decodeSitemapProjectionManifest, emptySitemapProjectionManifest, parseSitemapProjectionManifest, selectSitemapProjectionFiles, withSitemapProjectionFeed } from "./entities/sitemap-projection.mjs";
|
|
9
|
+
import { createSitemapStore } from "./entities/sitemap-write.mjs";
|
|
10
|
+
export { type CompactUrlsOptions, type CompactUrlsResult, type CompleteSitemapGeneration, type CreateEmptyTypesStoreOptions, type CreateIndexingMetadataStoreOptions, CreateInspectionStoreOptions, type CreateSitemapReadStoreOptions, type CreateSitemapStoreOptions, type DateRange, type DeltaEntry, type EmptyTypesDoc, type EmptyTypesStore, INSPECTION_HISTORY_MAX_BYTES, type IndexingMetadataIndex, type IndexingMetadataRecord, type IndexingMetadataStore, InspectionEventRow, InspectionHistoryShard, InspectionIndex, InspectionParquetRow, InspectionRecord, InspectionStore, type LoadUrlsOptions, type ParsedUrl, QueryDimDeps, QueryDimMeta, QueryDimRecord, QueryDimStore, type ReconcileResult, SITEMAP_PROJECTION_GRACE_MS, SitemapGenerationKey, type SitemapHistoryDoc, type SitemapIndex, type SitemapMembershipEvent, type SitemapMutation, SitemapProjectionFeed, SitemapProjectionFiles, SitemapProjectionManifest, type SitemapReadStore, type SitemapRecord, type SitemapStore, type SitemapUrlRecord, type SnapshotUrlsResult, buildQueryDimRecords, createEmptyTypesStore, createIndexingMetadataStore, createInspectionStore, createQueryDimStore, createSitemapReadStore, createSitemapStore, decodeSitemapProjectionManifest, emptySitemapProjectionManifest, emptyTypesKey, hashSortedUrlList, hashUrl, hashUrlList, indexingMetadataIndexKey, inspectionBaseKey, inspectionEventKey, inspectionEventsPrefix, inspectionHistoryPrefix, inspectionHistoryShardKey, inspectionIndexKey, inspectionParquetKey, inspectionTransitionsMonthKey, inspectionTransitionsPrefix, parseSitemapProjectionManifest, parseSitemapUrlsDeltaKey, queryDimMetaKey, queryDimParquetKey, selectSitemapProjectionFiles, sitemapHistoryKey, sitemapIndexKey, sitemapUrlsDeltaKey, sitemapUrlsEventKey, sitemapUrlsEventSeedKey, sitemapUrlsEventsPrefix, sitemapUrlsGenerationKey, sitemapUrlsIndexKey, sitemapUrlsIndexPrefix, sitemapUrlsPendingGenerationKey, sitemapUrlsPendingGenerationsPrefix, sitemapUrlsPrefix, sitemapUrlsProjectionManifestKey, sitemapUrlsReconcileGenerationKey, withSitemapProjectionFeed };
|