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(signal-slice): add signalSlice #135

Merged
merged 7 commits into from
Nov 7, 2023

Conversation

joshuamorony
Copy link
Contributor

This was created in collaboration with Chau, it adds signalSlice which is loosely inspired by the createSlice API from Redux Toolkit. The general idea is that it allows you to declaratively create a "slice" of state. This state will be available as a readonly signal.

The key motivation, and what makes this declarative, is that all the ways for updating this signal are declared upfront with sources and reducers. It is not possible to imperatively update the state.

This PR also makes minor changes to connect in order to expose types that are shared by this utility.

Example using all API features:

  state = signalSlice({
    initialState: this.initialState,
    sources: [this.sources$],
    reducers: {
      add: (state, checklist: AddChecklist) => ({
        checklists: [...state.checklists, this.addIdToChecklist(checklist)],
      }),
      edit: (state, update: EditChecklist) => ({
        checklists: state.checklists.map((checklist) =>
          checklist.id === update.id
            ? { ...checklist, title: update.data.title }
            : checklist
        ),
      }),
      remove: (state, id: RemoveChecklist) => ({
        checklists: state.checklists.filter((checklist) => checklist.id !== id),
      }),
    },
    selectors: (state) => ({
      loadedAndError: () => state().loaded && state().error,
      whatever: () => 'hi',
    }),
  });

Key features:

  • Sources will automatically update signal when they emit
  • Reducers will automatically create actions on the state object that can be called (e.g. this.state.remove(id))
  • Top-level properties of the initial state are automatically exposed as selectors (computeds) on the state object (e.g. this.state.loaded()`)
  • Additional selectors can be supplied which will also be added to the state object

For my own purposes this API is "feature complete" and does everything I need but I'm very open to comments/revisions/improvements.

Copy link

nx-cloud bot commented Nov 7, 2023

☁️ Nx Cloud Report

CI is running/has finished running commands for commit 512eb4d. As they complete they will appear below. Click to see the status, the terminal output, and the build insights.

📂 See all runs for this CI Pipeline Execution


⌛ The following targets are in progress

✅ Successfully ran 2 targets

Sent with 💌 from NxCloud.

Copy link
Collaborator

@nartc nartc left a comment

Choose a reason for hiding this comment

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

Some nits but approved

@nartc
Copy link
Collaborator

nartc commented Nov 7, 2023

@all-contributors please add @joshuamorony for code

Copy link
Contributor

@nartc

I've put up a pull request to add @joshuamorony! 🎉

joshuamorony and others added 2 commits November 7, 2023 19:05
Co-authored-by: Chau Tran <nartc7789@gmail.com>
@nartc nartc merged commit 76fcfad into ngxtension:main Nov 7, 2023
6 checks passed
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