2.52.0 • Published 2 months ago

@coveo/headless v2.52.0

Weekly downloads
3,036
License
Apache-2.0
Repository
github
Last release
2 months ago

Coveo Headless

Contributing:

Using the headless library:

Contributing

Getting started

Once you have cloned the repo, follow the instructions in the top-level README.md to install dependencies and link packages.

To start the project in development mode, run:

npm start

To build the library for production, run:

npm run build

To run the unit tests for the controllers, run:

npm test

To run the unit tests for the controllers and watch, run:

npm run test:watch

Redux

The headless project intensively uses "Redux" along with "Redux Toolkit", so prior knowledge is necessary.

Source folder structure

The base of the /src folder should only contain exports.

/app contains app-wide setup: Redux store, root reducer, middlewares.

/features has folders that each owns the functionalities of a feature, which is a subpart of the redux state. Following the "ducks pattern", those files contain Redux slices & reducers that define the state shape. Each feature folder has a file with actions that can be exported with the project.

/controllers contains all the headless controllers in folders. Those controllers are exported and used to provide abstraction from the store's features by being closer to the actual UI controllers of a customer's application.

/utils contains common useful utilities.

/api contains everything regarding api calls.

/test contains test mocks.

Using the headless library

Configuring a headless engine

You can setup a new headless engine by instantiating the HeadlessEngine class, which implements the Engine interface. The HeadlessEngine class requires some basic configuration, notably your Coveo organization and your access token. Reducers are also required for the HeadlessEngine to work. They are what build and manage the state of the headless engine. All reducers needed for a search page are already exported as searchPageReducers, to add your own custom reducers in order to extend the state, see the Extending the headless state section.

Then, make sure to export the instance so it's shared throughout your application.

Instantiation of a new headless HeadlessEngine instance:

import {HeadlessEngine, searchPageReducers} from '@coveo/headless';

export const engine = new HeadlessEngine({
  configuration: {
    organizationId: 'your_organization',
    accessToken: 'your_access_token',
    search: {
      pipeline: 'your_query_pipeline',
      searchHub: 'your_search_hub',
    },
  },
  reducers: searchPageReducers,
});

To only test out the library's capabilities, you can use our sample configuration. It will give you access to an organization with dummy data.

