Skip to content

Commit

Permalink
Merge pull request #11 from wpdas/feature/new-importables
Browse files Browse the repository at this point in the history
Feature: new importable files
  • Loading branch information
wpdas authored Apr 8, 2024
2 parents ce2f362 + 4ce0e10 commit 2d00cb2
Show file tree
Hide file tree
Showing 20 changed files with 397 additions and 83 deletions.
25 changes: 7 additions & 18 deletions lib/actions/injectModules.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,40 +2,29 @@ const fs = require("fs");
const path = require("path");

const injectModules = (bundle) => {
const modulesPath = path.join(".", "modules.json");
const modulesPath = path.join(".", "alem.modules.json");
if (!fs.existsSync(modulesPath)) {
bundle = bundle.replace("const MODULES_IFRAME = {};", "\n");
bundle = bundle.replace("<script>:::MODULES_SRC:::</script>", "\n");
return bundle;
}

const modulesRaw = fs.readFileSync(modulesPath);
try {
JSON.parse(modulesRaw);
} catch (e) {
throw new Error(`./modules.json is not a valid json file`);
throw new Error(`./alem.modules.json is not a valid json file`);
}

const modules = JSON.parse(modulesRaw);

let modulesBundle = `const iframeModulesCode = \`\n`;
let accessKeys = "";
let modulesSrc = "";

const modulesKeys = Object.keys(modules);
modulesKeys.forEach((moduleKey, index) => {
modulesBundle += `<script src="${modules[moduleKey].url}" crossorigin></script>\n`;
accessKeys += `${modules[moduleKey].accessKey},${modulesKeys.length === index ? "\n" : ""}`;
modulesKeys.forEach((moduleKey) => {
modulesSrc += `<script src="${modules[moduleKey]}" crossorigin></script>\n`;
});

// Final modules body
modulesBundle += `
<script>
window.addEventListener("message", (event) => {
event.source.postMessage({${accessKeys}}, "*");
}, false);
</script>
\`;\n`;

bundle = bundle.replace("const MODULES_IFRAME = {};", modulesBundle);
bundle = bundle.replace("<script>:::MODULES_SRC:::</script>", modulesSrc);

return bundle;
};
Expand Down
11 changes: 2 additions & 9 deletions lib/actions/transformSchemaToWidget.js
Original file line number Diff line number Diff line change
Expand Up @@ -94,15 +94,8 @@ const processSchema = (fileSchema) => {
fileSchema.filePath.includes("src/index.tsx") ||
fileSchema.filePath.includes("src/index.jsx");

let isModule =
(fileSchema.filePath.includes(".module.") ||
!hasWidgetPropsCheck(fileSchema.content)) &&
!isIndex;

// Se o componente for stateful, mesmo tendo o nome .module., ele é definido como não module
if (hasWidgetPropsCheck(fileSchema.content)) {
isModule = false;
}
// isModule = Arquivo sem controle de estado
let isModule = !hasWidgetPropsCheck(fileSchema.content) && !isIndex;

fileSchema.isModule = isModule;

Expand Down
67 changes: 59 additions & 8 deletions lib/alem-vm/alem-vm.d.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,47 @@
// ALEM Items:

export type ChildrenProps = {
children: JSX.Element | JSX.Element[] | string | number;
};

export type ModuleResponseData = { response: any; forCallId: number };

/**
* Provides the necessary states to handle modules
*/
export declare const ModulesContext: () => void;

/**
* Modules Provider
*/
export declare const ModulesProvider: ({
children,
}: ChildrenProps) => JSX.Element;

/**
* useModule hook
*/
export type UseModuleProps = {
setupCode?: string;
code: string;
onComplete?: <D>(data: D) => void;
};

export declare const useModule: (inputs: UseModuleProps) => void;

// ======= Routes =======

/**
* Provides the necessary states and props for Router.
*/
export declare const RouterProvider: () => void;
// export declare const RouterProvider: ({
// children,
// }: ChildrenProps) => JSX.Element;

/**
* Provides the necessary states and props for Router.
*/
export declare const RouterContext: () => void;

type Route = {
path: string;
Expand Down Expand Up @@ -93,10 +129,18 @@ export type RouteType = "URLBased" | "ContentBased";
*
* This is NOT going to update the URL path.
*/
export declare const navigate: (
routePath: string,
params?: Record<string, string>,
) => void;
export declare const navigate: {
/**
* Go to new route
* @param route
* @param params
*/
to: (route: string, params?: Record<string, any>) => void;
/**
* Go back to the previous route
*/
back: () => void;
};

/**
* Create Route child
Expand Down Expand Up @@ -131,6 +175,11 @@ export declare const getLocation: () => {
isRoutesReady: boolean;
};

export type History = {
route: string;
routeParams?: Record<string, any>;
};

export type UseRoutesProps = {
routesInitialized: boolean;
activeRoute: string;
Expand All @@ -139,13 +188,16 @@ export type UseRoutesProps = {
routeType: string;
routeBlocked: boolean;
routeParams: Record<string, any>;
history: string[];
};

export type UseRoutes = Omit<UseRoutesProps, "routeBlocked">;

/**
* Use Routes Context props. This can be useful if you'd like to perform some side effect whenever some context data changes.
* @returns
*/
export declare const useRoutes: () => UseRoutesProps;
export declare const useRoutes: () => UseRoutes;

// ======= Context =======

Expand All @@ -154,14 +206,13 @@ export declare const useRoutes: () => UseRoutesProps;
* This can be useful if you'd like to perform some side effect whenever some context data changes.
*
* @param contextKey Context key name (must be unique)
* @param defaultStateValue Default values to be inserted to the Component's State
* @param defaultPropsValue Default values to be inserted to the Component's props
*/
export declare const createContext: <S extends {}>(
contextKey: string,
) => {
setDefaultData: (defaultStateValue: S) => void;
updateData: (updates: Partial<S>) => void;
getSelf: () => S;
};

/**
Expand Down
10 changes: 0 additions & 10 deletions lib/alem-vm/components/AppIndexer.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,6 @@ const AlemApp = useMemo(() => {

return (
<AlemTheme>
{iframeModulesCode && (
<iframe
style={{ height: 0, width: 0 }}
srcDoc={iframeModulesCode}
message={"init modules"}
onMessage={(message) => {
console.log("Message:", message);
}}
/>
)}
<Widget
loading=" "
code={props.alem.componentsCode.App}
Expand Down
51 changes: 51 additions & 0 deletions lib/alem-vm/importable/ModulesContext.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { createContext } from "../alem-vm";

const ModulesContext = () => {
const { setDefaultData, updateData, getSelf } =
createContext<any>("alemModulesContext");

setDefaultData({
calls: {},

//
callModule: (
setupCode: string,
code: string,
callId: number,
onComplete: (data: any) => void,
) => {
if (!code || !callId) return;

const codeStructure = `
${setupCode}
event.source.postMessage({response: ${code.replaceAll(";", "")}, forCallId: ${callId}}, "*");
`;

const updatedCalls = { ...getSelf().calls };

// Registra as chamadas
updatedCalls[callId] = { code: codeStructure, handler: onComplete };

updateData({
calls: updatedCalls,
});
},

removeCall: (callId: number) => {
const updatedCalls: any = {};
const currentCalls = getSelf().calls;
const calls = Object.keys(currentCalls);
calls.forEach((call) => {
if (call !== callId.toString()) {
updatedCalls[call] = currentCalls[call];
}
});

updateData({
calls: updatedCalls,
});
},
});
};

export default ModulesContext;
44 changes: 44 additions & 0 deletions lib/alem-vm/importable/ModulesProvider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import ModulesContext from "./ModulesContext";
import { ChildrenProps, ModuleResponseData, useContext } from "../alem-vm";

const ModulesProvider = ({ children }: ChildrenProps) => {
ModulesContext();

const modulesHandler = `
<script>:::MODULES_SRC:::</script>
<script>
window.addEventListener("message", (event) => {
if (event.data.code) {
eval(event.data.code);
}
}, false);
</script>
`;

const modules = useContext<any>("alemModulesContext");
const calls = modules.calls;
const callsKeys = Object.keys(calls);

return (
<>
{callsKeys.map((callKey) => (
<iframe
style={{ height: 0, width: 0 }}
srcDoc={modulesHandler}
message={{
code: calls[callKey].code,
}}
onMessage={(message: ModuleResponseData) => {
if (message) {
calls[message.forCallId].handler(message.response);
modules.removeCall(message.forCallId);
}
}}
/>
))}
{children}
</>
);
};

export default ModulesProvider;
2 changes: 1 addition & 1 deletion lib/alem-vm/importable/RouteLink.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export const RouteLink = ({
}

if (routeContext.routeType === "ContentBased") {
navigate(to, params);
navigate.to(to, params);
}
};

Expand Down
32 changes: 31 additions & 1 deletion lib/alem-vm/importable/Router.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,16 @@ const Router = (props: RouterProps) => {
}

// Checa se o config.keepRoute esta ativado e se tiver, se tem uma rota salva
let _activeRouteParams = null;
let _history = null;
if (alem.keepRoute && type === "ContentBased") {
_activeRoute = Storage.privateGet("alem::keep-route");
const storedRouteProps = Storage.privateGet("alem::keep-route");
if (storedRouteProps) {
_history = storedRouteProps;
const lastHistory = storedRouteProps[storedRouteProps.length - 1];
_activeRoute = lastHistory.route || null;
_activeRouteParams = lastHistory.routeParams || null;
}
}

// Se nenhuma rota está ativa, define o primeiro item das rotas como o ativo
Expand All @@ -117,12 +125,34 @@ const Router = (props: RouterProps) => {
routes: _routes,
routeType: _type,
activeRoute: _activeRoute,
routeParams: _activeRouteParams,
history: _history,
routeBlocked: true,
});
}
}
}, [routeType]);

// Pre-render: NOTE: parece não ter necessidade ou vai deixar tudo muito complexo
// const Components = useMemo(() => {
// return (
// <>
// {routes.map((route) => {
// const Comp = route.component;
// return (
// <div
// style={{ display: activeRoute === route.path ? "block" : "none" }}
// >
// <Comp />
// </div>
// );
// })}
// </>
// );
// }, [routes, activeRoute]);

// return <>{Components}</>;

// Route by route path
const Component = routes.find((route: Route) => route.path === activeRoute)
?.component ||
Expand Down
Loading

0 comments on commit 2d00cb2

Please sign in to comment.