@dodona/papyros 0.3.4 → 0.3.7-scoped
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 +43 -27
- package/dist/Backend.d.ts +33 -1
- package/dist/BackendEvent.d.ts +2 -1
- package/dist/BackendEventQueue.d.ts +11 -2
- package/dist/BackendManager.d.ts +5 -0
- package/dist/CodeEditor.d.ts +6 -2
- package/dist/CodeRunner.d.ts +38 -3
- package/dist/Constants.d.ts +6 -0
- package/dist/InputManager.d.ts +1 -2
- package/dist/Library.d.ts +8 -5
- package/dist/Library.js +1 -1
- package/dist/OutputManager.d.ts +16 -3
- package/dist/Papyros.d.ts +2 -7
- package/dist/input/BatchInputHandler.d.ts +1 -1
- package/dist/input/InteractiveInputHandler.d.ts +2 -2
- package/dist/input/UserInputHandler.d.ts +7 -1
- package/dist/util/HTMLShapes.d.ts +2 -2
- package/dist/util/Rendering.d.ts +2 -2
- package/package.json +5 -9
package/README.md
CHANGED
|
@@ -23,9 +23,14 @@ Currently, Papyros provides support for the following programming languages:
|
|
|
23
23
|
|
|
24
24
|
## Using Papyros in your own project
|
|
25
25
|
|
|
26
|
-
You can
|
|
26
|
+
You can add Papyros to your project as follows:
|
|
27
|
+
- npm:
|
|
27
28
|
```shell
|
|
28
|
-
npm install
|
|
29
|
+
npm install @dodona/papyros
|
|
30
|
+
```
|
|
31
|
+
- yarn:
|
|
32
|
+
```shell
|
|
33
|
+
yarn add @dodona/papyros
|
|
29
34
|
```
|
|
30
35
|
|
|
31
36
|
Papyros currently supports two modes of operation: stand-alone and embedded.
|
|
@@ -38,50 +43,61 @@ as the user knows for what purpose Papyros is being used. For example, when used
|
|
|
38
43
|
scope of a Python exercise in Dodona, there is no need to support other programming languages.
|
|
39
44
|
The locale should also match that of the actual application.
|
|
40
45
|
|
|
41
|
-
|
|
42
|
-
|
|
46
|
+
Using Papyros in your project is done by following a few steps. First, you create a new
|
|
47
|
+
Papyros instance with a `PapyrosConfig` object.
|
|
43
48
|
The following options are supported:
|
|
44
49
|
|
|
45
50
|
- `standAlone`: Whether to operate in stand-alone or embedded mode as described above.
|
|
51
|
+
- `programmingLanguage`: The [programming language](/src/ProgrammingLanguage.ts) to use in the CodeEditor and Backend.
|
|
46
52
|
- `locale`: The locale to use, currently English and Dutch translations are provided.
|
|
47
|
-
- `programmingLanguage`: The language to use in the CodeEditor and Backend
|
|
48
53
|
- `inputMode`: How the users can provide input, according to the [InputMode enum](/src/InputManager.ts)
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
- `
|
|
56
|
-
- `
|
|
57
|
-
- `
|
|
58
|
-
- `
|
|
54
|
+
- `example`: Optional name of the selected example, only appliccable in standAlone-mode
|
|
55
|
+
- `channelOptions`: Optional options to provide to the [sync-message](https://github.com/alexmojaki/sync-message) channel. Extra is the serviceWorkerName, which is the relative pathname to the service worker script
|
|
56
|
+
|
|
57
|
+
Furthermore, you can provide fine-grained configuration by providing `RenderOptions` to each main component in the application when rendering Papyros. You minimally need to specify the ID of the parent element.
|
|
58
|
+
You can also specify attributes, such as `style`, `data`-attributes or `classNames` to be used.
|
|
59
|
+
The components you can style like this are the following:
|
|
60
|
+
- `standAloneOptions`: for the global application in standAlone mode
|
|
61
|
+
- `codeEditorOptions`: for the CodeEditor.
|
|
62
|
+
- `statusPanelOptions`: for the StatusPanel in the CodeEditor
|
|
63
|
+
- `inputOptions`: for the field that handles the user input
|
|
64
|
+
- `outputOptions`: for the panel that displays the output of the code
|
|
59
65
|
|
|
60
66
|
### User input
|
|
61
67
|
|
|
62
68
|
Important to note is that handling asynchronous input in a synchronous way is not straightforward.
|
|
63
|
-
This requires advanced features which are not available by default in your browser. We support two options
|
|
69
|
+
This requires advanced features which are not available by default in your browser. We support two options based on [sync-message](https://github.com/alexmojaki/sync-message).
|
|
64
70
|
|
|
65
71
|
The most efficient and practical way is using SharedArrayBuffers, which requires the presence of certain HTTP headers.
|
|
66
72
|
The following headers must be set on resources using Papyros.
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
|
|
73
|
+
```yaml
|
|
74
|
+
{
|
|
75
|
+
"Cross-Origin-Opener-Policy": "same-origin",
|
|
76
|
+
"Cross-Origin-Embedder-Policy": "require-corp"
|
|
77
|
+
}
|
|
70
78
|
```
|
|
71
|
-
If you are also embedding other components (such as iframes) in those pages, you will also need to set
|
|
72
|
-
'Cross-Origin-Resource-Policy' to 'cross-origin' to make them work correctly. In order to limit the effect of this
|
|
73
|
-
change, it is advised to restrict access using the 'Access-Control-Allow-Origin'-header to prevent abuse of including code.
|
|
79
|
+
If you are also embedding other components (such as iframes, videos or images) in those pages, you will also need to set the `Cross-Origin-Resource-Policy`-header to `cross-origin` to make them work correctly. If these elements come from external URLs, it will likely not be possible to keep using them. An alternative is described below.
|
|
74
80
|
|
|
75
81
|
If you would like to use this project without enabling these HTTP headers, we provide a solution using a service worker.
|
|
76
|
-
If your application does not use a service worker yet,
|
|
77
|
-
|
|
78
|
-
|
|
82
|
+
If your application does not use a service worker yet, you can create one based on the [service worker used in stand-alone mode](src/InputServiceWorker.ts)).
|
|
83
|
+
If you already use a service worker, simply include our [InputWorker](src/workers/input/InputWorker.ts) in your existing service worker using imports (you can import it separately from /dist/workers/input/InputWorker). An example of how to use it can be found in our described service worker. Afterwards, inform Papyros of the location using the channelOptions described earlier.
|
|
84
|
+
|
|
85
|
+
### Code editor
|
|
86
|
+
|
|
87
|
+
The editor used in Papyros is powered by [CodeMirror 6](https://codemirror.net/6/). It is accessible in code via an instance of Papyros and by default allows configuring many options:
|
|
88
|
+
- the [programming language](/src/ProgrammingLanguage.ts) of the contents (for e.g. syntax higlighting)
|
|
89
|
+
- the displayed placeholder
|
|
90
|
+
- the indentation unit
|
|
91
|
+
- the shown panel
|
|
92
|
+
- the autocompletion source
|
|
93
|
+
- the linting source
|
|
94
|
+
- the theme used to style the editor
|
|
79
95
|
|
|
80
|
-
If you
|
|
96
|
+
If you need more specific functionality, this can be added in your own code by accessing the internal CodeMirror editorView.
|
|
81
97
|
|
|
82
98
|
## Documentation
|
|
83
99
|
|
|
84
|
-
Visit our
|
|
100
|
+
Visit our documentation page at <https://docs.dodona.be/papyros/>.
|
|
85
101
|
|
|
86
102
|
## Building and developing
|
|
87
103
|
|
package/dist/Backend.d.ts
CHANGED
|
@@ -36,14 +36,45 @@ export interface WorkerAutocompleteContext {
|
|
|
36
36
|
} | null;
|
|
37
37
|
}
|
|
38
38
|
export interface WorkerDiagnostic {
|
|
39
|
+
/**
|
|
40
|
+
* 1-based index of the starting line containing the issue
|
|
41
|
+
*/
|
|
39
42
|
lineNr: number;
|
|
43
|
+
/**
|
|
44
|
+
* 0-based index of the column in the starting line
|
|
45
|
+
*/
|
|
40
46
|
columnNr: number;
|
|
47
|
+
/**
|
|
48
|
+
* 1-based index of the ending line containing the issue
|
|
49
|
+
* Can be the same as lineNr
|
|
50
|
+
*/
|
|
51
|
+
endLineNr: number;
|
|
52
|
+
/**
|
|
53
|
+
* 0-based index of the column in the ending line
|
|
54
|
+
*/
|
|
55
|
+
endColumnNr: number;
|
|
56
|
+
/**
|
|
57
|
+
* Severity of the issue
|
|
58
|
+
*/
|
|
41
59
|
severity: "info" | "warning" | "error";
|
|
60
|
+
/**
|
|
61
|
+
* Message describing the issue
|
|
62
|
+
*/
|
|
42
63
|
message: string;
|
|
43
64
|
}
|
|
44
65
|
export declare abstract class Backend<Extras extends SyncExtras = SyncExtras> {
|
|
66
|
+
/**
|
|
67
|
+
* SyncExtras object that grants access to helpful methods
|
|
68
|
+
* for synchronous operations
|
|
69
|
+
*/
|
|
45
70
|
protected extras: Extras;
|
|
71
|
+
/**
|
|
72
|
+
* Callback to handle events published by this Backend
|
|
73
|
+
*/
|
|
46
74
|
protected onEvent: (e: BackendEvent) => any;
|
|
75
|
+
/**
|
|
76
|
+
* Queue to handle published events without overloading the thread
|
|
77
|
+
*/
|
|
47
78
|
protected queue: BackendEventQueue;
|
|
48
79
|
/**
|
|
49
80
|
* Constructor is limited as it is meant to be used as a WebWorker
|
|
@@ -58,9 +89,10 @@ export declare abstract class Backend<Extras extends SyncExtras = SyncExtras> {
|
|
|
58
89
|
/**
|
|
59
90
|
* Initialize the backend by doing all setup-related work
|
|
60
91
|
* @param {function(BackendEvent):void} onEvent Callback for when events occur
|
|
92
|
+
* @param {function():void} onOverflow Callback for when overflow occurs
|
|
61
93
|
* @return {Promise<void>} Promise of launching
|
|
62
94
|
*/
|
|
63
|
-
launch(onEvent: (e: BackendEvent) => void): Promise<void>;
|
|
95
|
+
launch(onEvent: (e: BackendEvent) => void, onOverflow: () => void): Promise<void>;
|
|
64
96
|
/**
|
|
65
97
|
* Executes the given code
|
|
66
98
|
* @param {Extras} extras Helper properties to run code
|
package/dist/BackendEvent.d.ts
CHANGED
|
@@ -25,6 +25,14 @@ export declare class BackendEventQueue {
|
|
|
25
25
|
* Queue storing Output-events after overflowing
|
|
26
26
|
*/
|
|
27
27
|
private overflow;
|
|
28
|
+
/**
|
|
29
|
+
* Callback for when overflow occurs
|
|
30
|
+
*/
|
|
31
|
+
private onOverflow;
|
|
32
|
+
/**
|
|
33
|
+
* Keep track whether the queue reached its limit this run
|
|
34
|
+
*/
|
|
35
|
+
private overflown;
|
|
28
36
|
/**
|
|
29
37
|
* Time in milliseconds when the last flush occurred
|
|
30
38
|
*/
|
|
@@ -38,11 +46,12 @@ export declare class BackendEventQueue {
|
|
|
38
46
|
*/
|
|
39
47
|
private decoder;
|
|
40
48
|
/**
|
|
41
|
-
* @param {
|
|
49
|
+
* @param {function(BackendEvent):void} callback Function to process events in the queue
|
|
50
|
+
* @param {function():void} onOverflow Callback for when overflow occurs
|
|
42
51
|
* @param {number} limit The maximal amount of output lines to send before overflowing
|
|
43
52
|
* @param {number} flushTime The time in milliseconds before sending events through
|
|
44
53
|
*/
|
|
45
|
-
constructor(callback: (e: BackendEvent) => void, limit?: number, flushTime?: number);
|
|
54
|
+
constructor(callback: (e: BackendEvent) => void, onOverflow: () => void, limit?: number, flushTime?: number);
|
|
46
55
|
/**
|
|
47
56
|
* Add an element to the queue
|
|
48
57
|
* @param {BackendEventType} type The type of the event
|
package/dist/BackendManager.d.ts
CHANGED
|
@@ -26,6 +26,10 @@ export declare abstract class BackendManager {
|
|
|
26
26
|
* Uses an Array to maintain order of subscription
|
|
27
27
|
*/
|
|
28
28
|
private static subscriberMap;
|
|
29
|
+
/**
|
|
30
|
+
* Whether the BackendManager is publishing events
|
|
31
|
+
*/
|
|
32
|
+
private static halted;
|
|
29
33
|
/**
|
|
30
34
|
* The channel used to communicate with the SyncClients
|
|
31
35
|
*/
|
|
@@ -59,5 +63,6 @@ export declare abstract class BackendManager {
|
|
|
59
63
|
* @param {BackendEventType} e The event to publish
|
|
60
64
|
*/
|
|
61
65
|
static publish(e: BackendEvent): void;
|
|
66
|
+
private static halt;
|
|
62
67
|
}
|
|
63
68
|
export {};
|
package/dist/CodeEditor.d.ts
CHANGED
|
@@ -17,10 +17,11 @@ export declare class CodeEditor extends Renderable {
|
|
|
17
17
|
private compartments;
|
|
18
18
|
/**
|
|
19
19
|
* Construct a new CodeEditor
|
|
20
|
+
* @param {Function} onRunRequest Callback for when the user wants to run the code
|
|
20
21
|
* @param {string} initialCode The initial code to display
|
|
21
22
|
* @param {number} indentLength The length in spaces for the indent unit
|
|
22
23
|
*/
|
|
23
|
-
constructor(initialCode?: string, indentLength?: number);
|
|
24
|
+
constructor(onRunRequest: () => void, initialCode?: string, indentLength?: number);
|
|
24
25
|
/**
|
|
25
26
|
* Helper method to dispatch configuration changes at runtime
|
|
26
27
|
* @param {Array<[Option, Extension]>} items Array of items to reconfigure
|
|
@@ -51,6 +52,10 @@ export declare class CodeEditor extends Renderable {
|
|
|
51
52
|
* @param {number} indentLength The number of spaces to use for indentation
|
|
52
53
|
*/
|
|
53
54
|
setIndentLength(indentLength: number): void;
|
|
55
|
+
/**
|
|
56
|
+
* @param {Function} onChange Listener that performs actions on the new contents
|
|
57
|
+
*/
|
|
58
|
+
onChange(onChange: ((newContent: string) => void)): void;
|
|
54
59
|
/**
|
|
55
60
|
* @param {HTMLElement} panel The panel to display at the bottom of the editor
|
|
56
61
|
*/
|
|
@@ -82,7 +87,6 @@ export declare class CodeEditor extends Renderable {
|
|
|
82
87
|
* - special character highlighting
|
|
83
88
|
* - the undo history
|
|
84
89
|
* - a fold gutter
|
|
85
|
-
* - gutter for linting
|
|
86
90
|
* - custom selection drawing
|
|
87
91
|
* - multiple selections
|
|
88
92
|
* - reindentation on input
|
package/dist/CodeRunner.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { CodeEditor } from "./CodeEditor";
|
|
|
2
2
|
import { InputManager } from "./InputManager";
|
|
3
3
|
import { ProgrammingLanguage } from "./ProgrammingLanguage";
|
|
4
4
|
import { RenderOptions, ButtonOptions, Renderable } from "./util/Rendering";
|
|
5
|
+
import { OutputManager } from "./OutputManager";
|
|
5
6
|
interface CodeRunnerRenderOptions {
|
|
6
7
|
/**
|
|
7
8
|
* Options for rendering the panel
|
|
@@ -15,6 +16,10 @@ interface CodeRunnerRenderOptions {
|
|
|
15
16
|
* Options for rendering the editor
|
|
16
17
|
*/
|
|
17
18
|
codeEditorOptions: RenderOptions;
|
|
19
|
+
/**
|
|
20
|
+
* RenderOptions for the output field
|
|
21
|
+
*/
|
|
22
|
+
outputOptions: RenderOptions;
|
|
18
23
|
}
|
|
19
24
|
/**
|
|
20
25
|
* Enum representing the possible states while processing code
|
|
@@ -26,6 +31,19 @@ export declare enum RunState {
|
|
|
26
31
|
Stopping = "stopping",
|
|
27
32
|
Ready = "ready"
|
|
28
33
|
}
|
|
34
|
+
/**
|
|
35
|
+
* Interface to represent information required when handling loading events
|
|
36
|
+
*/
|
|
37
|
+
export interface LoadingData {
|
|
38
|
+
/**
|
|
39
|
+
* List of module names that are being loaded
|
|
40
|
+
*/
|
|
41
|
+
modules: Array<string>;
|
|
42
|
+
/**
|
|
43
|
+
* Whether the modules are being loaded or have been loaded
|
|
44
|
+
*/
|
|
45
|
+
loading: boolean;
|
|
46
|
+
}
|
|
29
47
|
/**
|
|
30
48
|
* Helper component to manage and visualize the current RunState
|
|
31
49
|
*/
|
|
@@ -42,6 +60,10 @@ export declare class CodeRunner extends Renderable<CodeRunnerRenderOptions> {
|
|
|
42
60
|
* Component to request and handle input from the user
|
|
43
61
|
*/
|
|
44
62
|
readonly inputManager: InputManager;
|
|
63
|
+
/**
|
|
64
|
+
* Component to handle output generated by the user's code
|
|
65
|
+
*/
|
|
66
|
+
readonly outputManager: OutputManager;
|
|
45
67
|
/**
|
|
46
68
|
* The backend that executes the code asynchronously
|
|
47
69
|
*/
|
|
@@ -54,6 +76,14 @@ export declare class CodeRunner extends Renderable<CodeRunnerRenderOptions> {
|
|
|
54
76
|
* Buttons managed by this component
|
|
55
77
|
*/
|
|
56
78
|
private buttons;
|
|
79
|
+
/**
|
|
80
|
+
* Array of packages that are being installed
|
|
81
|
+
*/
|
|
82
|
+
private loadingPackages;
|
|
83
|
+
/**
|
|
84
|
+
* Previous state to restore when loading is done
|
|
85
|
+
*/
|
|
86
|
+
private previousState;
|
|
57
87
|
/**
|
|
58
88
|
* Construct a new RunStateManager with the given listeners
|
|
59
89
|
* @param {ProgrammingLanguage} programmingLanguage The language to use
|
|
@@ -86,7 +116,7 @@ export declare class CodeRunner extends Renderable<CodeRunnerRenderOptions> {
|
|
|
86
116
|
* Show or hide the spinning circle, representing a running animation
|
|
87
117
|
* @param {boolean} show Whether to show the spinner
|
|
88
118
|
*/
|
|
89
|
-
showSpinner
|
|
119
|
+
private showSpinner;
|
|
90
120
|
/**
|
|
91
121
|
* Show the current state of the program to the user
|
|
92
122
|
* @param {RunState} state The current state of the run
|
|
@@ -102,9 +132,14 @@ export declare class CodeRunner extends Renderable<CodeRunnerRenderOptions> {
|
|
|
102
132
|
addButton(options: ButtonOptions, onClick: () => void): void;
|
|
103
133
|
protected _render(options: CodeRunnerRenderOptions): HTMLElement;
|
|
104
134
|
/**
|
|
105
|
-
*
|
|
135
|
+
* @param {string} code The code to run
|
|
106
136
|
* @return {Promise<void>} Promise of running the code
|
|
107
137
|
*/
|
|
108
|
-
runCode(): Promise<void>;
|
|
138
|
+
runCode(code: string): Promise<void>;
|
|
139
|
+
/**
|
|
140
|
+
* Callback to handle loading events
|
|
141
|
+
* @param {BackendEvent} e The loading event
|
|
142
|
+
*/
|
|
143
|
+
private onLoad;
|
|
109
144
|
}
|
|
110
145
|
export {};
|
package/dist/Constants.d.ts
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
import { ProgrammingLanguage } from "./ProgrammingLanguage";
|
|
2
|
+
/**
|
|
3
|
+
* Add a prefix to a string, ensuring uniqueness in the page
|
|
4
|
+
* @param {string} s The value to add a prefix to
|
|
5
|
+
* @return {string} The value with an almost certainly unused prefix
|
|
6
|
+
*/
|
|
7
|
+
export declare function addPapyrosPrefix(s: string): string;
|
|
2
8
|
export declare const MAIN_APP_ID: string;
|
|
3
9
|
export declare const OUTPUT_AREA_WRAPPER_ID: string;
|
|
4
10
|
export declare const OUTPUT_AREA_ID: string;
|
package/dist/InputManager.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { UserInputHandler } from "./input/UserInputHandler";
|
|
2
1
|
import { Renderable, RenderOptions } from "./util/Rendering";
|
|
3
2
|
export declare enum InputMode {
|
|
4
3
|
Interactive = "interactive",
|
|
@@ -15,7 +14,7 @@ export declare class InputManager extends Renderable {
|
|
|
15
14
|
private buildInputHandlerMap;
|
|
16
15
|
getInputMode(): InputMode;
|
|
17
16
|
setInputMode(inputMode: InputMode): void;
|
|
18
|
-
get inputHandler()
|
|
17
|
+
private get inputHandler();
|
|
19
18
|
isWaiting(): boolean;
|
|
20
19
|
protected _render(options: RenderOptions): void;
|
|
21
20
|
private waitWithPrompt;
|
package/dist/Library.d.ts
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import { BackendEvent } from "./BackendEvent";
|
|
2
2
|
import { CodeEditor } from "./CodeEditor";
|
|
3
3
|
import { InputManager, InputMode } from "./InputManager";
|
|
4
|
-
import { OutputManager } from "./OutputManager";
|
|
5
|
-
import { Papyros } from "./Papyros";
|
|
4
|
+
import { FriendlyError, OutputManager } from "./OutputManager";
|
|
5
|
+
import { Papyros, PapyrosConfig, PapyrosRenderOptions } from "./Papyros";
|
|
6
6
|
import { CodeRunner, RunState } from "./CodeRunner";
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
import { BackendManager } from "./BackendManager";
|
|
8
|
+
import { ProgrammingLanguage } from "./ProgrammingLanguage";
|
|
9
|
+
import { WorkerAutocompleteContext, WorkerDiagnostic } from "./Backend";
|
|
10
|
+
import { ButtonOptions, RenderOptions } from "./util/Rendering";
|
|
11
|
+
export type { BackendEvent, FriendlyError, WorkerAutocompleteContext, WorkerDiagnostic, PapyrosConfig, PapyrosRenderOptions, RenderOptions, ButtonOptions };
|
|
12
|
+
export { Papyros, ProgrammingLanguage, BackendManager, CodeEditor, CodeRunner, RunState, InputManager, InputMode, OutputManager };
|