UNPKG

@viamedici-spc/configurator-react

Version:

React library to build configurator web applications based on the Viamedici Headless Configuration Engine (HCE).

1,111 lines (1,110 loc) 37.8 kB
import { GlobalAttributeIdKeyBuilder as yt, globalAttributeIdKeyEq as Nt, globalAttributeIdEq as Wt, Logger as x, SessionFactory as Ot, DecisionKind as L, AttributeType as J, ExplainQuestionSubject as N, AttributeRefinements as rt, AttributeInterpreter as B, ExplainQuestionType as It, ChoiceValueInterpreter as Et } from "@viamedici-spc/configurator-ts"; import { pipe as j, RA as k, RM as H, Ord as kt, O as K, identity as et, Eq as b, Bool as at, Str as Rt, TE as nt, E as Bt, T as Lt, constVoid as Kt } from "@viamedici-spc/fp-ts-extensions"; import { atom as f, getDefaultStore as Qt, useSetAtom as Ft, useAtomValue as Ct, useAtom as G, Provider as $t } from "jotai"; import { createContext as Dt, useContext as Mt, useMemo as X, useEffect as At } from "react"; import { useStableMemo as Jt } from "fp-ts-react-stable-hooks"; import { selectAtom as zt, atomFamily as _ } from "jotai/utils"; import { jsx as q, Fragment as Pt, jsxs as Ht } from "react/jsx-runtime"; import { guid as Xt } from "dyna-guid"; import { atomEffect as ut } from "jotai-effect"; import { atomWithMachine as Yt } from "jotai-xstate"; import { fromPromise as Zt, setup as Gt, assign as ft, log as te, enqueueActions as gt } from "xstate"; const E = "ConfigurationUninitialized"; function D(t) { return f((e) => { try { return t(e, (n) => { const i = e(n); if (i === E) throw E; return i; }); } catch (n) { if (n === E) return E; throw n; } }); } function ht(t) { const { guardedConfigurationAtom: e, guardedAttributesAtom: n } = t; function i(o, s) { const r = o === "all" ? "all" : j( o, k.map((u) => typeof u == "string" ? u : yt(u)) ); return D((u, a) => { if (r === "all") return j(e, a, (m) => m.attributes, H.values(kt.trivial)); const c = a(n); return j( r, k.map((m) => u(c(m))), s ? k.filterMap(K.fromNullable) : et ); }); } return i; } const xt = globalThis.configuratorReactContexts ?? { AtomsContext: Dt(null), StoreContext: Dt(Qt()) }; globalThis.configuratorReactContexts = xt; const Ut = xt.AtomsContext, qt = xt.StoreContext, W = () => Mt(Ut), ct = () => Mt(qt); function vt(t, e, n) { const i = b.tuple(b.eqNullable(at.Eq), n); return (o, ...s) => { const r = W(), u = ct(), a = Ft(r.selectors.subscriberAtom, { store: u }), c = Jt(() => o ?? !0 ? e(r, ...s) : t(r, ...s), [o, s], i), m = X(() => a(c), [a, c]); return At(() => () => { m.unsubscribe(); }, [m]), Ct(c, { store: u }); }; } function y(t, e) { const n = vt((o) => t(o.selectors), (o) => e(o.suspended), b.tuple()); function i(o) { return n(o); } return i; } function lt(t, e) { const n = vt((o, s) => t(o.selectors)(s), (o, s) => e(o.suspended)(s), b.tuple(Rt.Eq)); function i(o, s) { const r = X(() => typeof o == "string" ? o : yt(o), [o]); return n(s, r); } return i; } function ee() { const t = {}; return t.promise = new Promise((e, n) => { t.resolve = e, t.reject = n; }), t; } function g(t) { const e = zt(t, (n, i) => { if (n !== E) return (i == null ? void 0 : i.deferredPromise) != null ? (i.deferredPromise.resolve(n), { deferredPromise: null, result: i.deferredPromise.promise }) : { deferredPromise: null, result: n }; const o = (i == null ? void 0 : i.deferredPromise) ?? ee(); return { deferredPromise: o, result: o.promise }; }); return f((n) => n(e).result); } const ne = b.union().with((t) => typeof t == "string", Nt).with((t) => typeof t == "object", Wt), ie = b.union().with((t) => t === "all", Rt.Eq).with((t) => Array.isArray(t), k.getEq(ne)), oe = vt( (t, e, n) => ht(t.selectors)(e, n), (t, e, n) => g(ht(t.selectors)(e, n)), b.tuple(ie, b.eqNullable(at.Eq)) ); function Rn(t, e, n) { const i = t == "all" ? e : n, o = t == "all" ? void 0 : e; return oe(i, t, o); } const Fn = lt((t) => t.choiceAttributeAtomFamily, (t) => t.choiceAttributeAtomFamily), Mn = lt((t) => t.numericAttributeAtomFamily, (t) => t.numericAttributeAtomFamily), zn = lt((t) => t.booleanAttributeAtomFamily, (t) => t.booleanAttributeAtomFamily), Pn = lt((t) => t.componentAttributeAtomFamily, (t) => t.componentAttributeAtomFamily); function se() { const { effects: t } = W(), { addSessionListenersEffect: e, cleanupAtomFamiliesEffect: n, atomSubscriberEffect: i, atomSubscriptionCleanupEffect: o } = t; return G(e), G(n), G(i), G(o), null; } const re = 30 * 1e3, ae = WeakRef != null ? (t) => new WeakRef(t) : (t) => ({ deref: () => t }); function ue() { return f(H.empty); } function ce(t) { return f(null, (e, n, i) => { const o = Xt(); x.debug("AtomSubscription:", "Creating subscription with id", o); const r = { unsubscribe: () => { n(t.subscriptionsAtom, (u) => { const a = u.get(i); if (a == null) return u; const c = new Map(a); c.delete(o); const m = new Map(u); return m.set(i, c), m; }); } }; return n(t.subscriptionsAtom, (u) => { const a = new Map(u.get(i) ?? H.empty); a.set(o, ae(r)); const c = new Map(u); return c.set(i, a), c; }), r; }); } function le(t) { return ut((e) => { const i = [...e(t.subscriptionsAtom).keys()]; x.debug("AtomSubscriber:", "There are", i.length, "Atoms to subscribe to."); for (const o of i) e(o); }); } function me(t) { return ut((e, n) => { const i = setInterval(() => { x.info("AtomSubscriptionCleanup:", "Running cleanup"); let o = !1; n(t.subscriptionsAtom, (s) => { const r = new Map(s); for (const u of [...r.keys()]) { const a = new Map(r.get(u) ?? H.empty); for (const c of [...a.keys()]) { const m = a.get(c); (m === void 0 || m.deref() === void 0) && (x.debug("AtomSubscriptionCleanup:", "Deleting subscription", c, "because it got garbage collected."), a.delete(c), o = !0); } r.set(u, a), a.size === 0 && (x.debug("AtomSubscriptionCleanup:", "Delete Atom with 0 subscriptions."), r.delete(u), o = !0); } return x.debug("AtomSubscriptionCleanup:", "There are", r.size, "Atoms with", [...r.values(), k.flatten].length, "subscriptions left."), o ? r : s; }); }, re); return () => { clearInterval(i); }; }); } const de = Zt(({ input: t }) => j( t.session, K.match( () => () => Ot.createSession(t.sessionContext), (e) => async () => (await e.setSessionContext(t.sessionContext), e) ), (e) => nt.tryCatch(e, (n) => n), nt.mapLeft((e) => ({ sessionContext: t.sessionContext, configurationError: e })) )()), fe = Gt({ types: { context: {}, events: {} }, actors: { createOrUpdateSession: de }, guards: { shallProcess: ({ context: t }) => ( // If there is no error or the SessionContext that resulted in an error is no longer desired. (t.sessionCreateOrUpdateError == null || t.sessionCreateOrUpdateError.sessionContext !== t.desiredSessionContext) && // Initially there is no Session but a SessionContext (t.configurationSession == null && t.desiredSessionContext != null || t.configurationSession != null && t.configurationSession.getSessionContext() !== t.desiredSessionContext) ), shallDispose: ({ context: t }) => t.configurationSession != null && t.desiredSessionContext == null } }).createMachine({ context: { desiredSessionContext: null, configurationSession: null, sessionCreateOrUpdateError: null }, on: { Retry: { actions: [ ft({ sessionCreateOrUpdateError: () => null }) ] }, SessionContextChanged: { actions: [ te("SessionContextChanged"), ft({ desiredSessionContext: ({ event: t }) => t.sessionContext }) ] }, Shutdown: { target: "#shutdown" } }, initial: "Idle", states: { Idle: { always: [ { target: "DisposeSession", guard: "shallDispose" }, { target: "Processing", guard: "shallProcess" } ] }, Processing: { entry: [ ft({ sessionCreateOrUpdateError: () => null }) ], invoke: { src: "createOrUpdateSession", input: ({ context: t }) => ({ sessionContext: t.desiredSessionContext, session: K.fromNullable(t.configurationSession) }), onDone: { target: "Idle", actions: [ gt(({ event: t, enqueue: e }) => { Bt.isRight(t.output) ? e.assign({ configurationSession: t.output.right }) : e.assign({ sessionCreateOrUpdateError: t.output.left }); }) ] } } }, DisposeSession: { always: [{ target: "Idle", actions: [ gt(({ enqueue: t, context: e }) => { nt.tryCatch(async () => { var n; return await ((n = e.configurationSession) == null ? void 0 : n.close()); }, et)(), t.assign({ configurationSession: () => null, sessionCreateOrUpdateError: () => null }); }) ] }] }, Shutdown: { type: "final", id: "shutdown", entry: [ gt(({ context: t, enqueue: e }) => { t.configurationSession && nt.tryCatch(async () => { var n; return await ((n = t.configurationSession) == null ? void 0 : n.close()); }, et)(), e.assign({ configurationSession: () => null, desiredSessionContext: () => null, sessionCreateOrUpdateError: () => null }); }) ] } } }); function ge() { return Yt(fe); } function Ae(t) { return f((e) => e(t.sessionManagementMachineAtom).context.configurationSession); } function he(t) { const e = f((o, s) => { var m; const r = o(t.sessionManagementMachineAtom), u = r.matches("Processing"), a = r.context.configurationSession != null, c = (m = r.context.sessionCreateOrUpdateError) != null && m.configurationError ? { ...r.context.sessionCreateOrUpdateError.configurationError, retry: () => { s.setSelf(); } } : null; return { isProcessing: u, hasSession: a, error: c }; }, (o, s) => { s(t.sessionManagementMachineAtom, { type: "Retry" }); }), n = f((o) => { const { hasSession: s, error: r, isProcessing: u } = o(e); return { isInitializing: !s && u, error: !s && r ? r : void 0 }; }), i = f((o) => { const { hasSession: s, error: r, isProcessing: u } = o(e); return { isUpdating: s && u, error: s && r ? r : void 0 }; }); return { sessionInitializationAtom: n, sessionUpdatingAtom: i }; } const pe = () => _(() => f()), be = () => f(), Se = () => f(), ye = () => f(), Ce = () => f(); function xe(t, e) { const { attributesAtom: n, configurationAtom: i, isSatisfiedAtom: o, canResetAtom: s } = t, { configurationSessionAtom: r } = e; return ut((u, a) => { const c = u(r); if (!c) { a(i, void 0), a(o, void 0), a(n, void 0), a(s, void 0); return; } const m = c.addConfigurationChangedListener((R, F) => { x.debug("SessionSubscription:", "Received ConfigurationChanged"), a(i, R), F.isSatisfied != null && a(o, F.isSatisfied); const Z = u.peek(n), V = Z ?? pe(); F.attributes.added.forEach((C) => { a(V(C.key), C); }), F.attributes.changed.forEach((C) => { a(V(C.key), C); }), F.attributes.removed.forEach((C) => { a(V(yt(C)), void 0); }), Z == null && a(n, () => V); }), Y = c.addCanResetConfigurationChangedListener((R) => { x.debug("SessionSubscription:", "Received CanResetConfigurationChanged"), a(s, R); }); return () => { m.unsubscribe(), Y.unsubscribe(); }; }); } function mt(t, e, n) { const i = f((o) => { const s = o(t); if (!s) return; const r = f(); return r.onMount = (u) => { const a = e(s, (...c) => { u(c); }); return () => { u(void 0), a.unsubscribe(); }; }, r; }); return f((o) => { const s = o(i); if (s == null) return; const r = o(s); if (r != null) return n(...r); }); } function ve(t) { return mt(t, (e, n) => e.addStoredConfigurationChangedListener(n), (e) => e); } function we(t) { return mt(t, (e, n) => e.addDecisionsChangedListener(n), (e) => e); } function Ee(t) { return mt(t, (e, n) => e.addDecisionsChangedListener(L.Explicit, n), (e) => e); } function De(t) { return mt(t, (e, n) => e.addDecisionsChangedListener(L.Implicit, n), (e) => e); } const Ie = () => ({ sessionManagementMachineAtom: ge(), configurationAtom: be(), isSatisfiedAtom: Se(), canResetAtom: ye(), attributesAtom: Ce(), subscriptionsAtom: ue() }); function ke(t, e) { return D((n, i) => { const o = i(t); return { canResetConfiguration: i(e), resetConfiguration: o.resetConfiguration.bind(o) }; }); } function Re(t) { return D((e, n) => { const i = n(t); return { explain: i.explain.bind(i), applySolution: i.applySolution.bind(i) }; }); } function Fe(t) { return j( t.values, H.values(kt.trivial), k.filter((e) => { var n; return ((n = e.decision) == null ? void 0 : n.kind) === L.Explicit; }), k.map((e) => ({ type: J.Choice, attributeId: t.id, choiceValueId: e.id, state: null })) ); } const p = Symbol.for("@ts-pattern/matcher"), jt = Symbol.for("@ts-pattern/isVariadic"), it = "@ts-pattern/anonymous-select-key", pt = (t) => !!(t && typeof t == "object"), tt = (t) => t && !!t[p], A = (t, e, n) => { if (tt(t)) { const i = t[p](), { matched: o, selections: s } = i.match(e); return o && s && Object.keys(s).forEach((r) => n(r, s[r])), o; } if (pt(t)) { if (!pt(e)) return !1; if (Array.isArray(t)) { if (!Array.isArray(e)) return !1; let i = [], o = [], s = []; for (const r of t.keys()) { const u = t[r]; tt(u) && u[jt] ? s.push(u) : s.length ? o.push(u) : i.push(u); } if (s.length) { if (s.length > 1) throw new Error("Pattern error: Using `...P.array(...)` several times in a single pattern is not allowed."); if (e.length < i.length + o.length) return !1; const r = e.slice(0, i.length), u = o.length === 0 ? [] : e.slice(-o.length), a = e.slice(i.length, o.length === 0 ? 1 / 0 : -o.length); return i.every((c, m) => A(c, r[m], n)) && o.every((c, m) => A(c, u[m], n)) && (s.length === 0 || A(s[0], a, n)); } return t.length === e.length && t.every((r, u) => A(r, e[u], n)); } return Reflect.ownKeys(t).every((i) => { const o = t[i]; return (i in e || tt(s = o) && s[p]().matcherType === "optional") && A(o, e[i], n); var s; }); } return Object.is(e, t); }, S = (t) => { var e, n, i; return pt(t) ? tt(t) ? (e = (n = (i = t[p]()).getSelectionKeys) == null ? void 0 : n.call(i)) != null ? e : [] : Array.isArray(t) ? Q(t, S) : Q(Object.values(t), S) : []; }, Q = (t, e) => t.reduce((n, i) => n.concat(e(i)), []); function Me(...t) { if (t.length === 1) { const [e] = t; return (n) => A(e, n, () => { }); } if (t.length === 2) { const [e, n] = t; return A(e, n, () => { }); } throw new Error(`isMatching wasn't given the right number of arguments: expected 1 or 2, received ${t.length}.`); } function h(t) { return Object.assign(t, { optional: () => wt(t), and: (e) => d(t, e), or: (e) => Tt(t, e), select: (e) => e === void 0 ? $(t) : $(e, t) }); } function bt(t) { return Object.assign(((e) => Object.assign(e, { [Symbol.iterator]() { let n = 0; const i = [{ value: Object.assign(e, { [jt]: !0 }), done: !1 }, { done: !0, value: void 0 }]; return { next: () => { var o; return (o = i[n++]) != null ? o : i.at(-1); } }; } }))(t), { optional: () => bt(wt(t)), select: (e) => bt(e === void 0 ? $(t) : $(e, t)) }); } function wt(t) { return h({ [p]: () => ({ match: (e) => { let n = {}; const i = (o, s) => { n[o] = s; }; return e === void 0 ? (S(t).forEach((o) => i(o, void 0)), { matched: !0, selections: n }) : { matched: A(t, e, i), selections: n }; }, getSelectionKeys: () => S(t), matcherType: "optional" }) }); } const ze = (t, e) => { for (const n of t) if (!e(n)) return !1; return !0; }, Pe = (t, e) => { for (const [n, i] of t.entries()) if (!e(i, n)) return !1; return !0; }; function d(...t) { return h({ [p]: () => ({ match: (e) => { let n = {}; const i = (o, s) => { n[o] = s; }; return { matched: t.every((o) => A(o, e, i)), selections: n }; }, getSelectionKeys: () => Q(t, S), matcherType: "and" }) }); } function Tt(...t) { return h({ [p]: () => ({ match: (e) => { let n = {}; const i = (o, s) => { n[o] = s; }; return Q(t, S).forEach((o) => i(o, void 0)), { matched: t.some((o) => A(o, e, i)), selections: n }; }, getSelectionKeys: () => Q(t, S), matcherType: "or" }) }); } function l(t) { return { [p]: () => ({ match: (e) => ({ matched: !!t(e) }) }) }; } function $(...t) { const e = typeof t[0] == "string" ? t[0] : void 0, n = t.length === 2 ? t[1] : typeof t[0] == "string" ? void 0 : t[0]; return h({ [p]: () => ({ match: (i) => { let o = { [e ?? it]: i }; return { matched: n === void 0 || A(n, i, (s, r) => { o[s] = r; }), selections: o }; }, getSelectionKeys: () => [e ?? it].concat(n === void 0 ? [] : S(n)) }) }); } function v(t) { return typeof t == "number"; } function M(t) { return typeof t == "string"; } function z(t) { return typeof t == "bigint"; } const Vt = h(l(function(t) { return !0; })), Ue = Vt, P = (t) => Object.assign(h(t), { startsWith: (e) => { return P(d(t, (n = e, l((i) => M(i) && i.startsWith(n))))); var n; }, endsWith: (e) => { return P(d(t, (n = e, l((i) => M(i) && i.endsWith(n))))); var n; }, minLength: (e) => P(d(t, ((n) => l((i) => M(i) && i.length >= n))(e))), length: (e) => P(d(t, ((n) => l((i) => M(i) && i.length === n))(e))), maxLength: (e) => P(d(t, ((n) => l((i) => M(i) && i.length <= n))(e))), includes: (e) => { return P(d(t, (n = e, l((i) => M(i) && i.includes(n))))); var n; }, regex: (e) => { return P(d(t, (n = e, l((i) => M(i) && !!i.match(n))))); var n; } }), qe = P(l(M)), w = (t) => Object.assign(h(t), { between: (e, n) => w(d(t, ((i, o) => l((s) => v(s) && i <= s && o >= s))(e, n))), lt: (e) => w(d(t, ((n) => l((i) => v(i) && i < n))(e))), gt: (e) => w(d(t, ((n) => l((i) => v(i) && i > n))(e))), lte: (e) => w(d(t, ((n) => l((i) => v(i) && i <= n))(e))), gte: (e) => w(d(t, ((n) => l((i) => v(i) && i >= n))(e))), int: () => w(d(t, l((e) => v(e) && Number.isInteger(e)))), finite: () => w(d(t, l((e) => v(e) && Number.isFinite(e)))), positive: () => w(d(t, l((e) => v(e) && e > 0))), negative: () => w(d(t, l((e) => v(e) && e < 0))) }), je = w(l(v)), U = (t) => Object.assign(h(t), { between: (e, n) => U(d(t, ((i, o) => l((s) => z(s) && i <= s && o >= s))(e, n))), lt: (e) => U(d(t, ((n) => l((i) => z(i) && i < n))(e))), gt: (e) => U(d(t, ((n) => l((i) => z(i) && i > n))(e))), lte: (e) => U(d(t, ((n) => l((i) => z(i) && i <= n))(e))), gte: (e) => U(d(t, ((n) => l((i) => z(i) && i >= n))(e))), positive: () => U(d(t, l((e) => z(e) && e > 0))), negative: () => U(d(t, l((e) => z(e) && e < 0))) }), Te = U(l(z)), Ve = h(l(function(t) { return typeof t == "boolean"; })), _e = h(l(function(t) { return typeof t == "symbol"; })), Ne = h(l(function(t) { return t == null; })), We = h(l(function(t) { return t != null; })); var Oe = { __proto__: null, matcher: p, optional: wt, array: function(...t) { return bt({ [p]: () => ({ match: (e) => { if (!Array.isArray(e)) return { matched: !1 }; if (t.length === 0) return { matched: !0 }; const n = t[0]; let i = {}; if (e.length === 0) return S(n).forEach((s) => { i[s] = []; }), { matched: !0, selections: i }; const o = (s, r) => { i[s] = (i[s] || []).concat([r]); }; return { matched: e.every((s) => A(n, s, o)), selections: i }; }, getSelectionKeys: () => t.length === 0 ? [] : S(t[0]) }) }); }, set: function(...t) { return h({ [p]: () => ({ match: (e) => { if (!(e instanceof Set)) return { matched: !1 }; let n = {}; if (e.size === 0) return { matched: !0, selections: n }; if (t.length === 0) return { matched: !0 }; const i = (s, r) => { n[s] = (n[s] || []).concat([r]); }, o = t[0]; return { matched: ze(e, (s) => A(o, s, i)), selections: n }; }, getSelectionKeys: () => t.length === 0 ? [] : S(t[0]) }) }); }, map: function(...t) { return h({ [p]: () => ({ match: (e) => { if (!(e instanceof Map)) return { matched: !1 }; let n = {}; if (e.size === 0) return { matched: !0, selections: n }; const i = (u, a) => { n[u] = (n[u] || []).concat([a]); }; if (t.length === 0) return { matched: !0 }; var o; if (t.length === 1) throw new Error(`\`P.map\` wasn't given enough arguments. Expected (key, value), received ${(o = t[0]) == null ? void 0 : o.toString()}`); const [s, r] = t; return { matched: Pe(e, (u, a) => { const c = A(s, a, i), m = A(r, u, i); return c && m; }), selections: n }; }, getSelectionKeys: () => t.length === 0 ? [] : [...S(t[0]), ...S(t[1])] }) }); }, intersection: d, union: Tt, not: function(t) { return h({ [p]: () => ({ match: (e) => ({ matched: !A(t, e, () => { }) }), getSelectionKeys: () => [], matcherType: "not" }) }); }, when: l, select: $, any: Vt, _: Ue, string: qe, number: je, bigint: Te, boolean: Ve, symbol: _e, nullish: Ne, nonNullable: We, instanceOf: function(t) { return h(l(/* @__PURE__ */ function(e) { return (n) => n instanceof e; }(t))); }, shape: function(t) { return h(l(Me(t))); } }; class Be extends Error { constructor(e) { let n; try { n = JSON.stringify(e); } catch { n = e; } super(`Pattern matching error: no pattern matches value ${n}`), this.input = void 0, this.input = e; } } const St = { matched: !1, value: void 0 }; function ot(t) { return new st(t, St); } class st { constructor(e, n) { this.input = void 0, this.state = void 0, this.input = e, this.state = n; } with(...e) { if (this.state.matched) return this; const n = e[e.length - 1], i = [e[0]]; let o; e.length === 3 && typeof e[1] == "function" ? o = e[1] : e.length > 2 && i.push(...e.slice(1, e.length - 1)); let s = !1, r = {}; const u = (c, m) => { s = !0, r[c] = m; }, a = !i.some((c) => A(c, this.input, u)) || o && !o(this.input) ? St : { matched: !0, value: n(s ? it in r ? r[it] : r : this.input, this.input) }; return new st(this.input, a); } when(e, n) { if (this.state.matched) return this; const i = !!e(this.input); return new st(this.input, i ? { matched: !0, value: n(this.input, this.input) } : St); } otherwise(e) { return this.state.matched ? this.state.value : e(this.input); } exhaustive() { if (this.state.matched) return this.state.value; throw new Be(this.input); } run() { return this.exhaustive(); } returnType() { return this; } } function T(t, e) { var n = 0, i, o; e = e || {}; function s() { var r = i, u = arguments.length, a, c; t: for (; r; ) { if (r.args.length !== arguments.length) { r = r.next; continue; } for (c = 0; c < u; c++) if (r.args[c] !== arguments[c]) { r = r.next; continue t; } return r !== i && (r === o && (o = r.prev), r.prev.next = r.next, r.next && (r.next.prev = r.prev), r.next = i, r.prev = null, i.prev = r, i = r), r.val; } for (a = new Array(u), c = 0; c < u; c++) a[c] = arguments[c]; return r = { args: a, // Generate the result from original function val: t.apply(null, a) }, i ? (i.prev = r, r.next = i) : o = r, n === /** @type {MemizeOptions} */ e.maxSize ? (o = /** @type {MemizeCacheNode} */ o.prev, o.next = null) : n++, i = r, r.val; } return s.clear = function() { i = null, o = null, n = 0; }, s; } function Le(t, e, n) { return dt( t, n, rt.choiceAttributeRefinement, N.choiceValue, (i, o, s) => { const { makeDecision: r, makeManyDecisions: u } = s(e); return { makeDecision: (a, c) => r({ type: J.Choice, attributeId: i.id, choiceValueId: a, state: c }), clearDecisions: () => j( i, Fe, // Only execute if there are decisions to clear. K.fromPredicate(k.isNonEmpty), K.match( () => () => Promise.resolve(), (a) => j(() => u(a, { type: "KeepExistingDecisions" }), Lt.map(Kt)) ) )(), isMultiSelect: T(() => B.isChoiceAttributeMultiSelect(i)), getAllowedChoiceValues: T(() => B.getAllowedChoiceValues(i)), getIncludedChoiceValues: T(() => B.getIncludedChoiceValues(i)), getBlockedChoiceValues: T(() => B.getBlockedChoiceValues(i)), isChoiceValueAllowed: T((a) => Et.isAllowed(a)), isChoiceValueBlocked: T((a) => Et.isBlocked(a)) }; } ); } function Ke(t, e, n) { return dt( t, n, rt.numericAttributeRefinement, N.numeric, (i, o, s) => { const { makeDecision: r } = s(e); return { makeDecision: (u) => r({ type: J.Numeric, attributeId: i.id, state: u }) }; } ); } function Qe(t, e, n) { return dt( t, n, rt.booleanAttributeRefinement, N.boolean, (i, o, s) => { const { makeDecision: r } = s(e); return { makeDecision: (u) => r({ type: J.Boolean, attributeId: i.id, state: u }) }; } ); } function $e(t, e, n) { return dt( t, n, rt.componentAttributeRefinement, N.component, (i, o, s) => { const { makeDecision: r } = s(e); return { makeDecision: (u) => r({ type: J.Component, attributeId: i.id, state: u }) }; } ); } function dt(t, e, n, i, o) { return _((s) => D((r, u) => { const a = u(t), c = r(a(s)); if (!c || !n(c)) return; const { explain: m, applySolution: Y } = u(e), R = o(c, r, u); return R === E ? E : { attribute: c, isMandatory: T(() => B.isMandatory(c)), explain: (F, Z) => { const V = ot(F.question).with(It.whyIsNotSatisfied, () => N.attribute).otherwise(() => i), C = { ...F, subject: V, attributeId: c.id }; return ot(Z).with("decisions", (O) => m(C, O)).with("constraints", (O) => m(C, O)).with("full", (O) => m(C, O)).exhaustive(); }, applySolution: Y, ...R }; })); } function _t(t, e) { const n = zt(t, et, e.equals); return "write" in t ? f((i) => i(n), (i, o, ...s) => o(t, ...s)) : n; } const Je = b.struct({ isInitializing: at.Eq, error: b.eqNullable(b.eqStrict) }); function He(t, e, n, i, o, s) { const r = [ e, n, i, o, s ], u = f((a) => { const c = j( r, k.every((R) => a(R) !== E) ), m = a(t); return { isInitializing: !(!m.isInitializing && c), error: m.error }; }); return _t(u, Je); } const Xe = b.struct({ isUpdating: at.Eq, error: b.eqNullable(b.eqStrict) }); function Ye(t) { return _t(t, Xe); } function Ze(t) { return D((e, n) => { const i = n(t); return { storeConfiguration: i.storeConfiguration.bind(i), restoreConfiguration: i.restoreConfiguration.bind(i) }; }); } function Ge(t, e) { const n = { question: It.whyIsNotSatisfied, subject: N.configuration }; return D((i, o) => { const s = o(t); return { isSatisfied: o(e), explain: (u) => ot(u).with("full", (a) => s.explain(n, a)).with("decisions", (a) => s.explain(n, a)).with("constraints", (a) => s.explain(n, a)).exhaustive() }; }); } function tn(t) { return D((e, n) => { const i = n(t); return { reinitializeSession: i.reinitialize.bind(i) }; }); } function en(t) { return D((e, n) => { const i = n(t); return { scheduleTask: i.scheduleTask.bind(i) }; }); } function nn(t) { return D((e, n) => { const i = n(t); return { getDecisions: i.getDecisions.bind(i) }; }); } function on(t) { return D((e, n) => { const i = n(t); return { makeDecision: i.makeDecision.bind(i), makeManyDecisions: i.makeManyDecisions.bind(i) }; }); } function I(t) { return f((e) => e(t) ?? E); } function sn(t) { const { sessionInitializationAtom: e, sessionUpdatingAtom: n } = he(t), i = Ae(t), o = { guardedConfigurationSessionAtom: I(i), guardedConfigurationAtom: I(t.configurationAtom), guardedIsSatisfiedAtom: I(t.isSatisfiedAtom), guardedCanResetAtom: I(t.canResetAtom), guardedAttributesAtom: I(t.attributesAtom), guardedStoredConfigurationAtom: I(ve(i)), guardedDecisionsAtom: I(we(i)), guardedExplicitDecisionsAtom: I(Ee(i)), guardedImplicitDecisionsAtom: I(De(i)) }, s = on(o.guardedConfigurationSessionAtom), r = Re(o.guardedConfigurationSessionAtom); return { ...o, configurationSessionAtom: i, sessionInitializationAtom: e, sessionUpdatingAtom: n, configurationInitializationAtom: He(e, o.guardedConfigurationSessionAtom, o.guardedConfigurationAtom, o.guardedCanResetAtom, o.guardedIsSatisfiedAtom, o.guardedAttributesAtom), configurationUpdatingAtom: Ye(n), makeDecisionAtom: s, explainAtom: r, decisionQueriesAtom: nn(o.guardedConfigurationSessionAtom), taskSchedulingAtom: en(o.guardedConfigurationSessionAtom), configurationSatisfactionAtom: Ge(o.guardedConfigurationSessionAtom, o.guardedIsSatisfiedAtom), configurationStoringAtom: Ze(o.guardedConfigurationSessionAtom), configurationResetAtom: ke(o.guardedConfigurationSessionAtom, o.guardedCanResetAtom), sessionReinitializationAtom: tn(o.guardedConfigurationSessionAtom), choiceAttributeAtomFamily: Le(o.guardedAttributesAtom, s, r), numericAttributeAtomFamily: Ke(o.guardedAttributesAtom, s, r), booleanAttributeAtomFamily: Qe(o.guardedAttributesAtom, s, r), componentAttributeAtomFamily: $e(o.guardedAttributesAtom, s, r), subscriberAtom: ce(t) }; } const rn = 30 * 1e3; function an(t, e, n) { const i = [ e.choiceAttributeAtomFamily, e.booleanAttributeAtomFamily, e.numericAttributeAtomFamily, e.componentAttributeAtomFamily, n.choiceAttributeAtomFamily, n.booleanAttributeAtomFamily, n.numericAttributeAtomFamily, n.componentAttributeAtomFamily ]; return ut((o) => { o(t.configurationAtom); const s = o(t.attributesAtom); if (s == null) return; x.debug("Scheduling atomFamily cleanup"); const r = setTimeout(() => { x.debug("Cleaning up atomFamilies"); for (const a of [...s.getParams()]) { const c = s(a); o.peek(c) == null && (x.debug("Removing attribute from attributes family because it is nullish", a), s.remove(a)); } const u = [...s.getParams()]; for (const a of i) for (const c of [...a.getParams()]) u.includes(c) || a.remove(c); }, rn); return () => { clearTimeout(r); }; }); } function un(t, e, n) { return { addSessionListenersEffect: xe(t, e), cleanupAtomFamiliesEffect: an(t, e, n), atomSubscriberEffect: le(t), atomSubscriptionCleanupEffect: me(t) }; } function cn(t) { return { configurationAtom: g(t.guardedConfigurationAtom), configurationStoringAtom: g(t.configurationStoringAtom), configurationSatisfactionAtom: g(t.configurationSatisfactionAtom), storedConfigurationAtom: g(t.guardedStoredConfigurationAtom), decisionsAtom: g(t.guardedDecisionsAtom), explicitDecisionsAtom: g(t.guardedExplicitDecisionsAtom), implicitDecisionsAtom: g(t.guardedImplicitDecisionsAtom), makeDecisionAtom: g(t.makeDecisionAtom), decisionQueriesAtom: g(t.decisionQueriesAtom), configurationResetAtom: g(t.configurationResetAtom), sessionReinitializationAtom: g(t.sessionReinitializationAtom), explainAtom: g(t.explainAtom), taskSchedulingAtom: g(t.taskSchedulingAtom), choiceAttributeAtomFamily: _((e) => g(t.choiceAttributeAtomFamily(e))), numericAttributeAtomFamily: _((e) => g(t.numericAttributeAtomFamily(e))), booleanAttributeAtomFamily: _((e) => g(t.booleanAttributeAtomFamily(e))), componentAttributeAtomFamily: _((e) => g(t.componentAttributeAtomFamily(e))) }; } function ln() { const t = Ie(), e = sn(t), n = cn(e); return { primitives: t, selectors: e, suspended: n, effects: un(t, e, n) }; } const mn = "The session context is null or undefined. This will dispose the session that may exist. If this was not intended, make sure you pass valid session context data."; function dn(t) { const { primitives: { sessionManagementMachineAtom: e } } = W(), n = Ft(e); return At(() => { n({ type: "SessionContextChanged", sessionContext: t.sessionContext }), t.sessionContext || console.warn(mn); }, [t.sessionContext]), At(() => () => { n({ type: "Shutdown" }); }, []), null; } function Un(t) { const e = X(() => ln(), []); return /* @__PURE__ */ q(Pt, { children: /* @__PURE__ */ q(Ut.Provider, { value: e, children: /* @__PURE__ */ q(fn, { jotaiStore: t.jotaiStore, children: /* @__PURE__ */ Ht(gn, { children: [ /* @__PURE__ */ q(dn, { sessionContext: t.sessionContext }), /* @__PURE__ */ q(se, {}), t.children ] }) }) }) }); } function fn(t) { return t.jotaiStore ? /* @__PURE__ */ q(qt.Provider, { value: t.jotaiStore, children: t.children }) : /* @__PURE__ */ q(Pt, { children: t.children }); } function gn(t) { const e = ct(); return /* @__PURE__ */ q($t, { store: e, children: t.children }); } function qn() { const { selectors: { configurationInitializationAtom: t } } = W(), e = ct(); return Ct(t, { store: e }); } function jn() { const { selectors: { configurationUpdatingAtom: t } } = W(), e = ct(); return Ct(t, { store: e }); } const Tn = y((t) => t.explainAtom, (t) => t.explainAtom), Vn = y((t) => t.guardedConfigurationAtom, (t) => t.configurationAtom), _n = y((t) => t.configurationSatisfactionAtom, (t) => t.configurationSatisfactionAtom), Nn = y((t) => t.configurationStoringAtom, (t) => t.configurationStoringAtom), Wn = y((t) => t.configurationResetAtom, (t) => t.configurationResetAtom), On = y((t) => t.sessionReinitializationAtom, (t) => t.sessionReinitializationAtom), Bn = y((t) => t.taskSchedulingAtom, (t) => t.taskSchedulingAtom), Ln = y((t) => t.guardedStoredConfigurationAtom, (t) => t.storedConfigurationAtom), Kn = y((t) => t.makeDecisionAtom, (t) => t.makeDecisionAtom), Qn = y((t) => t.decisionQueriesAtom, (t) => t.decisionQueriesAtom), An = y((t) => t.guardedDecisionsAtom, (t) => t.decisionsAtom), hn = y((t) => t.guardedExplicitDecisionsAtom, (t) => t.explicitDecisionsAtom), pn = y((t) => t.guardedImplicitDecisionsAtom, (t) => t.implicitDecisionsAtom); function $n(t, e) { const n = typeof t == "string" ? t : void 0, i = typeof t == "boolean" ? t : e, o = X(() => ot(n).returnType().with(Oe.nullish, () => An).with(L.Explicit, () => hn).with(L.Implicit, () => pn).exhaustive(), [n]); return i === !1 ? o(!1) : o(); } function Jn() { const { selectors: t } = W(); return X(() => ({ getConfigurationInitializationAtom: t.configurationInitializationAtom, getConfigurationUpdatingAtom: t.configurationUpdatingAtom, createAttributesAtom: ht(t), getChoiceAttributeAtomFamily: t.choiceAttributeAtomFamily, getNumericAttributeAtomFamily: t.numericAttributeAtomFamily, getBooleanAttributeAtomFamily: t.booleanAttributeAtomFamily, getComponentAttributeAtomFamily: t.componentAttributeAtomFamily, getConfigurationAtom: t.guardedConfigurationAtom, getConfigurationSatisfactionAtom: t.configurationSatisfactionAtom, getConfigurationStoringAtom: t.configurationStoringAtom, getMakeDecisionAtom: t.makeDecisionAtom, getDecisionQueriesAtom: t.decisionQueriesAtom, getConfigurationResetAtom: t.configurationResetAtom, getSessionReinitializationAtom: t.sessionReinitializationAtom, getExplainAtom: t.explainAtom, getTaskSchedulingAtom: t.taskSchedulingAtom, getStoredConfigurationAtom: t.guardedStoredConfigurationAtom, getDecisionsAtom: t.guardedDecisionsAtom, getExplicitDecisionsAtom: t.guardedExplicitDecisionsAtom, getImplicitDecisionsAtom: t.guardedImplicitDecisionsAtom }), [t]); } const Hn = (t) => t !== E; export { Un as Configuration, E as ConfigurationUninitialized, Hn as isConfigurationInitialized, Rn as useAttributes, zn as useBooleanAttribute, Fn as useChoiceAttribute, Pn as useComponentAttribute, Vn as useConfiguration, qn as useConfigurationInitialization, Wn as useConfigurationReset, _n as useConfigurationSatisfaction, Nn as useConfigurationStoring, jn as useConfigurationUpdating, ct as useConfiguratorStore, Qn as useDecisionQueries, $n as useDecisions, Tn as useExplain, Jn as useJotaiAtoms, Kn as useMakeDecision, Mn as useNumericAttribute, On as useSessionReinitialization, Ln as useStoredConfiguration, Bn as useTaskScheduling };