GithubHelp home page GithubHelp logo

frame-js / frame Goto Github PK

View Code? Open in Web Editor NEW
17.0 4.0 2.0 1003 KB

Frame is a flow based programming library for databases, APIs, utilities, objects, schemas and more!

License: MIT License

JavaScript 100.00%
frame orm library flow flow-based-programming flow-control databases api utilities schema

frame's Introduction

This project has moved to FlowJS

Why the move?

The code has been dranatically simplified and easier to reason about. Rather than trying to solve too many problems (like dynamic imports), it leaves these to your builder or toolchain of choice (New ES6 Imports can do this for you).

Instead, we now focus solely on Code Flow Control.


Frame

Frame is a flow based programming library for databases, APIs, utilities, objects, schemas and more!

Features:

  • Cross Platform - Runs everywhere Javascript does
  • Declarative style (tell the library WHAT you want, not how you want it) - 1 2 3 4
  • Custom module loaders (Browserify, Webpack, RequireJS, Github, Gist, GunDB, [any other module loader here])
  • Easy NodeRED-like Syntax
  • Modules known as Blueprints are easily shareable!
  • Blueprints have an extremely easy syntax, with Schema support.
  • Singletons offer optional Shared resources built right in! (New flows don't need multiple connections, etc)
  • Functions have a lot of freedom, they can use return values, Promises, async/await, or use the callback. Frame gets out of your preferred way/style of coding.

Coming Soon:

  • Full featured drag and drop Web + Electron IDE for building the future of apps
  • Mobile IDE (React Native) for iOS, Android, etc
  • Transpiling + Build steps for truly cross platform libraries
  • Hosted solution without having to upload your Blueprints somewhere (along with transpiling configurations)
  • Error propagation via the flow (with custom paths), without falling over

Pseudo-Examples:

Custom Loaders

// From Github files
const SomeBlueprint = Frame("git://pathToYourFile.js")

// From Github repos
const SomeBlueprintFromRepo = Frame("git://SomeOrganization/YourFavoriteRepo")

// From HTTP URLs
const BlueprintFromURL = Frame("http://example.com/yourFile.js")

// From many different databases and stores
const BlueprintFromDB = Frame("mongodb://fileInDb.js")

Easy syntax

Render HTML/CSS with a Message from a database (Gun)

Message
  .from(Gun) // Receive a message from a database
  .to(Schema) // Validate message format
  .to(HTML) // Convert to HTML
  .to(Style) // Dynamic styles!
  .to(RenderFunction) // Finally render it, using our own function

Order does not matter

// Example #1: Multiple event handlers (Left to right processing.)
Message
  .from(Slack)
  .from(Gitter)
  .to(Console)

// Example #2: (Right to left processing.)
Message
  .to(Console)
  .from(Slack)
  .from(Gitter)

Example #3: (Somewhere in the middle)
Message
  .from(Slack)
  .to(Console)
  .from(Gitter)

Using setters to chain to/from:

// Can be a function
Message.from = function(data, props, cb) {}

// Can be an arrow function
Message.from = (data, _, cb) => cb()

// Can be a Blueprint module
Message.from = Slack

// Can be a primitive value
Message.from = 'Something'

Blueprint.js Example:

Blueprint = {
  name: 'Console',

  in: function(data) {
    return console.log(data)
  },
}

Functional Programming:

function registerGunMessage() {
    gun.get(“app”).get(“users”).on(this.out)
}

Gun.from(registerGunMessage).to(Console)

Multiple flow paths (Coming soon):

Message.from(Gun).to(Schema).or.to(Error)

Fallback support for API, Databases, etc:

Message
  .from(Socket)
  .to(DB1)
  .or() // call it like a function
  .to(DB2)
  .or // can also be used with dot notation
  .to(DB3)
  .or
  .to(Sentry)
  .timeout(5000) // Timeouts for any of the Blueprints!

Property Descriptions for automatic destructuring:

Blueprint = {
  describe: {
    in: {
      firstPropName: 'Some property desscription.',
      secPropName: 'Some other prop description.',
    }
  }

  in: function(data, props) {
    // props.firstPropName
    // props.secPropName
  }
}

Multiple return styles:

Blueprint = {
  // Callback style - follows (err, data) callback convention
  in: function(data, props, callback) {
    callback(null, 'some data')
  },

  // return primitives
  in: function(data, props) {
    return 'some data'
  },
  
  // return promises
  in: function(data) {
    return new Promise(function(resolve, reject) {
      resolve('some data')
    })
  },
  
  // async/await
  in: async function(data) {
    return await someAsyncFunction()
  },
  
  // Out event
  in: function(data) {
    this.out('some data')
  },
}

More Examples coming soon!

frame's People

Contributors

bugs181 avatar dletta avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

frame's Issues

Improve ObjectModel with new types

Example:

{
  user: String, // Required
  age: ObjectModel.Optional, // Optional

  gravatar: [Image, Element], // oneOf
}

Added types would be:

  • Optional
  • Array
  • Null
  • Undefined
  • Falsey

Appropriate Error catching

Add blueprint.Frame.canCatch so we can determine whether an appropriate error path is available. Otherwise throw to main application. In addition, add .catch() API for all potential errors without error propagation handlers.

Progress:

  • blueprint.Frame.canCatch
  • .catch() API
  • .or() API

Bug: Stubbing init somehow ignores ObjectModel schema

Will need to look into why the init function is not being used in the Schema correctly.

Setup:

const Console = Frame('Console')

Testing init:

> Console.init = true
< true
> Console.to(function(){})
Error: Blueprint 'Console' could not initialize.
TypeError: undefined is not a function (near '...blueprint.init.call...')

Testing in:

> Console.in = true
Error: Expecting "in" to be one of "function", got "boolean"

Allow Frame to return final flow result as value

A value getter which resolves a Promise when last flow is complete. Great for one-off flows that aren't meant to be continuous.

Example:

let message = await Movie.from(IMDB).to(ShowTimes).value
console.log(message)

ObjectModel refactor

Overview Progress:

  • Add additional ObjectModel types
  • Get rid of unnecessary looping for left-over schema
  • De-duplicate code by using a protect() function
  • Restructure code so it is easier to read and maintain
  • Convert ObjectModel Errors to TypeErrors
  • Detect getter/setters and copy them appropriately

Add additional ObjectModel types:

  • Optional
  • Array
  • Null
  • Undefined
  • Falsey

Destructure properties

Using descriptions via the describe syntax on a Blueprint object, hands off parameter destructuring over to Frame for validating proper inputs and types.

Proposal (subject to change; and likely will to be the most flexible but easy to discern):

Blueprint = {
  ...

  describe: {
    init: {
      'Optional Message Format': 'The message format will transform messages of one type to another for blueprint intercompatibility.'
    },

    accepts: 'Any', // Something like IMDB: accepts: [Movie, Show, Actor]

    in: {
      'Message': 'Any',
    },

    out: {
      'Message': 'Any',
    },
  },
}

Allow blueprints to be a function.

Allowing blueprints to export themselves as a single function decreases the friction of development.

Use case:

Blueprint = function(...) {
}

Internally:

if (typeof Blueprint === 'function')
  Blueprint = { name: Blueprint.name,  in: Blueprint }

Bug: initBlueprint called multiple times while queue processes

Add initializing state. Due to the way flows are queued, initBlueprint may be called multiple times even though the blueprint is currently being initialized.

Example:

Called init for Message
Called init for Message
Called init for Message
socket.init config: { host: 'localhost', port: 8082 }
socket.init config: { host: 'localhost', port: 8082 }
socket.init config: { host: 'localhost', port: 8082 }
socket.init config: { host: 'localhost', port: 8082 }
socket.in: something

Code:

'use strict'

const Frame = require('Frame')

// Blueprints
const Message = Frame('Message')
const Console = Frame('Console')
const Socket = Frame('Socket')

// Setup websocket server
const socketConfig = {
  host: 'localhost',
  port: 8082,
}

const socket = Socket(socketConfig)

Message
  .from(socket, 'event')
  .to(Console)

Message
  .from(socket, '!')
  .to(Console)

function addAnother() {
  Message
    .from('something')
    .to(socket, 'another event')
}

addAnother()

Singletons should also be allowed to be instances

Singletons should also be allowed to be instances when it's fitting. Maybe perhaps determined by initializer. For example a Storage adapter may be a singleton for a specific connection/directory, but another singleton for a different directory. This essentially groups flows into singletons deterministically.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.