@rivetkit/framework-base
Version:
_Lightweight Libraries for Backends_
299 lines (298 loc) • 8 kB
JavaScript
const p = /* @__PURE__ */ new WeakMap(), S = /* @__PURE__ */ new WeakMap(), g = {
current: []
};
let b = !1;
const v = /* @__PURE__ */ new Set(), k = /* @__PURE__ */ new Map();
function C(i) {
const n = Array.from(i).sort((t, e) => t instanceof f && t.options.deps.includes(e) ? 1 : e instanceof f && e.options.deps.includes(t) ? -1 : 0);
for (const t of n) {
if (g.current.includes(t))
continue;
g.current.push(t), t.recompute();
const e = S.get(t);
if (e)
for (const s of e) {
const o = p.get(s);
o && C(o);
}
}
}
function F(i) {
i.listeners.forEach(
(n) => n({
prevVal: i.prevState,
currentVal: i.state
})
);
}
function O(i) {
i.listeners.forEach(
(n) => n({
prevVal: i.prevState,
currentVal: i.state
})
);
}
function G(i) {
if (v.add(i), !b)
try {
for (b = !0; v.size > 0; ) {
const n = Array.from(v);
v.clear();
for (const t of n) {
const e = k.get(t) ?? t.prevState;
t.prevState = e, F(t);
}
for (const t of n) {
const e = p.get(t);
e && (g.current.push(t), C(e));
}
for (const t of n) {
const e = p.get(t);
if (e)
for (const s of e)
O(s);
}
}
} finally {
b = !1, g.current = [], k.clear();
}
}
function I(i) {
return typeof i == "function";
}
class m {
constructor(n, t) {
this.listeners = /* @__PURE__ */ new Set(), this.subscribe = (e) => {
var s, o;
this.listeners.add(e);
const h = (o = (s = this.options) == null ? void 0 : s.onSubscribe) == null ? void 0 : o.call(s, e, this);
return () => {
this.listeners.delete(e), h == null || h();
};
}, this.prevState = n, this.state = n, this.options = t;
}
setState(n) {
var t, e, s;
this.prevState = this.state, (t = this.options) != null && t.updateFn ? this.state = this.options.updateFn(this.prevState)(n) : I(n) ? this.state = n(this.prevState) : this.state = n, (s = (e = this.options) == null ? void 0 : e.onUpdate) == null || s.call(e), G(this);
}
}
class f {
constructor(n) {
this.listeners = /* @__PURE__ */ new Set(), this._subscriptions = [], this.lastSeenDepValues = [], this.getDepVals = () => {
const t = [], e = [];
for (const s of this.options.deps)
t.push(s.prevState), e.push(s.state);
return this.lastSeenDepValues = e, {
prevDepVals: t,
currDepVals: e,
prevVal: this.prevState ?? void 0
};
}, this.recompute = () => {
var t, e;
this.prevState = this.state;
const { prevDepVals: s, currDepVals: o, prevVal: h } = this.getDepVals();
this.state = this.options.fn({
prevDepVals: s,
currDepVals: o,
prevVal: h
}), (e = (t = this.options).onUpdate) == null || e.call(t);
}, this.checkIfRecalculationNeededDeeply = () => {
for (const o of this.options.deps)
o instanceof f && o.checkIfRecalculationNeededDeeply();
let t = !1;
const e = this.lastSeenDepValues, { currDepVals: s } = this.getDepVals();
for (let o = 0; o < s.length; o++)
if (s[o] !== e[o]) {
t = !0;
break;
}
t && this.recompute();
}, this.mount = () => (this.registerOnGraph(), this.checkIfRecalculationNeededDeeply(), () => {
this.unregisterFromGraph();
for (const t of this._subscriptions)
t();
}), this.subscribe = (t) => {
var e, s;
this.listeners.add(t);
const o = (s = (e = this.options).onSubscribe) == null ? void 0 : s.call(e, t, this);
return () => {
this.listeners.delete(t), o == null || o();
};
}, this.options = n, this.state = n.fn({
prevDepVals: void 0,
prevVal: void 0,
currDepVals: this.getDepVals().currDepVals
});
}
registerOnGraph(n = this.options.deps) {
for (const t of n)
if (t instanceof f)
t.registerOnGraph(), this.registerOnGraph(t.options.deps);
else if (t instanceof m) {
let e = p.get(t);
e || (e = /* @__PURE__ */ new Set(), p.set(t, e)), e.add(this);
let s = S.get(this);
s || (s = /* @__PURE__ */ new Set(), S.set(this, s)), s.add(t);
}
}
unregisterFromGraph(n = this.options.deps) {
for (const t of n)
if (t instanceof f)
this.unregisterFromGraph(t.options.deps);
else if (t instanceof m) {
const e = p.get(t);
e && e.delete(this);
const s = S.get(this);
s && s.delete(t);
}
}
}
class R {
constructor(n) {
const { eager: t, fn: e, ...s } = n;
this._derived = new f({
...s,
fn: () => {
},
onUpdate() {
e();
}
}), t && e();
}
mount() {
return this._derived.mount();
}
}
function N(i, n = {}) {
const t = new m({
actors: {}
}), e = n.hashFunction || L, s = /* @__PURE__ */ new Map();
function o(h) {
const r = e(h), _ = s.get(r);
if (_)
return {
..._,
state: _.state
};
const d = new f({
fn: ({ currDepVals: [a] }) => a.actors[r],
deps: [t]
});
function V() {
async function a() {
const c = t.state.actors[r];
try {
const u = i.getOrCreate(
c.opts.name,
c.opts.key,
{
params: c.opts.params,
createInRegion: c.opts.createInRegion,
createWithInput: c.opts.createWithInput
}
), l = u.connect();
await u.resolve(
/*{ signal: AbortSignal.timeout(0) }*/
), t.setState((D) => ({
...D,
actors: {
...D.actors,
[r]: {
...D.actors[r],
isConnected: !0,
isConnecting: !1,
handle: u,
connection: l,
isError: !1,
error: null
}
}
}));
} catch (u) {
t.setState((l) => ({
...l,
actors: {
...l.actors,
[r]: {
...l.actors[r],
isError: !0,
isConnecting: !1,
error: u
}
}
}));
}
}
t.setState((c) => (c.actors[r].isConnecting = !0, c.actors[r].isError = !1, c.actors[r].error = null, a(), c));
}
const E = new R({
fn: () => {
const a = t.state.actors[r];
JSON.stringify(t.prevState.actors[r].opts) === JSON.stringify(t.state.actors[r].opts) && !a.isConnected && !a.isConnecting && !a.isError && a.opts.enabled && V();
},
deps: [d]
});
t.setState((a) => a.actors[r] ? a : {
...a,
actors: {
...a.actors,
[r]: {
hash: r,
isConnected: !1,
isConnecting: !1,
connection: null,
handle: null,
isError: !1,
error: null,
opts: h
}
}
});
function w(a) {
t.setState((c) => {
const u = c.actors[r];
if (!u)
throw new Error(`Actor with key "${r}" does not exist.`);
let l;
return typeof a == "function" ? l = a(u) : l = a, {
...c,
actors: {
...c.actors,
[r]: l
}
};
});
}
const y = () => {
const a = d.mount(), c = E.mount();
return () => {
a(), c();
};
};
return s.set(r, {
state: d,
key: r,
mount: y,
setState: w,
create: V,
addEventListener
}), {
mount: y,
setState: w,
state: d,
create: V,
key: r
};
}
return {
getOrCreateActor: o,
store: t
};
}
function L({ name: i, key: n, params: t }) {
return JSON.stringify({ name: i, key: n, params: t });
}
export {
N as createRivetKit
};