@dodona/papyros
Version:
Scratchpad for multiple programming languages in the browser.
116 lines • 5.39 kB
JavaScript
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
import { State, stateProperty } from "@dodona/lit-state";
import { Debugger } from "./Debugger";
import { Runner } from "./Runner";
import { InputOutput } from "./InputOutput";
import { Constants } from "./Constants";
import { Examples } from "./Examples";
import { BackendManager } from "../../communication/BackendManager";
import { makeChannel } from "sync-message";
import { I18n } from "./I18n";
import { Test } from "./Test";
import { PapyrosLaunchError, ServiceWorkerRegistrationError } from "./PapyrosErrors";
export class Papyros extends State {
constructor() {
super(...arguments);
this.debugger = new Debugger(this);
this.runner = new Runner(this);
this.io = new InputOutput(this);
this.constants = new Constants();
this.examples = new Examples(this);
this.i18n = new I18n();
this.test = new Test(this);
this.errorHandler = () => { };
this.serviceWorkerName = "InputServiceWorker.js";
}
/**
* Launch this instance of Papyros, making it ready to run code
* @return {Promise<Papyros>} Promise of launching, chainable
*/
launch() {
return __awaiter(this, void 0, void 0, function* () {
if (!(yield this.configureInput())) {
alert(this.i18n.t("Papyros.service_worker_error"));
}
else {
try {
yield this.runner.launch();
}
catch (e) {
this.errorHandler(new PapyrosLaunchError("Error launching papyros after registering service worker", { cause: e }));
if (confirm(this.i18n.t("Papyros.launch_error"))) {
return this.launch();
}
}
}
return this;
});
}
/**
* Set an error handler in papyros. Papyros will pass any errors to this handler that should be investigated but don't bubble up naturally.
*
* @param handler An error handler (e.g. something that passes the error on to sentry)
*/
setErrorHandler(handler) {
this.errorHandler = handler;
}
/**
* Configure how user input is handled within Papyros
* By default, we will try to use SharedArrayBuffers
* If this option is not available, the optional arguments in the channelOptions config are used
* They are needed to register a service worker to handle communication between threads
* @return {Promise<boolean>} Promise of configuring input
*/
configureInput() {
return __awaiter(this, void 0, void 0, function* () {
if (typeof SharedArrayBuffer === "undefined") {
if (!this.serviceWorkerName || !("serviceWorker" in navigator)) {
return false;
}
try {
yield navigator.serviceWorker.register(this.serviceWorkerName, { scope: "/" });
BackendManager.channel = makeChannel({ serviceWorker: { scope: "/" } });
yield this.waitForActiveRegistration();
}
catch (e) {
this.errorHandler(new ServiceWorkerRegistrationError("Error registering service worker", { cause: e }));
return false;
}
}
else {
BackendManager.channel = makeChannel({ atomics: {} });
}
return true;
});
}
waitForActiveRegistration() {
return __awaiter(this, arguments, void 0, function* (timeout = 5000) {
return new Promise((resolve, reject) => {
const timeoutHandle = setTimeout(() => reject(new Error("Timed out waiting for activated service worker")), timeout);
navigator.serviceWorker.ready.then(() => {
clearTimeout(timeoutHandle);
resolve();
});
});
});
}
}
__decorate([
stateProperty
], Papyros.prototype, "serviceWorkerName", void 0);
export const papyros = new Papyros();
//# sourceMappingURL=Papyros.js.map