@dodona/papyros 0.1.90 → 0.1.93

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.
Files changed (44) hide show
  1. package/dist/Backend.d.ts +64 -19
  2. package/dist/BackendEvent.d.ts +33 -0
  3. package/dist/BackendManager.d.ts +51 -8
  4. package/dist/CodeEditor.d.ts +12 -4
  5. package/dist/CodeRunner.d.ts +102 -0
  6. package/dist/InputManager.d.ts +13 -21
  7. package/dist/Library.d.ts +4 -5
  8. package/dist/Library.js +1 -1
  9. package/dist/OutputManager.d.ts +7 -9
  10. package/dist/Papyros.d.ts +7 -84
  11. package/dist/examples/PythonExamples.d.ts +1 -0
  12. package/dist/input/BatchInputHandler.d.ts +3 -4
  13. package/dist/input/InteractiveInputHandler.d.ts +3 -11
  14. package/dist/input/UserInputHandler.d.ts +5 -14
  15. package/dist/util/Util.d.ts +3 -3
  16. package/dist/workers/input/InputWorker.js +1 -1
  17. package/package.json +12 -7
  18. package/dist/App.js +0 -1
  19. package/dist/Backend.js +0 -1
  20. package/dist/BackendManager.js +0 -1
  21. package/dist/CodeEditor.js +0 -1
  22. package/dist/Constants.js +0 -1
  23. package/dist/InputManager.js +0 -1
  24. package/dist/InputServiceWorker.js +0 -1
  25. package/dist/OutputManager.js +0 -1
  26. package/dist/Papyros.js +0 -1
  27. package/dist/PapyrosEvent.d.ts +0 -22
  28. package/dist/PapyrosEvent.js +0 -1
  29. package/dist/ProgrammingLanguage.js +0 -1
  30. package/dist/RunListener.js +0 -1
  31. package/dist/RunStateManager.d.ts +0 -67
  32. package/dist/RunStateManager.js +0 -1
  33. package/dist/Translations.js +0 -1
  34. package/dist/examples/Examples.js +0 -1
  35. package/dist/examples/JavaScriptExamples.js +0 -1
  36. package/dist/examples/PythonExamples.js +0 -1
  37. package/dist/input/BatchInputHandler.js +0 -1
  38. package/dist/input/InteractiveInputHandler.js +0 -1
  39. package/dist/input/UserInputHandler.js +0 -1
  40. package/dist/util/HTMLShapes.js +0 -1
  41. package/dist/util/Logging.js +0 -1
  42. package/dist/util/Util.js +0 -1
  43. package/dist/workers/python/Pyodide.d.ts +0 -28
  44. package/dist/workers/python/Pyodide.js +0 -1
