Remove Polyfills (#101)
* poly: remove completely * bootstrap: remove unused request require * asarUpdate: rewrite request -> https * moduleUpdater: rewrite request -> https * ui: fallback to channel instead of "custom" if no hash * index: set name to branch for obvious testing * config/backend: tweak source * moduleUpdater: fix rewrite * moduleUpdater: fix rewrite (x2) * moduleUpdater: follow redirects with rewrite * ci: start multi-branch rewrite * ci: upgrade node to 18.x * ci: rewrite version changing to use existing * ci: change release version getting to in file * ci: mess with yaml syntax * ci: revert to node 16.x, fix version wrapped in quotes * ci: fix invalid yaml * ci: yaml syntax fixing * ci: append to tag * ci: make pre-release unless nightly build * ci: add title nicening * asarUpdate: fix release suffix * asarUpdate: fix not following redirect * winFirst: don't remake shortcuts, tweaks * ui: add channel prefix if non-nightly * chore: prep for main branch
This commit is contained in:
parent
f2da613f2b
commit
ec5082860e
|
@ -6,7 +6,6 @@ on:
|
||||||
paths:
|
paths:
|
||||||
- 'src/**'
|
- 'src/**'
|
||||||
- 'scripts/**'
|
- 'scripts/**'
|
||||||
- 'poly/**'
|
|
||||||
- '.github/workflows/**'
|
- '.github/workflows/**'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
@ -25,8 +24,7 @@ jobs:
|
||||||
- name: Pack base asar
|
- name: Pack base asar
|
||||||
run: |
|
run: |
|
||||||
npm i -g asar
|
npm i -g asar
|
||||||
bash scripts/injectPolyfills.sh
|
sed -i -e "s/oaVersion = '\(.*\)'/oaVersion = '\1-$(git rev-parse HEAD | cut -c 1-7)'/" src/index.js
|
||||||
sed -i -e "s/nightly/nightly-$(git rev-parse HEAD | cut -c 1-7)/" src/index.js
|
|
||||||
node scripts/strip.js
|
node scripts/strip.js
|
||||||
npx asar pack src app.asar
|
npx asar pack src app.asar
|
||||||
|
|
||||||
|
@ -147,15 +145,16 @@ jobs:
|
||||||
|
|
||||||
- name: GitHub Release
|
- name: GitHub Release
|
||||||
run: |
|
run: |
|
||||||
git tag -d nightly || true
|
echo ${{ env.VERSION }}
|
||||||
git push origin --delete nightly || true
|
git tag -d ${{ env.VERSION }} || true
|
||||||
git tag nightly
|
git push origin --delete ${{ env.VERSION }} || true
|
||||||
git push origin nightly
|
git tag ${{ env.VERSION }}
|
||||||
|
git push origin ${{ env.VERSION }}
|
||||||
gh release delete ${{ env.VERSION }} -y || true
|
gh release delete ${{ env.VERSION }} -y || true
|
||||||
gh release create ${{ env.VERSION }} -t "Nightly" -n "$(git rev-parse HEAD | cut -c 1-7) | $(git log -1 --pretty=%B)" ${{ env.FILES }}
|
gh release create ${{ env.VERSION }} -t "$(echo "${{ env.VERSION }}" | sed 's/.*/\u&/' | sed "s/nt/n't/")" -n "$(git rev-parse HEAD | cut -c 1-7) | $(git log -1 --pretty=%B)" "$([ "${{ env.VERSION }}" != "nightly" ] && echo "-p")" ${{ env.FILES }}
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}'
|
GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}'
|
||||||
VERSION: 'nightly'
|
VERSION: $(strings app.asar | grep -oP "oaVersion='.*?-" | grep -oP "(?<=').*?(?=-)")
|
||||||
FILES: app.asar
|
FILES: app.asar
|
||||||
|
|
||||||
# debug-linux:
|
# debug-linux:
|
||||||
|
|
2
faq.md
2
faq.md
|
@ -22,7 +22,7 @@ OpenAsar optimizes Chromium (the web engine / browser Discord uses) to help incr
|
||||||
The main speed increase (default options) is mostly accidental / coincidental (not intended) as it is mostly a side effect of rewriting it.
|
The main speed increase (default options) is mostly accidental / coincidental (not intended) as it is mostly a side effect of rewriting it.
|
||||||
|
|
||||||
### How is this so small?
|
### How is this so small?
|
||||||
Compared to Discord's original, OpenAsar is <2% of the size. This is because when rewriting we remove NPM dependencies with our own custom code for more performance and efficiency. These are replaced with custom polyfills (compatible replacements).
|
Compared to Discord's original, OpenAsar is <2% of the size. This is because when rewriting we remove NPM dependencies with our own custom code for more performance and efficiency.
|
||||||
|
|
||||||
### What is Quickstart?
|
### What is Quickstart?
|
||||||
Quickstart "skips" a few Discord features like the splash screen and waiting for updates in favour of speed. It is currently experimental and not fully recommended for normal use.
|
Quickstart "skips" a few Discord features like the splash screen and waiting for updates in favour of speed. It is currently experimental and not fully recommended for normal use.
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
// Stub
|
|
||||||
exports.lookup = (file) => 'text/plain';
|
|
|
@ -1,84 +0,0 @@
|
||||||
const https = require('https');
|
|
||||||
|
|
||||||
// Generic polyfill for "request" npm package, wrapper for https
|
|
||||||
const nodeReq = ({ method, url, headers, qs, timeout, body }) => new Promise((resolve) => {
|
|
||||||
let req;
|
|
||||||
try {
|
|
||||||
req = https.request(url + (qs != null ? `?${(new URLSearchParams(qs)).toString()}` : ''), { method, headers, timeout }, async (res) => {
|
|
||||||
const loc = res.headers.location;
|
|
||||||
if (loc) return resolve(await nodeReq({ url: loc, method, headers, timeout, body }));
|
|
||||||
|
|
||||||
resolve(res);
|
|
||||||
});
|
|
||||||
} catch (e) {
|
|
||||||
return resolve(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
req.on('error', resolve);
|
|
||||||
|
|
||||||
if (body) req.write(body); // Write POST body if included
|
|
||||||
|
|
||||||
req.end();
|
|
||||||
});
|
|
||||||
|
|
||||||
const request = (...args) => {
|
|
||||||
let options, callback;
|
|
||||||
switch (args.length) {
|
|
||||||
case 3: // request(url, options, callback)
|
|
||||||
options = {
|
|
||||||
url: args[0],
|
|
||||||
...args[1]
|
|
||||||
};
|
|
||||||
|
|
||||||
callback = args[2];
|
|
||||||
break;
|
|
||||||
|
|
||||||
default: // request(url, callback) / request(options, callback)
|
|
||||||
options = args[0];
|
|
||||||
callback = args[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof options === 'string') {
|
|
||||||
options = {
|
|
||||||
url: options
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
const listeners = {};
|
|
||||||
|
|
||||||
nodeReq(options).then(async (res) => {
|
|
||||||
if (!res.statusCode) {
|
|
||||||
listeners['error']?.(res);
|
|
||||||
return callback?.(res, null, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
listeners['response']?.(res);
|
|
||||||
|
|
||||||
let data = [];
|
|
||||||
res.on('data', (chunk) => {
|
|
||||||
data.push(chunk);
|
|
||||||
listeners['data']?.(chunk);
|
|
||||||
});
|
|
||||||
|
|
||||||
await new Promise((resolve) => res.on('end', resolve)); // Wait to read full body
|
|
||||||
|
|
||||||
const buf = Buffer.concat(data);
|
|
||||||
callback?.(undefined, res, options.encoding !== null ? buf.toString() : buf);
|
|
||||||
});
|
|
||||||
|
|
||||||
const ret = {
|
|
||||||
on: (type, handler) => {
|
|
||||||
listeners[type] = handler;
|
|
||||||
return ret; // Return self
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
};
|
|
||||||
|
|
||||||
for (const m of [ 'get', 'post', 'put', 'patch', 'delete', 'head', 'options' ]) {
|
|
||||||
request[m] = (url, callback) => request({ url, method: m }, callback);
|
|
||||||
}
|
|
||||||
request.del = request.delete; // Special case
|
|
||||||
|
|
||||||
module.exports = request;
|
|
|
@ -1,3 +0,0 @@
|
||||||
rm -rf src/node_modules
|
|
||||||
mkdir src/node_modules
|
|
||||||
cp -rf poly/* src/node_modules
|
|
|
@ -1,7 +1,6 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
echo "Packing asar..."
|
echo "Packing asar..."
|
||||||
./scripts/injectPolyfills.sh
|
|
||||||
asar pack src app.asar # Package asar
|
asar pack src app.asar # Package asar
|
||||||
# asar list app.asar # List asar for debugging / testing
|
# asar list app.asar # List asar for debugging / testing
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
const request = require('request');
|
const { get } = require('https');
|
||||||
const fs = require('original-fs'); // Use original-fs, not Electron's modified fs
|
const fs = require('original-fs'); // Use original-fs, not Electron's modified fs
|
||||||
const { join } = require('path');
|
const { join } = require('path');
|
||||||
|
|
||||||
|
@ -7,21 +7,23 @@ const downloadPath = join(asarPath, '..', 'app.asar.download');
|
||||||
|
|
||||||
const asarUrl = `https://github.com/GooseMod/OpenAsar/releases/download/${oaVersion.split('-')[0]}/app.asar`;
|
const asarUrl = `https://github.com/GooseMod/OpenAsar/releases/download/${oaVersion.split('-')[0]}/app.asar`;
|
||||||
|
|
||||||
|
// todo: have these https utils centralised?
|
||||||
|
const redirs = url => new Promise(res => get(url, r => { // Minimal wrapper around https.get to follow redirects
|
||||||
|
const loc = r.headers.location;
|
||||||
|
if (loc) return redirs(loc).then(res);
|
||||||
|
|
||||||
|
res(r);
|
||||||
|
}));
|
||||||
|
|
||||||
module.exports = async () => { // (Try) update asar
|
module.exports = async () => { // (Try) update asar
|
||||||
log('AsarUpdate', 'Updating...');
|
log('AsarUpdate', 'Updating...');
|
||||||
|
|
||||||
if (!oaVersion.includes('-')) return;
|
if (!oaVersion.includes('-')) return;
|
||||||
|
|
||||||
await new Promise((res) => {
|
|
||||||
const file = fs.createWriteStream(downloadPath);
|
const file = fs.createWriteStream(downloadPath);
|
||||||
|
(await redirs(asarUrl)).pipe(file);
|
||||||
|
|
||||||
file.on('finish', () => {
|
await new Promise(res => file.on('finish', res));
|
||||||
file.close();
|
|
||||||
res();
|
|
||||||
});
|
|
||||||
|
|
||||||
request.get(asarUrl).on('response', r => r.pipe(file));
|
|
||||||
});
|
|
||||||
|
|
||||||
if (fs.readFileSync(downloadPath, 'utf8').startsWith('<')) return log('AsarUpdate', 'Download error');
|
if (fs.readFileSync(downloadPath, 'utf8').startsWith('<')) return log('AsarUpdate', 'Download error');
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
const { app, session } = require('electron');
|
const { app, session } = require('electron');
|
||||||
const { readFileSync } = require('fs');
|
const { readFileSync } = require('fs');
|
||||||
const get = require('request');
|
|
||||||
const { join } = require('path');
|
const { join } = require('path');
|
||||||
|
|
||||||
if (!settings.get('enableHardwareAcceleration', true)) app.disableHardwareAcceleration();
|
if (!settings.get('enableHardwareAcceleration', true)) app.disableHardwareAcceleration();
|
||||||
|
@ -41,7 +40,7 @@ const startCore = () => {
|
||||||
const [ channel, hash ] = oaVersion.split('-'); // Split via -
|
const [ channel, hash ] = oaVersion.split('-'); // Split via -
|
||||||
|
|
||||||
bw.webContents.executeJavaScript(readFileSync(join(__dirname, 'mainWindow.js'), 'utf8')
|
bw.webContents.executeJavaScript(readFileSync(join(__dirname, 'mainWindow.js'), 'utf8')
|
||||||
.replaceAll('<hash>', hash || 'custom')
|
.replaceAll('<hash>', hash)
|
||||||
.replaceAll('<notrack>', oaConfig.noTrack)
|
.replaceAll('<notrack>', oaConfig.noTrack)
|
||||||
.replace('<css>', (oaConfig.css ?? '').replaceAll('\\', '\\\\').replaceAll('`', '\\`')));
|
.replace('<css>', (oaConfig.css ?? '').replaceAll('\\', '\\\\').replaceAll('`', '\\`')));
|
||||||
|
|
||||||
|
@ -92,7 +91,7 @@ const startUpdate = () => {
|
||||||
inst.on('InconsistentInstallerState', fatal);
|
inst.on('InconsistentInstallerState', fatal);
|
||||||
inst.on('update-error', console.error);
|
inst.on('update-error', console.error);
|
||||||
|
|
||||||
require('./winFirst').do(inst);
|
require('./winFirst').do();
|
||||||
} else {
|
} else {
|
||||||
moduleUpdater.init(Constants.UPDATE_ENDPOINT, buildInfo);
|
moduleUpdater.init(Constants.UPDATE_ENDPOINT, buildInfo);
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ exports.open = () => {
|
||||||
ipcMain.on('cs', (e, c) => {
|
ipcMain.on('cs', (e, c) => {
|
||||||
config = c;
|
config = c;
|
||||||
settings.set('openasar', config);
|
settings.set('openasar', config);
|
||||||
settings.save(); // Ensure saving
|
settings.save();
|
||||||
});
|
});
|
||||||
|
|
||||||
ipcMain.on('cg', e => {
|
ipcMain.on('cg', e => {
|
||||||
|
|
|
@ -3,7 +3,7 @@ const fs = require('fs');
|
||||||
const Module = require('module');
|
const Module = require('module');
|
||||||
const { execFile } = require('child_process');
|
const { execFile } = require('child_process');
|
||||||
const { app, autoUpdater } = require('electron');
|
const { app, autoUpdater } = require('electron');
|
||||||
const request = require('request');
|
const { get } = require('https');
|
||||||
|
|
||||||
const paths = require('../paths');
|
const paths = require('../paths');
|
||||||
|
|
||||||
|
@ -32,6 +32,20 @@ const resetTracking = () => {
|
||||||
installing = Object.assign({}, base);
|
installing = Object.assign({}, base);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const req = url => new Promise(res => get(url, r => { // Minimal wrapper around https.get to include body
|
||||||
|
let dat = '';
|
||||||
|
r.on('data', b => dat += b.toString());
|
||||||
|
|
||||||
|
r.on('end', () => res([ r, dat ]));
|
||||||
|
}));
|
||||||
|
|
||||||
|
const redirs = url => new Promise(res => get(url, r => { // Minimal wrapper around https.get to follow redirects
|
||||||
|
const loc = r.headers.location;
|
||||||
|
if (loc) return redirs(loc).then(res);
|
||||||
|
|
||||||
|
res(r);
|
||||||
|
}));
|
||||||
|
|
||||||
exports.init = (endpoint, { releaseChannel, version }) => {
|
exports.init = (endpoint, { releaseChannel, version }) => {
|
||||||
skipHost = settings.get('SKIP_HOST_UPDATE');
|
skipHost = settings.get('SKIP_HOST_UPDATE');
|
||||||
skipModule = settings.get('SKIP_MODULE_UPDATE');
|
skipModule = settings.get('SKIP_MODULE_UPDATE');
|
||||||
|
@ -63,9 +77,7 @@ exports.init = (endpoint, { releaseChannel, version }) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
checkForUpdates() {
|
checkForUpdates() {
|
||||||
request(this.url, (e, r, b) => {
|
req(this.url).then(([ r, b ]) => {
|
||||||
if (e) return this.emit('error');
|
|
||||||
|
|
||||||
if (r.statusCode === 204) return this.emit('update-not-available');
|
if (r.statusCode === 204) return this.emit('update-not-available');
|
||||||
|
|
||||||
this.emit('update-manually', b);
|
this.emit('update-manually', b);
|
||||||
|
@ -95,17 +107,11 @@ exports.init = (endpoint, { releaseChannel, version }) => {
|
||||||
host.setFeedURL(`${endpoint}/updates/${releaseChannel}?platform=${platform}&version=${version}`);
|
host.setFeedURL(`${endpoint}/updates/${releaseChannel}?platform=${platform}&version=${version}`);
|
||||||
|
|
||||||
baseUrl = `${endpoint}/modules/${releaseChannel}`;
|
baseUrl = `${endpoint}/modules/${releaseChannel}`;
|
||||||
qs = {
|
qs = `?host_version=${version}&platform=${platform}`;
|
||||||
host_version: version,
|
|
||||||
platform
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const checkModules = async () => {
|
const checkModules = async () => {
|
||||||
remote = await new Promise((res) => request({
|
remote = JSON.parse((await req(baseUrl + '/versions.json' + qs))[1]);
|
||||||
url: baseUrl + '/versions.json',
|
|
||||||
qs
|
|
||||||
}, (e, r, b) => res(JSON.parse(b))));
|
|
||||||
|
|
||||||
for (const name in installed) {
|
for (const name in installed) {
|
||||||
const inst = installed[name].installedVersion;
|
const inst = installed[name].installedVersion;
|
||||||
|
@ -130,10 +136,7 @@ const downloadModule = async (name, ver) => {
|
||||||
// log('Modules', 'Downloading', `${name}@${ver}`);
|
// log('Modules', 'Downloading', `${name}@${ver}`);
|
||||||
|
|
||||||
let success, total, cur = 0;
|
let success, total, cur = 0;
|
||||||
request({
|
const res = await redirs(baseUrl + '/' + name + '/' + ver + qs);
|
||||||
url: baseUrl + '/' + name + '/' + ver,
|
|
||||||
qs
|
|
||||||
}).on('response', (res) => {
|
|
||||||
success = res.statusCode === 200;
|
success = res.statusCode === 200;
|
||||||
total = parseInt(res.headers['content-length'] ?? 1, 10);
|
total = parseInt(res.headers['content-length'] ?? 1, 10);
|
||||||
|
|
||||||
|
@ -144,11 +147,9 @@ const downloadModule = async (name, ver) => {
|
||||||
|
|
||||||
events.emit('downloading-module', { name, cur, total });
|
events.emit('downloading-module', { name, cur, total });
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
|
||||||
await new Promise((res) => file.on('close', res));
|
await new Promise((res) => file.on('close', res));
|
||||||
|
|
||||||
|
|
||||||
if (success) commitManifest();
|
if (success) commitManifest();
|
||||||
else downloading.fail++;
|
else downloading.fail++;
|
||||||
|
|
||||||
|
@ -156,7 +157,6 @@ const downloadModule = async (name, ver) => {
|
||||||
name
|
name
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
downloading.done++;
|
downloading.done++;
|
||||||
|
|
||||||
if (downloading.done === downloading.total) {
|
if (downloading.done === downloading.total) {
|
||||||
|
|
|
@ -1,15 +1,14 @@
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const { join, resolve, basename } = require('path');
|
const { join, resolve } = require('path');
|
||||||
|
|
||||||
const Constants = require('./Constants');
|
const Constants = require('./Constants');
|
||||||
const reg = (a, c) => require('child_process').execFile('reg.exe', a, c);
|
const reg = (a, c) => require('child_process').execFile('reg.exe', a, c);
|
||||||
|
|
||||||
const exec = process.execPath;
|
const exec = process.execPath;
|
||||||
const app = resolve(exec, '..');
|
const app = resolve(exec, '..');
|
||||||
const root = resolve(app, '..');
|
|
||||||
|
|
||||||
|
|
||||||
exports.do = (updater) => {
|
exports.do = () => {
|
||||||
const flag = join(app, '.first-run');
|
const flag = join(app, '.first-run');
|
||||||
if (fs.existsSync(flag)) return; // Already done, skip
|
if (fs.existsSync(flag)) return; // Already done, skip
|
||||||
|
|
||||||
|
@ -23,31 +22,8 @@ exports.do = (updater) => {
|
||||||
[base + '\\shell\\open\\command', '/ve', '/d', `"${exec}" --url -- "%1"`]
|
[base + '\\shell\\open\\command', '/ve', '/d', `"${exec}" --url -- "%1"`]
|
||||||
]) reg([ 'add', ...x, '/f' ], e => {});
|
]) reg([ 'add', ...x, '/f' ], e => {});
|
||||||
|
|
||||||
try { // Make shortcuts
|
try {
|
||||||
const file = Constants.APP_NAME_FOR_HUMANS + '.lnk';
|
fs.writeFileSync(flag, '');
|
||||||
const icon_path = join(root, 'app.ico');
|
|
||||||
|
|
||||||
fs.copyFileSync(join(app, 'app.ico'), icon_path); // app-1.0.0/app.ico -> app.ico
|
|
||||||
|
|
||||||
for (const shortcut_path of [
|
|
||||||
join(updater.getKnownFolder('desktop'), file),
|
|
||||||
join(updater.getKnownFolder('programs'), Constants.APP_COMPANY, file)
|
|
||||||
]) {
|
|
||||||
if (!fs.existsSync(shortcut_path)) continue; // Don't update already deleted paths
|
|
||||||
|
|
||||||
updater.createShortcut({
|
|
||||||
target_path: join(root, 'Update.exe'),
|
|
||||||
shortcut_path,
|
|
||||||
arguments: '--processStart ' + basename(exec),
|
|
||||||
icon_path,
|
|
||||||
icon_index: 0,
|
|
||||||
description: Constants.APP_DESCRIPTION,
|
|
||||||
app_user_model_id: Constants.APP_ID,
|
|
||||||
working_directory: app
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
fs.writeFileSync(flag, 'true');
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
log('FirstRun', e);
|
log('FirstRun', e);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue