@gscdump/lakehouse 0.36.4 → 0.37.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/_chunks/catalog.mjs +14 -2
- package/dist/_chunks/libs/icebird.mjs +1 -1
- package/dist/index.d.mts +39 -1
- package/dist/index.mjs +3 -6
- package/dist/unsafe-raw.mjs +1 -1
- package/package.json +2 -2
package/dist/_chunks/catalog.mjs
CHANGED
|
@@ -1,4 +1,16 @@
|
|
|
1
1
|
import { cachingResolver, icebergAppend, icebergDropTable, icebergManifests, restCatalogConnect, restCatalogCreateNamespace, restCatalogListTables, restCatalogLoadTable, s3SignedResolver } from "./libs/icebird.mjs";
|
|
2
|
+
function bigintJsonReplacer(_key, value) {
|
|
3
|
+
return typeof value === "bigint" ? value.toString() : value;
|
|
4
|
+
}
|
|
5
|
+
function stringifyBigintSafe(value, space) {
|
|
6
|
+
return JSON.stringify(value, bigintJsonReplacer, space);
|
|
7
|
+
}
|
|
8
|
+
function encodeJsonBigintSafe(value) {
|
|
9
|
+
return new TextEncoder().encode(stringifyBigintSafe(value));
|
|
10
|
+
}
|
|
11
|
+
function coerceBigIntToNumber(value) {
|
|
12
|
+
return typeof value === "bigint" ? Number(value) : value;
|
|
13
|
+
}
|
|
2
14
|
async function cacheGet(cache, key, now) {
|
|
3
15
|
const boxed = await cache.storage.getItem(key).catch(() => null);
|
|
4
16
|
if (!boxed || typeof boxed.exp !== "number" || boxed.exp <= now) return void 0;
|
|
@@ -297,7 +309,7 @@ async function loadSnapshotId(conn, namespace, table, cache, now) {
|
|
|
297
309
|
if (cache) {
|
|
298
310
|
await cachePut(cache, snapshotRefKey(scope, namespace, table), snapshotId, SNAPSHOT_REF_TTL_MS, now);
|
|
299
311
|
if (snapshotId != null) {
|
|
300
|
-
if (
|
|
312
|
+
if (stringifyBigintSafe(metadata).length <= MAX_CACHED_METADATA_BYTES) await cachePut(cache, metadataRefKey(scope, namespace, table, snapshotId), metadata, METADATA_TTL_MS, now);
|
|
301
313
|
}
|
|
302
314
|
}
|
|
303
315
|
return {
|
|
@@ -373,4 +385,4 @@ async function resolveIcebergDataFiles(conn, opts) {
|
|
|
373
385
|
}
|
|
374
386
|
return out;
|
|
375
387
|
}
|
|
376
|
-
export { ICEBERG_TYPE_MAP, buildManifestPartitionFilter, cacheGet, cachePut, catalogCacheScope, connectIcebergCatalog, dropIcebergTables, ensureIcebergNamespace, icebergAppendRetrying, invalidateSnapshotRef, isCommitRateLimited, listIcebergTables, resolveIcebergDataFiles };
|
|
388
|
+
export { ICEBERG_TYPE_MAP, bigintJsonReplacer, buildManifestPartitionFilter, cacheGet, cachePut, catalogCacheScope, coerceBigIntToNumber, connectIcebergCatalog, dropIcebergTables, encodeJsonBigintSafe, ensureIcebergNamespace, icebergAppendRetrying, invalidateSnapshotRef, isCommitRateLimited, listIcebergTables, resolveIcebergDataFiles, stringifyBigintSafe };
|
|
@@ -527,7 +527,7 @@ function icebergLatestVersion({ tableUrl, resolver, lister }) {
|
|
|
527
527
|
return versions[versions.length - 1];
|
|
528
528
|
});
|
|
529
529
|
}).catch((err) => {
|
|
530
|
-
throw new Error(`failed to determine latest iceberg version: ${err.message}`);
|
|
530
|
+
throw new Error(`failed to determine latest iceberg version of ${tableUrl}: ${err.message}`);
|
|
531
531
|
});
|
|
532
532
|
}
|
|
533
533
|
async function resolveMetadata({ tableUrl, metadataFileName, resolver, lister }) {
|
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,43 @@
|
|
|
1
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
|
+
/**
|
|
4
|
+
* BigInt at JSON boundaries — the single place this policy lives.
|
|
5
|
+
*
|
|
6
|
+
* int64 reaches serialization from two origins:
|
|
7
|
+
* 1. DuckDB `SUM`/`COUNT` aggregates — already coerced to `number` at the
|
|
8
|
+
* source-factory boundary (`@gscdump/engine` `coerceRows`), so rows are
|
|
9
|
+
* BigInt-free by the time they cross the query boundary.
|
|
10
|
+
* 2. icebird / REST-catalog metadata (`current-snapshot-id`, `sequence-number`,
|
|
11
|
+
* `snapshot-id`) and other identity ids — these never pass through a source,
|
|
12
|
+
* so they arrive at envelope / cache / log serializers still as BigInt.
|
|
13
|
+
*
|
|
14
|
+
* A plain `JSON.stringify` throws `Do not know how to serialize a BigInt`, which
|
|
15
|
+
* is how a stray identity int64 turns into a request 500. Any boundary that can
|
|
16
|
+
* see origin (2) must serialize through here.
|
|
17
|
+
*
|
|
18
|
+
* TWO policies, because the correct target type depends on what the value is:
|
|
19
|
+
*
|
|
20
|
+
* - Identity / precision values (snapshot ids, large row ids) can exceed 2^53
|
|
21
|
+
* and must round-trip losslessly → serialize as a decimal STRING. Use
|
|
22
|
+
* {@link stringifyBigintSafe} / {@link bigintJsonReplacer} / {@link encodeJsonBigintSafe}
|
|
23
|
+
* for storage / transport / log serialization. Where values are already
|
|
24
|
+
* number-coerced (origin 1), the replacer is a no-op backstop.
|
|
25
|
+
*
|
|
26
|
+
* - Analytics aggregates that you want as real numbers downstream → coerce with
|
|
27
|
+
* {@link coerceBigIntToNumber}. Lossy above 2^53 by design; click / impression
|
|
28
|
+
* columns never reach that range. This is the scalar behind engine `coerceRows`.
|
|
29
|
+
*/
|
|
30
|
+
/** `JSON.stringify` replacer: BigInt → decimal string (lossless). Pass-through otherwise. */
|
|
31
|
+
declare function bigintJsonReplacer(_key: string, value: unknown): unknown;
|
|
32
|
+
/** `JSON.stringify` that never throws on BigInt; identity ids stay lossless as strings. */
|
|
33
|
+
declare function stringifyBigintSafe(value: unknown, space?: string | number): string;
|
|
34
|
+
/** UTF-8 JSON bytes, BigInt-safe — the payload shape for `DataSource.write`. */
|
|
35
|
+
declare function encodeJsonBigintSafe(value: unknown): Uint8Array;
|
|
36
|
+
/**
|
|
37
|
+
* BigInt → number for analytics aggregates (< 2^53). Lossy above; acceptable for
|
|
38
|
+
* click / impression sums. Non-BigInt values pass through untouched.
|
|
39
|
+
*/
|
|
40
|
+
declare function coerceBigIntToNumber<T>(value: T): T | number;
|
|
3
41
|
/**
|
|
4
42
|
* Closed identity shapes (ADR-0021 amendments 2 + 4). `'site-int'` is the
|
|
5
43
|
* team-scoped numeric Catalog Site Id (nuxtseo ADR-0091) stored under the
|
|
@@ -156,4 +194,4 @@ interface RunPyIcebergWriterOptions {
|
|
|
156
194
|
}
|
|
157
195
|
declare function resolvePyIcebergPython(override?: string): string;
|
|
158
196
|
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, catalogCacheScope, connectIcebergCatalog, defineIcebergDataset, deriveTableSpec, dropIcebergTables, ensureIcebergNamespace, invalidateSnapshotRef, listIcebergTables, resolveIcebergDataFiles, resolvePyIcebergPython, runPyIcebergWriter, toIcebergDayCount };
|
|
197
|
+
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,5 +1,5 @@
|
|
|
1
|
+
import { ICEBERG_TYPE_MAP, bigintJsonReplacer, buildManifestPartitionFilter, cacheGet, cachePut, catalogCacheScope, coerceBigIntToNumber, connectIcebergCatalog, dropIcebergTables, encodeJsonBigintSafe, ensureIcebergNamespace, icebergAppendRetrying, invalidateSnapshotRef, listIcebergTables, resolveIcebergDataFiles, stringifyBigintSafe } from "./_chunks/catalog.mjs";
|
|
1
2
|
import { icebergCreateTable } from "./_chunks/libs/icebird.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;
|
|
@@ -113,9 +113,6 @@ function toIcebergDayCount(value) {
|
|
|
113
113
|
if (Number.isNaN(ms)) throw new TypeError(`toIcebergDayCount: invalid date string '${value}'`);
|
|
114
114
|
return Math.floor(ms / DAY_MILLIS);
|
|
115
115
|
}
|
|
116
|
-
function coerceJsonSafe(value) {
|
|
117
|
-
return typeof value === "bigint" ? Number(value) : value;
|
|
118
|
-
}
|
|
119
116
|
function asInt32(value) {
|
|
120
117
|
if (typeof value !== "string" && typeof value !== "number" && typeof value !== "bigint") return null;
|
|
121
118
|
const n = Number(value);
|
|
@@ -141,7 +138,7 @@ function buildRowProcessor(def, tableSpec) {
|
|
|
141
138
|
}
|
|
142
139
|
}
|
|
143
140
|
for (const name of dimNames) out[name] = def.dims[name].toPartitionValue(String(row[name]));
|
|
144
|
-
for (const col of def.columns) out[col.name] =
|
|
141
|
+
for (const col of def.columns) out[col.name] = coerceBigIntToNumber(row[col.name]);
|
|
145
142
|
return out;
|
|
146
143
|
}
|
|
147
144
|
function dedupe(rows) {
|
|
@@ -353,4 +350,4 @@ async function runPyIcebergWriter(options) {
|
|
|
353
350
|
});
|
|
354
351
|
}
|
|
355
352
|
const DEFAULT_PARTITION_KEY_ENCODING = "int";
|
|
356
|
-
export { DEFAULT_PARTITION_KEY_ENCODING, ICEBERG_TYPE_MAP, buildManifestPartitionFilter, cacheGet, cachePut, catalogCacheScope, connectIcebergCatalog, defineIcebergDataset, deriveTableSpec, dropIcebergTables, ensureIcebergNamespace, invalidateSnapshotRef, listIcebergTables, resolveIcebergDataFiles, resolvePyIcebergPython, runPyIcebergWriter, toIcebergDayCount };
|
|
353
|
+
export { DEFAULT_PARTITION_KEY_ENCODING, ICEBERG_TYPE_MAP, bigintJsonReplacer, buildManifestPartitionFilter, cacheGet, cachePut, catalogCacheScope, coerceBigIntToNumber, connectIcebergCatalog, defineIcebergDataset, deriveTableSpec, dropIcebergTables, encodeJsonBigintSafe, ensureIcebergNamespace, invalidateSnapshotRef, listIcebergTables, resolveIcebergDataFiles, resolvePyIcebergPython, runPyIcebergWriter, stringifyBigintSafe, toIcebergDayCount };
|
package/dist/unsafe-raw.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { icebergAppend, icebergCreateTable, icebergDropTable, icebergManifests, restCatalogConnect, restCatalogCreateNamespace, restCatalogListTables, restCatalogLoadTable, s3SignedResolver } from "./_chunks/libs/icebird.mjs";
|
|
2
1
|
import { icebergAppendRetrying, isCommitRateLimited } from "./_chunks/catalog.mjs";
|
|
2
|
+
import { icebergAppend, icebergCreateTable, icebergDropTable, icebergManifests, restCatalogConnect, restCatalogCreateNamespace, restCatalogListTables, restCatalogLoadTable, s3SignedResolver } from "./_chunks/libs/icebird.mjs";
|
|
3
3
|
const DEFAULT_GRACE_HOURS = 48;
|
|
4
4
|
const DEFAULT_MAX_DELETES = 500;
|
|
5
5
|
const HOUR_MS = 3600 * 1e3;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gscdump/lakehouse",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.37.1",
|
|
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",
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
"devDependencies": {
|
|
49
49
|
"@types/node": "^26.1.0",
|
|
50
50
|
"hyparquet": "^1.26.2",
|
|
51
|
-
"icebird": "^0.8.
|
|
51
|
+
"icebird": "^0.8.13",
|
|
52
52
|
"unstorage": "^1.17.5",
|
|
53
53
|
"vitest": "^4.1.9"
|
|
54
54
|
},
|