react-shared-states
Version:
Global state made as simple as useState, with zero config, built-in async caching, and automatic scoping.
702 lines (700 loc) • 20.1 kB
JavaScript
/*!
* react-shared-states v1.0.11
* (c) Hichem Taboukouyout
* Released under the MIT License.
* Github: github.com/HichemTab-tech/react-shared-states
*/
import he, { createContext as Se, useMemo as L, useContext as ge, useEffect as te, useSyncExternalStore as V } from "react";
var k = { exports: {} }, j = {};
/**
* @license React
* react-jsx-runtime.production.js
*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
var M;
function xe() {
if (M) return j;
M = 1;
var i = Symbol.for("react.transitional.element"), e = Symbol.for("react.fragment");
function r(t, n, c) {
var a = null;
if (c !== void 0 && (a = "" + c), n.key !== void 0 && (a = "" + n.key), "key" in n) {
c = {};
for (var b in n)
b !== "key" && (c[b] = n[b]);
} else c = n;
return n = c.ref, {
$$typeof: i,
type: t,
key: a,
ref: n !== void 0 ? n : null,
props: c
};
}
return j.Fragment = e, j.jsx = r, j.jsxs = r, j;
}
var C = {};
/**
* @license React
* react-jsx-runtime.development.js
*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
var Q;
function ve() {
return Q || (Q = 1, process.env.NODE_ENV !== "production" && function() {
function i(s) {
if (s == null) return null;
if (typeof s == "function")
return s.$$typeof === de ? null : s.displayName || s.name || null;
if (typeof s == "string") return s;
switch (s) {
case S:
return "Fragment";
case y:
return "Profiler";
case P:
return "StrictMode";
case ce:
return "Suspense";
case ue:
return "SuspenseList";
case fe:
return "Activity";
}
if (typeof s == "object")
switch (typeof s.tag == "number" && console.error(
"Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."
), s.$$typeof) {
case p:
return "Portal";
case ie:
return (s.displayName || "Context") + ".Provider";
case ae:
return (s._context.displayName || "Context") + ".Consumer";
case oe:
var o = s.render;
return s = s.displayName, s || (s = o.displayName || o.name || "", s = s !== "" ? "ForwardRef(" + s + ")" : "ForwardRef"), s;
case le:
return o = s.displayName || null, o !== null ? o : i(s.type) || "Memo";
case q:
o = s._payload, s = s._init;
try {
return i(s(o));
} catch {
}
}
return null;
}
function e(s) {
return "" + s;
}
function r(s) {
try {
e(s);
var o = !1;
} catch {
o = !0;
}
if (o) {
o = console;
var f = o.error, g = typeof Symbol == "function" && Symbol.toStringTag && s[Symbol.toStringTag] || s.constructor.name || "Object";
return f.call(
o,
"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.",
g
), e(s);
}
}
function t(s) {
if (s === S) return "<>";
if (typeof s == "object" && s !== null && s.$$typeof === q)
return "<...>";
try {
var o = i(s);
return o ? "<" + o + ">" : "<...>";
} catch {
return "<...>";
}
}
function n() {
var s = N.A;
return s === null ? null : s.getOwner();
}
function c() {
return Error("react-stack-top-frame");
}
function a(s) {
if (J.call(s, "key")) {
var o = Object.getOwnPropertyDescriptor(s, "key").get;
if (o && o.isReactWarning) return !1;
}
return s.key !== void 0;
}
function b(s, o) {
function f() {
z || (z = !0, console.error(
"%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)",
o
));
}
f.isReactWarning = !0, Object.defineProperty(s, "key", {
get: f,
configurable: !0
});
}
function E() {
var s = i(this.type);
return X[s] || (X[s] = !0, console.error(
"Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release."
)), s = this.props.ref, s !== void 0 ? s : null;
}
function A(s, o, f, g, w, _, Y, $) {
return f = _.ref, s = {
$$typeof: h,
type: s,
key: o,
props: _,
_owner: w
}, (f !== void 0 ? f : null) !== null ? Object.defineProperty(s, "ref", {
enumerable: !1,
get: E
}) : Object.defineProperty(s, "ref", { enumerable: !1, value: null }), s._store = {}, Object.defineProperty(s._store, "validated", {
configurable: !1,
enumerable: !1,
writable: !0,
value: 0
}), Object.defineProperty(s, "_debugInfo", {
configurable: !1,
enumerable: !1,
writable: !0,
value: null
}), Object.defineProperty(s, "_debugStack", {
configurable: !1,
enumerable: !1,
writable: !0,
value: Y
}), Object.defineProperty(s, "_debugTask", {
configurable: !1,
enumerable: !1,
writable: !0,
value: $
}), Object.freeze && (Object.freeze(s.props), Object.freeze(s)), s;
}
function T(s, o, f, g, w, _, Y, $) {
var x = o.children;
if (x !== void 0)
if (g)
if (pe(x)) {
for (g = 0; g < x.length; g++)
l(x[g]);
Object.freeze && Object.freeze(x);
} else
console.error(
"React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead."
);
else l(x);
if (J.call(o, "key")) {
x = i(s);
var O = Object.keys(o).filter(function(be) {
return be !== "key";
});
g = 0 < O.length ? "{key: someKey, " + O.join(": ..., ") + ": ...}" : "{key: someKey}", Z[x + g] || (O = 0 < O.length ? "{" + O.join(": ..., ") + ": ...}" : "{}", console.error(
`A props object containing a "key" prop is being spread into JSX:
let props = %s;
<%s {...props} />
React keys must be passed directly to JSX without using spread:
let props = %s;
<%s key={someKey} {...props} />`,
g,
x,
O,
x
), Z[x + g] = !0);
}
if (x = null, f !== void 0 && (r(f), x = "" + f), a(o) && (r(o.key), x = "" + o.key), "key" in o) {
f = {};
for (var I in o)
I !== "key" && (f[I] = o[I]);
} else f = o;
return x && b(
f,
typeof s == "function" ? s.displayName || s.name || "Unknown" : s
), A(
s,
x,
_,
w,
n(),
f,
Y,
$
);
}
function l(s) {
typeof s == "object" && s !== null && s.$$typeof === h && s._store && (s._store.validated = 1);
}
var v = he, h = Symbol.for("react.transitional.element"), p = Symbol.for("react.portal"), S = Symbol.for("react.fragment"), P = Symbol.for("react.strict_mode"), y = Symbol.for("react.profiler"), ae = Symbol.for("react.consumer"), ie = Symbol.for("react.context"), oe = Symbol.for("react.forward_ref"), ce = Symbol.for("react.suspense"), ue = Symbol.for("react.suspense_list"), le = Symbol.for("react.memo"), q = Symbol.for("react.lazy"), fe = Symbol.for("react.activity"), de = Symbol.for("react.client.reference"), N = v.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE, J = Object.prototype.hasOwnProperty, pe = Array.isArray, F = console.createTask ? console.createTask : function() {
return null;
};
v = {
react_stack_bottom_frame: function(s) {
return s();
}
};
var z, X = {}, B = v.react_stack_bottom_frame.bind(
v,
c
)(), H = F(t(c)), Z = {};
C.Fragment = S, C.jsx = function(s, o, f, g, w) {
var _ = 1e4 > N.recentlyCreatedOwnerStacks++;
return T(
s,
o,
f,
!1,
g,
w,
_ ? Error("react-stack-top-frame") : B,
_ ? F(t(s)) : H
);
}, C.jsxs = function(s, o, f, g, w) {
var _ = 1e4 > N.recentlyCreatedOwnerStacks++;
return T(
s,
o,
f,
!0,
g,
w,
_ ? Error("react-stack-top-frame") : B,
_ ? F(t(s)) : H
);
};
}()), C;
}
var K;
function Ee() {
return K || (K = 1, process.env.NODE_ENV === "production" ? k.exports = xe() : k.exports = ve()), k.exports;
}
var me = Ee();
let re = !1;
const Oe = (i) => {
re = i;
}, W = (...i) => {
re && console.log(
"%c[react-shared-states]",
"color: #007acc; font-weight: bold",
...i
);
}, D = (i) => {
if (!i) throw new Error("Value is empty");
return i;
}, se = () => Math.random().toString(36).substring(2, 15), ne = Se(void 0), je = ({ children: i, scopeName: e }) => {
if (e && e.includes("//")) throw new Error("scopeName cannot contain '//'");
return e || (e = L(() => se(), [])), /* @__PURE__ */ me.jsx(ne.Provider, { value: { scopeName: e }, children: i });
}, Re = () => ge(ne), ee = [];
class u {
data = /* @__PURE__ */ new Map();
defaultValue() {
return {};
}
addListener(e, r, t) {
this.data.has(u.prefix(e, r)) || this.data.set(u.prefix(e, r), {
...this.defaultValue(),
listeners: []
}), this.data.get(u.prefix(e, r)).listeners.push(t);
}
removeListener(e, r, t) {
this.data.has(u.prefix(e, r)) && (this.data.get(u.prefix(e, r)).listeners = this.data.get(u.prefix(e, r)).listeners.filter((n) => n !== t));
}
callListeners(e, r) {
this.data.has(u.prefix(e, r)) && this.data.get(u.prefix(e, r)).listeners.forEach((t) => t());
}
init(e, r, t, n = !1) {
this.data.has(u.prefix(e, r)) || this.data.set(u.prefix(e, r), {
...t,
isStatic: n,
listeners: []
});
}
createStatic(e, r) {
const t = r ?? r ?? "_global", n = {
key: se(),
prefix: t,
...e
};
return ee.push(n), this.initStatic(n), n;
}
initStatic(e) {
const { key: r, prefix: t } = e;
this.init(r, t, this.defaultValue(), !0);
}
clearAll(e = !1, r = !1) {
this.data.forEach((t, n) => {
const [c, a] = u.extractPrefix(n);
this.clear(a, c, e, r);
});
}
clear(e, r, t = !1, n = !1) {
t || this.callListeners(e, r);
const c = this.data.get(u.prefix(e, r));
if (!c) return;
const a = { ...c };
if (this.data.delete(u.prefix(e, r)), a.isStatic && !n) {
const b = ee.find((E) => E.key === e && E.prefix === r);
b && this.initStatic(b);
}
}
get(e, r) {
let t = this.has(e, r);
if (t)
return this.data.get(t);
}
setValue(e, r, t) {
this.data.has(u.prefix(e, r)) && this.data.set(u.prefix(e, r), {
...this.data.get(u.prefix(e, r)),
...t
});
}
has(e, r) {
return this.data.has(u.prefix(e, r)) ? u.prefix(e, r) : this.data.has(u.prefix(e, "_global")) ? u.prefix(e, "_global") : void 0;
}
static prefix(e, r) {
if (e.includes("//")) throw new Error("key cannot contain '//'");
return `${r}//${e}`;
}
static extractPrefix(e) {
return e.split("//");
}
useEffect(e, r, t = null) {
te(() => () => {
t?.(), W(`[${u.prefix(e, r)}]`, "unmount effect"), this.data.get(u.prefix(e, r)).listeners?.length === 0 && this.clear(e, r);
}, []);
}
}
class U {
constructor(e) {
this.sharedData = e;
}
get(e, r) {
let t, n = r;
if (typeof e != "string") {
const { key: b, prefix: E } = e;
t = b, n = E;
} else
t = D(e);
const c = n || "_global";
return this.sharedData.get(t, c);
}
set(e, r, t) {
let n, c = t;
if (typeof e != "string") {
const { key: b, prefix: E } = e;
n = b, c = E;
} else
n = D(e);
const a = c || "_global";
this.sharedData.setValue(n, a, r);
}
/**
* clear all values from the shared data
*/
clearAll() {
this.sharedData.clearAll();
}
/**
* clear all values from the shared data in a scope
* @param scopeName
*/
clearScope(e) {
const r = e || "_global";
this.sharedData.data.forEach((t, n) => {
const [c, a] = u.extractPrefix(n);
if (c === r) {
this.sharedData.clear(a, c);
return;
}
});
}
/**
* resolve a shared created object to a value
* @param sharedCreated
*/
resolve(e) {
const { key: r, prefix: t } = e;
return this.get(r, t);
}
clear(e, r) {
let t, n;
typeof e == "string" ? (t = e, n = r || "_global") : (t = e.key, n = e.prefix), this.sharedData.clear(t, n);
}
/**
* check if a value exists in the shared data
* @param key
* @param scopeName
*/
has(e, r = "_global") {
const t = r || "_global";
return !!this.sharedData.has(e, t);
}
/**
* get all values from the shared data
*/
getAll() {
const e = {};
return this.sharedData.data.forEach((r, t) => {
const [n, c] = u.extractPrefix(t);
e[n] = e[n] || {}, e[n][c] = r;
}), e;
}
}
const G = (i) => {
const e = Re();
return {
prefix: i ?? e?.scopeName ?? "_global"
};
};
class _e extends u {
defaultValue() {
return { value: void 0 };
}
initValue(e, r, t, n = !1) {
super.init(e, r, { value: t }, n);
}
initStatic(e) {
const { key: r, prefix: t, initialValue: n } = e;
this.initValue(r, t, n, !0);
}
}
class Te extends U {
constructor(e) {
super(e);
}
get(e, r = "_global") {
return typeof e != "string" ? super.get(e)?.value : super.get(e, r)?.value;
}
set(e, r, t = "_global") {
if (typeof e != "string") {
super.set(e, { value: r });
return;
}
super.set(e, { value: r }, t);
}
}
const R = new _e(), Ce = new Te(R), De = (i, e) => R.createStatic({ initialValue: i }, e);
function ke(i, e, r) {
let t, n, c = r;
if (typeof i != "string") {
const { key: l, initialValue: v, prefix: h } = i;
t = l, n = v, c = h;
} else
t = D(i), n = e;
const { prefix: a } = G(c);
R.initValue(t, a, n);
const b = L(() => (l) => (R.initValue(t, a, e), R.addListener(t, a, l), () => {
R.removeListener(t, a, l);
}), []), E = L(() => () => R.get(t, a)?.value, []), A = V(b, E), T = (l) => {
const v = typeof l == "function" ? l(R.get(t, a)?.value) : l;
v !== A && (R.setValue(t, a, { value: v }), R.callListeners(t, a));
};
return R.useEffect(t, a), [
A,
T
];
}
class Ae extends u {
defaultValue() {
return {
fnState: {
results: void 0,
isLoading: !1,
error: void 0
}
};
}
initValue(e, r, t = !1) {
super.init(e, r, this.defaultValue(), t);
}
setValue(e, r, t) {
super.setValue(e, r, t);
}
}
class we extends U {
constructor(e) {
super(e);
}
get(e, r = "_global") {
return typeof e != "string" ? super.get(e)?.fnState : super.get(e, r)?.fnState;
}
set(e, r, t = "_global") {
if (typeof e != "string") {
super.set(e, r);
return;
}
super.set(e, r, t);
}
}
const m = new Ae(), Ne = new we(m), Fe = (i, e) => m.createStatic({ fn: i }, e);
function Ye(i, e, r) {
let t, n, c = r;
if (typeof i != "string") {
const { key: l, fn: v, prefix: h } = i;
t = l, n = v, c = h;
} else
t = D(i), n = e;
const { prefix: a } = G(c);
m.initValue(t, a);
const b = L(
() => (l) => (m.initValue(t, a), m.addListener(t, a, l), () => {
m.removeListener(t, a, l);
}),
[]
), E = L(
() => () => m.get(t, a).fnState,
[]
), A = V(b, E), T = async (l, ...v) => {
const h = m.get(t, a);
if (!l && (h.fnState.isLoading || h.fnState.results !== void 0)) return h.fnState;
h.fnState = { ...h.fnState, isLoading: !0, error: void 0 }, m.callListeners(t, a);
try {
const p = await n(...v);
h.fnState = { results: p, isLoading: !1, error: void 0 };
} catch (p) {
h.fnState = { ...h.fnState, isLoading: !1, error: p };
}
m.callListeners(t, a);
};
return m.useEffect(t, a), {
state: A,
trigger: (...l) => {
T(!1, ...l);
},
forceTrigger: (...l) => {
T(!0, ...l);
},
clear: () => {
const l = m.get(t, a);
l && (l.fnState = m.defaultValue().fnState, m.callListeners(t, a));
}
};
}
class Pe extends u {
defaultValue() {
return {
fnState: {
data: void 0,
isLoading: !1,
error: void 0,
subscribed: !1
}
};
}
initValue(e, r, t = !1) {
super.init(e, r, this.defaultValue(), t);
}
setValue(e, r, t) {
super.setValue(e, r, t);
}
useEffect(e, r) {
te(() => () => {
W(`[${u.prefix(e, r)}]`, "unmount effect2"), this.get(e, r)?.listeners.length === 0 && this.unsubscribe(e, r);
}, []), super.useEffect(e, r);
}
async unsubscribe(e, r) {
const t = this.get(e, r);
t && (t.unsubscribe && (t.unsubscribe(), t.unsubscribe = void 0), t.fnState = { ...t.fnState, subscribed: !1 }, this.callListeners(e, r));
}
}
class ye extends U {
constructor(e) {
super(e);
}
get(e, r = "_global") {
return typeof e != "string" ? super.get(e)?.fnState : super.get(e, r)?.fnState;
}
set(e, r, t = "_global") {
if (typeof e != "string") {
super.set(e, r);
return;
}
super.set(e, r, t);
}
}
const d = new Pe(), $e = new ye(d), Ie = (i, e) => d.createStatic({ subscriber: i }, e);
function Ve(i, e, r) {
let t, n, c = r;
if (typeof i != "string") {
const { key: p, subscriber: S, prefix: P } = i;
t = p, n = S, c = P;
} else
t = D(i), n = e;
const { prefix: a } = G(c);
d.initValue(t, a);
const b = L(
() => (p) => (d.initValue(t, a), d.addListener(t, a, p), () => {
d.removeListener(t, a, p);
}),
[]
), E = L(
() => () => d.get(t, a).fnState,
[]
), A = V(b, E), T = (p) => {
const S = d.get(t, a);
S.fnState = { ...S.fnState, data: p }, d.callListeners(t, a);
}, l = (p) => {
const S = d.get(t, a);
S.fnState = { ...S.fnState, isLoading: !1, data: void 0, error: p }, d.callListeners(t, a);
}, v = () => {
const p = d.get(t, a);
p.fnState = { ...p.fnState, isLoading: !1 }, d.callListeners(t, a);
}, h = async (p) => {
const S = d.get(t, a);
if (p && (await d.unsubscribe(t, a), S.fnState = { ...S.fnState, isLoading: !1, data: void 0, error: void 0, subscribed: !1 }), S.fnState.subscribed) return S.fnState;
W("triggered !!"), S.fnState = { ...S.fnState, isLoading: !0, error: void 0 }, d.callListeners(t, a);
try {
const P = await n(T, l, v), y = d.get(t, a);
y.unsubscribe = P, y.fnState.subscribed = !0;
} catch (P) {
const y = d.get(t, a);
y.fnState = { ...y.fnState, isLoading: !1, error: P };
}
d.callListeners(t, a);
};
return d.useEffect(t, a), {
state: A,
trigger: () => {
h(!1);
},
forceTrigger: () => {
h(!0);
},
unsubscribe: () => {
d.unsubscribe(t, a);
}
};
}
export {
we as SharedFunctionsApi,
Te as SharedStatesApi,
je as SharedStatesProvider,
ye as SharedSubscriptionsApi,
Fe as createSharedFunction,
De as createSharedState,
Ie as createSharedSubscription,
re as isDevMode,
Oe as setDevMode,
Ne as sharedFunctionsApi,
Ce as sharedStatesApi,
$e as sharedSubscriptionsApi,
Ye as useSharedFunction,
ke as useSharedState,
Ve as useSharedSubscription
};