@hpcc-js/observablehq-compiler 1.1.0

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.
Files changed (46) hide show
  1. package/README.md +106 -0
  2. package/bin/ojscc.mjs +75 -0
  3. package/dist/index.css +1 -0
  4. package/dist/index.esm.css +1 -0
  5. package/dist/index.esm.js +7168 -0
  6. package/dist/index.esm.js.map +1 -0
  7. package/dist/index.js +7176 -0
  8. package/dist/index.js.map +1 -0
  9. package/package.json +80 -0
  10. package/src/__package__.ts +3 -0
  11. package/src/__tests__/File Attachments.ts +895 -0
  12. package/src/__tests__/Introduction to Imports.ts +749 -0
  13. package/src/__tests__/Observable TimeChart.ts +772 -0
  14. package/src/__tests__/index.ts +13 -0
  15. package/src/__tests__/node.ts +177 -0
  16. package/src/__tests__/tsconfig.json +21 -0
  17. package/src/compiler.md +234 -0
  18. package/src/compiler.ts +264 -0
  19. package/src/cst.ts +172 -0
  20. package/src/index.css +460 -0
  21. package/src/index.ts +7 -0
  22. package/src/util.md +113 -0
  23. package/src/util.ts +154 -0
  24. package/src/writer.ts +80 -0
  25. package/types/__package__.d.ts +4 -0
  26. package/types/__package__.d.ts.map +1 -0
  27. package/types/__tests__/File Attachments.d.ts +110 -0
  28. package/types/__tests__/File Attachments.d.ts.map +1 -0
  29. package/types/__tests__/Introduction to Imports.d.ts +120 -0
  30. package/types/__tests__/Introduction to Imports.d.ts.map +1 -0
  31. package/types/__tests__/Observable TimeChart.d.ts +111 -0
  32. package/types/__tests__/Observable TimeChart.d.ts.map +1 -0
  33. package/types/__tests__/index.d.ts +2 -0
  34. package/types/__tests__/index.d.ts.map +1 -0
  35. package/types/__tests__/node.d.ts +2 -0
  36. package/types/__tests__/node.d.ts.map +1 -0
  37. package/types/compiler.d.ts +88 -0
  38. package/types/compiler.d.ts.map +1 -0
  39. package/types/cst.d.ts +42 -0
  40. package/types/cst.d.ts.map +1 -0
  41. package/types/index.d.ts +6 -0
  42. package/types/index.d.ts.map +1 -0
  43. package/types/util.d.ts +26 -0
  44. package/types/util.d.ts.map +1 -0
  45. package/types/writer.d.ts +19 -0
  46. package/types/writer.d.ts.map +1 -0
