@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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hpcc-js/observablehq-compiler",
3
- "version": "1.1.4",
3
+ "version": "1.2.1",
4
4
  "description": "hpcc-js - ObservableHQ Compiler (unoffical)",
5
5
  "keywords": [
6
6
  "observablehq",
@@ -56,13 +56,12 @@
56
56
  "update": "npx --yes npm-check-updates -u -t minor"
57
57
  },
58
58
  "dependencies": {
59
- "@hpcc-js/observable-shim": "^2.3.1",
59
+ "@hpcc-js/observable-shim": "^2.4.0",
60
60
  "node-fetch": "3.2.10",
61
61
  "yargs": "17.5.1"
62
62
  },
63
63
  "devDependencies": {
64
64
  "@hpcc-js/bundle": "^2.11.3",
65
- "@hpcc-js/util": "^2.50.0",
66
65
  "@observablehq/runtime": "4.25.0",
67
66
  "tslib": "2.4.0"
68
67
  },
@@ -77,5 +76,5 @@
77
76
  "url": "https://github.com/hpcc-systems/Visualization/issues"
78
77
  },
79
78
  "homepage": "https://github.com/hpcc-systems/Visualization/tree/trunk/packages/observablehq-compiler",
80
- "gitHead": "113e49eefde98196062fbf4150b20e833c4c8c19"
79
+ "gitHead": "015f4b88a046e6fd114ba409eff0ce286d0c063d"
81
80
  }
@@ -1,3 +1,3 @@
1
1
  export const PKG_NAME = "@hpcc-js/observablehq-compiler";
2
- export const PKG_VERSION = "1.1.4";
3
- export const BUILD_VERSION = "2.104.8";
2
+ export const PKG_VERSION = "1.2.1";
3
+ export const BUILD_VERSION = "2.104.10";
@@ -0,0 +1,3 @@
1
+ export function f(a, b) {
2
+ return a * b;
3
+ }
@@ -59,7 +59,7 @@ describe("ojs", function () {
59
59
  });
60
60
  });
61
61
 
