{"id":19873693,"url":"https://github.com/mediv0/v-bucket","last_synced_at":"2025-07-21T03:03:00.145Z","repository":{"id":37544344,"uuid":"298265037","full_name":"mediv0/v-bucket","owner":"mediv0","description":"📦 Fast, Simple, and Lightweight State Manager for Vue 3.0 built with composition API, inspired by Vuex.","archived":false,"fork":false,"pushed_at":"2024-08-19T04:47:49.000Z","size":540,"stargazers_count":43,"open_issues_count":0,"forks_count":4,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-04-09T23:50:51.443Z","etag":null,"topics":["bucket","component","composition","composition-api","getters","javascript","javascript-library","js","mutations","plugin","plugin-hooks","vue","vue-component","vue3","vue3-composition-api","vuejs","vuex"],"latest_commit_sha":null,"homepage":"https://codesandbox.io/s/dank-waterfall-mrfzq","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mediv0.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":".github/contributing.md","funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-09-24T11:59:40.000Z","updated_at":"2024-10-31T08:22:49.000Z","dependencies_parsed_at":"2024-08-19T05:45:48.427Z","dependency_job_id":"7736689c-3672-43d9-ae1f-f93222aef524","html_url":"https://github.com/mediv0/v-bucket","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/mediv0/v-bucket","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mediv0%2Fv-bucket","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mediv0%2Fv-bucket/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mediv0%2Fv-bucket/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mediv0%2Fv-bucket/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mediv0","download_url":"https://codeload.github.com/mediv0/v-bucket/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mediv0%2Fv-bucket/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":266231762,"owners_count":23896473,"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":["bucket","component","composition","composition-api","getters","javascript","javascript-library","js","mutations","plugin","plugin-hooks","vue","vue-component","vue3","vue3-composition-api","vuejs","vuex"],"created_at":"2024-11-12T16:19:37.184Z","updated_at":"2025-07-21T03:03:00.121Z","avatar_url":"https://github.com/mediv0.png","language":"JavaScript","funding_links":[],"categories":["Components \u0026 Libraries","Utilities [🔝](#readme)"],"sub_categories":["Utilities"],"readme":"# v-bucket [![codecov](https://codecov.io/gh/mediv0/v-bucket/branch/master/graph/badge.svg)](https://codecov.io/gh/mediv0/v-bucket) [![Code Grade](https://www.code-inspector.com/project/13923/status/svg)](https://www.code-inspector.com/project/13923/status/svg) [![Maintainability](https://api.codeclimate.com/v1/badges/1b4471bc8538eb0a2e67/maintainability)](https://codeclimate.com/github/mediv0/v-bucket/maintainability) [![License](https://img.shields.io/github/license/mediv0/v-bucket)](https://img.shields.io/github/license/mediv0/v-bucket) [![Last updar](https://img.shields.io/github/release-date/mediv0/v-bucket)](https://img.shields.io/github/release-date/mediv0/v-bucket)\n\n**NPM STATUS:** [![npm](https://img.shields.io/npm/v/@mediv0/v-bucket?style=plastic)](https://img.shields.io/npm/v/@mediv0/v-bucket?style=plastic) [![size](https://img.shields.io/bundlephobia/minzip/@mediv0/v-bucket)](https://img.shields.io/bundlephobia/minzip/@mediv0/v-bucket) [![download](https://img.shields.io/npm/dt/@mediv0/v-bucket)](https://img.shields.io/npm/dt/@mediv0/v-bucket)\n\n\u003e 📦 Fast, Simple, and Lightweight State Management for Vue 3.0 built with composition API, inspired by Vuex.\n\n\u003cp align=\"center\"\u003e\n  \u003cimg width=\"500px\" src=\"https://i.imgur.com/6wQ0GRr.png\"\u003e\n\u003c/p\u003e\n\n## Table of Contents\n\n### Main features\n\n-   [installation](#installation)\n-   [usage](#usage)\n-   [using with composition api](\"#using-with-composition-api\")\n-   [using with option api](\"#using-with-option-api\")\n-   [states](#states)\n-   [mutations](#mutations)\n-   [getters](#getters)\n-   [actions](#actions)\n-   [modules](#modules)\n\n### Access modules\n\n-   [how to access module states](#how-to-access-module-states)\n-   [how to access module getters](#how-to-access-module-getters)\n-   [how to access module mutations](#how-to-access-module-mutations)\n-   [how to access module actions](#how-to-access-module-actions)\n\n### Advanced\n\n-   [plugins](#plugins)\n-   [plugin hooks](#plugin-hooks)\n\n## Examples\n\n-   [CodeSandbox](https://codesandbox.io/s/dank-waterfall-mrfzq)\n-   [Counter](https://github.com/mediv0/v-bucket/blob/master/examples/components/counter.vue)\n-   [Shopping Cart](https://github.com/mediv0/v-bucket/blob/master/examples/components/shop.vue)\n\nRunning the examples:\n\n```bash\n$ npm run dev\n$ yarn dev\n```\n\n## Running tests\n\n```bash\n$ npm run test\n$ yarn test\n```\n\n## installation\n\ninstall this package from NPM:\n\n```bash\n$ npm install @mediv0/v-bucket\n```\n\nor yarn:\n\n```bash\n$ yarn add @mediv0/v-bucket\n```\n\n## usage\n\nfirst you need to create your bucket.\ncreate an index.js file, then import createBucket from v-bucket to start creating your store, like this:\n\n```javascript\nimport { createBucket } from \"@mediv0/v-bucket\";\n\nconst bucket = createBucket({\n    states: {\n        // your states here\n    },\n    mutations: {\n        // your mutations here\n    },\n    getters: {\n        // your getters here\n    },\n    modules: {\n        // your modules here\n    }\n});\nexport default bucket;\n```\n\nthen import it in your app entry point, main.js like this:\n\n```javascript\nimport { createApp } from \"vue\";\nimport App from \"./dev.vue\";\n// importing your bucket\nimport bucket from \"./bucket/index\";\n\ncreateApp(App)\n    .use(bucket)\n    .mount(\"#app\");\n```\n\n## using with composition api\n\nfor using v-bucket inside the setup() function you need to import useBucket first. like this:\n\n```javascript\n\u003cscript\u003e\nimport { useBucket } from \"@mediv0/v-bucket\"\nexport default {\n    setup() {\n        // get access to the v-bucket\n        const bucket = useBucket();\n\n        // ...\n\n        return {\n            // ....\n        };\n    }\n};\n\u003c/script\u003e\n```\n\n## using with option api\n\nlike vue 2.X apps you can access v-bucket on the vue instance outside of the setup() function. like this:\n\n```javascript\n\u003cscript\u003e\nexport default {\n    mounted() {\n        // accessing bucket on this\n        this.$bucket\n\n        // ...\n    },\n    methods: {\n      click() {\n        this.$bucket.commit(\"SET_ID\", this.id);\n\n        // ...\n      }\n    }\n};\n\u003c/script\u003e\n```\n\n_you only import useBucket when you want to use it inside setup() function_\n\n# Note\nin case of error \n` Named export 'createBucket' not found. The requested module '@mediv0+v-bucket@1.1.2_vue@3.4.35/node_modules/@mediv0/v-bucket/dist/v-bucket.cjs.js' is a CommonJS module, which may not support all module.exports as named exports.\nCommonJS modules can always be imported via the default export, `\n\nYou can import createBucket from esm module provided in the build `@mediv0/v-bucket/dist/v-bucket.esm-browser.prod` or just import it with default name then destruct `createBucket` function\n```js\n\nimport vBucket from \"@mediv0/v-bucket\";\nvBucket.createBucket({ ... })\n\n```\n\n\n## states\n\nthis is a single object contains all your application states.\n\naccessing states:\n\n```javascript\n mounted() {\n    // accessing id state in the root level\n    this.$bucket.state.id\n\n    // ...\n\n    // accessing name state in the nested tree\n    this.$bucket.state.module1.name\n },\n```\n\ndeclare states inside your bucket (index.js):\n\n```javascript\nimport { createBucket } from \"@mediv0/v-bucket\";\n\nconst bucket = createBucket({\n    states: {\n        id: 1,\n        name: \"mahdi\",\n        phone: 120304\n    },\n    mutations: {\n        // your mutations here\n    },\n    getters: {\n        // your getters here\n    },\n    modules: {\n        // your modules here\n    }\n});\nexport default bucket;\n```\n\n**NOTE:** states object will be reactive by default. that means they will react to changes and update based on it.\n\n**NOTE:** it's better to use mutations or getters to access states.\n\n## mutations\n\nuse mutations when you need to change a state value, all mutations will take 2 parameter:\n\n-   state\n-   payload\n\n```javascript\nconst bucket = createBucket({\n    mutations: {\n        SET_ID(state, payload)\n    },\n});\n```\n\nwith **state**, you can have access to states object and change its value by passing **payload**.\n\n**NOTE:** payload is optional.\n\n```javascript\nconst bucket = createBucket({\n    states: {\n      id: 0,\n      count: 0\n    }\n    mutations: {\n        SET_ID(state, payload) {\n          // changing id value\n          state.id = payload\n        }\n        COUNT_UP(state) {\n          // without payload\n          state.count++;\n        }\n    },\n});\n```\n\nyou can't access mutations directly. you have to call them with commit method. like this:\n\n```javascript\nmethods: {\n   click() {\n\n     this.$bucket.commit(\"SET_ID\", 5);\n     this.$bucket.state.id // must be 5 now!\n\n     // ...\n\n     this.$bucket.commit(\"SET_ID\"); // calling without a payload\n\n   }\n }\n```\n\n## getters\n\nyou can use getters to access states and their values. getters are like Vue computed methods, they will cache the state and return it only when the state value change.\n\n```javascript\nconst bucket = createBucket({\n    states: {\n      id: 0,\n      name: \"mahdi\",\n      phone: 893729837\n    }\n    getters: {\n      GET_ID(state) {\n        return state.id\n      }\n    },\n});\n```\n\nall getters will take 1 parameter:\n\n-   state (using to access states object)\n\nusing it in your vue app:\n\n```javascript\nmethods: {\n   click() {\n\n     this.$bucket.getters[\"GET_ID\"] // will return id state\n\n     // ...\n   }\n }\n```\n\n## actions\n\nActions are like mutations. the difference is:\n\n-   They can handle asynchronous operations\n-   Instead of mutating the state, actions commit mutations.\n\n```javascript\nconst bucket = createBucket({\n    states: {\n      count: 0\n    }\n    mutations: {\n      increment(state) {\n        state.count++\n      }\n    },\n    actions: {\n      increment(context) {\n        context.commit(\"increment\");\n      }\n\n      // or using argument destructuring to simplify the code.\n      anotherAction({ commit }) {\n        // do some action!\n        commit(\"someMutation\");\n      }\n    }\n});\n```\n\nalso you can call other actions with context.dispatch. like this:\n\n```javascript\nconst bucket = createBucket({\n    actions: {\n      actionOne(context) {\n        context.commit(\"someMutation\");\n      }\n      actionTwo(context) {\n        context.dispatch(\"actionOne\"); // dispatching actionOne from another action!\n      }\n    }\n});\n```\n\nalso you can't access actions directly. you have to call them with dispatch method. like this:\n\n```javascript\nmethods: {\n   click() {\n\n     this.$bucket.dispatch(\"increment\") // will call increment action\n\n     // ...\n\n   }\n }\n```\n\n**_the context parameter will return root instance of our bucket. this is useful when working with modules._**\n\n## modules\n\nfrom vuex docs:\n\n-   _Due to using a single state tree, all states of our application are contained inside one big object. However, as our application grows in scale, the store can get really bloated. To help with that, Vuex allows us to divide our store into **modules**._\n\n```javascript\nconst moduleA = {\n  states: { ... },\n  mutations: { ... },\n  actions: { ... },\n  modules: { ... }\n}\n\nconst moduleB = {\n  states: { ... },\n  mutations: { ... },\n  actions: { ... },\n  modules: { ... }\n}\n\nconst bucket = createBucket({\n  modules: {\n    // register modules\n    moduleA,\n    moduleB\n  }\n});\n\nbucket.state.moduleA // `moduleA`'s state\nbucket.state.moduleB // `moduleB`'s state\n```\n\n**every modules also can have their own states, mutations, actions or even modules**\n\n## how to access module states\n\nall modules will be installed under the root module. so by accessing the root state you can also have access to its children. like this:\n\n```javascript\nmethods: {\n   click() {\n\n     this.$bucket.state.moduleA.name // `moduleA`'s name state\n     this.$bucket.state.moduleB.id // `moduleB`'s id state\n\n     // ...\n   }\n }\n```\n\n## how to access module getters\n\nif you remember we used bracket notation to access getters, you can access your module's getter by defining its path. like this:\n\n```javascript\nmethods: {\n   click() {\n\n     this.$bucket.getters[\"moduleA/get_id\"]; // `moduleA`'s getter\n     this.$bucket.getters[\"moduleB/get_name\"]; // `moduleB`'s name state\n\n     // you can go deep as many levels as you want\n     this.$bucket.getters[\"moduleA/moduleB/moduleC/moduleH/...];\n\n\n     // ...\n   }\n }\n```\n\nthey above code represent something like this:\n\n-root\n\n-----moduleA\n\n-----moduleB\n\n## how to access module mutations\n\nmutations are like getters, you can access your module's mutation by defining its path. like this:\n\n```javascript\nmethods: {\n   click() {\n\n     this.$bucket.commit(\"moduleA/set_id\"); // we can access mutations by commit()\n     this.$bucket.commit(\"moduleB/set_name\"); // we can access mutations by commit()\n\n     // ...\n   }\n }\n```\n\n## how to access module actions\n\nactions are like getters, you can access your module's actions by defining its path. like this:\n\n```javascript\nmethods: {\n   click() {\n\n     this.$bucket.dispatch(\"moduleA/set_id\"); // we can access mutations by dispatch()\n     this.$bucket.dispatch(\"moduleB/set_name\"); // we can access mutations by dispatch()\n\n     // ...\n   }\n }\n```\n\nsometimes you need to access another module's mutation or action within the current module\n\nsince the context parameter refer to the root module, you can access all of your modules by defining their path. like this:\n\n```javascript\n// inside module a\nconst moduleA = {\n  actions: {\n    commitModuleB(context) {\n      context.commit(\"moduleB/set_name\"); // commiting in module b from module a\n    }\n    dispatchModuleB(context) {\n      context.dispatch(\"moduleB/request\"); // dispatching in module b from module a\n    }\n\n    dispatchRoot(context) {\n      context.dispatch(\"rootMutation\") //  dispatching in root from module a\n    }\n  }\n};\n\n```\n\n**NOTE:** if you want to access a module from another module like example, you need to define your paths from root\n\n## plugins\n\nv-bucket store accept the plugins option that exposes hooks for each mutation and actions. plugins will allow you to extend the functionality of v-bucket\n\na hello world plugin\n\n```javascript\nconst helloWorld = () =\u003e {\n    // called when the store is initialized\n    console.log(\"hello world\");\n    return bucket =\u003e {\n        // access bucket store\n    };\n};\n\nexport const bucket = createBucket({\n    // other options\n    // ...\n    plugins: [helloWorld()]\n});\n```\n\nthe function that has the responsibility to be a plugin, need to return another function.\nv-bucket will use that function to expose the root module and its hooks\n\n\n## plugin hooks\n\nthere are two hooks available:\n\n#### bucket.onMutation(callback(mutation))\n\nthis function will be called after every mutation.\nalso, it will return information about the mutation that has been fired.\n\nthis information contains: name, module and full path of that mutation.\n\n#### bucket.onAction(callback(action))\n\nthis function will be called after every action.\nalso, it will return information about the action that has been fired.\n\nthis information contains: name, module and full path of that action.\n\n**usage:**\n\n```javascript\nconst myPlugin = socket =\u003e {\n    return bucket =\u003e {\n        socket.on(\"data\", data =\u003e {\n            store.commit(\"receiveData\", data);\n        });\n        store.onMutation(mutation =\u003e {\n            if ((mutation.name = \"UPDATE_DATA\")) {\n                socket.emit(\"update\", mutation.payload);\n            }\n        });\n    };\n};\n```\n\nif you want use Class syntaxt, no worries! do something like this:\n\n```javascript\nClass Snapshot {\n  // other methods and options\n  // ...\n  constructor() {\n    this.snapshots = [];\n  }\n\n  plugin() {\n    return bucket =\u003e {\n      bucket.onMutation(mutation =\u003e {\n        if (mutation.name = \"UPDATE_SNAPSHOT\") {\n          this.snapshots.push(mutation.payload);\n        }\n      })\n    }\n  }\n}\n```\n\neasy right?\n\nand use it like this in your store:\n\n```javascript\nexport const bucket = createBucket({\n    // other options\n    // ...\n    plugins: [new Snapshot().plugin()]\n});\n```\n\nSince you have access to the bucket root module in the plugins, you also able to commit, dispatch and use getters.\n\n## Contribution\n\nPlease make sure to read the [Contributing Guide](https://github.com/mediv0/v-bucket/blob/master/.github/contributing.md) before making a pull request.\n\n**feel free to request new features!**\n\n## License\n\n[MIT](http://opensource.org/licenses/MIT)\n\n## Todo\n\n-   [ ] mapGetters\n-   [ ] mapActions\n-   [ ] optimization and refactoring\n-   and more....\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmediv0%2Fv-bucket","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmediv0%2Fv-bucket","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmediv0%2Fv-bucket/lists"}