package/src/cst.ts ADDED
@@ -0,0 +1,172 @@
1
+ import { parseCell as ohqParseCell, ancestor, walk } from "@hpcc-js/observable-shim";
2
+ import { createFunction, Refs } from "./util";
3
+
4
+ function calcRefs(cellAst, cellStr): Refs {
5
+ if (cellAst.references === undefined) return { inputs: [], args: [], patches: [] };
6
+
7
+ const dedup = {};
8
+ cellAst.references.forEach(r => dedup[cellStr.substring(r.start, r.end)] = true);
9
+ const retVal: Refs = {
10
+ inputs: Object.keys(dedup),
11
+ args: Object.keys(dedup).map(r => r.split(" ").join("_")),
12
+ patches: []
13
+ };
14
+ const pushPatch = (node, newText) => retVal.patches.push({ start: node.start - cellAst.body.start, end: node.end - cellAst.body.start, newText });
15
+ if (cellAst.body) {
16
+ ancestor(cellAst.body, {
17
+ Identifier(node) {
18
+ const value = cellStr.substring(node.start, node.end);
19
+ if (dedup[value]) {
20
+ }
21
+ },
22
+ MutableExpression(node) {
23
+ const value = cellStr.substring(node.start, node.end);
24
+ const newText = value.split(" ").join("_") + ".value";
25
+ pushPatch(node, newText);
26
+ },
27
+ ViewExpression(node) {
28
+ const value = cellStr.substring(node.start, node.end);
29
+ const newText = value.split(" ").join("_");
30
+ pushPatch(node, newText);
31
+ },
32
+ ThisExpression(node, ancestors: acorn.Node[]) {
33
+ const value = cellStr.substring(node.start, node.end);
34
+ if (value === "this" && !ancestors.find(n => n.type === "FunctionExpression")) {
35
+ pushPatch(node, "((this === globalThis || this === globalThis.window)? undefined : this?.valueOf())");
36
+ }
37
+ }
38
+ }, walk);
39
+ }
40
+ return retVal;
41
+ }
42
+
43
+ export interface ParsedCell {
44
+ type: "import" | "viewof" | "mutable" | "variable" | "identifier"
45
+ }
46
+
47
+ export interface ParsedImportCell extends ParsedCell {
48
+ type: "import"
49
+ src: string;
50
+ specifiers: { view: boolean, name: string, alias?: string }[];
51
+ injections: { name: string, alias: string }[];
52
+ }
53
+
54
+ function parseImportExpression(cellAst): ParsedImportCell {
55
+ return {
56
+ type: "import",
57
+ src: cellAst.body.source.value,
58
+ specifiers: cellAst.body.specifiers?.map(spec => {
59
+ return {
60
+ view: spec.view,
61
+ name: spec.imported.name,
62
+ alias: (spec.local?.name && spec.imported.name !== spec.local.name) ? spec.local.name : spec.imported.name
63
+ };
64
+ }) ?? [],
65
+ injections: cellAst.body.injections?.map(inj => {
66
+ return {
67
+ name: inj.imported.name,
68
+ alias: inj.local?.name ?? inj.imported.name
69
+ };
70
+ }) ?? [],
71
+ };
72
+ }
73
+
74
+ export interface ParsedVariable extends ParsedCell {
75
+ type: "variable"
76
+ id?: string,
77
+ inputs: string[],
78
+ func: any,
79
+ }
80
+
81
+ export interface ParsedViewCell extends ParsedCell {
82
+ type: "viewof",
83
+ variable: ParsedVariable;
84
+ variableValue: ParsedVariable;
85
+ }
86
+
87
+ function parseViewExpression(cellStr: string, cellAst, refs: Refs, bodyStr?: string): ParsedViewCell {
88
+ const id = cellAst.id && cellStr.substring(cellAst.id.start, cellAst.id.end);
89
+ return {
90
+ type: "viewof",
91
+ variable: {
92
+ type: "variable",
93
+ id,
94
+ inputs: refs.inputs,
95
+ func: createFunction(refs, cellAst.async, cellAst.generator, cellAst.body.type === "BlockStatement", bodyStr)
96
+ },
97
+ variableValue: {
98
+ type: "variable",
99
+ id: cellAst?.id?.id?.name,
100
+ inputs: ["Generators", id],
101
+ func: (G, _) => G.input(_)
102
+ }
103
+ };
104
+ }
105
+
106
+ interface ParsedMutableCell extends ParsedCell {
107
+ type: "mutable",
108
+ initial: ParsedVariable;
109
+ variable: ParsedVariable;
110
+ variableValue: ParsedVariable;
111
+ }
112
+
113
+ function parseMutableExpression(cellStr: string, cellAst, refs: Refs, bodyStr?: string): ParsedMutableCell {
114
+ const id = cellAst.id && cellStr.substring(cellAst.id.start, cellAst.id.end);
115
+ const initialValueId = cellAst?.id?.id?.name;
116
+ const initialId = `initial ${initialValueId}`;
117
+ return {
118
+ type: "mutable",
119
+ initial: {
120
+ type: "variable",
121
+ id: initialId,
122
+ inputs: refs.inputs,
123
+ func: createFunction(refs, cellAst.async, cellAst.generator, cellAst.body.type === "BlockStatement", bodyStr)
124
+ },
125
+ variable: {
126
+ type: "variable",
127
+ id,
128
+ inputs: ["Mutable", initialId],
129
+ func: (M, _) => new M(_)
130
+ },
131
+ variableValue: {
132
+ type: "variable",
133
+ id: initialValueId,
134
+ inputs: [id],
135
+ func: _ => _.generator
136
+ }
137
+ };
138
+ }
139
+
140
+ interface ParsedVariableCell extends ParsedCell {
141
+ type: "variable",
142
+ id: string,
143
+ inputs: string[],
144
+ func: any,
145
+ }
146
+
147
+ function parseVariableExpression(cellStr: string, cellAst, refs: Refs, bodyStr?: string): ParsedVariableCell {
148
+ return {
149
+ type: "variable",
150
+ id: cellAst.id && cellStr.substring(cellAst.id?.start, cellAst.id?.end),
151
+ inputs: refs.inputs,
152
+ func: createFunction(refs, cellAst.async, cellAst.generator, cellAst.body.type === "BlockStatement", bodyStr)
153
+ };
154
+ }
155
+
156
+ export function parseCell(cellStr: string): ParsedImportCell | ParsedViewCell | ParsedMutableCell | ParsedVariableCell {
157
+ const cellAst = ohqParseCell(cellStr);
158
+ if ((cellAst.body)?.type == "ImportDeclaration") {
159
+ return parseImportExpression(cellAst);
160
+ }
161
+ const refs = calcRefs(cellAst, cellStr);
162
+
163
+ const bodyStr = cellAst.body && cellStr.substring(cellAst.body.start, cellAst.body.end);
164
+ switch (cellAst.id?.type) {
165
+ case "ViewExpression":
166
+ return parseViewExpression(cellStr, cellAst, refs, bodyStr);
167
+ case "MutableExpression":
168
+ return parseMutableExpression(cellStr, cellAst, refs, bodyStr);
169
+ default:
170
+ return parseVariableExpression(cellStr, cellAst, refs, bodyStr);
171
+ }
172
+ }
package/src/index.css ADDED
@@ -0,0 +1,460 @@
1
+ @import url("https://fonts.googleapis.com/css2?family=Source+Serif+Pro:ital,wght@0,400;0,600;0,700;1,400;1,600;1,700&display=swap");
2
+
3
+ :root {
4
+ --syntax-normal: #1b1e23;
5
+ --syntax-comment: #828282;
6
+ --syntax-number: #20a5ba;
7
+ --syntax-keyword: #c30771;
8
+ --syntax-atom: #10a778;
9
+ --syntax-string: #008ec4;
10
+ --syntax-error: #ffbedc;
11
+ --syntax-unknown-variable: #838383;
12
+ --syntax-known-variable: #005f87;
13
+ --syntax-matchbracket: #20bbfc;
14
+ --syntax-key: #6636b4;
15
+ --mono-fonts: 82%/1.5 Menlo, Consolas, monospace;
16
+ }
17
+
18
+ .observablehq--expanded,
19
+ .observablehq--collapsed,
20
+ .observablehq--function,
21
+ .observablehq--import,
22
+ .observablehq--string:before,
23
+ .observablehq--string:after,
24
+ .observablehq--gray {
25
+ color: var(--syntax-normal);
26
+ }
27
+
28
+ .observablehq--collapsed,
29
+ .observablehq--expanded.observablehq--inspect a {
30
+ cursor: pointer;
31
+ }
32
+
33
+ .observablehq--field {
34
+ text-indent: -1em;
35
+ margin-left: 1em;
36
+ }
37
+
38
+ .observablehq--empty {
39
+ color: var(--syntax_comment);
40
+ }
41
+
42
+ a[href],
43
+ .observablehq--keyword,
44
+ .observablehq--blue {
45
+ color: #3182bd;
46
+ }
47
+
48
+ .hljs-deletion,
49
+ .hljs-variable,
50
+ .observablehq--forbidden,
51
+ .observablehq--pink {
52
+ color: #e377c2;
53
+ }
54
+
55
+ .observablehq--orange {
56
+ color: #e6550d;
57
+ }
58
+
59
+ .observablehq--null,
60
+ .observablehq--undefined,
61
+ .observablehq--boolean,
62
+ .hljs-literal {
63
+ color: var(--syntax-atom);
64
+ }
65
+
66
+ .hljs-number,
67
+ .hljs-regexp,
68
+ .hljs-bullet,
69
+ .hljs-link,
70
+ .observablehq--bigint,
71
+ .observablehq--number,
72
+ .observablehq--date,
73
+ .observablehq--regexp,
74
+ .observablehq--symbol,
75
+ .observablehq--green {
76
+ color: var(--syntax-number);
77
+ }
78
+
79
+ .observablehq--index,
80
+ .observablehq--key {
81
+ color: var(--syntax-key);
82
+ }
83
+
84
+ .observablehq--prototype-key {
85
+ color: #aaa;
86
+ }
87
+
88
+ .observablehq--empty {
89
+ font-style: oblique;
90
+ }
91
+
92
+ .hljs-string,
93
+ .hljs-meta,
94
+ .hljs-symbol,
95
+ .hljs-template-tag,
96
+ .hljs-template-variable,
97
+ .hljs-addition,
98
+ .observablehq--string,
99
+ .observablehq--purple {
100
+ color: var(--syntax-string);
101
+ }
102
+
103
+ .observablehq--error,
104
+ .observablehq--red {
105
+ color: #e7040f;
106
+ }
107
+
108
+ .observablehq:empty:after,
109
+ .observablehq>link:only-child,
110
+ .observablehq>style:only-child,
111
+ .observablehq--inspect {
112
+ font: var(--monospace-font);
113
+ overflow-x: auto;
114
+ display: block;
115
+ padding: 4px 0;
116
+ white-space: pre;
117
+ }
118
+
119
+ .observablehq--error .observablehq--inspect {
120
+ word-break: break-all;
121
+ white-space: pre-wrap;
122
+ }
123
+
124
+ :root {
125
+ --syntax-diff: #24292e;
126
+ --syntax-diff-bg: #ffffff;
127
+ --hr: rgba(0, 0, 0, 0.05);
128
+ --monospace: Menlo, Consolas, monospace;
129
+ --monospace-font: 14px/1.5 var(--monospace);
130
+ --serif: "Source Serif Pro", "Iowan Old Style", "Apple Garamond",
131
+ "Palatino Linotype", "Times New Roman", "Droid Serif", Times, serif,
132
+ "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
133
+ --sans-serif: -apple-system, BlinkMacSystemFont, "avenir next", avenir,
134
+ helvetica, "helvetica neue", ubuntu, roboto, noto, "segoe ui", arial,
135
+ sans-serif;
136
+ }
137
+
138
+ html {
139
+ font: 17px/1.5 var(--serif);
140
+ -webkit-text-size-adjust: 100%;
141
+ -webkit-font-smoothing: antialiased;
142
+ -moz-osx-font-smoothing: grayscale;
143
+ color: #1b1e23;
144
+ }
145
+
146
+ body {
147
+ margin: 0 14px;
148
+ }
149
+
150
+ body.fullscreen {
151
+ margin: 0;
152
+ }
153
+
154
+ h1,
155
+ h2,
156
+ h3,
157
+ h4,
158
+ h5,
159
+ h6 {
160
+ color: #333;
161
+ font-weight: 700;
162
+ line-height: 1.15;
163
+ margin-top: 0;
164
+ margin-bottom: 0.25rem;
165
+ }
166
+
167
+ h2~p,
168
+ h3~p,
169
+ h4~p,
170
+ h2~table,
171
+ h3~table,
172
+ h4~table {
173
+ margin-top: 0;
174
+ }
175
+
176
+ .observablehq:first-of-type h1+h2 {
177
+ font-size: 20px;
178
+ font-style: italic;
179
+ font-weight: normal;
180
+ margin-bottom: 1rem;
181
+ /* see h2 ~ p */
182
+ }
183
+
184
+ a[href] {
185
+ text-decoration: none;
186
+ }
187
+
188
+ a[href]:hover {
189
+ text-decoration: underline;
190
+ }
191
+
192
+ h1 code,
193
+ h2 code,
194
+ h3 code,
195
+ h4 code,
196
+ h5 code,
197
+ h6 code {
198
+ font-size: 90%;
199
+ }
200
+
201
+ pre,
202
+ code,
203
+ tt {
204
+ font-family: var(--monospace);
205
+ font-size: 14px;
206
+ line-height: 1.5;
207
+ }
208
+
209
+ img {
210
+ max-width: calc(100vw - 28px);
211
+ }
212
+
213
+ p,
214
+ table,
215
+ figure,
216
+ figcaption,
217
+ h1,
218
+ h2,
219
+ h3,
220
+ h4,
221
+ h5,
222
+ h6,
223
+ .katex-display {
224
+ max-width: 640px;
225
+ }
226
+
227
+ blockquote,
228
+ ol,
229
+ ul {
230
+ max-width: 600px;
231
+ }
232
+
233
+ blockquote {
234
+ margin: 1rem 1.5rem;
235
+ }
236
+
237
+ ul,
238
+ ol {
239
+ padding-left: 28px;
240
+ }
241
+
242
+ hr {
243
+ height: 1px;
244
+ margin: 1rem 0;
245
+ padding: 1rem 0;
246
+ border: none;
247
+ background: no-repeat center/100% 1px linear-gradient(to right, var(--hr), var(--hr));
248
+ }
249
+
250
+ pre {
251
+ padding: 2px 0;
252
+ }
253
+
254
+ .observablehq--md-pre {
255
+ overflow-x: auto;
256
+ }
257
+
258
+ input:not([type]),
259
+ input[type="email"],
260
+ input[type="number"],
261
+ input[type="password"],
262
+ input[type="range"],
263
+ input[type="search"],
264
+ input[type="tel"],
265
+ input[type="text"],
266
+ input[type="url"] {
267
+ width: 240px;
268
+ }
269
+
270
+ input,
271
+ canvas,
272
+ button {
273
+ vertical-align: middle;
274
+ }
275
+
276
+ button,
277
+ input,
278
+ textarea {
279
+ accent-color: #3b5fc0;
280
+ }
281
+
282
+ table {
283
+ width: 100%;
284
+ border-collapse: collapse;
285
+ font: 13px/1.2 var(--sans-serif);
286
+ }
287
+
288
+ table pre,
289
+ table code,
290
+ table tt {
291
+ font-size: inherit;
292
+ line-height: inherit;
293
+ }
294
+
295
+ th>pre:only-child,
296
+ td>pre:only-child {
297
+ margin: 0;
298
+ padding: 0;
299
+ }
300
+
301
+ th {
302
+ color: #111;
303
+ text-align: left;
304
+ vertical-align: bottom;
305
+ }
306
+
307
+ td {
308
+ color: #444;
309
+ vertical-align: top;
310
+ }
311
+
312
+ th,
313
+ td {
314
+ padding: 3px 6.5px 3px 0;
315
+ }
316
+
317
+ th:last-child,
318
+ td:last-child {
319
+ padding-right: 0;
320
+ }
321
+
322
+ tr:not(:last-child) {
323
+ border-bottom: solid 1px #eee;
324
+ }
325
+
326
+ thead tr {
327
+ border-bottom: solid 1px #ccc;
328
+ }
329
+
330
+ figure,
331
+ table {
332
+ margin: 1rem 0;
333
+ }
334
+
335
+ figure img {
336
+ max-width: 100%;
337
+ }
338
+
339
+ figcaption {
340
+ font: small var(--sans-serif);
341
+ color: var(--syntax-unknown-variable);
342
+ }
343
+
344
+ .observablehq--caret {
345
+ margin-right: 4px;
346
+ vertical-align: baseline;
347
+ }
348
+
349
+ .observablehq--field {
350
+ text-indent: -1rem;
351
+ margin-left: 1rem;
352
+ }
353
+
354
+ .observablehq--prototype-key,
355
+ .observablehq--empty,
356
+ .hljs-comment {
357
+ color: var(--syntax-comment);
358
+ }
359
+
360
+ .hljs-built_in {
361
+ color: var(--syntax-known-variable);
362
+ }
363
+
364
+ .observablehq--unknown {
365
+ color: var(--syntax-unknown-variable);
366
+ }
367
+
368
+ .hljs-keyword,
369
+ .hljs-selector-tag,
370
+ .hljs-section,
371
+ .hljs-doctag,
372
+ .hljs-type,
373
+ .hljs-tag,
374
+ .hljs-name,
375
+ .hljs-selector-id,
376
+ .hljs-selector-class,
377
+ .hljs-strong {
378
+ color: var(--syntax-keyword);
379
+ }
380
+
381
+ .observablehq {
382
+ position: relative;
383
+ margin: 17px 0;
384
+ min-height: 1.5rem;
385
+ /* the standard line-height */
386
+ }
387
+
388
+ .observablehq:before {
389
+ content: "";
390
+ position: absolute;
391
+ left: -14px;
392
+ top: 0;
393
+ bottom: 1px;
394
+ width: 4px;
395
+ transition: background-color 250ms linear;
396
+ }
397
+
398
+ .observablehq--running:before,
399
+ .observablehq--changed:before {
400
+ background-color: hsl(217, 13%, 70%);
401
+ transition: none;
402
+ }
403
+
404
+ .observablehq--error:before {
405
+ background-color: #e7040f;
406
+ }
407
+
408
+ .observablehq:not(.observablehq--running):empty:after {
409
+ content: "<detached>";
410
+ color: var(--syntax-comment);
411
+ font-style: oblique;
412
+ }
413
+
414
+ .observablehq>link:only-child,
415
+ .observablehq>style:only-child {
416
+ visibility: hidden;
417
+ white-space: nowrap;
418
+ color: var(--syntax-keyword);
419
+ }
420
+
421
+ .observablehq>link:only-child:before {
422
+ content: "<link>";
423
+ visibility: visible;
424
+ text-decoration: none;
425
+ pointer-events: none;
426
+ }
427
+
428
+ .observablehq>style:only-child:before {
429
+ content: "<style>";
430
+ visibility: visible;
431
+ }
432
+
433
+ .observablehq--inspect.observablehq--import {
434
+ white-space: normal;
435
+ }
436
+
437
+ .observablehq--inspect::-webkit-scrollbar {
438
+ display: none;
439
+ }
440
+
441
+ .observablehq--string-expand {
442
+ margin-left: 6px;
443
+ padding: 2px 6px;
444
+ border-radius: 2px;
445
+ font-size: 80%;
446
+ background: #eee;
447
+ color: var(--syntax-normal);
448
+ cursor: pointer;
449
+ vertical-align: middle;
450
+ position: sticky;
451
+ right: 0;
452
+ }
453
+
454
+ .observablehq--string-expand:hover {
455
+ background: #ddd;
456
+ }
457
+
458
+ .observablehq--string-expand:active {
459
+ background: #ddd;
460
+ }
package/src/index.ts ADDED
@@ -0,0 +1,7 @@
1
+ export type { ohq } from "@hpcc-js/observable-shim";
2
+
3
+ export * from "./compiler";
4
+ export { ojs2notebook, omd2notebook, download } from "./util";
5
+ export * from "./writer";
6
+
7
+ import "../src/index.css";