@minnowdb/core 0.4.1 → 0.5.0

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 CHANGED
@@ -9,15 +9,15 @@ npm install @minnowdb/core
9
9
 
10
10
  - Direct SQL through `MinnowDatabase.query()` and `execute()`.
11
11
  - Joins, CTEs, window functions, grouping sets, upserts, `RETURNING`, triggers, exact decimals,
12
- JSON/JSONB, arrays, enums, sequences, and savepoints.
12
+ JSON/JSONB, zoneless DATE, arrays, enums, sequences, and savepoints.
13
13
  - Compressed column storage, secondary indexes, full-text search, and snapshot reads.
14
14
  - Atomic writes across tabs through IndexedDB or OPFS, strict durability by default, and explicit
15
15
  origin-eviction persistence policy.
16
16
  - A ready-made worker client with the same everyday database API.
17
- - TypeScript schema declarations and metadata-only migrations, including SQL domains and
18
- composite primary/foreign keys.
19
- - Batch writes, pull-driven query cursors, live queries, snapshots, compaction, and configurable
20
- query memory.
17
+ - TypeScript schema declarations and metadata-only migrations, including SQL domains,
18
+ composite primary/foreign keys, and informational relationships.
19
+ - Guarded columnar upserts, result-column SQL domains, typed catalog errors, and batch writes.
20
+ - Pull-driven query cursors, live queries, snapshots, compaction, and configurable query memory.
21
21
 
