@gscdump/lakehouse 0.37.3 → 0.37.5

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.
@@ -11,6 +11,8 @@ interface CatalogCache {
11
11
  * inline so it is never cut off when the response returns.
12
12
  */
13
13
  defer?: (write: Promise<unknown>) => void;
14
+ /** Optional warning sink for best-effort cache driver failures. */
15
+ onError?: (operation: 'get' | 'set' | 'remove', key: string, error: unknown) => void;
14
16
  }
15
17
  /**
16
18
  * Read a cached value. Returns `undefined` on a miss, an expired entry, a
@@ -24,8 +26,8 @@ declare function cacheGet<T>(cache: CatalogCache, key: string, now: number): Pro
24
26
  * Returns the write promise. With a `defer` hook the write is handed to the
25
27
  * hook and a resolved promise is returned (the response is not blocked on it);
26
28
  * without one the write promise is returned for the caller to await, so a
27
- * fire-and-forget put is never silently dropped. Driver errors are swallowed —
28
- * a failed cache write must not fail the read.
29
+ * fire-and-forget put is never silently dropped. Driver errors are reported
30
+ * through `onError` (or `console.warn`) but do not fail the read.
29
31
  */
30
32
  declare function cachePut<T>(cache: CatalogCache, key: string, value: T, ttlMs: number, now: number): Promise<void>;
31
33
  /** Minimal shape of an icebird manifest-list `partitions` field-summary. */
@@ -11,8 +11,19 @@ function encodeJsonBigintSafe(value) {
11
11
  function coerceBigIntToNumber(value) {
12
12
  return typeof value === "bigint" ? Number(value) : value;
13
13
  }
14
+ function reportCatalogCacheError(cache, operation, key, error) {
15
+ try {
16
+ if (cache.onError) cache.onError(operation, key, error);
17
+ else console.warn(`[gscdump/lakehouse] cache ${operation} failed for ${key}`, error);
18
+ } catch (reportError) {
19
+ console.warn(`[gscdump/lakehouse] cache error reporter failed during ${operation} for ${key}`, reportError);
20
+ }
21
+ }
14
22
  async function cacheGet(cache, key, now) {
15
- const boxed = await cache.storage.getItem(key).catch(() => null);
23
+ const boxed = await cache.storage.getItem(key).catch((error) => {
24
+ reportCatalogCacheError(cache, "get", key, error);
25
+ return null;
26
+ });
16
27
  if (!boxed || typeof boxed.exp !== "number" || boxed.exp <= now) return void 0;
17
28
  return boxed.v;
18
29
  }
@@ -21,7 +32,9 @@ function cachePut(cache, key, value, ttlMs, now) {
21
32
  v: value,
22
33
  exp: now + ttlMs
23
34
  };
24
- const write = cache.storage.setItem(key, boxed, { ttl: Math.ceil(ttlMs / 1e3) }).catch(() => {});
35
+ const write = cache.storage.setItem(key, boxed, { ttl: Math.ceil(ttlMs / 1e3) }).catch((error) => {
36
+ reportCatalogCacheError(cache, "set", key, error);
37
+ });
25
38
  if (cache.defer) {
26
39
  cache.defer(write);
27
40
  return Promise.resolve();
@@ -257,7 +270,10 @@ function snapshotRefKey(scope, namespace, table) {
257
270
  return `lh-snapref\0${scope}\0${namespace}\0${table}`;
258
271
  }
259
272
  async function invalidateSnapshotRef(cache, namespace, table, cacheScope = "") {
260
- await cache.storage.removeItem(snapshotRefKey(cacheScope, namespace, table)).catch(() => {});
273
+ const key = snapshotRefKey(cacheScope, namespace, table);
274
+ await cache.storage.removeItem(key).catch((error) => {
275
+ reportCatalogCacheError(cache, "remove", key, error);
276
+ });
261
277
  }
262
278
  function metadataRefKey(scope, namespace, table, snapshotId) {
263
279
  return `lh-snapmeta\0${scope}\0${namespace}\0${table}\0${snapshotId}`;
package/dist/index.d.mts CHANGED
@@ -192,6 +192,14 @@ interface RunPyIcebergWriterOptions {
192
192
  processErrorAsParseFailure?: boolean;
193
193
  rejectOnProcessError?: boolean;
194
194
  }
195
+ /**
196
+ * @deprecated Import the engine-owned PyIceberg runtime instead. Retained as a
197
+ * compatibility shim for consumers of `@gscdump/lakehouse` 0.x.
198
+ */
195
199
  declare function resolvePyIcebergPython(override?: string): string;
200
+ /**
201
+ * @deprecated Import the engine-owned PyIceberg runtime instead. Retained as a
202
+ * compatibility shim for consumers of `@gscdump/lakehouse` 0.x.
203
+ */
196
204
  declare function runPyIcebergWriter<T extends PyIcebergWriterResult>(options: RunPyIcebergWriterOptions): Promise<T>;
197
205
  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, bigintJsonReplacer, buildManifestPartitionFilter, cacheGet, cachePut, catalogCacheScope, coerceBigIntToNumber, connectIcebergCatalog, defineIcebergDataset, deriveTableSpec, dropIcebergTables, encodeJsonBigintSafe, ensureIcebergNamespace, invalidateSnapshotRef, listIcebergTables, resolveIcebergDataFiles, resolvePyIcebergPython, runPyIcebergWriter, stringifyBigintSafe, toIcebergDayCount };
package/dist/index.mjs CHANGED
@@ -1,6 +1,5 @@
1
1
  import { ICEBERG_TYPE_MAP, bigintJsonReplacer, buildManifestPartitionFilter, cacheGet, cachePut, catalogCacheScope, coerceBigIntToNumber, connectIcebergCatalog, dropIcebergTables, encodeJsonBigintSafe, ensureIcebergNamespace, icebergAppendRetrying, invalidateSnapshotRef, listIcebergTables, resolveIcebergDataFiles, stringifyBigintSafe } from "./_chunks/catalog.mjs";
2
2
  import { icebergCreateTable } from "./_chunks/libs/icebird.mjs";
3
- import process from "node:process";
4
3
  const INT32_MIN = -2147483648;
5
4
  const INT32_MAX = 2147483647;
6
5
  const DAY_MILLIS = 864e5;
@@ -322,11 +321,15 @@ function defineIcebergDataset(def) {
322
321
  resolveDataFiles
323
322
  };
324
323
  }
324
+ function importRuntimeModule(specifier) {
325
+ return import(specifier);
326
+ }
325
327
  function resolvePyIcebergPython(override) {
326
- return override ?? process.env["GSCDUMP_ICEBERG_PYTHON"] ?? "python3";
328
+ const env = Reflect.get(globalThis, "process")?.env;
329
+ return override ?? env?.["GSCDUMP_ICEBERG_PYTHON"] ?? "python3";
327
330
  }
328
331
  async function runPyIcebergWriter(options) {
329
- const { execFile } = await import("node:child_process");
332
+ const { execFile } = await importRuntimeModule("node:child_process");
330
333
  return new Promise((resolve, reject) => {
331
334
  execFile(options.python, [options.script], { maxBuffer: 64 * 1024 * 1024 }, (err, stdout, stderr) => {
332
335
  let parsed;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@gscdump/lakehouse",
3
3
  "type": "module",
4
- "version": "0.37.3",
4
+ "version": "0.37.5",
5
5
  "description": "Dataset-agnostic Iceberg lakehouse layer + dataset registry for R2 Data Catalog producers (ADR-0021).",
6
6
  "author": {
7
7
  "name": "Harlan Wilton",