electron: removed workspaces, added sentry lib, electron-builder

This commit is contained in:
Steven Hugg 2021-07-10 14:28:02 -05:00
parent 10d04f9114
commit d31428aa42
8 changed files with 4489 additions and 646 deletions

View File

@ -23,18 +23,19 @@ all:
$(TSC)
npm run mkdoc
dist:
distro:
rm -fr $(TMP) && mkdir -p $(TMP)
git archive HEAD | tar x -C $(TMP)
cp -rp gen $(TMP)
rm -r $(TMP)/doc $(TMP)/meta $(TMP)/scripts $(TMP)/test* $(TMP)/tools $(TMP)/.[a-z]* $(TMP)/ts*.json
rm -r $(TMP)/doc $(TMP)/scripts $(TMP)/test* $(TMP)/tools $(TMP)/.[a-z]* $(TMP)/ts*.json # $(TMP)/meta
rm -f $(TMP)/javatari && mkdir -p $(TMP)/javatari && cp javatari.js/release/javatari/* $(TMP)/javatari/
tar cf - `cat electron.html | egrep "^<(script|link)" | egrep -o '"([^"]+).(js|css)"' | cut -d '"' -f2` | tar x -C $(TMP)
%.dist:
./node_modules/.bin/electron-packager $(TMP) --icon meta/icons/8bitworkshop-icon-1024.icns --out ./release --overwrite --platform $*
package: dist darwin.dist win32.dist linux.dist
desktop: distro
pushd $(TMP) && npm i && popd $(TMP)
mkdir -p $(TMP)/resources
./node_modules/.bin/electron-builder -mlw --project $(TMP) # --prepackaged $(TMP)
mv $(TMP)/dist/*.* ./release/
meta/electron.diff: index.html electron.html
-diff -u index.html electron.html > $@
@ -53,11 +54,11 @@ astrolibre.b64.txt: astrolibre.rom
VERSION := $(shell git tag -l --points-at HEAD)
syncdev: dist
syncdev: distro
cp config.js $(TMP)
aws --profile pzp s3 sync --follow-symlinks $(TMP)/ s3://8bitworkshop.com/dev
syncprod: dist
syncprod: distro
@[ "${VERSION}" ] || ( echo ">> No version set at HEAD, tag it first"; exit 1 )
echo Version: $(VERSION)
cp config.js $(TMP)

View File

@ -1,7 +1,22 @@
"use strict";
// preload.js for Electron app
const { ipcRenderer } = require('electron');
const fs = require('fs');
const modpath = require('path');
const _path = require('path');
const chokidar = require('chokidar');
const homeDirectory = require('os').homedir();
const wsroot = _path.join(homeDirectory, '8bitworkshop');
function getLocalDir() {
const _ui = window.ui_1 || window.ui || window; // TODO: module naming
var dir = _ui.repo_id || _ui.platform_id || 'default';
return _path.join(wsroot, dir);
}
function getLocalFilePath(path) {
return _path.join(getLocalDir(), path);
}
function isProbablyBinary(path, data) {
var score = 0;
@ -33,37 +48,84 @@ function isProbablyBinary(path, data) {
return score > 0;
}
// this is before startUI is called
process.once('loaded', () => {
// workspace root path
// reload() clears this, so we have to set it every time
var wsroot;
// from browser: read workspace file synchronously
window.getWorkspaceFile = function(path, filetype) {
if (wsroot == null) throw Error("no workspace root set");
try {
var fullpath = modpath.join(wsroot, modpath.normalize(path));
var data = fs.readFileSync(fullpath); // read binary
var buf = new Uint8Array(data); // convert to array
var isBinary = filetype != 'text' || isProbablyBinary(path, buf);
data = isBinary ? buf : data.toString('utf-8');
console.log("getWorkspaceFile", path, isBinary, data.length);
return data;
} catch (e) {
console.log(e);
return null;
var watcher;
var allfiles = new Set();
// get workspace root dir
// from browser: read workspace files asynchronously
window.alternateLocalFilesystem = {
getFileData: (path) => {
let fullpath = getLocalFilePath(path);
allfiles.add(fullpath);
if (!fs.existsSync(fullpath)) {
return null;
}
return new Promise( (resolve, reject) => {
fs.readFile(fullpath, (err,buf) => {
if (err) {
resolve(err);
} else {
let isBinary = isProbablyBinary(path, buf);
let data = isBinary ? buf : buf.toString('utf-8');
console.log("getWorkspaceFile", path, isBinary, data.length);
resolve(data);
}
});
});
},
setFileData: (path, data) => {
let fullpath = getLocalFilePath(path);
allfiles.add(fullpath);
let encoding = typeof data === 'string' ? 'utf8' : null;
console.log("setWorkspaceFile", fullpath, data.length);
return new Promise( (resolve, reject) => {
fs.mkdir(_path.dirname(fullpath), {recursive:true}, (err,dirpath) => {
fs.writeFile(fullpath, data, {encoding:encoding}, (err) => {
if (err) {
reject(err);
} else {
resolve();
}
});
});
});
}
}
// from browser: put workspace file
window.putWorkspaceFile = function(path, data) {
if (wsroot == null) throw Error("no workspace root set");
var fullpath = modpath.join(wsroot, modpath.normalize(path));
var encoding = typeof data === 'string' ? 'utf8' : null;
fs.writeFileSync(fullpath, data, {encoding:encoding});
}
// watch/unwatch files as browser loses/gains focus
window.addEventListener("blur", (e) => {
let localdir = getLocalDir();
if (!watcher && localdir) {
// watch files for changes
watcher = chokidar.watch(Array.from(allfiles), {
//awaitWriteFinish: {pollInterval:50,stabilityThreshold:300},
ignoreInitial: true
});
watcher.on('all', (event, path) => {
path = path.substring(localdir.length + 1); //strip off prefix
console.log('WATCH', event, path);
// we don't use awaitWriteFinish b/c we might close() the watcher
setTimeout(() => {
window.reloadWorkspaceFile(path);
}, 300);
});
console.log('watching', getLocalDir());
}
});
window.addEventListener("focus", (e) => {
if (watcher) {
watcher.close();
watcher = null;
}
console.log('stopped watching');
});
// from electron.js: set workspace root directory
/*
TODO
ipcRenderer.on('setWorkspaceRoot', (event, data) => {
wsroot = data.root;
var binpath = modpath.join(wsroot, 'bin');
var binpath = _path.join(wsroot, 'bin');
if (!fs.existsSync(binpath)) fs.mkdirSync(binpath, {});
console.log('setWorkspaceRoot', wsroot);
});
@ -72,4 +134,6 @@ process.once('loaded', () => {
var path = data.path;
window.reloadWorkspaceFile(path);
});
*/
console.log('loaded preload', window.alternateLocalFilesystem, window.startUI);
});

