@mnemotix/cortex-core

0.0.14 • Public • Published

Cortex Core

This is the main bundle that gathering all convenient toolkits to :

  • Fastly start a new Cortex-based application.
  • Create a new sharable Cortex bundle to share with every Cortex-based application.

Principle

The main idea to remember is that a Cortex-based application is no more than a bunch of bundles, costumized or not, cleverly placed in a React application and linked each other thanks to the excellent concept of dynamic routing from React Router V4.

Cortex-based application concepts

Skeleton

client/
    entrypoint.js  --> The client entrypoint for webpack
    Application.js --> Extends a Cortex Application.
    routes.js      --> A list of Cortex Routes
    schema/
        schema.json -->  Autogenerated JSON schema (https://json-schema.org/) 
    components/
      ...          --> All application related components
config/
    environment.js --> List of environment variables
resources/
    ...            --> All images/icons/fonts stuff.
locales/
    fr/
        labels.json --> A i18next label file.
    ...
server/
    entrypoint.js   --> The server entrypoint to start with node.
    schema/
        schemaBuilder.js --> The datamodel schema definition (that generates the two following schema files)
        schema.graphql   --> Autogenerated GraphQL schema
        schema.json      --> Autogenerated JSON introspection schema (useful for Idea GraphQL plugin)
    datastores/
        Session.js       --> Extends a SynaptixSession    
styling/
    semantic.less        --> Copy of semantic-ui-less/semantic.less (Needed to the compiler)
    theme.config         --> SemanticUI theme config definition
    theme/
      ... All less variables and less overrides files.
webpack.config.js
webpack.production.config.js   
package.json

Server side initialization steps.

1. Defining and building a schema

Defining a schema consists on expose a server/schema/schemaBuilder.js defined as following :

import {SchemaBuilder} from '@mnemotix/cortex-core';

export default new SchemaBuilder({
  typeDefs:  [] /* An array of GraphQL types (See Synaptix.js) */,
  resolvers: {} /* An object of GraphQL resolvers (See Synaptix.js) */,
  modelDefinitions: [] /* A list of ModelDefinitionAbstract (See Synaptix.js) */
});

For example if you want to use the FOAF ontology, Synaptix.js gives all resources defining the builder like so:

import {SchemaBuilder} from '@mnemotix/cortex-core';
import {Ontologies, mergeResolvers} from '@mnemotix/synaptix.js';

export default new SchemaBuilder({
  typeDefs: [].concat(Ontologies.foaf.schema.Types, Ontologies.foaf.schema.Mutations),
  resolvers: mergeResolvers(Ontologies.foaf.resolvers.Types, Ontologies.foaf.resolvers.Mutations),
  modelDefinitions: Ontologies.foaf.ModelDefinitions
});

Of course, this is highly customizable. You can define your own ontology. Please take a look on the standard ontologies defined in Synaptix.js to implement one.

The resulting schema files will be automatically generated a launch time (see entrypoint section).

  • server/schema/schema.graphql is the default GraphQL schema used by GraphQL server ans Relay compiler.
  • server/schema/schema.json is the introspection schema useful for IntelliJ Idea GraphQL Plugin
  • client/schema/schema.json is the JSON Schema (https://json-schema.org) usefull for generating forms (see @mnemotix/cortex-form bundle)

2. Create an entrypoint

The next step consists on defining a server entrypoint in server/entrypoint.js.

The launchApplication() magic function.

In this entrypoint you just have to call plug-n-play function to start the app.

import {launchApplication} from '@mnemotix/cortex-core';

launchApplication({
    Package, // This is the object related to package.json (needs a json-loader on Webpack)
    webpackDevConfig, //This is the Webpack config file.
    schemaBuilder, // This is the schema builder of the application
    bundles, //This list of bundles path (so as import/require path) used in the application. 
    generateGraphQLEndpoints, //GraphQL endpoints (detailed below)
    generateNetworkLayer //This is the network layer used to communicate with Synaptix middleware bus.
}).then(() => {
  /* app launched */
});

If you look to this function, you will see that it :

  • Print a beautiful banner.
  • Initialize and concatenate all environment variables defined in [bundle]/config/environment.js. See environment section
  • Initiate a connection to the Synaptix middleware bus
  • Setup an ExpressJS server.
  • Setup a Socket.IO websocket server binded to ExpressJS server.
  • Setup all ExpressJS server middlewares located in [bundle]/server/middlewares/index.js. See middleware section.
  • Setup a default SSO login/register endpoint. See graphQL endpoints section
  • Setup GraphQL endpoints
  • Initialize the Synaptix middleware adaptor. See Synaptix adaptor section.
Synaptix Adaptor

To interact with Synaptix middleware, the application needs to define three classes:

The Synaptix Adaptor

Located in server/datastores/Adapter.js

import {SynaptixAdapter} from '@mnemotix/cortex-core';

export default class Adapter extends SynaptixAdapter {
  init(){
    /* Called a startup. Usefull for example to instantiate application specific context connections */
  }
}

Note that if no initialisation is needed you can directly use the Cortex-Core SynaptixAdapter.

The Synaptix Session

Located in server/datastores/Session.js this class is instantiated for each GraphQL request (and more generally for all client user request).

This is in that class that you can add application specific middleware resolutions.

import {SynaptixSession} from '@mnemotix/cortex-core';

export default class Session extends SynaptixSession {
  createForExampleSpecificObject(){
    /* Retrieve here the services to communicate with Synatix middleware. See Synaptix.js.*/
  }
}
Instantiation of a network layer

The network layer is the lowest layer to communicate with Synaptix Middleware bus.

For example to connect the bus using AMQP, use a NetworkLayerAMQP class.

  import {NetworkLayerAMQP} from '@mnemotix/synaptix.js';
  import {SynaptixAdapter} from '@mnemotix/cortex-core';
  import {Session} from './datastores/synaptix/Session'; //See preceding section

  const amqpURL = `amqp://${process.env.RABBITMQ_LOGIN}:${process.env.RABBITMQ_PASSWORD}@${process.env.RABBITMQ_HOST}:${process.env.RABBITMQ_PORT}`;
  const networkLayer = new NetworkLayerAMQP(amqpURL, process.env.RABBITMQ_EXCHANGE_NAME);
  
  const datastoreAdapter = new SynaptixAdapter(schemaBuilder.generateModelDefinitionsRegister(), networkLayer, Session);

GraphQL Endpoints

An application can expose different GraphQL endpoints (Ex: one for the application, and one for a public API).

let graphQLEndpoints = [
    {
      endpointURI: '/graphql',  // The exposed URL
      graphQLSchema: schemaBuilder.generateExecutableSchema({ // This method of SchemaBuilder is a quick way to generate an executable GraphQL schema and the related physical files.
        printGraphQLSchemaPath: path.join(__dirname, 'schema/schema.graphql'),          // Points to [application]/server/schema/schema.graphql 
        printJSONSchemaPath: path.join(__dirname, 'schema/schema.json'),                // Points to [application]/server/schema/schema.json     
        printJSONSchemaDotOrgPath: path.join(__dirname, '../client/schema/schema.json') // Points to [application]/client/schema/schema.json     
      }),
      datastoreAdapter // The instance of SynaptixAdaptor (See preceding section)
    }
  ];

All together

For example, your entrypoint could look like this :

import path from 'path';
import Package from '../../package.json';
import webpackDevConfig from '../webpack.config';
import {SynaptixAdapter, launchApplication} from '@mnemotix/cortex-core';
import {NetworkLayerAMQP} from '@mnemotix/synaptix.js';

import Session from "./datastores/Session";
import schemaBuilder from "./schema/schemaBuilder";

const bundles = [
  path.resolve(__dirname, '../'),
  "@mnemotix/cortex-core",
  "@mnemotix/cortex-addressbook",
  "@mnemotix/cortex-profile",
  "@mnemotix/cortex-uploader",
  "@mnemotix/cortex-finder"
];


launchApplication({
    Package,
    schemaBuilder,
    webpackDevConfig,
    bundles,
    generateNetworkLayer: () => {
      const amqpURL = `amqp://${process.env.RABBITMQ_LOGIN}:${process.env.RABBITMQ_PASSWORD}@${process.env.RABBITMQ_HOST}:${process.env.RABBITMQ_PORT}`;
      return new NetworkLayerAMQP(amqpURL, process.env.RABBITMQ_EXCHANGE_NAME);
    },
    generateGraphQLEndpoints: (networkLayer) => {
      const datastoreAdapter = new SynaptixAdapter(schemaBuilder.generateModelDefinitionsRegister(), networkLayer, Session);
    
      return [
        {
          endpointURI: '/graphql',
          graphQLSchema: schemaBuilder.generateExecutableSchema({
            printGraphQLSchemaPath: path.join(__dirname, 'schema/schema.graphql'), /* Optionnal to print schema.graphql */
            printJSONSchemaPath: path.join(__dirname, 'schema/schema.json'),        /* Optionnal to print schema.json    */
            printJSONSchemaDotOrgPath: path.join(__dirname, '../client/schema/schema.json')        /* Optionnal to print schema.json    */
          }),
          datastoreAdapter
        }
      ];
    }
    })
.then()
.catch(error => console.log(error));

Client

Readme

Keywords

none

Package Sidebar

Install

npm i @mnemotix/cortex-core

Weekly Downloads

3

Version

0.0.14

License

Apache-2.0

Unpacked Size

1.33 MB

Total Files

128

Last publish

Collaborators

  • mrogelja
  • ndelaforge
  • qrichaud.mnemotix