npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@mnemotix/cortex-core

v0.0.14

Published

Cortex Core -----------

Downloads

5

Readme

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