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

feat(core): add politeiagui toolkit #2869

Merged
merged 21 commits into from Nov 30, 2022

Conversation

victorgcramos
Copy link
Member

@victorgcramos victorgcramos commented Oct 25, 2022

This PR adds the new politeiagui core toolkit, which exports the
createSliceService util.

Motivation

After defining some plugins services and their regarded setups for app
routes, I noticed that it's pretty hard to work with our previous setup flow
due to the following reasons:

  1. There are lots of params property names definitions to keep in mind,
    and it's easy to forget some name. Our error handler already gives us some
    good dev feedback, but it's still hard to remember the configuration flow.

  2. If we don't use any util to create slices services, it becomes hard
    to maintain our standards between services configuration for plugins, and
    services consumers.

  3. Setting up a service requires devs to know all services ids in order
    to consume them on app routes. Passing an invalid id as param throws
    an error, but it's still hard to tell which service id is valid or not without
    looking at each service configuration.

  4. Lack of services slice configuration docs.

Solution

The createSliceService util formats our services to include on our plugin
and to use them externally by setting up their services listeners.

Each service is composed by an id, used to identify the service among our
plugins and apps, an onSetup function to be executed when our service is
setup, and an effect that will be executed for each Service Listener.

Example:

Configure slice services:

// myplugin/myslice/services.js
import { createSliceServices } from "@politeiagui/core/toolkit";
import { createAction } from "@reduxjs/toolkit";

const services = createSliceServices({
  name: "my/test",
  services: {
    // `foo` is the service id
    foo: {
      effect: async (state, dispatch, payload) => {
        // Do something here to be executed on listener match
      },
      onSetup: () => {
        // Do something here to be executed when listener is initialized
      },
    },
  },
});

// Action to listen to.
const myAction = createAction("myAction")

export const { pluginServices, setup } = services;

Use on Plugin:

// myplugin/plugin.js
import { pluginServices } from "./myslice/services"

const plugin = pluginSetup({
  name: "playground",
  reducers: [],
  services: pluginServices,
});

Consume services on app route:

// myapp/routes.js
import { setup } from "@politeiagui/myplugin/myslice"
import App from "./app"

const { foo } = setup;

// setup foo without listeners. This return the serviceId, and once it's
// connected to our app, the `onSetup` action will be executed.
const fooWithoutListeners = foo;

// setup foo without any effect customization. This will execute the effect
// using the listened action payload as argument. Works for any Redux Toolkit
// listener action matcher.
const fooWithoutEffectCustomizationType = foo.listenTo({ type: "myAction" });
// or
const fooWithoutEffectCustomizationActionCreator = foo.listenTo({
  actionCreator: myAction
});

// setup foo with custom effect. This allows service's effect parameters
// customization, as well as the addition of a new listener handler.
const fooCustomized = foo
  .listenTo({ type: "myAction" })
  .customizeEffect((effect, { payload }, { dispatch, getState }) => {
    effect(getState(), dispatch, { token: payload });
  });

// Add on route
App.createRoute({
  path: "/",
  setupServices: [
    fooWithoutListeners,
    fooWithoutEffectCustomizationType,
    fooWithoutEffectCustomizationActionCreator,
    fooCustomized
  ]
})

Copy link
Member

@tiagoalvesdulce tiagoalvesdulce left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think the toolkit-playground app should be committed. Also, can you edit your PR to include the motivation to implement the toolkit for documentation? Code LGTM.

@victorgcramos
Copy link
Member Author

@tiagoalvesdulce Nice, I'll remove toolkit playground app. I used it as an example for this PR. Once I add the toolkit on pi app-shell, I'll update the description with the motivation. Thanks for the review 😉

@victorgcramos victorgcramos marked this pull request as ready for review November 21, 2022 20:21
Copy link
Member

@tiagoalvesdulce tiagoalvesdulce left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

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.

None yet

2 participants