package/dist/Backend.d.ts CHANGED
@@ -1,32 +1,77 @@
1
- import { PapyrosEvent } from "./PapyrosEvent";
2
- import { Channel } from "sync-message";
3
- export declare abstract class Backend {
4
- protected onEvent: (e: PapyrosEvent) => any;
5
- protected runId: number;
1
+ import { CompletionContext, CompletionResult } from "@codemirror/autocomplete";
2
+ import { BackendEvent } from "./BackendEvent";
3
+ import { SyncExtras } from "comsync";
4
+ /**
5
+ * Interface to represent the CodeMirror CompletionContext in a worker
6
+ */
7
+ export interface WorkerAutocompleteContext {
6
8
  /**
7
- * Constructor is limited as it is meant to be used as a WebWorker
8
- * These are then exposed via Comlink. Proper initialization occurs
9
- * in the launch method when the worker is started
9
+ * Whether the autocompletion was explicitly requested (using keybindings)
10
+ */
11
+ explicit: boolean;
12
+ /**
13
+ * The absolute position in the CodeMirror document
14
+ */
15
+ pos: number;
16
+ /**
17
+ * The line number of the cursor while completing (1-based)
18
+ */
19
+ line: number;
20
+ /**
21
+ * The column number of the cursor while completing (1-based)
22
+ */
23
+ column: number;
24
+ /**
25
+ * The full text to autocomplete for
26
+ */
27
+ text: string;
28
+ /**
29
+ * The match before the cursor (determined by a regex)
30
+ */
31
+ before: {
32
+ from: number;
33
+ to: number;
34
+ text: string;
35
+ } | null;
36
+ }
37
+ export declare abstract class Backend<Extras extends SyncExtras = SyncExtras> {
38
+ protected extras: Extras;
39
+ protected onEvent: (e: BackendEvent) => any;
40
+ /**
41
+ * Constructor is limited as it is meant to be used as a WebWorker
42
+ * Proper initialization occurs in the launch method when the worker is started
43
+ * Synchronously exposing methods should be done here
10
44
  */
11
45
  constructor();
12
46
  /**
13
- * Initialize the backend by doing all setup-related work
14
- * @param {function(PapyrosEvent):void} onEvent Callback for when events occur
15
- * @param {Channel} channel for communication with the main thread
16
- * @return {Promise<void>} Promise of launching
47
+ * @return {any} The function to expose methods for Comsync to allow interrupting
17
48
  */
18
- launch(onEvent: (e: PapyrosEvent) => void, channel: Channel): Promise<void>;
49
+ protected syncExpose(): any;
19
50
  /**
20
- * Internal helper method that actually executes the code
21
- * Results or Errors must be passed by using the onEvent-callback
22
- * @param code The code to run
51
+ * Initialize the backend by doing all setup-related work
52
+ * @param {function(BackendEvent):void} onEvent Callback for when events occur
53
+ * @return {Promise<void>} Promise of launching
23
54
  */
24
- protected abstract _runCodeInternal(code: string): Promise<any>;
55
+ launch(onEvent: (e: BackendEvent) => void): Promise<void>;
25
56
  /**
26
57
  * Executes the given code
58
+ * @param {Extras} extras Helper properties to run code
27
59
  * @param {string} code The code to run
28
- * @param {string} runId The uuid for this execution
29
60
  * @return {Promise<void>} Promise of execution
30
61
  */
31
- runCode(code: string, runId: number): Promise<any>;
62
+ abstract runCode(extras: Extras, code: string): Promise<void>;
63
+ /**
64
+ * Converts the context to a cloneable object containing useful properties
65
+ * to generate autocompletion suggestions with
66
+ * Class instances are not passable to workers, so we extract the useful information
67
+ * @param {CompletionContext} context Current context to autocomplete for
68
+ * @param {RegExp} expr Expression to match the previous token with
69
+ * @return {WorkerAutocompleteContext} Completion context that can be passed as a message
70
+ */
71
+ static convertCompletionContext(context: CompletionContext, expr?: RegExp): WorkerAutocompleteContext;
72
+ /**
73
+ * Generate autocompletion suggestions for the given context
74
+ * @param {WorkerAutocompleteContext} context Context to autcomplete in
75
+ */
76
+ abstract autocomplete(context: WorkerAutocompleteContext): Promise<CompletionResult | null>;
32
77
  }
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Enum representing all possible types for supported events
3
+ */
4
+ export declare enum BackendEventType {
5
+ Start = "start",
6
+ End = "end",
7
+ Input = "input",
8
+ Output = "output",
9
+ Sleep = "sleep",
10
+ Error = "error",
11
+ Interrupt = "interrupt"
12
+ }
13
+ /**
14
+ * All possible types for ease of iteration
15
+ */
16
+ export declare const BACKEND_EVENT_TYPES: BackendEventType[];
17
+ /**
18
+ * Interface for events used for communication between threads
19
+ */
20
+ export interface BackendEvent {
21
+ /**
22
+ * The type of action generating this event
23
+ */
24
+ type: BackendEventType;
25
+ /**
26
+ * The actual data stored in this event
27
+ */
28
+ data: any;
29
+ /**
30
+ * The format used for the data to help with parsing
31
+ */
32
+ contentType?: string;
33
+ }
@@ -1,14 +1,57 @@
1
- import { Remote } from "comlink";
2
1
  import { Backend } from "./Backend";
3
2
  import { ProgrammingLanguage } from "./ProgrammingLanguage";
3
+ import { BackendEvent, BackendEventType } from "./BackendEvent";
4
+ import { Channel } from "sync-message";
5
+ import { SyncClient } from "comsync";
4
6
  /**
5
- * Start a backend for the given language, while storing the worker
6
- * @param {ProgrammingLanguage} language The programming language supported by the backend
7
- * @return {Remote<Backend>} A Comlink proxy for the Backend
7
+ * Callback type definition for subscribers
8
+ * @param {BackendEvent} e The published event
8
9
  */
9
- export declare function startBackend(language: ProgrammingLanguage): Remote<Backend>;
10
+ declare type BackendEventListener = (e: BackendEvent) => void;
10
11
  /**
11
- * Stop a backend by terminating the worker and releasing memory
12
- * @param {Remote<Backend>} backend The proxy for the backend to stop
12
+ * Abstract class to implement the singleton pattern
13
+ * Static methods group functionality
13
14
  */
14
- export declare function stopBackend(backend: Remote<Backend>): void;
15
+ export declare abstract class BackendManager {
16
+ /**
17
+ * Map programming languages to Backend constructors
18
+ */
19
+ private static createBackendMap;
20
+ /**
21
+ * Map to cache Backends per ProgrammingLanguage
22
+ */
23
+ private static backendMap;
24
+ /**
25
+ * Map an event type to interested subscribers
26
+ * Uses an Array to maintain order of subscription
27
+ */
28
+ static subscriberMap: Map<BackendEventType, Array<BackendEventListener>>;
29
+ /**
30
+ * The channel used to communicate with the SyncClients
31
+ */
32
+ static channel: Channel;
33
+ /**
34
+ * @param {ProgrammingLanguage} language The language to support
35
+ * @param {Function} backendCreator The constructor for a SyncClient
36
+ */
37
+ static registerBackend(language: ProgrammingLanguage, backendCreator: () => SyncClient<Backend>): void;
38
+ /**
39
+ * Start a backend for the given language and cache for reuse
40
+ * @param {ProgrammingLanguage} language The programming language supported by the backend
41
+ * @return {SyncClient<Backend>} A SyncClient for the Backend
42
+ */
43
+ static startBackend(language: ProgrammingLanguage): SyncClient<Backend>;
44
+ /**
45
+ * Register a callback for when an event of a certain type is published
46
+ * @param {BackendEventType} type The type of event to subscribe to
47
+ * @param {BackendEventListener} subscriber Callback for when an event
48
+ * of the given type is published
49
+ */
50
+ static subscribe(type: BackendEventType, subscriber: BackendEventListener): void;
51
+ /**
52
+ * Publish an event, notifying all listeners for its type
53
+ * @param {BackendEventType} e The event to publish
54
+ */
55
+ static publish(e: BackendEvent): void;
56
+ }
57
+ export {};
@@ -2,6 +2,7 @@ import { LanguageSupport } from "@codemirror/language";
2
2
  import { Compartment, Extension } from "@codemirror/state";
3
3
  import { ProgrammingLanguage } from "./ProgrammingLanguage";
4
4
  import { EditorView } from "@codemirror/view";
5
+ import { CompletionSource } from "@codemirror/autocomplete";
5
6
  import { RenderOptions } from "./util/Util";
6
7
  /**
7
8
  * Component that provides useful features to users writing code
@@ -27,6 +28,10 @@ export declare class CodeEditor {
27
28
  * Compartment to configure the panel at runtime
28
29
  */
29
30
  panelCompartment: Compartment;
31
+ /**
32
+ * Compartment to configure the autocompletion at runtime
33
+ */
34
+ autocompletionCompartment: Compartment;
30
35
  /**
31
36
  * Construct a new CodeEditor
32
37
  * @param {ProgrammingLanguage} language The used programming language
@@ -34,7 +39,7 @@ export declare class CodeEditor {
34
39
  * @param {string} initialCode The initial code to display
35
40
  * @param {number} indentLength The length in spaces for the indent unit
36
41
  */
37
- constructor(language: ProgrammingLanguage, editorPlaceHolder: string, initialCode?: string, indentLength?: number);
42
+ constructor(initialCode?: string, indentLength?: number);
38
43
  /**
39
44
  * Render the editor with the given options and panel
40
45
  * @param {RenderOptions} options Options for rendering
@@ -43,11 +48,14 @@ export declare class CodeEditor {
43
48
  */
44
49
  render(options: RenderOptions, panel?: HTMLElement): HTMLElement;
45
50
  /**
46
- * Set the language that is currently used, with a corresponding placeholder
51
+ * Set the language that is currently used
47
52
  * @param {ProgrammingLanguage} language The language to use
48
- * @param {string} editorPlaceHolder Placeholder when empty
49
53
  */
50
- setLanguage(language: ProgrammingLanguage, editorPlaceHolder: string): void;
54
+ setLanguage(language: ProgrammingLanguage): void;
55
+ /**
56
+ * @param {CompletionSource} completionSource Function to obtain autocomplete results
57
+ */
58
+ setCompletionSource(completionSource: CompletionSource): void;
51
59
  /**
52
60
  * Set the length in spaces of the indentation unit
53
61
  * @param {number} indentLength The number of spaces to use
@@ -0,0 +1,102 @@
1
+ import { CodeEditor } from "./CodeEditor";
2
+ import { InputManager } from "./InputManager";
3
+ import { ProgrammingLanguage } from "./ProgrammingLanguage";
4
+ import { ButtonOptions, RenderOptions } from "./util/Util";
5
+ /**
6
+ * Enum representing the possible states while processing code
7
+ */
8
+ export declare enum RunState {
9
+ Loading = "loading",
10
+ Running = "running",
11
+ AwaitingInput = "awaiting_input",
12
+ Stopping = "stopping",
13
+ Ready = "ready"
14
+ }
15
+ /**
16
+ * Helper component to manage and visualize the current RunState
17
+ */
18
+ export declare class CodeRunner {
19
+ /**
20
+ * The currently used programming language
21
+ */
22
+ private programmingLanguage;
23
+ /**
24
+ * The editor in which the code is written
25
+ */
26
+ readonly editor: CodeEditor;
27
+ /**
28
+ * Component to request and handle input from the user
29
+ */
30
+ readonly inputManager: InputManager;
31
+ /**
32
+ * The backend that executes the code asynchronously
33
+ */
34
+ private backend;
35
+ /**
36
+ * Current state of the program
37
+ */
38
+ private state;
39
+ /**
40
+ * Buttons managed by this component
41
+ */
42
+ private buttons;
43
+ /**
44
+ * Construct a new RunStateManager with the given listeners
45
+ * @param {ProgrammingLanguage} programmingLanguage The language to use
46
+ */
47
+ constructor(programmingLanguage: ProgrammingLanguage);
48
+ /**
49
+ * Start the backend to enable running code
50
+ */
51
+ start(): Promise<void>;
52
+ /**
53
+ * Interrupt the currently running code
54
+ * @return {Promise<void>} Promise of stopping
55
+ */
56
+ stop(): Promise<void>;
57
+ /**
58
+ * Set the used programming language to the given one to allow editing and running code
59
+ * @param {ProgrammingLanguage} programmingLanguage The language to use
60
+ */
61
+ setProgrammingLanguage(programmingLanguage: ProgrammingLanguage): Promise<void>;
62
+ getProgrammingLanguage(): ProgrammingLanguage;
63
+ /**
64
+ * Get the button to run the code
65
+ */
66
+ get runButton(): HTMLButtonElement;
67
+ /**
68
+ * Get the button to interrupt the code
69
+ */
70
+ get stopButton(): HTMLButtonElement;
71
+ /**
72
+ * Show or hide the spinning circle, representing a running animation
73
+ * @param {boolean} show Whether to show the spinner
74
+ */
75
+ showSpinner(show: boolean): void;
76
+ /**
77
+ * Show the current state of the program to the user
78
+ * @param {RunState} state The current state of the run
79
+ * @param {string} message Optional message to indicate the state
80
+ */
81
+ setState(state: RunState, message?: string): void;
82
+ getState(): RunState;
83
+ /**
84
+ * Add a button to display to the user
85
+ * @param {ButtonOptions} options Options for rendering the button
86
+ * @param {function} onClick Listener for click events on the button
87
+ */
88
+ addButton(options: ButtonOptions, onClick: () => void): void;
89
+ /**
90
+ * Render the RunStateManager with the given options
91
+ * @param {RenderOptions} statusPanelOptions Options for rendering the panel
92
+ * @param {RenderOptions} inputOptions Options for rendering the InputManager
93
+ * @param {RenderOptions} codeEditorOptions Options for rendering the editor
94
+ * @return {HTMLElement} The rendered RunStateManager
95
+ */
96
+ render(statusPanelOptions: RenderOptions, inputOptions: RenderOptions, codeEditorOptions: RenderOptions): HTMLElement;
97
+ /**
98
+ * Run the code that is currently present in the editor
99
+ * @return {Promise<void>} Promise of running the code
100
+ */
101
+ runCode(): Promise<void>;
102
+ }
@@ -1,40 +1,32 @@
1
- import { PapyrosEvent } from "./PapyrosEvent";
1
+ import { BackendEvent } from "./BackendEvent";
2
2
  import { RenderOptions } from "./util/Util";
3
- import { Channel } from "sync-message";
4
3
  import { UserInputHandler } from "./input/UserInputHandler";
5
- import { RunListener } from "./RunListener";
6
4
  export declare enum InputMode {
7
5
  Interactive = "interactive",
8
6
  Batch = "batch"
9
7
  }
10
8
  export declare const INPUT_MODES: InputMode[];
11
- export interface InputData {
12
- prompt: string;
13
- messageId: string;
14
- }
15
- export declare class InputManager implements RunListener {
16
- private _inputMode;
9
+ export declare class InputManager {
10
+ private inputMode;
17
11
  private inputHandlers;
18
12
  private renderOptions;
19
- _waiting: boolean;
20
- prompt: string;
21
- onSend: () => void;
22
- channel: Channel;
23
- messageId: string;
24
- constructor(onSend: () => void, inputMode: InputMode);
13
+ private waiting;
14
+ private prompt;
15
+ private sendInput;
16
+ constructor(sendInput: (input: string) => void);
25
17
  private buildInputHandlerMap;
26
- get inputMode(): InputMode;
27
- set inputMode(inputMode: InputMode);
18
+ getInputMode(): InputMode;
19
+ setInputMode(inputMode: InputMode): void;
28
20
  get inputHandler(): UserInputHandler;
29
21
  render(options: RenderOptions): void;
30
- set waiting(waiting: boolean);
31
- sendLine(): Promise<void>;
22
+ waitWithPrompt(waiting: boolean, prompt?: string): void;
23
+ onUserInput(): Promise<void>;
32
24
  /**
33
25
  * Asynchronously handle an input request by prompting the user for input
34
- * @param {PapyrosEvent} e Event containing the input data
26
+ * @param {BackendEvent} e Event containing the input data
35
27
  * @return {Promise<void>} Promise of handling the request
36
28
  */
37
- onInput(e: PapyrosEvent): Promise<void>;
29
+ onInputRequest(e: BackendEvent): Promise<void>;
38
30
  onRunStart(): void;
39
31
  onRunEnd(): void;
40
32
  }
package/dist/Library.d.ts CHANGED
@@ -1,10 +1,9 @@
1
+ import { BackendEvent } from "./BackendEvent";
1
2
  import { CodeEditor } from "./CodeEditor";
2
3
  import { InputManager, InputMode } from "./InputManager";
3
4
  import { OutputManager } from "./OutputManager";
4
5
  import { Papyros } from "./Papyros";
5
- import { PapyrosEvent } from "./PapyrosEvent";
6
- import { RunStateManager, RunState } from "./RunStateManager";
7
- import { InputWorker } from "./workers/input/InputWorker";
6
+ import { CodeRunner, RunState } from "./CodeRunner";
8
7
  export * from "./ProgrammingLanguage";
9
- export type { PapyrosEvent };
10
- export { Papyros, CodeEditor, RunState, RunStateManager, InputManager, InputMode, OutputManager, InputWorker };
8
+ export type { BackendEvent };
9
+ export { Papyros, CodeEditor, RunState, CodeRunner, InputManager, InputMode, OutputManager, };