Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve treeshakeability of build artifacts #2176

Open
wants to merge 26 commits into
base: master
Choose a base branch
from

Conversation

aryaemami59
Copy link
Contributor

This PR:

  • Brings all of devModeChecks underneath process.env.NODE_ENV checks to ensure they are erased during production builds.
  • Adds @__PURE__ annotation to some of the function call sites to improve treeshakeability.
  • Adds getUseIsomorphicLayoutEffect with @__PURE__ annotation to improve further treeshakeability.
  • Adds @__PURE__ annotations to all react-is symbols.
  • Sets browser field in package.json to browser artifact. (Not sure if we want to keep the browser artifact so if not let me know and I can get remove it).

Copy link

codesandbox-ci bot commented May 31, 2024

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

Copy link

netlify bot commented Jun 17, 2024

Deploy Preview for react-redux-docs ready!

Name Link
🔨 Latest commit fa446ab
🔍 Latest deploy log https://app.netlify.com/sites/react-redux-docs/deploys/66bfdd8023dfee00085cfa5b
😎 Deploy Preview https://deploy-preview-2176--react-redux-docs.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

@aryaemami59
Copy link
Contributor Author

aryaemami59 commented Jun 25, 2024

Summary

With Rollup

batch changes (Click to expand)

File Content:

export { batch } from 'react-redux'
Before and After
--- before/react-redux/batch.js	2024-06-25 04:42:17.355572200 -0500
+++ after/react-redux/batch.js	2024-06-25 10:30:38.182405000 -0500
@@ -1,23 +1,13 @@
-import * as ReactOriginal from 'react';
+import 'react';
 import 'use-sync-external-store/with-selector.js';

-// src/index.ts
-var React = (
-  // prettier-ignore
-  // @ts-ignore
-  "default" in ReactOriginal ? ReactOriginal["default"] : ReactOriginal
-);
+// src/utils/bindActionCreators.ts

 // src/utils/batch.ts
 function defaultNoopBatch(callback) {
   callback();
 }

-// src/utils/useIsomorphicLayoutEffect.ts
-var canUseDOM = !!(typeof window !== "undefined" && typeof window.document !== "undefined" && typeof window.document.createElement !== "undefined");
-var isReactNative = typeof navigator !== "undefined" && navigator.product === "ReactNative";
-canUseDOM || isReactNative ? React.useLayoutEffect : React.useEffect;
-
 // src/exports.ts
 var batch = defaultNoopBatch;
connect changes (Click to expand)

File Content:

export { connect } from 'react-redux'
Before and After
--- before/react-redux/connect.js	2024-06-25 04:42:17.488571800 -0500
+++ after/react-redux/connect.js	2024-06-25 10:30:38.308406200 -0500
@@ -1,93 +1,108 @@
-import * as ReactOriginal from 'react';
+import * as React from 'react';
 import 'use-sync-external-store/with-selector.js';

