@hpcc-js/observablehq-compiler
Version:
hpcc-js - ObservableHQ Compiler (unoffical)
84 lines (67 loc) • 2.97 kB
text/typescript
import { ohq } from "./observable-shim.ts";
import { ParsedImportCell, ParsedVariable } from "./cst.ts";
export class Writer {
protected _files: ohq.File[] = [];
protected _imports: string[] = [];
protected _functions: string[] = [];
protected _defines: string[] = [];
protected _defineUid = 0;
protected _functionUid = 0;
constructor() {
}
toString() {
return `\
${this._imports.join("\n")}
${this._functions.join("\n").split("\n) {").join("){")}
export default function define(runtime, observer) {
const main = runtime.module();
function toString() { return this.url; }
const fileAttachments = new Map([
${this._files.map(f => `["${f.name}", { url: new URL("${f.url}"), mimeType: ${JSON.stringify(f.mime_type)}, toString }]`).join(",\n ")}
]);
main.builtin("FileAttachment", runtime.fileAttachments(name => fileAttachments.get(name)));
${this._defines.join("\n ")}
return main;
}\n`;
}
files(files: ohq.File[]) {
this._files = [...this._files, ...files];
}
import(url: string) {
this._imports.push(`import define${++this._defineUid} from "${url}"; `);
}
importDefine(imp: Partial<ParsedImportCell>) {
const impInjections = imp.injections ?? [];
const injections = impInjections.map(inj => {
return inj.name === inj.alias ?
`"${inj.name}"` :
`{name: "${inj.name}", alias: "${inj.alias}"}`;
});
const derive = impInjections.length ? `.derive([${injections.join(", ")}], main)` : "";
this._defines.push(`const child${this._defineUid} = runtime.module(define${this._defineUid})${derive};`);
const impSpecifiers = imp.specifiers ?? [];
impSpecifiers.forEach(s => {
this._defines.push(`main.import("${s.name}"${s.alias && s.alias !== s.name ? `, "${s.alias}"` : ""}, child${this._defineUid}); `);
});
}
function(variable: Partial<ParsedVariable>) {
let id = variable.id ?? `${++this._functionUid}`;
const idParts = id.split(" ");
id = `_${idParts[idParts.length - 1]}`;
this._functions.push(`${variable.func?.toString()?.replace("anonymous", `${id}`)}`);
return id;
}
define(variable: Partial<ParsedVariable>, observable = true, inlineFunc = false, funcId?: string) {
funcId = funcId ?? variable.id;
const observe = observable ? `.variable(observer(${variable.id ? JSON.stringify(variable.id) : ""}))` : "";
const id = variable.id ? `${JSON.stringify(variable.id)}, ` : "";
const variableInputs = variable.inputs ?? [];
const inputs = variableInputs.length ? `[${variableInputs.map(i => JSON.stringify(i)).join(", ")}], ` : "";
const func = inlineFunc ?
variable.func?.toString() :
funcId;
this._defines.push(`main${observe}.define(${id}${inputs}${func});`);
}
error(msg: string) {
}
}