Git Product home page Git Product logo

omega's Introduction

Special thanks

  • To @larsdecher , for letting me know about https://github.com/bures/mjml4-in-browser :
    • Indeed as I explain below, I have worked on projects, in which managing email campaigns, is a feature. And it happens to be the case in many of the projects I work on, starting with every time I commit to setup a devops infrastruture and team.
    • So I'am still interested in find out about new tools that process MJML.
    • What I wanna poin out here, is that htere might be a new approach to emails campaigns, considering those as involving content management. S we're speaking about a CMS to manage emails templates, right? And what is up today in the CMS world ? Headless CMS. Static sites generators turn into Static emails generators. And frol there we can hink of multi channel Headless CMS, that is, a Headless CMS able to manage multiple media, not only web site, but emails, facebook posts, tweets, @media.com articles, etc;... ALl relying on a set of static media generators, one generator for each media

Omega

Omega, is an evolution towards Angular 8, of the well known https://grapesjs.com.

It adds it a server-side, a distributed server-side, and makes it collaboration ready.

The whole IS distributed, as you'll see, and out-of-the box, just because git is, distributed.

Standing on the shoulders of giants.

How it all started

As I was working on a software that had to send e-mails, based on beautiful templates, I learned about MJML, a markup language designed and standardized by MailJet, in order to webdesign email templates, for mailing campaigns.

I then found out about a wysiwyg MJML editor, which happens to be a fork of GrapesJS.

That MJML editor, fork of GrapesJS, GrapesJS allow non-technical users (that barely know HTML, or a bit of web design, typically), to edit new email templates for their mailing campaigns, all on their own.

Which is exactly what I needed.

So I began working with this MJML editor, fork of GrapesJS :

  • Indeed, my first need was to find out how (and where) my users would persist each new email templates (for a given mailing campaign)
  • So digging into the MJML wysiwyg editor's behind the scene, I really quickly realized that its docuementation, was mainly reduced to that of its elder, the GrapesJS HTML wysiwyg editor 's documentation. Now working on the GrapesJS HTML wysiwyg editor 's documentation, I found out :
    • that both GrapesJS 's HTML and MJML wysiwyg editors were using a Javascript plugin mechanisms, that allows any developer to implement his own persistence module.
    • That this persistence module allows the developer to define how and where the editor's content is to be persited.
    • That a couple of Persistence Module are provided by the GrapesJS project team, like modules allowing to persist your edited template to firebase's firestore saas offer, cf. https://github.com/artf/grapesjs-firestore. That storage service, behind the scene is a no-sql document-oriented database. Well you can think of it as if it was MongoDB (And now I'm thinkng about Richard Stallman...).

So starting from there I had one good idea, plus two goods reasons, to fork GrapesJS, and launch a new project :

  • [The good idea] Make GrapesJS Collaboration-Ready (bring in a Git-based default Persistence Module) : Well I was first astonsihed to find out that there are no Git oriented persistence Module, So here I go with a good idea, people being able to collaborate / validate on a given new MJML / HTML template ! (MJML as Code / HTML as Code , or wasn't it code in the first place...?). I immediately realised that bringing in a new persistence module based on a git storage, not only makes GrapeJS Collaboration-Ready, but it makes it distributed. :
    • The GrapesJS initial Designer, still today, has a side company proposing SAAS hosted GrapesJS offers, where persisting and collaborating on files by teams is made easy (or so I hope for the customers of that company).
    • Using the Git Persistence Module, each collaborator uses his own server (the Omega server), most of the time a docker container on his own machine, and the git repos to persist and share with collaborators. No central Server needed here
  • [good reason no. 1] Bring in Dependency Injection it's a pure client app : no server there. Plus it's implemented in pure old fashioned JavaScript. So here there's an opportunity turning that into a pure Angular 8 PWA (Progressive Web App). If only that, for the sake of dependency injection (Thankfully, GrapesJS initial designer code relatively neat,but still, it's real old style JavaScript)
  • [good reason no. 2] Bring in a TDD Build Process since it's pure JavaScript, it's like there are zero build steps, and zero build process at all, so about the test stack, ouch.. Here Another Reason to bring webpack and Karma / Mocha / Jest / Jasmine

Omega in the guts

So :

  • Omega will be GrapesJS re-implemented in Angular 8 / TypeScript, plus a TypeScript server side :

    • defining a clean build process, pipeline-ready, for both the client, and the server.
    • using dependency injection, especially to implement the Persistence Module plugin mechanism (with an npm install [email protected], and a configuration for the build)
  • When a user editing an HTML or MJML template with Omega :

    • clicks the save button, a dialog box prompts the user to fill in commit message, and then the template is saved to a git repo with a :
    # The Omega user  doesn't know about the [/path/on/the/server] he just sees the file and directory 's tree inside [/path/on/the/server]. Plsu inside [/path/on/the/server] is where the git clone happened.
    export FILE_BEING_EDITED_WITH_OMEGA=/path/on/the/server/blackfriday-champions.mjml
    export COMMIT_MESSAGE="This is the text typed by the omega user, in the dialog box, through his web page, so angular app will fill that one up"
    git add $FILE_BEING_EDITED_WITH_OMEGA && git commit "$COMMIT_MESSAGE" && git push

