@gscdump/lakehouse 0.35.5 → 0.35.7
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/catalog.d.mts +27 -1
- package/dist/_chunks/catalog.mjs +23 -14
- package/dist/index.d.mts +2 -2
- package/dist/index.mjs +2 -2
- package/package.json +1 -1
|
@@ -121,6 +121,15 @@ interface IcebergConnection {
|
|
|
121
121
|
resolver: ReturnType<typeof cachingResolver>;
|
|
122
122
|
/** The namespace the dataset's table lives under. */
|
|
123
123
|
namespace: string;
|
|
124
|
+
/**
|
|
125
|
+
* Catalog identity baked into every cross-isolate cache key. Namespaces are
|
|
126
|
+
* NOT unique across catalogs (every per-team catalog uses the same 'gsc'
|
|
127
|
+
* namespace) while deployments share one KV, so a key of (namespace, table)
|
|
128
|
+
* alone lets one team's snapshot pointer/metadata poison every other team's
|
|
129
|
+
* reads. Set by {@link connectIcebergCatalog}; hand-built connections may
|
|
130
|
+
* omit it ONLY when their cache is not shared across catalogs.
|
|
131
|
+
*/
|
|
132
|
+
cacheScope?: string;
|
|
124
133
|
}
|
|
125
134
|
declare const ICEBERG_TYPE_MAP: Record<IcebergColumnType, IcebergPrimitiveType>;
|
|
126
135
|
/** Options for {@link connectIcebergCatalog}. */
|
|
@@ -139,6 +148,12 @@ interface ConnectIcebergOptions {
|
|
|
139
148
|
* `fetch`, no node builtins.
|
|
140
149
|
*/
|
|
141
150
|
declare function connectIcebergCatalog(config: IcebergCatalogConfig, opts?: ConnectIcebergOptions): Promise<IcebergConnection>;
|
|
151
|
+
/**
|
|
152
|
+
* The catalog-identity component of every cross-isolate cache key. Exported so
|
|
153
|
+
* write paths that only hold the config (not a connection) can invalidate the
|
|
154
|
+
* exact keys readers populate — see {@link invalidateSnapshotRef}.
|
|
155
|
+
*/
|
|
156
|
+
declare function catalogCacheScope(config: Pick<IcebergCatalogConfig, 'catalogUri' | 'warehouse'>): string;
|
|
142
157
|
/**
|
|
143
158
|
* Ensure the catalog namespace exists. Idempotent — an "already exists"
|
|
144
159
|
* response from the REST catalog is swallowed.
|
|
@@ -236,6 +251,17 @@ interface ResolveIcebergDataFilesOptions {
|
|
|
236
251
|
clock?: () => number;
|
|
237
252
|
profiler?: QueryProfiler;
|
|
238
253
|
}
|
|
254
|
+
/**
|
|
255
|
+
* Drop the cached snapshot pointer for `(namespace, table)` so the next read
|
|
256
|
+
* re-loads the table and sees the just-committed snapshot immediately instead
|
|
257
|
+
* of after {@link SNAPSHOT_REF_TTL_MS} (writers call this post-commit; without
|
|
258
|
+
* it worst-case reader staleness is TTL + the downstream ref's own TTL). Only
|
|
259
|
+
* the snapshot REF is dropped: `lh-snapmeta`/`lh-files` entries are keyed by
|
|
260
|
+
* snapshotId, so stale ones age out harmlessly and fresh ones rebuild on the
|
|
261
|
+
* next read. Best-effort like every cache path here — a failed delete only
|
|
262
|
+
* means TTL-bounded staleness, never an error.
|
|
263
|
+
*/
|
|
264
|
+
declare function invalidateSnapshotRef(cache: CatalogCache, namespace: string, table: string, cacheScope?: string): Promise<void>;
|
|
239
265
|
/**
|
|
240
266
|
* List the parquet data files in the current snapshot of `table`, filtered to
|
|
241
267
|
* one partition slice (`matches` + `range`). Generic over the partition spec —
|
|
@@ -243,4 +269,4 @@ interface ResolveIcebergDataFilesOptions {
|
|
|
243
269
|
* the def's own spec + identity/dims values.
|
|
244
270
|
*/
|
|
245
271
|
declare function resolveIcebergDataFiles(conn: IcebergConnection, opts: ResolveIcebergDataFilesOptions): Promise<IcebergListedDataFile[]>;
|
|
246
|
-
export { CatalogCache, CommitRetryOptions, ConnectIcebergOptions, ICEBERG_TYPE_MAP, IcebergCatalogConfig, IcebergConnection, IcebergFieldSummary, IcebergListedDataFile, IcebergPartitionSpec, IcebergPartitionSpecField, IcebergPrimitiveType, IcebergSchema, IcebergSchemaField, IcebergSortOrder, IcebergSortOrderField, IcebergTableOpResult, ManifestPartitionFilter, PartitionValueMatch, QueryProfiler, ResolveIcebergDataFilesOptions, buildManifestPartitionFilter, cacheGet, cachePut, connectIcebergCatalog, dropIcebergTables, ensureIcebergNamespace, icebergAppendRetrying, isCommitRateLimited, listIcebergTables, resolveIcebergDataFiles };
|
|
272
|
+
export { CatalogCache, CommitRetryOptions, ConnectIcebergOptions, ICEBERG_TYPE_MAP, IcebergCatalogConfig, IcebergConnection, IcebergFieldSummary, IcebergListedDataFile, IcebergPartitionSpec, IcebergPartitionSpecField, IcebergPrimitiveType, IcebergSchema, IcebergSchemaField, IcebergSortOrder, IcebergSortOrderField, IcebergTableOpResult, ManifestPartitionFilter, PartitionValueMatch, QueryProfiler, ResolveIcebergDataFilesOptions, buildManifestPartitionFilter, cacheGet, cachePut, catalogCacheScope, connectIcebergCatalog, dropIcebergTables, ensureIcebergNamespace, icebergAppendRetrying, invalidateSnapshotRef, isCommitRateLimited, listIcebergTables, resolveIcebergDataFiles };
|
package/dist/_chunks/catalog.mjs
CHANGED
|
@@ -116,9 +116,13 @@ async function connectIcebergCatalog(config, opts = {}) {
|
|
|
116
116
|
return {
|
|
117
117
|
catalog,
|
|
118
118
|
resolver,
|
|
119
|
-
namespace: config.namespace
|
|
119
|
+
namespace: config.namespace,
|
|
120
|
+
cacheScope: catalogCacheScope(config)
|
|
120
121
|
};
|
|
121
122
|
}
|
|
123
|
+
function catalogCacheScope(config) {
|
|
124
|
+
return `${config.catalogUri}\0${config.warehouse}`;
|
|
125
|
+
}
|
|
122
126
|
async function ensureIcebergNamespace(conn) {
|
|
123
127
|
await restCatalogCreateNamespace(conn.catalog, { namespace: conn.namespace }).catch(() => {});
|
|
124
128
|
}
|
|
@@ -201,14 +205,17 @@ const SNAPSHOT_REF_TTL_MS = 1800 * 1e3;
|
|
|
201
205
|
const RESOLVED_FILES_TTL_MS = 1440 * 60 * 1e3;
|
|
202
206
|
const METADATA_TTL_MS = 1440 * 60 * 1e3;
|
|
203
207
|
const MAX_CACHED_METADATA_BYTES = 2 * 1024 * 1024;
|
|
204
|
-
function snapshotRefKey(namespace, table) {
|
|
205
|
-
return `lh-snapref\0${namespace}\0${table}`;
|
|
208
|
+
function snapshotRefKey(scope, namespace, table) {
|
|
209
|
+
return `lh-snapref\0${scope}\0${namespace}\0${table}`;
|
|
210
|
+
}
|
|
211
|
+
async function invalidateSnapshotRef(cache, namespace, table, cacheScope = "") {
|
|
212
|
+
await cache.storage.removeItem(snapshotRefKey(cacheScope, namespace, table)).catch(() => {});
|
|
206
213
|
}
|
|
207
|
-
function metadataRefKey(namespace, table, snapshotId) {
|
|
208
|
-
return `lh-snapmeta\0${namespace}\0${table}\0${snapshotId}`;
|
|
214
|
+
function metadataRefKey(scope, namespace, table, snapshotId) {
|
|
215
|
+
return `lh-snapmeta\0${scope}\0${namespace}\0${table}\0${snapshotId}`;
|
|
209
216
|
}
|
|
210
|
-
function resolvedFilesKey(namespace, table, snapshotId, matches, wantedMonths) {
|
|
211
|
-
return `lh-files\0${namespace}\0${table}\0${snapshotId}\0${[...matches].map((m) => `${m.field}=${m.value}`).sort().join(",")}\0${[...wantedMonths].sort((a, b) => a - b).join(",")}`;
|
|
217
|
+
function resolvedFilesKey(scope, namespace, table, snapshotId, matches, wantedMonths) {
|
|
218
|
+
return `lh-files\0${scope}\0${namespace}\0${table}\0${snapshotId}\0${[...matches].map((m) => `${m.field}=${m.value}`).sort().join(",")}\0${[...wantedMonths].sort((a, b) => a - b).join(",")}`;
|
|
212
219
|
}
|
|
213
220
|
function monthsInRange(range) {
|
|
214
221
|
const [sy, sm] = range.start.split("-").map(Number);
|
|
@@ -237,8 +244,9 @@ function stripBucket(filePath) {
|
|
|
237
244
|
return slash >= 0 ? rest.slice(slash + 1) : rest;
|
|
238
245
|
}
|
|
239
246
|
async function loadSnapshotId(conn, namespace, table, cache, now) {
|
|
247
|
+
const scope = conn.cacheScope ?? "";
|
|
240
248
|
if (cache) {
|
|
241
|
-
const cached = await cacheGet(cache, snapshotRefKey(namespace, table), now);
|
|
249
|
+
const cached = await cacheGet(cache, snapshotRefKey(scope, namespace, table), now);
|
|
242
250
|
if (cached !== void 0) return {
|
|
243
251
|
snapshotId: cached,
|
|
244
252
|
metadata: null
|
|
@@ -251,9 +259,9 @@ async function loadSnapshotId(conn, namespace, table, cache, now) {
|
|
|
251
259
|
const raw = metadata["current-snapshot-id"];
|
|
252
260
|
const snapshotId = raw == null ? null : String(raw);
|
|
253
261
|
if (cache) {
|
|
254
|
-
await cachePut(cache, snapshotRefKey(namespace, table), snapshotId, SNAPSHOT_REF_TTL_MS, now);
|
|
262
|
+
await cachePut(cache, snapshotRefKey(scope, namespace, table), snapshotId, SNAPSHOT_REF_TTL_MS, now);
|
|
255
263
|
if (snapshotId != null) {
|
|
256
|
-
if (JSON.stringify(metadata).length <= MAX_CACHED_METADATA_BYTES) await cachePut(cache, metadataRefKey(namespace, table, snapshotId), metadata, METADATA_TTL_MS, now);
|
|
264
|
+
if (JSON.stringify(metadata).length <= MAX_CACHED_METADATA_BYTES) await cachePut(cache, metadataRefKey(scope, namespace, table, snapshotId), metadata, METADATA_TTL_MS, now);
|
|
257
265
|
}
|
|
258
266
|
}
|
|
259
267
|
return {
|
|
@@ -270,7 +278,8 @@ async function resolveIcebergDataFiles(conn, opts) {
|
|
|
270
278
|
let { snapshotId, metadata } = await loadSnapshotId(conn, namespace, table, opts.cache, now);
|
|
271
279
|
endSnapshot?.({ cached: metadata == null && snapshotId != null });
|
|
272
280
|
if (snapshotId == null) return [];
|
|
273
|
-
const
|
|
281
|
+
const scope = conn.cacheScope ?? "";
|
|
282
|
+
const filesKey = resolvedFilesKey(scope, namespace, table, snapshotId, opts.matches, wantedMonths);
|
|
274
283
|
if (opts.cache) {
|
|
275
284
|
const endCache = profiler?.start("iceberg.cache");
|
|
276
285
|
const cached = await cacheGet(opts.cache, filesKey, now);
|
|
@@ -278,7 +287,7 @@ async function resolveIcebergDataFiles(conn, opts) {
|
|
|
278
287
|
if (cached !== void 0) return cached;
|
|
279
288
|
}
|
|
280
289
|
if (!metadata && opts.cache) {
|
|
281
|
-
const cachedMeta = await cacheGet(opts.cache, metadataRefKey(namespace, table, snapshotId), now);
|
|
290
|
+
const cachedMeta = await cacheGet(opts.cache, metadataRefKey(scope, namespace, table, snapshotId), now);
|
|
282
291
|
if (cachedMeta != null) metadata = cachedMeta;
|
|
283
292
|
}
|
|
284
293
|
if (!metadata) {
|
|
@@ -323,9 +332,9 @@ async function resolveIcebergDataFiles(conn, opts) {
|
|
|
323
332
|
files: out.length
|
|
324
333
|
});
|
|
325
334
|
if (opts.cache) {
|
|
326
|
-
const freshKey = resolvedFilesKey(namespace, table, snapshotId, opts.matches, wantedMonths);
|
|
335
|
+
const freshKey = resolvedFilesKey(scope, namespace, table, snapshotId, opts.matches, wantedMonths);
|
|
327
336
|
await cachePut(opts.cache, freshKey, out, RESOLVED_FILES_TTL_MS, now);
|
|
328
337
|
}
|
|
329
338
|
return out;
|
|
330
339
|
}
|
|
331
|
-
export { ICEBERG_TYPE_MAP, buildManifestPartitionFilter, cacheGet, cachePut, connectIcebergCatalog, dropIcebergTables, ensureIcebergNamespace, icebergAppendRetrying, isCommitRateLimited, listIcebergTables, resolveIcebergDataFiles };
|
|
340
|
+
export { ICEBERG_TYPE_MAP, buildManifestPartitionFilter, cacheGet, cachePut, catalogCacheScope, connectIcebergCatalog, dropIcebergTables, ensureIcebergNamespace, icebergAppendRetrying, invalidateSnapshotRef, isCommitRateLimited, listIcebergTables, resolveIcebergDataFiles };
|
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CatalogCache, CommitRetryOptions, ConnectIcebergOptions, ICEBERG_TYPE_MAP, IcebergCatalogConfig, IcebergConnection, IcebergFieldSummary, IcebergListedDataFile, IcebergPartitionSpec, IcebergPartitionSpecField, IcebergPrimitiveType, IcebergSchema, IcebergSchemaField, IcebergSortOrder, IcebergSortOrderField, IcebergTableOpResult, ManifestPartitionFilter, PartitionValueMatch, QueryProfiler, ResolveIcebergDataFilesOptions, buildManifestPartitionFilter, cacheGet, cachePut, connectIcebergCatalog, dropIcebergTables, ensureIcebergNamespace, listIcebergTables, resolveIcebergDataFiles } from "./_chunks/catalog.mjs";
|
|
1
|
+
import { CatalogCache, CommitRetryOptions, ConnectIcebergOptions, ICEBERG_TYPE_MAP, IcebergCatalogConfig, IcebergConnection, IcebergFieldSummary, IcebergListedDataFile, IcebergPartitionSpec, IcebergPartitionSpecField, IcebergPrimitiveType, IcebergSchema, IcebergSchemaField, IcebergSortOrder, IcebergSortOrderField, IcebergTableOpResult, ManifestPartitionFilter, PartitionValueMatch, QueryProfiler, ResolveIcebergDataFilesOptions, buildManifestPartitionFilter, cacheGet, cachePut, catalogCacheScope, connectIcebergCatalog, dropIcebergTables, ensureIcebergNamespace, invalidateSnapshotRef, listIcebergTables, resolveIcebergDataFiles } from "./_chunks/catalog.mjs";
|
|
2
2
|
import { DEFAULT_PARTITION_KEY_ENCODING, IcebergColumn, IcebergColumnType, IcebergPartitionField, IcebergPartitionTransform, IcebergS3Config, IcebergTableSpec, PartitionKeyEncoding } from "./_chunks/schema.mjs";
|
|
3
3
|
/**
|
|
4
4
|
* Closed identity shapes (ADR-0021 amendments 2 + 4). `'site-int'` is the
|
|
@@ -156,4 +156,4 @@ interface RunPyIcebergWriterOptions {
|
|
|
156
156
|
}
|
|
157
157
|
declare function resolvePyIcebergPython(override?: string): string;
|
|
158
158
|
declare function runPyIcebergWriter<T extends PyIcebergWriterResult>(options: RunPyIcebergWriterOptions): Promise<T>;
|
|
159
|
-
export { type AppendCommitOptions, type AppendResult, type AppendSink, type AppendSinkCloseResult, type AppendSinkOptions, type CatalogCache, type CommitRetryOptions, type ConnectIcebergOptions, DEFAULT_PARTITION_KEY_ENCODING, type DatasetDim, type DatasetIdentity, ICEBERG_TYPE_MAP, type IcebergCatalogConfig, type IcebergColumn, type IcebergColumnType, type IcebergConnection, type IcebergDataset, type IcebergDatasetColumnDef, type IcebergDatasetDef, type IcebergDatasetLedger, type IcebergFieldSummary, type IcebergListedDataFile, type IcebergPartitionField, type IcebergPartitionSpec, type IcebergPartitionSpecField, type IcebergPartitionTransform, type IcebergPrimitiveType, type IcebergS3Config, type IcebergSchema, type IcebergSchemaField, type IcebergSortOrder, type IcebergSortOrderField, type IcebergTableOpResult, type IcebergTableSpec, type ManifestPartitionFilter, type PartitionKeyEncoding, type PartitionValueMatch, type PyIcebergWriterResult, type QueryProfiler, type ResolveDataFilesOptions, type ResolveIcebergDataFilesOptions, type RunPyIcebergWriterOptions, buildManifestPartitionFilter, cacheGet, cachePut, connectIcebergCatalog, defineIcebergDataset, deriveTableSpec, dropIcebergTables, ensureIcebergNamespace, listIcebergTables, resolveIcebergDataFiles, resolvePyIcebergPython, runPyIcebergWriter, toIcebergDayCount };
|
|
159
|
+
export { type AppendCommitOptions, type AppendResult, type AppendSink, type AppendSinkCloseResult, type AppendSinkOptions, type CatalogCache, type CommitRetryOptions, type ConnectIcebergOptions, DEFAULT_PARTITION_KEY_ENCODING, type DatasetDim, type DatasetIdentity, ICEBERG_TYPE_MAP, type IcebergCatalogConfig, type IcebergColumn, type IcebergColumnType, type IcebergConnection, type IcebergDataset, type IcebergDatasetColumnDef, type IcebergDatasetDef, type IcebergDatasetLedger, type IcebergFieldSummary, type IcebergListedDataFile, type IcebergPartitionField, type IcebergPartitionSpec, type IcebergPartitionSpecField, type IcebergPartitionTransform, type IcebergPrimitiveType, type IcebergS3Config, type IcebergSchema, type IcebergSchemaField, type IcebergSortOrder, type IcebergSortOrderField, type IcebergTableOpResult, type IcebergTableSpec, type ManifestPartitionFilter, type PartitionKeyEncoding, type PartitionValueMatch, type PyIcebergWriterResult, type QueryProfiler, type ResolveDataFilesOptions, type ResolveIcebergDataFilesOptions, type RunPyIcebergWriterOptions, buildManifestPartitionFilter, cacheGet, cachePut, catalogCacheScope, connectIcebergCatalog, defineIcebergDataset, deriveTableSpec, dropIcebergTables, ensureIcebergNamespace, invalidateSnapshotRef, listIcebergTables, resolveIcebergDataFiles, resolvePyIcebergPython, runPyIcebergWriter, toIcebergDayCount };
|
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { icebergCreateTable } from "./_chunks/libs/icebird.mjs";
|
|
2
|
-
import { ICEBERG_TYPE_MAP, buildManifestPartitionFilter, cacheGet, cachePut, connectIcebergCatalog, dropIcebergTables, ensureIcebergNamespace, icebergAppendRetrying, listIcebergTables, resolveIcebergDataFiles } from "./_chunks/catalog.mjs";
|
|
2
|
+
import { ICEBERG_TYPE_MAP, buildManifestPartitionFilter, cacheGet, cachePut, catalogCacheScope, connectIcebergCatalog, dropIcebergTables, ensureIcebergNamespace, icebergAppendRetrying, invalidateSnapshotRef, listIcebergTables, resolveIcebergDataFiles } from "./_chunks/catalog.mjs";
|
|
3
3
|
import process from "node:process";
|
|
4
4
|
const INT32_MIN = -2147483648;
|
|
5
5
|
const INT32_MAX = 2147483647;
|
|
@@ -353,4 +353,4 @@ async function runPyIcebergWriter(options) {
|
|
|
353
353
|
});
|
|
354
354
|
}
|
|
355
355
|
const DEFAULT_PARTITION_KEY_ENCODING = "int";
|
|
356
|
-
export { DEFAULT_PARTITION_KEY_ENCODING, ICEBERG_TYPE_MAP, buildManifestPartitionFilter, cacheGet, cachePut, connectIcebergCatalog, defineIcebergDataset, deriveTableSpec, dropIcebergTables, ensureIcebergNamespace, listIcebergTables, resolveIcebergDataFiles, resolvePyIcebergPython, runPyIcebergWriter, toIcebergDayCount };
|
|
356
|
+
export { DEFAULT_PARTITION_KEY_ENCODING, ICEBERG_TYPE_MAP, buildManifestPartitionFilter, cacheGet, cachePut, catalogCacheScope, connectIcebergCatalog, defineIcebergDataset, deriveTableSpec, dropIcebergTables, ensureIcebergNamespace, invalidateSnapshotRef, listIcebergTables, resolveIcebergDataFiles, resolvePyIcebergPython, runPyIcebergWriter, toIcebergDayCount };
|
package/package.json
CHANGED