-
Notifications
You must be signed in to change notification settings - Fork 29
System Implementation in Source Academy Frontend
This page contains developer information regarding the interaction between the Source Modules system and the Source Academy frontend cadet-frontend
.
In the Redux store of the Source Academy frontend, there is the debuggerContext
that Source Module developers should be concerned about. The debuggerContext
is collected from the Saga middleware, specifically at WorkspaceSaga
during evaluation of any Source program. After evaluation of the Source program, an action loaded with debuggerContext
is dispatched. The corresponding reducer, WorkspaceReducer
, saves the debuggerContext
into the Redux store.
Previously, there is almost no information passed by frontend to the Source Module's tabs. In other words, the Source Module tabs and bundle do not have direct access to the program being evaluated.
---> = data flow
---+ = child component (no data flow)
program ---> sagas ---> front-end ---+ source module tab
In the event that the source module tab requires additional information, they have to invent a way to collect the information and pass it to their corresponding module tab. This introduces many 'inventive' ways throughout the code base for their data collection.
---> = data flow
---+ = child component (no data flow)
_______________________
| | 'inventive' collection of data from sagas
| v
program ---> sagas ---> front-end ---+ source module tab
As such, the solution is to introduce a formalised pipeline such that module tabs are able to easily access their required information. The front-end now saves the required data and save it into the store, where module tabs can easily access the required information. This eliminates the need for other 'inventive' ways to be deployed and clutter the code base.
---> = data flow
---+ = child component (no data flow)
------> redux store
| |
program ---> sagas ---> front-end | debuggerContext passed as react component props
| v
---+ source module tab
Most likely, there is going to be a need for interaction between the Source Module tab and the Source Module bundle. For example, in the pix_n_flix
module, we would need a way to somehow let the Source Module tab know that we need to render the HTMLVideoElement
with the provided video filter. This is achieved through the debuggerContext
object where information related to the evaluation of the Source program is saved. A more detailed explanation of the debuggerContext
object is available in the previous section.
Within the debuggerContext
object received in the Source Module tab as react component props, there exists a result
property that contains the result of the evaluation of the last statement of the Source program string. The interaction between the Source Module bundles and tabs currently take advantage of this. Currently, the system mandates that the Source program's last statement returns an object that looks similar to the following type.
{
toReplString: () => string;
init: ( ... ) => any;
}
As described in the paragraphs above, this return value of the init()
function will be stored within the debuggerContext
in debuggerContext.result.value
. As a result, the Source Module tab will have to access the result's value in the debuggerContext
to retrieve information related to the imported instance of the Source Module bundle.
In the Source Module's Bundle
const arrayData = [];
function save(array: any[]): void {
arrayData.push([...array]);
}
function start(): any {
return () => arrayData;
}
export default function (__params) {
return { save, start }
}
In the Source program evaluated
import { save, start } from "bundle";
// This program saves [0], [0,1], [0,1,2], [0,1,2,3] and [0,1,2,3,4] into the Source Module's bundle
const newArray = [];
for (let counter = 0; counter < 5; counter = counter + 1) {
newArray[counter] = counter;
save(newArray);
}
start();
In the Source Module's tab
import React from "react";
...
class Tab extends React.Component<Props,State> {
constructor(props) { ... }
// this.props.debuggerContext.result.value is the function () => arrayData
// since start(); was the last statement evaluated in the Source program and
// the implementation of the start() function in the bundle returns the function
const getArraysState = () => this.props.debuggerContext.result.value();
...
}
- Home
- Overview
- System Implementation
-
Development Guide
- Getting Started
- Repository Structure
-
Creating a New Module
- Creating a Bundle
- Creating a Tab
- Writing Documentation
- Developer Documentation (TODO)
- Build System
- Source Modules
- FAQs
Try out Source Academy here.
Check out the Source Modules generated API documentation here.