@instantdb/core
Version:
Instant's core local abstraction
8,459 lines • 237 kB
JavaScript
function G(n) {
const e = We(n);
let t = 3735928559 ^ e.length, r = 1103547991 ^ e.length;
for (let s = 0; s < e.length; s++) {
const i = e.charCodeAt(s);
t = Math.imul(t ^ i, 2654435761), r = Math.imul(r ^ i, 1597334677);
}
return t = Math.imul(t ^ t >>> 16, 2246822507) ^ Math.imul(r ^ r >>> 13, 3266489909), r = Math.imul(r ^ r >>> 16, 2246822507) ^ Math.imul(t ^ t >>> 13, 3266489909), `${(r >>> 0).toString(16).padStart(8, "0")}${(t >>> 0).toString(16).padStart(8, "0")}`;
}
function We(n) {
if (n && typeof n.toJSON == "function")
return We(n.toJSON());
if (Array.isArray(n)) {
let e = "[";
for (let t = 0; t < n.length; t++)
t > 0 && (e += ","), e += We(n[t]);
return e + "]";
}
if (n && typeof n == "object") {
const e = Object.keys(n);
e.sort();
let t = "{", r = !0;
for (let s = 0; s < e.length; s++) {
const i = e[s], o = n[i];
o !== void 0 && (r || (t += ","), t += JSON.stringify(i) + ":" + We(o), r = !1);
}
return t + "}";
}
return n === void 0 ? "undefined" : typeof n == "bigint" ? `${n}n` : JSON.stringify(n) ?? String(n);
}
function Se(n) {
if (typeof n == "number")
return (Math.abs(n * 2654435761) >>> 0).toString(16);
if (typeof n == "boolean") return n ? "1" : "0";
if (n === null) return "null";
if (n === void 0) return "undefined";
if (typeof n == "string") {
let e = 2166136261;
for (let t = 0; t < n.length; t++)
e ^= n.charCodeAt(t), e += (e << 1) + (e << 4) + (e << 7) + (e << 8) + (e << 24), e = e >>> 0;
return e.toString(16);
}
if (Array.isArray(n)) {
let e = 2166136261;
for (let t = 0; t < n.length; t++) {
e ^= (t + 1) * 2654435761;
const r = Se(n[t]);
for (let s = 0; s < r.length; s++)
e ^= r.charCodeAt(s), e *= 16777619, e = e >>> 0;
}
return e.toString(16);
}
if (typeof n == "object") {
let e = 2166136261;
const t = Object.keys(n).sort();
for (let r = 0; r < t.length; r++) {
const s = t[r];
if (n[s] === void 0)
continue;
const i = Se(s);
e ^= parseInt(i, 16), e *= 16777619, e = e >>> 0;
const o = Se(n[s]);
e ^= parseInt(o, 16), e *= 16777619, e = e >>> 0;
}
return e.toString(16);
}
return Se(String(n));
}
const x = {
Remove: "remove",
Replace: "replace",
Add: "add"
}, In = /* @__PURE__ */ Symbol.for("__MUTATIVE_PROXY_DRAFT__"), _r = /* @__PURE__ */ Symbol("__MUTATIVE_RAW_RETURN_SYMBOL__"), Ve = Symbol.iterator, ee = {
mutable: "mutable",
immutable: "immutable"
}, Pt = {};
function $e(n, e) {
return n instanceof Map ? n.has(e) : Object.prototype.hasOwnProperty.call(n, e);
}
function Wt(n, e) {
if (e in n) {
let t = Reflect.getPrototypeOf(n);
for (; t; ) {
const r = Reflect.getOwnPropertyDescriptor(t, e);
if (r)
return r;
t = Reflect.getPrototypeOf(t);
}
}
}
function jt(n) {
return Object.getPrototypeOf(n) === Set.prototype;
}
function $t(n) {
return Object.getPrototypeOf(n) === Map.prototype;
}
function X(n) {
var e;
return (e = n.copy) !== null && e !== void 0 ? e : n.original;
}
function ye(n) {
return !!I(n);
}
function I(n) {
return typeof n != "object" ? null : n?.[In];
}
function xt(n) {
var e;
const t = I(n);
return t ? (e = t.copy) !== null && e !== void 0 ? e : t.original : n;
}
function ie(n, e) {
if (!n || typeof n != "object")
return !1;
let t;
return Object.getPrototypeOf(n) === Object.prototype || Array.isArray(n) || n instanceof Map || n instanceof Set || !!e?.mark && ((t = e.mark(n, ee)) === ee.immutable || typeof t == "function");
}
function Cn(n, e = []) {
if (Object.hasOwnProperty.call(n, "key")) {
const t = n.parent.copy, r = I(de(t, n.key));
if (r !== null && r?.original !== n.original)
return null;
const s = n.parent.type === 3, i = s ? Array.from(n.parent.setMap.keys()).indexOf(n.key) : n.key;
if (!(s && t.size > i || $e(t, i)))
return null;
e.push(i);
}
if (n.parent)
return Cn(n.parent, e);
e.reverse();
try {
Sr(n.copy, e);
} catch {
return null;
}
return e;
}
function be(n) {
return Array.isArray(n) ? 1 : n instanceof Map ? 2 : n instanceof Set ? 3 : 0;
}
function de(n, e) {
return be(n) === 2 ? n.get(e) : n[e];
}
function De(n, e, t) {
be(n) === 2 ? n.set(e, t) : n[e] = t;
}
function it(n, e) {
const t = I(n);
return (t ? X(t) : n)[e];
}
function le(n, e) {
return n === e ? n !== 0 || 1 / n === 1 / e : n !== n && e !== e;
}
function ht(n) {
if (n)
for (; n.finalities.revoke.length > 0; )
n.finalities.revoke.pop()();
}
function pe(n, e) {
return e ? n : [""].concat(n).map((t) => {
const r = `${t}`;
return r.indexOf("/") === -1 && r.indexOf("~") === -1 ? r : r.replace(/~/g, "~0").replace(/\//g, "~1");
}).join("/");
}
function Sr(n, e) {
for (let t = 0; t < e.length - 1; t += 1) {
const r = e[t];
if (n = de(be(n) === 3 ? Array.from(n) : n, r), typeof n != "object")
throw new Error(`Cannot resolve patch at '${e.join("/")}'.`);
}
return n;
}
function Tr(n) {
const e = Object.create(Object.getPrototypeOf(n));
return Reflect.ownKeys(n).forEach((t) => {
let r = Reflect.getOwnPropertyDescriptor(n, t);
if (r.enumerable && r.configurable && r.writable) {
e[t] = n[t];
return;
}
r.writable || (r.writable = !0, r.configurable = !0), (r.get || r.set) && (r = {
configurable: !0,
writable: !0,
enumerable: r.enumerable,
value: n[t]
}), Reflect.defineProperty(e, t, r);
}), e;
}
const vr = Object.prototype.propertyIsEnumerable;
function En(n, e) {
let t;
if (Array.isArray(n))
return Array.prototype.concat.call(n);
if (n instanceof Set) {
if (!jt(n)) {
const r = Object.getPrototypeOf(n).constructor;
return new r(n.values());
}
return Set.prototype.difference ? Set.prototype.difference.call(n, /* @__PURE__ */ new Set()) : new Set(n.values());
} else if (n instanceof Map) {
if (!$t(n)) {
const r = Object.getPrototypeOf(n).constructor;
return new r(n);
}
return new Map(n);
} else if (e?.mark && (t = e.mark(n, ee), t !== void 0) && t !== ee.mutable) {
if (t === ee.immutable)
return Tr(n);
if (typeof t == "function") {
if (e.enablePatches || e.enableAutoFreeze)
throw new Error("You can't use mark and patches or auto freeze together.");
return t();
}
throw new Error(`Unsupported mark result: ${t}`);
} else if (typeof n == "object" && Object.getPrototypeOf(n) === Object.prototype) {
const r = {};
return Object.keys(n).forEach((s) => {
r[s] = n[s];
}), Object.getOwnPropertySymbols(n).forEach((s) => {
vr.call(n, s) && (r[s] = n[s]);
}), r;
} else
throw new Error("Please check mark() to ensure that it is a stable marker draftable function.");
}
function W(n) {
n.copy || (n.copy = En(n.original, n.options));
}
function Ee(n) {
if (!ie(n))
return xt(n);
if (Array.isArray(n))
return n.map(Ee);
if (n instanceof Map) {
const t = Array.from(n.entries()).map(([r, s]) => [
r,
Ee(s)
]);
if (!$t(n)) {
const r = Object.getPrototypeOf(n).constructor;
return new r(t);
}
return new Map(t);
}
if (n instanceof Set) {
const t = Array.from(n).map(Ee);
if (!jt(n)) {
const r = Object.getPrototypeOf(n).constructor;
return new r(t);
}
return new Set(t);
}
const e = Object.create(Object.getPrototypeOf(n));
for (const t in n)
e[t] = Ee(n[t]);
return e;
}
function Qe(n) {
return ye(n) ? Ee(n) : n;
}
function ce(n) {
var e;
n.assignedMap = (e = n.assignedMap) !== null && e !== void 0 ? e : /* @__PURE__ */ new Map(), n.operated || (n.operated = !0, n.parent && ce(n.parent));
}
function Vt() {
throw new Error("Cannot modify frozen object");
}
function _e(n, e, t, r, s) {
{
t = t ?? /* @__PURE__ */ new WeakMap(), r = r ?? [], s = s ?? [];
const o = t.has(n) ? t.get(n) : n;
if (r.length > 0) {
const a = r.indexOf(o);
if (o && typeof o == "object" && a !== -1)
throw r[0] === o ? new Error("Forbids circular reference") : new Error(`Forbids circular reference: ~/${s.slice(0, a).map((c, u) => {
if (typeof c == "symbol")
return `[${c.toString()}]`;
const l = r[u];
return typeof c == "object" && (l instanceof Map || l instanceof Set) ? Array.from(l.keys()).indexOf(c) : c;
}).join("/")}`);
r.push(o), s.push(e);
} else
r.push(o);
}
if (Object.isFrozen(n) || ye(n)) {
r.pop(), s.pop();
return;
}
switch (be(n)) {
case 2:
for (const [a, c] of n)
_e(a, a, t, r, s), _e(c, a, t, r, s);
n.set = n.clear = n.delete = Vt;
break;
case 3:
for (const a of n)
_e(a, a, t, r, s);
n.add = n.clear = n.delete = Vt;
break;
case 1:
Object.freeze(n);
let o = 0;
for (const a of n)
_e(a, o, t, r, s), o += 1;
break;
default:
Object.freeze(n), Object.keys(n).forEach((a) => {
const c = n[a];
_e(c, a, t, r, s);
});
}
r.pop(), s.pop();
}
function Rt(n, e) {
const t = be(n);
if (t === 0)
Reflect.ownKeys(n).forEach((r) => {
e(r, n[r], n);
});
else if (t === 1) {
let r = 0;
for (const s of n)
e(r, s, n), r += 1;
} else
n.forEach((r, s) => e(s, r, n));
}
function Mn(n, e, t) {
if (ye(n) || !ie(n, t) || e.has(n) || Object.isFrozen(n))
return;
const r = n instanceof Set, s = r ? /* @__PURE__ */ new Map() : void 0;
if (e.add(n), Rt(n, (i, o) => {
var a;
if (ye(o)) {
const c = I(o);
W(c);
const u = !((a = c.assignedMap) === null || a === void 0) && a.size || c.operated ? c.copy : c.original;
De(r ? s : n, i, u);
} else
Mn(o, e, t);
}), s) {
const i = n, o = Array.from(i);
i.clear(), o.forEach((a) => {
i.add(s.has(a) ? s.get(a) : a);
});
}
}
function Ar(n, e) {
const t = n.type === 3 ? n.setMap : n.copy;
n.finalities.revoke.length > 1 && n.assignedMap.get(e) && t && Mn(de(t, e), n.finalities.handledSet, n.options);
}
function pt(n) {
n.type === 3 && n.copy && (n.copy.clear(), n.setMap.forEach((e) => {
n.copy.add(xt(e));
}));
}
function yt(n, e, t, r) {
if (n.operated && n.assignedMap && n.assignedMap.size > 0 && !n.finalized) {
if (t && r) {
const i = Cn(n);
i && e(n, i, t, r);
}
n.finalized = !0;
}
}
function Dt(n, e, t, r) {
const s = I(t);
s && (s.callbacks || (s.callbacks = []), s.callbacks.push((i, o) => {
var a;
const c = n.type === 3 ? n.setMap : n.copy;
if (le(de(c, e), t)) {
let u = s.original;
s.copy && (u = s.copy), pt(n), yt(n, r, i, o), n.options.enableAutoFreeze && (n.options.updatedValues = (a = n.options.updatedValues) !== null && a !== void 0 ? a : /* @__PURE__ */ new WeakMap(), n.options.updatedValues.set(u, s.original)), De(c, e, u);
}
}), n.options.enableAutoFreeze && s.finalities !== n.finalities && (n.options.enableAutoFreeze = !1)), ie(t, n.options) && n.finalities.draft.push(() => {
const i = n.type === 3 ? n.setMap : n.copy;
le(de(i, e), t) && Ar(n, e);
});
}
function kr(n, e, t, r, s) {
let { original: i, assignedMap: o, options: a } = n, c = n.copy;
c.length < i.length && ([i, c] = [c, i], [t, r] = [r, t]);
for (let u = 0; u < i.length; u += 1)
if (o.get(u.toString()) && c[u] !== i[u]) {
const l = e.concat([u]), f = pe(l, s);
t.push({
op: x.Replace,
path: f,
// If it is a draft, it needs to be deep cloned, and it may also be non-draft.
value: Qe(c[u])
}), r.push({
op: x.Replace,
path: f,
// If it is a draft, it needs to be deep cloned, and it may also be non-draft.
value: Qe(i[u])
});
}
for (let u = i.length; u < c.length; u += 1) {
const l = e.concat([u]), f = pe(l, s);
t.push({
op: x.Add,
path: f,
// If it is a draft, it needs to be deep cloned, and it may also be non-draft.
value: Qe(c[u])
});
}
if (i.length < c.length) {
const { arrayLengthAssignment: u = !0 } = a.enablePatches;
if (u) {
const l = e.concat(["length"]), f = pe(l, s);
r.push({
op: x.Replace,
path: f,
value: i.length
});
} else
for (let l = c.length; i.length < l; l -= 1) {
const f = e.concat([l - 1]), d = pe(f, s);
r.push({
op: x.Remove,
path: d
});
}
}
}
function Or({ original: n, copy: e, assignedMap: t }, r, s, i, o) {
t.forEach((a, c) => {
const u = de(n, c), l = Qe(de(e, c)), f = a ? $e(n, c) ? x.Replace : x.Add : x.Remove;
if (le(u, l) && f === x.Replace)
return;
const d = r.concat(c), h = pe(d, o);
s.push(f === x.Remove ? { op: f, path: h } : { op: f, path: h, value: l }), i.push(f === x.Add ? { op: x.Remove, path: h } : f === x.Remove ? { op: x.Add, path: h, value: u } : { op: x.Replace, path: h, value: u });
});
}
function Ir({ original: n, copy: e }, t, r, s, i) {
let o = 0;
n.forEach((a) => {
if (!e.has(a)) {
const c = t.concat([o]), u = pe(c, i);
r.push({
op: x.Remove,
path: u,
value: a
}), s.unshift({
op: x.Add,
path: u,
value: a
});
}
o += 1;
}), o = 0, e.forEach((a) => {
if (!n.has(a)) {
const c = t.concat([o]), u = pe(c, i);
r.push({
op: x.Add,
path: u,
value: a
}), s.unshift({
op: x.Remove,
path: u,
value: a
});
}
o += 1;
});
}
function Re(n, e, t, r) {
const { pathAsArray: s = !0 } = n.options.enablePatches;
switch (n.type) {
case 0:
case 2:
return Or(n, e, t, r, s);
case 1:
return kr(n, e, t, r, s);
case 3:
return Ir(n, e, t, r, s);
}
}
const He = (n, e, t = !1) => {
if (typeof n == "object" && n !== null && (!ie(n, e) || t))
throw new Error("Strict mode: Mutable data cannot be accessed directly, please use 'unsafe(callback)' wrap.");
}, bt = {
get size() {
return X(I(this)).size;
},
has(n) {
return X(I(this)).has(n);
},
set(n, e) {
const t = I(this), r = X(t);
return (!r.has(n) || !le(r.get(n), e)) && (W(t), ce(t), t.assignedMap.set(n, !0), t.copy.set(n, e), Dt(t, n, e, Re)), this;
},
delete(n) {
if (!this.has(n))
return !1;
const e = I(this);
return W(e), ce(e), e.original.has(n) ? e.assignedMap.set(n, !1) : e.assignedMap.delete(n), e.copy.delete(n), !0;
},
clear() {
const n = I(this);
if (this.size) {
W(n), ce(n), n.assignedMap = /* @__PURE__ */ new Map();
for (const [e] of n.original)
n.assignedMap.set(e, !1);
n.copy.clear();
}
},
forEach(n, e) {
const t = I(this);
X(t).forEach((r, s) => {
n.call(e, this.get(s), s, this);
});
},
get(n) {
var e, t;
const r = I(this), s = X(r).get(n), i = ((t = (e = r.options).mark) === null || t === void 0 ? void 0 : t.call(e, s, ee)) === ee.mutable;
if (r.options.strict && He(s, r.options, i), i || r.finalized || !ie(s, r.options) || s !== r.original.get(n))
return s;
const o = Pt.createDraft({
original: s,
parentDraft: r,
key: n,
finalities: r.finalities,
options: r.options
});
return W(r), r.copy.set(n, o), o;
},
keys() {
return X(I(this)).keys();
},
values() {
const n = this.keys();
return {
[Ve]: () => this.values(),
next: () => {
const e = n.next();
return e.done ? e : {
done: !1,
value: this.get(e.value)
};
}
};
},
entries() {
const n = this.keys();
return {
[Ve]: () => this.entries(),
next: () => {
const e = n.next();
if (e.done)
return e;
const t = this.get(e.value);
return {
done: !1,
value: [e.value, t]
};
}
};
},
[Ve]() {
return this.entries();
}
}, Cr = Reflect.ownKeys(bt), Qt = (n, e, { isValuesIterator: t }) => () => {
var r, s;
const i = e.next();
if (i.done)
return i;
const o = i.value;
let a = n.setMap.get(o);
const c = I(a), u = ((s = (r = n.options).mark) === null || s === void 0 ? void 0 : s.call(r, a, ee)) === ee.mutable;
if (n.options.strict && He(o, n.options, u), !u && !c && ie(o, n.options) && !n.finalized && n.original.has(o)) {
const l = Pt.createDraft({
original: o,
parentDraft: n,
key: o,
finalities: n.finalities,
options: n.options
});
n.setMap.set(o, l), a = l;
} else c && (a = c.proxy);
return {
done: !1,
value: t ? a : [a, a]
};
}, Je = {
get size() {
return I(this).setMap.size;
},
has(n) {
const e = I(this);
if (e.setMap.has(n))
return !0;
W(e);
const t = I(n);
return !!(t && e.setMap.has(t.original));
},
add(n) {
const e = I(this);
return this.has(n) || (W(e), ce(e), e.assignedMap.set(n, !0), e.setMap.set(n, n), Dt(e, n, n, Re)), this;
},
delete(n) {
if (!this.has(n))
return !1;
const e = I(this);
W(e), ce(e);
const t = I(n);
return t && e.setMap.has(t.original) ? (e.assignedMap.set(t.original, !1), e.setMap.delete(t.original)) : (!t && e.setMap.has(n) ? e.assignedMap.set(n, !1) : e.assignedMap.delete(n), e.setMap.delete(n));
},
clear() {
if (!this.size)
return;
const n = I(this);
W(n), ce(n);
for (const e of n.original)
n.assignedMap.set(e, !1);
n.setMap.clear();
},
values() {
const n = I(this);
W(n);
const e = n.setMap.keys();
return {
[Symbol.iterator]: () => this.values(),
next: Qt(n, e, { isValuesIterator: !0 })
};
},
entries() {
const n = I(this);
W(n);
const e = n.setMap.keys();
return {
[Symbol.iterator]: () => this.entries(),
next: Qt(n, e, {
isValuesIterator: !1
})
};
},
keys() {
return this.values();
},
[Ve]() {
return this.values();
},
forEach(n, e) {
const t = this.values();
let r = t.next();
for (; !r.done; )
n.call(e, r.value, r.value, this), r = t.next();
}
};
Set.prototype.difference && Object.assign(Je, {
intersection(n) {
return Set.prototype.intersection.call(new Set(this.values()), n);
},
union(n) {
return Set.prototype.union.call(new Set(this.values()), n);
},
difference(n) {
return Set.prototype.difference.call(new Set(this.values()), n);
},
symmetricDifference(n) {
return Set.prototype.symmetricDifference.call(new Set(this.values()), n);
},
isSubsetOf(n) {
return Set.prototype.isSubsetOf.call(new Set(this.values()), n);
},
isSupersetOf(n) {
return Set.prototype.isSupersetOf.call(new Set(this.values()), n);
},
isDisjointFrom(n) {
return Set.prototype.isDisjointFrom.call(new Set(this.values()), n);
}
});
const Er = Reflect.ownKeys(Je), Pn = /* @__PURE__ */ new WeakSet(), jn = {
get(n, e, t) {
var r, s;
const i = (r = n.copy) === null || r === void 0 ? void 0 : r[e];
if (i && Pn.has(i))
return i;
if (e === In)
return n;
let o;
if (n.options.mark) {
const u = e === "size" && (n.original instanceof Map || n.original instanceof Set) ? Reflect.get(n.original, e) : Reflect.get(n.original, e, t);
if (o = n.options.mark(u, ee), o === ee.mutable)
return n.options.strict && He(u, n.options, !0), u;
}
const a = X(n);
if (a instanceof Map && Cr.includes(e)) {
if (e === "size")
return Object.getOwnPropertyDescriptor(bt, "size").get.call(n.proxy);
const u = bt[e];
if (u)
return u.bind(n.proxy);
}
if (a instanceof Set && Er.includes(e)) {
if (e === "size")
return Object.getOwnPropertyDescriptor(Je, "size").get.call(n.proxy);
const u = Je[e];
if (u)
return u.bind(n.proxy);
}
if (!$e(a, e)) {
const u = Wt(a, e);
return u ? "value" in u ? u.value : (
// !case: support for getter
(s = u.get) === null || s === void 0 ? void 0 : s.call(n.proxy)
) : void 0;
}
const c = a[e];
if (n.options.strict && He(c, n.options), n.finalized || !ie(c, n.options))
return c;
if (c === it(n.original, e)) {
if (W(n), n.copy[e] = Ut({
original: n.original[e],
parentDraft: n,
key: n.type === 1 ? Number(e) : e,
finalities: n.finalities,
options: n.options
}), typeof o == "function") {
const u = I(n.copy[e]);
return W(u), ce(u), u.copy;
}
return n.copy[e];
}
return c;
},
set(n, e, t) {
var r;
if (n.type === 3 || n.type === 2)
throw new Error("Map/Set draft does not support any property assignment.");
let s;
if (n.type === 1 && e !== "length" && !(Number.isInteger(s = Number(e)) && s >= 0 && (e === 0 || s === 0 || String(s) === String(e))))
throw new Error("Only supports setting array indices and the 'length' property.");
const i = Wt(X(n), e);
if (i?.set)
return i.set.call(n.proxy, t), !0;
const o = it(X(n), e), a = I(o);
return a && le(a.original, t) ? (n.copy[e] = t, n.assignedMap = (r = n.assignedMap) !== null && r !== void 0 ? r : /* @__PURE__ */ new Map(), n.assignedMap.set(e, !1), !0) : (le(t, o) && (t !== void 0 || $e(n.original, e)) || (W(n), ce(n), $e(n.original, e) && le(t, n.original[e]) ? n.assignedMap.delete(e) : n.assignedMap.set(e, !0), n.copy[e] = t, Dt(n, e, t, Re)), !0);
},
has(n, e) {
return e in X(n);
},
ownKeys(n) {
return Reflect.ownKeys(X(n));
},
getOwnPropertyDescriptor(n, e) {
const t = X(n), r = Reflect.getOwnPropertyDescriptor(t, e);
return r && {
writable: !0,
configurable: n.type !== 1 || e !== "length",
enumerable: r.enumerable,
value: t[e]
};
},
getPrototypeOf(n) {
return Reflect.getPrototypeOf(n.original);
},
setPrototypeOf() {
throw new Error("Cannot call 'setPrototypeOf()' on drafts");
},
defineProperty() {
throw new Error("Cannot call 'defineProperty()' on drafts");
},
deleteProperty(n, e) {
var t;
return n.type === 1 ? jn.set.call(this, n, e, void 0, n.proxy) : (it(n.original, e) !== void 0 || e in n.original ? (W(n), ce(n), n.assignedMap.set(e, !1)) : (n.assignedMap = (t = n.assignedMap) !== null && t !== void 0 ? t : /* @__PURE__ */ new Map(), n.assignedMap.delete(e)), n.copy && delete n.copy[e], !0);
}
};
function Ut(n) {
const { original: e, parentDraft: t, key: r, finalities: s, options: i } = n, o = be(e), a = {
type: o,
finalized: !1,
parent: t,
original: e,
copy: null,
proxy: null,
finalities: s,
options: i,
// Mapping of draft Set items to their corresponding draft values.
setMap: o === 3 ? new Map(e.entries()) : void 0
};
(r || "key" in n) && (a.key = r);
const { proxy: c, revoke: u } = Proxy.revocable(o === 1 ? Object.assign([], a) : a, jn);
if (s.revoke.push(u), Pn.add(c), a.proxy = c, t) {
const l = t;
l.finalities.draft.push((f, d) => {
var h, p;
const m = I(c);
let b = l.type === 3 ? l.setMap : l.copy;
const y = de(b, r), g = I(y);
if (g) {
let A = g.original;
g.operated && (A = xt(y)), pt(g), yt(g, Re, f, d), l.options.enableAutoFreeze && (l.options.updatedValues = (h = l.options.updatedValues) !== null && h !== void 0 ? h : /* @__PURE__ */ new WeakMap(), l.options.updatedValues.set(A, g.original)), De(b, r, A);
}
(p = m.callbacks) === null || p === void 0 || p.forEach((A) => {
A(f, d);
});
});
} else {
const l = I(c);
l.finalities.draft.push((f, d) => {
pt(l), yt(l, Re, f, d);
});
}
return c;
}
Pt.createDraft = Ut;
function Mr(n, e, t, r, s) {
var i;
const o = I(n), a = (i = o?.original) !== null && i !== void 0 ? i : n, c = !!e.length;
if (o?.operated)
for (; o.finalities.draft.length > 0; )
o.finalities.draft.pop()(t, r);
const u = c ? e[0] : o ? o.operated ? o.copy : o.original : n;
return o && ht(o), s && _e(u, u, o?.options.updatedValues), [
u,
t && c ? [{ op: x.Replace, path: [], value: e[0] }] : t,
r && c ? [{ op: x.Replace, path: [], value: a }] : r
];
}
function Pr(n, e) {
var t;
const r = {
draft: [],
revoke: [],
handledSet: /* @__PURE__ */ new WeakSet()
};
let s, i;
e.enablePatches && (s = [], i = []);
const a = ((t = e.mark) === null || t === void 0 ? void 0 : t.call(e, n, ee)) === ee.mutable || !ie(n, e) ? n : Ut({
original: n,
parentDraft: null,
finalities: r,
options: e
});
return [
a,
(c = []) => {
const [u, l, f] = Mr(a, c, s, i, e.enableAutoFreeze);
return e.enablePatches ? [u, l, f] : u;
}
];
}
function gt(n) {
const { rootDraft: e, value: t, useRawReturn: r = !1, isRoot: s = !0 } = n;
Rt(t, (i, o, a) => {
const c = I(o);
if (c && e && c.finalities === e.finalities) {
n.isContainDraft = !0;
const u = c.original;
if (a instanceof Set) {
const l = Array.from(a);
a.clear(), l.forEach((f) => a.add(i === f ? u : f));
} else
De(a, i, u);
} else typeof o == "object" && o !== null && (n.value = o, n.isRoot = !1, gt(n));
}), s && (n.isContainDraft || console.warn("The return value does not contain any draft, please use 'rawReturn()' to wrap the return value to improve performance."), r && console.warn("The return value contains drafts, please don't use 'rawReturn()' to wrap the return value."));
}
function $n(n) {
var e;
const t = I(n);
if (!ie(n, t?.options))
return n;
const r = be(n);
if (t && !t.operated)
return t.original;
let s;
function i() {
s = r === 2 ? $t(n) ? new Map(n) : new (Object.getPrototypeOf(n)).constructor(n) : r === 3 ? Array.from(t.setMap.values()) : En(n, t?.options);
}
if (t) {
t.finalized = !0;
try {
i();
} finally {
t.finalized = !1;
}
} else
s = n;
if (Rt(s, (o, a) => {
if (t && le(de(t.original, o), a))
return;
const c = $n(a);
c !== a && (s === n && i(), De(s, o, c));
}), r === 3) {
const o = (e = t?.original) !== null && e !== void 0 ? e : s;
return jt(o) ? new Set(s) : new (Object.getPrototypeOf(o)).constructor(s);
}
return s;
}
function Bt(n) {
if (!ye(n))
throw new Error(`current() is only used for Draft, parameter: ${n}`);
return $n(n);
}
const jr = (n) => function e(t, r, s) {
var i, o, a;
if (typeof t == "function" && typeof r != "function")
return function(k, ...N) {
return e(k, (C) => t.call(this, C, ...N), r);
};
const c = t, u = r;
let l = s;
if (typeof r != "function" && (l = r), l !== void 0 && Object.prototype.toString.call(l) !== "[object Object]")
throw new Error(`Invalid options: ${l}, 'options' should be an object.`);
l = Object.assign(Object.assign({}, n), l);
const f = ye(c) ? Bt(c) : c, d = Array.isArray(l.mark) ? ((k, N) => {
for (const C of l.mark) {
if (typeof C != "function")
throw new Error(`Invalid mark: ${C}, 'mark' should be a function.`);
const O = C(k, N);
if (O)
return O;
}
}) : l.mark, h = (i = l.enablePatches) !== null && i !== void 0 ? i : !1, p = (o = l.strict) !== null && o !== void 0 ? o : !1, b = {
enableAutoFreeze: (a = l.enableAutoFreeze) !== null && a !== void 0 ? a : !1,
mark: d,
strict: p,
enablePatches: h
};
if (!ie(f, b) && typeof f == "object" && f !== null)
throw new Error("Invalid base state: create() only supports plain objects, arrays, Set, Map or using mark() to mark the state as immutable.");
const [y, g] = Pr(f, b);
if (typeof r != "function") {
if (!ie(f, b))
throw new Error("Invalid base state: create() only supports plain objects, arrays, Set, Map or using mark() to mark the state as immutable.");
return [y, g];
}
let A;
try {
A = u(y);
} catch (k) {
throw ht(I(y)), k;
}
const R = (k) => {
const N = I(y);
if (!ye(k)) {
if (k !== void 0 && !le(k, y) && N?.operated)
throw new Error("Either the value is returned as a new non-draft value, or only the draft is modified without returning any value.");
const O = k?.[_r];
if (O) {
const q = O[0];
return b.strict && typeof k == "object" && k !== null && gt({
rootDraft: N,
value: k,
useRawReturn: !0
}), g([q]);
}
if (k !== void 0)
return typeof k == "object" && k !== null && gt({ rootDraft: N, value: k }), g([k]);
}
if (k === y || k === void 0)
return g([]);
const C = I(k);
if (b === C.options) {
if (C.operated)
throw new Error("Cannot return a modified child draft.");
return g([Bt(k)]);
}
return g([k]);
};
return A instanceof Promise ? A.then(R, (k) => {
throw ht(I(y)), k;
}) : R(A);
}, Ye = jr();
Object.prototype.constructor.toString();
function xn(n, e) {
const t = Object.keys(n), r = Object.keys(e);
return t.length === r.length && Object.keys(n).every((s) => e.hasOwnProperty(s));
}
function Gt(n, e) {
return Object.keys(n).length === Object.keys(e).length && Object.keys(n).every(
(t) => e.hasOwnProperty(t) && n[t] === e[t]
);
}
function Be(n, e) {
return typeof n != "object" || typeof e != "object" || n === null || e === null ? n === e : xn(n, e) ? Object.keys(n).every(
(t) => Be(n[t], e[t])
) : !1;
}
function Lt(n) {
if (!Me(n))
return n;
const e = {};
for (const [t, r] of Object.entries(n))
r !== void 0 && (e[t] = r);
return e;
}
function Rn(n, e) {
if (!Me(n) || !Me(e))
return e;
const t = { ...n };
for (const r of Object.keys(e)) {
if (e[r] === void 0) continue;
if (e[r] === null) {
delete t[r];
continue;
}
const s = Me(n[r]) && Me(e[r]);
t[r] = s ? Rn(n[r], e[r]) : e[r];
}
return t;
}
function Me(n) {
return typeof n == "object" && n !== null && !Array.isArray(n);
}
function $r(n, e, t) {
if (!n || e.length === 0)
return;
let r = n || {};
for (let i = 0; i < e.length - 1; i++) {
const o = e[i];
(!(o in r) || typeof r[o] != "object") && (r[o] = typeof e[i + 1] == "number" ? [] : {}), r = r[o];
}
const s = e[e.length - 1];
Array.isArray(r) && typeof s == "number" ? r.splice(s, 0, t) : r[s] = t;
}
function Ht(n, e, t) {
if (!n || e.length === 0)
return;
let r = n || {};
for (let s = 0; s < e.length - 1; s++) {
const i = e[s];
(!(i in r) || typeof r[i] != "object") && (r[i] = typeof e[s + 1] == "number" ? [] : {}), r = r[i];
}
r[e[e.length - 1]] = t;
}
function Dn(n, e) {
if (!n || e.length === 0)
return;
const [t, ...r] = e;
if (t in n) {
if (r.length === 0) {
Array.isArray(n) ? n.splice(t, 1) : delete n[t];
return;
}
Dn(n[t], r), xr(n[t]) && delete n[t];
}
}
function xr(n) {
return n && Object.keys(n).length === 0;
}
const Jt = /ZULU|YEKT|YEKST|YAPT|YAKT|YAKST|XJT|WGT|WGST|WFT|WETDST|WET|WDT|WAT|WAST|WAKT|WADT|VUT|VOLT|VLAT|VLAST|VET|UZT|UZST|UYT|UYST|UTC|UT|ULAT|ULAST|UCT|TVT|TRUT|TOT|TMT|TKT|TJT|TFT|TAHT|SGT|SCT|SAST|SADT|RET|PYT|PYST|PWT|PST|PONT|PMST|PMDT|PKT|PKST|PHT|PGT|PETT|PETST|PET|PDT|OMST|OMSST|NZT|NZST|NZDT|NUT|NST|NPT|NOVT|NOVST|NFT|NDT|MYT|MVT|MUT|MUST|MST|MSK|MSD|MPT|MMT|MHT|MEZ|METDST|MET|MESZ|MEST|MDT|MAWT|MART|MAGT|MAGST|LKT|LINT|LIGT|LHST|LHDT|KST|KRAT|KRAST|KOST|KGT|KGST|KDT|JST|JAYT|IST|IRT|IRKT|IRKST|IOT|IDT|ICT|HST|HKT|GYT|GMT|GILT|GFT|GET|GEST|GAMT|GALT|FNT|FNST|FKT|FKST|FJT|FJST|FET|EST|EGT|EGST|EETDST|EET|EEST|EDT|EAT|EAST|EASST|DDUT|DAVT|CXT|CST|COT|CLT|CLST|CKT|CHUT|CHAST|CHADT|CETDST|CET|CEST|CDT|CCT|CAST|CADT|BTT|BST|BRT|BRST|BRA|BOT|BORT|BNT|BDT|BDST|AZT|AZST|AZOT|AZOST|AWST|AWSST|AST|ART|ARST|ANAT|ANAST|AMT|AMST|ALMT|ALMST|AKST|AKDT|AFT|AEST|AESST|AEDT|ADT|ACWST|ACT|ACST|ACSST|ACDT$/, Rr = {
ZULU: 0,
YEKT: 18e3,
YEKST: 21600,
YAPT: 36e3,
YAKT: 32400,
YAKST: 32400,
XJT: 21600,
WGT: -10800,
WGST: -7200,
WFT: 43200,
WETDST: 3600,
WET: 0,
WDT: 32400,
WAT: 3600,
WAST: 25200,
WAKT: 43200,
WADT: 28800,
VUT: 39600,
VOLT: 10800,
VLAT: 36e3,
VLAST: 36e3,
VET: -14400,
UZT: 18e3,
UZST: 21600,
UYT: -10800,
UYST: -7200,
UTC: 0,
UT: 0,
ULAT: 28800,
ULAST: 32400,
UCT: 0,
TVT: 43200,
TRUT: 36e3,
TOT: 46800,
TMT: 18e3,
TKT: 46800,
TJT: 18e3,
TFT: 18e3,
TAHT: -36e3,
SGT: 28800,
SCT: 14400,
SAST: 7200,
SADT: 37800,
RET: 14400,
PYT: -14400,
PYST: -10800,
PWT: 32400,
PST: -28800,
PONT: 39600,
PMST: -10800,
PMDT: -7200,
PKT: 18e3,
PKST: 21600,
PHT: 28800,
PGT: 36e3,
PETT: 43200,
PETST: 43200,
PET: -18e3,
PDT: -25200,
OMST: 21600,
OMSST: 21600,
NZT: 43200,
NZST: 43200,
NZDT: 46800,
NUT: -39600,
NST: -12600,
NPT: 20700,
NOVT: 25200,
NOVST: 25200,
NFT: -12600,
NDT: -9e3,
MYT: 28800,
MVT: 18e3,
MUT: 14400,
MUST: 18e3,
MST: -25200,
MSK: 10800,
MSD: 14400,
MPT: 36e3,
MMT: 23400,
MHT: 43200,
MEZ: 3600,
METDST: 7200,
MET: 3600,
MESZ: 7200,
MEST: 7200,
MDT: -21600,
MAWT: 18e3,
MART: -34200,
MAGT: 39600,
MAGST: 39600,
LKT: 19800,
LINT: 50400,
LIGT: 36e3,
LHST: 37800,
LHDT: 37800,
KST: 32400,
KRAT: 25200,
KRAST: 25200,
KOST: 39600,
KGT: 21600,
KGST: 21600,
KDT: 36e3,
JST: 32400,
JAYT: 32400,
IST: 7200,
IRT: 12600,
IRKT: 28800,
IRKST: 28800,
IOT: 21600,
IDT: 10800,
ICT: 25200,
HST: -36e3,
HKT: 28800,
GYT: -14400,
GMT: 0,
GILT: 43200,
GFT: -10800,
GET: 14400,
GEST: 14400,
GAMT: -32400,
GALT: -21600,
FNT: -7200,
FNST: -3600,
FKT: -10800,
FKST: -10800,
FJT: 43200,
FJST: 46800,
FET: 10800,
EST: -18e3,
EGT: -3600,
EGST: 0,
EETDST: 10800,
EET: 7200,
EEST: 10800,
EDT: -14400,
EAT: 10800,
EAST: -21600,
EASST: -21600,
DDUT: 36e3,
DAVT: 25200,
CXT: 25200,
CST: -21600,
COT: -18e3,
CLT: -14400,
CLST: -10800,
CKT: -36e3,
CHUT: 36e3,
CHAST: 45900,
CHADT: 49500,
CETDST: 7200,
CET: 3600,
CEST: 7200,
CDT: -18e3,
CCT: 28800,
CAST: 34200,
CADT: 37800,
BTT: 21600,
BST: 3600,
BRT: -10800,
BRST: -7200,
BRA: -10800,
BOT: -14400,
BORT: 28800,
BNT: 28800,
BDT: 21600,
BDST: 7200,
AZT: 14400,
AZST: 14400,
AZOT: -3600,
AZOST: 0,
AWST: 28800,
AWSST: 32400,
AST: -14400,
ART: -10800,
ARST: -10800,
ANAT: 43200,
ANAST: 43200,
AMT: -14400,
AMST: 14400,
ALMT: 21600,
ALMST: 25200,
AKST: -32400,
AKDT: -28800,
AFT: 16200,
AEST: 36e3,
AESST: 39600,
AEDT: 39600,
ADT: -10800,
ACWST: 31500,
ACT: -18e3,
ACST: 34200,
ACSST: 37800,
ACDT: 37800
};
function Dr(n) {
return new Date(n);
}
function Ur(n) {
return /* @__PURE__ */ new Date(n + "Z");
}
const Lr = /^(\d+)[\./-](\d+)[\./-](\d+)$/;
function Nr(n) {
const e = n.match(Lr);
if (!e)
return null;
const [t, r, s, i] = e;
return r <= 0 || s <= 0 || i <= 0 ? null : r > 999 ? new Date(Date.UTC(r, s - 1, i, 0, 0, 0, 0)) : new Date(Date.UTC(i, r - 1, s, 0, 0, 0, 0));
}
function Fr(n) {
const [e, t] = n.split(" ");
return /* @__PURE__ */ new Date(e + "T" + t + "Z");
}
function Kr(n) {
const [e, t] = n.split(" ");
return /* @__PURE__ */ new Date(e + "T" + t + "Z");
}
function qr(n) {
return new Date(n);
}
function zr(n) {
const e = /^(\w{3}) (\w{3}) (\d{2}) (\d{4})$/;
if (!n.match(e))
throw new Error(`Unable to parse \`${n}\` as a date.`);
const r = /* @__PURE__ */ new Date(n + " UTC");
return new Date(
Date.UTC(
r.getUTCFullYear(),
r.getUTCMonth(),
r.getUTCDate(),
0,
0,
0,
0
)
);
}
function Wr(n) {
const e = /^(.+T.+)([+-])(\d{2})$/, t = n.match(e);
if (t) {
const [, r, s, i] = t, o = `${r}${s}${i}:00`;
return new Date(o);
}
return null;
}
function Vr(n) {
const e = /^(\d+)-(\d{1,2})-(\d{1,2})([ T])(\d{1,2})(?::(\d{1,2}))?(?::(\d{1,2}))?(.*)$/, t = n.match(e);
if (t) {
const [, r, s, i, o, a, c, u, l] = t, f = s.padStart(2, "0"), d = i.padStart(2, "0");
let h = a.padStart(2, "0");
c !== void 0 && (h += `:${c.padStart(2, "0")}`), u !== void 0 && (h += `:${u.padStart(2, "0")}`);
const p = `${r}-${f}-${d}T${h}${l}`;
return new Date(p);
}
return null;
}
function Qr(n) {
const [e, t] = n.split(", "), [r, s, i] = e.split("/").map(Number), o = t.match(/(\d{1,2}):(\d{2}):(\d{2}) (AM|PM)/);
if (!o)
throw new Error(`Unable to parse time from: ${n}`);
let [, a, c, u, l] = o;
return a = Number(a), c = Number(c), u = Number(u), l === "PM" && a !== 12 ? a += 12 : l === "AM" && a === 12 && (a = 0), new Date(Date.UTC(i, r - 1, s, a, c, u));
}
function Br(n) {
switch (n) {
case "epoch":
return /* @__PURE__ */ new Date(0);
// These are not implemented yet because we need some way for the
// client and server to aggree on the values
case "infinity":
case "-infinity":
case "today":
case "tomorrow":
case "yesterday":
return null;
}
}
function Gr(n) {
const e = n.match(Jt);
if (!e)
return null;
const [t] = e, r = Rr[t], s = new Date(n.replace(Jt, "Z"));
return new Date(s.getTime() - r * 1e3);
}
const Hr = [
Nr,
Kr,
zr,
Qr,
Ur,
Wr,
Fr,
Dr,
Br,
Gr,
Vr,
qr
];
function Jr(n, e) {
try {
const t = n(e);
return t instanceof Date && !isNaN(t.getTime()) ? t : null;
} catch {
return null;
}
}
function mt(n) {
for (const e of Hr) {
const t = Jr(e, n);
if (t)
return t;
}
return null;
}
function Yr(n) {
try {
const e = JSON.parse(n);
return typeof e == "string" ? mt(e) : null;
} catch {
return null;
}
}
function et(n) {
if (n !== void 0) {
if (n === null)
return null;
if (n instanceof Date)
return n;
if (typeof n == "string") {
const e = mt(n) || Yr(n) || mt(n.trim());
if (!e)
throw new Error(`Unable to parse \`${n}\` as a date.`);
return e;
} else if (typeof n == "number")
return new Date(n);
throw new Error(
`Invalid date value \`${n}\`. Expected a date, number, or string, got type ${typeof n}.`
);
}
}
class fe {
attrs;
linkIndex;
_blobAttrs = null;
_primaryKeys = null;
_forwardIdents = null;
_revIdents = null;
constructor(e, t) {
this.attrs = e, this.linkIndex = t;
}
resetAttrIndexes() {
this._blobAttrs = null, this._primaryKeys = null, this._forwardIdents = null, this._revIdents = null;
}
addAttr(e) {
this.attrs[e.id] = e, this.resetAttrIndexes();
}
deleteAttr(e) {
delete this.attrs[e], this.resetAttrIndexes();
}
updateAttr(e) {
const t = this.attrs[e.id];
t && (this.attrs[e.id] = { ...t, ...e }, this.resetAttrIndexes());
}
getAttr(e) {
return this.attrs[e];
}
get blobAttrs() {
if (this._blobAttrs)
return this._blobAttrs;
this._blobAttrs = /* @__PURE__ */ new Map();
for (const e of Object.values(this.attrs))
if (Ft(e)) {
const [t, r, s] = e["forward-identity"];
H(this.blobAttrs, [r, s], e);
}
return this._blobAttrs;
}
get primaryKeys() {
if (this._primaryKeys)
return this._primaryKeys;
this._primaryKeys = /* @__PURE__ */ new Map();
for (const e of Object.values(this.attrs))
if (e["primary?"]) {
const [t, r] = e["forward-identity"];
H(this._primaryKeys, [r], e);
}
return this._primaryKeys;
}
get forwardIdents() {
if (this._forwardIdents)
return this._forwardIdents;
this._forwardIdents = /* @__PURE__ */ new Map();
for (const e of Object.values(this.attrs)) {
const t = e["forward-identity"], [r, s, i] = t;
H(this._forwardIdents, [s, i], e);
}
return this._forwardIdents;
}
get revIdents() {
if (this._revIdents)
return this._revIdents;
this._revIdents = /* @__PURE__ */ new Map();
for (const e of Object.values(this.attrs)) {
const t = e["reverse-identity"];
if (t) {
const [r, s, i] = t;
H(this._revIdents, [s, i], e);
}
}
return this._revIdents;
}
toJSON() {
return { attrs: this.attrs, linkIndex: this.linkIndex };
}
}
function Zr(n) {
return n.cardinality === "one";
}
function Nt(n) {
return n["value-type"] === "ref";
}
function Ft(n) {
return n["value-type"] === "blob";
}
function Ie(n, e) {
return e.reduce((t, r) => t && t.get(r), n);
}
function se(n, e) {
if (e.length === 0) throw new Error("path must have at least one element");
if (e.length === 1) {
n.delete(e[0]);
return;
}
const [t, ...r] = e;
n.has(t) && se(n.get(t), r);
}
function H(n, e, t) {
let r = n;
const s = e.length - 1;
for (let i = 0; i < s; i++) {
const o = e[i];
let a = r.get(o);
a === void 0 && (a = /* @__PURE__ */ new Map(), r.set(o, a)), r = a;
}
s > -1 && r.set(e[s], t);
}
function Un(n, e, t) {
const r = /* @__PURE__ */ new Map(), s = /* @__PURE__ */ new Map(), i = /* @__PURE__ */ new Map();
for (const o of e) {
let [a, c, u] = o;
const l = n.getAttr(c);
if (!l) {
console.warn("no such attr", c, a);
continue;
}
l["checked-data-type"] === "date" && t && (u = et(u), o[2] = u), Nt(l) && H(i, [u, c, a], o), H(r, [a, c, u], o), H(s, [c, a, u], o);
}
return { eav: r, aev: s, vae: i };
}
function Ln(n) {
return {
triples: J(n.eav, 3),
cardinalityInference: n.cardinalityInference,
useDateObjects: n.useDateObjects,
version: 1
};
}
function Nn(n, e) {
return Te(
n,
e.triples,
e.cardinalityInference,
e.useDateObjects
);
}
function Fn(n, e) {
if (n)
return new fe(n.attrs, n.linkIndex);
if (e && "__type" in e)
return new fe(e.attrs, e.linkIndex);
}
function Xr(n, e) {
return Ie(n.eav, [e]) !== void 0;
}
function Te(n, e, t, r) {
const s = Un(
n,
e,
r
);
return s.cardinalityInference = t, s.useDateObjects = r, s;
}
function Ue(n, e) {
let t;
if (Array.isArray(e[0])) {
const [s, i] = e[0], o = n.aev.get(s);
if (!o)
return null;
t = J(o, 2).find((c) => c[2] === i)?.[0];
} else
t = e[0];
if (!t)
return null;
const r = e[2];
if (Array.isArray(r) && r.length === 2 && n.aev.get(r[0])) {
const [s, i] = r, o = n.aev.get(s);
if (!o)
return null;
const c = J(o, 2).find((h) => h[2] === i)?.[0];
if (!c)
return null;
const [u, l, f, ...d] = e;
return [t, l, c, ...d];
} else {
const [s, ...i] = e;
return [t, ...i];
}
}
function Kn(n, e, t) {
const r = Ue(n, t);
if (!r)
return;
const [s, i, o] = r, a = e.getAttr(i);
a && (se(n.eav, [s, i, o]), se(n.aev, [i, s, o]), Nt(a) && se(n.vae, [o, i, s]));
}
let es = 0;
function qn(n, e, t) {
const [r, s, i] = t;
let o;
const a = Ie(n.eav, [r, s, i]);
return a && (o = a[3]), o || Date.now() * 10 + es++;
}
function zn(n, e, t) {
const r = Ue(n, t);
if (!r)
return;
let [s, i, o] = r;
const a = e.getAttr(i);
if (!a)
return;
a["checked-data-type"] === "date" && n.useDateObjects && (o = et(o));
const u = Ie(n.eav, [s, i, o])?.[3] ?? qn(n, a, r), l = [s, i, o, u];
Zr(a) ? (H(n.eav, [s, i], /* @__PURE__ */ new Map([[o, l]])), H(n.aev, [i, s], /* @__PURE__ */ new Map([[o, l]]))) : (H(n.eav, [s, i, o], l), H(n.aev, [i, s, o], l)), Nt(a) && H(n.vae, [o, i, s], l);
}
function ts(n, e, t) {
const r = Ue(n, t);
if (!r)
return;
const [s, i, o] = r, a = e.getAttr(i);
if (!a) return;
if (!Ft(a))
throw new Error("merge operation is not supported for links");
const c = Ie(n.eav, [s, i]);
if (!c) return;
const u = c.values().next()?.value;
if (!u) return;
const l = u[2], f = Rn(l, o), d = [
s,
i,
f,
qn(n, a, u)
];
H(n.eav, [s, i], /* @__PURE__ */ new Map([[f, d]])), H(n.aev, [i, s], /* @__PURE__ */ new Map([[f, d]]));
}
function wt(n, e, t) {
const [r, s] = t, i = Ue(n, [r]);
if (!i)
return;
const [o] = i, a = n.eav.get(o);
if (a) {
for (const u of a.keys()) {
const l = e.getAttr(u);
l && l["on-delete-reverse"] === "cascade" && J(a.get(u), 1).forEach(
([f, d, h]) => wt(n, e, [h, l["reverse-identity"]?.[1]])
), // Fall back to deleting everything if we've rehydrated tx-steps from
// the store that didn't set `etype` in deleteEntity
(!s || // If we don't know about the attr, let's just get rid of it
!l || // Make sure it matches the etype
l["forward-identity"]?.[1] === s) && (se(n.aev, [u, o]), se(n.eav, [o, u]));
}
a.size === 0 && se(n.eav, [o]);
}
const c = n.vae.get(o) && J(n.vae.get(o), 2);
c && c.forEach((u) => {
const [l, f, d] = u, h = e.getAttr(f);
(!s || !h || h["reverse-identity"]?.[1] === s) && (se(n.eav, [l, f, d]), se(n.aev, [f, l, d]), se(n.vae, [d, f, l])), h && h["on-delete"] === "cascade" && h["reverse-identity"]?.[1] === s && wt(n, e, [l, h["forward-identity"]?.[1]]);
}), n.vae.get(o)?.size === 0 && se(n.vae, [o]);
}
function Wn(n, e, t) {
const r = Un(
e,
t,
n.useDateObjects
);
Object.keys(r).forEach((s) => {
n[s] = r[s];
});
}
function ns(n, [e]) {
n.addAttr(e);
}
function Vn(n) {
return J(n.eav, 3);
}
function rs(n, e, [t]) {
if (!e.getAttr(t)) return;
const r = Vn(n).filter(([s, i]) => i !== t);
e.deleteAttr(t), Wn(n, e, r);
}
function ss(n, e, [t]) {
e.getAttr(t.id) && (e.updateAttr(t), Wn(n, e, Vn(n)));
}
function is(n, e, t) {
const [r, ...s] = t;
switch (r) {
case "add-triple":
zn(n, e, s);
break;
case "deep-merge-triple":
ts(n, e, s);
break;
case "retract-triple":
Kn(n, e, s);
break;
case "delete-entity":
wt(n, e, s);
break;
case "add-attr":
ns(e, s);
break;
case "delete-attr":
rs(n, e, s);
break;
case "update-attr":
ss(n, e, s);
break;
case "restore-attr":
break;
case "rule-params":
break;
default:
throw new Error(`unhandled transaction action: ${r}`);
}
}
function J(n, e, t = []) {
if (!n || e === 0)
return t;
if (e === 1) {
for (const r of n.values())
t.push(r);
return t;
}
for (const r of n.values())
J(r, e - 1, t);
return t;
}
function Ne(n, e, t) {
const r = [];
if (t?.hasOwnProperty("$not")) {
for (const i of e.keys())
t.$not !== i && r.push(e.get(i));
return r;
}
if (t?.hasOwnProperty("$isNull")) {
const { attrId: i, isNull: o, reverse: a } = t.$isNull;
if (a)
for (const c of e.keys()) {
const u = n.vae.get(c), l = !u || !u.get(i);
(o ? l : !l) && r.push(e.get(c));
}
else {
const c = n.aev.get(i);
for (const u of e.keys()) {
const l = !c || c.get(u)?.get(null) || !c.get(u);
(o ? l : !l) && r.push(e.get(u));
}
}
return r;
}
if (t?.$comparator)
return J(e, 1).filter(t.$op);
const s = t.in || t.$in || [t];
for (const i of s) {
const o = e.get(i);
o && r.push(o);
}
return r;
}
function os(n, e, t) {
let r = "";
return n !== void 0 && (r += "e"), e !== void 0 && (r += "a"), t !== void 0 && (r += "v"), r;
}
function as(n, [e, t, r]) {
switch (os(e, t, r)) {
case "e": {
const i = n.eav.get(e);
return J(i, 2);
}
case "ea": {
const i = n.eav.get(e)?.get(t);
return J(i, 1);
}
case "eav": {
const i = n.eav.get(e)?.get(t);
return i ? Ne(n, i, r) : [];
}
case "ev": {
const i = n.eav.get(e);
if (!i)
return [];
const o = [];
for (const a of i.values())
o.push(...Ne(n, a, r));
return o;
}
case "a": {
const i = n.aev.get(t);
return J(i, 2);
}
case "av": {
const i = n.aev.get(t);
if (!i)
return [];
const o = [];
for (const a of i.values())
o.push(...Ne(n, a, r));
return o;
}
case "v": {
const i = [];
for (const o of n.eav.values())
for (const a of o.values())
i.push(...Ne(n, a, r));
return i;
}
default:
return J(n.eav, 3);
}
}
function cs(n, e, t) {
const r = {};
if (!e)
return r;
for (const [s, i] of e.entries()) {
const o = n.eav.get(t)?.get(i.id), a = J(o, 1);
for (const c of a)
r[s] = c[2];
}
return r;
}
function U(n, e, t) {
return n.forwardIdents.get(e)?.get(t);
}
function ge(n, e, t) {
return n.revIdents.get(e)?.get(t);
}
function us(n, e) {
return n.blobAttrs.get(e);
}
function Qn(n, e) {
const t = n.primaryKeys.get(e);
return t || n.forwardIdents.get(e)?.get("id");
}
function ls(n, e, t) {
const r = Ue(n, t);
if (!r)
return;
const [s, i, o] = r;
if (e.getAttr(i))
return Ie(n.eav, [s, i]);
}
function ds(n, e, t) {
const r = t.filter(
([s, i, o, a, c]) => {
if (s !== "add-triple" && s !== "deep-merge-triple")
return !0;
const u = c?.mode;
if (u !== "create" && u !== "update")
return !0;
let l = !1;
const f = e.getAttr(o);
if (f) {
const d = Qn(
e,
f["forward-identity"][1]
);
l = !!ls(n, e, [
i,
d?.id,
i
]);
}
return !(u === "create" && l || u === "update" && !l);
}
);
return Ye(
{ store: n, attrsStore: e },
(s) => {
r.forEach((i) => {
is(s.store, s.attrsStore, i);
});
},
{
mark: (s) => {
if (s instanceof fe)
return "immutable";
}
}
);
}
function fs(n) {
return typeof n == "string" && n.startsWith("?");
}
function hs(n, e, t) {
if (t.hasOwnProperty(n)) {
const r = t[n];
return Bn(r, e, t);
}
return { ...t, [n]: e };
}
function Yt(n, e, t) {
return n === e ? t : null;
}
function ps(n) {
return typeof n === "string" && n.startsWith("?") ? hs : Yt;
}
const ys = [
"in",
"$in",
"$not",
"$isNull",
"$comparator"
// covers all of $gt, $lt, etc.
];
function bs(n) {
for (const e of ys)
if (n.hasOwnProperty(e))
return !0;
return !1;
}
function Bn(n, e, t) {
return t ? typeof n == "object" ? bs(n) ? t : null : ps(n)(n, e, t) : null;
}
function gs(n, e, t) {
return n.reduce((r, s, i) => {
const o = e[i];
return Bn(s, o, r);
}, t);
}
function ms(n, e, t) {
return Ss(n, e, t).map((r) => gs(e, r, t)).filter((r) => r);
}
function ws(n, e, t) {
return e.or ? e.or.patterns.flatMap((r) => _t(n, r, t)) : e.and ? e.and.patterns.reduce((r, s) => _t(n, s, r), t) : t.flatMap((r) => ms(n, e, r));
}
function _t(n, e, t = [{}]) {
return e.reduce((r, s) => ws(n, s, r), t);
}
function Kt(n, e) {
return Array.isArray(e) ? e.map((t) => Kt(n, t)) : fs(e) ? n[e] : e;
}
function _s(n, { find: e, where: t }) {
return _t(n, t).map((s) => Kt(s, e));
}
function Ss(n, e, t) {
return as(n, Kt(t, e));
}
const Ts = /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$/i;
function ke(n) {
return typeof n == "string" && Ts.test(n);
}
const K = [];
for (let n = 0; n < 256; ++n)
K.push((n + 256).toString(16).slice(1));
function vs(n, e = 0) {
return (K[n[e + 0]] + K[n[e + 1]] + K[n[e + 2]] + K[n[e + 3]] + "-" + K[n[e + 4]] + K[n[e + 5]] + "-" + K[n[e + 6]] + K[n[e + 7]] + "-" + K[n[e + 8]] + K[n[e + 9]] + "-" + K[n[e + 10]] + K[n[e + 11]] + K[n[e + 12]] + K[n[e + 13]] + K[n[e + 14]] + K[n[e + 15]]).toLowerCase();
}
let ot;
const As = new Uint8Array(16);
function ks() {
if (!ot) {
if (typeof crypto > "u" || !crypto.getRandomValues)
throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");
ot = crypto.getRandomValues.bind(crypto);
}
return ot(As);
}
const Os = typeof crypto < "u" && crypto.randomUUID && crypto.randomUUID.bind(crypto), Zt = { randomUUID: Os };
function Is(n, e, t) {
if (Zt.randomUUID && !n)
return Zt.randomUUID();
n = n || {};
const r = n.random ?? n.rng?.() ?? ks();
if (r.length < 16)
throw new Error("Random bytes length must be >= 16");
return r[6] = r[6] & 15 | 64, r[8] = r[8] & 63 | 128, vs(r);
}
function Xt(n) {
const e = n.replace(/-/g, ""), t = [];
for (let r = 0; r < e.length; r += 2)
t.push(parseInt(e.substring(r, r + 2), 16));
return t;
}
function Cs(n, e) {
for (let t = 0; t < n.length; t++) {
if (n[t] < e[t]) return -1;
if (n[t] > e[t]) return 1;
}
return 0;
}
function Es(n, e) {
return Cs(Xt(n), Xt(e));
}
function j() {
return Is();
}
function Ms(n, e) {
return n.localeCompare(e);
}
function Ps() {
let n = Ms;
if (typeof Intl == "object" && Intl.hasOwnProperty("Collator"))
try {
n = Intl.Collator("en-US").compare;
} catch {
}
return n;
}
const js = Ps();
let Gn = !0;
const Sa = (n) => {
Gn = n;
};
let $s = 0;
function xe(n) {
return tt(`_${n}`, $s++);
}
function tt(n, e) {
return `?${n}-${e}`;
}
class Oe extends Error {
constructor(e) {
super(e), this.name = "AttrNotFoundError";
}
}
function xs(n, e) {
const t = Qn(n, e);
if (!t)
throw new Oe(`Could not find id attr for ${e}`);
return t;
}
function en(n, e, t, r) {
return [Rs(n, e, t, r)];
}
function Rs(n, e, t, r) {
return [
n(t, r),
xs(e, t).id,
n(t, r),
n("time", r)
];
}
function Ds(n, e, t) {
return n.map((r) => r === e ? t : r);
}
function Hn(n, e, t, r, s) {
const i = U(e, t, s), o = ge(e, t, s), a = i || o;
if (!a)
throw new Oe(`Could not find attr for ${[t, s]}`);
if (a["value-type"] !== "ref")
throw new Error(`Attr ${a.id} is not a ref`);
const [c, u] = a["forward-identity"], [l, f] = a["reverse-identity"], d = r + 1, h = i ? [
n(u, r),
a.id,
n(f, d),
xe("time")
] : [
n(u, d),
a.id,
n(f, r),
xe("time")
];
return [i ? f : u, d, h, a, !!i];
}
function tn(n, e) {
if (typeof e != "string")
return function(o) {
return !1;
};
const r = e.replace(/[.*+?^${}()|[\]\\]/g, "\\$&").replace(/%/g, ".*").replace(/_/g, "."), s = new RegExp(`^${r}$`, n ? "s" : "is");
return function(o) {
return typeof o != "string" ? !1 : s.test(o);
};
}
function Us(n, e) {
if (typeof e != "object" || e.hasOwnProperty("$in") || e.hasOwnProperty("in"))
return e;
const t = n["checked-data-type"] === "date";
if (e.hasOwnProperty("$gt"))
return {
$comparator: !0,
$op: t ? function(s) {
return new Date(s[2]) > new Date(e.$gt);
} : function(s) {
return s[2] > e.$gt;
}
};
if (e.hasOwnProperty("$gte"))
return {
$comparator: !0,
$op: t ? function(s) {
return new Date(s[2]) >= new Date(e.$gte);
} : function(s) {
return s[2] >= e.$gte;
}
};
if (e.hasOwnProperty("$lt"))
return {
$comparator: !0,
$op: t ? function(s) {
return new Date(s[2]) < new Date(e.$lt);
} : function(s) {
return s[2] < e.$lt;
}
};
if (e.hasOwnProperty("$lte"))
return {
$comparator: !0,
$op: t ? function(s) {
return new Date(s[2]) <= new Date(e.$lte);
} : function(s) {
return s[2] <= e.$lte;
}
};
if (e.hasOwnProperty("$like")) {
const r = tn(!0, e.$like);
return {
$comparator: !0,
$op: function(i) {
return r(i[2]);
}
};
}
if (e.hasOwnProperty("$ilike")) {
const r = tn(!1, e.$ilike);
return {
$comparator: !0,
$op: function(i) {
return r(i[2]);
}
};
}
return e;
}
function Ls(n, e, t, r, s, i) {
const o = U(e, t, s), a = ge(
e,
t,
s
), c = o || a;
if (!c)
throw new Oe(
`No attr for etype = ${t} label = ${s}`
);
if (i?.hasOwnProperty("$isNull")) {
const u = U(e, t, "id");
if (!u)
throw new Oe(
`No attr for etype = ${t} label = id`
);
return [
n(t, r),
u.id,
{ $isNull: { attrId: c.id, isNull: i.$isNull, reverse: !o } },
xe("time")
];
}
return o ? [
n(t, r),
c.id,
Us(c, i),
xe("time")
] : [i, c.id, n(t, r), xe("time")];
}
function Ns(n, e, t, r, s) {
const [i, o, a] = s.reduce(
(c, u) => {
const [l, f, d] = c, [h, p, m] = Hn(
n,
e,
l,
f,
u
);
return [h, p, [...d, m]];
},
[t, r, []]
);
return [i, o, a];
}
function St(n, e, t, r, s, i) {
const o = s.slice(0, s.length - 1), a = s[s.length - 1], [c, u, l] = Ns(
n,
e,
t,
r,
o
), f = Ls(
n,
e,
c,
u,
a,
i
);
return l.concat([f]);
}
function Fs(n, e) {
return e ? [e].concat(n) : n;
}
function Ks([n, e]) {
return n === "or" && Array.isArray(e);
}
function qs([n, e]) {
return n === "and" && Array.isArray(e);
}
function zs(n, e, t) {
return (r, s) => {
const i = n(r, s);
return e == i ? i : `${i}-${t}`;
};
}
function nn(n, e, t, r, s, i) {
const o = n(r, s), a = i.map((c, u) => {
const l = zs(n, o, u);
return Jn(l, t, r, s, c);
});
return { [e]: { patterns: a, joinSym: o } };
}
function Ws(n) {
const e = [];
for (let t = 1; t <= n.length; t++)
e.push(n.slice(0, t));
return e;
}
function rn(n, e, t, r, s) {
return Ws(s).map(
(i) => St(n, e, t, r, i, {
$isNull: !0
})
);
}
function Jn(n, e, t, r, s) {
return Object.entries(s).flatMap(([i, o]) => {
if (Ks([i, o]))
return nn(n, "or", e, t, r, o);
if (qs([i, o]))
return nn(n, "and", e, t, r, o);
if (i === "$entityIdStartsWith")
return [];
const a = i.split(".");
if (o?.hasOwnProperty("$ne") && (o = { ...o, $not: o.$ne }, delete o.$ne), o?.hasOwnProperty("$not")) {
const c = St(
n,
e,
t,
r,
a,
o
), u = rn(
n,
e,
t,
r,
a
);
return [
{
or: {
patterns: [c, ...u],
joinSym: n(t, r)
}
}
];
}
return o?.hasOwnProperty("$isNull") && o.$isNull === !0 && a.length > 1 ? [
{
or: {
patterns: rn(
n,
e,
t,
r,
a
),
joinSym: n(t, r)
}
}
] : St(n, e, t, r, a, o);
});
}
function Vs(n, e, t, r) {
const s = tt;
return r ? Jn(s, n, e, t, r).concat(en(s, n, e, t)) : en(s, n, e, t);
}
function Qs(n, e, t) {
return [n(e, t), n("time", t)];
}
function Bs(n, e, t, r, s, i) {
const [o, a, c, u, l] = Hn(
n,
e,
t,
r,
s
), f = Ds(c, n(t, r), i);
return [o, a, f, u, l];
}
function Gs(n, e, t, { etype: r, level: s, form: i }, o) {
const a = Object.keys(i).filter((c) => c !== "$");
return a.length ? Object.entries(o).map(function([u, l]) {
return a.map(function(h) {
const p = !!(e.cardinalityInference && t.linkIndex?.[r]?.[h]?.isSingular);
try {
const [m, b, y] = Bs(
n,
t,
r,
s,
h,
u
), g = Xn(e, t, {
etype: m,
level: b,
form: i[h],
join: y
}), A = p ? g[0] : g;
return { [h]: A };
} catch (m) {
if (m instanceof Oe)
return { [h]: p ? void 0 : [] };
throw m;
}
}).reduce(function(h, p) {
return { ...h, ...p };
}, l);
}) : Object.values(o);
}
function Hs(n, e, t) {
return t === "string" ? js(n, e) : n > e ? 1 : -1;
}
function Pe(n, e, t, r, s) {
return e === r || e == null && r == null ? Es(n, t) : r == null ? 1 : e == null ? -1 : Hs(e, r, s);
}
function Ze([n, e], [t, r], s) {
return Pe(n, e, t, r, s);
}
function Tt(n) {
return n == null ? n : new Date(n).getTime();
}
function Yn(n, e, t) {
const [r, s, i, o] = n;
if (e["forward-identity"]?.[2] === "id")
return Ze(t, [r, o], null);
const [a, c] = t, u = e["checked-data-type"], l = u === "date" ? Tt(c) : c, f = u === "date" ? Tt(i) : i;
return Ze([a, l], [r, f], u);
}
function Js(n, e, t, r) {
const s = Yn(n, e, r);
return t === "desc" ? s > 0 : s < 0;
}
function Ys(n, e, t, r) {
const s = Yn(n, e, r);
return t === "desc" ? s < 0 : s > 0;
}
function Zs(n, e) {
const t = e[1];
return n.getAttr(t);
}
function Xs(n, e, t) {
const r = Object.keys(t)[0];
return U(n, e, r);
}
function ei(n, e, t, r) {
if (t)
return Zs(n, t);
if (r)
return Xs(n, e, r);
}
function ti(n, e, t) {
if (!Array.isArray(t.fields))
return us(n, e);
const r = /* @__PURE__ */ new Map();
for (const s of t.fields) {
const i = U(n, e, s), o = i?.["forward-identity"]?.[2];
o && Ft(i) && r.set(o, i);
}
if (!r.has("id")) {
const s = U(n, e, "id"), i = s?.["forward-identity"]?.[2];
i && r.set(i, s);
}
return r;
}
function ni(n, e, { etype: t, pageInfo: r, dq: s, form: i }) {
const o = i?.$?.order, a = Zn(i), c = ri(i);
let u = _s(n, s);
const l = r?.["start-cursor"], f = r?.["end-cursor"], d = ei(e, t, l, o);
if (d && d?.["forward-identity"]?.[2] !== "id") {
const m = d["checked-data-type"] === "date", b = d.id;
u = u.map(([y]) => {
let g = n.eav.get(y)?.get(b)?.values()?.next()?.value?.[2];
return m && (g = Tt(g)), [y, g];
});
}
u.sort(
c === "asc" ? function(b, y) {
return Ze(b, y, d?.["checked-data-type"]);
} : function(b, y) {
return Ze(y, b, d?.["checked-data-type"]);
}
);
let h = {};
const p = ti(e, t, s);
for (const m of u) {
const [b] = m;
if (h[b] || !a && l && d && Js(l, d, c, m) || !a && f && d && Ys(f, d, c, m))
continue;
const y = cs(n, p, b);
y && (h[b] = y);
}
return h;
}
function ri(n) {
const e = n.$?.order;
return e && e[Object.keys(e)[0]] || "asc";
}
function Zn(n) {
const e = n.$?.offset, t = n.$?.before, r = n.$?.after;
return !e && !t && !r;
}
function si(n, e, { etype: t, level: r, form: s, join: i, pageInfo: o }) {
if (!Zn(s) && (!o || !o["start-cursor"]))
return [];
const a = Fs(
Vs(e, t, r, s.$?.where),
i
), c = Qs(tt, t, r), u = s.$?.fields, l = ni(n, e, {
etype: t,
pageInfo: o,
form: s,
dq: { where: a, find: c, fields: u }
}), f = s.$?.limit || s.$?.first || s.$?.last;
if (f != null) {
r > 0 && Gn && console.warn(
"WARNING: Limits in child queries are only run client-side. Data returned from the server will not have a limit."
);
const d = Object.entries(l);
return d.length <= f ? l : Object.fromEntries(d.slice(0, f));
}
return l;
}
function ii(n, e, t) {
try {
return si(n, e, t);
} catch (r) {
if (r instanceof Oe)
return {};
throw r;
}
}
function Xn(n, e, t) {
const r = ii(n, e, t);
return Gs(tt, n, e, t, r);
}
function oi(n) {
const e = {};
for (const [t, r] of Object.entries(n))
e[t] = {
startCursor: r["start-cursor"],
endCursor: r["end-cursor"],
hasNextPage: r["has-next-page?"],
hasPreviousPage: r["has-previous-page?"]
};
return e;
}
function qt({
store: n,
attrsStore: e,
pageInfo: t,
aggregate: r
}, s) {
const o = { data: Object.keys(s).reduce(function(c, u) {
return r?.[u] || u === "$$ruleParams" || (c[u] = Xn(n, e, {
etype: u,
form: s[u],
level: 0,
pageInfo: t?.[u]
})), c;
}, {}) };
return t && (o.pageInfo = oi(t)), r && (o.aggregate = r), o;
}
function ai() {
const e = {
__etype: 1,
__ops: 1,
create: 1,
update: 1,
link: 1,
unlink: 1,
delete: 1,
merge: 1,
ruleParams: 1
};
return new Set(Object.keys(e));
}
const ci = ai();
function Ge(n, e, t) {
const r = {
__etype: n,
__ops: t
};
return new Proxy(r, {
get: (s, i) => {
if (i === "__ops") return t;
if (i === "__etype") return n;
if (ci.has(i))
return (o, a) => Ge(n, e, [
...t,
a ? [i, n, e, o, a] : [i, n, e, o]
]);
}
});
}
function ui(n, e) {
return `lookup__${n}__${JSON.stringify(e)}`;
}
function Xe(n) {
return n.startsWith("lookup__");
}
function vt(n) {
const [e, t, ...r] = n.split("__");
return [t, JSON.parse(r.join("__"))];
}
function li(n) {
return new Proxy(
{
__etype: n
},
{
get(e, t) {
if (t === "lookup")
return (s, i) => Ge(n, vt(ui(s, i)), []);
if (t === "__etype") return n;
const r = t;
return Xe(r) ? Ge(n, vt(r), []) : Ge(n, r, []);
}
}
);
}
function er() {
return new Proxy(
{},
{
get(n, e) {
return li(e);
}
}
);
}
const Ta = er();
function di(n) {
return n.__ops;
}
function fi(n, e) {
const { attrIdMap: t, refSwapAttrIds: r } = n, s = [];
for (const o of e) {
const a = t[o];
if (a)
s.push(a);
else if (Array.isArray(o) && o.length == 2 && t[o[0]]) {
const [c, u] = o;
s.push([t[c], u]);
} else
s.push(o);
}
const [i] = e;
if ((i === "add-triple" || i === "retract-triple") && r.has(e[2])) {
const o = s[1];
s[1] = s[3], s[3] = o;
}
return s;
}
function hi(n) {
if (Array.isArray(n))
return n;
const e = Object.entries(n);
if (e.length !== 1)
throw new Error(
"lookup must be an object with a single unique attr and value."
);
return e[0];
}
function pi(n, e, t) {
return t.indexOf(".") !== -1 && // attr names can have `.` in them, so use the attr we find with a `.`
// before assuming it's a ref lookup.
!U(n, e, t);
}
function At(n) {
const [e, t, ...r] = n.split(".");
if (r.length > 0 || t !== "id")
throw new Error(`${n} is not a valid lookup attribute.`);
return e;
}
function yi(n, e, t) {
if (!pi(n, e, t))
return U(n, e, t);
const r = At(t), s = U(n, e, r) || ge(n, e, r);
if (s && s["value-type"] !== "ref")
throw new Error(`${t} does not reference a valid link attribute.`);
return s;
}
function kt(n) {
return typeof n == "string" && !Xe(n) ? null : typeof n == "string" && Xe(n) ? vt(n) : hi(n);
}
function Y(n, e, t) {
const r = kt(t);
if (r === null)
return t;
const [s, i] = r, o = yi(n, e, s);
if (!o || !o["unique?"])
throw new Error(`${s} is not a unique attribute.`);
return [o.id, i];
}
function tr(n, e, t, r) {
const s = Y(n, e, t);
return Array.isArray(s) ? [[
"add-triple",
s,
U(n, e, "id")?.id,
s
]].concat(r) : r;
}
function bi({ attrsStore: n }, [e, t, r]) {
const s = Object.entries(r).flatMap(([i, o]) => {
const a = Array.isArray(o) ? o : [o], c = U(n, e, i), u = ge(n, e, i);
return a.map((l) => c ? [
"add-triple",
Y(n, e, t),
c.id,
// Uses `!` because if we get here, we should have created the attr if it doesn't
// already exist
Y(n, c["reverse-identity"][1], l)
] : [
"add-triple",
// Uses `!` because if we get here, we should have created the attr if it doesn't
// already exist
Y(n, u["forward-identity"][1], l),
u?.id,
Y(n, e, t)
]);
});
return tr(n, e, t, s);
}
function gi({ attrsStore: n }, [e, t, r]) {
const s = Object.entries(r).flatMap(([i, o]) => {
const a = Array.isArray(o) ? o : [o], c = U(n, e, i), u = ge(n, e, i);
return a.map((l) => c ? [
"retract-triple",
Y(n, e, t),
c.id,
// Uses `!` because if we get here, we should have created the attr if it doesn't
// already exist
Y(n, c["reverse-identity"][1], l)
] : [
"retract-triple",
// Uses `!` because if we get here, we should have created the attr if it doesn't
// already exist
Y(n, u["forward-identity"][1], l),
u.id,
Y(n, e, t)
]);
});
return tr(n, e, t, s);
}
function mi(n, e, t, r) {
if (Array.isArray(r)) {
const [s, i] = r;
for (const o of n || []) {
const a = o?.aev.get(s);
if (a) {
for (const [c, u, l] of J(a, 2))
if (l === i)
return !0;
}
}
} else
for (const s of n || []) {
const i = s?.eav.get(r);
if (i) {
for (const o of i.keys())
if (e.getAttr(o)?.["forward-identity"][1] == t)
return !0;
}
}
return !1;
}
function nr({ stores: n, attrsStore: e }, [t, r, s, i]) {
return i?.upsert === !1 ? { mode: "update" } : i?.upsert === !0 ? null : mi(n, e, t, r) ? { mode: "update" } : null;
}
function wi(n, e) {
const { attrsStore: t } = n, [r, s, i, o] = e, a = Lt(i), c = Y(t, r, s);
return [["id", c]].concat(Object.entries(a)).map(([l, f]) => {
const d = U(t, r, l);
return d["checked-data-type"] === "date" && n.useDateObjects && (f = et(f)), ["add-triple", c, d.id, f, { mode: "create" }];
});
}
function _i(n, e) {
const { attrsStore: t } = n, [r, s, i, o] = e, a = Lt(i), c = Y(t, r, s), u = nr(n, [r, c, i, o]);
return [["id", c]].concat(Object.entries(a)).map(([f, d]) => {
const h = U(t, r, f);
return h["checked-data-type"] === "date" && n.useDateObjects && (d = et(d)), [
"add-triple",
c,
h.id,
d,
...u ? [u] : []
];
});
}
function Si({ attrsStore: n }, [e, t]) {
return [["delete-entity", Y(n, e, t), e]];
}
function Ti(n, e) {
const { attrsStore: t } = n, [r, s, i, o] = e, a = Lt(i), c = Y(t, r, s), u = nr(n, [r, c, i, o]), l = Object.entries(a).map(([d, h]) => {
const p = U(t, r, d);
return [
"deep-merge-triple",
c,
p.id,
h,
...u ? [u] : []
];
});
return [[
"add-triple",
c,
U(t, r, "id").id,
c,
...u ? [u] : []
]].concat(l);
}
function vi({ attrsStore: n }, [e, t, r]) {
return [["rule-params", Y(n, e, t), e, r]];
}
function Ai(n) {
const [e, t, r, s, i] = n;
if (!s)
return n;
const o = { ...s };
return delete o.id, [e, t, r, o, ...i ? [i] : []];
}
function ki(n, e) {
const [t, ...r] = Ai(e);
switch (t) {
case "merge":
return Ti(n, r);
case "create":
return wi(n, r);
case "update":
return _i(n, r);
case "link":
return bi(n, r);
case "unlink":
return gi(n, r);
case "delete":
return Si(n, r);
case "ruleParams":
return vi(n, r);
default:
throw new Error(`unsupported action ${t}`);
}
}
function Oi(n) {
switch (n) {
case "string":
case "date":
case "boolean":
case "number":
return n;
default:
return;
}
}
function Ii(n, e, t) {
const r = n.entities[e]?.attrs?.[t];
if (t === "id") return null;
if (!r)
throw new Error(`${e}.${t} does not exist in your schema`);
const { unique: s, indexed: i } = r?.config, o = Oi(r?.valueType);
return {
"index?": i,
"unique?": s,
"checked-data-type": o
};
}
function Fe(n, e, t, r) {
const s = n ? Ii(n, e, t) : null, i = j(), a = [j(), e, t];
return {
id: i,
"forward-identity": a,
"value-type": "blob",
cardinality: "one",
"unique?": !1,
"index?": !1,
isUnsynced: !0,
...s || {},
...r || {}
};
}
function Ci(n, e, t) {
return Object.values(n.links).find((i) => i.forward.on === e && i.forward.label === t || i.reverse.on === e && i.reverse.label === t);
}
function Ei(n, e, t) {
const r = Ci(n, e, t);
if (!r)
throw new Error(`Couldn't find the link ${e}.${t} in your schema`);
const { forward: s, reverse: i } = r;
return {
"forward-identity": [j(), s.on, s.label],
"reverse-identity": [j(), i.on, i.label],
cardinality: s.has === "one" ? "one" : "many",
"unique?": i.has === "one",
"on-delete": s.onDelete,
"on-delete-reverse": i.onDelete
};
}
function sn(n, e, t, r) {
const s = n ? Ei(n, e, t) : null, i = j(), o = [j(), e, t], a = [j(), t, e];
return {
id: i,
// @ts-ignore: ts thinks it's any[]
"forward-identity": o,
// @ts-ignore: ts thinks it's any[]
"reverse-identity": a,
"value-type": "ref",
// @ts-ignore: ts thinks it's type string
cardinality: "many",
"unique?": !1,
"index?": !1,
isUnsynced: !0,
...s || {},
...r || {}
};
}
const Mi = /* @__PURE__ */ new Set(["create", "update", "merge", "link", "unlink"]), Pi = /* @__PURE__ */ new Set(["link", "unlink"]), ji = /* @__PURE__ */ new Set(["create", "update", "merge"]), $i = /* @__PURE__ */ new Set([
"link",
"unlink",
"create",
"update",
"merge",
"delete",
"ruleParams"
]), Ot = { "unique?": !0, "index?": !0 }, xi = {
...Ot,
cardinality: "one"
};
function Ri(n) {
const e = [], [t, r, s, i] = n;
if (!$i.has(t))
return e;
const o = kt(s);
if (o && e.push({ etype: r, lookupPair: o }), t === "link")
for (const [a, c] of Object.entries(i)) {
const u = Array.isArray(c) ? c : [c];
for (const l of u) {
const f = kt(l);
f && e.push({
etype: r,
lookupPair: f,
linkLabel: a
});
}
}
return e;
}
function Di({ attrsStore: n, schema: e }, t) {
const r = /* @__PURE__ */ new Set(), s = [], i = [];
function o(d, h) {
return U(n, d, h) || s.find(
(p) => p["forward-identity"][1] === d && p["forward-identity"][2] === h
);
}
function a(d, h) {
return ge(n, d, h) || s.find(
(p) => p["reverse-identity"]?.[1] === d && p["reverse-identity"]?.[2] === h
);
}
function c(d) {
s.push(d), i.push(["add-attr", d]), r.add(d.id);
}
function u(d) {
d && "isUnsynced" in d && d.isUnsynced && !r.has(d.id) && (s.push(d), i.push(["add-attr", d]), r.add(d.id));
}
function l(d, h) {
return h.indexOf(".") !== -1 && // attr names can have `.` in them, so use the attr we find with a `.`
// before assuming it's a ref lookup.
!o(d, h);
}
function f(d, h) {
const p = o(d, h), m = a(d, h);
u(p), u(m), !p && !m && c(sn(e, d, h, xi));
}
for (const d of t)
for (const { etype: h, lookupPair: p, linkLabel: m } of Ri(d)) {
const b = p[0];
if (m) {
f(h, m);
const y = o(h, m), g = a(h, m);
u(y), u(g);
const A = y?.["reverse-identity"]?.[1] || g?.["forward-identity"]?.[1] || m;
if (l(A, b))
f(A, At(b));
else {
const R = o(A, b);
R || c(
Fe(e, A, b, Ot)
), u(R);
}
} else if (l(h, b))
f(h, At(b));
else {
const y = o(h, b);
y || c(Fe(e, h, b, Ot)), u(y);
}
}
for (const d of t) {
const [h, p, m, b] = d;
if (Mi.has(h)) {
const y = o(p, "id");
u(y), y || c(Fe(e, p, "id", { "unique?": !0 }));
for (const g of Object.keys(b)) {
const A = o(p, g);
if (u(A), ji.has(h) && (A || c(
Fe(
e,
p,
g,
g === "id" ? { "unique?": !0 } : null
)
)), Pi.has(h)) {
const R = a(p, g);
!A && !R && c(sn(e, p, g)), u(R);
}
}
}
}
if (s.length) {
const d = { ...n.attrs };
for (const h of s)
d[h.id] = h;
return [new fe(d, n.linkIndex), i];
}
return [n, i];
}
function Ui(n, e) {
const r = (Array.isArray(e) ? e : [e]).flatMap((c) => di(c)), [s, i] = Di(n, r), o = { ...n, attrsStore: s }, a = r.flatMap((c) => ki(o, c));
return [...i, ...a];
}
function on(n, e) {
typeof requestIdleCallback > "u" ? n() : requestIdleCallback(n, { timeout: e });
}
const ve = "__meta";
class rr {
constructor(e, t) {
}
}
class It {
currentValue;
_subs = [];
_persister;
_merge;
serialize;
parse;
_saveThrottleMs;
_idleCallbackMaxWaitMs;
_nextSave = null;
_nextGc = null;
_pendingSaveKeys = /* @__PURE__ */ new Set();
_loadedKeys = /* @__PURE__ */ new Set();
_loadingKeys;
_objectSize;
_log;
onKeyLoaded;
_version = 0;
_meta = {
isLoading: !0,
onLoadCbs: [],
value: null,
error: null,
attempts: 0
};
_gcOpts;
constructor(e) {
this._persister = e.persister, this._merge = e.merge, this.serialize = e.serialize, this.parse = e.parse, this._objectSize = e.objectSize, this._log = e.logger, this._saveThrottleMs = e.saveThrottleMs ?? 100, this._idleCallbackMaxWaitMs = e.idleCallbackMaxWaitMs ?? 1e3, this._gcOpts = e.gc, this.currentValue = {}, this._loadedKeys = /* @__PURE__ */ new Set(), this._loadingKeys = {}, this._initMeta(), e.preloadEntryCount && this._preloadEntries(e.preloadEntryCount);
}
async _initMeta() {
this._meta.loadingPromise && await this._meta.loadingPromise;
try {
const e = this._persister.getItem(ve);
this._meta.loadingPromise = e;
const t = await e;
this._meta.isLoading = !1, this._meta.error = null, this._meta.loadingPromise = null, this._meta.attempts = 0;
const r = this._meta.value?.objects ?? {}, s = t ?? {}, i = s.objects ?? {};
this._meta.value = {
...s,
objects: { ...r, ...i }
};
} catch (e) {
this._meta.error = e, this._meta.attempts++, this._meta.loadingPromise = null;
}
}
async _getMeta() {
return this._meta.value ? this._meta.value : this._meta.loadingPromise ? (await this._meta.loadingPromise, this._meta.value) : (this._initMeta(), await this._meta.loadingPromise, this._meta.value);
}
async _refreshMeta() {
return await this._initMeta(), this._meta.value;
}
async _preloadEntries(e) {
const t = await this.waitForMetaToLoad();
if (!t) return;
const r = Object.entries(t.objects);
r.sort(([s, i], [o, a]) => a.updatedAt - i.updatedAt);
for (const [s] of r.slice(0, e))
this._loadKey(s);
}
async _getFromStorage(e) {
try {
const t = await this._persister.getItem(e);
return t && this.parse(e, t);
} catch (t) {
return console.error(`Unable to read from storage for key=${e}`, t), null;
}
}
async waitForKeyToLoad(e) {
return this._loadedKeys.has(e) ? this.currentValue[e] : (await (this._loadingKeys[e] || this._loadKey(e)), this.currentValue[e]);
}
// Used for tests
async waitForMetaToLoad() {
return this._getMeta();
}
// Unloads the key so that it can be garbage collected, but does not
// delete it. Removes the key from currentValue.
unloadKey(e) {
this._loadedKeys.delete(e), delete this._loadingKeys[e], delete this.currentValue[e];
}
async _loadKey(e) {
if (this._loadedKeys.has(e) || e in this._loadingKeys) return;
const t = this._getFromStorage(e);
this._loadingKeys[e] = t;
const r = await t;
if (delete this._loadingKeys[e], this._loadedKeys.add(e), r) {
const s = this._merge(e, r, this.currentValue[e]);
s && (this.currentValue[e] = s);
}
this.onKeyLoaded && this.onKeyLoaded(e);
}
// Returns a promise with a number so that we can wait for flush
// to finish in the tests. The number is the number of operations
// it performed, but it's mostly there so that typescript will warn
// us if we forget to retun the promise from the function.
_writeToStorage(e) {
const t = [], r = e?.skipGc;
if (this._meta.isLoading) {
const f = new Promise((d, h) => {
setTimeout(
() => this._enqueuePersist(
e ? { ...e, attempts: (e.attempts || 0) + 1 } : { attempts: 1 }
).then(d).catch(h),
10 + (e?.attempts ?? 0) * 1e3
);
});
return t.push(f), Promise.all(t).then(
(d) => d.reduce((h, p) => h + p, 0)
);
}
const s = this._meta.value;
if (!s)
return Promise.resolve(0);
const i = [], o = [];
for (const f of this._pendingSaveKeys)
f in this.currentValue ? o.push(f) : (i.push(f), delete s.objects[f]);
for (const f of i) {
const d = this._persister.removeItem(f);
t.push(d.then(() => 1)), this._loadedKeys.delete(f), this._pendingSaveKeys.delete(f);
}
const a = [], c = [[ve, s]], u = s.objects ?? {};
s.objects = u;
for (const f of o)
if (this._loadedKeys.has(f)) {
const d = this.serialize(f, this.currentValue[f]);
c.push([f, d]);
const h = this._objectSize(d), p = u[f] ?? {
createdAt: Date.now(),
updatedAt: Date.now(),
size: h
};
p.updatedAt = Date.now(), p.size = h, u[f] = p, this._pendingSaveKeys.delete(f);
} else
a.push(f);
const l = this._persister.multiSet(c);
t.push(l.then(() => 1));
for (const f of a) {
const d = this._loadKey(f).then(() => this._enqueuePersist(e));
t.push(d);
}
return r || this.gc(), Promise.all(t).then((f) => f.reduce((d, h) => d + h, 0));
}
async flush() {
return this._nextSave ? (clearTimeout(this._nextSave), this._nextSave = null, this._writeToStorage()) : void 0;
}
async _gc() {
if (!this._gcOpts)
return;
const e = new Set(await this._persister.getAllKeys());
e.delete(ve);
const t = new Set(Object.keys(this.currentValue));
for (const d of Object.keys(this._loadingKeys))
t.add(d);
for (const d of this._loadedKeys)
t.add(d);
const r = await this._refreshMeta();
if (!r) {
this._log.info("Could not gc because we were not able to load meta");
return;
}
const s = [], i = {
gcOpts: this._gcOpts,
keys: e,
sacredKeys: t,
removed: [],
metaRemoved: [],
removedMissingCount: 0,
removedOldCount: 0,
removedThresholdCount: 0,
removedSizeCount: 0
};
for (const d of e)
t.has(d) || d in r.objects || (this._log.info("Lost track of key in meta", d), s.push(this._persister.removeItem(d)), i.removed.push(d), i.removedMissingCount++);
const o = Date.now();
for (const [d, h] of Object.entries(r.objects))
!t.has(d) && h.updatedAt < o - this._gcOpts.maxAgeMs && (s.push(this._persister.removeItem(d)), delete r.objects[d], i.removed.push(d), i.removedOldCount++);
const a = Object.entries(r.objects);
a.sort(([d, h], [p, m]) => h.updatedAt - m.updatedAt);
const c = a.filter(([d]) => !t.has(d));
if (a.length > this._gcOpts.maxEntries)
for (const [d] of c.slice(
0,
a.length - this._gcOpts.maxEntries
))
s.push(this._persister.removeItem(d)), delete r.objects[d], i.removed.push(d), i.removedThresholdCount++;
const u = Object.entries(r.objects);
u.sort(([d, h], [p, m]) => h.updatedAt - m.updatedAt);
const l = u.filter(([d]) => !t.has(d));
let f = u.reduce((d, [h, p]) => d + p.size, 0);
for (; f > 0 && f > this._gcOpts.maxSize && l.length; ) {
const [[d, h]] = l.splice(0, 1);
f -= h.size, s.push(this._persister.removeItem(d)), delete r.objects[d], i.removed.push(d), i.removedSizeCount++;
}
for (const d of Object.keys(r.objects))
!e.has(d) && !t.has(d) && delete r.objects[d];
return (i.removed.length || i.metaRemoved.length) && s.push(this._enqueuePersist({ skipGc: !0 })), this._log.info("Completed GC", i), await Promise.all(s), i;
}
// Schedules a GC to run in one minute (unless it is already scheduled)
gc() {
this._nextGc || (this._nextGc = setTimeout(
() => {
on(() => {
this._nextGc = null, this._gc().catch(
(e) => this._log.error("Persisted Object GC Failed:", e)
);
}, 30 * 1e3);
},
// 1 minute + some jitter to keep multiple tabs from running at same time
1e3 * 60 + Math.random() * 500
));
}
_enqueuePersist(e) {
return new Promise((t, r) => {
if (this._nextSave) {
t(0);
return;
}
this._nextSave = setTimeout(() => {
on(() => {
this._nextSave = null, this._writeToStorage(e).then(t).catch(r);
}, this._idleCallbackMaxWaitMs);
}, this._saveThrottleMs);
});
}
version() {
return this._version;
}
// Takes a function that updates the store in place.
// Uses `mutative` to get a list of keys that were changed
// so that we know which entries we need to persist to the store.
updateInPlace(e) {
this._version++;
const [t, r] = Ye(this.currentValue, e, {
enablePatches: !0
});
for (const s of r) {
const i = s.path[0];
i && typeof i == "string" && (this._pendingSaveKeys.add(i), this._loadedKeys.has(i) || this._loadKey(i));
}
this.currentValue = t, this._enqueuePersist();
for (const s of this._subs)
s(this.currentValue);
return t;
}
subscribe(e) {
return this._subs.push(e), e(this.currentValue), () => {
this._subs = this._subs.filter((t) => t !== e);
};
}
// Removes any keys that we haven't loaded--used when
// changing users to make sure we clean out all user data
async clearUnloadedKeys() {
let e = !1;
for (const t of await this._persister.getAllKeys())
t === ve || t in this.currentValue || (this._pendingSaveKeys.add(t), e = !0);
e && await this._enqueuePersist();
}
}
const Li = 6, Ni = ["kv", "querySubs", "syncSubs"];
function Fi(n) {
return function(t) {
console.error("Error in IndexedDB event", { source: n, event: t });
};
}
async function Ki(n) {
return new Promise((e) => {
const t = indexedDB.open(n);
t.onerror = (r) => {
e(null);
}, t.onsuccess = (r) => {
const i = r.target.result;
e(i);
}, t.onupgradeneeded = (r) => {
r.target.transaction?.abort(), e(null);
};
});
}
async function qi(n, e, t) {
const r = (
// Backwards compatibility for older versions where we JSON.stringified before storing
typeof e == "string" ? JSON.parse(e) : e
);
if (!r)
return;
const s = /* @__PURE__ */ new Set();
return new Promise((i, o) => {
const a = {};
for (const [l, f] of Object.entries(r)) {
const d = typeof f == "string" ? JSON.parse(f) : f;
if (d.lastAccessed) {
const p = {
createdAt: d.lastAccessed,
updatedAt: d.lastAccessed,
size: d.result?.store?.triples?.length ?? 0
};
a[l] = p;
}
const h = t.put(d, l);
s.add(h);
}
const c = { objects: a }, u = t.put(c, ve);
s.add(u);
for (const l of s)
l.onsuccess = () => {
s.delete(l), s.size === 0 && i();
}, l.onerror = (f) => {
o(f);
};
});
}
async function an(n, e, t) {
const r = t.put(e, n);
return new Promise((s, i) => {
r.onsuccess = () => s(), r.onerror = (o) => i(o);
});
}
async function zi(n, e) {
const t = await Ki(`instant_${n}_5`);
if (!t)
return;
const r = await new Promise((l, f) => {
const p = t.transaction(["kv"], "readonly").objectStore("kv").openCursor();
p.onerror = (b) => {
f(b);
};
const m = [];
p.onsuccess = () => {
const b = p.result;
if (b) {
const y = b.key, g = b.value;
m.push([y, g]), b.continue();
} else
l(m);
}, p.onerror = (b) => {
f(b);
};
}), s = e.transaction(["kv", "querySubs"], "readwrite"), i = s.objectStore("kv"), o = s.objectStore("querySubs"), a = [], c = { objects: {} };
for (const [l, f] of r)
if (l === "querySubs") {
const d = qi(l, f, o);
a.push(d);
} else {
const d = an(l, f, i);
a.push(d);
const h = {
createdAt: Date.now(),
updatedAt: Date.now(),
size: 0
};
c.objects[l] = h;
}
const u = an(ve, c, i);
a.push(u), await Promise.all(a), await new Promise((l, f) => {
s.oncomplete = (d) => l(d), s.onerror = (d) => f(d), s.onabort = (d) => f(d);
});
}
const cn = /* @__PURE__ */ new Map();
class sr extends rr {
dbName;
_storeName;
_appId;
_prefix;
_dbPromise;
constructor(e, t) {
super(e, t), this.dbName = `instant_${e}_${Li}`, this._storeName = t, this._appId = e, this._dbPromise = this._init();
}
_init() {
return new Promise((e, t) => {
let r = !1;
const s = indexedDB.open(this.dbName, 1);
s.onerror = (i) => {
t(i);
}, s.onsuccess = (i) => {
const a = i.target.result;
if (a.onclose = () => {
this._dbPromise = this._init();
}, a.onversionchange = () => {
a.close();
}, r) {
const c = zi(this._appId, a).catch((u) => {
Fi("Error upgrading store from version 5 to 6.")(u);
});
cn.set(this.dbName, c), c.then(() => e(a)).catch(() => e(a));
} else {
const c = cn.get(this.dbName);
c ? c.then(() => e(a)).catch(() => e(a)) : e(a);
}
}, s.onupgradeneeded = (i) => {
r = !0, this._upgradeStore(i);
};
});
}
_upgradeStore(e) {
const r = e.target.result;
for (const s of Ni)
r.objectStoreNames.contains(s) || r.createObjectStore(s);
}
// Browsers can close IndexedDB connections unexpectedly (backgrounded tabs,
// memory pressure, cross-tab version changes, etc.), causing
// `db.transaction()` to throw InvalidStateError. This helper catches that
// error and retries once with a fresh connection.
async _withRetry(e) {
try {
const t = await this._dbPromise;
return await e(t);
} catch (t) {
if (t instanceof DOMException && t.name === "InvalidStateError") {
this._dbPromise = this._init();
const r = await this._dbPromise;
return await e(r);
}
throw t;
}
}
async getItem(e) {
return this._withRetry((t) => new Promise((r, s) => {
const a = t.transaction([this._storeName], "readonly").objectStore(this._storeName).get(e);
a.onerror = () => {
s(a.error);
}, a.onsuccess = () => {
a.result ? r(a.result) : r(null);
};
}));
}
async setItem(e, t) {
return this._withRetry((r) => new Promise((s, i) => {
const o = r.transaction([this._storeName], "readwrite");
o.objectStore(this._storeName).put(t, e), o.oncomplete = () => s(), o.onerror = () => i(o.error), o.onabort = () => i(o.error), o.commit?.();
}));
}
async multiSet(e) {
return this._withRetry((t) => new Promise((r, s) => {
const i = t.transaction([this._storeName], "readwrite"), o = i.objectStore(this._storeName);
for (const [a, c] of e)
o.put(c, a);
i.oncomplete = () => r(), i.onerror = () => s(i.error), i.onabort = () => s(i.error), i.commit?.();
}));
}
async removeItem(e) {
return this._withRetry((t) => new Promise((r, s) => {
const i = t.transaction([this._storeName], "readwrite");
i.objectStore(this._storeName).delete(e), i.oncomplete = () => r(), i.onerror = () => s(i.error), i.onabort = () => s(i.error), i.commit?.();
}));
}
async getAllKeys() {
return this._withRetry((e) => new Promise((t, r) => {
const o = e.transaction([this._storeName], "readonly").objectStore(this._storeName).getAllKeys();
o.onerror = () => {
r(o.error);
}, o.onsuccess = () => {
t(o.result.filter((a) => typeof a == "string"));
};
}));
}
}
class ir {
static async getIsOnline() {
return navigator.onLine;
}
static listen(e) {
const t = () => {
e(!0);
}, r = () => {
e(!1);
};
return addEventListener("online", t), addEventListener("offline", r), () => {
removeEventListener("online", t), removeEventListener("offline", r);
};
}
}
class L extends Error {
hint;
traceId;
constructor(e, t, r) {
super(e), this.hint = t, r && (this.traceId = r);
const s = new.target.prototype;
Object.setPrototypeOf && Object.setPrototypeOf(this, s), Error.captureStackTrace && Error.captureStackTrace(this, L), this.name = "InstantError";
}
get [Symbol.toStringTag]() {
return "InstantError";
}
}
class Le extends L {
body;
status;
constructor(e) {
const t = e.body?.message || `API Error (${e.status})`;
super(
t,
e.body.hint,
e.body?.traceId || e.body["trace-id"]
);
const r = new.target.prototype;
Object.setPrototypeOf && Object.setPrototypeOf(this, r), Error.captureStackTrace && Error.captureStackTrace(this, Le), this.name = "InstantAPIError", this.status = e.status, this.body = e.body;
}
get [Symbol.toStringTag]() {
return "InstantAPIError";
}
}
async function oe(n, e) {
const t = await fetch(n, e), r = await t.json();
return t.status === 200 ? Promise.resolve(r) : Promise.reject(new Le({ status: t.status, body: r }));
}
function Wi({
apiURI: n,
appId: e,
email: t
}) {
return oe(`${n}/runtime/auth/send_magic_code`, {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({ "app-id": e, email: t })
});
}
async function Vi({
apiURI: n,
appId: e,
email: t,
code: r,
refreshToken: s,
extraFields: i
}) {
return await oe(`${n}/runtime/auth/verify_magic_code`, {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({
"app-id": e,
email: t,
code: r,
...s ? { "refresh-token": s } : {},
...i ? { "extra-fields": i } : {}
})
});
}
async function Qi({
apiURI: n,
appId: e,
refreshToken: t
}) {
return await oe(`${n}/runtime/auth/verify_refresh_token`, {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({
"app-id": e,
"refresh-token": t
})
});
}
async function Bi({
apiURI: n,
appId: e,
extraFields: t
}) {
return await oe(`${n}/runtime/auth/sign_in_guest`, {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({
"app-id": e,
...t ? { "extra-fields": t } : {}
})
});
}
async function un({
apiURI: n,
appId: e,
code: t,
codeVerifier: r,
refreshToken: s,
extraFields: i
}) {
return await oe(`${n}/runtime/oauth/token`, {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({
app_id: e,
code: t,
code_verifier: r,
refresh_token: s,
...i ? { extra_fields: i } : {}
})
});
}
async function Gi({
apiURI: n,
appId: e,
nonce: t,
idToken: r,
clientName: s,
refreshToken: i,
extraFields: o
}) {
return await oe(`${n}/runtime/oauth/id_token`, {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({
app_id: e,
nonce: t,
id_token: r,
client_name: s,
refresh_token: i,
...o ? { extra_fields: o } : {}
})
});
}
async function Hi({
apiURI: n,
appId: e,
refreshToken: t
}) {
return await oe(`${n}/runtime/signout`, {
method: "POST",
headers: {
"content-type": "application/json"
},
body: JSON.stringify({
app_id: e,
refresh_token: t
})
});
}
async function Ji({
apiURI: n,
appId: e,
path: t,
file: r,
refreshToken: s,
contentType: i,
contentDisposition: o
}) {
const a = {
"app-id": e,
app_id: e,
path: t,
authorization: `Bearer ${s}`,
"content-type": i || r.type
};
return o && (a["content-disposition"] = o), await oe(`${n}/storage/upload`, {
method: "PUT",
headers: a,
body: r
});
}
async function Yi({
apiURI: n,
appId: e,
path: t,
refreshToken: r
}) {
const { data: s } = await oe(
`${n}/storage/files?app_id=${e}&filename=${encodeURIComponent(t)}`,
{
method: "DELETE",
headers: {
"content-type": "application/json",
authorization: `Bearer ${r}`
}
}
);
return s;
}
async function Zi({
apiURI: n,
appId: e,
fileName: t,
refreshToken: r,
metadata: s = {}
}) {
const { data: i } = await oe(`${n}/storage/signed-upload-url`, {
method: "POST",
headers: {
"content-type": "application/json",
authorization: `Bearer ${r}`
},
body: JSON.stringify({
app_id: e,
filename: t
})
});
return i;
}
async function Xi(n, e) {
return (await fetch(n, {
method: "PUT",
body: e,
headers: {
"Content-Type": e.type
}
})).ok;
}
async function eo({
apiURI: n,
appId: e,
path: t,
refreshToken: r
}) {
const { data: s } = await oe(
`${n}/storage/signed-download-url?app_id=${e}&filename=${encodeURIComponent(
t
)}`,
{
method: "GET",
headers: {
"content-type": "application/json",
authorization: `Bearer ${r}`
}
}
);
return s;
}
let zt = !1, or = !1, ar = !1;
typeof window < "u" && typeof window.localStorage < "u" && (zt = !!window.localStorage.getItem("devBackend"), or = !!window.localStorage.getItem("__instantLogging"), ar = !!window.localStorage.getItem("__devtoolLocalDash"));
function ln(n, e) {
if (!e) return n;
const t = {};
return e.forEach((r) => {
t[r] = n[r];
}), t;
}
function to(n, e, t) {
const r = {
peers: {}
};
if (e && "user" in e ? e.user : !0) {
const i = ln(n.user ?? {}, e?.keys);
r.user = { ...i, peerId: t };
}
for (const i of Object.keys(n.peers ?? {})) {
const o = e?.peers === void 0, a = Array.isArray(e?.peers) && e?.peers.includes(i);
if (o || a) {
const c = ln(n.peers[i], e?.keys);
r.peers[i] = { ...c, peerId: i };
}
}
return r;
}
function no(n, e) {
if (n.isLoading !== e.isLoading || n.error !== e.error || (n.user || e.user) && (!n.user || !e.user || !Gt(n.user, e.user)) || !xn(n.peers, e.peers)) return !0;
for (const r of Object.keys(n.peers))
if (!Gt(n.peers[r], e.peers[r])) return !0;
return !1;
}
class dn {
promise;
_resolve;
_reject;
constructor() {
this.promise = new Promise((e, t) => {
this._resolve = e, this._reject = t;
});
}
resolve(e) {
this._resolve(e);
}
reject(e) {
this._reject(e);
}
}
function cr(n, e = []) {
n.forEach((t) => {
const { data: r } = t, { "datalog-result": s } = r, { "join-rows": i } = s;
for (const o of i)
for (const a of o)
e.push(a);
cr(t["child-nodes"], e);
});
}
function fn(n) {
const e = [];
return cr(n, e), e;
}
function Ct(n) {
return Object.values(n.links).reduce((e, t) => (e[t.forward.on] ??= {}, e[t.forward.on][t.forward.label] = {
isForward: !0,
isSingular: t.forward.has === "one",
link: t
}, e[t.reverse.on] ??= {}, e[t.reverse.on][t.reverse.label] = {
isForward: !1,
isSingular: t.reverse.has === "one",
link: t
}, e), {});
}
const ur = "v1.0.67";
function ro(n, e, t = console) {
return {
info: n ? (...r) => t.info(...r, e()) : () => {
},
debug: n ? (...r) => t.debug(...r, e()) : () => {
},
error: n ? (...r) => t.error(...r, e()) : () => {
}
};
}
class V {
constructor(e, t, r, s = { indexed: !1, unique: !1 }) {
this.valueType = e, this.required = t, this.isIndexed = r, this.config = s;
}
metadata = {};
/**
* @deprecated Only use this temporarily for attributes that you want
* to treat as required in frontend code but can’t yet mark as required
* and enforced for backend
*/
clientRequired() {
return new V(
this.valueType,
!1,
this.isIndexed,
this.config
);
}
optional() {
return new V(
this.valueType,
!1,
this.isIndexed,
this.config
);
}
unique() {
return new V(
this.valueType,
this.required,
this.isIndexed,
{
...this.config,
unique: !0
}
);
}
indexed() {
return new V(
this.valueType,
this.required,
!0,
{
...this.config,
indexed: !0
}
);
}
// clientValidate(clientValidator: (value: ValueType) => boolean) {
// return new DataAttrDef(this.valueType, this.required, {
// ...this.config,
// clientValidator,
// });
// }
}
class nt {
constructor(e, t) {
this.attrs = e, this.links = t;
}
asType() {
return new nt(this.attrs, this.links);
}
}
class rt {
constructor(e, t, r) {
this.entities = e, this.links = t, this.rooms = r;
}
/**
* @deprecated
* `withRoomSchema` is deprecated. Define your schema in `rooms` directly:
*
* @example
* // Before:
* const schema = i.schema({
* // ...
* }).withRoomSchema<RoomSchema>()
*
* // After
* const schema = i.schema({
* rooms: {
* // ...
* }
* })
*
* @see https://instantdb.com/docs/presence-and-topics#typesafety
*/
withRoomSchema() {
return new rt(
this.entities,
this.links,
{}
);
}
}
class P extends Error {
constructor(e, t) {
const r = t ? `At path '${t}': ${e}` : e;
super(r), this.name = "QueryValidationError";
}
}
const hn = [
"where",
"order",
"limit",
"last",
"first",
"offset",
"after",
"afterInclusive",
"before",
"beforeInclusive",
"fields",
"aggregate"
], so = (n) => n.valueType || "unknown", lr = (n, e, t = !1) => {
if (t || n == null) return !0;
switch (e) {
case "string":
return typeof n == "string";
case "number":
return typeof n == "number" && !isNaN(n);
case "boolean":
return typeof n == "boolean";
case "date":
return n instanceof Date || typeof n == "string" || typeof n == "number";
default:
return !0;
}
}, io = (n, e, t, r, s, i, o) => {
const a = i.valueType === "json", c = (u, l, f) => {
if (!lr(f, l, a))
throw new P(
`Invalid value for operator '${u}' on attribute '${r}' in entity '${s}'. Expected ${l}, but received: ${typeof f}`,
o
);
};
switch (n) {
case "in":
case "$in":
if (!Array.isArray(e))
throw new P(
`Operator '${n}' for attribute '${r}' in entity '${s}' must be an array, but received: ${typeof e}`,
o
);
for (const u of e)
c(n, t, u);
break;
case "$not":
case "$ne":
case "$gt":
case "$lt":
case "$gte":
case "$lte":
c(n, t, e);
break;
case "$like":
case "$ilike":
if (c(n, "string", e), n === "$ilike" && !i.isIndexed)
throw new P(
`Operator '${n}' can only be used with indexed attributes, but '${r}' in entity '${s}' is not indexed`,
o
);
break;
case "$isNull":
c(n, "boolean", e);
break;
default:
throw new P(
`Unknown operator '${n}' for attribute '${r}' in entity '${s}'`,
o
);
}
}, Ae = (n, e, t, r, s) => {
const i = so(t), o = t.valueType === "json";
if (typeof n == "object" && n !== null && !Array.isArray(n)) {
if (o)
return;
const c = n;
for (const [u, l] of Object.entries(c))
io(
u,
l,
i,
e,
r,
t,
`${s}.${u}`
);
} else if (!lr(n, i, o))
throw new P(
`Invalid value for attribute '${e}' in entity '${r}'. Expected ${i}, but received: ${typeof n}`,
s
);
}, oo = (n, e, t, r, s) => {
const i = n.split(".");
if (i.length < 2)
throw new P(
`Invalid dot notation path '${n}'. Must contain at least one dot.`,
s
);
let o = t;
for (let l = 0; l < i.length - 1; l++) {
const f = i[l], d = r.entities[o];
if (!d)
throw new P(
`Entity '${o}' does not exist in schema while traversing dot notation path '${n}'.`,
s
);
const h = d.links[f];
if (!h) {
const p = Object.keys(d.links);
throw new P(
`Link '${f}' does not exist on entity '${o}' in dot notation path '${n}'. Available links: ${p.length > 0 ? p.join(", ") : "none"}`,
s
);
}
o = h.entityName;
}
const a = i[i.length - 1], c = r.entities[o];
if (!c)
throw new P(
`Target entity '${o}' does not exist in schema for dot notation path '${n}'.`,
s
);
if (a === "id") {
if (typeof e == "string" && !ke(e))
throw new P(
`Invalid value for id field in entity '${o}'. Expected a UUID, but received: ${e}`,
s
);
Ae(
e,
n,
new V("string", !1, !0),
t,
s
);
return;
}
const u = c.attrs[a];
if (Object.keys(c.links).includes(a)) {
if (typeof e == "string" && !ke(e))
throw new P(
`Invalid value for link '${a}' in entity '${o}'. Expected a UUID, but received: ${e}`,
s
);
Ae(
e,
n,
new V("string", !1, !0),
t,
s
);
return;
}
if (!u) {
const l = Object.keys(c.attrs);
throw new P(
`Attribute '${a}' does not exist on entity '${o}' in dot notation path '${n}'. Available attributes: ${l.length > 0 ? l.join(", ") + ", id" : "id"}`,
s
);
}
Ae(e, n, u, t, s);
}, dr = (n, e, t, r) => {
for (const [s, i] of Object.entries(n)) {
if (s === "or" || s === "and") {
if (Array.isArray(i))
for (const u of i)
typeof u == "object" && u !== null && dr(
u,
e,
t,
`${r}.${s}[${u}]`
);
continue;
}
if (s === "id") {
Ae(
i,
"id",
new V("string", !1, !0),
e,
`${r}.id`
);
continue;
}
if (s.includes(".")) {
oo(
s,
i,
e,
t,
`${r}.${s}`
);
continue;
}
const o = t.entities[e];
if (!o) continue;
const a = o.attrs[s], c = o.links[s];
if (!a && !c) {
const u = Object.keys(o.attrs), l = Object.keys(o.links);
throw new P(
`Attribute or link '${s}' does not exist on entity '${e}'. Available attributes: ${u.length > 0 ? u.join(", ") : "none"}. Available links: ${l.length > 0 ? l.join(", ") : "none"}`,
`${r}.${s}`
);
}
if (a)
Ae(
i,
s,
a,
e,
`${r}.${s}`
);
else if (c) {
if (typeof i == "string" && !ke(i))
throw new P(
`Invalid value for link '${s}' in entity '${e}'. Expected a UUID, but received: ${i}`,
`${r}.${s}`
);
const u = new V("string", !1, !0);
Ae(
i,
s,
u,
e,
`${r}.${s}`
);
}
}
}, ao = (n, e, t, r, s = 0) => {
for (const o of Object.keys(n))
if (!hn.includes(o))
throw new P(
`Invalid query parameter '${o}' in $ object. Valid parameters are: ${hn.join(", ")}. Found: ${o}`,
r
);
const i = [
// 'limit', // only supported client side
"offset",
"before",
"beforeInclusive",
"after",
"afterInclusive",
"first",
"last"
];
for (const o of i)
if (n[o] !== void 0 && s > 0)
throw new P(
`'${o}' can only be used on top-level namespaces. It cannot be used in nested queries.`,
r
);
if (n.where && t) {
if (typeof n.where != "object" || n.where === null)
throw new P(
`'where' clause must be an object in entity '${e}', but received: ${typeof n.where}`,
r ? `${r}.where` : void 0
);
dr(
n.where,
e,
t,
r ? `${r}.where` : "where"
);
}
}, fr = (n, e, t, r, s = 0) => {
if (!n || typeof n != "object")
throw new P(
`Query part for entity '${e}' must be an object, but received: ${typeof n}`,
r
);
for (const i of Object.keys(n))
if (i !== "$") {
if (t && !(i in t.entities[e].links)) {
const a = Object.keys(t.entities[e].links);
throw new P(
`Link '${i}' does not exist on entity '${e}'. Available links: ${a.length > 0 ? a.join(", ") : "none"}`,
`${r}.${i}`
);
}
const o = n[i];
if (typeof o == "object" && o !== null) {
const a = t?.entities[e].links[i]?.entityName;
a && fr(
o,
a,
t,
`${r}.${i}`,
s + 1
);
}
} else {
const o = n[i];
if (typeof o != "object" || o === null)
throw new P(
`Query parameter '$' must be an object in entity '${e}', but received: ${typeof o}`,
`${r}.$`
);
ao(
o,
e,
t,
`${r}.$`,
s
);
}
}, pn = (n, e) => {
if (typeof n != "object" || n === null)
throw new P(
`Query must be an object, but received: ${typeof n}${n === null ? " (null)" : ""}`
);
if (Array.isArray(n))
throw new P(
`Query must be an object, but received: ${typeof n}`
);
const t = n;
for (const r of Object.keys(t)) {
if (Array.isArray(n[r]))
throw new P(
`Query keys must be strings, but found key of type: ${typeof r}`,
r
);
if (typeof r != "string")
throw new P(
`Query keys must be strings, but found key of type: ${typeof r}`,
r
);
if (r !== "$$ruleParams") {
if (e && !e.entities[r]) {
const s = Object.keys(e.entities);
throw new P(
`Entity '${r}' does not exist in schema. Available entities: ${s.length > 0 ? s.join(", ") : "none"}`,
r
);
}
fr(
t[r],
r,
e,
r,
0
// Start at depth 0 for top-level entities
);
}
}
}, yn = (n) => typeof n != "string" ? !1 : Xe(n) ? !0 : ke(n);
class ne extends Error {
constructor(e) {
super(e), this.name = "TransactionValidationError";
}
}
const hr = (n) => n.length > 0 ? n.join(", ") : "none", co = (n, e) => new ne(
`Entity '${n}' does not exist in schema. Available entities: ${hr(e)}`
), uo = {
string: (n) => typeof n == "string",
number: (n) => typeof n == "number" && !isNaN(n),
boolean: (n) => typeof n == "boolean",
date: (n) => n instanceof Date || typeof n == "string" || typeof n == "number",
json: () => !0
}, lo = (n, e) => n == null ? !0 : uo[e.valueType]?.(n) ?? !1, pr = (n, e) => {
const t = e.entities[n];
if (!t)
throw co(n, Object.keys(e.entities));
return t;
}, at = (n, e, t) => {
const r = pr(n, t);
if (typeof e != "object" || e === null)
throw new ne(
`Arguments for data operation on entity '${n}' must be an object, but received: ${typeof e}`
);
for (const [s, i] of Object.entries(e)) {
if (s === "id") continue;
const o = r.attrs[s];
if (o && !lo(i, o))
throw new ne(
`Invalid value for attribute '${s}' in entity '${n}'. Expected ${o.valueType}, but received: ${typeof i}`
);
}
}, bn = (n, e, t) => {
const r = pr(n, t);
if (typeof e != "object" || e === null)
throw new ne(
`Arguments for link operation on entity '${n}' must be an object, but received: ${typeof e}`
);
for (const [s, i] of Object.entries(e)) {
if (!r.links[s]) {
const a = Object.keys(r.links);
throw new ne(
`Link '${s}' does not exist on entity '${n}'. Available links: ${hr(a)}`
);
}
if (i != null) {
if (Array.isArray(i)) {
for (const a of i)
if (!yn(a))
throw new ne(
`Invalid entity ID in link '${s}' for entity '${n}'. Expected a UUID or a lookup, but received: ${a}`
);
} else if (!yn(i))
throw new ne(
`Invalid UUID in link '${s}' for entity '${n}'. Expected a UUID, but received: ${i}`
);
}
}
}, fo = {
create: at,
update: at,
merge: at,
link: bn,
unlink: bn,
delete: () => {
}
}, ho = (n, e) => {
if (!e) return;
const [t, r, s, i] = n;
if (!Array.isArray(s) && !ke(s))
throw new ne(
`Invalid id for entity '${r}'. Expected a UUID, but received: ${s}`
);
if (typeof r != "string")
throw new ne(
`Entity name must be a string, but received: ${typeof r}`
);
const o = fo[t];
o && i !== void 0 && o(r, i, e);
}, po = (n, e) => {
const t = Array.isArray(n) ? n : [n];
for (const r of t) {
if (!r || typeof r != "object")
throw new ne(
`Transaction chunk must be an object, but received: ${typeof r}`
);
if (!Array.isArray(r.__ops))
throw new ne(
`Transaction chunk must have __ops array, but received: ${typeof r.__ops}`
);
for (const s of r.__ops) {
if (!Array.isArray(s))
throw new ne(
`Transaction operation must be an array, but received: ${typeof s}`
);
ho(s, e);
}
}
};
let yr = 0;
class gn {
type = "ws";
conn;
id;
onopen;
onmessage;
onclose;
onerror;
constructor(e) {
this.id = `${this.type}_${yr++}`, this.conn = new WebSocket(e), this.conn.onopen = (t) => {
this.onopen && this.onopen({ target: this });
}, this.conn.onmessage = (t) => {
this.onmessage && this.onmessage({
target: this,
message: JSON.parse(t.data.toString())
});
}, this.conn.onclose = (t) => {
this.onclose && this.onclose({ target: this });
}, this.conn.onerror = (t) => {
this.onerror && this.onerror({ target: this });
};
}
close() {
this.conn.close();
}
isOpen() {
return this.conn.readyState === (WebSocket.OPEN ?? 1);
}
isConnecting() {
return this.conn.readyState === (WebSocket.CONNECTING ?? 0);
}
send(e) {
return this.conn.send(JSON.stringify(e));
}
}
class yo {
type = "sse";
initParams = null;
sendQueue = [];
sendPromise;
closeFired = !1;
sseInitTimeout = void 0;
ES;
messageUrl;
conn;
url;
id;
onopen;
onmessage;
onclose;
onerror;
constructor(e, t, r) {
this.id = `${this.type}_${yr++}`, this.url = t, this.messageUrl = r || this.url, this.ES = e, this.conn = new e(t), this.sseInitTimeout = setTimeout(() => {
this.initParams || this.handleError();
}, 1e4), this.conn.onmessage = (s) => {
const i = JSON.parse(s.data);
if (Array.isArray(i))
for (const o of i)
this.handleMessage(o);
else
this.handleMessage(i);
}, this.conn.onerror = (s) => {
this.handleError();
};
}
handleMessage(e) {
if (e.op === "sse-init") {
this.initParams = {
machineId: e["machine-id"],
sessionId: e["session-id"],
sseToken: e["sse-token"]
}, this.onopen && this.onopen({ target: this }), clearTimeout(this.sseInitTimeout);
return;
}
this.onmessage && this.onmessage({
target: this,
message: e
});
}
// Runs the onerror and closes the connection
handleError() {
try {
this.onerror && this.onerror({ target: this });
} finally {
this.handleClose();
}
}
handleClose() {
this.conn.close(), this.onclose && !this.closeFired && (this.closeFired = !0, this.onclose({ target: this }));
}
async postMessages(e) {
try {
(await fetch(this.messageUrl, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
machine_id: this.initParams?.machineId,
session_id: this.initParams?.sessionId,
sse_token: this.initParams?.sseToken,
messages: e
})
})).ok || this.handleError();
} catch {
this.handleError();
}
}
async flushQueue() {
if (this.sendPromise || !this.sendQueue.length) return;
const e = this.sendQueue;
this.sendQueue = [];
const t = this.postMessages(e);
this.sendPromise = t, t.then(() => {
this.sendPromise = null, this.flushQueue();
});
}
send(e) {
if (!this.isOpen() || !this.initParams)
throw this.isConnecting() ? new Error(
"Failed to execute 'send' on 'EventSource': Still in CONNECTING state."
) : this.conn.readyState === this.ES.CLOSED ? new Error("EventSource is already in CLOSING or CLOSED state.") : new Error("EventSource is in invalid state.");
this.sendQueue.push(e), this.flushQueue();
}
isOpen() {
return this.conn.readyState === this.ES.OPEN && this.initParams !== null;
}
isConnecting() {
return this.conn.readyState === this.ES.CONNECTING || this.conn.readyState === this.ES.OPEN && this.initParams === null;
}
close() {
this.handleClose();
}
}
function bo(n, e) {
const t = n.values;
if (t) {
const r = Fn(t.attrsStore, null);
if (r) {
for (const s of t.entities || [])
s.store.useDateObjects = e, s.store = Nn(r, s.store);
t.attrsStore = r;
}
}
return n;
}
function go(n, e) {
if (e.values) {
const t = [];
for (const r of e.values?.entities) {
const s = Ln(r.store);
t.push({ ...r, store: s });
}
return {
...e,
values: { attrsStore: e.values.attrsStore.toJSON(), entities: t }
};
} else
return e;
}
function mo(n, e, t) {
const r = e?.state?.txId, s = t?.state?.txId;
return r && (!s || r > s) ? e : s && (!r || s > r) ? t : e || t;
}
function ct(n, e, t) {
return qt(
{ store: e, attrsStore: t, pageInfo: null, aggregate: null },
n.query
).data[n.table][0];
}
function mn(n, e, t, r) {
const s = U(t, n.table, "id")?.id;
if (!s)
return -1;
const i = Ie(e.eav, [r, s, r]);
return i ? i[3] : -1;
}
function wn(n, e, t) {
for (const { action: r, triple: s } of t)
switch (r) {
case "added":
zn(n, e, s);
break;
case "removed":
Kn(n, e, s);
break;
}
}
function wo(n, e, t) {
const r = {};
for (const { action: s, triple: i } of t) {
const [o, a, c] = i, u = e.getAttr(a)?.["forward-identity"]?.[2];
if (!u) continue;
const l = r[o] ?? {};
r[o] = l;
const f = l[u] ?? {};
switch (s) {
case "added":
f.newValue = c;
break;
case "removed":
f.oldValue === void 0 && (f.oldValue = c);
break;
}
l[u] = f;
}
for (const [s, i] of Object.entries(r))
for (const [o, { oldValue: a, newValue: c }] of Object.entries(i))
a === c && delete i[o];
return r;
}
function Ke(n, e) {
return { [n.table]: e.map((t) => t.entity) };
}
function _o(n, e) {
if (n.orderFieldType)
return n.orderFieldType;
const t = n.orderField === "serverCreatedAt" ? "number" : U(e(), n.table, n.orderField)?.["checked-data-type"];
return n.orderFieldType = t, t;
}
function So(n, e, t) {
const r = e;
if (n.orderField === "serverCreatedAt") {
t.sort(
n.orderDirection === "asc" ? function(o, a) {
return Pe(
o.entity.id,
o.serverCreatedAt,
a.entity.id,
a.serverCreatedAt,
r
);
} : function(o, a) {
return Pe(
a.entity.id,
a.serverCreatedAt,
o.entity.id,
o.serverCreatedAt,
r
);
}
);
return;
}
const s = n.orderField;
t.sort(
n.orderDirection === "asc" ? function(o, a) {
return Pe(
o.entity.id,
o.entity[s],
a.entity.id,
a.entity[s],
r
);
} : function(o, a) {
return Pe(
a.entity.id,
a.entity[s],
o.entity.id,
o.entity[s],
r
);
}
);
}
var To = /* @__PURE__ */ ((n) => (n.InitialSyncBatch = "InitialSyncBatch", n.InitialSyncComplete = "InitialSyncComplete", n.LoadFromStorage = "LoadFromStorage", n.SyncTransaction = "SyncTransaction", n.Error = "Error", n))(To || {});
class vo {
trySend;
subs;
// Using any for the SyncCallback because we'd need Reactor to be typed
callbacks = {};
config;
idToHash = {};
log;
createStore;
getAttrs;
constructor(e, t, r, s, i, o) {
this.trySend = e, this.config = r, this.log = s, this.createStore = i, this.getAttrs = o, this.subs = new It({
persister: t,
merge: mo,
serialize: go,
parse: (a, c) => bo(c, this.config.useDateObjects),
objectSize: (a) => a.values?.entities.length || 0,
logger: s,
gc: {
maxAgeMs: 1e3 * 60 * 60 * 24 * 7 * 52,
// 1 year
maxEntries: 1e3,
// Size of each sub is the number of entity
maxSize: 1e6
// 1 million entities
}
});
}
beforeUnload() {
this.subs.flush();
}
subscribe(e, t) {
const r = G(e);
return this.callbacks[r] = this.callbacks[r] || [], this.callbacks[r].push(t), this.initSubscription(e, r, t), (s) => {
this.unsubscribe(r, t, s?.keepSubscription);
};
}
unsubscribe(e, t, r) {
const s = (this.callbacks[e] || []).filter((i) => i !== t);
if (this.callbacks[e] = s, !s.length) {
delete this.callbacks[e];
const i = this.subs.currentValue[e];
i?.state && this.clearSubscriptionData(
i.state.subscriptionId,
!!r
), r || this.subs.updateInPlace((o) => {
delete o[e];
});
}
}
sendStart(e) {
this.trySend(j(), {
op: "start-sync",
q: e
});
}
sendResync(e, t, r) {
this.idToHash[t.subscriptionId] = e.hash, this.trySend(t.subscriptionId, {
op: "resync-table",
"subscription-id": t.subscriptionId,
"tx-id": r,
token: t.token
});
}
sendRemove(e, t) {
this.trySend(j(), {
op: "remove-sync",
"subscription-id": e.subscriptionId,
"keep-subscription": t
});
}
async initSubscription(e, t, r) {
await this.subs.waitForKeyToLoad(t);
const s = this.subs.currentValue[t];
if (s && s.state && s.state.txId) {
this.sendResync(s, s.state, s.state.txId), s.values?.entities && r && r({
type: "LoadFromStorage",
data: Ke(s, s.values?.entities)
});
return;
}
const i = Object.keys(e)[0], o = e[i]?.$?.order || { serverCreatedAt: "asc" }, [a, c] = Object.entries(o)[0];
this.subs.updateInPlace((u) => {
u[t] = {
query: e,
hash: t,
table: i,
orderDirection: c,
orderField: a,
createdAt: Date.now(),
updatedAt: Date.now()
};
}), this.sendStart(e);
}
async flushPending() {
for (const e of Object.keys(this.callbacks)) {
await this.subs.waitForKeyToLoad(e);
const t = this.subs.currentValue[e];
t ? await this.initSubscription(t.query, t.hash) : this.log.error("Missing sub for hash in flushPending", e);
}
}
onStartSyncOk(e) {
const t = e["subscription-id"], r = e.q, s = G(r);
this.idToHash[t] = s, this.subs.updateInPlace((i) => {
const o = i[s];
if (!o)
return this.log.error(
"Missing sub for hash",
s,
"subscription-id",
t,
"query",
r
), i;
o.state = {
subscriptionId: t,
token: e.token
};
});
}
notifyCbs(e, t) {
for (const r of this.callbacks[e] || [])
r(t);
}
onSyncLoadBatch(e) {
const t = e["subscription-id"], r = e["join-rows"], s = this.idToHash[t];
if (!s) {
this.log.error("Missing hash for subscription", e);
return;
}
const i = [], o = this.subs.currentValue[s];
if (!o) {
this.log.error("Missing sub for hash", s, e);
return;
}
const a = o.values ?? {
entities: [],
attrsStore: this.getAttrs()
};
o.values = a;
const c = a.entities;
for (const u of r) {
const l = this.createStore(u), f = ct(o, l, a.attrsStore);
c.push({
store: l,
entity: f,
serverCreatedAt: mn(
o,
l,
a.attrsStore,
f.id
)
}), i.push(f);
}
this.subs.updateInPlace((u) => {
u[s] = o, u[s].updatedAt = Date.now();
}), o.values && this.notifyCbs(s, {
type: "InitialSyncBatch",
data: Ke(o, o.values.entities),
batch: i
});
}
onSyncInitFinish(e) {
const t = e["subscription-id"], r = this.idToHash[t];
if (!r) {
this.log.error("Missing hash for subscription", e);
return;
}
this.subs.updateInPlace((i) => {
const o = i[r];
if (!o) {
this.log.error("Missing sub for hash", r, e);
return;
}
const a = o.state;
if (!a)
return this.log.error("Sub never set init, missing result", o, e), i;
a.txId = e["tx-id"], o.updatedAt = Date.now();
});
const s = this.subs.currentValue[r];
s && this.notifyCbs(r, {
type: "InitialSyncComplete",
data: Ke(s, s.values?.entities || [])
});
}
onSyncUpdateTriples(e) {
const t = e["subscription-id"], r = this.idToHash[t];
if (!r) {
this.log.error("Missing hash for subscription", e);
return;
}
const s = this.subs.currentValue[r];
if (!s) {
this.log.error("Missing sub for hash", r, e);
return;
}
const i = s.state;
if (!i) {
this.log.error("Missing state for sub", s, e);
return;
}
for (const o of e.txes) {
if (i.txId && i.txId >= o["tx-id"])
continue;
i.txId = o["tx-id"];
const a = [], c = {};
for (const m of o.changes) {
const b = c[m.triple[0]] ?? [];
c[m.triple[0]] = b, b.push(m);
}
const u = s.values ?? {
entities: [],
attrsStore: this.getAttrs()
}, l = u.entities;
s.values = u;
const f = [];
e: for (const [m, b] of Object.entries(c))
for (let y = 0; y < l.length; y++) {
const g = l[y];
if (Xr(g.store, m)) {
wn(g.store, u.attrsStore, b);
const A = ct(s, g.store, u.attrsStore), R = wo(
g.store,
u.attrsStore,
b
)[m];
A ? (f.push({
oldEntity: g.entity,
newEntity: A,
changedFields: R || {}
}), g.entity = A) : a.push(y), delete c[m];
continue e;
}
}
const d = [];
for (const [m, b] of Object.entries(c)) {
const y = this.createStore([]);
wn(y, u.attrsStore, b);
const g = ct(s, y, u.attrsStore);
if (!g) {
this.log.error("No entity found after applying change", {
sub: s,
changes: b,
store: y
});
continue;
}
l.push({
store: y,
entity: g,
serverCreatedAt: mn(
s,
y,
u.attrsStore,
g.id
)
}), d.push(g);
}
const h = [];
for (const m of a.sort().reverse())
h.push(l[m].entity), l.splice(m, 1);
const p = _o(s, this.getAttrs);
So(s, p, l), this.notifyCbs(r, {
type: "SyncTransaction",
data: Ke(s, s.values?.entities),
added: d,
removed: h,
updated: f
});
}
this.subs.updateInPlace((o) => {
o[r] = s, o[r].updatedAt = Date.now();
});
}
clearSubscriptionData(e, t) {
const r = this.idToHash[e];
if (r) {
delete this.idToHash[e];
const s = this.subs.currentValue[r];
if (s.state && this.sendRemove(s.state, t), t ? this.subs.unloadKey(r) : this.subs.updateInPlace((i) => {
delete i[r];
}), s)
return s;
}
}
onStartSyncError(e) {
const t = G(e["original-event"].q), r = {
message: e.message || "Uh-oh, something went wrong. Ping Joe & Stopa.",
status: e.status,
type: e.type,
hint: e.hint
}, s = Object.keys(e["original-event"].q)[0];
this.notifyCbs(t, {
type: "Error",
data: { [s]: [] },
error: r
});
}
onResyncError(e) {
const t = e["original-event"]["subscription-id"], r = this.clearSubscriptionData(t, !1);
r && this.initSubscription(r.query, r.hash);
}
}
function Ao({
WStream: n,
opts: e,
startStream: t,
appendStream: r,
registerStream: s
}) {
const i = e.clientId;
let o = null, a = null, c = null;
const u = j();
let l = !1, f = !1;
const d = [], h = [], p = [];
let m = !1, b = 0, y = 0;
const g = [], A = new TextEncoder();
function R() {
f = !0;
for (const _ of d)
_(a ?? void 0);
}
function k(_) {
return d.push(_), f && _(a ?? void 0), () => {
const v = d.indexOf(_);
v !== -1 && d.splice(v, 1);
};
}
function N(_) {
return p.push(_), () => {
const v = p.indexOf(_);
v !== -1 && p.splice(v, 1);
};
}
e.waitUntil && e.waitUntil(
new Promise((_) => {
p.push(_);
})
);
function C() {
for (const _ of p)
try {
_();
} catch {
}
}
function O(_) {
return h.push(_), o && _(o), () => {
const v = h.indexOf(_);
v !== -1 && h.splice(v, 1);
};
}
function q(_) {
o = _;
for (const v of h)
v(o);
}
function M() {
m = !0;
}
function w(_) {
let v = b, F = 0, B = 0;
for (const { byteLen: re } of g) {
const ue = v + re;
if (ue > _)
break;
v = ue, F++, B += re;
}
F > 0 && (b += B, y -= B, g.splice(0, F));
}
function S(_, v) {
a = v, R(), _.error(v), C();
}
async function T() {
const _ = await t({
clientId: i,
reconnectToken: u,
ruleParams: e.ruleParams
});
switch (_.type) {
case "ok": {
const { streamId: v, offset: F } = _;
o = v, w(F), g.length && r({
streamId: v,
chunks: g.map((B) => B.chunk),
offset: b
}), m = !1;
break;
}
case "disconnect": {
M();
break;
}
case "error": {
c && S(c, _.error);
break;
}
}
}
function E() {
M(), T();
}
function D({ offset: _, done: v }) {
w(_), v && (l = !0, C());
}
function Z(_) {
return l ? (S(_, new L("Stream has been closed.")), null) : o || (S(_, new L("Stream has not been initialized.")), null);
}
async function Q(_) {
c = _;
let v = !0, F = 0;
for (; v; ) {
let B = Date.now() + Math.min(15e3, 500 * (F - 1));
v = !1;
const re = await t({
clientId: e.clientId,
reconnectToken: u,
ruleParams: e.ruleParams
});
switch (re.type) {
case "ok": {
const { streamId: ue, offset: st } = re;
if (st !== 0) {
const he = new L("Write stream is corrupted");
S(_, he);
return;
}
q(ue), s(ue, {
onDisconnect: M,
onFlush: D,
onConnectionReconnect: T,
onAppendFailed: E
}), m = !1;
return;
}
case "disconnect": {
v = !0, M(), F++, await new Promise((ue) => {
setTimeout(ue, Math.max(0, B - Date.now()));
});
break;
}
case "error": {
S(_, re.error);
return;
}
}
}
}
class z extends n {
constructor(v, F) {
super(v, F);
}
async streamId() {
return o || new Promise((v, F) => {
const B = [], re = () => {
for (const he of B)
he();
}, ue = (he) => {
v(he), re();
}, st = (he) => {
F(he || new L("Stream is closed.")), re();
};
B.push(O(ue)), B.push(k(st));
});
}
}
return {
stream: new z({
// TODO(dww): accept a storage so that write streams can survive across
// browser restarts
async start(_) {
try {
await Q(_);
} catch (v) {
S(_, v);
}
},
write(_, v) {
const F = Z(v);
if (F) {
const B = A.encode(_).length;
g.push({ chunk: _, byteLen: B });
const re = b + y;
y += B, m || r({ streamId: F, chunks: [_], offset: re });
}
},
close() {
o ? r({
streamId: o,
chunks: [],
offset: b + y,
isDone: !0
}) : C(), R();
},
abort(_) {
o ? r({
streamId: o,
chunks: [],
offset: b + y,
isDone: !0,
abortReason: _
}) : C(), R();
}
}),
addCompleteCb: N,
closed() {
return f;
}
};
}
class ko {
items = [];
resolvers = [];
isClosed = !1;
constructor() {
}
push(e) {
if (this.isClosed) return;
const t = this.resolvers.shift();
t ? t({ value: e, done: !1 }) : this.items.push(e);
}
close() {
for (this.isClosed = !0; this.resolvers.length > 0; )
this.resolvers.shift()({ value: void 0, done: !0 });
}
async *[Symbol.asyncIterator]() {
for (; ; )
if (this.items.length > 0)
yield this.items.shift();
else {
if (this.isClosed)
return;
{
const { value: e, done: t } = await new Promise((r) => {
this.resolvers.push(r);
});
if (t || !e)
return;
yield e;
}
}
}
}
function Oo({
RStream: n,
opts: e,
startStream: t,
cancelStream: r
}) {
let s = e.byteOffset || 0, i = !1;
const o = new TextDecoder("utf-8"), a = new TextEncoder();
let c, u = !1;
const l = [], f = [];
let d = null, h = null;
function p(C) {
u = !0;
for (const O of l)
O(C);
}
function m(C) {
return l.push(C), () => {
const O = l.indexOf(C);
O !== -1 && l.splice(O, 1);
};
}
function b(C) {
return f.push(C), d && C(d), () => {
const O = f.indexOf(C);
O !== -1 && f.splice(O, 1);
};
}
function y(C, O) {
h = O, C.error(O), p(O);
}
let g = 0;
async function A(C, O) {
c = j();
const q = { ...C || {}, eventId: c };
for await (const M of t(q)) {
if (i)
return;
if (M.type === "reconnect")
return { retry: !0 };
if (M.type === "error") {
y(O, M.error);
return;
}
if (M.offset > s) {
y(O, new L("Stream is corrupted.")), i = !0;
return;
}
d = M.streamId;
for (const S of f)
S(d);
let w = s - M.offset;
if (M.files && M.files.length) {
const S = new AbortController();
let T = fetch(M.files[0].url, {
signal: S.signal
});
for (let E = 0; E < M.files.length; E++) {
const D = M.files[E + 1], Q = await T;
if (D && (T = fetch(D.url, { signal: S.signal })), !Q.ok) {
if (g++, g > 10) {
y(O, new L("Unable to process stream."));
return;
}
return { retry: !0 };
}
if (Q.body) {
const z = Q.body.getReader();
try {
for (; ; ) {
const { done: te, value: _ } = await z.read();
if (te)
break;
if (i) {
S.abort();
return;
}
let v = _;
if (w > 0 && (v = _.subarray(w), w -= _.length - v.length), !v.length)
continue;
s += v.length;
const F = o.decode(v);
O.enqueue(F);
}
} finally {
z.releaseLock();
}
} else {
const z = await Q.arrayBuffer();
let te = z;
if (i) {
S.abort();
return;
}
if (w > 0 && (te = new Uint8Array(z).subarray(w), w -= z.byteLength - te.length), !te.byteLength)
continue;
s += te.byteLength;
const _ = o.decode(te);
O.enqueue(_);
}
}
}
if (g = 0, M.content) {
let S = M.content, T = a.encode(M.content);
if (w > 0) {
const E = T.subarray(w);
if (w -= T.length - E.length, !E.length)
continue;
T = E, S = o.decode(E);
}
s += T.length, O.enqueue(S);
}
}
}
async function R(C) {
let O = !0, q = 0;
for (; O; ) {
O = !1;
let M = Date.now() + Math.min(15e3, 500 * (q - 1));
(await A(
{ ...e, offset: s },
C
))?.retry && (O = !0, q++, M < Date.now() - 3e5 && (q = 0), await new Promise((S) => {
setTimeout(S, Math.max(0, M - Date.now()));
}));
}
!i && !u && (C.close(), p());
}
class k extends n {
constructor(O, q) {
super(O, q);
}
async streamId() {
if (d)
return d;
if (h)
throw h;
return new Promise((O, q) => {
const M = [], w = () => {
for (const E of M)
E();
}, S = (E) => {
O(E), w();
}, T = (E) => {
q(E || new L("Stream is closed.")), w();
};
M.push(b(S)), M.push(m(T));
});
}
}
return {
stream: new k({
start(C) {
R(C);
},
cancel(C) {
i = !0, c && r({ eventId: c }), p();
}
}),
addCloseCb: m,
closed() {
return u;
}
};
}
class Io {
trySend;
WStream;
RStream;
writeStreams = {};
startWriteStreamCbs = {};
readStreamIterators = {};
log;
activeStreams = /* @__PURE__ */ new Set();
constructor({
WStream: e,
RStream: t,
trySend: r,
log: s
}) {
this.WStream = e, this.RStream = t, this.trySend = r, this.log = s;
}
createWriteStream(e) {
const { stream: t, addCompleteCb: r } = Ao({
WStream: this.WStream,
startStream: this.startWriteStream.bind(this),
appendStream: this.appendStream.bind(this),
registerStream: this.registerWriteStream.bind(this),
opts: e
});
return this.activeStreams.add(t), r(() => {
this.activeStreams.delete(t);
}), t;
}
createReadStream(e) {
const { stream: t, addCloseCb: r } = Oo({
RStream: this.RStream,
opts: e,
startStream: this.startReadStream.bind(this),
cancelStream: this.cancelReadStream.bind(this)
});
return this.activeStreams.add(t), r(() => {
this.activeStreams.delete(t);
}), t;
}
startWriteStream(e) {
const t = j();
let r = null;
const s = new Promise((o) => {
r = o;
});
this.startWriteStreamCbs[t] = r;
const i = {
op: "start-stream",
"client-id": e.clientId,
"reconnect-token": e.reconnectToken
};
return e.ruleParams && (i["rule-params"] = e.ruleParams), this.trySend(t, i), s;
}
registerWriteStream(e, t) {
this.writeStreams[e] = t;
}
appendStream({
streamId: e,
chunks: t,
isDone: r,
offset: s,
abortReason: i
}) {
const o = {
op: "append-stream",
"stream-id": e,
chunks: t,
offset: s,
done: !!r
};
i && (o["abort-reason"] = i), this.trySend(j(), o);
}
onAppendFailed(e) {
const t = this.writeStreams[e["stream-id"]];
t && t.onAppendFailed();
}
onStartStreamOk(e) {
const t = this.startWriteStreamCbs[e["client-event-id"]];
if (!t) {
this.log.info("No stream for start-stream-ok", e);
return;
}
t({ type: "ok", streamId: e["stream-id"], offset: e.offset }), delete this.startWriteStreamCbs[e["client-event-id"]];
}
onStreamFlushed(e) {
const t = e["stream-id"], r = this.writeStreams[t];
if (!r) {
this.log.info("No stream cbs for stream-flushed", e);
return;
}
r.onFlush({ offset: e.offset, done: e.done }), e.done && delete this.writeStreams[t];
}
startReadStream({
eventId: e,
clientId: t,
streamId: r,
offset: s,
ruleParams: i
}) {
const o = { op: "subscribe-stream" };
if (!r && !t)
throw new Error(
"Must provide one of streamId or clientId to subscribe to the stream."
);
r && (o["stream-id"] = r), t && (o["client-id"] = t), s && (o.offset = s), i && (o["rule-params"] = i);
const a = new ko();
return this.readStreamIterators[e] = a, this.trySend(e, o), a;
}
cancelReadStream({ eventId: e }) {
const t = {
op: "unsubscribe-stream",
"subscribe-event-id": e
};
this.trySend(j(), t), delete this.readStreamIterators[e];
}
onStreamAppend(e) {
const t = e["client-event-id"], r = this.readStreamIterators[t];
if (!r) {
this.log.info("No iterator for read stream", e);
return;
}
if (e.error) {
e.retry ? r.push({ type: "reconnect" }) : r.push({
type: "error",
error: new L(e.error)
}), r.close(), delete this.readStreamIterators[t];
return;
}
r.push({
type: "append",
offset: e.offset,
files: e.files,
content: e.content,
streamId: e["stream-id"]
}), e.done && (r.close(), delete this.readStreamIterators[t]);
}
onConnectionStatusChange(e) {
for (const t of Object.values(this.startWriteStreamCbs))
t({ type: "disconnect" });
if (this.startWriteStreamCbs = {}, e !== ae.AUTHENTICATED)
for (const { onDisconnect: t } of Object.values(this.writeStreams))
t();
else {
for (const { onConnectionReconnect: t } of Object.values(
this.writeStreams
))
t();
for (const t of Object.values(this.readStreamIterators))
t.push({ type: "reconnect" }), t.close();
this.readStreamIterators = {};
}
}
onRecieveError(e) {
const t = e["original-event"];
switch (t.op) {
case "append-stream": {
const r = t["stream-id"];
this.writeStreams[r]?.onAppendFailed();
break;
}
case "start-stream": {
const r = e["client-event-id"], s = this.startWriteStreamCbs[r];
s && (s({
type: "error",
error: new L(e.message || "Unknown error", e.hint)
}), delete this.startWriteStreamCbs[r]);
break;
}
case "subscribe-stream": {
const r = e["client-event-id"], s = this.readStreamIterators[r];
s && (s.push({
type: "error",
error: new L(e.message || "Unknown error", e.hint)
}), s.close(), delete this.readStreamIterators[r]);
break;
}
}
}
hasActiveStreams() {
return this.activeStreams.size > 0;
}
}
const ae = {
CONNECTING: "connecting",
OPENED: "opened",
AUTHENTICATED: "authenticated",
CLOSED: "closed",
ERRORED: "errored"
}, Co = 3e4, Eo = 3e4, Mo = 200, Po = 1e3 * 60, jo = Po * 60 * 24, _n = "lastSyncedUserCookie", $o = {
apiURI: "https://api.instantdb.com",
websocketURI: "wss://api.instantdb.com/runtime/session"
}, ut = "_instant_oauth_redirect", lt = "_instant_extra_fields_id", qe = "oauthExtraFields", me = "currentUser";
function xo({
transportType: n,
appId: e,
apiURI: t,
wsURI: r,
EventSourceImpl: s
}) {
if (!s)
return new gn(`${r}?app_id=${e}`);
switch (n) {
case "ws":
return new gn(`${r}?app_id=${e}`);
case "sse":
return new yo(
s,
`${t}/runtime/sse?app_id=${e}`
);
default:
throw new Error("Unknown transport type " + n);
}
}
function Ro() {
return typeof window < "u" || typeof chrome < "u";
}
const Sn = {
"set-presence": !0,
"set-presence-ok": !0,
"refresh-presence": !0,
"patch-presence": !0
};
function Do(n, e) {
const t = typeof n == "string" ? JSON.parse(n) : n;
if (t?.result?.store) {
const r = Fn(
t.result.attrsStore,
t.result.store
);
if (r) {
const s = t.result.store;
t.result.store = Nn(r, {
...s,
useDateObjects: e
}), t.result.attrsStore = r;
}
}
return t;
}
function Uo(n, e) {
const { result: t, ...r } = e, s = (
/** @type {import('./reactorTypes.ts').QuerySubInStorage} */
r
);
if (t) {
const i = {
...t,
store: Ln(t.store),
attrsStore: t.attrsStore.toJSON()
};
s.result = i;
}
return s;
}
function Lo(n, e) {
return n === "pendingMutations" ? new Map(typeof e == "string" ? JSON.parse(e) : e) : e;
}
function No(n, e) {
return n === "pendingMutations" ? [...e.entries()] : e;
}
function Fo(n, e, t) {
const r = e?.result, s = t?.result;
return r && !s && t && (t.result = r), t || e;
}
function dt(n) {
return [...n].sort((e, t) => {
const [r, s] = e, [i, o] = t, a = s.order || 0, c = o.order || 0;
return a == c ? r < i ? -1 : r > i ? 1 : 0 : a - c;
});
}
class Ko {
/** @type {s.AttrsStore | undefined} */
attrs;
_isOnline = !0;
_isShutdown = !1;
status = ae.CONNECTING;
/** @type {PersistedObject<string, QuerySub, QuerySubInStorage>} */
querySubs;
/** @type {PersistedObject} */
kv;
/** @type {SyncTable} */
_syncTable;
/** @type {InstantStream} */
_instantStream;
/** @type {Record<string, Array<{ q: any, cb: (data: any) => any }>>} */
queryCbs = {};
/** @type {Record<string, Array<{ q: any, eventId: string, dfd: Deferred }>>} */
queryOnceDfds = {};
authCbs = [];
attrsCbs = [];
mutationErrorCbs = [];
connectionStatusCbs = [];
appStatusCbs = [];
/**
* Carries the raw server status off the public type: `disabled` is an
* operator-level state we don't surface to apps.
* @type {import('./clientTypes.ts').AppStatusState & { status?: 'active' | 'read-only' | 'disabled' }}
*/
_appStatusState = { isLoading: !0, isReadOnly: void 0 };
config;
mutationDeferredStore = /* @__PURE__ */ new Map();
_reconnectTimeoutId = null;
_reconnectTimeoutMs = 0;
/** @type {Connection} */
_transport;
/** @type {TransportType} */
_transportType = "ws";
/** @type {EventSourceConstructor} */
_EventSource;
/** @type {boolean | null} */
_wsOk = null;
_localIdPromises = {};
_errorMessage = null;
/** @type {Promise<null | {error: {message: string}}> | null}**/
_oauthCallbackResponse = null;
/** @type {null | import('./utils/linkIndex.ts').LinkIndex}} */
_linkIndex = null;
/** @type BroadcastChannel | undefined */
_broadcastChannel;
/** @type {Record<string, {roomType: string; isConnected: boolean; error: any}>} */
_rooms = {};
/** @type {Record<string, boolean>} */
_roomsPendingLeave = {};
_presence = {};
_broadcastQueue = [];
_broadcastSubs = {};
/** @type {{isLoading: boolean; error: any | undefined, user: any | undefined}} */
_currentUserCached = { isLoading: !0, error: void 0, user: void 0 };
_beforeUnloadCbs = [];
_dataForQueryCache = {};
/** @type {Logger} */
_log;
_pendingTxCleanupTimeout;
_pendingMutationCleanupThreshold;
_inFlightMutationEventIds = /* @__PURE__ */ new Set();
/** @type FrameworkClient | null */
_frameworkClient = null;
constructor(e, t = sr, r = ir, s, i) {
if (this._EventSource = i, this.config = { ...$o, ...e }, this.queryCacheLimit = this.config.queryCacheLimit ?? 10, this._pendingTxCleanupTimeout = this.config.pendingTxCleanupTimeout ?? Eo, this._pendingMutationCleanupThreshold = this.config.pendingMutationCleanupThreshold ?? Mo, this._log = ro(
e.verbose || zt || or,
() => this._reactorStats(),
e.logger
), this.versions = { ...s || {}, "@instantdb/core": ur }, this.config.schema && (this._linkIndex = Ct(this.config.schema)), !!Ro()) {
if (!e.appId)
throw new Error("Instant must be initialized with an appId.");
if (!ke(e.appId))
throw new Error(
`Instant must be initialized with a valid appId. \`${e.appId}\` is not a valid uuid.`
);
typeof BroadcastChannel == "function" && (this._broadcastChannel = new BroadcastChannel("@instantdb"), this._broadcastChannel.addEventListener("message", async (o) => {
try {
if (o.data?.type === "auth") {
const a = await this.getCurrentUser({
forceReadFromStorage: !0
});
await this.updateUser(a.user).catch((c) => {
this._log.error("[error] update user", c);
});
}
} catch (a) {
this._log.error("[error] handle broadcast channel", a);
}
})), this._initStorage(t), this._syncTable = new vo(
this._trySendAuthed.bind(this),
new t(this.config.appId, "syncSubs"),
{
useDateObjects: this.config.useDateObjects
},
this._log,
(o) => Te(
this.ensureAttrs(),
o,
this.config.enableCardinalityInference,
this.config.useDateObjects
),
() => this.ensureAttrs()
), this._instantStream = new Io({
WStream: this.config.WritableStream || WritableStream,
RStream: this.config.ReadableStream || ReadableStream,
trySend: this._trySendAuthed.bind(this),
log: this._log
}), this._oauthCallbackResponse = this._oauthLoginInit(), this.setupUserSyncTimer(), r.getIsOnline().then((o) => {
this._isOnline = o, this._startSocket(), r.listen((a) => {
a !== this._isOnline && (this._log.info("[network] online =", a), this._isOnline = a, this._isOnline ? this._startSocket() : (this._log.info(
"Changing status from",
this.status,
"to",
ae.CLOSED
), this._setStatus(ae.CLOSED)));
});
}), typeof addEventListener < "u" && (this._beforeUnload = this._beforeUnload.bind(this), addEventListener("beforeunload", this._beforeUnload));
}
}
getFrameworkClient() {
return this._frameworkClient;
}
/** @param {FrameworkClient} client */
setFrameworkClient(e) {
this._frameworkClient = e;
}
ensureAttrs() {
if (!this.attrs)
throw new Error("attrs have not loaded.");
return this.attrs;
}
updateSchema(e) {
this.config = {
...this.config,
schema: e,
cardinalityInference: !!e
}, this._linkIndex = e ? Ct(this.config.schema) : null;
}
_reactorStats() {
return {
inFlightMutationCount: this._inFlightMutationEventIds.size,
storedMutationCount: this._pendingMutations().size,
transportType: this._transportType
};
}
_onQuerySubLoaded(e) {
this.kv.waitForKeyToLoad("pendingMutations").then(() => this.notifyOne(e));
}
_initStorage(e) {
this.querySubs = new It({
persister: new e(this.config.appId, "querySubs"),
merge: Fo,
serialize: Uo,
parse: (t, r) => Do(r, this.config.useDateObjects),
// objectSize
objectSize: (t) => t?.result?.store?.triples?.length ?? 0,
logger: this._log,
preloadEntryCount: 10,
gc: {
maxAgeMs: 1e3 * 60 * 60 * 24 * 7 * 52,
// 1 year
maxEntries: 1e3,
// Size of each query is the number of triples
maxSize: 1e6
// 1 million triples
}
}), this.querySubs.onKeyLoaded = (t) => this._onQuerySubLoaded(t), this.kv = new It({
persister: new e(this.config.appId, "kv"),
merge: this._onMergeKv,
serialize: No,
parse: Lo,
objectSize: () => 0,
logger: this._log,
saveThrottleMs: 100,
idleCallbackMaxWaitMs: 100,
// Don't GC the kv store
gc: null
}), this.kv.onKeyLoaded = (t) => {
t === "pendingMutations" && this.notifyAll();
}, this.kv.waitForKeyToLoad("pendingMutations"), this.kv.waitForKeyToLoad(me), this._beforeUnloadCbs.push(() => {
this.kv.flush(), this.querySubs.flush();
});
}
_beforeUnload() {
for (const e of this._beforeUnloadCbs)
e();
this._syncTable.beforeUnload();
}
/**
* @param {'enqueued' | 'pending' | 'synced' | 'timeout' | 'error' } status
* @param {string} eventId
* @param {{message?: string, type?: string, status?: number, hint?: unknown, traceId?: string}} [errorMsg]
*/
_finishTransaction(e, t, r) {
const s = this.mutationDeferredStore.get(t);
this.mutationDeferredStore.delete(t);
const i = e !== "error" && e !== "timeout";
if (!s && !i && console.error("Mutation failed", { status: e, eventId: t, ...r }), !!s)
if (i)
s.resolve({ status: e, eventId: t });
else if (r?.type) {
const { status: o, ...a } = r;
s.reject(
new Le({
// @ts-expect-error body.type is not constant typed
body: a,
status: o ?? 0
})
);
} else
s.reject(
new L(
r?.message || "Unknown error",
r?.hint,
r?.traceId
)
);
}
_setStatus(e, t) {
this.status = e, this._errorMessage = t, this.notifyConnectionStatusSubs(e), this._instantStream.onConnectionStatusChange(e);
}
_onMergeKv = (e, t, r) => {
if (e === "pendingMutations") {
const s = t?.entries() ?? [], i = r?.entries() ?? [], o = new Map([...s, ...i]);
return (t ? this._rewriteMutationsSorted(this.attrs, t) : []).forEach(([c, u]) => {
!r?.pendingMutations?.has(c) && !u["tx-id"] && this._sendMutation(c, u);
}), o;
} else
return r || t;
};
_flushEnqueuedRoomData(e) {
const t = this._presence[e]?.result?.user, r = this._broadcastQueue[e];
if (this._broadcastQueue[e] = [], t && this._trySetPresence(e, t), r)
for (const s of r) {
const { topic: i, roomType: o, data: a } = s;
this._tryBroadcast(e, o, i, a);
}
}
/**
* Does the same thing as add-query-ok
* but called as a result of receiving query info from ssr
* @param {any} q
* @param {{ triples: any; pageInfo: any; }} result
* @param {boolean} enableCardinalityInference
*/
_addQueryData(e, t, r) {
if (!this.attrs)
throw new Error("Attrs in reactor have not been set");
const s = G(e), i = this.ensureAttrs(), o = Te(
this.attrs,
t.triples,
r,
this.config.useDateObjects
);
this.querySubs.updateInPlace((a) => {
a[s] = {
result: {
store: o,
attrsStore: i,
pageInfo: t.pageInfo,
processedTxId: void 0,
isExternal: !0
},
q: e
};
}), this._cleanupPendingMutationsQueries(), this.notifyOne(s), this.notifyOneQueryOnce(s), this._cleanupPendingMutationsTimeout();
}
_handleReceive(e, t) {
const r = !!this.config.schema && ("cardinalityInference" in this.config ? !!this.config.cardinalityInference : !0);
switch (Sn[t.op] || this._log.info("[receive]", e, t.op, t), t.op) {
case "init-ok": {
this._setStatus(ae.AUTHENTICATED), this._reconnectTimeoutMs = 0, this._setAppStatus(t["app-status"]?.status ?? "active"), this._setAttrs(t.attrs), this._flushPendingMessages(), this._sessionId = t["session-id"];
for (const o of Object.keys(this._rooms)) {
const a = this._presence[o]?.result?.user, c = this._rooms[o]?.roomType;
this._tryJoinRoom(c, o, a);
}
break;
}
case "add-query-exists": {
this.notifyOneQueryOnce(G(t.q));
break;
}
case "add-query-ok": {
const { q: o, result: a } = t, c = G(o);
if (!this._hasQueryListeners() && !this.querySubs.currentValue[c])
break;
const u = a?.[0]?.data?.["page-info"], l = a?.[0]?.data?.aggregate, f = fn(a), d = this.ensureAttrs(), h = Te(
d,
f,
r,
this.config.useDateObjects
);
this.querySubs.updateInPlace((p) => {
if (!p[c]) {
this._log.info("Missing value in querySubs", { hash: c, q: o });
return;
}
p[c].result = {
store: h,
attrsStore: d,
pageInfo: u,
aggregate: l,
processedTxId: t["processed-tx-id"]
};
}), this._cleanupPendingMutationsQueries(), this.notifyOne(c), this.notifyOneQueryOnce(c), this._cleanupPendingMutationsTimeout();
break;
}
case "start-sync-ok": {
this._syncTable.onStartSyncOk(t);
break;
}
case "sync-load-batch": {
this._syncTable.onSyncLoadBatch(t);
break;
}
case "sync-init-finish": {
this._syncTable.onSyncInitFinish(t);
break;
}
case "sync-update-triples": {
this._syncTable.onSyncUpdateTriples(t);
break;
}
case "start-stream-ok": {
this._instantStream.onStartStreamOk(t);
break;
}
case "stream-flushed": {
this._instantStream.onStreamFlushed(t);
break;
}
case "append-failed": {
this._instantStream.onAppendFailed(t);
break;
}
case "stream-append": {
this._instantStream.onStreamAppend(t);
break;
}
case "refresh-ok": {
const { computations: o, attrs: a } = t, c = t["processed-tx-id"];
a && this._setAttrs(a), this._cleanupPendingMutationsTimeout();
const u = this._rewriteMutations(
this.ensureAttrs(),
this._pendingMutations(),
c
);
u !== this._pendingMutations() && this.kv.updateInPlace((d) => {
d.pendingMutations = u;
});
const l = dt(u.entries()), f = o.map((d) => {
const h = d["instaql-query"], p = d["instaql-result"], m = G(h), b = fn(p), y = this.ensureAttrs(), g = Te(
y,
b,
r,
this.config.useDateObjects
), { store: A, attrsStore: R } = this._applyOptimisticUpdates(
g,
y,
l,
c
), k = p?.[0]?.data?.["page-info"], N = p?.[0]?.data?.aggregate;
return {
q: h,
hash: m,
store: A,
attrsStore: R,
pageInfo: k,
aggregate: N
};
});
f.forEach(
({ hash: d, q: h, store: p, attrsStore: m, pageInfo: b, aggregate: y }) => {
this.querySubs.updateInPlace((g) => {
if (!g[d]) {
this._log.error("Missing value in querySubs", { hash: d, q: h });
return;
}
g[d].result = {
store: p,
attrsStore: m,
pageInfo: b,
aggregate: y,
processedTxId: c
};
});
}
), this._cleanupPendingMutationsQueries(), f.forEach(({ hash: d }) => {
this.notifyOne(d);
});
break;
}
case "transact-ok": {
const { "client-event-id": o, "tx-id": a } = t;
this._inFlightMutationEventIds.delete(o);
const u = this._rewriteMutations(
this.ensureAttrs(),
this._pendingMutations()
).get(o);
if (!u)
break;
this._updatePendingMutations((f) => {
f.set(o, {
...f.get(o),
"tx-id": a,
confirmed: Date.now()
});
});
const l = [];
for (const f of u["tx-steps"])
if (f[0] === "add-attr") {
const d = f[1];
l.push(d);
}
if (l.length) {
const f = Object.values(this.ensureAttrs().attrs);
this._setAttrs([...f, ...l]);
}
this._finishTransaction("synced", o), this._cleanupPendingMutationsTimeout();
break;
}
case "patch-presence": {
const o = t["room-id"];
this._trySetRoomConnected(o, !0), this._patchPresencePeers(o, t.edits), this._notifyPresenceSubs(o);
break;
}
case "refresh-presence": {
const o = t["room-id"];
this._trySetRoomConnected(o, !0), this._setPresencePeers(o, t.data), this._notifyPresenceSubs(o);
break;
}
case "server-broadcast": {
const o = t["room-id"], a = t.topic;
this._trySetRoomConnected(o, !0), this._notifyBroadcastSubs(o, a, t);
break;
}
case "join-room-ok": {
const o = t["room-id"];
if (!this._rooms[o]) {
this._roomsPendingLeave[o] && (this._tryLeaveRoom(o), delete this._roomsPendingLeave[o]);
break;
}
this._trySetRoomConnected(o, !0), this._flushEnqueuedRoomData(o);
break;
}
case "leave-room-ok": {
const o = t["room-id"];
this._trySetRoomConnected(o, !1);
break;
}
case "app-status-changed": {
const o = this._appStatusState.status;
if (this._setAppStatus(t.status), t.status === "disabled" && o !== "disabled") {
const a = {
message: "This app is currently disabled.",
hint: { status: "disabled" }
};
Object.keys(this.queryCbs).forEach(
(c) => this.notifyQueryError(c, a)
);
}
o === "disabled" && t.status !== "disabled" && this._startSocket();
break;
}
case "join-room-error":
const s = t["room-id"], i = this._rooms[s];
i && (i.error = t.error), this._notifyPresenceSubs(s);
break;
case "error":
this._handleReceiveError(t);
break;
default:
this._log.info("Unknown op", t.op, t);
break;
}
}
createWriteStream(e) {
return this._instantStream.createWriteStream(e);
}
createReadStream(e) {
return this._instantStream.createReadStream(e);
}
_pendingMutations() {
return this.kv.currentValue.pendingMutations ?? /* @__PURE__ */ new Map();
}
_updatePendingMutations(e) {
this.kv.updateInPlace((t) => {
const r = t.pendingMutations ?? /* @__PURE__ */ new Map();
t.pendingMutations = r, e(r);
});
}
/**
* @param {'timeout' | 'error'} status
* @param {string} eventId
* @param {{message?: string, type?: string, status?: number, hint?: unknown, traceId?: string}} errorMsg
*/
_handleMutationError(e, t, r) {
const s = this._pendingMutations().get(t);
if (s && (e !== "timeout" || !s["tx-id"])) {
this._updatePendingMutations((o) => (o.delete(t), o)), this._inFlightMutationEventIds.delete(t);
const i = {
message: r.message,
hint: r.hint,
traceId: r.traceId
};
this.notifyAll(), this.notifyAttrsSubs(), this.notifyMutationErrorSubs(i), this._finishTransaction(e, t, r);
}
}
_handleReceiveError(e) {
this._log.info("error", e);
const t = e["client-event-id"];
this._inFlightMutationEventIds.delete(t);
const r = this._pendingMutations().get(t), s = {
message: e.message || "Uh-oh, something went wrong. Ping Joe & Stopa."
};
if (e.hint && (s.hint = e.hint), e["trace-id"] || e["original-event"]?.["trace-id"]) {
const c = [e["trace-id"], e["original-event"]?.["trace-id"]].filter(Boolean).join(",");
s.traceId = c;
}
if (r) {
this._handleMutationError("error", t, s);
return;
}
if (e["original-event"]?.hasOwnProperty("q") && e["original-event"]?.op === "add-query") {
const a = e["original-event"]?.q, c = G(a);
this.notifyQueryError(G(a), s), this.notifyQueryOnceError(a, c, t, s);
return;
}
if (e["original-event"]?.op === "init") {
if (e.type === "record-not-found" && e.hint?.["record-type"] === "app-user") {
this.changeCurrentUser(null);
return;
}
this._setStatus(ae.ERRORED, s), this.notifyAll();
return;
}
switch (e["original-event"]?.op) {
case "resync-table": {
this._syncTable.onResyncError(e);
return;
}
case "start-sync": {
this._syncTable.onStartSyncError(e);
return;
}
case "start-stream":
case "append-stream":
case "subscribe-stream":
case "unsubscribe-stream": {
this._instantStream.onRecieveError(e);
return;
}
}
const o = { ...e };
delete o.message, delete o.hint, console.error(e.message, o), e.hint && console.error(
`This error comes with some debugging information. Here it is:
`,
e.hint
);
}
notifyQueryOnceError(e, t, r, s) {
const i = this.queryOnceDfds[t]?.find((o) => o.eventId === r);
i && (i.dfd.reject(s), this._completeQueryOnce(e, t, i.dfd));
}
_setAttrs(e) {
this.attrs = new fe(
e.reduce((t, r) => (t[r.id] = r, t), {}),
this._linkIndex
), this.notifyAttrsSubs();
}
// ---------------------------
// Queries
getPreviousResult = (e) => {
const t = G(e);
return this.dataForQuery(t)?.data;
};
_startQuerySub(e, t) {
const r = j();
return this.querySubs.updateInPlace((s) => {
if (!s[t]) {
const i = Se(e);
i !== t && s[i] && (s[t] = s[i], delete s[i]);
}
s[t] = s[t] || { q: e, result: null, eventId: r }, s[t].lastAccessed = Date.now();
}), this._tryMigrateLegacyQuerySub(e, t), this._trySendAuthed(r, { op: "add-query", q: e }), r;
}
// Legacy hash migration (async): covers entries that weren't preloaded
// into currentValue. Actively loads the legacy key from storage, moves
// its result onto the new key, and notifies subscribers. Safe to remove
// a few releases after v1.0.39.
async _tryMigrateLegacyQuerySub(e, t) {
const r = Se(e);
if (r === t) return;
await this.querySubs.waitForKeyToLoad(r);
const s = this.querySubs.currentValue[r];
if (!s) return;
let i = !1;
this.querySubs.updateInPlace((o) => {
const a = o[t];
a && !a.result && s.result ? (a.result = s.result, i = !0) : a || (o[t] = s, i = !!s.result), delete o[r];
}), i && this.notifyOne(t);
}
subscribeTable(e, t) {
return this._syncTable.subscribe(e, t);
}
/**
* When a user subscribes to a query the following side effects occur:
*
* - We update querySubs to include the new query
* - We update queryCbs to include the new cb
* - If we already have a result for the query we call cb immediately
* - We send the server an `add-query` message
*
* Returns an unsubscribe function
*/
subscribeQuery(e, t, r) {
this.config.disableValidation || pn(e, this.config.schema), r && "ruleParams" in r && (e = { $$ruleParams: r.ruleParams, ...e });
const s = G(e), i = this.getPreviousResult(e);
return i && t(i), this.queryCbs[s] = this.queryCbs[s] ?? [], this.queryCbs[s].push({ q: e, cb: t }), this._startQuerySub(e, s), () => {
this._unsubQuery(e, s, t);
};
}
queryOnce(e, t) {
this.config.disableValidation || pn(e, this.config.schema), t && "ruleParams" in t && (e = { $$ruleParams: t.ruleParams, ...e });
const r = new dn();
if (!this._isOnline)
return r.reject(
new Error("We can't run `queryOnce`, because the device is offline.")
), r.promise;
if (!this.querySubs)
return r.reject(
new Error(
"We can't run `queryOnce` on the backend. Use adminAPI.query instead: https://www.instantdb.com/docs/backend#query"
)
), r.promise;
const s = G(e), i = this._startQuerySub(e, s);
return this.queryOnceDfds[s] = this.queryOnceDfds[s] ?? [], this.queryOnceDfds[s].push({ q: e, dfd: r, eventId: i }), setTimeout(
() => r.reject(new Error("Query timed out")),
Co
), r.promise;
}
_completeQueryOnce(e, t, r) {
this.queryOnceDfds[t] && (this.queryOnceDfds[t] = this.queryOnceDfds[t].filter(
(s) => s.dfd !== r
), this._cleanupQuery(e, t));
}
_unsubQuery(e, t, r) {
this.queryCbs[t] && (this.queryCbs[t] = this.queryCbs[t].filter((s) => s.cb !== r), this._cleanupQuery(e, t));
}
_hasQueryListeners(e) {
return !!(this.queryCbs[e]?.length || this.queryOnceDfds[e]?.length);
}
_cleanupQuery(e, t) {
this._hasQueryListeners(t) || (delete this.queryCbs[t], delete this.queryOnceDfds[t], delete this._dataForQueryCache[t], this.querySubs.unloadKey(t), this._trySendAuthed(j(), { op: "remove-query", q: e }));
}
// When we `pushTx`, it's possible that we don't yet have `this.attrs`
// This means that `tx-steps` in `pendingMutations` will include `add-attr`
// commands for attrs that already exist.
//
// This will also affect `add-triple` and `retract-triple` which
// reference attr-ids that do not match the server.
//
// We fix this by rewriting `tx-steps` in each `pendingMutation`.
// We remove `add-attr` commands for attrs that already exist.
// We update `add-triple` and `retract-triple` commands to use the
// server attr-ids.
/**
*
* @param {s.AttrsStore} attrs
* @param {any} muts
* @param {number} [processedTxId]
*/
_rewriteMutations(e, t, r) {
if (!e) return t;
if (!t) return /* @__PURE__ */ new Map();
const s = (l) => {
const [f, d, h] = l["forward-identity"];
return U(e, d, h);
}, i = (l) => {
const [f, d, h] = l["forward-identity"];
return ge(e, d, h);
}, o = { attrIdMap: {}, refSwapAttrIds: /* @__PURE__ */ new Set() };
let a = !1;
const c = (l, f) => {
const d = [];
for (const h of l) {
const [p] = h;
if (p === "add-attr") {
const [b, y] = h, g = s(y);
if (g && y.id !== g.id) {
o.attrIdMap[y.id] = g.id, a = !0;
continue;
}
if (y["value-type"] === "ref") {
const A = i(y);
if (A) {
o.attrIdMap[y.id] = A.id, o.refSwapAttrIds.add(y.id), a = !0;
continue;
}
}
}
if (r && f && r >= f && p === "add-attr" || p === "update-attr" || p === "delete-attr") {
a = !0;
continue;
}
const m = a ? fi(o, h) : h;
d.push(m);
}
return a ? d : l;
}, u = /* @__PURE__ */ new Map();
for (const [l, f] of t.entries())
u.set(l, {
...f,
"tx-steps": c(f["tx-steps"], f["tx-id"])
});
return a ? u : t;
}
_rewriteMutationsSorted(e, t) {
return dt(this._rewriteMutations(e, t).entries());
}
// ---------------------------
// Transact
/**
* @returns {s.AttrsStore}
*/
optimisticAttrs() {
const e = [...this._pendingMutations().values()].flatMap((i) => i["tx-steps"]), t = new Set(
e.filter(([i, o]) => i === "delete-attr").map(([i, o]) => o)
), r = [];
for (const [i, o] of e)
if (i === "add-attr")
r.push(o);
else if (i === "update-attr" && o.id && this.attrs?.getAttr(o.id)) {
const a = { ...this.attrs.getAttr(o.id), ...o };
r.push(a);
}
if (!t.size && !r.length)
return this.attrs || new fe({}, this._linkIndex);
const s = { ...this.attrs?.attrs || {} };
for (const i of r)
s[i.id] = i;
for (const i of t)
delete s[i];
return new fe(s, this._linkIndex);
}
/** Runs instaql on a query and a store */
dataForQuery(e, t = !0) {
const r = this._errorMessage;
if (r)
return { error: r };
if (!this.querySubs || !this.kv.currentValue.pendingMutations) return;
const s = this.querySubs.version(), i = this.querySubs.currentValue, o = this.kv.version(), a = this._pendingMutations(), { q: c, result: u } = i[e] || {};
if (!u) return;
const l = this._dataForQueryCache[e];
if (l && s === l.querySubVersion && o === l.pendingMutationsVersion)
return l;
let f = u.store, d = u.attrsStore;
const { pageInfo: h, aggregate: p, processedTxId: m } = u, b = this._rewriteMutationsSorted(
d,
a
);
if (t) {
const g = this._applyOptimisticUpdates(
f,
d,
b,
m
);
f = g.store, d = g.attrsStore;
}
return { data: qt(
{ store: f, attrsStore: d, pageInfo: h, aggregate: p },
c
), querySubVersion: s, pendingMutationsVersion: o };
}
_applyOptimisticUpdates(e, t, r, s) {
for (const [i, o] of r)
if (!o["tx-id"] || s && o["tx-id"] > s) {
const a = ds(e, t, o["tx-steps"]);
e = a.store, t = a.attrsStore;
}
return { store: e, attrsStore: t };
}
/** Re-run instaql and call all callbacks with new data */
notifyOne = (e) => {
const t = this.queryCbs[e] ?? [], r = this._dataForQueryCache[e]?.data, s = this.dataForQuery(e);
s?.data && (this._dataForQueryCache[e] = s, !Be(s.data, r) && t.forEach((i) => i.cb(s.data)));
};
notifyOneQueryOnce = (e) => {
const t = this.queryOnceDfds[e] ?? [], r = this.dataForQuery(e)?.data;
t.forEach((s) => {
this._completeQueryOnce(s.q, e, s.dfd), s.dfd.resolve(r);
});
};
notifyQueryError = (e, t) => {
delete this._dataForQueryCache[e], (this.queryCbs[e] || []).forEach((s) => s.cb({ error: t }));
};
/** Re-compute all subscriptions */
notifyAll() {
Object.keys(this.queryCbs).forEach((e) => {
this.querySubs.waitForKeyToLoad(e).then(() => this.notifyOne(e)).catch(() => this.notifyOne(e));
});
}
loadedNotifyAll() {
this.kv.waitForKeyToLoad("pendingMutations").then(() => this.notifyAll()).catch(() => this.notifyAll());
}
/** Applies transactions locally and sends transact message to server */
pushTx = (e) => {
if (this._appStatusState.isReadOnly)
return Promise.reject(
this._appStatusState.status === "disabled" ? new L("This app is currently disabled.", {
status: "disabled"
}) : new L("This app is in read-only mode.", {
status: "read-only"
})
);
this.config.disableValidation || po(e, this.config.schema);
try {
const t = Ui(
{
attrsStore: this.optimisticAttrs(),
schema: this.config.schema,
stores: Object.values(this.querySubs.currentValue).map(
(r) => r?.result?.store
),
useDateObjects: this.config.useDateObjects
},
e
);
return this.pushOps(t);
} catch (t) {
return this.pushOps([], t);
}
};
/**
* @param {*} txSteps
* @param {*} [error]
* @returns
*/
pushOps = (e, t) => {
const r = j(), s = [...this._pendingMutations().values()], i = Math.max(0, ...s.map((c) => c.order || 0)) + 1, o = {
op: "transact",
"tx-steps": e,
created: Date.now(),
error: t,
order: i
};
this._updatePendingMutations((c) => {
c.set(r, o);
});
const a = new dn();
return this.mutationDeferredStore.set(r, a), this._sendMutation(r, o), this.notifyAll(), a.promise;
};
shutdown() {
this._log.info("[shutdown]", this.config.appId), this._isShutdown = !0, this._transport?.close();
}
/**
* Sends mutation to server and schedules a timeout to cancel it if
* we don't hear back in time.
* Note: If we're offline we don't schedule a timeout, we'll schedule it
* later once we're back online and send the mutation again
*
*/
_sendMutation(e, t) {
if (t.error) {
this._handleMutationError("error", e, {
message: t.error.message
});
return;
}
if (this.status !== ae.AUTHENTICATED) {
this._finishTransaction("enqueued", e);
return;
}
const r = Math.max(
6e3,
Math.min(
this._inFlightMutationEventIds.size + 1,
// Defensive code in case we don't clean up in flight mutation event ids
this._pendingMutations().size + 1
) * 6e3
);
this._isOnline ? (this._trySend(e, t), setTimeout(() => {
this._isOnline && this._handleMutationError("timeout", e, {
message: "transaction timed out"
});
}, r)) : this._finishTransaction("enqueued", e);
}
// ---------------------------
// Websocket
/** Send messages we accumulated while we were connecting */
_flushPendingMessages() {
Object.keys(this.queryCbs).map((i) => this.querySubs.currentValue[i]).filter((i) => i).forEach(({ eventId: i, q: o }) => {
this._trySendAuthed(i, { op: "add-query", q: o });
}), Object.values(this.queryOnceDfds).flat().forEach(({ eventId: i, q: o }) => {
this._trySendAuthed(i, { op: "add-query", q: o });
});
const r = this._rewriteMutations(
this.ensureAttrs(),
this._pendingMutations()
);
r !== this._pendingMutations() && this.kv.updateInPlace((i) => {
i.pendingMutations = r;
}), dt(r.entries()).forEach(([i, o]) => {
o["tx-id"] || this._sendMutation(i, o);
}), this._syncTable.flushPending();
}
/**
* Clean up pendingMutations that all queries have seen
*/
_cleanupPendingMutationsQueries() {
let e = Number.MAX_SAFE_INTEGER;
for (const { result: t } of Object.values(this.querySubs.currentValue))
t?.processedTxId && (e = Math.min(e, t?.processedTxId));
this._updatePendingMutations((t) => {
for (const [r, s] of Array.from(t.entries()))
s["tx-id"] && s["tx-id"] <= e && t.delete(r);
});
}
/**
* After mutations is confirmed by server, we give each query 30 sec
* to update its results. If that doesn't happen, we assume query is
* unaffected by this mutation and it’s safe to delete it from local queue
*/
_cleanupPendingMutationsTimeout() {
if (this._pendingMutations().size < this._pendingMutationCleanupThreshold)
return;
const e = Date.now();
this._updatePendingMutations((t) => {
for (const [r, s] of Array.from(t.entries()))
s.confirmed && s.confirmed + this._pendingTxCleanupTimeout < e && t.delete(r);
});
}
_trySendAuthed(...e) {
this.status === ae.AUTHENTICATED && this._trySend(...e);
}
_trySend(e, t, r) {
if (this._transport.isOpen()) {
switch (Sn[t.op] || this._log.info("[send]", this._transport.id, t.op, {
"client-event-id": e,
...t
}), t.op) {
case "transact": {
this._inFlightMutationEventIds.add(e);
break;
}
case "init":
this._inFlightMutationEventIds.clear();
}
this._transport.send({ "client-event-id": e, ...t });
}
}
_transportOnOpen = (e) => {
const t = e.target;
if (this._transport !== t) {
this._log.info(
"[socket][open]",
t.id,
"skip; this is no longer the current transport"
);
return;
}
this._log.info("[socket][open]", this._transport.id), this._setStatus(ae.OPENED), this.getCurrentUser().then((r) => {
this._trySend(j(), {
op: "init",
"app-id": this.config.appId,
"refresh-token": r.user?.refresh_token,
versions: this.versions,
// If an admin token is provided for an app, we will
// skip all permission checks. This is an advanced feature,
// to let users write internal tools
// This option is not exposed in `Config`, as it's
// not ready for prime time
"__admin-token": this.config.__adminToken
});
}).catch((r) => {
this._log.error("[socket][error]", t.id, r);
});
};
_transportOnMessage = (e) => {
const t = e.target, r = e.message;
if (this._transport !== t) {
this._log.info(
"[socket][message]",
t.id,
r,
"skip; this is no longer the current transport"
);
return;
}
if (!this._wsOk && t.type === "ws" && (this._wsOk = !0), this._transportType = "ws", Array.isArray(e.message))
for (const s of e.message)
this._handleReceive(t.id, s);
else
this._handleReceive(t.id, e.message);
};
_transportOnError = (e) => {
const t = e.target;
if (this._transport !== t) {
this._log.info(
"[socket][error]",
t.id,
"skip; this is no longer the current transport"
);
return;
}
this._log.error("[socket][error]", t.id, e);
};
_scheduleReconnect = () => {
!this._wsOk && this._transportType !== "sse" && (this._transportType = "sse", this._reconnectTimeoutMs = 0), setTimeout(() => {
if (this._reconnectTimeoutMs = Math.min(
this._reconnectTimeoutMs + 1e3,
1e4
), !this._isOnline) {
this._log.info(
"[socket][close]",
this._transport.id,
"we are offline, no need to start socket"
);
return;
}
this._startSocket();
}, this._reconnectTimeoutMs);
};
_transportOnClose = (e) => {
const t = e.target;
if (this._transport !== t) {
this._log.info(
"[socket][close]",
t.id,
"skip; this is no longer the current transport"
);
return;
}
this._setStatus(ae.CLOSED);
for (const r of Object.values(this._rooms))
r.isConnected = !1;
if (this._isShutdown) {
this._log.info(
"[socket][close]",
t.id,
"Reactor has been shut down and will not reconnect"
);
return;
}
this._log.info(
"[socket][close]",
t.id,
"schedule reconnect, ms =",
this._reconnectTimeoutMs
), this._scheduleReconnect();
};
_startSocket() {
if (this._wsOk = null, this._isShutdown) {
this._log.info(
"[socket][start]",
this.config.appId,
"Reactor has been shut down and will not start a new socket"
);
return;
}
if (this._transport && this._transport.isConnecting()) {
this._log.info(
"[socket][start]",
this._transport.id,
"maintained as current transport, we were still in a connecting state"
);
return;
}
const e = this._transport;
this._transport = xo({
transportType: this._transportType,
appId: this.config.appId,
apiURI: this.config.apiURI,
wsURI: this.config.websocketURI,
EventSourceImpl: this._EventSource
}), this._transport.onopen = this._transportOnOpen, this._transport.onmessage = this._transportOnMessage, this._transport.onclose = this._transportOnClose, this._transport.onerror = this._transportOnError, this._log.info("[socket][start]", this._transport.id), e?.isOpen() && (this._log.info(
"[socket][start]",
this._transport.id,
"close previous transport id = ",
e.id
), e.close());
}
/**
* Given a key, returns a stable local id, unique to this device and app.
*
* This can be useful if you want to create guest ids for example.
*
* Note: If the user deletes their local storage, this id will change.
*
*/
async getLocalId(e) {
const t = `localToken_${e}`;
if (this.kv.currentValue[t])
return this.kv.currentValue[t];
const r = await this.kv.waitForKeyToLoad(t);
if (r)
return r;
const s = j();
return this.kv.updateInPlace((i) => {
i[t] || (i[t] = s);
}), await this.kv.waitForKeyToLoad(t);
}
// ----
// Auth
_replaceUrlAfterOAuth() {
if (typeof URL > "u")
return;
const e = new URL(window.location.href);
if (e.searchParams.get(ut)) {
const t = e.toString();
e.searchParams.delete(ut), e.searchParams.delete(lt), e.searchParams.delete("code"), e.searchParams.delete("error");
const r = e.pathname + (e.searchParams.size ? "?" + e.searchParams : "") + e.hash;
if (history.replaceState(history.state, "", r), // @ts-ignore (waiting for ts support)
typeof navigation == "object" && // @ts-ignore (waiting for ts support)
typeof navigation.addEventListener == "function" && // @ts-ignore (waiting for ts support)
typeof navigation.removeEventListener == "function") {
let s = !1;
const i = (o) => {
s || (s = !0, navigation.removeEventListener("navigate", i), !o.userInitiated && o.navigationType === "replace" && o.destination?.url === t && history.replaceState(history.state, "", r));
};
navigation.addEventListener("navigate", i);
}
}
}
/**
*
* @returns Promise<null | {error: {message: string}}>
*/
async _oauthLoginInit() {
if (typeof window > "u" || typeof window.location > "u" || typeof URLSearchParams > "u")
return null;
const e = new URLSearchParams(window.location.search);
if (!e.get(ut))
return null;
const t = e.get("error");
if (t)
return this._replaceUrlAfterOAuth(), { error: { message: t } };
const r = e.get("code");
if (!r)
return null;
const s = e.get(lt);
this._replaceUrlAfterOAuth();
try {
let i;
const o = await this.kv.waitForKeyToLoad(qe);
s && o && (i = o[s]), o && this.kv.updateInPlace((l) => {
delete l[qe];
});
const a = await this._getCurrentUser(), c = a?.type === "guest", { user: u } = await un({
apiURI: this.config.apiURI,
appId: this.config.appId,
code: r,
refreshToken: c ? a.refresh_token : void 0,
extraFields: i
});
return this.setCurrentUser(u), null;
} catch (i) {
return i?.body?.type === "record-not-found" && i?.body?.hint?.["record-type"] === "app-oauth-code" && await this._hasCurrentUser() ? null : { error: { message: i?.body?.message || "Error logging in." } };
}
}
async _waitForOAuthCallbackResponse() {
return await this._oauthCallbackResponse;
}
__subscribeMutationErrors(e) {
return this.mutationErrorCbs.push(e), () => {
this.mutationErrorCbs = this.mutationErrorCbs.filter((t) => t !== e);
};
}
subscribeAuth(e) {
this.authCbs.push(e);
const t = this._currentUserCached;
t.isLoading || e(this._currentUserCached);
let r = !1;
return this.getCurrentUser().then((s) => {
r || Be(s, t) || e(s);
}), () => {
r = !0, this.authCbs = this.authCbs.filter((s) => s !== e);
};
}
async getAuth() {
const { user: e, error: t } = await this.getCurrentUser();
if (t)
throw new L("Could not get current user: " + t.message);
return e ?? null;
}
subscribeConnectionStatus(e) {
return this.connectionStatusCbs.push(e), () => {
this.connectionStatusCbs = this.connectionStatusCbs.filter(
(t) => t !== e
);
};
}
/**
* @param {'active' | 'read-only' | 'disabled' | undefined} status
*/
_setAppStatus(e) {
!e || e === this._appStatusState.status || (this._appStatusState = {
isLoading: !1,
isReadOnly: e !== "active",
status: e
}, this.notifyAppStatusSubs(this._appStatusState));
}
subscribeAppStatus(e) {
return this.appStatusCbs.push(e), e(this._appStatusState), () => {
this.appStatusCbs = this.appStatusCbs.filter((t) => t !== e);
};
}
subscribeAttrs(e) {
return this.attrsCbs.push(e), this.attrs && e(this.attrs.attrs), () => {
this.attrsCbs = this.attrsCbs.filter((t) => t !== e);
};
}
notifyAuthSubs(e) {
this.authCbs.forEach((t) => t(e));
}
notifyMutationErrorSubs(e) {
this.mutationErrorCbs.forEach((t) => t(e));
}
notifyAttrsSubs() {
if (!this.attrs) return;
const e = this.optimisticAttrs();
this.attrsCbs.forEach((t) => t(e.attrs));
}
notifyConnectionStatusSubs(e) {
this.connectionStatusCbs.forEach((t) => t(e));
}
notifyAppStatusSubs(e) {
this.appStatusCbs.forEach((t) => t(e));
}
async setCurrentUser(e) {
this.kv.updateInPlace((t) => {
t[me] = e;
}), await this.kv.waitForKeyToLoad(me);
}
getCurrentUserCached() {
return this._currentUserCached;
}
/**
* @param {{ forceReadFromStorage?: boolean }} [opts]
* @returns {Promise<User | undefined>}
*/
async _getCurrentUser(e) {
e?.forceReadFromStorage && await this.kv.unloadKey(me);
const t = await this.kv.waitForKeyToLoad(me);
return typeof t == "string" ? JSON.parse(t) : t;
}
/**
* @param {{ forceReadFromStorage?: boolean }} [opts]
* @returns {Promise<AuthState>}
*/
async getCurrentUser(e) {
const t = await this._waitForOAuthCallbackResponse();
if (t?.error) {
const r = { error: t.error, user: void 0 };
return this._currentUserCached = { isLoading: !1, ...r }, this._currentUserCached;
}
try {
const s = { user: await this._getCurrentUser(e), error: void 0 };
return this._currentUserCached = {
isLoading: !1,
...s
}, this._currentUserCached;
} catch (r) {
return {
user: void 0,
isLoading: !1,
error: { message: r?.message || "Error loading user" }
};
}
}
async _hasCurrentUser() {
const e = await this.kv.waitForKeyToLoad(me);
return typeof e == "string" ? JSON.parse(e) != null : e != null;
}
async changeCurrentUser(e) {
const { user: t } = await this.getCurrentUser();
if (!Be(t, e)) {
this._frameworkClient = null, await this.setCurrentUser(e), await this.updateUser(e);
try {
await this.kv.flush(), this._broadcastChannel?.postMessage({ type: "auth" });
} catch (r) {
console.error("Error posting message to broadcast channel", r);
}
}
}
async setupUserSyncTimer() {
if (this.config.firstPartyPath)
try {
const e = await this.kv.waitForKeyToLoad(
_n
), t = e ? new Date(e).getTime() : 0;
if (!(!Number.isFinite(t) || Date.now() - t >= jo)) return;
const { user: s } = await this.getCurrentUser();
await this.syncUserToEndpoint(s ?? null);
} catch (e) {
this._log.error("Error syncing user cookie on startup", e);
}
}
async syncUserToEndpoint(e) {
if (this.config.firstPartyPath) {
try {
const t = await fetch(this.config.firstPartyPath + "/", {
method: "POST",
body: JSON.stringify({
type: "sync-user",
appId: this.config.appId,
user: e
}),
headers: {
"Content-Type": "application/json"
}
});
if (!t.ok)
throw new Error(`HTTP error! status: ${t.status}`);
} catch (t) {
this._log.error("Error syncing user with external endpoint", t);
}
this.kv.updateInPlace((t) => {
t[_n] = (/* @__PURE__ */ new Date()).toISOString();
});
}
}
async updateUser(e) {
const t = { error: void 0, user: e };
this._currentUserCached = { isLoading: !1, ...t }, this._dataForQueryCache = {}, this.querySubs.updateInPlace((r) => {
Object.keys(r).forEach((s) => {
delete r[s].result;
});
}), this.querySubs.clearUnloadedKeys(), this._updatePendingMutations((r) => {
for (const [s, i] of r.entries())
this.mutationDeferredStore.get(s) && this._finishTransaction("error", s, {
message: "User changed while transaction was in progress.",
type: "user-changed"
});
r.clear();
}), this._reconnectTimeoutMs = 0, this._transport.close(), this._oauthCallbackResponse = null, this.notifyAuthSubs(t);
try {
await this.syncUserToEndpoint(e);
} catch (r) {
this._log.error("Error syncing user with external endpoint", r);
}
}
sendMagicCode({ email: e }) {
return Wi({
apiURI: this.config.apiURI,
appId: this.config.appId,
email: e
});
}
async signInWithMagicCode(e) {
const t = await this.getCurrentUser(), r = t?.user?.type === "guest", s = await Vi({
apiURI: this.config.apiURI,
appId: this.config.appId,
email: e.email,
code: e.code,
refreshToken: r ? t?.user?.refresh_token : void 0,
extraFields: e.extraFields
});
return await this.changeCurrentUser(s.user), s;
}
async signInWithCustomToken(e) {
const t = await Qi({
apiURI: this.config.apiURI,
appId: this.config.appId,
refreshToken: e
});
return await this.changeCurrentUser(t.user), t;
}
async signInAsGuest(e) {
const t = await Bi({
apiURI: this.config.apiURI,
appId: this.config.appId,
extraFields: e?.extraFields
});
return await this.changeCurrentUser(t.user), t;
}
potentiallyInvalidateToken(e, t) {
const r = e?.user?.refresh_token;
if (!r)
return;
if (t.invalidateToken === !1) {
this._log.info("[auth-invalidate] skipped invalidateToken");
return;
}
Hi({
apiURI: this.config.apiURI,
appId: this.config.appId,
refreshToken: r
}).then(() => {
this._log.info("[auth-invalidate] completed invalidateToken");
}).catch((i) => {
});
}
async signOut(e) {
const t = await this.getCurrentUser();
this.potentiallyInvalidateToken(t, e), await this.changeCurrentUser(null);
}
/**
* Creates an OAuth authorization URL.
*
* @param {Object} params - The parameters to create the authorization URL.
* @param {string} params.clientName - The name of the client requesting authorization.
* @param {string} params.redirectURL - The URL to redirect users to after authorization.
* @param {Record<string, any>} [params.extraFields] - Extra fields to write to $users on creation
* @returns {string} The created authorization URL.
*/
createAuthorizationURL({ clientName: e, redirectURL: t, extraFields: r }) {
const { apiURI: s, appId: i } = this.config;
let o = t;
if (r) {
const a = `${Math.random().toString(36).slice(2)}`;
this.kv.updateInPlace((c) => {
const u = c[qe] || {};
u[a] = r, c[qe] = u;
}), o = `${t}${t.includes("?") ? "&" : "?"}${lt}=${a}`;
}
return `${s}/runtime/oauth/start?app_id=${i}&client_name=${e}&redirect_uri=${encodeURIComponent(o)}`;
}
/**
* @param {Object} params
* @param {string} params.code - The code received from the OAuth service.
* @param {string} [params.codeVerifier] - The code verifier used to generate the code challenge.
* @param {Record<string, any>} [params.extraFields] - Extra fields to write to $users on creation
*/
async exchangeCodeForToken({ code: e, codeVerifier: t, extraFields: r }) {
const s = await this.getCurrentUser(), i = s?.user?.type === "guest", o = await un({
apiURI: this.config.apiURI,
appId: this.config.appId,
code: e,
codeVerifier: t,
refreshToken: i ? s?.user?.refresh_token : void 0,
extraFields: r
});
return await this.changeCurrentUser(o.user), o;
}
issuerURI() {
const { apiURI: e, appId: t } = this.config;
return `${e}/runtime/${t}`;
}
/**
* @param {Object} params
* @param {string} params.clientName - The name of the client requesting authorization.
* @param {string} params.idToken - The id_token from the external service
* @param {string | null | undefined} [params.nonce] - The nonce used when requesting the id_token from the external service
* @param {Record<string, any>} [params.extraFields] - Extra fields to write to $users on creation
*/
async signInWithIdToken(e) {
const r = (await this.getCurrentUser())?.user?.refresh_token, s = await Gi({
apiURI: this.config.apiURI,
appId: this.config.appId,
idToken: e.idToken,
clientName: e.clientName,
nonce: e.nonce,
refreshToken: r,
extraFields: e.extraFields
});
return await this.changeCurrentUser(s.user), s;
}
// --------
// Rooms
/**
* @param {string} roomType
* @param {string} roomId
* @param {any | null | undefined} [initialPresence] -- initial presence data to send when joining the room
* @returns () => void
*/
joinRoom(e, t, r) {
let s = !1;
this._rooms[t] || (s = !0, this._rooms[t] = {
roomType: e,
isConnected: !1,
error: void 0
}), this._presence[t] = this._presence[t] || {};
const i = this._presence[t].result;
return r && !i && (this._presence[t].result = this._presence[t].result || {}, this._presence[t].result.user = r, this._notifyPresenceSubs(t)), s && this._tryJoinRoom(e, t, r), () => {
this._cleanupRoom(t);
};
}
_cleanupRoom(e) {
if (!this._presence[e]?.handlers?.length && !Object.keys(this._broadcastSubs[e] ?? {}).length) {
const t = this._rooms[e]?.isConnected;
delete this._rooms[e], delete this._presence[e], delete this._broadcastSubs[e], t ? this._tryLeaveRoom(e) : this._roomsPendingLeave[e] = !0;
}
}
// --------
// Presence
// TODO: look into typing again
getPresence(e, t, r = {}) {
const s = this._rooms[t], i = this._presence[t];
return !s || !i || !i.result ? null : {
...to(i.result, r, this._sessionId),
isLoading: !s.isConnected,
error: s.error
};
}
// TODO: look into typing again
publishPresence(e, t, r) {
const s = this._rooms[t], i = this._presence[t];
if (!s || !i)
return;
i.result = i.result || {};
const o = {
...i.result.user,
...r
};
i.result.user = o, s.isConnected && (this._trySetPresence(t, o), this._notifyPresenceSubs(t));
}
_trySetPresence(e, t) {
this._trySendAuthed(j(), {
op: "set-presence",
"room-id": e,
data: t
});
}
_tryJoinRoom(e, t, r) {
this._trySendAuthed(j(), {
op: "join-room",
"room-type": e,
"room-id": t,
data: r
}), delete this._roomsPendingLeave[t];
}
_tryLeaveRoom(e) {
this._trySendAuthed(j(), { op: "leave-room", "room-id": e });
}
_trySetRoomConnected(e, t) {
const r = this._rooms[e];
r && (r.isConnected = t);
}
// TODO: look into typing again
subscribePresence(e, t, r, s) {
const i = this.joinRoom(
e,
t,
// Oct 28, 2025
// Note: initialData is deprecated.
// Keeping here for backwards compatibility
r.initialPresence || r.initialData
), o = { ...r, roomId: t, cb: s, prev: null };
return this._presence[t] = this._presence[t] || {}, this._presence[t].handlers = this._presence[t].handlers || [], this._presence[t].handlers.push(o), this._notifyPresenceSub(t, o), () => {
this._presence[t].handlers = this._presence[t]?.handlers?.filter((a) => a !== o) ?? [], i();
};
}
_notifyPresenceSubs(e) {
this._presence[e]?.handlers?.forEach((t) => {
this._notifyPresenceSub(e, t);
});
}
_notifyPresenceSub(e, t) {
const r = this.getPresence("", e, t);
r && (t.prev && !no(r, t.prev) || (t.prev = r, t.cb(r)));
}
_patchPresencePeers(e, t) {
const r = this._presence[e]?.result?.peers || {};
let s = Object.fromEntries(
Object.entries(r).map(([o, a]) => [o, { data: a }])
);
this._presence[e]?.result;
const i = Ye(s, (o) => {
for (let [a, c, u] of t)
switch (c) {
case "+":
$r(o, a, u);
break;
case "r":
Ht(o, a, u);
break;
case "-":
Dn(o, a);
break;
}
delete o[this._sessionId];
});
this._setPresencePeers(e, i);
}
_setPresencePeers(e, t) {
const r = { ...t };
delete r[this._sessionId];
const s = Object.fromEntries(
Object.entries(r).map(([i, o]) => [i, o.data])
);
this._presence = Ye(this._presence, (i) => {
Ht(i, [e, "result", "peers"], s);
});
}
// --------
// Broadcast
publishTopic({ roomType: e, roomId: t, topic: r, data: s }) {
const i = this._rooms[t];
if (i) {
if (!i.isConnected) {
this._broadcastQueue[t] = this._broadcastQueue[t] ?? [], this._broadcastQueue[t].push({ topic: r, roomType: e, data: s });
return;
}
this._tryBroadcast(t, e, r, s);
}
}
_tryBroadcast(e, t, r, s) {
this._trySendAuthed(j(), {
op: "client-broadcast",
"room-id": e,
roomType: t,
topic: r,
data: s
});
}
subscribeTopic(e, t, r, s) {
const i = this.joinRoom(e, t);
return this._broadcastSubs[t] = this._broadcastSubs[t] || {}, this._broadcastSubs[t][r] = this._broadcastSubs[t][r] || [], this._broadcastSubs[t][r].push(s), this._presence[t] = this._presence[t] || {}, () => {
this._broadcastSubs[t][r] = this._broadcastSubs[t][r].filter((o) => o !== s), this._broadcastSubs[t][r].length || delete this._broadcastSubs[t][r], i();
};
}
_notifyBroadcastSubs(e, t, r) {
this._broadcastSubs?.[e]?.[t]?.forEach((s) => {
const i = r.data?.data, o = r.data["peer-id"] === this._sessionId ? this._presence[e]?.result?.user : this._presence[e]?.result?.peers?.[r.data["peer-id"]];
return s(i, o);
});
}
// --------
// Storage
async uploadFile(e, t, r) {
const i = (await this.getCurrentUser())?.user?.refresh_token;
return Ji({
...r,
apiURI: this.config.apiURI,
appId: this.config.appId,
path: e,
file: t,
refreshToken: i
});
}
async deleteFile(e) {
const r = (await this.getCurrentUser())?.user?.refresh_token;
return await Yi({
apiURI: this.config.apiURI,
appId: this.config.appId,
path: e,
refreshToken: r
});
}
// Deprecated Storage API (Jan 2025)
// ---------------------------------
async upload(e, t) {
const s = (await this.getCurrentUser())?.user?.refresh_token, i = e || t.name, o = await Zi({
apiURI: this.config.apiURI,
appId: this.config.appId,
fileName: i,
refreshToken: s
});
return await Xi(o, t);
}
async getDownloadUrl(e) {
const r = (await this.getCurrentUser())?.user?.refresh_token;
return await eo({
apiURI: this.config.apiURI,
appId: this.config.appId,
path: e,
refreshToken: r
});
}
}
function qo(n, e) {
return new rt(
br(n, e),
// (XXX): LinksDef<any> stems from TypeScript’s inability to reconcile the
// type EntitiesWithLinks<EntitiesWithoutLinks, Links> with
// EntitiesWithoutLinks. TypeScript is strict about ensuring that types are
// correctly aligned and does not allow for substituting a type that might
// be broader or have additional properties.
e,
void 0
);
}
function zo(n) {
return new nt(n, {});
}
function Wo() {
return new V("string", !0, !1);
}
function Vo() {
return new V("number", !0, !1);
}
function Qo() {
return new V("boolean", !0, !1);
}
function Bo() {
return new V("date", !0, !1);
}
function Go() {
return new V("json", !0, !1);
}
function Ho() {
return new V("json", !0, !1);
}
function br(n, e) {
const t = { fwd: {}, rev: {} };
for (const s of Object.values(e))
t.fwd[s.forward.on] ||= {}, t.rev[s.reverse.on] ||= {}, t.fwd[s.forward.on][s.forward.label] = {
entityName: s.reverse.on,
cardinality: s.forward.has
}, t.rev[s.reverse.on][s.reverse.label] = {
entityName: s.forward.on,
cardinality: s.reverse.has
};
return Object.fromEntries(
Object.entries(n).map(([s, i]) => [
s,
new nt(i.attrs, {
...t.fwd[s],
...t.rev[s]
})
])
);
}
function Jo({
entities: n,
links: e,
rooms: t
}) {
const r = e ?? {}, s = t ?? {};
return new rt(
br(n, r),
// (XXX): LinksDef<any> stems from TypeScript's inability to reconcile the
// type EntitiesWithLinks<EntitiesWithoutLinks, Links> with
// EntitiesWithoutLinks. TypeScript is strict about ensuring that types are
// correctly aligned and does not allow for substituting a type that might
// be broader or have additional properties.
r,
s
);
}
const $ = {
// constructs
graph: qo,
schema: Jo,
entity: zo,
// value types
string: Wo,
number: Vo,
boolean: Qo,
date: Bo,
json: Go,
any: Ho
};
let Tn;
function Yo(n, e) {
Tn?.dispose();
const t = ra(e), r = ea(e, a), s = Xo(Zo(n, e));
function i(l) {
l.source === s.element.contentWindow && l.data?.type === "close" && t.isVisible() && a();
}
function o(l) {
const f = l.shiftKey && l.ctrlKey && l.code === "Digit0", d = l.key === "Escape" || l.key === "Esc";
(f || d && t.isVisible()) && a();
}
function a() {
t.isVisible() ? t.element.style.display = "none" : (t.element.style.display = "block", t.element.contains(s.element) || t.element.appendChild(s.element));
}
function c() {
t.element.remove(), r.element.remove(), removeEventListener("keydown", o), removeEventListener("message", i);
}
function u() {
document.body.appendChild(t.element), document.body.appendChild(r.element), addEventListener("keydown", o), addEventListener("message", i), Tn = {
dispose: c
};
}
return u();
}
function Zo(n, e) {
const t = zt || ar;
return `${(e.dashURI ?? (t ? "http://localhost:3000" : "https://instantdb.com")).replace(/\/+$/, "")}/_devtool?appId=${n}`;
}
function Xo(n) {
const e = document.createElement("iframe");
return e.src = n, e.className = "instant-devtool-iframe", Object.assign(e.style, {
width: "100%",
height: "100%",
backgroundColor: "white",
border: "none"
}), { element: e };
}
function ea(n, e) {
const t = `
<svg width="32" height="32" viewBox="0 0 512 512" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="512" height="512" fill="black"/>
<rect x="97.0973" y="91.3297" width="140" height="330" fill="white"/>
</svg>
`, r = document.createElement("button");
return r.innerHTML = t, r.className = "instant-devtool-toggler", Object.assign(r.style, {
// pos
position: "fixed",
...ta(n.position),
height: "32px",
width: "32px",
// layout
display: "flex",
alignItems: "center",
justifyContent: "center",
zIndex: "9010",
// look
padding: "0",
margin: "0",
border: "none",
cursor: "pointer"
}), r.addEventListener("click", e), { element: r };
}
function ta(n) {
switch (n) {
case "bottom-left":
return { bottom: "24px", left: "24px" };
case "bottom-right":
return { bottom: "24px", right: "24px" };
case "top-right":
return { top: "24px", right: "24px" };
case "top-left":
return { top: "24px", left: "24px" };
}
}
function na(n) {
switch (n) {
case "bottom-left":
return { bottom: "24px", right: "24px", left: "60px", top: "72px" };
case "bottom-right":
return { bottom: "24px", left: "24px", right: "60px", top: "72px" };
case "top-right":
return { top: "24px", left: "24px", right: "60px", bottom: "72px" };
case "top-left":
return { top: "24px", right: "24px", left: "60px", bottom: "72px" };
}
}
function ra(n) {
const e = document.createElement("div");
Object.assign(e.style, {
position: "fixed",
...na(n.position),
display: "block",
borderRadius: "4px",
border: "1px #ccc solid",
boxShadow: "0px 0px 8px #00000044",
backgroundColor: "#eee",
zIndex: "999990"
}), e.style.display = "none", e.className = "instant-devtool-container";
function t() {
return e.style.display !== "none";
}
return { element: e, isVisible: t };
}
function sa(n, e) {
return e && e.refresh_token ? new Response(JSON.stringify({ ok: !0 }), {
headers: {
"Content-Type": "application/json",
// 7 day expiry
"Set-Cookie": `instant_user_${n.appId}=${encodeURIComponent(JSON.stringify(e))}; Path=/; HttpOnly; Secure; SameSite=Strict; Max-Age=604800`
}
}) : new Response(JSON.stringify({ ok: !0 }), {
headers: {
"Content-Type": "application/json",
// remove the cookie (some browsers)
"Set-Cookie": `instant_user_${n.appId}=; Path=/; HttpOnly; Secure; SameSite=Strict; Max-Age=-1`
}
});
}
function ze(n, e) {
return new Response(JSON.stringify({ ok: !1, error: e }), {
status: n,
headers: { "Content-Type": "application/json" }
});
}
const va = (n) => ({
POST: async (e) => {
let t;
try {
t = await e.json();
} catch {
return ze(400, "Invalid JSON body");
}
return t.type ? t.appId !== n.appId ? ze(403, "App ID mismatch") : t.type === "sync-user" ? sa(n, t.user ?? null) : ze(400, `Unknown type: ${t.type}`) : ze(400, 'Missing "type" field');
}
}), Aa = (n) => {
const e = {};
for (const [i, o] of Object.entries(n.entities)) {
const a = o, c = {};
for (const [u, l] of Object.entries(a.attrs)) {
const f = l;
let d;
switch (f.valueType) {
case "string":
d = $.string();
break;
case "number":
d = $.number();
break;
case "boolean":
d = $.boolean();
break;
case "date":
d = $.date();
break;
case "json":
d = $.json();
break;
default:
d = $.json();
}
f.required || (d = d.optional()), f.config?.indexed && (d = d.indexed()), f.config?.unique && (d = d.unique()), c[u] = d;
}
e[i] = $.entity(c);
}
const t = n.links || {}, r = {};
if (n.rooms)
for (const [i, o] of Object.entries(n.rooms)) {
const a = o, c = {};
for (const [l, f] of Object.entries(
a.presence.attrs
)) {
const d = f;
let h;
switch (d.valueType) {
case "string":
h = $.string();
break;
case "number":
h = $.number();
break;
case "boolean":
h = $.boolean();
break;
case "date":
h = $.date();
break;
case "json":
h = $.json();
break;
default:
h = $.json();
}
d.required || (h = h.optional()), d.config?.indexed && (h = h.indexed()), d.config?.unique && (h = h.unique()), c[l] = h;
}
const u = {};
if (a.topics)
for (const [l, f] of Object.entries(a.topics)) {
const d = f, h = {};
for (const [p, m] of Object.entries(d.attrs)) {
const b = m;
let y;
switch (b.valueType) {
case "string":
y = $.string();
break;
case "number":
y = $.number();
break;
case "boolean":
y = $.boolean();
break;
case "date":
y = $.date();
break;
case "json":
y = $.json();
break;
default:
y = $.json();
}
b.required || (y = y.optional()), b.config?.indexed && (y = y.indexed()), b.config?.unique && (y = y.unique()), h[p] = y;
}
u[l] = $.entity(h);
}
r[i] = {
presence: $.entity(c),
topics: u
};
}
return $.schema({
entities: e,
links: t,
rooms: r
});
}, ia = typeof window > "u" || "Deno" in globalThis;
class ka {
params;
db;
// stores all of the query promises so that ssr can read them
// and send the relevant results alongside the html that resulted in the query resolving
resultMap = /* @__PURE__ */ new Map();
queryResolvedCallbacks = [];
constructor(e) {
this.params = e, this.db = e.db, this.resultMap = /* @__PURE__ */ new Map();
}
subscribe = (e) => {
this.queryResolvedCallbacks.push(e);
};
// Runs on the client when ssr gets html script tags
addQueryResult = (e, t) => {
this.resultMap.set(e, {
type: t.type,
status: "success",
data: t,
promise: null,
error: null
}), ia || (this.db._reactor.attrs || this.db._reactor._setAttrs(t.attrs), this.db._reactor._addQueryData(
t.query,
t,
!!this.db._reactor.config.schema
));
};
removeCachedQueryResult = (e) => {
this.resultMap.delete(e);
};
// Run a query on the client and return a promise with the result
queryClient = (e, t) => {
const { hash: r, query: s } = this.hashQuery(e, t);
let i, o;
const a = new Promise(
(l, f) => {
i = l, o = f;
}
);
let c = {
status: "pending",
type: "session",
data: void 0,
error: void 0,
promise: a
}, u = null;
return u = this.db.subscribeQuery(s, (l) => {
l.error ? (c.status = "error", c.error = l.error, c.promise = null, o(l.error)) : (c.status = "success", c.data = l, c.promise = null, i(l)), u !== null && u();
}), this.resultMap.set(r, c), a;
};
// creates an entry in the results map
// and returns the same thing added to the map
query = (e, t) => {
const { hash: r, query: s } = this.hashQuery(e, t);
if (this.db._reactor.status === "authenticated") {
const a = this.db.queryOnce(e, t);
let c = {
status: "pending",
type: "session",
data: void 0,
error: void 0,
promise: a
};
return a.then((u) => {
c.status = "success", c.data = u, c.promise = null;
}), a.catch((u) => {
c.status = "error", c.error = u, c.promise = null;
}), this.resultMap.set(r, c), c;
}
const i = this.getTriplesAndAttrsForQuery(s);
let o = {
status: "pending",
type: "http",
data: void 0,
error: void 0,
promise: i
};
return i.then((a) => {
o.status = "success", o.data = a, o.promise = null;
}), i.catch((a) => {
o.status = "error", o.error = a, o.promise = null;
}), i.then((a) => {
this.queryResolvedCallbacks.forEach((c) => {
c({
queryHash: r,
query: s,
attrs: a.attrs,
triples: a.triples,
pageInfo: a.pageInfo
});
});
}), this.resultMap.set(r, o), o;
};
getExistingResultForQuery = (e, t) => {
const { hash: r } = this.hashQuery(e, t);
return this.resultMap.get(r);
};
// creates a query result from a set of triples, query, and attrs
// can be run server side or client side
completeIsomorphic = (e, t, r, s) => {
const i = {};
r.forEach((l) => {
i[l.id] = l;
});
const o = !!this.db?._reactor?.config?.schema && ("cardinalityInference" in this.db?._reactor?.config ? !!this.db?._reactor.config?.cardinalityInference : !0), a = new fe(
r.reduce((l, f) => (l[f.id] = f, l), {}),
Ct(this.db?._reactor.config.schema)
), c = Te(
a,
t,
o,
this.params.db._reactor.config.useDateObjects || !1
);
return qt(
{
store: c,
attrsStore: a,
pageInfo: s,
aggregate: void 0
},
e
);
};
hashQuery = (e, t) => {
e && t && "ruleParams" in t && (e = { $$ruleParams: t.ruleParams, ...e });
const r = e ? wr(e) : null;
return { hash: G(r), query: r };
};
// Run by the server to get triples and attrs
getTriplesAndAttrsForQuery = async (e) => {
try {
const t = await fetch(
`${this.db._reactor.config.apiURI}/runtime/framework/query`,
{
method: "POST",
headers: {
"app-id": this.params.db._reactor.config.appId,
"Content-Type": "application/json",
Authorization: this.params.token ? `Bearer ${this.params.token}` : void 0
},
body: JSON.stringify({
query: e
})
}
);
if (!t.ok)
try {
const a = await t.json();
throw "message" in a ? new Le({ body: a, status: t.status }) : new Error("Error getting triples from server");
} catch (a) {
throw a instanceof L ? a : new Error("Error getting triples from server");
}
const r = await t.json(), s = r?.attrs;
if (!s)
throw new Error("No attrs");
const i = r.result?.[0].data?.["datalog-result"]?.["join-rows"][0], o = r.result?.[0]?.data?.["page-info"];
return {
attrs: s,
triples: i,
type: "http",
queryHash: this.hashQuery(e).hash,
query: e,
pageInfo: o
};
} catch (t) {
if (t instanceof L)
throw t;
const r = new Error(
"Error getting triples from framework client"
);
throw r.cause = t, r;
}
};
}
function Ce(n, e) {
if (!n)
throw new Error("[assertion error] " + e);
}
const oa = (n) => JSON.stringify(n), je = (n, e = !1) => JSON.stringify([n, e]), vn = (n) => {
const [e, t] = JSON.parse(n);
return { cursor: e, afterInclusive: t };
}, we = (n, e, t = !1) => `${n}:${je(e, t)}`, aa = (n) => !!n.endCursor, ca = (n) => {
const e = Array.from(n.values());
return e.length === 0 ? !1 : e[e.length - 1]?.hasMore || !1;
}, An = (n) => {
if (!n)
return {
serverCreatedAt: "asc"
};
const e = Object.keys(n).at(0);
return e ? {
[e]: n[e] === "asc" ? "desc" : "asc"
} : {
serverCreatedAt: "asc"
};
}, gr = (n) => n && Object.keys(n).length > 0 ? n : {
serverCreatedAt: "asc"
}, ua = (n, e) => {
const t = [
...Array.from(e.values()).slice().reverse(),
...Array.from(n.values())
], r = [
...Array.from(e.values()).slice().reverse().flatMap((s) => s.data.slice().reverse()),
...Array.from(n.values()).flatMap((s) => s.data)
];
return { chunks: t, data: r };
}, ft = ["bootstrap", "bootstrap", "bootstrap", 1], la = (n, e, t, r) => {
const { entityName: s, entityQuery: i } = mr(e), o = i.$?.limit || 10, a = s, c = gr(i.$?.order), u = /* @__PURE__ */ new Map(), l = /* @__PURE__ */ new Map(), f = /* @__PURE__ */ new Map();
let d = !1, h = !0, p = null, m = null;
const b = (w) => {
t({ error: w, data: void 0, canLoadNextPage: !1 });
}, y = () => {
if (!h) return;
const { chunks: w, data: S } = ua(u, l);
t({
data: { [a]: S },
// @ts-expect-error hidden debug variable
chunks: w,
canLoadNextPage: ca(u)
});
}, g = (w, S) => {
u.set(je(w, S.afterInclusive), S), y();
}, A = (w, S) => {
l.set(je(w), S), O(), y();
}, R = (w, S) => {
const { cursor: T } = vn(w);
f.get(we("reverse", T))?.();
const D = n.subscribeQuery(
{
[a]: {
...i,
$: {
after: T,
before: S.endCursor,
beforeInclusive: !0,
where: i.$?.where,
fields: i.$?.fields,
order: An(c)
}
}
},
(Z) => {
if (Z.error)
return b(Z.error);
const Q = Z.data[a], z = Z.pageInfo[a];
Ce(
Q && z,
"Expected query subscription to contain rows and pageInfo"
), A(T, {
data: Q,
status: "frozen",
hasMore: z.hasNextPage,
endCursor: z.endCursor
});
},
r
);
f.set(we("reverse", T), D);
}, k = (w) => {
const S = n.subscribeQuery(
{
[a]: {
...i,
$: {
limit: o,
after: w,
where: i.$?.where,
fields: i.$?.fields,
order: An(c)
}
}
},
(T) => {
if (T.error)
return b(T.error);
const E = T.data[a], D = T.pageInfo[a];
Ce(E && D, "Expected rows and pageInfo"), A(w, {
data: E,
status: "bootstrapping",
hasMore: D.hasNextPage,
endCursor: D.endCursor
});
},
r
);
f.set(we("reverse", w), S);
}, N = (w, S = !1) => {
const T = n.subscribeQuery(
{
[a]: {
...i,
$: {
limit: o,
after: w,
afterInclusive: S,
where: i.$?.where,
fields: i.$?.fields,
order: c
}
}
},
(E) => {
if (E.error)
return b(E.error);
const D = E.data[a], Z = E.pageInfo[a];
Ce(D && Z, "Page info and rows"), g(w, {
data: D,
status: "bootstrapping",
hasMore: Z.hasNextPage,
endCursor: Z.endCursor,
afterInclusive: S
});
},
r
);
f.set(
we("forward", w, S),
T
);
}, C = (w, S = !1) => {
const T = je(w, S);
f.get(
we("forward", w, S)
)?.();
const D = u.get(T);
if (!D?.endCursor) return;
const Z = n.subscribeQuery(
{
[a]: {
...i,
$: {
after: w,
afterInclusive: D.afterInclusive,
before: D.endCursor,
beforeInclusive: !0,
where: i.$?.where,
fields: i.$?.fields,
order: c
}
}
},
(Q) => {
if (Q.error)
return b(Q.error);
const z = Q.data[a], te = Q.pageInfo[a];
Ce(z && te, "Expected rows and pageInfo"), g(w, {
data: z,
status: "frozen",
hasMore: te.hasNextPage,
endCursor: te.endCursor,
afterInclusive: D.afterInclusive
});
},
r
);
f.set(we("forward", w, S), Z);
}, O = () => {
const w = Array.from(l.entries()).at(-1);
if (!w) return;
const [S, T] = w;
if (!T?.hasMore || !aa(T)) return;
const E = `${S}:${oa(T.endCursor)}`;
E != p && (p = E, R(S, T), k(T.endCursor));
}, q = () => {
const w = Array.from(u.entries()).at(-1);
if (!w) return;
const [S, T] = w;
if (!T.endCursor) return;
const { cursor: E, afterInclusive: D } = vn(S);
C(E, D), N(T.endCursor);
};
return m = n.subscribeQuery(
{
[a]: {
...i,
$: {
limit: o,
where: i.$?.where,
fields: i.$?.fields,
order: c
}
}
},
async (w) => {
if (d) return;
if (w.error)
return b(w.error);
const S = w.pageInfo[a], T = w?.data?.[a];
if (Ce(T && S, "Expected rows and pageInfo"), T.length < o) {
g(ft, {
data: T,
status: "pre-bootstrap"
});
return;
}
const E = S.startCursor;
if (!E) {
g(ft, {
data: T,
status: "pre-bootstrap"
});
return;
}
u.delete(je(ft)), N(E, !0), k(S.startCursor), d = !0;
},
r
), {
unsubscribe: () => {
if (h) {
h = !1, m?.(), m = null;
for (const w of f.values())
w?.();
f.clear();
}
},
loadNextPage: q
};
}, Oa = (n, e, t) => {
if (!e)
return {
canLoadNextPage: !1,
data: void 0,
error: void 0
};
const { entityName: r, entityQuery: s } = mr(e), i = s.$?.limit || 10, o = gr(s.$?.order);
let a = e ? wr({
[r]: {
...s,
$: {
limit: i,
where: s.$?.where,
fields: s.$?.fields,
order: o
}
}
}) : null;
return t && "ruleParams" in t && (a = {
$$ruleParams: t.ruleParams,
...a
}), {
canLoadNextPage: !1,
data: n._reactor.getPreviousResult(a)?.data || void 0,
error: void 0
};
}, mr = (n) => {
if (Object.keys(n).length !== 1)
throw new P(
"subscribeInfiniteQuery expects exactly one entity"
);
const [t, r] = Object.entries(n)[0];
if (!t || !r)
throw new P("No query provided for infinite query");
return { entityName: t, entityQuery: r };
}, da = {
apiURI: "https://api.instantdb.com",
websocketURI: "wss://api.instantdb.com/runtime/session"
};
function fa() {
return globalThis.__instantDbSchemaHashStore = globalThis.__instantDbSchemaHashStore ?? /* @__PURE__ */ new WeakMap(), globalThis.__instantDbSchemaHashStore;
}
function ha() {
return globalThis.__instantDbStore = globalThis.__instantDbStore ?? {}, globalThis.__instantDbStore;
}
function Et(n) {
const e = n.__adminToken, t = n.__extraDedupeKey;
return n.appId + "_" + (n.websocketURI || "default_ws_uri") + "_" + (n.apiURI || "default_api_uri") + "_" + (e || "client_only") + "_" + n.useDateObjects + "_" + (t || "");
}
const Mt = ha(), kn = fa();
class pa {
constructor(e) {
this.db = e;
}
/**
* Sends a magic code to the user's email address.
*
* Once you send the magic code, see {@link auth.signInWithMagicCode} to let the
* user verify.
*
* @see https://instantdb.com/docs/auth
* @example
* db.auth.sendMagicCode({email: "example@gmail.com"})
* .catch((err) => console.error(err.body?.message))
*/
sendMagicCode = (e) => this.db.sendMagicCode(e);
/**
* Verify a magic code that was sent to the user's email address.
*
* @see https://instantdb.com/docs/auth
*
* @example
* db.auth.signInWithMagicCode({email: "example@gmail.com", code: "123456"})
* .catch((err) => console.error(err.body?.message))
*/
signInWithMagicCode = (e) => this.db.signInWithMagicCode(e);
/**
* Sign in a user with a refresh token
*
* @see https://instantdb.com/docs/backend#frontend-auth-sign-in-with-token
*
* @example
* // Get the token from your backend
* const token = await fetch('/signin', ...);
* //Sign in
* db.auth.signInWithToken(token);
*/
signInWithToken = (e) => this.db.signInWithCustomToken(e);
/**
* Sign in as guest, creating a new user without email
*
* @see https://instantdb.com/docs/auth
*
* @example
* db.auth.signInAsGuest();
*/
signInAsGuest = (e) => this.db.signInAsGuest(e);
/**
* Create an authorization url to sign in with an external provider.
*
* @see https://instantdb.com/docs/auth
*
* @example
* // Get the authorization url from your backend
* const url = db.auth.createAuthorizationUrl({
* clientName: "google",
* redirectURL: window.location.href,
* });
*
* // Put it in a sign in link
* <a href={url}>Log in with Google</a>
*/
createAuthorizationURL = (e) => this.db.createAuthorizationURL(e);
/**
* Sign in with the id_token from an external provider like Google
*
* @see https://instantdb.com/docs/auth
* @example
* db.auth
* .signInWithIdToken({
* // Token from external service
* idToken: id_token,
* // The name you gave the client when you registered it with Instant
* clientName: "google",
* // The nonce, if any, that you used when you initiated the auth flow
* // with the external service.
* nonce: your_nonce
* })
* .catch((err) => console.error(err.body?.message));
*
*/
signInWithIdToken = (e) => this.db.signInWithIdToken(e);
/**
* Sign in with the id_token from an external provider like Google
*
* @see https://instantdb.com/docs/auth
* @example
* db.auth
* .exchangeOAuthCode({
* // code received in redirect from OAuth callback
* code: code
* // The PKCE code_verifier, if any, that you used when you
* // initiated the auth flow
* codeVerifier: your_code_verifier
* })
* .catch((err) => console.error(err.body?.message));
*
*/
exchangeOAuthCode = (e) => this.db.exchangeCodeForToken(e);
/**
* OpenID Discovery path for use with tools like
* expo-auth-session that use auto-discovery of
* OAuth parameters.
*
* @see https://instantdb.com/docs/auth
* @example
* const discovery = useAutoDiscovery(
* db.auth.issuerURI()
* );
*/
issuerURI = () => this.db.issuerURI();
/**
* Sign out the current user
*/
signOut = (e = { invalidateToken: !0 }) => this.db.signOut(e);
}
class ya {
constructor(e) {
this.db = e;
}
/**
* Uploads file at the provided path.
*
* @see https://instantdb.com/docs/storage
* @example
* const [file] = e.target.files; // result of file input
* const data = await db.storage.uploadFile('photos/demo.png', file);
*/
uploadFile = (e, t, r = {}) => this.db.uploadFile(e, t, r);
/**
* Deletes a file by path name.
*
* @deprecated Use `db.transact` to delete files instead:
* @example
* // Delete by id
* db.transact(db.tx.$files[fileId].delete());
*
* // Delete by path
* db.transact(db.tx.$files[lookup('path', 'photos/demo.png')].delete());
*
* // Delete multiple files
* db.transact(fileIds.map(id => db.tx.$files[id].delete()));
*
* @see https://instantdb.com/docs/storage
*/
delete = (e) => this.db.deleteFile(e);
// Deprecated Storage API (Jan 2025)
// ---------------------------------
/**
* @deprecated. Use `db.storage.uploadFile` instead
* remove in the future.
*/
upload = (e, t) => this.db.upload(e, t);
/**
* @deprecated Use `db.storage.uploadFile` instead
*/
put = this.upload;
/**
* @deprecated. getDownloadUrl will be removed in the future.
* Use `useQuery` instead to query and fetch for valid urls
*
* db.useQuery({
* $files: {
* $: {
* where: {
* path: "moop.png"
* }
* }
* }
* })
*/
getDownloadUrl = (e) => this.db.getDownloadUrl(e);
}
class ba {
constructor(e) {
this.db = e;
}
/**
* Creates a new ReadableStream for the given clientId.
*
* @example
* const stream = db.streams.createReadStream({clientId: clientId})
* for await (const chunk of stream) {
* console.log(chunk);
* }
*/
createReadStream = (e) => this.db.createReadStream(e);
/**
* Creates a new WritableStream for the given clientId.
*
* @example
* const writeStream = db.streams.createWriteStream({clientId: clientId})
* const writer = writeStream.getWriter();
* writer.write('Hello world');
* writer.close();
*/
createWriteStream = (e) => this.db.createWriteStream(e);
}
function wr(n) {
return JSON.parse(JSON.stringify(n));
}
class ga {
_reactor;
auth;
storage;
streams;
tx = er();
constructor(e) {
this._reactor = e, this.auth = new pa(this._reactor), this.storage = new ya(this._reactor), this.streams = new ba(this._reactor);
}
/**
* Use this to write data! You can create, update, delete, and link objects
*
* @see https://instantdb.com/docs/instaml
*
* @example
* // Create a new object in the `goals` namespace
* const goalId = id();
* db.transact(db.tx.goals[goalId].update({title: "Get fit"}))
*
* // Update the title
* db.transact(db.tx.goals[goalId].update({title: "Get super fit"}))
*
* // Delete it
* db.transact(db.tx.goals[goalId].delete())
*
* // Or create an association:
* todoId = id();
* db.transact([
* db.tx.todos[todoId].update({ title: 'Go on a run' }),
* db.tx.goals[goalId].link({todos: todoId}),
* ])
*/
transact(e) {
return this._reactor.pushTx(e);
}
getLocalId(e) {
return this._reactor.getLocalId(e);
}
/**
* Use this to query your data!
*
* @see https://instantdb.com/docs/instaql
*
* @example
* // listen to all goals
* db.subscribeQuery({ goals: {} }, (resp) => {
* console.log(resp.data.goals)
* })
*
* // goals where the title is "Get Fit"
* db.subscribeQuery(
* { goals: { $: { where: { title: "Get Fit" } } } },
* (resp) => {
* console.log(resp.data.goals)
* }
* )
*
* // all goals, _alongside_ their todos
* db.subscribeQuery({ goals: { todos: {} } }, (resp) => {
* console.log(resp.data.goals)
* });
*/
subscribeQuery(e, t, r) {
return this._reactor.subscribeQuery(e, t, r);
}
/**
* Subscribe to a query and incrementally load more items
*
* Only one top level namespace in the query is allowed.
* @example
* const { unsubscribe, loadNextPage } = db.subscribeInfiniteQuery({
* posts: {
* $: {
* limit: 20, // Load 20 posts at a time
* order: {
* createdAt: 'desc',
* },
* },
* },
* (resp) => {
* console.log(resp.data.posts);
* }
* });
*/
subscribeInfiniteQuery(e, t, r) {
return la(
this,
e,
t,
r
);
}
/**
* Listen for the logged in state. This is useful
* for deciding when to show a login screen.
*
* @see https://instantdb.com/docs/auth
* @example
* const unsub = db.subscribeAuth((auth) => {
* if (auth.user) {
* console.log('logged in as', auth.user.email)
* } else {
* console.log('logged out')
* }
* })
*/
subscribeAuth(e) {
return this._reactor.subscribeAuth(e);
}
/**
* One time query for the logged in state. This is useful
* for scenarios where you want to know the current auth
* state without subscribing to changes.
*
* @see https://instantdb.com/docs/auth
* @example
* const user = await db.getAuth();
* console.log('logged in as', user.email)
*/
getAuth() {
return this._reactor.getAuth();
}
/**
* Listen for connection status changes to Instant. This is useful
* for building things like connectivity indicators
*
* @see https://www.instantdb.com/docs/patterns#connection-status
* @example
* const unsub = db.subscribeConnectionStatus((status) => {
* const connectionState =
* status === 'connecting' || status === 'opened'
* ? 'authenticating'
* : status === 'authenticated'
* ? 'connected'
* : status === 'closed'
* ? 'closed'
* : status === 'errored'
* ? 'errored'
* : 'unexpected state';
*
* console.log('Connection status:', connectionState);
* });
*/
subscribeConnectionStatus(e) {
return this._reactor.subscribeConnectionStatus(e);
}
/**
* Observe the app's maintenance-mode state. While read-only, reads and
* live queries keep working but writes are rejected. The callback fires
* immediately with the current state and again on every change.
*
* @example
* const unsub = db.subscribeAppStatus(({ isLoading, isReadOnly }) => {
* if (isLoading) return;
* if (isReadOnly) showMaintenanceBanner();
* });
*/
subscribeAppStatus(e) {
return this._reactor.subscribeAppStatus(e);
}
/**
* Join a room to publish and subscribe to topics and presence.
*
* @see https://instantdb.com/docs/presence-and-topics
* @example
* // init
* const db = init();
* const room = db.joinRoom(roomType, roomId);
* // usage
* const unsubscribeTopic = room.subscribeTopic("foo", console.log);
* const unsubscribePresence = room.subscribePresence({}, console.log);
* room.publishTopic("hello", { message: "hello world!" });
* room.publishPresence({ name: "joe" });
* // later
* unsubscribePresence();
* unsubscribeTopic();
* room.leaveRoom();
*/
joinRoom(e = "_defaultRoomType", t = "_defaultRoomId", r) {
return {
leaveRoom: this._reactor.joinRoom(
e,
t,
r?.initialPresence
),
subscribeTopic: (i, o) => this._reactor.subscribeTopic(e, t, i, o),
subscribePresence: (i, o) => this._reactor.subscribePresence(e, t, i, o),
publishTopic: (i, o) => this._reactor.publishTopic({ roomType: e, roomId: t, topic: i, data: o }),
publishPresence: (i) => this._reactor.publishPresence(e, t, i),
getPresence: (i) => this._reactor.getPresence(e, t, i)
};
}
shutdown() {
delete Mt[Et(this._reactor.config)], this._reactor.shutdown();
}
/**
* Use this for one-off queries.
* Returns local data if available, otherwise fetches from the server.
* Because we want to avoid stale data, this method will throw an error
* if the user is offline or there is no active connection to the server.
*
* @see https://instantdb.com/docs/instaql
*
* @example
*
* const resp = await db.queryOnce({ goals: {} });
* console.log(resp.data.goals)
*/
queryOnce(e, t) {
return this._reactor.queryOnce(e, t);
}
/**
* @deprecated This is an experimental function that is not yet ready for production use.
* Use this function to sync an entire namespace.
* It has many limitations that will be removed in the future:
* 1. Must be used with an admin token
* 2. Does not support permissions
* 3. Does not support where clauses
* 4. Does not support links
* It also does not support multiple top-level namespaces. For example,
* {posts: {}, users: {}} is invalid. Only `posts` or `users` is allowed, but not both.
*/
_syncTableExperimental(e, t) {
return this._reactor.subscribeTable(e, t);
}
}
function On(n) {
if (!n)
return "0";
const e = kn.get(n);
if (e)
return e;
const t = G(n);
return kn.set(n, t), t;
}
function ma(n, e) {
return On(n._reactor.config.schema) !== On(e);
}
function wa(n, e, t, r, s) {
const i = {
...n,
appId: n.appId?.trim(),
useDateObjects: n.useDateObjects ?? !1
}, o = Mt[Et(i)];
if (o)
return ma(o, i.schema) && o._reactor.updateSchema(i.schema), o;
const a = new Ko(
{
...da,
...i,
cardinalityInference: !!i.schema
},
e || sr,
t || ir,
{ ...r || {}, "@instantdb/core": ur },
s
), c = new ga(a);
return Mt[Et(i)] = c, _a(i.appId, i.devtool), c;
}
function _a(n, e) {
if (typeof window > "u" || typeof window.location > "u" || typeof document > "u" || typeof e == "boolean" && !e)
return;
const t = {
position: "bottom-right",
allowedHosts: ["localhost"],
...typeof e == "object" ? e : {}
};
t.allowedHosts.includes(window.location.hostname) && Yo(n, t);
}
const Ia = wa, Ca = rr;
export {
pa as Auth,
ka as FrameworkClient,
sr as IndexedDBStorage,
Le as InstantAPIError,
ga as InstantCoreDatabase,
L as InstantError,
Io as InstantStream,
P as QueryValidationError,
Ko as Reactor,
yo as SSEConnection,
ya as Storage,
Ca as StorageInterface,
rr as StoreInterface,
ba as Streams,
To as SyncTableCallbackEventType,
ne as TransactionValidationError,
ir as WindowNetworkListener,
wr as coerceQuery,
et as coerceToDate,
va as createInstantRouteHandler,
Oa as getInfiniteQueryInitialSnapshot,
di as getOps,
$ as i,
j as id,
wa as init,
Ia as init_experimental,
ui as lookup,
Aa as parseSchemaFromJSON,
Sa as setInstantWarningsEnabled,
Ta as tx,
er as txInit,
pn as validateQuery,
po as validateTransactions,
ur as version,
G as weakHash
};