@voltro/sql-sqlite 0.70.0 → 0.71.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/index.d.ts CHANGED
@@ -7,6 +7,7 @@ import { Context } from 'effect';
7
7
  import { DataStore } from '@voltro/database';
8
8
  import { Effect } from 'effect';
9
9
  import { EventEmitter } from 'node:events';
10
+ import { InsertIgnoreResult } from '@voltro/database';
10
11
  import { Layer } from 'effect';
11
12
  import { ManagedRuntime } from 'effect';
12
13
  import { Predicate } from '@voltro/database';
@@ -166,6 +167,9 @@ export declare class SqliteStore implements DataStore {
166
167
  insertIgnore(table: string, row: Row, options: {
167
168
  conflictColumns: ReadonlyArray<string>;
168
169
  }): Promise<Row>;
170
+ insertIgnoreWithOutcome(table: string, row: Row, options: {
171
+ conflictColumns: ReadonlyArray<string>;
172
+ }): Promise<InsertIgnoreResult>;
169
173
  /* Excluded from this release type: emitChange */
170
174
  /* Excluded from this release type: getInternalExecuteQuery */
171
175
  /* Excluded from this release type: getInternalExecuteInsert */
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { SqliteClient as e } from "@effect/sql-sqlite-node";
2
2
  import { Config as t, Context as n, Effect as r, Layer as i, ManagedRuntime as a, Option as o } from "effect";
3
- import { EagerCardinalityError as s, SQLITE_TRANSIENT_CODES as c, attachEagerLoads as l, attributionFields as u, bulkInsertLimitsFor as d, causeBranches as f, chunkRowsForInsert as p, coercePredicateForSqlite as m, compileEagerJson as h, compileJsonPatch as g, compilePredicate as _, compileRawFragment as v, compileSelect as y, decodeRowsFromSchema as b, encodeRowForSchema as x, externalChangeEvent as ee, hasEagerLoads as S, isTableReactive as C, jsonPatchAssignments as w, makeEagerFallbackReporter as T, observeDbOp as E, qualifyTable as D, quoteIdent as O, raiseChangeListenerCeiling as k, recordsTable as A, requireTable as j, rowKeyColumns as M, runStoreTransaction as te, runWriteRecorders as N, stampGeneratedId as P, stampGeneratedIds as F, upsertUpdatePatch as I, upsertUpdateValues as L, withCapturedAttribution as R } from "@voltro/database";
3
+ import { EagerCardinalityError as s, SQLITE_TRANSIENT_CODES as c, attachEagerLoads as l, attributionFields as u, bulkInsertLimitsFor as d, causeBranches as f, chunkRowsForInsert as p, coercePredicateForSqlite as m, compileEagerJson as h, compileJsonPatch as g, compilePredicate as _, compileRawFragment as v, compileSelect as y, decodeRowsFromSchema as b, encodeRowForSchema as x, externalChangeEvent as S, hasEagerLoads as C, isTableReactive as w, jsonPatchAssignments as ee, makeEagerFallbackReporter as T, observeDbOp as E, qualifyTable as D, quoteIdent as O, raiseChangeListenerCeiling as k, recordsTable as A, requireTable as j, rowKeyColumns as M, runStoreTransaction as N, runWriteRecorders as te, stampGeneratedId as P, stampGeneratedIds as F, upsertUpdatePatch as I, upsertUpdateValues as L, withCapturedAttribution as R } from "@voltro/database";
4
4
  import { EventEmitter as z } from "node:events";
5
5
  import { createLogger as B } from "@voltro/logger";
6
6
  import { SqlClient as V, TransactionConnection as H } from "@effect/sql/SqlClient";
@@ -66,23 +66,23 @@ var U = (r) => e.layerConfig({
66
66
  }
67
67
  async executeInsert(e, t, n, i, a) {
68
68
  t = P(e, t);
69
- let o = this.sql, s = o`INSERT INTO ${o(this.nsT(e))} ${o.insert($(t, e))} RETURNING *`, c = n ? r.provideService(s, H, n) : s, l = (await this.runtime.runPromise(c))[0];
70
- if (!l) throw Error(`SqliteStore.insert: no row returned for table '${e}'`);
69
+ let o = this.sql, s = o`INSERT INTO ${o(this.nsT(e))} ${o.insert($(t, e))} RETURNING *`, c = n ? r.provideService(s, H, n) : s, l = await this.runtime.runPromise(c), u = b(l, e, "sqlite")[0];
70
+ if (!u) throw Error(`SqliteStore.insert: no row returned for table '${e}'`);
71
71
  return await this.routeEvent({
72
72
  table: e,
73
73
  op: "insert",
74
74
  old: null,
75
- new: l
76
- }, i, n, a), l;
75
+ new: u
76
+ }, i, n, a), u;
77
77
  }
