@kikko-land/kikko
Advanced tools
Comparing version 0.17.0 to 0.18.0
# @kikko-land/core | ||
## 0.18.0 | ||
### Minor Changes | ||
- eb496a0: Add Kysely support | ||
## 0.17.0 | ||
@@ -4,0 +10,0 @@ |
@@ -1,10 +0,10 @@ | ||
import { deepEqual as Z } from "fast-equals"; | ||
import { deepEqual as j } from "fast-equals"; | ||
import { sql as S } from "@kikko-land/boono-sql"; | ||
export * from "@kikko-land/boono-sql"; | ||
const v = typeof performance < "u" ? () => performance.now() : () => Date.now(); | ||
const v = () => Date.now(); | ||
class E extends Error { | ||
} | ||
class B extends Error { | ||
class L extends Error { | ||
} | ||
const j = (() => { | ||
const O = (() => { | ||
const e = /* @__PURE__ */ new Map(); | ||
@@ -19,3 +19,3 @@ let t = !1, r; | ||
else if (r < Date.now()) { | ||
t = !1, r = void 0, console.log("loop stopped"); | ||
t = !1, r = void 0; | ||
break; | ||
@@ -36,3 +36,3 @@ } | ||
}); | ||
})(), M = (e, t) => { | ||
})(), W = (e, t) => { | ||
const r = t.deduplicate === void 0 ? !0 : t.deduplicate; | ||
@@ -52,3 +52,3 @@ return { | ||
throw new Error(`reactiveVar ${t.label} is stopped!`); | ||
if (!(r && Z(this.__state.value, a))) { | ||
if (!(r && j(this.__state.value, a))) { | ||
this.__state.value = a; | ||
@@ -68,15 +68,15 @@ for (const i of this.__state.subscriptions) | ||
let s; | ||
const f = (h) => { | ||
s && s(), s = a(h); | ||
const f = (p) => { | ||
s && s(), s = a(p); | ||
}; | ||
return this.__state.subscriptions.push(f), i && f(this.__state.value), () => { | ||
this.__state.subscriptions = this.__state.subscriptions.filter((h) => h !== f); | ||
this.__state.subscriptions = this.__state.subscriptions.filter((p) => p !== f); | ||
}; | ||
}, | ||
waitTill(a, i) { | ||
const s = new B( | ||
const s = new L( | ||
`waitUntil for reactiveVar ${t.label} is stopped due to stop signal` | ||
), f = new E( | ||
`waitUntil for reactiveVar ${t.label} is timed out` | ||
), h = new B( | ||
), p = new L( | ||
`waitUntil for reactiveVar ${t.label} is stopped due to reactive var stop` | ||
@@ -87,3 +87,3 @@ ); | ||
return a(this.value) ? Promise.resolve() : new Promise((l, d) => { | ||
var p; | ||
var h; | ||
let n = !1, u = []; | ||
@@ -104,3 +104,3 @@ const m = () => { | ||
), n || o( | ||
((p = i == null ? void 0 : i.stopIf) == null ? void 0 : p.subscribe((T) => { | ||
((h = i == null ? void 0 : i.stopIf) == null ? void 0 : h.subscribe((T) => { | ||
!T || (m(), d(s)); | ||
@@ -110,3 +110,3 @@ }, !0)) || (() => { | ||
), !n && ((i == null ? void 0 : i.timeout) === void 0 || typeof (i == null ? void 0 : i.timeout) == "number")) { | ||
const T = j( | ||
const T = O( | ||
() => { | ||
@@ -123,3 +123,3 @@ m(), d(f); | ||
const T = () => { | ||
m(), d(h); | ||
m(), d(p); | ||
}; | ||
@@ -141,3 +141,3 @@ this.__state.onStop.push(T), o(() => { | ||
}; | ||
}, W = (e, t) => { | ||
}, P = (e, t) => { | ||
const { | ||
@@ -158,3 +158,3 @@ __state: { | ||
} | ||
const P = (e) => { | ||
const z = (e) => { | ||
const { current: t, queue: r } = e; | ||
@@ -166,3 +166,3 @@ return `Current running transaction job: ${JSON.stringify( | ||
)}, queue of transaction jobs: ${JSON.stringify(r, null, 2)}`; | ||
}, ue = () => M( | ||
}, de = () => W( | ||
{ | ||
@@ -173,3 +173,3 @@ queue: [], | ||
{ label: "jobsState", deduplicate: !1 } | ||
), L = (e) => ({ id: e }), J = async (e, t) => { | ||
), J = (e) => ({ id: e }), U = async (e, t) => { | ||
const { current: r, queue: a } = e.value; | ||
@@ -197,3 +197,3 @@ if (r || a.length > 0) { | ||
}, s instanceof E ? new E( | ||
`Timeout error while transaction job acquire: '${s.message}'. Is it a dead lock? ${P( | ||
`Timeout error while transaction job acquire: '${s.message}'. Is it a dead lock? ${z( | ||
e.value | ||
@@ -208,7 +208,7 @@ )}, jobToAcquire: ${JSON.stringify(t, null, 2)}` | ||
}; | ||
}, O = (e, t) => { | ||
}, ee = (e, t) => { | ||
const { current: r, queue: a } = e.value; | ||
if ((r == null ? void 0 : r.id) !== t.id) | ||
throw new Error( | ||
`Can't release job that is not currently running, ${P( | ||
`Can't release job that is not currently running, ${z( | ||
e.value | ||
@@ -218,3 +218,3 @@ )}, toRelease: ${JSON.stringify(t, null, 2)}` | ||
e.value = { queue: a.slice(1), current: a[0] }; | ||
}, de = async (e) => { | ||
}, me = async (e) => { | ||
try { | ||
@@ -230,7 +230,7 @@ return e.waitTill( | ||
} | ||
}, z = async (e, t) => { | ||
}, G = async (e, t) => { | ||
let r; | ||
if (t) { | ||
const a = L(t.transactionId); | ||
t.containsTransactionStart ? await J(e, a) : await e.waitTill((i) => { | ||
const a = J(t.transactionId); | ||
t.containsTransactionStart ? await U(e, a) : await e.waitTill((i) => { | ||
var s; | ||
@@ -240,12 +240,12 @@ return ((s = i.current) == null ? void 0 : s.id) === a.id; | ||
} else { | ||
const a = L(R()); | ||
await J(e, a), r = a; | ||
const a = J(R()); | ||
await U(e, a), r = a; | ||
} | ||
return r; | ||
}, G = (e, t, r) => { | ||
if (t && (!r || (r == null ? void 0 : r.containsTransactionFinish) || (r == null ? void 0 : r.containsTransactionRollback)) && O(e, t), !t && r) | ||
}, Y = (e, t, r) => { | ||
if (t && (!r || (r == null ? void 0 : r.containsTransactionFinish) || (r == null ? void 0 : r.containsTransactionRollback)) && ee(e, t), !t && r) | ||
throw new Error("Transaction job was not started, nothing to release!"); | ||
}, me = (e) => ({ | ||
}, fe = (e) => ({ | ||
async run(t, r, a) { | ||
const i = v(), s = await z(t, a), h = v() - i; | ||
const i = v(), s = await G(t, a), p = v() - i; | ||
try { | ||
@@ -277,3 +277,3 @@ return { | ||
performance: { | ||
blockTime: h | ||
blockTime: p | ||
} | ||
@@ -290,8 +290,8 @@ }; | ||
} finally { | ||
G(t, s, a); | ||
Y(t, s, a); | ||
} | ||
} | ||
}), fe = (e) => ({ | ||
}), pe = (e) => ({ | ||
async run(t, r, a) { | ||
const i = v(), s = await z(t, a), h = v() - i; | ||
const i = v(), s = await G(t, a), p = v() - i; | ||
try { | ||
@@ -315,3 +315,3 @@ return { | ||
performance: { | ||
blockTime: h | ||
blockTime: p | ||
} | ||
@@ -328,7 +328,7 @@ }; | ||
} finally { | ||
G(t, s, a); | ||
Y(t, s, a); | ||
} | ||
} | ||
}); | ||
class ee extends Error { | ||
class te extends Error { | ||
constructor(t, r, a) { | ||
@@ -338,7 +338,7 @@ super(t.message, { cause: t }), this.dbName = r, this.queries = a, this.cause = t, this.stack = t.stack, this.name = "QueryRunError"; | ||
} | ||
const U = (e, t) => { | ||
const D = (e, t) => { | ||
if (!e.__state.localState.transactionState.current) | ||
throw new Error("Not in transaction."); | ||
const r = e.__state.localState.transactionState.current, a = [], i = (s) => (f, h) => { | ||
if (r.id === h.id) { | ||
const r = e.__state.localState.transactionState.current, a = [], i = (s) => (f, p) => { | ||
if (r.id === p.id) { | ||
t(s, f, r); | ||
@@ -361,3 +361,3 @@ for (const c of a) | ||
}; | ||
function te() { | ||
function re() { | ||
const e = {}; | ||
@@ -378,3 +378,23 @@ return { | ||
} | ||
const re = (e) => e.filter((t) => t !== null), ae = (e) => e.reduce((t, r) => t + r, 0), D = (e) => ae(re(e)), ie = async ({ | ||
const ae = (e) => e.filter((t) => t !== null), ie = (e) => e.reduce((t, r) => t + r, 0), V = (e) => ie(ae(e)), F = (e) => { | ||
if ("compile" in e) { | ||
const { sql: t, parameters: r } = e.compile(); | ||
return { | ||
text: t, | ||
values: r | ||
}; | ||
} else { | ||
if ("preparedQuery" in e) | ||
return e.preparedQuery; | ||
if ("toSql" in e) | ||
return F(e.toSql()); | ||
{ | ||
const { sql: t, parameters: r } = e; | ||
return { | ||
text: t, | ||
values: r | ||
}; | ||
} | ||
} | ||
}, ne = async ({ | ||
db: e, | ||
@@ -384,3 +404,3 @@ queries: t, | ||
}) => { | ||
var p, T, $, F, C, I, Q, q, N; | ||
var h, T, $, C, I, Q, N, q, B; | ||
const { | ||
@@ -391,3 +411,3 @@ localState: { transactionState: a }, | ||
} = e.__state; | ||
if (a.current || W(e, () => JSON.stringify(t)), r && ((p = a.current) == null ? void 0 : p.id) !== r.transactionId) | ||
if (a.current || P(e, () => JSON.stringify(t)), r && ((h = a.current) == null ? void 0 : h.id) !== r.transactionId) | ||
throw new Error( | ||
@@ -398,3 +418,3 @@ `Cannot run queries in a transaction that is not the current one. Transaction opts: ${JSON.stringify( | ||
); | ||
const h = v(), c = (() => { | ||
const p = v(), c = (() => { | ||
const w = r || (a.current ? { | ||
@@ -409,19 +429,18 @@ transactionId: a.current.id, | ||
if (t.type === "prepared") { | ||
const _ = t.query.toSql(); | ||
if (_._values.length !== 0) | ||
const _ = F(t.query); | ||
if (_.values.length !== 0) | ||
throw new Error( | ||
"You can't use prepared var through ${} for runPreparedQuery. Please, manually specify variables with '?'." | ||
); | ||
const y = _.preparedQuery.text; | ||
return { | ||
toExecArg: { | ||
type: "prepared", | ||
query: _.preparedQuery, | ||
query: _, | ||
preparedValues: t.preparedValues | ||
}, | ||
toExecArgOpts: w, | ||
textQueries: [y] | ||
textQueries: [_.text] | ||
}; | ||
} else { | ||
const _ = t.values.map((y) => y.preparedQuery); | ||
const _ = t.values.map((g) => F(g)); | ||
return { | ||
@@ -433,3 +452,3 @@ toExecArg: { | ||
toExecArgOpts: w, | ||
textQueries: _.map((y) => y.text) | ||
textQueries: _.map((g) => g.text) | ||
}; | ||
@@ -447,3 +466,3 @@ } | ||
} catch (w) { | ||
throw w instanceof Error ? new ee( | ||
throw w instanceof Error ? new te( | ||
w, | ||
@@ -456,12 +475,12 @@ e.__state.sharedState.dbName, | ||
if (!e.__state.localState.suppressLog) { | ||
const w = (g, x) => `${g}=${(x / 1e3).toFixed(4)}`, _ = (() => { | ||
const w = (y, x) => `${y}=${(x / 1e3).toFixed(4)}`, _ = (() => { | ||
if (t.type === "prepared") { | ||
const g = d[0], x = [ | ||
g.performance.prepareTime !== void 0 ? w( | ||
const y = d[0], x = [ | ||
y.performance.prepareTime !== void 0 ? w( | ||
"prepareTime", | ||
D(d.map((b) => b.performance.prepareTime)) | ||
V(d.map((b) => b.performance.prepareTime)) | ||
) : "", | ||
g.performance.execTime !== void 0 ? w( | ||
y.performance.execTime !== void 0 ? w( | ||
"execTime", | ||
D(d.map((b) => b.performance.execTime)) | ||
V(d.map((b) => b.performance.execTime)) | ||
) : "" | ||
@@ -477,26 +496,26 @@ ].filter((b) => b.length !== 0).join(" "); | ||
} else | ||
return d.map(({ performance: g }, x) => { | ||
return d.map(({ performance: y }, x) => { | ||
const b = [ | ||
g.prepareTime !== void 0 ? w("prepareTime", g.prepareTime) : "", | ||
g.execTime !== void 0 ? w("execTime", g.execTime) : "" | ||
y.prepareTime !== void 0 ? w("prepareTime", y.prepareTime) : "", | ||
y.execTime !== void 0 ? w("execTime", y.execTime) : "" | ||
].filter((A) => A.length !== 0).join(" "); | ||
return [u[x].slice(0, 1e3), b].filter((A) => A.length !== 0).join(" "); | ||
}); | ||
})(), y = (() => _.length === 1 ? _[0] : ` | ||
` + _.map((g) => `{${g}}`).join(` | ||
`))(), K = `%c[${e.__state.sharedState.dbName}] ` + [ | ||
})(), g = (() => _.length === 1 ? _[0] : ` | ||
` + _.map((y) => `{${y}}`).join(` | ||
`))(), X = `%c[${e.__state.sharedState.dbName}] ` + [ | ||
(T = a.current) != null && T.id ? `[tr_id=${($ = a.current) == null ? void 0 : $.id.substring(0, 6)}]` : "", | ||
y, | ||
g, | ||
(n == null ? void 0 : n.sendTime) !== void 0 ? `sendTime=${(n.sendTime / 1e3).toFixed(4)}` : "", | ||
(n == null ? void 0 : n.receiveTime) !== void 0 ? `receiveTime=${(n.receiveTime / 1e3).toFixed(4)}` : "", | ||
(n == null ? void 0 : n.blockTime) !== void 0 ? `blockTime=${(n.blockTime / 1e3).toFixed(4)}` : "", | ||
`totalTime=${((m - h) / 1e3).toFixed(4)}` | ||
].filter((g) => g.length !== 0).join(" "), X = (I = f.transactionsStates.byId[(C = (F = a.current) == null ? void 0 : F.id) != null ? C : ""]) == null ? void 0 : I.i; | ||
s.logQuery(K, X); | ||
`totalTime=${((m - p) / 1e3).toFixed(4)}` | ||
].filter((y) => y.length !== 0).join(" "), Z = (Q = f.transactionsStates.byId[(I = (C = a.current) == null ? void 0 : C.id) != null ? I : ""]) == null ? void 0 : Q.i; | ||
s.logQuery(X, Z); | ||
} | ||
const o = (N = f.transactionsStates.byId[(q = (Q = a.current) == null ? void 0 : Q.id) != null ? q : ""]) == null ? void 0 : N.performance; | ||
const o = (B = f.transactionsStates.byId[(q = (N = a.current) == null ? void 0 : N.id) != null ? q : ""]) == null ? void 0 : B.performance; | ||
return o && (d.some((w) => w.performance.execTime !== void 0) && (o.execTime === void 0 && (o.execTime = 0), o.execTime += d.reduce( | ||
(w, _) => { | ||
var y; | ||
return w + ((y = _.performance.execTime) != null ? y : 0); | ||
var g; | ||
return w + ((g = _.performance.execTime) != null ? g : 0); | ||
}, | ||
@@ -506,4 +525,4 @@ 0 | ||
(w, _) => { | ||
var y; | ||
return w + ((y = _.performance.prepareTime) != null ? y : 0); | ||
var g; | ||
return w + ((g = _.performance.prepareTime) != null ? g : 0); | ||
}, | ||
@@ -515,3 +534,3 @@ 0 | ||
...e.__state.localState.queriesMiddlewares, | ||
ie | ||
ne | ||
].reverse(); | ||
@@ -521,3 +540,3 @@ let i = (s) => Promise.resolve(s); | ||
const f = i; | ||
i = (h) => s({ ...h, next: f }); | ||
i = (p) => s({ ...p, next: f }); | ||
} | ||
@@ -536,4 +555,4 @@ return await i({ | ||
}; | ||
let Y = 0; | ||
const H = (e, t, r) => { | ||
let H = 0; | ||
const K = (e, t, r) => { | ||
const a = e.__state.sharedState.logFns; | ||
@@ -556,6 +575,6 @@ if (e.__state.localState.suppressLog) | ||
); | ||
}, ne = async (e, t, r) => { | ||
}, se = async (e, t, r) => { | ||
const { | ||
localState: { transactionState: a }, | ||
sharedState: { eventsEmitter: i, transactionsStates: s, dbBackend: f, logFns: h } | ||
sharedState: { eventsEmitter: i, transactionsStates: s, dbBackend: f, logFns: p } | ||
} = e.__state; | ||
@@ -568,3 +587,3 @@ if (f.isUsualTransactionDisabled) | ||
return await r(e); | ||
W(e, () => "transaction"); | ||
P(e, () => "transaction"); | ||
const c = { | ||
@@ -585,3 +604,3 @@ id: R(), | ||
const l = v(), d = { | ||
i: Y++, | ||
i: H++, | ||
current: c, | ||
@@ -634,3 +653,3 @@ performance: { | ||
} catch (n) { | ||
h.logError("Rollback transaction", n), await i.emit("transactionWillRollback", e, c); | ||
p.logError("Rollback transaction", n), await i.emit("transactionWillRollback", e, c); | ||
try { | ||
@@ -650,3 +669,3 @@ await k( | ||
} catch (u) { | ||
h.logError("Rollback transaction failed", u); | ||
p.logError("Rollback transaction failed", u); | ||
} | ||
@@ -656,5 +675,5 @@ throw await i.emit("transactionRollbacked", e, c), n; | ||
} finally { | ||
d.performance.totalTime = v() - l, H(e, c.id, d.performance), delete s.byId[c.id]; | ||
d.performance.totalTime = v() - l, K(e, c.id, d.performance), delete s.byId[c.id]; | ||
} | ||
}, se = () => ({ | ||
}, oe = () => ({ | ||
__state: { | ||
@@ -674,6 +693,6 @@ queries: [], | ||
} | ||
}), oe = async (e, t, r) => { | ||
}), ce = async (e, t, r) => { | ||
const { | ||
localState: { transactionState: a }, | ||
sharedState: { eventsEmitter: i, transactionsStates: s, dbBackend: f, logFns: h } | ||
sharedState: { eventsEmitter: i, transactionsStates: s, dbBackend: f, logFns: p } | ||
} = e.__state; | ||
@@ -692,7 +711,7 @@ if (a.current) | ||
{ | ||
const p = se(); | ||
return await r(p), { | ||
inputQueries: p.__state.queries, | ||
afterCommits: p.__state.afterCommits, | ||
afterRollbacks: p.__state.afterRollbacks | ||
const h = oe(); | ||
return await r(h), { | ||
inputQueries: h.__state.queries, | ||
afterCommits: h.__state.afterCommits, | ||
afterRollbacks: h.__state.afterRollbacks | ||
}; | ||
@@ -704,3 +723,3 @@ } | ||
}, u = { | ||
i: Y++, | ||
i: H++, | ||
current: n, | ||
@@ -728,3 +747,3 @@ performance: { | ||
const m = v(), o = []; | ||
f.isAtomicRollbackCommitDisabled || o.push(S`BEGIN ${S.raw(t.toUpperCase())} TRANSACTION`), o.push(...c.map((p) => p.toSql())), f.isAtomicRollbackCommitDisabled || o.push(S`COMMIT`); | ||
f.isAtomicRollbackCommitDisabled || o.push(S`BEGIN ${S.raw(t.toUpperCase())} TRANSACTION`), o.push(...c), f.isAtomicRollbackCommitDisabled || o.push(S`COMMIT`); | ||
try { | ||
@@ -744,9 +763,9 @@ await i.emit("transactionWillStart", e, n), await i.emit("transactionStarted", e, n), await k( | ||
try { | ||
for (const p of l) | ||
p(); | ||
} catch (p) { | ||
h.logError("Error in afterCommit callback", p); | ||
for (const h of l) | ||
h(); | ||
} catch (h) { | ||
p.logError("Error in afterCommit callback", h); | ||
} | ||
} catch (p) { | ||
h.logError("Rollback transaction", p), await i.emit("transactionWillRollback", e, n), await i.emit("transactionRollbacked", e, n); | ||
} catch (h) { | ||
p.logError("Rollback transaction", h), await i.emit("transactionWillRollback", e, n), await i.emit("transactionRollbacked", e, n); | ||
try { | ||
@@ -756,9 +775,9 @@ for (const T of d) | ||
} catch (T) { | ||
h.logError("Error in afterRollback callback", T); | ||
p.logError("Error in afterRollback callback", T); | ||
} | ||
throw p; | ||
throw h; | ||
} finally { | ||
u.performance.totalTime = v() - m, H(e, n.id, u.performance), delete s.byId[n.id]; | ||
u.performance.totalTime = v() - m, K(e, n.id, u.performance), delete s.byId[n.id]; | ||
} | ||
}, V = ["yellow", "cyan", "magenta"], pe = async ({ | ||
}, M = ["yellow", "cyan", "magenta"], he = async ({ | ||
dbName: e, | ||
@@ -773,3 +792,3 @@ plugins: t, | ||
logQuery: (u, m) => { | ||
const o = typeof m == "number" ? V[m % V.length] : void 0; | ||
const o = typeof m == "number" ? M[m % M.length] : void 0; | ||
console.debug( | ||
@@ -791,3 +810,3 @@ ...o ? [ | ||
} | ||
}, h = M( | ||
}, p = W( | ||
"running", | ||
@@ -803,4 +822,4 @@ { label: "runningState" } | ||
dbName: e, | ||
runningState: h, | ||
eventsEmitter: te(), | ||
runningState: p, | ||
eventsEmitter: re(), | ||
transactionsStates: { byId: {} }, | ||
@@ -815,7 +834,10 @@ logFns: f | ||
}, | ||
get isInTransaction() { | ||
return this.__state.localState.transactionState.current !== void 0; | ||
}, | ||
runInTransaction(u, m) { | ||
return ne(this, (m == null ? void 0 : m.type) || "deferred", u); | ||
return se(this, (m == null ? void 0 : m.type) || "deferred", u); | ||
}, | ||
async runInAtomicTransaction(u, m) { | ||
return await oe(this, (m == null ? void 0 : m.type) || "deferred", u); | ||
return await ce(this, (m == null ? void 0 : m.type) || "deferred", u); | ||
}, | ||
@@ -825,3 +847,3 @@ async runQueries(u) { | ||
type: "usual", | ||
values: u.map((o) => o.toSql()) | ||
values: u | ||
})).result.map(({ rows: o }) => o); | ||
@@ -837,12 +859,12 @@ }, | ||
preparedValues: m | ||
})).result.map(({ rows: p }) => p); | ||
})).result.map(({ rows: h }) => h); | ||
}, | ||
runAfterTransactionCommitted(u) { | ||
return U(this, (m, o, p) => { | ||
m === "committed" && u(o, p); | ||
return D(this, (m, o, h) => { | ||
m === "committed" && u(o, h); | ||
}); | ||
}, | ||
runAfterTransactionRollbacked(u) { | ||
U(l, (m, o, p) => { | ||
m === "rollbacked" && u(o, p); | ||
D(l, (m, o, h) => { | ||
m === "rollbacked" && u(o, h); | ||
}); | ||
@@ -858,7 +880,7 @@ } | ||
return await l.__state.sharedState.eventsEmitter.emit("initialized", l), d; | ||
}, he = async (e) => { | ||
}, Te = async (e) => { | ||
e.__state.sharedState.runningState.value = "stopping", await e.__state.sharedState.dbBackend.stop(), e.__state.sharedState.runningState.value = "stopped", queueMicrotask(() => { | ||
e.__state.sharedState.runningState.stop(); | ||
}); | ||
}, Te = (e, t) => t({ | ||
}, we = (e, t) => t({ | ||
...e, | ||
@@ -872,3 +894,3 @@ __state: { | ||
} | ||
}), we = (e) => ({ | ||
}), _e = (e) => ({ | ||
...e, | ||
@@ -881,21 +903,21 @@ __state: { | ||
export { | ||
ee as QueryRunError, | ||
B as StoppedError, | ||
te as QueryRunError, | ||
L as StoppedError, | ||
E as TimeoutError, | ||
J as acquireJob, | ||
z as acquireWithTrJobOrWait, | ||
me as buildAsyncQueryRunner, | ||
fe as buildSyncQueryRunner, | ||
U as acquireJob, | ||
G as acquireWithTrJobOrWait, | ||
fe as buildAsyncQueryRunner, | ||
pe as buildSyncQueryRunner, | ||
v as getTime, | ||
pe as initDbClient, | ||
ue as initJobsState, | ||
he as initDbClient, | ||
de as initJobsState, | ||
R as makeId, | ||
M as reactiveVar, | ||
O as releaseJob, | ||
G as releaseTrJobIfPossible, | ||
he as stopDb, | ||
Te as suppressLog, | ||
de as whenAllJobsDone, | ||
we as withSuppressedLog | ||
W as reactiveVar, | ||
ee as releaseJob, | ||
Y as releaseTrJobIfPossible, | ||
Te as stopDb, | ||
we as suppressLog, | ||
me as whenAllJobsDone, | ||
_e as withSuppressedLog | ||
}; | ||
//# sourceMappingURL=index.es.js.map |
@@ -1,4 +0,4 @@ | ||
(function(f,$){typeof exports=="object"&&typeof module<"u"?$(exports,require("fast-equals"),require("@kikko-land/boono-sql")):typeof define=="function"&&define.amd?define(["exports","fast-equals","@kikko-land/boono-sql"],$):(f=typeof globalThis<"u"?globalThis:f||self,$(f.core={},f.fastEquals,f.boonoSql))})(this,function(f,$,S){"use strict";const v=typeof performance<"u"?()=>performance.now():()=>Date.now();class E extends Error{}class C extends Error{}const O=(()=>{const e=new Map;let t=!1,r;const a=async()=>{if(!t)for(t=!0;t;){if(e.size===0){if(!r)r=Date.now()+1e4;else if(r<Date.now()){t=!1,r=void 0,console.log("loop stopped");break}}else{r=void 0;for(const[i,s]of e.entries())s<Date.now()&&(i(),e.delete(i))}await new Promise(i=>{setTimeout(()=>i(),1e3)})}};return(i,s)=>(e.set(i,Date.now()+s),a(),()=>{e.delete(i)})})(),I=(e,t)=>{const r=t.deduplicate===void 0?!0:t.deduplicate;return{__state:{subscriptions:[],value:e,isStopped:!1,onStop:[]},get isStopped(){return this.__state.isStopped},set value(a){if(this.isStopped)throw new Error(`reactiveVar ${t.label} is stopped!`);if(!(r&&$.deepEqual(this.__state.value,a))){this.__state.value=a;for(const i of this.__state.subscriptions)i(a)}},get value(){if(this.isStopped)throw new Error(`reactiveVar ${t.label} is stopped!`);return this.__state.value},subscribe(a,i=!0){if(this.isStopped)throw new Error(`reactiveVar ${t.label} is stopped!`);let s;const h=T=>{s&&s(),s=a(T)};return this.__state.subscriptions.push(h),i&&h(this.__state.value),()=>{this.__state.subscriptions=this.__state.subscriptions.filter(T=>T!==h)}},waitTill(a,i){const s=new C(`waitUntil for reactiveVar ${t.label} is stopped due to stop signal`),h=new E(`waitUntil for reactiveVar ${t.label} is timed out`),T=new C(`waitUntil for reactiveVar ${t.label} is stopped due to reactive var stop`);if(this.isStopped)throw new Error(`reactiveVar ${t.label} is stopped!`);return a(this.value)?Promise.resolve():new Promise((l,d)=>{var p;let n=!1,u=[];const m=()=>{if(!n){for(const w of u)w();n=!0,u=[]}},o=w=>{n?w():u.push(w)};if(n||o(this.subscribe(w=>{!a(w)||(m(),l())},!0)),n||o(((p=i==null?void 0:i.stopIf)==null?void 0:p.subscribe(w=>{!w||(m(),d(s))},!0))||(()=>{})),!n&&((i==null?void 0:i.timeout)===void 0||typeof(i==null?void 0:i.timeout)=="number")){const w=O(()=>{m(),d(h)},(i==null?void 0:i.timeout)===void 0?12e4:i.timeout);o(()=>{w()})}if(!n){const w=()=>{m(),d(T)};this.__state.onStop.push(w),o(()=>{this.__state.onStop=this.__state.onStop.filter(F=>F!==w)})}})},stop(){if(this.isStopped)throw new Error(`reactiveVar ${t.label} is already stopped!`);this.__state.subscriptions=[];for(const a of this.__state.onStop)a();this.__state.onStop=[],this.__state.isStopped=!0}}},L=(e,t)=>{const{__state:{sharedState:{runningState:r,dbName:a}}}=e;if(r.value!=="running")throw new Error(`Failed to start ${t()}, db ${a} is stopping`)};function R(){let e="";const t="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",r=t.length;for(let a=0;a<32;a++)e+=t.charAt(Math.floor(Math.random()*r));return e}const B=e=>{const{current:t,queue:r}=e;return`Current running transaction job: ${JSON.stringify(t,null,2)}, queue of transaction jobs: ${JSON.stringify(r,null,2)}`},ee=()=>I({queue:[],current:void 0},{label:"jobsState",deduplicate:!1}),D=e=>({id:e}),q=async(e,t)=>{const{current:r,queue:a}=e.value;if(r||a.length>0){const i=e.waitTill(s=>{var h;return((h=s.current)==null?void 0:h.id)===t.id},{timeout:12e4});e.value={queue:[...a,t],current:r};try{await i}catch(s){throw e.value={...e.value,queue:e.value.queue.filter(h=>h.id!==t.id)},s instanceof E?new E(`Timeout error while transaction job acquire: '${s.message}'. Is it a dead lock? ${B(e.value)}, jobToAcquire: ${JSON.stringify(t,null,2)}`):s}}else e.value={queue:[],current:t}},U=(e,t)=>{const{current:r,queue:a}=e.value;if((r==null?void 0:r.id)!==t.id)throw new Error(`Can't release job that is not currently running, ${B(e.value)}, toRelease: ${JSON.stringify(t,null,2)}`);e.value={queue:a.slice(1),current:a[0]}},te=async e=>{try{return e.waitTill(({queue:t,current:r})=>t.length===0&&r===void 0,{timeout:12e4})}catch(t){throw t instanceof E?new E(`Timeout error while awaiting all jobs done: '${t.message}'. Is it a dead lock?`):t}},Q=async(e,t)=>{let r;if(t){const a=D(t.transactionId);t.containsTransactionStart?await q(e,a):await e.waitTill(i=>{var s;return((s=i.current)==null?void 0:s.id)===a.id}),r=a}else{const a=D(R());await q(e,a),r=a}return r},J=(e,t,r)=>{if(t&&(!r||(r==null?void 0:r.containsTransactionFinish)||(r==null?void 0:r.containsTransactionRollback))&&U(e,t),!t&&r)throw new Error("Transaction job was not started, nothing to release!")},re=e=>({async run(t,r,a){const i=v(),s=await Q(t,a),T=v()-i;try{return{result:await(async()=>{if(r.type==="usual")if("execUsual"in e){const l=[];for(const d of r.values)try{l.push(await e.execUsual(d))}catch(n){throw n instanceof Error&&(n.message=`Error(${n.message}) while executing query: ${d.text.slice(0,500)}`),n}return l}else return e.execUsualBatch(r.values);else try{return await e.execPrepared(r.query,r.preparedValues)}catch(l){throw l instanceof Error&&(l.message=`Error(${l.message}) while executing query: ${r.query.text.slice(0,500)}`),l}})(),performance:{blockTime:T}}}catch(c){if(a!=null&&a.rollbackOnFail)try{await e.rollback()}catch(l){console.error("Failed to rollback",c,l)}throw c}finally{J(t,s,a)}}}),ae=e=>({async run(t,r,a){const i=v(),s=await Q(t,a),T=v()-i;try{return{result:(()=>{if(r.type==="usual")return"execUsual"in e?r.values.map(l=>{try{return e.execUsual(l)}catch(d){throw d instanceof Error&&(d.message=`Error(${d.message}) while executing query: ${l.text.slice(0,500)}`),d}}):e.execUsualBatch(r.values);try{return e.execPrepared(r.query,r.preparedValues)}catch(l){throw l instanceof Error&&(l.message=`Error(${l.message}) while executing query: ${r.query.text.slice(0,500)}`),l}})(),performance:{blockTime:T}}}catch(c){if(a!=null&&a.rollbackOnFail)try{e.rollback()}catch(l){console.error("Failed to rollback",c,l)}throw c}finally{J(t,s,a)}}});class V extends Error{constructor(t,r,a){super(t.message,{cause:t}),this.dbName=r,this.queries=a,this.cause=t,this.stack=t.stack,this.name="QueryRunError"}}const M=(e,t)=>{if(!e.__state.localState.transactionState.current)throw new Error("Not in transaction.");const r=e.__state.localState.transactionState.current,a=[],i=s=>(h,T)=>{if(r.id===T.id){t(s,h,r);for(const c of a)c()}};a.push(e.__state.sharedState.eventsEmitter.on("transactionCommitted",i("committed"))),a.push(e.__state.sharedState.eventsEmitter.on("transactionRollbacked",i("rollbacked")))};function ie(){const e={};return{async emit(t,...r){const a=e[t]||[];for(const i of a)await i(...r)},on(t,r){return(e[t]=e[t]||[]).push(r),()=>{const a=e[t]||[];e[t]=a.filter(i=>i!==r)}}}}const ne=e=>e.filter(t=>t!==null),se=e=>e.reduce((t,r)=>t+r,0),W=e=>se(ne(e)),oe=async({db:e,queries:t,transactionOpts:r})=>{var p,w,F,Y,H,K,X,Z,j;const{localState:{transactionState:a},sharedState:{dbBackend:i,logFns:s},sharedState:h}=e.__state;if(a.current||L(e,()=>JSON.stringify(t)),r&&((p=a.current)==null?void 0:p.id)!==r.transactionId)throw new Error(`Cannot run queries in a transaction that is not the current one. Transaction opts: ${JSON.stringify(r)}, local transaction: ${JSON.stringify(a)}`);const T=v(),c=(()=>{const y=r||(a.current?{transactionId:a.current.id,containsTransactionStart:!1,containsTransactionFinish:!1,containsTransactionRollback:!1,rollbackOnFail:!1,isAtomic:!1}:void 0);if(t.type==="prepared"){const _=t.query.toSql();if(_._values.length!==0)throw new Error("You can't use prepared var through ${} for runPreparedQuery. Please, manually specify variables with '?'.");const g=_.preparedQuery.text;return{toExecArg:{type:"prepared",query:_.preparedQuery,preparedValues:t.preparedValues},toExecArgOpts:y,textQueries:[g]}}else{const _=t.values.map(g=>g.preparedQuery);return{toExecArg:{type:"usual",values:_},toExecArgOpts:y,textQueries:_.map(g=>g.text)}}})(),l=async()=>{try{return{...await i.execQueries(c.toExecArg,c.toExecArgOpts),textQueries:c.textQueries}}catch(y){throw y instanceof Error?new V(y,e.__state.sharedState.dbName,c.textQueries):y}},{result:d,performance:n,textQueries:u}=await l(),m=v();if(!e.__state.localState.suppressLog){const y=(b,A)=>`${b}=${(A/1e3).toFixed(4)}`,_=(()=>{if(t.type==="prepared"){const b=d[0],A=[b.performance.prepareTime!==void 0?y("prepareTime",W(d.map(k=>k.performance.prepareTime))):"",b.performance.execTime!==void 0?y("execTime",W(d.map(k=>k.performance.execTime))):""].filter(k=>k.length!==0).join(" ");return[[u[0].slice(0,1e3),`for ${t.preparedValues.length} values`,A].filter(k=>k.length!==0).join(" ")]}else return d.map(({performance:b},A)=>{const k=[b.prepareTime!==void 0?y("prepareTime",b.prepareTime):"",b.execTime!==void 0?y("execTime",b.execTime):""].filter(N=>N.length!==0).join(" ");return[u[A].slice(0,1e3),k].filter(N=>N.length!==0).join(" ")})})(),g=(()=>_.length===1?_[0]:` | ||
`+_.map(b=>`{${b}}`).join(` | ||
`))(),pe=`%c[${e.__state.sharedState.dbName}] `+[(w=a.current)!=null&&w.id?`[tr_id=${(F=a.current)==null?void 0:F.id.substring(0,6)}]`:"",g,(n==null?void 0:n.sendTime)!==void 0?`sendTime=${(n.sendTime/1e3).toFixed(4)}`:"",(n==null?void 0:n.receiveTime)!==void 0?`receiveTime=${(n.receiveTime/1e3).toFixed(4)}`:"",(n==null?void 0:n.blockTime)!==void 0?`blockTime=${(n.blockTime/1e3).toFixed(4)}`:"",`totalTime=${((m-T)/1e3).toFixed(4)}`].filter(b=>b.length!==0).join(" "),Te=(K=h.transactionsStates.byId[(H=(Y=a.current)==null?void 0:Y.id)!=null?H:""])==null?void 0:K.i;s.logQuery(pe,Te)}const o=(j=h.transactionsStates.byId[(Z=(X=a.current)==null?void 0:X.id)!=null?Z:""])==null?void 0:j.performance;return o&&(d.some(y=>y.performance.execTime!==void 0)&&(o.execTime===void 0&&(o.execTime=0),o.execTime+=d.reduce((y,_)=>{var g;return y+((g=_.performance.execTime)!=null?g:0)},0)),d.some(y=>y.performance.prepareTime!==void 0)&&(o.prepareTime===void 0&&(o.prepareTime=0),o.prepareTime+=d.reduce((y,_)=>{var g;return y+((g=_.performance.prepareTime)!=null?g:0)},0)),n.sendTime&&(o.sendTime||(o.sendTime=0),o.sendTime+=n.sendTime),n.receiveTime&&(o.receiveTime||(o.receiveTime=0),o.receiveTime+=n.receiveTime),n.blockTime&&(o.blockTime||(o.blockTime=0),o.blockTime+=n.blockTime)),{db:e,result:d,performance:n,queries:t}},x=async(e,t,r)=>{const a=[...e.__state.localState.queriesMiddlewares,oe].reverse();let i=s=>Promise.resolve(s);for(const s of a){const h=i;i=T=>s({...T,next:h})}return await i({db:e,result:[],performance:{sendTime:void 0,receiveTime:void 0,totalTime:0},queries:t,transactionOpts:r})};let P=0;const z=(e,t,r)=>{const a=e.__state.sharedState.logFns;if(e.__state.localState.suppressLog)return;const i=[r.prepareTime===void 0?"":`prepareTime=${(r.prepareTime/1e3).toFixed(4)}`,r.execTime===void 0?"":`execTime=${(r.execTime/1e3).toFixed(4)}`,r.sendTime===void 0?"":`sendTime=${(r.sendTime/1e3).toFixed(4)}`,r.receiveTime===void 0?"":`receiveTime=${(r.receiveTime/1e3).toFixed(4)}`,r.blockTime===void 0?"":`blockTime=${(r.blockTime/1e3).toFixed(4)}`,`totalTime=${(r.totalTime/1e3).toFixed(4)}`].filter(s=>s.length!==0).join(" ");a.logTrFinish(`%c[${e.__state.sharedState.dbName}][tr_id=${t.slice(0,6)}] Transaction finished with ${i}`)},ce=async(e,t,r)=>{const{localState:{transactionState:a},sharedState:{eventsEmitter:i,transactionsStates:s,dbBackend:h,logFns:T}}=e.__state;if(h.isUsualTransactionDisabled)throw new Error("Usual transactions are disabled for this type of backend. Please, use atomic transactions instead.");if(a.current)return await r(e);L(e,()=>"transaction");const c={id:R(),type:"async"};e={...e,__state:{...e.__state,localState:{...e.__state.localState,transactionState:{current:c}}}};const l=v(),d={i:P++,current:c,performance:{prepareTime:0,execTime:0,freeTime:0,sendTime:0,receiveTime:0,totalTime:0,blockTime:0}};s.byId[c.id]=d;try{await i.emit("transactionWillStart",e,c),await x(e,{type:"usual",values:[S.sql`BEGIN ${S.sql.raw(t.toLocaleUpperCase())} TRANSACTION`]},{transactionId:c.id,containsTransactionStart:!0,containsTransactionFinish:!1,containsTransactionRollback:!1,rollbackOnFail:!1,isAtomic:!1}),await i.emit("transactionStarted",e,c);try{const n=await r(e);return await i.emit("transactionWillCommit",e,c),await x(e,{type:"usual",values:[S.sql`COMMIT`]},{transactionId:c.id,containsTransactionStart:!1,containsTransactionFinish:!0,containsTransactionRollback:!1,rollbackOnFail:!1,isAtomic:!1}),await i.emit("transactionCommitted",e,c),n}catch(n){T.logError("Rollback transaction",n),await i.emit("transactionWillRollback",e,c);try{await x(e,{type:"usual",values:[S.sql`ROLLBACK`]},{transactionId:c.id,containsTransactionStart:!1,containsTransactionFinish:!1,containsTransactionRollback:!0,rollbackOnFail:!1,isAtomic:!1})}catch(u){T.logError("Rollback transaction failed",u)}throw await i.emit("transactionRollbacked",e,c),n}}finally{d.performance.totalTime=v()-l,z(e,c.id,d.performance),delete s.byId[c.id]}},le=()=>({__state:{queries:[],afterCommits:[],afterRollbacks:[]},addQuery(e){this.__state.queries.push(e)},afterCommit(e){this.__state.afterCommits.push(e)},afterRollback(e){this.__state.afterRollbacks.push(e)}}),ue=async(e,t,r)=>{const{localState:{transactionState:a},sharedState:{eventsEmitter:i,transactionsStates:s,dbBackend:h,logFns:T}}=e.__state;if(a.current)throw new Error("You are running atomic transaction inside of a transaction. Consider moving atomic transaction call to runAfterTransaction callback.");const{inputQueries:c,afterCommits:l,afterRollbacks:d}=await(async()=>{if(Array.isArray(r))return{inputQueries:r,afterCommits:[],afterRollbacks:[]};{const p=le();return await r(p),{inputQueries:p.__state.queries,afterCommits:p.__state.afterCommits,afterRollbacks:p.__state.afterRollbacks}}})(),n={id:R(),type:"atomic"},u={i:P++,current:n,performance:{prepareTime:0,execTime:0,freeTime:0,sendTime:0,receiveTime:0,totalTime:0,blockTime:0}};e={...e,__state:{...e.__state,localState:{...e.__state.localState,transactionState:{current:n}}}},s.byId[n.id]=u;const m=v(),o=[];h.isAtomicRollbackCommitDisabled||o.push(S.sql`BEGIN ${S.sql.raw(t.toUpperCase())} TRANSACTION`),o.push(...c.map(p=>p.toSql())),h.isAtomicRollbackCommitDisabled||o.push(S.sql`COMMIT`);try{await i.emit("transactionWillStart",e,n),await i.emit("transactionStarted",e,n),await x(e,{type:"usual",values:o},{transactionId:n.id,containsTransactionStart:!0,containsTransactionFinish:!0,containsTransactionRollback:!1,rollbackOnFail:!0,isAtomic:!0}),await i.emit("transactionWillCommit",e,n),await i.emit("transactionCommitted",e,n);try{for(const p of l)p()}catch(p){T.logError("Error in afterCommit callback",p)}}catch(p){T.logError("Rollback transaction",p),await i.emit("transactionWillRollback",e,n),await i.emit("transactionRollbacked",e,n);try{for(const w of d)w()}catch(w){T.logError("Error in afterRollback callback",w)}throw p}finally{u.performance.totalTime=v()-m,z(e,n.id,u.performance),delete s.byId[n.id]}},G=["yellow","cyan","magenta"],de=async({dbName:e,plugins:t,queriesMiddlewares:r,dbBackend:a,suppressLog:i,logFns:s})=>{const h=s||{logQuery:(u,m)=>{const o=typeof m=="number"?G[m%G.length]:void 0;console.debug(...o?[u,`color: ${o}; background-color: #202124; padding: 2px 4px; border-radius: 2px`]:[u,"padding: 0"])},logError:(u,m)=>{console.error(u,m)},logTrFinish:u=>{console.debug(u,"color: #fff; background-color: #1da1f2; padding: 2px 4px; border-radius: 2px")}},T=I("running",{label:"runningState"}),c=(await a)({dbName:e}),l={__state:{sharedState:{clientId:R(),dbBackend:c,dbName:e,runningState:T,eventsEmitter:ie(),transactionsStates:{byId:{}},logFns:h},localState:{queriesMiddlewares:r||[],transactionState:{},suppressLog:Boolean(i)}},runInTransaction(u,m){return ce(this,(m==null?void 0:m.type)||"deferred",u)},async runInAtomicTransaction(u,m){return await ue(this,(m==null?void 0:m.type)||"deferred",u)},async runQueries(u){return(await x(this,{type:"usual",values:u.map(o=>o.toSql())})).result.map(({rows:o})=>o)},async runQuery(u){return(await this.runQueries([u]))[0]},async runPreparedQuery(u,m){return(await x(this,{type:"prepared",query:u,preparedValues:m})).result.map(({rows:p})=>p)},runAfterTransactionCommitted(u){return M(this,(m,o,p)=>{m==="committed"&&u(o,p)})},runAfterTransactionRollbacked(u){M(l,(m,o,p)=>{m==="rollbacked"&&u(o,p)})}};let d=l;const n=()=>l.__state.sharedState.runningState.value;if(n()!=="running"||(await c.initialize(),n()!=="running"))return l;for(const u of t||[])d=u(d);return await l.__state.sharedState.eventsEmitter.emit("initialized",l),d},me=async e=>{e.__state.sharedState.runningState.value="stopping",await e.__state.sharedState.dbBackend.stop(),e.__state.sharedState.runningState.value="stopped",queueMicrotask(()=>{e.__state.sharedState.runningState.stop()})},fe=(e,t)=>t({...e,__state:{...e.__state,localState:{...e.__state.localState,suppressLog:!0}}}),he=e=>({...e,__state:{...e.__state,localState:{...e.__state.localState,suppressLog:!0}}});f.QueryRunError=V,f.StoppedError=C,f.TimeoutError=E,f.acquireJob=q,f.acquireWithTrJobOrWait=Q,f.buildAsyncQueryRunner=re,f.buildSyncQueryRunner=ae,f.getTime=v,f.initDbClient=de,f.initJobsState=ee,f.makeId=R,f.reactiveVar=I,f.releaseJob=U,f.releaseTrJobIfPossible=J,f.stopDb=me,f.suppressLog=fe,f.whenAllJobsDone=te,f.withSuppressedLog=he;for(const e in S)e!=="default"&&!f.hasOwnProperty(e)&&Object.defineProperty(f,e,{enumerable:!0,get:()=>S[e]});Object.defineProperties(f,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})}); | ||
(function(f,$){typeof exports=="object"&&typeof module<"u"?$(exports,require("fast-equals"),require("@kikko-land/boono-sql")):typeof define=="function"&&define.amd?define(["exports","fast-equals","@kikko-land/boono-sql"],$):(f=typeof globalThis<"u"?globalThis:f||self,$(f.core={},f.fastEquals,f.boonoSql))})(this,function(f,$,S){"use strict";const b=()=>Date.now();class E extends Error{}class C extends Error{}const ee=(()=>{const e=new Map;let t=!1,r;const a=async()=>{if(!t)for(t=!0;t;){if(e.size===0){if(!r)r=Date.now()+1e4;else if(r<Date.now()){t=!1,r=void 0;break}}else{r=void 0;for(const[i,s]of e.entries())s<Date.now()&&(i(),e.delete(i))}await new Promise(i=>{setTimeout(()=>i(),1e3)})}};return(i,s)=>(e.set(i,Date.now()+s),a(),()=>{e.delete(i)})})(),I=(e,t)=>{const r=t.deduplicate===void 0?!0:t.deduplicate;return{__state:{subscriptions:[],value:e,isStopped:!1,onStop:[]},get isStopped(){return this.__state.isStopped},set value(a){if(this.isStopped)throw new Error(`reactiveVar ${t.label} is stopped!`);if(!(r&&$.deepEqual(this.__state.value,a))){this.__state.value=a;for(const i of this.__state.subscriptions)i(a)}},get value(){if(this.isStopped)throw new Error(`reactiveVar ${t.label} is stopped!`);return this.__state.value},subscribe(a,i=!0){if(this.isStopped)throw new Error(`reactiveVar ${t.label} is stopped!`);let s;const h=p=>{s&&s(),s=a(p)};return this.__state.subscriptions.push(h),i&&h(this.__state.value),()=>{this.__state.subscriptions=this.__state.subscriptions.filter(p=>p!==h)}},waitTill(a,i){const s=new C(`waitUntil for reactiveVar ${t.label} is stopped due to stop signal`),h=new E(`waitUntil for reactiveVar ${t.label} is timed out`),p=new C(`waitUntil for reactiveVar ${t.label} is stopped due to reactive var stop`);if(this.isStopped)throw new Error(`reactiveVar ${t.label} is stopped!`);return a(this.value)?Promise.resolve():new Promise((l,d)=>{var T;let n=!1,u=[];const m=()=>{if(!n){for(const w of u)w();n=!0,u=[]}},o=w=>{n?w():u.push(w)};if(n||o(this.subscribe(w=>{!a(w)||(m(),l())},!0)),n||o(((T=i==null?void 0:i.stopIf)==null?void 0:T.subscribe(w=>{!w||(m(),d(s))},!0))||(()=>{})),!n&&((i==null?void 0:i.timeout)===void 0||typeof(i==null?void 0:i.timeout)=="number")){const w=ee(()=>{m(),d(h)},(i==null?void 0:i.timeout)===void 0?12e4:i.timeout);o(()=>{w()})}if(!n){const w=()=>{m(),d(p)};this.__state.onStop.push(w),o(()=>{this.__state.onStop=this.__state.onStop.filter(F=>F!==w)})}})},stop(){if(this.isStopped)throw new Error(`reactiveVar ${t.label} is already stopped!`);this.__state.subscriptions=[];for(const a of this.__state.onStop)a();this.__state.onStop=[],this.__state.isStopped=!0}}},B=(e,t)=>{const{__state:{sharedState:{runningState:r,dbName:a}}}=e;if(r.value!=="running")throw new Error(`Failed to start ${t()}, db ${a} is stopping`)};function R(){let e="";const t="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",r=t.length;for(let a=0;a<32;a++)e+=t.charAt(Math.floor(Math.random()*r));return e}const D=e=>{const{current:t,queue:r}=e;return`Current running transaction job: ${JSON.stringify(t,null,2)}, queue of transaction jobs: ${JSON.stringify(r,null,2)}`},te=()=>I({queue:[],current:void 0},{label:"jobsState",deduplicate:!1}),U=e=>({id:e}),q=async(e,t)=>{const{current:r,queue:a}=e.value;if(r||a.length>0){const i=e.waitTill(s=>{var h;return((h=s.current)==null?void 0:h.id)===t.id},{timeout:12e4});e.value={queue:[...a,t],current:r};try{await i}catch(s){throw e.value={...e.value,queue:e.value.queue.filter(h=>h.id!==t.id)},s instanceof E?new E(`Timeout error while transaction job acquire: '${s.message}'. Is it a dead lock? ${D(e.value)}, jobToAcquire: ${JSON.stringify(t,null,2)}`):s}}else e.value={queue:[],current:t}},V=(e,t)=>{const{current:r,queue:a}=e.value;if((r==null?void 0:r.id)!==t.id)throw new Error(`Can't release job that is not currently running, ${D(e.value)}, toRelease: ${JSON.stringify(t,null,2)}`);e.value={queue:a.slice(1),current:a[0]}},re=async e=>{try{return e.waitTill(({queue:t,current:r})=>t.length===0&&r===void 0,{timeout:12e4})}catch(t){throw t instanceof E?new E(`Timeout error while awaiting all jobs done: '${t.message}'. Is it a dead lock?`):t}},Q=async(e,t)=>{let r;if(t){const a=U(t.transactionId);t.containsTransactionStart?await q(e,a):await e.waitTill(i=>{var s;return((s=i.current)==null?void 0:s.id)===a.id}),r=a}else{const a=U(R());await q(e,a),r=a}return r},J=(e,t,r)=>{if(t&&(!r||(r==null?void 0:r.containsTransactionFinish)||(r==null?void 0:r.containsTransactionRollback))&&V(e,t),!t&&r)throw new Error("Transaction job was not started, nothing to release!")},ae=e=>({async run(t,r,a){const i=b(),s=await Q(t,a),p=b()-i;try{return{result:await(async()=>{if(r.type==="usual")if("execUsual"in e){const l=[];for(const d of r.values)try{l.push(await e.execUsual(d))}catch(n){throw n instanceof Error&&(n.message=`Error(${n.message}) while executing query: ${d.text.slice(0,500)}`),n}return l}else return e.execUsualBatch(r.values);else try{return await e.execPrepared(r.query,r.preparedValues)}catch(l){throw l instanceof Error&&(l.message=`Error(${l.message}) while executing query: ${r.query.text.slice(0,500)}`),l}})(),performance:{blockTime:p}}}catch(c){if(a!=null&&a.rollbackOnFail)try{await e.rollback()}catch(l){console.error("Failed to rollback",c,l)}throw c}finally{J(t,s,a)}}}),ie=e=>({async run(t,r,a){const i=b(),s=await Q(t,a),p=b()-i;try{return{result:(()=>{if(r.type==="usual")return"execUsual"in e?r.values.map(l=>{try{return e.execUsual(l)}catch(d){throw d instanceof Error&&(d.message=`Error(${d.message}) while executing query: ${l.text.slice(0,500)}`),d}}):e.execUsualBatch(r.values);try{return e.execPrepared(r.query,r.preparedValues)}catch(l){throw l instanceof Error&&(l.message=`Error(${l.message}) while executing query: ${r.query.text.slice(0,500)}`),l}})(),performance:{blockTime:p}}}catch(c){if(a!=null&&a.rollbackOnFail)try{e.rollback()}catch(l){console.error("Failed to rollback",c,l)}throw c}finally{J(t,s,a)}}});class M extends Error{constructor(t,r,a){super(t.message,{cause:t}),this.dbName=r,this.queries=a,this.cause=t,this.stack=t.stack,this.name="QueryRunError"}}const W=(e,t)=>{if(!e.__state.localState.transactionState.current)throw new Error("Not in transaction.");const r=e.__state.localState.transactionState.current,a=[],i=s=>(h,p)=>{if(r.id===p.id){t(s,h,r);for(const c of a)c()}};a.push(e.__state.sharedState.eventsEmitter.on("transactionCommitted",i("committed"))),a.push(e.__state.sharedState.eventsEmitter.on("transactionRollbacked",i("rollbacked")))};function ne(){const e={};return{async emit(t,...r){const a=e[t]||[];for(const i of a)await i(...r)},on(t,r){return(e[t]=e[t]||[]).push(r),()=>{const a=e[t]||[];e[t]=a.filter(i=>i!==r)}}}}const se=e=>e.filter(t=>t!==null),oe=e=>e.reduce((t,r)=>t+r,0),P=e=>oe(se(e)),N=e=>{if("compile"in e){const{sql:t,parameters:r}=e.compile();return{text:t,values:r}}else{if("preparedQuery"in e)return e.preparedQuery;if("toSql"in e)return N(e.toSql());{const{sql:t,parameters:r}=e;return{text:t,values:r}}}},ce=async({db:e,queries:t,transactionOpts:r})=>{var T,w,F,H,K,X,Z,j,O;const{localState:{transactionState:a},sharedState:{dbBackend:i,logFns:s},sharedState:h}=e.__state;if(a.current||B(e,()=>JSON.stringify(t)),r&&((T=a.current)==null?void 0:T.id)!==r.transactionId)throw new Error(`Cannot run queries in a transaction that is not the current one. Transaction opts: ${JSON.stringify(r)}, local transaction: ${JSON.stringify(a)}`);const p=b(),c=(()=>{const _=r||(a.current?{transactionId:a.current.id,containsTransactionStart:!1,containsTransactionFinish:!1,containsTransactionRollback:!1,rollbackOnFail:!1,isAtomic:!1}:void 0);if(t.type==="prepared"){const y=N(t.query);if(y.values.length!==0)throw new Error("You can't use prepared var through ${} for runPreparedQuery. Please, manually specify variables with '?'.");return{toExecArg:{type:"prepared",query:y,preparedValues:t.preparedValues},toExecArgOpts:_,textQueries:[y.text]}}else{const y=t.values.map(v=>N(v));return{toExecArg:{type:"usual",values:y},toExecArgOpts:_,textQueries:y.map(v=>v.text)}}})(),l=async()=>{try{return{...await i.execQueries(c.toExecArg,c.toExecArgOpts),textQueries:c.textQueries}}catch(_){throw _ instanceof Error?new M(_,e.__state.sharedState.dbName,c.textQueries):_}},{result:d,performance:n,textQueries:u}=await l(),m=b();if(!e.__state.localState.suppressLog){const _=(g,A)=>`${g}=${(A/1e3).toFixed(4)}`,y=(()=>{if(t.type==="prepared"){const g=d[0],A=[g.performance.prepareTime!==void 0?_("prepareTime",P(d.map(k=>k.performance.prepareTime))):"",g.performance.execTime!==void 0?_("execTime",P(d.map(k=>k.performance.execTime))):""].filter(k=>k.length!==0).join(" ");return[[u[0].slice(0,1e3),`for ${t.preparedValues.length} values`,A].filter(k=>k.length!==0).join(" ")]}else return d.map(({performance:g},A)=>{const k=[g.prepareTime!==void 0?_("prepareTime",g.prepareTime):"",g.execTime!==void 0?_("execTime",g.execTime):""].filter(L=>L.length!==0).join(" ");return[u[A].slice(0,1e3),k].filter(L=>L.length!==0).join(" ")})})(),v=(()=>y.length===1?y[0]:` | ||
`+y.map(g=>`{${g}}`).join(` | ||
`))(),Te=`%c[${e.__state.sharedState.dbName}] `+[(w=a.current)!=null&&w.id?`[tr_id=${(F=a.current)==null?void 0:F.id.substring(0,6)}]`:"",v,(n==null?void 0:n.sendTime)!==void 0?`sendTime=${(n.sendTime/1e3).toFixed(4)}`:"",(n==null?void 0:n.receiveTime)!==void 0?`receiveTime=${(n.receiveTime/1e3).toFixed(4)}`:"",(n==null?void 0:n.blockTime)!==void 0?`blockTime=${(n.blockTime/1e3).toFixed(4)}`:"",`totalTime=${((m-p)/1e3).toFixed(4)}`].filter(g=>g.length!==0).join(" "),we=(X=h.transactionsStates.byId[(K=(H=a.current)==null?void 0:H.id)!=null?K:""])==null?void 0:X.i;s.logQuery(Te,we)}const o=(O=h.transactionsStates.byId[(j=(Z=a.current)==null?void 0:Z.id)!=null?j:""])==null?void 0:O.performance;return o&&(d.some(_=>_.performance.execTime!==void 0)&&(o.execTime===void 0&&(o.execTime=0),o.execTime+=d.reduce((_,y)=>{var v;return _+((v=y.performance.execTime)!=null?v:0)},0)),d.some(_=>_.performance.prepareTime!==void 0)&&(o.prepareTime===void 0&&(o.prepareTime=0),o.prepareTime+=d.reduce((_,y)=>{var v;return _+((v=y.performance.prepareTime)!=null?v:0)},0)),n.sendTime&&(o.sendTime||(o.sendTime=0),o.sendTime+=n.sendTime),n.receiveTime&&(o.receiveTime||(o.receiveTime=0),o.receiveTime+=n.receiveTime),n.blockTime&&(o.blockTime||(o.blockTime=0),o.blockTime+=n.blockTime)),{db:e,result:d,performance:n,queries:t}},x=async(e,t,r)=>{const a=[...e.__state.localState.queriesMiddlewares,ce].reverse();let i=s=>Promise.resolve(s);for(const s of a){const h=i;i=p=>s({...p,next:h})}return await i({db:e,result:[],performance:{sendTime:void 0,receiveTime:void 0,totalTime:0},queries:t,transactionOpts:r})};let z=0;const G=(e,t,r)=>{const a=e.__state.sharedState.logFns;if(e.__state.localState.suppressLog)return;const i=[r.prepareTime===void 0?"":`prepareTime=${(r.prepareTime/1e3).toFixed(4)}`,r.execTime===void 0?"":`execTime=${(r.execTime/1e3).toFixed(4)}`,r.sendTime===void 0?"":`sendTime=${(r.sendTime/1e3).toFixed(4)}`,r.receiveTime===void 0?"":`receiveTime=${(r.receiveTime/1e3).toFixed(4)}`,r.blockTime===void 0?"":`blockTime=${(r.blockTime/1e3).toFixed(4)}`,`totalTime=${(r.totalTime/1e3).toFixed(4)}`].filter(s=>s.length!==0).join(" ");a.logTrFinish(`%c[${e.__state.sharedState.dbName}][tr_id=${t.slice(0,6)}] Transaction finished with ${i}`)},le=async(e,t,r)=>{const{localState:{transactionState:a},sharedState:{eventsEmitter:i,transactionsStates:s,dbBackend:h,logFns:p}}=e.__state;if(h.isUsualTransactionDisabled)throw new Error("Usual transactions are disabled for this type of backend. Please, use atomic transactions instead.");if(a.current)return await r(e);B(e,()=>"transaction");const c={id:R(),type:"async"};e={...e,__state:{...e.__state,localState:{...e.__state.localState,transactionState:{current:c}}}};const l=b(),d={i:z++,current:c,performance:{prepareTime:0,execTime:0,freeTime:0,sendTime:0,receiveTime:0,totalTime:0,blockTime:0}};s.byId[c.id]=d;try{await i.emit("transactionWillStart",e,c),await x(e,{type:"usual",values:[S.sql`BEGIN ${S.sql.raw(t.toLocaleUpperCase())} TRANSACTION`]},{transactionId:c.id,containsTransactionStart:!0,containsTransactionFinish:!1,containsTransactionRollback:!1,rollbackOnFail:!1,isAtomic:!1}),await i.emit("transactionStarted",e,c);try{const n=await r(e);return await i.emit("transactionWillCommit",e,c),await x(e,{type:"usual",values:[S.sql`COMMIT`]},{transactionId:c.id,containsTransactionStart:!1,containsTransactionFinish:!0,containsTransactionRollback:!1,rollbackOnFail:!1,isAtomic:!1}),await i.emit("transactionCommitted",e,c),n}catch(n){p.logError("Rollback transaction",n),await i.emit("transactionWillRollback",e,c);try{await x(e,{type:"usual",values:[S.sql`ROLLBACK`]},{transactionId:c.id,containsTransactionStart:!1,containsTransactionFinish:!1,containsTransactionRollback:!0,rollbackOnFail:!1,isAtomic:!1})}catch(u){p.logError("Rollback transaction failed",u)}throw await i.emit("transactionRollbacked",e,c),n}}finally{d.performance.totalTime=b()-l,G(e,c.id,d.performance),delete s.byId[c.id]}},ue=()=>({__state:{queries:[],afterCommits:[],afterRollbacks:[]},addQuery(e){this.__state.queries.push(e)},afterCommit(e){this.__state.afterCommits.push(e)},afterRollback(e){this.__state.afterRollbacks.push(e)}}),de=async(e,t,r)=>{const{localState:{transactionState:a},sharedState:{eventsEmitter:i,transactionsStates:s,dbBackend:h,logFns:p}}=e.__state;if(a.current)throw new Error("You are running atomic transaction inside of a transaction. Consider moving atomic transaction call to runAfterTransaction callback.");const{inputQueries:c,afterCommits:l,afterRollbacks:d}=await(async()=>{if(Array.isArray(r))return{inputQueries:r,afterCommits:[],afterRollbacks:[]};{const T=ue();return await r(T),{inputQueries:T.__state.queries,afterCommits:T.__state.afterCommits,afterRollbacks:T.__state.afterRollbacks}}})(),n={id:R(),type:"atomic"},u={i:z++,current:n,performance:{prepareTime:0,execTime:0,freeTime:0,sendTime:0,receiveTime:0,totalTime:0,blockTime:0}};e={...e,__state:{...e.__state,localState:{...e.__state.localState,transactionState:{current:n}}}},s.byId[n.id]=u;const m=b(),o=[];h.isAtomicRollbackCommitDisabled||o.push(S.sql`BEGIN ${S.sql.raw(t.toUpperCase())} TRANSACTION`),o.push(...c),h.isAtomicRollbackCommitDisabled||o.push(S.sql`COMMIT`);try{await i.emit("transactionWillStart",e,n),await i.emit("transactionStarted",e,n),await x(e,{type:"usual",values:o},{transactionId:n.id,containsTransactionStart:!0,containsTransactionFinish:!0,containsTransactionRollback:!1,rollbackOnFail:!0,isAtomic:!0}),await i.emit("transactionWillCommit",e,n),await i.emit("transactionCommitted",e,n);try{for(const T of l)T()}catch(T){p.logError("Error in afterCommit callback",T)}}catch(T){p.logError("Rollback transaction",T),await i.emit("transactionWillRollback",e,n),await i.emit("transactionRollbacked",e,n);try{for(const w of d)w()}catch(w){p.logError("Error in afterRollback callback",w)}throw T}finally{u.performance.totalTime=b()-m,G(e,n.id,u.performance),delete s.byId[n.id]}},Y=["yellow","cyan","magenta"],me=async({dbName:e,plugins:t,queriesMiddlewares:r,dbBackend:a,suppressLog:i,logFns:s})=>{const h=s||{logQuery:(u,m)=>{const o=typeof m=="number"?Y[m%Y.length]:void 0;console.debug(...o?[u,`color: ${o}; background-color: #202124; padding: 2px 4px; border-radius: 2px`]:[u,"padding: 0"])},logError:(u,m)=>{console.error(u,m)},logTrFinish:u=>{console.debug(u,"color: #fff; background-color: #1da1f2; padding: 2px 4px; border-radius: 2px")}},p=I("running",{label:"runningState"}),c=(await a)({dbName:e}),l={__state:{sharedState:{clientId:R(),dbBackend:c,dbName:e,runningState:p,eventsEmitter:ne(),transactionsStates:{byId:{}},logFns:h},localState:{queriesMiddlewares:r||[],transactionState:{},suppressLog:Boolean(i)}},get isInTransaction(){return this.__state.localState.transactionState.current!==void 0},runInTransaction(u,m){return le(this,(m==null?void 0:m.type)||"deferred",u)},async runInAtomicTransaction(u,m){return await de(this,(m==null?void 0:m.type)||"deferred",u)},async runQueries(u){return(await x(this,{type:"usual",values:u})).result.map(({rows:o})=>o)},async runQuery(u){return(await this.runQueries([u]))[0]},async runPreparedQuery(u,m){return(await x(this,{type:"prepared",query:u,preparedValues:m})).result.map(({rows:T})=>T)},runAfterTransactionCommitted(u){return W(this,(m,o,T)=>{m==="committed"&&u(o,T)})},runAfterTransactionRollbacked(u){W(l,(m,o,T)=>{m==="rollbacked"&&u(o,T)})}};let d=l;const n=()=>l.__state.sharedState.runningState.value;if(n()!=="running"||(await c.initialize(),n()!=="running"))return l;for(const u of t||[])d=u(d);return await l.__state.sharedState.eventsEmitter.emit("initialized",l),d},fe=async e=>{e.__state.sharedState.runningState.value="stopping",await e.__state.sharedState.dbBackend.stop(),e.__state.sharedState.runningState.value="stopped",queueMicrotask(()=>{e.__state.sharedState.runningState.stop()})},he=(e,t)=>t({...e,__state:{...e.__state,localState:{...e.__state.localState,suppressLog:!0}}}),pe=e=>({...e,__state:{...e.__state,localState:{...e.__state.localState,suppressLog:!0}}});f.QueryRunError=M,f.StoppedError=C,f.TimeoutError=E,f.acquireJob=q,f.acquireWithTrJobOrWait=Q,f.buildAsyncQueryRunner=ae,f.buildSyncQueryRunner=ie,f.getTime=b,f.initDbClient=me,f.initJobsState=te,f.makeId=R,f.reactiveVar=I,f.releaseJob=V,f.releaseTrJobIfPossible=J,f.stopDb=fe,f.suppressLog=he,f.whenAllJobsDone=re,f.withSuppressedLog=pe;for(const e in S)e!=="default"&&!f.hasOwnProperty(e)&&Object.defineProperty(f,e,{enumerable:!0,get:()=>S[e]});Object.defineProperties(f,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})}); | ||
//# sourceMappingURL=index.umd.js.map |
@@ -1,2 +0,7 @@ | ||
import { IDb, IQueriesMiddlewareState, IQueriesToRun, ITransactionOpts } from "./types"; | ||
import { IPrimitiveValue } from "@kikko-land/boono-sql"; | ||
import { IDb, IQueriesMiddlewareState, IQueriesToRun, ISqlToRun, ITransactionOpts } from "./types"; | ||
export declare const sqlToValues: (q: ISqlToRun) => { | ||
text: string; | ||
values: IPrimitiveValue[]; | ||
}; | ||
export declare const runQueries: (db: IDb, queries: IQueriesToRun, transactionOpts?: ITransactionOpts) => Promise<IQueriesMiddlewareState>; |
@@ -1,4 +0,3 @@ | ||
import { ISqlAdapter } from "@kikko-land/boono-sql"; | ||
import { IAtomicTransactionScope, IDb } from "./types"; | ||
import { IAtomicTransactionScope, IDb, ISqlToRun } from "./types"; | ||
export declare const runInTransactionFunc: <T>(db: IDb, transactionType: "deferred" | "immediate" | "exclusive", func: (state: IDb) => Promise<T>) => Promise<T>; | ||
export declare const execAtomicTransaction: (db: IDb, transactionType: "deferred" | "immediate" | "exclusive", funcOrQueries: ISqlAdapter[] | ((scope: IAtomicTransactionScope) => Promise<void> | void)) => Promise<void>; | ||
export declare const execAtomicTransaction: (db: IDb, transactionType: "deferred" | "immediate" | "exclusive", funcOrQueries: ISqlToRun[] | ((scope: IAtomicTransactionScope) => Promise<void> | void)) => Promise<void>; |
@@ -47,16 +47,25 @@ import { IPrimitiveValue, ISql, ISqlAdapter } from "@kikko-land/boono-sql"; | ||
__state: { | ||
queries: ISqlAdapter[]; | ||
queries: ISqlToRun[]; | ||
afterCommits: (() => void)[]; | ||
afterRollbacks: (() => void)[]; | ||
}; | ||
addQuery(q: ISqlAdapter): void; | ||
addQuery(q: ISqlToRun): void; | ||
afterCommit(cb: () => void): void; | ||
afterRollback(cb: () => void): void; | ||
} | ||
export declare type ISqlToRun = { | ||
sql: string; | ||
parameters: unknown[]; | ||
} | { | ||
compile: () => { | ||
readonly sql: string; | ||
readonly parameters: ReadonlyArray<unknown>; | ||
}; | ||
} | ISql | ISqlAdapter; | ||
export declare type IQueriesToRun = { | ||
type: "usual"; | ||
values: ISql[]; | ||
values: ISqlToRun[]; | ||
} | { | ||
type: "prepared"; | ||
query: ISql; | ||
query: ISqlToRun; | ||
preparedValues: IPrimitiveValue[][]; | ||
@@ -69,11 +78,12 @@ }; | ||
}; | ||
get isInTransaction(): boolean; | ||
runInTransaction<T>(func: (state: IDb) => Promise<T>, opts?: { | ||
type?: "deferred" | "immediate" | "exclusive"; | ||
}): Promise<T>; | ||
runInAtomicTransaction(func: ((scope: IAtomicTransactionScope) => Promise<void> | void) | ISqlAdapter[], opts?: { | ||
runInAtomicTransaction(func: ((scope: IAtomicTransactionScope) => Promise<void> | void) | ISqlToRun[], opts?: { | ||
type?: "deferred" | "immediate" | "exclusive"; | ||
}): Promise<void>; | ||
runQueries<D extends Record<string, unknown>>(queries: ISqlAdapter[]): Promise<D[][]>; | ||
runQuery<D extends Record<string, unknown>>(query: ISqlAdapter): Promise<D[]>; | ||
runPreparedQuery<D extends Record<string, unknown>>(query: ISql, preparedValues: IPrimitiveValue[][]): Promise<D[][]>; | ||
runQueries<D extends Record<string, unknown>>(queries: ISqlToRun[]): Promise<D[][]>; | ||
runQuery<D extends Record<string, unknown>>(query: ISqlToRun): Promise<D[]>; | ||
runPreparedQuery<D extends Record<string, unknown>>(query: ISqlToRun, preparedValues: IPrimitiveValue[][]): Promise<D[][]>; | ||
runAfterTransactionCommitted(func: (db: IDb, transaction: ITransaction) => void): void; | ||
@@ -80,0 +90,0 @@ runAfterTransactionRollbacked(func: (db: IDb, transaction: ITransaction) => void): void; |
{ | ||
"name": "@kikko-land/kikko", | ||
"version": "0.17.0", | ||
"version": "0.18.0", | ||
"author": "Sergey Popov", | ||
@@ -5,0 +5,0 @@ "license": "MIT", |
@@ -1,2 +0,2 @@ | ||
import { IPrimitiveValue, ISql, ISqlAdapter } from "@kikko-land/boono-sql"; | ||
import { IPrimitiveValue, ISql } from "@kikko-land/boono-sql"; | ||
@@ -15,2 +15,3 @@ import { runAfterTransaction } from "./afterTransaction"; | ||
IQueriesMiddleware, | ||
ISqlToRun, | ||
ITransaction, | ||
@@ -92,2 +93,5 @@ } from "./types"; | ||
}, | ||
get isInTransaction() { | ||
return this.__state.localState.transactionState.current !== undefined; | ||
}, | ||
runInTransaction<T>( | ||
@@ -102,3 +106,3 @@ func: (state: IDb) => Promise<T>, | ||
| ((scope: IAtomicTransactionScope) => Promise<void> | void) | ||
| ISqlAdapter[], | ||
| ISqlToRun[], | ||
@@ -110,7 +114,7 @@ opts?: { label?: string; type?: "deferred" | "immediate" | "exclusive" } | ||
async runQueries<D extends Record<string, unknown>>( | ||
queries: ISqlAdapter[] | ||
queries: ISqlToRun[] | ||
): Promise<D[][]> { | ||
const res = await runQueries(this, { | ||
type: "usual", | ||
values: queries.map((q) => q.toSql()), | ||
values: queries, | ||
}); | ||
@@ -120,3 +124,3 @@ return res.result.map(({ rows }) => rows) as D[][]; | ||
async runQuery<D extends Record<string, unknown>>( | ||
query: ISqlAdapter | ||
query: ISqlToRun | ||
): Promise<D[]> { | ||
@@ -123,0 +127,0 @@ return (await this.runQueries<D>([query]))[0]; |
@@ -1,7 +0,1 @@ | ||
/* eslint-disable @typescript-eslint/ban-ts-comment */ | ||
export const getTime = | ||
// @ts-ignore | ||
typeof performance !== "undefined" | ||
? // @ts-ignore | ||
() => performance.now() | ||
: () => Date.now(); | ||
export const getTime = () => Date.now(); |
@@ -44,3 +44,2 @@ import { deepEqual } from "fast-equals"; | ||
stopLoopAfter = undefined; | ||
console.log("loop stopped"); | ||
break; | ||
@@ -47,0 +46,0 @@ } |
@@ -0,1 +1,3 @@ | ||
import { IPrimitiveValue } from "@kikko-land/boono-sql"; | ||
import { QueryRunError } from "./errors"; | ||
@@ -9,2 +11,3 @@ import { getTime } from "./measurePerformance"; | ||
IQueriesToRun, | ||
ISqlToRun, | ||
ITransactionOpts, | ||
@@ -21,2 +24,26 @@ } from "./types"; | ||
export const sqlToValues = ( | ||
q: ISqlToRun | ||
): { text: string; values: IPrimitiveValue[] } => { | ||
if ("compile" in q) { | ||
const { sql, parameters } = q.compile(); | ||
return { | ||
text: sql, | ||
values: parameters as IPrimitiveValue[], | ||
}; | ||
} else if ("preparedQuery" in q) { | ||
return q.preparedQuery; | ||
} else if ("toSql" in q) { | ||
return sqlToValues(q.toSql()); | ||
} else { | ||
const { sql, parameters } = q; | ||
return { | ||
text: sql, | ||
values: parameters as IPrimitiveValue[], | ||
}; | ||
} | ||
}; | ||
const runQueriesMiddleware: IQueriesMiddleware = async ({ | ||
@@ -64,5 +91,5 @@ db, | ||
if (queries.type === "prepared") { | ||
const q = queries.query.toSql(); | ||
const toExec = sqlToValues(queries.query); | ||
if (q._values.length !== 0) { | ||
if (toExec.values.length !== 0) { | ||
throw new Error( | ||
@@ -72,3 +99,2 @@ "You can't use prepared var through ${} for runPreparedQuery. Please, manually specify variables with '?'." | ||
} | ||
const toExec = q.preparedQuery.text; | ||
@@ -78,10 +104,10 @@ return { | ||
type: "prepared", | ||
query: q.preparedQuery, | ||
query: toExec, | ||
preparedValues: queries.preparedValues, | ||
}, | ||
toExecArgOpts: opts, | ||
textQueries: [toExec], | ||
textQueries: [toExec.text], | ||
} as const; | ||
} else { | ||
const toExec = queries.values.map((q) => q.preparedQuery); | ||
const toExec = queries.values.map((q) => sqlToValues(q)); | ||
@@ -88,0 +114,0 @@ return { |
@@ -1,2 +0,2 @@ | ||
import { ISql, ISqlAdapter, sql } from "@kikko-land/boono-sql"; | ||
import { sql } from "@kikko-land/boono-sql"; | ||
@@ -8,2 +8,3 @@ import { getTime } from "./measurePerformance"; | ||
IDb, | ||
ISqlToRun, | ||
ITransaction, | ||
@@ -202,3 +203,3 @@ ITransactionPerformance, | ||
}, | ||
addQuery(q: ISqlAdapter): void { | ||
addQuery(q: ISqlToRun): void { | ||
this.__state.queries.push(q); | ||
@@ -220,3 +221,3 @@ }, | ||
| ((scope: IAtomicTransactionScope) => Promise<void> | void) | ||
| ISqlAdapter[] | ||
| ISqlToRun[] | ||
): Promise<void> => { | ||
@@ -285,3 +286,3 @@ const { | ||
const q: ISql[] = []; | ||
const q: ISqlToRun[] = []; | ||
@@ -292,3 +293,3 @@ if (!dbBackend.isAtomicRollbackCommitDisabled) { | ||
q.push(...inputQueries.map((q) => q.toSql())); | ||
q.push(...inputQueries); | ||
@@ -295,0 +296,0 @@ if (!dbBackend.isAtomicRollbackCommitDisabled) { |
@@ -76,7 +76,7 @@ import { IPrimitiveValue, ISql, ISqlAdapter } from "@kikko-land/boono-sql"; | ||
__state: { | ||
queries: ISqlAdapter[]; | ||
queries: ISqlToRun[]; | ||
afterCommits: (() => void)[]; | ||
afterRollbacks: (() => void)[]; | ||
}; | ||
addQuery(q: ISqlAdapter): void; | ||
addQuery(q: ISqlToRun): void; | ||
afterCommit(cb: () => void): void; | ||
@@ -86,5 +86,16 @@ afterRollback(cb: () => void): void; | ||
export type ISqlToRun = | ||
| { sql: string; parameters: unknown[] } | ||
| { | ||
compile: () => { | ||
readonly sql: string; | ||
readonly parameters: ReadonlyArray<unknown>; | ||
}; | ||
} | ||
| ISql | ||
| ISqlAdapter; | ||
export type IQueriesToRun = | ||
| { type: "usual"; values: ISql[] } | ||
| { type: "prepared"; query: ISql; preparedValues: IPrimitiveValue[][] }; | ||
| { type: "usual"; values: ISqlToRun[] } | ||
| { type: "prepared"; query: ISqlToRun; preparedValues: IPrimitiveValue[][] }; | ||
@@ -99,2 +110,4 @@ export interface IDb { | ||
get isInTransaction(): boolean; | ||
runInTransaction<T>( | ||
@@ -107,3 +120,3 @@ func: (state: IDb) => Promise<T>, | ||
| ((scope: IAtomicTransactionScope) => Promise<void> | void) | ||
| ISqlAdapter[], | ||
| ISqlToRun[], | ||
opts?: { type?: "deferred" | "immediate" | "exclusive" } | ||
@@ -113,7 +126,7 @@ ): Promise<void>; | ||
runQueries<D extends Record<string, unknown>>( | ||
queries: ISqlAdapter[] | ||
queries: ISqlToRun[] | ||
): Promise<D[][]>; | ||
runQuery<D extends Record<string, unknown>>(query: ISqlAdapter): Promise<D[]>; | ||
runQuery<D extends Record<string, unknown>>(query: ISqlToRun): Promise<D[]>; | ||
runPreparedQuery<D extends Record<string, unknown>>( | ||
query: ISql, | ||
query: ISqlToRun, | ||
preparedValues: IPrimitiveValue[][] | ||
@@ -120,0 +133,0 @@ ): Promise<D[][]>; |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
245606
2882