@kikko-land/kikko
Advanced tools
Comparing version 0.12.0 to 0.13.0
# @kikko-land/core | ||
## 0.13.0 | ||
### Minor Changes | ||
- 085297e: Fix memmory leak | ||
## 0.12.0 | ||
@@ -4,0 +10,0 @@ |
import { deepEqual as z } from "fast-equals"; | ||
import { sql as g } from "@kikko-land/boono-sql"; | ||
export * from "@kikko-land/boono-sql"; | ||
const q = (e, t) => { | ||
const Q = (e, t) => { | ||
if (!e.__state.localState.transactionState.current) | ||
throw new Error("Not in transaction."); | ||
const a = e.__state.localState.transactionState.current, i = [], r = (o) => (d, p) => { | ||
const a = e.__state.localState.transactionState.current, i = [], r = (o) => (m, p) => { | ||
if (a.id === p.id) { | ||
t(o, d, a); | ||
t(o, m, a); | ||
for (const c of i) | ||
@@ -76,7 +76,7 @@ c(); | ||
let o; | ||
const d = (p) => { | ||
const m = (p) => { | ||
o && o(), o = i(p); | ||
}; | ||
return this.__state.subscriptions.push(d), r && d(this.__state.value), () => { | ||
this.__state.subscriptions = this.__state.subscriptions.filter((p) => p !== d); | ||
return this.__state.subscriptions.push(m), r && m(this.__state.value), () => { | ||
this.__state.subscriptions = this.__state.subscriptions.filter((p) => p !== m); | ||
}; | ||
@@ -87,3 +87,3 @@ }, | ||
`waitUntil for reactiveVar ${t.label} is stopped due to stop signal` | ||
), d = new $( | ||
), m = new $( | ||
`waitUntil for reactiveVar ${t.label} is timed out` | ||
@@ -96,29 +96,36 @@ ), p = new N( | ||
return new Promise((s, T) => { | ||
var u; | ||
const l = [], n = () => { | ||
for (const m of l) | ||
m(); | ||
var f; | ||
let u = []; | ||
const n = () => { | ||
queueMicrotask(() => { | ||
for (const l of u) | ||
l(); | ||
u = []; | ||
}); | ||
}; | ||
if (l.push( | ||
((u = r == null ? void 0 : r.stopIf) == null ? void 0 : u.subscribe((m) => { | ||
!m || (n(), T(o)); | ||
if (u.push( | ||
((f = r == null ? void 0 : r.stopIf) == null ? void 0 : f.subscribe((l) => { | ||
!l || (n(), T(o)); | ||
}, !0)) || (() => { | ||
}) | ||
), l.push( | ||
this.subscribe((m) => { | ||
!i(m) || (n(), s()); | ||
), u.push( | ||
this.subscribe((l) => { | ||
!i(l) || (n(), s()); | ||
}, !0) | ||
), (r == null ? void 0 : r.timeout) === void 0 || typeof (r == null ? void 0 : r.timeout) == "number") { | ||
const m = setTimeout( | ||
const l = setTimeout( | ||
() => { | ||
n(), T(d); | ||
n(), T(m); | ||
}, | ||
(r == null ? void 0 : r.timeout) === void 0 ? 12e4 : r.timeout | ||
); | ||
l.push(() => { | ||
clearTimeout(m); | ||
u.push(() => { | ||
clearTimeout(l); | ||
}); | ||
} | ||
this.__state.onStop.push(() => { | ||
const d = () => { | ||
n(), T(p); | ||
}; | ||
this.__state.onStop.push(d), u.push(() => { | ||
this.__state.onStop = this.__state.onStop.filter((l) => l !== d); | ||
}); | ||
@@ -133,6 +140,6 @@ }); | ||
i(); | ||
this.__state.isStopped = !0; | ||
this.__state.onStop = [], this.__state.isStopped = !0; | ||
} | ||
}; | ||
}, k = typeof performance < "u" ? () => performance.now() : () => Date.now(), V = (e, t) => { | ||
}, k = typeof performance < "u" ? () => performance.now() : () => Date.now(), M = (e, t) => { | ||
const { | ||
@@ -153,3 +160,3 @@ __state: { | ||
} | ||
const Y = (e) => e.filter((t) => t !== null), K = (e) => e.reduce((t, a) => t + a, 0), J = (e) => K(Y(e)), H = async ({ | ||
const Y = (e) => e.filter((t) => t !== null), H = (e) => e.reduce((t, a) => t + a, 0), J = (e) => H(Y(e)), K = async ({ | ||
db: e, | ||
@@ -159,9 +166,9 @@ queries: t, | ||
}) => { | ||
var u, m, f, y, F, R, I, A, Q; | ||
var d, f, l, y, F, R, I, A, q; | ||
const { | ||
localState: { transactionState: i }, | ||
sharedState: { dbBackend: r, logFns: o }, | ||
sharedState: d | ||
sharedState: m | ||
} = e.__state; | ||
if (i.current || V(e, () => JSON.stringify(t)), a && ((u = i.current) == null ? void 0 : u.id) !== a.transactionId) | ||
if (i.current || M(e, () => JSON.stringify(t)), a && ((d = i.current) == null ? void 0 : d.id) !== a.transactionId) | ||
throw new Error( | ||
@@ -207,3 +214,3 @@ `Cannot run queries in a transaction that is not the current one. Transaction opts: ${JSON.stringify( | ||
} | ||
})(), l = k(); | ||
})(), u = k(); | ||
if (!e.__state.localState.suppressLog) { | ||
@@ -240,3 +247,3 @@ const h = (S, x) => `${S}=${(x / 1e3).toFixed(4)}`, _ = (() => { | ||
`))(), U = `%c[${e.__state.sharedState.dbName}] ` + [ | ||
(m = i.current) != null && m.id ? `[tr_id=${(f = i.current) == null ? void 0 : f.id.substring(0, 6)}]` : "", | ||
(f = i.current) != null && f.id ? `[tr_id=${(l = i.current) == null ? void 0 : l.id.substring(0, 6)}]` : "", | ||
w, | ||
@@ -246,7 +253,7 @@ (s == null ? void 0 : s.sendTime) !== void 0 ? `sendTime=${(s.sendTime / 1e3).toFixed(4)}` : "", | ||
(s == null ? void 0 : s.blockTime) !== void 0 ? `blockTime=${(s.blockTime / 1e3).toFixed(4)}` : "", | ||
`totalTime=${((l - p) / 1e3).toFixed(4)}` | ||
].filter((S) => S.length !== 0).join(" "), P = (R = d.transactionsStates.byId[(F = (y = i.current) == null ? void 0 : y.id) != null ? F : ""]) == null ? void 0 : R.i; | ||
`totalTime=${((u - p) / 1e3).toFixed(4)}` | ||
].filter((S) => S.length !== 0).join(" "), P = (R = m.transactionsStates.byId[(F = (y = i.current) == null ? void 0 : y.id) != null ? F : ""]) == null ? void 0 : R.i; | ||
o.logQuery(U, P); | ||
} | ||
const n = (Q = d.transactionsStates.byId[(A = (I = i.current) == null ? void 0 : I.id) != null ? A : ""]) == null ? void 0 : Q.performance; | ||
const n = (q = m.transactionsStates.byId[(A = (I = i.current) == null ? void 0 : I.id) != null ? A : ""]) == null ? void 0 : q.performance; | ||
return n && (c.some((h) => h.performance.execTime !== void 0) && (n.execTime === void 0 && (n.execTime = 0), n.execTime += c.reduce( | ||
@@ -268,8 +275,8 @@ (h, _) => { | ||
...e.__state.localState.queriesMiddlewares, | ||
H | ||
K | ||
].reverse(); | ||
let r = (o) => Promise.resolve(o); | ||
for (const o of i) { | ||
const d = r; | ||
r = (p) => o({ ...p, next: d }); | ||
const m = r; | ||
r = (p) => o({ ...p, next: m }); | ||
} | ||
@@ -288,4 +295,4 @@ return await r({ | ||
}; | ||
let B = 0; | ||
const M = (e, t, a) => { | ||
let V = 0; | ||
const B = (e, t, a) => { | ||
const i = e.__state.sharedState.logFns; | ||
@@ -311,5 +318,5 @@ if (e.__state.localState.suppressLog) | ||
localState: { transactionState: i }, | ||
sharedState: { eventsEmitter: r, transactionsStates: o, dbBackend: d, logFns: p } | ||
sharedState: { eventsEmitter: r, transactionsStates: o, dbBackend: m, logFns: p } | ||
} = e.__state; | ||
if (d.isUsualTransactionDisabled) | ||
if (m.isUsualTransactionDisabled) | ||
throw new Error( | ||
@@ -320,3 +327,3 @@ "Usual transactions are disabled for this type of backend. Please, use atomic transactions instead." | ||
return await a(e); | ||
V(e, () => "transaction"); | ||
M(e, () => "transaction"); | ||
const c = { | ||
@@ -337,3 +344,3 @@ id: C(), | ||
const s = k(), T = { | ||
i: B++, | ||
i: V++, | ||
current: c, | ||
@@ -372,3 +379,3 @@ performance: { | ||
try { | ||
const l = await a(e); | ||
const u = await a(e); | ||
return await r.emit("transactionWillCommit", e, c), await b( | ||
@@ -385,5 +392,5 @@ e, | ||
} | ||
), await r.emit("transactionCommitted", e, c), l; | ||
} catch (l) { | ||
p.logError("Rollback transaction", l), await r.emit("transactionWillRollback", e, c); | ||
), await r.emit("transactionCommitted", e, c), u; | ||
} catch (u) { | ||
p.logError("Rollback transaction", u), await r.emit("transactionWillRollback", e, c); | ||
try { | ||
@@ -405,6 +412,6 @@ await b( | ||
} | ||
throw await r.emit("transactionRollbacked", e, c), l; | ||
throw await r.emit("transactionRollbacked", e, c), u; | ||
} | ||
} finally { | ||
T.performance.totalTime = k() - s, M(e, c.id, T.performance), delete o.byId[c.id]; | ||
T.performance.totalTime = k() - s, B(e, c.id, T.performance), delete o.byId[c.id]; | ||
} | ||
@@ -429,3 +436,3 @@ }, Z = () => ({ | ||
localState: { transactionState: i }, | ||
sharedState: { eventsEmitter: r, transactionsStates: o, dbBackend: d, logFns: p } | ||
sharedState: { eventsEmitter: r, transactionsStates: o, dbBackend: m, logFns: p } | ||
} = e.__state; | ||
@@ -444,15 +451,15 @@ if (i.current) | ||
{ | ||
const f = Z(); | ||
return await a(f), { | ||
inputQueries: f.__state.queries, | ||
afterCommits: f.__state.afterCommits, | ||
afterRollbacks: f.__state.afterRollbacks | ||
const l = Z(); | ||
return await a(l), { | ||
inputQueries: l.__state.queries, | ||
afterCommits: l.__state.afterCommits, | ||
afterRollbacks: l.__state.afterRollbacks | ||
}; | ||
} | ||
})(), l = { | ||
})(), u = { | ||
id: C(), | ||
type: "atomic" | ||
}, n = { | ||
i: B++, | ||
current: l, | ||
i: V++, | ||
current: u, | ||
performance: { | ||
@@ -474,14 +481,14 @@ prepareTime: 0, | ||
...e.__state.localState, | ||
transactionState: { current: l } | ||
transactionState: { current: u } | ||
} | ||
} | ||
}, o.byId[l.id] = n; | ||
const u = k(), m = []; | ||
d.isAtomicRollbackCommitDisabled || m.push(g`BEGIN ${g.raw(t.toUpperCase())} TRANSACTION`), m.push(...c.map((f) => f.toSql())), d.isAtomicRollbackCommitDisabled || m.push(g`COMMIT`); | ||
}, o.byId[u.id] = n; | ||
const d = k(), f = []; | ||
m.isAtomicRollbackCommitDisabled || f.push(g`BEGIN ${g.raw(t.toUpperCase())} TRANSACTION`), f.push(...c.map((l) => l.toSql())), m.isAtomicRollbackCommitDisabled || f.push(g`COMMIT`); | ||
try { | ||
await r.emit("transactionWillStart", e, l), await r.emit("transactionStarted", e, l), await b( | ||
await r.emit("transactionWillStart", e, u), await r.emit("transactionStarted", e, u), await b( | ||
e, | ||
{ type: "usual", values: m }, | ||
{ type: "usual", values: f }, | ||
{ | ||
transactionId: l.id, | ||
transactionId: u.id, | ||
containsTransactionStart: !0, | ||
@@ -493,11 +500,11 @@ containsTransactionFinish: !0, | ||
} | ||
), await r.emit("transactionWillCommit", e, l), await r.emit("transactionCommitted", e, l); | ||
), await r.emit("transactionWillCommit", e, u), await r.emit("transactionCommitted", e, u); | ||
try { | ||
for (const f of s) | ||
f(); | ||
} catch (f) { | ||
p.logError("Error in afterCommit callback", f); | ||
for (const l of s) | ||
l(); | ||
} catch (l) { | ||
p.logError("Error in afterCommit callback", l); | ||
} | ||
} catch (f) { | ||
p.logError("Rollback transaction", f), await r.emit("transactionWillRollback", e, l), await r.emit("transactionRollbacked", e, l); | ||
} catch (l) { | ||
p.logError("Rollback transaction", l), await r.emit("transactionWillRollback", e, u), await r.emit("transactionRollbacked", e, u); | ||
try { | ||
@@ -509,5 +516,5 @@ for (const y of T) | ||
} | ||
throw f; | ||
throw l; | ||
} finally { | ||
n.performance.totalTime = k() - u, M(e, l.id, n.performance), delete o.byId[l.id]; | ||
n.performance.totalTime = k() - d, B(e, u.id, n.performance), delete o.byId[u.id]; | ||
} | ||
@@ -522,14 +529,14 @@ }, L = ["yellow", "cyan", "magenta"], ie = async ({ | ||
}) => { | ||
const d = o || { | ||
logQuery: (n, u) => { | ||
const m = typeof u == "number" ? L[u % L.length] : void 0; | ||
const m = o || { | ||
logQuery: (n, d) => { | ||
const f = typeof d == "number" ? L[d % L.length] : void 0; | ||
console.log( | ||
...m ? [ | ||
...f ? [ | ||
n, | ||
`color: ${m}; background-color: #202124; padding: 2px 4px; border-radius: 2px` | ||
`color: ${f}; background-color: #202124; padding: 2px 4px; border-radius: 2px` | ||
] : [n, "padding: 0"] | ||
); | ||
}, | ||
logError: (n, u) => { | ||
console.error(n, u); | ||
logError: (n, d) => { | ||
console.error(n, d); | ||
}, | ||
@@ -556,3 +563,3 @@ logTrFinish: (n) => { | ||
transactionsStates: { byId: {} }, | ||
logFns: d | ||
logFns: m | ||
}, | ||
@@ -565,7 +572,7 @@ localState: { | ||
}, | ||
runInTransaction(n, u) { | ||
return X(this, (u == null ? void 0 : u.type) || "deferred", n); | ||
runInTransaction(n, d) { | ||
return X(this, (d == null ? void 0 : d.type) || "deferred", n); | ||
}, | ||
async runInAtomicTransaction(n, u) { | ||
return await j(this, (u == null ? void 0 : u.type) || "deferred", n); | ||
async runInAtomicTransaction(n, d) { | ||
return await j(this, (d == null ? void 0 : d.type) || "deferred", n); | ||
}, | ||
@@ -575,4 +582,4 @@ async runQueries(n) { | ||
type: "usual", | ||
values: n.map((m) => m.toSql()) | ||
})).result.map(({ rows: m }) => m); | ||
values: n.map((f) => f.toSql()) | ||
})).result.map(({ rows: f }) => f); | ||
}, | ||
@@ -582,17 +589,17 @@ async runQuery(n) { | ||
}, | ||
async runPreparedQuery(n, u) { | ||
async runPreparedQuery(n, d) { | ||
return (await b(this, { | ||
type: "prepared", | ||
query: n, | ||
preparedValues: u | ||
})).result.map(({ rows: f }) => f); | ||
preparedValues: d | ||
})).result.map(({ rows: l }) => l); | ||
}, | ||
runAfterTransactionCommitted(n) { | ||
return q(this, (u, m, f) => { | ||
u === "committed" && n(m, f); | ||
return Q(this, (d, f, l) => { | ||
d === "committed" && n(f, l); | ||
}); | ||
}, | ||
runAfterTransactionRollbacked(n) { | ||
q(s, (u, m, f) => { | ||
u === "rollbacked" && n(m, f); | ||
Q(s, (d, f, l) => { | ||
d === "rollbacked" && n(f, l); | ||
}); | ||
@@ -602,4 +609,4 @@ } | ||
let T = s; | ||
const l = () => s.__state.sharedState.runningState.value; | ||
if (l() !== "running" || (await c.initialize(), l() !== "running")) | ||
const u = () => s.__state.sharedState.runningState.value; | ||
if (u() !== "running" || (await c.initialize(), u() !== "running")) | ||
return s; | ||
@@ -646,4 +653,4 @@ for (const n of t || []) | ||
(o) => { | ||
var d; | ||
return ((d = o.current) == null ? void 0 : d.id) === t.id; | ||
var m; | ||
return ((m = o.current) == null ? void 0 : m.id) === t.id; | ||
}, | ||
@@ -663,3 +670,3 @@ { | ||
...e.value, | ||
queue: e.value.queue.filter((d) => d.id !== t.id) | ||
queue: e.value.queue.filter((m) => m.id !== t.id) | ||
}, o instanceof $ ? new $( | ||
@@ -710,3 +717,3 @@ `Timeout error while trnsaction job acquire: '${o.message}'. Is it a dead lock? ${W( | ||
return a; | ||
}, me = (e, t, a) => { | ||
}, de = (e, t, a) => { | ||
if (t && (!a || (a == null ? void 0 : a.containsTransactionFinish) || (a == null ? void 0 : a.containsTransactionRollback)) && te(e, t), !t && a) | ||
@@ -726,3 +733,3 @@ throw new Error("Transaction job was not started, nothing to release!"); | ||
te as releaseJob, | ||
me as releaseTrJobIfPossible, | ||
de as releaseTrJobIfPossible, | ||
ne as stopDb, | ||
@@ -729,0 +736,0 @@ se as suppressLog, |
@@ -1,4 +0,4 @@ | ||
(function(m,C){typeof exports=="object"&&typeof module<"u"?C(exports,require("fast-equals"),require("@kikko-land/boono-sql")):typeof define=="function"&&define.amd?define(["exports","fast-equals","@kikko-land/boono-sql"],C):(m=typeof globalThis<"u"?globalThis:m||self,C(m.core={},m.fastEquals,m.boonoSql))})(this,function(m,C,S){"use strict";const q=(e,t)=>{if(!e.__state.localState.transactionState.current)throw new Error("Not in transaction.");const a=e.__state.localState.transactionState.current,r=[],i=o=>(f,p)=>{if(a.id===p.id){t(o,f,a);for(const c of r)c()}};r.push(e.__state.sharedState.eventsEmitter.on("transactionCommitted",i("committed"))),r.push(e.__state.sharedState.eventsEmitter.on("transactionRollbacked",i("rollbacked")))};function Y(){const e={};return{async emit(t,...a){const r=e[t]||[];for(const i of r)await i(...a)},on(t,a){return(e[t]=e[t]||[]).push(a),()=>{const r=e[t]||[];e[t]=r.filter(i=>i!==a)}}}}class k extends Error{}class x extends Error{}const R=(e,t)=>{const a=t.deduplicate===void 0?!0:t.deduplicate;return{__state:{subscriptions:[],value:e,isStopped:!1,onStop:[]},get isStopped(){return this.__state.isStopped},set value(r){if(this.isStopped)throw new Error(`reactiveVar ${t.label} is stopped!`);if(!(a&&C.deepEqual(this.__state.value,r))){this.__state.value=r;for(const i of this.__state.subscriptions)i(r)}},get value(){if(this.isStopped)throw new Error(`reactiveVar ${t.label} is stopped!`);return this.__state.value},subscribe(r,i=!0){if(this.isStopped)throw new Error(`reactiveVar ${t.label} is stopped!`);let o;const f=p=>{o&&o(),o=r(p)};return this.__state.subscriptions.push(f),i&&f(this.__state.value),()=>{this.__state.subscriptions=this.__state.subscriptions.filter(p=>p!==f)}},waitTill(r,i){const o=new x(`waitUntil for reactiveVar ${t.label} is stopped due to stop signal`),f=new k(`waitUntil for reactiveVar ${t.label} is timed out`),p=new x(`waitUntil for reactiveVar ${t.label} is stopped due to reactive var stop`);if(this.isStopped)throw new Error(`reactiveVar ${t.label} is stopped!`);return new Promise((s,h)=>{var u;const l=[],n=()=>{for(const d of l)d()};if(l.push(((u=i==null?void 0:i.stopIf)==null?void 0:u.subscribe(d=>{!d||(n(),h(o))},!0))||(()=>{})),l.push(this.subscribe(d=>{!r(d)||(n(),s())},!0)),(i==null?void 0:i.timeout)===void 0||typeof(i==null?void 0:i.timeout)=="number"){const d=setTimeout(()=>{n(),h(f)},(i==null?void 0:i.timeout)===void 0?12e4:i.timeout);l.push(()=>{clearTimeout(d)})}this.__state.onStop.push(()=>{n(),h(p)})})},stop(){if(this.isStopped)throw new Error(`reactiveVar ${t.label} is already stopped!`);this.__state.subscriptions=[];for(const r of this.__state.onStop)r();this.__state.isStopped=!0}}},y=typeof performance<"u"?()=>performance.now():()=>Date.now(),J=(e,t)=>{const{__state:{sharedState:{runningState:a,dbName:r}}}=e;if(a.value!=="running")throw new Error(`Failed to start ${t()}, db ${r} is stopping`)};function I(){let e="";const t="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",a=t.length;for(let r=0;r<32;r++)e+=t.charAt(Math.floor(Math.random()*a));return e}const K=e=>e.filter(t=>t!==null),H=e=>e.reduce((t,a)=>t+a,0),Q=e=>H(K(e)),X=async({db:e,queries:t,transactionOpts:a})=>{var u,d,T,$,B,U,P,z,G;const{localState:{transactionState:r},sharedState:{dbBackend:i,logFns:o},sharedState:f}=e.__state;if(r.current||J(e,()=>JSON.stringify(t)),a&&((u=r.current)==null?void 0:u.id)!==a.transactionId)throw new Error(`Cannot run queries in a transaction that is not the current one. Transaction opts: ${JSON.stringify(a)}, local transaction: ${JSON.stringify(r)}`);const p=y(),{result:c,performance:s,textQueries:h}=await(async()=>{const _=a||(r.current?{transactionId:r.current.id,containsTransactionStart:!1,containsTransactionFinish:!1,containsTransactionRollback:!1,rollbackOnFail:!1,isAtomic:!1}:void 0);if(t.type==="prepared"){const w=t.query.toSql();if(w._values.length!==0)throw new Error("You can't use prepared var through ${} for runPreparedQuery. Please, manually specify variables with '?'.");const v=w.preparedQuery.text;return{...await i.execPreparedQuery(w.preparedQuery,t.preparedValues,_),textQueries:[v]}}else{const w=t.values.map(v=>v.preparedQuery);return{...await i.execQueries(w,_),textQueries:w.map(v=>v.text)}}})(),l=y();if(!e.__state.localState.suppressLog){const _=(g,F)=>`${g}=${(F/1e3).toFixed(4)}`,w=(()=>{if(t.type==="prepared"){const g=c[0],F=[g.performance.prepareTime!==void 0?_("prepareTime",Q(c.map(b=>b.performance.prepareTime))):"",g.performance.execTime!==void 0?_("execTime",Q(c.map(b=>b.performance.execTime))):""].filter(b=>b.length!==0).join(" ");return[[h[0].slice(0,1e3),`for ${t.preparedValues.length} values`,F].filter(b=>b.length!==0).join(" ")]}else return c.map(({performance:g},F)=>{const b=[g.prepareTime!==void 0?_("prepareTime",g.prepareTime):"",g.execTime!==void 0?_("execTime",g.execTime):""].filter(A=>A.length!==0).join(" ");return[h[F].slice(0,1e3),b].filter(A=>A.length!==0).join(" ")})})(),v=(()=>w.length===1?w[0]:` | ||
`+w.map(g=>`{${g}}`).join(` | ||
`))(),le=`%c[${e.__state.sharedState.dbName}] `+[(d=r.current)!=null&&d.id?`[tr_id=${(T=r.current)==null?void 0:T.id.substring(0,6)}]`:"",v,(s==null?void 0:s.sendTime)!==void 0?`sendTime=${(s.sendTime/1e3).toFixed(4)}`:"",(s==null?void 0:s.receiveTime)!==void 0?`receiveTime=${(s.receiveTime/1e3).toFixed(4)}`:"",(s==null?void 0:s.blockTime)!==void 0?`blockTime=${(s.blockTime/1e3).toFixed(4)}`:"",`totalTime=${((l-p)/1e3).toFixed(4)}`].filter(g=>g.length!==0).join(" "),ue=(U=f.transactionsStates.byId[(B=($=r.current)==null?void 0:$.id)!=null?B:""])==null?void 0:U.i;o.logQuery(le,ue)}const n=(G=f.transactionsStates.byId[(z=(P=r.current)==null?void 0:P.id)!=null?z:""])==null?void 0:G.performance;return n&&(c.some(_=>_.performance.execTime!==void 0)&&(n.execTime===void 0&&(n.execTime=0),n.execTime+=c.reduce((_,w)=>{var v;return _+((v=w.performance.execTime)!=null?v:0)},0)),c.some(_=>_.performance.prepareTime!==void 0)&&(n.prepareTime===void 0&&(n.prepareTime=0),n.prepareTime+=c.reduce((_,w)=>{var v;return _+((v=w.performance.prepareTime)!=null?v:0)},0)),s.sendTime&&(n.sendTime||(n.sendTime=0),n.sendTime+=s.sendTime),s.receiveTime&&(n.receiveTime||(n.receiveTime=0),n.receiveTime+=s.receiveTime),s.blockTime&&(n.blockTime||(n.blockTime=0),n.blockTime+=s.blockTime)),{db:e,result:c,performance:s,queries:t}},E=async(e,t,a)=>{const r=[...e.__state.localState.queriesMiddlewares,X].reverse();let i=o=>Promise.resolve(o);for(const o of r){const f=i;i=p=>o({...p,next:f})}return await i({db:e,result:[],performance:{sendTime:void 0,receiveTime:void 0,totalTime:0},queries:t,transactionOpts:a})};let N=0;const L=(e,t,a)=>{const r=e.__state.sharedState.logFns;if(e.__state.localState.suppressLog)return;const i=[a.prepareTime===void 0?"":`prepareTime=${(a.prepareTime/1e3).toFixed(4)}`,a.execTime===void 0?"":`execTime=${(a.execTime/1e3).toFixed(4)}`,a.sendTime===void 0?"":`sendTime=${(a.sendTime/1e3).toFixed(4)}`,a.receiveTime===void 0?"":`receiveTime=${(a.receiveTime/1e3).toFixed(4)}`,a.blockTime===void 0?"":`blockTime=${(a.blockTime/1e3).toFixed(4)}`,`totalTime=${(a.totalTime/1e3).toFixed(4)}`].filter(o=>o.length!==0).join(" ");r.logTrFinish(`%c[${e.__state.sharedState.dbName}][tr_id=${t.slice(0,6)}] Transaction finished with ${i}`)},Z=async(e,t,a)=>{const{localState:{transactionState:r},sharedState:{eventsEmitter:i,transactionsStates:o,dbBackend:f,logFns:p}}=e.__state;if(f.isUsualTransactionDisabled)throw new Error("Usual transactions are disabled for this type of backend. Please, use atomic transactions instead.");if(r.current)return await a(e);J(e,()=>"transaction");const c={id:I(),type:"async"};e={...e,__state:{...e.__state,localState:{...e.__state.localState,transactionState:{current:c}}}};const s=y(),h={i:N++,current:c,performance:{prepareTime:0,execTime:0,freeTime:0,sendTime:0,receiveTime:0,totalTime:0,blockTime:0}};o.byId[c.id]=h;try{await i.emit("transactionWillStart",e,c),await E(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 l=await a(e);return await i.emit("transactionWillCommit",e,c),await E(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),l}catch(l){p.logError("Rollback transaction",l),await i.emit("transactionWillRollback",e,c);try{await E(e,{type:"usual",values:[S.sql`ROLLBACK`]},{transactionId:c.id,containsTransactionStart:!1,containsTransactionFinish:!1,containsTransactionRollback:!0,rollbackOnFail:!1,isAtomic:!1})}catch(n){p.logError("Rollback transaction failed",n)}throw await i.emit("transactionRollbacked",e,c),l}}finally{h.performance.totalTime=y()-s,L(e,c.id,h.performance),delete o.byId[c.id]}},j=()=>({__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)}}),O=async(e,t,a)=>{const{localState:{transactionState:r},sharedState:{eventsEmitter:i,transactionsStates:o,dbBackend:f,logFns:p}}=e.__state;if(r.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:s,afterRollbacks:h}=await(async()=>{if(Array.isArray(a))return{inputQueries:a,afterCommits:[],afterRollbacks:[]};{const T=j();return await a(T),{inputQueries:T.__state.queries,afterCommits:T.__state.afterCommits,afterRollbacks:T.__state.afterRollbacks}}})(),l={id:I(),type:"atomic"},n={i:N++,current:l,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:l}}}},o.byId[l.id]=n;const u=y(),d=[];f.isAtomicRollbackCommitDisabled||d.push(S.sql`BEGIN ${S.sql.raw(t.toUpperCase())} TRANSACTION`),d.push(...c.map(T=>T.toSql())),f.isAtomicRollbackCommitDisabled||d.push(S.sql`COMMIT`);try{await i.emit("transactionWillStart",e,l),await i.emit("transactionStarted",e,l),await E(e,{type:"usual",values:d},{transactionId:l.id,containsTransactionStart:!0,containsTransactionFinish:!0,containsTransactionRollback:!1,rollbackOnFail:!0,isAtomic:!0}),await i.emit("transactionWillCommit",e,l),await i.emit("transactionCommitted",e,l);try{for(const T of s)T()}catch(T){p.logError("Error in afterCommit callback",T)}}catch(T){p.logError("Rollback transaction",T),await i.emit("transactionWillRollback",e,l),await i.emit("transactionRollbacked",e,l);try{for(const $ of h)$()}catch($){p.logError("Error in afterRallback callback",$)}throw T}finally{n.performance.totalTime=y()-u,L(e,l.id,n.performance),delete o.byId[l.id]}},D=["yellow","cyan","magenta"],ee=async({dbName:e,plugins:t,queriesMiddlewares:a,dbBackend:r,suppressLog:i,logFns:o})=>{const f=o||{logQuery:(n,u)=>{const d=typeof u=="number"?D[u%D.length]:void 0;console.log(...d?[n,`color: ${d}; background-color: #202124; padding: 2px 4px; border-radius: 2px`]:[n,"padding: 0"])},logError:(n,u)=>{console.error(n,u)},logTrFinish:n=>{console.log(n,"color: #fff; background-color: #1da1f2; padding: 2px 4px; border-radius: 2px")}},p=R("running",{label:"runningState"}),c=(await r)({dbName:e}),s={__state:{sharedState:{clientId:I(),dbBackend:c,dbName:e,runningState:p,eventsEmitter:Y(),transactionsStates:{byId:{}},logFns:f},localState:{queriesMiddlewares:a||[],transactionState:{},suppressLog:Boolean(i)}},runInTransaction(n,u){return Z(this,(u==null?void 0:u.type)||"deferred",n)},async runInAtomicTransaction(n,u){return await O(this,(u==null?void 0:u.type)||"deferred",n)},async runQueries(n){return(await E(this,{type:"usual",values:n.map(d=>d.toSql())})).result.map(({rows:d})=>d)},async runQuery(n){return(await this.runQueries([n]))[0]},async runPreparedQuery(n,u){return(await E(this,{type:"prepared",query:n,preparedValues:u})).result.map(({rows:T})=>T)},runAfterTransactionCommitted(n){return q(this,(u,d,T)=>{u==="committed"&&n(d,T)})},runAfterTransactionRollbacked(n){q(s,(u,d,T)=>{u==="rollbacked"&&n(d,T)})}};let h=s;const l=()=>s.__state.sharedState.runningState.value;if(l()!=="running"||(await c.initialize(),l()!=="running"))return s;for(const n of t||[])h=n(h);return await s.__state.sharedState.eventsEmitter.emit("initialized",s),h},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()})},ae=(e,t)=>t({...e,__state:{...e.__state,localState:{...e.__state.localState,suppressLog:!0}}}),ie=e=>({...e,__state:{...e.__state,localState:{...e.__state.localState,suppressLog:!0}}}),M=e=>{const{current:t,queue:a}=e;return`Current running transaction job: ${JSON.stringify(t,null,2)}, queue of transaction jobs: ${JSON.stringify(a,null,2)}`},re=()=>R({queue:[],current:void 0},{label:"jobsState"}),ne=e=>({id:e}),V=async(e,t)=>{const{current:a,queue:r}=e.value;if(a||r.length>0){const i=e.waitTill(o=>{var f;return((f=o.current)==null?void 0:f.id)===t.id},{timeout:12e4});e.value={queue:[...r,t],current:a};try{await i}catch(o){throw e.value={...e.value,queue:e.value.queue.filter(f=>f.id!==t.id)},o instanceof k?new k(`Timeout error while trnsaction job acquire: '${o.message}'. Is it a dead lock? ${M(e.value)}, jobToAcquire: ${JSON.stringify(t,null,2)}`):o}}else e.value={queue:[],current:t}},W=(e,t)=>{const{current:a,queue:r}=e.value;if((a==null?void 0:a.id)!==t.id)throw new Error(`Can't release job that is not currently running, ${M(e.value)}, toRelease: ${JSON.stringify(t,null,2)}`);e.value={queue:r.slice(1),current:r[0]}},se=async e=>{try{return e.waitTill(({queue:t,current:a})=>t.length===0&&a===void 0,{timeout:12e4})}catch(t){throw t instanceof k?new k(`Timeout error while awaiting all jobs done: '${t.message}'. Is it a dead lock?`):t}},oe=async(e,t)=>{let a;if(t){const r=ne(t.transactionId);t.containsTransactionStart?await V(e,r):await e.waitTill(i=>{var o;return((o=i.current)==null?void 0:o.id)===r.id}),a=r}else await e.waitTill(r=>{var i;return((i=r.current)==null?void 0:i.id)===void 0});return a},ce=(e,t,a)=>{if(t&&(!a||(a==null?void 0:a.containsTransactionFinish)||(a==null?void 0:a.containsTransactionRollback))&&W(e,t),!t&&a)throw new Error("Transaction job was not started, nothing to release!")};m.StoppedError=x,m.TimeoutError=k,m.acquireJob=V,m.acquireWithTrJobOrWait=oe,m.getTime=y,m.initDbClient=ee,m.initJobsState=re,m.makeId=I,m.reactiveVar=R,m.releaseJob=W,m.releaseTrJobIfPossible=ce,m.stopDb=te,m.suppressLog=ae,m.whenAllJobsDone=se,m.withSuppressedLog=ie;for(const e in S)e!=="default"&&!m.hasOwnProperty(e)&&Object.defineProperty(m,e,{enumerable:!0,get:()=>S[e]});Object.defineProperties(m,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})}); | ||
(function(m,C){typeof exports=="object"&&typeof module<"u"?C(exports,require("fast-equals"),require("@kikko-land/boono-sql")):typeof define=="function"&&define.amd?define(["exports","fast-equals","@kikko-land/boono-sql"],C):(m=typeof globalThis<"u"?globalThis:m||self,C(m.core={},m.fastEquals,m.boonoSql))})(this,function(m,C,g){"use strict";const q=(e,t)=>{if(!e.__state.localState.transactionState.current)throw new Error("Not in transaction.");const a=e.__state.localState.transactionState.current,r=[],i=o=>(f,T)=>{if(a.id===T.id){t(o,f,a);for(const c of r)c()}};r.push(e.__state.sharedState.eventsEmitter.on("transactionCommitted",i("committed"))),r.push(e.__state.sharedState.eventsEmitter.on("transactionRollbacked",i("rollbacked")))};function Y(){const e={};return{async emit(t,...a){const r=e[t]||[];for(const i of r)await i(...a)},on(t,a){return(e[t]=e[t]||[]).push(a),()=>{const r=e[t]||[];e[t]=r.filter(i=>i!==a)}}}}class k extends Error{}class x extends Error{}const R=(e,t)=>{const a=t.deduplicate===void 0?!0:t.deduplicate;return{__state:{subscriptions:[],value:e,isStopped:!1,onStop:[]},get isStopped(){return this.__state.isStopped},set value(r){if(this.isStopped)throw new Error(`reactiveVar ${t.label} is stopped!`);if(!(a&&C.deepEqual(this.__state.value,r))){this.__state.value=r;for(const i of this.__state.subscriptions)i(r)}},get value(){if(this.isStopped)throw new Error(`reactiveVar ${t.label} is stopped!`);return this.__state.value},subscribe(r,i=!0){if(this.isStopped)throw new Error(`reactiveVar ${t.label} is stopped!`);let o;const f=T=>{o&&o(),o=r(T)};return this.__state.subscriptions.push(f),i&&f(this.__state.value),()=>{this.__state.subscriptions=this.__state.subscriptions.filter(T=>T!==f)}},waitTill(r,i){const o=new x(`waitUntil for reactiveVar ${t.label} is stopped due to stop signal`),f=new k(`waitUntil for reactiveVar ${t.label} is timed out`),T=new x(`waitUntil for reactiveVar ${t.label} is stopped due to reactive var stop`);if(this.isStopped)throw new Error(`reactiveVar ${t.label} is stopped!`);return new Promise((s,h)=>{var p;let u=[];const n=()=>{queueMicrotask(()=>{for(const l of u)l();u=[]})};if(u.push(((p=i==null?void 0:i.stopIf)==null?void 0:p.subscribe(l=>{!l||(n(),h(o))},!0))||(()=>{})),u.push(this.subscribe(l=>{!r(l)||(n(),s())},!0)),(i==null?void 0:i.timeout)===void 0||typeof(i==null?void 0:i.timeout)=="number"){const l=setTimeout(()=>{n(),h(f)},(i==null?void 0:i.timeout)===void 0?12e4:i.timeout);u.push(()=>{clearTimeout(l)})}const d=()=>{n(),h(T)};this.__state.onStop.push(d),u.push(()=>{this.__state.onStop=this.__state.onStop.filter(l=>l!==d)})})},stop(){if(this.isStopped)throw new Error(`reactiveVar ${t.label} is already stopped!`);this.__state.subscriptions=[];for(const r of this.__state.onStop)r();this.__state.onStop=[],this.__state.isStopped=!0}}},y=typeof performance<"u"?()=>performance.now():()=>Date.now(),J=(e,t)=>{const{__state:{sharedState:{runningState:a,dbName:r}}}=e;if(a.value!=="running")throw new Error(`Failed to start ${t()}, db ${r} is stopping`)};function I(){let e="";const t="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",a=t.length;for(let r=0;r<32;r++)e+=t.charAt(Math.floor(Math.random()*a));return e}const H=e=>e.filter(t=>t!==null),K=e=>e.reduce((t,a)=>t+a,0),Q=e=>K(H(e)),X=async({db:e,queries:t,transactionOpts:a})=>{var d,p,l,$,B,U,P,z,G;const{localState:{transactionState:r},sharedState:{dbBackend:i,logFns:o},sharedState:f}=e.__state;if(r.current||J(e,()=>JSON.stringify(t)),a&&((d=r.current)==null?void 0:d.id)!==a.transactionId)throw new Error(`Cannot run queries in a transaction that is not the current one. Transaction opts: ${JSON.stringify(a)}, local transaction: ${JSON.stringify(r)}`);const T=y(),{result:c,performance:s,textQueries:h}=await(async()=>{const _=a||(r.current?{transactionId:r.current.id,containsTransactionStart:!1,containsTransactionFinish:!1,containsTransactionRollback:!1,rollbackOnFail:!1,isAtomic:!1}:void 0);if(t.type==="prepared"){const w=t.query.toSql();if(w._values.length!==0)throw new Error("You can't use prepared var through ${} for runPreparedQuery. Please, manually specify variables with '?'.");const v=w.preparedQuery.text;return{...await i.execPreparedQuery(w.preparedQuery,t.preparedValues,_),textQueries:[v]}}else{const w=t.values.map(v=>v.preparedQuery);return{...await i.execQueries(w,_),textQueries:w.map(v=>v.text)}}})(),u=y();if(!e.__state.localState.suppressLog){const _=(S,F)=>`${S}=${(F/1e3).toFixed(4)}`,w=(()=>{if(t.type==="prepared"){const S=c[0],F=[S.performance.prepareTime!==void 0?_("prepareTime",Q(c.map(b=>b.performance.prepareTime))):"",S.performance.execTime!==void 0?_("execTime",Q(c.map(b=>b.performance.execTime))):""].filter(b=>b.length!==0).join(" ");return[[h[0].slice(0,1e3),`for ${t.preparedValues.length} values`,F].filter(b=>b.length!==0).join(" ")]}else return c.map(({performance:S},F)=>{const b=[S.prepareTime!==void 0?_("prepareTime",S.prepareTime):"",S.execTime!==void 0?_("execTime",S.execTime):""].filter(A=>A.length!==0).join(" ");return[h[F].slice(0,1e3),b].filter(A=>A.length!==0).join(" ")})})(),v=(()=>w.length===1?w[0]:` | ||
`+w.map(S=>`{${S}}`).join(` | ||
`))(),le=`%c[${e.__state.sharedState.dbName}] `+[(p=r.current)!=null&&p.id?`[tr_id=${(l=r.current)==null?void 0:l.id.substring(0,6)}]`:"",v,(s==null?void 0:s.sendTime)!==void 0?`sendTime=${(s.sendTime/1e3).toFixed(4)}`:"",(s==null?void 0:s.receiveTime)!==void 0?`receiveTime=${(s.receiveTime/1e3).toFixed(4)}`:"",(s==null?void 0:s.blockTime)!==void 0?`blockTime=${(s.blockTime/1e3).toFixed(4)}`:"",`totalTime=${((u-T)/1e3).toFixed(4)}`].filter(S=>S.length!==0).join(" "),ue=(U=f.transactionsStates.byId[(B=($=r.current)==null?void 0:$.id)!=null?B:""])==null?void 0:U.i;o.logQuery(le,ue)}const n=(G=f.transactionsStates.byId[(z=(P=r.current)==null?void 0:P.id)!=null?z:""])==null?void 0:G.performance;return n&&(c.some(_=>_.performance.execTime!==void 0)&&(n.execTime===void 0&&(n.execTime=0),n.execTime+=c.reduce((_,w)=>{var v;return _+((v=w.performance.execTime)!=null?v:0)},0)),c.some(_=>_.performance.prepareTime!==void 0)&&(n.prepareTime===void 0&&(n.prepareTime=0),n.prepareTime+=c.reduce((_,w)=>{var v;return _+((v=w.performance.prepareTime)!=null?v:0)},0)),s.sendTime&&(n.sendTime||(n.sendTime=0),n.sendTime+=s.sendTime),s.receiveTime&&(n.receiveTime||(n.receiveTime=0),n.receiveTime+=s.receiveTime),s.blockTime&&(n.blockTime||(n.blockTime=0),n.blockTime+=s.blockTime)),{db:e,result:c,performance:s,queries:t}},E=async(e,t,a)=>{const r=[...e.__state.localState.queriesMiddlewares,X].reverse();let i=o=>Promise.resolve(o);for(const o of r){const f=i;i=T=>o({...T,next:f})}return await i({db:e,result:[],performance:{sendTime:void 0,receiveTime:void 0,totalTime:0},queries:t,transactionOpts:a})};let N=0;const L=(e,t,a)=>{const r=e.__state.sharedState.logFns;if(e.__state.localState.suppressLog)return;const i=[a.prepareTime===void 0?"":`prepareTime=${(a.prepareTime/1e3).toFixed(4)}`,a.execTime===void 0?"":`execTime=${(a.execTime/1e3).toFixed(4)}`,a.sendTime===void 0?"":`sendTime=${(a.sendTime/1e3).toFixed(4)}`,a.receiveTime===void 0?"":`receiveTime=${(a.receiveTime/1e3).toFixed(4)}`,a.blockTime===void 0?"":`blockTime=${(a.blockTime/1e3).toFixed(4)}`,`totalTime=${(a.totalTime/1e3).toFixed(4)}`].filter(o=>o.length!==0).join(" ");r.logTrFinish(`%c[${e.__state.sharedState.dbName}][tr_id=${t.slice(0,6)}] Transaction finished with ${i}`)},Z=async(e,t,a)=>{const{localState:{transactionState:r},sharedState:{eventsEmitter:i,transactionsStates:o,dbBackend:f,logFns:T}}=e.__state;if(f.isUsualTransactionDisabled)throw new Error("Usual transactions are disabled for this type of backend. Please, use atomic transactions instead.");if(r.current)return await a(e);J(e,()=>"transaction");const c={id:I(),type:"async"};e={...e,__state:{...e.__state,localState:{...e.__state.localState,transactionState:{current:c}}}};const s=y(),h={i:N++,current:c,performance:{prepareTime:0,execTime:0,freeTime:0,sendTime:0,receiveTime:0,totalTime:0,blockTime:0}};o.byId[c.id]=h;try{await i.emit("transactionWillStart",e,c),await E(e,{type:"usual",values:[g.sql`BEGIN ${g.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 u=await a(e);return await i.emit("transactionWillCommit",e,c),await E(e,{type:"usual",values:[g.sql`COMMIT`]},{transactionId:c.id,containsTransactionStart:!1,containsTransactionFinish:!0,containsTransactionRollback:!1,rollbackOnFail:!1,isAtomic:!1}),await i.emit("transactionCommitted",e,c),u}catch(u){T.logError("Rollback transaction",u),await i.emit("transactionWillRollback",e,c);try{await E(e,{type:"usual",values:[g.sql`ROLLBACK`]},{transactionId:c.id,containsTransactionStart:!1,containsTransactionFinish:!1,containsTransactionRollback:!0,rollbackOnFail:!1,isAtomic:!1})}catch(n){T.logError("Rollback transaction failed",n)}throw await i.emit("transactionRollbacked",e,c),u}}finally{h.performance.totalTime=y()-s,L(e,c.id,h.performance),delete o.byId[c.id]}},j=()=>({__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)}}),O=async(e,t,a)=>{const{localState:{transactionState:r},sharedState:{eventsEmitter:i,transactionsStates:o,dbBackend:f,logFns:T}}=e.__state;if(r.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:s,afterRollbacks:h}=await(async()=>{if(Array.isArray(a))return{inputQueries:a,afterCommits:[],afterRollbacks:[]};{const l=j();return await a(l),{inputQueries:l.__state.queries,afterCommits:l.__state.afterCommits,afterRollbacks:l.__state.afterRollbacks}}})(),u={id:I(),type:"atomic"},n={i:N++,current:u,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:u}}}},o.byId[u.id]=n;const d=y(),p=[];f.isAtomicRollbackCommitDisabled||p.push(g.sql`BEGIN ${g.sql.raw(t.toUpperCase())} TRANSACTION`),p.push(...c.map(l=>l.toSql())),f.isAtomicRollbackCommitDisabled||p.push(g.sql`COMMIT`);try{await i.emit("transactionWillStart",e,u),await i.emit("transactionStarted",e,u),await E(e,{type:"usual",values:p},{transactionId:u.id,containsTransactionStart:!0,containsTransactionFinish:!0,containsTransactionRollback:!1,rollbackOnFail:!0,isAtomic:!0}),await i.emit("transactionWillCommit",e,u),await i.emit("transactionCommitted",e,u);try{for(const l of s)l()}catch(l){T.logError("Error in afterCommit callback",l)}}catch(l){T.logError("Rollback transaction",l),await i.emit("transactionWillRollback",e,u),await i.emit("transactionRollbacked",e,u);try{for(const $ of h)$()}catch($){T.logError("Error in afterRallback callback",$)}throw l}finally{n.performance.totalTime=y()-d,L(e,u.id,n.performance),delete o.byId[u.id]}},D=["yellow","cyan","magenta"],ee=async({dbName:e,plugins:t,queriesMiddlewares:a,dbBackend:r,suppressLog:i,logFns:o})=>{const f=o||{logQuery:(n,d)=>{const p=typeof d=="number"?D[d%D.length]:void 0;console.log(...p?[n,`color: ${p}; background-color: #202124; padding: 2px 4px; border-radius: 2px`]:[n,"padding: 0"])},logError:(n,d)=>{console.error(n,d)},logTrFinish:n=>{console.log(n,"color: #fff; background-color: #1da1f2; padding: 2px 4px; border-radius: 2px")}},T=R("running",{label:"runningState"}),c=(await r)({dbName:e}),s={__state:{sharedState:{clientId:I(),dbBackend:c,dbName:e,runningState:T,eventsEmitter:Y(),transactionsStates:{byId:{}},logFns:f},localState:{queriesMiddlewares:a||[],transactionState:{},suppressLog:Boolean(i)}},runInTransaction(n,d){return Z(this,(d==null?void 0:d.type)||"deferred",n)},async runInAtomicTransaction(n,d){return await O(this,(d==null?void 0:d.type)||"deferred",n)},async runQueries(n){return(await E(this,{type:"usual",values:n.map(p=>p.toSql())})).result.map(({rows:p})=>p)},async runQuery(n){return(await this.runQueries([n]))[0]},async runPreparedQuery(n,d){return(await E(this,{type:"prepared",query:n,preparedValues:d})).result.map(({rows:l})=>l)},runAfterTransactionCommitted(n){return q(this,(d,p,l)=>{d==="committed"&&n(p,l)})},runAfterTransactionRollbacked(n){q(s,(d,p,l)=>{d==="rollbacked"&&n(p,l)})}};let h=s;const u=()=>s.__state.sharedState.runningState.value;if(u()!=="running"||(await c.initialize(),u()!=="running"))return s;for(const n of t||[])h=n(h);return await s.__state.sharedState.eventsEmitter.emit("initialized",s),h},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()})},ae=(e,t)=>t({...e,__state:{...e.__state,localState:{...e.__state.localState,suppressLog:!0}}}),ie=e=>({...e,__state:{...e.__state,localState:{...e.__state.localState,suppressLog:!0}}}),M=e=>{const{current:t,queue:a}=e;return`Current running transaction job: ${JSON.stringify(t,null,2)}, queue of transaction jobs: ${JSON.stringify(a,null,2)}`},re=()=>R({queue:[],current:void 0},{label:"jobsState"}),ne=e=>({id:e}),V=async(e,t)=>{const{current:a,queue:r}=e.value;if(a||r.length>0){const i=e.waitTill(o=>{var f;return((f=o.current)==null?void 0:f.id)===t.id},{timeout:12e4});e.value={queue:[...r,t],current:a};try{await i}catch(o){throw e.value={...e.value,queue:e.value.queue.filter(f=>f.id!==t.id)},o instanceof k?new k(`Timeout error while trnsaction job acquire: '${o.message}'. Is it a dead lock? ${M(e.value)}, jobToAcquire: ${JSON.stringify(t,null,2)}`):o}}else e.value={queue:[],current:t}},W=(e,t)=>{const{current:a,queue:r}=e.value;if((a==null?void 0:a.id)!==t.id)throw new Error(`Can't release job that is not currently running, ${M(e.value)}, toRelease: ${JSON.stringify(t,null,2)}`);e.value={queue:r.slice(1),current:r[0]}},se=async e=>{try{return e.waitTill(({queue:t,current:a})=>t.length===0&&a===void 0,{timeout:12e4})}catch(t){throw t instanceof k?new k(`Timeout error while awaiting all jobs done: '${t.message}'. Is it a dead lock?`):t}},oe=async(e,t)=>{let a;if(t){const r=ne(t.transactionId);t.containsTransactionStart?await V(e,r):await e.waitTill(i=>{var o;return((o=i.current)==null?void 0:o.id)===r.id}),a=r}else await e.waitTill(r=>{var i;return((i=r.current)==null?void 0:i.id)===void 0});return a},ce=(e,t,a)=>{if(t&&(!a||(a==null?void 0:a.containsTransactionFinish)||(a==null?void 0:a.containsTransactionRollback))&&W(e,t),!t&&a)throw new Error("Transaction job was not started, nothing to release!")};m.StoppedError=x,m.TimeoutError=k,m.acquireJob=V,m.acquireWithTrJobOrWait=oe,m.getTime=y,m.initDbClient=ee,m.initJobsState=re,m.makeId=I,m.reactiveVar=R,m.releaseJob=W,m.releaseTrJobIfPossible=ce,m.stopDb=te,m.suppressLog=ae,m.whenAllJobsDone=se,m.withSuppressedLog=ie;for(const e in g)e!=="default"&&!m.hasOwnProperty(e)&&Object.defineProperty(m,e,{enumerable:!0,get:()=>g[e]});Object.defineProperties(m,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})}); | ||
//# sourceMappingURL=index.umd.js.map |
{ | ||
"name": "@kikko-land/kikko", | ||
"version": "0.12.0", | ||
"version": "0.13.0", | ||
"author": "Sergey Popov", | ||
@@ -5,0 +5,0 @@ "license": "MIT", |
@@ -113,8 +113,15 @@ import { deepEqual } from "fast-equals"; | ||
const toWait = new Promise<void>((resolve, reject) => { | ||
const unsubscriptions: (() => void)[] = []; | ||
let unsubscriptions: (() => void)[] = []; | ||
const unsubAll = () => { | ||
for (const unsub of unsubscriptions) { | ||
unsub(); | ||
} | ||
// We need to wait till all unsubscriptions will appear in array. | ||
// We can have case when subsctibe() emitted needed values, | ||
// but all other unsubscribes are not pushed | ||
queueMicrotask(() => { | ||
for (const unsub of unsubscriptions) { | ||
unsub(); | ||
} | ||
unsubscriptions = []; | ||
}); | ||
}; | ||
@@ -160,6 +167,14 @@ | ||
this.__state.onStop.push(() => { | ||
const onStopHandler = () => { | ||
unsubAll(); | ||
reject(stoppedError); | ||
}; | ||
this.__state.onStop.push(onStopHandler); | ||
unsubscriptions.push(() => { | ||
this.__state.onStop = this.__state.onStop.filter((s) => { | ||
return s !== onStopHandler; | ||
}); | ||
}); | ||
@@ -180,2 +195,4 @@ }); | ||
this.__state.onStop = []; | ||
this.__state.isStopped = true; | ||
@@ -182,0 +199,0 @@ }, |
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
203428
2450