@hpcc-js/observablehq-compiler 1.1.4 → 1.2.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/bin/ojscc.mjs CHANGED
@@ -10,7 +10,7 @@ if (!globalThis.fetch) {
10
10
  globalThis.Response = Response;
11
11
  }
12
12
  import { promises as fs } from "fs";
13
- import { compile, download, Writer } from "../dist/index.js";
13
+ import { compile, download } from "../dist/index.js";
14
14
  import yargsMode from "yargs/yargs";
15
15
 
16
16
  async function doDownload(url, filePath) {
@@ -25,12 +25,11 @@ async function doDownload(url, filePath) {
25
25
  async function doCompile(url, filePath) {
26
26
  const nb = await download(url);
27
27
  const define = await compile(nb, process.cwd());
28
- const w = new Writer();
29
- define.write(w);
28
+ const js = define.toString();
30
29
  if (filePath) {
31
- fs.writeFile(filePath, w.toString());
30
+ fs.writeFile(filePath, js);
32
31
  } else {
33
- console.info(w.toString());
32
+ console.info(js);
34
33
  }
35
34
  }
36
35
 
package/dist/index.esm.js CHANGED
@@ -1,5 +1,3 @@
1
- import { join, endsWith } from '@hpcc-js/util';
2
-
3
1
  // This file was generated. Do not modify manually!
4
2
  var astralIdentifierCodes = [509, 0, 227, 0, 150, 4, 294, 9, 1368, 2, 2, 1, 6, 3, 41, 2, 5, 0, 166, 1, 574, 3, 9, 9, 370, 1, 154, 10, 50, 3, 123, 2, 54, 14, 32, 10, 3, 1, 11, 3, 46, 10, 8, 0, 46, 9, 7, 2, 37, 13, 2, 9, 6, 1, 45, 0, 13, 2, 49, 13, 9, 3, 2, 11, 83, 11, 7, 0, 161, 11, 6, 9, 7, 3, 56, 1, 2, 6, 3, 1, 3, 2, 10, 0, 11, 1, 3, 6, 4, 4, 193, 17, 10, 9, 5, 0, 82, 19, 13, 9, 214, 6, 3, 8, 28, 1, 83, 16, 16, 9, 82, 12, 9, 9, 84, 14, 5, 9, 243, 14, 166, 9, 71, 5, 2, 1, 3, 3, 2, 0, 2, 1, 13, 9, 120, 6, 3, 6, 4, 0, 29, 9, 41, 6, 2, 3, 9, 0, 10, 10, 47, 15, 406, 7, 2, 7, 17, 9, 57, 21, 2, 13, 123, 5, 4, 0, 2, 1, 2, 6, 2, 0, 9, 9, 49, 4, 2, 1, 2, 4, 9, 9, 330, 3, 19306, 9, 87, 9, 39, 4, 60, 6, 26, 9, 1014, 0, 2, 54, 8, 3, 82, 0, 12, 1, 19628, 1, 4706, 45, 3, 22, 543, 4, 4, 5, 9, 7, 3, 6, 31, 3, 149, 2, 1418, 49, 513, 54, 5, 49, 9, 0, 15, 0, 23, 4, 2, 14, 1361, 6, 2, 16, 3, 6, 2, 1, 2, 4, 262, 6, 10, 9, 357, 0, 62, 13, 1495, 6, 110, 6, 6, 9, 4759, 9, 787719, 239];
5
3
 
@@ -6618,8 +6616,13 @@ class ModuleParser extends CellParser {
6618
6616
  }
6619
6617
  }
6620
6618
  function splitModule(input) {
6621
- // @ts-ignore
6622
- return ModuleParser.parse(input, { ecmaVersion: "latest" }).cells.map(cell => input.substring(cell.start, cell.end));
6619
+ return ModuleParser
6620
+ .parse(input, { ecmaVersion: "latest" })
6621
+ .cells.map((cell) => ({
6622
+ text: input.substring(cell.start, cell.end),
6623
+ start: cell.start,
6624
+ end: cell.end
6625
+ }));
6623
6626
  }
6624
6627
  function parseCell$2(input) {
6625
6628
  return parseCell$1(input);
@@ -6652,6 +6655,18 @@ function createFunction(refs, async = false, generator = false, blockStatement =
6652
6655
  body.substring(1, body.length - 1).trim() :
6653
6656
  `return (\n${body}\n);`);
6654
6657
  }
6658
+ function join(baseURL, relativeURL) {
6659
+ return relativeURL
6660
+ ? baseURL.replace(/\/+$/, "") + "/" + relativeURL.replace(/^\/+/, "")
6661
+ : baseURL;
6662
+ }
6663
+ const isRelativePath = (path) => path[0] === ".";
6664
+ const fixRelativeUrl = (path, basePath) => {
6665
+ if (isRelativePath(path)) {
6666
+ return join(basePath, path);
6667
+ }
6668
+ return path;
6669
+ };
6655
6670
  // Hide "import" from bundlers as they have a habit of replacing "import" with "require"
6656
6671
  async function obfuscatedImport(url) {
6657
6672
  return new FuncTypes.asyncFunctionType("url", "return import(url)")(url);
@@ -6677,7 +6692,7 @@ function createParsedOJS(ojs, offset, inlineMD) {
6677
6692
  error
6678
6693
  };
6679
6694
  }
6680
- function parseOmd(_) {
6695
+ function splitOmd(_) {
6681
6696
  const retVal = [];
6682
6697
  // Load Markdown ---
6683
6698
  const re = /(```(?:\s|\S)[\s\S]*?```)/g;
@@ -6712,20 +6727,24 @@ function ojs2notebook(ojs) {
6712
6727
  return {
6713
6728
  id: idx,
6714
6729
  mode: "js",
6715
- value: cell
6730
+ value: cell.text,
6731
+ start: cell.start,
6732
+ end: cell.end
6716
6733
  };
6717
6734
  })
6718
6735
  };
6719
6736
  }
