title |
---|
Overview |
Development of the interstellar
project has been paused. Please check out the JS Stellar SDK docs for how integrate with Stellar using JavaScript.
The Interstellar Module System is an open ecosystem of modules that aims to make it easy to build a web application on the Stellar network. This repository (interstellar
) contains a command line tool that standardizes the build process for Stellar web applications based on the module configuration.
Read the introductory blog post, get started or take a look at interstellar-client to see the system in action.
This document will guide you through main concepts and advantages of Interstellar Module System and will help you develop your first Interstellar application.
- Why Interstellar?
- Quick Overview
- Prerequisites
- Installing
interstellar
command line tool - Generating sample app
- Interstellar application architecture
- Where to go from here?
- Get a Stellar testnet account
- List of modules
People often think of modularity in silos:
- Feature modules
- Interface modules (header, navigation, buttons, tables)
- Code modules (libraries, services, dependencies)
Interstellar aims to connect disparate models of modular systems into one holistic, expressive, interconnected system.
- Development of different apps from reusable, modular pieces of the same system
- Development of features without codependencies (i.e., no house-of-cards style collapsing if you decide to pull out one feature)
- On-the-fly tests of beta features without impact on existing features
- Easy third-party customization
Before you start make sure you have Node v0.10 installed (use nvm if you don't) and npm.
Interstellar is written in JavaScript. We're using ECMAScript 6 standard thanks to Babel and Webpack for bundling. Knowledge of AngularJS will be very helpful.
Please install Yeoman to quickly generate sample project in this tutorial:
npm install -g yo generator-interstellar
interstellar
command line tool will help you build and develop your projects. To install interstellar
run:
npm install -g interstellar
Make sure it's successfully installed by running interstellar stroopy
. You may want to check out Stroopy adventures too :).
Let's start with bootstrapping our application using yo
:
mkdir sample-app
cd sample-app
yo interstellar sample-app
Now, simply run: interstellar develop
and a browser window with a sample app should open.
Let's look at our sample app code and discuss the most important parts. If you have no experience with ECMAScript 6 code, please read about ES6 features.
Open main.es6
file. In the top of the file you will notice import
statements:
import interstellarCore, {App, Inject, Intent} from "interstellar-core";
import interstellarSessions from "interstellar-sessions";
import interstellarNetwork from "interstellar-network";
import interstellarNetworkWidgets from "interstellar-network-widgets";
The most important concept of Modular Client System is modularity. Right now, there are several modules that provides different kinds of functionality for developers and interstellar-network
and interstellar-sessions
are two of them.
Modules can:
- Export helpful classes like
App
,Inject
andIntent
in the example above. - Create angular providers, services, filter and directives that can be used by other modules and apps.
interstellar-core
addsinterstellar-core.Config
service that allows to read configuration variables by other modules. - Create widgets that can be used by application developers. You can read more about widgets below.
As mentioned above interstellar-core
provides some interesting classes and App
is one of them. App
instance represents a single Interstellar application. To create an app we need to pass two parameters to a constructor: application name and application config:
let config = require('./config.json');
export const app = new App("sample-app", config);
Conceptually, an application's configuration presents itself as a simple nested json object. The interesting part, however, is that you can not only configure your application but also modules you included. When no modules configuration is present in you app config a module sets its default values. However, sometimes you may want to change it, for example horizon server hostname. To do it, simply add modules.{module-name}
field in your config json and extend it with your custom variables. For example:
{
"nested": {
"value": true
},
"modules": {
"interstellar-network": {
"horizon": {
"server"
}
}
}
}
To get a configuration variable you can use interstellar-core.Config
service.
let value = Config.get('nested.value');
console.log(value) // true
Every module that will be used by an app must be registered with use
method, like:
app.use(interstellarCore);
app.use(interstellarSessions);
app.use(interstellarNetwork);
app.use(interstellarNetworkWidgets);
This will make all Angular parts of a module (providers, services etc.) accessible from your app.
An application can contain its own Angular elements like controllers, services, templates etc. They are autoloaded using following code:
app.controllers = require.context("./controllers", true);
app.templates = require.context("raw!./templates", true);
We're using Webpack require.context to load many files at the same time.
We can configure app's ui-router:
app.routes = ($stateProvider) => {
$stateProvider.state('index', {
url: "/",
templateUrl: "sample-app/index"
});
$stateProvider.state('balance', {
url: "/balance",
templateUrl: "sample-app/balance"
});
};
And finally, we can add Angular config
and run
blocks.
After adding all elements we can bootstrap the app using:
app.bootstrap();
Modules (and apps) in Interstellar communicate by broadcasting Intent
objects using an Android-inspired intent system. Modules can:
- Broadcast Intents to trigger some events in other modules,
- Register Broadcast Receivers to listen to Intents sent by other modules.
Every Intent has a type which must be one of standard intent types. For a complete list of Intent types please check interstellar-core
documentation.
Broadcast Receivers should be registered in run
phase:
let registerBroadcastReceivers = ($state, IntentBroadcast) => {
IntentBroadcast.registerReceiver(Intent.TYPES.SHOW_DASHBOARD, intent => {
$state.go('balance');
});
};
registerBroadcastReceivers.$inject = ["$state", "interstellar-core.IntentBroadcast"];
app.run(registerBroadcastReceivers);
Intents are sent using interstellar-core.IntentBroadcast
service's sendBroadcast
method. Let's analyze how a controller can broadcast an Intent, open: index.controller.es6
file:
this.IntentBroadcast.sendBroadcast(
new Intent(
Intent.TYPES.SHOW_DASHBOARD
)
);
SHOW_DASHBOARD
intent tells all receivers that user should see your application dashboard. You can see that our broadcast receiver changes a current state of router to our dashboard.
Intent system is the important mechanism of communication between widgets.
Interstellar application is the AngularJS application and it also makes use of Dependency Injection design pattern which Angular implements. In Interstellar you can use $inject
property annotation to inject services but you can also use @Inject
decorator provided by interstellar-core
module like this:
import {Inject} from 'interstellar-core';
@Inject("interstellar-core.Config", "interstellar-core.IntentBroadcast", "interstellar-sessions.Sessions")
class IndexController {
constructor(Config, IntentBroadcast, Sessions) {
// constructor code
}
}
Important thing to notice is how services names are generated. Basically, a service name is a concatenation of module name and service name with a dot in the middle. Check a table below to find out how other artifacts names are generated:
Artifact type | Artifact name | Generated name |
---|---|---|
Controller | FooController |
interstellar-module.FooController |
Directive | fooDirective |
interstellar-module-foo-directive |
Service | FooService |
interstellar-module.FooService |
Provider | FooProvider |
interstellar-module.FooProvider |
The last important part of Interstellar we will mention in this document are widgets. Widgets are complex solutions that are reponsible for a single task, like: showing account balances. They consist of templates, controllers and directives. Widgets can be used by writing a directive name in your application template:
<interstellar-network-widgets-balance></interstellar-network-widgets-balance>
As with services, widget name is a concatenation of module name and service name but this time with a hyphen in the middle.
You can find full list of classes, services and widgets provided by each module in its documentation.
- Join our Slack channel to discuss Interstellar and share ideas!
- Help us develop our interstellar-client.
- Fix issues in Interstellar modules.
- Develop your own module!
The yeoman generator generates a testnet account for you automatically, but you can also create one for yourself using our friendbot.