As of Smartdown v1.0.20, the Smartdown engine is being reconstructed using Typescript. As of v1.0.21, Smartdown supports the dynamic compilation of Typescript in the browser via typescript
playables.
References:
For our first example, we'll create a little typescript
playable that just listens for changes to the Name
variable and adjusts its div
content accordingly. We'll use the /debug
qualifier on the playable to allow us to view the augmented code that will transpile typescript into javascript.
The source for this playable is encoded in Smartdown like this:
```javascript /typescript/playable/autoplay/debug
// SOURCE goes here
```
with // SOURCE goes here
being replaced by:
const myDiv = this.div;
myDiv.style.background = 'lavender !important';
myDiv.style.color = 'magenta !important';
myDiv.style.padding = '10px 2px';
myDiv.style.margin = '10px 2px';
this.dependOn = ['Name'];
this.depend = function(): void {
const msg: string = ['Nice', 'to', 'meet', 'you'].join(' ');
myDiv.innerHTML = `<p>${msg}, <b>${env.Name}</b>!</p>`;
};
What is your name?
const myDiv = this.div;
myDiv.style.background = 'lavender !important';
myDiv.style.color = 'magenta !important';
myDiv.style.padding = '10px 2px';
myDiv.style.margin = '10px 2px';
this.dependOn.Name = (): void => {
const msg: string = ['Nice', 'to', 'meet', 'you'].join(' ');
myDiv.innerHTML = `<p>${msg}, <b>${env.Name}</b>!</p>`;
};
The augmented code that Smartdown generates around Typescript to transpile it to Javascript has been recently (v1.0.24) improved so that syntax errors detected during transpilation are reported via the Smartdown per-playable console, which is a new feature (see Javascript).
Let's give this feature a try by creating a TypeScript playable that is syntactically incorrect because it lacks a closing single quote on a string declaration. This playable is NOT autoplay, so you will need to click the Play
button to see stuff happen:
const msg: string = 'I better not forget the closing quote...;
this.div.innerHTML = `<h1>${msg}</h1`;
Here's an example which is syntactically correct, but should fail Typescript's typechecking. Because Smartdown's usage of the Typescript transpiler does not currently use the typechecker, this playable will be transpiled successfully into Javascript.
const n: number = 'This is definitely NOT a number';
this.div.innerHTML = `<h1>n: ${n}</h1`;
Before Smartdown had a proper typescript
playable language type, I prototyped the capability by using an ordinary Javascript playable and then using smartdown.import
to dynamically load the TypeScript compiler via the jsDelivr CDN, followed by transpiling some example source and then generating a Function
and invoking it with the current playable's context. For the most part, the following playable is patterned after the augmented code generated by Smartdown when processing a Typescript playable.
String to uppercase Uppercased String
//smartdown.import=https://cdn.jsdelivr.net/npm/typescript/lib/typescript.min.js
const source =
`
this.dependOn = ['String'];
this.depend = function() {
const upper: string = env.String.toUpperCase();
smartdown.setVariable('StringUpper', upper);
}
`;
// https://github.com/Microsoft/TypeScript/wiki/Using-the-Compiler-API#transpiling-a-single-file
// compilerOptions?: CompilerOptions;
// fileName?: string;
// reportDiagnostics?: boolean;
// moduleName?: string;
// renamedDependencies?: Map<string>;
let result = ts.transpileModule(source, {
compilerOptions: {
module: ts.ModuleKind.CommonJS,
target: 'es6',
allowJs: true,
checkJs: true,
},
reportDiagnostics: true,
});
if (result.diagnostics.length > 0) {
console.log('result.diagnostics');
console.log(result.diagnostics);
}
smartdown.runFunction(
result.outputText,
this,
[...arguments],
playable.language,
this.div);
As of SD v1.0.25, Javascript playable sources are wrapped with an async
function wrapper so that await
can be used within the source of the playable. This is exercised in a Javascript example, but let's make sure it works with TypeScript.
console.log('Hello from the typescript playable');
const response: any = await fetch('https://unpkg.com/smartdown/package.json');
const myJson: any = await response.json();
smartdown.setVariable('Package', myJson);
package.json
- https://stackoverflow.com/questions/53733138/how-do-i-type-check-a-snippet-of-typescript-code-in-memory
- https://github.com/microsoft/TypeScript/wiki/Using-the-Compiler-API
Preliminary capability that allows a transpiled Typescript playable to execute as an ES6 Module by using the /module
qualifier. As with ordinary Javascript ES6 Playables, you must implement a start()
function which will receive a reference to the playable via playable
and to the Smartdown variables via env
. The signature for start()
is still in flux, and we may implement a corresponding stop()
hook.
Possibly this should be moved to the ES6 card, but it is here for now.
What is your name?
import * as Lib from './gallery/ExtensionsES6Module.js';
export default function start(playable, env) {
const log = this.log;
log('start', this, playable, env);
this.div.innerHTML = `<h1>Waiting for dependency</h1>`;
this.dependOn.NameA = () => {
smartdown.setVariable('NameB', env.NameA.toUpperCase());
this.div.innerHTML = `<h1>Hello from an ES6 Module A. ${env.NameA}</h1>`;
};
const nums = [12, 23, 34, 45];
log('sum', Lib.sum(...nums));
log('mult', Lib.mult(...nums));
Lib.note.note = 'ModuleA was here';
}
Back to Home