78
78
  async executeUpdate(e, t, n, i, a, o) {
79
- let s = this.sql, c = s`UPDATE ${s(this.nsT(e))} SET ${s.update($(n, e))} WHERE ${s.and(M(t).map(([e, t]) => s`${s(e)} = ${t}`))} RETURNING *`, l = i ? r.provideService(c, H, i) : c, u = (await this.runtime.runPromise(l))[0];
80
- return u ? (await this.routeEvent({
79
+ let s = this.sql, c = s`UPDATE ${s(this.nsT(e))} SET ${s.update($(n, e))} WHERE ${s.and(M(t).map(([e, t]) => s`${s(e)} = ${t}`))} RETURNING *`, l = i ? r.provideService(c, H, i) : c, u = await this.runtime.runPromise(l), d = b(u, e, "sqlite")[0];
80
+ return d ? (await this.routeEvent({
81
81
  table: e,
82
82
  op: "update",
83
83
  old: null,
84
- new: u
85
- }, a, i, o), u) : null;
84
+ new: d
85
+ }, a, i, o), d) : null;
86
86
  }
87
87
  async executeInsertMany(e, t, n, i, a) {
88
88
  if (t = F(e, t), t.length === 0) return [];
@@ -95,29 +95,30 @@ var U = (r) => e.layerConfig({
95
95
  for (let t of c) e.push(...await this.runtime.runPromise(r.provideService(l(t), H, n)));
96
96
  u = e;
97
97
  } else u = await this.runtime.runPromise(o.withTransaction(r.map(r.forEach(c, l, { concurrency: 1 }), (e) => e.flat())));
98
- for (let t of u) await this.routeEvent({
98
+ let f = b(u, e, "sqlite");
99
+ for (let t of f) await this.routeEvent({
99
100
  table: e,
100
101
  op: "insert",
101
102
  old: null,
102
103
  new: t
103
104
  }, i, n, a);
104
- return u;
105
+ return f;
105
106
  }
106
107
  async executePatchJson(e, t, n, i, a, o, s, c) {
107
- let l = this.sql, u = $(w(t, n, c), e), d = l.csv([g(l, "sqlite", n, i, l`${l(this.nsT(e))}.${l(n.split(".")[0])}`), ...Object.entries(u).map(([e, t]) => l`${l(e)} = ${t}`)]), f = l`UPDATE ${l(this.nsT(e))} SET ${d} WHERE ${l.and(M(t).map(([e, t]) => l`${l(e)} = ${t}`))} RETURNING *`, p = a ? r.provideService(f, H, a) : f, m = (await this.runtime.runPromise(p))[0];
108
- return m ? (await this.routeEvent({
108
+ let l = this.sql, u = $(ee(t, n, c), e), d = l.csv([g(l, "sqlite", n, i, l`${l(this.nsT(e))}.${l(n.split(".")[0])}`), ...Object.entries(u).map(([e, t]) => l`${l(e)} = ${t}`)]), f = l`UPDATE ${l(this.nsT(e))} SET ${d} WHERE ${l.and(M(t).map(([e, t]) => l`${l(e)} = ${t}`))} RETURNING *`, p = a ? r.provideService(f, H, a) : f, m = await this.runtime.runPromise(p), h = b(m, e, "sqlite")[0];
109
+ return h ? (await this.routeEvent({
109
110
  table: e,
110
111
  op: "update",
111
112
  old: null,
112
- new: m
113
- }, o, a, s), m) : null;
113
+ new: h
114
+ }, o, a, s), h) : null;
114
115
  }
115
116
  async executeDelete(e, t, n, i, a) {
116
- let o = this.sql, s = o`DELETE FROM ${o(this.nsT(e))} WHERE ${o.and(M(t).map(([e, t]) => o`${o(e)} = ${t}`))} RETURNING *`, c = n ? r.provideService(s, H, n) : s, l = (await this.runtime.runPromise(c))[0];
117
- return l ? (await this.routeEvent({
117
+ let o = this.sql, s = o`DELETE FROM ${o(this.nsT(e))} WHERE ${o.and(M(t).map(([e, t]) => o`${o(e)} = ${t}`))} RETURNING *`, c = n ? r.provideService(s, H, n) : s, l = await this.runtime.runPromise(c), u = b(l, e, "sqlite")[0];
118
+ return u ? (await this.routeEvent({
118
119
  table: e,
119
120
  op: "delete",
120
- old: l,
121
+ old: u,
121
122
  new: null
122
123
  }, i, n, a), !0) : !1;
123
124
  }
@@ -133,7 +134,7 @@ var U = (r) => e.layerConfig({
133
134
  e = {
134
135
  ...u(r),
135
136
  ...e
136
- }, A(e.table) && await N({
137
+ }, A(e.table) && await te({
137
138
  append: (e, t) => this.appendInTxn(e, t, n),
138
139
  maxOf: (e, t, r) => this.maxInTxn(e, t, r, n)
139
140
  }, {
@@ -143,41 +144,47 @@ var U = (r) => e.layerConfig({
143
144
  prev: e.old,
144
145
  traceId: e.traceId,
145
146
  subjectId: e.subjectId
146
- }), C(e.table) && (t === null ? this.emitter.emit("change", e) : t.push(e));
147
+ }), w(e.table) && (t === null ? this.emitter.emit("change", e) : t.push(e));
147
148
  }
148
149
  async executeUpsert(e, t, n, i, a, o) {
149
150
  let s = L(n);
150
151
  if (t = P(e, t), typeof n.update == "function") {
151
152
  let r = await this.findByConflict(e, t, n.conflictColumns, i);
152
- return r ? await this.executeUpdate(e, r.id, I(t, r, n), i, a) ?? r : this.executeInsert(e, t, i, a);
153
+ return r ? await this.executeUpdate(e, r.id, I(t, r, n), i, a, o) ?? r : this.executeInsert(e, t, i, a, o);
153
154
  }
154
- let c = this.sql, l = n.conflictColumns.map((e) => c`${c(e)}`), u = Object.keys(t).filter((e) => t[e] !== void 0), d = n.update === void 0 ? u.filter((e) => e !== "id" && !n.conflictColumns.includes(e)) : n.update, f = $(s, e), p = [...d.filter((e) => !Object.hasOwn(s, e)).map((e) => c`${c(e)} = excluded.${c(e)}`), ...Object.entries(f).map(([e, t]) => c`${c(e)} = ${t}`)], m = p.length > 0 ? c.csv(p) : c`${c(n.conflictColumns[0])} = excluded.${c(n.conflictColumns[0])}`, h = c`INSERT INTO ${c(this.nsT(e))} ${c.insert($(t, e))} ON CONFLICT (${c.csv(l)}) DO UPDATE SET ${m} RETURNING *`, g = i ? r.provideService(h, H, i) : h, _ = (await this.runtime.runPromise(g))[0];
155
- if (!_) throw Error(`SqliteStore.upsert: no row returned for table '${e}'`);
156
- let v = t.id !== void 0 && t.id === _.id ? "insert" : "update";
155
+ let c = this.sql, l = n.conflictColumns.map((e) => c`${c(e)}`), u = Object.keys(t).filter((e) => t[e] !== void 0), d = n.update === void 0 ? u.filter((e) => e !== "id" && !n.conflictColumns.includes(e)) : n.update, f = $(s, e), p = [...d.filter((e) => !Object.hasOwn(s, e)).map((e) => c`${c(e)} = excluded.${c(e)}`), ...Object.entries(f).map(([e, t]) => c`${c(e)} = ${t}`)], m = p.length > 0 ? c.csv(p) : c`${c(n.conflictColumns[0])} = excluded.${c(n.conflictColumns[0])}`, h = c`INSERT INTO ${c(this.nsT(e))} ${c.insert($(t, e))} ON CONFLICT (${c.csv(l)}) DO UPDATE SET ${m} RETURNING *`, g = i ? r.provideService(h, H, i) : h, _ = await this.runtime.runPromise(g), v = b(_, e, "sqlite")[0];
156
+ if (!v) throw Error(`SqliteStore.upsert: no row returned for table '${e}'`);
157
+ let y = t.id !== void 0 && t.id === v.id ? "insert" : "update";
157
158
  return await this.routeEvent({
158
159
  table: e,
159
- op: v,
160
+ op: y,
160
161
  old: null,
161
- new: _
162
- }, a, i, o), _;
162
+ new: v
163
+ }, a, i, o), v;
163
164
  }
164
165
  async executeInsertIgnore(e, t, n, i, a, o) {
165
166
  t = P(e, t);
166
- let s = this.sql, c = n.conflictColumns.map((e) => s`${s(e)}`), l = s`INSERT INTO ${s(this.nsT(e))} ${s.insert($(t, e))} ON CONFLICT (${s.csv(c)}) DO NOTHING RETURNING *`, u = i ? r.provideService(l, H, i) : l, d = (await this.runtime.runPromise(u))[0];
167
- if (d) return await this.routeEvent({
167
+ let s = this.sql, c = n.conflictColumns.map((e) => s`${s(e)}`), l = s`INSERT INTO ${s(this.nsT(e))} ${s.insert($(t, e))} ON CONFLICT (${s.csv(c)}) DO NOTHING RETURNING *`, u = i ? r.provideService(l, H, i) : l, d = await this.runtime.runPromise(u), f = b(d, e, "sqlite")[0];
168
+ if (f) return await this.routeEvent({
168
169
  table: e,
169
170
  op: "insert",
170
171
  old: null,
171
- new: d
172
- }, a, i, o), d;
173
- let f = await this.findByConflict(e, t, n.conflictColumns, i);
174
- if (!f) throw Error(`SqliteStore.insertIgnore: conflict fired but no existing row found in '${e}'`);
175
- return f;
172
+ new: f
173
+ }, a, i, o), {
174
+ row: f,
175
+ outcome: "inserted"
176
+ };
177
+ let p = await this.findByConflict(e, t, n.conflictColumns, i);
178
+ if (!p) throw Error(`SqliteStore.insertIgnore: conflict fired but no existing row found in '${e}'`);
179
+ return {
180
+ row: p,
181
+ outcome: "ignored"
182
+ };
176
183
  }
177
184
  async findByConflict(e, t, n, i) {
178
185
  if (n.length === 0) return;
179
- let a = this.sql, o = n.map((e) => a`${a(e)} = ${t[e]}`), s = a`SELECT * FROM ${a(this.nsT(e))} WHERE ${a.and(o)} LIMIT 1`, c = i ? r.provideService(s, H, i) : s;
180
- return (await this.runtime.runPromise(c))[0];
186
+ let a = this.sql, o = n.map((e) => a`${a(e)} = ${t[e]}`), s = a`SELECT * FROM ${a(this.nsT(e))} WHERE ${a.and(o)} LIMIT 1`, c = i ? r.provideService(s, H, i) : s, l = await this.runtime.runPromise(c);
187
+ return b(l, e, "sqlite")[0];
181
188
  }
182
189
  query(e) {
183
190
  return this.runWithEager(e, null);
@@ -190,7 +197,7 @@ var U = (r) => e.layerConfig({
190
197
  return E(this.systemName, "raw", () => this.runtime.runPromise(i));
191
198
  }
192
199
  async runWithEager(e, t) {
193
- if (!S(e)) return this.executeQuery(e, t);
200
+ if (!C(e)) return this.executeQuery(e, t);
194
201
  let n = this.namespace === null ? h(e, this.sql, "sqlite") : null;
195
202
  if (n !== null) try {
196
203
  let e = t ? r.provideService(n.fragment, H, t) : n.fragment, i = await E(this.systemName, "select", () => this.runtime.runPromise(e));
@@ -250,7 +257,7 @@ var U = (r) => e.layerConfig({
250
257
  }
251
258
  async executeUpdateMany(e, t, n, i, a, o) {
252
259
  let s = this.sql, c = _(Q(n.where), s, this.namespace), l = s`UPDATE ${s(this.nsT(e))} SET ${s.update($(t, e))} WHERE ${c} RETURNING *`, u = i ? r.provideService(l, H, i) : l, d = await E(this.systemName, "update", () => this.runtime.runPromise(u));
253
- for (let t of d) await this.routeEvent({
260
+ for (let t of b(d, e, "sqlite")) await this.routeEvent({
254
261
  table: e,
255
262
  op: "update",
256
263
  old: null,
@@ -260,7 +267,7 @@ var U = (r) => e.layerConfig({
260
267
  }
261
268
  async executeDeleteMany(e, t, n, i, a) {
262
269
  let o = this.sql, s = _(Q(t.where), o, this.namespace), c = o`DELETE FROM ${o(this.nsT(e))} WHERE ${s} RETURNING *`, l = n ? r.provideService(c, H, n) : c, u = await E(this.systemName, "delete", () => this.runtime.runPromise(l));
263
- for (let t of u) await this.routeEvent({
270
+ for (let t of b(u, e, "sqlite")) await this.routeEvent({
264
271
  table: e,
265
272
  op: "delete",
266
273
  old: t,
@@ -272,6 +279,9 @@ var U = (r) => e.layerConfig({
272
279
  return this.localWrite("upsert", e, (r, i, a) => this.executeUpsert(e, t, n, i, a, r));
273
280
  }
274
281
  insertIgnore(e, t, n) {
282
+ return this.insertIgnoreWithOutcome(e, t, n).then((e) => e.row);
283
+ }
284
+ insertIgnoreWithOutcome(e, t, n) {
275
285
  return this.localWrite("upsert", e, (r, i, a) => this.executeInsertIgnore(e, t, n, i, a, r));
276
286
  }
277
287
  emitChange(e) {
@@ -332,7 +342,7 @@ var U = (r) => e.layerConfig({
332
342
  async transactional(e) {
333
343
  this.inflightTxns++;
334
344
  try {
335
- return await te({
345
+ return await N({
336
346
  ...this.txnSpec("SqliteStore.transactional"),
337
347
  work: e,
338
348
  makeView: (e, t) => new ae(this, e, t)
@@ -364,7 +374,7 @@ var U = (r) => e.layerConfig({
364
374
  };
365
375
  }
366
376
  injectExternalChange(e) {
367
- C(e.table) && this.emitter.emit("change", ee(e));
377
+ w(e.table) && this.emitter.emit("change", S(e));
368
378
  }
369
379
  run(e) {
370
380
  return this.runtime.runPromise(e);
@@ -426,6 +436,9 @@ var U = (r) => e.layerConfig({
426
436
  return this.parent.getInternalExecuteUpsert()(e, t, n, this.txn, this.events, this.attr);
427
437
  }
428
438
  insertIgnore(e, t, n) {
439
+ return this.insertIgnoreWithOutcome(e, t, n).then((e) => e.row);
440
+ }
441
+ insertIgnoreWithOutcome(e, t, n) {
429
442
  return this.parent.getInternalExecuteInsertIgnore()(e, t, n, this.txn, this.events, this.attr);
430
443
  }
431
444
  transactional(e) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@voltro/sql-sqlite",
3
- "version": "0.70.0",
3
+ "version": "0.71.1",
4
4
  "description": "SQLite dialect adapter for Voltro's cross-dialect DataStore (single-process; in-process change events).",
5
5
  "keywords": [
6
6
  "voltro",
@@ -35,8 +35,8 @@
35
35
  "dependencies": {
36
36
  "@effect/sql": "^0.52.1",
37
37
  "@effect/sql-sqlite-node": "^0.53.0",
38
- "@voltro/database": "0.70.0",
39
- "@voltro/logger": "0.70.0"
38
+ "@voltro/database": "0.71.1",
39
+ "@voltro/logger": "0.71.1"
40
40
  },
41
41
  "peerDependencies": {
42
42
  "effect": "^3.22.1"