Skip to content

Commit

Permalink
Merge pull request #3 from pushkar8723/scope-pkg
Browse files Browse the repository at this point in the history
Moved to scope package
  • Loading branch information
pushkar8723 committed Sep 27, 2019
2 parents 3375c9e + 5be9904 commit d594c25
Show file tree
Hide file tree
Showing 115 changed files with 5,699 additions and 1,936 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ lib-esm
_bundles
coverage
.vscode
lerna-debug.log
4 changes: 0 additions & 4 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,6 @@ language: node_js
node_js:
- "8"

script:
- npm run check-all
- npm run build

jobs:
include:
- stage: Produce Coverage
Expand Down
7 changes: 0 additions & 7 deletions core/package.json

This file was deleted.

224 changes: 32 additions & 192 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -1,213 +1,53 @@

Sparkx :sparkles:
=================
[

[![npm version](https://badge.fury.io/js/sparkx.svg)](https://badge.fury.io/js/sparkx) [![Build Status](https://travis-ci.org/pushkar8723/sparkx.svg?branch=master)](https://travis-ci.org/pushkar8723/sparkx) [![Coverage Status](https://coveralls.io/repos/github/pushkar8723/sparkx/badge.svg?branch=master)](https://coveralls.io/github/pushkar8723/sparkx?branch=master) ![Minifized Size](https://badgen.net/bundlephobia/min/sparkx) ![Gzipped Size](https://badgen.net/bundlephobia/minzip/sparkx) [![license](https://badgen.now.sh/badge/license/MIT)](./LICENSE)
core
====

MVC framework with flux implementation for state management.
](#core)

Today a frontend developer has to make a very difficult choice before starting any project, i.e., to have an MVC framework or go with flux pattern. MVC brings a very well defined separation of concerns to the table whereas flux brings predictability which might help when the application grows to be a monolith, but adds the amount of boilerplate code that needs to be written for implementing a feature. Making application development slow. This only deteriorates with time.
**Sparkx state management module**. This module abstracts out state management part of the application. It is a facade over immutable js and redux to provide a flux architecture with an immutable state. It exposes `createStore` and `compose` from redux library to initialize store and add middlewares (if required).

This tradeoff between predictability and time for development is what sparkx tries to solve. By combining flux design pattern for state management with MVC structure, we get a framework with well-defined separation of concerns with all the features of flux like traceability and time travel for easy debug.
The `@sparkx/core/lib/stateManagement` module exposes various methods to fire actions that updates the global and local scope of the application. The reducers are combined and exposed from `@sparkx/core/lib/model`. All these are supposed to be abstracted out from the application developer by individual view facade module like `@sparkx/react` (for react).

### Features
It also exposes abstract implementation for controllers and services as `ControllerBase` and `ServiceBase` respectively. These are the only two entities application developer needs to know about.

* Application State management
* Immutable state
* Hierarchical state
* Routing with nested routes, transition hooks and lazy load
* Support for hash and browser history api routing
* Typed
* Sigleton services
* Support for React
* Support for Vue
* Support for Polymer
[

### Gettting Started
Usage
-----

All you need to keep in mind while writing an application using sparkx is that there are two scopes.
](#usage)

* Global: This state is available to every view and controller and can be used to save information required throughout the application like user context and metadata.
* Scope: This part of the state is specific to the view and controller. It is automatically cleared when the user moves to another state.
```typescript
import { compose, createStore } from '@sparkx/core';
import model from '@sparkx/core/lib/model';

##### Initializing App

To initialize an app, `initApp` function needs to be called. It takes a callback function as an argument. It exposes a setGlobal function as an argument to the given callback function. `setGlobal` can be used to initialize (if required) global scope with some initial value.

```TypeScript
import routes from 'config/routes';
import * as ReactDOM from 'react-dom';
import { initApp, pushStateLocationPlugin, RoutingService } from 'sparkx/react';

ReactDOM.render(
initApp<IGlobal>(
(setGlobal) => {
// Register plugin
routingService.registerPlugin(pushStateLocationPlugin);

// Register routes.
routingService.registerRoutes(routes);

// Setting starting route.
routingService.setInitialState('welcome');

// Setting fallback route.
routingService.set404State('404');
}),
document.getElementById('root'),
// Creating store.
const store = createStore(
model,
compose.apply(this, middlewares),
);
```

##### Routes Configuration

As evident by the code snippet above, we also need to configure application routes while initializing the application. For this, we use `RoutingService` (Detailed docs available [here](./docs/classes/_react_routingservice_.routingservice.md)). To create each route we need to call `createRoute` function as shown below. The `createRoute` method and `RoutingService` internally uses [UI-Router-React](https://github.com/ui-router/react) for creating and managing routes of the application.

```TypeScript
import { createRoute } from 'sparkx/react';
import { Error404 } from 'views/Error';
import { Welcome, WelcomeCtrl } from 'views/Welcome';

/**
* This is the 'welcome' state. It is the default state (as defined by app.js) if no other state
* can be matched to the URL.
*/
const welcomeState = createRoute({
component: Welcome,
controller: WelcomeCtrl,
name: 'welcome',
url: '/welcome',
});

/**
* Error state. If the user is routed to an unregister route,
* then the usere is redirected to this page.
*/
const errorState = createRoute({
component: Error404,
name: '404',
url: '/notFound',
});

/**
* This is just a place holder for posts route.
* It will be lazy loaded when user navigates to any posts route.
*/
const booksFutureState = createRoute({
lazyLoad: () => import('views/Books'),
name: 'books.**',
url: '/books',
});

export default [welcomeState, booksFutureState, errorState];
```

##### Creating a Controller

Creating a controller for a view is optional. To create a controller, the class must extend `ControllerBase` class (Detailed docs available [here](./docs/classes/_core_controllerbase_.controllerbase.md)). Each controller will be injected with 4 private members as described below:

* `this._scope`: Local scope of the view and controller.
* `this._setScope`: Method to update the local scope. This works similar to `setState` function in react. The object provided as an argument to this method will be spread over the previous state. The initial state is an empty object `{}`.
* `this._global`: The global scope of the application.
* `this._setGlobal`: Method to update the global scope. All public methods in controllers are exposed as props in react component (view of the application). Like in example below, `login` method is exposed in react component as prop.

```TypeScript
import { ControllerBase } from 'sparkx/core';
import { RoutingService } from 'sparkx/react';

/**
* Welcome Controller
*/
class WelcomeCtrl extends ControllerBase<any, any> {
/**
* Routing Service
*/
private _routingService: RoutingService = new RoutingService();

/**
* Logs in the user.
*/
public login = (response: any) => {
this._routingService.goTo('books');
this._setGlobal({
auth: response.profileObj,
});
}
}

export default WelcomeCtrl;
```

##### Creating a Service

A service can be created for any application logic which spreads across views. A service can be created simply by extending `ServiceBase` class (Detailed docs available [here](./docs/classes/_core_servicebase_.servicebase.md)). `HTTPService` is available in sparkx which helps in managing api calls (Detailed docs available [here](./docs/classes/_services_httpservice_.httpservice.md)). `HTTPService` internally uses [axios](https://github.com/axios/axios) to make requests. Extending `ServiceBase` class ensures that the service is a singleton.

```TypeScript
import { AxiosPromise } from 'axios';
import { ServiceBase } from 'sparkx/core';
import { HTTPService } from 'sparkx/services';

/**
* Service for Google Books apis.
*/
class GoogleBooksService extends ServiceBase {
/**
* Google Books Endpoint for apis.
*/
private endpoint = 'https://www.googleapis.com/books/v1';

/**
* Reference for HTTP service.
*/
private httpService = new HTTPService();

/**
* API to search for book by name.
*/
public searchBooks(bookName: string, start: number = 0, items: number = 20)
: AxiosPromise<IBookList> {
return this.httpService.get(`${this.endpoint}/volumes`, {
maxResults: items.toString(),
q: bookName,
startIndex: start.toString(),
});
}

/**
* API to get book by ID
*/
public getBook(id: string, errorHandled?: boolean): AxiosPromise<IBookDetail> {
return this.httpService.get(`${this.endpoint}/volumes/${id}`, null, null, { errorHandled });
}
}

export default GoogleBooksService;
```

### Demo Application

React: [https://github.com/pushkar8723/react-boilerplate](https://github.com/pushkar8723/react-boilerplate)

##### [MIT License](./LICENSE)

## Index

### External modules

* ["core/ControllerBase"](modules/_core_controllerbase_.md)
* ["core/ServiceBase"](modules/_core_servicebase_.md)
* ["core/index"](modules/_core_index_.md)
* ["core/model/globalReducer"](modules/_core_model_globalreducer_.md)
* ["core/model/index"](modules/_core_model_index_.md)
* ["core/model/scopeReducer"](modules/_core_model_scopereducer_.md)
* ["core/stateManagement"](modules/_core_statemanagement_.md)
* ["core/types"](modules/_core_types_.md)
* ["index"](modules/_index_.md)
* ["react/App"](modules/_react_app_.md)
* ["react/RoutingService"](modules/_react_routingservice_.md)
* ["react/index"](modules/_react_index_.md)
* ["react/route"](modules/_react_route_.md)
* ["services/HTTPService"](modules/_services_httpservice_.md)
* ["services/index"](modules/_services_index_.md)
* ["core/src/ControllerBase"](modules/_core_src_controllerbase_.md)
* ["core/src/ServiceBase"](modules/_core_src_servicebase_.md)
* ["core/src/index"](modules/_core_src_index_.md)
* ["core/src/model/globalReducer"](modules/_core_src_model_globalreducer_.md)
* ["core/src/model/index"](modules/_core_src_model_index_.md)
* ["core/src/model/scopeReducer"](modules/_core_src_model_scopereducer_.md)
* ["core/src/stateManagement"](modules/_core_src_statemanagement_.md)
* ["core/src/types"](modules/_core_src_types_.md)
* ["react/src/App"](modules/_react_src_app_.md)
* ["react/src/RoutingService"](modules/_react_src_routingservice_.md)
* ["react/src/index"](modules/_react_src_index_.md)
* ["react/src/route"](modules/_react_src_route_.md)
* ["services/src/HTTPService"](modules/_services_src_httpservice_.md)
* ["services/src/index"](modules/_services_src_index_.md)

---

54 changes: 0 additions & 54 deletions docs/classes/_core_servicebase_.servicebase.md

This file was deleted.

Loading

0 comments on commit d594c25

Please sign in to comment.