@dodona/papyros 0.1.0-rc
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/LICENSE +21 -0
- package/README.md +81 -0
- package/lib/114.index.js +1 -0
- package/lib/572.index.js +1 -0
- package/lib/806.index.js +1 -0
- package/lib/index.d.ts +189 -0
- package/lib/index.js +1 -0
- package/package.json +83 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2021 Dodona
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# Papyros
|
|
2
|
+
|
|
3
|
+
<p align="center">
|
|
4
|
+
<a href="https://www.npmjs.com/package/@dodona/papyros">
|
|
5
|
+
<img src="https://img.shields.io/npm/v/@dodona/papyros.svg" alt="Version of the npm package">
|
|
6
|
+
</a>
|
|
7
|
+
<a href="https://github.com/dodona-edu/papyros/actions?query=branch%3Amain">
|
|
8
|
+
<img src="https://github.com/dodona-edu/papyros/actions/workflows/deploy-pages.yaml/badge.svg" alt="GitHub checks status">
|
|
9
|
+
</a>
|
|
10
|
+
<a href="https://github.com/dodona-edu/papyros/blob/main/LICENSE">
|
|
11
|
+
<img alt="Source code license" src="https://img.shields.io/github/license/dodona-edu/papyros">
|
|
12
|
+
</a>
|
|
13
|
+
</p>
|
|
14
|
+
|
|
15
|
+
Papyros is a programming scratchpad in the browser. It allows running arbitrary
|
|
16
|
+
in various programming languages directly in your browser, no installation required.
|
|
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
|
|
24
|
+
|
|
25
|
+
Currently, Papyros provides support for the following programming languages:
|
|
26
|
+
- Python, powered by [Pyodide](https://pyodide.org/en/stable/)
|
|
27
|
+
- JavaScript, powered by your browser
|
|
28
|
+
|
|
29
|
+
## Installation
|
|
30
|
+
|
|
31
|
+
You can install Papyros on your system using npm:
|
|
32
|
+
```shell
|
|
33
|
+
npm install -g @dodona/papyros
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Usage
|
|
37
|
+
|
|
38
|
+
Papyros currently supports two modes of operation: stand-alone and embedded.
|
|
39
|
+
|
|
40
|
+
In stand-alone mode, Papyros runs as a full application in the browser.
|
|
41
|
+
This includes extra UI elements to allow selecting a locale, a programming language, ...
|
|
42
|
+
|
|
43
|
+
In embedded mode, the layout is reduced to the minimum. Dynamic selections are not displayed,
|
|
44
|
+
as the user knows for what purpose Papyros is being used. For example, when used in the
|
|
45
|
+
scope of a Python exercise in Dodona, there is no need to support other programming languages.
|
|
46
|
+
The locale should also match that of the actual application.
|
|
47
|
+
|
|
48
|
+
The easiest way to initialize Papyros is by using the static method Papyros.fromElement.
|
|
49
|
+
This method expects a parent element that wraps the scratchpad and a PapyrosConfig object.
|
|
50
|
+
The following options are supported:
|
|
51
|
+
- standAlone: Whether to operate in stand-alone or embedded mode as described above.
|
|
52
|
+
- locale: The locale to use, currently English and Dutch translations are provided.
|
|
53
|
+
- programmingLanguage: The language to use in the CodeEditor and Backend
|
|
54
|
+
|
|
55
|
+
## Documentation
|
|
56
|
+
|
|
57
|
+
Visit our web page at <https://docs.dodona.be/papyros/>.
|
|
58
|
+
|
|
59
|
+
## Building and developing
|
|
60
|
+
|
|
61
|
+
Clone the repository using git.
|
|
62
|
+
```shell
|
|
63
|
+
git@github.com:dodona-edu/papyros.git
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Install the required dependencies.
|
|
67
|
+
```shell
|
|
68
|
+
yarn install
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Start the local dev-server, powered by webpack.
|
|
72
|
+
```shell
|
|
73
|
+
yarn start
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
You can now develop with live-reloading.
|
|
77
|
+
You can view the results in your browser by visting http://localhost:8080.
|
|
78
|
+
|
|
79
|
+
## Try it online
|
|
80
|
+
|
|
81
|
+
Start coding immediately in your [browser](https://docs.dodona.be/papyros/).
|
package/lib/114.index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";exports.id=114,exports.ids=[114],exports.modules={872:(e,t,n)=>{var r;n.d(t,{z:()=>c}),function(e){e.Python="Python",e.JavaScript="JavaScript"}(r||(r={})),r.Python,r.JavaScript,new Map([["python",r.Python],["javascript",r.JavaScript]]),r.Python;var o,a=function(e,t){var n="function"==typeof Symbol&&e[Symbol.iterator];if(!n)return e;var r,o,a=n.call(e),i=[];try{for(;(void 0===t||t-- >0)&&!(r=a.next()).done;)i.push(r.value)}catch(e){o={error:e}}finally{try{r&&!r.done&&(n=a.return)&&n.call(a)}finally{if(o)throw o.error}}return i},i=function(e,t,n){if(n||2===arguments.length)for(var r,o=0,a=t.length;o<a;o++)!r&&o in t||(r||(r=Array.prototype.slice.call(t,0,o)),r[o]=t[o]);return e.concat(r||Array.prototype.slice.call(t))};function s(e){for(var t=[],n=1;n<arguments.length;n++)t[n-1]=arguments[n];var r=e!==o.Debug;r&&(e===o.Error?console.error.apply(console,i([],a(t),!1)):console.log.apply(console,i([],a(t),!1)))}!function(e){e[e.Debug=0]="Debug",e[e.Error=1]="Error",e[e.Important=2]="Important"}(o||(o={}));var c=function(){function e(){this.onEvent=function(){},this.runId=0}return e.prototype.launch=function(e,t,n){var r=this,o=function(e,t){if(e&&t){var n=new TextDecoder;return function(){for(;"timed-out"===Atomics.wait(t,0,0,100););Atomics.store(t,0,0);var r=Atomics.exchange(t,1,0),o=e.slice(0,r);return n.decode(o)}}return function(){var e=new XMLHttpRequest;do{e.open("GET","/__papyros_input",!1),e.send(null)}while(e.status>=400);return e.responseText}}(t,n);return this.onEvent=function(t){if(t.runId=r.runId,e(t),"input"===t.type)return o()},Promise.resolve()},e.prototype.runCode=function(e,t){return n=this,r=void 0,i=function(){var n,r,a;return function(e,t){var n,r,o,a,i={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return a={next:s(0),throw:s(1),return:s(2)},"function"==typeof Symbol&&(a[Symbol.iterator]=function(){return this}),a;function s(a){return function(s){return function(a){if(n)throw new TypeError("Generator is already executing.");for(;i;)try{if(n=1,r&&(o=2&a[0]?r.return:a[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,a[1])).done)return o;switch(r=0,o&&(a=[2&a[0],o.value]),a[0]){case 0:case 1:o=a;break;case 4:return i.label++,{value:a[1],done:!1};case 5:i.label++,r=a[1],a=[0];continue;case 7:a=i.ops.pop(),i.trys.pop();continue;default:if(!((o=(o=i.trys).length>0&&o[o.length-1])||6!==a[0]&&2!==a[0])){i=0;continue}if(3===a[0]&&(!o||a[1]>o[0]&&a[1]<o[3])){i.label=a[1];break}if(6===a[0]&&i.label<o[1]){i.label=o[1],o=a;break}if(o&&i.label<o[2]){i.label=o[2],i.ops.push(a);break}o[2]&&i.ops.pop(),i.trys.pop();continue}a=t.call(e,i)}catch(e){a=[6,e],r=0}finally{n=o=0}if(5&a[0])throw a[1];return{value:a[0]?a[1]:void 0,done:!0}}([a,s])}}}(this,(function(i){switch(i.label){case 0:this.runId=t,s(o.Debug,"Running code in worker: ",e),i.label=1;case 1:return i.trys.push([1,3,,4]),[4,this._runCodeInternal(e)];case 2:return n=i.sent(),s(o.Important,"ran code: "+e+" and received: ",n),[2,this.onEvent({type:"success",data:n,runId:t})];case 3:return r=i.sent(),a="toString"in r?r.toString():JSON.stringify(r),s(o.Error,"Error during execution: ",r,a),[2,this.onEvent({type:"error",data:a,runId:t})];case 4:return[2]}}))},new((a=void 0)||(a=Promise))((function(e,t){function o(e){try{c(i.next(e))}catch(e){t(e)}}function s(e){try{c(i.throw(e))}catch(e){t(e)}}function c(t){var n;t.done?e(t.value):(n=t.value,n instanceof a?n:new a((function(e){e(n)}))).then(o,s)}c((i=i.apply(n,r||[])).next())}));var n,r,a,i},e}()},375:(e,t,n)=>{n.d(t,{Jj:()=>u});const r=Symbol("Comlink.proxy"),o=Symbol("Comlink.endpoint"),a=Symbol("Comlink.releaseProxy"),i=Symbol("Comlink.thrown"),s=e=>"object"==typeof e&&null!==e||"function"==typeof e,c=new Map([["proxy",{canHandle:e=>s(e)&&e[r],serialize(e){const{port1:t,port2:n}=new MessageChannel;return u(e,t),[n,[n]]},deserialize:e=>(e.start(),f(e,[],undefined))}],["throw",{canHandle:e=>s(e)&&i in e,serialize({value:e}){let t;return t=e instanceof Error?{isError:!0,value:{message:e.message,name:e.name,stack:e.stack}}:{isError:!1,value:e},[t,[]]},deserialize(e){if(e.isError)throw Object.assign(new Error(e.value.message),e.value);throw e.value}}]]);function u(e,t=self){t.addEventListener("message",(function n(o){if(!o||!o.data)return;const{id:a,type:s,path:c}=Object.assign({path:[]},o.data),p=(o.data.argumentList||[]).map(v);let f;try{const t=c.slice(0,-1).reduce(((e,t)=>e[t]),e),n=c.reduce(((e,t)=>e[t]),e);switch(s){case"GET":f=n;break;case"SET":t[c.slice(-1)[0]]=v(o.data.value),f=!0;break;case"APPLY":f=n.apply(t,p);break;case"CONSTRUCT":f=function(e){return Object.assign(e,{[r]:!0})}(new n(...p));break;case"ENDPOINT":{const{port1:t,port2:n}=new MessageChannel;u(e,n),f=function(e,t){return d.set(e,t),e}(t,[t])}break;case"RELEASE":f=void 0;break;default:return}}catch(e){f={value:e,[i]:0}}Promise.resolve(f).catch((e=>({value:e,[i]:0}))).then((e=>{const[r,o]=y(e);t.postMessage(Object.assign(Object.assign({},r),{id:a}),o),"RELEASE"===s&&(t.removeEventListener("message",n),l(t))}))})),t.start&&t.start()}function l(e){(function(e){return"MessagePort"===e.constructor.name})(e)&&e.close()}function p(e){if(e)throw new Error("Proxy has been released and is not useable")}function f(e,t=[],n=function(){}){let r=!1;const i=new Proxy(n,{get(n,o){if(p(r),o===a)return()=>m(e,{type:"RELEASE",path:t.map((e=>e.toString()))}).then((()=>{l(e),r=!0}));if("then"===o){if(0===t.length)return{then:()=>i};const n=m(e,{type:"GET",path:t.map((e=>e.toString()))}).then(v);return n.then.bind(n)}return f(e,[...t,o])},set(n,o,a){p(r);const[i,s]=y(a);return m(e,{type:"SET",path:[...t,o].map((e=>e.toString())),value:i},s).then(v)},apply(n,a,i){p(r);const s=t[t.length-1];if(s===o)return m(e,{type:"ENDPOINT"}).then(v);if("bind"===s)return f(e,t.slice(0,-1));const[c,u]=h(i);return m(e,{type:"APPLY",path:t.map((e=>e.toString())),argumentList:c},u).then(v)},construct(n,o){p(r);const[a,i]=h(o);return m(e,{type:"CONSTRUCT",path:t.map((e=>e.toString())),argumentList:a},i).then(v)}});return i}function h(e){const t=e.map(y);return[t.map((e=>e[0])),(n=t.map((e=>e[1])),Array.prototype.concat.apply([],n))];var n}const d=new WeakMap;function y(e){for(const[t,n]of c)if(n.canHandle(e)){const[r,o]=n.serialize(e);return[{type:"HANDLER",name:t,value:r},o]}return[{type:"RAW",value:e},d.get(e)||[]]}function v(e){switch(e.type){case"HANDLER":return c.get(e.name).deserialize(e.value);case"RAW":return e.value}}function m(e,t,n){return new Promise((r=>{const o=new Array(4).fill(0).map((()=>Math.floor(Math.random()*Number.MAX_SAFE_INTEGER).toString(16))).join("-");e.addEventListener("message",(function t(n){n.data&&n.data.id&&n.data.id===o&&(e.removeEventListener("message",t),r(n.data))})),e.start&&e.start(),e.postMessage(Object.assign({id:o},t),n)}))}}};
|
package/lib/572.index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.Papyros=e():t.Papyros=e()}(global,(function(){return(()=>{"use strict";var t,e,n,r={572:(t,e,n)=>{var r,o=n(375),i=n(872),s=(r=function(t,e){return r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&(t[n]=e[n])},r(t,e)},function(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Class extends value "+String(e)+" is not a constructor or null");function n(){this.constructor=t}r(t,e),t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)}),a=function(t,e,n,r){return new(n||(n=Promise))((function(o,i){function s(t){try{u(r.next(t))}catch(t){i(t)}}function a(t){try{u(r.throw(t))}catch(t){i(t)}}function u(t){var e;t.done?o(t.value):(e=t.value,e instanceof n?e:new n((function(t){t(e)}))).then(s,a)}u((r=r.apply(t,e||[])).next())}))},u=function(t,e){var n,r,o,i,s={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return i={next:a(0),throw:a(1),return:a(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function a(i){return function(a){return function(i){if(n)throw new TypeError("Generator is already executing.");for(;s;)try{if(n=1,r&&(o=2&i[0]?r.return:i[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,i[1])).done)return o;switch(r=0,o&&(i=[2&i[0],o.value]),i[0]){case 0:case 1:o=i;break;case 4:return s.label++,{value:i[1],done:!1};case 5:s.label++,r=i[1],i=[0];continue;case 7:i=s.ops.pop(),s.trys.pop();continue;default:if(!((o=(o=s.trys).length>0&&o[o.length-1])||6!==i[0]&&2!==i[0])){s=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]<o[3])){s.label=i[1];break}if(6===i[0]&&s.label<o[1]){s.label=o[1],o=i;break}if(o&&s.label<o[2]){s.label=o[2],s.ops.push(i);break}o[2]&&s.ops.pop(),s.trys.pop();continue}i=e.call(t,s)}catch(t){i=[6,t],r=0}finally{n=o=0}if(5&i[0])throw i[1];return{value:i[0]?i[1]:void 0,done:!0}}([i,a])}}};importScripts("https://cdn.jsdelivr.net/pyodide/v0.18.1/full/pyodide.js");var l=function(t){function e(){var e=t.call(this)||this;return e.pyodide={},e.initialized=!1,e.globals=new Map,e}return s(e,t),e.prototype.launch=function(e,n,r){return a(this,void 0,void 0,(function(){var o,i,s=this;return u(this,(function(a){switch(a.label){case 0:return[4,t.prototype.launch.call(this,e,n,r)];case 1:return a.sent(),[4,loadPyodide({indexURL:"https://cdn.jsdelivr.net/pyodide/v0.18.1/full/",fullStdLib:!1})];case 2:return o=a.sent(),this.pyodide=o,[4,this.runCode('\nfrom pyodide import to_js\nimport sys\n\ndef __override_builtins(cb):\n __capture_stdout(cb)\n __override_stdin(cb)\n # set name to main instead of builtins\n globals()["__name__"] = "__main__"\n\ndef __capture_stdout(cb):\n class _OutputWriter:\n def __init__(self):\n self.encoding = "utf-8"\n \n def write(self, s):\n cb(to_js({"type": "output", "data":s}))\n\n def flush(self):\n pass # Given data is always immediately written\n\n sys.stdout = _OutputWriter()\n\n__papyros_input = ""\ndef __override_stdin(cb):\n def __papyros_readline(n=-1):\n global __papyros_input\n if not __papyros_input:\n __papyros_input = cb(to_js({"type": "input", "data":"next line"})) + "\\n"\n if n < 0 or n > len(__papyros_input):\n n = len(__papyros_input)\n to_return = __papyros_input[0:n]\n __papyros_input = __papyros_input[n:]\n return to_return\n\n sys.stdin.readline = __papyros_readline\n',0)];case 3:return a.sent(),i=function(t){var e="toJs"in t?t.toJs():Object.fromEntries(t);return s.onEvent(e)},this.pyodide.globals.get("__override_builtins")(i),this.globals=new Map(this.pyodide.globals.toJs()),this.initialized=!0,[2]}}))}))},e.prototype._cleanScope=function(){var t,e,n=this.pyodide.globals,r=[];try{for(var o=function(t){var e="function"==typeof Symbol&&Symbol.iterator,n=e&&t[e],r=0;if(n)return n.call(t);if(t&&"number"==typeof t.length)return{next:function(){return t&&r>=t.length&&(t=void 0),{value:t&&t[r++],done:!t}}};throw new TypeError(e?"Object is not iterable.":"Symbol.iterator is not defined.")}(n.keys()),i=o.next();!i.done;i=o.next()){var s=i.value;this.globals.has(s)?n.set(s,this.globals.get(s)):r.push(s)}}catch(e){t={error:e}}finally{try{i&&!i.done&&(e=o.return)&&e.call(o)}finally{if(t)throw t.error}}r.forEach((function(t){return n.delete(t)}))},e.prototype._runCodeInternal=function(t){return a(this,void 0,void 0,(function(){var e;return u(this,(function(n){switch(n.label){case 0:return[4,this.pyodide.loadPackagesFromImports(t)];case 1:return n.sent(),this.initialized?(e=this.pyodide.runPython(t),this._cleanScope(),[2,e]):[2,this.pyodide.runPythonAsync(t)]}}))}))},e}(i.z);(0,o.Jj)(new l)}},o={};function i(t){var e=o[t];if(void 0!==e)return e.exports;var n=o[t]={exports:{}};return r[t](n,n.exports,i),n.exports}return i.m=r,i.x=()=>{var t=i.O(void 0,[114],(()=>i(572)));return i.O(t)},t=[],i.O=(e,n,r,o)=>{if(!n){var s=1/0;for(p=0;p<t.length;p++){for(var[n,r,o]=t[p],a=!0,u=0;u<n.length;u++)(!1&o||s>=o)&&Object.keys(i.O).every((t=>i.O[t](n[u])))?n.splice(u--,1):(a=!1,o<s&&(s=o));if(a){t.splice(p--,1);var l=r();void 0!==l&&(e=l)}}return e}o=o||0;for(var p=t.length;p>0&&t[p-1][2]>o;p--)t[p]=t[p-1];t[p]=[n,r,o]},i.d=(t,e)=>{for(var n in e)i.o(e,n)&&!i.o(t,n)&&Object.defineProperty(t,n,{enumerable:!0,get:e[n]})},i.f={},i.e=t=>Promise.all(Object.keys(i.f).reduce(((e,n)=>(i.f[n](t,e),e)),[])),i.u=t=>t+".index.js",i.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e),n={572:1},i.O.require=t=>n[t],i.f.require=(t,e)=>{n[t]||(t=>{var e=t.modules,r=t.ids,o=t.runtime;for(var s in e)i.o(e,s)&&(i.m[s]=e[s]);o&&o(i);for(var a=0;a<r.length;a++)n[r[a]]=1;i.O()})(require("./"+i.u(t)))},e=i.x,i.x=()=>(i.e(114),e()),i.x()})()}));
|
package/lib/806.index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
!function(r,n){"object"==typeof exports&&"object"==typeof module?module.exports=n():"function"==typeof define&&define.amd?define([],n):"object"==typeof exports?exports.Papyros=n():r.Papyros=n()}(global,(function(){return(()=>{"use strict";var r,n,t,e={806:(r,n,t)=>{var e,o=t(375),i=t(872),a=(e=function(r,n){return e=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(r,n){r.__proto__=n}||function(r,n){for(var t in n)Object.prototype.hasOwnProperty.call(n,t)&&(r[t]=n[t])},e(r,n)},function(r,n){if("function"!=typeof n&&null!==n)throw new TypeError("Class extends value "+String(n)+" is not a constructor or null");function t(){this.constructor=r}e(r,n),r.prototype=null===n?Object.create(n):(t.prototype=n.prototype,new t)}),s=function(r,n){var t="function"==typeof Symbol&&r[Symbol.iterator];if(!t)return r;var e,o,i=t.call(r),a=[];try{for(;(void 0===n||n-- >0)&&!(e=i.next()).done;)a.push(e.value)}catch(r){o={error:r}}finally{try{e&&!e.done&&(t=i.return)&&t.call(i)}finally{if(o)throw o.error}}return a},u=function(r){function n(){return null!==r&&r.apply(this,arguments)||this}return a(n,r),n.prototype._runCodeInternal=function(r){var n,t,e=new Map([["prompt","__prompt"],["console.log","__papyros_log"],["console.error","__papyros_error"]]),o={__onEvent:this.onEvent.bind(this)},i=[],a=[];for(var u in o)Object.prototype.hasOwnProperty.call(o,u)&&a.push("const "+u+" = ctx['"+u+"'];");try{for(var l=function(r){var n="function"==typeof Symbol&&Symbol.iterator,t=n&&r[n],e=0;if(t)return t.call(r);if(r&&"number"==typeof r.length)return{next:function(){return r&&e>=r.length&&(r=void 0),{value:r&&r[e++],done:!r}}};throw new TypeError(n?"Object is not iterable.":"Symbol.iterator is not defined.")}(e.entries()),p=l.next();!p.done;p=l.next()){var f=s(p.value,2),c=f[0],y=f[1];a.push(y+" = "+c),i.push(c+" = "+y)}}catch(r){n={error:r}}finally{try{p&&!p.done&&(t=l.return)&&t.call(l)}finally{if(n)throw n.error}}a.push('\nfunction prompt(text="", defaultText=""){\n __onEvent({"type": "output", "data": text});\n const promptedValue = __onEvent({"type": "input", "data": text});\n __onEvent({"type": "output", "data": promptedValue + "\\n"});\n return promptedValue;\n}\nfunction __stringify(args, addNewline=false){\n let asString = "";\n if(Array.isArray(args)){\n if(args.length === 1){\n asString = JSON.stringify(args[0]);\n } else {\n asString = args.map(s => {\n if(typeof s === \'string\' || s instanceof String){\n return s; // prevent spurious quotes\n } else {\n return JSON.stringify(s);\n }\n }).join(" ");\n }\n } else {\n asString = JSON.stringify(args);\n }\n if(addNewline){\n asString += "\\n";\n }\n return asString;\n}\nconsole.log = (...args) => {\n __onEvent({"type": "output", "data": __stringify(args, true)});\n}\nconsole.error = (...args) => {\n __onEvent({"type": "error", "data": __stringify(args, true)});\n}\n '),a.push("\ntry {\n"+r+"\n} finally {\n"+i.join("\n")+"\n}\n ");var v=a.join("\n");return Promise.resolve(new Function("ctx",v)(o))},n}(i.z);(0,o.Jj)(new u)}},o={};function i(r){var n=o[r];if(void 0!==n)return n.exports;var t=o[r]={exports:{}};return e[r](t,t.exports,i),t.exports}return i.m=e,i.x=()=>{var r=i.O(void 0,[114],(()=>i(806)));return i.O(r)},r=[],i.O=(n,t,e,o)=>{if(!t){var a=1/0;for(p=0;p<r.length;p++){for(var[t,e,o]=r[p],s=!0,u=0;u<t.length;u++)(!1&o||a>=o)&&Object.keys(i.O).every((r=>i.O[r](t[u])))?t.splice(u--,1):(s=!1,o<a&&(a=o));if(s){r.splice(p--,1);var l=e();void 0!==l&&(n=l)}}return n}o=o||0;for(var p=r.length;p>0&&r[p-1][2]>o;p--)r[p]=r[p-1];r[p]=[t,e,o]},i.d=(r,n)=>{for(var t in n)i.o(n,t)&&!i.o(r,t)&&Object.defineProperty(r,t,{enumerable:!0,get:n[t]})},i.f={},i.e=r=>Promise.all(Object.keys(i.f).reduce(((n,t)=>(i.f[t](r,n),n)),[])),i.u=r=>r+".index.js",i.o=(r,n)=>Object.prototype.hasOwnProperty.call(r,n),t={806:1},i.O.require=r=>t[r],i.f.require=(r,n)=>{t[r]||(r=>{var n=r.modules,e=r.ids,o=r.runtime;for(var a in n)i.o(n,a)&&(i.m[a]=n[a]);o&&o(i);for(var s=0;s<e.length;s++)t[e[s]]=1;i.O()})(require("./"+i.u(r)))},n=i.x,i.x=()=>(i.e(114),n()),i.x()})()}));
|
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
declare module Papyros
|
|
2
|
+
{
|
|
3
|
+
import { PapyrosEvent } from "./PapyrosEvent";
|
|
4
|
+
export abstract class Backend {
|
|
5
|
+
onEvent: (e: PapyrosEvent) => any;
|
|
6
|
+
runId: number;
|
|
7
|
+
constructor();
|
|
8
|
+
/**
|
|
9
|
+
* Initialize the backend, setting up any globals required
|
|
10
|
+
* @param {function(PapyrosEvent):void} onEvent Callback for when events occur
|
|
11
|
+
* @param {Uint8Array} inputTextArray Optional shared buffer for input
|
|
12
|
+
* @param {Int32Array} inputMetaData Optional shared buffer for metadata about input
|
|
13
|
+
* @return {Promise<void>} Promise of launching
|
|
14
|
+
*/
|
|
15
|
+
launch(onEvent: (e: PapyrosEvent) => void, inputTextArray?: Uint8Array, inputMetaData?: Int32Array): Promise<void>;
|
|
16
|
+
abstract _runCodeInternal(code: string): Promise<any>;
|
|
17
|
+
/**
|
|
18
|
+
* Validate and run arbitrary code
|
|
19
|
+
* @param {string} code The code to run
|
|
20
|
+
* @param {string} runId The uuid for this execution
|
|
21
|
+
* @return {Promise<void>} Promise of execution
|
|
22
|
+
*/
|
|
23
|
+
runCode(code: string, runId: number): Promise<void>;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
import { Remote } from "comlink";
|
|
27
|
+
import { Backend } from "./Backend";
|
|
28
|
+
import { ProgrammingLanguage } from "./ProgrammingLanguage";
|
|
29
|
+
export function getBackend(language: ProgrammingLanguage): Remote<Backend>;
|
|
30
|
+
export function stopBackend(backend: Remote<Backend>): void;
|
|
31
|
+
|
|
32
|
+
import { Compartment } from "@codemirror/state";
|
|
33
|
+
import { ProgrammingLanguage } from "./ProgrammingLanguage";
|
|
34
|
+
import { EditorView } from "@codemirror/view";
|
|
35
|
+
export class CodeEditor {
|
|
36
|
+
editorView: EditorView;
|
|
37
|
+
languageCompartment: Compartment;
|
|
38
|
+
indentCompartment: Compartment;
|
|
39
|
+
constructor(element: HTMLElement, language: ProgrammingLanguage, initialCode?: string, indentLength?: number);
|
|
40
|
+
setLanguage(language: ProgrammingLanguage): void;
|
|
41
|
+
setIndentLength(indentLength: number): void;
|
|
42
|
+
getCode(): string;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
import { ProgrammingLanguage } from "./ProgrammingLanguage";
|
|
46
|
+
export const MAIN_APP_ID = "papyros";
|
|
47
|
+
export const OUTPUT_TA_ID = "code-output-area";
|
|
48
|
+
export const INPUT_TA_ID = "code-input-area";
|
|
49
|
+
export const EDITOR_WRAPPER_ID = "code-area";
|
|
50
|
+
export const STATE_SPINNER_ID = "state-spinner";
|
|
51
|
+
export const APPLICATION_STATE_TEXT_ID = "application-state-text";
|
|
52
|
+
export const RUN_BTN_ID = "run-code-btn";
|
|
53
|
+
export const TERMINATE_BTN_ID = "terminate-btn";
|
|
54
|
+
export const PROGRAMMING_LANGUAGE_SELECT_ID = "programming-language-select";
|
|
55
|
+
export const DEFAULT_PROGRAMMING_LANGUAGE = ProgrammingLanguage.Python;
|
|
56
|
+
export const LOCALE_SELECT_ID = "locale-select";
|
|
57
|
+
export const DEFAULT_LOCALE = "nl";
|
|
58
|
+
export const INPUT_RELATIVE_URL = "/__papyros_input";
|
|
59
|
+
export const SERVICE_WORKER_PATH = "./inputServiceWorker.js";
|
|
60
|
+
|
|
61
|
+
export {};
|
|
62
|
+
|
|
63
|
+
import "./Papyros.css";
|
|
64
|
+
import { Remote } from "comlink";
|
|
65
|
+
import { Backend } from "./Backend";
|
|
66
|
+
import { CodeEditor } from "./CodeEditor";
|
|
67
|
+
import { PapyrosEvent } from "./PapyrosEvent";
|
|
68
|
+
import { ProgrammingLanguage } from "./ProgrammingLanguage";
|
|
69
|
+
enum PapyrosState {
|
|
70
|
+
Loading = "loading",
|
|
71
|
+
Running = "running",
|
|
72
|
+
AwaitingInput = "awaiting_input",
|
|
73
|
+
Terminating = "terminating",
|
|
74
|
+
Ready = "ready"
|
|
75
|
+
}
|
|
76
|
+
class PapyrosStateManager {
|
|
77
|
+
state: PapyrosState;
|
|
78
|
+
stateSpinner: HTMLElement;
|
|
79
|
+
stateText: HTMLElement;
|
|
80
|
+
runButton: HTMLButtonElement;
|
|
81
|
+
terminateButton: HTMLButtonElement;
|
|
82
|
+
constructor();
|
|
83
|
+
setState(state: PapyrosState, message?: string): void;
|
|
84
|
+
}
|
|
85
|
+
interface PapyrosCodeState {
|
|
86
|
+
programmingLanguage: ProgrammingLanguage;
|
|
87
|
+
editor: CodeEditor;
|
|
88
|
+
backend: Remote<Backend>;
|
|
89
|
+
runId: number;
|
|
90
|
+
outputArea: HTMLInputElement;
|
|
91
|
+
}
|
|
92
|
+
interface PapyrosInputState {
|
|
93
|
+
lineNr: number;
|
|
94
|
+
textEncoder: TextEncoder;
|
|
95
|
+
inputArea: HTMLInputElement;
|
|
96
|
+
inputTextArray?: Uint8Array;
|
|
97
|
+
inputMetaData?: Int32Array;
|
|
98
|
+
}
|
|
99
|
+
interface PapyrosConfig {
|
|
100
|
+
standAlone: boolean;
|
|
101
|
+
locale: string;
|
|
102
|
+
programmingLanguage: ProgrammingLanguage;
|
|
103
|
+
}
|
|
104
|
+
export class Papyros {
|
|
105
|
+
stateManager: PapyrosStateManager;
|
|
106
|
+
codeState: PapyrosCodeState;
|
|
107
|
+
inputState: PapyrosInputState;
|
|
108
|
+
constructor(programmingLanguage: ProgrammingLanguage, inputTextArray?: Uint8Array, inputMetaData?: Int32Array);
|
|
109
|
+
launch(): Promise<Papyros>;
|
|
110
|
+
setProgrammingLanguage(programmingLanguage: ProgrammingLanguage): Promise<void>;
|
|
111
|
+
startBackend(): Promise<void>;
|
|
112
|
+
static fromElement(parent: HTMLElement, config: PapyrosConfig): Promise<Papyros>;
|
|
113
|
+
onError(e: PapyrosEvent): void;
|
|
114
|
+
sendInput(): Promise<boolean>;
|
|
115
|
+
onInput(e: PapyrosEvent): Promise<void>;
|
|
116
|
+
onMessage(e: PapyrosEvent): void;
|
|
117
|
+
runCode(): Promise<void>;
|
|
118
|
+
terminate(): Promise<void>;
|
|
119
|
+
}
|
|
120
|
+
export {};
|
|
121
|
+
|
|
122
|
+
export interface PapyrosEvent {
|
|
123
|
+
type: "input" | "output" | "script" | "success" | "error";
|
|
124
|
+
data: string;
|
|
125
|
+
runId: number;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export enum ProgrammingLanguage {
|
|
129
|
+
Python = "Python",
|
|
130
|
+
JavaScript = "JavaScript"
|
|
131
|
+
}
|
|
132
|
+
export const PROGRAMMING_LANGUAGES: ProgrammingLanguage[];
|
|
133
|
+
export function plFromString(language: string): ProgrammingLanguage;
|
|
134
|
+
|
|
135
|
+
export const TRANSLATIONS: {
|
|
136
|
+
en: {
|
|
137
|
+
Papyros: {
|
|
138
|
+
Papyros: string;
|
|
139
|
+
enter_code: string;
|
|
140
|
+
enter_input: string;
|
|
141
|
+
code_output: string;
|
|
142
|
+
run: string;
|
|
143
|
+
terminate: string;
|
|
144
|
+
running: string;
|
|
145
|
+
terminating: string;
|
|
146
|
+
loading: string;
|
|
147
|
+
awaiting_input: string;
|
|
148
|
+
ready: string;
|
|
149
|
+
finished: string;
|
|
150
|
+
programming_language: string;
|
|
151
|
+
Python: string;
|
|
152
|
+
JavaScript: string;
|
|
153
|
+
};
|
|
154
|
+
};
|
|
155
|
+
nl: {
|
|
156
|
+
Papyros: {
|
|
157
|
+
Papyros: string;
|
|
158
|
+
enter_code: string;
|
|
159
|
+
enter_input: string;
|
|
160
|
+
code_output: string;
|
|
161
|
+
run: string;
|
|
162
|
+
terminate: string;
|
|
163
|
+
running: string;
|
|
164
|
+
terminating: string;
|
|
165
|
+
loading: string;
|
|
166
|
+
awaiting_input: string;
|
|
167
|
+
ready: string;
|
|
168
|
+
finished: string;
|
|
169
|
+
programming_language: string;
|
|
170
|
+
Python: string;
|
|
171
|
+
JavaScript: string;
|
|
172
|
+
};
|
|
173
|
+
};
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
export enum LogType {
|
|
177
|
+
Debug = 0,
|
|
178
|
+
Error = 1,
|
|
179
|
+
Important = 2
|
|
180
|
+
}
|
|
181
|
+
export function papyrosLog(logType: LogType, ...args: any[]): void;
|
|
182
|
+
|
|
183
|
+
export {};
|
|
184
|
+
|
|
185
|
+
export {};
|
|
186
|
+
|
|
187
|
+
export const INITIALIZATION_CODE = "\nfrom pyodide import to_js\nimport sys\n\ndef __override_builtins(cb):\n __capture_stdout(cb)\n __override_stdin(cb)\n # set name to main instead of builtins\n globals()[\"__name__\"] = \"__main__\"\n\ndef __capture_stdout(cb):\n class _OutputWriter:\n def __init__(self):\n self.encoding = \"utf-8\"\n \n def write(self, s):\n cb(to_js({\"type\": \"output\", \"data\":s}))\n\n def flush(self):\n pass # Given data is always immediately written\n\n sys.stdout = _OutputWriter()\n\n__papyros_input = \"\"\ndef __override_stdin(cb):\n def __papyros_readline(n=-1):\n global __papyros_input\n if not __papyros_input:\n __papyros_input = cb(to_js({\"type\": \"input\", \"data\":\"next line\"})) + \"\\n\"\n if n < 0 or n > len(__papyros_input):\n n = len(__papyros_input)\n to_return = __papyros_input[0:n]\n __papyros_input = __papyros_input[n:]\n return to_return\n\n sys.stdin.readline = __papyros_readline\n";
|
|
188
|
+
|
|
189
|
+
}
|