22
22
  Use [the PostgreSQL compatibility page](https://minnowdb.com/docs/sql/feature-matrix/) for the
23
23
  exact SQL surface. Use [the documentation](https://minnowdb.com/docs/) for installation, storage,
@@ -33,6 +33,8 @@ export interface CatalogForeignKey {
33
33
  readonly parentTable: string;
34
34
  readonly parentColumns: readonly string[];
35
35
  readonly onDelete: "restrict" | "cascade" | "set null";
36
+ /** Whether writes and parent deletes enforce this relationship. */
37
+ readonly enforced: boolean;
36
38
  }
37
39
  export interface CatalogCheck {
38
40
  readonly name: string;
@@ -45,7 +45,10 @@ export function toCatalog(records) {
45
45
  ...(record.primaryKeyColumnIds === undefined
46
46
  ? {}
47
47
  : { primaryKeyColumnIds: [...record.primaryKeyColumnIds] }),
48
- foreignKeys: (record.foreignKeys ?? []).map((key) => ({ ...key })),
48
+ foreignKeys: (record.foreignKeys ?? []).map((key) => ({
49
+ ...key,
50
+ enforced: key.enforced !== false,
51
+ })),
49
52
  checks: (record.checks ?? []).map((check) => ({ ...check })),
50
53
  ...(record.secondaryIndexes === undefined
51
54
  ? {}
@@ -1,7 +1,7 @@
1
1
  import { type CompactionJobRecord, type GarbageCollectionJobRecord, type StorageIntegrityMode, type StorageIntegrityReport, type StorageStats, type InterruptedSnapshotImport, type InterruptedSnapshotImportAbortResult } from "../storage/types.js";
2
2
  import { type BatchRow, type InsertBatchInput } from "./batch.js";
3
3
  import type { Catalog } from "./catalog.js";
4
- import type { BatchValue, BufferPoolStats, StagedWriteResult, BufferedFlushResult, BufferedWriterOptions, CancelCompactionJobResult, CollectGarbageOptions, CollectGarbageStepOptions, CompactTableOptions, CompactTableResult, CompactTableStepOptions, CompactionJobProgress, CreateTableInput, DatabaseRow, MigrateOptions, DeleteBatchInput, DeleteBatchResult, ExecuteResult, GarbageCollectionProgress, GarbageCollectionResult, MaintenanceStatus, InsertBatchResult, QueryOptions, QueryCursorOptions, QuerySpillCleanupOptions, QuerySpillCleanupResult, ReadTableOptions, RunStatementOptions, SnapshotExportOptions, SnapshotImportOptions, TableDefinition, UpdateBatchInput, UpdateBatchResult, UpsertBatchResult, VisibleSegmentPage, VisibleSegmentPageOptions } from "./database.js";
4
+ import type { BatchValue, BufferPoolStats, StagedWriteResult, BufferedFlushResult, BufferedWriterOptions, CancelCompactionJobResult, CollectGarbageOptions, CollectGarbageStepOptions, CompactTableOptions, CompactTableResult, CompactTableStepOptions, CompactionJobProgress, CreateTableInput, DatabaseRow, MigrateOptions, DeleteBatchInput, DeleteBatchResult, ExecuteResult, GarbageCollectionProgress, GarbageCollectionResult, MaintenanceStatus, InsertBatchResult, QueryOptions, QueryCursorOptions, QuerySpillCleanupOptions, QuerySpillCleanupResult, ReadTableOptions, RunStatementOptions, SnapshotExportOptions, SnapshotImportOptions, TableDefinition, UpdateBatchInput, UpdateBatchResult, UpsertBatchResult, UpsertOptions, VisibleSegmentPage, VisibleSegmentPageOptions } from "./database.js";
5
5
  import type { LiveQueryInput, LiveQueryInvalidation, LiveQueryObserveOptions, LiveQueryStats, LiveQuerySubscribeOptions } from "./live.js";
6
6
  import type { CompiledQuery, CompiledStatement, QueryResult, QueryValue } from "./query.js";
7
7
  import type { AnyTable, SchemaDefinition } from "./schema.js";
@@ -78,8 +78,8 @@ export declare class MinnowDatabaseClient {
78
78
  migrate(definition: SchemaDefinition<readonly AnyTable[]>, options?: MigrateOptions): Promise<ClientMigrationResult>;
79
79
  insertBatch(tableName: string, input: InsertBatchInput): Promise<InsertBatchResult>;
80
80
  insert(tableName: string, row: BatchRow): Promise<InsertBatchResult>;
81
- upsertBatch(tableName: string, input: InsertBatchInput): Promise<UpsertBatchResult>;
82
- upsert(tableName: string, row: BatchRow): Promise<UpsertBatchResult>;
81
+ upsertBatch(tableName: string, input: InsertBatchInput, options?: UpsertOptions): Promise<UpsertBatchResult>;
82
+ upsert(tableName: string, row: BatchRow, options?: UpsertOptions): Promise<UpsertBatchResult>;
83
83
  updateBatch(tableName: string, input: UpdateBatchInput): Promise<UpdateBatchResult>;
84
84
  update(tableName: string, key: Exclude<BatchValue, null>, changes: Readonly<Record<string, BatchValue>>): Promise<UpdateBatchResult>;
85
85
  deleteBatch(tableName: string, input: DeleteBatchInput): Promise<DeleteBatchResult>;
@@ -2,7 +2,7 @@ import { BlockReadBatchTooLargeError, CompactionBacklogError, CompactionJobConfl
2
2
  import { MAX_SNAPSHOT_STREAM_CHUNK_BYTES } from "../storage/snapshot.js";
3
3
  import { parseRpcResponse, MAX_DATABASE_RPC_IN_FLIGHT, protocolVersion, } from "../worker-protocol/index.js";
4
4
  import { toColumnarBatch } from "./batch.js";
5
- import { CompactionJobCancelledError, CompactionMemoryBudgetError, CompactionWriteAmplificationError, MaintenanceBacklogError, MissingKeyError, SqlCompileError, UniqueConstraintError, VisibleSegmentCursorStaleError, } from "./errors.js";
5
+ import { CompactionJobCancelledError, CompactionMemoryBudgetError, CompactionWriteAmplificationError, MaintenanceBacklogError, MissingKeyError, SqlCompileError, UnknownTableError, UniqueConstraintError, VisibleSegmentCursorStaleError, } from "./errors.js";
6
6
  import { QueryMemoryBudgetError } from "./memory.js";
7
7
  import { decodeQueryResult } from "./result-wire.js";
8
8
  import { serializeSchema } from "./schema-wire.js";
@@ -30,6 +30,7 @@ function throwIfClientSnapshotAborted(signal) {
30
30
  const errorRegistry = new Map([
31
31
  UniqueConstraintError,
32
32
  MissingKeyError,
33
+ UnknownTableError,
33
34
  CompactionBacklogError,
34
35
  CompactionMemoryBudgetError,
35
36
  CompactionWriteAmplificationError,
@@ -163,12 +164,12 @@ export class MinnowDatabaseClient {
163
164
  async insert(tableName, row) {
164
165
  return (await this.#call("insert", [tableName, row]));
165
166
  }
166
- async upsertBatch(tableName, input) {
167
+ async upsertBatch(tableName, input, options = {}) {
167
168
  const batch = toColumnarBatch(input);
168
- return (await this.#call("upsertBatch", [tableName, batch]));
169
+ return (await this.#call("upsertBatch", [tableName, batch, options]));
169
170
  }
170
- async upsert(tableName, row) {
171
- return (await this.#call("upsert", [tableName, row]));
171
+ async upsert(tableName, row, options = {}) {
172
+ return (await this.#call("upsert", [tableName, row, options]));
172
173
  }
173
174
  async updateBatch(tableName, input) {
174
175
  return (await this.#call("updateBatch", [tableName, input]));
@@ -1,11 +1,11 @@
1
1
  import { type BatchRow, type BatchValue, type InsertBatchInput } from "./batch.js";
2
2
  import { BufferedTableWriter, type BufferedWriterOptions } from "./buffered-writer.js";
3
3
  export { attachLifecycleFlush, BufferedTableWriter, MAX_BUFFERED_WRITER_PENDING_ADDS, type BufferedFlushResult, type BufferedWriterOptions, type LifecycleDocumentTarget, type LifecycleFlushOptions, type LifecycleFlushRequester, type LifecyclePageTarget, } from "./buffered-writer.js";
4
- import { CompactionJobCancelledError, CompactionMemoryBudgetError, CompactionWriteAmplificationError, MaintenanceBacklogError, MissingKeyError, SqlCompileError, UniqueConstraintError, VisibleSegmentCursorStaleError } from "./errors.js";
4
+ import { CompactionJobCancelledError, CompactionMemoryBudgetError, CompactionWriteAmplificationError, MaintenanceBacklogError, MissingKeyError, SqlCompileError, UnknownTableError, UniqueConstraintError, VisibleSegmentCursorStaleError } from "./errors.js";
5
5
  import { type Compression } from "../block-format/index.js";
6
6
  import { type BlockStore, type ColumnDefault, CompactionBacklogError, type CompactionJobRecord, type CompactionJobState, type GarbageCollectionJobRecord, type GarbageCollectionJobState, type SimpleDataType, type SqlDomain, type StorageIntegrityMode, type StorageIntegrityReport, type StorageStats, type InterruptedSnapshotImport, type InterruptedSnapshotImportAbortResult, TableInUseError } from "../storage/types.js";
7
7
  import type { SnapshotExportProgress, SnapshotLoadProgress } from "../storage/snapshot.js";
8
- import { type CompiledQuery, type CompiledStatement, type ForeignKeyDefinition, type QueryResult, type QueryRow, type QueryValue, type UniqueConstraintDefinition } from "./query.js";
8
+ import { type ComparisonOperator, type CompiledQuery, type CompiledStatement, type ForeignKeyDefinition, type QueryResult, type QueryRow, type QueryValue, type UniqueConstraintDefinition } from "./query.js";
9
9
  import { LiveQuerySet, type LiveQuerySetOptions } from "./live.js";
10
10
  import { type Catalog } from "./catalog.js";
11
11
  import { type AnyTable, type MigrationStep, type SchemaDefinition } from "./schema.js";
@@ -91,9 +91,23 @@ export interface InsertBatchResult {
91
91
  */
92
92
  generatedColumns?: Record<string, BatchValue[]>;
93
93
  }
94
- export interface UpsertBatchResult extends InsertBatchResult {
94
+ export interface UpsertBatchResult extends Omit<InsertBatchResult, "segmentId"> {
95
+ segmentId: string | null;
96
+ /** Input rows considered by the statement, including conflicts rejected by `conflictWhere`. */
97
+ requestedRowCount: number;
95
98
  insertedRowCount: number;
96
99
  updatedRowCount: number;
100
+ skippedRowCount: number;
101
+ }
102
+ export interface UpsertConflictWhere {
103
+ /** Column of the existing conflicting row to test. */
104
+ column: string;
105
+ operator: ComparisonOperator;
106
+ value: BatchValue;
107
+ }
108
+ export interface UpsertOptions {
109
+ /** SQL `ON CONFLICT DO UPDATE ... WHERE` semantics over the existing target row. */
110
+ conflictWhere?: UpsertConflictWhere;
97
111
  }
98
112
  export interface UpdateBatchInput {
99
113
  /** Stable ordinary arrays; do not mutate or expose changing accessors until the write settles. */
@@ -415,7 +429,7 @@ export interface TableDefinition {
415
429
  uniqueKey?: string;
416
430
  }
417
431
  export type DatabaseRow = Record<string, Exclude<BatchValue, null> | null>;
418
- export { CompactionBacklogError, CompactionJobCancelledError, CompactionMemoryBudgetError, CompactionWriteAmplificationError, MaintenanceBacklogError, MissingKeyError, SqlCompileError, TableInUseError, UniqueConstraintError, VisibleSegmentCursorStaleError, };
432
+ export { CompactionBacklogError, CompactionJobCancelledError, CompactionMemoryBudgetError, CompactionWriteAmplificationError, MaintenanceBacklogError, MissingKeyError, SqlCompileError, UnknownTableError, TableInUseError, UniqueConstraintError, VisibleSegmentCursorStaleError, };
419
433
  export interface MinnowDatabaseOptions {
420
434
  /**
421
435
  * Block codec for newly written blocks; defaults to "gzip", which is also what compaction
@@ -722,8 +736,8 @@ export declare class MinnowDatabase {
722
736
  }): Promise<boolean>;
723
737
  insertBatch(tableName: string, input: InsertBatchInput): Promise<InsertBatchResult>;
724
738
  insert(tableName: string, row: BatchRow): Promise<InsertBatchResult>;
725
- upsertBatch(tableName: string, input: InsertBatchInput): Promise<UpsertBatchResult>;
726
- upsert(tableName: string, row: BatchRow): Promise<UpsertBatchResult>;
739
+ upsertBatch(tableName: string, input: InsertBatchInput, options?: UpsertOptions): Promise<UpsertBatchResult>;
740
+ upsert(tableName: string, row: BatchRow, options?: UpsertOptions): Promise<UpsertBatchResult>;
727
741
  updateBatch(tableName: string, input: UpdateBatchInput): Promise<UpdateBatchResult>;
728
742
  update(tableName: string, key: Exclude<BatchValue, null>, changes: Readonly<Record<string, BatchValue>>): Promise<UpdateBatchResult>;
729
743
  deleteBatch(tableName: string, input: DeleteBatchInput): Promise<DeleteBatchResult>;