new HeadlessEngine({
  configuration: HeadlessEngine.getSampleConfiguration(),
  ...

On the HeadlessEngine class instance, you have a few properties:

  • state: an object representing complete headless state tree.
  • dispatch: a method that dispatches an action directly. It is how modifications to the headless state are made.
  • subscribe: a method that lets you add a change listener. It will be called any time an action is dispatched. You may then access the new state.

Using headless controllers

The headless library offers different controllers. These controllers wrap the headless engine's state and actions to offer an interface that is simpler and closer to the actual end-user experience.

Using controllers is the recommended way to interact with the headless engine for most use cases. We will use the SearchBox controller as example here.

Instantiating a controller

You can setup a new headless controller by instantiating its class. Every controller constructor has the following parameters:

  1. The HeadlessEngine instance, created previously.
  2. The specific options for that controller, sometimes optional.

Instantiation of a SearchBox headless controller:

import {SearchBox, buildSearchBox} from '@coveo/headless';
import {engine} from './engine';

const searchBox: SearchBox = buildSearchBox(engine);
Controller options validation.

Every controller's option is validated at runtime according to their type and value. Details about each option is well documented. If an option is invalid, the instanciation of the controller will throw an error describing the issue. Make sure to manage those potential errors.

Interacting with a controller

The controller will interact with the headless state of the HeadlessEngine instance passed as an argument.

All controllers have a state attribute, which is a scoped part of the headless state that is relevant to the controller.

For the SearchBox controller, the state returns relevant parts of the headless state to be used or rendered in the UI.

console.log(searchBox.state); // {value: "", suggestions: [], redirectTo: null}

Controllers will manage the dispatching of necessary actions to the headless engine.

Every controller offers a high-level interface to be used by UI controller. E.g, the SearchBox controller offers methods like updateText, submit, clear, selectSuggestion, etc.

Subscribing to a SearchBox controller's state and interacting with its methods.

function onSearchBoxUpdate() {
  const state = searchBox.state;
  // do something with the updated searchBox state
}

const unsubscribe = searchBox.subscribe(onSearchBoxUpdate);

// This will dispatch an action to the engine and update the state
searchBox.updateText({value: 'hello world'});

// When you don't need to listen to state changes anymore (e.g., when a controller is deleted)
unsubscribe();

Updating the headless state

The headless state itself is organized by features (e.g., configuration, query suggestion, redirection). Each of those features reacts to different actions in order to update their respective piece of state. When headless controllers prove insufficient, you can use these actions directly to get a granular control over the application's state.

Let's first explain some basic concepts such as actions and action creators.

Understanding actions

An action is a plain object with a few properties:

  • type: a string value identifying the nature of the action. E.g., configuration/updateSearchConfiguration is an action from the configuration feature that updates the search configuration.
  • payload: optional, the payload could be of any type, and varies depending on the type of action. E.g., for an action with the type configuration/updateSearchConfiguration, the payload is an object containing the searchApiBaseUrl property which is a string.
  • error: optional, the error is set to true when the action represents an error (e.g., a failed promise). When the error value is true the payload should contain the error object.
  • meta: optional, the meta property can be of any type and is meant to add extra information not part of the payload (e.g., a request ID).

Actions can either be synchronous or asynchronous, meaning its effects can be seen instantly in the state or at a later time (e.g., when an API request finishes executing).

Understanding action creators

type ActionCreator = (...args: any) => Action;

Actions can get complex, that's why the headless library offers action creators for every action to simplify usage. An action creator is a function that takes only relevant arguments and returns the correct action.

Example:

import {ConfigurationActions} from '@coveo/headless';

// Calling the following action creator:
ConfigurationActions.updateSearchConfiguration({
  endpoint: 'https://platform.cloud.coveo.com/',
});

// ...returns the following action:
// {
//   type: 'configuration/updateSearchConfiguration',
//   payload: {
//     endpoint: 'https://platform.cloud.coveo.com/'
//   }
// }

Dispatching actions

To update the headless state, actions have to be dispatched using the dispatch method of the HeadlessEngine class instance.

import {ConfigurationActions} from '@coveo/headless';
import {engine} from './engine';

const action = ConfigurationActions.updateSearchConfiguration({
  endpoint: 'https://platform.cloud.coveo.com/',
});

// Calling dispatch with the action will make the headless engine update its state using the payload (endpoint value)
engine.dispatch(action);
Action validation

The actions parameters are validated at runtime according to their type and value. Details about each parameter is well documented. If a parameter is invalid, the action will not be dispatched to the headless engine and an error will be thrown.

Subscribing to state changes

Using the subscribe method on the HeadlessEngine class instance, the changes can be listened to. The listener function passed to subscribe will be called every time an action is dispatched.

import {engine} from './engine';

function onStateUpdate() {
  const state = engine.state;
  // do something with the updated state
}

const unsubscribe = engine.subscribe(onStateUpdate);

// When you don't need to listen to state changes anymore (e.g., when a controller is deleted).
unsubscribe();

Note: the listener function is called on every action dispatch, so make sure you only perform costly operations, like rendering a UI controller, if the state they depend on has changed.

Extending the headless state

It can be useful to add custom functionalities to the headless engine. That's why the headless engine is designed at its core to be extendable.

Adding reducers

The state shape of the headless engine is dictated by its reducers. A reducer is a function that accepts a piece of state and an action and returns a new permuted state.

type Reducer<S, A> = (state: S, action: A) => S;

In our example, for the sake of simplicity, let's create a simple counter reducer with actions:

export const incrementCounterAction = {type: 'counter/increment'};
export const decrementCounterAction = {type: 'counter/decrement'};

const initialCounterState = 0;

export const counterReducer = (
  state = initialCounterState,
  action: typeof incrementCounterAction | typeof decrementCounterAction
) => {
  switch (action.type) {
    case incrementCounterAction.type:
      return state + 1;
    case decrementCounterAction.type:
      return state - 1;
  }
  return state;
};

Here, the counter reducer function takes a state which is a number value, and an action. Depending on the action's type, it will return a new state with the value either incremented or decremented.

The headless library exports some of Redux Toolkit's utilitary functions to ease and streamline development:

  • createReducer: A utility that simplifies the creation of Redux reducers, and manages immutability internally.
  • createAction: A helper function for defining a Redux action type and creator.
  • createAsyncThunk: A helper function for defining a Redux "Thunk", which is more complex action creator that returns a function instead of an action. It is the recommended approach when handling async request lifecycles.

We strongly recommend using those utilitary functions and reading their respective documentation. If you are using TypeScript, we strongly recommend looking up the Usage With TypeScript section as well.

We also offer out-of-the-box reducers map that contain a group of features, like the searchPageReducers which offer all the necessary functionalities to build a search page. The reducer map is defined during initialization:

import {HeadlessEngine, searchPageReducers} from '@coveo/headless';
import {counterReducer} from './counter-reducer';

export const engine = new HeadlessEngine({
  configuration: {
    ...
  },
  reducers: {
    ...searchPageReducers
    counter: counterReducer,
  },
});

The state will be automatically built out of the reducers, and will respond accordingly to the dispatched actions:

import {engine} from './engine';
import {incrementCounterAction} from './counter-reducer';

engine.dispatch(incrementCounterAction);
console.log(engine.state.counter); // 1

Creating headless controllers

It is possible to create custom headless controllers using the buildController function. When using Typescript, it is necessary to specify the type of the engine.

import {
  Engine,
  buildController
} from '@coveo/headless';
import {
  incrementCounterAction,
  decrementCounterAction,
} from './counter-reducer';
import {engine} from './engine';

export type CounterState = Counter['state'];

export type Counter = ReturnType<typeof buildCounter>;

export const buildCounter = (
  engine: Engine
) => {
  const controller = buildController(engine);

  return {
    ...controller,

    increment() {
      dispatch(incrementCounterAction);
    },

    decrement() {
      dispatch(decrementCounterAction);
    },

    get state() {
      return engine.state.counter;
    },
  };
};
2.52.0

2 months ago

2.51.0

2 months ago

2.50.2

3 months ago

2.50.1

3 months ago

2.50.0

3 months ago

2.49.1

3 months ago

2.49.0

3 months ago

2.48.0

3 months ago

2.47.0

3 months ago

2.46.0

4 months ago

2.45.1

4 months ago

2.45.0

4 months ago

2.44.0

5 months ago

2.43.0

5 months ago

2.42.0

5 months ago

2.41.0

5 months ago

2.34.0

7 months ago

2.21.0

10 months ago

2.32.0

8 months ago

2.30.1

8 months ago

2.30.0

8 months ago

2.28.0

9 months ago

2.39.0

6 months ago

2.26.1

9 months ago

2.26.0

9 months ago

2.37.0

6 months ago

2.24.0

9 months ago

2.35.0

7 months ago

2.22.0

10 months ago

2.33.0

7 months ago

2.31.0

8 months ago

2.40.2

6 months ago

2.40.1

6 months ago

2.40.0

6 months ago

2.29.0

8 months ago

2.27.0

9 months ago

2.38.2

6 months ago

2.38.1

6 months ago

2.38.3

6 months ago

2.38.0

6 months ago

2.25.0

9 months ago

2.25.1

9 months ago

2.36.0

7 months ago

0.0.0-baguette.4

7 months ago

0.0.0-baguette.2

7 months ago

0.0.0-baguette.3

7 months ago

0.0.0-baguette.0

7 months ago

0.0.0-baguette.1

7 months ago

2.23.0

9 months ago

2.20.0

10 months ago

2.19.0

11 months ago

2.18.3

11 months ago

2.18.4

11 months ago

2.18.1

11 months ago

2.18.2

11 months ago

2.18.0

11 months ago

2.17.0

12 months ago

2.17.1

12 months ago

2.16.5

12 months ago

2.16.3

12 months ago

2.16.4

12 months ago

2.16.1

12 months ago

2.16.2

12 months ago

2.16.0

1 year ago

2.15.0

1 year ago

2.14.3

1 year ago

2.14.1

1 year ago

2.14.2

1 year ago

2.14.0

1 year ago

2.13.0

1 year ago

2.13.1

1 year ago

2.11.0

1 year ago

2.11.1

1 year ago

2.11.2

1 year ago

2.10.1

1 year ago

2.10.0

1 year ago

2.9.0

1 year ago

2.12.0

1 year ago

2.12.1

1 year ago

2.8.11

1 year ago

2.8.10

1 year ago

2.8.7

1 year ago

2.8.9

1 year ago

2.8.8

1 year ago

2.4.0

1 year ago

2.3.0

1 year ago

2.3.1

1 year ago

2.2.0

1 year ago

2.8.1

1 year ago

2.7.0

1 year ago

2.7.1

1 year ago

2.8.3

1 year ago

2.8.2

1 year ago

2.8.5

1 year ago

2.8.4

1 year ago

2.8.6

1 year ago

2.6.1

1 year ago

2.6.0

1 year ago

2.5.0

1 year ago

1.114.0

1 year ago

2.1.0

1 year ago

1.111.0

1 year ago

1.111.1

1 year ago

1.111.2

1 year ago

1.111.3

1 year ago

1.110.1

2 years ago

1.110.2

2 years ago

1.110.0

2 years ago

1.110.3

2 years ago

1.110.4

1 year ago

1.113.0

1 year ago

2.0.0-pre.1

1 year ago

2.0.0-pre.5

1 year ago

2.0.0-pre.4

1 year ago

2.0.0-pre.3

1 year ago

2.0.0-pre.2

1 year ago

2.0.0-pre.7

1 year ago

2.0.0-pre.6

1 year ago

1.112.0

1 year ago

2.0.1

1 year ago

1.109.0

2 years ago

1.108.0

2 years ago

1.107.0

2 years ago

1.106.0

2 years ago

1.103.5

2 years ago

1.103.6

2 years ago

1.103.3

2 years ago

1.103.4

2 years ago

1.103.1

2 years ago

1.103.2

2 years ago

1.103.0

2 years ago

1.102.0

2 years ago

1.105.1

2 years ago

1.105.2

2 years ago

1.105.0

2 years ago

1.104.2

2 years ago

1.104.0

2 years ago

1.104.1

2 years ago

1.101.2

2 years ago

1.101.0

2 years ago

1.101.1

2 years ago

1.100.0

2 years ago

1.94.0

2 years ago

1.82.0

2 years ago

1.70.0

2 years ago

1.70.1

2 years ago

1.93.0

2 years ago

1.83.0

2 years ago

1.71.0

2 years ago

1.96.1

2 years ago

1.96.0

2 years ago

1.84.0

2 years ago

1.72.0

2 years ago

1.95.0

2 years ago

1.73.0

2 years ago

1.75.3

2 years ago

1.98.0

2 years ago

1.86.0

2 years ago

1.74.0

2 years ago

1.74.1

2 years ago

1.74.2

2 years ago

1.76.2

2 years ago

1.76.3

2 years ago

1.97.0

2 years ago

1.76.4

2 years ago

1.76.5

2 years ago

1.76.6

2 years ago

1.76.7

2 years ago

1.76.8

2 years ago

1.76.9

2 years ago

1.87.0

2 years ago

1.87.1

2 years ago

1.75.0

2 years ago

1.75.1

2 years ago

1.75.2

2 years ago

1.77.1

2 years ago

1.77.2

2 years ago

1.77.3

2 years ago

1.77.4

2 years ago

1.77.5

2 years ago

1.77.6

2 years ago

1.77.7

2 years ago

1.77.8

2 years ago

1.77.9

2 years ago

1.89.0

2 years ago

1.88.0

2 years ago

1.88.1

2 years ago

1.76.0

2 years ago

1.76.1

2 years ago

1.99.0

2 years ago

1.78.0

2 years ago

1.76.10

2 years ago

1.77.0

2 years ago

1.79.0

2 years ago

1.69.0

2 years ago

1.69.1

2 years ago

1.90.0

2 years ago

1.92.0

2 years ago

1.80.0

2 years ago

1.91.0

2 years ago

1.81.0

2 years ago

1.67.0

2 years ago

1.67.1

2 years ago

1.68.0

2 years ago

1.68.1

2 years ago

1.63.0

2 years ago

1.63.1

2 years ago

1.64.0

2 years ago

1.65.0

2 years ago

1.66.0

2 years ago

1.66.1

2 years ago

1.66.2

2 years ago

1.66.3

2 years ago

1.60.0

2 years ago

1.60.1

2 years ago

1.61.1

2 years ago

1.61.0

2 years ago

1.62.0

2 years ago

1.57.0

2 years ago

1.58.0

2 years ago

1.59.0

2 years ago

1.52.1

2 years ago

1.54.3

2 years ago

1.54.2

2 years ago

1.54.4

2 years ago

1.53.0

2 years ago

1.54.1

2 years ago

1.54.0

2 years ago

1.56.0

2 years ago

1.55.0

2 years ago

1.51.0

2 years ago

1.52.0

2 years ago

1.47.1

2 years ago

1.50.1

2 years ago

1.50.0

2 years ago

1.48.0

2 years ago

1.48.2

2 years ago

1.48.1

2 years ago

1.49.1

2 years ago

1.49.0

2 years ago

1.44.0

2 years ago

1.45.1

2 years ago

1.45.0

2 years ago

1.45.2

2 years ago

1.46.0

2 years ago

1.46.2

2 years ago

1.46.1

2 years ago

1.46.3

2 years ago

1.47.0

2 years ago

1.41.10

2 years ago

1.41.13

2 years ago

1.41.12

2 years ago

1.41.11

2 years ago

1.41.1

2 years ago

1.41.3

2 years ago

1.41.2

2 years ago

1.41.5

2 years ago

1.41.4

2 years ago

1.41.7

2 years ago

1.41.6

2 years ago

1.41.9

2 years ago

1.41.8

2 years ago

1.42.0

2 years ago

1.43.1

2 years ago

1.43.0

2 years ago

1.43.2

2 years ago

1.33.1

2 years ago

1.33.2

2 years ago

1.32.0

2 years ago

1.34.0

2 years ago

1.33.0

2 years ago

1.35.2

2 years ago

1.36.0

2 years ago

1.37.0

2 years ago

1.37.1

2 years ago

1.37.2

2 years ago

1.40.0

2 years ago

1.40.1

2 years ago

1.38.0

2 years ago

1.38.1

2 years ago

1.41.0

2 years ago

1.31.5

2 years ago

1.31.6

2 years ago

1.31.3

2 years ago

1.31.4

2 years ago

1.31.7

2 years ago

1.39.0

2 years ago

1.30.2

3 years ago

1.30.3

3 years ago

1.30.1

3 years ago

1.31.1

3 years ago

1.31.2

3 years ago

1.31.0

3 years ago

1.30.0

3 years ago

1.29.0

3 years ago

1.29.1

3 years ago

1.24.1

3 years ago

1.25.0

3 years ago

1.26.0

3 years ago

1.27.0

3 years ago

1.28.1

3 years ago

1.28.2

3 years ago

1.28.0

3 years ago

1.24.0

3 years ago

1.23.0

3 years ago

1.21.0

3 years ago

1.22.0

3 years ago

1.20.3

3 years ago

1.20.4

3 years ago

1.20.1

3 years ago

1.20.2

3 years ago

1.20.0

3 years ago

1.19.4

3 years ago

1.19.5

3 years ago

1.19.3

3 years ago

1.19.2

3 years ago

1.18.5

3 years ago

1.18.4

3 years ago

1.19.0

3 years ago

1.19.1

3 years ago

1.18.3

3 years ago

1.18.2

3 years ago

1.18.1

3 years ago

1.18.0

3 years ago

1.17.2

3 years ago

1.17.1

3 years ago

1.17.3

3 years ago

1.16.2

3 years ago

1.17.0

3 years ago

1.15.0

3 years ago

1.16.1

3 years ago

1.16.0

3 years ago

1.14.1

3 years ago

1.13.1

3 years ago

1.14.0

3 years ago

1.13.0

3 years ago

1.12.0

3 years ago

1.11.4

3 years ago

1.11.3

3 years ago

1.11.2

3 years ago

1.11.0

3 years ago

1.9.0

3 years ago

1.8.0

3 years ago

1.7.4

3 years ago

1.7.3

3 years ago

1.7.2

3 years ago

1.7.1

3 years ago

1.7.0

3 years ago

1.6.3

3 years ago

1.6.2

3 years ago

1.6.1

3 years ago

1.6.0

3 years ago

1.5.2

3 years ago

1.5.1

3 years ago

1.5.0

3 years ago

1.4.1

3 years ago

1.4.0

3 years ago

1.3.3

3 years ago

1.3.2

3 years ago

1.3.1

3 years ago

1.3.0

3 years ago

1.2.0

3 years ago

1.1.0

3 years ago

0.31.1

3 years ago

1.0.0

3 years ago

0.29.0

3 years ago

0.29.1

3 years ago

0.30.0

3 years ago

0.31.0

3 years ago

0.27.0

3 years ago

0.28.1

3 years ago

0.28.0

3 years ago

0.25.0

3 years ago

0.26.0

3 years ago

0.24.0

3 years ago

0.20.0

3 years ago

0.17.0

3 years ago

0.21.0

3 years ago

0.18.0

3 years ago

0.22.1

3 years ago

0.22.0

3 years ago

0.15.5

3 years ago

0.15.6

3 years ago

0.15.0

3 years ago

0.15.2

3 years ago

0.15.3

3 years ago

0.16.0

3 years ago

0.16.1

3 years ago

0.16.2

3 years ago

0.19.0

3 years ago

0.23.3

3 years ago

0.23.1

3 years ago

0.23.0

3 years ago

0.11.0-alpha.5

3 years ago

0.11.0-alpha.8

3 years ago

0.12.0-alpha.0

3 years ago

0.13.0-alpha.7

3 years ago

0.13.0-alpha.6

3 years ago

0.13.0-alpha.2

3 years ago

0.13.0-alpha.1

3 years ago

0.13.0-alpha.0

3 years ago

0.14.0-alpha.3

3 years ago

0.13.0

3 years ago

0.14.0-alpha.0

3 years ago

0.11.0-alpha.12

3 years ago

0.11.0-alpha.10

3 years ago

0.11.0

3 years ago

0.12.0

3 years ago

1.1.0-alpha.1

3 years ago

1.1.0-alpha.0

3 years ago

1.1.0-alpha.5

3 years ago

1.1.0-alpha.3

3 years ago

0.11.0-alpha.3

3 years ago

0.11.0-alpha.2

3 years ago

0.10.0

3 years ago

0.10.0-alpha.17

3 years ago

0.10.0-alpha.16

3 years ago

0.10.0-alpha.14

3 years ago

0.10.0-alpha.13

3 years ago

0.10.0-alpha.15

3 years ago

0.10.0-alpha.12

3 years ago

0.10.0-alpha.10

3 years ago

0.10.0-alpha.7

3 years ago

0.10.0-alpha.6

3 years ago

0.10.0-alpha.3

3 years ago

0.10.0-alpha.4

3 years ago

0.10.0-alpha.0

3 years ago

0.9.0

3 years ago

0.9.0-alpha.9

3 years ago

0.9.0-alpha.7

3 years ago

0.9.0-alpha.0

3 years ago

0.8.0

3 years ago

0.8.1-alpha.0

3 years ago

0.8.0-alpha.17

3 years ago

0.8.0-alpha.19

3 years ago

0.8.0-alpha.20

3 years ago

0.8.0-alpha.15

3 years ago

0.8.0-alpha.16

3 years ago

0.8.0-alpha.10

3 years ago

0.8.0-alpha.12

3 years ago

0.7.0

3 years ago

0.7.0-alpha.38

3 years ago

0.7.0-alpha.36

3 years ago

0.7.0-alpha.35

3 years ago

0.7.0-alpha.39

3 years ago

0.8.0-alpha.9

3 years ago

0.8.0-alpha.5

3 years ago

0.8.0-alpha.8

3 years ago

0.8.0-alpha.7

3 years ago

0.8.0-alpha.2

3 years ago

0.8.0-alpha.1

3 years ago

0.8.0-alpha.3

3 years ago

0.7.0-alpha.34

3 years ago

0.7.0-alpha.33

3 years ago

0.7.0-alpha.31

3 years ago

0.7.0-alpha.30

3 years ago

0.7.0-alpha.29

3 years ago

0.7.0-alpha.26

3 years ago

0.7.0-alpha.25

3 years ago

0.7.0-alpha.24

3 years ago

0.7.0-alpha.23

3 years ago

0.7.0-alpha.22

3 years ago

0.7.0-alpha.21

3 years ago

0.7.0-alpha.19

3 years ago

0.7.0-alpha.20

3 years ago

0.7.0-alpha.16

3 years ago

0.7.0-alpha.17

3 years ago

0.7.0-alpha.15

3 years ago

0.7.0-alpha.14

3 years ago

0.7.0-alpha.13

3 years ago

0.7.0-alpha.12

3 years ago

0.7.0-alpha.11

3 years ago

0.7.0-alpha.10

3 years ago

0.7.0-alpha.3

3 years ago

0.7.0-alpha.2

3 years ago

0.7.0-alpha.1

3 years ago

0.7.0-alpha.0

3 years ago

0.6.1-alpha.0

3 years ago

0.6.0

3 years ago

0.6.0-alpha.8

3 years ago

0.6.0-alpha.7

3 years ago

0.6.0-alpha.6

3 years ago

0.6.0-alpha.4

3 years ago

0.6.0-alpha.1

3 years ago

0.6.0-alpha.2

3 years ago

0.6.0-alpha.0

3 years ago

0.5.0

3 years ago

0.5.0-alpha.2

3 years ago

0.5.0-alpha.1

3 years ago

0.5.0-alpha.0

3 years ago

0.4.0

3 years ago

0.4.0-alpha.8

3 years ago

0.4.0-alpha.7

3 years ago

0.4.0-alpha.4

3 years ago

0.3.0

3 years ago

0.3.0-alpha.5

3 years ago

0.3.0-alpha.4

3 years ago

0.3.0-alpha.0

3 years ago

0.2.1

3 years ago

0.2.1-alpha.0

3 years ago

0.2.0

3 years ago

0.2.0-alpha.10

3 years ago

0.2.0-alpha.9

3 years ago

0.2.0-alpha.7

3 years ago

0.2.0-alpha.6

3 years ago

0.2.0-alpha.5

3 years ago

0.2.0-alpha.4

3 years ago

0.2.0-alpha.3

3 years ago

0.2.0-alpha.2

3 years ago

0.2.0-alpha.0

3 years ago

0.2.0-alpha.1

3 years ago

0.1.0

3 years ago

0.1.0-alpha.113

3 years ago

0.1.0-alpha.112

3 years ago

0.1.0-alpha.110

3 years ago

0.1.0-alpha.111

3 years ago

0.1.0-alpha.108

3 years ago

0.1.0-alpha.109

3 years ago

0.1.0-alpha.104

3 years ago

0.1.0-alpha.105

3 years ago

0.1.0-alpha.106

3 years ago

0.1.0-alpha.107

3 years ago

0.1.0-alpha.103

3 years ago

0.1.0-alpha.100

3 years ago

0.1.0-alpha.101

3 years ago

0.1.0-alpha.102

3 years ago

0.1.0-alpha.99

3 years ago

0.1.0-alpha.98

3 years ago

0.1.0-alpha.96

3 years ago

0.1.0-alpha.97

3 years ago

0.1.0-alpha.95

3 years ago

0.1.0-alpha.94

3 years ago

0.1.0-alpha.93

3 years ago

0.1.0-alpha.92

3 years ago

0.1.0-alpha.91

3 years ago

0.1.0-alpha.89

3 years ago

0.1.0-alpha.90

3 years ago

0.1.0-alpha.87

3 years ago

0.1.0-alpha.86

3 years ago

0.1.0-alpha.88

3 years ago

0.1.0-alpha.85

3 years ago

0.1.0-alpha.83

3 years ago

0.1.0-alpha.81

3 years ago

0.1.0-alpha.82

3 years ago

0.1.0-alpha.80

3 years ago

0.1.0-alpha.77

3 years ago

0.1.0-alpha.79

3 years ago

0.1.0-alpha.75

3 years ago

0.1.0-alpha.74

3 years ago

0.1.0-alpha.73

3 years ago

0.1.0-alpha.72

3 years ago

0.1.0-alpha.71

3 years ago

0.1.0-alpha.69

3 years ago

0.1.0-alpha.68

3 years ago

0.1.0-alpha.65

3 years ago

0.1.0-alpha.66

3 years ago

0.1.0-alpha.63

3 years ago

0.1.0-alpha.64

3 years ago

0.1.0-alpha.62

3 years ago

0.1.0-alpha.61

3 years ago

0.1.0-alpha.60

3 years ago

0.1.0-alpha.58

3 years ago

0.1.0-alpha.57

3 years ago

0.1.0-alpha.56

3 years ago

0.1.0-alpha.55

3 years ago

0.1.0-alpha.53

3 years ago

0.1.0-alpha.52

3 years ago

0.1.0-alpha.51

3 years ago

0.1.0-alpha.50

3 years ago

0.1.0-alpha.49

3 years ago

0.1.0-alpha.48

3 years ago

0.1.0-alpha.47

3 years ago

0.1.0-alpha.42

3 years ago

0.1.0-alpha.45

3 years ago

0.1.0-alpha.46

3 years ago

0.1.0-alpha.41

3 years ago

0.1.0-alpha.40

3 years ago

0.1.0-alpha.39

3 years ago

0.1.0-alpha.38

3 years ago

0.1.0-alpha.36

4 years ago

0.1.0-alpha.37

4 years ago

0.1.0-alpha.35

4 years ago

0.1.0-alpha.34

4 years ago

0.1.0-alpha.33

4 years ago

0.1.0-alpha.32

4 years ago

0.1.0-alpha.30

4 years ago

0.1.0-alpha.29

4 years ago

0.1.0-alpha.27

4 years ago

0.1.0-alpha.26

4 years ago

0.1.0-alpha.28

4 years ago

0.1.0-alpha.24

4 years ago

0.1.0-alpha.23

4 years ago

0.1.0-alpha.22

4 years ago

0.1.0-alpha.21

4 years ago

0.1.0-alpha.19

4 years ago

0.1.0-alpha.18

4 years ago

0.1.0-alpha.17

4 years ago

0.1.0-alpha.10

4 years ago

0.1.0-alpha.11

4 years ago

0.1.0-alpha.9

4 years ago

0.1.0-alpha.8

4 years ago

0.1.0-alpha.7

4 years ago

0.1.0-alpha.6

4 years ago

0.1.0-alpha.5

4 years ago

0.1.0-alpha.4

4 years ago

0.1.0-alpha.3

4 years ago

0.1.0-alpha.2

4 years ago

0.1.0-alpha.0

4 years ago

0.0.2-alpha.2

4 years ago

0.0.2-alpha.0

4 years ago

0.0.1

4 years ago