0.0.13 • Published 4 years ago

@bloko/js v0.0.13

Weekly downloads
-
License
MIT
Repository
github
Last release
4 years ago

Travis build Codecov coverage NPM version

Packages

  • 🧱@bloko/js - Core library and utilities to handle Blokos
  • ⚛️@bloko/react - React hooks and utilities for using Bloko in React applications

Bloko is currently under heavy development, but can be installed by running:

npm install --save @bloko/js

Blokos Unit

Blokos Unit are the smaller of Blokos. Using these Blokos you can describe the application's Entities.

A quick example

import Bloko from '@bloko/js';

const User = Bloko.create({
  name: '',
  surname: '',
});

User();
// => { name: '', surname: '' }

User({ name: 'John' });
// => { name: 'John', surname: '' }

Derivated props

Blokos Unit can allow you to create derivated data from other props.

import Bloko from '@bloko/js';

const User = Bloko.create({
  name: '',
  surname: '',
  fullName() {
    if (!this.name || !this.surname) {
      return '';
    }

    return this.name + ' ' + this.surname;
  },
});

User();
// => { name: '',  surname: '', fullName: '' }

User({ name: 'John', surname: 'S.' });
// => { name: 'John',  surname: 'S.', fullName: 'John S.' }

Rules and Transformations

Blokos Unit can check prop rules and do transformations when needed.

import Bloko from '@bloko/js';

const User = Bloko.create({
  name: {
    value: '',
    rules: [
      v => !!v || 'Name is required',
      v => v.length > 1 || 'Name is too small',
    ],
  },
  surname: {
    value(surname) {
      if (!surname) {
        return '';
      }

      return surname.toUpperCase();
    },
    rules: v => !!v || 'Surname is required',
  },
});

// When entry is undefined, User will make a valid
// Bloko with default values and apply its transforms
User();
// => { name: '',  surname: '' }

// When entry is a object, User will run transformations
// and apply rules using fail fast strategy.
User({ name: '' });
// => Error: Name is required

User({ name: 'John', surname: 'Smith' });
// => { name: 'John',  surname: 'SMITH' }

// You could check a raw object following User rules
User.validate({ name: '' });
// => false
User.validate({ name: 'John', surname: 'S.' });
// => true

// You could get rules array of each prop and apply wherever you need
User.rules();
// => { name: [isRequiredRule, isSmallRule], surname: [isRequiredRule] }

Initial State

Blokos Unit can return initial state from default values.

import Bloko from '@bloko/js';

const User = Bloko.create({
  name: '',
  surname: {
    value: '',
    rules: [],
  },
  noDefault: {
    rules: [],
  },
  derivated() {
    return '';
  },
});

// Note that state() won't return derivated props
User.state();
// => { name: '',  surname: '', noDefault: undefined }

Composition between Blokos Unit

Blokos Unit can be more complex and compose other Blokos Unit and check children rules directly from parent.

import Bloko from '@bloko/js';

const Address = Bloko.create({
  zipcode: {
    value: '',
    rules: v => !!v || 'Zipcode is required',
  },
});

const User = Bloko.create({
  name: {
    value: '',
    rules: v => !!v || 'Name is required',
  },
  address: Address,
});

User();
// => { name: '', address: { zipcode: '' } }

User({ name: 'John' });
// => Error: Zipcode is required

User({ name: 'John', address: { zipcode: '84275' } });
// => { name: 'John', address: { zipcode: '84275' } }

Blokos Store

Blokos Store are the next important Bloko. Using these Blokos you can describe how application's global state will behave based on its actions.

A brief example

import Bloko from '@bloko/js';

const Session = Bloko.create({
  token: '',
});

const Auth = Bloko.createStore({
  key: 'auth',
  state: {
    session: {
      type: Session,
      setter: true,
    },
  },
  actions: {
    signIn: {
      // Use loading function when it is
      // necessary to return something
      // different than true
      loading(payload) {
        return payload.email;
      },
      request(payload) {
        // Using axios to exmplify, but could be any provider
        return axios.post('/auth/sign-in', {
          email: payload.email,
          password: payload.password,
        });
      },
      resolved(data, state) {
        return {
          session: {
            ...state.session,
            token: data.token,
          },
        };
      },
    },
  },
});

Auth will store all its actions and current state on application's global state and could be accessed by its key auth. Besides Auth session state, a special state named signIn will automatically be created because Auth has an action with this name. signIn state will follow an object with shape { loading, error } so on every signIn action call could be possible to track loading states and error feedback.

Blokos Store needs a context to work and specific bloko libraries like bloko-react will give it using Bloko.Provider.

When you call signIn with its necessary payload loading will be called and its changes loading request state and reset any errors to empty string. Using loading function it could be possible to return something different than true.

Next repository handler will be called. The example above will fire a http request simulating an authentication flow.

When it is finished and has a green response, resolved handler will be called and it is responsible to return the next state based on resolved data passed as first parameter. Given the example, session will be updated with a new token in data.token.

When repository rejects something a internal catch handles the error and updates signIn.error state with error.message string.

Why?

...

0.0.13

4 years ago

0.0.12

4 years ago

0.0.11

4 years ago

0.0.10

4 years ago

0.0.9

4 years ago

0.0.8

4 years ago

0.0.7

4 years ago

0.0.6

4 years ago

0.0.5

4 years ago

0.0.4

4 years ago

0.0.3

4 years ago

0.0.2

4 years ago

0.0.1

4 years ago