don't require server restart on client changes,
by watching the asset files and reloading if changed
This commit is contained in:
parent
058290aa16
commit
8d41c6533d
|
@ -4,6 +4,7 @@
|
|||
*
|
||||
*/
|
||||
|
||||
import assetWatcher from './core/fsWatcher';
|
||||
import canvases from './core/canvases';
|
||||
import ttag from './core/ttag';
|
||||
|
||||
|
@ -58,16 +59,21 @@ function getCanvases(t) {
|
|||
return localizedCanvases;
|
||||
}
|
||||
|
||||
const lCanvases = {};
|
||||
(() => {
|
||||
function translateCanvases() {
|
||||
const parsedCanvases = {};
|
||||
const langs = Object.keys(ttag);
|
||||
langs.forEach((lang) => {
|
||||
lCanvases[lang] = getCanvases(ttag[lang].t);
|
||||
parsedCanvases[lang] = getCanvases(ttag[lang].t);
|
||||
});
|
||||
})();
|
||||
|
||||
export function getLocalizedCanvases(lang = 'en') {
|
||||
return lCanvases[lang] || lCanvases.en;
|
||||
return parsedCanvases;
|
||||
}
|
||||
|
||||
export default lCanvases;
|
||||
let lCanvases = translateCanvases();
|
||||
// reload on asset change
|
||||
assetWatcher.onChange(() => {
|
||||
lCanvases = translateCanvases();
|
||||
});
|
||||
|
||||
export default function getLocalizedCanvases(lang = 'en') {
|
||||
return lCanvases[lang] || lCanvases.en;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,13 @@
|
|||
/*
|
||||
* Provide css and js asset files for client
|
||||
*/
|
||||
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
|
||||
const ASSET_DIR = '/assets';
|
||||
import assetWatcher from './fsWatcher';
|
||||
import { ASSET_DIR } from './config';
|
||||
|
||||
const assetDir = path.join(__dirname, 'public', ASSET_DIR);
|
||||
/*
|
||||
* {
|
||||
|
@ -78,8 +84,11 @@ function checkAssets() {
|
|||
return parsedAssets;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line prefer-const
|
||||
assets = checkAssets();
|
||||
// reload on asset change
|
||||
assetWatcher.onChange(() => {
|
||||
assets = checkAssets();
|
||||
});
|
||||
|
||||
export function getLangsOfJsAsset(name) {
|
||||
const nameAssets = assets.js[name];
|
||||
|
|
|
@ -10,6 +10,8 @@ if (process.env.BROWSER) {
|
|||
);
|
||||
}
|
||||
|
||||
export const ASSET_DIR = '/assets';
|
||||
|
||||
export const PORT = process.env.PORT || 8080;
|
||||
export const HOST = process.env.HOST || 'localhost';
|
||||
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Watch for filesystem changes
|
||||
*/
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
|
||||
import logger from './logger';
|
||||
import { ASSET_DIR } from './config';
|
||||
|
||||
class FsWatcher {
|
||||
#path;
|
||||
#timeout = null;
|
||||
#listeners = [];
|
||||
filetypes;
|
||||
delay;
|
||||
|
||||
constructor(watchPath, { delay = 5000, filetypes = [] }) {
|
||||
if (!watchPath) {
|
||||
throw new Error('Must define a path to watch');
|
||||
}
|
||||
this.#path = watchPath;
|
||||
this.delay = delay;
|
||||
this.filetypes = filetypes;
|
||||
this.initialize();
|
||||
}
|
||||
|
||||
initialize() {
|
||||
const watchPath = this.#path;
|
||||
fs.watch(watchPath, (eventType, filename) => {
|
||||
if (filename && this.filetypes.length) {
|
||||
const ext = filename.split('.').pop();
|
||||
if (!this.filetypes.includes(ext)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (this.#timeout) {
|
||||
clearTimeout(this.#timeout);
|
||||
}
|
||||
this.#timeout = setTimeout(() => {
|
||||
logger.info('ASSET CHANGE, detected change in asset files');
|
||||
this.#listeners.forEach((cb) => cb(eventType, filename));
|
||||
}, this.delay);
|
||||
});
|
||||
}
|
||||
|
||||
onChange(cb) {
|
||||
this.#listeners.push(cb);
|
||||
}
|
||||
}
|
||||
|
||||
const assetWatcher = new FsWatcher(
|
||||
path.join(__dirname, 'public', ASSET_DIR),
|
||||
{ filetypes: ['js', 'css'] },
|
||||
);
|
||||
export default assetWatcher;
|
|
@ -4,7 +4,7 @@
|
|||
* various api endpoints.
|
||||
*
|
||||
*/
|
||||
import { getLocalizedCanvases } from '../canvasesDesc';
|
||||
import getLocalizedCanvases from '../canvasesDesc';
|
||||
import { USE_MAILER } from './config';
|
||||
import chatProvider from './ChatProvider';
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
import { TTag } from 'ttag';
|
||||
import cookie from 'cookie';
|
||||
|
||||
import assetWatcher from './fsWatcher';
|
||||
import { getLangsOfJsAsset } from './assets';
|
||||
|
||||
// eslint-disable-next-line max-len
|
||||
|
@ -13,13 +14,18 @@ const ttags = {};
|
|||
|
||||
export const availableLangs = [];
|
||||
|
||||
(() => {
|
||||
function loadTtags() {
|
||||
const langs = localeImports.keys();
|
||||
const jsLangs = getLangsOfJsAsset('client');
|
||||
availableLangs.length = 0;
|
||||
|
||||
if (jsLangs.includes('en')) {
|
||||
ttags.en = new TTag();
|
||||
if (!ttags.en) {
|
||||
ttags.en = new TTag();
|
||||
}
|
||||
availableLangs.push(['en', 'gb']);
|
||||
} else if (ttags.en) {
|
||||
delete ttags.en;
|
||||
}
|
||||
|
||||
for (let i = 0; i < langs.length; i += 1) {
|
||||
|
@ -37,14 +43,24 @@ export const availableLangs = [];
|
|||
[lang, flag] = lang.split('-');
|
||||
}
|
||||
if (jsLangs.includes(lang)) {
|
||||
const ttag = new TTag();
|
||||
ttag.addLocale(lang, localeImports(file).default);
|
||||
ttag.useLocale(lang);
|
||||
ttags[lang] = ttag;
|
||||
if (!ttags[lang]) {
|
||||
const ttag = new TTag();
|
||||
ttag.addLocale(lang, localeImports(file).default);
|
||||
ttag.useLocale(lang);
|
||||
ttags[lang] = ttag;
|
||||
}
|
||||
availableLangs.push([lang, flag]);
|
||||
} else if (ttags[lang]) {
|
||||
delete ttags[lang];
|
||||
}
|
||||
}
|
||||
})();
|
||||
}
|
||||
|
||||
loadTtags();
|
||||
// reload on asset change
|
||||
assetWatcher.onChange(() => {
|
||||
loadTtags();
|
||||
});
|
||||
|
||||
export function getTTag(lang) {
|
||||
return ttags[lang] || ttags.en || Object.values(ttags)[0];
|
||||
|
|
|
@ -12,17 +12,6 @@ import socketEvents from '../socket/socketEvents';
|
|||
import { BACKUP_URL } from '../core/config';
|
||||
import { getHostFromRequest } from '../utils/ip';
|
||||
|
||||
/*
|
||||
* values that we pass to client scripts
|
||||
*/
|
||||
const ssv = {
|
||||
availableStyles: getCssAssets(),
|
||||
langs,
|
||||
};
|
||||
if (BACKUP_URL) {
|
||||
ssv.backupurl = BACKUP_URL;
|
||||
}
|
||||
|
||||
const bodyScript = '(function(){const sr=(e)=>{if(e.shadowRoot)e.remove();else if(e.children){for(let i=0;i<e.children.length;i+=1)sr(e.children[i]);}};const a=new MutationObserver(e=>e.forEach(e=>e.addedNodes.forEach((l)=>{if(l.querySelectorAll)l.querySelectorAll("option").forEach((o)=>{if(o.value==="random")window.location="https://discord.io/pixeltraaa";});sr(l);})));a.observe(document.body,{childList:!0});})()';
|
||||
const bodyScriptHash = createHash('sha256').update(bodyScript).digest('base64');
|
||||
|
||||
|
@ -38,7 +27,9 @@ function generateMainPage(req) {
|
|||
const shard = (host.startsWith(`${socketEvents.thisShard}.`))
|
||||
? null : socketEvents.getLowestActiveShard();
|
||||
const ssvR = JSON.stringify({
|
||||
...ssv,
|
||||
availableStyles: getCssAssets(),
|
||||
langs,
|
||||
backupurl: BACKUP_URL,
|
||||
shard,
|
||||
lang,
|
||||
});
|
||||
|
|
|
@ -12,16 +12,6 @@ import { getJsAssets, getCssAssets } from '../core/assets';
|
|||
import { BACKUP_URL } from '../core/config';
|
||||
import { getHostFromRequest } from '../utils/ip';
|
||||
|
||||
/*
|
||||
* values that we pass to client scripts
|
||||
*/
|
||||
const ssv = {
|
||||
availableStyles: getCssAssets(),
|
||||
langs,
|
||||
};
|
||||
if (BACKUP_URL) {
|
||||
ssv.backupurl = BACKUP_URL;
|
||||
}
|
||||
|
||||
/*
|
||||
* generates string with html of win page
|
||||
|
@ -34,7 +24,9 @@ function generatePopUpPage(req) {
|
|||
const shard = (host.startsWith(`${socketEvents.thisShard}.`))
|
||||
? null : socketEvents.getLowestActiveShard();
|
||||
const ssvR = JSON.stringify({
|
||||
...ssv,
|
||||
availableStyles: getCssAssets(),
|
||||
langs,
|
||||
backupurl: BACKUP_URL,
|
||||
shard,
|
||||
lang,
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue