refactor: publish .mjs files

This commit is contained in:
Ayo 2023-10-21 16:34:34 +02:00
parent 145ec4c4fe
commit b913e11e10
11 changed files with 105 additions and 48 deletions

View file

@ -1,4 +1,4 @@
import defineConfig from "@mcflyjs/core/define-config"; import defineConfig from "@mcflyjs/core/define-config.mjs";
export default defineConfig({ export default defineConfig({
components: "js", components: "js",

View file

@ -1,6 +1,6 @@
/** /**
* McFly SSR logic * McFly SSR logic
*/ */
import McFly from "@mcflyjs/core"; import McFly from "@mcflyjs/core/event-handler.mjs";
import config from "../mcfly.config"; import config from "../mcfly.config";
export default McFly(config, useStorage()); export default McFly(config, useStorage());

21
package-lock.json generated
View file

@ -4002,12 +4002,29 @@
"version": "0.0.1", "version": "0.0.1",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@mcflyjs/config": "^0.0.1", "@mcflyjs/config": "latest",
"@mcflyjs/core": "^0.1.0", "@mcflyjs/core": "latest",
"esprima": "^4.0.1", "esprima": "^4.0.1",
"nitropack": "latest", "nitropack": "latest",
"ultrahtml": "^1.5.2" "ultrahtml": "^1.5.2"
} }
},
"templates/basic/node_modules/@mcflyjs/config": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/@mcflyjs/config/-/config-0.0.1.tgz",
"integrity": "sha512-rcP21TqHNdvEZGxckpwQk6nfSdCSi52jHjMWfeyu37iPUhwZvRWzCqfGpRVW/396sN8j+674JRbZw0mHLq03DQ=="
},
"templates/basic/node_modules/@mcflyjs/core": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/@mcflyjs/core/-/core-0.1.1.tgz",
"integrity": "sha512-JsqChhe1+MhxFUT6vUbf7/4J6Phtt2pmSenUfjrywsG0ckMzxRSF9ei9yIThmmxhAEMUkIme/axXFZ3HpM1AKQ==",
"dependencies": {
"esprima": "^4.0.1",
"h3": "^1.8.2",
"nitropack": "^2.7.0",
"ultrahtml": "^1.5.2",
"unstorage": "^1.9.0"
}
} }
} }
} }

View file

@ -0,0 +1,3 @@
export default function defineConfig(config) {
return () => config;
}

View file

@ -1,9 +0,0 @@
import { NitroApp } from "nitropack";
export type McFlyConfig = {
onBuild?: Array<(event: NitroApp) => void>;
components: "js" | "ts";
};
export default function defineConfig(config: McFlyConfig) {
return () => config;
}

View file

@ -1,9 +1,10 @@
// @ts-check
import { eventHandler } from "h3"; import { eventHandler } from "h3";
import { Storage as NitroStorage } from "unstorage";
import { ELEMENT_NODE, parse, render, renderSync, walkSync } from "ultrahtml"; import { ELEMENT_NODE, parse, render, renderSync, walkSync } from "ultrahtml";
import { parseScript } from "esprima"; import { parseScript } from "esprima";
export default (config: Function, storage: NitroStorage) => { export default (config, storage) => {
return eventHandler(async (event) => { return eventHandler(async (event) => {
const { path } = event; const { path } = event;
const { components: componentType } = config(); const { components: componentType } = config();
@ -26,7 +27,7 @@ export default (config: Function, storage: NitroStorage) => {
}); });
}; };
const getHtml = async (path: string, storage) => { const getHtml = async (path, storage) => {
const rawPath = path[path.length - 1] === "/" ? path.slice(0, -1) : path; const rawPath = path[path.length - 1] === "/" ? path.slice(0, -1) : path;
const filename = rawPath === "" ? "/index.html" : `${rawPath}.html`; const filename = rawPath === "" ? "/index.html" : `${rawPath}.html`;
const fallback = getPath(rawPath + "/index.html"); const fallback = getPath(rawPath + "/index.html");
@ -38,15 +39,22 @@ const getHtml = async (path: string, storage) => {
return html; return html;
}; };
function getPath(filename: string) { /**
*
* @param {string} filename
* @returns string
*/
function getPath(filename) {
return `assets/pages${filename}`; return `assets/pages${filename}`;
} }
async function insertRegistry( /**
html: string, *
type: "js" | "ts", * @param {string} html
storage: NitroStorage * @param {"js" | "ts"} type
): Promise<string> { * @returns Promise<string>
*/
async function insertRegistry(html, type, storage) {
const ast = parse(html); const ast = parse(html);
const componentFiles = await getFiles(type, storage); const componentFiles = await getFiles(type, storage);
const availableComponents = componentFiles.map((key) => const availableComponents = componentFiles.map((key) =>
@ -80,17 +88,20 @@ async function insertRegistry(
return render(ast); return render(ast);
} }
async function buildRegistry( /**
usedCustomElements: string[], *
type: "js" | "ts", * @param {Array<string>} usedCustomElements
storage: NitroStorage * @param {"js" | "ts"} type
) { * @returns
*/
async function buildRegistry(usedCustomElements, type, storage) {
let registryScript = `<script type='module'>`; let registryScript = `<script type='module'>`;
let isBaseClassImported = false; let isBaseClassImported = false;
let classesImported = []; let classesImported = [];
for (const name of usedCustomElements) { for (const name of usedCustomElements) {
const content = await storage.getItem(`assets:components:${name}.${type}`); const content = await storage.getItem(`assets:components:${name}.${type}`);
if (!content) continue;
const evalStore = eval( const evalStore = eval(
`class WebComponent {}; class HTMLElement {}; (${content.toString()})` `class WebComponent {}; class HTMLElement {}; (${content.toString()})`
); );
@ -119,7 +130,12 @@ async function buildRegistry(
return registryScript; return registryScript;
} }
function doSetUp(html: string) { /**
*
* @param {string} html
* @returns string
*/
function doSetUp(html) {
const ast = parse(html); const ast = parse(html);
const serverScripts = []; const serverScripts = [];
walkSync(ast, (node) => { walkSync(ast, (node) => {
@ -138,11 +154,11 @@ function doSetUp(html: string) {
}); });
const setupMap = {}; const setupMap = {};
serverScripts.forEach((script: string) => { serverScripts.forEach((script) => {
const { body } = parseScript(script); const { body } = parseScript(script);
const keys = body const keys = body
.filter((node) => node.type === "VariableDeclaration") .filter((n) => n.type === "VariableDeclaration")
.map((node) => node.declarations[0].id.name); .map((n) => n["declarations"][0].id.name);
const constructor = `(function(){}.constructor)(\`${script}; return {${keys.join( const constructor = `(function(){}.constructor)(\`${script}; return {${keys.join(
"," ","
)}}\`);`; )}}\`);`;
@ -162,13 +178,18 @@ function doSetUp(html: string) {
return html; return html;
} }
function deleteServerScripts(html: string): string { /**
*
* @param {string} html
* @returns string
*/
function deleteServerScripts(html) {
const ast = parse(html); const ast = parse(html);
walkSync(ast, (node) => { walkSync(ast, (node) => {
const { attributes } = node; const { attributes } = node;
const attributeKeys = Object.keys(attributes ?? {}); const attributeKeys = Object.keys(attributes ?? {});
const isServerScript = attributeKeys.some((key) => key.includes("server:")); const isServerScript = attributeKeys.some((key) => key.includes("server:"));
if (isServerScript) { if (isServerScript && !!node.parent) {
node.parent.children.splice(node.parent.children.indexOf(node), 1); node.parent.children.splice(node.parent.children.indexOf(node), 1);
} }
}); });
@ -176,7 +197,12 @@ function deleteServerScripts(html: string): string {
return renderSync(ast); return renderSync(ast);
} }
function cleanScript(scripts: string[]): string { /**
*
* @param {Array<string>} scripts
* @returns string
*/
function cleanScript(scripts) {
let script = scripts.map((s) => s.trim()).join(" "); let script = scripts.map((s) => s.trim()).join(" ");
script = removeComments(script); script = removeComments(script);
@ -184,6 +210,10 @@ function cleanScript(scripts: string[]): string {
return script.replace(/\n/g, "").replace(/\s+/g, " "); return script.replace(/\n/g, "").replace(/\s+/g, " ");
} }
/**
*
* @returns boolean
*/
function isComment(node) { function isComment(node) {
return ( return (
node.type === "Line" || node.type === "Line" ||
@ -193,7 +223,12 @@ function isComment(node) {
); );
} }
function removeComments(script: string) { /**
*
* @param {string} script
* @returns string
*/
function removeComments(script) {
const entries = []; const entries = [];
parseScript(script, { comment: true }, function (node, meta) { parseScript(script, { comment: true }, function (node, meta) {
if (isComment(node)) { if (isComment(node)) {
@ -214,7 +249,12 @@ function removeComments(script: string) {
return script; return script;
} }
async function useFragments(html: string, storage: NitroStorage) { /**
*
* @param {string} html
* @returns Promise<string>
*/
async function useFragments(html, storage) {
const fragmentFiles = await getFiles("html", storage); const fragmentFiles = await getFiles("html", storage);
const availableFragments = fragmentFiles.reduce((acc, key) => { const availableFragments = fragmentFiles.reduce((acc, key) => {
@ -226,9 +266,11 @@ async function useFragments(html: string, storage: NitroStorage) {
const ast = parse(html); const ast = parse(html);
for (const key in availableFragments) { for (const key in availableFragments) {
let text: string = await storage.getItem( /**
"assets:components:" + key + ".html" * @type string | null
); */
let text = await storage.getItem("assets:components:" + key + ".html");
if (!text) continue;
availableFragments[key] = text.replace(/\n/g, "").replace(/\s+/g, " "); availableFragments[key] = text.replace(/\n/g, "").replace(/\s+/g, " ");
} }
@ -259,7 +301,11 @@ function replaceSlots(fragmentNode, node) {
}); });
} }
async function getFiles(type: string, storage: NitroStorage) { /**
*
* @param {string} type
*/
async function getFiles(type, storage) {
return (await storage.getKeys("assets:components")) return (await storage.getKeys("assets:components"))
.map((key) => key.replace("assets:components:", "")) .map((key) => key.replace("assets:components:", ""))
.filter((key) => key.includes(type)); .filter((key) => key.includes(type));

View file

@ -2,10 +2,10 @@
"name": "@mcflyjs/core", "name": "@mcflyjs/core",
"version": "0.1.1", "version": "0.1.1",
"description": "McFly core package", "description": "McFly core package",
"main": "index.ts", "main": "event-handler.mjs",
"files": [ "files": [
"index.ts", "event-handler.mjs",
"define-config.ts" "define-config.mjs"
], ],
"scripts": { "scripts": {
"test": "echo \"Error: no test specified\" && exit 1" "test": "echo \"Error: no test specified\" && exit 1"

View file

@ -1,4 +1,4 @@
import defineConfig from "@mcflyjs/core/define-config"; import defineConfig from "@mcflyjs/core/define-config.mjs";
export default defineConfig({ export default defineConfig({
components: "js", components: "js",

View file

@ -8,10 +8,10 @@
"preview": "node .output/server/index.mjs" "preview": "node .output/server/index.mjs"
}, },
"dependencies": { "dependencies": {
"@mcflyjs/config": "^0.0.1", "@mcflyjs/config": "latest",
"@mcflyjs/core": "^0.1.0", "@mcflyjs/core": "latest",
"esprima": "^4.0.1",
"nitropack": "latest", "nitropack": "latest",
"esprima": "^4.0.1",
"ultrahtml": "^1.5.2" "ultrahtml": "^1.5.2"
}, },
"name": "@templates/basic", "name": "@templates/basic",

View file

@ -1,6 +1,6 @@
/** /**
* McFly SSR logic * McFly SSR logic
*/ */
import McFly from "@mcflyjs/core"; import McFly from "@mcflyjs/core/event-handler.mjs";
import config from "../mcfly.config"; import config from "../mcfly.config";
export default McFly(config, useStorage()); export default McFly(config, useStorage());