@gscdump/engine 0.37.2 → 0.37.3
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/_chunks/entities.mjs +12 -1
- package/dist/entities.d.mts +30 -2
- package/package.json +4 -4
|
@@ -758,7 +758,10 @@ function createSitemapStore(opts) {
|
|
|
758
758
|
}
|
|
759
759
|
}
|
|
760
760
|
},
|
|
761
|
-
async compactUrls(ctx) {
|
|
761
|
+
async compactUrls(ctx, opts = {}) {
|
|
762
|
+
const startedAt = now();
|
|
763
|
+
const deadlineMs = opts.deadlineMs ?? Number.POSITIVE_INFINITY;
|
|
764
|
+
const maxFeedpaths = opts.maxFeedpaths ?? Number.POSITIVE_INFINITY;
|
|
762
765
|
const deltaKeys = await ds.list(`${sitemapUrlsPrefix(ctx)}/deltas/`);
|
|
763
766
|
const deltasByFeed = /* @__PURE__ */ new Map();
|
|
764
767
|
for (const key of deltaKeys) {
|
|
@@ -770,7 +773,10 @@ function createSitemapStore(opts) {
|
|
|
770
773
|
list.push(key);
|
|
771
774
|
deltasByFeed.set(feedpathHash, list);
|
|
772
775
|
}
|
|
776
|
+
const totalFeedpaths = deltasByFeed.size;
|
|
777
|
+
let compactedFeedpaths = 0;
|
|
773
778
|
for (const [fpHash, feedDeltaKeys] of deltasByFeed) {
|
|
779
|
+
if (compactedFeedpaths > 0 && (compactedFeedpaths >= maxFeedpaths || now() - startedAt >= deadlineMs)) break;
|
|
774
780
|
const indexKey = sitemapUrlsIndexKey(ctx, fpHash);
|
|
775
781
|
const indexBytes = await readOptional(ds, indexKey);
|
|
776
782
|
const indexRows = indexBytes ? await decodeParquetToRows(indexBytes) : [];
|
|
@@ -821,7 +827,12 @@ function createSitemapStore(opts) {
|
|
|
821
827
|
});
|
|
822
828
|
await ds.write(indexKey, bytes);
|
|
823
829
|
if (consumed.length > 0) await ds.delete(consumed);
|
|
830
|
+
compactedFeedpaths++;
|
|
824
831
|
}
|
|
832
|
+
return {
|
|
833
|
+
compactedFeedpaths,
|
|
834
|
+
remainingFeedpaths: totalFeedpaths - compactedFeedpaths
|
|
835
|
+
};
|
|
825
836
|
},
|
|
826
837
|
async reconcile(ctx, { liveFeedpaths, at: atOpt }) {
|
|
827
838
|
const at = atOpt ?? now();
|
package/dist/entities.d.mts
CHANGED
|
@@ -379,6 +379,29 @@ interface ReconcileResult {
|
|
|
379
379
|
/** Total URL rows transitioned live → removed across pruned feedpaths. */
|
|
380
380
|
urlsRemoved: number;
|
|
381
381
|
}
|
|
382
|
+
/**
|
|
383
|
+
* Bounds on a single `compactUrls` call. `compactUrls` is memory-bounded (one
|
|
384
|
+
* feedpath at a time) but was previously unbounded in TIME: a tenant with a
|
|
385
|
+
* large accumulated delta backlog could run past a caller's execution budget.
|
|
386
|
+
* Both bounds are checked BETWEEN feedpaths and only after at least one has
|
|
387
|
+
* been compacted, so a call always makes forward progress.
|
|
388
|
+
*/
|
|
389
|
+
interface CompactUrlsOptions {
|
|
390
|
+
/** Stop before starting another feedpath once this many ms have elapsed. */
|
|
391
|
+
deadlineMs?: number;
|
|
392
|
+
/** Stop after compacting this many feedpaths. */
|
|
393
|
+
maxFeedpaths?: number;
|
|
394
|
+
}
|
|
395
|
+
interface CompactUrlsResult {
|
|
396
|
+
/** Feedpaths whose deltas were folded and deleted by this call. */
|
|
397
|
+
compactedFeedpaths: number;
|
|
398
|
+
/**
|
|
399
|
+
* Feedpaths that still hold outstanding deltas. Call `compactUrls` again to
|
|
400
|
+
* continue — no cursor is needed, because a compacted feedpath's deltas are
|
|
401
|
+
* deleted, so the next call simply doesn't see it.
|
|
402
|
+
*/
|
|
403
|
+
remainingFeedpaths: number;
|
|
404
|
+
}
|
|
382
405
|
interface DeltaEntry {
|
|
383
406
|
feedpath: string;
|
|
384
407
|
feedpathHash: string;
|
|
@@ -428,8 +451,13 @@ interface SitemapStore {
|
|
|
428
451
|
* rewrites each touched feedpath's `by-feed/<hash>/index.parquet` and deletes
|
|
429
452
|
* the consumed delta files. Bounded per feedpath, so it stays within memory
|
|
430
453
|
* regardless of total site URL count.
|
|
454
|
+
*
|
|
455
|
+
* Optionally bounded in TIME too (`opts.deadlineMs` / `opts.maxFeedpaths`).
|
|
456
|
+
* A bounded call is safe to stop mid-way: each feedpath's deltas are deleted
|
|
457
|
+
* as soon as its index is rewritten, so the remainder is simply what the next
|
|
458
|
+
* call finds. Callers drive this from `remainingFeedpaths`, not a cursor.
|
|
431
459
|
*/
|
|
432
|
-
compactUrls: (ctx: TenantCtx) => Promise<
|
|
460
|
+
compactUrls: (ctx: TenantCtx, opts?: CompactUrlsOptions) => Promise<CompactUrlsResult>;
|
|
433
461
|
/**
|
|
434
462
|
* Site-wide convergence: mark every still-live URL whose owning feedpath is
|
|
435
463
|
* absent from `liveFeedpaths` as removed. `compactUrls`/`snapshotUrls` only
|
|
@@ -496,4 +524,4 @@ interface CreateEmptyTypesStoreOptions {
|
|
|
496
524
|
now?: () => number;
|
|
497
525
|
}
|
|
498
526
|
declare function createEmptyTypesStore(opts: CreateEmptyTypesStoreOptions): EmptyTypesStore;
|
|
499
|
-
export { CreateEmptyTypesStoreOptions, CreateIndexingMetadataStoreOptions, CreateInspectionStoreOptions, CreateSitemapStoreOptions, DateRange, DeltaEntry, EmptyTypesDoc, EmptyTypesStore, INSPECTION_EVENT_COLUMNS, INSPECTION_HISTORY_MAX_BYTES, IndexingMetadataIndex, IndexingMetadataRecord, IndexingMetadataStore, InspectionEventRow, InspectionHistoryShard, InspectionIndex, InspectionParquetRow, InspectionRecord, InspectionStore, LoadUrlsOptions, ParsedUrl, QueryDimDeps, QueryDimMeta, QueryDimRecord, QueryDimStore, ReconcileResult, SitemapHistoryDoc, SitemapIndex, SitemapRecord, SitemapStore, SitemapUrlRecord, SnapshotUrlsResult, buildQueryDimRecords, createEmptyTypesStore, createIndexingMetadataStore, createInspectionStore, createQueryDimStore, createSitemapStore, emptyTypesKey, hashUrl, hashUrlList, indexingMetadataIndexKey, inspectionBaseKey, inspectionEventKey, inspectionEventsPrefix, inspectionHistoryPrefix, inspectionHistoryShardKey, inspectionIndexKey, inspectionParquetKey, queryDimMetaKey, queryDimParquetKey, sitemapHistoryKey, sitemapIndexKey, sitemapUrlsDeltaKey, sitemapUrlsIndexKey, sitemapUrlsIndexPrefix };
|
|
527
|
+
export { CompactUrlsOptions, CompactUrlsResult, CreateEmptyTypesStoreOptions, CreateIndexingMetadataStoreOptions, CreateInspectionStoreOptions, CreateSitemapStoreOptions, DateRange, DeltaEntry, EmptyTypesDoc, EmptyTypesStore, INSPECTION_EVENT_COLUMNS, INSPECTION_HISTORY_MAX_BYTES, IndexingMetadataIndex, IndexingMetadataRecord, IndexingMetadataStore, InspectionEventRow, InspectionHistoryShard, InspectionIndex, InspectionParquetRow, InspectionRecord, InspectionStore, LoadUrlsOptions, ParsedUrl, QueryDimDeps, QueryDimMeta, QueryDimRecord, QueryDimStore, ReconcileResult, SitemapHistoryDoc, SitemapIndex, SitemapRecord, SitemapStore, SitemapUrlRecord, SnapshotUrlsResult, buildQueryDimRecords, createEmptyTypesStore, createIndexingMetadataStore, createInspectionStore, createQueryDimStore, createSitemapStore, emptyTypesKey, hashUrl, hashUrlList, indexingMetadataIndexKey, inspectionBaseKey, inspectionEventKey, inspectionEventsPrefix, inspectionHistoryPrefix, inspectionHistoryShardKey, inspectionIndexKey, inspectionParquetKey, queryDimMetaKey, queryDimParquetKey, sitemapHistoryKey, sitemapIndexKey, sitemapUrlsDeltaKey, sitemapUrlsIndexKey, sitemapUrlsIndexPrefix };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gscdump/engine",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.37.
|
|
4
|
+
"version": "0.37.3",
|
|
5
5
|
"description": "Append-only Parquet/DuckDB storage engine + planner + adapters for the gscdump pipeline. Node + edge runtimes; opt-in heavy peers.",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Harlan Wilton",
|
|
@@ -181,9 +181,9 @@
|
|
|
181
181
|
"dependencies": {
|
|
182
182
|
"drizzle-orm": "1.0.0-rc.3",
|
|
183
183
|
"proper-lockfile": "^4.1.2",
|
|
184
|
-
"@gscdump/
|
|
185
|
-
"gscdump": "0.37.
|
|
186
|
-
"
|
|
184
|
+
"@gscdump/lakehouse": "0.37.3",
|
|
185
|
+
"@gscdump/contracts": "0.37.3",
|
|
186
|
+
"gscdump": "0.37.3"
|
|
187
187
|
},
|
|
188
188
|
"devDependencies": {
|
|
189
189
|
"@duckdb/duckdb-wasm": "^1.32.0",
|