6720
6737
  function omd2notebook(omd) {
6721
- const cells = parseOmd(omd);
6738
+ const cells = splitOmd(omd);
6722
6739
  return {
6723
6740
  files: [],
6724
6741
  nodes: cells.map((cell, idx) => {
6725
6742
  return {
6726
6743
  id: idx,
6727
6744
  mode: cell.inlineMD ? "md" : "js",
6728
- value: cell.ojs
6745
+ value: cell.ojs,
6746
+ start: cell.offset,
6747
+ end: cell.offset + cell.ojs.length
6729
6748
  };
6730
6749
  })
6731
6750
  };
@@ -6790,7 +6809,7 @@ function calcRefs(cellAst, cellStr) {
6790
6809
  }
6791
6810
  return retVal;
6792
6811
  }
6793
- function parseImportExpression(cellAst) {
6812
+ function parseImportDeclaration(cellAst) {
6794
6813
  var _a, _b, _c, _d;
6795
6814
  return {
6796
6815
  type: "import",
@@ -6867,14 +6886,17 @@ function parseVariableExpression(cellStr, cellAst, refs, bodyStr) {
6867
6886
  func: createFunction(refs, cellAst.async, cellAst.generator, cellAst.body.type === "BlockStatement", bodyStr)
6868
6887
  };
6869
6888
  }
6870
- function parseCell(cellStr) {
6889
+ function parseCell(cellStr, baseUrl) {
6871
6890
  var _a, _b;
6872
6891
  const cellAst = parseCell$2(cellStr);
6873
- if (((_a = (cellAst.body)) === null || _a === void 0 ? void 0 : _a.type) == "ImportDeclaration") {
6874
- return parseImportExpression(cellAst);
6892
+ let bodyStr = cellAst.body && cellStr.substring(cellAst.body.start, cellAst.body.end);
6893
+ switch ((_a = (cellAst.body)) === null || _a === void 0 ? void 0 : _a.type) {
6894
+ case "ImportDeclaration":
6895
+ return parseImportDeclaration(cellAst);
6896
+ case "ImportExpression":
6897
+ bodyStr = `import("${fixRelativeUrl(cellAst.body.source.value, baseUrl)}")`;
6875
6898
  }
6876
6899
  const refs = calcRefs(cellAst, cellStr);
6877
- const bodyStr = cellAst.body && cellStr.substring(cellAst.body.start, cellAst.body.end);
6878
6900
  switch ((_b = cellAst.id) === null || _b === void 0 ? void 0 : _b.type) {
6879
6901
  case "ViewExpression":
6880
6902
  return parseViewExpression(cellStr, cellAst, refs, bodyStr);
@@ -6955,29 +6977,27 @@ export default function define(runtime, observer) {
6955
6977
  }
6956
6978
  }
6957
6979
 
6958
- const isRelativePath = (path) => path[0] === ".";
6959
- const fullUrl = (path, basePath) => isRelativePath(path) ? join(basePath, path) : path;
6960
6980
  async function importFile(relativePath, baseUrl) {
6961
- const path = fullUrl(relativePath, baseUrl);
6981
+ const path = fixRelativeUrl(relativePath, baseUrl);
6962
6982
  const content = await fetchEx(path).then(r => r.text());
6963
6983
  let notebook;
6964
- if (endsWith(relativePath, ".ojsnb")) {
6984
+ if (relativePath.endsWith(".ojsnb")) {
6965
6985
  notebook = JSON.parse(content);
6966
6986
  }
6967
- else if (endsWith(relativePath, ".ojs")) {
6987
+ else if (relativePath.endsWith(".ojs")) {
6968
6988
  notebook = ojs2notebook(content);
6969
6989
  }
6970
- else if (endsWith(relativePath, ".omd")) {
6990
+ else if (relativePath.endsWith(".omd")) {
6971
6991
  notebook = omd2notebook(content);
6972
6992
  }
6973
- const retVal = compile(notebook, baseUrl);
6974
- retVal.dispose = () => { };
6993
+ const retVal = compile(notebook, { baseUrl });
6994
+ retVal.delete = () => { };
6975
6995
  retVal.write = (w) => {
6976
6996
  w.import(path);
6977
6997
  };
6978
6998
  return retVal;
6979
6999
  }
6980
- // @ts-ignore - use precompiled notebook from observable
7000
+ // Import precompiled notebook from observable ---
6981
7001
  async function importCompiledNotebook(partial) {
6982
7002
  const url = `https://api.observablehq.com/${partial[0] === "@" ? partial : `d/${partial}`}.js?v=3`;
6983
7003
  let impMod = {
@@ -6991,17 +7011,72 @@ async function importCompiledNotebook(partial) {
6991
7011
  catch (e) {
6992
7012
  }
6993
7013
  const retVal = impMod.default;
6994
- retVal.dispose = () => { };
7014
+ retVal.delete = () => { };
6995
7015
  retVal.write = (w) => {
6996
7016
  w.import(url);
6997
7017
  };
6998
7018
  return retVal;
6999
7019
  }
7000
- function createVariable(inspect, name, inputs, definition, inline = false) {
7020
+ // Recursive notebook parsing and compiling
7021
+ async function importNotebook(partial) {
7022
+ const url = `https://api.observablehq.com/document/${partial}`;
7023
+ const notebook = fetchEx(url)
7024
+ .then(r => {
7025
+ return r.json();
7026
+ }).catch(e => {
7027
+ console.error(url);
7028
+ console.error(e);
7029
+ });
7030
+ const retVal = compile(await notebook);
7031
+ retVal.delete = () => { };
7032
+ retVal.write = (w) => {
7033
+ w.import(url);
7034
+ };
7035
+ return retVal;
7036
+ }
7037
+ async function createModule(node, parsed, text, { baseUrl, importMode }) {
7038
+ const otherModule = isRelativePath(parsed.src) ?
7039
+ await importFile(parsed.src, baseUrl) :
7040
+ importMode === "recursive" ?
7041
+ await importNotebook(parsed.src) :
7042
+ await importCompiledNotebook(parsed.src);
7043
+ const importVariables = [];
7044
+ const variables = [];
7045
+ parsed.specifiers.forEach(spec => {
7046
+ const viewof = spec.view ? "viewof " : "";
7047
+ importVariables.push(createImportVariable(viewof + spec.name, viewof + spec.alias));
7048
+ if (spec.view) {
7049
+ importVariables.push(createImportVariable(spec.name, spec.alias));
7050
+ }
7051
+ });
7052
+ const retVal = (runtime, main, inspector) => {
7053
+ let mod = runtime.module(otherModule);
7054
+ if (parsed.injections.length) {
7055
+ mod = mod.derive(parsed.injections, main);
7056
+ }
7057
+ variables.forEach(v => v(main, inspector));
7058
+ importVariables.forEach(v => v(main, mod));
7059
+ return mod;
7060
+ };
7061
+ retVal.importVariables = importVariables;
7062
+ retVal.variables = variables;
7063
+ retVal.delete = () => {
7064
+ importVariables.forEach(v => v.delete());
7065
+ variables.forEach(v => v.delete());
7066
+ otherModule.delete();
7067
+ };
7068
+ retVal.write = (w) => {
7069
+ otherModule.write(w);
7070
+ w.importDefine(parsed);
7071
+ };
7072
+ return retVal;
7073
+ }
7074
+ // Variable ---
7075
+ function createVariable(node, inspect, name, inputs, definition, inline = false) {
7001
7076
  let i;
7002
7077
  let v;
7003
7078
  const retVal = (module, inspector) => {
7004
- i = inspect ? inspector(name) : undefined;
7079
+ i = inspect ? inspector(name, node.id) : undefined;
7005
7080
  v = module.variable(i);
7006
7081
  if (arguments.length > 1) {
7007
7082
  try {
@@ -7011,9 +7086,22 @@ function createVariable(inspect, name, inputs, definition, inline = false) {
7011
7086
  console.error(e === null || e === void 0 ? void 0 : e.message);
7012
7087
  }
7013
7088
  }
7089
+ if (node.pinned) {
7090
+ v = module.variable(inspector(name, node.id));
7091
+ try {
7092
+ v.define(undefined, ["md"], md => {
7093
+ return md `\`\`\`js
7094
+ ${node.value}
7095
+ \`\`\``;
7096
+ });
7097
+ }
7098
+ catch (e) {
7099
+ console.error(e === null || e === void 0 ? void 0 : e.message);
7100
+ }
7101
+ }
7014
7102
  return v;
7015
7103
  };
7016
- retVal.dispose = () => {
7104
+ retVal.delete = () => {
7017
7105
  var _a;
7018
7106
  try {
7019
7107
  (_a = i === null || i === void 0 ? void 0 : i._node) === null || _a === void 0 ? void 0 : _a.remove();
@@ -7045,91 +7133,52 @@ function createImportVariable(name, alias) {
7045
7133
  v = main.variable();
7046
7134
  v.import(name, alias, otherModule);
7047
7135
  };
7048
- retVal.dispose = () => {
7136
+ retVal.delete = () => {
7049
7137
  v === null || v === void 0 ? void 0 : v.delete();
7050
7138
  };
7051
7139
  return retVal;
7052
7140
  }
7053
- async function createModule(parsed, text, baseUrl) {
7054
- const otherModule = isRelativePath(parsed.src) ?
7055
- await importFile(parsed.src, baseUrl) :
7056
- await importCompiledNotebook(parsed.src);
7057
- const importVariables = [];
7058
- const variables = [];
7059
- parsed.specifiers.forEach(spec => {
7060
- const viewof = spec.view ? "viewof " : "";
7061
- importVariables.push(createImportVariable(viewof + spec.name, viewof + spec.alias));
7062
- if (spec.view) {
7063
- importVariables.push(createImportVariable(spec.name, spec.alias));
7064
- }
7065
- });
7066
- variables.push(createVariable(true, undefined, ["md"], md => {
7067
- return md `\`\`\`JavaScript
7068
- ${text}
7069
- \`\`\``;
7070
- }));
7071
- const retVal = (runtime, main, inspector) => {
7072
- let mod = runtime.module(otherModule);
7073
- if (parsed.injections.length) {
7074
- mod = mod.derive(parsed.injections, main);
7075
- }
7076
- variables.forEach(v => v(main, inspector));
7077
- importVariables.forEach(v => v(main, mod));
7078
- return mod;
7079
- };
7080
- retVal.importVariables = importVariables;
7081
- retVal.variables = variables;
7082
- retVal.dispose = () => {
7083
- importVariables.forEach(v => v.dispose());
7084
- variables.forEach(v => v.dispose());
7085
- otherModule.dispose();
7086
- };
7087
- retVal.write = (w) => {
7088
- otherModule.write(w);
7089
- w.importDefine(parsed);
7090
- };
7091
- return retVal;
7092
- }
7093
- async function createCell(node, baseUrl) {
7141
+ // Cell ---
7142
+ async function createCell(node, options) {
7094
7143
  const modules = [];
7095
7144
  const variables = [];
7096
7145
  try {
7097
7146
  const text = node.mode && node.mode !== "js" ? `${node.mode}\`${encodeBacktick(node.value)}\`` : node.value;
7098
7147
  const parsedModule = splitModule(text);
7099
- for (const text of parsedModule) {
7100
- const parsed = parseCell(text);
7148
+ for (const cell of parsedModule) {
7149
+ const parsed = parseCell(cell.text, options.baseUrl);
7101
7150
  switch (parsed.type) {
7102
7151
  case "import":
7103
- modules.push(await createModule(parsed, text, baseUrl));
7152
+ modules.push(await createModule(node, parsed, cell.text, options));
7104
7153
  break;
7105
7154
  case "viewof":
7106
- variables.push(createVariable(true, parsed.variable.id, parsed.variable.inputs, parsed.variable.func));
7107
- variables.push(createVariable(false, parsed.variableValue.id, parsed.variableValue.inputs, parsed.variableValue.func, true));
7155
+ variables.push(createVariable(node, true, parsed.variable.id, parsed.variable.inputs, parsed.variable.func));
7156
+ variables.push(createVariable(node, false, parsed.variableValue.id, parsed.variableValue.inputs, parsed.variableValue.func, true));
7108
7157
  break;
7109
7158
  case "mutable":
7110
- variables.push(createVariable(false, parsed.initial.id, parsed.initial.inputs, parsed.initial.func));
7111
- variables.push(createVariable(false, parsed.variable.id, parsed.variable.inputs, parsed.variable.func));
7112
- variables.push(createVariable(true, parsed.variableValue.id, parsed.variableValue.inputs, parsed.variableValue.func, true));
7159
+ variables.push(createVariable(node, false, parsed.initial.id, parsed.initial.inputs, parsed.initial.func));
7160
+ variables.push(createVariable(node, false, parsed.variable.id, parsed.variable.inputs, parsed.variable.func));
7161
+ variables.push(createVariable(node, true, parsed.variableValue.id, parsed.variableValue.inputs, parsed.variableValue.func, true));
7113
7162
  break;
7114
7163
  case "variable":
7115
- variables.push(createVariable(true, parsed.id, parsed.inputs, parsed.func));
7164
+ variables.push(createVariable(node, true, parsed.id, parsed.inputs, parsed.func));
7116
7165
  break;
7117
7166
  }
7118
7167
  }
7119
7168
  }
7120
7169
  catch (e) {
7121
- variables.push(createVariable(true, undefined, [], e.message));
7170
+ variables.push(createVariable(node, true, undefined, [], e.message));
7122
7171
  }
7123
7172
  const retVal = (runtime, main, inspector) => {
7124
7173
  modules.forEach(imp => imp(runtime, main, inspector));
7125
7174
  variables.forEach(v => v(main, inspector));
7126
7175
  };
7127
- retVal.id = "" + node.id;
7176
+ retVal.id = node.id;
7128
7177
  retVal.modules = modules;
7129
7178
  retVal.variables = variables;
7130
- retVal.dispose = () => {
7131
- variables.forEach(v => v.dispose());
7132
- modules.forEach(mod => mod.dispose());
7179
+ retVal.delete = () => {
7180
+ variables.forEach(v => v.delete());
7181
+ modules.forEach(mod => mod.delete());
7133
7182
  };
7134
7183
  retVal.write = (w) => {
7135
7184
  modules.forEach(imp => imp.write(w));
@@ -7137,20 +7186,20 @@ async function createCell(node, baseUrl) {
7137
7186
  };
7138
7187
  return retVal;
7139
7188
  }
7140
- function createFile(file, baseUrl) {
7189
+ // File ---
7190
+ function createFile(file, options) {
7141
7191
  function toString() { return globalThis.url; }
7142
- return [file.name, { url: new URL(fullUrl(file.url, baseUrl)), mimeType: file.mime_type, toString }];
7192
+ return [file.name, { url: new URL(fixRelativeUrl(file.url, options.baseUrl)), mimeType: file.mime_type, toString }];
7143
7193
  }
7144
- async function compile(notebook, baseUrl = ".") {
7145
- const files = notebook.files.map(f => createFile(f, baseUrl));
7194
+ function notebook(_files = [], _cells = [], { baseUrl = ".", importMode = "precompiled" } = {}) {
7195
+ const files = _files.map(f => createFile(f, { baseUrl, importMode }));
7146
7196
  const fileAttachments = new Map(files);
7147
- const _cells = await Promise.all(notebook.nodes.map(n => createCell(n, baseUrl)));
7148
7197
  const cells = new Map(_cells.map(c => [c.id, c]));
7149
7198
  const retVal = (runtime, inspector) => {
7150
7199
  const main = runtime.module();
7151
7200
  main.builtin("FileAttachment", runtime.fileAttachments(name => {
7152
7201
  var _a;
7153
- return (_a = fileAttachments.get(name)) !== null && _a !== void 0 ? _a : { url: new URL(fullUrl(name, baseUrl)), mimeType: null };
7202
+ return (_a = fileAttachments.get(name)) !== null && _a !== void 0 ? _a : { url: new URL(fixRelativeUrl(name, baseUrl)), mimeType: null };
7154
7203
  }));
7155
7204
  main.builtin("fetchEx", fetchEx);
7156
7205
  cells.forEach(cell => {
@@ -7160,25 +7209,29 @@ async function compile(notebook, baseUrl = ".") {
7160
7209
  };
7161
7210
  retVal.fileAttachments = fileAttachments;
7162
7211
  retVal.cells = cells;
7163
- retVal.appendCell = async (n, baseUrl) => {
7164
- const cell = await createCell(n, baseUrl);
7165
- retVal.disposeCell(cell.id);
7212
+ retVal.set = async (n) => {
7213
+ const cell = await createCell(n, { baseUrl, importMode });
7214
+ retVal.delete(cell.id);
7166
7215
  cells.set(cell.id, cell);
7167
7216
  return cell;
7168
7217
  };
7169
- retVal.disposeCell = async (id) => {
7218
+ retVal.get = (id) => {
7219
+ return cells.get(id);
7220
+ };
7221
+ retVal.delete = (id) => {
7170
7222
  const cell = cells.get(id);
7171
7223
  if (cell) {
7172
- cells.delete(id);
7173
- cell.dispose();
7224
+ cell.delete();
7225
+ return cells.delete(id);
7174
7226
  }
7227
+ return false;
7175
7228
  };
7176
- retVal.dispose = () => {
7177
- cells.forEach(cell => cell.dispose());
7229
+ retVal.clear = () => {
7230
+ cells.forEach(cell => cell.delete());
7178
7231
  cells.clear();
7179
7232
  };
7180
7233
  retVal.write = (w) => {
7181
- w.files(notebook.files);
7234
+ w.files(_files);
7182
7235
  cells.forEach(cell => cell.write(w));
7183
7236
  };
7184
7237
  retVal.toString = (w = new Writer()) => {
@@ -7187,6 +7240,11 @@ async function compile(notebook, baseUrl = ".") {
7187
7240
  };
7188
7241
  return retVal;
7189
7242
  }
7243
+ async function compile(notebookOrOjs, { baseUrl = ".", importMode = "precompiled" } = {}) {
7244
+ const ojsNotebook = typeof notebookOrOjs === "string" ? ojs2notebook(notebookOrOjs) : notebookOrOjs;
7245
+ const _cells = await Promise.all(ojsNotebook.nodes.map(n => createCell(n, { baseUrl, importMode })));
7246
+ return notebook(ojsNotebook.files, _cells, { baseUrl, importMode });
7247
+ }
7190
7248
 
7191
- export { compile, download, ojs2notebook, omd2notebook, parseOmd };
7249
+ export { compile, download, notebook, ojs2notebook, omd2notebook };
7192
7250
  //# sourceMappingURL=index.esm.js.map