Ninja Pumpkin Mutants

    vuex-reflect

    0.1.2 • Public • Published

    Build Status Code coverage Maintenance yes GitHub license Documentation status

    Vuex Reflect

    Overview

    Vuex Reflect is a Vuex plugin that simplifies the configuration and management of data models in an application, providing a simple and declarative API for reflecting an external datasource. Modern web applications can be quite complex, and engineering a data store to reflect data models in your application doesn't need to be left up to interpretation. Abstractions like SQLAlchemy have reduced complexity and augmented developer experience for languages like Python, and this library similarly augments the developer experience associated with managing frontend application data.

    It does this with two main features:

    1. A declarative syntax for defining and configuring data models. This feature provides a) an easy way to connect models to an external API endpoint for CRUD actions, b) utilities for property mutations and validation, and c) a fluid query API for accessing data from the store.
    2. Automatic vuex-based data management for models tracked by this library. Vuex Relfect handles all of the details around managing how data are stored, updated, and normalized so that they can be easily be accessed via class-based model definitions (or from the store directly, if you're not a fan of ES6 classes).

    Notes on Vuex

    Vuex is a fantastic library for doing exactly what it needs to do: manage state. The scope of Vuex was never to inherently manage data retrieval and updates via an API or other external data sources -- it simply (and elegantly) stores data and provides utilities for updating those data and propagating those updates to the components of your application. This package is a logical abstraction of that pattern, providing a more developer-friendly experience around interacting with data models and other external application data.

    Because this module integrates with Vuex for storing data, it also integrates with Vue's official devtools extension to provide advanced features such as zero-config time-travel debugging and state snapshot export/import. It was made with REST API reflection specifically in mind, but can be extended to reflect other types of data sources (i.e. GraphQL).

    Why Reflect?

    The name Reflect was chosen because this package essentially lets you reflect the data provided via an API into your store, with minimal configuration. There are many types of data reflection throughout a well-designed application - the UI reflects data from the frontend data store, the frontend store reflects data from the API, and the API reflects data from the database. This library covers one piece of that puzzle.

    Installation

    Install in Project

    To use this library in a Vue project, add the package to your package dependencies via:

    npm install --save vuex-reflect

    Or, with yarn:

    yarn add vuex-reflect

    Use via CDN

    To use this package via CDN, import it in your project via:

    <script src="https://unpkg.com/vuex-reflect/dist/vuex-reflect.min.js"></script>

    Documentation

    Documentation for the project can be found here.

    Overview

    For full documentation on how to use the plugin, see the docs. The sections below will give a brief overview of some of the concepts.

    Defining Models

    For this example, let's say we're initially interested in a single Todo model. The endpoints supplying data for this model are as follows:

    /todos
      GET - Query all or a subset of objects.
      POST - Create a new todo.
    
    /todos/:id
      GET - Get the metadata for a single todo.
      PUT - Update data for a single todo.
      DELETE - Delete data for a single todo.
    

    And we can define this model using the following configuration:

    import { Model } from 'vuex-reflect';
     
    class Todo extends Model {
     
      /**
       * API config for fetching and updating data.
       */
      static api() {
        return {
          create: '/todos', // url for creating new todo items (POST)
          fetch: '/todos', // url for fetching data with parameters (GET /todos?name.like=my-todo)
          get: '/todos/:id', // url for getting data for a single todo (GET)
          update: '/todos/:id', // url for updating a single todo (PUT)
          delete: '/todos/:id', // url for deleting a single todo (DELETE)
        };
      }
     
      /**
       * Property definitions for the model.
       */
      static props() {
        return {
          /**
           * Todo text
           */
          text: {
            default: null,
            required: true
            mutation: value => `todo: ${value}`,
            validation: /^[a-zA-Z\-]+$/, // validate input with regex
          },
          /**
           * Todo status
           */
          done: {
            default: false,
            type: Boolean,
            validation: value => typeof value === "boolean", // validate input with function
          },
        };
      }
    }

    Registering Models with Vuex

    Once models are defined, you can register them with Vuex like so:

    import Vue from 'vue';
    import Vuex from 'vuex';
    import Reflect from 'vuex-reflect';
    import { Todo } from 'models';
     
    Vue.use(Vuex);
     
    const db = Reflect({
      Todo,
    });
     
    const store = new Vuex.Store({
      state: { ... },
      mutations: { ... },
      plugins: [db],
    })

    With the syntax provided by this library, you define (in clear code) 1) where the data come from, and 2) how that data are mutated and validated during updates. Once you have a model, you can use it to fetch data for the store using (typically called when a component is created):

    Todo.query().then(() => {
      console.log('Data fetched and saved to vuex store.');
    });

    To see all of the data fetched, you can access the store directly:

    // result of: store.state
    {
      todos: {
        1: { id: 1, text: 'first todo', done: false },
        2: { id: 2, text: 'done todo', done: true },
        ...
      }
    }

    Or, you can use the model classes to access the data:

    // result of: Todo.query().all().map(x => x.json())
    [
      { id: 1, text: 'first todo', done: false },
      { id: 2, text: 'done todo', done: true },
      ...
    ]

    Data Interaction

    Other api methods available on models include static methods for querying models from the store:

    // get an existing todo by id
    const todo = Todo.query(1);
    const todo = Todo.query().filter({ text: /part of todo text/ }).first(); // or by other properties
     
    // count all completed todos
    const doneTodos = Todo.query().filter({ done: true }).count();
     
    // query with a fluid api
    Todo.query().filter({ done: true }).has('text').offset(50).limit(3).count()

    Or, static methods for changing data and committing those changes to the API and store:

    // create a new todo
    const todo = new Todo({ text: 'read docs' });
     
    // update it and save it via the API (results will be available via store)
    todo.text += ' tomorrow';
    todo.$.text // 'read docs' -> see the store version of the data
    todo.commit() // POST /todos/:id -> commit result to store
    todo.$.text // 'read docs tomorrow' -> store is updated after commit
     
    // later in the application, fetch all todos and commit them to the store
    await Todo.fetch();
     
    // get the first todo and change the status
    const todo = Todo.query().first();
    todo.done = true;
     
    // PUT the changed data to the API and commit the result to the store
    await todo.commit();

    For full documentation on how to use the library (this README details a small portion of the functionality), see the docs.

    Contributors

    Getting Started

    To get started contributing to the project, simply clone the repo and setup the dependencies using yarn or npm install:

    git clone git@github.com:bprinty/vuex-reflect.git
    cd vuex-reflect/
    yarn

    Once you do that, you should be ready to write code, run tests, and edit the documentation.

    Building Documentation

    To develop documentation for the project, make sure you have all of the developer dependencies installed from the package.json file in the repo. Once you have all of those dependencies, you can work on the documentation locally using:

    yarn docs:dev

    Or, using vuepress directly:

    vuepress dev docs

    Running Tests

    The Jest framework is used for testing this application. To run tests for the project, use:

    yarn test

    To have Jest automatically watch for changes to code for re-running tests in an interactive way, use:

    yarn test:watch

    To run or watch a specific test during development, use:

    yarn test:watch -t model.update

    Or, you can invoke jest directly:

    jest
    jest --watch
    jest --watch -t model.update

    Submiting Feature Requests

    If you would like to see or build a new feature for the project, submit an issue in the GitHub Issue Tracker for the project. When submitting a feature request, please fully explain the context, purpose, and potential implementation for the feature, and label the ticket with the discussion label. Once the feature is approved, it will be re-labelled as feature and added to the project Roadmap.

    Improving Documentation

    Project documentation can always be improved. If you see typos, inconsistencies, or confusing wording in the documentation, please create an issue in the GitHub Issue Tracker with the label documentation. If you would like to fix the issue or improve the documentation, create a branch with the issue number (i.e. GH-123) and submit a PR against the master branch.

    Submitting PRs

    For contributors to this project, please submit improvements according to the following guidelines:

    1. Create a branch named after the ticket you're addressing. GH-1 or bp/GH-1 are examples of good branch naming.
    2. Make your changes and write tests for your changes.
    3. Run all tests locally before pushing code.
    4. Address any test failures caught by Travis CI.
    5. Make sure you've updated the documentation to reflect your changes (if applicable).
    6. Submit a PR against the master branch for the project. Provide any additional context in the PR description or comments.

    Keeping up to Speed on the Project

    All development efforts for the project are tracked by the project Kanban board. Contributors use that board to communicate the status of pending, in-progress, or resolved development efforts. If you have a question about the Roadmap or current in-progress issues for the project, see that board.

    Install

    npm i vuex-reflect

    DownloadsWeekly Downloads

    1

    Version

    0.1.2

    License

    Apache-2.0

    Unpacked Size

    1.01 MB

    Total Files

    92

    Last publish

    Collaborators

    • bprinty