Front-End-Resort / relite

A redux-like library for managing state with simpler api.
MIT License
2 stars 1 forks source link

Refactor with immer #3

Open tqma113 opened 2 years ago

tqma113 commented 2 years ago

Example: https://gist.github.com/tqma113/8d3935f5591549869d8d0799c0a6002c cc @Lucifier129

Lucifier129 commented 2 years ago

Does this keep compatible with the current implementation?

The benefit about this refactor is for mutable-style or something more?

tqma113 commented 2 years ago
Lucifier129 commented 2 years ago

Wow, it looks promising.

But due to the 16.2kB minified of immer, it should not be a minor update for relite. Since almost all relite app was written in immutable style, they may already use an old version of immer.

immer can be used in an opt-in way for current version of relite. Show below:

const setCount = (state, newCount) => {
  return produce(state, draft => {
    draft.count = newCount
  })
}

// even better if we define an help function
const createImmerAction = (immerAction) => {
  return (state, payload) => {
    return produce(state, draft => {
      immerAction(draft, payload)
    })
  }
}
const setCount = createImmerAction((state, newCount) => {
  state.count = newCount
})

So the benefit of immer can be decoupled from relite itself.

It's no doubt that built-in support for immer may has the better DX, but it's too late for the users of relite.

Maybe moving this refactor to a new package such as immer-relite will be good.

tqma113 commented 2 years ago

Looks good. I perfer immer-relite.

tqma113 commented 2 years ago

https://github.com/tqma113/immer-relite

Repo Fork from https://github.com/Front-End-Resort/relite does not has action, so I create a new one.

Lucifier129 commented 2 years ago

redux-devtools v3.0.0 has breaking change. The adapter of immer-relite will crash in v3.0.0.

react-imvc was removed the adapter of redux-devtools.

tqma113 commented 2 years ago

I find it and looking for the resolution. It worked well two days ago. :expressionless:

tqma113 commented 2 years ago

I find the window.__REDUX_DEVTOOLS_EXTENSION__.send api work well.

import type { Store, Actions } from "./index";

declare global {
  interface Window {
    __REDUX_DEVTOOLS_EXTENSION__: any;
  }
}

export const attachDevTool = <S extends object, AS extends Actions<S>>(
  store: Store<S, AS>
): void => {
  if (process.env.NODE_ENV === "production") {
    return;
  }

  if (typeof window === "undefined" || !window.__REDUX_DEVTOOLS_EXTENSION__ || !window.__REDUX_DEVTOOLS_EXTENSION__.send) {
    return;
  }

  const sendMessage = window.__REDUX_DEVTOOLS_EXTENSION__.send

  const config = {
    name: window.location.pathname + window.location.search,
    actionsWhitelist: Object.keys(store.actions),
  };

  store.subscribe((data) => {
    sendMessage({
      action: {
        type: data.actionType,
        payload: data.actionPayload
      },
      timestamp: data.end.getTime() - data.start.getTime(),
    }, data.currentState, config)
  });
};
Lucifier129 commented 2 years ago

Great. It still missing the backward message-passing. This API may help.