@dodona/papyros 0.1.7-rc → 0.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +37 -12
- package/dist/{Main.d.ts → App.d.ts} +0 -0
- package/dist/Backend.d.ts +3 -3
- package/dist/CodeEditor.d.ts +14 -3
- package/dist/Constants.d.ts +7 -3
- package/dist/InputManager.d.ts +32 -0
- package/dist/InputServiceWorker.d.ts +1 -0
- package/dist/OutputManager.d.ts +23 -0
- package/dist/Papyros.d.ts +32 -20
- package/dist/PapyrosEvent.d.ts +1 -0
- package/dist/ProgrammingLanguage.d.ts +0 -2
- package/dist/StatusPanel.d.ts +17 -0
- package/dist/examples/Examples.d.ts +6 -0
- package/dist/examples/JavaScriptExamples.d.ts +5 -0
- package/dist/examples/PythonExamples.d.ts +11 -0
- package/dist/index.js +2 -0
- package/dist/index.js.LICENSE.txt +7 -0
- package/dist/inputServiceWorker.js +1 -0
- package/dist/library.d.ts +9 -0
- package/dist/util/HTMLShapes.d.ts +2 -0
- package/dist/util/Util.d.ts +21 -0
- package/dist/workers/input/InputWorker.d.ts +6 -0
- package/dist/workers/javascript/JavaScriptWorker.worker.d.ts +2 -1
- package/dist/workers/python/Pyodide.d.ts +9 -0
- package/dist/workers/python/PythonWorker.worker.d.ts +2 -1
- package/package.json +32 -31
- package/dist/Backend.js +0 -133
- package/dist/Backend.js.map +0 -1
- package/dist/BackendManager.js +0 -39
- package/dist/BackendManager.js.map +0 -1
- package/dist/CodeEditor.js +0 -146
- package/dist/CodeEditor.js.map +0 -1
- package/dist/Constants.js +0 -16
- package/dist/Constants.js.map +0 -1
- package/dist/Main.js +0 -42
- package/dist/Main.js.map +0 -1
- package/dist/Papyros.css +0 -9
- package/dist/Papyros.js +0 -390
- package/dist/Papyros.js.map +0 -1
- package/dist/PapyrosEvent.js +0 -2
- package/dist/PapyrosEvent.js.map +0 -1
- package/dist/ProgrammingLanguage.js +0 -23
- package/dist/ProgrammingLanguage.js.map +0 -1
- package/dist/Translations.d.ts +0 -40
- package/dist/Translations.js +0 -39
- package/dist/Translations.js.map +0 -1
- package/dist/util/Logging.js +0 -48
- package/dist/util/Logging.js.map +0 -1
- package/dist/workers/javascript/JavaScriptWorker.worker.js +0 -91
- package/dist/workers/javascript/JavaScriptWorker.worker.js.map +0 -1
- package/dist/workers/python/PythonWorker.worker.js +0 -161
- package/dist/workers/python/PythonWorker.worker.js.map +0 -1
- package/dist/workers/python/init.py.d.ts +0 -1
- package/dist/workers/python/init.py.js +0 -2
- package/dist/workers/python/init.py.js.map +0 -1
package/README.md
CHANGED
|
@@ -12,29 +12,22 @@
|
|
|
12
12
|
</a>
|
|
13
13
|
</p>
|
|
14
14
|
|
|
15
|
-
Papyros is a programming scratchpad in the browser. It allows running
|
|
16
|
-
|
|
15
|
+
Papyros is a programming scratchpad in the browser. It allows running code
|
|
16
|
+
directly in your browser, no installation required. Right now, the focus in on providing a great experience for Python, while also supporting JavaScript.
|
|
17
17
|
By taking away obstacles between students and coding, the learning experience becomes
|
|
18
|
-
smoother and less error-prone.
|
|
19
|
-
|
|
20
|
-
Papyros aims to be:
|
|
21
|
-
|
|
22
|
-
- **Easy to use** by having minimal installation instructions and an intuitive user interface
|
|
23
|
-
- **Flexible** to support many programming languages
|
|
18
|
+
smoother and less error-prone.
|
|
24
19
|
|
|
25
20
|
Currently, Papyros provides support for the following programming languages:
|
|
26
21
|
- Python, powered by [Pyodide](https://pyodide.org/en/stable/)
|
|
27
22
|
- JavaScript, powered by your browser
|
|
28
23
|
|
|
29
|
-
##
|
|
24
|
+
## Using Papyros in your own project
|
|
30
25
|
|
|
31
26
|
You can install Papyros on your system using npm:
|
|
32
27
|
```shell
|
|
33
28
|
npm install -g @dodona/papyros
|
|
34
29
|
```
|
|
35
30
|
|
|
36
|
-
## Usage
|
|
37
|
-
|
|
38
31
|
Papyros currently supports two modes of operation: stand-alone and embedded.
|
|
39
32
|
|
|
40
33
|
In stand-alone mode, Papyros runs as a full application in the browser.
|
|
@@ -51,6 +44,38 @@ The following options are supported:
|
|
|
51
44
|
- standAlone: Whether to operate in stand-alone or embedded mode as described above.
|
|
52
45
|
- locale: The locale to use, currently English and Dutch translations are provided.
|
|
53
46
|
- programmingLanguage: The language to use in the CodeEditor and Backend
|
|
47
|
+
- inputMode: How the users can provide input, according to the [InputMode enum](/src/InputManager.ts)
|
|
48
|
+
|
|
49
|
+
Furthermore, you can provide fine-grained configuration in embedded mode by providing RenderOptions
|
|
50
|
+
to each main component in the application. You minimally need to specify the ID of the parent element.
|
|
51
|
+
You can also specify attributes, such as style or data, or classNames to be used.
|
|
52
|
+
The main components are the following:
|
|
53
|
+
- code -> the CodeEditor
|
|
54
|
+
- panel -> the StatusPanel in the CodeEditor
|
|
55
|
+
- input -> The field for the user input
|
|
56
|
+
- output -> The panel for output of the code
|
|
57
|
+
|
|
58
|
+
### User input
|
|
59
|
+
|
|
60
|
+
Important to note is that handling asynchronous input in a synchronous way is not straightforward.
|
|
61
|
+
This requires advanced features which are not available by default in your browser. We support two options
|
|
62
|
+
|
|
63
|
+
The most efficient and practical way is using SharedArrayBuffers, which requires the presence of certain HTTP headers.
|
|
64
|
+
The following headers must be set on resources using Papyros.
|
|
65
|
+
```json
|
|
66
|
+
'Cross-Origin-Opener-Policy': 'same-origin',
|
|
67
|
+
'Cross-Origin-Embedder-Policy': 'require-corp'
|
|
68
|
+
```
|
|
69
|
+
If you are also embedding other components (such as iframes) in those pages, you will also need to set
|
|
70
|
+
'Cross-Origin-Resource-Policy' to 'cross-origin' to make them work correctly. In order to limit the effect of this
|
|
71
|
+
change, it is advised to restrict access using the 'Access-Control-Allow-Origin'-header to prevent abuse of including code.
|
|
72
|
+
|
|
73
|
+
If you would like to use this project without enabling these HTTP headers, we provide a solution using a service worker.
|
|
74
|
+
If your application does not use a service worker yet, a default service worker is pre-built and included in the package.
|
|
75
|
+
Simply copy the file located [here](dist/inputServiceWorker.js) to a location of choice in your application where it can be served.
|
|
76
|
+
Then, before launching your instance of Papyros, make a call to configureInput with the location of the folder and the name of the file.
|
|
77
|
+
|
|
78
|
+
If you already use a service worker, simply include our functionality in your existing worker using imports. An example can be found [here](src/InputServiceWorker.ts). Afterwards, inform Papyros of this using configureInput as above.
|
|
54
79
|
|
|
55
80
|
## Documentation
|
|
56
81
|
|
|
@@ -78,4 +103,4 @@ You can view the results in your browser by visting http://localhost:8080.
|
|
|
78
103
|
|
|
79
104
|
## Try it online
|
|
80
105
|
|
|
81
|
-
Start coding immediately in your [browser](https://
|
|
106
|
+
Start coding immediately in your [browser](https://papyros.dodona.be/).
|
|
File without changes
|
package/dist/Backend.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { PapyrosEvent } from "./PapyrosEvent";
|
|
2
|
+
import { Channel } from "sync-message";
|
|
2
3
|
export declare abstract class Backend {
|
|
3
4
|
onEvent: (e: PapyrosEvent) => any;
|
|
4
5
|
runId: number;
|
|
@@ -6,11 +7,10 @@ export declare abstract class Backend {
|
|
|
6
7
|
/**
|
|
7
8
|
* Initialize the backend, setting up any globals required
|
|
8
9
|
* @param {function(PapyrosEvent):void} onEvent Callback for when events occur
|
|
9
|
-
* @param {
|
|
10
|
-
* @param {Int32Array} inputMetaData Optional shared buffer for metadata about input
|
|
10
|
+
* @param {Channel} channel for communication with the main thread
|
|
11
11
|
* @return {Promise<void>} Promise of launching
|
|
12
12
|
*/
|
|
13
|
-
launch(onEvent: (e: PapyrosEvent) => void,
|
|
13
|
+
launch(onEvent: (e: PapyrosEvent) => void, channel: Channel): Promise<void>;
|
|
14
14
|
abstract _runCodeInternal(code: string): Promise<any>;
|
|
15
15
|
/**
|
|
16
16
|
* Validate and run arbitrary code
|
package/dist/CodeEditor.d.ts
CHANGED
|
@@ -1,12 +1,23 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { LanguageSupport } from "@codemirror/language";
|
|
2
|
+
import { Compartment, Extension } from "@codemirror/state";
|
|
2
3
|
import { ProgrammingLanguage } from "./ProgrammingLanguage";
|
|
3
4
|
import { EditorView } from "@codemirror/view";
|
|
5
|
+
import { RenderOptions } from "./util/Util";
|
|
4
6
|
export declare class CodeEditor {
|
|
5
7
|
editorView: EditorView;
|
|
6
8
|
languageCompartment: Compartment;
|
|
7
9
|
indentCompartment: Compartment;
|
|
8
|
-
|
|
9
|
-
|
|
10
|
+
placeholderCompartment: Compartment;
|
|
11
|
+
panelCompartment: Compartment;
|
|
12
|
+
constructor(language: ProgrammingLanguage, editorPlaceHolder: string, initialCode?: string, indentLength?: number);
|
|
13
|
+
render(options: RenderOptions, panel?: HTMLElement): HTMLElement;
|
|
14
|
+
setLanguage(language: ProgrammingLanguage, editorPlaceHolder: string): void;
|
|
10
15
|
setIndentLength(indentLength: number): void;
|
|
16
|
+
setPanel(panel: HTMLElement): void;
|
|
11
17
|
getCode(): string;
|
|
18
|
+
setCode(code: string): void;
|
|
19
|
+
focus(): void;
|
|
20
|
+
static getIndentUnit(indentLength: number): string;
|
|
21
|
+
static getLanguageSupport(language: ProgrammingLanguage): LanguageSupport;
|
|
22
|
+
static getExtensions(): Array<Extension>;
|
|
12
23
|
}
|
package/dist/Constants.d.ts
CHANGED
|
@@ -1,15 +1,19 @@
|
|
|
1
1
|
import { ProgrammingLanguage } from "./ProgrammingLanguage";
|
|
2
2
|
export declare const MAIN_APP_ID = "papyros";
|
|
3
3
|
export declare const OUTPUT_TA_ID = "code-output-area";
|
|
4
|
+
export declare const INPUT_AREA_WRAPPER_ID = "code-input-area-wrapper";
|
|
4
5
|
export declare const INPUT_TA_ID = "code-input-area";
|
|
5
6
|
export declare const EDITOR_WRAPPER_ID = "code-area";
|
|
7
|
+
export declare const PANEL_WRAPPER_ID = "code-status-panel";
|
|
6
8
|
export declare const STATE_SPINNER_ID = "state-spinner";
|
|
7
9
|
export declare const APPLICATION_STATE_TEXT_ID = "application-state-text";
|
|
8
10
|
export declare const RUN_BTN_ID = "run-code-btn";
|
|
9
|
-
export declare const
|
|
11
|
+
export declare const STOP_BTN_ID = "stop-btn";
|
|
12
|
+
export declare const SEND_INPUT_BTN_ID = "send-input-btn";
|
|
13
|
+
export declare const SWITCH_INPUT_MODE_A_ID = "switch-input-mode";
|
|
10
14
|
export declare const PROGRAMMING_LANGUAGE_SELECT_ID = "programming-language-select";
|
|
11
15
|
export declare const DEFAULT_PROGRAMMING_LANGUAGE = ProgrammingLanguage.Python;
|
|
16
|
+
export declare const EXAMPLE_SELECT_ID = "example-select";
|
|
12
17
|
export declare const LOCALE_SELECT_ID = "locale-select";
|
|
13
18
|
export declare const DEFAULT_LOCALE = "nl";
|
|
14
|
-
export declare const
|
|
15
|
-
export declare const SERVICE_WORKER_PATH = "./inputServiceWorker.js";
|
|
19
|
+
export declare const DEFAULT_SERVICE_WORKER = "inputServiceWorker.js";
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { PapyrosEvent } from "./PapyrosEvent";
|
|
2
|
+
import { RenderOptions } from "./util/Util";
|
|
3
|
+
import { Channel } from "sync-message";
|
|
4
|
+
export declare enum InputMode {
|
|
5
|
+
Interactive = "interactive",
|
|
6
|
+
Batch = "batch"
|
|
7
|
+
}
|
|
8
|
+
export declare const INPUT_MODES: InputMode[];
|
|
9
|
+
interface InputSession {
|
|
10
|
+
lineNr: number;
|
|
11
|
+
}
|
|
12
|
+
export declare class InputManager {
|
|
13
|
+
renderOptions: RenderOptions;
|
|
14
|
+
inputMode: InputMode;
|
|
15
|
+
waiting: boolean;
|
|
16
|
+
batchInput: string;
|
|
17
|
+
onSend: () => void;
|
|
18
|
+
session: InputSession;
|
|
19
|
+
channel: Channel;
|
|
20
|
+
messageId: string;
|
|
21
|
+
constructor(onSend: () => void, inputMode: InputMode);
|
|
22
|
+
get enterButton(): HTMLButtonElement;
|
|
23
|
+
get inputArea(): HTMLInputElement;
|
|
24
|
+
render(options?: RenderOptions): void;
|
|
25
|
+
setInputMode(inputMode: InputMode): void;
|
|
26
|
+
setWaiting(waiting: boolean, prompt?: string): void;
|
|
27
|
+
sendLine(): Promise<boolean>;
|
|
28
|
+
onInput(e?: PapyrosEvent): Promise<void>;
|
|
29
|
+
onRunStart(): void;
|
|
30
|
+
onRunEnd(): void;
|
|
31
|
+
}
|
|
32
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { PapyrosEvent } from "./PapyrosEvent";
|
|
2
|
+
import { RenderOptions } from "./util/Util";
|
|
3
|
+
export interface FriendlyError {
|
|
4
|
+
name: string;
|
|
5
|
+
traceback?: string;
|
|
6
|
+
info?: string;
|
|
7
|
+
why?: string;
|
|
8
|
+
what?: string;
|
|
9
|
+
where?: string;
|
|
10
|
+
}
|
|
11
|
+
export declare class OutputManager {
|
|
12
|
+
outputAreaId: string;
|
|
13
|
+
options: RenderOptions;
|
|
14
|
+
get outputArea(): HTMLElement;
|
|
15
|
+
renderNextElement(html: string): void;
|
|
16
|
+
spanify(text: string, ignoreEmpty?: boolean): string;
|
|
17
|
+
showOutput(output: PapyrosEvent): void;
|
|
18
|
+
showError(error: FriendlyError | string): void;
|
|
19
|
+
render(options: RenderOptions): HTMLElement;
|
|
20
|
+
reset(): void;
|
|
21
|
+
onRunStart(): void;
|
|
22
|
+
onRunEnd(): void;
|
|
23
|
+
}
|
package/dist/Papyros.d.ts
CHANGED
|
@@ -2,57 +2,69 @@ import "./Papyros.css";
|
|
|
2
2
|
import { Remote } from "comlink";
|
|
3
3
|
import { Backend } from "./Backend";
|
|
4
4
|
import { CodeEditor } from "./CodeEditor";
|
|
5
|
+
import { InputManager, InputMode } from "./InputManager";
|
|
5
6
|
import { PapyrosEvent } from "./PapyrosEvent";
|
|
6
7
|
import { ProgrammingLanguage } from "./ProgrammingLanguage";
|
|
8
|
+
import { RenderOptions, ButtonOptions } from "./util/Util";
|
|
9
|
+
import { StatusPanel } from "./StatusPanel";
|
|
10
|
+
import { OutputManager } from "./OutputManager";
|
|
7
11
|
declare enum PapyrosState {
|
|
8
12
|
Loading = "loading",
|
|
9
13
|
Running = "running",
|
|
10
14
|
AwaitingInput = "awaiting_input",
|
|
11
|
-
|
|
15
|
+
Stopping = "stopping",
|
|
12
16
|
Ready = "ready"
|
|
13
17
|
}
|
|
14
18
|
declare class PapyrosStateManager {
|
|
15
19
|
state: PapyrosState;
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
constructor();
|
|
20
|
+
statusPanel: StatusPanel;
|
|
21
|
+
get runButton(): HTMLButtonElement;
|
|
22
|
+
get stopButton(): HTMLButtonElement;
|
|
23
|
+
constructor(statusPanel: StatusPanel, onRunClicked: () => void, onStopClicked: () => void);
|
|
21
24
|
setState(state: PapyrosState, message?: string): void;
|
|
25
|
+
render(options: RenderOptions): HTMLElement;
|
|
22
26
|
}
|
|
23
27
|
interface PapyrosCodeState {
|
|
24
28
|
programmingLanguage: ProgrammingLanguage;
|
|
25
29
|
editor: CodeEditor;
|
|
26
30
|
backend: Remote<Backend>;
|
|
27
31
|
runId: number;
|
|
28
|
-
outputArea: HTMLInputElement;
|
|
29
|
-
}
|
|
30
|
-
interface PapyrosInputState {
|
|
31
|
-
lineNr: number;
|
|
32
|
-
textEncoder: TextEncoder;
|
|
33
|
-
inputArea: HTMLInputElement;
|
|
34
|
-
inputTextArray?: Uint8Array;
|
|
35
|
-
inputMetaData?: Int32Array;
|
|
36
32
|
}
|
|
37
33
|
interface PapyrosConfig {
|
|
38
34
|
standAlone: boolean;
|
|
39
|
-
locale: string;
|
|
40
35
|
programmingLanguage: ProgrammingLanguage;
|
|
36
|
+
locale: string;
|
|
37
|
+
inputMode: InputMode;
|
|
38
|
+
}
|
|
39
|
+
interface PapyrosRenderOptions {
|
|
40
|
+
papyros?: RenderOptions;
|
|
41
|
+
code?: RenderOptions;
|
|
42
|
+
panel?: RenderOptions;
|
|
43
|
+
input?: RenderOptions;
|
|
44
|
+
output?: RenderOptions;
|
|
41
45
|
}
|
|
42
46
|
export declare class Papyros {
|
|
47
|
+
config: PapyrosConfig;
|
|
43
48
|
stateManager: PapyrosStateManager;
|
|
44
49
|
codeState: PapyrosCodeState;
|
|
45
|
-
|
|
46
|
-
|
|
50
|
+
inputManager: InputManager;
|
|
51
|
+
outputManager: OutputManager;
|
|
52
|
+
constructor(config: PapyrosConfig);
|
|
53
|
+
get state(): PapyrosState;
|
|
47
54
|
launch(): Promise<Papyros>;
|
|
48
55
|
setProgrammingLanguage(programmingLanguage: ProgrammingLanguage): Promise<void>;
|
|
56
|
+
setCode(code: string): void;
|
|
57
|
+
getCode(): string;
|
|
49
58
|
startBackend(): Promise<void>;
|
|
50
|
-
|
|
59
|
+
configureInput(allowReload: boolean, serviceWorkerRoot?: string, serviceWorkerName?: string): Promise<boolean>;
|
|
51
60
|
onError(e: PapyrosEvent): void;
|
|
52
|
-
sendInput(): Promise<boolean>;
|
|
53
61
|
onInput(e: PapyrosEvent): Promise<void>;
|
|
54
62
|
onMessage(e: PapyrosEvent): void;
|
|
55
63
|
runCode(): Promise<void>;
|
|
56
|
-
|
|
64
|
+
stop(): Promise<void>;
|
|
65
|
+
render(renderOptions: PapyrosRenderOptions): void;
|
|
66
|
+
addButton(options: ButtonOptions, onClick: () => void): void;
|
|
67
|
+
static supportsProgrammingLanguage(language: string): boolean;
|
|
68
|
+
static toProgrammingLanguage(language: string): ProgrammingLanguage | undefined;
|
|
57
69
|
}
|
|
58
70
|
export {};
|
package/dist/PapyrosEvent.d.ts
CHANGED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { ButtonOptions, RenderOptions } from "./util/Util";
|
|
2
|
+
interface DynamicButton {
|
|
3
|
+
id: string;
|
|
4
|
+
buttonHTML: string;
|
|
5
|
+
onClick: () => void;
|
|
6
|
+
}
|
|
7
|
+
export declare class StatusPanel {
|
|
8
|
+
buttons: Array<DynamicButton>;
|
|
9
|
+
constructor();
|
|
10
|
+
addButton(options: ButtonOptions, onClick: () => void): void;
|
|
11
|
+
get statusSpinner(): HTMLElement;
|
|
12
|
+
get statusText(): HTMLElement;
|
|
13
|
+
showSpinner(show: boolean): void;
|
|
14
|
+
setStatus(status: string): void;
|
|
15
|
+
render(options: RenderOptions): HTMLElement;
|
|
16
|
+
}
|
|
17
|
+
export {};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { ProgrammingLanguage } from "../ProgrammingLanguage";
|
|
2
|
+
export declare function getExamples(language: ProgrammingLanguage): {
|
|
3
|
+
[key: string]: string;
|
|
4
|
+
};
|
|
5
|
+
export declare function getExampleNames(language: ProgrammingLanguage): Array<string>;
|
|
6
|
+
export declare function getCodeForExample(language: ProgrammingLanguage, name: string): string;
|