-// src/index.ts
-var React = (
-  // prettier-ignore
-  // @ts-ignore
-  "default" in ReactOriginal ? ReactOriginal["default"] : ReactOriginal
-);
-
-// src/components/Context.ts
-var ContextKey = Symbol.for(`react-redux-context`);
-var gT = typeof globalThis !== "undefined" ? globalThis : (
-  /* fall back to a per-module scope (pre-8.1 behaviour) if `globalThis` is not available */
-  {}
-);
-function getContext() {
-  if (!React.createContext)
-    return {};
-  const contextMap = gT[ContextKey] ?? (gT[ContextKey] = /* @__PURE__ */ new Map());
-  let realContext = contextMap.get(React.createContext);
-  if (!realContext) {
-    realContext = React.createContext(
-      null
-    );
-    contextMap.set(React.createContext, realContext);
+// src/utils/bindActionCreators.ts
+function bindActionCreators(actionCreators, dispatch) {
+  const boundActionCreators = {};
+  for (const key in actionCreators) {
+    const actionCreator = actionCreators[key];
+    if (typeof actionCreator === "function") {
+      boundActionCreators[key] = (...args) => dispatch(actionCreator(...args));
   }
-  return realContext;
 }
-var ReactReduxContext = /* @__PURE__ */ getContext();
+  return boundActionCreators;
+}

-// src/utils/useSyncExternalStore.ts
-var notInitialized = () => {
-  throw new Error("uSES not initialized!");
+// src/connect/wrapMapToProps.ts
+function wrapMapToPropsConstant(getConstant) {
+  return function initConstantSelector(dispatch) {
+    const constant = getConstant(dispatch);
+    function constantSelector() {
+      return constant;
+    }
+    constantSelector.dependsOnOwnProps = false;
+    return constantSelector;
 };
-
-// src/utils/react-is.ts
-var REACT_ELEMENT_TYPE = Symbol.for("react.element");
-var REACT_PORTAL_TYPE = Symbol.for("react.portal");
-var REACT_FRAGMENT_TYPE = Symbol.for("react.fragment");
-var REACT_STRICT_MODE_TYPE = Symbol.for("react.strict_mode");
-var REACT_PROFILER_TYPE = Symbol.for("react.profiler");
-var REACT_PROVIDER_TYPE = Symbol.for("react.provider");
-var REACT_CONTEXT_TYPE = Symbol.for("react.context");
-var REACT_SERVER_CONTEXT_TYPE = Symbol.for("react.server_context");
-var REACT_FORWARD_REF_TYPE = Symbol.for("react.forward_ref");
-var REACT_SUSPENSE_TYPE = Symbol.for("react.suspense");
-var REACT_SUSPENSE_LIST_TYPE = Symbol.for("react.suspense_list");
-var REACT_MEMO_TYPE = Symbol.for("react.memo");
-var REACT_LAZY_TYPE = Symbol.for("react.lazy");
-var ForwardRef = REACT_FORWARD_REF_TYPE;
-var Memo = REACT_MEMO_TYPE;
-function typeOf(object) {
-  if (typeof object === "object" && object !== null) {
-    const $$typeof = object.$$typeof;
-    switch ($$typeof) {
-      case REACT_ELEMENT_TYPE: {
-        const type = object.type;
-        switch (type) {
-          case REACT_FRAGMENT_TYPE:
-          case REACT_PROFILER_TYPE:
-          case REACT_STRICT_MODE_TYPE:
-          case REACT_SUSPENSE_TYPE:
-          case REACT_SUSPENSE_LIST_TYPE:
-            return type;
-          default: {
-            const $$typeofType = type && type.$$typeof;
-            switch ($$typeofType) {
-              case REACT_SERVER_CONTEXT_TYPE:
-              case REACT_CONTEXT_TYPE:
-              case REACT_FORWARD_REF_TYPE:
-              case REACT_LAZY_TYPE:
-              case REACT_MEMO_TYPE:
-              case REACT_PROVIDER_TYPE:
-                return $$typeofType;
-              default:
-                return $$typeof;
             }
+function getDependsOnOwnProps(mapToProps) {
+  return mapToProps.dependsOnOwnProps ? Boolean(mapToProps.dependsOnOwnProps) : mapToProps.length !== 1;
           }
+function wrapMapToPropsFunc(mapToProps, methodName) {
+  return function initProxySelector(dispatch, { displayName }) {
+    const proxy = function mapToPropsProxy(stateOrDispatch, ownProps) {
+      return proxy.dependsOnOwnProps ? proxy.mapToProps(stateOrDispatch, ownProps) : proxy.mapToProps(stateOrDispatch, void 0);
+    };
+    proxy.dependsOnOwnProps = true;
+    proxy.mapToProps = function detectFactoryAndVerify(stateOrDispatch, ownProps) {
+      proxy.mapToProps = mapToProps;
+      proxy.dependsOnOwnProps = getDependsOnOwnProps(mapToProps);
+      let props = proxy(stateOrDispatch, ownProps);
+      if (typeof props === "function") {
+        proxy.mapToProps = props;
+        proxy.dependsOnOwnProps = getDependsOnOwnProps(props);
+        props = proxy(stateOrDispatch, ownProps);
         }
+      return props;
+    };
+    return proxy;
+  };
       }
-      case REACT_PORTAL_TYPE: {
-        return $$typeof;
+
+// src/connect/invalidArgFactory.ts
+function createInvalidArgFactory(arg, name) {
+  return (dispatch, options) => {
+    throw new Error(
+      `Invalid value of type ${typeof arg} for ${name} argument when connecting component ${options.wrappedComponentName}.`
+    );
+  };
+}
+
+// src/connect/mapDispatchToProps.ts
+function mapDispatchToPropsFactory(mapDispatchToProps) {
+  return mapDispatchToProps && typeof mapDispatchToProps === "object" ? wrapMapToPropsConstant(
+    (dispatch) => (
+      // @ts-ignore
+      bindActionCreators(mapDispatchToProps, dispatch)
+    )
+  ) : !mapDispatchToProps ? wrapMapToPropsConstant((dispatch) => ({
+    dispatch
+  })) : typeof mapDispatchToProps === "function" ? (
+    // @ts-ignore
+    wrapMapToPropsFunc(mapDispatchToProps)
+  ) : createInvalidArgFactory(mapDispatchToProps, "mapDispatchToProps");
+}
+
+// src/connect/mapStateToProps.ts
+function mapStateToPropsFactory(mapStateToProps) {
+  return !mapStateToProps ? wrapMapToPropsConstant(() => ({})) : typeof mapStateToProps === "function" ? (
+    // @ts-ignore
+    wrapMapToPropsFunc(mapStateToProps)
+  ) : createInvalidArgFactory(mapStateToProps, "mapStateToProps");
       }
+
+// src/connect/mergeProps.ts
+function defaultMergeProps(stateProps, dispatchProps, ownProps) {
+  return { ...ownProps, ...stateProps, ...dispatchProps };
     }
+function wrapMergePropsFunc(mergeProps) {
+  return function initMergePropsProxy(dispatch, { displayName, areMergedPropsEqual }) {
+    let hasRunOnce = false;
+    let mergedProps;
+    return function mergePropsProxy(stateProps, dispatchProps, ownProps) {
+      const nextMergedProps = mergeProps(stateProps, dispatchProps, ownProps);
+      if (hasRunOnce) {
+        if (!areMergedPropsEqual(nextMergedProps, mergedProps))
+          mergedProps = nextMergedProps;
+      } else {
+        hasRunOnce = true;
+        mergedProps = nextMergedProps;
   }
-  return void 0;
+      return mergedProps;
+    };
+  };
 }
-function isMemo(object) {
-  return typeOf(object) === REACT_MEMO_TYPE;
+function mergePropsFactory(mergeProps) {
+  return !mergeProps ? () => defaultMergeProps : typeof mergeProps === "function" ? wrapMergePropsFunc(mergeProps) : createInvalidArgFactory(mergeProps, "mergeProps");
 }

 // src/connect/selectorFactory.ts
@@ -144,12 +159,9 @@
     );
     state = nextState;
     ownProps = nextOwnProps;
-    if (propsChanged && stateChanged)
-      return handleNewPropsAndNewState();
-    if (propsChanged)
-      return handleNewProps();
-    if (stateChanged)
-      return handleNewState();
+    if (propsChanged && stateChanged) return handleNewPropsAndNewState();
+    if (propsChanged) return handleNewProps();
+    if (stateChanged) return handleNewState();
     return mergedProps;
   }
   return function pureFinalPropsSelector(nextState, nextOwnProps) {
@@ -168,108 +180,170 @@
   return pureFinalPropsSelectorFactory(mapStateToProps, mapDispatchToProps, mergeProps, dispatch, options);
 }

-// src/utils/bindActionCreators.ts
-function bindActionCreators(actionCreators, dispatch) {
-  const boundActionCreators = {};
-  for (const key in actionCreators) {
-    const actionCreator = actionCreators[key];
-    if (typeof actionCreator === "function") {
-      boundActionCreators[key] = (...args) => dispatch(actionCreator(...args));
+// src/utils/react-is.ts
+var REACT_ELEMENT_TYPE = /* @__PURE__ */ Symbol.for("react.element");
+var REACT_PORTAL_TYPE = /* @__PURE__ */ Symbol.for("react.portal");
+var REACT_FRAGMENT_TYPE = /* @__PURE__ */ Symbol.for("react.fragment");
+var REACT_STRICT_MODE_TYPE = /* @__PURE__ */ Symbol.for("react.strict_mode");
+var REACT_PROFILER_TYPE = /* @__PURE__ */ Symbol.for("react.profiler");
+var REACT_PROVIDER_TYPE = /* @__PURE__ */ Symbol.for("react.provider");
+var REACT_CONTEXT_TYPE = /* @__PURE__ */ Symbol.for("react.context");
+var REACT_SERVER_CONTEXT_TYPE = /* @__PURE__ */ Symbol.for(
+  "react.server_context"
+);
+var REACT_FORWARD_REF_TYPE = /* @__PURE__ */ Symbol.for("react.forward_ref");
+var REACT_SUSPENSE_TYPE = /* @__PURE__ */ Symbol.for("react.suspense");
+var REACT_SUSPENSE_LIST_TYPE = /* @__PURE__ */ Symbol.for(
+  "react.suspense_list"
+);
+var REACT_MEMO_TYPE = /* @__PURE__ */ Symbol.for("react.memo");
+var REACT_LAZY_TYPE = /* @__PURE__ */ Symbol.for("react.lazy");
+var ForwardRef = REACT_FORWARD_REF_TYPE;
+var Memo = REACT_MEMO_TYPE;
+function typeOf(object) {
+  if (typeof object === "object" && object !== null) {
+    const $$typeof = object.$$typeof;
+    switch ($$typeof) {
+      case REACT_ELEMENT_TYPE: {
+        const type = object.type;
+        switch (type) {
+          case REACT_FRAGMENT_TYPE:
+          case REACT_PROFILER_TYPE:
+          case REACT_STRICT_MODE_TYPE:
+          case REACT_SUSPENSE_TYPE:
+          case REACT_SUSPENSE_LIST_TYPE:
+            return type;
+          default: {
+            const $$typeofType = type && type.$$typeof;
+            switch ($$typeofType) {
+              case REACT_SERVER_CONTEXT_TYPE:
+              case REACT_CONTEXT_TYPE:
+              case REACT_FORWARD_REF_TYPE:
+              case REACT_LAZY_TYPE:
+              case REACT_MEMO_TYPE:
+              case REACT_PROVIDER_TYPE:
+                return $$typeofType;
+              default:
+                return $$typeof;
     }
   }
-  return boundActionCreators;
 }
-
-// src/connect/wrapMapToProps.ts
-function wrapMapToPropsConstant(getConstant) {
-  return function initConstantSelector(dispatch) {
-    const constant = getConstant(dispatch);
-    function constantSelector() {
-      return constant;
     }
-    constantSelector.dependsOnOwnProps = false;
-    return constantSelector;
-  };
+      case REACT_PORTAL_TYPE: {
+        return $$typeof;
 }
-function getDependsOnOwnProps(mapToProps) {
-  return mapToProps.dependsOnOwnProps ? Boolean(mapToProps.dependsOnOwnProps) : mapToProps.length !== 1;
 }
-function wrapMapToPropsFunc(mapToProps, methodName) {
-  return function initProxySelector(dispatch, { displayName }) {
-    const proxy = function mapToPropsProxy(stateOrDispatch, ownProps) {
-      return proxy.dependsOnOwnProps ? proxy.mapToProps(stateOrDispatch, ownProps) : proxy.mapToProps(stateOrDispatch, void 0);
-    };
-    proxy.dependsOnOwnProps = true;
-    proxy.mapToProps = function detectFactoryAndVerify(stateOrDispatch, ownProps) {
-      proxy.mapToProps = mapToProps;
-      proxy.dependsOnOwnProps = getDependsOnOwnProps(mapToProps);
-      let props = proxy(stateOrDispatch, ownProps);
-      if (typeof props === "function") {
-        proxy.mapToProps = props;
-        proxy.dependsOnOwnProps = getDependsOnOwnProps(props);
-        props = proxy(stateOrDispatch, ownProps);
       }
-      return props;
-    };
-    return proxy;
-  };
+  return void 0;
+}
+function isMemo(object) {
+  return typeOf(object) === REACT_MEMO_TYPE;
 }

-// src/connect/invalidArgFactory.ts
-function createInvalidArgFactory(arg, name) {
-  return (dispatch, options) => {
-    throw new Error(
-      `Invalid value of type ${typeof arg} for ${name} argument when connecting component ${options.wrappedComponentName}.`
-    );
+// src/utils/hoistStatics.ts
+var REACT_STATICS = {
+  childContextTypes: true,
+  contextType: true,
+  contextTypes: true,
+  defaultProps: true,
+  displayName: true,
+  getDefaultProps: true,
+  getDerivedStateFromError: true,
+  getDerivedStateFromProps: true,
+  mixins: true,
+  propTypes: true,
+  type: true
+};
+var KNOWN_STATICS = {
+  name: true,
+  length: true,
+  prototype: true,
+  caller: true,
+  callee: true,
+  arguments: true,
+  arity: true
   };
+var FORWARD_REF_STATICS = {
+  $$typeof: true,
+  render: true,
+  defaultProps: true,
+  displayName: true,
+  propTypes: true
+};
+var MEMO_STATICS = {
+  $$typeof: true,
+  compare: true,
+  defaultProps: true,
+  displayName: true,
+  propTypes: true,
+  type: true
+};
+var TYPE_STATICS = {
+  [ForwardRef]: FORWARD_REF_STATICS,
+  [Memo]: MEMO_STATICS
+};
+function getStatics(component) {
+  if (isMemo(component)) {
+    return MEMO_STATICS;
 }
-
-// src/connect/mapDispatchToProps.ts
-function mapDispatchToPropsFactory(mapDispatchToProps) {
-  return mapDispatchToProps && typeof mapDispatchToProps === "object" ? wrapMapToPropsConstant(
-    (dispatch) => (
-      // @ts-ignore
-      bindActionCreators(mapDispatchToProps, dispatch)
-    )
-  ) : !mapDispatchToProps ? wrapMapToPropsConstant((dispatch) => ({
-    dispatch
-  })) : typeof mapDispatchToProps === "function" ? (
-    // @ts-ignore
-    wrapMapToPropsFunc(mapDispatchToProps)
-  ) : createInvalidArgFactory(mapDispatchToProps, "mapDispatchToProps");
+  return TYPE_STATICS[component["$$typeof"]] || REACT_STATICS;
 }
-
-// src/connect/mapStateToProps.ts
-function mapStateToPropsFactory(mapStateToProps) {
-  return !mapStateToProps ? wrapMapToPropsConstant(() => ({})) : typeof mapStateToProps === "function" ? (
-    // @ts-ignore
-    wrapMapToPropsFunc(mapStateToProps)
-  ) : createInvalidArgFactory(mapStateToProps, "mapStateToProps");
+var defineProperty = Object.defineProperty;
+var getOwnPropertyNames = Object.getOwnPropertyNames;
+var getOwnPropertySymbols = Object.getOwnPropertySymbols;
+var getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
+var getPrototypeOf = Object.getPrototypeOf;
+var objectPrototype = Object.prototype;
+function hoistNonReactStatics(targetComponent, sourceComponent) {
+  if (typeof sourceComponent !== "string") {
+    if (objectPrototype) {
+      const inheritedComponent = getPrototypeOf(sourceComponent);
+      if (inheritedComponent && inheritedComponent !== objectPrototype) {
+        hoistNonReactStatics(targetComponent, inheritedComponent);
 }
-
-// src/connect/mergeProps.ts
-function defaultMergeProps(stateProps, dispatchProps, ownProps) {
-  return { ...ownProps, ...stateProps, ...dispatchProps };
 }
-function wrapMergePropsFunc(mergeProps) {
-  return function initMergePropsProxy(dispatch, { displayName, areMergedPropsEqual }) {
-    let hasRunOnce = false;
-    let mergedProps;
-    return function mergePropsProxy(stateProps, dispatchProps, ownProps) {
-      const nextMergedProps = mergeProps(stateProps, dispatchProps, ownProps);
-      if (hasRunOnce) {
-        if (!areMergedPropsEqual(nextMergedProps, mergedProps))
-          mergedProps = nextMergedProps;
+    let keys = getOwnPropertyNames(sourceComponent);
+    if (getOwnPropertySymbols) {
+      keys = keys.concat(getOwnPropertySymbols(sourceComponent));
+    }
+    const targetStatics = getStatics(targetComponent);
+    const sourceStatics = getStatics(sourceComponent);
+    for (let i = 0; i < keys.length; ++i) {
+      const key = keys[i];
+      if (!KNOWN_STATICS[key] && !(sourceStatics && sourceStatics[key]) && !(targetStatics && targetStatics[key])) {
+        const descriptor = getOwnPropertyDescriptor(sourceComponent, key);
+        try {
+          defineProperty(targetComponent, key, descriptor);
+        } catch (e) {
+        }
+      }
+    }
+  }
+  return targetComponent;
+}
+
+// src/utils/shallowEqual.ts
+function is(x, y) {
+  if (x === y) {
+    return x !== 0 || y !== 0 || 1 / x === 1 / y;
       } else {
-        hasRunOnce = true;
-        mergedProps = nextMergedProps;
+    return x !== x && y !== y;
       }
-      return mergedProps;
-    };
-  };
 }
-function mergePropsFactory(mergeProps) {
-  return !mergeProps ? () => defaultMergeProps : typeof mergeProps === "function" ? wrapMergePropsFunc(mergeProps) : createInvalidArgFactory(mergeProps, "mergeProps");
+function shallowEqual(objA, objB) {
+  if (is(objA, objB)) return true;
+  if (typeof objA !== "object" || objA === null || typeof objB !== "object" || objB === null) {
+    return false;
+  }
+  const keysA = Object.keys(objA);
+  const keysB = Object.keys(objB);
+  if (keysA.length !== keysB.length) return false;
+  for (let i = 0; i < keysA.length; i++) {
+    if (!Object.prototype.hasOwnProperty.call(objB, keysA[i]) || !is(objA[keysA[i]], objB[keysA[i]])) {
+      return false;
+    }
+  }
+  return true;
 }

 // src/utils/batch.ts
@@ -317,8 +391,7 @@
         first = listener;
       }
       return function unsubscribe() {
-        if (!isSubscribed || first === null)
-          return;
+        if (!isSubscribed || first === null) return;
         isSubscribed = false;
         if (listener.next) {
           listener.next.prev = listener.prev;
@@ -408,123 +481,34 @@
 }

 // src/utils/useIsomorphicLayoutEffect.ts
-var canUseDOM = !!(typeof window !== "undefined" && typeof window.document !== "undefined" && typeof window.document.createElement !== "undefined");
-var isReactNative = typeof navigator !== "undefined" && navigator.product === "ReactNative";
-var useIsomorphicLayoutEffect = canUseDOM || isReactNative ? React.useLayoutEffect : React.useEffect;
-
-// src/utils/shallowEqual.ts
-function is(x, y) {
-  if (x === y) {
-    return x !== 0 || y !== 0 || 1 / x === 1 / y;
-  } else {
-    return x !== x && y !== y;
-  }
-}
-function shallowEqual(objA, objB) {
-  if (is(objA, objB))
-    return true;
-  if (typeof objA !== "object" || objA === null || typeof objB !== "object" || objB === null) {
-    return false;
-  }
-  const keysA = Object.keys(objA);
-  const keysB = Object.keys(objB);
-  if (keysA.length !== keysB.length)
-    return false;
-  for (let i = 0; i < keysA.length; i++) {
-    if (!Object.prototype.hasOwnProperty.call(objB, keysA[i]) || !is(objA[keysA[i]], objB[keysA[i]])) {
-      return false;
-    }
-  }
-  return true;
-}
+var canUseDOM = () => !!(typeof window !== "undefined" && typeof window.document !== "undefined" && typeof window.document.createElement !== "undefined");
+var isDOM = /* @__PURE__ */ canUseDOM();
+var isRunningInReactNative = () => typeof navigator !== "undefined" && navigator.product === "ReactNative";
+var isReactNative = /* @__PURE__ */ isRunningInReactNative();
+var getUseIsomorphicLayoutEffect = () => isDOM || isReactNative ? React.useLayoutEffect : React.useEffect;
+var useIsomorphicLayoutEffect = /* @__PURE__ */ getUseIsomorphicLayoutEffect();

-// src/utils/hoistStatics.ts
-var REACT_STATICS = {
-  childContextTypes: true,
-  contextType: true,
-  contextTypes: true,
-  defaultProps: true,
-  displayName: true,
-  getDefaultProps: true,
-  getDerivedStateFromError: true,
-  getDerivedStateFromProps: true,
-  mixins: true,
-  propTypes: true,
-  type: true
-};
-var KNOWN_STATICS = {
-  name: true,
-  length: true,
-  prototype: true,
-  caller: true,
-  callee: true,
-  arguments: true,
-  arity: true
-};
-var FORWARD_REF_STATICS = {
-  $$typeof: true,
-  render: true,
-  defaultProps: true,
-  displayName: true,
-  propTypes: true
-};
-var MEMO_STATICS = {
-  $$typeof: true,
-  compare: true,
-  defaultProps: true,
-  displayName: true,
-  propTypes: true,
-  type: true
-};
-var TYPE_STATICS = {
-  [ForwardRef]: FORWARD_REF_STATICS,
-  [Memo]: MEMO_STATICS
-};
-function getStatics(component) {
-  if (isMemo(component)) {
-    return MEMO_STATICS;
-  }
-  return TYPE_STATICS[component["$$typeof"]] || REACT_STATICS;
-}
-var defineProperty = Object.defineProperty;
-var getOwnPropertyNames = Object.getOwnPropertyNames;
-var getOwnPropertySymbols = Object.getOwnPropertySymbols;
-var getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
-var getPrototypeOf = Object.getPrototypeOf;
-var objectPrototype = Object.prototype;
-function hoistNonReactStatics(targetComponent, sourceComponent) {
-  if (typeof sourceComponent !== "string") {
-    if (objectPrototype) {
-      const inheritedComponent = getPrototypeOf(sourceComponent);
-      if (inheritedComponent && inheritedComponent !== objectPrototype) {
-        hoistNonReactStatics(targetComponent, inheritedComponent);
-      }
-    }
-    let keys = getOwnPropertyNames(sourceComponent);
-    if (getOwnPropertySymbols) {
-      keys = keys.concat(getOwnPropertySymbols(sourceComponent));
-    }
-    const targetStatics = getStatics(targetComponent);
-    const sourceStatics = getStatics(sourceComponent);
-    for (let i = 0; i < keys.length; ++i) {
-      const key = keys[i];
-      if (!KNOWN_STATICS[key] && !(sourceStatics && sourceStatics[key]) && !(targetStatics && targetStatics[key])) {
-        const descriptor = getOwnPropertyDescriptor(sourceComponent, key);
-        try {
-          defineProperty(targetComponent, key, descriptor);
-        } catch (e) {
-        }
-      }
-    }
+// src/components/Context.ts
+var ContextKey = /* @__PURE__ */ Symbol.for(`react-redux-context`);
+var gT = typeof globalThis !== "undefined" ? globalThis : (
+  /* fall back to a per-module scope (pre-8.1 behaviour) if `globalThis` is not available */
+  {}
+);
+function getContext() {
+  if (!React.createContext) return {};
+  const contextMap = gT[ContextKey] ??= /* @__PURE__ */ new Map();
+  let realContext = contextMap.get(React.createContext);
+  if (!realContext) {
+    realContext = React.createContext(
+      null
+    );
+    contextMap.set(React.createContext, realContext);
   }
-  return targetComponent;
+  return realContext;
 }
+var ReactReduxContext = /* @__PURE__ */ getContext();

 // src/components/connect.tsx
-var useSyncExternalStore = notInitialized;
-var initializeConnect = (fn) => {
-  useSyncExternalStore = fn;
-};
 var NO_SUBSCRIPTION_ARRAY = [null, null];
 function useIsomorphicLayoutEffectWithArgs(effectFunc, effectArgs, dependencies) {
   useIsomorphicLayoutEffect(() => effectFunc(...effectArgs), dependencies);
@@ -538,8 +522,7 @@
   }
 }
 function subscribeUpdates(shouldHandleStateChanges, store, subscription, childPropsSelector, lastWrapperProps, lastChildProps, renderIsScheduled, isMounted, childPropsFromStoreUpdate, notifyNestedSubs, additionalSubscribeListener) {
-  if (!shouldHandleStateChanges)
-    return () => {
+  if (!shouldHandleStateChanges) return () => {
     };
   let didUnsubscribe = false;
   let lastThrownError = null;
@@ -616,7 +599,6 @@
       WrappedComponent,
       // @ts-ignore
       initMapStateToProps,
-      // @ts-ignore
       initMapDispatchToProps,
       initMergeProps,
       areStatesEqual,
@@ -643,8 +625,7 @@
         return finalPropsSelectorFactory(store.dispatch, selectorFactoryOptions);
       }, [store]);
       const [subscription, notifyNestedSubs] = React.useMemo(() => {
-        if (!shouldHandleStateChanges)
-          return NO_SUBSCRIPTION_ARRAY;
+        if (!shouldHandleStateChanges) return NO_SUBSCRIPTION_ARRAY;
         const subscription2 = createSubscription(
           store,
           didStoreComeFromProps ? void 0 : contextValue.subscription
@@ -717,7 +698,7 @@
       ]);
       let actualChildProps;
       try {
-        actualChildProps = useSyncExternalStore(
+        actualChildProps = React.useSyncExternalStore(
           // TODO We're passing through a big wrapper that does a bunch of extra side effects besides subscribing
           subscribeForReact,
           // TODO This is incredibly hacky. We've already processed the store update and calculated new child props,
@@ -780,6 +761,5 @@
   return wrapWithConnect;
 }
 var connect_default = connect;
-initializeConnect(ReactOriginal.useSyncExternalStore);

 export { connect_default as connect };
createDispatchHook changes (Click to expand)

File Content:

export { createDispatchHook } from 'react-redux'
Before and After
--- before/react-redux/createDispatchHook.js	2024-06-25 04:42:17.398572300 -0500
+++ after/react-redux/createDispatchHook.js	2024-06-25 10:30:38.137404200 -0500
@@ -1,23 +1,17 @@
-import * as ReactOriginal from 'react';
+import * as React from 'react';
 import 'use-sync-external-store/with-selector.js';

-// src/index.ts
-var React = (
-  // prettier-ignore
-  // @ts-ignore
-  "default" in ReactOriginal ? ReactOriginal["default"] : ReactOriginal
-);
+// src/utils/bindActionCreators.ts

 // src/components/Context.ts
-var ContextKey = Symbol.for(`react-redux-context`);
+var ContextKey = /* @__PURE__ */ Symbol.for(`react-redux-context`);
 var gT = typeof globalThis !== "undefined" ? globalThis : (
   /* fall back to a per-module scope (pre-8.1 behaviour) if `globalThis` is not available */
   {}
 );
 function getContext() {
-  if (!React.createContext)
-    return {};
-  const contextMap = gT[ContextKey] ?? (gT[ContextKey] = /* @__PURE__ */ new Map());
+  if (!React.createContext) return {};
+  const contextMap = gT[ContextKey] ??= /* @__PURE__ */ new Map();
   let realContext = contextMap.get(React.createContext);
   if (!realContext) {
     realContext = React.createContext(
@@ -38,11 +32,6 @@
 }
 var useReduxContext = /* @__PURE__ */ createReduxContextHook();

-// src/utils/useIsomorphicLayoutEffect.ts
-var canUseDOM = !!(typeof window !== "undefined" && typeof window.document !== "undefined" && typeof window.document.createElement !== "undefined");
-var isReactNative = typeof navigator !== "undefined" && navigator.product === "ReactNative";
-canUseDOM || isReactNative ? React.useLayoutEffect : React.useEffect;
-
 // src/hooks/useStore.ts
 function createStoreHook(context = ReactReduxContext) {
   const useReduxContext2 = context === ReactReduxContext ? useReduxContext : (
createSelectorHook changes (Click to expand)

File Content:

export { createSelectorHook } from 'react-redux'
Before and After
--- before/react-redux/createSelectorHook.js	2024-06-25 04:42:17.451573300 -0500
+++ after/react-redux/createSelectorHook.js	2024-06-25 10:30:38.479404900 -0500
@@ -1,23 +1,17 @@
-import * as ReactOriginal from 'react';
-import { useSyncExternalStoreWithSelector as useSyncExternalStoreWithSelector$1 } from 'use-sync-external-store/with-selector.js';
+import * as React from 'react';
+import { useSyncExternalStoreWithSelector } from 'use-sync-external-store/with-selector.js';

-// src/index.ts
-var React = (
-  // prettier-ignore
-  // @ts-ignore
-  "default" in ReactOriginal ? ReactOriginal["default"] : ReactOriginal
-);
+// src/utils/bindActionCreators.ts

 // src/components/Context.ts
-var ContextKey = Symbol.for(`react-redux-context`);
+var ContextKey = /* @__PURE__ */ Symbol.for(`react-redux-context`);
 var gT = typeof globalThis !== "undefined" ? globalThis : (
   /* fall back to a per-module scope (pre-8.1 behaviour) if `globalThis` is not available */
   {}
 );
 function getContext() {
-  if (!React.createContext)
-    return {};
-  const contextMap = gT[ContextKey] ?? (gT[ContextKey] = /* @__PURE__ */ new Map());
+  if (!React.createContext) return {};
+  const contextMap = gT[ContextKey] ??= /* @__PURE__ */ new Map();
   let realContext = contextMap.get(React.createContext);
   if (!realContext) {
     realContext = React.createContext(
@@ -29,11 +23,6 @@
 }
 var ReactReduxContext = /* @__PURE__ */ getContext();

-// src/utils/useSyncExternalStore.ts
-var notInitialized = () => {
-  throw new Error("uSES not initialized!");
-};
-
 // src/hooks/useReduxContext.ts
 function createReduxContextHook(context = ReactReduxContext) {
   return function useReduxContext2() {
@@ -42,24 +31,13 @@
   };
 }
 var useReduxContext = /* @__PURE__ */ createReduxContextHook();
-
-// src/hooks/useSelector.ts
-var useSyncExternalStoreWithSelector = notInitialized;
-var initializeUseSelector = (fn) => {
-  useSyncExternalStoreWithSelector = fn;
-};
 var refEquality = (a, b) => a === b;
 function createSelectorHook(context = ReactReduxContext) {
   const useReduxContext2 = context === ReactReduxContext ? useReduxContext : createReduxContextHook(context);
   const useSelector2 = (selector, equalityFnOrOptions = {}) => {
-    const { equalityFn = refEquality, devModeChecks = {} } = typeof equalityFnOrOptions === "function" ? { equalityFn: equalityFnOrOptions } : equalityFnOrOptions;
-    const {
-      store,
-      subscription,
-      getServerState,
-      stabilityCheck,
-      identityFunctionCheck
-    } = useReduxContext2();
+    const { equalityFn = refEquality } = typeof equalityFnOrOptions === "function" ? { equalityFn: equalityFnOrOptions } : equalityFnOrOptions;
+    const reduxContext = useReduxContext2();
+    const { store, subscription, getServerState } = reduxContext;
     React.useRef(true);
     const wrappedSelector = React.useCallback(
       {
@@ -68,7 +46,7 @@
           return selected;
         }
       }[selector.name],
-      [selector, stabilityCheck, devModeChecks.stabilityCheck]
+      [selector]
     );
     const selectedState = useSyncExternalStoreWithSelector(
       subscription.addNestedSub,
@@ -86,12 +64,4 @@
   return useSelector2;
 }

-// src/utils/useIsomorphicLayoutEffect.ts
-var canUseDOM = !!(typeof window !== "undefined" && typeof window.document !== "undefined" && typeof window.document.createElement !== "undefined");
-var isReactNative = typeof navigator !== "undefined" && navigator.product === "ReactNative";
-canUseDOM || isReactNative ? React.useLayoutEffect : React.useEffect;
-
-// src/index.ts
-initializeUseSelector(useSyncExternalStoreWithSelector$1);
-
 export { createSelectorHook };
createStoreHook changes (Click to expand)

File Content:

export { createStoreHook } from 'react-redux'
Before and After
--- before/react-redux/createStoreHook.js	2024-06-25 04:42:17.372573100 -0500
+++ after/react-redux/createStoreHook.js	2024-06-25 10:30:38.427404300 -0500
@@ -1,23 +1,17 @@
-import * as ReactOriginal from 'react';
+import * as React from 'react';
 import 'use-sync-external-store/with-selector.js';

-// src/index.ts
-var React = (
-  // prettier-ignore
-  // @ts-ignore
-  "default" in ReactOriginal ? ReactOriginal["default"] : ReactOriginal
-);
+// src/utils/bindActionCreators.ts

 // src/components/Context.ts
-var ContextKey = Symbol.for(`react-redux-context`);
+var ContextKey = /* @__PURE__ */ Symbol.for(`react-redux-context`);
 var gT = typeof globalThis !== "undefined" ? globalThis : (
   /* fall back to a per-module scope (pre-8.1 behaviour) if `globalThis` is not available */
   {}
 );
 function getContext() {
-  if (!React.createContext)
-    return {};
-  const contextMap = gT[ContextKey] ?? (gT[ContextKey] = /* @__PURE__ */ new Map());
+  if (!React.createContext) return {};
+  const contextMap = gT[ContextKey] ??= /* @__PURE__ */ new Map();
   let realContext = contextMap.get(React.createContext);
   if (!realContext) {
     realContext = React.createContext(
@@ -38,11 +32,6 @@
 }
 var useReduxContext = /* @__PURE__ */ createReduxContextHook();

-// src/utils/useIsomorphicLayoutEffect.ts
-var canUseDOM = !!(typeof window !== "undefined" && typeof window.document !== "undefined" && typeof window.document.createElement !== "undefined");
-var isReactNative = typeof navigator !== "undefined" && navigator.product === "ReactNative";
-canUseDOM || isReactNative ? React.useLayoutEffect : React.useEffect;
-
 // src/hooks/useStore.ts
 function createStoreHook(context = ReactReduxContext) {
   const useReduxContext2 = context === ReactReduxContext ? useReduxContext : (
Provider changes (Click to expand)

File Content:

export { Provider } from 'react-redux'
Before and After
--- before/react-redux/Provider.js	2024-06-25 04:42:17.556572300 -0500
+++ after/react-redux/Provider.js	2024-06-25 10:30:38.294404000 -0500
@@ -1,33 +1,7 @@
-import * as ReactOriginal from 'react';
+import * as React from 'react';
 import 'use-sync-external-store/with-selector.js';

-// src/index.ts
-var React = (
-  // prettier-ignore
-  // @ts-ignore
-  "default" in ReactOriginal ? ReactOriginal["default"] : ReactOriginal
-);
-
-// src/components/Context.ts
-var ContextKey = Symbol.for(`react-redux-context`);
-var gT = typeof globalThis !== "undefined" ? globalThis : (
-  /* fall back to a per-module scope (pre-8.1 behaviour) if `globalThis` is not available */
-  {}
-);
-function getContext() {
-  if (!React.createContext)
-    return {};
-  const contextMap = gT[ContextKey] ?? (gT[ContextKey] = /* @__PURE__ */ new Map());
-  let realContext = contextMap.get(React.createContext);
-  if (!realContext) {
-    realContext = React.createContext(
-      null
-    );
-    contextMap.set(React.createContext, realContext);
-  }
-  return realContext;
-}
-var ReactReduxContext = /* @__PURE__ */ getContext();
+// src/utils/bindActionCreators.ts

 // src/utils/batch.ts
 function defaultNoopBatch(callback) {
@@ -74,8 +48,7 @@
         first = listener;
       }
       return function unsubscribe() {
-        if (!isSubscribed || first === null)
-          return;
+        if (!isSubscribed || first === null) return;
         isSubscribed = false;
         if (listener.next) {
           listener.next.prev = listener.prev;
@@ -165,9 +138,32 @@
 }

 // src/utils/useIsomorphicLayoutEffect.ts
-var canUseDOM = !!(typeof window !== "undefined" && typeof window.document !== "undefined" && typeof window.document.createElement !== "undefined");
-var isReactNative = typeof navigator !== "undefined" && navigator.product === "ReactNative";
-var useIsomorphicLayoutEffect = canUseDOM || isReactNative ? React.useLayoutEffect : React.useEffect;
+var canUseDOM = () => !!(typeof window !== "undefined" && typeof window.document !== "undefined" && typeof window.document.createElement !== "undefined");
+var isDOM = /* @__PURE__ */ canUseDOM();
+var isRunningInReactNative = () => typeof navigator !== "undefined" && navigator.product === "ReactNative";
+var isReactNative = /* @__PURE__ */ isRunningInReactNative();
+var getUseIsomorphicLayoutEffect = () => isDOM || isReactNative ? React.useLayoutEffect : React.useEffect;
+var useIsomorphicLayoutEffect = /* @__PURE__ */ getUseIsomorphicLayoutEffect();
+
+// src/components/Context.ts
+var ContextKey = /* @__PURE__ */ Symbol.for(`react-redux-context`);
+var gT = typeof globalThis !== "undefined" ? globalThis : (
+  /* fall back to a per-module scope (pre-8.1 behaviour) if `globalThis` is not available */
+  {}
+);
+function getContext() {
+  if (!React.createContext) return {};
+  const contextMap = gT[ContextKey] ??= /* @__PURE__ */ new Map();
+  let realContext = contextMap.get(React.createContext);
+  if (!realContext) {
+    realContext = React.createContext(
+      null
+    );
+    contextMap.set(React.createContext, realContext);
+  }
+  return realContext;
+}
+var ReactReduxContext = /* @__PURE__ */ getContext();

 // src/components/Provider.tsx
 function Provider({
ReactReduxContext changes (Click to expand)

File Content:

export { ReactReduxContext } from 'react-redux'
Before and After
--- before/react-redux/ReactReduxContext.js	2024-06-25 04:42:17.243573500 -0500
+++ after/react-redux/ReactReduxContext.js	2024-06-25 10:30:38.485403500 -0500
@@ -1,23 +1,17 @@
-import * as ReactOriginal from 'react';
+import * as React from 'react';
 import 'use-sync-external-store/with-selector.js';

-// src/index.ts
-var React = (
-  // prettier-ignore
-  // @ts-ignore
-  "default" in ReactOriginal ? ReactOriginal["default"] : ReactOriginal
-);
+// src/utils/bindActionCreators.ts

 // src/components/Context.ts
-var ContextKey = Symbol.for(`react-redux-context`);
+var ContextKey = /* @__PURE__ */ Symbol.for(`react-redux-context`);
 var gT = typeof globalThis !== "undefined" ? globalThis : (
   /* fall back to a per-module scope (pre-8.1 behaviour) if `globalThis` is not available */
   {}
 );
 function getContext() {
-  if (!React.createContext)
-    return {};
-  const contextMap = gT[ContextKey] ?? (gT[ContextKey] = /* @__PURE__ */ new Map());
+  if (!React.createContext) return {};
+  const contextMap = gT[ContextKey] ??= /* @__PURE__ */ new Map();
   let realContext = contextMap.get(React.createContext);
   if (!realContext) {
     realContext = React.createContext(
@@ -29,9 +23,4 @@
 }
 var ReactReduxContext = /* @__PURE__ */ getContext();

-// src/utils/useIsomorphicLayoutEffect.ts
-var canUseDOM = !!(typeof window !== "undefined" && typeof window.document !== "undefined" && typeof window.document.createElement !== "undefined");
-var isReactNative = typeof navigator !== "undefined" && navigator.product === "ReactNative";
-canUseDOM || isReactNative ? React.useLayoutEffect : React.useEffect;
-
 export { ReactReduxContext };
shallowEqual changes (Click to expand)

File Content:

export { shallowEqual } from 'react-redux'
Before and After
--- before/react-redux/shallowEqual.js	2024-06-25 04:42:17.527573400 -0500
+++ after/react-redux/shallowEqual.js	2024-06-25 10:30:38.351405300 -0500
@@ -1,17 +1,7 @@
-import * as ReactOriginal from 'react';
+import 'react';
 import 'use-sync-external-store/with-selector.js';

-// src/index.ts
-var React = (
-  // prettier-ignore
-  // @ts-ignore
-  "default" in ReactOriginal ? ReactOriginal["default"] : ReactOriginal
-);
-
-// src/utils/useIsomorphicLayoutEffect.ts
-var canUseDOM = !!(typeof window !== "undefined" && typeof window.document !== "undefined" && typeof window.document.createElement !== "undefined");
-var isReactNative = typeof navigator !== "undefined" && navigator.product === "ReactNative";
-canUseDOM || isReactNative ? React.useLayoutEffect : React.useEffect;
+// src/utils/bindActionCreators.ts

 // src/utils/shallowEqual.ts
 function is(x, y) {
@@ -22,15 +12,13 @@
   }
 }
 function shallowEqual(objA, objB) {
-  if (is(objA, objB))
-    return true;
+  if (is(objA, objB)) return true;
   if (typeof objA !== "object" || objA === null || typeof objB !== "object" || objB === null) {
     return false;
   }
   const keysA = Object.keys(objA);
   const keysB = Object.keys(objB);
-  if (keysA.length !== keysB.length)
-    return false;
+  if (keysA.length !== keysB.length) return false;
   for (let i = 0; i < keysA.length; i++) {
     if (!Object.prototype.hasOwnProperty.call(objB, keysA[i]) || !is(objA[keysA[i]], objB[keysA[i]])) {
       return false;
useDispatch changes (Click to expand)

File Content:

export { useDispatch } from 'react-redux'
Before and After
--- before/react-redux/useDispatch.js	2024-06-25 04:42:17.326572800 -0500
+++ after/react-redux/useDispatch.js	2024-06-25 10:30:38.448404700 -0500
@@ -1,23 +1,17 @@
-import * as ReactOriginal from 'react';
+import * as React from 'react';
 import 'use-sync-external-store/with-selector.js';

-// src/index.ts
-var React = (
-  // prettier-ignore
-  // @ts-ignore
-  "default" in ReactOriginal ? ReactOriginal["default"] : ReactOriginal
-);
+// src/utils/bindActionCreators.ts

 // src/components/Context.ts
-var ContextKey = Symbol.for(`react-redux-context`);
+var ContextKey = /* @__PURE__ */ Symbol.for(`react-redux-context`);
 var gT = typeof globalThis !== "undefined" ? globalThis : (
   /* fall back to a per-module scope (pre-8.1 behaviour) if `globalThis` is not available */
   {}
 );
 function getContext() {
-  if (!React.createContext)
-    return {};
-  const contextMap = gT[ContextKey] ?? (gT[ContextKey] = /* @__PURE__ */ new Map());
+  if (!React.createContext) return {};
+  const contextMap = gT[ContextKey] ??= /* @__PURE__ */ new Map();
   let realContext = contextMap.get(React.createContext);
   if (!realContext) {
     realContext = React.createContext(
@@ -38,11 +32,6 @@
 }
 var useReduxContext = /* @__PURE__ */ createReduxContextHook();

-// src/utils/useIsomorphicLayoutEffect.ts
-var canUseDOM = !!(typeof window !== "undefined" && typeof window.document !== "undefined" && typeof window.document.createElement !== "undefined");
-var isReactNative = typeof navigator !== "undefined" && navigator.product === "ReactNative";
-canUseDOM || isReactNative ? React.useLayoutEffect : React.useEffect;
-
 // src/hooks/useStore.ts
 function createStoreHook(context = ReactReduxContext) {
   const useReduxContext2 = context === ReactReduxContext ? useReduxContext : (
useSelector changes (Click to expand)

File Content:

export { useSelector } from 'react-redux'
Before and After
--- before/react-redux/useSelector.js	2024-06-25 04:42:17.535572500 -0500
+++ after/react-redux/useSelector.js	2024-06-25 10:30:38.274405300 -0500
@@ -1,23 +1,17 @@
-import * as ReactOriginal from 'react';
-import { useSyncExternalStoreWithSelector as useSyncExternalStoreWithSelector$1 } from 'use-sync-external-store/with-selector.js';
+import * as React from 'react';
+import { useSyncExternalStoreWithSelector } from 'use-sync-external-store/with-selector.js';

-// src/index.ts
-var React = (
-  // prettier-ignore
-  // @ts-ignore
-  "default" in ReactOriginal ? ReactOriginal["default"] : ReactOriginal
-);
+// src/utils/bindActionCreators.ts

 // src/components/Context.ts
-var ContextKey = Symbol.for(`react-redux-context`);
+var ContextKey = /* @__PURE__ */ Symbol.for(`react-redux-context`);
 var gT = typeof globalThis !== "undefined" ? globalThis : (
   /* fall back to a per-module scope (pre-8.1 behaviour) if `globalThis` is not available */
   {}
 );
 function getContext() {
-  if (!React.createContext)
-    return {};
-  const contextMap = gT[ContextKey] ?? (gT[ContextKey] = /* @__PURE__ */ new Map());
+  if (!React.createContext) return {};
+  const contextMap = gT[ContextKey] ??= /* @__PURE__ */ new Map();
   let realContext = contextMap.get(React.createContext);
   if (!realContext) {
     realContext = React.createContext(
@@ -29,11 +23,6 @@
 }
 var ReactReduxContext = /* @__PURE__ */ getContext();

-// src/utils/useSyncExternalStore.ts
-var notInitialized = () => {
-  throw new Error("uSES not initialized!");
-};
-
 // src/hooks/useReduxContext.ts
 function createReduxContextHook(context = ReactReduxContext) {
   return function useReduxContext2() {
@@ -42,24 +31,13 @@
   };
 }
 var useReduxContext = /* @__PURE__ */ createReduxContextHook();
-
-// src/hooks/useSelector.ts
-var useSyncExternalStoreWithSelector = notInitialized;
-var initializeUseSelector = (fn) => {
-  useSyncExternalStoreWithSelector = fn;
-};
 var refEquality = (a, b) => a === b;
 function createSelectorHook(context = ReactReduxContext) {
   const useReduxContext2 = context === ReactReduxContext ? useReduxContext : createReduxContextHook(context);
   const useSelector2 = (selector, equalityFnOrOptions = {}) => {
-    const { equalityFn = refEquality, devModeChecks = {} } = typeof equalityFnOrOptions === "function" ? { equalityFn: equalityFnOrOptions } : equalityFnOrOptions;
-    const {
-      store,
-      subscription,
-      getServerState,
-      stabilityCheck,
-      identityFunctionCheck
-    } = useReduxContext2();
+    const { equalityFn = refEquality } = typeof equalityFnOrOptions === "function" ? { equalityFn: equalityFnOrOptions } : equalityFnOrOptions;
+    const reduxContext = useReduxContext2();
+    const { store, subscription, getServerState } = reduxContext;
     React.useRef(true);
     const wrappedSelector = React.useCallback(
       {
@@ -68,7 +46,7 @@
           return selected;
         }
       }[selector.name],
-      [selector, stabilityCheck, devModeChecks.stabilityCheck]
+      [selector]
     );
     const selectedState = useSyncExternalStoreWithSelector(
       subscription.addNestedSub,
@@ -87,12 +65,4 @@
 }
 var useSelector = /* @__PURE__ */ createSelectorHook();

-// src/utils/useIsomorphicLayoutEffect.ts
-var canUseDOM = !!(typeof window !== "undefined" && typeof window.document !== "undefined" && typeof window.document.createElement !== "undefined");
-var isReactNative = typeof navigator !== "undefined" && navigator.product === "ReactNative";
-canUseDOM || isReactNative ? React.useLayoutEffect : React.useEffect;
-
-// src/index.ts
-initializeUseSelector(useSyncExternalStoreWithSelector$1);
-
 export { useSelector };
useStore changes (Click to expand)

File Content:

export { useStore } from 'react-redux'
Before and After
--- before/react-redux/useStore.js	2024-06-25 04:42:17.586572600 -0500
+++ after/react-redux/useStore.js	2024-06-25 10:30:38.471405000 -0500
@@ -1,23 +1,17 @@
-import * as ReactOriginal from 'react';
+import * as React from 'react';
 import 'use-sync-external-store/with-selector.js';

-// src/index.ts
-var React = (
-  // prettier-ignore
-  // @ts-ignore
-  "default" in ReactOriginal ? ReactOriginal["default"] : ReactOriginal
-);
+// src/utils/bindActionCreators.ts

 // src/components/Context.ts
-var ContextKey = Symbol.for(`react-redux-context`);
+var ContextKey = /* @__PURE__ */ Symbol.for(`react-redux-context`);
 var gT = typeof globalThis !== "undefined" ? globalThis : (
   /* fall back to a per-module scope (pre-8.1 behaviour) if `globalThis` is not available */
   {}
 );
 function getContext() {
-  if (!React.createContext)
-    return {};
-  const contextMap = gT[ContextKey] ?? (gT[ContextKey] = /* @__PURE__ */ new Map());
+  if (!React.createContext) return {};
+  const contextMap = gT[ContextKey] ??= /* @__PURE__ */ new Map();
   let realContext = contextMap.get(React.createContext);
   if (!realContext) {
     realContext = React.createContext(
@@ -38,11 +32,6 @@
 }
 var useReduxContext = /* @__PURE__ */ createReduxContextHook();

-// src/utils/useIsomorphicLayoutEffect.ts
-var canUseDOM = !!(typeof window !== "undefined" && typeof window.document !== "undefined" && typeof window.document.createElement !== "undefined");
-var isReactNative = typeof navigator !== "undefined" && navigator.product === "ReactNative";
-canUseDOM || isReactNative ? React.useLayoutEffect : React.useEffect;
-
 // src/hooks/useStore.ts
 function createStoreHook(context = ReactReduxContext) {
   const useReduxContext2 = context === ReactReduxContext ? useReduxContext : (

@markerikson
Copy link
Contributor

@aryaemami59 note that the ReactOriginal changes were intentional - ESBuild still doesn't support deduplicating imports across multiple files, so prior to me consolidating all our React imports, we ended up up with a half-dozen import React5 from "react" lines in the bundle

@aryaemami59
Copy link
Contributor Author

aryaemami59 commented Jun 25, 2024

@markerikson Yeah I very much agree with that change, tsup and esbuild kind of collide when it comes to jsx, esbuild is supposed to automatically import it but it just doesn't work the way it's supposed to, so funneling all the React imports through a utils file is the way to go, which is why I didn't change the imports themselves. The issue is the conditional check for a default value in the React namespace makes it a little problematic as it becomes a side effect and starts bleeding into a bunch of files that might not need it. And as far as the duplicate imports go, I'm keeping a close eye on it. For reference, here is what the current react-redux.mjs file looks like and as of now it has only a single React import:

Click to expand
// src/utils/bindActionCreators.ts
function bindActionCreators(actionCreators, dispatch) {
  const boundActionCreators = {};
  for (const key in actionCreators) {
    const actionCreator = actionCreators[key];
    if (typeof actionCreator === "function") {
      boundActionCreators[key] = (...args) => dispatch(actionCreator(...args));
    }
  }
  return boundActionCreators;
}

// src/utils/isPlainObject.ts
function isPlainObject(obj) {
  if (typeof obj !== "object" || obj === null) return false;
  const proto = Object.getPrototypeOf(obj);
  if (proto === null) return true;
  let baseProto = proto;
  while (Object.getPrototypeOf(baseProto) !== null) {
    baseProto = Object.getPrototypeOf(baseProto);
  }
  return proto === baseProto;
}

// src/utils/warning.ts
function warning(message) {
  if (typeof console !== "undefined" && typeof console.error === "function") {
    console.error(message);
  }
  try {
    throw new Error(message);
  } catch (e) {
  }
}

// src/utils/verifyPlainObject.ts
function verifyPlainObject(value, displayName, methodName) {
  if (!isPlainObject(value)) {
    warning(
      `${methodName}() in ${displayName} must return a plain object. Instead received ${value}.`
    );
  }
}

// src/connect/wrapMapToProps.ts
function wrapMapToPropsConstant(getConstant) {
  return function initConstantSelector(dispatch) {
    const constant = getConstant(dispatch);
    function constantSelector() {
      return constant;
    }
    constantSelector.dependsOnOwnProps = false;
    return constantSelector;
  };
}
function getDependsOnOwnProps(mapToProps) {
  return mapToProps.dependsOnOwnProps ? Boolean(mapToProps.dependsOnOwnProps) : mapToProps.length !== 1;
}
function wrapMapToPropsFunc(mapToProps, methodName) {
  return function initProxySelector(dispatch, { displayName }) {
    const proxy = function mapToPropsProxy(stateOrDispatch, ownProps) {
      return proxy.dependsOnOwnProps ? proxy.mapToProps(stateOrDispatch, ownProps) : proxy.mapToProps(stateOrDispatch, void 0);
    };
    proxy.dependsOnOwnProps = true;
    proxy.mapToProps = function detectFactoryAndVerify(stateOrDispatch, ownProps) {
      proxy.mapToProps = mapToProps;
      proxy.dependsOnOwnProps = getDependsOnOwnProps(mapToProps);
      let props = proxy(stateOrDispatch, ownProps);
      if (typeof props === "function") {
        proxy.mapToProps = props;
        proxy.dependsOnOwnProps = getDependsOnOwnProps(props);
        props = proxy(stateOrDispatch, ownProps);
      }
      if (process.env.NODE_ENV !== "production")
        verifyPlainObject(props, displayName, methodName);
      return props;
    };
    return proxy;
  };
}

// src/connect/invalidArgFactory.ts
function createInvalidArgFactory(arg, name) {
  return (dispatch, options) => {
    throw new Error(
      `Invalid value of type ${typeof arg} for ${name} argument when connecting component ${options.wrappedComponentName}.`
    );
  };
}

// src/connect/mapDispatchToProps.ts
function mapDispatchToPropsFactory(mapDispatchToProps) {
  return mapDispatchToProps && typeof mapDispatchToProps === "object" ? wrapMapToPropsConstant(
    (dispatch) => (
      // @ts-ignore
      bindActionCreators(mapDispatchToProps, dispatch)
    )
  ) : !mapDispatchToProps ? wrapMapToPropsConstant((dispatch) => ({
    dispatch
  })) : typeof mapDispatchToProps === "function" ? (
    // @ts-ignore
    wrapMapToPropsFunc(mapDispatchToProps, "mapDispatchToProps")
  ) : createInvalidArgFactory(mapDispatchToProps, "mapDispatchToProps");
}

// src/connect/mapStateToProps.ts
function mapStateToPropsFactory(mapStateToProps) {
  return !mapStateToProps ? wrapMapToPropsConstant(() => ({})) : typeof mapStateToProps === "function" ? (
    // @ts-ignore
    wrapMapToPropsFunc(mapStateToProps, "mapStateToProps")
  ) : createInvalidArgFactory(mapStateToProps, "mapStateToProps");
}

// src/connect/mergeProps.ts
function defaultMergeProps(stateProps, dispatchProps, ownProps) {
  return { ...ownProps, ...stateProps, ...dispatchProps };
}
function wrapMergePropsFunc(mergeProps) {
  return function initMergePropsProxy(dispatch, { displayName, areMergedPropsEqual }) {
    let hasRunOnce = false;
    let mergedProps;
    return function mergePropsProxy(stateProps, dispatchProps, ownProps) {
      const nextMergedProps = mergeProps(stateProps, dispatchProps, ownProps);
      if (hasRunOnce) {
        if (!areMergedPropsEqual(nextMergedProps, mergedProps))
          mergedProps = nextMergedProps;
      } else {
        hasRunOnce = true;
        mergedProps = nextMergedProps;
        if (process.env.NODE_ENV !== "production")
          verifyPlainObject(mergedProps, displayName, "mergeProps");
      }
      return mergedProps;
    };
  };
}
function mergePropsFactory(mergeProps) {
  return !mergeProps ? () => defaultMergeProps : typeof mergeProps === "function" ? wrapMergePropsFunc(mergeProps) : createInvalidArgFactory(mergeProps, "mergeProps");
}

// src/connect/verifySubselectors.ts
function verify(selector, methodName) {
  if (!selector) {
    throw new Error(`Unexpected value for ${methodName} in connect.`);
  } else if (methodName === "mapStateToProps" || methodName === "mapDispatchToProps") {
    if (!Object.prototype.hasOwnProperty.call(selector, "dependsOnOwnProps")) {
      warning(
        `The selector for ${methodName} of connect did not specify a value for dependsOnOwnProps.`
      );
    }
  }
}
function verifySubselectors(mapStateToProps, mapDispatchToProps, mergeProps) {
  verify(mapStateToProps, "mapStateToProps");
  verify(mapDispatchToProps, "mapDispatchToProps");
  verify(mergeProps, "mergeProps");
}

// src/connect/selectorFactory.ts
function pureFinalPropsSelectorFactory(mapStateToProps, mapDispatchToProps, mergeProps, dispatch, {
  areStatesEqual,
  areOwnPropsEqual,
  areStatePropsEqual
}) {
  let hasRunAtLeastOnce = false;
  let state;
  let ownProps;
  let stateProps;
  let dispatchProps;
  let mergedProps;
  function handleFirstCall(firstState, firstOwnProps) {
    state = firstState;
    ownProps = firstOwnProps;
    stateProps = mapStateToProps(state, ownProps);
    dispatchProps = mapDispatchToProps(dispatch, ownProps);
    mergedProps = mergeProps(stateProps, dispatchProps, ownProps);
    hasRunAtLeastOnce = true;
    return mergedProps;
  }
  function handleNewPropsAndNewState() {
    stateProps = mapStateToProps(state, ownProps);
    if (mapDispatchToProps.dependsOnOwnProps)
      dispatchProps = mapDispatchToProps(dispatch, ownProps);
    mergedProps = mergeProps(stateProps, dispatchProps, ownProps);
    return mergedProps;
  }
  function handleNewProps() {
    if (mapStateToProps.dependsOnOwnProps)
      stateProps = mapStateToProps(state, ownProps);
    if (mapDispatchToProps.dependsOnOwnProps)
      dispatchProps = mapDispatchToProps(dispatch, ownProps);
    mergedProps = mergeProps(stateProps, dispatchProps, ownProps);
    return mergedProps;
  }
  function handleNewState() {
    const nextStateProps = mapStateToProps(state, ownProps);
    const statePropsChanged = !areStatePropsEqual(nextStateProps, stateProps);
    stateProps = nextStateProps;
    if (statePropsChanged)
      mergedProps = mergeProps(stateProps, dispatchProps, ownProps);
    return mergedProps;
  }
  function handleSubsequentCalls(nextState, nextOwnProps) {
    const propsChanged = !areOwnPropsEqual(nextOwnProps, ownProps);
    const stateChanged = !areStatesEqual(
      nextState,
      state,
      nextOwnProps,
      ownProps
    );
    state = nextState;
    ownProps = nextOwnProps;
    if (propsChanged && stateChanged) return handleNewPropsAndNewState();
    if (propsChanged) return handleNewProps();
    if (stateChanged) return handleNewState();
    return mergedProps;
  }
  return function pureFinalPropsSelector(nextState, nextOwnProps) {
    return hasRunAtLeastOnce ? handleSubsequentCalls(nextState, nextOwnProps) : handleFirstCall(nextState, nextOwnProps);
  };
}
function finalPropsSelectorFactory(dispatch, {
  initMapStateToProps,
  initMapDispatchToProps,
  initMergeProps,
  ...options
}) {
  const mapStateToProps = initMapStateToProps(dispatch, options);
  const mapDispatchToProps = initMapDispatchToProps(dispatch, options);
  const mergeProps = initMergeProps(dispatch, options);
  if (process.env.NODE_ENV !== "production") {
    verifySubselectors(mapStateToProps, mapDispatchToProps, mergeProps);
  }
  return pureFinalPropsSelectorFactory(mapStateToProps, mapDispatchToProps, mergeProps, dispatch, options);
}

// src/utils/react-is.ts
var REACT_ELEMENT_TYPE = /* @__PURE__ */ Symbol.for("react.element");
var REACT_PORTAL_TYPE = /* @__PURE__ */ Symbol.for("react.portal");
var REACT_FRAGMENT_TYPE = /* @__PURE__ */ Symbol.for("react.fragment");
var REACT_STRICT_MODE_TYPE = /* @__PURE__ */ Symbol.for("react.strict_mode");
var REACT_PROFILER_TYPE = /* @__PURE__ */ Symbol.for("react.profiler");
var REACT_PROVIDER_TYPE = /* @__PURE__ */ Symbol.for("react.provider");
var REACT_CONTEXT_TYPE = /* @__PURE__ */ Symbol.for("react.context");
var REACT_SERVER_CONTEXT_TYPE = /* @__PURE__ */ Symbol.for(
  "react.server_context"
);
var REACT_FORWARD_REF_TYPE = /* @__PURE__ */ Symbol.for("react.forward_ref");
var REACT_SUSPENSE_TYPE = /* @__PURE__ */ Symbol.for("react.suspense");
var REACT_SUSPENSE_LIST_TYPE = /* @__PURE__ */ Symbol.for(
  "react.suspense_list"
);
var REACT_MEMO_TYPE = /* @__PURE__ */ Symbol.for("react.memo");
var REACT_LAZY_TYPE = /* @__PURE__ */ Symbol.for("react.lazy");
var REACT_OFFSCREEN_TYPE = /* @__PURE__ */ Symbol.for("react.offscreen");
var REACT_CLIENT_REFERENCE = /* @__PURE__ */ Symbol.for(
  "react.client.reference"
);
var ForwardRef = REACT_FORWARD_REF_TYPE;
var Memo = REACT_MEMO_TYPE;
function isValidElementType(type) {
  if (typeof type === "string" || typeof type === "function") {
    return true;
  }
  if (type === REACT_FRAGMENT_TYPE || type === REACT_PROFILER_TYPE || type === REACT_STRICT_MODE_TYPE || type === REACT_SUSPENSE_TYPE || type === REACT_SUSPENSE_LIST_TYPE || type === REACT_OFFSCREEN_TYPE) {
    return true;
  }
  if (typeof type === "object" && type !== null) {
    if (type.$$typeof === REACT_LAZY_TYPE || type.$$typeof === REACT_MEMO_TYPE || type.$$typeof === REACT_PROVIDER_TYPE || type.$$typeof === REACT_CONTEXT_TYPE || type.$$typeof === REACT_FORWARD_REF_TYPE || // This needs to include all possible module reference object
    // types supported by any Flight configuration anywhere since
    // we don't know which Flight build this will end up being used
    // with.
    type.$$typeof === REACT_CLIENT_REFERENCE || type.getModuleId !== void 0) {
      return true;
    }
  }
  return false;
}
function typeOf(object) {
  if (typeof object === "object" && object !== null) {
    const $$typeof = object.$$typeof;
    switch ($$typeof) {
      case REACT_ELEMENT_TYPE: {
        const type = object.type;
        switch (type) {
          case REACT_FRAGMENT_TYPE:
          case REACT_PROFILER_TYPE:
          case REACT_STRICT_MODE_TYPE:
          case REACT_SUSPENSE_TYPE:
          case REACT_SUSPENSE_LIST_TYPE:
            return type;
          default: {
            const $$typeofType = type && type.$$typeof;
            switch ($$typeofType) {
              case REACT_SERVER_CONTEXT_TYPE:
              case REACT_CONTEXT_TYPE:
              case REACT_FORWARD_REF_TYPE:
              case REACT_LAZY_TYPE:
              case REACT_MEMO_TYPE:
              case REACT_PROVIDER_TYPE:
                return $$typeofType;
              default:
                return $$typeof;
            }
          }
        }
      }
      case REACT_PORTAL_TYPE: {
        return $$typeof;
      }
    }
  }
  return void 0;
}
function isContextConsumer(object) {
  return typeOf(object) === REACT_CONTEXT_TYPE;
}
function isMemo(object) {
  return typeOf(object) === REACT_MEMO_TYPE;
}

// src/utils/hoistStatics.ts
var REACT_STATICS = {
  childContextTypes: true,
  contextType: true,
  contextTypes: true,
  defaultProps: true,
  displayName: true,
  getDefaultProps: true,
  getDerivedStateFromError: true,
  getDerivedStateFromProps: true,
  mixins: true,
  propTypes: true,
  type: true
};
var KNOWN_STATICS = {
  name: true,
  length: true,
  prototype: true,
  caller: true,
  callee: true,
  arguments: true,
  arity: true
};
var FORWARD_REF_STATICS = {
  $$typeof: true,
  render: true,
  defaultProps: true,
  displayName: true,
  propTypes: true
};
var MEMO_STATICS = {
  $$typeof: true,
  compare: true,
  defaultProps: true,
  displayName: true,
  propTypes: true,
  type: true
};
var TYPE_STATICS = {
  [ForwardRef]: FORWARD_REF_STATICS,
  [Memo]: MEMO_STATICS
};
function getStatics(component) {
  if (isMemo(component)) {
    return MEMO_STATICS;
  }
  return TYPE_STATICS[component["$$typeof"]] || REACT_STATICS;
}
var defineProperty = Object.defineProperty;
var getOwnPropertyNames = Object.getOwnPropertyNames;
var getOwnPropertySymbols = Object.getOwnPropertySymbols;
var getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
var getPrototypeOf = Object.getPrototypeOf;
var objectPrototype = Object.prototype;
function hoistNonReactStatics(targetComponent, sourceComponent) {
  if (typeof sourceComponent !== "string") {
    if (objectPrototype) {
      const inheritedComponent = getPrototypeOf(sourceComponent);
      if (inheritedComponent && inheritedComponent !== objectPrototype) {
        hoistNonReactStatics(targetComponent, inheritedComponent);
      }
    }
    let keys = getOwnPropertyNames(sourceComponent);
    if (getOwnPropertySymbols) {
      keys = keys.concat(getOwnPropertySymbols(sourceComponent));
    }
    const targetStatics = getStatics(targetComponent);
    const sourceStatics = getStatics(sourceComponent);
    for (let i = 0; i < keys.length; ++i) {
      const key = keys[i];
      if (!KNOWN_STATICS[key] && !(sourceStatics && sourceStatics[key]) && !(targetStatics && targetStatics[key])) {
        const descriptor = getOwnPropertyDescriptor(sourceComponent, key);
        try {
          defineProperty(targetComponent, key, descriptor);
        } catch (e) {
        }
      }
    }
  }
  return targetComponent;
}

// src/utils/react.ts
import * as React from "react";

// src/utils/shallowEqual.ts
function is(x, y) {
  if (x === y) {
    return x !== 0 || y !== 0 || 1 / x === 1 / y;
  } else {
    return x !== x && y !== y;
  }
}
function shallowEqual(objA, objB) {
  if (is(objA, objB)) return true;
  if (typeof objA !== "object" || objA === null || typeof objB !== "object" || objB === null) {
    return false;
  }
  const keysA = Object.keys(objA);
  const keysB = Object.keys(objB);
  if (keysA.length !== keysB.length) return false;
  for (let i = 0; i < keysA.length; i++) {
    if (!Object.prototype.hasOwnProperty.call(objB, keysA[i]) || !is(objA[keysA[i]], objB[keysA[i]])) {
      return false;
    }
  }
  return true;
}

// src/utils/batch.ts
function defaultNoopBatch(callback) {
  callback();
}

// src/utils/Subscription.ts
function createListenerCollection() {
  let first = null;
  let last = null;
  return {
    clear() {
      first = null;
      last = null;
    },
    notify() {
      defaultNoopBatch(() => {
        let listener = first;
        while (listener) {
          listener.callback();
          listener = listener.next;
        }
      });
    },
    get() {
      const listeners = [];
      let listener = first;
      while (listener) {
        listeners.push(listener);
        listener = listener.next;
      }
      return listeners;
    },
    subscribe(callback) {
      let isSubscribed = true;
      const listener = last = {
        callback,
        next: null,
        prev: last
      };
      if (listener.prev) {
        listener.prev.next = listener;
      } else {
        first = listener;
      }
      return function unsubscribe() {
        if (!isSubscribed || first === null) return;
        isSubscribed = false;
        if (listener.next) {
          listener.next.prev = listener.prev;
        } else {
          last = listener.prev;
        }
        if (listener.prev) {
          listener.prev.next = listener.next;
        } else {
          first = listener.next;
        }
      };
    }
  };
}
var nullListeners = {
  notify() {
  },
  get: () => []
};
function createSubscription(store, parentSub) {
  let unsubscribe;
  let listeners = nullListeners;
  let subscriptionsAmount = 0;
  let selfSubscribed = false;
  function addNestedSub(listener) {
    trySubscribe();
    const cleanupListener = listeners.subscribe(listener);
    let removed = false;
    return () => {
      if (!removed) {
        removed = true;
        cleanupListener();
        tryUnsubscribe();
      }
    };
  }
  function notifyNestedSubs() {
    listeners.notify();
  }
  function handleChangeWrapper() {
    if (subscription.onStateChange) {
      subscription.onStateChange();
    }
  }
  function isSubscribed() {
    return selfSubscribed;
  }
  function trySubscribe() {
    subscriptionsAmount++;
    if (!unsubscribe) {
      unsubscribe = parentSub ? parentSub.addNestedSub(handleChangeWrapper) : store.subscribe(handleChangeWrapper);
      listeners = createListenerCollection();
    }
  }
  function tryUnsubscribe() {
    subscriptionsAmount--;
    if (unsubscribe && subscriptionsAmount === 0) {
      unsubscribe();
      unsubscribe = void 0;
      listeners.clear();
      listeners = nullListeners;
    }
  }
  function trySubscribeSelf() {
    if (!selfSubscribed) {
      selfSubscribed = true;
      trySubscribe();
    }
  }
  function tryUnsubscribeSelf() {
    if (selfSubscribed) {
      selfSubscribed = false;
      tryUnsubscribe();
    }
  }
  const subscription = {
    addNestedSub,
    notifyNestedSubs,
    handleChangeWrapper,
    isSubscribed,
    trySubscribe: trySubscribeSelf,
    tryUnsubscribe: tryUnsubscribeSelf,
    getListeners: () => listeners
  };
  return subscription;
}

// src/utils/useIsomorphicLayoutEffect.ts
var canUseDOM = () => !!(typeof window !== "undefined" && typeof window.document !== "undefined" && typeof window.document.createElement !== "undefined");
var isDOM = /* @__PURE__ */ canUseDOM();
var isRunningInReactNative = () => typeof navigator !== "undefined" && navigator.product === "ReactNative";
var isReactNative = /* @__PURE__ */ isRunningInReactNative();
var getUseIsomorphicLayoutEffect = () => isDOM || isReactNative ? React.useLayoutEffect : React.useEffect;
var useIsomorphicLayoutEffect = /* @__PURE__ */ getUseIsomorphicLayoutEffect();

// src/components/Context.ts
var ContextKey = /* @__PURE__ */ Symbol.for(`react-redux-context`);
var gT = typeof globalThis !== "undefined" ? globalThis : (
  /* fall back to a per-module scope (pre-8.1 behaviour) if `globalThis` is not available */
  {}
);
function getContext() {
  if (!React.createContext) return {};
  const contextMap = gT[ContextKey] ??= /* @__PURE__ */ new Map();
  let realContext = contextMap.get(React.createContext);
  if (!realContext) {
    realContext = React.createContext(
      null
    );
    if (process.env.NODE_ENV !== "production") {
      realContext.displayName = "ReactRedux";
    }
    contextMap.set(React.createContext, realContext);
  }
  return realContext;
}
var ReactReduxContext = /* @__PURE__ */ getContext();

// src/components/connect.tsx
var NO_SUBSCRIPTION_ARRAY = [null, null];
var stringifyComponent = (Comp) => {
  try {
    return JSON.stringify(Comp);
  } catch (err) {
    return String(Comp);
  }
};
function useIsomorphicLayoutEffectWithArgs(effectFunc, effectArgs, dependencies) {
  useIsomorphicLayoutEffect(() => effectFunc(...effectArgs), dependencies);
}
function captureWrapperProps(lastWrapperProps, lastChildProps, renderIsScheduled, wrapperProps, childPropsFromStoreUpdate, notifyNestedSubs) {
  lastWrapperProps.current = wrapperProps;
  renderIsScheduled.current = false;
  if (childPropsFromStoreUpdate.current) {
    childPropsFromStoreUpdate.current = null;
    notifyNestedSubs();
  }
}
function subscribeUpdates(shouldHandleStateChanges, store, subscription, childPropsSelector, lastWrapperProps, lastChildProps, renderIsScheduled, isMounted, childPropsFromStoreUpdate, notifyNestedSubs, additionalSubscribeListener) {
  if (!shouldHandleStateChanges) return () => {
  };
  let didUnsubscribe = false;
  let lastThrownError = null;
  const checkForUpdates = () => {
    if (didUnsubscribe || !isMounted.current) {
      return;
    }
    const latestStoreState = store.getState();
    let newChildProps, error;
    try {
      newChildProps = childPropsSelector(
        latestStoreState,
        lastWrapperProps.current
      );
    } catch (e) {
      error = e;
      lastThrownError = e;
    }
    if (!error) {
      lastThrownError = null;
    }
    if (newChildProps === lastChildProps.current) {
      if (!renderIsScheduled.current) {
        notifyNestedSubs();
      }
    } else {
      lastChildProps.current = newChildProps;
      childPropsFromStoreUpdate.current = newChildProps;
      renderIsScheduled.current = true;
      additionalSubscribeListener();
    }
  };
  subscription.onStateChange = checkForUpdates;
  subscription.trySubscribe();
  checkForUpdates();
  const unsubscribeWrapper = () => {
    didUnsubscribe = true;
    subscription.tryUnsubscribe();
    subscription.onStateChange = null;
    if (lastThrownError) {
      throw lastThrownError;
    }
  };
  return unsubscribeWrapper;
}
function strictEqual(a, b) {
  return a === b;
}
var hasWarnedAboutDeprecatedPureOption = false;
function connect(mapStateToProps, mapDispatchToProps, mergeProps, {
  // The `pure` option has been removed, so TS doesn't like us destructuring this to check its existence.
  // @ts-ignore
  pure,
  areStatesEqual = strictEqual,
  areOwnPropsEqual = shallowEqual,
  areStatePropsEqual = shallowEqual,
  areMergedPropsEqual = shallowEqual,
  // use React's forwardRef to expose a ref of the wrapped component
  forwardRef = false,
  // the context consumer to use
  context = ReactReduxContext
} = {}) {
  if (process.env.NODE_ENV !== "production") {
    if (pure !== void 0 && !hasWarnedAboutDeprecatedPureOption) {
      hasWarnedAboutDeprecatedPureOption = true;
      warning(
        'The `pure` option has been removed. `connect` is now always a "pure/memoized" component'
      );
    }
  }
  const Context = context;
  const initMapStateToProps = mapStateToPropsFactory(mapStateToProps);
  const initMapDispatchToProps = mapDispatchToPropsFactory(mapDispatchToProps);
  const initMergeProps = mergePropsFactory(mergeProps);
  const shouldHandleStateChanges = Boolean(mapStateToProps);
  const wrapWithConnect = (WrappedComponent) => {
    if (process.env.NODE_ENV !== "production") {
      const isValid = /* @__PURE__ */ isValidElementType(WrappedComponent);
      if (!isValid)
        throw new Error(
          `You must pass a component to the function returned by connect. Instead received ${stringifyComponent(
            WrappedComponent
          )}`
        );
    }
    const wrappedComponentName = WrappedComponent.displayName || WrappedComponent.name || "Component";
    const displayName = `Connect(${wrappedComponentName})`;
    const selectorFactoryOptions = {
      shouldHandleStateChanges,
      displayName,
      wrappedComponentName,
      WrappedComponent,
      // @ts-ignore
      initMapStateToProps,
      initMapDispatchToProps,
      initMergeProps,
      areStatesEqual,
      areStatePropsEqual,
      areOwnPropsEqual,
      areMergedPropsEqual
    };
    function ConnectFunction(props) {
      const [propsContext, reactReduxForwardedRef, wrapperProps] = React.useMemo(() => {
        const { reactReduxForwardedRef: reactReduxForwardedRef2, ...wrapperProps2 } = props;
        return [props.context, reactReduxForwardedRef2, wrapperProps2];
      }, [props]);
      const ContextToUse = React.useMemo(() => {
        let ResultContext = Context;
        if (propsContext?.Consumer) {
          if (process.env.NODE_ENV !== "production") {
            const isValid = /* @__PURE__ */ isContextConsumer(
              // @ts-ignore
              /* @__PURE__ */ React.createElement(propsContext.Consumer, null)
            );
            if (!isValid) {
              throw new Error(
                "You must pass a valid React context consumer as `props.context`"
              );
            }
            ResultContext = propsContext;
          }
        }
        return ResultContext;
      }, [propsContext, Context]);
      const contextValue = React.useContext(ContextToUse);
      const didStoreComeFromProps = Boolean(props.store) && Boolean(props.store.getState) && Boolean(props.store.dispatch);
      const didStoreComeFromContext = Boolean(contextValue) && Boolean(contextValue.store);
      if (process.env.NODE_ENV !== "production" && !didStoreComeFromProps && !didStoreComeFromContext) {
        throw new Error(
          `Could not find "store" in the context of "${displayName}". Either wrap the root component in a <Provider>, or pass a custom React context provider to <Provider> and the corresponding React context consumer to ${displayName} in connect options.`
        );
      }
      const store = didStoreComeFromProps ? props.store : contextValue.store;
      const getServerState = didStoreComeFromContext ? contextValue.getServerState : store.getState;
      const childPropsSelector = React.useMemo(() => {
        return finalPropsSelectorFactory(store.dispatch, selectorFactoryOptions);
      }, [store]);
      const [subscription, notifyNestedSubs] = React.useMemo(() => {
        if (!shouldHandleStateChanges) return NO_SUBSCRIPTION_ARRAY;
        const subscription2 = createSubscription(
          store,
          didStoreComeFromProps ? void 0 : contextValue.subscription
        );
        const notifyNestedSubs2 = subscription2.notifyNestedSubs.bind(subscription2);
        return [subscription2, notifyNestedSubs2];
      }, [store, didStoreComeFromProps, contextValue]);
      const overriddenContextValue = React.useMemo(() => {
        if (didStoreComeFromProps) {
          return contextValue;
        }
        return {
          ...contextValue,
          subscription
        };
      }, [didStoreComeFromProps, contextValue, subscription]);
      const lastChildProps = React.useRef(void 0);
      const lastWrapperProps = React.useRef(wrapperProps);
      const childPropsFromStoreUpdate = React.useRef(void 0);
      const renderIsScheduled = React.useRef(false);
      const isMounted = React.useRef(false);
      const latestSubscriptionCallbackError = React.useRef(
        void 0
      );
      useIsomorphicLayoutEffect(() => {
        isMounted.current = true;
        return () => {
          isMounted.current = false;
        };
      }, []);
      const actualChildPropsSelector = React.useMemo(() => {
        const selector = () => {
          if (childPropsFromStoreUpdate.current && wrapperProps === lastWrapperProps.current) {
            return childPropsFromStoreUpdate.current;
          }
          return childPropsSelector(store.getState(), wrapperProps);
        };
        return selector;
      }, [store, wrapperProps]);
      const subscribeForReact = React.useMemo(() => {
        const subscribe = (reactListener) => {
          if (!subscription) {
            return () => {
            };
          }
          return subscribeUpdates(
            shouldHandleStateChanges,
            store,
            subscription,
            // @ts-ignore
            childPropsSelector,
            lastWrapperProps,
            lastChildProps,
            renderIsScheduled,
            isMounted,
            childPropsFromStoreUpdate,
            notifyNestedSubs,
            reactListener
          );
        };
        return subscribe;
      }, [subscription]);
      useIsomorphicLayoutEffectWithArgs(captureWrapperProps, [
        lastWrapperProps,
        lastChildProps,
        renderIsScheduled,
        wrapperProps,
        childPropsFromStoreUpdate,
        notifyNestedSubs
      ]);
      let actualChildProps;
      try {
        actualChildProps = React.useSyncExternalStore(
          // TODO We're passing through a big wrapper that does a bunch of extra side effects besides subscribing
          subscribeForReact,
          // TODO This is incredibly hacky. We've already processed the store update and calculated new child props,
          // TODO and we're just passing that through so it triggers a re-render for us rather than relying on `uSES`.
          actualChildPropsSelector,
          getServerState ? () => childPropsSelector(getServerState(), wrapperProps) : actualChildPropsSelector
        );
      } catch (err) {
        if (latestSubscriptionCallbackError.current) {
          ;
          err.message += `
The error may be correlated with this previous error:
${latestSubscriptionCallbackError.current.stack}

`;
        }
        throw err;
      }
      useIsomorphicLayoutEffect(() => {
        latestSubscriptionCallbackError.current = void 0;
        childPropsFromStoreUpdate.current = void 0;
        lastChildProps.current = actualChildProps;
      });
      const renderedWrappedComponent = React.useMemo(() => {
        return (
          // @ts-ignore
          /* @__PURE__ */ React.createElement(
            WrappedComponent,
            {
              ...actualChildProps,
              ref: reactReduxForwardedRef
            }
          )
        );
      }, [reactReduxForwardedRef, WrappedComponent, actualChildProps]);
      const renderedChild = React.useMemo(() => {
        if (shouldHandleStateChanges) {
          return /* @__PURE__ */ React.createElement(ContextToUse.Provider, { value: overriddenContextValue }, renderedWrappedComponent);
        }
        return renderedWrappedComponent;
      }, [ContextToUse, renderedWrappedComponent, overriddenContextValue]);
      return renderedChild;
    }
    const _Connect = React.memo(ConnectFunction);
    const Connect = _Connect;
    Connect.WrappedComponent = WrappedComponent;
    Connect.displayName = ConnectFunction.displayName = displayName;
    if (forwardRef) {
      const _forwarded = React.forwardRef(
        function forwardConnectRef(props, ref) {
          return /* @__PURE__ */ React.createElement(Connect, { ...props, reactReduxForwardedRef: ref });
        }
      );
      const forwarded = _forwarded;
      forwarded.displayName = displayName;
      forwarded.WrappedComponent = WrappedComponent;
      return /* @__PURE__ */ hoistNonReactStatics(forwarded, WrappedComponent);
    }
    return /* @__PURE__ */ hoistNonReactStatics(Connect, WrappedComponent);
  };
  return wrapWithConnect;
}
var connect_default = connect;

// src/components/Provider.tsx
function Provider({
  store,
  context,
  children,
  serverState,
  stabilityCheck = "once",
  identityFunctionCheck = "once"
}) {
  const contextValue = React.useMemo(() => {
    const subscription = createSubscription(store);
    return {
      store,
      subscription,
      getServerState: serverState ? () => serverState : void 0,
      stabilityCheck,
      identityFunctionCheck
    };
  }, [store, serverState, stabilityCheck, identityFunctionCheck]);
  const previousState = React.useMemo(() => store.getState(), [store]);
  useIsomorphicLayoutEffect(() => {
    const { subscription } = contextValue;
    subscription.onStateChange = subscription.notifyNestedSubs;
    subscription.trySubscribe();
    if (previousState !== store.getState()) {
      subscription.notifyNestedSubs();
    }
    return () => {
      subscription.tryUnsubscribe();
      subscription.onStateChange = void 0;
    };
  }, [contextValue, previousState]);
  const Context = context || ReactReduxContext;
  return /* @__PURE__ */ React.createElement(Context.Provider, { value: contextValue }, children);
}
var Provider_default = Provider;

// src/hooks/useReduxContext.ts
function createReduxContextHook(context = ReactReduxContext) {
  return function useReduxContext2() {
    const contextValue = React.useContext(context);
    if (process.env.NODE_ENV !== "production" && !contextValue) {
      throw new Error(
        "could not find react-redux context value; please ensure the component is wrapped in a <Provider>"
      );
    }
    return contextValue;
  };
}
var useReduxContext = /* @__PURE__ */ createReduxContextHook();

// src/hooks/useStore.ts
function createStoreHook(context = ReactReduxContext) {
  const useReduxContext2 = context === ReactReduxContext ? useReduxContext : (
    // @ts-ignore
    createReduxContextHook(context)
  );
  const useStore2 = () => {
    const { store } = useReduxContext2();
    return store;
  };
  Object.assign(useStore2, {
    withTypes: () => useStore2
  });
  return useStore2;
}
var useStore = /* @__PURE__ */ createStoreHook();

// src/hooks/useDispatch.ts
function createDispatchHook(context = ReactReduxContext) {
  const useStore2 = context === ReactReduxContext ? useStore : createStoreHook(context);
  const useDispatch2 = () => {
    const store = useStore2();
    return store.dispatch;
  };
  Object.assign(useDispatch2, {
    withTypes: () => useDispatch2
  });
  return useDispatch2;
}
var useDispatch = /* @__PURE__ */ createDispatchHook();

// src/hooks/useSelector.ts
import { useSyncExternalStoreWithSelector } from "use-sync-external-store/with-selector.js";
var refEquality = (a, b) => a === b;
function createSelectorHook(context = ReactReduxContext) {
  const useReduxContext2 = context === ReactReduxContext ? useReduxContext : createReduxContextHook(context);
  const useSelector2 = (selector, equalityFnOrOptions = {}) => {
    const { equalityFn = refEquality } = typeof equalityFnOrOptions === "function" ? { equalityFn: equalityFnOrOptions } : equalityFnOrOptions;
    if (process.env.NODE_ENV !== "production") {
      if (!selector) {
        throw new Error(`You must pass a selector to useSelector`);
      }
      if (typeof selector !== "function") {
        throw new Error(`You must pass a function as a selector to useSelector`);
      }
      if (typeof equalityFn !== "function") {
        throw new Error(
          `You must pass a function as an equality function to useSelector`
        );
      }
    }
    const reduxContext = useReduxContext2();
    const { store, subscription, getServerState } = reduxContext;
    const firstRun = React.useRef(true);
    const wrappedSelector = React.useCallback(
      {
        [selector.name](state) {
          const selected = selector(state);
          if (process.env.NODE_ENV !== "production") {
            const { devModeChecks = {} } = typeof equalityFnOrOptions === "function" ? {} : equalityFnOrOptions;
            const { identityFunctionCheck, stabilityCheck } = reduxContext;
            const {
              identityFunctionCheck: finalIdentityFunctionCheck,
              stabilityCheck: finalStabilityCheck
            } = {
              stabilityCheck,
              identityFunctionCheck,
              ...devModeChecks
            };
            if (finalStabilityCheck === "always" || finalStabilityCheck === "once" && firstRun.current) {
              const toCompare = selector(state);
              if (!equalityFn(selected, toCompare)) {
                let stack = void 0;
                try {
                  throw new Error();
                } catch (e) {
                  ;
                  ({ stack } = e);
                }
                console.warn(
                  "Selector " + (selector.name || "unknown") + " returned a different result when called with the same parameters. This can lead to unnecessary rerenders.\nSelectors that return a new reference (such as an object or an array) should be memoized: https://redux.js.org/usage/deriving-data-selectors#optimizing-selectors-with-memoization",
                  {
                    state,
                    selected,
                    selected2: toCompare,
                    stack
                  }
                );
              }
            }
            if (finalIdentityFunctionCheck === "always" || finalIdentityFunctionCheck === "once" && firstRun.current) {
              if (selected === state) {
                let stack = void 0;
                try {
                  throw new Error();
                } catch (e) {
                  ;
                  ({ stack } = e);
                }
                console.warn(
                  "Selector " + (selector.name || "unknown") + " returned the root state when called. This can lead to unnecessary rerenders.\nSelectors that return the entire state are almost certainly a mistake, as they will cause a rerender whenever *anything* in state changes.",
                  { stack }
                );
              }
            }
            if (firstRun.current) firstRun.current = false;
          }
          return selected;
        }
      }[selector.name],
      [selector]
    );
    const selectedState = useSyncExternalStoreWithSelector(
      subscription.addNestedSub,
      store.getState,
      getServerState || store.getState,
      wrappedSelector,
      equalityFn
    );
    React.useDebugValue(selectedState);
    return selectedState;
  };
  Object.assign(useSelector2, {
    withTypes: () => useSelector2
  });
  return useSelector2;
}
var useSelector = /* @__PURE__ */ createSelectorHook();

// src/exports.ts
var batch = defaultNoopBatch;
export {
  Provider_default as Provider,
  ReactReduxContext,
  batch,
  connect_default as connect,
  createDispatchHook,
  createSelectorHook,
  createStoreHook,
  shallowEqual,
  useDispatch,
  useSelector,
  useStore
};
//# sourceMappingURL=react-redux.mjs.map

@markerikson
Copy link
Contributor

yeah, the default thing was basically a hacky version of the defaultInterop(someModule) pattern that these bundling tools spit out :)

@aryaemami59
Copy link
Contributor Author

Other changes to consider:

  1. Not sure if we want to keep the "./alternate-renderers" entry point, tbh I'm not sure what it's purpose is at the moment, I'm assuming it was something we had from before and we've kept it for backwards-compatibility and/or to prevent breakage.
  2. I did remove initializeConnect and initializeUseSelector. I understand why we had them, and from what I see now in our build artifacts, I'm not sure if the order of initialization is something that applies anymore since we're not relying on module initialization order.
  3. I haven't looked at the bundle sizes for CJS and other build artifacts yet, but it might be worth having a separate development and production entry points, I'm going to look into this some more and see if it might be worth considering.

@markerikson
Copy link
Contributor

alternate-renderers existed because we've imported unstable_batchedUpdates from ReactDOM and React Native. But, alternate reconciler implementations like React-Three-Fiber and Ink might not export that and we didn't know to import from them anyway, so if you were using React-Redux with those reconcilers, you'd want to alias to "react-redux/alternate-renderers" to let it keep working okay.

With RR v9, we now expect to work with React 18+, which always batches. So, we no longer even use unstable_batchedUpdates. But, it didn't occur to me until after 9.0 was out that we could drop all that. Removing the /alternate-renderers entry point would be a breaking change, so even if it's useless now, it has to stick around through this 9.x major.

@aryaemami59
Copy link
Contributor Author

@markerikson ahh I see, that's not a problem at all, maybe if we were to do a major (perhaps for React 19 though I highly doubt it'll be necessary), we can remove them then. Also not sure if you saw I did remove initializeUseSelector and initializeConnect, that's going to be okay right? So far it's working fine.

@markerikson
Copy link
Contributor

I honestly don't even remember why we had that there :)

@aryaemami59 aryaemami59 marked this pull request as ready for review July 12, 2024 21:06
@aryaemami59 aryaemami59 force-pushed the improve-treeshakeability branch 2 times, most recently from 31c0bc7 to 1bc8d62 Compare July 25, 2024 10:33
@markerikson
Copy link
Contributor

This one will be trickier to review than the other repos, so I'll come back to this when I have more time to look at it.

@aryaemami59 aryaemami59 force-pushed the improve-treeshakeability branch 2 times, most recently from 65b4e08 to 658c5e4 Compare August 13, 2024 07:01
@aryaemami59 aryaemami59 force-pushed the improve-treeshakeability branch 13 times, most recently from 903d6f2 to fff09d3 Compare September 17, 2024 12:41
- `env` is the same thing as `define` with `JSON.stringify`.
- Currently there is no difference between emitting type definitions with `cjs` or `esm` format, the only difference is the file extension. So we emit the type definitions with a `cjs` format to preserve the previous `.d.ts` extension as opposed to the new `.d.mts` extension.
- The conditional import of the `React` namespace seems to create a lot of side effects, so for now we'll de-duplicate the `React` namespace imports by funneling them through `src/utils/react.ts`.
- This was mainly done to stay consistent with other Redux repos.
- This was done to ensure that the remaining traces of dev mode checks will not be present in the `'production'` build.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants