Alt. updates; Build system tweaks
This commit is contained in:
parent
9b23a57eeb
commit
9a20834ac0
|
@ -1,3 +1,4 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
node ./SpaccDotWeb.js 'SpaccDotWeb.LibBuild()'
|
for file in ./SpaccDotWeb*.js
|
||||||
node ./SpaccDotWeb.Build.js 'BuildScriptFile("SpaccDotWeb.Alt.js")'
|
do node ./SpaccDotWeb.Build.js "BuildScriptFile('${file}')"
|
||||||
|
done
|
||||||
|
|
|
@ -3,13 +3,17 @@
|
||||||
|
|
||||||
SpaccDotWeb.AppInit = (meta) => {
|
SpaccDotWeb.AppInit = (meta) => {
|
||||||
// ... load meta from argument or page element and add to object
|
// ... load meta from argument or page element and add to object
|
||||||
return SpaccDotWeb;
|
return { ...SpaccDotWeb,
|
||||||
}
|
LocalStorage: (key, value) => SpaccDotWeb.LocalStorage(`${meta.uuid}/v1`, key, value),
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
SpaccDotWeb.Sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
SpaccDotWeb.LocalStorage = (prefix, key, value) => JSON.parse(
|
||||||
|
localStorage[value !== undefined ? 'setItem' : 'getItem'](
|
||||||
|
`${prefix}/${key}`, JSON.stringify(value)) || null);
|
||||||
|
|
||||||
SpaccDotWeb.RequireScript = (src, type) => {
|
SpaccDotWeb.RequireScript = (src, type) => {
|
||||||
return new Promise((resolve) => {
|
return (new Promise((resolve) => {
|
||||||
const scriptElem = document.createElement('script');
|
const scriptElem = document.createElement('script');
|
||||||
//if (type) {
|
//if (type) {
|
||||||
// scriptElem.type = type;
|
// scriptElem.type = type;
|
||||||
|
@ -19,39 +23,52 @@
|
||||||
};
|
};
|
||||||
scriptElem.src = src;
|
scriptElem.src = src;
|
||||||
document.body.appendChild(scriptElem);
|
document.body.appendChild(scriptElem);
|
||||||
});
|
}));
|
||||||
}
|
};
|
||||||
// .RequireScripts = (...) => {}
|
// .RequireScripts = (...) => {}
|
||||||
|
|
||||||
SpaccDotWeb.ShowModal = async (params) => {
|
SpaccDotWeb.ShowModal = async (params) => {
|
||||||
// TODO: delete dialogs from DOM after use (garbage collect)?
|
// TODO: delete dialogs from DOM after use (garbage collect)?
|
||||||
if (!window.HTMLDialogElement && !window.dialogPolyfill) {
|
if (!window.HTMLDialogElement && !window.dialogPolyfill) {
|
||||||
|
// TODO include in dependencies, don't load from external server
|
||||||
await SpaccDotWeb.RequireScript('https://googlechrome.github.io/dialog-polyfill/dist/dialog-polyfill.js');
|
await SpaccDotWeb.RequireScript('https://googlechrome.github.io/dialog-polyfill/dist/dialog-polyfill.js');
|
||||||
}
|
}
|
||||||
let output;
|
let output;
|
||||||
if (typeof(params) === 'string') {
|
if (typeof(params) === 'string') {
|
||||||
params = { label: params }
|
params = { label: params };
|
||||||
}
|
}
|
||||||
//params.deleteOnClose ||= true;
|
//params.deleteOnClose ||= true;
|
||||||
|
params.buttonsPosition ||= 'bottom';
|
||||||
const modal = document.createElement('dialog');
|
const modal = document.createElement('dialog');
|
||||||
const label = (params.label || params.text);
|
const label = (params.label || params.text);
|
||||||
|
let buttonCancel = `<button name="cancel">${params.cancelText || '🔙️ Cancel'}</button>`;
|
||||||
|
let buttonConfirm = '';
|
||||||
|
if (params.actionConfirm || params.action) {
|
||||||
|
buttonConfirm = `<button name="confirm">${params.confirmText || '⏩️ Confirm'}</button>`;
|
||||||
|
}
|
||||||
modal.innerHTML = `
|
modal.innerHTML = `
|
||||||
${label ? `<p>${label}</p>` : ''}
|
${label ? `<p>${label}</p>` : ''}
|
||||||
${params.extraHTML || ''}
|
|
||||||
<button name="cancel">🔙️ Cancel</button>
|
|
||||||
`;
|
`;
|
||||||
|
const buttonsHtml = `<p>
|
||||||
|
${buttonCancel}
|
||||||
|
${buttonConfirm}
|
||||||
|
</p>`;
|
||||||
|
if (params.buttonsPosition == 'top') {
|
||||||
|
modal.innerHTML += `${buttonsHtml}`;
|
||||||
|
}
|
||||||
|
modal.innerHTML += `${params.extraHTML || ''}`;
|
||||||
|
if (params.buttonsPosition == 'bottom') {
|
||||||
|
modal.innerHTML += `${buttonsHtml}`;
|
||||||
|
}
|
||||||
if (params.actionConfirm || params.action) {
|
if (params.actionConfirm || params.action) {
|
||||||
modal.innerHTML += `
|
buttonConfirm = modal.querySelector('button[name="confirm"]');
|
||||||
<button name="confirm">⏩️ Confirm</button>
|
|
||||||
`;
|
|
||||||
const buttonConfirm = modal.querySelector('button[name="confirm"]');
|
|
||||||
buttonConfirm.onclick = (event) => {
|
buttonConfirm.onclick = (event) => {
|
||||||
output = (params.actionConfirm || params.action)(event, buttonConfirm);
|
output = (params.actionConfirm || params.action)(event, buttonConfirm);
|
||||||
modal.close();
|
modal.close();
|
||||||
return output;
|
return output;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
const buttonCancel = modal.querySelector('button[name="cancel"]');
|
buttonCancel = modal.querySelector('button[name="cancel"]');
|
||||||
buttonCancel.onclick = (event) => {
|
buttonCancel.onclick = (event) => {
|
||||||
if (params.actionCancel) {
|
if (params.actionCancel) {
|
||||||
output = actionCancel(event, buttonCancel);
|
output = actionCancel(event, buttonCancel);
|
||||||
|
@ -65,7 +82,9 @@
|
||||||
}
|
}
|
||||||
modal.showModal();
|
modal.showModal();
|
||||||
return modal;
|
return modal;
|
||||||
}
|
};
|
||||||
|
|
||||||
|
SpaccDotWeb.Sleep = (ms) => (new Promise((resolve) => setTimeout(resolve, ms)));
|
||||||
|
|
||||||
window.SpaccDotWeb ||= SpaccDotWeb;
|
window.SpaccDotWeb ||= SpaccDotWeb;
|
||||||
})();
|
})();
|
||||||
|
|
|
@ -1,31 +1,52 @@
|
||||||
|
#!/usr/bin/env node
|
||||||
const Lib = {
|
const Lib = {
|
||||||
fs: require('fs'),
|
fs: require('fs'),
|
||||||
|
mime: require('mime-types'),
|
||||||
crypto: require('crypto'),
|
crypto: require('crypto'),
|
||||||
childProcess: require('child_process'),
|
babel: require('@babel/core'),
|
||||||
jsdom: require('jsdom'),
|
uglify: require('uglify-js'),
|
||||||
};
|
};
|
||||||
|
|
||||||
const BuildScriptFile = (scriptFile) => {
|
const BuildScriptFile = (scriptFile, options) => {
|
||||||
|
options = {
|
||||||
|
forceResult: false,
|
||||||
|
checkHash: true,
|
||||||
|
...options };
|
||||||
Lib.fs.mkdirSync(`${__dirname}/Build`, { recursive: true });
|
Lib.fs.mkdirSync(`${__dirname}/Build`, { recursive: true });
|
||||||
//let uptodate = true;
|
|
||||||
const __scriptname = scriptFile.split('/').slice(-1)[0].split('.').slice(0, -1).join('.');
|
const __scriptname = scriptFile.split('/').slice(-1)[0].split('.').slice(0, -1).join('.');
|
||||||
|
const scriptScript = Lib.fs.readFileSync(scriptFile, 'utf8');
|
||||||
const compiledPath = `${__dirname}/Build/${__scriptname}.js`;
|
const compiledPath = `${__dirname}/Build/${__scriptname}.js`;
|
||||||
const minifiedPath = `${__dirname}/Build/${__scriptname}.min.js`;
|
const minifiedPath = `${__dirname}/Build/${__scriptname}.min.js`;
|
||||||
const hashPath = `${__dirname}/Build/${__scriptname}.js.hash`;
|
const hashPath = `${__dirname}/Build/${__scriptname}.js.hash`;
|
||||||
const hashOld = (Lib.fs.existsSync(hashPath) && Lib.fs.readFileSync(hashPath, 'utf8'));
|
const hashOld = (Lib.fs.existsSync(hashPath) && Lib.fs.readFileSync(hashPath, 'utf8'));
|
||||||
const hashNew = Lib.crypto.createHash('sha256').update(Lib.fs.readFileSync(scriptFile, 'utf8')).digest('hex');
|
const hashNew = Lib.crypto.createHash('sha256').update(scriptScript).digest('hex');
|
||||||
if (!Lib.fs.existsSync(compiledPath) || !Lib.fs.existsSync(minifiedPath) || !(hashOld === hashNew)) {
|
if (!options.checkHash || !Lib.fs.existsSync(compiledPath) || !Lib.fs.existsSync(minifiedPath) || !(hashOld === hashNew)) {
|
||||||
//uptodate = false;
|
const compiledScript = Lib.babel.transformSync(scriptScript,
|
||||||
|
JSON.parse(Lib.fs.readFileSync(`${__dirname}/babel.config.json`, 'utf8'))).code;
|
||||||
|
const minifiedScript = Lib.uglify.minify(compiledScript).code;
|
||||||
|
Lib.fs.writeFileSync(compiledPath, compiledScript);
|
||||||
|
Lib.fs.writeFileSync(minifiedPath, minifiedScript);
|
||||||
Lib.fs.writeFileSync(hashPath, hashNew);
|
Lib.fs.writeFileSync(hashPath, hashNew);
|
||||||
Lib.fs.writeFileSync(compiledPath, Lib.childProcess.execSync(`cat "${scriptFile}" | npx babel -f "${__scriptname}.js"`));
|
return { compiled: compiledScript, minified: minifiedScript };
|
||||||
Lib.fs.writeFileSync(minifiedPath, Lib.childProcess.execSync(`cat "${compiledPath}" | npx uglifyjs`));
|
}
|
||||||
};
|
return { notice: `Target "${scriptFile}" is up-to-date.`, ...(options.forceResult && {
|
||||||
//uptodate && console.log('Target is up-to-date.');
|
compiled: Lib.fs.readFileSync(compiledPath, 'utf8'),
|
||||||
//return { compiledText: Lib.fs.readFileSync(compiledPath, 'utf8'), minified: Lib.fs.readFileSync(minifiedPath, 'utf8') };
|
minified: Lib.fs.readFileSync(minifiedPath, 'utf8'),
|
||||||
|
}) };
|
||||||
|
};
|
||||||
|
|
||||||
|
//const BuildHtmlFile = (htmlFile) => {
|
||||||
|
//
|
||||||
|
//}
|
||||||
|
|
||||||
|
const EncodeStaticFiles = (files, /* encoding='base64' */) => {
|
||||||
|
const data = {};
|
||||||
|
files.forEach(file => (data[file] = `data:${Lib.mime.lookup(file)};base64,${Lib.fs.readFileSync(file).toString('base64')}`));
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = { BuildScriptFile, EncodeStaticFiles };
|
||||||
|
|
||||||
|
if (require.main === module) {
|
||||||
|
console.log(eval(process.argv.slice(-1)[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
const BuildHtmlFile = (htmlFile) => {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log(eval(process.argv.slice(-1)[0]));
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
#!/usr/bin/env node
|
||||||
const SpaccDotWeb = ((args) => { //////////////////////////////////////////////
|
const SpaccDotWeb = ((args) => { //////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
@ -16,6 +17,7 @@ if (platformIsNode) {
|
||||||
Lib.crypto = require('crypto');
|
Lib.crypto = require('crypto');
|
||||||
Lib.childProcess = require('child_process');
|
Lib.childProcess = require('child_process');
|
||||||
Lib.jsdom = require('jsdom');
|
Lib.jsdom = require('jsdom');
|
||||||
|
Lib.Build = require('./SpaccDotWeb.Build.js').BuildScriptFile;
|
||||||
__scriptname = __filename__.split('/').slice(-1)[0];
|
__scriptname = __filename__.split('/').slice(-1)[0];
|
||||||
windowObject = new Lib.jsdom.JSDOM('', JsdomOptions).window;
|
windowObject = new Lib.jsdom.JSDOM('', JsdomOptions).window;
|
||||||
};
|
};
|
||||||
|
@ -50,24 +52,6 @@ if (platformIsNode) {
|
||||||
|
|
||||||
isBuildingApp = false;
|
isBuildingApp = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
SpaccDotWeb.LibBuild = () => {
|
|
||||||
Lib.fs.mkdirSync(`${__dirname}/Build/Assets.tmp`, { recursive: true });
|
|
||||||
let uptodate = true;
|
|
||||||
const compiledPath = `${__dirname}/Build/SpaccDotWeb.js`;
|
|
||||||
const minifiedPath = `${__dirname}/Build/SpaccDotWeb.min.js`;
|
|
||||||
const hashPath = `${__dirname}/Build/SpaccDotWeb.js.hash`;
|
|
||||||
const hashOld = (Lib.fs.existsSync(hashPath) && Lib.fs.readFileSync(hashPath, 'utf8'));
|
|
||||||
const hashNew = Lib.crypto.createHash('sha256').update(Lib.fs.readFileSync(__filename__, 'utf8')).digest('hex');
|
|
||||||
if (!Lib.fs.existsSync(compiledPath) || !Lib.fs.existsSync(minifiedPath) || !(hashOld === hashNew)) {
|
|
||||||
uptodate = false;
|
|
||||||
Lib.fs.writeFileSync(hashPath, hashNew);
|
|
||||||
Lib.fs.writeFileSync(compiledPath, Lib.childProcess.execSync(`cat "${__filename__}" | npx babel -f "${__scriptname}"`));
|
|
||||||
Lib.fs.writeFileSync(minifiedPath, Lib.childProcess.execSync(`cat "${compiledPath}" | npx uglifyjs`));
|
|
||||||
};
|
|
||||||
uptodate && console.log('Library is up-to-date.');
|
|
||||||
return { compiledText: Lib.fs.readFileSync(compiledPath, 'utf8'), minified: Lib.fs.readFileSync(minifiedPath, 'utf8') };
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
SpaccDotWeb.AppInit = () => {
|
SpaccDotWeb.AppInit = () => {
|
||||||
|
@ -128,7 +112,7 @@ const DomMakeBase = (Modules) => {
|
||||||
if (isBuildingApp) {
|
if (isBuildingApp) {
|
||||||
scriptsHtml += `<scr`+`ipt src="http://cdn.jsdelivr.net/npm/core-js-bundle/minified.min.js"></scr`+`ipt>`;
|
scriptsHtml += `<scr`+`ipt src="http://cdn.jsdelivr.net/npm/core-js-bundle/minified.min.js"></scr`+`ipt>`;
|
||||||
scriptsHtml += `<scr`+`ipt src="https://cdn.jsdelivr.net/npm/core-js-bundle/minified.min.js"></scr`+`ipt>`;
|
scriptsHtml += `<scr`+`ipt src="https://cdn.jsdelivr.net/npm/core-js-bundle/minified.min.js"></scr`+`ipt>`;
|
||||||
scriptsHtml += `<scr`+`ipt>${SpaccDotWeb.LibBuild().minified}</scr`+`ipt>`;
|
scriptsHtml += `<scr`+`ipt>${Lib.Build(__filename__, { forceResult: true }).minified}</scr`+`ipt>`;
|
||||||
for (const elem of documentObject.querySelectorAll('script[module]')) {
|
for (const elem of documentObject.querySelectorAll('script[module]')) {
|
||||||
//if (elem.module === 'Meta' && !['application/json', 'text/json'].includes(elem.type)) {
|
//if (elem.module === 'Meta' && !['application/json', 'text/json'].includes(elem.type)) {
|
||||||
// elem.innerHTML = `(${elem.innerHTML})`;
|
// elem.innerHTML = `(${elem.innerHTML})`;
|
||||||
|
@ -140,6 +124,7 @@ const DomMakeBase = (Modules) => {
|
||||||
} else {
|
} else {
|
||||||
const tmpHash = Lib.crypto.createHash('sha256').update(elem.innerHTML).digest('hex');
|
const tmpHash = Lib.crypto.createHash('sha256').update(elem.innerHTML).digest('hex');
|
||||||
const tmpPath = `${__dirname}/Build/Assets.tmp/${tmpHash}.js`;
|
const tmpPath = `${__dirname}/Build/Assets.tmp/${tmpHash}.js`;
|
||||||
|
Lib.fs.mkdirSync(`${__dirname}/Build/Assets.tmp`, { recursive: true });
|
||||||
Lib.fs.writeFileSync(tmpPath, elem.innerHTML);
|
Lib.fs.writeFileSync(tmpPath, elem.innerHTML);
|
||||||
const scriptCode = Lib.childProcess.execSync(`cat "${tmpPath}" | npx babel -f "${tmpHash}.js" | npx uglifyjs`);
|
const scriptCode = Lib.childProcess.execSync(`cat "${tmpPath}" | npx babel -f "${tmpHash}.js" | npx uglifyjs`);
|
||||||
scriptsCode += scriptCode;
|
scriptsCode += scriptCode;
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -6,7 +6,7 @@
|
||||||
"build:clear": "rm -rf ./Build"
|
"build:clear": "rm -rf ./Build"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/cli": "^7.23.0",
|
"@babel/cli": "^7.24.8",
|
||||||
"@babel/core": "^7.23.0",
|
"@babel/core": "^7.23.0",
|
||||||
"@babel/preset-env": "^7.22.20",
|
"@babel/preset-env": "^7.22.20",
|
||||||
"core-js": "^3.35.0",
|
"core-js": "^3.35.0",
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
if (window.URL) {
|
||||||
|
var _URL = window.URL;
|
||||||
|
window.URL = (function URL (url, base) {
|
||||||
|
try {
|
||||||
|
return new (Function.prototype.bind.apply(_URL, [{}].concat([url, base])));
|
||||||
|
} catch (err) {
|
||||||
|
url = (
|
||||||
|
window.SpaccDotWebServer.staticFilesData[url] ||
|
||||||
|
window.SpaccDotWebServer.staticFilesData[`./${url}`] ||
|
||||||
|
url);
|
||||||
|
return { href: url, toString: (function(){ return url; }) };
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (window.fetch) {
|
||||||
|
var _fetch = window.fetch;
|
||||||
|
window.fetch = (function fetch (resource, options) {
|
||||||
|
return _fetch((
|
||||||
|
window.SpaccDotWebServer.staticFilesData[resource] ||
|
||||||
|
window.SpaccDotWebServer.staticFilesData[`./${resource}`] ||
|
||||||
|
resource), options);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
})();
|
Loading…
Reference in New Issue