@gscdump/engine 0.33.0 → 0.33.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/engine.mjs
CHANGED
|
@@ -304,6 +304,12 @@ function txLeaf(leaf, columns) {
|
|
|
304
304
|
if (!column || !columns.has(column)) return null;
|
|
305
305
|
return { [column]: { $eq: leaf.expression } };
|
|
306
306
|
}
|
|
307
|
+
function combineFilters(parts, groupType) {
|
|
308
|
+
const first = parts[0];
|
|
309
|
+
if (!first) return null;
|
|
310
|
+
if (parts.length === 1) return first;
|
|
311
|
+
return groupType === "or" ? { $or: [...parts] } : { $and: [...parts] };
|
|
312
|
+
}
|
|
307
313
|
function txExact(node, columns) {
|
|
308
314
|
const groupType = node._groupType ?? "and";
|
|
309
315
|
const leafParts = [];
|
|
@@ -314,7 +320,7 @@ function txExact(node, columns) {
|
|
|
314
320
|
}
|
|
315
321
|
if (groupType === "or") {
|
|
316
322
|
if (node._nestedGroups?.length || leafParts.length === 0) return null;
|
|
317
|
-
return leafParts
|
|
323
|
+
return combineFilters(leafParts, "or");
|
|
318
324
|
}
|
|
319
325
|
const parts = leafParts;
|
|
320
326
|
for (const group of node._nestedGroups ?? []) {
|
|
@@ -323,7 +329,7 @@ function txExact(node, columns) {
|
|
|
323
329
|
parts.push(t);
|
|
324
330
|
}
|
|
325
331
|
if (parts.length === 0) return null;
|
|
326
|
-
return parts
|
|
332
|
+
return combineFilters(parts, "and");
|
|
327
333
|
}
|
|
328
334
|
function extractParquetPushdown(state, table) {
|
|
329
335
|
const filter = state?.filter;
|
|
@@ -341,7 +347,7 @@ function extractParquetPushdown(state, table) {
|
|
|
341
347
|
if (t) parts.push(t);
|
|
342
348
|
}
|
|
343
349
|
if (parts.length === 0) return void 0;
|
|
344
|
-
return parts
|
|
350
|
+
return combineFilters(parts, "and") ?? void 0;
|
|
345
351
|
}
|
|
346
352
|
const URL_PURGE_TABLES = ["pages", "page_queries"];
|
|
347
353
|
const MAX_DAY_BYTES = 100 * 1024 * 1024;
|
|
@@ -737,6 +737,7 @@ function createSitemapStore(opts) {
|
|
|
737
737
|
const m = SITEMAP_URLS_DELTA_PREFIX_RE.exec(key);
|
|
738
738
|
if (!m) continue;
|
|
739
739
|
const date = m[1];
|
|
740
|
+
if (!date) continue;
|
|
740
741
|
if (from && date < from) continue;
|
|
741
742
|
if (to && date > to) continue;
|
|
742
743
|
const bytes = await readOptional(ds, key);
|
|
@@ -763,9 +764,11 @@ function createSitemapStore(opts) {
|
|
|
763
764
|
for (const key of deltaKeys) {
|
|
764
765
|
const m = SITEMAP_URLS_DELTA_PREFIX_RE.exec(key);
|
|
765
766
|
if (!m) continue;
|
|
766
|
-
const
|
|
767
|
+
const feedpathHash = m[2];
|
|
768
|
+
if (!feedpathHash) continue;
|
|
769
|
+
const list = deltasByFeed.get(feedpathHash) ?? [];
|
|
767
770
|
list.push(key);
|
|
768
|
-
deltasByFeed.set(
|
|
771
|
+
deltasByFeed.set(feedpathHash, list);
|
|
769
772
|
}
|
|
770
773
|
for (const [fpHash, feedDeltaKeys] of deltasByFeed) {
|
|
771
774
|
const indexKey = sitemapUrlsIndexKey(ctx, fpHash);
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { inferLegacyTier, inferSearchType } from "./layout.mjs";
|
|
2
|
+
function manifestEntryKey(entry) {
|
|
3
|
+
return entry.objectKey;
|
|
4
|
+
}
|
|
5
|
+
function watermarkKey(watermark) {
|
|
6
|
+
return `${watermark.userId}|${watermark.siteId ?? ""}|${watermark.table}`;
|
|
7
|
+
}
|
|
8
|
+
function syncStateKey(state) {
|
|
9
|
+
return `${state.userId}|${state.siteId ?? ""}|${state.table}|${state.date}|${inferSearchType(state)}`;
|
|
10
|
+
}
|
|
11
|
+
function matchesManifestEntryFilter(entry, filter, options = {}) {
|
|
12
|
+
if (!options.ignoreUserId && entry.userId !== filter.userId) return false;
|
|
13
|
+
if (filter.siteId !== void 0 && entry.siteId !== filter.siteId) return false;
|
|
14
|
+
if (filter.table !== void 0 && entry.table !== filter.table) return false;
|
|
15
|
+
if (filter.partitions && !filter.partitions.includes(entry.partition)) return false;
|
|
16
|
+
if (filter.tier !== void 0 && inferLegacyTier(entry) !== filter.tier) return false;
|
|
17
|
+
if (filter.searchType !== void 0 && inferSearchType(entry) !== filter.searchType) return false;
|
|
18
|
+
return true;
|
|
19
|
+
}
|
|
20
|
+
function matchesWatermarkFilter(watermark, filter, options = {}) {
|
|
21
|
+
if (!options.ignoreUserId && watermark.userId !== filter.userId) return false;
|
|
22
|
+
if (filter.siteId !== void 0 && watermark.siteId !== filter.siteId) return false;
|
|
23
|
+
if (filter.table !== void 0 && watermark.table !== filter.table) return false;
|
|
24
|
+
return true;
|
|
25
|
+
}
|
|
26
|
+
function matchesSyncStateFilter(state, filter, options = {}) {
|
|
27
|
+
if (!options.ignoreUserId && state.userId !== filter.userId) return false;
|
|
28
|
+
if (filter.siteId !== void 0 && state.siteId !== filter.siteId) return false;
|
|
29
|
+
if (filter.table !== void 0 && state.table !== filter.table) return false;
|
|
30
|
+
if (filter.state !== void 0 && state.state !== filter.state) return false;
|
|
31
|
+
if (filter.searchType !== void 0 && inferSearchType(state) !== filter.searchType) return false;
|
|
32
|
+
return true;
|
|
33
|
+
}
|
|
34
|
+
function mergeSyncState(existing, scope, state, detail) {
|
|
35
|
+
const at = detail?.at ?? Date.now();
|
|
36
|
+
const attemptsBump = state === "inflight" ? 1 : 0;
|
|
37
|
+
if (!existing) return {
|
|
38
|
+
userId: scope.userId,
|
|
39
|
+
siteId: scope.siteId,
|
|
40
|
+
table: scope.table,
|
|
41
|
+
date: scope.date,
|
|
42
|
+
state,
|
|
43
|
+
updatedAt: at,
|
|
44
|
+
attempts: attemptsBump,
|
|
45
|
+
error: detail?.error,
|
|
46
|
+
...scope.searchType !== void 0 ? { searchType: scope.searchType } : {}
|
|
47
|
+
};
|
|
48
|
+
return {
|
|
49
|
+
...existing,
|
|
50
|
+
state,
|
|
51
|
+
updatedAt: at,
|
|
52
|
+
attempts: existing.attempts + attemptsBump,
|
|
53
|
+
error: state === "done" ? void 0 : detail?.error ?? existing.error
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
export { manifestEntryKey, matchesManifestEntryFilter, matchesSyncStateFilter, matchesWatermarkFilter, mergeSyncState, syncStateKey, watermarkKey };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { manifestEntryKey, matchesManifestEntryFilter, matchesSyncStateFilter, matchesWatermarkFilter, mergeSyncState, syncStateKey, watermarkKey } from "../_chunks/manifest-store-utils.mjs";
|
|
2
2
|
import { dirname, join, resolve } from "node:path";
|
|
3
3
|
import { Buffer } from "node:buffer";
|
|
4
4
|
import { randomBytes } from "node:crypto";
|
|
@@ -29,13 +29,13 @@ function createFilesystemDataSource(opts) {
|
|
|
29
29
|
}));
|
|
30
30
|
},
|
|
31
31
|
async list(prefix) {
|
|
32
|
-
const full =
|
|
32
|
+
const full = pathFor(prefix);
|
|
33
33
|
const out = [];
|
|
34
34
|
await walk(full, out);
|
|
35
35
|
return out.map((p) => p.slice(root.length + 1));
|
|
36
36
|
},
|
|
37
37
|
async *streamList(prefix) {
|
|
38
|
-
const full =
|
|
38
|
+
const full = pathFor(prefix);
|
|
39
39
|
for await (const p of walkStream(full)) yield p.slice(root.length + 1);
|
|
40
40
|
},
|
|
41
41
|
async head(key) {
|
|
@@ -71,57 +71,6 @@ async function walk(dir, out) {
|
|
|
71
71
|
else out.push(p);
|
|
72
72
|
}
|
|
73
73
|
}
|
|
74
|
-
function watermarkKey(w) {
|
|
75
|
-
return `${w.userId}|${w.siteId ?? ""}|${w.table}`;
|
|
76
|
-
}
|
|
77
|
-
function matchesWatermarkFilter(w, filter) {
|
|
78
|
-
if (w.userId !== filter.userId) return false;
|
|
79
|
-
if (filter.siteId !== void 0 && w.siteId !== filter.siteId) return false;
|
|
80
|
-
if (filter.table !== void 0 && w.table !== filter.table) return false;
|
|
81
|
-
return true;
|
|
82
|
-
}
|
|
83
|
-
function syncStateKey(s) {
|
|
84
|
-
return `${s.userId}|${s.siteId ?? ""}|${s.table}|${s.date}|${inferSearchType(s)}`;
|
|
85
|
-
}
|
|
86
|
-
function matchesSyncStateFilter(s, filter) {
|
|
87
|
-
if (s.userId !== filter.userId) return false;
|
|
88
|
-
if (filter.siteId !== void 0 && s.siteId !== filter.siteId) return false;
|
|
89
|
-
if (filter.table !== void 0 && s.table !== filter.table) return false;
|
|
90
|
-
if (filter.state !== void 0 && s.state !== filter.state) return false;
|
|
91
|
-
if (filter.searchType !== void 0 && inferSearchType(s) !== filter.searchType) return false;
|
|
92
|
-
return true;
|
|
93
|
-
}
|
|
94
|
-
function mergeSyncState(existing, scope, state, detail) {
|
|
95
|
-
const at = detail?.at ?? Date.now();
|
|
96
|
-
const attemptsBump = state === "inflight" ? 1 : 0;
|
|
97
|
-
if (!existing) return {
|
|
98
|
-
userId: scope.userId,
|
|
99
|
-
siteId: scope.siteId,
|
|
100
|
-
table: scope.table,
|
|
101
|
-
date: scope.date,
|
|
102
|
-
state,
|
|
103
|
-
updatedAt: at,
|
|
104
|
-
attempts: attemptsBump,
|
|
105
|
-
error: detail?.error,
|
|
106
|
-
...scope.searchType !== void 0 ? { searchType: scope.searchType } : {}
|
|
107
|
-
};
|
|
108
|
-
return {
|
|
109
|
-
...existing,
|
|
110
|
-
state,
|
|
111
|
-
updatedAt: at,
|
|
112
|
-
attempts: existing.attempts + attemptsBump,
|
|
113
|
-
error: state === "done" ? void 0 : detail?.error ?? existing.error
|
|
114
|
-
};
|
|
115
|
-
}
|
|
116
|
-
function matchesFilter(entry, filter) {
|
|
117
|
-
if (entry.userId !== filter.userId) return false;
|
|
118
|
-
if (filter.siteId !== void 0 && entry.siteId !== filter.siteId) return false;
|
|
119
|
-
if (filter.table !== void 0 && entry.table !== filter.table) return false;
|
|
120
|
-
if (filter.partitions && !filter.partitions.includes(entry.partition)) return false;
|
|
121
|
-
if (filter.tier !== void 0 && inferLegacyTier(entry) !== filter.tier) return false;
|
|
122
|
-
if (filter.searchType !== void 0 && inferSearchType(entry) !== filter.searchType) return false;
|
|
123
|
-
return true;
|
|
124
|
-
}
|
|
125
74
|
function lockFileFor(locksDir, scope) {
|
|
126
75
|
return join(locksDir, `${`${scope.userId}|${scope.siteId ?? ""}|${scope.table}|${scope.partition}`.replace(/[^\w.-]/g, "_")}.lock`);
|
|
127
76
|
}
|
|
@@ -166,30 +115,27 @@ function createFilesystemManifestStore(opts) {
|
|
|
166
115
|
while (queue.length > 0) await queue.shift()().catch(() => {});
|
|
167
116
|
running = false;
|
|
168
117
|
}
|
|
169
|
-
function entryKey(e) {
|
|
170
|
-
return e.objectKey;
|
|
171
|
-
}
|
|
172
118
|
async function registerVersionsImpl(newEntries, superseding) {
|
|
173
119
|
const data = await load();
|
|
174
120
|
const supersededAt = newEntries[0]?.createdAt ?? Date.now();
|
|
175
|
-
const byKey = new Map(data.entries.map((e) => [
|
|
121
|
+
const byKey = new Map(data.entries.map((e) => [manifestEntryKey(e), e]));
|
|
176
122
|
if (superseding) for (const s of superseding) {
|
|
177
|
-
const existing = byKey.get(
|
|
178
|
-
if (existing && existing.retiredAt === void 0) byKey.set(
|
|
123
|
+
const existing = byKey.get(manifestEntryKey(s));
|
|
124
|
+
if (existing && existing.retiredAt === void 0) byKey.set(manifestEntryKey(s), {
|
|
179
125
|
...existing,
|
|
180
126
|
retiredAt: supersededAt
|
|
181
127
|
});
|
|
182
128
|
}
|
|
183
|
-
for (const e of newEntries) byKey.set(
|
|
129
|
+
for (const e of newEntries) byKey.set(manifestEntryKey(e), e);
|
|
184
130
|
data.entries = Array.from(byKey.values());
|
|
185
131
|
await save(data);
|
|
186
132
|
}
|
|
187
133
|
return {
|
|
188
134
|
async listLive(filter) {
|
|
189
|
-
return (await load()).entries.filter((e) => e.retiredAt === void 0 &&
|
|
135
|
+
return (await load()).entries.filter((e) => e.retiredAt === void 0 && matchesManifestEntryFilter(e, filter));
|
|
190
136
|
},
|
|
191
137
|
async listAll(filter) {
|
|
192
|
-
return (await load()).entries.filter((e) =>
|
|
138
|
+
return (await load()).entries.filter((e) => matchesManifestEntryFilter(e, filter));
|
|
193
139
|
},
|
|
194
140
|
async registerVersion(entry, superseding) {
|
|
195
141
|
return enqueue(() => registerVersionsImpl([entry], superseding));
|
|
@@ -203,8 +149,8 @@ function createFilesystemManifestStore(opts) {
|
|
|
203
149
|
async delete(toDelete) {
|
|
204
150
|
return enqueue(async () => {
|
|
205
151
|
const data = await load();
|
|
206
|
-
const toDeleteKeys = new Set(toDelete.map(
|
|
207
|
-
data.entries = data.entries.filter((e) => !toDeleteKeys.has(
|
|
152
|
+
const toDeleteKeys = new Set(toDelete.map(manifestEntryKey));
|
|
153
|
+
data.entries = data.entries.filter((e) => !toDeleteKeys.has(manifestEntryKey(e)));
|
|
208
154
|
await save(data);
|
|
209
155
|
});
|
|
210
156
|
},
|
|
@@ -124,8 +124,11 @@ function naturalKeyFor(table, row) {
|
|
|
124
124
|
}
|
|
125
125
|
function encodeOrderedRows(rows, columns, rowGroupSize) {
|
|
126
126
|
const schema = buildWriteSchema(columns);
|
|
127
|
-
const
|
|
128
|
-
|
|
127
|
+
const codecs = columns.map((col) => ({
|
|
128
|
+
name: col.name,
|
|
129
|
+
isDate: col.type === "DATE",
|
|
130
|
+
type: basicTypeFor(col.type)
|
|
131
|
+
}));
|
|
129
132
|
const columnSpecs = columns.map((col) => ({
|
|
130
133
|
name: col.name,
|
|
131
134
|
nullable: col.nullable,
|
|
@@ -134,10 +137,7 @@ function encodeOrderedRows(rows, columns, rowGroupSize) {
|
|
|
134
137
|
function* coercedRows() {
|
|
135
138
|
for (const r of rows) {
|
|
136
139
|
const out = {};
|
|
137
|
-
for (
|
|
138
|
-
const name = columns[c].name;
|
|
139
|
-
out[name] = isDate[c] ? toEpochDays(r[name]) : coerceValue(r[name], types[c]);
|
|
140
|
-
}
|
|
140
|
+
for (const codec of codecs) out[codec.name] = codec.isDate ? toEpochDays(r[codec.name]) : coerceValue(r[codec.name], codec.type);
|
|
141
141
|
yield out;
|
|
142
142
|
}
|
|
143
143
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { inferSearchType } from "../_chunks/layout.mjs";
|
|
2
2
|
import { engineErrorToException, engineErrors } from "../errors.mjs";
|
|
3
|
+
import { matchesManifestEntryFilter, matchesSyncStateFilter, matchesWatermarkFilter } from "../_chunks/manifest-store-utils.mjs";
|
|
3
4
|
import { err, ok, unwrapResult } from "gscdump/result";
|
|
4
5
|
const SHARD_RE = /^u_[^/]+\/manifest\/(?<siteId>[^/]+)\/(?<table>[^/]+)\/HEAD$/;
|
|
5
6
|
const CAS_BACKOFF_BASE_MS = 5;
|
|
@@ -52,26 +53,6 @@ function shardScopesFromEntries(entries) {
|
|
|
52
53
|
}
|
|
53
54
|
return out;
|
|
54
55
|
}
|
|
55
|
-
function matchesEntryFilter(entry, filter) {
|
|
56
|
-
if (filter.siteId !== void 0 && entry.siteId !== filter.siteId) return false;
|
|
57
|
-
if (filter.table !== void 0 && entry.table !== filter.table) return false;
|
|
58
|
-
if (filter.partitions && !filter.partitions.includes(entry.partition)) return false;
|
|
59
|
-
if (filter.tier !== void 0 && inferLegacyTier(entry) !== filter.tier) return false;
|
|
60
|
-
if (filter.searchType !== void 0 && inferSearchType(entry) !== filter.searchType) return false;
|
|
61
|
-
return true;
|
|
62
|
-
}
|
|
63
|
-
function matchesWatermarkFilter(w, filter) {
|
|
64
|
-
if (filter.siteId !== void 0 && w.siteId !== filter.siteId) return false;
|
|
65
|
-
if (filter.table !== void 0 && w.table !== filter.table) return false;
|
|
66
|
-
return true;
|
|
67
|
-
}
|
|
68
|
-
function matchesSyncStateFilter(s, filter) {
|
|
69
|
-
if (filter.siteId !== void 0 && s.siteId !== filter.siteId) return false;
|
|
70
|
-
if (filter.table !== void 0 && s.table !== filter.table) return false;
|
|
71
|
-
if (filter.state !== void 0 && s.state !== filter.state) return false;
|
|
72
|
-
if (filter.searchType !== void 0 && inferSearchType(s) !== filter.searchType) return false;
|
|
73
|
-
return true;
|
|
74
|
-
}
|
|
75
56
|
function createR2ManifestStore(opts) {
|
|
76
57
|
const { bucket, userId } = opts;
|
|
77
58
|
const newSnapshotId = opts.newSnapshotId ?? defaultSnapshotId;
|
|
@@ -170,13 +151,17 @@ function createR2ManifestStore(opts) {
|
|
|
170
151
|
}];
|
|
171
152
|
return (await listShards()).filter((s) => (filter.siteId === void 0 || s.siteId === filter.siteId) && (filter.table === void 0 || s.table === filter.table));
|
|
172
153
|
}
|
|
154
|
+
function assertScopedUser(got, op) {
|
|
155
|
+
if (got !== userId) throw new Error(`${op}: R2 manifest store is scoped to userId=${userId}, got ${got}`);
|
|
156
|
+
}
|
|
173
157
|
async function readEntriesAcrossShards(filter, includeRetired) {
|
|
158
|
+
assertScopedUser(filter.userId, includeRetired ? "listAll" : "listLive");
|
|
174
159
|
return (await mapWithConcurrency(await shardsForFilter(filter), SHARD_IO_CONCURRENCY, async ({ siteId, table }) => {
|
|
175
160
|
const { snapshot } = await readShard(siteId, table);
|
|
176
161
|
const entries = [];
|
|
177
162
|
for (const entry of snapshot.entries) {
|
|
178
163
|
if (!includeRetired && entry.retiredAt !== void 0) continue;
|
|
179
|
-
if (
|
|
164
|
+
if (matchesManifestEntryFilter(entry, filter, { ignoreUserId: true })) entries.push(entry);
|
|
180
165
|
}
|
|
181
166
|
return entries;
|
|
182
167
|
})).flat();
|
|
@@ -195,6 +180,7 @@ function createR2ManifestStore(opts) {
|
|
|
195
180
|
const supersededAt = newEntries[0]?.createdAt ?? now();
|
|
196
181
|
const byShard = /* @__PURE__ */ new Map();
|
|
197
182
|
function bucket(entry, kind) {
|
|
183
|
+
assertScopedUser(entry.userId, "registerVersions");
|
|
198
184
|
if (entry.siteId === void 0) throw new Error("R2 manifest store requires entries to carry siteId");
|
|
199
185
|
const key = `${entry.siteId}\0${entry.table}`;
|
|
200
186
|
let bag = byShard.get(key);
|
|
@@ -258,14 +244,16 @@ function createR2ManifestStore(opts) {
|
|
|
258
244
|
});
|
|
259
245
|
},
|
|
260
246
|
async getWatermarks(filter) {
|
|
247
|
+
assertScopedUser(filter.userId, "getWatermarks");
|
|
261
248
|
return (await mapWithConcurrency(await shardsForFilter(filter), SHARD_IO_CONCURRENCY, async ({ siteId, table }) => {
|
|
262
249
|
const { snapshot } = await readShard(siteId, table);
|
|
263
250
|
const watermarks = [];
|
|
264
|
-
for (const w of snapshot.watermarks) if (matchesWatermarkFilter(w, filter)) watermarks.push(w);
|
|
251
|
+
for (const w of snapshot.watermarks) if (matchesWatermarkFilter(w, filter, { ignoreUserId: true })) watermarks.push(w);
|
|
265
252
|
return watermarks;
|
|
266
253
|
})).flat();
|
|
267
254
|
},
|
|
268
255
|
async bumpWatermark(scope, date, at) {
|
|
256
|
+
assertScopedUser(scope.userId, "bumpWatermark");
|
|
269
257
|
if (scope.siteId === void 0) throw new Error("R2 manifest store requires watermarks to carry siteId");
|
|
270
258
|
const ts = at ?? now();
|
|
271
259
|
await mutateShard(scope.siteId, scope.table, (snap) => {
|
|
@@ -294,14 +282,16 @@ function createR2ManifestStore(opts) {
|
|
|
294
282
|
});
|
|
295
283
|
},
|
|
296
284
|
async getSyncStates(filter) {
|
|
285
|
+
assertScopedUser(filter.userId, "getSyncStates");
|
|
297
286
|
return (await mapWithConcurrency(await shardsForFilter(filter), SHARD_IO_CONCURRENCY, async ({ siteId, table }) => {
|
|
298
287
|
const { snapshot } = await readShard(siteId, table);
|
|
299
288
|
const states = [];
|
|
300
|
-
for (const s of snapshot.syncStates) if (matchesSyncStateFilter(s, filter)) states.push(s);
|
|
289
|
+
for (const s of snapshot.syncStates) if (matchesSyncStateFilter(s, filter, { ignoreUserId: true })) states.push(s);
|
|
301
290
|
return states;
|
|
302
291
|
})).flat();
|
|
303
292
|
},
|
|
304
293
|
async setSyncState(scope, state, detail) {
|
|
294
|
+
assertScopedUser(scope.userId, "setSyncState");
|
|
305
295
|
if (scope.siteId === void 0) throw new Error("R2 manifest store requires sync states to carry siteId");
|
|
306
296
|
const at = detail?.at ?? now();
|
|
307
297
|
const scopeSearchType = inferSearchType(scope);
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gscdump/engine",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.33.
|
|
4
|
+
"version": "0.33.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,8 +181,8 @@
|
|
|
181
181
|
"dependencies": {
|
|
182
182
|
"drizzle-orm": "1.0.0-rc.3",
|
|
183
183
|
"proper-lockfile": "^4.1.2",
|
|
184
|
-
"@gscdump/contracts": "0.33.
|
|
185
|
-
"gscdump": "0.33.
|
|
184
|
+
"@gscdump/contracts": "0.33.3",
|
|
185
|
+
"gscdump": "0.33.3"
|
|
186
186
|
},
|
|
187
187
|
"devDependencies": {
|
|
188
188
|
"@duckdb/duckdb-wasm": "^1.32.0",
|