@gscdump/lakehouse 1.0.1 → 1.0.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/README.md +4 -0
- package/dist/_chunks/catalog.mjs +2 -13
- package/dist/bigint.d.mts +38 -0
- package/dist/bigint.mjs +15 -0
- package/dist/index.d.mts +1 -38
- package/dist/index.mjs +3 -2
- package/dist/maintenance.mjs +1 -1
- package/dist/schema.d.mts +2 -0
- package/dist/schema.mjs +2 -0
- package/dist/unsafe-raw.mjs +1 -1
- package/package.json +11 -1
package/README.md
CHANGED
|
@@ -15,6 +15,9 @@ Node.js 22 or newer is required.
|
|
|
15
15
|
|
|
16
16
|
- `@gscdump/lakehouse` — connect to a catalog, define datasets, derive table
|
|
17
17
|
specifications, resolve data files, and use bigint-safe serialization.
|
|
18
|
+
- `@gscdump/lakehouse/bigint`: bigint-safe JSON helpers without catalog or
|
|
19
|
+
Node dependencies.
|
|
20
|
+
- `@gscdump/lakehouse/schema`: lightweight shared schema constants.
|
|
18
21
|
- `@gscdump/lakehouse/maintenance` — stable commit classification and orphan
|
|
19
22
|
cleanup workflows.
|
|
20
23
|
- `@gscdump/lakehouse/provisioning` — adopt, allocate, or provision R2 Data
|
|
@@ -25,6 +28,7 @@ Node.js 22 or newer is required.
|
|
|
25
28
|
|
|
26
29
|
```ts
|
|
27
30
|
import { connectIcebergCatalog, listIcebergTables } from '@gscdump/lakehouse'
|
|
31
|
+
import { encodeJsonBigintSafe } from '@gscdump/lakehouse/bigint'
|
|
28
32
|
import { isCommitRateLimited } from '@gscdump/lakehouse/maintenance'
|
|
29
33
|
|
|
30
34
|
const connection = await connectIcebergCatalog(config)
|
package/dist/_chunks/catalog.mjs
CHANGED
|
@@ -1,16 +1,5 @@
|
|
|
1
|
+
import { stringifyBigintSafe } from "../bigint.mjs";
|
|
1
2
|
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
|
-
}
|
|
14
3
|
function reportCatalogCacheError(cache, operation, key, error) {
|
|
15
4
|
try {
|
|
16
5
|
if (cache.onError) cache.onError(operation, key, error);
|
|
@@ -410,4 +399,4 @@ async function resolveIcebergDataFiles(conn, opts) {
|
|
|
410
399
|
}
|
|
411
400
|
return out;
|
|
412
401
|
}
|
|
413
|
-
export { ICEBERG_TYPE_MAP,
|
|
402
|
+
export { ICEBERG_TYPE_MAP, buildManifestPartitionFilter, cacheGet, cachePut, catalogCacheScope, connectIcebergCatalog, dropIcebergTables, ensureIcebergNamespace, icebergAppendRetrying, invalidateSnapshotRef, isCommitRateLimited, listIcebergTables, resolveIcebergDataFiles };
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BigInt at JSON boundaries — the single place this policy lives.
|
|
3
|
+
*
|
|
4
|
+
* int64 reaches serialization from two origins:
|
|
5
|
+
* 1. DuckDB `SUM`/`COUNT` aggregates — already coerced to `number` at the
|
|
6
|
+
* source-factory boundary (`@gscdump/engine` `coerceRows`), so rows are
|
|
7
|
+
* BigInt-free by the time they cross the query boundary.
|
|
8
|
+
* 2. icebird / REST-catalog metadata (`current-snapshot-id`, `sequence-number`,
|
|
9
|
+
* `snapshot-id`) and other identity ids — these never pass through a source,
|
|
10
|
+
* so they arrive at envelope / cache / log serializers still as BigInt.
|
|
11
|
+
*
|
|
12
|
+
* A plain `JSON.stringify` throws `Do not know how to serialize a BigInt`, which
|
|
13
|
+
* is how a stray identity int64 turns into a request 500. Any boundary that can
|
|
14
|
+
* see origin (2) must serialize through here.
|
|
15
|
+
*
|
|
16
|
+
* TWO policies, because the correct target type depends on what the value is:
|
|
17
|
+
*
|
|
18
|
+
* - Identity / precision values (snapshot ids, large row ids) can exceed 2^53
|
|
19
|
+
* and must round-trip losslessly → serialize as a decimal STRING. Use
|
|
20
|
+
* {@link stringifyBigintSafe} / {@link bigintJsonReplacer} / {@link encodeJsonBigintSafe}
|
|
21
|
+
* for storage / transport / log serialization. Where values are already
|
|
22
|
+
* number-coerced (origin 1), the replacer is a no-op backstop.
|
|
23
|
+
*
|
|
24
|
+
* - Analytics aggregates that you want as real numbers downstream → coerce with
|
|
25
|
+
* {@link coerceBigIntToNumber}. Lossy above 2^53 by design; click / impression
|
|
26
|
+
* columns never reach that range. This is the scalar behind engine `coerceRows`.
|
|
27
|
+
*/
|
|
28
|
+
/** `JSON.stringify` replacer: BigInt → decimal string (lossless). Pass-through otherwise. */
|
|
29
|
+
declare function bigintJsonReplacer(_key: string, value: unknown): unknown;
|
|
30
|
+
/** `JSON.stringify` that never throws on BigInt; identity ids stay lossless as strings. */
|
|
31
|
+
declare function stringifyBigintSafe(value: unknown, space?: string | number): string;
|
|
32
|
+
declare function encodeJsonBigintSafe(value: unknown): Uint8Array;
|
|
33
|
+
/**
|
|
34
|
+
* BigInt → number for analytics aggregates (< 2^53). Lossy above; acceptable for
|
|
35
|
+
* click / impression sums. Non-BigInt values pass through untouched.
|
|
36
|
+
*/
|
|
37
|
+
declare function coerceBigIntToNumber<T>(value: T): T | number;
|
|
38
|
+
export { bigintJsonReplacer, coerceBigIntToNumber, encodeJsonBigintSafe, stringifyBigintSafe };
|
package/dist/bigint.mjs
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
function bigintJsonReplacer(_key, value) {
|
|
2
|
+
return typeof value === "bigint" ? value.toString() : value;
|
|
3
|
+
}
|
|
4
|
+
function stringifyBigintSafe(value, space) {
|
|
5
|
+
return JSON.stringify(value, bigintJsonReplacer, space);
|
|
6
|
+
}
|
|
7
|
+
let jsonEncoder;
|
|
8
|
+
function encodeJsonBigintSafe(value) {
|
|
9
|
+
jsonEncoder ??= new TextEncoder();
|
|
10
|
+
return jsonEncoder.encode(stringifyBigintSafe(value));
|
|
11
|
+
}
|
|
12
|
+
function coerceBigIntToNumber(value) {
|
|
13
|
+
return typeof value === "bigint" ? Number(value) : value;
|
|
14
|
+
}
|
|
15
|
+
export { bigintJsonReplacer, coerceBigIntToNumber, encodeJsonBigintSafe, stringifyBigintSafe };
|
package/dist/index.d.mts
CHANGED
|
@@ -1,43 +1,6 @@
|
|
|
1
|
+
import { bigintJsonReplacer, coerceBigIntToNumber, encodeJsonBigintSafe, stringifyBigintSafe } from "./bigint.mjs";
|
|
1
2
|
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
3
|
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;
|
|
41
4
|
/**
|
|
42
5
|
* Closed identity shapes (ADR-0021 amendments 2 + 4). `'site-int'` is the
|
|
43
6
|
* team-scoped numeric Catalog Site Id (nuxtseo ADR-0091) stored under the
|
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { bigintJsonReplacer, coerceBigIntToNumber, encodeJsonBigintSafe, stringifyBigintSafe } from "./bigint.mjs";
|
|
2
2
|
import { icebergCreateTable } from "./_chunks/libs/icebird.mjs";
|
|
3
|
+
import { ICEBERG_TYPE_MAP, buildManifestPartitionFilter, cacheGet, cachePut, catalogCacheScope, connectIcebergCatalog, dropIcebergTables, ensureIcebergNamespace, icebergAppendRetrying, invalidateSnapshotRef, listIcebergTables, resolveIcebergDataFiles } from "./_chunks/catalog.mjs";
|
|
4
|
+
import { DEFAULT_PARTITION_KEY_ENCODING } from "./schema.mjs";
|
|
3
5
|
const INT32_MIN = -2147483648;
|
|
4
6
|
const INT32_MAX = 2147483647;
|
|
5
7
|
const DAY_MILLIS = 864e5;
|
|
@@ -325,5 +327,4 @@ function defineIcebergDataset(def) {
|
|
|
325
327
|
resolveDataFiles
|
|
326
328
|
};
|
|
327
329
|
}
|
|
328
|
-
const DEFAULT_PARTITION_KEY_ENCODING = "int";
|
|
329
330
|
export { DEFAULT_PARTITION_KEY_ENCODING, ICEBERG_TYPE_MAP, bigintJsonReplacer, buildManifestPartitionFilter, cacheGet, cachePut, catalogCacheScope, coerceBigIntToNumber, connectIcebergCatalog, defineIcebergDataset, deriveTableSpec, dropIcebergTables, encodeJsonBigintSafe, ensureIcebergNamespace, invalidateSnapshotRef, listIcebergTables, resolveIcebergDataFiles, stringifyBigintSafe, toIcebergDayCount };
|
package/dist/maintenance.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { isCommitRateLimited } from "./_chunks/catalog.mjs";
|
|
2
1
|
import { icebergManifests, restCatalogListTables, restCatalogLoadTable } from "./_chunks/libs/icebird.mjs";
|
|
2
|
+
import { isCommitRateLimited } from "./_chunks/catalog.mjs";
|
|
3
3
|
const DEFAULT_GRACE_HOURS = 48;
|
|
4
4
|
const DEFAULT_MAX_DELETES = 500;
|
|
5
5
|
const DEFAULT_IO_CONCURRENCY = 4;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { DEFAULT_PARTITION_KEY_ENCODING, IcebergColumn, IcebergColumnType, IcebergPartitionField, IcebergPartitionTransform, IcebergS3Config, IcebergTableSpec, PartitionKeyEncoding } from "./_chunks/schema.mjs";
|
|
2
|
+
export { DEFAULT_PARTITION_KEY_ENCODING, IcebergColumn, IcebergColumnType, IcebergPartitionField, IcebergPartitionTransform, IcebergS3Config, IcebergTableSpec, PartitionKeyEncoding };
|
package/dist/schema.mjs
ADDED
package/dist/unsafe-raw.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { icebergAppendRetrying } from "./_chunks/catalog.mjs";
|
|
2
1
|
import { icebergAppend, icebergCreateTable, icebergDropTable, icebergManifests, restCatalogConnect, restCatalogCreateNamespace, restCatalogListTables, restCatalogLoadTable, s3SignedResolver } from "./_chunks/libs/icebird.mjs";
|
|
2
|
+
import { icebergAppendRetrying } from "./_chunks/catalog.mjs";
|
|
3
3
|
export { icebergAppend, icebergAppendRetrying, icebergCreateTable, icebergDropTable, icebergManifests, restCatalogConnect, restCatalogCreateNamespace, restCatalogListTables, restCatalogLoadTable, s3SignedResolver };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gscdump/lakehouse",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.0.
|
|
4
|
+
"version": "1.0.3",
|
|
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",
|
|
@@ -26,6 +26,16 @@
|
|
|
26
26
|
"import": "./dist/index.mjs",
|
|
27
27
|
"default": "./dist/index.mjs"
|
|
28
28
|
},
|
|
29
|
+
"./bigint": {
|
|
30
|
+
"types": "./dist/bigint.d.mts",
|
|
31
|
+
"import": "./dist/bigint.mjs",
|
|
32
|
+
"default": "./dist/bigint.mjs"
|
|
33
|
+
},
|
|
34
|
+
"./schema": {
|
|
35
|
+
"types": "./dist/schema.d.mts",
|
|
36
|
+
"import": "./dist/schema.mjs",
|
|
37
|
+
"default": "./dist/schema.mjs"
|
|
38
|
+
},
|
|
29
39
|
"./maintenance": {
|
|
30
40
|
"types": "./dist/maintenance.d.mts",
|
|
31
41
|
"import": "./dist/maintenance.mjs",
|