{"id":23072478,"url":"https://github.com/doches/generator-tfountain-redux-reducer","last_synced_at":"2025-04-03T10:43:42.016Z","repository":{"id":41696127,"uuid":"247051802","full_name":"doches/generator-tfountain-redux-reducer","owner":"doches","description":"A highly opinionated Yeoman generator for redux reducers","archived":false,"fork":false,"pushed_at":"2022-12-05T13:14:49.000Z","size":277,"stargazers_count":0,"open_issues_count":7,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-04-24T12:25:33.211Z","etag":null,"topics":["hacktoberfest","redux-reducers","yeoman-generator"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/doches.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-03-13T11:04:28.000Z","updated_at":"2020-10-06T07:51:49.000Z","dependencies_parsed_at":"2023-01-23T02:10:15.630Z","dependency_job_id":null,"html_url":"https://github.com/doches/generator-tfountain-redux-reducer","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/doches%2Fgenerator-tfountain-redux-reducer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/doches%2Fgenerator-tfountain-redux-reducer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/doches%2Fgenerator-tfountain-redux-reducer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/doches%2Fgenerator-tfountain-redux-reducer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/doches","download_url":"https://codeload.github.com/doches/generator-tfountain-redux-reducer/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246989505,"owners_count":20865305,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["hacktoberfest","redux-reducers","yeoman-generator"],"created_at":"2024-12-16T07:19:56.105Z","updated_at":"2025-04-03T10:43:41.997Z","avatar_url":"https://github.com/doches.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Generator TFountain Redux Reducer\n\nA strongly-opinionated [Yeoman](https://yeoman.io) generator for scaffolding out a redux reducer (and associated state slice \u0026 api calls)\nbased on the way that [@doches](https://github.com/doches) likes to set things up. Probably not useful for you, but _tremendously_ useful for him.\n\n### Usage\n\nInstall Yeoman via yarn, or npm, or whatever JS package manager is hot this week:\n\n    $ yarn global add yo\n\nOnce you've got Yeoman set up, install this generator:\n\n    $ yarn global add generator-tfountain-redux-reducer\n\nMove into the directory in your project where you want to create the new redux slice, and invoke Yeoman:\n\n    $ cd awesome-project/src/state\n    $ yo tfountain-redux-reducer\n\nTell Yeoman about your type name for this reducer, then sit back and bask in the glory of a lovely autogenerated piece of boilerplate _that you didn't have to write_. Finish your application. Move on with your life. Maybe write that novel you've always been dreaming about, or start learning the drums.\n\nGo on. Live a little.\n\n### Output\n\nBy way of example, the generator will ask you for singluar (e.g. \"item\") and plural (e.g. \"items\") type names, then produce a file like this:\n\n```typescript\nimport { Dispatch } from \"redux\";\nimport { baseURL, headers } from \"./api\";\n\nexport interface IItemsState {\n  fetchPending: boolean;\n  fetched: boolean;\n  updatePending: boolean;\n\n  items: IItem[];\n}\n\nexport const DEFAULT_ITEMS_STATE: IItemsState = {\n  fetchPending: false,\n  fetched: false,\n  updatePending: false,\n  items: [],\n}\n\nexport const SET_FETCH_PENDING = \"@@items/SET_FETCH_PENDING\";\nexport const SET_UPDATE_PENDING = \"@@items/SET_UPDATE_PENDING\";\nexport const SET_ITEMS = \"@@items/SET_ITEMS\";\nexport const ADD_ITEM = \"@@items/ADD_ITEM\";\nexport const REMOVE_ITEM = \"@@items/REMOVE_ITEM\";\nexport const UPDATE_ITEM = \"@@items/UPDATE_ITEM\";\n\nexport function setFetchPending(pending: boolean) {\n  return {\n      type: SET_FETCH_PENDING,\n      pending,\n  };\n}\n\nexport function setUpdatePending(pending: boolean) {\n  return {\n      type: SET_UPDATE_PENDING,\n      pending,\n  };\n}\n\nexport function setItems(items: IItem[]) {\n  return {\n      type: SET_ITEMS,\n      items,\n  };\n}\n\nexport function addItem(item: IItem) {\n  return {\n      type: ADD_ITEM,\n      item,\n  };\n}\n\nexport function removeItem(itemId: number) {\n  return {\n      type: REMOVE_ITEM,\n      id: itemId,\n  };\n}\n\nfunction replaceItem(item: IItem) {\n  return {\n      type: UPDATE_ITEM,\n      item,\n  };\n}\n\nexport function createItem(item: IItem) {\n  return (dispatch: Dispatch\u003cany\u003e) =\u003e {\n      dispatch(setUpdatePending(true));\n      return fetch(`${baseURL}items/create`, {\n          headers,\n          method: \"POST\",\n          body: JSON.stringify(item),\n      })\n      .then((response: Response) =\u003e {\n          if (!response.ok) {\n              throw new Error();\n          }\n          return response.json();\n      })\n      .then((created: IItem) =\u003e {\n        dispatch(addItem(created));\n      })\n      .catch((error: any) =\u003e {\n          console.error(error);\n      })\n      .finally(() =\u003e {\n          dispatch(setUpdatePending(false));\n      });\n  }\n}\n\nexport function listItems() {\n  return (dispatch: Dispatch\u003cany\u003e) =\u003e {\n      dispatch(setFetchPending(true));\n      return fetch(`${baseURL}items/list`, {\n          headers,\n          method: \"GET\",\n      })\n      .then((response: Response) =\u003e {\n          if (!response.ok) {\n              throw new Error();\n          }\n          return response.json();\n      })\n      .then((items: IItem[]) =\u003e {\n        dispatch(setItems(items));\n      })\n      .catch((error: any) =\u003e {\n          console.error(error);\n      })\n      .finally(() =\u003e {\n          dispatch(setFetchPending(false));\n      });\n  }\n}\n\nexport function updateItem(item: IItem) {\n  return (dispatch: Dispatch\u003cany\u003e) =\u003e {\n      dispatch(setUpdatePending(true));\n      return fetch(`${baseURL}items/update`, {\n          headers,\n          method: \"POST\",\n          body: JSON.stringify(item),\n      })\n      .then((response: Response) =\u003e {\n          if (!response.ok) {\n              throw new Error();\n          }\n\n          dispatch(replaceItem(item));\n      })\n      .catch((error: any) =\u003e {\n          console.error(error);\n      })\n      .finally(() =\u003e {\n          dispatch(setUpdatePending(false));\n      });\n  }\n}\n\nexport function deleteItem(itemId: number) {\n  return (dispatch: Dispatch\u003cany\u003e) =\u003e {\n      dispatch(setUpdatePending(true));\n      return fetch(`${baseURL}items/${itemId}/delete`, {\n          headers,\n          method: \"POST\",\n      })\n      .then((response: Response) =\u003e {\n          if (!response.ok) {\n              throw new Error();\n          }\n          dispatch(removeItem(itemId));\n      })\n      .catch((error: any) =\u003e {\n          console.error(error);\n      })\n      .finally(() =\u003e {\n          dispatch(setUpdatePending(false));\n      });\n  }\n}\n\nexport function items(state: IItemsState, action: any) {\n  if (!state) {\n    state = DEFAULT_ITEMS_STATE;\n  }\n\n  switch (action.type) {\n    default: \n      return state;\n    case SET_FETCH_PENDING:\n      return {\n        ...state,\n        fetchPending: action.pending,\n      };\n    case SET_UPDATE_PENDING:\n      return {\n        ...state,\n        updatePending: action.pending,\n    };\n    case SET_ITEMS:\n      return {\n        ...state,\n        fetchPending: false,\n        fetched: true,\n        items: action.items,\n      };\n    case ADD_ITEM:\n      return {\n        ...state,\n        updatePending: false,\n        items: [\n          ...state.items,\n          action.item,\n        ],\n      };\n    case REMOVE_ITEM:\n      return {\n        ...state,\n        updatePending: false,\n        items: state.items.filter((item: IItem) =\u003e item.id != action.item.id),\n      };\n    case UPDATE_ITEM:\n      return {\n        ...state,\n        updatePending: false,\n        items: state.items.map((item: IItem) =\u003e item.id === action.item.id ? action.item : item),\n      };\n  }\n}\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdoches%2Fgenerator-tfountain-redux-reducer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdoches%2Fgenerator-tfountain-redux-reducer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdoches%2Fgenerator-tfountain-redux-reducer/lists"}