@sixb/ducklake 0.1.5 → 0.1.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.
Files changed (34) hide show
  1. package/README.md +24 -26
  2. package/dist/ducklake-storage.d.ts +3 -1
  3. package/dist/ducklake-storage.d.ts.map +1 -1
  4. package/dist/index.js +1100 -661
  5. package/dist/index.js.map +22 -19
  6. package/dist/internal/duckdb-reader.d.ts +28 -0
  7. package/dist/internal/duckdb-reader.d.ts.map +1 -0
  8. package/dist/internal/duckdb-runtime.d.ts +5 -3
  9. package/dist/internal/duckdb-runtime.d.ts.map +1 -1
  10. package/dist/internal/ducklake-change-reader.d.ts +13 -0
  11. package/dist/internal/ducklake-change-reader.d.ts.map +1 -0
  12. package/dist/internal/ducklake-connection-manager.d.ts +19 -3
  13. package/dist/internal/ducklake-connection-manager.d.ts.map +1 -1
  14. package/dist/internal/ducklake-read-gate.d.ts +11 -0
  15. package/dist/internal/ducklake-read-gate.d.ts.map +1 -0
  16. package/dist/internal/ducklake-row-reader.d.ts.map +1 -1
  17. package/dist/internal/ducklake-snapshot-reader.d.ts.map +1 -1
  18. package/dist/internal/ducklake-write-coordinator.d.ts +2 -1
  19. package/dist/internal/ducklake-write-coordinator.d.ts.map +1 -1
  20. package/dist/types.d.ts +2 -0
  21. package/dist/types.d.ts.map +1 -1
  22. package/package.json +4 -4
  23. package/src/ducklake-storage.ts +13 -0
  24. package/src/internal/duckdb-reader.ts +129 -0
  25. package/src/internal/duckdb-runtime.ts +75 -51
  26. package/src/internal/ducklake-change-reader.ts +157 -0
  27. package/src/internal/ducklake-connection-manager.ts +117 -33
  28. package/src/internal/ducklake-maintenance.ts +1 -1
  29. package/src/internal/ducklake-read-gate.ts +58 -0
  30. package/src/internal/ducklake-row-reader.ts +84 -63
  31. package/src/internal/ducklake-snapshot-reader.ts +7 -2
  32. package/src/internal/ducklake-write-coordinator.ts +56 -15
  33. package/src/internal/ducklake-write-session.ts +1 -0
  34. package/src/types.ts +2 -0
