Skypager
universal javascript runtime / feature framework
Install / Use
/learn @skypager/SkypagerREADME
Skypager
Universal, Fully Integrated, Cross Platform JavaScript Container that you can talk to.
Skypager is a framework agnostic library and toolchain for creating, building, publishing, deploying, and running JavaScript projects that you can talk to.
By talk to, I don't just mean literally, but more importantly conceptually. It provides you with concepts and modules that follow natural language patterns, which allow your code to take on a conversational style that happens to fit very well with the way JavaScript runs in all environments.
As an author of code, you only want to have to say the minimum, and still achieve the desired effect. This is much harder to do than it sounds, and so this library is an attempt to make that easier.
If you are a familiar with JAMstack style applications, skypager can be considered a batteries included framework for building applications in this style. But you can also develop React Native and Desktop applications with it, so its not a 100% overlap.
Skypager's Structure
This project is a monorepo which publishes many different packages, some are useful only when authoring JavaScript programs, some only run in node, some only run in the browser.
The Core Framework has a Node Variant as well as a Web Variant, which load Specific Features that might only be relevant to that particular platform (e.g. node or web only)
It also has specific helper classes that may work differently depending on the platform, but are designed to let your code say the same thing anyway.
The goal of the core framework is to enable you, as a an author of many JavaScript projects, to just simply talk to your code and tell it what you want, and let the runtime figure out what to do with that information.
The goal of the extended, optional elements of the framework, is to make it as easy as possible to work with many different types of modules in a consistent way on top of the core runtime.
Build-time and Runtime modules
Modules like @skypager/cli provide you with commands that can be used in the build / run / publish / deploy phases of your JavaScript projects.
@skypager/cli is a script runner that will
- run scripts found in your current project's
scriptsfolder first - if your project is a monorepo, it will search your own @scope for
scripts/ - run any built in scripts from any of the
@skypager/*modules you have installed that "provide" those scripts.
When your code is running, Skypager provides a global runtime singleton (like document or window in the browser) that has different APIs which can be used to build all of
the components that are needed to power a modern JavaScript application, whose state and logic might be spread across the browser and node APIs.
In node requiring skypager will always return the same object, with the same state. It will be rooted in the current project, the nearest package.json in your current working directory. It will also be tied to the current git repository.
Similarly, in the browser, the skypager global is a singleton that is tied to the current URL (the hostname and pathname components of the URL at least.)
These instances of the runtime are designed to work together. (Consider that there's often a one to one relationship between some package.json in your portfolio, and some URL or domain that you own.)
The build environment and run environment can be connected in many different ways, all of which make all different phases of the application development cycle more productive.
Installation
You can install the single package skypager which provides you with the latest versions of the @skypager/cli @skypager/runtime @skypager/node and @skypager/web modules.
This package has been around the longest, and is version 40.x.x.
It is a single package to install that depends on the scoped @skypager/* modules which are version 1.x.x, and released from the master branch of this repository.
$ yarn add skypager --save
Or if you prefer you can install the individual packages you need.
# for single page apps and node servers or scripts
$ yarn add @skypager/cli @skypager/node --dev
# for the browser builds, this is a runtime / production dependency
$ yarn add @skypager/web --save
Optional Modules
If you wish to take advantage of webpack build start and watch scripts, modeled after Create React App, you can install @skypager/webpack
$ yarn add @skypager/webpack --dev
If you wish to use MDX, and the Skypager Document Helper to be able to build cool things using your project's Markdown and JavaScript modules as a database, such as generate runnable, editable websites from your README.md
$ yarn add @skypager/helpers-document --save
If you wish to use various Google Services, which let you treat Google Spreadsheets as a Database or Google Docs as a CMS
$ yarn add @skypager/google @skypager/helpers-sheet @skypager/helpers-google-doc --save
CLI
Installing @skypager/cli will provide an executable skypager.
Typing skypager help will show you all of the commands available, these commands are simple node.js scripts that live in a scripts/ folder in various packages.
It searches:
- scripts found in your current project's
scriptsfolder - if your project is a monorepo, it will search your node_modules paths for projects in your @scope, to see if they "provide" any
scripts/ - it will search your node_modules paths for any
@skypager/*modules that "provide" those scripts.
You might want to write your project scripts with es6 style imports, or with language features that require transpilation before running natively.
So the skypager executable will look for the following flags, or environment variables, to enable transpilation of your es6 code so it runs in node.
When you run skypager
- with the
--babelCLI flag, we enable@babel/register - with the
SKYPAGER_BABEL=trueenvironment variable set, we do the same - with the
--esmCLI flag we enable the esm module - with the
SKYPAGER_ESM=trueenvironment variable set, we do the same.
Which you use is up to you. esm is great if you don't want non-standard language features but still want es6 import / export
See The CLI Docs for more information
Usage
Usage with webpack or other bundlers
// this will be either @skypager/node or @skypager/web depending on your build platform
import runtime from 'skypager'
runtime.start().then(() => {
console.log('Skypager Runtime Is Started')
})
Usage via script tag
<script type="text/javascript" src="https://unpkg.com/@skypager/web"></script>
<script type="text/javascript">
skypager.start().then(() => {
console.log('Skypager Runtime is Ready')
})
</script>
Designed to be Extendable
The runtime, while useful by itelf, is designed to be extended.
We can extend the runtime with different Helper Classes. Helpers are classes which represent any kind of source code document that you can eventually require as a JavaScript module (which if you use webpack, is literally everything.)
Examples of helpers that are currently provided by skypager include servers, clients, features, spreadsheets, markdown documents.
In the example below, we start with the core JS runtime and add some features.
import runtime from '@skypager/runtime'
import MyNotificationsFeature from '@my/features-notifications'
import MyLoggingFeature from '@my/features-logging'
import MyAnalyticsFeature from '@my/features-analytics'
import MyUserAuthenticationFeature from '@my/features-authentication'
const myRuntime = runtime
.use(MyUserAuthenticationFeature)
.use(MyNotificationsFeature)
.use(MyLoggingFeature)
.use(MyAnalyticsFeature)
export default myRuntime
With this module, you have encoded a standard base layer that all of your apps can share.
These apps should never need to solve authentication, notifications, logging, or analytics on their own. They get the benefit of these features just by using your runtime.
Just tell the runtime what it needs to configure your authentication feature for the current environment
runtime.feature('authentication').enable({
provider: 'firebase',
options: { ... }
})
and then any application can do what it usually does
import runtime from 'my-example-runtime'
const auth = runtime.feature('authentication')
const loginButton = document.getElementById('login-button')
loginButton.addEventListener('click', () => auth.login({ username, password }))
you can see how the application code can easily use aws or google or your own custom auth, and it never needs to change.
Extensions API
Extending the runtime with another module, relies on the following API
Your extension module can
