diff --git a/docs/router/use-location.md b/docs/router/use-location.md
index 26a0ca0..e146824 100644
--- a/docs/router/use-location.md
+++ b/docs/router/use-location.md
@@ -2,13 +2,15 @@
This hook returns the current location object. It can be useful if you'd like to perform some side effect whenever the current location changes.
+Use `useLocation().isRoutesReady` to get to know when the routes are ready to be accessed.
+
```ts
// http://127.0.0.1:8080/alem-lib.near/widget/Index?path=profile
import { useLocation } from "alem/hooks";
export const SomeComponent = () => {
const location = useLocation();
- console.log(location); // { pathname: "profile", routes: ["home", "profile"] }
+ console.log(location); // { isRoutesReady: true, pathname: "profile", routes: ["home", "profile"] }
return "";
};
diff --git a/lib/actions/addSignatures.js b/lib/actions/addSignatures.js
new file mode 100644
index 0000000..593b901
--- /dev/null
+++ b/lib/actions/addSignatures.js
@@ -0,0 +1,24 @@
+const path = require("path");
+const fs = require("fs");
+const alemPkg = require("../../package.json");
+
+const addSignatures = (bundleContent) => {
+ const projectPkg = JSON.parse(
+ fs.readFileSync(path.join("package.json"), "utf-8"),
+ );
+
+ const projectRepositoryLink =
+ projectPkg?.repository && typeof projectPkg?.repository === "string"
+ ? projectPkg?.repository
+ : projectPkg.repository?.url || "";
+
+ bundleContent = `
+ /** Bundle generated by Além Library v${alemPkg.version} - See more here: https://github.com/wpdas/alem */
+ ${projectRepositoryLink ? `/** Project repository: ${projectRepositoryLink.replaceAll("git+", "").replaceAll(".git", "")} */` : ""}
+ ${bundleContent}
+ `;
+
+ return bundleContent;
+};
+
+module.exports = addSignatures;
diff --git a/lib/actions/loadFilesContent.js b/lib/actions/loadFilesContent.js
new file mode 100644
index 0000000..6b7b177
--- /dev/null
+++ b/lib/actions/loadFilesContent.js
@@ -0,0 +1,80 @@
+const { process_file } = require("../parse");
+
+// Load App Files Content based on files schema
+// const loadFilesContent = (orderedFilesToImport) => {
+// let bundleFile = "";
+// orderedFilesToImport.forEach((filePath) => {
+// bundleFile += process_file(filePath);
+// });
+
+// return bundleFile;
+// };
+
+/**
+ * (Recommended)
+ * Load files based on the filePath sequence
+ */
+const loadFilesContent = (filesToLoad) => {
+ let bundleFile = "";
+ filesToLoad.forEach((filePath) => {
+ bundleFile += process_file(filePath);
+ });
+
+ return bundleFile;
+};
+
+/**
+ * NOTE: Esse modelo joga as dependencias pra cima
+ */
+// const loadFilesContentSendingImportsToTheTop = (filesSchema) => {
+// let bundleFile = "";
+
+// // 1 - carrega o "filePath"
+// // 2 - carrega os arquivos "toImport" acima do "filePath"
+// // 3 - verificar se o conteúdo já nao existe antes de adicionar
+// // se existir, ignora a adicao
+// // 4 - Se conteudo já existir e estiver abaixo do "filePath", remove ele
+// // e tras pra cima
+
+// const addContent = (content) => {
+// if (!bundleFile.includes(content)) {
+// bundleFile = `
+// ${content}
+
+// ${bundleFile}
+// `;
+// }
+// };
+
+// filesSchema.forEach((fileSchema) => {
+// const filePathContent = process_file(fileSchema.filePath);
+// addContent(filePathContent);
+
+// // Adiciona os "toImport" deste File Schema
+// fileSchema.toImport.forEach((dependencyFilePath) => {
+// const dependentFileContent = process_file(dependencyFilePath);
+
+// // Checa se o conteudo dependente já existe e se esta acima do elemento
+// // pai (filePath), se estiver embaixo, manda pra cima
+// const filePathPosition = bundleFile.indexOf(filePathContent);
+// const dependentPosition = bundleFile.indexOf(dependentFileContent);
+
+// // Se existir tanto um quanto outro...
+// if (filePathPosition > 0 && dependentPosition > 0) {
+// // Se o dependent estiver abaixo do filePathContent
+// if (dependentPosition > filePathPosition) {
+// // Remove o dependente do conteudo do bundle
+// // Ele vai ser adicionado dnv no "addContent" abaixo, só que
+// // acima do arquivo "filePath"
+// bundleFile.replace(dependentFileContent, "");
+// }
+// }
+
+// addContent(dependentFileContent);
+// });
+// });
+
+// return bundleFile;
+// };
+
+module.exports = loadFilesContent;
diff --git a/lib/actions/loadFilesInfo.js b/lib/actions/loadFilesInfo.js
new file mode 100644
index 0000000..2692904
--- /dev/null
+++ b/lib/actions/loadFilesInfo.js
@@ -0,0 +1,125 @@
+const path = require("path");
+const fs = require("fs");
+const helpers = require("../helpers");
+const { removeComments } = require("../parse");
+
+/**
+ * To be like:
+ *
+ * ```ts
+ * [
+ * {
+ * filePath: "file/path/ModuleFile.tsx",
+ * toImport: ["path/moduleFile1.tsx", "path/moduleFile2.tsx"]
+ * nextFilesToLoad: [
+ * "path/to/import/ModuleFile1.tsx",
+ * "path/to/import/ModuleFile2.tsx",
+ * ]
+ * },
+ * {...}
+ * {...}
+ * ]
+ * ```
+ *
+ * Then, load files in a unique bundle, filtering to not add duplicated content
+ */
+let contentOrderer = [];
+// Arquivos já processados (evita duplicidade)
+let processedFiles = [];
+// Lista em ordem de arquivos para carregar / importar
+let orderedFilesToImport = [];
+const processFileSchema = (filePath) => {
+ // Se estiver vazio no primeiro processo, adiciona o arquivo de entrada 1
+ // (entry point File)
+ if (orderedFilesToImport.length === 0) {
+ orderedFilesToImport.push(filePath);
+ }
+ // console.log("\n\n");
+ // console.log("Processando:", filePath, "||");
+ let parentFolder = ".";
+ if (filePath) {
+ const parentPathParts = filePath.split("/");
+ parentPathParts.pop();
+ parentFolder = parentPathParts.join("/");
+ }
+
+ let fileContent = fs.readFileSync(filePath, "utf8");
+
+ // Remove comments from file
+ fileContent = removeComments(fileContent);
+
+ const fileImportsPath = helpers.getImportsPath(fileContent);
+ const currentFileSchema = {
+ filePath: filePath,
+ // usado para guiar as proximas cargas
+ // pode ser deletado no final do processo
+ nextFilesToLoad: [],
+ toImport: [],
+ };
+ fileImportsPath.forEach((importPath) => {
+ // Usa src para inicio ou o caminho do pai do arquivo sendo processado atualmente
+ let importedFileContentPath = path.join(parentFolder, importPath);
+
+ importedFileContentPath = helpers.getFilePathWithType(
+ importedFileContentPath,
+ );
+
+ // Registra todos os arquivos que o arquivo atual pede para importar
+ if (importedFileContentPath) {
+ currentFileSchema.toImport.push(importedFileContentPath);
+ }
+
+ // Registra os arquivos necessarios para o arquivo atual (imports)
+ // Esse dado da seguimento na busca de dados dos arquivos dos imports
+ if (!processedFiles.includes(importedFileContentPath)) {
+ if (importedFileContentPath) {
+ currentFileSchema.nextFilesToLoad.push(importedFileContentPath);
+ orderedFilesToImport.push(importedFileContentPath);
+ } else {
+ console.log(
+ `${filePath} -> Arquivo dependente nao encontrado: ${importPath}`,
+ );
+ }
+
+ processedFiles.push(importedFileContentPath);
+ }
+ });
+
+ // Push current schema result
+ contentOrderer.push(currentFileSchema);
+
+ // Recursividade
+ // console.log("RECURSIVIDADE:");
+ currentFileSchema.nextFilesToLoad.forEach((fileToImport) => {
+ processFileSchema(fileToImport);
+ });
+};
+
+const loadFilesInfo = (entryFile) => {
+ // Reset state
+ contentOrderer = [];
+ processedFiles = [];
+ // NOTE: Nao esta sendo usado no momento porque esta usando o contentOrderer.filePath
+ // NOTE: contentOrderer.filePath funcionou melhor do que a sequencia do orderedFilesToImport
+ orderedFilesToImport = [];
+
+ // Start loading process
+ processFileSchema(entryFile);
+
+ // Finaliza o processo do contentOrderer deletando o campo "filesToImport"
+ // de todos os filhos, já que agora náo são mais necessarios
+ contentOrderer.map((item) => {
+ delete item.filesToImport;
+ return item;
+ });
+
+ return {
+ filesSchema: contentOrderer,
+ // orderedFilesToImport: orderedFilesToImport.reverse(),
+ orderedFilesToImport: contentOrderer
+ .map((schema) => schema.filePath)
+ .reverse(),
+ };
+};
+
+module.exports = loadFilesInfo;
diff --git a/lib/actions/saveFinalBundleFile.js b/lib/actions/saveFinalBundleFile.js
new file mode 100644
index 0000000..6a4b3d5
--- /dev/null
+++ b/lib/actions/saveFinalBundleFile.js
@@ -0,0 +1,19 @@
+const path = require("path");
+const fs = require("fs");
+const { read_bos_config } = require("../config");
+
+// Save final bundle file
+// Note: must save inside a ./src folder. This is the only folder bos-clir-rs recognizes
+const saveFinalBundleFile = (bundleContent) => {
+ const config = read_bos_config();
+ const finalFileName = config.isIndex
+ ? "Index"
+ : config.name.replaceAll(" ", "-").toLowerCase();
+
+ fs.writeFileSync(
+ path.join(`./build/src/${finalFileName}.jsx`),
+ bundleContent,
+ );
+};
+
+module.exports = saveFinalBundleFile;
diff --git a/lib/actions/toolsFiles.js b/lib/actions/toolsFiles.js
new file mode 100644
index 0000000..787c9dd
--- /dev/null
+++ b/lib/actions/toolsFiles.js
@@ -0,0 +1,68 @@
+const path = require("path");
+const { process_file } = require("../parse");
+const { read_bos_config } = require("../config");
+const { for_rfile } = require("../utils");
+
+const TOOLS_FOLDER = "../tools";
+
+const loadHeaderFilesContent = () => {
+ const config = read_bos_config();
+
+ // Utils
+ let bundleFileBody = process_file(
+ path.join(__dirname, TOOLS_FOLDER, "utils.js"),
+ );
+
+ // Components
+ bundleFileBody += process_file(
+ path.join(__dirname, TOOLS_FOLDER, "components.jsx"),
+ );
+
+ // State manager
+ bundleFileBody += process_file(
+ path.join(__dirname, TOOLS_FOLDER, "stateManager.jsx"),
+ );
+
+ // Routes manager
+ bundleFileBody += process_file(
+ path.join(__dirname, TOOLS_FOLDER, "routes.jsx"),
+ );
+
+ // Hooks
+ bundleFileBody += process_file(
+ path.join(__dirname, TOOLS_FOLDER, "hooks.js"),
+ );
+
+ // Check if AlemSpinner should be used
+ if (!config?.options?.showFallbackSpinner) {
+ bundleFileBody = bundleFileBody.replace(
+ "return ;",
+ 'return "";',
+ );
+ }
+
+ // Load .CSS files
+ // Loop through all .css files inside the './src' and get their content
+ bundleFileBody += "const alemCssBody = `";
+ for_rfile(path.join(".", "src"), ["css", "sass"], (file) => {
+ const fileBody = process_file(file);
+ bundleFileBody += fileBody;
+ });
+ bundleFileBody += "`;";
+
+ // Theme
+ bundleFileBody += process_file(
+ path.join(__dirname, TOOLS_FOLDER, "theme.jsx"),
+ );
+
+ return bundleFileBody;
+};
+
+const loadIndexerContent = () => {
+ return process_file(path.join(__dirname, TOOLS_FOLDER, "appIndexer.jsx"));
+};
+
+module.exports = {
+ loadHeaderFilesContent,
+ loadIndexerContent,
+};
diff --git a/lib/build.js b/lib/build.js
index 122593b..447bf2f 100644
--- a/lib/build.js
+++ b/lib/build.js
@@ -1,29 +1,13 @@
const { generate_data_json } = require("./data.js");
-const { create_dist, for_rfile, log } = require("./utils.js");
-const {
- process_file,
- removeComments,
- removeBlankLines,
- mimify,
- applyEnvironment,
- parseOptions,
-} = require("./parse.js");
-const { read_bos_config } = require("./config");
-const alemPkg = require("../package.json");
-const path = require("path");
-const fs = require("fs");
-const {
- checkImportFeatures,
- checkFeaturesMarker,
- replaceMarkers,
-} = require("./organize.js");
+const { create_dist, log } = require("./utils.js");
+const { compile_files } = require("./compiler.js");
const distFolder = process.env.DIST_FOLDER || "build";
// Main function to orchestrate the build script
async function build() {
create_dist(distFolder);
- process_dist();
+ compile_files();
generate_data_json();
}
@@ -38,125 +22,7 @@ async function build_with_log() {
log.sucess("Build complete");
}
-// walk through each app folder
-function process_dist() {
- const config = read_bos_config();
- const finalFileName = config.isIndex
- ? "Index"
- : config.name.replaceAll(" ", "-").toLowerCase();
-
- // built in utils
- let fileBundleBody = process_file(path.join(__dirname, "tools", "utils.js"));
-
- // built in components
- fileBundleBody += process_file(
- path.join(__dirname, "tools", "components.jsx"),
- );
-
- // built in state manager
- fileBundleBody += process_file(
- path.join(__dirname, "tools", "stateManager.jsx"),
- );
-
- // built in route manager
- fileBundleBody += process_file(path.join(__dirname, "tools", "routes.jsx"));
-
- // built in hooks
- fileBundleBody += process_file(path.join(__dirname, "tools", "hooks.js"));
-
- // check if AlemSpinner should be used
- if (!config?.options?.showFallbackSpinner) {
- fileBundleBody = fileBundleBody.replace(
- "return ;",
- 'return "";',
- );
- }
-
- // loop through all .css files inside the './src' and get their content
- fileBundleBody += "const alemCssBody = `";
- for_rfile(path.join(".", "src"), ["css", "sass"], (file) => {
- const fileBody = process_file(file);
- fileBundleBody += fileBody;
- });
- fileBundleBody += "`;";
- fileBundleBody += process_file(path.join(__dirname, "tools", "theme.jsx"));
-
- // loop through all files inside the './plugins' and get their content
- for_rfile(path.join(".", "plugins"), ["js", "jsx", "ts", "tsx"], (file) => {
- const fileBody = process_file(file);
- fileBundleBody += fileBody;
- });
-
- // 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);
-
- // 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"),
- );
-
- // Remove comments
- fileBundleBody = removeComments(fileBundleBody);
-
- // Remove blank lines
- fileBundleBody = removeBlankLines(fileBundleBody);
-
- // Apply ports - works for development only
- // this won't affect production because the state of enviroment is going to be
- // production
- fileBundleBody = applyEnvironment(fileBundleBody);
-
- // Apply changes depending of the config.options
- fileBundleBody = parseOptions(fileBundleBody);
-
- // Mimify
- fileBundleBody = mimify(fileBundleBody);
-
- // Add Alem signature + repository info if available
- // TODO: abstract this in a separated file
- const projectPkg = JSON.parse(
- fs.readFileSync(path.join("package.json"), "utf-8"),
- );
-
- const projectRepositoryLink =
- projectPkg?.repository && typeof projectPkg?.repository === "string"
- ? projectPkg?.repository
- : projectPkg.repository?.url || "";
-
- fileBundleBody = `
- /** Bundle generated by Além Library v${alemPkg.version} - See more here: https://github.com/wpdas/alem */
- ${projectRepositoryLink ? `/** Project repository: ${projectRepositoryLink.replaceAll("git+", "").replaceAll(".git", "")} */` : ""}
- ${fileBundleBody}
- `;
-
- // Note: Save unified file
- // Note: must save inside a ./src folder. This is the only folder bos-clir-rs recognizes
- fs.writeFileSync(
- path.join(`./build/src/${finalFileName}.jsx`),
- fileBundleBody,
- );
-}
-
module.exports = {
build,
- process_dist,
build_with_log,
};
diff --git a/lib/compiler.js b/lib/compiler.js
new file mode 100644
index 0000000..efdc138
--- /dev/null
+++ b/lib/compiler.js
@@ -0,0 +1,77 @@
+const { create_dist } = require("./utils");
+const path = require("path");
+const loadFilesInfo = require("./actions/loadFilesInfo");
+const toolsFiles = require("./actions/toolsFiles");
+const loadFilesContent = require("./actions/loadFilesContent");
+const {
+ removeComments,
+ removeBlankLines,
+ applyEnvironment,
+ parseOptions,
+ mimify,
+} = require("./parse");
+const saveFinalBundleFile = require("./actions/saveFinalBundleFile");
+const addSignatures = require("./actions/addSignatures");
+
+const distFolder = process.env.DIST_FOLDER || "build";
+
+function compile_files() {
+ create_dist(distFolder);
+
+ const entryFile = path.join(".", "src", "index.tsx");
+
+ // TEST
+ // #1 - Load imported files content
+ // NOTE: Fazer isso recursivo, carregando o conteudo de todos os arquivos
+ // e fazer todo o processo de carga dnv
+
+ const filesInfo = loadFilesInfo(entryFile);
+
+ // console.log("Files Schema:");
+ // console.log(filesInfo.filesSchema);
+
+ // NOTE
+ /**
+ * Se essa ordem abaixo nao funcionar, mudar a hierarquia de carga pra carregar
+ * linearmente todo os items do arquivo sendo processado.
+ */
+ // console.log("\n\n");
+ // console.log("Ordered Files to Import:");
+ // console.log(filesInfo.orderedFilesToImport);
+
+ // Tools -> Header contents
+ let bundleContent = toolsFiles.loadHeaderFilesContent();
+
+ // Load App files content
+ bundleContent += loadFilesContent(filesInfo.orderedFilesToImport);
+
+ // Tools -> Indexer
+ bundleContent += toolsFiles.loadIndexerContent();
+
+ // Remove the remaining comments
+ bundleContent = removeComments(bundleContent);
+
+ // Remove blank lines
+ bundleContent = removeBlankLines(bundleContent);
+
+ // Apply ports - works for development only
+ // this won't affect production because the state of enviroment is going to be
+ // production
+ bundleContent = applyEnvironment(bundleContent);
+
+ // Apply changes depending of the config.options
+ bundleContent = parseOptions(bundleContent);
+
+ // Mimify
+ bundleContent = mimify(bundleContent);
+
+ // Add sinatures
+ bundleContent = addSignatures(bundleContent);
+
+ // Save final bundle file
+ saveFinalBundleFile(bundleContent);
+}
+
+module.exports = {
+ compile_files,
+};
diff --git a/lib/dev.js b/lib/dev.js
index 92cbf3f..249706c 100644
--- a/lib/dev.js
+++ b/lib/dev.js
@@ -21,6 +21,7 @@ const GATEWAY_PATH = path.join(__dirname, "..", "gateway", "dist");
// Main function to orchestrate the dev script
async function dev(opts) {
let loading = log.loading(`Building the project for the first time`);
+
await build().catch((err) => {
loading.error();
log.error(err);
diff --git a/lib/helpers.js b/lib/helpers.js
new file mode 100644
index 0000000..2034362
--- /dev/null
+++ b/lib/helpers.js
@@ -0,0 +1,95 @@
+const fs = require("fs");
+const regexp = require("./regexp");
+
+// Get all elements imports. ex:
+/**
+ * [
+ 'AppBackground',
+ 'AppContainer',
+ 'Sidebar',
+ 'ContentView',
+ 'Footer',
+ 'Modals',
+ 'styled',
+ 'Row'
+ ]
+ */
+const getFileImportsElements = (fileContent) => {
+ let fileImports = [];
+ fileContent.match(/(?<=import)(.*?)(?=from)/gm).forEach((value) => {
+ value.split(",").forEach((subValue) => {
+ fileImports.push(
+ subValue.replaceAll(regexp.SPECIAL_CHARACTERS_AND_SPACES, ""),
+ );
+ });
+ });
+ return fileImports;
+};
+
+/**
+ * Get import statements only
+ * ex:
+ * import Sidebar from "./components/Sidebar";
+ * import ContentView from "./components/ContentView";
+ * @param {*} fileContent
+ * @returns
+ */
+const getImportStatements = (fileContent) =>
+ fileContent.match(regexp.IMPORT_STATEMENT);
+
+/**
+ * Get Import's path
+ * ex:
+ * give: import Sidebar from "./components/Sidebar";
+ * return: ./components/Sidebar
+ * @param {*} fileContent
+ * @returns
+ */
+const getImportsPath = (fileContent) => {
+ let result = [];
+ const importStatements = fileContent.match(regexp.IMPORT_STATEMENT_2);
+
+ if (importStatements) {
+ importStatements.forEach((value) =>
+ value
+ .match(regexp.BETWEEN_QUOTES)
+ .forEach((subValue) => result.push(subValue)),
+ );
+ }
+
+ return result;
+};
+
+/**
+ * Given a file path, try to return the path + file type (ts, tsx, js, jsx).
+ * It supports these types at the moment: ts, tsx, js, jsx
+ * @param {*} filePath
+ * @returns
+ */
+const getFilePathWithType = (filePath) => {
+ if (fs.existsSync(`${filePath}.ts`)) {
+ return `${filePath}.ts`;
+ } else if (fs.existsSync(`${filePath}.tsx`)) {
+ return `${filePath}.tsx`;
+ } else if (fs.existsSync(`${filePath}.js`)) {
+ return `${filePath}.js`;
+ } else if (fs.existsSync(`${filePath}.jsx`)) {
+ return `${filePath}.jsx`;
+ } else if (fs.existsSync(`${filePath}/index.ts`)) {
+ return `${filePath}/index.ts`;
+ } else if (fs.existsSync(`${filePath}/index.tsx`)) {
+ return `${filePath}/index.tsx`;
+ } else if (fs.existsSync(`${filePath}/index.js`)) {
+ return `${filePath}/index.js`;
+ } else if (fs.existsSync(`${filePath}/index.jsx`)) {
+ return `${filePath}/index.jsx`;
+ }
+ return null;
+};
+
+module.exports = {
+ getFileImportsElements,
+ getImportStatements,
+ getImportsPath,
+ getFilePathWithType,
+};
diff --git a/lib/organize.js b/lib/organize.js
deleted file mode 100644
index 0db4832..0000000
--- a/lib/organize.js
+++ /dev/null
@@ -1,175 +0,0 @@
-/**
- * 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 " 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
- // TODO: refactor using regexp
- 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;
-}
-
-let 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) {
- 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, "");
-
- // Reset the markers organizer list
- listInstancesContent = [];
-
- return bundleBody;
-}
-
-module.exports = {
- checkImportFeatures,
- checkFeaturesMarker,
- replaceMarkers,
-};
diff --git a/lib/parse.js b/lib/parse.js
index 31d3350..84bf73b 100644
--- a/lib/parse.js
+++ b/lib/parse.js
@@ -1,5 +1,4 @@
const fs = require("fs");
-// const path = require("path");
const sucrase = require("sucrase");
const { read_bos_config } = require("./config");
@@ -15,8 +14,6 @@ const sucraseOptions = {
function process_file(filePath) {
let fileContent = fs.readFileSync(filePath, "utf8");
- if (shouldSkipFile(fileContent)) return;
-
if (filePath.endsWith(".ts") || filePath.endsWith(".tsx")) {
fileContent = transpileTypescript(fileContent);
}
@@ -29,41 +26,6 @@ function process_file(filePath) {
return fileContent;
}
-const shouldSkipFile = (c) => /\/\*__@skip__\*\//.test(c);
-
-// process comment commands and replace content in files
-// const processCommentCommands = (fileContent, aliases, account) => {
-// // Process the aliases
-// if (aliases) {
-// for (let alias in aliases) {
-// let replacePattern = new RegExp(`/\\*__@replace:${alias}__\\*/`, "g");
-// fileContent = fileContent.replace(replacePattern, aliases[alias]);
-// }
-// }
-
-// // Replace the account
-// if (account) {
-// let accountPattern = /\/\*__@account__\*\//g;
-// fileContent = fileContent.replace(accountPattern, account);
-// }
-
-// return fileContent;
-// };
-
-// import modules from /modules folder
-// const importModules = (fileContent) => {
-// let importPattern = /\/\*__@import:(.+?)__\*\//g;
-// let match;
-
-// while ((match = importPattern.exec(fileContent)) !== null) {
-// let modulePath = path.join("./modules", `${match[1]}.js`);
-// let moduleContent = fs.readFileSync(modulePath, "utf8");
-// fileContent = fileContent.replace(match[0], moduleContent);
-// }
-
-// return fileContent;
-// };
-
// transpile typescript files to valid BOS Lang
const transpileTypescript = (fileContent) => {
const transpiledCode = sucrase.transform(fileContent, sucraseOptions).code;
@@ -158,12 +120,8 @@ const injectHTML = (html, injections) => {
};
module.exports = {
- // processCommentCommands,
process_file,
- // importModules,
- shouldSkipFile,
ignoreFiles,
- // noStringifyJsonFiles,
removeComments,
injectHTML,
removeExports,
diff --git a/lib/regexp.js b/lib/regexp.js
new file mode 100644
index 0000000..79bcdb0
--- /dev/null
+++ b/lib/regexp.js
@@ -0,0 +1,28 @@
+// # TODAS AS CARACTERES ESPECIAIS
+const SPECIAL_CHARACTERS = /[^0-9A-záéíóúàèìòùâêîôûãõç\s]/gm;
+// # TODAS AS CARACTERES ESPECIAIS E ESPAÇOS
+const SPECIAL_CHARACTERS_AND_SPACES = /[^0-9A-záéíóúàèìòùâêîôûãõç\s]|\s/gm;
+// # TUDO ENTRE import e from
+// ex: { AppBackground, AppContainer }
+const GET_ALL_BETWEEN_IMPORT_AND_FROM = /(?<=import)(.*?)(?=from)/gm;
+// # ALL SPACES
+const SPACES = /\s/g;
+// # LINE BREAKS
+const LINE_BREAKS = /\r?\n|\r/g;
+// # IMPORT STATEMENT. ex: import { AppBackground, AppContainer } from "./styles";
+const IMPORT_STATEMENT = /^(import)(?:.*?(as))?(?:.*?(as))?(?:.*?(from))*.*$/gm;
+const IMPORT_STATEMENT_2 =
+ /^[ \t]*(import)\s+(?:\{[^}]*\}|\w+)\s+(from\s+)?["']([^"']+)["'];?$/gm; // USAR ESSE!
+// # BETWEEN quotation marks
+const BETWEEN_QUOTES = /(?<=")(.*?)(?=")/gm;
+
+module.exports = {
+ SPECIAL_CHARACTERS,
+ SPECIAL_CHARACTERS_AND_SPACES,
+ GET_ALL_BETWEEN_IMPORT_AND_FROM,
+ SPACES,
+ LINE_BREAKS,
+ IMPORT_STATEMENT,
+ IMPORT_STATEMENT_2,
+ BETWEEN_QUOTES,
+};
diff --git a/lib/tools/hooks.js b/lib/tools/hooks.js
index 68da811..55ca262 100644
--- a/lib/tools/hooks.js
+++ b/lib/tools/hooks.js
@@ -11,5 +11,6 @@ const useLocation = () => {
return {
pathname: activeRoute,
routes,
+ isRoutesReady: routes && routes.length > 0,
};
};
diff --git a/package.json b/package.json
index fa2db78..5fbcb81 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
{
"name": "alem",
"description": "Create web3 applications for NEAR BOS with a focus on performance while using concepts that are based on ReactJS.",
- "version": "0.0.1-alpha.16",
+ "version": "0.0.1-alpha.17",
"main": "main.js",
"types": "index.d.ts",
"author": "Wenderson Pires - wendersonpires.near",
diff --git a/roadmap.md b/roadmap.md
index aec10e8..55ba2bd 100644
--- a/roadmap.md
+++ b/roadmap.md
@@ -1,5 +1,7 @@
- Implement support for Testnet.
-- Implement `loadExternalStyles` API to load external css files. - ✔
+- Implement `loadExternalStyles` API to load external fonts and css files. - ✔
- E2E Tests
- Add parameter `parameterName` for `Routes` component. This is going to allow changing the default route param name ("path") that's used to control and watch all routes. - ✔
- Implement feature to the compiler that changes the consts/lets/vars names to avoid conflicts.
+- Add support to tsconfig.json `baseUrl` and `paths`.
+- Support to use same const names in defferent files.
diff --git a/router.d.ts b/router.d.ts
index 65dbdce..d4b10a5 100644
--- a/router.d.ts
+++ b/router.d.ts
@@ -89,4 +89,8 @@ export declare const useLocation: () => {
* Routes available
*/
routes: string[];
+ /**
+ * Is routes ready?
+ */
+ isRoutesReady: boolean;
};