62
- it.only("simple", async function () {
62
+ it("simple", async function () {
63
63
  this.timeout(10000);
64
64
 
65
65
  const notebook = ojs2notebook(ojs);
@@ -99,7 +99,7 @@ describe("ojs", function () {
99
99
  await main.value("tenTimes");
100
100
 
101
101
  for (const cellID in define.cells) {
102
- define.disposeCell(cellID);
102
+ define.delete(cellID);
103
103
  break;
104
104
  }
105
105
  });
@@ -132,6 +132,28 @@ describe("ojs", function () {
132
132
 
133
133
  });
134
134
 
135
+ it("esm imports", async function () {
136
+ this.timeout(10000);
137
+
138
+ const define = await compile(`\
139
+ m1 = import("../src/__tests__/m1.mjs");
140
+ x = m1.f(5, 7);
141
+ `);
142
+
143
+ const library = new Library();
144
+ const runtime = new Runtime(library);
145
+ const main: ohq.Module = define(runtime, name => {
146
+ return {
147
+ pending() { },
148
+ fulfilled(value) { console.info("fulfilled", name, value); },
149
+ rejected(error) { console.error("rejected", name, error); },
150
+ };
151
+ });
152
+
153
+ expect(await main.value("x")).to.equal(35);
154
+
155
+ });
156
+
135
157
  it("Introduction to Imports", async function () {
136
158
 
137
159
  const define = await compile(imports as any);
package/src/compiler.ts CHANGED
@@ -1,43 +1,50 @@
1
1
  import { ohq, splitModule } from "@hpcc-js/observable-shim";
2
-
3
- import { endsWith, join } from "@hpcc-js/util";
4
2
  import { parseCell, ParsedImportCell } from "./cst";
5
3
  import { Writer } from "./writer";
6
- import { encodeBacktick, fetchEx, obfuscatedImport, ojs2notebook, omd2notebook } from "./util";
4
+ import { fixRelativeUrl, isRelativePath, encodeBacktick, fetchEx, obfuscatedImport, ojs2notebook, omd2notebook } from "./util";
5
+
6
+ // Inspector Factory ---
7
+ export type InspectorFactoryEx = (name: string | undefined, id: string | number) => Inspector;
8
+
9
+ export interface Inspector {
10
+ _node?: HTMLDivElement;
11
+ pending();
12
+ fulfilled(value);
13
+ rejected(error);
14
+ }
7
15
 
8
- const isRelativePath = (path: string) => path[0] === ".";
9
- const fullUrl = (path: string, basePath: string) => isRelativePath(path) ? join(basePath, path) : path;
16
+ // Module ---
10
17
 
11
18
  interface ImportDefine {
12
- (runtime: ohq.Runtime, inspector?: ohq.InspectorFactory): ohq.Module;
13
- dispose: () => void;
19
+ (runtime: ohq.Runtime, inspector?: InspectorFactoryEx): ohq.Module;
20
+ delete: () => void;
14
21
  write: (w: Writer) => void;
15
22
  }
16
23
 
17
24
  async function importFile(relativePath: string, baseUrl: string) {
18
- const path = fullUrl(relativePath, baseUrl);
25
+ const path = fixRelativeUrl(relativePath, baseUrl);
19
26
  const content = await fetchEx(path).then(r => r.text());
20
27
  let notebook: ohq.Notebook;
21
- if (endsWith(relativePath, ".ojsnb")) {
28
+ if (relativePath.endsWith(".ojsnb")) {
22
29
  notebook = JSON.parse(content);
23
- } else if (endsWith(relativePath, ".ojs")) {
30
+ } else if (relativePath.endsWith(".ojs")) {
24
31
  notebook = ojs2notebook(content);
25
- } else if (endsWith(relativePath, ".omd")) {
32
+ } else if (relativePath.endsWith(".omd")) {
26
33
  notebook = omd2notebook(content);
27
34
  }
28
- const retVal: ImportDefine = compile(notebook, baseUrl) as any;
29
- retVal.dispose = () => { };
35
+ const retVal: ImportDefine = compile(notebook, { baseUrl }) as any;
36
+ retVal.delete = () => { };
30
37
  retVal.write = (w: Writer) => {
31
38
  w.import(path);
32
39
  };
33
40
  return retVal;
34
41
  }
35
42
 
36
- // @ts-ignore - use precompiled notebook from observable
43
+ // Import precompiled notebook from observable ---
37
44
  async function importCompiledNotebook(partial: string) {
38
45
  const url = `https://api.observablehq.com/${partial[0] === "@" ? partial : `d/${partial}`}.js?v=3`;
39
46
  let impMod = {
40
- default: function (runtime: ohq.Runtime, inspector?: ohq.InspectorFactory): ohq.Module {
47
+ default: function (runtime: ohq.Runtime, inspector?: InspectorFactoryEx): ohq.Module {
41
48
  return undefined;
42
49
  } as any
43
50
  };
@@ -46,14 +53,14 @@ async function importCompiledNotebook(partial: string) {
46
53
  } catch (e) {
47
54
  }
48
55
  const retVal: ImportDefine = impMod.default;
49
- retVal.dispose = () => { };
56
+ retVal.delete = () => { };
50
57
  retVal.write = (w: Writer) => {
51
58
  w.import(url);
52
59
  };
53
60
  return retVal;
54
61
  }
55
62
 
56
- // @ts-ignore - recursive notebook parsing and compiling
63
+ // Recursive notebook parsing and compiling
57
64
  async function importNotebook(partial: string) {
58
65
  const url = `https://api.observablehq.com/document/${partial}`;
59
66
  const notebook = fetchEx(url)
@@ -64,20 +71,63 @@ async function importNotebook(partial: string) {
64
71
  console.error(e);
65
72
  });
66
73
  const retVal: ImportDefine = compile(await notebook) as any;
67
- retVal.dispose = () => { };
74
+ retVal.delete = () => { };
68
75
  retVal.write = (w: Writer) => {
69
76
  w.import(url);
70
77
  };
71
78
  return retVal;
72
79
  }
73
80
 
74
- function createVariable(inspect: boolean, name?: string, inputs?: string[], definition?: any, inline = false) {
81
+ async function createModule(node: ohq.Node, parsed: ParsedImportCell, text: string, { baseUrl, importMode }: CompileOptions) {
82
+ const otherModule = isRelativePath(parsed.src) ?
83
+ await importFile(parsed.src, baseUrl) :
84
+ importMode === "recursive" ?
85
+ await importNotebook(parsed.src) :
86
+ await importCompiledNotebook(parsed.src);
87
+
88
+ const importVariables: ImportVariableFunc[] = [];
89
+ const variables: VariableFunc[] = [];
90
+ parsed.specifiers.forEach(spec => {
91
+ const viewof = spec.view ? "viewof " : "";
92
+ importVariables.push(createImportVariable(viewof + spec.name, viewof + spec.alias));
93
+ if (spec.view) {
94
+ importVariables.push(createImportVariable(spec.name, spec.alias));
95
+ }
96
+ });
97
+
98
+ const retVal = (runtime: ohq.Runtime, main: ohq.Module, inspector?: InspectorFactoryEx) => {
99
+
100
+ let mod = runtime.module(otherModule);
101
+ if (parsed.injections.length) {
102
+ mod = mod.derive(parsed.injections, main);
103
+ }
104
+ variables.forEach(v => v(main, inspector));
105
+ importVariables.forEach(v => v(main, mod));
106
+ return mod;
107
+ };
108
+ retVal.importVariables = importVariables;
109
+ retVal.variables = variables;
110
+ retVal.delete = () => {
111
+ importVariables.forEach(v => v.delete());
112
+ variables.forEach(v => v.delete());
113
+ otherModule.delete();
114
+ };
115
+ retVal.write = (w: Writer) => {
116
+ otherModule.write(w);
117
+ w.importDefine(parsed);
118
+ };
119
+ return retVal;
120
+ }
121
+ type ModuleFunc = Awaited<ReturnType<typeof createModule>>;
122
+
123
+ // Variable ---
124
+ function createVariable(node: ohq.Node, inspect: boolean, name?: string, inputs?: string[], definition?: any, inline = false) {
75
125
 
76
126
  let i: ohq.Inspector;
77
127
  let v: ohq.Variable;
78
128
 
79
- const retVal = (module: ohq.Module, inspector?: ohq.InspectorFactory) => {
80
- i = inspect ? inspector(name) : undefined;
129
+ const retVal = (module: ohq.Module, inspector?: InspectorFactoryEx) => {
130
+ i = inspect ? inspector(name, node.id) : undefined;
81
131
  v = module.variable(i);
82
132
  if (arguments.length > 1) {
83
133
  try {
@@ -86,9 +136,21 @@ function createVariable(inspect: boolean, name?: string, inputs?: string[], defi
86
136
  console.error(e?.message);
87
137
  }
88
138
  }
139
+ if (node.pinned) {
140
+ v = module.variable(inspector(name, node.id));
141
+ try {
142
+ v.define(undefined, ["md"], md => {
143
+ return md`\`\`\`js
144
+ ${node.value}
145
+ \`\`\``;
146
+ });
147
+ } catch (e: any) {
148
+ console.error(e?.message);
149
+ }
150
+ }
89
151
  return v;
90
152
  };
91
- retVal.dispose = () => {
153
+ retVal.delete = () => {
92
154
  try {
93
155
  i?._node?.remove();
94
156
  } catch (e) {
@@ -121,98 +183,54 @@ function createImportVariable(name?: string, alias?: string) {
121
183
  v.import(name, alias, otherModule);
122
184
  };
123
185
 
124
- retVal.dispose = () => {
186
+ retVal.delete = () => {
125
187
  v?.delete();
126
188
  };
127
189
  return retVal;
128
190
  }
129
191
  type ImportVariableFunc = ReturnType<typeof createImportVariable>;
130
192
 
131
- async function createModule(parsed: ParsedImportCell, text: string, baseUrl: string) {
132
- const otherModule = isRelativePath(parsed.src) ?
133
- await importFile(parsed.src, baseUrl) :
134
- await importCompiledNotebook(parsed.src);
135
-
136
- const importVariables: ImportVariableFunc[] = [];
137
- const variables: VariableFunc[] = [];
138
- parsed.specifiers.forEach(spec => {
139
- const viewof = spec.view ? "viewof " : "";
140
- importVariables.push(createImportVariable(viewof + spec.name, viewof + spec.alias));
141
- if (spec.view) {
142
- importVariables.push(createImportVariable(spec.name, spec.alias));
143
- }
144
- });
145
- variables.push(createVariable(true, undefined, ["md"], md => {
146
- return md`\`\`\`JavaScript
147
- ${text}
148
- \`\`\``;
149
- }));
150
-
151
- const retVal = (runtime: ohq.Runtime, main: ohq.Module, inspector?: ohq.InspectorFactory) => {
152
-
153
- let mod = runtime.module(otherModule);
154
- if (parsed.injections.length) {
155
- mod = mod.derive(parsed.injections, main);
156
- }
157
- variables.forEach(v => v(main, inspector));
158
- importVariables.forEach(v => v(main, mod));
159
- return mod;
160
- };
161
- retVal.importVariables = importVariables;
162
- retVal.variables = variables;
163
- retVal.dispose = () => {
164
- importVariables.forEach(v => v.dispose());
165
- variables.forEach(v => v.dispose());
166
- otherModule.dispose();
167
- };
168
- retVal.write = (w: Writer) => {
169
- otherModule.write(w);
170
- w.importDefine(parsed);
171
- };
172
- return retVal;
173
- }
174
- type ModuleFunc = Awaited<ReturnType<typeof createModule>>;
175
-
176
- async function createCell(node: ohq.Node, baseUrl: string) {
193
+ // Cell ---
194
+ async function createCell(node: ohq.Node, options: CompileOptions) {
177
195
  const modules: ModuleFunc[] = [];
178
196
  const variables: VariableFunc[] = [];
179
197
  try {
180
198
  const text = node.mode && node.mode !== "js" ? `${node.mode}\`${encodeBacktick(node.value)}\`` : node.value;
181
199
  const parsedModule = splitModule(text);
182
- for (const text of parsedModule) {
183
- const parsed = parseCell(text);
200
+ for (const cell of parsedModule) {
201
+ const parsed = parseCell(cell.text, options.baseUrl);
184
202
  switch (parsed.type) {
185
203
  case "import":
186
- modules.push(await createModule(parsed, text, baseUrl));
204
+ modules.push(await createModule(node, parsed, cell.text, options));
187
205
  break;
188
206
  case "viewof":
189
- variables.push(createVariable(true, parsed.variable.id, parsed.variable.inputs, parsed.variable.func));
190
- variables.push(createVariable(false, parsed.variableValue.id, parsed.variableValue.inputs, parsed.variableValue.func, true));
207
+ variables.push(createVariable(node, true, parsed.variable.id, parsed.variable.inputs, parsed.variable.func));
208
+ variables.push(createVariable(node, false, parsed.variableValue.id, parsed.variableValue.inputs, parsed.variableValue.func, true));
191
209
  break;
192
210
  case "mutable":
193
- variables.push(createVariable(false, parsed.initial.id, parsed.initial.inputs, parsed.initial.func));
194
- variables.push(createVariable(false, parsed.variable.id, parsed.variable.inputs, parsed.variable.func));
195
- variables.push(createVariable(true, parsed.variableValue.id, parsed.variableValue.inputs, parsed.variableValue.func, true));
211
+ variables.push(createVariable(node, false, parsed.initial.id, parsed.initial.inputs, parsed.initial.func));
212
+ variables.push(createVariable(node, false, parsed.variable.id, parsed.variable.inputs, parsed.variable.func));
213
+ variables.push(createVariable(node, true, parsed.variableValue.id, parsed.variableValue.inputs, parsed.variableValue.func, true));
196
214
  break;
197
215
  case "variable":
198
- variables.push(createVariable(true, parsed.id, parsed.inputs, parsed.func));
216
+ variables.push(createVariable(node, true, parsed.id, parsed.inputs, parsed.func));
199
217
  break;
200
218
  }
201
219
  }
202
220
  } catch (e) {
203
- variables.push(createVariable(true, undefined, [], e.message));
221
+ variables.push(createVariable(node, true, undefined, [], e.message));
204
222
  }
205
223
 
206
- const retVal = (runtime: ohq.Runtime, main: ohq.Module, inspector?: ohq.InspectorFactory) => {
224
+ const retVal = (runtime: ohq.Runtime, main: ohq.Module, inspector?: InspectorFactoryEx) => {
207
225
  modules.forEach(imp => imp(runtime, main, inspector));
208
226
  variables.forEach(v => v(main, inspector));
209
227
  };
210
- retVal.id = "" + node.id;
228
+ retVal.id = node.id;
211
229
  retVal.modules = modules;
212
230
  retVal.variables = variables;
213
- retVal.dispose = () => {
214
- variables.forEach(v => v.dispose());
215
- modules.forEach(mod => mod.dispose());
231
+ retVal.delete = () => {
232
+ variables.forEach(v => v.delete());
233
+ modules.forEach(mod => mod.delete());
216
234
  };
217
235
  retVal.write = (w: Writer) => {
218
236
  modules.forEach(imp => imp.write(w));
@@ -222,23 +240,27 @@ async function createCell(node: ohq.Node, baseUrl: string) {
222
240
  }
223
241
  export type CellFunc = Awaited<ReturnType<typeof createCell>>;
224
242
 
225
- function createFile(file: ohq.File, baseUrl: string): [string, any] {
243
+ // File ---
244
+ function createFile(file: ohq.File, options: CompileOptions): [string, any] {
226
245
  function toString() { return globalThis.url; }
227
- return [file.name, { url: new URL(fullUrl(file.url, baseUrl)), mimeType: file.mime_type, toString }];
246
+ return [file.name, { url: new URL(fixRelativeUrl(file.url, options.baseUrl)), mimeType: file.mime_type, toString }];
228
247
  }
229
- export type FileFunc = ReturnType<typeof createFile>;
248
+ type FileFunc = ReturnType<typeof createFile>;
230
249
 
231
- export async function compile(notebook: ohq.Notebook, baseUrl: string = ".") {
232
-
233
- const files = notebook.files.map(f => createFile(f, baseUrl));
250
+ // Interpret ---
251
+ export interface CompileOptions {
252
+ baseUrl?: string;
253
+ importMode?: "recursive" | "precompiled";
254
+ }
255
+ export function notebook(_files: ohq.File[] = [], _cells: CellFunc[] = [], { baseUrl = ".", importMode = "precompiled" }: CompileOptions = {}) {
256
+ const files: FileFunc[] = _files.map(f => createFile(f, { baseUrl, importMode }));
234
257
  const fileAttachments = new Map<string, any>(files);
235
- const _cells: CellFunc[] = await Promise.all(notebook.nodes.map(n => createCell(n, baseUrl)));
236
- const cells = new Map<string, CellFunc>(_cells.map(c => [c.id, c]));
258
+ const cells = new Map<string | number, CellFunc>(_cells.map(c => [c.id, c]));
237
259
 
238
- const retVal = (runtime: ohq.Runtime, inspector?: ohq.InspectorFactory): ohq.Module => {
260
+ const retVal = (runtime: ohq.Runtime, inspector?: InspectorFactoryEx): ohq.Module => {
239
261
  const main = runtime.module();
240
262
  main.builtin("FileAttachment", runtime.fileAttachments(name => {
241
- return fileAttachments.get(name) ?? { url: new URL(fullUrl(name, baseUrl)), mimeType: null };
263
+ return fileAttachments.get(name) ?? { url: new URL(fixRelativeUrl(name, baseUrl)), mimeType: null };
242
264
  }));
243
265
  main.builtin("fetchEx", fetchEx);
244
266
 
@@ -249,25 +271,29 @@ export async function compile(notebook: ohq.Notebook, baseUrl: string = ".") {
249
271
  };
250
272
  retVal.fileAttachments = fileAttachments;
251
273
  retVal.cells = cells;
252
- retVal.appendCell = async (n: ohq.Node, baseUrl) => {
253
- const cell = await createCell(n, baseUrl);
254
- retVal.disposeCell(cell.id);
274
+ retVal.set = async (n: ohq.Node): Promise<CellFunc> => {
275
+ const cell = await createCell(n, { baseUrl, importMode });
276
+ retVal.delete(cell.id);
255
277
  cells.set(cell.id, cell);
256
278
  return cell;
257
279
  };
258
- retVal.disposeCell = async (id: string) => {
280
+ retVal.get = (id: string | number): CellFunc => {
281
+ return cells.get(id);
282
+ };
283
+ retVal.delete = (id: string | number): boolean => {
259
284
  const cell = cells.get(id);
260
285
  if (cell) {
261
- cells.delete(id);
262
- cell.dispose();
286
+ cell.delete();
287
+ return cells.delete(id);
263
288
  }
289
+ return false;
264
290
  };
265
- retVal.dispose = () => {
266
- cells.forEach(cell => cell.dispose());
291
+ retVal.clear = () => {
292
+ cells.forEach(cell => cell.delete());
267
293
  cells.clear();
268
294
  };
269
295
  retVal.write = (w: Writer) => {
270
- w.files(notebook.files);
296
+ w.files(_files);
271
297
  cells.forEach(cell => cell.write(w));
272
298
  };
273
299
  retVal.toString = (w = new Writer()) => {
@@ -276,4 +302,10 @@ export async function compile(notebook: ohq.Notebook, baseUrl: string = ".") {
276
302
  };
277
303
  return retVal;
278
304
  }
305
+
306
+ export async function compile(notebookOrOjs: ohq.Notebook | string, { baseUrl = ".", importMode = "precompiled" }: CompileOptions = {}) {
307
+ const ojsNotebook = typeof notebookOrOjs === "string" ? ojs2notebook(notebookOrOjs) : notebookOrOjs;
308
+ const _cells: CellFunc[] = await Promise.all(ojsNotebook.nodes.map(n => createCell(n, { baseUrl, importMode })));
309
+ return notebook(ojsNotebook.files, _cells, { baseUrl, importMode });
310
+ }
279
311
  export type compileFunc = Awaited<ReturnType<typeof compile>>;
package/src/cst.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { parseCell as ohqParseCell, ancestor, walk } from "@hpcc-js/observable-shim";
2
- import { createFunction, Refs } from "./util";
2
+ import { fixRelativeUrl, createFunction, Refs } from "./util";
3
3
 
4
4
  function calcRefs(cellAst, cellStr): Refs {
5
5
  if (cellAst.references === undefined) return { inputs: [], args: [], patches: [] };
@@ -51,7 +51,7 @@ export interface ParsedImportCell extends ParsedCell {
51
51
  injections: { name: string, alias: string }[];
52
52
  }
53
53
 
54
- function parseImportExpression(cellAst): ParsedImportCell {
54
+ function parseImportDeclaration(cellAst): ParsedImportCell {
55
55
  return {
56
56
  type: "import",
57
57
  src: cellAst.body.source.value,
@@ -153,14 +153,17 @@ function parseVariableExpression(cellStr: string, cellAst, refs: Refs, bodyStr?:
153
153
  };
154
154
  }
155
155
 
156
- export function parseCell(cellStr: string): ParsedImportCell | ParsedViewCell | ParsedMutableCell | ParsedVariableCell {
156
+ export function parseCell(cellStr: string, baseUrl: string): ParsedImportCell | ParsedViewCell | ParsedMutableCell | ParsedVariableCell {
157
157
  const cellAst = ohqParseCell(cellStr);
158
- if ((cellAst.body)?.type == "ImportDeclaration") {
159
- return parseImportExpression(cellAst);
158
+ let bodyStr = cellAst.body && cellStr.substring(cellAst.body.start, cellAst.body.end);
159
+ switch ((cellAst.body)?.type) {
160
+ case "ImportDeclaration":
161
+ return parseImportDeclaration(cellAst);
162
+ case "ImportExpression":
163
+ bodyStr = `import("${fixRelativeUrl(cellAst.body.source.value, baseUrl)}")`;
160
164
  }
161
165
  const refs = calcRefs(cellAst, cellStr);
162
166
 
163
- const bodyStr = cellAst.body && cellStr.substring(cellAst.body.start, cellAst.body.end);
164
167
  switch (cellAst.id?.type) {
165
168
  case "ViewExpression":
166
169
  return parseViewExpression(cellStr, cellAst, refs, bodyStr);
package/src/index.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  export type { ohq } from "@hpcc-js/observable-shim";
2
2
 
3
3
  export * from "./compiler";
4
- export { ojs2notebook, omd2notebook, parseOmd, download } from "./util";
4
+ export { ojs2notebook, omd2notebook, download } from "./util";
5
5
 
6
6
  import "../src/index.css";
package/src/util.ts CHANGED
@@ -41,6 +41,20 @@ export function createFunction(refs: Refs, async = false, generator = false, blo
41
41
  `return (\n${body}\n);`);
42
42
  }
43
43
 
44
+ function join(baseURL, relativeURL) {
45
+ return relativeURL
46
+ ? baseURL.replace(/\/+$/, "") + "/" + relativeURL.replace(/^\/+/, "")
47
+ : baseURL;
48
+ }
49
+
50
+ export const isRelativePath = (path: string) => path[0] === ".";
51
+ export const fixRelativeUrl = (path: string, basePath: string) => {
52
+ if (isRelativePath(path)) {
53
+ return join(basePath, path);
54
+ }
55
+ return path;
56
+ };
57
+
44
58
  // Hide "import" from bundlers as they have a habit of replacing "import" with "require"
45
59
  export async function obfuscatedImport(url: string) {
46
60
  return new FuncTypes.asyncFunctionType("url", "return import(url)")(url);
@@ -77,7 +91,7 @@ function createParsedOJS(ojs: string, offset: number, inlineMD: boolean): Parsed
77
91
  };
78
92
  }
79
93
 
80
- export function parseOmd(_: string): ParsedOJS[] {
94
+ function splitOmd(_: string): ParsedOJS[] {
81
95
  const retVal: ParsedOJS[] = [];
82
96
  // Load Markdown ---
83
97
  const re = /(```(?:\s|\S)[\s\S]*?```)/g;
@@ -119,21 +133,25 @@ export function ojs2notebook(ojs: string): ohq.Notebook {
119
133
  return {
120
134
  id: idx,
121
135
  mode: "js",
122
- value: cell
136
+ value: cell.text,
137
+ start: cell.start,
138
+ end: cell.end
123
139
  };
124
140
  })
125
141
  } as ohq.Notebook;
126
142
  }
127
143
 
128
144
  export function omd2notebook(omd: string): ohq.Notebook {
129
- const cells = parseOmd(omd);
145
+ const cells = splitOmd(omd);
130
146
  return {
131
147
  files: [],
132
148
  nodes: cells.map((cell, idx) => {
133
149
  return {
134
150
  id: idx,
135
151
  mode: cell.inlineMD ? "md" : "js",
136
- value: cell.ojs
152
+ value: cell.ojs,
153
+ start: cell.offset,
154
+ end: cell.offset + cell.ojs.length
137
155
  };
138
156
  })
139
157
  } as ohq.Notebook;
@@ -1,4 +1,4 @@
1
1
  export declare const PKG_NAME = "@hpcc-js/observablehq-compiler";
2
- export declare const PKG_VERSION = "1.1.4";
3
- export declare const BUILD_VERSION = "2.104.8";
2
+ export declare const PKG_VERSION = "1.2.1";
3
+ export declare const BUILD_VERSION = "2.104.10";
4
4
  //# sourceMappingURL=__package__.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"__package__.d.ts","sourceRoot":"","sources":["../src/__package__.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,QAAQ,mCAAmC,CAAC;AACzD,eAAO,MAAM,WAAW,UAAU,CAAC;AACnC,eAAO,MAAM,aAAa,YAAY,CAAC"}
1
+ {"version":3,"file":"__package__.d.ts","sourceRoot":"","sources":["../src/__package__.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,QAAQ,mCAAmC,CAAC;AACzD,eAAO,MAAM,WAAW,UAAU,CAAC;AACnC,eAAO,MAAM,aAAa,aAAa,CAAC"}