View File

@ -363,6 +363,7 @@ body {
<script src="src/codemirror/fastbasic.js"></script>
<script src="src/codemirror/basic.js"></script>
<script src="src/codemirror/wiz.js"></script>
<script src="src/codemirror/vasm.js"></script>
<link rel="stylesheet" href="css/codemirror.css">
<script src="codemirror/addon/edit/matchbrackets.js"></script>
<script src="codemirror/addon/search/search.js"></script>
@ -420,6 +421,7 @@ function require(modname) {
<script src="gen/common/devices.js"></script>
<script src="gen/common/cpu/MOS6502.js"></script>
<script src="gen/common/cpu/ZilogZ80.js"></script>
<script src="gen/common/cpu/ARM.js"></script>
<script src="gen/machine/vdp_z80.js"></script>
<script>
@ -435,28 +437,5 @@ $( ".dropdown-submenu" ).click(function(event) {
startUI();
</script>
<!-- Sentry error reporting -->
<script
src="https://browser.sentry-cdn.com/6.4.1/bundle.min.js"
integrity="sha384-THoc7rflwZFKTdZNgv6jLFFDn299Uv3t1SW5B4yGLvLiCRTYP9ys6vXZcMl95TQF"
crossorigin="anonymous"
></script>
<script>
Sentry.init({
dsn: 'https://bf329df3d1b34afa9f5b5e8ecd80ad11@o320878.ingest.sentry.io/1813925',
beforeBreadcrumb(breadcrumb, hint) {
if (breadcrumb.category === 'xhr' && typeof breadcrumb.data.url === 'string') {
if (breadcrumb.data.url.startsWith('http')) return null; // discard external scripts
}
return breadcrumb;
},
beforeSend(event, hint) {
const error = hint.originalException;
if (error instanceof EmuHalt) return null; // ignore EmuHalt
return event;
},
});
</script>
</body>
</html>

View File

@ -1,217 +1,14 @@
const { app, dialog, ipcMain, ipcRenderer, Menu, BrowserWindow } = require('electron')
"use strict";
const { app, Menu, BrowserWindow } = require('electron')
const modpath = require('path')
const fs = require('fs')
const {URLSearchParams} = require('url')
const isMac = process.platform === 'darwin'
const chokidar = require('chokidar')
const Store = require('electron-store');
const store = new Store();
const WSMETA_FILENAME = "8bitworkshop.json"
const README_FILENAME = "README.md"
// call updater
require('update-electron-app')()
///require('update-electron-app')()
// show error dialog
function showError(msg, detail) {
msg = msg.message || msg;
dialog.showMessageBoxSync({
type: "error",
message: msg,
detail: detail
});
}
// file watcher
class Workspace {
constructor(directory, meta) {
this.directory = directory;
this.mainfile = meta.mainfile;
this.platform = meta.platform;
if (!this.mainfile) throw new Error(`The "mainfile" key is missing in ${WSMETA_FILENAME}.`)
if (!this.platform) throw new Error(`The "platform" key is missing in ${WSMETA_FILENAME}.`)
var mainfilepath = this.getMainFilePath();
if (!fs.existsSync(mainfilepath)) throw new Error(`The file "${mainfilepath}" is missing.`);
console.log("workspace opened", this.directory, this.mainfile);
}
getMainFilePath() {
return modpath.join(this.directory, this.mainfile);
}
close() {
this.unwatch();
console.log("workspace closed", this.directory, this.mainfile);
}
watch(wnd) {
this.watcher = chokidar.watch(this.directory, {
awaitWriteFinish: false
});
this.watcher.on('all', (event, path) => {
switch (event) {
case 'change':
console.log(event, path);
wnd.webContents.send('fileChanged', {
path: modpath.relative(this.directory, path),
});
break;
}
});
console.log("watching workspace");
}
unwatch() {
if (this.watcher) {
this.watcher.close();
this.watcher = null;
console.log("un-watching workspace");
}
}
}
function readWorkspaceMetadata(directory) {
// check README file
var readmepath = modpath.join(directory, README_FILENAME);
if (fs.existsSync(readmepath)) {
let readme = fs.readFileSync(readmepath, 'utf8');
let sess = {};
// check README for main file
const re8main = /8bitworkshop.com[^)]+file=([^)&]+)/;
m = re8main.exec(readme);
if (m && m[1]) {
sess.mainfile = m[1];
}
// check README for proper platform
// unless we use githubURL=
const re8plat = /8bitworkshop.com[^)]+platform=([A-Za-z0-9._\-]+)/;
m = re8plat.exec(readme);
if (m) {
sess.platform = m[1];
}
if (sess.mainfile != null && sess.platform != null) return sess;
}
// check JSON file
var metapath = modpath.join(directory, WSMETA_FILENAME);
if (fs.existsSync(metapath)) {
return JSON.parse(fs.readFileSync(metapath, 'utf8'));
}
}
function writeWorkspaceMetadata(directory, meta) {
var metapath = modpath.join(directory, WSMETA_FILENAME);
fs.writeFileSync(metapath, JSON.stringify(meta), 'utf8');
}
function openWorkspace(wnd, ws) {
if (wnd.workspace) { wnd.workspace.close(); }
wnd.workspace = ws;
wnd.on('closed', () => {
ws.close();
});
var qs = new URLSearchParams();
qs.set('electron_ws', 1);
qs.set('repo', ws.directory);
qs.set('file', ws.mainfile);
qs.set('platform', ws.platform);
console.log(qs);
wnd.loadURL(`file://${__dirname}/electron.html?${qs}`).then(() => {
wnd.webContents.send('setWorkspaceRoot', {root:ws.directory});
});
}
function getActiveWorkspace() {
var wnd = BrowserWindow.getFocusedWindow();
return wnd && wnd.workspace;
}
// TODO: doesn't work if browser window reloads itself
function reloadCurrentWindow() {
var wnd = BrowserWindow.getFocusedWindow();
if (wnd.workspace) {
openWorkspace(wnd, wnd.workspace);
} else {
wnd.reload();
}
}
// TODO: better way to get this?
function getCurrentPlatform(wnd) {
var url = wnd.webContents.getURL();
if (url != null) {
console.log(url);
var m = /platform=([^&]+)/.exec(url);
if (m) return m[1];
}
}
function openWorkspaceWindow(wspath) {
try {
// replace current window
var wnd = BrowserWindow.getFocusedWindow() || createWindow();
// read metadata file
var meta = readWorkspaceMetadata(wspath);
// does it exist?
if (meta == null) {
// create a new workspace?
var cancel = dialog.showMessageBoxSync(wnd, {
type: 'question',
title: 'Create Workspace?',
message: `Project metadata not found. Create new ${getCurrentPlatform(wnd)||""} project in this directory?`,
detail: wspath,
buttons: ['Create', 'Cancel'],
});
if (!cancel) {
var platform = getCurrentPlatform(wnd);
// choose main file
var files = dialog.showOpenDialogSync({
message: `Choose the main file of your ${platform} project, or create one.`,
defaultPath: wspath,
properties: ['openFile','promptToCreate'],
});
if (files != null) {
var mainfile = modpath.relative(wspath, files[0]);
// write new metadata
meta = {
platform: platform,
mainfile: mainfile,
};
console.log(meta);
if (meta.platform == null) {
showError("Can't determine current platform.");
} else {
writeWorkspaceMetadata(wspath, meta);
openWorkspaceWindow(wspath);
}
}
}
} else {
console.log(meta);
var ws = new Workspace(wspath, meta);
openWorkspace(wnd, ws);
app.addRecentDocument(wspath);
}
} catch (e) {
showError(e);
}
}
function openDefaultWorkspace() {
if (process.argv.length >= 3) {
openWorkspaceWindow(modpath.resolve(process.argv[2]));
} else {
createWindow();
}
}
function openWorkspaceDialog() {
dialog.showOpenDialog({
title: "Open Workspace",
properties: ['openDirectory'],
message: "Choose the directory that holds your source files.",
}).then((rtn) => {
if (!rtn.canceled && rtn.filePaths && rtn.filePaths.length > 0) {
var path = rtn.filePaths[0];
openWorkspaceWindow(path);
}
});
}
// init sentry
require('@sentry/electron').init({ dsn: "https://bf329df3d1b34afa9f5b5e8ecd80ad11@o320878.ingest.sentry.io/1813925" });
function openURL(url) {
return async () => {
@ -220,6 +17,37 @@ function openURL(url) {
}
}
function createWindow () {
// Create the browser window.
const win = new BrowserWindow({
width: 1024,
height: 768,
backgroundColor: '#fff',
webPreferences: {
preload: modpath.join(__dirname, './electron-preload.js'),
nodeIntegration: false,
enableRemoteModule: false,
contextIsolation: false,
sandbox: false,
}
})
// and load the index.html of the app.
win.loadFile('electron.html', {
search: 'electron=1&repo=/'
});
// Maximize
win.maximize();
return win;
}
// TODO: doesn't work if browser window reloads itself
function reloadCurrentWindow() {
var wnd = BrowserWindow.getFocusedWindow();
wnd.reload();
}
function buildMenu() {
const template = [
@ -242,28 +70,6 @@ function buildMenu() {
{
label: 'File',
submenu: [
{
label: 'New Playground',
click: createWindow,
accelerator: 'CmdOrCtrl+N',
},
{
label: 'Open Workspace...',
click: openWorkspaceDialog,
accelerator: 'CmdOrCtrl+O',
},
// When a file is requested from the recent documents menu, the open-file event of app module will be emitted for it.
{
"label":"Open Recent",
"role":"recentdocuments",
"submenu":[
{
"label":"Clear Recent",
"role":"clearrecentdocuments"
}
]
},
{ type: 'separator' },
isMac ? { role: 'close' } : { role: 'quit' }
]
},
@ -365,38 +171,10 @@ function buildMenu() {
Menu.setApplicationMenu(menu)
}
function createWindow () {
// Create the browser window.
const win = new BrowserWindow({
width: 1024,
height: 768,
backgroundColor: '#fff',
webPreferences: {
preload: modpath.join(__dirname, './electron-preload.js'),
nodeIntegration: false,
enableRemoteModule: false,
contextIsolation: false,
sandbox: false,
}
})
// and load the index.html of the app.
win.loadFile('electron.html', {
search: 'repo=/'
})
// Open the DevTools.
//win.webContents.openDevTools()
// Maximize
win.maximize();
return win;
}
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.whenReady().then(buildMenu).then(openDefaultWorkspace)
app.whenReady().then(buildMenu).then(createWindow)
// Quit when all windows are closed, except on macOS. There, it's common
// for applications and their menu bar to stay active until the user quits
@ -415,6 +193,7 @@ app.on('activate', () => {
}
})
/* TODO
app.on('browser-window-focus', (e) => {
var ws = e.sender.workspace;
if (ws) ws.unwatch();
@ -424,19 +203,4 @@ app.on('browser-window-blur', (e) => {
var ws = e.sender.workspace;
if (ws) ws.watch(e.sender);
})
app.on('open-file', (event, path) => {
openWorkspaceWindow(path);
})
// In this file you can include the rest of your app's specific main process
// code. You can also put them in separate files and require them here.
// Register IPC messages
// https://stackoverflow.com/questions/52236641/electron-ipc-and-nodeintegration
/*
ipcMain.on('hello', (event, message) => {
console.log(event);
});
*/

View File

@ -1,5 +1,5 @@
--- index.html 2020-12-08 10:30:08.000000000 -0600
+++ electron.html 2020-12-08 11:57:52.000000000 -0600
--- index.html 2021-07-09 15:15:12.000000000 -0500
+++ electron.html 2021-07-10 13:34:48.000000000 -0500
@@ -3,18 +3,7 @@
<head>
@ -223,3 +223,32 @@
<script src="jquery/jquery.min.js"></script>
@@ -614,28 +437,5 @@
startUI();
</script>
-<!-- Sentry error reporting -->
-<script
- src="https://browser.sentry-cdn.com/6.4.1/bundle.min.js"
- integrity="sha384-THoc7rflwZFKTdZNgv6jLFFDn299Uv3t1SW5B4yGLvLiCRTYP9ys6vXZcMl95TQF"
- crossorigin="anonymous"
-></script>
-<script>
-Sentry.init({
- dsn: 'https://bf329df3d1b34afa9f5b5e8ecd80ad11@o320878.ingest.sentry.io/1813925',
- beforeBreadcrumb(breadcrumb, hint) {
- if (breadcrumb.category === 'xhr' && typeof breadcrumb.data.url === 'string') {
- if (breadcrumb.data.url.startsWith('http')) return null; // discard external scripts
- }
- return breadcrumb;
- },
- beforeSend(event, hint) {
- const error = hint.originalException;
- if (error instanceof EmuHalt) return null; // ignore EmuHalt
- return event;
- },
-});
-</script>
-
</body>
</html>

4539
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,20 +1,20 @@
{
"name": "8bitworkshop",
"version": "3.7.2",
"version": "3.8.0b1",
"author": "Steven Hugg",
"description": "8bitworkshop.com",
"category": "Development",
"description": "Desktop version of 8bitworkshop.com retro programming IDE",
"repository": {
"type": "git",
"url": "git+https://github.com/sehugg/8bitworkshop.git"
},
"license": "GPL-3.0",
"dependencies": {
"@sentry/electron": "^2.5.1",
"binaryen": "^101.0.0",
"chokidar": "^3.5.0",
"electron-store": "^6.0.1",
"jquery": "^3.5.1",
"reflect-metadata": "^0.1.13",
"update-electron-app": "^1.5.0"
"reflect-metadata": "^0.1.13"
},
"devDependencies": {
"@types/bootbox": "^5.1.3",
@ -30,6 +30,7 @@
"clipboard": "^2.0.6",
"command-exists": "^1.2.9",
"electron": "^9.4.0",
"electron-builder": "^22.11.7",
"electron-packager": "^15.2.0",
"file-saver": "^2.0.5",
"heapdump": "^0.3.15",
@ -51,10 +52,6 @@
"typescript-formatter": "^7.2.2",
"vgm-parser": "^0.6.3"
},
"directories": {
"doc": "doc",
"test": "tests"
},
"scripts": {
"build": "make",
"test": "npm run test-node",
@ -82,5 +79,13 @@
"bugs": {
"url": "https://github.com/sehugg/8bitworkshop/issues"
},
"homepage": "https://github.com/sehugg/8bitworkshop#readme"
"homepage": "https://github.com/sehugg/8bitworkshop#readme",
"build": {
"appId": "com.8bitworkshop.ide",
"icon": "meta/icons/8bitworkshop-icon-1024.png",
"copyright": "Copyright (c) 2021 Puzzling Plans LLC",
"linux": {
"category": "Development"
}
}
}

View File

@ -183,19 +183,14 @@ function unsetLastPreset() {
function initProject() {
var basefs : ProjectFilesystem = new WebPresetsFileSystem(platform_id);
//basefs = new FirebaseProjectFilesystem("TEST", "TEST");
var filesystem = new OverlayFilesystem(
basefs,
new LocalForageFilesystem(store));
if (isElectron) {
console.log('using electron with local filesystem', alternateLocalFilesystem);
var filesystem = new OverlayFilesystem(basefs, alternateLocalFilesystem)
} else {
var filesystem = new OverlayFilesystem(basefs, new LocalForageFilesystem(store));
}
current_project = new CodeProject(newWorker(), platform_id, platform, filesystem);
projectWindows = new ProjectWindows($("#workspace")[0] as HTMLElement, current_project);
if (isElectronWorkspace) {
// TODO
/*
current_project.persistent = false;
current_project.callbackGetRemote = getElectronFile;
current_project.callbackStoreFile = putWorkspaceFile;
*/
}
current_project.callbackBuildResult = (result:WorkerResult) => {
setCompileOutput(result);
};
@ -1080,9 +1075,7 @@ async function updateSelector() {
await populateFiles(sel, "Local Files", "", foundFiles);
finishSelector(sel);
} else {
if (!isElectronWorkspace) {
sel.append($("<option />").val('/').text('Leave Repository'));
}
sel.append($("<option />").val('/').text('Leave Repository'));
$("#repo_name").text(getFilenameForPath(repo_id)+'/').show();
// repo: populate all files
await populateFiles(sel, repo_id, "", {});
@ -1958,8 +1951,7 @@ export var qs = (function (a : string[]) {
return b;
})(window.location.search.substr(1).split('&'));
const isElectronWorkspace = qs['electron_ws'];
const isElectron = qs['electron'] || isElectronWorkspace;
const isElectron = !!qs['electron'];
function globalErrorHandler(msgevent) {
var msg = (msgevent.message || msgevent.error || msgevent)+"";
@ -2220,13 +2212,7 @@ function setPlatformUI() {
$(".platform_name").text(name || platform_id);
}
// start
export async function startUI() {
// import from github?
if (qs['githubURL']) {
importProjectFromGithub(qs['githubURL'], true);
return;
}
export function getPlatformAndRepo() {
// add default platform?
// TODO: do this after repo_id
platform_id = qs['platform'] || (hasLocalStorage && localStorage.getItem("__lastplatform"));
@ -2249,6 +2235,16 @@ export async function startUI() {
repo_id = '';
delete qs['repo'];
}
}
// start
export async function startUI() {
// import from github?
if (qs['githubURL']) {
importProjectFromGithub(qs['githubURL'], true);
return;
}
getPlatformAndRepo();
setupSplits();
// create store
store_id = repo_id || getBasePlatform(platform_id);
@ -2340,7 +2336,7 @@ function redirectToHTTPS() {
// redirect to HTTPS after script loads?
redirectToHTTPS();
//// ELECTRON STUFF
//// ELECTRON (and other external) STUFF
export function setTestInput(path: string, data: FileData) {
platform.writeFile(path, data);
@ -2362,29 +2358,21 @@ export function emulationHalted(err: EmuHalt) {
}
// get remote file from local fs
declare var getWorkspaceFile, putWorkspaceFile;
export function getElectronFile(url:string, success:(text:string|Uint8Array)=>void, datatype:'text'|'arraybuffer') {
// TODO: we have to split() to strip off presets/platform, yukky
var contents = getWorkspaceFile(url.split('/',3)[2], datatype);
if (contents != null) {
success(contents); // return result
} else {
getWithBinary(url, success, datatype); // try to load from presets/platform via GET
}
}
export function reloadWorkspaceFile(path: string) {
declare var alternateLocalFilesystem : ProjectFilesystem;
export async function reloadWorkspaceFile(path: string) {
var oldval = current_project.filedata[path];
if (oldval != null) {
var datatype = typeof oldval == 'string' ? 'text' : 'arraybuffer';
projectWindows.updateFile(path, getWorkspaceFile(path, datatype));
projectWindows.updateFile(path, await alternateLocalFilesystem.getFileData(path));
console.log('updating file', path);
}
}
function writeOutputROMFile() {
if (isElectronWorkspace && current_output instanceof Uint8Array) {
if (isElectron && current_output instanceof Uint8Array) {
var prefix = getFilenamePrefix(getCurrentMainFilename());
var suffix = (platform.getROMExtension && platform.getROMExtension(current_output))
|| "-" + getBasePlatform(platform_id) + ".bin";
putWorkspaceFile(`bin/${prefix}${suffix}`, current_output);
alternateLocalFilesystem.setFileData(`bin/${prefix}${suffix}`, current_output);
}
}
export function highlightSearch(query: string) { // TODO: filename?