@sourceacademy/runner-module-loader 0.0.1
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 +46 -0
- package/dist/__tests__/runner.test.d.ts +1 -0
- package/dist/index.cjs +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.mjs +1 -0
- package/package.json +40 -0
package/README.md
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
<h1 align="center">Module Loader</h1>
|
|
2
|
+
|
|
3
|
+
<p align="center">Runner-side plugin for loading Source Academy modules</p>
|
|
4
|
+
|
|
5
|
+
<p align="center">
|
|
6
|
+
<a href="https://www.npmjs.com/package/@sourceacademy/runner-module-loader"><img src="https://img.shields.io/npm/v/@sourceacademy/runner-module-loader?color=1a2530&label=npm"></a>
|
|
7
|
+
<a href="https://github.com/source-academy/plugins/tree/main/src/runner/module-loader"><img src="https://img.shields.io/badge/github-repo-blue?logo=github"></a>
|
|
8
|
+
</p>
|
|
9
|
+
|
|
10
|
+
## Features
|
|
11
|
+
The plugin provides an interface to load modules with a module ID
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
```bash
|
|
15
|
+
yarn add @sourceacademy/runner-module-loader
|
|
16
|
+
# OR
|
|
17
|
+
npm i @sourceacademy/runner-module-loader
|
|
18
|
+
# OR
|
|
19
|
+
pnpm add @sourceacademy/runner-module-loader
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Structure
|
|
23
|
+
This package ([`@sourceacademy/runner-module-loader`](https://github.com/source-academy/plugins/tree/main/src/runner/module-loader)) contains the `ModuleLoaderRunnerPlugin` class — a Conductor runner plugin that an evaluator can call to load modules.
|
|
24
|
+
|
|
25
|
+
### API Reference
|
|
26
|
+
| Name | Description |
|
|
27
|
+
|------|-------------|
|
|
28
|
+
| `instance` | The singleton instance of the plugin. |
|
|
29
|
+
| `async requestModule(moduleName: string): Promise<IModulePlugin>` | Request a module by name from the host plugin. Rejects with an error if the module is not found. |
|
|
30
|
+
|
|
31
|
+
## Usage
|
|
32
|
+
After installation, import `ModuleLoaderRunnerPlugin` and register it with the Conductor evaluator. When evaluating `import` statements, call `requestModule` to load the module.
|
|
33
|
+
|
|
34
|
+
```ts
|
|
35
|
+
...
|
|
36
|
+
const pluginObj = await ModuleLoaderRunnerPlugin.instance.requestModule(moduleName);
|
|
37
|
+
context.nativeStorage.loadedModules[moduleName] = Object.fromEntries(
|
|
38
|
+
pluginObj?.exports.map(t => [t.symbol, t]) || [],
|
|
39
|
+
);
|
|
40
|
+
...
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Further reading
|
|
44
|
+
- For the shared protocol types and IDs, see [`@sourceacademy/common-module-loader`](https://github.com/source-academy/plugins/tree/main/src/common/module-loader)
|
|
45
|
+
- For the host-side plugin that accepts the module directory URL, see [`@sourceacademy/web-module-loader`](https://github.com/source-academy/plugins/tree/main/src/web/module-loader)
|
|
46
|
+
- The [plugins wiki](https://github.com/source-academy/plugins/wiki) covers how Conductor plugins communicate
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";function e(e,t,n,o){return new(n||(n=Promise))(function(_,u){function i(e){try{s(o.next(e))}catch(e){u(e)}}function r(e){try{s(o.throw(e))}catch(e){u(e)}}function s(e){var t;e.done?_(e.value):(t=e.value,t instanceof n?t:new n(function(e){e(t)})).then(i,r)}s((o=o.apply(e,t||[])).next())})}"function"==typeof SuppressedError&&SuppressedError;var t,n,o,_,u;(n=t||(t={})).REQUEST_MODULE="request_module",n.MODULE_RESPONSE="module_response",n.MODULE_ERROR="module_error",function(e){e[e.CALL=0]="CALL",e[e.RETURN=1]="RETURN",e[e.RETURN_ERR=2]="RETURN_ERR"}(o||(o={})),function(e){e.UNKNOWN="__unknown",e.INTERNAL="__internal",e.EVALUATOR="__evaluator",e.EVALUATOR_SYNTAX="__evaluator_syntax",e.EVALUATOR_TYPE="__evaluator_type",e.EVALUATOR_RUNTIME="__evaluator_runtime"}(_||(_={})),function(e){e[e.PROTOCOL_VERSION=0]="PROTOCOL_VERSION",e[e.PROTOCOL_MIN_VERSION=0]="PROTOCOL_MIN_VERSION",e[e.SETUP_MESSAGES_BUFFER_SIZE=10]="SETUP_MESSAGES_BUFFER_SIZE"}(u||(u={}));class i{constructor(e,[t],n,o){this.id="__runner_module_loader",this.__loadedPlugins=new Map,this.__moduleRequestChannel=t,this.__conductor=n,this.__evaluator=o,i.instance=this}requestModule(n){return e(this,void 0,void 0,function*(){return this.__loadedPlugins.has(n)||this.__loadedPlugins.set(n,new Promise((o,_)=>{const u=i=>e(this,void 0,void 0,function*(){try{if(i.moduleName!==n)return;if(this.__moduleRequestChannel.unsubscribe(u),i.type===t.MODULE_RESPONSE){const e=yield import(i.moduleURL).then(e=>e.default(()=>{}).default),t=this.__conductor.registerPlugin(e,this.__evaluator,{tabs:i.tabs,loadTab:e=>{if(!i.tabs.includes(e))throw new Error(`Tab ${e} not found in module ${n}`);this.__conductor.hostLoadPlugin(e)}});yield t.initialise(),o(t)}else if(i.type===t.MODULE_ERROR)throw Error(i.error)}catch(e){this.__loadedPlugins.delete(n),_(e)}});this.__moduleRequestChannel.subscribe(u),this.__moduleRequestChannel.send({type:t.REQUEST_MODULE,moduleName:n})})),this.__loadedPlugins.get(n)})}}i.channelAttach=["module_config"],i.instance=null,exports.ModuleLoaderRunnerPlugin=i;
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type IChannel, type IConduit, type IPlugin } from "@sourceacademy/conductor/conduit";
|
|
2
|
+
import type { IModulePlugin } from "@sourceacademy/conductor/module";
|
|
3
|
+
import type { IInterfacableEvaluator, IRunnerPlugin } from "@sourceacademy/conductor/runner";
|
|
4
|
+
export declare class ModuleLoaderRunnerPlugin implements IPlugin {
|
|
5
|
+
readonly id: string;
|
|
6
|
+
static readonly channelAttach: string[];
|
|
7
|
+
private readonly __moduleRequestChannel;
|
|
8
|
+
private readonly __conductor;
|
|
9
|
+
private readonly __evaluator;
|
|
10
|
+
private readonly __loadedPlugins;
|
|
11
|
+
static instance: ModuleLoaderRunnerPlugin | null;
|
|
12
|
+
constructor(conduit: IConduit, [moduleRequestChannel]: IChannel<any>[], conductor: IRunnerPlugin, evaluator: IInterfacableEvaluator);
|
|
13
|
+
requestModule(moduleName: string): Promise<IModulePlugin>;
|
|
14
|
+
}
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function e(e,t,n,o){return new(n||(n=Promise))(function(_,u){function i(e){try{s(o.next(e))}catch(e){u(e)}}function r(e){try{s(o.throw(e))}catch(e){u(e)}}function s(e){var t;e.done?_(e.value):(t=e.value,t instanceof n?t:new n(function(e){e(t)})).then(i,r)}s((o=o.apply(e,t||[])).next())})}"function"==typeof SuppressedError&&SuppressedError;var t,n,o,_,u;(n=t||(t={})).REQUEST_MODULE="request_module",n.MODULE_RESPONSE="module_response",n.MODULE_ERROR="module_error",function(e){e[e.CALL=0]="CALL",e[e.RETURN=1]="RETURN",e[e.RETURN_ERR=2]="RETURN_ERR"}(o||(o={})),function(e){e.UNKNOWN="__unknown",e.INTERNAL="__internal",e.EVALUATOR="__evaluator",e.EVALUATOR_SYNTAX="__evaluator_syntax",e.EVALUATOR_TYPE="__evaluator_type",e.EVALUATOR_RUNTIME="__evaluator_runtime"}(_||(_={})),function(e){e[e.PROTOCOL_VERSION=0]="PROTOCOL_VERSION",e[e.PROTOCOL_MIN_VERSION=0]="PROTOCOL_MIN_VERSION",e[e.SETUP_MESSAGES_BUFFER_SIZE=10]="SETUP_MESSAGES_BUFFER_SIZE"}(u||(u={}));class i{constructor(e,[t],n,o){this.id="__runner_module_loader",this.__loadedPlugins=new Map,this.__moduleRequestChannel=t,this.__conductor=n,this.__evaluator=o,i.instance=this}requestModule(n){return e(this,void 0,void 0,function*(){return this.__loadedPlugins.has(n)||this.__loadedPlugins.set(n,new Promise((o,_)=>{const u=i=>e(this,void 0,void 0,function*(){try{if(i.moduleName!==n)return;if(this.__moduleRequestChannel.unsubscribe(u),i.type===t.MODULE_RESPONSE){const e=yield import(i.moduleURL).then(e=>e.default(()=>{}).default),t=this.__conductor.registerPlugin(e,this.__evaluator,{tabs:i.tabs,loadTab:e=>{if(!i.tabs.includes(e))throw new Error(`Tab ${e} not found in module ${n}`);this.__conductor.hostLoadPlugin(e)}});yield t.initialise(),o(t)}else if(i.type===t.MODULE_ERROR)throw Error(i.error)}catch(e){this.__loadedPlugins.delete(n),_(e)}});this.__moduleRequestChannel.subscribe(u),this.__moduleRequestChannel.send({type:t.REQUEST_MODULE,moduleName:n})})),this.__loadedPlugins.get(n)})}}i.channelAttach=["module_config"],i.instance=null;export{i as ModuleLoaderRunnerPlugin};
|
package/package.json
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@sourceacademy/runner-module-loader",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"packageManager": "yarn@4.6.0",
|
|
5
|
+
"description": "The runner plugin for the module loader in Source Academy",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"build": "rollup -c",
|
|
8
|
+
"prepack": "yarn build"
|
|
9
|
+
},
|
|
10
|
+
"license": "ISC",
|
|
11
|
+
"files": [
|
|
12
|
+
"dist"
|
|
13
|
+
],
|
|
14
|
+
"main": "dist/index.cjs",
|
|
15
|
+
"module": "dist/index.mjs",
|
|
16
|
+
"types": "dist/index.d.ts",
|
|
17
|
+
"exports": {
|
|
18
|
+
".": {
|
|
19
|
+
"import": "./dist/index.mjs",
|
|
20
|
+
"require": "./dist/index.cjs",
|
|
21
|
+
"types": "./dist/index.d.ts"
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"peerDependencies": {
|
|
25
|
+
"@sourceacademy/conductor": ">=0.3.0"
|
|
26
|
+
},
|
|
27
|
+
"devDependencies": {
|
|
28
|
+
"@rollup/plugin-node-resolve": "^16.0.3",
|
|
29
|
+
"@rollup/plugin-terser": "^1.0.0",
|
|
30
|
+
"@rollup/plugin-typescript": "^12.3.0",
|
|
31
|
+
"@sourceacademy/common-module-loader": "workspace:*",
|
|
32
|
+
"@sourceacademy/conductor": ">=0.3.0",
|
|
33
|
+
"@sourceacademy/runner-remote-execution": "workspace:*",
|
|
34
|
+
"@vitest/coverage-istanbul": "^4.1.9",
|
|
35
|
+
"rollup": "^4.60.2",
|
|
36
|
+
"tslib": "^2.8.1",
|
|
37
|
+
"typescript": "^6.0.3",
|
|
38
|
+
"vitest": "^4.1.9"
|
|
39
|
+
}
|
|
40
|
+
}
|