Skip to content

Commit

Permalink
implemented organizer feature for the build process. this was made to…
Browse files Browse the repository at this point in the history
… avoid the usage of something before its definition
  • Loading branch information
wpdas committed Mar 7, 2024
1 parent b6a6955 commit 50770e7
Show file tree
Hide file tree
Showing 3 changed files with 197 additions and 1 deletion.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ Alem is a web3 JavaScript / TypeScript library for building user interfaces for
- **Declarative:** Alem makes it painless to create interactive UIs. Design simple views for each state in your application, and Alem will efficiently update and render just the right components when your data changes. Declarative views make your code more predictable, simpler to understand, and easier to debug.
- **Component-Based:** Build encapsulated components that manage their own state, then compose them to make complex UIs. Since component logic is written in JavaScript, you can easily pass rich data through your app.
- **Learn Once, Write Anywhere:** We don't make assumptions about the rest of your technology stack, so you can develop new features in Alem without rewriting existing code.
- **CSS:** Alem supports .css files. Just create them and they will all be included in the application.
- **Easy State Management:** Use state management to make it easier to process data through the application.
- **Routes System:** An integrated router system that makes it possible to navigate between pages easily.
- **Much more:** Take a look at the other documentation items to learn how to use all the features provided by Alem.

[**Learn how to use Alem in your project**](https://near.org/alem-lib.near/widget/Index).

Expand Down
22 changes: 21 additions & 1 deletion lib/build.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ const { read_bos_config } = require("./config");
const pkg = require("../package.json");
const path = require("path");
const fs = require("fs");
const {
checkImportFeatures,
checkFeaturesMarker,
replaceMarkers,
} = require("./organize.js");

const distFolder = process.env.DIST_FOLDER || "build";

Expand Down Expand Up @@ -82,10 +87,25 @@ function process_dist() {

// loop through all files inside the './src' and get their content
for_rfile(path.join(".", "src"), ["js", "jsx", "ts", "tsx"], (file) => {
// Verifica se a instancia dos objetos importados já estão no bundle body
// caso nao esteja, adicinar marcadores para inserir na posicao correta
// mais tarde
const pendingInstances = checkImportFeatures(file, fileBundleBody);
// console.log("PENDING INSTANCES", pendingInstances);
fileBundleBody += pendingInstances;

const fileBody = process_file(file);
fileBundleBody += fileBody;

// Verificar se já existe um marcador de espaço para as instancias
// deste arquivo, se existir, deve colocar o conteúdo no espaço
// do marcador criado para ele
fileBundleBody = checkFeaturesMarker(fileBody, fileBundleBody);

// fileBundleBody += fileBody;
});

fileBundleBody = replaceMarkers(fileBundleBody);

// finish the file body with the app indexer
fileBundleBody += process_file(
path.join(__dirname, "tools", "appIndexer.jsx"),
Expand Down
172 changes: 172 additions & 0 deletions lib/organize.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
/**
* Organize the sequence of instances and dependencies following an order of dependency.
*
* This is to avoid the usage of something before its definition
*/

const fs = require("fs");

const ELEMENT_SPACE_MARKER = ":::SM:::";

function buildSpaceMarker(elementName) {
return `${ELEMENT_SPACE_MARKER}${elementName}${ELEMENT_SPACE_MARKER}`;
}

function instanceElementExistsInBody(elementName, bundleBody) {
// Verificar se já tem algum "const/let/var <elementName>" no corpo do arquivo
// se nao tiver, criar marcador de espaço para este elemento
// se tiver, apenas ignora

return Boolean(
bundleBody.includes(`const ${elementName}`) ||
bundleBody.includes(`let ${elementName}`) ||
bundleBody.includes(`var ${elementName}`),
);
}

/**
* Vefirica se as instancias dos imports do arquivo já estao presentes dentro do bundleBody, caso não
* esteja, cria um marcador de espaço para alocar esse conteúdo pendente posteriormente.
*
* Isso é importante para manter as instancias na ordem correta e não ocorrer um error onde
* um recurso é chamado antes de ser implementado.
* @param {*} file
* @param {*} fileBundleBody
* @returns
*/
function checkImportFeatures(file, fileBundleBody) {
const fileContent = fs.readFileSync(file, "utf8");
const foundItems = fileContent.match(/(?<=import)(.*?)(?=from)/gm);

// List de pontos de espaço para inserir os conteúdos pendentes
let markers = "";

if (foundItems) {
foundItems.forEach((item) => {
// remove spaces and braces
const filteredItem = item
.replaceAll(" ", "")
.replaceAll("{", "")
.replaceAll("}", "");

// Check if there are more than one item
if (filteredItem.includes(",")) {
const subItems = filteredItem.split(",");
subItems.forEach((subItem) => {
if (!instanceElementExistsInBody(subItem, fileBundleBody)) {
// Insere um marcador de espaço para este elemento
markers += `
${buildSpaceMarker(subItem)}
`;
}
});

return;
}

if (!instanceElementExistsInBody(filteredItem, fileBundleBody)) {
// Insere um marcador de espaço para este elemento
markers += `
${buildSpaceMarker(filteredItem)}
`;
}
});
}

return markers;
}

const listInstancesContent = [];

/**
* Verifica sem tem marcadores pendentes para as instancias dentro do corpo
* do arquivo atual, se tiver, coloca o conteúdo deste arquivo no marcador
* em questão
* @param {*} fileBody
* @param {*} bundleBody
*/
function checkFeaturesMarker(fileBody, bundleBody) {
// Regexp: buscar por palavras depois de const, let e var
const foundItems = fileBody.match(
/(?<=\bconst\s)(\w+)|(?<=\blet\s)(\w+)|(?<=\bvar\s)(\w+)/,
);

// Checar se possui marcador de espaço para as instancias encontradas
let hasMarker = false;
foundItems.forEach((instance) => {
if (bundleBody.includes(buildSpaceMarker(instance)) && !hasMarker) {
hasMarker = true;

listInstancesContent.push({
instanceName: instance,
marker: buildSpaceMarker(instance),
content: fileBody,
});
}
});

// Se nenhum marcador for encontrado, simplesmente adiciona o conteúdo
// do arquivo atual ao conteúdo do bundle
if (!hasMarker) {
bundleBody += fileBody;
}

return bundleBody;
}

/**
* Troca os marcadores por seu respectivo conteúdo. Também verifica se um conteúdo de outro
* marcador deve ser colocado acima do marcador sendo tratado no momento.
*
* @param {*} bundleBody
* @returns
*/
function replaceMarkers(bundleBody) {
// console.log("LISTAAAA:", listInstancesContent);
const completed = [];

// Varre a lista de instancias marcadas
listInstancesContent.forEach((instanceContent, index) => {
// Para cada marcador, verificar se dentro dele esta sendo usado a outras instancias
// dentro do "listInstancesContent". Se tiver, coloca primeiro o conteúdo dessa instancia
// e só depois coloca o conteúdo da instancia atual. Se isso ocorrer, deve-se remover
// a instancia adicional colocada acima da lista "listInstancesContent"
let markerContent = "";

if (!completed.includes(instanceContent.instanceName)) {
// Verifica sub items
listInstancesContent.forEach((subInstanceContent, subIndex) => {
// Se nao for o mesmo item e o item principal tem parte do item secundario...
if (
instanceContent.content.includes(subInstanceContent.instanceName) &&
instanceContent.instanceName !== subInstanceContent.instanceName
) {
// Possui o sub item, coloca o conteúdo do subitem primeiro
// listInstancesContent[subIndex].done = true;
completed.push(listInstancesContent[subIndex].instanceName);
markerContent += listInstancesContent[subIndex].content;
}
});

// Coloca o conteúdo do item principal
// listInstancesContent[index].done = true;
completed.push(listInstancesContent[index].instanceName);
markerContent += listInstancesContent[index].content;

// Adiciona o conteudo do marcador no corpo do bundle principal
bundleBody = bundleBody.replace(instanceContent.marker, markerContent);
}
});

// Remove o restante dos marcadores que não foram tratados. Esses possivelmente são
// de biblitecas, nao de arquivos do projeto
bundleBody = bundleBody.replaceAll(/(:::SM:::)(.*?)(:::SM:::)/g, "");

return bundleBody;
}

module.exports = {
checkImportFeatures,
checkFeaturesMarker,
replaceMarkers,
};

0 comments on commit 50770e7

Please sign in to comment.