Git Product home page Git Product logo

Comments (6)

B3rn475 avatar B3rn475 commented on June 10, 2024

Hi.

First of all, you should take a look at https://github.com/B3rn475/almostjs which is the Model-to-"Anything" framework that is used by the project.

  • ALMOsT-Core provides a basic "map from a JavaScript object to any number of other object" framework with a highly customizable "reducer".
  • ALMOsT-Extend gives you, if you follow some simple rules in structuring your Model, a set of helpers to navigate the model. The main requirement is that your model is organized as a set of elements connected to each other via relationships.
  • ALMOsT builds on top of ALMOsT-Core, following the rules from ALMOsT-Extend, and privides you a simple way to write rules that apply to specific elements or relationships in your model (a.k.a. rules) and provides you somer default aggregators, i.e. Model To Model, Model To Almost (if you follow a specific structure the reducer can do more for you) or Model To Text. One nice property is that you can easily chain transformation.

The main concept you need to know about is "there are different types or Rules".

  • Model Rules they apply once for the whole mode.
  • Element Rules they apply once for each element in the model.
  • Relation Rules they apply once for each relationship betwen elements in the model.

There are a few papers linked in the ALMOsT repository.

IFMLEdit.org uses these libraries as follows:

  • client/js/ifml/index.js exposes an extend() function that is the ALMOsT-Extend extender configured with common concepts from IFML.
  • In client/js/ifml2pcn you will find a Model To Model (technically Model To Almost) transformation that generates a PCN model from an IFML model.
  • In client/js/ifml2code you will find 4 different transformations
    • client generates a thick client implementation of the application, with the ability to implement data sorces and actions either locally or invoking REST APIs, or a bit of both.
    • server generates a server implementation of the application, with the ability to implement data sources and actions server-side; the thin client always routes requests to the server.
    • mobile is similar to client, but focuses on a more mobile oriented design.
    • flutter [beta] is similar to mobile, but generates Flutter code, instead of JavaScript.

All of them follow a Model To Text approach, see m2t tranformation in ALMOsT.
TL;DR: the model generates folders and files which are then stored inside a Zip file.

These generators generally use Model Rules to generate global files that cannot be mapped to a specific element. E.g. the package.json file is always going to be there, or, in general, it is related to the entire model and not to a specific element or relationship.
They, instead, use Element Rules to generate files that are specific to an element, e.g. in client/js/ifml2code/client/elementrules/action.js there is a Rule that generates, for each action, a file implementing it.
There are no Relation Rules in these transformation only because the IFML model used here stores the Flows as entities, so, up to now, Element Rules were enough, but depending on what you need to do you may want to use them.

From a practical standpoint the Model Rules are stored in .../modelrules.js, while Element Rules are stored in the file of element they match against, e.g. ...elementrules/action.js focuses on Actions, while .../elementrules/viewcontainer.js on ViewContainers, ...

Taking a deeper dive into the rules you will notice that they are split into 2 functions. The first one decides if the rule applies, by returning a boolean, while the second actually generates the files/folders needed.

For practical purposes rules are generally implemented in 2 phases:

  1. Compute all the data needed to generate the files/folders.
  2. Generate
    • Folders are generated by just adding an element in the output object
    • Files are similar, but require the "content". To generate the content we invoke an ejs script that is implement in the .../templates folder next to it. We try to keep the templates as simple and linear as possible, if some complex decision needs to be made, we prefer to perform it in step (1) and just inject the information.

Now back to what you want to do

Depending on what you care about you may want to use either .../client or .../server as your starting point.
You probably want to add a new folder and copy the modelrules.js so that you can customize it.
Unless you have some specific requirement to alter the existing generated code, you can directly use the existing .../modelrules/*.js files and templates, this will guarantee that the generated files will be the same, and just add a few extra rules to generate the additional files/folder for Cypress.

If your rules are simple and easy to write, you could probably be happy already here.

But if you are having troubles...

How you can manage complexity

Depending on the complexity of what you want to do, you may even want to split your transformation in multiple stages.

Reasoning directly on IFML may be complicated in some cases.

A simple, but meaningful example.

You want to write a Model-to-Text transformation that generates SQL files needed to build a DB starting from an Entity-Relationship model.

If the original meta-model supports N-to-M relationships you cannot easily convert it directly in SQL, so it could be complicated to write the rules.

If you have the guarantee that you will only have 1-to-N relationships, the Model-to-Text transformation is way easier, right?

You can make your life easier by adding an intermediate Model-To-Model transformation that makes almost everything pass through "as-is", but transforms N-to-M relationships into a bridge Entity and the 2 1-to-N and a 1-to-M relationships. The output of this model can be then passed to a way simpler Model-To-Text transformation.

With ALMOsT this scenario is really easy complexModelToText(model) becomes simpleModelToText(simpleModelToModel(model)).

In your specific case, you can have the existing .../modelrules/*.js files take care of the generation of the application and, if you need to transform the model through multiple steps, a chain of transformations that generate the files for Cypress.
The output of the two can be naively merged together.

function serverWithCypress(ifmlModel) {
  var applicationFiles = client.transform(ifmlModel);

  var cypressFiles = cypress.modelToText(cypress.anyOtherTransformationNeeded(ifmlModel));

  return compact({...applicationFiles, ...cypressFiles});
}

Let me know if you have more questions.

from ifmledit.org.

AlexandroDRK avatar AlexandroDRK commented on June 10, 2024

Thank you very much, I'm glad to know that much of what I could infer just by analyzing the project is in fact valid. I've also read all the major articles related to almost and its components to understand how Ifmledit uses its rules. I intend to perform my implementation using the "server" transformation.

from ifmledit.org.

AlexandroDRK avatar AlexandroDRK commented on June 10, 2024

At first I intend to add new rules to the existing structure in order to reduce the initial implementation complexity. If necessary, I will be separating the new rules into a separate structure, but for this moment I will worry about leaving it working.

from ifmledit.org.

AlexandroDRK avatar AlexandroDRK commented on June 10, 2024

@B3rn475 I recently created a transform rule that should utilize the existing IFML transform framework. This rule should map the elements of an ifml template to a Cypress test script using the "form" stereotype. I also added the scripts template that should receive the data to assemble the script. However, when running the application, nothing is generated, as if the model data were not being provided to the template at the time of transformation. You could clone my fork, or just analyze my source code to suggest changes and/or show where I'm going wrong.

from ifmledit.org.

AlexandroDRK avatar AlexandroDRK commented on June 10, 2024

I would also like to know a way to debug the application code, since it is currently executed through the assets compiled using gulp routines. Maybe debugging the real-time execution flow would help me identify what's going wrong with my code.

from ifmledit.org.

B3rn475 avatar B3rn475 commented on June 10, 2024

You can easily debug the transformation in the browser. Just open the developer tools, find the file/line you care about in the source code and add a breakpoint.

from ifmledit.org.

Related Issues (20)

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.