UNPKG

@rivetkit/framework-base

Version:

_Lightweight Libraries for Backends_

299 lines (298 loc) 8 kB
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 };