package/README.md CHANGED
@@ -91,18 +91,24 @@ const report = await lakeStorage.runMaintenance({
91
91
 
92
92
  ### Read and Write Concurrency
93
93
 
94
- Reads, writes, SQL previews, and SQL transforms use the same DuckDB runtime and
95
- the same DuckLake PostgreSQL metadata pool. Work is serialized inside one
96
- `DuckLakeStorage` instance, so a queued DuckDB operation makes later operations
97
- wait. Only actual DuckDB work holds the runtime: bounded read pages, batch
98
- appends, commits, SQL transforms, and metadata reads.
99
-
100
- Large `readRows(...)` calls materialize bounded pages, using a physical-row keyset when available,
101
- and release the DuckDB queue between pages. This also applies when an explicit limit exceeds one
102
- page. A JavaScript pipeline can therefore stream one DuckLake dataset directly into another on the
103
- same provider without buffering the complete input or deadlocking at the destination appender's
104
- first flush. The read remains pinned to one immutable snapshot and keeps its attachment lease until
105
- the iterator completes or closes.
94
+ Large reads stream through dedicated connections in the same DuckDB engine, sharing its memory
95
+ budget and PostgreSQL metadata pool. Metadata and writes remain available between yielded rows.
96
+ Each read stays pinned to one immutable snapshot. Maintenance waits until no reads remain; it
97
+ blocks new reads only while running, so continuous traffic can postpone it.
98
+
99
+ `maxStreamingReads` limits native streaming readers per provider (default: `4`); extra reads use
100
+ bounded pages on the main connection. It does not limit pipeline inputs. Raise it when memory and
101
+ catalog capacity allow. Finish the iterator, use `for await` with `break`, or pass `signal` to cancel
102
+ it. Projection and pipeline workers propagate their cancellation automatically.
103
+
104
+ Small previews, SQLite/custom catalogs, and PostgreSQL reads without sufficient pool headroom
105
+ use bounded pages. PostgreSQL streaming admits at most `maxConnections - 4` cursors to leave
106
+ headroom for metadata and writes. Parallel scans can exceed the pool's cache limit, so this does
107
+ not guarantee a server-wide connection count.
108
+
109
+ Every engine uses its own spill subdirectory under `duckdb.config.temp_directory` (default:
110
+ `.tmp` for an in-memory engine). Closing it removes only that subdirectory. Sharing spill filenames
111
+ between engines can corrupt results. An empty `temp_directory` still disables spilling.
106
112
 
107
113
  A write does not hold the runtime while its source iterable is producing rows.
108
114
  `writeRows(...)` validates and stages rows in bounded in-memory batches, then
@@ -111,18 +117,6 @@ reads (pagination, APIs, SFTP, retries) run outside the queue, so other reads an
111
117
  write batches can interleave between a write's batches. Large in-memory writes
112
118
  also yield to the event loop between batches.
113
119
 
114
- ```txt
115
- same provider instance:
116
- read -> write -> read
117
-
118
- the operations run in order on one DuckDB runtime
119
- ```
120
-
121
- This is the simplest and most predictable default, especially for small
122
- PostgreSQL plans. A future provider option could add a bounded read-runtime pool
123
- for deployments that have enough PostgreSQL capacity and need more concurrent
124
- read throughput.
125
-
126
120
  Datasets must declare a schema before they can be stored in DuckLake:
127
121
 
128
122
  ```ts
@@ -196,12 +190,16 @@ Snapshot syncs use `commit({ createInitialVersion: true })` to make a first empt
196
190
  addressable. Later no-op commits reuse the current version, including after a concurrent write.
197
191
  Use `commit({ retryOnConflict: true })` to rebase retained changes, with at most 3 attempts.
198
192
  Explicit `expectedLatestVersionId` guards are never relaxed.
199
- See [source ordering](../../docs/data/datasets.md#source-ordering).
193
+ See [source ordering](../../docs/datasets/source-ordering.md).
200
194
 
201
195
  Local catalogs serialize commits within one process. PostgreSQL catalogs support concurrent
202
196
  writer processes; known snapshot-ID conflicts are retried from the retained staging table.
203
197
  Other provider/connection failures propagate without an automatic retry.
204
198
 
199
+ SQLite reads commit metadata before the write transaction, then verifies the native snapshot
200
+ has not changed. Preparation retries up to three times on a race; data writes are not replayed.
201
+ The catalog's existing journal mode is preserved.
202
+
205
203
  Snapshot, append, and SQL-transform writes to keyed datasets also enforce unique keys so a later
206
204
  merge never starts from an ambiguous baseline. Application authors normally use
207
205
  `defineSync(..., { mode: "merge" })`; the sync worker stages those changes through this contract.
@@ -467,7 +465,7 @@ DuckLake metadata catalog.
467
465
 
468
466
  | Option | Use it for |
469
467
  | --- | --- |
470
- | `maxConnections` | Hard cap for DuckDB PostgreSQL extension connections. |
468
+ | `maxConnections` | Pool cache limit; parallel scans can temporarily exceed it. |
471
469
  | `waitTimeoutMillis` | How long a request can wait for a pool connection. |
472
470
  | `idleTimeoutMillis` | How quickly unused pool connections are released. |
473
471
  | `maxLifetimeMillis` | Recycling long-lived PostgreSQL connections. |
@@ -1,5 +1,5 @@
1
1
  import type { DatasetDefinition, DatasetRow, LakeStorageWithSql } from "@sixb/core";
2
- import type { BeginDatasetMergeInput, BeginDatasetWriteInput, DatasetCatalogState, DatasetVersion, LakeMergeSession, LakeWriteSession, ReadDatasetRowsInput } from "@sixb/core/lake-storage";
2
+ import type { BeginDatasetMergeInput, BeginDatasetWriteInput, DatasetCatalogState, DatasetChanges, DatasetVersion, LakeMergeSession, LakeWriteSession, ReadDatasetChangesInput, ReadDatasetRowsInput } from "@sixb/core/lake-storage";
3
3
  import { DuckLakeSqlExecutor } from "./internal/ducklake-sql-executor";
4
4
  import type { DuckLakeMaintenanceOptions, DuckLakeMaintenanceReport, DuckLakeStorageOptions } from "./types";
5
5
  /**
@@ -19,6 +19,7 @@ export declare class DuckLakeStorage implements LakeStorageWithSql<"duckdb"> {
19
19
  private readonly datasets;
20
20
  private readonly maintenance;
21
21
  private readonly rows;
22
+ private readonly changes;
22
23
  private readonly snapshotReader;
23
24
  private readonly writes;
24
25
  constructor(options: DuckLakeStorageOptions);
@@ -33,6 +34,7 @@ export declare class DuckLakeStorage implements LakeStorageWithSql<"duckdb"> {
33
34
  getLatestVersion(datasetId: string): Promise<DatasetVersion | null>;
34
35
  getVersion(datasetId: string, versionId: string): Promise<DatasetVersion | null>;
35
36
  readRows(input: ReadDatasetRowsInput): AsyncIterable<DatasetRow>;
37
+ readChanges(input: ReadDatasetChangesInput): Promise<DatasetChanges | null>;
36
38
  runMaintenance(options?: DuckLakeMaintenanceOptions): Promise<DuckLakeMaintenanceReport>;
37
39
  /**
38
40
  * `close()` is provider-specific and intentionally not part of the core
@@ -1 +1 @@
1
- {"version":3,"file":"ducklake-storage.d.ts","sourceRoot":"","sources":["../src/ducklake-storage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AACnF,OAAO,KAAK,EACV,sBAAsB,EACtB,sBAAsB,EACtB,mBAAmB,EACnB,cAAc,EACd,gBAAgB,EAChB,gBAAgB,EAChB,oBAAoB,EACrB,MAAM,yBAAyB,CAAA;AAMhC,OAAO,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAA;AAEtE,OAAO,KAAK,EACV,0BAA0B,EAC1B,yBAAyB,EACzB,sBAAsB,EACvB,MAAM,SAAS,CAAA;AAEhB;;;;;;GAMG;AACH,qBAAa,eAAgB,YAAW,kBAAkB,CAAC,QAAQ,CAAC;IAClE,QAAQ,CAAC,QAAQ;;;MAA8C;IAC/D,QAAQ,CAAC,GAAG,EAAE,mBAAmB,CAAA;IAEjC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA2B;IACvD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAwB;IACjD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAqB;IACjD,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAmB;IACxC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAwB;IACvD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA0B;gBAErC,OAAO,EAAE,sBAAsB;IAmCrC,aAAa,CAAC,UAAU,EAAE,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAIxE,kCAAkC,CACtC,WAAW,EAAE,SAAS,iBAAiB,EAAE,GACxC,OAAO,CAAC,IAAI,CAAC;IAIV,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC;IAIhE,YAAY,IAAI,OAAO,CAAC,SAAS,iBAAiB,EAAE,CAAC;IAIrD,uBAAuB,CAC3B,UAAU,EAAE,SAAS,MAAM,EAAE,GAC5B,OAAO,CAAC,SAAS,mBAAmB,EAAE,CAAC;IAIpC,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,cAAc,EAAE,CAAC;IAInF,UAAU,CAAC,KAAK,EAAE,sBAAsB,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAIpE,UAAU,CAAC,KAAK,EAAE,sBAAsB,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAIpE,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IAInE,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IAItF,QAAQ,CAAC,KAAK,EAAE,oBAAoB,GAAG,aAAa,CAAC,UAAU,CAAC;IAI1D,cAAc,CAAC,OAAO,CAAC,EAAE,0BAA0B,GAAG,OAAO,CAAC,yBAAyB,CAAC;IAI9F;;;OAGG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAG7B"}
1
+ {"version":3,"file":"ducklake-storage.d.ts","sourceRoot":"","sources":["../src/ducklake-storage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AACnF,OAAO,KAAK,EACV,sBAAsB,EACtB,sBAAsB,EACtB,mBAAmB,EACnB,cAAc,EACd,cAAc,EACd,gBAAgB,EAChB,gBAAgB,EAChB,uBAAuB,EACvB,oBAAoB,EACrB,MAAM,yBAAyB,CAAA;AAOhC,OAAO,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAA;AAEtE,OAAO,KAAK,EACV,0BAA0B,EAC1B,yBAAyB,EACzB,sBAAsB,EACvB,MAAM,SAAS,CAAA;AAEhB;;;;;;GAMG;AACH,qBAAa,eAAgB,YAAW,kBAAkB,CAAC,QAAQ,CAAC;IAClE,QAAQ,CAAC,QAAQ;;;MAA8C;IAC/D,QAAQ,CAAC,GAAG,EAAE,mBAAmB,CAAA;IAEjC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA2B;IACvD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAwB;IACjD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAqB;IACjD,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAmB;IACxC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAsB;IAC9C,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAwB;IACvD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA0B;gBAErC,OAAO,EAAE,sBAAsB;IAwCrC,aAAa,CAAC,UAAU,EAAE,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAIxE,kCAAkC,CACtC,WAAW,EAAE,SAAS,iBAAiB,EAAE,GACxC,OAAO,CAAC,IAAI,CAAC;IAIV,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC;IAIhE,YAAY,IAAI,OAAO,CAAC,SAAS,iBAAiB,EAAE,CAAC;IAIrD,uBAAuB,CAC3B,UAAU,EAAE,SAAS,MAAM,EAAE,GAC5B,OAAO,CAAC,SAAS,mBAAmB,EAAE,CAAC;IAIpC,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,cAAc,EAAE,CAAC;IAInF,UAAU,CAAC,KAAK,EAAE,sBAAsB,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAIpE,UAAU,CAAC,KAAK,EAAE,sBAAsB,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAIpE,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IAInE,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IAItF,QAAQ,CAAC,KAAK,EAAE,oBAAoB,GAAG,aAAa,CAAC,UAAU,CAAC;IAIhE,WAAW,CAAC,KAAK,EAAE,uBAAuB,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IAIrE,cAAc,CAAC,OAAO,CAAC,EAAE,0BAA0B,GAAG,OAAO,CAAC,yBAAyB,CAAC;IAI9F;;;OAGG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAG7B"}