@voltro/sql-mssql 0.83.0 → 0.84.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/dist/index.d.ts CHANGED
@@ -289,7 +289,7 @@ export declare class MssqlStore implements DataStore {
289
289
  * — every value binds as a parameter (no interpolation), `$action`
290
290
  * distinguishes the insert vs update branch so the change event is
291
291
  * emitted with the right `op`, and `INSERTED.*` returns the post-image
292
- * in the SAME round-trip. Only reached for the column-list / default
292
+ * from that write. Only reached for the column-list / default
293
293
  * `update` form; the function form can't express its patch in a MERGE.
294
294
  */
295
295
  private mergeUpsert;
package/dist/index.js CHANGED
@@ -1,35 +1,41 @@
1
1
  import { MssqlClient as e } from "@effect/sql-mssql";
2
2
  import { TYPES as t } from "tedious";
3
3
  import { Config as n, Duration as r, Effect as i, Layer as a, ManagedRuntime as o, Option as s, Redacted as c } from "effect";
4
- import { CDC_OFFSETS_TABLE as l, DEFAULT_ACQUIRE_TIMEOUT_MS as u, EagerCardinalityError as d, MSSQL_TRANSIENT_NUMBERS as f, _voltroMssqlCdcOffsetsTable as p, attachEagerLoads as m, attributionFields as h, bulkInsertLimitsFor as g, causeBranches as _, chunkRowsForInsert as v, compileEagerJson as y, compileJsonPatch as b, compilePredicate as x, compileRawFragment as S, compileSelect as ee, decodeRowsFromSchema as C, encodeRowForSchema as w, externalChangeEvent as T, hasEagerLoads as te, isTableReactive as E, jsonPatchAssignments as ne, makeEagerFallbackReporter as re, makeTransactionAbortTracker as ie, observeDbOp as D, qualifyTable as ae, quoteIdent as oe, raiseChangeListenerCeiling as O, recordsTable as k, requireTable as se, rowKeyColumns as A, runSavepoint as ce, runStoreTransaction as le, runWriteRecorders as ue, stampGeneratedId as j, stampGeneratedIds as de, upsertUpdatePatch as M, upsertUpdateValues as N, withCapturedAttribution as fe } from "@voltro/database";
5
- import { EventEmitter as pe } from "node:events";
6
- import { createLogger as P } from "@voltro/logger";
7
- import { SqlClient as F, TransactionConnection as I } from "@effect/sql/SqlClient";
4
+ import { CDC_OFFSETS_TABLE as l, DEFAULT_ACQUIRE_TIMEOUT_MS as u, EagerCardinalityError as d, MSSQL_TRANSIENT_NUMBERS as f, _voltroMssqlCdcOffsetsTable as p, attachEagerLoads as m, attributionFields as h, bulkInsertLimitsFor as g, causeBranches as _, chunkRowsForInsert as v, compileEagerJson as y, compileJsonPatch as b, compilePredicate as x, compileRawFragment as S, compileSelect as ee, decodeRowsFromSchema as C, encodeRowForSchema as w, externalChangeEvent as T, hasEagerLoads as te, isTableReactive as E, jsonPatchAssignments as ne, makeEagerFallbackReporter as re, makeTransactionAbortTracker as ie, observeDbOp as D, qualifyTable as ae, quoteIdent as oe, raiseChangeListenerCeiling as se, recordsTable as O, requireTable as ce, rowKeyColumns as k, runSavepoint as le, runStoreTransaction as ue, runWriteRecorders as de, stampGeneratedId as A, stampGeneratedIds as fe, upsertUpdatePatch as j, upsertUpdateValues as M, withCapturedAttribution as pe } from "@voltro/database";
5
+ import { EventEmitter as me } from "node:events";
6
+ import { SqlError as he } from "@effect/sql";
7
+ import { createLogger as N } from "@voltro/logger";
8
+ import { SqlClient as P, TransactionConnection as F } from "@effect/sql/SqlClient";
8
9
  //#region src/numberParameter.ts
9
- var L = (e) => typeof e == "bigint" ? t.BigInt : typeof e == "number" && Number.isSafeInteger(e) ? e >= -2147483648 && e <= 2147483647 ? t.Int : t.BigInt : t.Float, me = {
10
+ var I = (e) => typeof e == "bigint" ? t.BigInt : typeof e == "number" && Number.isSafeInteger(e) ? e >= -2147483648 && e <= 2147483647 ? t.Int : t.BigInt : t.Float, ge = {
10
11
  ...t.Int,
11
- declaration: (e) => L(e.value).declaration(e),
12
- generateTypeInfo: (e, t) => L(e.value).generateTypeInfo(e, t),
13
- generateParameterLength: (e, t) => L(e.value).generateParameterLength(e, t),
14
- generateParameterData: (e, t) => L(e.value).generateParameterData(e, t),
12
+ declaration: (e) => I(e.value).declaration(e),
13
+ generateTypeInfo: (e, t) => I(e.value).generateTypeInfo(e, t),
14
+ generateParameterLength: (e, t) => I(e.value).generateParameterLength(e, t),
15
+ generateParameterData: (e, t) => I(e.value).generateParameterData(e, t),
15
16
  validate: (e, t, n) => {
16
17
  if (typeof e == "number" && !Number.isFinite(e)) throw TypeError("SQL Server numeric parameters must be finite.");
17
- return L(e).validate(e, t, n);
18
+ return I(e).validate(e, t, n);
18
19
  }
19
- }, R = {
20
+ }, _e = {
21
+ ...t.VarBinary,
22
+ resolveLength: (e) => Math.max(1, t.VarBinary.resolveLength(e)),
23
+ validate: (e, n, r) => t.VarBinary.validate(e instanceof Uint8Array && !Buffer.isBuffer(e) ? Buffer.from(e.buffer, e.byteOffset, e.byteLength) : e, n, r)
24
+ }, ve = {
20
25
  ...e.defaultParameterTypes,
21
26
  null: t.NVarChar,
22
27
  Date: t.DateTime2,
23
28
  string: t.NVarChar,
24
- number: me
25
- }, z = (e) => {
29
+ number: ge,
30
+ Uint8Array: _e
31
+ }, ye = (e) => {
26
32
  let t = e.acquireTimeoutMs ?? u;
27
33
  return t > 0 ? t : void 0;
28
- }, B = (t) => {
29
- let i = z(t);
34
+ }, L = (t) => {
35
+ let i = ye(t);
30
36
  return e.layerConfig({
31
37
  server: n.succeed(t.server),
32
- parameterTypes: n.succeed(R),
38
+ parameterTypes: n.succeed(ve),
33
39
  ...i === void 0 ? {} : { connectTimeout: n.succeed(r.millis(i)) },
34
40
  ...t.port === void 0 ? {} : { port: n.succeed(t.port) },
35
41
  ...t.database === void 0 ? {} : { database: n.succeed(t.database) },
@@ -39,7 +45,7 @@ var L = (e) => typeof e == "bigint" ? t.BigInt : typeof e == "number" && Number.
39
45
  ...t.trustServer === void 0 ? {} : { trustServer: n.succeed(t.trustServer) },
40
46
  ...t.maxConnections === void 0 ? {} : { maxConnections: n.succeed(t.maxConnections) }
41
47
  });
42
- }, he = (e) => {
48
+ }, be = (e) => {
43
49
  let t = e.get("sslmode");
44
50
  if (t !== null) {
45
51
  if (t === "require") return !0;
@@ -54,7 +60,7 @@ var L = (e) => typeof e == "bigint" ? t.BigInt : typeof e == "number" && Number.
54
60
  throw Error(`DB_URL '?${t}=${n}' is not supported by the mssql dialect — use 'true'/'1' or 'false'/'0'.`);
55
61
  }
56
62
  }
57
- }, V = (e) => {
63
+ }, R = (e) => {
58
64
  let t = e.acquireTimeoutMs === void 0 ? {} : { acquireTimeoutMs: e.acquireTimeoutMs }, n = (e) => e === void 0 ? {} : {
59
65
  encrypt: e,
60
66
  ...e ? { trustServer: !0 } : {}
@@ -67,7 +73,7 @@ var L = (e) => typeof e == "bigint" ? t.BigInt : typeof e == "number" && Number.
67
73
  username: decodeURIComponent(r.username || "sa"),
68
74
  password: decodeURIComponent(r.password || ""),
69
75
  database: r.pathname.replace(/^\//, "") || "master",
70
- ...n(e.ssl ?? he(r.searchParams)),
76
+ ...n(e.ssl ?? be(r.searchParams)),
71
77
  ...e.maxConnections === void 0 ? {} : { maxConnections: e.maxConnections },
72
78
  ...t
73
79
  };
@@ -82,7 +88,29 @@ var L = (e) => typeof e == "bigint" ? t.BigInt : typeof e == "number" && Number.
82
88
  ...e.maxConnections === void 0 ? {} : { maxConnections: e.maxConnections },
83
89
  ...t
84
90
  };
85
- }, H = (e) => B(V(e)), ge = f, U = (e) => {
91
+ }, z = (e) => L(R(e)), B = (e, t) => i.gen(function* () {
92
+ let n = yield* e`
93
+ SELECT name, system_type_id FROM sys.columns
94
+ WHERE object_id = OBJECT_ID(${e`${e(t)}`.compile()[0]}, 'U')
95
+ ORDER BY column_id
96
+ `.withoutTransform;
97
+ return n.length === 0 ? yield* new he.SqlError({ message: `Cannot inspect result columns for ${t}` }) : n;
98
+ }), V = (e, t, n) => e.join(", ", !1)(t.map((t) => {
99
+ let r = e.literal(`[${t.name.replaceAll("]", "]]")}]`), i = n ? e`${e(n)}.${r}` : r;
100
+ return t.system_type_id === 106 || t.system_type_id === 108 ? e`CONVERT(varchar(80), ${i}) AS ${r}` : i;
101
+ })), H = (e, t, n, r = !1) => i.uninterruptible(i.gen(function* () {
102
+ let i = e.literal("[#voltro_write_output]"), a = yield* B(e, t), o = e.join(", ", !1)(a.map((t) => {
103
+ let n = e.literal(`[${t.name.replaceAll("]", "]]")}]`);
104
+ return t.system_type_id === 189 ? e`CONVERT(binary(8), ${n}) AS ${n}` : n;
105
+ })), s = V(e, a);
106
+ return yield* e`
107
+ SELECT TOP (0) ${r ? e.literal("CAST(NULL AS nvarchar(10)) AS [__action],") : e.literal("")} source.* INTO ${i}
108
+ FROM (SELECT ${o} FROM ${e(t)} UNION ALL SELECT ${o} FROM ${e(t)}) AS source;
109
+ ${n(i)};
110
+ SELECT ${r ? e.literal("[__action],") : e.literal("")}${s} FROM ${i};
111
+ DROP TABLE ${i};
112
+ `;
113
+ })), xe = f, U = (e) => {
86
114
  let t = e;
87
115
  for (let e = 0; e < 5 && typeof t == "object" && t; e++) {
88
116
  let e = t.number;
@@ -93,16 +121,16 @@ var L = (e) => typeof e == "bigint" ? t.BigInt : typeof e == "number" && Number.
93
121
  }
94
122
  }, W = (e) => _(e).some((e) => {
95
123
  let t = U(e);
96
- return t !== void 0 && ge.has(t);
97
- }), _e = /* @__PURE__ */ new Set(["2601", "2627"]), G = (e) => _(e).some((e) => {
124
+ return t !== void 0 && xe.has(t);
125
+ }), Se = /* @__PURE__ */ new Set(["2601", "2627"]), G = (e) => _(e).some((e) => {
98
126
  let t = U(e);
99
- return t !== void 0 && _e.has(t);
100
- }), K = (e) => W(e) ? "retry" : "noRetry", ve = {
127
+ return t !== void 0 && Se.has(t);
128
+ }), K = (e) => W(e) ? "retry" : "noRetry", Ce = {
101
129
  I: "insert",
102
130
  U: "update",
103
131
  D: "delete"
104
132
  }, q = (e, t) => e(i.gen(function* () {
105
- let e = yield* F;
133
+ let e = yield* P;
106
134
  if (((yield* e`
107
135
  SELECT COUNT(*) AS ${e("on")}
108
136
  FROM sys.change_tracking_databases
@@ -122,11 +150,11 @@ var L = (e) => typeof e == "bigint" ? t.BigInt : typeof e == "number" && Number.
122
150
  }
123
151
  return n;
124
152
  })), J = (e) => `'${e.replace(/'/g, "''")}'`, Y = (e) => `[${e.replace(/\]/g, "]]")}]`, X = async (e) => {
125
- let t = P({ scope: "voltro:mssql:cdc" }), n = e.pollIntervalMs ?? 500, r = await q(e.run, e.tables), a = /* @__PURE__ */ new Set(), o = async () => (await e.run(i.gen(function* () {
126
- return yield* (yield* F)`SELECT CONVERT(VARCHAR(40), CHANGE_TRACKING_CURRENT_VERSION()) AS v`;
153
+ let t = N({ scope: "voltro:mssql:cdc" }), n = e.pollIntervalMs ?? 500, r = await q(e.run, e.tables), a = /* @__PURE__ */ new Set(), o = async () => (await e.run(i.gen(function* () {
154
+ return yield* (yield* P)`SELECT CONVERT(VARCHAR(40), CHANGE_TRACKING_CURRENT_VERSION()) AS v`;
127
155
  })))[0]?.v ?? "0", s = e.startVersion ?? await o(), c = !1, l = null, u = !1, d = (e, t) => BigInt(e) > BigInt(t), f = async (n, r) => {
128
156
  let c = await e.run(i.gen(function* () {
129
- let e = yield* F, t = e.unsafe(Y(n)), i = (yield* e`
157
+ let e = yield* P, t = e.unsafe(Y(n)), i = (yield* e`
130
158
  SELECT CONVERT(VARCHAR(40), CHANGE_TRACKING_MIN_VALID_VERSION(OBJECT_ID(${e.unsafe(J(n))}))) AS floor`)[0]?.floor, o = r;
131
159
  if (i != null && BigInt(r) < BigInt(i)) {
132
160
  if (!a.has(n)) return {
@@ -138,7 +166,7 @@ var L = (e) => typeof e == "bigint" ? t.BigInt : typeof e == "number" && Number.
138
166
  return {
139
167
  resync: !1,
140
168
  rows: yield* e`
141
- SELECT ct.SYS_CHANGE_OPERATION AS __ct_op, ct.id AS __ct_id, t.*
169
+ SELECT ct.SYS_CHANGE_OPERATION AS __ct_op, ct.id AS __ct_id, ${V(e, yield* B(e, n), "t")}
142
170
  FROM CHANGETABLE(CHANGES ${t}, ${BigInt(o)}) AS ct
143
171
  LEFT JOIN ${t} AS t ON t.id = ct.id
144
172
  ORDER BY ct.SYS_CHANGE_VERSION`.unprepared
@@ -149,7 +177,7 @@ var L = (e) => typeof e == "bigint" ? t.BigInt : typeof e == "number" && Number.
149
177
  return;
150
178
  }
151
179
  for (let t of c.rows) {
152
- let r = ve[t.__ct_op];
180
+ let r = Ce[t.__ct_op];
153
181
  if (!r) continue;
154
182
  let { __ct_op: i, __ct_id: a, ...o } = t;
155
183
  if (r === "delete") e.onChange({
@@ -188,7 +216,7 @@ var L = (e) => typeof e == "bigint" ? t.BigInt : typeof e == "number" && Number.
188
216
  s = d(t, s) ? t : s, e.onVersion?.(s);
189
217
  }
190
218
  } catch (n) {
191
- t.warn("cdc: poll cycle failed — retrying next tick", {}, n), e.onError?.(n);
219
+ c || (t.warn("cdc: poll cycle failed — retrying next tick", {}, n), e.onError?.(n));
192
220
  } finally {
193
221
  u = !1, c || (l = setTimeout(() => {
194
222
  p();
@@ -207,12 +235,12 @@ var L = (e) => typeof e == "bigint" ? t.BigInt : typeof e == "number" && Number.
207
235
  },
208
236
  currentVersion: () => s
209
237
  };
210
- }, Z = P({ scope: "voltro:mssql" }), Q = async (e) => {
238
+ }, Z = N({ scope: "voltro:mssql" }), Q = async (e) => {
211
239
  let t = e.changeStrategy ?? "inline", n = t;
212
240
  t === "cdc" && !e.cdcConfig && (Z.warn("changeStrategy='cdc' requires cdcConfig (replicaId + includeTables); falling back to 'inline'."), n = "inline");
213
- let r = e.tracerLayer ? a.mergeAll(e.sqlLayer, e.tracerLayer) : e.sqlLayer, i = o.make(r), s = new ye(await i.runPromise(F), i, n);
241
+ let r = e.tracerLayer ? a.mergeAll(e.sqlLayer, e.tracerLayer) : e.sqlLayer, i = o.make(r), s = new we(await i.runPromise(P), i, n);
214
242
  return n === "cdc" && e.cdcConfig && await s.startCdcConsumer(e.cdcConfig), s;
215
- }, ye = class e {
243
+ }, we = class e {
216
244
  sql;
217
245
  runtime;
218
246
  changeStrategy;
@@ -226,7 +254,7 @@ var L = (e) => typeof e == "bigint" ? t.BigInt : typeof e == "number" && Number.
226
254
  cdcReplicaId = "";
227
255
  cdcStreamName = "default";
228
256
  constructor(e, t, n = "inline", r = null, i) {
229
- this.sql = e, this.runtime = t, this.changeStrategy = n, this.namespace = r, this.emitter = i ?? new pe(), O(this.emitter);
257
+ this.sql = e, this.runtime = t, this.changeStrategy = n, this.namespace = r, this.emitter = i ?? new me(), se(this.emitter);
230
258
  }
231
259
  get inlineEmit() {
232
260
  return this.changeStrategy === "inline";
@@ -239,15 +267,15 @@ var L = (e) => typeof e == "bigint" ? t.BigInt : typeof e == "number" && Number.
239
267
  }
240
268
  __mssqlReplicationFriend = { runEffect: (e) => this.runtime.runPromise(e) };
241
269
  async executeQuery(e, t) {
242
- let n = ee(e, this.sql, this.namespace), r = t ? i.provideService(n, I, t) : n, a = await D("mssql", "select", () => this.runtime.runPromise(r));
270
+ let n = ee(e, this.sql, this.namespace), r = t ? i.provideService(n, F, t) : n, a = await D("mssql", "select", () => this.runtime.runPromise(r));
243
271
  return C(a, e.table, "mssql");
244
272
  }
245
273
  decodeWritten(e, t) {
246
274
  return C([t], e, "mssql")[0] ?? t;
247
275
  }
248
276
  async executeInsert(e, t, n, r, a) {
249
- t = j(e, t);
250
- let o = this.sql, s = o`INSERT INTO ${o(this.nsT(e))} ${o.insert(w(t, e)).returning("*")}`, c = n ? i.provideService(s, I, n) : s, l = (await this.runtime.runPromise(c))[0];
277
+ t = A(e, t);
278
+ let o = this.sql, s = H(o, this.nsT(e), (n) => o`INSERT INTO ${o(this.nsT(e))} ${o.insert(w(t, e)).returning(o`INSERTED.* INTO ${n}`)}`), c = n ? i.provideService(s, F, n) : s, l = (await this.runtime.runPromise(c))[0];
251
279
  if (!l) throw Error(`MssqlStore.insert: row not returned post-insert in '${e}'`);
252
280
  let u = this.decodeWritten(e, l);
253
281
  return await this.routeEvent({
@@ -258,7 +286,7 @@ var L = (e) => typeof e == "bigint" ? t.BigInt : typeof e == "number" && Number.
258
286
  }, r, n, a), u;
259
287
  }
260
288
  async executeUpdate(e, t, n, r, a, o) {
261
- let s = this.sql, c = s`UPDATE ${s(this.nsT(e))} SET ${s.update(w(n, e)).returning("*")} WHERE ${s.and(A(t).map(([e, t]) => s`${s(e)} = ${t}`))}`, l = r ? i.provideService(c, I, r) : c, u = (await this.runtime.runPromise(l))[0];
289
+ let s = this.sql, c = H(s, this.nsT(e), (r) => s`UPDATE ${s(this.nsT(e))} SET ${s.update(w(n, e)).returning(s`INSERTED.* INTO ${r}`)} WHERE ${s.and(k(t).map(([e, t]) => s`${s(e)} = ${t}`))}`), l = r ? i.provideService(c, F, r) : c, u = (await this.runtime.runPromise(l))[0];
262
290
  if (!u) return null;
263
291
  let d = this.decodeWritten(e, u);
264
292
  return await this.routeEvent({
@@ -269,14 +297,14 @@ var L = (e) => typeof e == "bigint" ? t.BigInt : typeof e == "number" && Number.
269
297
  }, a, r, o), d;
270
298
  }
271
299
  async executeInsertMany(e, t, n, r, a) {
272
- if (t = de(e, t), t.length === 0) return [];
273
- let o = this.sql, s = v(t, g("mssql")), c = (t) => o`INSERT INTO ${o(this.nsT(e))} ${o.insert(t.map((t) => w(t, e))).returning("*")}`, l;
300
+ if (t = fe(e, t), t.length === 0) return [];
301
+ let o = this.sql, s = v(t, g("mssql")), c = (t) => H(o, this.nsT(e), (n) => o`INSERT INTO ${o(this.nsT(e))} ${o.insert(t.map((t) => w(t, e))).returning(o`INSERTED.* INTO ${n}`)}`), l;
274
302
  if (s.length === 1) {
275
- let e = c(s[0]), t = n ? i.provideService(e, I, n) : e;
303
+ let e = c(s[0]), t = n ? i.provideService(e, F, n) : e;
276
304
  l = await this.runtime.runPromise(t);
277
305
  } else if (n) {
278
306
  let e = [];
279
- for (let t of s) e.push(...await this.runtime.runPromise(i.provideService(c(t), I, n)));
307
+ for (let t of s) e.push(...await this.runtime.runPromise(i.provideService(c(t), F, n)));
280
308
  l = e;
281
309
  } else l = await this.runtime.runPromise(o.withTransaction(i.map(i.forEach(s, c, { concurrency: 1 }), (e) => e.flat())));
282
310
  let u = t.map((e) => e.id), d = C(l, e, "mssql"), f = new Map(d.map((e) => [e.id, e])), p = u.map((e) => f.get(e)).filter((e) => e !== void 0), m = p.length === l.length ? p : d;
@@ -289,7 +317,7 @@ var L = (e) => typeof e == "bigint" ? t.BigInt : typeof e == "number" && Number.
289
317
  return m;
290
318
  }
291
319
  async executePatchJson(e, t, n, r, a, o, s, c) {
292
- let l = this.sql, u = w(ne(t, n, c), e), d = l.csv([b(l, "mssql", n, r), ...Object.entries(u).map(([e, t]) => l`${l(e)} = ${t}`)]), f = l`UPDATE ${l(this.nsT(e))} SET ${d} OUTPUT INSERTED.* WHERE ${l.and(A(t).map(([e, t]) => l`${l(e)} = ${t}`))}`, p = a ? i.provideService(f, I, a) : f, m = (await this.runtime.runPromise(p))[0];
320
+ let l = this.sql, u = w(ne(t, n, c), e), d = l.csv([b(l, "mssql", n, r), ...Object.entries(u).map(([e, t]) => l`${l(e)} = ${t}`)]), f = H(l, this.nsT(e), (n) => l`UPDATE ${l(this.nsT(e))} SET ${d} OUTPUT INSERTED.* INTO ${n} WHERE ${l.and(k(t).map(([e, t]) => l`${l(e)} = ${t}`))}`), p = a ? i.provideService(f, F, a) : f, m = (await this.runtime.runPromise(p))[0];
293
321
  if (!m) return null;
294
322
  let h = this.decodeWritten(e, m);
295
323
  return await this.routeEvent({
@@ -300,7 +328,7 @@ var L = (e) => typeof e == "bigint" ? t.BigInt : typeof e == "number" && Number.
300
328
  }, o, a, s), h;
301
329
  }
302
330
  async executeDelete(e, t, n, r, a) {
303
- let o = this.sql, s = o`DELETE FROM ${o(this.nsT(e))} OUTPUT DELETED.* WHERE ${o.and(A(t).map(([e, t]) => o`${o(e)} = ${t}`))}`, c = n ? i.provideService(s, I, n) : s, l = (await this.runtime.runPromise(c))[0];
331
+ let o = this.sql, s = H(o, this.nsT(e), (n) => o`DELETE FROM ${o(this.nsT(e))} OUTPUT DELETED.* INTO ${n} WHERE ${o.and(k(t).map(([e, t]) => o`${o(e)} = ${t}`))}`), c = n ? i.provideService(s, F, n) : s, l = (await this.runtime.runPromise(c))[0];
304
332
  if (!l) return !1;
305
333
  let u = this.decodeWritten(e, l);
306
334
  return await this.routeEvent({
@@ -312,17 +340,17 @@ var L = (e) => typeof e == "bigint" ? t.BigInt : typeof e == "number" && Number.
312
340
  }
313
341
  async appendInTxn(e, t, n) {
314
342
  let r = this.sql, a = r`INSERT INTO ${r(this.nsT(e))} ${r.insert(w(t, e))}`;
315
- await this.runtime.runPromise(n ? i.provideService(a, I, n) : a);
343
+ await this.runtime.runPromise(n ? i.provideService(a, F, n) : a);
316
344
  }
317
345
  async maxInTxn(e, t, n, r) {
318
- let a = this.sql, o = Object.entries(n).map(([e, t]) => a`${a(e)} = ${t}`), s = a`SELECT MAX(${a(t)}) AS ${a("m")} FROM ${a(this.nsT(e))} WHERE ${a.and(o)}`, c = (await this.runtime.runPromise(r ? i.provideService(s, I, r) : s))[0]?.m;
346
+ let a = this.sql, o = Object.entries(n).map(([e, t]) => a`${a(e)} = ${t}`), s = a`SELECT MAX(${a(t)}) AS ${a("m")} FROM ${a(this.nsT(e))} WHERE ${a.and(o)}`, c = (await this.runtime.runPromise(r ? i.provideService(s, F, r) : s))[0]?.m;
319
347
  return c == null ? null : Number(c);
320
348
  }
321
349
  async routeEvent(e, t, n = null, r) {
322
350
  e = {
323
351
  ...h(r),
324
352
  ...e
325
- }, k(e.table) && await ue({
353
+ }, O(e.table) && await de({
326
354
  append: (e, t) => this.appendInTxn(e, t, n),
327
355
  maxOf: (e, t, r) => this.maxInTxn(e, t, r, n)
328
356
  }, {
@@ -341,14 +369,14 @@ var L = (e) => typeof e == "bigint" ? t.BigInt : typeof e == "number" && Number.
341
369
  return this.rawOn(e, null);
342
370
  }
343
371
  rawOn(e, t) {
344
- let n = S(e, this.sql), r = t ? i.provideService(n, I, t) : n;
372
+ let n = S(e, this.sql), r = t ? i.provideService(n, F, t) : n;
345
373
  return D("mssql", "raw", () => this.runtime.runPromise(r));
346
374
  }
347
375
  async runWithEager(e, t) {
348
376
  if (!te(e)) return this.executeQuery(e, t);
349
377
  let n = this.namespace === null ? y(e, this.sql, "mssql") : null;
350
378
  if (n !== null) try {
351
- let e = t ? i.provideService(n.fragment, I, t) : n.fragment, r = await D("mssql", "select", () => this.runtime.runPromise(e));
379
+ let e = t ? i.provideService(n.fragment, F, t) : n.fragment, r = await D("mssql", "select", () => this.runtime.runPromise(e));
352
380
  return n.decode(r);
353
381
  } catch (t) {
354
382
  if (t instanceof d) throw t;
@@ -365,17 +393,17 @@ var L = (e) => typeof e == "bigint" ? t.BigInt : typeof e == "number" && Number.
365
393
  reason: "not-compilable"
366
394
  });
367
395
  let r = await this.executeQuery(e, t);
368
- return m(r, e.eager, e.sourceTable ?? se(e.table), (e) => this.executeQuery(e, t));
396
+ return m(r, e.eager, e.sourceTable ?? ce(e.table), (e) => this.executeQuery(e, t));
369
397
  }
370
398
  getInternalRunWithEager() {
371
399
  return this.runWithEager.bind(this);
372
400
  }
373
401
  localWrite(e, t, n) {
374
- let r = (e) => k(t) ? this.writeWithRecorders(n, e) : n(e, null, null);
375
- return D("mssql", e, () => fe(r));
402
+ let r = (e) => O(t) ? this.writeWithRecorders(n, e) : n(e, null, null);
403
+ return D("mssql", e, () => pe(r));
376
404
  }
377
405
  async writeWithRecorders(e, t) {
378
- let n = [], r = this.sql, a = await this.runtime.runPromise(r.withTransaction(i.flatMap(i.serviceOption(I), (r) => s.isNone(r) ? i.fail(/* @__PURE__ */ Error("MssqlStore.write: TransactionConnection missing.")) : i.tryPromise({
406
+ let n = [], r = this.sql, a = await this.runtime.runPromise(r.withTransaction(i.flatMap(i.serviceOption(F), (r) => s.isNone(r) ? i.fail(/* @__PURE__ */ Error("MssqlStore.write: TransactionConnection missing.")) : i.tryPromise({
379
407
  try: () => e(t, r.value, n),
380
408
  catch: (e) => e
381
409
  }))));
@@ -404,7 +432,7 @@ var L = (e) => typeof e == "bigint" ? t.BigInt : typeof e == "number" && Number.
404
432
  return this.executeDeleteMany(e, t, null, null);
405
433
  }
406
434
  async executeUpdateMany(e, t, n, r, a, o) {
407
- let s = this.sql, c = x(n.where, s, this.namespace), l = s`UPDATE ${s(this.nsT(e))} SET ${s.update(w(t, e))} OUTPUT INSERTED.* WHERE ${c}`, u = r ? i.provideService(l, I, r) : l, d = await D("mssql", "update", () => this.runtime.runPromise(u));
435
+ let s = this.sql, c = x(n.where, s, this.namespace), l = H(s, this.nsT(e), (n) => s`UPDATE ${s(this.nsT(e))} SET ${s.update(w(t, e))} OUTPUT INSERTED.* INTO ${n} WHERE ${c}`), u = r ? i.provideService(l, F, r) : l, d = await D("mssql", "update", () => this.runtime.runPromise(u));
408
436
  for (let t of C(d, e, "mssql")) await this.routeEvent({
409
437
  table: e,
410
438
  op: "update",
@@ -414,7 +442,7 @@ var L = (e) => typeof e == "bigint" ? t.BigInt : typeof e == "number" && Number.
414
442
  return d.length;
415
443
  }
416
444
  async executeDeleteMany(e, t, n, r, a) {
417
- let o = this.sql, s = x(t.where, o, this.namespace), c = o`DELETE FROM ${o(this.nsT(e))} OUTPUT DELETED.* WHERE ${s}`, l = n ? i.provideService(c, I, n) : c, u = await D("mssql", "delete", () => this.runtime.runPromise(l));
445
+ let o = this.sql, s = x(t.where, o, this.namespace), c = H(o, this.nsT(e), (t) => o`DELETE FROM ${o(this.nsT(e))} OUTPUT DELETED.* INTO ${t} WHERE ${s}`), l = n ? i.provideService(c, F, n) : c, u = await D("mssql", "delete", () => this.runtime.runPromise(l));
418
446
  for (let t of C(u, e, "mssql")) await this.routeEvent({
419
447
  table: e,
420
448
  op: "delete",
@@ -433,32 +461,32 @@ var L = (e) => typeof e == "bigint" ? t.BigInt : typeof e == "number" && Number.
433
461
  return this.localWrite("upsert", e, (r, i, a) => this.executeInsertIgnore(e, t, n, i, a, r));
434
462
  }
435
463
  async executeUpsert(e, t, n, r, i, a) {
436
- if (N(n), t = j(e, t), typeof n.update != "function" && n.conflictColumns.length > 0) return this.mergeUpsert(e, t, {
464
+ if (M(n), t = A(e, t), typeof n.update != "function" && n.conflictColumns.length > 0) return this.mergeUpsert(e, t, {
437
465
  conflictColumns: n.conflictColumns,
438
466
  ...n.update === void 0 ? {} : { update: n.update },
439
467
  ...n.updateValues === void 0 ? {} : { updateValues: n.updateValues }
440
468
  }, r, i, a);
441
469
  let o = await this.findByConflict(e, t, n.conflictColumns, r);
442
- if (o) return await this.executeUpdate(e, o.id, M(t, o, n), r, i, a) ?? o;
470
+ if (o) return await this.executeUpdate(e, Object.fromEntries(n.conflictColumns.map((e) => [e, o[e]])), j(t, o, n), r, i, a) ?? o;
443
471
  try {
444
472
  return await this.executeInsert(e, t, r, i, a);
445
473
  } catch (o) {
446
474
  if (!G(o)) throw o;
447
475
  let s = await this.findByConflict(e, t, n.conflictColumns, r);
448
476
  if (!s) throw o;
449
- return await this.executeUpdate(e, s.id, M(t, s, n), r, i, a) ?? s;
477
+ return await this.executeUpdate(e, Object.fromEntries(n.conflictColumns.map((e) => [e, s[e]])), j(t, s, n), r, i, a) ?? s;
450
478
  }
451
479
  }
452
480
  async mergeUpsert(e, t, n, r, a, o) {
453
- let s = this.sql, c = Object.keys(t), l = Array.isArray(n.update) ? n.update.filter((e) => c.includes(e)) : c.filter((e) => e !== "id" && !n.conflictColumns.includes(e)), u = w(t, e), d = c.map((e) => s`${u[e]}`), f = c.map((e) => s`${s(e)}`), p = n.conflictColumns.map((e) => s`tgt.${s(e)} = src.${s(e)}`), m = c.map((e) => s`${s(e)}`), h = c.map((e) => s`src.${s(e)}`), g = N(n), _ = w(g, e), v = [...l.filter((e) => !Object.hasOwn(g, e)).map((e) => s`tgt.${s(e)} = src.${s(e)}`), ...Object.entries(_).map(([e, t]) => s`tgt.${s(e)} = ${t}`)];
481
+ let s = this.sql, c = Object.keys(t), l = Array.isArray(n.update) ? n.update.filter((e) => c.includes(e)) : c.filter((e) => e !== "id" && !n.conflictColumns.includes(e)), u = w(t, e), d = c.map((e) => s`${u[e]}`), f = c.map((e) => s`${s(e)}`), p = n.conflictColumns.map((e) => s`tgt.${s(e)} = src.${s(e)}`), m = c.map((e) => s`${s(e)}`), h = c.map((e) => s`src.${s(e)}`), g = M(n), _ = w(g, e), v = [...l.filter((e) => !Object.hasOwn(g, e)).map((e) => s`tgt.${s(e)} = src.${s(e)}`), ...Object.entries(_).map(([e, t]) => s`tgt.${s(e)} = ${t}`)];
454
482
  v.length === 0 && v.push(s`tgt.${s(n.conflictColumns[0])} = src.${s(n.conflictColumns[0])}`);
455
- let y = s`
483
+ let y = H(s, this.nsT(e), (t) => s`
456
484
  MERGE ${s(this.nsT(e))} WITH (HOLDLOCK) AS tgt
457
485
  USING (VALUES (${s.csv(d)})) AS src (${s.csv(f)})
458
486
  ON ${s.and(p)}
459
487
  WHEN MATCHED THEN UPDATE SET ${s.csv(v)}
460
488
  WHEN NOT MATCHED THEN INSERT (${s.csv(m)}) VALUES (${s.csv(h)})
461
- OUTPUT $action AS ${s("__action")}, INSERTED.*;`, b = r ? i.provideService(y, I, r) : y, x = (await this.runtime.runPromise(b))[0];
489
+ OUTPUT $action AS ${s("__action")}, INSERTED.* INTO ${t};`, !0), b = r ? i.provideService(y, F, r) : y, x = (await this.runtime.runPromise(b))[0];
462
490
  if (!x) throw Error(`MssqlStore.upsert: MERGE returned no row for '${e}'`);
463
491
  let S = x.__action, { __action: ee, ...C } = x, T = this.decodeWritten(e, C);
464
492
  return await this.routeEvent({
@@ -469,7 +497,7 @@ var L = (e) => typeof e == "bigint" ? t.BigInt : typeof e == "number" && Number.
469
497
  }, a, r, o), T;
470
498
  }
471
499
  async executeInsertIgnore(e, t, n, r, i, a) {
472
- t = j(e, t);
500
+ t = A(e, t);
473
501
  let o = await this.findByConflict(e, t, n.conflictColumns, r);
474
502
  if (o) return {
475
503
  row: o,
@@ -492,7 +520,7 @@ var L = (e) => typeof e == "bigint" ? t.BigInt : typeof e == "number" && Number.
492
520
  }
493
521
  async findByConflict(e, t, n, r) {
494
522
  if (n.length === 0) return;
495
- let a = this.sql, o = n.map((e) => a`${a(e)} = ${t[e]}`), s = a`SELECT TOP 1 * FROM ${a(this.nsT(e))} WHERE ${a.and(o)}`, c = r ? i.provideService(s, I, r) : s, l = (await this.runtime.runPromise(c))[0];
523
+ let a = this.sql, o = n.map((e) => a`${a(e)} = ${t[e]}`), s = a`SELECT TOP 1 * FROM ${a(this.nsT(e))} WHERE ${a.and(o)}`, c = r ? i.provideService(s, F, r) : s, l = (await this.runtime.runPromise(c))[0];
496
524
  return l ? this.decodeWritten(e, l) : void 0;
497
525
  }
498
526
  emitChange(e) {
@@ -605,16 +633,16 @@ var L = (e) => typeof e == "bigint" ? t.BigInt : typeof e == "number" && Number.
605
633
  }
606
634
  async emptyTablesOn(e, t) {
607
635
  if (e.length === 0) return;
608
- let n = this.sql, r = (e) => this.nsT(e), a = (e, t) => n.unsafe(`ALTER TABLE ${oe(r(e), "mssql")} ${t ? "WITH CHECK CHECK" : "NOCHECK"} CONSTRAINT ALL`), o = i.acquireUseRelease(i.forEach(e, (e) => a(e, !1), { discard: !0 }), () => i.forEach(e, (e) => n`DELETE FROM ${n(r(e))}`, { discard: !0 }), () => i.orDie(i.ignore(i.forEach(e, (e) => a(e, !0), { discard: !0 })))), s = t === null ? n.withTransaction(o) : i.provideService(o, I, t);
636
+ let n = this.sql, r = (e) => this.nsT(e), a = (e, t) => n.unsafe(`ALTER TABLE ${oe(r(e), "mssql")} ${t ? "WITH CHECK CHECK" : "NOCHECK"} CONSTRAINT ALL`), o = i.acquireUseRelease(i.forEach(e, (e) => a(e, !1), { discard: !0 }), () => i.forEach(e, (e) => n`DELETE FROM ${n(r(e))}`, { discard: !0 }), () => i.orDie(i.ignore(i.forEach(e, (e) => a(e, !0), { discard: !0 })))), s = t === null ? n.withTransaction(o) : i.provideService(o, F, t);
609
637
  await this.runtime.runPromise(s);
610
638
  }
611
639
  async transactional(e) {
612
640
  this.inflightTxns++;
613
641
  try {
614
- return await le({
642
+ return await ue({
615
643
  ...this.txnSpec("MssqlStore.transactional"),
616
644
  work: e,
617
- makeView: (e, t) => new be(this, e, t)
645
+ makeView: (e, t) => new Te(this, e, t)
618
646
  });
619
647
  } finally {
620
648
  this.inflightTxns--;
@@ -668,7 +696,7 @@ var L = (e) => typeof e == "bigint" ? t.BigInt : typeof e == "number" && Number.
668
696
  async ping() {
669
697
  await this.runtime.runPromise(this.sql`SELECT 1`);
670
698
  }
671
- }, be = class {
699
+ }, Te = class {
672
700
  parent;
673
701
  txn;
674
702
  attr;
@@ -679,16 +707,16 @@ var L = (e) => typeof e == "bigint" ? t.BigInt : typeof e == "number" && Number.
679
707
  this.parent = e, this.txn = t, this.attr = n;
680
708
  }
681
709
  savepoint(e) {
682
- return ce({
710
+ return le({
683
711
  tracker: this.aborts,
684
712
  name: `voltro_sp_${++this.savepointCounter}`,
685
713
  spelling: "mssql",
686
- exec: (e) => this.parent.run(i.provideService(F.pipe(i.flatMap((t) => t.unsafe(e))), I, this.txn))
714
+ exec: (e) => this.parent.run(i.provideService(P.pipe(i.flatMap((t) => t.unsafe(e))), F, this.txn))
687
715
  }, e);
688
716
  }
689
717
  savepointCounter = 0;
690
718
  run(e) {
691
- return this.aborts.track(() => this.parent.run(i.provideService(e, I, this.txn)));
719
+ return this.aborts.track(() => this.parent.run(i.provideService(e, F, this.txn)));
692
720
  }
693
721
  abortedBy() {
694
722
  return this.aborts.abortedBy();
@@ -748,12 +776,12 @@ var L = (e) => typeof e == "bigint" ? t.BigInt : typeof e == "number" && Number.
748
776
  this.events.length = 0;
749
777
  }
750
778
  }
751
- }, $ = (e) => e.__mssqlReplicationFriend ?? null, xe = (e, t) => e === t ? 0 : e < t ? -1 : 1, Se = () => ({
779
+ }, $ = (e) => e.__mssqlReplicationFriend ?? null, Ee = (e, t) => e === t ? 0 : e < t ? -1 : 1, De = () => ({
752
780
  async capturePrimaryPosition(e) {
753
781
  let t = $(e);
754
782
  if (t === null) throw Error("mssqlReplicationAdapter: primary is not an MssqlStore (missing __mssqlReplicationFriend).");
755
783
  return t.runEffect(i.gen(function* () {
756
- return (yield* (yield* F)`
784
+ return (yield* (yield* P)`
757
785
  SELECT CONVERT(VARCHAR(40), end_of_log_lsn) AS lsn
758
786
  FROM sys.dm_hadr_database_replica_states
759
787
  WHERE database_id = DB_ID()
@@ -766,7 +794,7 @@ var L = (e) => typeof e == "bigint" ? t.BigInt : typeof e == "number" && Number.
766
794
  let t = $(e);
767
795
  if (t === null) throw Error("mssqlReplicationAdapter: replica is not an MssqlStore.");
768
796
  return t.runEffect(i.gen(function* () {
769
- return (yield* (yield* F)`
797
+ return (yield* (yield* P)`
770
798
  SELECT CONVERT(VARCHAR(40), last_hardened_lsn) AS lsn
771
799
  FROM sys.dm_hadr_database_replica_states
772
800
  WHERE database_id = DB_ID()
@@ -775,14 +803,14 @@ var L = (e) => typeof e == "bigint" ? t.BigInt : typeof e == "number" && Number.
775
803
  }));
776
804
  },
777
805
  compare(e, t) {
778
- return xe(t, e) >= 0 ? "caught-up" : "behind";
806
+ return Ee(t, e) >= 0 ? "caught-up" : "behind";
779
807
  }
780
- }), Ce = {
808
+ }), Oe = {
781
809
  id: "mssql",
782
- makeSqlLayer: (e) => H(e),
810
+ makeSqlLayer: (e) => z(e),
783
811
  makeStore: (e) => Q(e),
784
812
  compileContains: (e, t, n) => n`${e} LIKE ${`%${t.replace(/[\\%_[\]]/g, (e) => `\\${e}`)}%`} ESCAPE '\\'`,
785
813
  retryFilter: K
786
814
  };
787
815
  //#endregion
788
- export { l as CDC_OFFSETS_TABLE, e as MssqlClient, p as _voltroMssqlCdcOffsetsTable, V as connectionFromConfig, q as ensureChangeTracking, B as makeMssqlSqlLayer, H as makeMssqlSqlLayerFromConfig, Q as makeMssqlStore, Ce as mssqlDialect, Se as mssqlReplicationAdapter, K as mssqlRetryFilter, X as startChangeTrackingCdc };
816
+ export { l as CDC_OFFSETS_TABLE, e as MssqlClient, p as _voltroMssqlCdcOffsetsTable, R as connectionFromConfig, q as ensureChangeTracking, L as makeMssqlSqlLayer, z as makeMssqlSqlLayerFromConfig, Q as makeMssqlStore, Oe as mssqlDialect, De as mssqlReplicationAdapter, K as mssqlRetryFilter, X as startChangeTrackingCdc };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@voltro/sql-mssql",
3
- "version": "0.83.0",
3
+ "version": "0.84.0",
4
4
  "description": "SQL Server (mssql) dialect adapter for Voltro's cross-dialect DataStore (OUTPUT-clause returning, OFFSET/FETCH paging, inline reactivity).",
5
5
  "keywords": [
6
6
  "voltro",
@@ -35,8 +35,8 @@
35
35
  "dependencies": {
36
36
  "@effect/sql": "^0.52.1",
37
37
  "@effect/sql-mssql": "^0.54.0",
38
- "@voltro/database": "0.83.0",
39
- "@voltro/logger": "0.83.0",
38
+ "@voltro/database": "0.84.0",
39
+ "@voltro/logger": "0.84.0",
40
40
  "tedious": "18.6.2"
41
41
  },
42
42
  "peerDependencies": {