Basically here, I soon understood that in order to actually have a Git Persistence Module, I HAD, to implement A RESTful API on a server, that the Angular App wil call :

  • Indeed, If I want to persist to a git repo, and collaborate with others, I have to be able to git clone it in a filesystem, inside a system where the git software is installed. I would dream of an implementation of git inside our browsers, using a browser managed virutal filesystem, etc...
  • Before we have all that, in our daily web browsers, well the easiest and fastest way to execute git commands, for an Angular 8 App, is to ask a REST ful API (the backend, the server) to do it :
    • we need a server with a RESTfull API,
    • inside a container which has git installed, why not a NodeJS / TypeScript / Swagger / https://github.com/steveukx/git-js stack,
    • and that way the Angular App can git clone "FIR_REPO_URI" && git add --all && git commit -m "message from omega user" && git push, just out of calling an OpenAPI-compliant RESTful API.

Dev+ops Tech Stack

Dev Tech Stack Bill Of Material

  • NVM,
  • NodeJS,
  • typescript,
  • [SWAGGER TO TYPESCRIPT] I'll use tsoa, which supports "injecting dependency injection", has good community (secruing support), and works with a template concept (so there's potential customization features here).
  • [TYPESCRIPT TO SWAGGER] Re-generate JSON or YAML config file from Generated Source Code : Also tsoa;
  • [RxJS/TypeScript] : using rxjs installed with all modules, including those required for using RxJS in TypeScript, cf. https://rxjs.dev/guide/installation#all-module-types-cjs-es6-amd-typescript-via-npm

About tsoa, what is perfect for Omega, is that tsoa documents on its root README.md how to handle file upload with RESTful API generated : https://github.com/lukeautry/tsoa#uploading-files

But there's one more thing

Yeah, I have as goal, to bring in dependency injection :

  • As to the Angular Client, well dependency injection is builtin Angular
  • As to my TypeScript / RESTful Endpoints, there is no depndency injection there. I'll bring dependency injection here using http://inversify.io/ (and then I'll try https://github.com/nestjs/nest) . InversifyJS and NestJS appeared to be the two most suitable, and mature existing DEpendency Injection Frameworks, for a NodeJS "server side".

Ops Tech Stack Bill Of Material

All that dev stack will give us artifacts (packages, stuff, bumblebees, whatever you call them) to deploy. Well we will containerize all those artifacts, to deploy and operate them in production.

So here is our bill of material :

  • A single host deployement target, consisting of a Virutal MAchine in which are provisioned docker and docker-compose.
  • Omega si provisioned with a docker-compose.yml file defining the following services :
    • Traefik.io as reverse proxy AND load balancer
    • An API Gateway to bind up all Endpoints, and manage subscribe plans, and centralize OpenAPI documentation. I'll use an API Gateway called Gravitee.io
    • One docker-compose service for each and every REST API Endpoint
    • One docker-compose service for statically serving the Angular Client from within inside a container endowed with the lightest production-ready HTTP statis server, my first (maybe not last) choice will be an alpine:nginx OCI base image.
  • Aside Omega, antoher docker-compose.yml will provision infrastructure :
    • Keycloak to setup O.I.D.C. (OpenID Connect) Identity Provider
    • HashiCorp Vault, to manage the Certification Authority Chain, in the target PKI, and manage TLS/SSL Certificates granted to each deployed Omega component.

TODO List

For a start I'll decompose all tasks in this section of the projet 's root README.md, before task management / scheduling is managed by a dedicated tool.

  • Implement a first RESTfull API Endpoint, using tsoa, swagger generator, without any RxJS. This Endpoint will be a very simple allowing you to multiply any two positive or null integers.
  • Add JWT authntication, then OpenID Connect, managed by Keycloak
  • Add a new Endpoint, that basically returns a list of text files, among a given set of files, inside a given folder :
    • the endpoint will always return a map :
      • key being the path of the file, relative to workspace root,
      • the mapped value being the actual files itself as binary content. The workspace is a folder inside the OCI container, in which the RESTful API runs.
    • This endpoint will later return an additional tree, to manage workspace, and make the RESTful API stateless :
      • it will never "be on this file in the workspace", and later "be on this other file in the workspace",
      • because the browser's SPA will manage that.
      • That will make the server-side stateless, and the solution scalable-ready for multi-tenancy /multi-users
      • and I today believe that it's a definitive classic technique, to "push everything that is stateful to the SPA", in order to make the backend stateless.
      • and to make it all stateless, regarding git operatyions : It will be required to [commit, push, and send a merge/pull request], only ONE FILE AT A TIME, so that merge conflicts can always be easy to resolve, displaying a nice diff window in Angular Material Design, when it's time to save. So don't see this as an actual workspace, keeping track of the "workspace 's state", which file has been commit, which has not, etc... SO users will never ever be bound to keep working with a given container.

omega's People

Contributors

jean-baptiste-lasselle avatar

Stargazers

 avatar  avatar

Watchers

 avatar  avatar

omega's Issues

HOW_TO_TRANSPOSE_IFRAMES_IN_ANGULAR

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.